aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/emulate.c
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2009-10-30 01:47:15 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-11-05 00:49:56 -0500
commit9a7a9b09fee8487003df012d9af4b227b3661e4d (patch)
treed51f49af2f6eb0cd41bfcc62aba3c75a35f8f600 /arch/powerpc/kvm/emulate.c
parentc215c6e49fef6c79a5b98f66f11cc6b1e395cb59 (diff)
Add mfdec emulation
We support setting the DEC to a certain value right now. Doing that basically triggers the CPU local timer. But there's also an mfdec command that enabled the OS to read the decrementor. This is required at least by all desktop and server PowerPC Linux kernels. It can't really hurt to allow embedded ones to do it as well though. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kvm/emulate.c')
-rw-r--r--arch/powerpc/kvm/emulate.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
index 7737146af3f..50d411d946e 100644
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -66,12 +66,14 @@
66 66
67void kvmppc_emulate_dec(struct kvm_vcpu *vcpu) 67void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
68{ 68{
69 unsigned long nr_jiffies;
70
69 if (vcpu->arch.tcr & TCR_DIE) { 71 if (vcpu->arch.tcr & TCR_DIE) {
70 /* The decrementer ticks at the same rate as the timebase, so 72 /* The decrementer ticks at the same rate as the timebase, so
71 * that's how we convert the guest DEC value to the number of 73 * that's how we convert the guest DEC value to the number of
72 * host ticks. */ 74 * host ticks. */
73 unsigned long nr_jiffies;
74 75
76 vcpu->arch.dec_jiffies = mftb();
75 nr_jiffies = vcpu->arch.dec / tb_ticks_per_jiffy; 77 nr_jiffies = vcpu->arch.dec / tb_ticks_per_jiffy;
76 mod_timer(&vcpu->arch.dec_timer, 78 mod_timer(&vcpu->arch.dec_timer,
77 get_jiffies_64() + nr_jiffies); 79 get_jiffies_64() + nr_jiffies);
@@ -211,6 +213,15 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
211 /* Note: SPRG4-7 are user-readable, so we don't get 213 /* Note: SPRG4-7 are user-readable, so we don't get
212 * a trap. */ 214 * a trap. */
213 215
216 case SPRN_DEC:
217 {
218 u64 jd = mftb() - vcpu->arch.dec_jiffies;
219 vcpu->arch.gpr[rt] = vcpu->arch.dec - jd;
220#ifdef DEBUG_EMUL
221 printk(KERN_INFO "mfDEC: %x - %llx = %lx\n", vcpu->arch.dec, jd, vcpu->arch.gpr[rt]);
222#endif
223 break;
224 }
214 default: 225 default:
215 emulated = kvmppc_core_emulate_mfspr(vcpu, sprn, rt); 226 emulated = kvmppc_core_emulate_mfspr(vcpu, sprn, rt);
216 if (emulated == EMULATE_FAIL) { 227 if (emulated == EMULATE_FAIL) {