6.1.160-rc1 review
Subsystems (5)
Greg Kroah-Hartman
maintainerPATCH 132/634 cpuset: Treat cpusets in attaching as populated
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Ridong <[email protected]>
[ Upstream commit b1bcaed1e39a9e0dfbe324a15d2ca4253deda316 ]
Currently, the check for whether a partition is populated does not account for tasks in the cpuset of attaching. This is a corner case that can leave a task stuck in a partition with no effective CPUs.
The race condition occurs as follows:
cpu0 cpu1
//cpuset A with cpu N
migrate task p to Acpuset_can_attach
// with effective cpus
// check ok
// cpuset_mutex is not held // clear cpuset.cpus.exclusive
// making effective cpus empty update_exclusive_cpumask // tasks_nocpu_error check ok // empty effective cpus, partition valid
cpuset_attach
...
// task p stays in A, with non-effective cpus.
To fix this issue, this patch introduces cs_is_populated, which considers tasks in the attaching cpuset. This new helper is used in validate_change and partition_is_populated.
--- kernel/cgroup/cpuset.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-)
kernel/cgroup/cpuset.c +27 -8
@@ -476,6 +476,15 @@ static inline bool is_in_v2_mode(void) (cpuset_cgrp_subsys.root->flags &CGRP_ROOT_CPUSET_V2_MODE ); } +static inline bool cpuset_is_populated (struct cpuset *cs) +{ +lockdep_assert_held (&cpuset_mutex); + +/* Cpusets in the process of attaching should be considered as populated */ +return cgroup_is_populated (cs->css.cgroup) || + cs->attach_in_progress; +} +/** * partition_is_populated - check if partition has tasks * @cs: partition root to be checked
@@ -488,21 +497,31 @@ static inline bool is_in_v2_mode(void)static inline bool partition_is_populated (struct cpuset *cs,struct cpuset *excluded_child) { -struct cgroup_subsys_state *css; -struct cpuset *child; +struct cpuset *cp; +struct cgroup_subsys_state *pos_css; -if (cs->css.cgroup->nr_populated_csets) +/* +* We cannot call cs_is_populated(cs) directly, as +* nr_populated_domain_children may include populated +* csets from descendants that are partitions. +*/ +if (cs->css.cgroup->nr_populated_csets || + cs->attach_in_progress)return true;if (!excluded_child && !cs->nr_subparts_cpus)return cgroup_is_populated (cs->css.cgroup);rcu_read_lock (); -cpuset_for_each_child (child, css, cs) { -if (child == excluded_child) +cpuset_for_each_descendant_pre (cp, pos_css, cs) { +if (cp == cs || cp == excluded_child)continue ; -if (is_partition_valid (child)) + +if (is_partition_valid (cp)) { + pos_css =css_rightmost_descendant (pos_css);continue ; -if (cgroup_is_populated (child->css.cgroup)) { + } + +if (cpuset_is_populated (cp)) {rcu_read_unlock ();return true; }
@@ -774,7 +793,7 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial)* be changed to have empty cpus_allowed or mems_allowed. */ ret = -ENOSPC ; -if ((cgroup_is_populated (cur->css.cgroup) || cur->attach_in_progress)) { +if (cpuset_is_populated (cur)) {if (!cpumask_empty (cur->cpus_allowed) &&cpumask_empty (trial->cpus_allowed)) goto out;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 133/634 wifi: rtl818x: rtl8187: Fix potential buffer underflow in rtl8187_rx_cb()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Seungjin Bae <[email protected]>
[ Upstream commit b647d2574e4583c2e3b0ab35568f60c88e910840 ]
The rtl8187_rx_cb() calculates the rx descriptor header address by subtracting its size from the skb tail pointer. However, it does not validate if the received packet (skb->len from urb->actual_length) is large enough to contain this header.
If a truncated packet is received, this will lead to a buffer underflow, reading memory before the start of the skb data area, and causing a kernel panic.
Add length checks for both rtl8187 and rtl8187b descriptor headers before attempting to access them, dropping the packet cleanly if the check fails.
--- .../wireless/realtek/rtl818x/rtl8187/dev.c | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-)
drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +19 -8
@@ -338,14 +338,16 @@ static void rtl8187_rx_cb(struct urb *urb)spin_unlock_irqrestore (&priv->rx_queue.lock, f);skb_put (skb, urb->actual_length); -if (unlikely (urb->status)) { -dev_kfree_skb_irq (skb); -return ; - } +if (unlikely (urb->status)) + goto free_skb;if (!priv->is_rtl8187b) { -struct rtl8187_rx_hdr *hdr = - (typeof (hdr))(skb_tail_pointer (skb) -sizeof (*hdr)); +struct rtl8187_rx_hdr *hdr; + +if (skb->len <sizeof (struct rtl8187_rx_hdr )) + goto free_skb; + + hdr = (typeof (hdr))(skb_tail_pointer (skb) -sizeof (*hdr)); flags =le32_to_cpu (hdr->flags);/* As with the RTL8187B below, the AGC is used to calculate * signal strength. In this case, the scaling
@@ -355,8 +357,12 @@ static void rtl8187_rx_cb(struct urb *urb) rx_status.antenna = (hdr->signal >>7 ) &1 ; rx_status.mactime =le64_to_cpu (hdr->mac_time); }else { -struct rtl8187b_rx_hdr *hdr = - (typeof (hdr))(skb_tail_pointer (skb) -sizeof (*hdr)); +struct rtl8187b_rx_hdr *hdr; + +if (skb->len <sizeof (struct rtl8187b_rx_hdr )) + goto free_skb; + + hdr = (typeof (hdr))(skb_tail_pointer (skb) -sizeof (*hdr));/* The Realtek datasheet for the RTL8187B shows that the RX * header contains the following quantities: signal quality, * RSSI, AGC, the received power in dB, and the measured SNR.
@@ -409,6 +415,11 @@ static void rtl8187_rx_cb(struct urb *urb)skb_unlink (skb, &priv->rx_queue);dev_kfree_skb_irq (skb); } +return ; + +free_skb: +dev_kfree_skb_irq (skb); +return ; }static int rtl8187_init_urbs (struct ieee80211_hw *dev)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 134/634 ima: Handle error code returned by ima_filter_rule_match()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Yipeng <[email protected]>
[ Upstream commit 738c9738e690f5cea24a3ad6fd2d9a323cf614f6 ]
In ima_match_rules(), if ima_filter_rule_match() returns -ENOENT due to the rule being NULL, the function incorrectly skips the 'if (!rc)' check and sets 'result = true'. The LSM rule is considered a match, causing extra files to be measured by IMA.
This issue can be reproduced in the following scenario:
After unloading the SELinux policy module via 'semodule -d', if an IMA measurement is triggered before ima_lsm_rules is updated,
in ima_match_rules(), the first call to ima_filter_rule_match() returns -ESTALE. This causes the code to enter the 'if (rc == -ESTALE && !rule_reinitialized)' block, perform ima_lsm_copy_rule() and retry. In ima_lsm_copy_rule(), since the SELinux module has been removed, the rule becomes NULL, and the second call to ima_filter_rule_match() returns -ENOENT. This bypasses the 'if (!rc)' check and results in a false match.
Call trace: selinux_audit_rule_match+0x310/0x3b8 security_audit_rule_match+0x60/0xa0 ima_match_rules+0x2e4/0x4a0 ima_match_policy+0x9c/0x1e8 ima_get_action+0x48/0x60 process_measurement+0xf8/0xa98 ima_bprm_check+0x98/0xd8 security_bprm_check+0x5c/0x78 search_binary_handler+0x6c/0x318 exec_binprm+0x58/0x1b8 bprm_execve+0xb8/0x130 do_execveat_common.isra.0+0x1a8/0x258 __arm64_sys_execve+0x48/0x68 invoke_syscall+0x50/0x128 el0_svc_common.constprop.0+0xc8/0xf0 do_el0_svc+0x24/0x38 el0_svc+0x44/0x200 el0t_64_sync_handler+0x100/0x130 el0t_64_sync+0x3c8/0x3d0
Fix this by changing 'if (!rc)' to 'if (rc <= 0)' to ensure that error codes like -ENOENT do not bypass the check and accidentally result in a successful match.
--- security/integrity/ima/ima_policy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
security/integrity/ima/ima_policy.c +1 -1
@@ -646,7 +646,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, goto retry; } } -if (!rc) { +if (rc <=0 ) { result = false; goto out; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 135/634 usb: chaoskey: fix locking for O_NONBLOCK
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
[ Upstream commit a2fa8a12e6bc9d89c0505b8dd7ae38ec173d25de ]
A failure to take a lock with O_NONBLOCK needs to result in -EAGAIN. Change it.
--- drivers/usb/misc/chaoskey.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
drivers/usb/misc/chaoskey.c +13 -3
@@ -445,9 +445,19 @@ static ssize_t chaoskey_read(struct file *file, goto bail;mutex_unlock (&dev->rng_lock); - result =mutex_lock_interruptible (&dev->lock); -if (result) - goto bail; +if (file->f_flags &O_NONBLOCK ) { + result =mutex_trylock (&dev->lock); +if (result ==0 ) { + result = -EAGAIN ; + goto bail; + }else { + result =0 ; + } + }else { + result =mutex_lock_interruptible (&dev->lock); +if (result) + goto bail; + }if (dev->valid == dev->used) { result =_chaoskey_fill (dev);if (result <0 ) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 136/634 usb: dwc2: disable platform lowlevel hw resources during shutdown
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jisheng Zhang <[email protected]>
[ Upstream commit 7481a97c5f49f10c7490bb990d0e863f23b9bb71 ]
On some SoC platforms, in shutdown stage, most components' power is cut off, but there's still power supply to the so called always-on domain, so if the dwc2's regulator is from the always-on domain, we need to explicitly disable it to save power.
Disable platform lowlevel hw resources such as phy, clock and regulators etc. in device shutdown hook to reduce non-necessary power consumption when the platform enters shutdown stage.
Stable-dep-of: b6ebcfdcac40 ("usb: dwc2: fix hang during shutdown if set as peripheral")
--- drivers/usb/dwc2/platform.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/dwc2/platform.c +3 -0
@@ -340,6 +340,9 @@ static void dwc2_driver_shutdown(struct platform_device *dev)dwc2_disable_global_interrupts (hsotg);synchronize_irq (hsotg->irq); + +if (hsotg->ll_hw_enabled) +dwc2_lowlevel_hw_disable (hsotg); }/**
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 137/634 usb: dwc2: fix hang during shutdown if set as peripheral
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jisheng Zhang <[email protected]>
[ Upstream commit b6ebcfdcac40a27953f052e4269ce75a18825ffc ]
dwc2 on most platforms needs phy controller, clock and power supply. All of them must be enabled/activated to properly operate. If dwc2 is configured as peripheral mode, then all the above three hardware resources are disabled at the end of the probe:
/* Gadget code manages lowlevel hw on its own */ if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) dwc2_lowlevel_hw_disable(hsotg);
But dwc2_driver_shutdown() tries to disable the interrupts on HW IP level. This would result in hang during shutdown if dwc2 is configured as peripheral mode.
Fix this hang by only disable and sync irq when lowlevel hw is enabled.
--- drivers/usb/dwc2/platform.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/usb/dwc2/platform.c +4 -4
@@ -338,11 +338,11 @@ static void dwc2_driver_shutdown(struct platform_device *dev) {struct dwc2_hsotg *hsotg =platform_get_drvdata (dev); -dwc2_disable_global_interrupts (hsotg); -synchronize_irq (hsotg->irq); - -if (hsotg->ll_hw_enabled) +if (hsotg->ll_hw_enabled) { +dwc2_disable_global_interrupts (hsotg); +synchronize_irq (hsotg->irq);dwc2_lowlevel_hw_disable (hsotg); + } }/**
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 138/634 usb: dwc2: fix hang during suspend if set as peripheral
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jisheng Zhang <[email protected]>
[ Upstream commit 2b94b054ac4974ad2f89f7f7461840c851933adb ]
dwc2 on most platforms needs phy controller, clock and power supply. All of them must be enabled/activated to properly operate. If dwc2 is configured as peripheral mode, then all the above three hardware resources are disabled at the end of the probe:
/* Gadget code manages lowlevel hw on its own */ if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) dwc2_lowlevel_hw_disable(hsotg);
But the dwc2_suspend() tries to read the dwc2's reg to check whether is_device_mode or not, this would result in hang during suspend if dwc2 is configured as peripheral mode.
Fix this hang by bypassing suspend/resume if lowlevel hw isn't enabled.
--- drivers/usb/dwc2/platform.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/usb/dwc2/platform.c +8 -1
@@ -618,9 +618,13 @@ static int dwc2_driver_probe(struct platform_device *dev)static int __maybe_unused dwc2_suspend (struct device *dev) {struct dwc2_hsotg *dwc2 =dev_get_drvdata (dev); -bool is_device_mode =dwc2_is_device_mode (dwc2); +bool is_device_mode;int ret =0 ; +if (!dwc2->ll_hw_enabled) +return 0 ; + + is_device_mode =dwc2_is_device_mode (dwc2);if (is_device_mode)dwc2_hsotg_suspend (dwc2);
@@ -671,6 +675,9 @@ static int __maybe_unused dwc2_resume(struct device *dev)struct dwc2_hsotg *dwc2 =dev_get_drvdata (dev);int ret =0 ; +if (!dwc2->ll_hw_enabled) +return 0 ; +if (dwc2->phy_off_for_suspend && dwc2->ll_hw_enabled) { ret =__dwc2_lowlevel_hw_enable (dwc2);if (ret)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 139/634 usb: raw-gadget: cap raw_io transfer length to KMALLOC_MAX_SIZE
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gopi Krishna Menon <[email protected]>
[ Upstream commit a5160af78be7fcf3ade6caab0a14e349560c96d7 ]
The previous commit removed the PAGE_SIZE limit on transfer length of raw_io buffer in order to avoid any problems with emulating USB devices whose full configuration descriptor exceeds PAGE_SIZE in length. However this also removes the upperbound on user supplied length, allowing very large values to be passed to the allocator.
syzbot on fuzzing the transfer length with very large value (1.81GB) results in kmalloc() to fall back to the page allocator, which triggers a kernel warning as the page allocator cannot handle allocations more than MAX_PAGE_ORDER/KMALLOC_MAX_SIZE.
Since there is no limit imposed on the size of buffer for both control and non control transfers, cap the raw_io transfer length to KMALLOC_MAX_SIZE and return -EINVAL for larger transfer length to prevent any warnings from the page allocator.
--- drivers/usb/gadget/legacy/raw_gadget.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/gadget/legacy/raw_gadget.c +3 -0
@@ -39,6 +39,7 @@ MODULE_LICENSE("GPL");static DEFINE_IDA (driver_id_numbers);#define DRIVER_DRIVER_NAME_LENGTH_MAX 32 +#define USB_RAW_IO_LENGTH_MAX KMALLOC_MAX_SIZE#define RAW_EVENT_QUEUE_SIZE 16
@@ -620,6 +621,8 @@ static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr,return ERR_PTR (-EINVAL );if (!usb_raw_io_flags_valid (io->flags))return ERR_PTR (-EINVAL ); +if (io->length >USB_RAW_IO_LENGTH_MAX ) +return ERR_PTR (-EINVAL );if (get_from_user) data =memdup_user (ptr +sizeof (*io), io->length);else {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 140/634 selftests/bpf: skip test_perf_branches_hw() on unsupported platforms
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Bobrowski <[email protected]>
[ Upstream commit 27746aaf1b20172f0859546c4a3e82eca459f680 ]
Gracefully skip the test_perf_branches_hw subtest on platforms that do not support LBR or require specialized perf event attributes to enable branch sampling.
For example, AMD's Milan (Zen 3) supports BRS rather than traditional LBR. This requires specific configurations (attr.type = PERF_TYPE_RAW, attr.config = RETIRED_TAKEN_BRANCH_INSTRUCTIONS) that differ from the generic setup used within this test. Notably, it also probably doesn't hold much value to special case perf event configurations for selected micro architectures.
--- tools/testing/selftests/bpf/prog_tests/perf_branches.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
tools/testing/selftests/bpf/prog_tests/perf_branches.c +3 -3
@@ -116,11 +116,11 @@ static void test_perf_branches_hw(void) pfd =syscall (__NR_perf_event_open, &attr,-1 ,0 ,-1 ,PERF_FLAG_FD_CLOEXEC );/* -* Some setups don't support branch records (virtual machines, !x86), -* so skip test in this case. +* Some setups don't support LBR (virtual machines, !x86, AMD Milan Zen +* 3 which only supports BRS), so skip test in this case. */ if (pfd <0 ) { -if (errno ==ENOENT || errno ==EOPNOTSUPP ) { +if (errno ==ENOENT || errno ==EOPNOTSUPP || errno ==EINVAL ) {printf ("%s:SKIP:no PERF_SAMPLE_BRANCH_STACK\n" , __func__);test__skip ();
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 141/634 selftests/bpf: Improve reliability of test_perf_branches_no_hw()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Bobrowski <[email protected]>
[ Upstream commit ae24fc8a16b0481ea8c5acbc66453c49ec0431c4 ]
Currently, test_perf_branches_no_hw() relies on the busy loop within test_perf_branches_common() being slow enough to allow at least one perf event sample tick to occur before starting to tear down the backing perf event BPF program. With a relatively small fixed iteration count of 1,000,000, this is not guaranteed on modern fast CPUs, resulting in the test run to subsequently fail with the following:
bpf_testmod.ko is already unloaded.
Loading bpf_testmod.ko...
Successfully loaded bpf_testmod.ko. test_perf_branches_common:PASS:test_perf_branches_load 0 nsec test_perf_branches_common:PASS:attach_perf_event 0 nsec test_perf_branches_common:PASS:set_affinity 0 nsec check_good_sample:PASS:output not valid 0 nsec check_good_sample:PASS:read_branches_size 0 nsec check_good_sample:PASS:read_branches_stack 0 nsec check_good_sample:PASS:read_branches_stack 0 nsec check_good_sample:PASS:read_branches_global 0 nsec check_good_sample:PASS:read_branches_global 0 nsec check_good_sample:PASS:read_branches_size 0 nsec test_perf_branches_no_hw:PASS:perf_event_open 0 nsec test_perf_branches_common:PASS:test_perf_branches_load 0 nsec test_perf_branches_common:PASS:attach_perf_event 0 nsec test_perf_branches_common:PASS:set_affinity 0 nsec check_bad_sample:FAIL:output not valid no valid sample from prog
Summary: 0/1 PASSED, 0 SKIPPED, 1 FAILED
Successfully unloaded bpf_testmod.ko.
On a modern CPU (i.e. one with a 3.5 GHz clock rate), executing 1 million increments of a volatile integer can take significantly less than 1 millisecond. If the spin loop and detachment of the perf event BPF program elapses before the first 1 ms sampling interval elapses, the perf event will never end up firing. Fix this by bumping the loop iteration counter a little within test_perf_branches_common(), along with ensuring adding another loop termination condition which is directly influenced by the backing perf event BPF program executing. Notably, a concious decision was made to not adjust the sample_freq value as that is just not a reliable way to go about fixing the problem. It effectively still leaves the race window open.
--- .../selftests/bpf/prog_tests/perf_branches.c | 16 ++++++++++++++-- .../selftests/bpf/progs/test_perf_branches.c | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-)
tools/testing/selftests/bpf/prog_tests/perf_branches.c +14 -2
@@ -15,6 +15,10 @@ static void check_good_sample(struct test_perf_branches *skel)int pbe_size =sizeof (struct perf_branch_entry );int duration =0 ; +if (CHECK (!skel->bss->run_cnt,"invalid run_cnt" , +"checked sample validity before prog run" )) +return ; +if (CHECK (!skel->bss->valid,"output not valid" ,"no valid sample from prog" ))return ;
@@ -45,6 +49,10 @@ static void check_bad_sample(struct test_perf_branches *skel)int written_stack = skel->bss->written_stack_out;int duration =0 ; +if (CHECK (!skel->bss->run_cnt,"invalid run_cnt" , +"checked sample validity before prog run" )) +return ; +if (CHECK (!skel->bss->valid,"output not valid" ,"no valid sample from prog" ))return ;
@@ -83,8 +91,12 @@ static void test_perf_branches_common(int perf_fd, err =pthread_setaffinity_np (pthread_self (),sizeof (cpu_set), &cpu_set);if (CHECK (err,"set_affinity" ,"cpu #0, err %d\n" , err)) goto out_destroy; -/* spin the loop for a while (random high number) */ -for (i =0 ; i <1000000 ; ++i) + +/* Spin the loop for a while by using a high iteration count, and by +* checking whether the specific run count marker has been explicitly +* incremented at least once by the backing perf_event BPF program. +*/ +for (i =0 ; i <100000000 && !*(volatile int *)&skel->bss->run_cnt; ++i) ++j;test_perf_branches__detach (skel);
tools/testing/selftests/bpf/progs/test_perf_branches.c +3 -0
@@ -8,6 +8,7 @@#include <bpf/bpf_tracing.h> int valid =0 ; +int run_cnt =0 ;int required_size_out =0 ;int written_stack_out =0 ;int written_global_out =0 ;
@@ -24,6 +25,8 @@ int perf_branches(void *ctx)__u64 entries[4 *3 ] = {0 };int required_size, written_stack, written_global; + ++run_cnt; +/* write to stack */ written_stack =bpf_read_branch_records (ctx, entries,sizeof (entries),0 );/* ignore spurious events */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 142/634 crypto: ccree - Correctly handle return of sg_nents_for_len
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit 8700ce07c5c6bf27afa7b59a8d9cf58d783a7d5c ]
Fix error handling in cc_map_hash_request_update where sg_nents_for_len return value was assigned to u32, converting negative errors to large positive values before passing to sg_copy_to_buffer.
Check sg_nents_for_len return value and propagate errors before assigning to areq_ctx->in_nents.
--- drivers/crypto/ccree/cc_buffer_mgr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/crypto/ccree/cc_buffer_mgr.c +5 -1
@@ -1235,6 +1235,7 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx,int rc =0 ;u32 dummy =0 ;u32 mapped_nents =0 ; +int sg_nents;dev_dbg (dev," update params : curr_buff=%pK curr_buff_cnt=0x%X nbytes=0x%X src=%pK curr_index=%u\n" , curr_buff, *curr_buff_cnt, nbytes, src, areq_ctx->buff_index);
@@ -1248,7 +1249,10 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx,if (total_in_len < block_size) {dev_dbg (dev," less than one block: curr_buff=%pK *curr_buff_cnt=0x%X copy_to=%pK\n" , curr_buff, *curr_buff_cnt, &curr_buff[*curr_buff_cnt]); - areq_ctx->in_nents =sg_nents_for_len (src, nbytes); + sg_nents =sg_nents_for_len (src, nbytes); +if (sg_nents <0 ) +return sg_nents; + areq_ctx->in_nents = sg_nents;sg_copy_to_buffer (src, areq_ctx->in_nents, &curr_buff[*curr_buff_cnt], nbytes); *curr_buff_cnt += nbytes;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 143/634 RISC-V: KVM: Fix guest page fault within HLV* instructions
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fangyu Yu <[email protected]>
[ Upstream commit 974555d6e417974e63444266e495a06d06c23af5 ]
When executing HLV* instructions at the HS mode, a guest page fault may occur when a g-stage page table migration between triggering the virtual instruction exception and executing the HLV* instruction.
This may be a corner case, and one simpler way to handle this is to re-execute the instruction where the virtual instruction exception occurred, and the guest page fault will be automatically handled.
--- arch/riscv/kvm/vcpu_insn.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
arch/riscv/kvm/vcpu_insn.c +22 -0
@@ -393,6 +393,22 @@ static int system_opcode_insn(struct kvm_vcpu *vcpu, struct kvm_run *run,return (rc <=0 ) ? rc :1 ; } +static bool is_load_guest_page_fault (unsigned long scause) +{ +/** +* If a g-stage page fault occurs, the direct approach +* is to let the g-stage page fault handler handle it +* naturally, however, calling the g-stage page fault +* handler here seems rather strange. +* Considering this is a corner case, we can directly +* return to the guest and re-execute the same PC, this +* will trigger a g-stage page fault again and then the +* regular g-stage page fault handler will populate +* g-stage page table. +*/ +return (scause ==EXC_LOAD_GUEST_PAGE_FAULT ); +} +/** * kvm_riscv_vcpu_virtual_insn -- Handle virtual instruction trap *
@@ -418,6 +434,8 @@ int kvm_riscv_vcpu_virtual_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, ct->sepc, &utrap);if (utrap.scause) { +if (is_load_guest_page_fault (utrap.scause)) +return 1 ; utrap.sepc = ct->sepc;kvm_riscv_vcpu_trap_redirect (vcpu, &utrap);return 1 ;
@@ -473,6 +491,8 @@ int kvm_riscv_vcpu_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run, insn =kvm_riscv_vcpu_unpriv_read (vcpu, true, ct->sepc, &utrap);if (utrap.scause) { +if (is_load_guest_page_fault (utrap.scause)) +return 1 ;/* Redirect trap if we failed to read instruction */ utrap.sepc = ct->sepc;kvm_riscv_vcpu_trap_redirect (vcpu, &utrap);
@@ -599,6 +619,8 @@ int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run, insn =kvm_riscv_vcpu_unpriv_read (vcpu, true, ct->sepc, &utrap);if (utrap.scause) { +if (is_load_guest_page_fault (utrap.scause)) +return 1 ;/* Redirect trap if we failed to read instruction */ utrap.sepc = ct->sepc;kvm_riscv_vcpu_trap_redirect (vcpu, &utrap);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 144/634 mt76: mt7615: Fix memory leak in mt7615_mcu_wtbl_sta_add()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zilin Guan <[email protected]>
[ Upstream commit 53d1548612670aa8b5d89745116cc33d9d172863 ]
In mt7615_mcu_wtbl_sta_add(), an skb sskb is allocated. If the subsequent call to mt76_connac_mcu_alloc_wtbl_req() fails, the function returns an error without freeing sskb, leading to a memory leak.
Fix this by calling dev_kfree_skb() on sskb in the error handling path to ensure it is properly released.
--- drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +3 -1
@@ -869,8 +869,10 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif, wtbl_hdr =mt76_connac_mcu_alloc_wtbl_req (&dev->mt76, &msta->wcid,WTBL_RESET_AND_SET ,NULL , &wskb); -if (IS_ERR (wtbl_hdr)) +if (IS_ERR (wtbl_hdr)) { +dev_kfree_skb (sskb);return PTR_ERR (wtbl_hdr); + }if (enable) { mt76_connac_mcu_wtbl_generic_tlv(&dev->mt76, wskb, vif, sta,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 145/634 firmware: stratix10-svc: fix make htmldocs warning for stratix10_svc
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dinh Nguyen <[email protected]>
[ Upstream commit 377441d53a2df61b105e823b335010cd4f1a6e56 ]
Fix this warning that was generated from "make htmldocs":
WARNING: drivers/firmware/stratix10-svc.c:58 struct member 'intel_svc_fcs'
not described in 'stratix10_svc'
--- drivers/firmware/stratix10-svc.c | 1 + 1 file changed, 1 insertion(+)
drivers/firmware/stratix10-svc.c +1 -0
@@ -51,6 +51,7 @@ struct stratix10_svc_chan;/** * struct stratix10_svc - svc private data * @stratix10_svc_rsu: pointer to stratix10 RSU device +* @intel_svc_fcs: pointer to the FCS device */ struct stratix10_svc {struct platform_device *stratix10_svc_rsu;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 146/634 staging: fbtft: core: fix potential memory leak in fbtft_probe_common()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jianglei Nie <[email protected]>
[ Upstream commit 47d3949a9b04cbcb0e10abae30c2b53e98706e11 ]
fbtft_probe_common() allocates a memory chunk for "info" with fbtft_framebuffer_alloc(). When "display->buswidth == 0" is true, the function returns without releasing the "info", which will lead to a memory leak.
Fix it by calling fbtft_framebuffer_release() when "display->buswidth == 0" is true.
--- drivers/staging/fbtft/fbtft-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/staging/fbtft/fbtft-core.c +2 -2
@@ -1225,8 +1225,8 @@ int fbtft_probe_common(struct fbtft_display *display, par->pdev = pdev;if (display->buswidth ==0 ) { -dev_err (dev,"buswidth is not set\n" ); -return -EINVAL ; + ret =dev_err_probe (dev, -EINVAL ,"buswidth is not set\n" ); + goto out_release; }/* write register functions */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 147/634 PCI: dwc: Fix wrong PORT_LOGIC_LTSSM_STATE_MASK definition
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shawn Lin <[email protected]>
[ Upstream commit bcc9a4a0bca3aee4303fa4a20302e57b24ac8f68 ]
As per DesignWare Cores PCI Express Controller Databook, section 5.50,
SII: Debug Signals, cxpl_debug_info[63:0]:
[5:0] smlh_ltssm_state: LTSSM current state. Encoding is same as the dedicated smlh_ltssm_state output.
The mask should be 6 bits, from 0 to 5. Hence, fix the mask definition.
--- drivers/pci/controller/dwc/pcie-designware.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/controller/dwc/pcie-designware.h +1 -1
@@ -75,7 +75,7 @@#define PORT_LINK_MODE_8_LANES PORT_LINK_MODE(0xf)#define PCIE_PORT_DEBUG0 0x728 -#define PORT_LOGIC_LTSSM_STATE_MASK 0x1f +#define PORT_LOGIC_LTSSM_STATE_MASK 0x3f#define PORT_LOGIC_LTSSM_STATE_L0 0x11#define PCIE_PORT_DEBUG1 0x72C#define PCIE_PORT_DEBUG1_LINK_UP BIT(4)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 148/634 wifi: ieee80211: correct FILS status codes
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ria Thomas <[email protected]>
[ Upstream commit 24d4da5c2565313c2ad3c43449937a9351a64407 ]
The FILS status codes are set to 108/109, but the IEEE 802.11-2020 spec defines them as 112/113. Update the enum so it matches the specification and keeps the kernel consistent with standard values.
--- include/linux/ieee80211.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/ieee80211.h +2 -2
@@ -3157,8 +3157,8 @@ enum ieee80211_statuscode {WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL =99 ,WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT =103 ,/* 802.11ai */ -WLAN_STATUS_FILS_AUTHENTICATION_FAILURE =108 , -WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER =109 , +WLAN_STATUS_FILS_AUTHENTICATION_FAILURE =112 , +WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER =113 ,WLAN_STATUS_SAE_HASH_TO_ELEMENT =126 , WLAN_STATUS_SAE_PK = 127, };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 149/634 backlight: led_bl: Take led_access lock when required
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mans Rullgard <[email protected]>
[ Upstream commit a33677b9211b6c328ad359b072043af94f7c9592 ]
The led_access lock must be held when calling led_sysfs_enable() and led_sysfs_disable(). This fixes warnings such as this:
[ 2.432495] ------------[ cut here ]------------ [ 2.437316] WARNING: CPU: 0 PID: 22 at drivers/leds/led-core.c:349 led_sysfs_disable+0x54/0x58 [ 2.446105] Modules linked in: [ 2.449218] CPU: 0 PID: 22 Comm: kworker/u2:1 Not tainted 6.3.8+ #1 [ 2.456268] Hardware name: Generic AM3517 (Flattened Device Tree) [ 2.462402] Workqueue: events_unbound deferred_probe_work_func [ 2.468353] unwind_backtrace from show_stack+0x10/0x14 [ 2.473632] show_stack from dump_stack_lvl+0x24/0x2c [ 2.478759] dump_stack_lvl from __warn+0x9c/0xc4 [ 2.483551] __warn from warn_slowpath_fmt+0x64/0xc0 [ 2.488586] warn_slowpath_fmt from led_sysfs_disable+0x54/0x58 [ 2.494567] led_sysfs_disable from led_bl_probe+0x20c/0x3b0 [ 2.500305] led_bl_probe from platform_probe+0x5c/0xb8 [ 2.505615] platform_probe from really_probe+0xc8/0x2a0 [ 2.510986] really_probe from __driver_probe_device+0x88/0x19c [ 2.516967] __driver_probe_device from driver_probe_device+0x30/0xcc [ 2.523498] driver_probe_device from __device_attach_driver+0x94/0xc4 [ 2.530090] __device_attach_driver from bus_for_each_drv+0x80/0xcc [ 2.536437] bus_for_each_drv from __device_attach+0xf8/0x19c [ 2.542236] __device_attach from bus_probe_device+0x8c/0x90 [ 2.547973] bus_probe_device from deferred_probe_work_func+0x80/0xb0 [ 2.554504] deferred_probe_work_func from process_one_work+0x228/0x4c0 [ 2.561187] process_one_work from worker_thread+0x1fc/0x4d0 [ 2.566925] worker_thread from kthread+0xb4/0xd0 [ 2.571685] kthread from ret_from_fork+0x14/0x2c [ 2.576446] Exception stack(0xd0079fb0 to 0xd0079ff8) [ 2.581573] 9fa0: 00000000 00000000 00000000 00000000 [ 2.589813] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 2.598052] 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000 [ 2.604888] ---[ end trace 0000000000000000 ]---
Stable-dep-of: 9341d6698f4c ("backlight: led-bl: Add devlink to supplier LEDs")
--- drivers/video/backlight/led_bl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/video/backlight/led_bl.c +4 -1
@@ -209,8 +209,11 @@ static int led_bl_probe(struct platform_device *pdev)return PTR_ERR (priv->bl_dev); } -for (i =0 ; i < priv->nb_leds; i++) +for (i =0 ; i < priv->nb_leds; i++) { +mutex_lock (&priv->leds[i]->led_access);led_sysfs_disable (priv->leds[i]); +mutex_unlock (&priv->leds[i]->led_access); + }backlight_update_status (priv->bl_dev);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 150/634 backlight: led-bl: Add devlink to supplier LEDs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luca Ceresoli <[email protected]>
[ Upstream commit 9341d6698f4cfdfc374fb6944158d111ebe16a9d ]
LED Backlight is a consumer of one or multiple LED class devices, but devlink is currently unable to create correct supplier-producer links when the supplier is a class device. It creates instead a link where the supplier is the parent of the expected device.
One consequence is that removal order is not correctly enforced.
Issues happen for example with the following sections in a device tree overlay:
// An LED driver chip
pca9632@62 {
compatible = "nxp,pca9632";
reg = <0x62>;
// ...
addon_led_pwm: led-pwm@3 {
reg = <3>;
label = "addon:led:pwm";
};
};
backlight-addon {
compatible = "led-backlight";
leds = <&addon_led_pwm>;
brightness-levels = <255>;
default-brightness-level = <255>;
};In this example, the devlink should be created between the backlight-addon (consumer) and the pca9632@62 (supplier). Instead it is created between the backlight-addon (consumer) and the parent of the pca9632@62, which is typically the I2C bus adapter.
On removal of the above overlay, the LED driver can be removed before the backlight device, resulting in:
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010
...
Call trace:
led_put+0xe0/0x140
devm_led_release+0x6c/0x98Another way to reproduce the bug without any device tree overlays is unbinding the LED class device (pca9632@62) before unbinding the consumer (backlight-addon):
echo 11-0062 >/sys/bus/i2c/drivers/leds-pca963x/unbind echo ...backlight-dock >/sys/bus/platform/drivers/led-backlight/unbind
Fix by adding a devlink between the consuming led-backlight device and the supplying LED device, as other drivers and subsystems do as well.
--- drivers/video/backlight/led_bl.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/video/backlight/led_bl.c +13 -0
@@ -209,6 +209,19 @@ static int led_bl_probe(struct platform_device *pdev)return PTR_ERR (priv->bl_dev); } +for (i =0 ; i < priv->nb_leds; i++) { +struct device_link *link; + + link =device_link_add (&pdev->dev, priv->leds[i]->dev->parent, +DL_FLAG_AUTOREMOVE_CONSUMER ); +if (!link) { +dev_err (&pdev->dev,"Failed to add devlink (consumer %s, supplier %s)\n" , +dev_name (&pdev->dev),dev_name (priv->leds[i]->dev->parent)); +backlight_device_unregister (priv->bl_dev); +return -EINVAL ; + } + } +for (i =0 ; i < priv->nb_leds; i++) {mutex_lock (&priv->leds[i]->led_access);led_sysfs_disable (priv->leds[i]);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 151/634 backlight: lp855x: Fix lp855x.h kernel-doc warnings
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Randy Dunlap <[email protected]>
[ Upstream commit 2d45db63260c6ae3cf007361e04a1c41bd265084 ]
Add a missing struct short description and a missing leading " *" to lp855x.h to avoid kernel-doc warnings:
Warning: include/linux/platform_data/lp855x.h:126 missing initial short
description on line:
* struct lp855x_platform_data
Warning: include/linux/platform_data/lp855x.h:131 bad line:
Only valid when mode is PWM_BASED.
--- include/linux/platform_data/lp855x.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/platform_data/lp855x.h +2 -2
@@ -124,12 +124,12 @@ struct lp855x_rom_data { };/** -* struct lp855x_platform_data +* struct lp855x_platform_data - lp855 platform-specific data * @name : Backlight driver name. If it is not defined, default name is set. * @device_control : value of DEVICE CONTROL register * @initial_brightness : initial value of backlight brightness * @period_ns : platform specific pwm period value. unit is nano. -Only valid when mode is PWM_BASED. +* Only valid when mode is PWM_BASED. * @size_program : total size of lp855x_rom_data * @rom_data : list of new eeprom/eprom registers */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 152/634 iommu/arm-smmu-qcom: Enable use of all SMR groups when running bare-metal
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephan Gerhold <[email protected]>
[ Upstream commit 5583a55e074b33ccd88ac0542fd7cd656a7e2c8c ]
Some platforms (e.g. SC8280XP and X1E) support more than 128 stream matching groups. This is more than what is defined as maximum by the ARM SMMU architecture specification. Commit 122611347326 ("iommu/arm-smmu-qcom:
Limit the SMR groups to 128") disabled use of the additional groups because they don't exhibit the same behavior as the architecture supported ones.
It seems like this is just another quirk of the hypervisor: When running bare-metal without the hypervisor, the additional groups appear to behave just like all others. The boot firmware uses some of the additional groups, so ignoring them in this situation leads to stream match conflicts whenever we allocate a new SMR group for the same SID.
The workaround exists primarily because the bypass quirk detection fails when using a S2CR register from the additional matching groups, so let's perform the test with the last reliable S2CR (127) and then limit the number of SMR groups only if we detect that we are running below the hypervisor (because of the bypass quirk).
--- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 27 ++++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-)
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +17 -10
@@ -282,17 +282,19 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)/* * Some platforms support more than the Arm SMMU architected maximum of -* 128 stream matching groups. For unknown reasons, the additional -* groups don't exhibit the same behavior as the architected registers, -* so limit the groups to 128 until the behavior is fixed for the other -* groups. +* 128 stream matching groups. The additional registers appear to have +* the same behavior as the architected registers in the hardware. +* However, on some firmware versions, the hypervisor does not +* correctly trap and emulate accesses to the additional registers, +* resulting in unexpected behavior. +* +* If there are more than 128 groups, use the last reliable group to +* detect if we need to apply the bypass quirk. */ -if (smmu->num_mapping_groups >128 ) { -dev_notice (smmu->dev,"\tLimiting the stream matching groups to 128\n" ); - smmu->num_mapping_groups =128 ; - } - - last_s2cr =ARM_SMMU_GR0_S2CR (smmu->num_mapping_groups -1 ); +if (smmu->num_mapping_groups >128 ) + last_s2cr =ARM_SMMU_GR0_S2CR (127 ); +else + last_s2cr =ARM_SMMU_GR0_S2CR (smmu->num_mapping_groups -1 );/* * With some firmware versions writes to S2CR of type FAULT are
@@ -315,6 +317,11 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) reg =FIELD_PREP (ARM_SMMU_CBAR_TYPE ,CBAR_TYPE_S1_TRANS_S2_BYPASS );arm_smmu_gr1_write (smmu,ARM_SMMU_GR1_CBAR (qsmmu->bypass_cbndx), reg); + +if (smmu->num_mapping_groups >128 ) { +dev_notice (smmu->dev,"\tLimiting the stream matching groups to 128\n" ); + smmu->num_mapping_groups =128 ; + } }for (i =0 ; i < smmu->num_mapping_groups; i++) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 153/634 RDMA/irdma: Fix data race in irdma_sc_ccq_arm
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Czurylo <[email protected]>
[ Upstream commit a521928164433de44fed5aaf5f49aeb3f1fb96f5 ]
Adds a lock around irdma_sc_ccq_arm body to prevent inter-thread data race. Fixes data race in irdma_sc_ccq_arm() reported by KCSAN:
BUG: KCSAN: data-race in irdma_sc_ccq_arm [irdma] / irdma_sc_ccq_arm [irdma]
read to 0xffff9d51b4034220 of 8 bytes by task 255 on cpu 11:
irdma_sc_ccq_arm+0x36/0xd0 [irdma] irdma_cqp_ce_handler+0x300/0x310 [irdma] cqp_compl_worker+0x2a/0x40 [irdma] process_one_work+0x402/0x7e0 worker_thread+0xb3/0x6d0 kthread+0x178/0x1a0 ret_from_fork+0x2c/0x50
write to 0xffff9d51b4034220 of 8 bytes by task 89 on cpu 3:
irdma_sc_ccq_arm+0x7e/0xd0 [irdma] irdma_cqp_ce_handler+0x300/0x310 [irdma] irdma_wait_event+0xd4/0x3e0 [irdma] irdma_handle_cqp_op+0xa5/0x220 [irdma] irdma_hw_flush_wqes+0xb1/0x300 [irdma] irdma_flush_wqes+0x22e/0x3a0 [irdma] irdma_cm_disconn_true+0x4c7/0x5d0 [irdma] irdma_disconnect_worker+0x35/0x50 [irdma] process_one_work+0x402/0x7e0 worker_thread+0xb3/0x6d0 kthread+0x178/0x1a0 ret_from_fork+0x2c/0x50
value changed: 0x0000000000024000 -> 0x0000000000034000
--- drivers/infiniband/hw/irdma/ctrl.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/infiniband/hw/irdma/ctrl.c +3 -0
@@ -3303,11 +3303,13 @@ int irdma_sc_cqp_destroy(struct irdma_sc_cqp *cqp)*/ void irdma_sc_ccq_arm (struct irdma_sc_cq *ccq) { +unsigned long flags;u64 temp_val;u16 sw_cq_sel;u8 arm_next_se;u8 arm_seq_num; +spin_lock_irqsave (&ccq->dev->cqp_lock, flags);get_64bit_val (ccq->cq_uk.shadow_area,32 , &temp_val); sw_cq_sel = (u16 )FIELD_GET (IRDMA_CQ_DBSA_SW_CQ_SELECT , temp_val); arm_next_se = (u8 )FIELD_GET (IRDMA_CQ_DBSA_ARM_NEXT_SE , temp_val);
@@ -3318,6 +3320,7 @@ void irdma_sc_ccq_arm(struct irdma_sc_cq *ccq)FIELD_PREP (IRDMA_CQ_DBSA_ARM_NEXT_SE , arm_next_se) |FIELD_PREP (IRDMA_CQ_DBSA_ARM_NEXT ,1 );set_64bit_val (ccq->cq_uk.shadow_area,32 , temp_val); +spin_unlock_irqrestore (&ccq->dev->cqp_lock, flags);dma_wmb ();/* make sure shadow area is updated before arming */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 154/634 RDMA/irdma: Fix data race in irdma_free_pble
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Czurylo <[email protected]>
[ Upstream commit 81f44409fb4f027d1e6d54edbeba5156ad94b214 ]
Protects pble_rsrc counters with mutex to prevent data race. Fixes the following data race in irdma_free_pble reported by KCSAN:
BUG: KCSAN: data-race in irdma_free_pble [irdma] / irdma_free_pble [irdma]
write to 0xffff91430baa0078 of 8 bytes by task 16956 on cpu 5:
irdma_free_pble+0x3b/0xb0 [irdma] irdma_dereg_mr+0x108/0x110 [irdma] ib_dereg_mr_user+0x74/0x160 [ib_core] uverbs_free_mr+0x26/0x30 [ib_uverbs] destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs] uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs] uobj_destroy+0x61/0xb0 [ib_uverbs] ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs] ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs] ib_uverbs_ioctl+0x111/0x190 [ib_uverbs] __x64_sys_ioctl+0xc9/0x100 do_syscall_64+0x44/0xa0 entry_SYSCALL_64_after_hwframe+0x6e/0xd8
read to 0xffff91430baa0078 of 8 bytes by task 16953 on cpu 2:
irdma_free_pble+0x23/0xb0 [irdma] irdma_dereg_mr+0x108/0x110 [irdma] ib_dereg_mr_user+0x74/0x160 [ib_core] uverbs_free_mr+0x26/0x30 [ib_uverbs] destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs] uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs] uobj_destroy+0x61/0xb0 [ib_uverbs] ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs] ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs] ib_uverbs_ioctl+0x111/0x190 [ib_uverbs] __x64_sys_ioctl+0xc9/0x100 do_syscall_64+0x44/0xa0 entry_SYSCALL_64_after_hwframe+0x6e/0xd8
value changed: 0x0000000000005a62 -> 0x0000000000005a68
--- drivers/infiniband/hw/irdma/pble.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/infiniband/hw/irdma/pble.c +4 -2
@@ -498,12 +498,14 @@ int irdma_get_pble(struct irdma_hmc_pble_rsrc *pble_rsrc,void irdma_free_pble (struct irdma_hmc_pble_rsrc *pble_rsrc,struct irdma_pble_alloc *palloc) { - pble_rsrc->freedpbles += palloc->total_cnt; -if (palloc->level ==PBLE_LEVEL_2 )free_lvl2 (pble_rsrc, palloc);else irdma_prm_return_pbles (&pble_rsrc->pinfo, &palloc->level1.chunkinfo); + +mutex_lock (&pble_rsrc->pble_mutex_lock); + pble_rsrc->freedpbles += palloc->total_cnt; pble_rsrc->stats_alloc_freed++; +mutex_unlock (&pble_rsrc->pble_mutex_lock); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 155/634 ASoC: fsl_xcvr: Add Counter registers
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit 107d170dc46e14cfa575d1b995107ef2f2e51dfe ]
These counter registers are part of register list, add them to complete the register map
- DMAC counter control registers
- Data path Timestamp counter register
- Data path bit counter register
- Data path bit count timestamp register
- Data path bit read timestamp register
Stable-dep-of: 73b97d46dde6 ("ASoC: fsl_xcvr: clear the channel status control memory")
--- sound/soc/fsl/fsl_xcvr.c | 40 ++++++++++++++++++++++++++++++++++++++++ sound/soc/fsl/fsl_xcvr.h | 21 +++++++++++++++++++++ 2 files changed, 61 insertions(+)
sound/soc/fsl/fsl_xcvr.c +40 -0
@@ -934,6 +934,14 @@ static const struct reg_default fsl_xcvr_reg_defaults[] = { { FSL_XCVR_RX_DPTH_CTRL_SET, 0x00002C89 }, { FSL_XCVR_RX_DPTH_CTRL_CLR, 0x00002C89 }, { FSL_XCVR_RX_DPTH_CTRL_TOG, 0x00002C89 }, + { FSL_XCVR_RX_DPTH_CNTR_CTRL, 0x00000000 }, + { FSL_XCVR_RX_DPTH_CNTR_CTRL_SET, 0x00000000 }, + { FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR, 0x00000000 }, + { FSL_XCVR_RX_DPTH_CNTR_CTRL_TOG, 0x00000000 }, + { FSL_XCVR_RX_DPTH_TSCR, 0x00000000 }, + { FSL_XCVR_RX_DPTH_BCR, 0x00000000 }, + { FSL_XCVR_RX_DPTH_BCTR, 0x00000000 }, + { FSL_XCVR_RX_DPTH_BCRR, 0x00000000 }, { FSL_XCVR_TX_DPTH_CTRL, 0x00000000 }, { FSL_XCVR_TX_DPTH_CTRL_SET, 0x00000000 }, { FSL_XCVR_TX_DPTH_CTRL_CLR, 0x00000000 },
@@ -944,6 +952,14 @@ static const struct reg_default fsl_xcvr_reg_defaults[] = { { FSL_XCVR_TX_CS_DATA_3, 0x00000000 }, { FSL_XCVR_TX_CS_DATA_4, 0x00000000 }, { FSL_XCVR_TX_CS_DATA_5, 0x00000000 }, + { FSL_XCVR_TX_DPTH_CNTR_CTRL, 0x00000000 }, + { FSL_XCVR_TX_DPTH_CNTR_CTRL_SET, 0x00000000 }, + { FSL_XCVR_TX_DPTH_CNTR_CTRL_CLR, 0x00000000 }, + { FSL_XCVR_TX_DPTH_CNTR_CTRL_TOG, 0x00000000 }, + { FSL_XCVR_TX_DPTH_TSCR, 0x00000000 }, + { FSL_XCVR_TX_DPTH_BCR, 0x00000000 }, + { FSL_XCVR_TX_DPTH_BCTR, 0x00000000 }, + { FSL_XCVR_TX_DPTH_BCRR, 0x00000000 }, { FSL_XCVR_DEBUG_REG_0, 0x00000000 }, { FSL_XCVR_DEBUG_REG_1, 0x00000000 }, };
@@ -975,6 +991,14 @@ static bool fsl_xcvr_readable_reg(struct device *dev, unsigned int reg)case FSL_XCVR_RX_DPTH_CTRL_SET :case FSL_XCVR_RX_DPTH_CTRL_CLR :case FSL_XCVR_RX_DPTH_CTRL_TOG : +case FSL_XCVR_RX_DPTH_CNTR_CTRL : +case FSL_XCVR_RX_DPTH_CNTR_CTRL_SET : +case FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR : +case FSL_XCVR_RX_DPTH_CNTR_CTRL_TOG : +case FSL_XCVR_RX_DPTH_TSCR : +case FSL_XCVR_RX_DPTH_BCR : +case FSL_XCVR_RX_DPTH_BCTR : +case FSL_XCVR_RX_DPTH_BCRR :case FSL_XCVR_TX_DPTH_CTRL :case FSL_XCVR_TX_DPTH_CTRL_SET :case FSL_XCVR_TX_DPTH_CTRL_CLR :
@@ -985,6 +1009,14 @@ static bool fsl_xcvr_readable_reg(struct device *dev, unsigned int reg)case FSL_XCVR_TX_CS_DATA_3 :case FSL_XCVR_TX_CS_DATA_4 :case FSL_XCVR_TX_CS_DATA_5 : +case FSL_XCVR_TX_DPTH_CNTR_CTRL : +case FSL_XCVR_TX_DPTH_CNTR_CTRL_SET : +case FSL_XCVR_TX_DPTH_CNTR_CTRL_CLR : +case FSL_XCVR_TX_DPTH_CNTR_CTRL_TOG : +case FSL_XCVR_TX_DPTH_TSCR : +case FSL_XCVR_TX_DPTH_BCR : +case FSL_XCVR_TX_DPTH_BCTR : +case FSL_XCVR_TX_DPTH_BCRR :case FSL_XCVR_DEBUG_REG_0 :case FSL_XCVR_DEBUG_REG_1 :return true;
@@ -1017,6 +1049,10 @@ static bool fsl_xcvr_writeable_reg(struct device *dev, unsigned int reg)case FSL_XCVR_RX_DPTH_CTRL_SET :case FSL_XCVR_RX_DPTH_CTRL_CLR :case FSL_XCVR_RX_DPTH_CTRL_TOG : +case FSL_XCVR_RX_DPTH_CNTR_CTRL : +case FSL_XCVR_RX_DPTH_CNTR_CTRL_SET : +case FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR : +case FSL_XCVR_RX_DPTH_CNTR_CTRL_TOG :case FSL_XCVR_TX_DPTH_CTRL_SET :case FSL_XCVR_TX_DPTH_CTRL_CLR :case FSL_XCVR_TX_DPTH_CTRL_TOG :
@@ -1026,6 +1062,10 @@ static bool fsl_xcvr_writeable_reg(struct device *dev, unsigned int reg)case FSL_XCVR_TX_CS_DATA_3 :case FSL_XCVR_TX_CS_DATA_4 :case FSL_XCVR_TX_CS_DATA_5 : +case FSL_XCVR_TX_DPTH_CNTR_CTRL : +case FSL_XCVR_TX_DPTH_CNTR_CTRL_SET : +case FSL_XCVR_TX_DPTH_CNTR_CTRL_CLR : +case FSL_XCVR_TX_DPTH_CNTR_CTRL_TOG :return true;default :return false;
sound/soc/fsl/fsl_xcvr.h +21 -0
@@ -49,6 +49,16 @@#define FSL_XCVR_RX_DPTH_CTRL_CLR 0x188#define FSL_XCVR_RX_DPTH_CTRL_TOG 0x18c +#define FSL_XCVR_RX_DPTH_CNTR_CTRL 0x1C0 +#define FSL_XCVR_RX_DPTH_CNTR_CTRL_SET 0x1C4 +#define FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR 0x1C8 +#define FSL_XCVR_RX_DPTH_CNTR_CTRL_TOG 0x1CC + +#define FSL_XCVR_RX_DPTH_TSCR 0x1D0 +#define FSL_XCVR_RX_DPTH_BCR 0x1D4 +#define FSL_XCVR_RX_DPTH_BCTR 0x1D8 +#define FSL_XCVR_RX_DPTH_BCRR 0x1DC +#define FSL_XCVR_TX_DPTH_CTRL 0x220/* TX datapath ctrl reg */ #define FSL_XCVR_TX_DPTH_CTRL_SET 0x224#define FSL_XCVR_TX_DPTH_CTRL_CLR 0x228
@@ -59,6 +69,17 @@#define FSL_XCVR_TX_CS_DATA_3 0x23C#define FSL_XCVR_TX_CS_DATA_4 0x240#define FSL_XCVR_TX_CS_DATA_5 0x244 + +#define FSL_XCVR_TX_DPTH_CNTR_CTRL 0x260 +#define FSL_XCVR_TX_DPTH_CNTR_CTRL_SET 0x264 +#define FSL_XCVR_TX_DPTH_CNTR_CTRL_CLR 0x268 +#define FSL_XCVR_TX_DPTH_CNTR_CTRL_TOG 0x26C + +#define FSL_XCVR_TX_DPTH_TSCR 0x270 +#define FSL_XCVR_TX_DPTH_BCR 0x274 +#define FSL_XCVR_TX_DPTH_BCTR 0x278 +#define FSL_XCVR_TX_DPTH_BCRR 0x27C +#define FSL_XCVR_DEBUG_REG_0 0x2E0#define FSL_XCVR_DEBUG_REG_1 0x2F0
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 156/634 ASoC: fsl_xcvr: Add support for i.MX93 platform
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chancel Liu <[email protected]>
[ Upstream commit e240b9329a300af7b7c1eba2ce0abbf19e6c540b ]
Add compatible string and specific soc data to support XCVR on i.MX93 platform. XCVR IP on i.MX93 is cut to SPDIF only by removing external PHY.
Stable-dep-of: 73b97d46dde6 ("ASoC: fsl_xcvr: clear the channel status control memory")
--- sound/soc/fsl/fsl_xcvr.c | 143 ++++++++++++++++++++++++++------------- sound/soc/fsl/fsl_xcvr.h | 7 ++ 2 files changed, 102 insertions(+), 48 deletions(-)
sound/soc/fsl/fsl_xcvr.c +95 -48
@@ -21,6 +21,7 @@struct fsl_xcvr_soc_data {const char *fw_name; +bool spdif_only; };struct fsl_xcvr {
@@ -261,6 +262,9 @@ static int fsl_xcvr_en_phy_pll(struct fsl_xcvr *xcvr, u32 freq, bool tx)u32 i, div =0 , log2;int ret; +if (xcvr->soc_data->spdif_only) +return 0 ; +for (i =0 ; i <ARRAY_SIZE (fsl_xcvr_pll_cfg); i++) {if (fsl_xcvr_pll_cfg[i].fout % freq ==0 ) { div = fsl_xcvr_pll_cfg[i].fout / freq;
@@ -353,6 +357,7 @@ static int fsl_xcvr_en_aud_pll(struct fsl_xcvr *xcvr, u32 freq)struct device *dev = &xcvr->pdev->dev;int ret; + freq = xcvr->soc_data->spdif_only ? freq /10 : freq;clk_disable_unprepare (xcvr->phy_clk); ret =clk_set_rate (xcvr->phy_clk, freq);if (ret <0 ) {
@@ -365,6 +370,8 @@ static int fsl_xcvr_en_aud_pll(struct fsl_xcvr *xcvr, u32 freq)return ret; } +if (xcvr->soc_data->spdif_only) +return 0 ;/* Release AI interface from reset */ ret =regmap_write (xcvr->regmap,FSL_XCVR_PHY_AI_CTRL_SET ,FSL_XCVR_PHY_AI_CTRL_AI_RESETN );
@@ -547,10 +554,12 @@ static int fsl_xcvr_startup(struct snd_pcm_substream *substream, xcvr->streams |=BIT (substream->stream); -/* Disable XCVR controls if there is stream started */ -fsl_xcvr_activate_ctl (dai, fsl_xcvr_mode_kctl.name, false); -fsl_xcvr_activate_ctl (dai, fsl_xcvr_arc_mode_kctl.name, false); -fsl_xcvr_activate_ctl (dai, fsl_xcvr_earc_capds_kctl.name, false); +if (!xcvr->soc_data->spdif_only) { +/* Disable XCVR controls if there is stream started */ +fsl_xcvr_activate_ctl (dai, fsl_xcvr_mode_kctl.name, false); +fsl_xcvr_activate_ctl (dai, fsl_xcvr_arc_mode_kctl.name, false); +fsl_xcvr_activate_ctl (dai, fsl_xcvr_earc_capds_kctl.name, false); + }return 0 ; }
@@ -567,12 +576,13 @@ static void fsl_xcvr_shutdown(struct snd_pcm_substream *substream,/* Enable XCVR controls if there is no stream started */ if (!xcvr->streams) { -fsl_xcvr_activate_ctl (dai, fsl_xcvr_mode_kctl.name, true); -fsl_xcvr_activate_ctl (dai, fsl_xcvr_arc_mode_kctl.name, - (xcvr->mode ==FSL_XCVR_MODE_ARC )); -fsl_xcvr_activate_ctl (dai, fsl_xcvr_earc_capds_kctl.name, - (xcvr->mode ==FSL_XCVR_MODE_EARC )); - +if (!xcvr->soc_data->spdif_only) { +fsl_xcvr_activate_ctl (dai, fsl_xcvr_mode_kctl.name, true); +fsl_xcvr_activate_ctl (dai, fsl_xcvr_arc_mode_kctl.name, + (xcvr->mode ==FSL_XCVR_MODE_ARC )); +fsl_xcvr_activate_ctl (dai, fsl_xcvr_earc_capds_kctl.name, + (xcvr->mode ==FSL_XCVR_MODE_EARC )); + } ret =regmap_update_bits (xcvr->regmap,FSL_XCVR_EXT_IER0 ,FSL_XCVR_IRQ_EARC_ALL ,0 );if (ret <0 ) {
@@ -673,7 +683,10 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,dev_err (dai->dev,"Failed to stop DATA_TX: %d\n" , ret);return ret; } - fallthrough; +if (xcvr->soc_data->spdif_only) +break ; +else + fallthrough;case FSL_XCVR_MODE_EARC :/* clear ISR_CMDC_TX_EN, W1C */ ret = regmap_write(xcvr->regmap,
@@ -870,9 +883,13 @@ static int fsl_xcvr_dai_probe(struct snd_soc_dai *dai)snd_soc_dai_init_dma_data (dai, &xcvr->dma_prms_tx, &xcvr->dma_prms_rx); -snd_soc_add_dai_controls (dai, &fsl_xcvr_mode_kctl,1 ); -snd_soc_add_dai_controls (dai, &fsl_xcvr_arc_mode_kctl,1 ); -snd_soc_add_dai_controls (dai, &fsl_xcvr_earc_capds_kctl,1 ); +if (xcvr->soc_data->spdif_only) + xcvr->mode =FSL_XCVR_MODE_SPDIF ; +else { +snd_soc_add_dai_controls (dai, &fsl_xcvr_mode_kctl,1 ); +snd_soc_add_dai_controls (dai, &fsl_xcvr_arc_mode_kctl,1 ); +snd_soc_add_dai_controls (dai, &fsl_xcvr_earc_capds_kctl,1 ); + }snd_soc_add_dai_controls (dai, fsl_xcvr_tx_ctls,ARRAY_SIZE (fsl_xcvr_tx_ctls)); snd_soc_add_dai_controls(dai, fsl_xcvr_rx_ctls,
@@ -930,10 +947,11 @@ static const struct reg_default fsl_xcvr_reg_defaults[] = { { FSL_XCVR_ISR_SET, 0x00000000 }, { FSL_XCVR_ISR_CLR, 0x00000000 }, { FSL_XCVR_ISR_TOG, 0x00000000 }, - { FSL_XCVR_RX_DPTH_CTRL, 0x00002C89 }, - { FSL_XCVR_RX_DPTH_CTRL_SET, 0x00002C89 }, - { FSL_XCVR_RX_DPTH_CTRL_CLR, 0x00002C89 }, - { FSL_XCVR_RX_DPTH_CTRL_TOG, 0x00002C89 }, + { FSL_XCVR_CLK_CTRL, 0x0000018F }, + { FSL_XCVR_RX_DPTH_CTRL, 0x00040CC1 }, + { FSL_XCVR_RX_DPTH_CTRL_SET, 0x00040CC1 }, + { FSL_XCVR_RX_DPTH_CTRL_CLR, 0x00040CC1 }, + { FSL_XCVR_RX_DPTH_CTRL_TOG, 0x00040CC1 }, { FSL_XCVR_RX_DPTH_CNTR_CTRL, 0x00000000 }, { FSL_XCVR_RX_DPTH_CNTR_CTRL_SET, 0x00000000 }, { FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR, 0x00000000 },
@@ -966,6 +984,12 @@ static const struct reg_default fsl_xcvr_reg_defaults[] = {static bool fsl_xcvr_readable_reg (struct device *dev,unsigned int reg) { +struct fsl_xcvr *xcvr =dev_get_drvdata (dev); + +if (xcvr->soc_data->spdif_only) +if ((reg >=FSL_XCVR_IER && reg <=FSL_XCVR_PHY_AI_RDATA ) || + reg >FSL_XCVR_TX_DPTH_BCRR ) +return false;switch (reg) {case FSL_XCVR_VERSION :case FSL_XCVR_EXT_CTRL :
@@ -991,6 +1015,12 @@ static bool fsl_xcvr_readable_reg(struct device *dev, unsigned int reg)case FSL_XCVR_RX_DPTH_CTRL_SET :case FSL_XCVR_RX_DPTH_CTRL_CLR :case FSL_XCVR_RX_DPTH_CTRL_TOG : +case FSL_XCVR_RX_CS_DATA_0 : +case FSL_XCVR_RX_CS_DATA_1 : +case FSL_XCVR_RX_CS_DATA_2 : +case FSL_XCVR_RX_CS_DATA_3 : +case FSL_XCVR_RX_CS_DATA_4 : +case FSL_XCVR_RX_CS_DATA_5 :case FSL_XCVR_RX_DPTH_CNTR_CTRL :case FSL_XCVR_RX_DPTH_CNTR_CTRL_SET :case FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR :
@@ -1027,6 +1057,11 @@ static bool fsl_xcvr_readable_reg(struct device *dev, unsigned int reg)static bool fsl_xcvr_writeable_reg (struct device *dev,unsigned int reg) { +struct fsl_xcvr *xcvr =dev_get_drvdata (dev); + +if (xcvr->soc_data->spdif_only) +if (reg >=FSL_XCVR_IER && reg <=FSL_XCVR_PHY_AI_RDATA ) +return false;switch (reg) {case FSL_XCVR_EXT_CTRL :case FSL_XCVR_EXT_IER0 :
@@ -1103,32 +1138,34 @@ static irqreturn_t irq0_isr(int irq, void *devid)if (isr &FSL_XCVR_IRQ_NEW_CS ) {dev_dbg (dev,"Received new CS block\n" ); isr_clr |=FSL_XCVR_IRQ_NEW_CS ; -/* Data RAM is 4KiB, last two pages: 8 and 9. Select page 8. */ -regmap_update_bits (xcvr->regmap,FSL_XCVR_EXT_CTRL , -FSL_XCVR_EXT_CTRL_PAGE_MASK , -FSL_XCVR_EXT_CTRL_PAGE (8 )); - -/* Find updated CS buffer */ - reg_ctrl = xcvr->ram_addr +FSL_XCVR_RX_CS_CTRL_0 ; - reg_buff = xcvr->ram_addr +FSL_XCVR_RX_CS_BUFF_0 ; -memcpy_fromio (&val, reg_ctrl,sizeof (val)); -if (!val) { - reg_ctrl = xcvr->ram_addr +FSL_XCVR_RX_CS_CTRL_1 ; - reg_buff = xcvr->ram_addr +FSL_XCVR_RX_CS_BUFF_1 ; +if (!xcvr->soc_data->spdif_only) { +/* Data RAM is 4KiB, last two pages: 8 and 9. Select page 8. */ +regmap_update_bits (xcvr->regmap,FSL_XCVR_EXT_CTRL , +FSL_XCVR_EXT_CTRL_PAGE_MASK , +FSL_XCVR_EXT_CTRL_PAGE (8 )); + +/* Find updated CS buffer */ + reg_ctrl = xcvr->ram_addr +FSL_XCVR_RX_CS_CTRL_0 ; + reg_buff = xcvr->ram_addr +FSL_XCVR_RX_CS_BUFF_0 ;memcpy_fromio (&val, reg_ctrl,sizeof (val)); - } +if (!val) { + reg_ctrl = xcvr->ram_addr +FSL_XCVR_RX_CS_CTRL_1 ; + reg_buff = xcvr->ram_addr +FSL_XCVR_RX_CS_BUFF_1 ; +memcpy_fromio (&val, reg_ctrl,sizeof (val)); + } -if (val) { -/* copy CS buffer */ -memcpy_fromio (&xcvr->rx_iec958.status, reg_buff, -sizeof (xcvr->rx_iec958.status)); -for (i =0 ; i <6 ; i++) { - val = *(u32 *)(xcvr->rx_iec958.status + i*4 ); - *(u32 *)(xcvr->rx_iec958.status + i*4 ) = -bitrev32 (val); +if (val) { +/* copy CS buffer */ +memcpy_fromio (&xcvr->rx_iec958.status, reg_buff, +sizeof (xcvr->rx_iec958.status)); +for (i =0 ; i <6 ; i++) { + val = *(u32 *)(xcvr->rx_iec958.status + i*4 ); + *(u32 *)(xcvr->rx_iec958.status + i*4 ) = +bitrev32 (val); + } +/* clear CS control register */ +memset_io (reg_ctrl,0 ,sizeof (val)); } -/* clear CS control register */ -memset_io (reg_ctrl,0 ,sizeof (val)); } }if (isr &FSL_XCVR_IRQ_NEW_UD ) {
@@ -1168,8 +1205,13 @@ static const struct fsl_xcvr_soc_data fsl_xcvr_imx8mp_data = { .fw_name = "imx/xcvr/xcvr-imx8mp.bin", }; +static const struct fsl_xcvr_soc_data fsl_xcvr_imx93_data = { + .spdif_only = true, +}; +static const struct of_device_id fsl_xcvr_dt_ids[] = { { .compatible ="fsl,imx8mp-xcvr" , .data = &fsl_xcvr_imx8mp_data }, + { .compatible ="fsl,imx93-xcvr" , .data = &fsl_xcvr_imx93_data}, {/* sentinel */ } };MODULE_DEVICE_TABLE (of, fsl_xcvr_dt_ids);
@@ -1229,7 +1271,7 @@ static int fsl_xcvr_probe(struct platform_device *pdev)return PTR_ERR (xcvr->regmap); } - xcvr->reset =devm_reset_control_get_exclusive (dev,NULL ); + xcvr->reset =devm_reset_control_get_optional_exclusive (dev,NULL );if (IS_ERR (xcvr->reset)) {dev_err (dev,"failed to get XCVR reset control\n" );return PTR_ERR (xcvr->reset);
@@ -1306,12 +1348,14 @@ static __maybe_unused int fsl_xcvr_runtime_suspend(struct device *dev)if (ret <0 )dev_err (dev,"Failed to clear IER0: %d\n" , ret); -/* Assert M0+ reset */ - ret =regmap_update_bits (xcvr->regmap,FSL_XCVR_EXT_CTRL , -FSL_XCVR_EXT_CTRL_CORE_RESET , -FSL_XCVR_EXT_CTRL_CORE_RESET ); -if (ret <0 ) -dev_err (dev,"Failed to assert M0+ core: %d\n" , ret); +if (!xcvr->soc_data->spdif_only) { +/* Assert M0+ reset */ + ret =regmap_update_bits (xcvr->regmap,FSL_XCVR_EXT_CTRL , +FSL_XCVR_EXT_CTRL_CORE_RESET , +FSL_XCVR_EXT_CTRL_CORE_RESET ); +if (ret <0 ) +dev_err (dev,"Failed to assert M0+ core: %d\n" , ret); + }regcache_cache_only (xcvr->regmap, true);
@@ -1367,6 +1411,9 @@ static __maybe_unused int fsl_xcvr_runtime_resume(struct device *dev) goto stop_spba_clk; } +if (xcvr->soc_data->spdif_only) +return 0 ; + ret =reset_control_deassert (xcvr->reset);if (ret) {dev_err (dev,"failed to deassert M0+ reset.\n" );
sound/soc/fsl/fsl_xcvr.h +7 -0
@@ -49,6 +49,13 @@#define FSL_XCVR_RX_DPTH_CTRL_CLR 0x188#define FSL_XCVR_RX_DPTH_CTRL_TOG 0x18c +#define FSL_XCVR_RX_CS_DATA_0 0x190 +#define FSL_XCVR_RX_CS_DATA_1 0x194 +#define FSL_XCVR_RX_CS_DATA_2 0x198 +#define FSL_XCVR_RX_CS_DATA_3 0x19C +#define FSL_XCVR_RX_CS_DATA_4 0x1A0 +#define FSL_XCVR_RX_CS_DATA_5 0x1A4 +#define FSL_XCVR_RX_DPTH_CNTR_CTRL 0x1C0#define FSL_XCVR_RX_DPTH_CNTR_CTRL_SET 0x1C4#define FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR 0x1C8
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 157/634 ASoC: fsl_xcvr: clear the channel status control memory
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit 73b97d46dde64fa184d47865d4a532d818c3a007 ]
memset_io() writes memory byte by byte with __raw_writeb() on the arm platform if the size is word. but XCVR data RAM memory can't be accessed with byte address, so with memset_io() the channel status control memory is not really cleared, use writel_relaxed() instead.
--- sound/soc/fsl/fsl_xcvr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/fsl/fsl_xcvr.c +1 -1
@@ -1164,7 +1164,7 @@ static irqreturn_t irq0_isr(int irq, void *devid)bitrev32 (val); }/* clear CS control register */ -memset_io (reg_ctrl,0 ,sizeof (val)); +writel_relaxed (0 , reg_ctrl); } } }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 158/634 drm/amd/display: Fix logical vs bitwise bug in get_embedded_panel_info_v2_1()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 1a79482699b4d1e43948d14f0c7193dc1dcad858 ]
The .H_SYNC_POLARITY and .V_SYNC_POLARITY variables are 1 bit bitfields of a u32. The ATOM_HSYNC_POLARITY define is 0x2 and the ATOM_VSYNC_POLARITY is 0x4. When we do a bitwise negate of 0, 2, or 4 then the last bit is always 1 so this code always sets .H_SYNC_POLARITY and .V_SYNC_POLARITY to true.
This code is instead intended to check if the ATOM_HSYNC_POLARITY or ATOM_VSYNC_POLARITY flags are set and reverse the result. In other words, it's supposed to be a logical negate instead of a bitwise negate.
--- drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +4 -4
@@ -1480,10 +1480,10 @@ static enum bp_result get_embedded_panel_info_v2_1(/* not provided by VBIOS */ info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF =0 ; - info->lcd_timing.misc_info.H_SYNC_POLARITY = ~(uint32_t ) (lvds->lcd_timing.miscinfo - &ATOM_HSYNC_POLARITY ); - info->lcd_timing.misc_info.V_SYNC_POLARITY = ~(uint32_t ) (lvds->lcd_timing.miscinfo - &ATOM_VSYNC_POLARITY ); + info->lcd_timing.misc_info.H_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & +ATOM_HSYNC_POLARITY ); + info->lcd_timing.misc_info.V_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & +ATOM_VSYNC_POLARITY );/* not provided by VBIOS */ info->lcd_timing.misc_info.VERTICAL_CUT_OFF =0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 159/634 hwmon: sy7636a: Fix regulator_enable resource leak on error path
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit 2f88425ef590b7fcc2324334b342e048edc144a9 ]
In sy7636a_sensor_probe(), regulator_enable() is called but if devm_hwmon_device_register_with_info() fails, the function returns without calling regulator_disable(), leaving the regulator enabled and leaking the reference count.
Switch to devm_regulator_get_enable() to automatically manage the regulator resource.
--- drivers/hwmon/sy7636a-hwmon.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
drivers/hwmon/sy7636a-hwmon.c +1 -6
@@ -66,18 +66,13 @@ static const struct hwmon_chip_info sy7636a_chip_info = {static int sy7636a_sensor_probe (struct platform_device *pdev) {struct regmap *regmap =dev_get_regmap (pdev->dev.parent,NULL ); -struct regulator *regulator;struct device *hwmon_dev;int err;if (!regmap)return -EPROBE_DEFER ; - regulator =devm_regulator_get (&pdev->dev,"vcom" ); -if (IS_ERR (regulator)) -return PTR_ERR (regulator); - - err =regulator_enable (regulator); + err =devm_regulator_get_enable (&pdev->dev,"vcom" );if (err)return err;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 160/634 ACPI: processor_core: fix map_x2apic_id for amd-pstate on am4
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: René Rebe <[email protected]>
[ Upstream commit 17e7972979e147cc51d4a165e6b6b0f93273ca68 ]
On all AMD AM4 systems I have seen, e.g ASUS X470-i, Pro WS X570 Ace and equivalent Gigabyte, amd-pstate does not initialize when the x2apic is enabled in the BIOS. Kernel debug messages include:
[ 0.315438] acpi LNXCPU:00: Failed to get CPU physical ID. [ 0.354756] ACPI CPPC: No CPC descriptor for CPU:0 [ 0.714951] amd_pstate: the _CPC object is not present in SBIOS or ACPI disabled
I tracked this down to map_x2apic_id() checking device_declaration passed in via the type argument of acpi_get_phys_id() via map_madt_entry() while map_lapic_id() does not.
It appears these BIOSes use Processor statements for declaring the CPUs in the ACPI namespace instead of processor device objects (which should have been used). CPU declarations via Processor statements were deprecated in ACPI 6.0 that was released 10 years ago. They should not be used any more in any contemporary platform firmware.
I tried to contact Asus support multiple times, but never received a reply nor did any BIOS update ever change this.
Fix amd-pstate w/ x2apic on am4 by allowing map_x2apic_id() to work with CPUs declared via Processor statements for IDs less than 255, which is consistent with ACPI 5.0 that still allowed Processor statements to be used for declaring CPUs.
--- drivers/acpi/processor_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/acpi/processor_core.c +1 -1
@@ -54,7 +54,7 @@ static int map_x2apic_id(struct acpi_subtable_header *entry,if (!(apic->lapic_flags &ACPI_MADT_ENABLED ))return -ENODEV ; -if (device_declaration && (apic->uid == acpi_id)) { +if (apic->uid == acpi_id && (device_declaration || acpi_id <255 )) { *apic_id = apic->local_apic_id;return 0 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 161/634 ext4: remove unused return value of __mb_check_buddy
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kemeng Shi <[email protected]>
[ Upstream commit 133de5a0d8f8e32b34feaa8beae7a189482f1856 ]
Remove unused return value of __mb_check_buddy.
Stable-dep-of: d9ee3ff810f1 ("ext4: improve integrity checking in __mb_check_buddy by enhancing order-0 validation")
--- fs/ext4/mballoc.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
fs/ext4/mballoc.c +3 -4
@@ -666,7 +666,7 @@ do { \ } \ }while (0 ) -static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, +static void __mb_check_buddy(struct ext4_buddy *e4b, char *file,const char *function,int line) {struct super_block *sb = e4b->bd_sb;
@@ -685,7 +685,7 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file,void *buddy2;if (e4b->bd_info->bb_check_counter++ %10 ) -return 0 ; +return ;while (order >1 ) { buddy =mb_find_buddy (e4b, order, &max);
@@ -747,7 +747,7 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, grp =ext4_get_group_info (sb, e4b->bd_group);if (!grp) -return NULL ; +return ;list_for_each (cur, &grp->bb_prealloc_list) {ext4_group_t groupnr;struct ext4_prealloc_space *pa;
@@ -757,7 +757,6 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file,for (i =0 ; i < pa->pa_len; i++)MB_CHECK_ASSERT (mb_test_bit (k + i, buddy)); } -return 0 ; }#undef MB_CHECK_ASSERT#define mb_check_buddy (e4b) __mb_check_buddy(e4b, \
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 162/634 ext4: improve integrity checking in __mb_check_buddy by enhancing order-0 validation
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yongjian Sun <[email protected]>
[ Upstream commit d9ee3ff810f1cc0e253c9f2b17b668b973cb0e06 ]
When the MB_CHECK_ASSERT macro is enabled, we found that the current validation logic in __mb_check_buddy has a gap in detecting certain invalid buddy states, particularly related to order-0 (bitmap) bits.
The original logic consists of three steps:
1. Validates higher-order buddies: if a higher-order bit is set, at most one of the two corresponding lower-order bits may be free; if a higher-order bit is clear, both lower-order bits must be allocated (and their bitmap bits must be 0).
2. For any set bit in order-0, ensures all corresponding higher-order bits are not free.
3. Verifies that all preallocated blocks (pa) in the group have pa_pstart within bounds and their bitmap bits marked as allocated.
However, this approach fails to properly validate cases where order-0 bits are incorrectly cleared (0), allowing some invalid configurations to pass:
corrupt integral
order 3 1 1
order 2 1 1 1 1
order 1 1 1 1 1 1 1 1 1
order 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Here we get two adjacent free blocks at order-0 with inconsistent higher-order state, and the right one shows the correct scenario.
The root cause is insufficient validation of order-0 zero bits. To fix this and improve completeness without significant performance cost, we refine the logic:
1. Maintain the top-down higher-order validation, but we no longer check the cases where the higher-order bit is 0, as this case will be covered in step 2.
2. Enhance order-0 checking by examining pairs of bits:
- If either bit in a pair is set (1), all corresponding higher-order bits must not be free.
- If both bits are clear (0), then exactly one of the corresponding higher-order bits must be free
3. Keep the preallocation (pa) validation unchanged.
This change closes the validation gap, ensuring illegal buddy states involving order-0 are correctly detected, while removing redundant checks and maintaining efficiency.
Message-ID: <[email protected]>
--- fs/ext4/mballoc.c | 49 +++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 17 deletions(-)
fs/ext4/mballoc.c +32 -17
@@ -666,6 +666,24 @@ do { \ } \ }while (0 ) +/* +* Perform buddy integrity check with the following steps: +* +* 1. Top-down validation (from highest order down to order 1, excluding order-0 bitmap): +* For each pair of adjacent orders, if a higher-order bit is set (indicating a free block), +* at most one of the two corresponding lower-order bits may be clear (free). +* +* 2. Order-0 (bitmap) validation, performed on bit pairs: +* - If either bit in a pair is set (1, allocated), then all corresponding higher-order bits +* must not be free (0). +* - If both bits in a pair are clear (0, free), then exactly one of the corresponding +* higher-order bits must be free (0). +* +* 3. Preallocation (pa) list validation: +* For each preallocated block (pa) in the group: +* - Verify that pa_pstart falls within the bounds of this block group. +* - Ensure the corresponding bit(s) in the order-0 bitmap are marked as allocated (1). +*/ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file,const char *function,int line) {
@@ -707,15 +725,6 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file,continue ; } -/* both bits in buddy2 must be 1 */ -MB_CHECK_ASSERT (mb_test_bit (i <<1 , buddy2)); -MB_CHECK_ASSERT (mb_test_bit ((i <<1 ) +1 , buddy2)); - -for (j =0 ; j < (1 << order); j++) { - k = (i * (1 << order)) + j; -MB_CHECK_ASSERT ( - !mb_test_bit (k, e4b->bd_bitmap)); - } count++; }MB_CHECK_ASSERT (e4b->bd_info->bb_counters[order] == count);
@@ -731,15 +740,21 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, fragments++; fstart = i; } -continue ; + }else { + fstart =-1 ; } - fstart =-1 ; -/* check used bits only */ -for (j =0 ; j < e4b->bd_blkbits +1 ; j++) { - buddy2 =mb_find_buddy (e4b, j, &max2); - k = i >> j; -MB_CHECK_ASSERT (k < max2); -MB_CHECK_ASSERT (mb_test_bit (k, buddy2)); +if (!(i &1 )) { +int in_use, zero_bit_count =0 ; + + in_use =mb_test_bit (i, buddy) ||mb_test_bit (i +1 , buddy); +for (j =1 ; j < e4b->bd_blkbits +2 ; j++) { + buddy2 =mb_find_buddy (e4b, j, &max2); + k = i >> j; +MB_CHECK_ASSERT (k < max2); +if (!mb_test_bit (k, buddy2)) + zero_bit_count++; + } +MB_CHECK_ASSERT (zero_bit_count == !in_use); } }MB_CHECK_ASSERT (!EXT4_MB_GRP_NEED_INIT (e4b->bd_info));
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 163/634 virtio_vdpa: fix misleading return in void function
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alok Tiwari <[email protected]>
[ Upstream commit e40b6abe0b1247d43bc61942aa7534fca7209e44 ]
virtio_vdpa_set_status() is declared as returning void, but it used "return vdpa_set_status()" Since vdpa_set_status() also returns void, the return statement is unnecessary and misleading. Remove it.
Message-Id: <[email protected]>
--- drivers/virtio/virtio_vdpa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/virtio/virtio_vdpa.c +1 -1
@@ -92,7 +92,7 @@ static void virtio_vdpa_set_status(struct virtio_device *vdev, u8 status) {struct vdpa_device *vdpa =vd_get_vdpa (vdev); -return vdpa_set_status (vdpa, status); +vdpa_set_status (vdpa, status); }static void virtio_vdpa_reset (struct virtio_device *vdev)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 164/634 virtio: fix typo in virtio_device_ready() comment
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael S. Tsirkin <[email protected]>
[ Upstream commit 361173f95ae4b726ebbbf0bd594274f5576c4abc ]
"coherenct" -> "coherent"
Message-Id: <db286e9a65449347f6584e68c9960fd5ded2b4b0.1763026134.git.mst@redhat.com>
--- include/linux/virtio_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/virtio_config.h +1 -1
@@ -286,7 +286,7 @@ void virtio_device_ready(struct virtio_device *dev)* specific set_status() method. * * A well behaved device will only notify a virtqueue after -* DRIVER_OK, this means the device should "see" the coherenct +* DRIVER_OK, this means the device should "see" the coherent * memory write that set vq->broken as false which is done by * the driver when it sees DRIVER_OK, then the following * driver's vring_interrupt() will see vq->broken as false so
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 165/634 virtio: fix virtqueue_set_affinity() docs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael S. Tsirkin <[email protected]>
[ Upstream commit 43236d8bbafff94b423afecc4a692dd90602d426 ]
Rewrite the comment for better grammar and clarity.
Message-Id: <e317e91bd43b070e5eaec0ebbe60c5749d02e2dd.1763026134.git.mst@redhat.com>
--- include/linux/virtio_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/virtio_config.h +1 -1
@@ -308,7 +308,7 @@ const char *virtio_bus_name(struct virtio_device *vdev)* @vq: the virtqueue * @cpu_mask: the cpu mask * -* Pay attention the function are best-effort: the affinity hint may not be set +* Note that this function is best-effort: the affinity hint may not be set * due to config support, irq type and sharing. * */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 166/634 ASoC: Intel: catpt: Fix error path in hw_params()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cezary Rojewski <[email protected]>
[ Upstream commit 86a5b621be658fc8fe594ca6db317d64de30cce1 ]
Do not leave any resources hanging on the DSP side if applying user settings fails.
--- sound/soc/intel/catpt/pcm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
sound/soc/intel/catpt/pcm.c +3 -1
@@ -417,8 +417,10 @@ static int catpt_dai_hw_params(struct snd_pcm_substream *substream,return CATPT_IPC_ERROR (ret); ret =catpt_dai_apply_usettings (dai, stream); -if (ret) +if (ret) { +catpt_ipc_free_stream (cdev, stream->info.stream_hw_id);return ret; + } stream->allocated = true;return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 167/634 regulator: core: Protect regulator_supply_alias_list with regulator_list_mutex
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: sparkhuang <[email protected]>
[ Upstream commit 0cc15a10c3b4ab14cd71b779fd5c9ca0cb2bc30d ]
regulator_supply_alias_list was accessed without any locking in regulator_supply_alias(), regulator_register_supply_alias(), and regulator_unregister_supply_alias(). Concurrent registration, unregistration and lookups can race, leading to:
1 use-after-free if an alias entry is removed while being read, 2 duplicate entries when two threads register the same alias, 3 inconsistent alias mappings observed by consumers.
Protect all traversals, insertions and deletions on regulator_supply_alias_list with the existing regulator_list_mutex.
--- drivers/regulator/core.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-)
drivers/regulator/core.c +20 -12
@@ -1977,6 +1977,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) {struct regulator_supply_alias *map; +mutex_lock (®ulator_list_mutex); map =regulator_find_supply_alias (*dev, *supply);if (map) { dev_dbg(*dev, "Mapping supply %s to %s,%s\n",
@@ -1985,6 +1986,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) *dev = map->alias_dev; *supply = map->alias_supply; } +mutex_unlock (®ulator_list_mutex); }static int regulator_match (struct device *dev,const void *data)
@@ -2463,22 +2465,26 @@ int regulator_register_supply_alias(struct device *dev, const char *id, const char *alias_id) {struct regulator_supply_alias *map; +struct regulator_supply_alias *new_map; - map =regulator_find_supply_alias (dev, id); -if (map) -return -EEXIST ; - - map =kzalloc (sizeof (struct regulator_supply_alias ),GFP_KERNEL ); -if (!map) + new_map =kzalloc (sizeof (struct regulator_supply_alias ),GFP_KERNEL ); +if (!new_map)return -ENOMEM ; - map->src_dev = dev; - map->src_supply = id; - map->alias_dev = alias_dev; - map->alias_supply = alias_id; - -list_add (&map->list, ®ulator_supply_alias_list); +mutex_lock (®ulator_list_mutex); + map =regulator_find_supply_alias (dev, id); +if (map) { +mutex_unlock (®ulator_list_mutex); +kfree (new_map); +return -EEXIST ; + } + new_map->src_dev = dev; + new_map->src_supply = id; + new_map->alias_dev = alias_dev; + new_map->alias_supply = alias_id; +list_add (&new_map->list, ®ulator_supply_alias_list); +mutex_unlock (®ulator_list_mutex);pr_info ("Adding alias for supply %s,%s -> %s,%s\n" , id,dev_name (dev), alias_id,dev_name (alias_dev));
@@ -2498,11 +2504,13 @@ void regulator_unregister_supply_alias(struct device *dev, const char *id) {struct regulator_supply_alias *map; +mutex_lock (®ulator_list_mutex); map =regulator_find_supply_alias (dev, id);if (map) {list_del (&map->list);kfree (map); } +mutex_unlock (®ulator_list_mutex); }EXPORT_SYMBOL_GPL (regulator_unregister_supply_alias);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 168/634 resource: Replace printk(KERN_WARNING) by pr_warn(), printk() by pr_info()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit 2a4e628570d42fcc13a94f1acf25e3cfeaec08f6 ]
Replace printk(KERN_WARNING) by pr_warn() and printk() by pr_info().
While at it, use %pa for the resource_size_t variables. With that, for the sake of consistency, introduce a temporary variable for the end address in iomem_map_sanity_check() like it's done in another function in the same module.
Stable-dep-of: 6fb3acdebf65 ("Reinstate "resource: avoid unnecessary lookups in find_next_iomem_res()"")
--- kernel/resource.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-)
kernel/resource.c +7 -10
@@ -930,7 +930,7 @@ void insert_resource_expand_to_fit(struct resource *root, struct resource *new)if (conflict->end > new->end) new->end = conflict->end; -printk ("Expanded resource %s due to conflict with %s\n" , new->name, conflict->name); +pr_info ("Expanded resource %s due to conflict with %s\n" , new->name, conflict->name); }write_unlock (&resource_lock); }
@@ -1325,9 +1325,7 @@ void __release_region(struct resource *parent, resource_size_t start,write_unlock (&resource_lock); -printk (KERN_WARNING "Trying to free nonexistent resource " -"<%016llx-%016llx>\n" , (unsigned long long )start, - (unsigned long long )end); +pr_warn ("Trying to free nonexistent resource <%pa-%pa>\n" , &start, &end); }EXPORT_SYMBOL (__release_region);
@@ -1686,6 +1684,7 @@ __setup("reserve=", reserve_setup);int iomem_map_sanity_check (resource_size_t addr,unsigned long size) {struct resource *p = &iomem_resource; +resource_size_t end = addr + size -1 ;int err =0 ;loff_t l;
@@ -1695,12 +1694,12 @@ int iomem_map_sanity_check(resource_size_t addr, unsigned long size)* We can probably skip the resources without * IORESOURCE_IO attribute? */ -if (p->start >= addr + size) +if (p->start > end)continue ;if (p->end < addr)continue ;if (PFN_DOWN (p->start) <=PFN_DOWN (addr) && -PFN_DOWN (p->end) >=PFN_DOWN (addr + size -1 )) +PFN_DOWN (p->end) >=PFN_DOWN (end))continue ;/* * if a resource is "BUSY", it's not a hardware resource
@@ -1711,10 +1710,8 @@ int iomem_map_sanity_check(resource_size_t addr, unsigned long size)if (p->flags &IORESOURCE_BUSY )continue ; -printk (KERN_WARNING "resource sanity check: requesting [mem %#010llx-%#010llx], which spans more than %s %pR\n" , - (unsigned long long )addr, - (unsigned long long )(addr + size -1 ), - p->name, p); +pr_warn ("resource sanity check: requesting [mem %pa-%pa], which spans more than %s %pR\n" , + &addr, &end, p->name, p); err =-1 ;break ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 169/634 resource: Reuse for_each_resource() macro
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit 441f0dd8fa035a2c7cfe972047bb905d3be05c1b ]
We have a few places where for_each_resource() is open coded. Replace that by the macro. This makes code easier to read and understand.
With this, compile r_next() only for CONFIG_PROC_FS=y.
Stable-dep-of: 6fb3acdebf65 ("Reinstate "resource: avoid unnecessary lookups in find_next_iomem_res()"")
--- kernel/resource.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-)
kernel/resource.c +19 -15
@@ -77,13 +77,6 @@ static struct resource *next_resource_skip_children(struct resource *p) (_p) = (_skip_children) ? next_resource_skip_children(_p) : \ next_resource(_p)) -static void *r_next (struct seq_file *m,void *v,loff_t *pos) -{ -struct resource *p = v; - (*pos)++; -return (void *)next_resource (p); -} -#ifdef CONFIG_PROC_FS enum {MAX_IORES_LEVEL =5 };
@@ -91,14 +84,26 @@ enum { MAX_IORES_LEVEL = 5 };static void *r_start (struct seq_file *m,loff_t *pos)__acquires (resource_lock) { -struct resource *p =pde_data (file_inode (m->file)); -loff_t l =0 ; +struct resource *root =pde_data (file_inode (m->file)); +struct resource *p; +loff_t l = *pos; +read_lock (&resource_lock); -for (p = p->child; p && l < *pos; p =r_next (m, p, &l)) - ; +for_each_resource (root, p, false) { +if (l-- ==0 ) +break ; + } +return p; } +static void *r_next (struct seq_file *m,void *v,loff_t *pos) +{ +struct resource *p = v; + (*pos)++; +return (void *)next_resource (p); +} +static void r_stop (struct seq_file *m,void *v)__releases (resource_lock) {
@@ -336,7 +341,7 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end,read_lock (&resource_lock); -for (p = iomem_resource.child; p; p =next_resource (p)) { +for_each_resource (&iomem_resource, p, false) {/* If we passed the resource we are looking for, stop */ if (p->start > end) { p =NULL ;
@@ -1683,13 +1688,12 @@ __setup("reserve=", reserve_setup);*/ int iomem_map_sanity_check (resource_size_t addr,unsigned long size) { -struct resource *p = &iomem_resource;resource_size_t end = addr + size -1 ; +struct resource *p;int err =0 ; -loff_t l;read_lock (&resource_lock); -for (p = p->child; p ; p =r_next (NULL , p, &l)) { +for_each_resource (&iomem_resource, p, false) {/* * We can probably skip the resources without * IORESOURCE_IO attribute?
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 170/634 resource: replace open coded resource_intersection()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit 5c1edea773c98707fbb23d1df168bcff52f61e4b ]
Patch series "resource: A couple of cleanups".
A couple of ad-hoc cleanups since there was a recent development of the code in question. No functional changes intended.
This patch (of 2):
__region_intersects() uses open coded resource_intersection(). Replace it with existing API which also make more clear what we are checking.
Stable-dep-of: 6fb3acdebf65 ("Reinstate "resource: avoid unnecessary lookups in find_next_iomem_res()"")
--- kernel/resource.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
kernel/resource.c +6 -9
@@ -498,17 +498,16 @@ static int __region_intersects(struct resource *parent, resource_size_t start, size_t size, unsigned long flags, unsigned long desc) { - resource_size_t ostart, oend; int type = 0; int other = 0;struct resource *p, *dp; +struct resource res, o;bool is_type, covered; -struct resource res; res.start = start; res.end = start + size -1 ;for (p = parent->child; p ; p = p->sibling) { -if (!resource_overlaps (p, &res)) +if (!resource_intersection (p, &res, &o))continue ; is_type = (p->flags & flags) == flags && (desc ==IORES_DESC_NONE || desc == p->desc);
@@ -529,8 +528,6 @@ static int __region_intersects(struct resource *parent, resource_size_t start,* |-- "System RAM" --||-- "CXL Window 0a" --| */ covered = false; - ostart =max (res.start, p->start); - oend =min (res.end, p->end);for_each_resource (p, dp, false) {if (!resource_overlaps (dp, &res))continue ;
@@ -539,17 +536,17 @@ static int __region_intersects(struct resource *parent, resource_size_t start,if (is_type) { type++;/* -* Range from 'ostart' to 'dp->start' +* Range from 'o.start' to 'dp->start' * isn't covered by matched resource. */ -if (dp->start > ostart) +if (dp->start > o.start)break ; -if (dp->end >= oend) { +if (dp->end >= o.end) { covered = true;break ; }/* Remove covered range */ - ostart =max (ostart, dp->end +1 ); + o.start =max (o.start, dp->end +1 ); } }if (!covered)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 171/634 resource: introduce is_type_match() helper and use it
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit ba1eccc114ffc62c4495a5e15659190fa2c42308 ]
There are already a couple of places where we may replace a few lines of code by calling a helper, which increases readability while deduplicating the code.
Introduce is_type_match() helper and use it.
Stable-dep-of: 6fb3acdebf65 ("Reinstate "resource: avoid unnecessary lookups in find_next_iomem_res()"")
--- kernel/resource.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-)
kernel/resource.c +10 -13
@@ -310,6 +310,11 @@ int release_resource(struct resource *old)EXPORT_SYMBOL (release_resource); +static bool is_type_match (struct resource *p,unsigned long flags,unsigned long desc) +{ +return (p->flags & flags) == flags && (desc ==IORES_DESC_NONE || desc == p->desc); +} +/** * find_next_iomem_res - Finds the lowest iomem resource that covers part of * [@start..@end].
@@ -352,13 +357,9 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end,if (p->end < start)continue ; -if ((p->flags & flags) != flags) -continue ; -if ((desc !=IORES_DESC_NONE ) && (desc != p->desc)) -continue ; -/* Found a match, break */ -break ; +if (is_type_match (p, flags, desc)) +break ; }if (p) {
@@ -501,7 +502,7 @@ static int __region_intersects(struct resource *parent, resource_size_t start,int type =0 ;int other =0 ;struct resource *p, *dp;struct resource res, o; -bool is_type, covered; +bool covered; res.start = start; res.end = start + size -1 ;
@@ -509,9 +510,7 @@ static int __region_intersects(struct resource *parent, resource_size_t start,for (p = parent->child; p ; p = p->sibling) {if (!resource_intersection (p, &res, &o))continue ; - is_type = (p->flags & flags) == flags && - (desc ==IORES_DESC_NONE || desc == p->desc); -if (is_type) { +if (is_type_match (p, flags, desc)) { type++;continue ; }
@@ -531,9 +530,7 @@ static int __region_intersects(struct resource *parent, resource_size_t start,for_each_resource (p, dp, false) {if (!resource_overlaps (dp, &res))continue ; - is_type = (dp->flags & flags) == flags && - (desc ==IORES_DESC_NONE || desc == dp->desc); -if (is_type) { +if (is_type_match (dp, flags, desc)) { type++;/* * Range from 'o.start' to 'dp->start'
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 172/634 Reinstate "resource: avoid unnecessary lookups in find_next_iomem_res()"
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilias Stamatis <[email protected]>
[ Upstream commit 6fb3acdebf65a72df0a95f9fd2c901ff2bc9a3a2 ]
Commit 97523a4edb7b ("kernel/resource: remove first_lvl / siblings_only logic") removed an optimization introduced by commit 756398750e11 ("resource: avoid unnecessary lookups in find_next_iomem_res()"). That was not called out in the message of the first commit explicitly so it's not entirely clear whether removing the optimization happened inadvertently or not.
As the original commit message of the optimization explains there is no point considering the children of a subtree in find_next_iomem_res() if the top level range does not match.
Reinstating the optimization results in performance improvements in systems where /proc/iomem is ~5k lines long. Calling mmap() on /dev/mem in such platforms takes 700-1500μs without the optimisation and 10-50μs with the optimisation.
Note that even though commit 97523a4edb7b removed the 'sibling_only' parameter from next_resource(), newer kernels have basically reinstated it under the name 'skip_children'.
--- kernel/resource.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
kernel/resource.c +9 -1
@@ -336,6 +336,8 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, unsigned long flags, unsigned long desc, struct resource *res) { + /* Skip children until we find a top level range that matches */ + bool skip_children = true;struct resource *p;if (!res)
@@ -346,7 +348,7 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end,read_lock (&resource_lock); -for_each_resource (&iomem_resource, p, false) { +for_each_resource (&iomem_resource, p, skip_children) {/* If we passed the resource we are looking for, stop */ if (p->start > end) { p =NULL ;
@@ -357,6 +359,12 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end,if (p->end < start)continue ; +/* +* We found a top level range that matches what we are looking +* for. Time to start checking children too. +*/ + skip_children = false; +/* Found a match, break */ if (is_type_match (p, flags, desc))break ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 173/634 netfilter: flowtable: check for maximum number of encapsulations in bridge vlan
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
[ Upstream commit 634f3853cc98d73bdec8918010ee29b06981583e ]
Add a sanity check to skip path discovery if the maximum number of encapsulation is reached. While at it, check for underflow too.
--- net/netfilter/nft_flow_offload.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
net/netfilter/nft_flow_offload.c +8 -1
@@ -140,12 +140,19 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack, info->ingress_vlans |=BIT (info->num_encaps -1 );break ;case DEV_PATH_BR_VLAN_TAG : +if (info->num_encaps >=NF_FLOW_TABLE_ENCAP_MAX ) { + info->indev =NULL ; +break ; + } info->encap[info->num_encaps].id = path->bridge.vlan_id; info->encap[info->num_encaps].proto = path->bridge.vlan_proto; info->num_encaps++;break ;case DEV_PATH_BR_VLAN_UNTAG : - info->num_encaps--; +if (WARN_ON_ONCE (info->num_encaps-- ==0 )) { + info->indev =NULL ; +break ; + }break ;case DEV_PATH_BR_VLAN_KEEP :break ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 174/634 netfilter: nf_conncount: rework API to use sk_buff directly
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fernando Fernandez Mancera <[email protected]>
[ Upstream commit be102eb6a0e7c03db00e50540622f4e43b2d2844 ]
When using nf_conncount infrastructure for non-confirmed connections a duplicated track is possible due to an optimization introduced since commit d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC").
In order to fix this introduce a new conncount API that receives directly an sk_buff struct. It fetches the tuple and zone and the corresponding ct from it. It comes with both existing conncount variants nf_conncount_count_skb() and nf_conncount_add_skb(). In addition remove the old API and adjust all the users to use the new one.
This way, for each sk_buff struct it is possible to check if there is a ct present and already confirmed. If so, skip the add operation.
--- include/net/netfilter/nf_conntrack_count.h | 17 +- net/netfilter/nf_conncount.c | 177 ++++++++++++++------- net/netfilter/nft_connlimit.c | 21 +-- net/netfilter/xt_connlimit.c | 14 +- net/openvswitch/conntrack.c | 16 +- 5 files changed, 142 insertions(+), 103 deletions(-)
include/net/netfilter/nf_conntrack_count.h +8 -9
@@ -20,15 +20,14 @@ struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int familyvoid nf_conncount_destroy (struct net *net,unsigned int family,struct nf_conncount_data *data); -unsigned int nf_conncount_count (struct net *net, -struct nf_conncount_data *data, -const u32 *key, -const struct nf_conntrack_tuple *tuple, -const struct nf_conntrack_zone *zone); - -int nf_conncount_add (struct net *net,struct nf_conncount_list *list, -const struct nf_conntrack_tuple *tuple, -const struct nf_conntrack_zone *zone); +unsigned int nf_conncount_count_skb (struct net *net, +const struct sk_buff *skb, +u16 l3num, +struct nf_conncount_data *data, +const u32 *key); + +int nf_conncount_add_skb (struct net *net,const struct sk_buff *skb, +u16 l3num,struct nf_conncount_list *list);void nf_conncount_list_init (struct nf_conncount_list *list);
net/netfilter/nf_conncount.c +120 -57
298 lines not on this page · raw message
net/netfilter/nft_connlimit.c +3 -18
@@ -24,26 +24,11 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv,const struct nft_pktinfo *pkt, const struct nft_set_ext *ext) { - const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; -const struct nf_conntrack_tuple *tuple_ptr; -struct nf_conntrack_tuple tuple; -enum ip_conntrack_info ctinfo; -const struct nf_conn *ct; unsigned int count; +int err; - tuple_ptr = &tuple; - - ct =nf_ct_get (pkt->skb, &ctinfo); -if (ct !=NULL ) { - tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL ].tuple; - zone =nf_ct_zone (ct); - }else if (!nf_ct_get_tuplepr (pkt->skb,skb_network_offset (pkt->skb), -nft_pf (pkt),nft_net (pkt), &tuple)) { - regs->verdict.code =NF_DROP ; -return ; - } - -if (nf_conncount_add (nft_net (pkt), priv->list, tuple_ptr, zone)) { + err =nf_conncount_add_skb (nft_net (pkt), pkt->skb,nft_pf (pkt), priv->list); +if (err) { regs->verdict.code =NF_DROP ;return ; }
net/netfilter/xt_connlimit.c +3 -11
@@ -31,8 +31,6 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) {struct net *net =xt_net (par);const struct xt_connlimit_info *info = par->matchinfo; -struct nf_conntrack_tuple tuple; -const struct nf_conntrack_tuple *tuple_ptr = &tuple;const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt;enum ip_conntrack_info ctinfo;const struct nf_conn *ct;
@@ -40,13 +38,8 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)u32 key[5 ]; ct =nf_ct_get (skb, &ctinfo); -if (ct !=NULL ) { - tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL ].tuple; +if (ct) zone =nf_ct_zone (ct); - }else if (!nf_ct_get_tuplepr (skb,skb_network_offset (skb), -xt_family (par), net, &tuple)) { - goto hotdrop; - }if (xt_family (par) ==NFPROTO_IPV6 ) {const struct ipv6hdr *iph =ipv6_hdr (skb);
@@ -69,10 +62,9 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) key[1 ] = zone->id; } - connections =nf_conncount_count (net, info->data, key, tuple_ptr, - zone); + connections =nf_conncount_count_skb (net, skb,xt_family (par), info->data, key);if (connections ==0 ) -/* kmalloc failed, drop it entirely */ +/* kmalloc failed or tuple couldn't be found, drop it entirely */ goto hotdrop;return (connections > info->limit) ^ !!(info->flags &XT_CONNLIMIT_INVERT );
net/openvswitch/conntrack.c +8 -8
@@ -1166,8 +1166,8 @@ static u32 ct_limit_get(const struct ovs_ct_limit_info *info, u16 zone) }static int ovs_ct_check_limit (struct net *net, -const struct ovs_conntrack_info *info, -const struct nf_conntrack_tuple *tuple) +const struct sk_buff *skb, +const struct ovs_conntrack_info *info) {struct ovs_net *ovs_net =net_generic (net, ovs_net_id);const struct ovs_ct_limit_info *ct_limit_info = ovs_net->ct_limit_info;
@@ -1180,8 +1180,9 @@ static int ovs_ct_check_limit(struct net *net,if (per_zone_limit ==OVS_CT_LIMIT_UNLIMITED )return 0 ; - connections =nf_conncount_count (net, ct_limit_info->data, - &conncount_key, tuple, &info->zone); + connections =nf_conncount_count_skb (net, skb, info->family, + ct_limit_info->data, + &conncount_key);if (connections > per_zone_limit)return -ENOMEM ;
@@ -1210,8 +1211,7 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key,#if IS_ENABLED (CONFIG_NETFILTER_CONNCOUNT )if (static_branch_unlikely (&ovs_ct_limit_enabled)) {if (!nf_ct_is_confirmed (ct)) { - err =ovs_ct_check_limit (net, info, - &ct->tuplehash[IP_CT_DIR_ORIGINAL ].tuple); + err =ovs_ct_check_limit (net, skb, info);if (err) { net_warn_ratelimited("openvswitch: zone: %u " "exceeds conntrack limit\n",
@@ -2066,8 +2066,8 @@ static int __ovs_ct_limit_get_zone_limit(struct net *net, zone_limit.limit = limit;nf_ct_zone_init (&ct_zone, zone_id,NF_CT_DEFAULT_ZONE_DIR ,0 ); - zone_limit.count =nf_conncount_count (net, data, &conncount_key,NULL , - &ct_zone); + zone_limit.count =nf_conncount_count_skb (net,NULL ,0 , data, + &conncount_key);return nla_put_nohdr (reply,sizeof (zone_limit), &zone_limit); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 175/634 netfilter: nft_connlimit: update the count if add was skipped
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fernando Fernandez Mancera <[email protected]>
[ Upstream commit 69894e5b4c5e28cda5f32af33d4a92b7a4b93b0e ]
Connlimit expression can be used for all kind of packets and not only for packets with connection state new. See this ruleset as example:
table ip filter {
chain input {
type filter hook input priority filter; policy accept;
tcp dport 22 ct count over 4 counter
}
}Currently, if the connection count goes over the limit the counter will count the packets. When a connection is closed, the connection count won't decrement as it should because it is only updated for new connections due to an optimization on __nf_conncount_add() that prevents updating the list if the connection is duplicated.
To solve this problem, check whether the connection was skipped and if so, update the list. Adjust count_tree() too so the same fix is applied for xt_connlimit.
--- net/netfilter/nf_conncount.c | 12 ++++++++---- net/netfilter/nft_connlimit.c | 13 +++++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-)
net/netfilter/nf_conncount.c +8 -4
@@ -179,7 +179,7 @@ static int __nf_conncount_add(struct net *net,if (ct &&nf_ct_is_confirmed (ct)) {if (refcounted)nf_ct_put (ct); -return 0 ; +return -EEXIST ; }if ((u32 )jiffies == list->last_gc)
@@ -398,7 +398,7 @@ insert_tree(struct net *net,int ret; ret =nf_conncount_add_skb (net, skb, l3num, &rbconn->list); -if (ret) +if (ret && ret != -EEXIST ) count =0 ;/* hotdrop */ else count = rbconn->list.count;
@@ -501,10 +501,14 @@ count_tree(struct net *net,/* same source network -> be counted! */ ret =__nf_conncount_add (net, skb, l3num, &rbconn->list);spin_unlock_bh (&rbconn->list.list_lock); -if (ret) +if (ret && ret != -EEXIST ) {return 0 ;/* hotdrop */ -else + }else { +/* -EEXIST means add was skipped, update the list */ +if (ret == -EEXIST ) +nf_conncount_gc_list (net, &rbconn->list);return rbconn->list.count; + } } }
net/netfilter/nft_connlimit.c +11 -2
@@ -29,8 +29,17 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, err =nf_conncount_add_skb (nft_net (pkt), pkt->skb,nft_pf (pkt), priv->list);if (err) { - regs->verdict.code =NF_DROP ; -return ; +if (err == -EEXIST ) { +/* Call gc to update the list count if any connection has +* been closed already. This is useful for softlimit +* connections like limiting bandwidth based on a number +* of open connections. +*/ +nf_conncount_gc_list (nft_net (pkt), priv->list); + }else { + regs->verdict.code =NF_DROP ; +return ; + } } count = priv->list->count;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 176/634 net: stmmac: fix rx limit check in stmmac_rx_zc()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Kodanev <[email protected]>
[ Upstream commit 8048168df56e225c94e50b04cb7b0514135d7a1c ]
The extra "count >= limit" check in stmmac_rx_zc() is redundant and has no effect because the value of "count" doesn't change after the while condition at this point.
However, it can change after "read_again:" label:
while (count < limit) {
...
if (count >= limit)
break;
read_again:
...
/* XSK pool expects RX frame 1:1 mapped to XSK buffer */
if (likely(status & rx_not_ls)) {
xsk_buff_free(buf->xdp);
buf->xdp = NULL;
dirty++;
count++;
goto read_again;
}
...This patch addresses the same issue previously resolved in stmmac_rx() by commit fa02de9e7588 ("net: stmmac: fix rx budget limit check"). The fix is the same: move the check after the label to ensure that it bounds the goto loop.
--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +1 -1
@@ -5065,10 +5065,10 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) len =0 ; } +read_again:if (count >= limit)break ; -read_again: buf1_len =0 ; entry = next_entry; buf = &rx_q->buf_pool[entry];
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 177/634 mtd: rawnand: renesas: Handle devm_pm_runtime_enable() errors
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit a3623e1ae1ed6be4d49b2ccb9996a9d2b65c1828 ]
devm_pm_runtime_enable() can fail due to memory allocation failures. The current code ignores its return value and proceeds with pm_runtime_resume_and_get(), which may operate on incorrectly initialized runtime PM state.
Check the return value of devm_pm_runtime_enable() and return the error code if it fails.
--- drivers/mtd/nand/raw/renesas-nand-controller.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/mtd/nand/raw/renesas-nand-controller.c +4 -1
@@ -1342,7 +1342,10 @@ static int rnandc_probe(struct platform_device *pdev)if (IS_ERR (rnandc->regs))return PTR_ERR (rnandc->regs); -devm_pm_runtime_enable (&pdev->dev); + ret =devm_pm_runtime_enable (&pdev->dev); +if (ret) +return ret; + ret =pm_runtime_resume_and_get (&pdev->dev);if (ret <0 )return ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 178/634 mtd: lpddr_cmds: fix signed shifts in lpddr_cmds
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Stepchenko <[email protected]>
[ Upstream commit c909fec69f84b39e63876c69b9df2c178c6b76ba ]
There are several places where a value of type 'int' is shifted by lpddr->chipshift. lpddr->chipshift is derived from QINFO geometry and might reach 31 when QINFO reports a 2 GiB size - the maximum supported by LPDDR(1) compliant chips. This may cause unexpected sign-extensions when casting the integer value to the type of 'unsigned long'.
Use '1UL << lpddr->chipshift' and cast 'j' to unsigned long before shifting so the computation is performed at the destination width.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/mtd/lpddr/lpddr_cmds.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/mtd/lpddr/lpddr_cmds.c +4 -4
@@ -79,7 +79,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map)mutex_init (&shared[i].lock);for (j =0 ; j < lpddr->qinfo->HWPartsNum; j++) { *chip = lpddr->chips[i]; - chip->start += j << lpddr->chipshift; + chip->start += (unsigned long )j << lpddr->chipshift; chip->oldstate = chip->state =FL_READY ; chip->priv = &shared[i];/* those should be reset too since
@@ -562,7 +562,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len,break ;if ((len + ofs -1 ) >> lpddr->chipshift) - thislen = (1 <<lpddr->chipshift) - ofs; + thislen = (1UL << lpddr->chipshift) - ofs;else thislen = len;/* get the chip */
@@ -578,7 +578,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, len -= thislen; ofs =0 ; - last_end +=1 << lpddr->chipshift; + last_end +=1UL << lpddr->chipshift; chipnum++; chip = &lpddr->chips[chipnum]; }
@@ -604,7 +604,7 @@ static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len)break ;if ((len + ofs -1 ) >> lpddr->chipshift) - thislen = (1 <<lpddr->chipshift) - ofs; + thislen = (1UL << lpddr->chipshift) - ofs;else thislen = len;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 179/634 remoteproc: qcom_q6v5_wcss: fix parsing of qcom,halt-regs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexandru Gagniuc <[email protected]>
[ Upstream commit 7e81fa8d809ed1e67ae9ecd52d20a20c2c65d877 ]
The "qcom,halt-regs" consists of a phandle reference followed by the three offsets within syscon for halt registers. Thus, we need to request 4 integers from of_property_read_variable_u32_array(), with the halt_reg ofsets at indexes 1, 2, and 3. Offset 0 is the phandle.
With MAX_HALT_REG at 3, of_property_read_variable_u32_array() returns -EOVERFLOW, causing .probe() to fail.
Increase MAX_HALT_REG to 4, and update the indexes accordingly.
--- drivers/remoteproc/qcom_q6v5_wcss.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/remoteproc/qcom_q6v5_wcss.c +4 -4
@@ -85,7 +85,7 @@#define TCSR_WCSS_CLK_MASK 0x1F#define TCSR_WCSS_CLK_ENABLE 0x14 -#define MAX_HALT_REG 3 +#define MAX_HALT_REG 4enum {WCSS_IPQ8074 ,WCSS_QCS404 ,
@@ -864,9 +864,9 @@ static int q6v5_wcss_init_mmio(struct q6v5_wcss *wcss,return -EINVAL ; } - wcss->halt_q6 = halt_reg[0 ]; - wcss->halt_wcss = halt_reg[1 ]; - wcss->halt_nc = halt_reg[2 ]; + wcss->halt_q6 = halt_reg[1 ]; + wcss->halt_wcss = halt_reg[2 ]; + wcss->halt_nc = halt_reg[3 ];return 0 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 180/634 md: export md_is_rdwr() and is_md_suspended()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
[ Upstream commit 431e61257d631157e1d374f1368febf37aa59f7c ]
The two apis will be used later to fix a deadlock in raid456, there are no functional changes.
Stable-dep-of: a913d1f6a7f6 ("md/raid5: fix IO hang when array is broken with IO inflight")
--- drivers/md/md.c | 16 ---------------- drivers/md/md.h | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 16 deletions(-)
drivers/md/md.c +0 -16
@@ -93,18 +93,6 @@ static int remove_and_add_spares(struct mddev *mddev, struct md_rdev *this);static void mddev_detach (struct mddev *mddev); -enum md_ro_state { -MD_RDWR , -MD_RDONLY , -MD_AUTO_READ , -MD_MAX_STATE -}; - -static bool md_is_rdwr (struct mddev *mddev) -{ -return (mddev->ro ==MD_RDWR ); -} -/* * Default number of read corrections we'll attempt on an rdev * before ejecting it from the array. We divide the read error
@@ -380,10 +368,6 @@ EXPORT_SYMBOL_GPL(md_new_event);static LIST_HEAD (all_mddevs);static DEFINE_SPINLOCK (all_mddevs_lock); -static bool is_md_suspended (struct mddev *mddev) -{ -return percpu_ref_is_dying (&mddev->active_io); -}/* Rather than calling directly into the personality make_request function, * IO requests come here first so that we can check if the device is * being suspended pending a reconfiguration.
drivers/md/md.h +17 -0
@@ -555,6 +555,23 @@ enum recovery_flags { MD_RESYNCING_REMOTE, /* remote node is running resync thread */ }; +enum md_ro_state { +MD_RDWR , +MD_RDONLY , +MD_AUTO_READ , +MD_MAX_STATE +}; + +static inline bool md_is_rdwr (struct mddev *mddev) +{ +return (mddev->ro ==MD_RDWR ); +} + +static inline bool is_md_suspended (struct mddev *mddev) +{ +return percpu_ref_is_dying (&mddev->active_io); +} +static inline int __must_check mddev_lock (struct mddev *mddev) {return mutex_lock_interruptible (&mddev->reconfig_mutex);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 181/634 md/raid5: fix IO hang when array is broken with IO inflight
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
[ Upstream commit a913d1f6a7f607c110aeef8b58c8988f47a4b24e ]
Following test can cause IO hang:
mdadm -CvR /dev/md0 -l10 -n4 /dev/sd[abcd] --assume-clean --chunk=64K --bitmap=none sleep 5
echo 1 > /sys/block/sda/device/delete
echo 1 > /sys/block/sdb/device/delete
echo 1 > /sys/block/sdc/device/delete
echo 1 > /sys/block/sdd/device/delete
dd if=/dev/md0 of=/dev/null bs=8k count=1 iflag=direct
Root cause:
1) all disks removed, however all rdevs in the array is still in sync, IO will be issued normally.
2) IO failure from sda, and set badblocks failed, sda will be faulty and MD_SB_CHANGING_PENDING will be set.
3) error recovery try to recover this IO from other disks, IO will be issued to sdb, sdc, and sdd.
4) IO failure from sdb, and set badblocks failed again, now array is broken and will become read-only.
5) IO failure from sdc and sdd, however, stripe can't be handled anymore because MD_SB_CHANGING_PENDING is set:
handle_stripe
handle_stripe
if (test_bit MD_SB_CHANGING_PENDING)
set_bit STRIPE_HANDLE
goto finish
// skip handling failed stripe
release_stripe
if (test_bit STRIPE_HANDLE)
list_add_tail conf->hand_list
6) later raid5d can't handle failed stripe as well:
raid5d
md_check_recovery
md_update_sb
if (!md_is_rdwr())
// can't clear pending bit
return if (test_bit MD_SB_CHANGING_PENDING)
break;
// can't handle failed stripe
Since MD_SB_CHANGING_PENDING can never be cleared for read-only array, fix this problem by skip this checking for read-only array.
--- drivers/md/raid5.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/md/raid5.c +4 -2
@@ -5044,7 +5044,8 @@ static void handle_stripe(struct stripe_head *sh) goto finish;if (s.handle_bad_blocks || -test_bit (MD_SB_CHANGE_PENDING , &conf->mddev->sb_flags)) { + (md_is_rdwr (conf->mddev) && +test_bit (MD_SB_CHANGE_PENDING , &conf->mddev->sb_flags))) {set_bit (STRIPE_HANDLE , &sh->state); goto finish; }
@@ -6802,7 +6803,8 @@ static void raid5d(struct md_thread *thread)int batch_size, released;unsigned int offset; -if (test_bit (MD_SB_CHANGE_PENDING , &mddev->sb_flags)) +if (md_is_rdwr (mddev) && +test_bit (MD_SB_CHANGE_PENDING , &mddev->sb_flags))break ; released =release_stripe_list (conf, conf->temp_inactive_list);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 182/634 net/sched: sch_cake: Fix incorrect qlen reduction in cake_drop
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiang Mei <[email protected]>
[ Upstream commit 9fefc78f7f02d71810776fdeb119a05a946a27cc ]
In cake_drop(), qdisc_tree_reduce_backlog() is used to update the qlen and backlog of the qdisc hierarchy. Its caller, cake_enqueue(), assumes that the parent qdisc will enqueue the current packet. However, this assumption breaks when cake_enqueue() returns NET_XMIT_CN: the parent qdisc stops enqueuing current packet, leaving the tree qlen/backlog accounting inconsistent. This mismatch can lead to a NULL dereference (e.g., when the parent Qdisc is qfq_qdisc).
This patch computes the qlen/backlog delta in a more robust way by observing the difference before and after the series of cake_drop() calls, and then compensates the qdisc tree accounting if cake_enqueue() returns NET_XMIT_CN.
To ensure correct compensation when ACK thinning is enabled, a new variable is introduced to keep qlen unchanged.
--- net/sched/sch_cake.c | 58 ++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 26 deletions(-)
net/sched/sch_cake.c +32 -26
@@ -1608,7 +1608,6 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free)__qdisc_drop (skb, to_free); sch->q.qlen--; -qdisc_tree_reduce_backlog (sch,1 , len);cake_heapify (q,0 );
@@ -1754,14 +1753,14 @@ static void cake_reconfigure(struct Qdisc *sch);static s32 cake_enqueue (struct sk_buff *skb,struct Qdisc *sch,struct sk_buff **to_free) { +u32 idx, tin, prev_qlen, prev_backlog, drop_id;struct cake_sched_data *q =qdisc_priv (sch); -int len =qdisc_pkt_len (skb); -int ret; +int len =qdisc_pkt_len (skb), ret;struct sk_buff *ack =NULL ;ktime_t now =ktime_get ();struct cake_tin_data *b;struct cake_flow *flow; -u32 idx, tin; +bool same_flow = false;/* choose flow to insert into */ idx =cake_classify (sch, &b, skb, q->flow_mode, &ret);
@@ -1834,6 +1833,8 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,consume_skb (skb); }else {/* not splitting */ +int ack_pkt_len =0 ; +cobalt_set_enqueue_time (skb, now);get_cobalt_cb (skb)->adjusted_len =cake_overhead (q, skb);flow_queue_add (flow, skb);
@@ -1844,13 +1845,13 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,if (ack) { b->ack_drops++; sch->qstats.drops++; - b->bytes +=qdisc_pkt_len (ack); - len -=qdisc_pkt_len (ack); + ack_pkt_len =qdisc_pkt_len (ack); + b->bytes += ack_pkt_len; q->buffer_used += skb->truesize - ack->truesize;if (q->rate_flags &CAKE_FLAG_INGRESS )cake_advance_shaper (q, b, ack, now, true); -qdisc_tree_reduce_backlog (sch,1 ,qdisc_pkt_len (ack)); +qdisc_tree_reduce_backlog (sch,1 , ack_pkt_len);consume_skb (ack); }else { sch->q.qlen++;
@@ -1859,11 +1860,11 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,/* stats */ b->packets++; - b->bytes += len; - b->backlogs[idx] += len; - b->tin_backlog += len; - sch->qstats.backlog += len; - q->avg_window_bytes += len; + b->bytes += len - ack_pkt_len; + b->backlogs[idx] += len - ack_pkt_len; + b->tin_backlog += len - ack_pkt_len; + sch->qstats.backlog += len - ack_pkt_len; + q->avg_window_bytes += len - ack_pkt_len; }if (q->overflow_timeout)
@@ -1938,24 +1939,29 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,if (q->buffer_used > q->buffer_max_used) q->buffer_max_used = q->buffer_used; -if (q->buffer_used > q->buffer_limit) { -bool same_flow = false; -u32 dropped =0 ; -u32 drop_id; +if (q->buffer_used <= q->buffer_limit) +return NET_XMIT_SUCCESS ; -while (q->buffer_used > q->buffer_limit) { - dropped++; - drop_id =cake_drop (sch, to_free); + prev_qlen = sch->q.qlen; + prev_backlog = sch->qstats.backlog; -if ((drop_id >>16 ) == tin && - (drop_id &0xFFFF ) == idx) - same_flow = true; - } - b->drop_overlimit += dropped; +while (q->buffer_used > q->buffer_limit) { + drop_id =cake_drop (sch, to_free); +if ((drop_id >>16 ) == tin && + (drop_id &0xFFFF ) == idx) + same_flow = true; + } + + prev_qlen -= sch->q.qlen; + prev_backlog -= sch->qstats.backlog; + b->drop_overlimit += prev_qlen; -if (same_flow) -return NET_XMIT_CN ; +if (same_flow) { +qdisc_tree_reduce_backlog (sch, prev_qlen -1 , + prev_backlog - len); +return NET_XMIT_CN ; } +qdisc_tree_reduce_backlog (sch, prev_qlen, prev_backlog);return NET_XMIT_SUCCESS ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 183/634 perf tools: Fix split kallsyms DSO counting
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namhyung Kim <[email protected]>
[ Upstream commit ad0b9c4865b98dc37f4d606d26b1c19808796805 ]
It's counted twice as it's increased after calling maps__insert(). I guess we want to increase it only after it's added properly.
--- tools/perf/util/symbol.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/util/symbol.c +2 -2
@@ -904,11 +904,11 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta,if (dso->kernel ==DSO_SPACE__KERNEL_GUEST )snprintf (dso_name,sizeof (dso_name),"[guest.kernel].%d" , - kernel_range++); + kernel_range);else snprintf (dso_name,sizeof (dso_name),"[kernel].%d" , - kernel_range++); + kernel_range); ndso =dso__new (dso_name);if (ndso ==NULL )
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 184/634 pinctrl: single: Fix PIN_CONFIG_BIAS_DISABLE handling
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthijs Kooijman <[email protected]>
[ Upstream commit b5fe46efc147516a908d2d31bf40eb858ab76d51 ]
The pinctrl-single driver handles pin_config_set by looking up the requested setting in a DT-defined lookup table, which defines what bits correspond to each setting. There is no way to add PIN_CONFIG_BIAS_DISABLE entries to the table, since there is instead code to disable the bias by applying the disable values of both the pullup and pulldown entries in the table.
However, this code is inside the table-lookup loop, so it would only execute if there is an entry for PIN_CONFIG_BIAS_DISABLE in the table, which can never exist, so this code never runs.
This commit lifts the offending code out of the loop, so it just executes directly whenever PIN_CONFIG_BIAS_DISABLE is requested, skippipng the table lookup loop.
This also introduces a new param variable to make the code slightly more readable.
This bug seems to have existed when this code was first merged in commit 9dddb4df90d13 ("pinctrl: single: support generic pinconf"). Earlier versions of this patch did have an entry for PIN_CONFIG_BIAS_DISABLE in the lookup table, but that was removed, which is probably how this bug was introduced.
Message-ID: <[email protected]>
Stable-dep-of: 61d1bb53547d ("pinctrl: single: Fix incorrect type for error return variable")
--- drivers/pinctrl/pinctrl-single.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
drivers/pinctrl/pinctrl-single.c +12 -6
@@ -557,21 +557,30 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev,unsigned offset =0 , shift =0 , i, data, ret;u32 arg;int j; +enum pin_config_param param; ret =pcs_get_function (pctldev, pin, &func);if (ret)return ret;for (j =0 ; j < num_configs; j++) { + param =pinconf_to_config_param (configs[j]); + +/* BIAS_DISABLE has no entry in the func->conf table */ +if (param ==PIN_CONFIG_BIAS_DISABLE ) { +/* This just disables all bias entries */ +pcs_pinconf_clear_bias (pctldev, pin); +continue ; + } +for (i =0 ; i < func->nconfs; i++) { -if (pinconf_to_config_param (configs[j]) - != func->conf[i].param) +if (param != func->conf[i].param)continue ; offset = pin * (pcs->width /BITS_PER_BYTE ); data = pcs->read (pcs->base + offset); arg =pinconf_to_config_argument (configs[j]); -switch (func->conf[i].param) { +switch (param) {/* 2 parameters */ case PIN_CONFIG_INPUT_SCHMITT :case PIN_CONFIG_DRIVE_STRENGTH :
@@ -583,9 +592,6 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, data |= (arg << shift) & func->conf[i].mask;break ;/* 4 parameters */ -case PIN_CONFIG_BIAS_DISABLE : -pcs_pinconf_clear_bias (pctldev, pin); -break ;case PIN_CONFIG_BIAS_PULL_DOWN :case PIN_CONFIG_BIAS_PULL_UP :if (arg) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 185/634 pinctrl: single: Fix incorrect type for error return variable
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit 61d1bb53547d42c6bdaec9da4496beb3a1a05264 ]
pcs_pinconf_get() and pcs_pinconf_set() declare ret as unsigned int, but assign it the return values of pcs_get_function() that may return negative error codes. This causes negative error codes to be converted to large positive values.
Change ret from unsigned int to int in both functions.
--- drivers/pinctrl/pinctrl-single.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/pinctrl/pinctrl-single.c +4 -3
@@ -490,7 +490,8 @@ static int pcs_pinconf_get(struct pinctrl_dev *pctldev,struct pcs_device *pcs =pinctrl_dev_get_drvdata (pctldev);struct pcs_function *func;enum pin_config_param param; -unsigned offset =0 , data =0 , i, j, ret; +unsigned offset =0 , data =0 , i, j; +int ret; ret =pcs_get_function (pctldev, pin, &func);if (ret)
@@ -554,9 +555,9 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, {struct pcs_device *pcs =pinctrl_dev_get_drvdata (pctldev);struct pcs_function *func; -unsigned offset =0 , shift =0 , i, data, ret; +unsigned offset =0 , shift =0 , i, data;u32 arg; -int j; +int j, ret;enum pin_config_param param; ret =pcs_get_function (pctldev, pin, &func);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 186/634 fbdev: ssd1307fb: fix potential page leak in ssd1307fb_probe()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abdun Nihaal <[email protected]>
[ Upstream commit 164312662ae9764b83b84d97afb25c42eb2be473 ]
The page allocated for vmem using __get_free_pages() is not freed on the error paths after it. Fix that by adding a corresponding __free_pages() call to the error path.
--- drivers/video/fbdev/ssd1307fb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/video/fbdev/ssd1307fb.c +3 -1
@@ -732,7 +732,7 @@ static int ssd1307fb_probe(struct i2c_client *client)if (!ssd1307fb_defio) {dev_err (dev,"Couldn't allocate deferred io.\n" ); ret = -ENOMEM ; - goto fb_alloc_error; + goto fb_defio_error; } ssd1307fb_defio->delay =HZ / refreshrate;
@@ -812,6 +812,8 @@ static int ssd1307fb_probe(struct i2c_client *client)regulator_disable (par->vbat_reg); reset_oled_error:fb_deferred_io_cleanup (info); +fb_defio_error: +__free_pages (vmem,get_order (vmem_size)); fb_alloc_error:framebuffer_release (info);return ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 187/634 NFS: Avoid changing nlink when file removes and attribute updates race
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit bd4928ec799b31c492eb63f9f4a0c1e0bb4bb3f7 ]
If a file removal races with another operation that updates its attributes, then skip the change to nlink, and just mark the attributes as being stale.
--- fs/nfs/dir.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
fs/nfs/dir.c +13 -6
@@ -1891,13 +1891,15 @@ static int nfs_dentry_delete(const struct dentry *dentry) }/* Ensure that we revalidate inode->i_nlink */ -static void nfs_drop_nlink (struct inode *inode) +static void nfs_drop_nlink (struct inode *inode,unsigned long gencount) { +struct nfs_inode *nfsi =NFS_I (inode); +spin_lock (&inode->i_lock);/* drop the inode if we're reasonably sure this is the last link */ -if (inode->i_nlink >0 ) +if (inode->i_nlink >0 && gencount == nfsi->attr_gencount)drop_nlink (inode); -NFS_I (inode)->attr_gencount =nfs_inc_attr_generation_counter (); + nfsi->attr_gencount =nfs_inc_attr_generation_counter ();nfs_set_cache_invalid ( inode,NFS_INO_INVALID_CHANGE |NFS_INO_INVALID_CTIME |NFS_INO_INVALID_NLINK );
@@ -1911,8 +1913,9 @@ static void nfs_drop_nlink(struct inode *inode)static void nfs_dentry_iput (struct dentry *dentry,struct inode *inode) {if (dentry->d_flags &DCACHE_NFSFS_RENAMED ) { +unsigned long gencount =READ_ONCE (NFS_I (inode)->attr_gencount);nfs_complete_unlink (dentry, inode); -nfs_drop_nlink (inode); +nfs_drop_nlink (inode, gencount); }iput (inode); }
@@ -2465,9 +2468,11 @@ static int nfs_safe_remove(struct dentry *dentry)trace_nfs_remove_enter (dir, dentry);if (inode !=NULL ) { +unsigned long gencount =READ_ONCE (NFS_I (inode)->attr_gencount); + error =NFS_PROTO (dir)->remove (dir, dentry);if (error ==0 ) -nfs_drop_nlink (inode); +nfs_drop_nlink (inode, gencount); }else error =NFS_PROTO (dir)->remove (dir, dentry);if (error == -ENOENT )
@@ -2672,6 +2677,7 @@ int nfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, {struct inode *old_inode =d_inode (old_dentry);struct inode *new_inode =d_inode (new_dentry); +unsigned long new_gencount =0 ;struct dentry *dentry =NULL ;struct rpc_task *task;bool must_unblock = false;
@@ -2724,6 +2730,7 @@ int nfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, }else {block_revalidate (new_dentry); must_unblock = true; + new_gencount =NFS_I (new_inode)->attr_gencount;spin_unlock (&new_dentry->d_lock); }
@@ -2763,7 +2770,7 @@ int nfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, new_dir, new_dentry, error);if (!error) {if (new_inode !=NULL ) -nfs_drop_nlink (new_inode); +nfs_drop_nlink (new_inode, new_gencount);/* * The d_move() should be here instead of in an async RPC completion * handler because we need the proper locks to move the dentry. If
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 188/634 fs/nls: Fix utf16 to utf8 conversion
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Armin Wolf <[email protected]>
[ Upstream commit 25524b6190295577e4918c689644451365e6466d ]
Currently the function responsible for converting between utf16 and utf8 strings will ignore any characters that cannot be converted. This however also includes multi-byte characters that do not fit into the provided string buffer.
This can cause problems if such a multi-byte character is followed by a single-byte character. In such a case the multi-byte character might be ignored when the provided string buffer is too small, but the single-byte character might fit and is thus still copied into the resulting string.
Fix this by stop filling the provided string buffer once a character does not fit. In order to be able to do this extend utf32_to_utf8() to return useful errno codes instead of -1.
--- fs/nls/nls_base.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
fs/nls/nls_base.c +12 -4
@@ -94,7 +94,7 @@ int utf32_to_utf8(unicode_t u, u8 *s, int maxout) l = u;if (l >UNICODE_MAX || (l &SURROGATE_MASK ) ==SURROGATE_PAIR ) -return -1 ; +return -EILSEQ ; nc =0 ;for (t = utf8_table; t->cmask && maxout; t++, maxout--) {
@@ -110,7 +110,7 @@ int utf32_to_utf8(unicode_t u, u8 *s, int maxout)return nc; } } -return -1 ; +return -EOVERFLOW ; }EXPORT_SYMBOL (utf32_to_utf8);
@@ -217,8 +217,16 @@ int utf16s_to_utf8s(const wchar_t *pwcs, int inlen, enum utf16_endian endian, inlen--; } size =utf32_to_utf8 (u, op, maxout); -if (size ==-1 ) { -/* Ignore character and move on */ +if (size <0 ) { +if (size == -EILSEQ ) { +/* Ignore character and move on */ +continue ; + } +/* +* Stop filling the buffer with data once a character +* does not fit anymore. +*/ +break ; }else { op += size; maxout -= size;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 189/634 NFS: Initialise verifiers for visible dentries in readdir and lookup
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit 9bd545539b233725a3416801f7c374bff0327d6e ]
Ensure that the verifiers are initialised before calling d_splice_alias() in both nfs_prime_dcache() and nfs_lookup().
--- fs/nfs/dir.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
fs/nfs/dir.c +4 -2
@@ -788,16 +788,17 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry, goto out; } +nfs_set_verifier (dentry, dir_verifier); inode =nfs_fhget (dentry->d_sb, entry->fh, entry->fattr); alias =d_splice_alias (inode, dentry);d_lookup_done (dentry);if (alias) {if (IS_ERR (alias)) goto out; +nfs_set_verifier (alias, dir_verifier);dput (dentry); dentry = alias; } -nfs_set_verifier (dentry, dir_verifier);trace_nfs_readdir_lookup (d_inode (parent), dentry,0 ); out:dput (dentry);
@@ -1990,13 +1991,14 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned innfs_lookup_advise_force_readdirplus (dir, flags); no_entry: +nfs_set_verifier (dentry, dir_verifier); res =d_splice_alias (inode, dentry);if (res !=NULL ) {if (IS_ERR (res)) goto out; +nfs_set_verifier (res, dir_verifier); dentry = res; } -nfs_set_verifier (dentry, dir_verifier); out:trace_nfs_lookup_exit (dir, dentry, flags,PTR_ERR_OR_ZERO (res));nfs_free_fattr (fattr);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 190/634 NFS: Initialise verifiers for visible dentries in nfs_atomic_open()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit 518c32a1bc4f8df1a8442ee8cdfea3e2fcff20a0 ]
Ensure that the verifiers are initialised before calling d_splice_alias() in nfs_atomic_open().
--- fs/nfs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/dir.c +1 -1
@@ -2139,12 +2139,12 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,d_drop (dentry);switch (err) {case -ENOENT : -d_splice_alias (NULL , dentry);if (nfs_server_capable (dir,NFS_CAP_CASE_INSENSITIVE )) dir_verifier =inode_peek_iversion_raw (dir);else dir_verifier =nfs_save_change_attribute (dir);nfs_set_verifier (dentry, dir_verifier); +d_splice_alias (NULL , dentry);break ;case -EISDIR :case -ENOTDIR :
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 191/634 NFSv4/pNFS: Clear NFS_INO_LAYOUTCOMMIT in pnfs_mark_layout_stateid_invalid
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Curley <[email protected]>
[ Upstream commit e0f8058f2cb56de0b7572f51cd563ca5debce746 ]
Fixes a crash when layout is null during this call stack:
write_inode
-> nfs4_write_inode
-> pnfs_layoutcommit_inodepnfs_set_layoutcommit relies on the lseg refcount to keep the layout around. Need to clear NFS_INO_LAYOUTCOMMIT otherwise we might attempt to reference a null layout.
--- fs/nfs/pnfs.c | 1 + 1 file changed, 1 insertion(+)
fs/nfs/pnfs.c +1 -0
@@ -465,6 +465,7 @@ pnfs_mark_layout_stateid_invalid(struct pnfs_layout_hdr *lo,struct pnfs_layout_segment *lseg, *next;set_bit (NFS_LAYOUT_INVALID_STID , &lo->plh_flags); +clear_bit (NFS_INO_LAYOUTCOMMIT , &NFS_I (lo->plh_inode)->flags);list_for_each_entry_safe (lseg, next, &lo->plh_segs, pls_list)pnfs_clear_lseg_state (lseg, lseg_list);pnfs_clear_layoutreturn_info (lo);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 192/634 Revert "nfs: ignore SB_RDONLY when remounting nfs"
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit 400fa37afbb11a601c204b72af0f0e5bc2db695c ]
This reverts commit 80c4de6ab44c14e910117a02f2f8241ffc6ec54a.
Silently ignoring the "ro" and "rw" mount options causes user confusion, and regressions.
--- fs/nfs/super.c | 10 ---------- 1 file changed, 10 deletions(-)
fs/nfs/super.c +0 -10
@@ -1017,16 +1017,6 @@ int nfs_reconfigure(struct fs_context *fc)sync_filesystem (sb); -/* -* The SB_RDONLY flag has been removed from the superblock during -* mounts to prevent interference between different filesystems. -* Similarly, it is also necessary to ignore the SB_RDONLY flag -* during reconfiguration; otherwise, it may also result in the -* creation of redundant superblocks when mounting a directory with -* different rw and ro flags multiple times. -*/ - fc->sb_flags_mask &= ~SB_RDONLY ; -/* * Userspace mount programs that send binary options generally send * them populated with default values. We have no way to know which
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 193/634 Revert "nfs: clear SB_RDONLY before getting superblock"
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit d216b698d44e33417ad4cc796cb04ccddbb8c0ee ]
This reverts commit 8cd9b785943c57a136536250da80ba1eb6f8eb18.
Silently ignoring the "ro" and "rw" mount options causes user confusion, and regressions.
--- fs/nfs/super.c | 9 --------- 1 file changed, 9 deletions(-)
fs/nfs/super.c +0 -9
@@ -1273,17 +1273,8 @@ int nfs_get_tree_common(struct fs_context *fc)if (IS_ERR (server))return PTR_ERR (server); -/* -* When NFS_MOUNT_UNSHARED is not set, NFS forces the sharing of a -* superblock among each filesystem that mounts sub-directories -* belonging to a single exported root path. -* To prevent interference between different filesystems, the -* SB_RDONLY flag should be removed from the superblock. -*/ if (server->flags &NFS_MOUNT_UNSHARED ) compare_super =NULL ; -else - fc->sb_flags &= ~SB_RDONLY ;/* -o noac implies -o sync */ if (server->flags &NFS_MOUNT_NOAC )
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 194/634 Revert "nfs: ignore SB_RDONLY when mounting nfs"
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit d4a26d34f1946142f9d32e540490e4926ae9a46b ]
This reverts commit 52cb7f8f177878b4f22397b9c4d2c8f743766be3.
Silently ignoring the "ro" and "rw" mount options causes user confusion, and regressions.
--- fs/nfs/internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/internal.h +1 -1
@@ -11,7 +11,7 @@#include <linux/nfs_page.h> #include <linux/wait_bit.h> -#define NFS_SB_MASK (SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS) +#define NFS_SB_MASK (SB_RDONLY|SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS)extern const struct export_operations nfs_export_ops;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 195/634 fs_context: drop the unused lsm_flags member
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ondrej Mosnacek <[email protected]>
[ Upstream commit 4e04143c869c5b6d499fbd5083caa860d5c942c3 ]
This isn't ever used by VFS now, and it couldn't even work. Any FS that uses the SECURITY_LSM_NATIVE_LABELS flag needs to also process the value returned back from the LSM, so it needs to do its security_sb_set_mnt_opts() call on its own anyway.
Stable-dep-of: 8675c69816e4 ("NFS: Automounted filesystems should inherit ro,noexec,nodev,sync flags")
--- Documentation/filesystems/mount_api.rst | 1 - fs/nfs/super.c | 3 --- include/linux/fs_context.h | 1 - include/linux/security.h | 2 +- 4 files changed, 1 insertion(+), 6 deletions(-)
Documentation/filesystems/mount_api.rst +0 -1
@@ -79,7 +79,6 @@ context. This is represented by the fs_context structure:: unsigned int sb_flags; unsigned int sb_flags_mask; unsigned int s_iflags; - unsigned int lsm_flags; enum fs_context_purpose purpose:8; ... };
fs/nfs/super.c +0 -3
@@ -1284,9 +1284,6 @@ int nfs_get_tree_common(struct fs_context *fc)if (ctx->clone_data.sb->s_flags &SB_SYNCHRONOUS ) fc->sb_flags |=SB_SYNCHRONOUS ; -if (server->caps &NFS_CAP_SECURITY_LABEL ) - fc->lsm_flags |=SECURITY_LSM_NATIVE_LABELS ; -/* Get a superblock - note that we may end up sharing one that already exists */ fc->s_fs_info = server; s =sget_fc (fc, compare_super, nfs_set_super);
include/linux/fs_context.h +0 -1
@@ -104,7 +104,6 @@ struct fs_context {unsigned int sb_flags;/* Proposed superblock flags (SB_*) */ unsigned int sb_flags_mask;/* Superblock flags that were changed */ unsigned int s_iflags;/* OR'd with sb->s_iflags */ -unsigned int lsm_flags;/* Information flags from the fs to the LSM */ enum fs_context_purpose purpose:8; enum fs_context_phase phase:8; /* The phase the context is in */ bool need_free:1; /* Need to call ops->free() */
include/linux/security.h +1 -1
@@ -67,7 +67,7 @@ struct watch_notification;/* If capable is being called by a setid function */ #define CAP_OPT_INSETID BIT(2) -/* LSM Agnostic defines for fs_context::lsm_flags */ +/* LSM Agnostic defines for security_sb_set_mnt_opts() flags */ #define SECURITY_LSM_NATIVE_LABELS 1struct ctl_table ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 196/634 NFS: Automounted filesystems should inherit ro,noexec,nodev,sync flags
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit 8675c69816e4276b979ff475ee5fac4688f80125 ]
When a filesystem is being automounted, it needs to preserve the user-set superblock mount options, such as the "ro" flag.
--- fs/nfs/namespace.c | 6 ++++++ fs/nfs/super.c | 4 ---- 2 files changed, 6 insertions(+), 4 deletions(-)
fs/nfs/namespace.c +6 -0
@@ -149,6 +149,7 @@ struct vfsmount *nfs_d_automount(struct path *path)struct vfsmount *mnt =ERR_PTR (-ENOMEM );struct nfs_server *server =NFS_SB (path->dentry->d_sb);struct nfs_client *client = server->nfs_client; +unsigned long s_flags = path->dentry->d_sb->s_flags;int timeout =READ_ONCE (nfs_mountpoint_expiry_timeout);int ret;
@@ -174,6 +175,11 @@ struct vfsmount *nfs_d_automount(struct path *path) fc->net_ns =get_net (client->cl_net); } +/* Inherit the flags covered by NFS_SB_MASK */ + fc->sb_flags_mask |=NFS_SB_MASK ; + fc->sb_flags &= ~NFS_SB_MASK ; + fc->sb_flags |= s_flags &NFS_SB_MASK ; +/* for submounts we want the same server; referrals will reassign */ memcpy (&ctx->nfs_server._address, &client->cl_addr, client->cl_addrlen); ctx->nfs_server.addrlen = client->cl_addrlen;
fs/nfs/super.c +0 -4
@@ -1280,10 +1280,6 @@ int nfs_get_tree_common(struct fs_context *fc)if (server->flags &NFS_MOUNT_NOAC ) fc->sb_flags |=SB_SYNCHRONOUS ; -if (ctx->clone_data.sb) -if (ctx->clone_data.sb->s_flags &SB_SYNCHRONOUS ) - fc->sb_flags |=SB_SYNCHRONOUS ; -/* Get a superblock - note that we may end up sharing one that already exists */ fc->s_fs_info = server; s =sget_fc (fc, compare_super, nfs_set_super);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 197/634 Expand the type of nfs_fattr->valid
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit ce60ab3964782df9ba34f0a64c0bc766dd508bde ]
We need to be able to track more than 32 attributes per inode.
Stable-dep-of: 2b092175f5e3 ("NFS: Fix inheritance of the block sizes when automounting")
--- fs/nfs/inode.c | 2 +- include/linux/nfs_fs_sb.h | 2 +- include/linux/nfs_xdr.h | 54 +++++++++++++++++++-------------------- 3 files changed, 29 insertions(+), 29 deletions(-)
fs/nfs/inode.c +1 -1
@@ -2075,7 +2075,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)bool attr_changed = false;bool have_delegation; -dfprintk (VFS ,"NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n" , +dfprintk (VFS ,"NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%llx)\n" , __func__, inode->i_sb->s_id, inode->i_ino,nfs_display_fhandle_hash (NFS_FH (inode)),atomic_read (&inode->i_count), fattr->valid);
include/linux/nfs_fs_sb.h +1 -1
@@ -155,8 +155,8 @@ struct nfs_server {#define NFS_MOUNT_WRITE_WAIT 0x02000000#define NFS_MOUNT_TRUNK_DISCOVERY 0x04000000 -unsigned int fattr_valid;/* Valid attributes */ unsigned int caps;/* server capabilities */ +__u64 fattr_valid;/* Valid attributes */ unsigned int rsize;/* read size */ unsigned int rpages;/* read size (in pages) */ unsigned int wsize;/* write size */
include/linux/nfs_xdr.h +27 -27
66 lines not on this page · raw message
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 198/634 NFS: Fix inheritance of the block sizes when automounting
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit 2b092175f5e301cdaa935093edfef2be9defb6df ]
Only inherit the block sizes that were actually specified as mount parameters for the parent mount.
--- fs/nfs/client.c | 21 +++++++++++++++++---- fs/nfs/internal.h | 1 - fs/nfs/namespace.c | 5 ++++- fs/nfs/nfs4client.c | 18 ++++++++++++++---- fs/nfs/super.c | 10 +++------- include/linux/nfs_fs_sb.h | 5 +++++ 6 files changed, 43 insertions(+), 17 deletions(-)
fs/nfs/client.c +17 -4
@@ -745,10 +745,18 @@ static int nfs_init_server(struct nfs_server *server, server->fattr_valid =NFS_ATTR_FATTR_V4 ; } -if (ctx->rsize) +if (ctx->bsize) { + server->bsize = ctx->bsize; + server->automount_inherit |=NFS_AUTOMOUNT_INHERIT_BSIZE ; + } +if (ctx->rsize) { server->rsize =nfs_io_size (ctx->rsize, clp->cl_proto); -if (ctx->wsize) + server->automount_inherit |=NFS_AUTOMOUNT_INHERIT_RSIZE ; + } +if (ctx->wsize) { server->wsize =nfs_io_size (ctx->wsize, clp->cl_proto); + server->automount_inherit |=NFS_AUTOMOUNT_INHERIT_WSIZE ; + } server->acregmin = ctx->acregmin *HZ ; server->acregmax = ctx->acregmax *HZ ;
@@ -940,8 +948,13 @@ EXPORT_SYMBOL_GPL(nfs_probe_server);void nfs_server_copy_userdata (struct nfs_server *target,struct nfs_server *source) { target->flags = source->flags; - target->rsize = source->rsize; - target->wsize = source->wsize; + target->automount_inherit = source->automount_inherit; +if (source->automount_inherit &NFS_AUTOMOUNT_INHERIT_BSIZE ) + target->bsize = source->bsize; +if (source->automount_inherit &NFS_AUTOMOUNT_INHERIT_RSIZE ) + target->rsize = source->rsize; +if (source->automount_inherit &NFS_AUTOMOUNT_INHERIT_WSIZE ) + target->wsize = source->wsize; target->acregmin = source->acregmin; target->acregmax = source->acregmax; target->acdirmin = source->acdirmin;
fs/nfs/internal.h +0 -1
@@ -145,7 +145,6 @@ struct nfs_fs_context {struct super_block *sb;struct dentry *dentry;struct nfs_fattr *fattr; -unsigned int inherited_bsize; } clone_data; };
fs/nfs/namespace.c +4 -1
@@ -190,6 +190,10 @@ struct vfsmount *nfs_d_automount(struct path *path) ctx->nfs_mod = client->cl_nfs_mod;__module_get (ctx->nfs_mod->owner); +/* Inherit block sizes if they were specified as mount parameters */ +if (server->automount_inherit &NFS_AUTOMOUNT_INHERIT_BSIZE ) + ctx->bsize = server->bsize; + ret = client->rpc_ops->submount (fc, server);if (ret <0 ) { mnt =ERR_PTR (ret);
@@ -289,7 +293,6 @@ int nfs_do_submount(struct fs_context *fc)return -ENOMEM ; ctx->internal = true; - ctx->clone_data.inherited_bsize = ctx->clone_data.sb->s_blocksize_bits; p =nfs_devname (dentry, buffer,4096 );if (IS_ERR (p)) {
fs/nfs/nfs4client.c +14 -4
@@ -1149,10 +1149,20 @@ static int nfs4_init_server(struct nfs_server *server, struct fs_context *fc)if (error <0 )return error; -if (ctx->rsize) - server->rsize =nfs_io_size (ctx->rsize, server->nfs_client->cl_proto); -if (ctx->wsize) - server->wsize =nfs_io_size (ctx->wsize, server->nfs_client->cl_proto); +if (ctx->bsize) { + server->bsize = ctx->bsize; + server->automount_inherit |=NFS_AUTOMOUNT_INHERIT_BSIZE ; + } +if (ctx->rsize) { + server->rsize = +nfs_io_size (ctx->rsize, server->nfs_client->cl_proto); + server->automount_inherit |=NFS_AUTOMOUNT_INHERIT_RSIZE ; + } +if (ctx->wsize) { + server->wsize = +nfs_io_size (ctx->wsize, server->nfs_client->cl_proto); + server->automount_inherit |=NFS_AUTOMOUNT_INHERIT_WSIZE ; + } server->acregmin = ctx->acregmin *HZ ; server->acregmax = ctx->acregmax *HZ ;
fs/nfs/super.c +3 -7
@@ -1057,8 +1057,9 @@ static void nfs_fill_super(struct super_block *sb, struct nfs_fs_context *ctx) sb->s_blocksize =0 ; sb->s_xattr = server->nfs_client->cl_nfs_mod->xattr; sb->s_op = server->nfs_client->cl_nfs_mod->sops; -if (ctx->bsize) - sb->s_blocksize =nfs_block_size (ctx->bsize, &sb->s_blocksize_bits); +if (server->bsize) + sb->s_blocksize = +nfs_block_size (server->bsize, &sb->s_blocksize_bits);switch (server->nfs_client->rpc_ops->version) {case 2 :
@@ -1303,13 +1304,8 @@ int nfs_get_tree_common(struct fs_context *fc) }if (!s->s_root) { -unsigned bsize = ctx->clone_data.inherited_bsize;/* initial superblock/root creation */ nfs_fill_super (s, ctx); -if (bsize) { - s->s_blocksize_bits = bsize; - s->s_blocksize =1U << bsize; - } error =nfs_get_cache_cookie (s, ctx);if (error <0 ) goto error_splat_super;
include/linux/nfs_fs_sb.h +5 -0
@@ -155,6 +155,11 @@ struct nfs_server {#define NFS_MOUNT_WRITE_WAIT 0x02000000#define NFS_MOUNT_TRUNK_DISCOVERY 0x04000000 +unsigned int automount_inherit;/* Properties inherited by automount */ +#define NFS_AUTOMOUNT_INHERIT_BSIZE 0x0001 +#define NFS_AUTOMOUNT_INHERIT_RSIZE 0x0002 +#define NFS_AUTOMOUNT_INHERIT_WSIZE 0x0004 +unsigned int caps;/* server capabilities */ __u64 fattr_valid;/* Valid attributes */ unsigned int rsize;/* read size */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 199/634 fs/nls: Fix inconsistency between utf8_to_utf32() and utf32_to_utf8()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Armin Wolf <[email protected]>
[ Upstream commit c36f9d7b2869a003a2f7d6ff2c6bac9e62fd7d68 ]
After commit 25524b619029 ("fs/nls: Fix utf16 to utf8 conversion"), the return values of utf8_to_utf32() and utf32_to_utf8() are inconsistent when encountering an error: utf8_to_utf32() returns -1, while utf32_to_utf8() returns errno codes. Fix this inconsistency by modifying utf8_to_utf32() to return errno codes as well.
--- fs/nls/nls_base.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
fs/nls/nls_base.c +7 -4
@@ -67,19 +67,22 @@ int utf8_to_utf32(const u8 *s, int inlen, unicode_t *pu) l &= t->lmask;if (l < t->lval || l >UNICODE_MAX || (l &SURROGATE_MASK ) ==SURROGATE_PAIR ) -return -1 ; +return -EILSEQ ; + *pu = (unicode_t ) l;return nc; }if (inlen <= nc) -return -1 ; +return -EOVERFLOW ; + s++; c = (*s ^0x80 ) &0xFF ;if (c &0xC0 ) -return -1 ; +return -EILSEQ ; + l = (l <<6 ) | c; } -return -1 ; +return -EILSEQ ; }EXPORT_SYMBOL (utf8_to_utf32);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 200/634 platform/x86: asus-wmi: use brightness_set_blocking() for kbd led
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anton Khirnov <[email protected]>
[ Upstream commit ccb61a328321ba3f8567e350664c9ca7a42b6c70 ]
kbd_led_set() can sleep, and so may not be used as the brightness_set() callback.
Otherwise using this led with a trigger leads to system hangs accompanied by:
BUG: scheduling while atomic: acpi_fakekeyd/2588/0x00000003 CPU: 4 UID: 0 PID: 2588 Comm: acpi_fakekeyd Not tainted 6.17.9+deb14-amd64 #1 PREEMPT(lazy) Debian 6.17.9-1 Hardware name: ASUSTeK COMPUTER INC. ASUS EXPERTBOOK B9403CVAR/B9403CVAR, BIOS B9403CVAR.311 12/24/2024 Call Trace: <TASK> [...] schedule_timeout+0xbd/0x100 __down_common+0x175/0x290 down_timeout+0x67/0x70 acpi_os_wait_semaphore+0x57/0x90 [...] asus_wmi_evaluate_method3+0x87/0x190 [asus_wmi] led_trigger_event+0x3f/0x60 [...]
--- drivers/platform/x86/asus-wmi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/platform/x86/asus-wmi.c +4 -4
@@ -1046,14 +1046,14 @@ static void do_kbd_led_set(struct led_classdev *led_cdev, int value)kbd_led_update (asus); } -static void kbd_led_set (struct led_classdev *led_cdev, -enum led_brightness value) +static int kbd_led_set (struct led_classdev *led_cdev,enum led_brightness value) {/* Prevent disabling keyboard backlight on module unregister */ if (led_cdev->flags &LED_UNREGISTERING ) -return ; +return 0 ;do_kbd_led_set (led_cdev, value); +return 0 ; }static void kbd_led_set_by_kbd (struct asus_wmi *asus,enum led_brightness value)
@@ -1206,7 +1206,7 @@ static int asus_wmi_led_init(struct asus_wmi *asus) asus->kbd_led_wk = led_val; asus->kbd_led.name ="asus::kbd_backlight" ; asus->kbd_led.flags =LED_BRIGHT_HW_CHANGED ; - asus->kbd_led.brightness_set = kbd_led_set; + asus->kbd_led.brightness_set_blocking = kbd_led_set; asus->kbd_led.brightness_get = kbd_led_get; asus->kbd_led.max_brightness =3 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 201/634 ASoC: bcm: bcm63xx-pcm-whistler: Check return value of of_dma_configure()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit 0ebbd45c33d0049ebf5a22c1434567f0c420b333 ]
bcm63xx_soc_pcm_new() does not check the return value of of_dma_configure(), which may fail with -EPROBE_DEFER or other errors, allowing PCM setup to continue with incomplete DMA configuration.
Add error checking for of_dma_configure() and return on failure.
--- sound/soc/bcm/bcm63xx-pcm-whistler.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
sound/soc/bcm/bcm63xx-pcm-whistler.c +3 -1
@@ -354,7 +354,9 @@ static int bcm63xx_soc_pcm_new(struct snd_soc_component *component, i2s_priv =dev_get_drvdata (asoc_rtd_to_cpu (rtd,0 )->dev); -of_dma_configure (pcm->card->dev, pcm->card->dev->of_node,1 ); + ret =of_dma_configure (pcm->card->dev, pcm->card->dev->of_node,1 ); +if (ret) +return ret; ret =dma_coerce_mask_and_coherent (pcm->card->dev,DMA_BIT_MASK (32 ));if (ret)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 202/634 ASoC: ak4458: Disable regulator when error happens
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit ae585fabb9713a43e358cf606451386757225c95 ]
Disable regulator in runtime resume when error happens to balance the reference count of regulator.
--- sound/soc/codecs/ak4458.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
sound/soc/codecs/ak4458.c +9 -1
@@ -674,7 +674,15 @@ static int __maybe_unused ak4458_runtime_resume(struct device *dev)regcache_cache_only (ak4458->regmap, false);regcache_mark_dirty (ak4458->regmap); - return regcache_sync(ak4458->regmap); + ret =regcache_sync (ak4458->regmap); +if (ret) + goto err; + +return 0 ; +err: +regcache_cache_only (ak4458->regmap, true); +regulator_bulk_disable (ARRAY_SIZE (ak4458->supplies), ak4458->supplies); + return ret; }#endif /* CONFIG_PM */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 203/634 ASoC: ak5558: Disable regulator when error happens
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit 1f8f726a2a29c28f65b30880335a1610c5e63594 ]
Disable regulator in runtime resume when error happens to balance the reference count of regulator.
--- sound/soc/codecs/ak5558.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
sound/soc/codecs/ak5558.c +9 -1
@@ -372,7 +372,15 @@ static int __maybe_unused ak5558_runtime_resume(struct device *dev)regcache_cache_only (ak5558->regmap, false);regcache_mark_dirty (ak5558->regmap); -return regcache_sync (ak5558->regmap); + ret =regcache_sync (ak5558->regmap); +if (ret) + goto err; + +return 0 ; +err: +regcache_cache_only (ak5558->regmap, true); +regulator_bulk_disable (ARRAY_SIZE (ak5558->supplies), ak5558->supplies); +return ret; }static const struct dev_pm_ops ak5558_pm = {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 204/634 blk-mq: Abort suspend when wakeup events are pending
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Zhang <[email protected]>
[ Upstream commit c196bf43d706592d8801a7513603765080e495fb ]
During system suspend, wakeup capable IRQs for block device can be delayed, which can cause blk_mq_hctx_notify_offline() to hang indefinitely while waiting for pending request to complete. Skip the request waiting loop and abort suspend when wakeup events are pending to prevent the deadlock.
--- block/blk-mq.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
block/blk-mq.c +16 -2
@@ -24,6 +24,7 @@#include <linux/sched/sysctl.h> #include <linux/sched/topology.h> #include <linux/sched/signal.h> +#include <linux/suspend.h> #include <linux/delay.h> #include <linux/crash_dump.h> #include <linux/prefetch.h>
@@ -3510,6 +3511,7 @@ static int blk_mq_hctx_notify_offline(unsigned int cpu, struct hlist_node *node) {struct blk_mq_hw_ctx *hctx =hlist_entry_safe (node, struct blk_mq_hw_ctx, cpuhp_online); +int ret =0 ;if (!cpumask_test_cpu (cpu, hctx->cpumask) || !blk_mq_last_cpu_in_hctx (cpu, hctx))
@@ -3531,12 +3533,24 @@ static int blk_mq_hctx_notify_offline(unsigned int cpu, struct hlist_node *node)* frozen and there are no requests. */ if (percpu_ref_tryget (&hctx->queue->q_usage_counter)) { -while (blk_mq_hctx_has_requests (hctx)) +while (blk_mq_hctx_has_requests (hctx)) { +/* +* The wakeup capable IRQ handler of block device is +* not called during suspend. Skip the loop by checking +* pm_wakeup_pending to prevent the deadlock and improve +* suspend latency. +*/ +if (pm_wakeup_pending ()) { +clear_bit (BLK_MQ_S_INACTIVE , &hctx->state); + ret = -EBUSY ; +break ; + }msleep (5 ); + }percpu_ref_put (&hctx->queue->q_usage_counter); } -return 0 ; +return ret; }static int blk_mq_hctx_notify_online (unsigned int cpu,struct hlist_node *node)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 205/634 block: fix comment for op_is_zone_mgmt() to include RESET_ALL
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: shechenglong <[email protected]>
[ Upstream commit 8a32282175c964eb15638e8dfe199fc13c060f67 ]
REQ_OP_ZONE_RESET_ALL is a zone management request, and op_is_zone_mgmt() has returned true for it.
Update the comment to remove the misleading exception note so the documentation matches the implementation.
--- include/linux/blk_types.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
include/linux/blk_types.h +1 -4
@@ -510,10 +510,7 @@ static inline bool op_is_discard(blk_opf_t op) }/* -* Check if a bio or request operation is a zone management operation, with -* the exception of REQ_OP_ZONE_RESET_ALL which is treated as a special case -* due to its different handling in the block layer and device response in -* case of command failure. +* Check if a bio or request operation is a zone management operation. */ static inline bool op_is_zone_mgmt (enum req_op op) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 206/634 ALSA: firewire-motu: fix buffer overflow in hwdep read for DSP events
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junrui Luo <[email protected]>
[ Upstream commit 210d77cca3d0494ed30a5c628b20c1d95fa04fb1 ]
The DSP event handling code in hwdep_read() could write more bytes to the user buffer than requested, when a user provides a buffer smaller than the event header size (8 bytes).
Fix by using min_t() to clamp the copy size, This ensures we never copy more than the user requested.
--- sound/firewire/motu/motu-hwdep.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
sound/firewire/motu/motu-hwdep.c +3 -2
@@ -83,10 +83,11 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, event.motu_register_dsp_change.type =SNDRV_FIREWIRE_EVENT_MOTU_REGISTER_DSP_CHANGE ; event.motu_register_dsp_change.count = (consumed -sizeof (event.motu_register_dsp_change)) /4 ; -if (copy_to_user (buf, &event,sizeof (event.motu_register_dsp_change))) +if (copy_to_user (buf, &event, +min_t (long, count,sizeof (event.motu_register_dsp_change))))return -EFAULT ; - count = consumed; + count =min_t (long, count, consumed); }else {spin_unlock_irq (&motu->lock);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 207/634 dma/pool: eliminate alloc_pages warning in atomic_pool_expand
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Kleikamp <[email protected]>
[ Upstream commit 463d439becb81383f3a5a5d840800131f265a09c ]
atomic_pool_expand iteratively tries the allocation while decrementing the page order. There is no need to issue a warning if an attempted allocation fails.
--- kernel/dma/pool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/dma/pool.c +1 -1
@@ -93,7 +93,7 @@ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size, page =dma_alloc_from_contiguous (NULL ,1 << order, order, false);if (!page) - page =alloc_pages (gfp, order); + page =alloc_pages (gfp | __GFP_NOWARN, order); }while (!page && order-- >0 );if (!page) goto out;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 208/634 ALSA: uapi: Fix typo in asound.h comment
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andres J Rosa <[email protected]>
[ Upstream commit 9a97857db0c5655b8932f86b5d18bb959079b0ee ]
Fix 'level-shit' to 'level-shift' in struct snd_cea_861_aud_if comment.
--- include/uapi/sound/asound.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/uapi/sound/asound.h +1 -1
@@ -60,7 +60,7 @@ struct snd_cea_861_aud_if {unsigned char db2_sf_ss;/* sample frequency and size */ unsigned char db3;/* not used, all zeros */ unsigned char db4_ca;/* channel allocation code */ -unsigned char db5_dminh_lsv;/* downmix inhibit & level-shit values */ +unsigned char db5_dminh_lsv;/* downmix inhibit & level-shift values */ };/****************************************************************************
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 209/634 rtc: gamecube: Check the return value of ioremap()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit d1220e47e4bd2be8b84bc158f4dea44f2f88b226 ]
The function ioremap() in gamecube_rtc_read_offset_from_sram() can fail and return NULL, which is dereferenced without checking, leading to a NULL pointer dereference.
Add a check for the return value of ioremap() and return -ENOMEM on failure.
--- drivers/rtc/rtc-gamecube.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/rtc/rtc-gamecube.c +4 -0
@@ -242,6 +242,10 @@ static int gamecube_rtc_read_offset_from_sram(struct priv *d) } hw_srnprot =ioremap (res.start,resource_size (&res)); +if (!hw_srnprot) { +pr_err ("failed to ioremap hw_srnprot\n" ); +return -ENOMEM ; + } old =ioread32be (hw_srnprot);/* TODO: figure out why we use this magic constant. I obtained it by
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 210/634 ALSA: firewire-motu: add bounds check in put_user loop for DSP events
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junrui Luo <[email protected]>
[ Upstream commit 298e753880b6ea99ac30df34959a7a03b0878eed ]
In the DSP event handling code, a put_user() loop copies event data. When the user buffer size is not aligned to 4 bytes, it could overwrite beyond the buffer boundary.
Fix by adding a bounds check before put_user().
--- sound/firewire/motu/motu-hwdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/firewire/motu/motu-hwdep.c +1 -1
@@ -75,7 +75,7 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,while (consumed < count &&snd_motu_register_dsp_message_parser_copy_event (motu, &ev)) { ptr = (u32 __user *)(buf + consumed); -if (put_user (ev, ptr)) +if (consumed +sizeof (ev) > count ||put_user (ev, ptr))return -EFAULT ; consumed +=sizeof (ev); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 211/634 ARM: 9464/1: fix input-only operand modification in load_unaligned_zeropad()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liyuan Pang <[email protected]>
[ Upstream commit edb924a7211c9aa7a4a415e03caee4d875e46b8e ]
In the inline assembly inside load_unaligned_zeropad(), the "addr" is
constrained as input-only operand. The compiler assumes that on exit
from the asm statement these operands contain the same values as they
had before executing the statement, but when kernel page fault happened, the assembly fixup code "bic %2 %2, #0x3" modify the value of "addr", which may lead to an unexpected behavior.
Use a temporary variable "tmp" to handle it, instead of modifying the input-only operand, just like what arm64's load_unaligned_zeropad() does.
--- arch/arm/include/asm/word-at-a-time.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
arch/arm/include/asm/word-at-a-time.h +5 -5
@@ -66,7 +66,7 @@ static inline unsigned long find_zero(unsigned long mask)*/ static inline unsigned long load_unaligned_zeropad (const void *addr) { -unsigned long ret, offset; +unsigned long ret, tmp;/* Load word from unaligned pointer addr */ asm(
@@ -74,9 +74,9 @@ static inline unsigned long load_unaligned_zeropad(const void *addr)"2:\n" " .pushsection .text.fixup,\"ax\"\n" " .align 2\n" -"3: and %1, %2, #0x3\n" -" bic %2, %2, #0x3\n" -" ldr %0, [%2]\n" +"3: bic %1, %2, #0x3\n" +" ldr %0, [%1]\n" +" and %1, %2, #0x3\n" " lsl %1, %1, #0x3\n" #ifndef __ARMEB__" lsr %0, %0, %1\n"
@@ -89,7 +89,7 @@ static inline unsigned long load_unaligned_zeropad(const void *addr)" .align 3\n" " .long 1b, 3b\n" " .popsection" - : "=&r" (ret), "=&r" (offset) + : "=&r" (ret), "=&r" (tmp) : "r" (addr), "Qo" (*(unsigned long *)addr)); return ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 212/634 dm-raid: fix possible NULL dereference with undefined raid type
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Simakov <[email protected]>
[ Upstream commit 2f6cfd6d7cb165a7af8877b838a9f6aab4159324 ]
rs->raid_type is assigned from get_raid_type_by_ll(), which may return NULL. This NULL value could be dereferenced later in the condition 'if (!(rs_is_raid10(rs) && rt_is_raid0(rs->raid_type)))'.
Add a fail-fast check to return early with an error if raid_type is NULL, similar to other uses of this function.
Found by Linux Verification Center (linuxtesting.org) with Svace.
--- drivers/md/dm-raid.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/md/dm-raid.c +2 -0
@@ -2259,6 +2259,8 @@ static int super_init_validation(struct raid_set *rs, struct md_rdev *rdev) mddev->reshape_position =le64_to_cpu (sb->reshape_position); rs->raid_type =get_raid_type_by_ll (mddev->level, mddev->layout); +if (!rs->raid_type) +return -EINVAL ; } }else {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 213/634 dm log-writes: Add missing set_freezable() for freezable kthread
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit ab08f9c8b363297cafaf45475b08f78bf19b88ef ]
The log_writes_kthread() calls try_to_freeze() but lacks set_freezable(), rendering the freeze attempt ineffective since kernel threads are non-freezable by default. This prevents proper thread suspension during system suspend/hibernate.
Add set_freezable() to explicitly mark the thread as freezable.
--- drivers/md/dm-log-writes.c | 1 + 1 file changed, 1 insertion(+)
drivers/md/dm-log-writes.c +1 -0
@@ -431,6 +431,7 @@ static int log_writes_kthread(void *arg)struct log_writes_c *lc = (struct log_writes_c *)arg;sector_t sector =0 ; +set_freezable ();while (!kthread_should_stop ()) {bool super = false;bool logging_enabled;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 214/634 efi/cper: Add a new helper function to print bitmasks
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mauro Carvalho Chehab <[email protected]>
[ Upstream commit a976d790f49499ccaa0f991788ad8ebf92e7fd5c ]
Add a helper function to print a string with names associated to each bit field.
A typical example is:
const char * const bits[] = {
"bit 3 name",
"bit 4 name",
"bit 5 name",
};
char str[120];
unsigned int bitmask = BIT(3) | BIT(5);
#define MASK GENMASK(5,3)
cper_bits_to_str(str, sizeof(str), FIELD_GET(MASK, bitmask),
bits, ARRAY_SIZE(bits));The above code fills string "str" with "bit 3 name|bit 5 name".
--- drivers/firmware/efi/cper.c | 60 +++++++++++++++++++++++++++++++++++++ include/linux/cper.h | 2 ++ 2 files changed, 62 insertions(+)
drivers/firmware/efi/cper.c +60 -0
@@ -12,6 +12,7 @@* Specification version 2.4. */ +#include <linux/bitmap.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/time.h>
@@ -105,6 +106,65 @@ void cper_print_bits(const char *pfx, unsigned int bits,printk ("%s\n" , buf); } +/** +* cper_bits_to_str - return a string for set bits +* @buf: buffer to store the output string +* @buf_size: size of the output string buffer +* @bits: bit mask +* @strs: string array, indexed by bit position +* @strs_size: size of the string array: @strs +* +* Add to @buf the bitmask in hexadecimal. Then, for each set bit in @bits, +* add the corresponding string describing the bit in @strs to @buf. +* +* A typical example is:: +* +* const char * const bits[] = { +* "bit 3 name", +* "bit 4 name", +* "bit 5 name", +* }; +* char str[120]; +* unsigned int bitmask = BIT(3) | BIT(5); +* #define MASK GENMASK(5,3) +* +* cper_bits_to_str(str, sizeof(str), FIELD_GET(MASK, bitmask), +* bits, ARRAY_SIZE(bits)); +* +* The above code fills the string ``str`` with ``bit 3 name|bit 5 name``. +* +* Return: number of bytes stored or an error code if lower than zero. +*/ +int cper_bits_to_str (char *buf,int buf_size,unsigned long bits, +const char *const strs[],unsigned int strs_size) +{ +int len = buf_size; +char *str = buf; +int i, size; + + *buf ='\0' ; + +for_each_set_bit (i, &bits, strs_size) { +if (!(bits &BIT_ULL (i))) +continue ; + +if (*buf && len >0 ) { + *str ='|' ; + len--; + str++; + } + + size =strscpy (str, strs[i], len); +if (size <0 ) +return size; + + len -= size; + str += size; + } +return len - buf_size; +} +EXPORT_SYMBOL_GPL (cper_bits_to_str); +static const char *const proc_type_strs[] = {"IA32/X64" ,"IA64" ,
include/linux/cper.h +2 -0
@@ -561,6 +561,8 @@ const char *cper_mem_err_type_str(unsigned int);const char *cper_mem_err_status_str (u64 status);void cper_print_bits (const char *prefix,unsigned int bits,const char *const strs[],unsigned int strs_size); +int cper_bits_to_str (char *buf,int buf_size,unsigned long bits, +const char *const strs[],unsigned int strs_size);void cper_mem_err_pack (const struct cper_sec_mem_err *,struct cper_mem_err_compact *); const char *cper_mem_err_unpack(struct trace_seq *,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 215/634 efi/cper: Adjust infopfx size to accept an extra space
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mauro Carvalho Chehab <[email protected]>
[ Upstream commit 8ad2c72e21efb3dc76c5b14089fa7984cdd87898 ]
Compiling with W=1 with werror enabled produces an error:
drivers/firmware/efi/cper-arm.c: In function ‘cper_print_proc_arm’:drivers/firmware/efi/cper-arm.c:298:64: error: ‘snprintf’ output may be truncated before the last format character [-Werror=format-truncation=]
298 | snprintf(infopfx, sizeof(infopfx), "%s ", newpfx);
| ^drivers/firmware/efi/cper-arm.c:298:25: note: ‘snprintf’ output between 2 and 65 bytes into a destination of size 64
298 | snprintf(infopfx, sizeof(infopfx), "%s ", newpfx);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~As the logic there adds an space at the end of infopx buffer. Add an extra space to avoid such warning.
--- drivers/firmware/efi/cper-arm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/firmware/efi/cper-arm.c +1 -1
@@ -241,7 +241,7 @@ void cper_print_proc_arm(const char *pfx,int i, len, max_ctx_type;struct cper_arm_err_info *err_info;struct cper_arm_ctx_info *ctx_info; -char newpfx[64 ], infopfx[64 ]; +char newpfx[64 ], infopfx[ARRAY_SIZE (newpfx) +1 ];printk ("%sMIDR: 0x%016llx\n" , pfx, proc->midr);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 216/634 efi/cper: align ARM CPER type with UEFI 2.9A/2.10 specs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mauro Carvalho Chehab <[email protected]>
[ Upstream commit 96b010536ee020e716d28d9b359a4bcd18800aeb ]
Up to UEFI spec 2.9, the type byte of CPER struct for ARM processor was defined simply as:
Type at byte offset 4:
- Cache error
- TLB Error
- Bus Error
- Micro-architectural Error
All other values are reserved
Yet, there was no information about how this would be encoded.
Spec 2.9A errata corrected it by defining:
- Bit 1 - Cache Error
- Bit 2 - TLB Error
- Bit 3 - Bus Error
- Bit 4 - Micro-architectural Error
All other values are reserved
That actually aligns with the values already defined on older versions at N.2.4.1. Generic Processor Error Section.
Spec 2.10 also preserve the same encoding as 2.9A.
Adjust CPER and GHES handling code for both generic and ARM processors to properly handle UEFI 2.9A and 2.10 encoding.
--- drivers/acpi/apei/ghes.c | 16 +++++++---- drivers/firmware/efi/cper-arm.c | 50 ++++++++++++++++----------------- include/linux/cper.h | 10 +++---- 3 files changed, 39 insertions(+), 37 deletions(-)
drivers/acpi/apei/ghes.c +10 -6
@@ -22,6 +22,7 @@#include <linux/moduleparam.h> #include <linux/init.h> #include <linux/acpi.h> +#include <linux/bitfield.h> #include <linux/io.h> #include <linux/interrupt.h> #include <linux/timer.h>
@@ -500,6 +501,7 @@ static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, {struct cper_sec_proc_arm *err =acpi_hest_get_payload (gdata);int flags = sync ?MF_ACTION_REQUIRED :0 ; +char error_type[120 ];bool queued = false;int sec_sev, i;char *p;
@@ -513,9 +515,8 @@ static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, p = (char *)(err +1 );for (i =0 ; i < err->err_info_num; i++) {struct cper_arm_err_info *err_info = (struct cper_arm_err_info *)p; -bool is_cache = (err_info->type ==CPER_ARM_CACHE_ERROR ); +bool is_cache = err_info->type &CPER_ARM_CACHE_ERROR ;bool has_pa = (err_info->validation_bits &CPER_ARM_INFO_VALID_PHYSICAL_ADDR ); -const char *error_type ="unknown error" ;/* * The field (err_info->error_info & BIT(26)) is fixed to set to
@@ -529,12 +530,15 @@ static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata,continue ; } -if (err_info->type <ARRAY_SIZE (cper_proc_error_type_strs)) - error_type = cper_proc_error_type_strs[err_info->type]; +cper_bits_to_str (error_type,sizeof (error_type), +FIELD_GET (CPER_ARM_ERR_TYPE_MASK , err_info->type), + cper_proc_error_type_strs, +ARRAY_SIZE (cper_proc_error_type_strs)); pr_warn_ratelimited(FW_WARN GHES_PFX -"Unhandled processor error type: %s\n" , - error_type); +"Unhandled processor error type 0x%02x: %s%s\n" , + err_info->type, error_type, + (err_info->type & ~CPER_ARM_ERR_TYPE_MASK) ? " with reserved bit(s)" : ""); p += err_info->length; }
drivers/firmware/efi/cper-arm.c +24 -26
97 lines not on this page · raw message
include/linux/cper.h +5 -5
@@ -270,11 +270,11 @@ enum {#define CPER_ARM_INFO_FLAGS_PROPAGATED BIT(2)#define CPER_ARM_INFO_FLAGS_OVERFLOW BIT(3) -#define CPER_ARM_CACHE_ERROR 0 -#define CPER_ARM_TLB_ERROR 1 -#define CPER_ARM_BUS_ERROR 2 -#define CPER_ARM_VENDOR_ERROR 3 -#define CPER_ARM_MAX_TYPE CPER_ARM_VENDOR_ERROR +#define CPER_ARM_ERR_TYPE_MASK GENMASK(4,1) +#define CPER_ARM_CACHE_ERROR BIT(1) +#define CPER_ARM_TLB_ERROR BIT(2) +#define CPER_ARM_BUS_ERROR BIT(3) +#define CPER_ARM_VENDOR_ERROR BIT(4)#define CPER_ARM_ERR_VALID_TRANSACTION_TYPE BIT(0)#define CPER_ARM_ERR_VALID_OPERATION_TYPE BIT(1)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 217/634 irqchip/mchp-eic: Fix error code in mchp_eic_domain_alloc()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 7dbc0d40d8347bd9de55c904f59ea44bcc8dedb7 ]
If irq_domain_translate_twocell() sets "hwirq" to >= MCHP_EIC_NIRQ (2) then it results in an out of bounds access.
The code checks for invalid values, but doesn't set the error code. Return -EINVAL in that case, instead of returning success.
--- drivers/irqchip/irq-mchp-eic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/irqchip/irq-mchp-eic.c +1 -1
@@ -166,7 +166,7 @@ static int mchp_eic_domain_alloc(struct irq_domain *domain, unsigned int virq, ret =irq_domain_translate_twocell (domain, fwspec, &hwirq, &type);if (ret || hwirq >=MCHP_EIC_NIRQ ) -return ret; +return ret ?: -EINVAL ;switch (type) {case IRQ_TYPE_EDGE_RISING :
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 218/634 ocfs2: fix memory leak in ocfs2_merge_rec_left()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Antipov <[email protected]>
[ Upstream commit 2214ec4bf89d0fd27717322d3983a2f3b469c7f3 ]
In 'ocfs2_merge_rec_left()', do not reset 'left_path' to NULL after move, thus allowing 'ocfs2_free_path()' to free it before return.
--- fs/ocfs2/alloc.c | 1 - 1 file changed, 1 deletion(-)
fs/ocfs2/alloc.c +0 -1
@@ -3647,7 +3647,6 @@ static int ocfs2_merge_rec_left(struct ocfs2_path *right_path,* So we use the new rightmost path. */ ocfs2_mv_path (right_path, left_path); - left_path =NULL ; }else ocfs2_complete_edge_insert (handle, left_path, right_path, subtree_index);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 219/634 LoongArch: Add machine_kexec_mask_interrupts() implementation
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huacai Chen <[email protected]>
Commit 863a320dc6fd7c855f47da4b ("LoongArch: Mask all interrupts during kexec/kdump") is backported to LTS branches, but they lack a generic machine_kexec_mask_interrupts() implementation, so add an arch-specific one.
--- arch/loongarch/kernel/machine_kexec.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
arch/loongarch/kernel/machine_kexec.c +22 -0
@@ -136,6 +136,28 @@ void kexec_reboot(void)BUG (); } +static void machine_kexec_mask_interrupts (void ) +{ +unsigned int i; +struct irq_desc *desc; + +for_each_irq_desc (i, desc) { +struct irq_chip *chip; + + chip =irq_desc_get_chip (desc); +if (!chip) +continue ; + +if (chip->irq_eoi &&irqd_irq_inprogress (&desc->irq_data)) + chip->irq_eoi (&desc->irq_data); + +if (chip->irq_mask) + chip->irq_mask (&desc->irq_data); + +if (chip->irq_disable && !irqd_irq_disabled (&desc->irq_data)) + chip->irq_disable (&desc->irq_data); + } +}#ifdef CONFIG_SMP static void kexec_shutdown_secondary (void *regs)
Greg Kroah-Hartman
maintainerPATCH 220/634 net: lan743x: Allocate rings outside ZONE_DMA
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thangaraj Samynathan <[email protected]>
commit 8a8f3f4991761a70834fe6719d09e9fd338a766e upstream.
The driver allocates ring elements using GFP_DMA flags. There is no dependency from LAN743x hardware on memory allocation should be in DMA_ZONE. Hence modifying the flags to use only GFP_ATOMIC. This is consistent with other callers of lan743x_rx_init_ring_element().
--- drivers/net/ethernet/microchip/lan743x_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/ethernet/microchip/lan743x_main.c +1 -2
@@ -2627,8 +2627,7 @@ static int lan743x_rx_process_buffer(str/* save existing skb, allocate new skb and map to dma */ skb = buffer_info->skb; -if (lan743x_rx_init_ring_element (rx, rx->last_head, -GFP_ATOMIC |GFP_DMA )) { +if (lan743x_rx_init_ring_element (rx, rx->last_head,GFP_ATOMIC )) {/* failed to allocate next skb. * Memory is very low. * Drop this packet and reuse buffer.
Greg Kroah-Hartman
maintainerPATCH 221/634 usb: gadget: tegra-xudc: Always reinitialize data toggle when clear halt
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotien Hsu <[email protected]>
commit 2585973c7f9ee31d21e5848c996fab2521fd383d upstream.
The driver previously skipped handling ClearFeature(ENDPOINT_HALT) when the endpoint was already not halted. This prevented the controller from resetting the data sequence number and reinitializing the endpoint state.
According to USB 3.2 specification Rev. 1.1, section 9.4.5, ClearFeature(ENDPOINT_HALT) must always reset the data sequence and set the stream state machine to Disabled, regardless of whether the endpoint was halted.
Remove the early return so that ClearFeature(ENDPOINT_HALT) always resets the endpoint sequence state as required by the specification.
--- drivers/usb/gadget/udc/tegra-xudc.c | 6 ------ 1 file changed, 6 deletions(-)
drivers/usb/gadget/udc/tegra-xudc.c +0 -6
@@ -1548,12 +1548,6 @@ static int __tegra_xudc_ep_set_halt(strureturn -ENOTSUPP ; } -if (!!(xudc_readl (xudc,EP_HALT ) &BIT (ep->index)) == halt) { -dev_dbg (xudc->dev,"EP %u already %s\n" , ep->index, - halt ?"halted" :"not halted" ); -return 0 ; - } -if (halt) {ep_halt (xudc, ep->index); }else {
Greg Kroah-Hartman
maintainerPATCH 222/634 usb: phy: Initialize struct usb_phy list_head
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Diogo Ivo <[email protected]>
commit c69ff68b097b0f53333114f1b2c3dc128f389596 upstream.
As part of the registration of a new 'struct usb_phy' with the USB PHY core via either usb_add_phy(struct usb_phy *x, ...) or usb_add_phy_dev(struct usb_phy *x) these functions call list_add_tail(&x->head, phy_list) in order for the new instance x to be stored in phy_list, a static list kept internally by the core.
After 7d21114dc6a2 ("usb: phy: Introduce one extcon device into usb phy") when executing either of the registration functions above it is possible that usb_add_extcon() fails, leading to either function returning before the call to list_add_tail(), leaving x->head uninitialized.
Then, when a driver tries to undo the failed registration by calling usb_remove_phy(struct usb_phy *x) there will be an unconditional call to list_del(&x->head) acting on an uninitialized variable, and thus a possible NULL pointer dereference.
Fix this by initializing x->head before usb_add_extcon() has a chance to fail. Note that this was not needed before 7d21114dc6a2 since list_add_phy() was executed unconditionally and it guaranteed that x->head was initialized.
--- drivers/usb/phy/phy.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/phy/phy.c +4 -0
@@ -672,6 +672,8 @@ int usb_add_phy(struct usb_phy *x, enumreturn -EINVAL ; } +INIT_LIST_HEAD (&x->head); +usb_charger_init (x); ret =usb_add_extcon (x);if (ret)
@@ -722,6 +724,8 @@ int usb_add_phy_dev(struct usb_phy *x)return -EINVAL ; } +INIT_LIST_HEAD (&x->head); +usb_charger_init (x); ret =usb_add_extcon (x);if (ret)
Greg Kroah-Hartman
maintainerPATCH 223/634 ALSA: dice: fix buffer overflow in detect_stream_formats()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junrui Luo <[email protected]>
commit 324f3e03e8a85931ce0880654e3c3eb38b0f0bba upstream.
The function detect_stream_formats() reads the stream_count value directly from a FireWire device without validating it. This can lead to out-of-bounds writes when a malicious device provides a stream_count value greater than MAX_STREAMS.
Fix by applying the same validation to both TX and RX stream counts in detect_stream_formats().
--- sound/firewire/dice/dice-extension.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/firewire/dice/dice-extension.c +2 -2
@@ -116,7 +116,7 @@ static int detect_stream_formats(structbreak ; base_offset +=EXT_APP_STREAM_ENTRIES ; - stream_count =be32_to_cpu (reg[0 ]); + stream_count = min_t(unsigned int, be32_to_cpu(reg[0]), MAX_STREAMS); err = read_stream_entries(dice, section_addr, base_offset, stream_count, mode, dice->tx_pcm_chs,
@@ -125,7 +125,7 @@ static int detect_stream_formats(structbreak ; base_offset += stream_count *EXT_APP_STREAM_ENTRY_SIZE ; - stream_count =be32_to_cpu (reg[1 ]); + stream_count = min_t(unsigned int, be32_to_cpu(reg[1]), MAX_STREAMS); err = read_stream_entries(dice, section_addr, base_offset, stream_count, mode, dice->rx_pcm_chs,
Greg Kroah-Hartman
maintainerPATCH 224/634 ASoC: fsl_xcvr: get channel status data when PHY is not exists
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
commit ca592e20659e0304ebd8f4dabb273da4f9385848 upstream.
There is no PHY for the XCVR module on i.MX93, the channel status needs to be obtained from FSL_XCVR_RX_CS_DATA_* registers. And channel status acknowledge (CSA) bit should be set once channel status is processed.
--- sound/soc/fsl/fsl_xcvr.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
sound/soc/fsl/fsl_xcvr.c +20 -0
@@ -1166,6 +1166,26 @@ static irqreturn_t irq0_isr(int irq, voi/* clear CS control register */ writel_relaxed (0 , reg_ctrl); } + }else { +regmap_read (xcvr->regmap,FSL_XCVR_RX_CS_DATA_0 , + (u32 *)&xcvr->rx_iec958.status[0 ]); +regmap_read (xcvr->regmap,FSL_XCVR_RX_CS_DATA_1 , + (u32 *)&xcvr->rx_iec958.status[4 ]); +regmap_read (xcvr->regmap,FSL_XCVR_RX_CS_DATA_2 , + (u32 *)&xcvr->rx_iec958.status[8 ]); +regmap_read (xcvr->regmap,FSL_XCVR_RX_CS_DATA_3 , + (u32 *)&xcvr->rx_iec958.status[12 ]); +regmap_read (xcvr->regmap,FSL_XCVR_RX_CS_DATA_4 , + (u32 *)&xcvr->rx_iec958.status[16 ]); +regmap_read (xcvr->regmap,FSL_XCVR_RX_CS_DATA_5 , + (u32 *)&xcvr->rx_iec958.status[20 ]); +for (i =0 ; i <6 ; i++) { + val = *(u32 *)(xcvr->rx_iec958.status + i *4 ); + *(u32 *)(xcvr->rx_iec958.status + i *4 ) = +bitrev32 (val); + } +regmap_set_bits (xcvr->regmap,FSL_XCVR_RX_DPTH_CTRL , +FSL_XCVR_RX_DPTH_CTRL_CSA ); } }if (isr &FSL_XCVR_IRQ_NEW_UD ) {
Greg Kroah-Hartman
maintainerPATCH 225/634 btrfs: do not skip logging new dentries when logging a new name
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 5630f7557de61264ccb4f031d4734a1a97eaed16 ]
When we are logging a directory and the log context indicates that we are logging a new name for some other file (that is or was inside that directory), we skip logging the inodes for new dentries in the directory.
This is ok most of the time, but if after the rename or link operation that triggered the logging of that directory, we have an explicit fsync of that directory without the directory inode being evicted and reloaded, we end up never logging the inodes for the new dentries that we found during the new name logging, as the next directory fsync will only process dentries that were added after the last time we logged the directory (we are doing an incremental directory logging).
So make sure we always log new dentries for a directory even if we are in a context of logging a new name.
We started skipping logging inodes for new dentries as of commit c48792c6ee7a ("btrfs: do not log new dentries when logging that a new name exists") and it was fine back then, because when logging a directory we always iterated over all the directory entries (for leaves changed in the current transaction) so a subsequent fsync would always log anything that was previously skipped while logging a directory when logging a new name (with btrfs_log_new_name()). But later support for incrementally logging a directory was added in commit dc2872247ec0 ("btrfs: keep track of the last logged keys when logging a directory"), to avoid checking all dir items every time we log a directory, so the check to skip dentry logging added in the first commit should have been removed when the incremental support for logging a directory was added.
A test case for fstests will follow soon.
--- fs/btrfs/tree-log.c | 8 -------- 1 file changed, 8 deletions(-)
fs/btrfs/tree-log.c +0 -8
@@ -5478,14 +5478,6 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,u64 ino =btrfs_ino (start_inode);int ret =0 ; -/* -* If we are logging a new name, as part of a link or rename operation, -* don't bother logging new dentries, as we just want to log the names -* of an inode and that any new parents exist. -*/ -if (ctx->logging_new_name) -return 0 ; - path =btrfs_alloc_path ();if (!path)return -ENOMEM ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 226/634 bpf, arm64: Do not audit capability check in do_jit()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ondrej Mosnacek <[email protected]>
[ Upstream commit 189e5deb944a6f9c7992355d60bffd8ec2e54a9c ]
Analogically to the x86 commit 881a9c9cb785 ("bpf: Do not audit capability check in do_jit()"), change the capable() call to ns_capable_noaudit() in order to avoid spurious SELinux denials in audit log.
The commit log from that commit applies here as well:
"""
The failure of this check only results in a security mitigation being applied, slightly affecting performance of the compiled BPF program. It doesn't result in a failed syscall, an thus auditing a failed LSM permission check for it is unwanted. For example with SELinux, it causes a denial to be reported for confined processes running as root, which tends to be flagged as a problem to be fixed in the policy. Yet dontauditing or allowing CAP_SYS_ADMIN to the domain may not be desirable, as it would allow/silence also other checks - either going against the principle of least privilege or making debugging potentially harder.
Fix it by changing it from capable() to ns_capable_noaudit(), which instructs the LSMs to not audit the resulting denials. """
--- arch/arm64/net/bpf_jit_comp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/net/bpf_jit_comp.c +1 -1
@@ -666,7 +666,7 @@ static void __maybe_unused build_bhb_mitigation(struct jit_ctx *ctx) arm64_get_spectre_v2_state() == SPECTRE_VULNERABLE)return ; -if (capable (CAP_SYS_ADMIN )) +if (ns_capable_noaudit (&init_user_ns,CAP_SYS_ADMIN ))return ;if (supports_clearbhb (SCOPE_SYSTEM )) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 227/634 btrfs: fix memory leak of fs_devices in degraded seed device path
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Deepanshu Kartikey <[email protected]>
[ Upstream commit b57f2ddd28737db6ff0e9da8467f0ab9d707e997 ]
In open_seed_devices(), when find_fsid() fails and we're in DEGRADED mode, a new fs_devices is allocated via alloc_fs_devices() but is never added to the seed_list before returning. This contrasts with the normal path where fs_devices is properly added via list_add().
If any error occurs later in read_one_dev() or btrfs_read_chunk_tree(), the cleanup code iterates seed_list to free seed devices, but this orphaned fs_devices is never found and never freed, causing a memory leak. Any devices allocated via add_missing_dev() and attached to this fs_devices are also leaked.
Fix this by adding the newly allocated fs_devices to seed_list in the degraded path, consistent with the normal path.
--- fs/btrfs/volumes.c | 1 + 1 file changed, 1 insertion(+)
fs/btrfs/volumes.c +1 -0
@@ -7416,6 +7416,7 @@ static struct btrfs_fs_devices *open_seed_devices(struct btrfs_fs_info *fs_info, fs_devices->seeding = true; fs_devices->opened =1 ; +list_add (&fs_devices->seed_list, &fs_info->fs_devices->seed_list);return fs_devices; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 228/634 perf/x86/amd: Check event before enable to avoid GPF
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: George Kennedy <[email protected]>
[ Upstream commit 866cf36bfee4fba6a492d2dcc5133f857e3446b0 ]
On AMD machines cpuc->events[idx] can become NULL in a subtle race condition with NMI->throttle->x86_pmu_stop().
Check event for NULL in amd_pmu_enable_all() before enable to avoid a GPF. This appears to be an AMD only issue.
Syzkaller reported a GPF in amd_pmu_enable_all.
INFO: NMI handler (perf_event_nmi_handler) took too long to run: 13.143
msecs
Oops: general protection fault, probably for non-canonical address
0xdffffc0000000034: 0000 PREEMPT SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x00000000000001a0-0x00000000000001a7]
CPU: 0 UID: 0 PID: 328415 Comm: repro_36674776 Not tainted 6.12.0-rc1-syzk
RIP: 0010:x86_pmu_enable_event (arch/x86/events/perf_event.h:1195
arch/x86/events/core.c:1430)
RSP: 0018:ffff888118009d60 EFLAGS: 00010012
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000
RDX: 0000000000000034 RSI: 0000000000000000 RDI: 00000000000001a0
RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000002
R13: ffff88811802a440 R14: ffff88811802a240 R15: ffff8881132d8601
FS: 00007f097dfaa700(0000) GS:ffff888118000000(0000) GS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000200001c0 CR3: 0000000103d56000 CR4: 00000000000006f0
Call Trace:
<IRQ>
amd_pmu_enable_all (arch/x86/events/amd/core.c:760 (discriminator 2))
x86_pmu_enable (arch/x86/events/core.c:1360)
event_sched_out (kernel/events/core.c:1191 kernel/events/core.c:1186
kernel/events/core.c:2346)
__perf_remove_from_context (kernel/events/core.c:2435)
event_function (kernel/events/core.c:259)
remote_function (kernel/events/core.c:92 (discriminator 1)
kernel/events/core.c:72 (discriminator 1))
__flush_smp_call_function_queue (./arch/x86/include/asm/jump_label.h:27
./include/linux/jump_label.h:207 ./include/trace/events/csd.h:64
kernel/smp.c:135 kernel/smp.c:540)
__sysvec_call_function_single (./arch/x86/include/asm/jump_label.h:27
./include/linux/jump_label.h:207
./arch/x86/include/asm/trace/irq_vectors.h:99 arch/x86/kernel/smp.c:272)
sysvec_call_function_single (arch/x86/kernel/smp.c:266 (discriminator 47)
arch/x86/kernel/smp.c:266 (discriminator 47))
</IRQ>--- arch/x86/events/amd/core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
arch/x86/events/amd/core.c +6 -1
@@ -731,7 +731,12 @@ static void amd_pmu_enable_all(int added)if (!test_bit (idx, cpuc->active_mask))continue ; -amd_pmu_enable_event (cpuc->events[idx]); +/* +* FIXME: cpuc->events[idx] can become NULL in a subtle race +* condition with NMI->throttle->x86_pmu_stop(). +*/ +if (cpuc->events[idx]) +amd_pmu_enable_event (cpuc->events[idx]); } }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 229/634 sched/deadline: only set free_cpus for online runqueues
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Doug Berger <[email protected]>
[ Upstream commit 382748c05e58a9f1935f5a653c352422375566ea ]
Commit 16b269436b72 ("sched/deadline: Modify cpudl::free_cpus to reflect rd->online") introduced the cpudl_set/clear_freecpu functions to allow the cpu_dl::free_cpus mask to be manipulated by the deadline scheduler class rq_on/offline callbacks so the mask would also reflect this state.
Commit 9659e1eeee28 ("sched/deadline: Remove cpu_active_mask from cpudl_find()") removed the check of the cpu_active_mask to save some processing on the premise that the cpudl::free_cpus mask already reflected the runqueue online state.
Unfortunately, there are cases where it is possible for the cpudl_clear function to set the free_cpus bit for a CPU when the deadline runqueue is offline. When this occurs while a CPU is connected to the default root domain the flag may retain the bad state after the CPU has been unplugged. Later, a different CPU that is transitioning through the default root domain may push a deadline task to the powered down CPU when cpudl_find sees its free_cpus bit is set. If this happens the task will not have the opportunity to run.
One example is outlined here:
https://lore.kernel.org/lkml/[email protected]
Another occurs when the last deadline task is migrated from a CPU that has an offlined runqueue. The dequeue_task member of the deadline scheduler class will eventually call cpudl_clear and set the free_cpus bit for the CPU.
This commit modifies the cpudl_clear function to be aware of the online state of the deadline runqueue so that the free_cpus mask can be updated appropriately.
It is no longer necessary to manage the mask outside of the cpudl_set/clear functions so the cpudl_set/clear_freecpu functions are removed. In addition, since the free_cpus mask is now only updated under the cpudl lock the code was changed to use the non-atomic __cpumask functions.
--- kernel/sched/cpudeadline.c | 34 +++++++++------------------------- kernel/sched/cpudeadline.h | 4 +--- kernel/sched/deadline.c | 8 ++++---- 3 files changed, 14 insertions(+), 32 deletions(-)
kernel/sched/cpudeadline.c +9 -25
@@ -165,12 +165,13 @@ int cpudl_find(struct cpudl *cp, struct task_struct *p,* cpudl_clear - remove a CPU from the cpudl max-heap * @cp: the cpudl max-heap context * @cpu: the target CPU +* @online: the online state of the deadline runqueue * * Notes: assumes cpu_rq(cpu)->lock is locked * * Returns: (void) */ -void cpudl_clear (struct cpudl *cp,int cpu) +void cpudl_clear (struct cpudl *cp,int cpu,bool online) {int old_idx, new_cpu;unsigned long flags;
@@ -183,7 +184,7 @@ void cpudl_clear(struct cpudl *cp, int cpu)if (old_idx ==IDX_INVALID ) {/* * Nothing to remove if old_idx was invalid. -* This could happen if a rq_offline_dl is +* This could happen if rq_online_dl or rq_offline_dl is * called for a CPU without -dl tasks running. */ }else {
@@ -194,9 +195,12 @@ void cpudl_clear(struct cpudl *cp, int cpu) cp->elements[new_cpu].idx = old_idx; cp->elements[cpu].idx =IDX_INVALID ;cpudl_heapify (cp, old_idx); - -cpumask_set_cpu (cpu, cp->free_cpus); } +if (likely (online)) +__cpumask_set_cpu (cpu, cp->free_cpus); +else +__cpumask_clear_cpu (cpu, cp->free_cpus); +raw_spin_unlock_irqrestore (&cp->lock, flags); }
@@ -227,7 +231,7 @@ void cpudl_set(struct cpudl *cp, int cpu, u64 dl) cp->elements[new_idx].cpu = cpu; cp->elements[cpu].idx = new_idx;cpudl_heapify_up (cp, new_idx); -cpumask_clear_cpu (cpu, cp->free_cpus); +__cpumask_clear_cpu (cpu, cp->free_cpus); }else { cp->elements[old_idx].dl = dl;cpudl_heapify (cp, old_idx);
@@ -236,26 +240,6 @@ void cpudl_set(struct cpudl *cp, int cpu, u64 dl)raw_spin_unlock_irqrestore (&cp->lock, flags); } -/* -* cpudl_set_freecpu - Set the cpudl.free_cpus -* @cp: the cpudl max-heap context -* @cpu: rd attached CPU -*/ -void cpudl_set_freecpu (struct cpudl *cp,int cpu) -{ -cpumask_set_cpu (cpu, cp->free_cpus); -} - -/* -* cpudl_clear_freecpu - Clear the cpudl.free_cpus -* @cp: the cpudl max-heap context -* @cpu: rd attached CPU -*/ -void cpudl_clear_freecpu (struct cpudl *cp,int cpu) -{ -cpumask_clear_cpu (cpu, cp->free_cpus); -} -/* * cpudl_init - initialize the cpudl structure * @cp: the cpudl max-heap context
kernel/sched/cpudeadline.h +1 -3
@@ -18,9 +18,7 @@ struct cpudl {#ifdef CONFIG_SMP int cpudl_find (struct cpudl *cp,struct task_struct *p,struct cpumask *later_mask);void cpudl_set (struct cpudl *cp,int cpu,u64 dl); -void cpudl_clear (struct cpudl *cp,int cpu); +void cpudl_clear (struct cpudl *cp,int cpu,bool online);int cpudl_init (struct cpudl *cp); -void cpudl_set_freecpu (struct cpudl *cp,int cpu); -void cpudl_clear_freecpu (struct cpudl *cp,int cpu);void cpudl_cleanup (struct cpudl *cp);#endif /* CONFIG_SMP */
kernel/sched/deadline.c +4 -4
@@ -1486,7 +1486,7 @@ static void dec_dl_deadline(struct dl_rq *dl_rq, u64 deadline)if (!dl_rq->dl_nr_running) { dl_rq->earliest_dl.curr =0 ; dl_rq->earliest_dl.next =0 ; -cpudl_clear (&rq->rd->cpudl, rq->cpu); +cpudl_clear (&rq->rd->cpudl, rq->cpu, rq->online);cpupri_set (&rq->rd->cpupri, rq->cpu, rq->rt.highest_prio.curr); }else {struct rb_node *leftmost =rb_first_cached (&dl_rq->root);
@@ -2554,9 +2554,10 @@ static void rq_online_dl(struct rq *rq)if (rq->dl.overloaded)dl_set_overload (rq); -cpudl_set_freecpu (&rq->rd->cpudl, rq->cpu);if (rq->dl.dl_nr_running >0 )cpudl_set (&rq->rd->cpudl, rq->cpu, rq->dl.earliest_dl.curr); +else +cpudl_clear (&rq->rd->cpudl, rq->cpu, true); }/* Assumes rq->lock is held */
@@ -2565,8 +2566,7 @@ static void rq_offline_dl(struct rq *rq)if (rq->dl.overloaded)dl_clear_overload (rq); -cpudl_clear (&rq->rd->cpudl, rq->cpu); -cpudl_clear_freecpu (&rq->rd->cpudl, rq->cpu); +cpudl_clear (&rq->rd->cpudl, rq->cpu, false); }void __init init_sched_dl_class (void )
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 230/634 sched/fair: Revert max_newidle_lb_cost bump
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
[ Upstream commit d206fbad9328ddb68ebabd7cf7413392acd38081 ]
Many people reported regressions on their database workloads due to:
155213a2aed4 ("sched/fair: Bump sd->max_newidle_lb_cost when newidle balance fails")
For instance Adam Li reported a 6% regression on SpecJBB.
Conversely this will regress schbench again; on my machine from 2.22 Mrps/s down to 2.04 Mrps/s.
--- kernel/sched/fair.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-)
kernel/sched/fair.c +3 -16
@@ -10941,14 +10941,8 @@ static inline bool update_newidle_cost(struct sched_domain *sd, u64 cost)/* * Track max cost of a domain to make sure to not delay the * next wakeup on the CPU. -* -* sched_balance_newidle() bumps the cost whenever newidle -* balance fails, and we don't want things to grow out of -* control. Use the sysctl_sched_migration_cost as the upper -* limit, plus a litle extra to avoid off by ones. */ - sd->max_newidle_lb_cost = -min (cost, sysctl_sched_migration_cost +200 ); + sd->max_newidle_lb_cost = cost; sd->last_decay_max_lb_cost = jiffies; }else if (time_after (jiffies, sd->last_decay_max_lb_cost +HZ )) {/*
@@ -11630,17 +11624,10 @@ static int sched_balance_newidle(struct rq *this_rq, struct rq_flags *rf) t1 =sched_clock_cpu (this_cpu); domain_cost = t1 - t0; +update_newidle_cost (sd, domain_cost); + curr_cost += domain_cost; t0 = t1; - -/* -* Failing newidle means it is not effective; -* bump the cost so we end up doing less of it. -*/ -if (!pulled_task) - domain_cost = (3 * sd->max_newidle_lb_cost) /2 ; - -update_newidle_cost (sd, domain_cost); }/*
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 231/634 x86/ptrace: Always inline trivial accessors
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
[ Upstream commit 1fe4002cf7f23d70c79bda429ca2a9423ebcfdfa ]
A KASAN build bloats these single load/store helpers such that it fails to inline them:
vmlinux.o: error: objtool: irqentry_exit+0x5e8: call to instruction_pointer_set() with UACCESS enabled
Make sure the compiler isn't allowed to do stupid.
--- arch/x86/include/asm/ptrace.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
arch/x86/include/asm/ptrace.h +10 -10
@@ -109,12 +109,12 @@ convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs);extern void send_sigtrap (struct pt_regs *regs,int error_code,int si_code); -static inline unsigned long regs_return_value (struct pt_regs *regs) +static __always_inline unsigned long regs_return_value (struct pt_regs *regs) {return regs->ax; } -static inline void regs_set_return_value (struct pt_regs *regs,unsigned long rc) +static __always_inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) { regs->ax = rc; }
@@ -199,34 +199,34 @@ static __always_inline bool ip_within_syscall_gap(struct pt_regs *regs) }#endif -static inline unsigned long kernel_stack_pointer (struct pt_regs *regs) +static __always_inline unsigned long kernel_stack_pointer (struct pt_regs *regs) {return regs->sp; } -static inline unsigned long instruction_pointer (struct pt_regs *regs) +static __always_inline unsigned long instruction_pointer (struct pt_regs *regs) {return regs->ip; } -static inline void instruction_pointer_set (struct pt_regs *regs, -unsigned long val) +static __always_inline +void instruction_pointer_set(struct pt_regs *regs, unsigned long val) { regs->ip = val; } -static inline unsigned long frame_pointer (struct pt_regs *regs) +static __always_inline unsigned long frame_pointer (struct pt_regs *regs) {return regs->bp; } -static inline unsigned long user_stack_pointer (struct pt_regs *regs) +static __always_inline unsigned long user_stack_pointer (struct pt_regs *regs) {return regs->sp; } -static inline void user_stack_pointer_set (struct pt_regs *regs, -unsigned long val) +static __always_inline +void user_stack_pointer_set(struct pt_regs *regs, unsigned long val) { regs->sp = val; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 232/634 ACPICA: Avoid walking the Namespace if start_node is NULL
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cryolitia PukNgae <[email protected]>
[ Upstream commit 9d6c58dae8f6590c746ac5d0012ffe14a77539f0 ]
Although commit 0c9992315e73 ("ACPICA: Avoid walking the ACPI Namespace if it is not there") fixed the situation when both start_node and acpi_gbl_root_node are NULL, the Linux kernel mainline now still crashed on Honor Magicbook 14 Pro [1].
That happens due to the access to the member of parent_node in acpi_ns_get_next_node(). The NULL pointer dereference will always happen, no matter whether or not the start_node is equal to ACPI_ROOT_OBJECT, so move the check of start_node being NULL out of the if block.
Unfortunately, all the attempts to contact Honor have failed, they refused to provide any technical support for Linux.
The bad DSDT table's dump could be found on GitHub [2].
DMI: HONOR FMB-P/FMB-P-PCB, BIOS 1.13 05/08/2025
--- drivers/acpi/acpica/nswalk.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/acpi/acpica/nswalk.c +6 -3
@@ -169,9 +169,12 @@ acpi_ns_walk_namespace(acpi_object_type type,if (start_node ==ACPI_ROOT_OBJECT ) { start_node = acpi_gbl_root_node; -if (!start_node) { -return_ACPI_STATUS (AE_NO_NAMESPACE ); - } + } + +/* Avoid walking the namespace if the StartNode is NULL */ + +if (!start_node) { +return_ACPI_STATUS (AE_NO_NAMESPACE ); }/* Null child means "get first node" */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 233/634 ACPI: property: Use ACPI functions in acpi_graph_get_next_endpoint() only
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sakari Ailus <[email protected]>
[ Upstream commit 5d010473cdeaabf6a2d3a9e2aed2186c1b73c213 ]
Calling fwnode_get_next_child_node() in ACPI implementation of the fwnode property API is somewhat problematic as the latter is used in the impelementation of the former. Instead of using fwnode_get_next_child_node() in acpi_graph_get_next_endpoint(), call acpi_get_next_subnode() directly instead.
--- drivers/acpi/property.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/acpi/property.c +4 -4
@@ -1382,7 +1382,7 @@ static struct fwnode_handle *acpi_graph_get_next_endpoint(if (!prev) { do { - port = fwnode_get_next_child_node(fwnode, port); + port = acpi_get_next_subnode(fwnode, port); /* * The names of the port nodes begin with "port@" * followed by the number of the port node and they also
@@ -1400,13 +1400,13 @@ static struct fwnode_handle *acpi_graph_get_next_endpoint(if (!port)return NULL ; - endpoint =fwnode_get_next_child_node (port, prev); + endpoint =acpi_get_next_subnode (port, prev);while (!endpoint) { - port =fwnode_get_next_child_node (fwnode, port); + port =acpi_get_next_subnode (fwnode, port);if (!port)break ;if (is_acpi_graph_node (port,"port" )) - endpoint =fwnode_get_next_child_node (port,NULL ); + endpoint =acpi_get_next_subnode (port,NULL ); }/*
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 234/634 cpufreq: s5pv210: fix refcount leak
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shuhao Fu <[email protected]>
[ Upstream commit 2de5cb96060a1664880d65b120e59485a73588a8 ]
In function s5pv210_cpu_init, a possible refcount inconsistency has been identified, causing a resource leak.
Why it is a bug:
1. For every clk_get, there should be a matching clk_put on every successive error handling path.
2. After calling clk_get(dmc1_clk), variable dmc1_clk will not be freed even if any error happens.
How it is fixed: For every failed path, an extra goto label is added to ensure dmc1_clk will be freed regardlessly.
--- drivers/cpufreq/s5pv210-cpufreq.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/cpufreq/s5pv210-cpufreq.c +4 -2
@@ -518,7 +518,7 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy)if (policy->cpu !=0 ) { ret = -EINVAL ; - goto out_dmc1; + goto out; }/*
@@ -530,7 +530,7 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy)if ((mem_type !=LPDDR ) && (mem_type !=LPDDR2 )) {pr_err ("CPUFreq doesn't support this memory type\n" ); ret = -EINVAL ; - goto out_dmc1; + goto out; }/* Find current refresh counter and frequency each DMC */
@@ -544,6 +544,8 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy)cpufreq_generic_init (policy, s5pv210_freq_table,40000 );return 0 ; +out: +clk_put (dmc1_clk); out_dmc1:clk_put (dmc0_clk); out_dmc0:
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 235/634 livepatch: Match old_sympos 0 and 1 in klp_find_func()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Song Liu <[email protected]>
[ Upstream commit 139560e8b973402140cafeb68c656c1374bd4c20 ]
When there is only one function of the same name, old_sympos of 0 and 1 are logically identical. Match them in klp_find_func().
This is to avoid a corner case with different toolchain behavior.
In this specific issue, two versions of kpatch-build were used to build livepatch for the same kernel. One assigns old_sympos == 0 for unique local functions, the other assigns old_sympos == 1 for unique local functions. Both versions work fine by themselves. (PS: This behavior change was introduced in a downstream version of kpatch-build. This change does not exist in upstream kpatch-build.)
However, during livepatch upgrade (with the replace flag set) from a patch built with one version of kpatch-build to the same fix built with the other version of kpatch-build, livepatching fails with errors like:
[ 14.218706] sysfs: cannot create duplicate filename 'xxx/somefunc,1'
...
[ 14.219466] Call Trace:
[ 14.219468] <TASK>
[ 14.219469] dump_stack_lvl+0x47/0x60
[ 14.219474] sysfs_warn_dup.cold+0x17/0x27
[ 14.219476] sysfs_create_dir_ns+0x95/0xb0
[ 14.219479] kobject_add_internal+0x9e/0x260
[ 14.219483] kobject_add+0x68/0x80
[ 14.219485] ? kstrdup+0x3c/0xa0
[ 14.219486] klp_enable_patch+0x320/0x830
[ 14.219488] patch_init+0x443/0x1000 [ccc_0_6]
[ 14.219491] ? 0xffffffffa05eb000
[ 14.219492] do_one_initcall+0x2e/0x190
[ 14.219494] do_init_module+0x67/0x270
[ 14.219496] init_module_from_file+0x75/0xa0
[ 14.219499] idempotent_init_module+0x15a/0x240
[ 14.219501] __x64_sys_finit_module+0x61/0xc0
[ 14.219503] do_syscall_64+0x5b/0x160
[ 14.219505] entry_SYSCALL_64_after_hwframe+0x4b/0x53
[ 14.219507] RIP: 0033:0x7f545a4bd96d
...
[ 14.219516] kobject: kobject_add_internal failed for somefunc,1 with
-EEXIST, don't try to register things with the same name ...This happens because klp_find_func() thinks somefunc with old_sympos==0 is not the same as somefunc with old_sympos==1, and klp_add_object_nops adds another xxx/func,1 to the list of functions to patch.
--- kernel/livepatch/core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
kernel/livepatch/core.c +7 -1
@@ -89,8 +89,14 @@ static struct klp_func *klp_find_func(struct klp_object *obj,struct klp_func *func;klp_for_each_func (obj, func) { +/* +* Besides identical old_sympos, also consider old_sympos +* of 0 and 1 are identical. +*/ if ((strcmp (old_func->old_name, func->old_name) ==0 ) && - (old_func->old_sympos == func->old_sympos)) { + ((old_func->old_sympos == func->old_sympos) || + (old_func->old_sympos ==0 && func->old_sympos ==1 ) || + (old_func->old_sympos ==1 && func->old_sympos ==0 ))) {return func; } }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 236/634 fs/ntfs3: Support timestamps prior to epoch
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konstantin Komarov <[email protected]>
[ Upstream commit 5180138604323895b5c291eca6aa7c20be494ade ]
Before it used an unsigned 64-bit type, which prevented proper handling of timestamps earlier than 1970-01-01. Switch to a signed 64-bit type to support pre-epoch timestamps. The issue was caught by xfstests.
--- fs/ntfs3/ntfs_fs.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
fs/ntfs3/ntfs_fs.h +5 -4
@@ -978,11 +978,12 @@ static inline __le64 kernel2nt(const struct timespec64 *ts)*/ static inline void nt2kernel (const __le64 tm,struct timespec64 *ts) { -u64 t =le64_to_cpu (tm) - _100ns2seconds * SecondsToStartOf1970; +s32 t32; +/* use signed 64 bit to support timestamps prior to epoch. xfstest 258. */ +s64 t =le64_to_cpu (tm) - _100ns2seconds * SecondsToStartOf1970; -// WARNING: do_div changes its first argument(!) - ts->tv_nsec =do_div (t, _100ns2seconds) *100 ; - ts->tv_sec = t; + ts->tv_sec =div_s64_rem (t, _100ns2seconds, &t32); + ts->tv_nsec = t32 *100 ; }static inline struct ntfs_sb_info *ntfs_sb (struct super_block *sb)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 237/634 kbuild: Use objtree for module signing key path
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Malyshev <[email protected]>
[ Upstream commit af61da281f52aba0c5b090bafb3a31c5739850ff ]
When building out-of-tree modules with CONFIG_MODULE_SIG_FORCE=y, module signing fails because the private key path uses $(srctree) while the public key path uses $(objtree). Since signing keys are generated in the build directory during kernel compilation, both paths should use $(objtree) for consistency.
This causes SSL errors like:
SSL error:02001002:system library:fopen:No such file or directory
sign-file: /kernel-src/certs/signing_key.pem
The issue occurs because:
- sig-key uses: $(srctree)/certs/signing_key.pem (source tree)
- cmd_sign uses: $(objtree)/certs/signing_key.x509 (build tree)
But both keys are generated in $(objtree) during the build.
This complements commit 25ff08aa43e37 ("kbuild: Fix signing issue for external modules") which fixed the scripts path and public key path, but missed the private key path inconsistency.
Fixes out-of-tree module signing for configurations with separate source and build directories (e.g., O=/kernel-out).
--- scripts/Makefile.modinst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/Makefile.modinst +1 -1
@@ -67,7 +67,7 @@ endif # ifeq ($(CONFIG_MODULE_SIG_ALL),y) ifeq ($(filter pkcs11:%, $(CONFIG_MODULE_SIG_KEY)),) -sig-key := $(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(srctree)/)$(CONFIG_MODULE_SIG_KEY) +sig-key := $(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(objtree)/)$(CONFIG_MODULE_SIG_KEY) else sig-key := $(CONFIG_MODULE_SIG_KEY) endif
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 238/634 hfsplus: fix volume corruption issue for generic/070
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Viacheslav Dubeyko <[email protected]>
[ Upstream commit ed490f36f439b877393c12a2113601e4145a5a56 ]
The xfstests' test-case generic/070 leaves HFS+ volume in corrupted state:
sudo ./check generic/070
FSTYP -- hfsplus
PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 MKFS_OPTIONS -- /dev/loop51MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch
generic/070 _check_generic_filesystem: filesystem on /dev/loop50 is inconsistent (see xfstests-dev/results//generic/070.full for details)
Ran: generic/070
Failures: generic/070
Failed 1 of 1 tests
sudo fsck.hfsplus -d /dev/loop50
** /dev/loop50
Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. Executing fsck_hfs (version 540.1-Linux).
** Checking non-journaled HFS Plus Volume.
The volume name is test
** Checking extents overflow file.
Unused node is not erased (node = 1)
** Checking catalog file.
** Checking multi-linked files.
** Checking catalog hierarchy.
** Checking extended attributes file.
** Checking volume bitmap.
** Checking volume information.
Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0004 CBTStat = 0x0000 CatStat = 0x00000000
** Repairing volume.
** Rechecking volume.
** Checking non-journaled HFS Plus Volume.
The volume name is test
** Checking extents overflow file.
** Checking catalog file.
** Checking multi-linked files.
** Checking catalog hierarchy.
** Checking extended attributes file.
** Checking volume bitmap.
** Checking volume information.
** The volume test was repaired successfully.
It is possible to see that fsck.hfsplus detected not erased and unused node for the case of extents overflow file. The HFS+ logic has special method that defines if the node should be erased:
bool hfs_bnode_need_zeroout(struct hfs_btree *tree)
{
struct super_block *sb = tree->inode->i_sb;
struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
const u32 volume_attr = be32_to_cpu(sbi->s_vhdr->attributes);
return tree->cnid == HFSPLUS_CAT_CNID &&
volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX;
}However, it is possible to see that this method works only for the case of catalog file. But debugging of the issue has shown that HFSPLUS_VOL_UNUSED_NODE_FIX attribute has been requested for the extents overflow file too:
catalog file
kernel: hfsplus: node 4, num_recs 0, flags 0x10
kernel: hfsplus: tree->cnid 4, volume_attr 0x80000800
extents overflow file
kernel: hfsplus: node 1, num_recs 0, flags 0x10
kernel: hfsplus: tree->cnid 3, volume_attr 0x80000800
This patch modifies the hfs_bnode_need_zeroout() by checking only volume_attr but not the b-tree ID because node zeroing can be requested for all HFS+ b-tree types.
sudo ./check generic/070
FSTYP -- hfsplus PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #79 SMP PREEMPT_DYNAMIC Fri Oct 31 16:07:42 PDT 2025 MKFS_OPTIONS -- /dev/loop51
MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch
generic/070 33s ... 34s
Ran: generic/070
Passed all 1 tests
--- fs/hfsplus/bnode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
fs/hfsplus/bnode.c +1 -2
@@ -704,6 +704,5 @@ bool hfs_bnode_need_zeroout(struct hfs_btree *tree)struct hfsplus_sb_info *sbi =HFSPLUS_SB (sb);const u32 volume_attr =be32_to_cpu (sbi->s_vhdr->attributes); -return tree->cnid ==HFSPLUS_CAT_CNID && - volume_attr &HFSPLUS_VOL_UNUSED_NODE_FIX ; +return volume_attr &HFSPLUS_VOL_UNUSED_NODE_FIX ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 239/634 hfsplus: fix missing hfs_bnode_get() in __hfs_bnode_create
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Chenzhi <[email protected]>
[ Upstream commit 152af114287851583cf7e0abc10129941f19466a ]
When sync() and link() are called concurrently, both threads may enter hfs_bnode_find() without finding the node in the hash table and proceed to create it.
Thread A:
hfsplus_write_inode()
-> hfsplus_write_system_inode()
-> hfs_btree_write()
-> hfs_bnode_find(tree, 0)
-> __hfs_bnode_create(tree, 0)Thread B:
hfsplus_create_cat()
-> hfs_brec_insert()
-> hfs_bnode_split()
-> hfs_bmap_alloc()
-> hfs_bnode_find(tree, 0)
-> __hfs_bnode_create(tree, 0)In this case, thread A creates the bnode, sets refcnt=1, and hashes it. Thread B also tries to create the same bnode, notices it has already been inserted, drops its own instance, and uses the hashed one without getting the node.
```
node2 = hfs_bnode_findhash(tree, cnid);
if (!node2) { <- Thread A
hash = hfs_bnode_hash(cnid);
node->next_hash = tree->node_hash[hash];
tree->node_hash[hash] = node;
tree->node_hash_cnt++;
} else { <- Thread B
spin_unlock(&tree->hash_lock);
kfree(node);
wait_event(node2->lock_wq,
!test_bit(HFS_BNODE_NEW, &node2->flags));
return node2;
}
```However, hfs_bnode_find() requires each call to take a reference. Here both threads end up setting refcnt=1. When they later put the node, this triggers:
BUG_ON(!atomic_read(&node->refcnt))
In this scenario, Thread B in fact finds the node in the hash table rather than creating a new one, and thus must take a reference.
Fix this by calling hfs_bnode_get() when reusing a bnode newly created by another thread to ensure the refcount is updated correctly.
A similar bug was fixed in HFS long ago in commit a9dc087fd3c4 ("fix missing hfs_bnode_get() in __hfs_bnode_create") but the same issue remained in HFS+ until now.
--- fs/hfsplus/bnode.c | 1 + 1 file changed, 1 insertion(+)
fs/hfsplus/bnode.c +1 -0
@@ -481,6 +481,7 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) tree->node_hash[hash] = node; tree->node_hash_cnt++; }else { +hfs_bnode_get (node2);spin_unlock (&tree->hash_lock);kfree (node); wait_event(node2->lock_wq,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 240/634 hfsplus: Verify inode mode when loading from disk
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tetsuo Handa <[email protected]>
[ Upstream commit 005d4b0d33f6b4a23d382b7930f7a96b95b01f39 ]
syzbot is reporting that S_IFMT bits of inode->i_mode can become bogus when the S_IFMT bits of the 16bits "mode" field loaded from disk are corrupted.
According to [1], the permissions field was treated as reserved in Mac OS 8 and 9. According to [2], the reserved field was explicitly initialized with 0, and that field must remain 0 as long as reserved. Therefore, when the "mode" field is not 0 (i.e. no longer reserved), the file must be S_IFDIR if dir == 1, and the file must be one of S_IFREG/S_IFLNK/S_IFCHR/ S_IFBLK/S_IFIFO/S_IFSOCK if dir == 0.
--- fs/hfsplus/inode.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-)
fs/hfsplus/inode.c +28 -4
@@ -183,13 +183,29 @@ const struct dentry_operations hfsplus_dentry_operations = { .d_compare = hfsplus_compare_dentry, }; -static void hfsplus_get_perms (struct inode *inode, -struct hfsplus_perm *perms,int dir) +static int hfsplus_get_perms (struct inode *inode, +struct hfsplus_perm *perms,int dir) {struct hfsplus_sb_info *sbi =HFSPLUS_SB (inode->i_sb);u16 mode; mode =be16_to_cpu (perms->mode); +if (dir) { +if (mode && !S_ISDIR (mode)) + goto bad_type; + }else if (mode) { +switch (mode &S_IFMT ) { +case S_IFREG : +case S_IFLNK : +case S_IFCHR : +case S_IFBLK : +case S_IFIFO : +case S_IFSOCK : +break ; +default : + goto bad_type; + } + }i_uid_write (inode,be32_to_cpu (perms->owner));if ((test_bit (HFSPLUS_SB_UID , &sbi->flags)) || (!i_uid_read (inode) && !mode))
@@ -215,6 +231,10 @@ static void hfsplus_get_perms(struct inode *inode, inode->i_flags |=S_APPEND ; else inode->i_flags &= ~S_APPEND; +return 0 ; +bad_type: +pr_err ("invalid file type 0%04o for inode %lu\n" , mode, inode->i_ino); +return -EIO ; }static int hfsplus_file_open (struct inode *inode,struct file *file)
@@ -518,7 +538,9 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) }hfs_bnode_read (fd->bnode, &entry, fd->entryoffset,sizeof (struct hfsplus_cat_folder )); -hfsplus_get_perms (inode, &folder->permissions,1 ); + res =hfsplus_get_perms (inode, &folder->permissions,1 ); +if (res) + goto out;set_nlink (inode,1 ); inode->i_size =2 +be32_to_cpu (folder->valence); inode->i_atime =hfsp_mt2ut (folder->access_date);
@@ -545,7 +567,9 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)hfsplus_inode_read_fork (inode,HFSPLUS_IS_RSRC (inode) ? &file->rsrc_fork : &file->data_fork); -hfsplus_get_perms (inode, &file->permissions,0 ); + res =hfsplus_get_perms (inode, &file->permissions,0 ); +if (res) + goto out;set_nlink (inode,1 );if (S_ISREG (inode->i_mode)) {if (file->permissions.dev)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 241/634 hfsplus: fix volume corruption issue for generic/073
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Viacheslav Dubeyko <[email protected]>
[ Upstream commit 24e17a29cf7537f0947f26a50f85319abd723c6c ]
The xfstests' test-case generic/073 leaves HFS+ volume in corrupted state:
sudo ./check generic/073
FSTYP -- hfsplus
PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 MKFS_OPTIONS -- /dev/loop51MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch
generic/073 _check_generic_filesystem: filesystem on /dev/loop51 is inconsistent (see XFSTESTS-2/xfstests-dev/results//generic/073.full for details)
Ran: generic/073
Failures: generic/073
Failed 1 of 1 tests
sudo fsck.hfsplus -d /dev/loop51
** /dev/loop51
Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. Executing fsck_hfs (version 540.1-Linux).
** Checking non-journaled HFS Plus Volume.
The volume name is untitled
** Checking extents overflow file.
** Checking catalog file.
** Checking multi-linked files.
** Checking catalog hierarchy.
Invalid directory item count
(It should be 1 instead of 0)
** Checking extended attributes file.
** Checking volume bitmap.
** Checking volume information.
Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0000 CBTStat = 0x0000 CatStat = 0x00004000
** Repairing volume.
** Rechecking volume.
** Checking non-journaled HFS Plus Volume.
The volume name is untitled
** Checking extents overflow file.
** Checking catalog file.
** Checking multi-linked files.
** Checking catalog hierarchy.
** Checking extended attributes file.
** Checking volume bitmap.
** Checking volume information.
** The volume untitled was repaired successfully.
The test is doing these steps on final phase:
mv $SCRATCH_MNT/testdir_1/bar $SCRATCH_MNT/testdir_2/bar $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/testdir_1 $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foo
So, we move file bar from testdir_1 into testdir_2 folder. It means that HFS+ logic decrements the number of entries in testdir_1 and increments number of entries in testdir_2. Finally, we do fsync only for testdir_1 and foo but not for testdir_2. As a result, this is the reason why fsck.hfsplus detects the volume corruption afterwards.
This patch fixes the issue by means of adding the hfsplus_cat_write_inode() call for old_dir and new_dir in hfsplus_rename() after the successful ending of hfsplus_rename_cat(). This method makes modification of in-core inode objects for old_dir and new_dir but it doesn't save these modifications in Catalog File's entries. It was expected that hfsplus_write_inode() will save these modifications afterwards. However, because generic/073 does fsync only for testdir_1 and foo then testdir_2 modification hasn't beed saved into Catalog File's entry and it was flushed without this modification. And it was detected by fsck.hfsplus. Now, hfsplus_rename() stores in Catalog File all modified entries and correct state of Catalog File will be flushed during hfsplus_file_fsync() call. Finally, it makes fsck.hfsplus happy.
sudo ./check generic/073
FSTYP -- hfsplus PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #93 SMP PREEMPT_DYNAMIC Wed Nov 12 14:37:49 PST 2025 MKFS_OPTIONS -- /dev/loop51
MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch
generic/073 32s ... 32s
Ran: generic/073
Passed all 1 tests
--- fs/hfsplus/dir.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
fs/hfsplus/dir.c +6 -1
@@ -552,8 +552,13 @@ static int hfsplus_rename(struct user_namespace *mnt_userns, res =hfsplus_rename_cat ((u32 )(unsigned long )old_dentry->d_fsdata, old_dir, &old_dentry->d_name, new_dir, &new_dentry->d_name); -if (!res) +if (!res) { new_dentry->d_fsdata = old_dentry->d_fsdata; + + res =hfsplus_cat_write_inode (old_dir); +if (!res) + res =hfsplus_cat_write_inode (new_dir); + }return res; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 242/634 wifi: brcmfmac: Add DMI nvram filename quirk for Acer A1 840 tablet
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
[ Upstream commit a8e5a110c0c38e08e5dd66356cd1156e91cf88e1 ]
The Acer A1 840 tablet contains quite generic names in the sys_vendor and product_name DMI strings, without this patch brcmfmac will try to load:
brcmfmac43340-sdio.Insyde-BayTrail.txt as nvram file which is a bit too generic.
Add a DMI quirk so that a unique and clearly identifiable nvram file name is used on the Acer A1 840 tablet.
--- .../net/wireless/broadcom/brcm80211/brcmfmac/dmi.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c +14 -0
@@ -24,6 +24,10 @@ static const struct brcmf_dmi_data acepc_t8_data = { BRCM_CC_4345_CHIP_ID, 6, "acepc-t8" }; +static const struct brcmf_dmi_data acer_a1_840_data = { +BRCM_CC_43340_CHIP_ID ,2 ,"acer-a1-840" +}; +/* The Chuwi Hi8 Pro uses the same Ampak AP6212 module as the Chuwi Vi8 Plus * and the nvram for the Vi8 Plus is already in linux-firmware, so use that. */
@@ -91,6 +95,16 @@ static const struct dmi_system_id dmi_platform_data[] = { }, .driver_data = (void *)&acepc_t8_data, }, + { +/* Acer Iconia One 8 A1-840 (non FHD version) */ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"Insyde" ), +DMI_MATCH (DMI_PRODUCT_NAME ,"BayTrail" ), +/* Above strings are too generic also match BIOS date */ + DMI_MATCH(DMI_BIOS_DATE, "04/01/2014"), + }, + .driver_data = (void *)&acer_a1_840_data, + }, {/* Chuwi Hi8 Pro with D2D3_Hi8Pro.233 BIOS */ .matches = {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 243/634 btrfs: scrub: always update btrfs_scrub_progress::last_physical
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
[ Upstream commit 54df8b80cc63aa0f22c4590cad11542731ed43ff ]
[BUG]
When a scrub failed immediately without any byte scrubbed, the returned btrfs_scrub_progress::last_physical will always be 0, even if there is a non-zero @start passed into btrfs_scrub_dev() for resume cases.
This will reset the progress and make later scrub resume start from the beginning.
[CAUSE]
The function btrfs_scrub_dev() accepts a @progress parameter to copy its updated progress to the caller, there are cases where we either don't touch progress::last_physical at all or copy 0 into last_physical:
- last_physical not updated at all
If some error happened before scrubbing any super block or chunk, we will not copy the progress, leaving the @last_physical untouched.
E.g. failed to allocate @sctx, scrubbing a missing device or even there is already a running scrub and so on.
All those cases won't touch @progress at all, resulting the last_physical untouched and will be left as 0 for most cases.
- Error out before scrubbing any bytes
In those case we allocated @sctx, and sctx->stat.last_physical is all zero (initialized by kvzalloc()).
Unfortunately some critical errors happened during scrub_enumerate_chunks() or scrub_supers() before any stripe is really scrubbed.
In that case although we will copy sctx->stat back to @progress, since no byte is really scrubbed, last_physical will be overwritten to 0.
[FIX]
Make sure the parameter @progress always has its @last_physical member updated to @start parameter inside btrfs_scrub_dev().
At the very beginning of the function, set @progress->last_physical to @start, so that even if we error out without doing progress copying, last_physical is still at @start.
Then after we got @sctx allocated, set sctx->stat.last_physical to @start, this will make sure even if we didn't get any byte scrubbed, at the progress copying stage the @last_physical is not left as zero.
This should resolve the resume progress reset problem.
--- fs/btrfs/scrub.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/btrfs/scrub.c +5 -0
@@ -4294,6 +4294,10 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,unsigned int nofs_flag;bool need_commit = false; +/* Set the basic fallback @last_physical before we got a sctx. */ +if (progress) + progress->last_physical = start; +if (btrfs_fs_closing (fs_info))return -EAGAIN ;
@@ -4312,6 +4316,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, sctx =scrub_setup_ctx (fs_info, is_dev_replace);if (IS_ERR (sctx))return PTR_ERR (sctx); + sctx->stat.last_physical = start; ret =scrub_workers_get (fs_info, is_dev_replace);if (ret)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 244/634 smb/server: fix return value of smb2_ioctl()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: ChenXiaoSong <[email protected]>
[ Upstream commit 269df046c1e15ab34fa26fd90db9381f022a0963 ]
__process_request() will not print error messages if smb2_ioctl() always returns 0.
Fix this by returning the correct value at the end of function.
--- fs/smb/server/smb2pdu.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
fs/smb/server/smb2pdu.c +6 -3
@@ -7727,7 +7727,7 @@ int smb2_ioctl(struct ksmbd_work *work) id = req->VolatileFileId;if (req->Flags !=cpu_to_le32 (SMB2_0_IOCTL_IS_FSCTL )) { - rsp->hdr.Status =STATUS_NOT_SUPPORTED ; + ret = -EOPNOTSUPP ; goto out; }
@@ -7747,8 +7747,9 @@ int smb2_ioctl(struct ksmbd_work *work)case FSCTL_DFS_GET_REFERRALS :case FSCTL_DFS_GET_REFERRALS_EX :/* Not support DFS yet */ + ret = -EOPNOTSUPP ; rsp->hdr.Status =STATUS_FS_DRIVER_REQUIRED ; - goto out; + goto out2;case FSCTL_CREATE_OR_GET_OBJECT_ID : {struct file_object_buf_type1_ioctl_rsp *obj_buf;
@@ -8038,8 +8039,10 @@ int smb2_ioctl(struct ksmbd_work *work) rsp->hdr.Status =STATUS_BUFFER_TOO_SMALL ; else if (ret < 0 || rsp->hdr.Status == 0) rsp->hdr.Status =STATUS_INVALID_PARAMETER ; + +out2:smb2_set_err_rsp (work); -return 0 ; +return ret; }/**
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 245/634 ksmbd: fix use-after-free in ksmbd_tree_connect_put under concurrency
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ Upstream commit b39a1833cc4a2755b02603eec3a71a85e9dff926 ]
Under high concurrency, A tree-connection object (tcon) is freed on a disconnect path while another path still holds a reference and later executes *_put()/write on it.
--- fs/smb/server/mgmt/tree_connect.c | 18 ++++-------------- fs/smb/server/mgmt/tree_connect.h | 1 - fs/smb/server/smb2pdu.c | 3 --- 3 files changed, 4 insertions(+), 18 deletions(-)
fs/smb/server/mgmt/tree_connect.c +4 -14
@@ -77,7 +77,6 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name) tree_conn->t_state =TREE_NEW ; status.tree_conn = tree_conn;atomic_set (&tree_conn->refcount,1 ); -init_waitqueue_head (&tree_conn->refcount_q); ret =xa_err (xa_store (&sess->tree_conns, tree_conn->id, tree_conn,GFP_KERNEL ));
@@ -99,14 +98,8 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name)void ksmbd_tree_connect_put (struct ksmbd_tree_connect *tcon) { -/* -* Checking waitqueue to releasing tree connect on -* tree disconnect. waitqueue_active is safe because it -* uses atomic operation for condition. -*/ -if (!atomic_dec_return (&tcon->refcount) && -waitqueue_active (&tcon->refcount_q)) -wake_up (&tcon->refcount_q); +if (atomic_dec_and_test (&tcon->refcount)) +kfree (tcon); } int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess,
@@ -118,14 +111,11 @@ int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess,xa_erase (&sess->tree_conns, tree_conn->id);write_unlock (&sess->tree_conns_lock); -if (!atomic_dec_and_test (&tree_conn->refcount)) -wait_event (tree_conn->refcount_q, -atomic_read (&tree_conn->refcount) ==0 ); - ret =ksmbd_ipc_tree_disconnect_request (sess->id, tree_conn->id);ksmbd_release_tree_conn_id (sess, tree_conn->id);ksmbd_share_config_put (tree_conn->share_conf); -kfree (tree_conn); +if (atomic_dec_and_test (&tree_conn->refcount)) +kfree (tree_conn);return ret; }
fs/smb/server/mgmt/tree_connect.h +0 -1
@@ -33,7 +33,6 @@ struct ksmbd_tree_connect {int maximal_access;bool posix_extensions;atomic_t refcount; -wait_queue_head_t refcount_q;unsigned int t_state; };
fs/smb/server/smb2pdu.c +0 -3
@@ -2181,7 +2181,6 @@ int smb2_tree_disconnect(struct ksmbd_work *work) goto err_out; } -WARN_ON_ONCE (atomic_dec_and_test (&tcon->refcount)); tcon->t_state =TREE_DISCONNECTED ;write_unlock (&sess->tree_conns_lock);
@@ -2191,8 +2190,6 @@ int smb2_tree_disconnect(struct ksmbd_work *work) goto err_out; } - work->tcon =NULL ; - rsp->StructureSize =cpu_to_le16 (4 ); err =ksmbd_iov_pin_rsp (work, rsp,sizeof (struct smb2_tree_disconnect_rsp ));
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 246/634 Bluetooth: btusb: Add new VID/PID 13d3/3533 for RTL8821CE
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gongwei Li <[email protected]>
[ Upstream commit 525459da4bd62a81142fea3f3d52188ceb4d8907 ]
Add VID 13d3 & PID 3533 for Realtek RTL8821CE USB Bluetooth chip.
The information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below.
T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=13d3 ProdID=3533 Rev= 1.10 S: Manufacturer=Realtek S: Product=Bluetooth Radio S: SerialNumber=00e04c000001 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
--- drivers/bluetooth/btusb.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/bluetooth/btusb.c +2 -0
@@ -496,6 +496,8 @@ static const struct usb_device_id blacklist_table[] = {/* Realtek 8821CE Bluetooth devices */ { USB_DEVICE(0x13d3, 0x3529), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3533), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, /* Realtek 8822CE Bluetooth devices */ { USB_DEVICE(0x0bda, 0xb00c), .driver_info = BTUSB_REALTEK |
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 247/634 gfs2: Fix use of bio_chain
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Gruenbacher <[email protected]>
[ Upstream commit 8a157e0a0aa5143b5d94201508c0ca1bb8cfb941 ]
In gfs2_chain_bio(), the call to bio_chain() has its arguments swapped. The result is leaked bios and incorrect synchronization (only the last bio will actually be waited for). This code is only used during mount and filesystem thaw, so the bug normally won't be noticeable.
--- fs/gfs2/lops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/gfs2/lops.c +1 -1
@@ -491,7 +491,7 @@ static struct bio *gfs2_chain_bio(struct bio *prev, unsigned int nr_iovecs) new =bio_alloc (prev->bi_bdev, nr_iovecs, prev->bi_opf,GFP_NOIO );bio_clone_blkg_association (new, prev); new->bi_iter.bi_sector =bio_end_sector (prev); -bio_chain (new, prev); +bio_chain (prev, new);submit_bio (prev);return new; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 248/634 netrom: Fix memory leak in nr_sendmsg()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Liang <[email protected]>
[ Upstream commit 613d12dd794e078be8ff3cf6b62a6b9acf7f4619 ]
syzbot reported a memory leak [1].
When function sock_alloc_send_skb() return NULL in nr_output(), the original skb is not freed, which was allocated in nr_sendmsg(). Fix this by freeing it before return.
[1]
BUG: memory leak
unreferenced object 0xffff888129f35500 (size 240):
comm "syz.0.17", pid 6119, jiffies 4294944652
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 10 52 28 81 88 ff ff ..........R(....
backtrace (crc 1456a3e4):
kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
slab_post_alloc_hook mm/slub.c:4983 [inline]
slab_alloc_node mm/slub.c:5288 [inline]
kmem_cache_alloc_node_noprof+0x36f/0x5e0 mm/slub.c:5340
__alloc_skb+0x203/0x240 net/core/skbuff.c:660
alloc_skb include/linux/skbuff.h:1383 [inline]
alloc_skb_with_frags+0x69/0x3f0 net/core/skbuff.c:6671
sock_alloc_send_pskb+0x379/0x3e0 net/core/sock.c:2965
sock_alloc_send_skb include/net/sock.h:1859 [inline]
nr_sendmsg+0x287/0x450 net/netrom/af_netrom.c:1105
sock_sendmsg_nosec net/socket.c:727 [inline]
__sock_sendmsg net/socket.c:742 [inline]
sock_write_iter+0x293/0x2a0 net/socket.c:1195
new_sync_write fs/read_write.c:593 [inline]
vfs_write+0x45d/0x710 fs/read_write.c:686
ksys_write+0x143/0x170 fs/read_write.c:738
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xa4/0xfa0 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f--- net/netrom/nr_out.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/netrom/nr_out.c +3 -1
@@ -43,8 +43,10 @@ void nr_output(struct sock *sk, struct sk_buff *skb) frontlen =skb_headroom (skb);while (skb->len >0 ) { -if ((skbn =sock_alloc_send_skb (sk, frontlen +NR_MAX_PACKET_SIZE ,0 , &err)) ==NULL ) +if ((skbn =sock_alloc_send_skb (sk, frontlen +NR_MAX_PACKET_SIZE ,0 , &err)) ==NULL ) { +kfree_skb (skb);return ; + }skb_reserve (skbn, frontlen);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 249/634 net/sched: ets: Always remove class from active list before deleting in ets_qdisc_change
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <[email protected]>
[ Upstream commit ce052b9402e461a9aded599f5b47e76bc727f7de ]
[email protected] says:
The vulnerability is a race condition between ets_qdisc_dequeue and ets_qdisc_change. It leads to UAF on struct Qdisc object. Attacker requires the capability to create new user and network namespace in order to trigger the bug.
See my additional commentary at the end of the analysis.
Analysis:
static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{
...
// (1) this lock is preventing .change handler (`ets_qdisc_change`)
//to race with .dequeue handler (`ets_qdisc_dequeue`)
sch_tree_lock(sch);
for (i = nbands; i < oldbands; i++) {
if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
list_del_init(&q->classes[i].alist);
qdisc_purge_queue(q->classes[i].qdisc);
}
WRITE_ONCE(q->nbands, nbands);
for (i = nstrict; i < q->nstrict; i++) {
if (q->classes[i].qdisc->q.qlen) {
// (2) the class is added to the q->active
list_add_tail(&q->classes[i].alist, &q->active);
q->classes[i].deficit = quanta[i];
}
}
WRITE_ONCE(q->nstrict, nstrict);
memcpy(q->prio2band, priomap, sizeof(priomap));
for (i = 0; i < q->nbands; i++)
WRITE_ONCE(q->classes[i].quantum, quanta[i]);
for (i = oldbands; i < q->nbands; i++) {
q->classes[i].qdisc = queues[i];
if (q->classes[i].qdisc != &noop_qdisc)
qdisc_hash_add(q->classes[i].qdisc, true);
}
// (3) the qdisc is unlocked, now dequeue can be called in parallel
// to the rest of .change handler
sch_tree_unlock(sch);
ets_offload_change(sch);
for (i = q->nbands; i < oldbands; i++) {
// (4) we're reducing the refcount for our class's qdisc and
// freeing it
qdisc_put(q->classes[i].qdisc);
// (5) If we call .dequeue between (4) and (5), we will have
// a strong UAF and we can control RIP
q->classes[i].qdisc = NULL;
WRITE_ONCE(q->classes[i].quantum, 0);
q->classes[i].deficit = 0;
gnet_stats_basic_sync_init(&q->classes[i].bstats);
memset(&q->classes[i].qstats, 0, sizeof(q->classes[i].qstats));
}
return 0;
}Comment:
This happens because some of the classes have their qdiscs assigned to NULL, but remain in the active list. This commit fixes this issue by always removing the class from the active list before deleting and freeing its associated qdisc
Reproducer Steps
(trimmed version of what was sent by [email protected])
```
DEV="${DEV:-lo}"
ROOT_HANDLE="${ROOT_HANDLE:-1:}"
BAND2_HANDLE="${BAND2_HANDLE:-20:}" # child under 1:2
PING_BYTES="${PING_BYTES:-48}"
PING_COUNT="${PING_COUNT:-200000}"
PING_DST="${PING_DST:-127.0.0.1}"
SLOW_TBF_RATE="${SLOW_TBF_RATE:-8bit}"
SLOW_TBF_BURST="${SLOW_TBF_BURST:-100b}"
SLOW_TBF_LAT="${SLOW_TBF_LAT:-1s}"
cleanup() {
tc qdisc del dev "$DEV" root 2>/dev/null
}
trap cleanup EXIT
ip link set "$DEV" up
tc qdisc del dev "$DEV" root 2>/dev/null || true
tc qdisc add dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2
tc qdisc add dev "$DEV" parent 1:2 handle "$BAND2_HANDLE" \
tbf rate "$SLOW_TBF_RATE" burst "$SLOW_TBF_BURST" latency "$SLOW_TBF_LAT"
tc filter add dev "$DEV" parent 1: protocol all prio 1 u32 match u32 0 0 flowid 1:2
tc -s qdisc ls dev $DEV
ping -I "$DEV" -f -c "$PING_COUNT" -s "$PING_BYTES" -W 0.001 "$PING_DST" \
>/dev/null 2>&1 &
tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 0
tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2
tc -s qdisc ls dev $DEV
tc qdisc del dev "$DEV" parent 1:2 || true
tc -s qdisc ls dev $DEV
tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 1 strict 1
```KASAN report
```
==================================================================
BUG: KASAN: slab-use-after-free in ets_qdisc_dequeue+0x1071/0x11b0 kernel/net/sched/sch_ets.c:481 Read of size 8 at addr ffff8880502fc018 by task ping/12308
Quoted 1 line
CPU: 0 UID: 0 PID: 12308 Comm: ping Not tainted 6.18.0-rc4-dirty #1 PREEMPT(full) Hardware name: QEMU Ubuntu 25.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 Call Trace: <IRQ> __dump_stack kernel/lib/dump_stack.c:94 dump_stack_lvl+0x100/0x190 kernel/lib/dump_stack.c:120 print_address_description kernel/mm/kasan/report.c:378 print_report+0x156/0x4c9 kernel/mm/kasan/report.c:482 kasan_report+0xdf/0x110 kernel/mm/kasan/report.c:595 ets_qdisc_dequeue+0x1071/0x11b0 kernel/net/sched/sch_ets.c:481 dequeue_skb kernel/net/sched/sch_generic.c:294 qdisc_restart kernel/net/sched/sch_generic.c:399 __qdisc_run+0x1c9/0x1b00 kernel/net/sched/sch_generic.c:417 __dev_xmit_skb kernel/net/core/dev.c:4221 __dev_queue_xmit+0x2848/0x4410 kernel/net/core/dev.c:4729 dev_queue_xmit kernel/./include/linux/netdevice.h:3365
[...]
Allocated by task 17115: kasan_save_stack+0x30/0x50 kernel/mm/kasan/common.c:56 kasan_save_track+0x14/0x30 kernel/mm/kasan/common.c:77 poison_kmalloc_redzone kernel/mm/kasan/common.c:400 __kasan_kmalloc+0xaa/0xb0 kernel/mm/kasan/common.c:417 kasan_kmalloc kernel/./include/linux/kasan.h:262 __do_kmalloc_node kernel/mm/slub.c:5642 __kmalloc_node_noprof+0x34e/0x990 kernel/mm/slub.c:5648 kmalloc_node_noprof kernel/./include/linux/slab.h:987 qdisc_alloc+0xb8/0xc30 kernel/net/sched/sch_generic.c:950 qdisc_create_dflt+0x93/0x490 kernel/net/sched/sch_generic.c:1012 ets_class_graft+0x4fd/0x800 kernel/net/sched/sch_ets.c:261 qdisc_graft+0x3e4/0x1780 kernel/net/sched/sch_api.c:1196
[...]
Freed by task 9905: kasan_save_stack+0x30/0x50 kernel/mm/kasan/common.c:56 kasan_save_track+0x14/0x30 kernel/mm/kasan/common.c:77 __kasan_save_free_info+0x3b/0x70 kernel/mm/kasan/generic.c:587 kasan_save_free_info kernel/mm/kasan/kasan.h:406 poison_slab_object kernel/mm/kasan/common.c:252 __kasan_slab_free+0x5f/0x80 kernel/mm/kasan/common.c:284 kasan_slab_free kernel/./include/linux/kasan.h:234 slab_free_hook kernel/mm/slub.c:2539 slab_free kernel/mm/slub.c:6630 kfree+0x144/0x700 kernel/mm/slub.c:6837 rcu_do_batch kernel/kernel/rcu/tree.c:2605 rcu_core+0x7c0/0x1500 kernel/kernel/rcu/tree.c:2861 handle_softirqs+0x1ea/0x8a0 kernel/kernel/softirq.c:622 __do_softirq kernel/kernel/softirq.c:656
[...]
Commentary:
1. Maher Azzouzi working with Trend Micro Zero Day Initiative was reported as the person who found the issue. I requested to get a proper email to add to the reported-by tag but got no response. For this reason i will credit the person i exchanged emails with i.e [email protected]
2. Neither i nor Victor who did a much more thorough testing was able to reproduce a UAF with the PoC or other approaches we tried. We were both able to reproduce a null ptr deref. After exchange with [email protected] they sent a small change to be made to the code to add an extra delay which was able to simulate the UAF. i.e, this:
qdisc_put(q->classes[i].qdisc);
mdelay(90);
q->classes[i].qdisc = NULL;
I was informed by Thomas Gleixner([email protected]) that adding delays was acceptable approach for demonstrating the bug, quote:
"Adding such delays is common exploit validation practice"
The equivalent delay could happen "by virt scheduling the vCPU out, SMIs, NMIs, PREEMPT_RT enabled kernel"
3. I asked the OP to test and report back but got no response and after a few days gave up and proceeded to submit this fix.
--- net/sched/sch_ets.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/sched/sch_ets.c +1 -1
@@ -652,7 +652,7 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,sch_tree_lock (sch);for (i = nbands; i < oldbands; i++) { -if (i >= q->nstrict && q->classes[i].qdisc->q.qlen) +if (cl_is_active (&q->classes[i]))list_del_init (&q->classes[i].alist);qdisc_purge_queue (q->classes[i].qdisc); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 250/634 ipvlan: Ignore PACKET_LOOPBACK in handle_mode_l2()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Skorodumov <[email protected]>
[ Upstream commit 0c57ff008a11f24f7f05fa760222692a00465fec ]
Packets with pkt_type == PACKET_LOOPBACK are captured by handle_frame() function, but they don't have L2 header. We should not process them in handle_mode_l2().
This doesn't affect old L2 functionality, since handling was anyway incorrect.
Handle them the same way as in br_handle_frame():
just pass the skb.
To observe invalid behaviour, just start "ping -b" on bcast address of port-interface.
--- drivers/net/ipvlan/ipvlan_core.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ipvlan/ipvlan_core.c +3 -0
@@ -738,6 +738,9 @@ static rx_handler_result_t ipvlan_handle_mode_l2(struct sk_buff **pskb,struct ethhdr *eth =eth_hdr (skb);rx_handler_result_t ret =RX_HANDLER_PASS ; +if (unlikely (skb->pkt_type ==PACKET_LOOPBACK )) +return RX_HANDLER_PASS ; +if (is_multicast_ether_addr (eth->h_dest)) {if (ipvlan_external_frame (skb, port)) {struct sk_buff *nskb =skb_clone (skb,GFP_ATOMIC );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 251/634 mlxsw: spectrum_router: Fix neighbour use-after-free
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <[email protected]>
[ Upstream commit 8b0e69763ef948fb872a7767df4be665d18f5fd4 ]
We sometimes observe use-after-free when dereferencing a neighbour [1]. The problem seems to be that the driver stores a pointer to the neighbour, but without holding a reference on it. A reference is only taken when the neighbour is used by a nexthop.
Fix by simplifying the reference counting scheme. Always take a reference when storing a neighbour pointer in a neighbour entry. Avoid taking a referencing when the neighbour is used by a nexthop as the neighbour entry associated with the nexthop already holds a reference.
Tested by running the test that uncovered the problem over 300 times. Without this patch the problem was reproduced after a handful of iterations.
[1]
BUG: KASAN: slab-use-after-free in mlxsw_sp_neigh_entry_update+0x2d4/0x310 Read of size 8 at addr ffff88817f8e3420 by task ip/3929 CPU: 3 UID: 0 PID: 3929 Comm: ip Not tainted 6.18.0-rc4-virtme-g36b21a067510 #3 PREEMPT(full) Hardware name: Nvidia SN5600/VMOD0013, BIOS 5.13 05/31/2023 Call Trace: <TASK> dump_stack_lvl+0x6f/0xa0 print_address_description.constprop.0+0x6e/0x300 print_report+0xfc/0x1fb kasan_report+0xe4/0x110 mlxsw_sp_neigh_entry_update+0x2d4/0x310 mlxsw_sp_router_rif_gone_sync+0x35f/0x510 mlxsw_sp_rif_destroy+0x1ea/0x730 mlxsw_sp_inetaddr_port_vlan_event+0xa1/0x1b0 __mlxsw_sp_inetaddr_lag_event+0xcc/0x130 __mlxsw_sp_inetaddr_event+0xf5/0x3c0 mlxsw_sp_router_netdevice_event+0x1015/0x1580 notifier_call_chain+0xcc/0x150 call_netdevice_notifiers_info+0x7e/0x100 __netdev_upper_dev_unlink+0x10b/0x210 netdev_upper_dev_unlink+0x79/0xa0 vrf_del_slave+0x18/0x50 do_set_master+0x146/0x7d0 do_setlink.isra.0+0x9a0/0x2880 rtnl_newlink+0x637/0xb20 rtnetlink_rcv_msg+0x6fe/0xb90 netlink_rcv_skb+0x123/0x380 netlink_unicast+0x4a3/0x770 netlink_sendmsg+0x75b/0xc90 __sock_sendmsg+0xbe/0x160 ____sys_sendmsg+0x5b2/0x7d0 ___sys_sendmsg+0xfd/0x180 __sys_sendmsg+0x124/0x1c0 do_syscall_64+0xbb/0xfd0 entry_SYSCALL_64_after_hwframe+0x4b/0x53
[...]
Allocated by task 109: kasan_save_stack+0x30/0x50 kasan_save_track+0x14/0x30 __kasan_kmalloc+0x7b/0x90 __kmalloc_noprof+0x2c1/0x790 neigh_alloc+0x6af/0x8f0 ___neigh_create+0x63/0xe90 mlxsw_sp_nexthop_neigh_init+0x430/0x7e0 mlxsw_sp_nexthop_type_init+0x212/0x960 mlxsw_sp_nexthop6_group_info_init.constprop.0+0x81f/0x1280 mlxsw_sp_nexthop6_group_get+0x392/0x6a0 mlxsw_sp_fib6_entry_create+0x46a/0xfd0 mlxsw_sp_router_fib6_replace+0x1ed/0x5f0 mlxsw_sp_router_fib6_event_work+0x10a/0x2a0 process_one_work+0xd57/0x1390 worker_thread+0x4d6/0xd40 kthread+0x355/0x5b0 ret_from_fork+0x1d4/0x270 ret_from_fork_asm+0x11/0x20 Freed by task 154: kasan_save_stack+0x30/0x50 kasan_save_track+0x14/0x30 __kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x43/0x70 kmem_cache_free_bulk.part.0+0x1eb/0x5e0 kvfree_rcu_bulk+0x1f2/0x260 kfree_rcu_work+0x130/0x1b0 process_one_work+0xd57/0x1390 worker_thread+0x4d6/0xd40 kthread+0x355/0x5b0 ret_from_fork+0x1d4/0x270 ret_from_fork_asm+0x11/0x20 Last potentially related work creation: kasan_save_stack+0x30/0x50 kasan_record_aux_stack+0x8c/0xa0 kvfree_call_rcu+0x93/0x5b0 mlxsw_sp_router_neigh_event_work+0x67d/0x860 process_one_work+0xd57/0x1390 worker_thread+0x4d6/0xd40 kthread+0x355/0x5b0 ret_from_fork+0x1d4/0x270 ret_from_fork_asm+0x11/0x20
--- .../ethernet/mellanox/mlxsw/spectrum_router.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +9 -8
@@ -2163,6 +2163,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,if (!neigh_entry)return NULL ; +neigh_hold (n); neigh_entry->key.n = n; neigh_entry->rif = rif;INIT_LIST_HEAD (&neigh_entry->nexthop_list);
@@ -2172,6 +2173,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,static void mlxsw_sp_neigh_entry_free (struct mlxsw_sp_neigh_entry *neigh_entry) { +neigh_release (neigh_entry->key.n);kfree (neigh_entry); }
@@ -4027,6 +4029,8 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,if (err) goto err_neigh_entry_insert; +neigh_release (old_n); +read_lock_bh (&n->lock); nud_state = n->nud_state; dead = n->dead;
@@ -4035,14 +4039,10 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,list_for_each_entry (nh, &neigh_entry->nexthop_list, neigh_list_node) { -neigh_release (old_n); -neigh_clone (n);__mlxsw_sp_nexthop_neigh_update (nh, !entry_connected);mlxsw_sp_nexthop_group_refresh (mlxsw_sp, nh->nhgi->nh_grp); } -neigh_release (n); -return 0 ; err_neigh_entry_insert:
@@ -4130,6 +4130,11 @@ static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp, } } +/* Release the reference taken by neigh_lookup() / neigh_create() since +* neigh_entry already holds one. +*/ +neigh_release (n); +/* If that is the first nexthop connected to that neigh, add to * nexthop_neighs_list */
@@ -4156,11 +4161,9 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_nexthop *nh) {struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry; -struct neighbour *n;if (!neigh_entry)return ; - n = neigh_entry->key.n;__mlxsw_sp_nexthop_neigh_update (nh, true);list_del (&nh->neigh_list_node);
@@ -4174,8 +4177,6 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,if (!neigh_entry->connected &&list_empty (&neigh_entry->nexthop_list))mlxsw_sp_neigh_entry_destroy (mlxsw_sp, neigh_entry); - -neigh_release (n); }static bool mlxsw_sp_ipip_netdev_ul_up (struct net_device *ol_dev)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 252/634 mlxsw: spectrum_mr: Fix use-after-free when updating multicast route stats
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <[email protected]>
[ Upstream commit 8ac1dacec458f55f871f7153242ed6ab60373b90 ]
Cited commit added a dedicated mutex (instead of RTNL) to protect the multicast route list, so that it will not change while the driver periodically traverses it in order to update the kernel about multicast route stats that were queried from the device.
One instance of list entry deletion (during route replace) was missed and it can result in a use-after-free [1].
Fix by acquiring the mutex before deleting the entry from the list and releasing it afterwards.
[1]
BUG: KASAN: slab-use-after-free in mlxsw_sp_mr_stats_update+0x4a5/0x540 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:1006 [mlxsw_spectrum] Read of size 8 at addr ffff8881523c2fa8 by task kworker/2:5/22043 CPU: 2 UID: 0 PID: 22043 Comm: kworker/2:5 Not tainted 6.18.0-rc1-custom-g1a3d6d7cd014 #1 PREEMPT(full) Hardware name: Mellanox Technologies Ltd. MSN2010/SA002610, BIOS 5.6.5 08/24/2017 Workqueue: mlxsw_core mlxsw_sp_mr_stats_update [mlxsw_spectrum] Call Trace: <TASK> dump_stack_lvl+0xba/0x110 print_report+0x174/0x4f5 kasan_report+0xdf/0x110 mlxsw_sp_mr_stats_update+0x4a5/0x540 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:1006 [mlxsw_spectrum] process_one_work+0x9cc/0x18e0 worker_thread+0x5df/0xe40 kthread+0x3b8/0x730 ret_from_fork+0x3e9/0x560 ret_from_fork_asm+0x1a/0x30 </TASK> Allocated by task 29933: kasan_save_stack+0x30/0x50 kasan_save_track+0x14/0x30 __kasan_kmalloc+0x8f/0xa0 mlxsw_sp_mr_route_add+0xd8/0x4770 [mlxsw_spectrum] mlxsw_sp_router_fibmr_event_work+0x371/0xad0 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:7965 [mlxsw_spectrum] process_one_work+0x9cc/0x18e0 worker_thread+0x5df/0xe40 kthread+0x3b8/0x730 ret_from_fork+0x3e9/0x560 ret_from_fork_asm+0x1a/0x30 Freed by task 29933: kasan_save_stack+0x30/0x50 kasan_save_track+0x14/0x30 __kasan_save_free_info+0x3b/0x70 __kasan_slab_free+0x43/0x70 kfree+0x14e/0x700 mlxsw_sp_mr_route_add+0x2dea/0x4770 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:444 [mlxsw_spectrum] mlxsw_sp_router_fibmr_event_work+0x371/0xad0 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:7965 [mlxsw_spectrum] process_one_work+0x9cc/0x18e0 worker_thread+0x5df/0xe40 kthread+0x3b8/0x730 ret_from_fork+0x3e9/0x560 ret_from_fork_asm+0x1a/0x30
--- drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c +2 -0
@@ -440,7 +440,9 @@ int mlxsw_sp_mr_route_add(struct mlxsw_sp_mr_table *mr_table,rhashtable_remove_fast (&mr_table->route_ht, &mr_orig_route->ht_node, mlxsw_sp_mr_route_ht_params); +mutex_lock (&mr_table->route_list_lock);list_del (&mr_orig_route->node); +mutex_unlock (&mr_table->route_list_lock);mlxsw_sp_mr_route_destroy (mr_table, mr_orig_route); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 253/634 net: openvswitch: fix middle attribute validation in push_nsh() action
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Maximets <[email protected]>
[ Upstream commit 5ace7ef87f059d68b5f50837ef3e8a1a4870c36e ]
The push_nsh() action structure looks like this:
OVS_ACTION_ATTR_PUSH_NSH(OVS_KEY_ATTR_NSH(OVS_NSH_KEY_ATTR_BASE,...))
The outermost OVS_ACTION_ATTR_PUSH_NSH attribute is OK'ed by the nla_for_each_nested() inside __ovs_nla_copy_actions(). The innermost OVS_NSH_KEY_ATTR_BASE/MD1/MD2 are OK'ed by the nla_for_each_nested() inside nsh_key_put_from_nlattr(). But nothing checks if the attribute in the middle is OK. We don't even check that this attribute is the OVS_KEY_ATTR_NSH. We just do a double unwrap with a pair of nla_data() calls - first time directly while calling validate_push_nsh() and the second time as part of the nla_for_each_nested() macro, which isn't safe, potentially causing invalid memory access if the size of this attribute is incorrect. The failure may not be noticed during validation due to larger netlink buffer, but cause trouble later during action execution where the buffer is allocated exactly to the size:
BUG: KASAN: slab-out-of-bounds in nsh_hdr_from_nlattr+0x1dd/0x6a0 [openvswitch] Read of size 184 at addr ffff88816459a634 by task a.out/22624 CPU: 8 UID: 0 PID: 22624 6.18.0-rc7+ #115 PREEMPT(voluntary) Call Trace: <TASK> dump_stack_lvl+0x51/0x70 print_address_description.constprop.0+0x2c/0x390 kasan_report+0xdd/0x110 kasan_check_range+0x35/0x1b0 __asan_memcpy+0x20/0x60 nsh_hdr_from_nlattr+0x1dd/0x6a0 [openvswitch] push_nsh+0x82/0x120 [openvswitch] do_execute_actions+0x1405/0x2840 [openvswitch] ovs_execute_actions+0xd5/0x3b0 [openvswitch] ovs_packet_cmd_execute+0x949/0xdb0 [openvswitch] genl_family_rcv_msg_doit+0x1d6/0x2b0 genl_family_rcv_msg+0x336/0x580 genl_rcv_msg+0x9f/0x130 netlink_rcv_skb+0x11f/0x370 genl_rcv+0x24/0x40 netlink_unicast+0x73e/0xaa0 netlink_sendmsg+0x744/0xbf0 __sys_sendto+0x3d6/0x450 do_syscall_64+0x79/0x2c0 entry_SYSCALL_64_after_hwframe+0x76/0x7e </TASK>
Let's add some checks that the attribute is properly sized and it's the only one attribute inside the action. Technically, there is no real reason for OVS_KEY_ATTR_NSH to be there, as we know that we're pushing an NSH header already, it just creates extra nesting, but that's how uAPI works today. So, keeping as it is.
--- net/openvswitch/flow_netlink.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
net/openvswitch/flow_netlink.c +10 -3
@@ -2786,13 +2786,20 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,return err; } -static bool validate_push_nsh (const struct nlattr *attr,bool log) +static bool validate_push_nsh (const struct nlattr *a,bool log) { +struct nlattr *nsh_key =nla_data (a);struct sw_flow_match match;struct sw_flow_key key; +/* There must be one and only one NSH header. */ +if (!nla_ok (nsh_key,nla_len (a)) || +nla_total_size (nla_len (nsh_key)) !=nla_len (a) || +nla_type (nsh_key) !=OVS_KEY_ATTR_NSH ) +return false; +ovs_match_init (&match, &key, true,NULL ); -return !nsh_key_put_from_nlattr (attr, &match, false, true, log); +return !nsh_key_put_from_nlattr (nsh_key, &match, false, true, log); }/* Return false if there are any non-masked bits set.
@@ -3346,7 +3353,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,return -EINVAL ; } mac_proto =MAC_PROTO_NONE ; -if (!validate_push_nsh (nla_data (a), log)) +if (!validate_push_nsh (a, log))return -EINVAL ;break ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 254/634 broadcom: b44: prevent uninitialized value usage
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Simakov <[email protected]>
[ Upstream commit 50b3db3e11864cb4e18ff099cfb38e11e7f87a68 ]
On execution path with raised B44_FLAG_EXTERNAL_PHY, b44_readphy() leaves bmcr value uninitialized and it is used later in the code.
Add check of this flag at the beginning of the b44_nway_reset() and exit early of the function with restarting autonegotiation if an external PHY is used.
--- drivers/net/ethernet/broadcom/b44.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/broadcom/b44.c +3 -0
@@ -1811,6 +1811,9 @@ static int b44_nway_reset(struct net_device *dev)u32 bmcr;int r; +if (bp->flags &B44_FLAG_EXTERNAL_PHY ) +return phy_ethtool_nway_reset (dev); +spin_lock_irq (&bp->lock);b44_readphy (bp,MII_BMCR , &bmcr);b44_readphy (bp,MII_BMCR , &bmcr);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 255/634 netfilter: nf_conncount: fix leaked ct in error paths
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fernando Fernandez Mancera <[email protected]>
[ Upstream commit 2e2a720766886190a6d35c116794693aabd332b6 ]
There are some situations where ct might be leaked as error paths are skipping the refcounted check and return immediately. In order to solve it make sure that the check is always called.
--- net/netfilter/nf_conncount.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-)
net/netfilter/nf_conncount.c +14 -11
@@ -172,14 +172,14 @@ static int __nf_conncount_add(struct net *net,struct nf_conn *found_ct;unsigned int collect =0 ;bool refcounted = false; +int err =0 ;if (!get_ct_or_tuple_from_skb (net, skb, l3num, &ct, &tuple, &zone, &refcounted))return -ENOENT ;if (ct &&nf_ct_is_confirmed (ct)) { -if (refcounted) -nf_ct_put (ct); -return -EEXIST ; + err = -EEXIST ; + goto out_put; }if ((u32 )jiffies == list->last_gc)
@@ -231,12 +231,16 @@ static int __nf_conncount_add(struct net *net, } add_new_node: -if (WARN_ON_ONCE (list->count >INT_MAX )) -return -EOVERFLOW ; +if (WARN_ON_ONCE (list->count >INT_MAX )) { + err = -EOVERFLOW ; + goto out_put; + } conn =kmem_cache_alloc (conncount_conn_cachep,GFP_ATOMIC ); -if (conn ==NULL ) -return -ENOMEM ; +if (conn ==NULL ) { + err = -ENOMEM ; + goto out_put; + } conn->tuple = tuple; conn->zone = *zone;
@@ -249,7 +253,7 @@ static int __nf_conncount_add(struct net *net, out_put:if (refcounted)nf_ct_put (ct); -return 0 ; +return err; } int nf_conncount_add_skb(struct net *net,
@@ -446,11 +450,10 @@ insert_tree(struct net *net,rb_link_node_rcu (&rbconn->node, parent, rbnode);rb_insert_color (&rbconn->node, root); - -if (refcounted) -nf_ct_put (ct); } out_unlock: +if (refcounted) +nf_ct_put (ct);spin_unlock_bh (&nf_conncount_locks[hash]);return count; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 256/634 ipvs: fix ipv4 null-ptr-deref in route error path
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Slavin Liu <[email protected]>
[ Upstream commit ad891bb3d079a46a821bf2b8867854645191bab0 ]
The IPv4 code path in __ip_vs_get_out_rt() calls dst_link_failure() without ensuring skb->dev is set, leading to a NULL pointer dereference in fib_compute_spec_dst() when ipv4_link_failure() attempts to send ICMP destination unreachable messages.
The issue emerged after commit ed0de45a1008 ("ipv4: recompile ip options in ipv4_link_failure") started calling __ip_options_compile() from ipv4_link_failure(). This code path eventually calls fib_compute_spec_dst() which dereferences skb->dev. An attempt was made to fix the NULL skb->dev dereference in commit 0113d9c9d1cc ("ipv4: fix null-deref in ipv4_link_failure"), but it only addressed the immediate dev_net(skb->dev) dereference by using a fallback device. The fix was incomplete because fib_compute_spec_dst() later in the call chain still accesses skb->dev directly, which remains NULL when IPVS calls dst_link_failure().
The crash occurs when:
1. IPVS processes a packet in NAT mode with a misconfigured destination
2. Route lookup fails in __ip_vs_get_out_rt() before establishing a route
3. The error path calls dst_link_failure(skb) with skb->dev == NULL
4. ipv4_link_failure() → ipv4_send_dest_unreach() → __ip_options_compile() → fib_compute_spec_dst()
5. fib_compute_spec_dst() dereferences NULL skb->dev
Apply the same fix used for IPv6 in commit 326bf17ea5d4 ("ipvs: fix ipv6 route unreach panic"): set skb->dev from skb_dst(skb)->dev before calling dst_link_failure().
KASAN: null-ptr-deref in range [0x0000000000000328-0x000000000000032f] CPU: 1 PID: 12732 Comm: syz.1.3469 Not tainted 6.6.114 #2 RIP: 0010:__in_dev_get_rcu include/linux/inetdevice.h:233 RIP: 0010:fib_compute_spec_dst+0x17a/0x9f0 net/ipv4/fib_frontend.c:285 Call Trace: <TASK> spec_dst_fill net/ipv4/ip_options.c:232 spec_dst_fill net/ipv4/ip_options.c:229 __ip_options_compile+0x13a1/0x17d0 net/ipv4/ip_options.c:330 ipv4_send_dest_unreach net/ipv4/route.c:1252 ipv4_link_failure+0x702/0xb80 net/ipv4/route.c:1265 dst_link_failure include/net/dst.h:437 __ip_vs_get_out_rt+0x15fd/0x19e0 net/netfilter/ipvs/ip_vs_xmit.c:412 ip_vs_nat_xmit+0x1d8/0xc80 net/netfilter/ipvs/ip_vs_xmit.c:764
--- net/netfilter/ipvs/ip_vs_xmit.c | 3 +++ 1 file changed, 3 insertions(+)
net/netfilter/ipvs/ip_vs_xmit.c +3 -0
@@ -409,6 +409,9 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,return -1 ; err_unreach: +if (!skb->dev) + skb->dev =skb_dst (skb)->dev; +dst_link_failure (skb);return -1 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 257/634 caif: fix integer underflow in cffrml_receive()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junrui Luo <[email protected]>
[ Upstream commit 8a11ff0948b5ad09b71896b7ccc850625f9878d1 ]
The cffrml_receive() function extracts a length field from the packet header and, when FCS is disabled, subtracts 2 from this length without validating that len >= 2.
If an attacker sends a malicious packet with a length field of 0 or 1 to an interface with FCS disabled, the subtraction causes an integer underflow.
This can lead to memory exhaustion and kernel instability, potential information disclosure if padding contains uninitialized kernel memory.
Fix this by validating that len >= 2 before performing the subtraction.
--- net/caif/cffrml.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
net/caif/cffrml.c +8 -1
@@ -92,8 +92,15 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt) len =le16_to_cpu (tmp);/* Subtract for FCS on length if FCS is not used. */ -if (!this->dofcs) +if (!this->dofcs) { +if (len <2 ) { + ++cffrml_rcv_error; +pr_err ("Invalid frame length (%d)\n" , len); +cfpkt_destroy (pkt); +return -EPROTO ; + } len -=2 ; + }if (cfpkt_setlen (pkt, len) <0 ) { ++cffrml_rcv_error;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 258/634 net/sched: ets: Remove drr class from the active list if it changes to strict
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Nogueira <[email protected]>
[ Upstream commit b1e125ae425aba9b45252e933ca8df52a843ec70 ]
Whenever a user issues an ets qdisc change command, transforming a drr class into a strict one, the ets code isn't checking whether that class was in the active list and removing it. This means that, if a user changes a strict class (which was in the active list) back to a drr one, that class will be added twice to the active list [1].
Doing so with the following commands:
tc qdisc add dev lo root handle 1: ets bands 2 strict 1 tc qdisc add dev lo parent 1:2 handle 20: \
tbf rate 8bit burst 100b latency 1s
tc filter add dev lo parent 1: basic classid 1:2 ping -c1 -W0.01 -s 56 127.0.0.1
tc qdisc change dev lo root handle 1: ets bands 2 strict 2 tc qdisc change dev lo root handle 1: ets bands 2 strict 1 ping -c1 -W0.01 -s 56 127.0.0.1
Will trigger the following splat with list debug turned on:
[ 59.279014][ T365] ------------[ cut here ]------------ [ 59.279452][ T365] list_add double add: new=ffff88801d60e350, prev=ffff88801d60e350, next=ffff88801d60e2c0. [ 59.280153][ T365] WARNING: CPU: 3 PID: 365 at lib/list_debug.c:35 __list_add_valid_or_report+0x17f/0x220 [ 59.280860][ T365] Modules linked in: [ 59.281165][ T365] CPU: 3 UID: 0 PID: 365 Comm: tc Not tainted 6.18.0-rc7-00105-g7e9f13163c13-dirty #239 PREEMPT(voluntary) [ 59.281977][ T365] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 [ 59.282391][ T365] RIP: 0010:__list_add_valid_or_report+0x17f/0x220 [ 59.282842][ T365] Code: 89 c6 e8 d4 b7 0d ff 90 0f 0b 90 90 31 c0 e9 31 ff ff ff 90 48 c7 c7 e0 a0 22 9f 48 89 f2 48 89 c1 4c 89 c6 e8 b2 b7 0d ff 90 <0f> 0b 90 90 31 c0 e9 0f ff ff ff 48 89 f7 48 89 44 24 10 4c 89 44 ... [ 59.288812][ T365] Call Trace: [ 59.289056][ T365] <TASK> [ 59.289224][ T365] ? srso_alias_return_thunk+0x5/0xfbef5 [ 59.289546][ T365] ets_qdisc_change+0xd2b/0x1e80 [ 59.289891][ T365] ? __lock_acquire+0x7e7/0x1be0 [ 59.290223][ T365] ? __pfx_ets_qdisc_change+0x10/0x10 [ 59.290546][ T365] ? srso_alias_return_thunk+0x5/0xfbef5 [ 59.290898][ T365] ? __mutex_trylock_common+0xda/0x240 [ 59.291228][ T365] ? __pfx___mutex_trylock_common+0x10/0x10 [ 59.291655][ T365] ? srso_alias_return_thunk+0x5/0xfbef5 [ 59.291993][ T365] ? srso_alias_return_thunk+0x5/0xfbef5 [ 59.292313][ T365] ? trace_contention_end+0xc8/0x110 [ 59.292656][ T365] ? srso_alias_return_thunk+0x5/0xfbef5 [ 59.293022][ T365] ? srso_alias_return_thunk+0x5/0xfbef5 [ 59.293351][ T365] tc_modify_qdisc+0x63a/0x1cf0
Fix this by always checking and removing an ets class from the active list when changing it to strict.
--- net/sched/sch_ets.c | 4 ++++ 1 file changed, 4 insertions(+)
net/sched/sch_ets.c +4 -0
@@ -664,6 +664,10 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt, q->classes[i].deficit = quanta[i]; } } +for (i = q->nstrict; i < nstrict; i++) { +if (cl_is_active (&q->classes[i])) +list_del_init (&q->classes[i].alist); + }WRITE_ONCE (q->nstrict, nstrict);memcpy (q->prio2band, priomap,sizeof (priomap));
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 259/634 nfc: pn533: Fix error code in pn533_acr122_poweron_rdr()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 885bebac9909994050bbbeed0829c727e42bd1b7 ]
Set the error code if "transferred != sizeof(cmd)" instead of returning success.
--- drivers/nfc/pn533/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/nfc/pn533/usb.c +1 -1
@@ -407,7 +407,7 @@ static int pn533_acr122_poweron_rdr(struct pn533_usb_phy *phy)if (rc || (transferred !=sizeof (cmd))) {nfc_err (&phy->udev->dev,"Reader power on cmd error %d\n" , rc); -return rc; +return rc ?: -EINVAL ; } rc =usb_submit_urb (phy->in_urb,GFP_KERNEL );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 260/634 net/ethtool/ioctl: remove if n_stats checks from ethtool_get_phy_stats
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniil Tatianin <[email protected]>
[ Upstream commit fd4778581d61d8848b532f8cdc9b325138748437 ]
Now that we always early return if we don't have any stats we can remove these checks as they're no longer necessary.
Stable-dep-of: 7b07be1ff1cb ("ethtool: Avoid overflowing userspace buffer on stats query")
--- net/ethtool/ioctl.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-)
net/ethtool/ioctl.c +10 -14
@@ -2106,28 +2106,24 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr) stats.n_stats = n_stats; -if (n_stats) { - data =vzalloc (array_size (n_stats,sizeof (u64))); -if (!data) -return -ENOMEM ; + data =vzalloc (array_size (n_stats,sizeof (u64))); +if (!data) +return -ENOMEM ; -if (phydev && !ops->get_ethtool_phy_stats && - phy_ops && phy_ops->get_stats) { - ret = phy_ops->get_stats (phydev, &stats, data); -if (ret <0 ) - goto out; - }else { - ops->get_ethtool_phy_stats (dev, &stats, data); - } +if (phydev && !ops->get_ethtool_phy_stats && + phy_ops && phy_ops->get_stats) { + ret = phy_ops->get_stats (phydev, &stats, data); +if (ret <0 ) + goto out; }else { - data =NULL ; + ops->get_ethtool_phy_stats (dev, &stats, data); } ret = -EFAULT ;if (copy_to_user (useraddr, &stats,sizeof (stats))) goto out; useraddr +=sizeof (stats); -if (n_stats &©_to_user (useraddr, data,array_size (n_stats,sizeof (u64)))) +if (copy_to_user (useraddr, data,array_size (n_stats,sizeof (u64)))) goto out; ret =0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 261/634 net/ethtool/ioctl: split ethtool_get_phy_stats into multiple helpers
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniil Tatianin <[email protected]>
[ Upstream commit 201ed315f9676809cd5b20a39206e964106d4f27 ]
So that it's easier to follow and make sense of the branching and various conditions.
Stats retrieval has been split into two separate functions ethtool_get_phy_stats_phydev & ethtool_get_phy_stats_ethtool. The former attempts to retrieve the stats using phydev & phy_ops, while the latter uses ethtool_ops.
Actual n_stats validation & array allocation has been moved into a new ethtool_vzalloc_stats_array helper.
This also fixes a potential NULL dereference of ops->get_ethtool_phy_stats where it was getting called in an else branch unconditionally without making sure it was actually present.
Found by Linux Verification Center (linuxtesting.org) with the SVACE static analysis tool.
Stable-dep-of: 7b07be1ff1cb ("ethtool: Avoid overflowing userspace buffer on stats query")
--- net/ethtool/ioctl.c | 102 ++++++++++++++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 33 deletions(-)
net/ethtool/ioctl.c +69 -33
@@ -2077,23 +2077,8 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)return ret; } -static int ethtool_get_phy_stats (struct net_device *dev,void __user *useraddr) +static int ethtool_vzalloc_stats_array (int n_stats,u64 **data) { -const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops; -const struct ethtool_ops *ops = dev->ethtool_ops; -struct phy_device *phydev = dev->phydev; -struct ethtool_stats stats; -u64 *data; -int ret, n_stats; - -if (!phydev && (!ops->get_ethtool_phy_stats || !ops->get_sset_count)) -return -EOPNOTSUPP ; - -if (phydev && !ops->get_ethtool_phy_stats && - phy_ops && phy_ops->get_sset_count) - n_stats = phy_ops->get_sset_count (phydev); -else - n_stats = ops->get_sset_count (dev,ETH_SS_PHY_STATS );if (n_stats <0 )return n_stats;if (n_stats >S32_MAX /sizeof (u64))
@@ -2101,31 +2086,82 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)if (WARN_ON_ONCE (!n_stats))return -EOPNOTSUPP ; + *data =vzalloc (array_size (n_stats,sizeof (u64))); +if (!*data) +return -ENOMEM ; + +return 0 ; +} + +static int ethtool_get_phy_stats_phydev (struct phy_device *phydev, +struct ethtool_stats *stats, +u64 **data) + { +const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops; +int n_stats, ret; + +if (!phy_ops || !phy_ops->get_sset_count || !phy_ops->get_stats) +return -EOPNOTSUPP ; + + n_stats = phy_ops->get_sset_count (phydev); + + ret =ethtool_vzalloc_stats_array (n_stats, data); +if (ret) +return ret; + + stats->n_stats = n_stats; +return phy_ops->get_stats (phydev, stats, *data); +} + +static int ethtool_get_phy_stats_ethtool (struct net_device *dev, +struct ethtool_stats *stats, +u64 **data) +{ +const struct ethtool_ops *ops = dev->ethtool_ops; +int n_stats, ret; + +if (!ops || !ops->get_sset_count || ops->get_ethtool_phy_stats) +return -EOPNOTSUPP ; + + n_stats = ops->get_sset_count (dev,ETH_SS_PHY_STATS ); + + ret =ethtool_vzalloc_stats_array (n_stats, data); +if (ret) +return ret; + + stats->n_stats = n_stats; + ops->get_ethtool_phy_stats (dev, stats, *data); + +return 0 ; +} + +static int ethtool_get_phy_stats (struct net_device *dev,void __user *useraddr) +{ +struct phy_device *phydev = dev->phydev; +struct ethtool_stats stats; +u64 *data =NULL ; +int ret = -EOPNOTSUPP ; +if (copy_from_user (&stats, useraddr,sizeof (stats)))return -EFAULT ; - stats.n_stats = n_stats; +if (phydev) + ret =ethtool_get_phy_stats_phydev (phydev, &stats, &data); - data =vzalloc (array_size (n_stats,sizeof (u64))); -if (!data) -return -ENOMEM ; +if (ret == -EOPNOTSUPP ) + ret =ethtool_get_phy_stats_ethtool (dev, &stats, &data); -if (phydev && !ops->get_ethtool_phy_stats && - phy_ops && phy_ops->get_stats) { - ret = phy_ops->get_stats (phydev, &stats, data); -if (ret <0 ) - goto out; - }else { - ops->get_ethtool_phy_stats (dev, &stats, data); - } +if (ret) + goto out; - ret = -EFAULT ; -if (copy_to_user (useraddr, &stats,sizeof (stats))) +if (copy_to_user (useraddr, &stats,sizeof (stats))) { + ret = -EFAULT ; goto out; + } + useraddr +=sizeof (stats); -if (copy_to_user (useraddr, data,array_size (n_stats,sizeof (u64)))) - goto out; - ret =0 ; +if (copy_to_user (useraddr, data,array_size (stats.n_stats,sizeof (u64)))) + ret = -EFAULT ; out:vfree (data);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 262/634 ethtool: Avoid overflowing userspace buffer on stats query
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gal Pressman <[email protected]>
[ Upstream commit 7b07be1ff1cb6c49869910518650e8d0abc7d25f ]
The ethtool -S command operates across three ioctl calls:ETHTOOL_GSSET_INFO for the size, ETHTOOL_GSTRINGS for the names, and ETHTOOL_GSTATS for the values.
If the number of stats changes between these calls (e.g., due to device reconfiguration), userspace's buffer allocation will be incorrect, potentially leading to buffer overflow.
Drivers are generally expected to maintain stable stat counts, but some drivers (e.g., mlx5, bnx2x, bna, ksz884x) use dynamic counters, making this scenario possible.
Some drivers try to handle this internally:
- bnad_get_ethtool_stats() returns early in case stats.n_stats is not equal to the driver's stats count.
- micrel/ksz884x also makes sure not to write anything beyond stats.n_stats and overflow the buffer.
However, both use stats.n_stats which is already assigned with the value returned from get_sset_count(), hence won't solve the issue described here.
Change ethtool_get_strings(), ethtool_get_stats(), ethtool_get_phy_stats() to not return anything in case of a mismatch between userspace's size and get_sset_size(), to prevent buffer overflow.
The returned n_stats value will be equal to zero, to reflect that nothing has been returned.
This could result in one of two cases when using upstream ethtool, depending on when the size change is detected:
1. When detected in ethtool_get_strings():
# ethtool -S eth2
no stats available2. When detected in get stats, all stats will be reported as zero.
Both cases are presumably transient, and a subsequent ethtool call should succeed.
Other than the overflow avoidance, these two cases are very evident (no output/cleared stats), which is arguably better than presenting incorrect/shifted stats.
I also considered returning an error instead of a "silent" response, but that seems more destructive towards userspace apps.
Notes:
- This patch does not claim to fix the inherent race, it only makes sure that we do not overflow the userspace buffer, and makes for a more predictable behavior.
- RTNL lock is held during each ioctl, the race window exists between the separate ioctl calls when the lock is released.
- Userspace ethtool always fills stats.n_stats, but it is likely that these stats ioctls are implemented in other userspace applications which might not fill it. The added code checks that it's not zero, to prevent any regressions.
--- net/ethtool/ioctl.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-)
net/ethtool/ioctl.c +24 -6
@@ -1938,7 +1938,10 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)return -ENOMEM ;WARN_ON_ONCE (!ret); - gstrings.len = ret; +if (gstrings.len && gstrings.len != ret) + gstrings.len =0 ; +else + gstrings.len = ret;if (gstrings.len) { data =vzalloc (array_size (gstrings.len,ETH_GSTRING_LEN ));
@@ -2053,10 +2056,13 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)if (copy_from_user (&stats, useraddr,sizeof (stats)))return -EFAULT ; - stats.n_stats = n_stats; +if (stats.n_stats && stats.n_stats != n_stats) + stats.n_stats =0 ; +else + stats.n_stats = n_stats; -if (n_stats) { - data =vzalloc (array_size (n_stats,sizeof (u64))); +if (stats.n_stats) { + data =vzalloc (array_size (stats.n_stats,sizeof (u64)));if (!data)return -ENOMEM ; ops->get_ethtool_stats (dev, &stats, data);
@@ -2068,7 +2074,9 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)if (copy_to_user (useraddr, &stats,sizeof (stats))) goto out; useraddr +=sizeof (stats); -if (n_stats &©_to_user (useraddr, data,array_size (n_stats,sizeof (u64)))) +if (stats.n_stats && +copy_to_user (useraddr, data, +array_size (stats.n_stats,sizeof (u64)))) goto out; ret =0 ;
@@ -2104,6 +2112,10 @@ static int ethtool_get_phy_stats_phydev(struct phy_device *phydev,return -EOPNOTSUPP ; n_stats = phy_ops->get_sset_count (phydev); +if (stats->n_stats && stats->n_stats != n_stats) { + stats->n_stats =0 ; +return 0 ; + } ret =ethtool_vzalloc_stats_array (n_stats, data);if (ret)
@@ -2124,6 +2136,10 @@ static int ethtool_get_phy_stats_ethtool(struct net_device *dev,return -EOPNOTSUPP ; n_stats = ops->get_sset_count (dev,ETH_SS_PHY_STATS ); +if (stats->n_stats && stats->n_stats != n_stats) { + stats->n_stats =0 ; +return 0 ; + } ret =ethtool_vzalloc_stats_array (n_stats, data);if (ret)
@@ -2160,7 +2176,9 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr) } useraddr +=sizeof (stats); -if (copy_to_user (useraddr, data,array_size (stats.n_stats,sizeof (u64)))) +if (stats.n_stats && +copy_to_user (useraddr, data, +array_size (stats.n_stats,sizeof (u64)))) ret = -EFAULT ; out:
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 263/634 net/mlx5: fw reset, clear reset requested on drain_fw_reset
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Moshe Shemesh <[email protected]>
[ Upstream commit 89a898d63f6f588acf5c104c65c94a38b68c69a6 ]
drain_fw_reset() waits for ongoing firmware reset events and blocks new event handling, but does not clear the reset requested flag, and may keep sync reset polling.
To fix it, call mlx5_sync_reset_clear_reset_requested() to clear the flag, stop sync reset polling, and resume health polling, ensuring health issues are still detected after the firmware reset drain.
--- drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c +2 -1
@@ -534,7 +534,8 @@ void mlx5_drain_fw_reset(struct mlx5_core_dev *dev)cancel_work_sync (&fw_reset->reset_reload_work);cancel_work_sync (&fw_reset->reset_now_work);cancel_work_sync (&fw_reset->reset_abort_work); -cancel_delayed_work (&fw_reset->reset_timeout_work); +if (test_bit (MLX5_FW_RESET_FLAGS_RESET_REQUESTED , &fw_reset->reset_flags)) +mlx5_sync_reset_clear_reset_requested (dev, true); }int mlx5_fw_reset_init (struct mlx5_core_dev *dev)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 264/634 net/mlx5: Create a new profile for SFs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Parav Pandit <[email protected]>
[ Upstream commit 9df839a711aee437390b16ee39cf0b5c1620be6a ]
Create a new profile for SFs in order to disable the command cache. Each function command cache consumes ~500KB of memory, when using a large number of SFs this savings is notable on memory constarined systems.
Use a new profile to provide for future differences between SFs and PFs.
The mr_cache not used for non-PF functions, so it is excluded from the new profile.
Stable-dep-of: 5846a365fc64 ("net/mlx5: Drain firmware reset in shutdown callback")
--- drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 6 +++--- drivers/net/ethernet/mellanox/mlx5/core/main.c | 9 +++++++++ drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h | 1 + drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c | 2 +- include/linux/mlx5/driver.h | 1 + 5 files changed, 15 insertions(+), 4 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/cmd.c +3 -3
@@ -1833,7 +1833,7 @@ static struct mlx5_cmd_msg *alloc_msg(struct mlx5_core_dev *dev, int in_size,if (in_size <=16 ) goto cache_miss; -for (i =0 ; i <MLX5_NUM_COMMAND_CACHES ; i++) { +for (i =0 ; i < dev->profile.num_cmd_caches; i++) { ch = &cmd->cache[i];if (in_size > ch->max_inbox_size)continue ;
@@ -2129,7 +2129,7 @@ static void destroy_msg_cache(struct mlx5_core_dev *dev)struct mlx5_cmd_msg *n;int i; -for (i =0 ; i <MLX5_NUM_COMMAND_CACHES ; i++) { +for (i =0 ; i < dev->profile.num_cmd_caches; i++) { ch = &dev->cmd.cache[i];list_for_each_entry_safe (msg, n, &ch->head, list) {list_del (&msg->list);
@@ -2159,7 +2159,7 @@ static void create_msg_cache(struct mlx5_core_dev *dev)int k;/* Initialize and fill the caches with initial entries */ -for (k =0 ; k <MLX5_NUM_COMMAND_CACHES ; k++) { +for (k =0 ; k < dev->profile.num_cmd_caches; k++) { ch = &cmd->cache[k];spin_lock_init (&ch->lock);INIT_LIST_HEAD (&ch->head);
drivers/net/ethernet/mellanox/mlx5/core/main.c +9 -0
@@ -103,15 +103,19 @@ enum {static struct mlx5_profile profile[] = { [0 ] = { .mask =0 , + .num_cmd_caches =MLX5_NUM_COMMAND_CACHES , }, [1 ] = { .mask =MLX5_PROF_MASK_QP_SIZE , .log_max_qp =12 , + .num_cmd_caches =MLX5_NUM_COMMAND_CACHES , + }, [2 ] = { .mask =MLX5_PROF_MASK_QP_SIZE |MLX5_PROF_MASK_MR_CACHE , .log_max_qp =LOG_MAX_SUPPORTED_QPS , + .num_cmd_caches =MLX5_NUM_COMMAND_CACHES , .mr_cache[0 ] = { .size =500 , .limit =250
@@ -177,6 +181,11 @@ static struct mlx5_profile profile[] = { .limit = 4 }, }, + [3] = { + .mask = MLX5_PROF_MASK_QP_SIZE, + .log_max_qp = LOG_MAX_SUPPORTED_QPS, + .num_cmd_caches = 0, + }, }; static int wait_fw_init(struct mlx5_core_dev *dev, u32 max_wait_mili,
drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h +1 -0
@@ -142,6 +142,7 @@ enum mlx5_semaphore_space_address { };#define MLX5_DEFAULT_PROF 2 +#define MLX5_SF_PROF 3 static inline int mlx5_flexible_inlen(struct mlx5_core_dev *dev, size_t fixed, size_t item_size, size_t num_items,
drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c +1 -1
@@ -28,7 +28,7 @@ static int mlx5_sf_dev_probe(struct auxiliary_device *adev, const struct auxilia mdev->priv.adev_idx = adev->id; sf_dev->mdev = mdev; - err =mlx5_mdev_init (mdev,MLX5_DEFAULT_PROF ); + err =mlx5_mdev_init (mdev,MLX5_SF_PROF );if (err) {mlx5_core_warn (mdev,"mlx5_mdev_init on err=%d\n" , err); goto mdev_err;
include/linux/mlx5/driver.h +1 -0
@@ -755,6 +755,7 @@ enum {struct mlx5_profile {u64 mask;u8 log_max_qp; +u8 num_cmd_caches;struct {int size;int limit;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 265/634 net/mlx5: Drain firmware reset in shutdown callback
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Moshe Shemesh <[email protected]>
[ Upstream commit 5846a365fc6476b02d6766963cf0985520f0385f ]
Invoke drain_fw_reset() in the shutdown callback to ensure all firmware reset handling is completed before shutdown proceeds.
--- drivers/net/ethernet/mellanox/mlx5/core/main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/mellanox/mlx5/core/main.c +1 -0
@@ -1999,6 +1999,7 @@ static void shutdown(struct pci_dev *pdev)mlx5_core_info (dev,"Shutdown was called\n" );set_bit (MLX5_BREAK_FW_WAIT , &dev->intf_state); +mlx5_drain_fw_reset (dev);mlx5_drain_health_wq (dev); err =mlx5_try_fast_unload (dev);if (err)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 266/634 net/mlx5: fw_tracer, Add support for unrecognized string
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shay Drory <[email protected]>
[ Upstream commit f7133135235dbd11e7cb5fe62fe5d05ce5e82eeb ]
In case FW is publishing a string which isn't found in the driver's string DBs, keep the string as raw data.
Stable-dep-of: b35966042d20 ("net/mlx5: fw_tracer, Validate format string parameters")
--- .../mellanox/mlx5/core/diag/fw_tracer.c | 25 +++++++++++++++++-- .../mellanox/mlx5/core/diag/fw_tracer.h | 1 + 2 files changed, 24 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c +23 -2
@@ -460,6 +460,7 @@ static void poll_trace(struct mlx5_fw_tracer *tracer, tracer_event->event_id =MLX5_GET (tracer_event, trace, event_id); tracer_event->lost_event =MLX5_GET (tracer_event, trace, lost); + tracer_event->out = trace;switch (tracer_event->event_id) {case TRACER_EVENT_TYPE_TIMESTAMP :
@@ -582,6 +583,26 @@ void mlx5_tracer_print_trace(struct tracer_string_format *str_frmt,mlx5_tracer_clean_message (str_frmt); } +static int mlx5_tracer_handle_raw_string (struct mlx5_fw_tracer *tracer, +struct tracer_event *tracer_event) +{ +struct tracer_string_format *cur_string; + + cur_string =mlx5_tracer_message_insert (tracer, tracer_event); +if (!cur_string) +return -1 ; + + cur_string->event_id = tracer_event->event_id; + cur_string->timestamp = tracer_event->string_event.timestamp; + cur_string->lost = tracer_event->lost_event; + cur_string->string ="0x%08x%08x" ; + cur_string->num_of_params =2 ; + cur_string->params[0 ] =upper_32_bits (*tracer_event->out); + cur_string->params[1 ] =lower_32_bits (*tracer_event->out); +list_add_tail (&cur_string->list, &tracer->ready_strings_list); +return 0 ; +} +static int mlx5_tracer_handle_string_trace (struct mlx5_fw_tracer *tracer,struct tracer_event *tracer_event) {
@@ -590,7 +611,7 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,if (tracer_event->string_event.tdsn ==0 ) { cur_string =mlx5_tracer_get_string (tracer, tracer_event);if (!cur_string) -return -1 ; +return mlx5_tracer_handle_raw_string (tracer, tracer_event); cur_string->num_of_params =mlx5_tracer_get_num_of_params (cur_string->string); cur_string->last_param_num =0 ;
@@ -605,7 +626,7 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,if (!cur_string) {pr_debug ("%s Got string event for unknown string tmsn: %d\n" , __func__, tracer_event->string_event.tmsn); -return -1 ; +return mlx5_tracer_handle_raw_string (tracer, tracer_event); } cur_string->last_param_num +=1 ;if (cur_string->last_param_num >TRACER_MAX_PARAMS ) {
drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h +1 -0
@@ -158,6 +158,7 @@ struct tracer_event {struct tracer_string_event string_event;struct tracer_timestamp_event timestamp_event; }; +u64 *out; };struct mlx5_ifc_tracer_event_bits {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 267/634 net/mlx5: fw_tracer, Validate format string parameters
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shay Drory <[email protected]>
[ Upstream commit b35966042d20b14e2d83330049f77deec5229749 ]
Add validation for format string parameters in the firmware tracer to prevent potential security vulnerabilities and crashes from malformed format strings received from firmware.
The firmware tracer receives format strings from the device firmware and uses them to format trace messages. Without proper validation, bad firmware could provide format strings with invalid format specifiers (e.g., %s, %p, %n) that could lead to crashes, or other undefined behavior.
Add mlx5_tracer_validate_params() to validate that all format specifiers in trace strings are limited to safe integer/hex formats (%x, %d, %i, %u, %llx, %lx, etc.). Reject strings containing other format types that could be used to access arbitrary memory or cause crashes. Invalid format strings are added to the trace output for visibility with "BAD_FORMAT: " prefix.
--- .../mellanox/mlx5/core/diag/fw_tracer.c | 83 ++++++++++++++++--- .../mellanox/mlx5/core/diag/fw_tracer.h | 1 + 2 files changed, 74 insertions(+), 10 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c +73 -10
@@ -33,6 +33,7 @@#include "lib/eq.h" #include "fw_tracer.h" #include "fw_tracer_tracepoint.h" +#include <linux/ctype.h> static int mlx5_query_mtrc_caps (struct mlx5_fw_tracer *tracer) {
@@ -354,6 +355,43 @@ static const char *VAL_PARM = "%llx";static const char *REPLACE_64_VAL_PARM ="%x%x" ;static const char *PARAM_CHAR ="%" ; +static bool mlx5_is_valid_spec (const char *str) +{ +/* Parse format specifiers to find the actual type. +* Structure: %[flags][width][.precision][length]type +* Skip flags, width, precision & length. +*/ +while (isdigit (*str) || *str =='#' || *str =='.' || *str =='l' ) + str++; + +/* Check if it's a valid integer/hex specifier: +* Valid formats: %x, %d, %i, %u, etc. +*/ +if (*str !='x' && *str !='X' && *str !='d' && *str !='i' && + *str !='u' && *str !='c' ) +return false; + +return true; +} + +static bool mlx5_tracer_validate_params (const char *str) +{ +const char *substr = str; + +if (!str) +return false; + + substr =strstr (substr,PARAM_CHAR ); +while (substr) { +if (!mlx5_is_valid_spec (substr +1 )) +return false; + + substr =strstr (substr +1 ,PARAM_CHAR ); + } + +return true; +} +static int mlx5_tracer_message_hash (u32 message_id) {return jhash_1word (message_id,0 ) & (MESSAGE_HASH_SIZE -1 );
@@ -413,6 +451,10 @@ static int mlx5_tracer_get_num_of_params(char *str)char *substr, *pstr = str;int num_of_params =0 ; +/* Validate that all parameters are valid before processing */ +if (!mlx5_tracer_validate_params (str)) +return -EINVAL ; +/* replace %llx with %x%x */ substr =strstr (pstr,VAL_PARM );while (substr) {
@@ -564,14 +606,17 @@ void mlx5_tracer_print_trace(struct tracer_string_format *str_frmt, {char tmp[512 ]; -snprintf (tmp,sizeof (tmp), str_frmt->string, - str_frmt->params[0 ], - str_frmt->params[1 ], - str_frmt->params[2 ], - str_frmt->params[3 ], - str_frmt->params[4 ], - str_frmt->params[5 ], - str_frmt->params[6 ]); +if (str_frmt->invalid_string) +snprintf (tmp,sizeof (tmp),"BAD_FORMAT: %s" , str_frmt->string); +else +snprintf (tmp,sizeof (tmp), str_frmt->string, + str_frmt->params[0 ], + str_frmt->params[1 ], + str_frmt->params[2 ], + str_frmt->params[3 ], + str_frmt->params[4 ], + str_frmt->params[5 ], + str_frmt->params[6 ]);trace_mlx5_fw (dev->tracer, trace_timestamp, str_frmt->lost, str_frmt->event_id, tmp);
@@ -603,6 +648,13 @@ static int mlx5_tracer_handle_raw_string(struct mlx5_fw_tracer *tracer,return 0 ; } +static void mlx5_tracer_handle_bad_format_string (struct mlx5_fw_tracer *tracer, +struct tracer_string_format *cur_string) +{ + cur_string->invalid_string = true; +list_add_tail (&cur_string->list, &tracer->ready_strings_list); +} +static int mlx5_tracer_handle_string_trace (struct mlx5_fw_tracer *tracer,struct tracer_event *tracer_event) {
@@ -613,12 +665,18 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,if (!cur_string)return mlx5_tracer_handle_raw_string (tracer, tracer_event); - cur_string->num_of_params =mlx5_tracer_get_num_of_params (cur_string->string); - cur_string->last_param_num =0 ; cur_string->event_id = tracer_event->event_id; cur_string->tmsn = tracer_event->string_event.tmsn; cur_string->timestamp = tracer_event->string_event.timestamp; cur_string->lost = tracer_event->lost_event; + cur_string->last_param_num =0 ; + cur_string->num_of_params =mlx5_tracer_get_num_of_params (cur_string->string); +if (cur_string->num_of_params <0 ) { +pr_debug ("%s Invalid format string parameters\n" , + __func__); +mlx5_tracer_handle_bad_format_string (tracer, cur_string); +return 0 ; + }if (cur_string->num_of_params ==0 )/* trace with no params */ list_add_tail (&cur_string->list, &tracer->ready_strings_list); }else {
@@ -628,6 +686,11 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer, __func__, tracer_event->string_event.tmsn);return mlx5_tracer_handle_raw_string (tracer, tracer_event); } +if (cur_string->num_of_params <0 ) { +pr_debug ("%s string parameter of invalid string, dumping\n" , + __func__); +return 0 ; + } cur_string->last_param_num +=1 ;if (cur_string->last_param_num >TRACER_MAX_PARAMS ) { pr_debug("%s Number of params exceeds the max (%d)\n",
drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h +1 -0
@@ -117,6 +117,7 @@ struct tracer_string_format {struct list_head list;u32 timestamp;bool lost; +bool invalid_string; };enum mlx5_fw_tracer_ownership_state {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 268/634 net/mlx5: fw_tracer, Handle escaped percent properly
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shay Drory <[email protected]>
[ Upstream commit c0289f67f7d6a0dfba0e92cfe661a5c70c8c6e92 ]
The firmware tracer's format string validation and parameter counting did not properly handle escaped percent signs (%%). This caused fw_tracer to count more parameters when trace format strings contained literal percent characters.
To fix it, allow %% to pass string validation and skip %% sequences when counting parameters since they represent literal percent signs rather than format specifiers.
--- .../mellanox/mlx5/core/diag/fw_tracer.c | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c +14 -6
@@ -364,11 +364,11 @@ static bool mlx5_is_valid_spec(const char *str)while (isdigit (*str) || *str =='#' || *str =='.' || *str =='l' ) str++; -/* Check if it's a valid integer/hex specifier: +/* Check if it's a valid integer/hex specifier or %%: * Valid formats: %x, %d, %i, %u, etc. */ if (*str !='x' && *str !='X' && *str !='d' && *str !='i' && - *str !='u' && *str !='c' ) + *str !='u' && *str !='c' && *str !='%' )return false;return true;
@@ -386,7 +386,11 @@ static bool mlx5_tracer_validate_params(const char *str)if (!mlx5_is_valid_spec (substr +1 ))return false; - substr =strstr (substr +1 ,PARAM_CHAR ); +if (*(substr +1 ) =='%' ) + substr =strstr (substr +2 ,PARAM_CHAR ); +else + substr =strstr (substr +1 ,PARAM_CHAR ); + }return true;
@@ -463,11 +467,15 @@ static int mlx5_tracer_get_num_of_params(char *str) substr =strstr (pstr,VAL_PARM ); } -/* count all the % characters */ +/* count all the % characters, but skip %% (escaped percent) */ substr =strstr (str,PARAM_CHAR );while (substr) { - num_of_params +=1 ; - str = substr +1 ; +if (*(substr +1 ) !='%' ) { + num_of_params +=1 ; + str = substr +1 ; + }else { + str = substr +2 ; + } substr =strstr (str,PARAM_CHAR ); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 269/634 net: hns3: using the num_tqps in the vf driver to apply for resources
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jian Shen <[email protected]>
[ Upstream commit c2a16269742e176fccdd0ef9c016a233491a49ad ]
Currently, hdev->htqp is allocated using hdev->num_tqps, and kinfo->tqp is allocated using kinfo->num_tqps. However, kinfo->num_tqps is set to min(new_tqps, hdev->num_tqps); Therefore, kinfo->num_tqps may be smaller than hdev->num_tqps, which causes some hdev->htqp[i] to remain uninitialized in hclgevf_knic_setup().
Thus, this patch allocates hdev->htqp and kinfo->tqp using hdev->num_tqps, ensuring that the lengths of hdev->htqp and kinfo->tqp are consistent and that all elements are properly initialized.
--- drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +2 -2
@@ -385,12 +385,12 @@ static int hclgevf_knic_setup(struct hclgevf_dev *hdev) new_tqps = kinfo->rss_size * num_tc; kinfo->num_tqps =min (new_tqps, hdev->num_tqps); - kinfo->tqp =devm_kcalloc (&hdev->pdev->dev, kinfo->num_tqps, + kinfo->tqp =devm_kcalloc (&hdev->pdev->dev, hdev->num_tqps,sizeof (struct hnae3_queue *),GFP_KERNEL );if (!kinfo->tqp)return -ENOMEM ; -for (i =0 ; i < kinfo->num_tqps; i++) { +for (i =0 ; i < hdev->num_tqps; i++) { hdev->htqp[i].q.handle = &hdev->nic; hdev->htqp[i].q.tqp_index = i; kinfo->tqp[i] = &hdev->htqp[i].q;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 270/634 net: hns3: using the num_tqps to check whether tqp_index is out of range when vf get ring info from mbx
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jian Shen <[email protected]>
[ Upstream commit d180c11aa8a6fa735f9ac2c72c61364a9afc2ba7 ]
Currently, rss_size = num_tqps / tc_num. If tc_num is 1, then num_tqps equals rss_size. However, if the tc_num is greater than 1, then rss_size will be less than num_tqps, causing the tqp_index check for subsequent TCs using rss_size to always fail.
This patch uses the num_tqps to check whether tqp_index is out of range, instead of rss_size.
--- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +2 -2
@@ -193,10 +193,10 @@ static int hclge_get_ring_chain_from_mbx(return -EINVAL ;for (i =0 ; i < ring_num; i++) { -if (req->msg.param[i].tqp_index >= vport->nic.kinfo.rss_size) { +if (req->msg.param[i].tqp_index >= vport->nic.kinfo.num_tqps) {dev_err (&hdev->pdev->dev,"tqp index(%u) is out of range(0-%u)\n" , req->msg.param[i].tqp_index, - vport->nic.kinfo.rss_size -1U ); + vport->nic.kinfo.num_tqps -1U );return -EINVAL ; } }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 271/634 net: hns3: add VLAN id validation before using
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jian Shen <[email protected]>
[ Upstream commit 6ef935e65902bfed53980ad2754b06a284ea8ac1 ]
Currently, the VLAN id may be used without validation when receive a VLAN configuration mailbox from VF. The length of vlan_del_fail_bmap is BITS_TO_LONGS(VLAN_N_VID). It may cause out-of-bounds memory access once the VLAN id is bigger than or equal to VLAN_N_VID.
Therefore, VLAN id needs to be checked to ensure it is within the range of VLAN_N_VID.
--- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +3 -0
@@ -10585,6 +10585,9 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto,bool writen_to_tbl = false;int ret =0 ; +if (vlan_id >=VLAN_N_VID ) +return -EINVAL ; +/* When device is resetting or reset failed, firmware is unable to * handle mailbox. Just record the vlan id, and remove it after * reset finished.
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 272/634 hwmon: (ibmpex) fix use-after-free in high/low store
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junrui Luo <[email protected]>
[ Upstream commit 6946c726c3f4c36f0f049e6f97e88c510b15f65d ]
The ibmpex_high_low_store() function retrieves driver data using dev_get_drvdata() and uses it without validation. This creates a race condition where the sysfs callback can be invoked after the data structure is freed, leading to use-after-free.
Fix by adding a NULL check after dev_get_drvdata(), and reordering operations in the deletion path to prevent TOCTOU.
--- drivers/hwmon/ibmpex.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/hwmon/ibmpex.c +7 -2
@@ -282,6 +282,9 @@ static ssize_t ibmpex_high_low_store(struct device *dev, {struct ibmpex_bmc_data *data =dev_get_drvdata (dev); +if (!data) +return -ENODEV ; +ibmpex_reset_high_low_data (data);return count;
@@ -514,6 +517,9 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) {int i, j; +hwmon_device_unregister (data->hwmon_dev); +dev_set_drvdata (data->bmc_device,NULL ); +device_remove_file (data->bmc_device, &sensor_dev_attr_reset_high_low.dev_attr);device_remove_file (data->bmc_device, &sensor_dev_attr_name.dev_attr);
@@ -527,8 +533,7 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) }list_del (&data->list); -dev_set_drvdata (data->bmc_device,NULL ); -hwmon_device_unregister (data->hwmon_dev); +ipmi_destroy_user (data->user);kfree (data->sensors);kfree (data);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 273/634 hwmon: (tmp401) fix overflow caused by default conversion rate value
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Simakov <[email protected]>
[ Upstream commit 82f2aab35a1ab2e1460de06ef04c726460aed51c ]
The driver computes conversion intervals using the formula:
interval = (1 << (7 - rate)) * 125ms
where 'rate' is the sensor's conversion rate register value. According to the datasheet, the power-on reset value of this register is 0x8, which could be assigned to the register, after handling i2c general call. Using this default value causes a result greater than the bit width of left operand and an undefined behaviour in the calculation above, since shifting by values larger than the bit width is undefined behaviour as per C language standard.
Limit the maximum usable 'rate' value to 7 to prevent undefined behaviour in calculations.
Found by Linux Verification Center (linuxtesting.org) with Svace.
Note (groeck):
This does not matter in practice unless someone overwrites the chip configuration from outside the driver while the driver is loaded. The conversion time register is initialized with a value of 5 (500ms) when the driver is loaded, and the driver never writes a bad value.
--- drivers/hwmon/tmp401.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/tmp401.c +1 -1
@@ -408,7 +408,7 @@ static int tmp401_chip_read(struct device *dev, u32 attr, int channel, long *val ret =regmap_read (data->regmap,TMP401_CONVERSION_RATE , ®val);if (ret <0 )return ret; - *val = (1 << (7 - regval)) *125 ; + *val = (1 << (7 -min (regval,7 ))) *125 ;break ;case hwmon_chip_temp_reset_history: *val =0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 274/634 MIPS: Fix a reference leak bug in ip22_check_gio()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoxiang Li <[email protected]>
[ Upstream commit 680ad315caaa2860df411cb378bf3614d96c7648 ]
If gio_device_register fails, gio_dev_put() is required to drop the gio_dev device reference.
--- arch/mips/sgi-ip22/ip22-gio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/mips/sgi-ip22/ip22-gio.c +2 -1
@@ -373,7 +373,8 @@ static void ip22_check_gio(int slotno, unsigned long addr, int irq) gio_dev->resource.flags =IORESOURCE_MEM ; gio_dev->irq = irq;dev_set_name (&gio_dev->dev,"%d" , slotno); -gio_device_register (gio_dev); +if (gio_device_register (gio_dev)) +gio_dev_put (gio_dev); }else printk (KERN_INFO "GIO: slot %d : Empty\n" , slotno); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 275/634 x86/xen: Move Xen upcall handler
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brian Gerst <[email protected]>
[ Upstream commit 1ab7b5ed44ba9bce581e225f40219b793bc779d6 ]
Move the upcall handler to Xen-specific files.
No functional changes.
Stable-dep-of: e5aff444e3a7 ("x86/xen: Fix sparse warning in enlighten_pv.c")
--- arch/x86/entry/common.c | 72 ------------------------------------- arch/x86/xen/enlighten_pv.c | 69 +++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 72 deletions(-)
arch/x86/entry/common.c +0 -72
@@ -20,11 +20,6 @@#include <linux/syscalls.h> #include <linux/uaccess.h> -#ifdef CONFIG_XEN_PV -#include <xen/xen-ops.h> -#include <xen/events.h> -#endif -#include <asm/apic.h> #include <asm/desc.h> #include <asm/traps.h>
@@ -346,70 +341,3 @@ SYSCALL_DEFINE0(ni_syscall) {return -ENOSYS ; } - -#ifdef CONFIG_XEN_PV -#ifndef CONFIG_PREEMPTION -/* -* Some hypercalls issued by the toolstack can take many 10s of -* seconds. Allow tasks running hypercalls via the privcmd driver to -* be voluntarily preempted even if full kernel preemption is -* disabled. -* -* Such preemptible hypercalls are bracketed by -* xen_preemptible_hcall_begin() and xen_preemptible_hcall_end() -* calls. -*/ -DEFINE_PER_CPU (bool, xen_in_preemptible_hcall); -EXPORT_SYMBOL_GPL (xen_in_preemptible_hcall); - -/* -* In case of scheduling the flag must be cleared and restored after -* returning from schedule as the task might move to a different CPU. -*/ -static __always_inline bool get_and_clear_inhcall(void) -{ -bool inhcall =__this_cpu_read (xen_in_preemptible_hcall); - -__this_cpu_write (xen_in_preemptible_hcall, false); -return inhcall; -} - -static __always_inline void restore_inhcall(bool inhcall) -{ -__this_cpu_write (xen_in_preemptible_hcall, inhcall); -} -#else -static __always_inline bool get_and_clear_inhcall(void) { return false; } -static __always_inline void restore_inhcall(bool inhcall) { } -#endif - -static void __xen_pv_evtchn_do_upcall (struct pt_regs *regs) -{ -struct pt_regs *old_regs =set_irq_regs (regs); - -inc_irq_stat (irq_hv_callback_count); - -xen_evtchn_do_upcall (); - -set_irq_regs (old_regs); -} - -__visible noinstr void xen_pv_evtchn_do_upcall(struct pt_regs *regs) -{ -irqentry_state_t state =irqentry_enter (regs); -bool inhcall; - -instrumentation_begin (); -run_sysvec_on_irqstack_cond (__xen_pv_evtchn_do_upcall, regs); - - inhcall =get_and_clear_inhcall (); -if (inhcall && !WARN_ON_ONCE (state.exit_rcu)) { -irqentry_exit_cond_resched (); -instrumentation_end (); -restore_inhcall (inhcall); - }else { -instrumentation_end (); -irqentry_exit (regs, state); - } -} -#endif /* CONFIG_XEN_PV */
arch/x86/xen/enlighten_pv.c +69 -0
87 lines not on this page · raw message
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 276/634 x86/xen: Fix sparse warning in enlighten_pv.c
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Juergen Gross <[email protected]>
[ Upstream commit e5aff444e3a7bdeef5ea796a2099fc3c60a070fa ]
The sparse tool issues a warning for arch/x76/xen/enlighten_pv.c:
arch/x86/xen/enlighten_pv.c:120:9: sparse: sparse: incorrect type
in initializer (different address spaces)
expected void const [noderef] __percpu *__vpp_verify got bool *
This is due to the percpu variable xen_in_preemptible_hcall being exported via EXPORT_SYMBOL_GPL() instead of EXPORT_PER_CPU_SYMBOL_GPL().
Message-ID: <[email protected]>
--- arch/x86/xen/enlighten_pv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/xen/enlighten_pv.c +1 -1
@@ -109,7 +109,7 @@ static int xen_cpu_dead_pv(unsigned int cpu);* calls. */ DEFINE_PER_CPU (bool, xen_in_preemptible_hcall); -EXPORT_SYMBOL_GPL (xen_in_preemptible_hcall); +EXPORT_PER_CPU_SYMBOL_GPL (xen_in_preemptible_hcall);/* * In case of scheduling the flag must be cleared and restored after
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 277/634 spi: cadence-quadspi: Add support for StarFive JH7110 QSPI
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: William Qiu <[email protected]>
[ Upstream commit 47fef94afeae2a125607b6b45145594713471320 ]
Add QSPI reset operation in device probe and add RISCV support to QUAD SPI Kconfig.
Stable-dep-of: 1889dd208197 ("spi: cadence-quadspi: Fix clock disable on probe failure path")
--- drivers/spi/Kconfig | 2 +- drivers/spi/spi-cadence-quadspi.c | 21 ++++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-)
drivers/spi/Kconfig +1 -1
@@ -230,7 +230,7 @@ config SPI_CADENCE config SPI_CADENCE_QUADSPI tristate "Cadence Quad SPI controller" - depends on OF && (ARM || ARM64 || X86 || COMPILE_TEST) + depends on OF && (ARM || ARM64 || X86 || RISCV || COMPILE_TEST) help Enable support for the Cadence Quad SPI Flash controller.
drivers/spi/spi-cadence-quadspi.c +20 -1
@@ -1586,7 +1586,7 @@ static int cqspi_setup_flash(struct cqspi_st *cqspi)static int cqspi_probe (struct platform_device *pdev) {const struct cqspi_driver_platdata *ddata; -struct reset_control *rstc, *rstc_ocp; +struct reset_control *rstc, *rstc_ocp, *rstc_ref;struct device *dev = &pdev->dev;struct spi_master *master;struct resource *res_ahb;
@@ -1679,6 +1679,17 @@ static int cqspi_probe(struct platform_device *pdev) goto probe_reset_failed; } +if (of_device_is_compatible (pdev->dev.of_node,"starfive,jh7110-qspi" )) { + rstc_ref =devm_reset_control_get_optional_exclusive (dev,"rstc_ref" ); +if (IS_ERR (rstc_ref)) { + ret =PTR_ERR (rstc_ref); +dev_err (dev,"Cannot get QSPI REF reset.\n" ); + goto probe_reset_failed; + } +reset_control_assert (rstc_ref); +reset_control_deassert (rstc_ref); + } +reset_control_assert (rstc);reset_control_deassert (rstc);
@@ -1836,6 +1847,10 @@ static const struct cqspi_driver_platdata versal_ospi = { .get_dma_status = cqspi_get_versal_dma_status, }; +static const struct cqspi_driver_platdata jh7110_qspi = { + .quirks =CQSPI_DISABLE_DAC_MODE , +}; +static const struct of_device_id cqspi_dt_ids[] = { { .compatible ="cdns,qspi-nor" ,
@@ -1861,6 +1876,10 @@ static const struct of_device_id cqspi_dt_ids[] = { .compatible = "intel,socfpga-qspi", .data = &socfpga_qspi, }, + { + .compatible = "starfive,jh7110-qspi", + .data = &jh7110_qspi, + }, {/* end of table */ } };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 278/634 spi: cadence-quadspi: Add compatible for AMD Pensando Elba SoC
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brad Larson <[email protected]>
[ Upstream commit f5c2f9f9584353bc816d76a65c97dd03dc61678c ]
The AMD Pensando Elba SoC has the Cadence QSPI controller integrated.
The quirk CQSPI_NEEDS_APB_AHB_HAZARD_WAR is added and if enabled a dummy readback from the controller is performed to ensure synchronization.
Stable-dep-of: 1889dd208197 ("spi: cadence-quadspi: Fix clock disable on probe failure path")
--- drivers/spi/spi-cadence-quadspi.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
drivers/spi/spi-cadence-quadspi.c +19 -0
@@ -40,6 +40,7 @@#define CQSPI_SUPPORT_EXTERNAL_DMA BIT(2)#define CQSPI_NO_SUPPORT_WR_COMPLETION BIT(3)#define CQSPI_SLOW_SRAM BIT(4) +#define CQSPI_NEEDS_APB_AHB_HAZARD_WAR BIT(5)/* Capabilities */ #define CQSPI_SUPPORTS_OCTAL BIT(0)
@@ -89,6 +90,7 @@ struct cqspi_st {u32 pd_dev_id;bool wr_completion;bool slow_sram; +bool apb_ahb_hazard; };struct cqspi_driver_platdata {
@@ -983,6 +985,13 @@ static int cqspi_indirect_write_execute(struct cqspi_flash_pdata *f_pdata,if (cqspi->wr_delay)ndelay (cqspi->wr_delay); +/* +* If a hazard exists between the APB and AHB interfaces, perform a +* dummy readback from the controller to ensure synchronization. +*/ +if (cqspi->apb_ahb_hazard) +readl (reg_base +CQSPI_REG_INDIRECTWR ); +while (remaining >0 ) {size_t write_words, mod_bytes;
@@ -1717,6 +1726,8 @@ static int cqspi_probe(struct platform_device *pdev) cqspi->wr_completion = false;if (ddata->quirks &CQSPI_SLOW_SRAM ) cqspi->slow_sram = true; +if (ddata->quirks &CQSPI_NEEDS_APB_AHB_HAZARD_WAR ) + cqspi->apb_ahb_hazard = true;if (of_device_is_compatible (pdev->dev.of_node,"xlnx,versal-ospi-1.0" )) {
@@ -1851,6 +1862,10 @@ static const struct cqspi_driver_platdata jh7110_qspi = { .quirks = CQSPI_DISABLE_DAC_MODE, }; +static const struct cqspi_driver_platdata pensando_cdns_qspi = { + .quirks =CQSPI_NEEDS_APB_AHB_HAZARD_WAR |CQSPI_DISABLE_DAC_MODE , +}; +static const struct of_device_id cqspi_dt_ids[] = { { .compatible ="cdns,qspi-nor" ,
@@ -1880,6 +1895,10 @@ static const struct of_device_id cqspi_dt_ids[] = { .compatible = "starfive,jh7110-qspi", .data = &jh7110_qspi, }, + { + .compatible = "amd,pensando-elba-qspi", + .data = &pensando_cdns_qspi, + }, {/* end of table */ } };
Signature · 1 line
2.51.0