mirror of
https://git.proxmox.com/git/mirror_ubuntu-kernels.git
synced 2026-01-24 11:16:43 +00:00
Device interrupts which go through do_IRQ() or the spurious interrupt handler have their separate entry code on 64 bit for no good reason. Both 32 and 64 bit transport the vector number through ORIG_[RE]AX in pt_regs. Further the vector number is forced to fit into an u8 and is complemented and offset by 0x80 so it's in the signed character range. Otherwise GAS would expand the pushq to a 5 byte instruction for any vector > 0x7F. Treat the vector number like an error code and hand it to the C function as argument. This allows to get rid of the extra entry code in a later step. Simplify the error code push magic by implementing the pushq imm8 via a '.byte 0x6a, vector' sequence so GAS is not able to screw it up. As the pushq imm8 is sign extending the resulting error code needs to be truncated to 8 bits in C code. Originally-by: Andy Lutomirski <luto@kernel.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@kernel.org> Acked-by: Andy Lutomirski <luto@kernel.org> Link: https://lore.kernel.org/r/20200521202118.796915981@linutronix.de
74 lines
2.1 KiB
C
74 lines
2.1 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _ASM_X86_TRAPS_H
|
|
#define _ASM_X86_TRAPS_H
|
|
|
|
#include <linux/context_tracking_state.h>
|
|
#include <linux/kprobes.h>
|
|
|
|
#include <asm/debugreg.h>
|
|
#include <asm/idtentry.h>
|
|
#include <asm/siginfo.h> /* TRAP_TRACE, ... */
|
|
|
|
#ifdef CONFIG_X86_64
|
|
asmlinkage __visible notrace struct pt_regs *sync_regs(struct pt_regs *eregs);
|
|
asmlinkage __visible notrace
|
|
struct bad_iret_stack *fixup_bad_iret(struct bad_iret_stack *s);
|
|
void __init trap_init(void);
|
|
#endif
|
|
|
|
#ifdef CONFIG_X86_F00F_BUG
|
|
/* For handling the FOOF bug */
|
|
void handle_invalid_op(struct pt_regs *regs);
|
|
#endif
|
|
|
|
static inline int get_si_code(unsigned long condition)
|
|
{
|
|
if (condition & DR_STEP)
|
|
return TRAP_TRACE;
|
|
else if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3))
|
|
return TRAP_HWBKPT;
|
|
else
|
|
return TRAP_BRKPT;
|
|
}
|
|
|
|
extern int panic_on_unrecovered_nmi;
|
|
|
|
void math_emulate(struct math_emu_info *);
|
|
#ifndef CONFIG_X86_32
|
|
asmlinkage void smp_thermal_interrupt(struct pt_regs *regs);
|
|
asmlinkage void smp_threshold_interrupt(struct pt_regs *regs);
|
|
asmlinkage void smp_deferred_error_interrupt(struct pt_regs *regs);
|
|
#endif
|
|
|
|
void smp_apic_timer_interrupt(struct pt_regs *regs);
|
|
void smp_error_interrupt(struct pt_regs *regs);
|
|
void smp_spurious_apic_interrupt(struct pt_regs *regs);
|
|
void smp_spurious_interrupt(struct pt_regs *regs, unsigned long vector);
|
|
asmlinkage void smp_irq_move_cleanup_interrupt(void);
|
|
|
|
#ifdef CONFIG_VMAP_STACK
|
|
void __noreturn handle_stack_overflow(const char *message,
|
|
struct pt_regs *regs,
|
|
unsigned long fault_address);
|
|
#endif
|
|
|
|
/*
|
|
* Page fault error code bits:
|
|
*
|
|
* bit 0 == 0: no page found 1: protection fault
|
|
* bit 1 == 0: read access 1: write access
|
|
* bit 2 == 0: kernel-mode access 1: user-mode access
|
|
* bit 3 == 1: use of reserved bit detected
|
|
* bit 4 == 1: fault was an instruction fetch
|
|
* bit 5 == 1: protection keys block access
|
|
*/
|
|
enum x86_pf_error_code {
|
|
X86_PF_PROT = 1 << 0,
|
|
X86_PF_WRITE = 1 << 1,
|
|
X86_PF_USER = 1 << 2,
|
|
X86_PF_RSVD = 1 << 3,
|
|
X86_PF_INSTR = 1 << 4,
|
|
X86_PF_PK = 1 << 5,
|
|
};
|
|
#endif /* _ASM_X86_TRAPS_H */
|