Received: by 2002:ac0:a874:0:0:0:0:0 with SMTP id c49csp744266ima; Fri, 15 Mar 2019 13:09:24 -0700 (PDT) X-Google-Smtp-Source: APXvYqzBwUqj4vhXsxcPr2K5dcuHI5Uw5U4siAyFtPdJ07rjrD9cZ4k2KUO1Sf3kkbcR/t2cFVsd X-Received: by 2002:a63:4542:: with SMTP id u2mr5096957pgk.291.1552680564122; Fri, 15 Mar 2019 13:09:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1552680564; cv=none; d=google.com; s=arc-20160816; b=fP2LDDtOPzHNmCzEww/wwhz3cit3ggcp+tZYDCsLDplMJu87GgW/Ye5CpnRCF06jw/ iCOUQFNs12xZJ7fMtfrOY1+lYIUXp7EYgRF2aAX6aoQitH6CGM8ttbzqGMlEheaCaBRM G9qid0Sdezf6hJlNVVuS4pT4EH3iQD1As0D99wnb3Wc6Z2v9YdfuRvT/VoD6mAlnuJPi xlQBOCr8MBXcbfqhSWT5zTsXa5CTfxW1mGwVtpKpberlW9NToBC0NXbsJeX5zv8Clo6W 73BEL36bRjJEpuzf3EAkMmCCSXwqk4UatXzc+SgmR936XRpu4YodjmIi4f2SX17Rx4Zl EnRQ== 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; bh=FSHx6HxX3pGmtfte58Cv4/Ke4xfJrmz2ZWBPIi8RAxY=; b=HlWFdiLrbcEW+dYwHmVaScMWDcd0QaHbyl6VsCpg365jrH+hS9I3ip4XwygsLaGE5q MsKcVL5aw4IsfNNUv0C2JIgWqMiuOWw8IWsf9LcHFFxMnEz9Tq4Sw1tcr5guOCv/pPtr 1NbF8Qfqjq1+YB3HF8Z8X91tZwtR/jEUuG2cchkFvnAVCh7GjRZlrOeSq78FB+FyeyUS 0iMepEhv9VPbyhywmY8sXMNuf1vMifeFJRxY7k2y+pnZnkPLHGr+tcubIY3RIxRDkf13 3DCFSVAnGVLADUTMX6OFbYWtFOCpZyLLiTYYFy+Oawagg+5wOzQGe0VC44yJgwt7EcZX kp9A== 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 f2si2588878pgv.10.2019.03.15.13.09.08; Fri, 15 Mar 2019 13:09:24 -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 S1727081AbfCOUHz (ORCPT + 99 others); Fri, 15 Mar 2019 16:07:55 -0400 Received: from mga01.intel.com ([192.55.52.88]:22898 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726477AbfCOUHC (ORCPT ); Fri, 15 Mar 2019 16:07:02 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Mar 2019 13:07:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,483,1544515200"; d="scan'208";a="307617697" Received: from chang-linux-3.sc.intel.com ([143.183.85.65]) by orsmga005.jf.intel.com with ESMTP; 15 Mar 2019 13:07:01 -0700 From: "Chang S. Bae" To: Thomas Gleixner , Ingo Molnar , Andy Lutomirski , "H . Peter Anvin" , Andi Kleen Cc: Ravi Shankar , "Chang S . Bae" , LKML , Andrew Cooper Subject: [RESEND PATCH v6 04/12] x86/fsgsbase/64: Enable FSGSBASE instructions in the helper functions Date: Fri, 15 Mar 2019 13:06:37 -0700 Message-Id: <1552680405-5265-5-git-send-email-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1552680405-5265-1-git-send-email-chang.seok.bae@intel.com> References: <1552680405-5265-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 helper functions will switch on faster accesses to FSBASE and GSBASE when the FSGSBASE feature is enabled. Accessing user GSBASE needs a couple of SWAPGS operations. It is avoidable if the user GSBASE is saved at kernel entry, being updated as changes, and restored back at kernel exit. However, it seems to spend more cycles for savings and restorations. Little or no benefit was measured from experiments. Also, introduce __{rd,wr}gsbase_inactive() as helpers to access user GSBASE with SWAPGS. Note, for Xen PV, paravirt hooks can be added, since it may allow a very efficient but different implementation. Signed-off-by: Chang S. Bae Cc: Any Lutomirski Cc: H. Peter Anvin Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Andrew Cooper --- arch/x86/include/asm/fsgsbase.h | 27 +++++++--------- arch/x86/kernel/process_64.c | 56 +++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 15 deletions(-) diff --git a/arch/x86/include/asm/fsgsbase.h b/arch/x86/include/asm/fsgsbase.h index fdd1177499b4..aefd53767a5d 100644 --- a/arch/x86/include/asm/fsgsbase.h +++ b/arch/x86/include/asm/fsgsbase.h @@ -49,35 +49,32 @@ static __always_inline void wrgsbase(unsigned long gsbase) asm volatile("wrgsbase %0" :: "r" (gsbase) : "memory"); } +#include + /* 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); + if (static_cpu_has(X86_FEATURE_FSGSBASE)) + fsbase = rdfsbase(); + else + 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); + if (static_cpu_has(X86_FEATURE_FSGSBASE)) + wrfsbase(fsbase); + else + wrmsrl(MSR_FS_BASE, fsbase); } -static inline void x86_gsbase_write_cpu_inactive(unsigned long gsbase) -{ - wrmsrl(MSR_KERNEL_GS_BASE, gsbase); -} +extern unsigned long x86_gsbase_read_cpu_inactive(void); +extern void x86_gsbase_write_cpu_inactive(unsigned long gsbase); #endif /* CONFIG_X86_64 */ diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 6a62f4af9fcf..87b5ffce2a47 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -160,6 +160,42 @@ enum which_selector { GS }; +/* + * Interrupts are disabled here. Out of line to be protected + * from kprobes. It is not used on Xen paravirt. When paravirt + * support is needed, it needs to be renamed with native_ prefix. + */ +static noinline unsigned long __rdgsbase_inactive(void) +{ + unsigned long gsbase, flags; + + local_irq_save(flags); + native_swapgs(); + gsbase = rdgsbase(); + native_swapgs(); + local_irq_restore(flags); + + return gsbase; +} +NOKPROBE_SYMBOL(__rdgsbase_inactive); + +/* + * Interrupts are disabled here. Out of line to be protected + * from kprobes. It is not used on Xen paravirt. When paravirt + * support is needed, it needs to be renamed with native_ prefix. + */ +static noinline void __wrgsbase_inactive(unsigned long gsbase) +{ + unsigned long flags; + + local_irq_save(flags); + native_swapgs(); + wrgsbase(gsbase); + native_swapgs(); + local_irq_restore(flags); +} +NOKPROBE_SYMBOL(__wrgsbase_inactive); + /* * Saves the FS or GS base for an outgoing thread if FSGSBASE extensions are * not available. The goal is to be reasonably fast on non-FSGSBASE systems. @@ -338,6 +374,26 @@ static unsigned long x86_fsgsbase_read_task(struct task_struct *task, return base; } +unsigned long x86_gsbase_read_cpu_inactive(void) +{ + unsigned long gsbase; + + if (static_cpu_has(X86_FEATURE_FSGSBASE)) + gsbase = __rdgsbase_inactive(); + else + rdmsrl(MSR_KERNEL_GS_BASE, gsbase); + + return gsbase; +} + +void x86_gsbase_write_cpu_inactive(unsigned long gsbase) +{ + if (static_cpu_has(X86_FEATURE_FSGSBASE)) + __wrgsbase_inactive(gsbase); + else + wrmsrl(MSR_KERNEL_GS_BASE, gsbase); +} + unsigned long x86_fsbase_read_task(struct task_struct *task) { unsigned long fsbase; -- 2.19.1