diff options
Diffstat (limited to 'arch/arm/kernel/process.c')
| -rw-r--r-- | arch/arm/kernel/process.c | 65 | 
1 files changed, 51 insertions, 14 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index acf5e6fdb6dc..401e38be1f78 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -28,7 +28,9 @@  #include <linux/tick.h>  #include <linux/utsname.h>  #include <linux/uaccess.h> +#include <linux/random.h> +#include <asm/cacheflush.h>  #include <asm/leds.h>  #include <asm/processor.h>  #include <asm/system.h> @@ -36,6 +38,12 @@  #include <asm/stacktrace.h>  #include <asm/mach/time.h> +#ifdef CONFIG_CC_STACKPROTECTOR +#include <linux/stackprotector.h> +unsigned long __stack_chk_guard __read_mostly; +EXPORT_SYMBOL(__stack_chk_guard); +#endif +  static const char *processor_modes[] = {    "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,    "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26", @@ -84,10 +92,9 @@ __setup("hlt", hlt_setup);  void arm_machine_restart(char mode, const char *cmd)  { -	/* -	 * Clean and disable cache, and turn off interrupts -	 */ -	cpu_proc_fin(); +	/* Disable interrupts first */ +	local_irq_disable(); +	local_fiq_disable();  	/*  	 * Tell the mm system that we are going to reboot - @@ -96,6 +103,15 @@ void arm_machine_restart(char mode, const char *cmd)  	 */  	setup_mm_for_reboot(mode); +	/* Clean and invalidate caches */ +	flush_cache_all(); + +	/* Turn off caching */ +	cpu_proc_fin(); + +	/* Push out any further dirty data, and ensure cache is empty */ +	flush_cache_all(); +  	/*  	 * Now call the architecture specific reboot code.  	 */ @@ -189,19 +205,29 @@ int __init reboot_setup(char *str)  __setup("reboot=", reboot_setup); -void machine_halt(void) +void machine_shutdown(void)  { +#ifdef CONFIG_SMP +	smp_send_stop(); +#endif  } +void machine_halt(void) +{ +	machine_shutdown(); +	while (1); +}  void machine_power_off(void)  { +	machine_shutdown();  	if (pm_power_off)  		pm_power_off();  }  void machine_restart(char *cmd)  { +	machine_shutdown();  	arm_pm_restart(reboot_mode, cmd);  } @@ -351,17 +377,21 @@ EXPORT_SYMBOL(dump_fpu);  /*   * Shuffle the argument into the correct register before calling the - * thread function.  r1 is the thread argument, r2 is the pointer to - * the thread function, and r3 points to the exit function. + * thread function.  r4 is the thread argument, r5 is the pointer to + * the thread function, and r6 points to the exit function.   */  extern void kernel_thread_helper(void);  asm(	".pushsection .text\n"  "	.align\n"  "	.type	kernel_thread_helper, #function\n"  "kernel_thread_helper:\n" -"	mov	r0, r1\n" -"	mov	lr, r3\n" -"	mov	pc, r2\n" +#ifdef CONFIG_TRACE_IRQFLAGS +"	bl	trace_hardirqs_on\n" +#endif +"	msr	cpsr_c, r7\n" +"	mov	r0, r4\n" +"	mov	lr, r6\n" +"	mov	pc, r5\n"  "	.size	kernel_thread_helper, . - kernel_thread_helper\n"  "	.popsection"); @@ -391,11 +421,12 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)  	memset(®s, 0, sizeof(regs)); -	regs.ARM_r1 = (unsigned long)arg; -	regs.ARM_r2 = (unsigned long)fn; -	regs.ARM_r3 = (unsigned long)kernel_thread_exit; +	regs.ARM_r4 = (unsigned long)arg; +	regs.ARM_r5 = (unsigned long)fn; +	regs.ARM_r6 = (unsigned long)kernel_thread_exit; +	regs.ARM_r7 = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE;  	regs.ARM_pc = (unsigned long)kernel_thread_helper; -	regs.ARM_cpsr = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE; +	regs.ARM_cpsr = regs.ARM_r7 | PSR_I_BIT;  	return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);  } @@ -421,3 +452,9 @@ unsigned long get_wchan(struct task_struct *p)  	} while (count ++ < 16);  	return 0;  } + +unsigned long arch_randomize_brk(struct mm_struct *mm) +{ +	unsigned long range_end = mm->brk + 0x02000000; +	return randomize_range(mm->brk, range_end, 0) ? : mm->brk; +}  | 
