KVM: VMX: report internal error for the unhandleable event
PATCH 1/2 KVM: VMX: report internal error for the unhandleable event
VM exits during Event Delivery is really unexpected if it is not caused by Exceptions/EPT-VIOLATION/TASK_SWITCH, we'd better to report an internal and freeze the guest, the VMM has the chance to check the guest
--- arch/x86/kvm/vmx.c | 19 +++++++++++++++---- include/linux/kvm.h | 8 ++++++-- 2 files changed, 21 insertions(+), 6 deletions(-)
arch/x86/kvm/vmx.c +15 -4
@@ -5979,13 +5979,24 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)return 0 ; } +/* +* Note: +* Do not try to fix EXIT_REASON_EPT_MISCONFIG if it caused by +* delivery event since it indicates guest is accessing MMIO. +* The vm-exit can be triggered again after return to guest that +* will cause infinite loop. +*/ if ((vectoring_info &VECTORING_INFO_VALID_MASK ) && (exit_reason !=EXIT_REASON_EXCEPTION_NMI && exit_reason !=EXIT_REASON_EPT_VIOLATION && - exit_reason !=EXIT_REASON_TASK_SWITCH )) -printk (KERN_WARNING "%s: unexpected, valid vectoring info " -"(0x%x) and exit reason is 0x%x\n" , - __func__, vectoring_info, exit_reason); + exit_reason !=EXIT_REASON_TASK_SWITCH )) { + vcpu->run->exit_reason =KVM_EXIT_INTERNAL_ERROR ; + vcpu->run->internal.suberror =KVM_INTERNAL_ERROR_DELIVERY_EV ; + vcpu->run->internal.ndata =2 ; + vcpu->run->internal.data[0 ] = vectoring_info; + vcpu->run->internal.data[1 ] = exit_reason; +return 0 ; + } if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked && !(is_guest_mode(vcpu) && nested_cpu_has_virtual_nmis(
include/linux/kvm.h +6 -2
@@ -170,8 +170,12 @@ struct kvm_pit_config {#define KVM_EXIT_WATCHDOG 21/* For KVM_EXIT_INTERNAL_ERROR */ -#define KVM_INTERNAL_ERROR_EMULATION 1 -#define KVM_INTERNAL_ERROR_SIMUL_EX 2 +/* Emulate instruction failed. */ +#define KVM_INTERNAL_ERROR_EMULATION 1 +/* Encounter unexpected simultaneous exceptions. */ +#define KVM_INTERNAL_ERROR_SIMUL_EX 2 +/* Encounter unexpected vm-exit due to delivery event. */ +#define KVM_INTERNAL_ERROR_DELIVERY_EV 3/* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */ struct kvm_run {
Signature · 1 line
1.7.7.6
PATCH 2/2 KVM: VMX: report internal error for MMIO #PF due to delivery event
The #PF with PFEC.RSV = 1 indicates that the guest is accessing MMIO, we can not fix it if it is caused by delivery event. Reporting internal error for this case
--- arch/x86/kvm/vmx.c | 26 ++++++++++++++++---------- 1 files changed, 16 insertions(+), 10 deletions(-)
arch/x86/kvm/vmx.c +16 -10
@@ -4287,16 +4287,6 @@ static int handle_exception(struct kvm_vcpu *vcpu)if (is_machine_check (intr_info))return handle_machine_check (vcpu); -if ((vect_info &VECTORING_INFO_VALID_MASK ) && - !is_page_fault (intr_info)) { - vcpu->run->exit_reason =KVM_EXIT_INTERNAL_ERROR ; - vcpu->run->internal.suberror =KVM_INTERNAL_ERROR_SIMUL_EX ; - vcpu->run->internal.ndata =2 ; - vcpu->run->internal.data[0 ] = vect_info; - vcpu->run->internal.data[1 ] = intr_info; -return 0 ; - } -if ((intr_info &INTR_INFO_INTR_TYPE_MASK ) ==INTR_TYPE_NMI_INTR )return 1 ;/* already handled by vmx_vcpu_run() */
@@ -4315,6 +4305,22 @@ static int handle_exception(struct kvm_vcpu *vcpu) error_code =0 ;if (intr_info &INTR_INFO_DELIVER_CODE_MASK ) error_code =vmcs_read32 (VM_EXIT_INTR_ERROR_CODE ); + +/* +* The #PF with PFEC.RSVD = 1 indicates the guest is accessing +* MMIO, it is better to report an internal error. +* See the comments in vmx_handle_exit. +*/ +if ((vect_info &VECTORING_INFO_VALID_MASK ) && + !(is_page_fault (intr_info) && !(error_code &PFERR_RSVD_MASK ))) { + vcpu->run->exit_reason =KVM_EXIT_INTERNAL_ERROR ; + vcpu->run->internal.suberror =KVM_INTERNAL_ERROR_SIMUL_EX ; + vcpu->run->internal.ndata =2 ; + vcpu->run->internal.data[0 ] = vect_info; + vcpu->run->internal.data[1 ] = intr_info; +return 0 ; + } +if (is_page_fault (intr_info)) {/* EPT won't cause page fault directly */ BUG_ON (enable_ept);
Signature · 1 line
1.7.7.6
Avi Kivity
AppliedRe: [PATCH 2/2] KVM: VMX: report internal error for MMIO #PF due to delivery event
Quoted 3 lines · Xiao Guangrong
The #PF with PFEC.RSV = 1 indicates that the guest is accessing MMIO, we can not fix it if it is caused by delivery event. Reporting internal error for this case
Applied, thanks.
Signature · 1 line
error compiling committee.c: too many arguments to function