|
@@ -2984,11 +2984,13 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
|
|
|
static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,
|
|
|
struct kvm_xsave *guest_xsave)
|
|
|
{
|
|
|
- if (cpu_has_xsave)
|
|
|
+ if (cpu_has_xsave) {
|
|
|
memcpy(guest_xsave->region,
|
|
|
&vcpu->arch.guest_fpu.state->xsave,
|
|
|
- xstate_size);
|
|
|
- else {
|
|
|
+ vcpu->arch.guest_xstate_size);
|
|
|
+ *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)] &=
|
|
|
+ vcpu->arch.guest_supported_xcr0 | XSTATE_FPSSE;
|
|
|
+ } else {
|
|
|
memcpy(guest_xsave->region,
|
|
|
&vcpu->arch.guest_fpu.state->fxsave,
|
|
|
sizeof(struct i387_fxsave_struct));
|
|
@@ -3014,7 +3016,7 @@ static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
|
|
|
if (xstate_bv & ~host_xcr0)
|
|
|
return -EINVAL;
|
|
|
memcpy(&vcpu->arch.guest_fpu.state->xsave,
|
|
|
- guest_xsave->region, xstate_size);
|
|
|
+ guest_xsave->region, vcpu->arch.guest_xstate_size);
|
|
|
} else {
|
|
|
if (xstate_bv & ~XSTATE_FPSSE)
|
|
|
return -EINVAL;
|
|
@@ -6951,6 +6953,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
|
|
|
vcpu->arch.pv_time_enabled = false;
|
|
|
|
|
|
vcpu->arch.guest_supported_xcr0 = 0;
|
|
|
+ vcpu->arch.guest_xstate_size = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET;
|
|
|
|
|
|
kvm_async_pf_hash_reset(vcpu);
|
|
|
kvm_pmu_init(vcpu);
|