diff options
Diffstat (limited to 'arch/powerpc/kvm/powerpc.c')
| -rw-r--r-- | arch/powerpc/kvm/powerpc.c | 20 |
1 files changed, 17 insertions, 3 deletions
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 | ||
