diff options
author | Mohammed Gamal <m.gamal005@gmail.com> | 2008-08-17 09:47:05 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-10-15 04:15:20 -0400 |
commit | ea953ef0ca84e778187905177e2a789a1974837b (patch) | |
tree | 01a4b64c05382f978274b8d3e87a0a5334998073 | |
parent | 04fa4d32117b1a7773290fd59a97cf90cfc2a0d4 (diff) |
KVM: VMX: Add invalid guest state handler
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>
-rw-r--r-- | arch/x86/kvm/vmx.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 7c5f611e1a94..eae1f2c64f97 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -2892,6 +2892,43 @@ static int handle_nmi_window(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
2892 | return 1; | 2892 | return 1; |
2893 | } | 2893 | } |
2894 | 2894 | ||
2895 | static void handle_invalid_guest_state(struct kvm_vcpu *vcpu, | ||
2896 | struct kvm_run *kvm_run) | ||
2897 | { | ||
2898 | struct vcpu_vmx *vmx = to_vmx(vcpu); | ||
2899 | int err; | ||
2900 | |||
2901 | preempt_enable(); | ||
2902 | local_irq_enable(); | ||
2903 | |||
2904 | while (!guest_state_valid(vcpu)) { | ||
2905 | err = emulate_instruction(vcpu, kvm_run, 0, 0, 0); | ||
2906 | |||
2907 | switch (err) { | ||
2908 | case EMULATE_DONE: | ||
2909 | break; | ||
2910 | case EMULATE_DO_MMIO: | ||
2911 | kvm_report_emulation_failure(vcpu, "mmio"); | ||
2912 | /* TODO: Handle MMIO */ | ||
2913 | return; | ||
2914 | default: | ||
2915 | kvm_report_emulation_failure(vcpu, "emulation failure"); | ||
2916 | return; | ||
2917 | } | ||
2918 | |||
2919 | if (signal_pending(current)) | ||
2920 | break; | ||
2921 | if (need_resched()) | ||
2922 | schedule(); | ||
2923 | } | ||
2924 | |||
2925 | local_irq_disable(); | ||
2926 | preempt_disable(); | ||
2927 | |||
2928 | /* Guest state should be valid now, no more emulation should be needed */ | ||
2929 | vmx->emulation_required = 0; | ||
2930 | } | ||
2931 | |||
2895 | /* | 2932 | /* |
2896 | * The exit handlers return 1 if the exit was handled fully and guest execution | 2933 | * The exit handlers return 1 if the exit was handled fully and guest execution |
2897 | * may resume. Otherwise they set the kvm_run parameter to indicate what needs | 2934 | * may resume. Otherwise they set the kvm_run parameter to indicate what needs |