aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm
diff options
context:
space:
mode:
authorHendrik Brueckner <brueckner@linux.vnet.ibm.com>2015-06-12 07:53:51 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-07-22 03:57:59 -0400
commit96b2d7a83a27fbae10fc57c39577a7e2689d9f0a (patch)
treeb091792af14cd9f1ffcf54cdce37c1f4f402664d /arch/s390/kvm
parent4084eb7767418861a81d9e24d222f2536537f58e (diff)
s390/kvm: validate the floating-point control before restoring it
The kvm_arch_vcpu_load() does not validate whether the floating-point control (FPC) is valid. Further, the return code of the restore is not checked too. If the FPC is invalid, the restore fails and the host FPC value might remain. The correct behavior would be to clear the FPC if it is not valid. Hence, validate the FPC value and, optionally, reset the value before restoring it. Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kvm')
-rw-r--r--arch/s390/kvm/kvm-s390.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 2078f92d15ac..fc7bc7118b23 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -1200,6 +1200,8 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
1200 1200
1201void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) 1201void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
1202{ 1202{
1203 __u32 fpc;
1204
1203 save_fp_ctl(&vcpu->arch.host_fpregs.fpc); 1205 save_fp_ctl(&vcpu->arch.host_fpregs.fpc);
1204 if (test_kvm_facility(vcpu->kvm, 129)) 1206 if (test_kvm_facility(vcpu->kvm, 129))
1205 save_vx_regs((__vector128 *)&vcpu->arch.host_vregs->vrs); 1207 save_vx_regs((__vector128 *)&vcpu->arch.host_vregs->vrs);
@@ -1207,12 +1209,16 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
1207 save_fp_regs(vcpu->arch.host_fpregs.fprs); 1209 save_fp_regs(vcpu->arch.host_fpregs.fprs);
1208 save_access_regs(vcpu->arch.host_acrs); 1210 save_access_regs(vcpu->arch.host_acrs);
1209 if (test_kvm_facility(vcpu->kvm, 129)) { 1211 if (test_kvm_facility(vcpu->kvm, 129)) {
1210 restore_fp_ctl(&vcpu->run->s.regs.fpc); 1212 fpc = vcpu->run->s.regs.fpc;
1211 restore_vx_regs((__vector128 *)&vcpu->run->s.regs.vrs); 1213 restore_vx_regs((__vector128 *)&vcpu->run->s.regs.vrs);
1212 } else { 1214 } else {
1213 restore_fp_ctl(&vcpu->arch.guest_fpregs.fpc); 1215 fpc = vcpu->arch.guest_fpregs.fpc;
1214 restore_fp_regs(vcpu->arch.guest_fpregs.fprs); 1216 restore_fp_regs(vcpu->arch.guest_fpregs.fprs);
1215 } 1217 }
1218 if (test_fp_ctl(fpc))
1219 /* User space provided an invalid FPC, let's clear it */
1220 fpc = 0;
1221 restore_fp_ctl(&fpc);
1216 restore_access_regs(vcpu->run->s.regs.acrs); 1222 restore_access_regs(vcpu->run->s.regs.acrs);
1217 gmap_enable(vcpu->arch.gmap); 1223 gmap_enable(vcpu->arch.gmap);
1218 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); 1224 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);