Skip to content

Conversation

@Kunkka1988
Copy link

There are 47 patches in this single PR for FRED back-port from upstream stable kernel.
This PR is based on commit node:
"267e33ff5e03 (origin/6.6-velinux, 6.6-velinux) Revert "arm64: mm: hugetlb: Disable HUGETLB_PAGE_OPTIMIZE_VMEMMAP""

All of FRED LKVS test cases are passed:
$ sudo ./fred_test.sh -t cmdline
|1106_005244.661|TRACE|do_cmd() is called by fred_test.sh:35:cmdline_test()|
|1106_005244.665|TRACE|CMD=grep -q 'fred=on' '/proc/cmdline'|

$ sudo ./fred_test.sh -t dmesg
|1106_005249.770|TRACE|do_cmd() is called by fred_test.sh:40:dmesg_test()|
|1106_005249.773|TRACE|CMD=dmesg | grep 'Initialize FRED on CPU'|
[    0.008869] Initialize FRED on CPU0
[    4.845212] Initialize FRED on CPU25
[    4.845212] Initialize FRED on CPU15
[    4.845212] Initialize FRED on CPU5
[    4.845212] Initialize FRED on CPU27
[    4.845212] Initialize FRED on CPU18
[    4.845212] Initialize FRED on CPU3
[    4.845212] Initialize FRED on CPU13
[    4.845212] Initialize FRED on CPU6
[    4.845212] Initialize FRED on CPU1
[    4.845212] Initialize FRED on CPU7
[    4.845212] Initialize FRED on CPU19
[    4.845212] Initialize FRED on CPU14
[    4.845212] Initialize FRED on CPU17
[    4.845212] Initialize FRED on CPU12
[    4.845212] Initialize FRED on CPU4
[    4.845212] Initialize FRED on CPU24
[    4.845212] Initialize FRED on CPU2
[    4.845212] Initialize FRED on CPU26
[    4.845212] Initialize FRED on CPU16
[    4.845212] Initialize FRED on CPU36
[    4.845212] Initialize FRED on CPU37
[    4.845212] Initialize FRED on CPU38
[    4.845212] Initialize FRED on CPU44
[    4.845212] Initialize FRED on CPU45
[    4.845212] Initialize FRED on CPU39
[    4.845212] Initialize FRED on CPU46
[    4.845212] Initialize FRED on CPU47
[    4.845212] Initialize FRED on CPU8
[    4.845212] Initialize FRED on CPU9
[    4.845212] Initialize FRED on CPU10
[    4.845212] Initialize FRED on CPU48
[    4.845212] Initialize FRED on CPU11
[    4.845212] Initialize FRED on CPU49
[    4.845212] Initialize FRED on CPU40
[    4.845212] Initialize FRED on CPU41
[    4.845212] Initialize FRED on CPU50
[    4.845212] Initialize FRED on CPU51
[    4.845212] Initialize FRED on CPU42
[    4.845212] Initialize FRED on CPU43
[    4.845212] Initialize FRED on CPU20
[    4.845212] Initialize FRED on CPU21
[    4.845212] Initialize FRED on CPU22
[    4.845212] Initialize FRED on CPU52
[    4.845212] Initialize FRED on CPU80
[    4.845212] Initialize FRED on CPU23
[    4.845212] Initialize FRED on CPU53
[    4.845212] Initialize FRED on CPU81
[    4.845212] Initialize FRED on CPU54
[    4.845212] Initialize FRED on CPU82
[    4.845212] Initialize FRED on CPU55
[    4.845212] Initialize FRED on CPU83
[    4.845212] Initialize FRED on CPU56
[    4.845212] Initialize FRED on CPU84
[    4.845212] Initialize FRED on CPU57
[    4.845212] Initialize FRED on CPU85
[    4.845212] Initialize FRED on CPU58
[    4.845212] Initialize FRED on CPU60
[    4.845212] Initialize FRED on CPU76
[    4.845212] Initialize FRED on CPU86
[    4.845212] Initialize FRED on CPU59
[    4.845212] Initialize FRED on CPU61
[    4.845212] Initialize FRED on CPU96
[    4.845212] Initialize FRED on CPU77
[    4.845212] Initialize FRED on CPU62
[    4.845212] Initialize FRED on CPU97
[    4.845212] Initialize FRED on CPU78
[    4.845212] Initialize FRED on CPU63
[    4.845212] Initialize FRED on CPU87
[    4.845212] Initialize FRED on CPU79
[    4.845212] Initialize FRED on CPU98
[    4.845212] Initialize FRED on CPU99
[    4.845212] Initialize FRED on CPU64
[    4.845212] Initialize FRED on CPU65
[    4.845212] Initialize FRED on CPU66
[    4.845212] Initialize FRED on CPU67
[    4.845212] Initialize FRED on CPU128
[    4.845212] Initialize FRED on CPU129
[    4.845212] Initialize FRED on CPU130
[    4.845212] Initialize FRED on CPU131
[    4.845212] Initialize FRED on CPU100
[    4.845212] Initialize FRED on CPU101
[    4.845212] Initialize FRED on CPU108
[    4.845212] Initialize FRED on CPU102
[    4.845212] Initialize FRED on CPU109
[    4.845212] Initialize FRED on CPU103
[    4.845212] Initialize FRED on CPU110
[    4.845212] Initialize FRED on CPU111
[    4.845212] Initialize FRED on CPU140
[    4.845212] Initialize FRED on CPU141
[    4.845212] Initialize FRED on CPU142
[    4.845212] Initialize FRED on CPU143
[    4.845212] Initialize FRED on CPU132
[    4.845212] Initialize FRED on CPU133
[    4.845212] Initialize FRED on CPU134
[    4.845212] Initialize FRED on CPU135
[    4.845212] Initialize FRED on CPU136
[    4.845212] Initialize FRED on CPU137
[    4.845212] Initialize FRED on CPU138
[    4.845212] Initialize FRED on CPU139
[    4.845212] Initialize FRED on CPU104
[    4.845212] Initialize FRED on CPU105
[    4.845212] Initialize FRED on CPU106
[    4.845212] Initialize FRED on CPU107
[    4.845212] Initialize FRED on CPU160
[    4.845212] Initialize FRED on CPU161
[    4.845212] Initialize FRED on CPU162
[    4.845212] Initialize FRED on CPU163
[    4.845212] Initialize FRED on CPU152
[    4.845212] Initialize FRED on CPU153
[    4.845212] Initialize FRED on CPU154
[    4.845212] Initialize FRED on CPU155
[    4.845212] Initialize FRED on CPU156
[    4.845212] Initialize FRED on CPU157
[    4.845212] Initialize FRED on CPU158
[    4.845212] Initialize FRED on CPU159
[    4.845212] Initialize FRED on CPU144
[    4.845212] Initialize FRED on CPU145
[    4.845212] Initialize FRED on CPU146
[    4.845212] Initialize FRED on CPU147
[    4.845212] Initialize FRED on CPU172
[    4.845212] Initialize FRED on CPU180
[    4.845212] Initialize FRED on CPU173
[    4.845212] Initialize FRED on CPU176
[    4.845212] Initialize FRED on CPU181
[    4.845212] Initialize FRED on CPU174
[    4.845212] Initialize FRED on CPU177
[    4.845212] Initialize FRED on CPU175
[    4.845212] Initialize FRED on CPU182
[    4.845212] Initialize FRED on CPU183
[    4.845212] Initialize FRED on CPU178
[    4.845212] Initialize FRED on CPU179
[    4.845212] Initialize FRED on CPU184
[    4.845212] Initialize FRED on CPU192
[    4.845212] Initialize FRED on CPU196
[    4.845212] Initialize FRED on CPU185
[    4.845212] Initialize FRED on CPU186
[    4.845212] Initialize FRED on CPU193
[    4.845212] Initialize FRED on CPU187
[    4.845212] Initialize FRED on CPU188
[    4.845212] Initialize FRED on CPU194
[    4.845212] Initialize FRED on CPU195
[    4.845212] Initialize FRED on CPU189
[    4.845212] Initialize FRED on CPU197
[    4.845212] Initialize FRED on CPU198
[    4.845212] Initialize FRED on CPU190
[    4.845212] Initialize FRED on CPU191
[    4.845212] Initialize FRED on CPU148
[    4.845212] Initialize FRED on CPU149
[    4.845212] Initialize FRED on CPU150
[    4.845212] Initialize FRED on CPU151
[    4.845212] Initialize FRED on CPU120
[    4.845212] Initialize FRED on CPU121
[    4.845212] Initialize FRED on CPU122
[    4.845212] Initialize FRED on CPU123
[    4.845212] Initialize FRED on CPU112
[    4.845212] Initialize FRED on CPU113
[    4.845212] Initialize FRED on CPU114
[    4.845212] Initialize FRED on CPU115
[    4.845212] Initialize FRED on CPU28
[    4.845212] Initialize FRED on CPU29
[    4.845212] Initialize FRED on CPU30
[    4.845212] Initialize FRED on CPU31
[    4.845212] Initialize FRED on CPU164
[    4.845212] Initialize FRED on CPU165
[    4.845212] Initialize FRED on CPU166
[    4.845212] Initialize FRED on CPU167
[    4.845212] Initialize FRED on CPU32
[    4.845212] Initialize FRED on CPU33
[    4.845212] Initialize FRED on CPU168
[    4.845212] Initialize FRED on CPU34
[    4.845212] Initialize FRED on CPU35
[    4.845212] Initialize FRED on CPU169
[    4.845212] Initialize FRED on CPU170
[    4.845212] Initialize FRED on CPU171
[    4.845212] Initialize FRED on CPU68
[    4.845212] Initialize FRED on CPU69
[    4.845212] Initialize FRED on CPU70
[    4.845212] Initialize FRED on CPU71
[    4.845212] Initialize FRED on CPU72
[    4.845212] Initialize FRED on CPU73
[    4.845212] Initialize FRED on CPU74
[    4.845212] Initialize FRED on CPU75
[    4.845212] Initialize FRED on CPU116
[    4.845212] Initialize FRED on CPU117
[    4.845212] Initialize FRED on CPU88
[    4.845212] Initialize FRED on CPU118
[    4.845212] Initialize FRED on CPU89
[    4.845212] Initialize FRED on CPU119
[    4.845212] Initialize FRED on CPU90
[    4.845212] Initialize FRED on CPU91
[    4.845212] Initialize FRED on CPU92
[    4.845212] Initialize FRED on CPU93
[    4.845212] Initialize FRED on CPU94
[    4.845212] Initialize FRED on CPU95
[    4.845212] Initialize FRED on CPU124
[    4.845212] Initialize FRED on CPU125
[    4.845212] Initialize FRED on CPU126
[    4.845212] Initialize FRED on CPU127
[    4.845212] Initialize FRED on CPU199
[    4.845212] Initialize FRED on CPU200
[    4.845212] Initialize FRED on CPU201
[    4.845212] Initialize FRED on CPU202
[    4.845212] Initialize FRED on CPU203
[    4.845212] Initialize FRED on CPU204
[    4.845212] Initialize FRED on CPU205
[    4.845212] Initialize FRED on CPU206
[    4.845212] Initialize FRED on CPU207
[    4.845212] Initialize FRED on CPU208
[    4.845212] Initialize FRED on CPU209
[    4.845212] Initialize FRED on CPU210
[    4.845212] Initialize FRED on CPU211
[    4.845212] Initialize FRED on CPU212
[    4.845212] Initialize FRED on CPU213
[    4.845212] Initialize FRED on CPU214
[    4.845212] Initialize FRED on CPU215
[    4.845212] Initialize FRED on CPU216
[    4.845212] Initialize FRED on CPU217
[    4.845212] Initialize FRED on CPU218
[    4.845212] Initialize FRED on CPU219
[    4.845212] Initialize FRED on CPU220
[    4.845212] Initialize FRED on CPU221
[    4.845212] Initialize FRED on CPU222
[    4.845212] Initialize FRED on CPU223
[    4.845212] Initialize FRED on CPU228
[    4.845212] Initialize FRED on CPU229
[    4.845212] Initialize FRED on CPU230
[    4.845212] Initialize FRED on CPU231
[    4.845212] Initialize FRED on CPU225
[    4.845212] Initialize FRED on CPU224
[    4.845212] Initialize FRED on CPU226
[    4.845212] Initialize FRED on CPU227
[    4.845212] Initialize FRED on CPU232
[    4.845212] Initialize FRED on CPU233
[    4.845212] Initialize FRED on CPU234
[    4.845212] Initialize FRED on CPU235
[    4.845212] Initialize FRED on CPU236
[    4.845212] Initialize FRED on CPU237
[    4.845212] Initialize FRED on CPU238
[    4.845212] Initialize FRED on CPU239

$ sudo ./fred_test.sh -t cpuid
|1106_005302.323|TRACE|do_cmd() is called by fred_test.sh:46:cpuid_test()|
|1106_005302.326|TRACE|CMD=cpuid_check 7 0 1 0 a 17|
6 parameters, eax=7
cpuid(eax=00000007, ebx=00000000, ecx=00000001, edx=00000000)
cpuid(&eax=0x7fff1534cf28, &ebx=0x7fff1534cf2c, &ecx=0x7fff1534cf30, &edx=0x7fff1534cf34)
After native_cpuid:
out:  eax=4c9e09d7, ebx=00000001, ecx=00000023,  edx=0184d430
cpuid(&eax=0x7fff1534cf28, &ebx=0x7fff1534cf2c, &ecx=0x7fff1534cf30, &edx=0x7fff1534cf34)
output:
  eax=4c9e09d7    || Binary: 0100 1100 1001 1110 0000 1001 1101 0111
  ebx=00000001    || Binary: 0000 0000 0000 0000 0000 0000 0000 0001
  ecx=00000023    || Binary: 0000 0000 0000 0000 0000 0000 0010 0011
  edx=0184d430    || Binary: 0000 0001 1000 0100 1101 0100 0011 0000
Now check cpuid eax, bit 17
Start with 0, pass: bit set 1, fail: bit set 0
Order bit:14, invert order:17, bit:1, pass!
Done! Return:0.

