diff options
Diffstat (limited to 'arch/powerpc/kvm/powerpc.c')
-rw-r--r-- | arch/powerpc/kvm/powerpc.c | 187 |
1 files changed, 163 insertions, 24 deletions
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 4d213b8b0fb5..70739a089560 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <asm/kvm_ppc.h> | 30 | #include <asm/kvm_ppc.h> |
31 | #include <asm/tlbflush.h> | 31 | #include <asm/tlbflush.h> |
32 | #include <asm/cputhreads.h> | 32 | #include <asm/cputhreads.h> |
33 | #include <asm/irqflags.h> | ||
33 | #include "timing.h" | 34 | #include "timing.h" |
34 | #include "../mm/mmu_decl.h" | 35 | #include "../mm/mmu_decl.h" |
35 | 36 | ||
@@ -38,8 +39,7 @@ | |||
38 | 39 | ||
39 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) | 40 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) |
40 | { | 41 | { |
41 | return !(v->arch.shared->msr & MSR_WE) || | 42 | return !!(v->arch.pending_exceptions) || |
42 | !!(v->arch.pending_exceptions) || | ||
43 | v->requests; | 43 | v->requests; |
44 | } | 44 | } |
45 | 45 | ||
@@ -48,6 +48,85 @@ int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) | |||
48 | return 1; | 48 | return 1; |
49 | } | 49 | } |
50 | 50 | ||
51 | #ifndef CONFIG_KVM_BOOK3S_64_HV | ||
52 | /* | ||
53 | * Common checks before entering the guest world. Call with interrupts | ||
54 | * disabled. | ||
55 | * | ||
56 | * returns: | ||
57 | * | ||
58 | * == 1 if we're ready to go into guest state | ||
59 | * <= 0 if we need to go back to the host with return value | ||
60 | */ | ||
61 | int kvmppc_prepare_to_enter(struct kvm_vcpu *vcpu) | ||
62 | { | ||
63 | int r = 1; | ||
64 | |||
65 | WARN_ON_ONCE(!irqs_disabled()); | ||
66 | while (true) { | ||
67 | if (need_resched()) { | ||
68 | local_irq_enable(); | ||
69 | cond_resched(); | ||
70 | local_irq_disable(); | ||
71 | continue; | ||
72 | } | ||
73 | |||
74 | if (signal_pending(current)) { | ||
75 | kvmppc_account_exit(vcpu, SIGNAL_EXITS); | ||
76 | vcpu->run->exit_reason = KVM_EXIT_INTR; | ||
77 | r = -EINTR; | ||
78 | break; | ||
79 | } | ||
80 | |||
81 | vcpu->mode = IN_GUEST_MODE; | ||
82 | |||
83 | /* | ||
84 | * Reading vcpu->requests must happen after setting vcpu->mode, | ||
85 | * so we don't miss a request because the requester sees | ||
86 | * OUTSIDE_GUEST_MODE and assumes we'll be checking requests | ||
87 | * before next entering the guest (and thus doesn't IPI). | ||
88 | */ | ||
89 | smp_mb(); | ||
90 | |||
91 | if (vcpu->requests) { | ||
92 | /* Make sure we process requests preemptable */ | ||
93 | local_irq_enable(); | ||
94 | trace_kvm_check_requests(vcpu); | ||
95 | r = kvmppc_core_check_requests(vcpu); | ||
96 | local_irq_disable(); | ||
97 | if (r > 0) | ||
98 | continue; | ||
99 | break; | ||
100 | } | ||
101 | |||
102 | if (kvmppc_core_prepare_to_enter(vcpu)) { | ||
103 | /* interrupts got enabled in between, so we | ||
104 | are back at square 1 */ | ||
105 | continue; | ||
106 | } | ||
107 | |||
108 | #ifdef CONFIG_PPC64 | ||
109 | /* lazy EE magic */ | ||
110 | hard_irq_disable(); | ||
111 | if (lazy_irq_pending()) { | ||
112 | /* Got an interrupt in between, try again */ | ||
113 | local_irq_enable(); | ||
114 | local_irq_disable(); | ||
115 | kvm_guest_exit(); | ||
116 | continue; | ||
117 | } | ||
118 | |||
119 | trace_hardirqs_on(); | ||
120 | #endif | ||
121 | |||
122 | kvm_guest_enter(); | ||
123 | break; | ||
124 | } | ||
125 | |||
126 | return r; | ||
127 | } | ||
128 | #endif /* CONFIG_KVM_BOOK3S_64_HV */ | ||
129 | |||
51 | int kvmppc_kvm_pv(struct kvm_vcpu *vcpu) | 130 | int kvmppc_kvm_pv(struct kvm_vcpu *vcpu) |
52 | { | 131 | { |
53 | int nr = kvmppc_get_gpr(vcpu, 11); | 132 | int nr = kvmppc_get_gpr(vcpu, 11); |
@@ -67,18 +146,18 @@ int kvmppc_kvm_pv(struct kvm_vcpu *vcpu) | |||
67 | } | 146 | } |
68 | 147 | ||
69 | switch (nr) { | 148 | switch (nr) { |
70 | case HC_VENDOR_KVM | KVM_HC_PPC_MAP_MAGIC_PAGE: | 149 | case KVM_HCALL_TOKEN(KVM_HC_PPC_MAP_MAGIC_PAGE): |
71 | { | 150 | { |
72 | vcpu->arch.magic_page_pa = param1; | 151 | vcpu->arch.magic_page_pa = param1; |
73 | vcpu->arch.magic_page_ea = param2; | 152 | vcpu->arch.magic_page_ea = param2; |
74 | 153 | ||
75 | r2 = KVM_MAGIC_FEAT_SR | KVM_MAGIC_FEAT_MAS0_TO_SPRG7; | 154 | r2 = KVM_MAGIC_FEAT_SR | KVM_MAGIC_FEAT_MAS0_TO_SPRG7; |
76 | 155 | ||
77 | r = HC_EV_SUCCESS; | 156 | r = EV_SUCCESS; |
78 | break; | 157 | break; |
79 | } | 158 | } |
80 | case HC_VENDOR_KVM | KVM_HC_FEATURES: | 159 | case KVM_HCALL_TOKEN(KVM_HC_FEATURES): |
81 | r = HC_EV_SUCCESS; | 160 | r = EV_SUCCESS; |
82 | #if defined(CONFIG_PPC_BOOK3S) || defined(CONFIG_KVM_E500V2) | 161 | #if defined(CONFIG_PPC_BOOK3S) || defined(CONFIG_KVM_E500V2) |
83 | /* XXX Missing magic page on 44x */ | 162 | /* XXX Missing magic page on 44x */ |
84 | r2 |= (1 << KVM_FEATURE_MAGIC_PAGE); | 163 | r2 |= (1 << KVM_FEATURE_MAGIC_PAGE); |
@@ -86,8 +165,13 @@ int kvmppc_kvm_pv(struct kvm_vcpu *vcpu) | |||
86 | 165 | ||
87 | /* Second return value is in r4 */ | 166 | /* Second return value is in r4 */ |
88 | break; | 167 | break; |
168 | case EV_HCALL_TOKEN(EV_IDLE): | ||
169 | r = EV_SUCCESS; | ||
170 | kvm_vcpu_block(vcpu); | ||
171 | clear_bit(KVM_REQ_UNHALT, &vcpu->requests); | ||
172 | break; | ||
89 | default: | 173 | default: |
90 | r = HC_EV_UNIMPLEMENTED; | 174 | r = EV_UNIMPLEMENTED; |
91 | break; | 175 | break; |
92 | } | 176 | } |
93 | 177 | ||
@@ -220,6 +304,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
220 | switch (ext) { | 304 | switch (ext) { |
221 | #ifdef CONFIG_BOOKE | 305 | #ifdef CONFIG_BOOKE |
222 | case KVM_CAP_PPC_BOOKE_SREGS: | 306 | case KVM_CAP_PPC_BOOKE_SREGS: |
307 | case KVM_CAP_PPC_BOOKE_WATCHDOG: | ||
223 | #else | 308 | #else |
224 | case KVM_CAP_PPC_SEGSTATE: | 309 | case KVM_CAP_PPC_SEGSTATE: |
225 | case KVM_CAP_PPC_HIOR: | 310 | case KVM_CAP_PPC_HIOR: |
@@ -229,6 +314,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
229 | case KVM_CAP_PPC_IRQ_LEVEL: | 314 | case KVM_CAP_PPC_IRQ_LEVEL: |
230 | case KVM_CAP_ENABLE_CAP: | 315 | case KVM_CAP_ENABLE_CAP: |
231 | case KVM_CAP_ONE_REG: | 316 | case KVM_CAP_ONE_REG: |
317 | case KVM_CAP_IOEVENTFD: | ||
232 | r = 1; | 318 | r = 1; |
233 | break; | 319 | break; |
234 | #ifndef CONFIG_KVM_BOOK3S_64_HV | 320 | #ifndef CONFIG_KVM_BOOK3S_64_HV |
@@ -260,10 +346,22 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
260 | if (cpu_has_feature(CPU_FTR_ARCH_201)) | 346 | if (cpu_has_feature(CPU_FTR_ARCH_201)) |
261 | r = 2; | 347 | r = 2; |
262 | break; | 348 | break; |
349 | #endif | ||
263 | case KVM_CAP_SYNC_MMU: | 350 | case KVM_CAP_SYNC_MMU: |
351 | #ifdef CONFIG_KVM_BOOK3S_64_HV | ||
264 | r = cpu_has_feature(CPU_FTR_ARCH_206) ? 1 : 0; | 352 | r = cpu_has_feature(CPU_FTR_ARCH_206) ? 1 : 0; |
353 | #elif defined(KVM_ARCH_WANT_MMU_NOTIFIER) | ||
354 | r = 1; | ||
355 | #else | ||
356 | r = 0; | ||
357 | break; | ||
358 | #endif | ||
359 | #ifdef CONFIG_KVM_BOOK3S_64_HV | ||
360 | case KVM_CAP_PPC_HTAB_FD: | ||
361 | r = 1; | ||
265 | break; | 362 | break; |
266 | #endif | 363 | #endif |
364 | break; | ||
267 | case KVM_CAP_NR_VCPUS: | 365 | case KVM_CAP_NR_VCPUS: |
268 | /* | 366 | /* |
269 | * Recommending a number of CPUs is somewhat arbitrary; we | 367 | * Recommending a number of CPUs is somewhat arbitrary; we |
@@ -302,19 +400,12 @@ long kvm_arch_dev_ioctl(struct file *filp, | |||
302 | void kvm_arch_free_memslot(struct kvm_memory_slot *free, | 400 | void kvm_arch_free_memslot(struct kvm_memory_slot *free, |
303 | struct kvm_memory_slot *dont) | 401 | struct kvm_memory_slot *dont) |
304 | { | 402 | { |
305 | if (!dont || free->arch.rmap != dont->arch.rmap) { | 403 | kvmppc_core_free_memslot(free, dont); |
306 | vfree(free->arch.rmap); | ||
307 | free->arch.rmap = NULL; | ||
308 | } | ||
309 | } | 404 | } |
310 | 405 | ||
311 | int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) | 406 | int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) |
312 | { | 407 | { |
313 | slot->arch.rmap = vzalloc(npages * sizeof(*slot->arch.rmap)); | 408 | return kvmppc_core_create_memslot(slot, npages); |
314 | if (!slot->arch.rmap) | ||
315 | return -ENOMEM; | ||
316 | |||
317 | return 0; | ||
318 | } | 409 | } |
319 | 410 | ||
320 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | 411 | int kvm_arch_prepare_memory_region(struct kvm *kvm, |
@@ -323,7 +414,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, | |||
323 | struct kvm_userspace_memory_region *mem, | 414 | struct kvm_userspace_memory_region *mem, |
324 | int user_alloc) | 415 | int user_alloc) |
325 | { | 416 | { |
326 | return kvmppc_core_prepare_memory_region(kvm, mem); | 417 | return kvmppc_core_prepare_memory_region(kvm, memslot, mem); |
327 | } | 418 | } |
328 | 419 | ||
329 | void kvm_arch_commit_memory_region(struct kvm *kvm, | 420 | void kvm_arch_commit_memory_region(struct kvm *kvm, |
@@ -331,7 +422,7 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, | |||
331 | struct kvm_memory_slot old, | 422 | struct kvm_memory_slot old, |
332 | int user_alloc) | 423 | int user_alloc) |
333 | { | 424 | { |
334 | kvmppc_core_commit_memory_region(kvm, mem); | 425 | kvmppc_core_commit_memory_region(kvm, mem, old); |
335 | } | 426 | } |
336 | 427 | ||
337 | void kvm_arch_flush_shadow_all(struct kvm *kvm) | 428 | void kvm_arch_flush_shadow_all(struct kvm *kvm) |
@@ -341,6 +432,7 @@ void kvm_arch_flush_shadow_all(struct kvm *kvm) | |||
341 | void kvm_arch_flush_shadow_memslot(struct kvm *kvm, | 432 | void kvm_arch_flush_shadow_memslot(struct kvm *kvm, |
342 | struct kvm_memory_slot *slot) | 433 | struct kvm_memory_slot *slot) |
343 | { | 434 | { |
435 | kvmppc_core_flush_memslot(kvm, slot); | ||
344 | } | 436 | } |
345 | 437 | ||
346 | struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) | 438 | struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) |
@@ -354,6 +446,11 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) | |||
354 | return vcpu; | 446 | return vcpu; |
355 | } | 447 | } |
356 | 448 | ||
449 | int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) | ||
450 | { | ||
451 | return 0; | ||
452 | } | ||
453 | |||
357 | void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu) | 454 | void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu) |
358 | { | 455 | { |
359 | /* Make sure we're not using the vcpu anymore */ | 456 | /* Make sure we're not using the vcpu anymore */ |
@@ -390,6 +487,8 @@ enum hrtimer_restart kvmppc_decrementer_wakeup(struct hrtimer *timer) | |||
390 | 487 | ||
391 | int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | 488 | int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) |
392 | { | 489 | { |
490 | int ret; | ||
491 | |||
393 | hrtimer_init(&vcpu->arch.dec_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); | 492 | hrtimer_init(&vcpu->arch.dec_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); |
394 | tasklet_init(&vcpu->arch.tasklet, kvmppc_decrementer_func, (ulong)vcpu); | 493 | tasklet_init(&vcpu->arch.tasklet, kvmppc_decrementer_func, (ulong)vcpu); |
395 | vcpu->arch.dec_timer.function = kvmppc_decrementer_wakeup; | 494 | vcpu->arch.dec_timer.function = kvmppc_decrementer_wakeup; |
@@ -398,13 +497,14 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | |||
398 | #ifdef CONFIG_KVM_EXIT_TIMING | 497 | #ifdef CONFIG_KVM_EXIT_TIMING |
399 | mutex_init(&vcpu->arch.exit_timing_lock); | 498 | mutex_init(&vcpu->arch.exit_timing_lock); |
400 | #endif | 499 | #endif |
401 | 500 | ret = kvmppc_subarch_vcpu_init(vcpu); | |
402 | return 0; | 501 | return ret; |
403 | } | 502 | } |
404 | 503 | ||
405 | void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) | 504 | void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) |
406 | { | 505 | { |
407 | kvmppc_mmu_destroy(vcpu); | 506 | kvmppc_mmu_destroy(vcpu); |
507 | kvmppc_subarch_vcpu_uninit(vcpu); | ||
408 | } | 508 | } |
409 | 509 | ||
410 | void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | 510 | void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) |
@@ -420,7 +520,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
420 | mtspr(SPRN_VRSAVE, vcpu->arch.vrsave); | 520 | mtspr(SPRN_VRSAVE, vcpu->arch.vrsave); |
421 | #endif | 521 | #endif |
422 | kvmppc_core_vcpu_load(vcpu, cpu); | 522 | kvmppc_core_vcpu_load(vcpu, cpu); |
423 | vcpu->cpu = smp_processor_id(); | ||
424 | } | 523 | } |
425 | 524 | ||
426 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | 525 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) |
@@ -429,7 +528,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | |||
429 | #ifdef CONFIG_BOOKE | 528 | #ifdef CONFIG_BOOKE |
430 | vcpu->arch.vrsave = mfspr(SPRN_VRSAVE); | 529 | vcpu->arch.vrsave = mfspr(SPRN_VRSAVE); |
431 | #endif | 530 | #endif |
432 | vcpu->cpu = -1; | ||
433 | } | 531 | } |
434 | 532 | ||
435 | int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, | 533 | int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, |
@@ -527,6 +625,13 @@ int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
527 | vcpu->mmio_is_write = 0; | 625 | vcpu->mmio_is_write = 0; |
528 | vcpu->arch.mmio_sign_extend = 0; | 626 | vcpu->arch.mmio_sign_extend = 0; |
529 | 627 | ||
628 | if (!kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, run->mmio.phys_addr, | ||
629 | bytes, &run->mmio.data)) { | ||
630 | kvmppc_complete_mmio_load(vcpu, run); | ||
631 | vcpu->mmio_needed = 0; | ||
632 | return EMULATE_DONE; | ||
633 | } | ||
634 | |||
530 | return EMULATE_DO_MMIO; | 635 | return EMULATE_DO_MMIO; |
531 | } | 636 | } |
532 | 637 | ||
@@ -536,8 +641,8 @@ int kvmppc_handle_loads(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
536 | { | 641 | { |
537 | int r; | 642 | int r; |
538 | 643 | ||
539 | r = kvmppc_handle_load(run, vcpu, rt, bytes, is_bigendian); | ||
540 | vcpu->arch.mmio_sign_extend = 1; | 644 | vcpu->arch.mmio_sign_extend = 1; |
645 | r = kvmppc_handle_load(run, vcpu, rt, bytes, is_bigendian); | ||
541 | 646 | ||
542 | return r; | 647 | return r; |
543 | } | 648 | } |
@@ -575,6 +680,13 @@ int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
575 | } | 680 | } |
576 | } | 681 | } |
577 | 682 | ||
683 | if (!kvm_io_bus_write(vcpu->kvm, KVM_MMIO_BUS, run->mmio.phys_addr, | ||
684 | bytes, &run->mmio.data)) { | ||
685 | kvmppc_complete_mmio_load(vcpu, run); | ||
686 | vcpu->mmio_needed = 0; | ||
687 | return EMULATE_DONE; | ||
688 | } | ||
689 | |||
578 | return EMULATE_DO_MMIO; | 690 | return EMULATE_DO_MMIO; |
579 | } | 691 | } |
580 | 692 | ||
@@ -649,6 +761,12 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, | |||
649 | r = 0; | 761 | r = 0; |
650 | vcpu->arch.papr_enabled = true; | 762 | vcpu->arch.papr_enabled = true; |
651 | break; | 763 | break; |
764 | #ifdef CONFIG_BOOKE | ||
765 | case KVM_CAP_PPC_BOOKE_WATCHDOG: | ||
766 | r = 0; | ||
767 | vcpu->arch.watchdog_enabled = true; | ||
768 | break; | ||
769 | #endif | ||
652 | #if defined(CONFIG_KVM_E500V2) || defined(CONFIG_KVM_E500MC) | 770 | #if defined(CONFIG_KVM_E500V2) || defined(CONFIG_KVM_E500MC) |
653 | case KVM_CAP_SW_TLB: { | 771 | case KVM_CAP_SW_TLB: { |
654 | struct kvm_config_tlb cfg; | 772 | struct kvm_config_tlb cfg; |
@@ -751,9 +869,16 @@ int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf) | |||
751 | 869 | ||
752 | static int kvm_vm_ioctl_get_pvinfo(struct kvm_ppc_pvinfo *pvinfo) | 870 | static int kvm_vm_ioctl_get_pvinfo(struct kvm_ppc_pvinfo *pvinfo) |
753 | { | 871 | { |
872 | u32 inst_nop = 0x60000000; | ||
873 | #ifdef CONFIG_KVM_BOOKE_HV | ||
874 | u32 inst_sc1 = 0x44000022; | ||
875 | pvinfo->hcall[0] = inst_sc1; | ||
876 | pvinfo->hcall[1] = inst_nop; | ||
877 | pvinfo->hcall[2] = inst_nop; | ||
878 | pvinfo->hcall[3] = inst_nop; | ||
879 | #else | ||
754 | u32 inst_lis = 0x3c000000; | 880 | u32 inst_lis = 0x3c000000; |
755 | u32 inst_ori = 0x60000000; | 881 | u32 inst_ori = 0x60000000; |
756 | u32 inst_nop = 0x60000000; | ||
757 | u32 inst_sc = 0x44000002; | 882 | u32 inst_sc = 0x44000002; |
758 | u32 inst_imm_mask = 0xffff; | 883 | u32 inst_imm_mask = 0xffff; |
759 | 884 | ||
@@ -770,6 +895,9 @@ static int kvm_vm_ioctl_get_pvinfo(struct kvm_ppc_pvinfo *pvinfo) | |||
770 | pvinfo->hcall[1] = inst_ori | (KVM_SC_MAGIC_R0 & inst_imm_mask); | 895 | pvinfo->hcall[1] = inst_ori | (KVM_SC_MAGIC_R0 & inst_imm_mask); |
771 | pvinfo->hcall[2] = inst_sc; | 896 | pvinfo->hcall[2] = inst_sc; |
772 | pvinfo->hcall[3] = inst_nop; | 897 | pvinfo->hcall[3] = inst_nop; |
898 | #endif | ||
899 | |||
900 | pvinfo->flags = KVM_PPC_PVINFO_FLAGS_EV_IDLE; | ||
773 | 901 | ||
774 | return 0; | 902 | return 0; |
775 | } | 903 | } |
@@ -832,6 +960,17 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
832 | r = 0; | 960 | r = 0; |
833 | break; | 961 | break; |
834 | } | 962 | } |
963 | |||
964 | case KVM_PPC_GET_HTAB_FD: { | ||
965 | struct kvm *kvm = filp->private_data; | ||
966 | struct kvm_get_htab_fd ghf; | ||
967 | |||
968 | r = -EFAULT; | ||
969 | if (copy_from_user(&ghf, argp, sizeof(ghf))) | ||
970 | break; | ||
971 | r = kvm_vm_ioctl_get_htab_fd(kvm, &ghf); | ||
972 | break; | ||
973 | } | ||
835 | #endif /* CONFIG_KVM_BOOK3S_64_HV */ | 974 | #endif /* CONFIG_KVM_BOOK3S_64_HV */ |
836 | 975 | ||
837 | #ifdef CONFIG_PPC_BOOK3S_64 | 976 | #ifdef CONFIG_PPC_BOOK3S_64 |