]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
KVM: PPC: BOOK3S: PR: Fix PURR and SPURR emulation
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Wed, 4 Jun 2014 11:17:55 +0000 (16:47 +0530)
committerAlexander Graf <agraf@suse.de>
Sun, 6 Jul 2014 11:56:49 +0000 (13:56 +0200)
We use time base for PURR and SPURR emulation with PR KVM since we
are emulating a single threaded core. When using time base
we need to make sure that we don't accumulate time spent in the host
in PURR and SPURR value.

Also we don't need to emulate mtspr because both the registers are
hypervisor resource.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
arch/powerpc/include/asm/kvm_book3s.h
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/kvm/book3s_emulate.c
arch/powerpc/kvm/book3s_pr.c

index f52f65694527ea7b42ceb1df485039fc9abba623..a20cc0bbd04875a35fbe15bf8f68cd66330314dc 100644 (file)
@@ -83,8 +83,6 @@ struct kvmppc_vcpu_book3s {
        u64 sdr1;
        u64 hior;
        u64 msr_mask;
-       u64 purr_offset;
-       u64 spurr_offset;
 #ifdef CONFIG_PPC_BOOK3S_32
        u32 vsid_pool[VSID_POOL_SIZE];
        u32 vsid_next;
index bb66d8b8efdf073fb2a54c39b9d1dd984be713cd..4a58731a0a726e76b027d9a3c7d7b58de8085bd6 100644 (file)
@@ -503,8 +503,8 @@ struct kvm_vcpu_arch {
 #ifdef CONFIG_BOOKE
        u32 decar;
 #endif
-       u32 tbl;
-       u32 tbu;
+       /* Time base value when we entered the guest */
+       u64 entry_tb;
        u32 tcr;
        ulong tsr; /* we need to perform set/clr_bits() which requires ulong */
        u32 ivor[64];
index 3f295269af37e7625869d677241c3f12cf6e0d22..3565e775b61b787c4533edd27b4d933226ea9394 100644 (file)
@@ -439,12 +439,6 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
                    (mfmsr() & MSR_HV))
                        vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32;
                break;
-       case SPRN_PURR:
-               to_book3s(vcpu)->purr_offset = spr_val - get_tb();
-               break;
-       case SPRN_SPURR:
-               to_book3s(vcpu)->spurr_offset = spr_val - get_tb();
-               break;
        case SPRN_GQR0:
        case SPRN_GQR1:
        case SPRN_GQR2:
@@ -572,10 +566,16 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val
                *spr_val = 0;
                break;
        case SPRN_PURR:
-               *spr_val = get_tb() + to_book3s(vcpu)->purr_offset;
+               /*
+                * On exit we would have updated purr
+                */
+               *spr_val = vcpu->arch.purr;
                break;
        case SPRN_SPURR:
-               *spr_val = get_tb() + to_book3s(vcpu)->purr_offset;
+               /*
+                * On exit we would have updated spurr
+                */
+               *spr_val = vcpu->arch.spurr;
                break;
        case SPRN_GQR0:
        case SPRN_GQR1:
index 8eef1e5190773c9c290bf46581e7fd025f7dfaeb..671f5c92a54d79aae87d9cd9f6d76be4c60ba300 100644 (file)
@@ -120,6 +120,11 @@ void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu,
 #ifdef CONFIG_PPC_BOOK3S_64
        svcpu->shadow_fscr = vcpu->arch.shadow_fscr;
 #endif
+       /*
+        * Now also save the current time base value. We use this
+        * to find the guest purr and spurr value.
+        */
+       vcpu->arch.entry_tb = get_tb();
        svcpu->in_use = true;
 }
 
@@ -166,6 +171,12 @@ void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu,
 #ifdef CONFIG_PPC_BOOK3S_64
        vcpu->arch.shadow_fscr = svcpu->shadow_fscr;
 #endif
+       /*
+        * Update purr and spurr using time base on exit.
+        */
+       vcpu->arch.purr += get_tb() - vcpu->arch.entry_tb;
+       vcpu->arch.spurr += get_tb() - vcpu->arch.entry_tb;
+
        svcpu->in_use = false;
 
 out: