]> xenbits.xensource.com Git - xen.git/commitdiff
x86/EFI: further correct FPU state handling around runtime calls
authorJan Beulich <jbeulich@suse.com>
Thu, 28 Jun 2018 09:29:48 +0000 (11:29 +0200)
committerJan Beulich <jbeulich@suse.com>
Thu, 28 Jun 2018 09:29:48 +0000 (11:29 +0200)
We must not leave a vCPU with CR0.TS clear when it is not in fully eager
mode and has not touched non-lazy state. Instead of adding a 3rd
invocation of stts() to vcpu_restore_fpu_eager(), consolidate all of
them into a single one done at the end of the function.

Rename the function at the same time to better reflect its purpose, as
the patches touches all of its occurences anyway.

The new function parameter is not really well named, but
"need_stts_if_not_fully_eager" seemed excessive to me.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Paul Durrant <paul.durrant@citrix.com>
master commit: 23839a0fa0bbe78c174cd2bb49083e153f0f99df
master date: 2018-06-26 15:23:08 +0200

xen/arch/x86/domain.c
xen/arch/x86/i387.c
xen/common/efi/runtime.c
xen/include/asm-x86/i387.h

index a3e913b162c517ea542a1f32b08c962dd0e05e5b..596be5c4f529d98357521b58e82c8ecab3bb7c59 100644 (file)
@@ -2147,7 +2147,7 @@ static void __context_switch(void)
             if ( cpu_has_xsaves && has_hvm_container_vcpu(n) )
                 set_msr_xss(n->arch.hvm_vcpu.msr_xss);
         }
-        vcpu_restore_fpu_eager(n);
+        vcpu_restore_fpu_nonlazy(n, 0);
         n->arch.ctxt_switch_to(n);
     }
 
index 992d4d21c1cd3ea203f2ffab7374ce03b5acb050..286847148af06b9d60a027e777856720c50aee16 100644 (file)
@@ -207,11 +207,11 @@ static inline void fpu_fxsave(struct vcpu *v)
 /*       VCPU FPU Functions    */
 /*******************************/
 /* Restore FPU state whenever VCPU is schduled in. */
-void vcpu_restore_fpu_eager(struct vcpu *v)
+void vcpu_restore_fpu_nonlazy(struct vcpu *v, bool_t need_stts)
 {
     /* Restore nonlazy extended state (i.e. parts not tracked by CR0.TS). */
     if ( !v->arch.fully_eager_fpu && !v->arch.nonlazy_xstate_used )
-        return;
+        goto maybe_stts;
 
     ASSERT(!is_idle_vcpu(v));
 
@@ -234,14 +234,17 @@ void vcpu_restore_fpu_eager(struct vcpu *v)
         v->fpu_dirtied = 1;
 
         /* Xen doesn't need TS set, but the guest might. */
-        if ( is_pv_vcpu(v) && (v->arch.pv_vcpu.ctrlreg[0] & X86_CR0_TS) )
-            stts();
+        need_stts = is_pv_vcpu(v) && (v->arch.pv_vcpu.ctrlreg[0] & X86_CR0_TS);
     }
     else
     {
         fpu_xrstor(v, XSTATE_NONLAZY);
-        stts();
+        need_stts = 1;
     }
+
+ maybe_stts:
+    if ( need_stts )
+        stts();
 }
 
 /* 
index 65402e2d1f7bbb830fc07f121ff3becc13116cab..f53101a5e5f32adfabf5e50aea464fa64b729813 100644 (file)
@@ -130,7 +130,7 @@ void efi_rs_leave(struct efi_rs_state *state)
     irq_exit();
     efi_rs_on_cpu = NR_CPUS;
     spin_unlock(&efi_rs_lock);
-    vcpu_restore_fpu_eager(curr);
+    vcpu_restore_fpu_nonlazy(curr, 1);
 }
 
 bool_t efi_rs_using_pgtables(void)
index 7cfa215d303b273a832b4ea512aef9e11023a40a..5a4d778033863a3566caec2a88d8c0dfc95226d8 100644 (file)
@@ -28,7 +28,7 @@ struct ix87_env {
     uint16_t fds, _res6;
 };
 
-void vcpu_restore_fpu_eager(struct vcpu *v);
+void vcpu_restore_fpu_nonlazy(struct vcpu *v, bool_t need_stts);
 void vcpu_restore_fpu_lazy(struct vcpu *v);
 void vcpu_save_fpu(struct vcpu *v);
 void save_fpu_enable(void);