Messages in this thread Patch in this message | | | From | Lai Jiangshan <> | Subject | [PATCH V6 34/49] x86/entry: Add the C version ist_switch_to_kernel_gsbase() | Date | Fri, 26 Nov 2021 18:11:54 +0800 |
| |
From: Lai Jiangshan <laijs@linux.alibaba.com>
It implements the second half of paranoid_entry() whose functionality is to switch to kernel gsbase.
Not functional difference intended.
Signed-off-by: Lai Jiangshan <laijs@linux.alibaba.com> --- arch/x86/entry/entry64.c | 49 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+)
diff --git a/arch/x86/entry/entry64.c b/arch/x86/entry/entry64.c index 3ec145c38e9e..60c37dbe650b 100644 --- a/arch/x86/entry/entry64.c +++ b/arch/x86/entry/entry64.c @@ -219,3 +219,52 @@ static __always_inline unsigned long get_percpu_base(void) return pcpu_unit_offsets; } #endif + +/* + * Handle GSBASE depends on the availability of FSGSBASE. + * + * Without FSGSBASE the kernel enforces that negative GSBASE + * values indicate kernel GSBASE. With FSGSBASE no assumptions + * can be made about the GSBASE value when entering from user + * space. + */ +static __always_inline unsigned long ist_switch_to_kernel_gsbase(void) +{ + int ret = 1; + unsigned long gsbase; + + if (static_cpu_has(X86_FEATURE_FSGSBASE)) { + /* + * Read the current GSBASE for return. + * Retrieve and set the current CPUs kernel GSBASE. + * + * The unconditional write to GS base below ensures that + * no subsequent loads based on a mispredicted GS base can + * happen, therefore no LFENCE is needed here. + */ + gsbase = rdgsbase(); + wrgsbase(get_percpu_base()); + return gsbase; + } + + gsbase = __rdmsr(MSR_GS_BASE); + + /* + * The kernel-enforced convention is a negative GSBASE indicates + * a kernel value. No SWAPGS needed on entry and exit. + */ + if ((long)gsbase >= 0) { + /* User GSBASE active, SWAPGS required on exit */ + ret = 0; + native_swapgs(); + } + + /* + * The above ist_switch_to_kernel_cr3() doesn't do an unconditional + * CR3 write, even in the PTI case. So do an lfence to prevent GS + * speculation, regardless of whether PTI is enabled. + */ + fence_swapgs_kernel_entry(); + + return ret; +} -- 2.19.1.6.gb485710b
| |