1bbf45ba5SHollis Blanchard /* 2bbf45ba5SHollis Blanchard * This program is free software; you can redistribute it and/or modify 3bbf45ba5SHollis Blanchard * it under the terms of the GNU General Public License, version 2, as 4bbf45ba5SHollis Blanchard * published by the Free Software Foundation. 5bbf45ba5SHollis Blanchard * 6bbf45ba5SHollis Blanchard * This program is distributed in the hope that it will be useful, 7bbf45ba5SHollis Blanchard * but WITHOUT ANY WARRANTY; without even the implied warranty of 8bbf45ba5SHollis Blanchard * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9bbf45ba5SHollis Blanchard * GNU General Public License for more details. 10bbf45ba5SHollis Blanchard * 11bbf45ba5SHollis Blanchard * You should have received a copy of the GNU General Public License 12bbf45ba5SHollis Blanchard * along with this program; if not, write to the Free Software 13bbf45ba5SHollis Blanchard * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 14bbf45ba5SHollis Blanchard * 15bbf45ba5SHollis Blanchard * Copyright IBM Corp. 2007 16bbf45ba5SHollis Blanchard * 17bbf45ba5SHollis Blanchard * Authors: Hollis Blanchard <hollisb@us.ibm.com> 18bbf45ba5SHollis Blanchard * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com> 19bbf45ba5SHollis Blanchard */ 20bbf45ba5SHollis Blanchard 21bbf45ba5SHollis Blanchard #include <linux/errno.h> 22bbf45ba5SHollis Blanchard #include <linux/err.h> 23bbf45ba5SHollis Blanchard #include <linux/kvm_host.h> 24bbf45ba5SHollis Blanchard #include <linux/vmalloc.h> 25544c6761SAlexander Graf #include <linux/hrtimer.h> 26bbf45ba5SHollis Blanchard #include <linux/fs.h> 275a0e3ad6STejun Heo #include <linux/slab.h> 28bbf45ba5SHollis Blanchard #include <asm/cputable.h> 29bbf45ba5SHollis Blanchard #include <asm/uaccess.h> 30bbf45ba5SHollis Blanchard #include <asm/kvm_ppc.h> 3183aae4a8SHollis Blanchard #include <asm/tlbflush.h> 32371fefd6SPaul Mackerras #include <asm/cputhreads.h> 3373e75b41SHollis Blanchard #include "timing.h" 34fad7b9b5SPaul Mackerras #include "../mm/mmu_decl.h" 35bbf45ba5SHollis Blanchard 3646f43c6eSMarcelo Tosatti #define CREATE_TRACE_POINTS 3746f43c6eSMarcelo Tosatti #include "trace.h" 3846f43c6eSMarcelo Tosatti 39bbf45ba5SHollis Blanchard int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) 40bbf45ba5SHollis Blanchard { 41666e7252SAlexander Graf return !(v->arch.shared->msr & MSR_WE) || 42dfd4d47eSScott Wood !!(v->arch.pending_exceptions) || 43dfd4d47eSScott Wood v->requests; 44bbf45ba5SHollis Blanchard } 45bbf45ba5SHollis Blanchard 462a342ed5SAlexander Graf int kvmppc_kvm_pv(struct kvm_vcpu *vcpu) 472a342ed5SAlexander Graf { 482a342ed5SAlexander Graf int nr = kvmppc_get_gpr(vcpu, 11); 492a342ed5SAlexander Graf int r; 502a342ed5SAlexander Graf unsigned long __maybe_unused param1 = kvmppc_get_gpr(vcpu, 3); 512a342ed5SAlexander Graf unsigned long __maybe_unused param2 = kvmppc_get_gpr(vcpu, 4); 522a342ed5SAlexander Graf unsigned long __maybe_unused param3 = kvmppc_get_gpr(vcpu, 5); 532a342ed5SAlexander Graf unsigned long __maybe_unused param4 = kvmppc_get_gpr(vcpu, 6); 542a342ed5SAlexander Graf unsigned long r2 = 0; 552a342ed5SAlexander Graf 562a342ed5SAlexander Graf if (!(vcpu->arch.shared->msr & MSR_SF)) { 572a342ed5SAlexander Graf /* 32 bit mode */ 582a342ed5SAlexander Graf param1 &= 0xffffffff; 592a342ed5SAlexander Graf param2 &= 0xffffffff; 602a342ed5SAlexander Graf param3 &= 0xffffffff; 612a342ed5SAlexander Graf param4 &= 0xffffffff; 622a342ed5SAlexander Graf } 632a342ed5SAlexander Graf 642a342ed5SAlexander Graf switch (nr) { 655fc87407SAlexander Graf case HC_VENDOR_KVM | KVM_HC_PPC_MAP_MAGIC_PAGE: 665fc87407SAlexander Graf { 675fc87407SAlexander Graf vcpu->arch.magic_page_pa = param1; 685fc87407SAlexander Graf vcpu->arch.magic_page_ea = param2; 695fc87407SAlexander Graf 70b5904972SScott Wood r2 = KVM_MAGIC_FEAT_SR | KVM_MAGIC_FEAT_MAS0_TO_SPRG7; 717508e16cSAlexander Graf 725fc87407SAlexander Graf r = HC_EV_SUCCESS; 735fc87407SAlexander Graf break; 745fc87407SAlexander Graf } 752a342ed5SAlexander Graf case HC_VENDOR_KVM | KVM_HC_FEATURES: 762a342ed5SAlexander Graf r = HC_EV_SUCCESS; 77a4cd8b23SScott Wood #if defined(CONFIG_PPC_BOOK3S) || defined(CONFIG_KVM_E500) 78a4cd8b23SScott Wood /* XXX Missing magic page on 44x */ 795fc87407SAlexander Graf r2 |= (1 << KVM_FEATURE_MAGIC_PAGE); 805fc87407SAlexander Graf #endif 812a342ed5SAlexander Graf 822a342ed5SAlexander Graf /* Second return value is in r4 */ 832a342ed5SAlexander Graf break; 842a342ed5SAlexander Graf default: 852a342ed5SAlexander Graf r = HC_EV_UNIMPLEMENTED; 862a342ed5SAlexander Graf break; 872a342ed5SAlexander Graf } 882a342ed5SAlexander Graf 897508e16cSAlexander Graf kvmppc_set_gpr(vcpu, 4, r2); 907508e16cSAlexander Graf 912a342ed5SAlexander Graf return r; 922a342ed5SAlexander Graf } 93bbf45ba5SHollis Blanchard 94af8f38b3SAlexander Graf int kvmppc_sanity_check(struct kvm_vcpu *vcpu) 95af8f38b3SAlexander Graf { 96af8f38b3SAlexander Graf int r = false; 97af8f38b3SAlexander Graf 98af8f38b3SAlexander Graf /* We have to know what CPU to virtualize */ 99af8f38b3SAlexander Graf if (!vcpu->arch.pvr) 100af8f38b3SAlexander Graf goto out; 101af8f38b3SAlexander Graf 102af8f38b3SAlexander Graf /* PAPR only works with book3s_64 */ 103af8f38b3SAlexander Graf if ((vcpu->arch.cpu_type != KVM_CPU_3S_64) && vcpu->arch.papr_enabled) 104af8f38b3SAlexander Graf goto out; 105af8f38b3SAlexander Graf 106af8f38b3SAlexander Graf #ifdef CONFIG_KVM_BOOK3S_64_HV 107af8f38b3SAlexander Graf /* HV KVM can only do PAPR mode for now */ 108af8f38b3SAlexander Graf if (!vcpu->arch.papr_enabled) 109af8f38b3SAlexander Graf goto out; 110af8f38b3SAlexander Graf #endif 111af8f38b3SAlexander Graf 112af8f38b3SAlexander Graf r = true; 113af8f38b3SAlexander Graf 114af8f38b3SAlexander Graf out: 115af8f38b3SAlexander Graf vcpu->arch.sane = r; 116af8f38b3SAlexander Graf return r ? 0 : -EINVAL; 117af8f38b3SAlexander Graf } 118af8f38b3SAlexander Graf 119bbf45ba5SHollis Blanchard int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu) 120bbf45ba5SHollis Blanchard { 121bbf45ba5SHollis Blanchard enum emulation_result er; 122bbf45ba5SHollis Blanchard int r; 123bbf45ba5SHollis Blanchard 124bbf45ba5SHollis Blanchard er = kvmppc_emulate_instruction(run, vcpu); 125bbf45ba5SHollis Blanchard switch (er) { 126bbf45ba5SHollis Blanchard case EMULATE_DONE: 127bbf45ba5SHollis Blanchard /* Future optimization: only reload non-volatiles if they were 128bbf45ba5SHollis Blanchard * actually modified. */ 129bbf45ba5SHollis Blanchard r = RESUME_GUEST_NV; 130bbf45ba5SHollis Blanchard break; 131bbf45ba5SHollis Blanchard case EMULATE_DO_MMIO: 132bbf45ba5SHollis Blanchard run->exit_reason = KVM_EXIT_MMIO; 133bbf45ba5SHollis Blanchard /* We must reload nonvolatiles because "update" load/store 134bbf45ba5SHollis Blanchard * instructions modify register state. */ 135bbf45ba5SHollis Blanchard /* Future optimization: only reload non-volatiles if they were 136bbf45ba5SHollis Blanchard * actually modified. */ 137bbf45ba5SHollis Blanchard r = RESUME_HOST_NV; 138bbf45ba5SHollis Blanchard break; 139bbf45ba5SHollis Blanchard case EMULATE_FAIL: 140bbf45ba5SHollis Blanchard /* XXX Deliver Program interrupt to guest. */ 141bbf45ba5SHollis Blanchard printk(KERN_EMERG "%s: emulation failed (%08x)\n", __func__, 142c7f38f46SAlexander Graf kvmppc_get_last_inst(vcpu)); 143bbf45ba5SHollis Blanchard r = RESUME_HOST; 144bbf45ba5SHollis Blanchard break; 145bbf45ba5SHollis Blanchard default: 146bbf45ba5SHollis Blanchard BUG(); 147bbf45ba5SHollis Blanchard } 148bbf45ba5SHollis Blanchard 149bbf45ba5SHollis Blanchard return r; 150bbf45ba5SHollis Blanchard } 151bbf45ba5SHollis Blanchard 15210474ae8SAlexander Graf int kvm_arch_hardware_enable(void *garbage) 153bbf45ba5SHollis Blanchard { 15410474ae8SAlexander Graf return 0; 155bbf45ba5SHollis Blanchard } 156bbf45ba5SHollis Blanchard 157bbf45ba5SHollis Blanchard void kvm_arch_hardware_disable(void *garbage) 158bbf45ba5SHollis Blanchard { 159bbf45ba5SHollis Blanchard } 160bbf45ba5SHollis Blanchard 161bbf45ba5SHollis Blanchard int kvm_arch_hardware_setup(void) 162bbf45ba5SHollis Blanchard { 163bbf45ba5SHollis Blanchard return 0; 164bbf45ba5SHollis Blanchard } 165bbf45ba5SHollis Blanchard 166bbf45ba5SHollis Blanchard void kvm_arch_hardware_unsetup(void) 167bbf45ba5SHollis Blanchard { 168bbf45ba5SHollis Blanchard } 169bbf45ba5SHollis Blanchard 170bbf45ba5SHollis Blanchard void kvm_arch_check_processor_compat(void *rtn) 171bbf45ba5SHollis Blanchard { 1729dd921cfSHollis Blanchard *(int *)rtn = kvmppc_core_check_processor_compat(); 173bbf45ba5SHollis Blanchard } 174bbf45ba5SHollis Blanchard 175e08b9637SCarsten Otte int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) 176bbf45ba5SHollis Blanchard { 177e08b9637SCarsten Otte if (type) 178e08b9637SCarsten Otte return -EINVAL; 179e08b9637SCarsten Otte 180f9e0554dSPaul Mackerras return kvmppc_core_init_vm(kvm); 181bbf45ba5SHollis Blanchard } 182bbf45ba5SHollis Blanchard 183d89f5effSJan Kiszka void kvm_arch_destroy_vm(struct kvm *kvm) 184bbf45ba5SHollis Blanchard { 185bbf45ba5SHollis Blanchard unsigned int i; 186988a2caeSGleb Natapov struct kvm_vcpu *vcpu; 187bbf45ba5SHollis Blanchard 188988a2caeSGleb Natapov kvm_for_each_vcpu(i, vcpu, kvm) 189988a2caeSGleb Natapov kvm_arch_vcpu_free(vcpu); 190988a2caeSGleb Natapov 191988a2caeSGleb Natapov mutex_lock(&kvm->lock); 192988a2caeSGleb Natapov for (i = 0; i < atomic_read(&kvm->online_vcpus); i++) 193bbf45ba5SHollis Blanchard kvm->vcpus[i] = NULL; 194988a2caeSGleb Natapov 195988a2caeSGleb Natapov atomic_set(&kvm->online_vcpus, 0); 196f9e0554dSPaul Mackerras 197f9e0554dSPaul Mackerras kvmppc_core_destroy_vm(kvm); 198f9e0554dSPaul Mackerras 199988a2caeSGleb Natapov mutex_unlock(&kvm->lock); 200bbf45ba5SHollis Blanchard } 201bbf45ba5SHollis Blanchard 202ad8ba2cdSSheng Yang void kvm_arch_sync_events(struct kvm *kvm) 203ad8ba2cdSSheng Yang { 204ad8ba2cdSSheng Yang } 205ad8ba2cdSSheng Yang 206bbf45ba5SHollis Blanchard int kvm_dev_ioctl_check_extension(long ext) 207bbf45ba5SHollis Blanchard { 208bbf45ba5SHollis Blanchard int r; 209bbf45ba5SHollis Blanchard 210bbf45ba5SHollis Blanchard switch (ext) { 2115ce941eeSScott Wood #ifdef CONFIG_BOOKE 2125ce941eeSScott Wood case KVM_CAP_PPC_BOOKE_SREGS: 2135ce941eeSScott Wood #else 214e15a1137SAlexander Graf case KVM_CAP_PPC_SEGSTATE: 215930b412aSAlexander Graf case KVM_CAP_PPC_PAPR: 2165ce941eeSScott Wood #endif 21718978768SAlexander Graf case KVM_CAP_PPC_UNSET_IRQ: 2187b4203e8SAlexander Graf case KVM_CAP_PPC_IRQ_LEVEL: 21971fbfd5fSAlexander Graf case KVM_CAP_ENABLE_CAP: 220de56a948SPaul Mackerras r = 1; 221de56a948SPaul Mackerras break; 222de56a948SPaul Mackerras #ifndef CONFIG_KVM_BOOK3S_64_HV 223de56a948SPaul Mackerras case KVM_CAP_PPC_PAIRED_SINGLES: 224ad0a048bSAlexander Graf case KVM_CAP_PPC_OSI: 22515711e9cSAlexander Graf case KVM_CAP_PPC_GET_PVINFO: 226dc83b8bcSScott Wood #ifdef CONFIG_KVM_E500 227dc83b8bcSScott Wood case KVM_CAP_SW_TLB: 228dc83b8bcSScott Wood #endif 229e15a1137SAlexander Graf r = 1; 230e15a1137SAlexander Graf break; 231588968b6SLaurent Vivier case KVM_CAP_COALESCED_MMIO: 232588968b6SLaurent Vivier r = KVM_COALESCED_MMIO_PAGE_OFFSET; 233588968b6SLaurent Vivier break; 234de56a948SPaul Mackerras #endif 23554738c09SDavid Gibson #ifdef CONFIG_KVM_BOOK3S_64_HV 23654738c09SDavid Gibson case KVM_CAP_SPAPR_TCE: 23754738c09SDavid Gibson r = 1; 23854738c09SDavid Gibson break; 239371fefd6SPaul Mackerras case KVM_CAP_PPC_SMT: 240371fefd6SPaul Mackerras r = threads_per_core; 241371fefd6SPaul Mackerras break; 242aa04b4ccSPaul Mackerras case KVM_CAP_PPC_RMA: 243aa04b4ccSPaul Mackerras r = 1; 2449e368f29SPaul Mackerras /* PPC970 requires an RMA */ 2459e368f29SPaul Mackerras if (cpu_has_feature(CPU_FTR_ARCH_201)) 2469e368f29SPaul Mackerras r = 2; 247aa04b4ccSPaul Mackerras break; 248*342d3db7SPaul Mackerras case KVM_CAP_SYNC_MMU: 249*342d3db7SPaul Mackerras r = cpu_has_feature(CPU_FTR_ARCH_206) ? 1 : 0; 250*342d3db7SPaul Mackerras break; 25154738c09SDavid Gibson #endif 252bbf45ba5SHollis Blanchard default: 253bbf45ba5SHollis Blanchard r = 0; 254bbf45ba5SHollis Blanchard break; 255bbf45ba5SHollis Blanchard } 256bbf45ba5SHollis Blanchard return r; 257bbf45ba5SHollis Blanchard 258bbf45ba5SHollis Blanchard } 259bbf45ba5SHollis Blanchard 260bbf45ba5SHollis Blanchard long kvm_arch_dev_ioctl(struct file *filp, 261bbf45ba5SHollis Blanchard unsigned int ioctl, unsigned long arg) 262bbf45ba5SHollis Blanchard { 263bbf45ba5SHollis Blanchard return -EINVAL; 264bbf45ba5SHollis Blanchard } 265bbf45ba5SHollis Blanchard 266f7784b8eSMarcelo Tosatti int kvm_arch_prepare_memory_region(struct kvm *kvm, 267f7784b8eSMarcelo Tosatti struct kvm_memory_slot *memslot, 268bbf45ba5SHollis Blanchard struct kvm_memory_slot old, 269f7784b8eSMarcelo Tosatti struct kvm_userspace_memory_region *mem, 270bbf45ba5SHollis Blanchard int user_alloc) 271bbf45ba5SHollis Blanchard { 272f9e0554dSPaul Mackerras return kvmppc_core_prepare_memory_region(kvm, mem); 273bbf45ba5SHollis Blanchard } 274bbf45ba5SHollis Blanchard 275f7784b8eSMarcelo Tosatti void kvm_arch_commit_memory_region(struct kvm *kvm, 276f7784b8eSMarcelo Tosatti struct kvm_userspace_memory_region *mem, 277f7784b8eSMarcelo Tosatti struct kvm_memory_slot old, 278f7784b8eSMarcelo Tosatti int user_alloc) 279f7784b8eSMarcelo Tosatti { 280f9e0554dSPaul Mackerras kvmppc_core_commit_memory_region(kvm, mem); 281f7784b8eSMarcelo Tosatti } 282f7784b8eSMarcelo Tosatti 283f7784b8eSMarcelo Tosatti 28434d4cb8fSMarcelo Tosatti void kvm_arch_flush_shadow(struct kvm *kvm) 28534d4cb8fSMarcelo Tosatti { 28634d4cb8fSMarcelo Tosatti } 28734d4cb8fSMarcelo Tosatti 288bbf45ba5SHollis Blanchard struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) 289bbf45ba5SHollis Blanchard { 29073e75b41SHollis Blanchard struct kvm_vcpu *vcpu; 29173e75b41SHollis Blanchard vcpu = kvmppc_core_vcpu_create(kvm, id); 29219ccb76aSPaul Mackerras vcpu->arch.wqp = &vcpu->wq; 29306056bfbSWei Yongjun if (!IS_ERR(vcpu)) 29473e75b41SHollis Blanchard kvmppc_create_vcpu_debugfs(vcpu, id); 29573e75b41SHollis Blanchard return vcpu; 296bbf45ba5SHollis Blanchard } 297bbf45ba5SHollis Blanchard 298bbf45ba5SHollis Blanchard void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu) 299bbf45ba5SHollis Blanchard { 300a595405dSAlexander Graf /* Make sure we're not using the vcpu anymore */ 301a595405dSAlexander Graf hrtimer_cancel(&vcpu->arch.dec_timer); 302a595405dSAlexander Graf tasklet_kill(&vcpu->arch.tasklet); 303a595405dSAlexander Graf 30473e75b41SHollis Blanchard kvmppc_remove_vcpu_debugfs(vcpu); 305db93f574SHollis Blanchard kvmppc_core_vcpu_free(vcpu); 306bbf45ba5SHollis Blanchard } 307bbf45ba5SHollis Blanchard 308bbf45ba5SHollis Blanchard void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) 309bbf45ba5SHollis Blanchard { 310bbf45ba5SHollis Blanchard kvm_arch_vcpu_free(vcpu); 311bbf45ba5SHollis Blanchard } 312bbf45ba5SHollis Blanchard 313bbf45ba5SHollis Blanchard int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) 314bbf45ba5SHollis Blanchard { 3159dd921cfSHollis Blanchard return kvmppc_core_pending_dec(vcpu); 316bbf45ba5SHollis Blanchard } 317bbf45ba5SHollis Blanchard 318544c6761SAlexander Graf /* 319544c6761SAlexander Graf * low level hrtimer wake routine. Because this runs in hardirq context 320544c6761SAlexander Graf * we schedule a tasklet to do the real work. 321544c6761SAlexander Graf */ 322544c6761SAlexander Graf enum hrtimer_restart kvmppc_decrementer_wakeup(struct hrtimer *timer) 323544c6761SAlexander Graf { 324544c6761SAlexander Graf struct kvm_vcpu *vcpu; 325544c6761SAlexander Graf 326544c6761SAlexander Graf vcpu = container_of(timer, struct kvm_vcpu, arch.dec_timer); 327544c6761SAlexander Graf tasklet_schedule(&vcpu->arch.tasklet); 328544c6761SAlexander Graf 329544c6761SAlexander Graf return HRTIMER_NORESTART; 330544c6761SAlexander Graf } 331544c6761SAlexander Graf 332bbf45ba5SHollis Blanchard int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) 333bbf45ba5SHollis Blanchard { 334544c6761SAlexander Graf hrtimer_init(&vcpu->arch.dec_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); 335544c6761SAlexander Graf tasklet_init(&vcpu->arch.tasklet, kvmppc_decrementer_func, (ulong)vcpu); 336544c6761SAlexander Graf vcpu->arch.dec_timer.function = kvmppc_decrementer_wakeup; 337de56a948SPaul Mackerras vcpu->arch.dec_expires = ~(u64)0; 338bbf45ba5SHollis Blanchard 33909000adbSBharat Bhushan #ifdef CONFIG_KVM_EXIT_TIMING 34009000adbSBharat Bhushan mutex_init(&vcpu->arch.exit_timing_lock); 34109000adbSBharat Bhushan #endif 34209000adbSBharat Bhushan 343bbf45ba5SHollis Blanchard return 0; 344bbf45ba5SHollis Blanchard } 345bbf45ba5SHollis Blanchard 346bbf45ba5SHollis Blanchard void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) 347bbf45ba5SHollis Blanchard { 348ecc0981fSHollis Blanchard kvmppc_mmu_destroy(vcpu); 349bbf45ba5SHollis Blanchard } 350bbf45ba5SHollis Blanchard 351bbf45ba5SHollis Blanchard void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) 352bbf45ba5SHollis Blanchard { 353eab17672SScott Wood #ifdef CONFIG_BOOKE 354eab17672SScott Wood /* 355eab17672SScott Wood * vrsave (formerly usprg0) isn't used by Linux, but may 356eab17672SScott Wood * be used by the guest. 357eab17672SScott Wood * 358eab17672SScott Wood * On non-booke this is associated with Altivec and 359eab17672SScott Wood * is handled by code in book3s.c. 360eab17672SScott Wood */ 361eab17672SScott Wood mtspr(SPRN_VRSAVE, vcpu->arch.vrsave); 362eab17672SScott Wood #endif 3639dd921cfSHollis Blanchard kvmppc_core_vcpu_load(vcpu, cpu); 364de56a948SPaul Mackerras vcpu->cpu = smp_processor_id(); 365bbf45ba5SHollis Blanchard } 366bbf45ba5SHollis Blanchard 367bbf45ba5SHollis Blanchard void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) 368bbf45ba5SHollis Blanchard { 3699dd921cfSHollis Blanchard kvmppc_core_vcpu_put(vcpu); 370eab17672SScott Wood #ifdef CONFIG_BOOKE 371eab17672SScott Wood vcpu->arch.vrsave = mfspr(SPRN_VRSAVE); 372eab17672SScott Wood #endif 373de56a948SPaul Mackerras vcpu->cpu = -1; 374bbf45ba5SHollis Blanchard } 375bbf45ba5SHollis Blanchard 376d0bfb940SJan Kiszka int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, 377d0bfb940SJan Kiszka struct kvm_guest_debug *dbg) 378bbf45ba5SHollis Blanchard { 379f5d0906bSHollis Blanchard return -EINVAL; 380bbf45ba5SHollis Blanchard } 381bbf45ba5SHollis Blanchard 382bbf45ba5SHollis Blanchard static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu, 383bbf45ba5SHollis Blanchard struct kvm_run *run) 384bbf45ba5SHollis Blanchard { 3858e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, run->dcr.data); 386bbf45ba5SHollis Blanchard } 387bbf45ba5SHollis Blanchard 388bbf45ba5SHollis Blanchard static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, 389bbf45ba5SHollis Blanchard struct kvm_run *run) 390bbf45ba5SHollis Blanchard { 39169b61833SDenis Kirjanov u64 uninitialized_var(gpr); 392bbf45ba5SHollis Blanchard 3938e5b26b5SAlexander Graf if (run->mmio.len > sizeof(gpr)) { 394bbf45ba5SHollis Blanchard printk(KERN_ERR "bad MMIO length: %d\n", run->mmio.len); 395bbf45ba5SHollis Blanchard return; 396bbf45ba5SHollis Blanchard } 397bbf45ba5SHollis Blanchard 398bbf45ba5SHollis Blanchard if (vcpu->arch.mmio_is_bigendian) { 399bbf45ba5SHollis Blanchard switch (run->mmio.len) { 400b104d066SAlexander Graf case 8: gpr = *(u64 *)run->mmio.data; break; 4018e5b26b5SAlexander Graf case 4: gpr = *(u32 *)run->mmio.data; break; 4028e5b26b5SAlexander Graf case 2: gpr = *(u16 *)run->mmio.data; break; 4038e5b26b5SAlexander Graf case 1: gpr = *(u8 *)run->mmio.data; break; 404bbf45ba5SHollis Blanchard } 405bbf45ba5SHollis Blanchard } else { 406bbf45ba5SHollis Blanchard /* Convert BE data from userland back to LE. */ 407bbf45ba5SHollis Blanchard switch (run->mmio.len) { 4088e5b26b5SAlexander Graf case 4: gpr = ld_le32((u32 *)run->mmio.data); break; 4098e5b26b5SAlexander Graf case 2: gpr = ld_le16((u16 *)run->mmio.data); break; 4108e5b26b5SAlexander Graf case 1: gpr = *(u8 *)run->mmio.data; break; 411bbf45ba5SHollis Blanchard } 412bbf45ba5SHollis Blanchard } 4138e5b26b5SAlexander Graf 4143587d534SAlexander Graf if (vcpu->arch.mmio_sign_extend) { 4153587d534SAlexander Graf switch (run->mmio.len) { 4163587d534SAlexander Graf #ifdef CONFIG_PPC64 4173587d534SAlexander Graf case 4: 4183587d534SAlexander Graf gpr = (s64)(s32)gpr; 4193587d534SAlexander Graf break; 4203587d534SAlexander Graf #endif 4213587d534SAlexander Graf case 2: 4223587d534SAlexander Graf gpr = (s64)(s16)gpr; 4233587d534SAlexander Graf break; 4243587d534SAlexander Graf case 1: 4253587d534SAlexander Graf gpr = (s64)(s8)gpr; 4263587d534SAlexander Graf break; 4273587d534SAlexander Graf } 4283587d534SAlexander Graf } 4293587d534SAlexander Graf 4308e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr); 431b104d066SAlexander Graf 432b104d066SAlexander Graf switch (vcpu->arch.io_gpr & KVM_REG_EXT_MASK) { 433b104d066SAlexander Graf case KVM_REG_GPR: 434b104d066SAlexander Graf kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr); 435b104d066SAlexander Graf break; 436b104d066SAlexander Graf case KVM_REG_FPR: 437b104d066SAlexander Graf vcpu->arch.fpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; 438b104d066SAlexander Graf break; 439287d5611SAlexander Graf #ifdef CONFIG_PPC_BOOK3S 440b104d066SAlexander Graf case KVM_REG_QPR: 441b104d066SAlexander Graf vcpu->arch.qpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; 442b104d066SAlexander Graf break; 443b104d066SAlexander Graf case KVM_REG_FQPR: 444b104d066SAlexander Graf vcpu->arch.fpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; 445b104d066SAlexander Graf vcpu->arch.qpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; 446b104d066SAlexander Graf break; 447287d5611SAlexander Graf #endif 448b104d066SAlexander Graf default: 449b104d066SAlexander Graf BUG(); 450b104d066SAlexander Graf } 451bbf45ba5SHollis Blanchard } 452bbf45ba5SHollis Blanchard 453bbf45ba5SHollis Blanchard int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, 454bbf45ba5SHollis Blanchard unsigned int rt, unsigned int bytes, int is_bigendian) 455bbf45ba5SHollis Blanchard { 456bbf45ba5SHollis Blanchard if (bytes > sizeof(run->mmio.data)) { 457bbf45ba5SHollis Blanchard printk(KERN_ERR "%s: bad MMIO length: %d\n", __func__, 458bbf45ba5SHollis Blanchard run->mmio.len); 459bbf45ba5SHollis Blanchard } 460bbf45ba5SHollis Blanchard 461bbf45ba5SHollis Blanchard run->mmio.phys_addr = vcpu->arch.paddr_accessed; 462bbf45ba5SHollis Blanchard run->mmio.len = bytes; 463bbf45ba5SHollis Blanchard run->mmio.is_write = 0; 464bbf45ba5SHollis Blanchard 465bbf45ba5SHollis Blanchard vcpu->arch.io_gpr = rt; 466bbf45ba5SHollis Blanchard vcpu->arch.mmio_is_bigendian = is_bigendian; 467bbf45ba5SHollis Blanchard vcpu->mmio_needed = 1; 468bbf45ba5SHollis Blanchard vcpu->mmio_is_write = 0; 4693587d534SAlexander Graf vcpu->arch.mmio_sign_extend = 0; 470bbf45ba5SHollis Blanchard 471bbf45ba5SHollis Blanchard return EMULATE_DO_MMIO; 472bbf45ba5SHollis Blanchard } 473bbf45ba5SHollis Blanchard 4743587d534SAlexander Graf /* Same as above, but sign extends */ 4753587d534SAlexander Graf int kvmppc_handle_loads(struct kvm_run *run, struct kvm_vcpu *vcpu, 4763587d534SAlexander Graf unsigned int rt, unsigned int bytes, int is_bigendian) 4773587d534SAlexander Graf { 4783587d534SAlexander Graf int r; 4793587d534SAlexander Graf 4803587d534SAlexander Graf r = kvmppc_handle_load(run, vcpu, rt, bytes, is_bigendian); 4813587d534SAlexander Graf vcpu->arch.mmio_sign_extend = 1; 4823587d534SAlexander Graf 4833587d534SAlexander Graf return r; 4843587d534SAlexander Graf } 4853587d534SAlexander Graf 486bbf45ba5SHollis Blanchard int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, 487b104d066SAlexander Graf u64 val, unsigned int bytes, int is_bigendian) 488bbf45ba5SHollis Blanchard { 489bbf45ba5SHollis Blanchard void *data = run->mmio.data; 490bbf45ba5SHollis Blanchard 491bbf45ba5SHollis Blanchard if (bytes > sizeof(run->mmio.data)) { 492bbf45ba5SHollis Blanchard printk(KERN_ERR "%s: bad MMIO length: %d\n", __func__, 493bbf45ba5SHollis Blanchard run->mmio.len); 494bbf45ba5SHollis Blanchard } 495bbf45ba5SHollis Blanchard 496bbf45ba5SHollis Blanchard run->mmio.phys_addr = vcpu->arch.paddr_accessed; 497bbf45ba5SHollis Blanchard run->mmio.len = bytes; 498bbf45ba5SHollis Blanchard run->mmio.is_write = 1; 499bbf45ba5SHollis Blanchard vcpu->mmio_needed = 1; 500bbf45ba5SHollis Blanchard vcpu->mmio_is_write = 1; 501bbf45ba5SHollis Blanchard 502bbf45ba5SHollis Blanchard /* Store the value at the lowest bytes in 'data'. */ 503bbf45ba5SHollis Blanchard if (is_bigendian) { 504bbf45ba5SHollis Blanchard switch (bytes) { 505b104d066SAlexander Graf case 8: *(u64 *)data = val; break; 506bbf45ba5SHollis Blanchard case 4: *(u32 *)data = val; break; 507bbf45ba5SHollis Blanchard case 2: *(u16 *)data = val; break; 508bbf45ba5SHollis Blanchard case 1: *(u8 *)data = val; break; 509bbf45ba5SHollis Blanchard } 510bbf45ba5SHollis Blanchard } else { 511bbf45ba5SHollis Blanchard /* Store LE value into 'data'. */ 512bbf45ba5SHollis Blanchard switch (bytes) { 513bbf45ba5SHollis Blanchard case 4: st_le32(data, val); break; 514bbf45ba5SHollis Blanchard case 2: st_le16(data, val); break; 515bbf45ba5SHollis Blanchard case 1: *(u8 *)data = val; break; 516bbf45ba5SHollis Blanchard } 517bbf45ba5SHollis Blanchard } 518bbf45ba5SHollis Blanchard 519bbf45ba5SHollis Blanchard return EMULATE_DO_MMIO; 520bbf45ba5SHollis Blanchard } 521bbf45ba5SHollis Blanchard 522bbf45ba5SHollis Blanchard int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) 523bbf45ba5SHollis Blanchard { 524bbf45ba5SHollis Blanchard int r; 525bbf45ba5SHollis Blanchard sigset_t sigsaved; 526bbf45ba5SHollis Blanchard 527bbf45ba5SHollis Blanchard if (vcpu->sigset_active) 528bbf45ba5SHollis Blanchard sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); 529bbf45ba5SHollis Blanchard 530bbf45ba5SHollis Blanchard if (vcpu->mmio_needed) { 531bbf45ba5SHollis Blanchard if (!vcpu->mmio_is_write) 532bbf45ba5SHollis Blanchard kvmppc_complete_mmio_load(vcpu, run); 533bbf45ba5SHollis Blanchard vcpu->mmio_needed = 0; 534bbf45ba5SHollis Blanchard } else if (vcpu->arch.dcr_needed) { 535bbf45ba5SHollis Blanchard if (!vcpu->arch.dcr_is_write) 536bbf45ba5SHollis Blanchard kvmppc_complete_dcr_load(vcpu, run); 537bbf45ba5SHollis Blanchard vcpu->arch.dcr_needed = 0; 538ad0a048bSAlexander Graf } else if (vcpu->arch.osi_needed) { 539ad0a048bSAlexander Graf u64 *gprs = run->osi.gprs; 540ad0a048bSAlexander Graf int i; 541ad0a048bSAlexander Graf 542ad0a048bSAlexander Graf for (i = 0; i < 32; i++) 543ad0a048bSAlexander Graf kvmppc_set_gpr(vcpu, i, gprs[i]); 544ad0a048bSAlexander Graf vcpu->arch.osi_needed = 0; 545de56a948SPaul Mackerras } else if (vcpu->arch.hcall_needed) { 546de56a948SPaul Mackerras int i; 547de56a948SPaul Mackerras 548de56a948SPaul Mackerras kvmppc_set_gpr(vcpu, 3, run->papr_hcall.ret); 549de56a948SPaul Mackerras for (i = 0; i < 9; ++i) 550de56a948SPaul Mackerras kvmppc_set_gpr(vcpu, 4 + i, run->papr_hcall.args[i]); 551de56a948SPaul Mackerras vcpu->arch.hcall_needed = 0; 552bbf45ba5SHollis Blanchard } 553bbf45ba5SHollis Blanchard 554df6909e5SPaul Mackerras r = kvmppc_vcpu_run(run, vcpu); 555bbf45ba5SHollis Blanchard 556bbf45ba5SHollis Blanchard if (vcpu->sigset_active) 557bbf45ba5SHollis Blanchard sigprocmask(SIG_SETMASK, &sigsaved, NULL); 558bbf45ba5SHollis Blanchard 559bbf45ba5SHollis Blanchard return r; 560bbf45ba5SHollis Blanchard } 561bbf45ba5SHollis Blanchard 562dfd4d47eSScott Wood void kvm_vcpu_kick(struct kvm_vcpu *vcpu) 563dfd4d47eSScott Wood { 564ae21216bSAlexander Graf int me; 565ae21216bSAlexander Graf int cpu = vcpu->cpu; 566ae21216bSAlexander Graf 567ae21216bSAlexander Graf me = get_cpu(); 5684e72dbe1SPaul Mackerras if (waitqueue_active(vcpu->arch.wqp)) { 569dfd4d47eSScott Wood wake_up_interruptible(vcpu->arch.wqp); 570dfd4d47eSScott Wood vcpu->stat.halt_wakeup++; 571ae21216bSAlexander Graf } else if (cpu != me && cpu != -1) { 572dfd4d47eSScott Wood smp_send_reschedule(vcpu->cpu); 573dfd4d47eSScott Wood } 574ae21216bSAlexander Graf put_cpu(); 575dfd4d47eSScott Wood } 576dfd4d47eSScott Wood 577bbf45ba5SHollis Blanchard int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq) 578bbf45ba5SHollis Blanchard { 57919ccb76aSPaul Mackerras if (irq->irq == KVM_INTERRUPT_UNSET) { 58018978768SAlexander Graf kvmppc_core_dequeue_external(vcpu, irq); 58119ccb76aSPaul Mackerras return 0; 58219ccb76aSPaul Mackerras } 58319ccb76aSPaul Mackerras 5849dd921cfSHollis Blanchard kvmppc_core_queue_external(vcpu, irq); 585dfd4d47eSScott Wood kvm_vcpu_kick(vcpu); 58645c5eb67SHollis Blanchard 587bbf45ba5SHollis Blanchard return 0; 588bbf45ba5SHollis Blanchard } 589bbf45ba5SHollis Blanchard 59071fbfd5fSAlexander Graf static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, 59171fbfd5fSAlexander Graf struct kvm_enable_cap *cap) 59271fbfd5fSAlexander Graf { 59371fbfd5fSAlexander Graf int r; 59471fbfd5fSAlexander Graf 59571fbfd5fSAlexander Graf if (cap->flags) 59671fbfd5fSAlexander Graf return -EINVAL; 59771fbfd5fSAlexander Graf 59871fbfd5fSAlexander Graf switch (cap->cap) { 599ad0a048bSAlexander Graf case KVM_CAP_PPC_OSI: 600ad0a048bSAlexander Graf r = 0; 601ad0a048bSAlexander Graf vcpu->arch.osi_enabled = true; 602ad0a048bSAlexander Graf break; 603930b412aSAlexander Graf case KVM_CAP_PPC_PAPR: 604930b412aSAlexander Graf r = 0; 605930b412aSAlexander Graf vcpu->arch.papr_enabled = true; 606930b412aSAlexander Graf break; 607dc83b8bcSScott Wood #ifdef CONFIG_KVM_E500 608dc83b8bcSScott Wood case KVM_CAP_SW_TLB: { 609dc83b8bcSScott Wood struct kvm_config_tlb cfg; 610dc83b8bcSScott Wood void __user *user_ptr = (void __user *)(uintptr_t)cap->args[0]; 611dc83b8bcSScott Wood 612dc83b8bcSScott Wood r = -EFAULT; 613dc83b8bcSScott Wood if (copy_from_user(&cfg, user_ptr, sizeof(cfg))) 614dc83b8bcSScott Wood break; 615dc83b8bcSScott Wood 616dc83b8bcSScott Wood r = kvm_vcpu_ioctl_config_tlb(vcpu, &cfg); 617dc83b8bcSScott Wood break; 618dc83b8bcSScott Wood } 619dc83b8bcSScott Wood #endif 62071fbfd5fSAlexander Graf default: 62171fbfd5fSAlexander Graf r = -EINVAL; 62271fbfd5fSAlexander Graf break; 62371fbfd5fSAlexander Graf } 62471fbfd5fSAlexander Graf 625af8f38b3SAlexander Graf if (!r) 626af8f38b3SAlexander Graf r = kvmppc_sanity_check(vcpu); 627af8f38b3SAlexander Graf 62871fbfd5fSAlexander Graf return r; 62971fbfd5fSAlexander Graf } 63071fbfd5fSAlexander Graf 631bbf45ba5SHollis Blanchard int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, 632bbf45ba5SHollis Blanchard struct kvm_mp_state *mp_state) 633bbf45ba5SHollis Blanchard { 634bbf45ba5SHollis Blanchard return -EINVAL; 635bbf45ba5SHollis Blanchard } 636bbf45ba5SHollis Blanchard 637bbf45ba5SHollis Blanchard int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, 638bbf45ba5SHollis Blanchard struct kvm_mp_state *mp_state) 639bbf45ba5SHollis Blanchard { 640bbf45ba5SHollis Blanchard return -EINVAL; 641bbf45ba5SHollis Blanchard } 642bbf45ba5SHollis Blanchard 643bbf45ba5SHollis Blanchard long kvm_arch_vcpu_ioctl(struct file *filp, 644bbf45ba5SHollis Blanchard unsigned int ioctl, unsigned long arg) 645bbf45ba5SHollis Blanchard { 646bbf45ba5SHollis Blanchard struct kvm_vcpu *vcpu = filp->private_data; 647bbf45ba5SHollis Blanchard void __user *argp = (void __user *)arg; 648bbf45ba5SHollis Blanchard long r; 649bbf45ba5SHollis Blanchard 65093736624SAvi Kivity switch (ioctl) { 65193736624SAvi Kivity case KVM_INTERRUPT: { 652bbf45ba5SHollis Blanchard struct kvm_interrupt irq; 653bbf45ba5SHollis Blanchard r = -EFAULT; 654bbf45ba5SHollis Blanchard if (copy_from_user(&irq, argp, sizeof(irq))) 65593736624SAvi Kivity goto out; 656bbf45ba5SHollis Blanchard r = kvm_vcpu_ioctl_interrupt(vcpu, &irq); 65793736624SAvi Kivity goto out; 658bbf45ba5SHollis Blanchard } 65919483d14SAvi Kivity 66071fbfd5fSAlexander Graf case KVM_ENABLE_CAP: 66171fbfd5fSAlexander Graf { 66271fbfd5fSAlexander Graf struct kvm_enable_cap cap; 66371fbfd5fSAlexander Graf r = -EFAULT; 66471fbfd5fSAlexander Graf if (copy_from_user(&cap, argp, sizeof(cap))) 66571fbfd5fSAlexander Graf goto out; 66671fbfd5fSAlexander Graf r = kvm_vcpu_ioctl_enable_cap(vcpu, &cap); 66771fbfd5fSAlexander Graf break; 66871fbfd5fSAlexander Graf } 669dc83b8bcSScott Wood 670dc83b8bcSScott Wood #ifdef CONFIG_KVM_E500 671dc83b8bcSScott Wood case KVM_DIRTY_TLB: { 672dc83b8bcSScott Wood struct kvm_dirty_tlb dirty; 673dc83b8bcSScott Wood r = -EFAULT; 674dc83b8bcSScott Wood if (copy_from_user(&dirty, argp, sizeof(dirty))) 675dc83b8bcSScott Wood goto out; 676dc83b8bcSScott Wood r = kvm_vcpu_ioctl_dirty_tlb(vcpu, &dirty); 677dc83b8bcSScott Wood break; 678dc83b8bcSScott Wood } 679dc83b8bcSScott Wood #endif 680dc83b8bcSScott Wood 681bbf45ba5SHollis Blanchard default: 682bbf45ba5SHollis Blanchard r = -EINVAL; 683bbf45ba5SHollis Blanchard } 684bbf45ba5SHollis Blanchard 685bbf45ba5SHollis Blanchard out: 686bbf45ba5SHollis Blanchard return r; 687bbf45ba5SHollis Blanchard } 688bbf45ba5SHollis Blanchard 6895b1c1493SCarsten Otte int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf) 6905b1c1493SCarsten Otte { 6915b1c1493SCarsten Otte return VM_FAULT_SIGBUS; 6925b1c1493SCarsten Otte } 6935b1c1493SCarsten Otte 69415711e9cSAlexander Graf static int kvm_vm_ioctl_get_pvinfo(struct kvm_ppc_pvinfo *pvinfo) 69515711e9cSAlexander Graf { 69615711e9cSAlexander Graf u32 inst_lis = 0x3c000000; 69715711e9cSAlexander Graf u32 inst_ori = 0x60000000; 69815711e9cSAlexander Graf u32 inst_nop = 0x60000000; 69915711e9cSAlexander Graf u32 inst_sc = 0x44000002; 70015711e9cSAlexander Graf u32 inst_imm_mask = 0xffff; 70115711e9cSAlexander Graf 70215711e9cSAlexander Graf /* 70315711e9cSAlexander Graf * The hypercall to get into KVM from within guest context is as 70415711e9cSAlexander Graf * follows: 70515711e9cSAlexander Graf * 70615711e9cSAlexander Graf * lis r0, r0, KVM_SC_MAGIC_R0@h 70715711e9cSAlexander Graf * ori r0, KVM_SC_MAGIC_R0@l 70815711e9cSAlexander Graf * sc 70915711e9cSAlexander Graf * nop 71015711e9cSAlexander Graf */ 71115711e9cSAlexander Graf pvinfo->hcall[0] = inst_lis | ((KVM_SC_MAGIC_R0 >> 16) & inst_imm_mask); 71215711e9cSAlexander Graf pvinfo->hcall[1] = inst_ori | (KVM_SC_MAGIC_R0 & inst_imm_mask); 71315711e9cSAlexander Graf pvinfo->hcall[2] = inst_sc; 71415711e9cSAlexander Graf pvinfo->hcall[3] = inst_nop; 71515711e9cSAlexander Graf 71615711e9cSAlexander Graf return 0; 71715711e9cSAlexander Graf } 71815711e9cSAlexander Graf 719bbf45ba5SHollis Blanchard long kvm_arch_vm_ioctl(struct file *filp, 720bbf45ba5SHollis Blanchard unsigned int ioctl, unsigned long arg) 721bbf45ba5SHollis Blanchard { 72215711e9cSAlexander Graf void __user *argp = (void __user *)arg; 723bbf45ba5SHollis Blanchard long r; 724bbf45ba5SHollis Blanchard 725bbf45ba5SHollis Blanchard switch (ioctl) { 72615711e9cSAlexander Graf case KVM_PPC_GET_PVINFO: { 72715711e9cSAlexander Graf struct kvm_ppc_pvinfo pvinfo; 728d8cdddcdSVasiliy Kulikov memset(&pvinfo, 0, sizeof(pvinfo)); 72915711e9cSAlexander Graf r = kvm_vm_ioctl_get_pvinfo(&pvinfo); 73015711e9cSAlexander Graf if (copy_to_user(argp, &pvinfo, sizeof(pvinfo))) { 73115711e9cSAlexander Graf r = -EFAULT; 73215711e9cSAlexander Graf goto out; 73315711e9cSAlexander Graf } 73415711e9cSAlexander Graf 73515711e9cSAlexander Graf break; 73615711e9cSAlexander Graf } 73754738c09SDavid Gibson #ifdef CONFIG_KVM_BOOK3S_64_HV 73854738c09SDavid Gibson case KVM_CREATE_SPAPR_TCE: { 73954738c09SDavid Gibson struct kvm_create_spapr_tce create_tce; 74054738c09SDavid Gibson struct kvm *kvm = filp->private_data; 74154738c09SDavid Gibson 74254738c09SDavid Gibson r = -EFAULT; 74354738c09SDavid Gibson if (copy_from_user(&create_tce, argp, sizeof(create_tce))) 74454738c09SDavid Gibson goto out; 74554738c09SDavid Gibson r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce); 74654738c09SDavid Gibson goto out; 74754738c09SDavid Gibson } 748aa04b4ccSPaul Mackerras 749aa04b4ccSPaul Mackerras case KVM_ALLOCATE_RMA: { 750aa04b4ccSPaul Mackerras struct kvm *kvm = filp->private_data; 751aa04b4ccSPaul Mackerras struct kvm_allocate_rma rma; 752aa04b4ccSPaul Mackerras 753aa04b4ccSPaul Mackerras r = kvm_vm_ioctl_allocate_rma(kvm, &rma); 754aa04b4ccSPaul Mackerras if (r >= 0 && copy_to_user(argp, &rma, sizeof(rma))) 755aa04b4ccSPaul Mackerras r = -EFAULT; 756aa04b4ccSPaul Mackerras break; 757aa04b4ccSPaul Mackerras } 75854738c09SDavid Gibson #endif /* CONFIG_KVM_BOOK3S_64_HV */ 75954738c09SDavid Gibson 760bbf45ba5SHollis Blanchard default: 761367e1319SAvi Kivity r = -ENOTTY; 762bbf45ba5SHollis Blanchard } 763bbf45ba5SHollis Blanchard 76415711e9cSAlexander Graf out: 765bbf45ba5SHollis Blanchard return r; 766bbf45ba5SHollis Blanchard } 767bbf45ba5SHollis Blanchard 768bbf45ba5SHollis Blanchard int kvm_arch_init(void *opaque) 769bbf45ba5SHollis Blanchard { 770bbf45ba5SHollis Blanchard return 0; 771bbf45ba5SHollis Blanchard } 772bbf45ba5SHollis Blanchard 773bbf45ba5SHollis Blanchard void kvm_arch_exit(void) 774bbf45ba5SHollis Blanchard { 775bbf45ba5SHollis Blanchard } 776