process.c 10.6 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
#include <linux/sched.h>
15
#include <linux/sched/debug.h>
16
#include <linux/sched/task.h>
17
#include <linux/sched/task_stack.h>
L
Linus Torvalds 已提交
18 19 20 21 22 23 24 25
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/user.h>
#include <linux/interrupt.h>
#include <linux/kallsyms.h>
#include <linux/init.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>
L
Linus Torvalds 已提交
34 35

#include <asm/processor.h>
36
#include <asm/thread_notify.h>
37
#include <asm/stacktrace.h>
38
#include <asm/system_misc.h>
39
#include <asm/mach/time.h>
40
#include <asm/tls.h>
41
#include <asm/vdso.h>
L
Linus Torvalds 已提交
42

43 44 45 46 47 48
#ifdef CONFIG_CC_STACKPROTECTOR
#include <linux/stackprotector.h>
unsigned long __stack_chk_guard __read_mostly;
EXPORT_SYMBOL(__stack_chk_guard);
#endif

49
static const char *processor_modes[] __maybe_unused = {
50 51
  "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",
52 53
  "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"
54 55
};

56
static const char *isa_modes[] __maybe_unused = {
57 58 59
  "ARM" , "Thumb" , "Jazelle", "ThumbEE"
};

L
Linus Torvalds 已提交
60
/*
N
Nicolas Pitre 已提交
61
 * This is our default idle handler.
L
Linus Torvalds 已提交
62
 */
N
Nicolas Pitre 已提交
63 64 65

void (*arm_pm_idle)(void);

66 67 68 69 70
/*
 * Called from the core idle loop.
 */

void arch_cpu_idle(void)
L
Linus Torvalds 已提交
71
{
N
Nicolas Pitre 已提交
72 73 74
	if (arm_pm_idle)
		arm_pm_idle();
	else
N
Nicolas Pitre 已提交
75
		cpu_do_idle();
76
	local_irq_enable();
L
Linus Torvalds 已提交
77 78
}

T
Thomas Gleixner 已提交
79
void arch_cpu_idle_prepare(void)
L
Linus Torvalds 已提交
80 81
{
	local_fiq_enable();
T
Thomas Gleixner 已提交
82
}
L
Linus Torvalds 已提交
83

T
Thomas Gleixner 已提交
84 85 86 87 88
void arch_cpu_idle_enter(void)
{
	ledtrig_cpu(CPU_LED_IDLE_START);
#ifdef CONFIG_PL310_ERRATA_769419
	wmb();
89
#endif
T
Thomas Gleixner 已提交
90
}
91

T
Thomas Gleixner 已提交
92 93 94 95 96
void arch_cpu_idle_exit(void)
{
	ledtrig_cpu(CPU_LED_IDLE_END);
}

