diff options
Diffstat (limited to 'arch/powerpc/kvm/powerpc.c')
-rw-r--r-- | arch/powerpc/kvm/powerpc.c | 130 |
1 files changed, 112 insertions, 18 deletions
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 72a4ad86ee91..616dd516ca1f 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -38,9 +38,56 @@ | |||
38 | 38 | ||
39 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) | 39 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) |
40 | { | 40 | { |
41 | return !(v->arch.msr & MSR_WE) || !!(v->arch.pending_exceptions); | 41 | return !(v->arch.shared->msr & MSR_WE) || |
42 | !!(v->arch.pending_exceptions); | ||
42 | } | 43 | } |
43 | 44 | ||
45 | int kvmppc_kvm_pv(struct kvm_vcpu *vcpu) | ||
46 | { | ||
47 | int nr = kvmppc_get_gpr(vcpu, 11); | ||
48 | int r; | ||
49 | unsigned long __maybe_unused param1 = kvmppc_get_gpr(vcpu, 3); | ||
50 | unsigned long __maybe_unused param2 = kvmppc_get_gpr(vcpu, 4); | ||
51 | unsigned long __maybe_unused param3 = kvmppc_get_gpr(vcpu, 5); | ||
52 | unsigned long __maybe_unused param4 = kvmppc_get_gpr(vcpu, 6); | ||
53 | unsigned long r2 = 0; | ||
54 | |||
55 | if (!(vcpu->arch.shared->msr & MSR_SF)) { | ||
56 | /* 32 bit mode */ | ||
57 | param1 &= 0xffffffff; | ||
58 | param2 &= 0xffffffff; | ||
59 | param3 &= 0xffffffff; | ||
60 | param4 &= 0xffffffff; | ||
61 | } | ||
62 | |||
63 | switch (nr) { | ||
64 | case HC_VENDOR_KVM | KVM_HC_PPC_MAP_MAGIC_PAGE: | ||
65 | { | ||
66 | vcpu->arch.magic_page_pa = param1; | ||
67 | vcpu->arch.magic_page_ea = param2; | ||
68 | |||
69 | r2 = KVM_MAGIC_FEAT_SR; | ||
70 | |||
71 | r = HC_EV_SUCCESS; | ||
72 | break; | ||
73 | } | ||
74 | case HC_VENDOR_KVM | KVM_HC_FEATURES: | ||
75 | r = HC_EV_SUCCESS; | ||
76 | #if defined(CONFIG_PPC_BOOK3S) /* XXX Missing magic page on BookE */ | ||
77 | r2 |= (1 << KVM_FEATURE_MAGIC_PAGE); | ||
78 | #endif | ||
79 | |||
80 | /* Second return value is in r4 */ | ||
81 | break; | ||
82 | default: | ||
83 | r = HC_EV_UNIMPLEMENTED; | ||
84 | break; | ||
85 | } | ||
86 | |||
87 | kvmppc_set_gpr(vcpu, 4, r2); | ||
88 | |||
89 | return r; | ||
90 | } | ||
44 | 91 | ||
45 | int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu) | 92 | int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu) |
46 | { | 93 | { |
@@ -98,18 +145,12 @@ void kvm_arch_check_processor_compat(void *rtn) | |||
98 | *(int *)rtn = kvmppc_core_check_processor_compat(); | 145 | *(int *)rtn = kvmppc_core_check_processor_compat(); |
99 | } | 146 | } |
100 | 147 | ||
101 | struct kvm *kvm_arch_create_vm(void) | 148 | int kvm_arch_init_vm(struct kvm *kvm) |
102 | { | 149 | { |
103 | struct kvm *kvm; | 150 | return 0; |
104 | |||
105 | kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL); | ||
106 | if (!kvm) | ||
107 | return ERR_PTR(-ENOMEM); | ||
108 | |||
109 | return kvm; | ||
110 | } | 151 | } |
111 | 152 | ||
112 | static void kvmppc_free_vcpus(struct kvm *kvm) | 153 | void kvm_arch_destroy_vm(struct kvm *kvm) |
113 | { | 154 | { |
114 | unsigned int i; | 155 | unsigned int i; |
115 | struct kvm_vcpu *vcpu; | 156 | struct kvm_vcpu *vcpu; |
@@ -129,24 +170,22 @@ void kvm_arch_sync_events(struct kvm *kvm) | |||
129 | { | 170 | { |
130 | } | 171 | } |
131 | 172 | ||
132 | void kvm_arch_destroy_vm(struct kvm *kvm) | ||
133 | { | ||
134 | kvmppc_free_vcpus(kvm); | ||
135 | kvm_free_physmem(kvm); | ||
136 | cleanup_srcu_struct(&kvm->srcu); | ||
137 | kfree(kvm); | ||
138 | } | ||
139 | |||
140 | int kvm_dev_ioctl_check_extension(long ext) | 173 | int kvm_dev_ioctl_check_extension(long ext) |
141 | { | 174 | { |
142 | int r; | 175 | int r; |
143 | 176 | ||
144 | switch (ext) { | 177 | switch (ext) { |
178 | #ifdef CONFIG_BOOKE | ||
179 | case KVM_CAP_PPC_BOOKE_SREGS: | ||
180 | #else | ||
145 | case KVM_CAP_PPC_SEGSTATE: | 181 | case KVM_CAP_PPC_SEGSTATE: |
182 | #endif | ||
146 | case KVM_CAP_PPC_PAIRED_SINGLES: | 183 | case KVM_CAP_PPC_PAIRED_SINGLES: |
147 | case KVM_CAP_PPC_UNSET_IRQ: | 184 | case KVM_CAP_PPC_UNSET_IRQ: |
185 | case KVM_CAP_PPC_IRQ_LEVEL: | ||
148 | case KVM_CAP_ENABLE_CAP: | 186 | case KVM_CAP_ENABLE_CAP: |
149 | case KVM_CAP_PPC_OSI: | 187 | case KVM_CAP_PPC_OSI: |
188 | case KVM_CAP_PPC_GET_PVINFO: | ||
150 | r = 1; | 189 | r = 1; |
151 | break; | 190 | break; |
152 | case KVM_CAP_COALESCED_MMIO: | 191 | case KVM_CAP_COALESCED_MMIO: |
@@ -249,6 +288,10 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | |||
249 | tasklet_init(&vcpu->arch.tasklet, kvmppc_decrementer_func, (ulong)vcpu); | 288 | tasklet_init(&vcpu->arch.tasklet, kvmppc_decrementer_func, (ulong)vcpu); |
250 | vcpu->arch.dec_timer.function = kvmppc_decrementer_wakeup; | 289 | vcpu->arch.dec_timer.function = kvmppc_decrementer_wakeup; |
251 | 290 | ||
291 | #ifdef CONFIG_KVM_EXIT_TIMING | ||
292 | mutex_init(&vcpu->arch.exit_timing_lock); | ||
293 | #endif | ||
294 | |||
252 | return 0; | 295 | return 0; |
253 | } | 296 | } |
254 | 297 | ||
@@ -259,12 +302,25 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) | |||
259 | 302 | ||
260 | void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | 303 | void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) |
261 | { | 304 | { |
305 | #ifdef CONFIG_BOOKE | ||
306 | /* | ||
307 | * vrsave (formerly usprg0) isn't used by Linux, but may | ||
308 | * be used by the guest. | ||
309 | * | ||
310 | * On non-booke this is associated with Altivec and | ||
311 | * is handled by code in book3s.c. | ||
312 | */ | ||
313 | mtspr(SPRN_VRSAVE, vcpu->arch.vrsave); | ||
314 | #endif | ||
262 | kvmppc_core_vcpu_load(vcpu, cpu); | 315 | kvmppc_core_vcpu_load(vcpu, cpu); |
263 | } | 316 | } |
264 | 317 | ||
265 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | 318 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) |
266 | { | 319 | { |
267 | kvmppc_core_vcpu_put(vcpu); | 320 | kvmppc_core_vcpu_put(vcpu); |
321 | #ifdef CONFIG_BOOKE | ||
322 | vcpu->arch.vrsave = mfspr(SPRN_VRSAVE); | ||
323 | #endif | ||
268 | } | 324 | } |
269 | 325 | ||
270 | int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, | 326 | int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, |
@@ -534,16 +590,54 @@ out: | |||
534 | return r; | 590 | return r; |
535 | } | 591 | } |
536 | 592 | ||
593 | static int kvm_vm_ioctl_get_pvinfo(struct kvm_ppc_pvinfo *pvinfo) | ||
594 | { | ||
595 | u32 inst_lis = 0x3c000000; | ||
596 | u32 inst_ori = 0x60000000; | ||
597 | u32 inst_nop = 0x60000000; | ||
598 | u32 inst_sc = 0x44000002; | ||
599 | u32 inst_imm_mask = 0xffff; | ||
600 | |||
601 | /* | ||
602 | * The hypercall to get into KVM from within guest context is as | ||
603 | * follows: | ||
604 | * | ||
605 | * lis r0, r0, KVM_SC_MAGIC_R0@h | ||
606 | * ori r0, KVM_SC_MAGIC_R0@l | ||
607 | * sc | ||
608 | * nop | ||
609 | */ | ||
610 | pvinfo->hcall[0] = inst_lis | ((KVM_SC_MAGIC_R0 >> 16) & inst_imm_mask); | ||
611 | pvinfo->hcall[1] = inst_ori | (KVM_SC_MAGIC_R0 & inst_imm_mask); | ||
612 | pvinfo->hcall[2] = inst_sc; | ||
613 | pvinfo->hcall[3] = inst_nop; | ||
614 | |||
615 | return 0; | ||
616 | } | ||
617 | |||
537 | long kvm_arch_vm_ioctl(struct file *filp, | 618 | long kvm_arch_vm_ioctl(struct file *filp, |
538 | unsigned int ioctl, unsigned long arg) | 619 | unsigned int ioctl, unsigned long arg) |
539 | { | 620 | { |
621 | void __user *argp = (void __user *)arg; | ||
540 | long r; | 622 | long r; |
541 | 623 | ||
542 | switch (ioctl) { | 624 | switch (ioctl) { |
625 | case KVM_PPC_GET_PVINFO: { | ||
626 | struct kvm_ppc_pvinfo pvinfo; | ||
627 | memset(&pvinfo, 0, sizeof(pvinfo)); | ||
628 | r = kvm_vm_ioctl_get_pvinfo(&pvinfo); | ||
629 | if (copy_to_user(argp, &pvinfo, sizeof(pvinfo))) { | ||
630 | r = -EFAULT; | ||
631 | goto out; | ||
632 | } | ||
633 | |||
634 | break; | ||
635 | } | ||
543 | default: | 636 | default: |
544 | r = -ENOTTY; | 637 | r = -ENOTTY; |
545 | } | 638 | } |
546 | 639 | ||
640 | out: | ||
547 | return r; | 641 | return r; |
548 | } | 642 | } |
549 | 643 | ||