diff options
author | Jan Kiszka <jan.kiszka@siemens.com> | 2008-09-26 03:30:50 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2008-12-31 09:51:41 -0500 |
commit | f460ee43e250b675376246b1c4c9fe9b9af4ab16 (patch) | |
tree | 1d34055070abe9894f0290d5f3dc51566cb98719 /arch | |
parent | 33f089ca5a61f7aead26e8e1866dfc961dd88a9e (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')
-rw-r--r-- | arch/x86/kvm/vmx.c | 78 |
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 | ||
2392 | static void do_interrupt_requests(struct kvm_vcpu *vcpu, | 2392 | static 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 && | 2401 | static 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 | |||
2413 | static 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 | ||
2418 | static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr) | 2430 | static 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 | ||
3069 | static 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 | |||
3078 | static 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 | |||
3090 | static 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 | |||
3098 | static void vmx_complete_interrupts(struct vcpu_vmx *vmx) | 3081 | static 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 | } |