process.c 13.3 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12
/*
 *  linux/arch/arm/kernel/process.c
 *
 *  Copyright (C) 1996-2000 Russell King - Converted to ARM.
 *  Original Copyright (C) 1995  Linus Torvalds
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <stdarg.h>

13
#include <linux/export.h>
L
Linus Torvalds 已提交
14 15 16 17 18 19 20 21 22 23 24
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/user.h>
#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/interrupt.h>
#include <linux/kallsyms.h>
#include <linux/init.h>
25
#include <linux/cpu.h>
26
#include <linux/elfcore.h>
27
#include <linux/pm.h>
28
#include <linux/tick.h>
29
#include <linux/utsname.h>
30
#include <linux/uaccess.h>
31
#include <linux/random.h>
32
#include <linux/hw_breakpoint.h>
33
#include <linux/leds.h>
34
#include <linux/reboot.h>
L
Linus Torvalds 已提交
35

36
#include <asm/cacheflush.h>
37
#include <asm/idmap.h>
L
Linus Torvalds 已提交
38
#include <asm/processor.h>
39
#include <asm/thread_notify.h>
40
#include <asm/stacktrace.h>
41
#include <asm/system_misc.h>
42
#include <asm/mach/time.h>
43
#include <asm/tls.h>
R
Russell King 已提交
44
#include "reboot.h"
L
Linus Torvalds 已提交
45

46 47 48 49 50 51
#ifdef CONFIG_CC_STACKPROTECTOR
#include <linux/stackprotector.h>
unsigned long __stack_chk_guard __read_mostly;
EXPORT_SYMBOL(__stack_chk_guard);
#endif

52
static const char *processor_modes[] __maybe_unused = {
53 54
  "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
  "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
55 56
  "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "MON_32" , "ABT_32" ,
  "UK8_32" , "UK9_32" , "HYP_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
57 58
};

59
static const char *isa_modes[] __maybe_unused = {
60 61 62
  "ARM" , "Thumb" , "Jazelle", "ThumbEE"
};

63 64 65 66 67 68 69 70 71 72 73 74 75
extern void call_with_stack(void (*fn)(void *), void *arg, void *sp);
typedef void (*phys_reset_t)(unsigned long);

/*
 * A temporary stack to use for CPU reset. This is static so that we
 * don't clobber it with the identity mapping. When running with this
 * stack, any references to the current task *will not work* so you
 * should really do as little as possible before jumping to your reset
 * code.
 */
static u64 soft_restart_stack[16];

static void __soft_restart(void *addr)
76
{
77
	phys_reset_t phys_reset;
78

79
	/* Take out a flat memory mapping. */
80
	setup_mm_for_reboot();
81

82 83 84 85 86 87 88 89 90
	/* Clean and invalidate caches */
	flush_cache_all();

	/* Turn off caching */
	cpu_proc_fin();

	/* Push out any further dirty data, and ensure cache is empty */
	flush_cache_all();

91 92 93
	/* Switch to the identity mapping. */
	phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset);
	phys_reset((unsigned long)addr);
94

95 96 97 98
	/* Should never get here. */
	BUG();
}

R
Russell King 已提交
99
void _soft_restart(unsigned long addr, bool disable_l2)
100 101 102 103
{
	u64 *stack = soft_restart_stack + ARRAY_SIZE(soft_restart_stack);

	/* Disable interrupts first */
104
	raw_local_irq_disable();
105 106 107
	local_fiq_disable();

	/* Disable the L2 if we're the last man standing. */
R
Russell King 已提交
108
	if (disable_l2)
109 110 111 112 113 114 115
		outer_disable();

	/* Change to the new stack and continue with the reset. */
	call_with_stack(__soft_restart, (void *)addr, (void *)stack);

	/* Should never get here. */
	BUG();
116 117
}

R
Russell King 已提交
118 119 120 121 122
void soft_restart(unsigned long addr)
{
	_soft_restart(addr, num_online_cpus() == 1);
}

L
Linus Torvalds 已提交
123
/*
124
 * Function pointers to optional machine specific functions
L
Linus Torvalds 已提交
125 126 127 128
 */
