Messages in this thread Patch in this message | | | From | Lai Jiangshan <> | Subject | [PATCH V6 33/49] x86/entry: Add the C version get_percpu_base() | Date | Fri, 26 Nov 2021 18:11:53 +0800 |
| |
From: Lai Jiangshan <laijs@linux.alibaba.com>
It implements the C version of asm macro GET_PERCPU_BASE().
Not functional difference intended.
Signed-off-by: Lai Jiangshan <laijs@linux.alibaba.com> --- arch/x86/entry/entry64.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
diff --git a/arch/x86/entry/entry64.c b/arch/x86/entry/entry64.c index 5f47221d8935..3ec145c38e9e 100644 --- a/arch/x86/entry/entry64.c +++ b/arch/x86/entry/entry64.c @@ -183,3 +183,39 @@ struct pt_regs *error_entry(struct pt_regs *eregs) /* Enter from kernel, don't move pt_regs */ return eregs; } + +#ifdef CONFIG_SMP +/* + * CPU/node NR is loaded from the limit (size) field of a special segment + * descriptor entry in GDT. + * + * Do not use RDPID, because KVM loads guest's TSC_AUX on vm-entry and + * may not restore the host's value until the CPU returns to userspace. + * Thus the kernel would consume a guest's TSC_AUX if an NMI arrives + * while running KVM's run loop. + */ +static __always_inline unsigned int gdt_get_cpu(void) +{ + unsigned int p; + + asm ("lsl %[seg],%[p]" : [p] "=a" (p) : [seg] "r" (__CPUNODE_SEG)); + + return p & VDSO_CPUNODE_MASK; +} + +/* + * Fetch the per-CPU GSBASE value for this processor. + * + * We normally use %gs for accessing per-CPU data, but we are setting up + * %gs here and obviously can not use %gs itself to access per-CPU data. + */ +static __always_inline unsigned long get_percpu_base(void) +{ + return __per_cpu_offset[gdt_get_cpu()]; +} +#else +static __always_inline unsigned long get_percpu_base(void) +{ + return pcpu_unit_offsets; +} +#endif -- 2.19.1.6.gb485710b
| |