|
@@ -1812,19 +1812,6 @@ __u64 kvm_s390_get_cpu_timer(struct kvm_vcpu *vcpu)
|
|
|
|
|
|
void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
|
|
{
|
|
|
- /* Save host register state */
|
|
|
- save_fpu_regs();
|
|
|
- vcpu->arch.host_fpregs.fpc = current->thread.fpu.fpc;
|
|
|
- vcpu->arch.host_fpregs.regs = current->thread.fpu.regs;
|
|
|
-
|
|
|
- if (MACHINE_HAS_VX)
|
|
|
- current->thread.fpu.regs = vcpu->run->s.regs.vrs;
|
|
|
- else
|
|
|
- current->thread.fpu.regs = vcpu->run->s.regs.fprs;
|
|
|
- current->thread.fpu.fpc = vcpu->run->s.regs.fpc;
|
|
|
- if (test_fp_ctl(current->thread.fpu.fpc))
|
|
|
- /* User space provided an invalid FPC, let's clear it */
|
|
|
- current->thread.fpu.fpc = 0;
|
|
|
|
|
|
gmap_enable(vcpu->arch.enabled_gmap);
|
|
|
atomic_or(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
|
|
@@ -1842,13 +1829,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
|
|
|
vcpu->arch.enabled_gmap = gmap_get_enabled();
|
|
|
gmap_disable(vcpu->arch.enabled_gmap);
|
|
|
|
|
|
- /* Save guest register state */
|
|
|
- save_fpu_regs();
|
|
|
- vcpu->run->s.regs.fpc = current->thread.fpu.fpc;
|
|
|
-
|
|
|
- /* Restore host register state */
|
|
|
- current->thread.fpu.fpc = vcpu->arch.host_fpregs.fpc;
|
|
|
- current->thread.fpu.regs = vcpu->arch.host_fpregs.regs;
|
|
|
}
|
|
|
|
|
|
static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
|
|
@@ -2251,11 +2231,9 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
|
|
|
|
|
|
int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
|
|
|
{
|
|
|
- /* make sure the new values will be lazily loaded */
|
|
|
- save_fpu_regs();
|
|
|
if (test_fp_ctl(fpu->fpc))
|
|
|
return -EINVAL;
|
|
|
- current->thread.fpu.fpc = fpu->fpc;
|
|
|
+ vcpu->run->s.regs.fpc = fpu->fpc;
|
|
|
if (MACHINE_HAS_VX)
|
|
|
convert_fp_to_vx((__vector128 *) vcpu->run->s.regs.vrs,
|
|
|
(freg_t *) fpu->fprs);
|
|
@@ -2273,7 +2251,7 @@ int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
|
|
|
(__vector128 *) vcpu->run->s.regs.vrs);
|
|
|
else
|
|
|
memcpy(fpu->fprs, vcpu->run->s.regs.fprs, sizeof(fpu->fprs));
|
|
|
- fpu->fpc = current->thread.fpu.fpc;
|
|
|
+ fpu->fpc = vcpu->run->s.regs.fpc;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -2736,6 +2714,18 @@ static void sync_regs(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
|
|
}
|
|
|
save_access_regs(vcpu->arch.host_acrs);
|
|
|
restore_access_regs(vcpu->run->s.regs.acrs);
|
|
|
+ /* save host (userspace) fprs/vrs */
|
|
|
+ save_fpu_regs();
|
|
|
+ vcpu->arch.host_fpregs.fpc = current->thread.fpu.fpc;
|
|
|
+ vcpu->arch.host_fpregs.regs = current->thread.fpu.regs;
|
|
|
+ if (MACHINE_HAS_VX)
|
|
|
+ current->thread.fpu.regs = vcpu->run->s.regs.vrs;
|
|
|
+ else
|
|
|
+ current->thread.fpu.regs = vcpu->run->s.regs.fprs;
|
|
|
+ current->thread.fpu.fpc = vcpu->run->s.regs.fpc;
|
|
|
+ if (test_fp_ctl(current->thread.fpu.fpc))
|
|
|
+ /* User space provided an invalid FPC, let's clear it */
|
|
|
+ current->thread.fpu.fpc = 0;
|
|
|
|
|
|
kvm_run->kvm_dirty_regs = 0;
|
|
|
}
|
|
@@ -2756,6 +2746,13 @@ static void store_regs(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
|
|
kvm_run->s.regs.pfc = vcpu->arch.pfault_compare;
|
|
|
save_access_regs(vcpu->run->s.regs.acrs);
|
|
|
restore_access_regs(vcpu->arch.host_acrs);
|
|
|
+ /* Save guest register state */
|
|
|
+ save_fpu_regs();
|
|
|
+ vcpu->run->s.regs.fpc = current->thread.fpu.fpc;
|
|
|
+ /* Restore will be done lazily at return */
|
|
|
+ current->thread.fpu.fpc = vcpu->arch.host_fpregs.fpc;
|
|
|
+ current->thread.fpu.regs = vcpu->arch.host_fpregs.regs;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|