Received: by 2002:a25:868d:0:0:0:0:0 with SMTP id z13csp549448ybk; Sat, 9 May 2020 10:39:10 -0700 (PDT) X-Google-Smtp-Source: APiQypJ2QG8by5TRj930ORbjhv9QKZlZ0S3ld7Qxi7E+RYIXMuC8jOlvYhZMArlYT2vEsd46zhQo X-Received: by 2002:aa7:d918:: with SMTP id a24mr3435871edr.32.1589045950101; Sat, 09 May 2020 10:39:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1589045950; cv=none; d=google.com; s=arc-20160816; b=iGKCcuBW0eKnPrzOkkp86pXj5VjFnmgmhGxzMhd9H2bwTqazzyMqBmfKf+IU9rXYMm rrwSQAKd1BbKuUAthnoT+EGLl62VbpiLlN/kzljmeV/jYDlQkXiBewxIYUtD96Iwv8zW HQf5KVqbKYU2L9y1FIUGqz8V4KTQXKmfBgGkpvzcad/XJYYZTP3vp87S3RVQpn/p8tsf Blae4yMP0OKSGdwnVPQQvCJf6ZUGJKy5TeWyKEWM1Q/Kty2/lKFp6TailOcT2HRMX9Qv vuYEjQP3vjErE3RsmLm/J9uQF46tL/wMmKh9VEIXJ6Kqha4TcnKCg8Lw8RRvRdp1e5kG WJrg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=GYbESS0UYsclQphBoYgKbHXUzPdIfrMPa9ZPEURSMNs=; b=GPX/dtNOpBJ4SKy9yy84ip15u5JMIWs4lpsA834N/ysj00pSq+f6hQP7uwNgMuxdtY YDLLEQEBKIKHRLjZwdsz+PEUM263Fpr3ZV7zuMycniUmUcB5uszFwHuUX8J6X+x4Am17 pAyOmFNSAtIKMGkjPFTKsL8tZVSNx2tHJ/CNcNnalPqrigzx0bVGcQ65sdgNYJzXjeuU 7fu5kAw+x62/s2MYRtrt0qcY0x/KDpZ91Na7J+BoopX65la9NzaJQwPcGd5UtPh5gw/X ErCpX9p6+YnzBWApvPTGmzsk919IyLd8pyQqrKyyzjC3f1hK0FME1GV7I37StC7RpGPi 9rVw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=Ij9bufEn; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id p9si3243837ejf.493.2020.05.09.10.38.47; Sat, 09 May 2020 10:39:10 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=Ij9bufEn; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728600AbgEIRhS (ORCPT + 99 others); Sat, 9 May 2020 13:37:18 -0400 Received: from mail.kernel.org ([198.145.29.99]:54540 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728556AbgEIRhO (ORCPT ); Sat, 9 May 2020 13:37:14 -0400 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id CC28524956; Sat, 9 May 2020 17:37:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1589045834; bh=XB2DMbcdtt9RoxOfGiwesKsJ7IyXYEi8LfJOoe/YsnY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ij9bufEn7aeXjnEjYwvjndLQOf2Z2gYbt4queQSVYREcDPF/5rfsDMIN1uyEg1IxA gO4xQSE4/OLUrYDpqhv3C0MRRM0V8Fe4NtWZ8jlQQKdDzjxdzabygf5SGt+pHQ84eZ +Dq9nzrWnGye4VGYocL+WecUljpaYaqtNK1/pLwo= From: Sasha Levin To: linux-kernel@vger.kernel.org, tglx@linutronix.de, bp@alien8.de, luto@kernel.org Cc: hpa@zytor.com, dave.hansen@intel.com, tony.luck@intel.com, ak@linux.intel.com, ravi.v.shankar@intel.com, chang.seok.bae@intel.com, Sasha Levin , Andrew Cooper Subject: [PATCH v11 10/18] x86/fsgsbase/64: Enable FSGSBASE instructions in helper functions Date: Sat, 9 May 2020 13:36:47 -0400 Message-Id: <20200509173655.13977-11-sashal@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200509173655.13977-1-sashal@kernel.org> References: <20200509173655.13977-1-sashal@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: "Chang S. Bae" Add CPU feature conditional FS/GS base access to the relevant helper functions. That allows accelerating certain FS/GS base operations in subsequent changes. Note, that while possible, the user space entry/exit GS base operations are not going to use the new FSGSBASE instructions. The reason is that it would require additional storage for the user space value which adds more complexity to the low level code and experiments have shown marginal benefit. This may be revisited later but for now the SWAPGS based handling in the entry code is preserved except for the paranoid entry/exit code. Suggested-by: Tony Luck Signed-off-by: Chang S. Bae Signed-off-by: Sasha Levin Reviewed-by: Tony Luck Cc: Thomas Gleixner Cc: Borislav Petkov Cc: Andy Lutomirski Cc: H. Peter Anvin Cc: Dave Hansen Cc: Tony Luck Cc: Andi Kleen Cc: Andrew Cooper --- arch/x86/include/asm/fsgsbase.h | 27 +++++++-------- arch/x86/kernel/process_64.c | 58 +++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 15 deletions(-) diff --git a/arch/x86/include/asm/fsgsbase.h b/arch/x86/include/asm/fsgsbase.h index fdd1177499b40..aefd53767a5d4 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 5ef9d8f25b0e8..aaa65f284b9b9 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -328,6 +328,64 @@ 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)) { + bool need_restore = false; + unsigned long flags; + + /* + * We read the inactive GS base value by swapping + * to make it the active one. But we cannot allow + * an interrupt while we switch to and from. + */ + if (!irqs_disabled()) { + local_irq_save(flags); + need_restore = true; + } + + native_swapgs(); + gsbase = rdgsbase(); + native_swapgs(); + + if (need_restore) + local_irq_restore(flags); + } 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)) { + bool need_restore = false; + unsigned long flags; + + /* + * We write the inactive GS base value by swapping + * to make it the active one. But we cannot allow + * an interrupt while we switch to and from. + */ + if (!irqs_disabled()) { + local_irq_save(flags); + need_restore = true; + } + + native_swapgs(); + wrgsbase(gsbase); + native_swapgs(); + + if (need_restore) + local_irq_restore(flags); + } else { + wrmsrl(MSR_KERNEL_GS_BASE, gsbase); + } +} + unsigned long x86_fsbase_read_task(struct task_struct *task) { unsigned long fsbase; -- 2.20.1