aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/ia64/kernel/irq_ia64.c3
-rw-r--r--arch/ia64/kvm/kvm-ia64.c22
-rw-r--r--arch/x86/kernel/smp.c3
-rw-r--r--arch/x86/kvm/x86.c36
4 files changed, 25 insertions, 39 deletions
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index acc4d19ae62a..b448197728be 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -610,6 +610,9 @@ static struct irqaction ipi_irqaction = {
610 .name = "IPI" 610 .name = "IPI"
611}; 611};
612 612
613/*
614 * KVM uses this interrupt to force a cpu out of guest mode
615 */
613static struct irqaction resched_irqaction = { 616static struct irqaction resched_irqaction = {
614 .handler = dummy_handler, 617 .handler = dummy_handler,
615 .flags = IRQF_DISABLED, 618 .flags = IRQF_DISABLED,
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index be4413e1f43f..80c57b0a21c4 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -668,7 +668,7 @@ again:
668 host_ctx = kvm_get_host_context(vcpu); 668 host_ctx = kvm_get_host_context(vcpu);
669 guest_ctx = kvm_get_guest_context(vcpu); 669 guest_ctx = kvm_get_guest_context(vcpu);
670 670
671 vcpu->guest_mode = 1; 671 clear_bit(KVM_REQ_KICK, &vcpu->requests);
672 672
673 r = kvm_vcpu_pre_transition(vcpu); 673 r = kvm_vcpu_pre_transition(vcpu);
674 if (r < 0) 674 if (r < 0)
@@ -685,7 +685,7 @@ again:
685 kvm_vcpu_post_transition(vcpu); 685 kvm_vcpu_post_transition(vcpu);
686 686
687 vcpu->arch.launched = 1; 687 vcpu->arch.launched = 1;
688 vcpu->guest_mode = 0; 688 set_bit(KVM_REQ_KICK, &vcpu->requests);
689 local_irq_enable(); 689 local_irq_enable();
690 690
691 /* 691 /*
@@ -1879,24 +1879,18 @@ void kvm_arch_hardware_unsetup(void)
1879{ 1879{
1880} 1880}
1881 1881
1882static void vcpu_kick_intr(void *info)
1883{
1884#ifdef DEBUG
1885 struct kvm_vcpu *vcpu = (struct kvm_vcpu *)info;
1886 printk(KERN_DEBUG"vcpu_kick_intr %p \n", vcpu);
1887#endif
1888}
1889
1890void kvm_vcpu_kick(struct kvm_vcpu *vcpu) 1882void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
1891{ 1883{
1892 int ipi_pcpu = vcpu->cpu; 1884 int me;
1893 int cpu = get_cpu(); 1885 int cpu = vcpu->cpu;
1894 1886
1895 if (waitqueue_active(&vcpu->wq)) 1887 if (waitqueue_active(&vcpu->wq))
1896 wake_up_interruptible(&vcpu->wq); 1888 wake_up_interruptible(&vcpu->wq);
1897 1889
1898 if (vcpu->guest_mode && cpu != ipi_pcpu) 1890 me = get_cpu();
1899 smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0); 1891 if (cpu != me && (unsigned) cpu < nr_cpu_ids && cpu_online(cpu))
1892 if (!test_and_set_bit(KVM_REQ_KICK, &vcpu->requests))
1893 smp_send_reschedule(cpu);
1900 put_cpu(); 1894 put_cpu();
1901} 1895}
1902 1896
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