diff options
Diffstat (limited to 'arch/s390/kernel')
| -rw-r--r-- | arch/s390/kernel/process.c | 14 | ||||
| -rw-r--r-- | arch/s390/kernel/setup.c | 11 | ||||
| -rw-r--r-- | arch/s390/kernel/time.c | 2 | ||||
| -rw-r--r-- | arch/s390/kernel/vtime.c | 27 |
4 files changed, 46 insertions, 8 deletions
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 2ff90a1a105..008c74526fd 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -58,10 +58,18 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); */ unsigned long thread_saved_pc(struct task_struct *tsk) { - struct stack_frame *sf; + struct stack_frame *sf, *low, *high; - sf = (struct stack_frame *) tsk->thread.ksp; - sf = (struct stack_frame *) sf->back_chain; + if (!tsk || !task_stack_page(tsk)) + return 0; + low = task_stack_page(tsk); + high = (struct stack_frame *) task_pt_regs(tsk); + sf = (struct stack_frame *) (tsk->thread.ksp & PSW_ADDR_INSN); + if (sf <= low || sf > high) + return 0; + sf = (struct stack_frame *) (sf->back_chain & PSW_ADDR_INSN); + if (sf <= low || sf > high) + return 0; return sf->gprs[8]; } diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index b03847d100d..de878426747 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -268,7 +268,7 @@ static void do_machine_restart_nonsmp(char * __unused) reipl_diag(); if (MACHINE_IS_VM) - cpcmd ("IPL", NULL, 0); + cpcmd ("IPL", NULL, 0, NULL); else reipl (0x10000 | S390_lowcore.ipl_device); } @@ -276,14 +276,14 @@ static void do_machine_restart_nonsmp(char * __unused) static void do_machine_halt_nonsmp(void) { if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) - cpcmd(vmhalt_cmd, NULL, 0); + cpcmd(vmhalt_cmd, NULL, 0, NULL); signal_processor(smp_processor_id(), sigp_stop_and_store_status); } static void do_machine_power_off_nonsmp(void) { if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0) - cpcmd(vmpoff_cmd, NULL, 0); + cpcmd(vmpoff_cmd, NULL, 0, NULL); signal_processor(smp_processor_id(), sigp_stop_and_store_status); } @@ -315,6 +315,11 @@ void machine_power_off(void) _machine_power_off(); } +/* + * Dummy power off function. + */ +void (*pm_power_off)(void) = machine_power_off; + static void __init add_memory_hole(unsigned long start, unsigned long end) { diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index b0d8ca8e5ee..7c0fe152a11 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -214,7 +214,7 @@ void account_ticks(struct pt_regs *regs) #endif #ifdef CONFIG_VIRT_CPU_ACCOUNTING - account_user_vtime(current); + account_tick_vtime(current); #else while (ticks--) update_process_times(user_mode(regs)); diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 22a895ecb7a..dfe6f085661 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -32,7 +32,7 @@ DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer); * Update process times based on virtual cpu times stored by entry.S * to the lowcore fields user_timer, system_timer & steal_clock. */ -void account_user_vtime(struct task_struct *tsk) +void account_tick_vtime(struct task_struct *tsk) { cputime_t cputime; __u64 timer, clock; @@ -76,6 +76,31 @@ void account_user_vtime(struct task_struct *tsk) * Update process times based on virtual cpu times stored by entry.S * to the lowcore fields user_timer, system_timer & steal_clock. */ +void account_vtime(struct task_struct *tsk) +{ + cputime_t cputime; + __u64 timer; + + timer = S390_lowcore.last_update_timer; + asm volatile (" STPT %0" /* Store current cpu timer value */ + : "=m" (S390_lowcore.last_update_timer) ); + S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer; + + cputime = S390_lowcore.user_timer >> 12; + S390_lowcore.user_timer -= cputime << 12; + S390_lowcore.steal_clock -= cputime << 12; + account_user_time(tsk, cputime); + + cputime = S390_lowcore.system_timer >> 12; + S390_lowcore.system_timer -= cputime << 12; + S390_lowcore.steal_clock -= cputime << 12; + account_system_time(tsk, 0, cputime); +} + +/* + * Update process times based on virtual cpu times stored by entry.S + * to the lowcore fields user_timer, system_timer & steal_clock. + */ void account_system_vtime(struct task_struct *tsk) { cputime_t cputime; |