$ sudo ./fred_test.sh -t cpuinfo
|1106_005308.698|TRACE|do_cmd() is called by fred_test.sh:57:cpuinfo_test()|
|1106_005308.701|TRACE|CMD=cpu_info_check fred|
|1106_005308.709|TRACE|/proc/cpuinfo contain 'fred'|
	
$ sudo ./fred_test.sh -t lkgs
|1106_005314.921|TRACE|do_cmd() is called by fred_test.sh:52:lkgs_cpuid_test()|
|1106_005314.924|TRACE|CMD=cpuid_check 7 0 1 0 a 18|
6 parameters, eax=7
cpuid(eax=00000007, ebx=00000000, ecx=00000001, edx=00000000)
cpuid(&eax=0x7ffc4bb89d68, &ebx=0x7ffc4bb89d6c, &ecx=0x7ffc4bb89d70, &edx=0x7ffc4bb89d74)
After native_cpuid:
out:  eax=4c9e09d7, ebx=00000001, ecx=00000023,  edx=0184d430
cpuid(&eax=0x7ffc4bb89d68, &ebx=0x7ffc4bb89d6c, &ecx=0x7ffc4bb89d70, &edx=0x7ffc4bb89d74)
output:
  eax=4c9e09d7    || Binary: 0100 1100 1001 1110 0000 1001 1101 0111
  ebx=00000001    || Binary: 0000 0000 0000 0000 0000 0000 0000 0001
  ecx=00000023    || Binary: 0000 0000 0000 0000 0000 0000 0010 0011
  edx=0184d430    || Binary: 0000 0001 1000 0100 1101 0100 0011 0000
Now check cpuid eax, bit 18
Start with 0, pass: bit set 1, fail: bit set 0
Order bit:13, invert order:18, bit:1, pass!
    Done! Return:0.

xinli-intel and others added 30 commits November 6, 2025 17:39
commit a4cb5ec upstream.

WRMSRNS is an instruction that behaves exactly like WRMSR, with
the only difference being that it is not a serializing instruction
by default. Under certain conditions, WRMSRNS may replace WRMSR to
improve performance.

Add its CPU feature bit, opcode to the x86 opcode map, and an
always inline API __wrmsrns() to embed WRMSRNS into the code.

Intel-SIG: commit a4cb5ec x86/cpufeatures,opcode,msr: Add the
WRMSRNS instruction support
Backport FRED support.

Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Tested-by: Shan Kang <[email protected]>
Acked-by: Masami Hiramatsu (Google) <[email protected]>
Acked-by: Borislav Petkov (AMD) <[email protected]>
Link: https://lore.kernel.org/r/[email protected]

(cherry picked from commit a4cb5ec)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 3167b37 upstream.

idtentry_sysvec is really just DECLARE_IDTENTRY defined in
<asm/idtentry.h>, no need to define it separately.

Intel-SIG: commit 3167b37 x86/entry: Remove idtentry_sysvec
from entry_{32,64}.S
Backport FRED support.

Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]

(cherry picked from commit 3167b37)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 8df7193 upstream.

Intel VT-x classifies events into eight different types, which is inherited
by FRED for event identification. As such, event types becomes a common x86
concept, and should be defined in a common x86 header.

Add event type macros to <asm/trapnr.h>, and use them in <asm/vmx.h>.

