kvm: vmx: Allow disabling virtual NMI support

To simplify testing of these rarely used code paths, add a module parameter
that turns it on. One eventinj.flat test (NMI after iret) fails when
loading kvm_intel with vnmi=0.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>

+21 -10
+21 -10
arch/x86/kvm/vmx.c
··· 70 70 static bool __read_mostly enable_vpid = 1; 71 71 module_param_named(vpid, enable_vpid, bool, 0444); 72 72 73 + static bool __read_mostly enable_vnmi = 1; 74 + module_param_named(vnmi, enable_vnmi, bool, S_IRUGO); 75 + 73 76 static bool __read_mostly flexpriority_enabled = 1; 74 77 module_param_named(flexpriority, flexpriority_enabled, bool, S_IRUGO); 75 78 ··· 5239 5236 5240 5237 if (!kvm_vcpu_apicv_active(&vmx->vcpu)) 5241 5238 pin_based_exec_ctrl &= ~PIN_BASED_POSTED_INTR; 5239 + 5240 + if (!enable_vnmi) 5241 + pin_based_exec_ctrl &= ~PIN_BASED_VIRTUAL_NMIS; 5242 + 5242 5243 /* Enable the preemption timer dynamically */ 5243 5244 pin_based_exec_ctrl &= ~PIN_BASED_VMX_PREEMPTION_TIMER; 5244 5245 return pin_based_exec_ctrl; ··· 5677 5670 5678 5671 static void enable_nmi_window(struct kvm_vcpu *vcpu) 5679 5672 { 5680 - if (!cpu_has_virtual_nmis() || 5673 + if (!enable_vnmi || 5681 5674 vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & GUEST_INTR_STATE_STI) { 5682 5675 enable_irq_window(vcpu); 5683 5676 return; ··· 5718 5711 { 5719 5712 struct vcpu_vmx *vmx = to_vmx(vcpu); 5720 5713 5721 - if (!cpu_has_virtual_nmis()) { 5714 + if (!enable_vnmi) { 5722 5715 /* 5723 5716 * Tracking the NMI-blocked state in software is built upon 5724 5717 * finding the next open IRQ window. This, in turn, depends on ··· 5749 5742 struct vcpu_vmx *vmx = to_vmx(vcpu); 5750 5743 bool masked; 5751 5744 5752 - if (!cpu_has_virtual_nmis()) 5745 + if (!enable_vnmi) 5753 5746 return vmx->loaded_vmcs->soft_vnmi_blocked; 5754 5747 if (vmx->loaded_vmcs->nmi_known_unmasked) 5755 5748 return false; ··· 5762 5755 { 5763 5756 struct vcpu_vmx *vmx = to_vmx(vcpu); 5764 5757 5765 - if (!cpu_has_virtual_nmis()) { 5758 + if (!enable_vnmi) { 5766 5759 if (vmx->loaded_vmcs->soft_vnmi_blocked != masked) { 5767 5760 vmx->loaded_vmcs->soft_vnmi_blocked = masked; 5768 5761 vmx->loaded_vmcs->vnmi_blocked_time = 0; ··· 5783 5776 if (to_vmx(vcpu)->nested.nested_run_pending) 5784 5777 return 0; 5785 5778 5786 - if (!cpu_has_virtual_nmis() && 5779 + if (!enable_vnmi && 5787 5780 to_vmx(vcpu)->loaded_vmcs->soft_vnmi_blocked) 5788 5781 return 0; 5789 5782 ··· 6514 6507 * AAK134, BY25. 6515 6508 */ 6516 6509 if (!(to_vmx(vcpu)->idt_vectoring_info & VECTORING_INFO_VALID_MASK) && 6517 - cpu_has_virtual_nmis() && 6510 + enable_vnmi && 6518 6511 (exit_qualification & INTR_INFO_UNBLOCK_NMI)) 6519 6512 vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO, GUEST_INTR_STATE_NMI); 6520 6513 ··· 6574 6567 6575 6568 static int handle_nmi_window(struct kvm_vcpu *vcpu) 6576 6569 { 6570 + WARN_ON_ONCE(!enable_vnmi); 6577 6571 vmcs_clear_bits(CPU_BASED_VM_EXEC_CONTROL, 6578 6572 CPU_BASED_VIRTUAL_NMI_PENDING); 6579 6573 ++vcpu->stat.nmi_window_exits; ··· 6797 6789 6798 6790 if (!cpu_has_vmx_flexpriority()) 6799 6791 flexpriority_enabled = 0; 6792 + 6793 + if (!cpu_has_virtual_nmis()) 6794 + enable_vnmi = 0; 6800 6795 6801 6796 /* 6802 6797 * set_apic_access_page_addr() is used to reload apic access ··· 8022 8011 * "blocked by NMI" bit has to be set before next VM entry. 8023 8012 */ 8024 8013 if (!(to_vmx(vcpu)->idt_vectoring_info & VECTORING_INFO_VALID_MASK) && 8025 - cpu_has_virtual_nmis() && 8014 + enable_vnmi && 8026 8015 (exit_qualification & INTR_INFO_UNBLOCK_NMI)) 8027 8016 vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO, 8028 8017 GUEST_INTR_STATE_NMI); ··· 8867 8856 return 0; 8868 8857 } 8869 8858 8870 - if (unlikely(!cpu_has_virtual_nmis() && 8859 + if (unlikely(!enable_vnmi && 8871 8860 vmx->loaded_vmcs->soft_vnmi_blocked)) { 8872 8861 if (vmx_interrupt_allowed(vcpu)) { 8873 8862 vmx->loaded_vmcs->soft_vnmi_blocked = 0; ··· 9168 9157 9169 9158 idtv_info_valid = vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK; 9170 9159 9171 - if (cpu_has_virtual_nmis()) { 9160 + if (enable_vnmi) { 9172 9161 if (vmx->loaded_vmcs->nmi_known_unmasked) 9173 9162 return; 9174 9163 /* ··· 9317 9306 unsigned long debugctlmsr, cr3, cr4; 9318 9307 9319 9308 /* Record the guest's net vcpu time for enforced NMI injections. */ 9320 - if (unlikely(!cpu_has_virtual_nmis() && 9309 + if (unlikely(!enable_vnmi && 9321 9310 vmx->loaded_vmcs->soft_vnmi_blocked)) 9322 9311 vmx->loaded_vmcs->entry_time = ktime_get(); 9323 9312