This source file includes following definitions.
- ia64_do_show_stack
- show_stack
- show_regs
- console_print
- do_notify_resume_user
- nohalt_setup
- play_dead
- play_dead
- arch_cpu_idle_dead
- arch_cpu_idle
- ia64_save_extra
- ia64_load_extra
- copy_thread
- do_copy_task_regs
- do_dump_task_fpu
- do_copy_regs
- do_dump_fpu
- ia64_elf_core_copy_regs
- dump_fpu
- flush_thread
- exit_thread
- get_wchan
- cpu_halt
- machine_shutdown
- machine_restart
- machine_halt
- machine_power_off
1
2
3
4
5
6
7
8
9
10
11
12 #include <linux/cpu.h>
13 #include <linux/pm.h>
14 #include <linux/elf.h>
15 #include <linux/errno.h>
16 #include <linux/kernel.h>
17 #include <linux/mm.h>
18 #include <linux/slab.h>
19 #include <linux/module.h>
20 #include <linux/notifier.h>
21 #include <linux/personality.h>
22 #include <linux/sched.h>
23 #include <linux/sched/debug.h>
24 #include <linux/sched/hotplug.h>
25 #include <linux/sched/task.h>
26 #include <linux/sched/task_stack.h>
27 #include <linux/stddef.h>
28 #include <linux/thread_info.h>
29 #include <linux/unistd.h>
30 #include <linux/efi.h>
31 #include <linux/interrupt.h>
32 #include <linux/delay.h>
33 #include <linux/kdebug.h>
34 #include <linux/utsname.h>
35 #include <linux/tracehook.h>
36 #include <linux/rcupdate.h>
37
38 #include <asm/cpu.h>
39 #include <asm/delay.h>
40 #include <asm/elf.h>
41 #include <asm/irq.h>
42 #include <asm/kexec.h>
43 #include <asm/pgalloc.h>
44 #include <asm/processor.h>
45 #include <asm/sal.h>
46 #include <asm/switch_to.h>
47 #include <asm/tlbflush.h>
48 #include <linux/uaccess.h>
49 #include <asm/unwind.h>
50 #include <asm/user.h>
51
52 #include "entry.h"
53
54 #ifdef CONFIG_PERFMON
55 # include <asm/perfmon.h>
56 #endif
57
58 #include "sigframe.h"
59
60 void (*ia64_mark_idle)(int);
61
62 unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE;
63 EXPORT_SYMBOL(boot_option_idle_override);
64 void (*pm_power_off) (void);
65 EXPORT_SYMBOL(pm_power_off);
66
67 void
68 ia64_do_show_stack (struct unw_frame_info *info, void *arg)
69 {
70 unsigned long ip, sp, bsp;
71
72 printk("\nCall Trace:\n");
73 do {
74 unw_get_ip(info, &ip);
75 if (ip == 0)
76 break;
77
78 unw_get_sp(info, &sp);
79 unw_get_bsp(info, &bsp);
80 printk(" [<%016lx>] %pS\n"
81 " sp=%016lx bsp=%016lx\n",
82 ip, (void *)ip, sp, bsp);
83 } while (unw_unwind(info) >= 0);
84 }
85
86 void
87 show_stack (struct task_struct *task, unsigned long *sp)
88 {
89 if (!task)
90 unw_init_running(ia64_do_show_stack, NULL);
91 else {
92 struct unw_frame_info info;
93
94 unw_init_from_blocked_task(&info, task);
95 ia64_do_show_stack(&info, NULL);
96 }
97 }
98
99 void
100 show_regs (struct pt_regs *regs)
101 {
102 unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
103
104 print_modules();
105 printk("\n");
106 show_regs_print_info(KERN_DEFAULT);
107 printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s (%s)\n",
108 regs->cr_ipsr, regs->cr_ifs, ip, print_tainted(),
109 init_utsname()->release);
110 printk("ip is at %pS\n", (void *)ip);
111 printk("unat: %016lx pfs : %016lx rsc : %016lx\n",
112 regs->ar_unat, regs->ar_pfs, regs->ar_rsc);
113 printk("rnat: %016lx bsps: %016lx pr : %016lx\n",
114 regs->ar_rnat, regs->ar_bspstore, regs->pr);
115 printk("ldrs: %016lx ccv : %016lx fpsr: %016lx\n",
116 regs->loadrs, regs->ar_ccv, regs->ar_fpsr);
117 printk("csd : %016lx ssd : %016lx\n", regs->ar_csd, regs->ar_ssd);
118 printk("b0 : %016lx b6 : %016lx b7 : %016lx\n", regs->b0, regs->b6, regs->b7);
119 printk("f6 : %05lx%016lx f7 : %05lx%016lx\n",
120 regs->f6.u.bits[1], regs->f6.u.bits[0],
121 regs->f7.u.bits[1], regs->f7.u.bits[0]);
122 printk("f8 : %05lx%016lx f9 : %05lx%016lx\n",
123 regs->f8.u.bits[1], regs->f8.u.bits[0],
124 regs->f9.u.bits[1], regs->f9.u.bits[0]);
125 printk("f10 : %05lx%016lx f11 : %05lx%016lx\n",
126 regs->f10.u.bits[1], regs->f10.u.bits[0],
127 regs->f11.u.bits[1], regs->f11.u.bits[0]);
128
129 printk("r1 : %016lx r2 : %016lx r3 : %016lx\n", regs->r1, regs->r2, regs->r3);
130 printk("r8 : %016lx r9 : %016lx r10 : %016lx\n", regs->r8, regs->r9, regs->r10);
131 printk("r11 : %016lx r12 : %016lx r13 : %016lx\n", regs->r11, regs->r12, regs->r13);
132 printk("r14 : %016lx r15 : %016lx r16 : %016lx\n", regs->r14, regs->r15, regs->r16);
133 printk("r17 : %016lx r18 : %016lx r19 : %016lx\n", regs->r17, regs->r18, regs->r19);
134 printk("r20 : %016lx r21 : %016lx r22 : %016lx\n", regs->r20, regs->r21, regs->r22);
135 printk("r23 : %016lx r24 : %016lx r25 : %016lx\n", regs->r23, regs->r24, regs->r25);
136 printk("r26 : %016lx r27 : %016lx r28 : %016lx\n", regs->r26, regs->r27, regs->r28);
137 printk("r29 : %016lx r30 : %016lx r31 : %016lx\n", regs->r29, regs->r30, regs->r31);
138
139 if (user_mode(regs)) {
140
141 unsigned long val, *bsp, ndirty;
142 int i, sof, is_nat = 0;
143
144 sof = regs->cr_ifs & 0x7f;
145 ndirty = (regs->loadrs >> 19);
146 bsp = ia64_rse_skip_regs((unsigned long *) regs->ar_bspstore, ndirty);
147 for (i = 0; i < sof; ++i) {
148 get_user(val, (unsigned long __user *) ia64_rse_skip_regs(bsp, i));
149 printk("r%-3u:%c%016lx%s", 32 + i, is_nat ? '*' : ' ', val,
150 ((i == sof - 1) || (i % 3) == 2) ? "\n" : " ");
151 }
152 } else
153 show_stack(NULL, NULL);
154 }
155
156
157 void
158 console_print(const char *s)
159 {
160 printk(KERN_EMERG "%s", s);
161 }
162
163 void
164 do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
165 {
166 if (fsys_mode(current, &scr->pt)) {
167
168
169
170
171 if (!ia64_psr(&scr->pt)->lp)
172 ia64_psr(&scr->pt)->lp = 1;
173 return;
174 }
175
176 #ifdef CONFIG_PERFMON
177 if (current->thread.pfm_needs_checking)
178
179
180
181
182 pfm_handle_work();
183 #endif
184
185
186 if (test_thread_flag(TIF_SIGPENDING)) {
187 local_irq_enable();
188 ia64_do_signal(scr, in_syscall);
189 }
190
191 if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) {
192 local_irq_enable();
193 tracehook_notify_resume(&scr->pt);
194 }
195
196
197 if (unlikely(test_thread_flag(TIF_RESTORE_RSE))) {
198 local_irq_enable();
199 ia64_sync_krbs();
200 }
201
202 local_irq_disable();
203 }
204
205 static int __init nohalt_setup(char * str)
206 {
207 cpu_idle_poll_ctrl(true);
208 return 1;
209 }
210 __setup("nohalt", nohalt_setup);
211
212 #ifdef CONFIG_HOTPLUG_CPU
213
214 static inline void play_dead(void)
215 {
216 unsigned int this_cpu = smp_processor_id();
217
218
219 __this_cpu_write(cpu_state, CPU_DEAD);
220
221 max_xtp();
222 local_irq_disable();
223 idle_task_exit();
224 ia64_jump_to_sal(&sal_boot_rendez_state[this_cpu]);
225
226
227
228
229 BUG();
230 }
231 #else
232 static inline void play_dead(void)
233 {
234 BUG();
235 }
236 #endif
237
238 void arch_cpu_idle_dead(void)
239 {
240 play_dead();
241 }
242
243 void arch_cpu_idle(void)
244 {
245 void (*mark_idle)(int) = ia64_mark_idle;
246
247 #ifdef CONFIG_SMP
248 min_xtp();
249 #endif
250 rmb();
251 if (mark_idle)
252 (*mark_idle)(1);
253
254 safe_halt();
255
256 if (mark_idle)
257 (*mark_idle)(0);
258 #ifdef CONFIG_SMP
259 normal_xtp();
260 #endif
261 }
262
263 void
264 ia64_save_extra (struct task_struct *task)
265 {
266 #ifdef CONFIG_PERFMON
267 unsigned long info;
268 #endif
269
270 if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
271 ia64_save_debug_regs(&task->thread.dbr[0]);
272
273 #ifdef CONFIG_PERFMON
274 if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
275 pfm_save_regs(task);
276
277 info = __this_cpu_read(pfm_syst_info);
278 if (info & PFM_CPUINFO_SYST_WIDE)
279 pfm_syst_wide_update_task(task, info, 0);
280 #endif
281 }
282
283 void
284 ia64_load_extra (struct task_struct *task)
285 {
286 #ifdef CONFIG_PERFMON
287 unsigned long info;
288 #endif
289
290 if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
291 ia64_load_debug_regs(&task->thread.dbr[0]);
292
293 #ifdef CONFIG_PERFMON
294 if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
295 pfm_load_regs(task);
296
297 info = __this_cpu_read(pfm_syst_info);
298 if (info & PFM_CPUINFO_SYST_WIDE)
299 pfm_syst_wide_update_task(task, info, 1);
300 #endif
301 }
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334 int
335 copy_thread(unsigned long clone_flags,
336 unsigned long user_stack_base, unsigned long user_stack_size,
337 struct task_struct *p)
338 {
339 extern char ia64_ret_from_clone;
340 struct switch_stack *child_stack, *stack;
341 unsigned long rbs, child_rbs, rbs_size;
342 struct pt_regs *child_ptregs;
343 struct pt_regs *regs = current_pt_regs();
344 int retval = 0;
345
346 child_ptregs = (struct pt_regs *) ((unsigned long) p + IA64_STK_OFFSET) - 1;
347 child_stack = (struct switch_stack *) child_ptregs - 1;
348
349 rbs = (unsigned long) current + IA64_RBS_OFFSET;
350 child_rbs = (unsigned long) p + IA64_RBS_OFFSET;
351
352
353 p->thread.ksp = (unsigned long) child_stack - 16;
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371 # define THREAD_FLAGS_TO_CLEAR (IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID \
372 | IA64_THREAD_PM_VALID)
373 # define THREAD_FLAGS_TO_SET 0
374 p->thread.flags = ((current->thread.flags & ~THREAD_FLAGS_TO_CLEAR)
375 | THREAD_FLAGS_TO_SET);
376
377 ia64_drop_fpu(p);
378
379 if (unlikely(p->flags & PF_KTHREAD)) {
380 if (unlikely(!user_stack_base)) {
381
382 return 0;
383 }
384 memset(child_stack, 0, sizeof(*child_ptregs) + sizeof(*child_stack));
385 child_stack->r4 = user_stack_base;
386 child_stack->r5 = user_stack_size;
387
388
389
390
391 child_ptregs->cr_ipsr = ia64_getreg(_IA64_REG_PSR) | IA64_PSR_BN;
392
393 child_ptregs->cr_ifs = 1UL << 63;
394 child_stack->ar_fpsr = child_ptregs->ar_fpsr
395 = ia64_getreg(_IA64_REG_AR_FPSR);
396 child_stack->pr = (1 << PRED_KERNEL_STACK);
397 child_stack->ar_bspstore = child_rbs;
398 child_stack->b0 = (unsigned long) &ia64_ret_from_clone;
399
400
401
402
403
404
405 child_ptregs->cr_ipsr = ((child_ptregs->cr_ipsr | IA64_PSR_BITS_TO_SET)
406 & ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_PP | IA64_PSR_UP));
407
408 return 0;
409 }
410 stack = ((struct switch_stack *) regs) - 1;
411
412 memcpy(child_stack, stack, sizeof(*child_ptregs) + sizeof(*child_stack));
413
414
415 rbs_size = stack->ar_bspstore - rbs;
416 memcpy((void *) child_rbs, (void *) rbs, rbs_size);
417 if (clone_flags & CLONE_SETTLS)
418 child_ptregs->r13 = regs->r16;
419 if (user_stack_base) {
420 child_ptregs->r12 = user_stack_base + user_stack_size - 16;
421 child_ptregs->ar_bspstore = user_stack_base;
422 child_ptregs->ar_rnat = 0;
423 child_ptregs->loadrs = 0;
424 }
425 child_stack->ar_bspstore = child_rbs + rbs_size;
426 child_stack->b0 = (unsigned long) &ia64_ret_from_clone;
427
428
429
430
431
432
433 child_ptregs->cr_ipsr = ((child_ptregs->cr_ipsr | IA64_PSR_BITS_TO_SET)
434 & ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_PP | IA64_PSR_UP));
435
436 #ifdef CONFIG_PERFMON
437 if (current->thread.pfm_context)
438 pfm_inherit(p, child_ptregs);
439 #endif
440 return retval;
441 }
442
443 static void
444 do_copy_task_regs (struct task_struct *task, struct unw_frame_info *info, void *arg)
445 {
446 unsigned long mask, sp, nat_bits = 0, ar_rnat, urbs_end, cfm;
447 unsigned long uninitialized_var(ip);
448 elf_greg_t *dst = arg;
449 struct pt_regs *pt;
450 char nat;
451 int i;
452
453 memset(dst, 0, sizeof(elf_gregset_t));
454
455 if (unw_unwind_to_user(info) < 0)
456 return;
457
458 unw_get_sp(info, &sp);
459 pt = (struct pt_regs *) (sp + 16);
460
461 urbs_end = ia64_get_user_rbs_end(task, pt, &cfm);
462
463 if (ia64_sync_user_rbs(task, info->sw, pt->ar_bspstore, urbs_end) < 0)
464 return;
465
466 ia64_peek(task, info->sw, urbs_end, (long) ia64_rse_rnat_addr((long *) urbs_end),
467 &ar_rnat);
468
469
470
471
472
473
474
475
476
477
478
479
480
481 for (i = 1, mask = (1UL << i); i < 32; ++i) {
482 unw_get_gr(info, i, &dst[i], &nat);
483 if (nat)
484 nat_bits |= mask;
485 mask <<= 1;
486 }
487 dst[32] = nat_bits;
488 unw_get_pr(info, &dst[33]);
489
490 for (i = 0; i < 8; ++i)
491 unw_get_br(info, i, &dst[34 + i]);
492
493 unw_get_rp(info, &ip);
494 dst[42] = ip + ia64_psr(pt)->ri;
495 dst[43] = cfm;
496 dst[44] = pt->cr_ipsr & IA64_PSR_UM;
497
498 unw_get_ar(info, UNW_AR_RSC, &dst[45]);
499
500
501
502
503 dst[46] = urbs_end;
504 dst[47] = pt->ar_bspstore;
505 dst[48] = ar_rnat;
506 unw_get_ar(info, UNW_AR_CCV, &dst[49]);
507 unw_get_ar(info, UNW_AR_UNAT, &dst[50]);
508 unw_get_ar(info, UNW_AR_FPSR, &dst[51]);
509 dst[52] = pt->ar_pfs;
510 unw_get_ar(info, UNW_AR_LC, &dst[53]);
511 unw_get_ar(info, UNW_AR_EC, &dst[54]);
512 unw_get_ar(info, UNW_AR_CSD, &dst[55]);
513 unw_get_ar(info, UNW_AR_SSD, &dst[56]);
514 }
515
516 void
517 do_dump_task_fpu (struct task_struct *task, struct unw_frame_info *info, void *arg)
518 {
519 elf_fpreg_t *dst = arg;
520 int i;
521
522 memset(dst, 0, sizeof(elf_fpregset_t));
523
524 if (unw_unwind_to_user(info) < 0)
525 return;
526
527
528
529 for (i = 2; i < 32; ++i)
530 unw_get_fr(info, i, dst + i);
531
532 ia64_flush_fph(task);
533 if ((task->thread.flags & IA64_THREAD_FPH_VALID) != 0)
534 memcpy(dst + 32, task->thread.fph, 96*16);
535 }
536
537 void
538 do_copy_regs (struct unw_frame_info *info, void *arg)
539 {
540 do_copy_task_regs(current, info, arg);
541 }
542
543 void
544 do_dump_fpu (struct unw_frame_info *info, void *arg)
545 {
546 do_dump_task_fpu(current, info, arg);
547 }
548
549 void
550 ia64_elf_core_copy_regs (struct pt_regs *pt, elf_gregset_t dst)
551 {
552 unw_init_running(do_copy_regs, dst);
553 }
554
555 int
556 dump_fpu (struct pt_regs *pt, elf_fpregset_t dst)
557 {
558 unw_init_running(do_dump_fpu, dst);
559 return 1;
560 }
561
562
563
564
565 void
566 flush_thread (void)
567 {
568
569 current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID);
570 ia64_drop_fpu(current);
571 }
572
573
574
575
576
577 void
578 exit_thread (struct task_struct *tsk)
579 {
580
581 ia64_drop_fpu(tsk);
582 #ifdef CONFIG_PERFMON
583
584 if (tsk->thread.pfm_context)
585 pfm_exit_thread(tsk);
586
587
588 if (tsk->thread.flags & IA64_THREAD_DBG_VALID)
589 pfm_release_debug_registers(tsk);
590 #endif
591 }
592
593 unsigned long
594 get_wchan (struct task_struct *p)
595 {
596 struct unw_frame_info info;
597 unsigned long ip;
598 int count = 0;
599
600 if (!p || p == current || p->state == TASK_RUNNING)
601 return 0;
602
603
604
605
606
607
608
609
610
611 unw_init_from_blocked_task(&info, p);
612 do {
613 if (p->state == TASK_RUNNING)
614 return 0;
615 if (unw_unwind(&info) < 0)
616 return 0;
617 unw_get_ip(&info, &ip);
618 if (!in_sched_functions(ip))
619 return ip;
620 } while (count++ < 16);
621 return 0;
622 }
623
624 void
625 cpu_halt (void)
626 {
627 pal_power_mgmt_info_u_t power_info[8];
628 unsigned long min_power;
629 int i, min_power_state;
630
631 if (ia64_pal_halt_info(power_info) != 0)
632 return;
633
634 min_power_state = 0;
635 min_power = power_info[0].pal_power_mgmt_info_s.power_consumption;
636 for (i = 1; i < 8; ++i)
637 if (power_info[i].pal_power_mgmt_info_s.im
638 && power_info[i].pal_power_mgmt_info_s.power_consumption < min_power) {
639 min_power = power_info[i].pal_power_mgmt_info_s.power_consumption;
640 min_power_state = i;
641 }
642
643 while (1)
644 ia64_pal_halt(min_power_state);
645 }
646
647 void machine_shutdown(void)
648 {
649 #ifdef CONFIG_HOTPLUG_CPU
650 int cpu;
651
652 for_each_online_cpu(cpu) {
653 if (cpu != smp_processor_id())
654 cpu_down(cpu);
655 }
656 #endif
657 #ifdef CONFIG_KEXEC
658 kexec_disable_iosapic();
659 #endif
660 }
661
662 void
663 machine_restart (char *restart_cmd)
664 {
665 (void) notify_die(DIE_MACHINE_RESTART, restart_cmd, NULL, 0, 0, 0);
666 efi_reboot(REBOOT_WARM, NULL);
667 }
668
669 void
670 machine_halt (void)
671 {
672 (void) notify_die(DIE_MACHINE_HALT, "", NULL, 0, 0, 0);
673 cpu_halt();
674 }
675
676 void
677 machine_power_off (void)
678 {
679 if (pm_power_off)
680 pm_power_off();
681 machine_halt();
682 }
683