6.17.3-rc1 review
Subsystems (8)
Greg Kroah-Hartman
maintainerPATCH 513/563 tracing: Fix race condition in kprobe initialization causing NULL pointer dereference
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuan Chen <[email protected]>
commit 9cf9aa7b0acfde7545c1a1d912576e9bab28dc6f upstream.
There is a critical race condition in kprobe initialization that can lead to NULL pointer dereference and kernel crash.
[1135630.084782] Unable to handle kernel paging request at virtual address 0000710a04630000 ... [1135630.260314] pstate: 404003c9 (nZcv DAIF +PAN -UAO) [1135630.269239] pc : kprobe_perf_func+0x30/0x260 [1135630.277643] lr : kprobe_dispatcher+0x44/0x60 [1135630.286041] sp : ffffaeff4977fa40 [1135630.293441] x29: ffffaeff4977fa40 x28: ffffaf015340e400 [1135630.302837] x27: 0000000000000000 x26: 0000000000000000 [1135630.312257] x25: ffffaf029ed108a8 x24: ffffaf015340e528 [1135630.321705] x23: ffffaeff4977fc50 x22: ffffaeff4977fc50 [1135630.331154] x21: 0000000000000000 x20: ffffaeff4977fc50 [1135630.340586] x19: ffffaf015340e400 x18: 0000000000000000 [1135630.349985] x17: 0000000000000000 x16: 0000000000000000 [1135630.359285] x15: 0000000000000000 x14: 0000000000000000 [1135630.368445] x13: 0000000000000000 x12: 0000000000000000 [1135630.377473] x11: 0000000000000000 x10: 0000000000000000 [1135630.386411] x9 : 0000000000000000 x8 : 0000000000000000 [1135630.395252] x7 : 0000000000000000 x6 : 0000000000000000 [1135630.403963] x5 : 0000000000000000 x4 : 0000000000000000 [1135630.412545] x3 : 0000710a04630000 x2 : 0000000000000006 [1135630.421021] x1 : ffffaeff4977fc50 x0 : 0000710a04630000 [1135630.429410] Call trace: [1135630.434828] kprobe_perf_func+0x30/0x260 [1135630.441661] kprobe_dispatcher+0x44/0x60 [1135630.448396] aggr_pre_handler+0x70/0xc8 [1135630.454959] kprobe_breakpoint_handler+0x140/0x1e0 [1135630.462435] brk_handler+0xbc/0xd8 [1135630.468437] do_debug_exception+0x84/0x138 [1135630.475074] el1_dbg+0x18/0x8c [1135630.480582] security_file_permission+0x0/0xd0 [1135630.487426] vfs_write+0x70/0x1c0 [1135630.493059] ksys_write+0x5c/0xc8 [1135630.498638] __arm64_sys_write+0x24/0x30 [1135630.504821] el0_svc_common+0x78/0x130 [1135630.510838] el0_svc_handler+0x38/0x78 [1135630.516834] el0_svc+0x8/0x1b0
kernel/trace/trace_kprobe.c: 13080xffff3df8995039ec <kprobe_perf_func+0x2c>: ldr x21, [x24,#120]include/linux/compiler.h: 2940xffff3df8995039f0 <kprobe_perf_func+0x30>: ldr x1, [x21,x0]
kernel/trace/trace_kprobe.c
1308: head = this_cpu_ptr(call->perf_events);
1309: if (hlist_empty(head))
1310: return 0;
crash> struct trace_event_call -o
struct trace_event_call {
...
[120] struct hlist_head *perf_events; //(call->perf_event)
...
}
crash> struct trace_event_call ffffaf015340e528
struct trace_event_call {
...
perf_events = 0xffff0ad5fa89f088, //this value is correct, but x21 = 0
...
}
Race Condition Analysis:
The race occurs between kprobe activation and perf_events initialization:
CPU0 CPU1
==== ====
perf_kprobe_init
perf_trace_event_init
tp_event->perf_events = list;(1)
tp_event->class->reg (2)← KPROBE ACTIVE
Debug exception triggers
...
kprobe_dispatcher
kprobe_perf_func (tk->tp.flags & TP_FLAG_PROFILE)
head = this_cpu_ptr(call->perf_events)(3)
(perf_events is still NULL)Problem:
1. CPU0 executes (1) assigning tp_event->perf_events = list
2. CPU0 executes (2) enabling kprobe functionality via class->reg()
3. CPU1 triggers and reaches kprobe_dispatcher
4. CPU1 checks TP_FLAG_PROFILE - condition passes (step 2 completed)
5. CPU1 calls kprobe_perf_func() and crashes at (3) because call->perf_events is still NULL
CPU1 sees that kprobe functionality is enabled but does not see that perf_events has been assigned.
Add pairing read and write memory barriers to guarantee that if CPU1 sees that kprobe functionality is enabled, it must also see that perf_events has been assigned.
--- kernel/trace/trace_fprobe.c | 10 ++++++---- kernel/trace/trace_kprobe.c | 11 +++++++---- kernel/trace/trace_probe.h | 9 +++++++-- kernel/trace/trace_uprobe.c | 12 ++++++++---- 4 files changed, 28 insertions(+), 14 deletions(-)
kernel/trace/trace_fprobe.c +6 -4
@@ -522,13 +522,14 @@ static int fentry_dispatcher(struct fpro void *entry_data) { struct trace_fprobe *tf = container_of(fp, struct trace_fprobe, fp); +unsigned int flags =trace_probe_load_flag (&tf->tp);int ret =0 ; -if (trace_probe_test_flag (&tf->tp,TP_FLAG_TRACE )) +if (flags &TP_FLAG_TRACE )fentry_trace_func (tf, entry_ip, fregs);#ifdef CONFIG_PERF_EVENTS -if (trace_probe_test_flag (&tf->tp,TP_FLAG_PROFILE )) +if (flags &TP_FLAG_PROFILE ) ret =fentry_perf_func (tf, entry_ip, fregs);#endif return ret;
@@ -540,11 +541,12 @@ static void fexit_dispatcher(struct fpro void *entry_data) { struct trace_fprobe *tf = container_of(fp, struct trace_fprobe, fp); +unsigned int flags =trace_probe_load_flag (&tf->tp); -if (trace_probe_test_flag (&tf->tp,TP_FLAG_TRACE )) +if (flags &TP_FLAG_TRACE )fexit_trace_func (tf, entry_ip, ret_ip, fregs, entry_data);#ifdef CONFIG_PERF_EVENTS -if (trace_probe_test_flag (&tf->tp,TP_FLAG_PROFILE )) +if (flags &TP_FLAG_PROFILE )fexit_perf_func (tf, entry_ip, ret_ip, fregs, entry_data);#endif }
kernel/trace/trace_kprobe.c +7 -4
@@ -1815,14 +1815,15 @@ static int kprobe_register(struct trace_static int kprobe_dispatcher (struct kprobe *kp,struct pt_regs *regs) { struct trace_kprobe *tk = container_of(kp, struct trace_kprobe, rp.kp); +unsigned int flags =trace_probe_load_flag (&tk->tp);int ret =0 ;raw_cpu_inc (*tk->nhit); -if (trace_probe_test_flag (&tk->tp,TP_FLAG_TRACE )) +if (flags &TP_FLAG_TRACE )kprobe_trace_func (tk, regs);#ifdef CONFIG_PERF_EVENTS -if (trace_probe_test_flag (&tk->tp,TP_FLAG_PROFILE )) +if (flags &TP_FLAG_PROFILE ) ret =kprobe_perf_func (tk, regs);#endif return ret;
@@ -1834,6 +1835,7 @@ kretprobe_dispatcher(struct kretprobe_in {struct kretprobe *rp =get_kretprobe (ri);struct trace_kprobe *tk; +unsigned int flags;/* * There is a small chance that get_kretprobe(ri) returns NULL when
@@ -1846,10 +1848,11 @@ kretprobe_dispatcher(struct kretprobe_in tk = container_of(rp, struct trace_kprobe, rp);raw_cpu_inc (*tk->nhit); -if (trace_probe_test_flag (&tk->tp,TP_FLAG_TRACE )) + flags =trace_probe_load_flag (&tk->tp); +if (flags &TP_FLAG_TRACE )kretprobe_trace_func (tk, ri, regs);#ifdef CONFIG_PERF_EVENTS -if (trace_probe_test_flag (&tk->tp,TP_FLAG_PROFILE )) +if (flags &TP_FLAG_PROFILE )kretprobe_perf_func (tk, ri, regs);#endif return 0 ;/* We don't tweak kernel, so just return 0 */
kernel/trace/trace_probe.h +7 -2
@@ -271,16 +271,21 @@ struct event_file_link {struct list_head list; }; +static inline unsigned int trace_probe_load_flag (struct trace_probe *tp) +{ +return smp_load_acquire (&tp->event->flags); +} +static inline bool trace_probe_test_flag (struct trace_probe *tp,unsigned int flag) { -return !!(tp->event->flags & flag); +return !!(trace_probe_load_flag (tp) & flag); }static inline void trace_probe_set_flag (struct trace_probe *tp,unsigned int flag) { - tp->event->flags |= flag; +smp_store_release (&tp->event->flags, tp->event->flags | flag); } static inline void trace_probe_clear_flag(struct trace_probe *tp,
kernel/trace/trace_uprobe.c +8 -4
@@ -1547,6 +1547,7 @@ static int uprobe_dispatcher(struct uprostruct trace_uprobe *tu;struct uprobe_dispatch_data udd;struct uprobe_cpu_buffer *ucb =NULL ; +unsigned int flags;int ret =0 ; tu = container_of(con, struct trace_uprobe, consumer);
@@ -1561,11 +1562,12 @@ static int uprobe_dispatcher(struct uproif (WARN_ON_ONCE (!uprobe_cpu_buffer))return 0 ; -if (trace_probe_test_flag (&tu->tp,TP_FLAG_TRACE )) + flags =trace_probe_load_flag (&tu->tp); +if (flags &TP_FLAG_TRACE ) ret |=uprobe_trace_func (tu, regs, &ucb);#ifdef CONFIG_PERF_EVENTS -if (trace_probe_test_flag (&tu->tp,TP_FLAG_PROFILE )) +if (flags &TP_FLAG_PROFILE ) ret |=uprobe_perf_func (tu, regs, &ucb);#endif uprobe_buffer_put (ucb);
@@ -1579,6 +1581,7 @@ static int uretprobe_dispatcher(struct ustruct trace_uprobe *tu;struct uprobe_dispatch_data udd;struct uprobe_cpu_buffer *ucb =NULL ; +unsigned int flags; tu = container_of(con, struct trace_uprobe, consumer);
@@ -1590,11 +1593,12 @@ static int uretprobe_dispatcher(struct uif (WARN_ON_ONCE (!uprobe_cpu_buffer))return 0 ; -if (trace_probe_test_flag (&tu->tp,TP_FLAG_TRACE )) + flags =trace_probe_load_flag (&tu->tp); +if (flags &TP_FLAG_TRACE )uretprobe_trace_func (tu, func, regs, &ucb);#ifdef CONFIG_PERF_EVENTS -if (trace_probe_test_flag (&tu->tp,TP_FLAG_PROFILE )) +if (flags &TP_FLAG_PROFILE )uretprobe_perf_func (tu, func, regs, &ucb);#endif uprobe_buffer_put (ucb);
Greg Kroah-Hartman
maintainerPATCH 514/563 tracing: Fix wakeup tracers on failure of acquiring calltime
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <[email protected]>
commit 4f7bf54b07e5acf79edd58dafede4096854776cd upstream.
The functions wakeup_graph_entry() and wakeup_graph_return() both call func_prolog_preempt_disable() that will test if the data->disable is already set and if not, increment it and disable preemption. If it was set, it returns false and the caller exits.
The caller of this function must decrement the disable counter, but misses doing so if the calltime fails to be acquired.
Instead of exiting out when calltime is NULL, change the logic to do the work if it is not NULL and still do the clean up at the end of the function if it is NULL.
--- kernel/trace/trace_sched_wakeup.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-)
kernel/trace/trace_sched_wakeup.c +6 -10
@@ -138,12 +138,10 @@ static int wakeup_graph_entry(struct ftrreturn 0 ; calltime =fgraph_reserve_data (gops->idx,sizeof (*calltime)); -if (!calltime) -return 0 ; - - *calltime =trace_clock_local (); - - ret =__trace_graph_entry (tr, trace, trace_ctx); +if (calltime) { + *calltime =trace_clock_local (); + ret =__trace_graph_entry (tr, trace, trace_ctx); + }local_dec (&data->disabled);preempt_enable_notrace ();
@@ -169,12 +167,10 @@ static void wakeup_graph_return(struct f rettime =trace_clock_local (); calltime =fgraph_retrieve_data (gops->idx, &size); -if (!calltime) -return ; +if (calltime) +__trace_graph_return (tr, trace, trace_ctx, *calltime, rettime); -__trace_graph_return (tr, trace, trace_ctx, *calltime, rettime);local_dec (&data->disabled); -preempt_enable_notrace ();return ; }
Greg Kroah-Hartman
maintainerPATCH 515/563 tracing: Fix irqoff tracers on failure of acquiring calltime
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <[email protected]>
commit c834a97962c708ff5bb8582ca76b0e1225feb675 upstream.
The functions irqsoff_graph_entry() and irqsoff_graph_return() both call func_prolog_dec() that will test if the data->disable is already set and if not, increment it and return. If it was set, it returns false and the caller exits.
The caller of this function must decrement the disable counter, but misses doing so if the calltime fails to be acquired.
Instead of exiting out when calltime is NULL, change the logic to do the work if it is not NULL and still do the clean up at the end of the function if it is NULL.
--- kernel/trace/trace_irqsoff.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-)
kernel/trace/trace_irqsoff.c +10 -13
@@ -184,7 +184,7 @@ static int irqsoff_graph_entry(struct ftrace_graph_ent *trace,unsigned long flags;unsigned int trace_ctx;u64 *calltime; -int ret; +int ret =0 ;if (ftrace_graph_ignore_func (gops, trace))return 0 ;
@@ -202,13 +202,11 @@ static int irqsoff_graph_entry(struct ftrace_graph_ent *trace,return 0 ; calltime =fgraph_reserve_data (gops->idx,sizeof (*calltime)); -if (!calltime) -return 0 ; - - *calltime =trace_clock_local (); - - trace_ctx =tracing_gen_ctx_flags (flags); - ret =__trace_graph_entry (tr, trace, trace_ctx); +if (calltime) { + *calltime =trace_clock_local (); + trace_ctx =tracing_gen_ctx_flags (flags); + ret =__trace_graph_entry (tr, trace, trace_ctx); + }local_dec (&data->disabled);return ret;
@@ -233,11 +231,10 @@ static void irqsoff_graph_return(struct ftrace_graph_ret *trace, rettime =trace_clock_local (); calltime =fgraph_retrieve_data (gops->idx, &size); -if (!calltime) -return ; - - trace_ctx =tracing_gen_ctx_flags (flags); -__trace_graph_return (tr, trace, trace_ctx, *calltime, rettime); +if (calltime) { + trace_ctx =tracing_gen_ctx_flags (flags); +__trace_graph_return (tr, trace, trace_ctx, *calltime, rettime); + }local_dec (&data->disabled); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 516/563 tracing: Have trace_marker use per-cpu data to read user space
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <[email protected]>
commit 64cf7d058a005c5c31eb8a0b741f35dc12915d18 upstream.
It was reported that using __copy_from_user_inatomic() can actually schedule. Which is bad when preemption is disabled. Even though there's logic to check in_atomic() is set, but this is a nop when the kernel is configured with PREEMPT_NONE. This is due to page faulting and the code could schedule with preemption disabled.
The solution was to change the __copy_from_user_inatomic() to copy_from_user_nofault(). But then it was reported that this caused a regression in Android. There's several applications writing into trace_marker() in Android, but now instead of showing the expected data, it is showing:
tracing_mark_write: <faulted>
After reverting the conversion to copy_from_user_nofault(), Android was able to get the data again.
Writes to the trace_marker is a way to efficiently and quickly enter data into the Linux tracing buffer. It takes no locks and was designed to be as non-intrusive as possible. This means it cannot allocate memory, and must use pre-allocated data.
A method that is actively being worked on to have faultable system call tracepoints read user space data is to allocate per CPU buffers, and use them in the callback. The method uses a technique similar to seqcount. That is something like this:
preempt_disable();
cpu = smp_processor_id();
buffer = this_cpu_ptr(&pre_allocated_cpu_buffers, cpu);
do {
cnt = nr_context_switches_cpu(cpu);
migrate_disable();
preempt_enable();
ret = copy_from_user(buffer, ptr, size);
preempt_disable();
migrate_enable();
} while (!ret && cnt != nr_context_switches_cpu(cpu));
if (!ret)
ring_buffer_write(buffer);
preempt_enable();It's a little more involved than that, but the above is the basic logic. The idea is to acquire the current CPU buffer, disable migration, and then enable preemption. At this moment, it can safely use copy_from_user(). After reading the data from user space, it disables preemption again. It then checks to see if there was any new scheduling on this CPU. If there was, it must assume that the buffer was corrupted by another task. If there wasn't, then the buffer is still valid as only tasks in preemptable context can write to this buffer and only those that are running on the CPU.
By using this method, where trace_marker open allocates the per CPU buffers, trace_marker writes can access user space and even fault it in, without having to allocate or take any locks of its own.
--- kernel/trace/trace.c | 268 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 220 insertions(+), 48 deletions(-)
kernel/trace/trace.c +220 -48
@@ -4791,12 +4791,6 @@ int tracing_single_release_file_tr(strucreturn single_release (inode, filp); } -static int tracing_mark_open (struct inode *inode,struct file *filp) -{ -stream_open (inode, filp); -return tracing_open_generic_tr (inode, filp); -} -static int tracing_release (struct inode *inode,struct file *file) {struct trace_array *tr = inode->i_private;
@@ -7163,7 +7157,7 @@ tracing_free_buffer_release(struct inode#define TRACE_MARKER_MAX_SIZE 4096 -static ssize_t write_marker_to_buffer (struct trace_array *tr,const char __user *ubuf, +static ssize_t write_marker_to_buffer (struct trace_array *tr,const char *buf,size_t cnt,unsigned long ip) {struct ring_buffer_event *event;
@@ -7173,20 +7167,11 @@ static ssize_t write_marker_to_buffer(stint meta_size;ssize_t written;size_t size; -int len; - -/* Used in tracing_mark_raw_write() as well */ -#define FAULTED_STR "<faulted>" -#define FAULTED_SIZE (sizeof(FAULTED_STR) - 1)/* '\0' is already accounted for */ meta_size =sizeof (*entry) +2 ;/* add '\0' and possible '\n' */ again: size = cnt + meta_size; -/* If less than "<faulted>", then make sure we can still add that */ -if (cnt <FAULTED_SIZE ) - size +=FAULTED_SIZE - cnt; - buffer = tr->array_buffer.buffer; event =__trace_buffer_lock_reserve (buffer,TRACE_PRINT , size,tracing_gen_ctx ());
@@ -7196,9 +7181,6 @@ static ssize_t write_marker_to_buffer(st* make it smaller and try again. */ if (size >ring_buffer_max_event_size (buffer)) { -/* cnt < FAULTED size should never be bigger than max */ -if (WARN_ON_ONCE (cnt <FAULTED_SIZE )) -return -EBADF ; cnt =ring_buffer_max_event_size (buffer) - meta_size;/* The above should only happen once */ if (WARN_ON_ONCE (cnt + meta_size == size))
@@ -7212,14 +7194,8 @@ static ssize_t write_marker_to_buffer(st entry =ring_buffer_event_data (event); entry->ip = ip; - - len =copy_from_user_nofault (&entry->buf, ubuf, cnt); -if (len) { -memcpy (&entry->buf,FAULTED_STR ,FAULTED_SIZE ); - cnt =FAULTED_SIZE ; - written = -EFAULT ; - }else - written = cnt; +memcpy (&entry->buf, buf, cnt); + written = cnt;if (tr->trace_marker_file && !list_empty (&tr->trace_marker_file->triggers)) {/* do not add \n before testing triggers, but add \0 */
@@ -7243,6 +7219,169 @@ static ssize_t write_marker_to_buffer(streturn written; } +struct trace_user_buf { +char *buf; +}; + +struct trace_user_buf_info { +struct trace_user_buf __percpu *tbuf; +int ref; +}; + + +static DEFINE_MUTEX (trace_user_buffer_mutex); +static struct trace_user_buf_info *trace_user_buffer; + +static void trace_user_fault_buffer_free (struct trace_user_buf_info *tinfo) +{ +char *buf; +int cpu; + +for_each_possible_cpu (cpu) { + buf =per_cpu_ptr (tinfo->tbuf, cpu)->buf; +kfree (buf); + } +free_percpu (tinfo->tbuf); +kfree (tinfo); +} + +static int trace_user_fault_buffer_enable (void ) +{ +struct trace_user_buf_info *tinfo; +char *buf; +int cpu; + +guard (mutex)(&trace_user_buffer_mutex); + +if (trace_user_buffer) { + trace_user_buffer->ref++; +return 0 ; + } + + tinfo =kmalloc (sizeof (*tinfo),GFP_KERNEL ); +if (!tinfo) +return -ENOMEM ; + + tinfo->tbuf = alloc_percpu(struct trace_user_buf); +if (!tinfo->tbuf) { +kfree (tinfo); +return -ENOMEM ; + } + + tinfo->ref =1 ; + +/* Clear each buffer in case of error */ +for_each_possible_cpu (cpu) { +per_cpu_ptr (tinfo->tbuf, cpu)->buf =NULL ; + } + +for_each_possible_cpu (cpu) { + buf =kmalloc_node (TRACE_MARKER_MAX_SIZE ,GFP_KERNEL , +cpu_to_node (cpu)); +if (!buf) { +trace_user_fault_buffer_free (tinfo); +return -ENOMEM ; + } +per_cpu_ptr (tinfo->tbuf, cpu)->buf = buf; + } + + trace_user_buffer = tinfo; + +return 0 ; +} + +static void trace_user_fault_buffer_disable (void ) +{ +struct trace_user_buf_info *tinfo; + +guard (mutex)(&trace_user_buffer_mutex); + + tinfo = trace_user_buffer; + +if (WARN_ON_ONCE (!tinfo)) +return ; + +if (--tinfo->ref) +return ; + +trace_user_fault_buffer_free (tinfo); + trace_user_buffer =NULL ; +} + +/* Must be called with preemption disabled */ +static char *trace_user_fault_read (struct trace_user_buf_info *tinfo, +const char __user *ptr,size_t size, +size_t *read_size) +{ +int cpu =smp_processor_id (); +char *buffer =per_cpu_ptr (tinfo->tbuf, cpu)->buf; +unsigned int cnt; +int trys =0 ; +int ret; + +if (size >TRACE_MARKER_MAX_SIZE ) + size =TRACE_MARKER_MAX_SIZE ; + *read_size =0 ; + +/* +* This acts similar to a seqcount. The per CPU context switches are +* recorded, migration is disabled and preemption is enabled. The +* read of the user space memory is copied into the per CPU buffer. +* Preemption is disabled again, and if the per CPU context switches count +* is still the same, it means the buffer has not been corrupted. +* If the count is different, it is assumed the buffer is corrupted +* and reading must be tried again. +*/ + +do { +/* +* If for some reason, copy_from_user() always causes a context +* switch, this would then cause an infinite loop. +* If this task is preempted by another user space task, it +* will cause this task to try again. But just in case something +* changes where the copying from user space causes another task +* to run, prevent this from going into an infinite loop. +* 100 tries should be plenty. +*/ +if (WARN_ONCE (trys++ >100 ,"Error: Too many tries to read user space" )) +return NULL ; + +/* Read the current CPU context switch counter */ + cnt =nr_context_switches_cpu (cpu); + +/* +* Preemption is going to be enabled, but this task must +* remain on this CPU. +*/ +migrate_disable (); + +/* +* Now preemption is being enabed and another task can come in +* and use the same buffer and corrupt our data. +*/ +preempt_enable_notrace (); + + ret =__copy_from_user (buffer, ptr, size); + +preempt_disable_notrace (); +migrate_enable (); + +/* if it faulted, no need to test if the buffer was corrupted */ +if (ret) +return NULL ; + +/* +* Preemption is disabled again, now check the per CPU context +* switch counter. If it doesn't match, then another user space +* process may have schedule in and corrupted our buffer. In that +* case the copying must be retried. +*/ + }while (nr_context_switches_cpu (cpu) != cnt); + + *read_size = size; +return buffer; +} +static ssize_t tracing_mark_write (struct file *filp,const char __user *ubuf,size_t cnt,loff_t *fpos)
@@ -7250,6 +7389,8 @@ tracing_mark_write(struct file *filp, costruct trace_array *tr = filp->private_data;ssize_t written = -ENODEV ;unsigned long ip; +size_t size; +char *buf;if (tracing_disabled)return -EINVAL ;
@@ -7263,6 +7404,16 @@ tracing_mark_write(struct file *filp, coif (cnt >TRACE_MARKER_MAX_SIZE ) cnt =TRACE_MARKER_MAX_SIZE ; +/* Must have preemption disabled while having access to the buffer */ +guard (preempt_notrace)(); + + buf =trace_user_fault_read (trace_user_buffer, ubuf, cnt, &size); +if (!buf) +return -EFAULT ; + +if (cnt > size) + cnt = size; +/* The selftests expect this function to be the IP address */ ip = _THIS_IP_;
@@ -7270,32 +7421,27 @@ tracing_mark_write(struct file *filp, coif (tr == &global_trace) {guard (rcu)();list_for_each_entry_rcu (tr, &marker_copies, marker_list) { - written =write_marker_to_buffer (tr, ubuf, cnt, ip); + written =write_marker_to_buffer (tr, buf, cnt, ip);if (written <0 )break ; } }else { - written =write_marker_to_buffer (tr, ubuf, cnt, ip); + written =write_marker_to_buffer (tr, buf, cnt, ip); }return written; }static ssize_t write_raw_marker_to_buffer (struct trace_array *tr, -const char __user *ubuf,size_t cnt) +const char *buf,size_t cnt) {struct ring_buffer_event *event;struct trace_buffer *buffer;struct raw_data_entry *entry;ssize_t written; -int size; -int len; - -#define FAULT_SIZE_ID (FAULTED_SIZE + sizeof(int)) +size_t size; size =sizeof (*entry) + cnt; -if (cnt <FAULT_SIZE_ID ) - size +=FAULT_SIZE_ID - cnt; buffer = tr->array_buffer.buffer;
@@ -7309,14 +7455,8 @@ static ssize_t write_raw_marker_to_buffereturn -EBADF ; entry =ring_buffer_event_data (event); - - len =copy_from_user_nofault (&entry->id, ubuf, cnt); -if (len) { - entry->id =-1 ; -memcpy (&entry->buf,FAULTED_STR ,FAULTED_SIZE ); - written = -EFAULT ; - }else - written = cnt; +memcpy (&entry->id, buf, cnt); + written = cnt;__buffer_unlock_commit (buffer, event);
@@ -7329,8 +7469,8 @@ tracing_mark_raw_write(struct file *filp {struct trace_array *tr = filp->private_data;ssize_t written = -ENODEV ; - -#define FAULT_SIZE_ID (FAULTED_SIZE + sizeof(int)) +size_t size; +char *buf;if (tracing_disabled)return -EINVAL ;
@@ -7342,6 +7482,17 @@ tracing_mark_raw_write(struct file *filpif (cnt <sizeof (unsigned int ))return -EINVAL ; +/* Must have preemption disabled while having access to the buffer */ +guard (preempt_notrace)(); + + buf =trace_user_fault_read (trace_user_buffer, ubuf, cnt, &size); +if (!buf) +return -EFAULT ; + +/* raw write is all or nothing */ +if (cnt > size) +return -EINVAL ; +/* The global trace_marker_raw can go to multiple instances */ if (tr == &global_trace) {guard (rcu)();
@@ -7357,6 +7508,27 @@ tracing_mark_raw_write(struct file *filpreturn written; } +static int tracing_mark_open (struct inode *inode,struct file *filp) +{ +int ret; + + ret =trace_user_fault_buffer_enable (); +if (ret <0 ) +return ret; + +stream_open (inode, filp); + ret =tracing_open_generic_tr (inode, filp); +if (ret <0 ) +trace_user_fault_buffer_disable (); +return ret; +} + +static int tracing_mark_release (struct inode *inode,struct file *file) +{ +trace_user_fault_buffer_disable (); +return tracing_release_generic_tr (inode, file); +} +static int tracing_clock_show (struct seq_file *m,void *v) {struct trace_array *tr = m->private;
@@ -7764,13 +7936,13 @@ static const struct file_operations tracstatic const struct file_operations tracing_mark_fops = { .open = tracing_mark_open, .write = tracing_mark_write, - .release = tracing_release_generic_tr, + .release = tracing_mark_release, };static const struct file_operations tracing_mark_raw_fops = { .open = tracing_mark_open, .write = tracing_mark_raw_write, - .release = tracing_release_generic_tr, + .release = tracing_mark_release, };static const struct file_operations trace_clock_fops = {
Greg Kroah-Hartman
maintainerPATCH 517/563 tracing: Fix tracing_mark_raw_write() to use buf and not ubuf
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <[email protected]>
commit bda745ee8fbb63330d8f2f2ea4157229a5df959e upstream.
The fix to use a per CPU buffer to read user space tested only the writes to trace_marker. But it appears that the selftests are missing tests to the trace_maker_raw file. The trace_maker_raw file is used by applications that writes data structures and not strings into the file, and the tools read the raw ring buffer to process the structures it writes.
The fix that reads the per CPU buffers passes the new per CPU buffer to the trace_marker file writes, but the update to the trace_marker_raw write read the data from user space into the per CPU buffer, but then still used then passed the user space address to the function that records the data.
Pass in the per CPU buffer and not the user space address.
TODO: Add a test to better test trace_marker_raw.
--- kernel/trace/trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/trace/trace.c +2 -2
@@ -7497,12 +7497,12 @@ tracing_mark_raw_write(struct file *filpif (tr == &global_trace) {guard (rcu)();list_for_each_entry_rcu (tr, &marker_copies, marker_list) { - written =write_raw_marker_to_buffer (tr, ubuf, cnt); + written =write_raw_marker_to_buffer (tr, buf, cnt);if (written <0 )break ; } }else { - written =write_raw_marker_to_buffer (tr, ubuf, cnt); + written =write_raw_marker_to_buffer (tr, buf, cnt); }return written;
Greg Kroah-Hartman
maintainerPATCH 518/563 tracing: Stop fortify-string from warning in tracing_mark_raw_write()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <[email protected]>
commit 54b91e54b113d4f15ab023a44f508251db6e22e7 upstream.
The way tracing_mark_raw_write() records its data is that it has the following structure:
struct {
struct trace_entry;
int id;
char buf[];};
But memcpy(&entry->id, buf, size) triggers the following warning when the size is greater than the id:
------------[ cut here ]------------ memcpy: detected field-spanning write (size 6) of single field "&entry->id" at kernel/trace/trace.c:7458 (size 4) WARNING: CPU: 7 PID: 995 at kernel/trace/trace.c:7458 write_raw_marker_to_buffer.isra.0+0x1f9/0x2e0 Modules linked in: CPU: 7 UID: 0 PID: 995 Comm: bash Not tainted 6.17.0-test-00007-g60b82183e78a-dirty #211 PREEMPT(voluntary) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-debian-1.17.0-1 04/01/2014 RIP: 0010:write_raw_marker_to_buffer.isra.0+0x1f9/0x2e0 Code: 04 00 75 a7 b9 04 00 00 00 48 89 de 48 89 04 24 48 c7 c2 e0 b1 d1 b2 48 c7 c7 40 b2 d1 b2 c6 05 2d 88 6a 04 01 e8 f7 e8 bd ff <0f> 0b 48 8b 04 24 e9 76 ff ff ff 49 8d 7c 24 04 49 8d 5c 24 08 48 RSP: 0018:ffff888104c3fc78 EFLAGS: 00010292 RAX: 0000000000000000 RBX: 0000000000000006 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 1ffffffff6b363b4 RDI: 0000000000000001 RBP: ffff888100058a00 R08: ffffffffb041d459 R09: ffffed1020987f40 R10: 0000000000000007 R11: 0000000000000001 R12: ffff888100bb9010 R13: 0000000000000000 R14: 00000000000003e3 R15: ffff888134800000 FS: 00007fa61d286740(0000) GS:ffff888286cad000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000560d28d509f1 CR3: 00000001047a4006 CR4: 0000000000172ef0 Call Trace: <TASK> tracing_mark_raw_write+0x1fe/0x290 ? __pfx_tracing_mark_raw_write+0x10/0x10 ? security_file_permission+0x50/0xf0 ? rw_verify_area+0x6f/0x4b0 vfs_write+0x1d8/0xdd0 ? __pfx_vfs_write+0x10/0x10 ? __pfx_css_rstat_updated+0x10/0x10 ? count_memcg_events+0xd9/0x410 ? fdget_pos+0x53/0x5e0 ksys_write+0x182/0x200 ? __pfx_ksys_write+0x10/0x10 ? do_user_addr_fault+0x4af/0xa30 do_syscall_64+0x63/0x350 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7fa61d318687 Code: 48 89 fa 4c 89 df e8 58 b3 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff RSP: 002b:00007ffd87fe0120 EFLAGS: 00000202 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 00007fa61d286740 RCX: 00007fa61d318687 RDX: 0000000000000006 RSI: 0000560d28d509f0 RDI: 0000000000000001 RBP: 0000560d28d509f0 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000006 R13: 00007fa61d4715c0 R14: 00007fa61d46ee80 R15: 0000000000000000 </TASK> ---[ end trace 0000000000000000 ]---
This is because fortify string sees that the size of entry->id is only 4 bytes, but it is writing more than that. But this is OK as the dynamic_array is allocated to handle that copy.
The size allocated on the ring buffer was actually a bit too big:
size = sizeof(*entry) + cnt;
But cnt includes the 'id' and the buffer data, so adding cnt to the size of *entry actually allocates too much on the ring buffer.
Change the allocation to:
size = struct_size(entry, buf, cnt - sizeof(entry->id));
and the memcpy() to unsafe_memcpy() with an added justification.
--- kernel/trace/trace.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
kernel/trace/trace.c +6 -2
@@ -7441,7 +7441,8 @@ static ssize_t write_raw_marker_to_buffessize_t written;size_t size; - size =sizeof (*entry) + cnt; +/* cnt includes both the entry->id and the data behind it. */ + size =struct_size (entry, buf, cnt -sizeof (entry->id)); buffer = tr->array_buffer.buffer;
@@ -7455,7 +7456,10 @@ static ssize_t write_raw_marker_to_buffereturn -EBADF ; entry =ring_buffer_event_data (event); -memcpy (&entry->id, buf, cnt); +unsafe_memcpy (&entry->id, buf, cnt, +"id and content already reserved on ring buffer" +"'buf' includes the 'id' and the data." +"'entry' was allocated with cnt from 'id'." ); written = cnt;__buffer_unlock_commit (buffer, event);
Greg Kroah-Hartman
maintainerPATCH 519/563 dm: fix queue start/stop imbalance under suspend/load/resume races
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zheng Qixing <[email protected]>
commit 7f597c2cdb9d3263a6fce07c4fc0a9eaa8e8fc43 upstream.
When suspend and load run concurrently, before q->mq_ops is set in blk_mq_init_allocated_queue(), __dm_suspend() skip dm_stop_queue(). As a result, the queue's quiesce depth is not incremented.
Later, once table load has finished and __dm_resume() runs, which triggers q->quiesce_depth ==0 warning in blk_mq_unquiesce_queue():
Call Trace: <TASK> dm_start_queue+0x16/0x20 [dm_mod] __dm_resume+0xac/0xb0 [dm_mod] dm_resume+0x12d/0x150 [dm_mod] do_resume+0x2c2/0x420 [dm_mod] dev_suspend+0x30/0x130 [dm_mod] ctl_ioctl+0x402/0x570 [dm_mod] dm_ctl_ioctl+0x23/0x30 [dm_mod]
Fix this by explicitly tracking whether the request queue was stopped in __dm_suspend() via a new DMF_QUEUE_STOPPED flag. Only call dm_start_queue() in __dm_resume() if the queue was actually stopped.
--- drivers/md/dm-core.h | 1 + drivers/md/dm.c | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-)
drivers/md/dm-core.h +1 -0
@@ -162,6 +162,7 @@ struct mapped_device {#define DMF_SUSPENDED_INTERNALLY 7#define DMF_POST_SUSPENDING 8#define DMF_EMULATE_ZONE_APPEND 9 +#define DMF_QUEUE_STOPPED 10static inline sector_t dm_get_size (struct mapped_device *md) {
drivers/md/dm.c +5 -3
@@ -2960,8 +2960,10 @@ static int __dm_suspend(struct mapped_de* Stop md->queue before flushing md->wq in case request-based * dm defers requests to md->wq from md->queue. */ -if (dm_request_based (md)) +if (dm_request_based (md)) {dm_stop_queue (md->queue); +set_bit (DMF_QUEUE_STOPPED , &md->flags); + }flush_workqueue (md->wq);
@@ -2983,7 +2985,7 @@ static int __dm_suspend(struct mapped_deif (r <0 ) {dm_queue_flush (md); -if (dm_request_based (md)) +if (test_and_clear_bit (DMF_QUEUE_STOPPED , &md->flags))dm_start_queue (md->queue);unlock_fs (md);
@@ -3067,7 +3069,7 @@ static int __dm_resume(struct mapped_dev* so that mapping of targets can work correctly. * Request-based dm is queueing the deferred I/Os in its request_queue. */ -if (dm_request_based (md)) +if (test_and_clear_bit (DMF_QUEUE_STOPPED , &md->flags))dm_start_queue (md->queue);unlock_fs (md);
Greg Kroah-Hartman
maintainerPATCH 520/563 dm: fix NULL pointer dereference in __dm_suspend()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zheng Qixing <[email protected]>
commit 8d33a030c566e1f105cd5bf27f37940b6367f3be upstream.
There is a race condition between dm device suspend and table load that can lead to null pointer dereference. The issue occurs when suspend is invoked before table load completes:
BUG: kernel NULL pointer dereference, address: 0000000000000054 Oops: 0000 [#1] PREEMPT SMP PTI CPU: 6 PID: 6798 Comm: dmsetup Not tainted 6.6.0-g7e52f5f0ca9b #62 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014 RIP: 0010:blk_mq_wait_quiesce_done+0x0/0x50 Call Trace: <TASK> blk_mq_quiesce_queue+0x2c/0x50 dm_stop_queue+0xd/0x20 __dm_suspend+0x130/0x330 dm_suspend+0x11a/0x180 dev_suspend+0x27e/0x560 ctl_ioctl+0x4cf/0x850 dm_ctl_ioctl+0xd/0x20 vfs_ioctl+0x1d/0x50 __se_sys_ioctl+0x9b/0xc0 __x64_sys_ioctl+0x19/0x30 x64_sys_call+0x2c4a/0x4620 do_syscall_64+0x9e/0x1b0
The issue can be triggered as below:
T1 T2dm_suspend table_load__dm_suspend dm_setup_md_queue
dm_mq_init_request_queue blk_mq_init_allocated_queue => q->mq_ops = set->ops; (1) dm_stop_queue / dm_wait_for_completion => q->tag_set NULL pointer! (2) => q->tag_set = set; (3)
Fix this by checking if a valid table (map) exists before performing request-based suspend and waiting for target I/O. When map is NULL, skip these table-dependent suspend steps.
Even when map is NULL, no I/O can reach any target because there is no table loaded; I/O submitted in this state will fail early in the DM layer. Skipping the table-dependent suspend logic in this case is safe and avoids NULL pointer dereferences.
--- drivers/md/dm.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/md/dm.c +4 -3
@@ -2908,7 +2908,7 @@ static int __dm_suspend(struct mapped_de {bool do_lockfs = suspend_flags &DM_SUSPEND_LOCKFS_FLAG ;bool noflush = suspend_flags &DM_SUSPEND_NOFLUSH_FLAG ; -int r; +int r =0 ;lockdep_assert_held (&md->suspend_lock);
@@ -2960,7 +2960,7 @@ static int __dm_suspend(struct mapped_de* Stop md->queue before flushing md->wq in case request-based * dm defers requests to md->wq from md->queue. */ -if (dm_request_based (md)) { +if (map &&dm_request_based (md)) {dm_stop_queue (md->queue);set_bit (DMF_QUEUE_STOPPED , &md->flags); }
@@ -2972,7 +2972,8 @@ static int __dm_suspend(struct mapped_de* We call dm_wait_for_completion to wait for all existing requests * to finish. */ - r =dm_wait_for_completion (md, task_state); +if (map) + r =dm_wait_for_completion (md, task_state);if (!r)set_bit (dmf_suspended_flag, &md->flags);
Greg Kroah-Hartman
maintainerPATCH 521/563 LoongArch: Automatically disable kaslr if boot from kexec_file
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Youling Tang <[email protected]>
commit c8168b4faf1d62cbb320a3e518ad31cdd567cb05 upstream.
Automatically disable kaslr when the kernel loads from kexec_file.
kexec_file loads the secondary kernel image to a non-linked address, inherently providing KASLR-like randomization.
However, on LoongArch where System RAM may be non-contiguous, enabling KASLR for the second kernel may relocate it to an invalid memory region and cause a boot failure. Thus, we disable KASLR when "kexec_file" is detected in the command line.
To ensure compatibility with older kernels loaded via kexec_file, this patch should be backported to stable branches.
--- arch/loongarch/kernel/relocate.c | 4 ++++ 1 file changed, 4 insertions(+)
arch/loongarch/kernel/relocate.c +4 -0
@@ -166,6 +166,10 @@ static inline __init bool kaslr_disabledreturn true;#endif + str =strstr (boot_command_line,"kexec_file" ); +if (str == boot_command_line || (str > boot_command_line && *(str -1 ) ==' ' )) +return true; +return false; }
Greg Kroah-Hartman
maintainerPATCH 522/563 pwm: loongson: Fix LOONGSON_PWM_FREQ_DEFAULT
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xi Ruoyao <[email protected]>
commit 75604e9a5b60707722028947d6dc6bdacb42282e upstream.
Per the 7A1000 and 7A2000 user manual, the clock frequency of their PWM controllers is 50 MHz, not 50 kHz.
--- drivers/pwm/pwm-loongson.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pwm/pwm-loongson.c +1 -1
@@ -49,7 +49,7 @@#define LOONGSON_PWM_CTRL_REG_DZONE BIT(10)/* Anti-dead Zone Enable Bit */ /* default input clk frequency for the ACPI case */ -#define LOONGSON_PWM_FREQ_DEFAULT 50000/* Hz */ +#define LOONGSON_PWM_FREQ_DEFAULT 50000000/* Hz */ struct pwm_loongson_ddata {struct clk *clk;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 523/563 LoongArch: BPF: Sign-extend struct ops return values properly
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hengqi Chen <[email protected]>
commit 8b51b11b3d81c1ed48a52f87da9256d737b723a0 upstream.
The ns_bpf_qdisc selftest triggers a kernel panic:
Oops[#1]:
CPU 0 Unable to handle kernel paging request at virtual address 0000000000741d58, era == 90000000851b5ac0, ra == 90000000851b5aa4
CPU: 0 UID: 0 PID: 449 Comm: test_progs Tainted: G OE 6.16.0+ #3 PREEMPT(full)
Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
Hardware name: QEMU QEMU Virtual Machine, BIOS unknown 2/2/2022
pc 90000000851b5ac0 ra 90000000851b5aa4 tp 90000001076b8000 sp 90000001076bb600
a0 0000000000741ce8 a1 0000000000000001 a2 90000001076bb5c0 a3 0000000000000008
a4 90000001004c4620 a5 9000000100741ce8 a6 0000000000000000 a7 0100000000000000
t0 0000000000000010 t1 0000000000000000 t2 9000000104d24d30 t3 0000000000000001
t4 4f2317da8a7e08c4 t5 fffffefffc002f00 t6 90000001004c4620 t7 ffffffffc61c5b3d
t8 0000000000000000 u0 0000000000000001 s9 0000000000000050 s0 90000001075bc800
s1 0000000000000040 s2 900000010597c400 s3 0000000000000008 s4 90000001075bc880
s5 90000001075bc8f0 s6 0000000000000000 s7 0000000000741ce8 s8 0000000000000000
ra: 90000000851b5aa4 __qdisc_run+0xac/0x8d8
ERA: 90000000851b5ac0 __qdisc_run+0xc8/0x8d8
CRMD: 000000b0 (PLV0 -IE -DA +PG DACF=CC DACM=CC -WE)
PRMD: 00000004 (PPLV0 +PIE -PWE)
EUEN: 00000007 (+FPE +SXE +ASXE -BTE)
ECFG: 00071c1d (LIE=0,2-4,10-12 VS=7)
ESTAT: 00010000 [PIL] (IS= ECode=1 EsubCode=0)
BADV: 0000000000741d58
PRID: 0014c010 (Loongson-64bit, Loongson-3A5000)
Modules linked in: bpf_testmod(OE) [last unloaded: bpf_testmod(OE)]
Process test_progs (pid: 449, threadinfo=000000009af02b3a, task=00000000e9ba4956)
Stack : 0000000000000000 90000001075bc8ac 90000000869524a8 9000000100741ce8
90000001075bc800 9000000100415300 90000001075bc8ac 0000000000000000
900000010597c400 900000008694a000 0000000000000000 9000000105b59000
90000001075bc800 9000000100741ce8 0000000000000050 900000008513000c
9000000086936000 0000000100094d4c fffffff400676208 0000000000000000
9000000105b59000 900000008694a000 9000000086bf0dc0 9000000105b59000
9000000086bf0d68 9000000085147010 90000001075be788 0000000000000000
9000000086bf0f98 0000000000000001 0000000000000010 9000000006015840
0000000000000000 9000000086be6c40 0000000000000000 0000000000000000
0000000000000000 4f2317da8a7e08c4 0000000000000101 4f2317da8a7e08c4
...
Call Trace:
[<90000000851b5ac0>] __qdisc_run+0xc8/0x8d8
[<9000000085130008>] __dev_queue_xmit+0x578/0x10f0
[<90000000853701c0>] ip6_finish_output2+0x2f0/0x950
[<9000000085374bc8>] ip6_finish_output+0x2b8/0x448
[<9000000085370b24>] ip6_xmit+0x304/0x858
[<90000000853c4438>] inet6_csk_xmit+0x100/0x170
[<90000000852b32f0>] __tcp_transmit_skb+0x490/0xdd0
[<90000000852b47fc>] tcp_connect+0xbcc/0x1168
[<90000000853b9088>] tcp_v6_connect+0x580/0x8a0
[<90000000852e7738>] __inet_stream_connect+0x170/0x480
[<90000000852e7a98>] inet_stream_connect+0x50/0x88
[<90000000850f2814>] __sys_connect+0xe4/0x110
[<90000000850f2858>] sys_connect+0x18/0x28
[<9000000085520c94>] do_syscall+0x94/0x1a0
[<9000000083df1fb8>] handle_syscall+0xb8/0x158
Code: 4001ad80 2400873f 2400832d <240073cc> 001137ff 001133ff 6407b41f 001503cc 0280041d
---[ end trace 0000000000000000 ]---The bpf_fifo_dequeue prog returns a skb which is a pointer. The pointer is treated as a 32bit value and sign extend to 64bit in epilogue. This behavior is right for most bpf prog types but wrong for struct ops which requires LoongArch ABI.
So let's sign extend struct ops return values according to the LoongArch ABI ([1]) and return value spec in function model.
[1]: https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html
--- arch/loongarch/net/bpf_jit.c | 37 +++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-)
arch/loongarch/net/bpf_jit.c +36 -1
@@ -1448,6 +1448,37 @@ void arch_free_bpf_trampoline(void *image, unsigned int size)bpf_prog_pack_free (image, size); } +/* +* Sign-extend the register if necessary +*/ +static void sign_extend (struct jit_ctx *ctx,int rd,int rj,u8 size,bool sign) +{ +/* ABI requires unsigned char/short to be zero-extended */ +if (!sign && (size ==1 || size ==2 )) { +if (rd != rj) +move_reg (ctx, rd, rj); +return ; + } + +switch (size) { +case 1 : +emit_insn (ctx, extwb, rd, rj); +break ; +case 2 : +emit_insn (ctx, extwh, rd, rj); +break ; +case 4 : +emit_insn (ctx, addiw, rd, rj,0 ); +break ; +case 8 : +if (rd != rj) +move_reg (ctx, rd, rj); +break ; +default : +pr_warn ("bpf_jit: invalid size %d for sign_extend\n" , size); + } +} +static int __arch_prepare_bpf_trampoline (struct jit_ctx *ctx,struct bpf_tramp_image *im,const struct btf_func_model *m,struct bpf_tramp_links *tlinks,void *func_addr,u32 flags)
@@ -1655,8 +1686,12 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_irestore_args (ctx, m->nr_args, args_off);if (save_ret) { -emit_insn (ctx, ldd,LOONGARCH_GPR_A0 ,LOONGARCH_GPR_FP , -retval_off);emit_insn (ctx, ldd, regmap[BPF_REG_0 ],LOONGARCH_GPR_FP , -(retval_off -8 )); +if (is_struct_ops) +sign_extend (ctx,LOONGARCH_GPR_A0 , regmap[BPF_REG_0 ], + m->ret_size, m->ret_flags &BTF_FMODEL_SIGNED_ARG ); +else +emit_insn (ctx, ldd,LOONGARCH_GPR_A0 ,LOONGARCH_GPR_FP , -retval_off); }emit_insn (ctx, ldd,LOONGARCH_GPR_S1 ,LOONGARCH_GPR_FP , -sreg_off);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 524/563 LoongArch: BPF: No support of struct argument in trampoline programs
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hengqi Chen <[email protected]>
commit e82406c7cbdd368c5459b8a45e118811d2ba0794 upstream.
The current implementation does not support struct argument. This causes a oops when running bpf selftest:
$ ./test_progs -a tracing_struct
Oops[#1]:
CPU -1 Unable to handle kernel paging request at virtual address 0000000000000018, era == 9000000085bef268, ra == 90000000844f3938
rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
rcu: 1-...0: (19 ticks this GP) idle=1094/1/0x4000000000000000 softirq=1380/1382 fqs=801
rcu: (detected by 0, t=5252 jiffies, g=1197, q=52 ncpus=4)
Sending NMI from CPU 0 to CPUs 1:
rcu: rcu_preempt kthread starved for 2495 jiffies! g1197 f0x0 RCU_GP_DOING_FQS(6) ->state=0x0 ->cpu=2
rcu: Unless rcu_preempt kthread gets sufficient CPU time, OOM is now expected behavior.
rcu: RCU grace-period kthread stack dump:
task:rcu_preempt state:I stack:0 pid:15 tgid:15 ppid:2 task_flags:0x208040 flags:0x00000800
Stack : 9000000100423e80 0000000000000402 0000000000000010 90000001003b0680
9000000085d88000 0000000000000000 0000000000000040 9000000087159350
9000000085c2b9b0 0000000000000001 900000008704a000 0000000000000005
00000000ffff355b 00000000ffff355b 0000000000000000 0000000000000004
9000000085d90510 0000000000000000 0000000000000002 7b5d998f8281e86e
00000000ffff355c 7b5d998f8281e86e 000000000000003f 9000000087159350
900000008715bf98 0000000000000005 9000000087036000 900000008704a000
9000000100407c98 90000001003aff80 900000008715c4c0 9000000085c2b9b0
00000000ffff355b 9000000085c33d3c 00000000000000b4 0000000000000000
9000000007002150 00000000ffff355b 9000000084615480 0000000007000002
...
Call Trace:
[<9000000085c2a868>] __schedule+0x410/0x1520
[<9000000085c2b9ac>] schedule+0x34/0x190
[<9000000085c33d38>] schedule_timeout+0x98/0x140
[<90000000845e9120>] rcu_gp_fqs_loop+0x5f8/0x868
[<90000000845ed538>] rcu_gp_kthread+0x260/0x2e0
[<900000008454e8a4>] kthread+0x144/0x238
[<9000000085c26b60>] ret_from_kernel_thread+0x28/0xc8
[<90000000844f20e4>] ret_from_kernel_thread_asm+0xc/0x88 rcu: Stack dump where RCU GP kthread last ran:
Sending NMI from CPU 0 to CPUs 2:
NMI backtrace for cpu 2 skipped: idling at idle_exit+0x0/0x4
Reject it for now.
--- arch/loongarch/net/bpf_jit.c | 6 ++++++ 1 file changed, 6 insertions(+)
arch/loongarch/net/bpf_jit.c +6 -0
@@ -1526,6 +1526,12 @@ static int __arch_prepare_bpf_trampolineif (m->nr_args >LOONGARCH_MAX_REG_ARGS )return -ENOTSUPP ; +/* FIXME: No support of struct argument */ +for (i =0 ; i < m->nr_args; i++) { +if (m->arg_flags[i] &BTF_FMODEL_STRUCT_ARG ) +return -ENOTSUPP ; + } +if (flags & (BPF_TRAMP_F_ORIG_STACK |BPF_TRAMP_F_SHARE_IPMODIFY ))return -ENOTSUPP ;
Greg Kroah-Hartman
maintainerPATCH 525/563 LoongArch: BPF: Dont align trampoline size
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hengqi Chen <[email protected]>
commit a04731cbee6e981afa4263289a0c0059c8b2e7b9 upstream.
Currently, arch_alloc_bpf_trampoline() use bpf_prog_pack_alloc() which will pack multiple trampolines into a huge page. So, no need to assume the trampoline size is page aligned.
--- arch/loongarch/net/bpf_jit.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
arch/loongarch/net/bpf_jit.c +1 -2
@@ -1785,8 +1785,7 @@ int arch_bpf_trampoline_size(const struc ret =__arch_prepare_bpf_trampoline (&ctx, &im, m, tlinks, func_addr, flags); -/* Page align */ -return ret <0 ? ret :round_up (ret *LOONGARCH_INSN_SIZE ,PAGE_SIZE ); +return ret <0 ? ret : ret *LOONGARCH_INSN_SIZE ; }struct bpf_prog *bpf_int_jit_compile (struct bpf_prog *prog)
Greg Kroah-Hartman
maintainerPATCH 526/563 LoongArch: BPF: Make trampoline size stable
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hengqi Chen <[email protected]>
commit ea645cfd3d5f74a2bd40a60003f113b3c467975d upstream.
When attach fentry/fexit BPF programs, __arch_prepare_bpf_trampoline() is called twice with different struct bpf_tramp_image *im:
bpf_trampoline_update()
-> arch_bpf_trampoline_size()
-> __arch_prepare_bpf_trampoline()
-> arch_prepare_bpf_trampoline()
-> __arch_prepare_bpf_trampoline()Use move_imm() will emit unstable instruction sequences, so let's use move_addr() instead to prevent subtle bugs.
(I observed this while debugging other issues with printk.)
--- arch/loongarch/net/bpf_jit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/loongarch/net/bpf_jit.c +2 -2
@@ -1632,7 +1632,7 @@ static int __arch_prepare_bpf_trampoline orig_call +=LOONGARCH_BPF_FENTRY_NBYTES ;if (flags &BPF_TRAMP_F_CALL_ORIG ) { -move_imm (ctx,LOONGARCH_GPR_A0 , (const s64 )im, false); +move_addr (ctx,LOONGARCH_GPR_A0 , (const u64 )im); ret =emit_call (ctx, (const u64 )__bpf_tramp_enter);if (ret)return ret;
@@ -1682,7 +1682,7 @@ static int __arch_prepare_bpf_trampolineif (flags &BPF_TRAMP_F_CALL_ORIG ) { im->ip_epilogue = ctx->ro_image + ctx->idx; -move_imm (ctx,LOONGARCH_GPR_A0 , (const s64 )im, false); +move_addr (ctx,LOONGARCH_GPR_A0 , (const u64 )im); ret =emit_call (ctx, (const u64 )__bpf_tramp_exit);if (ret) goto out;
Greg Kroah-Hartman
maintainerPATCH 527/563 LoongArch: BPF: Make error handling robust in arch_prepare_bpf_trampoline()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hengqi Chen <[email protected]>
commit de2c0b7788648850b68b75f7cc8698b2749dd31e upstream.
Bail out instead of trying to perform a bpf_arch_text_copy() if __arch_prepare_bpf_trampoline() failed.
--- arch/loongarch/net/bpf_jit.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
arch/loongarch/net/bpf_jit.c +4 -1
@@ -1756,7 +1756,10 @@ int arch_prepare_bpf_trampoline(struct bjit_fill_hole (image, (unsigned int )(ro_image_end - ro_image)); ret =__arch_prepare_bpf_trampoline (&ctx, im, m, tlinks, func_addr, flags); -if (ret >0 &&validate_code (&ctx) <0 ) { +if (ret <0 ) + goto out; + +if (validate_code (&ctx) <0 ) { ret = -EINVAL ; goto out; }
Greg Kroah-Hartman
maintainerPATCH 528/563 LoongArch: BPF: Remove duplicated bpf_flush_icache()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hengqi Chen <[email protected]>
commit b0f50dc09bf008b2e581d5e6ad570d325725881c upstream.
The bpf_flush_icache() is called by bpf_arch_text_copy() already. So remove it. This has been done in arm64 and riscv.
--- arch/loongarch/net/bpf_jit.c | 1 - 1 file changed, 1 deletion(-)
arch/loongarch/net/bpf_jit.c +0 -1
@@ -1770,7 +1770,6 @@ int arch_prepare_bpf_trampoline(struct b goto out; } -bpf_flush_icache (ro_image, ro_image_end); out:kvfree (image);return ret <0 ? ret : size;
Greg Kroah-Hartman
maintainerPATCH 529/563 LoongArch: BPF: No text_poke() for kernel text
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hengqi Chen <[email protected]>
commit 3d770bd11b943066db11dba7be0b6f0d81cb5d50 upstream.
The current implementation of bpf_arch_text_poke() requires 5 nops at patch site which is not applicable for kernel/module functions. Because LoongArch reserves ONLY 2 nops at the function entry. With CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y, this can be done by ftrace instead.
See the following commit for details:
* commit b91e014f078e ("bpf: Make BPF trampoline use register_ftrace_direct() API")
* commit 9cdc3b6a299c ("LoongArch: ftrace: Add direct call support")
--- arch/loongarch/net/bpf_jit.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
arch/loongarch/net/bpf_jit.c +4 -2
@@ -1294,8 +1294,10 @@ int bpf_arch_text_poke(void *ip, enum bpu32 old_insns[LOONGARCH_LONG_JUMP_NINSNS ] = {[0 ...4 ] =INSN_NOP };u32 new_insns[LOONGARCH_LONG_JUMP_NINSNS ] = {[0 ...4 ] =INSN_NOP }; -if (!is_kernel_text ((unsigned long )ip) && - !is_bpf_text_address ((unsigned long )ip)) +/* Only poking bpf text is supported. Since kernel function entry +* is set up by ftrace, we rely on ftrace to poke kernel functions. +*/ +if (!is_bpf_text_address ((unsigned long )ip))return -ENOTSUPP ; ret =emit_jump_or_nops (old_addr, ip, old_insns, is_call);
Greg Kroah-Hartman
maintainerPATCH 530/563 LoongArch: BPF: Remove duplicated flags check
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hengqi Chen <[email protected]>
commit 909d3e3f51b1bc00f33a484ce0d41b42fed01965 upstream.
The check for (BPF_TRAMP_F_ORIG_STACK | BPF_TRAMP_F_SHARE_IPMODIFY) is duplicated in __arch_prepare_bpf_trampoline(). Remove it.
While at it, make sure stack_size and nargs are initialized once.
--- arch/loongarch/net/bpf_jit.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
arch/loongarch/net/bpf_jit.c +2 -7
@@ -1486,7 +1486,7 @@ static int __arch_prepare_bpf_trampoline void *func_addr, u32 flags) { int i, ret, save_ret; -int stack_size =0 , nargs =0 ; +int stack_size, nargs;int retval_off, args_off, nargs_off, ip_off, run_ctx_off, sreg_off, tcc_ptr_off;bool is_struct_ops = flags &BPF_TRAMP_F_INDIRECT ;void *orig_call = func_addr;
@@ -1495,9 +1495,6 @@ static int __arch_prepare_bpf_trampolinestruct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN ];u32 **branches =NULL ; -if (flags & (BPF_TRAMP_F_ORIG_STACK |BPF_TRAMP_F_SHARE_IPMODIFY )) -return -ENOTSUPP ; -/* * FP + 8 [ RA to parent func ] return address to parent * function
@@ -1537,10 +1534,8 @@ static int __arch_prepare_bpf_trampolineif (flags & (BPF_TRAMP_F_ORIG_STACK |BPF_TRAMP_F_SHARE_IPMODIFY ))return -ENOTSUPP ; - stack_size =0 ; -/* Room of trampoline frame to store return address and frame pointer */ - stack_size +=16 ; + stack_size =16 ; save_ret = flags & (BPF_TRAMP_F_CALL_ORIG |BPF_TRAMP_F_RET_FENTRY_RET );if (save_ret) {
Greg Kroah-Hartman
maintainerPATCH 531/563 LoongArch: BPF: Fix uninitialized symbol retval_off
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huacai Chen <[email protected]>
commit 7b6c2d172d023d344527d3cb4516d0d6b29f4919 upstream.
In __arch_prepare_bpf_trampoline(), retval_off is meaningful only when save_ret is not 0, so the current logic is correct. But it may cause a build warning:
arch/loongarch/net/bpf_jit.c:1547 __arch_prepare_bpf_trampoline() error: uninitialized symbol 'retval_off'.
So initialize retval_off unconditionally to fix it.
--- arch/loongarch/net/bpf_jit.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
arch/loongarch/net/bpf_jit.c +4 -5
@@ -1538,11 +1538,10 @@ static int __arch_prepare_bpf_trampoline stack_size =16 ; save_ret = flags & (BPF_TRAMP_F_CALL_ORIG |BPF_TRAMP_F_RET_FENTRY_RET ); -if (save_ret) { -/* Save BPF R0 and A0 */ - stack_size +=16 ; - retval_off = stack_size; - } +if (save_ret) + stack_size +=16 ;/* Save BPF R0 and A0 */ + + retval_off = stack_size;/* Room of trampoline frame to store args */ nargs = m->nr_args;
Greg Kroah-Hartman
maintainerPATCH 532/563 mm/ksm: fix flag-dropping behavior in ksm_madvise
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Acs <[email protected]>
commit f04aad36a07cc17b7a5d5b9a2d386ce6fae63e93 upstream.
syzkaller discovered the following crash: (kernel BUG)
[ 44.607039] ------------[ cut here ]------------ [ 44.607422] kernel BUG at mm/userfaultfd.c:2067! [ 44.608148] Oops: invalid opcode: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN NOPTI [ 44.608814] CPU: 1 UID: 0 PID: 2475 Comm: reproducer Not tainted 6.16.0-rc6 #1 PREEMPT(none) [ 44.609635] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 [ 44.610695] RIP: 0010:userfaultfd_release_all+0x3a8/0x460
<snip other registers, drop unreliable trace>
[ 44.617726] Call Trace: [ 44.617926] <TASK> [ 44.619284] userfaultfd_release+0xef/0x1b0 [ 44.620976] __fput+0x3f9/0xb60 [ 44.621240] fput_close_sync+0x110/0x210 [ 44.622222] __x64_sys_close+0x8f/0x120 [ 44.622530] do_syscall_64+0x5b/0x2f0 [ 44.622840] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 44.623244] RIP: 0033:0x7f365bb3f227
Kernel panics because it detects UFFD inconsistency during
userfaultfd_release_all(). Specifically, a VMA which has a valid pointer to vma->vm_userfaultfd_ctx, but no UFFD flags in vma->vm_flags.
The inconsistency is caused in ksm_madvise(): when user calls madvise() with MADV_UNMEARGEABLE on a VMA that is registered for UFFD in MINOR mode, it accidentally clears all flags stored in the upper 32 bits of vma->vm_flags.
Assuming x86_64 kernel build, unsigned long is 64-bit and unsigned int and int are 32-bit wide. This setup causes the following mishap during the &= ~VM_MERGEABLE assignment.
VM_MERGEABLE is a 32-bit constant of type unsigned int, 0x8000'0000. After ~ is applied, it becomes 0x7fff'ffff unsigned int, which is then promoted to unsigned long before the & operation. This promotion fills upper 32 bits with leading 0s, as we're doing unsigned conversion (and even for a signed conversion, this wouldn't help as the leading bit is 0). & operation thus ends up AND-ing vm_flags with 0x0000'0000'7fff'ffff instead of intended 0xffff'ffff'7fff'ffff and hence accidentally clears the upper 32-bits of its value.
Fix it by changing VM_MERGEABLE constant to unsigned long, using the BIT() macro.
Note: other VM_* flags are not affected: This only happens to the VM_MERGEABLE flag, as the other VM_* flags are all constants of type int and after ~ operation, they end up with leading 1 and are thus converted to unsigned long with leading 1s.
Note 2:
After commit 31defc3b01d9 ("userfaultfd: remove (VM_)BUG_ON()s"), this is no longer a kernel BUG, but a WARNING at the same place:
[ 45.595973] WARNING: CPU: 1 PID: 2474 at mm/userfaultfd.c:2067
but the root-cause (flag-drop) remains the same.
--- include/linux/mm.h | 2 +- rust/bindings/bindings_helper.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
include/linux/mm.h +1 -1
@@ -296,7 +296,7 @@ extern unsigned int kobjsize(const void#define VM_MIXEDMAP 0x10000000/* Can contain "struct page" and pure PFN pages */ #define VM_HUGEPAGE 0x20000000/* MADV_HUGEPAGE marked this vma */ #define VM_NOHUGEPAGE 0x40000000/* MADV_NOHUGEPAGE marked this vma */ -#define VM_MERGEABLE 0x80000000/* KSM may merge identical pages */ +#define VM_MERGEABLE BIT(31)/* KSM may merge identical pages */ #ifdef CONFIG_ARCH_USES_HIGH_VMA_FLAGS #define VM_HIGH_ARCH_BIT_0 32/* bit only usable on 64-bit architectures */
rust/bindings/bindings_helper.h +1 -0
@@ -99,3 +99,4 @@ const xa_mark_t RUST_CONST_HELPER_XA_PREconst gfp_t RUST_CONST_HELPER_XA_FLAGS_ALLOC =XA_FLAGS_ALLOC ;const gfp_t RUST_CONST_HELPER_XA_FLAGS_ALLOC1 =XA_FLAGS_ALLOC1 ; +const vm_flags_t RUST_CONST_HELPER_VM_MERGEABLE =VM_MERGEABLE ;
Greg Kroah-Hartman
maintainerPATCH 533/563 ksmbd: Fix race condition in RPC handle list access
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yunseong Kim <[email protected]>
commit 305853cce379407090a73b38c5de5ba748893aee upstream.
The 'sess->rpc_handle_list' XArray manages RPC handles within a ksmbd session. Access to this list is intended to be protected by 'sess->rpc_lock' (an rw_semaphore). However, the locking implementation was flawed, leading to potential race conditions.
In ksmbd_session_rpc_open(), the code incorrectly acquired only a read lock before calling xa_store() and xa_erase(). Since these operations modify the XArray structure, a write lock is required to ensure exclusive access and prevent data corruption from concurrent modifications.
Furthermore, ksmbd_session_rpc_method() accessed the list using xa_load() without holding any lock at all. This could lead to reading inconsistent data or a potential use-after-free if an entry is concurrently removed and the pointer is dereferenced.
Fix these issues by:
1. Using down_write() and up_write() in ksmbd_session_rpc_open() to ensure exclusive access during XArray modification, and ensuring the lock is correctly released on error paths.
2. Adding down_read() and up_read() in ksmbd_session_rpc_method() to safely protect the lookup.
--- fs/smb/server/mgmt/user_session.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-)
fs/smb/server/mgmt/user_session.c +17 -9
@@ -104,29 +104,32 @@ int ksmbd_session_rpc_open(struct ksmbd_if (!entry)return -ENOMEM ; -down_read (&sess->rpc_lock); entry->method = method; entry->id = id =ksmbd_ipc_id_alloc ();if (id <0 ) goto free_entry; + +down_write (&sess->rpc_lock); old =xa_store (&sess->rpc_handle_list, id, entry,KSMBD_DEFAULT_GFP ); -if (xa_is_err (old)) +if (xa_is_err (old)) { +up_write (&sess->rpc_lock); goto free_id; + } resp =ksmbd_rpc_open (sess, id); -if (!resp) - goto erase_xa; +if (!resp) { +xa_erase (&sess->rpc_handle_list, entry->id); +up_write (&sess->rpc_lock); + goto free_id; + } -up_read (&sess->rpc_lock); +up_write (&sess->rpc_lock);kvfree (resp);return id; -erase_xa: -xa_erase (&sess->rpc_handle_list, entry->id); free_id:ksmbd_rpc_id_free (entry->id); free_entry:kfree (entry); -up_read (&sess->rpc_lock);return -EINVAL ; }
@@ -144,9 +147,14 @@ void ksmbd_session_rpc_close(struct ksmbint ksmbd_session_rpc_method (struct ksmbd_session *sess,int id) {struct ksmbd_session_rpc *entry; +int method; +down_read (&sess->rpc_lock); entry =xa_load (&sess->rpc_handle_list, id); -return entry ? entry->method :0 ; + method = entry ? entry->method :0 ; +up_read (&sess->rpc_lock); + +return method; }void ksmbd_session_destroy (struct ksmbd_session *sess)
Greg Kroah-Hartman
maintainerPATCH 534/563 ksmbd: fix error code overwriting in smb2_get_info_filesystem()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matvey Kovalev <[email protected]>
commit 88daf2f448aad05a2e6df738d66fe8b0cf85cee0 upstream.
If client doesn't negotiate with SMB3.1.1 POSIX Extensions, then proper error code won't be returned due to overwriting.
Return error immediately.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- fs/smb/server/smb2pdu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/smb/server/smb2pdu.c +2 -1
@@ -5628,7 +5628,8 @@ static int smb2_get_info_filesystem(struif (!work->tcon->posix_extensions) {pr_err ("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n" ); - rc = -EOPNOTSUPP ; +path_put (&path); +return -EOPNOTSUPP ; }else { info = (struct filesystem_posix_info *)(rsp->Buffer); info->OptimalTransferSize =cpu_to_le32 (stfs.f_bsize);
Greg Kroah-Hartman
maintainerPATCH 535/563 ksmbd: add max ip connections parameter
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
commit d8b6dc9256762293048bf122fc11c4e612d0ef5d upstream.
This parameter set the maximum number of connections per ip address. The default is 8.
--- fs/smb/server/ksmbd_netlink.h | 5 +++-- fs/smb/server/server.h | 1 + fs/smb/server/transport_ipc.c | 3 +++ fs/smb/server/transport_tcp.c | 27 ++++++++++++++++----------- 4 files changed, 23 insertions(+), 13 deletions(-)
fs/smb/server/ksmbd_netlink.h +3 -2
@@ -112,10 +112,11 @@ struct ksmbd_startup_request {__u32 smbd_max_io_size;/* smbd read write size */ __u32 max_connections;/* Number of maximum simultaneous connections */ __s8 bind_interfaces_only; -__s8 reserved[503 ];/* Reserved room */ +__u32 max_ip_connections;/* Number of maximum connection per ip address */ +__s8 reserved[499 ];/* Reserved room */ __u32 ifc_list_sz;/* interfaces list size */ __s8 ____payload[]; -}; +} __packed;#define KSMBD_STARTUP_CONFIG_INTERFACES (s) ((s)->____payload)
fs/smb/server/server.h +1 -0
@@ -43,6 +43,7 @@ struct ksmbd_server_config {unsigned int auth_mechs;unsigned int max_connections;unsigned int max_inflight_req; +unsigned int max_ip_connections;char *conf[SERVER_CONF_WORK_GROUP +1 ];struct task_struct *dh_task;
fs/smb/server/transport_ipc.c +3 -0
@@ -335,6 +335,9 @@ static int ipc_server_config_on_startup(if (req->max_connections) server_conf.max_connections = req->max_connections; +if (req->max_ip_connections) + server_conf.max_ip_connections = req->max_ip_connections; + ret =ksmbd_set_netbios_name (req->netbios_name); ret |=ksmbd_set_server_string (req->server_string); ret |=ksmbd_set_work_group (req->work_group);
fs/smb/server/transport_tcp.c +16 -11
@@ -238,6 +238,7 @@ static int ksmbd_kthread_fn(void *p)struct interface *iface = (struct interface *)p;struct ksmbd_conn *conn;int ret; +unsigned int max_ip_conns;while (!kthread_should_stop ()) {mutex_lock (&iface->sock_release_lock);
@@ -255,34 +256,38 @@ static int ksmbd_kthread_fn(void *p)continue ; } +if (!server_conf.max_ip_connections) + goto skip_max_ip_conns_limit; +/* * Limits repeated connections from clients with the same IP. */ + max_ip_conns =0 ;down_read (&conn_list_lock); - list_for_each_entry(conn, &conn_list, conns_list) +list_for_each_entry (conn, &conn_list, conns_list) {#if IS_ENABLED (CONFIG_IPV6 )if (client_sk->sk->sk_family ==AF_INET6 ) {if (memcmp (&client_sk->sk->sk_v6_daddr, - &conn->inet6_addr,16 ) ==0 ) { - ret = -EAGAIN ; -break ; - } + &conn->inet6_addr,16 ) ==0 ) + max_ip_conns++; }else if (inet_sk (client_sk->sk)->inet_daddr == - conn->inet_addr) { - ret = -EAGAIN ; -break ; - } + conn->inet_addr) + max_ip_conns++;#else if (inet_sk (client_sk->sk)->inet_daddr == - conn->inet_addr) { + conn->inet_addr) + max_ip_conns++; +#endif +if (server_conf.max_ip_connections <= max_ip_conns) { ret = -EAGAIN ;break ; } -#endif + }up_read (&conn_list_lock);if (ret == -EAGAIN )continue ; +skip_max_ip_conns_limit:if (server_conf.max_connections &&atomic_inc_return (&active_num_conn) >= server_conf.max_connections) { pr_info_ratelimited("Limit the maximum number of connections(%u)\n",
Greg Kroah-Hartman
maintainerPATCH 536/563 ext4: fix potential null deref in ext4_mb_init()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit 3c3fac6bc0a9c00dbe65d8dc0d3a282afe4d3188 upstream.
In ext4_mb_init(), ext4_mb_avg_fragment_size_destroy() may be called when sbi->s_mb_avg_fragment_size remains uninitialized (e.g., if groupinfo slab cache allocation fails). Since ext4_mb_avg_fragment_size_destroy() lacks null pointer checking, this leads to a null pointer dereference.
==================================================================
EXT4-fs: no memory for groupinfo slab cache
BUG: kernel NULL pointer dereference, address: 0000000000000000 PGD 0 P4D 0 Oops: Oops: 0002 [#1] SMP PTI CPU:2 UID: 0 PID: 87 Comm:mount Not tainted 6.17.0-rc2 #1134 PREEMPT(none) RIP: 0010:_raw_spin_lock_irqsave+0x1b/0x40 Call Trace: <TASK> xa_destroy+0x61/0x130 ext4_mb_init+0x483/0x540 __ext4_fill_super+0x116d/0x17b0 ext4_fill_super+0xd3/0x280 get_tree_bdev_flags+0x132/0x1d0 vfs_get_tree+0x29/0xd0 do_new_mount+0x197/0x300 __x64_sys_mount+0x116/0x150 do_syscall_64+0x50/0x1c0 entry_SYSCALL_64_after_hwframe+0x76/0x7e ==================================================================
Therefore, add necessary null check to ext4_mb_avg_fragment_size_destroy() to prevent this issue. The same fix is also applied to ext4_mb_largest_free_orders_destroy().
--- fs/ext4/mballoc.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
fs/ext4/mballoc.c +10 -0
@@ -3655,16 +3655,26 @@ static void ext4_discard_work(struct worstatic inline void ext4_mb_avg_fragment_size_destroy (struct ext4_sb_info *sbi) { +if (!sbi->s_mb_avg_fragment_size) +return ; +for (int i =0 ; i <MB_NUM_ORDERS (sbi->s_sb); i++)xa_destroy (&sbi->s_mb_avg_fragment_size[i]); +kfree (sbi->s_mb_avg_fragment_size); + sbi->s_mb_avg_fragment_size =NULL ; }static inline void ext4_mb_largest_free_orders_destroy (struct ext4_sb_info *sbi) { +if (!sbi->s_mb_largest_free_orders) +return ; +for (int i =0 ; i <MB_NUM_ORDERS (sbi->s_sb); i++)xa_destroy (&sbi->s_mb_largest_free_orders[i]); +kfree (sbi->s_mb_largest_free_orders); + sbi->s_mb_largest_free_orders =NULL ; }int ext4_mb_init (struct super_block *sb)
Greg Kroah-Hartman
maintainerPATCH 537/563 ext4: fix checks for orphan inodes
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <[email protected]>
commit acf943e9768ec9d9be80982ca0ebc4bfd6b7631e upstream.
When orphan file feature is enabled, inode can be tracked as orphan either in the standard orphan list or in the orphan file. The first can be tested by checking ei->i_orphan list head, the second is recorded by EXT4_STATE_ORPHAN_FILE inode state flag. There are several places where we want to check whether inode is tracked as orphan and only some of them properly check for both possibilities. Luckily the consequences are mostly minor, the worst that can happen is that we track an inode as orphan although we don't need to and e2fsck then complains (resulting in occasional ext4/307 xfstest failures). Fix the problem by introducing a helper for checking whether an inode is tracked as orphan and use it in appropriate places.
Message-ID: <[email protected]>
--- fs/ext4/ext4.h | 10 ++++++++++ fs/ext4/file.c | 2 +- fs/ext4/inode.c | 2 +- fs/ext4/orphan.c | 6 +----- fs/ext4/super.c | 4 ++-- 5 files changed, 15 insertions(+), 9 deletions(-)
fs/ext4/ext4.h +10 -0
@@ -1982,6 +1982,16 @@ static inline bool ext4_verity_in_progre#define NEXT_ORPHAN (inode) EXT4_I(inode)->i_dtime/* +* Check whether the inode is tracked as orphan (either in orphan file or +* orphan list). +*/ +static inline bool ext4_inode_orphan_tracked (struct inode *inode) +{ +return ext4_test_inode_state (inode,EXT4_STATE_ORPHAN_FILE ) || + !list_empty (&EXT4_I (inode)->i_orphan); +} + +/* * Codes for operating systems */ #define EXT4_OS_LINUX 0
fs/ext4/file.c +1 -1
@@ -354,7 +354,7 @@ static void ext4_inode_extension_cleanup* to cleanup the orphan list in ext4_handle_inode_extension(). Do it * now. */ -if (!list_empty (&EXT4_I (inode)->i_orphan) && inode->i_nlink) { +if (ext4_inode_orphan_tracked (inode) && inode->i_nlink) {handle_t *handle =ext4_journal_start (inode,EXT4_HT_INODE ,2 );if (IS_ERR (handle)) {
fs/ext4/inode.c +1 -1
@@ -4748,7 +4748,7 @@ static int ext4_fill_raw_inode(struct in* old inodes get re-used with the upper 16 bits of the * uid/gid intact. */ -if (ei->i_dtime &&list_empty (&ei->i_orphan)) { +if (ei->i_dtime && !ext4_inode_orphan_tracked (inode)) { raw_inode->i_uid_high =0 ; raw_inode->i_gid_high =0 ; }else {
fs/ext4/orphan.c +1 -5
@@ -109,11 +109,7 @@ int ext4_orphan_add(handle_t *handle, stWARN_ON_ONCE (!(inode->i_state & (I_NEW |I_FREEING )) && !inode_is_locked (inode)); -/* -* Inode orphaned in orphan file or in orphan list? -*/ -if (ext4_test_inode_state (inode,EXT4_STATE_ORPHAN_FILE ) || - !list_empty (&EXT4_I (inode)->i_orphan)) +if (ext4_inode_orphan_tracked (inode))return 0 ;/*
fs/ext4/super.c +2 -2
@@ -1438,9 +1438,9 @@ static void ext4_free_in_core_inode(strustatic void ext4_destroy_inode (struct inode *inode) { -if (!list_empty (&(EXT4_I (inode)->i_orphan))) { +if (ext4_inode_orphan_tracked (inode)) {ext4_msg (inode->i_sb,KERN_ERR , -"Inode %lu (%p): orphan list check failed!" , +"Inode %lu (%p): inode tracked as orphan!" , inode->i_ino,EXT4_I (inode)); print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 4, EXT4_I(inode), sizeof(struct ext4_inode_info),
Greg Kroah-Hartman
maintainerPATCH 538/563 KVM: SVM: Skip fastpath emulation on VM-Exit if next RIP isnt valid
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit 0910dd7c9ad45a2605c45fd2bf3d1bcac087687c upstream.
Skip the WRMSR and HLT fastpaths in SVM's VM-Exit handler if the next RIP isn't valid, e.g. because KVM is running with nrips=false. SVM must decode and emulate to skip the instruction if the CPU doesn't provide the next RIP, and getting the instruction bytes to decode requires reading guest memory. Reading guest memory through the emulator can fault, i.e. can sleep, which is disallowed since the fastpath handlers run with IRQs disabled.
BUG: sleeping function called from invalid context at ./include/linux/uaccess.h:106 in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 32611, name: qemu preempt_count: 1, expected: 0 INFO: lockdep is turned off. irq event stamp: 30580 hardirqs last enabled at (30579): [<ffffffffc08b2527>] vcpu_run+0x1787/0x1db0 [kvm] hardirqs last disabled at (30580): [<ffffffffb4f62e32>] __schedule+0x1e2/0xed0 softirqs last enabled at (30570): [<ffffffffb4247a64>] fpu_swap_kvm_fpstate+0x44/0x210 softirqs last disabled at (30568): [<ffffffffb4247a64>] fpu_swap_kvm_fpstate+0x44/0x210 CPU: 298 UID: 0 PID: 32611 Comm: qemu Tainted: G U 6.16.0-smp--e6c618b51cfe-sleep #782 NONE Tainted: [U]=USER Hardware name: Google Astoria-Turin/astoria, BIOS 0.20241223.2-0 01/17/2025 Call Trace: <TASK> dump_stack_lvl+0x7d/0xb0 __might_resched+0x271/0x290 __might_fault+0x28/0x80 kvm_vcpu_read_guest_page+0x8d/0xc0 [kvm] kvm_fetch_guest_virt+0x92/0xc0 [kvm] __do_insn_fetch_bytes+0xf3/0x1e0 [kvm] x86_decode_insn+0xd1/0x1010 [kvm] x86_emulate_instruction+0x105/0x810 [kvm] __svm_skip_emulated_instruction+0xc4/0x140 [kvm_amd] handle_fastpath_invd+0xc4/0x1a0 [kvm] vcpu_run+0x11a1/0x1db0 [kvm] kvm_arch_vcpu_ioctl_run+0x5cc/0x730 [kvm] kvm_vcpu_ioctl+0x578/0x6a0 [kvm] __se_sys_ioctl+0x6d/0xb0 do_syscall_64+0x8a/0x2c0 entry_SYSCALL_64_after_hwframe+0x4b/0x53 RIP: 0033:0x7f479d57a94b </TASK>
Note, this is essentially a reapply of commit 5c30e8101e8d ("KVM: SVM:
Skip WRMSR fastpath on VM-Exit if next RIP isn't valid"), but with different justification (KVM now grabs SRCU when skipping the instruction for other reasons).
--- arch/x86/kvm/svm/svm.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
arch/x86/kvm/svm/svm.c +10 -2
@@ -4180,13 +4180,21 @@ static int svm_vcpu_pre_run(struct kvm_vstatic fastpath_t svm_exit_handlers_fastpath (struct kvm_vcpu *vcpu) {struct vcpu_svm *svm =to_svm (vcpu); +struct vmcb_control_area *control = &svm->vmcb->control; + +/* +* Next RIP must be provided as IRQs are disabled, and accessing guest +* memory to decode the instruction might fault, i.e. might sleep. +*/ +if (!nrips || !control->next_rip) +return EXIT_FASTPATH_NONE ;if (is_guest_mode (vcpu))return EXIT_FASTPATH_NONE ; -switch (svm->vmcb->control.exit_code) { +switch (control->exit_code) {case SVM_EXIT_MSR : -if (!svm->vmcb->control.exit_info_1) +if (!control->exit_info_1)break ;return handle_fastpath_set_msr_irqoff (vcpu);case SVM_EXIT_HLT :
Greg Kroah-Hartman
maintainerPATCH 539/563 fbdev: simplefb: Fix use after free in simplefb_detach_genpds()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Janne Grunau <[email protected]>
commit da1bb9135213744e7ec398826c8f2e843de4fb94 upstream.
The pm_domain cleanup can not be devres managed as it uses struct simplefb_par which is allocated within struct fb_info by framebuffer_alloc(). This allocation is explicitly freed by unregister_framebuffer() in simplefb_remove().
Devres managed cleanup runs after the device remove call and thus can no longer access struct simplefb_par.
Call simplefb_detach_genpds() explicitly from simplefb_destroy() like the cleanup functions for clocks and regulators.
Fixes an use after free on M2 Mac mini during aperture_remove_conflicting_devices() using the downstream asahi kernel with Debian's kernel config. For unknown reasons this started to consistently dereference an invalid pointer in v6.16.3 based kernels.
[ 6.736134] BUG: KASAN: slab-use-after-free in simplefb_detach_genpds+0x58/0x220 [ 6.743545] Read of size 4 at addr ffff8000304743f0 by task (udev-worker)/227 [ 6.750697] [ 6.752182] CPU: 6 UID: 0 PID: 227 Comm: (udev-worker) Tainted: G S 6.16.3-asahi+ #16 PREEMPTLAZY [ 6.752186] Tainted: [S]=CPU_OUT_OF_SPEC [ 6.752187] Hardware name: Apple Mac mini (M2, 2023) (DT) [ 6.752189] Call trace: [ 6.752190] show_stack+0x34/0x98 (C) [ 6.752194] dump_stack_lvl+0x60/0x80 [ 6.752197] print_report+0x17c/0x4d8 [ 6.752201] kasan_report+0xb4/0x100 [ 6.752206] __asan_report_load4_noabort+0x20/0x30 [ 6.752209] simplefb_detach_genpds+0x58/0x220 [ 6.752213] devm_action_release+0x50/0x98 [ 6.752216] release_nodes+0xd0/0x2c8 [ 6.752219] devres_release_all+0xfc/0x178 [ 6.752221] device_unbind_cleanup+0x28/0x168 [ 6.752224] device_release_driver_internal+0x34c/0x470 [ 6.752228] device_release_driver+0x20/0x38 [ 6.752231] bus_remove_device+0x1b0/0x380 [ 6.752234] device_del+0x314/0x820 [ 6.752238] platform_device_del+0x3c/0x1e8 [ 6.752242] platform_device_unregister+0x20/0x50 [ 6.752246] aperture_detach_platform_device+0x1c/0x30 [ 6.752250] aperture_detach_devices+0x16c/0x290 [ 6.752253] aperture_remove_conflicting_devices+0x34/0x50 ... [ 6.752343] [ 6.967409] Allocated by task 62: [ 6.970724] kasan_save_stack+0x3c/0x70 [ 6.974560] kasan_save_track+0x20/0x40 [ 6.978397] kasan_save_alloc_info+0x40/0x58 [ 6.982670] __kasan_kmalloc+0xd4/0xd8 [ 6.986420] __kmalloc_noprof+0x194/0x540 [ 6.990432] framebuffer_alloc+0xc8/0x130 [ 6.994444] simplefb_probe+0x258/0x2378 ... [ 7.054356] [ 7.055838] Freed by task 227: [ 7.058891] kasan_save_stack+0x3c/0x70 [ 7.062727] kasan_save_track+0x20/0x40 [ 7.066565] kasan_save_free_info+0x4c/0x80 [ 7.070751] __kasan_slab_free+0x6c/0xa0 [ 7.074675] kfree+0x10c/0x380 [ 7.077727] framebuffer_release+0x5c/0x90 [ 7.081826] simplefb_destroy+0x1b4/0x2c0 [ 7.085837] put_fb_info+0x98/0x100 [ 7.089326] unregister_framebuffer+0x178/0x320 [ 7.093861] simplefb_remove+0x3c/0x60 [ 7.097611] platform_remove+0x60/0x98 [ 7.101361] device_remove+0xb8/0x160 [ 7.105024] device_release_driver_internal+0x2fc/0x470 [ 7.110256] device_release_driver+0x20/0x38 [ 7.114529] bus_remove_device+0x1b0/0x380 [ 7.118628] device_del+0x314/0x820 [ 7.122116] platform_device_del+0x3c/0x1e8 [ 7.126302] platform_device_unregister+0x20/0x50 [ 7.131012] aperture_detach_platform_device+0x1c/0x30 [ 7.136157] aperture_detach_devices+0x16c/0x290 [ 7.140779] aperture_remove_conflicting_devices+0x34/0x50
...
--- drivers/video/fbdev/simplefb.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-)
drivers/video/fbdev/simplefb.c +23 -8
@@ -93,6 +93,7 @@ struct simplefb_par {static void simplefb_clocks_destroy (struct simplefb_par *par);static void simplefb_regulators_destroy (struct simplefb_par *par); +static void simplefb_detach_genpds (void *res);/* * fb_ops.fb_destroy is called by the last put_fb_info() call at the end
@@ -105,6 +106,7 @@ static void simplefb_destroy(struct fb_isimplefb_regulators_destroy (info->par);simplefb_clocks_destroy (info->par); +simplefb_detach_genpds (info->par);if (info->screen_base)iounmap (info->screen_base);
@@ -445,13 +447,14 @@ static void simplefb_detach_genpds(voidif (!IS_ERR_OR_NULL (par->genpds[i]))dev_pm_domain_detach (par->genpds[i], true); } + par->num_genpds =0 ; }static int simplefb_attach_genpds (struct simplefb_par *par,struct platform_device *pdev) {struct device *dev = &pdev->dev; -unsigned int i; +unsigned int i, num_genpds;int err; err = of_count_phandle_with_args(dev->of_node, "power-domains",
@@ -465,26 +468,35 @@ static int simplefb_attach_genpds(structreturn err; } - par->num_genpds = err; + num_genpds = err;/* * Single power-domain devices are handled by the driver core, so * nothing to do here. */ -if (par->num_genpds <=1 ) +if (num_genpds <=1 ) { + par->num_genpds = num_genpds;return 0 ; + } - par->genpds =devm_kcalloc (dev, par->num_genpds,sizeof (*par->genpds), + par->genpds =devm_kcalloc (dev, num_genpds,sizeof (*par->genpds),GFP_KERNEL );if (!par->genpds)return -ENOMEM ; - par->genpd_links =devm_kcalloc (dev, par->num_genpds, + par->genpd_links =devm_kcalloc (dev, num_genpds,sizeof (*par->genpd_links),GFP_KERNEL );if (!par->genpd_links)return -ENOMEM ; +/* +* Set par->num_genpds only after genpds and genpd_links are allocated +* to exit early from simplefb_detach_genpds() without full +* initialisation. +*/ + par->num_genpds = num_genpds; +for (i =0 ; i < par->num_genpds; i++) { par->genpds[i] =dev_pm_domain_attach_by_id (dev, i);if (IS_ERR (par->genpds[i])) {
@@ -506,9 +518,10 @@ static int simplefb_attach_genpds(struct dev_warn(dev, "failed to link power-domain %u\n", i); } -return devm_add_action_or_reset (dev, simplefb_detach_genpds, par); +return 0 ; }#else +static void simplefb_detach_genpds (void *res) { }static int simplefb_attach_genpds (struct simplefb_par *par,struct platform_device *pdev) {
@@ -622,18 +635,20 @@ static int simplefb_probe(struct platfor ret =devm_aperture_acquire_for_platform_device (pdev, par->base, par->size);if (ret) {dev_err (&pdev->dev,"Unable to acquire aperture: %d\n" , ret); - goto error_regulators; + goto error_genpds; } ret =register_framebuffer (info);if (ret <0 ) {dev_err (&pdev->dev,"Unable to register simplefb: %d\n" , ret); - goto error_regulators; + goto error_genpds; }dev_info (&pdev->dev,"fb%d: simplefb registered!\n" , info->node);return 0 ; +error_genpds: +simplefb_detach_genpds (par); error_regulators:simplefb_regulators_destroy (par); error_clocks:
Greg Kroah-Hartman
maintainerPATCH 540/563 mm: hugetlb: avoid soft lockup when mprotect to large memory area
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Shi <[email protected]>
commit f52ce0ea90c83a28904c7cc203a70e6434adfecb upstream.
When calling mprotect() to a large hugetlb memory area in our customer's workload (~300GB hugetlb memory), soft lockup was observed:
watchdog: BUG: soft lockup - CPU#98 stuck for 23s! [t2_new_sysv:126916] CPU: 98 PID: 126916 Comm: t2_new_sysv Kdump: loaded Not tainted 6.17-rc7 Hardware name: GIGACOMPUTING R2A3-T40-AAV1/Jefferson CIO, BIOS 5.4.4.1 07/15/2025
pstate: 20400009 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : mte_clear_page_tags+0x14/0x24
lr : mte_sync_tags+0x1c0/0x240
sp : ffff80003150bb80
x29: ffff80003150bb80 x28: ffff00739e9705a8 x27: 0000ffd2d6a00000
x26: 0000ff8e4bc00000 x25: 00e80046cde00f45 x24: 0000000000022458
x23: 0000000000000000 x22: 0000000000000004 x21: 000000011b380000
x20: ffff000000000000 x19: 000000011b379f40 x18: 0000000000000000
x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000
x11: 0000000000000000 x10: 0000000000000000 x9 : ffffc875e0aa5e2c x8 : 0000000000000000 x7 : 0000000000000000 x6 : 0000000000000000 x5 : fffffc01ce7a5c00 x4 : 00000000046cde00 x3 : fffffc0000000000 x2 : 0000000000000004 x1 : 0000000000000040 x0 : ffff0046cde7c000
Call trace: mte_clear_page_tags+0x14/0x24 set_huge_pte_at+0x25c/0x280 hugetlb_change_protection+0x220/0x430 change_protection+0x5c/0x8c mprotect_fixup+0x10c/0x294 do_mprotect_pkey.constprop.0+0x2e0/0x3d4 __arm64_sys_mprotect+0x24/0x44 invoke_syscall+0x50/0x160 el0_svc_common+0x48/0x144 do_el0_svc+0x30/0xe0 el0_svc+0x30/0xf0 el0t_64_sync_handler+0xc4/0x148 el0t_64_sync+0x1a4/0x1a8
Soft lockup is not triggered with THP or base page because there is cond_resched() called for each PMD size.
Although the soft lockup was triggered by MTE, it should be not MTE specific. The other processing which takes long time in the loop may trigger soft lockup too.
So add cond_resched() for hugetlb to avoid soft lockup.
--- mm/hugetlb.c | 2 ++ 1 file changed, 2 insertions(+)
mm/hugetlb.c +2 -0
@@ -7203,6 +7203,8 @@ long hugetlb_change_protection(struct vm psize); }spin_unlock (ptl); + +cond_resched (); }/* * Must flush TLB before releasing i_mmap_rwsem: x86's huge_pmd_unshare
Greg Kroah-Hartman
maintainerPATCH 541/563 selftests/mm: skip soft-dirty tests when CONFIG_MEM_SOFT_DIRTY is disabled
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lance Yang <[email protected]>
commit 0389c305ef56cbadca4cbef44affc0ec3213ed30 upstream.
The madv_populate and soft-dirty kselftests currently fail on systems where CONFIG_MEM_SOFT_DIRTY is disabled.
Introduce a new helper softdirty_supported() into vm_util.c/h to ensure tests are properly skipped when the feature is not enabled.
--- tools/testing/selftests/mm/madv_populate.c | 21 ++------------------- tools/testing/selftests/mm/soft-dirty.c | 5 ++++- tools/testing/selftests/mm/vm_util.c | 17 +++++++++++++++++ tools/testing/selftests/mm/vm_util.h | 1 + 4 files changed, 24 insertions(+), 20 deletions(-)
tools/testing/selftests/mm/madv_populate.c +2 -19
@@ -264,23 +264,6 @@ static void test_softdirty(void)munmap (addr,SIZE ); } -static int system_has_softdirty (void ) -{ -/* -* There is no way to check if the kernel supports soft-dirty, other -* than by writing to a page and seeing if the bit was set. But the -* tests are intended to check that the bit gets set when it should, so -* doing that check would turn a potentially legitimate fail into a -* skip. Fortunately, we know for sure that arm64 does not support -* soft-dirty. So for now, let's just use the arch as a corse guide. -*/ -#if defined(__aarch64__) -return 0 ; -#else -return 1 ; -#endif -} -int main (int argc,char **argv) {int nr_tests =16 ;
@@ -288,7 +271,7 @@ int main(int argc, char **argv) pagesize =getpagesize (); -if (system_has_softdirty ()) +if (softdirty_supported ()) nr_tests +=5 ;ksft_print_header ();
@@ -300,7 +283,7 @@ int main(int argc, char **argv)test_holes ();test_populate_read ();test_populate_write (); -if (system_has_softdirty ()) +if (softdirty_supported ())test_softdirty (); err =ksft_get_fail_cnt ();
tools/testing/selftests/mm/soft-dirty.c +4 -1
@@ -200,8 +200,11 @@ int main(int argc, char **argv)int pagesize;ksft_print_header (); -ksft_set_plan (15 ); +if (!softdirty_supported ()) +ksft_exit_skip ("soft-dirty is not support\n" ); + +ksft_set_plan (15 ); pagemap_fd =open (PAGEMAP_FILE_PATH ,O_RDONLY );if (pagemap_fd <0 )ksft_exit_fail_msg ("Failed to open %s\n" ,PAGEMAP_FILE_PATH );
tools/testing/selftests/mm/vm_util.c +17 -0
@@ -426,6 +426,23 @@ bool check_vmflag_io(void *addr) } } +bool softdirty_supported (void ) +{ +char *addr; +bool supported = false; +const size_t pagesize =getpagesize (); + +/* New mappings are expected to be marked with VM_SOFTDIRTY (sd). */ + addr =mmap (0 , pagesize,PROT_READ |PROT_WRITE , +MAP_ANONYMOUS |MAP_PRIVATE ,0 ,0 ); +if (!addr) +ksft_exit_fail_msg ("mmap failed\n" ); + + supported =check_vmflag (addr,"sd" ); +munmap (addr, pagesize); +return supported; +} +/* * Open an fd at /proc/$pid/maps and configure procmap_out ready for * PROCMAP_QUERY query. Returns 0 on success, or an error code otherwise.
tools/testing/selftests/mm/vm_util.h +1 -0
@@ -99,6 +99,7 @@ bool find_vma_procmap(struct procmap_fdint close_procmap (struct procmap_fd *procmap);int write_sysfs (const char *file_path,unsigned long val);int read_sysfs (const char *file_path,unsigned long *val); +bool softdirty_supported (void );static inline int open_self_procmap (struct procmap_fd *procmap_out) {
Greg Kroah-Hartman
maintainerPATCH 542/563 nvdimm: ndtest: Return -ENOMEM if devm_kcalloc() fails in ndtest_probe()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <[email protected]>
commit a9e6aa994917ee602798bbb03180a194b37865bb upstream.
devm_kcalloc() may fail. ndtest_probe() allocates three DMA address arrays (dcr_dma, label_dma, dimm_dma) and later unconditionally uses them in ndtest_nvdimm_init(), which can lead to a NULL pointer dereference under low-memory conditions.
Check all three allocations and return -ENOMEM if any allocation fails, jumping to the common error path. Do not emit an extra error message since the allocator already warns on allocation failure.
--- tools/testing/nvdimm/test/ndtest.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
tools/testing/nvdimm/test/ndtest.c +12 -1
@@ -850,11 +850,22 @@ static int ndtest_probe(struct platform_ p->dcr_dma =devm_kcalloc (&p->pdev.dev,NUM_DCR ,sizeof (dma_addr_t),GFP_KERNEL ); +if (!p->dcr_dma) { + rc = -ENOMEM ; + goto err; + } p->label_dma =devm_kcalloc (&p->pdev.dev,NUM_DCR ,sizeof (dma_addr_t),GFP_KERNEL ); +if (!p->label_dma) { + rc = -ENOMEM ; + goto err; + } p->dimm_dma =devm_kcalloc (&p->pdev.dev,NUM_DCR ,sizeof (dma_addr_t),GFP_KERNEL ); - +if (!p->dimm_dma) { + rc = -ENOMEM ; + goto err; + } rc =ndtest_nvdimm_init (p);if (rc) goto err;
Greg Kroah-Hartman
maintainerPATCH 543/563 misc: fastrpc: Save actual DMA size in fastrpc_map structure
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ling Xu <[email protected]>
commit 8b5b456222fd604079b5cf2af1f25ad690f54a25 upstream.
For user passed fd buffer, map is created using DMA calls. The map related information is stored in fastrpc_map structure. The actual DMA size is not stored in the structure. Store the actual size of buffer and check it against the user passed size.
--- drivers/misc/fastrpc.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-)
drivers/misc/fastrpc.c +18 -9
@@ -323,11 +323,11 @@ static void fastrpc_free_map(struct kref perm.vmid =QCOM_SCM_VMID_HLOS ; perm.perm =QCOM_SCM_PERM_RWX ; - err =qcom_scm_assign_mem (map->phys, map->size, + err =qcom_scm_assign_mem (map->phys, map->len, &src_perms, &perm,1 );if (err) {dev_err (map->fl->sctx->dev,"Failed to assign memory phys 0x%llx size 0x%llx err %d\n" , - map->phys, map->size, err); + map->phys, map->len, err);return ; } }
@@ -758,7 +758,8 @@ static int fastrpc_map_create(struct fasstruct fastrpc_session_ctx *sess = fl->sctx;struct fastrpc_map *map =NULL ;struct sg_table *table; -int err =0 ; +struct scatterlist *sgl =NULL ; +int err =0 , sgl_index =0 ;if (!fastrpc_map_lookup (fl, fd, ppmap, true))return 0 ;
@@ -798,7 +799,15 @@ static int fastrpc_map_create(struct fas map->phys =sg_dma_address (map->table->sgl); map->phys += ((u64 )fl->sctx->sid <<32 ); } - map->size = len; +for_each_sg (map->table->sgl, sgl, map->table->nents, + sgl_index) + map->size +=sg_dma_len (sgl); +if (len > map->size) { +dev_dbg (sess->dev,"Bad size passed len 0x%llx map size 0x%llx\n" , + len, map->size); + err = -EINVAL ; + goto map_err; + } map->va =sg_virt (map->table->sgl); map->len = len;
@@ -815,10 +824,10 @@ static int fastrpc_map_create(struct fas dst_perms[1 ].vmid = fl->cctx->vmperms[0 ].vmid; dst_perms[1 ].perm =QCOM_SCM_PERM_RWX ; map->attr = attr; - err =qcom_scm_assign_mem (map->phys, (u64 )map->size, &src_perms, dst_perms,2 ); + err =qcom_scm_assign_mem (map->phys, (u64 )map->len, &src_perms, dst_perms,2 );if (err) {dev_err (sess->dev,"Failed to assign memory with phys 0x%llx size 0x%llx err %d\n" , - map->phys, map->size, err); + map->phys, map->len, err); goto map_err; } }
@@ -2046,7 +2055,7 @@ static int fastrpc_req_mem_map(struct fa args[0 ].length =sizeof (req_msg); pages.addr = map->phys; - pages.size = map->size; + pages.size = map->len; args[1 ].ptr = (u64) (uintptr_t) &pages; args[1 ].length =sizeof (pages);
@@ -2061,7 +2070,7 @@ static int fastrpc_req_mem_map(struct fa err =fastrpc_internal_invoke (fl, true,FASTRPC_INIT_HANDLE , sc, &args[0 ]);if (err) {dev_err (dev,"mem mmap error, fd %d, vaddr %llx, size %lld\n" , - req.fd, req.vaddrin, map->size); + req.fd, req.vaddrin, map->len); goto err_invoke; }
@@ -2074,7 +2083,7 @@ static int fastrpc_req_mem_map(struct faif (copy_to_user ((void __user *)argp, &req,sizeof (req))) {/* unmap the memory and release the buffer */ req_unmap.vaddr = (uintptr_t ) rsp_msg.vaddr; - req_unmap.length = map->size; + req_unmap.length = map->len;fastrpc_req_mem_unmap_impl (fl, &req_unmap);return -EFAULT ; }
Greg Kroah-Hartman
maintainerPATCH 544/563 misc: fastrpc: Fix fastrpc_map_lookup operation
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ling Xu <[email protected]>
commit 9031626ade38b092b72638dfe0c6ffce8d8acd43 upstream.
Fastrpc driver creates maps for user allocated fd buffers. Before creating a new map, the map list is checked for any already existing maps using map fd. Checking with just map fd is not sufficient as the user can pass offsetted buffer with less size when the map is created and then a larger size the next time which could result in memory issues. Check for dma_buf object also when looking up for the map.
--- drivers/misc/fastrpc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/misc/fastrpc.c +6 -1
@@ -367,11 +367,16 @@ static int fastrpc_map_lookup(struct fas {struct fastrpc_session_ctx *sess = fl->sctx;struct fastrpc_map *map =NULL ; +struct dma_buf *buf;int ret = -ENOENT ; + buf =dma_buf_get (fd); +if (IS_ERR (buf)) +return PTR_ERR (buf); +spin_lock (&fl->lock);list_for_each_entry (map, &fl->maps, node) { -if (map->fd != fd) +if (map->fd != fd || map->buf != buf)continue ;if (take_ref) {
Greg Kroah-Hartman
maintainerPATCH 545/563 misc: fastrpc: fix possible map leak in fastrpc_put_args
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ling Xu <[email protected]>
commit da1ba64176e0138f2bfa96f9e43e8c3640d01e1e upstream.
copy_to_user() failure would cause an early return without cleaning up the fdlist, which has been updated by the DSP. This could lead to map leak. Fix this by redirecting to a cleanup path on failure, ensuring that all mapped buffers are properly released before returning.
--- drivers/misc/fastrpc.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
drivers/misc/fastrpc.c +7 -3
@@ -1085,6 +1085,7 @@ static int fastrpc_put_args(struct fastrstruct fastrpc_phy_page *pages;u64 *fdlist;int i, inbufs, outbufs, handles; +int ret =0 ; inbufs =REMOTE_SCALARS_INBUFS (ctx->sc); outbufs =REMOTE_SCALARS_OUTBUFS (ctx->sc);
@@ -1100,14 +1101,17 @@ static int fastrpc_put_args(struct fastru64 len = rpra[i].buf.len;if (!kernel) { -if (copy_to_user ((void __user *)dst, src, len)) -return -EFAULT ; +if (copy_to_user ((void __user *)dst, src, len)) { + ret = -EFAULT ; + goto cleanup_fdlist; + } }else {memcpy (dst, src, len); } } } +cleanup_fdlist:/* Clean up fdlist which is updated by DSP */ for (i =0 ; i <FASTRPC_MAX_FDLIST ; i++) {if (!fdlist[i])
@@ -1116,7 +1120,7 @@ static int fastrpc_put_args(struct fastrfastrpc_map_put (mmap); } -return 0 ; +return ret; } static int fastrpc_invoke_send(struct fastrpc_session_ctx *sctx,
Greg Kroah-Hartman
maintainerPATCH 546/563 misc: fastrpc: Skip reference for DMA handles
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ling Xu <[email protected]>
commit 10df039834f84a297c72ec962c0f9b7c8c5ca31a upstream.
If multiple dma handles are passed with same fd over a remote call the kernel driver takes a reference and expects that put for the map will be called as many times to free the map. But DSP only updates the fd one time in the fd list when the DSP refcount goes to zero and hence kernel make put call only once for the fd. This can cause SMMU fault issue as the same fd can be used in future for some other call.
--- drivers/misc/fastrpc.c | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-)
drivers/misc/fastrpc.c +27 -18
@@ -363,9 +363,8 @@ static int fastrpc_map_get(struct fastrpstatic int fastrpc_map_lookup (struct fastrpc_user *fl,int fd, -struct fastrpc_map **ppmap,bool take_ref) +struct fastrpc_map **ppmap) { -struct fastrpc_session_ctx *sess = fl->sctx;struct fastrpc_map *map =NULL ;struct dma_buf *buf;int ret = -ENOENT ;
@@ -379,15 +378,6 @@ static int fastrpc_map_lookup(struct fasif (map->fd != fd || map->buf != buf)continue ; -if (take_ref) { - ret =fastrpc_map_get (map); -if (ret) { -dev_dbg (sess->dev,"%s: Failed to get map fd=%d ret=%d\n" , - __func__, fd, ret); -break ; - } - } - *ppmap = map; ret =0 ;break ;
@@ -757,7 +747,7 @@ static const struct dma_buf_ops fastrpc_ .release = fastrpc_release, }; -static int fastrpc_map_create (struct fastrpc_user *fl,int fd, +static int fastrpc_map_attach (struct fastrpc_user *fl,int fd,u64 len,u32 attr,struct fastrpc_map **ppmap) {struct fastrpc_session_ctx *sess = fl->sctx;
@@ -766,9 +756,6 @@ static int fastrpc_map_create(struct fasstruct scatterlist *sgl =NULL ;int err =0 , sgl_index =0 ; -if (!fastrpc_map_lookup (fl, fd, ppmap, true)) -return 0 ; - map =kzalloc (sizeof (*map),GFP_KERNEL );if (!map)return -ENOMEM ;
@@ -853,6 +840,24 @@ get_err:return err; } +static int fastrpc_map_create (struct fastrpc_user *fl,int fd, +u64 len,u32 attr,struct fastrpc_map **ppmap) +{ +struct fastrpc_session_ctx *sess = fl->sctx; +int err =0 ; + +if (!fastrpc_map_lookup (fl, fd, ppmap)) { +if (!fastrpc_map_get (*ppmap)) +return 0 ; +dev_dbg (sess->dev,"%s: Failed to get map fd=%d\n" , + __func__, fd); + } + + err =fastrpc_map_attach (fl, fd, len, attr, ppmap); + +return err; +} +/* * Fastrpc payload buffer with metadata looks like: *
@@ -925,8 +930,12 @@ static int fastrpc_create_maps(struct fa ctx->args[i].length == 0)continue ; - err =fastrpc_map_create (ctx->fl, ctx->args[i].fd, - ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]); +if (i < ctx->nbufs) + err =fastrpc_map_create (ctx->fl, ctx->args[i].fd, + ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]); +else + err =fastrpc_map_attach (ctx->fl, ctx->args[i].fd, + ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]);if (err) {dev_err (dev,"Error Creating map %d\n" , err);return -EINVAL ;
@@ -1116,7 +1125,7 @@ cleanup_fdlist:for (i =0 ; i <FASTRPC_MAX_FDLIST ; i++) {if (!fdlist[i])break ; -if (!fastrpc_map_lookup (fl, (int )fdlist[i], &mmap, false)) +if (!fastrpc_map_lookup (fl, (int )fdlist[i], &mmap))fastrpc_map_put (mmap); }
Greg Kroah-Hartman
maintainerPATCH 547/563 Input: atmel_mxt_ts - allow reset GPIO to sleep
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Vasut <[email protected]>
commit c7866ee0a9ddd9789faadf58cdac6abd7aabf045 upstream.
The reset GPIO is not toggled in any critical section where it couldn't sleep, allow the reset GPIO to sleep. This allows the driver to operate reset GPIOs connected to I2C GPIO expanders.
--- drivers/input/touchscreen/atmel_mxt_ts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/input/touchscreen/atmel_mxt_ts.c +1 -1
@@ -3317,7 +3317,7 @@ static int mxt_probe(struct i2c_client *if (data->reset_gpio) {/* Wait a while and then de-assert the RESET GPIO line */ msleep (MXT_RESET_GPIO_TIME ); -gpiod_set_value (data->reset_gpio,0 ); +gpiod_set_value_cansleep (data->reset_gpio,0 );msleep (MXT_RESET_INVALID_CHG ); }
Greg Kroah-Hartman
maintainerPATCH 548/563 Input: uinput - zero-initialize uinput_ff_upload_compat to avoid info leak
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhen Ni <[email protected]>
commit d3366a04770eea807f2826cbdb96934dd8c9bf79 upstream.
Struct ff_effect_compat is embedded twice inside uinput_ff_upload_compat, contains internal padding. In particular, there is a hole after struct ff_replay to satisfy alignment requirements for the following union member. Without clearing the structure, copy_to_user() may leak stack data to userspace.
Initialize ff_up_compat to zero before filling valid fields.
--- drivers/input/misc/uinput.c | 1 + 1 file changed, 1 insertion(+)
drivers/input/misc/uinput.c +1 -0
@@ -775,6 +775,7 @@ static int uinput_ff_upload_to_user(charif (in_compat_syscall ()) {struct uinput_ff_upload_compat ff_up_compat; +memset (&ff_up_compat,0 ,sizeof (ff_up_compat)); ff_up_compat.request_id = ff_up->request_id; ff_up_compat.retval = ff_up->retval;/*
Greg Kroah-Hartman
maintainerPATCH 549/563 sunrpc: fix null pointer dereference on zero-length checksum
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lei Lu <[email protected]>
commit 6df164e29bd4e6505c5a2e0e5f1e1f6957a16a42 upstream.
In xdr_stream_decode_opaque_auth(), zero-length checksum.len causes checksum.data to be set to NULL. This triggers a NPD when accessing checksum.data in gss_krb5_verify_mic_v2(). This patch ensures that the value of checksum.len is not less than XDR_UNIT.
--- net/sunrpc/auth_gss/svcauth_gss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/sunrpc/auth_gss/svcauth_gss.c +1 -1
@@ -724,7 +724,7 @@ svcauth_gss_verify_header(struct svc_rqs rqstp->rq_auth_stat = rpc_autherr_badverf;return SVC_DENIED ; } -if (flavor !=RPC_AUTH_GSS ) { +if (flavor !=RPC_AUTH_GSS || checksum.len <XDR_UNIT ) { rqstp->rq_auth_stat = rpc_autherr_badverf;return SVC_DENIED ; }
Greg Kroah-Hartman
maintainerPATCH 550/563 PCI/AER: Avoid NULL pointer dereference in aer_ratelimit()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
commit deb2f228388ff3a9d0623e3b59a053e9235c341d upstream.
When platform firmware supplies error information to the OS, e.g., via the ACPI APEI GHES mechanism, it may identify an error source device that doesn't advertise an AER Capability and therefore dev->aer_info, which contains AER stats and ratelimiting data, is NULL.
pci_dev_aer_stats_incr() already checks dev->aer_info for NULL, but aer_ratelimit() did not, leading to NULL pointer dereferences like this one from the URL below:
{1}[Hardware Error]: Hardware error from APEI Generic Hardware Error Source: 0 {1}[Hardware Error]: event severity: corrected
{1}[Hardware Error]: device_id: 0000:00:00.0
{1}[Hardware Error]: vendor_id: 0x8086, device_id: 0x2020
{1}[Hardware Error]: aer_cor_status: 0x00001000, aer_cor_mask: 0x00002000
BUG: kernel NULL pointer dereference, address: 0000000000000264
RIP: 0010:___ratelimit+0xc/0x1b0
pci_print_aer+0x141/0x360
aer_recover_work_func+0xb5/0x130[8086:2020] is an Intel "Sky Lake-E DMI3 Registers" device that claims to be a Root Port but does not advertise an AER Capability.
Add a NULL check in aer_ratelimit() to avoid the NULL pointer dereference. Note that this also prevents ratelimiting these events from GHES.
--- drivers/pci/pcie/aer.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/pci/pcie/aer.c +3 -0
@@ -786,6 +786,9 @@ static void pci_rootport_aer_stats_incr(static int aer_ratelimit (struct pci_dev *dev,unsigned int severity) { +if (!dev->aer_info) +return 1 ; +switch (severity) {case AER_NONFATAL :return __ratelimit (&dev->aer_info->nonfatal_ratelimit);
Greg Kroah-Hartman
maintainerPATCH 551/563 remoteproc: pru: Fix potential NULL pointer dereference in pru_rproc_set_ctable()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhen Ni <[email protected]>
commit d41e075b077142bb9ae5df40b9ddf9fd7821a811 upstream.
pru_rproc_set_ctable() accessed rproc->priv before the IS_ERR_OR_NULL check, which could lead to a null pointer dereference. Move the pru assignment, ensuring we never dereference a NULL rproc pointer.
--- drivers/remoteproc/pru_rproc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/remoteproc/pru_rproc.c +2 -1
@@ -340,7 +340,7 @@ EXPORT_SYMBOL_GPL(pru_rproc_put);*/ int pru_rproc_set_ctable (struct rproc *rproc,enum pru_ctable_idx c,u32 addr) { -struct pru_rproc *pru = rproc->priv; +struct pru_rproc *pru;unsigned int reg;u32 mask, set;u16 idx;
@@ -352,6 +352,7 @@ int pru_rproc_set_ctable(struct rproc *rif (!rproc->dev.parent || !is_pru_rproc (rproc->dev.parent))return -ENODEV ; + pru = rproc->priv;/* pointer is 16 bit and index is 8-bit so mask out the rest */ idx_mask = (c >=PRU_C28 ) ?0xFFFF :0xFF ;
Greg Kroah-Hartman
maintainerPATCH 552/563 PCI: endpoint: pci-epf-test: Add NULL check for DMA channels before release
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shin'ichiro Kawasaki <[email protected]>
commit 85afa9ea122dd9d4a2ead104a951d318975dcd25 upstream.
The fields dma_chan_tx and dma_chan_rx of the struct pci_epf_test can be NULL even after EPF initialization. Then it is prudent to check that they have non-NULL values before releasing the channels. Add the checks in pci_epf_test_clean_dma_chan().
Without the checks, NULL pointer dereferences happen and they can lead to a kernel panic in some cases:
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000050 Call trace: dma_release_channel+0x2c/0x120 (P) pci_epf_test_epc_deinit+0x94/0xc0 [pci_epf_test] pci_epc_deinit_notify+0x74/0xc0 tegra_pcie_ep_pex_rst_irq+0x250/0x5d8 irq_thread_fn+0x34/0xb8 irq_thread+0x18c/0x2e8 kthread+0x14c/0x210 ret_from_fork+0x10/0x20
--- drivers/pci/endpoint/functions/pci-epf-test.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/pci/endpoint/functions/pci-epf-test.c +11 -6
@@ -301,15 +301,20 @@ static void pci_epf_test_clean_dma_chan(if (!epf_test->dma_supported)return ; -dma_release_channel (epf_test->dma_chan_tx); -if (epf_test->dma_chan_tx == epf_test->dma_chan_rx) { +if (epf_test->dma_chan_tx) { +dma_release_channel (epf_test->dma_chan_tx); +if (epf_test->dma_chan_tx == epf_test->dma_chan_rx) { + epf_test->dma_chan_tx =NULL ; + epf_test->dma_chan_rx =NULL ; +return ; + } epf_test->dma_chan_tx =NULL ; - epf_test->dma_chan_rx =NULL ; -return ; } -dma_release_channel (epf_test->dma_chan_rx); - epf_test->dma_chan_rx =NULL ; +if (epf_test->dma_chan_rx) { +dma_release_channel (epf_test->dma_chan_rx); + epf_test->dma_chan_rx =NULL ; + } } static void pci_epf_test_print_rate(struct pci_epf_test *epf_test,
Greg Kroah-Hartman
maintainerPATCH 553/563 thunderbolt: Fix use-after-free in tb_dp_dprx_work
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Duoming Zhou <[email protected]>
commit 67600ccfc4f38ebd331b9332ac94717bfbc87ea7 upstream.
The original code relies on cancel_delayed_work() in tb_dp_dprx_stop(), which does not ensure that the delayed work item tunnel->dprx_work has fully completed if it was already running. This leads to use-after-free scenarios where tb_tunnel is deallocated by tb_tunnel_put(), while tunnel->dprx_work remains active and attempts to dereference tb_tunnel in tb_dp_dprx_work().
A typical race condition is illustrated below:
CPU 0 | CPU 1
tb_dp_tunnel_active() |
tb_deactivate_and_free_tunnel()| tb_dp_dprx_start()
tb_tunnel_deactivate() | queue_delayed_work()
tb_dp_activate() |
tb_dp_dprx_stop() | tb_dp_dprx_work() //delayed worker
cancel_delayed_work() |
tb_tunnel_put(tunnel); |
| tunnel = container_of(...); //UAF
| tunnel-> //UAFReplacing cancel_delayed_work() with cancel_delayed_work_sync() is not feasible as it would introduce a deadlock: both tb_dp_dprx_work() and the cleanup path acquire tb->lock, and cancel_delayed_work_sync() would wait indefinitely for the work item that cannot proceed.
Instead, implement proper reference counting:
- If cancel_delayed_work() returns true (work is pending), we release the reference in the stop function.
- If it returns false (work is executing or already completed), the reference is released in delayed work function itself.
This ensures the tb_tunnel remains valid during work item execution while preventing memory leaks.
This bug was found by static analysis.
--- drivers/thunderbolt/tunnel.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/thunderbolt/tunnel.c +3 -2
@@ -1073,6 +1073,7 @@ static void tb_dp_dprx_work(struct work_if (tunnel->callback) tunnel->callback (tunnel, tunnel->callback_data); +tb_tunnel_put (tunnel); }static int tb_dp_dprx_start (struct tb_tunnel *tunnel)
@@ -1100,8 +1101,8 @@ static void tb_dp_dprx_stop(struct tb_tuif (tunnel->dprx_started) { tunnel->dprx_started = false; tunnel->dprx_canceled = true; -cancel_delayed_work (&tunnel->dprx_work); -tb_tunnel_put (tunnel); +if (cancel_delayed_work (&tunnel->dprx_work)) +tb_tunnel_put (tunnel); } }
Greg Kroah-Hartman
maintainerPATCH 554/563 tee: fix register_shm_helper()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Wiklander <[email protected]>
commit d5cf5b37064b1699d946e8b7ab4ac7d7d101814c upstream.
In register_shm_helper(), fix incorrect error handling for a call to iov_iter_extract_pages(). A case is missing for when iov_iter_extract_pages() only got some pages and return a number larger than 0, but not the requested amount.
This fixes a possible NULL pointer dereference following a bad input from ioctl(TEE_IOC_SHM_REGISTER) where parts of the buffer isn't mapped.
--- drivers/tee/tee_shm.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/tee/tee_shm.c +8 -0
@@ -321,6 +321,14 @@ register_shm_helper(struct tee_context *if (unlikely (len <=0 )) { ret = len ?ERR_PTR (len) :ERR_PTR (-ENOMEM ); goto err_free_shm_pages; + }else if (DIV_ROUND_UP (len + off,PAGE_SIZE ) != num_pages) { +/* +* If we only got a few pages, update to release the +* correct amount below. +*/ + shm->num_pages = len /PAGE_SIZE ; + ret =ERR_PTR (-ENOMEM ); + goto err_put_shm_pages; }/*
Greg Kroah-Hartman
maintainerPATCH 555/563 pinctrl: check the return value of pinmux_ops::get_function_name()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <[email protected]>
commit 4002ee98c022d671ecc1e4a84029e9ae7d8a5603 upstream.
While the API contract in docs doesn't specify it explicitly, the generic implementation of the get_function_name() callback from struct pinmux_ops - pinmux_generic_get_function_name() - can fail and return NULL. This is already checked in pinmux_check_ops() so add a similar check in pinmux_func_name_to_selector() instead of passing the returned pointer right down to strcmp() where the NULL can get dereferenced. This is normal operation when adding new pinfunctions.
--- drivers/pinctrl/pinmux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pinctrl/pinmux.c +1 -1
@@ -337,7 +337,7 @@ static int pinmux_func_name_to_selector(while (selector < nfuncs) {const char *fname = ops->get_function_name (pctldev, selector); -if (!strcmp (function, fname)) +if (fname && !strcmp (function, fname))return selector; selector++;
Greg Kroah-Hartman
maintainerPATCH 556/563 bus: fsl-mc: Check return value of platform_get_resource()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Salah Triki <[email protected]>
commit 25f526507b8ccc6ac3a43bc094d09b1f9b0b90ae upstream.
platform_get_resource() returns NULL in case of failure, so check its return value and propagate the error in order to prevent NULL pointer dereference.
--- drivers/bus/fsl-mc/fsl-mc-bus.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/bus/fsl-mc/fsl-mc-bus.c +3 -0
@@ -1104,6 +1104,9 @@ static int fsl_mc_bus_probe(struct platf* Get physical address of MC portal for the root DPRC: */ plat_res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); +if (!plat_res) +return -EINVAL ; + mc_portal_phys_addr = plat_res->start; mc_portal_size =resource_size (plat_res); mc_portal_base_phys_addr = mc_portal_phys_addr & ~0x3ffffff ;
Greg Kroah-Hartman
maintainerPATCH 557/563 net/9p: Fix buffer overflow in USB transport layer
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dominique Martinet <[email protected]>
commit c04db81cd0288dfc68b7a0f7d09bd49b40bba451 upstream.
A buffer overflow vulnerability exists in the USB 9pfs transport layer where inconsistent size validation between packet header parsing and actual data copying allows a malicious USB host to overflow heap buffers.
The issue occurs because:
- usb9pfs_rx_header() validates only the declared size in packet header
- usb9pfs_rx_complete() uses req->actual (actual received bytes) for memcpy
This allows an attacker to craft packets with small declared size (bypassing validation) but large actual payload (triggering overflow in memcpy).
Add validation in usb9pfs_rx_complete() to ensure req->actual does not exceed the buffer capacity before copying data.
Message-ID: <[email protected]>
--- net/9p/trans_usbg.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
net/9p/trans_usbg.c +13 -3
@@ -231,6 +231,8 @@ static void usb9pfs_rx_complete(struct ustruct f_usb9pfs *usb9pfs = ep->driver_data;struct usb_composite_dev *cdev = usb9pfs->function.config->cdev;struct p9_req_t *p9_rx_req; +unsigned int req_size = req->actual; +int status =REQ_STATUS_RCVD ;if (req->status) { dev_err(&cdev->gadget->dev, "%s usb9pfs complete --> %d, %d/%d\n",
@@ -242,11 +244,19 @@ static void usb9pfs_rx_complete(struct uif (!p9_rx_req)return ; -memcpy (p9_rx_req->rc.sdata, req->buf, req->actual); +if (req_size > p9_rx_req->rc.capacity) { +dev_err (&cdev->gadget->dev, +"%s received data size %u exceeds buffer capacity %zu\n" , + ep->name, req_size, p9_rx_req->rc.capacity); + req_size =0 ; + status =REQ_STATUS_ERROR ; + } + +memcpy (p9_rx_req->rc.sdata, req->buf, req_size); - p9_rx_req->rc.size = req->actual; + p9_rx_req->rc.size = req_size; -p9_client_cb (usb9pfs->client, p9_rx_req,REQ_STATUS_RCVD ); +p9_client_cb (usb9pfs->client, p9_rx_req, status);p9_req_put (usb9pfs->client, p9_rx_req);complete (&usb9pfs->received);
Greg Kroah-Hartman
maintainerPATCH 558/563 net: usb: asix: hold PM usage ref to avoid PM/MDIO + RTNL deadlock
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel <[email protected]>
commit 3d3c4cd5c62f24bb3cb4511b7a95df707635e00a upstream.
Prevent USB runtime PM (autosuspend) for AX88772* in bind.
usbnet enables runtime PM (autosuspend) by default, so disabling it via the usb_driver flag is ineffective. On AX88772B, autosuspend shows no measurable power saving with current driver (no link partner, admin up/down). The ~0.453 W -> ~0.248 W drop on v6.1 comes from phylib powering the PHY off on admin-down, not from USB autosuspend.
The real hazard is that with runtime PM enabled, ndo_open() (under RTNL) may synchronously trigger autoresume (usb_autopm_get_interface()) into asix_resume() while the USB PM lock is held. Resume paths then invoke phylink/phylib and MDIO, which also expect RTNL, leading to possible deadlocks or PM lock vs MDIO wake issues.
To avoid this, keep the device runtime-PM active by taking a usage reference in ax88772_bind() and dropping it in unbind(). A non-zero PM usage count blocks runtime suspend regardless of userspace policy (.../power/control - pm_runtime_allow/forbid), making this approach robust against sysfs overrides.
Holding a runtime-PM usage ref does not affect system-wide suspend; system sleep/resume callbacks continue to run as before.
--- drivers/net/usb/asix_devices.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
drivers/net/usb/asix_devices.c +29 -0
@@ -625,6 +625,21 @@ static void ax88772_suspend(struct usbne asix_read_medium_status(dev, 1)); } +/* Notes on PM callbacks and locking context: +* +* - asix_suspend()/asix_resume() are invoked for both runtime PM and +* system-wide suspend/resume. For struct usb_driver the ->resume() +* callback does not receive pm_message_t, so the resume type cannot +* be distinguished here. +* +* - The MAC driver must hold RTNL when calling phylink interfaces such as +* phylink_suspend()/resume(). Those calls will also perform MDIO I/O. +* +* - Taking RTNL and doing MDIO from a runtime-PM resume callback (while +* the USB PM lock is held) is fragile. Since autosuspend brings no +* measurable power saving here, we block it by holding a PM usage +* reference in ax88772_bind(). +*/ static int asix_suspend (struct usb_interface *intf,pm_message_t message) {struct usbnet *dev =usb_get_intfdata (intf);
@@ -919,6 +934,13 @@ static int ax88772_bind(struct usbnet *dif (ret) goto initphy_err; +/* Keep this interface runtime-PM active by taking a usage ref. +* Prevents runtime suspend while bound and avoids resume paths +* that could deadlock (autoresume under RTNL while USB PM lock +* is held, phylink/MDIO wants RTNL). +*/ +pm_runtime_get_noresume (&intf->dev); +return 0 ; initphy_err:
@@ -948,6 +970,8 @@ static void ax88772_unbind(struct usbnetphylink_destroy (priv->phylink);ax88772_mdio_unregister (priv);asix_rx_fixup_common_free (dev->driver_priv); +/* Drop the PM usage ref taken in bind() */ +pm_runtime_put (&intf->dev); }static void ax88178_unbind (struct usbnet *dev,struct usb_interface *intf)
@@ -1600,6 +1624,11 @@ static struct usb_driver asix_driver = { .resume = asix_resume, .reset_resume = asix_resume, .disconnect = usbnet_disconnect, +/* usbnet enables autosuspend by default (supports_autosuspend=1). +* We keep runtime-PM active for AX88772* by taking a PM usage +* reference in ax88772_bind() (pm_runtime_get_noresume()) and +* dropping it in unbind(), which effectively blocks autosuspend. +*/ .supports_autosuspend = 1, .disable_hub_initiated_lpm = 1, };
Greg Kroah-Hartman
maintainerPATCH 559/563 usb: typec: tipd: Clear interrupts first
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Peter <[email protected]>
commit be5ae730ffa6fd774a00a4705c1e11e078b08ca1 upstream.
Right now the interrupt handler first reads all updated status registers and only then clears the interrupts. It's possible that a duplicate interrupt for a changed register or plug state comes in after the interrupts have been processed but before they have been cleared:
* plug is inserted, TPS_REG_INT_PLUG_EVENT is set
* TPS_REG_INT_EVENT1 is read
* tps6598x_handle_plug_event() has run and registered the plug
* plug is removed again, TPS_REG_INT_PLUG_EVENT is set (again)
* TPS_REG_INT_CLEAR1 is written, TPS_REG_INT_PLUG_EVENT is cleared
We then have no plug connected and no pending interrupt but the tipd core still thinks there is a plug. It's possible to trigger this with e.g. a slightly broken Type-C to USB A converter.
Fix this by first clearing the interrupts and only then reading the updated registers.
--- drivers/usb/typec/tipd/core.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-)
drivers/usb/typec/tipd/core.c +11 -13
@@ -545,24 +545,23 @@ static irqreturn_t cd321x_interrupt(intif (!event) goto err_unlock; +tps6598x_write64 (tps,TPS_REG_INT_CLEAR1 , event); +if (!tps6598x_read_status (tps, &status)) - goto err_clear_ints; + goto err_unlock;if (event &APPLE_CD_REG_INT_POWER_STATUS_UPDATE )if (!tps6598x_read_power_status (tps)) - goto err_clear_ints; + goto err_unlock;if (event &APPLE_CD_REG_INT_DATA_STATUS_UPDATE )if (!tps6598x_read_data_status (tps)) - goto err_clear_ints; + goto err_unlock;/* Handle plug insert or removal */ if (event &APPLE_CD_REG_INT_PLUG_EVENT )tps6598x_handle_plug_event (tps, status); -err_clear_ints: -tps6598x_write64 (tps,TPS_REG_INT_CLEAR1 , event); - err_unlock:mutex_unlock (&tps->lock);
@@ -668,25 +667,24 @@ static irqreturn_t tps6598x_interrupt(inif (!(event1[0 ] | event1[1 ] | event2[0 ] | event2[1 ])) goto err_unlock; +tps6598x_block_write (tps,TPS_REG_INT_CLEAR1 , event1, intev_len); +tps6598x_block_write (tps,TPS_REG_INT_CLEAR2 , event2, intev_len); +if (!tps6598x_read_status (tps, &status)) - goto err_clear_ints; + goto err_unlock;if ((event1[0 ] | event2[0 ]) &TPS_REG_INT_POWER_STATUS_UPDATE )if (!tps6598x_read_power_status (tps)) - goto err_clear_ints; + goto err_unlock;if ((event1[0 ] | event2[0 ]) &TPS_REG_INT_DATA_STATUS_UPDATE )if (!tps6598x_read_data_status (tps)) - goto err_clear_ints; + goto err_unlock;/* Handle plug insert or removal */ if ((event1[0 ] | event2[0 ]) &TPS_REG_INT_PLUG_EVENT )tps6598x_handle_plug_event (tps, status); -err_clear_ints: -tps6598x_block_write (tps,TPS_REG_INT_CLEAR1 , event1, intev_len); -tps6598x_block_write (tps,TPS_REG_INT_CLEAR2 , event2, intev_len); - err_unlock:mutex_unlock (&tps->lock);
Greg Kroah-Hartman
maintainerPATCH 560/563 arm64: dts: qcom: qcm2290: Disable USB SS bus instances in park mode
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Dybcio <[email protected]>
commit 27f94b71532203b079537180924023a5f636fca1 upstream.
2290 was found in the field to also require this quirk, as long & high-bandwidth workloads (e.g. USB ethernet) are consistently able to crash the controller otherwise.
The same change has been made for a number of SoCs in [1], but QCM2290 somehow escaped the list (even though the very closely related SM6115 was there).
Upon a controller crash, the log would read:
xhci-hcd.12.auto: xHCI host not responding to stop endpoint command xhci-hcd.12.auto: xHCI host controller not responding, assume dead xhci-hcd.12.auto: HC died; cleaning up
Add snps,parkmode-disable-ss-quirk to the DWC3 instance in order to prevent the aforementioned breakage.
[1] https://lore.kernel.org/all/[email protected]/
--- arch/arm64/boot/dts/qcom/qcm2290.dtsi | 1 + 1 file changed, 1 insertion(+)
arch/arm64/boot/dts/qcom/qcm2290.dtsi +1 -0
@@ -1454,6 +1454,7 @@ snps,has-lpm-erratum; snps,hird-threshold = /bits/ 8 <0x10>; snps,usb3_lpm_capable; + snps,parkmode-disable-ss-quirk; maximum-speed = "super-speed"; dr_mode = "otg"; usb-role-switch;
Greg Kroah-Hartman
maintainerPATCH 561/563 usb: cdns3: cdnsp-pci: remove redundant pci_disable_device() call
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miaoqian Lin <[email protected]>
commit e9c206324eeb213957a567a9d066bdeb355c7491 upstream.
The cdnsp-pci driver uses pcim_enable_device() to enable a PCI device, which means the device will be automatically disabled on driver detach through the managed device framework. The manual pci_disable_device() call in the error path is therefore redundant.
Found via static anlaysis and this is similar to commit 99ca0b57e49f ("thermal: intel: int340x: processor: Fix warning during module unload").
--- drivers/usb/cdns3/cdnsp-pci.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
drivers/usb/cdns3/cdnsp-pci.c +1 -4
@@ -85,7 +85,7 @@ static int cdnsp_pci_probe(struct pci_de cdnsp =kzalloc (sizeof (*cdnsp),GFP_KERNEL );if (!cdnsp) { ret = -ENOMEM ; - goto disable_pci; + goto put_pci; } }
@@ -168,9 +168,6 @@ free_cdnsp:if (!pci_is_enabled (func))kfree (cdnsp); -disable_pci: -pci_disable_device (pdev); - put_pci:pci_dev_put (func);
Greg Kroah-Hartman
maintainerPATCH 562/563 scsi: ufs: core: Fix PM QoS mutex initialization
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Szyprowski <[email protected]>
commit 0ba7a254afd037cfc2b656f379c54b43c6e574e8 upstream.
hba->pm_qos_mutex is used very early as a part of ufshcd_init(), so it need to be initialized before that call. This fixes the following warning:
------------[ cut here ]------------ DEBUG_LOCKS_WARN_ON(lock->magic != lock) WARNING: kernel/locking/mutex.c:577 at __mutex_lock+0x268/0x894, CPU#4: kworker/u32:4/72 Modules linked in: CPU: 4 UID: 0 PID: 72 Comm: kworker/u32:4 Not tainted 6.17.0-rc7-next-20250926+ #11223 PREEMPT Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT) Workqueue: events_unbound deferred_probe_work_func pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : __mutex_lock+0x268/0x894 lr : __mutex_lock+0x268/0x894 ... Call trace: __mutex_lock+0x268/0x894 (P) mutex_lock_nested+0x24/0x30 ufshcd_pm_qos_update+0x30/0x78 ufshcd_setup_clocks+0x2d4/0x3c4 ufshcd_init+0x234/0x126c ufshcd_pltfrm_init+0x62c/0x82c ufs_qcom_probe+0x20/0x58 platform_probe+0x5c/0xac really_probe+0xbc/0x298 __driver_probe_device+0x78/0x12c driver_probe_device+0x40/0x164 __device_attach_driver+0xb8/0x138 bus_for_each_drv+0x80/0xdc __device_attach+0xa8/0x1b0 device_initial_probe+0x14/0x20 bus_probe_device+0xb0/0xb4 deferred_probe_work_func+0x8c/0xc8 process_one_work+0x208/0x60c worker_thread+0x244/0x388 kthread+0x150/0x228 ret_from_fork+0x10/0x20 irq event stamp: 57267 hardirqs last enabled at (57267): [<ffffd761485e868c>] _raw_spin_unlock_irqrestore+0x74/0x78 hardirqs last disabled at (57266): [<ffffd76147b13c44>] clk_enable_lock+0x7c/0xf0 softirqs last enabled at (56270): [<ffffd7614734446c>] handle_softirqs+0x4c4/0x4dc softirqs last disabled at (56265): [<ffffd76147290690>] __do_softirq+0x14/0x20 ---[ end trace 0000000000000000 ]---
Message-Id: <[email protected]>
--- drivers/ufs/core/ufshcd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/ufs/core/ufshcd.c +3 -3
@@ -10674,6 +10674,9 @@ int ufshcd_init(struct ufs_hba *hba, voi*/ spin_lock_init (&hba->clk_gating.lock); +/* Initialize mutex for PM QoS request synchronization */ +mutex_init (&hba->pm_qos_mutex); +/* * Set the default power management level for runtime and system PM. * Host controller drivers can override them in their
@@ -10762,9 +10765,6 @@ int ufshcd_init(struct ufs_hba *hba, voimutex_init (&hba->wb_mutex); -/* Initialize mutex for PM QoS request synchronization */ -mutex_init (&hba->pm_qos_mutex); -init_rwsem (&hba->clk_scaling_lock);ufshcd_init_clk_gating (hba);
Greg Kroah-Hartman
maintainerPATCH 563/563 drm/amdgpu/vcn: Fix double-free of vcn dump buffer
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lijo Lazar <[email protected]>
commit 1a0e57eb96c3fca338665ffd7d9b59f351e5fea7 upstream.
The buffer is already freed as part of amdgpu_vcn_reg_dump_fini(). The issue is introduced by below patch series.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 1 + drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 1 - drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c | 2 -- drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c | 2 -- 4 files changed, 1 insertion(+), 5 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +1 -0
@@ -1573,6 +1573,7 @@ int amdgpu_vcn_reg_dump_init(struct amdgstatic void amdgpu_vcn_reg_dump_fini (struct amdgpu_device *adev) {kfree (adev->vcn.ip_dump); + adev->vcn.ip_dump =NULL ; adev->vcn.reg_list =NULL ; adev->vcn.reg_count =0 ; }
drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c +0 -1
@@ -361,7 +361,6 @@ static int vcn_v3_0_sw_fini(struct amdgpreturn r; } -kfree (adev->vcn.ip_dump);return 0 ; }
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c +0 -2
@@ -287,8 +287,6 @@ static int vcn_v4_0_3_sw_fini(struct amdreturn r; } -kfree (adev->vcn.ip_dump); -return 0 ; }
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c +0 -2
@@ -284,8 +284,6 @@ static int vcn_v4_0_5_sw_fini(struct amdreturn r; } -kfree (adev->vcn.ip_dump); -return 0 ; }
Hi
no regressions here on x86_64 (RKL, Intel 11th Gen. CPU)
Thanks
# Librecast Test Results
010/010 [ OK ] libmld
120/120 [ OK ] liblibrecast
CPU/kernel: Linux auntie 6.17.3-rc1-g99cf54e7bd2f #106 SMP PREEMPT_DYNAMIC Mon Oct 13 16:44:03 -00 2025 x86_64 AMD Ryzen 9 9950X 16-Core Processor AuthenticAMD GNU/Linux
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.17.3 release. There are 563 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 15 Oct 2025 14:42:41 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.17.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.17.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Signature · 1 line
Florian
Am 13.10.2025 um 16:37 schrieb Greg Kroah-Hartman:
Quoted 4 lines
This is the start of the stable review cycle for the 6.17.3 release. There are 563 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Builds, boots and works on my 2-socket Ivy Bridge Xeon E5-2697 v2 server. No dmesg oddities or regressions found.
Beste Grüße,
Peter Schneider
Signature · 8 lines
Climb the mountain not to plant your flag, but to embrace the challenge, enjoy the air and behold the view. Climb it so you can see the world, not so the world can see you. -- David McCullough Jr. OpenPGP: 0xA3828BD796CCE11A8CADE8866E3A92C92C3FF244 Download: https://www.peters-netzplatz.de/download/pschneider1968_pub.asc https://keys.mailvelope.com/pks/lookup?op=get&[email protected] https://keys.mailvelope.com/pks/lookup?op=get&[email protected]
Hi Greg
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.17.3 release. There are 563 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 15 Oct 2025 14:42:41 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.17.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.17.y
and the diffstat can be found below.thanks,
greg k-h
6.17.3-rc1 tested.
Build successfully completed.
Boot successfully completed.
No dmesg regressions.
Video output normal.
Sound output normal.
Lenovo ThinkPad X1 Carbon Gen10(Intel i7-1260P(x86_64) arch linux)
[ 0.000000] Linux version 6.17.3-rc1rv-g99cf54e7bd2f
(takeshi@ThinkPadX1Gen10J0764) (gcc (GCC) 15.2.1 20250813, GNU ld (GNU Binutils) 2.45.0) #1 SMP PREEMPT_DYNAMIC Tue Oct 14 12:16:46 JST 2025
Thanks
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.17.3 release. There are 563 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 15 Oct 2025 14:42:41 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.17.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.17.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
## Build
* kernel: 6.17.3-rc1
* git: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
* git commit: 99cf54e7bd2fde42d75c71b54fb3652adea2e7a4
* git describe: v6.17.2-564-g99cf54e7bd2f
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.17.y/build/v6.17.2-564-g99cf54e7bd2f
## Test Regressions (compared to v6.17-43-g8902adbbfd36)
## Metric Regressions (compared to v6.17-43-g8902adbbfd36)
## Test Fixes (compared to v6.17-43-g8902adbbfd36)
## Metric Fixes (compared to v6.17-43-g8902adbbfd36)
## Test result summary
total: 150604, pass: 129081, fail: 4610, skip: 16913, xfail: 0
## Build Summary
* arc: 5 total, 5 passed, 0 failed
* arm: 139 total, 138 passed, 1 failed
* arm64: 57 total, 51 passed, 6 failed
* i386: 18 total, 18 passed, 0 failed
* mips: 34 total, 33 passed, 1 failed
* parisc: 4 total, 4 passed, 0 failed
* powerpc: 40 total, 39 passed, 1 failed
* riscv: 25 total, 24 passed, 1 failed
* s390: 22 total, 21 passed, 1 failed
* sh: 5 total, 5 passed, 0 failed
* sparc: 4 total, 3 passed, 1 failed
* x86_64: 49 total, 46 passed, 3 failed
## Test suites summary
* boot
* commands
* kselftest-arm64
* kselftest-breakpoints
* kselftest-capabilities
* kselftest-cgroup
* kselftest-clone3
* kselftest-core
* kselftest-cpu-hotplug
* kselftest-cpufreq
* kselftest-efivarfs
* kselftest-exec
* kselftest-fpu
* kselftest-ftrace
* kselftest-futex
* kselftest-gpio
* kselftest-intel_pstate
* kselftest-ipc
* kselftest-kcmp
* kselftest-kvm
* kselftest-livepatch
* kselftest-membarrier
* kselftest-memfd
* kselftest-mincore
* kselftest-mm
* kselftest-mqueue
* kselftest-net
* kselftest-net-mptcp
* kselftest-openat2
* kselftest-ptrace
* kselftest-rseq
* kselftest-rtc
* kselftest-rust
* kselftest-seccomp
* kselftest-sigaltstack
* kselftest-size
* kselftest-tc-testing
* kselftest-timers
* kselftest-tmpfs
* kselftest-tpm2
* kselftest-user_events
* kselftest-vDSO
* kselftest-x86
* kunit
* kvm-unit-tests
* lava
* libgpiod
* libhugetlbfs
* log-parser-boot
* log-parser-build-clang
* log-parser-build-gcc
* log-parser-test
* ltp-capability
* ltp-commands
* ltp-containers
* ltp-controllers
* ltp-cpuhotplug
* ltp-crypto
* ltp-cve
* ltp-dio
* ltp-fcntl-locktests
* ltp-fs
* ltp-fs_bind
* ltp-fs_perms_simple
* ltp-hugetlb
* ltp-math
* ltp-mm
* ltp-nptl
* ltp-pty
* ltp-sched
* ltp-smoke
* ltp-syscalls
* ltp-tracing
* perf
* rcutorture
* rt-tests-cyclicdeadline
* rt-tests-pi-stress
* rt-tests-pmqtest
* rt-tests-rt-migrate-test
* rt-tests-signaltest
--
Linaro LKFT
https://lkft.linaro.org
[2025-10-13 16:37] Greg Kroah-Hartman:
Quoted 5 lines
This is the start of the stable review cycle for the 6.17.3 release. There are 563 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 8 lines
Responses should be made by Wed, 15 Oct 2025 14:42:41 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.17.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.17.y
and the diffstat can be found below.
Kernel 6.17.3-rc1 compiles fine for x86_64 using GCC 15.2.1+r22+gc4e96a094636 and binutils 2.45+r29+g2b2e51a31ec7, and the resulting kernel boots and runs without any discernible issues on various physical machines of mine (Ivy Bridge, Haswell, Kaby Lake, Coffee Lake) and on a Zen 2 VM and a bunch of Kaby Lake VMs.
Hiii Greg,
Quoted 15 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.17.3 release. There are 563 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 15 Oct 2025 14:42:41 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.17.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.17.y
and the diffstat can be found below.
Quoted 5 lines
thanks,
greg k-h
-------------
Build and boot tested 6.17.3-rc1 using qemu-x86_64. The kernel was successfully built and booted in a virtualized environment without any issues.
Build
kernel: 6.17.1-rc1
git: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git commit: 99cf54e7bd2fde42d75c71b54fb3652adea2e7a4
Best regards
Dileep Malepu.
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.17.3 release. There are 563 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 15 Oct 2025 14:42:41 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.17.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.17.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.17.3 release. There are 563 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 15 Oct 2025 14:42:41 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.17.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.17.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v6.17:
10 builds: 10 pass, 0 fail
28 boots: 28 pass, 0 fail
120 tests: 120 pass, 0 failLinux version: 6.17.3-rc1-g99cf54e7bd2f
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra186-p3509-0000+p3636-0001, tegra194-p2972-0000,
tegra194-p3509-0000+p3668-0000, tegra20-ventana,
tegra210-p2371-2180, tegra210-p3450-0000,
tegra30-cardhu-a04Jon
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.17.3 release. There are 563 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 15 Oct 2025 14:42:41 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.17.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.17.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Quoted 8 lines · On Mon, 13 Oct 2025 16:37:41 +0200 Greg Kroah-Hartman…
This is the start of the stable review cycle for the 6.17.3 release. There are 563 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 15 Oct 2025 14:42:41 +0000. Anything received after that time might be too late.
Boot-tested under QEMU for Rust x86_64, arm64 and riscv64; built-tested for arm and loongarch64:
Thanks!
Cheers,
Miguel
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.17.3 release. There are 563 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 15 Oct 2025 14:42:41 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.17.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.17.y
and the diffstat can be found below.thanks,
greg k-h
Tested rc1 against the Fedora build system (aarch64, ppc64le, s390x, x86_64), and boot tested x86_64. No regressions noted.
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.17.3 release. There are 563 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 15 Oct 2025 14:42:41 +0000. Anything received after that time might be too late.
Building m68k:allmodconfig ... failed
--------------
Error log:drivers/vfio/cdx/intr.c: In function 'vfio_cdx_msi_enable':drivers/vfio/cdx/intr.c:41:15: error: implicit declaration of function 'msi_domain_alloc_irqs'; did you mean 'msi_domain_get_virq'? [-Wimplicit-function-declaration]
41 | ret = msi_domain_alloc_irqs(dev, MSI_DEFAULT_DOMAIN, nvec);
| ^~~~~~~~~~~~~~~~~~~~~
| msi_domain_get_virqdrivers/vfio/cdx/intr.c: In function 'vfio_cdx_msi_disable':drivers/vfio/cdx/intr.c:135:9: error: implicit declaration of function 'msi_domain_free_irqs_all' [-Wimplicit-function-declaration]
135 | msi_domain_free_irqs_all(dev, MSI_DEFAULT_DOMAIN);
Bisect results below.
Guenter
---
# bad: [17e9266e1aff69de51dbd554c8dad36c4cfef0bd] Linux 6.17.3
# good: [449d48b1b99fdaa076166e200132705ac2bee711] Linux 6.17.2
git bisect start 'HEAD' 'v6.17.2'
# bad: [8e0a18d6ee733f4fc77bc05d73f28dba33914ccb] accel/amdxdna: Use int instead of u32 to store error codes
git bisect bad 8e0a18d6ee733f4fc77bc05d73f28dba33914ccb
# good: [6b4eacd05f6b96dabc2d26b753f2bc4e39094f82] Revert "arm64: dts: ti: k3-j721e-beagleboneai64: Fix reversed C6x carveout locations" git bisect good 6b4eacd05f6b96dabc2d26b753f2bc4e39094f82
# good: [f74032d51f93114e361f17d9919d12d6036f3687] mfd: max77705: Setup the core driver as an interrupt controller git bisect good f74032d51f93114e361f17d9919d12d6036f3687
# good: [83ced3c206c292458e47c7fac54223abc7141585] scsi: pm80xx: Fix array-index-out-of-of-bounds on rmmod
git bisect good 83ced3c206c292458e47c7fac54223abc7141585
# good: [2ca40698d2d78da82b6450968ab6a8b606a90304] drm/panel: Allow powering on panel follower after panel is enabled git bisect good 2ca40698d2d78da82b6450968ab6a8b606a90304
# good: [03f3cd82ec4d88905e53ed60ece681266d54c000] PCI: qcom: Restrict port parsing only to PCIe bridge child nodes git bisect good 03f3cd82ec4d88905e53ed60ece681266d54c000
# bad: [5e6ebfc78c11ff4ffe01aed73555a6c97c866300] ALSA: lx_core: use int type to store negative error codes
git bisect bad 5e6ebfc78c11ff4ffe01aed73555a6c97c866300
# bad: [ab6cfdfd8bd76367828cc952d57120436a076258] PCI/ACPI: Fix pci_acpi_preserve_config() memory leak
git bisect bad ab6cfdfd8bd76367828cc952d57120436a076258
# bad: [db05b70c5d4c34c748e25697bf7489b909d1d71a] cdx: don't select CONFIG_GENERIC_MSI_IRQ
git bisect bad db05b70c5d4c34c748e25697bf7489b909d1d71a
# first bad commit: [db05b70c5d4c34c748e25697bf7489b909d1d71a] cdx: don't select CONFIG_GENERIC_MSI_IRQ
Quoted 21 lines · Guenter Roeck
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.17.3 release. There are 563 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 15 Oct 2025 14:42:41 +0000. Anything received after that time might be too late.
Building m68k:allmodconfig ... failed
--------------
Error log:drivers/vfio/cdx/intr.c: In function 'vfio_cdx_msi_enable':drivers/vfio/cdx/intr.c:41:15: error: implicit declaration of function 'msi_domain_alloc_irqs'; did you mean 'msi_domain_get_virq'? [-Wimplicit-function-declaration]41 | ret = msi_domain_alloc_irqs(dev, MSI_DEFAULT_DOMAIN, nvec); | ^~~~~~~~~~~~~~~~~~~~~ | msi_domain_get_virq
drivers/vfio/cdx/intr.c: In function 'vfio_cdx_msi_disable':drivers/vfio/cdx/intr.c:135:9: error: implicit declaration of function 'msi_domain_free_irqs_all' [-Wimplicit-function-declaration]
135 |msi_domain_free_irqs_all(dev, MSI_DEFAULT_DOMAIN);
...
Quoted 1 line
# first bad commit: [db05b70c5d4c34c748e25697bf7489b909d1d71a] cdx: don't select CONFIG_GENERIC_MSI_IRQ
Our CI sees this as well with ARCH=hexagon allmodconfig. Commit 9f3acb3d9a18 ("vfio/cdx: update driver to build without CONFIG_GENERIC_MSI_IRQ") resolves this for me.
Cheers,
Nathan
Greg Kroah-Hartman
maintainerQuoted 22 lines · Nathan Chancellor
Quoted 15 lines · Guenter Roeck
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.17.3 release. There are 563 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 15 Oct 2025 14:42:41 +0000. Anything received after that time might be too late.
Building m68k:allmodconfig ... failed
--------------
Error log:drivers/vfio/cdx/intr.c: In function 'vfio_cdx_msi_enable':drivers/vfio/cdx/intr.c:41:15: error: implicit declaration of function 'msi_domain_alloc_irqs'; did you mean 'msi_domain_get_virq'? [-Wimplicit-function-declaration]Quoted 6 lines
41 | ret = msi_domain_alloc_irqs(dev, MSI_DEFAULT_DOMAIN, nvec); | ^~~~~~~~~~~~~~~~~~~~~ | msi_domain_get_virq
drivers/vfio/cdx/intr.c: In function 'vfio_cdx_msi_disable':drivers/vfio/cdx/intr.c:135:9: error: implicit declaration of function 'msi_domain_free_irqs_all' [-Wimplicit-function-declaration]
135 |msi_domain_free_irqs_all(dev, MSI_DEFAULT_DOMAIN);
Quoted 6 lines
...
Quoted 1 line
# first bad commit: [db05b70c5d4c34c748e25697bf7489b909d1d71a] cdx: don't select CONFIG_GENERIC_MSI_IRQOur CI sees this as well with ARCH=hexagon allmodconfig. Commit
9f3acb3d9a18("vfio/cdx: update driver to build withoutCONFIG_GENERIC_MSI_IRQ") resolves this for me.
Now queued up,t hanks.
greg k-h