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.c134
1 files changed, 100 insertions, 34 deletions
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 4c79284b58be..c1f8f53cd312 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -294,7 +294,7 @@ int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu)
294 { 294 {
295 u32 last_inst; 295 u32 last_inst;
296 296
297 kvmppc_get_last_inst(vcpu, false, &last_inst); 297 kvmppc_get_last_inst(vcpu, INST_GENERIC, &last_inst);
298 /* XXX Deliver Program interrupt to guest. */ 298 /* XXX Deliver Program interrupt to guest. */
299 pr_emerg("%s: emulation failed (%08x)\n", __func__, last_inst); 299 pr_emerg("%s: emulation failed (%08x)\n", __func__, last_inst);
300 r = RESUME_HOST; 300 r = RESUME_HOST;
@@ -384,24 +384,16 @@ int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
384} 384}
385EXPORT_SYMBOL_GPL(kvmppc_ld); 385EXPORT_SYMBOL_GPL(kvmppc_ld);
386 386
387int kvm_arch_hardware_enable(void *garbage) 387int kvm_arch_hardware_enable(void)
388{ 388{
389 return 0; 389 return 0;
390} 390}
391 391
392void kvm_arch_hardware_disable(void *garbage)
393{
394}
395
396int kvm_arch_hardware_setup(void) 392int kvm_arch_hardware_setup(void)
397{ 393{
398 return 0; 394 return 0;
399} 395}
400 396
401void kvm_arch_hardware_unsetup(void)
402{
403}
404
405void kvm_arch_check_processor_compat(void *rtn) 397void kvm_arch_check_processor_compat(void *rtn)
406{ 398{
407 *(int *)rtn = kvmppc_core_check_processor_compat(); 399 *(int *)rtn = kvmppc_core_check_processor_compat();
@@ -462,10 +454,6 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
462 module_put(kvm->arch.kvm_ops->owner); 454 module_put(kvm->arch.kvm_ops->owner);
463} 455}
464 456
465void kvm_arch_sync_events(struct kvm *kvm)
466{
467}
468
469int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) 457int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
470{ 458{
471 int r; 459 int r;
@@ -608,10 +596,6 @@ int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot,
608 return kvmppc_core_create_memslot(kvm, slot, npages); 596 return kvmppc_core_create_memslot(kvm, slot, npages);
609} 597}
610 598
611void kvm_arch_memslots_updated(struct kvm *kvm)
612{
613}
614
615int kvm_arch_prepare_memory_region(struct kvm *kvm, 599int kvm_arch_prepare_memory_region(struct kvm *kvm,
616 struct kvm_memory_slot *memslot, 600 struct kvm_memory_slot *memslot,
617 struct kvm_userspace_memory_region *mem, 601 struct kvm_userspace_memory_region *mem,
@@ -628,10 +612,6 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
628 kvmppc_core_commit_memory_region(kvm, mem, old); 612 kvmppc_core_commit_memory_region(kvm, mem, old);
629} 613}
630 614
631void kvm_arch_flush_shadow_all(struct kvm *kvm)
632{
633}
634
635void kvm_arch_flush_shadow_memslot(struct kvm *kvm, 615void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
636 struct kvm_memory_slot *slot) 616 struct kvm_memory_slot *slot)
637{ 617{
@@ -658,7 +638,6 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
658{ 638{
659 /* Make sure we're not using the vcpu anymore */ 639 /* Make sure we're not using the vcpu anymore */
660 hrtimer_cancel(&vcpu->arch.dec_timer); 640 hrtimer_cancel(&vcpu->arch.dec_timer);
661 tasklet_kill(&vcpu->arch.tasklet);
662 641
663 kvmppc_remove_vcpu_debugfs(vcpu); 642 kvmppc_remove_vcpu_debugfs(vcpu);
664 643
@@ -684,16 +663,12 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
684 return kvmppc_core_pending_dec(vcpu); 663 return kvmppc_core_pending_dec(vcpu);
685} 664}
686 665
687/*
688 * low level hrtimer wake routine. Because this runs in hardirq context
689 * we schedule a tasklet to do the real work.
690 */
691enum hrtimer_restart kvmppc_decrementer_wakeup(struct hrtimer *timer) 666enum hrtimer_restart kvmppc_decrementer_wakeup(struct hrtimer *timer)
692{ 667{
693 struct kvm_vcpu *vcpu; 668 struct kvm_vcpu *vcpu;
694 669
695 vcpu = container_of(timer, struct kvm_vcpu, arch.dec_timer); 670 vcpu = container_of(timer, struct kvm_vcpu, arch.dec_timer);
696 tasklet_schedule(&vcpu->arch.tasklet); 671 kvmppc_decrementer_func(vcpu);
697 672
698 return HRTIMER_NORESTART; 673 return HRTIMER_NORESTART;
699} 674}
@@ -703,7 +678,6 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
703 int ret; 678 int ret;
704 679
705 hrtimer_init(&vcpu->arch.dec_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); 680 hrtimer_init(&vcpu->arch.dec_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
706 tasklet_init(&vcpu->arch.tasklet, kvmppc_decrementer_func, (ulong)vcpu);
707 vcpu->arch.dec_timer.function = kvmppc_decrementer_wakeup; 681 vcpu->arch.dec_timer.function = kvmppc_decrementer_wakeup;
708 vcpu->arch.dec_expires = ~(u64)0; 682 vcpu->arch.dec_expires = ~(u64)0;
709 683
@@ -927,6 +901,103 @@ int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
927} 901}
928EXPORT_SYMBOL_GPL(kvmppc_handle_store); 902EXPORT_SYMBOL_GPL(kvmppc_handle_store);
929 903
904int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
905{
906 int r = 0;
907 union kvmppc_one_reg val;
908 int size;
909
910 size = one_reg_size(reg->id);
911 if (size > sizeof(val))
912 return -EINVAL;
913
914 r = kvmppc_get_one_reg(vcpu, reg->id, &val);
915 if (r == -EINVAL) {
916 r = 0;
917 switch (reg->id) {
918#ifdef CONFIG_ALTIVEC
919 case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31:
920 if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
921 r = -ENXIO;
922 break;
923 }
924 vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0] = val.vval;
925 break;
926 case KVM_REG_PPC_VSCR:
927 if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
928 r = -ENXIO;
929 break;
930 }
931 vcpu->arch.vr.vscr.u[3] = set_reg_val(reg->id, val);
932 break;
933 case KVM_REG_PPC_VRSAVE:
934 if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
935 r = -ENXIO;
936 break;
937 }
938 vcpu->arch.vrsave = set_reg_val(reg->id, val);
939 break;
940#endif /* CONFIG_ALTIVEC */
941 default:
942 r = -EINVAL;
943 break;
944 }
945 }
946
947 if (r)
948 return r;
949
950 if (copy_to_user((char __user *)(unsigned long)reg->addr, &val, size))
951 r = -EFAULT;
952
953 return r;
954}
955
956int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
957{
958 int r;
959 union kvmppc_one_reg val;
960 int size;
961
962 size = one_reg_size(reg->id);
963 if (size > sizeof(val))
964 return -EINVAL;
965
966 if (copy_from_user(&val, (char __user *)(unsigned long)reg->addr, size))
967 return -EFAULT;
968
969 r = kvmppc_set_one_reg(vcpu, reg->id, &val);
970 if (r == -EINVAL) {
971 r = 0;
972 switch (reg->id) {
973#ifdef CONFIG_ALTIVEC
974 case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31:
975 if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
976 r = -ENXIO;
977 break;
978 }
979 val.vval = vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0];
980 break;
981 case KVM_REG_PPC_VSCR:
982 if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
983 r = -ENXIO;
984 break;
985 }
986 val = get_reg_val(reg->id, vcpu->arch.vr.vscr.u[3]);
987 break;
988 case KVM_REG_PPC_VRSAVE:
989 val = get_reg_val(reg->id, vcpu->arch.vrsave);
990 break;
991#endif /* CONFIG_ALTIVEC */
992 default:
993 r = -EINVAL;
994 break;
995 }
996 }
997
998 return r;
999}
1000
930int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) 1001int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
931{ 1002{
932 int r; 1003 int r;
@@ -1343,9 +1414,4 @@ int kvm_arch_init(void *opaque)
1343 return 0; 1414 return 0;
1344} 1415}
1345 1416
1346void kvm_arch_exit(void)
1347{
1348
1349}
1350
1351EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_ppc_instr); 1417EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_ppc_instr);