Loading Documentation/kvm/api.txt +74 −0 Original line number Diff line number Diff line Loading @@ -922,6 +922,80 @@ Define which vcpu is the Bootstrap Processor (BSP). Values are the same as the vcpu id in KVM_CREATE_VCPU. If this ioctl is not called, the default is vcpu 0. 4.41 KVM_GET_XSAVE Capability: KVM_CAP_XSAVE Architectures: x86 Type: vcpu ioctl Parameters: struct kvm_xsave (out) Returns: 0 on success, -1 on error struct kvm_xsave { __u32 region[1024]; }; This ioctl would copy current vcpu's xsave struct to the userspace. 4.42 KVM_SET_XSAVE Capability: KVM_CAP_XSAVE Architectures: x86 Type: vcpu ioctl Parameters: struct kvm_xsave (in) Returns: 0 on success, -1 on error struct kvm_xsave { __u32 region[1024]; }; This ioctl would copy userspace's xsave struct to the kernel. 4.43 KVM_GET_XCRS Capability: KVM_CAP_XCRS Architectures: x86 Type: vcpu ioctl Parameters: struct kvm_xcrs (out) Returns: 0 on success, -1 on error struct kvm_xcr { __u32 xcr; __u32 reserved; __u64 value; }; struct kvm_xcrs { __u32 nr_xcrs; __u32 flags; struct kvm_xcr xcrs[KVM_MAX_XCRS]; __u64 padding[16]; }; This ioctl would copy current vcpu's xcrs to the userspace. 4.44 KVM_SET_XCRS Capability: KVM_CAP_XCRS Architectures: x86 Type: vcpu ioctl Parameters: struct kvm_xcrs (in) Returns: 0 on success, -1 on error struct kvm_xcr { __u32 xcr; __u32 reserved; __u64 value; }; struct kvm_xcrs { __u32 nr_xcrs; __u32 flags; struct kvm_xcr xcrs[KVM_MAX_XCRS]; __u64 padding[16]; }; This ioctl would set vcpu's xcr to the value userspace specified. 5. The kvm_run structure Application code obtains a pointer to the kvm_run structure by Loading arch/x86/include/asm/kvm.h +22 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ #define __KVM_HAVE_XEN_HVM #define __KVM_HAVE_VCPU_EVENTS #define __KVM_HAVE_DEBUGREGS #define __KVM_HAVE_XSAVE #define __KVM_HAVE_XCRS /* Architectural interrupt line count. */ #define KVM_NR_INTERRUPTS 256 Loading Loading @@ -299,4 +301,24 @@ struct kvm_debugregs { __u64 reserved[9]; }; /* for KVM_CAP_XSAVE */ struct kvm_xsave { __u32 region[1024]; }; #define KVM_MAX_XCRS 16 struct kvm_xcr { __u32 xcr; __u32 reserved; __u64 value; }; struct kvm_xcrs { __u32 nr_xcrs; __u32 flags; struct kvm_xcr xcrs[KVM_MAX_XCRS]; __u64 padding[16]; }; #endif /* _ASM_X86_KVM_H */ arch/x86/include/asm/xsave.h +5 −2 Original line number Diff line number Diff line Loading @@ -13,8 +13,11 @@ #define FXSAVE_SIZE 512 #define XSTATE_YMM_SIZE 256 #define XSTATE_YMM_OFFSET (512 + 64) #define XSAVE_HDR_SIZE 64 #define XSAVE_HDR_OFFSET FXSAVE_SIZE #define XSAVE_YMM_SIZE 256 #define XSAVE_YMM_OFFSET (XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET) /* * These are the features that the OS can handle currently. Loading arch/x86/kvm/x86.c +139 −0 Original line number Diff line number Diff line Loading @@ -1680,6 +1680,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_PCI_SEGMENT: case KVM_CAP_DEBUGREGS: case KVM_CAP_X86_ROBUST_SINGLESTEP: case KVM_CAP_XSAVE: r = 1; break; case KVM_CAP_COALESCED_MMIO: Loading @@ -1703,6 +1704,9 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_MCE: r = KVM_MAX_MCE_BANKS; break; case KVM_CAP_XCRS: r = cpu_has_xsave; break; default: r = 0; break; Loading Loading @@ -2355,6 +2359,77 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, return 0; } static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu, struct kvm_xsave *guest_xsave) { if (cpu_has_xsave) memcpy(guest_xsave->region, &vcpu->arch.guest_fpu.state->xsave, sizeof(struct xsave_struct)); else { memcpy(guest_xsave->region, &vcpu->arch.guest_fpu.state->fxsave, sizeof(struct i387_fxsave_struct)); *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)] = XSTATE_FPSSE; } } static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu, struct kvm_xsave *guest_xsave) { u64 xstate_bv = *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)]; if (cpu_has_xsave) memcpy(&vcpu->arch.guest_fpu.state->xsave, guest_xsave->region, sizeof(struct xsave_struct)); else { if (xstate_bv & ~XSTATE_FPSSE) return -EINVAL; memcpy(&vcpu->arch.guest_fpu.state->fxsave, guest_xsave->region, sizeof(struct i387_fxsave_struct)); } return 0; } static void kvm_vcpu_ioctl_x86_get_xcrs(struct kvm_vcpu *vcpu, struct kvm_xcrs *guest_xcrs) { if (!cpu_has_xsave) { guest_xcrs->nr_xcrs = 0; return; } guest_xcrs->nr_xcrs = 1; guest_xcrs->flags = 0; guest_xcrs->xcrs[0].xcr = XCR_XFEATURE_ENABLED_MASK; guest_xcrs->xcrs[0].value = vcpu->arch.xcr0; } static int kvm_vcpu_ioctl_x86_set_xcrs(struct kvm_vcpu *vcpu, struct kvm_xcrs *guest_xcrs) { int i, r = 0; if (!cpu_has_xsave) return -EINVAL; if (guest_xcrs->nr_xcrs > KVM_MAX_XCRS || guest_xcrs->flags) return -EINVAL; for (i = 0; i < guest_xcrs->nr_xcrs; i++) /* Only support XCR0 currently */ if (guest_xcrs->xcrs[0].xcr == XCR_XFEATURE_ENABLED_MASK) { r = __kvm_set_xcr(vcpu, XCR_XFEATURE_ENABLED_MASK, guest_xcrs->xcrs[0].value); break; } if (r) r = -EINVAL; return r; } long kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { Loading Loading @@ -2556,6 +2631,70 @@ long kvm_arch_vcpu_ioctl(struct file *filp, r = kvm_vcpu_ioctl_x86_set_debugregs(vcpu, &dbgregs); break; } case KVM_GET_XSAVE: { struct kvm_xsave *xsave; xsave = kzalloc(sizeof(struct kvm_xsave), GFP_KERNEL); r = -ENOMEM; if (!xsave) break; kvm_vcpu_ioctl_x86_get_xsave(vcpu, xsave); r = -EFAULT; if (copy_to_user(argp, xsave, sizeof(struct kvm_xsave))) break; r = 0; break; } case KVM_SET_XSAVE: { struct kvm_xsave *xsave; xsave = kzalloc(sizeof(struct kvm_xsave), GFP_KERNEL); r = -ENOMEM; if (!xsave) break; r = -EFAULT; if (copy_from_user(xsave, argp, sizeof(struct kvm_xsave))) break; r = kvm_vcpu_ioctl_x86_set_xsave(vcpu, xsave); break; } case KVM_GET_XCRS: { struct kvm_xcrs *xcrs; xcrs = kzalloc(sizeof(struct kvm_xcrs), GFP_KERNEL); r = -ENOMEM; if (!xcrs) break; kvm_vcpu_ioctl_x86_get_xcrs(vcpu, xcrs); r = -EFAULT; if (copy_to_user(argp, xcrs, sizeof(struct kvm_xcrs))) break; r = 0; break; } case KVM_SET_XCRS: { struct kvm_xcrs *xcrs; xcrs = kzalloc(sizeof(struct kvm_xcrs), GFP_KERNEL); r = -ENOMEM; if (!xcrs) break; r = -EFAULT; if (copy_from_user(xcrs, argp, sizeof(struct kvm_xcrs))) break; r = kvm_vcpu_ioctl_x86_set_xcrs(vcpu, xcrs); break; } default: r = -EINVAL; } Loading include/linux/kvm.h +12 −0 Original line number Diff line number Diff line Loading @@ -524,6 +524,12 @@ struct kvm_enable_cap { #define KVM_CAP_PPC_OSI 52 #define KVM_CAP_PPC_UNSET_IRQ 53 #define KVM_CAP_ENABLE_CAP 54 #ifdef __KVM_HAVE_XSAVE #define KVM_CAP_XSAVE 55 #endif #ifdef __KVM_HAVE_XCRS #define KVM_CAP_XCRS 56 #endif #ifdef KVM_CAP_IRQ_ROUTING Loading Loading @@ -714,6 +720,12 @@ struct kvm_clock_data { #define KVM_GET_DEBUGREGS _IOR(KVMIO, 0xa1, struct kvm_debugregs) #define KVM_SET_DEBUGREGS _IOW(KVMIO, 0xa2, struct kvm_debugregs) #define KVM_ENABLE_CAP _IOW(KVMIO, 0xa3, struct kvm_enable_cap) /* Available with KVM_CAP_XSAVE */ #define KVM_GET_XSAVE _IOR(KVMIO, 0xa4, struct kvm_xsave) #define KVM_SET_XSAVE _IOW(KVMIO, 0xa5, struct kvm_xsave) /* Available with KVM_CAP_XCRS */ #define KVM_GET_XCRS _IOR(KVMIO, 0xa6, struct kvm_xcrs) #define KVM_SET_XCRS _IOW(KVMIO, 0xa7, struct kvm_xcrs) #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) Loading Loading
Documentation/kvm/api.txt +74 −0 Original line number Diff line number Diff line Loading @@ -922,6 +922,80 @@ Define which vcpu is the Bootstrap Processor (BSP). Values are the same as the vcpu id in KVM_CREATE_VCPU. If this ioctl is not called, the default is vcpu 0. 4.41 KVM_GET_XSAVE Capability: KVM_CAP_XSAVE Architectures: x86 Type: vcpu ioctl Parameters: struct kvm_xsave (out) Returns: 0 on success, -1 on error struct kvm_xsave { __u32 region[1024]; }; This ioctl would copy current vcpu's xsave struct to the userspace. 4.42 KVM_SET_XSAVE Capability: KVM_CAP_XSAVE Architectures: x86 Type: vcpu ioctl Parameters: struct kvm_xsave (in) Returns: 0 on success, -1 on error struct kvm_xsave { __u32 region[1024]; }; This ioctl would copy userspace's xsave struct to the kernel. 4.43 KVM_GET_XCRS Capability: KVM_CAP_XCRS Architectures: x86 Type: vcpu ioctl Parameters: struct kvm_xcrs (out) Returns: 0 on success, -1 on error struct kvm_xcr { __u32 xcr; __u32 reserved; __u64 value; }; struct kvm_xcrs { __u32 nr_xcrs; __u32 flags; struct kvm_xcr xcrs[KVM_MAX_XCRS]; __u64 padding[16]; }; This ioctl would copy current vcpu's xcrs to the userspace. 4.44 KVM_SET_XCRS Capability: KVM_CAP_XCRS Architectures: x86 Type: vcpu ioctl Parameters: struct kvm_xcrs (in) Returns: 0 on success, -1 on error struct kvm_xcr { __u32 xcr; __u32 reserved; __u64 value; }; struct kvm_xcrs { __u32 nr_xcrs; __u32 flags; struct kvm_xcr xcrs[KVM_MAX_XCRS]; __u64 padding[16]; }; This ioctl would set vcpu's xcr to the value userspace specified. 5. The kvm_run structure Application code obtains a pointer to the kvm_run structure by Loading
arch/x86/include/asm/kvm.h +22 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ #define __KVM_HAVE_XEN_HVM #define __KVM_HAVE_VCPU_EVENTS #define __KVM_HAVE_DEBUGREGS #define __KVM_HAVE_XSAVE #define __KVM_HAVE_XCRS /* Architectural interrupt line count. */ #define KVM_NR_INTERRUPTS 256 Loading Loading @@ -299,4 +301,24 @@ struct kvm_debugregs { __u64 reserved[9]; }; /* for KVM_CAP_XSAVE */ struct kvm_xsave { __u32 region[1024]; }; #define KVM_MAX_XCRS 16 struct kvm_xcr { __u32 xcr; __u32 reserved; __u64 value; }; struct kvm_xcrs { __u32 nr_xcrs; __u32 flags; struct kvm_xcr xcrs[KVM_MAX_XCRS]; __u64 padding[16]; }; #endif /* _ASM_X86_KVM_H */
arch/x86/include/asm/xsave.h +5 −2 Original line number Diff line number Diff line Loading @@ -13,8 +13,11 @@ #define FXSAVE_SIZE 512 #define XSTATE_YMM_SIZE 256 #define XSTATE_YMM_OFFSET (512 + 64) #define XSAVE_HDR_SIZE 64 #define XSAVE_HDR_OFFSET FXSAVE_SIZE #define XSAVE_YMM_SIZE 256 #define XSAVE_YMM_OFFSET (XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET) /* * These are the features that the OS can handle currently. Loading
arch/x86/kvm/x86.c +139 −0 Original line number Diff line number Diff line Loading @@ -1680,6 +1680,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_PCI_SEGMENT: case KVM_CAP_DEBUGREGS: case KVM_CAP_X86_ROBUST_SINGLESTEP: case KVM_CAP_XSAVE: r = 1; break; case KVM_CAP_COALESCED_MMIO: Loading @@ -1703,6 +1704,9 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_MCE: r = KVM_MAX_MCE_BANKS; break; case KVM_CAP_XCRS: r = cpu_has_xsave; break; default: r = 0; break; Loading Loading @@ -2355,6 +2359,77 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, return 0; } static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu, struct kvm_xsave *guest_xsave) { if (cpu_has_xsave) memcpy(guest_xsave->region, &vcpu->arch.guest_fpu.state->xsave, sizeof(struct xsave_struct)); else { memcpy(guest_xsave->region, &vcpu->arch.guest_fpu.state->fxsave, sizeof(struct i387_fxsave_struct)); *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)] = XSTATE_FPSSE; } } static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu, struct kvm_xsave *guest_xsave) { u64 xstate_bv = *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)]; if (cpu_has_xsave) memcpy(&vcpu->arch.guest_fpu.state->xsave, guest_xsave->region, sizeof(struct xsave_struct)); else { if (xstate_bv & ~XSTATE_FPSSE) return -EINVAL; memcpy(&vcpu->arch.guest_fpu.state->fxsave, guest_xsave->region, sizeof(struct i387_fxsave_struct)); } return 0; } static void kvm_vcpu_ioctl_x86_get_xcrs(struct kvm_vcpu *vcpu, struct kvm_xcrs *guest_xcrs) { if (!cpu_has_xsave) { guest_xcrs->nr_xcrs = 0; return; } guest_xcrs->nr_xcrs = 1; guest_xcrs->flags = 0; guest_xcrs->xcrs[0].xcr = XCR_XFEATURE_ENABLED_MASK; guest_xcrs->xcrs[0].value = vcpu->arch.xcr0; } static int kvm_vcpu_ioctl_x86_set_xcrs(struct kvm_vcpu *vcpu, struct kvm_xcrs *guest_xcrs) { int i, r = 0; if (!cpu_has_xsave) return -EINVAL; if (guest_xcrs->nr_xcrs > KVM_MAX_XCRS || guest_xcrs->flags) return -EINVAL; for (i = 0; i < guest_xcrs->nr_xcrs; i++) /* Only support XCR0 currently */ if (guest_xcrs->xcrs[0].xcr == XCR_XFEATURE_ENABLED_MASK) { r = __kvm_set_xcr(vcpu, XCR_XFEATURE_ENABLED_MASK, guest_xcrs->xcrs[0].value); break; } if (r) r = -EINVAL; return r; } long kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { Loading Loading @@ -2556,6 +2631,70 @@ long kvm_arch_vcpu_ioctl(struct file *filp, r = kvm_vcpu_ioctl_x86_set_debugregs(vcpu, &dbgregs); break; } case KVM_GET_XSAVE: { struct kvm_xsave *xsave; xsave = kzalloc(sizeof(struct kvm_xsave), GFP_KERNEL); r = -ENOMEM; if (!xsave) break; kvm_vcpu_ioctl_x86_get_xsave(vcpu, xsave); r = -EFAULT; if (copy_to_user(argp, xsave, sizeof(struct kvm_xsave))) break; r = 0; break; } case KVM_SET_XSAVE: { struct kvm_xsave *xsave; xsave = kzalloc(sizeof(struct kvm_xsave), GFP_KERNEL); r = -ENOMEM; if (!xsave) break; r = -EFAULT; if (copy_from_user(xsave, argp, sizeof(struct kvm_xsave))) break; r = kvm_vcpu_ioctl_x86_set_xsave(vcpu, xsave); break; } case KVM_GET_XCRS: { struct kvm_xcrs *xcrs; xcrs = kzalloc(sizeof(struct kvm_xcrs), GFP_KERNEL); r = -ENOMEM; if (!xcrs) break; kvm_vcpu_ioctl_x86_get_xcrs(vcpu, xcrs); r = -EFAULT; if (copy_to_user(argp, xcrs, sizeof(struct kvm_xcrs))) break; r = 0; break; } case KVM_SET_XCRS: { struct kvm_xcrs *xcrs; xcrs = kzalloc(sizeof(struct kvm_xcrs), GFP_KERNEL); r = -ENOMEM; if (!xcrs) break; r = -EFAULT; if (copy_from_user(xcrs, argp, sizeof(struct kvm_xcrs))) break; r = kvm_vcpu_ioctl_x86_set_xcrs(vcpu, xcrs); break; } default: r = -EINVAL; } Loading
include/linux/kvm.h +12 −0 Original line number Diff line number Diff line Loading @@ -524,6 +524,12 @@ struct kvm_enable_cap { #define KVM_CAP_PPC_OSI 52 #define KVM_CAP_PPC_UNSET_IRQ 53 #define KVM_CAP_ENABLE_CAP 54 #ifdef __KVM_HAVE_XSAVE #define KVM_CAP_XSAVE 55 #endif #ifdef __KVM_HAVE_XCRS #define KVM_CAP_XCRS 56 #endif #ifdef KVM_CAP_IRQ_ROUTING Loading Loading @@ -714,6 +720,12 @@ struct kvm_clock_data { #define KVM_GET_DEBUGREGS _IOR(KVMIO, 0xa1, struct kvm_debugregs) #define KVM_SET_DEBUGREGS _IOW(KVMIO, 0xa2, struct kvm_debugregs) #define KVM_ENABLE_CAP _IOW(KVMIO, 0xa3, struct kvm_enable_cap) /* Available with KVM_CAP_XSAVE */ #define KVM_GET_XSAVE _IOR(KVMIO, 0xa4, struct kvm_xsave) #define KVM_SET_XSAVE _IOW(KVMIO, 0xa5, struct kvm_xsave) /* Available with KVM_CAP_XCRS */ #define KVM_GET_XCRS _IOR(KVMIO, 0xa6, struct kvm_xcrs) #define KVM_SET_XCRS _IOW(KVMIO, 0xa7, struct kvm_xcrs) #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) Loading