From patchwork Mon Mar 20 16:39:30 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: 72320 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:604a:0:0:0:0:0 with SMTP id j10csp1340261wrt; Mon, 20 Mar 2023 10:31:10 -0700 (PDT) X-Google-Smtp-Source: AK7set/EQbjOs+QS3+S2t9E/gU69yRqQPHEdm7QOLdNbSZ3M/HTeDXs3ob750vF+l5tJw/SDNj6O X-Received: by 2002:a17:902:d48e:b0:1a1:cc5a:b04 with SMTP id c14-20020a170902d48e00b001a1cc5a0b04mr5979027plg.3.1679333470271; Mon, 20 Mar 2023 10:31:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679333470; cv=none; d=google.com; s=arc-20160816; b=VZXKp6C46r1hyUhHbleLei++dDvz5uyUKyW5lQtoHt3CSTqjZztW9f48JisJQxq8je l3lU81rXt2oeeV5vAY9VQqaNinoimiMY+TRCB7rv1+ocqERIRRroet7qWIc9ORft+Mgy +Hmi3ZbKx3kzm4jxY/S9MkMeueBsmkh1QjJmzbQzppGmuMjQKre6irBwYU4NgjI36MW4 NWQ6YykGem7dMUJc9ePKgc3lm4shPFZqXsEkVl5/y/OABerUaNEoFxz+DCjyW4RxqtsJ 2Qx4pTnRGIevkFj5OxYXB7aHD8GBU7qLWScTOYRs7mzY3SXRSElsHNR6yA8N0eymAC/+ v+hw== 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=wi6Yl5CUNpX5i5q0mEo24Zk7ZCq2pYwSx1YTVZMK+eE=; b=huS92r+S1aeDefvp4DP2pyAtMQm81xYrkz1yOOesG8PBI42iV6o5RGWVY0TJmJNZso +nB/Axur2GwELjzRNA9SqTihti2ZJuMr1Y4z7PuE6C3CASP04hNG8JUsE7PNQG/ojgCc KCbUn89ll3efx0xaT2mNkc1jtPP94wsEhCpO9iRDeAUbu1t7fEEueMWq6rPG2SkBERwd IIUc0tS3Xem9G9qk/eZ1fbJieVIKPRNdIpSAmwNnXT6XXwvNIw+Q4ohUr8sPDykujcus cGqFE+t5MxFhKl8ImOoOaqSSTr84yUeGHT40t6BTq2P38sU0SLBci62scDk87W+KQ8lj pmCg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=ECIbk3WC; dkim=neutral (no key) header.i=@linutronix.de header.b=XYRq4w6E; 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 o11-20020a170902d4cb00b001a1e0fd406csi119428plg.217.2023.03.20.10.30.57; Mon, 20 Mar 2023 10:31:10 -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=ECIbk3WC; dkim=neutral (no key) header.i=@linutronix.de header.b=XYRq4w6E; 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 S231329AbjCTQvY (ORCPT + 99 others); Mon, 20 Mar 2023 12:51:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50976 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232424AbjCTQuU (ORCPT ); Mon, 20 Mar 2023 12:50:20 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2BC342CFEC; Mon, 20 Mar 2023 09:42:42 -0700 (PDT) Date: Mon, 20 Mar 2023 16:39:30 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1679330370; 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=wi6Yl5CUNpX5i5q0mEo24Zk7ZCq2pYwSx1YTVZMK+eE=; b=ECIbk3WCRIxKg9n+/hVWlXeH89fhVjb6oqtQiHo75sHqbuf3xCklC8a7F9KrCN9Ov8eXT6 brOcBCCgY8PVEbu9hPCwhv08R7WbUW2rUm8FfPaAG1BaFUqm3+cKLfn3szl4VyD80BUftg +OuQuVwAzlUanne0FOQFokt0NsXPztNgqtRAsWm1eJ4z5b7gSZpPB7bvf2wCmHvVL8HNfQ P5Oym20fLWo79digfYC7xbCTUARVN7/YVA5Xd/qtyCRzqEPVRjMlgjnPfseaWAeHVikSeW 7gCWGyTEYtKzQzG6YL+eAYICPADiaLAjPnTiSNiuMbkhPxrFn2bQ57r5QTTEkA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1679330370; 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=wi6Yl5CUNpX5i5q0mEo24Zk7ZCq2pYwSx1YTVZMK+eE=; b=XYRq4w6Eu7Fvsj0DXQRrab32juS3445esiHZYbBwXzq6RdkLtvQxNVnNY4hcYroxcBakrV 1BBUqD0MT69XySDg== 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: <167933037004.5837.10727622061523111195.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_PASS 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: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1760908773386906907?= X-GMAIL-MSGID: =?utf-8?q?1760908773386906907?= The following commit has been merged into the x86/shstk branch of tip: Commit-ID: f2f3528ea37dd646cb2a9120e6cf758ef7faacc2 Gitweb: https://git.kernel.org/tip/f2f3528ea37dd646cb2a9120e6cf758ef7faacc2 Author: Rick Edgecombe AuthorDate: Sat, 18 Mar 2023 17:15:01 -07:00 Committer: Dave Hansen CommitterDate: Mon, 20 Mar 2023 09:01:08 -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/20230319001535.23210-7-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 503a577..aadc689 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 caf3348..f851558 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