patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / arch / s390 / kernel / time.c
1 /*
2  *  arch/s390/kernel/time.c
3  *
4  *  S390 version
5  *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
6  *    Author(s): Hartmut Penner (hp@de.ibm.com),
7  *               Martin Schwidefsky (schwidefsky@de.ibm.com),
8  *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
9  *
10  *  Derived from "arch/i386/kernel/time.c"
11  *    Copyright (C) 1991, 1992, 1995  Linus Torvalds
12  */
13
14 #include <linux/errno.h>
15 #include <linux/module.h>
16 #include <linux/sched.h>
17 #include <linux/kernel.h>
18 #include <linux/param.h>
19 #include <linux/string.h>
20 #include <linux/mm.h>
21 #include <linux/interrupt.h>
22 #include <linux/time.h>
23 #include <linux/delay.h>
24 #include <linux/init.h>
25 #include <linux/smp.h>
26 #include <linux/types.h>
27 #include <linux/profile.h>
28 #include <linux/timex.h>
29 #include <linux/config.h>
30
31 #include <asm/uaccess.h>
32 #include <asm/delay.h>
33 #include <asm/s390_ext.h>
34 #include <asm/div64.h>
35 #include <asm/irq.h>
36 #ifdef CONFIG_VIRT_TIMER
37 #include <asm/timer.h>
38 #endif
39
40 /* change this if you have some constant time drift */
41 #define USECS_PER_JIFFY     ((unsigned long) 1000000/HZ)
42 #define CLK_TICKS_PER_JIFFY ((unsigned long) USECS_PER_JIFFY << 12)
43
44 /*
45  * Create a small time difference between the timer interrupts
46  * on the different cpus to avoid lock contention.
47  */
48 #define CPU_DEVIATION       (smp_processor_id() << 12)
49
50 #define TICK_SIZE tick
51
52 u64 jiffies_64 = INITIAL_JIFFIES;
53
54 EXPORT_SYMBOL(jiffies_64);
55
56 static ext_int_info_t ext_int_info_cc;
57 static u64 init_timer_cc;
58 static u64 jiffies_timer_cc;
59 static u64 xtime_cc;
60
61 extern unsigned long wall_jiffies;
62
63 #ifdef CONFIG_VIRT_TIMER
64 #define VTIMER_MAGIC (0x4b87ad6e + 1)
65 static ext_int_info_t ext_int_info_timer;
66 DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer);
67 #endif
68
69 /*
70  * Scheduler clock - returns current time in nanosec units.
71  */
72 unsigned long long sched_clock(void)
73 {
74         return ((get_clock() - jiffies_timer_cc) * 1000) >> 12;
75 }
76
77 void tod_to_timeval(__u64 todval, struct timespec *xtime)
78 {
79         unsigned long long sec;
80
81         sec = todval >> 12;
82         do_div(sec, 1000000);
83         xtime->tv_sec = sec;
84         todval -= (sec * 1000000) << 12;
85         xtime->tv_nsec = ((todval * 1000) >> 12);
86 }
87
88 static inline unsigned long do_gettimeoffset(void) 
89 {
90         __u64 now;
91
92         now = (get_clock() - jiffies_timer_cc) >> 12;
93         /* We require the offset from the latest update of xtime */
94         now -= (__u64) wall_jiffies*USECS_PER_JIFFY;
95         return (unsigned long) now;
96 }
97
98 /*
99  * This version of gettimeofday has microsecond resolution.
100  */
101 void do_gettimeofday(struct timeval *tv)
102 {
103         unsigned long flags;
104         unsigned long seq;
105         unsigned long usec, sec;
106
107         do {
108                 seq = read_seqbegin_irqsave(&xtime_lock, flags);
109
110                 sec = xtime.tv_sec;
111                 usec = xtime.tv_nsec / 1000 + do_gettimeoffset();
112         } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
113
114         while (usec >= 1000000) {
115                 usec -= 1000000;
116                 sec++;
117         }
118
119         tv->tv_sec = sec;
120         tv->tv_usec = usec;
121 }
122
123 EXPORT_SYMBOL(do_gettimeofday);
124
125 int do_settimeofday(struct timespec *tv)
126 {
127         time_t wtm_sec, sec = tv->tv_sec;
128         long wtm_nsec, nsec = tv->tv_nsec;
129
130         if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
131                 return -EINVAL;
132
133         write_seqlock_irq(&xtime_lock);
134         /* This is revolting. We need to set the xtime.tv_nsec
135          * correctly. However, the value in this location is
136          * is value at the last tick.
137          * Discover what correction gettimeofday
138          * would have done, and then undo it!
139          */
140         nsec -= do_gettimeoffset() * 1000;
141
142         wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
143         wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
144
145         set_normalized_timespec(&xtime, sec, nsec);
146         set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
147
148         time_adjust = 0;                /* stop active adjtime() */
149         time_status |= STA_UNSYNC;
150         time_maxerror = NTP_PHASE_LIMIT;
151         time_esterror = NTP_PHASE_LIMIT;
152         write_sequnlock_irq(&xtime_lock);
153         clock_was_set();
154         return 0;
155 }
156
157 EXPORT_SYMBOL(do_settimeofday);
158
159 #ifndef CONFIG_ARCH_S390X
160
161 static inline __u32
162 __calculate_ticks(__u64 elapsed)
163 {
164         register_pair rp;
165
166         rp.pair = elapsed >> 1;
167         asm ("dr %0,%1" : "+d" (rp) : "d" (CLK_TICKS_PER_JIFFY >> 1));
168         return rp.subreg.odd;
169 }
170
171 #else /* CONFIG_ARCH_S390X */
172
173 static inline __u32
174 __calculate_ticks(__u64 elapsed)
175 {
176         return elapsed / CLK_TICKS_PER_JIFFY;
177 }
178
179 #endif /* CONFIG_ARCH_S390X */
180
181
182 #ifdef CONFIG_PROFILING
183 extern char _stext, _etext;
184
185 /*
186  * The profiling function is SMP safe. (nothing can mess
187  * around with "current", and the profiling counters are
188  * updated with atomic operations). This is especially
189  * useful with a profiling multiplier != 1
190  */
191 static inline void s390_do_profile(struct pt_regs * regs)
192 {
193         unsigned long eip;
194         extern cpumask_t prof_cpu_mask;
195
196         profile_hook(regs);
197
198         if (user_mode(regs))
199                 return;
200
201         if (!prof_buffer)
202                 return;
203
204         eip = instruction_pointer(regs);
205
206         /*
207          * Only measure the CPUs specified by /proc/irq/prof_cpu_mask.
208          * (default is all CPUs.)
209          */
210         if (!cpu_isset(smp_processor_id(), prof_cpu_mask))
211                 return;
212
213         eip -= (unsigned long) &_stext;
214         eip >>= prof_shift;
215         /*
216          * Don't ignore out-of-bounds EIP values silently,
217          * put them into the last histogram slot, so if
218          * present, they will show up as a sharp peak.
219          */
220         if (eip > prof_len-1)
221                 eip = prof_len-1;
222         atomic_inc((atomic_t *)&prof_buffer[eip]);
223 }
224 #else
225 #define s390_do_profile(regs)  do { ; } while(0)
226 #endif /* CONFIG_PROFILING */
227
228
229 /*
230  * timer_interrupt() needs to keep up the real-time clock,
231  * as well as call the "do_timer()" routine every clocktick
232  */
233 void account_ticks(struct pt_regs *regs)
234 {
235         __u64 tmp;
236         __u32 ticks;
237
238         /* Calculate how many ticks have passed. */
239         tmp = S390_lowcore.int_clock - S390_lowcore.jiffy_timer;
240         if (tmp >= 2*CLK_TICKS_PER_JIFFY) {  /* more than two ticks ? */
241                 ticks = __calculate_ticks(tmp) + 1;
242                 S390_lowcore.jiffy_timer +=
243                         CLK_TICKS_PER_JIFFY * (__u64) ticks;
244         } else if (tmp >= CLK_TICKS_PER_JIFFY) {
245                 ticks = 2;
246                 S390_lowcore.jiffy_timer += 2*CLK_TICKS_PER_JIFFY;
247         } else {
248                 ticks = 1;
249                 S390_lowcore.jiffy_timer += CLK_TICKS_PER_JIFFY;
250         }
251
252         /* set clock comparator for next tick */
253         tmp = S390_lowcore.jiffy_timer + CPU_DEVIATION;
254         asm volatile ("SCKC %0" : : "m" (tmp));
255
256 #ifdef CONFIG_SMP
257         /*
258          * Do not rely on the boot cpu to do the calls to do_timer.
259          * Spread it over all cpus instead.
260          */
261         write_seqlock(&xtime_lock);
262         if (S390_lowcore.jiffy_timer > xtime_cc) {
263                 __u32 xticks;
264
265                 tmp = S390_lowcore.jiffy_timer - xtime_cc;
266                 if (tmp >= 2*CLK_TICKS_PER_JIFFY) {
267                         xticks = __calculate_ticks(tmp);
268                         xtime_cc += (__u64) xticks * CLK_TICKS_PER_JIFFY;
269                 } else {
270                         xticks = 1;
271                         xtime_cc += CLK_TICKS_PER_JIFFY;
272                 }
273                 while (xticks--)
274                         do_timer(regs);
275         }
276         write_sequnlock(&xtime_lock);
277         while (ticks--)
278                 update_process_times(user_mode(regs));
279 #else
280         while (ticks--)
281                 do_timer(regs);
282 #endif
283         s390_do_profile(regs);
284 }
285
286 #ifdef CONFIG_VIRT_TIMER
287 void start_cpu_timer(void)
288 {
289         struct vtimer_queue *vt_list;
290
291         vt_list = &per_cpu(virt_cpu_timer, smp_processor_id());
292         set_vtimer(vt_list->idle);
293 }
294
295 int stop_cpu_timer(void)
296 {
297         __u64 done;
298         struct vtimer_queue *vt_list;
299
300         vt_list = &per_cpu(virt_cpu_timer, smp_processor_id());
301
302         /* nothing to do */
303         if (list_empty(&vt_list->list)) {
304                 vt_list->idle = VTIMER_MAX_SLICE;
305                 goto fire;
306         }
307
308         /* store progress */
309         asm volatile ("STPT %0" : "=m" (done));
310
311         /*
312          * If done is negative we do not stop the CPU timer
313          * because we will get instantly an interrupt that
314          * will start the CPU timer again.
315          */
316         if (done & 1LL<<63)
317                 return 1;
318         else
319                 vt_list->offset += vt_list->to_expire - done;
320
321         /* save the actual expire value */
322         vt_list->idle = done;
323
324         /*
325          * We cannot halt the CPU timer, we just write a value that
326          * nearly never expires (only after 71 years) and re-write
327          * the stored expire value if we continue the timer
328          */
329  fire:
330         set_vtimer(VTIMER_MAX_SLICE);
331         return 0;
332 }
333
334 void set_vtimer(__u64 expires)
335 {
336         asm volatile ("SPT %0" : : "m" (expires));
337
338         /* store expire time for this CPU timer */
339         per_cpu(virt_cpu_timer, smp_processor_id()).to_expire = expires;
340 }
341
342 /*
343  * Sorted add to a list. List is linear searched until first bigger
344  * element is found.
345  */
346 void list_add_sorted(struct vtimer_list *timer, struct list_head *head)
347 {
348         struct vtimer_list *event;
349
350         list_for_each_entry(event, head, entry) {
351                 if (event->expires > timer->expires) {
352                         list_add_tail(&timer->entry, &event->entry);
353                         return;
354                 }
355         }
356         list_add_tail(&timer->entry, head);
357 }
358
359 /*
360  * Do the callback functions of expired vtimer events.
361  * Called from within the interrupt handler.
362  */
363 static void do_callbacks(struct list_head *cb_list, struct pt_regs *regs)
364 {
365         struct vtimer_queue *vt_list;
366         struct vtimer_list *event, *tmp;
367         void (*fn)(unsigned long, struct pt_regs*);
368         unsigned long data;
369
370         if (list_empty(cb_list))
371                 return;
372
373         vt_list = &per_cpu(virt_cpu_timer, smp_processor_id());
374
375         list_for_each_entry_safe(event, tmp, cb_list, entry) {
376                 fn = event->function;
377                 data = event->data;
378                 fn(data, regs);
379
380                 if (!event->interval)
381                         /* delete one shot timer */
382                         list_del_init(&event->entry);
383                 else {
384                         /* move interval timer back to list */
385                         spin_lock(&vt_list->lock);
386                         list_del_init(&event->entry);
387                         list_add_sorted(event, &vt_list->list);
388                         spin_unlock(&vt_list->lock);
389                 }
390         }
391 }
392
393 /*
394  * Handler for the virtual CPU timer.
395  */
396 static void do_cpu_timer_interrupt(struct pt_regs *regs, __u16 error_code)
397 {
398         int cpu;
399         __u64 next, delta;
400         struct vtimer_queue *vt_list;
401         struct vtimer_list *event, *tmp;
402         struct list_head *ptr;
403         /* the callback queue */
404         struct list_head cb_list;
405
406         INIT_LIST_HEAD(&cb_list);
407         cpu = smp_processor_id();
408         vt_list = &per_cpu(virt_cpu_timer, cpu);
409
410         /* walk timer list, fire all expired events */
411         spin_lock(&vt_list->lock);
412
413         if (vt_list->to_expire < VTIMER_MAX_SLICE)
414                 vt_list->offset += vt_list->to_expire;
415
416         list_for_each_entry_safe(event, tmp, &vt_list->list, entry) {
417                 if (event->expires > vt_list->offset)
418                         /* found first unexpired event, leave */
419                         break;
420
421                 /* re-charge interval timer, we have to add the offset */
422                 if (event->interval)
423                         event->expires = event->interval + vt_list->offset;
424
425                 /* move expired timer to the callback queue */
426                 list_move_tail(&event->entry, &cb_list);
427         }
428         spin_unlock(&vt_list->lock);
429         do_callbacks(&cb_list, regs);
430
431         /* next event is first in list */
432         spin_lock(&vt_list->lock);
433         if (!list_empty(&vt_list->list)) {
434                 ptr = vt_list->list.next;
435                 event = list_entry(ptr, struct vtimer_list, entry);
436                 next = event->expires - vt_list->offset;
437
438                 /* add the expired time from this interrupt handler
439                  * and the callback functions
440                  */
441                 asm volatile ("STPT %0" : "=m" (delta));
442                 delta = 0xffffffffffffffffLL - delta + 1;
443                 vt_list->offset += delta;
444                 next -= delta;
445         } else {
446                 vt_list->offset = 0;
447                 next = VTIMER_MAX_SLICE;
448         }
449         spin_unlock(&vt_list->lock);
450         set_vtimer(next);
451 }
452 #endif
453
454 #ifdef CONFIG_NO_IDLE_HZ
455
456 #ifdef CONFIG_NO_IDLE_HZ_INIT
457 int sysctl_hz_timer = 0;
458 #else
459 int sysctl_hz_timer = 1;
460 #endif
461
462 /*
463  * Start the HZ tick on the current CPU.
464  * Only cpu_idle may call this function.
465  */
466 void start_hz_timer(struct pt_regs *regs)
467 {
468         __u64 tmp;
469         __u32 ticks;
470
471         if (!cpu_isset(smp_processor_id(), nohz_cpu_mask))
472                 return;
473
474         /* Calculate how many ticks have passed */
475         asm volatile ("STCK 0(%0)" : : "a" (&tmp) : "memory", "cc");
476         tmp = tmp + CLK_TICKS_PER_JIFFY - S390_lowcore.jiffy_timer;
477         ticks = __calculate_ticks(tmp);
478         S390_lowcore.jiffy_timer += CLK_TICKS_PER_JIFFY * (__u64) ticks;
479
480         /* Set the clock comparator to the next tick. */
481         tmp = S390_lowcore.jiffy_timer + CPU_DEVIATION;
482         asm volatile ("SCKC %0" : : "m" (tmp));
483
484         /* Charge the ticks. */
485         if (ticks > 0) {
486 #ifdef CONFIG_SMP
487                 /*
488                  * Do not rely on the boot cpu to do the calls to do_timer.
489                  * Spread it over all cpus instead.
490                  */
491                 write_seqlock(&xtime_lock);
492                 if (S390_lowcore.jiffy_timer > xtime_cc) {
493                         __u32 xticks;
494
495                         tmp = S390_lowcore.jiffy_timer - xtime_cc;
496                         if (tmp >= 2*CLK_TICKS_PER_JIFFY) {
497                                 xticks = __calculate_ticks(tmp);
498                                 xtime_cc += (__u64) xticks*CLK_TICKS_PER_JIFFY;
499                         } else {
500                                 xticks = 1;
501                                 xtime_cc += CLK_TICKS_PER_JIFFY;
502                         }
503                         while (xticks--)
504                                 do_timer(regs);
505                 }
506                 write_sequnlock(&xtime_lock);
507                 while (ticks--)
508                         update_process_times(user_mode(regs));
509 #else
510                 while (ticks--)
511                         do_timer(regs);
512 #endif
513         }
514         cpu_clear(smp_processor_id(), nohz_cpu_mask);
515 }
516
517 /*
518  * Stop the HZ tick on the current CPU.
519  * Only cpu_idle may call this function.
520  */
521 int stop_hz_timer(void)
522 {
523         __u64 timer;
524
525         if (sysctl_hz_timer != 0)
526                 return 1;
527
528         /*
529          * Leave the clock comparator set up for the next timer
530          * tick if either rcu or a softirq is pending.
531          */
532         if (rcu_pending(smp_processor_id()) || local_softirq_pending())
533                 return 1;
534
535         /*
536          * This cpu is going really idle. Set up the clock comparator
537          * for the next event.
538          */
539         cpu_set(smp_processor_id(), nohz_cpu_mask);
540         timer = (__u64) (next_timer_interrupt() - jiffies) + jiffies_64;
541         timer = jiffies_timer_cc + timer * CLK_TICKS_PER_JIFFY;
542         asm volatile ("SCKC %0" : : "m" (timer));
543
544         return 0;
545 }
546 #endif
547
548 #if defined(CONFIG_VIRT_TIMER) || defined(CONFIG_NO_IDLE_HZ)
549
550 void do_monitor_call(struct pt_regs *regs, long interruption_code)
551 {
552         /* disable monitor call class 0 */
553         __ctl_clear_bit(8, 15);
554
555 #ifdef CONFIG_VIRT_TIMER
556         start_cpu_timer();
557 #endif
558 #ifdef CONFIG_NO_IDLE_HZ
559         start_hz_timer(regs);
560 #endif
561 }
562
563 /*
564  * called from cpu_idle to stop any timers
565  * returns 1 if CPU should not be stopped
566  */
567 int stop_timers(void)
568 {
569 #ifdef CONFIG_VIRT_TIMER
570         if (stop_cpu_timer())
571                 return 1;
572 #endif
573
574 #ifdef CONFIG_NO_IDLE_HZ
575         if (stop_hz_timer())
576                 return 1;
577 #endif
578
579         /* enable monitor call class 0 */
580         __ctl_set_bit(8, 15);
581
582         return 0;
583 }
584
585 #endif
586
587 /*
588  * Start the clock comparator and the virtual CPU timer
589  * on the current CPU.
590  */
591 void init_cpu_timer(void)
592 {
593         unsigned long cr0;
594         __u64 timer;
595 #ifdef CONFIG_VIRT_TIMER
596         struct vtimer_queue *vt_list;
597 #endif
598
599         timer = jiffies_timer_cc + jiffies_64 * CLK_TICKS_PER_JIFFY;
600         S390_lowcore.jiffy_timer = timer + CLK_TICKS_PER_JIFFY;
601         timer += CLK_TICKS_PER_JIFFY + CPU_DEVIATION;
602         asm volatile ("SCKC %0" : : "m" (timer));
603         /* allow clock comparator timer interrupt */
604         __ctl_store(cr0, 0, 0);
605         cr0 |= 0x800;
606         __ctl_load(cr0, 0, 0);
607
608 #ifdef CONFIG_VIRT_TIMER
609         /* kick the virtual timer */
610         timer = VTIMER_MAX_SLICE;
611         asm volatile ("SPT %0" : : "m" (timer));
612         __ctl_store(cr0, 0, 0);
613         cr0 |= 0x400;
614         __ctl_load(cr0, 0, 0);
615
616         vt_list = &per_cpu(virt_cpu_timer, smp_processor_id());
617         INIT_LIST_HEAD(&vt_list->list);
618         spin_lock_init(&vt_list->lock);
619         vt_list->to_expire = 0;
620         vt_list->offset = 0;
621         vt_list->idle = 0;
622 #endif
623 }
624
625 /*
626  * Initialize the TOD clock and the CPU timer of
627  * the boot cpu.
628  */
629 void __init time_init(void)
630 {
631         __u64 set_time_cc;
632         int cc;
633
634         /* kick the TOD clock */
635         asm volatile ("STCK 0(%1)\n\t"
636                       "IPM  %0\n\t"
637                       "SRL  %0,28" : "=r" (cc) : "a" (&init_timer_cc) 
638                                    : "memory", "cc");
639         switch (cc) {
640         case 0: /* clock in set state: all is fine */
641                 break;
642         case 1: /* clock in non-set state: FIXME */
643                 printk("time_init: TOD clock in non-set state\n");
644                 break;
645         case 2: /* clock in error state: FIXME */
646                 printk("time_init: TOD clock in error state\n");
647                 break;
648         case 3: /* clock in stopped or not-operational state: FIXME */
649                 printk("time_init: TOD clock stopped/non-operational\n");
650                 break;
651         }
652         jiffies_timer_cc = init_timer_cc - jiffies_64 * CLK_TICKS_PER_JIFFY;
653
654         /* set xtime */
655         xtime_cc = init_timer_cc + CLK_TICKS_PER_JIFFY;
656         set_time_cc = init_timer_cc - 0x8126d60e46000000LL +
657                 (0x3c26700LL*1000000*4096);
658         tod_to_timeval(set_time_cc, &xtime);
659         set_normalized_timespec(&wall_to_monotonic,
660                                 -xtime.tv_sec, -xtime.tv_nsec);
661
662         /* request the clock comparator external interrupt */
663         if (register_early_external_interrupt(0x1004, 0,
664                                               &ext_int_info_cc) != 0)
665                 panic("Couldn't request external interrupt 0x1004");
666
667 #ifdef CONFIG_VIRT_TIMER
668         /* request the cpu timer external interrupt */
669         if (register_early_external_interrupt(0x1005, do_cpu_timer_interrupt,
670                                               &ext_int_info_timer) != 0)
671                 panic("Couldn't request external interrupt 0x1005");
672 #endif
673
674         init_cpu_timer();
675 }
676
677 #ifdef CONFIG_VIRT_TIMER
678 void init_virt_timer(struct vtimer_list *timer)
679 {
680         timer->magic = VTIMER_MAGIC;
681         timer->function = NULL;
682         INIT_LIST_HEAD(&timer->entry);
683         spin_lock_init(&timer->lock);
684 }
685
686 static inline int check_vtimer(struct vtimer_list *timer)
687 {
688         if (timer->magic != VTIMER_MAGIC)
689                 return -EINVAL;
690         return 0;
691 }
692
693 static inline int vtimer_pending(struct vtimer_list *timer)
694 {
695         return (!list_empty(&timer->entry));
696 }
697
698 /*
699  * this function should only run on the specified CPU
700  */
701 static void internal_add_vtimer(struct vtimer_list *timer)
702 {
703         unsigned long flags;
704         __u64 done;
705         struct vtimer_list *event;
706         struct vtimer_queue *vt_list;
707
708         vt_list = &per_cpu(virt_cpu_timer, timer->cpu);
709         spin_lock_irqsave(&vt_list->lock, flags);
710
711         if (timer->cpu != smp_processor_id())
712                 printk("internal_add_vtimer: BUG, running on wrong CPU");
713
714         /* if list is empty we only have to set the timer */
715         if (list_empty(&vt_list->list)) {
716                 /* reset the offset, this may happen if the last timer was
717                  * just deleted by mod_virt_timer and the interrupt
718                  * didn't happen until here
719                  */
720                 vt_list->offset = 0;
721                 goto fire;
722         }
723
724         /* save progress */
725         asm volatile ("STPT %0" : "=m" (done));
726
727         /* calculate completed work */
728         done = vt_list->to_expire - done + vt_list->offset;
729         vt_list->offset = 0;
730
731         list_for_each_entry(event, &vt_list->list, entry)
732                 event->expires -= done;
733
734  fire:
735         list_add_sorted(timer, &vt_list->list);
736
737         /* get first element, which is the next vtimer slice */
738         event = list_entry(vt_list->list.next, struct vtimer_list, entry);
739
740         set_vtimer(event->expires);
741         spin_unlock_irqrestore(&vt_list->lock, flags);
742         /* release CPU aquired in prepare_vtimer or mod_virt_timer() */
743         put_cpu();
744 }
745
746 static inline int prepare_vtimer(struct vtimer_list *timer)
747 {
748         if (check_vtimer(timer) || !timer->function) {
749                 printk("add_virt_timer: uninitialized timer\n");
750                 return -EINVAL;
751         }
752
753         if (!timer->expires || timer->expires > VTIMER_MAX_SLICE) {
754                 printk("add_virt_timer: invalid timer expire value!\n");
755                 return -EINVAL;
756         }
757
758         if (vtimer_pending(timer)) {
759                 printk("add_virt_timer: timer pending\n");
760                 return -EBUSY;
761         }
762
763         timer->cpu = get_cpu();
764         return 0;
765 }
766
767 /*
768  * add_virt_timer - add an oneshot virtual CPU timer
769  */
770 void add_virt_timer(void *new)
771 {
772         struct vtimer_list *timer;
773
774         timer = (struct vtimer_list *)new;
775
776         if (prepare_vtimer(timer) < 0)
777                 return;
778
779         timer->interval = 0;
780         internal_add_vtimer(timer);
781 }
782
783 /*
784  * add_virt_timer_int - add an interval virtual CPU timer
785  */
786 void add_virt_timer_periodic(void *new)
787 {
788         struct vtimer_list *timer;
789
790         timer = (struct vtimer_list *)new;
791
792         if (prepare_vtimer(timer) < 0)
793                 return;
794
795         timer->interval = timer->expires;
796         internal_add_vtimer(timer);
797 }
798
799 /*
800  * If we change a pending timer the function must be called on the CPU
801  * where the timer is running on, e.g. by smp_call_function_on()
802  *
803  * The original mod_timer adds the timer if it is not pending. For compatibility
804  * we do the same. The timer will be added on the current CPU as a oneshot timer.
805  *
806  * returns whether it has modified a pending timer (1) or not (0)
807  */
808 int mod_virt_timer(struct vtimer_list *timer, __u64 expires)
809 {
810         struct vtimer_queue *vt_list;
811         unsigned long flags;
812         int cpu;
813
814         if (check_vtimer(timer) || !timer->function) {
815                 printk("mod_virt_timer: uninitialized timer\n");
816                 return  -EINVAL;
817         }
818
819         if (!expires || expires > VTIMER_MAX_SLICE) {
820                 printk("mod_virt_timer: invalid expire range\n");
821                 return -EINVAL;
822         }
823
824         /*
825          * This is a common optimization triggered by the
826          * networking code - if the timer is re-modified
827          * to be the same thing then just return:
828          */
829         if (timer->expires == expires && vtimer_pending(timer))
830                 return 1;
831
832         cpu = get_cpu();
833         vt_list = &per_cpu(virt_cpu_timer, cpu);
834
835         /* disable interrupts before test if timer is pending */
836         spin_lock_irqsave(&vt_list->lock, flags);
837
838         /* if timer isn't pending add it on the current CPU */
839         if (!vtimer_pending(timer)) {
840                 spin_unlock_irqrestore(&vt_list->lock, flags);
841                 /* we do not activate an interval timer with mod_virt_timer */
842                 timer->interval = 0;
843                 timer->expires = expires;
844                 timer->cpu = cpu;
845                 internal_add_vtimer(timer);
846                 return 0;
847         }
848
849         /* check if we run on the right CPU */
850         if (timer->cpu != cpu) {
851                 printk("mod_virt_timer: running on wrong CPU, check your code\n");
852                 spin_unlock_irqrestore(&vt_list->lock, flags);
853                 put_cpu();
854                 return -EINVAL;
855         }
856
857         list_del_init(&timer->entry);
858         timer->expires = expires;
859
860         /* also change the interval if we have an interval timer */
861         if (timer->interval)
862                 timer->interval = expires;
863
864         /* the timer can't expire anymore so we can release the lock */
865         spin_unlock_irqrestore(&vt_list->lock, flags);
866         internal_add_vtimer(timer);
867         return 1;
868 }
869
870 /*
871  * delete a virtual timer
872  *
873  * returns whether the deleted timer was pending (1) or not (0)
874  */
875 int del_virt_timer(struct vtimer_list *timer)
876 {
877         unsigned long flags;
878         struct vtimer_queue *vt_list;
879
880         if (check_vtimer(timer)) {
881                 printk("del_virt_timer: timer not initialized\n");
882                 return -EINVAL;
883         }
884
885         /* check if timer is pending */
886         if (!vtimer_pending(timer))
887                 return 0;
888
889         if (!cpu_online(timer->cpu)) {
890                 printk("del_virt_timer: CPU not present!\n");
891                 return -1;
892         }
893
894         vt_list = &per_cpu(virt_cpu_timer, timer->cpu);
895         spin_lock_irqsave(&vt_list->lock, flags);
896
897         /* we don't interrupt a running timer, just let it expire! */
898         list_del_init(&timer->entry);
899
900         /* last timer removed */
901         if (list_empty(&vt_list->list)) {
902                 vt_list->to_expire = 0;
903                 vt_list->offset = 0;
904         }
905
906         spin_unlock_irqrestore(&vt_list->lock, flags);
907         return 1;
908 }
909 #endif
910