diff options
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r-- | arch/s390/kernel/Makefile | 3 | ||||
-rw-r--r-- | arch/s390/kernel/binfmt_elf32.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/compat_ioctl.c | 81 | ||||
-rw-r--r-- | arch/s390/kernel/compat_linux.c | 33 | ||||
-rw-r--r-- | arch/s390/kernel/compat_wrapper.S | 2 | ||||
-rw-r--r-- | arch/s390/kernel/crash.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/process.c | 47 | ||||
-rw-r--r-- | arch/s390/kernel/ptrace.c | 55 | ||||
-rw-r--r-- | arch/s390/kernel/s390_ksyms.c | 1 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 11 | ||||
-rw-r--r-- | arch/s390/kernel/smp.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/time.c | 4 | ||||
-rw-r--r-- | arch/s390/kernel/traps.c | 6 | ||||
-rw-r--r-- | arch/s390/kernel/vtime.c | 27 |
14 files changed, 79 insertions, 197 deletions
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 4865e4b49464..9269b5788fac 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -17,8 +17,7 @@ obj-$(CONFIG_MODULES) += s390_ksyms.o module.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \ - compat_ioctl.o compat_wrapper.o \ - compat_exec_domain.o + compat_wrapper.o compat_exec_domain.o obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o obj-$(CONFIG_VIRT_TIMER) += vtime.o diff --git a/arch/s390/kernel/binfmt_elf32.c b/arch/s390/kernel/binfmt_elf32.c index 03ba5893f17b..1f451c2cb071 100644 --- a/arch/s390/kernel/binfmt_elf32.c +++ b/arch/s390/kernel/binfmt_elf32.c @@ -112,7 +112,7 @@ static inline int dump_regs32(struct pt_regs *ptregs, elf_gregset_t *regs) static inline int dump_task_regs32(struct task_struct *tsk, elf_gregset_t *regs) { - struct pt_regs *ptregs = __KSTK_PTREGS(tsk); + struct pt_regs *ptregs = task_pt_regs(tsk); int i; memcpy(®s->psw.mask, &ptregs->psw.mask, 4); diff --git a/arch/s390/kernel/compat_ioctl.c b/arch/s390/kernel/compat_ioctl.c deleted file mode 100644 index 6504c4e69986..000000000000 --- a/arch/s390/kernel/compat_ioctl.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * ioctl32.c: Conversion between 32bit and 64bit native ioctls. - * - * S390 version - * Copyright (C) 2000-2003 IBM Deutschland Entwicklung GmbH, IBM Corporation - * Author(s): Gerhard Tonn (ton@de.ibm.com) - * Arnd Bergmann (arndb@de.ibm.com) - * - * Original implementation from 32-bit Sparc compat code which is - * Copyright (C) 2000 Silicon Graphics, Inc. - * Written by Ulf Carlsson (ulfc@engr.sgi.com) - */ - -#include "compat_linux.h" -#define INCLUDES -#define CODE -#include "../../../fs/compat_ioctl.c" -#include <asm/dasd.h> -#include <asm/cmb.h> -#include <asm/tape390.h> -#include <asm/ccwdev.h> -#include "../../../drivers/s390/char/raw3270.h" - -static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, - unsigned long arg, struct file *f) -{ - return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg)); -} - -static int do_ioctl32_ulong(unsigned int fd, unsigned int cmd, - unsigned long arg, struct file *f) -{ - return sys_ioctl(fd, cmd, arg); -} - -#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)do_ioctl32_pointer) -#define ULONG_IOCTL(cmd) HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)do_ioctl32_ulong) -#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler), NULL }, - -struct ioctl_trans ioctl_start[] = { -/* architecture independent ioctls */ -#include <linux/compat_ioctl.h> -#define DECLARES -#include "../../../fs/compat_ioctl.c" - -/* s390 only ioctls */ -COMPATIBLE_IOCTL(DASDAPIVER) -COMPATIBLE_IOCTL(BIODASDDISABLE) -COMPATIBLE_IOCTL(BIODASDENABLE) -COMPATIBLE_IOCTL(BIODASDRSRV) -COMPATIBLE_IOCTL(BIODASDRLSE) -COMPATIBLE_IOCTL(BIODASDSLCK) -COMPATIBLE_IOCTL(BIODASDINFO) -COMPATIBLE_IOCTL(BIODASDINFO2) -COMPATIBLE_IOCTL(BIODASDFMT) -COMPATIBLE_IOCTL(BIODASDPRRST) -COMPATIBLE_IOCTL(BIODASDQUIESCE) -COMPATIBLE_IOCTL(BIODASDRESUME) -COMPATIBLE_IOCTL(BIODASDPRRD) -COMPATIBLE_IOCTL(BIODASDPSRD) -COMPATIBLE_IOCTL(BIODASDGATTR) -COMPATIBLE_IOCTL(BIODASDSATTR) -COMPATIBLE_IOCTL(BIODASDCMFENABLE) -COMPATIBLE_IOCTL(BIODASDCMFDISABLE) -COMPATIBLE_IOCTL(BIODASDREADALLCMB) - -COMPATIBLE_IOCTL(TUBICMD) -COMPATIBLE_IOCTL(TUBOCMD) -COMPATIBLE_IOCTL(TUBGETI) -COMPATIBLE_IOCTL(TUBGETO) -COMPATIBLE_IOCTL(TUBSETMOD) -COMPATIBLE_IOCTL(TUBGETMOD) - -COMPATIBLE_IOCTL(TAPE390_DISPLAY) - -/* s390 doesn't need handlers here */ -COMPATIBLE_IOCTL(TIOCGSERIAL) -COMPATIBLE_IOCTL(TIOCSSERIAL) -}; - -int ioctl_table_size = ARRAY_SIZE(ioctl_start); diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 41b197a3f3a3..bf9a7a361b34 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -55,6 +55,7 @@ #include <linux/syscalls.h> #include <linux/sysctl.h> #include <linux/binfmts.h> +#include <linux/capability.h> #include <linux/compat.h> #include <linux/vfs.h> #include <linux/ptrace.h> @@ -1014,38 +1015,6 @@ asmlinkage long sys32_clone(struct pt_regs regs) } /* - * Wrapper function for sys_timer_create. - */ -extern asmlinkage long -sys_timer_create(clockid_t, struct sigevent *, timer_t *); - -asmlinkage long -sys32_timer_create(clockid_t which_clock, struct compat_sigevent *se32, - timer_t *timer_id) -{ - struct sigevent se; - timer_t ktimer_id; - mm_segment_t old_fs; - long ret; - - if (se32 == NULL) - return sys_timer_create(which_clock, NULL, timer_id); - - if (get_compat_sigevent(&se, se32)) - return -EFAULT; - - old_fs = get_fs(); - set_fs(KERNEL_DS); - ret = sys_timer_create(which_clock, &se, &ktimer_id); - set_fs(old_fs); - - if (!ret) - ret = put_user (ktimer_id, timer_id); - - return ret; -} - -/* * 31 bit emulation wrapper functions for sys_fadvise64/fadvise64_64. * These need to rewrite the advise values for POSIX_FADV_{DONTNEED,NOREUSE} * because the 31 bit values differ from the 64 bit values. diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 23fe94e58688..cfde1905d07d 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -1289,7 +1289,7 @@ sys32_timer_create_wrapper: lgfr %r2,%r2 # timer_t (int) llgtr %r3,%r3 # struct compat_sigevent * llgtr %r4,%r4 # timer_t * - jg sys32_timer_create + jg compat_sys_timer_create .globl sys32_timer_settime_wrapper sys32_timer_settime_wrapper: diff --git a/arch/s390/kernel/crash.c b/arch/s390/kernel/crash.c index 7bd169c58b0c..926cceeae0fa 100644 --- a/arch/s390/kernel/crash.c +++ b/arch/s390/kernel/crash.c @@ -10,8 +10,6 @@ #include <linux/threads.h> #include <linux/kexec.h> -note_buf_t crash_notes[NR_CPUS]; - void machine_crash_shutdown(struct pt_regs *regs) { } diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index a942bf2d58e9..008c74526fd3 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]; } @@ -153,7 +161,7 @@ void show_regs(struct pt_regs *regs) { struct task_struct *tsk = current; - printk("CPU: %d %s\n", tsk->thread_info->cpu, print_tainted()); + printk("CPU: %d %s\n", task_thread_info(tsk)->cpu, print_tainted()); printk("Process %s (pid: %d, task: %p, ksp: %p)\n", current->comm, current->pid, (void *) tsk, (void *) tsk->thread.ksp); @@ -217,8 +225,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp, struct pt_regs childregs; } *frame; - frame = ((struct fake_frame *) - (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; + frame = container_of(task_pt_regs(p), struct fake_frame, childregs); p->thread.ksp = (unsigned long) frame; /* Store access registers to kernel stack of new process. */ frame->childregs = *regs; @@ -352,38 +359,16 @@ int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs) return 1; } -/* - * fill in the user structure for a core dump.. - */ -void dump_thread(struct pt_regs * regs, struct user * dump) -{ - -/* changed the size calculations - should hopefully work better. lbt */ - dump->magic = CMAGIC; - dump->start_code = 0; - dump->start_stack = regs->gprs[15] & ~(PAGE_SIZE - 1); - dump->u_tsize = current->mm->end_code >> PAGE_SHIFT; - dump->u_dsize = (current->mm->brk + PAGE_SIZE - 1) >> PAGE_SHIFT; - dump->u_dsize -= dump->u_tsize; - dump->u_ssize = 0; - if (dump->start_stack < TASK_SIZE) - dump->u_ssize = (TASK_SIZE - dump->start_stack) >> PAGE_SHIFT; - memcpy(&dump->regs, regs, sizeof(s390_regs)); - dump_fpu (regs, &dump->regs.fp_regs); - dump->regs.per_info = current->thread.per_info; -} - unsigned long get_wchan(struct task_struct *p) { struct stack_frame *sf, *low, *high; unsigned long return_address; int count; - if (!p || p == current || p->state == TASK_RUNNING || !p->thread_info) + if (!p || p == current || p->state == TASK_RUNNING || !task_stack_page(p)) return 0; - low = (struct stack_frame *) p->thread_info; - high = (struct stack_frame *) - ((unsigned long) p->thread_info + THREAD_SIZE) - 1; + low = task_stack_page(p); + high = (struct stack_frame *) task_pt_regs(p); sf = (struct stack_frame *) (p->thread.ksp & PSW_ADDR_INSN); if (sf <= low || sf > high) return 0; diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 8ecda6d66de4..37dfe33dab73 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -52,7 +52,7 @@ FixPerRegisters(struct task_struct *task) struct pt_regs *regs; per_struct *per_info; - regs = __KSTK_PTREGS(task); + regs = task_pt_regs(task); per_info = (per_struct *) &task->thread.per_info; per_info->control_regs.bits.em_instruction_fetch = per_info->single_step | per_info->instruction_fetch; @@ -150,7 +150,7 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data) /* * psw and gprs are stored on the stack */ - tmp = *(addr_t *)((addr_t) &__KSTK_PTREGS(child)->psw + addr); + tmp = *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr); if (addr == (addr_t) &dummy->regs.psw.mask) /* Remove per bit from user psw. */ tmp &= ~PSW_MASK_PER; @@ -176,7 +176,7 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data) /* * orig_gpr2 is stored on the kernel stack */ - tmp = (addr_t) __KSTK_PTREGS(child)->orig_gpr2; + tmp = (addr_t) task_pt_regs(child)->orig_gpr2; } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) { /* @@ -243,7 +243,7 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) high order bit but older gdb's rely on it */ data |= PSW_ADDR_AMODE; #endif - *(addr_t *)((addr_t) &__KSTK_PTREGS(child)->psw + addr) = data; + *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data; } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) { /* @@ -267,7 +267,7 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) /* * orig_gpr2 is stored on the kernel stack */ - __KSTK_PTREGS(child)->orig_gpr2 = data; + task_pt_regs(child)->orig_gpr2 = data; } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) { /* @@ -393,15 +393,15 @@ peek_user_emu31(struct task_struct *child, addr_t addr, addr_t data) */ if (addr == (addr_t) &dummy32->regs.psw.mask) { /* Fake a 31 bit psw mask. */ - tmp = (__u32)(__KSTK_PTREGS(child)->psw.mask >> 32); + tmp = (__u32)(task_pt_regs(child)->psw.mask >> 32); tmp = PSW32_MASK_MERGE(PSW32_USER_BITS, tmp); } else if (addr == (addr_t) &dummy32->regs.psw.addr) { /* Fake a 31 bit psw address. */ - tmp = (__u32) __KSTK_PTREGS(child)->psw.addr | + tmp = (__u32) task_pt_regs(child)->psw.addr | PSW32_ADDR_AMODE31; } else { /* gpr 0-15 */ - tmp = *(__u32 *)((addr_t) &__KSTK_PTREGS(child)->psw + + tmp = *(__u32 *)((addr_t) &task_pt_regs(child)->psw + addr*2 + 4); } } else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) { @@ -415,7 +415,7 @@ peek_user_emu31(struct task_struct *child, addr_t addr, addr_t data) /* * orig_gpr2 is stored on the kernel stack */ - tmp = *(__u32*)((addr_t) &__KSTK_PTREGS(child)->orig_gpr2 + 4); + tmp = *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4); } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) { /* @@ -472,15 +472,15 @@ poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data) if (tmp != PSW32_MASK_MERGE(PSW32_USER_BITS, tmp)) /* Invalid psw mask. */ return -EINVAL; - __KSTK_PTREGS(child)->psw.mask = + task_pt_regs(child)->psw.mask = PSW_MASK_MERGE(PSW_USER32_BITS, (__u64) tmp << 32); } else if (addr == (addr_t) &dummy32->regs.psw.addr) { /* Build a 64 bit psw address from 31 bit address. */ - __KSTK_PTREGS(child)->psw.addr = + task_pt_regs(child)->psw.addr = (__u64) tmp & PSW32_ADDR_INSN; } else { /* gpr 0-15 */ - *(__u32*)((addr_t) &__KSTK_PTREGS(child)->psw + *(__u32*)((addr_t) &task_pt_regs(child)->psw + addr*2 + 4) = tmp; } } else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) { @@ -494,7 +494,7 @@ poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data) /* * orig_gpr2 is stored on the kernel stack */ - *(__u32*)((addr_t) &__KSTK_PTREGS(child)->orig_gpr2 + 4) = tmp; + *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4) = tmp; } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) { /* @@ -712,35 +712,18 @@ sys_ptrace(long request, long pid, long addr, long data) int ret; lock_kernel(); - if (request == PTRACE_TRACEME) { - /* are we already being traced? */ - ret = -EPERM; - if (current->ptrace & PT_PTRACED) - goto out; - ret = security_ptrace(current->parent, current); - if (ret) - goto out; - /* set the ptrace bit in the process flags. */ - current->ptrace |= PT_PTRACED; - goto out; + ret = ptrace_traceme(); + goto out; } - ret = -EPERM; - if (pid == 1) /* you may not mess with init */ - goto out; - - ret = -ESRCH; - read_lock(&tasklist_lock); - child = find_task_by_pid(pid); - if (child) - get_task_struct(child); - read_unlock(&tasklist_lock); - if (!child) + child = ptrace_get_task_struct(pid); + if (IS_ERR(child)) { + ret = PTR_ERR(child); goto out; + } ret = do_ptrace(child, request, addr, data); - put_task_struct(child); out: unlock_kernel(); diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c index bee654abb6d3..4176c77670c4 100644 --- a/arch/s390/kernel/s390_ksyms.c +++ b/arch/s390/kernel/s390_ksyms.c @@ -10,7 +10,6 @@ #include <linux/smp.h> #include <linux/syscalls.h> #include <linux/interrupt.h> -#include <linux/ioctl32.h> #include <asm/checksum.h> #include <asm/cpcmd.h> #include <asm/delay.h> diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index b03847d100d9..de8784267473 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/smp.c b/arch/s390/kernel/smp.c index e10f4ca00499..cbfcfd02a43a 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -657,7 +657,7 @@ __cpu_up(unsigned int cpu) idle = current_set[cpu]; cpu_lowcore = lowcore_ptr[cpu]; cpu_lowcore->kernel_stack = (unsigned long) - idle->thread_info + (THREAD_SIZE); + task_stack_page(idle) + (THREAD_SIZE); sf = (struct stack_frame *) (cpu_lowcore->kernel_stack - sizeof(struct pt_regs) - sizeof(struct stack_frame)); diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index c36353e8c140..7c0fe152a111 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)); @@ -282,7 +282,7 @@ static inline void start_hz_timer(void) { if (!cpu_isset(smp_processor_id(), nohz_cpu_mask)) return; - account_ticks(__KSTK_PTREGS(current)); + account_ticks(task_pt_regs(current)); cpu_clear(smp_processor_id(), nohz_cpu_mask); } diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 95d109968619..5d21e9e6e7b4 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -136,8 +136,8 @@ void show_trace(struct task_struct *task, unsigned long * stack) sp = __show_trace(sp, S390_lowcore.async_stack - ASYNC_SIZE, S390_lowcore.async_stack); if (task) - __show_trace(sp, (unsigned long) task->thread_info, - (unsigned long) task->thread_info + THREAD_SIZE); + __show_trace(sp, (unsigned long) task_stack_page(task), + (unsigned long) task_stack_page(task) + THREAD_SIZE); else __show_trace(sp, S390_lowcore.thread_info, S390_lowcore.thread_info + THREAD_SIZE); @@ -240,7 +240,7 @@ char *task_show_regs(struct task_struct *task, char *buffer) { struct pt_regs *regs; - regs = __KSTK_PTREGS(task); + regs = task_pt_regs(task); buffer += sprintf(buffer, "task: %p, ksp: %p\n", task, (void *)task->thread.ksp); buffer += sprintf(buffer, "User PSW : %p %p\n", diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 22a895ecb7a4..dfe6f0856617 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; |