R
Russell King 已提交
97
void __show_regs(struct pt_regs *regs)
L
Linus Torvalds 已提交
98
{
99 100
	unsigned long flags;
	char buf[64];
101
#ifndef CONFIG_CPU_V7M
102
	unsigned int domain, fs;
103 104 105 106 107 108
#ifdef CONFIG_CPU_SW_DOMAIN_PAN
	/*
	 * Get the domain register for the parent context. In user
	 * mode, we don't save the DACR, so lets use what it should
	 * be. For other modes, we place it after the pt_regs struct.
	 */
109
	if (user_mode(regs)) {
110
		domain = DACR_UACCESS_ENABLE;
111 112
		fs = get_fs();
	} else {
113
		domain = to_svc_pt_regs(regs)->dacr;
114 115
		fs = to_svc_pt_regs(regs)->addr_limit;
	}
116 117
#else
	domain = get_domain();
118
	fs = get_fs();
119 120
#endif
#endif
L
Linus Torvalds 已提交
121

122 123
	show_regs_print_info(KERN_DEFAULT);

L
Linus Torvalds 已提交
124 125
	print_symbol("PC is at %s\n", instruction_pointer(regs));
	print_symbol("LR is at %s\n", regs->ARM_lr);
126 127 128 129
	printk("pc : [<%08lx>]    lr : [<%08lx>]    psr: %08lx\n",
	       regs->ARM_pc, regs->ARM_lr, regs->ARM_cpsr);
	printk("sp : %08lx  ip : %08lx  fp : %08lx\n",
	       regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
L
Linus Torvalds 已提交
130 131 132 133 134 135 136 137 138
	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);
139 140 141 142 143 144 145 146

	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';

147
#ifndef CONFIG_CPU_V7M
148 149 150 151 152 153
	{
		const char *segment;

		if ((domain & domain_mask(DOMAIN_USER)) ==
		    domain_val(DOMAIN_USER, DOMAIN_NOACCESS))
			segment = "none";
154
		else if (fs == get_ds())
155 156 157 158 159 160 161 162 163 164
			segment = "kernel";
		else
			segment = "user";

		printk("Flags: %s  IRQs o%s  FIQs o%s  Mode %s  ISA %s  Segment %s\n",
			buf, interrupts_enabled(regs) ? "n" : "ff",
			fast_interrupts_enabled(regs) ? "n" : "ff",
			processor_modes[processor_mode(regs)],
			isa_modes[isa_mode(regs)], segment);
	}
165 166 167 168
#else
	printk("xPSR: %08lx\n", regs->ARM_cpsr);
#endif

169
#ifdef CONFIG_CPU_CP15
L
Linus Torvalds 已提交
170
	{
171
		unsigned int ctrl;
172 173

		buf[0] = '\0';
174
#ifdef CONFIG_CPU_CP15_MMU
175
		{
176
			unsigned int transbase;
177
			asm("mrc p15, 0, %0, c2, c0\n\t"
178
			    : "=r" (transbase));
179
			snprintf(buf, sizeof(buf), "  Table: %08x  DAC: %08x",
180
				transbase, domain);
181
		}
182
#endif
183 184 185 186
		asm("mrc p15, 0, %0, c1, c0\n" : "=r" (ctrl));

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

R
Russell King 已提交
190 191 192
void show_regs(struct pt_regs * regs)
{
	__show_regs(regs);
193
	dump_stack();
R
Russell King 已提交
194 195
}

196 197 198 199
ATOMIC_NOTIFIER_HEAD(thread_notify_head);

EXPORT_SYMBOL_GPL(thread_notify_head);

L
Linus Torvalds 已提交
200 201 202
/*
 * Free current thread data structures etc..
 */
203
void exit_thread(struct task_struct *tsk)
L
Linus Torvalds 已提交
204
{
205
	thread_notify(THREAD_NOTIFY_EXIT, task_thread_info(tsk));
L
Linus Torvalds 已提交
206 207 208 209 210 211 212
}

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

213 214
	flush_ptrace_hw_breakpoint(tsk);

L
Linus Torvalds 已提交
215 216
	memset(thread->used_cp, 0, sizeof(thread->used_cp));
	memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
217 218
	memset(&thread->fpstate, 0, sizeof(union fp_state));

219 220
	flush_tls();

221
	thread_notify(THREAD_NOTIFY_FLUSH, thread);
L
Linus Torvalds 已提交
222 223 224 225 226 227 228 229 230
}

void release_thread(struct task_struct *dead_task)
{
}

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

int
A
Alexey Dobriyan 已提交
231
copy_thread(unsigned long clone_flags, unsigned long stack_start,
232
	    unsigned long stk_sz, struct task_struct *p)
L
Linus Torvalds 已提交
233
{
A
Al Viro 已提交
234 235
	struct thread_info *thread = task_thread_info(p);
	struct pt_regs *childregs = task_pt_regs(p);
L
Linus Torvalds 已提交
236 237

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

239
#ifdef CONFIG_CPU_USE_DOMAINS
240 241 242 243 244 245 246
	/*
	 * Copy the initial value of the domain access control register
	 * from the current thread: thread->addr_limit will have been
	 * copied from the current thread via setup_thread_stack() in
	 * kernel/fork.c
	 */
	thread->cpu_domain = get_domain();
247
#endif
248

A
Al Viro 已提交
249 250
	if (likely(!(p->flags & PF_KTHREAD))) {
		*childregs = *current_pt_regs();
251
		childregs->ARM_r0 = 0;
A
Al Viro 已提交
252 253
		if (stack_start)
			childregs->ARM_sp = stack_start;
254
	} else {
255
		memset(childregs, 0, sizeof(struct pt_regs));
256 257 258 259
		thread->cpu_context.r4 = stk_sz;
		thread->cpu_context.r5 = stack_start;
		childregs->ARM_cpsr = SVC_MODE;
	}
260
	thread->cpu_context.pc = (unsigned long)ret_from_fork;
L
Linus Torvalds 已提交
261 262
	thread->cpu_context.sp = (unsigned long)childregs;

263 264
	clear_ptrace_hw_breakpoint(p);

L
Linus Torvalds 已提交
265
	if (clone_flags & CLONE_SETTLS)
266 267
		thread->tp_value[0] = childregs->ARM_r3;
	thread->tp_value[1] = get_tpuser();
L
Linus Torvalds 已提交
268

269 270
	thread_notify(THREAD_NOTIFY_COPY, thread);

L
Linus Torvalds 已提交
271 272 273
	return 0;
}

274 275 276 277 278 279 280 281 282
/*
 * 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 已提交
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
/*
 * 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)
{
300
	struct stackframe frame;
301
	unsigned long stack_page;
L
Linus Torvalds 已提交
302 303 304 305
	int count = 0;
	if (!p || p == current || p->state == TASK_RUNNING)
		return 0;

306 307 308 309
	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);
310
	stack_page = (unsigned long)task_stack_page(p);
L
Linus Torvalds 已提交
311
	do {
312 313 314
		if (frame.sp < stack_page ||
		    frame.sp >= stack_page + THREAD_SIZE ||
		    unwind_frame(&frame) < 0)
L
Linus Torvalds 已提交
315
			return 0;
316 317
		if (!in_sched_functions(frame.pc))
			return frame.pc;
L
Linus Torvalds 已提交
318 319 320
	} while (count ++ < 16);
	return 0;
}
321 322 323

unsigned long arch_randomize_brk(struct mm_struct *mm)
{
324
	return randomize_page(mm->brk, 0x02000000);
325
}
326

327
#ifdef CONFIG_MMU
328
#ifdef CONFIG_KUSER_HELPERS
329 330
/*
 * The vectors page is always readable from user space for the
331 332
 * atomic helpers. Insert it into the gate_vma so that it is visible
 * through ptrace and /proc/<pid>/mem.
333
 */
334 335 336 337 338
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,
};
339

