aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/time.h1
-rw-r--r--arch/powerpc/kernel/time.c3
-rw-r--r--arch/powerpc/kvm/emulate.c9
3 files changed, 10 insertions, 3 deletions
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h
index 2136f58a54e8..3b4b4a8da922 100644
--- a/arch/powerpc/include/asm/time.h
+++ b/arch/powerpc/include/asm/time.h
@@ -23,6 +23,7 @@
23extern unsigned long tb_ticks_per_jiffy; 23extern unsigned long tb_ticks_per_jiffy;
24extern unsigned long tb_ticks_per_usec; 24extern unsigned long tb_ticks_per_usec;
25extern unsigned long tb_ticks_per_sec; 25extern unsigned long tb_ticks_per_sec;
26extern struct clock_event_device decrementer_clockevent;
26 27
27struct rtc_time; 28struct rtc_time;
28extern void to_tm(int tim, struct rtc_time * tm); 29extern void to_tm(int tim, struct rtc_time * tm);
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 2c42cd72d0f5..99a995c2a3f2 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -100,7 +100,7 @@ static int decrementer_set_next_event(unsigned long evt,
100static void decrementer_set_mode(enum clock_event_mode mode, 100static void decrementer_set_mode(enum clock_event_mode mode,
101 struct clock_event_device *dev); 101 struct clock_event_device *dev);
102 102
103static struct clock_event_device decrementer_clockevent = { 103struct clock_event_device decrementer_clockevent = {
104 .name = "decrementer", 104 .name = "decrementer",
105 .rating = 200, 105 .rating = 200,
106 .irq = 0, 106 .irq = 0,
@@ -108,6 +108,7 @@ static struct clock_event_device decrementer_clockevent = {
108 .set_mode = decrementer_set_mode, 108 .set_mode = decrementer_set_mode,
109 .features = CLOCK_EVT_FEAT_ONESHOT, 109 .features = CLOCK_EVT_FEAT_ONESHOT,
110}; 110};
111EXPORT_SYMBOL(decrementer_clockevent);
111 112
112DEFINE_PER_CPU(u64, decrementers_next_tb); 113DEFINE_PER_CPU(u64, decrementers_next_tb);
113static DEFINE_PER_CPU(struct clock_event_device, decrementers); 114static DEFINE_PER_CPU(struct clock_event_device, decrementers);
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
index afc9154f1aef..b5872f61a213 100644
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -23,6 +23,7 @@
23#include <linux/types.h> 23#include <linux/types.h>
24#include <linux/string.h> 24#include <linux/string.h>
25#include <linux/kvm_host.h> 25#include <linux/kvm_host.h>
26#include <linux/clockchips.h>
26 27
27#include <asm/reg.h> 28#include <asm/reg.h>
28#include <asm/time.h> 29#include <asm/time.h>
@@ -104,8 +105,12 @@ void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
104 */ 105 */
105 106
106 dec_time = vcpu->arch.dec; 107 dec_time = vcpu->arch.dec;
107 dec_time *= 1000; 108 /*
108 do_div(dec_time, tb_ticks_per_usec); 109 * Guest timebase ticks at the same frequency as host decrementer.
110 * So use the host decrementer calculations for decrementer emulation.
111 */
112 dec_time = dec_time << decrementer_clockevent.shift;
113 do_div(dec_time, decrementer_clockevent.mult);
109 dec_nsec = do_div(dec_time, NSEC_PER_SEC); 114 dec_nsec = do_div(dec_time, NSEC_PER_SEC);
110 hrtimer_start(&vcpu->arch.dec_timer, 115 hrtimer_start(&vcpu->arch.dec_timer,
111 ktime_set(dec_time, dec_nsec), HRTIMER_MODE_REL); 116 ktime_set(dec_time, dec_nsec), HRTIMER_MODE_REL);