diff options
Diffstat (limited to 'arch/powerpc/kvm/powerpc.c')
-rw-r--r-- | arch/powerpc/kvm/powerpc.c | 94 |
1 files changed, 72 insertions, 22 deletions
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 00d7e345b3fe..1493c8de947b 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -43,6 +43,11 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) | |||
43 | v->requests; | 43 | v->requests; |
44 | } | 44 | } |
45 | 45 | ||
46 | int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) | ||
47 | { | ||
48 | return 1; | ||
49 | } | ||
50 | |||
46 | int kvmppc_kvm_pv(struct kvm_vcpu *vcpu) | 51 | int kvmppc_kvm_pv(struct kvm_vcpu *vcpu) |
47 | { | 52 | { |
48 | int nr = kvmppc_get_gpr(vcpu, 11); | 53 | int nr = kvmppc_get_gpr(vcpu, 11); |
@@ -74,7 +79,7 @@ int kvmppc_kvm_pv(struct kvm_vcpu *vcpu) | |||
74 | } | 79 | } |
75 | case HC_VENDOR_KVM | KVM_HC_FEATURES: | 80 | case HC_VENDOR_KVM | KVM_HC_FEATURES: |
76 | r = HC_EV_SUCCESS; | 81 | r = HC_EV_SUCCESS; |
77 | #if defined(CONFIG_PPC_BOOK3S) || defined(CONFIG_KVM_E500) | 82 | #if defined(CONFIG_PPC_BOOK3S) || defined(CONFIG_KVM_E500V2) |
78 | /* XXX Missing magic page on 44x */ | 83 | /* XXX Missing magic page on 44x */ |
79 | r2 |= (1 << KVM_FEATURE_MAGIC_PAGE); | 84 | r2 |= (1 << KVM_FEATURE_MAGIC_PAGE); |
80 | #endif | 85 | #endif |
@@ -109,6 +114,11 @@ int kvmppc_sanity_check(struct kvm_vcpu *vcpu) | |||
109 | goto out; | 114 | goto out; |
110 | #endif | 115 | #endif |
111 | 116 | ||
117 | #ifdef CONFIG_KVM_BOOKE_HV | ||
118 | if (!cpu_has_feature(CPU_FTR_EMB_HV)) | ||
119 | goto out; | ||
120 | #endif | ||
121 | |||
112 | r = true; | 122 | r = true; |
113 | 123 | ||
114 | out: | 124 | out: |
@@ -225,7 +235,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
225 | case KVM_CAP_PPC_PAIRED_SINGLES: | 235 | case KVM_CAP_PPC_PAIRED_SINGLES: |
226 | case KVM_CAP_PPC_OSI: | 236 | case KVM_CAP_PPC_OSI: |
227 | case KVM_CAP_PPC_GET_PVINFO: | 237 | case KVM_CAP_PPC_GET_PVINFO: |
228 | #ifdef CONFIG_KVM_E500 | 238 | #if defined(CONFIG_KVM_E500V2) || defined(CONFIG_KVM_E500MC) |
229 | case KVM_CAP_SW_TLB: | 239 | case KVM_CAP_SW_TLB: |
230 | #endif | 240 | #endif |
231 | r = 1; | 241 | r = 1; |
@@ -234,10 +244,12 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
234 | r = KVM_COALESCED_MMIO_PAGE_OFFSET; | 244 | r = KVM_COALESCED_MMIO_PAGE_OFFSET; |
235 | break; | 245 | break; |
236 | #endif | 246 | #endif |
237 | #ifdef CONFIG_KVM_BOOK3S_64_HV | 247 | #ifdef CONFIG_PPC_BOOK3S_64 |
238 | case KVM_CAP_SPAPR_TCE: | 248 | case KVM_CAP_SPAPR_TCE: |
239 | r = 1; | 249 | r = 1; |
240 | break; | 250 | break; |
251 | #endif /* CONFIG_PPC_BOOK3S_64 */ | ||
252 | #ifdef CONFIG_KVM_BOOK3S_64_HV | ||
241 | case KVM_CAP_PPC_SMT: | 253 | case KVM_CAP_PPC_SMT: |
242 | r = threads_per_core; | 254 | r = threads_per_core; |
243 | break; | 255 | break; |
@@ -267,6 +279,11 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
267 | case KVM_CAP_MAX_VCPUS: | 279 | case KVM_CAP_MAX_VCPUS: |
268 | r = KVM_MAX_VCPUS; | 280 | r = KVM_MAX_VCPUS; |
269 | break; | 281 | break; |
282 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
283 | case KVM_CAP_PPC_GET_SMMU_INFO: | ||
284 | r = 1; | ||
285 | break; | ||
286 | #endif | ||
270 | default: | 287 | default: |
271 | r = 0; | 288 | r = 0; |
272 | break; | 289 | break; |
@@ -588,21 +605,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
588 | return r; | 605 | return r; |
589 | } | 606 | } |
590 | 607 | ||
591 | void kvm_vcpu_kick(struct kvm_vcpu *vcpu) | ||
592 | { | ||
593 | int me; | ||
594 | int cpu = vcpu->cpu; | ||
595 | |||
596 | me = get_cpu(); | ||
597 | if (waitqueue_active(vcpu->arch.wqp)) { | ||
598 | wake_up_interruptible(vcpu->arch.wqp); | ||
599 | vcpu->stat.halt_wakeup++; | ||
600 | } else if (cpu != me && cpu != -1) { | ||
601 | smp_send_reschedule(vcpu->cpu); | ||
602 | } | ||
603 | put_cpu(); | ||
604 | } | ||
605 | |||
606 | int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq) | 608 | int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq) |
607 | { | 609 | { |
608 | if (irq->irq == KVM_INTERRUPT_UNSET) { | 610 | if (irq->irq == KVM_INTERRUPT_UNSET) { |
@@ -611,6 +613,7 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq) | |||
611 | } | 613 | } |
612 | 614 | ||
613 | kvmppc_core_queue_external(vcpu, irq); | 615 | kvmppc_core_queue_external(vcpu, irq); |
616 | |||
614 | kvm_vcpu_kick(vcpu); | 617 | kvm_vcpu_kick(vcpu); |
615 | 618 | ||
616 | return 0; | 619 | return 0; |
@@ -633,7 +636,7 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, | |||
633 | r = 0; | 636 | r = 0; |
634 | vcpu->arch.papr_enabled = true; | 637 | vcpu->arch.papr_enabled = true; |
635 | break; | 638 | break; |
636 | #ifdef CONFIG_KVM_E500 | 639 | #if defined(CONFIG_KVM_E500V2) || defined(CONFIG_KVM_E500MC) |
637 | case KVM_CAP_SW_TLB: { | 640 | case KVM_CAP_SW_TLB: { |
638 | struct kvm_config_tlb cfg; | 641 | struct kvm_config_tlb cfg; |
639 | void __user *user_ptr = (void __user *)(uintptr_t)cap->args[0]; | 642 | void __user *user_ptr = (void __user *)(uintptr_t)cap->args[0]; |
@@ -710,7 +713,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, | |||
710 | break; | 713 | break; |
711 | } | 714 | } |
712 | 715 | ||
713 | #ifdef CONFIG_KVM_E500 | 716 | #if defined(CONFIG_KVM_E500V2) || defined(CONFIG_KVM_E500MC) |
714 | case KVM_DIRTY_TLB: { | 717 | case KVM_DIRTY_TLB: { |
715 | struct kvm_dirty_tlb dirty; | 718 | struct kvm_dirty_tlb dirty; |
716 | r = -EFAULT; | 719 | r = -EFAULT; |
@@ -720,7 +723,6 @@ long kvm_arch_vcpu_ioctl(struct file *filp, | |||
720 | break; | 723 | break; |
721 | } | 724 | } |
722 | #endif | 725 | #endif |
723 | |||
724 | default: | 726 | default: |
725 | r = -EINVAL; | 727 | r = -EINVAL; |
726 | } | 728 | } |
@@ -777,7 +779,7 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
777 | 779 | ||
778 | break; | 780 | break; |
779 | } | 781 | } |
780 | #ifdef CONFIG_KVM_BOOK3S_64_HV | 782 | #ifdef CONFIG_PPC_BOOK3S_64 |
781 | case KVM_CREATE_SPAPR_TCE: { | 783 | case KVM_CREATE_SPAPR_TCE: { |
782 | struct kvm_create_spapr_tce create_tce; | 784 | struct kvm_create_spapr_tce create_tce; |
783 | struct kvm *kvm = filp->private_data; | 785 | struct kvm *kvm = filp->private_data; |
@@ -788,7 +790,9 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
788 | r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce); | 790 | r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce); |
789 | goto out; | 791 | goto out; |
790 | } | 792 | } |
793 | #endif /* CONFIG_PPC_BOOK3S_64 */ | ||
791 | 794 | ||
795 | #ifdef CONFIG_KVM_BOOK3S_64_HV | ||
792 | case KVM_ALLOCATE_RMA: { | 796 | case KVM_ALLOCATE_RMA: { |
793 | struct kvm *kvm = filp->private_data; | 797 | struct kvm *kvm = filp->private_data; |
794 | struct kvm_allocate_rma rma; | 798 | struct kvm_allocate_rma rma; |
@@ -800,6 +804,18 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
800 | } | 804 | } |
801 | #endif /* CONFIG_KVM_BOOK3S_64_HV */ | 805 | #endif /* CONFIG_KVM_BOOK3S_64_HV */ |
802 | 806 | ||
807 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
808 | case KVM_PPC_GET_SMMU_INFO: { | ||
809 | struct kvm *kvm = filp->private_data; | ||
810 | struct kvm_ppc_smmu_info info; | ||
811 | |||
812 | memset(&info, 0, sizeof(info)); | ||
813 | r = kvm_vm_ioctl_get_smmu_info(kvm, &info); | ||
814 | if (r >= 0 && copy_to_user(argp, &info, sizeof(info))) | ||
815 | r = -EFAULT; | ||
816 | break; | ||
817 | } | ||
818 | #endif /* CONFIG_PPC_BOOK3S_64 */ | ||
803 | default: | 819 | default: |
804 | r = -ENOTTY; | 820 | r = -ENOTTY; |
805 | } | 821 | } |
@@ -808,6 +824,40 @@ out: | |||
808 | return r; | 824 | return r; |
809 | } | 825 | } |
810 | 826 | ||
827 | static unsigned long lpid_inuse[BITS_TO_LONGS(KVMPPC_NR_LPIDS)]; | ||
828 | static unsigned long nr_lpids; | ||
829 | |||
830 | long kvmppc_alloc_lpid(void) | ||
831 | { | ||
832 | long lpid; | ||
833 | |||
834 | do { | ||
835 | lpid = find_first_zero_bit(lpid_inuse, KVMPPC_NR_LPIDS); | ||
836 | if (lpid >= nr_lpids) { | ||
837 | pr_err("%s: No LPIDs free\n", __func__); | ||
838 | return -ENOMEM; | ||
839 | } | ||
840 | } while (test_and_set_bit(lpid, lpid_inuse)); | ||
841 | |||
842 | return lpid; | ||
843 | } | ||
844 | |||
845 | void kvmppc_claim_lpid(long lpid) | ||
846 | { | ||
847 | set_bit(lpid, lpid_inuse); | ||
848 | } | ||
849 | |||
850 | void kvmppc_free_lpid(long lpid) | ||
851 | { | ||
852 | clear_bit(lpid, lpid_inuse); | ||
853 | } | ||
854 | |||
855 | void kvmppc_init_lpid(unsigned long nr_lpids_param) | ||
856 | { | ||
857 | nr_lpids = min_t(unsigned long, KVMPPC_NR_LPIDS, nr_lpids_param); | ||
858 | memset(lpid_inuse, 0, sizeof(lpid_inuse)); | ||
859 | } | ||
860 | |||
811 | int kvm_arch_init(void *opaque) | 861 | int kvm_arch_init(void *opaque) |
812 | { | 862 | { |
813 | return 0; | 863 | return 0; |