Skip to contentSkip to conversation

6.1.162-rc1 review

PATCH In review Greg Kroah-Hartman 8 participants 295 messages Feb 4 – Mar 19 Page 2 of 3

Subsystems (2)
lore
Share & tools
lore
author maintainer
#148 lore raw

PATCH 146/280 drm/amd/pm: Workaround SI powertune issue on Radeon 430 (v2)

In reply to Greg Kroah-Hartman

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

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

From: Timur Kristóf <[email protected]>

[ Upstream commit 764a90eb02268a23b1bb98be5f4a13671346804a ]

Radeon 430 and 520 are OEM GPUs from 2016~2017 They have the same device id: 0x6611 and revision: 0x87

On the Radeon 430, powertune is buggy and throttles the GPU, never allowing it to reach its maximum SCLK. Work around this bug by raising the TDP limits we program to the SMC from 24W (specified by the VBIOS on Radeon 430) to 32W.

Disabling powertune entirely is not a viable workaround,
because it causes the Radeon 520 to heat up above 100 C,
which I prefer to avoid.

Additionally, revise the maximum SCLK limit. Considering the above issue, these GPUs never reached a high SCLK on Linux, and the workarounds were added before the GPUs were released, so the workaround likely didn't target these specifically. Use 780 MHz (the maximum SCLK according to the VBIOS on the Radeon 430). Note that the Radeon 520 VBIOS has a higher maximum SCLK: 905 MHz, but in practice it doesn't seem to perform better with the higher clock, only heats up more.

v2:
Move the workaround to si_populate_smc_tdp_limits.

Fixes 841686df9f7d ("drm/amdgpu: add SI DPM support (v4)")
(cherry picked from commit 966d70f1e160bdfdecaf7ff2b3f22ad088516e9f)
---
 drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +12 -1
index a8278fa75ff9a..bcc4d9fa5b0d2 100644
@@ -2265,6 +2265,12 @@ static int si_populate_smc_tdp_limits(struct amdgpu_device *adev,
 		if (ret)
 			return ret;
 
+		if (adev->pdev->device == 0x6611 && adev->pdev->revision == 0x87) {
+			/* Workaround buggy powertune on Radeon 430 and 520. */
+			tdp_limit = 32;
+			near_tdp_limit = 28;
+		}
+
 		smc_table->dpm2Params.TDPLimit =
 			cpu_to_be32(si_scale_power_for_smc(tdp_limit, scaling_factor) * 1000);
 		smc_table->dpm2Params.NearTDPLimit =
@@ -3448,10 +3454,15 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev,
 		    (adev->pdev->revision == 0x80) ||
 		    (adev->pdev->revision == 0x81) ||
 		    (adev->pdev->revision == 0x83) ||
-		    (adev->pdev->revision == 0x87) ||
+		    (adev->pdev->revision == 0x87 &&
+				adev->pdev->device != 0x6611) ||
 		    (adev->pdev->device == 0x6604) ||
 		    (adev->pdev->device == 0x6605)) {
 			max_sclk = 75000;
+		} else if (adev->pdev->revision == 0x87 &&
+				adev->pdev->device == 0x6611) {
+			/* Radeon 430 and 520 */
+			max_sclk = 78000;
 		}
 	}
 
Signature · 1 line
2.51.0
author maintainer
#149 lore raw

PATCH 147/280 be2net: Fix NULL pointer dereference in be_cmd_get_mac_from_list

In reply to Greg Kroah-Hartman

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

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

From: Andrey Vatoropin <[email protected]>

[ Upstream commit 8215794403d264739cc676668087512950b2ff31 ]

When the parameter pmac_id_valid argument of be_cmd_get_mac_from_list() is set to false, the driver may request the PMAC_ID from the firmware of the network card, and this function will store that PMAC_ID at the provided address pmac_id. This is the contract of this function.

However, there is a location within the driver where both pmac_id_valid == false and pmac_id == NULL are being passed. This could result in dereferencing a NULL pointer.

To resolve this issue, it is necessary to pass the address of a stub variable to the function.

Fixes 95046b927a54 ("be2net: refactor MAC-addr setup code")
---
 drivers/net/ethernet/emulex/benet/be_cmds.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/emulex/benet/be_cmds.c +2 -1
index e764d2be4948a..12c48ad9a32d6 100644
@@ -3796,6 +3796,7 @@ int be_cmd_get_perm_mac(struct be_adapter *adapter, u8 *mac)
 {
 	int status;
 	bool pmac_valid = false;
+	u32 pmac_id;
 
 	eth_zero_addr(mac);
 
@@ -3808,7 +3809,7 @@ int be_cmd_get_perm_mac(struct be_adapter *adapter, u8 *mac)
 						       adapter->if_handle, 0);
 	} else {
 		status = be_cmd_get_mac_from_list(adapter, mac, &pmac_valid,
-						  NULL, adapter->if_handle, 0);
+						  &pmac_id, adapter->if_handle, 0);
 	}
 
 	return status;
Signature · 1 line
2.51.0
author maintainer
#150 lore raw

PATCH 148/280 selftests: net: amt: wait longer for connection before sending packets

In reply to Greg Kroah-Hartman

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

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

From: Taehee Yoo <[email protected]>

[ Upstream commit 04708606fd7bdc34b69089a4ff848ff36d7088f9 ]

Both send_mcast4() and send_mcast6() use sleep 2 to wait for the tunnel connection between the gateway and the relay, and for the listener socket to be created in the LISTENER namespace.

However, tests sometimes fail because packets are sent before the connection is fully established.

Increase the waiting time to make the tests more reliable, and use wait_local_port_listen() to explicitly wait for the listener socket.

Fixes c08e8baea78e ("selftests: add amt interface selftest script")
---
 tools/testing/selftests/net/amt.sh | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
tools/testing/selftests/net/amt.sh +5 -2
index 7e7ed6c558da9..ea40b469a8c11 100755
@@ -73,6 +73,8 @@
 #       +------------------------+
 #==============================================================================
 
+source lib.sh
+
 readonly LISTENER=$(mktemp -u listener-XXXXXXXX)
 readonly GATEWAY=$(mktemp -u gateway-XXXXXXXX)
 readonly RELAY=$(mktemp -u relay-XXXXXXXX)
@@ -240,14 +242,15 @@ test_ipv6_forward()
 
 send_mcast4()
 {
-	sleep 2
+	sleep 5
+	wait_local_port_listen ${LISTENER} 4000 udp
 	ip netns exec "${SOURCE}" bash -c \
 		'printf "%s %128s" 172.17.0.2 | nc -w 1 -u 239.0.0.1 4000' &
 }
 
 send_mcast6()
 {
-	sleep 2
+	wait_local_port_listen ${LISTENER} 6000 udp
 	ip netns exec "${SOURCE}" bash -c \
 		'printf "%s %128s" 2001:db8:3::2 | nc -w 1 -u ff0e::5:6 6000' &
 }
Signature · 1 line
2.51.0
#151 lore raw

Re: [PATCH 6.1 148/280] selftests: net: amt: wait longer for connection before sending packets

Quoted 1 line · Greg Kroah-Hartman

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

Hi Greg,

Apologies for the reply after review window. This patch depends on lib.sh under net selftests which doesn't exist in 6.1. The lib.sh file was introduced in v6.8-rc1 via commit 25ae948b4478 ("selftests/net: add lib.sh").

Without it, the test will fail on:
./amt.sh: line 76: source: lib.sh: file not found

Do you think, in this case, tools/testing/selftests/net/lib.sh is better backported? Or the patch should be reverted?

Thanks,
Nathan Gao

author maintainer
#152 lore raw

Re: [PATCH 6.1 148/280] selftests: net: amt: wait longer for connection before sending packets

Quoted 9 lines · Nathan Gao
Quoted 1 line · Greg Kroah-Hartman

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

Hi Greg,

Apologies for the reply after review window. This patch depends on lib.sh under net selftests which doesn't exist in 6.1. The lib.sh file was introduced in v6.8-rc1 via commit 25ae948b4478 ("selftests/net: add lib.sh").

Quoted 5 lines

Without it, the test will fail on:
./amt.sh: line 76: source: lib.sh: file not found

Do you think, in this case, tools/testing/selftests/net/lib.sh is better backported? Or the patch should be reverted?

Let's revert it, can you send a fix?

thanks,

greg k-h

author maintainer
#154 lore raw

PATCH 149/280 bonding: provide a net pointer to __skb_flow_dissect()

In reply to Greg Kroah-Hartman

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit 5f9b329096596b7e53e07d041d7fca4cbe1be752 ]

After 3cbf4ffba5ee ("net: plumb network namespace into __skb_flow_dissect") we have to provide a net pointer to __skb_flow_dissect(), either via skb->dev, skb->sk, or a user provided pointer.

In the following case, syzbot was able to cook a bare skb.

WARNING: net/core/flow_dissector.c:1131 at __skb_flow_dissect+0xb57/0x68b0 net/core/flow_dissector.c:1131, CPU#1: syz.2.1418/11053
Call Trace:
 <TASK>
  bond_flow_dissect drivers/net/bonding/bond_main.c:4093 [inline]
  __bond_xmit_hash+0x2d7/0xba0 drivers/net/bonding/bond_main.c:4157
  bond_xmit_hash_xdp drivers/net/bonding/bond_main.c:4208 [inline]
  bond_xdp_xmit_3ad_xor_slave_get drivers/net/bonding/bond_main.c:5139 [inline]
  bond_xdp_get_xmit_slave+0x1fd/0x710 drivers/net/bonding/bond_main.c:5515
  xdp_master_redirect+0x13f/0x2c0 net/core/filter.c:4388
  bpf_prog_run_xdp include/net/xdp.h:700 [inline]
  bpf_test_run+0x6b2/0x7d0 net/bpf/test_run.c:421
  bpf_prog_test_run_xdp+0x795/0x10e0 net/bpf/test_run.c:1390
  bpf_prog_test_run+0x2c7/0x340 kernel/bpf/syscall.c:4703
  __sys_bpf+0x562/0x860 kernel/bpf/syscall.c:6182
  __do_sys_bpf kernel/bpf/syscall.c:6274 [inline]
  __se_sys_bpf kernel/bpf/syscall.c:6272 [inline]
  __x64_sys_bpf+0x7c/0x90 kernel/bpf/syscall.c:6272
  do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
  do_syscall_64+0xec/0xf80 arch/x86/entry/syscall_64.c:94
---
 drivers/net/bonding/bond_main.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/bonding/bond_main.c +3 -2
index dd0ea86d7934a..b0bc811aaab91 100644
@@ -4128,8 +4128,9 @@ static bool bond_flow_dissect(struct bonding *bond, struct sk_buff *skb, const v
 	case BOND_XMIT_POLICY_ENCAP23:
 	case BOND_XMIT_POLICY_ENCAP34:
 		memset(fk, 0, sizeof(*fk));
-		return __skb_flow_dissect(NULL, skb, &flow_keys_bonding,
-					  fk, data, l2_proto, nhoff, hlen, 0);
+		return __skb_flow_dissect(dev_net(bond->dev), skb,
+					  &flow_keys_bonding, fk, data,
+					  l2_proto, nhoff, hlen, 0);
 	default:
 		break;
 	}
Signature · 1 line
2.51.0
author maintainer
#155 lore raw

PATCH 150/280 octeontx2-af: Fix error handling

In reply to Greg Kroah-Hartman

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

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

From: Ratheesh Kannoth <[email protected]>

[ Upstream commit 19e4175e997a5b85eab97d522f00cc99abd1873c ]

This commit adds error handling and rollback logic to rvu_mbox_handler_attach_resources() to properly clean up partially attached resources when rvu_attach_block() fails.

Fixes 746ea74241fa0 ("octeontx2-af: Add RVU block LF provisioning support")
---
 .../net/ethernet/marvell/octeontx2/af/rvu.c   | 86 ++++++++++++++-----
 1 file changed, 64 insertions(+), 22 deletions(-)
drivers/net/ethernet/marvell/octeontx2/af/rvu.c +64 -22
index d9c68f8166aff..7034a977102ea 100644
@@ -1540,8 +1540,8 @@ static int rvu_get_attach_blkaddr(struct rvu *rvu, int blktype,
 	return -ENODEV;
 }
 
-static void rvu_attach_block(struct rvu *rvu, int pcifunc, int blktype,
-			     int num_lfs, struct rsrc_attach *attach)
+static int rvu_attach_block(struct rvu *rvu, int pcifunc, int blktype,
+			    int num_lfs, struct rsrc_attach *attach)
 {
 	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
 	struct rvu_hwinfo *hw = rvu->hw;
@@ -1551,21 +1551,21 @@ static void rvu_attach_block(struct rvu *rvu, int pcifunc, int blktype,
 	u64 cfg;
 
 	if (!num_lfs)
-		return;
+		return -EINVAL;
 
 	blkaddr = rvu_get_attach_blkaddr(rvu, blktype, pcifunc, attach);
 	if (blkaddr < 0)
-		return;
+		return -EFAULT;
 
 	block = &hw->block[blkaddr];
 	if (!block->lf.bmap)
-		return;
+		return -ESRCH;
 
 	for (slot = 0; slot < num_lfs; slot++) {
 		/* Allocate the resource */
 		lf = rvu_alloc_rsrc(&block->lf);
 		if (lf < 0)
-			return;
+			return -EFAULT;
 
 		cfg = (1ULL << 63) | (pcifunc << 8) | slot;
 		rvu_write64(rvu, blkaddr, block->lfcfg_reg |
@@ -1576,6 +1576,8 @@ static void rvu_attach_block(struct rvu *rvu, int pcifunc, int blktype,
 		/* Set start MSIX vector for this LF within this PF/VF */
 		rvu_set_msix_offset(rvu, pfvf, block, lf);
 	}
+
+	return 0;
 }
 
 static int rvu_check_rsrc_availability(struct rvu *rvu,
@@ -1713,22 +1715,31 @@ int rvu_mbox_handler_attach_resources(struct rvu *rvu,
 	int err;
 
 	/* If first request, detach all existing attached resources */
-	if (!attach->modify)
-		rvu_detach_rsrcs(rvu, NULL, pcifunc);
+	if (!attach->modify) {
+		err = rvu_detach_rsrcs(rvu, NULL, pcifunc);
+		if (err)
+			return err;
+	}
 
 	mutex_lock(&rvu->rsrc_lock);
 
 	/* Check if the request can be accommodated */
 	err = rvu_check_rsrc_availability(rvu, attach, pcifunc);
 	if (err)
-		goto exit;
+		goto fail1;
 
 	/* Now attach the requested resources */
-	if (attach->npalf)
-		rvu_attach_block(rvu, pcifunc, BLKTYPE_NPA, 1, attach);
+	if (attach->npalf) {
+		err = rvu_attach_block(rvu, pcifunc, BLKTYPE_NPA, 1, attach);
+		if (err)
+			goto fail1;
+	}
 
-	if (attach->nixlf)
-		rvu_attach_block(rvu, pcifunc, BLKTYPE_NIX, 1, attach);
+	if (attach->nixlf) {
+		err = rvu_attach_block(rvu, pcifunc, BLKTYPE_NIX, 1, attach);
+		if (err)
+			goto fail2;
+	}
 
 	if (attach->sso) {
 		/* RVU func doesn't know which exact LF or slot is attached
@@ -1738,33 +1749,64 @@ int rvu_mbox_handler_attach_resources(struct rvu *rvu,
 		 */
 		if (attach->modify)
 			rvu_detach_block(rvu, pcifunc, BLKTYPE_SSO);
-		rvu_attach_block(rvu, pcifunc, BLKTYPE_SSO,
-				 attach->sso, attach);
+		err = rvu_attach_block(rvu, pcifunc, BLKTYPE_SSO,
+				       attach->sso, attach);
+		if (err)
+			goto fail3;
 	}
 
 	if (attach->ssow) {
 		if (attach->modify)
 			rvu_detach_block(rvu, pcifunc, BLKTYPE_SSOW);
-		rvu_attach_block(rvu, pcifunc, BLKTYPE_SSOW,
-				 attach->ssow, attach);
+		err = rvu_attach_block(rvu, pcifunc, BLKTYPE_SSOW,
+				       attach->ssow, attach);
+		if (err)
+			goto fail4;
 	}
 
 	if (attach->timlfs) {
 		if (attach->modify)
 			rvu_detach_block(rvu, pcifunc, BLKTYPE_TIM);
-		rvu_attach_block(rvu, pcifunc, BLKTYPE_TIM,
-				 attach->timlfs, attach);
+		err = rvu_attach_block(rvu, pcifunc, BLKTYPE_TIM,
+				       attach->timlfs, attach);
+		if (err)
+			goto fail5;
 	}
 
 	if (attach->cptlfs) {
 		if (attach->modify &&
 		    rvu_attach_from_same_block(rvu, BLKTYPE_CPT, attach))
 			rvu_detach_block(rvu, pcifunc, BLKTYPE_CPT);
-		rvu_attach_block(rvu, pcifunc, BLKTYPE_CPT,
-				 attach->cptlfs, attach);
+		err = rvu_attach_block(rvu, pcifunc, BLKTYPE_CPT,
+				       attach->cptlfs, attach);
+		if (err)
+			goto fail6;
 	}
 
-exit:
+	mutex_unlock(&rvu->rsrc_lock);
+	return 0;
+
+fail6:
+	if (attach->timlfs)
+		rvu_detach_block(rvu, pcifunc, BLKTYPE_TIM);
+
+fail5:
+	if (attach->ssow)
+		rvu_detach_block(rvu, pcifunc, BLKTYPE_SSOW);
+
+fail4:
+	if (attach->sso)
+		rvu_detach_block(rvu, pcifunc, BLKTYPE_SSO);
+
+fail3:
+	if (attach->nixlf)
+		rvu_detach_block(rvu, pcifunc, BLKTYPE_NIX);
+
+fail2:
+	if (attach->npalf)
+		rvu_detach_block(rvu, pcifunc, BLKTYPE_NPA);
+
+fail1:
 	mutex_unlock(&rvu->rsrc_lock);
 	return err;
 }
Signature · 1 line
2.51.0
author maintainer
#156 lore raw

PATCH 151/280 vsock/virtio: fix potential underflow in virtio_transport_get_credit()

In reply to Greg Kroah-Hartman

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

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

From: Melbin K Mathew <[email protected]>

[ Upstream commit 3ef3d52a1a9860d094395c7a3e593f3aa26ff012 ]

The credit calculation in virtio_transport_get_credit() uses unsigned arithmetic:

  ret = vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt);

If the peer shrinks its advertised buffer (peer_buf_alloc) while bytes are in flight, the subtraction can underflow and produce a large positive value, potentially allowing more data to be queued than the peer can handle.

Reuse virtio_transport_has_space() which already handles this case and add a comment to make it clear why we are doing that.

Fixes 06a8fc78367d ("VSOCK: Introduce virtio_vsock_common.ko")
[Stefano: use virtio_transport_has_space() instead of duplicating the code]
[Stefano: tweak the commit message]
---
 net/vmw_vsock/virtio_transport_common.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)
net/vmw_vsock/virtio_transport_common.c +9 -7
index a65da57fe26fd..76329191102a0 100644
@@ -28,6 +28,7 @@
 
 static void virtio_transport_cancel_close_work(struct vsock_sock *vsk,
 					       bool cancel_timeout);
+static s64 virtio_transport_has_space(struct virtio_vsock_sock *vvs);
 
 static const struct virtio_transport *
 virtio_transport_get_ops(struct vsock_sock *vsk)
@@ -284,9 +285,7 @@ u32 virtio_transport_get_credit(struct virtio_vsock_sock *vvs, u32 credit)
 	u32 ret;
 
 	spin_lock_bh(&vvs->tx_lock);
-	ret = vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt);
-	if (ret > credit)
-		ret = credit;
+	ret = min_t(u32, credit, virtio_transport_has_space(vvs));
 	vvs->tx_cnt += ret;
 	spin_unlock_bh(&vvs->tx_lock);
 
@@ -588,11 +587,14 @@ u32 virtio_transport_seqpacket_has_data(struct vsock_sock *vsk)
 }
 EXPORT_SYMBOL_GPL(virtio_transport_seqpacket_has_data);
 
-static s64 virtio_transport_has_space(struct vsock_sock *vsk)
+static s64 virtio_transport_has_space(struct virtio_vsock_sock *vvs)
 {
-	struct virtio_vsock_sock *vvs = vsk->trans;
 	s64 bytes;
 
+	/* Use s64 arithmetic so if the peer shrinks peer_buf_alloc while
+	 * we have bytes in flight (tx_cnt - peer_fwd_cnt), the subtraction
+	 * does not underflow.
+	 */
 	bytes = (s64)vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt);
 	if (bytes < 0)
 		bytes = 0;
@@ -606,7 +608,7 @@ s64 virtio_transport_stream_has_space(struct vsock_sock *vsk)
 	s64 bytes;
 
 	spin_lock_bh(&vvs->tx_lock);
-	bytes = virtio_transport_has_space(vsk);
+	bytes = virtio_transport_has_space(vvs);
 	spin_unlock_bh(&vvs->tx_lock);
 
 	return bytes;
@@ -1207,7 +1209,7 @@ static bool virtio_transport_space_update(struct sock *sk,
 	spin_lock_bh(&vvs->tx_lock);
 	vvs->peer_buf_alloc = le32_to_cpu(hdr->buf_alloc);
 	vvs->peer_fwd_cnt = le32_to_cpu(hdr->fwd_cnt);
-	space_available = virtio_transport_has_space(vsk);
+	space_available = virtio_transport_has_space(vvs);
 	spin_unlock_bh(&vvs->tx_lock);
 	return space_available;
 }
Signature · 1 line
2.51.0
author maintainer
#157 lore raw

PATCH 152/280 vsock/virtio: cap TX credit to local buffer size

In reply to Greg Kroah-Hartman

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

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

From: Melbin K Mathew <[email protected]>

[ Upstream commit 8ee784fdf006cbe8739cfa093f54d326cbf54037 ]

The virtio transports derives its TX credit directly from peer_buf_alloc, which is set from the remote endpoint's SO_VM_SOCKETS_BUFFER_SIZE value.

On the host side this means that the amount of data we are willing to queue for a connection is scaled by a guest-chosen buffer size, rather than the host's own vsock configuration. A malicious guest can advertise a large buffer and read slowly, causing the host to allocate a correspondingly large amount of sk_buff memory.
The same thing would happen in the guest with a malicious host, since virtio transports share the same code base.

Introduce a small helper, virtio_transport_tx_buf_size(), that returns min(peer_buf_alloc, buf_alloc), and use it wherever we consume peer_buf_alloc.

This ensures the effective TX window is bounded by both the peer's advertised buffer and our own buf_alloc (already clamped to buffer_max_size via SO_VM_SOCKETS_BUFFER_MAX_SIZE), so a remote peer cannot force the other to queue more data than allowed by its own vsock settings.

On an unpatched Ubuntu 22.04 host (~64 GiB RAM), running a PoC with 32 guest vsock connections advertising 2 GiB each and reading slowly drove Slab/SUnreclaim from ~0.5 GiB to ~57 GiB; the system only recovered after killing the QEMU process. That said, if QEMU memory is limited with cgroups, the maximum memory used will be limited.

With this patch applied:

Before:

    MemFree:        ~61.6 GiB
    Slab:           ~142 MiB
    SUnreclaim:     ~117 MiB

After 32 high-credit connections:

    MemFree:        ~61.5 GiB
    Slab:           ~178 MiB
    SUnreclaim:     ~152 MiB

Only ~35 MiB increase in Slab/SUnreclaim, no host OOM, and the guest remains responsive.

Compatibility with non-virtio transports:

- VMCI uses the AF_VSOCK buffer knobs to size its queue pairs per socket based on the local vsk->buffer_* values; the remote side cannot enlarge those queues beyond what the local endpoint configured.

- Hyper-V's vsock transport uses fixed-size VMBus ring buffers and an MTU bound; there is no peer-controlled credit field comparable to peer_buf_alloc, and the remote endpoint cannot drive in-flight kernel memory above those ring sizes.

- The loopback path reuses virtio_transport_common.c, so it naturally follows the same semantics as the virtio transport.

This change is limited to virtio_transport_common.c and thus affects virtio-vsock, vhost-vsock, and loopback, bringing them in line with the "remote window intersected with local policy" behaviour that VMCI and Hyper-V already effectively have.

Fixes 06a8fc78367d ("VSOCK: Introduce virtio_vsock_common.ko")
[Stefano: small adjustments after changing the previous patch]
[Stefano: tweak the commit message]
---
 net/vmw_vsock/virtio_transport_common.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
net/vmw_vsock/virtio_transport_common.c +12 -2
index 76329191102a0..bb44a95b43d5a 100644
@@ -532,6 +532,15 @@ virtio_transport_seqpacket_dequeue(struct vsock_sock *vsk,
 }
 EXPORT_SYMBOL_GPL(virtio_transport_seqpacket_dequeue);
 
+static u32 virtio_transport_tx_buf_size(struct virtio_vsock_sock *vvs)
+{
+	/* The peer advertises its receive buffer via peer_buf_alloc, but we
+	 * cap it to our local buf_alloc so a remote peer cannot force us to
+	 * queue more data than our own buffer configuration allows.
+	 */
+	return min(vvs->peer_buf_alloc, vvs->buf_alloc);
+}
+
 int
 virtio_transport_seqpacket_enqueue(struct vsock_sock *vsk,
 				   struct msghdr *msg,
@@ -541,7 +550,7 @@ virtio_transport_seqpacket_enqueue(struct vsock_sock *vsk,
 
 	spin_lock_bh(&vvs->tx_lock);
 
-	if (len > vvs->peer_buf_alloc) {
+	if (len > virtio_transport_tx_buf_size(vvs)) {
 		spin_unlock_bh(&vvs->tx_lock);
 		return -EMSGSIZE;
 	}
@@ -595,7 +604,8 @@ static s64 virtio_transport_has_space(struct virtio_vsock_sock *vvs)
 	 * we have bytes in flight (tx_cnt - peer_fwd_cnt), the subtraction
 	 * does not underflow.
 	 */
-	bytes = (s64)vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt);
+	bytes = (s64)virtio_transport_tx_buf_size(vvs) -
+		(vvs->tx_cnt - vvs->peer_fwd_cnt);
 	if (bytes < 0)
 		bytes = 0;
 
Signature · 1 line
2.51.0
author maintainer
#158 lore raw

PATCH 153/280 net/sched: act_ife: avoid possible NULL deref

In reply to Greg Kroah-Hartman

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit 27880b0b0d35ad1c98863d09788254e36f874968 ]

tcf_ife_encode() must make sure ife_encode() does not return NULL.

syzbot reported:

Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
 RIP: 0010:ife_tlv_meta_encode+0x41/0xa0 net/ife/ife.c:166
CPU: 3 UID: 0 PID: 8990 Comm: syz.0.696 Not tainted syzkaller #0 PREEMPT(full)
Call Trace:
 <TASK>
  ife_encode_meta_u32+0x153/0x180 net/sched/act_ife.c:101
  tcf_ife_encode net/sched/act_ife.c:841 [inline]
  tcf_ife_act+0x1022/0x1de0 net/sched/act_ife.c:877
  tc_act include/net/tc_wrapper.h:130 [inline]
  tcf_action_exec+0x1c0/0xa20 net/sched/act_api.c:1152
  tcf_exts_exec include/net/pkt_cls.h:349 [inline]
  mall_classify+0x1a0/0x2a0 net/sched/cls_matchall.c:42
  tc_classify include/net/tc_wrapper.h:197 [inline]
  __tcf_classify net/sched/cls_api.c:1764 [inline]
  tcf_classify+0x7f2/0x1380 net/sched/cls_api.c:1860
  multiq_classify net/sched/sch_multiq.c:39 [inline]
  multiq_enqueue+0xe0/0x510 net/sched/sch_multiq.c:66
  dev_qdisc_enqueue+0x45/0x250 net/core/dev.c:4147
  __dev_xmit_skb net/core/dev.c:4262 [inline]
  __dev_queue_xmit+0x2998/0x46c0 net/core/dev.c:4798
---
 net/sched/act_ife.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
net/sched/act_ife.c +4 -2
index a4505b926a1e4..2e2283ce2d886 100644
@@ -820,6 +820,7 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a,
 	/* could be stupid policy setup or mtu config
 	 * so lets be conservative.. */
 	if ((action == TC_ACT_SHOT) || exceed_mtu) {
+drop:
 		qstats_drop_inc(this_cpu_ptr(ife->common.cpu_qstats));
 		return TC_ACT_SHOT;
 	}
@@ -828,6 +829,8 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a,
 		skb_push(skb, skb->dev->hard_header_len);
 
 	ife_meta = ife_encode(skb, metalen);
+	if (!ife_meta)
+		goto drop;
 
 	spin_lock(&ife->tcf_lock);
 
@@ -843,8 +846,7 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a,
 		if (err < 0) {
 			/* too corrupt to keep around if overwritten */
 			spin_unlock(&ife->tcf_lock);
-			qstats_drop_inc(this_cpu_ptr(ife->common.cpu_qstats));
-			return TC_ACT_SHOT;
+			goto drop;
 		}
 		skboff += err;
 	}
Signature · 1 line
2.51.0
author maintainer
#159 lore raw

PATCH 154/280 x86: make page fault handling disable interrupts properly

In reply to Greg Kroah-Hartman

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

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

From: Cedric Xing <[email protected]>

[ Upstream commit 614da1d3d4cdbd6e41aea06bc97ec15aacff6daf ]

There's a big comment in the x86 do_page_fault() about our interrupt disabling code:

* User address page fault handling might have reenabled
* interrupts. Fixing up all potential exit points of
* do_user_addr_fault() and its leaf functions is just not
* doable w/o creating an unholy mess or turning the code
* upside down.

but it turns out that comment is subtly wrong, and the code as a result is also wrong.

Because it's certainly true that we may have re-enabled interrupts when handling user page faults. And it's most certainly true that we don't want to bother fixing up all the cases.

But what isn't true is that it's limited to user address page faults.

The confusion stems from the fact that we have logic here that depends on the address range of the access, but other code then depends on the _context_ the access was done in. The two are not related, even though both of them are about user-vs-kernel.

In other words, both user and kernel addresses can cause interrupts to have been enabled (eg when __bad_area_nosemaphore() gets called for user accesses to kernel addresses). As a result we should make sure to disable interrupts again regardless of the address range before returning to the low-level fault handling code.

The __bad_area_nosemaphore() code actually did disable interrupts again after enabling them, just not consistently. Ironically, as noted in the original comment, fixing up all the cases is just not worth it, when the simple solution is to just do it unconditionally in one single place.

So remove the incomplete case that unsuccessfully tried to do what the comment said was "not doable" in commit ca4c6a9858c2 ("x86/traps: Make interrupt enable/disable symmetric in C code"), and just make it do the simple and straightforward thing.

Fixes ca4c6a9858c2 ("x86/traps: Make interrupt enable/disable symmetric in C code")
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 arch/x86/mm/fault.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)
arch/x86/mm/fault.c +5 -10
index 2fc007752ceb1..54f8fe0ea5a93 100644
@@ -835,8 +835,6 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
 		force_sig_pkuerr((void __user *)address, pkey);
 	else
 		force_sig_fault(SIGSEGV, si_code, (void __user *)address);
-
-	local_irq_disable();
 }
 
 static noinline void
@@ -1429,15 +1427,12 @@ handle_page_fault(struct pt_regs *regs, unsigned long error_code,
 		do_kern_addr_fault(regs, error_code, address);
 	} else {
 		do_user_addr_fault(regs, error_code, address);
-		/*
-		 * User address page fault handling might have reenabled
-		 * interrupts. Fixing up all potential exit points of
-		 * do_user_addr_fault() and its leaf functions is just not
-		 * doable w/o creating an unholy mess or turning the code
-		 * upside down.
-		 */
-		local_irq_disable();
 	}
+	/*
+	 * page fault handling might have reenabled interrupts,
+	 * make sure to disable them again.
+	 */
+	local_irq_disable();
 }
 
 DEFINE_IDTENTRY_RAW_ERRORCODE(exc_page_fault)
Signature · 1 line
2.51.0
author maintainer
#160 lore raw

PATCH 155/280 leds: led-class: Only Add LED to leds_list when it is fully ready

In reply to Greg Kroah-Hartman

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

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

From: Hans de Goede <[email protected]>

commit d1883cefd31752f0504b94c3bcfa1f6d511d6e87 upstream.

Before this change the LED was added to leds_list before led_init_core() gets called adding it the list before led_classdev.set_brightness_work gets initialized.

This leaves a window where led_trigger_register() of a LED's default trigger will call led_trigger_set() which calls led_set_brightness() which in turn will end up queueing the *uninitialized* led_classdev.set_brightness_work.

This race gets hit by the lenovo-thinkpad-t14s EC driver which registers 2 LEDs with a default trigger provided by snd_ctl_led.ko in quick succession. The first led_classdev_register() causes an async modprobe of snd_ctl_led to run and that async modprobe manages to exactly hit the window where the second LED is on the leds_list without led_init_core() being called for it, resulting in:

 ------------[ cut here ]------------
 WARNING: CPU: 11 PID: 5608 at kernel/workqueue.c:4234 __flush_work+0x344/0x390
 Hardware name: LENOVO 21N2S01F0B/21N2S01F0B, BIOS N42ET93W (2.23 ) 09/01/2025
 ...
 Call trace:
  __flush_work+0x344/0x390 (P)
  flush_work+0x2c/0x50
  led_trigger_set+0x1c8/0x340
  led_trigger_register+0x17c/0x1c0
  led_trigger_register_simple+0x84/0xe8
  snd_ctl_led_init+0x40/0xf88 [snd_ctl_led]
  do_one_initcall+0x5c/0x318
  do_init_module+0x9c/0x2b8
  load_module+0x7e0/0x998

Close the race window by moving the adding of the LED to leds_list to after the led_init_core() call.

---
 drivers/leds/led-class.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/leds/led-class.c +5 -5
@@ -410,11 +410,6 @@ int led_classdev_register_ext(struct dev
 #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED
 	led_cdev->brightness_hw_changed = -1;
 #endif
-	/* add to the list of leds */
-	down_write(&leds_list_lock);
-	list_add_tail(&led_cdev->node, &leds_list);
-	up_write(&leds_list_lock);
-
 	if (!led_cdev->max_brightness)
 		led_cdev->max_brightness = LED_FULL;
 
@@ -422,6 +417,11 @@ int led_classdev_register_ext(struct dev
 
 	led_init_core(led_cdev);
 
+	/* add to the list of leds */
+	down_write(&leds_list_lock);
+	list_add_tail(&led_cdev->node, &leds_list);
+	up_write(&leds_list_lock);
+
 #ifdef CONFIG_LEDS_TRIGGERS
 	led_trigger_set_default(led_cdev);
 #endif
author maintainer
#161 lore raw

PATCH 156/280 of: fix reference count leak in of_alias_scan()

In reply to Greg Kroah-Hartman

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

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

From: Weigang He <[email protected]>

commit 81122fba08fa3ccafab6ed272a5c6f2203923a7e upstream.

of_find_node_by_path() returns a device_node with its refcount incremented. When kstrtoint() fails or dt_alloc() fails, the function continues to the next iteration without calling of_node_put(), causing a reference count leak.

Add of_node_put(np) before continue on both error paths to properly release the device_node reference.

---
 drivers/of/base.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/of/base.c +6 -2
@@ -1956,13 +1956,17 @@ void of_alias_scan(void * (*dt_alloc)(u6
 			end--;
 		len = end - start;
 
-		if (kstrtoint(end, 10, &id) < 0)
+		if (kstrtoint(end, 10, &id) < 0) {
+			of_node_put(np);
 			continue;
+		}
 
 		/* Allocate an alias_prop with enough space for the stem */
 		ap = dt_alloc(sizeof(*ap) + len + 1, __alignof__(*ap));
-		if (!ap)
+		if (!ap) {
+			of_node_put(np);
 			continue;
+		}
 		memset(ap, 0, sizeof(*ap) + len + 1);
 		ap->alias = start;
 		of_alias_add(ap, np, id, start, len);
author maintainer
#162 lore raw

PATCH 157/280 of: platform: Use default match table for /firmware

In reply to Greg Kroah-Hartman

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

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

From: Rob Herring (Arm) <[email protected]>

commit 48e6a9c4a20870e09f85ff1a3628275d6bce31c0 upstream.

Calling of_platform_populate() without a match table will only populate the immediate child nodes under /firmware. This is usually fine, but in the case of something like a "simple-mfd" node such as "raspberrypi,bcm2835-firmware", those child nodes will not be populated. And subsequent calls won't work either because the /firmware node is marked as processed already.

Switch the call to of_platform_default_populate() to solve this problem. It should be a nop for existing cases.

Fixes 3aa0582fdb82 ("of: platform: populate /firmware/ node from of_platform_default_populate_init()")
---
 drivers/of/platform.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/of/platform.c +1 -1
@@ -587,7 +587,7 @@ static int __init of_platform_default_po
 
 		node = of_find_node_by_path("/firmware");
 		if (node) {
-			of_platform_populate(node, NULL, NULL, NULL);
+			of_platform_default_populate(node, NULL, NULL);
 			of_node_put(node);
 		}
 
author maintainer
#163 lore raw

PATCH 158/280 iio: adc: ad9467: fix ad9434 vref mask

In reply to Greg Kroah-Hartman

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

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

From: Tomas Melin <[email protected]>

commit 92452b1760ff2d1d411414965d4d06f75e1bda9a upstream.

The mask setting is 5 bits wide for the ad9434
(ref. data sheet register 0x18 FLEX_VREF). Apparently the settings from ad9265 were copied by mistake when support for the device was added to the driver.

Fixes 4606d0f4b05f ("iio: adc: ad9467: add support for AD9434 high-speed ADC")
---
 drivers/iio/adc/ad9467.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/ad9467.c +1 -1
@@ -90,7 +90,7 @@
 
 #define CHIPID_AD9434			0x6A
 #define AD9434_DEF_OUTPUT_MODE		0x00
-#define AD9434_REG_VREF_MASK		0xC0
+#define AD9434_REG_VREF_MASK		GENMASK(4, 0)
 
 /*
  * Analog Devices AD9467 16-Bit, 200/250 MSPS ADC
author maintainer
#164 lore raw

PATCH 159/280 iio: adc: at91-sama5d2_adc: Fix potential use-after-free in sama5d2_adc driver

In reply to Greg Kroah-Hartman

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

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

From: Pei Xiao <[email protected]>

commit dbdb442218cd9d613adeab31a88ac973f22c4873 upstream.

at91_adc_interrupt can call at91_adc_touch_data_handler function to start the work by schedule_work(&st->touch_st.workq).

If we remove the module which will call at91_adc_remove to make cleanup, it will free indio_dev through iio_device_unregister but quite a bit later. While the work mentioned above will be used. The sequence of operations that may lead to a UAF bug is as follows:

CPU0 CPU1

                                     | at91_adc_workq_handler
at91_adc_remove                      |
iio_device_unregister(indio_dev)     |
//free indio_dev a bit later         |
                                     | iio_push_to_buffers(indio_dev)
                                     | //use indio_dev

Fix it by ensuring that the work is canceled before proceeding with the cleanup in at91_adc_remove.

Fixes 23ec2774f1cc ("iio: adc: at91-sama5d2_adc: add support for position and pressure channels")
---
 drivers/iio/adc/at91-sama5d2_adc.c |    1 +
 1 file changed, 1 insertion(+)
drivers/iio/adc/at91-sama5d2_adc.c +1 -0
@@ -2521,6 +2521,7 @@ static int at91_adc_remove(struct platfo
 	struct at91_adc_state *st = iio_priv(indio_dev);
 
 	iio_device_unregister(indio_dev);
+	cancel_work_sync(&st->touch_st.workq);
 
 	at91_adc_dma_disable(st);
 
author maintainer
#165 lore raw

PATCH 160/280 iio: dac: ad5686: add AD5695R to ad5686_chip_info_tbl

In reply to Greg Kroah-Hartman

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

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

From: Kübrich, Andreas <[email protected]>

commit 441ac29923c9172bc5e4b2c4f52ae756192f5715 upstream.

The chip info for this variant (I2C, four channels, 14 bit, internal reference) seems to have been left out due to oversight, so ad5686_chip_info_tbl[ID_AD5695R] is all zeroes. Initialisation of an AD5695R still succeeds, but the resulting IIO device has no channels and no /dev/iio:device* node.

Add the missing chip info to the table.

Fixes 4177381b4401 ("iio:dac:ad5686: Add AD5671R/75R/94/94R/95R/96/96R support")
---
 drivers/iio/dac/ad5686.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/iio/dac/ad5686.c +6 -0
@@ -427,6 +427,12 @@ static const struct ad5686_chip_info ad5
 		.num_channels = 4,
 		.regmap_type = AD5686_REGMAP,
 	},
+	[ID_AD5695R] = {
+		.channels = ad5685r_channels,
+		.int_vref_mv = 2500,
+		.num_channels = 4,
+		.regmap_type = AD5686_REGMAP,
+	},
 	[ID_AD5696] = {
 		.channels = ad5686_channels,
 		.num_channels = 4,
author maintainer
#166 lore raw

PATCH 161/280 ALSA: ctxfi: Fix potential OOB access in audio mixer handling

In reply to Greg Kroah-Hartman

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

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

From: Takashi Iwai <[email protected]>

commit 61006c540cbdedea83b05577dc7fb7fa18fe1276 upstream.

In the audio mixer handling code of ctxfi driver, the conf field is used as a kind of loop index, and it's referred in the index callbacks (amixer_index() and sum_index()).

As spotted recently by fuzzers, the current code causes OOB access at
those functions.
| UBSAN: array-index-out-of-bounds in /build/reproducible-path/linux-6.17.8/sound/pci/ctxfi/ctamixer.c:347:48 | index 8 is out of range for type 'unsigned char [8]'

After the analysis, the cause was found to be the lack of the proper (re-)initialization of conj field.

This patch addresses those OOB accesses by adding the proper initializations of the loop indices.

---
 sound/pci/ctxfi/ctamixer.c |    2 ++
 1 file changed, 2 insertions(+)
sound/pci/ctxfi/ctamixer.c +2 -0
@@ -205,6 +205,7 @@ static int amixer_rsc_init(struct amixer
 
 	/* Set amixer specific operations */
 	amixer->rsc.ops = &amixer_basic_rsc_ops;
+	amixer->rsc.conj = 0;
 	amixer->ops = &amixer_ops;
 	amixer->input = NULL;
 	amixer->sum = NULL;
@@ -369,6 +370,7 @@ static int sum_rsc_init(struct sum *sum,
 		return err;
 
 	sum->rsc.ops = &sum_basic_rsc_ops;
+	sum->rsc.conj = 0;
 
 	return 0;
 }
author maintainer
#167 lore raw

PATCH 162/280 ALSA: usb-audio: Fix use-after-free in snd_usb_mixer_free()

In reply to Greg Kroah-Hartman

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

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

From: Berk Cem Goksel <[email protected]>

commit 930e69757b74c3ae083b0c3c7419bfe7f0edc7b2 upstream.

When snd_usb_create_mixer() fails, snd_usb_mixer_free() frees mixer->id_elems but the controls already added to the card still reference the freed memory. Later when snd_card_register() runs, the OSS mixer layer calls their callbacks and hits a use-after-free read.

Call trace:
  get_ctl_value+0x63f/0x820 sound/usb/mixer.c:411
  get_min_max_with_quirks.isra.0+0x240/0x1f40 sound/usb/mixer.c:1241
  mixer_ctl_feature_info+0x26b/0x490 sound/usb/mixer.c:1381
  snd_mixer_oss_build_test+0x174/0x3a0 sound/core/oss/mixer_oss.c:887
  ...
  snd_card_register+0x4ed/0x6d0 sound/core/init.c:923
  usb_audio_probe+0x5ef/0x2a90 sound/usb/card.c:1025

Fix by calling snd_ctl_remove() for all mixer controls before freeing id_elems. We save the next pointer first because snd_ctl_remove() frees the current element.

Fixes 6639b6c2367f ("[ALSA] usb-audio - add mixer control notifications")
Cc Andrey Konovalov <[email protected]>
---
 sound/usb/mixer.c |   15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)
sound/usb/mixer.c +14 -1
@@ -2940,10 +2940,23 @@ static int parse_audio_unit(struct mixer
 
 static void snd_usb_mixer_free(struct usb_mixer_interface *mixer)
 {
+	struct usb_mixer_elem_list *list, *next;
+	int id;
+
 	/* kill pending URBs */
 	snd_usb_mixer_disconnect(mixer);
 
-	kfree(mixer->id_elems);
+	/* Unregister controls first, snd_ctl_remove() frees the element */
+	if (mixer->id_elems) {
+		for (id = 0; id < MAX_ID_ELEMS; id++) {
+			for (list = mixer->id_elems[id]; list; list = next) {
+				next = list->next_id_elem;
+				if (list->kctl)
+					snd_ctl_remove(mixer->chip->card, list->kctl);
+			}
+		}
+		kfree(mixer->id_elems);
+	}
 	if (mixer->urb) {
 		kfree(mixer->urb->transfer_buffer);
 		usb_free_urb(mixer->urb);
author maintainer
#168 lore raw

PATCH 163/280 mmc: rtsx_pci_sdmmc: implement sdmmc_card_busy function

In reply to Greg Kroah-Hartman

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

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

From: Matthew Schwartz <[email protected]>

commit 122610220134b32c742cc056eaf64f7017ac8cd9 upstream.

rtsx_pci_sdmmc does not have an sdmmc_card_busy function, so any voltage switches cause a kernel warning, "mmc0: cannot verify signal voltage switch."

Copy the sdmmc_card_busy function from rtsx_pci_usb to rtsx_pci_sdmmc to fix this.

Fixes ff984e57d36e ("mmc: Add realtek pcie sdmmc host driver")
---
 drivers/mmc/host/rtsx_pci_sdmmc.c |   41 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)
drivers/mmc/host/rtsx_pci_sdmmc.c +41 -0
@@ -1307,6 +1307,46 @@ out:
 	return err;
 }
 
+static int sdmmc_card_busy(struct mmc_host *mmc)
+{
+	struct realtek_pci_sdmmc *host = mmc_priv(mmc);
+	struct rtsx_pcr *pcr = host->pcr;
+	int err;
+	u8 stat;
+	u8 mask = SD_DAT3_STATUS | SD_DAT2_STATUS | SD_DAT1_STATUS
+	| SD_DAT0_STATUS;
+
+	mutex_lock(&pcr->pcr_mutex);
+
+	rtsx_pci_start_run(pcr);
+
+	err = rtsx_pci_write_register(pcr, SD_BUS_STAT,
+				      SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP,
+			       SD_CLK_TOGGLE_EN);
+	if (err)
+		goto out;
+
+	mdelay(1);
+
+	err = rtsx_pci_read_register(pcr, SD_BUS_STAT, &stat);
+	if (err)
+		goto out;
+
+	err = rtsx_pci_write_register(pcr, SD_BUS_STAT,
+				      SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
+out:
+	mutex_unlock(&pcr->pcr_mutex);
+
+	if (err)
+		return err;
+
+	/* check if any pin between dat[0:3] is low */
+	if ((stat & mask) != mask)
+		return 1;
+	else
+		return 0;
+}
+
 static int sdmmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
 {
 	struct realtek_pci_sdmmc *host = mmc_priv(mmc);
@@ -1405,6 +1445,7 @@ static const struct mmc_host_ops realtek
 	.get_ro = sdmmc_get_ro,
 	.get_cd = sdmmc_get_cd,
 	.start_signal_voltage_switch = sdmmc_switch_voltage,
+	.card_busy = sdmmc_card_busy,
 	.execute_tuning = sdmmc_execute_tuning,
 	.init_sd_express = sdmmc_init_sd_express,
 };
author maintainer
#169 lore raw

PATCH 164/280 wifi: ath10k: fix dma_free_coherent() pointer

In reply to Greg Kroah-Hartman

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

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

From: Thomas Fourier <[email protected]>

commit 9282a1e171ad8d2205067e8ec3bbe4e3cef4f29f upstream.

dma_alloc_coherent() allocates a DMA mapped buffer and stores the addresses in XXX_unaligned fields. Those should be reused when freeing the buffer rather than the aligned addresses.

---
 drivers/net/wireless/ath/ath10k/ce.c |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/net/wireless/ath/ath10k/ce.c +8 -8
@@ -1791,8 +1791,8 @@ static void _ath10k_ce_free_pipe(struct
 				  (ce_state->src_ring->nentries *
 				   sizeof(struct ce_desc) +
 				   CE_DESC_RING_ALIGN),
-				  ce_state->src_ring->base_addr_owner_space,
-				  ce_state->src_ring->base_addr_ce_space);
+				  ce_state->src_ring->base_addr_owner_space_unaligned,
+				  ce_state->src_ring->base_addr_ce_space_unaligned);
 		kfree(ce_state->src_ring);
 	}
 
@@ -1801,8 +1801,8 @@ static void _ath10k_ce_free_pipe(struct
 				  (ce_state->dest_ring->nentries *
 				   sizeof(struct ce_desc) +
 				   CE_DESC_RING_ALIGN),
-				  ce_state->dest_ring->base_addr_owner_space,
-				  ce_state->dest_ring->base_addr_ce_space);
+				  ce_state->dest_ring->base_addr_owner_space_unaligned,
+				  ce_state->dest_ring->base_addr_ce_space_unaligned);
 		kfree(ce_state->dest_ring);
 	}
 
@@ -1822,8 +1822,8 @@ static void _ath10k_ce_free_pipe_64(stru
 				  (ce_state->src_ring->nentries *
 				   sizeof(struct ce_desc_64) +
 				   CE_DESC_RING_ALIGN),
-				  ce_state->src_ring->base_addr_owner_space,
-				  ce_state->src_ring->base_addr_ce_space);
+				  ce_state->src_ring->base_addr_owner_space_unaligned,
+				  ce_state->src_ring->base_addr_ce_space_unaligned);
 		kfree(ce_state->src_ring);
 	}
 
@@ -1832,8 +1832,8 @@ static void _ath10k_ce_free_pipe_64(stru
 				  (ce_state->dest_ring->nentries *
 				   sizeof(struct ce_desc_64) +
 				   CE_DESC_RING_ALIGN),
-				  ce_state->dest_ring->base_addr_owner_space,
-				  ce_state->dest_ring->base_addr_ce_space);
+				  ce_state->dest_ring->base_addr_owner_space_unaligned,
+				  ce_state->dest_ring->base_addr_ce_space_unaligned);
 		kfree(ce_state->dest_ring);
 	}
 
author maintainer
#170 lore raw

PATCH 165/280 wifi: mwifiex: Fix a loop in mwifiex_update_ampdu_rxwinsize()

In reply to Greg Kroah-Hartman

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

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

From: Dan Carpenter <[email protected]>

commit 2120f3a3738a65730c81bf10447b1ff776078915 upstream.

The "i" iterator variable is used to count two different things but unfortunately we can't store two different numbers in the same variable. Use "i" for the outside loop and "j" for the inside loop.

Fixes d219b7eb3792 ("mwifiex: handle BT coex event to adjust Rx BA window size")
---
 drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c +3 -3
@@ -827,7 +827,7 @@ void mwifiex_update_rxreor_flags(struct
 static void mwifiex_update_ampdu_rxwinsize(struct mwifiex_adapter *adapter,
 					   bool coex_flag)
 {
-	u8 i;
+	u8 i, j;
 	u32 rx_win_size;
 	struct mwifiex_private *priv;
 
@@ -867,8 +867,8 @@ static void mwifiex_update_ampdu_rxwinsi
 		if (rx_win_size != priv->add_ba_param.rx_win_size) {
 			if (!priv->media_connected)
 				continue;
-			for (i = 0; i < MAX_NUM_TID; i++)
-				mwifiex_11n_delba(priv, i);
+			for (j = 0; j < MAX_NUM_TID; j++)
+				mwifiex_11n_delba(priv, j);
 		}
 	}
 }
author maintainer
#171 lore raw

PATCH 166/280 wifi: rsi: Fix memory corruption due to not set vif driver data size

In reply to Greg Kroah-Hartman

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

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

From: Marek Vasut <[email protected]>

commit 4f431d88ea8093afc7ba55edf4652978c5a68f33 upstream.

The struct ieee80211_vif contains trailing space for vif driver data, when struct ieee80211_vif is allocated, the total memory size that is allocated is sizeof(struct ieee80211_vif) + size of vif driver data. The size of vif driver data is set by each WiFi driver as needed.

The RSI911x driver does not set vif driver data size, no trailing space for vif driver data is therefore allocated past struct ieee80211_vif . The RSI911x driver does however use the vif driver data to store its vif driver data structure "struct vif_priv". An access to vif->drv_priv leads to access out of struct ieee80211_vif bounds and corruption of some memory.

In case of the failure observed locally, rsi_mac80211_add_interface() would write struct vif_priv *vif_info = (struct vif_priv *)vif->drv_priv; vif_info->vap_id = vap_idx. This write corrupts struct fq_tin member struct list_head new_flows . The flow = list_first_entry(head, struct fq_flow, flowchain); in fq_tin_reset() then reports non-NULL bogus address, which when accessed causes a crash.

The trigger is very simple, boot the machine with init=/bin/sh , mount devtmpfs, sysfs, procfs, and then do "ip link set wlan0 up", "sleep 1", "ip link set wlan0 down" and the crash occurs.

Fix this by setting the correct size of vif driver data, which is the size of "struct vif_priv", so that memory is allocated and the driver can store its driver data in it, instead of corrupting memory around it.

---
 drivers/net/wireless/rsi/rsi_91x_mac80211.c |    1 +
 1 file changed, 1 insertion(+)
drivers/net/wireless/rsi/rsi_91x_mac80211.c +1 -0
@@ -2022,6 +2022,7 @@ int rsi_mac80211_attach(struct rsi_commo
 
 	hw->queues = MAX_HW_QUEUES;
 	hw->extra_tx_headroom = RSI_NEEDED_HEADROOM;
+	hw->vif_data_size = sizeof(struct vif_priv);
 
 	hw->max_rates = 1;
 	hw->max_rate_tries = MAX_RETRIES;
author maintainer
#172 lore raw

PATCH 167/280 arm64/fpsimd: signal: Allocate SSVE storage when restoring ZA

In reply to Greg Kroah-Hartman

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

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

From: Mark Rutland <[email protected]>

commit ea8ccfddbce0bee6310da4f3fc560ad520f5e6b4 upstream.

The code to restore a ZA context doesn't attempt to allocate the task's sve_state before setting TIF_SME. Consequently, restoring a ZA context can place a task into an invalid state where TIF_SME is set but the task's sve_state is NULL.

In legitimate but uncommon cases where the ZA signal context was NOT created by the kernel in the context of the same task (e.g. if the task is saved/restored with something like CRIU), we have no guarantee that sve_state had been allocated previously. In these cases, userspace can enter streaming mode without trapping while sve_state is NULL, causing a later NULL pointer dereference when the kernel attempts to store the register state:

| # ./sigreturn-za
| Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
| Mem abort info:
|   ESR = 0x0000000096000046
|   EC = 0x25: DABT (current EL), IL = 32 bits
|   SET = 0, FnV = 0
|   EA = 0, S1PTW = 0
|   FSC = 0x06: level 2 translation fault
| Data abort info:
|   ISV = 0, ISS = 0x00000046, ISS2 = 0x00000000
|   CM = 0, WnR = 1, TnD = 0, TagAccess = 0
|   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
| user pgtable: 4k pages, 52-bit VAs, pgdp=0000000101f47c00
| [0000000000000000] pgd=08000001021d8403, p4d=0800000102274403, pud=0800000102275403, pmd=0000000000000000
| Internal error: Oops: 0000000096000046 [#1]  SMP
| Modules linked in:
| CPU: 0 UID: 0 PID: 153 Comm: sigreturn-za Not tainted 6.19.0-rc1 #1 PREEMPT
| Hardware name: linux,dummy-virt (DT)
| pstate: 214000c9 (nzCv daIF +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
| pc : sve_save_state+0x4/0xf0
| lr : fpsimd_save_user_state+0xb0/0x1c0
| sp : ffff80008070bcc0
| x29: ffff80008070bcc0 x28: fff00000c1ca4c40 x27: 63cfa172fb5cf658
| x26: fff00000c1ca5228 x25: 0000000000000000 x24: 0000000000000000
| x23: 0000000000000000 x22: fff00000c1ca4c40 x21: fff00000c1ca4c40
| x20: 0000000000000020 x19: fff00000ff6900f0 x18: 0000000000000000
| x17: fff05e8e0311f000 x16: 0000000000000000 x15: 028fca8f3bdaf21c
| x14: 0000000000000212 x13: fff00000c0209f10 x12: 0000000000000020
| x11: 0000000000200b20 x10: 0000000000000000 x9 : fff00000ff69dcc0
| x8 : 00000000000003f2 x7 : 0000000000000001 x6 : fff00000c1ca5b48
| x5 : fff05e8e0311f000 x4 : 0000000008000000 x3 : 0000000000000000
| x2 : 0000000000000001 x1 : fff00000c1ca5970 x0 : 0000000000000440
| Call trace:
|  sve_save_state+0x4/0xf0 (P)
|  fpsimd_thread_switch+0x48/0x198
|  __switch_to+0x20/0x1c0
|  __schedule+0x36c/0xce0
|  schedule+0x34/0x11c
|  exit_to_user_mode_loop+0x124/0x188
|  el0_interrupt+0xc8/0xd8
|  __el0_irq_handler_common+0x18/0x24
|  el0t_64_irq_handler+0x10/0x1c
|  el0t_64_irq+0x198/0x19c
| Code: 54000040 d51b4408 d65f03c0 d503245f (e5bb5800)
| ---[ end trace 0000000000000000 ]---

Fix this by having restore_za_context() ensure that the task's sve_state is allocated, matching what we do when taking an SME trap. Any live SVE/SSVE state (which is restored earlier from a separate signal context) must be preserved, and hence this is not zeroed.

Fixes 39782210eb7e ("arm64/sme: Implement ZA signal handling")
Cc Mark Brown <[email protected]>
Cc Will Deacon <[email protected]>
---
 arch/arm64/kernel/signal.c |    4 ++++
 1 file changed, 4 insertions(+)
arch/arm64/kernel/signal.c +4 -0
@@ -433,6 +433,10 @@ static int restore_za_context(struct use
 	fpsimd_flush_task_state(current);
 	/* From now, fpsimd_thread_switch() won't touch thread.sve_state */
 
+	sve_alloc(current, false);
+	if (!current->thread.sve_state)
+		return -ENOMEM;
+
 	sme_alloc(current, true);
 	if (!current->thread.za_state) {
 		current->thread.svcr &= ~SVCR_ZA_MASK;
author maintainer
#173 lore raw

PATCH 168/280 arm64: Set __nocfi on swsusp_arch_resume()

In reply to Greg Kroah-Hartman

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

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

From: Zhaoyang Huang <[email protected]>

commit e2f8216ca2d8e61a23cb6ec355616339667e0ba6 upstream.

A DABT is reported[1] on an android based system when resume from hiberate. This happens because swsusp_arch_suspend_exit() is marked with SYM_CODE_*() and does not have a CFI hash, but swsusp_arch_resume() will attempt to verify the CFI hash when calling a copy of swsusp_arch_suspend_exit().

Given that there's an existing requirement that the entrypoint to swsusp_arch_suspend_exit() is the first byte of the .hibernate_exit.text section, we cannot fix this by marking swsusp_arch_suspend_exit() with SYM_FUNC_*(). The simplest fix for now is to disable the CFI check in swsusp_arch_resume().

Mark swsusp_arch_resume() as __nocfi to disable the CFI check.

[1]

[   22.991934][    T1] Unable to handle kernel paging request at virtual address 0000000109170ffc
[   22.991934][    T1] Mem abort info:
[   22.991934][    T1]   ESR = 0x0000000096000007
[   22.991934][    T1]   EC = 0x25: DABT (current EL), IL = 32 bits
[   22.991934][    T1]   SET = 0, FnV = 0
[   22.991934][    T1]   EA = 0, S1PTW = 0
[   22.991934][    T1]   FSC = 0x07: level 3 translation fault
[   22.991934][    T1] Data abort info:
[   22.991934][    T1]   ISV = 0, ISS = 0x00000007, ISS2 = 0x00000000
[   22.991934][    T1]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[   22.991934][    T1]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[   22.991934][    T1] [0000000109170ffc] user address but active_mm is swapper
[   22.991934][    T1] Internal error: Oops: 0000000096000007 [#1] PREEMPT SMP
[   22.991934][    T1] Dumping ftrace buffer:
[   22.991934][    T1]    (ftrace buffer empty)
[   22.991934][    T1] Modules linked in:
[   22.991934][    T1] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.6.98-android15-8-g0b1d2aee7fc3-dirty-4k #1 688c7060a825a3ac418fe53881730b355915a419
[   22.991934][    T1] Hardware name: Unisoc UMS9360-base Board (DT)
[   22.991934][    T1] pstate: 804000c5 (Nzcv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[   22.991934][    T1] pc : swsusp_arch_resume+0x2ac/0x344
[   22.991934][    T1] lr : swsusp_arch_resume+0x294/0x344
[   22.991934][    T1] sp : ffffffc08006b960
[   22.991934][    T1] x29: ffffffc08006b9c0 x28: 0000000000000000 x27: 0000000000000000
[   22.991934][    T1] x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000820
[   22.991934][    T1] x23: ffffffd0817e3000 x22: ffffffd0817e3000 x21: 0000000000000000
[   22.991934][    T1] x20: ffffff8089171000 x19: ffffffd08252c8c8 x18: ffffffc080061058
[   22.991934][    T1] x17: 00000000529c6ef0 x16: 00000000529c6ef0 x15: 0000000000000004
[   22.991934][    T1] x14: ffffff8178c88000 x13: 0000000000000006 x12: 0000000000000000
[   22.991934][    T1] x11: 0000000000000015 x10: 0000000000000001 x9 : ffffffd082533000
[   22.991934][    T1] x8 : 0000000109171000 x7 : 205b5d3433393139 x6 : 392e32322020205b
[   22.991934][    T1] x5 : 000000010916f000 x4 : 000000008164b000 x3 : ffffff808a4e0530
[   22.991934][    T1] x2 : ffffffd08058e784 x1 : 0000000082326000 x0 : 000000010a283000
[   22.991934][    T1] Call trace:
[   22.991934][    T1]  swsusp_arch_resume+0x2ac/0x344
[   22.991934][    T1]  hibernation_restore+0x158/0x18c
[   22.991934][    T1]  load_image_and_restore+0xb0/0xec
[   22.991934][    T1]  software_resume+0xf4/0x19c
[   22.991934][    T1]  software_resume_initcall+0x34/0x78
[   22.991934][    T1]  do_one_initcall+0xe8/0x370
[   22.991934][    T1]  do_initcall_level+0xc8/0x19c
[   22.991934][    T1]  do_initcalls+0x70/0xc0
[   22.991934][    T1]  do_basic_setup+0x1c/0x28
[   22.991934][    T1]  kernel_init_freeable+0xe0/0x148
[   22.991934][    T1]  kernel_init+0x20/0x1a8
[   22.991934][    T1]  ret_from_fork+0x10/0x20
[   22.991934][    T1] Code: a9400a61 f94013e0 f9438923 f9400a64 (b85fc110)
---
 arch/arm64/kernel/hibernate.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/kernel/hibernate.c +1 -1
@@ -397,7 +397,7 @@ int swsusp_arch_suspend(void)
  * Memory allocated by get_safe_page() will be dealt with by the hibernate code,
  * we don't need to free it here.
  */
-int swsusp_arch_resume(void)
+int __nocfi swsusp_arch_resume(void)
 {
 	int rc;
 	void *zero_page;
author maintainer
#174 lore raw

PATCH 169/280 octeontx2: Fix otx2_dma_map_page() error return code

In reply to Greg Kroah-Hartman

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

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

From: Thomas Fourier <[email protected]>

commit d998b0e5afffa90d0f03770bad31083767079858 upstream.

0 is a valid DMA address [1] so using it as the error value can lead to errors. The error value of dma_map_XXX() functions is DMA_MAPPING_ERROR which is ~0. The callers of otx2_dma_map_page() use dma_mapping_error() to test the return value of otx2_dma_map_page(). This means that they would not detect an error in otx2_dma_map_page().

Make otx2_dma_map_page() return the raw value of dma_map_page_attrs().

[1] https://lore.kernel.org/all/[email protected]

---
 drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h |    7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h +1 -6
@@ -864,13 +864,8 @@ static inline dma_addr_t otx2_dma_map_pa
 					   size_t offset, size_t size,
 					   enum dma_data_direction dir)
 {
-	dma_addr_t iova;
-
-	iova = dma_map_page_attrs(pfvf->dev, page,
+	return dma_map_page_attrs(pfvf->dev, page,
 				  offset, size, dir, DMA_ATTR_SKIP_CPU_SYNC);
-	if (unlikely(dma_mapping_error(pfvf->dev, iova)))
-		return (dma_addr_t)NULL;
-	return iova;
 }
 
 static inline void otx2_dma_unmap_page(struct otx2_nic *pfvf,
author maintainer
#175 lore raw

PATCH 170/280 slimbus: core: fix runtime PM imbalance on report present

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit 0eb4ff6596114aabba1070a66afa2c2f5593739f upstream.

Make sure to balance the runtime PM usage count in case slimbus device or address allocation fails on report present, which would otherwise prevent the controller from suspending.

Fixes 4b14e62ad3c9 ("slimbus: Add support for 'clock-pause' feature")
---
 drivers/slimbus/core.c |   16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)
drivers/slimbus/core.c +9 -7
@@ -496,21 +496,23 @@ int slim_device_report_present(struct sl
 	if (ctrl->sched.clk_state != SLIM_CLK_ACTIVE) {
 		dev_err(ctrl->dev, "slim ctrl not active,state:%d, ret:%d\n",
 				    ctrl->sched.clk_state, ret);
-		goto slimbus_not_active;
+		goto out_put_rpm;
 	}
 
 	sbdev = slim_get_device(ctrl, e_addr);
-	if (IS_ERR(sbdev))
-		return -ENODEV;
+	if (IS_ERR(sbdev)) {
+		ret = -ENODEV;
+		goto out_put_rpm;
+	}
 
 	if (sbdev->is_laddr_valid) {
 		*laddr = sbdev->laddr;
-		return 0;
+		ret = 0;
+	} else {
+		ret = slim_device_alloc_laddr(sbdev, true);
 	}
 
-	ret = slim_device_alloc_laddr(sbdev, true);
-
-slimbus_not_active:
+out_put_rpm:
 	pm_runtime_mark_last_busy(ctrl->dev);
 	pm_runtime_put_autosuspend(ctrl->dev);
 	return ret;
author maintainer
#176 lore raw

PATCH 171/280 slimbus: core: fix device reference leak on report present

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit 9391380eb91ea5ac792aae9273535c8da5b9aa01 upstream.

Slimbus devices can be allocated dynamically upon reception of report-present messages.

Make sure to drop the reference taken when looking up already registered devices.

Note that this requires taking an extra reference in case the device has not yet been registered and has to be allocated.

Fixes 46a2bb5a7f7e ("slimbus: core: Add slim controllers support")
---
 drivers/slimbus/core.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/slimbus/core.c +3 -0
@@ -378,6 +378,8 @@ struct slim_device *slim_get_device(stru
 		sbdev = slim_alloc_device(ctrl, e_addr, NULL);
 		if (!sbdev)
 			return ERR_PTR(-ENOMEM);
+
+		get_device(&sbdev->dev);
 	}
 
 	return sbdev;
@@ -512,6 +514,7 @@ int slim_device_report_present(struct sl
 		ret = slim_device_alloc_laddr(sbdev, true);
 	}
 
+	put_device(&sbdev->dev);
 out_put_rpm:
 	pm_runtime_mark_last_busy(ctrl->dev);
 	pm_runtime_put_autosuspend(ctrl->dev);
author maintainer
#177 lore raw

PATCH 172/280 intel_th: fix device leak on output open()

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit 95fc36a234da24bbc5f476f8104a5a15f99ed3e3 upstream.

Make sure to drop the reference taken when looking up the th device during output device open() on errors and on close().

Note that a recent commit fixed the leak in a couple of open() error paths but not all of them, and the reference is still leaking on successful open().

Fixes 39f4034693b7 ("intel_th: Add driver infrastructure for Intel(R) Trace Hub devices")
Fixes 6d5925b667e4 ("intel_th: Fix error handling in intel_th_output_open")
Cc [email protected] # 4.4: 6d5925b667e4
Cc Alexander Shishkin <[email protected]>
---
 drivers/hwtracing/intel_th/core.c |   19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)
drivers/hwtracing/intel_th/core.c +16 -3
@@ -810,9 +810,12 @@ static int intel_th_output_open(struct i
 	int err;
 
 	dev = bus_find_device_by_devt(&intel_th_bus, inode->i_rdev);
-	if (!dev || !dev->driver) {
+	if (!dev)
+		return -ENODEV;
+
+	if (!dev->driver) {
 		err = -ENODEV;
-		goto out_no_device;
+		goto out_put_device;
 	}
 
 	thdrv = to_intel_th_driver(dev->driver);
@@ -836,12 +839,22 @@ static int intel_th_output_open(struct i
 
 out_put_device:
 	put_device(dev);
-out_no_device:
+
 	return err;
 }
 
+static int intel_th_output_release(struct inode *inode, struct file *file)
+{
+	struct intel_th_device *thdev = file->private_data;
+
+	put_device(&thdev->dev);
+
+	return 0;
+}
+
 static const struct file_operations intel_th_output_fops = {
 	.open	= intel_th_output_open,
+	.release = intel_th_output_release,
 	.llseek	= noop_llseek,
 };
 
author maintainer
#178 lore raw

PATCH 173/280 uacce: fix cdev handling in the cleanup path

In reply to Greg Kroah-Hartman

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

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

From: Wenkai Lin <[email protected]>

commit a3bece3678f6c88db1f44c602b2a63e84b4040ac upstream.

When cdev_device_add fails, it internally releases the cdev memory, and if cdev_device_del is then executed, it will cause a hang error. To fix it, we check the return value of cdev_device_add() and clear uacce->cdev to avoid calling cdev_device_del in the uacce_remove.

---
 drivers/misc/uacce/uacce.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/misc/uacce/uacce.c +7 -1
@@ -500,6 +500,8 @@ EXPORT_SYMBOL_GPL(uacce_alloc);
  */
 int uacce_register(struct uacce_device *uacce)
 {
+	int ret;
+
 	if (!uacce)
 		return -ENODEV;
 
@@ -510,7 +512,11 @@ int uacce_register(struct uacce_device *
 	uacce->cdev->ops = &uacce_fops;
 	uacce->cdev->owner = THIS_MODULE;
 
-	return cdev_device_add(uacce->cdev, &uacce->dev);
+	ret = cdev_device_add(uacce->cdev, &uacce->dev);
+	if (ret)
+		uacce->cdev = NULL;
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(uacce_register);
 
author maintainer
#179 lore raw

PATCH 174/280 uacce: implement mremap in uacce_vm_ops to return -EPERM

In reply to Greg Kroah-Hartman

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

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

From: Yang Shen <[email protected]>

commit 02695347be532b628f22488300d40c4eba48b9b7 upstream.

The current uacce_vm_ops does not support the mremap operation of vm_operations_struct. Implement .mremap to return -EPERM to remind users.

The reason we need to explicitly disable mremap is that when the driver does not implement .mremap, it uses the default mremap method. This could lead to a risk scenario:

An application might first mmap address p1, then mremap to p2, followed by munmap(p1), and finally munmap(p2). Since the default mremap copies the original vma's vm_private_data (i.e., q) to the new vma, both munmap operations would trigger vma_close, causing q->qfr to be freed twice(qfr will be set to null here, so repeated release is ok).

---
 drivers/misc/uacce/uacce.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/misc/uacce/uacce.c +6 -0
@@ -208,8 +208,14 @@ static void uacce_vma_close(struct vm_ar
 	kfree(qfr);
 }
 
+static int uacce_vma_mremap(struct vm_area_struct *area)
+{
+	return -EPERM;
+}
+
 static const struct vm_operations_struct uacce_vm_ops = {
 	.close = uacce_vma_close,
+	.mremap = uacce_vma_mremap,
 };
 
 static int uacce_fops_mmap(struct file *filep, struct vm_area_struct *vma)
author maintainer
#180 lore raw

PATCH 175/280 uacce: ensure safe queue release with state management

In reply to Greg Kroah-Hartman

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

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

From: Chenghai Huang <[email protected]>

commit 26c08dabe5475d99a13f353d8dd70e518de45663 upstream.

Directly calling put_queue carries risks since it cannot guarantee that resources of uacce_queue have been fully released beforehand. So adding a stop_queue operation for the UACCE_CMD_PUT_Q command and leaving the put_queue operation to the final resource release ensures safety.

Queue states are defined as follows:
- UACCE_Q_ZOMBIE: Initial state
- UACCE_Q_INIT: After opening uacce
- UACCE_Q_STARTED: After start is issued via ioctl

When executing poweroff -f in virt while accelerator are still working, uacce_fops_release and uacce_remove may execute concurrently. This can cause uacce_put_queue within uacce_fops_release to access a NULL ops pointer. Therefore, add state checks to prevent accessing freed pointers.

---
 drivers/misc/uacce/uacce.c |   28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)
drivers/misc/uacce/uacce.c +21 -7
@@ -37,20 +37,34 @@ static int uacce_start_queue(struct uacc
 	return 0;
 }
 
-static int uacce_put_queue(struct uacce_queue *q)
+static int uacce_stop_queue(struct uacce_queue *q)
 {
 	struct uacce_device *uacce = q->uacce;
 
-	if ((q->state == UACCE_Q_STARTED) && uacce->ops->stop_queue)
+	if (q->state != UACCE_Q_STARTED)
+		return 0;
+
+	if (uacce->ops->stop_queue)
 		uacce->ops->stop_queue(q);
 
-	if ((q->state == UACCE_Q_INIT || q->state == UACCE_Q_STARTED) &&
-	     uacce->ops->put_queue)
+	q->state = UACCE_Q_INIT;
+
+	return 0;
+}
+
+static void uacce_put_queue(struct uacce_queue *q)
+{
+	struct uacce_device *uacce = q->uacce;
+
+	uacce_stop_queue(q);
+
+	if (q->state != UACCE_Q_INIT)
+		return;
+
+	if (uacce->ops->put_queue)
 		uacce->ops->put_queue(q);
 
 	q->state = UACCE_Q_ZOMBIE;
-
-	return 0;
 }
 
 static long uacce_fops_unl_ioctl(struct file *filep,
@@ -77,7 +91,7 @@ static long uacce_fops_unl_ioctl(struct
 		ret = uacce_start_queue(q);
 		break;
 	case UACCE_CMD_PUT_Q:
-		ret = uacce_put_queue(q);
+		ret = uacce_stop_queue(q);
 		break;
 	default:
 		if (uacce->ops->ioctl)
author maintainer
#181 lore raw

PATCH 176/280 netrom: fix double-free in nr_route_frame()

In reply to Greg Kroah-Hartman

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

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

From: Jeongjun Park <[email protected]>

commit ba1096c315283ee3292765f6aea4cca15816c4f7 upstream.

In nr_route_frame(), old_skb is immediately freed without checking if nr_neigh->ax25 pointer is NULL. Therefore, if nr_neigh->ax25 is NULL, the caller function will free old_skb again, causing a double-free bug.

Therefore, to prevent this, we need to modify it to check whether nr_neigh->ax25 is NULL before freeing old_skb.

---
 net/netrom/nr_route.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)
net/netrom/nr_route.c +9 -4
@@ -752,7 +752,7 @@ int nr_route_frame(struct sk_buff *skb,
 	unsigned char *dptr;
 	ax25_cb *ax25s;
 	int ret;
-	struct sk_buff *skbn;
+	struct sk_buff *nskb, *oskb;
 
 	/*
 	 * Reject malformed packets early. Check that it contains at least 2
@@ -811,14 +811,16 @@ int nr_route_frame(struct sk_buff *skb,
 	/* We are going to change the netrom headers so we should get our
 	   own skb, we also did not know until now how much header space
 	   we had to reserve... - RXQ */
-	if ((skbn=skb_copy_expand(skb, dev->hard_header_len, 0, GFP_ATOMIC)) == NULL) {
+	nskb = skb_copy_expand(skb, dev->hard_header_len, 0, GFP_ATOMIC);
+
+	if (!nskb) {
 		nr_node_unlock(nr_node);
 		nr_node_put(nr_node);
 		dev_put(dev);
 		return 0;
 	}
-	kfree_skb(skb);
-	skb=skbn;
+	oskb = skb;
+	skb = nskb;
 	skb->data[14]--;
 
 	dptr  = skb_push(skb, 1);
@@ -837,6 +839,9 @@ int nr_route_frame(struct sk_buff *skb,
 	nr_node_unlock(nr_node);
 	nr_node_put(nr_node);
 
+	if (ret)
+		kfree_skb(oskb);
+
 	return ret;
 }
 
author maintainer
#182 lore raw

PATCH 177/280 perf/x86/intel: Do not enable BTS for guests

In reply to Greg Kroah-Hartman

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

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

From: Fernand Sieber <[email protected]>

commit 91dcfae0ff2b9b9ab03c1ec95babaceefbffb9f4 upstream.

By default when users program perf to sample branch instructions (PERF_COUNT_HW_BRANCH_INSTRUCTIONS) with a sample period of 1, perf interprets this as a special case and enables BTS (Branch Trace Store) as an optimization to avoid taking an interrupt on every branch.

Since BTS doesn't virtualize, this optimization doesn't make sense when the request originates from a guest. Add an additional check that prevents this optimization for virtualized events (exclude_host).

---
 arch/x86/events/perf_event.h |   13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)
arch/x86/events/perf_event.h +11 -2
@@ -1421,13 +1421,22 @@ static inline bool intel_pmu_has_bts_per
 	struct hw_perf_event *hwc = &event->hw;
 	unsigned int hw_event, bts_event;
 
-	if (event->attr.freq)
+	/*
+	 * Only use BTS for fixed rate period==1 events.
+	 */
+	if (event->attr.freq || period != 1)
+		return false;
+
+	/*
+	 * BTS doesn't virtualize.
+	 */
+	if (event->attr.exclude_host)
 		return false;
 
 	hw_event = hwc->config & INTEL_ARCH_EVENT_MASK;
 	bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
 
-	return hw_event == bts_event && period == 1;
+	return hw_event == bts_event;
 }
 
 static inline bool intel_pmu_has_bts(struct perf_event *event)
author maintainer
#183 lore raw

PATCH 178/280 irqchip/gic-v3-its: Avoid truncating memory addresses

In reply to Greg Kroah-Hartman

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

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

From: Arnd Bergmann <[email protected]>

commit 8d76a7d89c12d08382b66e2f21f20d0627d14859 upstream.

On 32-bit machines with CONFIG_ARM_LPAE, it is possible for lowmem allocations to be backed by addresses physical memory above the 32-bit address limit, as found while experimenting with larger VMSPLIT configurations.

This caused the qemu virt model to crash in the GICv3 driver, which allocates the 'itt' object using GFP_KERNEL. Since all memory below the 4GB physical address limit is in ZONE_DMA in this configuration, kmalloc() defaults to higher addresses for ZONE_NORMAL, and the ITS driver stores the physical address in a 32-bit 'unsigned long' variable.

Change the itt_addr variable to the correct phys_addr_t type instead, along with all other variables in this driver that hold a physical address.

The gicv5 driver correctly uses u64 variables, while all other irqchip drivers don't call virt_to_phys or similar interfaces. It's expected that other device drivers have similar issues, but fixing this one is sufficient for booting a virtio based guest.

---
 drivers/irqchip/irq-gic-v3-its.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/irqchip/irq-gic-v3-its.c +4 -4
@@ -613,7 +613,7 @@ static struct its_collection *its_build_
 						 struct its_cmd_block *cmd,
 						 struct its_cmd_desc *desc)
 {
-	unsigned long itt_addr;
+	phys_addr_t itt_addr;
 	u8 size = ilog2(desc->its_mapd_cmd.dev->nr_ites);
 
 	itt_addr = virt_to_phys(desc->its_mapd_cmd.dev->itt);
@@ -784,7 +784,7 @@ static struct its_vpe *its_build_vmapp_c
 					   struct its_cmd_desc *desc)
 {
 	struct its_vpe *vpe = valid_vpe(its, desc->its_vmapp_cmd.vpe);
-	unsigned long vpt_addr, vconf_addr;
+	phys_addr_t vpt_addr, vconf_addr;
 	u64 target;
 	bool alloc;
 
@@ -2399,10 +2399,10 @@ retry_baser:
 	baser->psz = psz;
 	tmp = indirect ? GITS_LVL1_ENTRY_SIZE : esz;
 
-	pr_info("ITS@%pa: allocated %d %s @%lx (%s, esz %d, psz %dK, shr %d)\n",
+	pr_info("ITS@%pa: allocated %d %s @%llx (%s, esz %d, psz %dK, shr %d)\n",
 		&its->phys_base, (int)(PAGE_ORDER_TO_SIZE(order) / (int)tmp),
 		its_base_type_string[type],
-		(unsigned long)virt_to_phys(base),
+		(u64)virt_to_phys(base),
 		indirect ? "indirect" : "flat", (int)esz,
 		psz / SZ_1K, (int)shr >> GITS_BASER_SHAREABILITY_SHIFT);
 
author maintainer
#184 lore raw

PATCH 179/280 can: ems_usb: ems_usb_read_bulk_callback(): fix URB memory leak

In reply to Greg Kroah-Hartman

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

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

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

commit 0ce73a0eb5a27070957b67fd74059b6da89cc516 upstream.

Fix similar memory leak as in commit 7352e1d5932a ("can: gs_usb:
gs_usb_receive_bulk_callback(): fix URB memory leak").

In ems_usb_open(), the URBs for USB-in transfers are allocated, added to the dev->rx_submitted anchor and submitted. In the complete callback ems_usb_read_bulk_callback(), the URBs are processed and resubmitted. In ems_usb_close() the URBs are freed by calling usb_kill_anchored_urbs(&dev->rx_submitted).

However, this does not take into account that the USB framework unanchors the URB before the complete function is called. This means that once an in-URB has been completed, it is no longer anchored and is ultimately not released in ems_usb_close().

Fix the memory leak by anchoring the URB in the ems_usb_read_bulk_callback() to the dev->rx_submitted anchor.

---
 drivers/net/can/usb/ems_usb.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/net/can/usb/ems_usb.c +7 -1
@@ -486,11 +486,17 @@ resubmit_urb:
 			  urb->transfer_buffer, RX_BUFFER_SIZE,
 			  ems_usb_read_bulk_callback, dev);
 
+	usb_anchor_urb(urb, &dev->rx_submitted);
+
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
+	if (!retval)
+		return;
+
+	usb_unanchor_urb(urb);
 
 	if (retval == -ENODEV)
 		netif_device_detach(netdev);
-	else if (retval)
+	else
 		netdev_err(netdev,
 			   "failed resubmitting read bulk urb: %d\n", retval);
 }
author maintainer
#185 lore raw

PATCH 180/280 can: kvaser_usb: kvaser_usb_read_bulk_callback(): fix URB memory leak

In reply to Greg Kroah-Hartman

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

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

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

commit 248e8e1a125fa875158df521b30f2cc7e27eeeaa upstream.

Fix similar memory leak as in commit 7352e1d5932a ("can: gs_usb:
gs_usb_receive_bulk_callback(): fix URB memory leak").

In kvaser_usb_set_{,data_}bittiming() -> kvaser_usb_setup_rx_urbs(), the URBs for USB-in transfers are allocated, added to the dev->rx_submitted anchor and submitted. In the complete callback kvaser_usb_read_bulk_callback(), the URBs are processed and resubmitted. In kvaser_usb_remove_interfaces() the URBs are freed by calling usb_kill_anchored_urbs(&dev->rx_submitted).

However, this does not take into account that the USB framework unanchors the URB before the complete function is called. This means that once an in-URB has been completed, it is no longer anchored and is ultimately not released in usb_kill_anchored_urbs().

Fix the memory leak by anchoring the URB in the kvaser_usb_read_bulk_callback() to the dev->rx_submitted anchor.

---
 drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +8 -1
@@ -349,7 +349,14 @@ resubmit_urb:
 			  urb->transfer_buffer, KVASER_USB_RX_BUFFER_SIZE,
 			  kvaser_usb_read_bulk_callback, dev);
 
+	usb_anchor_urb(urb, &dev->rx_submitted);
+
 	err = usb_submit_urb(urb, GFP_ATOMIC);
+	if (!err)
+		return;
+
+	usb_unanchor_urb(urb);
+
 	if (err == -ENODEV) {
 		for (i = 0; i < dev->nchannels; i++) {
 			if (!dev->nets[i])
@@ -357,7 +364,7 @@ resubmit_urb:
 
 			netif_device_detach(dev->nets[i]->netdev);
 		}
-	} else if (err) {
+	} else {
 		dev_err(&dev->intf->dev,
 			"Failed resubmitting read bulk urb: %d\n", err);
 	}
author maintainer
#186 lore raw

PATCH 181/280 can: mcba_usb: mcba_usb_read_bulk_callback(): fix URB memory leak

In reply to Greg Kroah-Hartman

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

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

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

commit 710a7529fb13c5a470258ff5508ed3c498d54729 upstream.

Fix similar memory leak as in commit 7352e1d5932a ("can: gs_usb:
gs_usb_receive_bulk_callback(): fix URB memory leak").

In mcba_usb_probe() -> mcba_usb_start(), the URBs for USB-in transfers are allocated, added to the priv->rx_submitted anchor and submitted. In the complete callback mcba_usb_read_bulk_callback(), the URBs are processed and resubmitted. In mcba_usb_close() -> mcba_urb_unlink() the URBs are freed by calling usb_kill_anchored_urbs(&priv->rx_submitted).

However, this does not take into account that the USB framework unanchors the URB before the complete function is called. This means that once an in-URB has been completed, it is no longer anchored and is ultimately not released in usb_kill_anchored_urbs().

Fix the memory leak by anchoring the URB in the mcba_usb_read_bulk_callback()to the priv->rx_submitted anchor.

---
 drivers/net/can/usb/mcba_usb.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/net/can/usb/mcba_usb.c +7 -1
@@ -608,11 +608,17 @@ resubmit_urb:
 			  urb->transfer_buffer, MCBA_USB_RX_BUFF_SIZE,
 			  mcba_usb_read_bulk_callback, priv);
 
+	usb_anchor_urb(urb, &priv->rx_submitted);
+
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
+	if (!retval)
+		return;
+
+	usb_unanchor_urb(urb);
 
 	if (retval == -ENODEV)
 		netif_device_detach(netdev);
-	else if (retval)
+	else
 		netdev_err(netdev, "failed resubmitting read bulk urb: %d\n",
 			   retval);
 }
author maintainer
#187 lore raw

PATCH 182/280 can: usb_8dev: usb_8dev_read_bulk_callback(): fix URB memory leak

In reply to Greg Kroah-Hartman

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

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

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

commit f7a980b3b8f80fe367f679da376cf76e800f9480 upstream.

Fix similar memory leak as in commit 7352e1d5932a ("can: gs_usb:
gs_usb_receive_bulk_callback(): fix URB memory leak").

In usb_8dev_open() -> usb_8dev_start(), the URBs for USB-in transfers are allocated, added to the priv->rx_submitted anchor and submitted. In the complete callback usb_8dev_read_bulk_callback(), the URBs are processed and resubmitted. In usb_8dev_close() -> unlink_all_urbs() the URBs are freed by calling usb_kill_anchored_urbs(&priv->rx_submitted).

However, this does not take into account that the USB framework unanchors the URB before the complete function is called. This means that once an in-URB has been completed, it is no longer anchored and is ultimately not released in usb_kill_anchored_urbs().

Fix the memory leak by anchoring the URB in the usb_8dev_read_bulk_callback() to the priv->rx_submitted anchor.

---
 drivers/net/can/usb/usb_8dev.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/net/can/usb/usb_8dev.c +7 -1
@@ -541,11 +541,17 @@ resubmit_urb:
 			  urb->transfer_buffer, RX_BUFFER_SIZE,
 			  usb_8dev_read_bulk_callback, priv);
 
+	usb_anchor_urb(urb, &priv->rx_submitted);
+
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
+	if (!retval)
+		return;
+
+	usb_unanchor_urb(urb);
 
 	if (retval == -ENODEV)
 		netif_device_detach(netdev);
-	else if (retval)
+	else
 		netdev_err(netdev,
 			"failed resubmitting read bulk urb: %d\n", retval);
 }
author maintainer
#188 lore raw

PATCH 183/280 migrate: correct lock ordering for hugetlb file folios

In reply to Greg Kroah-Hartman

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

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

From: Matthew Wilcox (Oracle) <[email protected]>

commit b7880cb166ab62c2409046b2347261abf701530e upstream.

Syzbot has found a deadlock (analyzed by Lance Yang):

1) Task (5749): Holds folio_lock, then tries to acquire i_mmap_rwsem(read lock).
2) Task (5754): Holds i_mmap_rwsem(write lock), then tries to acquire folio_lock.

migrate_pages()
-> migrate_hugetlbs()

    -> unmap_and_move_huge_page()     <- Takes folio_lock!
      -> remove_migration_ptes()
        -> __rmap_walk_file()
          -> i_mmap_lock_read()       <- Waits for i_mmap_rwsem(read lock)!

hugetlbfs_fallocate()
-> hugetlbfs_punch_hole() <- Takes i_mmap_rwsem(write lock)!

    -> hugetlbfs_zero_partial_page()
     -> filemap_lock_hugetlb_folio()
      -> filemap_lock_folio()
        -> __filemap_get_folio        <- Waits for folio_lock!

The migration path is the one taking locks in the wrong order according to the documentation at the top of mm/rmap.c. So expand the scope of the existing i_mmap_lock to cover the calls to remove_migration_ptes() too.

This is (mostly) how it used to be after commit c0d0381ade79. That was removed by 336bf30eb765 for both file & anon hugetlb pages when it should only have been removed for anon hugetlb pages.

---
 mm/migrate.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
mm/migrate.c +6 -6
@@ -1357,6 +1357,7 @@ static int unmap_and_move_huge_page(new_
 	struct page *new_hpage;
 	struct anon_vma *anon_vma = NULL;
 	struct address_space *mapping = NULL;
+	enum ttu_flags ttu = 0;
 
 	/*
 	 * Migratability of hugepages depends on architectures and their size.
@@ -1409,8 +1410,6 @@ static int unmap_and_move_huge_page(new_
 		goto put_anon;
 
 	if (folio_mapped(src)) {
-		enum ttu_flags ttu = 0;
-
 		if (!folio_test_anon(src)) {
 			/*
 			 * In shared mappings, try_to_unmap could potentially
@@ -1427,9 +1426,6 @@ static int unmap_and_move_huge_page(new_
 
 		try_to_migrate(src, ttu);
 		page_was_mapped = 1;
-
-		if (ttu & TTU_RMAP_LOCKED)
-			i_mmap_unlock_write(mapping);
 	}
 
 	if (!folio_mapped(src))
@@ -1437,7 +1433,11 @@ static int unmap_and_move_huge_page(new_
 
 	if (page_was_mapped)
 		remove_migration_ptes(src,
-			rc == MIGRATEPAGE_SUCCESS ? dst : src, false);
+			rc == MIGRATEPAGE_SUCCESS ? dst : src,
+				ttu ? true : false);
+
+	if (ttu & TTU_RMAP_LOCKED)
+		i_mmap_unlock_write(mapping);
 
 unlock_put_anon:
 	folio_unlock(dst);
author maintainer
#189 lore raw

PATCH 184/280 bpf: Do not let BPF test infra emit invalid GSO types to stack

In reply to Greg Kroah-Hartman

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

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

From: Daniel Borkmann <[email protected]>

commit 04a899573fb87273a656f178b5f920c505f68875 upstream.

Yinhao et al. reported that their fuzzer tool was able to trigger a skb_warn_bad_offload() from netif_skb_features() -> gso_features_check(). When a BPF program - triggered via BPF test infra - pushes the packet to the loopback device via bpf_clone_redirect() then mentioned offload warning can be seen. GSO-related features are then rightfully disabled.

We get into this situation due to convert___skb_to_skb() setting gso_segs and gso_size but not gso_type. Technically, it makes sense that this warning triggers since the GSO properties are malformed due to the gso_type. Potentially, the gso_type could be marked non-trustworthy through setting it at least to SKB_GSO_DODGY without any other specific assumptions, but that also feels wrong given we should not go further into the GSO engine in the first place.

The checks were added in 121d57af308d ("gso: validate gso_type in GSO handlers") because there were malicious (syzbot) senders that combine a protocol with a non-matching gso_type. If we would want to drop such packets, gso_features_check() currently only returns feature flags via netif_skb_features(), so one location for potentially dropping such skbs could be validate_xmit_unreadable_skb(), but then otoh it would be an additional check in the fast-path for a very corner case. Given bpf_clone_redirect() is the only place where BPF test infra could emit such packets, lets reject them right there.

Fixes 850a88cc4096 ("bpf: Expose __sk_buff wire_len/gso_segs to BPF_PROG_TEST_RUN")
Fixes cf62089b0edd ("bpf: Add gso_size to __sk_buff")
---
 net/bpf/test_run.c |    5 +++++
 net/core/filter.c  |    7 +++++++
 2 files changed, 12 insertions(+)
net/bpf/test_run.c +5 -0
@@ -1047,6 +1047,11 @@ static int convert___skb_to_skb(struct s
 
 	if (__skb->gso_segs > GSO_MAX_SEGS)
 		return -EINVAL;
+
+	/* Currently GSO type is zero/unset. If this gets extended with
+	 * a small list of accepted GSO types in future, the filter for
+	 * an unset GSO type in bpf_clone_redirect() can be lifted.
+	 */
 	skb_shinfo(skb)->gso_segs = __skb->gso_segs;
 	skb_shinfo(skb)->gso_size = __skb->gso_size;
 	skb_shinfo(skb)->hwtstamps.hwtstamp = __skb->hwtstamp;
net/core/filter.c +7 -0
@@ -2444,6 +2444,13 @@ BPF_CALL_3(bpf_clone_redirect, struct sk
 	if (unlikely(flags & (~(BPF_F_INGRESS) | BPF_F_REDIRECT_INTERNAL)))
 		return -EINVAL;
 
+	/* BPF test infra's convert___skb_to_skb() can create type-less
+	 * GSO packets. gso_features_check() will detect this as a bad
+	 * offload. However, lets not leak them out in the first place.
+	 */
+	if (unlikely(skb_is_gso(skb) && !skb_shinfo(skb)->gso_type))
+		return -EBADMSG;
+
 	dev = dev_get_by_index_rcu(dev_net(skb->dev), ifindex);
 	if (unlikely(!dev))
 		return -EINVAL;
author maintainer
#190 lore raw

PATCH 185/280 bpf: Reject narrower access to pointer ctx fields

In reply to Greg Kroah-Hartman

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

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

From: Paul Chaignon <[email protected]>

commit e09299225d5ba3916c91ef70565f7d2187e4cca0 upstream.

The following BPF program, simplified from a syzkaller repro, causes a kernel warning:

    r0 = *(u8 *)(r1 + 169);
    exit;

With pointer field sk being at offset 168 in __sk_buff. This access is detected as a narrower read in bpf_skb_is_valid_access because it doesn't match offsetof(struct __sk_buff, sk). It is therefore allowed and later proceeds to bpf_convert_ctx_access. Note that for the "is_narrower_load" case in the convert_ctx_accesses(), the insn->off is aligned, so the cnt may not be 0 because it matches the offsetof(struct __sk_buff, sk) in the bpf_convert_ctx_access. However, the target_size stays 0 and the verifier errors with a kernel warning:

verifier bug: error during ctx access conversion(1)

This patch fixes that to return a proper "invalid bpf_context access off=X size=Y" error on the load instruction.

The same issue affects multiple other fields in context structures that allow narrow access. Some other non-affected fields (for sk_msg, sk_lookup, and sockopt) were also changed to use bpf_ctx_range_ptr for consistency.

Note this syzkaller crash was reported in the "Closes" link below, which used to be about a different bug, fixed in
commit fce7bd8e385a ("bpf/verifier: Handle BPF_LOAD_ACQ instructions in insn_def_regno()"). Because syzbot somehow confused the two bugs, the new crash and repro didn't get reported to the mailing list.

[shung-hsi.yu: offset(struct bpf_sock_ops, skb_hwtstamp) case was dropped becasuse it was only added in v6.2 with commit 9bb053490f1a ("bpf: Add hwtstamp field for the sockops prog")]

---
 kernel/bpf/cgroup.c |    8 ++++----
 net/core/filter.c   |   18 +++++++++---------
 2 files changed, 13 insertions(+), 13 deletions(-)
kernel/bpf/cgroup.c +4 -4
@@ -2384,22 +2384,22 @@ static bool cg_sockopt_is_valid_access(i
 	}
 
 	switch (off) {
-	case offsetof(struct bpf_sockopt, sk):
+	case bpf_ctx_range_ptr(struct bpf_sockopt, sk):
 		if (size != sizeof(__u64))
 			return false;
 		info->reg_type = PTR_TO_SOCKET;
 		break;
-	case offsetof(struct bpf_sockopt, optval):
+	case bpf_ctx_range_ptr(struct bpf_sockopt, optval):
 		if (size != sizeof(__u64))
 			return false;
 		info->reg_type = PTR_TO_PACKET;
 		break;
-	case offsetof(struct bpf_sockopt, optval_end):
+	case bpf_ctx_range_ptr(struct bpf_sockopt, optval_end):
 		if (size != sizeof(__u64))
 			return false;
 		info->reg_type = PTR_TO_PACKET_END;
 		break;
-	case offsetof(struct bpf_sockopt, retval):
+	case bpf_ctx_range(struct bpf_sockopt, retval):
 		if (size != size_default)
 			return false;
 		return prog->expected_attach_type == BPF_CGROUP_GETSOCKOPT;
net/core/filter.c +9 -9
@@ -8522,7 +8522,7 @@ static bool bpf_skb_is_valid_access(int
 		if (size != sizeof(__u64))
 			return false;
 		break;
-	case offsetof(struct __sk_buff, sk):
+	case bpf_ctx_range_ptr(struct __sk_buff, sk):
 		if (type == BPF_WRITE || size != sizeof(__u64))
 			return false;
 		info->reg_type = PTR_TO_SOCK_COMMON_OR_NULL;
@@ -9106,7 +9106,7 @@ static bool sock_addr_is_valid_access(in
 				return false;
 		}
 		break;
-	case offsetof(struct bpf_sock_addr, sk):
+	case bpf_ctx_range_ptr(struct bpf_sock_addr, sk):
 		if (type != BPF_READ)
 			return false;
 		if (size != sizeof(__u64))
@@ -9160,17 +9160,17 @@ static bool sock_ops_is_valid_access(int
 			if (size != sizeof(__u64))
 				return false;
 			break;
-		case offsetof(struct bpf_sock_ops, sk):
+		case bpf_ctx_range_ptr(struct bpf_sock_ops, sk):
 			if (size != sizeof(__u64))
 				return false;
 			info->reg_type = PTR_TO_SOCKET_OR_NULL;
 			break;
-		case offsetof(struct bpf_sock_ops, skb_data):
+		case bpf_ctx_range_ptr(struct bpf_sock_ops, skb_data):
 			if (size != sizeof(__u64))
 				return false;
 			info->reg_type = PTR_TO_PACKET;
 			break;
-		case offsetof(struct bpf_sock_ops, skb_data_end):
+		case bpf_ctx_range_ptr(struct bpf_sock_ops, skb_data_end):
 			if (size != sizeof(__u64))
 				return false;
 			info->reg_type = PTR_TO_PACKET_END;
@@ -9245,17 +9245,17 @@ static bool sk_msg_is_valid_access(int o
 		return false;
 
 	switch (off) {
-	case offsetof(struct sk_msg_md, data):
+	case bpf_ctx_range_ptr(struct sk_msg_md, data):
 		info->reg_type = PTR_TO_PACKET;
 		if (size != sizeof(__u64))
 			return false;
 		break;
-	case offsetof(struct sk_msg_md, data_end):
+	case bpf_ctx_range_ptr(struct sk_msg_md, data_end):
 		info->reg_type = PTR_TO_PACKET_END;
 		if (size != sizeof(__u64))
 			return false;
 		break;
-	case offsetof(struct sk_msg_md, sk):
+	case bpf_ctx_range_ptr(struct sk_msg_md, sk):
 		if (size != sizeof(__u64))
 			return false;
 		info->reg_type = PTR_TO_SOCKET;
@@ -11444,7 +11444,7 @@ static bool sk_lookup_is_valid_access(in
 		return false;
 
 	switch (off) {
-	case offsetof(struct bpf_sk_lookup, sk):
+	case bpf_ctx_range_ptr(struct bpf_sk_lookup, sk):
 		info->reg_type = PTR_TO_SOCKET_OR_NULL;
 		return size == sizeof(__u64);
 
author maintainer
#191 lore raw

PATCH 186/280 mm/damon/sysfs-scheme: cleanup quotas subdirs on scheme dir setup failure

In reply to Greg Kroah-Hartman

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

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

From: SeongJae Park <[email protected]>

commit dc7e1d75fd8c505096d0cddeca9e2efb2b55aaf9 upstream.

When a DAMOS-scheme DAMON sysfs directory setup fails after setup of quotas/ directory, subdirectories of quotas/ directory are not cleaned up. As a result, DAMON sysfs interface is nearly broken until the system reboots, and the memory for the unremoved directory is leaked.

Cleanup the directories under such failures.

Fixes 1b32234ab087 ("mm/damon/sysfs: support DAMOS watermarks")
Cc chongjiapeng <[email protected]>
Cc <[email protected]> # 5.18.x
---
 mm/damon/sysfs.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
mm/damon/sysfs.c +3 -2
@@ -859,7 +859,7 @@ static int damon_sysfs_scheme_add_dirs(s
 		goto put_access_pattern_out;
 	err = damon_sysfs_scheme_set_watermarks(scheme);
 	if (err)
-		goto put_quotas_access_pattern_out;
+		goto rmdir_put_quotas_access_pattern_out;
 	err = damon_sysfs_scheme_set_stats(scheme);
 	if (err)
 		goto put_watermarks_quotas_access_pattern_out;
@@ -868,7 +868,8 @@ static int damon_sysfs_scheme_add_dirs(s
 put_watermarks_quotas_access_pattern_out:
 	kobject_put(&scheme->watermarks->kobj);
 	scheme->watermarks = NULL;
-put_quotas_access_pattern_out:
+rmdir_put_quotas_access_pattern_out:
+	damon_sysfs_quotas_rm_dirs(scheme->quotas);
 	kobject_put(&scheme->quotas->kobj);
 	scheme->quotas = NULL;
 put_access_pattern_out:
author maintainer
#192 lore raw

PATCH 187/280 mm/damon/sysfs-scheme: cleanup access_pattern subdirs on scheme dir setup failure

In reply to Greg Kroah-Hartman

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

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

From: SeongJae Park <[email protected]>

commit 392b3d9d595f34877dd745b470c711e8ebcd225c upstream.

When a DAMOS-scheme DAMON sysfs directory setup fails after setup of access_pattern/ directory, subdirectories of access_pattern/ directory are not cleaned up. As a result, DAMON sysfs interface is nearly broken until the system reboots, and the memory for the unremoved directory is leaked.

Cleanup the directories under such failures.

---
 mm/damon/sysfs.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
mm/damon/sysfs.c +3 -2
@@ -856,7 +856,7 @@ static int damon_sysfs_scheme_add_dirs(s
 		return err;
 	err = damon_sysfs_scheme_set_quotas(scheme);
 	if (err)
-		goto put_access_pattern_out;
+		goto rmdir_put_access_pattern_out;
 	err = damon_sysfs_scheme_set_watermarks(scheme);
 	if (err)
 		goto rmdir_put_quotas_access_pattern_out;
@@ -872,7 +872,8 @@ rmdir_put_quotas_access_pattern_out:
 	damon_sysfs_quotas_rm_dirs(scheme->quotas);
 	kobject_put(&scheme->quotas->kobj);
 	scheme->quotas = NULL;
-put_access_pattern_out:
+rmdir_put_access_pattern_out:
+	damon_sysfs_access_pattern_rm_dirs(scheme->access_pattern);
 	kobject_put(&scheme->access_pattern->kobj);
 	scheme->access_pattern = NULL;
 	return err;
author maintainer
#193 lore raw

PATCH 188/280 Bluetooth: hci_uart: fix null-ptr-deref in hci_uart_write_work

In reply to Greg Kroah-Hartman

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

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

From: Jia-Hong Su <[email protected]>

[ Upstream commit 0c3cd7a0b862c37acbee6d9502107146cc944398 ]

hci_uart_set_proto() sets HCI_UART_PROTO_INIT before calling hci_uart_register_dev(), which calls proto->open() to initialize hu->priv. However, if a TTY write wakeup occurs during this window, hci_uart_tx_wakeup() may schedule write_work before hu->priv is initialized, leading to a NULL pointer dereference in hci_uart_write_work() when proto->dequeue() accesses hu->priv.

The race condition is:

CPU0 CPU1
---- ----
hci_uart_set_proto()

    set_bit(HCI_UART_PROTO_INIT)
    hci_uart_register_dev()
                                    tty write wakeup
                                      hci_uart_tty_wakeup()
                                        hci_uart_tx_wakeup()
                                          schedule_work(&hu->write_work)
      proto->open(hu)
        // initializes hu->priv
                                    hci_uart_write_work()
                                      hci_uart_dequeue()
                                        proto->dequeue(hu)
                                          // accesses hu->priv (NULL!)

Fix this by moving set_bit(HCI_UART_PROTO_INIT) after proto->open() succeeds, ensuring hu->priv is initialized before any work can be scheduled.

Fixes 5df5dafc171b ("Bluetooth: hci_uart: Fix another race during initialization")
---
 drivers/bluetooth/hci_ldisc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/bluetooth/hci_ldisc.c +2 -2
index 6a90fc69ef444..2752857dbccf3 100644
@@ -687,6 +687,8 @@ static int hci_uart_register_dev(struct hci_uart *hu)
 		return err;
 	}
 
+	set_bit(HCI_UART_PROTO_INIT, &hu->flags);
+
 	if (test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags))
 		return 0;
 
@@ -714,8 +716,6 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id)
 
 	hu->proto = p;
 
-	set_bit(HCI_UART_PROTO_INIT, &hu->flags);
-
 	err = hci_uart_register_dev(hu);
 	if (err) {
 		return err;
Signature · 1 line
2.51.0
author maintainer
#194 lore raw

PATCH 189/280 net/mlx5: Fix memory leak in esw_acl_ingress_lgcy_setup()

In reply to Greg Kroah-Hartman

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

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

From: Zilin Guan <[email protected]>

[ Upstream commit 108948f723b13874b7ebf6b3f1cc598a7de38622 ]

In esw_acl_ingress_lgcy_setup(), if esw_acl_table_create() fails, the function returns directly without releasing the previously created counter, leading to a memory leak.

Fix this by jumping to the out label instead of returning directly, which aligns with the error handling logic of other paths in this function.

Compile tested only. Issue found using a prototype static analysis tool and code review.

Fixes 07bab9502641 ("net/mlx5: E-Switch, Refactor eswitch ingress acl codes")
---
 drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c +1 -1
index 093ed86a0acd8..db51c500ed359 100644
@@ -188,7 +188,7 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
 		if (IS_ERR(vport->ingress.acl)) {
 			err = PTR_ERR(vport->ingress.acl);
 			vport->ingress.acl = NULL;
-			return err;
+			goto out;
 		}
 
 		err = esw_acl_ingress_lgcy_groups_create(esw, vport);
Signature · 1 line
2.51.0
author maintainer
#195 lore raw

PATCH 190/280 can: gs_usb: gs_usb_receive_bulk_callback(): fix error message

In reply to Greg Kroah-Hartman

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

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

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

[ Upstream commit 494fc029f662c331e06b7c2031deff3c64200eed ]

Sinc commit 79a6d1bfe114 ("can: gs_usb: gs_usb_receive_bulk_callback():
unanchor URL on usb_submit_urb() error") a failing resubmit URB will print an info message.

In the case of a short read where netdev has not yet been assigned, initialize as NULL to avoid dereferencing an undefined value. Also report the error value of the failed resubmit.

---
 drivers/net/can/usb/gs_usb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/can/usb/gs_usb.c +2 -2
index f782c3aa179e0..8859e65d4470b 100644
@@ -526,7 +526,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
 {
 	struct gs_usb *parent = urb->context;
 	struct gs_can *dev;
-	struct net_device *netdev;
+	struct net_device *netdev = NULL;
 	int rc;
 	struct net_device_stats *stats;
 	struct gs_host_frame *hf = urb->transfer_buffer;
@@ -674,7 +674,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
 		}
 	} else if (rc != -ESHUTDOWN && net_ratelimit()) {
 		netdev_info(netdev, "failed to re-submit IN URB: %pe\n",
-			    ERR_PTR(urb->status));
+			    ERR_PTR(rc));
 	}
 }
 
Signature · 1 line
2.51.0
author maintainer
#196 lore raw

PATCH 191/280 bonding: annotate data-races around slave->last_rx

In reply to Greg Kroah-Hartman

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit f6c3665b6dc53c3ab7d31b585446a953a74340ef ]

slave->last_rx and slave->target_last_arp_rx[...] can be read and written locklessly. Add READ_ONCE() and WRITE_ONCE() annotations.

syzbot reported:

BUG: KCSAN: data-race in bond_rcv_validate / bond_rcv_validate

write to 0xffff888149f0d428 of 8 bytes by interrupt on cpu 1:

  bond_rcv_validate+0x202/0x7a0 drivers/net/bonding/bond_main.c:3335
  bond_handle_frame+0xde/0x5e0 drivers/net/bonding/bond_main.c:1533
  __netif_receive_skb_core+0x5b1/0x1950 net/core/dev.c:6039
  __netif_receive_skb_one_core net/core/dev.c:6150 [inline]
  __netif_receive_skb+0x59/0x270 net/core/dev.c:6265
  netif_receive_skb_internal net/core/dev.c:6351 [inline]
  netif_receive_skb+0x4b/0x2d0 net/core/dev.c:6410

...

write to 0xffff888149f0d428 of 8 bytes by interrupt on cpu 0:

  bond_rcv_validate+0x202/0x7a0 drivers/net/bonding/bond_main.c:3335
  bond_handle_frame+0xde/0x5e0 drivers/net/bonding/bond_main.c:1533
  __netif_receive_skb_core+0x5b1/0x1950 net/core/dev.c:6039
  __netif_receive_skb_one_core net/core/dev.c:6150 [inline]
  __netif_receive_skb+0x59/0x270 net/core/dev.c:6265
  netif_receive_skb_internal net/core/dev.c:6351 [inline]
  netif_receive_skb+0x4b/0x2d0 net/core/dev.c:6410
  br_netif_receive_skb net/bridge/br_input.c:30 [inline]
  NF_HOOK include/linux/netfilter.h:318 [inline]

...

value changed: 0x0000000100005365 -> 0x0000000100005366

Fixes f5b2b966f032 ("[PATCH] bonding: Validate probe replies in ARP monitor")
---
 drivers/net/bonding/bond_main.c    | 18 ++++++++++--------
 drivers/net/bonding/bond_options.c |  8 ++++----
 include/net/bonding.h              | 13 +++++++------
 3 files changed, 21 insertions(+), 18 deletions(-)
drivers/net/bonding/bond_main.c +10 -8
index b0bc811aaab91..71912ddfa7149 100644
@@ -3082,8 +3082,8 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32
 			   __func__, &sip);
 		return;
 	}
-	slave->last_rx = jiffies;
-	slave->target_last_arp_rx[i] = jiffies;
+	WRITE_ONCE(slave->last_rx, jiffies);
+	WRITE_ONCE(slave->target_last_arp_rx[i], jiffies);
 }
 
 static int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
@@ -3302,8 +3302,8 @@ static void bond_validate_na(struct bonding *bond, struct slave *slave,
 			  __func__, saddr);
 		return;
 	}
-	slave->last_rx = jiffies;
-	slave->target_last_arp_rx[i] = jiffies;
+	WRITE_ONCE(slave->last_rx, jiffies);
+	WRITE_ONCE(slave->target_last_arp_rx[i], jiffies);
 }
 
 static int bond_na_rcv(const struct sk_buff *skb, struct bonding *bond,
@@ -3373,7 +3373,7 @@ int bond_rcv_validate(const struct sk_buff *skb, struct bonding *bond,
 		    (slave_do_arp_validate_only(bond) && is_ipv6) ||
 #endif
 		    !slave_do_arp_validate_only(bond))
-			slave->last_rx = jiffies;
+			WRITE_ONCE(slave->last_rx, jiffies);
 		return RX_HANDLER_ANOTHER;
 	} else if (is_arp) {
 		return bond_arp_rcv(skb, bond, slave);
@@ -3441,7 +3441,7 @@ static void bond_loadbalance_arp_mon(struct bonding *bond)
 
 		if (slave->link != BOND_LINK_UP) {
 			if (bond_time_in_interval(bond, last_tx, 1) &&
-			    bond_time_in_interval(bond, slave->last_rx, 1)) {
+			    bond_time_in_interval(bond, READ_ONCE(slave->last_rx), 1)) {
 
 				bond_propose_link_state(slave, BOND_LINK_UP);
 				slave_state_changed = 1;
@@ -3465,8 +3465,10 @@ static void bond_loadbalance_arp_mon(struct bonding *bond)
 			 * when the source ip is 0, so don't take the link down
 			 * if we don't know our ip yet
 			 */
-			if (!bond_time_in_interval(bond, last_tx, bond->params.missed_max) ||
-			    !bond_time_in_interval(bond, slave->last_rx, bond->params.missed_max)) {
+			if (!bond_time_in_interval(bond, last_tx,
+						   bond->params.missed_max) ||
+			    !bond_time_in_interval(bond, READ_ONCE(slave->last_rx),
+						   bond->params.missed_max)) {
 
 				bond_propose_link_state(slave, BOND_LINK_DOWN);
 				slave_state_changed = 1;
drivers/net/bonding/bond_options.c +4 -4
index 1235878d87159..9473e76c6dc9d 100644
@@ -1133,7 +1133,7 @@ static void _bond_options_arp_ip_target_set(struct bonding *bond, int slot,
 
 	if (slot >= 0 && slot < BOND_MAX_ARP_TARGETS) {
 		bond_for_each_slave(bond, slave, iter)
-			slave->target_last_arp_rx[slot] = last_rx;
+			WRITE_ONCE(slave->target_last_arp_rx[slot], last_rx);
 		targets[slot] = target;
 	}
 }
@@ -1202,8 +1202,8 @@ static int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target)
 	bond_for_each_slave(bond, slave, iter) {
 		targets_rx = slave->target_last_arp_rx;
 		for (i = ind; (i < BOND_MAX_ARP_TARGETS-1) && targets[i+1]; i++)
-			targets_rx[i] = targets_rx[i+1];
-		targets_rx[i] = 0;
+			WRITE_ONCE(targets_rx[i], READ_ONCE(targets_rx[i+1]));
+		WRITE_ONCE(targets_rx[i], 0);
 	}
 	for (i = ind; (i < BOND_MAX_ARP_TARGETS-1) && targets[i+1]; i++)
 		targets[i] = targets[i+1];
@@ -1358,7 +1358,7 @@ static void _bond_options_ns_ip6_target_set(struct bonding *bond, int slot,
 
 	if (slot >= 0 && slot < BOND_MAX_NS_TARGETS) {
 		bond_for_each_slave(bond, slave, iter) {
-			slave->target_last_arp_rx[slot] = last_rx;
+			WRITE_ONCE(slave->target_last_arp_rx[slot], last_rx);
 			slave_set_ns_maddr(bond, slave, target, &targets[slot]);
 		}
 		targets[slot] = *target;
include/net/bonding.h +7 -6
index bfd3e4e58f861..bdfbe77c18420 100644
@@ -525,13 +525,14 @@ static inline int bond_is_ip6_target_ok(struct in6_addr *addr)
 static inline unsigned long slave_oldest_target_arp_rx(struct bonding *bond,
 						       struct slave *slave)
 {
+	unsigned long tmp, ret = READ_ONCE(slave->target_last_arp_rx[0]);
 	int i = 1;
-	unsigned long ret = slave->target_last_arp_rx[0];
-
-	for (; (i < BOND_MAX_ARP_TARGETS) && bond->params.arp_targets[i]; i++)
-		if (time_before(slave->target_last_arp_rx[i], ret))
-			ret = slave->target_last_arp_rx[i];
 
+	for (; (i < BOND_MAX_ARP_TARGETS) && bond->params.arp_targets[i]; i++) {
+		tmp = READ_ONCE(slave->target_last_arp_rx[i]);
+		if (time_before(tmp, ret))
+			ret = tmp;
+	}
 	return ret;
 }
 
@@ -541,7 +542,7 @@ static inline unsigned long slave_last_rx(struct bonding *bond,
 	if (bond->params.arp_all_targets == BOND_ARP_TARGETS_ALL)
 		return slave_oldest_target_arp_rx(bond, slave);
 
-	return slave->last_rx;
+	return READ_ONCE(slave->last_rx);
 }
 
 static inline void slave_update_last_tx(struct slave *slave)
Signature · 1 line
2.51.0
author maintainer
#197 lore raw

PATCH 192/280 net: mvpp2: cls: Fix memory leak in mvpp2_ethtool_cls_rule_ins()

In reply to Greg Kroah-Hartman

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

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

From: Zilin Guan <[email protected]>

[ Upstream commit 09f979d1f312627b31d2ee1e46f9692e442610cd ]

In mvpp2_ethtool_cls_rule_ins(), the ethtool_rule is allocated by ethtool_rx_flow_rule_create(). If the subsequent conversion to flow type fails, the function jumps to the clean_rule label.

However, the clean_rule label only frees efs, skipping the cleanup of ethtool_rule, which leads to a memory leak.

Fix this by jumping to the clean_eth_rule label, which properly calls ethtool_rx_flow_rule_destroy() before freeing efs.

Compile tested only. Issue found using a prototype static analysis tool and code review.

Fixes f4f1ba18195d ("net: mvpp2: cls: Report an error for unsupported flow types")
---
 drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c +1 -1
index d2757cc116139..038382a0b8e9f 100644
@@ -1389,7 +1389,7 @@ int mvpp2_ethtool_cls_rule_ins(struct mvpp2_port *port,
 	efs->rule.flow_type = mvpp2_cls_ethtool_flow_to_type(info->fs.flow_type);
 	if (efs->rule.flow_type < 0) {
 		ret = efs->rule.flow_type;
-		goto clean_rule;
+		goto clean_eth_rule;
 	}
 
 	ret = mvpp2_cls_rfs_parse_rule(&efs->rule);
Signature · 1 line
2.51.0
author maintainer
#198 lore raw

PATCH 193/280 ipv6: use the right ifindex when replying to icmpv6 from localhost

In reply to Greg Kroah-Hartman

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

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

From: Fernando Fernandez Mancera <[email protected]>

[ Upstream commit 03cbcdf93866e61beb0063392e6dbb701f03aea2 ]

When replying to a ICMPv6 echo request that comes from localhost address the right output ifindex is 1 (lo) and not rt6i_idev dev index. Use the skb device ifindex instead. This fixes pinging to a local address from localhost source address.

$ ping6 -I ::1 2001:1:1::2 -c 3
PING 2001:1:1::2 (2001:1:1::2) from ::1 : 56 data bytes
64 bytes from 2001:1:1::2: icmp_seq=1 ttl=64 time=0.037 ms
64 bytes from 2001:1:1::2: icmp_seq=2 ttl=64 time=0.069 ms
64 bytes from 2001:1:1::2: icmp_seq=3 ttl=64 time=0.122 ms

2001:1:1::2 ping statistics
3 packets transmitted, 3 received, 0% packet loss, time 2032ms rtt min/avg/max/mdev = 0.037/0.076/0.122/0.035 ms

Fixes 1b70d792cf67 ("ipv6: Use rt6i_idev index for echo replies to a local address")
---
 net/ipv6/icmp.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
net/ipv6/icmp.c +3 -1
index 7d88fd314c390..7ba3c642ab3c3 100644
@@ -765,7 +765,9 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
 	fl6.daddr = ipv6_hdr(skb)->saddr;
 	if (saddr)
 		fl6.saddr = *saddr;
-	fl6.flowi6_oif = icmp6_iif(skb);
+	fl6.flowi6_oif = ipv6_addr_loopback(&fl6.daddr) ?
+			 skb->dev->ifindex :
+			 icmp6_iif(skb);
 	fl6.fl6_icmp_type = type;
 	fl6.flowi6_mark = mark;
 	fl6.flowi6_uid = sock_net_uid(net, NULL);
Signature · 1 line
2.51.0
author maintainer
#199 lore raw

PATCH 194/280 net: wwan: t7xx: fix potential skb->frags overflow in RX path

In reply to Greg Kroah-Hartman

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

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

From: Kery Qi <[email protected]>

[ Upstream commit f0813bcd2d9d97fdbdf2efb9532ab03ae92e99e6 ]

When receiving data in the DPMAIF RX path,
the t7xx_dpmaif_set_frag_to_skb() function adds
page fragments to an skb without checking if the number of fragments has exceeded MAX_SKB_FRAGS. This could lead to a buffer overflow in skb_shinfo(skb)->frags[] array, corrupting adjacent memory and potentially causing kernel crashes or other undefined behavior.

This issue was identified through static code analysis by comparing with a similar vulnerability fixed in the mt76 driver commit b102f0c522cf ("mt76:
fix array overflow on receiving too many fragments for a packet").

The vulnerability could be triggered if the modem firmware sends packets with excessive fragments. While under normal protocol conditions (MTU 3080 bytes, BAT buffer 3584 bytes),
a single packet should not require additional
fragments, the kernel should not blindly trust firmware behavior. Malicious, buggy, or compromised firmware could potentially craft packets with more fragments than the kernel expects.

Fix this by adding a bounds check before calling skb_add_rx_frag() to ensure nr_frags does not exceed MAX_SKB_FRAGS.

The check must be performed before unmapping to avoid a page leak and double DMA unmap during device teardown.

Fixes d642b012df70a ("net: wwan: t7xx: Add data path interface")
---
 drivers/net/wwan/t7xx/t7xx_hif_dpmaif_rx.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/net/wwan/t7xx/t7xx_hif_dpmaif_rx.c +7 -2
index f4f924d75103a..bdf1451fbc87d 100644
@@ -430,6 +430,7 @@ static int t7xx_dpmaif_set_frag_to_skb(const struct dpmaif_rx_queue *rxq,
 				       struct sk_buff *skb)
 {
 	unsigned long long data_bus_addr, data_base_addr;
+	struct skb_shared_info *shinfo = skb_shinfo(skb);
 	struct device *dev = rxq->dpmaif_ctrl->dev;
 	struct dpmaif_bat_page *page_info;
 	unsigned int data_len;
@@ -437,18 +438,22 @@ static int t7xx_dpmaif_set_frag_to_skb(const struct dpmaif_rx_queue *rxq,
 
 	page_info = rxq->bat_frag->bat_skb;
 	page_info += t7xx_normal_pit_bid(pkt_info);
-	dma_unmap_page(dev, page_info->data_bus_addr, page_info->data_len, DMA_FROM_DEVICE);
 
 	if (!page_info->page)
 		return -EINVAL;
 
+	if (shinfo->nr_frags >= MAX_SKB_FRAGS)
+		return -EINVAL;
+
+	dma_unmap_page(dev, page_info->data_bus_addr, page_info->data_len, DMA_FROM_DEVICE);
+
 	data_bus_addr = le32_to_cpu(pkt_info->pd.data_addr_h);
 	data_bus_addr = (data_bus_addr << 32) + le32_to_cpu(pkt_info->pd.data_addr_l);
 	data_base_addr = page_info->data_bus_addr;
 	data_offset = data_bus_addr - data_base_addr;
 	data_offset += page_info->offset;
 	data_len = FIELD_GET(PD_PIT_DATA_LEN, le32_to_cpu(pkt_info->header));
-	skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page_info->page,
+	skb_add_rx_frag(skb, shinfo->nr_frags, page_info->page,
 			data_offset, data_len, page_info->data_len);
 
 	page_info->page = NULL;
Signature · 1 line
2.51.0
author maintainer
#200 lore raw

PATCH 195/280 rocker: fix memory leak in rocker_world_port_post_fini()

In reply to Greg Kroah-Hartman

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

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

From: Kery Qi <[email protected]>

[ Upstream commit 8d7ba71e46216b8657a82ca2ec118bc93812a4d0 ]

In rocker_world_port_pre_init(), rocker_port->wpriv is allocated with kzalloc(wops->port_priv_size, GFP_KERNEL). However, in rocker_world_port_post_fini(), the memory is only freed when wops->port_post_fini callback is set:

    if (!wops->port_post_fini)
        return;
    wops->port_post_fini(rocker_port);
    kfree(rocker_port->wpriv);

Since rocker_ofdpa_ops does not implement port_post_fini callback (it is NULL), the wpriv memory allocated for each port is never freed when ports are removed. This leads to a memory leak of sizeof(struct ofdpa_port) bytes per port on every device removal.

Fix this by always calling kfree(rocker_port->wpriv) regardless of whether the port_post_fini callback exists.

Fixes e420114eef4a ("rocker: introduce worlds infrastructure")
---
 drivers/net/ethernet/rocker/rocker_main.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/net/ethernet/rocker/rocker_main.c +2 -3
index 2e2826c901fcc..b741d335b1dc4 100644
@@ -1525,9 +1525,8 @@ static void rocker_world_port_post_fini(struct rocker_port *rocker_port)
 {
 	struct rocker_world_ops *wops = rocker_port->rocker->wops;
 
-	if (!wops->port_post_fini)
-		return;
-	wops->port_post_fini(rocker_port);
+	if (wops->port_post_fini)
+		wops->port_post_fini(rocker_port);
 	kfree(rocker_port->wpriv);
 }
 
Signature · 1 line
2.51.0
author maintainer
#201 lore raw

PATCH 196/280 nfc: llcp: Fix memleak in nfc_llcp_send_ui_frame().

In reply to Greg Kroah-Hartman

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

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

From: Kuniyuki Iwashima <[email protected]>

[ Upstream commit 165c34fb6068ff153e3fc99a932a80a9d5755709 ]

syzbot reported various memory leaks related to NFC, struct nfc_llcp_sock, sk_buff, nfc_dev, etc. [0]

The leading log hinted that nfc_llcp_send_ui_frame() failed to allocate skb due to sock_error(sk) being -ENXIO.

ENXIO is set by nfc_llcp_socket_release() when struct nfc_llcp_local is destroyed by local_cleanup().

The problem is that there is no synchronisation between nfc_llcp_send_ui_frame() and local_cleanup(), and skb could be put into local->tx_queue after it was purged in local_cleanup():

  CPU1                          CPU2
  ----                          ----
  nfc_llcp_send_ui_frame()      local_cleanup()
  |- do {                       '
     |- pdu = nfc_alloc_send_skb(..., &err)
     |                          .
     |                          |- nfc_llcp_socket_release(local, false, ENXIO);
     |                          |- skb_queue_purge(&local->tx_queue);      |
     |                          '                                          |
     |- skb_queue_tail(&local->tx_queue, pdu);                             |

... |
|- pdu = nfc_alloc_send_skb(..., &err) |
^._________________________________.'

local_cleanup() is called for struct nfc_llcp_local only after nfc_llcp_remove_local() unlinks it from llcp_devices.

If we hold local->tx_queue.lock then, we can synchronise the thread and nfc_llcp_send_ui_frame().

Let's do that and check list_empty(&local->list) before queuing skb to local->tx_queue in nfc_llcp_send_ui_frame().

[0]:

[   56.074943][ T6096] llcp: nfc_llcp_send_ui_frame: Could not allocate PDU (error=-6)
[   64.318868][ T5813] kmemleak: 6 new suspected memory leaks (see /sys/kernel/debug/kmemleak)
BUG: memory leak
unreferenced object 0xffff8881272f6800 (size 1024):
  comm "syz.0.17", pid 6096, jiffies 4294942766
  hex dump (first 32 bytes):
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    27 00 03 40 00 00 00 00 00 00 00 00 00 00 00 00  '..@............
  backtrace (crc da58d84d):
    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
    slab_post_alloc_hook mm/slub.c:4979 [inline]
    slab_alloc_node mm/slub.c:5284 [inline]
    __do_kmalloc_node mm/slub.c:5645 [inline]
    __kmalloc_noprof+0x3e3/0x6b0 mm/slub.c:5658
    kmalloc_noprof include/linux/slab.h:961 [inline]
    sk_prot_alloc+0x11a/0x1b0 net/core/sock.c:2239
    sk_alloc+0x36/0x360 net/core/sock.c:2295
    nfc_llcp_sock_alloc+0x37/0x130 net/nfc/llcp_sock.c:979
    llcp_sock_create+0x71/0xd0 net/nfc/llcp_sock.c:1044
    nfc_sock_create+0xc9/0xf0 net/nfc/af_nfc.c:31
    __sock_create+0x1a9/0x340 net/socket.c:1605
    sock_create net/socket.c:1663 [inline]
    __sys_socket_create net/socket.c:1700 [inline]
    __sys_socket+0xb9/0x1a0 net/socket.c:1747
    __do_sys_socket net/socket.c:1761 [inline]
    __se_sys_socket net/socket.c:1759 [inline]
    __x64_sys_socket+0x1b/0x30 net/socket.c:1759
    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
    do_syscall_64+0xa4/0xfa0 arch/x86/entry/syscall_64.c:94
    entry_SYSCALL_64_after_hwframe+0x77/0x7f

BUG: memory leak
unreferenced object 0xffff88810fbd9800 (size 240):
  comm "syz.0.17", pid 6096, jiffies 4294942850
  hex dump (first 32 bytes):
    68 f0 ff 08 81 88 ff ff 68 f0 ff 08 81 88 ff ff  h.......h.......
    00 00 00 00 00 00 00 00 00 68 2f 27 81 88 ff ff  .........h/'....
  backtrace (crc 6cc652b1):
    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
    slab_post_alloc_hook mm/slub.c:4979 [inline]
    slab_alloc_node mm/slub.c:5284 [inline]
    kmem_cache_alloc_node_noprof+0x36f/0x5e0 mm/slub.c:5336
    __alloc_skb+0x203/0x240 net/core/skbuff.c:660
    alloc_skb include/linux/skbuff.h:1383 [inline]
    alloc_skb_with_frags+0x69/0x3f0 net/core/skbuff.c:6671
    sock_alloc_send_pskb+0x379/0x3e0 net/core/sock.c:2965
    sock_alloc_send_skb include/net/sock.h:1859 [inline]
    nfc_alloc_send_skb+0x45/0x80 net/nfc/core.c:724
    nfc_llcp_send_ui_frame+0x162/0x360 net/nfc/llcp_commands.c:766
    llcp_sock_sendmsg+0x14c/0x1d0 net/nfc/llcp_sock.c:814
    sock_sendmsg_nosec net/socket.c:727 [inline]
    __sock_sendmsg net/socket.c:742 [inline]
    __sys_sendto+0x2d8/0x2f0 net/socket.c:2244
    __do_sys_sendto net/socket.c:2251 [inline]
    __se_sys_sendto net/socket.c:2247 [inline]
    __x64_sys_sendto+0x28/0x30 net/socket.c:2247
    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
    do_syscall_64+0xa4/0xfa0 arch/x86/entry/syscall_64.c:94
    entry_SYSCALL_64_after_hwframe+0x77/0x7f
---
 net/nfc/llcp_commands.c | 17 ++++++++++++++++-
 net/nfc/llcp_core.c     |  4 +++-
 2 files changed, 19 insertions(+), 2 deletions(-)
net/nfc/llcp_commands.c +16 -1
index e2680a3bef799..b652323bc2c12 100644
@@ -778,8 +778,23 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap,
 		if (likely(frag_len > 0))
 			skb_put_data(pdu, msg_ptr, frag_len);
 
+		spin_lock(&local->tx_queue.lock);
+
+		if (list_empty(&local->list)) {
+			spin_unlock(&local->tx_queue.lock);
+
+			kfree_skb(pdu);
+
+			len -= remaining_len;
+			if (len == 0)
+				len = -ENXIO;
+			break;
+		}
+
 		/* No need to check for the peer RW for UI frames */
-		skb_queue_tail(&local->tx_queue, pdu);
+		__skb_queue_tail(&local->tx_queue, pdu);
+
+		spin_unlock(&local->tx_queue.lock);
 
 		remaining_len -= frag_len;
 		msg_ptr += frag_len;
net/nfc/llcp_core.c +3 -1
index 18be13fb9b75a..ced99d2a90cc1 100644
@@ -314,7 +314,9 @@ static struct nfc_llcp_local *nfc_llcp_remove_local(struct nfc_dev *dev)
 	spin_lock(&llcp_devices_lock);
 	list_for_each_entry_safe(local, tmp, &llcp_devices, list)
 		if (local->dev == dev) {
-			list_del(&local->list);
+			spin_lock(&local->tx_queue.lock);
+			list_del_init(&local->list);
+			spin_unlock(&local->tx_queue.lock);
 			spin_unlock(&llcp_devices_lock);
 			return local;
 		}
Signature · 1 line
2.51.0
author maintainer
#202 lore raw

PATCH 197/280 ice: stop counting UDP csum mismatch as rx_errors

In reply to Greg Kroah-Hartman

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

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

From: Jesse Brandeburg <[email protected]>

[ Upstream commit 05faf2c0a76581d0a7fdbb8ec46477ba183df95b ]

Since the beginning, the Intel ice driver has counted receive checksum offload mismatches into the rx_errors member of the rtnl_link_stats64 struct. In ethtool -S these show up as rx_csum_bad.nic.

I believe counting these in rx_errors is fundamentally wrong, as it's pretty clear from the comments in if_link.h and from every other statistic the driver is summing into rx_errors, that all of them would cause a "hardware drop" except for the UDP checksum mismatch, as well as the fact that all the other causes for rx_errors are L2 reasons, and this L4 UDP "mismatch" is an outlier.

A last nail in the coffin is that rx_errors is monitored in production and can indicate a bad NIC/cable/Switch port, but instead some random series of UDP packets with bad checksums will now trigger this alert. This false positive makes the alert useless and affects us as well as other companies.

This packet with presumably a bad UDP checksum is *already* passed to the stack, just not marked as offloaded by the hardware/driver. If it is dropped by the stack it will show up as UDP_MIB_CSUMERRORS.

And one more thing, none of the other Intel drivers, and at least bnxt_en and mlx5 both don't appear to count UDP offload mismatches as rx_errors.

Here is a related customer complaint:
https://community.intel.com/t5/Ethernet-Products/ice-rx-errros-is-too-sensitive-to-IP-TCP-attack-packets-Intel/td-p/1662125

Fixes 4f1fe43c920b ("ice: Add more Rx errors to netdev's rx_error counter")
Cc Tony Nguyen <[email protected]>
Cc Jake Keller <[email protected]>
---
 drivers/net/ethernet/intel/ice/ice_main.c | 1 -
 1 file changed, 1 deletion(-)
drivers/net/ethernet/intel/ice/ice_main.c +0 -1
index 9a540b85756f4..2737050aae218 100644
@@ -6546,7 +6546,6 @@ void ice_update_vsi_stats(struct ice_vsi *vsi)
 				    pf->stats.illegal_bytes +
 				    pf->stats.rx_len_errors +
 				    pf->stats.rx_undersize +
-				    pf->hw_csum_rx_error +
 				    pf->stats.rx_jabber +
 				    pf->stats.rx_fragments +
 				    pf->stats.rx_oversize;
Signature · 1 line
2.51.0
author maintainer
#203 lore raw

PATCH 198/280 net/mlx5e: Report rx_discards_phy via rx_dropped

In reply to Greg Kroah-Hartman

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

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

From: Yafang Shao <[email protected]>

[ Upstream commit c9cfced17365b1df8c6ae6cd5db56aebd7ed9b57 ]

We noticed a high number of rx_discards_phy events on certain servers while running ethtool -S. However, this critical counter is not currently included in the standard /proc/net/dev statistics file, making it difficult to monitor effectively—especially given the diversity of vendors across a large fleet of servers.

Let's report it via the standard rx_dropped metric.

Stable-dep-of: 476681f10cc1 ("net/mlx5e: Account for netdev stats in ndo_get_stats64")

---
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 1 +
 1 file changed, 1 insertion(+)
drivers/net/ethernet/mellanox/mlx5/core/en_main.c +1 -0
index 73011870e5ff6..1d7fe4ffdd734 100644
@@ -3667,6 +3667,7 @@ mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
 	}
 
 	stats->rx_missed_errors = priv->stats.qcnt.rx_out_of_buffer;
+	stats->rx_dropped = PPORT_2863_GET(pstats, if_in_discards);
 
 	stats->rx_length_errors =
 		PPORT_802_3_GET(pstats, a_in_range_length_errors) +
Signature · 1 line
2.51.0
author maintainer
#204 lore raw

PATCH 199/280 net/mlx5e: Account for netdev stats in ndo_get_stats64

In reply to Greg Kroah-Hartman

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

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

From: Gal Pressman <[email protected]>

[ Upstream commit 476681f10cc1e0e56e26856684e75d4678b072b2 ]

The driver's ndo_get_stats64 callback is only reporting mlx5 counters, without accounting for the netdev stats, causing errors from the network stack to be invisible in statistics.

Add netdev_stats_to_stats64() call to first populate the counters, then add mlx5 counters on top, ensuring both are accounted for (where appropriate).

Fixes f62b8bb8f2d3 ("net/mlx5: Extend mlx5_core to support ConnectX-4 Ethernet functionality")
---
 .../net/ethernet/mellanox/mlx5/core/en_main.c | 20 ++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_main.c +11 -9
index 1d7fe4ffdd734..2d0b57583ea35 100644
@@ -3650,6 +3650,8 @@ mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
 		mlx5e_queue_update_stats(priv);
 	}
 
+	netdev_stats_to_stats64(stats, &dev->stats);
+
 	if (mlx5e_is_uplink_rep(priv)) {
 		struct mlx5e_vport_stats *vstats = &priv->stats.vport;
 
@@ -3666,21 +3668,21 @@ mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
 		mlx5e_fold_sw_stats64(priv, stats);
 	}
 
-	stats->rx_missed_errors = priv->stats.qcnt.rx_out_of_buffer;
-	stats->rx_dropped = PPORT_2863_GET(pstats, if_in_discards);
+	stats->rx_missed_errors += priv->stats.qcnt.rx_out_of_buffer;
+	stats->rx_dropped += PPORT_2863_GET(pstats, if_in_discards);
 
-	stats->rx_length_errors =
+	stats->rx_length_errors +=
 		PPORT_802_3_GET(pstats, a_in_range_length_errors) +
 		PPORT_802_3_GET(pstats, a_out_of_range_length_field) +
 		PPORT_802_3_GET(pstats, a_frame_too_long_errors) +
 		VNIC_ENV_GET(&priv->stats.vnic, eth_wqe_too_small);
-	stats->rx_crc_errors =
+	stats->rx_crc_errors +=
 		PPORT_802_3_GET(pstats, a_frame_check_sequence_errors);
-	stats->rx_frame_errors = PPORT_802_3_GET(pstats, a_alignment_errors);
-	stats->tx_aborted_errors = PPORT_2863_GET(pstats, if_out_discards);
-	stats->rx_errors = stats->rx_length_errors + stats->rx_crc_errors +
-			   stats->rx_frame_errors;
-	stats->tx_errors = stats->tx_aborted_errors + stats->tx_carrier_errors;
+	stats->rx_frame_errors += PPORT_802_3_GET(pstats, a_alignment_errors);
+	stats->tx_aborted_errors += PPORT_2863_GET(pstats, if_out_discards);
+	stats->rx_errors += stats->rx_length_errors + stats->rx_crc_errors +
+			    stats->rx_frame_errors;
+	stats->tx_errors += stats->tx_aborted_errors + stats->tx_carrier_errors;
 }
 
 static void mlx5e_nic_set_rx_mode(struct mlx5e_priv *priv)
Signature · 1 line
2.51.0
author maintainer
#205 lore raw

PATCH 200/280 nfc: nci: Fix race between rfkill and nci_unregister_device().

In reply to Greg Kroah-Hartman

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

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

From: Kuniyuki Iwashima <[email protected]>

[ Upstream commit d2492688bb9fed6ab6e313682c387ae71a66ebae ]

syzbot reported the splat below [0] without a repro.

It indicates that struct nci_dev.cmd_wq had been destroyed before nci_close_device() was called via rfkill.

nci_dev.cmd_wq is only destroyed in nci_unregister_device(), which (I think) was called from virtual_ncidev_close() when syzbot close()d an fd of virtual_ncidev.

The problem is that nci_unregister_device() destroys nci_dev.cmd_wq first and then calls nfc_unregister_device(), which removes the device from rfkill by rfkill_unregister().

So, the device is still visible via rfkill even after nci_dev.cmd_wq is destroyed.

Let's unregister the device from rfkill first in nci_unregister_device().

Note that we cannot call nfc_unregister_device() before nci_close_device() because

1) nfc_unregister_device() calls device_del() which frees all memory allocated by devm_kzalloc() and linked to ndev->conn_info_list

2) nci_rx_work() could try to queue nci_conn_info to

     ndev->conn_info_list which could be leaked

Thus, nfc_unregister_device() is split into two functions so we can remove rfkill interfaces only before nci_close_device().

[0]:
DEBUG_LOCKS_WARN_ON(1)

WARNING: kernel/locking/lockdep.c:238 at hlock_class kernel/locking/lockdep.c:238 [inline], CPU#0: syz.0.8675/6349
WARNING: kernel/locking/lockdep.c:238 at check_wait_context kernel/locking/lockdep.c:4854 [inline], CPU#0: syz.0.8675/6349
WARNING: kernel/locking/lockdep.c:238 at __lock_acquire+0x39d/0x2cf0 kernel/locking/lockdep.c:5187, CPU#0: syz.0.8675/6349
Modules linked in:
CPU: 0 UID: 0 PID: 6349 Comm: syz.0.8675 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/13/2026
RIP: 0010:hlock_class kernel/locking/lockdep.c:238 [inline]
RIP: 0010:check_wait_context kernel/locking/lockdep.c:4854 [inline]
RIP: 0010:__lock_acquire+0x3a4/0x2cf0 kernel/locking/lockdep.c:5187
Code: 18 00 4c 8b 74 24 08 75 27 90 e8 17 f2 fc 02 85 c0 74 1c 83 3d 50 e0 4e 0e 00 75 13 48 8d 3d 43 f7 51 0e 48 c7 c6 8b 3a de 8d <67> 48 0f b9 3a 90 31 c0 0f b6 98 c4 00 00 00 41 8b 45 20 25 ff 1f
RSP: 0018:ffffc9000c767680 EFLAGS: 00010046
RAX: 0000000000000001 RBX: 0000000000040000 RCX: 0000000000080000
RDX: ffffc90013080000 RSI: ffffffff8dde3a8b RDI: ffffffff8ff24ca0
RBP: 0000000000000003 R08: ffffffff8fef35a3 R09: 1ffffffff1fde6b4
R10: dffffc0000000000 R11: fffffbfff1fde6b5 R12: 00000000000012a2
R13: ffff888030338ba8 R14: ffff888030338000 R15: ffff888030338b30
FS:  00007fa5995f66c0(0000) GS:ffff8881256f8000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f7e72f842d0 CR3: 00000000485a0000 CR4: 00000000003526f0
Call Trace:
 <TASK>
 lock_acquire+0x106/0x330 kernel/locking/lockdep.c:5868
 touch_wq_lockdep_map+0xcb/0x180 kernel/workqueue.c:3940
 __flush_workqueue+0x14b/0x14f0 kernel/workqueue.c:3982
 nci_close_device+0x302/0x630 net/nfc/nci/core.c:567
 nci_dev_down+0x3b/0x50 net/nfc/nci/core.c:639
 nfc_dev_down+0x152/0x290 net/nfc/core.c:161
 nfc_rfkill_set_block+0x2d/0x100 net/nfc/core.c:179
 rfkill_set_block+0x1d2/0x440 net/rfkill/core.c:346
 rfkill_fop_write+0x461/0x5a0 net/rfkill/core.c:1301
 vfs_write+0x29a/0xb90 fs/read_write.c:684
 ksys_write+0x150/0x270 fs/read_write.c:738
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fa59b39acb9
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fa5995f6028 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 00007fa59b615fa0 RCX: 00007fa59b39acb9
RDX: 0000000000000008 RSI: 0000200000000080 RDI: 0000000000000007
RBP: 00007fa59b408bf7 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007fa59b616038 R14: 00007fa59b615fa0 R15: 00007ffc82218788
 </TASK>
---
 include/net/nfc/nfc.h |  2 ++
 net/nfc/core.c        | 27 ++++++++++++++++++++++++---
 net/nfc/nci/core.c    |  4 +++-
 3 files changed, 29 insertions(+), 4 deletions(-)
include/net/nfc/nfc.h +2 -0
index 5dee575fbe86a..b82f4f2a27fb8 100644
@@ -215,6 +215,8 @@ static inline void nfc_free_device(struct nfc_dev *dev)
 
 int nfc_register_device(struct nfc_dev *dev);
 
+void nfc_unregister_rfkill(struct nfc_dev *dev);
+void nfc_remove_device(struct nfc_dev *dev);
 void nfc_unregister_device(struct nfc_dev *dev);
 
 /**
net/nfc/core.c +24 -3
index 5352571b62148..a02ede8b067bd 100644
@@ -1147,14 +1147,14 @@ int nfc_register_device(struct nfc_dev *dev)
 EXPORT_SYMBOL(nfc_register_device);
 
 /**
- * nfc_unregister_device - unregister a nfc device in the nfc subsystem
+ * nfc_unregister_rfkill - unregister a nfc device in the rfkill subsystem
  *
  * @dev: The nfc device to unregister
  */
-void nfc_unregister_device(struct nfc_dev *dev)
+void nfc_unregister_rfkill(struct nfc_dev *dev)
 {
-	int rc;
 	struct rfkill *rfk = NULL;
+	int rc;
 
 	pr_debug("dev_name=%s\n", dev_name(&dev->dev));
 
@@ -1175,7 +1175,16 @@ void nfc_unregister_device(struct nfc_dev *dev)
 		rfkill_unregister(rfk);
 		rfkill_destroy(rfk);
 	}
+}
+EXPORT_SYMBOL(nfc_unregister_rfkill);
 
+/**
+ * nfc_remove_device - remove a nfc device in the nfc subsystem
+ *
+ * @dev: The nfc device to remove
+ */
+void nfc_remove_device(struct nfc_dev *dev)
+{
 	if (dev->ops->check_presence) {
 		del_timer_sync(&dev->check_pres_timer);
 		cancel_work_sync(&dev->check_pres_work);
@@ -1188,6 +1197,18 @@ void nfc_unregister_device(struct nfc_dev *dev)
 	device_del(&dev->dev);
 	mutex_unlock(&nfc_devlist_mutex);
 }
+EXPORT_SYMBOL(nfc_remove_device);
+
+/**
+ * nfc_unregister_device - unregister a nfc device in the nfc subsystem
+ *
+ * @dev: The nfc device to unregister
+ */
+void nfc_unregister_device(struct nfc_dev *dev)
+{
+	nfc_unregister_rfkill(dev);
+	nfc_remove_device(dev);
+}
 EXPORT_SYMBOL(nfc_unregister_device);
 
 static int __init nfc_init(void)
net/nfc/nci/core.c +3 -1
index 6196bb512dfc1..2ffdbbf90eb70 100644
@@ -1291,6 +1291,8 @@ void nci_unregister_device(struct nci_dev *ndev)
 {
 	struct nci_conn_info *conn_info, *n;
 
+	nfc_unregister_rfkill(ndev->nfc_dev);
+
 	/* This set_bit is not protected with specialized barrier,
 	 * However, it is fine because the mutex_lock(&ndev->req_lock);
 	 * in nci_close_device() will help to emit one.
@@ -1308,7 +1310,7 @@ void nci_unregister_device(struct nci_dev *ndev)
 		/* conn_info is allocated with devm_kzalloc */
 	}
 
-	nfc_unregister_device(ndev->nfc_dev);
+	nfc_remove_device(ndev->nfc_dev);
 }
 EXPORT_SYMBOL(nci_unregister_device);
 
Signature · 1 line
2.51.0
author maintainer
#206 lore raw

PATCH 201/280 net: bridge: fix static key check

In reply to Greg Kroah-Hartman

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

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

From: Martin Kaiser <[email protected]>

[ Upstream commit cc0cf10fdaeadf5542d64a55b5b4120d3df90b7d ]

Fix the check if netfilter's static keys are available. netfilter defines and exports static keys if CONFIG_JUMP_LABEL is enabled. (HAVE_JUMP_LABEL is never defined.)

Fixes 971502d77faa ("bridge: netfilter: unroll NF_HOOK helper in bridge input path")
---
 net/bridge/br_input.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/bridge/br_input.c +1 -1
index f11345720c275..e33500771b30f 100644
@@ -243,7 +243,7 @@ static int nf_hook_bridge_pre(struct sk_buff *skb, struct sk_buff **pskb)
 	int ret;
 
 	net = dev_net(skb->dev);
-#ifdef HAVE_JUMP_LABEL
+#ifdef CONFIG_JUMP_LABEL
 	if (!static_key_false(&nf_hooks_needed[NFPROTO_BRIDGE][NF_BR_PRE_ROUTING]))
 		goto frame_finish;
 #endif
Signature · 1 line
2.51.0
author maintainer
#207 lore raw

PATCH 202/280 scsi: firewire: sbp-target: Fix overflow in sbp_make_tpg()

In reply to Greg Kroah-Hartman

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

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

From: Kery Qi <[email protected]>

[ Upstream commit b2d6b1d443009ed4da2d69f5423ab38e5780505a ]

The code in sbp_make_tpg() limits "tpgt" to UINT_MAX but the data type of "tpg->tport_tpgt" is u16. This causes a type truncation issue.

When a user creates a TPG via configfs mkdir, for example:

    mkdir /sys/kernel/config/target/sbp/<wwn>/tpgt_70000

The value 70000 passes the "tpgt > UINT_MAX" check since 70000 is far less than 4294967295. However, when assigned to the u16 field tpg->tport_tpgt, the value is silently truncated to 4464 (70000 & 0xFFFF). This causes the value the user specified to differ from what is actually stored, leading to confusion and potential unexpected behavior.

Fix this by changing the type of "tpgt" to u16 and using kstrtou16() which will properly reject values outside the u16 range.

Fixes a511ce339780 ("sbp-target: Initial merge of firewire/ieee-1394 target mode support")
---
 drivers/target/sbp/sbp_target.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/target/sbp/sbp_target.c +2 -2
index 504670994fb46..97a5565fb14e9 100644
@@ -1986,12 +1986,12 @@ static struct se_portal_group *sbp_make_tpg(struct se_wwn *wwn,
 		container_of(wwn, struct sbp_tport, tport_wwn);
 
 	struct sbp_tpg *tpg;
-	unsigned long tpgt;
+	u16 tpgt;
 	int ret;
 
 	if (strstr(name, "tpgt_") != name)
 		return ERR_PTR(-EINVAL);
-	if (kstrtoul(name + 5, 10, &tpgt) || tpgt > UINT_MAX)
+	if (kstrtou16(name + 5, 10, &tpgt))
 		return ERR_PTR(-EINVAL);
 
 	if (tport->tpg) {
Signature · 1 line
2.51.0
author maintainer
#208 lore raw

PATCH 203/280 ASoC: Intel: sof_es8336: fix headphone GPIO logic inversion

In reply to Greg Kroah-Hartman

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

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

From: Tagir Garaev <[email protected]>

[ Upstream commit 213c4e51267fd825cd21a08a055450cac7e0b7fb ]

The headphone GPIO should be set to the inverse of speaker_en. When speakers are enabled, headphones should be disabled and vice versa.

Currently both GPIOs are set to the same value (speaker_en), causing audio to play through both speakers and headphones simultaneously when headphones are plugged in.

Tested on Huawei Matebook (BOD-WXX9) with ES8336 codec.

Fixes 6e1ff1459e00 ("ASoC: Intel: sof_es8336: support a separate gpio to control headphone")
---
 sound/soc/intel/boards/sof_es8336.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/intel/boards/sof_es8336.c +1 -1
index e22d767b6e97a..41dab5dcf79a3 100644
@@ -120,7 +120,7 @@ static void pcm_pop_work_events(struct work_struct *work)
 	gpiod_set_value_cansleep(priv->gpio_speakers, priv->speaker_en);
 
 	if (quirk & SOF_ES8336_HEADPHONE_GPIO)
-		gpiod_set_value_cansleep(priv->gpio_headphone, priv->speaker_en);
+		gpiod_set_value_cansleep(priv->gpio_headphone, !priv->speaker_en);
 
 }
 
Signature · 1 line
2.51.0
author maintainer
#209 lore raw

PATCH 204/280 gpiolib: acpi: use BIT_ULL() for u64 mask in address space handler

In reply to Greg Kroah-Hartman

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

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

From: Denis Sergeev <[email protected]>

[ Upstream commit c0ae43d303e45764918fa8c1dc13d6a5db59c479 ]

The BIT() macro uses unsigned long, which is 32 bits on 32-bit architectures. When iterating over GPIO pins with index >= 32, the expression (*value & BIT(i)) causes undefined behavior due to shifting by a value >= type width.

Since 'value' is a pointer to u64, use BIT_ULL() to ensure correct 64-bit mask on all architectures.

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

Fixes 2c4d00cb8fc5 ("gpiolib: acpi: Use BIT() macro to increase readability")
---
 drivers/gpio/gpiolib-acpi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpio/gpiolib-acpi.c +1 -1
index baa77a8e83652..11338f47d884d 100644
@@ -1184,7 +1184,7 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
 		mutex_unlock(&achip->conn_lock);
 
 		if (function == ACPI_WRITE)
-			gpiod_set_raw_value_cansleep(desc, !!(*value & BIT(i)));
+			gpiod_set_raw_value_cansleep(desc, !!(*value & BIT_ULL(i)));
 		else
 			*value |= (u64)gpiod_get_raw_value_cansleep(desc) << i;
 	}
Signature · 1 line
2.51.0
author maintainer
#210 lore raw

PATCH 205/280 dma/pool: distinguish between missing and exhausted atomic pools

In reply to Greg Kroah-Hartman

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

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

From: Sai Sree Kartheek Adivi <[email protected]>

[ Upstream commit 56c430c7f06d838fe3b2077dbbc4cc0bf992312b ]

Currently, dma_alloc_from_pool() unconditionally warns and dumps a stack trace when an allocation fails, with the message "Failed to get suitable pool".

This conflates two distinct failure modes:
1. Configuration error: No atomic pool is available for the requested DMA mask (a fundamental system setup issue)
2. Resource Exhaustion: A suitable pool exists but is currently full (a recoverable runtime state)

This lack of distinction prevents drivers from using __GFP_NOWARN to suppress error messages during temporary pressure spikes, such as when awaiting synchronous reclaim of descriptors.

Refactor the error handling to distinguish these cases:
- If no suitable pool is found, keep the unconditional WARN regarding the missing pool.
- If a pool was found but is exhausted, respect __GFP_NOWARN and update the warning message to explicitly state "DMA pool exhausted".

Fixes 9420139f516d ("dma-pool: fix coherent pool allocations for IOMMU mappings")
---
 kernel/dma/pool.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
kernel/dma/pool.c +6 -1
index 1e9d4cb018693..8fc6e3b8f8372 100644
@@ -268,15 +268,20 @@ struct page *dma_alloc_from_pool(struct device *dev, size_t size,
 {
 	struct gen_pool *pool = NULL;
 	struct page *page;
+	bool pool_found = false;
 
 	while ((pool = dma_guess_pool(pool, gfp))) {
+		pool_found = true;
 		page = __dma_alloc_from_pool(dev, size, pool, cpu_addr,
 					     phys_addr_ok);
 		if (page)
 			return page;
 	}
 
-	WARN(1, "Failed to get suitable pool for %s\n", dev_name(dev));
+	if (pool_found)
+		WARN(!(gfp & __GFP_NOWARN), "DMA pool exhausted for %s\n", dev_name(dev));
+	else
+		WARN(1, "Failed to get suitable pool for %s\n", dev_name(dev));
 	return NULL;
 }
 
Signature · 1 line
2.51.0
author maintainer
#211 lore raw

PATCH 206/280 pinctrl: meson: mark the GPIO controller as sleeping

In reply to Greg Kroah-Hartman

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

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

From: Bartosz Golaszewski <[email protected]>

commit 28f24068387169722b508bba6b5257cb68b86e74 upstream.

The GPIO controller is configured as non-sleeping but it uses generic pinctrl helpers which use a mutex for synchronization.

This can cause the following lockdep splat with shared GPIOs enabled on boards which have multiple devices using the same GPIO:

BUG: sleeping function called from invalid context at

kernel/locking/mutex.c:591
in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 142, name:
kworker/u25:3
preempt_count: 1, expected: 0
RCU nest depth: 0, expected: 0
INFO: lockdep is turned off.

irq event stamp: 46379
hardirqs last  enabled at (46379): [<ffff8000813acb24>]
_raw_spin_unlock_irqrestore+0x74/0x78
hardirqs last disabled at (46378): [<ffff8000813abf38>]
_raw_spin_lock_irqsave+0x84/0x88
softirqs last  enabled at (46330): [<ffff8000800c71b4>]
handle_softirqs+0x4c4/0x4dc
softirqs last disabled at (46295): [<ffff800080010674>]
__do_softirq+0x14/0x20
CPU: 1 UID: 0 PID: 142 Comm: kworker/u25:3 Tainted: G C
6.19.0-rc4-next-20260105+ #11963 PREEMPT
Tainted: [C]=CRAP
Hardware name: Khadas VIM3 (DT)
Workqueue: events_unbound deferred_probe_work_func
Call trace:
  show_stack+0x18/0x24 (C)
  dump_stack_lvl+0x90/0xd0
  dump_stack+0x18/0x24
  __might_resched+0x144/0x248
  __might_sleep+0x48/0x98
  __mutex_lock+0x5c/0x894
  mutex_lock_nested+0x24/0x30
  pinctrl_get_device_gpio_range+0x44/0x128
  pinctrl_gpio_set_config+0x40/0xdc
  gpiochip_generic_config+0x28/0x3c
  gpio_do_set_config+0xa8/0x194
  gpiod_set_config+0x34/0xfc
  gpio_shared_proxy_set_config+0x6c/0xfc [gpio_shared_proxy]
  gpio_do_set_config+0xa8/0x194
  gpiod_set_transitory+0x4c/0xf0
  gpiod_configure_flags+0xa4/0x480
  gpiod_find_and_request+0x1a0/0x574
  gpiod_get_index+0x58/0x84
  devm_gpiod_get_index+0x20/0xb4
  devm_gpiod_get+0x18/0x24
  mmc_pwrseq_emmc_probe+0x40/0xb8
  platform_probe+0x5c/0xac
  really_probe+0xbc/0x298
  __driver_probe_device+0x78/0x12c
  driver_probe_device+0xdc/0x164
  __device_attach_driver+0xb8/0x138
  bus_for_each_drv+0x80/0xdc
  __device_attach+0xa8/0x1b0
---
 drivers/pinctrl/meson/pinctrl-meson.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pinctrl/meson/pinctrl-meson.c +1 -1
@@ -619,7 +619,7 @@ static int meson_gpiolib_register(struct
 	pc->chip.set = meson_gpio_set;
 	pc->chip.base = -1;
 	pc->chip.ngpio = pc->data->num_pins;
-	pc->chip.can_sleep = false;
+	pc->chip.can_sleep = true;
 
 	ret = gpiochip_add_data(&pc->chip, pc);
 	if (ret) {
author maintainer
#212 lore raw

PATCH 207/280 riscv: compat: fix COMPAT_UTS_MACHINE definition

In reply to Greg Kroah-Hartman

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

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

From: Han Gao <[email protected]>

commit 0ea05c4f7527a98f5946f96c829733788934311d upstream.

The COMPAT_UTS_MACHINE for riscv was incorrectly defined as "riscv". Change it to "riscv32" to reflect the correct 32-bit compat name.

---
 arch/riscv/include/asm/compat.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/include/asm/compat.h +1 -1
@@ -2,7 +2,7 @@
 #ifndef __ASM_COMPAT_H
 #define __ASM_COMPAT_H
 
-#define COMPAT_UTS_MACHINE	"riscv\0\0"
+#define COMPAT_UTS_MACHINE	"riscv32\0\0"
 
 /*
  * Architecture specific compatibility types
author maintainer
#213 lore raw

PATCH 208/280 ASoC: fsl: imx-card: Do not force slot width to sample width

In reply to Greg Kroah-Hartman

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

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

From: Fabio Estevam <[email protected]>

commit 9210f5ff6318163835d9e42ee68006be4da0f531 upstream.

imx-card currently sets the slot width to the physical sample width for I2S links. This breaks controllers that use fixed-width slots (e.g. 32-bit FIFO words), causing the unused bits in the slot to contain undefined data when playing 16-bit streams.

Do not override the slot width in the machine driver and let the CPU DAI select an appropriate default instead. This matches the behavior of simple-audio-card and avoids embedding controller-specific policy in the machine driver.

On an i.MX8MP-based board using SAI as the I2S master with 32-bit slots, playing 16-bit audio resulted in spurious frequencies and an incorrect SAI data waveform, as the slot width was forced to 16 bits. After this change, audio artifacts are eliminated and the 16-bit samples correctly occupy the first half of the 32-bit slot, with the remaining bits padded with zeroes.

---
 sound/soc/fsl/imx-card.c |    1 -
 1 file changed, 1 deletion(-)
sound/soc/fsl/imx-card.c +0 -1
@@ -314,7 +314,6 @@ static int imx_aif_hw_params(struct snd_
 			      SND_SOC_DAIFMT_PDM;
 		} else {
 			slots = 2;
-			slot_width = params_physical_width(params);
 			fmt = (rtd->dai_link->dai_fmt & ~SND_SOC_DAIFMT_FORMAT_MASK) |
 			      SND_SOC_DAIFMT_I2S;
 		}
author maintainer
#214 lore raw

PATCH 209/280 scsi: be2iscsi: Fix a memory leak in beiscsi_boot_get_sinfo()

In reply to Greg Kroah-Hartman

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

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

From: Haoxiang Li <[email protected]>

commit 4747bafaa50115d9667ece446b1d2d4aba83dc7f upstream.

If nonemb_cmd->va fails to be allocated, free the allocation previously made by alloc_mcc_wrb().

Fixes 50a4b824be9e ("scsi: be2iscsi: Fix to make boot discovery non-blocking")
---
 drivers/scsi/be2iscsi/be_mgmt.c |    1 +
 1 file changed, 1 insertion(+)
drivers/scsi/be2iscsi/be_mgmt.c +1 -0
@@ -1025,6 +1025,7 @@ unsigned int beiscsi_boot_get_sinfo(stru
 					      &nonemb_cmd->dma,
 					      GFP_KERNEL);
 	if (!nonemb_cmd->va) {
+		free_mcc_wrb(ctrl, tag);
 		mutex_unlock(&ctrl->mbox_lock);
 		return 0;
 	}
author maintainer
#215 lore raw

PATCH 210/280 ASoC: amd: yc: Add DMI quirk for Acer TravelMate P216-41-TCO

In reply to Greg Kroah-Hartman

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

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

From: Zhang Heng <[email protected]>

commit 9502b7df5a3c7e174f74f20324ac1fe781fc5c2d upstream.

Add a DMI quirk for the Acer TravelMate P216-41-TCO fixing the issue where the internal microphone was not detected.

---
 sound/soc/amd/yc/acp6x-mach.c |    8 ++++++++
 1 file changed, 8 insertions(+)
sound/soc/amd/yc/acp6x-mach.c +8 -0
@@ -528,6 +528,14 @@ static const struct dmi_system_id yc_acp
 			DMI_MATCH(DMI_PRODUCT_NAME, "GOH-X"),
 		}
 	},
+	{
+		.driver_data = &acp6x_card,
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "RB"),
+			DMI_MATCH(DMI_BOARD_NAME, "XyloD5_RBU"),
+		}
+	},
+
 	{}
 };
 
author maintainer
#216 lore raw

PATCH 211/280 scsi: qla2xxx: edif: Fix dma_free_coherent() size

In reply to Greg Kroah-Hartman

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

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

From: Thomas Fourier <[email protected]>

commit 56bd3c0f749f45793d1eae1d0ddde4255c749bf6 upstream.

Earlier in the function, the ha->flt buffer is allocated with size sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE but freed in the error path with size SFP_DEV_SIZE.

Fixes 84318a9f01ce ("scsi: qla2xxx: edif: Add send, receive, and accept for auth_els")
---
 drivers/scsi/qla2xxx/qla_os.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/qla2xxx/qla_os.c +1 -1
@@ -4464,7 +4464,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha
 fail_elsrej:
 	dma_pool_destroy(ha->purex_dma_pool);
 fail_flt:
-	dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE,
+	dma_free_coherent(&ha->pdev->dev, sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE,
 	    ha->flt, ha->flt_dma);
 
 fail_flt_buffer:
author maintainer
#217 lore raw

PATCH 212/280 efivarfs: fix error propagation in efivar_entry_get()

In reply to Greg Kroah-Hartman

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

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

From: Kohei Enju <[email protected]>

commit 4b22ec1685ce1fc0d862dcda3225d852fb107995 upstream.

efivar_entry_get() always returns success even if the underlying __efivar_entry_get() fails, masking errors.

This may result in uninitialized heap memory being copied to userspace in the efivarfs_file_read() path.

Fix it by returning the error from __efivar_entry_get().

Fixes 2d82e6227ea1 ("efi: vars: Move efivar caching layer into efivarfs")
Cc <[email protected]> # v6.1+
---
 fs/efivarfs/vars.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/efivarfs/vars.c +1 -1
@@ -609,7 +609,7 @@ int efivar_entry_get(struct efivar_entry
 	err = __efivar_entry_get(entry, attributes, size, data);
 	efivar_unlock();
 
-	return 0;
+	return err;
 }
 
 /**
author maintainer
#218 lore raw

PATCH 213/280 mptcp: only reset subflow errors when propagated

In reply to Greg Kroah-Hartman

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

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

From: Matthieu Baerts (NGI0) <[email protected]>

commit dccf46179ddd6c04c14be8ed584dc54665f53f0e upstream.

Some subflow socket errors need to be reported to the MPTCP socket: the initial subflow connect (MP_CAPABLE), and the ones from the fallback sockets. The others are not propagated.

The issue is that sock_error() was used to retrieve the error, which was also resetting the sk_err field. Because of that, when notifying the userspace about subflow close events later on from the MPTCP worker, the ssk->sk_err field was always 0.

Now, the error (sk_err) is only reset when propagating it to the msk.

---
 net/mptcp/protocol.c |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
net/mptcp/protocol.c +5 -4
@@ -807,11 +807,8 @@ static bool __mptcp_ofo_queue(struct mpt
 
 static bool __mptcp_subflow_error_report(struct sock *sk, struct sock *ssk)
 {
-	int err = sock_error(ssk);
 	int ssk_state;
-
-	if (!err)
-		return false;
+	int err;
 
 	/* only propagate errors on fallen-back sockets or
 	 * on MPC connect
@@ -819,6 +816,10 @@ static bool __mptcp_subflow_error_report
 	if (sk->sk_state != TCP_SYN_SENT && !__mptcp_check_fallback(mptcp_sk(sk)))
 		return false;
 
+	err = sock_error(ssk);
+	if (!err)
+		return false;
+
 	/* We need to propagate only transition to CLOSE state.
 	 * Orphaned socket will see such state change via
 	 * subflow_sched_work_if_closed() and that path will properly
author maintainer
#219 lore raw

PATCH 214/280 flex_proportions: make fprop_new_period() hardirq safe

In reply to Greg Kroah-Hartman

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

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

From: Jan Kara <[email protected]>

commit dd9e2f5b38f1fdd49b1ab6d3a85f81c14369eacc upstream.

Bernd has reported a lockdep splat from flexible proportions code that is essentially complaining about the following race:

<timer fires>
run_timer_softirq - we are in softirq context
call_timer_fn

    writeout_period
      fprop_new_period
        write_seqcount_begin(&p->sequence);

        <hardirq is raised>
        ...
        blk_mq_end_request()
	  blk_update_request()
	    ext4_end_bio()
	      folio_end_writeback()
		__wb_writeout_add()
		  __fprop_add_percpu_max()
		    if (unlikely(max_frac < FPROP_FRAC_BASE)) {
		      fprop_fraction_percpu()
			seq = read_seqcount_begin(&p->sequence);
			  - sees odd sequence so loops indefinitely

Note that a deadlock like this is only possible if the bdi has configured maximum fraction of writeout throughput which is very rare in general but frequent for example for FUSE bdis. To fix this problem we have to make sure write section of the sequence counter is irqsafe.

---
 lib/flex_proportions.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
lib/flex_proportions.c +3 -2
index 84ecccddc771..012d5614efb9 100644
@@ -64,13 +64,14 @@ void fprop_global_destroy(struct fprop_global *p)
 bool fprop_new_period(struct fprop_global *p, int periods)
 {
 	s64 events = percpu_counter_sum(&p->events);
+	unsigned long flags;
 
 	/*
 	 * Don't do anything if there are no events.
 	 */
 	if (events <= 1)
 		return false;
-	preempt_disable_nested();
+	local_irq_save(flags);
 	write_seqcount_begin(&p->sequence);
 	if (periods < 64)
 		events -= events >> periods;
@@ -78,7 +79,7 @@ bool fprop_new_period(struct fprop_global *p, int periods)
 	percpu_counter_add(&p->events, -events);
 	p->period += periods;
 	write_seqcount_end(&p->sequence);
-	preempt_enable_nested();
+	local_irq_restore(flags);
 
 	return true;
 }
Signature · 1 line
2.53.0
author maintainer
#220 lore raw

PATCH 215/280 scripts: generate_rust_analyzer: Add compiler_builtins -> core dep

In reply to Greg Kroah-Hartman

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

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

From: Tamir Duberstein <[email protected]>

commit 5157c328edb35bac05ce77da473c3209d20e0bbb upstream.

Add a dependency edge from compiler_builtins to core to scripts/generate_rust_analyzer.py to match rust/Makefile. This has been incorrect since commit 8c4555ccc55c ("scripts: add generate_rust_analyzer.py")

---
 scripts/generate_rust_analyzer.py |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/generate_rust_analyzer.py +1 -1
@@ -73,7 +73,7 @@ def generate_crates(srctree, objtree, sy
     append_crate(
         "compiler_builtins",
         srctree / "rust" / "compiler_builtins.rs",
-        [],
+        ["core"],
     )
 
     append_crate(
author maintainer
#221 lore raw

PATCH 216/280 drm/amdgpu/soc21: fix xclk for APUs

In reply to Greg Kroah-Hartman

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

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

From: Alex Deucher <[email protected]>

commit e7fbff9e7622a00c2b53cb14df481916f0019742 upstream.

The reference clock is supposed to be 100Mhz, but it appears to actually be slightly lower (99.81Mhz).

(cherry picked from commit 637fee3954d4bd509ea9d95ad1780fc174489860)
---
 drivers/gpu/drm/amd/amdgpu/soc21.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/soc21.c +7 -1
@@ -202,7 +202,13 @@ static u32 soc21_get_config_memsize(stru
 
 static u32 soc21_get_xclk(struct amdgpu_device *adev)
 {
-	return adev->clock.spll.reference_freq;
+	u32 reference_clock = adev->clock.spll.reference_freq;
+
+	/* reference clock is actually 99.81 Mhz rather than 100 Mhz */
+	if ((adev->flags & AMD_IS_APU) && reference_clock == 10000)
+		return 9981;
+
+	return reference_clock;
 }
 
 
author maintainer
#222 lore raw

PATCH 217/280 drm/amdgpu/gfx10: fix wptr reset in KGQ init

In reply to Greg Kroah-Hartman

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

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

From: Alex Deucher <[email protected]>

commit cc4f433b14e05eaa4a98fd677b836e9229422387 upstream.

wptr is a 64 bit value and we need to update the full value, not just 32 bits. Align with what we already do for KCQs.

(cherry picked from commit e80b1d1aa1073230b6c25a1a72e88f37e425ccda)
---
 drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +1 -1
@@ -6584,7 +6584,7 @@ static int gfx_v10_0_gfx_init_queue(stru
 			memcpy(mqd, adev->gfx.me.mqd_backup[mqd_idx], sizeof(*mqd));
 		/* reset the ring */
 		ring->wptr = 0;
-		*ring->wptr_cpu_addr = 0;
+		atomic64_set((atomic64_t *)ring->wptr_cpu_addr, 0);
 		amdgpu_ring_clear_ring(ring);
 #ifdef BRING_UP_DEBUG
 		mutex_lock(&adev->srbm_mutex);
author maintainer
#223 lore raw

PATCH 218/280 drm/amdgpu/gfx11: fix wptr reset in KGQ init

In reply to Greg Kroah-Hartman

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

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

From: Alex Deucher <[email protected]>

commit b1f810471c6a6bd349f7f9f2f2fed96082056d46 upstream.

wptr is a 64 bit value and we need to update the full value, not just 32 bits. Align with what we already do for KCQs.

(cherry picked from commit 1f16866bdb1daed7a80ca79ae2837a9832a74fbc)
---
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +1 -1
@@ -3716,7 +3716,7 @@ static int gfx_v11_0_gfx_init_queue(stru
 			memcpy(mqd, adev->gfx.me.mqd_backup[mqd_idx], sizeof(*mqd));
 		/* reset the ring */
 		ring->wptr = 0;
-		*ring->wptr_cpu_addr = 0;
+		atomic64_set((atomic64_t *)ring->wptr_cpu_addr, 0);
 		amdgpu_ring_clear_ring(ring);
 #ifdef BRING_UP_DEBUG
 		mutex_lock(&adev->srbm_mutex);
author maintainer
#224 lore raw

PATCH 219/280 gpio: rockchip: Stop calling pinctrl for set_direction

In reply to Greg Kroah-Hartman

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

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

From: Robin Murphy <[email protected]>

commit 7ca497be00163610afb663867db24ac408752f13 upstream.

Marking the whole controller as sleeping due to the pinctrl calls in the .direction_{input,output} callbacks has the unfortunate side effect that legitimate invocations of .get and .set, which cannot themselves sleep, in atomic context now spew WARN()s from gpiolib.

However, as Heiko points out, the driver doing this is a bit silly to begin with, as the pinctrl .gpio_set_direction hook doesn't even care about the direction, the hook is only used to claim the mux. And sure enough, the .gpio_request_enable hook exists to serve this very purpose, so switch to that and remove the problematic business entirely.

---
 drivers/gpio/gpio-rockchip.c       |    8 --------
 drivers/pinctrl/pinctrl-rockchip.c |    9 ++++-----
 2 files changed, 4 insertions(+), 13 deletions(-)
drivers/gpio/gpio-rockchip.c +0 -8
@@ -19,7 +19,6 @@
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
-#include <linux/pinctrl/consumer.h>
 #include <linux/pinctrl/pinconf-generic.h>
 #include <linux/regmap.h>
 
@@ -157,12 +156,6 @@ static int rockchip_gpio_set_direction(s
 	unsigned long flags;
 	u32 data = input ? 0 : 1;
 
-
-	if (input)
-		pinctrl_gpio_direction_input(bank->pin_base + offset);
-	else
-		pinctrl_gpio_direction_output(bank->pin_base + offset);
-
 	raw_spin_lock_irqsave(&bank->slock, flags);
 	rockchip_gpio_writel_bit(bank, offset, data, bank->gpio_regs->port_ddr);
 	raw_spin_unlock_irqrestore(&bank->slock, flags);
@@ -584,7 +577,6 @@ static int rockchip_gpiolib_register(str
 	gc->ngpio = bank->nr_pins;
 	gc->label = bank->name;
 	gc->parent = bank->dev;
-	gc->can_sleep = true;
 
 	ret = gpiochip_add_data(gc, bank);
 	if (ret) {
drivers/pinctrl/pinctrl-rockchip.c +4 -5
@@ -2750,10 +2750,9 @@ static int rockchip_pmx_set(struct pinct
 	return 0;
 }
 
-static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
-					   struct pinctrl_gpio_range *range,
-					   unsigned offset,
-					   bool input)
+static int rockchip_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
+					    struct pinctrl_gpio_range *range,
+					    unsigned int offset)
 {
 	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
 	struct rockchip_pin_bank *bank;
@@ -2767,7 +2766,7 @@ static const struct pinmux_ops rockchip_
 	.get_function_name	= rockchip_pmx_get_func_name,
 	.get_function_groups	= rockchip_pmx_get_groups,
 	.set_mux		= rockchip_pmx_set,
-	.gpio_set_direction	= rockchip_pmx_gpio_set_direction,
+	.gpio_request_enable	= rockchip_pmx_gpio_request_enable,
 };
 
 /*
author maintainer
#225 lore raw

PATCH 220/280 mm/rmap: fix two comments related to huge_pmd_unshare()

In reply to Greg Kroah-Hartman

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

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

From: "David Hildenbrand (Red Hat)" <[email protected]>

[ Upstream commit a8682d500f691b6dfaa16ae1502d990aeb86e8be ]

PMD page table unsharing no longer touches the refcount of a PMD page table. Also, it is not about dropping the refcount of a "PMD page" but the "PMD page table".

Let's just simplify by saying that the PMD page table was unmapped, consequently also unmapping the folio that was mapped into this page.

This code should be deduplicated in the future.

---
 mm/rmap.c |   20 ++++----------------
 1 file changed, 4 insertions(+), 16 deletions(-)
mm/rmap.c +4 -16
@@ -1574,14 +1574,8 @@ static bool try_to_unmap_one(struct foli
 					mmu_notifier_invalidate_range(mm,
 						range.start, range.end);
 					/*
-					 * The ref count of the PMD page was
-					 * dropped which is part of the way map
-					 * counting is done for shared PMDs.
-					 * Return 'true' here.  When there is
-					 * no other sharing, huge_pmd_unshare
-					 * returns false and we will unmap the
-					 * actual page and drop map count
-					 * to zero.
+					 * The PMD table was unmapped,
+					 * consequently unmapping the folio.
 					 */
 					page_vma_mapped_walk_done(&pvmw);
 					break;
@@ -1965,14 +1959,8 @@ static bool try_to_migrate_one(struct fo
 						range.start, range.end);
 
 					/*
-					 * The ref count of the PMD page was
-					 * dropped which is part of the way map
-					 * counting is done for shared PMDs.
-					 * Return 'true' here.  When there is
-					 * no other sharing, huge_pmd_unshare
-					 * returns false and we will unmap the
-					 * actual page and drop map count
-					 * to zero.
+					 * The PMD table was unmapped,
+					 * consequently unmapping the folio.
 					 */
 					page_vma_mapped_walk_done(&pvmw);
 					break;
author maintainer
#226 lore raw

PATCH 221/280 arm64: dts: rockchip: remove redundant max-link-speed from nanopi-r4s

In reply to Greg Kroah-Hartman

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

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

From: Geraldo Nascimento <[email protected]>

[ Upstream commit ce652c98a7bfa0b7c675ef5cd85c44c186db96af ]

This is already the default in rk3399-base.dtsi, remove redundant declaration from rk3399-nanopi-r4s.dtsi.

Fixes db792e9adbf8 ("rockchip: rk3399: Add support for FriendlyARM NanoPi R4S")
[ adapted file path from rk3399-nanopi-r4s.dtsi to rk3399-nanopi-r4s.dts ]
---
 arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts |    1 -
 1 file changed, 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts +0 -1
@@ -73,7 +73,6 @@
 };
 
 &pcie0 {
-	max-link-speed = <1>;
 	num-lanes = <1>;
 	vpcie3v3-supply = <&vcc3v3_sys>;
 };
author maintainer
#227 lore raw

PATCH 222/280 xen: make remove callback of xen driver void returned

In reply to Greg Kroah-Hartman

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

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

From: Dawei Li <[email protected]>

[ Upstream commit 7cffcade57a429667447c4f41d8414bbcf1b3aaa ]

Since commit fc7a6209d571 ("bus: Make remove callback return void") forces bus_type::remove be void-returned, it doesn't make much sense for any bus based driver implementing remove callbalk to return non-void to its caller.

This change is for xen bus based drivers.

Stable-dep-of: 901a5f309dab ("scsi: xen: scsiback: Fix potential memory leak in scsiback_remove()")

---
 drivers/block/xen-blkback/xenbus.c  |    4 +---
 drivers/block/xen-blkfront.c        |    3 +--
 drivers/char/tpm/xen-tpmfront.c     |    3 +--
 drivers/gpu/drm/xen/xen_drm_front.c |    3 +--
 drivers/input/misc/xen-kbdfront.c   |    5 ++---
 drivers/net/xen-netback/xenbus.c    |    3 +--
 drivers/net/xen-netfront.c          |    4 +---
 drivers/pci/xen-pcifront.c          |    4 +---
 drivers/scsi/xen-scsifront.c        |    4 +---
 drivers/tty/hvc/hvc_xen.c           |    4 ++--
 drivers/usb/host/xen-hcd.c          |    4 +---
 drivers/video/fbdev/xen-fbfront.c   |    6 ++----
 drivers/xen/pvcalls-back.c          |    3 +--
 drivers/xen/pvcalls-front.c         |    3 +--
 drivers/xen/xen-pciback/xenbus.c    |    4 +---
 drivers/xen/xen-scsiback.c          |    4 +---
 include/xen/xenbus.h                |    2 +-
 net/9p/trans_xen.c                  |    3 +--
 sound/xen/xen_snd_front.c           |    3 +--
 19 files changed, 22 insertions(+), 47 deletions(-)
drivers/block/xen-blkback/xenbus.c +1 -3
@@ -524,7 +524,7 @@ static int xen_vbd_create(struct xen_blk
 	return 0;
 }
 
-static int xen_blkbk_remove(struct xenbus_device *dev)
+static void xen_blkbk_remove(struct xenbus_device *dev)
 {
 	struct backend_info *be = dev_get_drvdata(&dev->dev);
 
@@ -547,8 +547,6 @@ static int xen_blkbk_remove(struct xenbu
 		/* Put the reference we set in xen_blkif_alloc(). */
 		xen_blkif_put(be->blkif);
 	}
-
-	return 0;
 }
 
 int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt,
drivers/block/xen-blkfront.c +1 -2
@@ -2469,7 +2469,7 @@ static void blkback_changed(struct xenbu
 	}
 }
 
-static int blkfront_remove(struct xenbus_device *xbdev)
+static void blkfront_remove(struct xenbus_device *xbdev)
 {
 	struct blkfront_info *info = dev_get_drvdata(&xbdev->dev);
 
@@ -2490,7 +2490,6 @@ static int blkfront_remove(struct xenbus
 	}
 
 	kfree(info);
-	return 0;
 }
 
 static int blkfront_is_ready(struct xenbus_device *dev)
drivers/char/tpm/xen-tpmfront.c +1 -2
@@ -360,14 +360,13 @@ static int tpmfront_probe(struct xenbus_
 	return tpm_chip_register(priv->chip);
 }
 
-static int tpmfront_remove(struct xenbus_device *dev)
+static void tpmfront_remove(struct xenbus_device *dev)
 {
 	struct tpm_chip *chip = dev_get_drvdata(&dev->dev);
 	struct tpm_private *priv = dev_get_drvdata(&chip->dev);
 	tpm_chip_unregister(chip);
 	ring_free(priv);
 	dev_set_drvdata(&chip->dev, NULL);
-	return 0;
 }
 
 static int tpmfront_resume(struct xenbus_device *dev)
drivers/gpu/drm/xen/xen_drm_front.c +1 -2
@@ -717,7 +717,7 @@ static int xen_drv_probe(struct xenbus_d
 	return xenbus_switch_state(xb_dev, XenbusStateInitialising);
 }
 
-static int xen_drv_remove(struct xenbus_device *dev)
+static void xen_drv_remove(struct xenbus_device *dev)
 {
 	struct xen_drm_front_info *front_info = dev_get_drvdata(&dev->dev);
 	int to = 100;
@@ -751,7 +751,6 @@ static int xen_drv_remove(struct xenbus_
 
 	xen_drm_drv_fini(front_info);
 	xenbus_frontend_closed(dev);
-	return 0;
 }
 
 static const struct xenbus_device_id xen_driver_ids[] = {
drivers/input/misc/xen-kbdfront.c +2 -3
@@ -51,7 +51,7 @@ module_param_array(ptr_size, int, NULL,
 MODULE_PARM_DESC(ptr_size,
 	"Pointing device width, height in pixels (default 800,600)");
 
-static int xenkbd_remove(struct xenbus_device *);
+static void xenkbd_remove(struct xenbus_device *);
 static int xenkbd_connect_backend(struct xenbus_device *, struct xenkbd_info *);
 static void xenkbd_disconnect_backend(struct xenkbd_info *);
 
@@ -404,7 +404,7 @@ static int xenkbd_resume(struct xenbus_d
 	return xenkbd_connect_backend(dev, info);
 }
 
-static int xenkbd_remove(struct xenbus_device *dev)
+static void xenkbd_remove(struct xenbus_device *dev)
 {
 	struct xenkbd_info *info = dev_get_drvdata(&dev->dev);
 
@@ -417,7 +417,6 @@ static int xenkbd_remove(struct xenbus_d
 		input_unregister_device(info->mtouch);
 	free_page((unsigned long)info->page);
 	kfree(info);
-	return 0;
 }
 
 static int xenkbd_connect_backend(struct xenbus_device *dev,
drivers/net/xen-netback/xenbus.c +1 -2
@@ -977,7 +977,7 @@ static int read_xenbus_vif_flags(struct
 	return 0;
 }
 
-static int netback_remove(struct xenbus_device *dev)
+static void netback_remove(struct xenbus_device *dev)
 {
 	struct backend_info *be = dev_get_drvdata(&dev->dev);
 
@@ -992,7 +992,6 @@ static int netback_remove(struct xenbus_
 	kfree(be->hotplug_script);
 	kfree(be);
 	dev_set_drvdata(&dev->dev, NULL);
-	return 0;
 }
 
 /*
drivers/net/xen-netfront.c +1 -3
@@ -2652,7 +2652,7 @@ static void xennet_bus_close(struct xenb
 	} while (!ret);
 }
 
-static int xennet_remove(struct xenbus_device *dev)
+static void xennet_remove(struct xenbus_device *dev)
 {
 	struct netfront_info *info = dev_get_drvdata(&dev->dev);
 
@@ -2668,8 +2668,6 @@ static int xennet_remove(struct xenbus_d
 		rtnl_unlock();
 	}
 	xennet_free_netdev(info->netdev);
-
-	return 0;
 }
 
 static const struct xenbus_device_id netfront_ids[] = {
drivers/pci/xen-pcifront.c +1 -3
@@ -1055,14 +1055,12 @@ out:
 	return err;
 }
 
-static int pcifront_xenbus_remove(struct xenbus_device *xdev)
+static void pcifront_xenbus_remove(struct xenbus_device *xdev)
 {
 	struct pcifront_device *pdev = dev_get_drvdata(&xdev->dev);
 
 	if (pdev)
 		free_pdev(pdev);
-
-	return 0;
 }
 
 static const struct xenbus_device_id xenpci_ids[] = {
drivers/scsi/xen-scsifront.c +1 -3
@@ -995,7 +995,7 @@ static int scsifront_suspend(struct xenb
 	return err;
 }
 
-static int scsifront_remove(struct xenbus_device *dev)
+static void scsifront_remove(struct xenbus_device *dev)
 {
 	struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev);
 
@@ -1011,8 +1011,6 @@ static int scsifront_remove(struct xenbu
 
 	scsifront_free_ring(info);
 	scsi_host_put(info->host);
-
-	return 0;
 }
 
 static void scsifront_disconnect(struct vscsifrnt_info *info)
drivers/tty/hvc/hvc_xen.c +2 -2
@@ -420,9 +420,9 @@ static int xen_console_remove(struct xen
 	return 0;
 }
 
-static int xencons_remove(struct xenbus_device *dev)
+static void xencons_remove(struct xenbus_device *dev)
 {
-	return xen_console_remove(dev_get_drvdata(&dev->dev));
+	xen_console_remove(dev_get_drvdata(&dev->dev));
 }
 
 static int xencons_connect_backend(struct xenbus_device *dev,
drivers/usb/host/xen-hcd.c +1 -3
@@ -1530,15 +1530,13 @@ static void xenhcd_backend_changed(struc
 	}
 }
 
-static int xenhcd_remove(struct xenbus_device *dev)
+static void xenhcd_remove(struct xenbus_device *dev)
 {
 	struct xenhcd_info *info = dev_get_drvdata(&dev->dev);
 	struct usb_hcd *hcd = xenhcd_info_to_hcd(info);
 
 	xenhcd_destroy_rings(info);
 	usb_put_hcd(hcd);
-
-	return 0;
 }
 
 static int xenhcd_probe(struct xenbus_device *dev,
drivers/video/fbdev/xen-fbfront.c +2 -4
@@ -67,7 +67,7 @@ MODULE_PARM_DESC(video,
 	"Video memory size in MB, width, height in pixels (default 2,800,600)");
 
 static void xenfb_make_preferred_console(void);
-static int xenfb_remove(struct xenbus_device *);
+static void xenfb_remove(struct xenbus_device *);
 static void xenfb_init_shared_page(struct xenfb_info *, struct fb_info *);
 static int xenfb_connect_backend(struct xenbus_device *, struct xenfb_info *);
 static void xenfb_disconnect_backend(struct xenfb_info *);
@@ -527,7 +527,7 @@ static int xenfb_resume(struct xenbus_de
 	return xenfb_connect_backend(dev, info);
 }
 
-static int xenfb_remove(struct xenbus_device *dev)
+static void xenfb_remove(struct xenbus_device *dev)
 {
 	struct xenfb_info *info = dev_get_drvdata(&dev->dev);
 
@@ -542,8 +542,6 @@ static int xenfb_remove(struct xenbus_de
 	vfree(info->gfns);
 	vfree(info->fb);
 	kfree(info);
-
-	return 0;
 }
 
 static unsigned long vmalloc_to_gfn(void *address)
drivers/xen/pvcalls-back.c +1 -2
@@ -1180,9 +1180,8 @@ static void pvcalls_back_changed(struct
 	}
 }
 
-static int pvcalls_back_remove(struct xenbus_device *dev)
+static void pvcalls_back_remove(struct xenbus_device *dev)
 {
-	return 0;
 }
 
 static int pvcalls_back_uevent(struct xenbus_device *xdev,
drivers/xen/pvcalls-front.c +1 -2
@@ -1087,7 +1087,7 @@ static const struct xenbus_device_id pvc
 	{ "" }
 };
 
-static int pvcalls_front_remove(struct xenbus_device *dev)
+static void pvcalls_front_remove(struct xenbus_device *dev)
 {
 	struct pvcalls_bedata *bedata;
 	struct sock_mapping *map = NULL, *n;
@@ -1123,7 +1123,6 @@ static int pvcalls_front_remove(struct x
 	kfree(bedata->ring.sring);
 	kfree(bedata);
 	xenbus_switch_state(dev, XenbusStateClosed);
-	return 0;
 }
 
 static int pvcalls_front_probe(struct xenbus_device *dev,
drivers/xen/xen-pciback/xenbus.c +1 -3
@@ -716,14 +716,12 @@ out:
 	return err;
 }
 
-static int xen_pcibk_xenbus_remove(struct xenbus_device *dev)
+static void xen_pcibk_xenbus_remove(struct xenbus_device *dev)
 {
 	struct xen_pcibk_device *pdev = dev_get_drvdata(&dev->dev);
 
 	if (pdev != NULL)
 		free_pdev(pdev);
-
-	return 0;
 }
 
 static const struct xenbus_device_id xen_pcibk_ids[] = {
drivers/xen/xen-scsiback.c +1 -3
@@ -1249,7 +1249,7 @@ static void scsiback_release_translation
 	spin_unlock_irqrestore(&info->v2p_lock, flags);
 }
 
-static int scsiback_remove(struct xenbus_device *dev)
+static void scsiback_remove(struct xenbus_device *dev)
 {
 	struct vscsibk_info *info = dev_get_drvdata(&dev->dev);
 
@@ -1261,8 +1261,6 @@ static int scsiback_remove(struct xenbus
 	gnttab_page_cache_shrink(&info->free_pages, 0);
 
 	dev_set_drvdata(&dev->dev, NULL);
-
-	return 0;
 }
 
 static int scsiback_probe(struct xenbus_device *dev,
include/xen/xenbus.h +1 -1
@@ -117,7 +117,7 @@ struct xenbus_driver {
 		     const struct xenbus_device_id *id);
 	void (*otherend_changed)(struct xenbus_device *dev,
 				 enum xenbus_state backend_state);
-	int (*remove)(struct xenbus_device *dev);
+	void (*remove)(struct xenbus_device *dev);
 	int (*suspend)(struct xenbus_device *dev);
 	int (*resume)(struct xenbus_device *dev);
 	int (*uevent)(struct xenbus_device *, struct kobj_uevent_env *);
net/9p/trans_xen.c +1 -2
@@ -307,13 +307,12 @@ static void xen_9pfs_front_free(struct x
 	kfree(priv);
 }
 
-static int xen_9pfs_front_remove(struct xenbus_device *dev)
+static void xen_9pfs_front_remove(struct xenbus_device *dev)
 {
 	struct xen_9pfs_front_priv *priv = dev_get_drvdata(&dev->dev);
 
 	dev_set_drvdata(&dev->dev, NULL);
 	xen_9pfs_front_free(priv);
-	return 0;
 }
 
 static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev,
sound/xen/xen_snd_front.c +1 -2
@@ -311,7 +311,7 @@ static int xen_drv_probe(struct xenbus_d
 	return xenbus_switch_state(xb_dev, XenbusStateInitialising);
 }
 
-static int xen_drv_remove(struct xenbus_device *dev)
+static void xen_drv_remove(struct xenbus_device *dev)
 {
 	struct xen_snd_front_info *front_info = dev_get_drvdata(&dev->dev);
 	int to = 100;
@@ -345,7 +345,6 @@ static int xen_drv_remove(struct xenbus_
 
 	xen_snd_drv_fini(front_info);
 	xenbus_frontend_closed(dev);
-	return 0;
 }
 
 static const struct xenbus_device_id xen_drv_ids[] = {
author maintainer
#228 lore raw

PATCH 223/280 scsi: xen: scsiback: Fix potential memory leak in scsiback_remove()

In reply to Greg Kroah-Hartman

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

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

From: Abdun Nihaal <[email protected]>

[ Upstream commit 901a5f309daba412e2a30364d7ec1492fa11c32c ]

Memory allocated for struct vscsiblk_info in scsiback_probe() is not freed in scsiback_remove() leading to potential memory leaks on remove, as well as in the scsiback_probe() error paths. Fix that by freeing it in scsiback_remove().

---
 drivers/xen/xen-scsiback.c |    1 +
 1 file changed, 1 insertion(+)
drivers/xen/xen-scsiback.c +1 -0
@@ -1261,6 +1261,7 @@ static void scsiback_remove(struct xenbu
 	gnttab_page_cache_shrink(&info->free_pages, 0);
 
 	dev_set_drvdata(&dev->dev, NULL);
+	kfree(info);
 }
 
 static int scsiback_probe(struct xenbus_device *dev,
author maintainer
#229 lore raw

PATCH 224/280 dmaengine: stm32: dmamux: fix OF node leak on route allocation failure

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

[ Upstream commit b1b590a590af13ded598e70f0b72bc1e515787a1 ]

Make sure to drop the reference taken to the DMA master OF node also on late route allocation failures.

---
 drivers/dma/stm32-dmamux.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/dma/stm32-dmamux.c +3 -1
@@ -140,7 +140,7 @@ static void *stm32_dmamux_route_allocate
 	ret = pm_runtime_resume_and_get(&pdev->dev);
 	if (ret < 0) {
 		spin_unlock_irqrestore(&dmamux->lock, flags);
-		goto error;
+		goto err_put_dma_spec_np;
 	}
 	spin_unlock_irqrestore(&dmamux->lock, flags);
 
@@ -160,6 +160,8 @@ static void *stm32_dmamux_route_allocate
 
 	return mux;
 
+err_put_dma_spec_np:
+	of_node_put(dma_spec->np);
 error:
 	clear_bit(mux->chan_id, dmamux->dma_inuse);
 
author maintainer
#230 lore raw

PATCH 225/280 mm/page_alloc: prevent pcp corruption with SMP=n

In reply to Greg Kroah-Hartman

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

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

From: Vlastimil Babka <[email protected]>

[ Upstream commit 038a102535eb49e10e93eafac54352fcc5d78847 ]

The kernel test robot has reported:

 BUG: spinlock trylock failure on UP on CPU#0, kcompactd0/28
  lock: 0xffff888807e35ef0, .magic: dead4ead, .owner: kcompactd0/28, .owner_cpu: 0
 CPU: 0 UID: 0 PID: 28 Comm: kcompactd0 Not tainted 6.18.0-rc5-00127-ga06157804399 #1 PREEMPT  8cc09ef94dcec767faa911515ce9e609c45db470
 Call Trace:
  <IRQ>
  __dump_stack (lib/dump_stack.c:95)
  dump_stack_lvl (lib/dump_stack.c:123)
  dump_stack (lib/dump_stack.c:130)
  spin_dump (kernel/locking/spinlock_debug.c:71)
  do_raw_spin_trylock (kernel/locking/spinlock_debug.c:?)
  _raw_spin_trylock (include/linux/spinlock_api_smp.h:89 kernel/locking/spinlock.c:138)
  __free_frozen_pages (mm/page_alloc.c:2973)
  ___free_pages (mm/page_alloc.c:5295)
  __free_pages (mm/page_alloc.c:5334)
  tlb_remove_table_rcu (include/linux/mm.h:? include/linux/mm.h:3122 include/asm-generic/tlb.h:220 mm/mmu_gather.c:227 mm/mmu_gather.c:290)
  ? __cfi_tlb_remove_table_rcu (mm/mmu_gather.c:289)
  ? rcu_core (kernel/rcu/tree.c:?)
  rcu_core (include/linux/rcupdate.h:341 kernel/rcu/tree.c:2607 kernel/rcu/tree.c:2861)
  rcu_core_si (kernel/rcu/tree.c:2879)
  handle_softirqs (arch/x86/include/asm/jump_label.h:36 include/trace/events/irq.h:142 kernel/softirq.c:623)
  __irq_exit_rcu (arch/x86/include/asm/jump_label.h:36 kernel/softirq.c:725)
  irq_exit_rcu (kernel/softirq.c:741)
  sysvec_apic_timer_interrupt (arch/x86/kernel/apic/apic.c:1052)
  </IRQ>
  <TASK>
 RIP: 0010:_raw_spin_unlock_irqrestore (arch/x86/include/asm/preempt.h:95 include/linux/spinlock_api_smp.h:152 kernel/locking/spinlock.c:194)
  free_pcppages_bulk (mm/page_alloc.c:1494)
  drain_pages_zone (include/linux/spinlock.h:391 mm/page_alloc.c:2632)
  __drain_all_pages (mm/page_alloc.c:2731)
  drain_all_pages (mm/page_alloc.c:2747)
  kcompactd (mm/compaction.c:3115)
  kthread (kernel/kthread.c:465)
  ? __cfi_kcompactd (mm/compaction.c:3166)
  ? __cfi_kthread (kernel/kthread.c:412)
  ret_from_fork (arch/x86/kernel/process.c:164)
  ? __cfi_kthread (kernel/kthread.c:412)
  ret_from_fork_asm (arch/x86/entry/entry_64.S:255)
  </TASK>

Matthew has analyzed the report and identified that in drain_page_zone() we are in a section protected by spin_lock(&pcp->lock) and then get an interrupt that attempts spin_trylock() on the same lock. The code is designed to work this way without disabling IRQs and occasionally fail the trylock with a fallback. However, the SMP=n spinlock implementation assumes spin_trylock() will always succeed, and thus it's normally a no-op. Here the enabled lock debugging catches the problem, but otherwise it could cause a corruption of the pcp structure.

The problem has been introduced by commit 574907741599 ("mm/page_alloc:
leave IRQs enabled for per-cpu page allocations"). The pcp locking scheme recognizes the need for disabling IRQs to prevent nesting spin_trylock() sections on SMP=n, but the need to prevent the nesting in spin_lock() has not been recognized. Fix it by introducing local wrappers that change the spin_lock() to spin_lock_iqsave() with SMP=n and use them in all places that do spin_lock(&pcp->lock).

[[email protected]: add pcp_ prefix to the spin_lock_irqsave wrappers, per Steven]
Fixes 574907741599 ("mm/page_alloc: leave IRQs enabled for per-cpu page allocations")
Cc Brendan Jackman <[email protected]>
Cc Johannes Weiner <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Sebastian Andrzej Siewior <[email protected]>
Cc Steven Rostedt <[email protected]>
Cc Suren Baghdasaryan <[email protected]>
Cc Zi Yan <[email protected]>
[ drop changes to decay_pcp_high() and zone_pcp_update_cacheinfo() ]
---
 mm/page_alloc.c |   37 +++++++++++++++++++++++++++++++++----
 1 file changed, 33 insertions(+), 4 deletions(-)
mm/page_alloc.c +33 -4
@@ -198,6 +198,33 @@ static DEFINE_MUTEX(pcp_batch_high_lock)
 #define pcp_spin_unlock(ptr)						\
 	pcpu_spin_unlock(lock, ptr)
 
+/*
+ * With the UP spinlock implementation, when we spin_lock(&pcp->lock) (for i.e.
+ * a potentially remote cpu drain) and get interrupted by an operation that
+ * attempts pcp_spin_trylock(), we can't rely on the trylock failure due to UP
+ * spinlock assumptions making the trylock a no-op. So we have to turn that
+ * spin_lock() to a spin_lock_irqsave(). This works because on UP there are no
+ * remote cpu's so we can only be locking the only existing local one.
+ */
+#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)
+static inline void __flags_noop(unsigned long *flags) { }
+#define pcp_spin_lock_maybe_irqsave(ptr, flags)		\
+({							\
+	 __flags_noop(&(flags));			\
+	 spin_lock(&(ptr)->lock);			\
+})
+#define pcp_spin_unlock_maybe_irqrestore(ptr, flags)	\
+({							\
+	 spin_unlock(&(ptr)->lock);			\
+	 __flags_noop(&(flags));			\
+})
+#else
+#define pcp_spin_lock_maybe_irqsave(ptr, flags)		\
+		spin_lock_irqsave(&(ptr)->lock, flags)
+#define pcp_spin_unlock_maybe_irqrestore(ptr, flags)	\
+		spin_unlock_irqrestore(&(ptr)->lock, flags)
+#endif
+
 #ifdef CONFIG_USE_PERCPU_NUMA_NODE_ID
 DEFINE_PER_CPU(int, numa_node);
 EXPORT_PER_CPU_SYMBOL(numa_node);
@@ -3174,14 +3201,15 @@ static int rmqueue_bulk(struct zone *zon
  */
 void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp)
 {
+	unsigned long UP_flags;
 	int to_drain, batch;
 
 	batch = READ_ONCE(pcp->batch);
 	to_drain = min(pcp->count, batch);
 	if (to_drain > 0) {
-		spin_lock(&pcp->lock);
+		pcp_spin_lock_maybe_irqsave(pcp, UP_flags);
 		free_pcppages_bulk(zone, to_drain, pcp, 0);
-		spin_unlock(&pcp->lock);
+		pcp_spin_unlock_maybe_irqrestore(pcp, UP_flags);
 	}
 }
 #endif
@@ -3192,10 +3220,11 @@ void drain_zone_pages(struct zone *zone,
 static void drain_pages_zone(unsigned int cpu, struct zone *zone)
 {
 	struct per_cpu_pages *pcp = per_cpu_ptr(zone->per_cpu_pageset, cpu);
+	unsigned long UP_flags;
 	int count;
 
 	do {
-		spin_lock(&pcp->lock);
+		pcp_spin_lock_maybe_irqsave(pcp, UP_flags);
 		count = pcp->count;
 		if (count) {
 			int to_drain = min(count,
@@ -3204,7 +3233,7 @@ static void drain_pages_zone(unsigned in
 			free_pcppages_bulk(zone, to_drain, pcp, 0);
 			count -= to_drain;
 		}
-		spin_unlock(&pcp->lock);
+		pcp_spin_unlock_maybe_irqrestore(pcp, UP_flags);
 	} while (count);
 }
 
author maintainer
#231 lore raw

PATCH 226/280 dmaengine: stm32: dmamux: fix device leak on route allocation

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

[ Upstream commit dd6e4943889fb354efa3f700e42739da9bddb6ef ]

Make sure to drop the reference taken when looking up the DMA mux platform device during route allocation.

Note that holding a reference to a device does not prevent its driver data from going away so there is no point in keeping the reference.

---
 drivers/dma/stm32-dmamux.c |   18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)
drivers/dma/stm32-dmamux.c +12 -6
@@ -88,23 +88,25 @@ static void *stm32_dmamux_route_allocate
 	struct stm32_dmamux_data *dmamux = platform_get_drvdata(pdev);
 	struct stm32_dmamux *mux;
 	u32 i, min, max;
-	int ret;
+	int ret = -EINVAL;
 	unsigned long flags;
 
 	if (dma_spec->args_count != 3) {
 		dev_err(&pdev->dev, "invalid number of dma mux args\n");
-		return ERR_PTR(-EINVAL);
+		goto err_put_pdev;
 	}
 
 	if (dma_spec->args[0] > dmamux->dmamux_requests) {
 		dev_err(&pdev->dev, "invalid mux request number: %d\n",
 			dma_spec->args[0]);
-		return ERR_PTR(-EINVAL);
+		goto err_put_pdev;
 	}
 
 	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
-	if (!mux)
-		return ERR_PTR(-ENOMEM);
+	if (!mux) {
+		ret = -ENOMEM;
+		goto err_put_pdev;
+	}
 
 	spin_lock_irqsave(&dmamux->lock, flags);
 	mux->chan_id = find_first_zero_bit(dmamux->dma_inuse,
@@ -131,7 +133,6 @@ static void *stm32_dmamux_route_allocate
 	dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", i - 1);
 	if (!dma_spec->np) {
 		dev_err(&pdev->dev, "can't get dma master\n");
-		ret = -EINVAL;
 		goto error;
 	}
 
@@ -158,6 +159,8 @@ static void *stm32_dmamux_route_allocate
 	dev_dbg(&pdev->dev, "Mapping DMAMUX(%u) to DMA%u(%u)\n",
 		mux->request, mux->master, mux->chan_id);
 
+	put_device(&pdev->dev);
+
 	return mux;
 
 err_put_dma_spec_np:
@@ -167,6 +170,9 @@ error:
 
 error_chan_id:
 	kfree(mux);
+err_put_pdev:
+	put_device(&pdev->dev);
+
 	return ERR_PTR(ret);
 }
 
author maintainer
#232 lore raw

PATCH 227/280 mm: kmsan: fix poisoning of high-order non-compound pages

In reply to Greg Kroah-Hartman

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

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

From: Ryan Roberts <[email protected]>

[ Upstream commit 4795d205d78690a46b60164f44b8bb7b3e800865 ]

kmsan_free_page() is called by the page allocator's free_pages_prepare() during page freeing. Its job is to poison all the memory covered by the page. It can be called with an order-0 page, a compound high-order page or a non-compound high-order page. But page_size() only works for order-0 and compound pages. For a non-compound high-order page it will incorrectly return PAGE_SIZE.

The implication is that the tail pages of a high-order non-compound page do not get poisoned at free, so any invalid access while they are free could go unnoticed. It looks like the pages will be poisoned again at allocation time, so that would bookend the window.

Fix this by using the order parameter to calculate the size.

---
 mm/kmsan/shadow.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
mm/kmsan/shadow.c +1 -2
@@ -209,8 +209,7 @@ void kmsan_free_page(struct page *page,
 	if (!kmsan_enabled || kmsan_in_runtime())
 		return;
 	kmsan_enter_runtime();
-	kmsan_internal_poison_memory(page_address(page),
-				     PAGE_SIZE << compound_order(page),
+	kmsan_internal_poison_memory(page_address(page), PAGE_SIZE << order,
 				     GFP_KERNEL,
 				     KMSAN_POISON_CHECK | KMSAN_POISON_FREE);
 	kmsan_leave_runtime();
author maintainer
#233 lore raw

PATCH 228/280 xfs: set max_agbno to allow sparse alloc of last full inode chunk

In reply to Greg Kroah-Hartman

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

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

From: Brian Foster <[email protected]>

[ Upstream commit c360004c0160dbe345870f59f24595519008926f ]

Sparse inode cluster allocation sets min/max agbno values to avoid allocating an inode cluster that might map to an invalid inode chunk. For example, we can't have an inode record mapped to agbno 0 or that extends past the end of a runt AG of misaligned size.

The initial calculation of max_agbno is unnecessarily conservative, however. This has triggered a corner case allocation failure where a small runt AG (i.e. 2063 blocks) is mostly full save for an extent to the EOFS boundary: [2050,13]. max_agbno is set to 2048 in this case, which happens to be the offset of the last possible valid inode chunk in the AG. In practice, we should be able to allocate the 4-block cluster at agbno 2052 to map to the parent inode record at agbno 2048, but the max_agbno value precludes it.

Note that this can result in filesystem shutdown via dirty trans cancel on stable kernels prior to commit 9eb775968b68 ("xfs: walk all AGs if TRYLOCK passed to xfs_alloc_vextent_iterate_ags") because the tail AG selection by the allocator sets t_highest_agno on the transaction. If the inode allocator spins around and finds an inode chunk with free inodes in an earlier AG, the subsequent dir name creation path may still fail to allocate due to the AG restriction and cancel.

To avoid this problem, update the max_agbno calculation to the agbno prior to the last chunk aligned agbno in the AG. This is not necessarily the last valid allocation target for a sparse chunk, but since inode chunks (i.e. records) are chunk aligned and sparse allocs are cluster sized/aligned, this allows the sb_spino_align alignment restriction to take over and round down the max effective agbno to within the last valid inode chunk in the AG.

Note that even though the allocator improvements in the aforementioned commit seem to avoid this particular dirty trans cancel situation, the max_agbno logic improvement still applies as we should be able to allocate from an AG that has been appropriately selected. The more important target for this patch however are older/stable kernels prior to this allocator rework/improvement.

Fixes 56d1115c9bc7 ("xfs: allocate sparse inode chunks on full chunk allocation failure")
[ xfs_ag_block_count(args.mp, pag_agno(pag)) => args.mp->m_sb.sb_agblocks ]
---
 fs/xfs/libxfs/xfs_ialloc.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
fs/xfs/libxfs/xfs_ialloc.c +6 -5
@@ -772,14 +772,15 @@ sparse_alloc:
 		 * invalid inode records, such as records that start at agbno 0
 		 * or extend beyond the AG.
 		 *
-		 * Set min agbno to the first aligned, non-zero agbno and max to
-		 * the last aligned agbno that is at least one full chunk from
-		 * the end of the AG.
+		 * Set min agbno to the first chunk aligned, non-zero agbno and
+		 * max to one less than the last chunk aligned agbno from the
+		 * end of the AG. We subtract 1 from max so that the cluster
+		 * allocation alignment takes over and allows allocation within
+		 * the last full inode chunk in the AG.
 		 */
 		args.min_agbno = args.mp->m_sb.sb_inoalignmt;
 		args.max_agbno = round_down(args.mp->m_sb.sb_agblocks,
-					    args.mp->m_sb.sb_inoalignmt) -
-				 igeo->ialloc_blks;
+					    args.mp->m_sb.sb_inoalignmt) - 1;
 
 		error = xfs_alloc_vextent(&args);
 		if (error)
author maintainer
#234 lore raw

PATCH 229/280 pmdomain: imx8m-blk-ctrl: Remove separate rst and clk mask for 8mq vpu

In reply to Greg Kroah-Hartman

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

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

From: Ming Qian <[email protected]>

[ Upstream commit 3de49966499634454fd59e0e6fecd50baab7febd ]

For i.MX8MQ platform, the ADB in the VPUMIX domain has no separate reset and clock enable bits, but is ungated and reset together with the VPUs. So we can't reset G1 or G2 separately, it may led to the system hang. Remove rst_mask and clk_mask of imx8mq_vpu_blk_ctl_domain_data. Let imx8mq_vpu_power_notifier() do really vpu reset.

Fixes 608d7c325e85 ("soc: imx: imx8m-blk-ctrl: add i.MX8MQ VPU blk-ctrl")
---
 drivers/soc/imx/imx8m-blk-ctrl.c |   11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/soc/imx/imx8m-blk-ctrl.c +7 -4
@@ -810,22 +810,25 @@ static int imx8mq_vpu_power_notifier(str
 	return NOTIFY_OK;
 }
 
+/*
+ * For i.MX8MQ, the ADB in the VPUMIX domain has no separate reset and clock
+ * enable bits, but is ungated and reset together with the VPUs.
+ * Resetting G1 or G2 separately may led to system hang.
+ * Remove the rst_mask and clk_mask from the domain data of G1 and G2,
+ * Let imx8mq_vpu_power_notifier() do really vpu reset.
+ */
 static const struct imx8m_blk_ctrl_domain_data imx8mq_vpu_blk_ctl_domain_data[] = {
 	[IMX8MQ_VPUBLK_PD_G1] = {
 		.name = "vpublk-g1",
 		.clk_names = (const char *[]){ "g1", },
 		.num_clks = 1,
 		.gpc_name = "g1",
-		.rst_mask = BIT(1),
-		.clk_mask = BIT(1),
 	},
 	[IMX8MQ_VPUBLK_PD_G2] = {
 		.name = "vpublk-g2",
 		.clk_names = (const char *[]){ "g2", },
 		.num_clks = 1,
 		.gpc_name = "g2",
-		.rst_mask = BIT(0),
-		.clk_mask = BIT(0),
 	},
 };
 
author maintainer
#235 lore raw

PATCH 230/280 ksmbd: smbd: fix dma_unmap_sg() nents

In reply to Greg Kroah-Hartman

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

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

From: Thomas Fourier <[email protected]>

[ Upstream commit 98e3e2b561bc88f4dd218d1c05890672874692f6 ]

The dma_unmap_sg() functions should be called with the same nents as the dma_map_sg(), not the value the map function returned.

Fixes 0626e6641f6b ("cifsd: add server handler for central processing and tranport layers")
[ Context ]
---
 fs/smb/server/transport_rdma.c |   15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)
fs/smb/server/transport_rdma.c +7 -8
@@ -1103,14 +1103,12 @@ static int get_sg_list(void *buf, int si
 
 static int get_mapped_sg_list(struct ib_device *device, void *buf, int size,
 			      struct scatterlist *sg_list, int nentries,
-			      enum dma_data_direction dir)
+			      enum dma_data_direction dir, int *npages)
 {
-	int npages;
-
-	npages = get_sg_list(buf, size, sg_list, nentries);
-	if (npages < 0)
+	*npages = get_sg_list(buf, size, sg_list, nentries);
+	if (*npages < 0)
 		return -EINVAL;
-	return ib_dma_map_sg(device, sg_list, npages, dir);
+	return ib_dma_map_sg(device, sg_list, *npages, dir);
 }
 
 static int post_sendmsg(struct smb_direct_transport *t,
@@ -1179,12 +1177,13 @@ static int smb_direct_post_send_data(str
 	for (i = 0; i < niov; i++) {
 		struct ib_sge *sge;
 		int sg_cnt;
+		int npages;
 
 		sg_init_table(sg, SMB_DIRECT_MAX_SEND_SGES - 1);
 		sg_cnt = get_mapped_sg_list(t->cm_id->device,
 					    iov[i].iov_base, iov[i].iov_len,
 					    sg, SMB_DIRECT_MAX_SEND_SGES - 1,
-					    DMA_TO_DEVICE);
+					    DMA_TO_DEVICE, &npages);
 		if (sg_cnt <= 0) {
 			pr_err("failed to map buffer\n");
 			ret = -ENOMEM;
@@ -1192,7 +1191,7 @@ static int smb_direct_post_send_data(str
 		} else if (sg_cnt + msg->num_sge > SMB_DIRECT_MAX_SEND_SGES) {
 			pr_err("buffer not fitted into sges\n");
 			ret = -E2BIG;
-			ib_dma_unmap_sg(t->cm_id->device, sg, sg_cnt,
+			ib_dma_unmap_sg(t->cm_id->device, sg, npages,
 					DMA_TO_DEVICE);
 			goto err;
 		}
author maintainer
#236 lore raw

PATCH 231/280 mei: trace: treat reg parameter as string

In reply to Greg Kroah-Hartman

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

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

From: Alexander Usyskin <[email protected]>

[ Upstream commit 06d5a7afe1d0b47102936d8fba568572c2b4b941 ]

The commit
afd2627f727b ("tracing: Check "%s" dereference via the field and not the TP_printk format") forbids to emit event with a plain char* without a wrapper.

The reg parameter always passed as static string and wrapper is not strictly required, contrary to dev parameter.
Use the string wrapper anyway to check sanity of the reg parameters, store it value independently and prevent internal kernel data leaks.

Since some code refactoring has taken place, explicit backporting may be needed for kernels older than 6.10.

Cc [email protected] # v6.11+
Fixes a0a927d06d79 ("mei: me: add io register tracing")
[ adapted __assign_str() calls to use two arguments ]
---
 drivers/misc/mei/mei-trace.h |   18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)
drivers/misc/mei/mei-trace.h +9 -9
@@ -21,18 +21,18 @@ TRACE_EVENT(mei_reg_read,
 	TP_ARGS(dev, reg, offs, val),
 	TP_STRUCT__entry(
 		__string(dev, dev_name(dev))
-		__field(const char *, reg)
+		__string(reg, reg)
 		__field(u32, offs)
 		__field(u32, val)
 	),
 	TP_fast_assign(
 		__assign_str(dev, dev_name(dev));
-		__entry->reg  = reg;
+		__assign_str(reg, reg);
 		__entry->offs = offs;
 		__entry->val = val;
 	),
 	TP_printk("[%s] read %s:[%#x] = %#x",
-		  __get_str(dev), __entry->reg, __entry->offs, __entry->val)
+		  __get_str(dev), __get_str(reg), __entry->offs, __entry->val)
 );
 
 TRACE_EVENT(mei_reg_write,
@@ -40,18 +40,18 @@ TRACE_EVENT(mei_reg_write,
 	TP_ARGS(dev, reg, offs, val),
 	TP_STRUCT__entry(
 		__string(dev, dev_name(dev))
-		__field(const char *, reg)
+		__string(reg, reg)
 		__field(u32, offs)
 		__field(u32, val)
 	),
 	TP_fast_assign(
 		__assign_str(dev, dev_name(dev));
-		__entry->reg = reg;
+		__assign_str(reg, reg);
 		__entry->offs = offs;
 		__entry->val = val;
 	),
 	TP_printk("[%s] write %s[%#x] = %#x",
-		  __get_str(dev), __entry->reg,  __entry->offs, __entry->val)
+		  __get_str(dev), __get_str(reg),  __entry->offs, __entry->val)
 );
 
 TRACE_EVENT(mei_pci_cfg_read,
@@ -59,18 +59,18 @@ TRACE_EVENT(mei_pci_cfg_read,
 	TP_ARGS(dev, reg, offs, val),
 	TP_STRUCT__entry(
 		__string(dev, dev_name(dev))
-		__field(const char *, reg)
+		__string(reg, reg)
 		__field(u32, offs)
 		__field(u32, val)
 	),
 	TP_fast_assign(
 		__assign_str(dev, dev_name(dev));
-		__entry->reg  = reg;
+		__assign_str(reg, reg);
 		__entry->offs = offs;
 		__entry->val = val;
 	),
 	TP_printk("[%s] pci cfg read %s:[%#x] = %#x",
-		  __get_str(dev), __entry->reg, __entry->offs, __entry->val)
+		  __get_str(dev), __get_str(reg), __entry->offs, __entry->val)
 );
 
 #endif /* _MEI_TRACE_H_ */
author maintainer
#237 lore raw

PATCH 232/280 arm64/fpsimd: signal: Fix restoration of SVE context

In reply to Greg Kroah-Hartman

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

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

From: Mark Rutland <[email protected]>

[ Upstream commit d2907cbe9ea0a54cbe078076f9d089240ee1e2d9 ]

When SME is supported, Restoring SVE signal context can go wrong in a few ways, including placing the task into an invalid state where the kernel may read from out-of-bounds memory (and may potentially take a fatal fault) and/or may kill the task with a SIGKILL.

(1) Restoring a context with SVE_SIG_FLAG_SM set can place the task into an invalid state where SVCR.SM is set (and sve_state is non-NULL) but TIF_SME is clear, consequently resuting in out-of-bounds memory reads and/or killing the task with SIGKILL.

This can only occur in unusual (but legitimate) cases where the SVE signal context has either been modified by userspace or was saved in the context of another task (e.g. as with CRIU), as otherwise the presence of an SVE signal context with SVE_SIG_FLAG_SM implies that TIF_SME is already set.

While in this state, task_fpsimd_load() will NOT configure SMCR_ELx (leaving some arbitrary value configured in hardware) before restoring SVCR and attempting to restore the streaming mode SVE registers from memory via sve_load_state(). As the value of SMCR_ELx.LEN may be larger than the task's streaming SVE vector length, this may read memory outside of the task's allocated sve_state, reading unrelated data and/or triggering a fault.

While this can result in secrets being loaded into streaming SVE registers, these values are never exposed. As TIF_SME is clear, fpsimd_bind_task_to_cpu() will configure CPACR_ELx.SMEN to trap EL0 accesses to streaming mode SVE registers, so these cannot be accessed directly at EL0. As fpsimd_save_user_state() verifies the live vector length before saving (S)SVE state to memory, no secret values can be saved back to memory (and hence cannot be observed via ptrace, signals, etc).

When the live vector length doesn't match the expected vector length for the task, fpsimd_save_user_state() will send a fatal SIGKILL signal to the task. Hence the task may be killed after executing userspace for some period of time.

(2) Restoring a context with SVE_SIG_FLAG_SM clear does not clear the task's SVCR.SM. If SVCR.SM was set prior to restoring the context, then the task will be left in streaming mode unexpectedly, and some register state will be combined inconsistently, though the task will be left in legitimate state from the kernel's PoV.

This can only occur in unusual (but legitimate) cases where ptrace has been used to set SVCR.SM after entry to the sigreturn syscall, as syscall entry clears SVCR.SM.

In these cases, the the provided SVE register data will be loaded into the task's sve_state using the non-streaming SVE vector length and the FPSIMD registers will be merged into this using the streaming SVE vector length.

Fix (1) by setting TIF_SME when setting SVCR.SM. This also requires ensuring that the task's sme_state has been allocated, but as this could contain live ZA state, it should not be zeroed. Fix (2) by clearing SVCR.SM when restoring a SVE signal context with SVE_SIG_FLAG_SM clear.

For consistency, I've pulled the manipulation of SVCR, TIF_SVE, TIF_SME, and fp_type earlier, immediately after the allocation of sve_state/sme_state, before the restore of the actual register state. This makes it easier to ensure that these are always modified consistently, even if a fault is taken while reading the register data from the signal context. I do not expect any software to depend on the exact state restored when a fault is taken while reading the context.

Fixes 85ed24dad290 ("arm64/sme: Implement streaming SVE signal handling")
Cc Mark Brown <[email protected]>
Cc Will Deacon <[email protected]>
[ adapted sme_state to za_state ]
---
 arch/arm64/kernel/signal.c |   22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)
arch/arm64/kernel/signal.c +16 -6
@@ -317,12 +317,28 @@ static int restore_sve_fpsimd_context(st
 	fpsimd_flush_task_state(current);
 	/* From now, fpsimd_thread_switch() won't touch thread.sve_state */
 
+	if (sve.flags & SVE_SIG_FLAG_SM) {
+		sme_alloc(current, false);
+		if (!current->thread.za_state)
+			return -ENOMEM;
+	}
+
 	sve_alloc(current, true);
 	if (!current->thread.sve_state) {
 		clear_thread_flag(TIF_SVE);
 		return -ENOMEM;
 	}
 
+	if (sve.flags & SVE_SIG_FLAG_SM) {
+		current->thread.svcr |= SVCR_SM_MASK;
+		set_thread_flag(TIF_SME);
+	} else {
+		current->thread.svcr &= ~SVCR_SM_MASK;
+		set_thread_flag(TIF_SVE);
+	}
+
+	current->thread.fp_type = FP_STATE_SVE;
+
 	err = __copy_from_user(current->thread.sve_state,
 			       (char __user const *)user->sve +
 					SVE_SIG_REGS_OFFSET,
@@ -330,12 +346,6 @@ static int restore_sve_fpsimd_context(st
 	if (err)
 		return -EFAULT;
 
-	if (sve.flags & SVE_SIG_FLAG_SM)
-		current->thread.svcr |= SVCR_SM_MASK;
-	else
-		set_thread_flag(TIF_SVE);
-	current->thread.fp_type = FP_STATE_SVE;
-
 fpsimd_only:
 	/* copy the FP and status/control registers */
 	/* restore_sigframe() already checked that user->fpsimd != NULL. */
author maintainer
#238 lore raw

PATCH 233/280 mmc: sdhci-of-dwcmshc: Update DLL and pre-change delay for rockchip platform

In reply to Greg Kroah-Hartman

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

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

From: Shawn Lin <[email protected]>

[ Upstream commit b75a52b0dda353aeefb4830a320589a363f49579 ]

For Rockchip platform, DLL bypass bit and start bit need to be set if DLL is not locked. And adjust pre-change delay to 0x3 for better signal test result.

Stable-dep-of: 3009738a855c ("mmc: sdhci-of-dwcmshc: Prevent illegal clock reduction in HS200/HS400 mode")

---
 drivers/mmc/host/sdhci-of-dwcmshc.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/mmc/host/sdhci-of-dwcmshc.c +9 -4
@@ -48,6 +48,7 @@
 #define DWCMSHC_EMMC_DLL_RXCLK_SRCSEL	29
 #define DWCMSHC_EMMC_DLL_START_POINT	16
 #define DWCMSHC_EMMC_DLL_INC		8
+#define DWCMSHC_EMMC_DLL_BYPASS		BIT(24)
 #define DWCMSHC_EMMC_DLL_DLYENA		BIT(27)
 #define DLL_TXCLK_TAPNUM_DEFAULT	0x10
 #define DLL_TXCLK_TAPNUM_90_DEGREES	0xA
@@ -60,6 +61,7 @@
 #define DLL_RXCLK_NO_INVERTER		1
 #define DLL_RXCLK_INVERTER		0
 #define DLL_CMDOUT_TAPNUM_90_DEGREES	0x8
+#define DLL_RXCLK_ORI_GATE		BIT(31)
 #define DLL_CMDOUT_TAPNUM_FROM_SW	BIT(24)
 #define DLL_CMDOUT_SRC_CLK_NEG		BIT(28)
 #define DLL_CMDOUT_EN_SRC_CLK_NEG	BIT(29)
@@ -234,9 +236,12 @@ static void dwcmshc_rk3568_set_clock(str
 	sdhci_writel(host, extra, reg);
 
 	if (clock <= 52000000) {
-		/* Disable DLL and reset both of sample and drive clock */
-		sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_CTRL);
-		sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_RXCLK);
+		/*
+		 * Disable DLL and reset both of sample and drive clock.
+		 * The bypass bit and start bit need to be set if DLL is not locked.
+		 */
+		sdhci_writel(host, DWCMSHC_EMMC_DLL_BYPASS | DWCMSHC_EMMC_DLL_START, DWCMSHC_EMMC_DLL_CTRL);
+		sdhci_writel(host, DLL_RXCLK_ORI_GATE, DWCMSHC_EMMC_DLL_RXCLK);
 		sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_TXCLK);
 		sdhci_writel(host, 0, DECMSHC_EMMC_DLL_CMDOUT);
 		/*
@@ -279,7 +284,7 @@ static void dwcmshc_rk3568_set_clock(str
 	}
 
 	extra = 0x1 << 16 | /* tune clock stop en */
-		0x2 << 17 | /* pre-change delay */
+		0x3 << 17 | /* pre-change delay */
 		0x3 << 19;  /* post-change delay */
 	sdhci_writel(host, extra, dwc_priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL);
 
author maintainer
#239 lore raw

PATCH 234/280 mmc: sdhci-of-dwcmshc: Prevent illegal clock reduction in HS200/HS400 mode

In reply to Greg Kroah-Hartman

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

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

From: Shawn Lin <[email protected]>

[ Upstream commit 3009738a855cf938bbfc9078bec725031ae623a4 ]

When operating in HS200 or HS400 timing modes, reducing the clock frequency below 52MHz will lead to link broken as the Rockchip DWC MSHC controller requires maintaining a minimum clock of 52MHz in these modes.

Add a check to prevent illegal clock reduction through debugfs:

root@debian:/# echo 50000000 > /sys/kernel/debug/mmc0/clock
root@debian:/# [   30.090146] mmc0: running CQE recovery
mmc0: cqhci: Failed to halt
mmc0: cqhci: spurious TCN for tag 0
WARNING: drivers/mmc/host/cqhci-core.c:797 at cqhci_irq+0x254/0x818, CPU#1: kworker/1:0H/24
Modules linked in:
CPU: 1 UID: 0 PID: 24 Comm: kworker/1:0H Not tainted 6.19.0-rc1-00001-g09db0998649d-dirty #204 PREEMPT
Hardware name: Rockchip RK3588 EVB1 V10 Board (DT)
Workqueue: kblockd blk_mq_run_work_fn
pstate: 604000c9 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : cqhci_irq+0x254/0x818
lr : cqhci_irq+0x254/0x818
...
Fixes c6f361cba51c ("mmc: sdhci-of-dwcmshc: add support for rk3588")
Cc Sebastian Reichel <[email protected]>
Cc Yifeng Zhao <[email protected]>
---
 drivers/mmc/host/sdhci-of-dwcmshc.c |    7 +++++++
 1 file changed, 7 insertions(+)
drivers/mmc/host/sdhci-of-dwcmshc.c +7 -0
@@ -236,6 +236,13 @@ static void dwcmshc_rk3568_set_clock(str
 	sdhci_writel(host, extra, reg);
 
 	if (clock <= 52000000) {
+		if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200 ||
+		    host->mmc->ios.timing == MMC_TIMING_MMC_HS400) {
+			dev_err(mmc_dev(host->mmc),
+				"Can't reduce the clock below 52MHz in HS200/HS400 mode");
+			return;
+		}
+
 		/*
 		 * Disable DLL and reset both of sample and drive clock.
 		 * The bypass bit and start bit need to be set if DLL is not locked.
author maintainer
#240 lore raw

PATCH 235/280 ALSA: scarlett2: Fix buffer overflow in config retrieval

In reply to Greg Kroah-Hartman

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

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

From: Samasth Norway Ananda <[email protected]>

[ Upstream commit 6f5c69f72e50d51be3a8c028ae7eda42c82902cb ]

The scarlett2_usb_get_config() function has a logic error in the endianness conversion code that can cause buffer overflows when count > 1.

The code checks if (size == 2) where size is the total buffer size in bytes, then loops count times treating each element as u16 (2 bytes). This causes the loop to access count * 2 bytes when the buffer only has size bytes allocated.

Fix by checking the element size (config_item->size) instead of the total buffer size. This ensures the endianness conversion matches the actual element type.

Fixes ac34df733d2d ("ALSA: usb-audio: scarlett2: Update get_config to do endian conversion")
[ add 32-bit handling block ]
---
 sound/usb/mixer_scarlett2.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
sound/usb/mixer_scarlett2.c +6 -1
@@ -1408,11 +1408,16 @@ static int scarlett2_usb_get_config(
 		err = scarlett2_usb_get(mixer, config_item->offset, buf, size);
 		if (err < 0)
 			return err;
-		if (size == 2) {
+		if (config_item->size == 16) {
 			u16 *buf_16 = buf;
 
 			for (i = 0; i < count; i++, buf_16++)
 				*buf_16 = le16_to_cpu(*(__le16 *)buf_16);
+		} else if (config_item->size == 32) {
+			u32 *buf_32 = (u32 *)buf;
+
+			for (i = 0; i < count; i++, buf_32++)
+				*buf_32 = le32_to_cpu(*(__le32 *)buf_32);
 		}
 		return 0;
 	}
author maintainer
#241 lore raw

PATCH 236/280 iio: adc: exynos_adc: fix OF populate on driver rebind

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

[ Upstream commit ea6b4feba85e996e840e0b661bc42793df6eb701 ]

Since commit c6e126de43e7 ("of: Keep track of populated platform devices") child devices will not be created by of_platform_populate() if the devices had previously been deregistered individually so that the OF_POPULATED flag is still set in the corresponding OF nodes.

Switch to using of_platform_depopulate() instead of open coding so that the child devices are created if the driver is rebound.

Fixes c6e126de43e7 ("of: Keep track of populated platform devices")
[ Adjust context ]
---
 drivers/iio/adc/exynos_adc.c |   13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)
drivers/iio/adc/exynos_adc.c +2 -11
@@ -721,14 +721,7 @@ static const struct iio_chan_spec exynos
 	ADC_CHANNEL(9, "adc9"),
 };
 
-static int exynos_adc_remove_devices(struct device *dev, void *c)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-
-	platform_device_unregister(pdev);
 
-	return 0;
-}
 
 static int exynos_adc_ts_open(struct input_dev *dev)
 {
@@ -929,8 +922,7 @@ static int exynos_adc_probe(struct platf
 	return 0;
 
 err_of_populate:
-	device_for_each_child(&indio_dev->dev, NULL,
-				exynos_adc_remove_devices);
+	of_platform_depopulate(&indio_dev->dev);
 	if (has_ts) {
 		input_unregister_device(info->input);
 		free_irq(info->tsirq, info);
@@ -959,8 +951,7 @@ static int exynos_adc_remove(struct plat
 		free_irq(info->tsirq, info);
 		input_unregister_device(info->input);
 	}
-	device_for_each_child(&indio_dev->dev, NULL,
-				exynos_adc_remove_devices);
+	of_platform_depopulate(&indio_dev->dev);
 	iio_device_unregister(indio_dev);
 	free_irq(info->irq, info);
 	if (info->data->exit_hw)
author maintainer
#242 lore raw

PATCH 237/280 iio: chemical: scd4x: fix reported channel endianness

In reply to Greg Kroah-Hartman

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

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

From: Fiona Klute <[email protected]>

[ Upstream commit 81d5a5366d3c20203fb9d7345e1aa46d668445a2 ]

The driver converts values read from the sensor from BE to CPU endianness in scd4x_read_meas(). The result is then pushed into the buffer in scd4x_trigger_handler(), so on LE architectures parsing the buffer using the reported BE type gave wrong results.

scd4x_read_raw() which provides sysfs *_raw values is not affected, it used the values returned by scd4x_read_meas() without further conversion.

Fixes 49d22b695cbb6 ("drivers: iio: chemical: Add support for Sensirion SCD4x CO2 sensor")
---
 drivers/iio/chemical/scd4x.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/iio/chemical/scd4x.c +3 -3
@@ -518,7 +518,7 @@ static const struct iio_chan_spec scd4x_
 			.sign = 'u',
 			.realbits = 16,
 			.storagebits = 16,
-			.endianness = IIO_BE,
+			.endianness = IIO_CPU,
 		},
 	},
 	{
@@ -533,7 +533,7 @@ static const struct iio_chan_spec scd4x_
 			.sign = 'u',
 			.realbits = 16,
 			.storagebits = 16,
-			.endianness = IIO_BE,
+			.endianness = IIO_CPU,
 		},
 	},
 	{
@@ -546,7 +546,7 @@ static const struct iio_chan_spec scd4x_
 			.sign = 'u',
 			.realbits = 16,
 			.storagebits = 16,
-			.endianness = IIO_BE,
+			.endianness = IIO_CPU,
 		},
 	},
 };
author maintainer
#243 lore raw

PATCH 238/280 nvme-fc: rename free_ctrl callback to match name pattern

In reply to Greg Kroah-Hartman

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

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

From: Daniel Wagner <[email protected]>

[ Upstream commit 205fb5fa6fde1b5b426015eb1ff69f2ff25ef5bb ]

Rename nvme_fc_nvme_ctrl_freed to nvme_fc_free_ctrl to match the name pattern for the callback.

Stable-dep-of: 0edb475ac0a7 ("nvme: fix PCIe subsystem reset controller state transition")

---
 drivers/nvme/host/fc.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/nvme/host/fc.c +2 -2
@@ -2417,7 +2417,7 @@ nvme_fc_ctrl_get(struct nvme_fc_ctrl *ct
  * controller. Called after last nvme_put_ctrl() call
  */
 static void
-nvme_fc_nvme_ctrl_freed(struct nvme_ctrl *nctrl)
+nvme_fc_free_ctrl(struct nvme_ctrl *nctrl)
 {
 	struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl);
 
@@ -3362,7 +3362,7 @@ static const struct nvme_ctrl_ops nvme_f
 	.reg_read32		= nvmf_reg_read32,
 	.reg_read64		= nvmf_reg_read64,
 	.reg_write32		= nvmf_reg_write32,
-	.free_ctrl		= nvme_fc_nvme_ctrl_freed,
+	.free_ctrl		= nvme_fc_free_ctrl,
 	.submit_async_event	= nvme_fc_submit_async_event,
 	.delete_ctrl		= nvme_fc_delete_ctrl,
 	.get_address		= nvmf_get_address,
author maintainer
#244 lore raw

PATCH 239/280 nvme-pci: do not directly handle subsys reset fallout

In reply to Greg Kroah-Hartman

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

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

From: Keith Busch <[email protected]>

[ Upstream commit 210b1f6576e8b367907e7ff51ef425062e1468e4 ]

Scheduling reset_work after a nvme subsystem reset is expected to fail on pcie, but this also prevents potential handling the platform's pcie services may provide that might successfully recovering the link without re-enumeration. Such examples include AER, DPC, and power's EEH.

Provide a pci specific operation that safely initiates a subsystem reset, and instead of scheduling reset work, read back the status register to trigger a pcie read error.

Since this only affects pci, the other fabrics drivers subscribe to a generic nvmf subsystem reset that is exactly the same as before. The loop fabric doesn't use it because nvmet doesn't support setting that property anyway.

And since we're using the magic NSSR value in two places now, provide a symbolic define for it.

Stable-dep-of: 0edb475ac0a7 ("nvme: fix PCIe subsystem reset controller state transition")

---
 drivers/nvme/host/fabrics.c |   15 +++++++++++++++
 drivers/nvme/host/fabrics.h |    1 +
 drivers/nvme/host/fc.c      |    1 +
 drivers/nvme/host/nvme.h    |   14 +++-----------
 drivers/nvme/host/pci.c     |   36 ++++++++++++++++++++++++++++++++++++
 drivers/nvme/host/rdma.c    |    1 +
 drivers/nvme/host/tcp.c     |    1 +
 include/linux/nvme.h        |    3 +++
 8 files changed, 61 insertions(+), 11 deletions(-)
drivers/nvme/host/fabrics.c +15 -0
@@ -253,6 +253,21 @@ int nvmf_reg_write32(struct nvme_ctrl *c
 }
 EXPORT_SYMBOL_GPL(nvmf_reg_write32);
 
+int nvmf_subsystem_reset(struct nvme_ctrl *ctrl)
+{
+	int ret;
+
+	if (!nvme_wait_reset(ctrl))
+		return -EBUSY;
+
+	ret = ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, NVME_SUBSYS_RESET);
+	if (ret)
+		return ret;
+
+	return nvme_try_sched_reset(ctrl);
+}
+EXPORT_SYMBOL_GPL(nvmf_subsystem_reset);
+
 /**
  * nvmf_log_connect_error() - Error-parsing-diagnostic print out function for
  * 				connect() errors.
drivers/nvme/host/fabrics.h +1 -0
@@ -199,6 +199,7 @@ static inline void nvmf_complete_timed_o
 int nvmf_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val);
 int nvmf_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val);
 int nvmf_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val);
+int nvmf_subsystem_reset(struct nvme_ctrl *ctrl);
 int nvmf_connect_admin_queue(struct nvme_ctrl *ctrl);
 int nvmf_connect_io_queue(struct nvme_ctrl *ctrl, u16 qid);
 int nvmf_register_transport(struct nvmf_transport_ops *ops);
drivers/nvme/host/fc.c +1 -0
@@ -3362,6 +3362,7 @@ static const struct nvme_ctrl_ops nvme_f
 	.reg_read32		= nvmf_reg_read32,
 	.reg_read64		= nvmf_reg_read64,
 	.reg_write32		= nvmf_reg_write32,
+	.subsystem_reset	= nvmf_subsystem_reset,
 	.free_ctrl		= nvme_fc_free_ctrl,
 	.submit_async_event	= nvme_fc_submit_async_event,
 	.delete_ctrl		= nvme_fc_delete_ctrl,
drivers/nvme/host/nvme.h +3 -11
@@ -538,6 +538,7 @@ struct nvme_ctrl_ops {
 	int (*reg_read64)(struct nvme_ctrl *ctrl, u32 off, u64 *val);
 	void (*free_ctrl)(struct nvme_ctrl *ctrl);
 	void (*submit_async_event)(struct nvme_ctrl *ctrl);
+	int (*subsystem_reset)(struct nvme_ctrl *ctrl);
 	void (*delete_ctrl)(struct nvme_ctrl *ctrl);
 	void (*stop_ctrl)(struct nvme_ctrl *ctrl);
 	int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size);
@@ -636,18 +637,9 @@ int nvme_try_sched_reset(struct nvme_ctr
 
 static inline int nvme_reset_subsystem(struct nvme_ctrl *ctrl)
 {
-	int ret;
-
-	if (!ctrl->subsystem)
+	if (!ctrl->subsystem || !ctrl->ops->subsystem_reset)
 		return -ENOTTY;
-	if (!nvme_wait_reset(ctrl))
-		return -EBUSY;
-
-	ret = ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65);
-	if (ret)
-		return ret;
-
-	return nvme_try_sched_reset(ctrl);
+	return ctrl->ops->subsystem_reset(ctrl);
 }
 
 /*
drivers/nvme/host/pci.c +36 -0
@@ -1190,6 +1190,41 @@ static void nvme_pci_submit_async_event(
 	spin_unlock(&nvmeq->sq_lock);
 }
 
+static int nvme_pci_subsystem_reset(struct nvme_ctrl *ctrl)
+{
+	struct nvme_dev *dev = to_nvme_dev(ctrl);
+	int ret = 0;
+
+	/*
+	 * Taking the shutdown_lock ensures the BAR mapping is not being
+	 * altered by reset_work. Holding this lock before the RESETTING state
+	 * change, if successful, also ensures nvme_remove won't be able to
+	 * proceed to iounmap until we're done.
+	 */
+	mutex_lock(&dev->shutdown_lock);
+	if (!dev->bar_mapped_size) {
+		ret = -ENODEV;
+		goto unlock;
+	}
+
+	if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	writel(NVME_SUBSYS_RESET, dev->bar + NVME_REG_NSSR);
+	nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE);
+
+	/*
+	 * Read controller status to flush the previous write and trigger a
+	 * pcie read error.
+	 */
+	readl(dev->bar + NVME_REG_CSTS);
+unlock:
+	mutex_unlock(&dev->shutdown_lock);
+	return ret;
+}
+
 static int adapter_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id)
 {
 	struct nvme_command c = { };
@@ -3033,6 +3068,7 @@ static const struct nvme_ctrl_ops nvme_p
 	.reg_read64		= nvme_pci_reg_read64,
 	.free_ctrl		= nvme_pci_free_ctrl,
 	.submit_async_event	= nvme_pci_submit_async_event,
+	.subsystem_reset	= nvme_pci_subsystem_reset,
 	.get_address		= nvme_pci_get_address,
 	.print_device_info	= nvme_pci_print_device_info,
 	.supports_pci_p2pdma	= nvme_pci_supports_pci_p2pdma,
drivers/nvme/host/rdma.c +1 -0
@@ -2256,6 +2256,7 @@ static const struct nvme_ctrl_ops nvme_r
 	.reg_read32		= nvmf_reg_read32,
 	.reg_read64		= nvmf_reg_read64,
 	.reg_write32		= nvmf_reg_write32,
+	.subsystem_reset	= nvmf_subsystem_reset,
 	.free_ctrl		= nvme_rdma_free_ctrl,
 	.submit_async_event	= nvme_rdma_submit_async_event,
 	.delete_ctrl		= nvme_rdma_delete_ctrl,
drivers/nvme/host/tcp.c +1 -0
@@ -2612,6 +2612,7 @@ static const struct nvme_ctrl_ops nvme_t
 	.reg_read32		= nvmf_reg_read32,
 	.reg_read64		= nvmf_reg_read64,
 	.reg_write32		= nvmf_reg_write32,
+	.subsystem_reset	= nvmf_subsystem_reset,
 	.free_ctrl		= nvme_tcp_free_ctrl,
 	.submit_async_event	= nvme_tcp_submit_async_event,
 	.delete_ctrl		= nvme_tcp_delete_ctrl,
include/linux/nvme.h +3 -0
@@ -28,6 +28,9 @@
 
 #define NVME_NSID_ALL		0xffffffff
 
+/* Special NSSR value, 'NVMe' */
+#define NVME_SUBSYS_RESET	0x4E564D65
+
 enum nvme_subsys_type {
 	/* Referral to another discovery type target subsystem */
 	NVME_NQN_DISC	= 1,
author maintainer
#245 lore raw

PATCH 240/280 nvme: fix PCIe subsystem reset controller state transition

In reply to Greg Kroah-Hartman

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

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

From: Nilay Shroff <[email protected]>

[ Upstream commit 0edb475ac0a7d153318a24d4dca175a270a5cc4f ]

The commit d2fe192348f9 (“nvme: only allow entering LIVE from CONNECTING state”) disallows controller state transitions directly from RESETTING to LIVE. However, the NVMe PCIe subsystem reset path relies on this transition to recover the controller on PowerPC (PPC) systems.

On PPC systems, issuing a subsystem reset causes a temporary loss of communication with the NVMe adapter. A subsequent PCIe MMIO read then triggers EEH recovery, which restores the PCIe link and brings the controller back online. For EEH recovery to proceed correctly, the controller must transition back to the LIVE state.

Due to the changes introduced by commit d2fe192348f9 (“nvme: only allow entering LIVE from CONNECTING state”), the controller can no longer transition directly from RESETTING to LIVE. As a result, EEH recovery exits prematurely, leaving the controller stuck in the RESETTING state.

Fix this by explicitly transitioning the controller state from RESETTING to CONNECTING and then to LIVE. This satisfies the updated state transition rules and allows the controller to be successfully recovered on PPC systems following a PCIe subsystem reset.

Fixes d2fe192348f9 ("nvme: only allow entering LIVE from CONNECTING state")
---
 drivers/nvme/host/pci.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/nvme/host/pci.c +4 -1
@@ -1213,7 +1213,10 @@ static int nvme_pci_subsystem_reset(stru
 	}
 
 	writel(NVME_SUBSYS_RESET, dev->bar + NVME_REG_NSSR);
-	nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE);
+
+	if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_CONNECTING) ||
+	    !nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE))
+		goto unlock;
 
 	/*
 	 * Read controller status to flush the previous write and trigger a
author maintainer
#246 lore raw

PATCH 241/280 phy: phy-rockchip-inno-usb2: simplify phy clock handling

In reply to Greg Kroah-Hartman

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

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

From: Sebastian Reichel <[email protected]>

[ Upstream commit b43511233c6e34b9c0d9a55e41b078d10e7d9ea6 ]

Simplify phyclk handling by using devm_clk_get_optional_enabled to acquire and enable the optional clock. This also fixes a resource leak in driver remove path and adds proper error handling.

Stable-dep-of: e07dea3de508 ("phy: rockchip: inno-usb2: Fix a double free bug in rockchip_usb2phy_probe()")

---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c |   17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)
drivers/phy/rockchip/phy-rockchip-inno-usb2.c +5 -12
@@ -1273,18 +1273,16 @@ static int rockchip_usb2phy_probe(struct
 		return -EINVAL;
 	}
 
-	rphy->clk = of_clk_get_by_name(np, "phyclk");
-	if (!IS_ERR(rphy->clk)) {
-		clk_prepare_enable(rphy->clk);
-	} else {
-		dev_info(&pdev->dev, "no phyclk specified\n");
-		rphy->clk = NULL;
+	rphy->clk = devm_clk_get_optional_enabled(dev, "phyclk");
+	if (IS_ERR(rphy->clk)) {
+		return dev_err_probe(&pdev->dev, PTR_ERR(rphy->clk),
+				     "failed to get phyclk\n");
 	}
 
 	ret = rockchip_usb2phy_clk480m_register(rphy);
 	if (ret) {
 		dev_err(dev, "failed to register 480m output clock\n");
-		goto disable_clks;
+		return ret;
 	}
 
 	index = 0;
@@ -1347,11 +1345,6 @@ next_child:
 
 put_child:
 	of_node_put(child_np);
-disable_clks:
-	if (rphy->clk) {
-		clk_disable_unprepare(rphy->clk);
-		clk_put(rphy->clk);
-	}
 	return ret;
 }
 
author maintainer
#247 lore raw

PATCH 242/280 phy: phy-rockchip-inno-usb2: Use dev_err_probe() in the probe path

In reply to Greg Kroah-Hartman

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

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

From: Dragan Simic <[email protected]>

[ Upstream commit 40452520850683f6771094ca218ff206d1fcb022 ]

Improve error handling in the probe path by using function dev_err_probe() instead of function dev_err(), where appropriate.

Stable-dep-of: e07dea3de508 ("phy: rockchip: inno-usb2: Fix a double free bug in rockchip_usb2phy_probe()")

---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c |   27 +++++++++-----------------
 1 file changed, 10 insertions(+), 17 deletions(-)
drivers/phy/rockchip/phy-rockchip-inno-usb2.c +10 -17
@@ -380,11 +380,9 @@ static int rockchip_usb2phy_extcon_regis
 
 	if (of_property_read_bool(node, "extcon")) {
 		edev = extcon_get_edev_by_phandle(rphy->dev, 0);
-		if (IS_ERR(edev)) {
-			if (PTR_ERR(edev) != -EPROBE_DEFER)
-				dev_err(rphy->dev, "Invalid or missing extcon\n");
-			return PTR_ERR(edev);
-		}
+		if (IS_ERR(edev))
+			return dev_err_probe(rphy->dev, PTR_ERR(edev),
+					     "invalid or missing extcon\n");
 	} else {
 		/* Initialize extcon device */
 		edev = devm_extcon_dev_allocate(rphy->dev,
@@ -394,10 +392,9 @@ static int rockchip_usb2phy_extcon_regis
 			return -ENOMEM;
 
 		ret = devm_extcon_dev_register(rphy->dev, edev);
-		if (ret) {
-			dev_err(rphy->dev, "failed to register extcon device\n");
-			return ret;
-		}
+		if (ret)
+			return dev_err_probe(rphy->dev, ret,
+					     "failed to register extcon device\n");
 	}
 
 	rphy->edev = edev;
@@ -1280,10 +1277,8 @@ static int rockchip_usb2phy_probe(struct
 	}
 
 	ret = rockchip_usb2phy_clk480m_register(rphy);
-	if (ret) {
-		dev_err(dev, "failed to register 480m output clock\n");
-		return ret;
-	}
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to register 480m output clock\n");
 
 	index = 0;
 	for_each_available_child_of_node(np, child_np) {
@@ -1297,8 +1292,7 @@ static int rockchip_usb2phy_probe(struct
 
 		phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops);
 		if (IS_ERR(phy)) {
-			dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n");
-			ret = PTR_ERR(phy);
+			ret = dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n");
 			goto put_child;
 		}
 
@@ -1335,8 +1329,7 @@ next_child:
 						"rockchip_usb2phy",
 						rphy);
 		if (ret) {
-			dev_err(rphy->dev,
-				"failed to request usb2phy irq handle\n");
+			dev_err_probe(rphy->dev, ret, "failed to request usb2phy irq handle\n");
 			goto put_child;
 		}
 	}
author maintainer
#248 lore raw

PATCH 243/280 phy: rockchip: inno-usb2: Fix a double free bug in rockchip_usb2phy_probe()

In reply to Greg Kroah-Hartman

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

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

From: Wentao Liang <[email protected]>

[ Upstream commit e07dea3de508cd6950c937cec42de7603190e1ca ]

The for_each_available_child_of_node() calls of_node_put() to release child_np in each success loop. After breaking from the loop with the child_np has been released, the code will jump to the put_child label and will call the of_node_put() again if the devm_request_threaded_irq() fails. These cause a double free bug.

Fix by returning directly to avoid the duplicate of_node_put().

---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/phy/rockchip/phy-rockchip-inno-usb2.c +1 -1
@@ -1330,7 +1330,7 @@ next_child:
 						rphy);
 		if (ret) {
 			dev_err_probe(rphy->dev, ret, "failed to request usb2phy irq handle\n");
-			goto put_child;
+			return ret;
 		}
 	}
 
author maintainer
#249 lore raw

PATCH 244/280 ASoC: codecs: wsa881x: Simplify &pdev->dev in probe

In reply to Greg Kroah-Hartman

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

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

From: Krzysztof Kozlowski <[email protected]>

[ Upstream commit c617c9e7024d152426acf9f1aaf01070b6852f13 ]

The probe already stores pointer to &pdev->dev, so use it to make the code a bit easier to read.

Stable-dep-of: 29d71b8a5a40 ("ASoC: codecs: wsa881x: fix unnecessary initialisation")

---
 sound/soc/codecs/wsa881x.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
sound/soc/codecs/wsa881x.c +5 -5
@@ -1112,20 +1112,20 @@ static int wsa881x_probe(struct sdw_slav
 	struct wsa881x_priv *wsa881x;
 	struct device *dev = &pdev->dev;
 
-	wsa881x = devm_kzalloc(&pdev->dev, sizeof(*wsa881x), GFP_KERNEL);
+	wsa881x = devm_kzalloc(dev, sizeof(*wsa881x), GFP_KERNEL);
 	if (!wsa881x)
 		return -ENOMEM;
 
-	wsa881x->sd_n = devm_gpiod_get_optional(&pdev->dev, "powerdown",
+	wsa881x->sd_n = devm_gpiod_get_optional(dev, "powerdown",
 						GPIOD_FLAGS_BIT_NONEXCLUSIVE);
 	if (IS_ERR(wsa881x->sd_n)) {
 		dev_err(&pdev->dev, "Shutdown Control GPIO not found\n");
 		return PTR_ERR(wsa881x->sd_n);
 	}
 
-	dev_set_drvdata(&pdev->dev, wsa881x);
+	dev_set_drvdata(dev, wsa881x);
 	wsa881x->slave = pdev;
-	wsa881x->dev = &pdev->dev;
+	wsa881x->dev = dev;
 	wsa881x->sconfig.ch_count = 1;
 	wsa881x->sconfig.bps = 1;
 	wsa881x->sconfig.frame_rate = 48000;
@@ -1148,7 +1148,7 @@ static int wsa881x_probe(struct sdw_slav
 	pm_runtime_set_active(dev);
 	pm_runtime_enable(dev);
 
-	return devm_snd_soc_register_component(&pdev->dev,
+	return devm_snd_soc_register_component(dev,
 					       &wsa881x_component_drv,
 					       wsa881x_dais,
 					       ARRAY_SIZE(wsa881x_dais));
author maintainer
#250 lore raw

PATCH 245/280 ASoC: codecs: wsa881x: Use proper shutdown GPIO polarity

In reply to Greg Kroah-Hartman

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

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

From: Krzysztof Kozlowski <[email protected]>

[ Upstream commit 738455858a2d21b769f673892546cf8300c9fd78 ]

The shutdown GPIO is active low (SD_N), but this depends on actual board layout. Linux drivers should only care about logical state, where high
(1) means shutdown and low (0) means do not shutdown.

Invert the GPIO to match logical value while preserving backwards DTB compatibility. It is not possible to detect whether ACTIVE_HIGH flag in DTB is because it is an old DTB (using incorrect flag) or it is a new DTB with a correct hardware pin polarity description. Therefore the solution prioritizes backwards compatibility while relying on relevant DTS being upstreamed.

Stable-dep-of: 29d71b8a5a40 ("ASoC: codecs: wsa881x: fix unnecessary initialisation")

---
 sound/soc/codecs/wsa881x.c |   33 +++++++++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 4 deletions(-)
sound/soc/codecs/wsa881x.c +29 -4
@@ -678,6 +678,11 @@ struct wsa881x_priv {
 	struct sdw_stream_runtime *sruntime;
 	struct sdw_port_config port_config[WSA881X_MAX_SWR_PORTS];
 	struct gpio_desc *sd_n;
+	/*
+	 * Logical state for SD_N GPIO: high for shutdown, low for enable.
+	 * For backwards compatibility.
+	 */
+	unsigned int sd_n_val;
 	int version;
 	int active_ports;
 	bool port_prepared[WSA881X_MAX_SWR_PORTS];
@@ -1123,6 +1128,26 @@ static int wsa881x_probe(struct sdw_slav
 		return PTR_ERR(wsa881x->sd_n);
 	}
 
+	/*
+	 * Backwards compatibility work-around.
+	 *
+	 * The SD_N GPIO is active low, however upstream DTS used always active
+	 * high.  Changing the flag in driver and DTS will break backwards
+	 * compatibility, so add a simple value inversion to work with both old
+	 * and new DTS.
+	 *
+	 * This won't work properly with DTS using the flags properly in cases:
+	 * 1. Old DTS with proper ACTIVE_LOW, however such case was broken
+	 *    before as the driver required the active high.
+	 * 2. New DTS with proper ACTIVE_HIGH (intended), which is rare case
+	 *    (not existing upstream) but possible. This is the price of
+	 *    backwards compatibility, therefore this hack should be removed at
+	 *    some point.
+	 */
+	wsa881x->sd_n_val = gpiod_is_active_low(wsa881x->sd_n);
+	if (!wsa881x->sd_n_val)
+		dev_warn(dev, "Using ACTIVE_HIGH for shutdown GPIO. Your DTB might be outdated or you use unsupported configuration for the GPIO.");
+
 	dev_set_drvdata(dev, wsa881x);
 	wsa881x->slave = pdev;
 	wsa881x->dev = dev;
@@ -1134,7 +1159,7 @@ static int wsa881x_probe(struct sdw_slav
 	pdev->prop.sink_ports = GENMASK(WSA881X_MAX_SWR_PORTS - 1, 0);
 	pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop;
 	pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY;
-	gpiod_direction_output(wsa881x->sd_n, 1);
+	gpiod_direction_output(wsa881x->sd_n, !wsa881x->sd_n_val);
 
 	wsa881x->regmap = devm_regmap_init_sdw(pdev, &wsa881x_regmap_config);
 	if (IS_ERR(wsa881x->regmap)) {
@@ -1159,7 +1184,7 @@ static int __maybe_unused wsa881x_runtim
 	struct regmap *regmap = dev_get_regmap(dev, NULL);
 	struct wsa881x_priv *wsa881x = dev_get_drvdata(dev);
 
-	gpiod_direction_output(wsa881x->sd_n, 0);
+	gpiod_direction_output(wsa881x->sd_n, wsa881x->sd_n_val);
 
 	regcache_cache_only(regmap, true);
 	regcache_mark_dirty(regmap);
@@ -1174,13 +1199,13 @@ static int __maybe_unused wsa881x_runtim
 	struct wsa881x_priv *wsa881x = dev_get_drvdata(dev);
 	unsigned long time;
 
-	gpiod_direction_output(wsa881x->sd_n, 1);
+	gpiod_direction_output(wsa881x->sd_n, !wsa881x->sd_n_val);
 
 	time = wait_for_completion_timeout(&slave->initialization_complete,
 					   msecs_to_jiffies(WSA881X_PROBE_TIMEOUT));
 	if (!time) {
 		dev_err(dev, "Initialization not complete, timed out\n");
-		gpiod_direction_output(wsa881x->sd_n, 0);
+		gpiod_direction_output(wsa881x->sd_n, wsa881x->sd_n_val);
 		return -ETIMEDOUT;
 	}
 
author maintainer
#251 lore raw

PATCH 246/280 ASoC: codecs: wsa881x: Drop unused version readout

In reply to Greg Kroah-Hartman

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

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

From: Krzysztof Kozlowski <[email protected]>

[ Upstream commit 3d2a69eb503d15171a7ba51cf0b562728ac396b7 ]

Driver does not use the device version after reading it from the registers, so simplify by dropping unneeded code.

Stable-dep-of: 29d71b8a5a40 ("ASoC: codecs: wsa881x: fix unnecessary initialisation")

---
 sound/soc/codecs/wsa881x.c |    2 --
 1 file changed, 2 deletions(-)
sound/soc/codecs/wsa881x.c +0 -2
@@ -683,7 +683,6 @@ struct wsa881x_priv {
 	 * For backwards compatibility.
 	 */
 	unsigned int sd_n_val;
-	int version;
 	int active_ports;
 	bool port_prepared[WSA881X_MAX_SWR_PORTS];
 	bool port_enable[WSA881X_MAX_SWR_PORTS];
@@ -694,7 +693,6 @@ static void wsa881x_init(struct wsa881x_
 	struct regmap *rm = wsa881x->regmap;
 	unsigned int val = 0;
 
-	regmap_read(rm, WSA881X_CHIP_ID1, &wsa881x->version);
 	regmap_register_patch(wsa881x->regmap, wsa881x_rev_2_0,
 			      ARRAY_SIZE(wsa881x_rev_2_0));
 
author maintainer
#252 lore raw

PATCH 247/280 ASoC: codecs: wsa881x: fix unnecessary initialisation

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

[ Upstream commit 29d71b8a5a40708b3eed9ba4953bfc2312c9c776 ]

The soundwire update_status() callback may be called multiple times with the same ATTACHED status but initialisation should only be done when transitioning from UNATTACHED to ATTACHED.

---
 sound/soc/codecs/wsa881x.c |    9 +++++++++
 1 file changed, 9 insertions(+)
sound/soc/codecs/wsa881x.c +9 -0
@@ -684,6 +684,7 @@ struct wsa881x_priv {
 	 */
 	unsigned int sd_n_val;
 	int active_ports;
+	bool hw_init;
 	bool port_prepared[WSA881X_MAX_SWR_PORTS];
 	bool port_enable[WSA881X_MAX_SWR_PORTS];
 };
@@ -693,6 +694,9 @@ static void wsa881x_init(struct wsa881x_
 	struct regmap *rm = wsa881x->regmap;
 	unsigned int val = 0;
 
+	if (wsa881x->hw_init)
+		return;
+
 	regmap_register_patch(wsa881x->regmap, wsa881x_rev_2_0,
 			      ARRAY_SIZE(wsa881x_rev_2_0));
 
@@ -730,6 +734,8 @@ static void wsa881x_init(struct wsa881x_
 	regmap_update_bits(rm, WSA881X_OTP_REG_28, 0x3F, 0x3A);
 	regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG1, 0xFF, 0xB2);
 	regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG2, 0xFF, 0x05);
+
+	wsa881x->hw_init = true;
 }
 
 static int wsa881x_component_probe(struct snd_soc_component *comp)
@@ -1074,6 +1080,9 @@ static int wsa881x_update_status(struct
 {
 	struct wsa881x_priv *wsa881x = dev_get_drvdata(&slave->dev);
 
+	if (status == SDW_SLAVE_UNATTACHED)
+		wsa881x->hw_init = false;
+
 	if (status == SDW_SLAVE_ATTACHED && slave->dev_num > 0)
 		wsa881x_init(wsa881x);
 
author maintainer
#253 lore raw

PATCH 248/280 ASoC: codecs: wsa883x: fix unnecessary initialisation

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

[ Upstream commit 49aadf830eb048134d33ad7329d92ecff45d8dbb ]

The soundwire update_status() callback may be called multiple times with the same ATTACHED status but initialisation should only be done when transitioning from UNATTACHED to ATTACHED.

This avoids repeated initialisation of the codecs during boot of machines like the Lenovo ThinkPad X13s:

[   11.614523] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2
[   11.618022] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2
[   11.621377] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2
[   11.624065] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2
[   11.631382] wsa883x-codec sdw:1:0:0217:0202:00:2: WSA883X Version 1_1, Variant: WSA8835_V2
[   11.634424] wsa883x-codec sdw:1:0:0217:0202:00:2: WSA883X Version 1_1, Variant: WSA8835_V2
Fixes 43b8c7dc85a1 ("ASoC: codecs: add wsa883x amplifier support")
Cc Srinivas Kandagatla <[email protected]>
[ Adjust context ]
---
 sound/soc/codecs/wsa883x.c |    9 +++++++++
 1 file changed, 9 insertions(+)
sound/soc/codecs/wsa883x.c +9 -0
@@ -448,6 +448,7 @@ struct wsa883x_priv {
 	int active_ports;
 	int dev_mode;
 	int comp_offset;
+	bool hw_init;
 };
 
 enum {
@@ -1007,6 +1008,9 @@ static int wsa883x_init(struct wsa883x_p
 	struct regmap *regmap = wsa883x->regmap;
 	int variant, version, ret;
 
+	if (wsa883x->hw_init)
+		return 0;
+
 	ret = regmap_read(regmap, WSA883X_OTP_REG_0, &variant);
 	if (ret)
 		return ret;
@@ -1050,6 +1054,8 @@ static int wsa883x_init(struct wsa883x_p
 				   wsa883x->comp_offset);
 	}
 
+	wsa883x->hw_init = true;
+
 	return 0;
 }
 
@@ -1058,6 +1064,9 @@ static int wsa883x_update_status(struct
 {
 	struct wsa883x_priv *wsa883x = dev_get_drvdata(&slave->dev);
 
+	if (status == SDW_SLAVE_UNATTACHED)
+		wsa883x->hw_init = false;
+
 	if (status == SDW_SLAVE_ATTACHED && slave->dev_num > 0)
 		return wsa883x_init(wsa883x);
 
author maintainer
#254 lore raw

PATCH 249/280 x86/fpu: Clear XSTATE_BV[i] in guest XSAVE state whenever XFD[i]=1

In reply to Greg Kroah-Hartman

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

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

From: Sean Christopherson <[email protected]>

[ Upstream commit b45f721775947a84996deb5c661602254ce25ce6 ]

When loading guest XSAVE state via KVM_SET_XSAVE, and when updating XFD in response to a guest WRMSR, clear XFD-disabled features in the saved (or to be restored) XSTATE_BV to ensure KVM doesn't attempt to load state for features that are disabled via the guest's XFD. Because the kernel executes XRSTOR with the guest's XFD, saving XSTATE_BV[i]=1 with XFD[i]=1 will cause XRSTOR to #NM and panic the kernel.

E.g. if fpu_update_guest_xfd() sets XFD without clearing XSTATE_BV:

  ------------[ cut here ]------------
  WARNING: arch/x86/kernel/traps.c:1524 at exc_device_not_available+0x101/0x110, CPU#29: amx_test/848
  Modules linked in: kvm_intel kvm irqbypass
  CPU: 29 UID: 1000 PID: 848 Comm: amx_test Not tainted 6.19.0-rc2-ffa07f7fd437-x86_amx_nm_xfd_non_init-vm #171 NONE
  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
  RIP: 0010:exc_device_not_available+0x101/0x110
  Call Trace:
   <TASK>
   asm_exc_device_not_available+0x1a/0x20
  RIP: 0010:restore_fpregs_from_fpstate+0x36/0x90
   switch_fpu_return+0x4a/0xb0
   kvm_arch_vcpu_ioctl_run+0x1245/0x1e40 [kvm]
   kvm_vcpu_ioctl+0x2c3/0x8f0 [kvm]
   __x64_sys_ioctl+0x8f/0xd0
   do_syscall_64+0x62/0x940
   entry_SYSCALL_64_after_hwframe+0x4b/0x53
   </TASK>
  ---[ end trace 0000000000000000 ]---

This can happen if the guest executes WRMSR(MSR_IA32_XFD) to set XFD[18] = 1, and a host IRQ triggers kernel_fpu_begin() prior to the vmexit handler's call to fpu_update_guest_xfd().

and if userspace stuffs XSTATE_BV[i]=1 via KVM_SET_XSAVE:

  ------------[ cut here ]------------
  WARNING: arch/x86/kernel/traps.c:1524 at exc_device_not_available+0x101/0x110, CPU#14: amx_test/867
  Modules linked in: kvm_intel kvm irqbypass
  CPU: 14 UID: 1000 PID: 867 Comm: amx_test Not tainted 6.19.0-rc2-2dace9faccd6-x86_amx_nm_xfd_non_init-vm #168 NONE
  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
  RIP: 0010:exc_device_not_available+0x101/0x110
  Call Trace:
   <TASK>
   asm_exc_device_not_available+0x1a/0x20
  RIP: 0010:restore_fpregs_from_fpstate+0x36/0x90
   fpu_swap_kvm_fpstate+0x6b/0x120
   kvm_load_guest_fpu+0x30/0x80 [kvm]
   kvm_arch_vcpu_ioctl_run+0x85/0x1e40 [kvm]
   kvm_vcpu_ioctl+0x2c3/0x8f0 [kvm]
   __x64_sys_ioctl+0x8f/0xd0
   do_syscall_64+0x62/0x940
   entry_SYSCALL_64_after_hwframe+0x4b/0x53
   </TASK>
  ---[ end trace 0000000000000000 ]---

The new behavior is consistent with the AMX architecture. Per Intel's SDM, XSAVE saves XSTATE_BV as '0' for components that are disabled via XFD (and non-compacted XSAVE saves the initial configuration of the state component):

If XSAVE, XSAVEC, XSAVEOPT, or XSAVES is saving the state component i, the instruction does not generate #NM when XCR0[i] = IA32_XFD[i] = 1; instead, it operates as if XINUSE[i] = 0 (and the state component was in its initial state): it saves bit i of XSTATE_BV field of the XSAVE header as 0; in addition, XSAVE saves the initial configuration of the state component (the other instructions do not save state component i).

Alternatively, KVM could always do XRSTOR with XFD=0, e.g. by using a constant XFD based on the set of enabled features when XSAVEing for a struct fpu_guest. However, having XSTATE_BV[i]=1 for XFD-disabled features can only happen in the above interrupt case, or in similar scenarios involving preemption on preemptible kernels, because fpu_swap_kvm_fpstate()'s call to save_fpregs_to_fpstate() saves the outgoing FPU state with the current XFD; and that is (on all but the first WRMSR to XFD) the guest XFD.

Therefore, XFD can only go out of sync with XSTATE_BV in the above interrupt case, or in similar scenarios involving preemption on preemptible kernels, and it we can consider it (de facto) part of KVM ABI that KVM_GET_XSAVE returns XSTATE_BV[i]=0 for XFD-disabled features.

Fixes 820a6ee944e7 ("kvm: x86: Add emulation for IA32_XFD", 2022-01-14)

[Move clearing of XSTATE_BV from fpu_copy_uabi_to_guest_fpstate
to kvm_vcpu_ioctl_x86_set_xsave. - Paolo]

---
 arch/x86/kernel/fpu/core.c |   32 +++++++++++++++++++++++++++++---
 arch/x86/kvm/x86.c         |    9 +++++++++
 2 files changed, 38 insertions(+), 3 deletions(-)
arch/x86/kernel/fpu/core.c +29 -3
@@ -294,10 +294,29 @@ EXPORT_SYMBOL_GPL(fpu_enable_guest_xfd_f
 #ifdef CONFIG_X86_64
 void fpu_update_guest_xfd(struct fpu_guest *guest_fpu, u64 xfd)
 {
+	struct fpstate *fpstate = guest_fpu->fpstate;
+
 	fpregs_lock();
-	guest_fpu->fpstate->xfd = xfd;
-	if (guest_fpu->fpstate->in_use)
-		xfd_update_state(guest_fpu->fpstate);
+
+	/*
+	 * KVM's guest ABI is that setting XFD[i]=1 *can* immediately revert the
+	 * save state to its initial configuration.  Likewise, KVM_GET_XSAVE does
+	 * the same as XSAVE and returns XSTATE_BV[i]=0 whenever XFD[i]=1.
+	 *
+	 * If the guest's FPU state is in hardware, just update XFD: the XSAVE
+	 * in fpu_swap_kvm_fpstate will clear XSTATE_BV[i] whenever XFD[i]=1.
+	 *
+	 * If however the guest's FPU state is NOT resident in hardware, clear
+	 * disabled components in XSTATE_BV now, or a subsequent XRSTOR will
+	 * attempt to load disabled components and generate #NM _in the host_.
+	 */
+	if (xfd && test_thread_flag(TIF_NEED_FPU_LOAD))
+		fpstate->regs.xsave.header.xfeatures &= ~xfd;
+
+	fpstate->xfd = xfd;
+	if (fpstate->in_use)
+		xfd_update_state(fpstate);
+
 	fpregs_unlock();
 }
 EXPORT_SYMBOL_GPL(fpu_update_guest_xfd);
@@ -406,6 +425,13 @@ int fpu_copy_uabi_to_guest_fpstate(struc
 		return -EINVAL;
 
 	/*
+	 * Disabled features must be in their initial state, otherwise XRSTOR
+	 * causes an exception.
+	 */
+	if (WARN_ON_ONCE(ustate->xsave.header.xfeatures & kstate->xfd))
+		return -EINVAL;
+
+	/*
 	 * Nullify @vpkru to preserve its current value if PKRU's bit isn't set
 	 * in the header.  KVM's odd ABI is to leave PKRU untouched in this
 	 * case (all other components are eventually re-initialized).
arch/x86/kvm/x86.c +9 -0
@@ -5341,9 +5341,18 @@ static void kvm_vcpu_ioctl_x86_get_xsave
 static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
 					struct kvm_xsave *guest_xsave)
 {
+	union fpregs_state *xstate = (union fpregs_state *)guest_xsave->region;
+
 	if (fpstate_is_confidential(&vcpu->arch.guest_fpu))
 		return 0;
 
+	/*
+	 * For backwards compatibility, do not expect disabled features to be in
+	 * their initial state.  XSTATE_BV[i] must still be cleared whenever
+	 * XFD[i]=1, or XRSTOR would cause a #NM.
+	 */
+	xstate->xsave.header.xfeatures &= ~vcpu->arch.guest_fpu.fpstate->xfd;
+
 	return fpu_copy_uabi_to_guest_fpstate(&vcpu->arch.guest_fpu,
 					      guest_xsave->region,
 					      kvm_caps.supported_xcr0,
author maintainer
#255 lore raw

PATCH 250/280 team: Move team device type change at the end of team_port_add

In reply to Greg Kroah-Hartman

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

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

From: "Nikola Z. Ivanov" <[email protected]>

[ Upstream commit 0ae9cfc454ea5ead5f3ddbdfe2e70270d8e2c8ef ]

Attempting to add a port device that is already up will expectedly fail, but not before modifying the team device header_ops.

In the case of the syzbot reproducer the gre0 device is already in state UP when it attempts to add it as a
port device of team0, this fails but before that header_ops->create of team0 is changed from eth_header to ipgre_header in the call to team_dev_type_check_change.

Later when we end up in ipgre_header() struct ip_tunnel* points to nonsense as the private data of the device still holds a struct team.

Example sequence of iproute2 commands to reproduce the hang/BUG():
ip link add dev team0 type team
ip link add dev gre0 type gre
ip link set dev gre0 up
ip link set dev gre0 master team0
ip link set dev team0 up
ping -I team0 1.1.1.1

Move team_dev_type_check_change down where all other checks have passed as it changes the dev type with no way to restore it in case one of the checks that follow it fail.

Also make sure to preserve the origial mtu assignment:
- If port_dev is not the same type as dev, dev takes mtu from port_dev
- If port_dev is the same type as dev, port_dev takes mtu from dev

This is done by adding a conditional before the call to dev_set_mtu to prevent it from assigning port_dev->mtu = dev->mtu and instead letting team_dev_type_check_change assign dev->mtu = port_dev->mtu. The conditional is needed because the patch moves the call to team_dev_type_check_change past dev_set_mtu.

Testing:
- team device driver in-tree selftests
- Add/remove various devices as slaves of team device
- syzbot

---
 drivers/net/team/team.c |   23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)
drivers/net/team/team.c +15 -8
@@ -1186,10 +1186,6 @@ static int team_port_add(struct team *te
 		return -EPERM;
 	}
 
-	err = team_dev_type_check_change(dev, port_dev);
-	if (err)
-		return err;
-
 	if (port_dev->flags & IFF_UP) {
 		NL_SET_ERR_MSG(extack, "Device is up. Set it down before adding it as a team port");
 		netdev_err(dev, "Device %s is up. Set it down before adding it as a team port\n",
@@ -1207,10 +1203,16 @@ static int team_port_add(struct team *te
 	INIT_LIST_HEAD(&port->qom_list);
 
 	port->orig.mtu = port_dev->mtu;
-	err = dev_set_mtu(port_dev, dev->mtu);
-	if (err) {
-		netdev_dbg(dev, "Error %d calling dev_set_mtu\n", err);
-		goto err_set_mtu;
+	/*
+	 * MTU assignment will be handled in team_dev_type_check_change
+	 * if dev and port_dev are of different types
+	 */
+	if (dev->type == port_dev->type) {
+		err = dev_set_mtu(port_dev, dev->mtu);
+		if (err) {
+			netdev_dbg(dev, "Error %d calling dev_set_mtu\n", err);
+			goto err_set_mtu;
+		}
 	}
 
 	memcpy(port->orig.dev_addr, port_dev->dev_addr, port_dev->addr_len);
@@ -1285,6 +1287,10 @@ static int team_port_add(struct team *te
 		}
 	}
 
+	err = team_dev_type_check_change(dev, port_dev);
+	if (err)
+		goto err_set_dev_type;
+
 	if (dev->flags & IFF_UP) {
 		netif_addr_lock_bh(dev);
 		dev_uc_sync_multiple(port_dev, dev);
@@ -1303,6 +1309,7 @@ static int team_port_add(struct team *te
 
 	return 0;
 
+err_set_dev_type:
 err_set_slave_promisc:
 	__team_option_inst_del_port(team, port);
 
author maintainer
#256 lore raw

PATCH 251/280 wifi: mac80211: use wiphy work for sdata->work

In reply to Greg Kroah-Hartman

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

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

From: Johannes Berg <[email protected]>

[ Upstream commit 16114496d684a3df4ce09f7c6b7557a8b2922795 ]

We'll need this later to convert other works that might be cancelled from here, so convert this one first.

(cherry picked from commit 16114496d684a3df4ce09f7c6b7557a8b2922795)
---
 net/mac80211/ibss.c        |    8 ++++----
 net/mac80211/ieee80211_i.h |    2 +-
 net/mac80211/iface.c       |   10 +++++-----
 net/mac80211/mesh.c        |   10 +++++-----
 net/mac80211/mesh_hwmp.c   |    6 +++---
 net/mac80211/mlme.c        |    6 +++---
 net/mac80211/ocb.c         |    6 +++---
 net/mac80211/rx.c          |    2 +-
 net/mac80211/scan.c        |    2 +-
 net/mac80211/status.c      |    6 +++---
 net/mac80211/util.c        |    2 +-
 11 files changed, 30 insertions(+), 30 deletions(-)
net/mac80211/ibss.c +4 -4
@@ -741,7 +741,7 @@ static void ieee80211_csa_connection_dro
 	skb_queue_purge(&sdata->skb_queue);
 
 	/* trigger a scan to find another IBSS network to join */
-	ieee80211_queue_work(&sdata->local->hw, &sdata->work);
+	wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work);
 
 	sdata_unlock(sdata);
 }
@@ -1242,7 +1242,7 @@ void ieee80211_ibss_rx_no_sta(struct iee
 	spin_lock(&ifibss->incomplete_lock);
 	list_add(&sta->list, &ifibss->incomplete_stations);
 	spin_unlock(&ifibss->incomplete_lock);
-	ieee80211_queue_work(&local->hw, &sdata->work);
+	wiphy_work_queue(local->hw.wiphy, &sdata->work);
 }
 
 static void ieee80211_ibss_sta_expire(struct ieee80211_sub_if_data *sdata)
@@ -1721,7 +1721,7 @@ static void ieee80211_ibss_timer(struct
 	struct ieee80211_sub_if_data *sdata =
 		from_timer(sdata, t, u.ibss.timer);
 
-	ieee80211_queue_work(&sdata->local->hw, &sdata->work);
+	wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work);
 }
 
 void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)
@@ -1856,7 +1856,7 @@ int ieee80211_ibss_join(struct ieee80211
 	sdata->deflink.needed_rx_chains = local->rx_chains;
 	sdata->control_port_over_nl80211 = params->control_port_over_nl80211;
 
-	ieee80211_queue_work(&local->hw, &sdata->work);
+	wiphy_work_queue(local->hw.wiphy, &sdata->work);
 
 	return 0;
 }
net/mac80211/ieee80211_i.h +1 -1
@@ -1046,7 +1046,7 @@ struct ieee80211_sub_if_data {
 	/* used to reconfigure hardware SM PS */
 	struct work_struct recalc_smps;
 
-	struct work_struct work;
+	struct wiphy_work work;
 	struct sk_buff_head skb_queue;
 	struct sk_buff_head status_queue;
 
net/mac80211/iface.c +5 -5
@@ -43,7 +43,7 @@
  * by either the RTNL, the iflist_mtx or RCU.
  */
 
-static void ieee80211_iface_work(struct work_struct *work);
+static void ieee80211_iface_work(struct wiphy *wiphy, struct wiphy_work *work);
 
 bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
 {
@@ -650,7 +650,7 @@ static void ieee80211_do_stop(struct iee
 		RCU_INIT_POINTER(local->p2p_sdata, NULL);
 		fallthrough;
 	default:
-		cancel_work_sync(&sdata->work);
+		wiphy_work_cancel(sdata->local->hw.wiphy, &sdata->work);
 		/*
 		 * When we get here, the interface is marked down.
 		 * Free the remaining keys, if there are any
@@ -1224,7 +1224,7 @@ int ieee80211_add_virtual_monitor(struct
 
 	skb_queue_head_init(&sdata->skb_queue);
 	skb_queue_head_init(&sdata->status_queue);
-	INIT_WORK(&sdata->work, ieee80211_iface_work);
+	wiphy_work_init(&sdata->work, ieee80211_iface_work);
 
 	return 0;
 }
@@ -1707,7 +1707,7 @@ static void ieee80211_iface_process_stat
 	}
 }
 
-static void ieee80211_iface_work(struct work_struct *work)
+static void ieee80211_iface_work(struct wiphy *wiphy, struct wiphy_work *work)
 {
 	struct ieee80211_sub_if_data *sdata =
 		container_of(work, struct ieee80211_sub_if_data, work);
@@ -1819,7 +1819,7 @@ static void ieee80211_setup_sdata(struct
 
 	skb_queue_head_init(&sdata->skb_queue);
 	skb_queue_head_init(&sdata->status_queue);
-	INIT_WORK(&sdata->work, ieee80211_iface_work);
+	wiphy_work_init(&sdata->work, ieee80211_iface_work);
 	INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work);
 	INIT_WORK(&sdata->activate_links_work, ieee80211_activate_links_work);
 
net/mac80211/mesh.c +5 -5
@@ -44,7 +44,7 @@ static void ieee80211_mesh_housekeeping_
 
 	set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags);
 
-	ieee80211_queue_work(&local->hw, &sdata->work);
+	wiphy_work_queue(local->hw.wiphy, &sdata->work);
 }
 
 /**
@@ -643,7 +643,7 @@ static void ieee80211_mesh_path_timer(st
 	struct ieee80211_sub_if_data *sdata =
 		from_timer(sdata, t, u.mesh.mesh_path_timer);
 
-	ieee80211_queue_work(&sdata->local->hw, &sdata->work);
+	wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work);
 }
 
 static void ieee80211_mesh_path_root_timer(struct timer_list *t)
@@ -654,7 +654,7 @@ static void ieee80211_mesh_path_root_tim
 
 	set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);
 
-	ieee80211_queue_work(&sdata->local->hw, &sdata->work);
+	wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work);
 }
 
 void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh)
@@ -1018,7 +1018,7 @@ void ieee80211_mbss_info_change_notify(s
 	for_each_set_bit(bit, &bits, sizeof(changed) * BITS_PER_BYTE)
 		set_bit(bit, &ifmsh->mbss_changed);
 	set_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags);
-	ieee80211_queue_work(&sdata->local->hw, &sdata->work);
+	wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work);
 }
 
 int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
@@ -1043,7 +1043,7 @@ int ieee80211_start_mesh(struct ieee8021
 	ifmsh->sync_offset_clockdrift_max = 0;
 	set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags);
 	ieee80211_mesh_root_setup(ifmsh);
-	ieee80211_queue_work(&local->hw, &sdata->work);
+	wiphy_work_queue(local->hw.wiphy, &sdata->work);
 	sdata->vif.bss_conf.ht_operation_mode =
 				ifmsh->mshcfg.ht_opmode;
 	sdata->vif.bss_conf.enable_beacon = true;
net/mac80211/mesh_hwmp.c +3 -3
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2008, 2009 open80211s Ltd.
- * Copyright (C) 2019, 2021-2022 Intel Corporation
+ * Copyright (C) 2019, 2021-2023 Intel Corporation
  * Author:     Luis Carlos Cobo <[email protected]>
  */
 
@@ -1025,14 +1025,14 @@ static void mesh_queue_preq(struct mesh_
 	spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
 
 	if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata)))
-		ieee80211_queue_work(&sdata->local->hw, &sdata->work);
+		wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work);
 
 	else if (time_before(jiffies, ifmsh->last_preq)) {
 		/* avoid long wait if did not send preqs for a long time
 		 * and jiffies wrapped around
 		 */
 		ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1;
-		ieee80211_queue_work(&sdata->local->hw, &sdata->work);
+		wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work);
 	} else
 		mod_timer(&ifmsh->mesh_path_timer, ifmsh->last_preq +
 						min_preq_int_jiff(sdata));
net/mac80211/mlme.c +3 -3
@@ -3168,7 +3168,7 @@ void ieee80211_sta_tx_notify(struct ieee
 		sdata->u.mgd.probe_send_count = 0;
 	else
 		sdata->u.mgd.nullfunc_failed = true;
-	ieee80211_queue_work(&sdata->local->hw, &sdata->work);
+	wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work);
 }
 
 static void ieee80211_mlme_send_probe_req(struct ieee80211_sub_if_data *sdata,
@@ -6031,7 +6031,7 @@ static void ieee80211_sta_timer(struct t
 	struct ieee80211_sub_if_data *sdata =
 		from_timer(sdata, t, u.mgd.timer);
 
-	ieee80211_queue_work(&sdata->local->hw, &sdata->work);
+	wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work);
 }
 
 void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
@@ -6175,7 +6175,7 @@ void ieee80211_mgd_conn_tx_status(struct
 	sdata->u.mgd.status_acked = acked;
 	sdata->u.mgd.status_received = true;
 
-	ieee80211_queue_work(&local->hw, &sdata->work);
+	wiphy_work_queue(local->hw.wiphy, &sdata->work);
 }
 
 void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
net/mac80211/ocb.c +3 -3
@@ -81,7 +81,7 @@ void ieee80211_ocb_rx_no_sta(struct ieee
 	spin_lock(&ifocb->incomplete_lock);
 	list_add(&sta->list, &ifocb->incomplete_stations);
 	spin_unlock(&ifocb->incomplete_lock);
-	ieee80211_queue_work(&local->hw, &sdata->work);
+	wiphy_work_queue(local->hw.wiphy, &sdata->work);
 }
 
 static struct sta_info *ieee80211_ocb_finish_sta(struct sta_info *sta)
@@ -157,7 +157,7 @@ static void ieee80211_ocb_housekeeping_t
 
 	set_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags);
 
-	ieee80211_queue_work(&local->hw, &sdata->work);
+	wiphy_work_queue(local->hw.wiphy, &sdata->work);
 }
 
 void ieee80211_ocb_setup_sdata(struct ieee80211_sub_if_data *sdata)
@@ -197,7 +197,7 @@ int ieee80211_ocb_join(struct ieee80211_
 	ifocb->joined = true;
 
 	set_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags);
-	ieee80211_queue_work(&local->hw, &sdata->work);
+	wiphy_work_queue(local->hw.wiphy, &sdata->work);
 
 	netif_carrier_on(sdata->dev);
 	return 0;
net/mac80211/rx.c +1 -1
@@ -229,7 +229,7 @@ static void __ieee80211_queue_skb_to_ifa
 	}
 
 	skb_queue_tail(&sdata->skb_queue, skb);
-	ieee80211_queue_work(&sdata->local->hw, &sdata->work);
+	wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work);
 	if (sta)
 		sta->deflink.rx_stats.packets++;
 }
net/mac80211/scan.c +1 -1
@@ -503,7 +503,7 @@ static void __ieee80211_scan_completed(s
 	 */
 	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
 		if (ieee80211_sdata_running(sdata))
-			ieee80211_queue_work(&sdata->local->hw, &sdata->work);
+			wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work);
 	}
 
 	if (was_scanning)
net/mac80211/status.c +3 -3
@@ -5,7 +5,7 @@
  * Copyright 2006-2007	Jiri Benc <[email protected]>
  * Copyright 2008-2010	Johannes Berg <[email protected]>
  * Copyright 2013-2014  Intel Mobile Communications GmbH
- * Copyright 2021-2022  Intel Corporation
+ * Copyright 2021-2023  Intel Corporation
  */
 
 #include <linux/export.h>
@@ -747,8 +747,8 @@ static void ieee80211_report_used_skb(st
 					if (qskb) {
 						skb_queue_tail(&sdata->status_queue,
 							       qskb);
-						ieee80211_queue_work(&local->hw,
-								     &sdata->work);
+						wiphy_work_queue(local->hw.wiphy,
+								 &sdata->work);
 					}
 				}
 			} else {
net/mac80211/util.c +1 -1
@@ -2751,7 +2751,7 @@ int ieee80211_reconfig(struct ieee80211_
 
 		/* Requeue all works */
 		list_for_each_entry(sdata, &local->interfaces, list)
-			ieee80211_queue_work(&local->hw, &sdata->work);
+			wiphy_work_queue(local->hw.wiphy, &sdata->work);
 	}
 
 	ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
author maintainer
#257 lore raw

PATCH 252/280 wifi: mac80211: move TDLS work to wiphy work

In reply to Greg Kroah-Hartman

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

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

From: Johannes Berg <[email protected]>

[ Upstream commit 777b26002b73127e81643d9286fadf3d41e0e477 ]

Again, to have the wiphy locked for it.

[ Summary of conflict resolutions:
- In mlme.c, move only tdls_peer_del_work
to wiphy work, and none the other works ]

---
 net/mac80211/ieee80211_i.h |    4 ++--
 net/mac80211/mlme.c        |    7 ++++---
 net/mac80211/tdls.c        |   11 ++++++-----
 3 files changed, 12 insertions(+), 10 deletions(-)
net/mac80211/ieee80211_i.h +2 -2
@@ -531,7 +531,7 @@ struct ieee80211_if_managed {
 
 	/* TDLS support */
 	u8 tdls_peer[ETH_ALEN] __aligned(2);
-	struct delayed_work tdls_peer_del_work;
+	struct wiphy_delayed_work tdls_peer_del_work;
 	struct sk_buff *orig_teardown_skb; /* The original teardown skb */
 	struct sk_buff *teardown_skb; /* A copy to send through the AP */
 	spinlock_t teardown_lock; /* To lock changing teardown_skb */
@@ -2525,7 +2525,7 @@ int ieee80211_tdls_mgmt(struct wiphy *wi
 			size_t extra_ies_len);
 int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
 			const u8 *peer, enum nl80211_tdls_operation oper);
-void ieee80211_tdls_peer_del_work(struct work_struct *wk);
+void ieee80211_tdls_peer_del_work(struct wiphy *wiphy, struct wiphy_work *wk);
 int ieee80211_tdls_channel_switch(struct wiphy *wiphy, struct net_device *dev,
 				  const u8 *addr, u8 oper_class,
 				  struct cfg80211_chan_def *chandef);
net/mac80211/mlme.c +4 -3
@@ -6517,8 +6517,8 @@ void ieee80211_sta_setup_sdata(struct ie
 		  ieee80211_beacon_connection_loss_work);
 	INIT_WORK(&ifmgd->csa_connection_drop_work,
 		  ieee80211_csa_connection_drop_work);
-	INIT_DELAYED_WORK(&ifmgd->tdls_peer_del_work,
-			  ieee80211_tdls_peer_del_work);
+	wiphy_delayed_work_init(&ifmgd->tdls_peer_del_work,
+				ieee80211_tdls_peer_del_work);
 	timer_setup(&ifmgd->timer, ieee80211_sta_timer, 0);
 	timer_setup(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, 0);
 	timer_setup(&ifmgd->conn_mon_timer, ieee80211_sta_conn_mon_timer, 0);
@@ -7524,7 +7524,8 @@ void ieee80211_mgd_stop(struct ieee80211
 	cancel_work_sync(&ifmgd->monitor_work);
 	cancel_work_sync(&ifmgd->beacon_connection_loss_work);
 	cancel_work_sync(&ifmgd->csa_connection_drop_work);
-	cancel_delayed_work_sync(&ifmgd->tdls_peer_del_work);
+	wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
+				  &ifmgd->tdls_peer_del_work);
 
 	sdata_lock(sdata);
 	if (ifmgd->assoc_data)
net/mac80211/tdls.c +6 -5
@@ -21,7 +21,7 @@
 /* give usermode some time for retries in setting up the TDLS session */
 #define TDLS_PEER_SETUP_TIMEOUT	(15 * HZ)
 
-void ieee80211_tdls_peer_del_work(struct work_struct *wk)
+void ieee80211_tdls_peer_del_work(struct wiphy *wiphy, struct wiphy_work *wk)
 {
 	struct ieee80211_sub_if_data *sdata;
 	struct ieee80211_local *local;
@@ -1128,9 +1128,9 @@ ieee80211_tdls_mgmt_setup(struct wiphy *
 		return ret;
 	}
 
-	ieee80211_queue_delayed_work(&sdata->local->hw,
-				     &sdata->u.mgd.tdls_peer_del_work,
-				     TDLS_PEER_SETUP_TIMEOUT);
+	wiphy_delayed_work_queue(sdata->local->hw.wiphy,
+				 &sdata->u.mgd.tdls_peer_del_work,
+				 TDLS_PEER_SETUP_TIMEOUT);
 	return 0;
 
 out_unlock:
@@ -1427,7 +1427,8 @@ int ieee80211_tdls_oper(struct wiphy *wi
 	}
 
 	if (ret == 0 && ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) {
-		cancel_delayed_work(&sdata->u.mgd.tdls_peer_del_work);
+		wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
+					  &sdata->u.mgd.tdls_peer_del_work);
 		eth_zero_addr(sdata->u.mgd.tdls_peer);
 	}
 
author maintainer
#258 lore raw

PATCH 253/280 genirq/irq_sim: Initialize work context pointers properly

In reply to Greg Kroah-Hartman

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

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

From: Gyeyoung Baek <[email protected]>

[ Upstream commit 8a2277a3c9e4cc5398f80821afe7ecbe9bdf2819 ]

Initialize ops member's pointers properly by using kzalloc() instead of kmalloc() when allocating the simulation work context. Otherwise the pointers contain random content leading to invalid dereferencing.

[ The context change is due to the commit 011f583781fa ("genirq/irq_sim: add an extended irq_sim initializer") which is irrelevant to the logic of this patch. ]

---
 kernel/irq/irq_sim.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/irq/irq_sim.c +1 -1
@@ -166,7 +166,7 @@ struct irq_domain *irq_domain_create_sim
 {
 	struct irq_sim_work_ctx *work_ctx;
 
-	work_ctx = kmalloc(sizeof(*work_ctx), GFP_KERNEL);
+	work_ctx = kzalloc(sizeof(*work_ctx), GFP_KERNEL);
 	if (!work_ctx)
 		goto err_out;
 
author maintainer
#259 lore raw

PATCH 254/280 drm/amdkfd: fix a memory leak in device_queue_manager_init()

In reply to Greg Kroah-Hartman

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

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

From: Haoxiang Li <[email protected]>

commit 80614c509810fc051312d1a7ccac8d0012d6b8d0 upstream.

If dqm->ops.initialize() fails, add deallocate_hiq_sdma_mqd() to release the memory allocated by allocate_hiq_sdma_mqd(). Move deallocate_hiq_sdma_mqd() up to ensure proper function visibility at the point of use.

Fixes 11614c36bc8f ("drm/amdkfd: Allocate MQD trunk for HIQ and SDMA")
(cherry picked from commit b7cccc8286bb9919a0952c812872da1dcfe9d390)
---
 drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c |   18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +10 -8
@@ -2257,6 +2257,14 @@ static int allocate_hiq_sdma_mqd(struct
 	return retval;
 }
 
+static void deallocate_hiq_sdma_mqd(struct kfd_dev *dev,
+				    struct kfd_mem_obj *mqd)
+{
+	WARN(!mqd, "No hiq sdma mqd trunk to free");
+
+	amdgpu_amdkfd_free_gtt_mem(dev->adev, &mqd->gtt_mem);
+}
+
 struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
 {
 	struct device_queue_manager *dqm;
@@ -2382,19 +2390,13 @@ struct device_queue_manager *device_queu
 	if (!dqm->ops.initialize(dqm))
 		return dqm;
 
+	deallocate_hiq_sdma_mqd(dev, &dqm->hiq_sdma_mqd);
+
 out_free:
 	kfree(dqm);
 	return NULL;
 }
 
-static void deallocate_hiq_sdma_mqd(struct kfd_dev *dev,
-				    struct kfd_mem_obj *mqd)
-{
-	WARN(!mqd, "No hiq sdma mqd trunk to free");
-
-	amdgpu_amdkfd_free_gtt_mem(dev->adev, &mqd->gtt_mem);
-}
-
 void device_queue_manager_uninit(struct device_queue_manager *dqm)
 {
 	dqm->ops.uninitialize(dqm);
author maintainer
#260 lore raw

PATCH 255/280 can: esd_usb: esd_usb_read_bulk_callback(): fix URB memory leak

In reply to Greg Kroah-Hartman

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

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

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

commit 5a4391bdc6c8357242f62f22069c865b792406b3 upstream.

Fix similar memory leak as in commit 7352e1d5932a ("can: gs_usb:
gs_usb_receive_bulk_callback(): fix URB memory leak").

In esd_usb_open(), the URBs for USB-in transfers are allocated, added to the dev->rx_submitted anchor and submitted. In the complete callback esd_usb_read_bulk_callback(), the URBs are processed and resubmitted. In esd_usb_close() the URBs are freed by calling usb_kill_anchored_urbs(&dev->rx_submitted).

However, this does not take into account that the USB framework unanchors the URB before the complete function is called. This means that once an in-URB has been completed, it is no longer anchored and is ultimately not released in esd_usb_close().

Fix the memory leak by anchoring the URB in the esd_usb_read_bulk_callback() to the dev->rx_submitted anchor.

---
 drivers/net/can/usb/esd_usb.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/net/can/usb/esd_usb.c +8 -1
@@ -447,13 +447,20 @@ resubmit_urb:
 			  urb->transfer_buffer, RX_BUFFER_SIZE,
 			  esd_usb_read_bulk_callback, dev);
 
+	usb_anchor_urb(urb, &dev->rx_submitted);
+
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
+	if (!retval)
+		return;
+
+	usb_unanchor_urb(urb);
+
 	if (retval == -ENODEV) {
 		for (i = 0; i < dev->net_count; i++) {
 			if (dev->nets[i])
 				netif_device_detach(dev->nets[i]->netdev);
 		}
-	} else if (retval) {
+	} else {
 		dev_err(dev->udev->dev.parent,
 			"failed resubmitting read bulk urb: %d\n", retval);
 	}
author maintainer
#261 lore raw

PATCH 256/280 Revert "mm/mprotect: delete pmd_none_or_clear_bad_unless_trans_huge()"

In reply to Greg Kroah-Hartman

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

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

From: Harry Yoo <[email protected]>

This reverts commit 91750c8a4be42d73b6810a1c35d73c8a3cd0b481 which is commit 670ddd8cdcbd1d07a4571266ae3517f821728c3a upstream.

While the commit fixes a race condition between NUMA balancing and THP migration, it causes a NULL-pointer-deref when the pmd temporarily transitions from pmd_trans_huge() to pmd_none(). Verifying whether the pmd value has changed under page table lock does not prevent the crash, as it occurs when acquiring the lock.

Since the original issue addressed by the commit is quite rare and non-fatal, revert the commit. A better backport solution that more closely matches the upstream semantics will be provided as a follow-up.

---
 mm/mprotect.c |  101 +++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 58 insertions(+), 43 deletions(-)
mm/mprotect.c +58 -43
@@ -73,12 +73,10 @@ static inline bool can_change_pte_writab
 }
 
 static long change_pte_range(struct mmu_gather *tlb,
-		struct vm_area_struct *vma, pmd_t *pmd, pmd_t pmd_old,
-		unsigned long addr, unsigned long end, pgprot_t newprot,
-		unsigned long cp_flags)
+		struct vm_area_struct *vma, pmd_t *pmd, unsigned long addr,
+		unsigned long end, pgprot_t newprot, unsigned long cp_flags)
 {
 	pte_t *pte, oldpte;
-	pmd_t _pmd;
 	spinlock_t *ptl;
 	long pages = 0;
 	int target_node = NUMA_NO_NODE;
@@ -88,15 +86,21 @@ static long change_pte_range(struct mmu_
 
 	tlb_change_page_size(tlb, PAGE_SIZE);
 
+	/*
+	 * Can be called with only the mmap_lock for reading by
+	 * prot_numa so we must check the pmd isn't constantly
+	 * changing from under us from pmd_none to pmd_trans_huge
+	 * and/or the other way around.
+	 */
+	if (pmd_trans_unstable(pmd))
+		return 0;
+
+	/*
+	 * The pmd points to a regular pte so the pmd can't change
+	 * from under us even if the mmap_lock is only hold for
+	 * reading.
+	 */
 	pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
-	/* Make sure pmd didn't change after acquiring ptl */
-	_pmd = pmd_read_atomic(pmd);
-	/* See pmd_none_or_trans_huge_or_clear_bad for info on barrier */
-	barrier();
-	if (!pmd_same(pmd_old, _pmd)) {
-		pte_unmap_unlock(pte, ptl);
-		return -EAGAIN;
-	}
 
 	/* Get target node for single threaded private VMAs */
 	if (prot_numa && !(vma->vm_flags & VM_SHARED) &&
@@ -284,6 +288,31 @@ static long change_pte_range(struct mmu_
 	return pages;
 }
 
+/*
+ * Used when setting automatic NUMA hinting protection where it is
+ * critical that a numa hinting PMD is not confused with a bad PMD.
+ */
+static inline int pmd_none_or_clear_bad_unless_trans_huge(pmd_t *pmd)
+{
+	pmd_t pmdval = pmd_read_atomic(pmd);
+
+	/* See pmd_none_or_trans_huge_or_clear_bad for info on barrier */
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+	barrier();
+#endif
+
+	if (pmd_none(pmdval))
+		return 1;
+	if (pmd_trans_huge(pmdval))
+		return 0;
+	if (unlikely(pmd_bad(pmdval))) {
+		pmd_clear_bad(pmd);
+		return 1;
+	}
+
+	return 0;
+}
+
 /* Return true if we're uffd wr-protecting file-backed memory, or false */
 static inline bool
 uffd_wp_protect_file(struct vm_area_struct *vma, unsigned long cp_flags)
@@ -331,34 +360,22 @@ static inline long change_pmd_range(stru
 
 	pmd = pmd_offset(pud, addr);
 	do {
-		long ret;
-		pmd_t _pmd;
-again:
+		long this_pages;
+
 		next = pmd_addr_end(addr, end);
-		_pmd = pmd_read_atomic(pmd);
-		/* See pmd_none_or_trans_huge_or_clear_bad for info on barrier */
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-		barrier();
-#endif
 
 		change_pmd_prepare(vma, pmd, cp_flags);
 		/*
 		 * Automatic NUMA balancing walks the tables with mmap_lock
 		 * held for read. It's possible a parallel update to occur
-		 * between pmd_trans_huge(), is_swap_pmd(), and
-		 * a pmd_none_or_clear_bad() check leading to a false positive
-		 * and clearing. Hence, it's necessary to atomically read
-		 * the PMD value for all the checks.
+		 * between pmd_trans_huge() and a pmd_none_or_clear_bad()
+		 * check leading to a false positive and clearing.
+		 * Hence, it's necessary to atomically read the PMD value
+		 * for all the checks.
 		 */
-		if (!is_swap_pmd(_pmd) && !pmd_devmap(_pmd) && !pmd_trans_huge(_pmd)) {
-			if (pmd_none(_pmd))
-				goto next;
-
-			if (pmd_bad(_pmd)) {
-				pmd_clear_bad(pmd);
-				goto next;
-			}
-		}
+		if (!is_swap_pmd(*pmd) && !pmd_devmap(*pmd) &&
+		     pmd_none_or_clear_bad_unless_trans_huge(pmd))
+			goto next;
 
 		/* invoke the mmu notifier if the pmd is populated */
 		if (!range.start) {
@@ -368,7 +385,7 @@ again:
 			mmu_notifier_invalidate_range_start(&range);
 		}
 
-		if (is_swap_pmd(_pmd) || pmd_trans_huge(_pmd) || pmd_devmap(_pmd)) {
+		if (is_swap_pmd(*pmd) || pmd_trans_huge(*pmd) || pmd_devmap(*pmd)) {
 			if ((next - addr != HPAGE_PMD_SIZE) ||
 			    uffd_wp_protect_file(vma, cp_flags)) {
 				__split_huge_pmd(vma, pmd, addr, false, NULL);
@@ -383,11 +400,11 @@ again:
 				 * change_huge_pmd() does not defer TLB flushes,
 				 * so no need to propagate the tlb argument.
 				 */
-				ret = change_huge_pmd(tlb, vma, pmd,
-						      addr, newprot, cp_flags);
+				int nr_ptes = change_huge_pmd(tlb, vma, pmd,
+						addr, newprot, cp_flags);
 
-				if (ret) {
-					if (ret == HPAGE_PMD_NR) {
+				if (nr_ptes) {
+					if (nr_ptes == HPAGE_PMD_NR) {
 						pages += HPAGE_PMD_NR;
 						nr_huge_updates++;
 					}
@@ -398,11 +415,9 @@ again:
 			}
 			/* fall through, the trans huge pmd just split */
 		}
-		ret = change_pte_range(tlb, vma, pmd, _pmd, addr, next,
-				       newprot, cp_flags);
-		if (ret < 0)
-			goto again;
-		pages += ret;
+		this_pages = change_pte_range(tlb, vma, pmd, addr, next,
+					      newprot, cp_flags);
+		pages += this_pages;
 next:
 		cond_resched();
 	} while (pmd++, addr = next, addr != end);
author maintainer
#262 lore raw

PATCH 257/280 drm/amd/display: Check dce_hwseq before dereferencing it

In reply to Greg Kroah-Hartman

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

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

From: Alex Hung <[email protected]>

[ Upstream commit b669507b637eb6b1aaecf347f193efccc65d756e ]

[WHAT]

hws was checked for null earlier in dce110_blank_stream, indicating hws can be null, and should be checked whenever it is used.

Cc Mario Limonciello <[email protected]>
Cc Alex Deucher <[email protected]>
(cherry picked from commit 79db43611ff61280b6de58ce1305e0b2ecf675ad)

[ The context change is due to the commit 8e7b3f5435b3 ("drm/amd/display: Add control flag to dc_stream_state to skip eDP BL off/link off") and the commit a8728dbb4ba2 ("drm/amd/display: Refactor edp power control") and the proper adoption is done. ]

---
 drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +2 -1
@@ -1233,7 +1233,8 @@ void dce110_blank_stream(struct pipe_ctx
 	struct dce_hwseq *hws = link->dc->hwseq;
 
 	if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
-		hws->funcs.edp_backlight_control(link, false);
+		if (hws)
+			hws->funcs.edp_backlight_control(link, false);
 		link->dc->hwss.set_abm_immediate_disable(pipe_ctx);
 	}
 
author maintainer
#263 lore raw

PATCH 258/280 crypto: qat - flush misc workqueue during device shutdown

In reply to Greg Kroah-Hartman

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

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

From: Giovanni Cabiddu <[email protected]>

[ Upstream commit 3d4df408ba9bad2b205c7fb8afc1836a6a4ca88a ]

Repeated loading and unloading of a device specific QAT driver, for example qat_4xxx, in a tight loop can lead to a crash due to a use-after-free scenario. This occurs when a power management (PM) interrupt triggers just before the device-specific driver (e.g., qat_4xxx.ko) is unloaded, while the core driver (intel_qat.ko) remains loaded.

Since the driver uses a shared workqueue (qat_misc_wq) across all devices and owned by intel_qat.ko, a deferred routine from the device-specific driver may still be pending in the queue. If this routine executes after the driver is unloaded, it can dereference freed memory, resulting in a page fault and kernel crash like the following:

    BUG: unable to handle page fault for address: ffa000002e50a01c
    #PF: supervisor read access in kernel mode
    RIP: 0010:pm_bh_handler+0x1d2/0x250 [intel_qat]
    Call Trace:
      pm_bh_handler+0x1d2/0x250 [intel_qat]
      process_one_work+0x171/0x340
      worker_thread+0x277/0x3a0
      kthread+0xf0/0x120
      ret_from_fork+0x2d/0x50

To prevent this, flush the misc workqueue during device shutdown to ensure that all pending work items are completed before the driver is unloaded.

Note: This approach may slightly increase shutdown latency if the workqueue contains jobs from other devices, but it ensures correctness and stability.

Fixes e5745f34113b ("crypto: qat - enable power management for QAT GEN4")

[ Intel crypto drivers was moved by
a4b16dad4657 ("crypto: qat - Move driver to drivers/crypto/intel/qat") so apply the patch to files under drivers/crypto/qat/qat_common in 6.1.y. ]

---
 drivers/crypto/qat/qat_common/adf_common_drv.h |    1 +
 drivers/crypto/qat/qat_common/adf_init.c       |    1 +
 drivers/crypto/qat/qat_common/adf_isr.c        |    5 +++++
 3 files changed, 7 insertions(+)
drivers/crypto/qat/qat_common/adf_common_drv.h +1 -0
@@ -194,6 +194,7 @@ int qat_uclo_set_cfg_ae_mask(struct icp_
 int adf_init_misc_wq(void);
 void adf_exit_misc_wq(void);
 bool adf_misc_wq_queue_work(struct work_struct *work);
+void adf_misc_wq_flush(void);
 #if defined(CONFIG_PCI_IOV)
 int adf_sriov_configure(struct pci_dev *pdev, int numvfs);
 void adf_disable_sriov(struct adf_accel_dev *accel_dev);
drivers/crypto/qat/qat_common/adf_init.c +1 -0
@@ -337,6 +337,7 @@ void adf_dev_shutdown(struct adf_accel_d
 		hw_data->exit_admin_comms(accel_dev);
 
 	adf_cleanup_etr_data(accel_dev);
+	adf_misc_wq_flush();
 	adf_dev_restore(accel_dev);
 }
 EXPORT_SYMBOL_GPL(adf_dev_shutdown);
drivers/crypto/qat/qat_common/adf_isr.c +5 -0
@@ -380,3 +380,8 @@ bool adf_misc_wq_queue_work(struct work_
 {
 	return queue_work(adf_misc_wq, work);
 }
+
+void adf_misc_wq_flush(void)
+{
+	flush_workqueue(adf_misc_wq);
+}
author maintainer
#264 lore raw

PATCH 259/280 iomap: Fix possible overflow condition in iomap_write_delalloc_scan

In reply to Greg Kroah-Hartman

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

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

From: "Ritesh Harjani (IBM)" <[email protected]>

[ Upstream commit eee2d2e6ea5550118170dbd5bb1316ceb38455fb ]

folio_next_index() returns an unsigned long value which left shifted by PAGE_SHIFT could possibly cause an overflow on 32-bit system. Instead use folio_pos(folio) + folio_size(folio), which does this correctly.

---
 fs/iomap/buffered-io.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/iomap/buffered-io.c +1 -1
@@ -903,7 +903,7 @@ static int iomap_write_delalloc_scan(str
 			 * the end of this data range, not the end of the folio.
 			 */
 			*punch_start_byte = min_t(loff_t, end_byte,
-					folio_next_index(folio) << PAGE_SHIFT);
+					folio_pos(folio) + folio_size(folio));
 		}
 
 		/* move offset to start of next folio in range */
author maintainer
#265 lore raw

PATCH 260/280 fs/ntfs3: Initialize allocated memory before use

In reply to Greg Kroah-Hartman

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

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

From: Bartlomiej Kubik <[email protected]>

[ Upstream commit a8a3ca23bbd9d849308a7921a049330dc6c91398 ]

KMSAN reports: Multiple uninitialized values detected:

- KMSAN: uninit-value in ntfs_read_hdr (3)
- KMSAN: uninit-value in bcmp (3)

Memory is allocated by __getname(), which is a wrapper for kmem_cache_alloc(). This memory is used before being properly cleared. Change kmem_cache_alloc() to kmem_cache_zalloc() to properly allocate and clear memory before use.

Fixes 82cae269cfa9 ("fs/ntfs3: Add initialization of super block")
Fixes 78ab59fee07f ("fs/ntfs3: Rework file operations")
Reported-by [email protected]
Fixes 82cae269cfa9 ("fs/ntfs3: Add initialization of super block")
Fixes 78ab59fee07f ("fs/ntfs3: Rework file operations")
Reported-by [email protected]
---
 fs/ntfs3/inode.c |    7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
fs/ntfs3/inode.c +3 -4
@@ -1294,7 +1294,7 @@ struct inode *ntfs_create_inode(struct u
 		fa |= FILE_ATTRIBUTE_READONLY;
 
 	/* Allocate PATH_MAX bytes. */
-	new_de = __getname();
+	new_de = kmem_cache_zalloc(names_cachep, GFP_KERNEL);
 	if (!new_de) {
 		err = -ENOMEM;
 		goto out1;
@@ -1698,10 +1698,9 @@ int ntfs_link_inode(struct inode *inode,
 	struct NTFS_DE *de;
 
 	/* Allocate PATH_MAX bytes. */
-	de = __getname();
+	de = kmem_cache_zalloc(names_cachep, GFP_KERNEL);
 	if (!de)
 		return -ENOMEM;
-	memset(de, 0, PATH_MAX);
 
 	/* Mark rw ntfs as dirty. It will be cleared at umount. */
 	ntfs_set_state(sbi, NTFS_DIRTY_DIRTY);
@@ -1737,7 +1736,7 @@ int ntfs_unlink_inode(struct inode *dir,
 		return -EINVAL;
 
 	/* Allocate PATH_MAX bytes. */
-	de = __getname();
+	de = kmem_cache_zalloc(names_cachep, GFP_KERNEL);
 	if (!de)
 		return -ENOMEM;
 
author maintainer
#266 lore raw

PATCH 261/280 blk-cgroup: Reinit blkg_iostat_set after clearing in blkcg_reset_stats()

In reply to Greg Kroah-Hartman

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

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

From: Waiman Long <[email protected]>

[ Upstream commit 3d2af77e31ade05ff7ccc3658c3635ec1bea0979 ]

When blkg_alloc() is called to allocate a blkcg_gq structure with the associated blkg_iostat_set's, there are 2 fields within blkg_iostat_set that requires proper initialization - blkg & sync. The former field was introduced by commit 3b8cc6298724 ("blk-cgroup:
Optimize blkcg_rstat_flush()") while the later one was introduced by commit f73316482977 ("blk-cgroup: reimplement basic IO stats using cgroup rstat").

Unfortunately those fields in the blkg_iostat_set's are not properly re-initialized when they are cleared in v1's blkcg_reset_stats(). This can lead to a kernel panic due to NULL pointer access of the blkg pointer. The missing initialization of sync is less problematic and can be a problem in a debug kernel due to missing lockdep initialization.

Fix these problems by re-initializing them after memory clearing.

Fixes 3b8cc6298724 ("blk-cgroup: Optimize blkcg_rstat_flush()")
Fixes f73316482977 ("blk-cgroup: reimplement basic IO stats using cgroup rstat")

[ Remove this line: bis -> blkg = blkg for blkg was introduced by commit
3b8cc6298724 ("blk-cgroup: Optimize blkcg_rstat_flush()") since v6.2. ]

---
 block/blk-cgroup.c |    4 ++++
 1 file changed, 4 insertions(+)
block/blk-cgroup.c +4 -0
@@ -531,8 +531,12 @@ static int blkcg_reset_stats(struct cgro
 			struct blkg_iostat_set *bis =
 				per_cpu_ptr(blkg->iostat_cpu, cpu);
 			memset(bis, 0, sizeof(*bis));
+
+			/* Re-initialize the cleared blkg_iostat_set */
+			u64_stats_init(&bis->sync);
 		}
 		memset(&blkg->iostat, 0, sizeof(blkg->iostat));
+		u64_stats_init(&blkg->iostat.sync);
 
 		for (i = 0; i < BLKCG_MAX_POLS; i++) {
 			struct blkcg_policy *pol = blkcg_policy[i];
author maintainer
#267 lore raw

PATCH 262/280 Revert "net/mlx5: Block entering switchdev mode with ns inconsistency"

In reply to Greg Kroah-Hartman

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

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

From: Gavin Li <[email protected]>

[ Upstream commit 8deeefb24786ea7950b37bde4516b286c877db00 ]

This reverts commit 662404b24a4c4d839839ed25e3097571f5938b9b. The revert is required due to the suspicion it is not good for anything and cause crash.

Fixes 662404b24a4c ("net/mlx5e: Block entering switchdev mode with ns inconsistency")

[ The context change is due to the commit e25373416678 ("net/mlx5e: Rewrite IPsec vs. TC block interface") in v6.6 which is irrelevant to the logic of this patch. ]

---
 drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c |   19 -------------
 1 file changed, 19 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +0 -19
@@ -3493,18 +3493,6 @@ static int esw_inline_mode_to_devlink(u8
 	return 0;
 }
 
-static bool esw_offloads_devlink_ns_eq_netdev_ns(struct devlink *devlink)
-{
-	struct net *devl_net, *netdev_net;
-	struct mlx5_eswitch *esw;
-
-	esw = mlx5_devlink_eswitch_get(devlink);
-	netdev_net = dev_net(esw->dev->mlx5e_res.uplink_netdev);
-	devl_net = devlink_net(devlink);
-
-	return net_eq(devl_net, netdev_net);
-}
-
 int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
 				  struct netlink_ext_ack *extack)
 {
@@ -3519,13 +3507,6 @@ int mlx5_devlink_eswitch_mode_set(struct
 	if (esw_mode_from_devlink(mode, &mlx5_mode))
 		return -EINVAL;
 
-	if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV &&
-	    !esw_offloads_devlink_ns_eq_netdev_ns(devlink)) {
-		NL_SET_ERR_MSG_MOD(extack,
-				   "Can't change E-Switch mode to switchdev when netdev net namespace has diverged from the devlink's.");
-		return -EPERM;
-	}
-
 	mlx5_lag_disable_change(esw->dev);
 	err = mlx5_esw_try_lock(esw);
 	if (err < 0) {
author maintainer
#268 lore raw

PATCH 263/280 gfs2: Fix NULL pointer dereference in gfs2_log_flush

In reply to Greg Kroah-Hartman

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

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

From: Andreas Gruenbacher <[email protected]>

[ Upstream commit 35264909e9d1973ab9aaa2a1b07cda70f12bb828 ]

In gfs2_jindex_free(), set sdp->sd_jdesc to NULL under the log flush lock to provide exclusion against gfs2_log_flush().

In gfs2_log_flush(), check if sdp->sd_jdesc is non-NULL before dereferencing it. Otherwise, we could run into a NULL pointer dereference when outstanding glock work races with an unmount (glock_work_func -> run_queue -> do_xmote -> inode_go_sync -> gfs2_log_flush).

[ The context change is due to the commit 4d927b03a688 ("gfs2: Rename gfs2_withdrawn to gfs2_withdrawing_or_withdrawn") in v6.8 which is irrelevant to the logic of this patch. ]

---
 fs/gfs2/log.c   |    3 ++-
 fs/gfs2/super.c |    4 ++++
 2 files changed, 6 insertions(+), 1 deletion(-)
fs/gfs2/log.c +2 -1
@@ -1102,7 +1102,8 @@ repeat:
 	lops_before_commit(sdp, tr);
 	if (gfs2_withdrawn(sdp))
 		goto out_withdraw;
-	gfs2_log_submit_bio(&sdp->sd_jdesc->jd_log_bio, REQ_OP_WRITE);
+	if (sdp->sd_jdesc)
+		gfs2_log_submit_bio(&sdp->sd_jdesc->jd_log_bio, REQ_OP_WRITE);
 	if (gfs2_withdrawn(sdp))
 		goto out_withdraw;
 
fs/gfs2/super.c +4 -0
@@ -67,9 +67,13 @@ void gfs2_jindex_free(struct gfs2_sbd *s
 	sdp->sd_journals = 0;
 	spin_unlock(&sdp->sd_jindex_spin);
 
+	down_write(&sdp->sd_log_flush_lock);
 	sdp->sd_jdesc = NULL;
+	up_write(&sdp->sd_log_flush_lock);
+
 	while (!list_empty(&list)) {
 		jd = list_first_entry(&list, struct gfs2_jdesc, jd_list);
+		BUG_ON(jd->jd_log_bio);
 		gfs2_free_journal_extents(jd);
 		list_del(&jd->jd_list);
 		iput(jd->jd_inode);
author maintainer
#269 lore raw

PATCH 264/280 NFSD: fix race between nfsd registration and exports_proc

In reply to Greg Kroah-Hartman

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

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

From: Maninder Singh <[email protected]>

[ Upstream commit f7fb730cac9aafda8b9813b55d04e28a9664d17c ]

As of now nfsd calls create_proc_exports_entry() at start of init_nfsd and cleanup by remove_proc_entry() at last of exit_nfsd.

Which causes kernel OOPs if there is race between below 2 operations:
(i) exportfs -r
(ii) mount -t nfsd none /proc/fs/nfsd

for 5.4 kernel ARM64:

CPU 1:

el1_irq+0xbc/0x180
arch_counter_get_cntvct+0x14/0x18
running_clock+0xc/0x18
preempt_count_add+0x88/0x110
prep_new_page+0xb0/0x220
get_page_from_freelist+0x2d8/0x1778
__alloc_pages_nodemask+0x15c/0xef0
__vmalloc_node_range+0x28c/0x478
__vmalloc_node_flags_caller+0x8c/0xb0
kvmalloc_node+0x88/0xe0
nfsd_init_net+0x6c/0x108 [nfsd]
ops_init+0x44/0x170
register_pernet_operations+0x114/0x270
register_pernet_subsys+0x34/0x50
init_nfsd+0xa8/0x718 [nfsd]
do_one_initcall+0x54/0x2e0

CPU 2 :

Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010

PC is at : exports_net_open+0x50/0x68 [nfsd]

Call trace:
exports_net_open+0x50/0x68 [nfsd]
exports_proc_open+0x2c/0x38 [nfsd]
proc_reg_open+0xb8/0x198
do_dentry_open+0x1c4/0x418
vfs_open+0x38/0x48
path_openat+0x28c/0xf18
do_filp_open+0x70/0xe8
do_sys_open+0x154/0x248

Sometimes it crashes at exports_net_open() and sometimes cache_seq_next_rcu().

and same is happening on latest 6.14 kernel as well:

[    0.000000] Linux version 6.14.0-rc5-next-20250304-dirty
...
[  285.455918] Unable to handle kernel paging request at virtual address 00001f4800001f48
...
[  285.464902] pc : cache_seq_next_rcu+0x78/0xa4
...
[  285.469695] Call trace:
[  285.470083]  cache_seq_next_rcu+0x78/0xa4 (P)
[  285.470488]  seq_read+0xe0/0x11c
[  285.470675]  proc_reg_read+0x9c/0xf0
[  285.470874]  vfs_read+0xc4/0x2fc
[  285.471057]  ksys_read+0x6c/0xf4
[  285.471231]  __arm64_sys_read+0x1c/0x28
[  285.471428]  invoke_syscall+0x44/0x100
[  285.471633]  el0_svc_common.constprop.0+0x40/0xe0
[  285.471870]  do_el0_svc_compat+0x1c/0x34
[  285.472073]  el0_svc_compat+0x2c/0x80
[  285.472265]  el0t_32_sync_handler+0x90/0x140
[  285.472473]  el0t_32_sync+0x19c/0x1a0
[  285.472887] Code: f9400885 93407c23 937d7c27 11000421 (f86378a3)
[  285.473422] ---[ end trace 0000000000000000 ]---

It reproduced simply with below script:
while [ 1 ]
do
/exportfs -r
done &

while [ 1 ]
do
insmod /nfsd.ko
mount -t nfsd none /proc/fs/nfsd
umount /proc/fs/nfsd
rmmod nfsd
done &

So exporting interfaces to user space shall be done at last and cleanup at first place.

With change there is no Kernel OOPs.

[ The context change is due to the commit bd9d6a3efa97 ("NFSD: add rpc_status netlink support") in v6.7 and the proper adoption is done. ]

---
 fs/nfsd/nfsctl.c |   17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)
fs/nfsd/nfsctl.c +8 -9
@@ -1511,12 +1511,9 @@ static int __init init_nfsd(void)
 	if (retval)
 		goto out_free_pnfs;
 	nfsd_lockd_init();	/* lockd->nfsd callbacks */
-	retval = create_proc_exports_entry();
-	if (retval)
-		goto out_free_lockd;
 	retval = register_pernet_subsys(&nfsd_net_ops);
 	if (retval < 0)
-		goto out_free_exports;
+		goto out_free_lockd;
 	retval = register_cld_notifier();
 	if (retval)
 		goto out_free_subsys;
@@ -1525,17 +1522,19 @@ static int __init init_nfsd(void)
 		goto out_free_cld;
 	retval = register_filesystem(&nfsd_fs_type);
 	if (retval)
+		goto out_free_nfsd4;
+	retval = create_proc_exports_entry();
+	if (retval)
 		goto out_free_all;
 	return 0;
 out_free_all:
+	unregister_filesystem(&nfsd_fs_type);
+out_free_nfsd4:
 	nfsd4_destroy_laundry_wq();
 out_free_cld:
 	unregister_cld_notifier();
 out_free_subsys:
 	unregister_pernet_subsys(&nfsd_net_ops);
-out_free_exports:
-	remove_proc_entry("fs/nfs/exports", NULL);
-	remove_proc_entry("fs/nfs", NULL);
 out_free_lockd:
 	nfsd_lockd_shutdown();
 	nfsd_drc_slab_free();
@@ -1548,13 +1547,13 @@ out_free_slabs:
 
 static void __exit exit_nfsd(void)
 {
+	remove_proc_entry("fs/nfs/exports", NULL);
+	remove_proc_entry("fs/nfs", NULL);
 	unregister_filesystem(&nfsd_fs_type);
 	nfsd4_destroy_laundry_wq();
 	unregister_cld_notifier();
 	unregister_pernet_subsys(&nfsd_net_ops);
 	nfsd_drc_slab_free();
-	remove_proc_entry("fs/nfs/exports", NULL);
-	remove_proc_entry("fs/nfs", NULL);
 	nfsd_lockd_shutdown();
 	nfsd4_free_slabs();
 	nfsd4_exit_pnfs();
author maintainer
#270 lore raw

PATCH 265/280 usbnet: Fix using smp_processor_id() in preemptible code warnings

In reply to Greg Kroah-Hartman

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

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

From: Zqiang <[email protected]>

[ Upstream commit 327cd4b68b4398b6c24f10eb2b2533ffbfc10185 ]

Syzbot reported the following warning:

BUG: using smp_processor_id() in preemptible [00000000] code: dhcpcd/2879
caller is usbnet_skb_return+0x74/0x490 drivers/net/usb/usbnet.c:331
CPU: 1 UID: 0 PID: 2879 Comm: dhcpcd Not tainted 6.15.0-rc4-syzkaller-00098-g615dca38c2ea #0 PREEMPT(voluntary)
Call Trace:
 <TASK>
 __dump_stack lib/dump_stack.c:94 [inline]
 dump_stack_lvl+0x16c/0x1f0 lib/dump_stack.c:120
 check_preemption_disabled+0xd0/0xe0 lib/smp_processor_id.c:49
 usbnet_skb_return+0x74/0x490 drivers/net/usb/usbnet.c:331
 usbnet_resume_rx+0x4b/0x170 drivers/net/usb/usbnet.c:708
 usbnet_change_mtu+0x1be/0x220 drivers/net/usb/usbnet.c:417
 __dev_set_mtu net/core/dev.c:9443 [inline]
 netif_set_mtu_ext+0x369/0x5c0 net/core/dev.c:9496
 netif_set_mtu+0xb0/0x160 net/core/dev.c:9520
 dev_set_mtu+0xae/0x170 net/core/dev_api.c:247
 dev_ifsioc+0xa31/0x18d0 net/core/dev_ioctl.c:572
 dev_ioctl+0x223/0x10e0 net/core/dev_ioctl.c:821
 sock_do_ioctl+0x19d/0x280 net/socket.c:1204
 sock_ioctl+0x42f/0x6a0 net/socket.c:1311
 vfs_ioctl fs/ioctl.c:51 [inline]
 __do_sys_ioctl fs/ioctl.c:906 [inline]
 __se_sys_ioctl fs/ioctl.c:892 [inline]
 __x64_sys_ioctl+0x190/0x200 fs/ioctl.c:892
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0xcd/0x260 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

For historical and portability reasons, the netif_rx() is usually run in the softirq or interrupt context, this commit therefore add local_bh_disable/enable() protection in the usbnet_resume_rx().

[ The context change is due to the commit 2c04d279e857 ("net: usb: Convert tasklet API to new bottom half workqueue mechanism") in v6.17 which is irrelevant to the logic of this patch.]

---
 drivers/net/usb/usbnet.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/net/usb/usbnet.c +2 -0
@@ -704,6 +704,7 @@ void usbnet_resume_rx(struct usbnet *dev
 	struct sk_buff *skb;
 	int num = 0;
 
+	local_bh_disable();
 	clear_bit(EVENT_RX_PAUSED, &dev->flags);
 
 	while ((skb = skb_dequeue(&dev->rxq_pause)) != NULL) {
@@ -712,6 +713,7 @@ void usbnet_resume_rx(struct usbnet *dev
 	}
 
 	tasklet_schedule(&dev->bh);
+	local_bh_enable();
 
 	netif_dbg(dev, rx_status, dev->net,
 		  "paused rx queue disabled, %d skbs requeued\n", num);
author maintainer
#271 lore raw

PATCH 266/280 drm/amdgpu: Replace Mutex with Spinlock for RLCG register access to avoid Priority Inversion in SRIOV

In reply to Greg Kroah-Hartman

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

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

From: Srinivasan Shanmugam <[email protected]>

[ Upstream commit dc0297f3198bd60108ccbd167ee5d9fa4af31ed0 ]

RLCG Register Access is a way for virtual functions to safely access GPU registers in a virtualized environment., including TLB flushes and register reads. When multiple threads or VFs try to access the same registers simultaneously, it can lead to race conditions. By using the RLCG interface, the driver can serialize access to the registers. This means that only one thread can access the registers at a time, preventing conflicts and ensuring that operations are performed correctly. Additionally, when a low-priority task holds a mutex that a high-priority task needs, ie., If a thread holding a spinlock tries to acquire a mutex, it can lead to priority inversion. register access in amdgpu_virt_rlcg_reg_rw especially in a fast code path is critical.

The call stack shows that the function amdgpu_virt_rlcg_reg_rw is being called, which attempts to acquire the mutex. This function is invoked from amdgpu_sriov_wreg, which in turn is called from gmc_v11_0_flush_gpu_tlb.

The [ BUG: Invalid wait context ] indicates that a thread is trying to acquire a mutex while it is in a context that does not allow it to sleep (like holding a spinlock).

Fixes the below:

[  253.013423] =============================
[  253.013434] [ BUG: Invalid wait context ]
[  253.013446] 6.12.0-amdstaging-drm-next-lol-050225 #14 Tainted: G     U     OE
[  253.013464] -----------------------------
[  253.013475] kworker/0:1/10 is trying to lock:
[  253.013487] ffff9f30542e3cf8 (&adev->virt.rlcg_reg_lock){+.+.}-{3:3}, at: amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu]
[  253.013815] other info that might help us debug this:
[  253.013827] context-{4:4}
[  253.013835] 3 locks held by kworker/0:1/10:
[  253.013847]  #0: ffff9f3040050f58 ((wq_completion)events){+.+.}-{0:0}, at: process_one_work+0x3f5/0x680
[  253.013877]  #1: ffffb789c008be40 ((work_completion)(&wfc.work)){+.+.}-{0:0}, at: process_one_work+0x1d6/0x680
[  253.013905]  #2: ffff9f3054281838 (&adev->gmc.invalidate_lock){+.+.}-{2:2}, at: gmc_v11_0_flush_gpu_tlb+0x198/0x4f0 [amdgpu]
[  253.014154] stack backtrace:
[  253.014164] CPU: 0 UID: 0 PID: 10 Comm: kworker/0:1 Tainted: G     U     OE      6.12.0-amdstaging-drm-next-lol-050225 #14
[  253.014189] Tainted: [U]=USER, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
[  253.014203] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v4.1 11/18/2024
[  253.014224] Workqueue: events work_for_cpu_fn
[  253.014241] Call Trace:
[  253.014250]  <TASK>
[  253.014260]  dump_stack_lvl+0x9b/0xf0
[  253.014275]  dump_stack+0x10/0x20
[  253.014287]  __lock_acquire+0xa47/0x2810
[  253.014303]  ? srso_alias_return_thunk+0x5/0xfbef5
[  253.014321]  lock_acquire+0xd1/0x300
[  253.014333]  ? amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu]
[  253.014562]  ? __lock_acquire+0xa6b/0x2810
[  253.014578]  __mutex_lock+0x85/0xe20
[  253.014591]  ? amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu]
[  253.014782]  ? sched_clock_noinstr+0x9/0x10
[  253.014795]  ? srso_alias_return_thunk+0x5/0xfbef5
[  253.014808]  ? local_clock_noinstr+0xe/0xc0
[  253.014822]  ? amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu]
[  253.015012]  ? srso_alias_return_thunk+0x5/0xfbef5
[  253.015029]  mutex_lock_nested+0x1b/0x30
[  253.015044]  ? mutex_lock_nested+0x1b/0x30
[  253.015057]  amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu]
[  253.015249]  amdgpu_sriov_wreg+0xc5/0xd0 [amdgpu]
[  253.015435]  gmc_v11_0_flush_gpu_tlb+0x44b/0x4f0 [amdgpu]
[  253.015667]  gfx_v11_0_hw_init+0x499/0x29c0 [amdgpu]
[  253.015901]  ? __pfx_smu_v13_0_update_pcie_parameters+0x10/0x10 [amdgpu]
[  253.016159]  ? srso_alias_return_thunk+0x5/0xfbef5
[  253.016173]  ? smu_hw_init+0x18d/0x300 [amdgpu]
[  253.016403]  amdgpu_device_init+0x29ad/0x36a0 [amdgpu]
[  253.016614]  amdgpu_driver_load_kms+0x1a/0xc0 [amdgpu]
[  253.017057]  amdgpu_pci_probe+0x1c2/0x660 [amdgpu]
[  253.017493]  local_pci_probe+0x4b/0xb0
[  253.017746]  work_for_cpu_fn+0x1a/0x30
[  253.017995]  process_one_work+0x21e/0x680
[  253.018248]  worker_thread+0x190/0x330
[  253.018500]  ? __pfx_worker_thread+0x10/0x10
[  253.018746]  kthread+0xe7/0x120
[  253.018988]  ? __pfx_kthread+0x10/0x10
[  253.019231]  ret_from_fork+0x3c/0x60
[  253.019468]  ? __pfx_kthread+0x10/0x10
[  253.019701]  ret_from_fork_asm+0x1a/0x30
[  253.019939]  </TASK>

v2: s/spin_trylock/spin_lock_irqsave to be safe (Christian).

Fixes e864180ee49b ("drm/amdgpu: Add lock around VF RLCG interface")
Cc lin cao <[email protected]>
Cc Jingwen Chen <[email protected]>
Cc Victor Skvortsov <[email protected]>
Cc Zhigang Luo <[email protected]>
Cc Christian König <[email protected]>
Cc Alex Deucher <[email protected]>
[ Minor conflict resolved. ]
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |    2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c   |    5 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h   |    3 ++-
 3 files changed, 6 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +1 -1
@@ -3652,7 +3652,6 @@ int amdgpu_device_init(struct amdgpu_dev
 	mutex_init(&adev->grbm_idx_mutex);
 	mutex_init(&adev->mn_lock);
 	mutex_init(&adev->virt.vf_errors.lock);
-	mutex_init(&adev->virt.rlcg_reg_lock);
 	hash_init(adev->mn_hash);
 	mutex_init(&adev->psp.mutex);
 	mutex_init(&adev->notifier_lock);
@@ -3674,6 +3673,7 @@ int amdgpu_device_init(struct amdgpu_dev
 	spin_lock_init(&adev->se_cac_idx_lock);
 	spin_lock_init(&adev->audio_endpt_idx_lock);
 	spin_lock_init(&adev->mm_stats.lock);
+	spin_lock_init(&adev->virt.rlcg_reg_lock);
 
 	INIT_LIST_HEAD(&adev->shadow_list);
 	mutex_init(&adev->shadow_list_lock);
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +3 -2
@@ -965,6 +965,7 @@ static u32 amdgpu_virt_rlcg_reg_rw(struc
 	void *scratch_reg2;
 	void *scratch_reg3;
 	void *spare_int;
+	unsigned long flags;
 
 	if (!adev->gfx.rlc.rlcg_reg_access_supported) {
 		dev_err(adev->dev,
@@ -978,7 +979,7 @@ static u32 amdgpu_virt_rlcg_reg_rw(struc
 	scratch_reg2 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg2;
 	scratch_reg3 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg3;
 
-	mutex_lock(&adev->virt.rlcg_reg_lock);
+	spin_lock_irqsave(&adev->virt.rlcg_reg_lock, flags);
 
 	if (reg_access_ctrl->spare_int)
 		spare_int = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->spare_int;
@@ -1034,7 +1035,7 @@ static u32 amdgpu_virt_rlcg_reg_rw(struc
 
 	ret = readl(scratch_reg0);
 
-	mutex_unlock(&adev->virt.rlcg_reg_lock);
+	spin_unlock_irqrestore(&adev->virt.rlcg_reg_lock, flags);
 
 	return ret;
 }
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +2 -1
@@ -264,7 +264,8 @@ struct amdgpu_virt {
 	/* the ucode id to signal the autoload */
 	uint32_t autoload_ucode_id;
 
-	struct mutex rlcg_reg_lock;
+	/* Spinlock to protect access to the RLCG register interface */
+	spinlock_t rlcg_reg_lock;
 };
 
 struct amdgpu_video_codec_info;
author maintainer
#272 lore raw

PATCH 267/280 net: stmmac: make sure that ptp_rate is not 0 before configuring EST

In reply to Greg Kroah-Hartman

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

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

From: Alexis Lothoré <[email protected]>

[ Upstream commit cbefe2ffa7784525ec5d008ba87c7add19ec631a ]

If the ptp_rate recorded earlier in the driver happens to be 0, this bogus value will propagate up to EST configuration, where it will trigger a division by 0.

Prevent this division by 0 by adding the corresponding check and error code.

Fixes 8572aec3d0dc ("net: stmmac: Add basic EST support for XGMAC")

[ The context change is due to the commit c3f3b97238f6 ("net: stmmac: Refactor EST implementation") and the proper adoption is done. ]

---
 drivers/net/ethernet/stmicro/stmmac/dwmac5.c        |    5 +++++
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c |    5 +++++
 2 files changed, 10 insertions(+)
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +5 -0
@@ -597,6 +597,11 @@ int dwmac5_est_configure(void __iomem *i
 	int i, ret = 0x0;
 	u32 ctrl;
 
+	if (!ptp_rate) {
+		pr_warn("Dwmac5: Invalid PTP rate");
+		return -EINVAL;
+	}
+
 	ret |= dwmac5_est_write(ioaddr, BTR_LOW, cfg->btr[0], false);
 	ret |= dwmac5_est_write(ioaddr, BTR_HIGH, cfg->btr[1], false);
 	ret |= dwmac5_est_write(ioaddr, TER, cfg->ter, false);
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c +5 -0
@@ -1497,6 +1497,11 @@ static int dwxgmac3_est_configure(void _
 	int i, ret = 0x0;
 	u32 ctrl;
 
+	if (!ptp_rate) {
+		pr_warn("Dwxgmac2: Invalid PTP rate");
+		return -EINVAL;
+	}
+
 	ret |= dwxgmac3_est_write(ioaddr, XGMAC_BTR_LOW, cfg->btr[0], false);
 	ret |= dwxgmac3_est_write(ioaddr, XGMAC_BTR_HIGH, cfg->btr[1], false);
 	ret |= dwxgmac3_est_write(ioaddr, XGMAC_TER, cfg->ter, false);
author maintainer
#273 lore raw

PATCH 268/280 sctp: linearize cloned gso packets in sctp_rcv

In reply to Greg Kroah-Hartman

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

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

From: Xin Long <[email protected]>

[ Upstream commit fd60d8a086191fe33c2d719732d2482052fa6805 ]

A cloned head skb still shares these frag skbs in fraglist with the original head skb. It's not safe to access these frag skbs.

syzbot reported two use-of-uninitialized-memory bugs caused by this:

  BUG: KMSAN: uninit-value in sctp_inq_pop+0x15b7/0x1920 net/sctp/inqueue.c:211
   sctp_inq_pop+0x15b7/0x1920 net/sctp/inqueue.c:211
   sctp_assoc_bh_rcv+0x1a7/0xc50 net/sctp/associola.c:998
   sctp_inq_push+0x2ef/0x380 net/sctp/inqueue.c:88
   sctp_backlog_rcv+0x397/0xdb0 net/sctp/input.c:331
   sk_backlog_rcv+0x13b/0x420 include/net/sock.h:1122
   __release_sock+0x1da/0x330 net/core/sock.c:3106
   release_sock+0x6b/0x250 net/core/sock.c:3660
   sctp_wait_for_connect+0x487/0x820 net/sctp/socket.c:9360
   sctp_sendmsg_to_asoc+0x1ec1/0x1f00 net/sctp/socket.c:1885
   sctp_sendmsg+0x32b9/0x4a80 net/sctp/socket.c:2031
   inet_sendmsg+0x25a/0x280 net/ipv4/af_inet.c:851
   sock_sendmsg_nosec net/socket.c:718 [inline]

and

  BUG: KMSAN: uninit-value in sctp_assoc_bh_rcv+0x34e/0xbc0 net/sctp/associola.c:987
   sctp_assoc_bh_rcv+0x34e/0xbc0 net/sctp/associola.c:987
   sctp_inq_push+0x2a3/0x350 net/sctp/inqueue.c:88
   sctp_backlog_rcv+0x3c7/0xda0 net/sctp/input.c:331
   sk_backlog_rcv+0x142/0x420 include/net/sock.h:1148
   __release_sock+0x1d3/0x330 net/core/sock.c:3213
   release_sock+0x6b/0x270 net/core/sock.c:3767
   sctp_wait_for_connect+0x458/0x820 net/sctp/socket.c:9367
   sctp_sendmsg_to_asoc+0x223a/0x2260 net/sctp/socket.c:1886
   sctp_sendmsg+0x3910/0x49f0 net/sctp/socket.c:2032
   inet_sendmsg+0x269/0x2a0 net/ipv4/af_inet.c:851
   sock_sendmsg_nosec net/socket.c:712 [inline]

This patch fixes it by linearizing cloned gso packets in sctp_rcv().

---
This patch is lost/missing, as it has already been added
into stable branches less than and greater than 6.1. Previous patch in
https://lore.kernel.org/stable/[email protected]/ is still not added. So I resent it again.

---

---
 net/sctp/input.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/sctp/input.c +1 -1
@@ -114,7 +114,7 @@ int sctp_rcv(struct sk_buff *skb)
 	 * it's better to just linearize it otherwise crc computing
 	 * takes longer.
 	 */
-	if ((!is_gso && skb_linearize(skb)) ||
+	if (((!is_gso || skb_cloned(skb)) && skb_linearize(skb)) ||
 	    !pskb_may_pull(skb, sizeof(struct sctphdr)))
 		goto discard_it;
 
author maintainer
#274 lore raw

PATCH 269/280 ksmbd: fix use-after-free in ksmbd_session_rpc_open

In reply to Greg Kroah-Hartman

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

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

From: Namjae Jeon <[email protected]>

[ Upstream commit a1f46c99d9ea411f9bf30025b912d881d36fc709 ]

A UAF issue can occur due to a race condition between ksmbd_session_rpc_open() and __session_rpc_close(). Add rpc_lock to the session to protect it.

[ KSMBD_DEFAULT_GFP is introduced by commit 0066f623bce8 ("ksmbd: use __GFP_RETRY_MAYFAIL")
after linux-6.13. Here we still use GFP_KERNEL. ]

---
 fs/smb/server/mgmt/user_session.c |   20 ++++++++++++++------
 fs/smb/server/mgmt/user_session.h |    1 +
 2 files changed, 15 insertions(+), 6 deletions(-)
fs/smb/server/mgmt/user_session.c +14 -6
@@ -59,10 +59,12 @@ static void ksmbd_session_rpc_clear_list
 	struct ksmbd_session_rpc *entry;
 	long index;
 
+	down_write(&sess->rpc_lock);
 	xa_for_each(&sess->rpc_handle_list, index, entry) {
 		xa_erase(&sess->rpc_handle_list, index);
 		__session_rpc_close(sess, entry);
 	}
+	up_write(&sess->rpc_lock);
 
 	xa_destroy(&sess->rpc_handle_list);
 }
@@ -92,7 +94,7 @@ int ksmbd_session_rpc_open(struct ksmbd_
 {
 	struct ksmbd_session_rpc *entry, *old;
 	struct ksmbd_rpc_command *resp;
-	int method;
+	int method, id;
 
 	method = __rpc_method(rpc_name);
 	if (!method)
@@ -102,26 +104,29 @@ int ksmbd_session_rpc_open(struct ksmbd_
 	if (!entry)
 		return -ENOMEM;
 
+	down_read(&sess->rpc_lock);
 	entry->method = method;
-	entry->id = ksmbd_ipc_id_alloc();
-	if (entry->id < 0)
+	entry->id = id = ksmbd_ipc_id_alloc();
+	if (id < 0)
 		goto free_entry;
-	old = xa_store(&sess->rpc_handle_list, entry->id, entry, GFP_KERNEL);
+	old = xa_store(&sess->rpc_handle_list, id, entry, GFP_KERNEL);
 	if (xa_is_err(old))
 		goto free_id;
 
-	resp = ksmbd_rpc_open(sess, entry->id);
+	resp = ksmbd_rpc_open(sess, id);
 	if (!resp)
 		goto erase_xa;
 
+	up_read(&sess->rpc_lock);
 	kvfree(resp);
-	return entry->id;
+	return id;
 erase_xa:
 	xa_erase(&sess->rpc_handle_list, entry->id);
 free_id:
 	ksmbd_rpc_id_free(entry->id);
 free_entry:
 	kfree(entry);
+	up_read(&sess->rpc_lock);
 	return -EINVAL;
 }
 
@@ -129,9 +134,11 @@ void ksmbd_session_rpc_close(struct ksmb
 {
 	struct ksmbd_session_rpc *entry;
 
+	down_write(&sess->rpc_lock);
 	entry = xa_erase(&sess->rpc_handle_list, id);
 	if (entry)
 		__session_rpc_close(sess, entry);
+	up_write(&sess->rpc_lock);
 }
 
 int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id)
@@ -404,6 +411,7 @@ static struct ksmbd_session *__session_c
 	sess->sequence_number = 1;
 	rwlock_init(&sess->tree_conns_lock);
 	atomic_set(&sess->refcnt, 2);
+	init_rwsem(&sess->rpc_lock);
 
 	ret = __init_smb2_session(sess);
 	if (ret)
fs/smb/server/mgmt/user_session.h +1 -0
@@ -63,6 +63,7 @@ struct ksmbd_session {
 	rwlock_t			tree_conns_lock;
 
 	atomic_t			refcnt;
+	struct rw_semaphore		rpc_lock;
 };
 
 static inline int test_session_flag(struct ksmbd_session *sess, int bit)
author maintainer
#275 lore raw

PATCH 270/280 ksmbd: Fix race condition in RPC handle list access

In reply to Greg Kroah-Hartman

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

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

From: Yunseong Kim <[email protected]>

[ Upstream commit 305853cce379407090a73b38c5de5ba748893aee ]

The 'sess->rpc_handle_list' XArray manages RPC handles within a ksmbd session. Access to this list is intended to be protected by 'sess->rpc_lock' (an rw_semaphore). However, the locking implementation was flawed, leading to potential race conditions.

In ksmbd_session_rpc_open(), the code incorrectly acquired only a read lock before calling xa_store() and xa_erase(). Since these operations modify the XArray structure, a write lock is required to ensure exclusive access and prevent data corruption from concurrent modifications.

Furthermore, ksmbd_session_rpc_method() accessed the list using xa_load() without holding any lock at all. This could lead to reading inconsistent data or a potential use-after-free if an entry is concurrently removed and the pointer is dereferenced.

Fix these issues by:
1. Using down_write() and up_write() in ksmbd_session_rpc_open() to ensure exclusive access during XArray modification, and ensuring the lock is correctly released on error paths.
2. Adding down_read() and up_read() in ksmbd_session_rpc_method() to safely protect the lookup.

Fixes a1f46c99d9ea ("ksmbd: fix use-after-free in ksmbd_session_rpc_open")
Fixes b685757c7b08 ("ksmbd: Implements sess->rpc_handle_list as xarray")
[ Minor conflict resolved. ]
---
 fs/smb/server/mgmt/user_session.c |   26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)
fs/smb/server/mgmt/user_session.c +17 -9
@@ -104,29 +104,32 @@ int ksmbd_session_rpc_open(struct ksmbd_
 	if (!entry)
 		return -ENOMEM;
 
-	down_read(&sess->rpc_lock);
 	entry->method = method;
 	entry->id = id = ksmbd_ipc_id_alloc();
 	if (id < 0)
 		goto free_entry;
+
+	down_write(&sess->rpc_lock);
 	old = xa_store(&sess->rpc_handle_list, id, entry, GFP_KERNEL);
-	if (xa_is_err(old))
+	if (xa_is_err(old)) {
+		up_write(&sess->rpc_lock);
 		goto free_id;
+	}
 
 	resp = ksmbd_rpc_open(sess, id);
-	if (!resp)
-		goto erase_xa;
+	if (!resp) {
+		xa_erase(&sess->rpc_handle_list, entry->id);
+		up_write(&sess->rpc_lock);
+		goto free_id;
+	}
 
-	up_read(&sess->rpc_lock);
+	up_write(&sess->rpc_lock);
 	kvfree(resp);
 	return id;
-erase_xa:
-	xa_erase(&sess->rpc_handle_list, entry->id);
 free_id:
 	ksmbd_rpc_id_free(entry->id);
 free_entry:
 	kfree(entry);
-	up_read(&sess->rpc_lock);
 	return -EINVAL;
 }
 
@@ -144,9 +147,14 @@ void ksmbd_session_rpc_close(struct ksmb
 int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id)
 {
 	struct ksmbd_session_rpc *entry;
+	int method;
 
+	down_read(&sess->rpc_lock);
 	entry = xa_load(&sess->rpc_handle_list, id);
-	return entry ? entry->method : 0;
+	method = entry ? entry->method : 0;
+	up_read(&sess->rpc_lock);
+
+	return method;
 }
 
 void ksmbd_session_destroy(struct ksmbd_session *sess)
author maintainer
#276 lore raw

PATCH 271/280 vhost-scsi: Fix handling of multiple calls to vhost_scsi_set_endpoint

In reply to Greg Kroah-Hartman

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

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

From: Mike Christie <[email protected]>

[ Upstream commit 5dd639a1646ef5fe8f4bf270fad47c5c3755b9b6 ]

If vhost_scsi_set_endpoint is called multiple times without a vhost_scsi_clear_endpoint between them, we can hit multiple bugs found by Haoran Zhang:

1. Use-after-free when no tpgs are found:

This fixes a use after free that occurs when vhost_scsi_set_endpoint is called more than once and calls after the first call do not find any tpgs to add to the vs_tpg. When vhost_scsi_set_endpoint first finds tpgs to add to the vs_tpg array match=true, so we will do:

vhost_vq_set_backend(vq, vs_tpg);
...

kfree(vs->vs_tpg);
vs->vs_tpg = vs_tpg;

If vhost_scsi_set_endpoint is called again and no tpgs are found match=false so we skip the vhost_vq_set_backend call leaving the pointer to the vs_tpg we then free via:

kfree(vs->vs_tpg);
vs->vs_tpg = vs_tpg;

If a scsi request is then sent we do:

vhost_scsi_handle_vq -> vhost_scsi_get_req -> vhost_vq_get_backend

which sees the vs_tpg we just did a kfree on.

2. Tpg dir removal hang:

This patch fixes an issue where we cannot remove a LIO/target layer tpg (and structs above it like the target) dir due to the refcount dropping to -1.

The problem is that if vhost_scsi_set_endpoint detects a tpg is already in the vs->vs_tpg array or if the tpg has been removed so target_depend_item fails, the undepend goto handler will do target_undepend_item on all tpgs in the vs_tpg array dropping their refcount to 0. At this time vs_tpg contains both the tpgs we have added in the current vhost_scsi_set_endpoint call as well as tpgs we added in previous calls which are also in vs->vs_tpg.

Later, when vhost_scsi_clear_endpoint runs it will do target_undepend_item on all the tpgs in the vs->vs_tpg which will drop their refcount to -1. Userspace will then not be able to remove the tpg and will hang when it tries to do rmdir on the tpg dir.

3. Tpg leak:

This fixes a bug where we can leak tpgs and cause them to be un-removable because the target name is overwritten when vhost_scsi_set_endpoint is called multiple times but with different target names.

The bug occurs if a user has called VHOST_SCSI_SET_ENDPOINT and setup a vhost-scsi device to target/tpg mapping, then calls VHOST_SCSI_SET_ENDPOINT again with a new target name that has tpgs we haven't seen before (target1 has tpg1 but target2 has tpg2). When this happens we don't teardown the old target tpg mapping and just overwrite the target name and the vs->vs_tpg array. Later when we do vhost_scsi_clear_endpoint, we are passed in either target1 or target2's name and we will only match that target's tpgs when we loop over the vs->vs_tpg. We will then return from the function without doing target_undepend_item on the tpgs.

Because of all these bugs, it looks like being able to call vhost_scsi_set_endpoint multiple times was never supported. The major user, QEMU, already has checks to prevent this use case. So to fix the issues, this patch prevents vhost_scsi_set_endpoint from being called if it's already successfully added tpgs. To add, remove or change the tpg config or target name, you must do a vhost_scsi_clear_endpoint first.

Fixes 25b98b64e284 ("vhost scsi: alloc cmds per vq instead of session")
Fixes 4f7f46d32c98 ("tcm_vhost: Use vq->private_data to indicate if the endpoint is setup")

Message-Id: <[email protected]>

---
 drivers/vhost/scsi.c |   24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)
drivers/vhost/scsi.c +13 -11
@@ -1572,14 +1572,19 @@ vhost_scsi_set_endpoint(struct vhost_scs
 		}
 	}
 
+	if (vs->vs_tpg) {
+		pr_err("vhost-scsi endpoint already set for %s.\n",
+		       vs->vs_vhost_wwpn);
+		ret = -EEXIST;
+		goto out;
+	}
+
 	len = sizeof(vs_tpg[0]) * VHOST_SCSI_MAX_TARGET;
 	vs_tpg = kzalloc(len, GFP_KERNEL);
 	if (!vs_tpg) {
 		ret = -ENOMEM;
 		goto out;
 	}
-	if (vs->vs_tpg)
-		memcpy(vs_tpg, vs->vs_tpg, len);
 
 	list_for_each_entry(tpg, &vhost_scsi_list, tv_tpg_list) {
 		mutex_lock(&tpg->tv_tpg_mutex);
@@ -1594,11 +1599,6 @@ vhost_scsi_set_endpoint(struct vhost_scs
 		tv_tport = tpg->tport;
 
 		if (!strcmp(tv_tport->tport_name, t->vhost_wwpn)) {
-			if (vs->vs_tpg && vs->vs_tpg[tpg->tport_tpgt]) {
-				mutex_unlock(&tpg->tv_tpg_mutex);
-				ret = -EEXIST;
-				goto undepend;
-			}
 			/*
 			 * In order to ensure individual vhost-scsi configfs
 			 * groups cannot be removed while in use by vhost ioctl,
@@ -1643,15 +1643,15 @@ vhost_scsi_set_endpoint(struct vhost_scs
 		}
 		ret = 0;
 	} else {
-		ret = -EEXIST;
+		ret = -ENODEV;
+		goto free_tpg;
 	}
 
 	/*
-	 * Act as synchronize_rcu to make sure access to
-	 * old vs->vs_tpg is finished.
+	 * Act as synchronize_rcu to make sure requests after this point
+	 * see a fully setup device.
 	 */
 	vhost_scsi_flush(vs);
-	kfree(vs->vs_tpg);
 	vs->vs_tpg = vs_tpg;
 	goto out;
 
@@ -1668,6 +1668,7 @@ undepend:
 			target_undepend_item(&tpg->se_tpg.tpg_group.cg_item);
 		}
 	}
+free_tpg:
 	kfree(vs_tpg);
 out:
 	mutex_unlock(&vs->dev.mutex);
@@ -1757,6 +1758,7 @@ vhost_scsi_clear_endpoint(struct vhost_s
 	vhost_scsi_flush(vs);
 	kfree(vs->vs_tpg);
 	vs->vs_tpg = NULL;
+	memset(vs->vs_vhost_wwpn, 0, sizeof(vs->vs_vhost_wwpn));
 	WARN_ON(vs->vs_events_nr);
 	mutex_unlock(&vs->dev.mutex);
 	mutex_unlock(&vhost_scsi_mutex);
author maintainer
#277 lore raw

PATCH 272/280 drm/radeon: delete radeon_fence_process in is_signaled, no deadlock

In reply to Greg Kroah-Hartman

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

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

From: Robert McClinton <[email protected]>

[ Upstream commit 9eb00b5f5697bd56baa3222c7a1426fa15bacfb5 ]

Delete the attempt to progress the queue when checking if fence is signaled. This avoids deadlock.

dma-fence_ops::signaled can be called with the fence lock in unknown state. For radeon, the fence lock is also the wait queue lock. This can cause a self deadlock when signaled() tries to make forward progress on the wait queue. But advancing the queue is unneeded because incorrectly returning false from signaled() is perfectly acceptable.

---
 drivers/gpu/drm/radeon/radeon_fence.c |    8 --------
 1 file changed, 8 deletions(-)
drivers/gpu/drm/radeon/radeon_fence.c +0 -8
@@ -362,14 +362,6 @@ static bool radeon_fence_is_signaled(str
 		return true;
 	}
 
-	if (down_read_trylock(&rdev->exclusive_lock)) {
-		radeon_fence_process(rdev, ring);
-		up_read(&rdev->exclusive_lock);
-
-		if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq) {
-			return true;
-		}
-	}
 	return false;
 }
 
author maintainer
#278 lore raw

PATCH 273/280 btrfs: prevent use-after-free on page private data in btrfs_subpage_clear_uptodate()

In reply to Greg Kroah-Hartman

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

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

From: JP Kobryn <[email protected]>

This is a stable-only patch. The issue was inadvertently fixed in 6.17 [0] as part of a refactoring, but this patch serves as a minimal targeted fix for prior kernels.

Users of find_lock_page() need to guard against the situation where releasepage() has been invoked during reclaim but the page was ultimately not removed from the page cache. This patch covers one location that was overlooked.

After acquiring the page, use set_page_extent_mapped() to ensure the page private state is valid. This is especially important in the subpage case, where the private field is an allocated struct containing bitmap and lock data.

Without this protection, the race below is possible:

[mm] page cache reclaim path [fs] relocation in subpage mode
shrink_page_list()
trylock_page() /* lock acquired */
try_to_release_page()
mapping->a_ops->releasepage()
btrfs_releasepage()
__btrfs_releasepage()
clear_page_extent_mapped()
btrfs_detach_subpage()
subpage = detach_page_private(page) btrfs_free_subpage(subpage)
kfree(subpage) /* point A */
prealloc_file_extent_cluster()
find_lock_page()
page_cache_get_speculative() lock_page() /* wait for lock */
if (...)

    ...

else if (!mapping || !__remove_mapping(..))
/*
* __remove_mapping() returns zero when
* page_ref_freeze(page, refcount) fails /* point B */ */
goto keep_locked /* page remains in cache */
keep_locked:
unlock_page(page) /* lock released */

                                        /* lock acquired */
                                        btrfs_subpage_clear_uptodate()
                                          /* use-after-free */
                                          subpage = page->private

[0] 4e346baee95f ("btrfs: reloc: unconditionally invalidate the page cache for each cluster")

Fixes 9d9ea1e68a05 ("btrfs: subpage: fix relocation potentially overwriting last page data")
Cc [email protected] # 5.15 - 6.9
---
 fs/btrfs/relocation.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)
fs/btrfs/relocation.c +13 -0
@@ -2897,6 +2897,19 @@ static noinline_for_stack int prealloc_f
 		 * will re-read the whole page anyway.
 		 */
 		if (page) {
+			/*
+			 * releasepage() could have cleared the page private data while
+			 * we were not holding the lock. Reset the mapping if needed so
+			 * subpage operations can access a valid private page state.
+			 */
+			ret = set_page_extent_mapped(page);
+			if (ret) {
+				unlock_page(page);
+				put_page(page);
+
+				return ret;
+			}
+
 			btrfs_subpage_clear_uptodate(fs_info, page, i_size,
 					round_up(i_size, PAGE_SIZE) - i_size);
 			unlock_page(page);
author maintainer
#279 lore raw

PATCH 274/280 net/sched: act_ife: convert comma to semicolon

In reply to Greg Kroah-Hartman

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

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

From: Chen Ni <[email protected]>

commit 205305c028ad986d0649b8b100bab6032dcd1bb5 upstream.

Replace comma between expressions with semicolons.

Using a ',' in place of a ';' can have unintended side effects. Although that is not the case here, it is seems best to use ';' unless ',' is intended.

Found by inspection.
No functional change intended.
Compile tested only.

---
 net/sched/act_ife.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
net/sched/act_ife.c +3 -3
@@ -648,9 +648,9 @@ static int tcf_ife_dump(struct sk_buff *
 
 	memset(&opt, 0, sizeof(opt));
 
-	opt.index = ife->tcf_index,
-	opt.refcnt = refcount_read(&ife->tcf_refcnt) - ref,
-	opt.bindcnt = atomic_read(&ife->tcf_bindcnt) - bind,
+	opt.index = ife->tcf_index;
+	opt.refcnt = refcount_read(&ife->tcf_refcnt) - ref;
+	opt.bindcnt = atomic_read(&ife->tcf_bindcnt) - bind;
 
 	spin_lock_bh(&ife->tcf_lock);
 	opt.action = ife->tcf_action;
author maintainer
#280 lore raw

PATCH 275/280 mptcp: avoid dup SUB_CLOSED events after disconnect

In reply to Greg Kroah-Hartman

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

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

From: "Matthieu Baerts (NGI0)" <[email protected]>

[ Upstream commit 280d654324e33f8e6e3641f76764694c7b64c5db ]

In case of subflow disconnect(), which can also happen with the first subflow in case of errors like timeout or reset, mptcp_subflow_ctx_reset will reset most fields from the mptcp_subflow_context structure, including close_event_done. Then, when another subflow is closed, yet another SUB_CLOSED event for the disconnected initial subflow is sent. Because of the previous reset, there are no source address and destination port.

A solution is then to also check the subflow's local id: it shouldn't be negative anyway.

Another solution would be not to reset subflow->close_event_done at disconnect time, but when reused. But then, probably the whole reset could be done when being reused. Let's not change this logic, similar to TCP with tcp_disconnect().

---
 net/mptcp/protocol.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/mptcp/protocol.c +2 -2
@@ -2569,8 +2569,8 @@ out:
 void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
 		     struct mptcp_subflow_context *subflow)
 {
-	/* The first subflow can already be closed and still in the list */
-	if (subflow->close_event_done)
+	/* The first subflow can already be closed or disconnected */
+	if (subflow->close_event_done || READ_ONCE(subflow->local_id) < 0)
 		return;
 
 	subflow->close_event_done = true;
author maintainer
#281 lore raw

PATCH 276/280 mm/kfence: randomize the freelist on initialization

In reply to Greg Kroah-Hartman

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

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

From: Pimyn Girgis <[email protected]>

[ Upstream commit 870ff19251bf3910dda7a7245da826924045fedd ]

Randomize the KFENCE freelist during pool initialization to make allocation patterns less predictable. This is achieved by shuffling the order in which metadata objects are added to the freelist using get_random_u32_below().

Additionally, ensure the error path correctly calculates the address range to be reset if initialization fails, as the address increment logic has been moved to a separate loop.

Fixes 0ce20dd84089 ("mm: add Kernel Electric-Fence infrastructure")
Cc Dmitry Vyukov <[email protected]>
Cc Marco Elver <[email protected]>
Cc Ernesto Martnez Garca <[email protected]>
Cc Greg KH <[email protected]>
Cc Kees Cook <[email protected]>
[ replaced kfence_metadata_init with kfence_metadata ]
---
 mm/kfence/core.c |   23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)
mm/kfence/core.c +19 -4
@@ -542,7 +542,7 @@ static unsigned long kfence_init_pool(vo
 {
 	unsigned long addr = (unsigned long)__kfence_pool;
 	struct page *pages;
-	int i;
+	int i, rand;
 
 	if (!arch_kfence_init_pool())
 		return addr;
@@ -590,19 +590,34 @@ static unsigned long kfence_init_pool(vo
 		INIT_LIST_HEAD(&meta->list);
 		raw_spin_lock_init(&meta->lock);
 		meta->state = KFENCE_OBJECT_UNUSED;
-		meta->addr = addr; /* Initialize for validation in metadata_to_pageaddr(). */
-		list_add_tail(&meta->list, &kfence_freelist);
+		/* Use addr to randomize the freelist. */
+		meta->addr = i;
 
 		/* Protect the right redzone. */
-		if (unlikely(!kfence_protect(addr + PAGE_SIZE)))
+		if (unlikely(!kfence_protect(addr + 2 * i * PAGE_SIZE + PAGE_SIZE)))
 			goto reset_slab;
+	}
+
+	for (i = CONFIG_KFENCE_NUM_OBJECTS; i > 0; i--) {
+		rand = get_random_u32_below(i);
+		swap(kfence_metadata[i - 1].addr, kfence_metadata[rand].addr);
+	}
 
+	for (i = 0; i < CONFIG_KFENCE_NUM_OBJECTS; i++) {
+		struct kfence_metadata *meta_1 = &kfence_metadata[i];
+		struct kfence_metadata *meta_2 = &kfence_metadata[meta_1->addr];
+
+		list_add_tail(&meta_2->list, &kfence_freelist);
+	}
+	for (i = 0; i < CONFIG_KFENCE_NUM_OBJECTS; i++) {
+		kfence_metadata[i].addr = addr;
 		addr += 2 * PAGE_SIZE;
 	}
 
 	return 0;
 
 reset_slab:
+	addr += 2 * i * PAGE_SIZE;
 	for (i = 0; i < KFENCE_POOL_SIZE / PAGE_SIZE; i++) {
 		struct slab *slab = page_slab(nth_page(pages, i));
 
author maintainer
#282 lore raw

PATCH 277/280 writeback: fix 100% CPU usage when dirtytime_expire_interval is 0

In reply to Greg Kroah-Hartman

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

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

From: Laveesh Bansal <[email protected]>

[ Upstream commit 543467d6fe97e27e22a26e367fda972dbefebbff ]

When vm.dirtytime_expire_seconds is set to 0, wakeup_dirtytime_writeback() schedules delayed work with a delay of 0, causing immediate execution. The function then reschedules itself with 0 delay again, creating an infinite busy loop that causes 100% kworker CPU usage.

Fix by:
- Only scheduling delayed work in wakeup_dirtytime_writeback() when dirtytime_expire_interval is non-zero
- Cancelling the delayed work in dirtytime_interval_handler() when the interval is set to 0
- Adding a guard in start_dirtytime_writeback() for defensive coding

Tested by booting kernel in QEMU with virtme-ng:
- Before fix: kworker CPU spikes to ~73%
- After fix: CPU remains at normal levels
- Setting interval back to non-zero correctly resumes writeback

Fixes a2f4870697a5 ("fs: make sure the timestamps for lazytime inodes eventually get written")
[ adapted system_percpu_wq to system_wq for the workqueue used in dirtytime_interval_handler() ]
---
 fs/fs-writeback.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
fs/fs-writeback.c +10 -4
@@ -2360,12 +2360,14 @@ static void wakeup_dirtytime_writeback(s
 				wb_wakeup(wb);
 	}
 	rcu_read_unlock();
-	schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ);
+	if (dirtytime_expire_interval)
+		schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ);
 }
 
 static int __init start_dirtytime_writeback(void)
 {
-	schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ);
+	if (dirtytime_expire_interval)
+		schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ);
 	return 0;
 }
 __initcall(start_dirtytime_writeback);
@@ -2376,8 +2378,12 @@ int dirtytime_interval_handler(struct ct
 	int ret;
 
 	ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
-	if (ret == 0 && write)
-		mod_delayed_work(system_wq, &dirtytime_work, 0);
+	if (ret == 0 && write) {
+		if (dirtytime_expire_interval)
+			mod_delayed_work(system_wq, &dirtytime_work, 0);
+		else
+			cancel_delayed_work_sync(&dirtytime_work);
+	}
 	return ret;
 }
 
author maintainer
#283 lore raw

PATCH 278/280 drm/imx/tve: fix probe device leak

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

[ Upstream commit e535c23513c63f02f67e3e09e0787907029efeaf ]

Make sure to drop the reference taken to the DDC device during probe on probe failure (e.g. probe deferral) and on driver unbind.

Fixes fcbc51e54d2a ("staging: drm/imx: Add support for Television Encoder (TVEv2)")
Cc Philipp Zabel <[email protected]>
---
 drivers/gpu/drm/imx/imx-tve.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)
drivers/gpu/drm/imx/imx-tve.c +13 -0
@@ -522,6 +522,13 @@ static const struct component_ops imx_tv
 	.bind	= imx_tve_bind,
 };
 
+static void imx_tve_put_device(void *_dev)
+{
+	struct device *dev = _dev;
+
+	put_device(dev);
+}
+
 static int imx_tve_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -543,6 +550,12 @@ static int imx_tve_probe(struct platform
 	if (ddc_node) {
 		tve->ddc = of_find_i2c_adapter_by_node(ddc_node);
 		of_node_put(ddc_node);
+		if (tve->ddc) {
+			ret = devm_add_action_or_reset(dev, imx_tve_put_device,
+						       &tve->ddc->dev);
+			if (ret)
+				return ret;
+		}
 	}
 
 	tve->mode = of_get_tve_mode(np);
author maintainer
#284 lore raw

PATCH 279/280 pinctrl: lpass-lpi: implement .get_direction() for the GPIO driver

In reply to Greg Kroah-Hartman

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

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

From: Bartosz Golaszewski <[email protected]>

[ Upstream commit 4f0d22ec60cee420125f4055af76caa0f373a3fe ]

GPIO controller driver should typically implement the .get_direction() callback as GPIOLIB internals may try to use it to determine the state of a pin. Add it for the LPASS LPI driver.

Fixes 6e261d1090d6 ("pinctrl: qcom: Add sm8250 lpass lpi pinctrl driver")
[ PIN_CONFIG_LEVEL => PIN_CONFIG_OUTPUT ]
---
 drivers/pinctrl/qcom/pinctrl-lpass-lpi.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)
drivers/pinctrl/qcom/pinctrl-lpass-lpi.c +17 -0
@@ -248,6 +248,22 @@ static const struct pinconf_ops lpi_gpio
 	.pin_config_group_set		= lpi_config_set,
 };
 
+static int lpi_gpio_get_direction(struct gpio_chip *chip, unsigned int pin)
+{
+	unsigned long config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, 0);
+	struct lpi_pinctrl *state = gpiochip_get_data(chip);
+	unsigned long arg;
+	int ret;
+
+	ret = lpi_config_get(state->ctrl, pin, &config);
+	if (ret)
+		return ret;
+
+	arg = pinconf_to_config_argument(config);
+
+	return arg ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
+}
+
 static int lpi_gpio_direction_input(struct gpio_chip *chip, unsigned int pin)
 {
 	struct lpi_pinctrl *state = gpiochip_get_data(chip);
@@ -346,6 +362,7 @@ static void lpi_gpio_dbg_show(struct seq
 #endif
 
 static const struct gpio_chip lpi_gpio_template = {
+	.get_direction		= lpi_gpio_get_direction,
 	.direction_input	= lpi_gpio_direction_input,
 	.direction_output	= lpi_gpio_direction_output,
 	.get			= lpi_gpio_get,
author maintainer
#285 lore raw

PATCH 280/280 ksmbd: fix recursive locking in RPC handle list access

In reply to Greg Kroah-Hartman

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

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

From: Marios Makassikis <[email protected]>

[ Upstream commit 88f170814fea74911ceab798a43cbd7c5599bed4 ]

Since commit 305853cce3794 ("ksmbd: Fix race condition in RPC handle list access"), ksmbd_session_rpc_method() attempts to lock sess->rpc_lock.

This causes hung connections / tasks when a client attempts to open a named pipe. Using Samba's rpcclient tool:

 $ rpcclient //192.168.1.254 -U user%password
 $ rpcclient $> srvinfo
 <connection hung here>

Kernel side:
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. task:kworker/0:0 state:D stack:0 pid:5021 tgid:5021 ppid:2 flags:0x00200000

  Workqueue: ksmbd-io handle_ksmbd_work
  Call trace:
  __schedule from schedule+0x3c/0x58
  schedule from schedule_preempt_disabled+0xc/0x10
  schedule_preempt_disabled from rwsem_down_read_slowpath+0x1b0/0x1d8
  rwsem_down_read_slowpath from down_read+0x28/0x30
  down_read from ksmbd_session_rpc_method+0x18/0x3c
  ksmbd_session_rpc_method from ksmbd_rpc_open+0x34/0x68
  ksmbd_rpc_open from ksmbd_session_rpc_open+0x194/0x228
  ksmbd_session_rpc_open from create_smb2_pipe+0x8c/0x2c8
  create_smb2_pipe from smb2_open+0x10c/0x27ac
  smb2_open from handle_ksmbd_work+0x238/0x3dc
  handle_ksmbd_work from process_scheduled_works+0x160/0x25c
  process_scheduled_works from worker_thread+0x16c/0x1e8
  worker_thread from kthread+0xa8/0xb8
  kthread from ret_from_fork+0x14/0x38
  Exception stack(0x8529ffb0 to 0x8529fff8)

The task deadlocks because the lock is already held:
ksmbd_session_rpc_open

    down_write(&sess->rpc_lock)
    ksmbd_rpc_open
      ksmbd_session_rpc_method
        down_read(&sess->rpc_lock)   <-- deadlock

Adjust ksmbd_session_rpc_method() callers to take the lock when necessary.

Fixes 305853cce3794 ("ksmbd: Fix race condition in RPC handle list access")
---
 fs/smb/server/mgmt/user_session.c |    7 ++-----
 fs/smb/server/smb2pdu.c           |    9 ++++++++-
 fs/smb/server/transport_ipc.c     |   12 ++++++++++++
 3 files changed, 22 insertions(+), 6 deletions(-)
fs/smb/server/mgmt/user_session.c +2 -5
@@ -147,14 +147,11 @@ void ksmbd_session_rpc_close(struct ksmb
 int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id)
 {
 	struct ksmbd_session_rpc *entry;
-	int method;
 
-	down_read(&sess->rpc_lock);
+	lockdep_assert_held(&sess->rpc_lock);
 	entry = xa_load(&sess->rpc_handle_list, id);
-	method = entry ? entry->method : 0;
-	up_read(&sess->rpc_lock);
 
-	return method;
+	return entry ? entry->method : 0;
 }
 
 void ksmbd_session_destroy(struct ksmbd_session *sess)
fs/smb/server/smb2pdu.c +8 -1
@@ -4308,8 +4308,15 @@ static int smb2_get_info_file_pipe(struc
 	 * pipe without opening it, checking error condition here
 	 */
 	id = req->VolatileFileId;
-	if (!ksmbd_session_rpc_method(sess, id))
+
+	lockdep_assert_not_held(&sess->rpc_lock);
+
+	down_read(&sess->rpc_lock);
+	if (!ksmbd_session_rpc_method(sess, id)) {
+		up_read(&sess->rpc_lock);
 		return -ENOENT;
+	}
+	up_read(&sess->rpc_lock);
 
 	ksmbd_debug(SMB, "FileInfoClass %u, FileId 0x%llx\n",
 		    req->FileInfoClass, req->VolatileFileId);
fs/smb/server/transport_ipc.c +12 -0
@@ -775,6 +775,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_writ
 	if (!msg)
 		return NULL;
 
+	lockdep_assert_not_held(&sess->rpc_lock);
+
+	down_read(&sess->rpc_lock);
 	msg->type = KSMBD_EVENT_RPC_REQUEST;
 	req = (struct ksmbd_rpc_command *)msg->payload;
 	req->handle = handle;
@@ -783,6 +786,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_writ
 	req->flags |= KSMBD_RPC_WRITE_METHOD;
 	req->payload_sz = payload_sz;
 	memcpy(req->payload, payload, payload_sz);
+	up_read(&sess->rpc_lock);
 
 	resp = ipc_msg_send_request(msg, req->handle);
 	ipc_msg_free(msg);
@@ -799,6 +803,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_read
 	if (!msg)
 		return NULL;
 
+	lockdep_assert_not_held(&sess->rpc_lock);
+
+	down_read(&sess->rpc_lock);
 	msg->type = KSMBD_EVENT_RPC_REQUEST;
 	req = (struct ksmbd_rpc_command *)msg->payload;
 	req->handle = handle;
@@ -806,6 +813,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_read
 	req->flags |= rpc_context_flags(sess);
 	req->flags |= KSMBD_RPC_READ_METHOD;
 	req->payload_sz = 0;
+	up_read(&sess->rpc_lock);
 
 	resp = ipc_msg_send_request(msg, req->handle);
 	ipc_msg_free(msg);
@@ -826,6 +834,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_ioct
 	if (!msg)
 		return NULL;
 
+	lockdep_assert_not_held(&sess->rpc_lock);
+
+	down_read(&sess->rpc_lock);
 	msg->type = KSMBD_EVENT_RPC_REQUEST;
 	req = (struct ksmbd_rpc_command *)msg->payload;
 	req->handle = handle;
@@ -834,6 +845,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_ioct
 	req->flags |= KSMBD_RPC_IOCTL_METHOD;
 	req->payload_sz = payload_sz;
 	memcpy(req->payload, payload, payload_sz);
+	up_read(&sess->rpc_lock);
 
 	resp = ipc_msg_send_request(msg, req->handle);
 	ipc_msg_free(msg);
Tested-by on the v1 series
#287 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.1.162 release. There are 280 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 Fri, 06 Feb 2026 14:38:23 +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.1.162-rc1.gz

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

thanks,

greg k-h

On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:

Signature · 1 line
Florian
#288 lore raw
In reply to Greg Kroah-Hartman

Hi Greg,

Am 04.02.2026 um 15:36 schrieb Greg Kroah-Hartman:

Quoted 7 lines

This is the start of the stable review cycle for the 6.1.162 release. There are 280 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 Fri, 06 Feb 2026 14:38:23 +0000. Anything received after that time might be too late.

It seems that this time, I cannot even build this RC. When I run "make menuconfig" I get a big serious of warning and error messages; something seems to be really messed up here...

root@linus:/usr/src/linux-stable-rc# vim .config
root@linus:/usr/src/linux-stable-rc# make menuconfig
scripts/kconfig/Makefile:215: Warnung: Das Musterrezept hat das Peer-Ziel „scripts/kconfig/mconf-bin“ nicht aktualisiert.
  HOSTCC  scripts/kconfig/mconf.o
  HOSTCC  scripts/kconfig/lxdialog/checklist.o
  HOSTCC  scripts/kconfig/lxdialog/inputbox.o
  HOSTCC  scripts/kconfig/lxdialog/menubox.o
  HOSTCC  scripts/kconfig/lxdialog/textbox.o
  HOSTCC  scripts/kconfig/lxdialog/util.o
  HOSTCC  scripts/kconfig/lxdialog/yesno.o
  HOSTLD  scripts/kconfig/mconf
/usr/bin/ld: scripts/kconfig/lxdialog/yesno.o: warning: relocation against `acs_map' in read-only section `.text'
/usr/bin/ld: scripts/kconfig/mconf.o: in function `show_help':
mconf.c:(.text+0xa1b): undefined reference to `stdscr'
/usr/bin/ld: mconf.c:(.text+0xa20): undefined reference to `getmaxx'
/usr/bin/ld: scripts/kconfig/lxdialog/checklist.o: in function `print_arrows':
checklist.c:(.text+0x2c): undefined reference to `wmove'
/usr/bin/ld: checklist.c:(.text+0x43): undefined reference to `wattrset'
/usr/bin/ld: checklist.c:(.text+0x49): undefined reference to `acs_map'
/usr/bin/ld: checklist.c:(.text+0x51): undefined reference to `waddch'
/usr/bin/ld: checklist.c:(.text+0x65): undefined reference to `waddnstr'
/usr/bin/ld: checklist.c:(.text+0x75): undefined reference to `wmove'
/usr/bin/ld: checklist.c:(.text+0x97): undefined reference to `wattrset'
/usr/bin/ld: checklist.c:(.text+0x9d): undefined reference to `acs_map'
/usr/bin/ld: checklist.c:(.text+0xa5): undefined reference to `waddch'
/usr/bin/ld: checklist.c:(.text+0xab): undefined reference to `acs_map'
/usr/bin/ld: checklist.c:(.text+0xb3): undefined reference to `waddch'
/usr/bin/ld: checklist.c:(.text+0xb9): undefined reference to `acs_map'
/usr/bin/ld: checklist.c:(.text+0xc1): undefined reference to `waddch'
/usr/bin/ld: checklist.c:(.text+0xc7): undefined reference to `acs_map'
/usr/bin/ld: checklist.c:(.text+0xf2): undefined reference to `wattrset'
/usr/bin/ld: checklist.c:(.text+0xf8): undefined reference to `acs_map'
/usr/bin/ld: checklist.c:(.text+0x100): undefined reference to `waddch'
/usr/bin/ld: checklist.c:(.text+0x13a): undefined reference to `wattrset'
/usr/bin/ld: checklist.c:(.text+0x140): undefined reference to `acs_map'
/usr/bin/ld: checklist.c:(.text+0x148): undefined reference to `waddch'
/usr/bin/ld: checklist.c:(.text+0x14e): undefined reference to `acs_map'
/usr/bin/ld: checklist.c:(.text+0x156): undefined reference to `waddch'
/usr/bin/ld: checklist.c:(.text+0x15c): undefined reference to `acs_map'
/usr/bin/ld: checklist.c:(.text+0x164): undefined reference to `waddch'
/usr/bin/ld: checklist.c:(.text+0x16a): undefined reference to `acs_map'
/usr/bin/ld: checklist.c:(.text+0x172): undefined reference to `waddch'
/usr/bin/ld: scripts/kconfig/lxdialog/checklist.o: in function `print_item':
checklist.c:(.text+0x1de): undefined reference to `wattrset'
/usr/bin/ld: checklist.c:(.text+0x1eb): undefined reference to `wmove'
/usr/bin/ld: checklist.c:(.text+0x20c): undefined reference to `waddch'
/usr/bin/ld: checklist.c:(.text+0x225): undefined reference to `wmove'
/usr/bin/ld: checklist.c:(.text+0x23c): undefined reference to `wattrset'
/usr/bin/ld: checklist.c:(.text+0x25c): undefined reference to `wattrset'
/usr/bin/ld: checklist.c:(.text+0x26d): undefined reference to `wmove'
/usr/bin/ld: checklist.c:(.text+0x284): undefined reference to `wattrset'
/usr/bin/ld: checklist.c:(.text+0x296): undefined reference to `waddnstr'
/usr/bin/ld: checklist.c:(.text+0x2aa): undefined reference to `wmove'
/usr/bin/ld: checklist.c:(.text+0x2b2): undefined reference to `wrefresh'
/usr/bin/ld: checklist.c:(.text+0x2da): undefined reference to `wattrset'
/usr/bin/ld: checklist.c:(.text+0x2f6): undefined reference to `wattrset'
/usr/bin/ld: checklist.c:(.text+0x307): undefined reference to `wmove'
/usr/bin/ld: checklist.c:(.text+0x31a): undefined reference to `wattrset'
/usr/bin/ld: checklist.c:(.text+0x32c): undefined reference to `waddnstr'
/usr/bin/ld: checklist.c:(.text+0x349): undefined reference to `waddch'
/usr/bin/ld: checklist.c:(.text+0x359): undefined reference to `waddch'
/usr/bin/ld: checklist.c:(.text+0x388): undefined reference to `wprintw'
/usr/bin/ld: checklist.c:(.text+0x3b8): undefined reference to `wprintw'
/usr/bin/ld: checklist.c:(.text+0x3d3): undefined reference to `wprintw'
/usr/bin/ld: checklist.c:(.text+0x3ee): undefined reference to `wprintw'
/usr/bin/ld: scripts/kconfig/lxdialog/checklist.o: in function `print_buttons':
checklist.c:(.text+0x46a): undefined reference to `wmove'
/usr/bin/ld: scripts/kconfig/lxdialog/checklist.o: in function `dialog_checklist':
checklist.c:(.text+0x565): undefined reference to `stdscr'
/usr/bin/ld: checklist.c:(.text+0x56a): undefined reference to `getmaxy'
/usr/bin/ld: checklist.c:(.text+0x57d): undefined reference to `stdscr'
/usr/bin/ld: checklist.c:(.text+0x582): undefined reference to `getmaxx'
/usr/bin/ld: checklist.c:(.text+0x5a7): undefined reference to `stdscr'
/usr/bin/ld: checklist.c:(.text+0x5ac): undefined reference to `getmaxx'
/usr/bin/ld: checklist.c:(.text+0x5b8): undefined reference to `stdscr'
/usr/bin/ld: checklist.c:(.text+0x5d0): undefined reference to `getmaxy'
/usr/bin/ld: checklist.c:(.text+0x5e1): undefined reference to `stdscr'
/usr/bin/ld: checklist.c:(.text+0x60a): undefined reference to `newwin'
/usr/bin/ld: checklist.c:(.text+0x61a): undefined reference to `keypad'
/usr/bin/ld: checklist.c:(.text+0x64b): undefined reference to `wattrset'
/usr/bin/ld: checklist.c:(.text+0x658): undefined reference to `wmove'
/usr/bin/ld: checklist.c:(.text+0x666): undefined reference to `acs_map'
/usr/bin/ld: checklist.c:(.text+0x66e): undefined reference to `waddch'
/usr/bin/ld: checklist.c:(.text+0x682): undefined reference to `acs_map'
/usr/bin/ld: checklist.c:(.text+0x68e): undefined reference to `waddch'
/usr/bin/ld: checklist.c:(.text+0x6a1): undefined reference to `wattrset'
/usr/bin/ld: checklist.c:(.text+0x6a7): undefined reference to `acs_map'
/usr/bin/ld: checklist.c:(.text+0x6af): undefined reference to `waddch'
/usr/bin/ld: checklist.c:(.text+0x6d2): undefined reference to `wattrset'
/usr/bin/ld: checklist.c:(.text+0x717): undefined reference to `subwin'
/usr/bin/ld: checklist.c:(.text+0x729): undefined reference to `keypad'
/usr/bin/ld: checklist.c:(.text+0x8b5): undefined reference to `wnoutrefresh'
/usr/bin/ld: checklist.c:(.text+0x8bf): undefined reference to `wnoutrefresh'
/usr/bin/ld: checklist.c:(.text+0x8c4): undefined reference to `doupdate'
/usr/bin/ld: checklist.c:(.text+0x8e4): undefined reference to `wgetch'
/usr/bin/ld: checklist.c:(.text+0x9f7): undefined reference to `wrefresh'
/usr/bin/ld: checklist.c:(.text+0xa40): undefined reference to `delwin'
/usr/bin/ld: checklist.c:(.text+0xa48): undefined reference to `delwin'
/usr/bin/ld: checklist.c:(.text+0xaa8): undefined reference to `scrollok'
/usr/bin/ld: checklist.c:(.text+0xab5): undefined reference to `wscrl'
/usr/bin/ld: checklist.c:(.text+0xabf): undefined reference to `scrollok'
/usr/bin/ld: checklist.c:(.text+0xb12): undefined reference to `wnoutrefresh'
/usr/bin/ld: checklist.c:(.text+0xb1a): undefined reference to `wrefresh'
/usr/bin/ld: checklist.c:(.text+0xb79): undefined reference to `wnoutrefresh'
/usr/bin/ld: checklist.c:(.text+0xb81): undefined reference to `wrefresh'
/usr/bin/ld: checklist.c:(.text+0xbe2): undefined reference to `scrollok'
/usr/bin/ld: checklist.c:(.text+0xbef): undefined reference to `wscrl'
/usr/bin/ld: checklist.c:(.text+0xbf9): undefined reference to `scrollok'
/usr/bin/ld: checklist.c:(.text+0xc56): undefined reference to `wnoutrefresh'
/usr/bin/ld: checklist.c:(.text+0xc5e): undefined reference to `wrefresh'
/usr/bin/ld: checklist.c:(.text+0xc68): undefined reference to `wgetch'
/usr/bin/ld: checklist.c:(.text+0xcdc): undefined reference to `doupdate'
/usr/bin/ld: checklist.c:(.text+0xcf1): undefined reference to `doupdate'
/usr/bin/ld: checklist.c:(.text+0xd16): undefined reference to `delwin'
/usr/bin/ld: checklist.c:(.text+0xd1e): undefined reference to `delwin'
/usr/bin/ld: checklist.c:(.text+0xdb8): undefined reference to `delwin'
/usr/bin/ld: checklist.c:(.text+0xdc0): undefined reference to `delwin'
/usr/bin/ld: checklist.c:(.text+0xe08): undefined reference to `doupdate'
/usr/bin/ld: scripts/kconfig/lxdialog/checklist.o: in function `print_arrows':
checklist.c:(.text+0xdd): undefined reference to `waddch'
/usr/bin/ld: checklist.c:(.text+0x122): undefined reference to `waddnstr'
/usr/bin/ld: scripts/kconfig/lxdialog/checklist.o: in function `print_buttons':
checklist.c:(.text+0x47c): undefined reference to `wrefresh'
/usr/bin/ld: scripts/kconfig/lxdialog/inputbox.o: in function `print_buttons':
inputbox.c:(.text+0x63): undefined reference to `wmove'
/usr/bin/ld: scripts/kconfig/lxdialog/inputbox.o: in function `dialog_inputbox':
inputbox.c:(.text+0xd6): undefined reference to `stdscr'
/usr/bin/ld: inputbox.c:(.text+0xdb): undefined reference to `getmaxy'
/usr/bin/ld: inputbox.c:(.text+0xee): undefined reference to `stdscr'
/usr/bin/ld: inputbox.c:(.text+0xf3): undefined reference to `getmaxx'
/usr/bin/ld: inputbox.c:(.text+0x106): undefined reference to `stdscr'
/usr/bin/ld: inputbox.c:(.text+0x10b): undefined reference to `getmaxx'
/usr/bin/ld: inputbox.c:(.text+0x112): undefined reference to `stdscr'
/usr/bin/ld: inputbox.c:(.text+0x124): undefined reference to `getmaxy'
/usr/bin/ld: inputbox.c:(.text+0x137): undefined reference to `stdscr'
/usr/bin/ld: inputbox.c:(.text+0x15a): undefined reference to `newwin'
/usr/bin/ld: inputbox.c:(.text+0x16a): undefined reference to `keypad'
/usr/bin/ld: inputbox.c:(.text+0x19c): undefined reference to `wattrset'
/usr/bin/ld: inputbox.c:(.text+0x1ab): undefined reference to `wmove'
/usr/bin/ld: inputbox.c:(.text+0x1ba): undefined reference to `acs_map'
/usr/bin/ld: inputbox.c:(.text+0x1c2): undefined reference to `waddch'
/usr/bin/ld: inputbox.c:(.text+0x1d2): undefined reference to `acs_map'
/usr/bin/ld: inputbox.c:(.text+0x1dd): undefined reference to `waddch'
/usr/bin/ld: inputbox.c:(.text+0x1f3): undefined reference to `wattrset'
/usr/bin/ld: inputbox.c:(.text+0x1f9): undefined reference to `acs_map'
/usr/bin/ld: inputbox.c:(.text+0x201): undefined reference to `waddch'
/usr/bin/ld: inputbox.c:(.text+0x21f): undefined reference to `wattrset'
/usr/bin/ld: inputbox.c:(.text+0x246): undefined reference to `getcury'
/usr/bin/ld: inputbox.c:(.text+0x250): undefined reference to `getcurx'
/usr/bin/ld: inputbox.c:(.text+0x2a6): undefined reference to `wmove'
/usr/bin/ld: inputbox.c:(.text+0x2b4): undefined reference to `wattrset'
/usr/bin/ld: inputbox.c:(.text+0x2e8): undefined reference to `waddnstr'
/usr/bin/ld: inputbox.c:(.text+0x307): undefined reference to `wmove'
/usr/bin/ld: inputbox.c:(.text+0x30f): undefined reference to `wrefresh'
/usr/bin/ld: inputbox.c:(.text+0x31c): undefined reference to `wgetch'
/usr/bin/ld: inputbox.c:(.text+0x382): undefined reference to `wgetch'
/usr/bin/ld: inputbox.c:(.text+0x3ea): undefined reference to `wgetch'
/usr/bin/ld: inputbox.c:(.text+0x41f): undefined reference to `flash'
/usr/bin/ld: inputbox.c:(.text+0x434): undefined reference to `wgetch'
/usr/bin/ld: inputbox.c:(.text+0x487): undefined reference to `wgetch'
/usr/bin/ld: inputbox.c:(.text+0x4da): undefined reference to `delwin'
/usr/bin/ld: inputbox.c:(.text+0x55c): undefined reference to `waddch'
/usr/bin/ld: inputbox.c:(.text+0x5ab): undefined reference to `wgetch'
/usr/bin/ld: inputbox.c:(.text+0x5d5): undefined reference to `delwin'
/usr/bin/ld: inputbox.c:(.text+0x5f4): undefined reference to `delwin'
/usr/bin/ld: inputbox.c:(.text+0x635): undefined reference to `delwin'
/usr/bin/ld: inputbox.c:(.text+0x6c2): undefined reference to `delwin'
/usr/bin/ld: inputbox.c:(.text+0x75a): undefined reference to `wgetch'
/usr/bin/ld: inputbox.c:(.text+0x79f): undefined reference to `wmove'
/usr/bin/ld: inputbox.c:(.text+0x7a7): undefined reference to `wrefresh'
/usr/bin/ld: inputbox.c:(.text+0x7af): undefined reference to `wgetch'
/usr/bin/ld: inputbox.c:(.text+0x7de): undefined reference to `wgetch'
/usr/bin/ld: inputbox.c:(.text+0x7fc): undefined reference to `wgetch'
/usr/bin/ld: inputbox.c:(.text+0x85e): undefined reference to `wmove'
/usr/bin/ld: inputbox.c:(.text+0x879): undefined reference to `wmove'
/usr/bin/ld: inputbox.c:(.text+0x890): undefined reference to `wattrset'
/usr/bin/ld: inputbox.c:(.text+0x8dd): undefined reference to `wmove'
/usr/bin/ld: inputbox.c:(.text+0x918): undefined reference to `waddch'
/usr/bin/ld: inputbox.c:(.text+0x933): undefined reference to `waddch'
/usr/bin/ld: inputbox.c:(.text+0x946): undefined reference to `wmove'
/usr/bin/ld: inputbox.c:(.text+0x94e): undefined reference to `wrefresh'
/usr/bin/ld: inputbox.c:(.text+0x956): undefined reference to `wgetch'
/usr/bin/ld: inputbox.c:(.text+0x9b7): undefined reference to `wmove'
/usr/bin/ld: inputbox.c:(.text+0x9ed): undefined reference to `waddch'
/usr/bin/ld: inputbox.c:(.text+0xa07): undefined reference to `waddch'
/usr/bin/ld: inputbox.c:(.text+0xa18): undefined reference to `wmove'
/usr/bin/ld: inputbox.c:(.text+0xa33): undefined reference to `wattrset'
/usr/bin/ld: inputbox.c:(.text+0xa8b): undefined reference to `wmove'
/usr/bin/ld: inputbox.c:(.text+0xac5): undefined reference to `waddch'
/usr/bin/ld: inputbox.c:(.text+0xae6): undefined reference to `waddch'
/usr/bin/ld: inputbox.c:(.text+0xaf9): undefined reference to `wmove'
/usr/bin/ld: inputbox.c:(.text+0xb01): undefined reference to `wrefresh'
/usr/bin/ld: inputbox.c:(.text+0xb59): undefined reference to `wmove'
/usr/bin/ld: inputbox.c:(.text+0xb93): undefined reference to `waddch'
/usr/bin/ld: inputbox.c:(.text+0xbad): undefined reference to `waddch'
/usr/bin/ld: inputbox.c:(.text+0xbc0): undefined reference to `wmove'
/usr/bin/ld: scripts/kconfig/lxdialog/inputbox.o: in function `print_buttons':
inputbox.c:(.text+0x75): undefined reference to `wrefresh'
/usr/bin/ld: scripts/kconfig/lxdialog/menubox.o: in function `do_print_item':
menubox.c:(.text+0x6d): undefined reference to `wattrset'
/usr/bin/ld: menubox.c:(.text+0x7a): undefined reference to `wmove'
/usr/bin/ld: menubox.c:(.text+0x82): undefined reference to `wclrtoeol'
/usr/bin/ld: menubox.c:(.text+0x9a): undefined reference to `wattrset'
/usr/bin/ld: menubox.c:(.text+0xab): undefined reference to `wmove'
/usr/bin/ld: menubox.c:(.text+0xc0): undefined reference to `waddnstr'
/usr/bin/ld: menubox.c:(.text+0xd8): undefined reference to `wattrset'
/usr/bin/ld: menubox.c:(.text+0xeb): undefined reference to `wmove'
/usr/bin/ld: menubox.c:(.text+0x108): undefined reference to `wmove'
/usr/bin/ld: menubox.c:(.text+0x14a): undefined reference to `wattrset'
/usr/bin/ld: menubox.c:(.text+0x15d): undefined reference to `wmove'
/usr/bin/ld: menubox.c:(.text+0x16f): undefined reference to `waddch'
/usr/bin/ld: menubox.c:(.text+0x181): undefined reference to `waddch'
/usr/bin/ld: scripts/kconfig/lxdialog/menubox.o: in function `print_buttons':
menubox.c:(.text+0x253): undefined reference to `wmove'
/usr/bin/ld: scripts/kconfig/lxdialog/menubox.o: in function `print_arrows.constprop.0':
menubox.c:(.text+0x28d): undefined reference to `getcury'
/usr/bin/ld: menubox.c:(.text+0x299): undefined reference to `getcurx'
/usr/bin/ld: menubox.c:(.text+0x2ac): undefined reference to `wmove'
/usr/bin/ld: menubox.c:(.text+0x2c2): undefined reference to `wattrset'
/usr/bin/ld: menubox.c:(.text+0x2c8): undefined reference to `acs_map'
/usr/bin/ld: menubox.c:(.text+0x2d0): undefined reference to `waddch'
/usr/bin/ld: menubox.c:(.text+0x2e4): undefined reference to `waddnstr'
/usr/bin/ld: menubox.c:(.text+0x2f4): undefined reference to `wmove'
/usr/bin/ld: menubox.c:(.text+0x2fc): undefined reference to `wrefresh'
/usr/bin/ld: menubox.c:(.text+0x317): undefined reference to `wattrset'
/usr/bin/ld: menubox.c:(.text+0x31d): undefined reference to `acs_map'
/usr/bin/ld: menubox.c:(.text+0x325): undefined reference to `waddch'
/usr/bin/ld: menubox.c:(.text+0x32b): undefined reference to `acs_map'
/usr/bin/ld: menubox.c:(.text+0x333): undefined reference to `waddch'
/usr/bin/ld: menubox.c:(.text+0x339): undefined reference to `acs_map'
/usr/bin/ld: menubox.c:(.text+0x341): undefined reference to `waddch'
/usr/bin/ld: menubox.c:(.text+0x347): undefined reference to `acs_map'
/usr/bin/ld: menubox.c:(.text+0x34f): undefined reference to `waddch'
/usr/bin/ld: menubox.c:(.text+0x35e): undefined reference to `wmove'
/usr/bin/ld: menubox.c:(.text+0x38a): undefined reference to `wattrset'
/usr/bin/ld: menubox.c:(.text+0x390): undefined reference to `acs_map'
/usr/bin/ld: menubox.c:(.text+0x398): undefined reference to `waddch'
/usr/bin/ld: menubox.c:(.text+0x3ac): undefined reference to `waddnstr'
/usr/bin/ld: menubox.c:(.text+0x3c2): undefined reference to `wattrset'
/usr/bin/ld: menubox.c:(.text+0x3c8): undefined reference to `acs_map'
/usr/bin/ld: menubox.c:(.text+0x3d0): undefined reference to `waddch'
/usr/bin/ld: menubox.c:(.text+0x3d6): undefined reference to `acs_map'
/usr/bin/ld: menubox.c:(.text+0x3de): undefined reference to `waddch'
/usr/bin/ld: menubox.c:(.text+0x3e4): undefined reference to `acs_map'
/usr/bin/ld: menubox.c:(.text+0x3ec): undefined reference to `waddch'
/usr/bin/ld: menubox.c:(.text+0x3f2): undefined reference to `acs_map'
/usr/bin/ld: menubox.c:(.text+0x3fa): undefined reference to `waddch'
/usr/bin/ld: scripts/kconfig/lxdialog/menubox.o: in function `dialog_menu':
menubox.c:(.text+0x446): undefined reference to `stdscr'
/usr/bin/ld: menubox.c:(.text+0x44b): undefined reference to `getmaxy'
/usr/bin/ld: menubox.c:(.text+0x452): undefined reference to `stdscr'
/usr/bin/ld: menubox.c:(.text+0x459): undefined reference to `getmaxx'
/usr/bin/ld: menubox.c:(.text+0x49f): undefined reference to `stdscr'
/usr/bin/ld: menubox.c:(.text+0x4a4): undefined reference to `getmaxx'
/usr/bin/ld: menubox.c:(.text+0x4b0): undefined reference to `stdscr'
/usr/bin/ld: menubox.c:(.text+0x4ca): undefined reference to `getmaxy'
/usr/bin/ld: menubox.c:(.text+0x4d6): undefined reference to `stdscr'
/usr/bin/ld: menubox.c:(.text+0x50b): undefined reference to `newwin'
/usr/bin/ld: menubox.c:(.text+0x51b): undefined reference to `keypad'
/usr/bin/ld: menubox.c:(.text+0x54d): undefined reference to `wattrset'
/usr/bin/ld: menubox.c:(.text+0x55a): undefined reference to `wmove'
/usr/bin/ld: menubox.c:(.text+0x568): undefined reference to `acs_map'
/usr/bin/ld: menubox.c:(.text+0x570): undefined reference to `waddch'
/usr/bin/ld: menubox.c:(.text+0x582): undefined reference to `acs_map'
/usr/bin/ld: menubox.c:(.text+0x58e): undefined reference to `waddch'
/usr/bin/ld: menubox.c:(.text+0x5a1): undefined reference to `wattrset'
/usr/bin/ld: menubox.c:(.text+0x5b5): undefined reference to `wbkgdset'
/usr/bin/ld: menubox.c:(.text+0x5bb): undefined reference to `acs_map'
/usr/bin/ld: menubox.c:(.text+0x5c3): undefined reference to `waddch'
/usr/bin/ld: menubox.c:(.text+0x5e2): undefined reference to `wattrset'
/usr/bin/ld: menubox.c:(.text+0x621): undefined reference to `subwin'
/usr/bin/ld: menubox.c:(.text+0x631): undefined reference to `keypad'
/usr/bin/ld: menubox.c:(.text+0x7ac): undefined reference to `wnoutrefresh'
/usr/bin/ld: menubox.c:(.text+0x7f5): undefined reference to `wmove'
/usr/bin/ld: menubox.c:(.text+0x7fd): undefined reference to `wrefresh'
/usr/bin/ld: menubox.c:(.text+0x805): undefined reference to `wgetch'
/usr/bin/ld: menubox.c:(.text+0x933): undefined reference to `delwin'
/usr/bin/ld: menubox.c:(.text+0x93b): undefined reference to `delwin'
/usr/bin/ld: menubox.c:(.text+0x97e): undefined reference to `delwin'
/usr/bin/ld: menubox.c:(.text+0x986): undefined reference to `delwin'
/usr/bin/ld: menubox.c:(.text+0xab9): undefined reference to `scrollok'
/usr/bin/ld: menubox.c:(.text+0xac6): undefined reference to `wscrl'
/usr/bin/ld: menubox.c:(.text+0xad0): undefined reference to `scrollok'
/usr/bin/ld: menubox.c:(.text+0xadd): undefined reference to `wrefresh'
/usr/bin/ld: menubox.c:(.text+0xb81): undefined reference to `wnoutrefresh'
/usr/bin/ld: menubox.c:(.text+0xb89): undefined reference to `wrefresh'
/usr/bin/ld: menubox.c:(.text+0xbe6): undefined reference to `wrefresh'
/usr/bin/ld: menubox.c:(.text+0xcc3): undefined reference to `delwin'
/usr/bin/ld: menubox.c:(.text+0xccb): undefined reference to `delwin'
/usr/bin/ld: menubox.c:(.text+0xf96): undefined reference to `wrefresh'
/usr/bin/ld: menubox.c:(.text+0xfca): undefined reference to `scrollok'
/usr/bin/ld: menubox.c:(.text+0xfd7): undefined reference to `wscrl'
/usr/bin/ld: menubox.c:(.text+0xfe1): undefined reference to `scrollok'
/usr/bin/ld: menubox.c:(.text+0xff3): undefined reference to `wrefresh'
/usr/bin/ld: menubox.c:(.text+0x1066): undefined reference to `delwin'
/usr/bin/ld: menubox.c:(.text+0x106e): undefined reference to `delwin'
/usr/bin/ld: menubox.c:(.text+0x111a): undefined reference to `scrollok'
/usr/bin/ld: menubox.c:(.text+0x112c): undefined reference to `wscrl'
/usr/bin/ld: menubox.c:(.text+0x1136): undefined reference to `scrollok'
/usr/bin/ld: menubox.c:(.text+0x113e): undefined reference to `wrefresh'
/usr/bin/ld: menubox.c:(.text+0x11f4): undefined reference to `scrollok'
/usr/bin/ld: menubox.c:(.text+0x1231): undefined reference to `scrollok'
/usr/bin/ld: menubox.c:(.text+0x123e): undefined reference to `wscrl'
/usr/bin/ld: menubox.c:(.text+0x1248): undefined reference to `scrollok'
/usr/bin/ld: menubox.c:(.text+0x1250): undefined reference to `wrefresh'
/usr/bin/ld: scripts/kconfig/lxdialog/menubox.o: in function `do_print_item':
menubox.c:(.text+0x126): undefined reference to `wrefresh'
/usr/bin/ld: scripts/kconfig/lxdialog/menubox.o: in function `print_buttons':
menubox.c:(.text+0x265): undefined reference to `wrefresh'
/usr/bin/ld: scripts/kconfig/lxdialog/menubox.o: in function `print_arrows.constprop.0':
menubox.c:(.text+0x374): undefined reference to `wrefresh'
/usr/bin/ld: scripts/kconfig/lxdialog/textbox.o: in function `refresh_text_box':
textbox.c:(.text+0x2da): undefined reference to `wmove'
/usr/bin/ld: textbox.c:(.text+0x2e7): undefined reference to `waddch'
/usr/bin/ld: textbox.c:(.text+0x304): undefined reference to `waddnstr'
/usr/bin/ld: textbox.c:(.text+0x30c): undefined reference to `wclrtoeol'
/usr/bin/ld: textbox.c:(.text+0x33d): undefined reference to `wnoutrefresh'
/usr/bin/ld: textbox.c:(.text+0x350): undefined reference to `wattrset'
/usr/bin/ld: textbox.c:(.text+0x364): undefined reference to `wbkgdset'
/usr/bin/ld: textbox.c:(.text+0x39c): undefined reference to `getmaxx'
/usr/bin/ld: textbox.c:(.text+0x3a6): undefined reference to `getmaxy'
/usr/bin/ld: textbox.c:(.text+0x3b4): undefined reference to `wmove'
/usr/bin/ld: textbox.c:(.text+0x3c7): undefined reference to `wprintw'
/usr/bin/ld: textbox.c:(.text+0x3d7): undefined reference to `wmove'
/usr/bin/ld: scripts/kconfig/lxdialog/textbox.o: in function `dialog_textbox':
textbox.c:(.text+0x48a): undefined reference to `stdscr'
/usr/bin/ld: textbox.c:(.text+0x48f): undefined reference to `getmaxy'
/usr/bin/ld: textbox.c:(.text+0x496): undefined reference to `stdscr'
/usr/bin/ld: textbox.c:(.text+0x49e): undefined reference to `getmaxx'
/usr/bin/ld: textbox.c:(.text+0x4c4): undefined reference to `stdscr'
/usr/bin/ld: textbox.c:(.text+0x4d9): undefined reference to `getmaxx'
/usr/bin/ld: textbox.c:(.text+0x4e0): undefined reference to `stdscr'
/usr/bin/ld: textbox.c:(.text+0x4f5): undefined reference to `getmaxy'
/usr/bin/ld: textbox.c:(.text+0x508): undefined reference to `stdscr'
/usr/bin/ld: textbox.c:(.text+0x530): undefined reference to `newwin'
/usr/bin/ld: textbox.c:(.text+0x540): undefined reference to `keypad'
/usr/bin/ld: textbox.c:(.text+0x55c): undefined reference to `subwin'
/usr/bin/ld: textbox.c:(.text+0x56d): undefined reference to `wattrset'
/usr/bin/ld: textbox.c:(.text+0x581): undefined reference to `wbkgdset'
/usr/bin/ld: textbox.c:(.text+0x58e): undefined reference to `keypad'
/usr/bin/ld: textbox.c:(.text+0x5c0): undefined reference to `wattrset'
/usr/bin/ld: textbox.c:(.text+0x5cf): undefined reference to `wmove'
/usr/bin/ld: textbox.c:(.text+0x5dc): undefined reference to `acs_map'
/usr/bin/ld: textbox.c:(.text+0x5e4): undefined reference to `waddch'
/usr/bin/ld: textbox.c:(.text+0x5f2): undefined reference to `acs_map'
/usr/bin/ld: textbox.c:(.text+0x5fe): undefined reference to `waddch'
/usr/bin/ld: textbox.c:(.text+0x611): undefined reference to `wattrset'
/usr/bin/ld: textbox.c:(.text+0x625): undefined reference to `wbkgdset'
/usr/bin/ld: textbox.c:(.text+0x62b): undefined reference to `acs_map'
/usr/bin/ld: textbox.c:(.text+0x633): undefined reference to `waddch'
/usr/bin/ld: textbox.c:(.text+0x670): undefined reference to `wnoutrefresh'
/usr/bin/ld: textbox.c:(.text+0x678): undefined reference to `getcury'
/usr/bin/ld: textbox.c:(.text+0x683): undefined reference to `getcurx'
/usr/bin/ld: textbox.c:(.text+0x6ca): undefined reference to `wgetch'
/usr/bin/ld: textbox.c:(.text+0x763): undefined reference to `delwin'
/usr/bin/ld: textbox.c:(.text+0x76b): undefined reference to `delwin'
/usr/bin/ld: textbox.c:(.text+0x82c): undefined reference to `wgetch'
/usr/bin/ld: textbox.c:(.text+0x9d4): undefined reference to `delwin'
/usr/bin/ld: textbox.c:(.text+0x9dc): undefined reference to `delwin'
/usr/bin/ld: scripts/kconfig/lxdialog/textbox.o: in function `refresh_text_box':
textbox.c:(.text+0x3ed): undefined reference to `wrefresh'
/usr/bin/ld: scripts/kconfig/lxdialog/util.o: in function `init_one_color':
util.c:(.text+0x2ef): undefined reference to `init_pair'
/usr/bin/ld: scripts/kconfig/lxdialog/util.o: in function `attr_clear':
util.c:(.text+0x324): undefined reference to `wattrset'
/usr/bin/ld: util.c:(.text+0x335): undefined reference to `wmove'
/usr/bin/ld: util.c:(.text+0x36c): undefined reference to `waddch'
/usr/bin/ld: util.c:(.text+0x387): undefined reference to `wmove'
/usr/bin/ld: util.c:(.text+0x3a0): undefined reference to `wmove'
/usr/bin/ld: util.c:(.text+0x3b0): undefined reference to `getmaxy'
/usr/bin/ld: scripts/kconfig/lxdialog/util.o: in function `dialog_clear':
util.c:(.text+0x3e1): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x3e6): undefined reference to `getmaxy'
/usr/bin/ld: util.c:(.text+0x3ed): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x3f4): undefined reference to `getmaxx'
/usr/bin/ld: util.c:(.text+0x401): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x428): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x42d): undefined reference to `wattrset'
/usr/bin/ld: util.c:(.text+0x434): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x440): undefined reference to `wmove'
/usr/bin/ld: util.c:(.text+0x47c): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x48f): undefined reference to `wmove'
/usr/bin/ld: util.c:(.text+0x4a6): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x4c2): undefined reference to `acs_map'
/usr/bin/ld: util.c:(.text+0x4c9): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x4d2): undefined reference to `waddch'
/usr/bin/ld: util.c:(.text+0x4de): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x502): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x50c): undefined reference to `waddnstr'
/usr/bin/ld: util.c:(.text+0x52b): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x542): undefined reference to `waddnstr'
/usr/bin/ld: util.c:(.text+0x59a): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x5a7): undefined reference to `waddnstr'
/usr/bin/ld: util.c:(.text+0x5ae): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x5b8): undefined reference to `waddch'
/usr/bin/ld: util.c:(.text+0x5cc): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x5d2): undefined reference to `acs_map'
/usr/bin/ld: util.c:(.text+0x5d7): undefined reference to `waddch'
/usr/bin/ld: util.c:(.text+0x5de): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x5e8): undefined reference to `waddch'
/usr/bin/ld: scripts/kconfig/lxdialog/util.o: in function `init_dialog':
util.c:(.text+0x61a): undefined reference to `initscr'
/usr/bin/ld: util.c:(.text+0x621): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x626): undefined reference to `getcury'
/usr/bin/ld: util.c:(.text+0x62d): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x638): undefined reference to `getcurx'
/usr/bin/ld: util.c:(.text+0x63f): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x64a): undefined reference to `getmaxy'
/usr/bin/ld: util.c:(.text+0x651): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x658): undefined reference to `getmaxx'
/usr/bin/ld: util.c:(.text+0x6ea): undefined reference to `has_colors'
/usr/bin/ld: util.c:(.text+0x6f7): undefined reference to `start_color'
/usr/bin/ld: util.c:(.text+0x866): undefined reference to `has_colors'
/usr/bin/ld: util.c:(.text+0x997): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0x9a1): undefined reference to `keypad'
/usr/bin/ld: util.c:(.text+0x9a6): undefined reference to `cbreak'
/usr/bin/ld: util.c:(.text+0x9ab): undefined reference to `noecho'
/usr/bin/ld: util.c:(.text+0xc01): undefined reference to `endwin'
/usr/bin/ld: scripts/kconfig/lxdialog/util.o: in function `end_dialog':
util.c:(.text+0xc39): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0xc3e): undefined reference to `wmove'
/usr/bin/ld: util.c:(.text+0xc45): undefined reference to `stdscr'
/usr/bin/ld: util.c:(.text+0xc4a): undefined reference to `wrefresh'
/usr/bin/ld: scripts/kconfig/lxdialog/util.o: in function `print_title':
util.c:(.text+0xca9): undefined reference to `wattrset'
/usr/bin/ld: util.c:(.text+0xcb6): undefined reference to `wmove'
/usr/bin/ld: util.c:(.text+0xcc8): undefined reference to `waddch'
/usr/bin/ld: util.c:(.text+0xcd4): undefined reference to `wmove'
/usr/bin/ld: util.c:(.text+0xce7): undefined reference to `waddnstr'
/usr/bin/ld: scripts/kconfig/lxdialog/util.o: in function `print_autowrap':
util.c:(.text+0xe18): undefined reference to `wmove'
/usr/bin/ld: util.c:(.text+0xe28): undefined reference to `waddnstr'
/usr/bin/ld: util.c:(.text+0xe30): undefined reference to `getcury'
/usr/bin/ld: util.c:(.text+0xe3a): undefined reference to `getcurx'
/usr/bin/ld: util.c:(.text+0xe9d): undefined reference to `wmove'
/usr/bin/ld: util.c:(.text+0xead): undefined reference to `waddnstr'
/usr/bin/ld: util.c:(.text+0xeb5): undefined reference to `getcury'
/usr/bin/ld: util.c:(.text+0xebd): undefined reference to `getcurx'
/usr/bin/ld: util.c:(.text+0xf65): undefined reference to `wmove'
/usr/bin/ld: util.c:(.text+0xf75): undefined reference to `waddnstr'
/usr/bin/ld: scripts/kconfig/lxdialog/util.o: in function `print_button':
util.c:(.text+0xfa3): undefined reference to `wmove'
/usr/bin/ld: util.c:(.text+0xfba): undefined reference to `wattrset'
/usr/bin/ld: util.c:(.text+0xfce): undefined reference to `waddnstr'
/usr/bin/ld: util.c:(.text+0xff5): undefined reference to `wattrset'
/usr/bin/ld: util.c:(.text+0x101d): undefined reference to `waddch'
/usr/bin/ld: util.c:(.text+0x1039): undefined reference to `wattrset'
/usr/bin/ld: util.c:(.text+0x1046): undefined reference to `waddch'
/usr/bin/ld: util.c:(.text+0x1054): undefined reference to `wattrset'
/usr/bin/ld: util.c:(.text+0x1066): undefined reference to `waddnstr'
/usr/bin/ld: util.c:(.text+0x1074): undefined reference to `wattrset'
/usr/bin/ld: util.c:(.text+0x1088): undefined reference to `waddnstr'
/usr/bin/ld: util.c:(.text+0x10ba): undefined reference to `wattrset'
/usr/bin/ld: util.c:(.text+0x10c7): undefined reference to `waddch'
/usr/bin/ld: util.c:(.text+0x10d5): undefined reference to `wattrset'
/usr/bin/ld: util.c:(.text+0x10e7): undefined reference to `waddnstr'
/usr/bin/ld: util.c:(.text+0x110a): undefined reference to `wattrset'
/usr/bin/ld: util.c:(.text+0x111e): undefined reference to `waddnstr'
/usr/bin/ld: util.c:(.text+0x1145): undefined reference to `wattrset'
/usr/bin/ld: scripts/kconfig/lxdialog/util.o: in function `draw_box':
util.c:(.text+0x118d): undefined reference to `wattrset'
/usr/bin/ld: util.c:(.text+0x11a4): undefined reference to `wmove'
/usr/bin/ld: util.c:(.text+0x11b9): undefined reference to `acs_map'
/usr/bin/ld: util.c:(.text+0x11c1): undefined reference to `waddch'
/usr/bin/ld: util.c:(.text+0x11ff): undefined reference to `waddch'
/usr/bin/ld: util.c:(.text+0x122d): undefined reference to `wmove'
/usr/bin/ld: util.c:(.text+0x1248): undefined reference to `acs_map'
/usr/bin/ld: util.c:(.text+0x124d): undefined reference to `waddch'
/usr/bin/ld: util.c:(.text+0x126e): undefined reference to `acs_map'
/usr/bin/ld: util.c:(.text+0x1273): undefined reference to `waddch'
/usr/bin/ld: util.c:(.text+0x1293): undefined reference to `acs_map'
/usr/bin/ld: util.c:(.text+0x129b): undefined reference to `waddch'
/usr/bin/ld: util.c:(.text+0x12aa): undefined reference to `acs_map'
/usr/bin/ld: util.c:(.text+0x12b2): undefined reference to `waddch'
/usr/bin/ld: util.c:(.text+0x12c4): undefined reference to `acs_map'
/usr/bin/ld: util.c:(.text+0x12c9): undefined reference to `waddch'
/usr/bin/ld: util.c:(.text+0x12e1): undefined reference to `acs_map'
/usr/bin/ld: util.c:(.text+0x12e6): undefined reference to `waddch'
/usr/bin/ld: util.c:(.text+0x12f2): undefined reference to `acs_map'
/usr/bin/ld: util.c:(.text+0x12fa): undefined reference to `waddch'
/usr/bin/ld: scripts/kconfig/lxdialog/util.o: in function `draw_shadow':
util.c:(.text+0x133e): undefined reference to `has_colors'
/usr/bin/ld: util.c:(.text+0x136a): undefined reference to `wattrset'
/usr/bin/ld: util.c:(.text+0x137c): undefined reference to `wmove'
/usr/bin/ld: util.c:(.text+0x1398): undefined reference to `winch'
/usr/bin/ld: util.c:(.text+0x13a3): undefined reference to `waddch'
/usr/bin/ld: util.c:(.text+0x13cc): undefined reference to `wmove'
/usr/bin/ld: util.c:(.text+0x13d4): undefined reference to `winch'
/usr/bin/ld: util.c:(.text+0x13df): undefined reference to `waddch'
/usr/bin/ld: util.c:(.text+0x13e7): undefined reference to `winch'
/usr/bin/ld: util.c:(.text+0x13f2): undefined reference to `waddch'
/usr/bin/ld: scripts/kconfig/lxdialog/util.o: in function `on_key_esc':
util.c:(.text+0x1513): undefined reference to `nodelay'
/usr/bin/ld: util.c:(.text+0x151d): undefined reference to `keypad'
/usr/bin/ld: util.c:(.text+0x1525): undefined reference to `wgetch'
/usr/bin/ld: util.c:(.text+0x1530): undefined reference to `wgetch'
/usr/bin/ld: util.c:(.text+0x1544): undefined reference to `wgetch'
/usr/bin/ld: util.c:(.text+0x1555): undefined reference to `nodelay'
/usr/bin/ld: util.c:(.text+0x1562): undefined reference to `keypad'
/usr/bin/ld: util.c:(.text+0x159e): undefined reference to `ungetch'
/usr/bin/ld: scripts/kconfig/lxdialog/util.o: in function `attr_clear':
util.c:(.text+0x3c9): undefined reference to `wtouchln'
/usr/bin/ld: scripts/kconfig/lxdialog/util.o: in function `dialog_clear':
util.c:(.text+0x4f1): undefined reference to `wnoutrefresh'
/usr/bin/ld: scripts/kconfig/lxdialog/util.o: in function `end_dialog':
util.c:(.text+0xc53): undefined reference to `endwin'
/usr/bin/ld: scripts/kconfig/lxdialog/util.o: in function `print_title':
util.c:(.text+0xcfc): undefined reference to `waddch'
/usr/bin/ld: scripts/kconfig/lxdialog/util.o: in function `print_button':
util.c:(.text+0x10a7): undefined reference to `wmove'
/usr/bin/ld: scripts/kconfig/lxdialog/util.o: in function `draw_shadow':
util.c:(.text+0x140d): undefined reference to `wnoutrefresh'
/usr/bin/ld: scripts/kconfig/lxdialog/yesno.o: in function `print_buttons':
yesno.c:(.text+0x6d): undefined reference to `wmove'
/usr/bin/ld: scripts/kconfig/lxdialog/yesno.o: in function `dialog_yesno':
yesno.c:(.text+0xc2): undefined reference to `stdscr'
/usr/bin/ld: yesno.c:(.text+0xc7): undefined reference to `getmaxy'
/usr/bin/ld: yesno.c:(.text+0xda): undefined reference to `stdscr'
/usr/bin/ld: yesno.c:(.text+0xdf): undefined reference to `getmaxx'
/usr/bin/ld: yesno.c:(.text+0xf0): undefined reference to `stdscr'
/usr/bin/ld: yesno.c:(.text+0xf5): undefined reference to `getmaxx'
/usr/bin/ld: yesno.c:(.text+0xfc): undefined reference to `stdscr'
/usr/bin/ld: yesno.c:(.text+0x10b): undefined reference to `getmaxy'
/usr/bin/ld: yesno.c:(.text+0x11d): undefined reference to `stdscr'
/usr/bin/ld: yesno.c:(.text+0x13e): undefined reference to `newwin'
/usr/bin/ld: yesno.c:(.text+0x14e): undefined reference to `keypad'
/usr/bin/ld: yesno.c:(.text+0x180): undefined reference to `wattrset'
/usr/bin/ld: yesno.c:(.text+0x18e): undefined reference to `wmove'
/usr/bin/ld: yesno.c:(.text+0x19b): undefined reference to `acs_map'
/usr/bin/ld: yesno.c:(.text+0x1a3): undefined reference to `waddch'
/usr/bin/ld: yesno.c:(.text+0x1c2): undefined reference to `acs_map'
/usr/bin/ld: yesno.c:(.text+0x1ce): undefined reference to `waddch'
/usr/bin/ld: yesno.c:(.text+0x1e1): undefined reference to `wattrset'
/usr/bin/ld: yesno.c:(.text+0x1e7): undefined reference to `acs_map'
/usr/bin/ld: yesno.c:(.text+0x1ef): undefined reference to `waddch'
/usr/bin/ld: yesno.c:(.text+0x20d): undefined reference to `wattrset'
/usr/bin/ld: yesno.c:(.text+0x23f): undefined reference to `wgetch'
/usr/bin/ld: yesno.c:(.text+0x26b): undefined reference to `delwin'
/usr/bin/ld: yesno.c:(.text+0x29b): undefined reference to `delwin'
/usr/bin/ld: yesno.c:(.text+0x2ba): undefined reference to `delwin'
/usr/bin/ld: yesno.c:(.text+0x2df): undefined reference to `delwin'
/usr/bin/ld: yesno.c:(.text+0x30d): undefined reference to `delwin'
/usr/bin/ld: yesno.c:(.text+0x344): undefined reference to `wrefresh'
/usr/bin/ld: yesno.c:(.text+0x373): undefined reference to `wrefresh'
/usr/bin/ld: scripts/kconfig/lxdialog/yesno.o: in function `print_buttons':
yesno.c:(.text+0x7f): undefined reference to `wrefresh'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
make[1]: *** [scripts/Makefile.host:123: scripts/kconfig/mconf] Fehler 1
make: *** [Makefile:703: menuconfig] Fehler 2
root@linus:/usr/src/linux-stable-rc#

Beste Grüße,
Peter Schneider

Signature · 8 lines
Climb the mountain not to plant your flag, but to embrace the challenge,
enjoy the air and behold the view. Climb it so you can see the world,
not so the world can see you.                    -- David McCullough Jr.

OpenPGP:  0xA3828BD796CCE11A8CADE8866E3A92C92C3FF244
Download: https://www.peters-netzplatz.de/download/pschneider1968_pub.asc
https://keys.mailvelope.com/pks/lookup?op=get&[email protected]
https://keys.mailvelope.com/pks/lookup?op=get&[email protected]
author maintainer
#289 lore raw
Quoted 25 lines · Peter Schneider

Hi Greg,

Am 04.02.2026 um 15:36 schrieb Greg Kroah-Hartman:

Quoted 7 lines

This is the start of the stable review cycle for the 6.1.162 release. There are 280 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 Fri, 06 Feb 2026 14:38:23 +0000. Anything received after that time might be too late.

It seems that this time, I cannot even build this RC. When I run "make menuconfig" I get a big serious of warning and error messages; something seems to be really messed up here...

root@linus:/usr/src/linux-stable-rc# vim .config
root@linus:/usr/src/linux-stable-rc# make menuconfig
scripts/kconfig/Makefile:215: Warnung: Das Musterrezept hat das Peer-Ziel „scripts/kconfig/mconf-bin“ nicht aktualisiert.
  HOSTCC  scripts/kconfig/mconf.o
  HOSTCC  scripts/kconfig/lxdialog/checklist.o
  HOSTCC  scripts/kconfig/lxdialog/inputbox.o
  HOSTCC  scripts/kconfig/lxdialog/menubox.o
  HOSTCC  scripts/kconfig/lxdialog/textbox.o
  HOSTCC  scripts/kconfig/lxdialog/util.o
Quoted 8 lines
  HOSTCC  scripts/kconfig/lxdialog/yesno.o
  HOSTLD  scripts/kconfig/mconf
/usr/bin/ld: scripts/kconfig/lxdialog/yesno.o: warning: relocation against `acs_map' in read-only section `.text'
/usr/bin/ld: scripts/kconfig/mconf.o: in function `show_help':
mconf.c:(.text+0xa1b): undefined reference to `stdscr'
/usr/bin/ld: mconf.c:(.text+0xa20): undefined reference to `getmaxx'
/usr/bin/ld: scripts/kconfig/lxdialog/checklist.o: in function `print_arrows':
checklist.c:(.text+0x2c): undefined reference to `wmove'

<snip>

Ick, yes, I can reproduce this myself here, something is odd. Let me track it down...

thanks,

greg k-h

author maintainer
#290 lore raw
Quoted 35 lines · Greg Kroah-Hartman
Quoted 25 lines · Peter Schneider

Hi Greg,

Am 04.02.2026 um 15:36 schrieb Greg Kroah-Hartman:

Quoted 7 lines

This is the start of the stable review cycle for the 6.1.162 release. There are 280 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 Fri, 06 Feb 2026 14:38:23 +0000. Anything received after that time might be too late.

It seems that this time, I cannot even build this RC. When I run "make menuconfig" I get a big serious of warning and error messages; something seems to be really messed up here...

root@linus:/usr/src/linux-stable-rc# vim .config
root@linus:/usr/src/linux-stable-rc# make menuconfig
scripts/kconfig/Makefile:215: Warnung: Das Musterrezept hat das Peer-Ziel „scripts/kconfig/mconf-bin“ nicht aktualisiert.
  HOSTCC  scripts/kconfig/mconf.o
  HOSTCC  scripts/kconfig/lxdialog/checklist.o
  HOSTCC  scripts/kconfig/lxdialog/inputbox.o
  HOSTCC  scripts/kconfig/lxdialog/menubox.o
  HOSTCC  scripts/kconfig/lxdialog/textbox.o
  HOSTCC  scripts/kconfig/lxdialog/util.o
Quoted 8 lines
  HOSTCC  scripts/kconfig/lxdialog/yesno.o
  HOSTLD  scripts/kconfig/mconf
/usr/bin/ld: scripts/kconfig/lxdialog/yesno.o: warning: relocation against `acs_map' in read-only section `.text'
/usr/bin/ld: scripts/kconfig/mconf.o: in function `show_help':
mconf.c:(.text+0xa1b): undefined reference to `stdscr'
/usr/bin/ld: mconf.c:(.text+0xa20): undefined reference to `getmaxx'
/usr/bin/ld: scripts/kconfig/lxdialog/checklist.o: in function `print_arrows':
checklist.c:(.text+0x2c): undefined reference to `wmove'
Quoted 4 lines

<snip>

Ick, yes, I can reproduce this myself here, something is odd. Let me track it down...

Ok, found the offending commit, will push out a -rc2 in a bit with this fixed, thanks for testing!

greg k-h

#291 lore raw

Hi Greg,

Am 05.02.2026 um 09:33 schrieb Greg Kroah-Hartman:

Quoted 38 lines · Greg Kroah-Hartman
Quoted 37 lines · Peter Schneider
Quoted 33 lines

Hi Greg,

Am 04.02.2026 um 15:36 schrieb Greg Kroah-Hartman:

Quoted 7 lines

This is the start of the stable review cycle for the 6.1.162 release. There are 280 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 Fri, 06 Feb 2026 14:38:23 +0000. Anything received after that time might be too late.

It seems that this time, I cannot even build this RC. When I run "make menuconfig" I get a big serious of warning and error messages; something seems to be really messed up here...

root@linus:/usr/src/linux-stable-rc# vim .config
root@linus:/usr/src/linux-stable-rc# make menuconfig
scripts/kconfig/Makefile:215: Warnung: Das Musterrezept hat das Peer-Ziel „scripts/kconfig/mconf-bin“ nicht aktualisiert.
   HOSTCC  scripts/kconfig/mconf.o
   HOSTCC  scripts/kconfig/lxdialog/checklist.o
   HOSTCC  scripts/kconfig/lxdialog/inputbox.o
   HOSTCC  scripts/kconfig/lxdialog/menubox.o
   HOSTCC  scripts/kconfig/lxdialog/textbox.o
   HOSTCC  scripts/kconfig/lxdialog/util.o
   HOSTCC  scripts/kconfig/lxdialog/yesno.o
   HOSTLD  scripts/kconfig/mconf
/usr/bin/ld: scripts/kconfig/lxdialog/yesno.o: warning: relocation against `acs_map' in read-only section `.text'
/usr/bin/ld: scripts/kconfig/mconf.o: in function `show_help':
mconf.c:(.text+0xa1b): undefined reference to `stdscr'
/usr/bin/ld: mconf.c:(.text+0xa20): undefined reference to `getmaxx'
/usr/bin/ld: scripts/kconfig/lxdialog/checklist.o: in function `print_arrows':
checklist.c:(.text+0x2c): undefined reference to `wmove'

<snip>

Quoted 7 lines
Quoted 2 lines

Ick, yes, I can reproduce this myself here, something is odd. Let me track it down...

Ok, found the offending commit, will push out a -rc2 in a bit with this fixed, thanks for testing!

greg k-h

I was too tired yesterday evening to investigate my build error and poke around deeper, but today I looked into it again, and I found that when I revert the two kconfig patches in this RC

7c177eca9e7af1f0a56171b7718a1b05aaa0f237 "kconfig: fix static linking of nconf" eb5defa1e8284b8b79653beadc92c273c170db7d "kconfig: refactor Makefile to reduce process forks"

then my build error goes away, the build succeeds and the produced kernel seems to work fine.

Beste Grüße,
Peter Schneider

Signature · 8 lines
Climb the mountain not to plant your flag, but to embrace the challenge,
enjoy the air and behold the view. Climb it so you can see the world,
not so the world can see you.                    -- David McCullough Jr.

OpenPGP:  0xA3828BD796CCE11A8CADE8866E3A92C92C3FF244
Download: https://www.peters-netzplatz.de/download/pschneider1968_pub.asc
https://keys.mailvelope.com/pks/lookup?op=get&[email protected]
https://keys.mailvelope.com/pks/lookup?op=get&[email protected]
author maintainer
#292 lore raw
Quoted 49 lines · Peter Schneider

Hi Greg,

Am 05.02.2026 um 09:33 schrieb Greg Kroah-Hartman:

Quoted 38 lines · Greg Kroah-Hartman
Quoted 37 lines · Peter Schneider
Quoted 33 lines

Hi Greg,

Am 04.02.2026 um 15:36 schrieb Greg Kroah-Hartman:

Quoted 7 lines

This is the start of the stable review cycle for the 6.1.162 release. There are 280 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 Fri, 06 Feb 2026 14:38:23 +0000. Anything received after that time might be too late.

It seems that this time, I cannot even build this RC. When I run "make menuconfig" I get a big serious of warning and error messages; something seems to be really messed up here...

root@linus:/usr/src/linux-stable-rc# vim .config
root@linus:/usr/src/linux-stable-rc# make menuconfig
scripts/kconfig/Makefile:215: Warnung: Das Musterrezept hat das Peer-Ziel „scripts/kconfig/mconf-bin“ nicht aktualisiert.
   HOSTCC  scripts/kconfig/mconf.o
   HOSTCC  scripts/kconfig/lxdialog/checklist.o
   HOSTCC  scripts/kconfig/lxdialog/inputbox.o
   HOSTCC  scripts/kconfig/lxdialog/menubox.o
   HOSTCC  scripts/kconfig/lxdialog/textbox.o
   HOSTCC  scripts/kconfig/lxdialog/util.o
   HOSTCC  scripts/kconfig/lxdialog/yesno.o
   HOSTLD  scripts/kconfig/mconf
/usr/bin/ld: scripts/kconfig/lxdialog/yesno.o: warning: relocation against `acs_map' in read-only section `.text'
/usr/bin/ld: scripts/kconfig/mconf.o: in function `show_help':
mconf.c:(.text+0xa1b): undefined reference to `stdscr'
/usr/bin/ld: mconf.c:(.text+0xa20): undefined reference to `getmaxx'
/usr/bin/ld: scripts/kconfig/lxdialog/checklist.o: in function `print_arrows':
checklist.c:(.text+0x2c): undefined reference to `wmove'

<snip>

Quoted 7 lines
Quoted 2 lines

Ick, yes, I can reproduce this myself here, something is odd. Let me track it down...

Ok, found the offending commit, will push out a -rc2 in a bit with this fixed, thanks for testing!

greg k-h

Quoted 8 lines

I was too tired yesterday evening to investigate my build error and poke around deeper, but today I looked into it again, and I found that when I revert the two kconfig patches in this RC

7c177eca9e7af1f0a56171b7718a1b05aaa0f237 "kconfig: fix static linking of nconf" eb5defa1e8284b8b79653beadc92c273c170db7d "kconfig: refactor Makefile to reduce process forks"

then my build error goes away, the build succeeds and the produced kernel seems to work fine.

Yes, those are the commits I dropped, thanks for verifying.

greg k-h