KVM: PPC: Add AGAIN type for emulation return
authorAlexander Graf <agraf@suse.de>
Fri, 19 Feb 2010 10:00:31 +0000 (11:00 +0100)
committerAvi Kivity <avi@redhat.com>
Sun, 25 Apr 2010 09:34:47 +0000 (12:34 +0300)
Emulation of an instruction can have different outcomes. It can succeed,
fail, require MMIO, do funky BookE stuff - or it can just realize something's
odd and will be fixed the next time around.

Exactly that is what EMULATE_AGAIN means. Using that flag we can now tell
the caller that nothing happened, but we still want to go back to the
guest and see what happens next time we come around.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Avi Kivity <avi@redhat.com>
arch/powerpc/include/asm/kvm_ppc.h
arch/powerpc/kvm/book3s.c
arch/powerpc/kvm/emulate.c

index a288dd2fbb2cd009ffe94561a0bf6fcc7961c0b4..07612189eb8b8e2f369b997062ed779fb8e849ce 100644 (file)
@@ -37,6 +37,7 @@ enum emulation_result {
        EMULATE_DO_MMIO,      /* kvm_run filled with MMIO request */
        EMULATE_DO_DCR,       /* kvm_run filled with DCR request */
        EMULATE_FAIL,         /* can't emulate this instruction */
+       EMULATE_AGAIN,        /* something went wrong. go again */
 };
 
 extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
index 604af29b71ed28ac8d641ab977496a2638cdeb19..6416f227d34567c8737c39d37c3cfa201c0e1ace 100644 (file)
@@ -789,6 +789,9 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
                case EMULATE_DONE:
                        r = RESUME_GUEST_NV;
                        break;
+               case EMULATE_AGAIN:
+                       r = RESUME_GUEST;
+                       break;
                case EMULATE_FAIL:
                        printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n",
                               __func__, vcpu->arch.pc, vcpu->arch.last_inst);
index 11789dd33a132d5defc7cb3f2fc0459f3544ea02..2410ec2a756acfe09e7599ca2628ee5ef75d4ff9 100644 (file)
@@ -486,7 +486,9 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
 
        if (emulated == EMULATE_FAIL) {
                emulated = kvmppc_core_emulate_op(run, vcpu, inst, &advance);
-               if (emulated == EMULATE_FAIL) {
+               if (emulated == EMULATE_AGAIN) {
+                       advance = 0;
+               } else if (emulated == EMULATE_FAIL) {
                        advance = 0;
                        printk(KERN_ERR "Couldn't emulate instruction 0x%08x "
                               "(op %d xop %d)\n", inst, get_op(inst), get_xop(inst));