]> Pileus Git - ~andy/linux/blobdiff - arch/powerpc/kvm/e500_emulate.c
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[~andy/linux] / arch / powerpc / kvm / e500_emulate.c
index b10a01243abdeb788a7d3513b25a266cfc09d35c..89b7f821f6c41d84acfd997215b907047b0cd0a1 100644 (file)
@@ -26,6 +26,7 @@
 #define XOP_TLBRE   946
 #define XOP_TLBWE   978
 #define XOP_TLBILX  18
+#define XOP_EHPRIV  270
 
 #ifdef CONFIG_KVM_E500MC
 static int dbell2prio(ulong param)
@@ -82,8 +83,28 @@ static int kvmppc_e500_emul_msgsnd(struct kvm_vcpu *vcpu, int rb)
 }
 #endif
 
-int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
-                           unsigned int inst, int *advance)
+static int kvmppc_e500_emul_ehpriv(struct kvm_run *run, struct kvm_vcpu *vcpu,
+                                  unsigned int inst, int *advance)
+{
+       int emulated = EMULATE_DONE;
+
+       switch (get_oc(inst)) {
+       case EHPRIV_OC_DEBUG:
+               run->exit_reason = KVM_EXIT_DEBUG;
+               run->debug.arch.address = vcpu->arch.pc;
+               run->debug.arch.status = 0;
+               kvmppc_account_exit(vcpu, DEBUG_EXITS);
+               emulated = EMULATE_EXIT_USER;
+               *advance = 0;
+               break;
+       default:
+               emulated = EMULATE_FAIL;
+       }
+       return emulated;
+}
+
+int kvmppc_core_emulate_op_e500(struct kvm_run *run, struct kvm_vcpu *vcpu,
+                               unsigned int inst, int *advance)
 {
        int emulated = EMULATE_DONE;
        int ra = get_ra(inst);
@@ -130,6 +151,11 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
                        emulated = kvmppc_e500_emul_tlbivax(vcpu, ea);
                        break;
 
+               case XOP_EHPRIV:
+                       emulated = kvmppc_e500_emul_ehpriv(run, vcpu, inst,
+                                                          advance);
+                       break;
+
                default:
                        emulated = EMULATE_FAIL;
                }
@@ -146,7 +172,7 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
        return emulated;
 }
 
-int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
+int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
 {
        struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
        int emulated = EMULATE_DONE;
@@ -237,7 +263,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
        return emulated;
 }
 
-int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
+int kvmppc_core_emulate_mfspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
 {
        struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
        int emulated = EMULATE_DONE;