Skip to contentSkip to conversation

6.12.21-rc1 review

PATCH In review Greg Kroah-Hartman 7 participants 123 messages Mar 25, 2025 – Dec 2, 2025

Subsystems (5)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 6.12.21-rc1 review

This is the start of the stable review cycle for the 6.12.21 release. There are 116 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Thu, 27 Mar 2025 12:21:27 +0000. Anything received after that time might be too late.

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

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

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

thanks,

greg k-h

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

Greg Kroah-Hartman <[email protected]>

    Linux 6.12.21-rc1

Arthur Mongodin <[email protected]>
mptcp: Fix data stream corruption in the address announcement

Zi Yan <[email protected]>
mm/huge_memory: drop beyond-EOF folios with the right number of refs

Justin Klaassen <[email protected]>
arm64: dts: rockchip: fix u2phy1_host status for NanoPi R4S

Eder Zulian <[email protected]>
libsubcmd: Silence compiler warning

Dietmar Eggemann <[email protected]>
Revert "sched/core: Reduce cost of sched_move_task when config autogroup"

Mark Rutland <[email protected]>

    KVM: arm64: Eagerly switch ZCR_EL{1,2}

Mark Rutland <[email protected]>
KVM: arm64: Mark some header functions as inline

Mark Rutland <[email protected]>
KVM: arm64: Refactor exit handlers

Mark Rutland <[email protected]>
KVM: arm64: Remove VHE host restore of CPACR_EL1.SMEN

Mark Rutland <[email protected]>
KVM: arm64: Remove VHE host restore of CPACR_EL1.ZEN

Mark Rutland <[email protected]>
KVM: arm64: Remove host FPSIMD saving for non-protected KVM

Mark Rutland <[email protected]>
KVM: arm64: Unconditionally save+flush host FPSIMD/SVE/SME state

Fuad Tabba <[email protected]>
KVM: arm64: Calculate cptr_el2 traps on activating traps

Pavel Begunkov <[email protected]>
io_uring/net: fix sendzc double notif flush

Namjae Jeon <[email protected]>
ksmbd: fix incorrect validation for num_aces field of smb_acl

Philip Yang <[email protected]>
drm/amdkfd: Fix user queue validation on Gfx7/8

David Rosca <[email protected]>
drm/amdgpu: Fix JPEG video caps max size for navi1x and raven

David Rosca <[email protected]>
drm/amdgpu: Fix MPEG2, MPEG4 and VC1 video caps max size

David Rosca <[email protected]>
drm/amdgpu: Remove JPEG from vega and carrizo video caps

Alex Deucher <[email protected]>
drm/amdgpu/pm: wire up hwmon fan speed for smu 14.0.2

Tomasz Pakuła <[email protected]>
drm/amdgpu/pm: Handle SCLK offset correctly in overdrive for smu 14.0.2

David Belanger <[email protected]>
drm/amdgpu: Restore uncached behaviour on GFX12

Harish Kasiviswanathan <[email protected]>
drm/amd/pm: add unique_id for gfx12

Mario Limonciello <[email protected]>
drm/amd/display: Use HW lock mgr for PSR1 when only one eDP

Yilin Chen <[email protected]>
drm/amd/display: Fix message for support_edp0_on_dp1

Wentao Liang <[email protected]>
drm/amdgpu/gfx12: correct cleanup of 'me' field with gfx_v12_0_me_fini()

qianyi liu <[email protected]>
drm/sched: Fix fence reference count leak

Nikita Zhandarovich <[email protected]>
drm/radeon: fix uninitialized size issue in radeon_vce_cs_parse()

Xianwei Zhao <[email protected]>
pmdomain: amlogic: fix T7 ISP secpower

Saranya R <[email protected]>
soc: qcom: pdr: Fix the potential deadlock

Sven Eckelmann <[email protected]>
batman-adv: Ignore own maximum aggregation size during RX

Gavrilov Ilia <[email protected]>
xsk: fix an integer overflow in xp_create_and_assign_umem()

David Howells <[email protected]>
keys: Fix UAF in key_put()

Ard Biesheuvel <[email protected]>

    efi/libstub: Avoid physical address 0x0 when doing random allocation

Johan Hovold <[email protected]>
firmware: qcom: uefisecapp: fix efivars registration race

Geert Uytterhoeven <[email protected]>
ARM: shmobile: smp: Enforce shmobile_smp_* alignment

Stefan Eichenberger <[email protected]>
ARM: dts: imx6qdl-apalis: Fix poweroff on Apalis iMX6

Shakeel Butt <[email protected]>
memcg: drain obj stock on cpu hotplug teardown

Ye Bin <[email protected]>
proc: fix UAF in proc_get_inode()

Kirill A. Shutemov <[email protected]>
mm/page_alloc: fix memory accept before watermarks gets initialized

Zi Yan <[email protected]>
mm/migrate: fix shmem xarray update during migration

Raphael S. Carvalho <[email protected]>
mm: fix error handling in __filemap_get_folio() with FGP_NOWAIT

Rafael Aquini <[email protected]>
selftests/mm: run_vmtests.sh: fix half_ufd_size_MB calculation

Gu Bowen <[email protected]>
mmc: atmel-mci: Add missing clk_disable_unprepare()

Kamal Dasu <[email protected]>
mmc: sdhci-brcmstb: add cqhci suspend/resume to PM ops

Dragan Simic <[email protected]>
arm64: dts: rockchip: Add missing PCIe supplies to RockPro64 board dtsi

Quentin Schulz <[email protected]>
arm64: dts: rockchip: fix pinmux of UART5 for PX30 Ringneck on Haikou

Quentin Schulz <[email protected]>
arm64: dts: rockchip: fix pinmux of UART0 for PX30 Ringneck on Haikou

Stefan Eichenberger <[email protected]>
arm64: dts: freescale: imx8mm-verdin-dahlia: add Microphone Jack to sound card

Stefan Eichenberger <[email protected]>
arm64: dts: freescale: imx8mp-verdin-dahlia: add Microphone Jack to sound card

Dan Carpenter <[email protected]>
accel/qaic: Fix integer overflow in qaic_validate_req()

Christian Eggers <[email protected]>
regulator: check that dummy regulator has been probed before using it

Christian Eggers <[email protected]>
regulator: dummy: force synchronous probing

Max Kellermann <[email protected]>
netfs: Call invalidate_cache only if implemented

E Shattow <[email protected]>
riscv: dts: starfive: Fix a typo in StarFive JH7110 pin function definitions

Jens Axboe <[email protected]>
io_uring/net: don't clear REQ_F_NEED_CLEANUP unconditionally

Maíra Canal <[email protected]>
drm/v3d: Don't run jobs that have errors flagged in its fence

Tomasz Rusinowicz <[email protected]>
drm/xe: Fix exporting xe buffers multiple times

Haibo Chen <[email protected]>
can: flexcan: disable transceiver during system PM

Haibo Chen <[email protected]>
can: flexcan: only change CAN state when link up in system PM

Vincent Mailhol <[email protected]>
can: ucan: fix out of bound read in strscpy() source

Biju Das <[email protected]>
can: rcar_canfd: Fix page entries in the AFL list

Biju Das <[email protected]>
dt-bindings: can: renesas,rcar-canfd: Fix typo in pattern properties for R-Car V4M

Haiyang Zhang <[email protected]>
net: mana: Support holes in device list reply msg

Andreas Kemnade <[email protected]>
i2c: omap: fix IRQ storms

Masami Hiramatsu (Google) <[email protected]>
tracing: tprobe-events: Fix leakage of module refcount

Guillaume Nault <[email protected]>
Revert "gre: Fix IPv6 link-local address generation."

Lin Ma <[email protected]>
net/neighbor: add missing policy for NDTPA_QUEUE_LENBYTES

Yongjian Sun <[email protected]>
libfs: Fix duplicate directory entry in offset_dir_lookup

Justin Iurman <[email protected]>
net: ipv6: ioam6: fix lwtunnel_output() loop

Justin Iurman <[email protected]>
net: lwtunnel: fix recursion loops

MD Danish Anwar <[email protected]>
net: ti: icssg-prueth: Add lock to stats

Dan Carpenter <[email protected]>
net: atm: fix use after free in lec_send()

Jason Gunthorpe <[email protected]>
gpu: host1x: Do not assume that a NULL domain means no DMA IOMMU

Michal Swiatkowski <[email protected]>
phy: fix xa_alloc_cyclic() error handling

Michal Swiatkowski <[email protected]>
dpll: fix xa_alloc_cyclic() error handling

Michal Swiatkowski <[email protected]>
devlink: fix xa_alloc_cyclic() error handling

Kuniyuki Iwashima <[email protected]>
ipv6: Set errno after ip_fib_metrics_init() in ip6_route_info_create().

Kuniyuki Iwashima <[email protected]>
ipv6: Fix memleak of nhc_pcpu_rth_output in fib_check_nh_v6_gw().

Felix Fietkau <[email protected]>
net: ipv6: fix TCP GSO segmentation with NAT

Vignesh Raghavendra <[email protected]>
net: ethernet: ti: am65-cpsw: Fix NAPI registration sequence

Niklas Cassel <[email protected]>
ata: libata-core: Add ATA_QUIRK_NO_LPM_ON_ATI for certain Samsung SSDs

Masami Hiramatsu (Google) <[email protected]>
tracing: tprobe-events: Fix to clean up tprobe correctly when module unload

David Lechner <[email protected]>
ARM: davinci: da850: fix selecting ARCH_DAVINCI_DA8XX

Jeffrey Hugo <[email protected]>
accel/qaic: Fix possible data corruption in BOs > 2G

Arkadiusz Bokowy <[email protected]>
Bluetooth: hci_event: Fix connection regression between LE and non-LE adapters

Dan Carpenter <[email protected]>
Bluetooth: Fix error code in chan_alloc_skb_cb()

Junxian Huang <[email protected]>
RDMA/hns: Fix wrong value of max_sge_rd

Junxian Huang <[email protected]>
RDMA/hns: Fix missing xa_destroy()

Junxian Huang <[email protected]>
RDMA/hns: Fix a missing rollback in error path of hns_roce_create_qp_common()

Junxian Huang <[email protected]>
RDMA/hns: Fix invalid sq params not being blocked

Junxian Huang <[email protected]>
RDMA/hns: Fix unmatched condition in error path of alloc_user_qp_db()

Junxian Huang <[email protected]>
RDMA/hns: Fix soft lockup during bt pages loop

Saravanan Vajravel <[email protected]>
RDMA/bnxt_re: Avoid clearing VLAN_ID mask in modify qp path

Baochen Qiang <[email protected]>
dma-mapping: fix missing clear bdr in check_ram_in_range_map()

Chester A. Unal <[email protected]>
ARM: dts: BCM5301X: Fix switch port labels of ASUS RT-AC3200

Chester A. Unal <[email protected]>
ARM: dts: BCM5301X: Fix switch port labels of ASUS RT-AC5300

Phil Elwell <[email protected]>
ARM: dts: bcm2711: Don't mark timer regs unconfigured

Arnd Bergmann <[email protected]>
ARM: OMAP1: select CONFIG_GENERIC_IRQ_CHIP

Qasim Ijaz <[email protected]>
RDMA/mlx5: Handle errors returned from mlx5r_ib_rate()

Kashyap Desai <[email protected]>
RDMA/bnxt_re: Add missing paranthesis in map_qp_id_to_tbl_indx

Zhu Yanjun <[email protected]>
RDMA/rxe: Fix the failure of ibv_query_device() and ibv_query_device_ex() tests

Yao Zi <[email protected]>
arm64: dts: rockchip: Remove undocumented sdmmc property from lubancat-1

Phil Elwell <[email protected]>

    arm64: dts: bcm2712: PL011 UARTs are actually r1p5

Phil Elwell <[email protected]>
ARM: dts: bcm2711: PL011 UARTs are actually r1p5

Stefan Wahren <[email protected]>
ARM: dts: bcm2711: Fix xHCI power-domain

Peng Fan <[email protected]>
soc: imx8m: Unregister cpufreq and soc dev in cleanup path

Marek Vasut <[email protected]>
soc: imx8m: Use devm_* to simplify probe failure handling

Marek Vasut <[email protected]>
soc: imx8m: Remove global soc_uid

Cosmin Ratiu <[email protected]>
xfrm_output: Force software GSO only in tunnel mode

Alexandre Cassen <[email protected]>
xfrm: fix tunnel mode TX datapath in packet offload mode

Heiko Stuebner <[email protected]>
arm64: dts: rockchip: remove supports-cqe from rk3588 tiger

Heiko Stuebner <[email protected]>
arm64: dts: rockchip: remove supports-cqe from rk3588 jaguar

Alexander Stein <[email protected]>
arm64: dts: freescale: tqma8mpql: Fix vqmmc-supply

Joe Hattori <[email protected]>
firmware: imx-scu: fix OF node leak in .probe()

Dan Carpenter <[email protected]>
firmware: qcom: scm: Fix error code in probe()

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

Diffstat:

 .../bindings/net/can/renesas,rcar-canfd.yaml       |   2 +-
 Makefile                                           |   4 +-
 arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi        |   5 -
 arch/arm/boot/dts/broadcom/bcm2711.dtsi            |  12 +-
 .../boot/dts/broadcom/bcm4709-asus-rt-ac3200.dts   |  12 +-
 .../boot/dts/broadcom/bcm47094-asus-rt-ac5300.dts  |   8 +-
 arch/arm/boot/dts/nxp/imx/imx6qdl-apalis.dtsi      |  10 +-
 arch/arm/mach-davinci/Kconfig                      |   1 +
 arch/arm/mach-omap1/Kconfig                        |   1 +
 arch/arm/mach-shmobile/headsmp.S                   |   1 +
 arch/arm64/boot/dts/broadcom/bcm2712.dtsi          |   2 +-
 .../boot/dts/freescale/imx8mm-verdin-dahlia.dtsi   |   6 +-
 .../arm64/boot/dts/freescale/imx8mp-tqma8mpql.dtsi |  16 +--
 .../boot/dts/freescale/imx8mp-verdin-dahlia.dtsi   |   6 +-
 .../boot/dts/rockchip/px30-ringneck-haikou.dts     |  12 ++
 arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts |   2 +-
 arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi |   2 +
 arch/arm64/boot/dts/rockchip/rk3566-lubancat-1.dts |   1 -
 arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts     |   1 -
 arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi     |   1 -
 arch/arm64/include/asm/kvm_host.h                  |  23 +---
 arch/arm64/kernel/fpsimd.c                         |  25 ----
 arch/arm64/kvm/arm.c                               |   9 --
 arch/arm64/kvm/fpsimd.c                            | 100 ++------------
 arch/arm64/kvm/hyp/entry.S                         |   5 +
 arch/arm64/kvm/hyp/include/hyp/switch.h            | 133 +++++++++++++-----
 arch/arm64/kvm/hyp/nvhe/hyp-main.c                 |  11 +-
 arch/arm64/kvm/hyp/nvhe/pkvm.c                     |  29 ----
 arch/arm64/kvm/hyp/nvhe/switch.c                   | 140 ++++++++++---------
 arch/arm64/kvm/hyp/vhe/switch.c                    |  21 ++-
 arch/riscv/boot/dts/starfive/jh7110-pinfunc.h      |   2 +-
 drivers/accel/qaic/qaic_data.c                     |   9 +-
 drivers/ata/libata-core.c                          |  14 +-
 drivers/dpll/dpll_core.c                           |   2 +-
 drivers/firmware/efi/libstub/randomalloc.c         |   4 +
 drivers/firmware/imx/imx-scu.c                     |   1 +
 drivers/firmware/qcom/qcom_qseecom_uefisecapp.c    |  18 +--
 drivers/firmware/qcom/qcom_scm.c                   |   4 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c             |   2 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c             |  22 +--
 drivers/gpu/drm/amd/amdgpu/nv.c                    |  20 +--
 drivers/gpu/drm/amd/amdgpu/soc15.c                 |  21 ++-
 drivers/gpu/drm/amd/amdgpu/vi.c                    |  43 +++---
 drivers/gpu/drm/amd/amdkfd/kfd_queue.c             |  12 +-
 drivers/gpu/drm/amd/amdkfd/kfd_svm.c               |   8 +-
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |   2 +-
 .../gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c  |  11 ++
 drivers/gpu/drm/amd/pm/amdgpu_pm.c                 |   2 +
 .../gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c   |  96 +++++++------
 drivers/gpu/drm/radeon/radeon_vce.c                |   2 +-
 drivers/gpu/drm/scheduler/sched_entity.c           |  11 +-
 drivers/gpu/drm/v3d/v3d_sched.c                    |   9 +-
 drivers/gpu/drm/xe/xe_bo.h                         |   2 -
 drivers/gpu/drm/xe/xe_dma_buf.c                    |   2 +-
 drivers/gpu/host1x/dev.c                           |   6 +
 drivers/i2c/busses/i2c-omap.c                      |  26 +---
 drivers/infiniband/hw/bnxt_re/qplib_fp.c           |   2 -
 drivers/infiniband/hw/bnxt_re/qplib_rcfw.h         |   3 +-
 drivers/infiniband/hw/hns/hns_roce_alloc.c         |   4 +-
 drivers/infiniband/hw/hns/hns_roce_cq.c            |   1 +
 drivers/infiniband/hw/hns/hns_roce_hem.c           |  16 ++-
 drivers/infiniband/hw/hns/hns_roce_main.c          |   2 +-
 drivers/infiniband/hw/hns/hns_roce_qp.c            |  20 +--
 drivers/infiniband/hw/mlx5/ah.c                    |  14 +-
 drivers/infiniband/sw/rxe/rxe.c                    |  25 +---
 drivers/mmc/host/atmel-mci.c                       |   4 +-
 drivers/mmc/host/sdhci-brcmstb.c                   |  10 ++
 drivers/net/can/flexcan/flexcan-core.c             |  18 ++-
 drivers/net/can/rcar/rcar_canfd.c                  |  28 ++--
 drivers/net/can/usb/ucan.c                         |  43 +++---
 drivers/net/ethernet/microsoft/mana/gdma_main.c    |  14 +-
 drivers/net/ethernet/ti/am65-cpsw-nuss.c           |  32 +++--
 drivers/net/ethernet/ti/icssg/icssg_prueth.c       |   1 +
 drivers/net/ethernet/ti/icssg/icssg_prueth.h       |   2 +
 drivers/net/ethernet/ti/icssg/icssg_stats.c        |   4 +
 drivers/net/phy/phy_link_topology.c                |   2 +-
 drivers/pmdomain/amlogic/meson-secure-pwrc.c       |   2 +-
 drivers/regulator/core.c                           |  12 +-
 drivers/regulator/dummy.c                          |   2 +-
 drivers/soc/imx/soc-imx8m.c                        | 151 ++++++++++-----------
 drivers/soc/qcom/pdr_interface.c                   |   8 +-
 fs/libfs.c                                         |   2 +-
 fs/netfs/write_collect.c                           |   3 +-
 fs/proc/generic.c                                  |  10 +-
 fs/proc/inode.c                                    |   6 +-
 fs/proc/internal.h                                 |  14 ++
 fs/smb/server/smbacl.c                             |   5 +-
 include/linux/key.h                                |   1 +
 include/linux/libata.h                             |   2 +
 include/linux/proc_fs.h                            |   7 +-
 include/net/bluetooth/hci.h                        |   2 +-
 include/net/mana/gdma.h                            |  11 +-
 io_uring/net.c                                     |   5 +-
 kernel/dma/direct.c                                |  28 ++--
 kernel/sched/core.c                                |  21 +--
 kernel/trace/trace_fprobe.c                        |  30 ++--
 mm/filemap.c                                       |  13 +-
 mm/huge_memory.c                                   |   2 +-
 mm/memcontrol.c                                    |   9 ++
 mm/migrate.c                                       |  10 +-
 mm/page_alloc.c                                    |  14 +-
 net/atm/lec.c                                      |   3 +-
 net/batman-adv/bat_iv_ogm.c                        |   3 +-
 net/batman-adv/bat_v_ogm.c                         |   3 +-
 net/bluetooth/6lowpan.c                            |   7 +-
 net/core/lwtunnel.c                                |  65 +++++++--
 net/core/neighbour.c                               |   1 +
 net/devlink/core.c                                 |   2 +-
 net/ipv6/addrconf.c                                |  15 +-
 net/ipv6/ioam6_iptunnel.c                          |   8 +-
 net/ipv6/route.c                                   |   5 +-
 net/ipv6/tcpv6_offload.c                           |  21 ++-
 net/mptcp/options.c                                |   6 +-
 net/xdp/xsk_buff_pool.c                            |   2 +-
 net/xfrm/xfrm_output.c                             |  43 +++++-
 security/keys/gc.c                                 |   4 +-
 security/keys/key.c                                |   2 +
 tools/lib/subcmd/parse-options.c                   |   2 +-
 tools/testing/selftests/mm/run_vmtests.sh          |   4 +-
 119 files changed, 944 insertions(+), 819 deletions(-)
author maintainer
#1 lore raw

PATCH 1/116 firmware: qcom: scm: Fix error code in probe()

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

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

From: Dan Carpenter <[email protected]>

[ Upstream commit 7f048b202333b967782a98aa21bb3354dc379bbf ]

Set the error code if devm_qcom_tzmem_pool_new() fails. Don't return success.

Fixes 1e76b546e6fc ("firmware: qcom: scm: Cleanup global '__scm' on probe failures")
---
 drivers/firmware/qcom/qcom_scm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/firmware/qcom/qcom_scm.c +2 -2
index 2e093c39b610a..23aefbf6fca58 100644
@@ -2054,8 +2054,8 @@ static int qcom_scm_probe(struct platform_device *pdev)
 
 	__scm->mempool = devm_qcom_tzmem_pool_new(__scm->dev, &pool_config);
 	if (IS_ERR(__scm->mempool)) {
-		dev_err_probe(__scm->dev, PTR_ERR(__scm->mempool),
-			      "Failed to create the SCM memory pool\n");
+		ret = dev_err_probe(__scm->dev, PTR_ERR(__scm->mempool),
+				    "Failed to create the SCM memory pool\n");
 		goto err;
 	}
 
Signature · 1 line
2.39.5
author maintainer
#2 lore raw

PATCH 2/116 firmware: imx-scu: fix OF node leak in .probe()

In reply to Greg Kroah-Hartman

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

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

From: Joe Hattori <[email protected]>

[ Upstream commit fbf10b86f6057cf79300720da4ea4b77e6708b0d ]

imx_scu_probe() calls of_parse_phandle_with_args(), but does not release the OF node reference obtained by it. Add a of_node_put() call after done with the node.

Fixes f25a066d1a07 ("firmware: imx-scu: Support one TX and one RX")
---
 drivers/firmware/imx/imx-scu.c | 1 +
 1 file changed, 1 insertion(+)
drivers/firmware/imx/imx-scu.c +1 -0
index 1dd4362ef9a3f..8c28e25ddc8a6 100644
@@ -280,6 +280,7 @@ static int imx_scu_probe(struct platform_device *pdev)
 		return ret;
 
 	sc_ipc->fast_ipc = of_device_is_compatible(args.np, "fsl,imx8-mu-scu");
+	of_node_put(args.np);
 
 	num_channel = sc_ipc->fast_ipc ? 2 : SCU_MU_CHAN_NUM;
 	for (i = 0; i < num_channel; i++) {
Signature · 1 line
2.39.5
author maintainer
#3 lore raw

PATCH 3/116 arm64: dts: freescale: tqma8mpql: Fix vqmmc-supply

In reply to Greg Kroah-Hartman

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

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

From: Alexander Stein <[email protected]>

[ Upstream commit 38f59e0e8bd2b3e1319716e4aeaeb9a6223b006d ]

eMMC is supplied by BUCK5 rail. Use the actual regulator instead of a virtual fixed regulator.

Fixes 418d1d840e421 ("arm64: dts: freescale: add initial device tree for TQMa8MPQL with i.MX8MP")
---
 .../boot/dts/freescale/imx8mp-tqma8mpql.dtsi     | 16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)
arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql.dtsi +4 -12
index 336785a9fba89..3ddc5aaa7c5f0 100644
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
 /*
- * Copyright 2021-2022 TQ-Systems GmbH
- * Author: Alexander Stein <[email protected]>
+ * Copyright 2021-2025 TQ-Systems GmbH <[email protected]>,
+ * D-82229 Seefeld, Germany.
+ * Author: Alexander Stein
  */
 
 #include "imx8mp.dtsi"
@@ -23,15 +24,6 @@ reg_vcc3v3: regulator-vcc3v3 {
 		regulator-max-microvolt = <3300000>;
 		regulator-always-on;
 	};
-
-	/* e-MMC IO, needed for HS modes */
-	reg_vcc1v8: regulator-vcc1v8 {
-		compatible = "regulator-fixed";
-		regulator-name = "VCC1V8";
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <1800000>;
-		regulator-always-on;
-	};
 };
 
 &A53_0 {
@@ -197,7 +189,7 @@ &usdhc3 {
 	no-sd;
 	no-sdio;
 	vmmc-supply = <&reg_vcc3v3>;
-	vqmmc-supply = <&reg_vcc1v8>;
+	vqmmc-supply = <&buck5_reg>;
 	status = "okay";
 };
 
Signature · 1 line
2.39.5
author maintainer
#4 lore raw

PATCH 4/116 arm64: dts: rockchip: remove supports-cqe from rk3588 jaguar

In reply to Greg Kroah-Hartman

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

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

From: Heiko Stuebner <[email protected]>

[ Upstream commit 304b0a60d38dc24bfbfc9adc7d254d1cf8f98317 ]

The sdhci controller supports cqe it seems and necessary code also is in place - in theory.

At this point Jaguar and Tiger are the only boards enabling cqe support on the rk3588 and we are seeing reliability issues under load.

This can be caused by either a controller-, hw- or driver-issue and definitly needs more investigation to work properly it seems.

So disable cqe support on Jaguar for now.

Fixes d1b8b36a2cc5 ("arm64: dts: rockchip: add Theobroma Jaguar SBC")
---
 arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts | 1 -
 1 file changed, 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts +0 -1
index 31d2f8994f851..e61c5731fb99f 100644
@@ -455,7 +455,6 @@ &sdhci {
 	non-removable;
 	pinctrl-names = "default";
 	pinctrl-0 = <&emmc_bus8 &emmc_cmd &emmc_clk &emmc_data_strobe>;
-	supports-cqe;
 	vmmc-supply = <&vcc_3v3_s3>;
 	vqmmc-supply = <&vcc_1v8_s3>;
 	status = "okay";
Signature · 1 line
2.39.5
author maintainer
#5 lore raw

PATCH 5/116 arm64: dts: rockchip: remove supports-cqe from rk3588 tiger

In reply to Greg Kroah-Hartman

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

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

From: Heiko Stuebner <[email protected]>

[ Upstream commit 3e0711f89e5e7b0c7b2ab4843dc92dcbbdbba777 ]

The sdhci controller supports cqe it seems and necessary code also is in place - in theory.

At this point Jaguar and Tiger are the only boards enabling cqe support on the rk3588 and we are seeing reliability issues under load.

This can be caused by either a controller-, hw- or driver-issue and definitly needs more investigation to work properly it seems.

So disable cqe support on Tiger for now.

Fixes 6173ef24b35b ("arm64: dts: rockchip: add RK3588-Q7 (Tiger) SoM")
---
 arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi | 1 -
 1 file changed, 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi +0 -1
index 615094bb8ba38..a82fe75bda55c 100644
@@ -367,7 +367,6 @@ &sdhci {
 	non-removable;
 	pinctrl-names = "default";
 	pinctrl-0 = <&emmc_bus8 &emmc_cmd &emmc_clk &emmc_data_strobe>;
-	supports-cqe;
 	vmmc-supply = <&vcc_3v3_s3>;
 	vqmmc-supply = <&vcc_1v8_s3>;
 	status = "okay";
Signature · 1 line
2.39.5
author maintainer
#6 lore raw

PATCH 6/116 xfrm: fix tunnel mode TX datapath in packet offload mode

In reply to Greg Kroah-Hartman

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

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

From: Alexandre Cassen <[email protected]>

[ Upstream commit 5eddd76ec2fd1988f0a3450fde9730b10dd22992 ]

Packets that match the output xfrm policy are delivered to the netstack. In IPsec packet mode for tunnel mode, the HW is responsible for building the hard header and outer IP header. In such a situation, the inner header may refer to a network that is not directly reachable by the host, resulting in a failed neighbor resolution. The packet is then dropped. xfrm policy defines the netdevice to use for xmit so we can send packets directly to it.

Makes direct xmit exclusive to tunnel mode, since some rules may apply in transport mode.

Fixes f8a70afafc17 ("xfrm: add TX datapath support for IPsec packet offload mode")
---
 net/xfrm/xfrm_output.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)
net/xfrm/xfrm_output.c +41 -0
index e5722c95b8bb3..9160a5e09041d 100644
@@ -610,6 +610,40 @@ int xfrm_output_resume(struct sock *sk, struct sk_buff *skb, int err)
 }
 EXPORT_SYMBOL_GPL(xfrm_output_resume);
 
+static int xfrm_dev_direct_output(struct sock *sk, struct xfrm_state *x,
+				  struct sk_buff *skb)
+{
+	struct dst_entry *dst = skb_dst(skb);
+	struct net *net = xs_net(x);
+	int err;
+
+	dst = skb_dst_pop(skb);
+	if (!dst) {
+		XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
+		kfree_skb(skb);
+		return -EHOSTUNREACH;
+	}
+	skb_dst_set(skb, dst);
+	nf_reset_ct(skb);
+
+	err = skb_dst(skb)->ops->local_out(net, sk, skb);
+	if (unlikely(err != 1)) {
+		kfree_skb(skb);
+		return err;
+	}
+
+	/* In transport mode, network destination is
+	 * directly reachable, while in tunnel mode,
+	 * inner packet network may not be. In packet
+	 * offload type, HW is responsible for hard
+	 * header packet mangling so directly xmit skb
+	 * to netdevice.
+	 */
+	skb->dev = x->xso.dev;
+	__skb_push(skb, skb->dev->hard_header_len);
+	return dev_queue_xmit(skb);
+}
+
 static int xfrm_output2(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
 	return xfrm_output_resume(sk, skb, 1);
@@ -729,6 +763,13 @@ int xfrm_output(struct sock *sk, struct sk_buff *skb)
 			return -EHOSTUNREACH;
 		}
 
+		/* Exclusive direct xmit for tunnel mode, as
+		 * some filtering or matching rules may apply
+		 * in transport mode.
+		 */
+		if (x->props.mode == XFRM_MODE_TUNNEL)
+			return xfrm_dev_direct_output(sk, x, skb);
+
 		return xfrm_output_resume(sk, skb, 0);
 	}
 
Signature · 1 line
2.39.5
author maintainer
#7 lore raw

PATCH 7/116 xfrm_output: Force software GSO only in tunnel mode

In reply to Greg Kroah-Hartman

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

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

From: Cosmin Ratiu <[email protected]>

[ Upstream commit 0aae2867aa6067f73d066bc98385e23c8454a1d7 ]

The cited commit fixed a software GSO bug with VXLAN + IPSec in tunnel mode. Unfortunately, it is slightly broader than necessary, as it also severely affects performance for Geneve + IPSec transport mode over a device capable of both HW GSO and IPSec crypto offload. In this case, xfrm_output unnecessarily triggers software GSO instead of letting the HW do it. In simple iperf3 tests over Geneve + IPSec transport mode over a back-2-back pair of NICs with MTU 1500, the performance was observed to be up to 6x worse when doing software GSO compared to leaving it to the hardware.

This commit makes xfrm_output only trigger software GSO in crypto offload cases for already encapsulated packets in tunnel mode, as not doing so would then cause the inner tunnel skb->inner_networking_header to be overwritten and break software GSO for that packet later if the device turns out to not be capable of HW GSO.

Taking a closer look at the conditions for the original bug, to better understand the reasons for this change:
- vxlan_build_skb -> iptunnel_handle_offloads sets inner_protocol and inner network header.
- then, udp_tunnel_xmit_skb -> ip_tunnel_xmit adds outer transport and network headers.
- later in the xmit path, xfrm_output -> xfrm_outer_mode_output -> xfrm4_prepare_output -> xfrm4_tunnel_encap_add overwrites the inner network header with the one set in ip_tunnel_xmit before adding the second outer header.
- __dev_queue_xmit -> validate_xmit_skb checks whether GSO segmentation needs to happen based on dev features. In the original bug, the hw couldn't segment the packets, so skb_gso_segment was invoked.
- deep in the .gso_segment callback machinery, __skb_udp_tunnel_segment tries to use the wrong inner network header, expecting the one set in iptunnel_handle_offloads but getting the one set by xfrm instead.
- a bit later, ipv6_gso_segment accesses the wrong memory based on that wrong inner network header.

With the new change, the original bug (or similar ones) cannot happen again, as xfrm will now trigger software GSO before applying a tunnel. This concern doesn't exist in packet offload mode, when the HW adds encapsulation headers. For the non-offloaded packets (crypto in SW), software GSO is still done unconditionally in the else branch.

Fixes a204aef9fd77 ("xfrm: call xfrm_output_gso when inner_protocol is set in xfrm_output")
---
 net/xfrm/xfrm_output.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/xfrm/xfrm_output.c +1 -1
index 9160a5e09041d..a30538a980cc7 100644
@@ -793,7 +793,7 @@ int xfrm_output(struct sock *sk, struct sk_buff *skb)
 		skb->encapsulation = 1;
 
 		if (skb_is_gso(skb)) {
-			if (skb->inner_protocol)
+			if (skb->inner_protocol && x->props.mode == XFRM_MODE_TUNNEL)
 				return xfrm_output_gso(net, sk, skb);
 
 			skb_shinfo(skb)->gso_type |= SKB_GSO_ESP;
Signature · 1 line
2.39.5
author maintainer
#8 lore raw

PATCH 8/116 soc: imx8m: Remove global soc_uid

In reply to Greg Kroah-Hartman

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

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

From: Marek Vasut <[email protected]>

[ Upstream commit 9c1c02fe8d7f33c18547b79c41f3fa41ef7bae8f ]

The static global soc_uid is only ever used as kasprintf() parameter in imx8m_soc_probe(). Pass pointer to local u64 variable to .soc_revision() callback instead and let the .soc_revision() callback fill in the content. Remove the unnecessary static global variable.

Stable-dep-of: cf7139aac463 ("soc: imx8m: Unregister cpufreq and soc dev in cleanup path")

---
 drivers/soc/imx/soc-imx8m.c | 31 +++++++++++++++----------------
 1 file changed, 15 insertions(+), 16 deletions(-)
drivers/soc/imx/soc-imx8m.c +15 -16
index 5ea8887828c06..966593320e28d 100644
@@ -30,11 +30,9 @@
 
 struct imx8_soc_data {
 	char *name;
-	int (*soc_revision)(u32 *socrev);
+	int (*soc_revision)(u32 *socrev, u64 *socuid);
 };
 
-static u64 soc_uid;
-
 #ifdef CONFIG_HAVE_ARM_SMCCC
 static u32 imx8mq_soc_revision_from_atf(void)
 {
@@ -51,7 +49,7 @@ static u32 imx8mq_soc_revision_from_atf(void)
 static inline u32 imx8mq_soc_revision_from_atf(void) { return 0; };
 #endif
 
-static int imx8mq_soc_revision(u32 *socrev)
+static int imx8mq_soc_revision(u32 *socrev, u64 *socuid)
 {
 	struct device_node *np;
 	void __iomem *ocotp_base;
@@ -89,9 +87,9 @@ static int imx8mq_soc_revision(u32 *socrev)
 			rev = REV_B1;
 	}
 
-	soc_uid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH);
-	soc_uid <<= 32;
-	soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW);
+	*socuid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH);
+	*socuid <<= 32;
+	*socuid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW);
 
 	*socrev = rev;
 
@@ -109,7 +107,7 @@ static int imx8mq_soc_revision(u32 *socrev)
 	return ret;
 }
 
-static int imx8mm_soc_uid(void)
+static int imx8mm_soc_uid(u64 *socuid)
 {
 	void __iomem *ocotp_base;
 	struct device_node *np;
@@ -136,9 +134,9 @@ static int imx8mm_soc_uid(void)
 
 	clk_prepare_enable(clk);
 
-	soc_uid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH + offset);
-	soc_uid <<= 32;
-	soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW + offset);
+	*socuid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH + offset);
+	*socuid <<= 32;
+	*socuid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW + offset);
 
 	clk_disable_unprepare(clk);
 	clk_put(clk);
@@ -151,7 +149,7 @@ static int imx8mm_soc_uid(void)
 	return ret;
 }
 
-static int imx8mm_soc_revision(u32 *socrev)
+static int imx8mm_soc_revision(u32 *socrev, u64 *socuid)
 {
 	struct device_node *np;
 	void __iomem *anatop_base;
@@ -172,7 +170,7 @@ static int imx8mm_soc_revision(u32 *socrev)
 	iounmap(anatop_base);
 	of_node_put(np);
 
-	return imx8mm_soc_uid();
+	return imx8mm_soc_uid(socuid);
 
 err_iomap:
 	of_node_put(np);
@@ -215,10 +213,11 @@ static __maybe_unused const struct of_device_id imx8_soc_match[] = {
 static int imx8m_soc_probe(struct platform_device *pdev)
 {
 	struct soc_device_attribute *soc_dev_attr;
-	struct soc_device *soc_dev;
+	const struct imx8_soc_data *data;
 	const struct of_device_id *id;
+	struct soc_device *soc_dev;
 	u32 soc_rev = 0;
-	const struct imx8_soc_data *data;
+	u64 soc_uid = 0;
 	int ret;
 
 	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
@@ -241,7 +240,7 @@ static int imx8m_soc_probe(struct platform_device *pdev)
 	if (data) {
 		soc_dev_attr->soc_id = data->name;
 		if (data->soc_revision) {
-			ret = data->soc_revision(&soc_rev);
+			ret = data->soc_revision(&soc_rev, &soc_uid);
 			if (ret)
 				goto free_soc;
 		}
Signature · 1 line
2.39.5
author maintainer
#9 lore raw

PATCH 9/116 soc: imx8m: Use devm_* to simplify probe failure handling

In reply to Greg Kroah-Hartman

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

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

From: Marek Vasut <[email protected]>

[ Upstream commit 22b03a4e957e462b380a982759ccf0f6554735d3 ]

Use device managed functions to simplify handling of failures during probe. Remove fail paths which are no longer necessary.

Stable-dep-of: cf7139aac463 ("soc: imx8m: Unregister cpufreq and soc dev in cleanup path")

---
 drivers/soc/imx/soc-imx8m.c | 92 ++++++++++++-------------------------
 1 file changed, 29 insertions(+), 63 deletions(-)
drivers/soc/imx/soc-imx8m.c +29 -63
index 966593320e28d..8ac7658e3d525 100644
@@ -51,22 +51,20 @@ static inline u32 imx8mq_soc_revision_from_atf(void) { return 0; };
 
 static int imx8mq_soc_revision(u32 *socrev, u64 *socuid)
 {
-	struct device_node *np;
+	struct device_node *np __free(device_node) =
+		of_find_compatible_node(NULL, NULL, "fsl,imx8mq-ocotp");
 	void __iomem *ocotp_base;
 	u32 magic;
 	u32 rev;
 	struct clk *clk;
 	int ret;
 
-	np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-ocotp");
 	if (!np)
 		return -EINVAL;
 
 	ocotp_base = of_iomap(np, 0);
-	if (!ocotp_base) {
-		ret = -EINVAL;
-		goto err_iomap;
-	}
+	if (!ocotp_base)
+		return -EINVAL;
 
 	clk = of_clk_get_by_name(np, NULL);
 	if (IS_ERR(clk)) {
@@ -96,35 +94,30 @@ static int imx8mq_soc_revision(u32 *socrev, u64 *socuid)
 	clk_disable_unprepare(clk);
 	clk_put(clk);
 	iounmap(ocotp_base);
-	of_node_put(np);
 
 	return 0;
 
 err_clk:
 	iounmap(ocotp_base);
-err_iomap:
-	of_node_put(np);
 	return ret;
 }
 
 static int imx8mm_soc_uid(u64 *socuid)
 {
+	struct device_node *np __free(device_node) =
+		of_find_compatible_node(NULL, NULL, "fsl,imx8mm-ocotp");
 	void __iomem *ocotp_base;
-	struct device_node *np;
 	struct clk *clk;
 	int ret = 0;
 	u32 offset = of_machine_is_compatible("fsl,imx8mp") ?
 		     IMX8MP_OCOTP_UID_OFFSET : 0;
 
-	np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-ocotp");
 	if (!np)
 		return -EINVAL;
 
 	ocotp_base = of_iomap(np, 0);
-	if (!ocotp_base) {
-		ret = -EINVAL;
-		goto err_iomap;
-	}
+	if (!ocotp_base)
+		return -EINVAL;
 
 	clk = of_clk_get_by_name(np, NULL);
 	if (IS_ERR(clk)) {
@@ -143,38 +136,27 @@ static int imx8mm_soc_uid(u64 *socuid)
 
 err_clk:
 	iounmap(ocotp_base);
-err_iomap:
-	of_node_put(np);
-
 	return ret;
 }
 
 static int imx8mm_soc_revision(u32 *socrev, u64 *socuid)
 {
-	struct device_node *np;
+	struct device_node *np __free(device_node) =
+		of_find_compatible_node(NULL, NULL, "fsl,imx8mm-anatop");
 	void __iomem *anatop_base;
-	int ret;
 
-	np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-anatop");
 	if (!np)
 		return -EINVAL;
 
 	anatop_base = of_iomap(np, 0);
-	if (!anatop_base) {
-		ret = -EINVAL;
-		goto err_iomap;
-	}
+	if (!anatop_base)
+		return -EINVAL;
 
 	*socrev = readl_relaxed(anatop_base + ANADIG_DIGPROG_IMX8MM);
 
 	iounmap(anatop_base);
-	of_node_put(np);
 
 	return imx8mm_soc_uid(socuid);
-
-err_iomap:
-	of_node_put(np);
-	return ret;
 }
 
 static const struct imx8_soc_data imx8mq_soc_data = {
@@ -205,22 +187,23 @@ static __maybe_unused const struct of_device_id imx8_soc_match[] = {
 	{ }
 };
 
-#define imx8_revision(soc_rev) \
-	soc_rev ? \
-	kasprintf(GFP_KERNEL, "%d.%d", (soc_rev >> 4) & 0xf,  soc_rev & 0xf) : \
+#define imx8_revision(dev, soc_rev) \
+	(soc_rev) ? \
+	devm_kasprintf((dev), GFP_KERNEL, "%d.%d", ((soc_rev) >> 4) & 0xf, (soc_rev) & 0xf) : \
 	"unknown"
 
 static int imx8m_soc_probe(struct platform_device *pdev)
 {
 	struct soc_device_attribute *soc_dev_attr;
 	const struct imx8_soc_data *data;
+	struct device *dev = &pdev->dev;
 	const struct of_device_id *id;
 	struct soc_device *soc_dev;
 	u32 soc_rev = 0;
 	u64 soc_uid = 0;
 	int ret;
 
-	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+	soc_dev_attr = devm_kzalloc(dev, sizeof(*soc_dev_attr), GFP_KERNEL);
 	if (!soc_dev_attr)
 		return -ENOMEM;
 
@@ -228,13 +211,11 @@ static int imx8m_soc_probe(struct platform_device *pdev)
 
 	ret = of_property_read_string(of_root, "model", &soc_dev_attr->machine);
 	if (ret)
-		goto free_soc;
+		return ret;
 
 	id = of_match_node(imx8_soc_match, of_root);
-	if (!id) {
-		ret = -ENODEV;
-		goto free_soc;
-	}
+	if (!id)
+		return -ENODEV;
 
 	data = id->data;
 	if (data) {
@@ -242,27 +223,21 @@ static int imx8m_soc_probe(struct platform_device *pdev)
 		if (data->soc_revision) {
 			ret = data->soc_revision(&soc_rev, &soc_uid);
 			if (ret)
-				goto free_soc;
+				return ret;
 		}
 	}
 
-	soc_dev_attr->revision = imx8_revision(soc_rev);
-	if (!soc_dev_attr->revision) {
-		ret = -ENOMEM;
-		goto free_soc;
-	}
+	soc_dev_attr->revision = imx8_revision(dev, soc_rev);
+	if (!soc_dev_attr->revision)
+		return -ENOMEM;
 
-	soc_dev_attr->serial_number = kasprintf(GFP_KERNEL, "%016llX", soc_uid);
-	if (!soc_dev_attr->serial_number) {
-		ret = -ENOMEM;
-		goto free_rev;
-	}
+	soc_dev_attr->serial_number = devm_kasprintf(dev, GFP_KERNEL, "%016llX", soc_uid);
+	if (!soc_dev_attr->serial_number)
+		return -ENOMEM;
 
 	soc_dev = soc_device_register(soc_dev_attr);
-	if (IS_ERR(soc_dev)) {
-		ret = PTR_ERR(soc_dev);
-		goto free_serial_number;
-	}
+	if (IS_ERR(soc_dev))
+		return PTR_ERR(soc_dev);
 
 	pr_info("SoC: %s revision %s\n", soc_dev_attr->soc_id,
 		soc_dev_attr->revision);
@@ -271,15 +246,6 @@ static int imx8m_soc_probe(struct platform_device *pdev)
 		platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);
 
 	return 0;
-
-free_serial_number:
-	kfree(soc_dev_attr->serial_number);
-free_rev:
-	if (strcmp(soc_dev_attr->revision, "unknown"))
-		kfree(soc_dev_attr->revision);
-free_soc:
-	kfree(soc_dev_attr);
-	return ret;
 }
 
 static struct platform_driver imx8m_soc_driver = {
Signature · 1 line
2.39.5
author maintainer
#10 lore raw

PATCH 10/116 soc: imx8m: Unregister cpufreq and soc dev in cleanup path

In reply to Greg Kroah-Hartman

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

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

From: Peng Fan <[email protected]>

[ Upstream commit cf7139aac463880cbd5c5e999c118fbe91631411 ]

Unregister the cpufreq device and soc device when resource unwinding, otherwise there will be warning when do removing test:
sysfs: cannot create duplicate filename '/devices/platform/imx-cpufreq-dt'

CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.13.0-rc1-next-20241204
Hardware name: NXP i.MX8MPlus EVK board (DT)
Fixes 9cc832d37799 ("soc: imx8m: Probe the SoC driver as platform driver")
Cc Marco Felsch <[email protected]>
---
 drivers/soc/imx/soc-imx8m.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)
drivers/soc/imx/soc-imx8m.c +24 -2
index 8ac7658e3d525..3ed8161d7d28b 100644
@@ -192,9 +192,20 @@ static __maybe_unused const struct of_device_id imx8_soc_match[] = {
 	devm_kasprintf((dev), GFP_KERNEL, "%d.%d", ((soc_rev) >> 4) & 0xf, (soc_rev) & 0xf) : \
 	"unknown"
 
+static void imx8m_unregister_soc(void *data)
+{
+	soc_device_unregister(data);
+}
+
+static void imx8m_unregister_cpufreq(void *data)
+{
+	platform_device_unregister(data);
+}
+
 static int imx8m_soc_probe(struct platform_device *pdev)
 {
 	struct soc_device_attribute *soc_dev_attr;
+	struct platform_device *cpufreq_dev;
 	const struct imx8_soc_data *data;
 	struct device *dev = &pdev->dev;
 	const struct of_device_id *id;
@@ -239,11 +250,22 @@ static int imx8m_soc_probe(struct platform_device *pdev)
 	if (IS_ERR(soc_dev))
 		return PTR_ERR(soc_dev);
 
+	ret = devm_add_action(dev, imx8m_unregister_soc, soc_dev);
+	if (ret)
+		return ret;
+
 	pr_info("SoC: %s revision %s\n", soc_dev_attr->soc_id,
 		soc_dev_attr->revision);
 
-	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT))
-		platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);
+	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT)) {
+		cpufreq_dev = platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);
+		if (IS_ERR(cpufreq_dev))
+			return dev_err_probe(dev, PTR_ERR(cpufreq_dev),
+					     "Failed to register imx-cpufreq-dev device\n");
+		ret = devm_add_action(dev, imx8m_unregister_cpufreq, cpufreq_dev);
+		if (ret)
+			return ret;
+	}
 
 	return 0;
 }
Signature · 1 line
2.39.5
author maintainer
#11 lore raw

PATCH 11/116 ARM: dts: bcm2711: Fix xHCI power-domain

In reply to Greg Kroah-Hartman

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

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

From: Stefan Wahren <[email protected]>

[ Upstream commit f44fa354a0715577ca32b085f6f60bcf32c748dd ]

During s2idle tests on the Raspberry CM4 the VPU firmware always crashes on xHCI power-domain resume:

root@raspberrypi:/sys/power# echo freeze > state
[   70.724347] xhci_suspend finished
[   70.727730] xhci_plat_suspend finished
[   70.755624] bcm2835-power bcm2835-power: Power grafx off
[   70.761127]  USB: Set power to 0
[   74.653040]  USB: Failed to set power to 1 (-110)

This seems to be caused because of the mixed usage of raspberrypi-power and bcm2835-power at the same time. So avoid the usage of the VPU firmware power-domain driver, which prevents the VPU crash.

---
 arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi | 5 -----
 arch/arm/boot/dts/broadcom/bcm2711.dtsi     | 1 +
 2 files changed, 1 insertion(+), 5 deletions(-)
arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi +0 -5
index 6bf4241fe3b73..c78ed064d1667 100644
@@ -1,7 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include "bcm2835-rpi.dtsi"
 
-#include <dt-bindings/power/raspberrypi-power.h>
 #include <dt-bindings/reset/raspberrypi,firmware-reset.h>
 
 / {
@@ -101,7 +100,3 @@ &v3d {
 &vchiq {
 	interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
 };
-
-&xhci {
-	power-domains = <&power RPI_POWER_DOMAIN_USB>;
-};
arch/arm/boot/dts/broadcom/bcm2711.dtsi +1 -0
index e4e42af21ef3a..5eaec6c6a1df3 100644
@@ -610,6 +610,7 @@ xhci: usb@7e9c0000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
+			power-domains = <&pm BCM2835_POWER_DOMAIN_USB>;
 			/* DWC2 and this IP block share the same USB PHY,
 			 * enabling both at the same time results in lockups.
 			 * So keep this node disabled and let the bootloader
Signature · 1 line
2.39.5
author maintainer
#12 lore raw

PATCH 12/116 ARM: dts: bcm2711: PL011 UARTs are actually r1p5

In reply to Greg Kroah-Hartman

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

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

From: Phil Elwell <[email protected]>

[ Upstream commit 0de09025f161f67c07978c4742e221243d070d41 ]

The ARM PL011 UART instances in BCM2711 are r1p5 spec, which means they have 32-entry FIFOs. The correct periphid value for this is 0x00341011. Thanks to N Buchwitz for pointing this out.

Fixes 7dbe8c62ceeb ("ARM: dts: Add minimal Raspberry Pi 4 support")
---
 arch/arm/boot/dts/broadcom/bcm2711.dtsi | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
arch/arm/boot/dts/broadcom/bcm2711.dtsi +5 -4
index 5eaec6c6a1df3..4fd0732a34d32 100644
@@ -134,7 +134,7 @@ uart2: serial@7e201400 {
 			clocks = <&clocks BCM2835_CLOCK_UART>,
 				 <&clocks BCM2835_CLOCK_VPU>;
 			clock-names = "uartclk", "apb_pclk";
-			arm,primecell-periphid = <0x00241011>;
+			arm,primecell-periphid = <0x00341011>;
 			status = "disabled";
 		};
 
@@ -145,7 +145,7 @@ uart3: serial@7e201600 {
 			clocks = <&clocks BCM2835_CLOCK_UART>,
 				 <&clocks BCM2835_CLOCK_VPU>;
 			clock-names = "uartclk", "apb_pclk";
-			arm,primecell-periphid = <0x00241011>;
+			arm,primecell-periphid = <0x00341011>;
 			status = "disabled";
 		};
 
@@ -156,7 +156,7 @@ uart4: serial@7e201800 {
 			clocks = <&clocks BCM2835_CLOCK_UART>,
 				 <&clocks BCM2835_CLOCK_VPU>;
 			clock-names = "uartclk", "apb_pclk";
-			arm,primecell-periphid = <0x00241011>;
+			arm,primecell-periphid = <0x00341011>;
 			status = "disabled";
 		};
 
@@ -167,7 +167,7 @@ uart5: serial@7e201a00 {
 			clocks = <&clocks BCM2835_CLOCK_UART>,
 				 <&clocks BCM2835_CLOCK_VPU>;
 			clock-names = "uartclk", "apb_pclk";
-			arm,primecell-periphid = <0x00241011>;
+			arm,primecell-periphid = <0x00341011>;
 			status = "disabled";
 		};
 
@@ -1178,6 +1178,7 @@ &txp {
 };
 
 &uart0 {
+	arm,primecell-periphid = <0x00341011>;
 	interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
 };
 
Signature · 1 line
2.39.5
author maintainer
#13 lore raw

PATCH 13/116 arm64: dts: bcm2712: PL011 UARTs are actually r1p5

In reply to Greg Kroah-Hartman

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

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

From: Phil Elwell <[email protected]>

[ Upstream commit 768953614c1c13fdf771be5742f1be573eea8fa4 ]

The ARM PL011 UART instances in BCM2712 are r1p5 spec, which means they have 32-entry FIFOs. The correct periphid value for this is 0x00341011. Thanks to N Buchwitz for pointing this out.

Fixes faa3381267d0 ("arm64: dts: broadcom: Add minimal support for Raspberry Pi 5")
---
 arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/broadcom/bcm2712.dtsi +1 -1
index 26a29e5e5078d..447bfa060918c 100644
@@ -232,7 +232,7 @@ uart10: serial@7d001000 {
 			interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&clk_uart>, <&clk_vpu>;
 			clock-names = "uartclk", "apb_pclk";
-			arm,primecell-periphid = <0x00241011>;
+			arm,primecell-periphid = <0x00341011>;
 			status = "disabled";
 		};
 
Signature · 1 line
2.39.5
author maintainer
#14 lore raw

PATCH 14/116 arm64: dts: rockchip: Remove undocumented sdmmc property from lubancat-1

In reply to Greg Kroah-Hartman

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

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

From: Yao Zi <[email protected]>

[ Upstream commit 43c854c65e47d2f3763345683b06257b4d12e4e3 ]

Property "supports-sd" isn't documented anywhere and is unnecessary for mainline driver to function. It seems a property used by downstream kernel was brought into mainline.

This should be reported by dtbs_check, but mmc-controller-common.yaml defaults additionalProperties to true thus allows it. Remove the property to clean the devicetree up and avoid possible confusion.

Fixes 8d94da58de53 ("arm64: dts: rockchip: Add EmbedFire LubanCat 1")
---
 arch/arm64/boot/dts/rockchip/rk3566-lubancat-1.dts | 1 -
 1 file changed, 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3566-lubancat-1.dts +0 -1
index 9a2f59a351dee..48ccdd6b47118 100644
@@ -512,7 +512,6 @@ &sdhci {
 
 &sdmmc0 {
 	max-frequency = <150000000>;
-	supports-sd;
 	bus-width = <4>;
 	cap-mmc-highspeed;
 	cap-sd-highspeed;
Signature · 1 line
2.39.5
author maintainer
#15 lore raw

PATCH 15/116 RDMA/rxe: Fix the failure of ibv_query_device() and ibv_query_device_ex() tests

In reply to Greg Kroah-Hartman

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

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

From: Zhu Yanjun <[email protected]>

[ Upstream commit 8ce2eb9dfac8743d1c423b86339336a5b6a6069e ]

In rdma-core, the following failures appear.

"

$ ./build/bin/run_tests.py -k device
ssssssss....FF........s
======================================================================
FAIL: test_query_device (tests.test_device.DeviceTest.test_query_device)
Test ibv_query_device()
----------------------------------------------------------------------
Traceback (most recent call last):
   File "/home/ubuntu/rdma-core/tests/test_device.py", line 63, in
   test_query_device
     self.verify_device_attr(attr, dev)
   File "/home/ubuntu/rdma-core/tests/test_device.py", line 200, in
   verify_device_attr
     assert attr.sys_image_guid != 0
            ^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError

======================================================================
FAIL: test_query_device_ex (tests.test_device.DeviceTest.test_query_device_ex) Test ibv_query_device_ex()
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/ubuntu/rdma-core/tests/test_device.py", line 222, in test_query_device_ex
self.verify_device_attr(attr_ex.orig_attr, dev)
File "/home/ubuntu/rdma-core/tests/test_device.py", line 200, in verify_device_attr

     assert attr.sys_image_guid != 0
            ^^^^^^^^^^^^^^^^^^^^^^^^

AssertionError
"

The root cause is: before a net device is set with rxe, this net device is used to generate a sys_image_guid.

---
 drivers/infiniband/sw/rxe/rxe.c | 25 ++++++-------------------
 1 file changed, 6 insertions(+), 19 deletions(-)
drivers/infiniband/sw/rxe/rxe.c +6 -19
index 1ba4a0c8726ae..e27478fe9456c 100644
@@ -38,10 +38,8 @@ void rxe_dealloc(struct ib_device *ib_dev)
 }
 
 /* initialize rxe device parameters */
-static void rxe_init_device_param(struct rxe_dev *rxe)
+static void rxe_init_device_param(struct rxe_dev *rxe, struct net_device *ndev)
 {
-	struct net_device *ndev;
-
 	rxe->max_inline_data			= RXE_MAX_INLINE_DATA;
 
 	rxe->attr.vendor_id			= RXE_VENDOR_ID;
@@ -74,15 +72,9 @@ static void rxe_init_device_param(struct rxe_dev *rxe)
 	rxe->attr.max_pkeys			= RXE_MAX_PKEYS;
 	rxe->attr.local_ca_ack_delay		= RXE_LOCAL_CA_ACK_DELAY;
 
-	ndev = rxe_ib_device_get_netdev(&rxe->ib_dev);
-	if (!ndev)
-		return;
-
 	addrconf_addr_eui48((unsigned char *)&rxe->attr.sys_image_guid,
 			ndev->dev_addr);
 
-	dev_put(ndev);
-
 	rxe->max_ucontext			= RXE_MAX_UCONTEXT;
 }
 
@@ -115,18 +107,13 @@ static void rxe_init_port_param(struct rxe_port *port)
 /* initialize port state, note IB convention that HCA ports are always
  * numbered from 1
  */
-static void rxe_init_ports(struct rxe_dev *rxe)
+static void rxe_init_ports(struct rxe_dev *rxe, struct net_device *ndev)
 {
 	struct rxe_port *port = &rxe->port;
-	struct net_device *ndev;
 
 	rxe_init_port_param(port);
-	ndev = rxe_ib_device_get_netdev(&rxe->ib_dev);
-	if (!ndev)
-		return;
 	addrconf_addr_eui48((unsigned char *)&port->port_guid,
 			    ndev->dev_addr);
-	dev_put(ndev);
 	spin_lock_init(&port->port_lock);
 }
 
@@ -144,12 +131,12 @@ static void rxe_init_pools(struct rxe_dev *rxe)
 }
 
 /* initialize rxe device state */
-static void rxe_init(struct rxe_dev *rxe)
+static void rxe_init(struct rxe_dev *rxe, struct net_device *ndev)
 {
 	/* init default device parameters */
-	rxe_init_device_param(rxe);
+	rxe_init_device_param(rxe, ndev);
 
-	rxe_init_ports(rxe);
+	rxe_init_ports(rxe, ndev);
 	rxe_init_pools(rxe);
 
 	/* init pending mmap list */
@@ -184,7 +171,7 @@ void rxe_set_mtu(struct rxe_dev *rxe, unsigned int ndev_mtu)
 int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name,
 			struct net_device *ndev)
 {
-	rxe_init(rxe);
+	rxe_init(rxe, ndev);
 	rxe_set_mtu(rxe, mtu);
 
 	return rxe_register_device(rxe, ibdev_name, ndev);
Signature · 1 line
2.39.5
author maintainer
#16 lore raw

PATCH 16/116 RDMA/bnxt_re: Add missing paranthesis in map_qp_id_to_tbl_indx

In reply to Greg Kroah-Hartman

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

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

From: Kashyap Desai <[email protected]>

[ Upstream commit 67ee8d496511ad8e1cb88f72944847e7b3e4e47c ]

The modulo operation returns wrong result without the paranthesis and that resulted in wrong QP table indexing.

---
 drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/infiniband/hw/bnxt_re/qplib_rcfw.h +2 -1
index 07779aeb75759..a4deb45ec849f 100644
@@ -283,9 +283,10 @@ int bnxt_qplib_deinit_rcfw(struct bnxt_qplib_rcfw *rcfw);
 int bnxt_qplib_init_rcfw(struct bnxt_qplib_rcfw *rcfw,
 			 struct bnxt_qplib_ctx *ctx, int is_virtfn);
 void bnxt_qplib_mark_qp_error(void *qp_handle);
+
 static inline u32 map_qp_id_to_tbl_indx(u32 qid, struct bnxt_qplib_rcfw *rcfw)
 {
 	/* Last index of the qp_tbl is for QP1 ie. qp_tbl_size - 1*/
-	return (qid == 1) ? rcfw->qp_tbl_size - 1 : qid % rcfw->qp_tbl_size - 2;
+	return (qid == 1) ? rcfw->qp_tbl_size - 1 : (qid % (rcfw->qp_tbl_size - 2));
 }
 #endif /* __BNXT_QPLIB_RCFW_H__ */
Signature · 1 line
2.39.5
author maintainer
#17 lore raw

PATCH 17/116 RDMA/mlx5: Handle errors returned from mlx5r_ib_rate()

In reply to Greg Kroah-Hartman

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

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

From: Qasim Ijaz <[email protected]>

[ Upstream commit 556f93b90c1872ad85e216e613c0b33803e621cb ]

In function create_ib_ah() the following line attempts to left shift the return value of mlx5r_ib_rate() by 4 and store it in the stat_rate_sl member of av:

However the code overlooks the fact that mlx5r_ib_rate() may return -EINVAL if the rate passed to it is less than IB_RATE_2_5_GBPS or greater than IB_RATE_800_GBPS.

Because of this, the code may invoke undefined behaviour when shifting a signed negative value when doing "-EINVAL << 4".

To fix this check for errors before assigning stat_rate_sl and propagate any error value to the callers.

---
 drivers/infiniband/hw/mlx5/ah.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)
drivers/infiniband/hw/mlx5/ah.c +9 -5
index 99036afb3aef0..531a57f9ee7e8 100644
@@ -50,11 +50,12 @@ static __be16 mlx5_ah_get_udp_sport(const struct mlx5_ib_dev *dev,
 	return sport;
 }
 
-static void create_ib_ah(struct mlx5_ib_dev *dev, struct mlx5_ib_ah *ah,
+static int create_ib_ah(struct mlx5_ib_dev *dev, struct mlx5_ib_ah *ah,
 			 struct rdma_ah_init_attr *init_attr)
 {
 	struct rdma_ah_attr *ah_attr = init_attr->ah_attr;
 	enum ib_gid_type gid_type;
+	int rate_val;
 
 	if (rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH) {
 		const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr);
@@ -67,8 +68,10 @@ static void create_ib_ah(struct mlx5_ib_dev *dev, struct mlx5_ib_ah *ah,
 		ah->av.tclass = grh->traffic_class;
 	}
 
-	ah->av.stat_rate_sl =
-		(mlx5r_ib_rate(dev, rdma_ah_get_static_rate(ah_attr)) << 4);
+	rate_val = mlx5r_ib_rate(dev, rdma_ah_get_static_rate(ah_attr));
+	if (rate_val < 0)
+		return rate_val;
+	ah->av.stat_rate_sl = rate_val << 4;
 
 	if (ah_attr->type == RDMA_AH_ATTR_TYPE_ROCE) {
 		if (init_attr->xmit_slave)
@@ -89,6 +92,8 @@ static void create_ib_ah(struct mlx5_ib_dev *dev, struct mlx5_ib_ah *ah,
 		ah->av.fl_mlid = rdma_ah_get_path_bits(ah_attr) & 0x7f;
 		ah->av.stat_rate_sl |= (rdma_ah_get_sl(ah_attr) & 0xf);
 	}
+
+	return 0;
 }
 
 int mlx5_ib_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
@@ -121,8 +126,7 @@ int mlx5_ib_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
 			return err;
 	}
 
-	create_ib_ah(dev, ah, init_attr);
-	return 0;
+	return create_ib_ah(dev, ah, init_attr);
 }
 
 int mlx5_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
Signature · 1 line
2.39.5
author maintainer
#18 lore raw

PATCH 18/116 ARM: OMAP1: select CONFIG_GENERIC_IRQ_CHIP

In reply to Greg Kroah-Hartman

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

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

From: Arnd Bergmann <[email protected]>

[ Upstream commit 98f3ab18a0a55aa1ff2cd6b74bd0c02c8f76f17e ]

When GENERIC_IRQ_CHIP is disabled, OMAP1 kernels fail to link:

arm-linux-gnueabi-ld: arch/arm/mach-omap1/irq.o: in function `omap1_init_irq':
irq.c:(.init.text+0x1e8): undefined reference to `irq_alloc_generic_chip'
arm-linux-gnueabi-ld: irq.c:(.init.text+0x228): undefined reference to `irq_setup_generic_chip'
arm-linux-gnueabi-ld: irq.c:(.init.text+0x2a8): undefined reference to `irq_gc_set_wake'
arm-linux-gnueabi-ld: irq.c:(.init.text+0x2b0): undefined reference to `irq_gc_mask_set_bit'
arm-linux-gnueabi-ld: irq.c:(.init.text+0x2b4): undefined reference to `irq_gc_mask_clr_bit'

This has apparently been the case for many years, but I never caught it in randconfig builds until now, as there are dozens of other drivers that also 'select GENERIC_IRQ_CHIP' and statistically there is almost always one of them enabled.

Fixes 55b447744389 ("ARM: OMAP1: Switch to use generic irqchip in preparation for sparse IRQ")
---
 arch/arm/mach-omap1/Kconfig | 1 +
 1 file changed, 1 insertion(+)
arch/arm/mach-omap1/Kconfig +1 -0
index a643b71e30a35..08ec6bd84ada5 100644
@@ -8,6 +8,7 @@ menuconfig ARCH_OMAP1
 	select ARCH_OMAP
 	select CLKSRC_MMIO
 	select FORCE_PCI if PCCARD
+	select GENERIC_IRQ_CHIP
 	select GPIOLIB
 	help
 	  Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx)
Signature · 1 line
2.39.5
author maintainer
#19 lore raw

PATCH 19/116 ARM: dts: bcm2711: Dont mark timer regs unconfigured

In reply to Greg Kroah-Hartman

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

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

From: Phil Elwell <[email protected]>

[ Upstream commit c24f272ae751a9f54f8816430e7f2d56031892cc ]

During upstream process of Raspberry Pi 4 back in 2019 the ARMv7 stubs didn't configured the ARM architectural timer. This firmware issue has been fixed in 2020, which gave users enough time to update their system.

So drop this property to allow the use of the vDSO version of clock_gettime.

---
 arch/arm/boot/dts/broadcom/bcm2711.dtsi | 2 --
 1 file changed, 2 deletions(-)
arch/arm/boot/dts/broadcom/bcm2711.dtsi +0 -2
index 4fd0732a34d32..c06d9f5e53c80 100644
@@ -451,8 +451,6 @@ IRQ_TYPE_LEVEL_LOW)>,
 					  IRQ_TYPE_LEVEL_LOW)>,
 			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
 					  IRQ_TYPE_LEVEL_LOW)>;
-		/* This only applies to the ARMv7 stub */
-		arm,cpu-registers-not-fw-configured;
 	};
 
 	cpus: cpus {
Signature · 1 line
2.39.5
author maintainer
#20 lore raw

PATCH 20/116 ARM: dts: BCM5301X: Fix switch port labels of ASUS RT-AC5300

In reply to Greg Kroah-Hartman

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

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

From: Chester A. Unal <[email protected]>

[ Upstream commit 56e12d0c8d395b6e48f128858d4f725c1ded6c95 ]

After using the device for a while, Tom reports that he initially described the switch port labels incorrectly. Correct them.

---
 arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac5300.dts | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac5300.dts +4 -4
index 6c666dc7ad23e..01ec8c03686a6 100644
@@ -126,11 +126,11 @@ &srab {
 
 	ports {
 		port@0 {
-			label = "lan4";
+			label = "wan";
 		};
 
 		port@1 {
-			label = "lan3";
+			label = "lan1";
 		};
 
 		port@2 {
@@ -138,11 +138,11 @@ port@2 {
 		};
 
 		port@3 {
-			label = "lan1";
+			label = "lan3";
 		};
 
 		port@4 {
-			label = "wan";
+			label = "lan4";
 		};
 	};
 };
Signature · 1 line
2.39.5
author maintainer
#21 lore raw

PATCH 21/116 ARM: dts: BCM5301X: Fix switch port labels of ASUS RT-AC3200

In reply to Greg Kroah-Hartman

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

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

From: Chester A. Unal <[email protected]>

[ Upstream commit 24d4c56dd68906bf55ff8fc2e2d36760f97dce5f ]

After using the device for a while, Tom reports that he initially described the switch port labels incorrectly. Apparently, ASUS's own firmware also describes them incorrectly. Correct them to what is seen on the chassis.

---
 arch/arm/boot/dts/broadcom/bcm4709-asus-rt-ac3200.dts | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm/boot/dts/broadcom/bcm4709-asus-rt-ac3200.dts +4 -4
index 53cb0c58f6d05..3da2daee0c849 100644
@@ -124,19 +124,19 @@ port@0 {
 		};
 
 		port@1 {
-			label = "lan1";
+			label = "lan4";
 		};
 
 		port@2 {
-			label = "lan2";
+			label = "lan3";
 		};
 
 		port@3 {
-			label = "lan3";
+			label = "lan2";
 		};
 
 		port@4 {
-			label = "lan4";
+			label = "lan1";
 		};
 	};
 };
Signature · 1 line
2.39.5
author maintainer
#22 lore raw

PATCH 22/116 dma-mapping: fix missing clear bdr in check_ram_in_range_map()

In reply to Greg Kroah-Hartman

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

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

From: Baochen Qiang <[email protected]>

[ Upstream commit 8324993f60305e50f27b98358b01b9837e10d159 ]

As discussed in [1], if 'bdr' is set once, it would never get cleared, hence 0 is always returned.

Refactor the range check hunk into a new helper dma_find_range(), which allows 'bdr' to be cleared in each iteration.

Fixes a409d9600959 ("dma-mapping: fix dma_addressing_limited() if dma_range_map can't cover all system RAM")
---
 kernel/dma/direct.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)
kernel/dma/direct.c +18 -10
index 5b4e6d3bf7bcc..b8fe0b3d0ffb6 100644
@@ -584,6 +584,22 @@ int dma_direct_supported(struct device *dev, u64 mask)
 	return mask >= phys_to_dma_unencrypted(dev, min_mask);
 }
 
+static const struct bus_dma_region *dma_find_range(struct device *dev,
+						   unsigned long start_pfn)
+{
+	const struct bus_dma_region *m;
+
+	for (m = dev->dma_range_map; PFN_DOWN(m->size); m++) {
+		unsigned long cpu_start_pfn = PFN_DOWN(m->cpu_start);
+
+		if (start_pfn >= cpu_start_pfn &&
+		    start_pfn - cpu_start_pfn < PFN_DOWN(m->size))
+			return m;
+	}
+
+	return NULL;
+}
+
 /*
  * To check whether all ram resource ranges are covered by dma range map
  * Returns 0 when further check is needed
@@ -593,20 +609,12 @@ static int check_ram_in_range_map(unsigned long start_pfn,
 				  unsigned long nr_pages, void *data)
 {
 	unsigned long end_pfn = start_pfn + nr_pages;
-	const struct bus_dma_region *bdr = NULL;
-	const struct bus_dma_region *m;
 	struct device *dev = data;
 
 	while (start_pfn < end_pfn) {
-		for (m = dev->dma_range_map; PFN_DOWN(m->size); m++) {
-			unsigned long cpu_start_pfn = PFN_DOWN(m->cpu_start);
+		const struct bus_dma_region *bdr;
 
-			if (start_pfn >= cpu_start_pfn &&
-			    start_pfn - cpu_start_pfn < PFN_DOWN(m->size)) {
-				bdr = m;
-				break;
-			}
-		}
+		bdr = dma_find_range(dev, start_pfn);
 		if (!bdr)
 			return 1;
 
Signature · 1 line
2.39.5
author maintainer
#23 lore raw

PATCH 23/116 RDMA/bnxt_re: Avoid clearing VLAN_ID mask in modify qp path

In reply to Greg Kroah-Hartman

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

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

From: Saravanan Vajravel <[email protected]>

[ Upstream commit 81c0db302a674f8004ed805393d17fd76f552e83 ]

Driver is always clearing the mask that sets the VLAN ID/Service Level in the adapter. Recent change for supporting multiple traffic class exposed this issue.

Allow setting SL and VLAN_ID while QP is moved from INIT to RTR state.

Fixes 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver")
Fixes c64b16a37b6d ("RDMA/bnxt_re: Support different traffic class")
---
 drivers/infiniband/hw/bnxt_re/qplib_fp.c | 2 --
 1 file changed, 2 deletions(-)
drivers/infiniband/hw/bnxt_re/qplib_fp.c +0 -2
index 613b5fc70e13e..7436ce5515797 100644
@@ -1216,8 +1216,6 @@ static void __modify_flags_from_init_state(struct bnxt_qplib_qp *qp)
 			qp->path_mtu =
 				CMDQ_MODIFY_QP_PATH_MTU_MTU_2048;
 		}
-		qp->modify_flags &=
-			~CMDQ_MODIFY_QP_MODIFY_MASK_VLAN_ID;
 		/* Bono FW require the max_dest_rd_atomic to be >= 1 */
 		if (qp->max_dest_rd_atomic < 1)
 			qp->max_dest_rd_atomic = 1;
Signature · 1 line
2.39.5
author maintainer
#24 lore raw

PATCH 24/116 RDMA/hns: Fix soft lockup during bt pages loop

In reply to Greg Kroah-Hartman

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

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

From: Junxian Huang <[email protected]>

[ Upstream commit 25655580136de59ec89f09089dd28008ea440fc9 ]

Driver runs a for-loop when allocating bt pages and mapping them with buffer pages. When a large buffer (e.g. MR over 100GB) is being allocated, it may require a considerable loop count. This will lead to soft lockup:

        watchdog: BUG: soft lockup - CPU#27 stuck for 22s!
        ...
        Call trace:
         hem_list_alloc_mid_bt+0x124/0x394 [hns_roce_hw_v2]
         hns_roce_hem_list_request+0xf8/0x160 [hns_roce_hw_v2]
         hns_roce_mtr_create+0x2e4/0x360 [hns_roce_hw_v2]
         alloc_mr_pbl+0xd4/0x17c [hns_roce_hw_v2]
         hns_roce_reg_user_mr+0xf8/0x190 [hns_roce_hw_v2]
         ib_uverbs_reg_mr+0x118/0x290

        watchdog: BUG: soft lockup - CPU#35 stuck for 23s!
        ...
        Call trace:
         hns_roce_hem_list_find_mtt+0x7c/0xb0 [hns_roce_hw_v2]
         mtr_map_bufs+0xc4/0x204 [hns_roce_hw_v2]
         hns_roce_mtr_create+0x31c/0x3c4 [hns_roce_hw_v2]
         alloc_mr_pbl+0xb0/0x160 [hns_roce_hw_v2]
         hns_roce_reg_user_mr+0x108/0x1c0 [hns_roce_hw_v2]
         ib_uverbs_reg_mr+0x120/0x2bc

Add a cond_resched() to fix soft lockup during these loops. In order not to affect the allocation performance of normal-size buffer, set the loop count of a 100GB MR as the threshold to call cond_resched().

Fixes 38389eaa4db1 ("RDMA/hns: Add mtr support for mixed multihop addressing")
---
 drivers/infiniband/hw/hns/hns_roce_hem.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)
drivers/infiniband/hw/hns/hns_roce_hem.c +15 -1
index 605562122ecce..ca0798224e565 100644
@@ -1361,6 +1361,11 @@ static int hem_list_alloc_root_bt(struct hns_roce_dev *hr_dev,
 	return ret;
 }
 
+/* This is the bottom bt pages number of a 100G MR on 4K OS, assuming
+ * the bt page size is not expanded by cal_best_bt_pg_sz()
+ */
+#define RESCHED_LOOP_CNT_THRESHOLD_ON_4K 12800
+
 /* construct the base address table and link them by address hop config */
 int hns_roce_hem_list_request(struct hns_roce_dev *hr_dev,
 			      struct hns_roce_hem_list *hem_list,
@@ -1369,6 +1374,7 @@ int hns_roce_hem_list_request(struct hns_roce_dev *hr_dev,
 {
 	const struct hns_roce_buf_region *r;
 	int ofs, end;
+	int loop;
 	int unit;
 	int ret;
 	int i;
@@ -1386,7 +1392,10 @@ int hns_roce_hem_list_request(struct hns_roce_dev *hr_dev,
 			continue;
 
 		end = r->offset + r->count;
-		for (ofs = r->offset; ofs < end; ofs += unit) {
+		for (ofs = r->offset, loop = 1; ofs < end; ofs += unit, loop++) {
+			if (!(loop % RESCHED_LOOP_CNT_THRESHOLD_ON_4K))
+				cond_resched();
+
 			ret = hem_list_alloc_mid_bt(hr_dev, r, unit, ofs,
 						    hem_list->mid_bt[i],
 						    &hem_list->btm_bt);
@@ -1443,9 +1452,14 @@ void *hns_roce_hem_list_find_mtt(struct hns_roce_dev *hr_dev,
 	struct list_head *head = &hem_list->btm_bt;
 	struct hns_roce_hem_item *hem, *temp_hem;
 	void *cpu_base = NULL;
+	int loop = 1;
 	int nr = 0;
 
 	list_for_each_entry_safe(hem, temp_hem, head, sibling) {
+		if (!(loop % RESCHED_LOOP_CNT_THRESHOLD_ON_4K))
+			cond_resched();
+		loop++;
+
 		if (hem_list_page_is_in_range(hem, offset)) {
 			nr = offset - hem->start;
 			cpu_base = hem->addr + nr * BA_BYTE_LEN;
Signature · 1 line
2.39.5
author maintainer
#25 lore raw

PATCH 25/116 RDMA/hns: Fix unmatched condition in error path of alloc_user_qp_db()

In reply to Greg Kroah-Hartman

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

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

From: Junxian Huang <[email protected]>

[ Upstream commit b9f59a24ba35a7d955a9f8e148dd9f85b7b40a01 ]

Currently the condition of unmapping sdb in error path is not exactly the same as the condition of mapping in alloc_user_qp_db(). This may cause a problem of unmapping an unmapped db in some case, such as when the QP is XRC TGT. Unified the two conditions.

Fixes 90ae0b57e4a5 ("RDMA/hns: Combine enable flags of qp")
---
 drivers/infiniband/hw/hns/hns_roce_qp.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/infiniband/hw/hns/hns_roce_qp.c +5 -3
index 9e2e76c594063..a97348a1c61f1 100644
@@ -868,12 +868,14 @@ static int alloc_user_qp_db(struct hns_roce_dev *hr_dev,
 			    struct hns_roce_ib_create_qp *ucmd,
 			    struct hns_roce_ib_create_qp_resp *resp)
 {
+	bool has_sdb = user_qp_has_sdb(hr_dev, init_attr, udata, resp, ucmd);
 	struct hns_roce_ucontext *uctx = rdma_udata_to_drv_context(udata,
 		struct hns_roce_ucontext, ibucontext);
+	bool has_rdb = user_qp_has_rdb(hr_dev, init_attr, udata, resp);
 	struct ib_device *ibdev = &hr_dev->ib_dev;
 	int ret;
 
-	if (user_qp_has_sdb(hr_dev, init_attr, udata, resp, ucmd)) {
+	if (has_sdb) {
 		ret = hns_roce_db_map_user(uctx, ucmd->sdb_addr, &hr_qp->sdb);
 		if (ret) {
 			ibdev_err(ibdev,
@@ -884,7 +886,7 @@ static int alloc_user_qp_db(struct hns_roce_dev *hr_dev,
 		hr_qp->en_flags |= HNS_ROCE_QP_CAP_SQ_RECORD_DB;
 	}
 
-	if (user_qp_has_rdb(hr_dev, init_attr, udata, resp)) {
+	if (has_rdb) {
 		ret = hns_roce_db_map_user(uctx, ucmd->db_addr, &hr_qp->rdb);
 		if (ret) {
 			ibdev_err(ibdev,
@@ -898,7 +900,7 @@ static int alloc_user_qp_db(struct hns_roce_dev *hr_dev,
 	return 0;
 
 err_sdb:
-	if (hr_qp->en_flags & HNS_ROCE_QP_CAP_SQ_RECORD_DB)
+	if (has_sdb)
 		hns_roce_db_unmap_user(uctx, &hr_qp->sdb);
 err_out:
 	return ret;
Signature · 1 line
2.39.5
author maintainer
#26 lore raw

PATCH 26/116 RDMA/hns: Fix invalid sq params not being blocked

In reply to Greg Kroah-Hartman

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

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

From: Junxian Huang <[email protected]>

[ Upstream commit 13c90c222049764bb7e6a1689bd785f424bd8bd5 ]

SQ params from userspace are checked in by set_user_sq_size(). But when the check fails, the function doesn't return but instead keep running and overwrite 'ret'. As a result, the invalid params will not get blocked actually.

Add a return right after the failed check. Besides, although the check result of kernel sq params will not be overwritten, to keep coding style unified, move default_congest_type() before set_kernel_sq_size().

Fixes 6ec429d5887a ("RDMA/hns: Support userspace configuring congestion control algorithm with QP granularity")
---
 drivers/infiniband/hw/hns/hns_roce_qp.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)
drivers/infiniband/hw/hns/hns_roce_qp.c +4 -5
index a97348a1c61f1..8408f9a5c309d 100644
@@ -1121,24 +1121,23 @@ static int set_qp_param(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp,
 						 ibucontext);
 		hr_qp->config = uctx->config;
 		ret = set_user_sq_size(hr_dev, &init_attr->cap, hr_qp, ucmd);
-		if (ret)
+		if (ret) {
 			ibdev_err(ibdev,
 				  "failed to set user SQ size, ret = %d.\n",
 				  ret);
+			return ret;
+		}
 
 		ret = set_congest_param(hr_dev, hr_qp, ucmd);
-		if (ret)
-			return ret;
 	} else {
 		if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09)
 			hr_qp->config = HNS_ROCE_EXSGE_FLAGS;
+		default_congest_type(hr_dev, hr_qp);
 		ret = set_kernel_sq_size(hr_dev, &init_attr->cap, hr_qp);
 		if (ret)
 			ibdev_err(ibdev,
 				  "failed to set kernel SQ size, ret = %d.\n",
 				  ret);
-
-		default_congest_type(hr_dev, hr_qp);
 	}
 
 	return ret;
Signature · 1 line
2.39.5
author maintainer
#27 lore raw

PATCH 27/116 RDMA/hns: Fix a missing rollback in error path of hns_roce_create_qp_common()

In reply to Greg Kroah-Hartman

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

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

From: Junxian Huang <[email protected]>

[ Upstream commit 444907dd45cbe62fd69398805b6e2c626fab5b3a ]

When ib_copy_to_udata() fails in hns_roce_create_qp_common(), hns_roce_qp_remove() should be called in the error path to clean up resources in hns_roce_qp_store().

Fixes 0f00571f9433 ("RDMA/hns: Use new SQ doorbell register for HIP09")
---
 drivers/infiniband/hw/hns/hns_roce_qp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/hns/hns_roce_qp.c +1 -1
index 8408f9a5c309d..52b671156246b 100644
@@ -1220,7 +1220,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
 				       min(udata->outlen, sizeof(resp)));
 		if (ret) {
 			ibdev_err(ibdev, "copy qp resp failed!\n");
-			goto err_store;
+			goto err_flow_ctrl;
 		}
 	}
 
Signature · 1 line
2.39.5
author maintainer
#28 lore raw

PATCH 28/116 RDMA/hns: Fix missing xa_destroy()

In reply to Greg Kroah-Hartman

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

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

From: Junxian Huang <[email protected]>

[ Upstream commit eda0a2fdbc24c35cd8d61d9c9111cafd5f89b2dc ]

Add xa_destroy() for xarray in driver.

Fixes 5c1f167af112 ("RDMA/hns: Init SRQ table for hip08")
Fixes 27e19f451089 ("RDMA/hns: Convert cq_table to XArray")
Fixes 736b5a70db98 ("RDMA/hns: Convert qp_table_tree to XArray")
---
 drivers/infiniband/hw/hns/hns_roce_alloc.c | 4 +++-
 drivers/infiniband/hw/hns/hns_roce_cq.c    | 1 +
 drivers/infiniband/hw/hns/hns_roce_qp.c    | 1 +
 3 files changed, 5 insertions(+), 1 deletion(-)
drivers/infiniband/hw/hns/hns_roce_alloc.c +3 -1
index 950c133d4220e..6ee911f6885b5 100644
@@ -175,8 +175,10 @@ void hns_roce_cleanup_bitmap(struct hns_roce_dev *hr_dev)
 	if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_XRC)
 		ida_destroy(&hr_dev->xrcd_ida.ida);
 
-	if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_SRQ)
+	if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_SRQ) {
 		ida_destroy(&hr_dev->srq_table.srq_ida.ida);
+		xa_destroy(&hr_dev->srq_table.xa);
+	}
 	hns_roce_cleanup_qp_table(hr_dev);
 	hns_roce_cleanup_cq_table(hr_dev);
 	ida_destroy(&hr_dev->mr_table.mtpt_ida.ida);
drivers/infiniband/hw/hns/hns_roce_cq.c +1 -0
index 4106423a1b399..3a5c93c9fb3e6 100644
@@ -537,5 +537,6 @@ void hns_roce_cleanup_cq_table(struct hns_roce_dev *hr_dev)
 
 	for (i = 0; i < HNS_ROCE_CQ_BANK_NUM; i++)
 		ida_destroy(&hr_dev->cq_table.bank[i].ida);
+	xa_destroy(&hr_dev->cq_table.array);
 	mutex_destroy(&hr_dev->cq_table.bank_mutex);
 }
drivers/infiniband/hw/hns/hns_roce_qp.c +1 -0
index 52b671156246b..8901c142c1b65 100644
@@ -1603,6 +1603,7 @@ void hns_roce_cleanup_qp_table(struct hns_roce_dev *hr_dev)
 	for (i = 0; i < HNS_ROCE_QP_BANK_NUM; i++)
 		ida_destroy(&hr_dev->qp_table.bank[i].ida);
 	xa_destroy(&hr_dev->qp_table.dip_xa);
+	xa_destroy(&hr_dev->qp_table_xa);
 	mutex_destroy(&hr_dev->qp_table.bank_mutex);
 	mutex_destroy(&hr_dev->qp_table.scc_mutex);
 }
Signature · 1 line
2.39.5
author maintainer
#29 lore raw

PATCH 29/116 RDMA/hns: Fix wrong value of max_sge_rd

In reply to Greg Kroah-Hartman

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

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

From: Junxian Huang <[email protected]>

[ Upstream commit 6b5e41a8b51fce520bb09bd651a29ef495e990de ]

There is no difference between the sge of READ and non-READ operations in hns RoCE. Set max_sge_rd to the same value as max_send_sge.

Fixes 9a4435375cd1 ("IB/hns: Add driver files for hns RoCE driver")
---
 drivers/infiniband/hw/hns/hns_roce_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/hns/hns_roce_main.c +1 -1
index ae24c81c9812d..cf89a8db4f64c 100644
@@ -183,7 +183,7 @@ static int hns_roce_query_device(struct ib_device *ib_dev,
 				  IB_DEVICE_RC_RNR_NAK_GEN;
 	props->max_send_sge = hr_dev->caps.max_sq_sg;
 	props->max_recv_sge = hr_dev->caps.max_rq_sg;
-	props->max_sge_rd = 1;
+	props->max_sge_rd = hr_dev->caps.max_sq_sg;
 	props->max_cq = hr_dev->caps.num_cqs;
 	props->max_cqe = hr_dev->caps.max_cqes;
 	props->max_mr = hr_dev->caps.num_mtpts;
Signature · 1 line
2.39.5
author maintainer
#30 lore raw

PATCH 30/116 Bluetooth: Fix error code in chan_alloc_skb_cb()

In reply to Greg Kroah-Hartman

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

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

From: Dan Carpenter <[email protected]>

[ Upstream commit 72d061ee630d0dbb45c2920d8d19b3861c413e54 ]

The chan_alloc_skb_cb() function is supposed to return error pointers on error. Returning NULL will lead to a NULL dereference.

Fixes 6b8d4a6a0314 ("Bluetooth: 6LoWPAN: Use connected oriented channel instead of fixed one")
---
 net/bluetooth/6lowpan.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
net/bluetooth/6lowpan.c +6 -1
index 50cfec8ccac4f..3c29778171c58 100644
@@ -825,11 +825,16 @@ static struct sk_buff *chan_alloc_skb_cb(struct l2cap_chan *chan,
 					 unsigned long hdr_len,
 					 unsigned long len, int nb)
 {
+	struct sk_buff *skb;
+
 	/* Note that we must allocate using GFP_ATOMIC here as
 	 * this function is called originally from netdev hard xmit
 	 * function in atomic context.
 	 */
-	return bt_skb_alloc(hdr_len + len, GFP_ATOMIC);
+	skb = bt_skb_alloc(hdr_len + len, GFP_ATOMIC);
+	if (!skb)
+		return ERR_PTR(-ENOMEM);
+	return skb;
 }
 
 static void chan_suspend_cb(struct l2cap_chan *chan)
Signature · 1 line
2.39.5
author maintainer
#31 lore raw

PATCH 31/116 Bluetooth: hci_event: Fix connection regression between LE and non-LE adapters

In reply to Greg Kroah-Hartman

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

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

From: Arkadiusz Bokowy <[email protected]>

[ Upstream commit f6685a96c8c8a07e260e39bac86d4163cfb38a4d ]

Due to a typo during defining HCI errors it is not possible to connect LE-capable device with BR/EDR only adapter. The connection is terminated by the LE adapter because the invalid LL params error code is treated as unsupported remote feature.

Fixes 79c0868ad65a ("Bluetooth: hci_event: Use HCI error defines instead of magic values")
---
 include/net/bluetooth/hci.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/net/bluetooth/hci.h +1 -1
index 5bb4eaa52e14c..dd10e02bfc746 100644
@@ -683,7 +683,7 @@ enum {
 #define HCI_ERROR_REMOTE_POWER_OFF	0x15
 #define HCI_ERROR_LOCAL_HOST_TERM	0x16
 #define HCI_ERROR_PAIRING_NOT_ALLOWED	0x18
-#define HCI_ERROR_UNSUPPORTED_REMOTE_FEATURE	0x1e
+#define HCI_ERROR_UNSUPPORTED_REMOTE_FEATURE	0x1a
 #define HCI_ERROR_INVALID_LL_PARAMS	0x1e
 #define HCI_ERROR_UNSPECIFIED		0x1f
 #define HCI_ERROR_ADVERTISING_TIMEOUT	0x3c
Signature · 1 line
2.39.5
author maintainer
#32 lore raw

PATCH 32/116 accel/qaic: Fix possible data corruption in BOs > 2G

In reply to Greg Kroah-Hartman

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

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

From: Jeffrey Hugo <[email protected]>

[ Upstream commit 84a833d90635e4b846333e2df0ae72f9cbecac39 ]

When slicing a BO, we need to iterate through the BO's sgt to find the right pieces to construct the slice. Some of the data types chosen for this process are incorrectly too small, and can overflow. This can result in the incorrect slice construction, which can lead to data corruption in workload execution.

The device can only handle 32-bit sized transfers, and the scatterlist struct only supports 32-bit buffer sizes, so our upper limit for an individual transfer is an unsigned int. Using an int is incorrect due to the reservation of the sign bit. Upgrade the length of a scatterlist entry and the offsets into a scatterlist entry to unsigned int for a correct representation.

While each transfer may be limited to 32-bits, the overall BO may exceed that size. For counting the total length of the BO, we need a type that can represent the largest allocation possible on the system. That is the definition of size_t, so use it.

---
 drivers/accel/qaic/qaic_data.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/accel/qaic/qaic_data.c +4 -1
index c20eb63750f51..ffcdf5738d099 100644
@@ -172,9 +172,10 @@ static void free_slice(struct kref *kref)
 static int clone_range_of_sgt_for_slice(struct qaic_device *qdev, struct sg_table **sgt_out,
 					struct sg_table *sgt_in, u64 size, u64 offset)
 {
-	int total_len, len, nents, offf = 0, offl = 0;
 	struct scatterlist *sg, *sgn, *sgf, *sgl;
+	unsigned int len, nents, offf, offl;
 	struct sg_table *sgt;
+	size_t total_len;
 	int ret, j;
 
 	/* find out number of relevant nents needed for this mem */
@@ -182,6 +183,8 @@ static int clone_range_of_sgt_for_slice(struct qaic_device *qdev, struct sg_tabl
 	sgf = NULL;
 	sgl = NULL;
 	nents = 0;
+	offf = 0;
+	offl = 0;
 
 	size = size ? size : PAGE_SIZE;
 	for_each_sgtable_dma_sg(sgt_in, sg, j) {
Signature · 1 line
2.39.5
author maintainer
#33 lore raw

PATCH 33/116 ARM: davinci: da850: fix selecting ARCH_DAVINCI_DA8XX

In reply to Greg Kroah-Hartman

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

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

From: David Lechner <[email protected]>

[ Upstream commit 45d5fe1c53baaed1fb3043f45d1e15ebb4bbe86a ]

Chips in the DA850 family need to have ARCH_DAVINCI_DA8XX to be selected in order to enable some peripheral drivers.

This was accidentally removed in a previous commit.

Fixes dec85a95167a ("ARM: davinci: clean up platform support")
---
 arch/arm/mach-davinci/Kconfig | 1 +
 1 file changed, 1 insertion(+)
arch/arm/mach-davinci/Kconfig +1 -0
index 2a8a9fe46586d..3fa15f3422409 100644
@@ -27,6 +27,7 @@ config ARCH_DAVINCI_DA830
 
 config ARCH_DAVINCI_DA850
 	bool "DA850/OMAP-L138/AM18x based system"
+	select ARCH_DAVINCI_DA8XX
 	select DAVINCI_CP_INTC
 
 config ARCH_DAVINCI_DA8XX
Signature · 1 line
2.39.5
author maintainer
#34 lore raw

PATCH 34/116 tracing: tprobe-events: Fix to clean up tprobe correctly when module unload

In reply to Greg Kroah-Hartman

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

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

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

[ Upstream commit 0a8bb688aa824863716fc570d818b8659a79309d ]

When unloading module, the tprobe events are not correctly cleaned up. Thus it becomes fprobe-event and never be enabled again even if loading the same module again.

For example;

 # cd /sys/kernel/tracing
 # modprobe trace_events_sample
 # echo 't:my_tprobe foo_bar' >> dynamic_events
 # cat dynamic_events
t:tracepoints/my_tprobe foo_bar
 # rmmod trace_events_sample
 # cat dynamic_events
f:tracepoints/my_tprobe foo_bar

As you can see, the second time my_tprobe starts with 'f' instead of 't'.

This unregisters the fprobe and tracepoint callback when module is unloaded but marks the fprobe-event is tprobe-event.

Fixes 57a7e6de9e30 ("tracing/fprobe: Support raw tracepoints on future loaded modules")
---
 kernel/trace/trace_fprobe.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
kernel/trace/trace_fprobe.c +6 -3
index 99048c3303822..092c31907c71a 100644
@@ -977,10 +977,13 @@ static int __tracepoint_probe_module_cb(struct notifier_block *self,
 					reenable_trace_fprobe(tf);
 			}
 		} else if (val == MODULE_STATE_GOING && tp_mod->mod == tf->mod) {
-			tracepoint_probe_unregister(tf->tpoint,
+			unregister_fprobe(&tf->fp);
+			if (trace_fprobe_is_tracepoint(tf)) {
+				tracepoint_probe_unregister(tf->tpoint,
 					tf->tpoint->probestub, NULL);
-			tf->tpoint = NULL;
-			tf->mod = NULL;
+				tf->tpoint = TRACEPOINT_STUB;
+				tf->mod = NULL;
+			}
 		}
 	}
 	mutex_unlock(&event_mutex);
Signature · 1 line
2.39.5
#35 lore raw

Re: [PATCH 6.12 034/116] tracing: tprobe-events: Fix to clean up tprobe correctly when module unload

We found the kernel crashed when running kselftest (ftrace:ftracetest-ktap) in kernel 6.12.52 with the next trace:

[  321.365532] ------------[ cut here ]------------
[  321.368124] WARNING: CPU: 0 PID: 1132 at kernel/trace/ftrace.c:378 __unregister_ftrace_function+0x12a/0x1c0
[  321.373445] Modules linked in: intel_rapl_msr(E) intel_rapl_common(E) crct10dif_pclmul(E) ghash_clmulni_intel(E) sha512_ssse3(E) sha256_ssse3(E) sha1_ssse3(E) aesni_intel(E) crypto_simd(E) cryptd(E) rapl(E) snd_pcm(E) snd_timer(E) vmw_balloon(E) snd(E) vmwgfx(E) soundcore(E) drm_ttm_helper(E) vga16fb(E) ttm(E) vgastate(E) pcspkr(E) drm_kms_helper(E) vmw_vmci(E) ac(E) button(E) joydev(E) serio_raw(E) sg(E) openvswitch(E) nsh(E) nf_conncount(E) drm(E) dm_mod(E) fuse(E) autofs4(E) sd_mod(E) ata_generic(E) hid_generic(E) mptspi(E) ata_piix(E) mptscsih(E) mptbase(E) i2c_piix4(E) scsi_transport_spi(E) crc32_pclmul(E) libata(E) crc32c_intel(E) psmouse(E) ehci_pci(E) uhci_hcd(E) i2c_smbus(E) e1000(E) scsi_mod(E) ehci_hcd(E) scsi_common(E) [last unloaded: trace_events_sample(E)] [  321.404373] CPU: 0 UID: 0 PID: 1132 Comm: ftracetest Tainted: G            E      6.12.52 #4
[  321.408625] Tainted: [E]=UNSIGNED_MODULE
[  321.410729] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020
[  321.416039] RIP: 0010:__unregister_ftrace_function+0x12a/0x1c0
[  321.419046] Code: 00 48 8b 1d 48 7e ac 02 48 81 fb e0 09 df bd 0f 84 90 00 00 00 48 39 dd 0f 85 1d ff ff ff 48 c7 c0 b0 09 df bd e9 36 ff ff ff <0f> 0b b8 f0 ff ff ff e9 8a 03 ea 00 be ff ff ff ff 48 c7 c7 68 23
[  321.429097] RSP: 0018:ffffa0ba8106fb90 EFLAGS: 00010246
[  321.431997] RAX: 0000000000000000 RBX: ffff92a988808418 RCX: 0000000000000000
[  321.435654] RDX: 0000000000000000 RSI: ffffffffbc1be80c RDI: ffff92a988808418
[  321.439480] RBP: 00000000ffffffea R08: 0000000000000001 R09: 0000000000000000
[  321.443158] R10: ffffa0ba8106fb98 R11: 0000000080000000 R12: ffff92a988808620
[  321.446896] R13: ffffffffbb3905b0 R14: ffff92a985c012c0 R15: 00000000000041ed
[  321.450646] FS:  00007efce9408740(0000) GS:ffff92a9b9600000(0000) knlGS:0000000000000000
[  321.454781] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  321.457970] CR2: 00007fdc3c2d64c0 CR3: 000000010c79a000 CR4: 0000000000752ef0
[  321.462499] PKRU: 55555554
[  321.464322] Call Trace:
[  321.466060]  <TASK>
[  321.467592]  unregister_ftrace_function+0x35/0x170
[  321.470541]  ? __pfx_dyn_event_open+0x10/0x10
[  321.473070]  unregister_fprobe+0x4e/0x90
[  321.475486]  trace_fprobe_release+0x118/0x160
[  321.478052]  dyn_events_release_all+0xba/0xe0
[  321.480961]  dyn_event_open+0x46/0x50
[  321.483330]  do_dentry_open+0x160/0x460
[  321.485611]  vfs_open+0x30/0xf0
[  321.487524]  path_openat+0x66d/0xc60
[  321.489674]  do_filp_open+0xac/0x150
[  321.491860]  ? rcu_is_watching+0xd/0x50
[  321.494179]  ? _raw_spin_unlock+0x29/0x50
[  321.496489]  ? trace_preempt_on+0x80/0xc0
[  321.498966]  ? preempt_count_sub+0x92/0xd0
[  321.501451]  ? _raw_spin_unlock+0x29/0x50
[  321.503836]  do_sys_openat2+0x91/0xc0
[  321.505932]  __x64_sys_openat+0x6a/0xa0
[  321.508307]  do_syscall_64+0x87/0x140
[  321.510619]  ? do_syscall_64+0x93/0x140
[  321.512889]  ? do_syscall_64+0x93/0x140
[  321.515095]  ? trace_hardirqs_on_prepare+0x38/0xd0
[  321.517782]  ? syscall_exit_to_user_mode+0x80/0x170
[  321.520563]  ? do_syscall_64+0x93/0x140
[  321.522916]  ? do_syscall_64+0x93/0x140
[  321.525047]  ? clear_bhb_loop+0x60/0xb0
[  321.527358]  ? clear_bhb_loop+0x60/0xb0
[  321.529568]  ? clear_bhb_loop+0x60/0xb0
[  321.531867]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[  321.534549] RIP: 0033:0x7efce9502f01
[  321.536647] Code: 75 57 89 f0 25 00 00 41 00 3d 00 00 41 00 74 49 80 3d ea 26 0e 00 00 74 6d 89 da 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00 f0 ff ff 0f 87 93 00 00 00 48 8b 54 24 28 64 48 2b 14 25
[  321.545776] RSP: 002b:00007ffee609e920 EFLAGS: 00000202 ORIG_RAX: 0000000000000101
[  321.549681] RAX: ffffffffffffffda RBX: 0000000000000241 RCX: 00007efce9502f01
[  321.553486] RDX: 0000000000000241 RSI: 000056032f3378e8 RDI: 00000000ffffff9c
[  321.557137] RBP: 000056032f3378e8 R08: 000000000000000f R09: 0000000000000001
[  321.561025] R10: 00000000000001b6 R11: 0000000000000202 R12: 0000000000000000
[  321.564879] R13: 0000000000000003 R14: 000056032f337898 R15: 000056032f3378c0
[  321.568737]  </TASK>
[  321.570407] irq event stamp: 0
[  321.572420] hardirqs last  enabled at (0): [<0000000000000000>] 0x0
[  321.575750] hardirqs last disabled at (0): [<ffffffffbb18ad04>] copy_process+0xad4/0x2bf0
[  321.579887] softirqs last  enabled at (0): [<ffffffffbb18ad04>] copy_process+0xad4/0x2bf0
[  321.584131] softirqs last disabled at (0): [<0000000000000000>] 0x0
[  321.587407] ---[ end trace 0000000000000000 ]---
[  321.590005] BUG: kernel NULL pointer dereference, address: 000000000000002e
[  321.594462] #PF: supervisor read access in kernel mode
[  321.597485] #PF: error_code(0x0000) - not-present page
[  321.600377] PGD 0 P4D 0
[  321.602138] Oops: Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC NOPTI
[  321.605966] CPU: 2 UID: 0 PID: 1132 Comm: ftracetest Tainted: G        W   E      6.12.52 #4
[  321.610759] Tainted: [W]=WARN, [E]=UNSIGNED_MODULE
[  321.613608] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020
[  321.625523] RIP: 0010:trace_fprobe_release+0x135/0x160
[  321.628287] Code: e9 5a ff ff ff 48 89 ef e8 78 e9 ff ff 31 c0 b9 3e 00 00 00 48 89 ef f3 48 ab 48 8b bb 10 02 00 00 48 85 ff 0f 84 27 ff ff ff <48> 8b 77 30 31 d2 e8 c0 a6 f8 ff 48 c7 83 10 02 00 00 00 00 00 00
[  321.638446] RSP: 0018:ffffa0ba8106fbf0 EFLAGS: 00010282
[  321.641267] RAX: 0000000000000000 RBX: ffff92a988808400 RCX: 0000000000000000
[  321.644913] RDX: 0000000000000000 RSI: ffffffffbcabc8e0 RDI: fffffffffffffffe
[  321.648727] RBP: ffff92a988808418 R08: 0000000000000001 R09: 0000000000000000
[  321.652390] R10: 0000000000000000 R11: 0000000080000000 R12: ffff92a988808620
[  321.656067] R13: ffffffffbb3905b0 R14: ffff92a985c012c0 R15: 00000000000041ed
[  321.659841] FS:  00007efce9408740(0000) GS:ffff92a9b9680000(0000) knlGS:0000000000000000
[  321.663892] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  321.666927] CR2: 000000000000002e CR3: 000000010c79a000 CR4: 0000000000752ef0
[  321.671048] PKRU: 55555554
[  321.672617] Call Trace:
[  321.674080]  <TASK>
[  321.675439]  dyn_events_release_all+0xba/0xe0
[  321.677796]  dyn_event_open+0x46/0x50
[  321.679875]  do_dentry_open+0x160/0x460
[  321.681973]  vfs_open+0x30/0xf0
[  321.683816]  path_openat+0x66d/0xc60
[  321.685805]  do_filp_open+0xac/0x150
[  321.687823]  ? rcu_is_watching+0xd/0x50
[  321.689933]  ? _raw_spin_unlock+0x29/0x50
[  321.692269]  ? trace_preempt_on+0x80/0xc0
[  321.694623]  ? preempt_count_sub+0x92/0xd0
[  321.696919]  ? _raw_spin_unlock+0x29/0x50
[  321.699104]  do_sys_openat2+0x91/0xc0
[  321.701098]  __x64_sys_openat+0x6a/0xa0
[  321.703233]  do_syscall_64+0x87/0x140
[  321.705229]  ? do_syscall_64+0x93/0x140
[  321.707314]  ? do_syscall_64+0x93/0x140
[  321.709748]  ? trace_hardirqs_on_prepare+0x38/0xd0
[  321.712646]  ? syscall_exit_to_user_mode+0x80/0x170
[  321.715242]  ? do_syscall_64+0x93/0x140
[  321.717292]  ? do_syscall_64+0x93/0x140
[  321.719373]  ? clear_bhb_loop+0x60/0xb0
[  321.721412]  ? clear_bhb_loop+0x60/0xb0
[  321.723602]  ? clear_bhb_loop+0x60/0xb0
[  321.725925]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[  321.728644] RIP: 0033:0x7efce9502f01
[  321.730619] Code: 75 57 89 f0 25 00 00 41 00 3d 00 00 41 00 74 49 80 3d ea 26 0e 00 00 74 6d 89 da 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00 f0 ff ff 0f 87 93 00 00 00 48 8b 54 24 28 64 48 2b 14 25
[  321.739534] RSP: 002b:00007ffee609e920 EFLAGS: 00000202 ORIG_RAX: 0000000000000101
[  321.743467] RAX: ffffffffffffffda RBX: 0000000000000241 RCX: 00007efce9502f01
[  321.747137] RDX: 0000000000000241 RSI: 000056032f3378e8 RDI: 00000000ffffff9c
[  321.750552] RBP: 000056032f3378e8 R08: 000000000000000f R09: 0000000000000001
[  321.753932] R10: 00000000000001b6 R11: 0000000000000202 R12: 0000000000000000
[  321.757373] R13: 0000000000000003 R14: 000056032f337898 R15: 000056032f3378c0
[  321.761149]  </TASK>
[  321.762475] Modules linked in: intel_rapl_msr(E) intel_rapl_common(E) crct10dif_pclmul(E) ghash_clmulni_intel(E) sha512_ssse3(E) sha256_ssse3(E) sha1_ssse3(E) aesni_intel(E) crypto_simd(E) cryptd(E) rapl(E) snd_pcm(E) snd_timer(E) vmw_balloon(E) snd(E) vmwgfx(E) soundcore(E) drm_ttm_helper(E) vga16fb(E) ttm(E) vgastate(E) pcspkr(E) drm_kms_helper(E) vmw_vmci(E) ac(E) button(E) joydev(E) serio_raw(E) sg(E) openvswitch(E) nsh(E) nf_conncount(E) drm(E) dm_mod(E) fuse(E) autofs4(E) sd_mod(E) ata_generic(E) hid_generic(E) mptspi(E) ata_piix(E) mptscsih(E) mptbase(E) i2c_piix4(E) scsi_transport_spi(E) crc32_pclmul(E) libata(E) crc32c_intel(E) psmouse(E) ehci_pci(E) uhci_hcd(E) i2c_smbus(E) e1000(E) scsi_mod(E) ehci_hcd(E) scsi_common(E) [last unloaded: trace_events_sample(E)] [  321.793650] CR2: 000000000000002e
[  321.795444] ---[ end trace 0000000000000000 ]---
[  321.797783] RIP: 0010:trace_fprobe_release+0x135/0x160
[  321.800487] Code: e9 5a ff ff ff 48 89 ef e8 78 e9 ff ff 31 c0 b9 3e 00 00 00 48 89 ef f3 48 ab 48 8b bb 10 02 00 00 48 85 ff 0f 84 27 ff ff ff <48> 8b 77 30 31 d2 e8 c0 a6 f8 ff 48 c7 83 10 02 00 00 00 00 00 00
[  321.809544] RSP: 0018:ffffa0ba8106fbf0 EFLAGS: 00010282
[  321.812136] RAX: 0000000000000000 RBX: ffff92a988808400 RCX: 0000000000000000
[  321.815574] RDX: 0000000000000000 RSI: ffffffffbcabc8e0 RDI: fffffffffffffffe
[  321.819020] RBP: ffff92a988808418 R08: 0000000000000001 R09: 0000000000000000
[  321.822463] R10: 0000000000000000 R11: 0000000080000000 R12: ffff92a988808620
[  321.825928] R13: ffffffffbb3905b0 R14: ffff92a985c012c0 R15: 00000000000041ed
[  321.829385] FS:  00007efce9408740(0000) GS:ffff92a9b9680000(0000) knlGS:0000000000000000
[  321.833218] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  321.836153] CR2: 000000000000002e CR3: 000000010c79a000 CR4: 0000000000752ef0
[  321.839711] PKRU: 55555554
[  321.841241] Kernel panic - not syncing: Fatal exception
[  321.844568] Kernel Offset: 0x3a000000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
[  331.783046] ---[ end Kernel panic - not syncing: Fatal exception ]---

This panic was bisected to this particular commit and can be reproduced by running this specific subtest:

./ftracetest test.d/dynevent/add_remove_tprobe_module.tc

Regards,

Lenar Khannanov

#36 lore raw

Re: [PATCH 6.12 034/116] tracing: tprobe-events: Fix to clean up tprobe correctly when module unload

Quoted 141 lines · On Mon, 24 Nov 2025 11:06:41 +0000 Khannanov Lenar…

We found the kernel crashed when running kselftest (ftrace:ftracetest-ktap) in kernel 6.12.52 with the next trace:

[  321.365532] ------------[ cut here ]------------
[  321.368124] WARNING: CPU: 0 PID: 1132 at kernel/trace/ftrace.c:378 __unregister_ftrace_function+0x12a/0x1c0
[  321.373445] Modules linked in: intel_rapl_msr(E) intel_rapl_common(E) crct10dif_pclmul(E) ghash_clmulni_intel(E) sha512_ssse3(E) sha256_ssse3(E) sha1_ssse3(E) aesni_intel(E) crypto_simd(E) cryptd(E) rapl(E) snd_pcm(E) snd_timer(E) vmw_balloon(E) snd(E) vmwgfx(E) soundcore(E) drm_ttm_helper(E) vga16fb(E) ttm(E) vgastate(E) pcspkr(E) drm_kms_helper(E) vmw_vmci(E) ac(E) button(E) joydev(E) serio_raw(E) sg(E) openvswitch(E) nsh(E) nf_conncount(E) drm(E) dm_mod(E) fuse(E) autofs4(E) sd_mod(E) ata_generic(E) hid_generic(E) mptspi(E) ata_piix(E) mptscsih(E) mptbase(E) i2c_piix4(E) scsi_transport_spi(E) crc32_pclmul(E) libata(E) crc32c_intel(E) psmouse(E) ehci_pci(E) uhci_hcd(E) i2c_smbus(E) e1000(E) scsi_mod(E) ehci_hcd(E) scsi_common(E) [last unloaded: trace_events_sample(E)] [  321.404373] CPU: 0 UID: 0 PID: 1132 Comm: ftracetest Tainted: G            E      6.12.52 #4
[  321.408625] Tainted: [E]=UNSIGNED_MODULE
[  321.410729] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020
[  321.416039] RIP: 0010:__unregister_ftrace_function+0x12a/0x1c0
[  321.419046] Code: 00 48 8b 1d 48 7e ac 02 48 81 fb e0 09 df bd 0f 84 90 00 00 00 48 39 dd 0f 85 1d ff ff ff 48 c7 c0 b0 09 df bd e9 36 ff ff ff <0f> 0b b8 f0 ff ff ff e9 8a 03 ea 00 be ff ff ff ff 48 c7 c7 68 23
[  321.429097] RSP: 0018:ffffa0ba8106fb90 EFLAGS: 00010246
[  321.431997] RAX: 0000000000000000 RBX: ffff92a988808418 RCX: 0000000000000000
[  321.435654] RDX: 0000000000000000 RSI: ffffffffbc1be80c RDI: ffff92a988808418
[  321.439480] RBP: 00000000ffffffea R08: 0000000000000001 R09: 0000000000000000
[  321.443158] R10: ffffa0ba8106fb98 R11: 0000000080000000 R12: ffff92a988808620
[  321.446896] R13: ffffffffbb3905b0 R14: ffff92a985c012c0 R15: 00000000000041ed
[  321.450646] FS:  00007efce9408740(0000) GS:ffff92a9b9600000(0000) knlGS:0000000000000000
[  321.454781] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  321.457970] CR2: 00007fdc3c2d64c0 CR3: 000000010c79a000 CR4: 0000000000752ef0
[  321.462499] PKRU: 55555554
[  321.464322] Call Trace:
[  321.466060]  <TASK>
[  321.467592]  unregister_ftrace_function+0x35/0x170
[  321.470541]  ? __pfx_dyn_event_open+0x10/0x10
[  321.473070]  unregister_fprobe+0x4e/0x90
[  321.475486]  trace_fprobe_release+0x118/0x160
[  321.478052]  dyn_events_release_all+0xba/0xe0
[  321.480961]  dyn_event_open+0x46/0x50
[  321.483330]  do_dentry_open+0x160/0x460
[  321.485611]  vfs_open+0x30/0xf0
[  321.487524]  path_openat+0x66d/0xc60
[  321.489674]  do_filp_open+0xac/0x150
[  321.491860]  ? rcu_is_watching+0xd/0x50
[  321.494179]  ? _raw_spin_unlock+0x29/0x50
[  321.496489]  ? trace_preempt_on+0x80/0xc0
[  321.498966]  ? preempt_count_sub+0x92/0xd0
[  321.501451]  ? _raw_spin_unlock+0x29/0x50
[  321.503836]  do_sys_openat2+0x91/0xc0
[  321.505932]  __x64_sys_openat+0x6a/0xa0
[  321.508307]  do_syscall_64+0x87/0x140
[  321.510619]  ? do_syscall_64+0x93/0x140
[  321.512889]  ? do_syscall_64+0x93/0x140
[  321.515095]  ? trace_hardirqs_on_prepare+0x38/0xd0
[  321.517782]  ? syscall_exit_to_user_mode+0x80/0x170
[  321.520563]  ? do_syscall_64+0x93/0x140
[  321.522916]  ? do_syscall_64+0x93/0x140
[  321.525047]  ? clear_bhb_loop+0x60/0xb0
[  321.527358]  ? clear_bhb_loop+0x60/0xb0
[  321.529568]  ? clear_bhb_loop+0x60/0xb0
[  321.531867]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[  321.534549] RIP: 0033:0x7efce9502f01
[  321.536647] Code: 75 57 89 f0 25 00 00 41 00 3d 00 00 41 00 74 49 80 3d ea 26 0e 00 00 74 6d 89 da 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00 f0 ff ff 0f 87 93 00 00 00 48 8b 54 24 28 64 48 2b 14 25
[  321.545776] RSP: 002b:00007ffee609e920 EFLAGS: 00000202 ORIG_RAX: 0000000000000101
[  321.549681] RAX: ffffffffffffffda RBX: 0000000000000241 RCX: 00007efce9502f01
[  321.553486] RDX: 0000000000000241 RSI: 000056032f3378e8 RDI: 00000000ffffff9c
[  321.557137] RBP: 000056032f3378e8 R08: 000000000000000f R09: 0000000000000001
[  321.561025] R10: 00000000000001b6 R11: 0000000000000202 R12: 0000000000000000
[  321.564879] R13: 0000000000000003 R14: 000056032f337898 R15: 000056032f3378c0
[  321.568737]  </TASK>
[  321.570407] irq event stamp: 0
[  321.572420] hardirqs last  enabled at (0): [<0000000000000000>] 0x0
[  321.575750] hardirqs last disabled at (0): [<ffffffffbb18ad04>] copy_process+0xad4/0x2bf0
[  321.579887] softirqs last  enabled at (0): [<ffffffffbb18ad04>] copy_process+0xad4/0x2bf0
[  321.584131] softirqs last disabled at (0): [<0000000000000000>] 0x0
[  321.587407] ---[ end trace 0000000000000000 ]---
[  321.590005] BUG: kernel NULL pointer dereference, address: 000000000000002e
[  321.594462] #PF: supervisor read access in kernel mode
[  321.597485] #PF: error_code(0x0000) - not-present page
[  321.600377] PGD 0 P4D 0
[  321.602138] Oops: Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC NOPTI
[  321.605966] CPU: 2 UID: 0 PID: 1132 Comm: ftracetest Tainted: G        W   E      6.12.52 #4
[  321.610759] Tainted: [W]=WARN, [E]=UNSIGNED_MODULE
[  321.613608] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020
[  321.625523] RIP: 0010:trace_fprobe_release+0x135/0x160
[  321.628287] Code: e9 5a ff ff ff 48 89 ef e8 78 e9 ff ff 31 c0 b9 3e 00 00 00 48 89 ef f3 48 ab 48 8b bb 10 02 00 00 48 85 ff 0f 84 27 ff ff ff <48> 8b 77 30 31 d2 e8 c0 a6 f8 ff 48 c7 83 10 02 00 00 00 00 00 00
[  321.638446] RSP: 0018:ffffa0ba8106fbf0 EFLAGS: 00010282
[  321.641267] RAX: 0000000000000000 RBX: ffff92a988808400 RCX: 0000000000000000
[  321.644913] RDX: 0000000000000000 RSI: ffffffffbcabc8e0 RDI: fffffffffffffffe
[  321.648727] RBP: ffff92a988808418 R08: 0000000000000001 R09: 0000000000000000
[  321.652390] R10: 0000000000000000 R11: 0000000080000000 R12: ffff92a988808620
[  321.656067] R13: ffffffffbb3905b0 R14: ffff92a985c012c0 R15: 00000000000041ed
[  321.659841] FS:  00007efce9408740(0000) GS:ffff92a9b9680000(0000) knlGS:0000000000000000
[  321.663892] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  321.666927] CR2: 000000000000002e CR3: 000000010c79a000 CR4: 0000000000752ef0
[  321.671048] PKRU: 55555554
[  321.672617] Call Trace:
[  321.674080]  <TASK>
[  321.675439]  dyn_events_release_all+0xba/0xe0
[  321.677796]  dyn_event_open+0x46/0x50
[  321.679875]  do_dentry_open+0x160/0x460
[  321.681973]  vfs_open+0x30/0xf0
[  321.683816]  path_openat+0x66d/0xc60
[  321.685805]  do_filp_open+0xac/0x150
[  321.687823]  ? rcu_is_watching+0xd/0x50
[  321.689933]  ? _raw_spin_unlock+0x29/0x50
[  321.692269]  ? trace_preempt_on+0x80/0xc0
[  321.694623]  ? preempt_count_sub+0x92/0xd0
[  321.696919]  ? _raw_spin_unlock+0x29/0x50
[  321.699104]  do_sys_openat2+0x91/0xc0
[  321.701098]  __x64_sys_openat+0x6a/0xa0
[  321.703233]  do_syscall_64+0x87/0x140
[  321.705229]  ? do_syscall_64+0x93/0x140
[  321.707314]  ? do_syscall_64+0x93/0x140
[  321.709748]  ? trace_hardirqs_on_prepare+0x38/0xd0
[  321.712646]  ? syscall_exit_to_user_mode+0x80/0x170
[  321.715242]  ? do_syscall_64+0x93/0x140
[  321.717292]  ? do_syscall_64+0x93/0x140
[  321.719373]  ? clear_bhb_loop+0x60/0xb0
[  321.721412]  ? clear_bhb_loop+0x60/0xb0
[  321.723602]  ? clear_bhb_loop+0x60/0xb0
[  321.725925]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[  321.728644] RIP: 0033:0x7efce9502f01
[  321.730619] Code: 75 57 89 f0 25 00 00 41 00 3d 00 00 41 00 74 49 80 3d ea 26 0e 00 00 74 6d 89 da 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00 f0 ff ff 0f 87 93 00 00 00 48 8b 54 24 28 64 48 2b 14 25
[  321.739534] RSP: 002b:00007ffee609e920 EFLAGS: 00000202 ORIG_RAX: 0000000000000101
[  321.743467] RAX: ffffffffffffffda RBX: 0000000000000241 RCX: 00007efce9502f01
[  321.747137] RDX: 0000000000000241 RSI: 000056032f3378e8 RDI: 00000000ffffff9c
[  321.750552] RBP: 000056032f3378e8 R08: 000000000000000f R09: 0000000000000001
[  321.753932] R10: 00000000000001b6 R11: 0000000000000202 R12: 0000000000000000
[  321.757373] R13: 0000000000000003 R14: 000056032f337898 R15: 000056032f3378c0
[  321.761149]  </TASK>
[  321.762475] Modules linked in: intel_rapl_msr(E) intel_rapl_common(E) crct10dif_pclmul(E) ghash_clmulni_intel(E) sha512_ssse3(E) sha256_ssse3(E) sha1_ssse3(E) aesni_intel(E) crypto_simd(E) cryptd(E) rapl(E) snd_pcm(E) snd_timer(E) vmw_balloon(E) snd(E) vmwgfx(E) soundcore(E) drm_ttm_helper(E) vga16fb(E) ttm(E) vgastate(E) pcspkr(E) drm_kms_helper(E) vmw_vmci(E) ac(E) button(E) joydev(E) serio_raw(E) sg(E) openvswitch(E) nsh(E) nf_conncount(E) drm(E) dm_mod(E) fuse(E) autofs4(E) sd_mod(E) ata_generic(E) hid_generic(E) mptspi(E) ata_piix(E) mptscsih(E) mptbase(E) i2c_piix4(E) scsi_transport_spi(E) crc32_pclmul(E) libata(E) crc32c_intel(E) psmouse(E) ehci_pci(E) uhci_hcd(E) i2c_smbus(E) e1000(E) scsi_mod(E) ehci_hcd(E) scsi_common(E) [last unloaded: trace_events_sample(E)] [  321.793650] CR2: 000000000000002e
[  321.795444] ---[ end trace 0000000000000000 ]---
[  321.797783] RIP: 0010:trace_fprobe_release+0x135/0x160
[  321.800487] Code: e9 5a ff ff ff 48 89 ef e8 78 e9 ff ff 31 c0 b9 3e 00 00 00 48 89 ef f3 48 ab 48 8b bb 10 02 00 00 48 85 ff 0f 84 27 ff ff ff <48> 8b 77 30 31 d2 e8 c0 a6 f8 ff 48 c7 83 10 02 00 00 00 00 00 00
[  321.809544] RSP: 0018:ffffa0ba8106fbf0 EFLAGS: 00010282
[  321.812136] RAX: 0000000000000000 RBX: ffff92a988808400 RCX: 0000000000000000
[  321.815574] RDX: 0000000000000000 RSI: ffffffffbcabc8e0 RDI: fffffffffffffffe
[  321.819020] RBP: ffff92a988808418 R08: 0000000000000001 R09: 0000000000000000
[  321.822463] R10: 0000000000000000 R11: 0000000080000000 R12: ffff92a988808620
[  321.825928] R13: ffffffffbb3905b0 R14: ffff92a985c012c0 R15: 00000000000041ed
[  321.829385] FS:  00007efce9408740(0000) GS:ffff92a9b9680000(0000) knlGS:0000000000000000
[  321.833218] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  321.836153] CR2: 000000000000002e CR3: 000000010c79a000 CR4: 0000000000752ef0
[  321.839711] PKRU: 55555554
[  321.841241] Kernel panic - not syncing: Fatal exception
[  321.844568] Kernel Offset: 0x3a000000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
[  331.783046] ---[ end Kernel panic - not syncing: Fatal exception ]---

Quoted 4 lines

This panic was bisected to this particular commit and can be reproduced by running this specific subtest:

./ftracetest test.d/dynevent/add_remove_tprobe_module.tc

This might be fixed by the series of:

https://lore.kernel.org/all/176244792552.155515.3285089581362758469.stgit@devnote2/

Thanks,

Quoted 5 lines

Regards,

Lenar Khannanov

Signature · 1 line
Masami Hiramatsu (Google) <[email protected]>
author maintainer
#37 lore raw

PATCH 35/116 ata: libata-core: Add ATA_QUIRK_NO_LPM_ON_ATI for certain Samsung SSDs

In reply to Greg Kroah-Hartman

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

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

From: Niklas Cassel <[email protected]>

[ Upstream commit f2aac4c73c9945cce156fd58a9a2f31f2c8a90c7 ]

Before commit 7627a0edef54 ("ata: ahci: Drop low power policy board type") the ATI AHCI controllers specified board type 'board_ahci' rather than board type 'board_ahci'. This means that LPM was historically not enabled for the ATI AHCI controllers.

By looking at commit 7a8526a5cd51 ("libata: Add ATA_HORKAGE_NO_NCQ_ON_ATI for Samsung 860 and 870 SSD."), it is clear that, for some unknown reason, that Samsung SSDs do not play nice with ATI AHCI controllers. (When using other AHCI controllers, NCQ can be enabled on these Samsung SSDs without issues.)

In a similar way, from user reports, it is clear the ATI AHCI controllers can enable LPM on e.g. Maxtor HDDs perfectly fine, but when enabling LPM on certain Samsung SSDs, things break. (E.g. the SSDs will not get detected by the ATI AHCI controller even after a COMRESET.)

Yet, when using LPM on these Samsung SSDs with other AHCI controllers, e.g. Intel AHCI controllers, these Samsung drives appear to work perfectly fine.

Considering that the combination of ATI + Samsung, for some unknown reason, does not seem to work well, disable LPM when detecting an ATI AHCI controller with a problematic Samsung SSD.

Apply this new ATA_QUIRK_NO_LPM_ON_ATI quirk for all Samsung SSDs that have already been reported to not play nice with ATI (ATA_QUIRK_NO_NCQ_ON_ATI).

---
 drivers/ata/libata-core.c | 14 +++++++++++---
 include/linux/libata.h    |  2 ++
 2 files changed, 13 insertions(+), 3 deletions(-)
drivers/ata/libata-core.c +11 -3
index c085dd81ebe7f..d956735e2a764 100644
@@ -2845,6 +2845,10 @@ int ata_dev_configure(struct ata_device *dev)
 	    (id[ATA_ID_SATA_CAPABILITY] & 0xe) == 0x2)
 		dev->quirks |= ATA_QUIRK_NOLPM;
 
+	if (dev->quirks & ATA_QUIRK_NO_LPM_ON_ATI &&
+	    ata_dev_check_adapter(dev, PCI_VENDOR_ID_ATI))
+		dev->quirks |= ATA_QUIRK_NOLPM;
+
 	if (ap->flags & ATA_FLAG_NO_LPM)
 		dev->quirks |= ATA_QUIRK_NOLPM;
 
@@ -3897,6 +3901,7 @@ static const char * const ata_quirk_names[] = {
 	[__ATA_QUIRK_MAX_SEC_1024]	= "maxsec1024",
 	[__ATA_QUIRK_MAX_TRIM_128M]	= "maxtrim128m",
 	[__ATA_QUIRK_NO_NCQ_ON_ATI]	= "noncqonati",
+	[__ATA_QUIRK_NO_LPM_ON_ATI]	= "nolpmonati",
 	[__ATA_QUIRK_NO_ID_DEV_LOG]	= "noiddevlog",
 	[__ATA_QUIRK_NO_LOG_DIR]	= "nologdir",
 	[__ATA_QUIRK_NO_FUA]		= "nofua",
@@ -4142,13 +4147,16 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = {
 						ATA_QUIRK_ZERO_AFTER_TRIM },
 	{ "Samsung SSD 860*",		NULL,	ATA_QUIRK_NO_NCQ_TRIM |
 						ATA_QUIRK_ZERO_AFTER_TRIM |
-						ATA_QUIRK_NO_NCQ_ON_ATI },
+						ATA_QUIRK_NO_NCQ_ON_ATI |
+						ATA_QUIRK_NO_LPM_ON_ATI },
 	{ "Samsung SSD 870*",		NULL,	ATA_QUIRK_NO_NCQ_TRIM |
 						ATA_QUIRK_ZERO_AFTER_TRIM |
-						ATA_QUIRK_NO_NCQ_ON_ATI },
+						ATA_QUIRK_NO_NCQ_ON_ATI |
+						ATA_QUIRK_NO_LPM_ON_ATI },
 	{ "SAMSUNG*MZ7LH*",		NULL,	ATA_QUIRK_NO_NCQ_TRIM |
 						ATA_QUIRK_ZERO_AFTER_TRIM |
-						ATA_QUIRK_NO_NCQ_ON_ATI, },
+						ATA_QUIRK_NO_NCQ_ON_ATI |
+						ATA_QUIRK_NO_LPM_ON_ATI },
 	{ "FCCT*M500*",			NULL,	ATA_QUIRK_NO_NCQ_TRIM |
 						ATA_QUIRK_ZERO_AFTER_TRIM },
 
include/linux/libata.h +2 -0
index 9b4a6ff03235b..79974a99265fc 100644
@@ -88,6 +88,7 @@ enum ata_quirks {
 	__ATA_QUIRK_MAX_SEC_1024,	/* Limit max sects to 1024 */
 	__ATA_QUIRK_MAX_TRIM_128M,	/* Limit max trim size to 128M */
 	__ATA_QUIRK_NO_NCQ_ON_ATI,	/* Disable NCQ on ATI chipset */
+	__ATA_QUIRK_NO_LPM_ON_ATI,	/* Disable LPM on ATI chipset */
 	__ATA_QUIRK_NO_ID_DEV_LOG,	/* Identify device log missing */
 	__ATA_QUIRK_NO_LOG_DIR,		/* Do not read log directory */
 	__ATA_QUIRK_NO_FUA,		/* Do not use FUA */
@@ -434,6 +435,7 @@ enum {
 	ATA_QUIRK_MAX_SEC_1024		= (1U << __ATA_QUIRK_MAX_SEC_1024),
 	ATA_QUIRK_MAX_TRIM_128M		= (1U << __ATA_QUIRK_MAX_TRIM_128M),
 	ATA_QUIRK_NO_NCQ_ON_ATI		= (1U << __ATA_QUIRK_NO_NCQ_ON_ATI),
+	ATA_QUIRK_NO_LPM_ON_ATI		= (1U << __ATA_QUIRK_NO_LPM_ON_ATI),
 	ATA_QUIRK_NO_ID_DEV_LOG		= (1U << __ATA_QUIRK_NO_ID_DEV_LOG),
 	ATA_QUIRK_NO_LOG_DIR		= (1U << __ATA_QUIRK_NO_LOG_DIR),
 	ATA_QUIRK_NO_FUA		= (1U << __ATA_QUIRK_NO_FUA),
Signature · 1 line
2.39.5
author maintainer
#38 lore raw

PATCH 36/116 net: ethernet: ti: am65-cpsw: Fix NAPI registration sequence

In reply to Greg Kroah-Hartman

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

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

From: Vignesh Raghavendra <[email protected]>

[ Upstream commit 5f079290e5913a0060e059500b7d440990ac1066 ]

Registering the interrupts for TX or RX DMA Channels prior to registering their respective NAPI callbacks can result in a NULL pointer dereference. This is seen in practice as a random occurrence since it depends on the randomness associated with the generation of traffic by Linux and the reception of traffic from the wire.

---
 drivers/net/ethernet/ti/am65-cpsw-nuss.c | 32 +++++++++++++-----------
 1 file changed, 18 insertions(+), 14 deletions(-)
drivers/net/ethernet/ti/am65-cpsw-nuss.c +18 -14
index 3e090f87f97eb..308a2b72a65de 100644
@@ -2225,14 +2225,18 @@ static void am65_cpsw_nuss_remove_tx_chns(struct am65_cpsw_common *common)
 static int am65_cpsw_nuss_ndev_add_tx_napi(struct am65_cpsw_common *common)
 {
 	struct device *dev = common->dev;
+	struct am65_cpsw_tx_chn *tx_chn;
 	int i, ret = 0;
 
 	for (i = 0; i < common->tx_ch_num; i++) {
-		struct am65_cpsw_tx_chn *tx_chn = &common->tx_chns[i];
+		tx_chn = &common->tx_chns[i];
 
 		hrtimer_init(&tx_chn->tx_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_PINNED);
 		tx_chn->tx_hrtimer.function = &am65_cpsw_nuss_tx_timer_callback;
 
+		netif_napi_add_tx(common->dma_ndev, &tx_chn->napi_tx,
+				  am65_cpsw_nuss_tx_poll);
+
 		ret = devm_request_irq(dev, tx_chn->irq,
 				       am65_cpsw_nuss_tx_irq,
 				       IRQF_TRIGGER_HIGH,
@@ -2242,19 +2246,16 @@ static int am65_cpsw_nuss_ndev_add_tx_napi(struct am65_cpsw_common *common)
 				tx_chn->id, tx_chn->irq, ret);
 			goto err;
 		}
-
-		netif_napi_add_tx(common->dma_ndev, &tx_chn->napi_tx,
-				  am65_cpsw_nuss_tx_poll);
 	}
 
 	return 0;
 
 err:
-	for (--i ; i >= 0 ; i--) {
-		struct am65_cpsw_tx_chn *tx_chn = &common->tx_chns[i];
-
-		netif_napi_del(&tx_chn->napi_tx);
+	netif_napi_del(&tx_chn->napi_tx);
+	for (--i; i >= 0; i--) {
+		tx_chn = &common->tx_chns[i];
 		devm_free_irq(dev, tx_chn->irq, tx_chn);
+		netif_napi_del(&tx_chn->napi_tx);
 	}
 
 	return ret;
@@ -2488,6 +2489,9 @@ static int am65_cpsw_nuss_init_rx_chns(struct am65_cpsw_common *common)
 			     HRTIMER_MODE_REL_PINNED);
 		flow->rx_hrtimer.function = &am65_cpsw_nuss_rx_timer_callback;
 
+		netif_napi_add(common->dma_ndev, &flow->napi_rx,
+			       am65_cpsw_nuss_rx_poll);
+
 		ret = devm_request_irq(dev, flow->irq,
 				       am65_cpsw_nuss_rx_irq,
 				       IRQF_TRIGGER_HIGH,
@@ -2496,11 +2500,8 @@ static int am65_cpsw_nuss_init_rx_chns(struct am65_cpsw_common *common)
 			dev_err(dev, "failure requesting rx %d irq %u, %d\n",
 				i, flow->irq, ret);
 			flow->irq = -EINVAL;
-			goto err_flow;
+			goto err_request_irq;
 		}
-
-		netif_napi_add(common->dma_ndev, &flow->napi_rx,
-			       am65_cpsw_nuss_rx_poll);
 	}
 
 	/* setup classifier to route priorities to flows */
@@ -2508,11 +2509,14 @@ static int am65_cpsw_nuss_init_rx_chns(struct am65_cpsw_common *common)
 
 	return 0;
 
+err_request_irq:
+	netif_napi_del(&flow->napi_rx);
+
 err_flow:
-	for (--i; i >= 0 ; i--) {
+	for (--i; i >= 0; i--) {
 		flow = &rx_chn->flows[i];
-		netif_napi_del(&flow->napi_rx);
 		devm_free_irq(dev, flow->irq, flow);
+		netif_napi_del(&flow->napi_rx);
 	}
 
 err:
Signature · 1 line
2.39.5
author maintainer
#39 lore raw

PATCH 37/116 net: ipv6: fix TCP GSO segmentation with NAT

In reply to Greg Kroah-Hartman

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

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

From: Felix Fietkau <[email protected]>

[ Upstream commit daa624d3c2ddffdcbad140a9625a4064371db44f ]

When updating the source/destination address, the TCP/UDP checksum needs to be updated as well.

Fixes bee88cd5bd83 ("net: add support for segmenting TCP fraglist GSO packets")
---
 net/ipv6/tcpv6_offload.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)
net/ipv6/tcpv6_offload.c +15 -6
index a45bf17cb2a17..ae2da28f9dfb1 100644
@@ -94,14 +94,23 @@ INDIRECT_CALLABLE_SCOPE int tcp6_gro_complete(struct sk_buff *skb, int thoff)
 }
 
 static void __tcpv6_gso_segment_csum(struct sk_buff *seg,
+				     struct in6_addr *oldip,
+				     const struct in6_addr *newip,
 				     __be16 *oldport, __be16 newport)
 {
-	struct tcphdr *th;
+	struct tcphdr *th = tcp_hdr(seg);
+
+	if (!ipv6_addr_equal(oldip, newip)) {
+		inet_proto_csum_replace16(&th->check, seg,
+					  oldip->s6_addr32,
+					  newip->s6_addr32,
+					  true);
+		*oldip = *newip;
+	}
 
 	if (*oldport == newport)
 		return;
 
-	th = tcp_hdr(seg);
 	inet_proto_csum_replace2(&th->check, seg, *oldport, newport, false);
 	*oldport = newport;
 }
@@ -129,10 +138,10 @@ static struct sk_buff *__tcpv6_gso_segment_list_csum(struct sk_buff *segs)
 		th2 = tcp_hdr(seg);
 		iph2 = ipv6_hdr(seg);
 
-		iph2->saddr = iph->saddr;
-		iph2->daddr = iph->daddr;
-		__tcpv6_gso_segment_csum(seg, &th2->source, th->source);
-		__tcpv6_gso_segment_csum(seg, &th2->dest, th->dest);
+		__tcpv6_gso_segment_csum(seg, &iph2->saddr, &iph->saddr,
+					 &th2->source, th->source);
+		__tcpv6_gso_segment_csum(seg, &iph2->daddr, &iph->daddr,
+					 &th2->dest, th->dest);
 	}
 
 	return segs;
Signature · 1 line
2.39.5
author maintainer
#40 lore raw

PATCH 38/116 ipv6: Fix memleak of nhc_pcpu_rth_output in fib_check_nh_v6_gw().

In reply to Greg Kroah-Hartman

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

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

From: Kuniyuki Iwashima <[email protected]>

[ Upstream commit 9740890ee20e01f99ff1dde84c63dcf089fabb98 ]

fib_check_nh_v6_gw() expects that fib6_nh_init() cleans up everything when it fails.

Commit 7dd73168e273 ("ipv6: Always allocate pcpu memory in a fib6_nh") moved fib_nh_common_init() before alloc_percpu_gfp() within fib6_nh_init() but forgot to add cleanup for fib6_nh->nh_common.nhc_pcpu_rth_output in case it fails to allocate fib6_nh->rt6i_pcpu, resulting in memleak.

Let's call fib_nh_common_release() and clear nhc_pcpu_rth_output in the error path.

Note that we can remove the fib6_nh_release() call in nh_create_ipv6() later in net-next.git.

Fixes 7dd73168e273 ("ipv6: Always allocate pcpu memory in a fib6_nh")
---
 net/ipv6/route.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
net/ipv6/route.c +2 -1
index 2736dea77575b..e9a30978abac1 100644
@@ -3644,7 +3644,8 @@ int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh,
 		in6_dev_put(idev);
 
 	if (err) {
-		lwtstate_put(fib6_nh->fib_nh_lws);
+		fib_nh_common_release(&fib6_nh->nh_common);
+		fib6_nh->nh_common.nhc_pcpu_rth_output = NULL;
 		fib6_nh->fib_nh_lws = NULL;
 		netdev_put(dev, dev_tracker);
 	}
Signature · 1 line
2.39.5
author maintainer
#41 lore raw

PATCH 39/116 ipv6: Set errno after ip_fib_metrics_init() in ip6_route_info_create().

In reply to Greg Kroah-Hartman

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

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

From: Kuniyuki Iwashima <[email protected]>

[ Upstream commit 9a81fc3480bf5dbe2bf80e278c440770f6ba2692 ]

While creating a new IPv6, we could get a weird -ENOMEM when RTA_NH_ID is set and either of the conditions below is true:

1) CONFIG_IPV6_SUBTREES is enabled and rtm_src_len is specified
2) nexthop_get() fails

e.g.)

  # strace ip -6 route add fe80::dead:beef:dead:beef nhid 1 from ::
  recvmsg(3, {msg_iov=[{iov_base=[...[
    {error=-ENOMEM, msg=[... [...]]},
    [{nla_len=49, nla_type=NLMSGERR_ATTR_MSG}, "Nexthops can not be used with so"...]
  ]], iov_len=32768}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 148

Let's set err explicitly after ip_fib_metrics_init() in ip6_route_info_create().

Fixes f88d8ea67fbd ("ipv6: Plumb support for nexthop object in a fib6_info")
---
 net/ipv6/route.c | 2 ++
 1 file changed, 2 insertions(+)
net/ipv6/route.c +2 -0
index e9a30978abac1..b393c37d24245 100644
@@ -3803,10 +3803,12 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
 	if (nh) {
 		if (rt->fib6_src.plen) {
 			NL_SET_ERR_MSG(extack, "Nexthops can not be used with source routing");
+			err = -EINVAL;
 			goto out_free;
 		}
 		if (!nexthop_get(nh)) {
 			NL_SET_ERR_MSG(extack, "Nexthop has been deleted");
+			err = -ENOENT;
 			goto out_free;
 		}
 		rt->nh = nh;
Signature · 1 line
2.39.5
author maintainer
#42 lore raw

PATCH 40/116 devlink: fix xa_alloc_cyclic() error handling

In reply to Greg Kroah-Hartman

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

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

From: Michal Swiatkowski <[email protected]>

[ Upstream commit f3b97b7d4bf316c3991e5634c9f4847c2df35478 ]

In case of returning 1 from xa_alloc_cyclic() (wrapping) ERR_PTR(1) will be returned, which will cause IS_ERR() to be false. Which can lead to dereference not allocated pointer (rel).

Fix it by checking if err is lower than zero.

This wasn't found in real usecase, only noticed. Credit to Pierre.

Fixes c137743bce02 ("devlink: introduce object and nested devlink relationship infra")
---
 net/devlink/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/devlink/core.c +1 -1
index f49cd83f1955f..7203c39532fcc 100644
@@ -117,7 +117,7 @@ static struct devlink_rel *devlink_rel_alloc(void)
 
 	err = xa_alloc_cyclic(&devlink_rels, &rel->index, rel,
 			      xa_limit_32b, &next, GFP_KERNEL);
-	if (err) {
+	if (err < 0) {
 		kfree(rel);
 		return ERR_PTR(err);
 	}
Signature · 1 line
2.39.5
author maintainer
#43 lore raw

PATCH 41/116 dpll: fix xa_alloc_cyclic() error handling

In reply to Greg Kroah-Hartman

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

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

From: Michal Swiatkowski <[email protected]>

[ Upstream commit 3614bf90130d60f191a5fe218d04f6251c678e13 ]

In case of returning 1 from xa_alloc_cyclic() (wrapping) ERR_PTR(1) will be returned, which will cause IS_ERR() to be false. Which can lead to dereference not allocated pointer (pin).

Fix it by checking if err is lower than zero.

This wasn't found in real usecase, only noticed. Credit to Pierre.

---
 drivers/dpll/dpll_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/dpll/dpll_core.c +1 -1
index 32019dc33cca7..1877201d1aa9f 100644
@@ -505,7 +505,7 @@ dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module,
 	xa_init_flags(&pin->parent_refs, XA_FLAGS_ALLOC);
 	ret = xa_alloc_cyclic(&dpll_pin_xa, &pin->id, pin, xa_limit_32b,
 			      &dpll_pin_xa_id, GFP_KERNEL);
-	if (ret)
+	if (ret < 0)
 		goto err_xa_alloc;
 	return pin;
 err_xa_alloc:
Signature · 1 line
2.39.5
author maintainer
#44 lore raw

PATCH 42/116 phy: fix xa_alloc_cyclic() error handling

In reply to Greg Kroah-Hartman

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

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

From: Michal Swiatkowski <[email protected]>

[ Upstream commit 3178d2b048365fe2c078cd53f85f2abf1487733b ]

xa_alloc_cyclic() can return 1, which isn't an error. To prevent situation when the caller of this function will treat it as no error do a check only for negative here.

Fixes 384968786909 ("net: phy: Introduce ethernet link topology representation")
---
 drivers/net/phy/phy_link_topology.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/phy/phy_link_topology.c +1 -1
index 4a5d73002a1a8..0e9e987f37dd8 100644
@@ -73,7 +73,7 @@ int phy_link_topo_add_phy(struct net_device *dev,
 				      xa_limit_32b, &topo->next_phy_index,
 				      GFP_KERNEL);
 
-	if (ret)
+	if (ret < 0)
 		goto err;
 
 	return 0;
Signature · 1 line
2.39.5
author maintainer
#45 lore raw

PATCH 43/116 gpu: host1x: Do not assume that a NULL domain means no DMA IOMMU

In reply to Greg Kroah-Hartman

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

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

From: Jason Gunthorpe <[email protected]>

[ Upstream commit cb83f4b965a66d85e9a03621ef3b22c044f4a033 ]

Previously with tegra-smmu, even with CONFIG_IOMMU_DMA, the default domain could have been left as NULL. The NULL domain is specially recognized by host1x_iommu_attach() as meaning it is not the DMA domain and should be replaced with the special shared domain.

This happened prior to the below commit because tegra-smmu was using the NULL domain to mean IDENTITY.

Now that the domain is properly labled the test in DRM doesn't see NULL. Check for IDENTITY as well to enable the special domains.

This is the same issue and basic fix as seen in
commit fae6e669cdc5 ("drm/tegra: Do not assume that a NULL domain means no DMA IOMMU").

---
 drivers/gpu/host1x/dev.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/gpu/host1x/dev.c +6 -0
index 710674ef40a97..3f23a7d91519f 100644
@@ -367,6 +367,10 @@ static bool host1x_wants_iommu(struct host1x *host1x)
 	return true;
 }
 
+/*
+ * Returns ERR_PTR on failure, NULL if the translation is IDENTITY, otherwise a
+ * valid paging domain.
+ */
 static struct iommu_domain *host1x_iommu_attach(struct host1x *host)
 {
 	struct iommu_domain *domain = iommu_get_domain_for_dev(host->dev);
@@ -391,6 +395,8 @@ static struct iommu_domain *host1x_iommu_attach(struct host1x *host)
 	 * Similarly, if host1x is already attached to an IOMMU (via the DMA
 	 * API), don't try to attach again.
 	 */
+	if (domain && domain->type == IOMMU_DOMAIN_IDENTITY)
+		domain = NULL;
 	if (!host1x_wants_iommu(host) || domain)
 		return domain;
 
Signature · 1 line
2.39.5
author maintainer
#46 lore raw

PATCH 44/116 net: atm: fix use after free in lec_send()

In reply to Greg Kroah-Hartman

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

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

From: Dan Carpenter <[email protected]>

[ Upstream commit f3009d0d6ab78053117f8857b921a8237f4d17b3 ]

The ->send() operation frees skb so save the length before calling ->send() to avoid a use after free.

---
 net/atm/lec.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
net/atm/lec.c +2 -1
index ffef658862db1..a948dd47c3f34 100644
@@ -181,6 +181,7 @@ static void
 lec_send(struct atm_vcc *vcc, struct sk_buff *skb)
 {
 	struct net_device *dev = skb->dev;
+	unsigned int len = skb->len;
 
 	ATM_SKB(skb)->vcc = vcc;
 	atm_account_tx(vcc, skb);
@@ -191,7 +192,7 @@ lec_send(struct atm_vcc *vcc, struct sk_buff *skb)
 	}
 
 	dev->stats.tx_packets++;
-	dev->stats.tx_bytes += skb->len;
+	dev->stats.tx_bytes += len;
 }
 
 static void lec_tx_timeout(struct net_device *dev, unsigned int txqueue)
Signature · 1 line
2.39.5
author maintainer
#47 lore raw

PATCH 45/116 net: ti: icssg-prueth: Add lock to stats

In reply to Greg Kroah-Hartman

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

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

From: MD Danish Anwar <[email protected]>

[ Upstream commit 47a9b5e52abd2b717dfc8b9460589f89936d93cf ]

Currently the API emac_update_hardware_stats() reads different ICSSG stats without any lock protection.

This API gets called by .ndo_get_stats64() which is only under RCU protection and nothing else. Add lock to this API so that the reading of statistics happens during lock.

---
 drivers/net/ethernet/ti/icssg/icssg_prueth.c | 1 +
 drivers/net/ethernet/ti/icssg/icssg_prueth.h | 2 ++
 drivers/net/ethernet/ti/icssg/icssg_stats.c  | 4 ++++
 3 files changed, 7 insertions(+)
drivers/net/ethernet/ti/icssg/icssg_prueth.c +1 -0
index cb11635a8d120..6f0700d156e71 100644
@@ -1555,6 +1555,7 @@ static int prueth_probe(struct platform_device *pdev)
 	}
 
 	spin_lock_init(&prueth->vtbl_lock);
+	spin_lock_init(&prueth->stats_lock);
 	/* setup netdev interfaces */
 	if (eth0_node) {
 		ret = prueth_netdev_init(prueth, eth0_node);
drivers/net/ethernet/ti/icssg/icssg_prueth.h +2 -0
index 5473315ea2040..e456a11c5d4e3 100644
@@ -297,6 +297,8 @@ struct prueth {
 	int default_vlan;
 	/** @vtbl_lock: Lock for vtbl in shared memory */
 	spinlock_t vtbl_lock;
+	/** @stats_lock: Lock for reading icssg stats */
+	spinlock_t stats_lock;
 };
 
 struct emac_tx_ts_response {
drivers/net/ethernet/ti/icssg/icssg_stats.c +4 -0
index 8800bd3a8d074..6f0edae38ea24 100644
@@ -26,6 +26,8 @@ void emac_update_hardware_stats(struct prueth_emac *emac)
 	u32 val, reg;
 	int i;
 
+	spin_lock(&prueth->stats_lock);
+
 	for (i = 0; i < ARRAY_SIZE(icssg_all_miig_stats); i++) {
 		regmap_read(prueth->miig_rt,
 			    base + icssg_all_miig_stats[i].offset,
@@ -51,6 +53,8 @@ void emac_update_hardware_stats(struct prueth_emac *emac)
 			emac->pa_stats[i] += val;
 		}
 	}
+
+	spin_unlock(&prueth->stats_lock);
 }
 
 void icssg_stats_work_handler(struct work_struct *work)
Signature · 1 line
2.39.5
author maintainer
#48 lore raw

PATCH 46/116 net: lwtunnel: fix recursion loops

In reply to Greg Kroah-Hartman

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

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

From: Justin Iurman <[email protected]>

[ Upstream commit 986ffb3a57c5650fb8bf6d59a8f0f07046abfeb6 ]

This patch acts as a parachute, catch all solution, by detecting recursion loops in lwtunnel users and taking care of them (e.g., a loop between routes, a loop within the same route, etc). In general, such loops are the consequence of pathological configurations. Each lwtunnel user is still free to catch such loops early and do whatever they want with them. It will be the case in a separate patch for, e.g., seg6 and seg6_local, in order to provide drop reasons and update statistics. Another example of a lwtunnel user taking care of loops is ioam6, which has valid use cases that include loops (e.g., inline mode), and which is addressed by the next patch in this series. Overall, this patch acts as a last resort to catch loops and drop packets, since we don't want to leak something unintentionally because of a pathological configuration in lwtunnels.

The solution in this patch reuses dev_xmit_recursion(), dev_xmit_recursion_inc(), and dev_xmit_recursion_dec(), which seems fine considering the context.

Fixes ffce41962ef6 ("lwtunnel: support dst output redirect function")
Fixes 2536862311d2 ("lwt: Add support to redirect dst.input")
Fixes 14972cbd34ff ("net: lwtunnel: Handle fragmentation")
---
 net/core/lwtunnel.c | 65 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 53 insertions(+), 12 deletions(-)
net/core/lwtunnel.c +53 -12
index 711cd3b4347a7..4417a18b3e951 100644
@@ -23,6 +23,8 @@
 #include <net/ip6_fib.h>
 #include <net/rtnh.h>
 
+#include "dev.h"
+
 DEFINE_STATIC_KEY_FALSE(nf_hooks_lwtunnel_enabled);
 EXPORT_SYMBOL_GPL(nf_hooks_lwtunnel_enabled);
 
@@ -325,13 +327,23 @@ EXPORT_SYMBOL_GPL(lwtunnel_cmp_encap);
 
 int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
-	struct dst_entry *dst = skb_dst(skb);
 	const struct lwtunnel_encap_ops *ops;
 	struct lwtunnel_state *lwtstate;
-	int ret = -EINVAL;
+	struct dst_entry *dst;
+	int ret;
+
+	if (dev_xmit_recursion()) {
+		net_crit_ratelimited("%s(): recursion limit reached on datapath\n",
+				     __func__);
+		ret = -ENETDOWN;
+		goto drop;
+	}
 
-	if (!dst)
+	dst = skb_dst(skb);
+	if (!dst) {
+		ret = -EINVAL;
 		goto drop;
+	}
 	lwtstate = dst->lwtstate;
 
 	if (lwtstate->type == LWTUNNEL_ENCAP_NONE ||
@@ -341,8 +353,11 @@ int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 	ret = -EOPNOTSUPP;
 	rcu_read_lock();
 	ops = rcu_dereference(lwtun_encaps[lwtstate->type]);
-	if (likely(ops && ops->output))
+	if (likely(ops && ops->output)) {
+		dev_xmit_recursion_inc();
 		ret = ops->output(net, sk, skb);
+		dev_xmit_recursion_dec();
+	}
 	rcu_read_unlock();
 
 	if (ret == -EOPNOTSUPP)
@@ -359,13 +374,23 @@ EXPORT_SYMBOL_GPL(lwtunnel_output);
 
 int lwtunnel_xmit(struct sk_buff *skb)
 {
-	struct dst_entry *dst = skb_dst(skb);
 	const struct lwtunnel_encap_ops *ops;
 	struct lwtunnel_state *lwtstate;
-	int ret = -EINVAL;
+	struct dst_entry *dst;
+	int ret;
+
+	if (dev_xmit_recursion()) {
+		net_crit_ratelimited("%s(): recursion limit reached on datapath\n",
+				     __func__);
+		ret = -ENETDOWN;
+		goto drop;
+	}
 
-	if (!dst)
+	dst = skb_dst(skb);
+	if (!dst) {
+		ret = -EINVAL;
 		goto drop;
+	}
 
 	lwtstate = dst->lwtstate;
 
@@ -376,8 +401,11 @@ int lwtunnel_xmit(struct sk_buff *skb)
 	ret = -EOPNOTSUPP;
 	rcu_read_lock();
 	ops = rcu_dereference(lwtun_encaps[lwtstate->type]);
-	if (likely(ops && ops->xmit))
+	if (likely(ops && ops->xmit)) {
+		dev_xmit_recursion_inc();
 		ret = ops->xmit(skb);
+		dev_xmit_recursion_dec();
+	}
 	rcu_read_unlock();
 
 	if (ret == -EOPNOTSUPP)
@@ -394,13 +422,23 @@ EXPORT_SYMBOL_GPL(lwtunnel_xmit);
 
 int lwtunnel_input(struct sk_buff *skb)
 {
-	struct dst_entry *dst = skb_dst(skb);
 	const struct lwtunnel_encap_ops *ops;
 	struct lwtunnel_state *lwtstate;
-	int ret = -EINVAL;
+	struct dst_entry *dst;
+	int ret;
 
-	if (!dst)
+	if (dev_xmit_recursion()) {
+		net_crit_ratelimited("%s(): recursion limit reached on datapath\n",
+				     __func__);
+		ret = -ENETDOWN;
 		goto drop;
+	}
+
+	dst = skb_dst(skb);
+	if (!dst) {
+		ret = -EINVAL;
+		goto drop;
+	}
 	lwtstate = dst->lwtstate;
 
 	if (lwtstate->type == LWTUNNEL_ENCAP_NONE ||
@@ -410,8 +448,11 @@ int lwtunnel_input(struct sk_buff *skb)
 	ret = -EOPNOTSUPP;
 	rcu_read_lock();
 	ops = rcu_dereference(lwtun_encaps[lwtstate->type]);
-	if (likely(ops && ops->input))
+	if (likely(ops && ops->input)) {
+		dev_xmit_recursion_inc();
 		ret = ops->input(skb);
+		dev_xmit_recursion_dec();
+	}
 	rcu_read_unlock();
 
 	if (ret == -EOPNOTSUPP)
Signature · 1 line
2.39.5
author maintainer
#49 lore raw

PATCH 47/116 net: ipv6: ioam6: fix lwtunnel_output() loop

In reply to Greg Kroah-Hartman

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

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

From: Justin Iurman <[email protected]>

[ Upstream commit 3e7a60b368eadf6c30a4a79dea1eb8f88b6d620d ]

Fix the lwtunnel_output() reentry loop in ioam6_iptunnel when the destination is the same after transformation. Note that a check on the destination address was already performed, but it was not enough. This is the example of a lwtunnel user taking care of loops without relying only on the last resort detection offered by lwtunnel.

Fixes 8cb3bf8bff3c ("ipv6: ioam: Add support for the ip6ip6 encapsulation")
---
 net/ipv6/ioam6_iptunnel.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
net/ipv6/ioam6_iptunnel.c +4 -4
index 4215cebe7d85a..647dd8417c6cf 100644
@@ -339,7 +339,6 @@ static int ioam6_do_encap(struct net *net, struct sk_buff *skb,
 static int ioam6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
 	struct dst_entry *dst = skb_dst(skb), *cache_dst = NULL;
-	struct in6_addr orig_daddr;
 	struct ioam6_lwt *ilwt;
 	int err = -EINVAL;
 	u32 pkt_cnt;
@@ -354,8 +353,6 @@ static int ioam6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 	if (pkt_cnt % ilwt->freq.n >= ilwt->freq.k)
 		goto out;
 
-	orig_daddr = ipv6_hdr(skb)->daddr;
-
 	local_bh_disable();
 	cache_dst = dst_cache_get(&ilwt->cache);
 	local_bh_enable();
@@ -424,7 +421,10 @@ static int ioam6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 			goto drop;
 	}
 
-	if (!ipv6_addr_equal(&orig_daddr, &ipv6_hdr(skb)->daddr)) {
+	/* avoid lwtunnel_output() reentry loop when destination is the same
+	 * after transformation (e.g., with the inline mode)
+	 */
+	if (dst->lwtstate != cache_dst->lwtstate) {
 		skb_dst_drop(skb);
 		skb_dst_set(skb, cache_dst);
 		return dst_output(net, sk, skb);
Signature · 1 line
2.39.5
author maintainer
#50 lore raw

PATCH 48/116 libfs: Fix duplicate directory entry in offset_dir_lookup

In reply to Greg Kroah-Hartman

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

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

From: Yongjian Sun <[email protected]>

[ Upstream commit f70681e9e6066ab7b102e6b46a336a8ed67812ae ]

There is an issue in the kernel:

In tmpfs, when using the "ls" command to list the contents of a directory with a large number of files, glibc performs the getdents call in multiple rounds. If a concurrent unlink occurs between these getdents calls, it may lead to duplicate directory entries in the ls output. One possible reproduction scenario is as follows:

Create 1026 files and execute ls and rm concurrently:

for i in {1..1026}; do
echo "This is file $i" > /tmp/dir/file$i
done

ls /tmp/dir rm /tmp/dir/file4

	->getdents(file1026-file5)
						->unlink(file4)

	->getdents(file5,file3,file2,file1)

It is expected that the second getdents call to return file3 through file1, but instead it returns an extra file5.

The root cause of this problem is in the offset_dir_lookup function. It uses mas_find to determine the starting position for the current getdents call. Since mas_find locates the first position that is greater than or equal to mas->index, when file4 is deleted, it ends up returning file5.

It can be fixed by replacing mas_find with mas_find_rev, which finds the first position that is less than or equal to mas->index.

Fixes b9b588f22a0c ("libfs: Use d_children list to iterate simple_offset directories")
---
 fs/libfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/libfs.c +1 -1
index b0f262223b535..3cb49463a8496 100644
@@ -492,7 +492,7 @@ offset_dir_lookup(struct dentry *parent, loff_t offset)
 		found = find_positive_dentry(parent, NULL, false);
 	else {
 		rcu_read_lock();
-		child = mas_find(&mas, DIR_OFFSET_MAX);
+		child = mas_find_rev(&mas, DIR_OFFSET_MIN);
 		found = find_positive_dentry(parent, child, false);
 		rcu_read_unlock();
 	}
Signature · 1 line
2.39.5
author maintainer
#51 lore raw

PATCH 49/116 net/neighbor: add missing policy for NDTPA_QUEUE_LENBYTES

In reply to Greg Kroah-Hartman

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

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

From: Lin Ma <[email protected]>

[ Upstream commit 90a7138619a0c55e2aefaad27b12ffc2ddbeed78 ]

Previous commit 8b5c171bb3dc ("neigh: new unresolved queue limits") introduces new netlink attribute NDTPA_QUEUE_LENBYTES to represent approximative value for deprecated QUEUE_LEN. However, it forgot to add the associated nla_policy in nl_ntbl_parm_policy array. Fix it with one simple NLA_U32 type policy.

Fixes 8b5c171bb3dc ("neigh: new unresolved queue limits")
---
 net/core/neighbour.c | 1 +
 1 file changed, 1 insertion(+)
net/core/neighbour.c +1 -0
index c7f7ea61b524a..8082cc6be4fc1 100644
@@ -2301,6 +2301,7 @@ static const struct nla_policy nl_neightbl_policy[NDTA_MAX+1] = {
 static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = {
 	[NDTPA_IFINDEX]			= { .type = NLA_U32 },
 	[NDTPA_QUEUE_LEN]		= { .type = NLA_U32 },
+	[NDTPA_QUEUE_LENBYTES]		= { .type = NLA_U32 },
 	[NDTPA_PROXY_QLEN]		= { .type = NLA_U32 },
 	[NDTPA_APP_PROBES]		= { .type = NLA_U32 },
 	[NDTPA_UCAST_PROBES]		= { .type = NLA_U32 },
Signature · 1 line
2.39.5
author maintainer
#52 lore raw

PATCH 50/116 Revert "gre: Fix IPv6 link-local address generation."

In reply to Greg Kroah-Hartman

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

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

From: Guillaume Nault <[email protected]>

[ Upstream commit fc486c2d060f67d672ddad81724f7c8a4d329570 ]

This reverts commit 183185a18ff96751db52a46ccf93fff3a1f42815.

This patch broke net/forwarding/ip6gre_custom_multipath_hash.sh in some circumstances (https://lore.kernel.org/netdev/Z9RIyKZDNoka53EO@mini-arch/).
Let's revert it while the problem is being investigated.

---
 net/ipv6/addrconf.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)
net/ipv6/addrconf.c +6 -9
index 26cdb66574757..f7c17388ff6aa 100644
@@ -3237,13 +3237,16 @@ static void add_v4_addrs(struct inet6_dev *idev)
 	struct in6_addr addr;
 	struct net_device *dev;
 	struct net *net = dev_net(idev->dev);
-	int scope, plen;
+	int scope, plen, offset = 0;
 	u32 pflags = 0;
 
 	ASSERT_RTNL();
 
 	memset(&addr, 0, sizeof(struct in6_addr));
-	memcpy(&addr.s6_addr32[3], idev->dev->dev_addr, 4);
+	/* in case of IP6GRE the dev_addr is an IPv6 and therefore we use only the last 4 bytes */
+	if (idev->dev->addr_len == sizeof(struct in6_addr))
+		offset = sizeof(struct in6_addr) - 4;
+	memcpy(&addr.s6_addr32[3], idev->dev->dev_addr + offset, 4);
 
 	if (!(idev->dev->flags & IFF_POINTOPOINT) && idev->dev->type == ARPHRD_SIT) {
 		scope = IPV6_ADDR_COMPATv4;
@@ -3554,13 +3557,7 @@ static void addrconf_gre_config(struct net_device *dev)
 		return;
 	}
 
-	/* Generate the IPv6 link-local address using addrconf_addr_gen(),
-	 * unless we have an IPv4 GRE device not bound to an IP address and
-	 * which is in EUI64 mode (as __ipv6_isatap_ifid() would fail in this
-	 * case). Such devices fall back to add_v4_addrs() instead.
-	 */
-	if (!(dev->type == ARPHRD_IPGRE && *(__be32 *)dev->dev_addr == 0 &&
-	      idev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_EUI64)) {
+	if (dev->type == ARPHRD_ETHER) {
 		addrconf_addr_gen(idev, true);
 		return;
 	}
Signature · 1 line
2.39.5
author maintainer
#53 lore raw

PATCH 51/116 tracing: tprobe-events: Fix leakage of module refcount

In reply to Greg Kroah-Hartman

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

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

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

commit ac91052f0ae5be9e46211ba92cc31c0e3b0a933a upstream.

When enabling the tracepoint at loading module, the target module refcount is incremented by find_tracepoint_in_module(). But it is unnecessary because the module is not unloaded while processing module loading callbacks.
Moreover, the refcount is not decremented in that function. To be clear the module refcount handling, move the try_module_get() callsite to trace_fprobe_create_internal(), where it is actually required.

Fixes 57a7e6de9e30 ("tracing/fprobe: Support raw tracepoints on future loaded modules")
---
 kernel/trace/trace_fprobe.c |   21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)
kernel/trace/trace_fprobe.c +8 -13
@@ -889,13 +889,8 @@ static void __find_tracepoint_module_cb(
 
 	if (!data->tpoint && !strcmp(data->tp_name, tp->name)) {
 		data->tpoint = tp;
-		if (!data->mod) {
+		if (!data->mod)
 			data->mod = mod;
-			if (!try_module_get(data->mod)) {
-				data->tpoint = NULL;
-				data->mod = NULL;
-			}
-		}
 	}
 }
 
@@ -907,13 +902,7 @@ static void __find_tracepoint_cb(struct
 		data->tpoint = tp;
 }
 
-/*
- * Find a tracepoint from kernel and module. If the tracepoint is in a module,
- * this increments the module refcount to prevent unloading until the
- * trace_fprobe is registered to the list. After registering the trace_fprobe
- * on the trace_fprobe list, the module refcount is decremented because
- * tracepoint_probe_module_cb will handle it.
- */
+/* Find a tracepoint from kernel and module. */
 static struct tracepoint *find_tracepoint(const char *tp_name,
 					  struct module **tp_mod)
 {
@@ -942,6 +931,7 @@ static void reenable_trace_fprobe(struct
 	}
 }
 
+/* Find a tracepoint from specified module. */
 static struct tracepoint *find_tracepoint_in_module(struct module *mod,
 						    const char *tp_name)
 {
@@ -1177,6 +1167,11 @@ static int __trace_fprobe_create(int arg
 	if (is_tracepoint) {
 		ctx.flags |= TPARG_FL_TPOINT;
 		tpoint = find_tracepoint(symbol, &tp_mod);
+		/* lock module until register this tprobe. */
+		if (tp_mod && !try_module_get(tp_mod)) {
+			tpoint = NULL;
+			tp_mod = NULL;
+		}
 		if (tpoint) {
 			ctx.funcname = kallsyms_lookup(
 				(unsigned long)tpoint->probestub,
author maintainer
#54 lore raw

PATCH 52/116 i2c: omap: fix IRQ storms

In reply to Greg Kroah-Hartman

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

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

From: Andreas Kemnade <[email protected]>

commit 285df995f90e3d61d97f327d34b9659d92313314 upstream.

On the GTA04A5 writing a reset command to the gyroscope causes IRQ storms because NACK IRQs are enabled and therefore triggered but not acked.

Sending a reset command to the gyroscope by
i2cset 1 0x69 0x14 0xb6
with an additional debug print in the ISR (not the thread) itself causes

[ 363.353515] i2c i2c-1: ioctl, cmd=0x720, arg=0xbe801b00
[ 363.359039] omap_i2c 48072000.i2c: addr: 0x0069, len: 2, flags: 0x0, stop: 1
[ 363.366180] omap_i2c 48072000.i2c: IRQ LL (ISR = 0x1110)
[ 363.371673] omap_i2c 48072000.i2c: IRQ (ISR = 0x0010)
[ 363.376892] omap_i2c 48072000.i2c: IRQ LL (ISR = 0x0102)
[ 363.382263] omap_i2c 48072000.i2c: IRQ LL (ISR = 0x0102)
[ 363.387664] omap_i2c 48072000.i2c: IRQ LL (ISR = 0x0102)

repeating till infinity
[...]
(0x2 = NACK, 0x100 = Bus free, which is not enabled) Apparently no other IRQ bit gets set, so this stalls.

Do not ignore enabled interrupts and make sure they are acked. If the NACK IRQ is not needed, it should simply not enabled, but according to the above log, caring about it is necessary unless the Bus free IRQ is enabled and handled. The assumption that is will always come with a ARDY IRQ, which was the idea behind ignoring it, proves wrong.
It is true for simple reads from an unused address.

To still avoid the i2cdetect trouble which is the reason for commit c770657bd261 ("i2c: omap: Fix standard mode false ACK readings"), avoid doing much about NACK in omap_i2c_xfer_data() which is used by both IRQ mode and polling mode, so also the false detection fix is extended to polling usage and IRQ storms are avoided.

By changing this, the hardirq handler is not needed anymore to filter stuff.

The mentioned gyro reset now just causes a -ETIMEDOUT instead of hanging the system.

---
 drivers/i2c/busses/i2c-omap.c |   26 +++++++-------------------
 1 file changed, 7 insertions(+), 19 deletions(-)
drivers/i2c/busses/i2c-omap.c +7 -19
@@ -1048,23 +1048,6 @@ static int omap_i2c_transmit_data(struct
 	return 0;
 }
 
-static irqreturn_t
-omap_i2c_isr(int irq, void *dev_id)
-{
-	struct omap_i2c_dev *omap = dev_id;
-	irqreturn_t ret = IRQ_HANDLED;
-	u16 mask;
-	u16 stat;
-
-	stat = omap_i2c_read_reg(omap, OMAP_I2C_STAT_REG);
-	mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG) & ~OMAP_I2C_STAT_NACK;
-
-	if (stat & mask)
-		ret = IRQ_WAKE_THREAD;
-
-	return ret;
-}
-
 static int omap_i2c_xfer_data(struct omap_i2c_dev *omap)
 {
 	u16 bits;
@@ -1095,8 +1078,13 @@ static int omap_i2c_xfer_data(struct oma
 		}
 
 		if (stat & OMAP_I2C_STAT_NACK) {
-			err |= OMAP_I2C_STAT_NACK;
+			omap->cmd_err |= OMAP_I2C_STAT_NACK;
 			omap_i2c_ack_stat(omap, OMAP_I2C_STAT_NACK);
+
+			if (!(stat & ~OMAP_I2C_STAT_NACK)) {
+				err = -EAGAIN;
+				break;
+			}
 		}
 
 		if (stat & OMAP_I2C_STAT_AL) {
@@ -1472,7 +1460,7 @@ omap_i2c_probe(struct platform_device *p
 				IRQF_NO_SUSPEND, pdev->name, omap);
 	else
 		r = devm_request_threaded_irq(&pdev->dev, omap->irq,
-				omap_i2c_isr, omap_i2c_isr_thread,
+				NULL, omap_i2c_isr_thread,
 				IRQF_NO_SUSPEND | IRQF_ONESHOT,
 				pdev->name, omap);
 
author maintainer
#55 lore raw

PATCH 53/116 net: mana: Support holes in device list reply msg

In reply to Greg Kroah-Hartman

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

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

From: Haiyang Zhang <[email protected]>

commit 2fc8a346625eb1abfe202062c7e6a13d76cde5ea upstream.

According to GDMA protocol, holes (zeros) are allowed at the beginning or middle of the gdma_list_devices_resp message. The existing code cannot properly handle this, and may miss some devices in the list.

To fix, scan the entire list until the num_of_devs are found, or until the end of the list.

---
 drivers/net/ethernet/microsoft/mana/gdma_main.c |   14 ++++++++++----
 include/net/mana/gdma.h                         |   11 +++++++----
 2 files changed, 17 insertions(+), 8 deletions(-)
drivers/net/ethernet/microsoft/mana/gdma_main.c +10 -4
@@ -131,9 +131,10 @@ static int mana_gd_detect_devices(struct
 	struct gdma_list_devices_resp resp = {};
 	struct gdma_general_req req = {};
 	struct gdma_dev_id dev;
-	u32 i, max_num_devs;
+	int found_dev = 0;
 	u16 dev_type;
 	int err;
+	u32 i;
 
 	mana_gd_init_req_hdr(&req.hdr, GDMA_LIST_DEVICES, sizeof(req),
 			     sizeof(resp));
@@ -145,12 +146,17 @@ static int mana_gd_detect_devices(struct
 		return err ? err : -EPROTO;
 	}
 
-	max_num_devs = min_t(u32, MAX_NUM_GDMA_DEVICES, resp.num_of_devs);
-
-	for (i = 0; i < max_num_devs; i++) {
+	for (i = 0; i < GDMA_DEV_LIST_SIZE &&
+	     found_dev < resp.num_of_devs; i++) {
 		dev = resp.devs[i];
 		dev_type = dev.type;
 
+		/* Skip empty devices */
+		if (dev.as_uint32 == 0)
+			continue;
+
+		found_dev++;
+
 		/* HWC is already detected in mana_hwc_create_channel(). */
 		if (dev_type == GDMA_DEVICE_HWC)
 			continue;
include/net/mana/gdma.h +7 -4
@@ -406,8 +406,6 @@ struct gdma_context {
 	struct gdma_dev		mana_ib;
 };
 
-#define MAX_NUM_GDMA_DEVICES	4
-
 static inline bool mana_gd_is_mana(struct gdma_dev *gd)
 {
 	return gd->dev_id.type == GDMA_DEVICE_MANA;
@@ -554,11 +552,15 @@ enum {
 #define GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECONFIG BIT(3)
 #define GDMA_DRV_CAP_FLAG_1_VARIABLE_INDIRECTION_TABLE_SUPPORT BIT(5)
 
+/* Driver can handle holes (zeros) in the device list */
+#define GDMA_DRV_CAP_FLAG_1_DEV_LIST_HOLES_SUP BIT(11)
+
 #define GDMA_DRV_CAP_FLAGS1 \
 	(GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT | \
 	 GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX | \
 	 GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECONFIG | \
-	 GDMA_DRV_CAP_FLAG_1_VARIABLE_INDIRECTION_TABLE_SUPPORT)
+	 GDMA_DRV_CAP_FLAG_1_VARIABLE_INDIRECTION_TABLE_SUPPORT | \
+	 GDMA_DRV_CAP_FLAG_1_DEV_LIST_HOLES_SUP)
 
 #define GDMA_DRV_CAP_FLAGS2 0
 
@@ -619,11 +621,12 @@ struct gdma_query_max_resources_resp {
 }; /* HW DATA */
 
 /* GDMA_LIST_DEVICES */
+#define GDMA_DEV_LIST_SIZE 64
 struct gdma_list_devices_resp {
 	struct gdma_resp_hdr hdr;
 	u32 num_of_devs;
 	u32 reserved;
-	struct gdma_dev_id devs[64];
+	struct gdma_dev_id devs[GDMA_DEV_LIST_SIZE];
 }; /* HW DATA */
 
 /* GDMA_REGISTER_DEVICE */
author maintainer
#56 lore raw

PATCH 54/116 dt-bindings: can: renesas,rcar-canfd: Fix typo in pattern properties for R-Car V4M

In reply to Greg Kroah-Hartman

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

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

From: Biju Das <[email protected]>

commit 51f6fc9eb1d77ae5cacc796fc043dedc1f0f0073 upstream.

The Renesas R-Car V4M(R8A779H0) SoC, supports up to four channels. Fix the typo 5->4 in pattern properties.

---
 .../devicetree/bindings/net/can/renesas,rcar-canfd.yaml         | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Documentation/devicetree/bindings/net/can/renesas,rcar-canfd.yaml +1 -1
index 7c5ac5d2e880..f6884f6e59e7 100644
@@ -170,7 +170,7 @@ allOf:
             const: renesas,r8a779h0-canfd
     then:
       patternProperties:
-        "^channel[5-7]$": false
+        "^channel[4-7]$": false
     else:
       if:
         not:
Signature · 1 line
2.49.0
author maintainer
#57 lore raw

PATCH 55/116 can: rcar_canfd: Fix page entries in the AFL list

In reply to Greg Kroah-Hartman

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

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

From: Biju Das <[email protected]>

commit 1dba0a37644ed3022558165bbb5cb9bda540eaf7 upstream.

There are a total of 96 AFL pages and each page has 16 entries with registers CFDGAFLIDr, CFDGAFLMr, CFDGAFLP0r, CFDGAFLP1r holding the rule entries (r = 0..15).

Currently, RCANFD_GAFL* macros use a start variable to find AFL entries, which is incorrect as the testing on RZ/G3E shows ch1 and ch4 gets a start value of 0 and the register contents are overwritten.

Fix this issue by using rule_entry corresponding to the channel to find the page entries in the AFL list.

---
 drivers/net/can/rcar/rcar_canfd.c |   28 +++++++++++-----------------
 1 file changed, 11 insertions(+), 17 deletions(-)
drivers/net/can/rcar/rcar_canfd.c +11 -17
@@ -787,22 +787,14 @@ static void rcar_canfd_configure_control
 }
 
 static void rcar_canfd_configure_afl_rules(struct rcar_canfd_global *gpriv,
-					   u32 ch)
+					   u32 ch, u32 rule_entry)
 {
-	u32 cfg;
-	int offset, start, page, num_rules = RCANFD_CHANNEL_NUMRULES;
+	int offset, page, num_rules = RCANFD_CHANNEL_NUMRULES;
+	u32 rule_entry_index = rule_entry % 16;
 	u32 ridx = ch + RCANFD_RFFIFO_IDX;
 
-	if (ch == 0) {
-		start = 0; /* Channel 0 always starts from 0th rule */
-	} else {
-		/* Get number of Channel 0 rules and adjust */
-		cfg = rcar_canfd_read(gpriv->base, RCANFD_GAFLCFG(ch));
-		start = RCANFD_GAFLCFG_GETRNC(gpriv, 0, cfg);
-	}
-
 	/* Enable write access to entry */
-	page = RCANFD_GAFL_PAGENUM(start);
+	page = RCANFD_GAFL_PAGENUM(rule_entry);
 	rcar_canfd_set_bit(gpriv->base, RCANFD_GAFLECTR,
 			   (RCANFD_GAFLECTR_AFLPN(gpriv, page) |
 			    RCANFD_GAFLECTR_AFLDAE));
@@ -818,13 +810,13 @@ static void rcar_canfd_configure_afl_rul
 		offset = RCANFD_C_GAFL_OFFSET;
 
 	/* Accept all IDs */
-	rcar_canfd_write(gpriv->base, RCANFD_GAFLID(offset, start), 0);
+	rcar_canfd_write(gpriv->base, RCANFD_GAFLID(offset, rule_entry_index), 0);
 	/* IDE or RTR is not considered for matching */
-	rcar_canfd_write(gpriv->base, RCANFD_GAFLM(offset, start), 0);
+	rcar_canfd_write(gpriv->base, RCANFD_GAFLM(offset, rule_entry_index), 0);
 	/* Any data length accepted */
-	rcar_canfd_write(gpriv->base, RCANFD_GAFLP0(offset, start), 0);
+	rcar_canfd_write(gpriv->base, RCANFD_GAFLP0(offset, rule_entry_index), 0);
 	/* Place the msg in corresponding Rx FIFO entry */
-	rcar_canfd_set_bit(gpriv->base, RCANFD_GAFLP1(offset, start),
+	rcar_canfd_set_bit(gpriv->base, RCANFD_GAFLP1(offset, rule_entry_index),
 			   RCANFD_GAFLP1_GAFLFDP(ridx));
 
 	/* Disable write access to page */
@@ -1851,6 +1843,7 @@ static int rcar_canfd_probe(struct platf
 	unsigned long channels_mask = 0;
 	int err, ch_irq, g_irq;
 	int g_err_irq, g_recc_irq;
+	u32 rule_entry = 0;
 	bool fdmode = true;			/* CAN FD only mode - default */
 	char name[9] = "channelX";
 	int i;
@@ -2023,7 +2016,8 @@ static int rcar_canfd_probe(struct platf
 		rcar_canfd_configure_tx(gpriv, ch);
 
 		/* Configure receive rules */
-		rcar_canfd_configure_afl_rules(gpriv, ch);
+		rcar_canfd_configure_afl_rules(gpriv, ch, rule_entry);
+		rule_entry += RCANFD_CHANNEL_NUMRULES;
 	}
 
 	/* Configure common interrupts */
author maintainer
#58 lore raw

PATCH 56/116 can: ucan: fix out of bound read in strscpy() source

In reply to Greg Kroah-Hartman

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

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

From: Vincent Mailhol <[email protected]>

commit 1d22a122ffb116c3cf78053e812b8b21f8852ee9 upstream.

Commit 7fdaf8966aae ("can: ucan: use strscpy() to instead of strncpy()") unintentionally introduced a one byte out of bound read on strscpy()'s source argument (which is kind of ironic knowing that strscpy() is meant to be a more secure alternative :)).

Let's consider below buffers:

dest[len + 1]; /* will be NUL terminated */
src[len]; /* may not be NUL terminated */

When doing:

  strncpy(dest, src, len);
  dest[len] = '\0';

strncpy() will read up to len bytes from src.

On the other hand:

  strscpy(dest, src, len + 1);

will read up to len + 1 bytes from src, that is to say, an out of bound read of one byte will occur on src if it is not NUL terminated. Note that the src[len] byte is never copied, but strscpy() still needs to read it to check whether a truncation occurred or not.

This exact pattern happened in ucan.

The root cause is that the source is not NUL terminated. Instead of doing a copy in a local buffer, directly NUL terminate it as soon as usb_control_msg() returns. With this, the local firmware_str[] variable can be removed.

On top of this do a couple refactors:

- ucan_ctl_payload->raw is only used for the firmware string, so

    rename it to ucan_ctl_payload->fw_str and change its type from u8 to
    char.

- ucan_device_request_in() is only used to retrieve the firmware string, so rename it to ucan_get_fw_str() and refactor it to make it directly handle all the string termination logic.

---
 drivers/net/can/usb/ucan.c |   43 ++++++++++++++++++-------------------------
 1 file changed, 18 insertions(+), 25 deletions(-)
drivers/net/can/usb/ucan.c +18 -25
@@ -186,7 +186,7 @@ union ucan_ctl_payload {
 	 */
 	struct ucan_ctl_cmd_get_protocol_version cmd_get_protocol_version;
 
-	u8 raw[128];
+	u8 fw_str[128];
 } __packed;
 
 enum {
@@ -424,18 +424,20 @@ static int ucan_ctrl_command_out(struct
 			       UCAN_USB_CTL_PIPE_TIMEOUT);
 }
 
-static int ucan_device_request_in(struct ucan_priv *up,
-				  u8 cmd, u16 subcmd, u16 datalen)
+static void ucan_get_fw_str(struct ucan_priv *up, char *fw_str, size_t size)
 {
-	return usb_control_msg(up->udev,
-			       usb_rcvctrlpipe(up->udev, 0),
-			       cmd,
-			       USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-			       subcmd,
-			       0,
-			       up->ctl_msg_buffer,
-			       datalen,
-			       UCAN_USB_CTL_PIPE_TIMEOUT);
+	int ret;
+
+	ret = usb_control_msg(up->udev, usb_rcvctrlpipe(up->udev, 0),
+			      UCAN_DEVICE_GET_FW_STRING,
+			      USB_DIR_IN | USB_TYPE_VENDOR |
+			      USB_RECIP_DEVICE,
+			      0, 0, fw_str, size - 1,
+			      UCAN_USB_CTL_PIPE_TIMEOUT);
+	if (ret > 0)
+		fw_str[ret] = '\0';
+	else
+		strscpy(fw_str, "unknown", size);
 }
 
 /* Parse the device information structure reported by the device and
@@ -1314,7 +1316,6 @@ static int ucan_probe(struct usb_interfa
 	u8 in_ep_addr;
 	u8 out_ep_addr;
 	union ucan_ctl_payload *ctl_msg_buffer;
-	char firmware_str[sizeof(union ucan_ctl_payload) + 1];
 
 	udev = interface_to_usbdev(intf);
 
@@ -1527,17 +1528,6 @@ static int ucan_probe(struct usb_interfa
 	 */
 	ucan_parse_device_info(up, &ctl_msg_buffer->cmd_get_device_info);
 
-	/* just print some device information - if available */
-	ret = ucan_device_request_in(up, UCAN_DEVICE_GET_FW_STRING, 0,
-				     sizeof(union ucan_ctl_payload));
-	if (ret > 0) {
-		/* copy string while ensuring zero termination */
-		strscpy(firmware_str, up->ctl_msg_buffer->raw,
-			sizeof(union ucan_ctl_payload) + 1);
-	} else {
-		strcpy(firmware_str, "unknown");
-	}
-
 	/* device is compatible, reset it */
 	ret = ucan_ctrl_command_out(up, UCAN_COMMAND_RESET, 0, 0);
 	if (ret < 0)
@@ -1555,7 +1545,10 @@ static int ucan_probe(struct usb_interfa
 
 	/* initialisation complete, log device info */
 	netdev_info(up->netdev, "registered device\n");
-	netdev_info(up->netdev, "firmware string: %s\n", firmware_str);
+	ucan_get_fw_str(up, up->ctl_msg_buffer->fw_str,
+			sizeof(up->ctl_msg_buffer->fw_str));
+	netdev_info(up->netdev, "firmware string: %s\n",
+		    up->ctl_msg_buffer->fw_str);
 
 	/* success */
 	return 0;
author maintainer
#59 lore raw

PATCH 57/116 can: flexcan: only change CAN state when link up in system PM

In reply to Greg Kroah-Hartman

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

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

From: Haibo Chen <[email protected]>

commit fd99d6ed20234b83d65b9c5417794343577cf3e5 upstream.

After a suspend/resume cycle on a down interface, it will come up as ERROR-ACTIVE.

$ ip -details -s -s a s dev flexcan0
3: flexcan0: <NOARP,ECHO> mtu 16 qdisc pfifo_fast state DOWN group default qlen 10
    link/can  promiscuity 0 allmulti 0 minmtu 0 maxmtu 0
    can state STOPPED (berr-counter tx 0 rx 0) restart-ms 1000
$ sudo systemctl suspend
$ ip -details -s -s a s dev flexcan0
3: flexcan0: <NOARP,ECHO> mtu 16 qdisc pfifo_fast state DOWN group default qlen 10
    link/can  promiscuity 0 allmulti 0 minmtu 0 maxmtu 0
    can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 1000

And only set CAN state to CAN_STATE_ERROR_ACTIVE when resume process has no issue, otherwise keep in CAN_STATE_SLEEPING as suspend did.

---
 drivers/net/can/flexcan/flexcan-core.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/can/flexcan/flexcan-core.c +4 -2
@@ -2266,8 +2266,9 @@ static int __maybe_unused flexcan_suspen
 		}
 		netif_stop_queue(dev);
 		netif_device_detach(dev);
+
+		priv->can.state = CAN_STATE_SLEEPING;
 	}
-	priv->can.state = CAN_STATE_SLEEPING;
 
 	return 0;
 }
@@ -2278,7 +2279,6 @@ static int __maybe_unused flexcan_resume
 	struct flexcan_priv *priv = netdev_priv(dev);
 	int err;
 
-	priv->can.state = CAN_STATE_ERROR_ACTIVE;
 	if (netif_running(dev)) {
 		netif_device_attach(dev);
 		netif_start_queue(dev);
@@ -2298,6 +2298,8 @@ static int __maybe_unused flexcan_resume
 
 			flexcan_chip_interrupts_enable(dev);
 		}
+
+		priv->can.state = CAN_STATE_ERROR_ACTIVE;
 	}
 
 	return 0;
author maintainer
#60 lore raw

PATCH 58/116 can: flexcan: disable transceiver during system PM

In reply to Greg Kroah-Hartman

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

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

From: Haibo Chen <[email protected]>

commit 5a19143124be42900b3fbc9ada3c919632eb45eb upstream.

During system PM, if no wakeup requirement, disable transceiver to save power.

Fixes 4de349e786a3 ("can: flexcan: fix resume function")
[mkl: add newlines]
---
 drivers/net/can/flexcan/flexcan-core.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/net/can/flexcan/flexcan-core.c +11 -1
@@ -2260,6 +2260,10 @@ static int __maybe_unused flexcan_suspen
 
 			flexcan_chip_interrupts_disable(dev);
 
+			err = flexcan_transceiver_disable(priv);
+			if (err)
+				return err;
+
 			err = pinctrl_pm_select_sleep_state(device);
 			if (err)
 				return err;
@@ -2292,10 +2296,16 @@ static int __maybe_unused flexcan_resume
 			if (err)
 				return err;
 
-			err = flexcan_chip_start(dev);
+			err = flexcan_transceiver_enable(priv);
 			if (err)
 				return err;
 
+			err = flexcan_chip_start(dev);
+			if (err) {
+				flexcan_transceiver_disable(priv);
+				return err;
+			}
+
 			flexcan_chip_interrupts_enable(dev);
 		}
 
author maintainer
#61 lore raw

PATCH 59/116 drm/xe: Fix exporting xe buffers multiple times

In reply to Greg Kroah-Hartman

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

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

From: Tomasz Rusinowicz <[email protected]>

commit 50af7cab7520e46680cf4633bba6801443b75856 upstream.

The struct ttm_resource->placement contains TTM_PL_FLAG_* flags, but it was incorrectly tested for XE_PL_* flags.
This caused xe_dma_buf_pin() to always fail when invoked for the second time. Fix this by checking the mem_type field instead.

Fixes 7764222d54b7 ("drm/xe: Disallow pinning dma-bufs in VRAM")
Cc Thomas Hellström <[email protected]>
Cc Rodrigo Vivi <[email protected]>
Cc Lucas De Marchi <[email protected]>
Cc "Thomas Hellström" <[email protected]>
Cc Michal Wajdeczko <[email protected]>
Cc Matthew Brost <[email protected]>
Cc Matthew Auld <[email protected]>
Cc Nirmoy Das <[email protected]>
Cc Jani Nikula <[email protected]>
Cc <[email protected]> # v6.8+
(cherry picked from commit b96dabdba9b95f71ded50a1c094ee244408b2a8e)
---
 drivers/gpu/drm/xe/xe_bo.h      |    2 --
 drivers/gpu/drm/xe/xe_dma_buf.c |    2 +-
 2 files changed, 1 insertion(+), 3 deletions(-)
drivers/gpu/drm/xe/xe_bo.h +0 -2
@@ -314,7 +314,6 @@ static inline unsigned int xe_sg_segment
 
 #define i915_gem_object_flush_if_display(obj)		((void)(obj))
 
-#if IS_ENABLED(CONFIG_DRM_XE_KUNIT_TEST)
 /**
  * xe_bo_is_mem_type - Whether the bo currently resides in the given
  * TTM memory type
@@ -329,4 +328,3 @@ static inline bool xe_bo_is_mem_type(str
 	return bo->ttm.resource->mem_type == mem_type;
 }
 #endif
-#endif
drivers/gpu/drm/xe/xe_dma_buf.c +1 -1
@@ -58,7 +58,7 @@ static int xe_dma_buf_pin(struct dma_buf
 	 * 1) Avoid pinning in a placement not accessible to some importers.
 	 * 2) Pinning in VRAM requires PIN accounting which is a to-do.
 	 */
-	if (xe_bo_is_pinned(bo) && bo->ttm.resource->placement != XE_PL_TT) {
+	if (xe_bo_is_pinned(bo) && !xe_bo_is_mem_type(bo, XE_PL_TT)) {
 		drm_dbg(&xe->drm, "Can't migrate pinned bo for dma-buf pin.\n");
 		return -EINVAL;
 	}
author maintainer
#62 lore raw

PATCH 60/116 drm/v3d: Dont run jobs that have errors flagged in its fence

In reply to Greg Kroah-Hartman

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

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

From: Maíra Canal <[email protected]>

commit 80cbee810e4e13cdbd3ae9654e9ecddf17f3e828 upstream.

The V3D driver still relies on drm_sched_increase_karma() and drm_sched_resubmit_jobs() for resubmissions when a timeout occurs. The function drm_sched_increase_karma() marks the job as guilty, while drm_sched_resubmit_jobs() sets an error (-ECANCELED) in the DMA fence of that guilty job.

Because of this, we must check whether the job’s DMA fence has been flagged with an error before executing the job. Otherwise, the same guilty job may be resubmitted indefinitely, causing repeated GPU resets.

This patch adds a check for an error on the job's fence to prevent running a guilty job that was previously flagged when the GPU timed out.

Note that the CPU and CACHE_CLEAN queues do not require this check, as their jobs are executed synchronously once the DRM scheduler starts them.

Fixes d223f98f0209 ("drm/v3d: Add support for compute shader dispatch.")
Fixes 1584f16ca96e ("drm/v3d: Add support for submitting jobs to the TFU.")
---
 drivers/gpu/drm/v3d/v3d_sched.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/gpu/drm/v3d/v3d_sched.c +8 -1
@@ -319,11 +319,15 @@ v3d_tfu_job_run(struct drm_sched_job *sc
 	struct drm_device *dev = &v3d->drm;
 	struct dma_fence *fence;
 
+	if (unlikely(job->base.base.s_fence->finished.error))
+		return NULL;
+
+	v3d->tfu_job = job;
+
 	fence = v3d_fence_create(v3d, V3D_TFU);
 	if (IS_ERR(fence))
 		return NULL;
 
-	v3d->tfu_job = job;
 	if (job->base.irq_fence)
 		dma_fence_put(job->base.irq_fence);
 	job->base.irq_fence = dma_fence_get(fence);
@@ -361,6 +365,9 @@ v3d_csd_job_run(struct drm_sched_job *sc
 	struct dma_fence *fence;
 	int i, csd_cfg0_reg;
 
+	if (unlikely(job->base.base.s_fence->finished.error))
+		return NULL;
+
 	v3d->csd_job = job;
 
 	v3d_invalidate_caches(v3d);
author maintainer
#63 lore raw

PATCH 61/116 io_uring/net: dont clear REQ_F_NEED_CLEANUP unconditionally

In reply to Greg Kroah-Hartman

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

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

From: Jens Axboe <[email protected]>

commit cc34d8330e036b6bffa88db9ea537bae6b03948f upstream.

io_req_msg_cleanup() relies on the fact that io_netmsg_recycle() will always fully recycle, but that may not be the case if the msg cache was already full. To ensure that normal cleanup always gets run, let io_netmsg_recycle() deal with clearing the relevant cleanup flags, as it knows exactly when that should be done.

Fixes 75191341785e ("io_uring/net: add iovec recycling")
---
 io_uring/net.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
io_uring/net.c +1 -2
@@ -152,7 +152,7 @@ static void io_netmsg_recycle(struct io_
 		if (iov)
 			kasan_mempool_poison_object(iov);
 		req->async_data = NULL;
-		req->flags &= ~REQ_F_ASYNC_DATA;
+		req->flags &= ~(REQ_F_ASYNC_DATA|REQ_F_NEED_CLEANUP);
 	}
 }
 
@@ -447,7 +447,6 @@ int io_sendmsg_prep(struct io_kiocb *req
 static void io_req_msg_cleanup(struct io_kiocb *req,
 			       unsigned int issue_flags)
 {
-	req->flags &= ~REQ_F_NEED_CLEANUP;
 	io_netmsg_recycle(req, issue_flags);
 }
 
author maintainer
#64 lore raw

PATCH 62/116 riscv: dts: starfive: Fix a typo in StarFive JH7110 pin function definitions

In reply to Greg Kroah-Hartman

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

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

From: E Shattow <[email protected]>

commit 1b133129ad6b28186214259af3bd5fc651a85509 upstream.

Fix a typo in StarFive JH7110 pin function definitions for GPOUT_SYS_SDIO1_DATA4

Fixes e22f09e598d12 ("riscv: dts: starfive: Add StarFive JH7110 pin function definitions")
---
 arch/riscv/boot/dts/starfive/jh7110-pinfunc.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/boot/dts/starfive/jh7110-pinfunc.h +1 -1
@@ -89,7 +89,7 @@
 #define GPOUT_SYS_SDIO1_DATA1			59
 #define GPOUT_SYS_SDIO1_DATA2			60
 #define GPOUT_SYS_SDIO1_DATA3			61
-#define GPOUT_SYS_SDIO1_DATA4			63
+#define GPOUT_SYS_SDIO1_DATA4			62
 #define GPOUT_SYS_SDIO1_DATA5			63
 #define GPOUT_SYS_SDIO1_DATA6			64
 #define GPOUT_SYS_SDIO1_DATA7			65
author maintainer
#65 lore raw

PATCH 63/116 netfs: Call `invalidate_cache` only if implemented

In reply to Greg Kroah-Hartman

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

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

From: Max Kellermann <[email protected]>

commit 344b7ef248f420ed4ba3a3539cb0a0fc18df9a6c upstream.

Many filesystems such as NFS and Ceph do not implement the invalidate_cache method. On those filesystems, if writing to the cache (NETFS_WRITE_TO_CACHE) fails for some reason, the kernel crashes like this:

 BUG: kernel NULL pointer dereference, address: 0000000000000000
 #PF: supervisor instruction fetch in kernel mode
 #PF: error_code(0x0010) - not-present page
 PGD 0 P4D 0
 Oops: Oops: 0010 [#1] SMP PTI
 CPU: 9 UID: 0 PID: 3380 Comm: kworker/u193:11 Not tainted 6.13.3-cm4all1-hp #437
 Hardware name: HP ProLiant DL380 Gen9/ProLiant DL380 Gen9, BIOS P89 10/17/2018
 Workqueue: events_unbound netfs_write_collection_worker
 RIP: 0010:0x0
 Code: Unable to access opcode bytes at 0xffffffffffffffd6.
 RSP: 0018:ffff9b86e2ca7dc0 EFLAGS: 00010202
 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 7fffffffffffffff
 RDX: 0000000000000001 RSI: ffff89259d576a18 RDI: ffff89259d576900
 RBP: ffff89259d5769b0 R08: ffff9b86e2ca7d28 R09: 0000000000000002
 R10: ffff89258ceaca80 R11: 0000000000000001 R12: 0000000000000020
 R13: ffff893d158b9338 R14: ffff89259d576900 R15: ffff89259d5769b0
 FS:  0000000000000000(0000) GS:ffff893c9fa40000(0000) knlGS:0000000000000000
 CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 CR2: ffffffffffffffd6 CR3: 000000054442e003 CR4: 00000000001706f0
 Call Trace:
  <TASK>
  ? __die+0x1f/0x60
  ? page_fault_oops+0x15c/0x460
  ? try_to_wake_up+0x2d2/0x530
  ? exc_page_fault+0x5e/0x100
  ? asm_exc_page_fault+0x22/0x30
  netfs_write_collection_worker+0xe9f/0x12b0
  ? xs_poll_check_readable+0x3f/0x80
  ? xs_stream_data_receive_workfn+0x8d/0x110
  process_one_work+0x134/0x2d0
  worker_thread+0x299/0x3a0
  ? __pfx_worker_thread+0x10/0x10
  kthread+0xba/0xe0
  ? __pfx_kthread+0x10/0x10
  ret_from_fork+0x30/0x50
  ? __pfx_kthread+0x10/0x10
  ret_from_fork_asm+0x1a/0x30
  </TASK>
 Modules linked in:
 CR2: 0000000000000000

This patch adds the missing NULL check.

Fixes 0e0f2dfe880f ("netfs: Dispatch write requests to process a writeback slice")
Fixes 288ace2f57c9 ("netfs: New writeback implementation")
---
 fs/netfs/write_collect.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
fs/netfs/write_collect.c +2 -1
@@ -576,7 +576,8 @@ void netfs_write_collection_worker(struc
 	trace_netfs_rreq(wreq, netfs_rreq_trace_write_done);
 
 	if (wreq->io_streams[1].active &&
-	    wreq->io_streams[1].failed) {
+	    wreq->io_streams[1].failed &&
+	    ictx->ops->invalidate_cache) {
 		/* Cache write failure doesn't prevent writeback completion
 		 * unless we're in disconnected mode.
 		 */
author maintainer
#66 lore raw

PATCH 64/116 regulator: dummy: force synchronous probing

In reply to Greg Kroah-Hartman

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

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

From: Christian Eggers <[email protected]>

commit 8619909b38eeebd3e60910158d7d68441fc954e9 upstream.

Sometimes I get a NULL pointer dereference at boot time in kobject_get() with the following call stack:

anatop_regulator_probe()
devm_regulator_register()
regulator_register()
regulator_resolve_supply()
kobject_get()

By placing some extra BUG_ON() statements I could verify that this is raised because probing of the 'dummy' regulator driver is not completed ('dummy_regulator_rdev' is still NULL).

In the JTAG debugger I can see that dummy_regulator_probe() and anatop_regulator_probe() can be run by different kernel threads (kworker/u4:*). I haven't further investigated whether this can be changed or if there are other possibilities to force synchronization between these two probe routines. On the other hand I don't expect much boot time penalty by probing the 'dummy' regulator synchronously.

Fixes 259b93b21a9f ("regulator: Set PROBE_PREFER_ASYNCHRONOUS for drivers that existed in 4.14")
---
 drivers/regulator/dummy.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/regulator/dummy.c +1 -1
@@ -60,7 +60,7 @@ static struct platform_driver dummy_regu
 	.probe		= dummy_regulator_probe,
 	.driver		= {
 		.name		= "reg-dummy",
-		.probe_type	= PROBE_PREFER_ASYNCHRONOUS,
+		.probe_type	= PROBE_FORCE_SYNCHRONOUS,
 	},
 };
 
author maintainer
#67 lore raw

PATCH 65/116 regulator: check that dummy regulator has been probed before using it

In reply to Greg Kroah-Hartman

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

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

From: Christian Eggers <[email protected]>

commit 2c7a50bec4958f1d1c84d19cde518d0e96a676fd upstream.

Due to asynchronous driver probing there is a chance that the dummy regulator hasn't already been probed when first accessing it.

---
 drivers/regulator/core.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/regulator/core.c +11 -1
@@ -2024,6 +2024,10 @@ static int regulator_resolve_supply(stru
 
 		if (have_full_constraints()) {
 			r = dummy_regulator_rdev;
+			if (!r) {
+				ret = -EPROBE_DEFER;
+				goto out;
+			}
 			get_device(&r->dev);
 		} else {
 			dev_err(dev, "Failed to resolve %s-supply for %s\n",
@@ -2041,6 +2045,10 @@ static int regulator_resolve_supply(stru
 			goto out;
 		}
 		r = dummy_regulator_rdev;
+		if (!r) {
+			ret = -EPROBE_DEFER;
+			goto out;
+		}
 		get_device(&r->dev);
 	}
 
@@ -2166,8 +2174,10 @@ struct regulator *_regulator_get_common(
 			 * enabled, even if it isn't hooked up, and just
 			 * provide a dummy.
 			 */
-			dev_warn(dev, "supply %s not found, using dummy regulator\n", id);
 			rdev = dummy_regulator_rdev;
+			if (!rdev)
+				return ERR_PTR(-EPROBE_DEFER);
+			dev_warn(dev, "supply %s not found, using dummy regulator\n", id);
 			get_device(&rdev->dev);
 			break;
 
author maintainer
#68 lore raw

PATCH 66/116 accel/qaic: Fix integer overflow in qaic_validate_req()

In reply to Greg Kroah-Hartman

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

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

From: Dan Carpenter <[email protected]>

commit 67d15c7aa0864dfd82325c7e7e7d8548b5224c7b upstream.

These are u64 variables that come from the user via qaic_attach_slice_bo_ioctl(). Use check_add_overflow() to ensure that the math doesn't have an integer wrapping bug.

---
 drivers/accel/qaic/qaic_data.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/accel/qaic/qaic_data.c +3 -1
@@ -557,6 +557,7 @@ static bool invalid_sem(struct qaic_sem
 static int qaic_validate_req(struct qaic_device *qdev, struct qaic_attach_slice_entry *slice_ent,
 			     u32 count, u64 total_size)
 {
+	u64 total;
 	int i;
 
 	for (i = 0; i < count; i++) {
@@ -566,7 +567,8 @@ static int qaic_validate_req(struct qaic
 		      invalid_sem(&slice_ent[i].sem2) || invalid_sem(&slice_ent[i].sem3))
 			return -EINVAL;
 
-		if (slice_ent[i].offset + slice_ent[i].size > total_size)
+		if (check_add_overflow(slice_ent[i].offset, slice_ent[i].size, &total) ||
+		    total > total_size)
 			return -EINVAL;
 	}
 
author maintainer
#69 lore raw

PATCH 67/116 arm64: dts: freescale: imx8mp-verdin-dahlia: add Microphone Jack to sound card

In reply to Greg Kroah-Hartman

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

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

From: Stefan Eichenberger <[email protected]>

commit b0612fdba9afdce261bfb8684e0cece6f2e2b0bb upstream.

The simple-audio-card's microphone widget currently connects to the headphone jack. Routing the microphone input to the microphone jack allows for independent operation of the microphone and headphones.

This resolves the following boot-time kernel log message, which indicated a conflict when the microphone and headphone functions were not separated:
debugfs: File 'Headphone Jack' in directory 'dapm' already present!

Fixes 874958916844 ("arm64: dts: freescale: verdin-imx8mp: dahlia: add sound card")
---
 arch/arm64/boot/dts/freescale/imx8mp-verdin-dahlia.dtsi |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm64/boot/dts/freescale/imx8mp-verdin-dahlia.dtsi +3 -3
@@ -28,10 +28,10 @@
 			"Headphone Jack", "HPOUTR",
 			"IN2L", "Line In Jack",
 			"IN2R", "Line In Jack",
-			"Headphone Jack", "MICBIAS",
-			"IN1L", "Headphone Jack";
+			"Microphone Jack", "MICBIAS",
+			"IN1L", "Microphone Jack";
 		simple-audio-card,widgets =
-			"Microphone", "Headphone Jack",
+			"Microphone", "Microphone Jack",
 			"Headphone", "Headphone Jack",
 			"Line", "Line In Jack";
 
author maintainer
#70 lore raw

PATCH 68/116 arm64: dts: freescale: imx8mm-verdin-dahlia: add Microphone Jack to sound card

In reply to Greg Kroah-Hartman

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

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

From: Stefan Eichenberger <[email protected]>

commit 2c1092823eb03f8508d6769e2f38eef7e1fe62a0 upstream.

The simple-audio-card's microphone widget currently connects to the headphone jack. Routing the microphone input to the microphone jack allows for independent operation of the microphone and headphones.

This resolves the following boot-time kernel log message, which indicated a conflict when the microphone and headphone functions were not separated:
debugfs: File 'Headphone Jack' in directory 'dapm' already present!

Fixes 6a57f224f734 ("arm64: dts: freescale: add initial support for verdin imx8m mini")
---
 arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi +3 -3
@@ -16,10 +16,10 @@
 			"Headphone Jack", "HPOUTR",
 			"IN2L", "Line In Jack",
 			"IN2R", "Line In Jack",
-			"Headphone Jack", "MICBIAS",
-			"IN1L", "Headphone Jack";
+			"Microphone Jack", "MICBIAS",
+			"IN1L", "Microphone Jack";
 		simple-audio-card,widgets =
-			"Microphone", "Headphone Jack",
+			"Microphone", "Microphone Jack",
 			"Headphone", "Headphone Jack",
 			"Line", "Line In Jack";
 
author maintainer
#71 lore raw

PATCH 69/116 arm64: dts: rockchip: fix pinmux of UART0 for PX30 Ringneck on Haikou

In reply to Greg Kroah-Hartman

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

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

From: Quentin Schulz <[email protected]>

commit 2db7d29c7b1629ced3cbab3de242511eb3c22066 upstream.

UART0 pinmux by default configures GPIO0_B5 in its UART RTS function for UART0. However, by default on Haikou, it is used as GPIO as UART RTS for UART5.

Therefore, let's update UART0 pinmux to not configure the pin in that mode, a later commit will make UART5 request the GPIO pinmux.

Fixes c484cf93f61b ("arm64: dts: rockchip: add PX30-µQ7 (Ringneck) SoM with Haikou baseboard")
---
 arch/arm64/boot/dts/rockchip/px30-ringneck-haikou.dts |    2 ++
 1 file changed, 2 insertions(+)
arch/arm64/boot/dts/rockchip/px30-ringneck-haikou.dts +2 -0
@@ -222,6 +222,8 @@
 };
 
 &uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_xfer>;
 	status = "okay";
 };
 
author maintainer
#72 lore raw

PATCH 70/116 arm64: dts: rockchip: fix pinmux of UART5 for PX30 Ringneck on Haikou

In reply to Greg Kroah-Hartman

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

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

From: Quentin Schulz <[email protected]>

commit 55de171bba1b8c0e3dd18b800955ac4b46a63d4b upstream.

UART5 uses GPIO0_B5 as UART RTS but muxed in its GPIO function, therefore UART5 must request this pin to be muxed in that function, so let's do that.

Fixes 5963d97aa780 ("arm64: dts: rockchip: add rs485 support on uart5 of px30-ringneck-haikou")
---
 arch/arm64/boot/dts/rockchip/px30-ringneck-haikou.dts |   10 ++++++++++
 1 file changed, 10 insertions(+)
arch/arm64/boot/dts/rockchip/px30-ringneck-haikou.dts +10 -0
@@ -194,6 +194,13 @@
 			  <3 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
 	};
+
+	uart {
+		uart5_rts_pin: uart5-rts-pin {
+			rockchip,pins =
+			  <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
 };
 
 &pwm0 {
@@ -228,6 +235,9 @@
 };
 
 &uart5 {
+	/* Add pinmux for rts-gpios (uart5_rts_pin) */
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart5_xfer &uart5_rts_pin>;
 	rts-gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>;
 	status = "okay";
 };
author maintainer
#73 lore raw

PATCH 71/116 arm64: dts: rockchip: Add missing PCIe supplies to RockPro64 board dtsi

In reply to Greg Kroah-Hartman

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

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

From: Dragan Simic <[email protected]>

commit ffcef3df680c437ca33ff434be18ec24d72907c2 upstream.

Add missing "vpcie0v9-supply" and "vpcie1v8-supply" properties to the "pcie0" node in the Pine64 RockPro64 board dtsi file. This eliminates the following warnings from the kernel log:

rockchip-pcie f8000000.pcie: supply vpcie1v8 not found, using dummy regulator rockchip-pcie f8000000.pcie: supply vpcie0v9 not found, using dummy regulator

These additions improve the accuracy of hardware description of the RockPro64 and, in theory, they should result in no functional changes to the way board works after the changes, because the "vcca_0v9" and "vcca_1v8" regulators are always enabled. [1][2] However, extended reliability testing, performed by Chris, [3] has proven that the age-old issues with some PCI Express cards, when used with a Pine64 RockPro64, are also resolved.

Those issues were already mentioned in the commit 43853e843aa6 (arm64: dts:
rockchip: Remove unsupported node from the Pinebook Pro dts, 2024-04-01), together with a brief description of the out-of-tree enumeration delay patch that reportedly resolves those issues. In a nutshell, booting a RockPro64 with some PCI Express cards attached to it caused a kernel oops. [4]

Symptomatically enough, to the commit author's best knowledge, only the Pine64 RockPro64, out of all RK3399-based boards and devices supported upstream, has been reported to suffer from those PCI Express issues, and only the RockPro64 had some of the PCI Express supplies missing in its DT. Thus, perhaps some weird timing issues exist that caused the "vcca_1v8" always-on regulator, which is part of the RK808 PMIC, to actually not be enabled before the PCI Express is initialized and enumerated on the RockPro64, causing oopses with some PCIe cards, and the aforementioned enumeration delay patch [4] probably acted as just a workaround for the underlying timing issue.

Admittedly, the Pine64 RockPro64 is a bit specific board by having a standard PCI Express slot, allowing use of various standard cards, but pretty much standard PCI Express cards have been attached to other RK3399 boards as well, and the commit author is unaware ot such issues reported for them.

It's quite hard to be sure that the PCI Express issues are fully resolved by these additions to the DT, without some really extensive and time-consuming testing. However, these additions to the DT can result in good things and improvements anyway, making them perfectly safe from the standpoint of being unable to do any harm or cause some unforeseen regressions.

These changes apply to the both supported hardware revisions of the Pine64 RockPro64, i.e. to the production-run revisions 2.0 and 2.1. [1][2]

[1] https://files.pine64.org/doc/rockpro64/rockpro64_v21-SCH.pdf
[2] https://files.pine64.org/doc/rockpro64/rockpro64_v20-SCH.pdf
[3] https://z9.de/hedgedoc/s/nF4d5G7rg#reboot-tests-for-PCIe-improvements
[4] https://lore.kernel.org/lkml/[email protected]/T/#u

---
 arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi |    2 ++
 1 file changed, 2 insertions(+)
arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi +2 -0
@@ -661,6 +661,8 @@
 	num-lanes = <4>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pcie_perst>;
+	vpcie0v9-supply = <&vcca_0v9>;
+	vpcie1v8-supply = <&vcca_1v8>;
 	vpcie12v-supply = <&vcc12v_dcin>;
 	vpcie3v3-supply = <&vcc3v3_pcie>;
 	status = "okay";
author maintainer
#74 lore raw

PATCH 72/116 mmc: sdhci-brcmstb: add cqhci suspend/resume to PM ops

In reply to Greg Kroah-Hartman

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

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

From: Kamal Dasu <[email protected]>

commit 723ef0e20dbb2aa1b5406d2bb75374fc48187daa upstream.

cqhci timeouts observed on brcmstb platforms during suspend:
...

  [  164.832853] mmc0: cqhci: timeout for tag 18
  ...

Adding cqhci_suspend()/resume() calls to disable cqe in sdhci_brcmstb_suspend()/resume() respectively to fix CQE timeouts seen on PM suspend.

Fixes d46ba2d17f90 ("mmc: sdhci-brcmstb: Add support for Command Queuing (CQE)")
---
 drivers/mmc/host/sdhci-brcmstb.c |   10 ++++++++++
 1 file changed, 10 insertions(+)
drivers/mmc/host/sdhci-brcmstb.c +10 -0
@@ -503,8 +503,15 @@ static int sdhci_brcmstb_suspend(struct
 	struct sdhci_host *host = dev_get_drvdata(dev);
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_brcmstb_priv *priv = sdhci_pltfm_priv(pltfm_host);
+	int ret;
 
 	clk_disable_unprepare(priv->base_clk);
+	if (host->mmc->caps2 & MMC_CAP2_CQE) {
+		ret = cqhci_suspend(host->mmc);
+		if (ret)
+			return ret;
+	}
+
 	return sdhci_pltfm_suspend(dev);
 }
 
@@ -529,6 +536,9 @@ static int sdhci_brcmstb_resume(struct d
 			ret = clk_set_rate(priv->base_clk, priv->base_freq_hz);
 	}
 
+	if (host->mmc->caps2 & MMC_CAP2_CQE)
+		ret = cqhci_resume(host->mmc);
+
 	return ret;
 }
 #endif
author maintainer
#75 lore raw

PATCH 73/116 mmc: atmel-mci: Add missing clk_disable_unprepare()

In reply to Greg Kroah-Hartman

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

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

From: Gu Bowen <[email protected]>

commit e51a349d2dcf1df8422dabb90b2f691dc7df6f92 upstream.

The error path when atmci_configure_dma() set dma fails in atmci driver does not correctly disable the clock.
Add the missing clk_disable_unprepare() to the error path for pair with clk_prepare_enable().

Fixes 467e081d23e6 ("mmc: atmel-mci: use probe deferring if dma controller is not ready yet")
---
 drivers/mmc/host/atmel-mci.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/mmc/host/atmel-mci.c +3 -1
@@ -2499,8 +2499,10 @@ static int atmci_probe(struct platform_d
 	/* Get MCI capabilities and set operations according to it */
 	atmci_get_cap(host);
 	ret = atmci_configure_dma(host);
-	if (ret == -EPROBE_DEFER)
+	if (ret == -EPROBE_DEFER) {
+		clk_disable_unprepare(host->mck);
 		goto err_dma_probe_defer;
+	}
 	if (ret == 0) {
 		host->prepare_data = &atmci_prepare_data_dma;
 		host->submit_data = &atmci_submit_data_dma;
author maintainer
#76 lore raw

PATCH 74/116 selftests/mm: run_vmtests.sh: fix half_ufd_size_MB calculation

In reply to Greg Kroah-Hartman

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

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

From: Rafael Aquini <[email protected]>

commit 67a2f86846f244d81601cf2e1552c4656b8556d6 upstream.

We noticed that uffd-stress test was always failing to run when invoked for the hugetlb profiles on x86_64 systems with a processor count of 64 or bigger:

...
# ------------------------------------

  # running ./uffd-stress hugetlb 128 32
  # ------------------------------------
  # ERROR: invalid MiB (errno=9, @uffd-stress.c:459)
  ...
  # [FAIL]
  not ok 3 uffd-stress hugetlb 128 32 # exit=1
  ...

The problem boils down to how run_vmtests.sh (mis)calculates the size of the region it feeds to uffd-stress. The latter expects to see an amount of MiB while the former is just giving out the number of free hugepages halved down. This measurement discrepancy ends up violating uffd-stress' assertion on number of hugetlb pages allocated per CPU, causing it to bail out with the error above.

This commit fixes that issue by adjusting run_vmtests.sh's half_ufd_size_MB calculation so it properly renders the region size in MiB, as expected, while maintaining all of its original constraints in place.

Fixes 2e47a445d7b3 ("selftests/mm: run_vmtests.sh: fix hugetlb mem size calculation")
Cc Shuah Khan <[email protected]>
---
 tools/testing/selftests/mm/run_vmtests.sh |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
tools/testing/selftests/mm/run_vmtests.sh +3 -1
@@ -300,7 +300,9 @@ uffd_stress_bin=./uffd-stress
 CATEGORY="userfaultfd" run_test ${uffd_stress_bin} anon 20 16
 # Hugetlb tests require source and destination huge pages. Pass in half
 # the size of the free pages we have, which is used for *each*.
-half_ufd_size_MB=$((freepgs / 2))
+# uffd-stress expects a region expressed in MiB, so we adjust
+# half_ufd_size_MB accordingly.
+half_ufd_size_MB=$(((freepgs * hpgsize_KB) / 1024 / 2))
 CATEGORY="userfaultfd" run_test ${uffd_stress_bin} hugetlb "$half_ufd_size_MB" 32
 CATEGORY="userfaultfd" run_test ${uffd_stress_bin} hugetlb-private "$half_ufd_size_MB" 32
 CATEGORY="userfaultfd" run_test ${uffd_stress_bin} shmem 20 16
author maintainer
#77 lore raw

PATCH 75/116 mm: fix error handling in __filemap_get_folio() with FGP_NOWAIT

In reply to Greg Kroah-Hartman

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

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

From: Raphael S. Carvalho <[email protected]>

commit 182db972c9568dc530b2f586a2f82dfd039d9f2a upstream.

original report:
https://lore.kernel.org/all/CAKhLTr1UL3ePTpYjXOx2AJfNk8Ku2EdcEfu+CH1sf3Asr=B-Dw@mail.gmail.com/T/

When doing buffered writes with FGP_NOWAIT, under memory pressure, the system returned ENOMEM despite there being plenty of available memory, to be reclaimed from page cache. The user space used io_uring interface, which in turn submits I/O with FGP_NOWAIT (the fast path).

retsnoop pointed to iomap_get_folio:

00:34:16.180612 -> 00:34:16.180651 TID/PID 253786/253721 (reactor-1/combined_tests):

                    entry_SYSCALL_64_after_hwframe+0x76
                    do_syscall_64+0x82
                    __do_sys_io_uring_enter+0x265
                    io_submit_sqes+0x209
                    io_issue_sqe+0x5b
                    io_write+0xdd
                    xfs_file_buffered_write+0x84
                    iomap_file_buffered_write+0x1a6
    32us [-ENOMEM]  iomap_write_begin+0x408

iter=&{.inode=0xffff8c67aa031138,.len=4096,.flags=33,.iomap={.addr=0xffffffffffffffff,.length=4096,.type=1,.flags=3,.bdev=0x… pos=0 len=4096 foliop=0xffffb32c296b7b80
! 4us [-ENOMEM] iomap_get_folio
iter=&{.inode=0xffff8c67aa031138,.len=4096,.flags=33,.iomap={.addr=0xffffffffffffffff,.length=4096,.type=1,.flags=3,.bdev=0x… pos=0 len=4096

This is likely a regression caused by 66dabbb65d67 ("mm: return an ERR_PTR from __filemap_get_folio"), which moved error handling from io_map_get_folio() to __filemap_get_folio(), but broke FGP_NOWAIT handling, so ENOMEM is being escaped to user space. Had it correctly returned -EAGAIN with NOWAIT, either io_uring or user space itself would be able to retry the request.

It's not enough to patch io_uring since the iomap interface is the one responsible for it, and pwritev2(RWF_NOWAIT) and AIO interfaces must return the proper error too.

The patch was tested with scylladb test suite (its original reproducer), and the tests all pass now when memory is pressured.

Fixes 66dabbb65d67 ("mm: return an ERR_PTR from __filemap_get_folio")
Cc "Darrick J. Wong" <[email protected]>
Cc Matthew Wilcow (Oracle) <[email protected]>
---
 mm/filemap.c |   13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
mm/filemap.c +12 -1
@@ -1966,8 +1966,19 @@ no_page:
 
 		if (err == -EEXIST)
 			goto repeat;
-		if (err)
+		if (err) {
+			/*
+			 * When NOWAIT I/O fails to allocate folios this could
+			 * be due to a nonblocking memory allocation and not
+			 * because the system actually is out of memory.
+			 * Return -EAGAIN so that there caller retries in a
+			 * blocking fashion instead of propagating -ENOMEM
+			 * to the application.
+			 */
+			if ((fgp_flags & FGP_NOWAIT) && err == -ENOMEM)
+				err = -EAGAIN;
 			return ERR_PTR(err);
+		}
 		/*
 		 * filemap_add_folio locks the page, and for mmap
 		 * we expect an unlocked page.
author maintainer
#78 lore raw

PATCH 76/116 mm/migrate: fix shmem xarray update during migration

In reply to Greg Kroah-Hartman

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

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

From: Zi Yan <[email protected]>

commit 60cf233b585cdf1f3c5e52d1225606b86acd08b0 upstream.

A shmem folio can be either in page cache or in swap cache, but not at the same time. Namely, once it is in swap cache, folio->mapping should be NULL, and the folio is no longer in a shmem mapping.

In __folio_migrate_mapping(), to determine the number of xarray entries to update, folio_test_swapbacked() is used, but that conflates shmem in page cache case and shmem in swap cache case. It leads to xarray multi-index entry corruption, since it turns a sibling entry to a normal entry during xas_store() (see [1] for a userspace reproduction). Fix it by only using folio_test_swapcache() to determine whether xarray is storing swap cache entries or not to choose the right number of xarray entries to update.

[1] https://lore.kernel.org/linux-mm/[email protected]/

Note:
In __split_huge_page(), folio_test_anon() && folio_test_swapcache() is used to get swap_cache address space, but that ignores the shmem folio in swap cache case. It could lead to NULL pointer dereferencing when a in-swap-cache shmem folio is split at __xa_store(), since !folio_test_anon() is true and folio->mapping is NULL. But fortunately, its caller split_huge_page_to_list_to_order() bails out early with EBUSY when folio->mapping is NULL. So no need to take care of it here.

---
 mm/migrate.c |   10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)
mm/migrate.c +4 -6
@@ -526,15 +526,13 @@ static int __folio_migrate_mapping(struc
 	if (folio_test_anon(folio) && folio_test_large(folio))
 		mod_mthp_stat(folio_order(folio), MTHP_STAT_NR_ANON, 1);
 	folio_ref_add(newfolio, nr); /* add cache reference */
-	if (folio_test_swapbacked(folio)) {
+	if (folio_test_swapbacked(folio))
 		__folio_set_swapbacked(newfolio);
-		if (folio_test_swapcache(folio)) {
-			folio_set_swapcache(newfolio);
-			newfolio->private = folio_get_private(folio);
-		}
+	if (folio_test_swapcache(folio)) {
+		folio_set_swapcache(newfolio);
+		newfolio->private = folio_get_private(folio);
 		entries = nr;
 	} else {
-		VM_BUG_ON_FOLIO(folio_test_swapcache(folio), folio);
 		entries = 1;
 	}
 
author maintainer
#79 lore raw

PATCH 77/116 mm/page_alloc: fix memory accept before watermarks gets initialized

In reply to Greg Kroah-Hartman

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

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

From: Kirill A. Shutemov <[email protected]>

commit 800f1059c99e2b39899bdc67a7593a7bea6375d8 upstream.

Watermarks are initialized during the postcore initcall. Until then, all watermarks are set to zero. This causes cond_accept_memory() to incorrectly skip memory acceptance because a watermark of 0 is always met.

This can lead to a premature OOM on boot.

To ensure progress, accept one MAX_ORDER page if the watermark is zero.

Fixes dcdfdd40fa82 ("mm: Add support for unaccepted memory")
Cc Ashish Kalra <[email protected]>
Cc David Hildenbrand <[email protected]>
Cc "Edgecombe, Rick P" <[email protected]>
Cc Mel Gorman <[email protected]>
Cc "Mike Rapoport (IBM)" <[email protected]>
Cc Thomas Lendacky <[email protected]>
Cc <[email protected]> [6.5+]
---
 mm/page_alloc.c |   14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
mm/page_alloc.c +12 -2
@@ -7094,7 +7094,7 @@ static inline bool has_unaccepted_memory
 
 static bool cond_accept_memory(struct zone *zone, unsigned int order)
 {
-	long to_accept;
+	long to_accept, wmark;
 	bool ret = false;
 
 	if (!has_unaccepted_memory())
@@ -7103,8 +7103,18 @@ static bool cond_accept_memory(struct zo
 	if (list_empty(&zone->unaccepted_pages))
 		return false;
 
+	wmark = promo_wmark_pages(zone);
+
+	/*
+	 * Watermarks have not been initialized yet.
+	 *
+	 * Accepting one MAX_ORDER page to ensure progress.
+	 */
+	if (!wmark)
+		return try_to_accept_memory_one(zone);
+
 	/* How much to accept to get to promo watermark? */
-	to_accept = promo_wmark_pages(zone) -
+	to_accept = wmark -
 		    (zone_page_state(zone, NR_FREE_PAGES) -
 		    __zone_watermark_unusable_free(zone, order, 0) -
 		    zone_page_state(zone, NR_UNACCEPTED));
author maintainer
#80 lore raw

PATCH 78/116 proc: fix UAF in proc_get_inode()

In reply to Greg Kroah-Hartman

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

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

From: Ye Bin <[email protected]>

commit 654b33ada4ab5e926cd9c570196fefa7bec7c1df upstream.

Fix race between rmmod and /proc/XXX's inode instantiation.

The bug is that pde->proc_ops don't belong to /proc, it belongs to a module, therefore dereferencing it after /proc entry has been registered is a bug unless use_pde/unuse_pde() pair has been used.

use_pde/unuse_pde can be avoided (2 atomic ops!) because pde->proc_ops never changes so information necessary for inode instantiation can be saved _before_ proc_register() in PDE itself and used later, avoiding pde->proc_ops->... dereference.

rmmod lookup
sys_delete_module

                         proc_lookup_de
			   pde_get(de);
			   proc_get_inode(dir->i_sb, de);
  mod->exit()
    proc_remove
      remove_proc_subtree
       proc_entry_rundown(de);

free_module(mod);

                               if (S_ISREG(inode->i_mode))
	                         if (de->proc_ops->proc_read_iter)
                           --> As module is already freed, will trigger UAF
BUG: unable to handle page fault for address: fffffbfff80a702b
PGD 817fc4067 P4D 817fc4067 PUD 817fc0067 PMD 102ef4067 PTE 0
Oops: Oops: 0000 [#1] PREEMPT SMP KASAN PTI
CPU: 26 UID: 0 PID: 2667 Comm: ls Tainted: G
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996)
RIP: 0010:proc_get_inode+0x302/0x6e0
RSP: 0018:ffff88811c837998 EFLAGS: 00010a06
RAX: dffffc0000000000 RBX: ffffffffc0538140 RCX: 0000000000000007
RDX: 1ffffffff80a702b RSI: 0000000000000001 RDI: ffffffffc0538158
RBP: ffff8881299a6000 R08: 0000000067bbe1e5 R09: 1ffff11023906f20
R10: ffffffffb560ca07 R11: ffffffffb2b43a58 R12: ffff888105bb78f0
R13: ffff888100518048 R14: ffff8881299a6004 R15: 0000000000000001
FS:  00007f95b9686840(0000) GS:ffff8883af100000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: fffffbfff80a702b CR3: 0000000117dd2000 CR4: 00000000000006f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 <TASK>
 proc_lookup_de+0x11f/0x2e0
 __lookup_slow+0x188/0x350
 walk_component+0x2ab/0x4f0
 path_lookupat+0x120/0x660
 filename_lookup+0x1ce/0x560
 vfs_statx+0xac/0x150
 __do_sys_newstat+0x96/0x110
 do_syscall_64+0x5f/0x170
 entry_SYSCALL_64_after_hwframe+0x76/0x7e
[[email protected]: don't do 2 atomic ops on the common path]
Fixes 778f3dd5a13c ("Fix procfs compat_ioctl regression")
Cc Al Viro <[email protected]>
Cc David S. Miller <[email protected]>
---
 fs/proc/generic.c       |   10 +++++++++-
 fs/proc/inode.c         |    6 +++---
 fs/proc/internal.h      |   14 ++++++++++++++
 include/linux/proc_fs.h |    7 +++++--
 4 files changed, 31 insertions(+), 6 deletions(-)
fs/proc/generic.c +9 -1
@@ -557,10 +557,16 @@ struct proc_dir_entry *proc_create_reg(c
 	return p;
 }
 
-static inline void pde_set_flags(struct proc_dir_entry *pde)
+static void pde_set_flags(struct proc_dir_entry *pde)
 {
 	if (pde->proc_ops->proc_flags & PROC_ENTRY_PERMANENT)
 		pde->flags |= PROC_ENTRY_PERMANENT;
+	if (pde->proc_ops->proc_read_iter)
+		pde->flags |= PROC_ENTRY_proc_read_iter;
+#ifdef CONFIG_COMPAT
+	if (pde->proc_ops->proc_compat_ioctl)
+		pde->flags |= PROC_ENTRY_proc_compat_ioctl;
+#endif
 }
 
 struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
@@ -624,6 +630,7 @@ struct proc_dir_entry *proc_create_seq_p
 	p->proc_ops = &proc_seq_ops;
 	p->seq_ops = ops;
 	p->state_size = state_size;
+	pde_set_flags(p);
 	return proc_register(parent, p);
 }
 EXPORT_SYMBOL(proc_create_seq_private);
@@ -654,6 +661,7 @@ struct proc_dir_entry *proc_create_singl
 		return NULL;
 	p->proc_ops = &proc_single_ops;
 	p->single_show = show;
+	pde_set_flags(p);
 	return proc_register(parent, p);
 }
 EXPORT_SYMBOL(proc_create_single_data);
fs/proc/inode.c +3 -3
@@ -656,13 +656,13 @@ struct inode *proc_get_inode(struct supe
 
 	if (S_ISREG(inode->i_mode)) {
 		inode->i_op = de->proc_iops;
-		if (de->proc_ops->proc_read_iter)
+		if (pde_has_proc_read_iter(de))
 			inode->i_fop = &proc_iter_file_ops;
 		else
 			inode->i_fop = &proc_reg_file_ops;
 #ifdef CONFIG_COMPAT
-		if (de->proc_ops->proc_compat_ioctl) {
-			if (de->proc_ops->proc_read_iter)
+		if (pde_has_proc_compat_ioctl(de)) {
+			if (pde_has_proc_read_iter(de))
 				inode->i_fop = &proc_iter_file_ops_compat;
 			else
 				inode->i_fop = &proc_reg_file_ops_compat;
fs/proc/internal.h +14 -0
@@ -85,6 +85,20 @@ static inline void pde_make_permanent(st
 	pde->flags |= PROC_ENTRY_PERMANENT;
 }
 
+static inline bool pde_has_proc_read_iter(const struct proc_dir_entry *pde)
+{
+	return pde->flags & PROC_ENTRY_proc_read_iter;
+}
+
+static inline bool pde_has_proc_compat_ioctl(const struct proc_dir_entry *pde)
+{
+#ifdef CONFIG_COMPAT
+	return pde->flags & PROC_ENTRY_proc_compat_ioctl;
+#else
+	return false;
+#endif
+}
+
 extern struct kmem_cache *proc_dir_entry_cache;
 void pde_free(struct proc_dir_entry *pde);
 
include/linux/proc_fs.h +5 -2
@@ -20,10 +20,13 @@ enum {
 	 * If in doubt, ignore this flag.
 	 */
 #ifdef MODULE
-	PROC_ENTRY_PERMANENT = 0U,
+	PROC_ENTRY_PERMANENT		= 0U,
 #else
-	PROC_ENTRY_PERMANENT = 1U << 0,
+	PROC_ENTRY_PERMANENT		= 1U << 0,
 #endif
+
+	PROC_ENTRY_proc_read_iter	= 1U << 1,
+	PROC_ENTRY_proc_compat_ioctl	= 1U << 2,
 };
 
 struct proc_ops {
author maintainer
#81 lore raw

PATCH 79/116 memcg: drain obj stock on cpu hotplug teardown

In reply to Greg Kroah-Hartman

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

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

From: Shakeel Butt <[email protected]>

commit 9f01b4954490d4ccdbcc2b9be34a9921ceee9cbb upstream.

Currently on cpu hotplug teardown, only memcg stock is drained but we need to drain the obj stock as well otherwise we will miss the stats accumulated on the target cpu as well as the nr_bytes cached. The stats include MEMCG_KMEM, NR_SLAB_RECLAIMABLE_B & NR_SLAB_UNRECLAIMABLE_B. In addition we are leaking reference to struct obj_cgroup object.

---
 mm/memcontrol.c |    9 +++++++++
 1 file changed, 9 insertions(+)
mm/memcontrol.c +9 -0
@@ -1882,9 +1882,18 @@ void drain_all_stock(struct mem_cgroup *
 static int memcg_hotplug_cpu_dead(unsigned int cpu)
 {
 	struct memcg_stock_pcp *stock;
+	struct obj_cgroup *old;
+	unsigned long flags;
 
 	stock = &per_cpu(memcg_stock, cpu);
+
+	/* drain_obj_stock requires stock_lock */
+	local_lock_irqsave(&memcg_stock.stock_lock, flags);
+	old = drain_obj_stock(stock);
+	local_unlock_irqrestore(&memcg_stock.stock_lock, flags);
+
 	drain_stock(stock);
+	obj_cgroup_put(old);
 
 	return 0;
 }
author maintainer
#82 lore raw

PATCH 80/116 ARM: dts: imx6qdl-apalis: Fix poweroff on Apalis iMX6

In reply to Greg Kroah-Hartman

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

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

From: Stefan Eichenberger <[email protected]>

commit 83964a29379cb08929a39172780a4c2992bc7c93 upstream.

The current solution for powering off the Apalis iMX6 is not functioning as intended. To resolve this, it is necessary to power off the vgen2_reg, which will also set the POWER_ENABLE_MOCI signal to a low state. This ensures the carrier board is properly informed to initiate its power-off sequence.

The new solution uses the regulator-poweroff driver, which will power off the regulator during a system shutdown.

Fixes 4eb56e26f92e ("ARM: dts: imx6q-apalis: Command pmic to standby for poweroff")
---
 arch/arm/boot/dts/nxp/imx/imx6qdl-apalis.dtsi |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
arch/arm/boot/dts/nxp/imx/imx6qdl-apalis.dtsi +5 -5
@@ -108,6 +108,11 @@
 		};
 	};
 
+	poweroff {
+		compatible = "regulator-poweroff";
+		cpu-supply = <&vgen2_reg>;
+	};
+
 	reg_module_3v3: regulator-module-3v3 {
 		compatible = "regulator-fixed";
 		regulator-always-on;
@@ -236,10 +241,6 @@
 	status = "disabled";
 };
 
-&clks {
-	fsl,pmic-stby-poweroff;
-};
-
 /* Apalis SPI1 */
 &ecspi1 {
 	cs-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>;
@@ -527,7 +528,6 @@
 
 	pmic: pmic@8 {
 		compatible = "fsl,pfuze100";
-		fsl,pmic-stby-poweroff;
 		reg = <0x08>;
 
 		regulators {
author maintainer
#83 lore raw

PATCH 81/116 ARM: shmobile: smp: Enforce shmobile_smp_* alignment

In reply to Greg Kroah-Hartman

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

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

From: Geert Uytterhoeven <[email protected]>

commit 379c590113ce46f605439d4887996c60ab8820cc upstream.

When the addresses of the shmobile_smp_mpidr, shmobile_smp_fn, and shmobile_smp_arg variables are not multiples of 4 bytes, secondary CPU bring-up fails:

smp: Bringing up secondary CPUs ...
CPU1: failed to come online
CPU2: failed to come online
CPU3: failed to come online
smp: Brought up 1 node, 1 CPU

Fix this by adding the missing alignment directive.

---
 arch/arm/mach-shmobile/headsmp.S |    1 +
 1 file changed, 1 insertion(+)
arch/arm/mach-shmobile/headsmp.S +1 -0
@@ -136,6 +136,7 @@ ENDPROC(shmobile_smp_sleep)
 	.long	shmobile_smp_arg - 1b
 
 	.bss
+	.align	2
 	.globl	shmobile_smp_mpidr
 shmobile_smp_mpidr:
 	.space	NR_CPUS * 4
author maintainer
#84 lore raw

PATCH 82/116 firmware: qcom: uefisecapp: fix efivars registration race

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit da8d493a80993972c427002684d0742560f3be4a upstream.

Since the conversion to using the TZ allocator, the efivars service is registered before the memory pool has been allocated, something which can lead to a NULL-pointer dereference in case of a racing EFI variable access.

Make sure that all resources have been set up before registering the efivars.

---
 drivers/firmware/qcom/qcom_qseecom_uefisecapp.c |   18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)
drivers/firmware/qcom/qcom_qseecom_uefisecapp.c +9 -9
@@ -814,15 +814,6 @@ static int qcom_uefisecapp_probe(struct
 
 	qcuefi->client = container_of(aux_dev, struct qseecom_client, aux_dev);
 
-	auxiliary_set_drvdata(aux_dev, qcuefi);
-	status = qcuefi_set_reference(qcuefi);
-	if (status)
-		return status;
-
-	status = efivars_register(&qcuefi->efivars, &qcom_efivar_ops);
-	if (status)
-		qcuefi_set_reference(NULL);
-
 	memset(&pool_config, 0, sizeof(pool_config));
 	pool_config.initial_size = SZ_4K;
 	pool_config.policy = QCOM_TZMEM_POLICY_MULTIPLIER;
@@ -833,6 +824,15 @@ static int qcom_uefisecapp_probe(struct
 	if (IS_ERR(qcuefi->mempool))
 		return PTR_ERR(qcuefi->mempool);
 
+	auxiliary_set_drvdata(aux_dev, qcuefi);
+	status = qcuefi_set_reference(qcuefi);
+	if (status)
+		return status;
+
+	status = efivars_register(&qcuefi->efivars, &qcom_efivar_ops);
+	if (status)
+		qcuefi_set_reference(NULL);
+
 	return status;
 }
 
author maintainer
#85 lore raw

PATCH 83/116 efi/libstub: Avoid physical address 0x0 when doing random allocation

In reply to Greg Kroah-Hartman

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

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

From: Ard Biesheuvel <[email protected]>

commit cb16dfed0093217a68c0faa9394fa5823927e04c upstream.

Ben reports spurious EFI zboot failures on a system where physical RAM starts at 0x0. When doing random memory allocation from the EFI stub on such a platform, a random seed of 0x0 (which means no entropy source is available) will result in the allocation to be placed at address 0x0 if sufficient space is available.

When this allocation is subsequently passed on to the decompression code, the 0x0 address is mistaken for NULL and the code complains and gives up.

So avoid address 0x0 when doing random allocation, and set the minimum address to the minimum alignment.

---
 drivers/firmware/efi/libstub/randomalloc.c |    4 ++++
 1 file changed, 4 insertions(+)
drivers/firmware/efi/libstub/randomalloc.c +4 -0
@@ -75,6 +75,10 @@ efi_status_t efi_random_alloc(unsigned l
 	if (align < EFI_ALLOC_ALIGN)
 		align = EFI_ALLOC_ALIGN;
 
+	/* Avoid address 0x0, as it can be mistaken for NULL */
+	if (alloc_min == 0)
+		alloc_min = align;
+
 	size = round_up(size, EFI_ALLOC_ALIGN);
 
 	/* count the suitable slots in each memory map entry */
author maintainer
#86 lore raw

PATCH 84/116 keys: Fix UAF in key_put()

In reply to Greg Kroah-Hartman

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

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

From: David Howells <[email protected]>

commit 75845c6c1a64483e9985302793dbf0dfa5f71e32 upstream.

Once a key's reference count has been reduced to 0, the garbage collector thread may destroy it at any time and so key_put() is not allowed to touch the key after that point. The most key_put() is normally allowed to do is to touch key_gc_work as that's a static global variable.

However, in an effort to speed up the reclamation of quota, this is now done in key_put() once the key's usage is reduced to 0 - but now the code is looking at the key after the deadline, which is forbidden.

Fix this by using a flag to indicate that a key can be gc'd now rather than looking at the key's refcount in the garbage collector.

---
 include/linux/key.h |    1 +
 security/keys/gc.c  |    4 +++-
 security/keys/key.c |    2 ++
 3 files changed, 6 insertions(+), 1 deletion(-)
include/linux/key.h +1 -0
@@ -236,6 +236,7 @@ struct key {
 #define KEY_FLAG_ROOT_CAN_INVAL	7	/* set if key can be invalidated by root without permission */
 #define KEY_FLAG_KEEP		8	/* set if key should not be removed */
 #define KEY_FLAG_UID_KEYRING	9	/* set if key is a user or user session keyring */
+#define KEY_FLAG_FINAL_PUT	10	/* set if final put has happened on key */
 
 	/* the key type and key description string
 	 * - the desc is used to match a key against search criteria
security/keys/gc.c +3 -1
@@ -218,8 +218,10 @@ continue_scanning:
 		key = rb_entry(cursor, struct key, serial_node);
 		cursor = rb_next(cursor);
 
-		if (refcount_read(&key->usage) == 0)
+		if (test_bit(KEY_FLAG_FINAL_PUT, &key->flags)) {
+			smp_mb(); /* Clobber key->user after FINAL_PUT seen. */
 			goto found_unreferenced_key;
+		}
 
 		if (unlikely(gc_state & KEY_GC_REAPING_DEAD_1)) {
 			if (key->type == key_gc_dead_keytype) {
security/keys/key.c +2 -0
@@ -658,6 +658,8 @@ void key_put(struct key *key)
 				key->user->qnbytes -= key->quotalen;
 				spin_unlock_irqrestore(&key->user->lock, flags);
 			}
+			smp_mb(); /* key->user before FINAL_PUT set. */
+			set_bit(KEY_FLAG_FINAL_PUT, &key->flags);
 			schedule_work(&key_gc_work);
 		}
 	}
author maintainer
#87 lore raw

PATCH 85/116 xsk: fix an integer overflow in xp_create_and_assign_umem()

In reply to Greg Kroah-Hartman

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

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

From: Gavrilov Ilia <[email protected]>

commit 559847f56769037e5b2e0474d3dbff985b98083d upstream.

Since the i and pool->chunk_size variables are of type 'u32', their product can wrap around and then be cast to 'u64'. This can lead to two different XDP buffers pointing to the same memory area.

Found by InfoTeCS on behalf of Linux Verification Center (linuxtesting.org) with SVACE.

---
 net/xdp/xsk_buff_pool.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/xdp/xsk_buff_pool.c +1 -1
@@ -106,7 +106,7 @@ struct xsk_buff_pool *xp_create_and_assi
 		if (pool->unaligned)
 			pool->free_heads[i] = xskb;
 		else
-			xp_init_xskb_addr(xskb, pool, i * pool->chunk_size);
+			xp_init_xskb_addr(xskb, pool, (u64)i * pool->chunk_size);
 	}
 
 	return pool;
author maintainer
#88 lore raw

PATCH 86/116 batman-adv: Ignore own maximum aggregation size during RX

In reply to Greg Kroah-Hartman

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

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

From: Sven Eckelmann <[email protected]>

commit 548b0c5de7619ef53bbde5590700693f2f6d2a56 upstream.

An OGMv1 and OGMv2 packet receive processing were not only limited by the number of bytes in the received packet but also by the nodes maximum aggregation packet size limit. But this limit is relevant for TX and not for RX. It must not be enforced by batadv_(i)v_ogm_aggr_packet to avoid loss of information in case of a different limit for sender and receiver.

This has a minor side effect for B.A.T.M.A.N. IV because the batadv_iv_ogm_aggr_packet is also used for the preprocessing for the TX. But since the aggregation code itself will not allow more than BATADV_MAX_AGGREGATION_BYTES bytes, this check was never triggering (in this context) prior of removing it.

Fixes c6c8fea29769 ("net: Add batman-adv meshing protocol")
Fixes 9323158ef9f4 ("batman-adv: OGMv2 - implement originators logic")
---
 net/batman-adv/bat_iv_ogm.c |    3 +--
 net/batman-adv/bat_v_ogm.c  |    3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)
net/batman-adv/bat_iv_ogm.c +1 -2
@@ -324,8 +324,7 @@ batadv_iv_ogm_aggr_packet(int buff_pos,
 	/* check if there is enough space for the optional TVLV */
 	next_buff_pos += ntohs(ogm_packet->tvlv_len);
 
-	return (next_buff_pos <= packet_len) &&
-	       (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
+	return next_buff_pos <= packet_len;
 }
 
 /* send a batman ogm to a given interface */
net/batman-adv/bat_v_ogm.c +1 -2
@@ -839,8 +839,7 @@ batadv_v_ogm_aggr_packet(int buff_pos, i
 	/* check if there is enough space for the optional TVLV */
 	next_buff_pos += ntohs(ogm2_packet->tvlv_len);
 
-	return (next_buff_pos <= packet_len) &&
-	       (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
+	return next_buff_pos <= packet_len;
 }
 
 /**
author maintainer
#89 lore raw

PATCH 87/116 soc: qcom: pdr: Fix the potential deadlock

In reply to Greg Kroah-Hartman

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

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

From: Saranya R <[email protected]>

commit 2eeb03ad9f42dfece63051be2400af487ddb96d2 upstream.

When some client process A call pdr_add_lookup() to add the look up for the service and does schedule locator work, later a process B got a new server packet indicating locator is up and call pdr_locator_new_server() which eventually sets pdr->locator_init_complete to true which process A sees and takes list lock and queries domain list but it will timeout due to deadlock as the response will queued to the same qmi->wq and it is ordered workqueue and process B is not able to complete new server request work due to deadlock on list lock.

Fix it by removing the unnecessary list iteration as the list iteration is already being done inside locator work, so avoid it here and just call schedule_work() here.

Process A Process B

process_scheduled_works()
pdr_add_lookup() qmi_data_ready_work()
process_scheduled_works() pdr_locator_new_server()

                                         pdr->locator_init_complete=true;
   pdr_locator_work()
    mutex_lock(&pdr->list_lock);

     pdr_locate_service()                  mutex_lock(&pdr->list_lock);

      pdr_get_domain_list()
       pr_err("PDR: %s get domain list
               txn wait failed: %d\n",
               req->service_name,
               ret);

Timeout error log due to deadlock:

"
PDR: tms/servreg get domain list txn wait failed: -110
PDR: service lookup for msm/adsp/sensor_pd:tms/servreg failed: -110
"

Thanks to Bjorn and Johan for letting me know that this commit also fixes an audio regression when using the in-kernel pd-mapper as that makes it easier to hit this race. [1]

---
 drivers/soc/qcom/pdr_interface.c |    8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)
drivers/soc/qcom/pdr_interface.c +1 -7
@@ -75,7 +75,6 @@ static int pdr_locator_new_server(struct
 {
 	struct pdr_handle *pdr = container_of(qmi, struct pdr_handle,
 					      locator_hdl);
-	struct pdr_service *pds;
 
 	mutex_lock(&pdr->lock);
 	/* Create a local client port for QMI communication */
@@ -87,12 +86,7 @@ static int pdr_locator_new_server(struct
 	mutex_unlock(&pdr->lock);
 
 	/* Service pending lookup requests */
-	mutex_lock(&pdr->list_lock);
-	list_for_each_entry(pds, &pdr->lookups, node) {
-		if (pds->need_locator_lookup)
-			schedule_work(&pdr->locator_work);
-	}
-	mutex_unlock(&pdr->list_lock);
+	schedule_work(&pdr->locator_work);
 
 	return 0;
 }
author maintainer
#90 lore raw

PATCH 88/116 pmdomain: amlogic: fix T7 ISP secpower

In reply to Greg Kroah-Hartman

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

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

From: Xianwei Zhao <[email protected]>

commit ef17b519088ee0c167cf507820609732ec8bad1a upstream.

ISP and MIPI_ISP, these two have a parent-child relationship, ISP depends on MIPI_ISP.

Fixes ca75e4b214c6 ("pmdomain: amlogic: Add support for T7 power domains controller")
---
 drivers/pmdomain/amlogic/meson-secure-pwrc.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pmdomain/amlogic/meson-secure-pwrc.c +1 -1
@@ -221,7 +221,7 @@ static const struct meson_secure_pwrc_do
 	SEC_PD(T7_VI_CLK2,	0),
 	/* ETH is for ethernet online wakeup, and should be always on */
 	SEC_PD(T7_ETH,		GENPD_FLAG_ALWAYS_ON),
-	SEC_PD(T7_ISP,		0),
+	TOP_PD(T7_ISP,		0, PWRC_T7_MIPI_ISP_ID),
 	SEC_PD(T7_MIPI_ISP,	0),
 	TOP_PD(T7_GDC,		0, PWRC_T7_NIC3_ID),
 	TOP_PD(T7_DEWARP,	0, PWRC_T7_NIC3_ID),
author maintainer
#91 lore raw

PATCH 89/116 drm/radeon: fix uninitialized size issue in radeon_vce_cs_parse()

In reply to Greg Kroah-Hartman

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

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

From: Nikita Zhandarovich <[email protected]>

commit dd8689b52a24807c2d5ce0a17cb26dc87f75235c upstream.

On the off chance that command stream passed from userspace via ioctl() call to radeon_vce_cs_parse() is weirdly crafted and first command to execute is to encode (case 0x03000001), the function in question will attempt to call radeon_vce_cs_reloc() with size argument that has not been properly initialized. Specifically, 'size' will point to 'tmp' variable before the latter had a chance to be assigned any value.

Play it safe and init 'tmp' with 0, thus ensuring that radeon_vce_cs_reloc() will catch an early error in cases like these.

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

Fixes 2fc5703abda2 ("drm/radeon: check VCE relocation buffer range v3")
(cherry picked from commit 2d52de55f9ee7aaee0e09ac443f77855989c6b68)
---
 drivers/gpu/drm/radeon/radeon_vce.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/radeon/radeon_vce.c +1 -1
@@ -557,7 +557,7 @@ int radeon_vce_cs_parse(struct radeon_cs
 {
 	int session_idx = -1;
 	bool destroyed = false, created = false, allocated = false;
-	uint32_t tmp, handle = 0;
+	uint32_t tmp = 0, handle = 0;
 	uint32_t *size = &tmp;
 	int i, r = 0;
 
author maintainer
#92 lore raw

PATCH 90/116 drm/sched: Fix fence reference count leak

In reply to Greg Kroah-Hartman

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

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

From: qianyi liu <[email protected]>

commit a952f1ab696873be124e31ce5ef964d36bce817f upstream.

The last_scheduled fence leaks when an entity is being killed and adding the cleanup callback fails.

Decrement the reference count of prev when dma_fence_add_callback() fails, ensuring proper balance.

[phasta: add git tag info for stable kernel]
Fixes 2fdb8a8f07c2 ("drm/scheduler: rework entity flush, kill and fini")
---
 drivers/gpu/drm/scheduler/sched_entity.c |   11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/gpu/drm/scheduler/sched_entity.c +9 -2
@@ -259,9 +259,16 @@ static void drm_sched_entity_kill(struct
 		struct drm_sched_fence *s_fence = job->s_fence;
 
 		dma_fence_get(&s_fence->finished);
-		if (!prev || dma_fence_add_callback(prev, &job->finish_cb,
-					   drm_sched_entity_kill_jobs_cb))
+		if (!prev ||
+		    dma_fence_add_callback(prev, &job->finish_cb,
+					   drm_sched_entity_kill_jobs_cb)) {
+			/*
+			 * Adding callback above failed.
+			 * dma_fence_put() checks for NULL.
+			 */
+			dma_fence_put(prev);
 			drm_sched_entity_kill_jobs_cb(NULL, &job->finish_cb);
+		}
 
 		prev = &s_fence->finished;
 	}
author maintainer
#93 lore raw

PATCH 91/116 drm/amdgpu/gfx12: correct cleanup of me field with gfx_v12_0_me_fini()

In reply to Greg Kroah-Hartman

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

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

From: Wentao Liang <[email protected]>

commit 86730b5261d4d8dae3f5b97709d40d694ecf1ddf upstream.

In gfx_v12_0_cp_gfx_load_me_microcode_rs64(), gfx_v12_0_pfp_fini() is incorrectly used to free 'me' field of 'gfx', since gfx_v12_0_pfp_fini() can only release 'pfp' field of 'gfx'. The release function of 'me' field should be gfx_v12_0_me_fini().

Fixes 52cb80c12e8a ("drm/amdgpu: Add gfx v12_0 ip block support (v6)")
(cherry picked from commit ebdc52607a46cda08972888178c6aa9cd6965141)
Cc [email protected] # 6.12.x
---
 drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c +1 -1
@@ -2395,7 +2395,7 @@ static int gfx_v12_0_cp_gfx_load_me_micr
 				      (void **)&adev->gfx.me.me_fw_data_ptr);
 	if (r) {
 		dev_err(adev->dev, "(%d) failed to create me data bo\n", r);
-		gfx_v12_0_pfp_fini(adev);
+		gfx_v12_0_me_fini(adev);
 		return r;
 	}
 
author maintainer
#94 lore raw

PATCH 92/116 drm/amd/display: Fix message for support_edp0_on_dp1

In reply to Greg Kroah-Hartman

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

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

From: Yilin Chen <[email protected]>

commit 35f0f9f421390f66cb062f4d79f4924af5f55b04 upstream.

[WHY]
The info message was wrong when support_edp0_on_dp1 is enabled

[HOW]
Use correct info message for support_edp0_on_dp1

Fixes f6d17270d18a ("drm/amd/display: add a quirk to enable eDP0 on DP1")
(cherry picked from commit 79538e6365c99d7b1c3e560d1ea8d11ef8313465)
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +1 -1
@@ -1720,7 +1720,7 @@ static void retrieve_dmi_info(struct amd
 	}
 	if (quirk_entries.support_edp0_on_dp1) {
 		init_data->flags.support_edp0_on_dp1 = true;
-		drm_info(dev, "aux_hpd_discon_quirk attached\n");
+		drm_info(dev, "support_edp0_on_dp1 attached\n");
 	}
 }
 
author maintainer
#95 lore raw

PATCH 93/116 drm/amd/display: Use HW lock mgr for PSR1 when only one eDP

In reply to Greg Kroah-Hartman

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

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

From: Mario Limonciello <[email protected]>

commit acbf16a6ae775b4db86f537448cc466288aa307e upstream.

[WHY]
DMUB locking is important to make sure that registers aren't accessed while in PSR. Previously it was enabled but caused a deadlock in situations with multiple eDP panels.

[HOW]
Detect if multiple eDP panels are in use to decide whether to use lock. Refactor the function so that the first check is for PSR-SU and then replay is in use to prevent having to look up number of eDP panels for those configurations.

Fixes f245b400a223 ("Revert "drm/amd/display: Use HW lock mgr for PSR1"")
(cherry picked from commit ed569e1279a3045d6b974226c814e071fa0193a6)
---
 drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c |   11 +++++++++++
 1 file changed, 11 insertions(+)
drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c +11 -0
@@ -69,5 +69,16 @@ bool should_use_dmub_lock(struct dc_link
 	if (link->replay_settings.replay_feature_enabled)
 		return true;
 
+	/* only use HW lock for PSR1 on single eDP */
+	if (link->psr_settings.psr_version == DC_PSR_VERSION_1) {
+		struct dc_link *edp_links[MAX_NUM_EDP];
+		int edp_num;
+
+		dc_get_edp_links(link->dc, edp_links, &edp_num);
+
+		if (edp_num == 1)
+			return true;
+	}
+
 	return false;
 }
author maintainer
#96 lore raw

PATCH 94/116 drm/amd/pm: add unique_id for gfx12

In reply to Greg Kroah-Hartman

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

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

From: Harish Kasiviswanathan <[email protected]>

commit 19b53f96856b5316ee1fd6ca485af0889e001677 upstream.

Expose unique_id for gfx12

(cherry picked from commit 16fbc18cb07470cd33fb5f37ad181b51583e6dc0)
Cc [email protected] # 6.12.x
---
 drivers/gpu/drm/amd/pm/amdgpu_pm.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/pm/amdgpu_pm.c +2 -0
@@ -2493,6 +2493,8 @@ static int default_attr_update(struct am
 		case IP_VERSION(11, 0, 1):
 		case IP_VERSION(11, 0, 2):
 		case IP_VERSION(11, 0, 3):
+		case IP_VERSION(12, 0, 0):
+		case IP_VERSION(12, 0, 1):
 			*states = ATTR_STATE_SUPPORTED;
 			break;
 		default:
author maintainer
#97 lore raw

PATCH 95/116 drm/amdgpu: Restore uncached behaviour on GFX12

In reply to Greg Kroah-Hartman

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

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

From: David Belanger <[email protected]>

commit 35b6162bb790555ad56b7f0d120e307b8334d778 upstream.

Always use MTYPE_UC if UNCACHED flag is specified.

This makes kernarg region uncached and it restores usermode cache disable debug flag functionality.

Do not set MTYPE_UC for COHERENT flag, on GFX12 coherence is handled by shader code.

(cherry picked from commit eb6cdfb807d038d9b9986b5c87188f28a4071eae)
Cc [email protected] # 6.12.x
---
 drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c |   22 ++--------------------
 drivers/gpu/drm/amd/amdkfd/kfd_svm.c   |    8 +-------
 2 files changed, 3 insertions(+), 27 deletions(-)
drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c +2 -20
@@ -498,9 +498,6 @@ static void gmc_v12_0_get_vm_pte(struct
 				 uint64_t *flags)
 {
 	struct amdgpu_bo *bo = mapping->bo_va->base.bo;
-	struct amdgpu_device *bo_adev;
-	bool coherent, is_system;
-
 
 	*flags &= ~AMDGPU_PTE_EXECUTABLE;
 	*flags |= mapping->flags & AMDGPU_PTE_EXECUTABLE;
@@ -516,26 +513,11 @@ static void gmc_v12_0_get_vm_pte(struct
 		*flags &= ~AMDGPU_PTE_VALID;
 	}
 
-	if (!bo)
-		return;
-
-	if (bo->flags & (AMDGPU_GEM_CREATE_COHERENT |
-			       AMDGPU_GEM_CREATE_UNCACHED))
-		*flags = AMDGPU_PTE_MTYPE_GFX12(*flags, MTYPE_UC);
-
-	bo_adev = amdgpu_ttm_adev(bo->tbo.bdev);
-	coherent = bo->flags & AMDGPU_GEM_CREATE_COHERENT;
-	is_system = bo->tbo.resource &&
-		(bo->tbo.resource->mem_type == TTM_PL_TT ||
-		 bo->tbo.resource->mem_type == AMDGPU_PL_PREEMPT);
-
 	if (bo && bo->flags & AMDGPU_GEM_CREATE_GFX12_DCC)
 		*flags |= AMDGPU_PTE_DCC;
 
-	/* WA for HW bug */
-	if (is_system || ((bo_adev != adev) && coherent))
-		*flags = AMDGPU_PTE_MTYPE_GFX12(*flags, MTYPE_NC);
-
+	if (bo && bo->flags & AMDGPU_GEM_CREATE_UNCACHED)
+		*flags = AMDGPU_PTE_MTYPE_GFX12(*flags, MTYPE_UC);
 }
 
 static unsigned gmc_v12_0_get_vbios_fb_size(struct amdgpu_device *adev)
drivers/gpu/drm/amd/amdkfd/kfd_svm.c +1 -7
@@ -1276,13 +1276,7 @@ svm_range_get_pte_flags(struct kfd_node
 		break;
 	case IP_VERSION(12, 0, 0):
 	case IP_VERSION(12, 0, 1):
-		if (domain == SVM_RANGE_VRAM_DOMAIN) {
-			if (bo_node != node)
-				mapping_flags |= AMDGPU_VM_MTYPE_NC;
-		} else {
-			mapping_flags |= coherent ?
-				AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC;
-		}
+		mapping_flags |= AMDGPU_VM_MTYPE_NC;
 		break;
 	default:
 		mapping_flags |= coherent ?
author maintainer
#98 lore raw

PATCH 96/116 drm/amdgpu/pm: Handle SCLK offset correctly in overdrive for smu 14.0.2

In reply to Greg Kroah-Hartman

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

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

From: Tomasz Pakuła <[email protected]>

commit d9d4cb224e4140f51847642aa5a4a5c3eb998af0 upstream.

Currently, it seems like the code was carried over from RDNA3 because it assumes two possible values to set. RDNA4, instead of having:
0: min SCLK
1: max SCLK
only has
0: SCLK offset

This change makes it so it only reports current offset value instead of showing possible min/max values and their indices. Moreover, it now only accepts the offset as a value, without the indice index.

Additionally, the lower bound was printed as %u by mistake.

Old:
OD_SCLK_OFFSET:
0: -500Mhz
1: 1000Mhz
OD_MCLK:
0: 97Mhz
1: 1259MHz
OD_VDDGFX_OFFSET:
0mV
OD_RANGE:

SCLK_OFFSET:    -500Mhz       1000Mhz
MCLK:      97Mhz       1500Mhz
VDDGFX_OFFSET:    -200mv          0mv

New:
OD_SCLK_OFFSET:
0Mhz
OD_MCLK:
0: 97Mhz
1: 1259MHz
OD_VDDGFX_OFFSET:
0mV
OD_RANGE:

SCLK_OFFSET:    -500Mhz       1000Mhz
MCLK:      97Mhz       1500Mhz
VDDGFX_OFFSET:    -200mv          0mv

Setting this offset:
Old: "s 1 <offset>"
New: "s <offset>"

(cherry picked from commit 1cfeb60e6e8837b1de5eb4e17df7cf31f4442144)
Cc [email protected] # 6.12.x
---
 drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c |   59 +++++--------------
 1 file changed, 18 insertions(+), 41 deletions(-)
drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c +18 -41
@@ -1206,16 +1206,9 @@ static int smu_v14_0_2_print_clk_levels(
 							 PP_OD_FEATURE_GFXCLK_BIT))
 			break;
 
-		PPTable_t *pptable = smu->smu_table.driver_pptable;
-		const OverDriveLimits_t * const overdrive_upperlimits =
-					&pptable->SkuTable.OverDriveLimitsBasicMax;
-		const OverDriveLimits_t * const overdrive_lowerlimits =
-					&pptable->SkuTable.OverDriveLimitsBasicMin;
-
 		size += sysfs_emit_at(buf, size, "OD_SCLK_OFFSET:\n");
-		size += sysfs_emit_at(buf, size, "0: %dMhz\n1: %uMhz\n",
-					overdrive_lowerlimits->GfxclkFoffset,
-					overdrive_upperlimits->GfxclkFoffset);
+		size += sysfs_emit_at(buf, size, "%dMhz\n",
+					od_table->OverDriveTable.GfxclkFoffset);
 		break;
 
 	case SMU_OD_MCLK:
@@ -1350,12 +1343,8 @@ static int smu_v14_0_2_print_clk_levels(
 
 		if (smu_v14_0_2_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT)) {
 			smu_v14_0_2_get_od_setting_limits(smu,
-							  PP_OD_FEATURE_GFXCLK_FMIN,
-							  &min_value,
-							  NULL);
-			smu_v14_0_2_get_od_setting_limits(smu,
 							  PP_OD_FEATURE_GFXCLK_FMAX,
-							  NULL,
+							  &min_value,
 							  &max_value);
 			size += sysfs_emit_at(buf, size, "SCLK_OFFSET: %7dMhz %10uMhz\n",
 					      min_value, max_value);
@@ -2429,36 +2418,24 @@ static int smu_v14_0_2_od_edit_dpm_table
 			return -ENOTSUPP;
 		}
 
-		for (i = 0; i < size; i += 2) {
-			if (i + 2 > size) {
-				dev_info(adev->dev, "invalid number of input parameters %d\n", size);
-				return -EINVAL;
-			}
+		if (size != 1) {
+			dev_info(adev->dev, "invalid number of input parameters %d\n", size);
+			return -EINVAL;
+		}
 
-			switch (input[i]) {
-			case 1:
-				smu_v14_0_2_get_od_setting_limits(smu,
-								  PP_OD_FEATURE_GFXCLK_FMAX,
-								  &minimum,
-								  &maximum);
-				if (input[i + 1] < minimum ||
-				    input[i + 1] > maximum) {
-					dev_info(adev->dev, "GfxclkFmax (%ld) must be within [%u, %u]!\n",
-						input[i + 1], minimum, maximum);
-					return -EINVAL;
-				}
-
-				od_table->OverDriveTable.GfxclkFoffset = input[i + 1];
-				od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_GFXCLK_BIT;
-				break;
-
-			default:
-				dev_info(adev->dev, "Invalid SCLK_VDDC_TABLE index: %ld\n", input[i]);
-				dev_info(adev->dev, "Supported indices: [0:min,1:max]\n");
-				return -EINVAL;
-			}
+		smu_v14_0_2_get_od_setting_limits(smu,
+						  PP_OD_FEATURE_GFXCLK_FMAX,
+						  &minimum,
+						  &maximum);
+		if (input[0] < minimum ||
+		    input[0] > maximum) {
+			dev_info(adev->dev, "GfxclkFoffset must be within [%d, %u]!\n",
+				 minimum, maximum);
+			return -EINVAL;
 		}
 
+		od_table->OverDriveTable.GfxclkFoffset = input[0];
+		od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_GFXCLK_BIT;
 		break;
 
 	case PP_OD_EDIT_MCLK_VDDC_TABLE:
author maintainer
#99 lore raw

PATCH 97/116 drm/amdgpu/pm: wire up hwmon fan speed for smu 14.0.2

In reply to Greg Kroah-Hartman

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

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

From: Alex Deucher <[email protected]>

commit 5ca0040ecfe8ba0dee9df1f559e8d7587f12bf89 upstream.

Add callbacks for fan speed fetching.

(cherry picked from commit 90df6db62fa78a8ab0b705ec38db99c7973b95d6)
Cc [email protected] # 6.12.x
---
 drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c |   35 +++++++++++++++++++
 1 file changed, 35 insertions(+)
drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c +35 -0
@@ -1628,6 +1628,39 @@ out:
 	adev->unique_id = ((uint64_t)upper32 << 32) | lower32;
 }
 
+static int smu_v14_0_2_get_fan_speed_pwm(struct smu_context *smu,
+					 uint32_t *speed)
+{
+	int ret;
+
+	if (!speed)
+		return -EINVAL;
+
+	ret = smu_v14_0_2_get_smu_metrics_data(smu,
+					       METRICS_CURR_FANPWM,
+					       speed);
+	if (ret) {
+		dev_err(smu->adev->dev, "Failed to get fan speed(PWM)!");
+		return ret;
+	}
+
+	/* Convert the PMFW output which is in percent to pwm(255) based */
+	*speed = min(*speed * 255 / 100, (uint32_t)255);
+
+	return 0;
+}
+
+static int smu_v14_0_2_get_fan_speed_rpm(struct smu_context *smu,
+					 uint32_t *speed)
+{
+	if (!speed)
+		return -EINVAL;
+
+	return smu_v14_0_2_get_smu_metrics_data(smu,
+						METRICS_CURR_FANSPEED,
+						speed);
+}
+
 static int smu_v14_0_2_get_power_limit(struct smu_context *smu,
 				       uint32_t *current_power_limit,
 				       uint32_t *default_power_limit,
@@ -2794,6 +2827,8 @@ static const struct pptable_funcs smu_v1
 	.set_performance_level = smu_v14_0_set_performance_level,
 	.gfx_off_control = smu_v14_0_gfx_off_control,
 	.get_unique_id = smu_v14_0_2_get_unique_id,
+	.get_fan_speed_pwm = smu_v14_0_2_get_fan_speed_pwm,
+	.get_fan_speed_rpm = smu_v14_0_2_get_fan_speed_rpm,
 	.get_power_limit = smu_v14_0_2_get_power_limit,
 	.set_power_limit = smu_v14_0_2_set_power_limit,
 	.get_power_profile_mode = smu_v14_0_2_get_power_profile_mode,
author maintainer
#100 lore raw

PATCH 98/116 drm/amdgpu: Remove JPEG from vega and carrizo video caps

In reply to Greg Kroah-Hartman

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

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

From: David Rosca <[email protected]>

commit 7fc0765208502e53297ce72c49ca43729f9d6ff3 upstream.

JPEG is only supported for VCN1+.

(cherry picked from commit 0a6e7b06bdbead2e43d56a2274b7e0c9c86d536e)
---
 drivers/gpu/drm/amd/amdgpu/soc15.c |    1 -
 drivers/gpu/drm/amd/amdgpu/vi.c    |    7 -------
 2 files changed, 8 deletions(-)
drivers/gpu/drm/amd/amdgpu/soc15.c +0 -1
@@ -108,7 +108,6 @@ static const struct amdgpu_video_codec_i
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
 };
 
 static const struct amdgpu_video_codecs vega_video_codecs_decode =
drivers/gpu/drm/amd/amdgpu/vi.c +0 -7
@@ -239,13 +239,6 @@ static const struct amdgpu_video_codec_i
 		.max_pixels_per_frame = 4096 * 4096,
 		.max_level = 186,
 	},
-	{
-		.codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG,
-		.max_width = 4096,
-		.max_height = 4096,
-		.max_pixels_per_frame = 4096 * 4096,
-		.max_level = 0,
-	},
 };
 
 static const struct amdgpu_video_codecs cz_video_codecs_decode =
author maintainer
#101 lore raw

PATCH 99/116 drm/amdgpu: Fix MPEG2, MPEG4 and VC1 video caps max size

In reply to Greg Kroah-Hartman

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

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

From: David Rosca <[email protected]>

commit f0105e173103c9d30a2bb959f7399437d536c848 upstream.

1920x1088 is the maximum supported resolution.

(cherry picked from commit 1a0807feb97082bff2b1342dbbe55a2a9a8bdb88)
---
 drivers/gpu/drm/amd/amdgpu/nv.c    |   18 +++++++++---------
 drivers/gpu/drm/amd/amdgpu/soc15.c |   18 +++++++++---------
 drivers/gpu/drm/amd/amdgpu/vi.c    |   36 ++++++++++++++++++------------------
 3 files changed, 36 insertions(+), 36 deletions(-)
drivers/gpu/drm/amd/amdgpu/nv.c +9 -9
@@ -78,10 +78,10 @@ static const struct amdgpu_video_codecs
 
 /* Navi1x */
 static const struct amdgpu_video_codec_info nv_video_codecs_decode_array[] = {
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 1920, 1088, 3)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 1920, 1088, 5)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 1920, 1088, 4)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
@@ -104,10 +104,10 @@ static const struct amdgpu_video_codecs
 };
 
 static const struct amdgpu_video_codec_info sc_video_codecs_decode_array_vcn0[] = {
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 1920, 1088, 3)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 1920, 1088, 5)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 1920, 1088, 4)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 16384, 16384, 0)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
@@ -115,10 +115,10 @@ static const struct amdgpu_video_codec_i
 };
 
 static const struct amdgpu_video_codec_info sc_video_codecs_decode_array_vcn1[] = {
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 1920, 1088, 3)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 1920, 1088, 5)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 1920, 1088, 4)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 16384, 16384, 0)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
drivers/gpu/drm/amd/amdgpu/soc15.c +9 -9
@@ -103,10 +103,10 @@ static const struct amdgpu_video_codecs
 /* Vega */
 static const struct amdgpu_video_codec_info vega_video_codecs_decode_array[] =
 {
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 1920, 1088, 3)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 1920, 1088, 5)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 1920, 1088, 4)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)},
 };
 
@@ -119,10 +119,10 @@ static const struct amdgpu_video_codecs
 /* Raven */
 static const struct amdgpu_video_codec_info rv_video_codecs_decode_array[] =
 {
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 1920, 1088, 3)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 1920, 1088, 5)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 1920, 1088, 4)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 4096, 4096, 0)},
@@ -137,10 +137,10 @@ static const struct amdgpu_video_codecs
 /* Renoir, Arcturus */
 static const struct amdgpu_video_codec_info rn_video_codecs_decode_array[] =
 {
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 1920, 1088, 3)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 1920, 1088, 5)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 1920, 1088, 4)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 16384, 16384, 0)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
drivers/gpu/drm/amd/amdgpu/vi.c +18 -18
@@ -167,16 +167,16 @@ static const struct amdgpu_video_codec_i
 {
 	{
 		.codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2,
-		.max_width = 4096,
-		.max_height = 4096,
-		.max_pixels_per_frame = 4096 * 4096,
+		.max_width = 1920,
+		.max_height = 1088,
+		.max_pixels_per_frame = 1920 * 1088,
 		.max_level = 3,
 	},
 	{
 		.codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4,
-		.max_width = 4096,
-		.max_height = 4096,
-		.max_pixels_per_frame = 4096 * 4096,
+		.max_width = 1920,
+		.max_height = 1088,
+		.max_pixels_per_frame = 1920 * 1088,
 		.max_level = 5,
 	},
 	{
@@ -188,9 +188,9 @@ static const struct amdgpu_video_codec_i
 	},
 	{
 		.codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1,
-		.max_width = 4096,
-		.max_height = 4096,
-		.max_pixels_per_frame = 4096 * 4096,
+		.max_width = 1920,
+		.max_height = 1088,
+		.max_pixels_per_frame = 1920 * 1088,
 		.max_level = 4,
 	},
 };
@@ -206,16 +206,16 @@ static const struct amdgpu_video_codec_i
 {
 	{
 		.codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2,
-		.max_width = 4096,
-		.max_height = 4096,
-		.max_pixels_per_frame = 4096 * 4096,
+		.max_width = 1920,
+		.max_height = 1088,
+		.max_pixels_per_frame = 1920 * 1088,
 		.max_level = 3,
 	},
 	{
 		.codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4,
-		.max_width = 4096,
-		.max_height = 4096,
-		.max_pixels_per_frame = 4096 * 4096,
+		.max_width = 1920,
+		.max_height = 1088,
+		.max_pixels_per_frame = 1920 * 1088,
 		.max_level = 5,
 	},
 	{
@@ -227,9 +227,9 @@ static const struct amdgpu_video_codec_i
 	},
 	{
 		.codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1,
-		.max_width = 4096,
-		.max_height = 4096,
-		.max_pixels_per_frame = 4096 * 4096,
+		.max_width = 1920,
+		.max_height = 1088,
+		.max_pixels_per_frame = 1920 * 1088,
 		.max_level = 4,
 	},
 	{
author maintainer
#102 lore raw

PATCH 100/116 drm/amdgpu: Fix JPEG video caps max size for navi1x and raven

In reply to Greg Kroah-Hartman

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

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

From: David Rosca <[email protected]>

commit ec33964d9d88488fa954a03d476a8b811efc6e85 upstream.

8192x8192 is the maximum supported resolution.

(cherry picked from commit 6e0d2fde3ae8fdb5b47e10389f23ed2cb4daec5d)
---
 drivers/gpu/drm/amd/amdgpu/nv.c    |    2 +-
 drivers/gpu/drm/amd/amdgpu/soc15.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/nv.c +1 -1
@@ -83,7 +83,7 @@ static const struct amdgpu_video_codec_i
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 1920, 1088, 4)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 8192, 8192, 0)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
 };
 
drivers/gpu/drm/amd/amdgpu/soc15.c +1 -1
@@ -124,7 +124,7 @@ static const struct amdgpu_video_codec_i
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 1920, 1088, 4)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 8192, 8192, 0)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 4096, 4096, 0)},
 };
 
author maintainer
#103 lore raw

PATCH 101/116 drm/amdkfd: Fix user queue validation on Gfx7/8

In reply to Greg Kroah-Hartman

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

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

From: Philip Yang <[email protected]>

commit 542c3bb836733a1325874310d54d25b4907ed10e upstream.

To workaround queue full h/w issue on Gfx7/8, when application create AQL queue, the ring buffer bo allocate size is queue_size/2 and map queue_size ring buffer to GPU in 2 pieces using 2 attachments, each attachment map size is queue_size/2, with same ring_bo backing memory.

For Gfx7/8, user queue buffer validation should use queue_size/2 to verify ring_bo allocation and mapping size.

Fixes 68e599db7a54 ("drm/amdkfd: Validate user queue buffers")
(cherry picked from commit e7a477735f1771b9a9346a5fbd09d7ff0641723a)
---
 drivers/gpu/drm/amd/amdkfd/kfd_queue.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdkfd/kfd_queue.c +11 -1
index 24396a2c77bd..4afff7094caf 100644
@@ -233,6 +233,7 @@ void kfd_queue_buffer_put(struct amdgpu_bo **bo)
 int kfd_queue_acquire_buffers(struct kfd_process_device *pdd, struct queue_properties *properties)
 {
 	struct kfd_topology_device *topo_dev;
+	u64 expected_queue_size;
 	struct amdgpu_vm *vm;
 	u32 total_cwsr_size;
 	int err;
@@ -241,6 +242,15 @@ int kfd_queue_acquire_buffers(struct kfd_process_device *pdd, struct queue_prope
 	if (!topo_dev)
 		return -EINVAL;
 
+	/* AQL queues on GFX7 and GFX8 appear twice their actual size */
+	if (properties->type == KFD_QUEUE_TYPE_COMPUTE &&
+	    properties->format == KFD_QUEUE_FORMAT_AQL &&
+	    topo_dev->node_props.gfx_target_version >= 70000 &&
+	    topo_dev->node_props.gfx_target_version < 90000)
+		expected_queue_size = properties->queue_size / 2;
+	else
+		expected_queue_size = properties->queue_size;
+
 	vm = drm_priv_to_vm(pdd->drm_priv);
 	err = amdgpu_bo_reserve(vm->root.bo, false);
 	if (err)
@@ -255,7 +265,7 @@ int kfd_queue_acquire_buffers(struct kfd_process_device *pdd, struct queue_prope
 		goto out_err_unreserve;
 
 	err = kfd_queue_buffer_get(vm, (void *)properties->queue_address,
-				   &properties->ring_bo, properties->queue_size);
+				   &properties->ring_bo, expected_queue_size);
 	if (err)
 		goto out_err_unreserve;
 
Signature · 1 line
2.49.0
author maintainer
#104 lore raw

PATCH 102/116 ksmbd: fix incorrect validation for num_aces field of smb_acl

In reply to Greg Kroah-Hartman

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

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

From: Namjae Jeon <[email protected]>

commit 1b8b67f3c5e5169535e26efedd3e422172e2db64 upstream.

parse_dcal() validate num_aces to allocate posix_ace_state_array.

if (num_aces > ULONG_MAX / sizeof(struct smb_ace *))

It is an incorrect validation that we can create an array of size ULONG_MAX. smb_acl has ->size field to calculate actual number of aces in request buffer size. Use this to check invalid num_aces.

---
 fs/smb/server/smbacl.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
fs/smb/server/smbacl.c +4 -1
@@ -398,7 +398,9 @@ static void parse_dacl(struct mnt_idmap
 	if (num_aces <= 0)
 		return;
 
-	if (num_aces > ULONG_MAX / sizeof(struct smb_ace *))
+	if (num_aces > (le16_to_cpu(pdacl->size) - sizeof(struct smb_acl)) /
+			(offsetof(struct smb_ace, sid) +
+			 offsetof(struct smb_sid, sub_auth) + sizeof(__le16)))
 		return;
 
 	ret = init_acl_state(&acl_state, num_aces);
@@ -432,6 +434,7 @@ static void parse_dacl(struct mnt_idmap
 			offsetof(struct smb_sid, sub_auth);
 
 		if (end_of_acl - acl_base < acl_size ||
+		    ppace[i]->sid.num_subauth == 0 ||
 		    ppace[i]->sid.num_subauth > SID_MAX_SUB_AUTHORITIES ||
 		    (end_of_acl - acl_base <
 		     acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth) ||
author maintainer
#105 lore raw

PATCH 103/116 io_uring/net: fix sendzc double notif flush

In reply to Greg Kroah-Hartman

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

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

From: Pavel Begunkov <[email protected]>

commit 67c007d6c12da3e456c005083696c20d4498ae72 upstream.

refcount_t: underflow; use-after-free.

WARNING: CPU: 0 PID: 5823 at lib/refcount.c:28 refcount_warn_saturate+0x15a/0x1d0 lib/refcount.c:28
RIP: 0010:refcount_warn_saturate+0x15a/0x1d0 lib/refcount.c:28
Call Trace:
 <TASK>
 io_notif_flush io_uring/notif.h:40 [inline]
 io_send_zc_cleanup+0x121/0x170 io_uring/net.c:1222
 io_clean_op+0x58c/0x9a0 io_uring/io_uring.c:406
 io_free_batch_list io_uring/io_uring.c:1429 [inline]
 __io_submit_flush_completions+0xc16/0xd20 io_uring/io_uring.c:1470
 io_submit_flush_completions io_uring/io_uring.h:159 [inline]

Before the blamed commit, sendzc relied on io_req_msg_cleanup() to clear REQ_F_NEED_CLEANUP, so after the following snippet the request will never hit the core io_uring cleanup path.

io_notif_flush();
io_req_msg_cleanup();

The easiest fix is to null the notification. io_send_zc_cleanup() can still be called after, but it's tolerated.

---
 io_uring/net.c |    2 ++
 1 file changed, 2 insertions(+)
io_uring/net.c +2 -0
@@ -1427,6 +1427,7 @@ int io_send_zc(struct io_kiocb *req, uns
 	 */
 	if (!(issue_flags & IO_URING_F_UNLOCKED)) {
 		io_notif_flush(zc->notif);
+		zc->notif = NULL;
 		io_req_msg_cleanup(req, 0);
 	}
 	io_req_set_res(req, ret, IORING_CQE_F_MORE);
@@ -1487,6 +1488,7 @@ int io_sendmsg_zc(struct io_kiocb *req,
 	 */
 	if (!(issue_flags & IO_URING_F_UNLOCKED)) {
 		io_notif_flush(sr->notif);
+		sr->notif = NULL;
 		io_req_msg_cleanup(req, 0);
 	}
 	io_req_set_res(req, ret, IORING_CQE_F_MORE);
author maintainer
#106 lore raw

PATCH 104/116 KVM: arm64: Calculate cptr_el2 traps on activating traps

In reply to Greg Kroah-Hartman

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

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

From: Fuad Tabba <[email protected]>

[ Upstream commit 2fd5b4b0e7b440602455b79977bfa64dea101e6c ]

Similar to VHE, calculate the value of cptr_el2 from scratch on activate traps. This removes the need to store cptr_el2 in every vcpu structure. Moreover, some traps, such as whether the guest owns the fp registers, need to be set on every vcpu run.

Fixes 5294afdbf45a ("KVM: arm64: Exclude FP ownership from kvm_vcpu_arch")
---
 arch/arm64/include/asm/kvm_host.h |    1 
 arch/arm64/kvm/arm.c              |    1 
 arch/arm64/kvm/hyp/nvhe/pkvm.c    |   29 ---------------------
 arch/arm64/kvm/hyp/nvhe/switch.c  |   51 +++++++++++++++++++++++---------------
 4 files changed, 32 insertions(+), 50 deletions(-)
arch/arm64/include/asm/kvm_host.h +0 -1
@@ -697,7 +697,6 @@ struct kvm_vcpu_arch {
 	u64 hcr_el2;
 	u64 hcrx_el2;
 	u64 mdcr_el2;
-	u64 cptr_el2;
 
 	/* Exception Information */
 	struct kvm_vcpu_fault_info fault;
arch/arm64/kvm/arm.c +0 -1
@@ -1577,7 +1577,6 @@ static int kvm_arch_vcpu_ioctl_vcpu_init
 	}
 
 	vcpu_reset_hcr(vcpu);
-	vcpu->arch.cptr_el2 = kvm_get_reset_cptr_el2(vcpu);
 
 	/*
 	 * Handle the "start in power-off" case.
arch/arm64/kvm/hyp/nvhe/pkvm.c +0 -29
@@ -28,8 +28,6 @@ static void pvm_init_traps_aa64pfr0(stru
 	const u64 feature_ids = pvm_read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
 	u64 hcr_set = HCR_RW;
 	u64 hcr_clear = 0;
-	u64 cptr_set = 0;
-	u64 cptr_clear = 0;
 
 	/* Protected KVM does not support AArch32 guests. */
 	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0),
@@ -59,21 +57,10 @@ static void pvm_init_traps_aa64pfr0(stru
 	/* Trap AMU */
 	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AMU), feature_ids)) {
 		hcr_clear |= HCR_AMVOFFEN;
-		cptr_set |= CPTR_EL2_TAM;
-	}
-
-	/* Trap SVE */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_SVE), feature_ids)) {
-		if (has_hvhe())
-			cptr_clear |= CPACR_ELx_ZEN;
-		else
-			cptr_set |= CPTR_EL2_TZ;
 	}
 
 	vcpu->arch.hcr_el2 |= hcr_set;
 	vcpu->arch.hcr_el2 &= ~hcr_clear;
-	vcpu->arch.cptr_el2 |= cptr_set;
-	vcpu->arch.cptr_el2 &= ~cptr_clear;
 }
 
 /*
@@ -103,7 +90,6 @@ static void pvm_init_traps_aa64dfr0(stru
 	const u64 feature_ids = pvm_read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
 	u64 mdcr_set = 0;
 	u64 mdcr_clear = 0;
-	u64 cptr_set = 0;
 
 	/* Trap/constrain PMU */
 	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), feature_ids)) {
@@ -130,21 +116,12 @@ static void pvm_init_traps_aa64dfr0(stru
 	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceFilt), feature_ids))
 		mdcr_set |= MDCR_EL2_TTRF;
 
-	/* Trap Trace */
-	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_TraceVer), feature_ids)) {
-		if (has_hvhe())
-			cptr_set |= CPACR_EL1_TTA;
-		else
-			cptr_set |= CPTR_EL2_TTA;
-	}
-
 	/* Trap External Trace */
 	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_ExtTrcBuff), feature_ids))
 		mdcr_clear |= MDCR_EL2_E2TB_MASK << MDCR_EL2_E2TB_SHIFT;
 
 	vcpu->arch.mdcr_el2 |= mdcr_set;
 	vcpu->arch.mdcr_el2 &= ~mdcr_clear;
-	vcpu->arch.cptr_el2 |= cptr_set;
 }
 
 /*
@@ -195,10 +172,6 @@ static void pvm_init_trap_regs(struct kv
 	/* Clear res0 and set res1 bits to trap potential new features. */
 	vcpu->arch.hcr_el2 &= ~(HCR_RES0);
 	vcpu->arch.mdcr_el2 &= ~(MDCR_EL2_RES0);
-	if (!has_hvhe()) {
-		vcpu->arch.cptr_el2 |= CPTR_NVHE_EL2_RES1;
-		vcpu->arch.cptr_el2 &= ~(CPTR_NVHE_EL2_RES0);
-	}
 }
 
 /*
@@ -579,8 +552,6 @@ unlock:
 		return ret;
 	}
 
-	hyp_vcpu->vcpu.arch.cptr_el2 = kvm_get_reset_cptr_el2(&hyp_vcpu->vcpu);
-
 	return 0;
 }
 
arch/arm64/kvm/hyp/nvhe/switch.c +32 -19

65 lines not on this page · raw message

author maintainer
#107 lore raw

PATCH 105/116 KVM: arm64: Unconditionally save+flush host FPSIMD/SVE/SME state

In reply to Greg Kroah-Hartman

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

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

From: Mark Rutland <[email protected]>

[ Upstream commit fbc7e61195e23f744814e78524b73b59faa54ab4 ]

There are several problems with the way hyp code lazily saves the host's FPSIMD/SVE state, including:

* Host SVE being discarded unexpectedly due to inconsistent configuration of TIF_SVE and CPACR_ELx.ZEN. This has been seen to result in QEMU crashes where SVE is used by memmove(), as reported by Eric Auger:

https://issues.redhat.com/browse/RHEL-68997

* Host SVE state is discarded *after* modification by ptrace, which was an unintentional ptrace ABI change introduced with lazy discarding of SVE state.

* The host FPMR value can be discarded when running a non-protected VM, where FPMR support is not exposed to a VM, and that VM uses FPSIMD/SVE. In these cases the hyp code does not save the host's FPMR before unbinding the host's FPSIMD/SVE/SME state, leaving a stale value in memory.

Avoid these by eagerly saving and "flushing" the host's FPSIMD/SVE/SME state when loading a vCPU such that KVM does not need to save any of the host's FPSIMD/SVE/SME state. For clarity, fpsimd_kvm_prepare() is removed and the necessary call to fpsimd_save_and_flush_cpu_state() is placed in kvm_arch_vcpu_load_fp(). As 'fpsimd_state' and 'fpmr_ptr' should not be used, they are set to NULL; all uses of these will be removed in subsequent patches.

Historical problems go back at least as far as v5.17, e.g. erroneous assumptions about TIF_SVE being clear in commit:

8383741ab2e773a9 ("KVM: arm64: Get rid of host SVE tracking/saving")

... and so this eager save+flush probably needs to be backported to ALL stable trees.

Fixes 93ae6b01bafee8fa ("KVM: arm64: Discard any SVE state when entering KVM guests")
Fixes 8c845e2731041f0f ("arm64/sve: Leave SVE enabled on syscall if we don't context switch")
Fixes ef3be86021c3bdf3 ("KVM: arm64: Add save/restore support for FPMR")
Cc Catalin Marinas <[email protected]>
Cc Florian Weimer <[email protected]>
Cc Fuad Tabba <[email protected]>
Cc Jeremy Linton <[email protected]>
Cc Marc Zyngier <[email protected]>
Cc Oliver Upton <[email protected]>
Cc Paolo Bonzini <[email protected]>
[ Mark: Handle vcpu/host flag conflict ]
---
 arch/arm64/kernel/fpsimd.c |   25 -------------------------
 arch/arm64/kvm/fpsimd.c    |   35 ++++++++++-------------------------
 2 files changed, 10 insertions(+), 50 deletions(-)
arch/arm64/kernel/fpsimd.c +0 -25
@@ -1695,31 +1695,6 @@ void fpsimd_signal_preserve_current_stat
 }
 
 /*
- * Called by KVM when entering the guest.
- */
-void fpsimd_kvm_prepare(void)
-{
-	if (!system_supports_sve())
-		return;
-
-	/*
-	 * KVM does not save host SVE state since we can only enter
-	 * the guest from a syscall so the ABI means that only the
-	 * non-saved SVE state needs to be saved.  If we have left
-	 * SVE enabled for performance reasons then update the task
-	 * state to be FPSIMD only.
-	 */
-	get_cpu_fpsimd_context();
-
-	if (test_and_clear_thread_flag(TIF_SVE)) {
-		sve_to_fpsimd(current);
-		current->thread.fp_type = FP_STATE_FPSIMD;
-	}
-
-	put_cpu_fpsimd_context();
-}
-
-/*
  * Associate current's FPSIMD context with this cpu
  * The caller must have ownership of the cpu FPSIMD context before calling
  * this function.
arch/arm64/kvm/fpsimd.c +10 -25
@@ -54,16 +54,18 @@ void kvm_arch_vcpu_load_fp(struct kvm_vc
 	if (!system_supports_fpsimd())
 		return;
 
-	fpsimd_kvm_prepare();
-
 	/*
-	 * We will check TIF_FOREIGN_FPSTATE just before entering the
-	 * guest in kvm_arch_vcpu_ctxflush_fp() and override this to
-	 * FP_STATE_FREE if the flag set.
+	 * Ensure that any host FPSIMD/SVE/SME state is saved and unbound such
+	 * that the host kernel is responsible for restoring this state upon
+	 * return to userspace, and the hyp code doesn't need to save anything.
+	 *
+	 * When the host may use SME, fpsimd_save_and_flush_cpu_state() ensures
+	 * that PSTATE.{SM,ZA} == {0,0}.
 	 */
-	*host_data_ptr(fp_owner) = FP_STATE_HOST_OWNED;
-	*host_data_ptr(fpsimd_state) = kern_hyp_va(&current->thread.uw.fpsimd_state);
-	*host_data_ptr(fpmr_ptr) = kern_hyp_va(&current->thread.uw.fpmr);
+	fpsimd_save_and_flush_cpu_state();
+	*host_data_ptr(fp_owner) = FP_STATE_FREE;
+	*host_data_ptr(fpsimd_state) = NULL;
+	*host_data_ptr(fpmr_ptr) = NULL;
 
 	vcpu_clear_flag(vcpu, HOST_SVE_ENABLED);
 	if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN)
@@ -73,23 +75,6 @@ void kvm_arch_vcpu_load_fp(struct kvm_vc
 		vcpu_clear_flag(vcpu, HOST_SME_ENABLED);
 		if (read_sysreg(cpacr_el1) & CPACR_EL1_SMEN_EL0EN)
 			vcpu_set_flag(vcpu, HOST_SME_ENABLED);
-
-		/*
-		 * If PSTATE.SM is enabled then save any pending FP
-		 * state and disable PSTATE.SM. If we leave PSTATE.SM
-		 * enabled and the guest does not enable SME via
-		 * CPACR_EL1.SMEN then operations that should be valid
-		 * may generate SME traps from EL1 to EL1 which we
-		 * can't intercept and which would confuse the guest.
-		 *
-		 * Do the same for PSTATE.ZA in the case where there
-		 * is state in the registers which has not already
-		 * been saved, this is very unlikely to happen.
-		 */
-		if (read_sysreg_s(SYS_SVCR) & (SVCR_SM_MASK | SVCR_ZA_MASK)) {
-			*host_data_ptr(fp_owner) = FP_STATE_FREE;
-			fpsimd_save_and_flush_cpu_state();
-		}
 	}
 
 	/*
author maintainer
#108 lore raw

PATCH 106/116 KVM: arm64: Remove host FPSIMD saving for non-protected KVM

In reply to Greg Kroah-Hartman

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

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

From: Mark Rutland <[email protected]>

[ Upstream commit 8eca7f6d5100b6997df4f532090bc3f7e0203bef ]

Now that the host eagerly saves its own FPSIMD/SVE/SME state, non-protected KVM never needs to save the host FPSIMD/SVE/SME state, and the code to do this is never used. Protected KVM still needs to save/restore the host FPSIMD/SVE state to avoid leaking guest state to the host (and to avoid revealing to the host whether the guest used FPSIMD/SVE/SME), and that code needs to be retained.

Remove the unused code and data structures.

To avoid the need for a stub copy of kvm_hyp_save_fpsimd_host() in the VHE hyp code, the nVHE/hVHE version is moved into the shared switch header, where it is only invoked when KVM is in protected mode.

---
 arch/arm64/include/asm/kvm_host.h       |   18 ++++--------------
 arch/arm64/kvm/arm.c                    |    8 --------
 arch/arm64/kvm/fpsimd.c                 |    2 --
 arch/arm64/kvm/hyp/include/hyp/switch.h |   25 +++++++++++++++++++++++--
 arch/arm64/kvm/hyp/nvhe/hyp-main.c      |    2 +-
 arch/arm64/kvm/hyp/nvhe/switch.c        |   28 ----------------------------
 arch/arm64/kvm/hyp/vhe/switch.c         |    8 --------
 7 files changed, 28 insertions(+), 63 deletions(-)
arch/arm64/include/asm/kvm_host.h +4 -14
@@ -602,23 +602,13 @@ struct kvm_host_data {
 	struct kvm_cpu_context host_ctxt;
 
 	/*
-	 * All pointers in this union are hyp VA.
+	 * Hyp VA.
 	 * sve_state is only used in pKVM and if system_supports_sve().
 	 */
-	union {
-		struct user_fpsimd_state *fpsimd_state;
-		struct cpu_sve_state *sve_state;
-	};
+	struct cpu_sve_state *sve_state;
 
-	union {
-		/* HYP VA pointer to the host storage for FPMR */
-		u64	*fpmr_ptr;
-		/*
-		 * Used by pKVM only, as it needs to provide storage
-		 * for the host
-		 */
-		u64	fpmr;
-	};
+	/* Used by pKVM only. */
+	u64	fpmr;
 
 	/* Ownership of the FP regs */
 	enum {
arch/arm64/kvm/arm.c +0 -8
@@ -2476,14 +2476,6 @@ static void finalize_init_hyp_mode(void)
 			per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->sve_state =
 				kern_hyp_va(sve_state);
 		}
-	} else {
-		for_each_possible_cpu(cpu) {
-			struct user_fpsimd_state *fpsimd_state;
-
-			fpsimd_state = &per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->host_ctxt.fp_regs;
-			per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->fpsimd_state =
-				kern_hyp_va(fpsimd_state);
-		}
 	}
 }
 
arch/arm64/kvm/fpsimd.c +0 -2
@@ -64,8 +64,6 @@ void kvm_arch_vcpu_load_fp(struct kvm_vc
 	 */
 	fpsimd_save_and_flush_cpu_state();
 	*host_data_ptr(fp_owner) = FP_STATE_FREE;
-	*host_data_ptr(fpsimd_state) = NULL;
-	*host_data_ptr(fpmr_ptr) = NULL;
 
 	vcpu_clear_flag(vcpu, HOST_SVE_ENABLED);
 	if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN)
arch/arm64/kvm/hyp/include/hyp/switch.h +23 -2
@@ -344,7 +344,28 @@ static inline void __hyp_sve_save_host(v
 			 true);
 }
 
-static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu);
+static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu)
+{
+	/*
+	 * Non-protected kvm relies on the host restoring its sve state.
+	 * Protected kvm restores the host's sve state as not to reveal that
+	 * fpsimd was used by a guest nor leak upper sve bits.
+	 */
+	if (system_supports_sve()) {
+		__hyp_sve_save_host();
+
+		/* Re-enable SVE traps if not supported for the guest vcpu. */
+		if (!vcpu_has_sve(vcpu))
+			cpacr_clear_set(CPACR_ELx_ZEN, 0);
+
+	} else {
+		__fpsimd_save_state(host_data_ptr(host_ctxt.fp_regs));
+	}
+
+	if (kvm_has_fpmr(kern_hyp_va(vcpu->kvm)))
+		*host_data_ptr(fpmr) = read_sysreg_s(SYS_FPMR);
+}
+
 
 /*
  * We trap the first access to the FP/SIMD to save the host context and
@@ -394,7 +415,7 @@ static bool kvm_hyp_handle_fpsimd(struct
 	isb();
 
 	/* Write out the host state if it's in the registers */
-	if (host_owns_fp_regs())
+	if (is_protected_kvm_enabled() && host_owns_fp_regs())
 		kvm_hyp_save_fpsimd_host(vcpu);
 
 	/* Restore the guest state */
arch/arm64/kvm/hyp/nvhe/hyp-main.c +1 -1
@@ -83,7 +83,7 @@ static void fpsimd_sve_sync(struct kvm_v
 	if (system_supports_sve())
 		__hyp_sve_restore_host();
 	else
-		__fpsimd_restore_state(*host_data_ptr(fpsimd_state));
+		__fpsimd_restore_state(host_data_ptr(host_ctxt.fp_regs));
 
 	if (has_fpmr)
 		write_sysreg_s(*host_data_ptr(fpmr), SYS_FPMR);
arch/arm64/kvm/hyp/nvhe/switch.c +0 -28
@@ -193,34 +193,6 @@ static bool kvm_handle_pvm_sys64(struct
 		kvm_handle_pvm_sysreg(vcpu, exit_code));
 }
 
-static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu)
-{
-	/*
-	 * Non-protected kvm relies on the host restoring its sve state.
-	 * Protected kvm restores the host's sve state as not to reveal that
-	 * fpsimd was used by a guest nor leak upper sve bits.
-	 */
-	if (unlikely(is_protected_kvm_enabled() && system_supports_sve())) {
-		__hyp_sve_save_host();
-
-		/* Re-enable SVE traps if not supported for the guest vcpu. */
-		if (!vcpu_has_sve(vcpu))
-			cpacr_clear_set(CPACR_ELx_ZEN, 0);
-
-	} else {
-		__fpsimd_save_state(*host_data_ptr(fpsimd_state));
-	}
-
-	if (kvm_has_fpmr(kern_hyp_va(vcpu->kvm))) {
-		u64 val = read_sysreg_s(SYS_FPMR);
-
-		if (unlikely(is_protected_kvm_enabled()))
-			*host_data_ptr(fpmr) = val;
-		else
-			**host_data_ptr(fpmr_ptr) = val;
-	}
-}
-
 static const exit_handler_fn hyp_exit_handlers[] = {
 	[0 ... ESR_ELx_EC_MAX]		= NULL,
 	[ESR_ELx_EC_CP15_32]		= kvm_hyp_handle_cp15_32,
arch/arm64/kvm/hyp/vhe/switch.c +0 -8
@@ -309,14 +309,6 @@ static bool kvm_hyp_handle_eret(struct k
 	return true;
 }
 
-static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu)
-{
-	__fpsimd_save_state(*host_data_ptr(fpsimd_state));
-
-	if (kvm_has_fpmr(vcpu->kvm))
-		**host_data_ptr(fpmr_ptr) = read_sysreg_s(SYS_FPMR);
-}
-
 static bool kvm_hyp_handle_tlbi_el2(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
 	int ret = -EINVAL;
author maintainer
#109 lore raw

PATCH 107/116 KVM: arm64: Remove VHE host restore of CPACR_EL1.ZEN

In reply to Greg Kroah-Hartman

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

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

From: Mark Rutland <[email protected]>

[ Upstream commit 459f059be702056d91537b99a129994aa6ccdd35 ]

When KVM is in VHE mode, the host kernel tries to save and restore the configuration of CPACR_EL1.ZEN (i.e. CPTR_EL2.ZEN when HCR_EL2.E2H=1) across kvm_arch_vcpu_load_fp() and kvm_arch_vcpu_put_fp(), since the configuration may be clobbered by hyp when running a vCPU. This logic is currently redundant.

The VHE hyp code unconditionally configures CPTR_EL2.ZEN to 0b01 when returning to the host, permitting host kernel usage of SVE.

Now that the host eagerly saves and unbinds its own FPSIMD/SVE/SME state, there's no need to save/restore the state of the EL0 SVE trap. The kernel can safely save/restore state without trapping, as described above, and will restore userspace state (including trap controls) before returning to userspace.

Remove the redundant logic.

---
 arch/arm64/include/asm/kvm_host.h |    2 --
 arch/arm64/kvm/fpsimd.c           |   16 ----------------
 2 files changed, 18 deletions(-)
arch/arm64/include/asm/kvm_host.h +0 -2
@@ -891,8 +891,6 @@ struct kvm_vcpu_arch {
 /* Save TRBE context if active  */
 #define DEBUG_STATE_SAVE_TRBE	__vcpu_single_flag(iflags, BIT(6))
 
-/* SVE enabled for host EL0 */
-#define HOST_SVE_ENABLED	__vcpu_single_flag(sflags, BIT(0))
 /* SME enabled for EL0 */
 #define HOST_SME_ENABLED	__vcpu_single_flag(sflags, BIT(1))
 /* Physical CPU not in supported_cpus */
arch/arm64/kvm/fpsimd.c +0 -16
@@ -65,10 +65,6 @@ void kvm_arch_vcpu_load_fp(struct kvm_vc
 	fpsimd_save_and_flush_cpu_state();
 	*host_data_ptr(fp_owner) = FP_STATE_FREE;
 
-	vcpu_clear_flag(vcpu, HOST_SVE_ENABLED);
-	if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN)
-		vcpu_set_flag(vcpu, HOST_SVE_ENABLED);
-
 	if (system_supports_sme()) {
 		vcpu_clear_flag(vcpu, HOST_SME_ENABLED);
 		if (read_sysreg(cpacr_el1) & CPACR_EL1_SMEN_EL0EN)
@@ -202,18 +198,6 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcp
 		 * when needed.
 		 */
 		fpsimd_save_and_flush_cpu_state();
-	} else if (has_vhe() && system_supports_sve()) {
-		/*
-		 * The FPSIMD/SVE state in the CPU has not been touched, and we
-		 * have SVE (and VHE): CPACR_EL1 (alias CPTR_EL2) has been
-		 * reset by kvm_reset_cptr_el2() in the Hyp code, disabling SVE
-		 * for EL0.  To avoid spurious traps, restore the trap state
-		 * seen by kvm_arch_vcpu_load_fp():
-		 */
-		if (vcpu_get_flag(vcpu, HOST_SVE_ENABLED))
-			sysreg_clear_set(CPACR_EL1, 0, CPACR_EL1_ZEN_EL0EN);
-		else
-			sysreg_clear_set(CPACR_EL1, CPACR_EL1_ZEN_EL0EN, 0);
 	}
 
 	local_irq_restore(flags);
author maintainer
#110 lore raw

PATCH 108/116 KVM: arm64: Remove VHE host restore of CPACR_EL1.SMEN

In reply to Greg Kroah-Hartman

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

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

From: Mark Rutland <[email protected]>

[ Upstream commit 407a99c4654e8ea65393f412c421a55cac539f5b ]

When KVM is in VHE mode, the host kernel tries to save and restore the configuration of CPACR_EL1.SMEN (i.e. CPTR_EL2.SMEN when HCR_EL2.E2H=1) across kvm_arch_vcpu_load_fp() and kvm_arch_vcpu_put_fp(), since the configuration may be clobbered by hyp when running a vCPU. This logic has historically been broken, and is currently redundant.

This logic was originally introduced in commit:

861262ab86270206 ("KVM: arm64: Handle SME host state when running guests")

At the time, the VHE hyp code would reset CPTR_EL2.SMEN to 0b00 when returning to the host, trapping host access to SME state. Unfortunately, this was unsafe as the host could take a softirq before calling kvm_arch_vcpu_put_fp(), and if a softirq handler were to use kernel mode NEON the resulting attempt to save the live FPSIMD/SVE/SME state would result in a fatal trap.

That issue was limited to VHE mode. For nVHE/hVHE modes, KVM always saved/restored the host kernel's CPACR_EL1 value, and configured CPTR_EL2.TSM to 0b0, ensuring that host usage of SME would not be trapped.

The issue above was incidentally fixed by commit:

375110ab51dec5dc ("KVM: arm64: Fix resetting SME trap values on reset for (h)VHE")

That commit changed the VHE hyp code to configure CPTR_EL2.SMEN to 0b01 when returning to the host, permitting host kernel usage of SME, avoiding the issue described above. At the time, this was not identified as a fix for commit 861262ab86270206.

Now that the host eagerly saves and unbinds its own FPSIMD/SVE/SME state, there's no need to save/restore the state of the EL0 SME trap. The kernel can safely save/restore state without trapping, as described above, and will restore userspace state (including trap controls) before returning to userspace.

Remove the redundant logic.

---
 arch/arm64/include/asm/kvm_host.h |    2 --
 arch/arm64/kvm/fpsimd.c           |   21 ---------------------
 2 files changed, 23 deletions(-)
arch/arm64/include/asm/kvm_host.h +0 -2
@@ -891,8 +891,6 @@ struct kvm_vcpu_arch {
 /* Save TRBE context if active  */
 #define DEBUG_STATE_SAVE_TRBE	__vcpu_single_flag(iflags, BIT(6))
 
-/* SME enabled for EL0 */
-#define HOST_SME_ENABLED	__vcpu_single_flag(sflags, BIT(1))
 /* Physical CPU not in supported_cpus */
 #define ON_UNSUPPORTED_CPU	__vcpu_single_flag(sflags, BIT(2))
 /* WFIT instruction trapped */
arch/arm64/kvm/fpsimd.c +0 -21
@@ -65,12 +65,6 @@ void kvm_arch_vcpu_load_fp(struct kvm_vc
 	fpsimd_save_and_flush_cpu_state();
 	*host_data_ptr(fp_owner) = FP_STATE_FREE;
 
-	if (system_supports_sme()) {
-		vcpu_clear_flag(vcpu, HOST_SME_ENABLED);
-		if (read_sysreg(cpacr_el1) & CPACR_EL1_SMEN_EL0EN)
-			vcpu_set_flag(vcpu, HOST_SME_ENABLED);
-	}
-
 	/*
 	 * If normal guests gain SME support, maintain this behavior for pKVM
 	 * guests, which don't support SME.
@@ -141,21 +135,6 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcp
 
 	local_irq_save(flags);
 
-	/*
-	 * If we have VHE then the Hyp code will reset CPACR_EL1 to
-	 * the default value and we need to reenable SME.
-	 */
-	if (has_vhe() && system_supports_sme()) {
-		/* Also restore EL0 state seen on entry */
-		if (vcpu_get_flag(vcpu, HOST_SME_ENABLED))
-			sysreg_clear_set(CPACR_EL1, 0, CPACR_ELx_SMEN);
-		else
-			sysreg_clear_set(CPACR_EL1,
-					 CPACR_EL1_SMEN_EL0EN,
-					 CPACR_EL1_SMEN_EL1EN);
-		isb();
-	}
-
 	if (guest_owns_fp_regs()) {
 		if (vcpu_has_sve(vcpu)) {
 			u64 zcr = read_sysreg_el1(SYS_ZCR);
author maintainer
#111 lore raw

PATCH 109/116 KVM: arm64: Refactor exit handlers

In reply to Greg Kroah-Hartman

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

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

From: Mark Rutland <[email protected]>

[ Upstream commit 9b66195063c5a145843547b1d692bd189be85287 ]

The hyp exit handling logic is largely shared between VHE and nVHE/hVHE, with common logic in arch/arm64/kvm/hyp/include/hyp/switch.h. The code in the header depends on function definitions provided by arch/arm64/kvm/hyp/vhe/switch.c and arch/arm64/kvm/hyp/nvhe/switch.c when they include the header.

This is an unusual header dependency, and prevents the use of arch/arm64/kvm/hyp/include/hyp/switch.h in other files as this would result in compiler warnings regarding missing definitions, e.g.

| In file included from arch/arm64/kvm/hyp/nvhe/hyp-main.c:8:
| ./arch/arm64/kvm/hyp/include/hyp/switch.h:733:31: warning: 'kvm_get_exit_handler_array' used but never defined
|   733 | static const exit_handler_fn *kvm_get_exit_handler_array(struct kvm_vcpu *vcpu);
|       |                               ^~~~~~~~~~~~~~~~~~~~~~~~~~
| ./arch/arm64/kvm/hyp/include/hyp/switch.h:735:13: warning: 'early_exit_filter' used but never defined
|   735 | static void early_exit_filter(struct kvm_vcpu *vcpu, u64 *exit_code);
|       |             ^~~~~~~~~~~~~~~~~

Refactor the logic such that the header doesn't depend on anything from the C files. There should be no functional change as a result of this patch.

---
 arch/arm64/kvm/hyp/include/hyp/switch.h |   30 ++++++------------------------
 arch/arm64/kvm/hyp/nvhe/switch.c        |   28 ++++++++++++++++------------
 arch/arm64/kvm/hyp/vhe/switch.c         |    9 ++++-----
 3 files changed, 26 insertions(+), 41 deletions(-)
arch/arm64/kvm/hyp/include/hyp/switch.h +6 -24
@@ -635,23 +635,16 @@ static bool kvm_hyp_handle_dabt_low(stru
 
 typedef bool (*exit_handler_fn)(struct kvm_vcpu *, u64 *);
 
-static const exit_handler_fn *kvm_get_exit_handler_array(struct kvm_vcpu *vcpu);
-
-static void early_exit_filter(struct kvm_vcpu *vcpu, u64 *exit_code);
-
 /*
  * Allow the hypervisor to handle the exit with an exit handler if it has one.
  *
  * Returns true if the hypervisor handled the exit, and control should go back
  * to the guest, or false if it hasn't.
  */
-static inline bool kvm_hyp_handle_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
+static inline bool kvm_hyp_handle_exit(struct kvm_vcpu *vcpu, u64 *exit_code,
+				       const exit_handler_fn *handlers)
 {
-	const exit_handler_fn *handlers = kvm_get_exit_handler_array(vcpu);
-	exit_handler_fn fn;
-
-	fn = handlers[kvm_vcpu_trap_get_class(vcpu)];
-
+	exit_handler_fn fn = handlers[kvm_vcpu_trap_get_class(vcpu)];
 	if (fn)
 		return fn(vcpu, exit_code);
 
@@ -681,20 +674,9 @@ static inline void synchronize_vcpu_psta
  * the guest, false when we should restore the host state and return to the
  * main run loop.
  */
-static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
+static inline bool __fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code,
+				      const exit_handler_fn *handlers)
 {
-	/*
-	 * Save PSTATE early so that we can evaluate the vcpu mode
-	 * early on.
-	 */
-	synchronize_vcpu_pstate(vcpu, exit_code);
-
-	/*
-	 * Check whether we want to repaint the state one way or
-	 * another.
-	 */
-	early_exit_filter(vcpu, exit_code);
-
 	if (ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ)
 		vcpu->arch.fault.esr_el2 = read_sysreg_el2(SYS_ESR);
 
@@ -724,7 +706,7 @@ static inline bool fixup_guest_exit(stru
 		goto exit;
 
 	/* Check if there's an exit handler and allow it to handle the exit. */
-	if (kvm_hyp_handle_exit(vcpu, exit_code))
+	if (kvm_hyp_handle_exit(vcpu, exit_code, handlers))
 		goto guest;
 exit:
 	/* Return to the host kernel and handle the exit */
arch/arm64/kvm/hyp/nvhe/switch.c +16 -12
@@ -224,19 +224,21 @@ static const exit_handler_fn *kvm_get_ex
 	return hyp_exit_handlers;
 }
 
-/*
- * Some guests (e.g., protected VMs) are not be allowed to run in AArch32.
- * The ARMv8 architecture does not give the hypervisor a mechanism to prevent a
- * guest from dropping to AArch32 EL0 if implemented by the CPU. If the
- * hypervisor spots a guest in such a state ensure it is handled, and don't
- * trust the host to spot or fix it.  The check below is based on the one in
- * kvm_arch_vcpu_ioctl_run().
- *
- * Returns false if the guest ran in AArch32 when it shouldn't have, and
- * thus should exit to the host, or true if a the guest run loop can continue.
- */
-static void early_exit_filter(struct kvm_vcpu *vcpu, u64 *exit_code)
+static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
+	const exit_handler_fn *handlers = kvm_get_exit_handler_array(vcpu);
+
+	synchronize_vcpu_pstate(vcpu, exit_code);
+
+	/*
+	 * Some guests (e.g., protected VMs) are not be allowed to run in
+	 * AArch32.  The ARMv8 architecture does not give the hypervisor a
+	 * mechanism to prevent a guest from dropping to AArch32 EL0 if
+	 * implemented by the CPU. If the hypervisor spots a guest in such a
+	 * state ensure it is handled, and don't trust the host to spot or fix
+	 * it.  The check below is based on the one in
+	 * kvm_arch_vcpu_ioctl_run().
+	 */
 	if (unlikely(vcpu_is_protected(vcpu) && vcpu_mode_is_32bit(vcpu))) {
 		/*
 		 * As we have caught the guest red-handed, decide that it isn't
@@ -249,6 +251,8 @@ static void early_exit_filter(struct kvm
 		*exit_code &= BIT(ARM_EXIT_WITH_SERROR_BIT);
 		*exit_code |= ARM_EXCEPTION_IL;
 	}
+
+	return __fixup_guest_exit(vcpu, exit_code, handlers);
 }
 
 /* Switch to the guest for legacy non-VHE systems */
arch/arm64/kvm/hyp/vhe/switch.c +4 -5
@@ -423,13 +423,10 @@ static const exit_handler_fn hyp_exit_ha
 	[ESR_ELx_EC_MOPS]		= kvm_hyp_handle_mops,
 };
 
-static const exit_handler_fn *kvm_get_exit_handler_array(struct kvm_vcpu *vcpu)
+static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
-	return hyp_exit_handlers;
-}
+	synchronize_vcpu_pstate(vcpu, exit_code);
 
-static void early_exit_filter(struct kvm_vcpu *vcpu, u64 *exit_code)
-{
 	/*
 	 * If we were in HYP context on entry, adjust the PSTATE view
 	 * so that the usual helpers work correctly.
@@ -449,6 +446,8 @@ static void early_exit_filter(struct kvm
 		*vcpu_cpsr(vcpu) &= ~(PSR_MODE_MASK | PSR_MODE32_BIT);
 		*vcpu_cpsr(vcpu) |= mode;
 	}
+
+	return __fixup_guest_exit(vcpu, exit_code, hyp_exit_handlers);
 }
 
 /* Switch to the guest for VHE systems running in EL2 */
author maintainer
#112 lore raw

PATCH 110/116 KVM: arm64: Mark some header functions as inline

In reply to Greg Kroah-Hartman

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

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

From: Mark Rutland <[email protected]>

[ Upstream commit f9dd00de1e53a47763dfad601635d18542c3836d ]

The shared hyp switch header has a number of static functions which might not be used by all files that include the header, and when unused they will provoke compiler warnings, e.g.

| In file included from arch/arm64/kvm/hyp/nvhe/hyp-main.c:8:
| ./arch/arm64/kvm/hyp/include/hyp/switch.h:703:13: warning: 'kvm_hyp_handle_dabt_low' defined but not used [-Wunused-function]
|   703 | static bool kvm_hyp_handle_dabt_low(struct kvm_vcpu *vcpu, u64 *exit_code)
|       |             ^~~~~~~~~~~~~~~~~~~~~~~
| ./arch/arm64/kvm/hyp/include/hyp/switch.h:682:13: warning: 'kvm_hyp_handle_cp15_32' defined but not used [-Wunused-function]
|   682 | static bool kvm_hyp_handle_cp15_32(struct kvm_vcpu *vcpu, u64 *exit_code)
|       |             ^~~~~~~~~~~~~~~~~~~~~~
| ./arch/arm64/kvm/hyp/include/hyp/switch.h:662:13: warning: 'kvm_hyp_handle_sysreg' defined but not used [-Wunused-function]
|   662 | static bool kvm_hyp_handle_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code)
|       |             ^~~~~~~~~~~~~~~~~~~~~
| ./arch/arm64/kvm/hyp/include/hyp/switch.h:458:13: warning: 'kvm_hyp_handle_fpsimd' defined but not used [-Wunused-function]
|   458 | static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
|       |             ^~~~~~~~~~~~~~~~~~~~~
| ./arch/arm64/kvm/hyp/include/hyp/switch.h:329:13: warning: 'kvm_hyp_handle_mops' defined but not used [-Wunused-function]
|   329 | static bool kvm_hyp_handle_mops(struct kvm_vcpu *vcpu, u64 *exit_code)
|       |             ^~~~~~~~~~~~~~~~~~~

Mark these functions as 'inline' to suppress this warning. This shouldn't result in any functional change.

At the same time, avoid the use of __alias() in the header and alias kvm_hyp_handle_iabt_low() and kvm_hyp_handle_watchpt_low() to kvm_hyp_handle_memory_fault() using CPP, matching the style in the rest of the kernel. For consistency, kvm_hyp_handle_memory_fault() is also marked as 'inline'.

---
 arch/arm64/kvm/hyp/include/hyp/switch.h |   19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)
arch/arm64/kvm/hyp/include/hyp/switch.h +9 -10
@@ -295,7 +295,7 @@ static inline bool __populate_fault_info
 	return __get_fault_info(vcpu->arch.fault.esr_el2, &vcpu->arch.fault);
 }
 
-static bool kvm_hyp_handle_mops(struct kvm_vcpu *vcpu, u64 *exit_code)
+static inline bool kvm_hyp_handle_mops(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
 	*vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR);
 	arm64_mops_reset_regs(vcpu_gp_regs(vcpu), vcpu->arch.fault.esr_el2);
@@ -373,7 +373,7 @@ static void kvm_hyp_save_fpsimd_host(str
  * If FP/SIMD is not implemented, handle the trap and inject an undefined
  * instruction exception to the guest. Similarly for trapped SVE accesses.
  */
-static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
+static inline bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
 	bool sve_guest;
 	u8 esr_ec;
@@ -564,7 +564,7 @@ static bool handle_ampere1_tcr(struct kv
 	return true;
 }
 
-static bool kvm_hyp_handle_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code)
+static inline bool kvm_hyp_handle_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
 	if (cpus_have_final_cap(ARM64_WORKAROUND_CAVIUM_TX2_219_TVM) &&
 	    handle_tx2_tvm(vcpu))
@@ -584,7 +584,7 @@ static bool kvm_hyp_handle_sysreg(struct
 	return false;
 }
 
-static bool kvm_hyp_handle_cp15_32(struct kvm_vcpu *vcpu, u64 *exit_code)
+static inline bool kvm_hyp_handle_cp15_32(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
 	if (static_branch_unlikely(&vgic_v3_cpuif_trap) &&
 	    __vgic_v3_perform_cpuif_access(vcpu) == 1)
@@ -593,19 +593,18 @@ static bool kvm_hyp_handle_cp15_32(struc
 	return false;
 }
 
-static bool kvm_hyp_handle_memory_fault(struct kvm_vcpu *vcpu, u64 *exit_code)
+static inline bool kvm_hyp_handle_memory_fault(struct kvm_vcpu *vcpu,
+					       u64 *exit_code)
 {
 	if (!__populate_fault_info(vcpu))
 		return true;
 
 	return false;
 }
-static bool kvm_hyp_handle_iabt_low(struct kvm_vcpu *vcpu, u64 *exit_code)
-	__alias(kvm_hyp_handle_memory_fault);
-static bool kvm_hyp_handle_watchpt_low(struct kvm_vcpu *vcpu, u64 *exit_code)
-	__alias(kvm_hyp_handle_memory_fault);
+#define kvm_hyp_handle_iabt_low		kvm_hyp_handle_memory_fault
+#define kvm_hyp_handle_watchpt_low	kvm_hyp_handle_memory_fault
 
-static bool kvm_hyp_handle_dabt_low(struct kvm_vcpu *vcpu, u64 *exit_code)
+static inline bool kvm_hyp_handle_dabt_low(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
 	if (kvm_hyp_handle_memory_fault(vcpu, exit_code))
 		return true;
author maintainer
#113 lore raw

PATCH 111/116 KVM: arm64: Eagerly switch ZCR_EL{1,2}

In reply to Greg Kroah-Hartman

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

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

From: Mark Rutland <[email protected]>

[ Upstream commit 59419f10045bc955d2229819c7cf7a8b0b9c5b59 ]

In non-protected KVM modes, while the guest FPSIMD/SVE/SME state is live on the CPU, the host's active SVE VL may differ from the guest's maximum SVE VL:

* For VHE hosts, when a VM uses NV, ZCR_EL2 contains a value constrained by the guest hypervisor, which may be less than or equal to that guest's maximum VL.

Note: in this case the value of ZCR_EL1 is immaterial due to E2H.

* For nVHE/hVHE hosts, ZCR_EL1 contains a value written by the guest, which may be less than or greater than the guest's maximum VL.

Note: in this case hyp code traps host SVE usage and lazily restores ZCR_EL2 to the host's maximum VL, which may be greater than the guest's maximum VL.

This can be the case between exiting a guest and kvm_arch_vcpu_put_fp(). If a softirq is taken during this period and the softirq handler tries to use kernel-mode NEON, then the kernel will fail to save the guest's FPSIMD/SVE state, and will pend a SIGKILL for the current thread.

This happens because kvm_arch_vcpu_ctxsync_fp() binds the guest's live FPSIMD/SVE state with the guest's maximum SVE VL, and fpsimd_save_user_state() verifies that the live SVE VL is as expected before attempting to save the register state:

| if (WARN_ON(sve_get_vl() != vl)) {
|         force_signal_inject(SIGKILL, SI_KERNEL, 0, 0);
|         return;
| }

Fix this and make this a bit easier to reason about by always eagerly switching ZCR_EL{1,2} at hyp during guest<->host transitions. With this happening, there's no need to trap host SVE usage, and the nVHE/nVHE __deactivate_cptr_traps() logic can be simplified to enable host access to all present FPSIMD/SVE/SME features.

In protected nVHE/hVHE modes, the host's state is always saved/restored by hyp, and the guest's state is saved prior to exit to the host, so from the host's PoV the guest never has live FPSIMD/SVE/SME state, and the host's ZCR_EL1 is never clobbered by hyp.

Fixes 8c8010d69c132273 ("KVM: arm64: Save/restore SVE state for nVHE")
Fixes 2e3cf82063a00ea0 ("KVM: arm64: nv: Ensure correct VL is loaded before saving SVE state")
Cc Catalin Marinas <[email protected]>
Cc Fuad Tabba <[email protected]>
Cc Marc Zyngier <[email protected]>
Cc Oliver Upton <[email protected]>
Cc Will Deacon <[email protected]>
---
 arch/arm64/kvm/fpsimd.c                 |   30 ----------------
 arch/arm64/kvm/hyp/entry.S              |    5 ++
 arch/arm64/kvm/hyp/include/hyp/switch.h |   59 ++++++++++++++++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/hyp-main.c      |    9 +---
 arch/arm64/kvm/hyp/nvhe/switch.c        |   33 +++++++++++++++--
 arch/arm64/kvm/hyp/vhe/switch.c         |    4 ++
 6 files changed, 100 insertions(+), 40 deletions(-)
arch/arm64/kvm/fpsimd.c +0 -30
@@ -136,36 +136,6 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcp
 	local_irq_save(flags);
 
 	if (guest_owns_fp_regs()) {
-		if (vcpu_has_sve(vcpu)) {
-			u64 zcr = read_sysreg_el1(SYS_ZCR);
-
-			/*
-			 * If the vCPU is in the hyp context then ZCR_EL1 is
-			 * loaded with its vEL2 counterpart.
-			 */
-			__vcpu_sys_reg(vcpu, vcpu_sve_zcr_elx(vcpu)) = zcr;
-
-			/*
-			 * Restore the VL that was saved when bound to the CPU,
-			 * which is the maximum VL for the guest. Because the
-			 * layout of the data when saving the sve state depends
-			 * on the VL, we need to use a consistent (i.e., the
-			 * maximum) VL.
-			 * Note that this means that at guest exit ZCR_EL1 is
-			 * not necessarily the same as on guest entry.
-			 *
-			 * ZCR_EL2 holds the guest hypervisor's VL when running
-			 * a nested guest, which could be smaller than the
-			 * max for the vCPU. Similar to above, we first need to
-			 * switch to a VL consistent with the layout of the
-			 * vCPU's SVE state. KVM support for NV implies VHE, so
-			 * using the ZCR_EL1 alias is safe.
-			 */
-			if (!has_vhe() || (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)))
-				sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1,
-						       SYS_ZCR_EL1);
-		}
-
 		/*
 		 * Flush (save and invalidate) the fpsimd/sve state so that if
 		 * the host tries to use fpsimd/sve, it's not using stale data
arch/arm64/kvm/hyp/entry.S +5 -0
@@ -44,6 +44,11 @@ alternative_if ARM64_HAS_RAS_EXTN
 alternative_else_nop_endif
 	mrs	x1, isr_el1
 	cbz	x1,  1f
+
+	// Ensure that __guest_enter() always provides a context
+	// synchronization event so that callers don't need ISBs for anything
+	// that would usually be synchonized by the ERET.
+	isb
 	mov	x0, #ARM_EXCEPTION_IRQ
 	ret
 
arch/arm64/kvm/hyp/include/hyp/switch.h +59 -0

65 lines not on this page · raw message

arch/arm64/kvm/hyp/nvhe/hyp-main.c +3 -6
@@ -5,6 +5,7 @@
  */
 
 #include <hyp/adjust_pc.h>
+#include <hyp/switch.h>
 
 #include <asm/pgtable-types.h>
 #include <asm/kvm_asm.h>
@@ -177,7 +178,9 @@ static void handle___kvm_vcpu_run(struct
 		pkvm_put_hyp_vcpu(hyp_vcpu);
 	} else {
 		/* The host is fully trusted, run its vCPU directly. */
+		fpsimd_lazy_switch_to_guest(host_vcpu);
 		ret = __kvm_vcpu_run(host_vcpu);
+		fpsimd_lazy_switch_to_host(host_vcpu);
 	}
 
 out:
@@ -486,12 +489,6 @@ void handle_trap(struct kvm_cpu_context
 	case ESR_ELx_EC_SMC64:
 		handle_host_smc(host_ctxt);
 		break;
-	case ESR_ELx_EC_SVE:
-		cpacr_clear_set(0, CPACR_ELx_ZEN);
-		isb();
-		sve_cond_update_zcr_vq(sve_vq_from_vl(kvm_host_sve_max_vl) - 1,
-				       SYS_ZCR_EL2);
-		break;
 	case ESR_ELx_EC_IABT_LOW:
 	case ESR_ELx_EC_DABT_LOW:
 		handle_host_mem_abort(host_ctxt);
arch/arm64/kvm/hyp/nvhe/switch.c +29 -4
@@ -40,6 +40,9 @@ static void __activate_cptr_traps(struct
 {
 	u64 val = CPTR_EL2_TAM;	/* Same bit irrespective of E2H */
 
+	if (!guest_owns_fp_regs())
+		__activate_traps_fpsimd32(vcpu);
+
 	if (has_hvhe()) {
 		val |= CPACR_ELx_TTA;
 
@@ -48,6 +51,8 @@ static void __activate_cptr_traps(struct
 			if (vcpu_has_sve(vcpu))
 				val |= CPACR_ELx_ZEN;
 		}
+
+		write_sysreg(val, cpacr_el1);
 	} else {
 		val |= CPTR_EL2_TTA | CPTR_NVHE_EL2_RES1;
 
@@ -62,12 +67,32 @@ static void __activate_cptr_traps(struct
 
 		if (!guest_owns_fp_regs())
 			val |= CPTR_EL2_TFP;
+
+		write_sysreg(val, cptr_el2);
 	}
+}
 
-	if (!guest_owns_fp_regs())
-		__activate_traps_fpsimd32(vcpu);
+static void __deactivate_cptr_traps(struct kvm_vcpu *vcpu)
+{
+	if (has_hvhe()) {
+		u64 val = CPACR_ELx_FPEN;
+
+		if (cpus_have_final_cap(ARM64_SVE))
+			val |= CPACR_ELx_ZEN;
+		if (cpus_have_final_cap(ARM64_SME))
+			val |= CPACR_ELx_SMEN;
+
+		write_sysreg(val, cpacr_el1);
+	} else {
+		u64 val = CPTR_NVHE_EL2_RES1;
+
+		if (!cpus_have_final_cap(ARM64_SVE))
+			val |= CPTR_EL2_TZ;
+		if (!cpus_have_final_cap(ARM64_SME))
+			val |= CPTR_EL2_TSM;
 
-	kvm_write_cptr_el2(val);
+		write_sysreg(val, cptr_el2);
+	}
 }
 
 static void __activate_traps(struct kvm_vcpu *vcpu)
@@ -120,7 +145,7 @@ static void __deactivate_traps(struct kv
 
 	write_sysreg(this_cpu_ptr(&kvm_init_params)->hcr_el2, hcr_el2);
 
-	kvm_reset_cptr_el2(vcpu);
+	__deactivate_cptr_traps(vcpu);
 	write_sysreg(__kvm_hyp_host_vector, vbar_el2);
 }
 
arch/arm64/kvm/hyp/vhe/switch.c +4 -0
@@ -462,6 +462,8 @@ static int __kvm_vcpu_run_vhe(struct kvm
 
 	sysreg_save_host_state_vhe(host_ctxt);
 
+	fpsimd_lazy_switch_to_guest(vcpu);
+
 	/*
 	 * Note that ARM erratum 1165522 requires us to configure both stage 1
 	 * and stage 2 translation for the guest context before we clear
@@ -486,6 +488,8 @@ static int __kvm_vcpu_run_vhe(struct kvm
 
 	__deactivate_traps(vcpu);
 
+	fpsimd_lazy_switch_to_host(vcpu);
+
 	sysreg_restore_host_state_vhe(host_ctxt);
 
 	if (guest_owns_fp_regs())
author maintainer
#114 lore raw

PATCH 112/116 Revert "sched/core: Reduce cost of sched_move_task when config autogroup"

In reply to Greg Kroah-Hartman

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

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

From: Dietmar Eggemann <[email protected]>

commit 76f970ce51c80f625eb6ddbb24e9cb51b977b598 upstream.

This reverts commit eff6c8ce8d4d7faef75f66614dd20bb50595d261.

Hazem reported a 30% drop in UnixBench spawn test with commit eff6c8ce8d4d ("sched/core: Reduce cost of sched_move_task when config autogroup") on a m6g.xlarge AWS EC2 instance with 4 vCPUs and 16 GiB RAM (aarch64) (single level MC sched domain):

https://lkml.kernel.org/r/[email protected]

There is an early bail from sched_move_task() if p->sched_task_group is equal to p's 'cpu cgroup' (sched_get_task_group()). E.g. both are pointing to taskgroup '/user.slice/user-1000.slice/session-1.scope' (Ubuntu '22.04.5 LTS').

So in:

do_exit()

    sched_autogroup_exit_task()

      sched_move_task()

        if sched_get_task_group(p) == p->sched_task_group
          return

        /* p is enqueued */
        dequeue_task()              \
        sched_change_group()        |
          task_change_group_fair()  |
            detach_task_cfs_rq()    |                              (1)
            set_task_rq()           |
            attach_task_cfs_rq()    |
        enqueue_task()              /

(1) isn't called for p anymore.

Turns out that the regression is related to sgs->group_util in group_is_overloaded() and group_has_capacity(). If (1) isn't called for all the 'spawn' tasks then sgs->group_util is ~900 and sgs->group_capacity = 1024 (single CPU sched domain) and this leads to group_is_overloaded() returning true (2) and group_has_capacity() false
(3) much more often compared to the case when (1) is called.

I.e. there are much more cases of 'group_is_overloaded' and 'group_fully_busy' in WF_FORK wakeup sched_balance_find_dst_cpu() which then returns much more often a CPU != smp_processor_id() (5).

This isn't good for these extremely short running tasks (FORK + EXIT) and also involves calling sched_balance_find_dst_group_cpu() unnecessary (single CPU sched domain).

Instead if (1) is called for 'p->flags & PF_EXITING' then the path (4),(6) is taken much more often.

select_task_rq_fair(..., wake_flags = WF_FORK)

cpu = smp_processor_id()

new_cpu = sched_balance_find_dst_cpu(..., cpu, ...)

group = sched_balance_find_dst_group(..., cpu)

do {

update_sg_wakeup_stats()

sgs->group_type = group_classify()

if group_is_overloaded() (2)
return group_overloaded

if !group_has_capacity() (3)
return group_fully_busy

return group_has_spare (4)

} while group

if local_sgs.group_type > idlest_sgs.group_type
return idlest (5)

case group_has_spare:

if local_sgs.idle_cpus >= idlest_sgs.idle_cpus
return NULL (6)

Unixbench Tests './Run -c 4 spawn' on:

(a) VM AWS instance (m7gd.16xlarge) with v6.13 ('maxcpus=4 nr_cpus=4')

    and Ubuntu 22.04.5 LTS (aarch64).

    Shell & test run in '/user.slice/user-1000.slice/session-1.scope'.

    w/o patch	w/ patch
    21005	27120

(b) i7-13700K with tip/sched/core ('nosmt maxcpus=8 nr_cpus=8') and Ubuntu 22.04.5 LTS (x86_64).

Shell & test run in '/A'.

w/o patch w/ patch
67675 88806

CONFIG_SCHED_AUTOGROUP=y & /sys/proc/kernel/sched_autogroup_enabled equal 0 or 1.

---
 kernel/sched/core.c |   21 +++------------------
 1 file changed, 3 insertions(+), 18 deletions(-)
kernel/sched/core.c +3 -18
@@ -8919,7 +8919,7 @@ void sched_release_group(struct task_gro
 	spin_unlock_irqrestore(&task_group_lock, flags);
 }
 
-static struct task_group *sched_get_task_group(struct task_struct *tsk)
+static void sched_change_group(struct task_struct *tsk)
 {
 	struct task_group *tg;
 
@@ -8931,13 +8931,7 @@ static struct task_group *sched_get_task
 	tg = container_of(task_css_check(tsk, cpu_cgrp_id, true),
 			  struct task_group, css);
 	tg = autogroup_task_group(tsk, tg);
-
-	return tg;
-}
-
-static void sched_change_group(struct task_struct *tsk, struct task_group *group)
-{
-	tsk->sched_task_group = group;
+	tsk->sched_task_group = tg;
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
 	if (tsk->sched_class->task_change_group)
@@ -8958,20 +8952,11 @@ void sched_move_task(struct task_struct
 {
 	int queued, running, queue_flags =
 		DEQUEUE_SAVE | DEQUEUE_MOVE | DEQUEUE_NOCLOCK;
-	struct task_group *group;
 	struct rq *rq;
 
 	CLASS(task_rq_lock, rq_guard)(tsk);
 	rq = rq_guard.rq;
 
-	/*
-	 * Esp. with SCHED_AUTOGROUP enabled it is possible to get superfluous
-	 * group changes.
-	 */
-	group = sched_get_task_group(tsk);
-	if (group == tsk->sched_task_group)
-		return;
-
 	update_rq_clock(rq);
 
 	running = task_current(rq, tsk);
@@ -8982,7 +8967,7 @@ void sched_move_task(struct task_struct
 	if (running)
 		put_prev_task(rq, tsk);
 
-	sched_change_group(tsk, group);
+	sched_change_group(tsk);
 	if (!for_autogroup)
 		scx_cgroup_move_task(tsk);
 
author maintainer
#115 lore raw

PATCH 113/116 libsubcmd: Silence compiler warning

In reply to Greg Kroah-Hartman

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

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

From: Eder Zulian <[email protected]>

commit 7a4ffec9fd54ea27395e24dff726dbf58e2fe06b upstream.

Initialize the pointer 'o' in options__order to NULL to prevent a compiler warning/error which is observed when compiling with the '-Og' option, but is not emitted by the compiler with the current default compilation options.

For example, when compiling libsubcmd with

 $ make "EXTRA_CFLAGS=-Og" -C tools/lib/subcmd/ clean all

Clang version 17.0.6 and GCC 13.3.1 fail to compile parse-options.c due to following error:

parse-options.c: In function ‘options__order’:
parse-options.c:832:9: error: ‘o’ may be used uninitialized [-Werror=maybe-uninitialized]

    832 |         memcpy(&ordered[nr_opts], o, sizeof(*o));
        |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  parse-options.c:810:30: note: ‘o’ was declared here
    810 |         const struct option *o, *p = opts;
        |                              ^

cc1: all warnings being treated as errors

---
 tools/lib/subcmd/parse-options.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/lib/subcmd/parse-options.c +1 -1
@@ -807,7 +807,7 @@ static int option__cmp(const void *va, c
 static struct option *options__order(const struct option *opts)
 {
 	int nr_opts = 0, nr_group = 0, nr_parent = 0, len;
-	const struct option *o, *p = opts;
+	const struct option *o = NULL, *p = opts;
 	struct option *opt, *ordered = NULL, *group;
 
 	/* flatten the options that have parents */
author maintainer
#116 lore raw

PATCH 114/116 arm64: dts: rockchip: fix u2phy1_host status for NanoPi R4S

In reply to Greg Kroah-Hartman

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

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

From: Justin Klaassen <[email protected]>

commit 38f4aa34a5f737ea8588dac320d884cc2e762c03 upstream.

The u2phy1_host should always have the same status as usb_host1_ehci and usb_host1_ohci, otherwise the EHCI and OHCI drivers may be initialized for a disabled usb port.

Per the NanoPi R4S schematic, the phy-supply for u2phy1_host is set to the vdd_5v regulator.

---
 arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts +1 -1
@@ -117,7 +117,7 @@
 };
 
 &u2phy1_host {
-	status = "disabled";
+	phy-supply = <&vdd_5v>;
 };
 
 &uart0 {
author maintainer
#117 lore raw

PATCH 115/116 mm/huge_memory: drop beyond-EOF folios with the right number of refs

In reply to Greg Kroah-Hartman

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

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

From: Zi Yan <[email protected]>

commit 14efb4793519d73fb2902bb0ece319b886e4b4b9 upstream.

When an after-split folio is large and needs to be dropped due to EOF, folio_put_refs(folio, folio_nr_pages(folio)) should be used to drop all page cache refs. Otherwise, the folio will not be freed, causing memory leak.

This leak would happen on a filesystem with blocksize > page_size and a truncate is performed, where the blocksize makes folios split to >0 order ones, causing truncated folios not being freed.

Fixes c010d47f107f ("mm: thp: split huge page to any lower order pages")
Cc Baolin Wang <[email protected]>
Cc David Hildenbrand <[email protected]>
Cc John Hubbard <[email protected]>
Cc Kefeng Wang <[email protected]>
Cc Kirill A. Shuemov <[email protected]>
Cc Luis Chamberalin <[email protected]>
Cc Matthew Wilcow (Oracle) <[email protected]>
Cc Miaohe Lin <[email protected]>
Cc Pankaj Raghav <[email protected]>
Cc Ryan Roberts <[email protected]>
Cc Yang Shi <[email protected]>
Cc Yu Zhao <[email protected]>
---
 mm/huge_memory.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
mm/huge_memory.c +1 -1
@@ -3224,7 +3224,7 @@ static void __split_huge_page(struct pag
 				folio_account_cleaned(tail,
 					inode_to_wb(folio->mapping->host));
 			__filemap_remove_folio(tail, NULL);
-			folio_put(tail);
+			folio_put_refs(tail, folio_nr_pages(tail));
 		} else if (!PageAnon(page)) {
 			__xa_store(&folio->mapping->i_pages, head[i].index,
 					head + i, 0);
author maintainer
#118 lore raw

PATCH 116/116 mptcp: Fix data stream corruption in the address announcement

In reply to Greg Kroah-Hartman

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

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

From: Arthur Mongodin <[email protected]>

commit 2c1f97a52cb827a5f2768e67a9dddffae1ed47ab upstream.

Because of the size restriction in the TCP options space, the MPTCP ADD_ADDR option is exclusive and cannot be sent with other MPTCP ones. For this reason, in the linked mptcp_out_options structure, group of fields linked to different options are part of the same union.

There is a case where the mptcp_pm_add_addr_signal() function can modify opts->addr, but not ended up sending an ADD_ADDR. Later on, back in mptcp_established_options, other options will be sent, but with unexpected data written in other fields due to the union, e.g. in opts->ext_copy. This could lead to a data stream corruption in the next packet.

Using an intermediate variable, prevents from corrupting previously established DSS option. The assignment of the ADD_ADDR option parameters is now done once we are sure this ADD_ADDR option can be set in the packet, e.g. after having dropped other suboptions.

Fixes 1bff1e43a30e ("mptcp: optimize out option generation")

[ Matt: the commit message has been updated: long lines splits and some
clarifications. ]

---
 net/mptcp/options.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
net/mptcp/options.c +4 -2
@@ -651,6 +651,7 @@ static bool mptcp_established_options_ad
 	struct mptcp_sock *msk = mptcp_sk(subflow->conn);
 	bool drop_other_suboptions = false;
 	unsigned int opt_size = *size;
+	struct mptcp_addr_info addr;
 	bool echo;
 	int len;
 
@@ -659,7 +660,7 @@ static bool mptcp_established_options_ad
 	 */
 	if (!mptcp_pm_should_add_signal(msk) ||
 	    (opts->suboptions & (OPTION_MPTCP_MPJ_ACK | OPTION_MPTCP_MPC_ACK)) ||
-	    !mptcp_pm_add_addr_signal(msk, skb, opt_size, remaining, &opts->addr,
+	    !mptcp_pm_add_addr_signal(msk, skb, opt_size, remaining, &addr,
 		    &echo, &drop_other_suboptions))
 		return false;
 
@@ -672,7 +673,7 @@ static bool mptcp_established_options_ad
 	else if (opts->suboptions & OPTION_MPTCP_DSS)
 		return false;
 
-	len = mptcp_add_addr_len(opts->addr.family, echo, !!opts->addr.port);
+	len = mptcp_add_addr_len(addr.family, echo, !!addr.port);
 	if (remaining < len)
 		return false;
 
@@ -689,6 +690,7 @@ static bool mptcp_established_options_ad
 		opts->ahmac = 0;
 		*size -= opt_size;
 	}
+	opts->addr = addr;
 	opts->suboptions |= OPTION_MPTCP_ADD_ADDR;
 	if (!echo) {
 		MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_ADDADDRTX);
#119 lore raw
In reply to Greg Kroah-Hartman
Quoted 10 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 6.12.21 release. There are 116 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Thu, 27 Mar 2025 12:21:27 +0000. Anything received after that time might be too late.

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

Quoted 8 lines
        https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.12.21-rc1.gz

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

thanks,

greg k-h

Regressions on arm64 rk3399 dtb builds failed with gcc-13 the stable-rc 6.12.21-rc1

First seen on the v6.12.19-349-g8c2b29e24438
Good: v6.12.20
Bad: 6.12.21-rc1

* arm64, build
- gcc-13-defconfig

Regression Analysis:
- New regression? yes
- Reproducibility? Yes

Build regression: arm64 dtb rockchip non-existent node or label "vcca_0v9"

## Build log arch/arm64/boot/dts/rockchip/rk3399.dtsi:221.23-266.4: ERROR (phandle_references):
/pcie@f8000000: Reference to non-existent node or label "vcca_0v9"

also defined at arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi:665.8-675.3

Anders bisected this to,

# first bad commit:
  [b3d8759e5e8530302831e24232cb360388a2d62e]
  arm64: dts: rockchip: Add missing PCIe supplies to RockPro64 board dtsi

## Source
* Kernel version: 6.12.21-rc1
* Git tree: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
* Git sha: 8c2b29e24438f0439af527927ea2989df3a41c6f
* Git describe: v6.12.19-349-g8c2b29e24438
* Project details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.12.y/build/v6.12.19-349-g8c2b29e24438/

## Build
* Build log: https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.12.y/build/v6.12.19-349-g8c2b29e24438/testrun/27759652/suite/build/test/gcc-13-lkftconfig/log
* Build history:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.12.y/build/v6.12.19-349-g8c2b29e24438/testrun/27759652/suite/build/test/gcc-13-lkftconfig/history/
* Build details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.12.y/build/v6.12.19-349-g8c2b29e24438/testrun/27759652/suite/build/test/gcc-13-lkftconfig/details/
* Build link: https://storage.tuxsuite.com/public/linaro/lkft/builds/2uoHnrrOWLw0FMCQJDU4Si0cD9n/
* Kernel config:
https://storage.tuxsuite.com/public/linaro/lkft/builds/2uoHnrrOWLw0FMCQJDU4Si0cD9n/config

## Steps to reproduce
- # tuxmake --runtime podman --target-arch arm64 --toolchain gcc-13
--kconfig defconfig

--
Linaro LKFT
https://lkft.linaro.org

Tested-by on the v1 series
#120 lore raw
In reply to Greg Kroah-Hartman
Quoted 9 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 6.12.21 release. There are 116 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Thu, 27 Mar 2025 12:21:27 +0000. Anything received after that time might be too late.

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

Quoted 8 lines
	https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.12.21-rc1.gz

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

thanks,

greg k-h

On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:

Signature · 1 line
Florian
Tested-by on the v1 series
#121 lore raw
In reply to Greg Kroah-Hartman
Quoted 8 lines · On Tue, 25 Mar 2025 08:21:27 -0400 Greg Kroah-Hartman…

This is the start of the stable review cycle for the 6.12.21 release. There are 116 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Thu, 27 Mar 2025 12:21:27 +0000. Anything received after that time might be too late.

Using my usual Rust configs, for all of them, I got the same issue in arm64 that Naresh reported:

    arch/arm64/boot/dts/rockchip/rk3399-base.dtsi:291.23-336.4: ERROR (phandle_references): /pcie@f8000000: Reference to non-existent node or label "vcca_0v9"

      also defined at arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi:659.8-669.3
    ERROR: Input tree has errors, aborting (use -f to force output)
    make[3]: *** [scripts/Makefile.dtbs:131: arch/arm64/boot/dts/rockchip/rk3399-rockpro64-v2.dtb] Error 2

Boot-tested under QEMU for Rust x86_64 and riscv64; built-tested for loongarch64, build failure for arm64:

Thanks!

Cheers,
Miguel

Tested-by on the v1 series
#122 lore raw
In reply to Greg Kroah-Hartman

Hi!

Quoted 4 lines

This is the start of the stable review cycle for the 6.12.21 release. There are 116 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.

CIP testing did not find any problems here:

https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-6.12.y

6.6 looks broken, I assume that's similar error to 6.1.

6.13 is being retried, I guess it will pass.

https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-6.13.y

Best regards,
Pavel

Signature · 2 lines
DENX Software Engineering GmbH,        Managing Director: Erika Unter
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany