KVM: PPC: Book3S PR: Emulate PURR, SPURR and DSCR registers
authorPaul Mackerras <paulus@samba.org>
Sun, 4 Nov 2012 18:15:43 +0000 (18:15 +0000)
committerAlexander Graf <agraf@suse.de>
Thu, 6 Dec 2012 00:34:01 +0000 (01:34 +0100)
This adds basic emulation of the PURR and SPURR registers.  We assume
we are emulating a single-threaded core, so these advance at the same
rate as the timebase.  A Linux kernel running on a POWER7 expects to
be able to access these registers and is not prepared to handle a
program interrupt on accessing them.

This also adds a very minimal emulation of the DSCR (data stream
control register).  Writes are ignored and reads return zero.

Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
arch/powerpc/include/asm/kvm_book3s.h
arch/powerpc/kvm/book3s_emulate.c

index 46763d1..5a56e1c 100644 (file)
@@ -81,6 +81,8 @@ 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 b9a989d..d31a716 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/kvm_book3s.h>
 #include <asm/reg.h>
 #include <asm/switch_to.h>
+#include <asm/time.h>
 
 #define OP_19_XOP_RFID         18
 #define OP_19_XOP_RFI          50
@@ -395,6 +396,12 @@ int kvmppc_core_emulate_mtspr(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:
@@ -412,6 +419,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
        case SPRN_CTRLF:
        case SPRN_CTRLT:
        case SPRN_L2CR:
+       case SPRN_DSCR:
        case SPRN_MMCR0_GEKKO:
        case SPRN_MMCR1_GEKKO:
        case SPRN_PMC1_GEKKO:
@@ -483,9 +491,15 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
                *spr_val = to_book3s(vcpu)->hid[5];
                break;
        case SPRN_CFAR:
-       case SPRN_PURR:
+       case SPRN_DSCR:
                *spr_val = 0;
                break;
+       case SPRN_PURR:
+               *spr_val = get_tb() + to_book3s(vcpu)->purr_offset;
+               break;
+       case SPRN_SPURR:
+               *spr_val = get_tb() + to_book3s(vcpu)->purr_offset;
+               break;
        case SPRN_GQR0:
        case SPRN_GQR1:
        case SPRN_GQR2: