aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/xen/enlighten.c2
-rw-r--r--arch/i386/xen/time.c27
-rw-r--r--arch/i386/xen/xen-ops.h3
3 files changed, 28 insertions, 4 deletions
diff --git a/arch/i386/xen/enlighten.c b/arch/i386/xen/enlighten.c
index 9550ae3b1fb1..a9ba834295a2 100644
--- a/arch/i386/xen/enlighten.c
+++ b/arch/i386/xen/enlighten.c
@@ -683,7 +683,7 @@ static const struct paravirt_ops xen_paravirt_ops __initdata = {
683 .set_wallclock = xen_set_wallclock, 683 .set_wallclock = xen_set_wallclock,
684 .get_wallclock = xen_get_wallclock, 684 .get_wallclock = xen_get_wallclock,
685 .get_cpu_khz = xen_cpu_khz, 685 .get_cpu_khz = xen_cpu_khz,
686 .sched_clock = xen_clocksource_read, 686 .sched_clock = xen_sched_clock,
687 687
688 .cpuid = xen_cpuid, 688 .cpuid = xen_cpuid,
689 689
diff --git a/arch/i386/xen/time.c b/arch/i386/xen/time.c
index acbfd9969462..2aab44bec2a5 100644
--- a/arch/i386/xen/time.c
+++ b/arch/i386/xen/time.c
@@ -28,6 +28,8 @@
28#define TIMER_SLOP 100000 28#define TIMER_SLOP 100000
29#define NS_PER_TICK (1000000000LL / HZ) 29#define NS_PER_TICK (1000000000LL / HZ)
30 30
31static cycle_t xen_clocksource_read(void);
32
31/* These are perodically updated in shared_info, and then copied here. */ 33/* These are perodically updated in shared_info, and then copied here. */
32struct shadow_time_info { 34struct shadow_time_info {
33 u64 tsc_timestamp; /* TSC at last update of time vals. */ 35 u64 tsc_timestamp; /* TSC at last update of time vals. */
@@ -169,6 +171,29 @@ static void do_stolen_accounting(void)
169 account_steal_time(idle_task(smp_processor_id()), ticks); 171 account_steal_time(idle_task(smp_processor_id()), ticks);
170} 172}
171 173
174/*
175 * Xen sched_clock implementation. Returns the number of unstolen
176 * nanoseconds, which is nanoseconds the VCPU spent in RUNNING+BLOCKED
177 * states.
178 */
179unsigned long long xen_sched_clock(void)
180{
181 struct vcpu_runstate_info state;
182 cycle_t now = xen_clocksource_read();
183 s64 offset;
184
185 get_runstate_snapshot(&state);
186
187 WARN_ON(state.state != RUNSTATE_running);
188
189 offset = now - state.state_entry_time;
190 if (offset < 0)
191 offset = 0;
192
193 return state.time[RUNSTATE_blocked] +
194 state.time[RUNSTATE_running] +
195 offset;
196}
172 197
173 198
174/* Get the CPU speed from Xen */ 199/* Get the CPU speed from Xen */
@@ -261,7 +286,7 @@ static u64 get_nsec_offset(struct shadow_time_info *shadow)
261 return scale_delta(delta, shadow->tsc_to_nsec_mul, shadow->tsc_shift); 286 return scale_delta(delta, shadow->tsc_to_nsec_mul, shadow->tsc_shift);
262} 287}
263 288
264cycle_t xen_clocksource_read(void) 289static cycle_t xen_clocksource_read(void)
265{ 290{
266 struct shadow_time_info *shadow = &get_cpu_var(shadow_time); 291 struct shadow_time_info *shadow = &get_cpu_var(shadow_time);
267 cycle_t ret; 292 cycle_t ret;
diff --git a/arch/i386/xen/xen-ops.h b/arch/i386/xen/xen-ops.h
index 54d98b52085e..7667abd390ec 100644
--- a/arch/i386/xen/xen-ops.h
+++ b/arch/i386/xen/xen-ops.h
@@ -2,7 +2,6 @@
2#define XEN_OPS_H 2#define XEN_OPS_H
3 3
4#include <linux/init.h> 4#include <linux/init.h>
5#include <linux/clocksource.h>
6 5
7DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu); 6DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu);
8DECLARE_PER_CPU(unsigned long, xen_cr3); 7DECLARE_PER_CPU(unsigned long, xen_cr3);
@@ -18,7 +17,7 @@ unsigned long xen_cpu_khz(void);
18void __init xen_time_init(void); 17void __init xen_time_init(void);
19unsigned long xen_get_wallclock(void); 18unsigned long xen_get_wallclock(void);
20int xen_set_wallclock(unsigned long time); 19int xen_set_wallclock(unsigned long time);
21cycle_t xen_clocksource_read(void); 20unsigned long long xen_sched_clock(void);
22 21
23void xen_mark_init_mm_pinned(void); 22void xen_mark_init_mm_pinned(void);
24 23