Merge tag 'kvm-4.15-1' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[linux-2.6-block.git] / virt / kvm / arm / arm.c
index bc126fb99a3d2ce1c4bc55781c1db51f4aada264..772bf74ac2e9ae8380e0ba2b87b385883eca6d4c 100644 (file)
@@ -651,6 +651,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
                 */
                preempt_disable();
 
+               /* Flush FP/SIMD state that can't survive guest entry/exit */
+               kvm_fpsimd_flush_cpu_state();
+
                kvm_pmu_flush_hwstate(vcpu);
 
                local_irq_disable();
@@ -1335,21 +1338,12 @@ static void teardown_hyp_mode(void)
 {
        int cpu;
 
-       if (is_kernel_in_hyp_mode())
-               return;
-
        free_hyp_pgds();
        for_each_possible_cpu(cpu)
                free_page(per_cpu(kvm_arm_hyp_stack_page, cpu));
        hyp_cpu_pm_exit();
 }
 
-static int init_vhe_mode(void)
-{
-       kvm_info("VHE mode initialized successfully\n");
-       return 0;
-}
-
 /**
  * Inits Hyp-mode on all online CPUs
  */
@@ -1430,8 +1424,6 @@ static int init_hyp_mode(void)
                }
        }
 
-       kvm_info("Hyp mode initialized successfully\n");
-
        return 0;
 
 out_err:
@@ -1465,6 +1457,7 @@ int kvm_arch_init(void *opaque)
 {
        int err;
        int ret, cpu;
+       bool in_hyp_mode;
 
        if (!is_hyp_mode_available()) {
                kvm_err("HYP mode not available\n");
@@ -1483,21 +1476,28 @@ int kvm_arch_init(void *opaque)
        if (err)
                return err;
 
-       if (is_kernel_in_hyp_mode())
-               err = init_vhe_mode();
-       else
+       in_hyp_mode = is_kernel_in_hyp_mode();
+
+       if (!in_hyp_mode) {
                err = init_hyp_mode();
-       if (err)
-               goto out_err;
+               if (err)
+                       goto out_err;
+       }
 
        err = init_subsystems();
        if (err)
                goto out_hyp;
 
+       if (in_hyp_mode)
+               kvm_info("VHE mode initialized successfully\n");
+       else
+               kvm_info("Hyp mode initialized successfully\n");
+
        return 0;
 
 out_hyp:
-       teardown_hyp_mode();
+       if (!in_hyp_mode)
+               teardown_hyp_mode();
 out_err:
        teardown_common_resources();
        return err;