aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/process.c')
-rw-r--r--arch/s390/kernel/process.c80
1 files changed, 52 insertions, 28 deletions
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index d3a2d1c6438e..541a7509faeb 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -9,38 +9,27 @@
9 9
10#include <linux/compiler.h> 10#include <linux/compiler.h>
11#include <linux/cpu.h> 11#include <linux/cpu.h>
12#include <linux/errno.h>
13#include <linux/sched.h> 12#include <linux/sched.h>
14#include <linux/kernel.h> 13#include <linux/kernel.h>
15#include <linux/mm.h> 14#include <linux/mm.h>
16#include <linux/fs.h>
17#include <linux/smp.h> 15#include <linux/smp.h>
18#include <linux/stddef.h>
19#include <linux/slab.h> 16#include <linux/slab.h>
20#include <linux/unistd.h>
21#include <linux/ptrace.h>
22#include <linux/vmalloc.h>
23#include <linux/user.h>
24#include <linux/interrupt.h> 17#include <linux/interrupt.h>
25#include <linux/delay.h>
26#include <linux/reboot.h>
27#include <linux/init.h>
28#include <linux/module.h>
29#include <linux/notifier.h>
30#include <linux/tick.h> 18#include <linux/tick.h>
31#include <linux/elfcore.h> 19#include <linux/personality.h>
32#include <linux/kernel_stat.h>
33#include <linux/syscalls.h> 20#include <linux/syscalls.h>
34#include <linux/compat.h> 21#include <linux/compat.h>
35#include <asm/compat.h> 22#include <linux/kprobes.h>
36#include <asm/uaccess.h> 23#include <linux/random.h>
37#include <asm/pgtable.h> 24#include <linux/module.h>
38#include <asm/system.h> 25#include <asm/system.h>
39#include <asm/io.h> 26#include <asm/io.h>
40#include <asm/processor.h> 27#include <asm/processor.h>
41#include <asm/irq.h> 28#include <asm/irq.h>
42#include <asm/timer.h> 29#include <asm/timer.h>
43#include <asm/nmi.h> 30#include <asm/nmi.h>
31#include <asm/compat.h>
32#include <asm/smp.h>
44#include "entry.h" 33#include "entry.h"
45 34
46asmlinkage void ret_from_fork(void) asm ("ret_from_fork"); 35asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
@@ -75,18 +64,13 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
75 */ 64 */
76static void default_idle(void) 65static void default_idle(void)
77{ 66{
78 /* CPU is going idle. */ 67 if (cpu_is_offline(smp_processor_id()))
68 cpu_die();
79 local_irq_disable(); 69 local_irq_disable();
80 if (need_resched()) { 70 if (need_resched()) {
81 local_irq_enable(); 71 local_irq_enable();
82 return; 72 return;
83 } 73 }
84#ifdef CONFIG_HOTPLUG_CPU
85 if (cpu_is_offline(smp_processor_id())) {
86 preempt_enable_no_resched();
87 cpu_die();
88 }
89#endif
90 local_mcck_disable(); 74 local_mcck_disable();
91 if (test_thread_flag(TIF_MCCK_PENDING)) { 75 if (test_thread_flag(TIF_MCCK_PENDING)) {
92 local_mcck_enable(); 76 local_mcck_enable();
@@ -116,15 +100,17 @@ void cpu_idle(void)
116 } 100 }
117} 101}
118 102
119extern void kernel_thread_starter(void); 103extern void __kprobes kernel_thread_starter(void);
120 104
121asm( 105asm(
122 ".align 4\n" 106 ".section .kprobes.text, \"ax\"\n"
107 ".global kernel_thread_starter\n"
123 "kernel_thread_starter:\n" 108 "kernel_thread_starter:\n"
124 " la 2,0(10)\n" 109 " la 2,0(10)\n"
125 " basr 14,9\n" 110 " basr 14,9\n"
126 " la 2,0\n" 111 " la 2,0\n"
127 " br 11\n"); 112 " br 11\n"
113 ".previous\n");
128 114
129int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) 115int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
130{ 116{
@@ -214,8 +200,10 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
214 /* start new process with ar4 pointing to the correct address space */ 200 /* start new process with ar4 pointing to the correct address space */
215 p->thread.mm_segment = get_fs(); 201 p->thread.mm_segment = get_fs();
216 /* Don't copy debug registers */ 202 /* Don't copy debug registers */
217 memset(&p->thread.per_info, 0, sizeof(p->thread.per_info)); 203 memset(&p->thread.per_user, 0, sizeof(p->thread.per_user));
204 memset(&p->thread.per_event, 0, sizeof(p->thread.per_event));
218 clear_tsk_thread_flag(p, TIF_SINGLE_STEP); 205 clear_tsk_thread_flag(p, TIF_SINGLE_STEP);
206 clear_tsk_thread_flag(p, TIF_PER_TRAP);
219 /* Initialize per thread user and system timer values */ 207 /* Initialize per thread user and system timer values */
220 ti = task_thread_info(p); 208 ti = task_thread_info(p);
221 ti->user_timer = 0; 209 ti->user_timer = 0;
@@ -331,3 +319,39 @@ unsigned long get_wchan(struct task_struct *p)
331 } 319 }
332 return 0; 320 return 0;
333} 321}
322
323unsigned long arch_align_stack(unsigned long sp)
324{
325 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
326 sp -= get_random_int() & ~PAGE_MASK;
327 return sp & ~0xf;
328}
329
330static inline unsigned long brk_rnd(void)
331{
332 /* 8MB for 32bit, 1GB for 64bit */
333 if (is_32bit_task())
334 return (get_random_int() & 0x7ffUL) << PAGE_SHIFT;
335 else
336 return (get_random_int() & 0x3ffffUL) << PAGE_SHIFT;
337}
338
339unsigned long arch_randomize_brk(struct mm_struct *mm)
340{
341 unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd());
342
343 if (ret < mm->brk)
344 return mm->brk;
345 return ret;
346}
347
348unsigned long randomize_et_dyn(unsigned long base)
349{
350 unsigned long ret = PAGE_ALIGN(base + brk_rnd());
351
352 if (!(current->flags & PF_RANDOMIZE))
353 return base;
354 if (ret < base)
355 return base;
356 return ret;
357}