Intel-SIG: commit 8df7193 x86/trapnr: Add event type macros to
<asm/trapnr.h>
Backport FRED support.

Suggested-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]

(cherry picked from commit 8df7193)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 51383e7 upstream.

Briefly introduce FRED, and its advantages compared to IDT.

Intel-SIG: commit 51383e7 Documentation/x86/64: Add
documentation for FRED
Backport FRED support.

Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Reviewed-by: Bagas Sanjaya <[email protected]>
Link: https://lore.kernel.org/r/[email protected]

(cherry picked from commit 51383e7)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 2cce959 upstream.

Add the configuration option CONFIG_X86_FRED to enable FRED.

Intel-SIG: commit 2cce959 x86/fred: Add Kconfig option
for FRED (CONFIG_X86_FRED)
Backport FRED support.

Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]

(cherry picked from commit 2cce959)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 51c158f upstream.

Any FRED enabled CPU will always have the following features as its
baseline:

  1) LKGS, load attributes of the GS segment but the base address into
     the IA32_KERNEL_GS_BASE MSR instead of the GS segment’s descriptor
     cache.

  2) WRMSRNS, non-serializing WRMSR for faster MSR writes.

Intel-SIG: commit 51c158f x86/cpufeatures: Add the CPU feature bit
for FRED
Backport FRED support.

Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]

(cherry picked from commit 51c158f)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit e554a8c upstream.

Add CONFIG_X86_FRED to <asm/disabled-features.h> to make
cpu_feature_enabled() work correctly with FRED.

Intel-SIG: commit e554a8c x86/fred: Disable FRED support
if CONFIG_X86_FRED is disabled
Backport FRED support.

Originally-by: Megha Dey <[email protected]>
Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]

(cherry picked from commit e554a8c)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 3810da1 upstream.

Let command line option "fred" accept multiple options to make it
easier to tweak its behavior.

Currently, two options 'on' and 'off' are allowed, and the default
behavior is to disable FRED. To enable FRED, append "fred=on" to the
kernel command line.

  [ bp: Use cpu_feature_enabled(), touch ups. ]

Intel-SIG: commit 3810da1 x86/fred: Add a fred= cmdline param
Backport FRED support.

Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit 3810da1)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 0115f8b upstream.

ERETU returns from an event handler while making a transition to ring 3,
and ERETS returns from an event handler while staying in ring 0.

Add instruction opcodes used by ERET[US] to the x86 opcode map; opcode
numbers are per FRED spec v5.0.

Intel-SIG: commit 0115f8b x86/opcode: Add ERET[US] instructions
to the x86 opcode map
Backport FRED support.

Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Reviewed-by: Masami Hiramatsu (Google) <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit 0115f8b)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit cd19bab upstream.

Update the objtool decoder to know about the ERET[US] instructions
(type INSN_CONTEXT_SWITCH).

Intel-SIG: commit cd19bab x86/objtool: Teach objtool about ERET[US]
Backport FRED support.

Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit cd19bab)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit ff45746 upstream.

Add X86_CR4_FRED macro for the FRED bit in %cr4. This bit must not be
changed after initialization, so add it to the pinned CR4 bits.

Intel-SIG: commit ff45746 x86/cpu: Add X86_CR4_FRED macro
Backport FRED support.

Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit ff45746)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit cd6df3f upstream.

Add MSR numbers for the FRED configuration registers per FRED spec 5.0.
Intel-SIG: commit cd6df3f x86/cpu: Add MSR numbers for FRED
configuration
Backport FRED support.

Originally-by: Megha Dey <[email protected]>
Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit cd6df3f)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 32b09c2 upstream.

Add a header file for FRED prototypes and definitions.

Intel-SIG: commit 32b09c2 x86/fred: Add a new header file
for FRED definitions
Backport FRED support.

Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit 32b09c2)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 65c9cc9 upstream.

When using FRED, reserve space at the top of the stack frame, just
like i386 does.
Intel-SIG: commit 65c9cc9 x86/fred: Reserve space for the
FRED stack frame
Backport FRED support.

Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit 65c9cc9)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 9356c4b upstream.

MSR_IA32_FRED_RSP0 is used during ring 3 event delivery, and needs to
be updated to point to the top of next task stack during task switch.

Intel-SIG: commit 9356c4b x86/fred: Update MSR_IA32_FRED_RSP0
during task switch
Backport FRED support.

Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit 9356c4b)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 09794f6 upstream.

SWAPGS is no longer needed thus NOT allowed with FRED because FRED
transitions ensure that an operating system can _always_ operate
with its own GS base address:

  - For events that occur in ring 3, FRED event delivery swaps the GS
    base address with the IA32_KERNEL_GS_BASE MSR.

  - ERETU (the FRED transition that returns to ring 3) also swaps the
    GS base address with the IA32_KERNEL_GS_BASE MSR.

And the operating system can still setup the GS segment for a user
thread without the need of loading a user thread GS with:

  - Using LKGS, available with FRED, to modify other attributes of the
    GS segment without compromising its ability always to operate with
    its own GS base address.

  - Accessing the GS segment base address for a user thread as before
    using RDMSR or WRMSR on the IA32_KERNEL_GS_BASE MSR.

Note, LKGS loads the GS base address into the IA32_KERNEL_GS_BASE MSR
instead of the GS segment's descriptor cache. As such, the operating
system never changes its runtime GS base address.

Intel-SIG: commit 09794f6 x86/fred: Disallow the swapgs
instruction when FRED is enabled
Backport FRED support.

Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit 09794f6)
Signed-off-by: Ethan Zhao <[email protected]>
commit df88387 upstream.

Because FRED always restores the full value of %rsp, ESPFIX is
no longer needed when it's enabled.
Intel-SIG: commit df88387 x86/fred: No ESPFIX needed when
FRED is enabled
Backport FRED support.

Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit df88387)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit ad41a14 upstream.

