From: "tip-bot2 for Thomas Gleixner" <tip-bot2@linutronix.de>
To: linux-tip-commits@vger.kernel.org
Cc: Thomas Gleixner <tglx@linutronix.de>,
Borislav Petkov <bp@suse.de>,
x86@kernel.org, linux-kernel@vger.kernel.org
Subject: [tip: x86/urgent] x86/fpu/xsave: Handle compacted offsets correctly with supervisor states
Date: Thu, 31 Mar 2022 09:00:56 -0000 [thread overview]
Message-ID: <164871725613.389.9141180455154024348.tip-bot2@tip-bot2> (raw)
In-Reply-To: <20220324134623.627636809@linutronix.de>
The following commit has been merged into the x86/urgent branch of tip:
Commit-ID: 7aa5128b5fea26cf224766303ea3b8df343f9a87
Gitweb: https://git.kernel.org/tip/7aa5128b5fea26cf224766303ea3b8df343f9a87
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Thu, 24 Mar 2022 14:47:13 +01:00
Committer: Borislav Petkov <bp@suse.de>
CommitterDate: Wed, 30 Mar 2022 11:20:36 +02:00
x86/fpu/xsave: Handle compacted offsets correctly with supervisor states
So far the cached fixed compacted offsets worked, but with (re-)enabling
of ENQCMD this does no longer work with KVM fpstate.
KVM does not have supervisor features enabled for the guest FPU, which
means that KVM has then a different XSAVE area layout than the host FPU
state. This in turn breaks the copy from/to UABI functions when invoked for
a guest state.
Remove the pre-calculated compacted offsets and calculate the offset
of each component at runtime based on the XCOMP_BV field in the XSAVE
header.
The runtime overhead is not interesting because these copy from/to UABI
functions are not used in critical fast paths. KVM uses them to save and
restore FPU state during migration. The host uses them for ptrace and for
the slow path of 32bit signal handling.
Fixes: 7c1ef59145f1 ("x86/cpufeatures: Re-enable ENQCMD")
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lore.kernel.org/r/20220324134623.627636809@linutronix.de
---
arch/x86/kernel/fpu/xstate.c | 86 ++++++++++++++++-------------------
1 file changed, 41 insertions(+), 45 deletions(-)
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 5a069c2..c55f72e 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -81,8 +81,6 @@ static unsigned int xstate_offsets[XFEATURE_MAX] __ro_after_init =
{ [ 0 ... XFEATURE_MAX - 1] = -1};
static unsigned int xstate_sizes[XFEATURE_MAX] __ro_after_init =
{ [ 0 ... XFEATURE_MAX - 1] = -1};
-static unsigned int xstate_comp_offsets[XFEATURE_MAX] __ro_after_init =
- { [ 0 ... XFEATURE_MAX - 1] = -1};
static unsigned int xstate_flags[XFEATURE_MAX] __ro_after_init;
#define XSTATE_FLAG_SUPERVISOR BIT(0)
@@ -136,6 +134,33 @@ static bool xfeature_is_supervisor(int xfeature_nr)
return xstate_flags[xfeature_nr] & XSTATE_FLAG_SUPERVISOR;
}
+static unsigned int xfeature_get_offset(u64 xcomp_bv, int xfeature)
+{
+ unsigned int offs, i;
+
+ /*
+ * Non-compacted format and legacy features use the cached fixed
+ * offsets.
+ */
+ if (!cpu_feature_enabled(X86_FEATURE_XSAVES) || xfeature <= XFEATURE_SSE)
+ return xstate_offsets[xfeature];
+
+ /*
+ * Compacted format offsets depend on the actual content of the
+ * compacted xsave area which is determined by the xcomp_bv header
+ * field.
+ */
+ offs = FXSAVE_SIZE + XSAVE_HDR_SIZE;
+ for_each_extended_xfeature(i, xcomp_bv) {
+ if (xfeature_is_aligned64(i))
+ offs = ALIGN(offs, 64);
+ if (i == xfeature)
+ break;
+ offs += xstate_sizes[i];
+ }
+ return offs;
+}
+
/*
* Enable the extended processor state save/restore feature.
* Called once per CPU onlining.
@@ -264,42 +289,6 @@ static void __init print_xstate_features(void)
} while (0)
/*
- * This function sets up offsets and sizes of all extended states in
- * xsave area. This supports both standard format and compacted format
- * of the xsave area.
- */
-static void __init setup_xstate_comp_offsets(void)
-{
- unsigned int next_offset;
- int i;
-
- /*
- * The FP xstates and SSE xstates are legacy states. They are always
- * in the fixed offsets in the xsave area in either compacted form
- * or standard form.
- */
- xstate_comp_offsets[XFEATURE_FP] = 0;
- xstate_comp_offsets[XFEATURE_SSE] = offsetof(struct fxregs_state,
- xmm_space);
-
- if (!cpu_feature_enabled(X86_FEATURE_XSAVES)) {
- for_each_extended_xfeature(i, fpu_kernel_cfg.max_features)
- xstate_comp_offsets[i] = xstate_offsets[i];
- return;
- }
-
- next_offset = FXSAVE_SIZE + XSAVE_HDR_SIZE;
-
- for_each_extended_xfeature(i, fpu_kernel_cfg.max_features) {
- if (xfeature_is_aligned64(i))
- next_offset = ALIGN(next_offset, 64);
-
- xstate_comp_offsets[i] = next_offset;
- next_offset += xstate_sizes[i];
- }
-}
-
-/*
* Print out xstate component offsets and sizes
*/
static void __init print_xstate_offset_size(void)
@@ -308,7 +297,8 @@ static void __init print_xstate_offset_size(void)
for_each_extended_xfeature(i, fpu_kernel_cfg.max_features) {
pr_info("x86/fpu: xstate_offset[%d]: %4d, xstate_sizes[%d]: %4d\n",
- i, xstate_comp_offsets[i], i, xstate_sizes[i]);
+ i, xfeature_get_offset(fpu_kernel_cfg.max_features, i),
+ i, xstate_sizes[i]);
}
}
@@ -901,7 +891,6 @@ void __init fpu__init_system_xstate(unsigned int legacy_size)
fpu_user_cfg.max_features);
setup_init_fpu_buf();
- setup_xstate_comp_offsets();
/*
* Paranoia check whether something in the setup modified the
@@ -956,13 +945,19 @@ void fpu__resume_cpu(void)
*/
static void *__raw_xsave_addr(struct xregs_state *xsave, int xfeature_nr)
{
- if (!xfeature_enabled(xfeature_nr)) {
- WARN_ON_FPU(1);
+ u64 xcomp_bv = xsave->header.xcomp_bv;
+
+ if (WARN_ON_ONCE(!xfeature_enabled(xfeature_nr)))
return NULL;
+
+ if (cpu_feature_enabled(X86_FEATURE_XSAVES)) {
+ if (WARN_ON_ONCE(!(xcomp_bv & BIT_ULL(xfeature_nr))))
+ return NULL;
}
- return (void *)xsave + xstate_comp_offsets[xfeature_nr];
+ return (void *)xsave + xfeature_get_offset(xcomp_bv, xfeature_nr);
}
+
/*
* Given the xsave area and a state inside, this function returns the
* address of the state.
@@ -993,8 +988,9 @@ void *get_xsave_addr(struct xregs_state *xsave, int xfeature_nr)
* We should not ever be requesting features that we
* have not enabled.
*/
- WARN_ONCE(!(fpu_kernel_cfg.max_features & BIT_ULL(xfeature_nr)),
- "get of unsupported state");
+ if (WARN_ON_ONCE(!xfeature_enabled(xfeature_nr)))
+ return NULL;
+
/*
* This assumes the last 'xsave*' instruction to
* have requested that 'xfeature_nr' be saved.
next prev parent reply other threads:[~2022-03-31 9:01 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-24 13:47 [patch 0/7] x86/fpu: Cure supervisor mode (ENQCMD) fallout Thomas Gleixner
2022-03-24 13:47 ` [patch 1/7] x86/fpu: Remove redundant XCOMP_BV initialization Thomas Gleixner
2022-03-31 9:01 ` [tip: x86/urgent] " tip-bot2 for Thomas Gleixner
2022-03-24 13:47 ` [patch 2/7] x86/fpu: Remove unused supervisor only offsets Thomas Gleixner
2022-03-31 9:00 ` [tip: x86/urgent] " tip-bot2 for Thomas Gleixner
2022-03-24 13:47 ` [patch 3/7] x86/fpu/xsave: Initialize offset/size cache early Thomas Gleixner
2022-03-31 9:00 ` [tip: x86/urgent] " tip-bot2 for Thomas Gleixner
2022-03-24 13:47 ` [patch 4/7] x86/fpu: Cache xfeature flags from CPUID Thomas Gleixner
2022-03-31 9:00 ` [tip: x86/urgent] " tip-bot2 for Thomas Gleixner
2022-03-24 13:47 ` [patch 5/7] x86/fpu/xsave: Handle compacted offsets correctly with supervisor states Thomas Gleixner
2022-03-31 9:00 ` tip-bot2 for Thomas Gleixner [this message]
2022-03-24 13:47 ` [patch 6/7] x86/fpu/xstate: Handle supervisor states in XSTATE permissions Thomas Gleixner
2022-03-31 9:00 ` [tip: x86/urgent] " tip-bot2 for Thomas Gleixner
2022-03-24 13:47 ` [patch 7/7] x86/fpu/xstate: Consolidate size calculations Thomas Gleixner
2022-03-28 18:43 ` [patch V2 " Thomas Gleixner
2022-03-31 9:00 ` [tip: x86/urgent] " tip-bot2 for Thomas Gleixner
2022-03-28 12:39 ` [patch 0/7] x86/fpu: Cure supervisor mode (ENQCMD) fallout Chang S. Bae
2022-03-28 22:30 ` Fenghua Yu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=164871725613.389.9141180455154024348.tip-bot2@tip-bot2 \
--to=tip-bot2@linutronix.de \
--cc=bp@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®