diff options
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-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 |