Merge branch 'x86/irq' into x86/core
This commit is contained in:
commit
bed4f13065
|
@ -6,56 +6,91 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Macros for dwarf2 CFI unwind table entries.
|
* Macros for dwarf2 CFI unwind table entries.
|
||||||
See "as.info" for details on these pseudo ops. Unfortunately
|
* See "as.info" for details on these pseudo ops. Unfortunately
|
||||||
they are only supported in very new binutils, so define them
|
* they are only supported in very new binutils, so define them
|
||||||
away for older version.
|
* away for older version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_AS_CFI
|
#ifdef CONFIG_AS_CFI
|
||||||
|
|
||||||
#define CFI_STARTPROC .cfi_startproc
|
#define CFI_STARTPROC .cfi_startproc
|
||||||
#define CFI_ENDPROC .cfi_endproc
|
#define CFI_ENDPROC .cfi_endproc
|
||||||
#define CFI_DEF_CFA .cfi_def_cfa
|
#define CFI_DEF_CFA .cfi_def_cfa
|
||||||
#define CFI_DEF_CFA_REGISTER .cfi_def_cfa_register
|
#define CFI_DEF_CFA_REGISTER .cfi_def_cfa_register
|
||||||
#define CFI_DEF_CFA_OFFSET .cfi_def_cfa_offset
|
#define CFI_DEF_CFA_OFFSET .cfi_def_cfa_offset
|
||||||
#define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset
|
#define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset
|
||||||
#define CFI_OFFSET .cfi_offset
|
#define CFI_OFFSET .cfi_offset
|
||||||
#define CFI_REL_OFFSET .cfi_rel_offset
|
#define CFI_REL_OFFSET .cfi_rel_offset
|
||||||
#define CFI_REGISTER .cfi_register
|
#define CFI_REGISTER .cfi_register
|
||||||
#define CFI_RESTORE .cfi_restore
|
#define CFI_RESTORE .cfi_restore
|
||||||
#define CFI_REMEMBER_STATE .cfi_remember_state
|
#define CFI_REMEMBER_STATE .cfi_remember_state
|
||||||
#define CFI_RESTORE_STATE .cfi_restore_state
|
#define CFI_RESTORE_STATE .cfi_restore_state
|
||||||
#define CFI_UNDEFINED .cfi_undefined
|
#define CFI_UNDEFINED .cfi_undefined
|
||||||
|
|
||||||
#ifdef CONFIG_AS_CFI_SIGNAL_FRAME
|
#ifdef CONFIG_AS_CFI_SIGNAL_FRAME
|
||||||
#define CFI_SIGNAL_FRAME .cfi_signal_frame
|
#define CFI_SIGNAL_FRAME .cfi_signal_frame
|
||||||
#else
|
#else
|
||||||
#define CFI_SIGNAL_FRAME
|
#define CFI_SIGNAL_FRAME
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* Due to the structure of pre-exisiting code, don't use assembler line
|
/*
|
||||||
comment character # to ignore the arguments. Instead, use a dummy macro. */
|
* Due to the structure of pre-exisiting code, don't use assembler line
|
||||||
|
* comment character # to ignore the arguments. Instead, use a dummy macro.
|
||||||
|
*/
|
||||||
.macro cfi_ignore a=0, b=0, c=0, d=0
|
.macro cfi_ignore a=0, b=0, c=0, d=0
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
#define CFI_STARTPROC cfi_ignore
|
#define CFI_STARTPROC cfi_ignore
|
||||||
#define CFI_ENDPROC cfi_ignore
|
#define CFI_ENDPROC cfi_ignore
|
||||||
#define CFI_DEF_CFA cfi_ignore
|
#define CFI_DEF_CFA cfi_ignore
|
||||||
#define CFI_DEF_CFA_REGISTER cfi_ignore
|
#define CFI_DEF_CFA_REGISTER cfi_ignore
|
||||||
#define CFI_DEF_CFA_OFFSET cfi_ignore
|
#define CFI_DEF_CFA_OFFSET cfi_ignore
|
||||||
#define CFI_ADJUST_CFA_OFFSET cfi_ignore
|
#define CFI_ADJUST_CFA_OFFSET cfi_ignore
|
||||||
#define CFI_OFFSET cfi_ignore
|
#define CFI_OFFSET cfi_ignore
|
||||||
#define CFI_REL_OFFSET cfi_ignore
|
#define CFI_REL_OFFSET cfi_ignore
|
||||||
#define CFI_REGISTER cfi_ignore
|
#define CFI_REGISTER cfi_ignore
|
||||||
#define CFI_RESTORE cfi_ignore
|
#define CFI_RESTORE cfi_ignore
|
||||||
#define CFI_REMEMBER_STATE cfi_ignore
|
#define CFI_REMEMBER_STATE cfi_ignore
|
||||||
#define CFI_RESTORE_STATE cfi_ignore
|
#define CFI_RESTORE_STATE cfi_ignore
|
||||||
#define CFI_UNDEFINED cfi_ignore
|
#define CFI_UNDEFINED cfi_ignore
|
||||||
#define CFI_SIGNAL_FRAME cfi_ignore
|
#define CFI_SIGNAL_FRAME cfi_ignore
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* An attempt to make CFI annotations more or less
|
||||||
|
* correct and shorter. It is implied that you know
|
||||||
|
* what you're doing if you use them.
|
||||||
|
*/
|
||||||
|
#ifdef __ASSEMBLY__
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
|
.macro pushq_cfi reg
|
||||||
|
pushq \reg
|
||||||
|
CFI_ADJUST_CFA_OFFSET 8
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro popq_cfi reg
|
||||||
|
popq \reg
|
||||||
|
CFI_ADJUST_CFA_OFFSET -8
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro movq_cfi reg offset=0
|
||||||
|
movq %\reg, \offset(%rsp)
|
||||||
|
CFI_REL_OFFSET \reg, \offset
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro movq_cfi_restore offset reg
|
||||||
|
movq \offset(%rsp), %\reg
|
||||||
|
CFI_RESTORE \reg
|
||||||
|
.endm
|
||||||
|
#else /*!CONFIG_X86_64*/
|
||||||
|
|
||||||
|
/* 32bit defenitions are missed yet */
|
||||||
|
|
||||||
|
#endif /*!CONFIG_X86_64*/
|
||||||
|
#endif /*__ASSEMBLY__*/
|
||||||
|
|
||||||
#endif /* _ASM_X86_DWARF2_H */
|
#endif /* _ASM_X86_DWARF2_H */
|
||||||
|
|
|
@ -22,6 +22,8 @@ DECLARE_PER_CPU(irq_cpustat_t, irq_stat);
|
||||||
#define __ARCH_IRQ_STAT
|
#define __ARCH_IRQ_STAT
|
||||||
#define __IRQ_STAT(cpu, member) (per_cpu(irq_stat, cpu).member)
|
#define __IRQ_STAT(cpu, member) (per_cpu(irq_stat, cpu).member)
|
||||||
|
|
||||||
|
#define inc_irq_stat(member) (__get_cpu_var(irq_stat).member++)
|
||||||
|
|
||||||
void ack_bad_irq(unsigned int irq);
|
void ack_bad_irq(unsigned int irq);
|
||||||
#include <linux/irq_cpustat.h>
|
#include <linux/irq_cpustat.h>
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
#define __ARCH_IRQ_STAT 1
|
#define __ARCH_IRQ_STAT 1
|
||||||
|
|
||||||
|
#define inc_irq_stat(member) add_pda(member, 1)
|
||||||
|
|
||||||
#define local_softirq_pending() read_pda(__softirq_pending)
|
#define local_softirq_pending() read_pda(__softirq_pending)
|
||||||
|
|
||||||
#define __ARCH_SET_SOFTIRQ_PENDING 1
|
#define __ARCH_SET_SOFTIRQ_PENDING 1
|
||||||
|
|
|
@ -109,9 +109,7 @@ extern asmlinkage void smp_invalidate_interrupt(struct pt_regs *);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
extern void (*__initconst interrupt[NR_VECTORS-FIRST_EXTERNAL_VECTOR])(void);
|
||||||
extern void (*const interrupt[NR_VECTORS])(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef int vector_irq_t[NR_VECTORS];
|
typedef int vector_irq_t[NR_VECTORS];
|
||||||
DECLARE_PER_CPU(vector_irq_t, vector_irq);
|
DECLARE_PER_CPU(vector_irq_t, vector_irq);
|
||||||
|
|
|
@ -57,5 +57,65 @@
|
||||||
#define __ALIGN_STR ".align 16,0x90"
|
#define __ALIGN_STR ".align 16,0x90"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* to check ENTRY_X86/END_X86 and
|
||||||
|
* KPROBE_ENTRY_X86/KPROBE_END_X86
|
||||||
|
* unbalanced-missed-mixed appearance
|
||||||
|
*/
|
||||||
|
#define __set_entry_x86 .set ENTRY_X86_IN, 0
|
||||||
|
#define __unset_entry_x86 .set ENTRY_X86_IN, 1
|
||||||
|
#define __set_kprobe_x86 .set KPROBE_X86_IN, 0
|
||||||
|
#define __unset_kprobe_x86 .set KPROBE_X86_IN, 1
|
||||||
|
|
||||||
|
#define __macro_err_x86 .error "ENTRY_X86/KPROBE_X86 unbalanced,missed,mixed"
|
||||||
|
|
||||||
|
#define __check_entry_x86 \
|
||||||
|
.ifdef ENTRY_X86_IN; \
|
||||||
|
.ifeq ENTRY_X86_IN; \
|
||||||
|
__macro_err_x86; \
|
||||||
|
.abort; \
|
||||||
|
.endif; \
|
||||||
|
.endif
|
||||||
|
|
||||||
|
#define __check_kprobe_x86 \
|
||||||
|
.ifdef KPROBE_X86_IN; \
|
||||||
|
.ifeq KPROBE_X86_IN; \
|
||||||
|
__macro_err_x86; \
|
||||||
|
.abort; \
|
||||||
|
.endif; \
|
||||||
|
.endif
|
||||||
|
|
||||||
|
#define __check_entry_kprobe_x86 \
|
||||||
|
__check_entry_x86; \
|
||||||
|
__check_kprobe_x86
|
||||||
|
|
||||||
|
#define ENTRY_KPROBE_FINAL_X86 __check_entry_kprobe_x86
|
||||||
|
|
||||||
|
#define ENTRY_X86(name) \
|
||||||
|
__check_entry_kprobe_x86; \
|
||||||
|
__set_entry_x86; \
|
||||||
|
.globl name; \
|
||||||
|
__ALIGN; \
|
||||||
|
name:
|
||||||
|
|
||||||
|
#define END_X86(name) \
|
||||||
|
__unset_entry_x86; \
|
||||||
|
__check_entry_kprobe_x86; \
|
||||||
|
.size name, .-name
|
||||||
|
|
||||||
|
#define KPROBE_ENTRY_X86(name) \
|
||||||
|
__check_entry_kprobe_x86; \
|
||||||
|
__set_kprobe_x86; \
|
||||||
|
.pushsection .kprobes.text, "ax"; \
|
||||||
|
.globl name; \
|
||||||
|
__ALIGN; \
|
||||||
|
name:
|
||||||
|
|
||||||
|
#define KPROBE_END_X86(name) \
|
||||||
|
__unset_kprobe_x86; \
|
||||||
|
__check_entry_kprobe_x86; \
|
||||||
|
.size name, .-name; \
|
||||||
|
.popsection
|
||||||
|
|
||||||
#endif /* _ASM_X86_LINKAGE_H */
|
#endif /* _ASM_X86_LINKAGE_H */
|
||||||
|
|
||||||
|
|
|
@ -777,11 +777,7 @@ static void local_apic_timer_interrupt(void)
|
||||||
/*
|
/*
|
||||||
* the NMI deadlock-detector uses this.
|
* the NMI deadlock-detector uses this.
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_X86_64
|
inc_irq_stat(apic_timer_irqs);
|
||||||
add_pda(apic_timer_irqs, 1);
|
|
||||||
#else
|
|
||||||
per_cpu(irq_stat, cpu).apic_timer_irqs++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
evt->event_handler(evt);
|
evt->event_handler(evt);
|
||||||
}
|
}
|
||||||
|
@ -1677,14 +1673,11 @@ void smp_spurious_interrupt(struct pt_regs *regs)
|
||||||
if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f)))
|
if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f)))
|
||||||
ack_APIC_irq();
|
ack_APIC_irq();
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
inc_irq_stat(irq_spurious_count);
|
||||||
add_pda(irq_spurious_count, 1);
|
|
||||||
#else
|
|
||||||
/* see sw-dev-man vol 3, chapter 7.4.13.5 */
|
/* see sw-dev-man vol 3, chapter 7.4.13.5 */
|
||||||
pr_info("spurious APIC interrupt on CPU#%d, "
|
pr_info("spurious APIC interrupt on CPU#%d, "
|
||||||
"should never happen.\n", smp_processor_id());
|
"should never happen.\n", smp_processor_id());
|
||||||
__get_cpu_var(irq_stat).irq_spurious_count++;
|
|
||||||
#endif
|
|
||||||
irq_exit();
|
irq_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -237,7 +237,7 @@ asmlinkage void mce_threshold_interrupt(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
add_pda(irq_threshold_count, 1);
|
inc_irq_stat(irq_threshold_count);
|
||||||
irq_exit();
|
irq_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ asmlinkage void smp_thermal_interrupt(void)
|
||||||
if (therm_throt_process(msr_val & 1))
|
if (therm_throt_process(msr_val & 1))
|
||||||
mce_log_therm_throt_event(smp_processor_id(), msr_val);
|
mce_log_therm_throt_event(smp_processor_id(), msr_val);
|
||||||
|
|
||||||
add_pda(irq_thermal_count, 1);
|
inc_irq_stat(irq_thermal_count);
|
||||||
irq_exit();
|
irq_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -619,28 +619,37 @@ END(syscall_badsys)
|
||||||
27:;
|
27:;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build the entry stubs and pointer table with
|
* Build the entry stubs and pointer table with some assembler magic.
|
||||||
* some assembler magic.
|
* We pack 7 stubs into a single 32-byte chunk, which will fit in a
|
||||||
|
* single cache line on all modern x86 implementations.
|
||||||
*/
|
*/
|
||||||
.section .rodata,"a"
|
.section .init.rodata,"a"
|
||||||
ENTRY(interrupt)
|
ENTRY(interrupt)
|
||||||
.text
|
.text
|
||||||
|
.p2align 5
|
||||||
|
.p2align CONFIG_X86_L1_CACHE_SHIFT
|
||||||
ENTRY(irq_entries_start)
|
ENTRY(irq_entries_start)
|
||||||
RING0_INT_FRAME
|
RING0_INT_FRAME
|
||||||
vector=0
|
vector=FIRST_EXTERNAL_VECTOR
|
||||||
.rept NR_VECTORS
|
.rept (NR_VECTORS-FIRST_EXTERNAL_VECTOR+6)/7
|
||||||
ALIGN
|
.balign 32
|
||||||
.if vector
|
.rept 7
|
||||||
|
.if vector < NR_VECTORS
|
||||||
|
.if vector <> FIRST_EXTERNAL_VECTOR
|
||||||
CFI_ADJUST_CFA_OFFSET -4
|
CFI_ADJUST_CFA_OFFSET -4
|
||||||
.endif
|
.endif
|
||||||
1: pushl $~(vector)
|
1: pushl $(~vector+0x80) /* Note: always in signed byte range */
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
jmp common_interrupt
|
.if ((vector-FIRST_EXTERNAL_VECTOR)%7) <> 6
|
||||||
.previous
|
jmp 2f
|
||||||
|
.endif
|
||||||
|
.previous
|
||||||
.long 1b
|
.long 1b
|
||||||
.text
|
.text
|
||||||
vector=vector+1
|
vector=vector+1
|
||||||
|
.endif
|
||||||
|
.endr
|
||||||
|
2: jmp common_interrupt
|
||||||
.endr
|
.endr
|
||||||
END(irq_entries_start)
|
END(irq_entries_start)
|
||||||
|
|
||||||
|
@ -652,8 +661,9 @@ END(interrupt)
|
||||||
* the CPU automatically disables interrupts when executing an IRQ vector,
|
* the CPU automatically disables interrupts when executing an IRQ vector,
|
||||||
* so IRQ-flags tracing has to follow that:
|
* so IRQ-flags tracing has to follow that:
|
||||||
*/
|
*/
|
||||||
ALIGN
|
.p2align CONFIG_X86_L1_CACHE_SHIFT
|
||||||
common_interrupt:
|
common_interrupt:
|
||||||
|
addl $-0x80,(%esp) /* Adjust vector into the [-256,-1] range */
|
||||||
SAVE_ALL
|
SAVE_ALL
|
||||||
TRACE_IRQS_OFF
|
TRACE_IRQS_OFF
|
||||||
movl %esp,%eax
|
movl %esp,%eax
|
||||||
|
@ -678,65 +688,6 @@ ENDPROC(name)
|
||||||
/* The include is where all of the SMP etc. interrupts come from */
|
/* The include is where all of the SMP etc. interrupts come from */
|
||||||
#include "entry_arch.h"
|
#include "entry_arch.h"
|
||||||
|
|
||||||
KPROBE_ENTRY(page_fault)
|
|
||||||
RING0_EC_FRAME
|
|
||||||
pushl $do_page_fault
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
ALIGN
|
|
||||||
error_code:
|
|
||||||
/* the function address is in %fs's slot on the stack */
|
|
||||||
pushl %es
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
/*CFI_REL_OFFSET es, 0*/
|
|
||||||
pushl %ds
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
/*CFI_REL_OFFSET ds, 0*/
|
|
||||||
pushl %eax
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
CFI_REL_OFFSET eax, 0
|
|
||||||
pushl %ebp
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
CFI_REL_OFFSET ebp, 0
|
|
||||||
pushl %edi
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
CFI_REL_OFFSET edi, 0
|
|
||||||
pushl %esi
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
CFI_REL_OFFSET esi, 0
|
|
||||||
pushl %edx
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
CFI_REL_OFFSET edx, 0
|
|
||||||
pushl %ecx
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
CFI_REL_OFFSET ecx, 0
|
|
||||||
pushl %ebx
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
CFI_REL_OFFSET ebx, 0
|
|
||||||
cld
|
|
||||||
pushl %fs
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
/*CFI_REL_OFFSET fs, 0*/
|
|
||||||
movl $(__KERNEL_PERCPU), %ecx
|
|
||||||
movl %ecx, %fs
|
|
||||||
UNWIND_ESPFIX_STACK
|
|
||||||
popl %ecx
|
|
||||||
CFI_ADJUST_CFA_OFFSET -4
|
|
||||||
/*CFI_REGISTER es, ecx*/
|
|
||||||
movl PT_FS(%esp), %edi # get the function address
|
|
||||||
movl PT_ORIG_EAX(%esp), %edx # get the error code
|
|
||||||
movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
|
|
||||||
mov %ecx, PT_FS(%esp)
|
|
||||||
/*CFI_REL_OFFSET fs, ES*/
|
|
||||||
movl $(__USER_DS), %ecx
|
|
||||||
movl %ecx, %ds
|
|
||||||
movl %ecx, %es
|
|
||||||
TRACE_IRQS_OFF
|
|
||||||
movl %esp,%eax # pt_regs pointer
|
|
||||||
call *%edi
|
|
||||||
jmp ret_from_exception
|
|
||||||
CFI_ENDPROC
|
|
||||||
KPROBE_END(page_fault)
|
|
||||||
|
|
||||||
ENTRY(coprocessor_error)
|
ENTRY(coprocessor_error)
|
||||||
RING0_INT_FRAME
|
RING0_INT_FRAME
|
||||||
pushl $0
|
pushl $0
|
||||||
|
@ -767,140 +718,6 @@ ENTRY(device_not_available)
|
||||||
CFI_ENDPROC
|
CFI_ENDPROC
|
||||||
END(device_not_available)
|
END(device_not_available)
|
||||||
|
|
||||||
/*
|
|
||||||
* Debug traps and NMI can happen at the one SYSENTER instruction
|
|
||||||
* that sets up the real kernel stack. Check here, since we can't
|
|
||||||
* allow the wrong stack to be used.
|
|
||||||
*
|
|
||||||
* "TSS_sysenter_sp0+12" is because the NMI/debug handler will have
|
|
||||||
* already pushed 3 words if it hits on the sysenter instruction:
|
|
||||||
* eflags, cs and eip.
|
|
||||||
*
|
|
||||||
* We just load the right stack, and push the three (known) values
|
|
||||||
* by hand onto the new stack - while updating the return eip past
|
|
||||||
* the instruction that would have done it for sysenter.
|
|
||||||
*/
|
|
||||||
#define FIX_STACK(offset, ok, label) \
|
|
||||||
cmpw $__KERNEL_CS,4(%esp); \
|
|
||||||
jne ok; \
|
|
||||||
label: \
|
|
||||||
movl TSS_sysenter_sp0+offset(%esp),%esp; \
|
|
||||||
CFI_DEF_CFA esp, 0; \
|
|
||||||
CFI_UNDEFINED eip; \
|
|
||||||
pushfl; \
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4; \
|
|
||||||
pushl $__KERNEL_CS; \
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4; \
|
|
||||||
pushl $sysenter_past_esp; \
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4; \
|
|
||||||
CFI_REL_OFFSET eip, 0
|
|
||||||
|
|
||||||
KPROBE_ENTRY(debug)
|
|
||||||
RING0_INT_FRAME
|
|
||||||
cmpl $ia32_sysenter_target,(%esp)
|
|
||||||
jne debug_stack_correct
|
|
||||||
FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
|
|
||||||
debug_stack_correct:
|
|
||||||
pushl $-1 # mark this as an int
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
SAVE_ALL
|
|
||||||
TRACE_IRQS_OFF
|
|
||||||
xorl %edx,%edx # error code 0
|
|
||||||
movl %esp,%eax # pt_regs pointer
|
|
||||||
call do_debug
|
|
||||||
jmp ret_from_exception
|
|
||||||
CFI_ENDPROC
|
|
||||||
KPROBE_END(debug)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NMI is doubly nasty. It can happen _while_ we're handling
|
|
||||||
* a debug fault, and the debug fault hasn't yet been able to
|
|
||||||
* clear up the stack. So we first check whether we got an
|
|
||||||
* NMI on the sysenter entry path, but after that we need to
|
|
||||||
* check whether we got an NMI on the debug path where the debug
|
|
||||||
* fault happened on the sysenter path.
|
|
||||||
*/
|
|
||||||
KPROBE_ENTRY(nmi)
|
|
||||||
RING0_INT_FRAME
|
|
||||||
pushl %eax
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
movl %ss, %eax
|
|
||||||
cmpw $__ESPFIX_SS, %ax
|
|
||||||
popl %eax
|
|
||||||
CFI_ADJUST_CFA_OFFSET -4
|
|
||||||
je nmi_espfix_stack
|
|
||||||
cmpl $ia32_sysenter_target,(%esp)
|
|
||||||
je nmi_stack_fixup
|
|
||||||
pushl %eax
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
movl %esp,%eax
|
|
||||||
/* Do not access memory above the end of our stack page,
|
|
||||||
* it might not exist.
|
|
||||||
*/
|
|
||||||
andl $(THREAD_SIZE-1),%eax
|
|
||||||
cmpl $(THREAD_SIZE-20),%eax
|
|
||||||
popl %eax
|
|
||||||
CFI_ADJUST_CFA_OFFSET -4
|
|
||||||
jae nmi_stack_correct
|
|
||||||
cmpl $ia32_sysenter_target,12(%esp)
|
|
||||||
je nmi_debug_stack_check
|
|
||||||
nmi_stack_correct:
|
|
||||||
/* We have a RING0_INT_FRAME here */
|
|
||||||
pushl %eax
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
SAVE_ALL
|
|
||||||
TRACE_IRQS_OFF
|
|
||||||
xorl %edx,%edx # zero error code
|
|
||||||
movl %esp,%eax # pt_regs pointer
|
|
||||||
call do_nmi
|
|
||||||
jmp restore_nocheck_notrace
|
|
||||||
CFI_ENDPROC
|
|
||||||
|
|
||||||
nmi_stack_fixup:
|
|
||||||
RING0_INT_FRAME
|
|
||||||
FIX_STACK(12,nmi_stack_correct, 1)
|
|
||||||
jmp nmi_stack_correct
|
|
||||||
|
|
||||||
nmi_debug_stack_check:
|
|
||||||
/* We have a RING0_INT_FRAME here */
|
|
||||||
cmpw $__KERNEL_CS,16(%esp)
|
|
||||||
jne nmi_stack_correct
|
|
||||||
cmpl $debug,(%esp)
|
|
||||||
jb nmi_stack_correct
|
|
||||||
cmpl $debug_esp_fix_insn,(%esp)
|
|
||||||
ja nmi_stack_correct
|
|
||||||
FIX_STACK(24,nmi_stack_correct, 1)
|
|
||||||
jmp nmi_stack_correct
|
|
||||||
|
|
||||||
nmi_espfix_stack:
|
|
||||||
/* We have a RING0_INT_FRAME here.
|
|
||||||
*
|
|
||||||
* create the pointer to lss back
|
|
||||||
*/
|
|
||||||
pushl %ss
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
pushl %esp
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
addw $4, (%esp)
|
|
||||||
/* copy the iret frame of 12 bytes */
|
|
||||||
.rept 3
|
|
||||||
pushl 16(%esp)
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
.endr
|
|
||||||
pushl %eax
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
SAVE_ALL
|
|
||||||
TRACE_IRQS_OFF
|
|
||||||
FIXUP_ESPFIX_STACK # %eax == %esp
|
|
||||||
xorl %edx,%edx # zero error code
|
|
||||||
call do_nmi
|
|
||||||
RESTORE_REGS
|
|
||||||
lss 12+4(%esp), %esp # back to espfix stack
|
|
||||||
CFI_ADJUST_CFA_OFFSET -24
|
|
||||||
jmp irq_return
|
|
||||||
CFI_ENDPROC
|
|
||||||
KPROBE_END(nmi)
|
|
||||||
|
|
||||||
#ifdef CONFIG_PARAVIRT
|
#ifdef CONFIG_PARAVIRT
|
||||||
ENTRY(native_iret)
|
ENTRY(native_iret)
|
||||||
iret
|
iret
|
||||||
|
@ -916,19 +733,6 @@ ENTRY(native_irq_enable_sysexit)
|
||||||
END(native_irq_enable_sysexit)
|
END(native_irq_enable_sysexit)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
KPROBE_ENTRY(int3)
|
|
||||||
RING0_INT_FRAME
|
|
||||||
pushl $-1 # mark this as an int
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
SAVE_ALL
|
|
||||||
TRACE_IRQS_OFF
|
|
||||||
xorl %edx,%edx # zero error code
|
|
||||||
movl %esp,%eax # pt_regs pointer
|
|
||||||
call do_int3
|
|
||||||
jmp ret_from_exception
|
|
||||||
CFI_ENDPROC
|
|
||||||
KPROBE_END(int3)
|
|
||||||
|
|
||||||
ENTRY(overflow)
|
ENTRY(overflow)
|
||||||
RING0_INT_FRAME
|
RING0_INT_FRAME
|
||||||
pushl $0
|
pushl $0
|
||||||
|
@ -993,14 +797,6 @@ ENTRY(stack_segment)
|
||||||
CFI_ENDPROC
|
CFI_ENDPROC
|
||||||
END(stack_segment)
|
END(stack_segment)
|
||||||
|
|
||||||
KPROBE_ENTRY(general_protection)
|
|
||||||
RING0_EC_FRAME
|
|
||||||
pushl $do_general_protection
|
|
||||||
CFI_ADJUST_CFA_OFFSET 4
|
|
||||||
jmp error_code
|
|
||||||
CFI_ENDPROC
|
|
||||||
KPROBE_END(general_protection)
|
|
||||||
|
|
||||||
ENTRY(alignment_check)
|
ENTRY(alignment_check)
|
||||||
RING0_EC_FRAME
|
RING0_EC_FRAME
|
||||||
pushl $do_alignment_check
|
pushl $do_alignment_check
|
||||||
|
@ -1211,3 +1007,227 @@ END(mcount)
|
||||||
#include "syscall_table_32.S"
|
#include "syscall_table_32.S"
|
||||||
|
|
||||||
syscall_table_size=(.-sys_call_table)
|
syscall_table_size=(.-sys_call_table)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some functions should be protected against kprobes
|
||||||
|
*/
|
||||||
|
.pushsection .kprobes.text, "ax"
|
||||||
|
|
||||||
|
ENTRY(page_fault)
|
||||||
|
RING0_EC_FRAME
|
||||||
|
pushl $do_page_fault
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
ALIGN
|
||||||
|
error_code:
|
||||||
|
/* the function address is in %fs's slot on the stack */
|
||||||
|
pushl %es
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
/*CFI_REL_OFFSET es, 0*/
|
||||||
|
pushl %ds
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
/*CFI_REL_OFFSET ds, 0*/
|
||||||
|
pushl %eax
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
CFI_REL_OFFSET eax, 0
|
||||||
|
pushl %ebp
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
CFI_REL_OFFSET ebp, 0
|
||||||
|
pushl %edi
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
CFI_REL_OFFSET edi, 0
|
||||||
|
pushl %esi
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
CFI_REL_OFFSET esi, 0
|
||||||
|
pushl %edx
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
CFI_REL_OFFSET edx, 0
|
||||||
|
pushl %ecx
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
CFI_REL_OFFSET ecx, 0
|
||||||
|
pushl %ebx
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
CFI_REL_OFFSET ebx, 0
|
||||||
|
cld
|
||||||
|
pushl %fs
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
/*CFI_REL_OFFSET fs, 0*/
|
||||||
|
movl $(__KERNEL_PERCPU), %ecx
|
||||||
|
movl %ecx, %fs
|
||||||
|
UNWIND_ESPFIX_STACK
|
||||||
|
popl %ecx
|
||||||
|
CFI_ADJUST_CFA_OFFSET -4
|
||||||
|
/*CFI_REGISTER es, ecx*/
|
||||||
|
movl PT_FS(%esp), %edi # get the function address
|
||||||
|
movl PT_ORIG_EAX(%esp), %edx # get the error code
|
||||||
|
movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
|
||||||
|
mov %ecx, PT_FS(%esp)
|
||||||
|
/*CFI_REL_OFFSET fs, ES*/
|
||||||
|
movl $(__USER_DS), %ecx
|
||||||
|
movl %ecx, %ds
|
||||||
|
movl %ecx, %es
|
||||||
|
TRACE_IRQS_OFF
|
||||||
|
movl %esp,%eax # pt_regs pointer
|
||||||
|
call *%edi
|
||||||
|
jmp ret_from_exception
|
||||||
|
CFI_ENDPROC
|
||||||
|
END(page_fault)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Debug traps and NMI can happen at the one SYSENTER instruction
|
||||||
|
* that sets up the real kernel stack. Check here, since we can't
|
||||||
|
* allow the wrong stack to be used.
|
||||||
|
*
|
||||||
|
* "TSS_sysenter_sp0+12" is because the NMI/debug handler will have
|
||||||
|
* already pushed 3 words if it hits on the sysenter instruction:
|
||||||
|
* eflags, cs and eip.
|
||||||
|
*
|
||||||
|
* We just load the right stack, and push the three (known) values
|
||||||
|
* by hand onto the new stack - while updating the return eip past
|
||||||
|
* the instruction that would have done it for sysenter.
|
||||||
|
*/
|
||||||
|
#define FIX_STACK(offset, ok, label) \
|
||||||
|
cmpw $__KERNEL_CS,4(%esp); \
|
||||||
|
jne ok; \
|
||||||
|
label: \
|
||||||
|
movl TSS_sysenter_sp0+offset(%esp),%esp; \
|
||||||
|
CFI_DEF_CFA esp, 0; \
|
||||||
|
CFI_UNDEFINED eip; \
|
||||||
|
pushfl; \
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4; \
|
||||||
|
pushl $__KERNEL_CS; \
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4; \
|
||||||
|
pushl $sysenter_past_esp; \
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4; \
|
||||||
|
CFI_REL_OFFSET eip, 0
|
||||||
|
|
||||||
|
ENTRY(debug)
|
||||||
|
RING0_INT_FRAME
|
||||||
|
cmpl $ia32_sysenter_target,(%esp)
|
||||||
|
jne debug_stack_correct
|
||||||
|
FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
|
||||||
|
debug_stack_correct:
|
||||||
|
pushl $-1 # mark this as an int
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
SAVE_ALL
|
||||||
|
TRACE_IRQS_OFF
|
||||||
|
xorl %edx,%edx # error code 0
|
||||||
|
movl %esp,%eax # pt_regs pointer
|
||||||
|
call do_debug
|
||||||
|
jmp ret_from_exception
|
||||||
|
CFI_ENDPROC
|
||||||
|
END(debug)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NMI is doubly nasty. It can happen _while_ we're handling
|
||||||
|
* a debug fault, and the debug fault hasn't yet been able to
|
||||||
|
* clear up the stack. So we first check whether we got an
|
||||||
|
* NMI on the sysenter entry path, but after that we need to
|
||||||
|
* check whether we got an NMI on the debug path where the debug
|
||||||
|
* fault happened on the sysenter path.
|
||||||
|
*/
|
||||||
|
ENTRY(nmi)
|
||||||
|
RING0_INT_FRAME
|
||||||
|
pushl %eax
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
movl %ss, %eax
|
||||||
|
cmpw $__ESPFIX_SS, %ax
|
||||||
|
popl %eax
|
||||||
|
CFI_ADJUST_CFA_OFFSET -4
|
||||||
|
je nmi_espfix_stack
|
||||||
|
cmpl $ia32_sysenter_target,(%esp)
|
||||||
|
je nmi_stack_fixup
|
||||||
|
pushl %eax
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
movl %esp,%eax
|
||||||
|
/* Do not access memory above the end of our stack page,
|
||||||
|
* it might not exist.
|
||||||
|
*/
|
||||||
|
andl $(THREAD_SIZE-1),%eax
|
||||||
|
cmpl $(THREAD_SIZE-20),%eax
|
||||||
|
popl %eax
|
||||||
|
CFI_ADJUST_CFA_OFFSET -4
|
||||||
|
jae nmi_stack_correct
|
||||||
|
cmpl $ia32_sysenter_target,12(%esp)
|
||||||
|
je nmi_debug_stack_check
|
||||||
|
nmi_stack_correct:
|
||||||
|
/* We have a RING0_INT_FRAME here */
|
||||||
|
pushl %eax
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
SAVE_ALL
|
||||||
|
TRACE_IRQS_OFF
|
||||||
|
xorl %edx,%edx # zero error code
|
||||||
|
movl %esp,%eax # pt_regs pointer
|
||||||
|
call do_nmi
|
||||||
|
jmp restore_nocheck_notrace
|
||||||
|
CFI_ENDPROC
|
||||||
|
|
||||||
|
nmi_stack_fixup:
|
||||||
|
RING0_INT_FRAME
|
||||||
|
FIX_STACK(12,nmi_stack_correct, 1)
|
||||||
|
jmp nmi_stack_correct
|
||||||
|
|
||||||
|
nmi_debug_stack_check:
|
||||||
|
/* We have a RING0_INT_FRAME here */
|
||||||
|
cmpw $__KERNEL_CS,16(%esp)
|
||||||
|
jne nmi_stack_correct
|
||||||
|
cmpl $debug,(%esp)
|
||||||
|
jb nmi_stack_correct
|
||||||
|
cmpl $debug_esp_fix_insn,(%esp)
|
||||||
|
ja nmi_stack_correct
|
||||||
|
FIX_STACK(24,nmi_stack_correct, 1)
|
||||||
|
jmp nmi_stack_correct
|
||||||
|
|
||||||
|
nmi_espfix_stack:
|
||||||
|
/* We have a RING0_INT_FRAME here.
|
||||||
|
*
|
||||||
|
* create the pointer to lss back
|
||||||
|
*/
|
||||||
|
pushl %ss
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
pushl %esp
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
addw $4, (%esp)
|
||||||
|
/* copy the iret frame of 12 bytes */
|
||||||
|
.rept 3
|
||||||
|
pushl 16(%esp)
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
.endr
|
||||||
|
pushl %eax
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
SAVE_ALL
|
||||||
|
TRACE_IRQS_OFF
|
||||||
|
FIXUP_ESPFIX_STACK # %eax == %esp
|
||||||
|
xorl %edx,%edx # zero error code
|
||||||
|
call do_nmi
|
||||||
|
RESTORE_REGS
|
||||||
|
lss 12+4(%esp), %esp # back to espfix stack
|
||||||
|
CFI_ADJUST_CFA_OFFSET -24
|
||||||
|
jmp irq_return
|
||||||
|
CFI_ENDPROC
|
||||||
|
END(nmi)
|
||||||
|
|
||||||
|
ENTRY(int3)
|
||||||
|
RING0_INT_FRAME
|
||||||
|
pushl $-1 # mark this as an int
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
SAVE_ALL
|
||||||
|
TRACE_IRQS_OFF
|
||||||
|
xorl %edx,%edx # zero error code
|
||||||
|
movl %esp,%eax # pt_regs pointer
|
||||||
|
call do_int3
|
||||||
|
jmp ret_from_exception
|
||||||
|
CFI_ENDPROC
|
||||||
|
END(int3)
|
||||||
|
|
||||||
|
ENTRY(general_protection)
|
||||||
|
RING0_EC_FRAME
|
||||||
|
pushl $do_general_protection
|
||||||
|
CFI_ADJUST_CFA_OFFSET 4
|
||||||
|
jmp error_code
|
||||||
|
CFI_ENDPROC
|
||||||
|
END(general_protection)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* End of kprobes section
|
||||||
|
*/
|
||||||
|
.popsection
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -129,7 +129,7 @@ void __init native_init_IRQ(void)
|
||||||
for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) {
|
for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) {
|
||||||
/* SYSCALL_VECTOR was reserved in trap_init. */
|
/* SYSCALL_VECTOR was reserved in trap_init. */
|
||||||
if (i != SYSCALL_VECTOR)
|
if (i != SYSCALL_VECTOR)
|
||||||
set_intr_gate(i, interrupt[i]);
|
set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,41 +23,6 @@
|
||||||
#include <asm/apic.h>
|
#include <asm/apic.h>
|
||||||
#include <asm/i8259.h>
|
#include <asm/i8259.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* Common place to define all x86 IRQ vectors
|
|
||||||
*
|
|
||||||
* This builds up the IRQ handler stubs using some ugly macros in irq.h
|
|
||||||
*
|
|
||||||
* These macros create the low-level assembly IRQ routines that save
|
|
||||||
* register context and call do_IRQ(). do_IRQ() then does all the
|
|
||||||
* operations that are needed to keep the AT (or SMP IOAPIC)
|
|
||||||
* interrupt-controller happy.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define IRQ_NAME2(nr) nr##_interrupt(void)
|
|
||||||
#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SMP has a few special interrupts for IPI messages
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BUILD_IRQ(nr) \
|
|
||||||
asmlinkage void IRQ_NAME(nr); \
|
|
||||||
asm("\n.text\n.p2align\n" \
|
|
||||||
"IRQ" #nr "_interrupt:\n\t" \
|
|
||||||
"push $~(" #nr ") ; " \
|
|
||||||
"jmp common_interrupt\n" \
|
|
||||||
".previous");
|
|
||||||
|
|
||||||
#define BI(x,y) \
|
|
||||||
BUILD_IRQ(x##y)
|
|
||||||
|
|
||||||
#define BUILD_16_IRQS(x) \
|
|
||||||
BI(x,0) BI(x,1) BI(x,2) BI(x,3) \
|
|
||||||
BI(x,4) BI(x,5) BI(x,6) BI(x,7) \
|
|
||||||
BI(x,8) BI(x,9) BI(x,a) BI(x,b) \
|
|
||||||
BI(x,c) BI(x,d) BI(x,e) BI(x,f)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts:
|
* ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts:
|
||||||
* (these are usually mapped to vectors 0x30-0x3f)
|
* (these are usually mapped to vectors 0x30-0x3f)
|
||||||
|
@ -73,37 +38,6 @@
|
||||||
*
|
*
|
||||||
* (these are usually mapped into the 0x30-0xff vector range)
|
* (these are usually mapped into the 0x30-0xff vector range)
|
||||||
*/
|
*/
|
||||||
BUILD_16_IRQS(0x2) BUILD_16_IRQS(0x3)
|
|
||||||
BUILD_16_IRQS(0x4) BUILD_16_IRQS(0x5) BUILD_16_IRQS(0x6) BUILD_16_IRQS(0x7)
|
|
||||||
BUILD_16_IRQS(0x8) BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb)
|
|
||||||
BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) BUILD_16_IRQS(0xe) BUILD_16_IRQS(0xf)
|
|
||||||
|
|
||||||
#undef BUILD_16_IRQS
|
|
||||||
#undef BI
|
|
||||||
|
|
||||||
|
|
||||||
#define IRQ(x,y) \
|
|
||||||
IRQ##x##y##_interrupt
|
|
||||||
|
|
||||||
#define IRQLIST_16(x) \
|
|
||||||
IRQ(x,0), IRQ(x,1), IRQ(x,2), IRQ(x,3), \
|
|
||||||
IRQ(x,4), IRQ(x,5), IRQ(x,6), IRQ(x,7), \
|
|
||||||
IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \
|
|
||||||
IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f)
|
|
||||||
|
|
||||||
/* for the irq vectors */
|
|
||||||
static void (*__initdata interrupt[NR_VECTORS - FIRST_EXTERNAL_VECTOR])(void) = {
|
|
||||||
IRQLIST_16(0x2), IRQLIST_16(0x3),
|
|
||||||
IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7),
|
|
||||||
IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb),
|
|
||||||
IRQLIST_16(0xc), IRQLIST_16(0xd), IRQLIST_16(0xe), IRQLIST_16(0xf)
|
|
||||||
};
|
|
||||||
|
|
||||||
#undef IRQ
|
|
||||||
#undef IRQLIST_16
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IRQ2 is cascade interrupt to second interrupt controller
|
* IRQ2 is cascade interrupt to second interrupt controller
|
||||||
|
|
|
@ -165,11 +165,7 @@ static void native_smp_send_stop(void)
|
||||||
void smp_reschedule_interrupt(struct pt_regs *regs)
|
void smp_reschedule_interrupt(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
ack_APIC_irq();
|
ack_APIC_irq();
|
||||||
#ifdef CONFIG_X86_32
|
inc_irq_stat(irq_resched_count);
|
||||||
__get_cpu_var(irq_stat).irq_resched_count++;
|
|
||||||
#else
|
|
||||||
add_pda(irq_resched_count, 1);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void smp_call_function_interrupt(struct pt_regs *regs)
|
void smp_call_function_interrupt(struct pt_regs *regs)
|
||||||
|
@ -177,11 +173,7 @@ void smp_call_function_interrupt(struct pt_regs *regs)
|
||||||
ack_APIC_irq();
|
ack_APIC_irq();
|
||||||
irq_enter();
|
irq_enter();
|
||||||
generic_smp_call_function_interrupt();
|
generic_smp_call_function_interrupt();
|
||||||
#ifdef CONFIG_X86_32
|
inc_irq_stat(irq_call_count);
|
||||||
__get_cpu_var(irq_stat).irq_call_count++;
|
|
||||||
#else
|
|
||||||
add_pda(irq_call_count, 1);
|
|
||||||
#endif
|
|
||||||
irq_exit();
|
irq_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,11 +182,7 @@ void smp_call_function_single_interrupt(struct pt_regs *regs)
|
||||||
ack_APIC_irq();
|
ack_APIC_irq();
|
||||||
irq_enter();
|
irq_enter();
|
||||||
generic_smp_call_function_single_interrupt();
|
generic_smp_call_function_single_interrupt();
|
||||||
#ifdef CONFIG_X86_32
|
inc_irq_stat(irq_call_count);
|
||||||
__get_cpu_var(irq_stat).irq_call_count++;
|
|
||||||
#else
|
|
||||||
add_pda(irq_call_count, 1);
|
|
||||||
#endif
|
|
||||||
irq_exit();
|
irq_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ EXPORT_SYMBOL(profile_pc);
|
||||||
irqreturn_t timer_interrupt(int irq, void *dev_id)
|
irqreturn_t timer_interrupt(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
/* Keep nmi watchdog up to date */
|
/* Keep nmi watchdog up to date */
|
||||||
per_cpu(irq_stat, smp_processor_id()).irq0_irqs++;
|
inc_irq_stat(irq0_irqs);
|
||||||
|
|
||||||
#ifdef CONFIG_X86_IO_APIC
|
#ifdef CONFIG_X86_IO_APIC
|
||||||
if (timer_ack) {
|
if (timer_ack) {
|
||||||
|
|
|
@ -51,7 +51,7 @@ EXPORT_SYMBOL(profile_pc);
|
||||||
|
|
||||||
static irqreturn_t timer_interrupt(int irq, void *dev_id)
|
static irqreturn_t timer_interrupt(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
add_pda(irq0_irqs, 1);
|
inc_irq_stat(irq0_irqs);
|
||||||
|
|
||||||
global_clock_event->event_handler(global_clock_event);
|
global_clock_event->event_handler(global_clock_event);
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ void smp_invalidate_interrupt(struct pt_regs *regs)
|
||||||
smp_mb__after_clear_bit();
|
smp_mb__after_clear_bit();
|
||||||
out:
|
out:
|
||||||
put_cpu_no_resched();
|
put_cpu_no_resched();
|
||||||
__get_cpu_var(irq_stat).irq_tlb_count++;
|
inc_irq_stat(irq_tlb_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
|
void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
|
||||||
|
|
|
@ -154,7 +154,7 @@ asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs)
|
||||||
out:
|
out:
|
||||||
ack_APIC_irq();
|
ack_APIC_irq();
|
||||||
cpu_clear(cpu, f->flush_cpumask);
|
cpu_clear(cpu, f->flush_cpumask);
|
||||||
add_pda(irq_tlb_count, 1);
|
inc_irq_stat(irq_tlb_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
|
void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
|
||||||
|
|
|
@ -481,11 +481,7 @@ do_nmi(struct pt_regs *regs, long error_code)
|
||||||
{
|
{
|
||||||
nmi_enter();
|
nmi_enter();
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
inc_irq_stat(__nmi_count);
|
||||||
{ int cpu; cpu = smp_processor_id(); ++nmi_count(cpu); }
|
|
||||||
#else
|
|
||||||
add_pda(__nmi_count, 1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!ignore_nmis)
|
if (!ignore_nmis)
|
||||||
default_do_nmi(regs);
|
default_do_nmi(regs);
|
||||||
|
|
|
@ -590,7 +590,8 @@ static void __init lguest_init_IRQ(void)
|
||||||
* a straightforward 1 to 1 mapping, so force that here. */
|
* a straightforward 1 to 1 mapping, so force that here. */
|
||||||
__get_cpu_var(vector_irq)[vector] = i;
|
__get_cpu_var(vector_irq)[vector] = i;
|
||||||
if (vector != SYSCALL_VECTOR) {
|
if (vector != SYSCALL_VECTOR) {
|
||||||
set_intr_gate(vector, interrupt[vector]);
|
set_intr_gate(vector,
|
||||||
|
interrupt[vector-FIRST_EXTERNAL_VECTOR]);
|
||||||
set_irq_chip_and_handler_name(i, &lguest_irq_controller,
|
set_irq_chip_and_handler_name(i, &lguest_irq_controller,
|
||||||
handle_level_irq,
|
handle_level_irq,
|
||||||
"level");
|
"level");
|
||||||
|
|
|
@ -64,14 +64,6 @@
|
||||||
name:
|
name:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define KPROBE_ENTRY(name) \
|
|
||||||
.pushsection .kprobes.text, "ax"; \
|
|
||||||
ENTRY(name)
|
|
||||||
|
|
||||||
#define KPROBE_END(name) \
|
|
||||||
END(name); \
|
|
||||||
.popsection
|
|
||||||
|
|
||||||
#ifndef END
|
#ifndef END
|
||||||
#define END(name) \
|
#define END(name) \
|
||||||
.size name, .-name
|
.size name, .-name
|
||||||
|
|
Reference in New Issue