diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-03-31 13:53:43 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-03-31 13:53:43 +0200 |
commit | 7bee946358c3cb957d4aa648fc5ab3cad0b232d0 (patch) | |
tree | 693061ebde2abc35ecc846e5084630d7225aaaff /arch/powerpc/kernel/process.c | |
parent | d820ac4c2fa881079e6b689d2098adce337558ae (diff) | |
parent | 15f7176eb1cccec0a332541285ee752b935c1c85 (diff) |
Merge branch 'linus' into locking-for-linus
Conflicts:
lib/Kconfig.debug
Diffstat (limited to 'arch/powerpc/kernel/process.c')
-rw-r--r-- | arch/powerpc/kernel/process.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index fb7049c054c0..eac064948780 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -33,7 +33,10 @@ #include <linux/mqueue.h> #include <linux/hardirq.h> #include <linux/utsname.h> +#include <linux/ftrace.h> #include <linux/kernel_stat.h> +#include <linux/personality.h> +#include <linux/random.h> #include <asm/pgtable.h> #include <asm/uaccess.h> @@ -1008,6 +1011,14 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) unsigned long sp, ip, lr, newsp; int count = 0; int firstframe = 1; +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + int curr_frame = current->curr_ret_stack; + extern void return_to_handler(void); + unsigned long addr = (unsigned long)return_to_handler; +#ifdef CONFIG_PPC64 + addr = *(unsigned long*)addr; +#endif +#endif sp = (unsigned long) stack; if (tsk == NULL) @@ -1030,6 +1041,13 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) ip = stack[STACK_FRAME_LR_SAVE]; if (!firstframe || ip != lr) { printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip); +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + if (ip == addr && curr_frame >= 0) { + printk(" (%pS)", + (void *)current->ret_stack[curr_frame].ret); + curr_frame--; + } +#endif if (firstframe) printk(" (unreliable)"); printk("\n"); @@ -1122,3 +1140,43 @@ void thread_info_cache_init(void) } #endif /* THREAD_SHIFT < PAGE_SHIFT */ + +unsigned long arch_align_stack(unsigned long sp) +{ + if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) + sp -= get_random_int() & ~PAGE_MASK; + return sp & ~0xf; +} + +static inline unsigned long brk_rnd(void) +{ + unsigned long rnd = 0; + + /* 8MB for 32bit, 1GB for 64bit */ + if (is_32bit_task()) + rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT))); + else + rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT))); + + return rnd << PAGE_SHIFT; +} + +unsigned long arch_randomize_brk(struct mm_struct *mm) +{ + unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd()); + + if (ret < mm->brk) + return mm->brk; + + return ret; +} + +unsigned long randomize_et_dyn(unsigned long base) +{ + unsigned long ret = PAGE_ALIGN(base + brk_rnd()); + + if (ret < base) + return base; + + return ret; +} |