x86/fred: Allow single-step trap and NMI when starting a new task
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. Signed-off-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-21-xin3.li@intel.com
This commit is contained in:
parent
df8838737b
commit
ad41a14cc2
@ -56,6 +56,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>
|
||||
@ -528,7 +529,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());
|
||||
|
||||
@ -545,11 +546,36 @@ 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;
|
||||
regs->ssx = _ss;
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Paranoia: High-order 48 bits above the lowest 16 bit SS are
|
||||
* discarded by the legacy IRET instruction on all Intel, AMD,
|
||||
* and Cyrix/Centaur/VIA CPUs, thus can be set unconditionally,
|
||||
* even when FRED is not enabled. But we choose the safer side
|
||||
* to use these bits only when FRED is enabled.
|
||||
*/
|
||||
if (cpu_feature_enabled(X86_FEATURE_FRED)) {
|
||||
regs->fred_ss.swevent = true;
|
||||
regs->fred_ss.nmi = true;
|
||||
}
|
||||
|
||||
regs->flags = X86_EFLAGS_IF | X86_EFLAGS_FIXED;
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
x
Reference in New Issue
Block a user