KVM: VMX: Add invalid guest state handler
authorMohammed Gamal <m.gamal005@gmail.com>
Sun, 17 Aug 2008 13:47:05 +0000 (16:47 +0300)
committerAvi Kivity <avi@qumranet.com>
Wed, 15 Oct 2008 08:15:20 +0000 (10:15 +0200)
This adds the invalid guest state handler function which invokes the x86
emulator until getting the guest to a VMX-friendly state.

[avi: leave atomic context if scheduling]
[guillaume: return to atomic context correctly]

Signed-off-by: Laurent Vivier <laurent.vivier@bull.net>
Signed-off-by: Guillaume Thouvenin <guillaume.thouvenin@ext.bull.net>
Signed-off-by: Mohammed Gamal <m.gamal005@gmail.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
arch/x86/kvm/vmx.c

index 7c5f611..eae1f2c 100644 (file)
@@ -2892,6 +2892,43 @@ static int handle_nmi_window(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
        return 1;
 }
 
+static void handle_invalid_guest_state(struct kvm_vcpu *vcpu,
+                               struct kvm_run *kvm_run)
+{
+       struct vcpu_vmx *vmx = to_vmx(vcpu);
+       int err;
+
+       preempt_enable();
+       local_irq_enable();
+
+       while (!guest_state_valid(vcpu)) {
+               err = emulate_instruction(vcpu, kvm_run, 0, 0, 0);
+
+               switch (err) {
+                       case EMULATE_DONE:
+                               break;
+                       case EMULATE_DO_MMIO:
+                               kvm_report_emulation_failure(vcpu, "mmio");
+                               /* TODO: Handle MMIO */
+                               return;
+                       default:
+                               kvm_report_emulation_failure(vcpu, "emulation failure");
+                               return;
+               }
+
+               if (signal_pending(current))
+                       break;
+               if (need_resched())
+                       schedule();
+       }
+
+       local_irq_disable();
+       preempt_disable();
+
+       /* Guest state should be valid now, no more emulation should be needed */
+       vmx->emulation_required = 0;
+}
+
 /*
  * The exit handlers return 1 if the exit was handled fully and guest execution
  * may resume.  Otherwise they set the kvm_run parameter to indicate what needs