Message ID | 20230410081438.1750-27-xin3.li@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | x86: enable FRED for x86-64 | expand |
On Mon, Apr 10 2023 at 01:14, Xin Li wrote: > Allow single-step trap and NMI when starting a new thread, thus once > the new thread returns to ring3, single-step trap and NMI are both > enabled immediately. > > High-order 48 bits above the lowest 16 bit CS are discarded by the > legacy IRET instruction, thus can be set unconditionally, even when > FRED is not enabled. I assume this has been validated to be true on _all_ CPU incarnations of _all_ x86 vendors. If so, then please document it. If not, then go back to the drawing board. Thanks, tglx
On Mon, Jun 05 2023 at 15:50, Thomas Gleixner wrote: > On Mon, Apr 10 2023 at 01:14, Xin Li wrote: >> Allow single-step trap and NMI when starting a new thread, thus once >> the new thread returns to ring3, single-step trap and NMI are both >> enabled immediately. >> >> High-order 48 bits above the lowest 16 bit CS are discarded by the >> legacy IRET instruction, thus can be set unconditionally, even when >> FRED is not enabled. > > I assume this has been validated to be true on _all_ CPU incarnations of > _all_ x86 vendors. It's also ensured that VMMs do not get confused by this, right? > If so, then please document it. If not, then go back to the drawing > board. > > Thanks, > > tglx
diff --git a/arch/x86/include/asm/fred.h b/arch/x86/include/asm/fred.h index c5fbc4f18059..f7caf3b2f3f7 100644 --- a/arch/x86/include/asm/fred.h +++ b/arch/x86/include/asm/fred.h @@ -70,6 +70,14 @@ */ #define FRED_DF_STACK_LEVEL 3 +/* + * High-order 48 bits above the lowest 16 bit CS are discarded by the + * legacy IRET instruction, thus can be set unconditionally, even when + * FRED is not enabled. + */ +#define CSX_PROCESS_START \ + (FRED_CSX_ENABLE_NMI | FRED_CSX_ALLOW_SINGLE_STEP) + #ifndef __ASSEMBLY__ #include <linux/kernel.h> @@ -133,6 +141,9 @@ void fred_setup_apic(void); #else #define cpu_init_fred_exceptions() BUG() #define fred_setup_apic() BUG() + +#define CSX_PROCESS_START 0 + #endif /* CONFIG_X86_FRED */ #endif /* ASM_X86_FRED_H */ diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 2bea86073646..c732d9dbff3a 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -55,6 +55,7 @@ #include <asm/resctrl.h> #include <asm/unistd.h> #include <asm/fsgsbase.h> +#include <asm/fred.h> #ifdef CONFIG_IA32_EMULATION /* Not included via unistd.h */ #include <asm/unistd_32_ia32.h> @@ -506,7 +507,7 @@ void x86_gsbase_write_task(struct task_struct *task, unsigned long gsbase) static void start_thread_common(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp, - unsigned int _cs, unsigned int _ss, unsigned int _ds) + u16 _cs, u16 _ss, u16 _ds) { WARN_ON_ONCE(regs != current_pt_regs()); @@ -521,11 +522,11 @@ start_thread_common(struct pt_regs *regs, unsigned long new_ip, loadsegment(ds, _ds); load_gs_index(0); - regs->ip = new_ip; - regs->sp = new_sp; - regs->cs = _cs; - regs->ss = _ss; - regs->flags = X86_EFLAGS_IF; + regs->ip = new_ip; + regs->sp = new_sp; + regs->csx = _cs | CSX_PROCESS_START; + regs->ssx = _ss; + regs->flags = X86_EFLAGS_IF | X86_EFLAGS_FIXED; } void