KVM: PPC: BookE: Add EPR ONE_REG sync
authorAlexander Graf <agraf@suse.de>
Fri, 4 Jan 2013 17:28:51 +0000 (18:28 +0100)
committerAlexander Graf <agraf@suse.de>
Thu, 10 Jan 2013 12:42:33 +0000 (13:42 +0100)
We need to be able to read and write the contents of the EPR register
from user space.

This patch implements that logic through the ONE_REG API and declares
its (never implemented) SREGS counterpart as deprecated.

Signed-off-by: Alexander Graf <agraf@suse.de>
Documentation/virtual/kvm/api.txt
arch/powerpc/include/uapi/asm/kvm.h
arch/powerpc/kvm/booke.c

index a98ed09269d7eaccd971ab2ee291e4f3f0794015..09905cbcbb0bdbe8878a36f0008c7fd0a46724d6 100644 (file)
@@ -1774,6 +1774,7 @@ registers, find a list below:
   PPC   | KVM_REG_PPC_VPA_SLB   | 128
   PPC   | KVM_REG_PPC_VPA_DTL   | 128
   PPC   | KVM_REG_PPC_EPCR     | 32
+  PPC   | KVM_REG_PPC_EPR      | 32
 
 4.69 KVM_GET_ONE_REG
 
index 2fba8a66fb10f8a609d2e95e3b97174bbd70a6a6..16064d00adb900057039423fc548772eec5c938c 100644 (file)
@@ -114,7 +114,10 @@ struct kvm_regs {
 /* Embedded Floating Point (SPE) -- IVOR32-34 if KVM_SREGS_E_IVOR */
 #define KVM_SREGS_E_SPE                        (1 << 9)
 
-/* External Proxy (EXP) -- EPR */
+/*
+ * DEPRECATED! USE ONE_REG FOR THIS ONE!
+ * External Proxy (EXP) -- EPR
+ */
 #define KVM_SREGS_EXP                  (1 << 10)
 
 /* External PID (E.PD) -- EPSC/EPLC */
@@ -412,5 +415,6 @@ struct kvm_get_htab_header {
 #define KVM_REG_PPC_VPA_DTL    (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x84)
 
 #define KVM_REG_PPC_EPCR       (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x85)
+#define KVM_REG_PPC_EPR                (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x86)
 
 #endif /* __LINUX_KVM_POWERPC_H */
index 940ec806187edffc60de243d3241f957b9f84601..8779cd4c52d9c67e69916304a5319c1b2b39d00c 100644 (file)
@@ -300,6 +300,15 @@ static void set_guest_esr(struct kvm_vcpu *vcpu, u32 esr)
 #endif
 }
 
+static unsigned long get_guest_epr(struct kvm_vcpu *vcpu)
+{
+#ifdef CONFIG_KVM_BOOKE_HV
+       return mfspr(SPRN_GEPR);
+#else
+       return vcpu->arch.epr;
+#endif
+}
+
 /* Deliver the interrupt of the corresponding priority, if possible. */
 static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
                                         unsigned int priority)
@@ -1405,6 +1414,11 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
                                 &vcpu->arch.dbg_reg.dac[dac], sizeof(u64));
                break;
        }
+       case KVM_REG_PPC_EPR: {
+               u32 epr = get_guest_epr(vcpu);
+               r = put_user(epr, (u32 __user *)(long)reg->addr);
+               break;
+       }
 #if defined(CONFIG_64BIT)
        case KVM_REG_PPC_EPCR:
                r = put_user(vcpu->arch.epcr, (u32 __user *)(long)reg->addr);
@@ -1437,6 +1451,13 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
                             (u64 __user *)(long)reg->addr, sizeof(u64));
                break;
        }
+       case KVM_REG_PPC_EPR: {
+               u32 new_epr;
+               r = get_user(new_epr, (u32 __user *)(long)reg->addr);
+               if (!r)
+                       kvmppc_set_epr(vcpu, new_epr);
+               break;
+       }
 #if defined(CONFIG_64BIT)
        case KVM_REG_PPC_EPCR: {
                u32 new_epcr;