Commit 775acc82 authored by Kirill A. Shutemov's avatar Kirill A. Shutemov Committed by Dave Hansen

x86/traps: Refactor exc_general_protection()

TDX brings a new exception -- Virtualization Exception (#VE). Handling
of #VE structurally very similar to handling #GP.

Extract two helpers from exc_general_protection() that can be reused for
handling #VE.

No functional changes.
Suggested-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarKirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: default avatarDave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: default avatarDave Hansen <dave.hansen@linux.intel.com>
Link: https://lkml.kernel.org/r/20220405232939.73860-7-kirill.shutemov@linux.intel.com
parent 65fab5bc
...@@ -686,13 +686,40 @@ static bool try_fixup_enqcmd_gp(void) ...@@ -686,13 +686,40 @@ static bool try_fixup_enqcmd_gp(void)
#endif #endif
} }
static bool gp_try_fixup_and_notify(struct pt_regs *regs, int trapnr,
unsigned long error_code, const char *str)
{
if (fixup_exception(regs, trapnr, error_code, 0))
return true;
current->thread.error_code = error_code;
current->thread.trap_nr = trapnr;
/*
* To be potentially processing a kprobe fault and to trust the result
* from kprobe_running(), we have to be non-preemptible.
*/
if (!preemptible() && kprobe_running() &&
kprobe_fault_handler(regs, trapnr))
return true;
return notify_die(DIE_GPF, str, regs, error_code, trapnr, SIGSEGV) == NOTIFY_STOP;
}
static void gp_user_force_sig_segv(struct pt_regs *regs, int trapnr,
unsigned long error_code, const char *str)
{
current->thread.error_code = error_code;
current->thread.trap_nr = trapnr;
show_signal(current, SIGSEGV, "", str, regs, error_code);
force_sig(SIGSEGV);
}
DEFINE_IDTENTRY_ERRORCODE(exc_general_protection) DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
{ {
char desc[sizeof(GPFSTR) + 50 + 2*sizeof(unsigned long) + 1] = GPFSTR; char desc[sizeof(GPFSTR) + 50 + 2*sizeof(unsigned long) + 1] = GPFSTR;
enum kernel_gp_hint hint = GP_NO_HINT; enum kernel_gp_hint hint = GP_NO_HINT;
struct task_struct *tsk;
unsigned long gp_addr; unsigned long gp_addr;
int ret;
if (user_mode(regs) && try_fixup_enqcmd_gp()) if (user_mode(regs) && try_fixup_enqcmd_gp())
return; return;
...@@ -711,40 +738,18 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection) ...@@ -711,40 +738,18 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
return; return;
} }
tsk = current;
if (user_mode(regs)) { if (user_mode(regs)) {
if (fixup_iopl_exception(regs)) if (fixup_iopl_exception(regs))
goto exit; goto exit;
tsk->thread.error_code = error_code;
tsk->thread.trap_nr = X86_TRAP_GP;
if (fixup_vdso_exception(regs, X86_TRAP_GP, error_code, 0)) if (fixup_vdso_exception(regs, X86_TRAP_GP, error_code, 0))
goto exit; goto exit;
show_signal(tsk, SIGSEGV, "", desc, regs, error_code); gp_user_force_sig_segv(regs, X86_TRAP_GP, error_code, desc);
force_sig(SIGSEGV);
goto exit; goto exit;
} }
if (fixup_exception(regs, X86_TRAP_GP, error_code, 0)) if (gp_try_fixup_and_notify(regs, X86_TRAP_GP, error_code, desc))
goto exit;
tsk->thread.error_code = error_code;
tsk->thread.trap_nr = X86_TRAP_GP;
/*
* To be potentially processing a kprobe fault and to trust the result
* from kprobe_running(), we have to be non-preemptible.
*/
if (!preemptible() &&
kprobe_running() &&
kprobe_fault_handler(regs, X86_TRAP_GP))
goto exit;
ret = notify_die(DIE_GPF, desc, regs, error_code, X86_TRAP_GP, SIGSEGV);
if (ret == NOTIFY_STOP)
goto exit; goto exit;
if (error_code) if (error_code)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment