aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/powerpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kvm/powerpc.c')
-rw-r--r--arch/powerpc/kvm/powerpc.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 026036efcde0..3a4f379ee70f 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -38,8 +38,12 @@
38 38
39int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) 39int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
40{ 40{
41#ifndef CONFIG_KVM_BOOK3S_64_HV
41 return !(v->arch.shared->msr & MSR_WE) || 42 return !(v->arch.shared->msr & MSR_WE) ||
42 !!(v->arch.pending_exceptions); 43 !!(v->arch.pending_exceptions);
44#else
45 return 1;
46#endif
43} 47}
44 48
45int kvmppc_kvm_pv(struct kvm_vcpu *vcpu) 49int kvmppc_kvm_pv(struct kvm_vcpu *vcpu)
@@ -184,10 +188,13 @@ int kvm_dev_ioctl_check_extension(long ext)
184#else 188#else
185 case KVM_CAP_PPC_SEGSTATE: 189 case KVM_CAP_PPC_SEGSTATE:
186#endif 190#endif
187 case KVM_CAP_PPC_PAIRED_SINGLES:
188 case KVM_CAP_PPC_UNSET_IRQ: 191 case KVM_CAP_PPC_UNSET_IRQ:
189 case KVM_CAP_PPC_IRQ_LEVEL: 192 case KVM_CAP_PPC_IRQ_LEVEL:
190 case KVM_CAP_ENABLE_CAP: 193 case KVM_CAP_ENABLE_CAP:
194 r = 1;
195 break;
196#ifndef CONFIG_KVM_BOOK3S_64_HV
197 case KVM_CAP_PPC_PAIRED_SINGLES:
191 case KVM_CAP_PPC_OSI: 198 case KVM_CAP_PPC_OSI:
192 case KVM_CAP_PPC_GET_PVINFO: 199 case KVM_CAP_PPC_GET_PVINFO:
193 r = 1; 200 r = 1;
@@ -195,6 +202,7 @@ int kvm_dev_ioctl_check_extension(long ext)
195 case KVM_CAP_COALESCED_MMIO: 202 case KVM_CAP_COALESCED_MMIO:
196 r = KVM_COALESCED_MMIO_PAGE_OFFSET; 203 r = KVM_COALESCED_MMIO_PAGE_OFFSET;
197 break; 204 break;
205#endif
198 default: 206 default:
199 r = 0; 207 r = 0;
200 break; 208 break;
@@ -291,6 +299,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
291 hrtimer_init(&vcpu->arch.dec_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); 299 hrtimer_init(&vcpu->arch.dec_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
292 tasklet_init(&vcpu->arch.tasklet, kvmppc_decrementer_func, (ulong)vcpu); 300 tasklet_init(&vcpu->arch.tasklet, kvmppc_decrementer_func, (ulong)vcpu);
293 vcpu->arch.dec_timer.function = kvmppc_decrementer_wakeup; 301 vcpu->arch.dec_timer.function = kvmppc_decrementer_wakeup;
302 vcpu->arch.dec_expires = ~(u64)0;
294 303
295#ifdef CONFIG_KVM_EXIT_TIMING 304#ifdef CONFIG_KVM_EXIT_TIMING
296 mutex_init(&vcpu->arch.exit_timing_lock); 305 mutex_init(&vcpu->arch.exit_timing_lock);
@@ -317,6 +326,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
317 mtspr(SPRN_VRSAVE, vcpu->arch.vrsave); 326 mtspr(SPRN_VRSAVE, vcpu->arch.vrsave);
318#endif 327#endif
319 kvmppc_core_vcpu_load(vcpu, cpu); 328 kvmppc_core_vcpu_load(vcpu, cpu);
329 vcpu->cpu = smp_processor_id();
320} 330}
321 331
322void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) 332void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
@@ -325,6 +335,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
325#ifdef CONFIG_BOOKE 335#ifdef CONFIG_BOOKE
326 vcpu->arch.vrsave = mfspr(SPRN_VRSAVE); 336 vcpu->arch.vrsave = mfspr(SPRN_VRSAVE);
327#endif 337#endif
338 vcpu->cpu = -1;
328} 339}
329 340
330int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, 341int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
@@ -496,6 +507,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
496 for (i = 0; i < 32; i++) 507 for (i = 0; i < 32; i++)
497 kvmppc_set_gpr(vcpu, i, gprs[i]); 508 kvmppc_set_gpr(vcpu, i, gprs[i]);
498 vcpu->arch.osi_needed = 0; 509 vcpu->arch.osi_needed = 0;
510 } else if (vcpu->arch.hcall_needed) {
511 int i;
512
513 kvmppc_set_gpr(vcpu, 3, run->papr_hcall.ret);
514 for (i = 0; i < 9; ++i)
515 kvmppc_set_gpr(vcpu, 4 + i, run->papr_hcall.args[i]);
516 vcpu->arch.hcall_needed = 0;
499 } 517 }
500 518
501 kvmppc_core_deliver_interrupts(vcpu); 519 kvmppc_core_deliver_interrupts(vcpu);
@@ -518,6 +536,8 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq)
518 if (waitqueue_active(&vcpu->wq)) { 536 if (waitqueue_active(&vcpu->wq)) {
519 wake_up_interruptible(&vcpu->wq); 537 wake_up_interruptible(&vcpu->wq);
520 vcpu->stat.halt_wakeup++; 538 vcpu->stat.halt_wakeup++;
539 } else if (vcpu->cpu != -1) {
540 smp_send_reschedule(vcpu->cpu);
521 } 541 }
522 542
523 return 0; 543 return 0;