diff options
-rw-r--r-- | Documentation/kvm/api.txt | 23 | ||||
-rw-r--r-- | arch/powerpc/kvm/powerpc.c | 38 | ||||
-rw-r--r-- | include/linux/kvm.h | 11 |
3 files changed, 72 insertions, 0 deletions
diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt index 5f5b64982b1a..44d9893f9db1 100644 --- a/Documentation/kvm/api.txt +++ b/Documentation/kvm/api.txt | |||
@@ -1032,6 +1032,29 @@ are defined as follows: | |||
1032 | eax, ebx, ecx, edx: the values returned by the cpuid instruction for | 1032 | eax, ebx, ecx, edx: the values returned by the cpuid instruction for |
1033 | this function/index combination | 1033 | this function/index combination |
1034 | 1034 | ||
1035 | 4.46 KVM_PPC_GET_PVINFO | ||
1036 | |||
1037 | Capability: KVM_CAP_PPC_GET_PVINFO | ||
1038 | Architectures: ppc | ||
1039 | Type: vm ioctl | ||
1040 | Parameters: struct kvm_ppc_pvinfo (out) | ||
1041 | Returns: 0 on success, !0 on error | ||
1042 | |||
1043 | struct kvm_ppc_pvinfo { | ||
1044 | __u32 flags; | ||
1045 | __u32 hcall[4]; | ||
1046 | __u8 pad[108]; | ||
1047 | }; | ||
1048 | |||
1049 | This ioctl fetches PV specific information that need to be passed to the guest | ||
1050 | using the device tree or other means from vm context. | ||
1051 | |||
1052 | For now the only implemented piece of information distributed here is an array | ||
1053 | of 4 instructions that make up a hypercall. | ||
1054 | |||
1055 | If any additional field gets added to this structure later on, a bit for that | ||
1056 | additional piece of information will be set in the flags bitmap. | ||
1057 | |||
1035 | 5. The kvm_run structure | 1058 | 5. The kvm_run structure |
1036 | 1059 | ||
1037 | Application code obtains a pointer to the kvm_run structure by | 1060 | Application code obtains a pointer to the kvm_run structure by |
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 | ||
582 | static 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 | |||
581 | long kvm_arch_vm_ioctl(struct file *filp, | 607 | long 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 | ||
628 | out: | ||
591 | return r; | 629 | return r; |
592 | } | 630 | } |
593 | 631 | ||
diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 636fc381c897..37077045970b 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h | |||
@@ -414,6 +414,14 @@ struct kvm_enable_cap { | |||
414 | __u8 pad[64]; | 414 | __u8 pad[64]; |
415 | }; | 415 | }; |
416 | 416 | ||
417 | /* for KVM_PPC_GET_PVINFO */ | ||
418 | struct kvm_ppc_pvinfo { | ||
419 | /* out */ | ||
420 | __u32 flags; | ||
421 | __u32 hcall[4]; | ||
422 | __u8 pad[108]; | ||
423 | }; | ||
424 | |||
417 | #define KVMIO 0xAE | 425 | #define KVMIO 0xAE |
418 | 426 | ||
419 | /* | 427 | /* |
@@ -530,6 +538,7 @@ struct kvm_enable_cap { | |||
530 | #ifdef __KVM_HAVE_XCRS | 538 | #ifdef __KVM_HAVE_XCRS |
531 | #define KVM_CAP_XCRS 56 | 539 | #define KVM_CAP_XCRS 56 |
532 | #endif | 540 | #endif |
541 | #define KVM_CAP_PPC_GET_PVINFO 57 | ||
533 | 542 | ||
534 | #ifdef KVM_CAP_IRQ_ROUTING | 543 | #ifdef KVM_CAP_IRQ_ROUTING |
535 | 544 | ||
@@ -664,6 +673,8 @@ struct kvm_clock_data { | |||
664 | /* Available with KVM_CAP_PIT_STATE2 */ | 673 | /* Available with KVM_CAP_PIT_STATE2 */ |
665 | #define KVM_GET_PIT2 _IOR(KVMIO, 0x9f, struct kvm_pit_state2) | 674 | #define KVM_GET_PIT2 _IOR(KVMIO, 0x9f, struct kvm_pit_state2) |
666 | #define KVM_SET_PIT2 _IOW(KVMIO, 0xa0, struct kvm_pit_state2) | 675 | #define KVM_SET_PIT2 _IOW(KVMIO, 0xa0, struct kvm_pit_state2) |
676 | /* Available with KVM_CAP_PPC_GET_PVINFO */ | ||
677 | #define KVM_PPC_GET_PVINFO _IOW(KVMIO, 0xa1, struct kvm_ppc_pvinfo) | ||
667 | 678 | ||
668 | /* | 679 | /* |
669 | * ioctls for vcpu fds | 680 | * ioctls for vcpu fds |