Entering a new task is logically speaking a return from a system call
(exec, fork, clone, etc.). As such, if ptrace enables single stepping
a single step exception should be allowed to trigger immediately upon
entering user space. This is not optional.

NMI should *never* be disabled in user space. As such, this is an
optional, opportunistic way to catch errors.

Allow single-step trap and NMI when starting a new task, thus once
the new task enters user space, single-step trap and NMI are both
enabled immediately.

Intel-SIG: commit ad41a14 x86/fred: Allow single-step trap and
NMI when starting a new task
Backport FRED support.

Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit ad41a14)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 58c80cc upstream.

On a FRED system, the faulting address (CR2) is passed on the stack,
to avoid the problem of transient state.  Thus the page fault address
is read from the FRED stack frame instead of CR2 when FRED is enabled.

Intel-SIG: commit 58c80cc x86/fred: Make exc_page_fault() work
for FRED
Backport FRED support.

Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit 58c80cc)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 99fcc96 upstream.

When occurred on different ring level, i.e., from user or kernel context,
stack, while kernel #DB on a dedicated stack. This is exactly how FRED
event delivery invokes an exception handler: ring 3 event on level 0
stack, i.e., current task stack; ring 0 event on the #DB dedicated stack
specified in the IA32_FRED_STKLVLS MSR. So unlike IDT, the FRED debug
exception entry stub doesn't do stack switch.

On a FRED system, the debug trap status information (DR6) is passed on
the stack, to avoid the problem of transient state. Furthermore, FRED
transitions avoid a lot of ugly corner cases the handling of which can,
and should be, skipped.

The FRED debug trap status information saved on the stack differs from
DR6 in both stickiness and polarity; it is exactly in the format which
debug_read_clear_dr6() returns for the IDT entry points.

Intel-SIG: commit 99fcc96 x86/fred: Add a debug fault entry stub
for FRED
Backport FRED support.

Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit 99fcc96)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit f8b8ee4 upstream.

On a FRED system, NMIs nest both with themselves and faults, transient
information is saved into the stack frame, and NMI unblocking only
happens when the stack frame indicates that so should happen.

Thus, the NMI entry stub for FRED is really quite small...

Intel-SIG: commit f8b8ee4 x86/fred: Add a NMI entry stub for FRED
Backport FRED support.

Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit f8b8ee4)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit ffa4901 upstream.

Like #DB, when occurred on different ring level, i.e., from user or kernel
context, #MCE needs to be handled on different stack: User #MCE on current
task stack, while kernel #MCE on a dedicated stack.

This is exactly how FRED event delivery invokes an exception handler: ring
3 event on level 0 stack, i.e., current task stack; ring 0 event on the
the FRED machine check entry stub doesn't do stack switch.

Intel-SIG: commit ffa4901 x86/fred: Add a machine check entry stub
for FRED
Backport FRED support.

Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit ffa4901)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 370dcd5 upstream.

To limit the IA32 exposure on 64bit kernels while keeping the
flexibility for the user to enable it when required, the compile time
enable/disable via CONFIG_IA32_EMULATION is not good enough and will
be complemented with a kernel command line option.

Right now entry_SYSCALL32_ignore() is only compiled when
CONFIG_IA32_EMULATION=n, but boot-time enable- / disablement obviously
requires it to be unconditionally available.

Remove the #ifndef CONFIG_IA32_EMULATION guard.

Intel-SIG: commit 370dcd5 x86/entry: Compile entry_SYSCALL32_ignore()
unconditionally
Backport FRED support.

Signed-off-by: Nikolay Borisov <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lore.kernel.org/r/[email protected]

(cherry picked from commit 370dcd5)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 6138228 upstream.

Another major aspect of supporting running of 32bit processes is the
ability to access 32bit syscalls. Such syscalls can be invoked by
using the legacy int 0x80 handler and  sysenter/syscall instructions.

If IA32 emulation is disabled ensure that each of those 3 distinct
mechanisms are also disabled. For int 0x80 a #GP exception would be
generated since the respective descriptor is not going to be loaded at
all. Invoking sysenter will also result in a #GP since IA32_SYSENTER_CS
contains an invalid segment. Finally, syscall instruction cannot really
be disabled so it's configured to execute a minimal handler.

Intel-SIG: commit 6138228 x86/entry: Make IA32 syscalls'
availability depend on ia32_enabled()
Backport FRED support.

Signed-off-by: Nikolay Borisov <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lore.kernel.org/r/[email protected]

(cherry picked from commit 6138228)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 14619d9 upstream.

The code to actually handle kernel and event entry/exit using
FRED. It is split up into two files thus:

 - entry_64_fred.S contains the actual entrypoints and exit code, and
   saves and restores registers.

 - entry_fred.c contains the two-level event dispatch code for FRED.
   The first-level dispatch is on the event type, and the second-level
   is on the event vector.

  [ bp: Fold in an allmodconfig clang build fix:
    https://lore.kernel.org/r/[email protected]
    and a CONFIG_IA32_EMULATION=n build fix:
    https://lore.kernel.org/r/[email protected]]

Intel-SIG: commit 14619d9 x86/fred: FRED entry/exit and dispatch
code
Backport FRED support.

Suggested-by: Thomas Gleixner <[email protected]>
Originally-by: Megha Dey <[email protected]>
Co-developed-by: Xin Li <[email protected]>
Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit 14619d9)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 8f4a29b upstream.

Add sysvec_install() to install a system interrupt handler into the IDT
or the FRED system interrupt handler table.

Intel-SIG: commit 8f4a29b x86/traps: Add sysvec_install() to
install a system interrupt handler
Backport FRED support.

Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit 8f4a29b)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
… is enabled

commit 51ef2a4 upstream.

Let ret_from_fork_asm() jmp to asm_fred_exit_user when FRED is enabled,
otherwise the existing IDT code is chosen.

