6.12.59-rc1 review
Subsystems (3)
Greg Kroah-Hartman
maintainerPATCH 147/185 btrfs: release root after error in data_reloc_print_warning_inode()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zilin Guan <[email protected]>
commit c367af440e03eba7beb0c9f3fe540f9bcb69134a upstream.
data_reloc_print_warning_inode() calls btrfs_get_fs_root() to obtain local_root, but fails to release its reference when paths_from_inode() returns an error. This causes a potential memory leak.
Add a missing btrfs_put_root() call in the error path to properly decrease the reference count of local_root.
--- fs/btrfs/inode.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/btrfs/inode.c +3 -1
@@ -174,8 +174,10 @@ static int data_reloc_print_warning_inodreturn ret; } ret =paths_from_inode (inum, ipath); -if (ret <0 ) +if (ret <0 ) { +btrfs_put_root (local_root); goto err; + }/* * We deliberately ignore the bit ipath might have been too small to
Greg Kroah-Hartman
maintainerPATCH 148/185 drm/amdkfd: relax checks for over allocation of save area
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Kim <[email protected]>
commit d15deafab5d722afb9e2f83c5edcdef9d9d98bd1 upstream.
Over allocation of save area is not fatal, only under allocation is. ROCm has various components that independently claim authority over save area size.
Unless KFD decides to claim single authority, relax size checks.
--- drivers/gpu/drm/amd/amdkfd/kfd_queue.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/gpu/drm/amd/amdkfd/kfd_queue.c +6 -6
@@ -297,16 +297,16 @@ int kfd_queue_acquire_buffers(struct kfd goto out_err_unreserve; } -if (properties->ctx_save_restore_area_size != topo_dev->node_props.cwsr_size) { -pr_debug ("queue cwsr size 0x%x not equal to node cwsr size 0x%x\n" , +if (properties->ctx_save_restore_area_size < topo_dev->node_props.cwsr_size) { +pr_debug ("queue cwsr size 0x%x not sufficient for node cwsr size 0x%x\n" , properties->ctx_save_restore_area_size, topo_dev->node_props.cwsr_size); err = -EINVAL ; goto out_err_unreserve; } - total_cwsr_size = (topo_dev->node_props.cwsr_size + topo_dev->node_props.debug_memory_size) - *NUM_XCC (pdd->dev->xcc_mask); + total_cwsr_size = (properties->ctx_save_restore_area_size + + topo_dev->node_props.debug_memory_size) *NUM_XCC (pdd->dev->xcc_mask); total_cwsr_size =ALIGN (total_cwsr_size,PAGE_SIZE ); err = kfd_queue_buffer_get(vm, (void *)properties->ctx_save_restore_area_address,
@@ -352,8 +352,8 @@ int kfd_queue_release_buffers(struct kfd topo_dev =kfd_topology_device_by_id (pdd->dev->id);if (!topo_dev)return -EINVAL ; - total_cwsr_size = (topo_dev->node_props.cwsr_size + topo_dev->node_props.debug_memory_size) - *NUM_XCC (pdd->dev->xcc_mask); + total_cwsr_size = (properties->ctx_save_restore_area_size + + topo_dev->node_props.debug_memory_size) *NUM_XCC (pdd->dev->xcc_mask); total_cwsr_size =ALIGN (total_cwsr_size,PAGE_SIZE );kfd_queue_buffer_svm_put (pdd, properties->ctx_save_restore_area_address, total_cwsr_size);
Greg Kroah-Hartman
maintainerPATCH 149/185 drm/amdgpu: disable peer-to-peer access for DCC-enabled GC12 VRAM surfaces
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vitaly Prosyak <[email protected]>
commit 22a36e660d014925114feb09a2680bb3c2d1e279 upstream.
Certain multi-GPU configurations (especially GFX12) may hit data corruption when a DCC-compressed VRAM surface is shared across GPUs using peer-to-peer (P2P) DMA transfers.
Such surfaces rely on device-local metadata and cannot be safely accessed through a remote GPU’s page tables. Attempting to import a DCC-enabled surface through P2P leads to incorrect rendering or GPU faults.
This change disables P2P for DCC-enabled VRAM buffers that are contiguous and allocated on GFX12+ hardware. In these cases, the importer falls back to the standard system-memory path, avoiding invalid access to compressed surfaces.
Future work could consider optional migration (VRAM→System→VRAM) if a performance regression is observed when attach->peer2peer = false.
Tested on:
- Dual RX 9700 XT (Navi4x) setup
- GNOME and Wayland compositor scenarios
- Confirmed no corruption after disabling P2P under these conditions
v2: Remove check TTM_PL_VRAM & TTM_PL_FLAG_CONTIGUOUS.
v3: simplify for upsteam and fix ip version check (Alex)
--- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +12 -0
@@ -81,6 +81,18 @@ static int amdgpu_dma_buf_attach(structstruct amdgpu_bo *bo =gem_to_amdgpu_bo (obj);struct amdgpu_device *adev =amdgpu_ttm_adev (bo->tbo.bdev); +/* +* Disable peer-to-peer access for DCC-enabled VRAM surfaces on GFX12+. +* Such buffers cannot be safely accessed over P2P due to device-local +* compression metadata. Fallback to system-memory path instead. +* Device supports GFX12 (GC 12.x or newer) +* BO was created with the AMDGPU_GEM_CREATE_GFX12_DCC flag +* +*/ +if (amdgpu_ip_version (adev,GC_HWIP ,0 ) >=IP_VERSION (12 ,0 ,0 ) && + bo->flags &AMDGPU_GEM_CREATE_GFX12_DCC ) + attach->peer2peer = false; +if (!amdgpu_dmabuf_is_xgmi_accessible (attach_adev, bo) &&pci_p2pdma_distance (adev->pdev, attach->dev, false) <0 ) attach->peer2peer = false;
Greg Kroah-Hartman
maintainerPATCH 150/185 pmdomain: arm: scmi: Fix genpd leak on provider registration failure
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sudeep Holla <[email protected]>
commit 7458f72cc28f9eb0de811effcb5376d0ec19094a upstream.
If of_genpd_add_provider_onecell() fails during probe, the previously created generic power domains are not removed, leading to a memory leak and potential kernel crash later in genpd_debug_add().
Add proper error handling to unwind the initialized domains before returning from probe to ensure all resources are correctly released on failure.
Example crash trace observed without this fix:
| Unable to handle kernel paging request at virtual address fffffffffffffc70 | CPU: 1 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.18.0-rc1 #405 PREEMPT | Hardware name: ARM LTD ARM Juno Development Platform/ARM Juno Development Platform | pstate: 00000005 (nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) | pc : genpd_debug_add+0x2c/0x160 | lr : genpd_debug_init+0x74/0x98 | Call trace: | genpd_debug_add+0x2c/0x160 (P) | genpd_debug_init+0x74/0x98 | do_one_initcall+0xd0/0x2d8 | do_initcall_level+0xa0/0x140 | do_initcalls+0x60/0xa8 | do_basic_setup+0x28/0x40 | kernel_init_freeable+0xe8/0x170 | kernel_init+0x2c/0x140 | ret_from_fork+0x10/0x20
--- drivers/pmdomain/arm/scmi_pm_domain.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
drivers/pmdomain/arm/scmi_pm_domain.c +11 -2
@@ -54,7 +54,7 @@ static int scmi_pd_power_off(struct genestatic int scmi_pm_domain_probe (struct scmi_device *sdev) { -int num_domains, i; +int num_domains, i, ret;struct device *dev = &sdev->dev;struct device_node *np = dev->of_node;struct scmi_pm_domain *scmi_pd;
@@ -113,9 +113,18 @@ static int scmi_pm_domain_probe(struct s scmi_pd_data->domains = domains; scmi_pd_data->num_domains = num_domains; + ret =of_genpd_add_provider_onecell (np, scmi_pd_data); +if (ret) + goto err_rm_genpds; +dev_set_drvdata (dev, scmi_pd_data); -return of_genpd_add_provider_onecell (np, scmi_pd_data); +return 0 ; +err_rm_genpds: +for (i = num_domains -1 ; i >=0 ; i--) +pm_genpd_remove (domains[i]); + +return ret; }static void scmi_pm_domain_remove (struct scmi_device *sdev)
Greg Kroah-Hartman
maintainerPATCH 151/185 pmdomain: imx: Fix reference count leak in imx_gpc_remove
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miaoqian Lin <[email protected]>
commit bbde14682eba21d86f5f3d6fe2d371b1f97f1e61 upstream.
of_get_child_by_name() returns a node pointer with refcount incremented, we should use of_node_put() on it when not needed anymore. Add the missing of_node_put() to avoid refcount leak.
--- drivers/pmdomain/imx/gpc.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/pmdomain/imx/gpc.c +2 -0
@@ -537,6 +537,8 @@ static void imx_gpc_remove(struct platforeturn ; } } + +of_node_put (pgc_node); }static struct platform_driver imx_gpc_driver = {
Greg Kroah-Hartman
maintainerPATCH 152/185 pmdomain: samsung: plug potential memleak during probe
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: André Draszik <[email protected]>
commit 90c82941adf1986364e0f82c35cf59f2bf5f6a1d upstream.
of_genpd_add_provider_simple() could fail, in which case this code leaks the domain name, pd->pd.name.
Use devm_kstrdup_const() to plug this leak. As a side-effect, we can simplify existing error handling.
--- drivers/pmdomain/samsung/exynos-pm-domains.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/pmdomain/samsung/exynos-pm-domains.c +5 -6
@@ -92,13 +92,14 @@ static const struct of_device_id exynos_ { }, }; -static const char *exynos_get_domain_name (struct device_node *node) +static const char *exynos_get_domain_name (struct device *dev, +struct device_node *node) {const char *name;if (of_property_read_string (node,"label" , &name) <0 ) name =kbasename (node->full_name); -return kstrdup_const (name,GFP_KERNEL ); +return devm_kstrdup_const (dev, name,GFP_KERNEL ); }static int exynos_pd_probe (struct platform_device *pdev)
@@ -115,15 +116,13 @@ static int exynos_pd_probe(struct platfoif (!pd)return -ENOMEM ; - pd->pd.name =exynos_get_domain_name (np); + pd->pd.name =exynos_get_domain_name (dev, np);if (!pd->pd.name)return -ENOMEM ; pd->base =of_iomap (np,0 ); -if (!pd->base) { -kfree_const (pd->pd.name); +if (!pd->base)return -ENODEV ; - } pd->pd.power_off = exynos_pd_power_off; pd->pd.power_on = exynos_pd_power_on;
Greg Kroah-Hartman
maintainerPATCH 153/185 selftests: mptcp: connect: fix fallback note due to OoO
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <[email protected]>
commit 63c643aa7b7287fdbb0167063785f89ece3f000f upstream.
The "fallback due to TCP OoO" was never printed because the stat_ooo_now variable was checked twice: once in the parent if-statement, and one in the child one. The second condition was then always true then, and the 'else' branch was never taken.
The idea is that when there are more ACK + MP_CAPABLE than expected, the test either fails if there was no out of order packets, or a notice is printed.
--- tools/testing/selftests/net/mptcp/mptcp_connect.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/net/mptcp/mptcp_connect.sh +1 -1
@@ -493,7 +493,7 @@ do_transfer() "than expected (${expect_synrx})" retc=1 fi - if [ ${stat_ackrx_now_l} -lt ${expect_ackrx} ] && [ ${stat_ooo_now} -eq 0 ]; then + if [ ${stat_ackrx_now_l} -lt ${expect_ackrx} ]; then if [ ${stat_ooo_now} -eq 0 ]; then mptcp_lib_pr_fail "lower MPC ACK rx (${stat_ackrx_now_l})" \ "than expected (${expect_ackrx})"
Greg Kroah-Hartman
maintainerPATCH 154/185 selftests: mptcp: join: rm: set backup flag
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <[email protected]>
commit aea73bae662a0e184393d6d7d0feb18d2577b9b9 upstream.
Some of these 'remove' tests rarely fail because a subflow has been reset instead of cleanly removed. This can happen when one extra subflow which has never carried data is being closed (FIN) on one side, while the other is sending data for the first time.
To avoid such subflows to be used right at the end, the backup flag has been added. With that, data will be only carried on the initial subflow.
--- tools/testing/selftests/net/mptcp/mptcp_join.sh | 54 ++++++++++++------------ 1 file changed, 27 insertions(+), 27 deletions(-)
tools/testing/selftests/net/mptcp/mptcp_join.sh +27 -27
@@ -2321,7 +2321,7 @@ remove_tests() if reset "remove single subflow"; then pm_nl_set_limits $ns1 0 1 pm_nl_set_limits $ns2 0 1 - pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow + pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup addr_nr_ns2=-1 speed=slow \ run_tests $ns1 $ns2 10.0.1.1 chk_join_nr 1 1 1
@@ -2334,8 +2334,8 @@ remove_tests() if reset "remove multiple subflows"; then pm_nl_set_limits $ns1 0 2 pm_nl_set_limits $ns2 0 2 - pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow - pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow + pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,backup + pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup addr_nr_ns2=-2 speed=slow \ run_tests $ns1 $ns2 10.0.1.1 chk_join_nr 2 2 2
@@ -2346,7 +2346,7 @@ remove_tests() # single address, remove if reset "remove single address"; then pm_nl_set_limits $ns1 0 1 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup pm_nl_set_limits $ns2 1 1 addr_nr_ns1=-1 speed=slow \ run_tests $ns1 $ns2 10.0.1.1
@@ -2359,9 +2359,9 @@ remove_tests() # subflow and signal, remove if reset "remove subflow and signal"; then pm_nl_set_limits $ns1 0 2 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup pm_nl_set_limits $ns2 1 2 - pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow + pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup addr_nr_ns1=-1 addr_nr_ns2=-1 speed=slow \ run_tests $ns1 $ns2 10.0.1.1 chk_join_nr 2 2 2
@@ -2373,10 +2373,10 @@ remove_tests() # subflows and signal, remove if reset "remove subflows and signal"; then pm_nl_set_limits $ns1 0 3 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup pm_nl_set_limits $ns2 1 3 - pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow - pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow + pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup + pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow,backup addr_nr_ns1=-1 addr_nr_ns2=-2 speed=10 \ run_tests $ns1 $ns2 10.0.1.1 chk_join_nr 3 3 3
@@ -2388,9 +2388,9 @@ remove_tests() # addresses remove if reset "remove addresses"; then pm_nl_set_limits $ns1 3 3 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal id 250 - pm_nl_add_endpoint $ns1 10.0.3.1 flags signal - pm_nl_add_endpoint $ns1 10.0.4.1 flags signal + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup id 250 + pm_nl_add_endpoint $ns1 10.0.3.1 flags signal,backup + pm_nl_add_endpoint $ns1 10.0.4.1 flags signal,backup pm_nl_set_limits $ns2 3 3 addr_nr_ns1=-3 speed=10 \ run_tests $ns1 $ns2 10.0.1.1
@@ -2403,10 +2403,10 @@ remove_tests() # invalid addresses remove if reset "remove invalid addresses"; then pm_nl_set_limits $ns1 3 3 - pm_nl_add_endpoint $ns1 10.0.12.1 flags signal + pm_nl_add_endpoint $ns1 10.0.12.1 flags signal,backup # broadcast IP: no packet for this address will be received on ns1 - pm_nl_add_endpoint $ns1 224.0.0.1 flags signal - pm_nl_add_endpoint $ns1 10.0.3.1 flags signal + pm_nl_add_endpoint $ns1 224.0.0.1 flags signal,backup + pm_nl_add_endpoint $ns1 10.0.3.1 flags signal,backup pm_nl_set_limits $ns2 2 2 addr_nr_ns1=-3 speed=10 \ run_tests $ns1 $ns2 10.0.1.1
@@ -2420,10 +2420,10 @@ remove_tests() # subflows and signal, flush if reset "flush subflows and signal"; then pm_nl_set_limits $ns1 0 3 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup pm_nl_set_limits $ns2 1 3 - pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow - pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow + pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup + pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow,backup addr_nr_ns1=-8 addr_nr_ns2=-8 speed=slow \ run_tests $ns1 $ns2 10.0.1.1 chk_join_nr 3 3 3
@@ -2436,9 +2436,9 @@ remove_tests() if reset "flush subflows"; then pm_nl_set_limits $ns1 3 3 pm_nl_set_limits $ns2 3 3 - pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow id 150 - pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow - pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow + pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,backup id 150 + pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup + pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow,backup addr_nr_ns1=-8 addr_nr_ns2=-8 speed=slow \ run_tests $ns1 $ns2 10.0.1.1 chk_join_nr 3 3 3
@@ -2455,9 +2455,9 @@ remove_tests() # addresses flush if reset "flush addresses"; then pm_nl_set_limits $ns1 3 3 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal id 250 - pm_nl_add_endpoint $ns1 10.0.3.1 flags signal - pm_nl_add_endpoint $ns1 10.0.4.1 flags signal + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup id 250 + pm_nl_add_endpoint $ns1 10.0.3.1 flags signal,backup + pm_nl_add_endpoint $ns1 10.0.4.1 flags signal,backup pm_nl_set_limits $ns2 3 3 addr_nr_ns1=-8 addr_nr_ns2=-8 speed=slow \ run_tests $ns1 $ns2 10.0.1.1
@@ -2470,9 +2470,9 @@ remove_tests() # invalid addresses flush if reset "flush invalid addresses"; then pm_nl_set_limits $ns1 3 3 - pm_nl_add_endpoint $ns1 10.0.12.1 flags signal - pm_nl_add_endpoint $ns1 10.0.3.1 flags signal - pm_nl_add_endpoint $ns1 10.0.14.1 flags signal + pm_nl_add_endpoint $ns1 10.0.12.1 flags signal,backup + pm_nl_add_endpoint $ns1 10.0.3.1 flags signal,backup + pm_nl_add_endpoint $ns1 10.0.14.1 flags signal,backup pm_nl_set_limits $ns2 3 3 addr_nr_ns1=-8 speed=slow \ run_tests $ns1 $ns2 10.0.1.1
Greg Kroah-Hartman
maintainerPATCH 155/185 selftests: mptcp: join: endpoints: longer transfer
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <[email protected]>
commit 6457595db9870298ee30b6d75287b8548e33fe19 upstream.
In rare cases, when the test environment is very slow, some userspace tests can fail because some expected events have not been seen.
Because the tests are expecting a long on-going connection, and they are not waiting for the end of the transfer, it is fine to make the connection longer. This connection will be killed at the end, after the verifications, so making it longer doesn't change anything, apart from avoid it to end before the end of the verifications
To play it safe, all endpoints tests not waiting for the end of the transfer are now sharing a longer file (128KB) at slow speed.
--- tools/testing/selftests/net/mptcp/mptcp_join.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
tools/testing/selftests/net/mptcp/mptcp_join.sh +4 -4
@@ -3728,7 +3728,7 @@ endpoint_tests() pm_nl_set_limits $ns1 2 2 pm_nl_set_limits $ns2 2 2 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal - { speed=slow \ + { test_linkfail=128 speed=slow \ run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null local tests_pid=$!
@@ -3755,7 +3755,7 @@ endpoint_tests() pm_nl_set_limits $ns2 0 3 pm_nl_add_endpoint $ns2 10.0.1.2 id 1 dev ns2eth1 flags subflow pm_nl_add_endpoint $ns2 10.0.2.2 id 2 dev ns2eth2 flags subflow - { test_linkfail=4 speed=5 \ + { test_linkfail=128 speed=5 \ run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null local tests_pid=$!
@@ -3833,7 +3833,7 @@ endpoint_tests() # broadcast IP: no packet for this address will be received on ns1 pm_nl_add_endpoint $ns1 224.0.0.1 id 2 flags signal pm_nl_add_endpoint $ns1 10.0.1.1 id 42 flags signal - { test_linkfail=4 speed=5 \ + { test_linkfail=128 speed=5 \ run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null local tests_pid=$!
@@ -3906,7 +3906,7 @@ endpoint_tests() # broadcast IP: no packet for this address will be received on ns1 pm_nl_add_endpoint $ns1 224.0.0.1 id 2 flags signal pm_nl_add_endpoint $ns2 10.0.3.2 id 3 flags subflow - { test_linkfail=4 speed=20 \ + { test_linkfail=128 speed=20 \ run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null local tests_pid=$!
Greg Kroah-Hartman
maintainerPATCH 156/185 selftests: mptcp: connect: trunc: read all recv data
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <[email protected]>
commit ee79980f7a428ec299f6261bea4c1084dcbc9631 upstream.
MPTCP Join "fastclose server" selftest is sometimes failing because the client output file doesn't have the expected size, e.g. 296B instead of 1024B.
When looking at a packet trace when this happens, the server sent the expected 1024B in two parts -- 100B, then 924B -- then the MP_FASTCLOSE. It is then strange to see the client only receiving 296B, which would mean it only got a part of the second packet. The problem is then not on the networking side, but rather on the data reception side.
When mptcp_connect is launched with '-f -1', it means the connection might stop before having sent everything, because a reset has been received. When this happens, the program was directly stopped. But it is also possible there are still some data to read, simply because the previous 'read' step was done with a buffer smaller than the pending data, see do_rnd_read(). In this case, it is important to read what's left in the kernel buffers before stopping without error like before.
SIGPIPE is now ignored, not to quit the app before having read everything.
--- tools/testing/selftests/net/mptcp/mptcp_connect.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
tools/testing/selftests/net/mptcp/mptcp_connect.c +13 -5
@@ -696,8 +696,14 @@ static int copyfd_io_poll(int infd, int bw =do_rnd_write (peerfd, winfo->buf + winfo->off, winfo->len);if (bw <0 ) { -if (cfg_rcv_trunc) -return 0 ; +/* expected reset, continue to read */ +if (cfg_rcv_trunc && + (errno ==ECONNRESET || + errno ==EPIPE )) { + fds.events &= ~POLLOUT ; +continue ; + } +perror ("write" );return 111 ; }
@@ -723,8 +729,10 @@ static int copyfd_io_poll(int infd, int }if (fds.revents & (POLLERR |POLLNVAL )) { -if (cfg_rcv_trunc) -return 0 ; +if (cfg_rcv_trunc) { + fds.events &= ~(POLLERR |POLLNVAL ); +continue ; + }fprintf (stderr,"Unexpected revents: " "POLLERR/POLLNVAL(%x)\n" , fds.revents);return 5 ;
@@ -1419,7 +1427,7 @@ static void parse_opts(int argc, char ***/ if (cfg_truncate <0 ) { cfg_rcv_trunc = true; -signal (SIGPIPE , handle_signal); +signal (SIGPIPE ,SIG_IGN ); }break ;case 'j' :
Greg Kroah-Hartman
maintainerPATCH 157/185 selftests: mptcp: join: userspace: longer transfer
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <[email protected]>
commit 290493078b96ce2ce3e60f55c23654acb678042a upstream.
In rare cases, when the test environment is very slow, some userspace tests can fail because some expected events have not been seen.
Because the tests are expecting a long on-going connection, and they are not waiting for the end of the transfer, it is fine to make the connection longer. This connection will be killed at the end, after the verifications, so making it longer doesn't change anything, apart from avoid it to end before the end of the verifications
To play it safe, all userspace tests not waiting for the end of the transfer are now sharing a longer file (128KB) at slow speed.
--- tools/testing/selftests/net/mptcp/mptcp_join.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
tools/testing/selftests/net/mptcp/mptcp_join.sh +5 -5
@@ -3591,7 +3591,7 @@ userspace_tests() continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then set_userspace_pm $ns1 pm_nl_set_limits $ns2 2 2 - { speed=5 \ + { test_linkfail=128 speed=5 \ run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null local tests_pid=$! wait_mpj $ns1
@@ -3624,7 +3624,7 @@ userspace_tests() continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then set_userspace_pm $ns2 pm_nl_set_limits $ns1 0 1 - { speed=5 \ + { test_linkfail=128 speed=5 \ run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null local tests_pid=$! wait_mpj $ns2
@@ -3652,7 +3652,7 @@ userspace_tests() continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then set_userspace_pm $ns2 pm_nl_set_limits $ns1 0 1 - { speed=5 \ + { test_linkfail=128 speed=5 \ run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null local tests_pid=$! wait_mpj $ns2
@@ -3673,7 +3673,7 @@ userspace_tests() continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then set_userspace_pm $ns2 pm_nl_set_limits $ns1 0 1 - { speed=5 \ + { test_linkfail=128 speed=5 \ run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null local tests_pid=$! wait_mpj $ns2
@@ -3697,7 +3697,7 @@ userspace_tests() continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then set_userspace_pm $ns1 pm_nl_set_limits $ns2 1 1 - { speed=5 \ + { test_linkfail=128 speed=5 \ run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null local tests_pid=$! wait_mpj $ns1
Greg Kroah-Hartman
maintainerPATCH 158/185 selftests: mptcp: join: properly kill background tasks
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <[email protected]>
commit 852b644acbce1529307a4bb283752c4e77b5cda7 upstream.
The 'run_tests' function is executed in the background, but killing its associated PID would not kill the children tasks running in the background.
To properly kill all background tasks, 'kill -- -PID' could be used, but this requires kill from procps-ng. Instead, all children tasks are listed using 'ps', and 'kill' is called with all PIDs of this group.
--- tools/testing/selftests/net/mptcp/mptcp_join.sh | 18 +++++++++--------- tools/testing/selftests/net/mptcp/mptcp_lib.sh | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-)
tools/testing/selftests/net/mptcp/mptcp_join.sh +9 -9
@@ -3616,7 +3616,7 @@ userspace_tests() chk_mptcp_info subflows 0 subflows 0 chk_subflows_total 1 1 kill_events_pids - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid fi # userspace pm create destroy subflow
@@ -3644,7 +3644,7 @@ userspace_tests() chk_mptcp_info subflows 0 subflows 0 chk_subflows_total 1 1 kill_events_pids - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid fi # userspace pm create id 0 subflow
@@ -3665,7 +3665,7 @@ userspace_tests() chk_mptcp_info subflows 1 subflows 1 chk_subflows_total 2 2 kill_events_pids - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid fi # userspace pm remove initial subflow
@@ -3689,7 +3689,7 @@ userspace_tests() chk_mptcp_info subflows 1 subflows 1 chk_subflows_total 1 1 kill_events_pids - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid fi # userspace pm send RM_ADDR for ID 0
@@ -3715,7 +3715,7 @@ userspace_tests() chk_mptcp_info subflows 1 subflows 1 chk_subflows_total 1 1 kill_events_pids - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid fi }
@@ -3745,7 +3745,7 @@ endpoint_tests() pm_nl_add_endpoint $ns2 10.0.2.2 flags signal pm_nl_check_endpoint "modif is allowed" \ $ns2 10.0.2.2 id 1 flags signal - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid fi if reset_with_tcp_filter "delete and re-add" ns2 10.0.3.2 REJECT OUTPUT &&
@@ -3800,7 +3800,7 @@ endpoint_tests() chk_mptcp_info subflows 3 subflows 3 done - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid kill_events_pids chk_evt_nr ns1 MPTCP_LIB_EVENT_LISTENER_CREATED 1
@@ -3874,7 +3874,7 @@ endpoint_tests() wait_mpj $ns2 chk_subflow_nr "after re-re-add ID 0" 3 chk_mptcp_info subflows 3 subflows 3 - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid kill_events_pids chk_evt_nr ns1 MPTCP_LIB_EVENT_LISTENER_CREATED 1
@@ -3922,7 +3922,7 @@ endpoint_tests() wait_mpj $ns2 pm_nl_add_endpoint $ns1 10.0.3.1 id 2 flags signal wait_mpj $ns2 - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid join_syn_tx=3 join_connect_err=1 \ chk_join_nr 2 2 2
tools/testing/selftests/net/mptcp/mptcp_lib.sh +21 -0
@@ -327,6 +327,27 @@ mptcp_lib_kill_wait() { wait "${1}" 2>/dev/null } +# $1: PID +mptcp_lib_pid_list_children() { + local curr="${1}" + # evoke 'ps' only once + local pids="${2:-"$(ps o pid,ppid)"}" + + echo "${curr}" + + local pid + for pid in $(echo "${pids}" | awk "\$2 == ${curr} { print \$1 }"); do + mptcp_lib_pid_list_children "${pid}" "${pids}" + done +} + +# $1: PID +mptcp_lib_kill_group_wait() { + # Some users might not have procps-ng: cannot use "kill -- -PID" + mptcp_lib_pid_list_children "${1}" | xargs -r kill &>/dev/null + wait "${1}" 2>/dev/null +} + # $1: IP address mptcp_lib_is_v6() { [ -z "${1##*:*}" ]
Greg Kroah-Hartman
maintainerPATCH 159/185 mptcp: fix MSG_PEEK stream corruption
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
[ Upstream commit 8e04ce45a8db7a080220e86e249198fa676b83dc ]
If a MSG_PEEK | MSG_WAITALL read operation consumes all the bytes in the receive queue and recvmsg() need to waits for more data - i.e. it's a blocking one - upon arrival of the next packet the MPTCP protocol will start again copying the oldest data present in the receive queue, corrupting the data stream.
Address the issue explicitly tracking the peeked sequence number, restarting from the last peeked byte.
---
Note: this is the patch Sasha sent for the v6.6 which applies on v6.12 without conflicts. On v6.12, Sasha sent another version with dependences that caused some issues, see:
https://lore.kernel.org/[email protected]
--- net/mptcp/protocol.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-)
net/mptcp/protocol.c +25 -11
@@ -1977,19 +1977,35 @@ static void mptcp_rcv_space_adjust(strucstatic int __mptcp_recvmsg_mskq (struct mptcp_sock *msk,struct msghdr *msg, -size_t len,int flags, +size_t len,int flags,int copied_total,struct scm_timestamping_internal *tss,int *cmsg_flags) {struct sk_buff *skb, *tmp; +int total_data_len =0 ;int copied =0 ; skb_queue_walk_safe(&msk->receive_queue, skb, tmp) { -u32 offset =MPTCP_SKB_CB (skb)->offset; +u32 delta, offset =MPTCP_SKB_CB (skb)->offset;u32 data_len = skb->len - offset; -u32 count =min_t (size_t, len - copied, data_len); +u32 count;int err; +if (flags &MSG_PEEK ) { +/* skip already peeked skbs */ +if (total_data_len + data_len <= copied_total) { + total_data_len += data_len; +continue ; + } + +/* skip the already peeked data in the current skb */ + delta = copied_total - total_data_len; + offset += delta; + data_len -= delta; + } + + count =min_t (size_t, len - copied, data_len); +if (!(flags &MSG_TRUNC )) { err =skb_copy_datagram_msg (skb, offset, msg, count);if (unlikely (err <0 )) {
@@ -2006,22 +2022,19 @@ static int __mptcp_recvmsg_mskq(struct m copied += count; -if (count < data_len) { -if (!(flags &MSG_PEEK )) { +if (!(flags &MSG_PEEK )) { + msk->bytes_consumed += count; +if (count < data_len) {MPTCP_SKB_CB (skb)->offset += count;MPTCP_SKB_CB (skb)->map_seq += count; - msk->bytes_consumed += count; +break ; } -break ; - } -if (!(flags &MSG_PEEK )) {/* we will bulk release the skb memory later */ skb->destructor =NULL ;WRITE_ONCE (msk->rmem_released, msk->rmem_released + skb->truesize);__skb_unlink (skb, &msk->receive_queue);__kfree_skb (skb); - msk->bytes_consumed += count; }if (copied >= len)
@@ -2245,7 +2258,8 @@ static int mptcp_recvmsg(struct sock *skwhile (copied < len) {int err, bytes_read; - bytes_read =__mptcp_recvmsg_mskq (msk, msg, len - copied, flags, &tss, &cmsg_flags); + bytes_read =__mptcp_recvmsg_mskq (msk, msg, len - copied, flags, + copied, &tss, &cmsg_flags);if (unlikely (bytes_read <0 )) {if (!copied) copied = bytes_read;
Greg Kroah-Hartman
maintainerPATCH 160/185 wifi: cfg80211: add an hrtimer based delayed work item
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Berg <[email protected]>
[ Upstream commit 7ceba45a6658ce637da334cd0ebf27f4ede6c0fe ]
The normal timer mechanism assume that timeout further in the future need a lower accuracy. As an example, the granularity for a timer scheduled 4096 ms in the future on a 1000 Hz system is already 512 ms. This granularity is perfectly sufficient for e.g. timeouts, but there are other types of events that will happen at a future point in time and require a higher accuracy.
Add a new wiphy_hrtimer_work type that uses an hrtimer internally. The API is almost identical to the existing wiphy_delayed_work and it can be used as a drop-in replacement after minor adjustments. The work will be scheduled relative to the current time with a slack of 1 millisecond.
--- include/net/cfg80211.h | 78 +++++++++++++++++++++++++++++++++++++++++++++++++ net/wireless/core.c | 56 +++++++++++++++++++++++++++++++++++ net/wireless/trace.h | 21 +++++++++++++ 3 files changed, 155 insertions(+)
include/net/cfg80211.h +78 -0
@@ -6105,6 +6105,11 @@ static inline void wiphy_delayed_work_in* after wiphy_lock() was called. Therefore, wiphy_cancel_work() can * use just cancel_work() instead of cancel_work_sync(), it requires * being in a section protected by wiphy_lock(). +* +* Note that these are scheduled with a timer where the accuracy +* becomes less the longer in the future the scheduled timer is. Use +* wiphy_hrtimer_work_queue() if the timer must be not be late by more +* than approximately 10 percent. */ void wiphy_delayed_work_queue(struct wiphy *wiphy, struct wiphy_delayed_work *dwork,
@@ -6176,6 +6181,79 @@ void wiphy_delayed_work_flush(struct wipbool wiphy_delayed_work_pending (struct wiphy *wiphy,struct wiphy_delayed_work *dwork); +struct wiphy_hrtimer_work { +struct wiphy_work work; +struct wiphy *wiphy; +struct hrtimer timer; +}; + +enum hrtimer_restart wiphy_hrtimer_work_timer (struct hrtimer *t); + +static inline void wiphy_hrtimer_work_init (struct wiphy_hrtimer_work *hrwork, +wiphy_work_func_t func) +{ +hrtimer_init (&hrwork->timer,CLOCK_BOOTTIME ,HRTIMER_MODE_REL ); + hrwork->timer.function = wiphy_hrtimer_work_timer; +wiphy_work_init (&hrwork->work, func); +} + +/** +* wiphy_hrtimer_work_queue - queue hrtimer work for the wiphy +* @wiphy: the wiphy to queue for +* @hrwork: the high resolution timer worker +* @delay: the delay given as a ktime_t +* +* Please refer to wiphy_delayed_work_queue(). The difference is that +* the hrtimer work uses a high resolution timer for scheduling. This +* may be needed if timeouts might be scheduled further in the future +* and the accuracy of the normal timer is not sufficient. +* +* Expect a delay of a few milliseconds as the timer is scheduled +* with some slack and some more time may pass between queueing the +* work and its start. +*/ +void wiphy_hrtimer_work_queue (struct wiphy *wiphy, +struct wiphy_hrtimer_work *hrwork, +ktime_t delay); + +/** +* wiphy_hrtimer_work_cancel - cancel previously queued hrtimer work +* @wiphy: the wiphy, for debug purposes +* @hrtimer: the hrtimer work to cancel +* +* Cancel the work *without* waiting for it, this assumes being +* called under the wiphy mutex acquired by wiphy_lock(). +*/ +void wiphy_hrtimer_work_cancel (struct wiphy *wiphy, +struct wiphy_hrtimer_work *hrtimer); + +/** +* wiphy_hrtimer_work_flush - flush previously queued hrtimer work +* @wiphy: the wiphy, for debug purposes +* @hrwork: the hrtimer work to flush +* +* Flush the work (i.e. run it if pending). This must be called +* under the wiphy mutex acquired by wiphy_lock(). +*/ +void wiphy_hrtimer_work_flush (struct wiphy *wiphy, +struct wiphy_hrtimer_work *hrwork); + +/** +* wiphy_hrtimer_work_pending - Find out whether a wiphy hrtimer +* work item is currently pending. +* +* @wiphy: the wiphy, for debug purposes +* @hrwork: the hrtimer work in question +* +* Return: true if timer is pending, false otherwise +* +* Please refer to the wiphy_delayed_work_pending() documentation as +* this is the equivalent function for hrtimer based delayed work +* items. +*/ +bool wiphy_hrtimer_work_pending (struct wiphy *wiphy, +struct wiphy_hrtimer_work *hrwork); +/** * enum ieee80211_ap_reg_power - regulatory power for an Access Point *
net/wireless/core.c +56 -0
62 lines not on this page · raw message
net/wireless/trace.h +21 -0
@@ -304,6 +304,27 @@ TRACE_EVENT(wiphy_delayed_work_queue, __entry->delay) ); +TRACE_EVENT (wiphy_hrtimer_work_queue, + TP_PROTO(struct wiphy *wiphy, struct wiphy_work *work, + ktime_t delay), +TP_ARGS (wiphy, work, delay), +TP_STRUCT__entry ( + WIPHY_ENTRY + __field(void *, instance) + __field(void *, func) +__field (ktime_t, delay) + ), +TP_fast_assign ( + WIPHY_ASSIGN; + __entry->instance = work; + __entry->func = work->func; + __entry->delay = delay; + ), +TP_printk (WIPHY_PR_FMT " instance=%p func=%pS delay=%llu" , +WIPHY_PR_ARG , __entry->instance, __entry->func, + __entry->delay) +); + TRACE_EVENT(wiphy_work_worker_start, TP_PROTO(struct wiphy *wiphy), TP_ARGS(wiphy),
Greg Kroah-Hartman
maintainerPATCH 161/185 wifi: mac80211: use wiphy_hrtimer_work for csa.switch_work
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Berg <[email protected]>
[ Upstream commit fbc1cc6973099f45e4c30b86f12b4435c7cb7d24 ]
The work item may be scheduled relatively far in the future. As the event happens at a specific point in time, the normal timer accuracy is not sufficient in that case.
Switch to use wiphy_hrtimer_work so that the accuracy is sufficient. To make this work, use the same clock to store the timestamp.
--- net/mac80211/chan.c | 2 +- net/mac80211/ieee80211_i.h | 4 ++-- net/mac80211/link.c | 4 ++-- net/mac80211/mlme.c | 18 +++++++++--------- 4 files changed, 14 insertions(+), 14 deletions(-)
net/mac80211/chan.c +1 -1
@@ -1246,7 +1246,7 @@ ieee80211_link_chanctx_reservation_compl &link->csa.finalize_work);break ;case NL80211_IFTYPE_STATION : -wiphy_delayed_work_queue (sdata->local->hw.wiphy, +wiphy_hrtimer_work_queue (sdata->local->hw.wiphy, &link->u.mgd.csa.switch_work,0 );break ;case NL80211_IFTYPE_UNSPECIFIED :
net/mac80211/ieee80211_i.h +2 -2
@@ -981,10 +981,10 @@ struct ieee80211_link_data_managed {bool operating_11g_mode;struct { -struct wiphy_delayed_work switch_work; +struct wiphy_hrtimer_work switch_work;struct cfg80211_chan_def ap_chandef;struct ieee80211_parsed_tpe tpe; -unsigned long time; +ktime_t time;bool waiting_bcn;bool ignored_same_chan;bool blocked_tx;
net/mac80211/link.c +2 -2
@@ -469,10 +469,10 @@ static int _ieee80211_set_active_links(s* from there. */ if (link->conf->csa_active) -wiphy_delayed_work_queue (local->hw.wiphy, +wiphy_hrtimer_work_queue (local->hw.wiphy, &link->u.mgd.csa.switch_work, link->u.mgd.csa.time - - jiffies); +ktime_get_boottime ()); }list_for_each_entry (sta, &local->sta_list, list) {
net/mac80211/mlme.c +9 -9
@@ -2225,7 +2225,7 @@ void ieee80211_chswitch_done(struct ieeereturn ; } -wiphy_delayed_work_queue (sdata->local->hw.wiphy, +wiphy_hrtimer_work_queue (sdata->local->hw.wiphy, &link->u.mgd.csa.switch_work,0 ); }
@@ -2384,7 +2384,8 @@ ieee80211_sta_process_chanswitch(struct .timestamp = timestamp, .device_timestamp = device_timestamp, }; -unsigned long now; +u32 csa_time_tu; +ktime_t now;int res;lockdep_assert_wiphy (local->hw.wiphy);
@@ -2614,10 +2615,9 @@ ieee80211_sta_process_chanswitch(struct csa_ie.mode);/* we may have to handle timeout for deactivated link in software */ - now = jiffies; - link->u.mgd.csa.time = now + -TU_TO_JIFFIES ((max_t (int, csa_ie.count,1 ) -1 ) * - link->conf->beacon_int); + now =ktime_get_boottime (); + csa_time_tu = (max_t (int, csa_ie.count,1 ) -1 ) * link->conf->beacon_int; + link->u.mgd.csa.time = now +ns_to_ktime (ieee80211_tu_to_usec (csa_time_tu) *NSEC_PER_USEC );if (ieee80211_vif_link_active (&sdata->vif, link->link_id) && local->ops->channel_switch) {
@@ -2632,7 +2632,7 @@ ieee80211_sta_process_chanswitch(struct }/* channel switch handled in software */ -wiphy_delayed_work_queue (local->hw.wiphy, +wiphy_hrtimer_work_queue (local->hw.wiphy, &link->u.mgd.csa.switch_work, link->u.mgd.csa.time - now);return ;
@@ -8137,7 +8137,7 @@ void ieee80211_mgd_setup_link(struct ieeelse link->u.mgd.req_smps =IEEE80211_SMPS_OFF ; -wiphy_delayed_work_init (&link->u.mgd.csa.switch_work, +wiphy_hrtimer_work_init (&link->u.mgd.csa.switch_work, ieee80211_csa_switch_work);ieee80211_clear_tpe (&link->conf->tpe);
@@ -9267,7 +9267,7 @@ void ieee80211_mgd_stop_link(struct ieee &link->u.mgd.request_smps_work);wiphy_work_cancel (link->sdata->local->hw.wiphy, &link->u.mgd.recalc_smps); -wiphy_delayed_work_cancel (link->sdata->local->hw.wiphy, +wiphy_hrtimer_work_cancel (link->sdata->local->hw.wiphy, &link->u.mgd.csa.switch_work); }
Greg Kroah-Hartman
maintainerPATCH 162/185 mm, percpu: do not consider sleepable allocations atomic
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Hocko <[email protected]>
[ Upstream commit 9a5b183941b52f84c0f9e5f27ce44e99318c9e0f ]
28307d938fb2 ("percpu: make pcpu_alloc() aware of current gfp context") has fixed a reclaim recursion for scoped GFP_NOFS context. It has done that by avoiding taking pcpu_alloc_mutex. This is a correct solution as the worker context with full GFP_KERNEL allocation/reclaim power and which is using the same lock cannot block the NOFS pcpu_alloc caller.
On the other hand this is a very conservative approach that could lead to failures because pcpu_alloc lockless implementation is quite limited.
We have a bug report about premature failures when scsi array of 193 devices is scanned. Sometimes (not consistently) the scanning aborts because the iscsid daemon fails to create the queue for a random scsi device during the scan. iscsid itself is running with PR_SET_IO_FLUSHER set so all allocations from this process context are GFP_NOIO. This in turn makes any pcpu_alloc lockless (without pcpu_alloc_mutex) which leads to pre-mature failures.
It has turned out that iscsid has worked around this by dropping PR_SET_IO_FLUSHER (https://github.com/open-iscsi/open-iscsi/pull/382) when scanning host. But we can do better in this case on the kernel side and use pcpu_alloc_mutex for NOIO resp. NOFS constrained allocation scopes too. We just need the WQ worker to never trigger IO/FS reclaim. Achieve that by enforcing scoped GFP_NOIO for the whole execution of pcpu_balance_workfn (this will imply NOFS constrain as well). This will remove the dependency chain and preserve the full allocation power of the pcpu_alloc call.
While at it make is_atomic really test for blockable allocations.
--- mm/percpu.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
mm/percpu.c +7 -1
@@ -1758,7 +1758,7 @@ void __percpu *pcpu_alloc_noprof(size_t gfp =current_gfp_context (gfp);/* whitelisted flags that can be passed to the backing allocators */ pcpu_gfp = gfp & (GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN); - is_atomic = (gfp &GFP_KERNEL ) !=GFP_KERNEL ; + is_atomic = !gfpflags_allow_blocking (gfp); do_warn = !(gfp & __GFP_NOWARN);/*
@@ -2203,7 +2203,12 @@ static void pcpu_balance_workfn(struct w* to grow other chunks. This then gives pcpu_reclaim_populated() time * to move fully free chunks to the active list to be freed if * appropriate. +* +* Enforce GFP_NOIO allocations because we have pcpu_alloc users +* constrained to GFP_NOIO/NOFS contexts and they could form lock +* dependency through pcpu_alloc_mutex */ +unsigned int flags =memalloc_noio_save ();mutex_lock (&pcpu_alloc_mutex);spin_lock_irq (&pcpu_lock);
@@ -2214,6 +2219,7 @@ static void pcpu_balance_workfn(struct wspin_unlock_irq (&pcpu_lock);mutex_unlock (&pcpu_alloc_mutex); +memalloc_noio_restore (flags); }/**
Greg Kroah-Hartman
maintainerPATCH 163/185 KVM: guest_memfd: Pass index, not gfn, to __kvm_gmem_get_pfn()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
[ Upstream commit 4af18dc6a9204464db76d9771d1f40e2b46bf6ae ]
Refactor guest_memfd usage of __kvm_gmem_get_pfn() to pass the index into the guest_memfd file instead of the gfn, i.e. resolve the index based on the slot+gfn in the caller instead of in __kvm_gmem_get_pfn(). This will allow kvm_gmem_get_pfn() to retrieve and return the specific "struct page", which requires the index into the folio, without a redoing the index calculation multiple times (which isn't costly, just hard to follow).
Opportunistically add a kvm_gmem_get_index() helper to make the copy+pasted code easier to understand.
Message-ID: <[email protected]>
Stable-dep-of: ae431059e75d ("KVM: guest_memfd: Remove bindings on memslot deletion when gmem is dying")
--- virt/kvm/guest_memfd.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
virt/kvm/guest_memfd.c +13 -7
@@ -304,6 +304,11 @@ static inline struct file *kvm_gmem_get_return get_file_active (&slot->gmem.file); } +static pgoff_t kvm_gmem_get_index (struct kvm_memory_slot *slot,gfn_t gfn) +{ +return gfn - slot->base_gfn + slot->gmem.pgoff; +} +static struct file_operations kvm_gmem_fops = { .open = generic_file_open, .release = kvm_gmem_release,
@@ -553,12 +558,11 @@ void kvm_gmem_unbind(struct kvm_memory_s }/* Returns a locked folio on success. */ -static struct folio * -__kvm_gmem_get_pfn (struct file *file,struct kvm_memory_slot *slot, -gfn_t gfn,kvm_pfn_t *pfn,bool *is_prepared, -int *max_order) +static struct folio *__kvm_gmem_get_pfn (struct file *file, +struct kvm_memory_slot *slot, +pgoff_t index,kvm_pfn_t *pfn, +bool *is_prepared,int *max_order) { -pgoff_t index = gfn - slot->base_gfn + slot->gmem.pgoff;struct kvm_gmem *gmem = file->private_data;struct folio *folio;
@@ -594,6 +598,7 @@ __kvm_gmem_get_pfn(struct file *file, stint kvm_gmem_get_pfn (struct kvm *kvm,struct kvm_memory_slot *slot,gfn_t gfn,kvm_pfn_t *pfn,int *max_order) { +pgoff_t index =kvm_gmem_get_index (slot, gfn);struct file *file =kvm_gmem_get_file (slot);struct folio *folio;bool is_prepared = false;
@@ -602,7 +607,7 @@ int kvm_gmem_get_pfn(struct kvm *kvm, stif (!file)return -EFAULT ; - folio =__kvm_gmem_get_pfn (file, slot, gfn, pfn, &is_prepared, max_order); + folio =__kvm_gmem_get_pfn (file, slot, index, pfn, &is_prepared, max_order);if (IS_ERR (folio)) { r =PTR_ERR (folio); goto out;
@@ -650,6 +655,7 @@ long kvm_gmem_populate(struct kvm *kvm,for (i =0 ; i < npages; i += (1 << max_order)) {struct folio *folio;gfn_t gfn = start_gfn + i; +pgoff_t index =kvm_gmem_get_index (slot, gfn);bool is_prepared = false;kvm_pfn_t pfn;
@@ -658,7 +664,7 @@ long kvm_gmem_populate(struct kvm *kvm,break ; } - folio =__kvm_gmem_get_pfn (file, slot, gfn, &pfn, &is_prepared, &max_order); + folio =__kvm_gmem_get_pfn (file, slot, index, &pfn, &is_prepared, &max_order);if (IS_ERR (folio)) { ret =PTR_ERR (folio);break ;
Greg Kroah-Hartman
maintainerPATCH 164/185 KVM: guest_memfd: Remove RCU-protected attribute from slot->gmem.file
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yan Zhao <[email protected]>
[ Upstream commit 67b43038ce14d6b0673bdffb2052d879065c94ae ]
Remove the RCU-protected attribute from slot->gmem.file. No need to use RCU primitives rcu_assign_pointer()/synchronize_rcu() to update this pointer.
- slot->gmem.file is updated in 3 places:
kvm_gmem_bind(), kvm_gmem_unbind(), kvm_gmem_release(). All of them are protected by kvm->slots_lock.
- slot->gmem.file is read in 2 paths:
(1) kvm_gmem_populate
kvm_gmem_get_file
__kvm_gmem_get_pfn (2) kvm_gmem_get_pfn
kvm_gmem_get_file
__kvm_gmem_get_pfn Path (1) kvm_gmem_populate() requires holding kvm->slots_lock, so slot->gmem.file is protected by the kvm->slots_lock in this path.
Path (2) kvm_gmem_get_pfn() does not require holding kvm->slots_lock. However, it's also not guarded by rcu_read_lock() and rcu_read_unlock(). So synchronize_rcu() in kvm_gmem_unbind()/kvm_gmem_release() actually will not wait for the readers in kvm_gmem_get_pfn() due to lack of RCU read-side critical section.
The path (2) kvm_gmem_get_pfn() is safe without RCU protection because:
a) kvm_gmem_bind() is called on a new memslot, before the memslot is visible to kvm_gmem_get_pfn().
b) kvm->srcu ensures that kvm_gmem_unbind() and freeing of a memslot occur after the memslot is no longer visible to kvm_gmem_get_pfn().
c) get_file_active() ensures that kvm_gmem_get_pfn() will not access the stale file if kvm_gmem_release() sets it to NULL. This is because if kvm_gmem_release() occurs before kvm_gmem_get_pfn(), get_file_active() will return NULL; if get_file_active() does not return NULL, kvm_gmem_release() should not occur until after kvm_gmem_get_pfn() releases the file reference.
Message-ID: <[email protected]>
Stable-dep-of: ae431059e75d ("KVM: guest_memfd: Remove bindings on memslot deletion when gmem is dying")
--- include/linux/kvm_host.h | 7 ++++++- virt/kvm/guest_memfd.c | 34 +++++++++++++++++++++------------- 2 files changed, 27 insertions(+), 14 deletions(-)
include/linux/kvm_host.h +6 -1
@@ -608,7 +608,12 @@ struct kvm_memory_slot {#ifdef CONFIG_KVM_PRIVATE_MEM struct { -struct file __rcu *file; +/* +* Writes protected by kvm->slots_lock. Acquiring a +* reference via kvm_gmem_get_file() is protected by +* either kvm->slots_lock or kvm->srcu. +*/ +struct file *file;pgoff_t pgoff; } gmem;#endif
virt/kvm/guest_memfd.c +21 -13
@@ -261,15 +261,19 @@ static int kvm_gmem_release(struct inode* dereferencing the slot for existing bindings needs to be protected * against memslot updates, specifically so that unbind doesn't race * and free the memslot (kvm_gmem_get_file() will return NULL). +* +* Since .release is called only when the reference count is zero, +* after which file_ref_get() and get_file_active() fail, +* kvm_gmem_get_pfn() cannot be using the file concurrently. +* file_ref_put() provides a full barrier, and get_file_active() the +* matching acquire barrier. */ mutex_lock (&kvm->slots_lock);filemap_invalidate_lock (inode->i_mapping);xa_for_each (&gmem->bindings, index, slot) -rcu_assign_pointer (slot->gmem.file,NULL ); - -synchronize_rcu (); +WRITE_ONCE (slot->gmem.file,NULL );/* * All in-flight operations are gone and new bindings can be created.
@@ -298,8 +302,7 @@ static inline struct file *kvm_gmem_get_/* * Do not return slot->gmem.file if it has already been closed; * there might be some time between the last fput() and when -* kvm_gmem_release() clears slot->gmem.file, and you do not -* want to spin in the meanwhile. +* kvm_gmem_release() clears slot->gmem.file. */ return get_file_active (&slot->gmem.file); }
@@ -510,11 +513,11 @@ int kvm_gmem_bind(struct kvm *kvm, struc }/* -* No synchronize_rcu() needed, any in-flight readers are guaranteed to -* be see either a NULL file or this new file, no need for them to go -* away. +* memslots of flag KVM_MEM_GUEST_MEMFD are immutable to change, so +* kvm_gmem_bind() must occur on a new memslot. Because the memslot +* is not visible yet, kvm_gmem_get_pfn() is guaranteed to see the file. */ -rcu_assign_pointer (slot->gmem.file, file); +WRITE_ONCE (slot->gmem.file, file); slot->gmem.pgoff = start;xa_store_range (&gmem->bindings, start, end -1 , slot,GFP_KERNEL );
@@ -550,8 +553,12 @@ void kvm_gmem_unbind(struct kvm_memory_sfilemap_invalidate_lock (file->f_mapping);xa_store_range (&gmem->bindings, start, end -1 ,NULL ,GFP_KERNEL ); -rcu_assign_pointer (slot->gmem.file,NULL ); -synchronize_rcu (); + +/* +* synchronize_srcu(&kvm->srcu) ensured that kvm_gmem_get_pfn() +* cannot see this memslot. +*/ +WRITE_ONCE (slot->gmem.file,NULL );filemap_invalidate_unlock (file->f_mapping);fput (file);
@@ -563,11 +570,12 @@ static struct folio *__kvm_gmem_get_pfn( pgoff_t index, kvm_pfn_t *pfn, bool *is_prepared, int *max_order) { + struct file *gmem_file = READ_ONCE(slot->gmem.file);struct kvm_gmem *gmem = file->private_data;struct folio *folio; -if (file != slot->gmem.file) { -WARN_ON_ONCE (slot->gmem.file); +if (file != gmem_file) { +WARN_ON_ONCE (gmem_file);return ERR_PTR (-EFAULT ); }
Greg Kroah-Hartman
maintainerPATCH 165/185 KVM: guest_memfd: Remove bindings on memslot deletion when gmem is dying
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
[ Upstream commit ae431059e75d36170a5ae6b44cc4d06d43613215 ]
When unbinding a memslot from a guest_memfd instance, remove the bindings even if the guest_memfd file is dying, i.e. even if its file refcount has gone to zero. If the memslot is freed before the file is fully released, nullifying the memslot side of the binding in kvm_gmem_release() will write to freed memory, as detected by syzbot+KASAN:
==================================================================
BUG: KASAN: slab-use-after-free in kvm_gmem_release+0x176/0x440 virt/kvm/guest_memfd.c:353 Write of size 8 at addr ffff88807befa508 by task syz.0.17/6022 CPU: 0 UID: 0 PID: 6022 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/02/2025 Call Trace: <TASK> dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:378 [inline] print_report+0xca/0x240 mm/kasan/report.c:482 kasan_report+0x118/0x150 mm/kasan/report.c:595 kvm_gmem_release+0x176/0x440 virt/kvm/guest_memfd.c:353 __fput+0x44c/0xa70 fs/file_table.c:468 task_work_run+0x1d4/0x260 kernel/task_work.c:227 resume_user_mode_work include/linux/resume_user_mode.h:50 [inline] exit_to_user_mode_loop+0xe9/0x130 kernel/entry/common.c:43 exit_to_user_mode_prepare include/linux/irq-entry-common.h:225 [inline] syscall_exit_to_user_mode_work include/linux/entry-common.h:175 [inline] syscall_exit_to_user_mode include/linux/entry-common.h:210 [inline] do_syscall_64+0x2bd/0xfa0 arch/x86/entry/syscall_64.c:100 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7fbeeff8efc9 </TASK> Allocated by task 6023: kasan_save_stack mm/kasan/common.c:56 [inline] kasan_save_track+0x3e/0x80 mm/kasan/common.c:77 poison_kmalloc_redzone mm/kasan/common.c:397 [inline] __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:414 kasan_kmalloc include/linux/kasan.h:262 [inline] __kmalloc_cache_noprof+0x3e2/0x700 mm/slub.c:5758 kmalloc_noprof include/linux/slab.h:957 [inline] kzalloc_noprof include/linux/slab.h:1094 [inline] kvm_set_memory_region+0x747/0xb90 virt/kvm/kvm_main.c:2104 kvm_vm_ioctl_set_memory_region+0x6f/0xd0 virt/kvm/kvm_main.c:2154 kvm_vm_ioctl+0x957/0xc60 virt/kvm/kvm_main.c:5201 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:597 [inline] __se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0xfa0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 6023: kasan_save_stack mm/kasan/common.c:56 [inline] kasan_save_track+0x3e/0x80 mm/kasan/common.c:77 kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:584 poison_slab_object mm/kasan/common.c:252 [inline] __kasan_slab_free+0x5c/0x80 mm/kasan/common.c:284 kasan_slab_free include/linux/kasan.h:234 [inline] slab_free_hook mm/slub.c:2533 [inline] slab_free mm/slub.c:6622 [inline] kfree+0x19a/0x6d0 mm/slub.c:6829 kvm_set_memory_region+0x9c4/0xb90 virt/kvm/kvm_main.c:2130 kvm_vm_ioctl_set_memory_region+0x6f/0xd0 virt/kvm/kvm_main.c:2154 kvm_vm_ioctl+0x957/0xc60 virt/kvm/kvm_main.c:5201 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:597 [inline] __se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0xfa0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f
Deliberately don't acquire filemap invalid lock when the file is dying as the lifecycle of f_mapping is outside the purview of KVM. Dereferencing the mapping is *probably* fine, but there's no need to invalidate anything as memslot deletion is responsible for zapping SPTEs, and the only code that can access the dying file is kvm_gmem_release(), whose core code is mutually exclusive with unbinding.
Note, the mutual exclusivity is also what makes it safe to access the bindings on a dying gmem instance. Unbinding either runs with slots_lock held, or after the last reference to the owning "struct kvm" is put, and kvm_gmem_release() nullifies the slot pointer under slots_lock, and puts its reference to the VM after that is done.
--- virt/kvm/guest_memfd.c | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-)
virt/kvm/guest_memfd.c +32 -13
@@ -534,31 +534,50 @@ err:return r; } -void kvm_gmem_unbind (struct kvm_memory_slot *slot) +static void __kvm_gmem_unbind (struct kvm_memory_slot *slot,struct kvm_gmem *gmem) {unsigned long start = slot->gmem.pgoff;unsigned long end = start + slot->npages; -struct kvm_gmem *gmem; + +xa_store_range (&gmem->bindings, start, end -1 ,NULL ,GFP_KERNEL ); + +/* +* synchronize_srcu(&kvm->srcu) ensured that kvm_gmem_get_pfn() +* cannot see this memslot. +*/ +WRITE_ONCE (slot->gmem.file,NULL ); +} + +void kvm_gmem_unbind (struct kvm_memory_slot *slot) +{struct file *file;/* -* Nothing to do if the underlying file was already closed (or is being -* closed right now), kvm_gmem_release() invalidates all bindings. +* Nothing to do if the underlying file was _already_ closed, as +* kvm_gmem_release() invalidates and nullifies all bindings. */ - file =kvm_gmem_get_file (slot); -if (!file) +if (!slot->gmem.file)return ; - gmem = file->private_data; - -filemap_invalidate_lock (file->f_mapping); -xa_store_range (&gmem->bindings, start, end -1 ,NULL ,GFP_KERNEL ); + file =kvm_gmem_get_file (slot);/* -* synchronize_srcu(&kvm->srcu) ensured that kvm_gmem_get_pfn() -* cannot see this memslot. +* However, if the file is _being_ closed, then the bindings need to be +* removed as kvm_gmem_release() might not run until after the memslot +* is freed. Note, modifying the bindings is safe even though the file +* is dying as kvm_gmem_release() nullifies slot->gmem.file under +* slots_lock, and only puts its reference to KVM after destroying all +* bindings. I.e. reaching this point means kvm_gmem_release() hasn't +* yet destroyed the bindings or freed the gmem_file, and can't do so +* until the caller drops slots_lock. */ -WRITE_ONCE (slot->gmem.file,NULL ); +if (!file) { +__kvm_gmem_unbind (slot, slot->gmem.file->private_data); +return ; + } + +filemap_invalidate_lock (file->f_mapping); +__kvm_gmem_unbind (slot, file->private_data);filemap_invalidate_unlock (file->f_mapping);fput (file);
Greg Kroah-Hartman
maintainerPATCH 166/185 net: netpoll: Individualize the skb pool
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
[ Upstream commit 221a9c1df790fa711d65daf5ba05d0addc279153 ]
The current implementation of the netpoll system uses a global skb pool, which can lead to inefficient memory usage and waste when targets are disabled or no longer in use.
This can result in a significant amount of memory being unnecessarily allocated and retained, potentially causing performance issues and limiting the availability of resources for other system components.
Modify the netpoll system to assign a skb pool to each target instead of using a global one.
This approach allows for more fine-grained control over memory allocation and deallocation, ensuring that resources are only allocated and retained as needed.
Stable-dep-of: 49c8d2c1f94c ("net: netpoll: fix incorrect refcount handling causing incorrect cleanup")
--- include/linux/netpoll.h | 1 + net/core/netpoll.c | 31 +++++++++++++------------------ 2 files changed, 14 insertions(+), 18 deletions(-)
include/linux/netpoll.h +1 -0
@@ -32,6 +32,7 @@ struct netpoll {bool ipv6;u16 local_port, remote_port;u8 remote_mac[ETH_ALEN ]; +struct sk_buff_head skb_pool; };struct netpoll_info {
net/core/netpoll.c +13 -18
@@ -45,9 +45,6 @@#define MAX_UDP_CHUNK 1460#define MAX_SKBS 32 - -static struct sk_buff_head skb_pool; -#define USEC_PER_POLL 50#define MAX_SKB_SIZE \
@@ -234,20 +231,23 @@ void netpoll_poll_enable(struct net_deviup (&ni->dev_lock); } -static void refill_skbs (void ) +static void refill_skbs (struct netpoll *np) { +struct sk_buff_head *skb_pool;struct sk_buff *skb;unsigned long flags; -spin_lock_irqsave (&skb_pool.lock, flags); -while (skb_pool.qlen <MAX_SKBS ) { + skb_pool = &np->skb_pool; + +spin_lock_irqsave (&skb_pool->lock, flags); +while (skb_pool->qlen <MAX_SKBS ) { skb =alloc_skb (MAX_SKB_SIZE ,GFP_ATOMIC );if (!skb)break ; -__skb_queue_tail (&skb_pool, skb); +__skb_queue_tail (skb_pool, skb); } -spin_unlock_irqrestore (&skb_pool.lock, flags); +spin_unlock_irqrestore (&skb_pool->lock, flags); }static void zap_completion_queue (void )
@@ -284,12 +284,12 @@ static struct sk_buff *find_skb(struct nstruct sk_buff *skb;zap_completion_queue (); -refill_skbs (); +refill_skbs (np); repeat: skb =alloc_skb (len,GFP_ATOMIC );if (!skb) - skb =skb_dequeue (&skb_pool); + skb =skb_dequeue (&np->skb_pool);if (!skb) {if (++count <10 ) {
@@ -678,6 +678,8 @@ int netpoll_setup(struct netpoll *np)struct in_device *in_dev;int err; +skb_queue_head_init (&np->skb_pool); +rtnl_lock ();if (np->dev_name[0 ]) {struct net *net = current->nsproxy->net_ns;
@@ -778,7 +780,7 @@ put_noaddr: }/* fill up the skb queue */ -refill_skbs (); +refill_skbs (np); err =__netpoll_setup (np, ndev);if (err)
@@ -804,13 +806,6 @@ unlock: }EXPORT_SYMBOL (netpoll_setup); -static int __init netpoll_init (void ) -{ -skb_queue_head_init (&skb_pool); -return 0 ; -} -core_initcall (netpoll_init); -static void rcu_cleanup_netpoll_info (struct rcu_head *rcu_head) { struct netpoll_info *npinfo =
Greg Kroah-Hartman
maintainerPATCH 167/185 net: netpoll: flush skb pool during cleanup
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
[ Upstream commit 6c59f16f1770481a6ee684720ec55b1e38b3a4b2 ]
The netpoll subsystem maintains a pool of 32 pre-allocated SKBs per instance, but these SKBs are not freed when the netpoll user is brought down. This leads to memory waste as these buffers remain allocated but unused.
Add skb_pool_flush() to properly clean up these SKBs when netconsole is terminated, improving memory efficiency.
Stable-dep-of: 49c8d2c1f94c ("net: netpoll: fix incorrect refcount handling causing incorrect cleanup")
--- net/core/netpoll.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
net/core/netpoll.c +13 -1
@@ -536,6 +536,14 @@ static int netpoll_parse_ip_addr(const creturn -1 ; } +static void skb_pool_flush (struct netpoll *np) +{ +struct sk_buff_head *skb_pool; + + skb_pool = &np->skb_pool; +skb_queue_purge_reason (skb_pool,SKB_CONSUMED ); +} +int netpoll_parse_options (struct netpoll *np,char *opt) {char *cur=opt, *delim;
@@ -784,7 +792,7 @@ put_noaddr: err =__netpoll_setup (np, ndev);if (err) - goto put; + goto flush;rtnl_unlock ();/* Make sure all NAPI polls which started before dev->npinfo
@@ -795,6 +803,8 @@ put_noaddr:return 0 ; +flush: +skb_pool_flush (np); put:DEBUG_NET_WARN_ON_ONCE (np->dev);if (ip_overwritten)
@@ -842,6 +852,8 @@ void __netpoll_cleanup(struct netpoll *ncall_rcu (&npinfo->rcu, rcu_cleanup_netpoll_info); }else RCU_INIT_POINTER (np->dev->npinfo,NULL ); + +skb_pool_flush (np); }EXPORT_SYMBOL_GPL (__netpoll_cleanup);
Greg Kroah-Hartman
maintainerPATCH 168/185 net: netpoll: fix incorrect refcount handling causing incorrect cleanup
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
[ Upstream commit 49c8d2c1f94cc2f4d1a108530d7ba52614b874c2 ]
commit efa95b01da18 ("netpoll: fix use after free") incorrectly ignored the refcount and prematurely set dev->npinfo to NULL during netpoll cleanup, leading to improper behavior and memory leaks.
Scenario causing lack of proper cleanup:
1) A netpoll is associated with a NIC (e.g., eth0) and netdev->npinfo is allocated, and refcnt = 1
- Keep in mind that npinfo is shared among all netpoll instances. In this case, there is just one.
2) Another netpoll is also associated with the same NIC and npinfo->refcnt += 1.
- Now dev->npinfo->refcnt = 2;
- There is just one npinfo associated to the netdev.
3) When the first netpolls goes to clean up:
- The first cleanup succeeds and clears np->dev->npinfo, ignoring refcnt.
- It basically calls RCU_INIT_POINTER(np->dev->npinfo, NULL);
- Set dev->npinfo = NULL, without proper cleanup
- No ->ndo_netpoll_cleanup() is either called
4) Now the second target tries to clean up
- The second cleanup fails because np->dev->npinfo is already NULL.
* In this case, ops->ndo_netpoll_cleanup() was never called, and the skb pool is not cleaned as well (for the second netpoll instance)
- This leaks npinfo and skbpool skbs, which is clearly reported by kmemleak.
Revert commit efa95b01da18 ("netpoll: fix use after free") and adds clarifying comments emphasizing that npinfo cleanup should only happen once the refcount reaches zero, ensuring stable and correct netpoll behavior.
--- net/core/netpoll.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
net/core/netpoll.c +5 -2
@@ -841,6 +841,10 @@ void __netpoll_cleanup(struct netpoll *nif (!npinfo)return ; +/* At this point, there is a single npinfo instance per netdevice, and +* its refcnt tracks how many netpoll structures are linked to it. We +* only perform npinfo cleanup when the refcnt decrements to zero. +*/ if (refcount_dec_and_test (&npinfo->refcnt)) {const struct net_device_ops *ops;
@@ -850,8 +854,7 @@ void __netpoll_cleanup(struct netpoll *nRCU_INIT_POINTER (np->dev->npinfo,NULL );call_rcu (&npinfo->rcu, rcu_cleanup_netpoll_info); - }else -RCU_INIT_POINTER (np->dev->npinfo,NULL ); + }skb_pool_flush (np); }
Greg Kroah-Hartman
maintainerPATCH 169/185 KVM: VMX: Split out guts of EPT violation to common/exposed function
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
[ Upstream commit c8563d1b69988ef9b6803508e1c95f2aea0a171d ]
The difference of TDX EPT violation is how to retrieve information, GPA, and exit qualification. To share the code to handle EPT violation, split out the guts of EPT violation handler so that VMX/TDX exit handler can call it after retrieving GPA and exit qualification.
Message-ID: <[email protected]>
Stable-dep-of: d0164c161923 ("KVM: VMX: Fix check for valid GVA on an EPT violation")
--- arch/x86/kvm/vmx/common.h | 34 ++++++++++++++++++++++++++++++++++ arch/x86/kvm/vmx/vmx.c | 25 +++---------------------- 2 files changed, 37 insertions(+), 22 deletions(-) create mode 100644 arch/x86/kvm/vmx/common.h
arch/x86/kvm/vmx/common.h new file +34 -0
@@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __KVM_X86_VMX_COMMON_H +#define __KVM_X86_VMX_COMMON_H + +#include <linux/kvm_host.h> + +#include "mmu.h" + +static inline int __vmx_handle_ept_violation (struct kvm_vcpu *vcpu,gpa_t gpa, +unsigned long exit_qualification) +{ +u64 error_code; + +/* Is it a read fault? */ + error_code = (exit_qualification &EPT_VIOLATION_ACC_READ ) + ?PFERR_USER_MASK :0 ; +/* Is it a write fault? */ + error_code |= (exit_qualification &EPT_VIOLATION_ACC_WRITE ) + ?PFERR_WRITE_MASK :0 ; +/* Is it a fetch fault? */ + error_code |= (exit_qualification &EPT_VIOLATION_ACC_INSTR ) + ?PFERR_FETCH_MASK :0 ; +/* ept page table entry is present? */ + error_code |= (exit_qualification &EPT_VIOLATION_RWX_MASK ) + ?PFERR_PRESENT_MASK :0 ; + +if (error_code &EPT_VIOLATION_GVA_IS_VALID ) + error_code |= (exit_qualification &EPT_VIOLATION_GVA_TRANSLATED ) ? +PFERR_GUEST_FINAL_MASK :PFERR_GUEST_PAGE_MASK ; + +return kvm_mmu_page_fault (vcpu, gpa, error_code,NULL ,0 ); +} + +#endif /* __KVM_X86_VMX_COMMON_H */
arch/x86/kvm/vmx/vmx.c +3 -22
@@ -53,6 +53,7 @@#include <trace/events/ipi.h> #include "capabilities.h" +#include "common.h" #include "cpuid.h" #include "hyperv.h" #include "kvm_onhyperv.h"
@@ -5777,11 +5778,8 @@ static int handle_task_switch(struct kvmstatic int handle_ept_violation (struct kvm_vcpu *vcpu) { -unsigned long exit_qualification; +unsigned long exit_qualification =vmx_get_exit_qual (vcpu);gpa_t gpa; -u64 error_code; - - exit_qualification =vmx_get_exit_qual (vcpu);/* * EPT violation happened while executing iret from NMI,
@@ -5797,23 +5795,6 @@ static int handle_ept_violation(struct k gpa =vmcs_read64 (GUEST_PHYSICAL_ADDRESS );trace_kvm_page_fault (vcpu, gpa, exit_qualification); -/* Is it a read fault? */ - error_code = (exit_qualification &EPT_VIOLATION_ACC_READ ) - ?PFERR_USER_MASK :0 ; -/* Is it a write fault? */ - error_code |= (exit_qualification &EPT_VIOLATION_ACC_WRITE ) - ?PFERR_WRITE_MASK :0 ; -/* Is it a fetch fault? */ - error_code |= (exit_qualification &EPT_VIOLATION_ACC_INSTR ) - ?PFERR_FETCH_MASK :0 ; -/* ept page table entry is present? */ - error_code |= (exit_qualification &EPT_VIOLATION_RWX_MASK ) - ?PFERR_PRESENT_MASK :0 ; - -if (error_code &EPT_VIOLATION_GVA_IS_VALID ) - error_code |= (exit_qualification &EPT_VIOLATION_GVA_TRANSLATED ) ? -PFERR_GUEST_FINAL_MASK :PFERR_GUEST_PAGE_MASK ; -/* * Check that the GPA doesn't exceed physical memory limits, as that is * a guest page fault. We have to emulate the instruction here, because
@@ -5825,7 +5806,7 @@ static int handle_ept_violation(struct kif (unlikely (allow_smaller_maxphyaddr && !kvm_vcpu_is_legal_gpa (vcpu, gpa)))return kvm_emulate_instruction (vcpu,0 ); -return kvm_mmu_page_fault (vcpu, gpa, error_code,NULL ,0 ); +return __vmx_handle_ept_violation (vcpu, gpa, exit_qualification); }static int handle_ept_misconfig (struct kvm_vcpu *vcpu)
Greg Kroah-Hartman
maintainerPATCH 170/185 KVM: VMX: Fix check for valid GVA on an EPT violation
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sukrit Bhatnagar <[email protected]>
[ Upstream commit d0164c161923ac303bd843e04ebe95cfd03c6e19 ]
On an EPT violation, bit 7 of the exit qualification is set if the guest linear-address is valid. The derived page fault error code should not be checked for this bit.
--- arch/x86/kvm/vmx/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/vmx/common.h +1 -1
@@ -24,7 +24,7 @@ static inline int __vmx_handle_ept_viola error_code |= (exit_qualification &EPT_VIOLATION_RWX_MASK ) ?PFERR_PRESENT_MASK :0 ; -if (error_code &EPT_VIOLATION_GVA_IS_VALID ) +if (exit_qualification &EPT_VIOLATION_GVA_IS_VALID ) error_code |= (exit_qualification &EPT_VIOLATION_GVA_TRANSLATED ) ?PFERR_GUEST_FINAL_MASK :PFERR_GUEST_PAGE_MASK ;
Greg Kroah-Hartman
maintainerPATCH 171/185 ALSA: hda: Fix missing pointer check in hda_component_manager_init function
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Denis Arefev <[email protected]>
[ Upstream commit 1cf11d80db5df805b538c942269e05a65bcaf5bc ]
The __component_match_add function may assign the 'matchptr' pointer the value ERR_PTR(-ENOMEM), which will subsequently be dereferenced.
The call stack leading to the error looks like this:
hda_component_manager_init
|-> component_match_add
|-> component_match_add_release
|-> __component_match_add ( ... ,**matchptr, ... )
|-> *matchptr = ERR_PTR(-ENOMEM); // assign
|-> component_master_add_with_match( ... match)
|-> component_match_realloc(match, match->num); // dereferenceAdd IS_ERR() check to prevent the crash.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
[ Modified the source code path due to 6.12 doesn't have commit:6014e9021b28 ("ALSA: hda: Move codec drivers into sound/hda/codecs directory ") ]
--- sound/pci/hda/hda_component.c | 4 ++++ 1 file changed, 4 insertions(+)
sound/pci/hda/hda_component.c +4 -0
@@ -181,6 +181,10 @@ int hda_component_manager_init(struct hd sm->match_str = match_str; sm->index = i;component_match_add (dev, &match, hda_comp_match_dev_name, sm); +if (IS_ERR (match)) { +codec_err (cdc,"Fail to add component %ld\n" ,PTR_ERR (match)); +return PTR_ERR (match); + } } ret =component_master_add_with_match (dev, ops, match);
Greg Kroah-Hartman
maintainerPATCH 172/185 io_uring/napi: fix io_napi_entry RCU accesses
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Olivier Langlois <[email protected]>
[Upstream commit 45b3941d09d13b3503309be1f023b83deaf69b4d ]
correct 3 RCU structures modifications that were not using the RCU functions to make their update.
--- io_uring/napi.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-)
io_uring/napi.c +12 -7
@@ -81,19 +81,24 @@ void __io_napi_add(struct io_ring_ctx *c }hlist_add_tail_rcu (&e->node, hash_list); -list_add_tail (&e->list, &ctx->napi_list); +list_add_tail_rcu (&e->list, &ctx->napi_list);spin_unlock (&ctx->napi_lock); }static void __io_napi_remove_stale (struct io_ring_ctx *ctx) {struct io_napi_entry *e; -unsigned int i;spin_lock (&ctx->napi_lock); -hash_for_each (ctx->napi_ht, i, e, node) { -if (time_after (jiffies, e->timeout)) { -list_del (&e->list); +/* +* list_for_each_entry_safe() is not required as long as: +* 1. list_del_rcu() does not reset the deleted node next pointer +* 2. kfree_rcu() delays the memory freeing until the next quiescent +* state +*/ +list_for_each_entry (e, &ctx->napi_list, list) { +if (time_after (jiffies,READ_ONCE (e->timeout))) { +list_del_rcu (&e->list);hash_del_rcu (&e->node);kfree_rcu (e, rcu); }
@@ -204,13 +209,13 @@ void io_napi_init(struct io_ring_ctx *ctvoid io_napi_free (struct io_ring_ctx *ctx) {struct io_napi_entry *e; -unsigned int i;spin_lock (&ctx->napi_lock); -hash_for_each (ctx->napi_ht, i, e, node) { +list_for_each_entry (e, &ctx->napi_list, list) {hash_del_rcu (&e->node);kfree_rcu (e, rcu); } +INIT_LIST_HEAD_RCU (&ctx->napi_list);spin_unlock (&ctx->napi_lock); }
Greg Kroah-Hartman
maintainerPATCH 173/185 rust: kbuild: treat `build_error` and `rustdoc` as kernel objects
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
[ Upstream commit 16c43a56b79e2c3220b043236369a129d508c65a ]
Even if normally build_error isn't a kernel object, it should still be treated as such so that we pass the same flags. Similarly, rustdoc targets are never kernel objects, but we need to treat them as such.
Otherwise, starting with Rust 1.91.0 (released 2025-10-30), rustc will complain about missing sanitizer flags since -Zsanitizer is a target modifier too [1]:
error: mixing -Zsanitizer will cause an ABI mismatch in crate build_error
--> rust/build_error.rs:3:1
|
3 | //! Build-time error.
| ^
|
= help: the -Zsanitizer flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely = note: unset -Zsanitizer in this crate is incompatible with -Zsanitizer=kernel-address in dependency core
= help: set -Zsanitizer=kernel-address in this crate or unset -Zsanitizer in core
= help: if you are sure this will not cause problems, you may use -Cunsafe-allow-abi-mismatch=sanitizer to silence this error
Thus explicitly mark them as kernel objects.
--- rust/Makefile | 10 ++++++++++ 1 file changed, 10 insertions(+)
rust/Makefile +10 -0
@@ -107,12 +107,18 @@ rustdoc-core: private rustc_target_flags rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs rustdoc-clean FORCE +$(call if_changed,rustdoc) +# Even if `rustdoc` targets are not kernel objects, they should still be +# treated as such so that we pass the same flags. Otherwise, for instance, +# `rustdoc` will complain about missing sanitizer flags causing an ABI mismatch. +rustdoc-compiler_builtins: private is-kernel-object := y rustdoc-compiler_builtins: $(src)/compiler_builtins.rs rustdoc-core FORCE +$(call if_changed,rustdoc) +rustdoc-ffi: private is-kernel-object := y rustdoc-ffi: $(src)/ffi.rs rustdoc-core FORCE +$(call if_changed,rustdoc) +rustdoc-kernel: private is-kernel-object := y rustdoc-kernel: private rustc_target_flags = --extern ffi \ --extern build_error --extern macros=$(objtree)/$(obj)/libmacros.so \ --extern bindings --extern uapi
@@ -433,6 +439,10 @@ $(obj)/compiler_builtins.o: private rust $(obj)/compiler_builtins.o: $(src)/compiler_builtins.rs $(obj)/core.o FORCE +$(call if_changed_rule,rustc_library) +# Even if normally `build_error` is not a kernel object, it should still be +# treated as such so that we pass the same flags. Otherwise, for instance, +# `rustc` will complain about missing sanitizer flags causing an ABI mismatch. +$(obj)/build_error.o: private is-kernel-object := y $(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FORCE +$(call if_changed_rule,rustc_library)
Greg Kroah-Hartman
maintainerPATCH 174/185 rust: kbuild: workaround `rustdoc` doctests modifier bug
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
[ Upstream commit fad472efab0a805dd939f017c5b8669a786a4bcf ]
The rustdoc modifiers bug [1] was fixed in Rust 1.90.0 [2], for which we added a workaround in commit abbf9a449441 ("rust: workaround rustdoc target modifiers bug").
However, rustdoc's doctest generation still has a similar issue [3], being fixed at [4], which does not affect us because we apply the workaround to both, and now, starting with Rust 1.91.0 (released 2025-10-30), -Zsanitizer is a target modifier too [5], which means we fail with:
RUSTDOC TK rust/kernel/lib.rs
error: mixing -Zsanitizer will cause an ABI mismatch in crate kernel
--> rust/kernel/lib.rs:3:1
|
3 | //! The kernel crate.
| ^
|
= help: the -Zsanitizer flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely = note: unset -Zsanitizer in this crate is incompatible with -Zsanitizer=kernel-address in dependency core
= help: set -Zsanitizer=kernel-address in this crate or unset -Zsanitizer in core
= help: if you are sure this will not cause problems, you may use -Cunsafe-allow-abi-mismatch=sanitizer to silence this error
A simple way around is to add the sanitizer to the list in the existing workaround (especially if we had not started to pass the sanitizer flags in the previous commit, since in that case that would not be necessary). However, that still applies the workaround in more cases than necessary.
Instead, only modify the doctests flags to ignore the check for sanitizers, so that it is more local (and thus the compiler keeps checking it for us in the normal rustdoc calls). Since the previous commit already treated the rustdoc calls as kernel objects, this should allow us in the future to easily remove this workaround when the time comes.
By the way, the -Cunsafe-allow-abi-mismatch flag overwrites previous ones rather than appending, so it needs to be all done in the same flag. Moreover, unknown modifiers are rejected, and thus we have to gate based on the version too.
Finally, -Zsanitizer-cfi-normalize-integers is not affected (in Rust 1.91.0), so it is not needed in the workaround for the moment.
--- rust/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
rust/Makefile +3 -1
@@ -59,6 +59,8 @@ core-edition := $(if $(call rustc-min-ve # the time being (https://github.com/rust-lang/rust/issues/144521). rustdoc_modifiers_workaround := $(if $(call rustc-min-version,108800),-Cunsafe-allow-abi-mismatch=fixed-x18) +# Similarly, for doctests (https://github.com/rust-lang/rust/issues/146465). +doctests_modifiers_workaround := $(rustdoc_modifiers_workaround)$(if $(call rustc-min-version,109100),$(comma)sanitizer) quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $< cmd_rustdoc = \ OBJTREE=$(abspath $(objtree)) \
@@ -189,7 +191,7 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC --extern bindings --extern uapi \ --no-run --crate-name kernel -Zunstable-options \ --sysroot=/dev/null \ - $(rustdoc_modifiers_workaround) \ + $(doctests_modifiers_workaround) \ --test-builder $(objtree)/scripts/rustdoc_test_builder \ $< $(rustdoc_test_kernel_quiet); \ $(objtree)/scripts/rustdoc_test_gen
Greg Kroah-Hartman
maintainerPATCH 175/185 uio_hv_generic: Set event for all channels on the device
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Long Li <[email protected]>
commit d062463edf1770427dc2d637df4088df4835aa47 upstream.
Hyper-V may offer a non latency sensitive device with subchannels without monitor bit enabled. The decision is entirely on the Hyper-V host not configurable within guest.
When a device has subchannels, also signal events for the subchannel if its monitor bit is disabled.
This patch also removes the memory barrier when monitor bit is enabled as it is not necessary. The memory barrier is only needed between setting up interrupt mask and calling vmbus_set_event() when monitor bit is disabled.
--- drivers/uio/uio_hv_generic.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-)
drivers/uio/uio_hv_generic.c +26 -6
@@ -65,6 +65,16 @@ struct hv_uio_private_data {char send_name[32 ]; }; +static void set_event (struct vmbus_channel *channel,s32 irq_state) +{ + channel->inbound.ring_buffer->interrupt_mask = !irq_state; +if (!channel->offermsg.monitor_allocated && irq_state) { +/* MB is needed for host to see the interrupt mask first */ +virt_mb (); +vmbus_set_event (channel); + } +} +/* * This is the irqcontrol callback to be registered to uio_info. * It can be used to disable/enable interrupt from user space processes.
@@ -79,12 +89,15 @@ hv_uio_irqcontrol(struct uio_info *info, {struct hv_uio_private_data *pdata = info->priv;struct hv_device *dev = pdata->device; +struct vmbus_channel *primary, *sc; - dev->channel->inbound.ring_buffer->interrupt_mask = !irq_state; -virt_mb (); + primary = dev->channel; +set_event (primary, irq_state); -if (!dev->channel->offermsg.monitor_allocated && irq_state) -vmbus_setevent (dev->channel); +mutex_lock (&vmbus_connection.channel_mutex); +list_for_each_entry (sc, &primary->sc_list, sc_list) +set_event (sc, irq_state); +mutex_unlock (&vmbus_connection.channel_mutex);return 0 ; }
@@ -95,11 +108,18 @@ hv_uio_irqcontrol(struct uio_info *info,static void hv_uio_channel_cb (void *context) {struct vmbus_channel *chan = context; -struct hv_device *hv_dev = chan->device_obj; -struct hv_uio_private_data *pdata =hv_get_drvdata (hv_dev); +struct hv_device *hv_dev; +struct hv_uio_private_data *pdata;virt_mb (); +/* +* The callback may come from a subchannel, in which case look +* for the hv device in the primary channel +*/ + hv_dev = chan->primary_channel ? + chan->primary_channel->device_obj : chan->device_obj; + pdata =hv_get_drvdata (hv_dev);uio_event_notify (&pdata->info); }
Greg Kroah-Hartman
maintainerPATCH 176/185 mm/memory: do not populate page table entries beyond i_size
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kiryl Shutsemau <[email protected]>
commit 74207de2ba10c2973334906822dc94d2e859ffc5 upstream.
Patch series "Fix SIGBUS semantics with large folios", v3.
Accessing memory within a VMA, but beyond i_size rounded up to the next page size, is supposed to generate SIGBUS.
Darrick reported[1] an xfstests regression in v6.18-rc1. generic/749 failed due to missing SIGBUS. This was caused by my recent changes that try to fault in the whole folio where possible:
19773df031bc ("mm/fault: try to map the entire file folio in finish_fault()") 357b92761d94 ("mm/filemap: map entire large folio faultaround")
These changes did not consider i_size when setting up PTEs, leading to xfstest breakage.
However, the problem has been present in the kernel for a long time - since huge tmpfs was introduced in 2016. The kernel happily maps PMD-sized folios as PMD without checking i_size. And huge=always tmpfs allocates PMD-size folios on any writes.
I considered this corner case when I implemented a large tmpfs, and my conclusion was that no one in their right mind should rely on receiving a SIGBUS signal when accessing beyond i_size. I cannot imagine how it could be useful for the workload.
But apparently filesystem folks care a lot about preserving strict SIGBUS semantics.
Generic/749 was introduced last year with reference to POSIX, but no real workloads were mentioned. It also acknowledged the tmpfs deviation from the test case.
POSIX indeed says[3]:
References within the address range starting at pa and continuing for len bytes to whole pages following the end of an object shall result in delivery of a SIGBUS signal.
The patchset fixes the regression introduced by recent changes as well as more subtle SIGBUS breakage due to split failure on truncation.
This patch (of 2):
Accesses within VMA, but beyond i_size rounded up to PAGE_SIZE are supposed to generate SIGBUS.
Recent changes attempted to fault in full folio where possible. They did not respect i_size, which led to populating PTEs beyond i_size and breaking SIGBUS semantics.
Darrick reported generic/749 breakage because of this.
However, the problem existed before the recent changes. With huge=always tmpfs, any write to a file leads to PMD-size allocation. Following the fault-in of the folio will install PMD mapping regardless of i_size.
Fix filemap_map_pages() and finish_fault() to not install:
- PTEs beyond i_size;
- PMD mappings across i_size;
Make an exception for shmem/tmpfs that for long time intentionally mapped with PMDs across i_size.
--- mm/filemap.c | 20 +++++++++++++++----- mm/memory.c | 23 +++++++++++++++++++++-- 2 files changed, 36 insertions(+), 7 deletions(-)
mm/filemap.c +15 -5
@@ -3653,13 +3653,27 @@ vm_fault_t filemap_map_pages(struct vm_fvm_fault_t ret =0 ;unsigned long rss =0 ;unsigned int nr_pages =0 , mmap_miss =0 , mmap_miss_saved, folio_type; +bool can_map_large;rcu_read_lock (); folio =next_uptodate_folio (&xas, mapping, end_pgoff);if (!folio) goto out; -if (filemap_map_pmd (vmf, folio, start_pgoff)) { + file_end =DIV_ROUND_UP (i_size_read (mapping->host),PAGE_SIZE ) -1 ; + end_pgoff =min (end_pgoff, file_end); + +/* +* Do not allow to map with PTEs beyond i_size and with PMD +* across i_size to preserve SIGBUS semantics. +* +* Make an exception for shmem/tmpfs that for long time +* intentionally mapped with PMDs across i_size. +*/ + can_map_large =shmem_mapping (mapping) || + file_end >=folio_next_index (folio); + +if (can_map_large &&filemap_map_pmd (vmf, folio, start_pgoff)) { ret =VM_FAULT_NOPAGE ; goto out; }
@@ -3672,10 +3686,6 @@ vm_fault_t filemap_map_pages(struct vm_f goto out; } - file_end =DIV_ROUND_UP (i_size_read (mapping->host),PAGE_SIZE ) -1 ; -if (end_pgoff > file_end) - end_pgoff = file_end; - folio_type =mm_counter_file (folio); do { unsigned long end;
mm/memory.c +21 -2
@@ -68,6 +68,7 @@#include <linux/gfp.h> #include <linux/migrate.h> #include <linux/string.h> +#include <linux/shmem_fs.h> #include <linux/memory-tiers.h> #include <linux/debugfs.h> #include <linux/userfaultfd_k.h>
@@ -5088,6 +5089,8 @@ fallback:else page = vmf->page; + folio =page_folio (page); +/* * check even for read faults because we might have lost our CoWed * page
@@ -5098,8 +5101,25 @@ fallback:return ret; } +if (!needs_fallback && vma->vm_file) { +struct address_space *mapping = vma->vm_file->f_mapping; +pgoff_t file_end; + + file_end =DIV_ROUND_UP (i_size_read (mapping->host),PAGE_SIZE ); + +/* +* Do not allow to map with PTEs beyond i_size and with PMD +* across i_size to preserve SIGBUS semantics. +* +* Make an exception for shmem/tmpfs that for long time +* intentionally mapped with PMDs across i_size. +*/ + needs_fallback = !shmem_mapping (mapping) && + file_end <folio_next_index (folio); + } +if (pmd_none (*vmf->pmd)) { -if (PageTransCompound (page)) { +if (!needs_fallback &&PageTransCompound (page)) { ret =do_set_pmd (vmf, page);if (ret !=VM_FAULT_FALLBACK )return ret;
@@ -5111,7 +5131,6 @@ fallback:return VM_FAULT_OOM ; } - folio =page_folio (page); nr_pages =folio_nr_pages (folio);/*
Greg Kroah-Hartman
maintainerPATCH 177/185 mm/truncate: unmap large folio on split failure
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kiryl Shutsemau <[email protected]>
commit fa04f5b60fda62c98a53a60de3a1e763f11feb41 upstream.
Accesses within VMA, but beyond i_size rounded up to PAGE_SIZE are supposed to generate SIGBUS.
This behavior might not be respected on truncation.
During truncation, the kernel splits a large folio in order to reclaim memory. As a side effect, it unmaps the folio and destroys PMD mappings of the folio. The folio will be refaulted as PTEs and SIGBUS semantics are preserved.
However, if the split fails, PMD mappings are preserved and the user will not receive SIGBUS on any accesses within the PMD.
Unmap the folio on split failure. It will lead to refault as PTEs and preserve SIGBUS semantics.
Make an exception for shmem/tmpfs that for long time intentionally mapped with PMDs across i_size.
--- mm/truncate.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
mm/truncate.c +26 -1
@@ -179,6 +179,31 @@ int truncate_inode_folio(struct address_return 0 ; } +static int try_folio_split_or_unmap (struct folio *folio) +{ +enum ttu_flags ttu_flags = +TTU_SYNC | +TTU_SPLIT_HUGE_PMD | +TTU_IGNORE_MLOCK ; +int ret; + + ret =split_folio (folio); + +/* +* If the split fails, unmap the folio, so it will be refaulted +* with PTEs to respect SIGBUS semantics. +* +* Make an exception for shmem/tmpfs that for long time +* intentionally mapped with PMDs across i_size. +*/ +if (ret && !shmem_mapping (folio->mapping)) { +try_to_unmap (folio, ttu_flags); +WARN_ON (folio_mapped (folio)); + } + +return ret; +} +/* * Handle partial folios. The folio may be entirely within the * range if a split has raced with us. If not, we zero the part of the
@@ -223,7 +248,7 @@ bool truncate_inode_partial_folio(structfolio_invalidate (folio, offset, length);if (!folio_test_large (folio))return true; -if (split_folio (folio) ==0 ) +if (try_folio_split_or_unmap (folio) ==0 )return true;if (folio_test_dirty (folio))return false;
Greg Kroah-Hartman
maintainerPATCH 178/185 mm/secretmem: fix use-after-free race in fault handler
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lance Yang <[email protected]>
commit 6f86d0534fddfbd08687fa0f01479d4226bc3c3d upstream.
When a page fault occurs in a secret memory file created with memfd_secret(2), the kernel will allocate a new folio for it, mark the underlying page as not-present in the direct map, and add it to the file mapping.
If two tasks cause a fault in the same page concurrently, both could end up allocating a folio and removing the page from the direct map, but only one would succeed in adding the folio to the file mapping. The task that failed undoes the effects of its attempt by (a) freeing the folio again and (b) putting the page back into the direct map. However, by doing these two operations in this order, the page becomes available to the allocator again before it is placed back in the direct mapping.
If another task attempts to allocate the page between (a) and (b), and the kernel tries to access it via the direct map, it would result in a supervisor not-present page fault.
Fix the ordering to restore the direct map before the folio is freed.
--- mm/secretmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/secretmem.c +1 -1
@@ -84,13 +84,13 @@ retry:__folio_mark_uptodate (folio); err =filemap_add_folio (mapping, folio, offset, gfp);if (unlikely (err)) { -folio_put (folio);/* * If a split of large page was required, it * already happened when we marked the page invalid * which guarantees that this call won't fail */ set_direct_map_default_noflush (page); +folio_put (folio);if (err == -EEXIST ) goto retry;
Greg Kroah-Hartman
maintainerPATCH 179/185 mm/huge_memory: do not change split_huge_page*() target order silently
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zi Yan <[email protected]>
commit 77008e1b2ef73249bceb078a321a3ff6bc087afb upstream.
Page cache folios from a file system that support large block size (LBS) can have minimal folio order greater than 0, thus a high order folio might not be able to be split down to order-0. Commit e220917fa507 ("mm: split a folio in minimum folio order chunks") bumps the target order of split_huge_page*() to the minimum allowed order when splitting a LBS folio. This causes confusion for some split_huge_page*() callers like memory failure handling code, since they expect after-split folios all have order-0 when split succeeds but in reality get min_order_for_split() order folios and give warnings.
Fix it by failing a split if the folio cannot be split to the target order. Rename try_folio_split() to try_folio_split_to_order() to reflect the added new_order parameter. Remove its unused list parameter.
[The test poisons LBS folios, which cannot be split to order-0 folios, and also tries to poison all memory. The non split LBS folios take more memory than the test anticipated, leading to OOM. The patch fixed the kernel warning and the test needs some change to avoid OOM.]
--- include/linux/huge_mm.h | 21 +++++++-------------- mm/huge_memory.c | 7 +------ 2 files changed, 8 insertions(+), 20 deletions(-)
include/linux/huge_mm.h +7 -14
@@ -353,20 +353,7 @@ int min_order_for_split(struct folio *foint split_folio_to_list (struct folio *folio,struct list_head *list);static inline int split_huge_page (struct page *page) { -struct folio *folio =page_folio (page); -int ret =min_order_for_split (folio); - -if (ret <0 ) -return ret; - -/* -* split_huge_page() locks the page before splitting and -* expects the same page that has been split to be locked when -* returned. split_folio(page_folio(page)) cannot be used here -* because it converts the page to folio and passes the head -* page to be split. -*/ -return split_huge_page_to_list_to_order (page,NULL , ret); +return split_huge_page_to_list_to_order (page,NULL ,0 ); }void deferred_split_folio (struct folio *folio,bool partially_mapped);
@@ -538,6 +525,12 @@ static inline int split_huge_page(structreturn 0 ; } +static inline int min_order_for_split (struct folio *folio) +{ +VM_WARN_ON_ONCE_FOLIO (1 , folio); +return -EINVAL ; +} +static inline int split_folio_to_list (struct folio *folio,struct list_head *list) {return 0 ;
mm/huge_memory.c +1 -6
@@ -3597,12 +3597,7 @@ int min_order_for_split(struct folio *foint split_folio_to_list (struct folio *folio,struct list_head *list) { -int ret =min_order_for_split (folio); - -if (ret <0 ) -return ret; - -return split_huge_page_to_list_to_order (&folio->page, list, ret); +return split_huge_page_to_list_to_order (&folio->page, list,0 ); }/*
Greg Kroah-Hartman
maintainerPATCH 180/185 mm/huge_memory: preserve PG_has_hwpoisoned if a folio is split to >0 order
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zi Yan <[email protected]>
commit fa5a061700364bc28ee1cb1095372f8033645dcb upstream.
folio split clears PG_has_hwpoisoned, but the flag should be preserved in after-split folios containing pages with PG_hwpoisoned flag if the folio is split to >0 order folios. Scan all pages in a to-be-split folio to determine which after-split folios need the flag.
An alternatives is to change PG_has_hwpoisoned to PG_maybe_hwpoisoned to avoid the scan and set it on all after-split folios, but resulting false positive has undesirable negative impact. To remove false positive, caller of folio_test_has_hwpoisoned() and folio_contain_hwpoisoned_page() needs to do the scan. That might be causing a hassle for current and future callers and more costly than doing the scan in the split code. More details are discussed in [1].
This issue can be exposed via:
1. splitting a has_hwpoisoned folio to >0 order from debugfs interface;
2. truncating part of a has_hwpoisoned folio in truncate_inode_partial_folio().
And later accesses to a hwpoisoned page could be possible due to the missing has_hwpoisoned folio flag. This will lead to MCE errors.
--- mm/huge_memory.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-)
mm/huge_memory.c +23 -2
@@ -3091,9 +3091,17 @@ static void lru_add_page_tail(struct fol } } +static bool page_range_has_hwpoisoned (struct page *page,long nr_pages) +{ +for (; nr_pages; page++, nr_pages--) +if (PageHWPoison (page)) +return true; +return false; +} +static void __split_huge_page_tail (struct folio *folio,int tail,struct lruvec *lruvec,struct list_head *list, -unsigned int new_order) +unsigned int new_order,const bool handle_hwpoison) {struct page *head = &folio->page;struct page *page_tail = head + tail;
@@ -3170,6 +3178,11 @@ static void __split_huge_page_tail(strucfolio_set_large_rmappable (new_folio); } +/* Set has_hwpoisoned flag on new_folio if any of its pages is HWPoison */ +if (handle_hwpoison && +page_range_has_hwpoisoned (page_tail,1 << new_order)) +folio_set_has_hwpoisoned (new_folio); +/* Finally unfreeze refcount. Additional reference from page cache. */ page_ref_unfreeze(page_tail, 1 + ((!folio_test_anon(folio) || folio_test_swapcache(folio)) ?
@@ -3194,6 +3207,8 @@ static void __split_huge_page(struct pag pgoff_t end, unsigned int new_order) { struct folio *folio = page_folio(page); +/* Scan poisoned pages when split a poisoned folio to large folios */ +const bool handle_hwpoison =folio_test_has_hwpoisoned (folio) && new_order;struct page *head = &folio->page;struct lruvec *lruvec;struct address_space *swap_cache =NULL ;
@@ -3217,8 +3232,14 @@ static void __split_huge_page(struct pagClearPageHasHWPoisoned (head); +/* Check first new_nr pages since the loop below skips them */ +if (handle_hwpoison && +page_range_has_hwpoisoned (folio_page (folio,0 ), new_nr)) +folio_set_has_hwpoisoned (folio); +for (i = nr - new_nr; i >= new_nr; i -= new_nr) { -__split_huge_page_tail (folio, i, lruvec, list, new_order); +__split_huge_page_tail (folio, i, lruvec, list, new_order, + handle_hwpoison);/* Some pages can be beyond EOF: drop them from page cache */ if (head[i].index >= end) {struct folio *tail =page_folio (head + i);
Greg Kroah-Hartman
maintainerPATCH 181/185 isdn: mISDN: hfcsusb: fix memory leak in hfcsusb_probe()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abdun Nihaal <[email protected]>
commit 3f978e3f1570155a1327ffa25f60968bc7b9398f upstream.
In hfcsusb_probe(), the memory allocated for ctrl_urb gets leaked when setup_instance() fails with an error code. Fix that by freeing the urb before freeing the hw structure. Also change the error paths to use the goto ladder style.
Compile tested only. Issue found using a prototype static analysis tool.
--- drivers/isdn/hardware/mISDN/hfcsusb.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
drivers/isdn/hardware/mISDN/hfcsusb.c +13 -5
@@ -1904,13 +1904,13 @@ out:mISDN_freebchannel (&hw->bch[1 ]);mISDN_freebchannel (&hw->bch[0 ]);mISDN_freedchannel (&hw->dch); -kfree (hw);return err; }static int hfcsusb_probe (struct usb_interface *intf,const struct usb_device_id *id) { +int err;struct hfcsusb *hw;struct usb_device *dev =interface_to_usbdev (intf);struct usb_host_interface *iface = intf->cur_altsetting;
@@ -2101,20 +2101,28 @@ hfcsusb_probe(struct usb_interface *intfif (!hw->ctrl_urb) {pr_warn ("%s: No memory for control urb\n" , driver_info->vend_name); -kfree (hw); -return -ENOMEM ; + err = -ENOMEM ; + goto err_free_hw; }pr_info ("%s: %s: detected \"%s\" (%s, if=%d alt=%d)\n" , hw->name, __func__, driver_info->vend_name, conf_str[small_match], ifnum, alt_used); -if (setup_instance (hw, dev->dev.parent)) -return -EIO ; +if (setup_instance (hw, dev->dev.parent)) { + err = -EIO ; + goto err_free_urb; + } hw->intf = intf;usb_set_intfdata (hw->intf, hw);return 0 ; + +err_free_urb: +usb_free_urb (hw->ctrl_urb); +err_free_hw: +kfree (hw); +return err; }/* function called when an active device is removed */
Greg Kroah-Hartman
maintainerPATCH 182/185 net: phy: micrel: Fix lan8814_config_init
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Horatiu Vultur <[email protected]>
commit bf91f4bc9c1dfba75e457e6a5f11e3cda658729a upstream.
The blamed commit introduced the function lanphy_modify_page_reg which as name suggests it, it modifies the registers. In the same commit we have started to use this function inside the drivers. The problem is that in the function lan8814_config_init we passed the wrong page number when disabling the aneg towards host side. We passed extended page number 4(LAN8814_PAGE_COMMON_REGS) instead of extended page 5(LAN8814_PAGE_PORT_REGS)
--- drivers/net/phy/micrel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/phy/micrel.c +1 -1
@@ -4085,7 +4085,7 @@ static int lan8814_config_init(struct phstruct kszphy_priv *lan8814 = phydev->priv;/* Disable ANEG with QSGMII PCS Host side */ -lanphy_modify_page_reg (phydev,LAN8814_PAGE_COMMON_REGS , +lanphy_modify_page_reg (phydev,LAN8814_PAGE_PORT_REGS ,LAN8814_QSGMII_PCS1G_ANEG_CONFIG ,LAN8814_QSGMII_PCS1G_ANEG_CONFIG_ANEG_ENA ,0 );
Greg Kroah-Hartman
maintainerPATCH 183/185 net: netpoll: ensure skb_pool list is always initialized
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Sperbeck <[email protected]>
commit f0d0277796db613c124206544b6dbe95b520ab6c upstream.
When __netpoll_setup() is called directly, instead of through netpoll_setup(), the np->skb_pool list head isn't initialized. If skb_pool_flush() is later called, then we hit a NULL pointer in skb_queue_purge_reason(). This can be seen with this repro, when CONFIG_NETCONSOLE is enabled as a module:
ip tuntap add mode tap tap0
ip link add name br0 type bridge
ip link set dev tap0 master br0
modprobe netconsole [email protected]/br0,[email protected]/ rmmod netconsole
The backtrace is:
BUG: kernel NULL pointer dereference, address: 0000000000000008
#PF: supervisor write access in kernel mode
#PF: error_code(0x0002) - not-present page
... ... ...
Call Trace:
<TASK>
__netpoll_free+0xa5/0xf0
br_netpoll_cleanup+0x43/0x50 [bridge]
do_netpoll_cleanup+0x43/0xc0
netconsole_netdev_event+0x1e3/0x300 [netconsole]
unregister_netdevice_notifier+0xd9/0x150
cleanup_module+0x45/0x920 [netconsole]
__se_sys_delete_module+0x205/0x290
do_syscall_64+0x70/0x150
entry_SYSCALL_64_after_hwframe+0x76/0x7eMove the skb_pool list setup and initial skb fill into __netpoll_setup().
--- net/core/netpoll.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
net/core/netpoll.c +5 -5
@@ -632,6 +632,8 @@ int __netpoll_setup(struct netpoll *np,const struct net_device_ops *ops;int err; +skb_queue_head_init (&np->skb_pool); +if (ndev->priv_flags &IFF_DISABLE_NETPOLL ) {np_err (np,"%s doesn't support polling, aborting\n" , ndev->name);
@@ -667,6 +669,9 @@ int __netpoll_setup(struct netpoll *np,strscpy (np->dev_name, ndev->name,IFNAMSIZ ); npinfo->netpoll = np; +/* fill up the skb queue */ +refill_skbs (np); +/* last thing to do is link it to the net device structure */ rcu_assign_pointer (ndev->npinfo, npinfo);
@@ -686,8 +691,6 @@ int netpoll_setup(struct netpoll *np)struct in_device *in_dev;int err; -skb_queue_head_init (&np->skb_pool); -rtnl_lock ();if (np->dev_name[0 ]) {struct net *net = current->nsproxy->net_ns;
@@ -787,9 +790,6 @@ put_noaddr: } } -/* fill up the skb queue */ -refill_skbs (np); - err =__netpoll_setup (np, ndev);if (err) goto flush;
Greg Kroah-Hartman
maintainerPATCH 184/185 proc: proc_maps_open allow proc_mem_open to return NULL
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jialin Wang <[email protected]>
commit c0e1b774f68bdbea1618e356e30672c7f1e32509 upstream.
The commit 65c66047259f ("proc: fix the issue of proc_mem_open returning NULL") caused proc_maps_open() to return -ESRCH when proc_mem_open() returns NULL. This breaks legitimate /proc/<pid>/maps access for kernel threads since kernel threads have NULL mm_struct.
The regression causes perf to fail and exit when profiling a kernel thread:
# perf record -v -g -p $(pgrep kswapd0) ... couldn't open /proc/65/task/65/maps
This patch partially reverts the commit to fix it.
--- fs/proc/task_mmu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/proc/task_mmu.c +2 -2
@@ -212,8 +212,8 @@ static int proc_maps_open(struct inode * priv->inode = inode; priv->mm =proc_mem_open (inode,PTRACE_MODE_READ ); -if (IS_ERR_OR_NULL (priv->mm)) { -int err = priv->mm ?PTR_ERR (priv->mm) : -ESRCH ; +if (IS_ERR (priv->mm)) { +int err =PTR_ERR (priv->mm);seq_release_private (inode, file);return err;
Greg Kroah-Hartman
maintainerPATCH 185/185 Bluetooth: MGMT: fix crash in set_mesh_sync and set_mesh_complete
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pauli Virtanen <[email protected]>
commit e8785404de06a69d89dcdd1e9a0b6ea42dc6d327 upstream.
There is a BUG: KASAN: stack-out-of-bounds in set_mesh_sync due to memcpy from badly declared on-stack flexible array.
Another crash is in set_mesh_complete() due to double list_del via mgmt_pending_valid + mgmt_pending_remove.
Use DEFINE_FLEX to declare the flexible array right, and don't memcpy outside bounds.
As mgmt_pending_valid removes the cmd from list, use mgmt_pending_free, and also report status on error.
--- include/net/bluetooth/mgmt.h | 2 +- net/bluetooth/mgmt.c | 26 +++++++++++++++----------- 2 files changed, 16 insertions(+), 12 deletions(-)
include/net/bluetooth/mgmt.h +1 -1
@@ -847,7 +847,7 @@ struct mgmt_cp_set_mesh {__le16 window;__le16 period;__u8 num_ad_types; -__u8 ad_types[]; + __u8 ad_types[] __counted_by(num_ad_types); } __packed;#define MGMT_SET_MESH_RECEIVER_SIZE 6
net/bluetooth/mgmt.c +15 -11
@@ -2170,19 +2170,24 @@ static void set_mesh_complete(struct hci sk = cmd->sk;if (status) { +mgmt_cmd_status (cmd->sk, hdev->id,MGMT_OP_SET_MESH_RECEIVER , + status);mgmt_pending_foreach (MGMT_OP_SET_MESH_RECEIVER , hdev, true, cmd_status_rsp, &status); -return ; + goto done; } -mgmt_pending_remove (cmd);mgmt_cmd_complete (sk, hdev->id,MGMT_OP_SET_MESH_RECEIVER ,0 ,NULL ,0 ); + +done: +mgmt_pending_free (cmd); }static int set_mesh_sync (struct hci_dev *hdev,void *data) {struct mgmt_pending_cmd *cmd = data; -struct mgmt_cp_set_mesh cp; + DEFINE_FLEX(struct mgmt_cp_set_mesh, cp, ad_types, num_ad_types, + sizeof(hdev->mesh_ad_types));size_t len;mutex_lock (&hdev->mgmt_pending_lock);
@@ -2192,27 +2197,26 @@ static int set_mesh_sync(struct hci_devreturn -ECANCELED ; } -memcpy (&cp, cmd->param,sizeof (cp)); + len = cmd->param_len; +memcpy (cp, cmd->param,min (__struct_size (cp), len));mutex_unlock (&hdev->mgmt_pending_lock); - len = cmd->param_len; -memset (hdev->mesh_ad_types,0 ,sizeof (hdev->mesh_ad_types)); -if (cp.enable) +if (cp->enable)hci_dev_set_flag (hdev,HCI_MESH );else hci_dev_clear_flag (hdev,HCI_MESH ); - hdev->le_scan_interval =__le16_to_cpu (cp.period); - hdev->le_scan_window =__le16_to_cpu (cp.window); + hdev->le_scan_interval =__le16_to_cpu (cp->period); + hdev->le_scan_window =__le16_to_cpu (cp->window); - len -=sizeof (cp); + len -=sizeof (struct mgmt_cp_set_mesh );/* If filters don't fit, forward all adv pkts */ if (len <=sizeof (hdev->mesh_ad_types)) -memcpy (hdev->mesh_ad_types, cp.ad_types, len); +memcpy (hdev->mesh_ad_types, cp->ad_types, len);hci_update_passive_scan_sync (hdev);return 0 ;
Hi!
Quoted 4 lines
This is the start of the stable review cycle for the 6.12.59 release. There are 185 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.
I have successful test result, but I am not sure it matches the release. Please quote git hashes to make this easier.
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/pipelines/2170546623
Linux 6.12.59-rc1 (bba98f3faf27)
Passed
cip-ci created pipeline for commit eac30293  19 hours ago, finished 18 hours ago
Best regards,
Pavel
Signature · 2 lines
In cooperation with DENX Software Engineering GmbH, HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.12.59 release. There are 185 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 23 Nov 2025 13:01:08 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.12.59-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.12.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v6.12:
10 builds: 10 pass, 0 fail
28 boots: 28 pass, 0 fail
120 tests: 120 pass, 0 failLinux version: 6.12.59-rc1-g92f6b4140c17
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra186-p3509-0000+p3636-0001, tegra194-p2972-0000,
tegra194-p3509-0000+p3668-0000, tegra20-ventana,
tegra210-p2371-2180, tegra210-p3450-0000,
tegra30-cardhu-a04Jon
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.12.59 release. There are 185 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 23 Nov 2025 13:01:08 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.12.59-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.12.y
and the diffstat can be found below.thanks,
greg k-h
Builds successfully. Boots and works on qemu and Dell XPS 15 9520 w/ Intel Core i7-12600H
Thanks,
Brett
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.12.59 release. There are 185 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 23 Nov 2025 13:01:08 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.12.59-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.12.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Signature · 1 line
Florian
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.12.59 release. There are 185 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 23 Nov 2025 13:01:08 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.12.59-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.12.y
and the diffstat can be found below.thanks,
greg k-h
The LTP syscalls listmount04 failures noticed across the 6.18.0-rc6, Linux next-20251120, stable-rc 6.17.9-rc1, 6.17.9-rc2 and 6.12.59-rc1.
First seen on 6.12.59-rc1
Good: v6.12.56
Bad: 6.12.59-rc1
Regression Analysis:
- New regression? yes
- Reproducibility? yes
Test regression: listmount04.c:128: TFAIL: invalid mnt_id_req.spare expected EINVAL: EBADF (9)
## Test log,
<8>[ 467.451816] <LAVA_SIGNAL_STARTTC listmount04>
tst_buffers.c:57: TINFO: Test is using guarded buffers tst_test.c:2021: TINFO: LTP version: 20250930
tst_test.c:2024: TINFO: Tested kernel: 6.17.9-rc1 #1 SMP PREEMPT @1763732790 aarch64
tst_kconfig.c:88: TINFO: Parsing kernel config '/proc/config.gz' tst_kconfig.c:676: TINFO: CONFIG_TRACE_IRQFLAGS kernel option detected which might slow the execution
tst_test.c:1842: TINFO: Overall timeout per run is 0h 21m 36s listmount04.c:128: TPASS: request points to unaccessible memory : EFAULT (14) listmount04.c:128: TPASS: mnt_ids points to unaccessible memory : EFAULT (14) listmount04.c:128: TPASS: invalid flags : EINVAL (22) listmount04.c:128: TPASS: insufficient mnt_id_req.size : EINVAL (22) listmount04.c:128: TFAIL: invalid mnt_id_req.spare expected EINVAL: EBADF (9) listmount04.c:128: TPASS: invalid mnt_id_req.param : EINVAL (22) listmount04.c:128: TPASS: invalid mnt_id_req.mnt_id : EINVAL (22) listmount04.c:128: TPASS: non-existant mnt_id : ENOENT (2)
Summary:
passed 7 failed 1 broken 0 skipped 0
warnings 0
## Build
* kernel: 6.12.59-rc1
* git: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
* git commit: 92f6b4140c17182e28e19312fce7c6ee90cd3077
* git describe: v6.12.56-790-g92f6b4140c17
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.12.y/build/v6.12.56-790-g92f6b4140c17
## Test
* Test details:
https://regressions.linaro.org/lkft/linux-stable-rc-linux-6.12.y/v6.12.56-790-g92f6b4140c17/ltp-syscalls/listmount04/
* Test log: https://lkft.validation.linaro.org/scheduler/job/8532397#L26259
* Test plan: https://tuxapi.tuxsuite.com/v1/groups/linaro/projects/lkft/tests/35n4IGltUEJH9dNtMu47XsPdqo4
* Build link: https://storage.tuxsuite.com/public/linaro/lkft/builds/35n4GHe84Of9RjprzsxRkq6NEho/
* Kernel config:
https://storage.tuxsuite.com/public/linaro/lkft/builds/35n4GHe84Of9RjprzsxRkq6NEho/config
--
Linaro LKFT
https://lkft.linaro.org
Greg Kroah-Hartman
maintainerQuoted 17 lines · Naresh Kamboju
Quoted 15 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.12.59 release. There are 185 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 23 Nov 2025 13:01:08 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.12.59-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.12.y
and the diffstat can be found below.
Quoted 5 lines
Quoted 3 lines
thanks,
greg k-h
The LTP syscalls listmount04 failures noticed across the 6.18.0-rc6,
So this is upstream, has it been bisected and reported there?
thanks,
greg k-h
# Librecast Test Results
020/020 [ OK ] liblcrq
010/010 [ OK ] libmld
120/120 [ OK ] liblibrecast
CPU/kernel: Linux auntie 6.12.59-rc1-g92f6b4140c17 #131 SMP PREEMPT_DYNAMIC Sat Nov 22 05:46:45 -00 2025 x86_64 AMD Ryzen 9 9950X 16-Core Processor AuthenticAMD GNU/Linux
Hi!
Quoted 4 lines
This is the start of the stable review cycle for the 6.12.59 release. There are 185 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
CIP testing did not find any problems here:
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-6.12.y
Best regards,
Pavel
Signature · 2 lines
In cooperation with DENX Software Engineering GmbH, HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Am 21.11.2025 um 14:10 schrieb Greg Kroah-Hartman:
Quoted 4 lines
This is the start of the stable review cycle for the 6.12.59 release. There are 185 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.
Builds, boots and works on my 2-socket Ivy Bridge Xeon E5-2697 v2 server. No dmesg oddities or regressions found.
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]
hello
Compiled and booted 6.12.59-rc1+
No new regressions from dmesg.
As per dmidecode command.
Version: AMD Ryzen 3 3250U with Radeon Graphics
Processor Information
Socket Designation: FP5
Type: Central Processor
Family: Zen
Manufacturer: Advanced Micro Devices, Inc.
ID: 81 0F 81 00 FF FB 8B 17
Signature: Family 23, Model 24, Stepping 1
--
software engineer
rajagiri school of engineering and technology
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.12.59 release. There are 185 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 23 Nov 2025 13:01:08 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.12.59-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.12.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Quoted 8 lines · On Fri, 21 Nov 2025 14:10:27 +0100 Greg Kroah-Hartman…
This is the start of the stable review cycle for the 6.12.59 release. There are 185 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 23 Nov 2025 13:01:08 +0000. Anything received after that time might be too late.
Boot-tested under QEMU for Rust x86_64, arm64 and riscv64; built-tested for loongarch64:
Thanks!
Cheers,
Miguel
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.12.59 release. There are 185 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.
I'm seeing the same regression Naresh is in LTP listmount04, bisected to
[c5d44c8b2ed1fd6761bf9157d2c5b887a4dc78cf] fs/namespace: correctly handle errors returned by grab_requested_mnt_ns
# bad: [92f6b4140c17182e28e19312fce7c6ee90cd3077] Linux 6.12.59-rc1
# good: [7475d784169c7df48b0c55525fb862e06674d63c] Linux 6.12.58
git bisect start '92f6b4140c17182e28e19312fce7c6ee90cd3077' '7475d784169c7df48b0c55525fb862e06674d63c'
# test job: [92f6b4140c17182e28e19312fce7c6ee90cd3077] https://lava.sirena.org.uk/scheduler/job/2121934 # bad: [92f6b4140c17182e28e19312fce7c6ee90cd3077] Linux 6.12.59-rc1 git bisect bad 92f6b4140c17182e28e19312fce7c6ee90cd3077 # test job: [c16418189c97fd90c46b3b00d7d7224711d49e42] https://lava.sirena.org.uk/scheduler/job/2123608 # good: [c16418189c97fd90c46b3b00d7d7224711d49e42] mtd: onenand: Pass correct pointer to IRQ handler git bisect good c16418189c97fd90c46b3b00d7d7224711d49e42 # test job: [9c7df79d445495aeb1ea7fae6bd5e6beb5a86ea2] https://lava.sirena.org.uk/scheduler/job/2124517 # bad: [9c7df79d445495aeb1ea7fae6bd5e6beb5a86ea2] LoongArch: Use physical addresses for CSR_MERRENTRY/CSR_TLBRENTRY git bisect bad 9c7df79d445495aeb1ea7fae6bd5e6beb5a86ea2 # test job: [4e681269759ae153055fbcffeadd611a7b15df84] https://lava.sirena.org.uk/scheduler/job/2124890 # bad: [4e681269759ae153055fbcffeadd611a7b15df84] strparser: Fix signed/unsigned mismatch bug git bisect bad 4e681269759ae153055fbcffeadd611a7b15df84 # test job: [fb4fd3fb2f254aa4ce76f70e3f3a2e1fa5dd9031] https://lava.sirena.org.uk/scheduler/job/2125058 # bad: [fb4fd3fb2f254aa4ce76f70e3f3a2e1fa5dd9031] HID: playstation: Fix memory leak in dualshock4_get_calibration_data() git bisect bad fb4fd3fb2f254aa4ce76f70e3f3a2e1fa5dd9031 # test job: [ec7a798f14ae4058e88ebe088e89ded5fe17e312] https://lava.sirena.org.uk/scheduler/job/2125258 # bad: [ec7a798f14ae4058e88ebe088e89ded5fe17e312] netfilter: nf_tables: reject duplicate device on updates git bisect bad ec7a798f14ae4058e88ebe088e89ded5fe17e312 # test job: [c5d44c8b2ed1fd6761bf9157d2c5b887a4dc78cf] https://lava.sirena.org.uk/scheduler/job/2125373 # bad: [c5d44c8b2ed1fd6761bf9157d2c5b887a4dc78cf] fs/namespace: correctly handle errors returned by grab_requested_mnt_ns git bisect bad c5d44c8b2ed1fd6761bf9157d2c5b887a4dc78cf # test job: [652ab7b107fd7121b28113d0e3ba63b7821ee36e] https://lava.sirena.org.uk/scheduler/job/2125457 # good: [652ab7b107fd7121b28113d0e3ba63b7821ee36e] virtio-fs: fix incorrect check for fsvq->kobj git bisect good 652ab7b107fd7121b28113d0e3ba63b7821ee36e # first bad commit: [c5d44c8b2ed1fd6761bf9157d2c5b887a4dc78cf] fs/namespace: correctly handle errors returned by grab_requested_mnt_ns
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.12.59 release. There are 185 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.
Takashi Iwai <[email protected]>
ALSA: usb-audio: Fix potential overflow of PCM transfer buffer
This one is wrong for at least 6.12 and older.
+ if (ep->packsize[1] > ep->maxpacksize) {
+ usb_audio_dbg(chip, "Too small maxpacksize %u for rate %u / pps %u\n",
+ ep->maxpacksize, ep->cur_rate, ep->pps);
+ return -EINVAL;
+ }
Needs to be err = -EINVAL; goto unlock;.
(Or cherry pick guard() handling from newer kernels).
Best regards,
Pavel
Signature · 2 lines
In cooperation with DENX Software Engineering GmbH, HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Quoted 19 lines · Pavel Machek
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.12.59 release. There are 185 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.
Takashi Iwai <[email protected]>
ALSA: usb-audio: Fix potential overflow of PCM transfer bufferThis one is wrong for at least 6.12 and older.
(quoted diff) +5
-0+ if (ep->packsize[1] > ep->maxpacksize) { + usb_audio_dbg(chip, "Too small maxpacksize %u for rate %u / pps %u\n", + ep->maxpacksize, ep->cur_rate, ep->pps); + return -EINVAL; + }
Quoted 3 lines
Needs to be err =
-EINVAL; goto unlock;.(Or cherry pick
guard()handling from newer kernels).
Thanks Pavel, a good catch!
A cherry-pick of the commit efea7a57370b for converting to guard() doesn't seem to be cleanly applicable on 6.12.y, unfortunately. So I guess it'd be easier to have a correction on the top instead, something like below.
Takashi
-- 8< --
From: Takashi Iwai <[email protected]>
Subject: [PATCH v6.12.y] ALSA: usb-audio: Fix missing unlock at error path of
maxpacksize check
The recent backport of the upstream commit 05a1fc5efdd8 ("ALSA:
usb-audio: Fix potential overflow of PCM transfer buffer") on the older stable kernels like 6.12.y was broken since it doesn't consider the mutex unlock, where the upstream code manages with guard(). In the older code, we still need an explicit unlock.
This is a fix that corrects the error path, applied only on old stable trees.
--- sound/usb/endpoint.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
sound/usb/endpoint.c +2 -1
@@ -1389,7 +1389,8 @@ int snd_usb_endpoint_set_params(struct snd_usb_audio *chip,if (ep->packsize[1 ] > ep->maxpacksize) {usb_audio_dbg (chip,"Too small maxpacksize %u for rate %u / pps %u\n" , ep->maxpacksize, ep->cur_rate, ep->pps); -return -EINVAL ; + err = -EINVAL ; + goto unlock; }/* calculate the frequency in 16.16 format */
Signature · 1 line
2.52.0
Pavel Machek
Reviewed-byHi!
Quoted 13 lines
Quoted 13 lines
Quoted 2 lines
Takashi Iwai <[email protected]>
ALSA: usb-audio: Fix potential overflow of PCM transfer bufferThis one is wrong for at least 6.12 and older.
(quoted diff) +5
-0+ if (ep->packsize[1] > ep->maxpacksize) { + usb_audio_dbg(chip, "Too small maxpacksize %u for rate %u / pps %u\n", + ep->maxpacksize, ep->cur_rate, ep->pps); + return -EINVAL; + }Needs to be err =
-EINVAL; goto unlock;.
Quoted 8 lines
Quoted 1 line
(Or cherry pick
guard()handling from newer kernels).Thanks Pavel, a good catch!
A cherry-pick of the commit
efea7a57370bfor converting toguard()doesn't seem to be cleanly applicable on 6.12.y, unfortunately. So I guess it'd be easier to have a correction on the top instead, something like below.
Yes, works for me, thanks for handling this.
Quoted 11 lines
-- 8< --
From: Takashi Iwai <[email protected]>
Subject: [PATCH v6.12.y] ALSA: usb-audio: Fix missing unlock at error path of
maxpacksize checkThe recent backport of the upstream commit
05a1fc5efdd8("ALSA:
usb-audio: Fix potential overflow of PCM transfer buffer") on the older stable kernels like 6.12.y was broken since it doesn't consider the mutex unlock, where the upstream code manages withguard(). In the older code, we still need an explicit unlock.
Quoted 7 lines
This is a fix that corrects the error path, applied only on old stable trees.
Reported-by Pavel Machek <[email protected]>Fixes 98e9d5e33bda ("ALSA: usb-audio: Fix potential overflow of PCM transfer buffer")Signed-off-by Takashi Iwai <[email protected]>
Best regards,
Pavel
Signature · 2 lines
In cooperation with DENX Software Engineering GmbH, HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Quoted 41 lines · Pavel Machek
Hi!
Quoted 13 lines
Quoted 13 lines
Quoted 2 lines
Takashi Iwai <[email protected]>
ALSA: usb-audio: Fix potential overflow of PCM transfer bufferThis one is wrong for at least 6.12 and older.
(quoted diff) +5
-0+ if (ep->packsize[1] > ep->maxpacksize) { + usb_audio_dbg(chip, "Too small maxpacksize %u for rate %u / pps %u\n", + ep->maxpacksize, ep->cur_rate, ep->pps); + return -EINVAL; + }Needs to be err =
-EINVAL; goto unlock;.Quoted 8 lines
Quoted 1 line
(Or cherry pick
guard()handling from newer kernels).Thanks Pavel, a good catch!
A cherry-pick of the commit
efea7a57370bfor converting toguard()doesn't seem to be cleanly applicable on 6.12.y, unfortunately. So I guess it'd be easier to have a correction on the top instead, something like below.Yes, works for me, thanks for handling this.
Quoted 14 lines
-- 8< --
From: Takashi Iwai <[email protected]>
Subject: [PATCH v6.12.y] ALSA: usb-audio: Fix missing unlock at error path of
maxpacksize checkThe recent backport of the upstream commit
05a1fc5efdd8("ALSA:
usb-audio: Fix potential overflow of PCM transfer buffer") on the older stable kernels like 6.12.y was broken since it doesn't consider the mutex unlock, where the upstream code manages withguard(). In the older code, we still need an explicit unlock.This is a fix that corrects the error path, applied only on old stable trees.
Quoted 6 lines
Quoted 4 lines
Reported-by Pavel Machek <[email protected]>Fixes 98e9d5e33bda ("ALSA: usb-audio: Fix potential overflow of PCM transfer buffer")Signed-off-by Takashi Iwai <[email protected]>Reviewed-by Pavel Machek <[email protected]>
OK, will submit properly.
thanks,
Takashi