Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp5106543pxj; Tue, 22 Jun 2021 15:27:10 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwxp3PH8fB0RTxUVY+/EXPIZb8YZLxU95dBYnvcdMJ6njt0yTDCuJ/9hpXrSMQHKx8u9Fyi X-Received: by 2002:a02:2547:: with SMTP id g68mr5980985jag.24.1624400830465; Tue, 22 Jun 2021 15:27:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1624400830; cv=none; d=google.com; s=arc-20160816; b=Z33F/E6zjBfbias2m58Z4RGGuT4W3FdpFohDMnRPJoFkYMIB9BPMc0Nh3gAYEposGw 5iQPYXYVw5EWgBhXxxSKtlveeY+w1x2l7HVVeZ4Nhhq7uK/t7fiA5D4r+WiG6J1Lb65u D0caav2alWVj5KZvsb8cLefO7DdCrEOFD5TZ2YhiMt/Z84aYJ341q4T9SBo3jNjahPY6 jin+D9AZ4MnUlldiDxvv31RW5XaRI7Xq+ui65zzfXyUdMbOCyJrCF2EF1Byfwgq5pT/K sIeoeF4eU4GSB03dCGttzR/Fho45MdqX1TKem6hmEC2vS+qveZDt6NwpmymKF1tCidoT EOkg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:message-id:in-reply-to:references:date:from:cc :to:subject:ironport-sdr:ironport-sdr; bh=yMgvnEMB8nYkCwe23h7sHYokq6wOdcvRK/X3BZwHQLo=; b=wMwEmcM5EjK5NJX1teE8hGSdnvJr6JfDW7iAR17vODxmK+ruFXma7cy/QqZG0PyJQN dFbQbWKGoS7m+Y/ACgic5zkPwUotP5nBCbXx1r3oT1P6vvNI1q69B1ocCpDBO9c5OvA+ IH0GPH4N4f9i94+8HLJbDCodp7NMilC9W0RJEPQfUu57dhEDx5wsXmfIpsQmfP+MpLQf lT5BY4+1Oi578/XJkqAmcIPqspjMhaAoneLkkkkfdQji3YdxYudjAdVdNIZpac50u2gI c3MKxClrFHmzpkNl36/iS0ES9Ni31WuD56IwhAzPS+rgVIYVw61r9dpX0zZwREteFWzk VSZw== ARC-Authentication-Results: i=1; mx.google.com; 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=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id 187si23210212iow.86.2021.06.22.15.26.58; Tue, 22 Jun 2021 15:27: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; 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=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230397AbhFVW2O (ORCPT + 99 others); Tue, 22 Jun 2021 18:28:14 -0400 Received: from mga18.intel.com ([134.134.136.126]:18298 "EHLO mga18.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230427AbhFVW2I (ORCPT ); Tue, 22 Jun 2021 18:28:08 -0400 IronPort-SDR: oqycNp9X+xkFfmXQAKnyHauukT9+Y2wmgN9ymsgw2JPZO2pqvj+d+gNS6S93M2aTEpU6NisocY o1sQmoHUljyA== X-IronPort-AV: E=McAfee;i="6200,9189,10023"; a="194459949" X-IronPort-AV: E=Sophos;i="5.83,292,1616482800"; d="scan'208";a="194459949" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga106.jf.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> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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; } _