mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-02 19:36:42 +07:00
KVM: VMX: Avoid vmx_recover_nmi_blocking() when unneeded
When we haven't injected an interrupt, we don't need to recover the nmi blocking state (since the guest can't set it by itself). This allows us to avoid a VMREAD later on. Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
parent
69c7302890
commit
9d58b93192
@ -129,6 +129,7 @@ struct vcpu_vmx {
|
||||
int launched;
|
||||
u8 fail;
|
||||
u8 cpl;
|
||||
bool nmi_known_unmasked;
|
||||
u32 exit_intr_info;
|
||||
u32 idt_vectoring_info;
|
||||
ulong rflags;
|
||||
@ -2959,6 +2960,7 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
|
||||
}
|
||||
|
||||
++vcpu->stat.nmi_injections;
|
||||
vmx->nmi_known_unmasked = false;
|
||||
if (vmx->rmode.vm86_active) {
|
||||
if (kvm_inject_realmode_interrupt(vcpu, NMI_VECTOR) != EMULATE_DONE)
|
||||
kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
|
||||
@ -2983,6 +2985,8 @@ static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (!cpu_has_virtual_nmis())
|
||||
return to_vmx(vcpu)->soft_vnmi_blocked;
|
||||
if (to_vmx(vcpu)->nmi_known_unmasked)
|
||||
return false;
|
||||
return vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & GUEST_INTR_STATE_NMI;
|
||||
}
|
||||
|
||||
@ -2996,6 +3000,7 @@ static void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked)
|
||||
vmx->vnmi_blocked_time = 0;
|
||||
}
|
||||
} else {
|
||||
vmx->nmi_known_unmasked = !masked;
|
||||
if (masked)
|
||||
vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
|
||||
GUEST_INTR_STATE_NMI);
|
||||
@ -3527,9 +3532,11 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
|
||||
switch (type) {
|
||||
case INTR_TYPE_NMI_INTR:
|
||||
vcpu->arch.nmi_injected = false;
|
||||
if (cpu_has_virtual_nmis())
|
||||
if (cpu_has_virtual_nmis()) {
|
||||
vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
|
||||
GUEST_INTR_STATE_NMI);
|
||||
vmx->nmi_known_unmasked = false;
|
||||
}
|
||||
break;
|
||||
case INTR_TYPE_EXT_INTR:
|
||||
case INTR_TYPE_SOFT_INTR:
|
||||
@ -3916,6 +3923,8 @@ static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx)
|
||||
idtv_info_valid = vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK;
|
||||
|
||||
if (cpu_has_virtual_nmis()) {
|
||||
if (vmx->nmi_known_unmasked)
|
||||
return;
|
||||
unblock_nmi = (exit_intr_info & INTR_INFO_UNBLOCK_NMI) != 0;
|
||||
vector = exit_intr_info & INTR_INFO_VECTOR_MASK;
|
||||
/*
|
||||
@ -3932,6 +3941,10 @@ static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx)
|
||||
vector != DF_VECTOR && !idtv_info_valid)
|
||||
vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
|
||||
GUEST_INTR_STATE_NMI);
|
||||
else
|
||||
vmx->nmi_known_unmasked =
|
||||
!(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO)
|
||||
& GUEST_INTR_STATE_NMI);
|
||||
} else if (unlikely(vmx->soft_vnmi_blocked))
|
||||
vmx->vnmi_blocked_time +=
|
||||
ktime_to_ns(ktime_sub(ktime_get(), vmx->entry_time));
|
||||
@ -3970,6 +3983,7 @@ static void __vmx_complete_interrupts(struct vcpu_vmx *vmx,
|
||||
*/
|
||||
vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
|
||||
GUEST_INTR_STATE_NMI);
|
||||
vmx->nmi_known_unmasked = true;
|
||||
break;
|
||||
case INTR_TYPE_SOFT_EXCEPTION:
|
||||
vmx->vcpu.arch.event_exit_inst_len =
|
||||
|
Loading…
Reference in New Issue
Block a user