8 #include <linux/sched.h>
9 #include <linux/module.h>
13 #include <linux/ptrace.h>
14 #include <linux/slab.h>
15 #include <linux/reboot.h>
22 #include <asm/syscalls.h>
37 tick_nohz_idle_enter();
39 while (!need_resched())
42 tick_nohz_idle_exit();
54 asm volatile(
"sleep 3\n\t"
84 __asm__(
" .type kernel_thread_helper, @function\n"
85 "kernel_thread_helper:\n"
89 " .size kernel_thread_helper, . - kernel_thread_helper");
95 memset(®s, 0,
sizeof(regs));
97 regs.
r0 = (
unsigned long)arg;
127 static void dump_mem(
const char *
str,
const char *log_lvl,
133 printk(
"%s%s(0x%08lx to 0x%08lx)\n", log_lvl, str, bottom, top);
135 for (p = bottom & ~31; p <
top; ) {
136 printk(
"%s%04lx: ", log_lvl, p & 0xffff);
138 for (i = 0; i < 8; i++, p += 4) {
141 if (p < bottom || p >= top)
144 if (
__get_user(val, (
unsigned int __user *)p)) {
158 static inline int valid_stack_ptr(
struct thread_info *
tinfo,
unsigned long p)
160 return (p > (
unsigned long)tinfo)
164 #ifdef CONFIG_FRAME_POINTER
165 static void show_trace_log_lvl(
struct task_struct *tsk,
unsigned long *
sp,
168 unsigned long lr,
fp;
174 asm(
"mov %0, r7" :
"=r"(
fp));
176 fp = tsk->
thread.cpu_context.r7;
184 printk(
"%sCall trace:\n", log_lvl);
185 while (valid_stack_ptr(tinfo, fp)) {
186 unsigned long new_fp;
188 lr = *(
unsigned long *)fp;
189 #ifdef CONFIG_KALLSYMS
190 printk(
"%s [<%08lx>] ", log_lvl, lr);
192 printk(
" [<%08lx>] ", lr);
194 print_symbol(
"%s\n", lr);
196 new_fp = *(
unsigned long *)(fp + 4);
204 static void show_trace_log_lvl(
struct task_struct *tsk,
unsigned long *sp,
205 struct pt_regs *regs,
const char *log_lvl)
209 printk(
"%sCall trace:\n", log_lvl);
211 while (!kstack_end(sp)) {
214 #ifdef CONFIG_KALLSYMS
215 printk(
"%s [<%08lx>] ", log_lvl, addr);
217 printk(
" [<%08lx>] ", addr);
219 print_symbol(
"%s\n", addr);
227 struct pt_regs *regs,
const char *log_lvl)
233 sp = tsk->
thread.cpu_context.ksp;
235 sp = (
unsigned long)&tinfo;
242 if (valid_stack_ptr(tinfo, sp)) {
243 dump_mem(
"Stack: ", log_lvl, sp,
245 show_trace_log_lvl(tsk, (
unsigned long *)sp, regs, log_lvl);
262 static const char *cpu_modes[] = {
263 "Application",
"Supervisor",
"Interrupt level 0",
"Interrupt level 1",
264 "Interrupt level 2",
"Interrupt level 3",
"Exception",
"NMI"
269 unsigned long sp = regs->
sp;
270 unsigned long lr = regs->
lr;
279 print_symbol(
"LR is at %s\n", lr);
282 printk(
"%spc : [<%08lx>] lr : [<%08lx>] %s\n"
283 "%ssp : %08lx r12: %08lx r11: %08lx\n",
285 log_lvl, sp, regs->
r12, regs->
r11);
286 printk(
"%sr10: %08lx r9 : %08lx r8 : %08lx\n",
287 log_lvl, regs->
r10, regs->
r9, regs->
r8);
288 printk(
"%sr7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
289 log_lvl, regs->
r7, regs->
r6, regs->
r5, regs->
r4);
290 printk(
"%sr3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
291 log_lvl, regs->
r3, regs->
r2, regs->
r1, regs->
r0);
292 printk(
"%sFlags: %c%c%c%c%c\n", log_lvl,
293 regs->
sr &
SR_Q ?
'Q' :
'q',
294 regs->
sr &
SR_V ?
'V' :
'v',
295 regs->
sr &
SR_N ?
'N' :
'n',
296 regs->
sr &
SR_Z ?
'Z' :
'z',
297 regs->
sr &
SR_C ?
'C' :
'c');
298 printk(
"%sMode bits: %c%c%c%c%c%c%c%c%c%c\n", log_lvl,
299 regs->
sr &
SR_H ?
'H' :
'h',
300 regs->
sr &
SR_J ?
'J' :
'j',
302 regs->
sr &
SR_D ?
'D' :
'd',
309 printk(
"%sCPU Mode: %s\n", log_lvl, cpu_modes[mode]);
310 printk(
"%sProcess: %s [%d] (task: %p thread: %p)\n",
317 unsigned long sp = regs->
sp;
323 show_trace_log_lvl(
current, (
unsigned long *)sp, regs,
"");
353 p->
thread.cpu_context.ksp = (
unsigned long)childregs;
370 void __user *parent_tidptr,
void __user *child_tidptr,
375 return do_fork(clone_flags, newsp, regs, 0, parent_tidptr,
386 const char __user *
const __user *uargv,
387 const char __user *
const __user *uenvp,
394 error = PTR_ERR(filename);
395 if (IS_ERR(filename))
413 unsigned long stack_page;
427 #ifdef CONFIG_FRAME_POINTER
428 unsigned long fp = p->
thread.cpu_context.r7;
430 pc = *(
unsigned long *)fp;
441 unsigned long sp = p->
thread.cpu_context.ksp + 16;
443 pc = *(
unsigned long *)sp;