* [PATCH v1 1/1] x86/fred: Fix the FRED RSP0 MSR out of sync with its per CPU cache
@ 2025-01-08 2:36 Xin Li (Intel)
2025-01-08 3:27 ` H. Peter Anvin
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Xin Li (Intel) @ 2025-01-08 2:36 UTC (permalink / raw)
To: linux-kernel; +Cc: tglx, mingo, bp, dave.hansen, x86, hpa, andrew.cooper3
The FRED RSP0 MSR (pointing to the top of the kernel stack for user
level event delivery) and its per CPU cache should be kept in sync to
avoid redundant writes in the exit to user space path, as a result,
a write to the FRED RSP0 MSR is paired with a write to its per CPU
cache as fred_update_rsp0() does.
However as the FRED RSP0 MSR is set to 0 in cpu_init_fred_exceptions(),
it gets out of sync with its per CPU cache during a CPU offline/online
cycle, which causes #DF exceptions if no context switch happens after
a CPU offline/online cycle and before exit to user space.
Fix the bug through resynchronizing the FRED RSP0 MSR with its per CPU
cache value in cpu_init_fred_exceptions().
Fixes: fe85ee391966 ("x86/entry: Set FRED RSP0 on return to userspace instead of context switch")
Signed-off-by: Xin Li (Intel) <xin@zytor.com>
Cc: stable@vger.kernel.org
---
arch/x86/kernel/fred.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/fred.c b/arch/x86/kernel/fred.c
index 8d32c3f48abc..9524ace96bfa 100644
--- a/arch/x86/kernel/fred.c
+++ b/arch/x86/kernel/fred.c
@@ -50,7 +50,18 @@ void cpu_init_fred_exceptions(void)
FRED_CONFIG_ENTRYPOINT(asm_fred_entrypoint_user));
wrmsrl(MSR_IA32_FRED_STKLVLS, 0);
- wrmsrl(MSR_IA32_FRED_RSP0, 0);
+
+ /*
+ * Resynchronize the FRED RSP0 MSR with its per CPU cache value.
+ *
+ * Another option is to leave the FRED RSP0 MSR as-is, because the RESET
+ * state of FRED MSRs is zero and INIT does not change the value of the
+ * FRED MSRs in a CPU offline/online cycle. But it doesn't seem safe to
+ * depend on the properties of INIT as that's way too many things that
+ * could cause bugs.
+ */
+ wrmsrl(MSR_IA32_FRED_RSP0, __this_cpu_read(fred_rsp0));
+
wrmsrl(MSR_IA32_FRED_RSP1, 0);
wrmsrl(MSR_IA32_FRED_RSP2, 0);
wrmsrl(MSR_IA32_FRED_RSP3, 0);
base-commit: cf6b067860f69fe01b08ebae9138fe0f89854398
--
2.47.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v1 1/1] x86/fred: Fix the FRED RSP0 MSR out of sync with its per CPU cache
2025-01-08 2:36 [PATCH v1 1/1] x86/fred: Fix the FRED RSP0 MSR out of sync with its per CPU cache Xin Li (Intel)
@ 2025-01-08 3:27 ` H. Peter Anvin
2025-01-08 20:14 ` Dave Hansen
2025-01-08 23:04 ` Dave Hansen
2 siblings, 0 replies; 10+ messages in thread
From: H. Peter Anvin @ 2025-01-08 3:27 UTC (permalink / raw)
To: Xin Li (Intel), linux-kernel
Cc: tglx, mingo, bp, dave.hansen, x86, andrew.cooper3
On January 7, 2025 6:36:41 PM PST, "Xin Li (Intel)" <xin@zytor.com> wrote:
>The FRED RSP0 MSR (pointing to the top of the kernel stack for user
>level event delivery) and its per CPU cache should be kept in sync to
>avoid redundant writes in the exit to user space path, as a result,
>a write to the FRED RSP0 MSR is paired with a write to its per CPU
>cache as fred_update_rsp0() does.
>
>However as the FRED RSP0 MSR is set to 0 in cpu_init_fred_exceptions(),
>it gets out of sync with its per CPU cache during a CPU offline/online
>cycle, which causes #DF exceptions if no context switch happens after
>a CPU offline/online cycle and before exit to user space.
>
>Fix the bug through resynchronizing the FRED RSP0 MSR with its per CPU
>cache value in cpu_init_fred_exceptions().
>
>Fixes: fe85ee391966 ("x86/entry: Set FRED RSP0 on return to userspace instead of context switch")
>Signed-off-by: Xin Li (Intel) <xin@zytor.com>
>Cc: stable@vger.kernel.org
>---
> arch/x86/kernel/fred.c | 13 ++++++++++++-
> 1 file changed, 12 insertions(+), 1 deletion(-)
>
>diff --git a/arch/x86/kernel/fred.c b/arch/x86/kernel/fred.c
>index 8d32c3f48abc..9524ace96bfa 100644
>--- a/arch/x86/kernel/fred.c
>+++ b/arch/x86/kernel/fred.c
>@@ -50,7 +50,18 @@ void cpu_init_fred_exceptions(void)
> FRED_CONFIG_ENTRYPOINT(asm_fred_entrypoint_user));
>
> wrmsrl(MSR_IA32_FRED_STKLVLS, 0);
>- wrmsrl(MSR_IA32_FRED_RSP0, 0);
>+
>+ /*
>+ * Resynchronize the FRED RSP0 MSR with its per CPU cache value.
>+ *
>+ * Another option is to leave the FRED RSP0 MSR as-is, because the RESET
>+ * state of FRED MSRs is zero and INIT does not change the value of the
>+ * FRED MSRs in a CPU offline/online cycle. But it doesn't seem safe to
>+ * depend on the properties of INIT as that's way too many things that
>+ * could cause bugs.
>+ */
>+ wrmsrl(MSR_IA32_FRED_RSP0, __this_cpu_read(fred_rsp0));
>+
> wrmsrl(MSR_IA32_FRED_RSP1, 0);
> wrmsrl(MSR_IA32_FRED_RSP2, 0);
> wrmsrl(MSR_IA32_FRED_RSP3, 0);
>
>base-commit: cf6b067860f69fe01b08ebae9138fe0f89854398
Looks straightforward enough.
Reviewed-by: H. Peter Anvin (Intel) <hpa@zytor.com>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v1 1/1] x86/fred: Fix the FRED RSP0 MSR out of sync with its per CPU cache
2025-01-08 2:36 [PATCH v1 1/1] x86/fred: Fix the FRED RSP0 MSR out of sync with its per CPU cache Xin Li (Intel)
2025-01-08 3:27 ` H. Peter Anvin
@ 2025-01-08 20:14 ` Dave Hansen
2025-01-08 21:10 ` Andrew Cooper
2025-01-09 9:46 ` H. Peter Anvin
2025-01-08 23:04 ` Dave Hansen
2 siblings, 2 replies; 10+ messages in thread
From: Dave Hansen @ 2025-01-08 20:14 UTC (permalink / raw)
To: Xin Li (Intel), linux-kernel
Cc: tglx, mingo, bp, dave.hansen, x86, hpa, andrew.cooper3
On 1/7/25 18:36, Xin Li (Intel) wrote:
> + * Another option is to leave the FRED RSP0 MSR as-is, because the RESET
> + * state of FRED MSRs is zero and INIT does not change the value of the
> + * FRED MSRs in a CPU offline/online cycle. But it doesn't seem safe to
> + * depend on the properties of INIT as that's way too many things that
> + * could cause bugs.
Wouldn't that also open us up to kexec problems? If the last kernel
(maybe not even Linux) left RSP0 set, then the current kernel might
eventually try to run userspace with the old kernel's RSP0 value.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v1 1/1] x86/fred: Fix the FRED RSP0 MSR out of sync with its per CPU cache
2025-01-08 20:14 ` Dave Hansen
@ 2025-01-08 21:10 ` Andrew Cooper
2025-01-08 22:31 ` Dave Hansen
2025-01-09 9:46 ` H. Peter Anvin
1 sibling, 1 reply; 10+ messages in thread
From: Andrew Cooper @ 2025-01-08 21:10 UTC (permalink / raw)
To: Dave Hansen, Xin Li (Intel), linux-kernel
Cc: tglx, mingo, bp, dave.hansen, x86, hpa
On 08/01/2025 8:14 pm, Dave Hansen wrote:
> On 1/7/25 18:36, Xin Li (Intel) wrote:
>> + * Another option is to leave the FRED RSP0 MSR as-is, because the RESET
>> + * state of FRED MSRs is zero and INIT does not change the value of the
>> + * FRED MSRs in a CPU offline/online cycle. But it doesn't seem safe to
>> + * depend on the properties of INIT as that's way too many things that
>> + * could cause bugs.
> Wouldn't that also open us up to kexec problems? If the last kernel
> (maybe not even Linux) left RSP0 set, then the current kernel might
> eventually try to run userspace with the old kernel's RSP0 value.
That's why the init code needs to write every control MSR, even if it's
filling in 0 because it doesn't want to use the feature.
The job of the init code is to go from an unknown state into a good
state, not from the INIT/#RESET state.
Or someone could finally write down an ABI for Kexec which details who's
responsibility it is :)
~Andrew
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v1 1/1] x86/fred: Fix the FRED RSP0 MSR out of sync with its per CPU cache
2025-01-08 21:10 ` Andrew Cooper
@ 2025-01-08 22:31 ` Dave Hansen
2025-01-08 23:32 ` Xin Li
0 siblings, 1 reply; 10+ messages in thread
From: Dave Hansen @ 2025-01-08 22:31 UTC (permalink / raw)
To: Andrew Cooper, Xin Li (Intel), linux-kernel
Cc: tglx, mingo, bp, dave.hansen, x86, hpa
On 1/8/25 13:10, Andrew Cooper wrote:
> On 08/01/2025 8:14 pm, Dave Hansen wrote:
>> On 1/7/25 18:36, Xin Li (Intel) wrote:
>>> + * Another option is to leave the FRED RSP0 MSR as-is, because the RESET
>>> + * state of FRED MSRs is zero and INIT does not change the value of the
>>> + * FRED MSRs in a CPU offline/online cycle. But it doesn't seem safe to
>>> + * depend on the properties of INIT as that's way too many things that
>>> + * could cause bugs.
>> Wouldn't that also open us up to kexec problems? If the last kernel
>> (maybe not even Linux) left RSP0 set, then the current kernel might
>> eventually try to run userspace with the old kernel's RSP0 value.
> That's why the init code needs to write every control MSR, even if it's
> filling in 0 because it doesn't want to use the feature.
>
> The job of the init code is to go from an unknown state into a good
> state, not from the INIT/#RESET state.
Right, so I think the quoted "Another option..." comment needs to get
zapped. Because it's not really another option. Discussing alternatives
is better left for changelogs anyway, not code comments.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v1 1/1] x86/fred: Fix the FRED RSP0 MSR out of sync with its per CPU cache
2025-01-08 22:31 ` Dave Hansen
@ 2025-01-08 23:32 ` Xin Li
0 siblings, 0 replies; 10+ messages in thread
From: Xin Li @ 2025-01-08 23:32 UTC (permalink / raw)
To: Dave Hansen, Andrew Cooper, linux-kernel
Cc: tglx, mingo, bp, dave.hansen, x86, hpa
On 1/8/2025 2:31 PM, Dave Hansen wrote:
> On 1/8/25 13:10, Andrew Cooper wrote:
>> On 08/01/2025 8:14 pm, Dave Hansen wrote:
>>> On 1/7/25 18:36, Xin Li (Intel) wrote:
>>>> + * Another option is to leave the FRED RSP0 MSR as-is, because the RESET
>>>> + * state of FRED MSRs is zero and INIT does not change the value of the
>>>> + * FRED MSRs in a CPU offline/online cycle. But it doesn't seem safe to
>>>> + * depend on the properties of INIT as that's way too many things that
>>>> + * could cause bugs.
>>> Wouldn't that also open us up to kexec problems? If the last kernel
>>> (maybe not even Linux) left RSP0 set, then the current kernel might
>>> eventually try to run userspace with the old kernel's RSP0 value.
>> That's why the init code needs to write every control MSR, even if it's
>> filling in 0 because it doesn't want to use the feature.
>>
>> The job of the init code is to go from an unknown state into a good
>> state, not from the INIT/#RESET state.
>
> Right, so I think the quoted "Another option..." comment needs to get
> zapped. Because it's not really another option. Discussing alternatives
> is better left for changelogs anyway, not code comments.
>
Will do!
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v1 1/1] x86/fred: Fix the FRED RSP0 MSR out of sync with its per CPU cache
2025-01-08 20:14 ` Dave Hansen
2025-01-08 21:10 ` Andrew Cooper
@ 2025-01-09 9:46 ` H. Peter Anvin
2025-01-09 18:48 ` Xin Li
1 sibling, 1 reply; 10+ messages in thread
From: H. Peter Anvin @ 2025-01-09 9:46 UTC (permalink / raw)
To: Dave Hansen, Xin Li (Intel), linux-kernel
Cc: tglx, mingo, bp, dave.hansen, x86, andrew.cooper3
On January 8, 2025 12:14:18 PM PST, Dave Hansen <dave.hansen@intel.com> wrote:
>On 1/7/25 18:36, Xin Li (Intel) wrote:
>> + * Another option is to leave the FRED RSP0 MSR as-is, because the RESET
>> + * state of FRED MSRs is zero and INIT does not change the value of the
>> + * FRED MSRs in a CPU offline/online cycle. But it doesn't seem safe to
>> + * depend on the properties of INIT as that's way too many things that
>> + * could cause bugs.
>
>Wouldn't that also open us up to kexec problems? If the last kernel
>(maybe not even Linux) left RSP0 set, then the current kernel might
>eventually try to run userspace with the old kernel's RSP0 value.
>
Yeah, it is a nonstarter. I believe Xin was trying to document the problems with *not* doing this, so someone doesn't have the bright idea to "optimize" this later.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v1 1/1] x86/fred: Fix the FRED RSP0 MSR out of sync with its per CPU cache
2025-01-09 9:46 ` H. Peter Anvin
@ 2025-01-09 18:48 ` Xin Li
0 siblings, 0 replies; 10+ messages in thread
From: Xin Li @ 2025-01-09 18:48 UTC (permalink / raw)
To: H. Peter Anvin, Dave Hansen, linux-kernel
Cc: tglx, mingo, bp, dave.hansen, x86, andrew.cooper3
On 1/9/2025 1:46 AM, H. Peter Anvin wrote:
> On January 8, 2025 12:14:18 PM PST, Dave Hansen <dave.hansen@intel.com> wrote:
>> On 1/7/25 18:36, Xin Li (Intel) wrote:
>>> + * Another option is to leave the FRED RSP0 MSR as-is, because the RESET
>>> + * state of FRED MSRs is zero and INIT does not change the value of the
>>> + * FRED MSRs in a CPU offline/online cycle. But it doesn't seem safe to
>>> + * depend on the properties of INIT as that's way too many things that
>>> + * could cause bugs.
>>
>> Wouldn't that also open us up to kexec problems? If the last kernel
>> (maybe not even Linux) left RSP0 set, then the current kernel might
>> eventually try to run userspace with the old kernel's RSP0 value.
>>
>
> Yeah, it is a nonstarter. I believe Xin was trying to document the problems with *not* doing this, so someone doesn't have the bright idea to "optimize" this later.
>
exactly ;)
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v1 1/1] x86/fred: Fix the FRED RSP0 MSR out of sync with its per CPU cache
2025-01-08 2:36 [PATCH v1 1/1] x86/fred: Fix the FRED RSP0 MSR out of sync with its per CPU cache Xin Li (Intel)
2025-01-08 3:27 ` H. Peter Anvin
2025-01-08 20:14 ` Dave Hansen
@ 2025-01-08 23:04 ` Dave Hansen
2025-01-08 23:32 ` Xin Li
2 siblings, 1 reply; 10+ messages in thread
From: Dave Hansen @ 2025-01-08 23:04 UTC (permalink / raw)
To: Xin Li (Intel), linux-kernel
Cc: tglx, mingo, bp, dave.hansen, x86, hpa, andrew.cooper3
On 1/7/25 18:36, Xin Li (Intel) wrote:
> The FRED RSP0 MSR (pointing to the top of the kernel stack for user
> level event delivery) and its per CPU cache should be kept in sync to
> avoid redundant writes in the exit to user space path, as a result,
> a write to the FRED RSP0 MSR is paired with a write to its per CPU
> cache as fred_update_rsp0() does.
I _think_ you're trying to explain the general use of a per-cpu MSR
cache. That's good. But I was reading this paragraph and thinking at
this point that the bug had something to do with redundant writes to the
MSR.
How about this?
The FRED RSP0 MSR is only used for delivering events when
running userspace. This kernel leverages this property to reduce
expensive MSR writes and optimize context switches. The kernel
only writes the MSR when about to run userspace *and* when the
MSR has actually changed since the last time userspace ran.
This optimization is implemented by maintaining a per-cpu cache
of FRED RSP0 and then checking that against the value for the
current task's stack before running userspace.
However cpu_init_fred_exceptions() writes the MSR without
updating the per-cpu cache. This means that the kernel might
return to userspace with MSR_IA32_FRED_RSP0==0 when it needed to
point to the current task stack. This would induce a double
fault (#DF), which is bad.
A context switch after cpu_init_fred_exceptions() can paper over
the issue since it updates the cached value. That evidently
happens most of the time explaining how this bug got through.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v1 1/1] x86/fred: Fix the FRED RSP0 MSR out of sync with its per CPU cache
2025-01-08 23:04 ` Dave Hansen
@ 2025-01-08 23:32 ` Xin Li
0 siblings, 0 replies; 10+ messages in thread
From: Xin Li @ 2025-01-08 23:32 UTC (permalink / raw)
To: Dave Hansen, linux-kernel
Cc: tglx, mingo, bp, dave.hansen, x86, hpa, andrew.cooper3
On 1/8/2025 3:04 PM, Dave Hansen wrote:
> On 1/7/25 18:36, Xin Li (Intel) wrote:
>> The FRED RSP0 MSR (pointing to the top of the kernel stack for user
>> level event delivery) and its per CPU cache should be kept in sync to
>> avoid redundant writes in the exit to user space path, as a result,
>> a write to the FRED RSP0 MSR is paired with a write to its per CPU
>> cache as fred_update_rsp0() does.
>
> I _think_ you're trying to explain the general use of a per-cpu MSR
> cache. That's good. But I was reading this paragraph and thinking at
> this point that the bug had something to do with redundant writes to the
> MSR.
>
> How about this?
>
> The FRED RSP0 MSR is only used for delivering events when
> running userspace. This kernel leverages this property to reduce
> expensive MSR writes and optimize context switches. The kernel
> only writes the MSR when about to run userspace *and* when the
> MSR has actually changed since the last time userspace ran.
>
> This optimization is implemented by maintaining a per-cpu cache
> of FRED RSP0 and then checking that against the value for the
> current task's stack before running userspace.
>
> However cpu_init_fred_exceptions() writes the MSR without
> updating the per-cpu cache. This means that the kernel might
> return to userspace with MSR_IA32_FRED_RSP0==0 when it needed to
> point to the current task stack. This would induce a double
> fault (#DF), which is bad.
>
> A context switch after cpu_init_fred_exceptions() can paper over
> the issue since it updates the cached value. That evidently
> happens most of the time explaining how this bug got through.
>
This is a way better explanation, thanks a lot!
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-01-09 18:49 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-08 2:36 [PATCH v1 1/1] x86/fred: Fix the FRED RSP0 MSR out of sync with its per CPU cache Xin Li (Intel)
2025-01-08 3:27 ` H. Peter Anvin
2025-01-08 20:14 ` Dave Hansen
2025-01-08 21:10 ` Andrew Cooper
2025-01-08 22:31 ` Dave Hansen
2025-01-08 23:32 ` Xin Li
2025-01-09 9:46 ` H. Peter Anvin
2025-01-09 18:48 ` Xin Li
2025-01-08 23:04 ` Dave Hansen
2025-01-08 23:32 ` Xin Li
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox