mirror of
https://github.com/torvalds/linux.git
synced 2024-12-20 01:52:13 +00:00
87ab4689ca
Andy spotted a regression in the fs/gs base helpers after the patch series
was committed. The helper functions which write fs/gs base are not just
writing the base, they are also changing the index. That's wrong and needs
to be separated because writing the base has not to modify the index.
While the regression is not causing any harm right now because the only
caller depends on that behaviour, it's a guarantee for subtle breakage down
the road.
Make the index explicitly changed from the caller, instead of including
the code in the helpers.
Subsequently, the task write helpers do not handle for the current task
anymore. The range check for a base value is also factored out, to minimize
code redundancy from the caller.
Fixes: b1378a561f
("x86/fsgsbase/64: Introduce FS/GS base helper functions")
Suggested-by: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Andy Lutomirski <luto@kernel.org>
Cc: "H . Peter Anvin" <hpa@zytor.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Ravi Shankar <ravi.v.shankar@intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Link: https://lkml.kernel.org/r/20181126195524.32179-1-chang.seok.bae@intel.com
57 lines
1.3 KiB
C
57 lines
1.3 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _ASM_FSGSBASE_H
|
|
#define _ASM_FSGSBASE_H
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
#include <asm/msr-index.h>
|
|
|
|
/*
|
|
* Read/write a task's FSBASE or GSBASE. This returns the value that
|
|
* the FS/GS base would have (if the task were to be resumed). These
|
|
* work on the current task or on a non-running (typically stopped
|
|
* ptrace child) task.
|
|
*/
|
|
extern unsigned long x86_fsbase_read_task(struct task_struct *task);
|
|
extern unsigned long x86_gsbase_read_task(struct task_struct *task);
|
|
extern void x86_fsbase_write_task(struct task_struct *task, unsigned long fsbase);
|
|
extern void x86_gsbase_write_task(struct task_struct *task, unsigned long gsbase);
|
|
|
|
/* Helper functions for reading/writing FS/GS base */
|
|
|
|
static inline unsigned long x86_fsbase_read_cpu(void)
|
|
{
|
|
unsigned long fsbase;
|
|
|
|
rdmsrl(MSR_FS_BASE, fsbase);
|
|
|
|
return fsbase;
|
|
}
|
|
|
|
static inline unsigned long x86_gsbase_read_cpu_inactive(void)
|
|
{
|
|
unsigned long gsbase;
|
|
|
|
rdmsrl(MSR_KERNEL_GS_BASE, gsbase);
|
|
|
|
return gsbase;
|
|
}
|
|
|
|
static inline void x86_fsbase_write_cpu(unsigned long fsbase)
|
|
{
|
|
wrmsrl(MSR_FS_BASE, fsbase);
|
|
}
|
|
|
|
static inline void x86_gsbase_write_cpu_inactive(unsigned long gsbase)
|
|
{
|
|
wrmsrl(MSR_KERNEL_GS_BASE, gsbase);
|
|
}
|
|
|
|
#endif /* CONFIG_X86_64 */
|
|
|
|
#endif /* __ASSEMBLY__ */
|
|
|
|
#endif /* _ASM_FSGSBASE_H */
|