340
static int __init gate_vma_init(void)
341
{
342
	gate_vma.vm_page_prot = PAGE_READONLY_EXEC;
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359
	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);
360
}
361
#define is_gate_vma(vma)	((vma) == &gate_vma)
362 363 364
#else
#define is_gate_vma(vma)	0
#endif
365 366 367

const char *arch_vma_name(struct vm_area_struct *vma)
{
368
	return is_gate_vma(vma) ? "[vectors]" : NULL;
369 370
}

371
/* If possible, provide a placement hint at a random offset from the
372
 * stack for the sigpage and vdso pages.
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
 */
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;
402 403
}

404
static struct page *signal_page;
405 406
extern struct page *get_signal_page(void);

407 408 409 410 411
static const struct vm_special_mapping sigpage_mapping = {
	.name = "[sigpage]",
	.pages = &signal_page,
};

412 413 414
int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
{
	struct mm_struct *mm = current->mm;
415
	struct vm_area_struct *vma;
416
	unsigned long npages;
417
	unsigned long addr;
418
	unsigned long hint;
419
	int ret = 0;
420

421 422 423
	if (!signal_page)
		signal_page = get_signal_page();
	if (!signal_page)
424 425
		return -ENOMEM;

426 427 428
	npages = 1; /* for sigpage */
	npages += vdso_total_pages;

429 430
	if (down_write_killable(&mm->mmap_sem))
		return -EINTR;
431 432
	hint = sigpage_addr(mm, npages);
	addr = get_unmapped_area(NULL, hint, npages << PAGE_SHIFT, 0, 0);
433 434 435 436 437
	if (IS_ERR_VALUE(addr)) {
		ret = addr;
		goto up_fail;
	}

438
	vma = _install_special_mapping(mm, addr, PAGE_SIZE,
439
		VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
440 441 442 443 444 445
		&sigpage_mapping);

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

447
	mm->context.sigpage = addr;
448

449 450 451 452 453 454
	/* Unlike the sigpage, failure to install the vdso is unlikely
	 * to be fatal to the process, so no error check needed
	 * here.
	 */
	arm_install_vdso(mm, addr + PAGE_SIZE);

455 456 457
 up_fail:
	up_write(&mm->mmap_sem);
	return ret;
458
}
459
#endif