+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+/*
+ * Update process times based on virtual cpu times stored by entry.S
+ * to the lowcore fields user_timer, system_timer & steal_clock.
+ */
+void account_tick_vtime(struct task_struct *tsk)
+{
+ cputime_t cputime;
+ __u64 timer, clock;
+ int rcu_user_flag;
+
+ timer = S390_lowcore.last_update_timer;
+ clock = S390_lowcore.last_update_clock;
+ asm volatile (" STPT %0\n" /* Store current cpu timer value */
+ " STCK %1" /* Store current tod clock value */
+ : "=m" (S390_lowcore.last_update_timer),
+ "=m" (S390_lowcore.last_update_clock) );
+ S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer;
+ S390_lowcore.steal_clock += S390_lowcore.last_update_clock - clock;
+
+ cputime = S390_lowcore.user_timer >> 12;
+ rcu_user_flag = cputime != 0;
+ 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, HARDIRQ_OFFSET, cputime);
+
+ cputime = S390_lowcore.steal_clock;
+ if ((__s64) cputime > 0) {
+ cputime >>= 12;
+ S390_lowcore.steal_clock -= cputime << 12;
+ account_steal_time(tsk, cputime);
+ }
+
+ run_local_timers();
+ if (rcu_pending(smp_processor_id()))
+ rcu_check_callbacks(smp_processor_id(), rcu_user_flag);
+ scheduler_tick();
+ run_posix_cpu_timers(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;
+ __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.system_timer >> 12;
+ S390_lowcore.system_timer -= cputime << 12;
+ S390_lowcore.steal_clock -= cputime << 12;
+ account_system_time(tsk, 0, cputime);
+}
+
+static inline void set_vtimer(__u64 expires)
+{
+ __u64 timer;
+
+ asm volatile (" STPT %0\n" /* Store current cpu timer value */
+ " SPT %1" /* Set new value immediatly afterwards */
+ : "=m" (timer) : "m" (expires) );
+ S390_lowcore.system_timer += S390_lowcore.last_update_timer - timer;
+ S390_lowcore.last_update_timer = expires;
+
+ /* store expire time for this CPU timer */
+ per_cpu(virt_cpu_timer, smp_processor_id()).to_expire = expires;
+}
+#else
+static inline void set_vtimer(__u64 expires)
+{
+ S390_lowcore.last_update_timer = expires;
+ asm volatile ("SPT %0" : : "m" (S390_lowcore.last_update_timer));
+
+ /* store expire time for this CPU timer */
+ per_cpu(virt_cpu_timer, smp_processor_id()).to_expire = expires;
+}
+#endif
+
+static void start_cpu_timer(void)