diff options
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r-- | arch/x86/kvm/x86.c | 73 |
1 files changed, 40 insertions, 33 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 00462bd63129..7ffc224bbe41 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -2763,6 +2763,26 @@ static int kvm_vcpu_ioctl_set_lapic(struct kvm_vcpu *vcpu, | |||
2763 | return 0; | 2763 | return 0; |
2764 | } | 2764 | } |
2765 | 2765 | ||
2766 | static int kvm_cpu_accept_dm_intr(struct kvm_vcpu *vcpu) | ||
2767 | { | ||
2768 | return (!lapic_in_kernel(vcpu) || | ||
2769 | kvm_apic_accept_pic_intr(vcpu)); | ||
2770 | } | ||
2771 | |||
2772 | /* | ||
2773 | * if userspace requested an interrupt window, check that the | ||
2774 | * interrupt window is open. | ||
2775 | * | ||
2776 | * No need to exit to userspace if we already have an interrupt queued. | ||
2777 | */ | ||
2778 | static int kvm_vcpu_ready_for_interrupt_injection(struct kvm_vcpu *vcpu) | ||
2779 | { | ||
2780 | return kvm_arch_interrupt_allowed(vcpu) && | ||
2781 | !kvm_cpu_has_interrupt(vcpu) && | ||
2782 | !kvm_event_needs_reinjection(vcpu) && | ||
2783 | kvm_cpu_accept_dm_intr(vcpu); | ||
2784 | } | ||
2785 | |||
2766 | static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, | 2786 | static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, |
2767 | struct kvm_interrupt *irq) | 2787 | struct kvm_interrupt *irq) |
2768 | { | 2788 | { |
@@ -2786,6 +2806,7 @@ static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, | |||
2786 | return -EEXIST; | 2806 | return -EEXIST; |
2787 | 2807 | ||
2788 | vcpu->arch.pending_external_vector = irq->irq; | 2808 | vcpu->arch.pending_external_vector = irq->irq; |
2809 | kvm_make_request(KVM_REQ_EVENT, vcpu); | ||
2789 | return 0; | 2810 | return 0; |
2790 | } | 2811 | } |
2791 | 2812 | ||
@@ -3551,9 +3572,11 @@ static int kvm_vm_ioctl_get_pit(struct kvm *kvm, struct kvm_pit_state *ps) | |||
3551 | 3572 | ||
3552 | static int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps) | 3573 | static int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps) |
3553 | { | 3574 | { |
3575 | int i; | ||
3554 | mutex_lock(&kvm->arch.vpit->pit_state.lock); | 3576 | mutex_lock(&kvm->arch.vpit->pit_state.lock); |
3555 | memcpy(&kvm->arch.vpit->pit_state, ps, sizeof(struct kvm_pit_state)); | 3577 | memcpy(&kvm->arch.vpit->pit_state, ps, sizeof(struct kvm_pit_state)); |
3556 | kvm_pit_load_count(kvm, 0, ps->channels[0].count, 0); | 3578 | for (i = 0; i < 3; i++) |
3579 | kvm_pit_load_count(kvm, i, ps->channels[i].count, 0); | ||
3557 | mutex_unlock(&kvm->arch.vpit->pit_state.lock); | 3580 | mutex_unlock(&kvm->arch.vpit->pit_state.lock); |
3558 | return 0; | 3581 | return 0; |
3559 | } | 3582 | } |
@@ -3572,6 +3595,7 @@ static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps) | |||
3572 | static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps) | 3595 | static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps) |
3573 | { | 3596 | { |
3574 | int start = 0; | 3597 | int start = 0; |
3598 | int i; | ||
3575 | u32 prev_legacy, cur_legacy; | 3599 | u32 prev_legacy, cur_legacy; |
3576 | mutex_lock(&kvm->arch.vpit->pit_state.lock); | 3600 | mutex_lock(&kvm->arch.vpit->pit_state.lock); |
3577 | prev_legacy = kvm->arch.vpit->pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY; | 3601 | prev_legacy = kvm->arch.vpit->pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY; |
@@ -3581,7 +3605,8 @@ static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps) | |||
3581 | memcpy(&kvm->arch.vpit->pit_state.channels, &ps->channels, | 3605 | memcpy(&kvm->arch.vpit->pit_state.channels, &ps->channels, |
3582 | sizeof(kvm->arch.vpit->pit_state.channels)); | 3606 | sizeof(kvm->arch.vpit->pit_state.channels)); |
3583 | kvm->arch.vpit->pit_state.flags = ps->flags; | 3607 | kvm->arch.vpit->pit_state.flags = ps->flags; |
3584 | kvm_pit_load_count(kvm, 0, kvm->arch.vpit->pit_state.channels[0].count, start); | 3608 | for (i = 0; i < 3; i++) |
3609 | kvm_pit_load_count(kvm, i, kvm->arch.vpit->pit_state.channels[i].count, start); | ||
3585 | mutex_unlock(&kvm->arch.vpit->pit_state.lock); | 3610 | mutex_unlock(&kvm->arch.vpit->pit_state.lock); |
3586 | return 0; | 3611 | return 0; |
3587 | } | 3612 | } |
@@ -5910,23 +5935,10 @@ static int emulator_fix_hypercall(struct x86_emulate_ctxt *ctxt) | |||
5910 | return emulator_write_emulated(ctxt, rip, instruction, 3, NULL); | 5935 | return emulator_write_emulated(ctxt, rip, instruction, 3, NULL); |
5911 | } | 5936 | } |
5912 | 5937 | ||
5913 | /* | ||
5914 | * Check if userspace requested an interrupt window, and that the | ||
5915 | * interrupt window is open. | ||
5916 | * | ||
5917 | * No need to exit to userspace if we already have an interrupt queued. | ||
5918 | */ | ||
5919 | static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu) | 5938 | static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu) |
5920 | { | 5939 | { |
5921 | if (!vcpu->run->request_interrupt_window || pic_in_kernel(vcpu->kvm)) | 5940 | return vcpu->run->request_interrupt_window && |
5922 | return false; | 5941 | likely(!pic_in_kernel(vcpu->kvm)); |
5923 | |||
5924 | if (kvm_cpu_has_interrupt(vcpu)) | ||
5925 | return false; | ||
5926 | |||
5927 | return (irqchip_split(vcpu->kvm) | ||
5928 | ? kvm_apic_accept_pic_intr(vcpu) | ||
5929 | : kvm_arch_interrupt_allowed(vcpu)); | ||
5930 | } | 5942 | } |
5931 | 5943 | ||
5932 | static void post_kvm_run_save(struct kvm_vcpu *vcpu) | 5944 | static void post_kvm_run_save(struct kvm_vcpu *vcpu) |
@@ -5937,17 +5949,9 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu) | |||
5937 | kvm_run->flags = is_smm(vcpu) ? KVM_RUN_X86_SMM : 0; | 5949 | kvm_run->flags = is_smm(vcpu) ? KVM_RUN_X86_SMM : 0; |
5938 | kvm_run->cr8 = kvm_get_cr8(vcpu); | 5950 | kvm_run->cr8 = kvm_get_cr8(vcpu); |
5939 | kvm_run->apic_base = kvm_get_apic_base(vcpu); | 5951 | kvm_run->apic_base = kvm_get_apic_base(vcpu); |
5940 | if (!irqchip_in_kernel(vcpu->kvm)) | 5952 | kvm_run->ready_for_interrupt_injection = |
5941 | kvm_run->ready_for_interrupt_injection = | 5953 | pic_in_kernel(vcpu->kvm) || |
5942 | kvm_arch_interrupt_allowed(vcpu) && | 5954 | kvm_vcpu_ready_for_interrupt_injection(vcpu); |
5943 | !kvm_cpu_has_interrupt(vcpu) && | ||
5944 | !kvm_event_needs_reinjection(vcpu); | ||
5945 | else if (!pic_in_kernel(vcpu->kvm)) | ||
5946 | kvm_run->ready_for_interrupt_injection = | ||
5947 | kvm_apic_accept_pic_intr(vcpu) && | ||
5948 | !kvm_cpu_has_interrupt(vcpu); | ||
5949 | else | ||
5950 | kvm_run->ready_for_interrupt_injection = 1; | ||
5951 | } | 5955 | } |
5952 | 5956 | ||
5953 | static void update_cr8_intercept(struct kvm_vcpu *vcpu) | 5957 | static void update_cr8_intercept(struct kvm_vcpu *vcpu) |
@@ -6360,8 +6364,10 @@ void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm, | |||
6360 | static int vcpu_enter_guest(struct kvm_vcpu *vcpu) | 6364 | static int vcpu_enter_guest(struct kvm_vcpu *vcpu) |
6361 | { | 6365 | { |
6362 | int r; | 6366 | int r; |
6363 | bool req_int_win = !lapic_in_kernel(vcpu) && | 6367 | bool req_int_win = |
6364 | vcpu->run->request_interrupt_window; | 6368 | dm_request_for_irq_injection(vcpu) && |
6369 | kvm_cpu_accept_dm_intr(vcpu); | ||
6370 | |||
6365 | bool req_immediate_exit = false; | 6371 | bool req_immediate_exit = false; |
6366 | 6372 | ||
6367 | if (vcpu->requests) { | 6373 | if (vcpu->requests) { |
@@ -6513,6 +6519,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) | |||
6513 | if (req_immediate_exit) | 6519 | if (req_immediate_exit) |
6514 | smp_send_reschedule(vcpu->cpu); | 6520 | smp_send_reschedule(vcpu->cpu); |
6515 | 6521 | ||
6522 | trace_kvm_entry(vcpu->vcpu_id); | ||
6523 | wait_lapic_expire(vcpu); | ||
6516 | __kvm_guest_enter(); | 6524 | __kvm_guest_enter(); |
6517 | 6525 | ||
6518 | if (unlikely(vcpu->arch.switch_db_regs)) { | 6526 | if (unlikely(vcpu->arch.switch_db_regs)) { |
@@ -6525,8 +6533,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) | |||
6525 | vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD; | 6533 | vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD; |
6526 | } | 6534 | } |
6527 | 6535 | ||
6528 | trace_kvm_entry(vcpu->vcpu_id); | ||
6529 | wait_lapic_expire(vcpu); | ||
6530 | kvm_x86_ops->run(vcpu); | 6536 | kvm_x86_ops->run(vcpu); |
6531 | 6537 | ||
6532 | /* | 6538 | /* |
@@ -6663,7 +6669,8 @@ static int vcpu_run(struct kvm_vcpu *vcpu) | |||
6663 | if (kvm_cpu_has_pending_timer(vcpu)) | 6669 | if (kvm_cpu_has_pending_timer(vcpu)) |
6664 | kvm_inject_pending_timer_irqs(vcpu); | 6670 | kvm_inject_pending_timer_irqs(vcpu); |
6665 | 6671 | ||
6666 | if (dm_request_for_irq_injection(vcpu)) { | 6672 | if (dm_request_for_irq_injection(vcpu) && |
6673 | kvm_vcpu_ready_for_interrupt_injection(vcpu)) { | ||
6667 | r = 0; | 6674 | r = 0; |
6668 | vcpu->run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN; | 6675 | vcpu->run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN; |
6669 | ++vcpu->stat.request_irq_exits; | 6676 | ++vcpu->stat.request_irq_exits; |