Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rmk/linux

Pull ARM and clkdev fixes from Russell King:

- Fix clkdev - erroring out on long strings causes boot failures, so
don't do this. Still warn about the over-sized strings (which will
never match and thus their registration with clkdev is useless)

- Fix for ftrace with frame pointer unwinder with recent GCC changing
the way frames are stacked.

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rmk/linux:
ARM: 9405/1: ftrace: Don't assume stack frames are contiguous in memory
clkdev: don't fail clkdev_alloc() if over-sized

+24 -4
+15 -2
arch/arm/kernel/ftrace.c
··· 232 232 unsigned long old; 233 233 234 234 if (unlikely(atomic_read(&current->tracing_graph_pause))) 235 + err_out: 235 236 return; 236 237 237 238 if (IS_ENABLED(CONFIG_UNWINDER_FRAME_POINTER)) { 238 - /* FP points one word below parent's top of stack */ 239 - frame_pointer += 4; 239 + /* 240 + * Usually, the stack frames are contiguous in memory but cases 241 + * have been observed where the next stack frame does not live 242 + * at 'frame_pointer + 4' as this code used to assume. 243 + * 244 + * Instead, dereference the field in the stack frame that 245 + * stores the SP of the calling frame: to avoid unbounded 246 + * recursion, this cannot involve any ftrace instrumented 247 + * functions, so use the __get_kernel_nofault() primitive 248 + * directly. 249 + */ 250 + __get_kernel_nofault(&frame_pointer, 251 + (unsigned long *)(frame_pointer - 8), 252 + unsigned long, err_out); 240 253 } else { 241 254 struct stackframe frame = { 242 255 .fp = frame_pointer,
+9 -2
drivers/clk/clkdev.c
··· 204 204 pr_err("%pV:%s: %s ID is greater than %zu\n", 205 205 &vaf, con_id, failure, max_size); 206 206 va_end(ap_copy); 207 - kfree(cla); 208 - return NULL; 207 + 208 + /* 209 + * Don't fail in this case, but as the entry won't ever match just 210 + * fill it with something that also won't match. 211 + */ 212 + strscpy(cla->con_id, "bad", sizeof(cla->con_id)); 213 + strscpy(cla->dev_id, "bad", sizeof(cla->dev_id)); 214 + 215 + return &cla->cl; 209 216 } 210 217 211 218 static struct clk_lookup *