xref: /linux/arch/powerpc/kernel/process.c (revision c6622f63db86fcbd41bf6fe05ddf2e00c1e51ced)
114cf11afSPaul Mackerras /*
214cf11afSPaul Mackerras  *  Derived from "arch/i386/kernel/process.c"
314cf11afSPaul Mackerras  *    Copyright (C) 1995  Linus Torvalds
414cf11afSPaul Mackerras  *
514cf11afSPaul Mackerras  *  Updated and modified by Cort Dougan (cort@cs.nmt.edu) and
614cf11afSPaul Mackerras  *  Paul Mackerras (paulus@cs.anu.edu.au)
714cf11afSPaul Mackerras  *
814cf11afSPaul Mackerras  *  PowerPC version
914cf11afSPaul Mackerras  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
1014cf11afSPaul Mackerras  *
1114cf11afSPaul Mackerras  *  This program is free software; you can redistribute it and/or
1214cf11afSPaul Mackerras  *  modify it under the terms of the GNU General Public License
1314cf11afSPaul Mackerras  *  as published by the Free Software Foundation; either version
1414cf11afSPaul Mackerras  *  2 of the License, or (at your option) any later version.
1514cf11afSPaul Mackerras  */
1614cf11afSPaul Mackerras 
1714cf11afSPaul Mackerras #include <linux/config.h>
1814cf11afSPaul Mackerras #include <linux/errno.h>
1914cf11afSPaul Mackerras #include <linux/sched.h>
2014cf11afSPaul Mackerras #include <linux/kernel.h>
2114cf11afSPaul Mackerras #include <linux/mm.h>
2214cf11afSPaul Mackerras #include <linux/smp.h>
2314cf11afSPaul Mackerras #include <linux/smp_lock.h>
2414cf11afSPaul Mackerras #include <linux/stddef.h>
2514cf11afSPaul Mackerras #include <linux/unistd.h>
2614cf11afSPaul Mackerras #include <linux/ptrace.h>
2714cf11afSPaul Mackerras #include <linux/slab.h>
2814cf11afSPaul Mackerras #include <linux/user.h>
2914cf11afSPaul Mackerras #include <linux/elf.h>
3014cf11afSPaul Mackerras #include <linux/init.h>
3114cf11afSPaul Mackerras #include <linux/prctl.h>
3214cf11afSPaul Mackerras #include <linux/init_task.h>
3314cf11afSPaul Mackerras #include <linux/module.h>
3414cf11afSPaul Mackerras #include <linux/kallsyms.h>
3514cf11afSPaul Mackerras #include <linux/mqueue.h>
3614cf11afSPaul Mackerras #include <linux/hardirq.h>
3706d67d54SPaul Mackerras #include <linux/utsname.h>
3806d67d54SPaul Mackerras #include <linux/kprobes.h>
3914cf11afSPaul Mackerras 
4014cf11afSPaul Mackerras #include <asm/pgtable.h>
4114cf11afSPaul Mackerras #include <asm/uaccess.h>
4214cf11afSPaul Mackerras #include <asm/system.h>
4314cf11afSPaul Mackerras #include <asm/io.h>
4414cf11afSPaul Mackerras #include <asm/processor.h>
4514cf11afSPaul Mackerras #include <asm/mmu.h>
4614cf11afSPaul Mackerras #include <asm/prom.h>
4776032de8SMichael Ellerman #include <asm/machdep.h>
48*c6622f63SPaul Mackerras #include <asm/time.h>
4906d67d54SPaul Mackerras #ifdef CONFIG_PPC64
5006d67d54SPaul Mackerras #include <asm/firmware.h>
5106d67d54SPaul Mackerras #endif
5214cf11afSPaul Mackerras 
5314cf11afSPaul Mackerras extern unsigned long _get_SP(void);
5414cf11afSPaul Mackerras 
5514cf11afSPaul Mackerras #ifndef CONFIG_SMP
5614cf11afSPaul Mackerras struct task_struct *last_task_used_math = NULL;
5714cf11afSPaul Mackerras struct task_struct *last_task_used_altivec = NULL;
5814cf11afSPaul Mackerras struct task_struct *last_task_used_spe = NULL;
5914cf11afSPaul Mackerras #endif
6014cf11afSPaul Mackerras 
6114cf11afSPaul Mackerras /*
6214cf11afSPaul Mackerras  * Make sure the floating-point register state in the
6314cf11afSPaul Mackerras  * the thread_struct is up to date for task tsk.
6414cf11afSPaul Mackerras  */
6514cf11afSPaul Mackerras void flush_fp_to_thread(struct task_struct *tsk)
6614cf11afSPaul Mackerras {
6714cf11afSPaul Mackerras 	if (tsk->thread.regs) {
6814cf11afSPaul Mackerras 		/*
6914cf11afSPaul Mackerras 		 * We need to disable preemption here because if we didn't,
7014cf11afSPaul Mackerras 		 * another process could get scheduled after the regs->msr
7114cf11afSPaul Mackerras 		 * test but before we have finished saving the FP registers
7214cf11afSPaul Mackerras 		 * to the thread_struct.  That process could take over the
7314cf11afSPaul Mackerras 		 * FPU, and then when we get scheduled again we would store
7414cf11afSPaul Mackerras 		 * bogus values for the remaining FP registers.
7514cf11afSPaul Mackerras 		 */
7614cf11afSPaul Mackerras 		preempt_disable();
7714cf11afSPaul Mackerras 		if (tsk->thread.regs->msr & MSR_FP) {
7814cf11afSPaul Mackerras #ifdef CONFIG_SMP
7914cf11afSPaul Mackerras 			/*
8014cf11afSPaul Mackerras 			 * This should only ever be called for current or
8114cf11afSPaul Mackerras 			 * for a stopped child process.  Since we save away
8214cf11afSPaul Mackerras 			 * the FP register state on context switch on SMP,
8314cf11afSPaul Mackerras 			 * there is something wrong if a stopped child appears
8414cf11afSPaul Mackerras 			 * to still have its FP state in the CPU registers.
8514cf11afSPaul Mackerras 			 */
8614cf11afSPaul Mackerras 			BUG_ON(tsk != current);
8714cf11afSPaul Mackerras #endif
8814cf11afSPaul Mackerras 			giveup_fpu(current);
8914cf11afSPaul Mackerras 		}
9014cf11afSPaul Mackerras 		preempt_enable();
9114cf11afSPaul Mackerras 	}
9214cf11afSPaul Mackerras }
9314cf11afSPaul Mackerras 
9414cf11afSPaul Mackerras void enable_kernel_fp(void)
9514cf11afSPaul Mackerras {
9614cf11afSPaul Mackerras 	WARN_ON(preemptible());
9714cf11afSPaul Mackerras 
9814cf11afSPaul Mackerras #ifdef CONFIG_SMP
9914cf11afSPaul Mackerras 	if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
10014cf11afSPaul Mackerras 		giveup_fpu(current);
10114cf11afSPaul Mackerras 	else
10214cf11afSPaul Mackerras 		giveup_fpu(NULL);	/* just enables FP for kernel */
10314cf11afSPaul Mackerras #else
10414cf11afSPaul Mackerras 	giveup_fpu(last_task_used_math);
10514cf11afSPaul Mackerras #endif /* CONFIG_SMP */
10614cf11afSPaul Mackerras }
10714cf11afSPaul Mackerras EXPORT_SYMBOL(enable_kernel_fp);
10814cf11afSPaul Mackerras 
10914cf11afSPaul Mackerras int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
11014cf11afSPaul Mackerras {
11114cf11afSPaul Mackerras 	if (!tsk->thread.regs)
11214cf11afSPaul Mackerras 		return 0;
11314cf11afSPaul Mackerras 	flush_fp_to_thread(current);
11414cf11afSPaul Mackerras 
11514cf11afSPaul Mackerras 	memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs));
11614cf11afSPaul Mackerras 
11714cf11afSPaul Mackerras 	return 1;
11814cf11afSPaul Mackerras }
11914cf11afSPaul Mackerras 
12014cf11afSPaul Mackerras #ifdef CONFIG_ALTIVEC
12114cf11afSPaul Mackerras void enable_kernel_altivec(void)
12214cf11afSPaul Mackerras {
12314cf11afSPaul Mackerras 	WARN_ON(preemptible());
12414cf11afSPaul Mackerras 
12514cf11afSPaul Mackerras #ifdef CONFIG_SMP
12614cf11afSPaul Mackerras 	if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
12714cf11afSPaul Mackerras 		giveup_altivec(current);
12814cf11afSPaul Mackerras 	else
12914cf11afSPaul Mackerras 		giveup_altivec(NULL);	/* just enable AltiVec for kernel - force */
13014cf11afSPaul Mackerras #else
13114cf11afSPaul Mackerras 	giveup_altivec(last_task_used_altivec);
13214cf11afSPaul Mackerras #endif /* CONFIG_SMP */
13314cf11afSPaul Mackerras }
13414cf11afSPaul Mackerras EXPORT_SYMBOL(enable_kernel_altivec);
13514cf11afSPaul Mackerras 
13614cf11afSPaul Mackerras /*
13714cf11afSPaul Mackerras  * Make sure the VMX/Altivec register state in the
13814cf11afSPaul Mackerras  * the thread_struct is up to date for task tsk.
13914cf11afSPaul Mackerras  */
14014cf11afSPaul Mackerras void flush_altivec_to_thread(struct task_struct *tsk)
14114cf11afSPaul Mackerras {
14214cf11afSPaul Mackerras 	if (tsk->thread.regs) {
14314cf11afSPaul Mackerras 		preempt_disable();
14414cf11afSPaul Mackerras 		if (tsk->thread.regs->msr & MSR_VEC) {
14514cf11afSPaul Mackerras #ifdef CONFIG_SMP
14614cf11afSPaul Mackerras 			BUG_ON(tsk != current);
14714cf11afSPaul Mackerras #endif
14814cf11afSPaul Mackerras 			giveup_altivec(current);
14914cf11afSPaul Mackerras 		}
15014cf11afSPaul Mackerras 		preempt_enable();
15114cf11afSPaul Mackerras 	}
15214cf11afSPaul Mackerras }
15314cf11afSPaul Mackerras 
15414cf11afSPaul Mackerras int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
15514cf11afSPaul Mackerras {
15614cf11afSPaul Mackerras 	flush_altivec_to_thread(current);
15714cf11afSPaul Mackerras 	memcpy(vrregs, &current->thread.vr[0], sizeof(*vrregs));
15814cf11afSPaul Mackerras 	return 1;
15914cf11afSPaul Mackerras }
16014cf11afSPaul Mackerras #endif /* CONFIG_ALTIVEC */
16114cf11afSPaul Mackerras 
16214cf11afSPaul Mackerras #ifdef CONFIG_SPE
16314cf11afSPaul Mackerras 
16414cf11afSPaul Mackerras void enable_kernel_spe(void)
16514cf11afSPaul Mackerras {
16614cf11afSPaul Mackerras 	WARN_ON(preemptible());
16714cf11afSPaul Mackerras 
16814cf11afSPaul Mackerras #ifdef CONFIG_SMP
16914cf11afSPaul Mackerras 	if (current->thread.regs && (current->thread.regs->msr & MSR_SPE))
17014cf11afSPaul Mackerras 		giveup_spe(current);
17114cf11afSPaul Mackerras 	else
17214cf11afSPaul Mackerras 		giveup_spe(NULL);	/* just enable SPE for kernel - force */
17314cf11afSPaul Mackerras #else
17414cf11afSPaul Mackerras 	giveup_spe(last_task_used_spe);
17514cf11afSPaul Mackerras #endif /* __SMP __ */
17614cf11afSPaul Mackerras }
17714cf11afSPaul Mackerras EXPORT_SYMBOL(enable_kernel_spe);
17814cf11afSPaul Mackerras 
17914cf11afSPaul Mackerras void flush_spe_to_thread(struct task_struct *tsk)
18014cf11afSPaul Mackerras {
18114cf11afSPaul Mackerras 	if (tsk->thread.regs) {
18214cf11afSPaul Mackerras 		preempt_disable();
18314cf11afSPaul Mackerras 		if (tsk->thread.regs->msr & MSR_SPE) {
18414cf11afSPaul Mackerras #ifdef CONFIG_SMP
18514cf11afSPaul Mackerras 			BUG_ON(tsk != current);
18614cf11afSPaul Mackerras #endif
18714cf11afSPaul Mackerras 			giveup_spe(current);
18814cf11afSPaul Mackerras 		}
18914cf11afSPaul Mackerras 		preempt_enable();
19014cf11afSPaul Mackerras 	}
19114cf11afSPaul Mackerras }
19214cf11afSPaul Mackerras 
19314cf11afSPaul Mackerras int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
19414cf11afSPaul Mackerras {
19514cf11afSPaul Mackerras 	flush_spe_to_thread(current);
19614cf11afSPaul Mackerras 	/* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */
19714cf11afSPaul Mackerras 	memcpy(evrregs, &current->thread.evr[0], sizeof(u32) * 35);
19814cf11afSPaul Mackerras 	return 1;
19914cf11afSPaul Mackerras }
20014cf11afSPaul Mackerras #endif /* CONFIG_SPE */
20114cf11afSPaul Mackerras 
2025388fb10SPaul Mackerras #ifndef CONFIG_SMP
20348abec07SPaul Mackerras /*
20448abec07SPaul Mackerras  * If we are doing lazy switching of CPU state (FP, altivec or SPE),
20548abec07SPaul Mackerras  * and the current task has some state, discard it.
20648abec07SPaul Mackerras  */
2075388fb10SPaul Mackerras void discard_lazy_cpu_state(void)
20848abec07SPaul Mackerras {
20948abec07SPaul Mackerras 	preempt_disable();
21048abec07SPaul Mackerras 	if (last_task_used_math == current)
21148abec07SPaul Mackerras 		last_task_used_math = NULL;
21248abec07SPaul Mackerras #ifdef CONFIG_ALTIVEC
21348abec07SPaul Mackerras 	if (last_task_used_altivec == current)
21448abec07SPaul Mackerras 		last_task_used_altivec = NULL;
21548abec07SPaul Mackerras #endif /* CONFIG_ALTIVEC */
21648abec07SPaul Mackerras #ifdef CONFIG_SPE
21748abec07SPaul Mackerras 	if (last_task_used_spe == current)
21848abec07SPaul Mackerras 		last_task_used_spe = NULL;
21948abec07SPaul Mackerras #endif
22048abec07SPaul Mackerras 	preempt_enable();
22148abec07SPaul Mackerras }
2225388fb10SPaul Mackerras #endif /* CONFIG_SMP */
22348abec07SPaul Mackerras 
224624cee31SPaul Mackerras #ifdef CONFIG_PPC_MERGE		/* XXX for now */
22514cf11afSPaul Mackerras int set_dabr(unsigned long dabr)
22614cf11afSPaul Mackerras {
227cab0af98SMichael Ellerman 	if (ppc_md.set_dabr)
228cab0af98SMichael Ellerman 		return ppc_md.set_dabr(dabr);
22914cf11afSPaul Mackerras 
230cab0af98SMichael Ellerman 	mtspr(SPRN_DABR, dabr);
231cab0af98SMichael Ellerman 	return 0;
23214cf11afSPaul Mackerras }
233624cee31SPaul Mackerras #endif
23414cf11afSPaul Mackerras 
23506d67d54SPaul Mackerras #ifdef CONFIG_PPC64
23606d67d54SPaul Mackerras DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array);
23714cf11afSPaul Mackerras static DEFINE_PER_CPU(unsigned long, current_dabr);
23806d67d54SPaul Mackerras #endif
23914cf11afSPaul Mackerras 
24014cf11afSPaul Mackerras struct task_struct *__switch_to(struct task_struct *prev,
24114cf11afSPaul Mackerras 	struct task_struct *new)
24214cf11afSPaul Mackerras {
24314cf11afSPaul Mackerras 	struct thread_struct *new_thread, *old_thread;
24414cf11afSPaul Mackerras 	unsigned long flags;
24514cf11afSPaul Mackerras 	struct task_struct *last;
24614cf11afSPaul Mackerras 
24714cf11afSPaul Mackerras #ifdef CONFIG_SMP
24814cf11afSPaul Mackerras 	/* avoid complexity of lazy save/restore of fpu
24914cf11afSPaul Mackerras 	 * by just saving it every time we switch out if
25014cf11afSPaul Mackerras 	 * this task used the fpu during the last quantum.
25114cf11afSPaul Mackerras 	 *
25214cf11afSPaul Mackerras 	 * If it tries to use the fpu again, it'll trap and
25314cf11afSPaul Mackerras 	 * reload its fp regs.  So we don't have to do a restore
25414cf11afSPaul Mackerras 	 * every switch, just a save.
25514cf11afSPaul Mackerras 	 *  -- Cort
25614cf11afSPaul Mackerras 	 */
25714cf11afSPaul Mackerras 	if (prev->thread.regs && (prev->thread.regs->msr & MSR_FP))
25814cf11afSPaul Mackerras 		giveup_fpu(prev);
25914cf11afSPaul Mackerras #ifdef CONFIG_ALTIVEC
26014cf11afSPaul Mackerras 	/*
26114cf11afSPaul Mackerras 	 * If the previous thread used altivec in the last quantum
26214cf11afSPaul Mackerras 	 * (thus changing altivec regs) then save them.
26314cf11afSPaul Mackerras 	 * We used to check the VRSAVE register but not all apps
26414cf11afSPaul Mackerras 	 * set it, so we don't rely on it now (and in fact we need
26514cf11afSPaul Mackerras 	 * to save & restore VSCR even if VRSAVE == 0).  -- paulus
26614cf11afSPaul Mackerras 	 *
26714cf11afSPaul Mackerras 	 * On SMP we always save/restore altivec regs just to avoid the
26814cf11afSPaul Mackerras 	 * complexity of changing processors.
26914cf11afSPaul Mackerras 	 *  -- Cort
27014cf11afSPaul Mackerras 	 */
27114cf11afSPaul Mackerras 	if (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC))
27214cf11afSPaul Mackerras 		giveup_altivec(prev);
27314cf11afSPaul Mackerras #endif /* CONFIG_ALTIVEC */
27414cf11afSPaul Mackerras #ifdef CONFIG_SPE
27514cf11afSPaul Mackerras 	/*
27614cf11afSPaul Mackerras 	 * If the previous thread used spe in the last quantum
27714cf11afSPaul Mackerras 	 * (thus changing spe regs) then save them.
27814cf11afSPaul Mackerras 	 *
27914cf11afSPaul Mackerras 	 * On SMP we always save/restore spe regs just to avoid the
28014cf11afSPaul Mackerras 	 * complexity of changing processors.
28114cf11afSPaul Mackerras 	 */
28214cf11afSPaul Mackerras 	if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE)))
28314cf11afSPaul Mackerras 		giveup_spe(prev);
284c0c0d996SPaul Mackerras #endif /* CONFIG_SPE */
285c0c0d996SPaul Mackerras 
286c0c0d996SPaul Mackerras #else  /* CONFIG_SMP */
287c0c0d996SPaul Mackerras #ifdef CONFIG_ALTIVEC
288c0c0d996SPaul Mackerras 	/* Avoid the trap.  On smp this this never happens since
289c0c0d996SPaul Mackerras 	 * we don't set last_task_used_altivec -- Cort
290c0c0d996SPaul Mackerras 	 */
291c0c0d996SPaul Mackerras 	if (new->thread.regs && last_task_used_altivec == new)
292c0c0d996SPaul Mackerras 		new->thread.regs->msr |= MSR_VEC;
293c0c0d996SPaul Mackerras #endif /* CONFIG_ALTIVEC */
294c0c0d996SPaul Mackerras #ifdef CONFIG_SPE
29514cf11afSPaul Mackerras 	/* Avoid the trap.  On smp this this never happens since
29614cf11afSPaul Mackerras 	 * we don't set last_task_used_spe
29714cf11afSPaul Mackerras 	 */
29814cf11afSPaul Mackerras 	if (new->thread.regs && last_task_used_spe == new)
29914cf11afSPaul Mackerras 		new->thread.regs->msr |= MSR_SPE;
30014cf11afSPaul Mackerras #endif /* CONFIG_SPE */
301c0c0d996SPaul Mackerras 
30214cf11afSPaul Mackerras #endif /* CONFIG_SMP */
30314cf11afSPaul Mackerras 
30414cf11afSPaul Mackerras #ifdef CONFIG_PPC64	/* for now */
30514cf11afSPaul Mackerras 	if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) {
30614cf11afSPaul Mackerras 		set_dabr(new->thread.dabr);
30714cf11afSPaul Mackerras 		__get_cpu_var(current_dabr) = new->thread.dabr;
30814cf11afSPaul Mackerras 	}
30906d67d54SPaul Mackerras 
31006d67d54SPaul Mackerras 	flush_tlb_pending();
31114cf11afSPaul Mackerras #endif
31214cf11afSPaul Mackerras 
31314cf11afSPaul Mackerras 	new_thread = &new->thread;
31414cf11afSPaul Mackerras 	old_thread = &current->thread;
31506d67d54SPaul Mackerras 
31606d67d54SPaul Mackerras #ifdef CONFIG_PPC64
31706d67d54SPaul Mackerras 	/*
31806d67d54SPaul Mackerras 	 * Collect processor utilization data per process
31906d67d54SPaul Mackerras 	 */
32006d67d54SPaul Mackerras 	if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
32106d67d54SPaul Mackerras 		struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array);
32206d67d54SPaul Mackerras 		long unsigned start_tb, current_tb;
32306d67d54SPaul Mackerras 		start_tb = old_thread->start_tb;
32406d67d54SPaul Mackerras 		cu->current_tb = current_tb = mfspr(SPRN_PURR);
32506d67d54SPaul Mackerras 		old_thread->accum_tb += (current_tb - start_tb);
32606d67d54SPaul Mackerras 		new_thread->start_tb = current_tb;
32706d67d54SPaul Mackerras 	}
32806d67d54SPaul Mackerras #endif
32906d67d54SPaul Mackerras 
33014cf11afSPaul Mackerras 	local_irq_save(flags);
331*c6622f63SPaul Mackerras 
332*c6622f63SPaul Mackerras 	account_system_vtime(current);
333*c6622f63SPaul Mackerras 	account_process_vtime(current);
334*c6622f63SPaul Mackerras 	calculate_steal_time();
335*c6622f63SPaul Mackerras 
33614cf11afSPaul Mackerras 	last = _switch(old_thread, new_thread);
33714cf11afSPaul Mackerras 
33814cf11afSPaul Mackerras 	local_irq_restore(flags);
33914cf11afSPaul Mackerras 
34014cf11afSPaul Mackerras 	return last;
34114cf11afSPaul Mackerras }
34214cf11afSPaul Mackerras 
34306d67d54SPaul Mackerras static int instructions_to_print = 16;
34406d67d54SPaul Mackerras 
34506d67d54SPaul Mackerras #ifdef CONFIG_PPC64
34606d67d54SPaul Mackerras #define BAD_PC(pc)	((REGION_ID(pc) != KERNEL_REGION_ID) && \
34706d67d54SPaul Mackerras 		         (REGION_ID(pc) != VMALLOC_REGION_ID))
34806d67d54SPaul Mackerras #else
34906d67d54SPaul Mackerras #define BAD_PC(pc)	((pc) < KERNELBASE)
35006d67d54SPaul Mackerras #endif
35106d67d54SPaul Mackerras 
35206d67d54SPaul Mackerras static void show_instructions(struct pt_regs *regs)
35306d67d54SPaul Mackerras {
35406d67d54SPaul Mackerras 	int i;
35506d67d54SPaul Mackerras 	unsigned long pc = regs->nip - (instructions_to_print * 3 / 4 *
35606d67d54SPaul Mackerras 			sizeof(int));
35706d67d54SPaul Mackerras 
35806d67d54SPaul Mackerras 	printk("Instruction dump:");
35906d67d54SPaul Mackerras 
36006d67d54SPaul Mackerras 	for (i = 0; i < instructions_to_print; i++) {
36106d67d54SPaul Mackerras 		int instr;
36206d67d54SPaul Mackerras 
36306d67d54SPaul Mackerras 		if (!(i % 8))
36406d67d54SPaul Mackerras 			printk("\n");
36506d67d54SPaul Mackerras 
36606d67d54SPaul Mackerras 		if (BAD_PC(pc) || __get_user(instr, (unsigned int *)pc)) {
36706d67d54SPaul Mackerras 			printk("XXXXXXXX ");
36806d67d54SPaul Mackerras 		} else {
36906d67d54SPaul Mackerras 			if (regs->nip == pc)
37006d67d54SPaul Mackerras 				printk("<%08x> ", instr);
37106d67d54SPaul Mackerras 			else
37206d67d54SPaul Mackerras 				printk("%08x ", instr);
37306d67d54SPaul Mackerras 		}
37406d67d54SPaul Mackerras 
37506d67d54SPaul Mackerras 		pc += sizeof(int);
37606d67d54SPaul Mackerras 	}
37706d67d54SPaul Mackerras 
37806d67d54SPaul Mackerras 	printk("\n");
37906d67d54SPaul Mackerras }
38006d67d54SPaul Mackerras 
38106d67d54SPaul Mackerras static struct regbit {
38206d67d54SPaul Mackerras 	unsigned long bit;
38306d67d54SPaul Mackerras 	const char *name;
38406d67d54SPaul Mackerras } msr_bits[] = {
38506d67d54SPaul Mackerras 	{MSR_EE,	"EE"},
38606d67d54SPaul Mackerras 	{MSR_PR,	"PR"},
38706d67d54SPaul Mackerras 	{MSR_FP,	"FP"},
38806d67d54SPaul Mackerras 	{MSR_ME,	"ME"},
38906d67d54SPaul Mackerras 	{MSR_IR,	"IR"},
39006d67d54SPaul Mackerras 	{MSR_DR,	"DR"},
39106d67d54SPaul Mackerras 	{0,		NULL}
39206d67d54SPaul Mackerras };
39306d67d54SPaul Mackerras 
39406d67d54SPaul Mackerras static void printbits(unsigned long val, struct regbit *bits)
39506d67d54SPaul Mackerras {
39606d67d54SPaul Mackerras 	const char *sep = "";
39706d67d54SPaul Mackerras 
39806d67d54SPaul Mackerras 	printk("<");
39906d67d54SPaul Mackerras 	for (; bits->bit; ++bits)
40006d67d54SPaul Mackerras 		if (val & bits->bit) {
40106d67d54SPaul Mackerras 			printk("%s%s", sep, bits->name);
40206d67d54SPaul Mackerras 			sep = ",";
40306d67d54SPaul Mackerras 		}
40406d67d54SPaul Mackerras 	printk(">");
40506d67d54SPaul Mackerras }
40606d67d54SPaul Mackerras 
40706d67d54SPaul Mackerras #ifdef CONFIG_PPC64
40806d67d54SPaul Mackerras #define REG		"%016lX"
40906d67d54SPaul Mackerras #define REGS_PER_LINE	4
41006d67d54SPaul Mackerras #define LAST_VOLATILE	13
41106d67d54SPaul Mackerras #else
41206d67d54SPaul Mackerras #define REG		"%08lX"
41306d67d54SPaul Mackerras #define REGS_PER_LINE	8
41406d67d54SPaul Mackerras #define LAST_VOLATILE	12
41506d67d54SPaul Mackerras #endif
41606d67d54SPaul Mackerras 
41714cf11afSPaul Mackerras void show_regs(struct pt_regs * regs)
41814cf11afSPaul Mackerras {
41914cf11afSPaul Mackerras 	int i, trap;
42014cf11afSPaul Mackerras 
42106d67d54SPaul Mackerras 	printk("NIP: "REG" LR: "REG" CTR: "REG"\n",
42206d67d54SPaul Mackerras 	       regs->nip, regs->link, regs->ctr);
42306d67d54SPaul Mackerras 	printk("REGS: %p TRAP: %04lx   %s  (%s)\n",
42406d67d54SPaul Mackerras 	       regs, regs->trap, print_tainted(), system_utsname.release);
42506d67d54SPaul Mackerras 	printk("MSR: "REG" ", regs->msr);
42606d67d54SPaul Mackerras 	printbits(regs->msr, msr_bits);
42706d67d54SPaul Mackerras 	printk("  CR: %08lX  XER: %08lX\n", regs->ccr, regs->xer);
42814cf11afSPaul Mackerras 	trap = TRAP(regs);
42914cf11afSPaul Mackerras 	if (trap == 0x300 || trap == 0x600)
43006d67d54SPaul Mackerras 		printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
43106d67d54SPaul Mackerras 	printk("TASK = %p[%d] '%s' THREAD: %p",
432b5e2fc1cSAl Viro 	       current, current->pid, current->comm, task_thread_info(current));
43314cf11afSPaul Mackerras 
43414cf11afSPaul Mackerras #ifdef CONFIG_SMP
43514cf11afSPaul Mackerras 	printk(" CPU: %d", smp_processor_id());
43614cf11afSPaul Mackerras #endif /* CONFIG_SMP */
43714cf11afSPaul Mackerras 
43814cf11afSPaul Mackerras 	for (i = 0;  i < 32;  i++) {
43906d67d54SPaul Mackerras 		if ((i % REGS_PER_LINE) == 0)
44014cf11afSPaul Mackerras 			printk("\n" KERN_INFO "GPR%02d: ", i);
44106d67d54SPaul Mackerras 		printk(REG " ", regs->gpr[i]);
44206d67d54SPaul Mackerras 		if (i == LAST_VOLATILE && !FULL_REGS(regs))
44314cf11afSPaul Mackerras 			break;
44414cf11afSPaul Mackerras 	}
44514cf11afSPaul Mackerras 	printk("\n");
44614cf11afSPaul Mackerras #ifdef CONFIG_KALLSYMS
44714cf11afSPaul Mackerras 	/*
44814cf11afSPaul Mackerras 	 * Lookup NIP late so we have the best change of getting the
44914cf11afSPaul Mackerras 	 * above info out without failing
45014cf11afSPaul Mackerras 	 */
45106d67d54SPaul Mackerras 	printk("NIP ["REG"] ", regs->nip);
45214cf11afSPaul Mackerras 	print_symbol("%s\n", regs->nip);
45306d67d54SPaul Mackerras 	printk("LR ["REG"] ", regs->link);
45414cf11afSPaul Mackerras 	print_symbol("%s\n", regs->link);
45514cf11afSPaul Mackerras #endif
45614cf11afSPaul Mackerras 	show_stack(current, (unsigned long *) regs->gpr[1]);
45706d67d54SPaul Mackerras 	if (!user_mode(regs))
45806d67d54SPaul Mackerras 		show_instructions(regs);
45914cf11afSPaul Mackerras }
46014cf11afSPaul Mackerras 
46114cf11afSPaul Mackerras void exit_thread(void)
46214cf11afSPaul Mackerras {
46306d67d54SPaul Mackerras 	kprobe_flush_task(current);
46448abec07SPaul Mackerras 	discard_lazy_cpu_state();
46514cf11afSPaul Mackerras }
46614cf11afSPaul Mackerras 
46714cf11afSPaul Mackerras void flush_thread(void)
46814cf11afSPaul Mackerras {
46906d67d54SPaul Mackerras #ifdef CONFIG_PPC64
47006d67d54SPaul Mackerras 	struct thread_info *t = current_thread_info();
47106d67d54SPaul Mackerras 
47206d67d54SPaul Mackerras 	if (t->flags & _TIF_ABI_PENDING)
47306d67d54SPaul Mackerras 		t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT);
47406d67d54SPaul Mackerras #endif
47506d67d54SPaul Mackerras 
47648abec07SPaul Mackerras 	discard_lazy_cpu_state();
47714cf11afSPaul Mackerras 
47814cf11afSPaul Mackerras #ifdef CONFIG_PPC64	/* for now */
47914cf11afSPaul Mackerras 	if (current->thread.dabr) {
48014cf11afSPaul Mackerras 		current->thread.dabr = 0;
48114cf11afSPaul Mackerras 		set_dabr(0);
48214cf11afSPaul Mackerras 	}
48314cf11afSPaul Mackerras #endif
48414cf11afSPaul Mackerras }
48514cf11afSPaul Mackerras 
48614cf11afSPaul Mackerras void
48714cf11afSPaul Mackerras release_thread(struct task_struct *t)
48814cf11afSPaul Mackerras {
48914cf11afSPaul Mackerras }
49014cf11afSPaul Mackerras 
49114cf11afSPaul Mackerras /*
49214cf11afSPaul Mackerras  * This gets called before we allocate a new thread and copy
49314cf11afSPaul Mackerras  * the current task into it.
49414cf11afSPaul Mackerras  */
49514cf11afSPaul Mackerras void prepare_to_copy(struct task_struct *tsk)
49614cf11afSPaul Mackerras {
49714cf11afSPaul Mackerras 	flush_fp_to_thread(current);
49814cf11afSPaul Mackerras 	flush_altivec_to_thread(current);
49914cf11afSPaul Mackerras 	flush_spe_to_thread(current);
50014cf11afSPaul Mackerras }
50114cf11afSPaul Mackerras 
50214cf11afSPaul Mackerras /*
50314cf11afSPaul Mackerras  * Copy a thread..
50414cf11afSPaul Mackerras  */
50506d67d54SPaul Mackerras int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
50606d67d54SPaul Mackerras 		unsigned long unused, struct task_struct *p,
50706d67d54SPaul Mackerras 		struct pt_regs *regs)
50814cf11afSPaul Mackerras {
50914cf11afSPaul Mackerras 	struct pt_regs *childregs, *kregs;
51014cf11afSPaul Mackerras 	extern void ret_from_fork(void);
5110cec6fd1SAl Viro 	unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
51214cf11afSPaul Mackerras 
51314cf11afSPaul Mackerras 	CHECK_FULL_REGS(regs);
51414cf11afSPaul Mackerras 	/* Copy registers */
51514cf11afSPaul Mackerras 	sp -= sizeof(struct pt_regs);
51614cf11afSPaul Mackerras 	childregs = (struct pt_regs *) sp;
51714cf11afSPaul Mackerras 	*childregs = *regs;
51814cf11afSPaul Mackerras 	if ((childregs->msr & MSR_PR) == 0) {
51914cf11afSPaul Mackerras 		/* for kernel thread, set `current' and stackptr in new task */
52014cf11afSPaul Mackerras 		childregs->gpr[1] = sp + sizeof(struct pt_regs);
52106d67d54SPaul Mackerras #ifdef CONFIG_PPC32
52214cf11afSPaul Mackerras 		childregs->gpr[2] = (unsigned long) p;
52306d67d54SPaul Mackerras #else
524b5e2fc1cSAl Viro 		clear_tsk_thread_flag(p, TIF_32BIT);
52506d67d54SPaul Mackerras #endif
52614cf11afSPaul Mackerras 		p->thread.regs = NULL;	/* no user register state */
52714cf11afSPaul Mackerras 	} else {
52814cf11afSPaul Mackerras 		childregs->gpr[1] = usp;
52914cf11afSPaul Mackerras 		p->thread.regs = childregs;
53006d67d54SPaul Mackerras 		if (clone_flags & CLONE_SETTLS) {
53106d67d54SPaul Mackerras #ifdef CONFIG_PPC64
53206d67d54SPaul Mackerras 			if (!test_thread_flag(TIF_32BIT))
53306d67d54SPaul Mackerras 				childregs->gpr[13] = childregs->gpr[6];
53406d67d54SPaul Mackerras 			else
53506d67d54SPaul Mackerras #endif
53614cf11afSPaul Mackerras 				childregs->gpr[2] = childregs->gpr[6];
53714cf11afSPaul Mackerras 		}
53806d67d54SPaul Mackerras 	}
53914cf11afSPaul Mackerras 	childregs->gpr[3] = 0;  /* Result from fork() */
54014cf11afSPaul Mackerras 	sp -= STACK_FRAME_OVERHEAD;
54114cf11afSPaul Mackerras 
54214cf11afSPaul Mackerras 	/*
54314cf11afSPaul Mackerras 	 * The way this works is that at some point in the future
54414cf11afSPaul Mackerras 	 * some task will call _switch to switch to the new task.
54514cf11afSPaul Mackerras 	 * That will pop off the stack frame created below and start
54614cf11afSPaul Mackerras 	 * the new task running at ret_from_fork.  The new task will
54714cf11afSPaul Mackerras 	 * do some house keeping and then return from the fork or clone
54814cf11afSPaul Mackerras 	 * system call, using the stack frame created above.
54914cf11afSPaul Mackerras 	 */
55014cf11afSPaul Mackerras 	sp -= sizeof(struct pt_regs);
55114cf11afSPaul Mackerras 	kregs = (struct pt_regs *) sp;
55214cf11afSPaul Mackerras 	sp -= STACK_FRAME_OVERHEAD;
55314cf11afSPaul Mackerras 	p->thread.ksp = sp;
55414cf11afSPaul Mackerras 
55506d67d54SPaul Mackerras #ifdef CONFIG_PPC64
55606d67d54SPaul Mackerras 	if (cpu_has_feature(CPU_FTR_SLB)) {
55706d67d54SPaul Mackerras 		unsigned long sp_vsid = get_kernel_vsid(sp);
5583c726f8dSBenjamin Herrenschmidt 		unsigned long llp = mmu_psize_defs[mmu_linear_psize].sllp;
55906d67d54SPaul Mackerras 
56006d67d54SPaul Mackerras 		sp_vsid <<= SLB_VSID_SHIFT;
5613c726f8dSBenjamin Herrenschmidt 		sp_vsid |= SLB_VSID_KERNEL | llp;
56206d67d54SPaul Mackerras 		p->thread.ksp_vsid = sp_vsid;
56306d67d54SPaul Mackerras 	}
56406d67d54SPaul Mackerras 
56506d67d54SPaul Mackerras 	/*
56606d67d54SPaul Mackerras 	 * The PPC64 ABI makes use of a TOC to contain function
56706d67d54SPaul Mackerras 	 * pointers.  The function (ret_from_except) is actually a pointer
56806d67d54SPaul Mackerras 	 * to the TOC entry.  The first entry is a pointer to the actual
56906d67d54SPaul Mackerras 	 * function.
57006d67d54SPaul Mackerras  	 */
57106d67d54SPaul Mackerras 	kregs->nip = *((unsigned long *)ret_from_fork);
57206d67d54SPaul Mackerras #else
57306d67d54SPaul Mackerras 	kregs->nip = (unsigned long)ret_from_fork;
57414cf11afSPaul Mackerras 	p->thread.last_syscall = -1;
57506d67d54SPaul Mackerras #endif
57614cf11afSPaul Mackerras 
57714cf11afSPaul Mackerras 	return 0;
57814cf11afSPaul Mackerras }
57914cf11afSPaul Mackerras 
58014cf11afSPaul Mackerras /*
58114cf11afSPaul Mackerras  * Set up a thread for executing a new program
58214cf11afSPaul Mackerras  */
58306d67d54SPaul Mackerras void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
58414cf11afSPaul Mackerras {
58590eac727SMichael Ellerman #ifdef CONFIG_PPC64
58690eac727SMichael Ellerman 	unsigned long load_addr = regs->gpr[2];	/* saved by ELF_PLAT_INIT */
58790eac727SMichael Ellerman #endif
58890eac727SMichael Ellerman 
58914cf11afSPaul Mackerras 	set_fs(USER_DS);
59006d67d54SPaul Mackerras 
59106d67d54SPaul Mackerras 	/*
59206d67d54SPaul Mackerras 	 * If we exec out of a kernel thread then thread.regs will not be
59306d67d54SPaul Mackerras 	 * set.  Do it now.
59406d67d54SPaul Mackerras 	 */
59506d67d54SPaul Mackerras 	if (!current->thread.regs) {
5960cec6fd1SAl Viro 		struct pt_regs *regs = task_stack_page(current) + THREAD_SIZE;
5970cec6fd1SAl Viro 		current->thread.regs = regs - 1;
59806d67d54SPaul Mackerras 	}
59906d67d54SPaul Mackerras 
60014cf11afSPaul Mackerras 	memset(regs->gpr, 0, sizeof(regs->gpr));
60114cf11afSPaul Mackerras 	regs->ctr = 0;
60214cf11afSPaul Mackerras 	regs->link = 0;
60314cf11afSPaul Mackerras 	regs->xer = 0;
60414cf11afSPaul Mackerras 	regs->ccr = 0;
60514cf11afSPaul Mackerras 	regs->gpr[1] = sp;
60606d67d54SPaul Mackerras 
60706d67d54SPaul Mackerras #ifdef CONFIG_PPC32
60806d67d54SPaul Mackerras 	regs->mq = 0;
60906d67d54SPaul Mackerras 	regs->nip = start;
61014cf11afSPaul Mackerras 	regs->msr = MSR_USER;
61106d67d54SPaul Mackerras #else
612d4bf9a78SStephen Rothwell 	if (!test_thread_flag(TIF_32BIT)) {
61390eac727SMichael Ellerman 		unsigned long entry, toc;
61406d67d54SPaul Mackerras 
61506d67d54SPaul Mackerras 		/* start is a relocated pointer to the function descriptor for
61606d67d54SPaul Mackerras 		 * the elf _start routine.  The first entry in the function
61706d67d54SPaul Mackerras 		 * descriptor is the entry address of _start and the second
61806d67d54SPaul Mackerras 		 * entry is the TOC value we need to use.
61906d67d54SPaul Mackerras 		 */
62006d67d54SPaul Mackerras 		__get_user(entry, (unsigned long __user *)start);
62106d67d54SPaul Mackerras 		__get_user(toc, (unsigned long __user *)start+1);
62206d67d54SPaul Mackerras 
62306d67d54SPaul Mackerras 		/* Check whether the e_entry function descriptor entries
62406d67d54SPaul Mackerras 		 * need to be relocated before we can use them.
62506d67d54SPaul Mackerras 		 */
62606d67d54SPaul Mackerras 		if (load_addr != 0) {
62706d67d54SPaul Mackerras 			entry += load_addr;
62806d67d54SPaul Mackerras 			toc   += load_addr;
62906d67d54SPaul Mackerras 		}
63006d67d54SPaul Mackerras 		regs->nip = entry;
63106d67d54SPaul Mackerras 		regs->gpr[2] = toc;
63206d67d54SPaul Mackerras 		regs->msr = MSR_USER64;
633d4bf9a78SStephen Rothwell 	} else {
634d4bf9a78SStephen Rothwell 		regs->nip = start;
635d4bf9a78SStephen Rothwell 		regs->gpr[2] = 0;
636d4bf9a78SStephen Rothwell 		regs->msr = MSR_USER32;
63706d67d54SPaul Mackerras 	}
63806d67d54SPaul Mackerras #endif
63906d67d54SPaul Mackerras 
64048abec07SPaul Mackerras 	discard_lazy_cpu_state();
64114cf11afSPaul Mackerras 	memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
64225c8a78bSDavid Gibson 	current->thread.fpscr.val = 0;
64314cf11afSPaul Mackerras #ifdef CONFIG_ALTIVEC
64414cf11afSPaul Mackerras 	memset(current->thread.vr, 0, sizeof(current->thread.vr));
64514cf11afSPaul Mackerras 	memset(&current->thread.vscr, 0, sizeof(current->thread.vscr));
64606d67d54SPaul Mackerras 	current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */
64714cf11afSPaul Mackerras 	current->thread.vrsave = 0;
64814cf11afSPaul Mackerras 	current->thread.used_vr = 0;
64914cf11afSPaul Mackerras #endif /* CONFIG_ALTIVEC */
65014cf11afSPaul Mackerras #ifdef CONFIG_SPE
65114cf11afSPaul Mackerras 	memset(current->thread.evr, 0, sizeof(current->thread.evr));
65214cf11afSPaul Mackerras 	current->thread.acc = 0;
65314cf11afSPaul Mackerras 	current->thread.spefscr = 0;
65414cf11afSPaul Mackerras 	current->thread.used_spe = 0;
65514cf11afSPaul Mackerras #endif /* CONFIG_SPE */
65614cf11afSPaul Mackerras }
65714cf11afSPaul Mackerras 
65814cf11afSPaul Mackerras #define PR_FP_ALL_EXCEPT (PR_FP_EXC_DIV | PR_FP_EXC_OVF | PR_FP_EXC_UND \
65914cf11afSPaul Mackerras 		| PR_FP_EXC_RES | PR_FP_EXC_INV)
66014cf11afSPaul Mackerras 
66114cf11afSPaul Mackerras int set_fpexc_mode(struct task_struct *tsk, unsigned int val)
66214cf11afSPaul Mackerras {
66314cf11afSPaul Mackerras 	struct pt_regs *regs = tsk->thread.regs;
66414cf11afSPaul Mackerras 
66514cf11afSPaul Mackerras 	/* This is a bit hairy.  If we are an SPE enabled  processor
66614cf11afSPaul Mackerras 	 * (have embedded fp) we store the IEEE exception enable flags in
66714cf11afSPaul Mackerras 	 * fpexc_mode.  fpexc_mode is also used for setting FP exception
66814cf11afSPaul Mackerras 	 * mode (asyn, precise, disabled) for 'Classic' FP. */
66914cf11afSPaul Mackerras 	if (val & PR_FP_EXC_SW_ENABLE) {
67014cf11afSPaul Mackerras #ifdef CONFIG_SPE
67114cf11afSPaul Mackerras 		tsk->thread.fpexc_mode = val &
67214cf11afSPaul Mackerras 			(PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT);
67306d67d54SPaul Mackerras 		return 0;
67414cf11afSPaul Mackerras #else
67514cf11afSPaul Mackerras 		return -EINVAL;
67614cf11afSPaul Mackerras #endif
67706d67d54SPaul Mackerras 	}
67806d67d54SPaul Mackerras 
67914cf11afSPaul Mackerras 	/* on a CONFIG_SPE this does not hurt us.  The bits that
68014cf11afSPaul Mackerras 	 * __pack_fe01 use do not overlap with bits used for
68114cf11afSPaul Mackerras 	 * PR_FP_EXC_SW_ENABLE.  Additionally, the MSR[FE0,FE1] bits
68214cf11afSPaul Mackerras 	 * on CONFIG_SPE implementations are reserved so writing to
68314cf11afSPaul Mackerras 	 * them does not change anything */
68414cf11afSPaul Mackerras 	if (val > PR_FP_EXC_PRECISE)
68514cf11afSPaul Mackerras 		return -EINVAL;
68614cf11afSPaul Mackerras 	tsk->thread.fpexc_mode = __pack_fe01(val);
68714cf11afSPaul Mackerras 	if (regs != NULL && (regs->msr & MSR_FP) != 0)
68814cf11afSPaul Mackerras 		regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1))
68914cf11afSPaul Mackerras 			| tsk->thread.fpexc_mode;
69014cf11afSPaul Mackerras 	return 0;
69114cf11afSPaul Mackerras }
69214cf11afSPaul Mackerras 
69314cf11afSPaul Mackerras int get_fpexc_mode(struct task_struct *tsk, unsigned long adr)
69414cf11afSPaul Mackerras {
69514cf11afSPaul Mackerras 	unsigned int val;
69614cf11afSPaul Mackerras 
69714cf11afSPaul Mackerras 	if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE)
69814cf11afSPaul Mackerras #ifdef CONFIG_SPE
69914cf11afSPaul Mackerras 		val = tsk->thread.fpexc_mode;
70014cf11afSPaul Mackerras #else
70114cf11afSPaul Mackerras 		return -EINVAL;
70214cf11afSPaul Mackerras #endif
70314cf11afSPaul Mackerras 	else
70414cf11afSPaul Mackerras 		val = __unpack_fe01(tsk->thread.fpexc_mode);
70514cf11afSPaul Mackerras 	return put_user(val, (unsigned int __user *) adr);
70614cf11afSPaul Mackerras }
70714cf11afSPaul Mackerras 
70806d67d54SPaul Mackerras #define TRUNC_PTR(x)	((typeof(x))(((unsigned long)(x)) & 0xffffffff))
70906d67d54SPaul Mackerras 
71014cf11afSPaul Mackerras int sys_clone(unsigned long clone_flags, unsigned long usp,
71114cf11afSPaul Mackerras 	      int __user *parent_tidp, void __user *child_threadptr,
71214cf11afSPaul Mackerras 	      int __user *child_tidp, int p6,
71314cf11afSPaul Mackerras 	      struct pt_regs *regs)
71414cf11afSPaul Mackerras {
71514cf11afSPaul Mackerras 	CHECK_FULL_REGS(regs);
71614cf11afSPaul Mackerras 	if (usp == 0)
71714cf11afSPaul Mackerras 		usp = regs->gpr[1];	/* stack pointer for child */
71806d67d54SPaul Mackerras #ifdef CONFIG_PPC64
71906d67d54SPaul Mackerras 	if (test_thread_flag(TIF_32BIT)) {
72006d67d54SPaul Mackerras 		parent_tidp = TRUNC_PTR(parent_tidp);
72106d67d54SPaul Mackerras 		child_tidp = TRUNC_PTR(child_tidp);
72206d67d54SPaul Mackerras 	}
72306d67d54SPaul Mackerras #endif
72414cf11afSPaul Mackerras  	return do_fork(clone_flags, usp, regs, 0, parent_tidp, child_tidp);
72514cf11afSPaul Mackerras }
72614cf11afSPaul Mackerras 
72714cf11afSPaul Mackerras int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
72814cf11afSPaul Mackerras 	     unsigned long p4, unsigned long p5, unsigned long p6,
72914cf11afSPaul Mackerras 	     struct pt_regs *regs)
73014cf11afSPaul Mackerras {
73114cf11afSPaul Mackerras 	CHECK_FULL_REGS(regs);
73214cf11afSPaul Mackerras 	return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL);
73314cf11afSPaul Mackerras }
73414cf11afSPaul Mackerras 
73514cf11afSPaul Mackerras int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
73614cf11afSPaul Mackerras 	      unsigned long p4, unsigned long p5, unsigned long p6,
73714cf11afSPaul Mackerras 	      struct pt_regs *regs)
73814cf11afSPaul Mackerras {
73914cf11afSPaul Mackerras 	CHECK_FULL_REGS(regs);
74014cf11afSPaul Mackerras 	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1],
74114cf11afSPaul Mackerras 			regs, 0, NULL, NULL);
74214cf11afSPaul Mackerras }
74314cf11afSPaul Mackerras 
74414cf11afSPaul Mackerras int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
74514cf11afSPaul Mackerras 	       unsigned long a3, unsigned long a4, unsigned long a5,
74614cf11afSPaul Mackerras 	       struct pt_regs *regs)
74714cf11afSPaul Mackerras {
74814cf11afSPaul Mackerras 	int error;
74914cf11afSPaul Mackerras 	char *filename;
75014cf11afSPaul Mackerras 
75114cf11afSPaul Mackerras 	filename = getname((char __user *) a0);
75214cf11afSPaul Mackerras 	error = PTR_ERR(filename);
75314cf11afSPaul Mackerras 	if (IS_ERR(filename))
75414cf11afSPaul Mackerras 		goto out;
75514cf11afSPaul Mackerras 	flush_fp_to_thread(current);
75614cf11afSPaul Mackerras 	flush_altivec_to_thread(current);
75714cf11afSPaul Mackerras 	flush_spe_to_thread(current);
75820c8c210SPaul Mackerras 	error = do_execve(filename, (char __user * __user *) a1,
75920c8c210SPaul Mackerras 			  (char __user * __user *) a2, regs);
76014cf11afSPaul Mackerras 	if (error == 0) {
76114cf11afSPaul Mackerras 		task_lock(current);
76214cf11afSPaul Mackerras 		current->ptrace &= ~PT_DTRACE;
76314cf11afSPaul Mackerras 		task_unlock(current);
76414cf11afSPaul Mackerras 	}
76514cf11afSPaul Mackerras 	putname(filename);
76614cf11afSPaul Mackerras out:
76714cf11afSPaul Mackerras 	return error;
76814cf11afSPaul Mackerras }
76914cf11afSPaul Mackerras 
77014cf11afSPaul Mackerras static int validate_sp(unsigned long sp, struct task_struct *p,
77114cf11afSPaul Mackerras 		       unsigned long nbytes)
77214cf11afSPaul Mackerras {
7730cec6fd1SAl Viro 	unsigned long stack_page = (unsigned long)task_stack_page(p);
77414cf11afSPaul Mackerras 
77514cf11afSPaul Mackerras 	if (sp >= stack_page + sizeof(struct thread_struct)
77614cf11afSPaul Mackerras 	    && sp <= stack_page + THREAD_SIZE - nbytes)
77714cf11afSPaul Mackerras 		return 1;
77814cf11afSPaul Mackerras 
77914cf11afSPaul Mackerras #ifdef CONFIG_IRQSTACKS
78014cf11afSPaul Mackerras 	stack_page = (unsigned long) hardirq_ctx[task_cpu(p)];
78114cf11afSPaul Mackerras 	if (sp >= stack_page + sizeof(struct thread_struct)
78214cf11afSPaul Mackerras 	    && sp <= stack_page + THREAD_SIZE - nbytes)
78314cf11afSPaul Mackerras 		return 1;
78414cf11afSPaul Mackerras 
78514cf11afSPaul Mackerras 	stack_page = (unsigned long) softirq_ctx[task_cpu(p)];
78614cf11afSPaul Mackerras 	if (sp >= stack_page + sizeof(struct thread_struct)
78714cf11afSPaul Mackerras 	    && sp <= stack_page + THREAD_SIZE - nbytes)
78814cf11afSPaul Mackerras 		return 1;
78914cf11afSPaul Mackerras #endif
79014cf11afSPaul Mackerras 
79114cf11afSPaul Mackerras 	return 0;
79214cf11afSPaul Mackerras }
79314cf11afSPaul Mackerras 
79406d67d54SPaul Mackerras #ifdef CONFIG_PPC64
79506d67d54SPaul Mackerras #define MIN_STACK_FRAME	112	/* same as STACK_FRAME_OVERHEAD, in fact */
79606d67d54SPaul Mackerras #define FRAME_LR_SAVE	2
79706d67d54SPaul Mackerras #define INT_FRAME_SIZE	(sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD + 288)
79806d67d54SPaul Mackerras #define REGS_MARKER	0x7265677368657265ul
79906d67d54SPaul Mackerras #define FRAME_MARKER	12
80006d67d54SPaul Mackerras #else
80106d67d54SPaul Mackerras #define MIN_STACK_FRAME	16
80206d67d54SPaul Mackerras #define FRAME_LR_SAVE	1
80306d67d54SPaul Mackerras #define INT_FRAME_SIZE	(sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD)
80406d67d54SPaul Mackerras #define REGS_MARKER	0x72656773ul
80506d67d54SPaul Mackerras #define FRAME_MARKER	2
80606d67d54SPaul Mackerras #endif
80714cf11afSPaul Mackerras 
80806d67d54SPaul Mackerras unsigned long get_wchan(struct task_struct *p)
80906d67d54SPaul Mackerras {
81006d67d54SPaul Mackerras 	unsigned long ip, sp;
81106d67d54SPaul Mackerras 	int count = 0;
81206d67d54SPaul Mackerras 
81306d67d54SPaul Mackerras 	if (!p || p == current || p->state == TASK_RUNNING)
81406d67d54SPaul Mackerras 		return 0;
81506d67d54SPaul Mackerras 
81606d67d54SPaul Mackerras 	sp = p->thread.ksp;
81706d67d54SPaul Mackerras 	if (!validate_sp(sp, p, MIN_STACK_FRAME))
81806d67d54SPaul Mackerras 		return 0;
81906d67d54SPaul Mackerras 
82006d67d54SPaul Mackerras 	do {
82106d67d54SPaul Mackerras 		sp = *(unsigned long *)sp;
82206d67d54SPaul Mackerras 		if (!validate_sp(sp, p, MIN_STACK_FRAME))
82306d67d54SPaul Mackerras 			return 0;
82406d67d54SPaul Mackerras 		if (count > 0) {
82506d67d54SPaul Mackerras 			ip = ((unsigned long *)sp)[FRAME_LR_SAVE];
82606d67d54SPaul Mackerras 			if (!in_sched_functions(ip))
82706d67d54SPaul Mackerras 				return ip;
82806d67d54SPaul Mackerras 		}
82906d67d54SPaul Mackerras 	} while (count++ < 16);
83006d67d54SPaul Mackerras 	return 0;
83106d67d54SPaul Mackerras }
83206d67d54SPaul Mackerras EXPORT_SYMBOL(get_wchan);
83306d67d54SPaul Mackerras 
83406d67d54SPaul Mackerras static int kstack_depth_to_print = 64;
83514cf11afSPaul Mackerras 
83614cf11afSPaul Mackerras void show_stack(struct task_struct *tsk, unsigned long *stack)
83714cf11afSPaul Mackerras {
83806d67d54SPaul Mackerras 	unsigned long sp, ip, lr, newsp;
83914cf11afSPaul Mackerras 	int count = 0;
84006d67d54SPaul Mackerras 	int firstframe = 1;
84114cf11afSPaul Mackerras 
84214cf11afSPaul Mackerras 	sp = (unsigned long) stack;
84314cf11afSPaul Mackerras 	if (tsk == NULL)
84414cf11afSPaul Mackerras 		tsk = current;
84514cf11afSPaul Mackerras 	if (sp == 0) {
84614cf11afSPaul Mackerras 		if (tsk == current)
84714cf11afSPaul Mackerras 			asm("mr %0,1" : "=r" (sp));
84814cf11afSPaul Mackerras 		else
84914cf11afSPaul Mackerras 			sp = tsk->thread.ksp;
85014cf11afSPaul Mackerras 	}
85114cf11afSPaul Mackerras 
85206d67d54SPaul Mackerras 	lr = 0;
85306d67d54SPaul Mackerras 	printk("Call Trace:\n");
85414cf11afSPaul Mackerras 	do {
85506d67d54SPaul Mackerras 		if (!validate_sp(sp, tsk, MIN_STACK_FRAME))
85606d67d54SPaul Mackerras 			return;
85706d67d54SPaul Mackerras 
85806d67d54SPaul Mackerras 		stack = (unsigned long *) sp;
85906d67d54SPaul Mackerras 		newsp = stack[0];
86006d67d54SPaul Mackerras 		ip = stack[FRAME_LR_SAVE];
86106d67d54SPaul Mackerras 		if (!firstframe || ip != lr) {
86206d67d54SPaul Mackerras 			printk("["REG"] ["REG"] ", sp, ip);
86306d67d54SPaul Mackerras 			print_symbol("%s", ip);
86406d67d54SPaul Mackerras 			if (firstframe)
86506d67d54SPaul Mackerras 				printk(" (unreliable)");
86606d67d54SPaul Mackerras 			printk("\n");
86714cf11afSPaul Mackerras 		}
86806d67d54SPaul Mackerras 		firstframe = 0;
86906d67d54SPaul Mackerras 
87006d67d54SPaul Mackerras 		/*
87106d67d54SPaul Mackerras 		 * See if this is an exception frame.
87206d67d54SPaul Mackerras 		 * We look for the "regshere" marker in the current frame.
87306d67d54SPaul Mackerras 		 */
87406d67d54SPaul Mackerras 		if (validate_sp(sp, tsk, INT_FRAME_SIZE)
87506d67d54SPaul Mackerras 		    && stack[FRAME_MARKER] == REGS_MARKER) {
87606d67d54SPaul Mackerras 			struct pt_regs *regs = (struct pt_regs *)
87706d67d54SPaul Mackerras 				(sp + STACK_FRAME_OVERHEAD);
87806d67d54SPaul Mackerras 			printk("--- Exception: %lx", regs->trap);
87906d67d54SPaul Mackerras 			print_symbol(" at %s\n", regs->nip);
88006d67d54SPaul Mackerras 			lr = regs->link;
88106d67d54SPaul Mackerras 			print_symbol("    LR = %s\n", lr);
88206d67d54SPaul Mackerras 			firstframe = 1;
88314cf11afSPaul Mackerras 		}
88406d67d54SPaul Mackerras 
88506d67d54SPaul Mackerras 		sp = newsp;
88606d67d54SPaul Mackerras 	} while (count++ < kstack_depth_to_print);
88706d67d54SPaul Mackerras }
88806d67d54SPaul Mackerras 
88906d67d54SPaul Mackerras void dump_stack(void)
89006d67d54SPaul Mackerras {
89106d67d54SPaul Mackerras 	show_stack(current, NULL);
89206d67d54SPaul Mackerras }
89306d67d54SPaul Mackerras EXPORT_SYMBOL(dump_stack);
894cb2c9b27SAnton Blanchard 
895cb2c9b27SAnton Blanchard #ifdef CONFIG_PPC64
896cb2c9b27SAnton Blanchard void ppc64_runlatch_on(void)
897cb2c9b27SAnton Blanchard {
898cb2c9b27SAnton Blanchard 	unsigned long ctrl;
899cb2c9b27SAnton Blanchard 
900cb2c9b27SAnton Blanchard 	if (cpu_has_feature(CPU_FTR_CTRL) && !test_thread_flag(TIF_RUNLATCH)) {
901cb2c9b27SAnton Blanchard 		HMT_medium();
902cb2c9b27SAnton Blanchard 
903cb2c9b27SAnton Blanchard 		ctrl = mfspr(SPRN_CTRLF);
904cb2c9b27SAnton Blanchard 		ctrl |= CTRL_RUNLATCH;
905cb2c9b27SAnton Blanchard 		mtspr(SPRN_CTRLT, ctrl);
906cb2c9b27SAnton Blanchard 
907cb2c9b27SAnton Blanchard 		set_thread_flag(TIF_RUNLATCH);
908cb2c9b27SAnton Blanchard 	}
909cb2c9b27SAnton Blanchard }
910cb2c9b27SAnton Blanchard 
911cb2c9b27SAnton Blanchard void ppc64_runlatch_off(void)
912cb2c9b27SAnton Blanchard {
913cb2c9b27SAnton Blanchard 	unsigned long ctrl;
914cb2c9b27SAnton Blanchard 
915cb2c9b27SAnton Blanchard 	if (cpu_has_feature(CPU_FTR_CTRL) && test_thread_flag(TIF_RUNLATCH)) {
916cb2c9b27SAnton Blanchard 		HMT_medium();
917cb2c9b27SAnton Blanchard 
918cb2c9b27SAnton Blanchard 		clear_thread_flag(TIF_RUNLATCH);
919cb2c9b27SAnton Blanchard 
920cb2c9b27SAnton Blanchard 		ctrl = mfspr(SPRN_CTRLF);
921cb2c9b27SAnton Blanchard 		ctrl &= ~CTRL_RUNLATCH;
922cb2c9b27SAnton Blanchard 		mtspr(SPRN_CTRLT, ctrl);
923cb2c9b27SAnton Blanchard 	}
924cb2c9b27SAnton Blanchard }
925cb2c9b27SAnton Blanchard #endif
926