void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);

129
void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
130

L
Linus Torvalds 已提交
131
/*
N
Nicolas Pitre 已提交
132
 * This is our default idle handler.
L
Linus Torvalds 已提交
133
 */
N
Nicolas Pitre 已提交
134 135 136

void (*arm_pm_idle)(void);

137 138 139 140 141
/*
 * Called from the core idle loop.
 */

void arch_cpu_idle(void)
L
Linus Torvalds 已提交
142
{
N
Nicolas Pitre 已提交
143 144 145
	if (arm_pm_idle)
		arm_pm_idle();
	else
N
Nicolas Pitre 已提交
146
		cpu_do_idle();
147
	local_irq_enable();
L
Linus Torvalds 已提交
148 149
}

T
Thomas Gleixner 已提交
150
void arch_cpu_idle_prepare(void)
L
Linus Torvalds 已提交
151 152
{
	local_fiq_enable();
T
Thomas Gleixner 已提交
153
}
L
Linus Torvalds 已提交
154

T
Thomas Gleixner 已提交
155 156 157 158 159
void arch_cpu_idle_enter(void)
{
	ledtrig_cpu(CPU_LED_IDLE_START);
#ifdef CONFIG_PL310_ERRATA_769419
	wmb();
160
#endif
T
Thomas Gleixner 已提交
161
}
162

T
Thomas Gleixner 已提交
163 164 165 166 167 168 169 170 171 172
void arch_cpu_idle_exit(void)
{
	ledtrig_cpu(CPU_LED_IDLE_END);
}

#ifdef CONFIG_HOTPLUG_CPU
void arch_cpu_idle_dead(void)
{
	cpu_die();
}
173
#endif
T
Thomas Gleixner 已提交
174

175 176 177 178 179 180 181 182 183
/*
 * Called by kexec, immediately prior to machine_kexec().
 *
 * This must completely disable all secondary CPUs; simply causing those CPUs
 * to execute e.g. a RAM-based pin loop is not sufficient. This allows the
 * kexec'd kernel to use any and all RAM as it sees fit, without having to
 * avoid any code or data used by any SW CPU pin loop. The CPU hotplug
 * functionality embodied in disable_nonboot_cpus() to achieve this.
 */
184
void machine_shutdown(void)
L
Linus Torvalds 已提交
185
{
186
	disable_nonboot_cpus();
L
Linus Torvalds 已提交
187 188
}

189 190 191 192 193
/*
 * Halting simply requires that the secondary CPUs stop performing any
 * activity (executing tasks, handling interrupts). smp_send_stop()
 * achieves this.
 */
194 195
void machine_halt(void)
{
196
	local_irq_disable();
197 198
	smp_send_stop();

199
	local_irq_disable();
200 201
	while (1);
}
L
Linus Torvalds 已提交
202

203 204 205 206 207 208
/*
 * Power-off simply requires that the secondary CPUs stop performing any
 * activity (executing tasks, handling interrupts). smp_send_stop()
 * achieves this. When the system power is turned off, it will take all CPUs
 * with it.
 */
L
Linus Torvalds 已提交
209 210
void machine_power_off(void)
{
211
	local_irq_disable();
212 213
	smp_send_stop();

L
Linus Torvalds 已提交
214 215 216 217
	if (pm_power_off)
		pm_power_off();
}

218 219 220 221 222 223 224 225 226 227 228
/*
 * Restart requires that the secondary CPUs stop performing any activity
 * while the primary CPU resets the system. Systems with a single CPU can
 * use soft_restart() as their machine descriptor's .restart hook, since that
 * will cause the only available CPU to reset. Systems with multiple CPUs must
 * provide a HW restart implementation, to ensure that all CPUs reset at once.
 * This is required so that any code running after reset on the primary CPU
 * doesn't have to co-ordinate with other CPUs to ensure they aren't still
 * executing pre-reset code, and using RAM that the primary CPU's code wishes
 * to use. Implementing such co-ordination would be essentially impossible.
 */
