aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/vmx.c
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@siemens.com>2008-09-26 03:30:50 -0400
committerAvi Kivity <avi@redhat.com>2008-12-31 09:51:41 -0500
commitf460ee43e250b675376246b1c4c9fe9b9af4ab16 (patch)
tree1d34055070abe9894f0290d5f3dc51566cb98719 /arch/x86/kvm/vmx.c
parent33f089ca5a61f7aead26e8e1866dfc961dd88a9e (diff)
KVM: VMX: refactor IRQ and NMI window enabling
do_interrupt_requests and vmx_intr_assist go different way for achieving the same: enabling the nmi/irq window start notification. Unify their code over enable_{irq|nmi}_window, get rid of a redundant call to enable_intr_window instead of direct enable_nmi_window invocation and unroll enable_intr_window for both in-kernel and user space irq injection accordingly. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r--arch/x86/kvm/vmx.c78
1 files changed, 32 insertions, 46 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index f0866e1d20ee..440f56cd4bdd 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2389,30 +2389,42 @@ static void kvm_do_inject_irq(struct kvm_vcpu *vcpu)
2389 kvm_queue_interrupt(vcpu, irq); 2389 kvm_queue_interrupt(vcpu, irq);
2390} 2390}
2391 2391
2392static void do_interrupt_requests(struct kvm_vcpu *vcpu, 2392static void enable_irq_window(struct kvm_vcpu *vcpu)
2393 struct kvm_run *kvm_run)
2394{ 2393{
2395 u32 cpu_based_vm_exec_control; 2394 u32 cpu_based_vm_exec_control;
2396 2395
2397 vmx_update_window_states(vcpu); 2396 cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
2397 cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
2398 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
2399}
2398 2400
2399 if (vcpu->arch.interrupt_window_open && 2401static void enable_nmi_window(struct kvm_vcpu *vcpu)
2400 vcpu->arch.irq_summary && !vcpu->arch.interrupt.pending) 2402{
2401 kvm_do_inject_irq(vcpu); 2403 u32 cpu_based_vm_exec_control;
2402 2404
2403 if (vcpu->arch.interrupt_window_open && vcpu->arch.interrupt.pending) 2405 if (!cpu_has_virtual_nmis())
2404 vmx_inject_irq(vcpu, vcpu->arch.interrupt.nr); 2406 return;
2405 2407
2406 cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); 2408 cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
2409 cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_NMI_PENDING;
2410 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
2411}
2412
2413static void do_interrupt_requests(struct kvm_vcpu *vcpu,
2414 struct kvm_run *kvm_run)
2415{
2416 vmx_update_window_states(vcpu);
2417
2418 if (vcpu->arch.interrupt_window_open) {
2419 if (vcpu->arch.irq_summary && !vcpu->arch.interrupt.pending)
2420 kvm_do_inject_irq(vcpu);
2421
2422 if (vcpu->arch.interrupt.pending)
2423 vmx_inject_irq(vcpu, vcpu->arch.interrupt.nr);
2424 }
2407 if (!vcpu->arch.interrupt_window_open && 2425 if (!vcpu->arch.interrupt_window_open &&
2408 (vcpu->arch.irq_summary || kvm_run->request_interrupt_window)) 2426 (vcpu->arch.irq_summary || kvm_run->request_interrupt_window))
2409 /* 2427 enable_irq_window(vcpu);
2410 * Interrupts blocked. Wait for unblock.
2411 */
2412 cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
2413 else
2414 cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
2415 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
2416} 2428}
2417 2429
2418static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr) 2430static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr)
@@ -3066,35 +3078,6 @@ static void update_tpr_threshold(struct kvm_vcpu *vcpu)
3066 vmcs_write32(TPR_THRESHOLD, (max_irr > tpr) ? tpr >> 4 : max_irr >> 4); 3078 vmcs_write32(TPR_THRESHOLD, (max_irr > tpr) ? tpr >> 4 : max_irr >> 4);
3067} 3079}
3068 3080
3069static void enable_irq_window(struct kvm_vcpu *vcpu)
3070{
3071 u32 cpu_based_vm_exec_control;
3072
3073 cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
3074 cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
3075 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
3076}
3077
3078static void enable_nmi_window(struct kvm_vcpu *vcpu)
3079{
3080 u32 cpu_based_vm_exec_control;
3081
3082 if (!cpu_has_virtual_nmis())
3083 return;
3084
3085 cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
3086 cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_NMI_PENDING;
3087 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
3088}
3089
3090static void enable_intr_window(struct kvm_vcpu *vcpu)
3091{
3092 if (vcpu->arch.nmi_pending)
3093 enable_nmi_window(vcpu);
3094 else if (kvm_cpu_has_interrupt(vcpu))
3095 enable_irq_window(vcpu);
3096}
3097
3098static void vmx_complete_interrupts(struct vcpu_vmx *vmx) 3081static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
3099{ 3082{
3100 u32 exit_intr_info; 3083 u32 exit_intr_info;
@@ -3165,13 +3148,16 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu)
3165 vcpu->arch.nmi_pending = false; 3148 vcpu->arch.nmi_pending = false;
3166 vcpu->arch.nmi_injected = true; 3149 vcpu->arch.nmi_injected = true;
3167 } else { 3150 } else {
3168 enable_intr_window(vcpu); 3151 enable_nmi_window(vcpu);
3169 return; 3152 return;
3170 } 3153 }
3171 } 3154 }
3172 if (vcpu->arch.nmi_injected) { 3155 if (vcpu->arch.nmi_injected) {
3173 vmx_inject_nmi(vcpu); 3156 vmx_inject_nmi(vcpu);
3174 enable_intr_window(vcpu); 3157 if (vcpu->arch.nmi_pending)
3158 enable_nmi_window(vcpu);
3159 else if (kvm_cpu_has_interrupt(vcpu))
3160 enable_irq_window(vcpu);
3175 return; 3161 return;
3176 } 3162 }
3177 } 3163 }