aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2010-07-29 08:48:08 -0400
committerAvi Kivity <avi@redhat.com>2010-10-24 04:50:57 -0400
commit15711e9c927bfc08e66791cbf0ca7887c0880768 (patch)
tree0b44274b4592b298177122178e83927d45919a19 /arch/powerpc/kvm
parentd7d3c2ea99c4845611997cf728af88c4c232e908 (diff)
KVM: PPC: Add get_pvinfo interface to query hypercall instructions
We need to tell the guest the opcodes that make up a hypercall through interfaces that are controlled by userspace. So we need to add a call for userspace to allow it to query those opcodes so it can pass them on. This is required because the hypercall opcodes can change based on the hypervisor conditions. If we're running in hardware accelerated hypervisor mode, a hypercall looks different from when we're running without hardware acceleration. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/powerpc/kvm')
-rw-r--r--arch/powerpc/kvm/powerpc.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index fecfe043458d..6a53a3f86dae 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -191,6 +191,7 @@ int kvm_dev_ioctl_check_extension(long ext)
191 case KVM_CAP_PPC_UNSET_IRQ: 191 case KVM_CAP_PPC_UNSET_IRQ:
192 case KVM_CAP_ENABLE_CAP: 192 case KVM_CAP_ENABLE_CAP:
193 case KVM_CAP_PPC_OSI: 193 case KVM_CAP_PPC_OSI:
194 case KVM_CAP_PPC_GET_PVINFO:
194 r = 1; 195 r = 1;
195 break; 196 break;
196 case KVM_CAP_COALESCED_MMIO: 197 case KVM_CAP_COALESCED_MMIO:
@@ -578,16 +579,53 @@ out:
578 return r; 579 return r;
579} 580}
580 581
582static int kvm_vm_ioctl_get_pvinfo(struct kvm_ppc_pvinfo *pvinfo)
583{
584 u32 inst_lis = 0x3c000000;
585 u32 inst_ori = 0x60000000;
586 u32 inst_nop = 0x60000000;
587 u32 inst_sc = 0x44000002;
588 u32 inst_imm_mask = 0xffff;
589
590 /*
591 * The hypercall to get into KVM from within guest context is as
592 * follows:
593 *
594 * lis r0, r0, KVM_SC_MAGIC_R0@h
595 * ori r0, KVM_SC_MAGIC_R0@l
596 * sc
597 * nop
598 */
599 pvinfo->hcall[0] = inst_lis | ((KVM_SC_MAGIC_R0 >> 16) & inst_imm_mask);
600 pvinfo->hcall[1] = inst_ori | (KVM_SC_MAGIC_R0 & inst_imm_mask);
601 pvinfo->hcall[2] = inst_sc;
602 pvinfo->hcall[3] = inst_nop;
603
604 return 0;
605}
606
581long kvm_arch_vm_ioctl(struct file *filp, 607long kvm_arch_vm_ioctl(struct file *filp,
582 unsigned int ioctl, unsigned long arg) 608 unsigned int ioctl, unsigned long arg)
583{ 609{
610 void __user *argp = (void __user *)arg;
584 long r; 611 long r;
585 612
586 switch (ioctl) { 613 switch (ioctl) {
614 case KVM_PPC_GET_PVINFO: {
615 struct kvm_ppc_pvinfo pvinfo;
616 r = kvm_vm_ioctl_get_pvinfo(&pvinfo);
617 if (copy_to_user(argp, &pvinfo, sizeof(pvinfo))) {
618 r = -EFAULT;
619 goto out;
620 }
621
622 break;
623 }
587 default: 624 default:
588 r = -ENOTTY; 625 r = -ENOTTY;
589 } 626 }
590 627
628out:
591 return r; 629 return r;
592} 630}
593 631