aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/smp.c3
-rw-r--r--arch/x86/kvm/x86.c36
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
177void smp_call_function_interrupt(struct pt_regs *regs) 180void 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
4574static 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
4582void kvm_vcpu_kick(struct kvm_vcpu *vcpu) 4570void 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