1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * linux/arch/alpha/kernel/process.c |
4 | * |
5 | * Copyright (C) 1995 Linus Torvalds |
6 | */ |
7 | |
8 | /* |
9 | * This file handles the architecture-dependent parts of process handling. |
10 | */ |
11 | |
12 | #include <linux/cpu.h> |
13 | #include <linux/errno.h> |
14 | #include <linux/module.h> |
15 | #include <linux/sched.h> |
16 | #include <linux/sched/debug.h> |
17 | #include <linux/sched/task.h> |
18 | #include <linux/sched/task_stack.h> |
19 | #include <linux/kernel.h> |
20 | #include <linux/mm.h> |
21 | #include <linux/smp.h> |
22 | #include <linux/stddef.h> |
23 | #include <linux/unistd.h> |
24 | #include <linux/ptrace.h> |
25 | #include <linux/user.h> |
26 | #include <linux/time.h> |
27 | #include <linux/major.h> |
28 | #include <linux/stat.h> |
29 | #include <linux/vt.h> |
30 | #include <linux/mman.h> |
31 | #include <linux/elfcore.h> |
32 | #include <linux/reboot.h> |
33 | #include <linux/tty.h> |
34 | #include <linux/console.h> |
35 | #include <linux/slab.h> |
36 | #include <linux/rcupdate.h> |
37 | |
38 | #include <asm/reg.h> |
39 | #include <linux/uaccess.h> |
40 | #include <asm/io.h> |
41 | #include <asm/hwrpb.h> |
42 | #include <asm/fpu.h> |
43 | |
44 | #include "proto.h" |
45 | #include "pci_impl.h" |
46 | |
47 | /* |
48 | * Power off function, if any |
49 | */ |
50 | void (*pm_power_off)(void) = machine_power_off; |
51 | EXPORT_SYMBOL(pm_power_off); |
52 | |
53 | #ifdef CONFIG_ALPHA_WTINT |
54 | /* |
55 | * Sleep the CPU. |
56 | * EV6, LCA45 and QEMU know how to power down, skipping N timer interrupts. |
57 | */ |
58 | void arch_cpu_idle(void) |
59 | { |
60 | wtint(0); |
61 | } |
62 | |
63 | void __noreturn arch_cpu_idle_dead(void) |
64 | { |
65 | wtint(INT_MAX); |
66 | BUG(); |
67 | } |
68 | #endif /* ALPHA_WTINT */ |
69 | |
70 | struct halt_info { |
71 | int mode; |
72 | char *restart_cmd; |
73 | }; |
74 | |
75 | static void |
76 | common_shutdown_1(void *generic_ptr) |
77 | { |
78 | struct halt_info *how = generic_ptr; |
79 | struct percpu_struct *cpup; |
80 | unsigned long *pflags, flags; |
81 | int cpuid = smp_processor_id(); |
82 | |
83 | /* No point in taking interrupts anymore. */ |
84 | local_irq_disable(); |
85 | |
86 | cpup = (struct percpu_struct *) |
87 | ((unsigned long)hwrpb + hwrpb->processor_offset |
88 | + hwrpb->processor_size * cpuid); |
89 | pflags = &cpup->flags; |
90 | flags = *pflags; |
91 | |
92 | /* Clear reason to "default"; clear "bootstrap in progress". */ |
93 | flags &= ~0x00ff0001UL; |
94 | |
95 | #ifdef CONFIG_SMP |
96 | /* Secondaries halt here. */ |
97 | if (cpuid != boot_cpuid) { |
98 | flags |= 0x00040000UL; /* "remain halted" */ |
99 | *pflags = flags; |
100 | set_cpu_present(cpu: cpuid, present: false); |
101 | set_cpu_possible(cpu: cpuid, possible: false); |
102 | halt(); |
103 | } |
104 | #endif |
105 | |
106 | if (how->mode == LINUX_REBOOT_CMD_RESTART) { |
107 | if (!how->restart_cmd) { |
108 | flags |= 0x00020000UL; /* "cold bootstrap" */ |
109 | } else { |
110 | /* For SRM, we could probably set environment |
111 | variables to get this to work. We'd have to |
112 | delay this until after srm_paging_stop unless |
113 | we ever got srm_fixup working. |
114 | |
115 | At the moment, SRM will use the last boot device, |
116 | but the file and flags will be the defaults, when |
117 | doing a "warm" bootstrap. */ |
118 | flags |= 0x00030000UL; /* "warm bootstrap" */ |
119 | } |
120 | } else { |
121 | flags |= 0x00040000UL; /* "remain halted" */ |
122 | } |
123 | *pflags = flags; |
124 | |
125 | #ifdef CONFIG_SMP |
126 | /* Wait for the secondaries to halt. */ |
127 | set_cpu_present(cpu: boot_cpuid, present: false); |
128 | set_cpu_possible(cpu: boot_cpuid, possible: false); |
129 | while (!cpumask_empty(cpu_present_mask)) |
130 | barrier(); |
131 | #endif |
132 | |
133 | /* If booted from SRM, reset some of the original environment. */ |
134 | if (alpha_using_srm) { |
135 | #ifdef CONFIG_DUMMY_CONSOLE |
136 | /* If we've gotten here after SysRq-b, leave interrupt |
137 | context before taking over the console. */ |
138 | if (in_hardirq()) |
139 | irq_exit(); |
140 | /* This has the effect of resetting the VGA video origin. */ |
141 | console_lock(); |
142 | do_take_over_console(sw: &dummy_con, first: 0, MAX_NR_CONSOLES-1, deflt: 1); |
143 | console_unlock(); |
144 | #endif |
145 | pci_restore_srm_config(); |
146 | set_hae(srm_hae); |
147 | } |
148 | |
149 | if (alpha_mv.kill_arch) |
150 | alpha_mv.kill_arch(how->mode); |
151 | |
152 | if (! alpha_using_srm && how->mode != LINUX_REBOOT_CMD_RESTART) { |
153 | /* Unfortunately, since MILO doesn't currently understand |
154 | the hwrpb bits above, we can't reliably halt the |
155 | processor and keep it halted. So just loop. */ |
156 | return; |
157 | } |
158 | |
159 | if (alpha_using_srm) |
160 | srm_paging_stop(); |
161 | |
162 | halt(); |
163 | } |
164 | |
165 | static void |
166 | common_shutdown(int mode, char *restart_cmd) |
167 | { |
168 | struct halt_info args; |
169 | args.mode = mode; |
170 | args.restart_cmd = restart_cmd; |
171 | on_each_cpu(func: common_shutdown_1, info: &args, wait: 0); |
172 | } |
173 | |
174 | void |
175 | machine_restart(char *restart_cmd) |
176 | { |
177 | common_shutdown(LINUX_REBOOT_CMD_RESTART, restart_cmd); |
178 | } |
179 | |
180 | |
181 | void |
182 | machine_halt(void) |
183 | { |
184 | common_shutdown(LINUX_REBOOT_CMD_HALT, NULL); |
185 | } |
186 | |
187 | |
188 | void |
189 | machine_power_off(void) |
190 | { |
191 | common_shutdown(LINUX_REBOOT_CMD_POWER_OFF, NULL); |
192 | } |
193 | |
194 | |
195 | /* Used by sysrq-p, among others. I don't believe r9-r15 are ever |
196 | saved in the context it's used. */ |
197 | |
198 | void |
199 | show_regs(struct pt_regs *regs) |
200 | { |
201 | show_regs_print_info(KERN_DEFAULT); |
202 | dik_show_regs(regs, NULL); |
203 | } |
204 | |
205 | /* |
206 | * Re-start a thread when doing execve() |
207 | */ |
208 | void |
209 | start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) |
210 | { |
211 | regs->pc = pc; |
212 | regs->ps = 8; |
213 | wrusp(sp); |
214 | } |
215 | EXPORT_SYMBOL(start_thread); |
216 | |
217 | void |
218 | flush_thread(void) |
219 | { |
220 | /* Arrange for each exec'ed process to start off with a clean slate |
221 | with respect to the FPU. This is all exceptions disabled. */ |
222 | current_thread_info()->ieee_state = 0; |
223 | wrfpcr(FPCR_DYN_NORMAL | ieee_swcr_to_fpcr(0)); |
224 | |
225 | /* Clean slate for TLS. */ |
226 | current_thread_info()->pcb.unique = 0; |
227 | } |
228 | |
229 | /* |
230 | * Copy architecture-specific thread state |
231 | */ |
232 | int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) |
233 | { |
234 | unsigned long clone_flags = args->flags; |
235 | unsigned long usp = args->stack; |
236 | unsigned long tls = args->tls; |
237 | extern void ret_from_fork(void); |
238 | extern void ret_from_kernel_thread(void); |
239 | |
240 | struct thread_info *childti = task_thread_info(p); |
241 | struct pt_regs *childregs = task_pt_regs(p); |
242 | struct pt_regs *regs = current_pt_regs(); |
243 | struct switch_stack *childstack, *stack; |
244 | |
245 | childstack = ((struct switch_stack *) childregs) - 1; |
246 | childti->pcb.ksp = (unsigned long) childstack; |
247 | childti->pcb.flags = 1; /* set FEN, clear everything else */ |
248 | childti->status |= TS_SAVED_FP | TS_RESTORE_FP; |
249 | |
250 | if (unlikely(args->fn)) { |
251 | /* kernel thread */ |
252 | memset(childstack, 0, |
253 | sizeof(struct switch_stack) + sizeof(struct pt_regs)); |
254 | childstack->r26 = (unsigned long) ret_from_kernel_thread; |
255 | childstack->r9 = (unsigned long) args->fn; |
256 | childstack->r10 = (unsigned long) args->fn_arg; |
257 | childregs->hae = alpha_mv.hae_cache; |
258 | memset(childti->fp, '\0', sizeof(childti->fp)); |
259 | childti->pcb.usp = 0; |
260 | return 0; |
261 | } |
262 | /* Note: if CLONE_SETTLS is not set, then we must inherit the |
263 | value from the parent, which will have been set by the block |
264 | copy in dup_task_struct. This is non-intuitive, but is |
265 | required for proper operation in the case of a threaded |
266 | application calling fork. */ |
267 | if (clone_flags & CLONE_SETTLS) |
268 | childti->pcb.unique = tls; |
269 | else |
270 | regs->r20 = 0; /* OSF/1 has some strange fork() semantics. */ |
271 | childti->pcb.usp = usp ?: rdusp(); |
272 | *childregs = *regs; |
273 | childregs->r0 = 0; |
274 | childregs->r19 = 0; |
275 | childregs->r20 = 1; /* OSF/1 has some strange fork() semantics. */ |
276 | stack = ((struct switch_stack *) regs) - 1; |
277 | *childstack = *stack; |
278 | childstack->r26 = (unsigned long) ret_from_fork; |
279 | return 0; |
280 | } |
281 | |
282 | /* |
283 | * Fill in the user structure for a ELF core dump. |
284 | */ |
285 | void |
286 | dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt, struct thread_info *ti) |
287 | { |
288 | /* switch stack follows right below pt_regs: */ |
289 | struct switch_stack * sw = ((struct switch_stack *) pt) - 1; |
290 | |
291 | dest[ 0] = pt->r0; |
292 | dest[ 1] = pt->r1; |
293 | dest[ 2] = pt->r2; |
294 | dest[ 3] = pt->r3; |
295 | dest[ 4] = pt->r4; |
296 | dest[ 5] = pt->r5; |
297 | dest[ 6] = pt->r6; |
298 | dest[ 7] = pt->r7; |
299 | dest[ 8] = pt->r8; |
300 | dest[ 9] = sw->r9; |
301 | dest[10] = sw->r10; |
302 | dest[11] = sw->r11; |
303 | dest[12] = sw->r12; |
304 | dest[13] = sw->r13; |
305 | dest[14] = sw->r14; |
306 | dest[15] = sw->r15; |
307 | dest[16] = pt->r16; |
308 | dest[17] = pt->r17; |
309 | dest[18] = pt->r18; |
310 | dest[19] = pt->r19; |
311 | dest[20] = pt->r20; |
312 | dest[21] = pt->r21; |
313 | dest[22] = pt->r22; |
314 | dest[23] = pt->r23; |
315 | dest[24] = pt->r24; |
316 | dest[25] = pt->r25; |
317 | dest[26] = pt->r26; |
318 | dest[27] = pt->r27; |
319 | dest[28] = pt->r28; |
320 | dest[29] = pt->gp; |
321 | dest[30] = ti == current_thread_info() ? rdusp() : ti->pcb.usp; |
322 | dest[31] = pt->pc; |
323 | |
324 | /* Once upon a time this was the PS value. Which is stupid |
325 | since that is always 8 for usermode. Usurped for the more |
326 | useful value of the thread's UNIQUE field. */ |
327 | dest[32] = ti->pcb.unique; |
328 | } |
329 | EXPORT_SYMBOL(dump_elf_thread); |
330 | |
331 | int |
332 | dump_elf_task(elf_greg_t *dest, struct task_struct *task) |
333 | { |
334 | dump_elf_thread(dest, task_pt_regs(task), task_thread_info(task)); |
335 | return 1; |
336 | } |
337 | EXPORT_SYMBOL(dump_elf_task); |
338 | |
339 | int elf_core_copy_task_fpregs(struct task_struct *t, elf_fpregset_t *fpu) |
340 | { |
341 | memcpy(fpu, task_thread_info(t)->fp, 32 * 8); |
342 | return 1; |
343 | } |
344 | |
345 | /* |
346 | * Return saved PC of a blocked thread. This assumes the frame |
347 | * pointer is the 6th saved long on the kernel stack and that the |
348 | * saved return address is the first long in the frame. This all |
349 | * holds provided the thread blocked through a call to schedule() ($15 |
350 | * is the frame pointer in schedule() and $15 is saved at offset 48 by |
351 | * entry.S:do_switch_stack). |
352 | * |
353 | * Under heavy swap load I've seen this lose in an ugly way. So do |
354 | * some extra sanity checking on the ranges we expect these pointers |
355 | * to be in so that we can fail gracefully. This is just for ps after |
356 | * all. -- r~ |
357 | */ |
358 | |
359 | static unsigned long |
360 | thread_saved_pc(struct task_struct *t) |
361 | { |
362 | unsigned long base = (unsigned long)task_stack_page(task: t); |
363 | unsigned long fp, sp = task_thread_info(t)->pcb.ksp; |
364 | |
365 | if (sp > base && sp+6*8 < base + 16*1024) { |
366 | fp = ((unsigned long*)sp)[6]; |
367 | if (fp > sp && fp < base + 16*1024) |
368 | return *(unsigned long *)fp; |
369 | } |
370 | |
371 | return 0; |
372 | } |
373 | |
374 | unsigned long |
375 | __get_wchan(struct task_struct *p) |
376 | { |
377 | unsigned long schedule_frame; |
378 | unsigned long pc; |
379 | |
380 | /* |
381 | * This one depends on the frame size of schedule(). Do a |
382 | * "disass schedule" in gdb to find the frame size. Also, the |
383 | * code assumes that sleep_on() follows immediately after |
384 | * interruptible_sleep_on() and that add_timer() follows |
385 | * immediately after interruptible_sleep(). Ugly, isn't it? |
386 | * Maybe adding a wchan field to task_struct would be better, |
387 | * after all... |
388 | */ |
389 | |
390 | pc = thread_saved_pc(t: p); |
391 | if (in_sched_functions(addr: pc)) { |
392 | schedule_frame = ((unsigned long *)task_thread_info(p)->pcb.ksp)[6]; |
393 | return ((unsigned long *)schedule_frame)[12]; |
394 | } |
395 | return pc; |
396 | } |
397 | |