From patchwork Wed Jul 19 22:47:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: tip-bot2 for Thomas Gleixner X-Patchwork-Id: 122901 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c923:0:b0:3e4:2afc:c1 with SMTP id j3csp2770197vqt; Wed, 19 Jul 2023 16:24:30 -0700 (PDT) X-Google-Smtp-Source: APBJJlF65ZTvNI6p5FqKsTM7bTpoj0CqExN1UNZVma61cD+BNl9b5+U37aFar9GdgOa7qje20bC5 X-Received: by 2002:a17:902:e5d2:b0:1b9:ca58:34df with SMTP id u18-20020a170902e5d200b001b9ca5834dfmr4992636plf.63.1689809070115; Wed, 19 Jul 2023 16:24:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689809070; cv=none; d=google.com; s=arc-20160816; b=bx4yvcfexRblREKLmpoNaCYCnNpStT1m668sZ3fhXIJ+NZ+LY3rUOR25nMJ+cjeXg6 9laRswOut8h2293zgatWe2Wv2ltmEp7JFpGmb+T4WFdu9HGBAfo2E84KDm7h73rJPwvb wpFXL3NLld50yW+94SMkN2fBmS5HJfPVn0h4HDGqdRaIlXHbQ40XWbbF5fIAar2v/QqB jDr+VXRiZUcZXLGpPW9OJyRHjkbexKMeLZIRg0Dn1GNUI97EieuovxgcgYHglEHBdtNT 3s2SJyH4LHYoFZQLUn0ZKgGQoeAyO5mnQSLPIU+2pQ8DSX25KoNoMuWx8jetn6BR1pxJ AVAA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:robot-unsubscribe :robot-id:message-id:mime-version:cc:subject:to:reply-to:sender:from :dkim-signature:dkim-signature:date; bh=bjEn3JqcSQo1gJAI2nh37QcddKb+X0YfjVkcDqUbRNE=; fh=iQKiEOXb5C++oE5tneTGKBC6WCZ3nmt1n8YpsMtaR6c=; b=LcT18lyJrpcI7z9Z/hY3gywEukFivmE3IMe0NgKYLfmNQcqrhAE6sLn9nrinFZSEYC SD0jR1i+Augdg5EOrBVzLfM42+hndOGWKKRO8FNnIeWtdqxtUvbMi0hNuB9Nxjt9b34U 42jR9GRrcqADKYfMQrQWx4yYJMUXMUmoKn8JXeWL++drtvH/U+WsPc7fowYflF85hrl0 r/wWm8CdBNl3jVRPuWXn8l/4uXmV5S7YNkpyHAiaeoL3EHoIwWjmnoJiQDrQNAk8julR wxtuIdMVZkmqtYzg2QY/eFusle1iScL9epWadICF8TPRyKKQlRvCvaop97zRMgJvv3oW r+tQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=WVJLfvck; dkim=neutral (no key) header.i=@linutronix.de header.b=Miafcrqq; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id 21-20020a170902c21500b001b811b9d416si4319490pll.578.2023.07.19.16.24.17; Wed, 19 Jul 2023 16:24:30 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=WVJLfvck; dkim=neutral (no key) header.i=@linutronix.de header.b=Miafcrqq; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231295AbjGSWsj (ORCPT + 99 others); Wed, 19 Jul 2023 18:48:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42316 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230409AbjGSWro (ORCPT ); Wed, 19 Jul 2023 18:47:44 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4DC56210B; Wed, 19 Jul 2023 15:47:35 -0700 (PDT) Date: Wed, 19 Jul 2023 22:47:33 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1689806853; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=bjEn3JqcSQo1gJAI2nh37QcddKb+X0YfjVkcDqUbRNE=; b=WVJLfvckgsYf1Hc0dfZS90Leuokjt+X2ZgJ6u7ZK9/IvltI96fj2KJtbstixVjGl4ukqXo yPiMPDyrieXIQEXVhHpV0cYS1tGEmOFSyFweQ1VSb749J6bAggXEEjWSm27tXHqXsC36Kt XanxdqcYBvzVfWT0ucq/Ouezcq5Sz1hqEEXBMiInrKVpH7yOejqSgJb7DnUevw85Q+t3/h n1eFDN6ZGuhFP9fUbK6huSDDTvA1A5Uh7gy5LZN1pUMJX/spdP/ve30F1/cn8+mLv+4CDr QU8eJFMM9J16YeY53eElJxIBmFf0L81uNe9z2TuKSpFmvROxQeofOGXH8SW6UA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1689806853; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=bjEn3JqcSQo1gJAI2nh37QcddKb+X0YfjVkcDqUbRNE=; b=MiafcrqqFlX8u0opRaYwdc/OFNts5yQNAsP82i8AlkbmzyEV7gj0FfuWRb6SzcbbGbexGy ld/H6Ka21jtyUHAw== From: "tip-bot2 for Rick Edgecombe" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: x86/shstk] x86/fpu: Add helper for modifying xstate Cc: Thomas Gleixner , Rick Edgecombe , Dave Hansen , "Borislav Petkov (AMD)" , Kees Cook , "Mike Rapoport (IBM)" , Pengfei Xu , John Allen , x86@kernel.org, linux-kernel@vger.kernel.org MIME-Version: 1.0 Message-ID: <168980685323.28540.16408510205774794327.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1771893235968193516 X-GMAIL-MSGID: 1771893235968193516 The following commit has been merged into the x86/shstk branch of tip: Commit-ID: b89e93a76d9b525b72e5684c8187ab3e83052337 Gitweb: https://git.kernel.org/tip/b89e93a76d9b525b72e5684c8187ab3e83052337 Author: Rick Edgecombe AuthorDate: Mon, 12 Jun 2023 17:10:51 -07:00 Committer: Rick Edgecombe CommitterDate: Tue, 11 Jul 2023 14:12:49 -07:00 x86/fpu: Add helper for modifying xstate Just like user xfeatures, supervisor xfeatures can be active in the registers or present in the task FPU buffer. If the registers are active, the registers can be modified directly. If the registers are not active, the modification must be performed on the task FPU buffer. When the state is not active, the kernel could perform modifications directly to the buffer. But in order for it to do that, it needs to know where in the buffer the specific state it wants to modify is located. Doing this is not robust against optimizations that compact the FPU buffer, as each access would require computing where in the buffer it is. The easiest way to modify supervisor xfeature data is to force restore the registers and write directly to the MSRs. Often times this is just fine anyway as the registers need to be restored before returning to userspace. Do this for now, leaving buffer writing optimizations for the future. Add a new function fpregs_lock_and_load() that can simultaneously call fpregs_lock() and do this restore. Also perform some extra sanity checks in this function since this will be used in non-fpu focused code. Suggested-by: Thomas Gleixner Signed-off-by: Rick Edgecombe Signed-off-by: Dave Hansen Reviewed-by: Borislav Petkov (AMD) Reviewed-by: Kees Cook Acked-by: Mike Rapoport (IBM) Tested-by: Pengfei Xu Tested-by: John Allen Tested-by: Kees Cook Link: https://lore.kernel.org/all/20230613001108.3040476-26-rick.p.edgecombe%40intel.com --- arch/x86/include/asm/fpu/api.h | 9 +++++++++ arch/x86/kernel/fpu/core.c | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/arch/x86/include/asm/fpu/api.h b/arch/x86/include/asm/fpu/api.h index b475d9a..31089b8 100644 --- a/arch/x86/include/asm/fpu/api.h +++ b/arch/x86/include/asm/fpu/api.h @@ -82,6 +82,15 @@ static inline void fpregs_unlock(void) preempt_enable(); } +/* + * FPU state gets lazily restored before returning to userspace. So when in the + * kernel, the valid FPU state may be kept in the buffer. This function will force + * restore all the fpu state to the registers early if needed, and lock them from + * being automatically saved/restored. Then FPU state can be modified safely in the + * registers, before unlocking with fpregs_unlock(). + */ +void fpregs_lock_and_load(void); + #ifdef CONFIG_X86_DEBUG_FPU extern void fpregs_assert_state_consistent(void); #else diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c index 1015af1..375852c 100644 --- a/arch/x86/kernel/fpu/core.c +++ b/arch/x86/kernel/fpu/core.c @@ -753,6 +753,24 @@ void switch_fpu_return(void) } EXPORT_SYMBOL_GPL(switch_fpu_return); +void fpregs_lock_and_load(void) +{ + /* + * fpregs_lock() only disables preemption (mostly). So modifying state + * in an interrupt could screw up some in progress fpregs operation. + * Warn about it. + */ + WARN_ON_ONCE(!irq_fpu_usable()); + WARN_ON_ONCE(current->flags & PF_KTHREAD); + + fpregs_lock(); + + fpregs_assert_state_consistent(); + + if (test_thread_flag(TIF_NEED_FPU_LOAD)) + fpregs_restore_userregs(); +} + #ifdef CONFIG_X86_DEBUG_FPU /* * If current FPU state according to its tracking (loaded FPU context on this