Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp30471imm; Mon, 4 Jun 2018 12:26:31 -0700 (PDT) X-Google-Smtp-Source: ADUXVKLKtGBCKb/rHeQkEUKuJT8a5q8doLNrS7BOK8hMsvem68gJdXsblZ0uyhzhfMI1kIx1fPu3 X-Received: by 2002:a65:49cb:: with SMTP id t11-v6mr17976105pgs.218.1528140391360; Mon, 04 Jun 2018 12:26:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528140391; cv=none; d=google.com; s=arc-20160816; b=pGkD8OM7Tl8gITnuE6VVkS+Tv2EaqwTaSMkorVTw2nAvHKgWTpR9m7LM7SPLeKVWXv 4DJFqOslglrFv4q9IjTKi0LEjEiPFN08o/U/IfLY+LfVhHxr29gjwOVs733WcbHpTkNX 12sqLr6FI/KaRHdors2Vdik7QQ/5rNcS5jXbZ1IJpGbz3aqvdqIPIzw6JxGU02TVNRkb HaRRCXMmMxgV6AmqjBwCSrCacUyZ/nToOMp8xdnTgcQxDXE91OnpW3DZy97ylNcBgSL+ Cf+hgKyfMjWT1g1XKgzoaweHwUkLgkXSPOcRL6hVDN6mzqTBVN1sWU/MXljpPNIVZhSa NJJQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=CTCfNtmVbH16e+SvM+Bcmm7oIAaYN0zuP8pgtyVPA1E=; b=WxTpLw/nu6P0QwiWFUgEGq9eA1SQTAe9GiqpaLbRtDVe1+MHEsHP9QdQ/hhbhULPDA tkeoJFSOhoQwOonhUjWPL9TYdgFdrAxKbbWrU95ozZ5scHwvdW7qHi6TfCYUUgnxYMDr 5aJ6U+c899btZ6sj9DCB4Lode0zn7VwyVzx9yUfOr31hM0wZmCVcMptEQHrPAIqOn9Jl AjG3+H8nxQidYopaMRyprgu+zH7krCB9srpo6F76nMbJm2bxDDggObSPjGGcMapYE9FT t4YKyFA5OzyQFxX/H+7HCqnvrO1rmsnbFtK7+uDkGGxd2AUMksPsn2RxZUAqLgIm6Xol x4sw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d14-v6si21560671pln.206.2018.06.04.12.26.16; Mon, 04 Jun 2018 12:26:31 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751303AbeFDTYu (ORCPT + 99 others); Mon, 4 Jun 2018 15:24:50 -0400 Received: from mga05.intel.com ([192.55.52.43]:40504 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751233AbeFDTYr (ORCPT ); Mon, 4 Jun 2018 15:24:47 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 04 Jun 2018 12:24:46 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,476,1520924400"; d="scan'208";a="64240696" Received: from chang-linux-2.sc.intel.com ([10.3.52.139]) by orsmga002.jf.intel.com with ESMTP; 04 Jun 2018 12:24:46 -0700 From: "Chang S. Bae" To: Andy Lutomirski , "H . Peter Anvin" , Thomas Gleixner , Ingo Molnar Cc: Andi Kleen , Dave Hansen , Markus T Metzger , "Ravi V . Shankar" , "Chang S . Bae" , LKML Subject: [PATCH 6/6] x86/vdso: Move out the CPU number store Date: Mon, 4 Jun 2018 12:24:29 -0700 Message-Id: <1528140269-26205-7-git-send-email-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1528140269-26205-1-git-send-email-chang.seok.bae@intel.com> References: <1528140269-26205-1-git-send-email-chang.seok.bae@intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The CPU (and node) number will be written, as early enough, to the segment limit of per CPU data and TSC_AUX MSR entry. The information has been retrieved by vgetcpu in user space and will be also loaded from the paranoid entry, when FSGSBASE enabled. So, it is moved out from vDSO to the CPU initialization path where IST setup is serialized. Now, redundant setting of the segment in entry/vdso/vma.c was removed; a substantial code removal. It removes a hotplug notifier, makes a facility useful to both the kernel and userspace unconditionally available much sooner, and unification with i386. (Thanks to HPA for suggesting the cleanup) Signed-off-by: Chang S. Bae Cc: H. Peter Anvin Cc: Dave Hansen Cc: Andy Lutomirski Cc: Andi Kleen Cc: Thomas Gleixner Cc: Ingo Molnar --- arch/x86/entry/vdso/vgetcpu.c | 4 ++-- arch/x86/entry/vdso/vma.c | 38 +------------------------------------- arch/x86/include/asm/segment.h | 29 +++++++++++++++++++++++++++-- arch/x86/include/asm/vgtod.h | 2 -- arch/x86/kernel/cpu/common.c | 5 +++++ arch/x86/kernel/setup_percpu.c | 17 +++++++++++++---- 6 files changed, 48 insertions(+), 47 deletions(-) diff --git a/arch/x86/entry/vdso/vgetcpu.c b/arch/x86/entry/vdso/vgetcpu.c index 8ec3d1f..3284069 100644 --- a/arch/x86/entry/vdso/vgetcpu.c +++ b/arch/x86/entry/vdso/vgetcpu.c @@ -18,9 +18,9 @@ __vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused) p = __getcpu(); if (cpu) - *cpu = p & VGETCPU_CPU_MASK; + *cpu = lsl_tscp_to_cpu(p); if (node) - *node = p >> 12; + *node = lsl_tscp_to_node(p); return 0; } diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c index 5b8b556..3f9d43f 100644 --- a/arch/x86/entry/vdso/vma.c +++ b/arch/x86/entry/vdso/vma.c @@ -332,40 +332,6 @@ static __init int vdso_setup(char *s) return 0; } __setup("vdso=", vdso_setup); -#endif - -#ifdef CONFIG_X86_64 -static void vgetcpu_cpu_init(void *arg) -{ - int cpu = smp_processor_id(); - struct desc_struct d = { }; - unsigned long node = 0; -#ifdef CONFIG_NUMA - node = cpu_to_node(cpu); -#endif - if (static_cpu_has(X86_FEATURE_RDTSCP)) - write_rdtscp_aux((node << 12) | cpu); - - /* - * Store cpu number in limit so that it can be loaded - * quickly in user space in vgetcpu. (12 bits for the CPU - * and 8 bits for the node) - */ - d.limit0 = cpu | ((node & 0xf) << 12); - d.limit1 = node >> 4; - d.type = 5; /* RO data, expand down, accessed */ - d.dpl = 3; /* Visible to user code */ - d.s = 1; /* Not a system segment */ - d.p = 1; /* Present */ - d.d = 1; /* 32-bit */ - - write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_PER_CPU, &d, DESCTYPE_S); -} - -static int vgetcpu_online(unsigned int cpu) -{ - return smp_call_function_single(cpu, vgetcpu_cpu_init, NULL, 1); -} static int __init init_vdso(void) { @@ -375,9 +341,7 @@ static int __init init_vdso(void) init_vdso_image(&vdso_image_x32); #endif - /* notifier priority > KVM */ - return cpuhp_setup_state(CPUHP_AP_X86_VDSO_VMA_ONLINE, - "x86/vdso/vma:online", vgetcpu_online, NULL); + return 0; } subsys_initcall(init_vdso); #endif /* CONFIG_X86_64 */ diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h index 8f09012b..596112c 100644 --- a/arch/x86/include/asm/segment.h +++ b/arch/x86/include/asm/segment.h @@ -187,7 +187,7 @@ #define GDT_ENTRY_TLS_MAX 14 /* Abused to load per CPU data from limit */ -#define GDT_ENTRY_PER_CPU 15 +#define GDT_ENTRY_PERCPU 15 /* * Number of entries in the GDT table: @@ -207,7 +207,7 @@ #define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8 + 3) #define __USER32_DS __USER_DS #define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8 + 3) -#define __PER_CPU_SEG (GDT_ENTRY_PER_CPU*8 + 3) +#define __PER_CPU_SEG (GDT_ENTRY_PERCPU*8 + 3) #endif @@ -225,6 +225,31 @@ #define GDT_ENTRY_TLS_ENTRIES 3 #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES* 8) +/* Bit size and mask of CPU number stored in the per CPU data (and TSC_AUX) */ +#define LSL_TSCP_CPU_SIZE 12 +#define LSL_TSCP_CPU_MASK 0xfff + +#ifndef __ASSEMBLY__ + +/* Helper functions to store/load CPU and node numbers */ + +static inline unsigned long make_lsl_tscp(int cpu, unsigned long node) +{ + return ((node << LSL_TSCP_CPU_SIZE) | cpu); +} + +static inline unsigned int lsl_tscp_to_cpu(unsigned long x) +{ + return (x & LSL_TSCP_CPU_MASK); +} + +static inline unsigned int lsl_tscp_to_node(unsigned long x) +{ + return (x >> LSL_TSCP_CPU_SIZE); +} + +#endif + #ifdef __KERNEL__ /* diff --git a/arch/x86/include/asm/vgtod.h b/arch/x86/include/asm/vgtod.h index fb856c9..1cc9d30 100644 --- a/arch/x86/include/asm/vgtod.h +++ b/arch/x86/include/asm/vgtod.h @@ -79,8 +79,6 @@ static inline void gtod_write_end(struct vsyscall_gtod_data *s) #ifdef CONFIG_X86_64 -#define VGETCPU_CPU_MASK 0xfff - static inline unsigned int __getcpu(void) { unsigned int p; diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 38276f5..c7b54f0 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1665,6 +1665,11 @@ void cpu_init(void) wrmsrl(MSR_FS_BASE, 0); wrmsrl(MSR_KERNEL_GS_BASE, 0); +#ifdef CONFIG_NUMA + write_rdtscp_aux(make_lsl_tscp(cpu, early_cpu_to_node(cpu))); +#else + write_rdtscp_aux(make_lsl_tscp(cpu, 0)); +#endif barrier(); x86_configure_nx(); diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index ea554f8..e716e94 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -155,12 +155,21 @@ static void __init pcpup_populate_pte(unsigned long addr) static inline void setup_percpu_segment(int cpu) { -#ifdef CONFIG_X86_32 - struct desc_struct d = GDT_ENTRY_INIT(0x8092, per_cpu_offset(cpu), - 0xFFFFF); +#ifdef CONFIG_NUMA + unsigned long node = early_cpu_to_node(cpu); +#else + unsigned long node = 0; +#endif + struct desc_struct d = GDT_ENTRY_INIT(0x0, per_cpu_offset(cpu), + make_lsl_tscp(cpu, node)); + + d.type = 5; /* R0 data, expand down, accessed */ + d.dpl = 3; /* Visible to user code */ + d.s = 1; /* Not a system segment */ + d.p = 1; /* Present */ + d.d = 1; /* 32-bit */ write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_PERCPU, &d, DESCTYPE_S); -#endif } void __init setup_per_cpu_areas(void) -- 2.7.4