diff options
Diffstat (limited to 'arch/powerpc/kvm/powerpc.c')
-rw-r--r-- | arch/powerpc/kvm/powerpc.c | 134 |
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 | } |
385 | EXPORT_SYMBOL_GPL(kvmppc_ld); | 385 | EXPORT_SYMBOL_GPL(kvmppc_ld); |
386 | 386 | ||
387 | int kvm_arch_hardware_enable(void *garbage) | 387 | int kvm_arch_hardware_enable(void) |
388 | { | 388 | { |
389 | return 0; | 389 | return 0; |
390 | } | 390 | } |
391 | 391 | ||
392 | void kvm_arch_hardware_disable(void *garbage) | ||
393 | { | ||
394 | } | ||
395 | |||
396 | int kvm_arch_hardware_setup(void) | 392 | int kvm_arch_hardware_setup(void) |
397 | { | 393 | { |
398 | return 0; | 394 | return 0; |
399 | } | 395 | } |
400 | 396 | ||
401 | void kvm_arch_hardware_unsetup(void) | ||
402 | { | ||
403 | } | ||
404 | |||
405 | void kvm_arch_check_processor_compat(void *rtn) | 397 | void 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 | ||
465 | void kvm_arch_sync_events(struct kvm *kvm) | ||
466 | { | ||
467 | } | ||
468 | |||
469 | int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) | 457 | int 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 | ||
611 | void kvm_arch_memslots_updated(struct kvm *kvm) | ||
612 | { | ||
613 | } | ||
614 | |||
615 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | 599 | int 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 | ||
631 | void kvm_arch_flush_shadow_all(struct kvm *kvm) | ||
632 | { | ||
633 | } | ||
634 | |||
635 | void kvm_arch_flush_shadow_memslot(struct kvm *kvm, | 615 | void 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 | */ | ||
691 | enum hrtimer_restart kvmppc_decrementer_wakeup(struct hrtimer *timer) | 666 | enum 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 | } |
928 | EXPORT_SYMBOL_GPL(kvmppc_handle_store); | 902 | EXPORT_SYMBOL_GPL(kvmppc_handle_store); |
929 | 903 | ||
904 | int 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 | |||
956 | int 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 | |||
930 | int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | 1001 | int 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 | ||
1346 | void kvm_arch_exit(void) | ||
1347 | { | ||
1348 | |||
1349 | } | ||
1350 | |||
1351 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_ppc_instr); | 1417 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_ppc_instr); |