6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xin Li xin3.li@intel.com
[ Upstream commit 3c77bf02d0c03beb3efdf7a5b427fb2e1a76c265 ]
FRED defines additional information in the upper 48 bits of cs/ss fields. Therefore add the information definitions into the pt_regs structure.
Specifically introduce a new structure fred_ss to denote the FRED flags above SS selector, which avoids FRED_SSX_ macros and makes the code simpler and easier to read.
Suggested-by: Thomas Gleixner tglx@linutronix.de Originally-by: H. Peter Anvin (Intel) hpa@zytor.com Signed-off-by: Xin Li xin3.li@intel.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Tested-by: Shan Kang shan.kang@intel.com Link: https://lore.kernel.org/r/20231205105030.8698-15-xin3.li@intel.com Stable-dep-of: dc81e556f2a0 ("x86/fred: Clear WFE in missing-ENDBRANCH #CPs") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/include/asm/ptrace.h | 66 ++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 5 deletions(-)
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index b268cd2a2d01..5a83fbd9bc0b 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -56,6 +56,50 @@ struct pt_regs {
#else /* __i386__ */
+struct fred_cs { + /* CS selector */ + u64 cs : 16, + /* Stack level at event time */ + sl : 2, + /* IBT in WAIT_FOR_ENDBRANCH state */ + wfe : 1, + : 45; +}; + +struct fred_ss { + /* SS selector */ + u64 ss : 16, + /* STI state */ + sti : 1, + /* Set if syscall, sysenter or INT n */ + swevent : 1, + /* Event is NMI type */ + nmi : 1, + : 13, + /* Event vector */ + vector : 8, + : 8, + /* Event type */ + type : 4, + : 4, + /* Event was incident to enclave execution */ + enclave : 1, + /* CPU was in long mode */ + lm : 1, + /* + * Nested exception during FRED delivery, not set + * for #DF. + */ + nested : 1, + : 1, + /* + * The length of the instruction causing the event. + * Only set for INTO, INT1, INT3, INT n, SYSCALL + * and SYSENTER. 0 otherwise. + */ + insnlen : 4; +}; + struct pt_regs { /* * C ABI says these regs are callee-preserved. They aren't saved on @@ -85,6 +129,12 @@ struct pt_regs { * - the syscall number (syscall, sysenter, int80) * - error_code stored by the CPU on traps and exceptions * - the interrupt number for device interrupts + * + * A FRED stack frame starts here: + * 1) It _always_ includes an error code; + * + * 2) The return frame for ERET[US] starts here, but + * the content of orig_ax is ignored. */ unsigned long orig_ax;
@@ -92,24 +142,30 @@ struct pt_regs { unsigned long ip;
union { - /* The full 64-bit data slot containing CS */ - u64 csx; /* CS selector */ u16 cs; + /* The extended 64-bit data slot containing CS */ + u64 csx; + /* The FRED CS extension */ + struct fred_cs fred_cs; };
unsigned long flags; unsigned long sp;
union { - /* The full 64-bit data slot containing SS */ - u64 ssx; /* SS selector */ u16 ss; + /* The extended 64-bit data slot containing SS */ + u64 ssx; + /* The FRED SS extension */ + struct fred_ss fred_ss; };
/* - * Top of stack on IDT systems. + * Top of stack on IDT systems, while FRED systems have extra fields + * defined above for storing exception related information, e.g. CR2 or + * DR6. */ };