aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/process.c')
-rw-r--r--arch/powerpc/kernel/process.c58
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 @@
33#include <linux/mqueue.h> 33#include <linux/mqueue.h>
34#include <linux/hardirq.h> 34#include <linux/hardirq.h>
35#include <linux/utsname.h> 35#include <linux/utsname.h>
36#include <linux/ftrace.h>
36#include <linux/kernel_stat.h> 37#include <linux/kernel_stat.h>
38#include <linux/personality.h>
39#include <linux/random.h>
37 40
38#include <asm/pgtable.h> 41#include <asm/pgtable.h>
39#include <asm/uaccess.h> 42#include <asm/uaccess.h>
@@ -1008,6 +1011,14 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
1008 unsigned long sp, ip, lr, newsp; 1011 unsigned long sp, ip, lr, newsp;
1009 int count = 0; 1012 int count = 0;
1010 int firstframe = 1; 1013 int firstframe = 1;
1014#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1015 int curr_frame = current->curr_ret_stack;
1016 extern void return_to_handler(void);
1017 unsigned long addr = (unsigned long)return_to_handler;
1018#ifdef CONFIG_PPC64
1019 addr = *(unsigned long*)addr;
1020#endif
1021#endif
1011 1022
1012 sp = (unsigned long) stack; 1023 sp = (unsigned long) stack;
1013 if (tsk == NULL) 1024 if (tsk == NULL)
@@ -1030,6 +1041,13 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
1030 ip = stack[STACK_FRAME_LR_SAVE]; 1041 ip = stack[STACK_FRAME_LR_SAVE];
1031 if (!firstframe || ip != lr) { 1042 if (!firstframe || ip != lr) {
1032 printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip); 1043 printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip);
1044#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1045 if (ip == addr && curr_frame >= 0) {
1046 printk(" (%pS)",
1047 (void *)current->ret_stack[curr_frame].ret);
1048 curr_frame--;
1049 }
1050#endif
1033 if (firstframe) 1051 if (firstframe)
1034 printk(" (unreliable)"); 1052 printk(" (unreliable)");
1035 printk("\n"); 1053 printk("\n");
@@ -1122,3 +1140,43 @@ void thread_info_cache_init(void)
1122} 1140}
1123 1141
1124#endif /* THREAD_SHIFT < PAGE_SHIFT */ 1142#endif /* THREAD_SHIFT < PAGE_SHIFT */
1143
1144unsigned long arch_align_stack(unsigned long sp)
1145{
1146 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
1147 sp -= get_random_int() & ~PAGE_MASK;
1148 return sp & ~0xf;
1149}
1150
1151static inline unsigned long brk_rnd(void)
1152{
1153 unsigned long rnd = 0;
1154
1155 /* 8MB for 32bit, 1GB for 64bit */
1156 if (is_32bit_task())
1157 rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT)));
1158 else
1159 rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT)));
1160
1161 return rnd << PAGE_SHIFT;
1162}
1163
1164unsigned long arch_randomize_brk(struct mm_struct *mm)
1165{
1166 unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd());
1167
1168 if (ret < mm->brk)
1169 return mm->brk;
1170
1171 return ret;
1172}
1173
1174unsigned long randomize_et_dyn(unsigned long base)
1175{
1176 unsigned long ret = PAGE_ALIGN(base + brk_rnd());
1177
1178 if (ret < base)
1179 return base;
1180
1181 return ret;
1182}