x86, traps: introduce dotraplinkage
Mark the exception handlers with "dotraplinkage" to hide the calling convention differences between i386 and x86_64. Signed-off-by: Alexander van Heukelum <heukelum@fastmail.fm> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
committed by
Ingo Molnar
parent
ae82157b3d
commit
e407d62088
@@ -1243,7 +1243,7 @@ ENTRY(simd_coprocessor_error)
|
|||||||
END(simd_coprocessor_error)
|
END(simd_coprocessor_error)
|
||||||
|
|
||||||
ENTRY(device_not_available)
|
ENTRY(device_not_available)
|
||||||
zeroentry math_state_restore
|
zeroentry do_device_not_available
|
||||||
END(device_not_available)
|
END(device_not_available)
|
||||||
|
|
||||||
/* runs on exception stack */
|
/* runs on exception stack */
|
||||||
|
@@ -190,7 +190,7 @@ vm86_trap:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define DO_ERROR(trapnr, signr, str, name) \
|
#define DO_ERROR(trapnr, signr, str, name) \
|
||||||
void do_##name(struct pt_regs *regs, long error_code) \
|
dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
|
||||||
{ \
|
{ \
|
||||||
if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
|
if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
|
||||||
== NOTIFY_STOP) \
|
== NOTIFY_STOP) \
|
||||||
@@ -200,7 +200,7 @@ void do_##name(struct pt_regs *regs, long error_code) \
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
|
#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
|
||||||
void do_##name(struct pt_regs *regs, long error_code) \
|
dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
|
||||||
{ \
|
{ \
|
||||||
siginfo_t info; \
|
siginfo_t info; \
|
||||||
info.si_signo = signr; \
|
info.si_signo = signr; \
|
||||||
@@ -224,7 +224,7 @@ DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
|
|||||||
DO_ERROR(12, SIGBUS, "stack segment", stack_segment)
|
DO_ERROR(12, SIGBUS, "stack segment", stack_segment)
|
||||||
DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
|
DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
|
||||||
|
|
||||||
void __kprobes
|
dotraplinkage void __kprobes
|
||||||
do_general_protection(struct pt_regs *regs, long error_code)
|
do_general_protection(struct pt_regs *regs, long error_code)
|
||||||
{
|
{
|
||||||
struct task_struct *tsk;
|
struct task_struct *tsk;
|
||||||
@@ -428,7 +428,8 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
|
|||||||
reassert_nmi();
|
reassert_nmi();
|
||||||
}
|
}
|
||||||
|
|
||||||
notrace __kprobes void do_nmi(struct pt_regs *regs, long error_code)
|
dotraplinkage notrace __kprobes void
|
||||||
|
do_nmi(struct pt_regs *regs, long error_code)
|
||||||
{
|
{
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
@@ -456,7 +457,7 @@ void restart_nmi(void)
|
|||||||
acpi_nmi_enable();
|
acpi_nmi_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void __kprobes do_int3(struct pt_regs *regs, long error_code)
|
dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_KPROBES
|
#ifdef CONFIG_KPROBES
|
||||||
if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
|
if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
|
||||||
@@ -494,7 +495,7 @@ void __kprobes do_int3(struct pt_regs *regs, long error_code)
|
|||||||
* find every occurrence of the TF bit that could be saved away even
|
* find every occurrence of the TF bit that could be saved away even
|
||||||
* by user code)
|
* by user code)
|
||||||
*/
|
*/
|
||||||
void __kprobes do_debug(struct pt_regs *regs, long error_code)
|
dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
|
||||||
{
|
{
|
||||||
struct task_struct *tsk = current;
|
struct task_struct *tsk = current;
|
||||||
unsigned int condition;
|
unsigned int condition;
|
||||||
@@ -627,7 +628,7 @@ void math_error(void __user *ip)
|
|||||||
force_sig_info(SIGFPE, &info, task);
|
force_sig_info(SIGFPE, &info, task);
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_coprocessor_error(struct pt_regs *regs, long error_code)
|
dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
|
||||||
{
|
{
|
||||||
conditional_sti(regs);
|
conditional_sti(regs);
|
||||||
ignore_fpu_irq = 1;
|
ignore_fpu_irq = 1;
|
||||||
@@ -682,7 +683,8 @@ static void simd_math_error(void __user *ip)
|
|||||||
force_sig_info(SIGFPE, &info, task);
|
force_sig_info(SIGFPE, &info, task);
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
|
dotraplinkage void
|
||||||
|
do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
|
||||||
{
|
{
|
||||||
conditional_sti(regs);
|
conditional_sti(regs);
|
||||||
|
|
||||||
@@ -706,7 +708,8 @@ void do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
|
|||||||
force_sig(SIGSEGV, current);
|
force_sig(SIGSEGV, current);
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_spurious_interrupt_bug(struct pt_regs *regs, long error_code)
|
dotraplinkage void
|
||||||
|
do_spurious_interrupt_bug(struct pt_regs *regs, long error_code)
|
||||||
{
|
{
|
||||||
conditional_sti(regs);
|
conditional_sti(regs);
|
||||||
#if 0
|
#if 0
|
||||||
@@ -784,7 +787,8 @@ asmlinkage void math_emulate(long arg)
|
|||||||
|
|
||||||
#endif /* CONFIG_MATH_EMULATION */
|
#endif /* CONFIG_MATH_EMULATION */
|
||||||
|
|
||||||
void __kprobes do_device_not_available(struct pt_regs *regs, long error)
|
dotraplinkage void __kprobes
|
||||||
|
do_device_not_available(struct pt_regs *regs, long error)
|
||||||
{
|
{
|
||||||
if (read_cr0() & X86_CR0_EM) {
|
if (read_cr0() & X86_CR0_EM) {
|
||||||
conditional_sti(regs);
|
conditional_sti(regs);
|
||||||
@@ -796,14 +800,14 @@ void __kprobes do_device_not_available(struct pt_regs *regs, long error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_X86_MCE
|
#ifdef CONFIG_X86_MCE
|
||||||
void __kprobes do_machine_check(struct pt_regs *regs, long error)
|
dotraplinkage void __kprobes do_machine_check(struct pt_regs *regs, long error)
|
||||||
{
|
{
|
||||||
conditional_sti(regs);
|
conditional_sti(regs);
|
||||||
machine_check_vector(regs, error);
|
machine_check_vector(regs, error);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void do_iret_error(struct pt_regs *regs, long error_code)
|
dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code)
|
||||||
{
|
{
|
||||||
siginfo_t info;
|
siginfo_t info;
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
|
@@ -125,7 +125,7 @@ kernel_trap:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define DO_ERROR(trapnr, signr, str, name) \
|
#define DO_ERROR(trapnr, signr, str, name) \
|
||||||
asmlinkage void do_##name(struct pt_regs *regs, long error_code) \
|
dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
|
||||||
{ \
|
{ \
|
||||||
if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
|
if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
|
||||||
== NOTIFY_STOP) \
|
== NOTIFY_STOP) \
|
||||||
@@ -135,7 +135,7 @@ asmlinkage void do_##name(struct pt_regs *regs, long error_code) \
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
|
#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
|
||||||
asmlinkage void do_##name(struct pt_regs *regs, long error_code) \
|
dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
|
||||||
{ \
|
{ \
|
||||||
siginfo_t info; \
|
siginfo_t info; \
|
||||||
info.si_signo = signr; \
|
info.si_signo = signr; \
|
||||||
@@ -159,7 +159,7 @@ DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
|
|||||||
DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
|
DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
|
||||||
|
|
||||||
/* Runs on IST stack */
|
/* Runs on IST stack */
|
||||||
asmlinkage void do_stack_segment(struct pt_regs *regs, long error_code)
|
dotraplinkage void do_stack_segment(struct pt_regs *regs, long error_code)
|
||||||
{
|
{
|
||||||
if (notify_die(DIE_TRAP, "stack segment", regs, error_code,
|
if (notify_die(DIE_TRAP, "stack segment", regs, error_code,
|
||||||
12, SIGBUS) == NOTIFY_STOP)
|
12, SIGBUS) == NOTIFY_STOP)
|
||||||
@@ -169,7 +169,7 @@ asmlinkage void do_stack_segment(struct pt_regs *regs, long error_code)
|
|||||||
preempt_conditional_cli(regs);
|
preempt_conditional_cli(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage void do_double_fault(struct pt_regs *regs, long error_code)
|
dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
|
||||||
{
|
{
|
||||||
static const char str[] = "double fault";
|
static const char str[] = "double fault";
|
||||||
struct task_struct *tsk = current;
|
struct task_struct *tsk = current;
|
||||||
@@ -186,7 +186,7 @@ asmlinkage void do_double_fault(struct pt_regs *regs, long error_code)
|
|||||||
die(str, regs, error_code);
|
die(str, regs, error_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage void __kprobes
|
dotraplinkage void __kprobes
|
||||||
do_general_protection(struct pt_regs *regs, long error_code)
|
do_general_protection(struct pt_regs *regs, long error_code)
|
||||||
{
|
{
|
||||||
struct task_struct *tsk;
|
struct task_struct *tsk;
|
||||||
@@ -317,7 +317,7 @@ asmlinkage notrace __kprobes void default_do_nmi(struct pt_regs *regs)
|
|||||||
io_check_error(reason, regs);
|
io_check_error(reason, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage notrace __kprobes void
|
dotraplinkage notrace __kprobes void
|
||||||
do_nmi(struct pt_regs *regs, long error_code)
|
do_nmi(struct pt_regs *regs, long error_code)
|
||||||
{
|
{
|
||||||
nmi_enter();
|
nmi_enter();
|
||||||
@@ -343,7 +343,7 @@ void restart_nmi(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* runs on IST stack. */
|
/* runs on IST stack. */
|
||||||
asmlinkage void __kprobes do_int3(struct pt_regs *regs, long error_code)
|
dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code)
|
||||||
{
|
{
|
||||||
if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
|
if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
|
||||||
== NOTIFY_STOP)
|
== NOTIFY_STOP)
|
||||||
@@ -376,8 +376,7 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* runs on IST stack. */
|
/* runs on IST stack. */
|
||||||
asmlinkage void __kprobes do_debug(struct pt_regs *regs,
|
dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
|
||||||
unsigned long error_code)
|
|
||||||
{
|
{
|
||||||
struct task_struct *tsk = current;
|
struct task_struct *tsk = current;
|
||||||
unsigned long condition;
|
unsigned long condition;
|
||||||
@@ -510,7 +509,7 @@ void math_error(void __user *ip)
|
|||||||
force_sig_info(SIGFPE, &info, task);
|
force_sig_info(SIGFPE, &info, task);
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
|
dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
|
||||||
{
|
{
|
||||||
conditional_sti(regs);
|
conditional_sti(regs);
|
||||||
if (!user_mode(regs) &&
|
if (!user_mode(regs) &&
|
||||||
@@ -572,7 +571,8 @@ static void simd_math_error(void __user *ip)
|
|||||||
force_sig_info(SIGFPE, &info, task);
|
force_sig_info(SIGFPE, &info, task);
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
|
dotraplinkage void
|
||||||
|
do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
|
||||||
{
|
{
|
||||||
conditional_sti(regs);
|
conditional_sti(regs);
|
||||||
if (!user_mode(regs) &&
|
if (!user_mode(regs) &&
|
||||||
@@ -581,7 +581,8 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
|
|||||||
simd_math_error((void __user *)regs->ip);
|
simd_math_error((void __user *)regs->ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage void do_spurious_interrupt_bug(struct pt_regs *regs, long error_code)
|
dotraplinkage void
|
||||||
|
do_spurious_interrupt_bug(struct pt_regs *regs, long error_code)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -633,6 +634,12 @@ asmlinkage void math_state_restore(void)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(math_state_restore);
|
EXPORT_SYMBOL_GPL(math_state_restore);
|
||||||
|
|
||||||
|
dotraplinkage void __kprobes
|
||||||
|
do_device_not_available(struct pt_regs *regs, long error)
|
||||||
|
{
|
||||||
|
math_state_restore();
|
||||||
|
}
|
||||||
|
|
||||||
void __init trap_init(void)
|
void __init trap_init(void)
|
||||||
{
|
{
|
||||||
set_intr_gate(0, ÷_error);
|
set_intr_gate(0, ÷_error);
|
||||||
|
@@ -3,7 +3,12 @@
|
|||||||
|
|
||||||
#include <asm/debugreg.h>
|
#include <asm/debugreg.h>
|
||||||
|
|
||||||
/* Common in X86_32 and X86_64 */
|
#ifdef CONFIG_X86_32
|
||||||
|
#define dotraplinkage
|
||||||
|
#else
|
||||||
|
#define dotraplinkage asmlinkage
|
||||||
|
#endif
|
||||||
|
|
||||||
asmlinkage void divide_error(void);
|
asmlinkage void divide_error(void);
|
||||||
asmlinkage void debug(void);
|
asmlinkage void debug(void);
|
||||||
asmlinkage void nmi(void);
|
asmlinkage void nmi(void);
|
||||||
@@ -12,31 +17,47 @@ asmlinkage void overflow(void);
|
|||||||
asmlinkage void bounds(void);
|
asmlinkage void bounds(void);
|
||||||
asmlinkage void invalid_op(void);
|
asmlinkage void invalid_op(void);
|
||||||
asmlinkage void device_not_available(void);
|
asmlinkage void device_not_available(void);
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
|
asmlinkage void double_fault(void);
|
||||||
|
#endif
|
||||||
asmlinkage void coprocessor_segment_overrun(void);
|
asmlinkage void coprocessor_segment_overrun(void);
|
||||||
asmlinkage void invalid_TSS(void);
|
asmlinkage void invalid_TSS(void);
|
||||||
asmlinkage void segment_not_present(void);
|
asmlinkage void segment_not_present(void);
|
||||||
asmlinkage void stack_segment(void);
|
asmlinkage void stack_segment(void);
|
||||||
asmlinkage void general_protection(void);
|
asmlinkage void general_protection(void);
|
||||||
asmlinkage void page_fault(void);
|
asmlinkage void page_fault(void);
|
||||||
asmlinkage void coprocessor_error(void);
|
|
||||||
asmlinkage void simd_coprocessor_error(void);
|
|
||||||
asmlinkage void alignment_check(void);
|
|
||||||
asmlinkage void spurious_interrupt_bug(void);
|
asmlinkage void spurious_interrupt_bug(void);
|
||||||
|
asmlinkage void coprocessor_error(void);
|
||||||
|
asmlinkage void alignment_check(void);
|
||||||
#ifdef CONFIG_X86_MCE
|
#ifdef CONFIG_X86_MCE
|
||||||
asmlinkage void machine_check(void);
|
asmlinkage void machine_check(void);
|
||||||
#endif /* CONFIG_X86_MCE */
|
#endif /* CONFIG_X86_MCE */
|
||||||
|
asmlinkage void simd_coprocessor_error(void);
|
||||||
|
|
||||||
void do_divide_error(struct pt_regs *, long);
|
dotraplinkage void do_divide_error(struct pt_regs *, long);
|
||||||
void do_overflow(struct pt_regs *, long);
|
dotraplinkage void do_debug(struct pt_regs *, long);
|
||||||
void do_bounds(struct pt_regs *, long);
|
dotraplinkage void do_nmi(struct pt_regs *, long);
|
||||||
void do_coprocessor_segment_overrun(struct pt_regs *, long);
|
dotraplinkage void do_int3(struct pt_regs *, long);
|
||||||
void do_invalid_TSS(struct pt_regs *, long);
|
dotraplinkage void do_overflow(struct pt_regs *, long);
|
||||||
void do_segment_not_present(struct pt_regs *, long);
|
dotraplinkage void do_bounds(struct pt_regs *, long);
|
||||||
void do_stack_segment(struct pt_regs *, long);
|
dotraplinkage void do_invalid_op(struct pt_regs *, long);
|
||||||
void do_alignment_check(struct pt_regs *, long);
|
dotraplinkage void do_device_not_available(struct pt_regs *, long);
|
||||||
void do_invalid_op(struct pt_regs *, long);
|
dotraplinkage void do_coprocessor_segment_overrun(struct pt_regs *, long);
|
||||||
void do_general_protection(struct pt_regs *, long);
|
dotraplinkage void do_invalid_TSS(struct pt_regs *, long);
|
||||||
void do_nmi(struct pt_regs *, long);
|
dotraplinkage void do_segment_not_present(struct pt_regs *, long);
|
||||||
|
dotraplinkage void do_stack_segment(struct pt_regs *, long);
|
||||||
|
dotraplinkage void do_general_protection(struct pt_regs *, long);
|
||||||
|
dotraplinkage void do_page_fault(struct pt_regs *, unsigned long);
|
||||||
|
dotraplinkage void do_spurious_interrupt_bug(struct pt_regs *, long);
|
||||||
|
dotraplinkage void do_coprocessor_error(struct pt_regs *, long);
|
||||||
|
dotraplinkage void do_alignment_check(struct pt_regs *, long);
|
||||||
|
#ifdef CONFIG_X86_MCE
|
||||||
|
dotraplinkage void do_machine_check(struct pt_regs *, long);
|
||||||
|
#endif
|
||||||
|
dotraplinkage void do_simd_coprocessor_error(struct pt_regs *, long);
|
||||||
|
#ifdef CONFIG_X86_32
|
||||||
|
dotraplinkage void do_iret_error(struct pt_regs *, long);
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline int get_si_code(unsigned long condition)
|
static inline int get_si_code(unsigned long condition)
|
||||||
{
|
{
|
||||||
@@ -52,31 +73,9 @@ extern int panic_on_unrecovered_nmi;
|
|||||||
extern int kstack_depth_to_print;
|
extern int kstack_depth_to_print;
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
|
|
||||||
void do_iret_error(struct pt_regs *, long);
|
|
||||||
void do_int3(struct pt_regs *, long);
|
|
||||||
void do_debug(struct pt_regs *, long);
|
|
||||||
void math_error(void __user *);
|
void math_error(void __user *);
|
||||||
void do_coprocessor_error(struct pt_regs *, long);
|
|
||||||
void do_simd_coprocessor_error(struct pt_regs *, long);
|
|
||||||
void do_spurious_interrupt_bug(struct pt_regs *, long);
|
|
||||||
unsigned long patch_espfix_desc(unsigned long, unsigned long);
|
unsigned long patch_espfix_desc(unsigned long, unsigned long);
|
||||||
asmlinkage void math_emulate(long);
|
asmlinkage void math_emulate(long);
|
||||||
|
#endif
|
||||||
|
|
||||||
void do_page_fault(struct pt_regs *regs, unsigned long error_code);
|
|
||||||
|
|
||||||
#else /* CONFIG_X86_32 */
|
|
||||||
|
|
||||||
asmlinkage void double_fault(void);
|
|
||||||
|
|
||||||
asmlinkage void do_int3(struct pt_regs *, long);
|
|
||||||
asmlinkage void do_stack_segment(struct pt_regs *, long);
|
|
||||||
asmlinkage void do_debug(struct pt_regs *, unsigned long);
|
|
||||||
asmlinkage void do_coprocessor_error(struct pt_regs *, long);
|
|
||||||
asmlinkage void do_simd_coprocessor_error(struct pt_regs *, long);
|
|
||||||
asmlinkage void do_spurious_interrupt_bug(struct pt_regs *, long);
|
|
||||||
|
|
||||||
asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code);
|
|
||||||
|
|
||||||
#endif /* CONFIG_X86_32 */
|
|
||||||
#endif /* ASM_X86__TRAPS_H */
|
#endif /* ASM_X86__TRAPS_H */
|
||||||
|
Reference in New Issue
Block a user