diff options
Diffstat (limited to 'arch/s390/kernel/process.c')
-rw-r--r-- | arch/s390/kernel/process.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 70c57378f426..96492cf2d491 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <asm/processor.h> | 44 | #include <asm/processor.h> |
45 | #include <asm/irq.h> | 45 | #include <asm/irq.h> |
46 | #include <asm/timer.h> | 46 | #include <asm/timer.h> |
47 | #include <asm/cpu.h> | ||
47 | 48 | ||
48 | asmlinkage void ret_from_fork(void) asm ("ret_from_fork"); | 49 | asmlinkage void ret_from_fork(void) asm ("ret_from_fork"); |
49 | 50 | ||
@@ -91,6 +92,14 @@ EXPORT_SYMBOL(unregister_idle_notifier); | |||
91 | 92 | ||
92 | void do_monitor_call(struct pt_regs *regs, long interruption_code) | 93 | void do_monitor_call(struct pt_regs *regs, long interruption_code) |
93 | { | 94 | { |
95 | struct s390_idle_data *idle; | ||
96 | |||
97 | idle = &__get_cpu_var(s390_idle); | ||
98 | spin_lock(&idle->lock); | ||
99 | idle->idle_time += get_clock() - idle->idle_enter; | ||
100 | idle->in_idle = 0; | ||
101 | spin_unlock(&idle->lock); | ||
102 | |||
94 | /* disable monitor call class 0 */ | 103 | /* disable monitor call class 0 */ |
95 | __ctl_clear_bit(8, 15); | 104 | __ctl_clear_bit(8, 15); |
96 | 105 | ||
@@ -105,6 +114,7 @@ extern void s390_handle_mcck(void); | |||
105 | static void default_idle(void) | 114 | static void default_idle(void) |
106 | { | 115 | { |
107 | int cpu, rc; | 116 | int cpu, rc; |
117 | struct s390_idle_data *idle; | ||
108 | 118 | ||
109 | /* CPU is going idle. */ | 119 | /* CPU is going idle. */ |
110 | cpu = smp_processor_id(); | 120 | cpu = smp_processor_id(); |
@@ -142,6 +152,12 @@ static void default_idle(void) | |||
142 | return; | 152 | return; |
143 | } | 153 | } |
144 | 154 | ||
155 | idle = &__get_cpu_var(s390_idle); | ||
156 | spin_lock(&idle->lock); | ||
157 | idle->idle_count++; | ||
158 | idle->in_idle = 1; | ||
159 | idle->idle_enter = get_clock(); | ||
160 | spin_unlock(&idle->lock); | ||
145 | trace_hardirqs_on(); | 161 | trace_hardirqs_on(); |
146 | /* Wait for external, I/O or machine check interrupt. */ | 162 | /* Wait for external, I/O or machine check interrupt. */ |
147 | __load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT | | 163 | __load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT | |
@@ -254,14 +270,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp, | |||
254 | save_fp_regs(¤t->thread.fp_regs); | 270 | save_fp_regs(¤t->thread.fp_regs); |
255 | memcpy(&p->thread.fp_regs, ¤t->thread.fp_regs, | 271 | memcpy(&p->thread.fp_regs, ¤t->thread.fp_regs, |
256 | sizeof(s390_fp_regs)); | 272 | sizeof(s390_fp_regs)); |
257 | p->thread.user_seg = __pa((unsigned long) p->mm->pgd) | _SEGMENT_TABLE; | ||
258 | /* Set a new TLS ? */ | 273 | /* Set a new TLS ? */ |
259 | if (clone_flags & CLONE_SETTLS) | 274 | if (clone_flags & CLONE_SETTLS) |
260 | p->thread.acrs[0] = regs->gprs[6]; | 275 | p->thread.acrs[0] = regs->gprs[6]; |
261 | #else /* CONFIG_64BIT */ | 276 | #else /* CONFIG_64BIT */ |
262 | /* Save the fpu registers to new thread structure. */ | 277 | /* Save the fpu registers to new thread structure. */ |
263 | save_fp_regs(&p->thread.fp_regs); | 278 | save_fp_regs(&p->thread.fp_regs); |
264 | p->thread.user_seg = __pa((unsigned long) p->mm->pgd) | _REGION_TABLE; | ||
265 | /* Set a new TLS ? */ | 279 | /* Set a new TLS ? */ |
266 | if (clone_flags & CLONE_SETTLS) { | 280 | if (clone_flags & CLONE_SETTLS) { |
267 | if (test_thread_flag(TIF_31BIT)) { | 281 | if (test_thread_flag(TIF_31BIT)) { |