aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorGuillaume Thouvenin <guillaume.thouvenin@ext.bull.net>2008-10-29 04:39:42 -0400
committerAvi Kivity <avi@redhat.com>2008-12-31 09:51:48 -0500
commit1d5a4d9b92028d9fe77da34037bd5a1ebfecc733 (patch)
tree5e8725c9af5b206f49936a327f116eec858b6bd9 /arch/x86/kvm
parente93f36bcfaa9e899c595e1c446c784a69021854a (diff)
KVM: VMX: Handle mmio emulation when guest state is invalid
If emulate_invalid_guest_state is enabled, the emulator is called when guest state is invalid. Until now, we reported an mmio failure when emulate_instruction() returned EMULATE_DO_MMIO. This patch adds the case where emulate_instruction() failed and an MMIO emulation is needed. Signed-off-by: Guillaume Thouvenin <guillaume.thouvenin@ext.bull.net> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/vmx.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 816d23185fb8..427dbc14fae9 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -3052,16 +3052,12 @@ static void handle_invalid_guest_state(struct kvm_vcpu *vcpu,
3052 while (!guest_state_valid(vcpu)) { 3052 while (!guest_state_valid(vcpu)) {
3053 err = emulate_instruction(vcpu, kvm_run, 0, 0, 0); 3053 err = emulate_instruction(vcpu, kvm_run, 0, 0, 0);
3054 3054
3055 switch (err) { 3055 if (err == EMULATE_DO_MMIO)
3056 case EMULATE_DONE: 3056 break;
3057 break; 3057
3058 case EMULATE_DO_MMIO: 3058 if (err != EMULATE_DONE) {
3059 kvm_report_emulation_failure(vcpu, "mmio"); 3059 kvm_report_emulation_failure(vcpu, "emulation failure");
3060 /* TODO: Handle MMIO */ 3060 return;
3061 return;
3062 default:
3063 kvm_report_emulation_failure(vcpu, "emulation failure");
3064 return;
3065 } 3061 }
3066 3062
3067 if (signal_pending(current)) 3063 if (signal_pending(current))
@@ -3073,8 +3069,10 @@ static void handle_invalid_guest_state(struct kvm_vcpu *vcpu,
3073 local_irq_disable(); 3069 local_irq_disable();
3074 preempt_disable(); 3070 preempt_disable();
3075 3071
3076 /* Guest state should be valid now, no more emulation should be needed */ 3072 /* Guest state should be valid now except if we need to
3077 vmx->emulation_required = 0; 3073 * emulate an MMIO */
3074 if (guest_state_valid(vcpu))
3075 vmx->emulation_required = 0;
3078} 3076}
3079 3077
3080/* 3078/*
@@ -3121,6 +3119,11 @@ static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
3121 KVMTRACE_3D(VMEXIT, vcpu, exit_reason, (u32)kvm_rip_read(vcpu), 3119 KVMTRACE_3D(VMEXIT, vcpu, exit_reason, (u32)kvm_rip_read(vcpu),
3122 (u32)((u64)kvm_rip_read(vcpu) >> 32), entryexit); 3120 (u32)((u64)kvm_rip_read(vcpu) >> 32), entryexit);
3123 3121
3122 /* If we need to emulate an MMIO from handle_invalid_guest_state
3123 * we just return 0 */
3124 if (vmx->emulation_required && emulate_invalid_guest_state)
3125 return 0;
3126
3124 /* Access CR3 don't cause VMExit in paging mode, so we need 3127 /* Access CR3 don't cause VMExit in paging mode, so we need
3125 * to sync with guest real CR3. */ 3128 * to sync with guest real CR3. */
3126 if (vm_need_ept() && is_paging(vcpu)) { 3129 if (vm_need_ept() && is_paging(vcpu)) {