229
void machine_restart(char *cmd)
L
Linus Torvalds 已提交
230
{
231
	local_irq_disable();
232
	smp_send_stop();
233

234 235 236 237
	if (arm_pm_restart)
		arm_pm_restart(reboot_mode, cmd);
	else
		do_kernel_restart(cmd);
238 239 240 241 242 243

	/* Give a grace period for failure to restart of 1s */
	mdelay(1000);

	/* Whoops - the platform was unable to reboot. Tell the user! */
	printk("Reboot failed -- System halted\n");
244
	local_irq_disable();
245
	while (1);
L
Linus Torvalds 已提交
246 247
}

R
Russell King 已提交
248
void __show_regs(struct pt_regs *regs)
L
Linus Torvalds 已提交
249
{
250 251
	unsigned long flags;
	char buf[64];
L
Linus Torvalds 已提交
252

253 254
	show_regs_print_info(KERN_DEFAULT);

L
Linus Torvalds 已提交
255 256
	print_symbol("PC is at %s\n", instruction_pointer(regs));
	print_symbol("LR is at %s\n", regs->ARM_lr);
257
	printk("pc : [<%08lx>]    lr : [<%08lx>]    psr: %08lx\n"
L
Linus Torvalds 已提交
258
	       "sp : %08lx  ip : %08lx  fp : %08lx\n",
259 260
		regs->ARM_pc, regs->ARM_lr, regs->ARM_cpsr,
		regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
L
Linus Torvalds 已提交
261 262 263 264 265 266 267 268 269
	printk("r10: %08lx  r9 : %08lx  r8 : %08lx\n",
		regs->ARM_r10, regs->ARM_r9,
		regs->ARM_r8);
	printk("r7 : %08lx  r6 : %08lx  r5 : %08lx  r4 : %08lx\n",
		regs->ARM_r7, regs->ARM_r6,
		regs->ARM_r5, regs->ARM_r4);
	printk("r3 : %08lx  r2 : %08lx  r1 : %08lx  r0 : %08lx\n",
		regs->ARM_r3, regs->ARM_r2,
		regs->ARM_r1, regs->ARM_r0);
270 271 272 273 274 275 276 277

	flags = regs->ARM_cpsr;
	buf[0] = flags & PSR_N_BIT ? 'N' : 'n';
	buf[1] = flags & PSR_Z_BIT ? 'Z' : 'z';
	buf[2] = flags & PSR_C_BIT ? 'C' : 'c';
	buf[3] = flags & PSR_V_BIT ? 'V' : 'v';
	buf[4] = '\0';

278
#ifndef CONFIG_CPU_V7M
279
	printk("Flags: %s  IRQs o%s  FIQs o%s  Mode %s  ISA %s  Segment %s\n",
280
		buf, interrupts_enabled(regs) ? "n" : "ff",
L
Linus Torvalds 已提交
281 282
		fast_interrupts_enabled(regs) ? "n" : "ff",
		processor_modes[processor_mode(regs)],
283
		isa_modes[isa_mode(regs)],
L
Linus Torvalds 已提交
284
		get_fs() == get_ds() ? "kernel" : "user");
285 286 287 288
#else
	printk("xPSR: %08lx\n", regs->ARM_cpsr);
#endif

289
#ifdef CONFIG_CPU_CP15
L
Linus Torvalds 已提交
290
	{
291
		unsigned int ctrl;
292 293

		buf[0] = '\0';
294
#ifdef CONFIG_CPU_CP15_MMU
295 296 297 298 299 300 301 302
		{
			unsigned int transbase, dac;
			asm("mrc p15, 0, %0, c2, c0\n\t"
			    "mrc p15, 0, %1, c3, c0\n"
			    : "=r" (transbase), "=r" (dac));
			snprintf(buf, sizeof(buf), "  Table: %08x  DAC: %08x",
			  	transbase, dac);
		}
303
#endif
304 305 306 307
		asm("mrc p15, 0, %0, c1, c0\n" : "=r" (ctrl));

		printk("Control: %08x%s\n", ctrl, buf);
	}
308
#endif
L
Linus Torvalds 已提交
309 310
}

R
Russell King 已提交
311 312 313
void show_regs(struct pt_regs * regs)
{
	__show_regs(regs);
314
	dump_stack();
R
Russell King 已提交
315 316
}

317 318 319 320
ATOMIC_NOTIFIER_HEAD(thread_notify_head);

EXPORT_SYMBOL_GPL(thread_notify_head);

L
Linus Torvalds 已提交
321 322 323 324 325
/*
 * Free current thread data structures etc..
 */
void exit_thread(void)
{
326
	thread_notify(THREAD_NOTIFY_EXIT, current_thread_info());
L
Linus Torvalds 已提交
327 328 329 330 331 332 333
}

void flush_thread(void)
{
	struct thread_info *thread = current_thread_info();
	struct task_struct *tsk = current;

334 335
	flush_ptrace_hw_breakpoint(tsk);

L
Linus Torvalds 已提交
336 337
	memset(thread->used_cp, 0, sizeof(thread->used_cp));
	memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
338 339
	memset(&thread->fpstate, 0, sizeof(union fp_state));

340 341
	flush_tls();

342
	thread_notify(THREAD_NOTIFY_FLUSH, thread);
L
Linus Torvalds 已提交
343 344 345 346 347 348 349 350 351
}

void release_thread(struct task_struct *dead_task)
{
}

asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");

int
A
Alexey Dobriyan 已提交
352
copy_thread(unsigned long clone_flags, unsigned long stack_start,
353
	    unsigned long stk_sz, struct task_struct *p)
L
Linus Torvalds 已提交
354
{
A
Al Viro 已提交
355 356
	struct thread_info *thread = task_thread_info(p);
	struct pt_regs *childregs = task_pt_regs(p);
L
Linus Torvalds 已提交
357 358

	memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
359

A
Al Viro 已提交
360 361
	if (likely(!(p->flags & PF_KTHREAD))) {
		*childregs = *current_pt_regs();
362
		childregs->ARM_r0 = 0;
A
Al Viro 已提交
363 364
		if (stack_start)
			childregs->ARM_sp = stack_start;
365
	} else {
366
		memset(childregs, 0, sizeof(struct pt_regs));
367 368 369 370
		thread->cpu_context.r4 = stk_sz;
		thread->cpu_context.r5 = stack_start;
		childregs->ARM_cpsr = SVC_MODE;
	}
371
	thread->cpu_context.pc = (unsigned long)ret_from_fork;
L
Linus Torvalds 已提交
372 373
	thread->cpu_context.sp = (unsigned long)childregs;

374 375
	clear_ptrace_hw_breakpoint(p);

L
Linus Torvalds 已提交
376
	if (clone_flags & CLONE_SETTLS)
377 378
		thread->tp_value[0] = childregs->ARM_r3;
	thread->tp_value[1] = get_tpuser();
L
Linus Torvalds 已提交
379

380 381
	thread_notify(THREAD_NOTIFY_COPY, thread);

L
Linus Torvalds 已提交
382 383 384
	return 0;
}

385 386 387 388 389 390 391 392 393
/*
 * Fill in the task's elfregs structure for a core dump.
 */
int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs)
{
	elf_core_copy_regs(elfregs, task_pt_regs(t));
	return 1;
}

