xref: /linux/arch/powerpc/kernel/process.c (revision 06d67d54741a5bfefa31945ef195dfa748c29025)
114cf11afSPaul Mackerras /*
214cf11afSPaul Mackerras  *  arch/ppc/kernel/process.c
314cf11afSPaul Mackerras  *
414cf11afSPaul Mackerras  *  Derived from "arch/i386/kernel/process.c"
514cf11afSPaul Mackerras  *    Copyright (C) 1995  Linus Torvalds
614cf11afSPaul Mackerras  *
714cf11afSPaul Mackerras  *  Updated and modified by Cort Dougan (cort@cs.nmt.edu) and
814cf11afSPaul Mackerras  *  Paul Mackerras (paulus@cs.anu.edu.au)
914cf11afSPaul Mackerras  *
1014cf11afSPaul Mackerras  *  PowerPC version
1114cf11afSPaul Mackerras  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
1214cf11afSPaul Mackerras  *
1314cf11afSPaul Mackerras  *  This program is free software; you can redistribute it and/or
1414cf11afSPaul Mackerras  *  modify it under the terms of the GNU General Public License
1514cf11afSPaul Mackerras  *  as published by the Free Software Foundation; either version
1614cf11afSPaul Mackerras  *  2 of the License, or (at your option) any later version.
1714cf11afSPaul Mackerras  */
1814cf11afSPaul Mackerras 
1914cf11afSPaul Mackerras #include <linux/config.h>
2014cf11afSPaul Mackerras #include <linux/errno.h>
2114cf11afSPaul Mackerras #include <linux/sched.h>
2214cf11afSPaul Mackerras #include <linux/kernel.h>
2314cf11afSPaul Mackerras #include <linux/mm.h>
2414cf11afSPaul Mackerras #include <linux/smp.h>
2514cf11afSPaul Mackerras #include <linux/smp_lock.h>
2614cf11afSPaul Mackerras #include <linux/stddef.h>
2714cf11afSPaul Mackerras #include <linux/unistd.h>
2814cf11afSPaul Mackerras #include <linux/ptrace.h>
2914cf11afSPaul Mackerras #include <linux/slab.h>
3014cf11afSPaul Mackerras #include <linux/user.h>
3114cf11afSPaul Mackerras #include <linux/elf.h>
3214cf11afSPaul Mackerras #include <linux/init.h>
3314cf11afSPaul Mackerras #include <linux/prctl.h>
3414cf11afSPaul Mackerras #include <linux/init_task.h>
3514cf11afSPaul Mackerras #include <linux/module.h>
3614cf11afSPaul Mackerras #include <linux/kallsyms.h>
3714cf11afSPaul Mackerras #include <linux/mqueue.h>
3814cf11afSPaul Mackerras #include <linux/hardirq.h>
39*06d67d54SPaul Mackerras #include <linux/utsname.h>
40*06d67d54SPaul Mackerras #include <linux/kprobes.h>
4114cf11afSPaul Mackerras 
4214cf11afSPaul Mackerras #include <asm/pgtable.h>
4314cf11afSPaul Mackerras #include <asm/uaccess.h>
4414cf11afSPaul Mackerras #include <asm/system.h>
4514cf11afSPaul Mackerras #include <asm/io.h>
4614cf11afSPaul Mackerras #include <asm/processor.h>
4714cf11afSPaul Mackerras #include <asm/mmu.h>
4814cf11afSPaul Mackerras #include <asm/prom.h>
49*06d67d54SPaul Mackerras #ifdef CONFIG_PPC64
50*06d67d54SPaul Mackerras #include <asm/firmware.h>
51*06d67d54SPaul Mackerras #include <asm/plpar_wrappers.h>
52*06d67d54SPaul Mackerras #include <asm/time.h>
53*06d67d54SPaul Mackerras #endif
5414cf11afSPaul Mackerras 
5514cf11afSPaul Mackerras extern unsigned long _get_SP(void);
5614cf11afSPaul Mackerras 
5714cf11afSPaul Mackerras #ifndef CONFIG_SMP
5814cf11afSPaul Mackerras struct task_struct *last_task_used_math = NULL;
5914cf11afSPaul Mackerras struct task_struct *last_task_used_altivec = NULL;
6014cf11afSPaul Mackerras struct task_struct *last_task_used_spe = NULL;
6114cf11afSPaul Mackerras #endif
6214cf11afSPaul Mackerras 
6314cf11afSPaul Mackerras /*
6414cf11afSPaul Mackerras  * Make sure the floating-point register state in the
6514cf11afSPaul Mackerras  * the thread_struct is up to date for task tsk.
6614cf11afSPaul Mackerras  */
6714cf11afSPaul Mackerras void flush_fp_to_thread(struct task_struct *tsk)
6814cf11afSPaul Mackerras {
6914cf11afSPaul Mackerras 	if (tsk->thread.regs) {
7014cf11afSPaul Mackerras 		/*
7114cf11afSPaul Mackerras 		 * We need to disable preemption here because if we didn't,
7214cf11afSPaul Mackerras 		 * another process could get scheduled after the regs->msr
7314cf11afSPaul Mackerras 		 * test but before we have finished saving the FP registers
7414cf11afSPaul Mackerras 		 * to the thread_struct.  That process could take over the
7514cf11afSPaul Mackerras 		 * FPU, and then when we get scheduled again we would store
7614cf11afSPaul Mackerras 		 * bogus values for the remaining FP registers.
7714cf11afSPaul Mackerras 		 */
7814cf11afSPaul Mackerras 		preempt_disable();
7914cf11afSPaul Mackerras 		if (tsk->thread.regs->msr & MSR_FP) {
8014cf11afSPaul Mackerras #ifdef CONFIG_SMP
8114cf11afSPaul Mackerras 			/*
8214cf11afSPaul Mackerras 			 * This should only ever be called for current or
8314cf11afSPaul Mackerras 			 * for a stopped child process.  Since we save away
8414cf11afSPaul Mackerras 			 * the FP register state on context switch on SMP,
8514cf11afSPaul Mackerras 			 * there is something wrong if a stopped child appears
8614cf11afSPaul Mackerras 			 * to still have its FP state in the CPU registers.
8714cf11afSPaul Mackerras 			 */
8814cf11afSPaul Mackerras 			BUG_ON(tsk != current);
8914cf11afSPaul Mackerras #endif
9014cf11afSPaul Mackerras 			giveup_fpu(current);
9114cf11afSPaul Mackerras 		}
9214cf11afSPaul Mackerras 		preempt_enable();
9314cf11afSPaul Mackerras 	}
9414cf11afSPaul Mackerras }
9514cf11afSPaul Mackerras 
9614cf11afSPaul Mackerras void enable_kernel_fp(void)
9714cf11afSPaul Mackerras {
9814cf11afSPaul Mackerras 	WARN_ON(preemptible());
9914cf11afSPaul Mackerras 
10014cf11afSPaul Mackerras #ifdef CONFIG_SMP
10114cf11afSPaul Mackerras 	if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
10214cf11afSPaul Mackerras 		giveup_fpu(current);
10314cf11afSPaul Mackerras 	else
10414cf11afSPaul Mackerras 		giveup_fpu(NULL);	/* just enables FP for kernel */
10514cf11afSPaul Mackerras #else
10614cf11afSPaul Mackerras 	giveup_fpu(last_task_used_math);
10714cf11afSPaul Mackerras #endif /* CONFIG_SMP */
10814cf11afSPaul Mackerras }
10914cf11afSPaul Mackerras EXPORT_SYMBOL(enable_kernel_fp);
11014cf11afSPaul Mackerras 
11114cf11afSPaul Mackerras int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
11214cf11afSPaul Mackerras {
11314cf11afSPaul Mackerras 	if (!tsk->thread.regs)
11414cf11afSPaul Mackerras 		return 0;
11514cf11afSPaul Mackerras 	flush_fp_to_thread(current);
11614cf11afSPaul Mackerras 
11714cf11afSPaul Mackerras 	memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs));
11814cf11afSPaul Mackerras 
11914cf11afSPaul Mackerras 	return 1;
12014cf11afSPaul Mackerras }
12114cf11afSPaul Mackerras 
12214cf11afSPaul Mackerras #ifdef CONFIG_ALTIVEC
12314cf11afSPaul Mackerras void enable_kernel_altivec(void)
12414cf11afSPaul Mackerras {
12514cf11afSPaul Mackerras 	WARN_ON(preemptible());
12614cf11afSPaul Mackerras 
12714cf11afSPaul Mackerras #ifdef CONFIG_SMP
12814cf11afSPaul Mackerras 	if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
12914cf11afSPaul Mackerras 		giveup_altivec(current);
13014cf11afSPaul Mackerras 	else
13114cf11afSPaul Mackerras 		giveup_altivec(NULL);	/* just enable AltiVec for kernel - force */
13214cf11afSPaul Mackerras #else
13314cf11afSPaul Mackerras 	giveup_altivec(last_task_used_altivec);
13414cf11afSPaul Mackerras #endif /* CONFIG_SMP */
13514cf11afSPaul Mackerras }
13614cf11afSPaul Mackerras EXPORT_SYMBOL(enable_kernel_altivec);
13714cf11afSPaul Mackerras 
13814cf11afSPaul Mackerras /*
13914cf11afSPaul Mackerras  * Make sure the VMX/Altivec register state in the
14014cf11afSPaul Mackerras  * the thread_struct is up to date for task tsk.
14114cf11afSPaul Mackerras  */
14214cf11afSPaul Mackerras void flush_altivec_to_thread(struct task_struct *tsk)
14314cf11afSPaul Mackerras {
14414cf11afSPaul Mackerras 	if (tsk->thread.regs) {
14514cf11afSPaul Mackerras 		preempt_disable();
14614cf11afSPaul Mackerras 		if (tsk->thread.regs->msr & MSR_VEC) {
14714cf11afSPaul Mackerras #ifdef CONFIG_SMP
14814cf11afSPaul Mackerras 			BUG_ON(tsk != current);
14914cf11afSPaul Mackerras #endif
15014cf11afSPaul Mackerras 			giveup_altivec(current);
15114cf11afSPaul Mackerras 		}
15214cf11afSPaul Mackerras 		preempt_enable();
15314cf11afSPaul Mackerras 	}
15414cf11afSPaul Mackerras }
15514cf11afSPaul Mackerras 
15614cf11afSPaul Mackerras int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
15714cf11afSPaul Mackerras {
15814cf11afSPaul Mackerras 	flush_altivec_to_thread(current);
15914cf11afSPaul Mackerras 	memcpy(vrregs, &current->thread.vr[0], sizeof(*vrregs));
16014cf11afSPaul Mackerras 	return 1;
16114cf11afSPaul Mackerras }
16214cf11afSPaul Mackerras #endif /* CONFIG_ALTIVEC */
16314cf11afSPaul Mackerras 
16414cf11afSPaul Mackerras #ifdef CONFIG_SPE
16514cf11afSPaul Mackerras 
16614cf11afSPaul Mackerras void enable_kernel_spe(void)
16714cf11afSPaul Mackerras {
16814cf11afSPaul Mackerras 	WARN_ON(preemptible());
16914cf11afSPaul Mackerras 
17014cf11afSPaul Mackerras #ifdef CONFIG_SMP
17114cf11afSPaul Mackerras 	if (current->thread.regs && (current->thread.regs->msr & MSR_SPE))
17214cf11afSPaul Mackerras 		giveup_spe(current);
17314cf11afSPaul Mackerras 	else
17414cf11afSPaul Mackerras 		giveup_spe(NULL);	/* just enable SPE for kernel - force */
17514cf11afSPaul Mackerras #else
17614cf11afSPaul Mackerras 	giveup_spe(last_task_used_spe);
17714cf11afSPaul Mackerras #endif /* __SMP __ */
17814cf11afSPaul Mackerras }
17914cf11afSPaul Mackerras EXPORT_SYMBOL(enable_kernel_spe);
18014cf11afSPaul Mackerras 
18114cf11afSPaul Mackerras void flush_spe_to_thread(struct task_struct *tsk)
18214cf11afSPaul Mackerras {
18314cf11afSPaul Mackerras 	if (tsk->thread.regs) {
18414cf11afSPaul Mackerras 		preempt_disable();
18514cf11afSPaul Mackerras 		if (tsk->thread.regs->msr & MSR_SPE) {
18614cf11afSPaul Mackerras #ifdef CONFIG_SMP
18714cf11afSPaul Mackerras 			BUG_ON(tsk != current);
18814cf11afSPaul Mackerras #endif
18914cf11afSPaul Mackerras 			giveup_spe(current);
19014cf11afSPaul Mackerras 		}
19114cf11afSPaul Mackerras 		preempt_enable();
19214cf11afSPaul Mackerras 	}
19314cf11afSPaul Mackerras }
19414cf11afSPaul Mackerras 
19514cf11afSPaul Mackerras int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
19614cf11afSPaul Mackerras {
19714cf11afSPaul Mackerras 	flush_spe_to_thread(current);
19814cf11afSPaul Mackerras 	/* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */
19914cf11afSPaul Mackerras 	memcpy(evrregs, &current->thread.evr[0], sizeof(u32) * 35);
20014cf11afSPaul Mackerras 	return 1;
20114cf11afSPaul Mackerras }
20214cf11afSPaul Mackerras #endif /* CONFIG_SPE */
20314cf11afSPaul Mackerras 
20414cf11afSPaul Mackerras static void set_dabr_spr(unsigned long val)
20514cf11afSPaul Mackerras {
20614cf11afSPaul Mackerras 	mtspr(SPRN_DABR, val);
20714cf11afSPaul Mackerras }
20814cf11afSPaul Mackerras 
20914cf11afSPaul Mackerras int set_dabr(unsigned long dabr)
21014cf11afSPaul Mackerras {
21114cf11afSPaul Mackerras 	int ret = 0;
21214cf11afSPaul Mackerras 
21314cf11afSPaul Mackerras #ifdef CONFIG_PPC64
21414cf11afSPaul Mackerras 	if (firmware_has_feature(FW_FEATURE_XDABR)) {
21514cf11afSPaul Mackerras 		/* We want to catch accesses from kernel and userspace */
21614cf11afSPaul Mackerras 		unsigned long flags = H_DABRX_KERNEL|H_DABRX_USER;
21714cf11afSPaul Mackerras 		ret = plpar_set_xdabr(dabr, flags);
21814cf11afSPaul Mackerras 	} else if (firmware_has_feature(FW_FEATURE_DABR)) {
21914cf11afSPaul Mackerras 		ret = plpar_set_dabr(dabr);
22014cf11afSPaul Mackerras 	} else
22114cf11afSPaul Mackerras #endif
22214cf11afSPaul Mackerras 		set_dabr_spr(dabr);
22314cf11afSPaul Mackerras 
22414cf11afSPaul Mackerras 	return ret;
22514cf11afSPaul Mackerras }
22614cf11afSPaul Mackerras 
227*06d67d54SPaul Mackerras #ifdef CONFIG_PPC64
228*06d67d54SPaul Mackerras DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array);
22914cf11afSPaul Mackerras static DEFINE_PER_CPU(unsigned long, current_dabr);
230*06d67d54SPaul Mackerras #endif
23114cf11afSPaul Mackerras 
23214cf11afSPaul Mackerras struct task_struct *__switch_to(struct task_struct *prev,
23314cf11afSPaul Mackerras 	struct task_struct *new)
23414cf11afSPaul Mackerras {
23514cf11afSPaul Mackerras 	struct thread_struct *new_thread, *old_thread;
23614cf11afSPaul Mackerras 	unsigned long flags;
23714cf11afSPaul Mackerras 	struct task_struct *last;
23814cf11afSPaul Mackerras 
23914cf11afSPaul Mackerras #ifdef CONFIG_SMP
24014cf11afSPaul Mackerras 	/* avoid complexity of lazy save/restore of fpu
24114cf11afSPaul Mackerras 	 * by just saving it every time we switch out if
24214cf11afSPaul Mackerras 	 * this task used the fpu during the last quantum.
24314cf11afSPaul Mackerras 	 *
24414cf11afSPaul Mackerras 	 * If it tries to use the fpu again, it'll trap and
24514cf11afSPaul Mackerras 	 * reload its fp regs.  So we don't have to do a restore
24614cf11afSPaul Mackerras 	 * every switch, just a save.
24714cf11afSPaul Mackerras 	 *  -- Cort
24814cf11afSPaul Mackerras 	 */
24914cf11afSPaul Mackerras 	if (prev->thread.regs && (prev->thread.regs->msr & MSR_FP))
25014cf11afSPaul Mackerras 		giveup_fpu(prev);
25114cf11afSPaul Mackerras #ifdef CONFIG_ALTIVEC
25214cf11afSPaul Mackerras 	/*
25314cf11afSPaul Mackerras 	 * If the previous thread used altivec in the last quantum
25414cf11afSPaul Mackerras 	 * (thus changing altivec regs) then save them.
25514cf11afSPaul Mackerras 	 * We used to check the VRSAVE register but not all apps
25614cf11afSPaul Mackerras 	 * set it, so we don't rely on it now (and in fact we need
25714cf11afSPaul Mackerras 	 * to save & restore VSCR even if VRSAVE == 0).  -- paulus
25814cf11afSPaul Mackerras 	 *
25914cf11afSPaul Mackerras 	 * On SMP we always save/restore altivec regs just to avoid the
26014cf11afSPaul Mackerras 	 * complexity of changing processors.
26114cf11afSPaul Mackerras 	 *  -- Cort
26214cf11afSPaul Mackerras 	 */
26314cf11afSPaul Mackerras 	if (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC))
26414cf11afSPaul Mackerras 		giveup_altivec(prev);
26514cf11afSPaul Mackerras #endif /* CONFIG_ALTIVEC */
26614cf11afSPaul Mackerras #ifdef CONFIG_SPE
26714cf11afSPaul Mackerras 	/*
26814cf11afSPaul Mackerras 	 * If the previous thread used spe in the last quantum
26914cf11afSPaul Mackerras 	 * (thus changing spe regs) then save them.
27014cf11afSPaul Mackerras 	 *
27114cf11afSPaul Mackerras 	 * On SMP we always save/restore spe regs just to avoid the
27214cf11afSPaul Mackerras 	 * complexity of changing processors.
27314cf11afSPaul Mackerras 	 */
27414cf11afSPaul Mackerras 	if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE)))
27514cf11afSPaul Mackerras 		giveup_spe(prev);
276c0c0d996SPaul Mackerras #endif /* CONFIG_SPE */
277c0c0d996SPaul Mackerras 
278c0c0d996SPaul Mackerras #else  /* CONFIG_SMP */
279c0c0d996SPaul Mackerras #ifdef CONFIG_ALTIVEC
280c0c0d996SPaul Mackerras 	/* Avoid the trap.  On smp this this never happens since
281c0c0d996SPaul Mackerras 	 * we don't set last_task_used_altivec -- Cort
282c0c0d996SPaul Mackerras 	 */
283c0c0d996SPaul Mackerras 	if (new->thread.regs && last_task_used_altivec == new)
284c0c0d996SPaul Mackerras 		new->thread.regs->msr |= MSR_VEC;
285c0c0d996SPaul Mackerras #endif /* CONFIG_ALTIVEC */
286c0c0d996SPaul Mackerras #ifdef CONFIG_SPE
28714cf11afSPaul Mackerras 	/* Avoid the trap.  On smp this this never happens since
28814cf11afSPaul Mackerras 	 * we don't set last_task_used_spe
28914cf11afSPaul Mackerras 	 */
29014cf11afSPaul Mackerras 	if (new->thread.regs && last_task_used_spe == new)
29114cf11afSPaul Mackerras 		new->thread.regs->msr |= MSR_SPE;
29214cf11afSPaul Mackerras #endif /* CONFIG_SPE */
293c0c0d996SPaul Mackerras 
29414cf11afSPaul Mackerras #endif /* CONFIG_SMP */
29514cf11afSPaul Mackerras 
29614cf11afSPaul Mackerras #ifdef CONFIG_PPC64	/* for now */
29714cf11afSPaul Mackerras 	if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) {
29814cf11afSPaul Mackerras 		set_dabr(new->thread.dabr);
29914cf11afSPaul Mackerras 		__get_cpu_var(current_dabr) = new->thread.dabr;
30014cf11afSPaul Mackerras 	}
301*06d67d54SPaul Mackerras 
302*06d67d54SPaul Mackerras 	flush_tlb_pending();
30314cf11afSPaul Mackerras #endif
30414cf11afSPaul Mackerras 
30514cf11afSPaul Mackerras 	new_thread = &new->thread;
30614cf11afSPaul Mackerras 	old_thread = &current->thread;
307*06d67d54SPaul Mackerras 
308*06d67d54SPaul Mackerras #ifdef CONFIG_PPC64
309*06d67d54SPaul Mackerras 	/*
310*06d67d54SPaul Mackerras 	 * Collect processor utilization data per process
311*06d67d54SPaul Mackerras 	 */
312*06d67d54SPaul Mackerras 	if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
313*06d67d54SPaul Mackerras 		struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array);
314*06d67d54SPaul Mackerras 		long unsigned start_tb, current_tb;
315*06d67d54SPaul Mackerras 		start_tb = old_thread->start_tb;
316*06d67d54SPaul Mackerras 		cu->current_tb = current_tb = mfspr(SPRN_PURR);
317*06d67d54SPaul Mackerras 		old_thread->accum_tb += (current_tb - start_tb);
318*06d67d54SPaul Mackerras 		new_thread->start_tb = current_tb;
319*06d67d54SPaul Mackerras 	}
320*06d67d54SPaul Mackerras #endif
321*06d67d54SPaul Mackerras 
32214cf11afSPaul Mackerras 	local_irq_save(flags);
32314cf11afSPaul Mackerras 	last = _switch(old_thread, new_thread);
32414cf11afSPaul Mackerras 
32514cf11afSPaul Mackerras 	local_irq_restore(flags);
32614cf11afSPaul Mackerras 
32714cf11afSPaul Mackerras 	return last;
32814cf11afSPaul Mackerras }
32914cf11afSPaul Mackerras 
330*06d67d54SPaul Mackerras static int instructions_to_print = 16;
331*06d67d54SPaul Mackerras 
332*06d67d54SPaul Mackerras #ifdef CONFIG_PPC64
333*06d67d54SPaul Mackerras #define BAD_PC(pc)	((REGION_ID(pc) != KERNEL_REGION_ID) && \
334*06d67d54SPaul Mackerras 		         (REGION_ID(pc) != VMALLOC_REGION_ID))
335*06d67d54SPaul Mackerras #else
336*06d67d54SPaul Mackerras #define BAD_PC(pc)	((pc) < KERNELBASE)
337*06d67d54SPaul Mackerras #endif
338*06d67d54SPaul Mackerras 
339*06d67d54SPaul Mackerras static void show_instructions(struct pt_regs *regs)
340*06d67d54SPaul Mackerras {
341*06d67d54SPaul Mackerras 	int i;
342*06d67d54SPaul Mackerras 	unsigned long pc = regs->nip - (instructions_to_print * 3 / 4 *
343*06d67d54SPaul Mackerras 			sizeof(int));
344*06d67d54SPaul Mackerras 
345*06d67d54SPaul Mackerras 	printk("Instruction dump:");
346*06d67d54SPaul Mackerras 
347*06d67d54SPaul Mackerras 	for (i = 0; i < instructions_to_print; i++) {
348*06d67d54SPaul Mackerras 		int instr;
349*06d67d54SPaul Mackerras 
350*06d67d54SPaul Mackerras 		if (!(i % 8))
351*06d67d54SPaul Mackerras 			printk("\n");
352*06d67d54SPaul Mackerras 
353*06d67d54SPaul Mackerras 		if (BAD_PC(pc) || __get_user(instr, (unsigned int *)pc)) {
354*06d67d54SPaul Mackerras 			printk("XXXXXXXX ");
355*06d67d54SPaul Mackerras 		} else {
356*06d67d54SPaul Mackerras 			if (regs->nip == pc)
357*06d67d54SPaul Mackerras 				printk("<%08x> ", instr);
358*06d67d54SPaul Mackerras 			else
359*06d67d54SPaul Mackerras 				printk("%08x ", instr);
360*06d67d54SPaul Mackerras 		}
361*06d67d54SPaul Mackerras 
362*06d67d54SPaul Mackerras 		pc += sizeof(int);
363*06d67d54SPaul Mackerras 	}
364*06d67d54SPaul Mackerras 
365*06d67d54SPaul Mackerras 	printk("\n");
366*06d67d54SPaul Mackerras }
367*06d67d54SPaul Mackerras 
368*06d67d54SPaul Mackerras static struct regbit {
369*06d67d54SPaul Mackerras 	unsigned long bit;
370*06d67d54SPaul Mackerras 	const char *name;
371*06d67d54SPaul Mackerras } msr_bits[] = {
372*06d67d54SPaul Mackerras 	{MSR_EE,	"EE"},
373*06d67d54SPaul Mackerras 	{MSR_PR,	"PR"},
374*06d67d54SPaul Mackerras 	{MSR_FP,	"FP"},
375*06d67d54SPaul Mackerras 	{MSR_ME,	"ME"},
376*06d67d54SPaul Mackerras 	{MSR_IR,	"IR"},
377*06d67d54SPaul Mackerras 	{MSR_DR,	"DR"},
378*06d67d54SPaul Mackerras 	{0,		NULL}
379*06d67d54SPaul Mackerras };
380*06d67d54SPaul Mackerras 
381*06d67d54SPaul Mackerras static void printbits(unsigned long val, struct regbit *bits)
382*06d67d54SPaul Mackerras {
383*06d67d54SPaul Mackerras 	const char *sep = "";
384*06d67d54SPaul Mackerras 
385*06d67d54SPaul Mackerras 	printk("<");
386*06d67d54SPaul Mackerras 	for (; bits->bit; ++bits)
387*06d67d54SPaul Mackerras 		if (val & bits->bit) {
388*06d67d54SPaul Mackerras 			printk("%s%s", sep, bits->name);
389*06d67d54SPaul Mackerras 			sep = ",";
390*06d67d54SPaul Mackerras 		}
391*06d67d54SPaul Mackerras 	printk(">");
392*06d67d54SPaul Mackerras }
393*06d67d54SPaul Mackerras 
394*06d67d54SPaul Mackerras #ifdef CONFIG_PPC64
395*06d67d54SPaul Mackerras #define REG		"%016lX"
396*06d67d54SPaul Mackerras #define REGS_PER_LINE	4
397*06d67d54SPaul Mackerras #define LAST_VOLATILE	13
398*06d67d54SPaul Mackerras #else
399*06d67d54SPaul Mackerras #define REG		"%08lX"
400*06d67d54SPaul Mackerras #define REGS_PER_LINE	8
401*06d67d54SPaul Mackerras #define LAST_VOLATILE	12
402*06d67d54SPaul Mackerras #endif
403*06d67d54SPaul Mackerras 
40414cf11afSPaul Mackerras void show_regs(struct pt_regs * regs)
40514cf11afSPaul Mackerras {
40614cf11afSPaul Mackerras 	int i, trap;
40714cf11afSPaul Mackerras 
408*06d67d54SPaul Mackerras 	printk("NIP: "REG" LR: "REG" CTR: "REG"\n",
409*06d67d54SPaul Mackerras 	       regs->nip, regs->link, regs->ctr);
410*06d67d54SPaul Mackerras 	printk("REGS: %p TRAP: %04lx   %s  (%s)\n",
411*06d67d54SPaul Mackerras 	       regs, regs->trap, print_tainted(), system_utsname.release);
412*06d67d54SPaul Mackerras 	printk("MSR: "REG" ", regs->msr);
413*06d67d54SPaul Mackerras 	printbits(regs->msr, msr_bits);
414*06d67d54SPaul Mackerras 	printk("  CR: %08lX  XER: %08lX\n", regs->ccr, regs->xer);
41514cf11afSPaul Mackerras 	trap = TRAP(regs);
41614cf11afSPaul Mackerras 	if (trap == 0x300 || trap == 0x600)
417*06d67d54SPaul Mackerras 		printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
418*06d67d54SPaul Mackerras 	printk("TASK = %p[%d] '%s' THREAD: %p",
41914cf11afSPaul Mackerras 	       current, current->pid, current->comm, current->thread_info);
42014cf11afSPaul Mackerras 
42114cf11afSPaul Mackerras #ifdef CONFIG_SMP
42214cf11afSPaul Mackerras 	printk(" CPU: %d", smp_processor_id());
42314cf11afSPaul Mackerras #endif /* CONFIG_SMP */
42414cf11afSPaul Mackerras 
42514cf11afSPaul Mackerras 	for (i = 0;  i < 32;  i++) {
426*06d67d54SPaul Mackerras 		if ((i % REGS_PER_LINE) == 0)
42714cf11afSPaul Mackerras 			printk("\n" KERN_INFO "GPR%02d: ", i);
428*06d67d54SPaul Mackerras 		printk(REG " ", regs->gpr[i]);
429*06d67d54SPaul Mackerras 		if (i == LAST_VOLATILE && !FULL_REGS(regs))
43014cf11afSPaul Mackerras 			break;
43114cf11afSPaul Mackerras 	}
43214cf11afSPaul Mackerras 	printk("\n");
43314cf11afSPaul Mackerras #ifdef CONFIG_KALLSYMS
43414cf11afSPaul Mackerras 	/*
43514cf11afSPaul Mackerras 	 * Lookup NIP late so we have the best change of getting the
43614cf11afSPaul Mackerras 	 * above info out without failing
43714cf11afSPaul Mackerras 	 */
438*06d67d54SPaul Mackerras 	printk("NIP ["REG"] ", regs->nip);
43914cf11afSPaul Mackerras 	print_symbol("%s\n", regs->nip);
440*06d67d54SPaul Mackerras 	printk("LR ["REG"] ", regs->link);
44114cf11afSPaul Mackerras 	print_symbol("%s\n", regs->link);
44214cf11afSPaul Mackerras #endif
44314cf11afSPaul Mackerras 	show_stack(current, (unsigned long *) regs->gpr[1]);
444*06d67d54SPaul Mackerras 	if (!user_mode(regs))
445*06d67d54SPaul Mackerras 		show_instructions(regs);
44614cf11afSPaul Mackerras }
44714cf11afSPaul Mackerras 
44814cf11afSPaul Mackerras void exit_thread(void)
44914cf11afSPaul Mackerras {
450*06d67d54SPaul Mackerras 	kprobe_flush_task(current);
451*06d67d54SPaul Mackerras 
45214cf11afSPaul Mackerras #ifndef CONFIG_SMP
45314cf11afSPaul Mackerras 	if (last_task_used_math == current)
45414cf11afSPaul Mackerras 		last_task_used_math = NULL;
45514cf11afSPaul Mackerras #ifdef CONFIG_ALTIVEC
45614cf11afSPaul Mackerras 	if (last_task_used_altivec == current)
45714cf11afSPaul Mackerras 		last_task_used_altivec = NULL;
45814cf11afSPaul Mackerras #endif /* CONFIG_ALTIVEC */
45914cf11afSPaul Mackerras #ifdef CONFIG_SPE
46014cf11afSPaul Mackerras 	if (last_task_used_spe == current)
46114cf11afSPaul Mackerras 		last_task_used_spe = NULL;
46214cf11afSPaul Mackerras #endif
46314cf11afSPaul Mackerras #endif /* CONFIG_SMP */
46414cf11afSPaul Mackerras }
46514cf11afSPaul Mackerras 
46614cf11afSPaul Mackerras void flush_thread(void)
46714cf11afSPaul Mackerras {
468*06d67d54SPaul Mackerras #ifdef CONFIG_PPC64
469*06d67d54SPaul Mackerras 	struct thread_info *t = current_thread_info();
470*06d67d54SPaul Mackerras 
471*06d67d54SPaul Mackerras 	if (t->flags & _TIF_ABI_PENDING)
472*06d67d54SPaul Mackerras 		t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT);
473*06d67d54SPaul Mackerras #endif
474*06d67d54SPaul Mackerras 	kprobe_flush_task(current);
475*06d67d54SPaul Mackerras 
47614cf11afSPaul Mackerras #ifndef CONFIG_SMP
47714cf11afSPaul Mackerras 	if (last_task_used_math == current)
47814cf11afSPaul Mackerras 		last_task_used_math = NULL;
47914cf11afSPaul Mackerras #ifdef CONFIG_ALTIVEC
48014cf11afSPaul Mackerras 	if (last_task_used_altivec == current)
48114cf11afSPaul Mackerras 		last_task_used_altivec = NULL;
48214cf11afSPaul Mackerras #endif /* CONFIG_ALTIVEC */
48314cf11afSPaul Mackerras #ifdef CONFIG_SPE
48414cf11afSPaul Mackerras 	if (last_task_used_spe == current)
48514cf11afSPaul Mackerras 		last_task_used_spe = NULL;
48614cf11afSPaul Mackerras #endif
48714cf11afSPaul Mackerras #endif /* CONFIG_SMP */
48814cf11afSPaul Mackerras 
48914cf11afSPaul Mackerras #ifdef CONFIG_PPC64	/* for now */
49014cf11afSPaul Mackerras 	if (current->thread.dabr) {
49114cf11afSPaul Mackerras 		current->thread.dabr = 0;
49214cf11afSPaul Mackerras 		set_dabr(0);
49314cf11afSPaul Mackerras 	}
49414cf11afSPaul Mackerras #endif
49514cf11afSPaul Mackerras }
49614cf11afSPaul Mackerras 
49714cf11afSPaul Mackerras void
49814cf11afSPaul Mackerras release_thread(struct task_struct *t)
49914cf11afSPaul Mackerras {
50014cf11afSPaul Mackerras }
50114cf11afSPaul Mackerras 
50214cf11afSPaul Mackerras /*
50314cf11afSPaul Mackerras  * This gets called before we allocate a new thread and copy
50414cf11afSPaul Mackerras  * the current task into it.
50514cf11afSPaul Mackerras  */
50614cf11afSPaul Mackerras void prepare_to_copy(struct task_struct *tsk)
50714cf11afSPaul Mackerras {
50814cf11afSPaul Mackerras 	flush_fp_to_thread(current);
50914cf11afSPaul Mackerras 	flush_altivec_to_thread(current);
51014cf11afSPaul Mackerras 	flush_spe_to_thread(current);
51114cf11afSPaul Mackerras }
51214cf11afSPaul Mackerras 
51314cf11afSPaul Mackerras /*
51414cf11afSPaul Mackerras  * Copy a thread..
51514cf11afSPaul Mackerras  */
516*06d67d54SPaul Mackerras int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
517*06d67d54SPaul Mackerras 		unsigned long unused, struct task_struct *p,
518*06d67d54SPaul Mackerras 		struct pt_regs *regs)
51914cf11afSPaul Mackerras {
52014cf11afSPaul Mackerras 	struct pt_regs *childregs, *kregs;
52114cf11afSPaul Mackerras 	extern void ret_from_fork(void);
52214cf11afSPaul Mackerras 	unsigned long sp = (unsigned long)p->thread_info + THREAD_SIZE;
52314cf11afSPaul Mackerras 
52414cf11afSPaul Mackerras 	CHECK_FULL_REGS(regs);
52514cf11afSPaul Mackerras 	/* Copy registers */
52614cf11afSPaul Mackerras 	sp -= sizeof(struct pt_regs);
52714cf11afSPaul Mackerras 	childregs = (struct pt_regs *) sp;
52814cf11afSPaul Mackerras 	*childregs = *regs;
52914cf11afSPaul Mackerras 	if ((childregs->msr & MSR_PR) == 0) {
53014cf11afSPaul Mackerras 		/* for kernel thread, set `current' and stackptr in new task */
53114cf11afSPaul Mackerras 		childregs->gpr[1] = sp + sizeof(struct pt_regs);
532*06d67d54SPaul Mackerras #ifdef CONFIG_PPC32
53314cf11afSPaul Mackerras 		childregs->gpr[2] = (unsigned long) p;
534*06d67d54SPaul Mackerras #else
535*06d67d54SPaul Mackerras 		clear_ti_thread_flag(p->thread_info, TIF_32BIT);
536*06d67d54SPaul Mackerras #endif
53714cf11afSPaul Mackerras 		p->thread.regs = NULL;	/* no user register state */
53814cf11afSPaul Mackerras 	} else {
53914cf11afSPaul Mackerras 		childregs->gpr[1] = usp;
54014cf11afSPaul Mackerras 		p->thread.regs = childregs;
541*06d67d54SPaul Mackerras 		if (clone_flags & CLONE_SETTLS) {
542*06d67d54SPaul Mackerras #ifdef CONFIG_PPC64
543*06d67d54SPaul Mackerras 			if (!test_thread_flag(TIF_32BIT))
544*06d67d54SPaul Mackerras 				childregs->gpr[13] = childregs->gpr[6];
545*06d67d54SPaul Mackerras 			else
546*06d67d54SPaul Mackerras #endif
54714cf11afSPaul Mackerras 				childregs->gpr[2] = childregs->gpr[6];
54814cf11afSPaul Mackerras 		}
549*06d67d54SPaul Mackerras 	}
55014cf11afSPaul Mackerras 	childregs->gpr[3] = 0;  /* Result from fork() */
55114cf11afSPaul Mackerras 	sp -= STACK_FRAME_OVERHEAD;
55214cf11afSPaul Mackerras 
55314cf11afSPaul Mackerras 	/*
55414cf11afSPaul Mackerras 	 * The way this works is that at some point in the future
55514cf11afSPaul Mackerras 	 * some task will call _switch to switch to the new task.
55614cf11afSPaul Mackerras 	 * That will pop off the stack frame created below and start
55714cf11afSPaul Mackerras 	 * the new task running at ret_from_fork.  The new task will
55814cf11afSPaul Mackerras 	 * do some house keeping and then return from the fork or clone
55914cf11afSPaul Mackerras 	 * system call, using the stack frame created above.
56014cf11afSPaul Mackerras 	 */
56114cf11afSPaul Mackerras 	sp -= sizeof(struct pt_regs);
56214cf11afSPaul Mackerras 	kregs = (struct pt_regs *) sp;
56314cf11afSPaul Mackerras 	sp -= STACK_FRAME_OVERHEAD;
56414cf11afSPaul Mackerras 	p->thread.ksp = sp;
56514cf11afSPaul Mackerras 
566*06d67d54SPaul Mackerras #ifdef CONFIG_PPC64
567*06d67d54SPaul Mackerras 	if (cpu_has_feature(CPU_FTR_SLB)) {
568*06d67d54SPaul Mackerras 		unsigned long sp_vsid = get_kernel_vsid(sp);
569*06d67d54SPaul Mackerras 
570*06d67d54SPaul Mackerras 		sp_vsid <<= SLB_VSID_SHIFT;
571*06d67d54SPaul Mackerras 		sp_vsid |= SLB_VSID_KERNEL;
572*06d67d54SPaul Mackerras 		if (cpu_has_feature(CPU_FTR_16M_PAGE))
573*06d67d54SPaul Mackerras 			sp_vsid |= SLB_VSID_L;
574*06d67d54SPaul Mackerras 
575*06d67d54SPaul Mackerras 		p->thread.ksp_vsid = sp_vsid;
576*06d67d54SPaul Mackerras 	}
577*06d67d54SPaul Mackerras 
578*06d67d54SPaul Mackerras 	/*
579*06d67d54SPaul Mackerras 	 * The PPC64 ABI makes use of a TOC to contain function
580*06d67d54SPaul Mackerras 	 * pointers.  The function (ret_from_except) is actually a pointer
581*06d67d54SPaul Mackerras 	 * to the TOC entry.  The first entry is a pointer to the actual
582*06d67d54SPaul Mackerras 	 * function.
583*06d67d54SPaul Mackerras  	 */
584*06d67d54SPaul Mackerras 	kregs->nip = *((unsigned long *)ret_from_fork);
585*06d67d54SPaul Mackerras #else
586*06d67d54SPaul Mackerras 	kregs->nip = (unsigned long)ret_from_fork;
58714cf11afSPaul Mackerras 	p->thread.last_syscall = -1;
588*06d67d54SPaul Mackerras #endif
58914cf11afSPaul Mackerras 
59014cf11afSPaul Mackerras 	return 0;
59114cf11afSPaul Mackerras }
59214cf11afSPaul Mackerras 
59314cf11afSPaul Mackerras /*
59414cf11afSPaul Mackerras  * Set up a thread for executing a new program
59514cf11afSPaul Mackerras  */
596*06d67d54SPaul Mackerras void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
59714cf11afSPaul Mackerras {
59814cf11afSPaul Mackerras 	set_fs(USER_DS);
599*06d67d54SPaul Mackerras 
600*06d67d54SPaul Mackerras 	/*
601*06d67d54SPaul Mackerras 	 * If we exec out of a kernel thread then thread.regs will not be
602*06d67d54SPaul Mackerras 	 * set.  Do it now.
603*06d67d54SPaul Mackerras 	 */
604*06d67d54SPaul Mackerras 	if (!current->thread.regs) {
605*06d67d54SPaul Mackerras 		unsigned long childregs = (unsigned long)current->thread_info +
606*06d67d54SPaul Mackerras 						THREAD_SIZE;
607*06d67d54SPaul Mackerras 		childregs -= sizeof(struct pt_regs);
608*06d67d54SPaul Mackerras 		current->thread.regs = (struct pt_regs *)childregs;
609*06d67d54SPaul Mackerras 	}
610*06d67d54SPaul Mackerras 
61114cf11afSPaul Mackerras 	memset(regs->gpr, 0, sizeof(regs->gpr));
61214cf11afSPaul Mackerras 	regs->ctr = 0;
61314cf11afSPaul Mackerras 	regs->link = 0;
61414cf11afSPaul Mackerras 	regs->xer = 0;
61514cf11afSPaul Mackerras 	regs->ccr = 0;
61614cf11afSPaul Mackerras 	regs->gpr[1] = sp;
617*06d67d54SPaul Mackerras 
618*06d67d54SPaul Mackerras #ifdef CONFIG_PPC32
619*06d67d54SPaul Mackerras 	regs->mq = 0;
620*06d67d54SPaul Mackerras 	regs->nip = start;
62114cf11afSPaul Mackerras 	regs->msr = MSR_USER;
622*06d67d54SPaul Mackerras #else
623*06d67d54SPaul Mackerras 	if (test_thread_flag(TIF_32BIT)) {
624*06d67d54SPaul Mackerras 		unsigned long entry, toc, load_addr = regs->gpr[2];
625*06d67d54SPaul Mackerras 
626*06d67d54SPaul Mackerras 		/* start is a relocated pointer to the function descriptor for
627*06d67d54SPaul Mackerras 		 * the elf _start routine.  The first entry in the function
628*06d67d54SPaul Mackerras 		 * descriptor is the entry address of _start and the second
629*06d67d54SPaul Mackerras 		 * entry is the TOC value we need to use.
630*06d67d54SPaul Mackerras 		 */
631*06d67d54SPaul Mackerras 		__get_user(entry, (unsigned long __user *)start);
632*06d67d54SPaul Mackerras 		__get_user(toc, (unsigned long __user *)start+1);
633*06d67d54SPaul Mackerras 
634*06d67d54SPaul Mackerras 		/* Check whether the e_entry function descriptor entries
635*06d67d54SPaul Mackerras 		 * need to be relocated before we can use them.
636*06d67d54SPaul Mackerras 		 */
637*06d67d54SPaul Mackerras 		if (load_addr != 0) {
638*06d67d54SPaul Mackerras 			entry += load_addr;
639*06d67d54SPaul Mackerras 			toc   += load_addr;
640*06d67d54SPaul Mackerras 		}
641*06d67d54SPaul Mackerras 		regs->nip = entry;
642*06d67d54SPaul Mackerras 		regs->gpr[2] = toc;
643*06d67d54SPaul Mackerras 		regs->msr = MSR_USER64;
644*06d67d54SPaul Mackerras 	} else {
645*06d67d54SPaul Mackerras 		regs->nip = start;
646*06d67d54SPaul Mackerras 		regs->gpr[2] = 0;
647*06d67d54SPaul Mackerras 		regs->msr = MSR_USER32;
648*06d67d54SPaul Mackerras 	}
649*06d67d54SPaul Mackerras #endif
650*06d67d54SPaul Mackerras 
65114cf11afSPaul Mackerras #ifndef CONFIG_SMP
65214cf11afSPaul Mackerras 	if (last_task_used_math == current)
65314cf11afSPaul Mackerras 		last_task_used_math = NULL;
65414cf11afSPaul Mackerras #ifdef CONFIG_ALTIVEC
65514cf11afSPaul Mackerras 	if (last_task_used_altivec == current)
65614cf11afSPaul Mackerras 		last_task_used_altivec = NULL;
65714cf11afSPaul Mackerras #endif
65814cf11afSPaul Mackerras #ifdef CONFIG_SPE
65914cf11afSPaul Mackerras 	if (last_task_used_spe == current)
66014cf11afSPaul Mackerras 		last_task_used_spe = NULL;
66114cf11afSPaul Mackerras #endif
66214cf11afSPaul Mackerras #endif /* CONFIG_SMP */
66314cf11afSPaul Mackerras 	memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
66414cf11afSPaul Mackerras 	current->thread.fpscr = 0;
66514cf11afSPaul Mackerras #ifdef CONFIG_ALTIVEC
66614cf11afSPaul Mackerras 	memset(current->thread.vr, 0, sizeof(current->thread.vr));
66714cf11afSPaul Mackerras 	memset(&current->thread.vscr, 0, sizeof(current->thread.vscr));
668*06d67d54SPaul Mackerras 	current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */
66914cf11afSPaul Mackerras 	current->thread.vrsave = 0;
67014cf11afSPaul Mackerras 	current->thread.used_vr = 0;
67114cf11afSPaul Mackerras #endif /* CONFIG_ALTIVEC */
67214cf11afSPaul Mackerras #ifdef CONFIG_SPE
67314cf11afSPaul Mackerras 	memset(current->thread.evr, 0, sizeof(current->thread.evr));
67414cf11afSPaul Mackerras 	current->thread.acc = 0;
67514cf11afSPaul Mackerras 	current->thread.spefscr = 0;
67614cf11afSPaul Mackerras 	current->thread.used_spe = 0;
67714cf11afSPaul Mackerras #endif /* CONFIG_SPE */
67814cf11afSPaul Mackerras }
67914cf11afSPaul Mackerras 
68014cf11afSPaul Mackerras #define PR_FP_ALL_EXCEPT (PR_FP_EXC_DIV | PR_FP_EXC_OVF | PR_FP_EXC_UND \
68114cf11afSPaul Mackerras 		| PR_FP_EXC_RES | PR_FP_EXC_INV)
68214cf11afSPaul Mackerras 
68314cf11afSPaul Mackerras int set_fpexc_mode(struct task_struct *tsk, unsigned int val)
68414cf11afSPaul Mackerras {
68514cf11afSPaul Mackerras 	struct pt_regs *regs = tsk->thread.regs;
68614cf11afSPaul Mackerras 
68714cf11afSPaul Mackerras 	/* This is a bit hairy.  If we are an SPE enabled  processor
68814cf11afSPaul Mackerras 	 * (have embedded fp) we store the IEEE exception enable flags in
68914cf11afSPaul Mackerras 	 * fpexc_mode.  fpexc_mode is also used for setting FP exception
69014cf11afSPaul Mackerras 	 * mode (asyn, precise, disabled) for 'Classic' FP. */
69114cf11afSPaul Mackerras 	if (val & PR_FP_EXC_SW_ENABLE) {
69214cf11afSPaul Mackerras #ifdef CONFIG_SPE
69314cf11afSPaul Mackerras 		tsk->thread.fpexc_mode = val &
69414cf11afSPaul Mackerras 			(PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT);
695*06d67d54SPaul Mackerras 		return 0;
69614cf11afSPaul Mackerras #else
69714cf11afSPaul Mackerras 		return -EINVAL;
69814cf11afSPaul Mackerras #endif
699*06d67d54SPaul Mackerras 	}
700*06d67d54SPaul Mackerras 
70114cf11afSPaul Mackerras 	/* on a CONFIG_SPE this does not hurt us.  The bits that
70214cf11afSPaul Mackerras 	 * __pack_fe01 use do not overlap with bits used for
70314cf11afSPaul Mackerras 	 * PR_FP_EXC_SW_ENABLE.  Additionally, the MSR[FE0,FE1] bits
70414cf11afSPaul Mackerras 	 * on CONFIG_SPE implementations are reserved so writing to
70514cf11afSPaul Mackerras 	 * them does not change anything */
70614cf11afSPaul Mackerras 	if (val > PR_FP_EXC_PRECISE)
70714cf11afSPaul Mackerras 		return -EINVAL;
70814cf11afSPaul Mackerras 	tsk->thread.fpexc_mode = __pack_fe01(val);
70914cf11afSPaul Mackerras 	if (regs != NULL && (regs->msr & MSR_FP) != 0)
71014cf11afSPaul Mackerras 		regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1))
71114cf11afSPaul Mackerras 			| tsk->thread.fpexc_mode;
71214cf11afSPaul Mackerras 	return 0;
71314cf11afSPaul Mackerras }
71414cf11afSPaul Mackerras 
71514cf11afSPaul Mackerras int get_fpexc_mode(struct task_struct *tsk, unsigned long adr)
71614cf11afSPaul Mackerras {
71714cf11afSPaul Mackerras 	unsigned int val;
71814cf11afSPaul Mackerras 
71914cf11afSPaul Mackerras 	if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE)
72014cf11afSPaul Mackerras #ifdef CONFIG_SPE
72114cf11afSPaul Mackerras 		val = tsk->thread.fpexc_mode;
72214cf11afSPaul Mackerras #else
72314cf11afSPaul Mackerras 		return -EINVAL;
72414cf11afSPaul Mackerras #endif
72514cf11afSPaul Mackerras 	else
72614cf11afSPaul Mackerras 		val = __unpack_fe01(tsk->thread.fpexc_mode);
72714cf11afSPaul Mackerras 	return put_user(val, (unsigned int __user *) adr);
72814cf11afSPaul Mackerras }
72914cf11afSPaul Mackerras 
730*06d67d54SPaul Mackerras #define TRUNC_PTR(x)	((typeof(x))(((unsigned long)(x)) & 0xffffffff))
731*06d67d54SPaul Mackerras 
73214cf11afSPaul Mackerras int sys_clone(unsigned long clone_flags, unsigned long usp,
73314cf11afSPaul Mackerras 	      int __user *parent_tidp, void __user *child_threadptr,
73414cf11afSPaul Mackerras 	      int __user *child_tidp, int p6,
73514cf11afSPaul Mackerras 	      struct pt_regs *regs)
73614cf11afSPaul Mackerras {
73714cf11afSPaul Mackerras 	CHECK_FULL_REGS(regs);
73814cf11afSPaul Mackerras 	if (usp == 0)
73914cf11afSPaul Mackerras 		usp = regs->gpr[1];	/* stack pointer for child */
740*06d67d54SPaul Mackerras #ifdef CONFIG_PPC64
741*06d67d54SPaul Mackerras 	if (test_thread_flag(TIF_32BIT)) {
742*06d67d54SPaul Mackerras 		parent_tidp = TRUNC_PTR(parent_tidp);
743*06d67d54SPaul Mackerras 		child_tidp = TRUNC_PTR(child_tidp);
744*06d67d54SPaul Mackerras 	}
745*06d67d54SPaul Mackerras #endif
74614cf11afSPaul Mackerras  	return do_fork(clone_flags, usp, regs, 0, parent_tidp, child_tidp);
74714cf11afSPaul Mackerras }
74814cf11afSPaul Mackerras 
74914cf11afSPaul Mackerras int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
75014cf11afSPaul Mackerras 	     unsigned long p4, unsigned long p5, unsigned long p6,
75114cf11afSPaul Mackerras 	     struct pt_regs *regs)
75214cf11afSPaul Mackerras {
75314cf11afSPaul Mackerras 	CHECK_FULL_REGS(regs);
75414cf11afSPaul Mackerras 	return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL);
75514cf11afSPaul Mackerras }
75614cf11afSPaul Mackerras 
75714cf11afSPaul Mackerras int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
75814cf11afSPaul Mackerras 	      unsigned long p4, unsigned long p5, unsigned long p6,
75914cf11afSPaul Mackerras 	      struct pt_regs *regs)
76014cf11afSPaul Mackerras {
76114cf11afSPaul Mackerras 	CHECK_FULL_REGS(regs);
76214cf11afSPaul Mackerras 	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1],
76314cf11afSPaul Mackerras 			regs, 0, NULL, NULL);
76414cf11afSPaul Mackerras }
76514cf11afSPaul Mackerras 
76614cf11afSPaul Mackerras int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
76714cf11afSPaul Mackerras 	       unsigned long a3, unsigned long a4, unsigned long a5,
76814cf11afSPaul Mackerras 	       struct pt_regs *regs)
76914cf11afSPaul Mackerras {
77014cf11afSPaul Mackerras 	int error;
77114cf11afSPaul Mackerras 	char *filename;
77214cf11afSPaul Mackerras 
77314cf11afSPaul Mackerras 	filename = getname((char __user *) a0);
77414cf11afSPaul Mackerras 	error = PTR_ERR(filename);
77514cf11afSPaul Mackerras 	if (IS_ERR(filename))
77614cf11afSPaul Mackerras 		goto out;
77714cf11afSPaul Mackerras 	flush_fp_to_thread(current);
77814cf11afSPaul Mackerras 	flush_altivec_to_thread(current);
77914cf11afSPaul Mackerras 	flush_spe_to_thread(current);
78020c8c210SPaul Mackerras 	error = do_execve(filename, (char __user * __user *) a1,
78120c8c210SPaul Mackerras 			  (char __user * __user *) a2, regs);
78214cf11afSPaul Mackerras 	if (error == 0) {
78314cf11afSPaul Mackerras 		task_lock(current);
78414cf11afSPaul Mackerras 		current->ptrace &= ~PT_DTRACE;
78514cf11afSPaul Mackerras 		task_unlock(current);
78614cf11afSPaul Mackerras 	}
78714cf11afSPaul Mackerras 	putname(filename);
78814cf11afSPaul Mackerras out:
78914cf11afSPaul Mackerras 	return error;
79014cf11afSPaul Mackerras }
79114cf11afSPaul Mackerras 
79214cf11afSPaul Mackerras static int validate_sp(unsigned long sp, struct task_struct *p,
79314cf11afSPaul Mackerras 		       unsigned long nbytes)
79414cf11afSPaul Mackerras {
79514cf11afSPaul Mackerras 	unsigned long stack_page = (unsigned long)p->thread_info;
79614cf11afSPaul Mackerras 
79714cf11afSPaul Mackerras 	if (sp >= stack_page + sizeof(struct thread_struct)
79814cf11afSPaul Mackerras 	    && sp <= stack_page + THREAD_SIZE - nbytes)
79914cf11afSPaul Mackerras 		return 1;
80014cf11afSPaul Mackerras 
80114cf11afSPaul Mackerras #ifdef CONFIG_IRQSTACKS
80214cf11afSPaul Mackerras 	stack_page = (unsigned long) hardirq_ctx[task_cpu(p)];
80314cf11afSPaul Mackerras 	if (sp >= stack_page + sizeof(struct thread_struct)
80414cf11afSPaul Mackerras 	    && sp <= stack_page + THREAD_SIZE - nbytes)
80514cf11afSPaul Mackerras 		return 1;
80614cf11afSPaul Mackerras 
80714cf11afSPaul Mackerras 	stack_page = (unsigned long) softirq_ctx[task_cpu(p)];
80814cf11afSPaul Mackerras 	if (sp >= stack_page + sizeof(struct thread_struct)
80914cf11afSPaul Mackerras 	    && sp <= stack_page + THREAD_SIZE - nbytes)
81014cf11afSPaul Mackerras 		return 1;
81114cf11afSPaul Mackerras #endif
81214cf11afSPaul Mackerras 
81314cf11afSPaul Mackerras 	return 0;
81414cf11afSPaul Mackerras }
81514cf11afSPaul Mackerras 
816*06d67d54SPaul Mackerras #ifdef CONFIG_PPC64
817*06d67d54SPaul Mackerras #define MIN_STACK_FRAME	112	/* same as STACK_FRAME_OVERHEAD, in fact */
818*06d67d54SPaul Mackerras #define FRAME_LR_SAVE	2
819*06d67d54SPaul Mackerras #define INT_FRAME_SIZE	(sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD + 288)
820*06d67d54SPaul Mackerras #define REGS_MARKER	0x7265677368657265ul
821*06d67d54SPaul Mackerras #define FRAME_MARKER	12
822*06d67d54SPaul Mackerras #else
823*06d67d54SPaul Mackerras #define MIN_STACK_FRAME	16
824*06d67d54SPaul Mackerras #define FRAME_LR_SAVE	1
825*06d67d54SPaul Mackerras #define INT_FRAME_SIZE	(sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD)
826*06d67d54SPaul Mackerras #define REGS_MARKER	0x72656773ul
827*06d67d54SPaul Mackerras #define FRAME_MARKER	2
828*06d67d54SPaul Mackerras #endif
82914cf11afSPaul Mackerras 
830*06d67d54SPaul Mackerras unsigned long get_wchan(struct task_struct *p)
831*06d67d54SPaul Mackerras {
832*06d67d54SPaul Mackerras 	unsigned long ip, sp;
833*06d67d54SPaul Mackerras 	int count = 0;
834*06d67d54SPaul Mackerras 
835*06d67d54SPaul Mackerras 	if (!p || p == current || p->state == TASK_RUNNING)
836*06d67d54SPaul Mackerras 		return 0;
837*06d67d54SPaul Mackerras 
838*06d67d54SPaul Mackerras 	sp = p->thread.ksp;
839*06d67d54SPaul Mackerras 	if (!validate_sp(sp, p, MIN_STACK_FRAME))
840*06d67d54SPaul Mackerras 		return 0;
841*06d67d54SPaul Mackerras 
842*06d67d54SPaul Mackerras 	do {
843*06d67d54SPaul Mackerras 		sp = *(unsigned long *)sp;
844*06d67d54SPaul Mackerras 		if (!validate_sp(sp, p, MIN_STACK_FRAME))
845*06d67d54SPaul Mackerras 			return 0;
846*06d67d54SPaul Mackerras 		if (count > 0) {
847*06d67d54SPaul Mackerras 			ip = ((unsigned long *)sp)[FRAME_LR_SAVE];
848*06d67d54SPaul Mackerras 			if (!in_sched_functions(ip))
849*06d67d54SPaul Mackerras 				return ip;
850*06d67d54SPaul Mackerras 		}
851*06d67d54SPaul Mackerras 	} while (count++ < 16);
852*06d67d54SPaul Mackerras 	return 0;
853*06d67d54SPaul Mackerras }
854*06d67d54SPaul Mackerras EXPORT_SYMBOL(get_wchan);
855*06d67d54SPaul Mackerras 
856*06d67d54SPaul Mackerras static int kstack_depth_to_print = 64;
85714cf11afSPaul Mackerras 
85814cf11afSPaul Mackerras void show_stack(struct task_struct *tsk, unsigned long *stack)
85914cf11afSPaul Mackerras {
860*06d67d54SPaul Mackerras 	unsigned long sp, ip, lr, newsp;
86114cf11afSPaul Mackerras 	int count = 0;
862*06d67d54SPaul Mackerras 	int firstframe = 1;
86314cf11afSPaul Mackerras 
86414cf11afSPaul Mackerras 	sp = (unsigned long) stack;
86514cf11afSPaul Mackerras 	if (tsk == NULL)
86614cf11afSPaul Mackerras 		tsk = current;
86714cf11afSPaul Mackerras 	if (sp == 0) {
86814cf11afSPaul Mackerras 		if (tsk == current)
86914cf11afSPaul Mackerras 			asm("mr %0,1" : "=r" (sp));
87014cf11afSPaul Mackerras 		else
87114cf11afSPaul Mackerras 			sp = tsk->thread.ksp;
87214cf11afSPaul Mackerras 	}
87314cf11afSPaul Mackerras 
874*06d67d54SPaul Mackerras 	lr = 0;
875*06d67d54SPaul Mackerras 	printk("Call Trace:\n");
87614cf11afSPaul Mackerras 	do {
877*06d67d54SPaul Mackerras 		if (!validate_sp(sp, tsk, MIN_STACK_FRAME))
878*06d67d54SPaul Mackerras 			return;
879*06d67d54SPaul Mackerras 
880*06d67d54SPaul Mackerras 		stack = (unsigned long *) sp;
881*06d67d54SPaul Mackerras 		newsp = stack[0];
882*06d67d54SPaul Mackerras 		ip = stack[FRAME_LR_SAVE];
883*06d67d54SPaul Mackerras 		if (!firstframe || ip != lr) {
884*06d67d54SPaul Mackerras 			printk("["REG"] ["REG"] ", sp, ip);
885*06d67d54SPaul Mackerras 			print_symbol("%s", ip);
886*06d67d54SPaul Mackerras 			if (firstframe)
887*06d67d54SPaul Mackerras 				printk(" (unreliable)");
888*06d67d54SPaul Mackerras 			printk("\n");
88914cf11afSPaul Mackerras 		}
890*06d67d54SPaul Mackerras 		firstframe = 0;
891*06d67d54SPaul Mackerras 
892*06d67d54SPaul Mackerras 		/*
893*06d67d54SPaul Mackerras 		 * See if this is an exception frame.
894*06d67d54SPaul Mackerras 		 * We look for the "regshere" marker in the current frame.
895*06d67d54SPaul Mackerras 		 */
896*06d67d54SPaul Mackerras 		if (validate_sp(sp, tsk, INT_FRAME_SIZE)
897*06d67d54SPaul Mackerras 		    && stack[FRAME_MARKER] == REGS_MARKER) {
898*06d67d54SPaul Mackerras 			struct pt_regs *regs = (struct pt_regs *)
899*06d67d54SPaul Mackerras 				(sp + STACK_FRAME_OVERHEAD);
900*06d67d54SPaul Mackerras 			printk("--- Exception: %lx", regs->trap);
901*06d67d54SPaul Mackerras 			print_symbol(" at %s\n", regs->nip);
902*06d67d54SPaul Mackerras 			lr = regs->link;
903*06d67d54SPaul Mackerras 			print_symbol("    LR = %s\n", lr);
904*06d67d54SPaul Mackerras 			firstframe = 1;
90514cf11afSPaul Mackerras 		}
906*06d67d54SPaul Mackerras 
907*06d67d54SPaul Mackerras 		sp = newsp;
908*06d67d54SPaul Mackerras 	} while (count++ < kstack_depth_to_print);
909*06d67d54SPaul Mackerras }
910*06d67d54SPaul Mackerras 
911*06d67d54SPaul Mackerras void dump_stack(void)
912*06d67d54SPaul Mackerras {
913*06d67d54SPaul Mackerras 	show_stack(current, NULL);
914*06d67d54SPaul Mackerras }
915*06d67d54SPaul Mackerras EXPORT_SYMBOL(dump_stack);
916