diff options
| author | Hollis Blanchard <hollisb@us.ibm.com> | 2008-04-25 18:55:49 -0400 |
|---|---|---|
| committer | Avi Kivity <avi@qumranet.com> | 2008-05-04 07:44:44 -0400 |
| commit | 45c5eb67da5a668abe79c23a7e64dbc87a600f90 (patch) | |
| tree | b2b9ff85ecb5b35d246d68da94b20cb9f9912bff /arch/powerpc/kvm | |
| parent | 3fe913e7c550a869e250d04c34410f7a6e263f7c (diff) | |
KVM: ppc: Handle guest idle by emulating MSR[WE] writes
This reduces host CPU usage when the guest is idle. However, the guest must
set MSR[WE] in its idle loop, which Linux did not do until 2.6.26.
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
Signed-off-by: Jerone Young <jyoung5@us.ibm.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch/powerpc/kvm')
| -rw-r--r-- | arch/powerpc/kvm/booke_guest.c | 1 | ||||
| -rw-r--r-- | arch/powerpc/kvm/powerpc.c | 20 |
2 files changed, 18 insertions, 3 deletions
diff --git a/arch/powerpc/kvm/booke_guest.c b/arch/powerpc/kvm/booke_guest.c index 6d9884a6884a..b3db6f4576ad 100644 --- a/arch/powerpc/kvm/booke_guest.c +++ b/arch/powerpc/kvm/booke_guest.c | |||
| @@ -49,6 +49,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
| 49 | { "inst_emu", VCPU_STAT(emulated_inst_exits) }, | 49 | { "inst_emu", VCPU_STAT(emulated_inst_exits) }, |
| 50 | { "dec", VCPU_STAT(dec_exits) }, | 50 | { "dec", VCPU_STAT(dec_exits) }, |
| 51 | { "ext_intr", VCPU_STAT(ext_intr_exits) }, | 51 | { "ext_intr", VCPU_STAT(ext_intr_exits) }, |
| 52 | { "halt_wakeup", VCPU_STAT(halt_wakeup) }, | ||
| 52 | { NULL } | 53 | { NULL } |
| 53 | }; | 54 | }; |
| 54 | 55 | ||
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index bad40bd2d3ac..777e0f34e0ea 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
| @@ -36,13 +36,12 @@ gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) | |||
| 36 | 36 | ||
| 37 | int kvm_cpu_has_interrupt(struct kvm_vcpu *v) | 37 | int kvm_cpu_has_interrupt(struct kvm_vcpu *v) |
| 38 | { | 38 | { |
| 39 | /* XXX implement me */ | 39 | return !!(v->arch.pending_exceptions); |
| 40 | return 0; | ||
| 41 | } | 40 | } |
| 42 | 41 | ||
| 43 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) | 42 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) |
| 44 | { | 43 | { |
| 45 | return 1; | 44 | return !(v->arch.msr & MSR_WE); |
| 46 | } | 45 | } |
| 47 | 46 | ||
| 48 | 47 | ||
| @@ -214,6 +213,11 @@ static void kvmppc_decrementer_func(unsigned long data) | |||
| 214 | struct kvm_vcpu *vcpu = (struct kvm_vcpu *)data; | 213 | struct kvm_vcpu *vcpu = (struct kvm_vcpu *)data; |
| 215 | 214 | ||
| 216 | kvmppc_queue_exception(vcpu, BOOKE_INTERRUPT_DECREMENTER); | 215 | kvmppc_queue_exception(vcpu, BOOKE_INTERRUPT_DECREMENTER); |
| 216 | |||
| 217 | if (waitqueue_active(&vcpu->wq)) { | ||
| 218 | wake_up_interruptible(&vcpu->wq); | ||
| 219 | vcpu->stat.halt_wakeup++; | ||
| 220 | } | ||
| 217 | } | 221 | } |
| 218 | 222 | ||
| 219 | int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | 223 | int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) |
| @@ -339,6 +343,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
| 339 | int r; | 343 | int r; |
| 340 | sigset_t sigsaved; | 344 | sigset_t sigsaved; |
| 341 | 345 | ||
| 346 | vcpu_load(vcpu); | ||
| 347 | |||
| 342 | if (vcpu->sigset_active) | 348 | if (vcpu->sigset_active) |
| 343 | sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); | 349 | sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); |
| 344 | 350 | ||
| @@ -363,12 +369,20 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
| 363 | if (vcpu->sigset_active) | 369 | if (vcpu->sigset_active) |
| 364 | sigprocmask(SIG_SETMASK, &sigsaved, NULL); | 370 | sigprocmask(SIG_SETMASK, &sigsaved, NULL); |
| 365 | 371 | ||
| 372 | vcpu_put(vcpu); | ||
| 373 | |||
| 366 | return r; | 374 | return r; |
| 367 | } | 375 | } |
| 368 | 376 | ||
| 369 | int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq) | 377 | int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq) |
| 370 | { | 378 | { |
| 371 | kvmppc_queue_exception(vcpu, BOOKE_INTERRUPT_EXTERNAL); | 379 | kvmppc_queue_exception(vcpu, BOOKE_INTERRUPT_EXTERNAL); |
| 380 | |||
| 381 | if (waitqueue_active(&vcpu->wq)) { | ||
| 382 | wake_up_interruptible(&vcpu->wq); | ||
| 383 | vcpu->stat.halt_wakeup++; | ||
| 384 | } | ||
| 385 | |||
| 372 | return 0; | 386 | return 0; |
| 373 | } | 387 | } |
| 374 | 388 | ||
