aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/ia64/include/asm/kvm_host.h1
-rw-r--r--arch/ia64/kvm/kvm-ia64.c20
-rw-r--r--arch/powerpc/include/asm/kvm_host.h6
-rw-r--r--arch/powerpc/kvm/powerpc.c21
-rw-r--r--arch/s390/kvm/kvm-s390.c8
-rw-r--r--arch/x86/kvm/x86.c16
-rw-r--r--include/linux/kvm_host.h9
-rw-r--r--virt/kvm/kvm_main.c22
8 files changed, 59 insertions, 44 deletions
diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h
index e35b3a84a40b..c4b4bac3d09e 100644
--- a/arch/ia64/include/asm/kvm_host.h
+++ b/arch/ia64/include/asm/kvm_host.h
@@ -365,6 +365,7 @@ struct thash_cb {
365}; 365};
366 366
367struct kvm_vcpu_stat { 367struct kvm_vcpu_stat {
368 u32 halt_wakeup;
368}; 369};
369 370
370struct kvm_vcpu_arch { 371struct kvm_vcpu_arch {
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index f5104b7c52cd..9d80ff8d9eff 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -1872,21 +1872,6 @@ void kvm_arch_hardware_unsetup(void)
1872{ 1872{
1873} 1873}
1874 1874
1875void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
1876{
1877 int me;
1878 int cpu = vcpu->cpu;
1879
1880 if (waitqueue_active(&vcpu->wq))
1881 wake_up_interruptible(&vcpu->wq);
1882
1883 me = get_cpu();
1884 if (cpu != me && (unsigned) cpu < nr_cpu_ids && cpu_online(cpu))
1885 if (!test_and_set_bit(KVM_REQ_KICK, &vcpu->requests))
1886 smp_send_reschedule(cpu);
1887 put_cpu();
1888}
1889
1890int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq) 1875int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq)
1891{ 1876{
1892 return __apic_accept_irq(vcpu, irq->vector); 1877 return __apic_accept_irq(vcpu, irq->vector);
@@ -1956,6 +1941,11 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
1956 (kvm_highest_pending_irq(vcpu) != -1); 1941 (kvm_highest_pending_irq(vcpu) != -1);
1957} 1942}
1958 1943
1944int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
1945{
1946 return (!test_and_set_bit(KVM_REQ_KICK, &vcpu->requests));
1947}
1948
1959int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, 1949int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
1960 struct kvm_mp_state *mp_state) 1950 struct kvm_mp_state *mp_state)
1961{ 1951{
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 52eb9c1f4fe0..889383735e73 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -498,4 +498,10 @@ struct kvm_vcpu_arch {
498#define KVM_MMIO_REG_QPR 0x0040 498#define KVM_MMIO_REG_QPR 0x0040
499#define KVM_MMIO_REG_FQPR 0x0060 499#define KVM_MMIO_REG_FQPR 0x0060
500 500
501#define __KVM_HAVE_ARCH_VCPU_GET_WQ 1
502static inline wait_queue_head *kvm_arch_vcpu_wq(struct kvm_vcpu *vcpu)
503{
504 return vcpu->arch.wqp;
505}
506
501#endif /* __POWERPC_KVM_HOST_H__ */ 507#endif /* __POWERPC_KVM_HOST_H__ */
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 00d7e345b3fe..b5e9046462fd 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -43,6 +43,11 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
43 v->requests; 43 v->requests;
44} 44}
45 45
46int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
47{
48 return 1;
49}
50
46int kvmppc_kvm_pv(struct kvm_vcpu *vcpu) 51int kvmppc_kvm_pv(struct kvm_vcpu *vcpu)
47{ 52{
48 int nr = kvmppc_get_gpr(vcpu, 11); 53 int nr = kvmppc_get_gpr(vcpu, 11);
@@ -588,21 +593,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
588 return r; 593 return r;
589} 594}
590 595
591void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
592{
593 int me;
594 int cpu = vcpu->cpu;
595
596 me = get_cpu();
597 if (waitqueue_active(vcpu->arch.wqp)) {
598 wake_up_interruptible(vcpu->arch.wqp);
599 vcpu->stat.halt_wakeup++;
600 } else if (cpu != me && cpu != -1) {
601 smp_send_reschedule(vcpu->cpu);
602 }
603 put_cpu();
604}
605
606int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq) 596int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq)
607{ 597{
608 if (irq->irq == KVM_INTERRUPT_UNSET) { 598 if (irq->irq == KVM_INTERRUPT_UNSET) {
@@ -611,6 +601,7 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq)
611 } 601 }
612 602
613 kvmppc_core_queue_external(vcpu, irq); 603 kvmppc_core_queue_external(vcpu, irq);
604
614 kvm_vcpu_kick(vcpu); 605 kvm_vcpu_kick(vcpu);
615 606
616 return 0; 607 return 0;
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 217ce44395a4..d30c8350b949 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -423,6 +423,14 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
423 return 0; 423 return 0;
424} 424}
425 425
426int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
427{
428 /* kvm common code refers to this, but never calls it */
429 BUG();
430 return 0;
431}
432
433
426static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu) 434static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
427{ 435{
428 kvm_s390_vcpu_initial_reset(vcpu); 436 kvm_s390_vcpu_initial_reset(vcpu);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 4044ce0bf7c1..511031dcb9cc 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6403,21 +6403,9 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
6403 kvm_cpu_has_interrupt(vcpu)); 6403 kvm_cpu_has_interrupt(vcpu));
6404} 6404}
6405 6405
6406void kvm_vcpu_kick(struct kvm_vcpu *vcpu) 6406int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
6407{ 6407{
6408 int me; 6408 return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
6409 int cpu = vcpu->cpu;
6410
6411 if (waitqueue_active(&vcpu->wq)) {
6412 wake_up_interruptible(&vcpu->wq);
6413 ++vcpu->stat.halt_wakeup;
6414 }
6415
6416 me = get_cpu();
6417 if (cpu != me && (unsigned)cpu < nr_cpu_ids && cpu_online(cpu))
6418 if (kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE)
6419 smp_send_reschedule(cpu);
6420 put_cpu();
6421} 6409}
6422 6410
6423int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu) 6411int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 3a2cea616283..5b624e1ff814 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -439,6 +439,7 @@ void mark_page_dirty_in_slot(struct kvm *kvm, struct kvm_memory_slot *memslot,
439 gfn_t gfn); 439 gfn_t gfn);
440 440
441void kvm_vcpu_block(struct kvm_vcpu *vcpu); 441void kvm_vcpu_block(struct kvm_vcpu *vcpu);
442void kvm_vcpu_kick(struct kvm_vcpu *vcpu);
442void kvm_vcpu_on_spin(struct kvm_vcpu *vcpu); 443void kvm_vcpu_on_spin(struct kvm_vcpu *vcpu);
443void kvm_resched(struct kvm_vcpu *vcpu); 444void kvm_resched(struct kvm_vcpu *vcpu);
444void kvm_load_guest_fpu(struct kvm_vcpu *vcpu); 445void kvm_load_guest_fpu(struct kvm_vcpu *vcpu);
@@ -507,6 +508,7 @@ int kvm_arch_hardware_setup(void);
507void kvm_arch_hardware_unsetup(void); 508void kvm_arch_hardware_unsetup(void);
508void kvm_arch_check_processor_compat(void *rtn); 509void kvm_arch_check_processor_compat(void *rtn);
509int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu); 510int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu);
511int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu);
510 512
511void kvm_free_physmem(struct kvm *kvm); 513void kvm_free_physmem(struct kvm *kvm);
512 514
@@ -522,6 +524,13 @@ static inline void kvm_arch_free_vm(struct kvm *kvm)
522} 524}
523#endif 525#endif
524 526
527#ifndef __KVM_HAVE_ARCH_VCPU_GET_WQ
528static inline wait_queue_head_t *kvm_arch_vcpu_wq(struct kvm_vcpu *vcpu)
529{
530 return &vcpu->wq;
531}
532#endif
533
525int kvm_arch_init_vm(struct kvm *kvm, unsigned long type); 534int kvm_arch_init_vm(struct kvm *kvm, unsigned long type);
526void kvm_arch_destroy_vm(struct kvm *kvm); 535void kvm_arch_destroy_vm(struct kvm *kvm);
527void kvm_free_all_assigned_devices(struct kvm *kvm); 536void kvm_free_all_assigned_devices(struct kvm *kvm);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index a9565e240636..7149a2e65524 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1514,6 +1514,28 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)
1514 finish_wait(&vcpu->wq, &wait); 1514 finish_wait(&vcpu->wq, &wait);
1515} 1515}
1516 1516
1517/*
1518 * Kick a sleeping VCPU, or a guest VCPU in guest mode, into host kernel mode.
1519 */
1520void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
1521{
1522 int me;
1523 int cpu = vcpu->cpu;
1524 wait_queue_head_t *wqp;
1525
1526 wqp = kvm_arch_vcpu_wq(vcpu);
1527 if (waitqueue_active(wqp)) {
1528 wake_up_interruptible(wqp);
1529 ++vcpu->stat.halt_wakeup;
1530 }
1531
1532 me = get_cpu();
1533 if (cpu != me && (unsigned)cpu < nr_cpu_ids && cpu_online(cpu))
1534 if (kvm_arch_vcpu_should_kick(vcpu))
1535 smp_send_reschedule(cpu);
1536 put_cpu();
1537}
1538
1517void kvm_resched(struct kvm_vcpu *vcpu) 1539void kvm_resched(struct kvm_vcpu *vcpu)
1518{ 1540{
1519 if (!need_resched()) 1541 if (!need_resched())