From patchwork Tue Jun 22 22:25:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Hansen X-Patchwork-Id: 12338689 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 05828C48BDF for ; Tue, 22 Jun 2021 22:25:58 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 979FF60FF1 for ; Tue, 22 Jun 2021 22:25:57 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 979FF60FF1 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id B1C016B0074; Tue, 22 Jun 2021 18:25:53 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id ACC4A6B0075; Tue, 22 Jun 2021 18:25:53 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 995776B0078; Tue, 22 Jun 2021 18:25:53 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0029.hostedemail.com [216.40.44.29]) by kanga.kvack.org (Postfix) with ESMTP id 648356B0074 for ; Tue, 22 Jun 2021 18:25:53 -0400 (EDT) Received: from smtpin20.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay01.hostedemail.com (Postfix) with ESMTP id AAFA618152284 for ; Tue, 22 Jun 2021 22:25:53 +0000 (UTC) X-FDA: 78282793386.20.CC2CA8B Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by imf22.hostedemail.com (Postfix) with ESMTP id 02387C0042C0 for ; Tue, 22 Jun 2021 22:25:52 +0000 (UTC) IronPort-SDR: B9uVrCvJoyE9LWURtwPtK0u34VVn02KOgZ9dr1udsrtylkDXG0N1ovorCZmvpFRaoDF9CT/7ou UGDsfpLvmMyg== X-IronPort-AV: E=McAfee;i="6200,9189,10023"; a="187534869" X-IronPort-AV: E=Sophos;i="5.83,292,1616482800"; d="scan'208";a="187534869" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jun 2021 15:25:51 -0700 IronPort-SDR: 8h1ivEevCcvcvKasuE7E3vjioywbSQBgHnl3WN/kInbDe+bfu7cl3ImusDRpE/WuXGKVzyG1zG jirLmmK4LayQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.83,292,1616482800"; d="scan'208";a="480949400" Received: from viggo.jf.intel.com (HELO localhost.localdomain) ([10.54.77.144]) by FMSMGA003.fm.intel.com with ESMTP; 22 Jun 2021 15:25:51 -0700 Subject: [RFC][PATCH 6/8] x86/fpu: update xstate size calculations for non-XSAVE-managed features To: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org,Dave Hansen ,tglx@linutronix.de,mingo@redhat.com,bp@alien8.de,x86@kernel.org,luto@kernel.org From: Dave Hansen Date: Tue, 22 Jun 2021 15:25:06 -0700 References: <20210622222455.E901B5AC@viggo.jf.intel.com> In-Reply-To: <20210622222455.E901B5AC@viggo.jf.intel.com> Message-Id: <20210622222506.487B6DF3@viggo.jf.intel.com> Authentication-Results: imf22.hostedemail.com; dkim=none; dmarc=fail reason="No valid SPF, No valid DKIM" header.from=intel.com (policy=none); spf=none (imf22.hostedemail.com: domain of dave.hansen@linux.intel.com has no SPF policy when checking 192.55.52.151) smtp.mailfrom=dave.hansen@linux.intel.com X-Rspamd-Server: rspam02 X-Stat-Signature: xagbjnbr9sncm4ipea44ykyyeuty83sa X-Rspamd-Queue-Id: 02387C0042C0 X-HE-Tag: 1624400752-618503 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: From: Dave Hansen Now that PKRU will no longer be XSAVE-managed, it needs to be removed from the XSAVE size calculations. get_xsaves_size_no_independent() currently masks independent supervisor features out of XSS, but PKRU must be masked out of XCR0 instead. Also, instead of recalculating XSS (and XCR0), just save and restore them. This will be more durable in case there are any future changes to how they are calculated. The way it is now, the values must be recalculated exactly in two separate places. The save/restore approach also makes the code more obvious. For instance, the old code does: /* Disable independent features. */ wrmsrl(MSR_IA32_XSS, xfeatures_mask_supervisor()); but the new code does: /* Disable independent features. */ wrmsrl(MSR_IA32_XSS, old_xss & ~xfeatures_mask_independent()); The second is much more obviously correct and the comment could probably even be removed; it's basically self-documenting. There is a minor, temporary hack in here. PKRU is currently not in xfeatures_mask_fpstate(), even though it is allocated in the fpstate. To avoid size mismatch warnings, hack it into XCR0 for the size calculation. Signed-off-by: Dave Hansen Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: x86@kernel.org Cc: Andy Lutomirski --- b/arch/x86/kernel/fpu/xstate.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff -puN arch/x86/kernel/fpu/xstate.c~xsave-checks arch/x86/kernel/fpu/xstate.c --- a/arch/x86/kernel/fpu/xstate.c~xsave-checks 2021-06-22 14:49:12.547051748 -0700 +++ b/arch/x86/kernel/fpu/xstate.c 2021-06-22 14:49:12.556051748 -0700 @@ -643,14 +643,26 @@ static unsigned int __init get_xsaves_si */ static unsigned int __init get_xsaves_size_no_independent(void) { - u64 mask = xfeatures_mask_independent(); unsigned int size; + u64 xfeatures_in_xcr0; + u64 old_xss; + u64 old_xcr0; - if (!mask) - return get_xsaves_size(); + /* Stash the old XSAVE control register values: */ + rdmsrl(MSR_IA32_XSS, old_xss); + old_xcr0 = xgetbv(0); /* Disable independent features. */ - wrmsrl(MSR_IA32_XSS, xfeatures_mask_supervisor()); + wrmsrl(MSR_IA32_XSS, old_xss & ~xfeatures_mask_independent()); + + /* + * *Temporarily* (to be removed in a later patch), ennsure there + * is still space for PKRU in the fpstate buffer even though it's + * essentially unused. + */ + xfeatures_in_xcr0 = xfeatures_mask_fpstate() | XFEATURE_MASK_PKRU; + /* Disable user features which are not kept in the fpstate: */ + xsetbv(XCR_XFEATURE_ENABLED_MASK, old_xcr0 & xfeatures_in_xcr0); /* * Ask the hardware what size is required of the buffer. @@ -658,8 +670,9 @@ static unsigned int __init get_xsaves_si */ size = get_xsaves_size(); - /* Re-enable independent features so XSAVES will work on them again. */ - wrmsrl(MSR_IA32_XSS, xfeatures_mask_supervisor() | mask); + /* Re-enable original features so XSAVES will work on them again. */ + wrmsrl(MSR_IA32_XSS, old_xss); + xsetbv(XCR_XFEATURE_ENABLED_MASK, old_xcr0); return size; }