] VMX: Enhance invalid guest state emulation
PATCH v2 1/1 ] VMX: Enhance invalid guest state emulation
- Change returned handle_invalid_guest_state() to return relevant exit codes
- Move triggering the emulation from vmx_vcpu_run() to vmx_handle_exit()
- Return to userspace instead of repeatedly trying to emulate instructions that have already failed
Signed-off-by Mohammed Gamal <[email protected]>
--- arch/x86/kvm/vmx.c | 31 +++++++++++++++---------------- 1 files changed, 15 insertions(+), 16 deletions(-)
arch/x86/kvm/vmx.c +15 -16
@@ -107,7 +107,6 @@ struct vcpu_vmx { } rmode;int vpid;bool emulation_required; -enum emulation_result invalid_state_emulation_result;/* Support for vnmi-less CPUs */ int soft_vnmi_blocked;
@@ -3318,22 +3317,24 @@ static int handle_nmi_window(struct kvm_vcpu *vcpu)return 1 ; } -static void handle_invalid_guest_state (struct kvm_vcpu *vcpu) +static int handle_invalid_guest_state (struct kvm_vcpu *vcpu) { -struct vcpu_vmx *vmx =to_vmx (vcpu);enum emulation_result err =EMULATE_DONE ; - -local_irq_enable (); -preempt_enable (); +int ret =1 ;while (!guest_state_valid (vcpu)) { err =emulate_instruction (vcpu,0 ,0 ,0 ); -if (err ==EMULATE_DO_MMIO ) +if (err ==EMULATE_DO_MMIO ) { + ret =0 ;break ; + }if (err !=EMULATE_DONE ) {kvm_report_emulation_failure (vcpu,"emulation failure" ); + vcpu->run->exit_reason =KVM_EXIT_INTERNAL_ERROR ; + vcpu->run->internal.suberror =KVM_INTERNAL_ERROR_EMULATION ; + ret =0 ;break ; }
@@ -3343,10 +3344,7 @@ static void handle_invalid_guest_state(struct kvm_vcpu *vcpu)schedule (); } -preempt_disable (); -local_irq_disable (); - - vmx->invalid_state_emulation_result = err; +return ret; }/*
@@ -3405,9 +3403,12 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)/* If we need to emulate an MMIO from handle_invalid_guest_state * we just return 0 */ if (vmx->emulation_required && emulate_invalid_guest_state) { -if (guest_state_valid (vcpu)) +if (!guest_state_valid (vcpu)) { +return handle_invalid_guest_state (vcpu); + }else { vmx->emulation_required =0 ; -return vmx->invalid_state_emulation_result !=EMULATE_DO_MMIO ; +return 1 ; + } }/* Access CR3 don't cause VMExit in paging mode, so we need
@@ -3604,10 +3605,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu) vmx->entry_time =ktime_get ();/* Handle invalid guest state instead of entering VMX */ -if (vmx->emulation_required && emulate_invalid_guest_state) { -handle_invalid_guest_state (vcpu); +if (vmx->emulation_required && emulate_invalid_guest_state)return ; - }if (test_bit (VCPU_REGS_RSP , (unsigned long *)&vcpu->arch.regs_dirty))vmcs_writel (GUEST_RSP , vcpu->arch.regs[VCPU_REGS_RSP ]);
Signature · 1 line
1.6.0.4