diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/smp.c | 3 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 36 |
2 files changed, 14 insertions, 25 deletions
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index 13f33ea8ccaa..3b2e55e8ad2b 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c | |||
@@ -172,6 +172,9 @@ void smp_reschedule_interrupt(struct pt_regs *regs) | |||
172 | { | 172 | { |
173 | ack_APIC_irq(); | 173 | ack_APIC_irq(); |
174 | inc_irq_stat(irq_resched_count); | 174 | inc_irq_stat(irq_resched_count); |
175 | /* | ||
176 | * KVM uses this interrupt to force a cpu out of guest mode | ||
177 | */ | ||
175 | } | 178 | } |
176 | 179 | ||
177 | void smp_call_function_interrupt(struct pt_regs *regs) | 180 | void smp_call_function_interrupt(struct pt_regs *regs) |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 75927700a26d..3c4c327490af 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -3230,6 +3230,9 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
3230 | 3230 | ||
3231 | local_irq_disable(); | 3231 | local_irq_disable(); |
3232 | 3232 | ||
3233 | clear_bit(KVM_REQ_KICK, &vcpu->requests); | ||
3234 | smp_mb__after_clear_bit(); | ||
3235 | |||
3233 | if (vcpu->requests || need_resched() || signal_pending(current)) { | 3236 | if (vcpu->requests || need_resched() || signal_pending(current)) { |
3234 | local_irq_enable(); | 3237 | local_irq_enable(); |
3235 | preempt_enable(); | 3238 | preempt_enable(); |
@@ -3237,13 +3240,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
3237 | goto out; | 3240 | goto out; |
3238 | } | 3241 | } |
3239 | 3242 | ||
3240 | vcpu->guest_mode = 1; | ||
3241 | /* | ||
3242 | * Make sure that guest_mode assignment won't happen after | ||
3243 | * testing the pending IRQ vector bitmap. | ||
3244 | */ | ||
3245 | smp_wmb(); | ||
3246 | |||
3247 | if (vcpu->arch.exception.pending) | 3243 | if (vcpu->arch.exception.pending) |
3248 | __queue_exception(vcpu); | 3244 | __queue_exception(vcpu); |
3249 | else | 3245 | else |
@@ -3288,7 +3284,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
3288 | set_debugreg(vcpu->arch.host_dr6, 6); | 3284 | set_debugreg(vcpu->arch.host_dr6, 6); |
3289 | set_debugreg(vcpu->arch.host_dr7, 7); | 3285 | set_debugreg(vcpu->arch.host_dr7, 7); |
3290 | 3286 | ||
3291 | vcpu->guest_mode = 0; | 3287 | set_bit(KVM_REQ_KICK, &vcpu->requests); |
3292 | local_irq_enable(); | 3288 | local_irq_enable(); |
3293 | 3289 | ||
3294 | ++vcpu->stat.exits; | 3290 | ++vcpu->stat.exits; |
@@ -4571,30 +4567,20 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) | |||
4571 | || vcpu->arch.nmi_pending; | 4567 | || vcpu->arch.nmi_pending; |
4572 | } | 4568 | } |
4573 | 4569 | ||
4574 | static void vcpu_kick_intr(void *info) | ||
4575 | { | ||
4576 | #ifdef DEBUG | ||
4577 | struct kvm_vcpu *vcpu = (struct kvm_vcpu *)info; | ||
4578 | printk(KERN_DEBUG "vcpu_kick_intr %p \n", vcpu); | ||
4579 | #endif | ||
4580 | } | ||
4581 | |||
4582 | void kvm_vcpu_kick(struct kvm_vcpu *vcpu) | 4570 | void kvm_vcpu_kick(struct kvm_vcpu *vcpu) |
4583 | { | 4571 | { |
4584 | int ipi_pcpu = vcpu->cpu; | 4572 | int me; |
4585 | int cpu; | 4573 | int cpu = vcpu->cpu; |
4586 | 4574 | ||
4587 | if (waitqueue_active(&vcpu->wq)) { | 4575 | if (waitqueue_active(&vcpu->wq)) { |
4588 | wake_up_interruptible(&vcpu->wq); | 4576 | wake_up_interruptible(&vcpu->wq); |
4589 | ++vcpu->stat.halt_wakeup; | 4577 | ++vcpu->stat.halt_wakeup; |
4590 | } | 4578 | } |
4591 | /* | 4579 | |
4592 | * We may be called synchronously with irqs disabled in guest mode, | 4580 | me = get_cpu(); |
4593 | * So need not to call smp_call_function_single() in that case. | 4581 | if (cpu != me && (unsigned)cpu < nr_cpu_ids && cpu_online(cpu)) |
4594 | */ | 4582 | if (!test_and_set_bit(KVM_REQ_KICK, &vcpu->requests)) |
4595 | cpu = get_cpu(); | 4583 | smp_send_reschedule(cpu); |
4596 | if (vcpu->guest_mode && vcpu->cpu != cpu) | ||
4597 | smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0); | ||
4598 | put_cpu(); | 4584 | put_cpu(); |
4599 | } | 4585 | } |
4600 | 4586 | ||