diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/ia64/kernel/irq_ia64.c | 3 | ||||
-rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 22 | ||||
-rw-r--r-- | arch/x86/kernel/smp.c | 3 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 36 |
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 | */ | ||
613 | static struct irqaction resched_irqaction = { | 616 | static 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 | ||
1882 | static 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 | |||
1890 | void kvm_vcpu_kick(struct kvm_vcpu *vcpu) | 1882 | void 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 | ||
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 | ||