19702785aSThomas Gleixner /* 29702785aSThomas Gleixner * Xen time implementation. 39702785aSThomas Gleixner * 49702785aSThomas Gleixner * This is implemented in terms of a clocksource driver which uses 59702785aSThomas Gleixner * the hypervisor clock as a nanosecond timebase, and a clockevent 69702785aSThomas Gleixner * driver which uses the hypervisor's timer mechanism. 79702785aSThomas Gleixner * 89702785aSThomas Gleixner * Jeremy Fitzhardinge <jeremy@xensource.com>, XenSource Inc, 2007 99702785aSThomas Gleixner */ 109702785aSThomas Gleixner #include <linux/kernel.h> 119702785aSThomas Gleixner #include <linux/interrupt.h> 129702785aSThomas Gleixner #include <linux/clocksource.h> 139702785aSThomas Gleixner #include <linux/clockchips.h> 149702785aSThomas Gleixner #include <linux/kernel_stat.h> 15f595ec96SJeremy Fitzhardinge #include <linux/math64.h> 165a0e3ad6STejun Heo #include <linux/gfp.h> 179702785aSThomas Gleixner 181c7b67f7SGerd Hoffmann #include <asm/pvclock.h> 199702785aSThomas Gleixner #include <asm/xen/hypervisor.h> 209702785aSThomas Gleixner #include <asm/xen/hypercall.h> 219702785aSThomas Gleixner 229702785aSThomas Gleixner #include <xen/events.h> 23409771d2SStefano Stabellini #include <xen/features.h> 249702785aSThomas Gleixner #include <xen/interface/xen.h> 259702785aSThomas Gleixner #include <xen/interface/vcpu.h> 269702785aSThomas Gleixner 279702785aSThomas Gleixner #include "xen-ops.h" 289702785aSThomas Gleixner 299702785aSThomas Gleixner /* Xen may fire a timer up to this many ns early */ 309702785aSThomas Gleixner #define TIMER_SLOP 100000 319702785aSThomas Gleixner #define NS_PER_TICK (1000000000LL / HZ) 329702785aSThomas Gleixner 339702785aSThomas Gleixner /* runstate info updated by Xen */ 34c6e22f9eSTejun Heo static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate); 359702785aSThomas Gleixner 369702785aSThomas Gleixner /* snapshots of runstate info */ 37c6e22f9eSTejun Heo static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate_snapshot); 389702785aSThomas Gleixner 399702785aSThomas Gleixner /* unused ns of stolen and blocked time */ 40c6e22f9eSTejun Heo static DEFINE_PER_CPU(u64, xen_residual_stolen); 41c6e22f9eSTejun Heo static DEFINE_PER_CPU(u64, xen_residual_blocked); 429702785aSThomas Gleixner 439702785aSThomas Gleixner /* return an consistent snapshot of 64-bit time/counter value */ 449702785aSThomas Gleixner static u64 get64(const u64 *p) 459702785aSThomas Gleixner { 469702785aSThomas Gleixner u64 ret; 479702785aSThomas Gleixner 489702785aSThomas Gleixner if (BITS_PER_LONG < 64) { 499702785aSThomas Gleixner u32 *p32 = (u32 *)p; 509702785aSThomas Gleixner u32 h, l; 519702785aSThomas Gleixner 529702785aSThomas Gleixner /* 539702785aSThomas Gleixner * Read high then low, and then make sure high is 549702785aSThomas Gleixner * still the same; this will only loop if low wraps 559702785aSThomas Gleixner * and carries into high. 569702785aSThomas Gleixner * XXX some clean way to make this endian-proof? 579702785aSThomas Gleixner */ 589702785aSThomas Gleixner do { 599702785aSThomas Gleixner h = p32[1]; 609702785aSThomas Gleixner barrier(); 619702785aSThomas Gleixner l = p32[0]; 629702785aSThomas Gleixner barrier(); 639702785aSThomas Gleixner } while (p32[1] != h); 649702785aSThomas Gleixner 659702785aSThomas Gleixner ret = (((u64)h) << 32) | l; 669702785aSThomas Gleixner } else 679702785aSThomas Gleixner ret = *p; 689702785aSThomas Gleixner 699702785aSThomas Gleixner return ret; 709702785aSThomas Gleixner } 719702785aSThomas Gleixner 729702785aSThomas Gleixner /* 739702785aSThomas Gleixner * Runstate accounting 749702785aSThomas Gleixner */ 759702785aSThomas Gleixner static void get_runstate_snapshot(struct vcpu_runstate_info *res) 769702785aSThomas Gleixner { 779702785aSThomas Gleixner u64 state_time; 789702785aSThomas Gleixner struct vcpu_runstate_info *state; 799702785aSThomas Gleixner 809702785aSThomas Gleixner BUG_ON(preemptible()); 819702785aSThomas Gleixner 82c6e22f9eSTejun Heo state = &__get_cpu_var(xen_runstate); 839702785aSThomas Gleixner 849702785aSThomas Gleixner /* 859702785aSThomas Gleixner * The runstate info is always updated by the hypervisor on 869702785aSThomas Gleixner * the current CPU, so there's no need to use anything 879702785aSThomas Gleixner * stronger than a compiler barrier when fetching it. 889702785aSThomas Gleixner */ 899702785aSThomas Gleixner do { 909702785aSThomas Gleixner state_time = get64(&state->state_entry_time); 919702785aSThomas Gleixner barrier(); 929702785aSThomas Gleixner *res = *state; 939702785aSThomas Gleixner barrier(); 949702785aSThomas Gleixner } while (get64(&state->state_entry_time) != state_time); 959702785aSThomas Gleixner } 969702785aSThomas Gleixner 97f0d73394SJeremy Fitzhardinge /* return true when a vcpu could run but has no real cpu to run on */ 98f0d73394SJeremy Fitzhardinge bool xen_vcpu_stolen(int vcpu) 99f0d73394SJeremy Fitzhardinge { 100c6e22f9eSTejun Heo return per_cpu(xen_runstate, vcpu).state == RUNSTATE_runnable; 101f0d73394SJeremy Fitzhardinge } 102f0d73394SJeremy Fitzhardinge 103be012920SIan Campbell void xen_setup_runstate_info(int cpu) 1049702785aSThomas Gleixner { 1059702785aSThomas Gleixner struct vcpu_register_runstate_memory_area area; 1069702785aSThomas Gleixner 107c6e22f9eSTejun Heo area.addr.v = &per_cpu(xen_runstate, cpu); 1089702785aSThomas Gleixner 1099702785aSThomas Gleixner if (HYPERVISOR_vcpu_op(VCPUOP_register_runstate_memory_area, 1109702785aSThomas Gleixner cpu, &area)) 1119702785aSThomas Gleixner BUG(); 1129702785aSThomas Gleixner } 1139702785aSThomas Gleixner 1149702785aSThomas Gleixner static void do_stolen_accounting(void) 1159702785aSThomas Gleixner { 1169702785aSThomas Gleixner struct vcpu_runstate_info state; 1179702785aSThomas Gleixner struct vcpu_runstate_info *snap; 1189702785aSThomas Gleixner s64 blocked, runnable, offline, stolen; 1199702785aSThomas Gleixner cputime_t ticks; 1209702785aSThomas Gleixner 1219702785aSThomas Gleixner get_runstate_snapshot(&state); 1229702785aSThomas Gleixner 1239702785aSThomas Gleixner WARN_ON(state.state != RUNSTATE_running); 1249702785aSThomas Gleixner 125c6e22f9eSTejun Heo snap = &__get_cpu_var(xen_runstate_snapshot); 1269702785aSThomas Gleixner 1279702785aSThomas Gleixner /* work out how much time the VCPU has not been runn*ing* */ 1289702785aSThomas Gleixner blocked = state.time[RUNSTATE_blocked] - snap->time[RUNSTATE_blocked]; 1299702785aSThomas Gleixner runnable = state.time[RUNSTATE_runnable] - snap->time[RUNSTATE_runnable]; 1309702785aSThomas Gleixner offline = state.time[RUNSTATE_offline] - snap->time[RUNSTATE_offline]; 1319702785aSThomas Gleixner 1329702785aSThomas Gleixner *snap = state; 1339702785aSThomas Gleixner 1349702785aSThomas Gleixner /* Add the appropriate number of ticks of stolen time, 13579741dd3SMartin Schwidefsky including any left-overs from last time. */ 136780f36d8SChristoph Lameter stolen = runnable + offline + __this_cpu_read(xen_residual_stolen); 1379702785aSThomas Gleixner 1389702785aSThomas Gleixner if (stolen < 0) 1399702785aSThomas Gleixner stolen = 0; 1409702785aSThomas Gleixner 141f595ec96SJeremy Fitzhardinge ticks = iter_div_u64_rem(stolen, NS_PER_TICK, &stolen); 142780f36d8SChristoph Lameter __this_cpu_write(xen_residual_stolen, stolen); 14379741dd3SMartin Schwidefsky account_steal_ticks(ticks); 1449702785aSThomas Gleixner 1459702785aSThomas Gleixner /* Add the appropriate number of ticks of blocked time, 14679741dd3SMartin Schwidefsky including any left-overs from last time. */ 147780f36d8SChristoph Lameter blocked += __this_cpu_read(xen_residual_blocked); 1489702785aSThomas Gleixner 1499702785aSThomas Gleixner if (blocked < 0) 1509702785aSThomas Gleixner blocked = 0; 1519702785aSThomas Gleixner 152f595ec96SJeremy Fitzhardinge ticks = iter_div_u64_rem(blocked, NS_PER_TICK, &blocked); 153780f36d8SChristoph Lameter __this_cpu_write(xen_residual_blocked, blocked); 15479741dd3SMartin Schwidefsky account_idle_ticks(ticks); 1559702785aSThomas Gleixner } 1569702785aSThomas Gleixner 157e93ef949SAlok Kataria /* Get the TSC speed from Xen */ 158409771d2SStefano Stabellini static unsigned long xen_tsc_khz(void) 1599702785aSThomas Gleixner { 1603807f345SGlauber Costa struct pvclock_vcpu_time_info *info = 1619702785aSThomas Gleixner &HYPERVISOR_shared_info->vcpu_info[0].time; 1629702785aSThomas Gleixner 1633807f345SGlauber Costa return pvclock_tsc_khz(info); 1649702785aSThomas Gleixner } 1659702785aSThomas Gleixner 166ee7686bcSJeremy Fitzhardinge cycle_t xen_clocksource_read(void) 1679702785aSThomas Gleixner { 1681c7b67f7SGerd Hoffmann struct pvclock_vcpu_time_info *src; 1699702785aSThomas Gleixner cycle_t ret; 1709702785aSThomas Gleixner 1711c7b67f7SGerd Hoffmann src = &get_cpu_var(xen_vcpu)->time; 1721c7b67f7SGerd Hoffmann ret = pvclock_clocksource_read(src); 1731c7b67f7SGerd Hoffmann put_cpu_var(xen_vcpu); 1749702785aSThomas Gleixner return ret; 1759702785aSThomas Gleixner } 1769702785aSThomas Gleixner 1778e19608eSMagnus Damm static cycle_t xen_clocksource_get_cycles(struct clocksource *cs) 1788e19608eSMagnus Damm { 1798e19608eSMagnus Damm return xen_clocksource_read(); 1808e19608eSMagnus Damm } 1818e19608eSMagnus Damm 1829702785aSThomas Gleixner static void xen_read_wallclock(struct timespec *ts) 1839702785aSThomas Gleixner { 1841c7b67f7SGerd Hoffmann struct shared_info *s = HYPERVISOR_shared_info; 1851c7b67f7SGerd Hoffmann struct pvclock_wall_clock *wall_clock = &(s->wc); 1861c7b67f7SGerd Hoffmann struct pvclock_vcpu_time_info *vcpu_time; 1879702785aSThomas Gleixner 1881c7b67f7SGerd Hoffmann vcpu_time = &get_cpu_var(xen_vcpu)->time; 1891c7b67f7SGerd Hoffmann pvclock_read_wallclock(wall_clock, vcpu_time, ts); 1901c7b67f7SGerd Hoffmann put_cpu_var(xen_vcpu); 1919702785aSThomas Gleixner } 1929702785aSThomas Gleixner 193409771d2SStefano Stabellini static unsigned long xen_get_wallclock(void) 1949702785aSThomas Gleixner { 1959702785aSThomas Gleixner struct timespec ts; 1969702785aSThomas Gleixner 1979702785aSThomas Gleixner xen_read_wallclock(&ts); 1989702785aSThomas Gleixner return ts.tv_sec; 1999702785aSThomas Gleixner } 2009702785aSThomas Gleixner 201409771d2SStefano Stabellini static int xen_set_wallclock(unsigned long now) 2029702785aSThomas Gleixner { 203*fdb9eb9fSJeremy Fitzhardinge struct xen_platform_op op; 204*fdb9eb9fSJeremy Fitzhardinge int rc; 205*fdb9eb9fSJeremy Fitzhardinge 2069702785aSThomas Gleixner /* do nothing for domU */ 207*fdb9eb9fSJeremy Fitzhardinge if (!xen_initial_domain()) 2089702785aSThomas Gleixner return -1; 209*fdb9eb9fSJeremy Fitzhardinge 210*fdb9eb9fSJeremy Fitzhardinge op.cmd = XENPF_settime; 211*fdb9eb9fSJeremy Fitzhardinge op.u.settime.secs = now; 212*fdb9eb9fSJeremy Fitzhardinge op.u.settime.nsecs = 0; 213*fdb9eb9fSJeremy Fitzhardinge op.u.settime.system_time = xen_clocksource_read(); 214*fdb9eb9fSJeremy Fitzhardinge 215*fdb9eb9fSJeremy Fitzhardinge rc = HYPERVISOR_dom0_op(&op); 216*fdb9eb9fSJeremy Fitzhardinge WARN(rc != 0, "XENPF_settime failed: now=%ld\n", now); 217*fdb9eb9fSJeremy Fitzhardinge 218*fdb9eb9fSJeremy Fitzhardinge return rc; 2199702785aSThomas Gleixner } 2209702785aSThomas Gleixner 2219702785aSThomas Gleixner static struct clocksource xen_clocksource __read_mostly = { 2229702785aSThomas Gleixner .name = "xen", 2239702785aSThomas Gleixner .rating = 400, 2248e19608eSMagnus Damm .read = xen_clocksource_get_cycles, 2259702785aSThomas Gleixner .mask = ~0, 2269702785aSThomas Gleixner .flags = CLOCK_SOURCE_IS_CONTINUOUS, 2279702785aSThomas Gleixner }; 2289702785aSThomas Gleixner 2299702785aSThomas Gleixner /* 2309702785aSThomas Gleixner Xen clockevent implementation 2319702785aSThomas Gleixner 2329702785aSThomas Gleixner Xen has two clockevent implementations: 2339702785aSThomas Gleixner 2349702785aSThomas Gleixner The old timer_op one works with all released versions of Xen prior 2359702785aSThomas Gleixner to version 3.0.4. This version of the hypervisor provides a 2369702785aSThomas Gleixner single-shot timer with nanosecond resolution. However, sharing the 2379702785aSThomas Gleixner same event channel is a 100Hz tick which is delivered while the 2389702785aSThomas Gleixner vcpu is running. We don't care about or use this tick, but it will 2399702785aSThomas Gleixner cause the core time code to think the timer fired too soon, and 2409702785aSThomas Gleixner will end up resetting it each time. It could be filtered, but 2419702785aSThomas Gleixner doing so has complications when the ktime clocksource is not yet 2429702785aSThomas Gleixner the xen clocksource (ie, at boot time). 2439702785aSThomas Gleixner 2449702785aSThomas Gleixner The new vcpu_op-based timer interface allows the tick timer period 2459702785aSThomas Gleixner to be changed or turned off. The tick timer is not useful as a 2469702785aSThomas Gleixner periodic timer because events are only delivered to running vcpus. 2479702785aSThomas Gleixner The one-shot timer can report when a timeout is in the past, so 2489702785aSThomas Gleixner set_next_event is capable of returning -ETIME when appropriate. 2499702785aSThomas Gleixner This interface is used when available. 2509702785aSThomas Gleixner */ 2519702785aSThomas Gleixner 2529702785aSThomas Gleixner 2539702785aSThomas Gleixner /* 2549702785aSThomas Gleixner Get a hypervisor absolute time. In theory we could maintain an 2559702785aSThomas Gleixner offset between the kernel's time and the hypervisor's time, and 2569702785aSThomas Gleixner apply that to a kernel's absolute timeout. Unfortunately the 2579702785aSThomas Gleixner hypervisor and kernel times can drift even if the kernel is using 2589702785aSThomas Gleixner the Xen clocksource, because ntp can warp the kernel's clocksource. 2599702785aSThomas Gleixner */ 2609702785aSThomas Gleixner static s64 get_abs_timeout(unsigned long delta) 2619702785aSThomas Gleixner { 2629702785aSThomas Gleixner return xen_clocksource_read() + delta; 2639702785aSThomas Gleixner } 2649702785aSThomas Gleixner 2659702785aSThomas Gleixner static void xen_timerop_set_mode(enum clock_event_mode mode, 2669702785aSThomas Gleixner struct clock_event_device *evt) 2679702785aSThomas Gleixner { 2689702785aSThomas Gleixner switch (mode) { 2699702785aSThomas Gleixner case CLOCK_EVT_MODE_PERIODIC: 2709702785aSThomas Gleixner /* unsupported */ 2719702785aSThomas Gleixner WARN_ON(1); 2729702785aSThomas Gleixner break; 2739702785aSThomas Gleixner 2749702785aSThomas Gleixner case CLOCK_EVT_MODE_ONESHOT: 2759702785aSThomas Gleixner case CLOCK_EVT_MODE_RESUME: 2769702785aSThomas Gleixner break; 2779702785aSThomas Gleixner 2789702785aSThomas Gleixner case CLOCK_EVT_MODE_UNUSED: 2799702785aSThomas Gleixner case CLOCK_EVT_MODE_SHUTDOWN: 2809702785aSThomas Gleixner HYPERVISOR_set_timer_op(0); /* cancel timeout */ 2819702785aSThomas Gleixner break; 2829702785aSThomas Gleixner } 2839702785aSThomas Gleixner } 2849702785aSThomas Gleixner 2859702785aSThomas Gleixner static int xen_timerop_set_next_event(unsigned long delta, 2869702785aSThomas Gleixner struct clock_event_device *evt) 2879702785aSThomas Gleixner { 2889702785aSThomas Gleixner WARN_ON(evt->mode != CLOCK_EVT_MODE_ONESHOT); 2899702785aSThomas Gleixner 2909702785aSThomas Gleixner if (HYPERVISOR_set_timer_op(get_abs_timeout(delta)) < 0) 2919702785aSThomas Gleixner BUG(); 2929702785aSThomas Gleixner 2939702785aSThomas Gleixner /* We may have missed the deadline, but there's no real way of 2949702785aSThomas Gleixner knowing for sure. If the event was in the past, then we'll 2959702785aSThomas Gleixner get an immediate interrupt. */ 2969702785aSThomas Gleixner 2979702785aSThomas Gleixner return 0; 2989702785aSThomas Gleixner } 2999702785aSThomas Gleixner 3009702785aSThomas Gleixner static const struct clock_event_device xen_timerop_clockevent = { 3019702785aSThomas Gleixner .name = "xen", 3029702785aSThomas Gleixner .features = CLOCK_EVT_FEAT_ONESHOT, 3039702785aSThomas Gleixner 3049702785aSThomas Gleixner .max_delta_ns = 0xffffffff, 3059702785aSThomas Gleixner .min_delta_ns = TIMER_SLOP, 3069702785aSThomas Gleixner 3079702785aSThomas Gleixner .mult = 1, 3089702785aSThomas Gleixner .shift = 0, 3099702785aSThomas Gleixner .rating = 500, 3109702785aSThomas Gleixner 3119702785aSThomas Gleixner .set_mode = xen_timerop_set_mode, 3129702785aSThomas Gleixner .set_next_event = xen_timerop_set_next_event, 3139702785aSThomas Gleixner }; 3149702785aSThomas Gleixner 3159702785aSThomas Gleixner 3169702785aSThomas Gleixner 3179702785aSThomas Gleixner static void xen_vcpuop_set_mode(enum clock_event_mode mode, 3189702785aSThomas Gleixner struct clock_event_device *evt) 3199702785aSThomas Gleixner { 3209702785aSThomas Gleixner int cpu = smp_processor_id(); 3219702785aSThomas Gleixner 3229702785aSThomas Gleixner switch (mode) { 3239702785aSThomas Gleixner case CLOCK_EVT_MODE_PERIODIC: 3249702785aSThomas Gleixner WARN_ON(1); /* unsupported */ 3259702785aSThomas Gleixner break; 3269702785aSThomas Gleixner 3279702785aSThomas Gleixner case CLOCK_EVT_MODE_ONESHOT: 3289702785aSThomas Gleixner if (HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer, cpu, NULL)) 3299702785aSThomas Gleixner BUG(); 3309702785aSThomas Gleixner break; 3319702785aSThomas Gleixner 3329702785aSThomas Gleixner case CLOCK_EVT_MODE_UNUSED: 3339702785aSThomas Gleixner case CLOCK_EVT_MODE_SHUTDOWN: 3349702785aSThomas Gleixner if (HYPERVISOR_vcpu_op(VCPUOP_stop_singleshot_timer, cpu, NULL) || 3359702785aSThomas Gleixner HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer, cpu, NULL)) 3369702785aSThomas Gleixner BUG(); 3379702785aSThomas Gleixner break; 3389702785aSThomas Gleixner case CLOCK_EVT_MODE_RESUME: 3399702785aSThomas Gleixner break; 3409702785aSThomas Gleixner } 3419702785aSThomas Gleixner } 3429702785aSThomas Gleixner 3439702785aSThomas Gleixner static int xen_vcpuop_set_next_event(unsigned long delta, 3449702785aSThomas Gleixner struct clock_event_device *evt) 3459702785aSThomas Gleixner { 3469702785aSThomas Gleixner int cpu = smp_processor_id(); 3479702785aSThomas Gleixner struct vcpu_set_singleshot_timer single; 3489702785aSThomas Gleixner int ret; 3499702785aSThomas Gleixner 3509702785aSThomas Gleixner WARN_ON(evt->mode != CLOCK_EVT_MODE_ONESHOT); 3519702785aSThomas Gleixner 3529702785aSThomas Gleixner single.timeout_abs_ns = get_abs_timeout(delta); 3539702785aSThomas Gleixner single.flags = VCPU_SSHOTTMR_future; 3549702785aSThomas Gleixner 3559702785aSThomas Gleixner ret = HYPERVISOR_vcpu_op(VCPUOP_set_singleshot_timer, cpu, &single); 3569702785aSThomas Gleixner 3579702785aSThomas Gleixner BUG_ON(ret != 0 && ret != -ETIME); 3589702785aSThomas Gleixner 3599702785aSThomas Gleixner return ret; 3609702785aSThomas Gleixner } 3619702785aSThomas Gleixner 3629702785aSThomas Gleixner static const struct clock_event_device xen_vcpuop_clockevent = { 3639702785aSThomas Gleixner .name = "xen", 3649702785aSThomas Gleixner .features = CLOCK_EVT_FEAT_ONESHOT, 3659702785aSThomas Gleixner 3669702785aSThomas Gleixner .max_delta_ns = 0xffffffff, 3679702785aSThomas Gleixner .min_delta_ns = TIMER_SLOP, 3689702785aSThomas Gleixner 3699702785aSThomas Gleixner .mult = 1, 3709702785aSThomas Gleixner .shift = 0, 3719702785aSThomas Gleixner .rating = 500, 3729702785aSThomas Gleixner 3739702785aSThomas Gleixner .set_mode = xen_vcpuop_set_mode, 3749702785aSThomas Gleixner .set_next_event = xen_vcpuop_set_next_event, 3759702785aSThomas Gleixner }; 3769702785aSThomas Gleixner 3779702785aSThomas Gleixner static const struct clock_event_device *xen_clockevent = 3789702785aSThomas Gleixner &xen_timerop_clockevent; 3799702785aSThomas Gleixner static DEFINE_PER_CPU(struct clock_event_device, xen_clock_events); 3809702785aSThomas Gleixner 3819702785aSThomas Gleixner static irqreturn_t xen_timer_interrupt(int irq, void *dev_id) 3829702785aSThomas Gleixner { 3839702785aSThomas Gleixner struct clock_event_device *evt = &__get_cpu_var(xen_clock_events); 3849702785aSThomas Gleixner irqreturn_t ret; 3859702785aSThomas Gleixner 3869702785aSThomas Gleixner ret = IRQ_NONE; 3879702785aSThomas Gleixner if (evt->event_handler) { 3889702785aSThomas Gleixner evt->event_handler(evt); 3899702785aSThomas Gleixner ret = IRQ_HANDLED; 3909702785aSThomas Gleixner } 3919702785aSThomas Gleixner 3929702785aSThomas Gleixner do_stolen_accounting(); 3939702785aSThomas Gleixner 3949702785aSThomas Gleixner return ret; 3959702785aSThomas Gleixner } 3969702785aSThomas Gleixner 3979702785aSThomas Gleixner void xen_setup_timer(int cpu) 3989702785aSThomas Gleixner { 3999702785aSThomas Gleixner const char *name; 4009702785aSThomas Gleixner struct clock_event_device *evt; 4019702785aSThomas Gleixner int irq; 4029702785aSThomas Gleixner 4039702785aSThomas Gleixner printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu); 4049702785aSThomas Gleixner 4059702785aSThomas Gleixner name = kasprintf(GFP_KERNEL, "timer%d", cpu); 4069702785aSThomas Gleixner if (!name) 4079702785aSThomas Gleixner name = "<timer kasprintf failed>"; 4089702785aSThomas Gleixner 4099702785aSThomas Gleixner irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, xen_timer_interrupt, 410f611f2daSIan Campbell IRQF_DISABLED|IRQF_PERCPU| 411f611f2daSIan Campbell IRQF_NOBALANCING|IRQF_TIMER| 412f611f2daSIan Campbell IRQF_FORCE_RESUME, 4139702785aSThomas Gleixner name, NULL); 4149702785aSThomas Gleixner 4159702785aSThomas Gleixner evt = &per_cpu(xen_clock_events, cpu); 4169702785aSThomas Gleixner memcpy(evt, xen_clockevent, sizeof(*evt)); 4179702785aSThomas Gleixner 418320ab2b0SRusty Russell evt->cpumask = cpumask_of(cpu); 4199702785aSThomas Gleixner evt->irq = irq; 4209702785aSThomas Gleixner } 4219702785aSThomas Gleixner 422d68d82afSAlex Nixon void xen_teardown_timer(int cpu) 423d68d82afSAlex Nixon { 424d68d82afSAlex Nixon struct clock_event_device *evt; 425d68d82afSAlex Nixon BUG_ON(cpu == 0); 426d68d82afSAlex Nixon evt = &per_cpu(xen_clock_events, cpu); 427d68d82afSAlex Nixon unbind_from_irqhandler(evt->irq, NULL); 428d68d82afSAlex Nixon } 429d68d82afSAlex Nixon 4309702785aSThomas Gleixner void xen_setup_cpu_clockevents(void) 4319702785aSThomas Gleixner { 4329702785aSThomas Gleixner BUG_ON(preemptible()); 4339702785aSThomas Gleixner 4349702785aSThomas Gleixner clockevents_register_device(&__get_cpu_var(xen_clock_events)); 4359702785aSThomas Gleixner } 4369702785aSThomas Gleixner 437d07af1f0SJeremy Fitzhardinge void xen_timer_resume(void) 438d07af1f0SJeremy Fitzhardinge { 439d07af1f0SJeremy Fitzhardinge int cpu; 440d07af1f0SJeremy Fitzhardinge 441e7a3481cSJeremy Fitzhardinge pvclock_resume(); 442e7a3481cSJeremy Fitzhardinge 443d07af1f0SJeremy Fitzhardinge if (xen_clockevent != &xen_vcpuop_clockevent) 444d07af1f0SJeremy Fitzhardinge return; 445d07af1f0SJeremy Fitzhardinge 446d07af1f0SJeremy Fitzhardinge for_each_online_cpu(cpu) { 447d07af1f0SJeremy Fitzhardinge if (HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer, cpu, NULL)) 448d07af1f0SJeremy Fitzhardinge BUG(); 449d07af1f0SJeremy Fitzhardinge } 450d07af1f0SJeremy Fitzhardinge } 451d07af1f0SJeremy Fitzhardinge 452fb6ce5deSDaniel Kiper static const struct pv_time_ops xen_time_ops __initconst = { 453ca50a5f3SJeremy Fitzhardinge .sched_clock = xen_clocksource_read, 454409771d2SStefano Stabellini }; 455409771d2SStefano Stabellini 456fb6ce5deSDaniel Kiper static void __init xen_time_init(void) 4579702785aSThomas Gleixner { 4589702785aSThomas Gleixner int cpu = smp_processor_id(); 459c4507257SJohn Stultz struct timespec tp; 4609702785aSThomas Gleixner 461b01cc1b0SJohn Stultz clocksource_register_hz(&xen_clocksource, NSEC_PER_SEC); 4629702785aSThomas Gleixner 4639702785aSThomas Gleixner if (HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer, cpu, NULL) == 0) { 4649702785aSThomas Gleixner /* Successfully turned off 100Hz tick, so we have the 4659702785aSThomas Gleixner vcpuop-based timer interface */ 4669702785aSThomas Gleixner printk(KERN_DEBUG "Xen: using vcpuop timer interface\n"); 4679702785aSThomas Gleixner xen_clockevent = &xen_vcpuop_clockevent; 4689702785aSThomas Gleixner } 4699702785aSThomas Gleixner 4709702785aSThomas Gleixner /* Set initial system time with full resolution */ 471c4507257SJohn Stultz xen_read_wallclock(&tp); 472c4507257SJohn Stultz do_settimeofday(&tp); 4739702785aSThomas Gleixner 474404ee5b1SAndi Kleen setup_force_cpu_cap(X86_FEATURE_TSC); 4759702785aSThomas Gleixner 476be012920SIan Campbell xen_setup_runstate_info(cpu); 4779702785aSThomas Gleixner xen_setup_timer(cpu); 4789702785aSThomas Gleixner xen_setup_cpu_clockevents(); 4799702785aSThomas Gleixner } 480409771d2SStefano Stabellini 481fb6ce5deSDaniel Kiper void __init xen_init_time_ops(void) 482409771d2SStefano Stabellini { 483409771d2SStefano Stabellini pv_time_ops = xen_time_ops; 484409771d2SStefano Stabellini 485409771d2SStefano Stabellini x86_init.timers.timer_init = xen_time_init; 486409771d2SStefano Stabellini x86_init.timers.setup_percpu_clockev = x86_init_noop; 487409771d2SStefano Stabellini x86_cpuinit.setup_percpu_clockev = x86_init_noop; 488409771d2SStefano Stabellini 489409771d2SStefano Stabellini x86_platform.calibrate_tsc = xen_tsc_khz; 490409771d2SStefano Stabellini x86_platform.get_wallclock = xen_get_wallclock; 491409771d2SStefano Stabellini x86_platform.set_wallclock = xen_set_wallclock; 492409771d2SStefano Stabellini } 493409771d2SStefano Stabellini 494ca65f9fcSStefano Stabellini #ifdef CONFIG_XEN_PVHVM 495409771d2SStefano Stabellini static void xen_hvm_setup_cpu_clockevents(void) 496409771d2SStefano Stabellini { 497409771d2SStefano Stabellini int cpu = smp_processor_id(); 498409771d2SStefano Stabellini xen_setup_runstate_info(cpu); 499409771d2SStefano Stabellini xen_setup_timer(cpu); 500409771d2SStefano Stabellini xen_setup_cpu_clockevents(); 501409771d2SStefano Stabellini } 502409771d2SStefano Stabellini 503fb6ce5deSDaniel Kiper void __init xen_hvm_init_time_ops(void) 504409771d2SStefano Stabellini { 505409771d2SStefano Stabellini /* vector callback is needed otherwise we cannot receive interrupts 50631e7e931SStefano Stabellini * on cpu > 0 and at this point we don't know how many cpus are 50731e7e931SStefano Stabellini * available */ 50831e7e931SStefano Stabellini if (!xen_have_vector_callback) 509409771d2SStefano Stabellini return; 510409771d2SStefano Stabellini if (!xen_feature(XENFEAT_hvm_safe_pvclock)) { 511409771d2SStefano Stabellini printk(KERN_INFO "Xen doesn't support pvclock on HVM," 512409771d2SStefano Stabellini "disable pv timer\n"); 513409771d2SStefano Stabellini return; 514409771d2SStefano Stabellini } 515409771d2SStefano Stabellini 516409771d2SStefano Stabellini pv_time_ops = xen_time_ops; 517409771d2SStefano Stabellini x86_init.timers.setup_percpu_clockev = xen_time_init; 518409771d2SStefano Stabellini x86_cpuinit.setup_percpu_clockev = xen_hvm_setup_cpu_clockevents; 519409771d2SStefano Stabellini 520409771d2SStefano Stabellini x86_platform.calibrate_tsc = xen_tsc_khz; 521409771d2SStefano Stabellini x86_platform.get_wallclock = xen_get_wallclock; 522409771d2SStefano Stabellini x86_platform.set_wallclock = xen_set_wallclock; 523409771d2SStefano Stabellini } 524ca65f9fcSStefano Stabellini #endif 525