]> git.baikalelectronics.ru Git - kernel.git/commitdiff
x86/process/64: Make save_fsgs_for_kvm() ready for FSGSBASE
authorThomas Gleixner <tglx@linutronix.de>
Thu, 28 May 2020 20:13:52 +0000 (16:13 -0400)
committerThomas Gleixner <tglx@linutronix.de>
Thu, 18 Jun 2020 13:47:01 +0000 (15:47 +0200)
save_fsgs_for_kvm() is invoked via

  vcpu_enter_guest()
    kvm_x86_ops.prepare_guest_switch(vcpu)
      vmx_prepare_switch_to_guest()
        save_fsgs_for_kvm()

with preemption disabled, but interrupts enabled.

The upcoming FSGSBASE based GS safe needs interrupts to be disabled. This
could be done in the helper function, but that function is also called from
switch_to() which has interrupts disabled already.

Disable interrupts inside save_fsgs_for_kvm() and rename the function to
current_save_fsgs() so it can be invoked from other places.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lkml.kernel.org/r/20200528201402.1708239-7-sashal@kernel.org
arch/x86/include/asm/processor.h
arch/x86/kernel/process_64.c
arch/x86/kvm/vmx/vmx.c

index f66202d6121af9c31d53bb846fd6cc7619596049..7c2ecdf7e064b5506b36ce1ff74a90d14c3ee07e 100644 (file)
@@ -457,10 +457,8 @@ static inline unsigned long cpu_kernelmode_gs_base(int cpu)
 DECLARE_PER_CPU(unsigned int, irq_count);
 extern asmlinkage void ignore_sysret(void);
 
-#if IS_ENABLED(CONFIG_KVM)
 /* Save actual FS/GS selectors and bases to current->thread */
-void save_fsgs_for_kvm(void);
-#endif
+void current_save_fsgs(void);
 #else  /* X86_64 */
 #ifdef CONFIG_STACKPROTECTOR
 /*
index c41e0aae842621ffa0bd413fdb0c2d87514fe67e..ef2f75588f413ebf24bdd4ac76dfa41ba1441910 100644 (file)
@@ -240,18 +240,21 @@ static __always_inline void save_fsgs(struct task_struct *task)
        save_base_legacy(task, task->thread.gsindex, GS);
 }
 
-#if IS_ENABLED(CONFIG_KVM)
 /*
  * While a process is running,current->thread.fsbase and current->thread.gsbase
- * may not match the corresponding CPU registers (see save_base_legacy()). KVM
- * wants an efficient way to save and restore FSBASE and GSBASE.
- * When FSGSBASE extensions are enabled, this will have to use RD{FS,GS}BASE.
+ * may not match the corresponding CPU registers (see save_base_legacy()).
  */
-void save_fsgs_for_kvm(void)
+void current_save_fsgs(void)
 {
+       unsigned long flags;
+
+       /* Interrupts need to be off for FSGSBASE */
+       local_irq_save(flags);
        save_fsgs(current);
+       local_irq_restore(flags);
 }
-EXPORT_SYMBOL_GPL(save_fsgs_for_kvm);
+#if IS_ENABLED(CONFIG_KVM)
+EXPORT_SYMBOL_GPL(current_save_fsgs);
 #endif
 
 static __always_inline void loadseg(enum which_selector which,
index 36c771728c8cb0ec4873d795180b37ad9be88f00..ccd5b7bb617c84601ad8e2dc879aa1c932813971 100644 (file)
@@ -1172,7 +1172,7 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
 
        gs_base = cpu_kernelmode_gs_base(cpu);
        if (likely(is_64bit_mm(current->mm))) {
-               save_fsgs_for_kvm();
+               current_save_fsgs();
                fs_sel = current->thread.fsindex;
                gs_sel = current->thread.gsindex;
                fs_base = current->thread.fsbase;