Intel-SIG: commit 51ef2a4 x86/fred: Let ret_from_fork_asm() jmp to
asm_fred_exit_user when FRED is enabled
Backport FRED support.

Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit 51ef2a4)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 5105e76 upstream.

If the stack frame contains an invalid user context (e.g. due to invalid SS,
a non-canonical RIP, etc.) the ERETU instruction will trap (#SS or #GP).

From a Linux point of view, this really should be considered a user space
failure, so use the standard fault fixup mechanism to intercept the fault,
fix up the exception frame, and redirect execution to fred_entrypoint_user.
The end result is that it appears just as if the hardware had taken the
exception immediately after completing the transition to user space.

Intel-SIG: commit 5105e76 x86/fred: Fixup fault on ERETU by jumping to
fred_entrypoint_user
Backport FRED support.

Suggested-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit 5105e76)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
… entry code

commit 2333f3c upstream.

PUSH_AND_CLEAR_REGS could be used besides actual entry code; in that case
%rbp shouldn't be cleared (otherwise the frame pointer is destroyed) and
UNWIND_HINT shouldn't be added.

Intel-SIG: commit 2333f3c x86/entry/calling: Allow PUSH_AND_CLEAR_REGS
being used beyond actual entry code
Backport FRED support.

Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit 2333f3c)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 2e67035 upstream.

In IRQ/NMI induced VM exits, KVM VMX needs to execute the respective
handlers, which requires the software to create a FRED stack frame,
and use it to invoke the handlers. Add fred_irq_entry_from_kvm() for
this job.

Export fred_entry_from_kvm() because VMX can be compiled as a module.

Intel-SIG: commit 2e67035 x86/entry: Add fred_entry_from_kvm()
for VMX to handle IRQ/NMI
Backport FRED support.

Suggested-by: Sean Christopherson <[email protected]>
Suggested-by: Thomas Gleixner <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit 2e67035)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
xinli-intel and others added 17 commits November 6, 2025 17:39
commit 70d0fe5 upstream.

When FRED is enabled, call fred_entry_from_kvm() to handle IRQ/NMI in
IRQ/NMI induced VM exits.

Intel-SIG: commit 70d0fe5 KVM: VMX: Call fred_entry_from_kvm()
for IRQ/NMI handling
Backport FRED support.

Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Acked-by: Paolo Bonzini <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit 70d0fe5)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 530dce2 upstream.

Because FRED uses the ring 3 FRED entrypoint for SYSCALL and SYSENTER and
ERETU is the only legit instruction to return to ring 3, there is NO need
to setup SYSCALL and SYSENTER MSRs for FRED, except the IA32_STAR MSR.

Split IDT syscall setup code into idt_syscall_init() to make it easy to
skip syscall setup code when FRED is enabled.

Intel-SIG: commit 530dce2 x86/syscall: Split IDT syscall setup code
into idt_syscall_init()
Backport FRED support.

Suggested-by: Thomas Gleixner <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit 530dce2)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit cdd99dd upstream.

Add cpu_init_fred_exceptions() to:
  - Set FRED entrypoints for events happening in ring 0 and 3.
  - Specify the stack level for IRQs occurred ring 0.
  - Specify dedicated event stacks for #DB/NMI/#MCE/#DF.
  - Enable FRED and invalidtes IDT.
  - Force 32-bit system calls to use "int $0x80" only.

Add fred_complete_exception_setup() to:
  - Initialize system_vectors as done for IDT systems.
  - Set unused sysvec_table entries to fred_handle_spurious_interrupt().
Intel-SIG: commit cdd99dd x86/fred: Add FRED initialization
functions
Backport FRED support.

Co-developed-by: Xin Li <[email protected]>
Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit cdd99dd)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 208d8c7 upstream.

Let cpu_init_exception_handling() call cpu_init_fred_exceptions() to
initialize FRED. However if FRED is unavailable or disabled, it falls
back to set up TSS IST and initialize IDT.

Intel-SIG: commit 208d8c7 x86/fred: Invoke FRED initialization
code to enable FRED
Backport FRED support.

Co-developed-by: Xin Li <[email protected]>
Signed-off-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Tested-by: Shan Kang <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit 208d8c7)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
…ng to inline properly

commit cba9ff3 upstream.

Change array_index_mask_nospec() to __always_inline because "inline" is
broken as https://www.kernel.org/doc/local/inline.html.

Intel-SIG: commit cba9ff3 x86/fred: Fix a build warning with
allmodconfig due to 'inline' failing to inline properly
Backport FRED support.

Fixes: 6786137bf8fd ("x86/fred: FRED entry/exit and dispatch code")
Reported-by: Stephen Rothwell <[email protected]>
Signed-off-by: Xin Li (Intel) <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit cba9ff3)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit e138419 upstream.

Add H. Peter Anvin and myself as FRED maintainers.

Intel-SIG: commit e138419 MAINTAINERS: Add a maintainer entry
for FRED
Backport FRED support.

Signed-off-by: Xin Li (Intel) <[email protected]>
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Acked-by: H. Peter Anvin (Intel) <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit e138419)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit c416b5b upstream.

As TOP_OF_KERNEL_STACK_PADDING was defined as 0 on x86_64, it went
unnoticed that the initialization of the .sp field in INIT_THREAD and some
calculations in the low level startup code do not take the padding into
account.

FRED enabled kernels require a 16 byte padding, which means that the init
task initialization and the low level startup code use the wrong stack
offset.

Subtract TOP_OF_KERNEL_STACK_PADDING in all affected places to adjust for
this.

Intel-SIG: commit c416b5b x86/fred: Fix init_task thread stack pointer
initialization
Backport FRED support.

Fixes: 65c9cc9 ("x86/fred: Reserve space for the FRED stack frame")
Fixes: 3adee77 ("x86/smpboot: Remove initial_stack on 64-bit")
Reported-by: kernel test robot <[email protected]>
Signed-off-by: Xin Li (Intel) <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Closes: https://lore.kernel.org/oe-lkp/[email protected]
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit c416b5b)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 989b5cf upstream.

