summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHendrik Brueckner <brueckner@linux.vnet.ibm.com>2015-06-12 13:53:51 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-07-22 09:57:59 +0200
commit96b2d7a83a27fbae10fc57c39577a7e2689d9f0a (patch)
treeb091792af14cd9f1ffcf54cdce37c1f4f402664d
parent4084eb7767418861a81d9e24d222f2536537f58e (diff)
downloadop-kernel-dev-96b2d7a83a27fbae10fc57c39577a7e2689d9f0a.zip
op-kernel-dev-96b2d7a83a27fbae10fc57c39577a7e2689d9f0a.tar.gz
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>
-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 2078f92..fc7bc71 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)
void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
+ __u32 fpc;
+
save_fp_ctl(&vcpu->arch.host_fpregs.fpc);
if (test_kvm_facility(vcpu->kvm, 129))
save_vx_regs((__vector128 *)&vcpu->arch.host_vregs->vrs);
@@ -1207,12 +1209,16 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
save_fp_regs(vcpu->arch.host_fpregs.fprs);
save_access_regs(vcpu->arch.host_acrs);
if (test_kvm_facility(vcpu->kvm, 129)) {
- restore_fp_ctl(&vcpu->run->s.regs.fpc);
+ fpc = vcpu->run->s.regs.fpc;
restore_vx_regs((__vector128 *)&vcpu->run->s.regs.vrs);
} else {
- restore_fp_ctl(&vcpu->arch.guest_fpregs.fpc);
+ fpc = vcpu->arch.guest_fpregs.fpc;
restore_fp_regs(vcpu->arch.guest_fpregs.fprs);
}
+ if (test_fp_ctl(fpc))
+ /* User space provided an invalid FPC, let's clear it */
+ fpc = 0;
+ restore_fp_ctl(&fpc);
restore_access_regs(vcpu->run->s.regs.acrs);
gmap_enable(vcpu->arch.gmap);
atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
OpenPOWER on IntegriCloud