diff options
Diffstat (limited to 'arch/powerpc/kernel/process.c')
-rw-r--r-- | arch/powerpc/kernel/process.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 0a3216433051..c930ac38e59f 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -1016,9 +1016,13 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) | |||
1016 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 1016 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
1017 | int curr_frame = current->curr_ret_stack; | 1017 | int curr_frame = current->curr_ret_stack; |
1018 | extern void return_to_handler(void); | 1018 | extern void return_to_handler(void); |
1019 | unsigned long addr = (unsigned long)return_to_handler; | 1019 | unsigned long rth = (unsigned long)return_to_handler; |
1020 | unsigned long mrth = -1; | ||
1020 | #ifdef CONFIG_PPC64 | 1021 | #ifdef CONFIG_PPC64 |
1021 | addr = *(unsigned long*)addr; | 1022 | extern void mod_return_to_handler(void); |
1023 | rth = *(unsigned long *)rth; | ||
1024 | mrth = (unsigned long)mod_return_to_handler; | ||
1025 | mrth = *(unsigned long *)mrth; | ||
1022 | #endif | 1026 | #endif |
1023 | #endif | 1027 | #endif |
1024 | 1028 | ||
@@ -1044,7 +1048,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) | |||
1044 | if (!firstframe || ip != lr) { | 1048 | if (!firstframe || ip != lr) { |
1045 | printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip); | 1049 | printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip); |
1046 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 1050 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
1047 | if (ip == addr && curr_frame >= 0) { | 1051 | if ((ip == rth || ip == mrth) && curr_frame >= 0) { |
1048 | printk(" (%pS)", | 1052 | printk(" (%pS)", |
1049 | (void *)current->ret_stack[curr_frame].ret); | 1053 | (void *)current->ret_stack[curr_frame].ret); |
1050 | curr_frame--; | 1054 | curr_frame--; |
@@ -1165,7 +1169,22 @@ static inline unsigned long brk_rnd(void) | |||
1165 | 1169 | ||
1166 | unsigned long arch_randomize_brk(struct mm_struct *mm) | 1170 | unsigned long arch_randomize_brk(struct mm_struct *mm) |
1167 | { | 1171 | { |
1168 | unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd()); | 1172 | unsigned long base = mm->brk; |
1173 | unsigned long ret; | ||
1174 | |||
1175 | #ifdef CONFIG_PPC_STD_MMU_64 | ||
1176 | /* | ||
1177 | * If we are using 1TB segments and we are allowed to randomise | ||
1178 | * the heap, we can put it above 1TB so it is backed by a 1TB | ||
1179 | * segment. Otherwise the heap will be in the bottom 1TB | ||
1180 | * which always uses 256MB segments and this may result in a | ||
1181 | * performance penalty. | ||
1182 | */ | ||
1183 | if (!is_32bit_task() && (mmu_highuser_ssize == MMU_SEGSIZE_1T)) | ||
1184 | base = max_t(unsigned long, mm->brk, 1UL << SID_SHIFT_1T); | ||
1185 | #endif | ||
1186 | |||
1187 | ret = PAGE_ALIGN(base + brk_rnd()); | ||
1169 | 1188 | ||
1170 | if (ret < mm->brk) | 1189 | if (ret < mm->brk) |
1171 | return mm->brk; | 1190 | return mm->brk; |