L
Linus Torvalds 已提交
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
/*
 * fill in the fpe structure for a core dump...
 */
int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
{
	struct thread_info *thread = current_thread_info();
	int used_math = thread->used_cp[1] | thread->used_cp[2];

	if (used_math)
		memcpy(fp, &thread->fpstate.soft, sizeof (*fp));

	return used_math != 0;
}
EXPORT_SYMBOL(dump_fpu);

unsigned long get_wchan(struct task_struct *p)
{
411
	struct stackframe frame;
412
	unsigned long stack_page;
L
Linus Torvalds 已提交
413 414 415 416
	int count = 0;
	if (!p || p == current || p->state == TASK_RUNNING)
		return 0;

417 418 419 420
	frame.fp = thread_saved_fp(p);
	frame.sp = thread_saved_sp(p);
	frame.lr = 0;			/* recovered from the stack */
	frame.pc = thread_saved_pc(p);
421
	stack_page = (unsigned long)task_stack_page(p);
L
Linus Torvalds 已提交
422
	do {
423 424 425
		if (frame.sp < stack_page ||
		    frame.sp >= stack_page + THREAD_SIZE ||
		    unwind_frame(&frame) < 0)
L
Linus Torvalds 已提交
426
			return 0;
427 428
		if (!in_sched_functions(frame.pc))
			return frame.pc;
L
Linus Torvalds 已提交
429 430 431
	} while (count ++ < 16);
	return 0;
}
432 433 434 435 436 437

