Re: [RESEND PATCH v6 07/12] x86/fsgsbase/64: Introduce the FIND_PERCPU_BASE macro
From: Thomas Gleixner
Date: Mon Mar 25 2019 - 05:02:47 EST
On Fri, 15 Mar 2019, Chang S. Bae wrote:
> GSBASE is used to find per-CPU data in the kernel.
It's not used to find per cpu data. per cpu data access is using GS based
addressing.
> But when it is unknown,
What is unknown?
> the per-CPU base can be found from the per_cpu_offset table with a CPU NR.
> The CPU NR is extracted from the limit field of the CPUNODE entry in GDT,
> or by the RDPID instruction.
>
> Also, add the GAS-compatible RDPID macro.
>
> The new macro will be used on a following patch.
So this is yet another changelog which describes the WHAT and not the WHY
and lacks any form of sensible context.
> diff --git a/arch/x86/include/asm/fsgsbase.h b/arch/x86/include/asm/fsgsbase.h
> index aefd53767a5d..5e3dfbe8c1bf 100644
> --- a/arch/x86/include/asm/fsgsbase.h
> +++ b/arch/x86/include/asm/fsgsbase.h
> @@ -78,6 +78,47 @@ extern void x86_gsbase_write_cpu_inactive(unsigned long gsbase);
>
> #endif /* CONFIG_X86_64 */
>
> +#else /* __ASSEMBLY__ */
> +
> +#ifdef CONFIG_X86_64
> +
> +#include <asm/inst.h>
Is there are good reason why this ASM MACRO maze needs to be in a global
visible header. AFAICT this is only used in the entry code. So why can't it
be added to the other entry code macros in calling.h or some other sensible
place?
> +#ifdef CONFIG_SMP
> +
> +/*
> + * CPU/node NR is loaded from the limit (size) field of a special segment
> + * descriptor entry in GDT.
> + */
> +.macro LOAD_CPU_AND_NODE_SEG_LIMIT reg:req
> + movq $__CPUNODE_SEG, \reg
> + lsl \reg, \reg
> +.endm
> +
> +/*
> + * Fetch the per-CPU GSBASE value for this processor and put it in @reg.
> + * 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.
> + */
> +.macro FIND_PERCPU_BASE reg:req
This is a complete misnomer. It's not searching for the per cpu base, it's
retrieving the per cpu base from a known place. So something like
GET_PERCPU_BASE would be appropriate.
> + ALTERNATIVE \
> + "LOAD_CPU_AND_NODE_SEG_LIMIT \reg", \
> + "RDPID \reg", \
> + X86_FEATURE_RDPID
> + andq $VDSO_CPUNODE_MASK, \reg
> + movq __per_cpu_offset(, \reg, 8), \reg
> +.endm
> diff --git a/arch/x86/include/asm/inst.h b/arch/x86/include/asm/inst.h
> index f5a796da07f8..d063841a17e3 100644
> --- a/arch/x86/include/asm/inst.h
> +++ b/arch/x86/include/asm/inst.h
> @@ -306,6 +306,21 @@
> .endif
> MODRM 0xc0 movq_r64_xmm_opd1 movq_r64_xmm_opd2
> .endm
> +
> +.macro RDPID opd
So the update to require binutils >= 2.21 does not cover RDPID?
Thanks,
tglx