diff options
-rw-r--r-- | Documentation/kvm/api.txt | 74 | ||||
-rw-r--r-- | arch/x86/include/asm/kvm.h | 22 | ||||
-rw-r--r-- | arch/x86/include/asm/xsave.h | 7 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 139 | ||||
-rw-r--r-- | include/linux/kvm.h | 12 |
5 files changed, 252 insertions, 2 deletions
diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt index 159b4efe1b0e..ffba03f55bdf 100644 --- a/Documentation/kvm/api.txt +++ b/Documentation/kvm/api.txt | |||
@@ -922,6 +922,80 @@ Define which vcpu is the Bootstrap Processor (BSP). Values are the same | |||
922 | as the vcpu id in KVM_CREATE_VCPU. If this ioctl is not called, the default | 922 | as the vcpu id in KVM_CREATE_VCPU. If this ioctl is not called, the default |
923 | is vcpu 0. | 923 | is vcpu 0. |
924 | 924 | ||
925 | 4.41 KVM_GET_XSAVE | ||
926 | |||
927 | Capability: KVM_CAP_XSAVE | ||
928 | Architectures: x86 | ||
929 | Type: vcpu ioctl | ||
930 | Parameters: struct kvm_xsave (out) | ||
931 | Returns: 0 on success, -1 on error | ||
932 | |||
933 | struct kvm_xsave { | ||
934 | __u32 region[1024]; | ||
935 | }; | ||
936 | |||
937 | This ioctl would copy current vcpu's xsave struct to the userspace. | ||
938 | |||
939 | 4.42 KVM_SET_XSAVE | ||
940 | |||
941 | Capability: KVM_CAP_XSAVE | ||
942 | Architectures: x86 | ||
943 | Type: vcpu ioctl | ||
944 | Parameters: struct kvm_xsave (in) | ||
945 | Returns: 0 on success, -1 on error | ||
946 | |||
947 | struct kvm_xsave { | ||
948 | __u32 region[1024]; | ||
949 | }; | ||
950 | |||
951 | This ioctl would copy userspace's xsave struct to the kernel. | ||
952 | |||
953 | 4.43 KVM_GET_XCRS | ||
954 | |||
955 | Capability: KVM_CAP_XCRS | ||
956 | Architectures: x86 | ||
957 | Type: vcpu ioctl | ||
958 | Parameters: struct kvm_xcrs (out) | ||
959 | Returns: 0 on success, -1 on error | ||
960 | |||
961 | struct kvm_xcr { | ||
962 | __u32 xcr; | ||
963 | __u32 reserved; | ||
964 | __u64 value; | ||
965 | }; | ||
966 | |||
967 | struct kvm_xcrs { | ||
968 | __u32 nr_xcrs; | ||
969 | __u32 flags; | ||
970 | struct kvm_xcr xcrs[KVM_MAX_XCRS]; | ||
971 | __u64 padding[16]; | ||
972 | }; | ||
973 | |||
974 | This ioctl would copy current vcpu's xcrs to the userspace. | ||
975 | |||
976 | 4.44 KVM_SET_XCRS | ||
977 | |||
978 | Capability: KVM_CAP_XCRS | ||
979 | Architectures: x86 | ||
980 | Type: vcpu ioctl | ||
981 | Parameters: struct kvm_xcrs (in) | ||
982 | Returns: 0 on success, -1 on error | ||
983 | |||
984 | struct kvm_xcr { | ||
985 | __u32 xcr; | ||
986 | __u32 reserved; | ||
987 | __u64 value; | ||
988 | }; | ||
989 | |||
990 | struct kvm_xcrs { | ||
991 | __u32 nr_xcrs; | ||
992 | __u32 flags; | ||
993 | struct kvm_xcr xcrs[KVM_MAX_XCRS]; | ||
994 | __u64 padding[16]; | ||
995 | }; | ||
996 | |||
997 | This ioctl would set vcpu's xcr to the value userspace specified. | ||
998 | |||
925 | 5. The kvm_run structure | 999 | 5. The kvm_run structure |
926 | 1000 | ||
927 | Application code obtains a pointer to the kvm_run structure by | 1001 | Application code obtains a pointer to the kvm_run structure by |
diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h index ff90055c7f0b..4d8dcbdfc120 100644 --- a/arch/x86/include/asm/kvm.h +++ b/arch/x86/include/asm/kvm.h | |||
@@ -22,6 +22,8 @@ | |||
22 | #define __KVM_HAVE_XEN_HVM | 22 | #define __KVM_HAVE_XEN_HVM |
23 | #define __KVM_HAVE_VCPU_EVENTS | 23 | #define __KVM_HAVE_VCPU_EVENTS |
24 | #define __KVM_HAVE_DEBUGREGS | 24 | #define __KVM_HAVE_DEBUGREGS |
25 | #define __KVM_HAVE_XSAVE | ||
26 | #define __KVM_HAVE_XCRS | ||
25 | 27 | ||
26 | /* Architectural interrupt line count. */ | 28 | /* Architectural interrupt line count. */ |
27 | #define KVM_NR_INTERRUPTS 256 | 29 | #define KVM_NR_INTERRUPTS 256 |
@@ -299,4 +301,24 @@ struct kvm_debugregs { | |||
299 | __u64 reserved[9]; | 301 | __u64 reserved[9]; |
300 | }; | 302 | }; |
301 | 303 | ||
304 | /* for KVM_CAP_XSAVE */ | ||
305 | struct kvm_xsave { | ||
306 | __u32 region[1024]; | ||
307 | }; | ||
308 | |||
309 | #define KVM_MAX_XCRS 16 | ||
310 | |||
311 | struct kvm_xcr { | ||
312 | __u32 xcr; | ||
313 | __u32 reserved; | ||
314 | __u64 value; | ||
315 | }; | ||
316 | |||
317 | struct kvm_xcrs { | ||
318 | __u32 nr_xcrs; | ||
319 | __u32 flags; | ||
320 | struct kvm_xcr xcrs[KVM_MAX_XCRS]; | ||
321 | __u64 padding[16]; | ||
322 | }; | ||
323 | |||
302 | #endif /* _ASM_X86_KVM_H */ | 324 | #endif /* _ASM_X86_KVM_H */ |
diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h index 29ee4e4c64cf..32c36668fa7b 100644 --- a/arch/x86/include/asm/xsave.h +++ b/arch/x86/include/asm/xsave.h | |||
@@ -13,8 +13,11 @@ | |||
13 | 13 | ||
14 | #define FXSAVE_SIZE 512 | 14 | #define FXSAVE_SIZE 512 |
15 | 15 | ||
16 | #define XSTATE_YMM_SIZE 256 | 16 | #define XSAVE_HDR_SIZE 64 |
17 | #define XSTATE_YMM_OFFSET (512 + 64) | 17 | #define XSAVE_HDR_OFFSET FXSAVE_SIZE |
18 | |||
19 | #define XSAVE_YMM_SIZE 256 | ||
20 | #define XSAVE_YMM_OFFSET (XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET) | ||
18 | 21 | ||
19 | /* | 22 | /* |
20 | * These are the features that the OS can handle currently. | 23 | * These are the features that the OS can handle currently. |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 795999e1ac19..0c8dc9614e7d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -1680,6 +1680,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
1680 | case KVM_CAP_PCI_SEGMENT: | 1680 | case KVM_CAP_PCI_SEGMENT: |
1681 | case KVM_CAP_DEBUGREGS: | 1681 | case KVM_CAP_DEBUGREGS: |
1682 | case KVM_CAP_X86_ROBUST_SINGLESTEP: | 1682 | case KVM_CAP_X86_ROBUST_SINGLESTEP: |
1683 | case KVM_CAP_XSAVE: | ||
1683 | r = 1; | 1684 | r = 1; |
1684 | break; | 1685 | break; |
1685 | case KVM_CAP_COALESCED_MMIO: | 1686 | case KVM_CAP_COALESCED_MMIO: |
@@ -1703,6 +1704,9 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
1703 | case KVM_CAP_MCE: | 1704 | case KVM_CAP_MCE: |
1704 | r = KVM_MAX_MCE_BANKS; | 1705 | r = KVM_MAX_MCE_BANKS; |
1705 | break; | 1706 | break; |
1707 | case KVM_CAP_XCRS: | ||
1708 | r = cpu_has_xsave; | ||
1709 | break; | ||
1706 | default: | 1710 | default: |
1707 | r = 0; | 1711 | r = 0; |
1708 | break; | 1712 | break; |
@@ -2355,6 +2359,77 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, | |||
2355 | return 0; | 2359 | return 0; |
2356 | } | 2360 | } |
2357 | 2361 | ||
2362 | static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu, | ||
2363 | struct kvm_xsave *guest_xsave) | ||
2364 | { | ||
2365 | if (cpu_has_xsave) | ||
2366 | memcpy(guest_xsave->region, | ||
2367 | &vcpu->arch.guest_fpu.state->xsave, | ||
2368 | sizeof(struct xsave_struct)); | ||
2369 | else { | ||
2370 | memcpy(guest_xsave->region, | ||
2371 | &vcpu->arch.guest_fpu.state->fxsave, | ||
2372 | sizeof(struct i387_fxsave_struct)); | ||
2373 | *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)] = | ||
2374 | XSTATE_FPSSE; | ||
2375 | } | ||
2376 | } | ||
2377 | |||
2378 | static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu, | ||
2379 | struct kvm_xsave *guest_xsave) | ||
2380 | { | ||
2381 | u64 xstate_bv = | ||
2382 | *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)]; | ||
2383 | |||
2384 | if (cpu_has_xsave) | ||
2385 | memcpy(&vcpu->arch.guest_fpu.state->xsave, | ||
2386 | guest_xsave->region, sizeof(struct xsave_struct)); | ||
2387 | else { | ||
2388 | if (xstate_bv & ~XSTATE_FPSSE) | ||
2389 | return -EINVAL; | ||
2390 | memcpy(&vcpu->arch.guest_fpu.state->fxsave, | ||
2391 | guest_xsave->region, sizeof(struct i387_fxsave_struct)); | ||
2392 | } | ||
2393 | return 0; | ||
2394 | } | ||
2395 | |||
2396 | static void kvm_vcpu_ioctl_x86_get_xcrs(struct kvm_vcpu *vcpu, | ||
2397 | struct kvm_xcrs *guest_xcrs) | ||
2398 | { | ||
2399 | if (!cpu_has_xsave) { | ||
2400 | guest_xcrs->nr_xcrs = 0; | ||
2401 | return; | ||
2402 | } | ||
2403 | |||
2404 | guest_xcrs->nr_xcrs = 1; | ||
2405 | guest_xcrs->flags = 0; | ||
2406 | guest_xcrs->xcrs[0].xcr = XCR_XFEATURE_ENABLED_MASK; | ||
2407 | guest_xcrs->xcrs[0].value = vcpu->arch.xcr0; | ||
2408 | } | ||
2409 | |||
2410 | static int kvm_vcpu_ioctl_x86_set_xcrs(struct kvm_vcpu *vcpu, | ||
2411 | struct kvm_xcrs *guest_xcrs) | ||
2412 | { | ||
2413 | int i, r = 0; | ||
2414 | |||
2415 | if (!cpu_has_xsave) | ||
2416 | return -EINVAL; | ||
2417 | |||
2418 | if (guest_xcrs->nr_xcrs > KVM_MAX_XCRS || guest_xcrs->flags) | ||
2419 | return -EINVAL; | ||
2420 | |||
2421 | for (i = 0; i < guest_xcrs->nr_xcrs; i++) | ||
2422 | /* Only support XCR0 currently */ | ||
2423 | if (guest_xcrs->xcrs[0].xcr == XCR_XFEATURE_ENABLED_MASK) { | ||
2424 | r = __kvm_set_xcr(vcpu, XCR_XFEATURE_ENABLED_MASK, | ||
2425 | guest_xcrs->xcrs[0].value); | ||
2426 | break; | ||
2427 | } | ||
2428 | if (r) | ||
2429 | r = -EINVAL; | ||
2430 | return r; | ||
2431 | } | ||
2432 | |||
2358 | long kvm_arch_vcpu_ioctl(struct file *filp, | 2433 | long kvm_arch_vcpu_ioctl(struct file *filp, |
2359 | unsigned int ioctl, unsigned long arg) | 2434 | unsigned int ioctl, unsigned long arg) |
2360 | { | 2435 | { |
@@ -2556,6 +2631,70 @@ long kvm_arch_vcpu_ioctl(struct file *filp, | |||
2556 | r = kvm_vcpu_ioctl_x86_set_debugregs(vcpu, &dbgregs); | 2631 | r = kvm_vcpu_ioctl_x86_set_debugregs(vcpu, &dbgregs); |
2557 | break; | 2632 | break; |
2558 | } | 2633 | } |
2634 | case KVM_GET_XSAVE: { | ||
2635 | struct kvm_xsave *xsave; | ||
2636 | |||
2637 | xsave = kzalloc(sizeof(struct kvm_xsave), GFP_KERNEL); | ||
2638 | r = -ENOMEM; | ||
2639 | if (!xsave) | ||
2640 | break; | ||
2641 | |||
2642 | kvm_vcpu_ioctl_x86_get_xsave(vcpu, xsave); | ||
2643 | |||
2644 | r = -EFAULT; | ||
2645 | if (copy_to_user(argp, xsave, sizeof(struct kvm_xsave))) | ||
2646 | break; | ||
2647 | r = 0; | ||
2648 | break; | ||
2649 | } | ||
2650 | case KVM_SET_XSAVE: { | ||
2651 | struct kvm_xsave *xsave; | ||
2652 | |||
2653 | xsave = kzalloc(sizeof(struct kvm_xsave), GFP_KERNEL); | ||
2654 | r = -ENOMEM; | ||
2655 | if (!xsave) | ||
2656 | break; | ||
2657 | |||
2658 | r = -EFAULT; | ||
2659 | if (copy_from_user(xsave, argp, sizeof(struct kvm_xsave))) | ||
2660 | break; | ||
2661 | |||
2662 | r = kvm_vcpu_ioctl_x86_set_xsave(vcpu, xsave); | ||
2663 | break; | ||
2664 | } | ||
2665 | case KVM_GET_XCRS: { | ||
2666 | struct kvm_xcrs *xcrs; | ||
2667 | |||
2668 | xcrs = kzalloc(sizeof(struct kvm_xcrs), GFP_KERNEL); | ||
2669 | r = -ENOMEM; | ||
2670 | if (!xcrs) | ||
2671 | break; | ||
2672 | |||
2673 | kvm_vcpu_ioctl_x86_get_xcrs(vcpu, xcrs); | ||
2674 | |||
2675 | r = -EFAULT; | ||
2676 | if (copy_to_user(argp, xcrs, | ||
2677 | sizeof(struct kvm_xcrs))) | ||
2678 | break; | ||
2679 | r = 0; | ||
2680 | break; | ||
2681 | } | ||
2682 | case KVM_SET_XCRS: { | ||
2683 | struct kvm_xcrs *xcrs; | ||
2684 | |||
2685 | xcrs = kzalloc(sizeof(struct kvm_xcrs), GFP_KERNEL); | ||
2686 | r = -ENOMEM; | ||
2687 | if (!xcrs) | ||
2688 | break; | ||
2689 | |||
2690 | r = -EFAULT; | ||
2691 | if (copy_from_user(xcrs, argp, | ||
2692 | sizeof(struct kvm_xcrs))) | ||
2693 | break; | ||
2694 | |||
2695 | r = kvm_vcpu_ioctl_x86_set_xcrs(vcpu, xcrs); | ||
2696 | break; | ||
2697 | } | ||
2559 | default: | 2698 | default: |
2560 | r = -EINVAL; | 2699 | r = -EINVAL; |
2561 | } | 2700 | } |
diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 23ea02253900..6fd40f540a8e 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h | |||
@@ -524,6 +524,12 @@ struct kvm_enable_cap { | |||
524 | #define KVM_CAP_PPC_OSI 52 | 524 | #define KVM_CAP_PPC_OSI 52 |
525 | #define KVM_CAP_PPC_UNSET_IRQ 53 | 525 | #define KVM_CAP_PPC_UNSET_IRQ 53 |
526 | #define KVM_CAP_ENABLE_CAP 54 | 526 | #define KVM_CAP_ENABLE_CAP 54 |
527 | #ifdef __KVM_HAVE_XSAVE | ||
528 | #define KVM_CAP_XSAVE 55 | ||
529 | #endif | ||
530 | #ifdef __KVM_HAVE_XCRS | ||
531 | #define KVM_CAP_XCRS 56 | ||
532 | #endif | ||
527 | 533 | ||
528 | #ifdef KVM_CAP_IRQ_ROUTING | 534 | #ifdef KVM_CAP_IRQ_ROUTING |
529 | 535 | ||
@@ -714,6 +720,12 @@ struct kvm_clock_data { | |||
714 | #define KVM_GET_DEBUGREGS _IOR(KVMIO, 0xa1, struct kvm_debugregs) | 720 | #define KVM_GET_DEBUGREGS _IOR(KVMIO, 0xa1, struct kvm_debugregs) |
715 | #define KVM_SET_DEBUGREGS _IOW(KVMIO, 0xa2, struct kvm_debugregs) | 721 | #define KVM_SET_DEBUGREGS _IOW(KVMIO, 0xa2, struct kvm_debugregs) |
716 | #define KVM_ENABLE_CAP _IOW(KVMIO, 0xa3, struct kvm_enable_cap) | 722 | #define KVM_ENABLE_CAP _IOW(KVMIO, 0xa3, struct kvm_enable_cap) |
723 | /* Available with KVM_CAP_XSAVE */ | ||
724 | #define KVM_GET_XSAVE _IOR(KVMIO, 0xa4, struct kvm_xsave) | ||
725 | #define KVM_SET_XSAVE _IOW(KVMIO, 0xa5, struct kvm_xsave) | ||
726 | /* Available with KVM_CAP_XCRS */ | ||
727 | #define KVM_GET_XCRS _IOR(KVMIO, 0xa6, struct kvm_xcrs) | ||
728 | #define KVM_SET_XCRS _IOW(KVMIO, 0xa7, struct kvm_xcrs) | ||
717 | 729 | ||
718 | #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) | 730 | #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) |
719 | 731 | ||