unsigned long arch_randomize_brk(struct mm_struct *mm)
{
	unsigned long range_end = mm->brk + 0x02000000;
	return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
}
438

439
#ifdef CONFIG_MMU
440
#ifdef CONFIG_KUSER_HELPERS
441 442
/*
 * The vectors page is always readable from user space for the
443 444
 * atomic helpers. Insert it into the gate_vma so that it is visible
 * through ptrace and /proc/<pid>/mem.
445
 */
446 447 448 449 450
static struct vm_area_struct gate_vma = {
	.vm_start	= 0xffff0000,
	.vm_end		= 0xffff0000 + PAGE_SIZE,
	.vm_flags	= VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC,
};
451

452
static int __init gate_vma_init(void)
453
{
454
	gate_vma.vm_page_prot = PAGE_READONLY_EXEC;
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
	return 0;
}
arch_initcall(gate_vma_init);

struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
{
	return &gate_vma;
}

int in_gate_area(struct mm_struct *mm, unsigned long addr)
{
	return (addr >= gate_vma.vm_start) && (addr < gate_vma.vm_end);
}

int in_gate_area_no_mm(unsigned long addr)
{
	return in_gate_area(NULL, addr);
472
}
473
#define is_gate_vma(vma)	((vma) == &gate_vma)
474 475 476
#else
#define is_gate_vma(vma)	0
#endif
477 478 479

const char *arch_vma_name(struct vm_area_struct *vma)
{
480
	return is_gate_vma(vma) ? "[vectors]" : NULL;
481 482
}

483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513
/* If possible, provide a placement hint at a random offset from the
 * stack for the signal page.
 */
static unsigned long sigpage_addr(const struct mm_struct *mm,
				  unsigned int npages)
{
	unsigned long offset;
	unsigned long first;
	unsigned long last;
	unsigned long addr;
	unsigned int slots;

	first = PAGE_ALIGN(mm->start_stack);

	last = TASK_SIZE - (npages << PAGE_SHIFT);

	/* No room after stack? */
	if (first > last)
		return 0;

	/* Just enough room? */
	if (first == last)
		return first;

	slots = ((last - first) >> PAGE_SHIFT) + 1;

	offset = get_random_int() % slots;

	addr = first + (offset << PAGE_SHIFT);

	return addr;
514 515
}

516
static struct page *signal_page;
517 518
extern struct page *get_signal_page(void);

519 520 521 522 523
static const struct vm_special_mapping sigpage_mapping = {
	.name = "[sigpage]",
	.pages = &signal_page,
};

524 525 526
int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
{
	struct mm_struct *mm = current->mm;
527
	struct vm_area_struct *vma;
528
	unsigned long addr;
529
	unsigned long hint;
530
	int ret = 0;
531

532 533 534
	if (!signal_page)
		signal_page = get_signal_page();
	if (!signal_page)
535 536 537
		return -ENOMEM;

	down_write(&mm->mmap_sem);
538 539
	hint = sigpage_addr(mm, 1);
	addr = get_unmapped_area(NULL, hint, PAGE_SIZE, 0, 0);
540 541 542 543 544
	if (IS_ERR_VALUE(addr)) {
		ret = addr;
		goto up_fail;
	}

545
	vma = _install_special_mapping(mm, addr, PAGE_SIZE,
546
		VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
547 548 549 550 551 552
		&sigpage_mapping);

	if (IS_ERR(vma)) {
		ret = PTR_ERR(vma);
		goto up_fail;
	}
553

554
	mm->context.sigpage = addr;
555 556 557 558

 up_fail:
	up_write(&mm->mmap_sem);
	return ret;
559
}
560
#endif