Skip to content

Commit 3620976

Browse files
committed
x86/traps: Cleanup do_general_protection()
Hoist the user_mode() case up because it is less code and can be dealt with up-front like the other special cases UMIP and vm86. This saves an indentation level for the kernel-mode #GP case and allows to "unfold" the code more so that it is more readable. No functional changes. Signed-off-by: Borislav Petkov <[email protected]> Cc: Jann Horn <[email protected]> Cc: [email protected]
1 parent 2f004ee commit 3620976

File tree

1 file changed

+40
-39
lines changed

1 file changed

+40
-39
lines changed

arch/x86/kernel/traps.c

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,10 @@ static enum kernel_gp_hint get_kernel_gp_address(struct pt_regs *regs,
567567
dotraplinkage void do_general_protection(struct pt_regs *regs, long error_code)
568568
{
569569
char desc[sizeof(GPFSTR) + 50 + 2*sizeof(unsigned long) + 1] = GPFSTR;
570+
enum kernel_gp_hint hint = GP_NO_HINT;
570571
struct task_struct *tsk;
572+
unsigned long gp_addr;
573+
int ret;
571574

572575
RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
573576
cond_local_irq_enable(regs);
@@ -584,58 +587,56 @@ dotraplinkage void do_general_protection(struct pt_regs *regs, long error_code)
584587
}
585588

586589
tsk = current;
587-
if (!user_mode(regs)) {
588-
enum kernel_gp_hint hint = GP_NO_HINT;
589-
unsigned long gp_addr;
590-
591-
if (fixup_exception(regs, X86_TRAP_GP, error_code, 0))
592-
return;
593590

591+
if (user_mode(regs)) {
594592
tsk->thread.error_code = error_code;
595593
tsk->thread.trap_nr = X86_TRAP_GP;
596594

597-
/*
598-
* To be potentially processing a kprobe fault and to
599-
* trust the result from kprobe_running(), we have to
600-
* be non-preemptible.
601-
*/
602-
if (!preemptible() && kprobe_running() &&
603-
kprobe_fault_handler(regs, X86_TRAP_GP))
604-
return;
595+
show_signal(tsk, SIGSEGV, "", desc, regs, error_code);
596+
force_sig(SIGSEGV);
605597

606-
if (notify_die(DIE_GPF, desc, regs, error_code,
607-
X86_TRAP_GP, SIGSEGV) == NOTIFY_STOP)
608-
return;
598+
return;
599+
}
609600

610-
if (error_code)
611-
snprintf(desc, sizeof(desc), "segment-related " GPFSTR);
612-
else
613-
hint = get_kernel_gp_address(regs, &gp_addr);
601+
if (fixup_exception(regs, X86_TRAP_GP, error_code, 0))
602+
return;
614603

615-
if (hint != GP_NO_HINT)
616-
snprintf(desc, sizeof(desc), GPFSTR ", %s 0x%lx",
617-
(hint == GP_NON_CANONICAL) ?
618-
"probably for non-canonical address" :
619-
"maybe for address",
620-
gp_addr);
604+
tsk->thread.error_code = error_code;
605+
tsk->thread.trap_nr = X86_TRAP_GP;
621606

622-
/*
623-
* KASAN is interested only in the non-canonical case, clear it
624-
* otherwise.
625-
*/
626-
if (hint != GP_NON_CANONICAL)
627-
gp_addr = 0;
607+
/*
608+
* To be potentially processing a kprobe fault and to trust the result
609+
* from kprobe_running(), we have to be non-preemptible.
610+
*/
611+
if (!preemptible() &&
612+
kprobe_running() &&
613+
kprobe_fault_handler(regs, X86_TRAP_GP))
614+
return;
628615

629-
die_addr(desc, regs, error_code, gp_addr);
616+
ret = notify_die(DIE_GPF, desc, regs, error_code, X86_TRAP_GP, SIGSEGV);
617+
if (ret == NOTIFY_STOP)
630618
return;
631-
}
632619

633-
tsk->thread.error_code = error_code;
634-
tsk->thread.trap_nr = X86_TRAP_GP;
620+
if (error_code)
621+
snprintf(desc, sizeof(desc), "segment-related " GPFSTR);
622+
else
623+
hint = get_kernel_gp_address(regs, &gp_addr);
624+
625+
if (hint != GP_NO_HINT)
626+
snprintf(desc, sizeof(desc), GPFSTR ", %s 0x%lx",
627+
(hint == GP_NON_CANONICAL) ? "probably for non-canonical address"
628+
: "maybe for address",
629+
gp_addr);
630+
631+
/*
632+
* KASAN is interested only in the non-canonical case, clear it
633+
* otherwise.
634+
*/
635+
if (hint != GP_NON_CANONICAL)
636+
gp_addr = 0;
635637

636-
show_signal(tsk, SIGSEGV, "", desc, regs, error_code);
638+
die_addr(desc, regs, error_code, gp_addr);
637639

638-
force_sig(SIGSEGV);
639640
}
640641
NOKPROBE_SYMBOL(do_general_protection);
641642

0 commit comments

Comments
 (0)