Depending on whether FRED is enabled, sysvec_install() installs a system
interrupt handler into either into FRED's system vector dispatch table or
into the IDT.

However FRED can be disabled later in trap_init(), after sysvec_install()
has been invoked already; e.g., the HYPERVISOR_CALLBACK_VECTOR handler is
registered with sysvec_install() in kvm_guest_init(), which is called in
setup_arch() but way before trap_init().

IOW, there is a gap between FRED is available and available but disabled.
As a result, when FRED is available but disabled, early sysvec_install()
invocations fail to install the IDT handler resulting in spurious
interrupts.

Fix it by parsing cmdline param "fred=" in cpu_parse_early_param() to
ensure that FRED is disabled before the first sysvec_install() incovations.
Intel-SIG: commit 989b5cf x86/fred: Parse cmdline param "fred=" in
cpu_parse_early_param()
Backport FRED support.

Fixes: 3810da1 ("x86/fred: Add a fred= cmdline param")
Reported-by: Hou Wenlong <[email protected]>
Suggested-by: Thomas Gleixner <[email protected]>
Signed-off-by: Xin Li (Intel) <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lore.kernel.org/all/[email protected]

(cherry picked from commit 989b5cf)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 73270c1 upstream.

To enable FRED earlier, move the RSP initialization out of
cpu_init_fred_exceptions() into cpu_init_fred_rsps().

This is required as the FRED RSP initialization depends on the availability
of the CPU entry areas which are set up late in trap_init(),

No functional change intended. Marked with Fixes as it's a depedency for
the real fix.

Intel-SIG: commit 73270c1 x86/fred: Move FRED RSP initialization into
separate function
Backport FRED support.

Fixes: 14619d9 ("x86/fred: FRED entry/exit and dispatch code")
Signed-off-by: Xin Li (Intel) <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lore.kernel.org/all/[email protected]
(cherry picked from commit 73270c1)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit a97756c upstream.

On 64-bit init_mem_mapping() relies on the minimal page fault handler
provided by the early IDT mechanism. The real page fault handler is
installed right afterwards into the IDT.

This is problematic on CPUs which have X86_FEATURE_FRED set because the
real page fault handler retrieves the faulting address from the FRED
exception stack frame and not from CR2, but that does obviously not work
when FRED is not yet enabled in the CPU.

To prevent this enable FRED right after init_mem_mapping() without
interrupt stacks. Those are enabled later in trap_init() after the CPU
entry area is set up.

[ tglx: Encapsulate the FRED details ]

Intel-SIG: commit a97756c x86/fred: Enable FRED right after
init_mem_mapping()
Backport FRED support.

Fixes: 14619d9 ("x86/fred: FRED entry/exit and dispatch code")
Reported-by: Hou Wenlong <[email protected]>
Suggested-by: Thomas Gleixner <[email protected]>
Signed-off-by: Xin Li (Intel) <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lore.kernel.org/all/[email protected]
(cherry picked from commit a97756c)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 23edbd2ca5fb4c78ac4a5644511c63895fd1c57 upstream.

SS is initialized to NULL during boot time and not explicitly set to
__KERNEL_DS.

With FRED enabled, if a kernel event is delivered before a CPU goes to
user level for the first time, its SS is NULL thus NULL is pushed into
the SS field of the FRED stack frame.  But before ERETS is executed,
the CPU may context switch to another task and go to user level.  Then
when the CPU comes back to kernel mode, SS is changed to __KERNEL_DS.
Later when ERETS is executed to return from the kernel event handler,
a #GP fault is generated because SS doesn't match the SS saved in the
FRED stack frame.

Initialize SS to __KERNEL_DS when enabling FRED to prevent that.

Note, IRET doesn't check if SS matches the SS saved in its stack frame,
thus IDT doesn't have this problem.  For IDT it doesn't matter whether
SS is set to __KERNEL_DS or not, because it's set to NULL upon interrupt
or exception delivery and __KERNEL_DS upon SYSCALL.  Thus it's pointless
to initialize SS for IDT.

Intel-SIG: commit 723edbd x86/fred: Set SS to __KERNEL_DS when
enabling FRED
Backport FRED support.

Signed-off-by: Xin Li (Intel) <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lore.kernel.org/all/[email protected]

(cherry picked from commit 723edbd)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit 0dfac6f upstream.

In most cases, ti_work values passed to arch_exit_to_user_mode_prepare()
are zeros, e.g., 99% in kernel build tests.  So an obvious optimization is
to test ti_work for zero before processing individual bits in it.

Omit the optimization when FPU debugging is enabled, otherwise the
FPU consistency check is never executed.

Intel 0day tests did not find a perfermance regression with this change.

Intel-SIG: commit 0dfac6f x86/entry: Test ti_work for zero before
processing individual bits
Backport FRED support.

Suggested-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li (Intel) <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lore.kernel.org/all/[email protected]

(cherry picked from commit 0dfac6f)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
…nism

commit efe5088 upstream.

Per the discussion about FRED MSR writes with WRMSRNS instruction [1],
use the alternatives mechanism to choose WRMSRNS when it's available,
otherwise fallback to WRMSR.

Remove the dependency on X86_FEATURE_WRMSRNS as WRMSRNS is no longer
dependent on FRED.

[1] https://lore.kernel.org/lkml/[email protected]/

Use DS prefix to pad WRMSR instead of a NOP. The prefix is ignored. At
least that's the current information from the hardware folks.

Intel-SIG: commit efe5088 x86/msr: Switch between WRMSRNS and WRMSR
with the alternatives mechanism
Backport FRED support.

Signed-off-by: Andrew Cooper <[email protected]>
Signed-off-by: Xin Li (Intel) <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lore.kernel.org/all/[email protected]

(cherry picked from commit efe5088)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
…itch

commit fe85ee3 upstream.

The FRED RSP0 MSR points to the top of the kernel stack for user level
event delivery. As this is the task stack it needs to be updated when a
task is scheduled in.

The update is done at context switch. That means it's also done when
switching to kernel threads, which is pointless as those never go out to
user space. For KVM threads this means there are two writes to FRED_RSP0 as
KVM has to switch to the guest value before VMENTER.

Defer the update to the exit to user space path and cache the per CPU
FRED_RSP0 value, so redundant writes can be avoided.

Provide fred_sync_rsp0() for KVM to keep the cache in sync with the actual
MSR value after returning from guest to host mode.

[ tglx: Massage change log ]

Intel-SIG: commit fe85ee3 x86/entry: Set FRED RSP0 on return to
userspace instead of context switch
Backport FRED support.

Suggested-by: Sean Christopherson <[email protected]>
Suggested-by: Thomas Gleixner <[email protected]>
Signed-off-by: Xin Li (Intel) <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lore.kernel.org/all/[email protected]
(cherry picked from commit fe85ee3)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit de31b3cd706347044e1a57d68c3a683d58e8cca4 upstream.

The FRED RSP0 MSR is only used for delivering events when running
userspace.  Linux 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 top of
current task 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
top of 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.

Fix the bug through resynchronizing the FRED RSP0 MSR with its
per-CPU cache in cpu_init_fred_exceptions().

Intel-SIG: commit de31b3cd7063 x86/fred: Fix the FRED RSP0 MSR out
of sync with its per-CPU cache
Backport FRED support.

Fixes: fe85ee3 ("x86/entry: Set FRED RSP0 on return to userspace instead of context switch")
Signed-off-by: Xin Li (Intel) <[email protected]>
Signed-off-by: Dave Hansen <[email protected]>
Acked-by: Dave Hansen <[email protected]>
Cc:[email protected]
Link: https://lore.kernel.org/all/20250110174639.1250829-1-xin%40zytor.com
(cherry picked from commit de31b3cd706347044e1a57d68c3a683d58e8cca4)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
commit e5f1e8af9c9e151ecd665f6d2e36fb25fec3b110 upstream.

Upon a wakeup from S4, the restore kernel starts and initializes the
FRED MSRs as needed from its perspective.  It then loads a hibernation
image, including the image kernel, and attempts to load image pages
directly into their original page frames used before hibernation unless
those frames are currently in use.  Once all pages are moved to their
original locations, it jumps to a "trampoline" page in the image kernel.

At this point, the image kernel takes control, but the FRED MSRs still
contain values set by the restore kernel, which may differ from those
set by the image kernel before hibernation.  Therefore, the image kernel
must ensure the FRED MSRs have the same values as before hibernation.
Since these values depend only on the location of the kernel text and
data, they can be recomputed from scratch.

Intel-SIG: commit e5f1e8af9c9e1 x86/fred: Fix system hang during S4
 resume with FRED enabled
Backport FRED support.

Reported-by: Xi Pardee <[email protected]>
Reported-by: Todd Brandt <[email protected]>
Tested-by: Todd Brandt <[email protected]>
Suggested-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li (Intel) <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
Reviewed-by: Rafael J. Wysocki <[email protected]>
Reviewed-by: H. Peter Anvin (Intel) <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Cc: Brian Gerst <[email protected]>
Cc: Juergen Gross <[email protected]>
Cc: Linus Torvalds <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
(cherry picked from commit e5f1e8af9c9e151ecd665f6d2e36fb25fec3b110)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
…rn from SIGTRAP handler

commit e34dbbc85d64af59176fe59fad7b4122f4330fe2 upstream.

Clear the software event flag in the augmented SS to prevent immediate
repeat of single step trap on return from SIGTRAP handler if the trap
flag (TF) is set without an external debugger attached.

Following is a typical single-stepping flow for a user process:

1) The user process is prepared for single-stepping by setting
   RFLAGS.TF = 1.
2) When any instruction in user space completes, a #DB is triggered.
3) The kernel handles the #DB and returns to user space, invoking the
   SIGTRAP handler with RFLAGS.TF = 0.
4) After the SIGTRAP handler finishes, the user process performs a
   sigreturn syscall, restoring the original state, including
   RFLAGS.TF = 1.
5) Goto step 2.

According to the FRED specification:

A) Bit 17 in the augmented SS is designated as the software event
   flag, which is set to 1 for FRED event delivery of SYSCALL,
   SYSENTER, or INT n.
B) If bit 17 of the augmented SS is 1 and ERETU would result in
   RFLAGS.TF = 1, a single-step trap will be pending upon completion
   of ERETU.

In step 4) above, the software event flag is set upon the sigreturn
syscall, and its corresponding ERETU would restore RFLAGS.TF = 1.
This combination causes a pending single-step trap upon completion of
ERETU.  Therefore, another #DB is triggered before any user space
instruction is executed, which leads to an infinite loop in which the
SIGTRAP handler keeps being invoked on the same user space IP.

Intel-SIG: commit e34dbbc85d64a x86/fred/signal: Prevent immediate repeat
 of single step trap on return from SIGTRAP handler
Backport FRED support.

Fixes: 14619d9 ("x86/fred: FRED entry/exit and dispatch code")
Suggested-by: H. Peter Anvin (Intel) <[email protected]>
Signed-off-by: Xin Li (Intel) <[email protected]>
Signed-off-by: Dave Hansen <[email protected]>
Tested-by: Sohil Mehta <[email protected]>
Cc:[email protected]
Link: https://lore.kernel.org/all/20250609084054.2083189-2-xin%40zytor.com
(cherry picked from commit e34dbbc85d64af59176fe59fad7b4122f4330fe2)
[ Ethan Zhao: amend commit log ]
Signed-off-by: Ethan Zhao <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants