1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
#ifndef __X86_64_ASM_DEFNS_H__
#define __X86_64_ASM_DEFNS_H__
#include <asm/percpu.h>
#ifdef CONFIG_FRAME_POINTER
/* Indicate special exception stack frame by inverting the frame pointer. */
#define SETUP_EXCEPTION_FRAME_POINTER \
movq %rsp,%rbp; \
notq %rbp
#else
#define SETUP_EXCEPTION_FRAME_POINTER
#endif
#ifndef NDEBUG
#define ASSERT_INTERRUPT_STATUS(x) \
pushf; \
testb $X86_EFLAGS_IF>>8,1(%rsp); \
j##x 1f; \
ud2a; \
1: addq $8,%rsp;
#else
#define ASSERT_INTERRUPT_STATUS(x)
#endif
#define ASSERT_INTERRUPTS_ENABLED ASSERT_INTERRUPT_STATUS(nz)
#define ASSERT_INTERRUPTS_DISABLED ASSERT_INTERRUPT_STATUS(z)
#define SAVE_ALL \
cld; \
pushq %rdi; \
pushq %rsi; \
pushq %rdx; \
pushq %rcx; \
pushq %rax; \
pushq %r8; \
pushq %r9; \
pushq %r10; \
pushq %r11; \
pushq %rbx; \
pushq %rbp; \
SETUP_EXCEPTION_FRAME_POINTER; \
pushq %r12; \
pushq %r13; \
pushq %r14; \
pushq %r15;
#define RESTORE_ALL \
popq %r15; \
popq %r14; \
popq %r13; \
popq %r12; \
popq %rbp; \
popq %rbx; \
popq %r11; \
popq %r10; \
popq %r9; \
popq %r8; \
popq %rax; \
popq %rcx; \
popq %rdx; \
popq %rsi; \
popq %rdi;
#ifdef PERF_COUNTERS
#define PERFC_INCR(_name,_idx,_cur) \
pushq _cur; \
movslq VCPU_processor(_cur),_cur; \
pushq %rdx; \
leaq per_cpu__perfcounters(%rip),%rdx; \
shlq $PERCPU_SHIFT,_cur; \
addq %rdx,_cur; \
popq %rdx; \
incl ASM_PERFC_##_name*4(_cur,_idx,4); \
popq _cur
#else
#define PERFC_INCR(_name,_idx,_cur)
#endif
/* Work around AMD erratum #88 */
#define safe_swapgs \
"mfence; swapgs;"
#ifdef __sun__
#define REX64_PREFIX "rex64\\"
#else
#define REX64_PREFIX "rex64/"
#endif
#define BUILD_SMP_INTERRUPT(x,v) XBUILD_SMP_INTERRUPT(x,v)
#define XBUILD_SMP_INTERRUPT(x,v) \
__asm__( \
"\n"__ALIGN_STR"\n" \
".globl " STR(x) "\n\t" \
STR(x) ":\n\t" \
"pushq $0\n\t" \
"movl $"#v",4(%rsp)\n\t" \
STR(SAVE_ALL) \
"movq %rsp,%rdi\n\t" \
"callq "STR(smp_##x)"\n\t" \
"jmp ret_from_intr\n");
#define BUILD_COMMON_IRQ() \
__asm__( \
"\n" __ALIGN_STR"\n" \
"common_interrupt:\n\t" \
STR(SAVE_ALL) \
"movq %rsp,%rdi\n\t" \
"callq " STR(do_IRQ) "\n\t" \
"jmp ret_from_intr\n");
#define IRQ_NAME2(nr) nr##_interrupt(void)
#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
#define BUILD_IRQ(nr) \
asmlinkage void IRQ_NAME(nr); \
__asm__( \
"\n"__ALIGN_STR"\n" \
STR(IRQ) #nr "_interrupt:\n\t" \
"pushq $0\n\t" \
"movl $"#nr",4(%rsp)\n\t" \
"jmp common_interrupt");
#endif /* __X86_64_ASM_DEFNS_H__ */
|