Commit a1f3bb9ae4497a2ed3eac773fd7798ac33a0371f

Authored by Roland McGrath
Committed by Linus Torvalds
1 parent 7f6ee1adc7

[PATCH] Fix CONFIG_COMPAT_VDSO

I wouldn't mind if CONFIG_COMPAT_VDSO went away entirely.  But if it's there,
it should work properly.  Currently it's quite haphazard: both real vma and
fixmap are mapped, both are put in the two different AT_* slots, sysenter
returns to the vma address rather than the fixmap address, and core dumps yet
are another story.

This patch makes CONFIG_COMPAT_VDSO disable the real vma and use the fixmap
area consistently.  This makes it actually compatible with what the old vdso
implementation did.

Signed-off-by: Roland McGrath <roland@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 5 changed files with 13 additions and 4 deletions Inline Diff

arch/i386/kernel/entry.S
1 /* 1 /*
2 * linux/arch/i386/entry.S 2 * linux/arch/i386/entry.S
3 * 3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds 4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */ 5 */
6 6
7 /* 7 /*
8 * entry.S contains the system-call and fault low-level handling routines. 8 * entry.S contains the system-call and fault low-level handling routines.
9 * This also contains the timer-interrupt handler, as well as all interrupts 9 * This also contains the timer-interrupt handler, as well as all interrupts
10 * and faults that can result in a task-switch. 10 * and faults that can result in a task-switch.
11 * 11 *
12 * NOTE: This code handles signal-recognition, which happens every time 12 * NOTE: This code handles signal-recognition, which happens every time
13 * after a timer-interrupt and after each system call. 13 * after a timer-interrupt and after each system call.
14 * 14 *
15 * I changed all the .align's to 4 (16 byte alignment), as that's faster 15 * I changed all the .align's to 4 (16 byte alignment), as that's faster
16 * on a 486. 16 * on a 486.
17 * 17 *
18 * Stack layout in 'ret_from_system_call': 18 * Stack layout in 'ret_from_system_call':
19 * ptrace needs to have all regs on the stack. 19 * ptrace needs to have all regs on the stack.
20 * if the order here is changed, it needs to be 20 * if the order here is changed, it needs to be
21 * updated in fork.c:copy_process, signal.c:do_signal, 21 * updated in fork.c:copy_process, signal.c:do_signal,
22 * ptrace.c and ptrace.h 22 * ptrace.c and ptrace.h
23 * 23 *
24 * 0(%esp) - %ebx 24 * 0(%esp) - %ebx
25 * 4(%esp) - %ecx 25 * 4(%esp) - %ecx
26 * 8(%esp) - %edx 26 * 8(%esp) - %edx
27 * C(%esp) - %esi 27 * C(%esp) - %esi
28 * 10(%esp) - %edi 28 * 10(%esp) - %edi
29 * 14(%esp) - %ebp 29 * 14(%esp) - %ebp
30 * 18(%esp) - %eax 30 * 18(%esp) - %eax
31 * 1C(%esp) - %ds 31 * 1C(%esp) - %ds
32 * 20(%esp) - %es 32 * 20(%esp) - %es
33 * 24(%esp) - %gs 33 * 24(%esp) - %gs
34 * 28(%esp) - orig_eax 34 * 28(%esp) - orig_eax
35 * 2C(%esp) - %eip 35 * 2C(%esp) - %eip
36 * 30(%esp) - %cs 36 * 30(%esp) - %cs
37 * 34(%esp) - %eflags 37 * 34(%esp) - %eflags
38 * 38(%esp) - %oldesp 38 * 38(%esp) - %oldesp
39 * 3C(%esp) - %oldss 39 * 3C(%esp) - %oldss
40 * 40 *
41 * "current" is in register %ebx during any slow entries. 41 * "current" is in register %ebx during any slow entries.
42 */ 42 */
43 43
44 #include <linux/linkage.h> 44 #include <linux/linkage.h>
45 #include <asm/thread_info.h> 45 #include <asm/thread_info.h>
46 #include <asm/irqflags.h> 46 #include <asm/irqflags.h>
47 #include <asm/errno.h> 47 #include <asm/errno.h>
48 #include <asm/segment.h> 48 #include <asm/segment.h>
49 #include <asm/smp.h> 49 #include <asm/smp.h>
50 #include <asm/page.h> 50 #include <asm/page.h>
51 #include <asm/desc.h> 51 #include <asm/desc.h>
52 #include <asm/percpu.h> 52 #include <asm/percpu.h>
53 #include <asm/dwarf2.h> 53 #include <asm/dwarf2.h>
54 #include "irq_vectors.h" 54 #include "irq_vectors.h"
55 55
56 /* 56 /*
57 * We use macros for low-level operations which need to be overridden 57 * We use macros for low-level operations which need to be overridden
58 * for paravirtualization. The following will never clobber any registers: 58 * for paravirtualization. The following will never clobber any registers:
59 * INTERRUPT_RETURN (aka. "iret") 59 * INTERRUPT_RETURN (aka. "iret")
60 * GET_CR0_INTO_EAX (aka. "movl %cr0, %eax") 60 * GET_CR0_INTO_EAX (aka. "movl %cr0, %eax")
61 * ENABLE_INTERRUPTS_SYSEXIT (aka "sti; sysexit"). 61 * ENABLE_INTERRUPTS_SYSEXIT (aka "sti; sysexit").
62 * 62 *
63 * For DISABLE_INTERRUPTS/ENABLE_INTERRUPTS (aka "cli"/"sti"), you must 63 * For DISABLE_INTERRUPTS/ENABLE_INTERRUPTS (aka "cli"/"sti"), you must
64 * specify what registers can be overwritten (CLBR_NONE, CLBR_EAX/EDX/ECX/ANY). 64 * specify what registers can be overwritten (CLBR_NONE, CLBR_EAX/EDX/ECX/ANY).
65 * Allowing a register to be clobbered can shrink the paravirt replacement 65 * Allowing a register to be clobbered can shrink the paravirt replacement
66 * enough to patch inline, increasing performance. 66 * enough to patch inline, increasing performance.
67 */ 67 */
68 68
69 #define nr_syscalls ((syscall_table_size)/4) 69 #define nr_syscalls ((syscall_table_size)/4)
70 70
71 CF_MASK = 0x00000001 71 CF_MASK = 0x00000001
72 TF_MASK = 0x00000100 72 TF_MASK = 0x00000100
73 IF_MASK = 0x00000200 73 IF_MASK = 0x00000200
74 DF_MASK = 0x00000400 74 DF_MASK = 0x00000400
75 NT_MASK = 0x00004000 75 NT_MASK = 0x00004000
76 VM_MASK = 0x00020000 76 VM_MASK = 0x00020000
77 77
78 #ifdef CONFIG_PREEMPT 78 #ifdef CONFIG_PREEMPT
79 #define preempt_stop(clobbers) DISABLE_INTERRUPTS(clobbers); TRACE_IRQS_OFF 79 #define preempt_stop(clobbers) DISABLE_INTERRUPTS(clobbers); TRACE_IRQS_OFF
80 #else 80 #else
81 #define preempt_stop(clobbers) 81 #define preempt_stop(clobbers)
82 #define resume_kernel restore_nocheck 82 #define resume_kernel restore_nocheck
83 #endif 83 #endif
84 84
85 .macro TRACE_IRQS_IRET 85 .macro TRACE_IRQS_IRET
86 #ifdef CONFIG_TRACE_IRQFLAGS 86 #ifdef CONFIG_TRACE_IRQFLAGS
87 testl $IF_MASK,PT_EFLAGS(%esp) # interrupts off? 87 testl $IF_MASK,PT_EFLAGS(%esp) # interrupts off?
88 jz 1f 88 jz 1f
89 TRACE_IRQS_ON 89 TRACE_IRQS_ON
90 1: 90 1:
91 #endif 91 #endif
92 .endm 92 .endm
93 93
94 #ifdef CONFIG_VM86 94 #ifdef CONFIG_VM86
95 #define resume_userspace_sig check_userspace 95 #define resume_userspace_sig check_userspace
96 #else 96 #else
97 #define resume_userspace_sig resume_userspace 97 #define resume_userspace_sig resume_userspace
98 #endif 98 #endif
99 99
100 #define SAVE_ALL \ 100 #define SAVE_ALL \
101 cld; \ 101 cld; \
102 pushl %gs; \ 102 pushl %gs; \
103 CFI_ADJUST_CFA_OFFSET 4;\ 103 CFI_ADJUST_CFA_OFFSET 4;\
104 /*CFI_REL_OFFSET gs, 0;*/\ 104 /*CFI_REL_OFFSET gs, 0;*/\
105 pushl %es; \ 105 pushl %es; \
106 CFI_ADJUST_CFA_OFFSET 4;\ 106 CFI_ADJUST_CFA_OFFSET 4;\
107 /*CFI_REL_OFFSET es, 0;*/\ 107 /*CFI_REL_OFFSET es, 0;*/\
108 pushl %ds; \ 108 pushl %ds; \
109 CFI_ADJUST_CFA_OFFSET 4;\ 109 CFI_ADJUST_CFA_OFFSET 4;\
110 /*CFI_REL_OFFSET ds, 0;*/\ 110 /*CFI_REL_OFFSET ds, 0;*/\
111 pushl %eax; \ 111 pushl %eax; \
112 CFI_ADJUST_CFA_OFFSET 4;\ 112 CFI_ADJUST_CFA_OFFSET 4;\
113 CFI_REL_OFFSET eax, 0;\ 113 CFI_REL_OFFSET eax, 0;\
114 pushl %ebp; \ 114 pushl %ebp; \
115 CFI_ADJUST_CFA_OFFSET 4;\ 115 CFI_ADJUST_CFA_OFFSET 4;\
116 CFI_REL_OFFSET ebp, 0;\ 116 CFI_REL_OFFSET ebp, 0;\
117 pushl %edi; \ 117 pushl %edi; \
118 CFI_ADJUST_CFA_OFFSET 4;\ 118 CFI_ADJUST_CFA_OFFSET 4;\
119 CFI_REL_OFFSET edi, 0;\ 119 CFI_REL_OFFSET edi, 0;\
120 pushl %esi; \ 120 pushl %esi; \
121 CFI_ADJUST_CFA_OFFSET 4;\ 121 CFI_ADJUST_CFA_OFFSET 4;\
122 CFI_REL_OFFSET esi, 0;\ 122 CFI_REL_OFFSET esi, 0;\
123 pushl %edx; \ 123 pushl %edx; \
124 CFI_ADJUST_CFA_OFFSET 4;\ 124 CFI_ADJUST_CFA_OFFSET 4;\
125 CFI_REL_OFFSET edx, 0;\ 125 CFI_REL_OFFSET edx, 0;\
126 pushl %ecx; \ 126 pushl %ecx; \
127 CFI_ADJUST_CFA_OFFSET 4;\ 127 CFI_ADJUST_CFA_OFFSET 4;\
128 CFI_REL_OFFSET ecx, 0;\ 128 CFI_REL_OFFSET ecx, 0;\
129 pushl %ebx; \ 129 pushl %ebx; \
130 CFI_ADJUST_CFA_OFFSET 4;\ 130 CFI_ADJUST_CFA_OFFSET 4;\
131 CFI_REL_OFFSET ebx, 0;\ 131 CFI_REL_OFFSET ebx, 0;\
132 movl $(__USER_DS), %edx; \ 132 movl $(__USER_DS), %edx; \
133 movl %edx, %ds; \ 133 movl %edx, %ds; \
134 movl %edx, %es; \ 134 movl %edx, %es; \
135 movl $(__KERNEL_PDA), %edx; \ 135 movl $(__KERNEL_PDA), %edx; \
136 movl %edx, %gs 136 movl %edx, %gs
137 137
138 #define RESTORE_INT_REGS \ 138 #define RESTORE_INT_REGS \
139 popl %ebx; \ 139 popl %ebx; \
140 CFI_ADJUST_CFA_OFFSET -4;\ 140 CFI_ADJUST_CFA_OFFSET -4;\
141 CFI_RESTORE ebx;\ 141 CFI_RESTORE ebx;\
142 popl %ecx; \ 142 popl %ecx; \
143 CFI_ADJUST_CFA_OFFSET -4;\ 143 CFI_ADJUST_CFA_OFFSET -4;\
144 CFI_RESTORE ecx;\ 144 CFI_RESTORE ecx;\
145 popl %edx; \ 145 popl %edx; \
146 CFI_ADJUST_CFA_OFFSET -4;\ 146 CFI_ADJUST_CFA_OFFSET -4;\
147 CFI_RESTORE edx;\ 147 CFI_RESTORE edx;\
148 popl %esi; \ 148 popl %esi; \
149 CFI_ADJUST_CFA_OFFSET -4;\ 149 CFI_ADJUST_CFA_OFFSET -4;\
150 CFI_RESTORE esi;\ 150 CFI_RESTORE esi;\
151 popl %edi; \ 151 popl %edi; \
152 CFI_ADJUST_CFA_OFFSET -4;\ 152 CFI_ADJUST_CFA_OFFSET -4;\
153 CFI_RESTORE edi;\ 153 CFI_RESTORE edi;\
154 popl %ebp; \ 154 popl %ebp; \
155 CFI_ADJUST_CFA_OFFSET -4;\ 155 CFI_ADJUST_CFA_OFFSET -4;\
156 CFI_RESTORE ebp;\ 156 CFI_RESTORE ebp;\
157 popl %eax; \ 157 popl %eax; \
158 CFI_ADJUST_CFA_OFFSET -4;\ 158 CFI_ADJUST_CFA_OFFSET -4;\
159 CFI_RESTORE eax 159 CFI_RESTORE eax
160 160
161 #define RESTORE_REGS \ 161 #define RESTORE_REGS \
162 RESTORE_INT_REGS; \ 162 RESTORE_INT_REGS; \
163 1: popl %ds; \ 163 1: popl %ds; \
164 CFI_ADJUST_CFA_OFFSET -4;\ 164 CFI_ADJUST_CFA_OFFSET -4;\
165 /*CFI_RESTORE ds;*/\ 165 /*CFI_RESTORE ds;*/\
166 2: popl %es; \ 166 2: popl %es; \
167 CFI_ADJUST_CFA_OFFSET -4;\ 167 CFI_ADJUST_CFA_OFFSET -4;\
168 /*CFI_RESTORE es;*/\ 168 /*CFI_RESTORE es;*/\
169 3: popl %gs; \ 169 3: popl %gs; \
170 CFI_ADJUST_CFA_OFFSET -4;\ 170 CFI_ADJUST_CFA_OFFSET -4;\
171 /*CFI_RESTORE gs;*/\ 171 /*CFI_RESTORE gs;*/\
172 .pushsection .fixup,"ax"; \ 172 .pushsection .fixup,"ax"; \
173 4: movl $0,(%esp); \ 173 4: movl $0,(%esp); \
174 jmp 1b; \ 174 jmp 1b; \
175 5: movl $0,(%esp); \ 175 5: movl $0,(%esp); \
176 jmp 2b; \ 176 jmp 2b; \
177 6: movl $0,(%esp); \ 177 6: movl $0,(%esp); \
178 jmp 3b; \ 178 jmp 3b; \
179 .section __ex_table,"a";\ 179 .section __ex_table,"a";\
180 .align 4; \ 180 .align 4; \
181 .long 1b,4b; \ 181 .long 1b,4b; \
182 .long 2b,5b; \ 182 .long 2b,5b; \
183 .long 3b,6b; \ 183 .long 3b,6b; \
184 .popsection 184 .popsection
185 185
186 #define RING0_INT_FRAME \ 186 #define RING0_INT_FRAME \
187 CFI_STARTPROC simple;\ 187 CFI_STARTPROC simple;\
188 CFI_SIGNAL_FRAME;\ 188 CFI_SIGNAL_FRAME;\
189 CFI_DEF_CFA esp, 3*4;\ 189 CFI_DEF_CFA esp, 3*4;\
190 /*CFI_OFFSET cs, -2*4;*/\ 190 /*CFI_OFFSET cs, -2*4;*/\
191 CFI_OFFSET eip, -3*4 191 CFI_OFFSET eip, -3*4
192 192
193 #define RING0_EC_FRAME \ 193 #define RING0_EC_FRAME \
194 CFI_STARTPROC simple;\ 194 CFI_STARTPROC simple;\
195 CFI_SIGNAL_FRAME;\ 195 CFI_SIGNAL_FRAME;\
196 CFI_DEF_CFA esp, 4*4;\ 196 CFI_DEF_CFA esp, 4*4;\
197 /*CFI_OFFSET cs, -2*4;*/\ 197 /*CFI_OFFSET cs, -2*4;*/\
198 CFI_OFFSET eip, -3*4 198 CFI_OFFSET eip, -3*4
199 199
200 #define RING0_PTREGS_FRAME \ 200 #define RING0_PTREGS_FRAME \
201 CFI_STARTPROC simple;\ 201 CFI_STARTPROC simple;\
202 CFI_SIGNAL_FRAME;\ 202 CFI_SIGNAL_FRAME;\
203 CFI_DEF_CFA esp, PT_OLDESP-PT_EBX;\ 203 CFI_DEF_CFA esp, PT_OLDESP-PT_EBX;\
204 /*CFI_OFFSET cs, PT_CS-PT_OLDESP;*/\ 204 /*CFI_OFFSET cs, PT_CS-PT_OLDESP;*/\
205 CFI_OFFSET eip, PT_EIP-PT_OLDESP;\ 205 CFI_OFFSET eip, PT_EIP-PT_OLDESP;\
206 /*CFI_OFFSET es, PT_ES-PT_OLDESP;*/\ 206 /*CFI_OFFSET es, PT_ES-PT_OLDESP;*/\
207 /*CFI_OFFSET ds, PT_DS-PT_OLDESP;*/\ 207 /*CFI_OFFSET ds, PT_DS-PT_OLDESP;*/\
208 CFI_OFFSET eax, PT_EAX-PT_OLDESP;\ 208 CFI_OFFSET eax, PT_EAX-PT_OLDESP;\
209 CFI_OFFSET ebp, PT_EBP-PT_OLDESP;\ 209 CFI_OFFSET ebp, PT_EBP-PT_OLDESP;\
210 CFI_OFFSET edi, PT_EDI-PT_OLDESP;\ 210 CFI_OFFSET edi, PT_EDI-PT_OLDESP;\
211 CFI_OFFSET esi, PT_ESI-PT_OLDESP;\ 211 CFI_OFFSET esi, PT_ESI-PT_OLDESP;\
212 CFI_OFFSET edx, PT_EDX-PT_OLDESP;\ 212 CFI_OFFSET edx, PT_EDX-PT_OLDESP;\
213 CFI_OFFSET ecx, PT_ECX-PT_OLDESP;\ 213 CFI_OFFSET ecx, PT_ECX-PT_OLDESP;\
214 CFI_OFFSET ebx, PT_EBX-PT_OLDESP 214 CFI_OFFSET ebx, PT_EBX-PT_OLDESP
215 215
216 ENTRY(ret_from_fork) 216 ENTRY(ret_from_fork)
217 CFI_STARTPROC 217 CFI_STARTPROC
218 pushl %eax 218 pushl %eax
219 CFI_ADJUST_CFA_OFFSET 4 219 CFI_ADJUST_CFA_OFFSET 4
220 call schedule_tail 220 call schedule_tail
221 GET_THREAD_INFO(%ebp) 221 GET_THREAD_INFO(%ebp)
222 popl %eax 222 popl %eax
223 CFI_ADJUST_CFA_OFFSET -4 223 CFI_ADJUST_CFA_OFFSET -4
224 pushl $0x0202 # Reset kernel eflags 224 pushl $0x0202 # Reset kernel eflags
225 CFI_ADJUST_CFA_OFFSET 4 225 CFI_ADJUST_CFA_OFFSET 4
226 popfl 226 popfl
227 CFI_ADJUST_CFA_OFFSET -4 227 CFI_ADJUST_CFA_OFFSET -4
228 jmp syscall_exit 228 jmp syscall_exit
229 CFI_ENDPROC 229 CFI_ENDPROC
230 230
231 /* 231 /*
232 * Return to user mode is not as complex as all this looks, 232 * Return to user mode is not as complex as all this looks,
233 * but we want the default path for a system call return to 233 * but we want the default path for a system call return to
234 * go as quickly as possible which is why some of this is 234 * go as quickly as possible which is why some of this is
235 * less clear than it otherwise should be. 235 * less clear than it otherwise should be.
236 */ 236 */
237 237
238 # userspace resumption stub bypassing syscall exit tracing 238 # userspace resumption stub bypassing syscall exit tracing
239 ALIGN 239 ALIGN
240 RING0_PTREGS_FRAME 240 RING0_PTREGS_FRAME
241 ret_from_exception: 241 ret_from_exception:
242 preempt_stop(CLBR_ANY) 242 preempt_stop(CLBR_ANY)
243 ret_from_intr: 243 ret_from_intr:
244 GET_THREAD_INFO(%ebp) 244 GET_THREAD_INFO(%ebp)
245 check_userspace: 245 check_userspace:
246 movl PT_EFLAGS(%esp), %eax # mix EFLAGS and CS 246 movl PT_EFLAGS(%esp), %eax # mix EFLAGS and CS
247 movb PT_CS(%esp), %al 247 movb PT_CS(%esp), %al
248 andl $(VM_MASK | SEGMENT_RPL_MASK), %eax 248 andl $(VM_MASK | SEGMENT_RPL_MASK), %eax
249 cmpl $USER_RPL, %eax 249 cmpl $USER_RPL, %eax
250 jb resume_kernel # not returning to v8086 or userspace 250 jb resume_kernel # not returning to v8086 or userspace
251 251
252 ENTRY(resume_userspace) 252 ENTRY(resume_userspace)
253 DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt 253 DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
254 # setting need_resched or sigpending 254 # setting need_resched or sigpending
255 # between sampling and the iret 255 # between sampling and the iret
256 movl TI_flags(%ebp), %ecx 256 movl TI_flags(%ebp), %ecx
257 andl $_TIF_WORK_MASK, %ecx # is there any work to be done on 257 andl $_TIF_WORK_MASK, %ecx # is there any work to be done on
258 # int/exception return? 258 # int/exception return?
259 jne work_pending 259 jne work_pending
260 jmp restore_all 260 jmp restore_all
261 261
262 #ifdef CONFIG_PREEMPT 262 #ifdef CONFIG_PREEMPT
263 ENTRY(resume_kernel) 263 ENTRY(resume_kernel)
264 DISABLE_INTERRUPTS(CLBR_ANY) 264 DISABLE_INTERRUPTS(CLBR_ANY)
265 cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? 265 cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ?
266 jnz restore_nocheck 266 jnz restore_nocheck
267 need_resched: 267 need_resched:
268 movl TI_flags(%ebp), %ecx # need_resched set ? 268 movl TI_flags(%ebp), %ecx # need_resched set ?
269 testb $_TIF_NEED_RESCHED, %cl 269 testb $_TIF_NEED_RESCHED, %cl
270 jz restore_all 270 jz restore_all
271 testl $IF_MASK,PT_EFLAGS(%esp) # interrupts off (exception path) ? 271 testl $IF_MASK,PT_EFLAGS(%esp) # interrupts off (exception path) ?
272 jz restore_all 272 jz restore_all
273 call preempt_schedule_irq 273 call preempt_schedule_irq
274 jmp need_resched 274 jmp need_resched
275 #endif 275 #endif
276 CFI_ENDPROC 276 CFI_ENDPROC
277 277
278 /* SYSENTER_RETURN points to after the "sysenter" instruction in 278 /* SYSENTER_RETURN points to after the "sysenter" instruction in
279 the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */ 279 the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */
280 280
281 # sysenter call handler stub 281 # sysenter call handler stub
282 ENTRY(sysenter_entry) 282 ENTRY(sysenter_entry)
283 CFI_STARTPROC simple 283 CFI_STARTPROC simple
284 CFI_SIGNAL_FRAME 284 CFI_SIGNAL_FRAME
285 CFI_DEF_CFA esp, 0 285 CFI_DEF_CFA esp, 0
286 CFI_REGISTER esp, ebp 286 CFI_REGISTER esp, ebp
287 movl TSS_sysenter_esp0(%esp),%esp 287 movl TSS_sysenter_esp0(%esp),%esp
288 sysenter_past_esp: 288 sysenter_past_esp:
289 /* 289 /*
290 * No need to follow this irqs on/off section: the syscall 290 * No need to follow this irqs on/off section: the syscall
291 * disabled irqs and here we enable it straight after entry: 291 * disabled irqs and here we enable it straight after entry:
292 */ 292 */
293 ENABLE_INTERRUPTS(CLBR_NONE) 293 ENABLE_INTERRUPTS(CLBR_NONE)
294 pushl $(__USER_DS) 294 pushl $(__USER_DS)
295 CFI_ADJUST_CFA_OFFSET 4 295 CFI_ADJUST_CFA_OFFSET 4
296 /*CFI_REL_OFFSET ss, 0*/ 296 /*CFI_REL_OFFSET ss, 0*/
297 pushl %ebp 297 pushl %ebp
298 CFI_ADJUST_CFA_OFFSET 4 298 CFI_ADJUST_CFA_OFFSET 4
299 CFI_REL_OFFSET esp, 0 299 CFI_REL_OFFSET esp, 0
300 pushfl 300 pushfl
301 CFI_ADJUST_CFA_OFFSET 4 301 CFI_ADJUST_CFA_OFFSET 4
302 pushl $(__USER_CS) 302 pushl $(__USER_CS)
303 CFI_ADJUST_CFA_OFFSET 4 303 CFI_ADJUST_CFA_OFFSET 4
304 /*CFI_REL_OFFSET cs, 0*/ 304 /*CFI_REL_OFFSET cs, 0*/
305 #ifndef CONFIG_COMPAT_VDSO
305 /* 306 /*
306 * Push current_thread_info()->sysenter_return to the stack. 307 * Push current_thread_info()->sysenter_return to the stack.
307 * A tiny bit of offset fixup is necessary - 4*4 means the 4 words 308 * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
308 * pushed above; +8 corresponds to copy_thread's esp0 setting. 309 * pushed above; +8 corresponds to copy_thread's esp0 setting.
309 */ 310 */
310 pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp) 311 pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
312 #else
313 pushl $SYSENTER_RETURN
314 #endif
311 CFI_ADJUST_CFA_OFFSET 4 315 CFI_ADJUST_CFA_OFFSET 4
312 CFI_REL_OFFSET eip, 0 316 CFI_REL_OFFSET eip, 0
313 317
314 /* 318 /*
315 * Load the potential sixth argument from user stack. 319 * Load the potential sixth argument from user stack.
316 * Careful about security. 320 * Careful about security.
317 */ 321 */
318 cmpl $__PAGE_OFFSET-3,%ebp 322 cmpl $__PAGE_OFFSET-3,%ebp
319 jae syscall_fault 323 jae syscall_fault
320 1: movl (%ebp),%ebp 324 1: movl (%ebp),%ebp
321 .section __ex_table,"a" 325 .section __ex_table,"a"
322 .align 4 326 .align 4
323 .long 1b,syscall_fault 327 .long 1b,syscall_fault
324 .previous 328 .previous
325 329
326 pushl %eax 330 pushl %eax
327 CFI_ADJUST_CFA_OFFSET 4 331 CFI_ADJUST_CFA_OFFSET 4
328 SAVE_ALL 332 SAVE_ALL
329 GET_THREAD_INFO(%ebp) 333 GET_THREAD_INFO(%ebp)
330 334
331 /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ 335 /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
332 testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp) 336 testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
333 jnz syscall_trace_entry 337 jnz syscall_trace_entry
334 cmpl $(nr_syscalls), %eax 338 cmpl $(nr_syscalls), %eax
335 jae syscall_badsys 339 jae syscall_badsys
336 call *sys_call_table(,%eax,4) 340 call *sys_call_table(,%eax,4)
337 movl %eax,PT_EAX(%esp) 341 movl %eax,PT_EAX(%esp)
338 DISABLE_INTERRUPTS(CLBR_ECX|CLBR_EDX) 342 DISABLE_INTERRUPTS(CLBR_ECX|CLBR_EDX)
339 TRACE_IRQS_OFF 343 TRACE_IRQS_OFF
340 movl TI_flags(%ebp), %ecx 344 movl TI_flags(%ebp), %ecx
341 testw $_TIF_ALLWORK_MASK, %cx 345 testw $_TIF_ALLWORK_MASK, %cx
342 jne syscall_exit_work 346 jne syscall_exit_work
343 /* if something modifies registers it must also disable sysexit */ 347 /* if something modifies registers it must also disable sysexit */
344 movl PT_EIP(%esp), %edx 348 movl PT_EIP(%esp), %edx
345 movl PT_OLDESP(%esp), %ecx 349 movl PT_OLDESP(%esp), %ecx
346 xorl %ebp,%ebp 350 xorl %ebp,%ebp
347 TRACE_IRQS_ON 351 TRACE_IRQS_ON
348 1: mov PT_GS(%esp), %gs 352 1: mov PT_GS(%esp), %gs
349 ENABLE_INTERRUPTS_SYSEXIT 353 ENABLE_INTERRUPTS_SYSEXIT
350 CFI_ENDPROC 354 CFI_ENDPROC
351 .pushsection .fixup,"ax" 355 .pushsection .fixup,"ax"
352 2: movl $0,PT_GS(%esp) 356 2: movl $0,PT_GS(%esp)
353 jmp 1b 357 jmp 1b
354 .section __ex_table,"a" 358 .section __ex_table,"a"
355 .align 4 359 .align 4
356 .long 1b,2b 360 .long 1b,2b
357 .popsection 361 .popsection
358 362
359 # system call handler stub 363 # system call handler stub
360 ENTRY(system_call) 364 ENTRY(system_call)
361 RING0_INT_FRAME # can't unwind into user space anyway 365 RING0_INT_FRAME # can't unwind into user space anyway
362 pushl %eax # save orig_eax 366 pushl %eax # save orig_eax
363 CFI_ADJUST_CFA_OFFSET 4 367 CFI_ADJUST_CFA_OFFSET 4
364 SAVE_ALL 368 SAVE_ALL
365 GET_THREAD_INFO(%ebp) 369 GET_THREAD_INFO(%ebp)
366 testl $TF_MASK,PT_EFLAGS(%esp) 370 testl $TF_MASK,PT_EFLAGS(%esp)
367 jz no_singlestep 371 jz no_singlestep
368 orl $_TIF_SINGLESTEP,TI_flags(%ebp) 372 orl $_TIF_SINGLESTEP,TI_flags(%ebp)
369 no_singlestep: 373 no_singlestep:
370 # system call tracing in operation / emulation 374 # system call tracing in operation / emulation
371 /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ 375 /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
372 testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp) 376 testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
373 jnz syscall_trace_entry 377 jnz syscall_trace_entry
374 cmpl $(nr_syscalls), %eax 378 cmpl $(nr_syscalls), %eax
375 jae syscall_badsys 379 jae syscall_badsys
376 syscall_call: 380 syscall_call:
377 call *sys_call_table(,%eax,4) 381 call *sys_call_table(,%eax,4)
378 movl %eax,PT_EAX(%esp) # store the return value 382 movl %eax,PT_EAX(%esp) # store the return value
379 syscall_exit: 383 syscall_exit:
380 DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt 384 DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
381 # setting need_resched or sigpending 385 # setting need_resched or sigpending
382 # between sampling and the iret 386 # between sampling and the iret
383 TRACE_IRQS_OFF 387 TRACE_IRQS_OFF
384 movl TI_flags(%ebp), %ecx 388 movl TI_flags(%ebp), %ecx
385 testw $_TIF_ALLWORK_MASK, %cx # current->work 389 testw $_TIF_ALLWORK_MASK, %cx # current->work
386 jne syscall_exit_work 390 jne syscall_exit_work
387 391
388 restore_all: 392 restore_all:
389 movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS 393 movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
390 # Warning: PT_OLDSS(%esp) contains the wrong/random values if we 394 # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
391 # are returning to the kernel. 395 # are returning to the kernel.
392 # See comments in process.c:copy_thread() for details. 396 # See comments in process.c:copy_thread() for details.
393 movb PT_OLDSS(%esp), %ah 397 movb PT_OLDSS(%esp), %ah
394 movb PT_CS(%esp), %al 398 movb PT_CS(%esp), %al
395 andl $(VM_MASK | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax 399 andl $(VM_MASK | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax
396 cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax 400 cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax
397 CFI_REMEMBER_STATE 401 CFI_REMEMBER_STATE
398 je ldt_ss # returning to user-space with LDT SS 402 je ldt_ss # returning to user-space with LDT SS
399 restore_nocheck: 403 restore_nocheck:
400 TRACE_IRQS_IRET 404 TRACE_IRQS_IRET
401 restore_nocheck_notrace: 405 restore_nocheck_notrace:
402 RESTORE_REGS 406 RESTORE_REGS
403 addl $4, %esp # skip orig_eax/error_code 407 addl $4, %esp # skip orig_eax/error_code
404 CFI_ADJUST_CFA_OFFSET -4 408 CFI_ADJUST_CFA_OFFSET -4
405 1: INTERRUPT_RETURN 409 1: INTERRUPT_RETURN
406 .section .fixup,"ax" 410 .section .fixup,"ax"
407 iret_exc: 411 iret_exc:
408 TRACE_IRQS_ON 412 TRACE_IRQS_ON
409 ENABLE_INTERRUPTS(CLBR_NONE) 413 ENABLE_INTERRUPTS(CLBR_NONE)
410 pushl $0 # no error code 414 pushl $0 # no error code
411 pushl $do_iret_error 415 pushl $do_iret_error
412 jmp error_code 416 jmp error_code
413 .previous 417 .previous
414 .section __ex_table,"a" 418 .section __ex_table,"a"
415 .align 4 419 .align 4
416 .long 1b,iret_exc 420 .long 1b,iret_exc
417 .previous 421 .previous
418 422
419 CFI_RESTORE_STATE 423 CFI_RESTORE_STATE
420 ldt_ss: 424 ldt_ss:
421 larl PT_OLDSS(%esp), %eax 425 larl PT_OLDSS(%esp), %eax
422 jnz restore_nocheck 426 jnz restore_nocheck
423 testl $0x00400000, %eax # returning to 32bit stack? 427 testl $0x00400000, %eax # returning to 32bit stack?
424 jnz restore_nocheck # allright, normal return 428 jnz restore_nocheck # allright, normal return
425 429
426 #ifdef CONFIG_PARAVIRT 430 #ifdef CONFIG_PARAVIRT
427 /* 431 /*
428 * The kernel can't run on a non-flat stack if paravirt mode 432 * The kernel can't run on a non-flat stack if paravirt mode
429 * is active. Rather than try to fixup the high bits of 433 * is active. Rather than try to fixup the high bits of
430 * ESP, bypass this code entirely. This may break DOSemu 434 * ESP, bypass this code entirely. This may break DOSemu
431 * and/or Wine support in a paravirt VM, although the option 435 * and/or Wine support in a paravirt VM, although the option
432 * is still available to implement the setting of the high 436 * is still available to implement the setting of the high
433 * 16-bits in the INTERRUPT_RETURN paravirt-op. 437 * 16-bits in the INTERRUPT_RETURN paravirt-op.
434 */ 438 */
435 cmpl $0, paravirt_ops+PARAVIRT_enabled 439 cmpl $0, paravirt_ops+PARAVIRT_enabled
436 jne restore_nocheck 440 jne restore_nocheck
437 #endif 441 #endif
438 442
439 /* If returning to userspace with 16bit stack, 443 /* If returning to userspace with 16bit stack,
440 * try to fix the higher word of ESP, as the CPU 444 * try to fix the higher word of ESP, as the CPU
441 * won't restore it. 445 * won't restore it.
442 * This is an "official" bug of all the x86-compatible 446 * This is an "official" bug of all the x86-compatible
443 * CPUs, which we can try to work around to make 447 * CPUs, which we can try to work around to make
444 * dosemu and wine happy. */ 448 * dosemu and wine happy. */
445 movl PT_OLDESP(%esp), %eax 449 movl PT_OLDESP(%esp), %eax
446 movl %esp, %edx 450 movl %esp, %edx
447 call patch_espfix_desc 451 call patch_espfix_desc
448 pushl $__ESPFIX_SS 452 pushl $__ESPFIX_SS
449 CFI_ADJUST_CFA_OFFSET 4 453 CFI_ADJUST_CFA_OFFSET 4
450 pushl %eax 454 pushl %eax
451 CFI_ADJUST_CFA_OFFSET 4 455 CFI_ADJUST_CFA_OFFSET 4
452 DISABLE_INTERRUPTS(CLBR_EAX) 456 DISABLE_INTERRUPTS(CLBR_EAX)
453 TRACE_IRQS_OFF 457 TRACE_IRQS_OFF
454 lss (%esp), %esp 458 lss (%esp), %esp
455 CFI_ADJUST_CFA_OFFSET -8 459 CFI_ADJUST_CFA_OFFSET -8
456 jmp restore_nocheck 460 jmp restore_nocheck
457 CFI_ENDPROC 461 CFI_ENDPROC
458 462
459 # perform work that needs to be done immediately before resumption 463 # perform work that needs to be done immediately before resumption
460 ALIGN 464 ALIGN
461 RING0_PTREGS_FRAME # can't unwind into user space anyway 465 RING0_PTREGS_FRAME # can't unwind into user space anyway
462 work_pending: 466 work_pending:
463 testb $_TIF_NEED_RESCHED, %cl 467 testb $_TIF_NEED_RESCHED, %cl
464 jz work_notifysig 468 jz work_notifysig
465 work_resched: 469 work_resched:
466 call schedule 470 call schedule
467 DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt 471 DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
468 # setting need_resched or sigpending 472 # setting need_resched or sigpending
469 # between sampling and the iret 473 # between sampling and the iret
470 TRACE_IRQS_OFF 474 TRACE_IRQS_OFF
471 movl TI_flags(%ebp), %ecx 475 movl TI_flags(%ebp), %ecx
472 andl $_TIF_WORK_MASK, %ecx # is there any work to be done other 476 andl $_TIF_WORK_MASK, %ecx # is there any work to be done other
473 # than syscall tracing? 477 # than syscall tracing?
474 jz restore_all 478 jz restore_all
475 testb $_TIF_NEED_RESCHED, %cl 479 testb $_TIF_NEED_RESCHED, %cl
476 jnz work_resched 480 jnz work_resched
477 481
478 work_notifysig: # deal with pending signals and 482 work_notifysig: # deal with pending signals and
479 # notify-resume requests 483 # notify-resume requests
480 #ifdef CONFIG_VM86 484 #ifdef CONFIG_VM86
481 testl $VM_MASK, PT_EFLAGS(%esp) 485 testl $VM_MASK, PT_EFLAGS(%esp)
482 movl %esp, %eax 486 movl %esp, %eax
483 jne work_notifysig_v86 # returning to kernel-space or 487 jne work_notifysig_v86 # returning to kernel-space or
484 # vm86-space 488 # vm86-space
485 xorl %edx, %edx 489 xorl %edx, %edx
486 call do_notify_resume 490 call do_notify_resume
487 jmp resume_userspace_sig 491 jmp resume_userspace_sig
488 492
489 ALIGN 493 ALIGN
490 work_notifysig_v86: 494 work_notifysig_v86:
491 pushl %ecx # save ti_flags for do_notify_resume 495 pushl %ecx # save ti_flags for do_notify_resume
492 CFI_ADJUST_CFA_OFFSET 4 496 CFI_ADJUST_CFA_OFFSET 4
493 call save_v86_state # %eax contains pt_regs pointer 497 call save_v86_state # %eax contains pt_regs pointer
494 popl %ecx 498 popl %ecx
495 CFI_ADJUST_CFA_OFFSET -4 499 CFI_ADJUST_CFA_OFFSET -4
496 movl %eax, %esp 500 movl %eax, %esp
497 #else 501 #else
498 movl %esp, %eax 502 movl %esp, %eax
499 #endif 503 #endif
500 xorl %edx, %edx 504 xorl %edx, %edx
501 call do_notify_resume 505 call do_notify_resume
502 jmp resume_userspace_sig 506 jmp resume_userspace_sig
503 507
504 # perform syscall exit tracing 508 # perform syscall exit tracing
505 ALIGN 509 ALIGN
506 syscall_trace_entry: 510 syscall_trace_entry:
507 movl $-ENOSYS,PT_EAX(%esp) 511 movl $-ENOSYS,PT_EAX(%esp)
508 movl %esp, %eax 512 movl %esp, %eax
509 xorl %edx,%edx 513 xorl %edx,%edx
510 call do_syscall_trace 514 call do_syscall_trace
511 cmpl $0, %eax 515 cmpl $0, %eax
512 jne resume_userspace # ret != 0 -> running under PTRACE_SYSEMU, 516 jne resume_userspace # ret != 0 -> running under PTRACE_SYSEMU,
513 # so must skip actual syscall 517 # so must skip actual syscall
514 movl PT_ORIG_EAX(%esp), %eax 518 movl PT_ORIG_EAX(%esp), %eax
515 cmpl $(nr_syscalls), %eax 519 cmpl $(nr_syscalls), %eax
516 jnae syscall_call 520 jnae syscall_call
517 jmp syscall_exit 521 jmp syscall_exit
518 522
519 # perform syscall exit tracing 523 # perform syscall exit tracing
520 ALIGN 524 ALIGN
521 syscall_exit_work: 525 syscall_exit_work:
522 testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl 526 testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl
523 jz work_pending 527 jz work_pending
524 TRACE_IRQS_ON 528 TRACE_IRQS_ON
525 ENABLE_INTERRUPTS(CLBR_ANY) # could let do_syscall_trace() call 529 ENABLE_INTERRUPTS(CLBR_ANY) # could let do_syscall_trace() call
526 # schedule() instead 530 # schedule() instead
527 movl %esp, %eax 531 movl %esp, %eax
528 movl $1, %edx 532 movl $1, %edx
529 call do_syscall_trace 533 call do_syscall_trace
530 jmp resume_userspace 534 jmp resume_userspace
531 CFI_ENDPROC 535 CFI_ENDPROC
532 536
533 RING0_INT_FRAME # can't unwind into user space anyway 537 RING0_INT_FRAME # can't unwind into user space anyway
534 syscall_fault: 538 syscall_fault:
535 pushl %eax # save orig_eax 539 pushl %eax # save orig_eax
536 CFI_ADJUST_CFA_OFFSET 4 540 CFI_ADJUST_CFA_OFFSET 4
537 SAVE_ALL 541 SAVE_ALL
538 GET_THREAD_INFO(%ebp) 542 GET_THREAD_INFO(%ebp)
539 movl $-EFAULT,PT_EAX(%esp) 543 movl $-EFAULT,PT_EAX(%esp)
540 jmp resume_userspace 544 jmp resume_userspace
541 545
542 syscall_badsys: 546 syscall_badsys:
543 movl $-ENOSYS,PT_EAX(%esp) 547 movl $-ENOSYS,PT_EAX(%esp)
544 jmp resume_userspace 548 jmp resume_userspace
545 CFI_ENDPROC 549 CFI_ENDPROC
546 550
547 #define FIXUP_ESPFIX_STACK \ 551 #define FIXUP_ESPFIX_STACK \
548 /* since we are on a wrong stack, we cant make it a C code :( */ \ 552 /* since we are on a wrong stack, we cant make it a C code :( */ \
549 movl %gs:PDA_cpu, %ebx; \ 553 movl %gs:PDA_cpu, %ebx; \
550 PER_CPU(cpu_gdt_descr, %ebx); \ 554 PER_CPU(cpu_gdt_descr, %ebx); \
551 movl GDS_address(%ebx), %ebx; \ 555 movl GDS_address(%ebx), %ebx; \
552 GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \ 556 GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
553 addl %esp, %eax; \ 557 addl %esp, %eax; \
554 pushl $__KERNEL_DS; \ 558 pushl $__KERNEL_DS; \
555 CFI_ADJUST_CFA_OFFSET 4; \ 559 CFI_ADJUST_CFA_OFFSET 4; \
556 pushl %eax; \ 560 pushl %eax; \
557 CFI_ADJUST_CFA_OFFSET 4; \ 561 CFI_ADJUST_CFA_OFFSET 4; \
558 lss (%esp), %esp; \ 562 lss (%esp), %esp; \
559 CFI_ADJUST_CFA_OFFSET -8; 563 CFI_ADJUST_CFA_OFFSET -8;
560 #define UNWIND_ESPFIX_STACK \ 564 #define UNWIND_ESPFIX_STACK \
561 movl %ss, %eax; \ 565 movl %ss, %eax; \
562 /* see if on espfix stack */ \ 566 /* see if on espfix stack */ \
563 cmpw $__ESPFIX_SS, %ax; \ 567 cmpw $__ESPFIX_SS, %ax; \
564 jne 27f; \ 568 jne 27f; \
565 movl $__KERNEL_DS, %eax; \ 569 movl $__KERNEL_DS, %eax; \
566 movl %eax, %ds; \ 570 movl %eax, %ds; \
567 movl %eax, %es; \ 571 movl %eax, %es; \
568 /* switch to normal stack */ \ 572 /* switch to normal stack */ \
569 FIXUP_ESPFIX_STACK; \ 573 FIXUP_ESPFIX_STACK; \
570 27:; 574 27:;
571 575
572 /* 576 /*
573 * Build the entry stubs and pointer table with 577 * Build the entry stubs and pointer table with
574 * some assembler magic. 578 * some assembler magic.
575 */ 579 */
576 .data 580 .data
577 ENTRY(interrupt) 581 ENTRY(interrupt)
578 .text 582 .text
579 583
580 vector=0 584 vector=0
581 ENTRY(irq_entries_start) 585 ENTRY(irq_entries_start)
582 RING0_INT_FRAME 586 RING0_INT_FRAME
583 .rept NR_IRQS 587 .rept NR_IRQS
584 ALIGN 588 ALIGN
585 .if vector 589 .if vector
586 CFI_ADJUST_CFA_OFFSET -4 590 CFI_ADJUST_CFA_OFFSET -4
587 .endif 591 .endif
588 1: pushl $~(vector) 592 1: pushl $~(vector)
589 CFI_ADJUST_CFA_OFFSET 4 593 CFI_ADJUST_CFA_OFFSET 4
590 jmp common_interrupt 594 jmp common_interrupt
591 .data 595 .data
592 .long 1b 596 .long 1b
593 .text 597 .text
594 vector=vector+1 598 vector=vector+1
595 .endr 599 .endr
596 600
597 /* 601 /*
598 * the CPU automatically disables interrupts when executing an IRQ vector, 602 * the CPU automatically disables interrupts when executing an IRQ vector,
599 * so IRQ-flags tracing has to follow that: 603 * so IRQ-flags tracing has to follow that:
600 */ 604 */
601 ALIGN 605 ALIGN
602 common_interrupt: 606 common_interrupt:
603 SAVE_ALL 607 SAVE_ALL
604 TRACE_IRQS_OFF 608 TRACE_IRQS_OFF
605 movl %esp,%eax 609 movl %esp,%eax
606 call do_IRQ 610 call do_IRQ
607 jmp ret_from_intr 611 jmp ret_from_intr
608 CFI_ENDPROC 612 CFI_ENDPROC
609 613
610 #define BUILD_INTERRUPT(name, nr) \ 614 #define BUILD_INTERRUPT(name, nr) \
611 ENTRY(name) \ 615 ENTRY(name) \
612 RING0_INT_FRAME; \ 616 RING0_INT_FRAME; \
613 pushl $~(nr); \ 617 pushl $~(nr); \
614 CFI_ADJUST_CFA_OFFSET 4; \ 618 CFI_ADJUST_CFA_OFFSET 4; \
615 SAVE_ALL; \ 619 SAVE_ALL; \
616 TRACE_IRQS_OFF \ 620 TRACE_IRQS_OFF \
617 movl %esp,%eax; \ 621 movl %esp,%eax; \
618 call smp_/**/name; \ 622 call smp_/**/name; \
619 jmp ret_from_intr; \ 623 jmp ret_from_intr; \
620 CFI_ENDPROC 624 CFI_ENDPROC
621 625
622 /* The include is where all of the SMP etc. interrupts come from */ 626 /* The include is where all of the SMP etc. interrupts come from */
623 #include "entry_arch.h" 627 #include "entry_arch.h"
624 628
625 KPROBE_ENTRY(page_fault) 629 KPROBE_ENTRY(page_fault)
626 RING0_EC_FRAME 630 RING0_EC_FRAME
627 pushl $do_page_fault 631 pushl $do_page_fault
628 CFI_ADJUST_CFA_OFFSET 4 632 CFI_ADJUST_CFA_OFFSET 4
629 ALIGN 633 ALIGN
630 error_code: 634 error_code:
631 /* the function address is in %gs's slot on the stack */ 635 /* the function address is in %gs's slot on the stack */
632 pushl %es 636 pushl %es
633 CFI_ADJUST_CFA_OFFSET 4 637 CFI_ADJUST_CFA_OFFSET 4
634 /*CFI_REL_OFFSET es, 0*/ 638 /*CFI_REL_OFFSET es, 0*/
635 pushl %ds 639 pushl %ds
636 CFI_ADJUST_CFA_OFFSET 4 640 CFI_ADJUST_CFA_OFFSET 4
637 /*CFI_REL_OFFSET ds, 0*/ 641 /*CFI_REL_OFFSET ds, 0*/
638 pushl %eax 642 pushl %eax
639 CFI_ADJUST_CFA_OFFSET 4 643 CFI_ADJUST_CFA_OFFSET 4
640 CFI_REL_OFFSET eax, 0 644 CFI_REL_OFFSET eax, 0
641 pushl %ebp 645 pushl %ebp
642 CFI_ADJUST_CFA_OFFSET 4 646 CFI_ADJUST_CFA_OFFSET 4
643 CFI_REL_OFFSET ebp, 0 647 CFI_REL_OFFSET ebp, 0
644 pushl %edi 648 pushl %edi
645 CFI_ADJUST_CFA_OFFSET 4 649 CFI_ADJUST_CFA_OFFSET 4
646 CFI_REL_OFFSET edi, 0 650 CFI_REL_OFFSET edi, 0
647 pushl %esi 651 pushl %esi
648 CFI_ADJUST_CFA_OFFSET 4 652 CFI_ADJUST_CFA_OFFSET 4
649 CFI_REL_OFFSET esi, 0 653 CFI_REL_OFFSET esi, 0
650 pushl %edx 654 pushl %edx
651 CFI_ADJUST_CFA_OFFSET 4 655 CFI_ADJUST_CFA_OFFSET 4
652 CFI_REL_OFFSET edx, 0 656 CFI_REL_OFFSET edx, 0
653 pushl %ecx 657 pushl %ecx
654 CFI_ADJUST_CFA_OFFSET 4 658 CFI_ADJUST_CFA_OFFSET 4
655 CFI_REL_OFFSET ecx, 0 659 CFI_REL_OFFSET ecx, 0
656 pushl %ebx 660 pushl %ebx
657 CFI_ADJUST_CFA_OFFSET 4 661 CFI_ADJUST_CFA_OFFSET 4
658 CFI_REL_OFFSET ebx, 0 662 CFI_REL_OFFSET ebx, 0
659 cld 663 cld
660 pushl %gs 664 pushl %gs
661 CFI_ADJUST_CFA_OFFSET 4 665 CFI_ADJUST_CFA_OFFSET 4
662 /*CFI_REL_OFFSET gs, 0*/ 666 /*CFI_REL_OFFSET gs, 0*/
663 movl $(__KERNEL_PDA), %ecx 667 movl $(__KERNEL_PDA), %ecx
664 movl %ecx, %gs 668 movl %ecx, %gs
665 UNWIND_ESPFIX_STACK 669 UNWIND_ESPFIX_STACK
666 popl %ecx 670 popl %ecx
667 CFI_ADJUST_CFA_OFFSET -4 671 CFI_ADJUST_CFA_OFFSET -4
668 /*CFI_REGISTER es, ecx*/ 672 /*CFI_REGISTER es, ecx*/
669 movl PT_GS(%esp), %edi # get the function address 673 movl PT_GS(%esp), %edi # get the function address
670 movl PT_ORIG_EAX(%esp), %edx # get the error code 674 movl PT_ORIG_EAX(%esp), %edx # get the error code
671 movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart 675 movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
672 mov %ecx, PT_GS(%esp) 676 mov %ecx, PT_GS(%esp)
673 /*CFI_REL_OFFSET gs, ES*/ 677 /*CFI_REL_OFFSET gs, ES*/
674 movl $(__USER_DS), %ecx 678 movl $(__USER_DS), %ecx
675 movl %ecx, %ds 679 movl %ecx, %ds
676 movl %ecx, %es 680 movl %ecx, %es
677 movl %esp,%eax # pt_regs pointer 681 movl %esp,%eax # pt_regs pointer
678 call *%edi 682 call *%edi
679 jmp ret_from_exception 683 jmp ret_from_exception
680 CFI_ENDPROC 684 CFI_ENDPROC
681 KPROBE_END(page_fault) 685 KPROBE_END(page_fault)
682 686
683 ENTRY(coprocessor_error) 687 ENTRY(coprocessor_error)
684 RING0_INT_FRAME 688 RING0_INT_FRAME
685 pushl $0 689 pushl $0
686 CFI_ADJUST_CFA_OFFSET 4 690 CFI_ADJUST_CFA_OFFSET 4
687 pushl $do_coprocessor_error 691 pushl $do_coprocessor_error
688 CFI_ADJUST_CFA_OFFSET 4 692 CFI_ADJUST_CFA_OFFSET 4
689 jmp error_code 693 jmp error_code
690 CFI_ENDPROC 694 CFI_ENDPROC
691 695
692 ENTRY(simd_coprocessor_error) 696 ENTRY(simd_coprocessor_error)
693 RING0_INT_FRAME 697 RING0_INT_FRAME
694 pushl $0 698 pushl $0
695 CFI_ADJUST_CFA_OFFSET 4 699 CFI_ADJUST_CFA_OFFSET 4
696 pushl $do_simd_coprocessor_error 700 pushl $do_simd_coprocessor_error
697 CFI_ADJUST_CFA_OFFSET 4 701 CFI_ADJUST_CFA_OFFSET 4
698 jmp error_code 702 jmp error_code
699 CFI_ENDPROC 703 CFI_ENDPROC
700 704
701 ENTRY(device_not_available) 705 ENTRY(device_not_available)
702 RING0_INT_FRAME 706 RING0_INT_FRAME
703 pushl $-1 # mark this as an int 707 pushl $-1 # mark this as an int
704 CFI_ADJUST_CFA_OFFSET 4 708 CFI_ADJUST_CFA_OFFSET 4
705 SAVE_ALL 709 SAVE_ALL
706 GET_CR0_INTO_EAX 710 GET_CR0_INTO_EAX
707 testl $0x4, %eax # EM (math emulation bit) 711 testl $0x4, %eax # EM (math emulation bit)
708 jne device_not_available_emulate 712 jne device_not_available_emulate
709 preempt_stop(CLBR_ANY) 713 preempt_stop(CLBR_ANY)
710 call math_state_restore 714 call math_state_restore
711 jmp ret_from_exception 715 jmp ret_from_exception
712 device_not_available_emulate: 716 device_not_available_emulate:
713 pushl $0 # temporary storage for ORIG_EIP 717 pushl $0 # temporary storage for ORIG_EIP
714 CFI_ADJUST_CFA_OFFSET 4 718 CFI_ADJUST_CFA_OFFSET 4
715 call math_emulate 719 call math_emulate
716 addl $4, %esp 720 addl $4, %esp
717 CFI_ADJUST_CFA_OFFSET -4 721 CFI_ADJUST_CFA_OFFSET -4
718 jmp ret_from_exception 722 jmp ret_from_exception
719 CFI_ENDPROC 723 CFI_ENDPROC
720 724
721 /* 725 /*
722 * Debug traps and NMI can happen at the one SYSENTER instruction 726 * Debug traps and NMI can happen at the one SYSENTER instruction
723 * that sets up the real kernel stack. Check here, since we can't 727 * that sets up the real kernel stack. Check here, since we can't
724 * allow the wrong stack to be used. 728 * allow the wrong stack to be used.
725 * 729 *
726 * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have 730 * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have
727 * already pushed 3 words if it hits on the sysenter instruction: 731 * already pushed 3 words if it hits on the sysenter instruction:
728 * eflags, cs and eip. 732 * eflags, cs and eip.
729 * 733 *
730 * We just load the right stack, and push the three (known) values 734 * We just load the right stack, and push the three (known) values
731 * by hand onto the new stack - while updating the return eip past 735 * by hand onto the new stack - while updating the return eip past
732 * the instruction that would have done it for sysenter. 736 * the instruction that would have done it for sysenter.
733 */ 737 */
734 #define FIX_STACK(offset, ok, label) \ 738 #define FIX_STACK(offset, ok, label) \
735 cmpw $__KERNEL_CS,4(%esp); \ 739 cmpw $__KERNEL_CS,4(%esp); \
736 jne ok; \ 740 jne ok; \
737 label: \ 741 label: \
738 movl TSS_sysenter_esp0+offset(%esp),%esp; \ 742 movl TSS_sysenter_esp0+offset(%esp),%esp; \
739 CFI_DEF_CFA esp, 0; \ 743 CFI_DEF_CFA esp, 0; \
740 CFI_UNDEFINED eip; \ 744 CFI_UNDEFINED eip; \
741 pushfl; \ 745 pushfl; \
742 CFI_ADJUST_CFA_OFFSET 4; \ 746 CFI_ADJUST_CFA_OFFSET 4; \
743 pushl $__KERNEL_CS; \ 747 pushl $__KERNEL_CS; \
744 CFI_ADJUST_CFA_OFFSET 4; \ 748 CFI_ADJUST_CFA_OFFSET 4; \
745 pushl $sysenter_past_esp; \ 749 pushl $sysenter_past_esp; \
746 CFI_ADJUST_CFA_OFFSET 4; \ 750 CFI_ADJUST_CFA_OFFSET 4; \
747 CFI_REL_OFFSET eip, 0 751 CFI_REL_OFFSET eip, 0
748 752
749 KPROBE_ENTRY(debug) 753 KPROBE_ENTRY(debug)
750 RING0_INT_FRAME 754 RING0_INT_FRAME
751 cmpl $sysenter_entry,(%esp) 755 cmpl $sysenter_entry,(%esp)
752 jne debug_stack_correct 756 jne debug_stack_correct
753 FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn) 757 FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
754 debug_stack_correct: 758 debug_stack_correct:
755 pushl $-1 # mark this as an int 759 pushl $-1 # mark this as an int
756 CFI_ADJUST_CFA_OFFSET 4 760 CFI_ADJUST_CFA_OFFSET 4
757 SAVE_ALL 761 SAVE_ALL
758 xorl %edx,%edx # error code 0 762 xorl %edx,%edx # error code 0
759 movl %esp,%eax # pt_regs pointer 763 movl %esp,%eax # pt_regs pointer
760 call do_debug 764 call do_debug
761 jmp ret_from_exception 765 jmp ret_from_exception
762 CFI_ENDPROC 766 CFI_ENDPROC
763 KPROBE_END(debug) 767 KPROBE_END(debug)
764 768
765 /* 769 /*
766 * NMI is doubly nasty. It can happen _while_ we're handling 770 * NMI is doubly nasty. It can happen _while_ we're handling
767 * a debug fault, and the debug fault hasn't yet been able to 771 * a debug fault, and the debug fault hasn't yet been able to
768 * clear up the stack. So we first check whether we got an 772 * clear up the stack. So we first check whether we got an
769 * NMI on the sysenter entry path, but after that we need to 773 * NMI on the sysenter entry path, but after that we need to
770 * check whether we got an NMI on the debug path where the debug 774 * check whether we got an NMI on the debug path where the debug
771 * fault happened on the sysenter path. 775 * fault happened on the sysenter path.
772 */ 776 */
773 KPROBE_ENTRY(nmi) 777 KPROBE_ENTRY(nmi)
774 RING0_INT_FRAME 778 RING0_INT_FRAME
775 pushl %eax 779 pushl %eax
776 CFI_ADJUST_CFA_OFFSET 4 780 CFI_ADJUST_CFA_OFFSET 4
777 movl %ss, %eax 781 movl %ss, %eax
778 cmpw $__ESPFIX_SS, %ax 782 cmpw $__ESPFIX_SS, %ax
779 popl %eax 783 popl %eax
780 CFI_ADJUST_CFA_OFFSET -4 784 CFI_ADJUST_CFA_OFFSET -4
781 je nmi_espfix_stack 785 je nmi_espfix_stack
782 cmpl $sysenter_entry,(%esp) 786 cmpl $sysenter_entry,(%esp)
783 je nmi_stack_fixup 787 je nmi_stack_fixup
784 pushl %eax 788 pushl %eax
785 CFI_ADJUST_CFA_OFFSET 4 789 CFI_ADJUST_CFA_OFFSET 4
786 movl %esp,%eax 790 movl %esp,%eax
787 /* Do not access memory above the end of our stack page, 791 /* Do not access memory above the end of our stack page,
788 * it might not exist. 792 * it might not exist.
789 */ 793 */
790 andl $(THREAD_SIZE-1),%eax 794 andl $(THREAD_SIZE-1),%eax
791 cmpl $(THREAD_SIZE-20),%eax 795 cmpl $(THREAD_SIZE-20),%eax
792 popl %eax 796 popl %eax
793 CFI_ADJUST_CFA_OFFSET -4 797 CFI_ADJUST_CFA_OFFSET -4
794 jae nmi_stack_correct 798 jae nmi_stack_correct
795 cmpl $sysenter_entry,12(%esp) 799 cmpl $sysenter_entry,12(%esp)
796 je nmi_debug_stack_check 800 je nmi_debug_stack_check
797 nmi_stack_correct: 801 nmi_stack_correct:
798 /* We have a RING0_INT_FRAME here */ 802 /* We have a RING0_INT_FRAME here */
799 pushl %eax 803 pushl %eax
800 CFI_ADJUST_CFA_OFFSET 4 804 CFI_ADJUST_CFA_OFFSET 4
801 SAVE_ALL 805 SAVE_ALL
802 xorl %edx,%edx # zero error code 806 xorl %edx,%edx # zero error code
803 movl %esp,%eax # pt_regs pointer 807 movl %esp,%eax # pt_regs pointer
804 call do_nmi 808 call do_nmi
805 jmp restore_nocheck_notrace 809 jmp restore_nocheck_notrace
806 CFI_ENDPROC 810 CFI_ENDPROC
807 811
808 nmi_stack_fixup: 812 nmi_stack_fixup:
809 RING0_INT_FRAME 813 RING0_INT_FRAME
810 FIX_STACK(12,nmi_stack_correct, 1) 814 FIX_STACK(12,nmi_stack_correct, 1)
811 jmp nmi_stack_correct 815 jmp nmi_stack_correct
812 816
813 nmi_debug_stack_check: 817 nmi_debug_stack_check:
814 /* We have a RING0_INT_FRAME here */ 818 /* We have a RING0_INT_FRAME here */
815 cmpw $__KERNEL_CS,16(%esp) 819 cmpw $__KERNEL_CS,16(%esp)
816 jne nmi_stack_correct 820 jne nmi_stack_correct
817 cmpl $debug,(%esp) 821 cmpl $debug,(%esp)
818 jb nmi_stack_correct 822 jb nmi_stack_correct
819 cmpl $debug_esp_fix_insn,(%esp) 823 cmpl $debug_esp_fix_insn,(%esp)
820 ja nmi_stack_correct 824 ja nmi_stack_correct
821 FIX_STACK(24,nmi_stack_correct, 1) 825 FIX_STACK(24,nmi_stack_correct, 1)
822 jmp nmi_stack_correct 826 jmp nmi_stack_correct
823 827
824 nmi_espfix_stack: 828 nmi_espfix_stack:
825 /* We have a RING0_INT_FRAME here. 829 /* We have a RING0_INT_FRAME here.
826 * 830 *
827 * create the pointer to lss back 831 * create the pointer to lss back
828 */ 832 */
829 pushl %ss 833 pushl %ss
830 CFI_ADJUST_CFA_OFFSET 4 834 CFI_ADJUST_CFA_OFFSET 4
831 pushl %esp 835 pushl %esp
832 CFI_ADJUST_CFA_OFFSET 4 836 CFI_ADJUST_CFA_OFFSET 4
833 addw $4, (%esp) 837 addw $4, (%esp)
834 /* copy the iret frame of 12 bytes */ 838 /* copy the iret frame of 12 bytes */
835 .rept 3 839 .rept 3
836 pushl 16(%esp) 840 pushl 16(%esp)
837 CFI_ADJUST_CFA_OFFSET 4 841 CFI_ADJUST_CFA_OFFSET 4
838 .endr 842 .endr
839 pushl %eax 843 pushl %eax
840 CFI_ADJUST_CFA_OFFSET 4 844 CFI_ADJUST_CFA_OFFSET 4
841 SAVE_ALL 845 SAVE_ALL
842 FIXUP_ESPFIX_STACK # %eax == %esp 846 FIXUP_ESPFIX_STACK # %eax == %esp
843 xorl %edx,%edx # zero error code 847 xorl %edx,%edx # zero error code
844 call do_nmi 848 call do_nmi
845 RESTORE_REGS 849 RESTORE_REGS
846 lss 12+4(%esp), %esp # back to espfix stack 850 lss 12+4(%esp), %esp # back to espfix stack
847 CFI_ADJUST_CFA_OFFSET -24 851 CFI_ADJUST_CFA_OFFSET -24
848 1: INTERRUPT_RETURN 852 1: INTERRUPT_RETURN
849 CFI_ENDPROC 853 CFI_ENDPROC
850 .section __ex_table,"a" 854 .section __ex_table,"a"
851 .align 4 855 .align 4
852 .long 1b,iret_exc 856 .long 1b,iret_exc
853 .previous 857 .previous
854 KPROBE_END(nmi) 858 KPROBE_END(nmi)
855 859
856 #ifdef CONFIG_PARAVIRT 860 #ifdef CONFIG_PARAVIRT
857 ENTRY(native_iret) 861 ENTRY(native_iret)
858 1: iret 862 1: iret
859 .section __ex_table,"a" 863 .section __ex_table,"a"
860 .align 4 864 .align 4
861 .long 1b,iret_exc 865 .long 1b,iret_exc
862 .previous 866 .previous
863 867
864 ENTRY(native_irq_enable_sysexit) 868 ENTRY(native_irq_enable_sysexit)
865 sti 869 sti
866 sysexit 870 sysexit
867 #endif 871 #endif
868 872
869 KPROBE_ENTRY(int3) 873 KPROBE_ENTRY(int3)
870 RING0_INT_FRAME 874 RING0_INT_FRAME
871 pushl $-1 # mark this as an int 875 pushl $-1 # mark this as an int
872 CFI_ADJUST_CFA_OFFSET 4 876 CFI_ADJUST_CFA_OFFSET 4
873 SAVE_ALL 877 SAVE_ALL
874 xorl %edx,%edx # zero error code 878 xorl %edx,%edx # zero error code
875 movl %esp,%eax # pt_regs pointer 879 movl %esp,%eax # pt_regs pointer
876 call do_int3 880 call do_int3
877 jmp ret_from_exception 881 jmp ret_from_exception
878 CFI_ENDPROC 882 CFI_ENDPROC
879 KPROBE_END(int3) 883 KPROBE_END(int3)
880 884
881 ENTRY(overflow) 885 ENTRY(overflow)
882 RING0_INT_FRAME 886 RING0_INT_FRAME
883 pushl $0 887 pushl $0
884 CFI_ADJUST_CFA_OFFSET 4 888 CFI_ADJUST_CFA_OFFSET 4
885 pushl $do_overflow 889 pushl $do_overflow
886 CFI_ADJUST_CFA_OFFSET 4 890 CFI_ADJUST_CFA_OFFSET 4
887 jmp error_code 891 jmp error_code
888 CFI_ENDPROC 892 CFI_ENDPROC
889 893
890 ENTRY(bounds) 894 ENTRY(bounds)
891 RING0_INT_FRAME 895 RING0_INT_FRAME
892 pushl $0 896 pushl $0
893 CFI_ADJUST_CFA_OFFSET 4 897 CFI_ADJUST_CFA_OFFSET 4
894 pushl $do_bounds 898 pushl $do_bounds
895 CFI_ADJUST_CFA_OFFSET 4 899 CFI_ADJUST_CFA_OFFSET 4
896 jmp error_code 900 jmp error_code
897 CFI_ENDPROC 901 CFI_ENDPROC
898 902
899 ENTRY(invalid_op) 903 ENTRY(invalid_op)
900 RING0_INT_FRAME 904 RING0_INT_FRAME
901 pushl $0 905 pushl $0
902 CFI_ADJUST_CFA_OFFSET 4 906 CFI_ADJUST_CFA_OFFSET 4
903 pushl $do_invalid_op 907 pushl $do_invalid_op
904 CFI_ADJUST_CFA_OFFSET 4 908 CFI_ADJUST_CFA_OFFSET 4
905 jmp error_code 909 jmp error_code
906 CFI_ENDPROC 910 CFI_ENDPROC
907 911
908 ENTRY(coprocessor_segment_overrun) 912 ENTRY(coprocessor_segment_overrun)
909 RING0_INT_FRAME 913 RING0_INT_FRAME
910 pushl $0 914 pushl $0
911 CFI_ADJUST_CFA_OFFSET 4 915 CFI_ADJUST_CFA_OFFSET 4
912 pushl $do_coprocessor_segment_overrun 916 pushl $do_coprocessor_segment_overrun
913 CFI_ADJUST_CFA_OFFSET 4 917 CFI_ADJUST_CFA_OFFSET 4
914 jmp error_code 918 jmp error_code
915 CFI_ENDPROC 919 CFI_ENDPROC
916 920
917 ENTRY(invalid_TSS) 921 ENTRY(invalid_TSS)
918 RING0_EC_FRAME 922 RING0_EC_FRAME
919 pushl $do_invalid_TSS 923 pushl $do_invalid_TSS
920 CFI_ADJUST_CFA_OFFSET 4 924 CFI_ADJUST_CFA_OFFSET 4
921 jmp error_code 925 jmp error_code
922 CFI_ENDPROC 926 CFI_ENDPROC
923 927
924 ENTRY(segment_not_present) 928 ENTRY(segment_not_present)
925 RING0_EC_FRAME 929 RING0_EC_FRAME
926 pushl $do_segment_not_present 930 pushl $do_segment_not_present
927 CFI_ADJUST_CFA_OFFSET 4 931 CFI_ADJUST_CFA_OFFSET 4
928 jmp error_code 932 jmp error_code
929 CFI_ENDPROC 933 CFI_ENDPROC
930 934
931 ENTRY(stack_segment) 935 ENTRY(stack_segment)
932 RING0_EC_FRAME 936 RING0_EC_FRAME
933 pushl $do_stack_segment 937 pushl $do_stack_segment
934 CFI_ADJUST_CFA_OFFSET 4 938 CFI_ADJUST_CFA_OFFSET 4
935 jmp error_code 939 jmp error_code
936 CFI_ENDPROC 940 CFI_ENDPROC
937 941
938 KPROBE_ENTRY(general_protection) 942 KPROBE_ENTRY(general_protection)
939 RING0_EC_FRAME 943 RING0_EC_FRAME
940 pushl $do_general_protection 944 pushl $do_general_protection
941 CFI_ADJUST_CFA_OFFSET 4 945 CFI_ADJUST_CFA_OFFSET 4
942 jmp error_code 946 jmp error_code
943 CFI_ENDPROC 947 CFI_ENDPROC
944 KPROBE_END(general_protection) 948 KPROBE_END(general_protection)
945 949
946 ENTRY(alignment_check) 950 ENTRY(alignment_check)
947 RING0_EC_FRAME 951 RING0_EC_FRAME
948 pushl $do_alignment_check 952 pushl $do_alignment_check
949 CFI_ADJUST_CFA_OFFSET 4 953 CFI_ADJUST_CFA_OFFSET 4
950 jmp error_code 954 jmp error_code
951 CFI_ENDPROC 955 CFI_ENDPROC
952 956
953 ENTRY(divide_error) 957 ENTRY(divide_error)
954 RING0_INT_FRAME 958 RING0_INT_FRAME
955 pushl $0 # no error code 959 pushl $0 # no error code
956 CFI_ADJUST_CFA_OFFSET 4 960 CFI_ADJUST_CFA_OFFSET 4
957 pushl $do_divide_error 961 pushl $do_divide_error
958 CFI_ADJUST_CFA_OFFSET 4 962 CFI_ADJUST_CFA_OFFSET 4
959 jmp error_code 963 jmp error_code
960 CFI_ENDPROC 964 CFI_ENDPROC
961 965
962 #ifdef CONFIG_X86_MCE 966 #ifdef CONFIG_X86_MCE
963 ENTRY(machine_check) 967 ENTRY(machine_check)
964 RING0_INT_FRAME 968 RING0_INT_FRAME
965 pushl $0 969 pushl $0
966 CFI_ADJUST_CFA_OFFSET 4 970 CFI_ADJUST_CFA_OFFSET 4
967 pushl machine_check_vector 971 pushl machine_check_vector
968 CFI_ADJUST_CFA_OFFSET 4 972 CFI_ADJUST_CFA_OFFSET 4
969 jmp error_code 973 jmp error_code
970 CFI_ENDPROC 974 CFI_ENDPROC
971 #endif 975 #endif
972 976
973 ENTRY(spurious_interrupt_bug) 977 ENTRY(spurious_interrupt_bug)
974 RING0_INT_FRAME 978 RING0_INT_FRAME
975 pushl $0 979 pushl $0
976 CFI_ADJUST_CFA_OFFSET 4 980 CFI_ADJUST_CFA_OFFSET 4
977 pushl $do_spurious_interrupt_bug 981 pushl $do_spurious_interrupt_bug
978 CFI_ADJUST_CFA_OFFSET 4 982 CFI_ADJUST_CFA_OFFSET 4
979 jmp error_code 983 jmp error_code
980 CFI_ENDPROC 984 CFI_ENDPROC
981 985
982 ENTRY(kernel_thread_helper) 986 ENTRY(kernel_thread_helper)
983 pushl $0 # fake return address for unwinder 987 pushl $0 # fake return address for unwinder
984 CFI_STARTPROC 988 CFI_STARTPROC
985 movl %edx,%eax 989 movl %edx,%eax
986 push %edx 990 push %edx
987 CFI_ADJUST_CFA_OFFSET 4 991 CFI_ADJUST_CFA_OFFSET 4
988 call *%ebx 992 call *%ebx
989 push %eax 993 push %eax
990 CFI_ADJUST_CFA_OFFSET 4 994 CFI_ADJUST_CFA_OFFSET 4
991 call do_exit 995 call do_exit
992 CFI_ENDPROC 996 CFI_ENDPROC
993 ENDPROC(kernel_thread_helper) 997 ENDPROC(kernel_thread_helper)
994 998
995 .section .rodata,"a" 999 .section .rodata,"a"
996 #include "syscall_table.S" 1000 #include "syscall_table.S"
997 1001
998 syscall_table_size=(.-sys_call_table) 1002 syscall_table_size=(.-sys_call_table)
999 1003
arch/i386/kernel/sysenter.c
1 /* 1 /*
2 * linux/arch/i386/kernel/sysenter.c 2 * linux/arch/i386/kernel/sysenter.c
3 * 3 *
4 * (C) Copyright 2002 Linus Torvalds 4 * (C) Copyright 2002 Linus Torvalds
5 * Portions based on the vdso-randomization code from exec-shield: 5 * Portions based on the vdso-randomization code from exec-shield:
6 * Copyright(C) 2005-2006, Red Hat, Inc., Ingo Molnar 6 * Copyright(C) 2005-2006, Red Hat, Inc., Ingo Molnar
7 * 7 *
8 * This file contains the needed initializations to support sysenter. 8 * This file contains the needed initializations to support sysenter.
9 */ 9 */
10 10
11 #include <linux/init.h> 11 #include <linux/init.h>
12 #include <linux/smp.h> 12 #include <linux/smp.h>
13 #include <linux/thread_info.h> 13 #include <linux/thread_info.h>
14 #include <linux/sched.h> 14 #include <linux/sched.h>
15 #include <linux/gfp.h> 15 #include <linux/gfp.h>
16 #include <linux/string.h> 16 #include <linux/string.h>
17 #include <linux/elf.h> 17 #include <linux/elf.h>
18 #include <linux/mm.h> 18 #include <linux/mm.h>
19 #include <linux/module.h> 19 #include <linux/module.h>
20 20
21 #include <asm/cpufeature.h> 21 #include <asm/cpufeature.h>
22 #include <asm/msr.h> 22 #include <asm/msr.h>
23 #include <asm/pgtable.h> 23 #include <asm/pgtable.h>
24 #include <asm/unistd.h> 24 #include <asm/unistd.h>
25 25
26 /* 26 /*
27 * Should the kernel map a VDSO page into processes and pass its 27 * Should the kernel map a VDSO page into processes and pass its
28 * address down to glibc upon exec()? 28 * address down to glibc upon exec()?
29 */ 29 */
30 #ifdef CONFIG_PARAVIRT 30 #ifdef CONFIG_PARAVIRT
31 unsigned int __read_mostly vdso_enabled = 0; 31 unsigned int __read_mostly vdso_enabled = 0;
32 #else 32 #else
33 unsigned int __read_mostly vdso_enabled = 1; 33 unsigned int __read_mostly vdso_enabled = 1;
34 #endif 34 #endif
35 35
36 EXPORT_SYMBOL_GPL(vdso_enabled); 36 EXPORT_SYMBOL_GPL(vdso_enabled);
37 37
38 static int __init vdso_setup(char *s) 38 static int __init vdso_setup(char *s)
39 { 39 {
40 vdso_enabled = simple_strtoul(s, NULL, 0); 40 vdso_enabled = simple_strtoul(s, NULL, 0);
41 41
42 return 1; 42 return 1;
43 } 43 }
44 44
45 __setup("vdso=", vdso_setup); 45 __setup("vdso=", vdso_setup);
46 46
47 extern asmlinkage void sysenter_entry(void); 47 extern asmlinkage void sysenter_entry(void);
48 48
49 void enable_sep_cpu(void) 49 void enable_sep_cpu(void)
50 { 50 {
51 int cpu = get_cpu(); 51 int cpu = get_cpu();
52 struct tss_struct *tss = &per_cpu(init_tss, cpu); 52 struct tss_struct *tss = &per_cpu(init_tss, cpu);
53 53
54 if (!boot_cpu_has(X86_FEATURE_SEP)) { 54 if (!boot_cpu_has(X86_FEATURE_SEP)) {
55 put_cpu(); 55 put_cpu();
56 return; 56 return;
57 } 57 }
58 58
59 tss->ss1 = __KERNEL_CS; 59 tss->ss1 = __KERNEL_CS;
60 tss->esp1 = sizeof(struct tss_struct) + (unsigned long) tss; 60 tss->esp1 = sizeof(struct tss_struct) + (unsigned long) tss;
61 wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); 61 wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
62 wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp1, 0); 62 wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp1, 0);
63 wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0); 63 wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0);
64 put_cpu(); 64 put_cpu();
65 } 65 }
66 66
67 /* 67 /*
68 * These symbols are defined by vsyscall.o to mark the bounds 68 * These symbols are defined by vsyscall.o to mark the bounds
69 * of the ELF DSO images included therein. 69 * of the ELF DSO images included therein.
70 */ 70 */
71 extern const char vsyscall_int80_start, vsyscall_int80_end; 71 extern const char vsyscall_int80_start, vsyscall_int80_end;
72 extern const char vsyscall_sysenter_start, vsyscall_sysenter_end; 72 extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;
73 static void *syscall_page; 73 static void *syscall_page;
74 74
75 int __init sysenter_setup(void) 75 int __init sysenter_setup(void)
76 { 76 {
77 syscall_page = (void *)get_zeroed_page(GFP_ATOMIC); 77 syscall_page = (void *)get_zeroed_page(GFP_ATOMIC);
78 78
79 #ifdef CONFIG_COMPAT_VDSO 79 #ifdef CONFIG_COMPAT_VDSO
80 __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY); 80 __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY);
81 printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO)); 81 printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO));
82 #else 82 #else
83 /* 83 /*
84 * In the non-compat case the ELF coredumping code needs the fixmap: 84 * In the non-compat case the ELF coredumping code needs the fixmap:
85 */ 85 */
86 __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_KERNEL_RO); 86 __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_KERNEL_RO);
87 #endif 87 #endif
88 88
89 if (!boot_cpu_has(X86_FEATURE_SEP)) { 89 if (!boot_cpu_has(X86_FEATURE_SEP)) {
90 memcpy(syscall_page, 90 memcpy(syscall_page,
91 &vsyscall_int80_start, 91 &vsyscall_int80_start,
92 &vsyscall_int80_end - &vsyscall_int80_start); 92 &vsyscall_int80_end - &vsyscall_int80_start);
93 return 0; 93 return 0;
94 } 94 }
95 95
96 memcpy(syscall_page, 96 memcpy(syscall_page,
97 &vsyscall_sysenter_start, 97 &vsyscall_sysenter_start,
98 &vsyscall_sysenter_end - &vsyscall_sysenter_start); 98 &vsyscall_sysenter_end - &vsyscall_sysenter_start);
99 99
100 return 0; 100 return 0;
101 } 101 }
102 102
103 #ifndef CONFIG_COMPAT_VDSO
103 static struct page *syscall_nopage(struct vm_area_struct *vma, 104 static struct page *syscall_nopage(struct vm_area_struct *vma,
104 unsigned long adr, int *type) 105 unsigned long adr, int *type)
105 { 106 {
106 struct page *p = virt_to_page(adr - vma->vm_start + syscall_page); 107 struct page *p = virt_to_page(adr - vma->vm_start + syscall_page);
107 get_page(p); 108 get_page(p);
108 return p; 109 return p;
109 } 110 }
110 111
111 /* Prevent VMA merging */ 112 /* Prevent VMA merging */
112 static void syscall_vma_close(struct vm_area_struct *vma) 113 static void syscall_vma_close(struct vm_area_struct *vma)
113 { 114 {
114 } 115 }
115 116
116 static struct vm_operations_struct syscall_vm_ops = { 117 static struct vm_operations_struct syscall_vm_ops = {
117 .close = syscall_vma_close, 118 .close = syscall_vma_close,
118 .nopage = syscall_nopage, 119 .nopage = syscall_nopage,
119 }; 120 };
120 121
121 /* Defined in vsyscall-sysenter.S */ 122 /* Defined in vsyscall-sysenter.S */
122 extern void SYSENTER_RETURN; 123 extern void SYSENTER_RETURN;
123 124
124 /* Setup a VMA at program startup for the vsyscall page */ 125 /* Setup a VMA at program startup for the vsyscall page */
125 int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) 126 int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack)
126 { 127 {
127 struct vm_area_struct *vma; 128 struct vm_area_struct *vma;
128 struct mm_struct *mm = current->mm; 129 struct mm_struct *mm = current->mm;
129 unsigned long addr; 130 unsigned long addr;
130 int ret; 131 int ret;
131 132
132 down_write(&mm->mmap_sem); 133 down_write(&mm->mmap_sem);
133 addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0); 134 addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
134 if (IS_ERR_VALUE(addr)) { 135 if (IS_ERR_VALUE(addr)) {
135 ret = addr; 136 ret = addr;
136 goto up_fail; 137 goto up_fail;
137 } 138 }
138 139
139 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); 140 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
140 if (!vma) { 141 if (!vma) {
141 ret = -ENOMEM; 142 ret = -ENOMEM;
142 goto up_fail; 143 goto up_fail;
143 } 144 }
144 145
145 vma->vm_start = addr; 146 vma->vm_start = addr;
146 vma->vm_end = addr + PAGE_SIZE; 147 vma->vm_end = addr + PAGE_SIZE;
147 /* MAYWRITE to allow gdb to COW and set breakpoints */ 148 /* MAYWRITE to allow gdb to COW and set breakpoints */
148 vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; 149 vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE;
149 vma->vm_flags |= mm->def_flags; 150 vma->vm_flags |= mm->def_flags;
150 vma->vm_page_prot = protection_map[vma->vm_flags & 7]; 151 vma->vm_page_prot = protection_map[vma->vm_flags & 7];
151 vma->vm_ops = &syscall_vm_ops; 152 vma->vm_ops = &syscall_vm_ops;
152 vma->vm_mm = mm; 153 vma->vm_mm = mm;
153 154
154 ret = insert_vm_struct(mm, vma); 155 ret = insert_vm_struct(mm, vma);
155 if (unlikely(ret)) { 156 if (unlikely(ret)) {
156 kmem_cache_free(vm_area_cachep, vma); 157 kmem_cache_free(vm_area_cachep, vma);
157 goto up_fail; 158 goto up_fail;
158 } 159 }
159 160
160 current->mm->context.vdso = (void *)addr; 161 current->mm->context.vdso = (void *)addr;
161 current_thread_info()->sysenter_return = 162 current_thread_info()->sysenter_return =
162 (void *)VDSO_SYM(&SYSENTER_RETURN); 163 (void *)VDSO_SYM(&SYSENTER_RETURN);
163 mm->total_vm++; 164 mm->total_vm++;
164 up_fail: 165 up_fail:
165 up_write(&mm->mmap_sem); 166 up_write(&mm->mmap_sem);
166 return ret; 167 return ret;
167 } 168 }
168 169
169 const char *arch_vma_name(struct vm_area_struct *vma) 170 const char *arch_vma_name(struct vm_area_struct *vma)
170 { 171 {
171 if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) 172 if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
172 return "[vdso]"; 173 return "[vdso]";
173 return NULL; 174 return NULL;
174 } 175 }
175 176
176 struct vm_area_struct *get_gate_vma(struct task_struct *tsk) 177 struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
177 { 178 {
178 return NULL; 179 return NULL;
179 } 180 }
180 181
181 int in_gate_area(struct task_struct *task, unsigned long addr) 182 int in_gate_area(struct task_struct *task, unsigned long addr)
182 { 183 {
183 return 0; 184 return 0;
184 } 185 }
185 186
186 int in_gate_area_no_task(unsigned long addr) 187 int in_gate_area_no_task(unsigned long addr)
187 { 188 {
188 return 0; 189 return 0;
189 } 190 }
191 #endif
190 192
include/asm-i386/elf.h
1 #ifndef __ASMi386_ELF_H 1 #ifndef __ASMi386_ELF_H
2 #define __ASMi386_ELF_H 2 #define __ASMi386_ELF_H
3 3
4 /* 4 /*
5 * ELF register definitions.. 5 * ELF register definitions..
6 */ 6 */
7 7
8 #include <asm/ptrace.h> 8 #include <asm/ptrace.h>
9 #include <asm/user.h> 9 #include <asm/user.h>
10 #include <asm/auxvec.h> 10 #include <asm/auxvec.h>
11 11
12 #include <linux/utsname.h> 12 #include <linux/utsname.h>
13 13
14 #define R_386_NONE 0 14 #define R_386_NONE 0
15 #define R_386_32 1 15 #define R_386_32 1
16 #define R_386_PC32 2 16 #define R_386_PC32 2
17 #define R_386_GOT32 3 17 #define R_386_GOT32 3
18 #define R_386_PLT32 4 18 #define R_386_PLT32 4
19 #define R_386_COPY 5 19 #define R_386_COPY 5
20 #define R_386_GLOB_DAT 6 20 #define R_386_GLOB_DAT 6
21 #define R_386_JMP_SLOT 7 21 #define R_386_JMP_SLOT 7
22 #define R_386_RELATIVE 8 22 #define R_386_RELATIVE 8
23 #define R_386_GOTOFF 9 23 #define R_386_GOTOFF 9
24 #define R_386_GOTPC 10 24 #define R_386_GOTPC 10
25 #define R_386_NUM 11 25 #define R_386_NUM 11
26 26
27 typedef unsigned long elf_greg_t; 27 typedef unsigned long elf_greg_t;
28 28
29 #define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) 29 #define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
30 typedef elf_greg_t elf_gregset_t[ELF_NGREG]; 30 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
31 31
32 typedef struct user_i387_struct elf_fpregset_t; 32 typedef struct user_i387_struct elf_fpregset_t;
33 typedef struct user_fxsr_struct elf_fpxregset_t; 33 typedef struct user_fxsr_struct elf_fpxregset_t;
34 34
35 /* 35 /*
36 * This is used to ensure we don't load something for the wrong architecture. 36 * This is used to ensure we don't load something for the wrong architecture.
37 */ 37 */
38 #define elf_check_arch(x) \ 38 #define elf_check_arch(x) \
39 (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486)) 39 (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486))
40 40
41 /* 41 /*
42 * These are used to set parameters in the core dumps. 42 * These are used to set parameters in the core dumps.
43 */ 43 */
44 #define ELF_CLASS ELFCLASS32 44 #define ELF_CLASS ELFCLASS32
45 #define ELF_DATA ELFDATA2LSB 45 #define ELF_DATA ELFDATA2LSB
46 #define ELF_ARCH EM_386 46 #define ELF_ARCH EM_386
47 47
48 #ifdef __KERNEL__ 48 #ifdef __KERNEL__
49 49
50 #include <asm/processor.h> 50 #include <asm/processor.h>
51 #include <asm/system.h> /* for savesegment */ 51 #include <asm/system.h> /* for savesegment */
52 #include <asm/desc.h> 52 #include <asm/desc.h>
53 53
54 /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program starts %edx 54 /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program starts %edx
55 contains a pointer to a function which might be registered using `atexit'. 55 contains a pointer to a function which might be registered using `atexit'.
56 This provides a mean for the dynamic linker to call DT_FINI functions for 56 This provides a mean for the dynamic linker to call DT_FINI functions for
57 shared libraries that have been loaded before the code runs. 57 shared libraries that have been loaded before the code runs.
58 58
59 A value of 0 tells we have no such handler. 59 A value of 0 tells we have no such handler.
60 60
61 We might as well make sure everything else is cleared too (except for %esp), 61 We might as well make sure everything else is cleared too (except for %esp),
62 just to make things more deterministic. 62 just to make things more deterministic.
63 */ 63 */
64 #define ELF_PLAT_INIT(_r, load_addr) do { \ 64 #define ELF_PLAT_INIT(_r, load_addr) do { \
65 _r->ebx = 0; _r->ecx = 0; _r->edx = 0; \ 65 _r->ebx = 0; _r->ecx = 0; _r->edx = 0; \
66 _r->esi = 0; _r->edi = 0; _r->ebp = 0; \ 66 _r->esi = 0; _r->edi = 0; _r->ebp = 0; \
67 _r->eax = 0; \ 67 _r->eax = 0; \
68 } while (0) 68 } while (0)
69 69
70 #define USE_ELF_CORE_DUMP 70 #define USE_ELF_CORE_DUMP
71 #define ELF_EXEC_PAGESIZE 4096 71 #define ELF_EXEC_PAGESIZE 4096
72 72
73 /* This is the location that an ET_DYN program is loaded if exec'ed. Typical 73 /* This is the location that an ET_DYN program is loaded if exec'ed. Typical
74 use of this is to invoke "./ld.so someprog" to test out a new version of 74 use of this is to invoke "./ld.so someprog" to test out a new version of
75 the loader. We need to make sure that it is out of the way of the program 75 the loader. We need to make sure that it is out of the way of the program
76 that it will "exec", and that there is sufficient room for the brk. */ 76 that it will "exec", and that there is sufficient room for the brk. */
77 77
78 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) 78 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
79 79
80 /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is 80 /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
81 now struct_user_regs, they are different) */ 81 now struct_user_regs, they are different) */
82 82
83 #define ELF_CORE_COPY_REGS(pr_reg, regs) \ 83 #define ELF_CORE_COPY_REGS(pr_reg, regs) \
84 pr_reg[0] = regs->ebx; \ 84 pr_reg[0] = regs->ebx; \
85 pr_reg[1] = regs->ecx; \ 85 pr_reg[1] = regs->ecx; \
86 pr_reg[2] = regs->edx; \ 86 pr_reg[2] = regs->edx; \
87 pr_reg[3] = regs->esi; \ 87 pr_reg[3] = regs->esi; \
88 pr_reg[4] = regs->edi; \ 88 pr_reg[4] = regs->edi; \
89 pr_reg[5] = regs->ebp; \ 89 pr_reg[5] = regs->ebp; \
90 pr_reg[6] = regs->eax; \ 90 pr_reg[6] = regs->eax; \
91 pr_reg[7] = regs->xds; \ 91 pr_reg[7] = regs->xds; \
92 pr_reg[8] = regs->xes; \ 92 pr_reg[8] = regs->xes; \
93 savesegment(fs,pr_reg[9]); \ 93 savesegment(fs,pr_reg[9]); \
94 pr_reg[10] = regs->xgs; \ 94 pr_reg[10] = regs->xgs; \
95 pr_reg[11] = regs->orig_eax; \ 95 pr_reg[11] = regs->orig_eax; \
96 pr_reg[12] = regs->eip; \ 96 pr_reg[12] = regs->eip; \
97 pr_reg[13] = regs->xcs; \ 97 pr_reg[13] = regs->xcs; \
98 pr_reg[14] = regs->eflags; \ 98 pr_reg[14] = regs->eflags; \
99 pr_reg[15] = regs->esp; \ 99 pr_reg[15] = regs->esp; \
100 pr_reg[16] = regs->xss; 100 pr_reg[16] = regs->xss;
101 101
102 /* This yields a mask that user programs can use to figure out what 102 /* This yields a mask that user programs can use to figure out what
103 instruction set this CPU supports. This could be done in user space, 103 instruction set this CPU supports. This could be done in user space,
104 but it's not easy, and we've already done it here. */ 104 but it's not easy, and we've already done it here. */
105 105
106 #define ELF_HWCAP (boot_cpu_data.x86_capability[0]) 106 #define ELF_HWCAP (boot_cpu_data.x86_capability[0])
107 107
108 /* This yields a string that ld.so will use to load implementation 108 /* This yields a string that ld.so will use to load implementation
109 specific libraries for optimization. This is more specific in 109 specific libraries for optimization. This is more specific in
110 intent than poking at uname or /proc/cpuinfo. 110 intent than poking at uname or /proc/cpuinfo.
111 111
112 For the moment, we have only optimizations for the Intel generations, 112 For the moment, we have only optimizations for the Intel generations,
113 but that could change... */ 113 but that could change... */
114 114
115 #define ELF_PLATFORM (utsname()->machine) 115 #define ELF_PLATFORM (utsname()->machine)
116 116
117 #define SET_PERSONALITY(ex, ibcs2) do { } while (0) 117 #define SET_PERSONALITY(ex, ibcs2) do { } while (0)
118 118
119 /* 119 /*
120 * An executable for which elf_read_implies_exec() returns TRUE will 120 * An executable for which elf_read_implies_exec() returns TRUE will
121 * have the READ_IMPLIES_EXEC personality flag set automatically. 121 * have the READ_IMPLIES_EXEC personality flag set automatically.
122 */ 122 */
123 #define elf_read_implies_exec(ex, executable_stack) (executable_stack != EXSTACK_DISABLE_X) 123 #define elf_read_implies_exec(ex, executable_stack) (executable_stack != EXSTACK_DISABLE_X)
124 124
125 struct task_struct; 125 struct task_struct;
126 126
127 extern int dump_task_regs (struct task_struct *, elf_gregset_t *); 127 extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
128 extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *); 128 extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
129 extern int dump_task_extended_fpu (struct task_struct *, struct user_fxsr_struct *); 129 extern int dump_task_extended_fpu (struct task_struct *, struct user_fxsr_struct *);
130 130
131 #define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs) 131 #define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs)
132 #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs) 132 #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
133 #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs) 133 #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)
134 134
135 #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO)) 135 #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO))
136 #define VDSO_BASE ((unsigned long)current->mm->context.vdso) 136 #define VDSO_BASE ((unsigned long)current->mm->context.vdso)
137 137
138 #ifdef CONFIG_COMPAT_VDSO 138 #ifdef CONFIG_COMPAT_VDSO
139 # define VDSO_COMPAT_BASE VDSO_HIGH_BASE 139 # define VDSO_COMPAT_BASE VDSO_HIGH_BASE
140 # define VDSO_PRELINK VDSO_HIGH_BASE 140 # define VDSO_PRELINK VDSO_HIGH_BASE
141 #else 141 #else
142 # define VDSO_COMPAT_BASE VDSO_BASE 142 # define VDSO_COMPAT_BASE VDSO_BASE
143 # define VDSO_PRELINK 0 143 # define VDSO_PRELINK 0
144 #endif 144 #endif
145 145
146 #define VDSO_COMPAT_SYM(x) \ 146 #define VDSO_SYM(x) \
147 (VDSO_COMPAT_BASE + (unsigned long)(x) - VDSO_PRELINK) 147 (VDSO_COMPAT_BASE + (unsigned long)(x) - VDSO_PRELINK)
148 148
149 #define VDSO_SYM(x) \
150 (VDSO_BASE + (unsigned long)(x) - VDSO_PRELINK)
151
152 #define VDSO_HIGH_EHDR ((const struct elfhdr *) VDSO_HIGH_BASE) 149 #define VDSO_HIGH_EHDR ((const struct elfhdr *) VDSO_HIGH_BASE)
153 #define VDSO_EHDR ((const struct elfhdr *) VDSO_COMPAT_BASE) 150 #define VDSO_EHDR ((const struct elfhdr *) VDSO_COMPAT_BASE)
154 151
155 extern void __kernel_vsyscall; 152 extern void __kernel_vsyscall;
156 153
157 #define VDSO_ENTRY VDSO_SYM(&__kernel_vsyscall) 154 #define VDSO_ENTRY VDSO_SYM(&__kernel_vsyscall)
158 155
156 #ifndef CONFIG_COMPAT_VDSO
159 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 157 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
160 struct linux_binprm; 158 struct linux_binprm;
161 extern int arch_setup_additional_pages(struct linux_binprm *bprm, 159 extern int arch_setup_additional_pages(struct linux_binprm *bprm,
162 int executable_stack); 160 int executable_stack);
161 #endif
163 162
164 extern unsigned int vdso_enabled; 163 extern unsigned int vdso_enabled;
165 164
166 #define ARCH_DLINFO \ 165 #define ARCH_DLINFO \
167 do if (vdso_enabled) { \ 166 do if (vdso_enabled) { \
168 NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \ 167 NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \
169 NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_COMPAT_BASE); \ 168 NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_COMPAT_BASE); \
170 } while (0) 169 } while (0)
171 170
172 /* 171 /*
173 * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out 172 * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
174 * extra segments containing the vsyscall DSO contents. Dumping its 173 * extra segments containing the vsyscall DSO contents. Dumping its
175 * contents makes post-mortem fully interpretable later without matching up 174 * contents makes post-mortem fully interpretable later without matching up
176 * the same kernel and hardware config to see what PC values meant. 175 * the same kernel and hardware config to see what PC values meant.
177 * Dumping its extra ELF program headers includes all the other information 176 * Dumping its extra ELF program headers includes all the other information
178 * a debugger needs to easily find how the vsyscall DSO was being used. 177 * a debugger needs to easily find how the vsyscall DSO was being used.
179 */ 178 */
180 #define ELF_CORE_EXTRA_PHDRS (VDSO_HIGH_EHDR->e_phnum) 179 #define ELF_CORE_EXTRA_PHDRS (VDSO_HIGH_EHDR->e_phnum)
181 #define ELF_CORE_WRITE_EXTRA_PHDRS \ 180 #define ELF_CORE_WRITE_EXTRA_PHDRS \
182 do { \ 181 do { \
183 const struct elf_phdr *const vsyscall_phdrs = \ 182 const struct elf_phdr *const vsyscall_phdrs = \
184 (const struct elf_phdr *) (VDSO_HIGH_BASE \ 183 (const struct elf_phdr *) (VDSO_HIGH_BASE \
185 + VDSO_HIGH_EHDR->e_phoff); \ 184 + VDSO_HIGH_EHDR->e_phoff); \
186 int i; \ 185 int i; \
187 Elf32_Off ofs = 0; \ 186 Elf32_Off ofs = 0; \
188 for (i = 0; i < VDSO_HIGH_EHDR->e_phnum; ++i) { \ 187 for (i = 0; i < VDSO_HIGH_EHDR->e_phnum; ++i) { \
189 struct elf_phdr phdr = vsyscall_phdrs[i]; \ 188 struct elf_phdr phdr = vsyscall_phdrs[i]; \
190 if (phdr.p_type == PT_LOAD) { \ 189 if (phdr.p_type == PT_LOAD) { \
191 BUG_ON(ofs != 0); \ 190 BUG_ON(ofs != 0); \
192 ofs = phdr.p_offset = offset; \ 191 ofs = phdr.p_offset = offset; \
193 phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \ 192 phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \
194 phdr.p_filesz = phdr.p_memsz; \ 193 phdr.p_filesz = phdr.p_memsz; \
195 offset += phdr.p_filesz; \ 194 offset += phdr.p_filesz; \
196 } \ 195 } \
197 else \ 196 else \
198 phdr.p_offset += ofs; \ 197 phdr.p_offset += ofs; \
199 phdr.p_paddr = 0; /* match other core phdrs */ \ 198 phdr.p_paddr = 0; /* match other core phdrs */ \
200 DUMP_WRITE(&phdr, sizeof(phdr)); \ 199 DUMP_WRITE(&phdr, sizeof(phdr)); \
201 } \ 200 } \
202 } while (0) 201 } while (0)
203 #define ELF_CORE_WRITE_EXTRA_DATA \ 202 #define ELF_CORE_WRITE_EXTRA_DATA \
204 do { \ 203 do { \
205 const struct elf_phdr *const vsyscall_phdrs = \ 204 const struct elf_phdr *const vsyscall_phdrs = \
206 (const struct elf_phdr *) (VDSO_HIGH_BASE \ 205 (const struct elf_phdr *) (VDSO_HIGH_BASE \
207 + VDSO_HIGH_EHDR->e_phoff); \ 206 + VDSO_HIGH_EHDR->e_phoff); \
208 int i; \ 207 int i; \
209 for (i = 0; i < VDSO_HIGH_EHDR->e_phnum; ++i) { \ 208 for (i = 0; i < VDSO_HIGH_EHDR->e_phnum; ++i) { \
210 if (vsyscall_phdrs[i].p_type == PT_LOAD) \ 209 if (vsyscall_phdrs[i].p_type == PT_LOAD) \
211 DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr, \ 210 DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr, \
212 PAGE_ALIGN(vsyscall_phdrs[i].p_memsz)); \ 211 PAGE_ALIGN(vsyscall_phdrs[i].p_memsz)); \
213 } \ 212 } \
214 } while (0) 213 } while (0)
215 214
216 #endif 215 #endif
217 216
include/asm-i386/fixmap.h
1 /* 1 /*
2 * fixmap.h: compile-time virtual memory allocation 2 * fixmap.h: compile-time virtual memory allocation
3 * 3 *
4 * This file is subject to the terms and conditions of the GNU General Public 4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive 5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details. 6 * for more details.
7 * 7 *
8 * Copyright (C) 1998 Ingo Molnar 8 * Copyright (C) 1998 Ingo Molnar
9 * 9 *
10 * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 10 * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
11 */ 11 */
12 12
13 #ifndef _ASM_FIXMAP_H 13 #ifndef _ASM_FIXMAP_H
14 #define _ASM_FIXMAP_H 14 #define _ASM_FIXMAP_H
15 15
16 16
17 /* used by vmalloc.c, vsyscall.lds.S. 17 /* used by vmalloc.c, vsyscall.lds.S.
18 * 18 *
19 * Leave one empty page between vmalloc'ed areas and 19 * Leave one empty page between vmalloc'ed areas and
20 * the start of the fixmap. 20 * the start of the fixmap.
21 */ 21 */
22 #ifndef CONFIG_COMPAT_VDSO 22 #ifndef CONFIG_COMPAT_VDSO
23 extern unsigned long __FIXADDR_TOP; 23 extern unsigned long __FIXADDR_TOP;
24 #else 24 #else
25 #define __FIXADDR_TOP 0xfffff000 25 #define __FIXADDR_TOP 0xfffff000
26 #define FIXADDR_USER_START __fix_to_virt(FIX_VDSO)
27 #define FIXADDR_USER_END __fix_to_virt(FIX_VDSO - 1)
26 #endif 28 #endif
27 29
28 #ifndef __ASSEMBLY__ 30 #ifndef __ASSEMBLY__
29 #include <linux/kernel.h> 31 #include <linux/kernel.h>
30 #include <asm/acpi.h> 32 #include <asm/acpi.h>
31 #include <asm/apicdef.h> 33 #include <asm/apicdef.h>
32 #include <asm/page.h> 34 #include <asm/page.h>
33 #ifdef CONFIG_HIGHMEM 35 #ifdef CONFIG_HIGHMEM
34 #include <linux/threads.h> 36 #include <linux/threads.h>
35 #include <asm/kmap_types.h> 37 #include <asm/kmap_types.h>
36 #endif 38 #endif
37 39
38 /* 40 /*
39 * Here we define all the compile-time 'special' virtual 41 * Here we define all the compile-time 'special' virtual
40 * addresses. The point is to have a constant address at 42 * addresses. The point is to have a constant address at
41 * compile time, but to set the physical address only 43 * compile time, but to set the physical address only
42 * in the boot process. We allocate these special addresses 44 * in the boot process. We allocate these special addresses
43 * from the end of virtual memory (0xfffff000) backwards. 45 * from the end of virtual memory (0xfffff000) backwards.
44 * Also this lets us do fail-safe vmalloc(), we 46 * Also this lets us do fail-safe vmalloc(), we
45 * can guarantee that these special addresses and 47 * can guarantee that these special addresses and
46 * vmalloc()-ed addresses never overlap. 48 * vmalloc()-ed addresses never overlap.
47 * 49 *
48 * these 'compile-time allocated' memory buffers are 50 * these 'compile-time allocated' memory buffers are
49 * fixed-size 4k pages. (or larger if used with an increment 51 * fixed-size 4k pages. (or larger if used with an increment
50 * highger than 1) use fixmap_set(idx,phys) to associate 52 * highger than 1) use fixmap_set(idx,phys) to associate
51 * physical memory with fixmap indices. 53 * physical memory with fixmap indices.
52 * 54 *
53 * TLB entries of such buffers will not be flushed across 55 * TLB entries of such buffers will not be flushed across
54 * task switches. 56 * task switches.
55 */ 57 */
56 enum fixed_addresses { 58 enum fixed_addresses {
57 FIX_HOLE, 59 FIX_HOLE,
58 FIX_VDSO, 60 FIX_VDSO,
59 #ifdef CONFIG_X86_LOCAL_APIC 61 #ifdef CONFIG_X86_LOCAL_APIC
60 FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */ 62 FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */
61 #endif 63 #endif
62 #ifdef CONFIG_X86_IO_APIC 64 #ifdef CONFIG_X86_IO_APIC
63 FIX_IO_APIC_BASE_0, 65 FIX_IO_APIC_BASE_0,
64 FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1, 66 FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1,
65 #endif 67 #endif
66 #ifdef CONFIG_X86_VISWS_APIC 68 #ifdef CONFIG_X86_VISWS_APIC
67 FIX_CO_CPU, /* Cobalt timer */ 69 FIX_CO_CPU, /* Cobalt timer */
68 FIX_CO_APIC, /* Cobalt APIC Redirection Table */ 70 FIX_CO_APIC, /* Cobalt APIC Redirection Table */
69 FIX_LI_PCIA, /* Lithium PCI Bridge A */ 71 FIX_LI_PCIA, /* Lithium PCI Bridge A */
70 FIX_LI_PCIB, /* Lithium PCI Bridge B */ 72 FIX_LI_PCIB, /* Lithium PCI Bridge B */
71 #endif 73 #endif
72 #ifdef CONFIG_X86_F00F_BUG 74 #ifdef CONFIG_X86_F00F_BUG
73 FIX_F00F_IDT, /* Virtual mapping for IDT */ 75 FIX_F00F_IDT, /* Virtual mapping for IDT */
74 #endif 76 #endif
75 #ifdef CONFIG_X86_CYCLONE_TIMER 77 #ifdef CONFIG_X86_CYCLONE_TIMER
76 FIX_CYCLONE_TIMER, /*cyclone timer register*/ 78 FIX_CYCLONE_TIMER, /*cyclone timer register*/
77 #endif 79 #endif
78 #ifdef CONFIG_HIGHMEM 80 #ifdef CONFIG_HIGHMEM
79 FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ 81 FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
80 FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, 82 FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
81 #endif 83 #endif
82 #ifdef CONFIG_ACPI 84 #ifdef CONFIG_ACPI
83 FIX_ACPI_BEGIN, 85 FIX_ACPI_BEGIN,
84 FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1, 86 FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
85 #endif 87 #endif
86 #ifdef CONFIG_PCI_MMCONFIG 88 #ifdef CONFIG_PCI_MMCONFIG
87 FIX_PCIE_MCFG, 89 FIX_PCIE_MCFG,
88 #endif 90 #endif
89 __end_of_permanent_fixed_addresses, 91 __end_of_permanent_fixed_addresses,
90 /* temporary boot-time mappings, used before ioremap() is functional */ 92 /* temporary boot-time mappings, used before ioremap() is functional */
91 #define NR_FIX_BTMAPS 16 93 #define NR_FIX_BTMAPS 16
92 FIX_BTMAP_END = __end_of_permanent_fixed_addresses, 94 FIX_BTMAP_END = __end_of_permanent_fixed_addresses,
93 FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1, 95 FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1,
94 FIX_WP_TEST, 96 FIX_WP_TEST,
95 __end_of_fixed_addresses 97 __end_of_fixed_addresses
96 }; 98 };
97 99
98 extern void __set_fixmap (enum fixed_addresses idx, 100 extern void __set_fixmap (enum fixed_addresses idx,
99 unsigned long phys, pgprot_t flags); 101 unsigned long phys, pgprot_t flags);
100 extern void reserve_top_address(unsigned long reserve); 102 extern void reserve_top_address(unsigned long reserve);
101 103
102 #define set_fixmap(idx, phys) \ 104 #define set_fixmap(idx, phys) \
103 __set_fixmap(idx, phys, PAGE_KERNEL) 105 __set_fixmap(idx, phys, PAGE_KERNEL)
104 /* 106 /*
105 * Some hardware wants to get fixmapped without caching. 107 * Some hardware wants to get fixmapped without caching.
106 */ 108 */
107 #define set_fixmap_nocache(idx, phys) \ 109 #define set_fixmap_nocache(idx, phys) \
108 __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE) 110 __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
109 111
110 #define clear_fixmap(idx) \ 112 #define clear_fixmap(idx) \
111 __set_fixmap(idx, 0, __pgprot(0)) 113 __set_fixmap(idx, 0, __pgprot(0))
112 114
113 #define FIXADDR_TOP ((unsigned long)__FIXADDR_TOP) 115 #define FIXADDR_TOP ((unsigned long)__FIXADDR_TOP)
114 116
115 #define __FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT) 117 #define __FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT)
116 #define __FIXADDR_BOOT_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) 118 #define __FIXADDR_BOOT_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
117 #define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE) 119 #define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE)
118 #define FIXADDR_BOOT_START (FIXADDR_TOP - __FIXADDR_BOOT_SIZE) 120 #define FIXADDR_BOOT_START (FIXADDR_TOP - __FIXADDR_BOOT_SIZE)
119 121
120 #define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT)) 122 #define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
121 #define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT) 123 #define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
122 124
123 extern void __this_fixmap_does_not_exist(void); 125 extern void __this_fixmap_does_not_exist(void);
124 126
125 /* 127 /*
126 * 'index to address' translation. If anyone tries to use the idx 128 * 'index to address' translation. If anyone tries to use the idx
127 * directly without tranlation, we catch the bug with a NULL-deference 129 * directly without tranlation, we catch the bug with a NULL-deference
128 * kernel oops. Illegal ranges of incoming indices are caught too. 130 * kernel oops. Illegal ranges of incoming indices are caught too.
129 */ 131 */
130 static __always_inline unsigned long fix_to_virt(const unsigned int idx) 132 static __always_inline unsigned long fix_to_virt(const unsigned int idx)
131 { 133 {
132 /* 134 /*
133 * this branch gets completely eliminated after inlining, 135 * this branch gets completely eliminated after inlining,
134 * except when someone tries to use fixaddr indices in an 136 * except when someone tries to use fixaddr indices in an
135 * illegal way. (such as mixing up address types or using 137 * illegal way. (such as mixing up address types or using
136 * out-of-range indices). 138 * out-of-range indices).
137 * 139 *
138 * If it doesn't get removed, the linker will complain 140 * If it doesn't get removed, the linker will complain
139 * loudly with a reasonably clear error message.. 141 * loudly with a reasonably clear error message..
140 */ 142 */
141 if (idx >= __end_of_fixed_addresses) 143 if (idx >= __end_of_fixed_addresses)
142 __this_fixmap_does_not_exist(); 144 __this_fixmap_does_not_exist();
143 145
144 return __fix_to_virt(idx); 146 return __fix_to_virt(idx);
145 } 147 }
146 148
147 static inline unsigned long virt_to_fix(const unsigned long vaddr) 149 static inline unsigned long virt_to_fix(const unsigned long vaddr)
148 { 150 {
149 BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); 151 BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
150 return __virt_to_fix(vaddr); 152 return __virt_to_fix(vaddr);
151 } 153 }
152 154
153 #endif /* !__ASSEMBLY__ */ 155 #endif /* !__ASSEMBLY__ */
154 #endif 156 #endif
155 157
include/asm-i386/page.h
1 #ifndef _I386_PAGE_H 1 #ifndef _I386_PAGE_H
2 #define _I386_PAGE_H 2 #define _I386_PAGE_H
3 3
4 /* PAGE_SHIFT determines the page size */ 4 /* PAGE_SHIFT determines the page size */
5 #define PAGE_SHIFT 12 5 #define PAGE_SHIFT 12
6 #define PAGE_SIZE (1UL << PAGE_SHIFT) 6 #define PAGE_SIZE (1UL << PAGE_SHIFT)
7 #define PAGE_MASK (~(PAGE_SIZE-1)) 7 #define PAGE_MASK (~(PAGE_SIZE-1))
8 8
9 #define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1)) 9 #define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1))
10 #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT) 10 #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
11 11
12 #ifdef __KERNEL__ 12 #ifdef __KERNEL__
13 #ifndef __ASSEMBLY__ 13 #ifndef __ASSEMBLY__
14 14
15 15
16 #ifdef CONFIG_X86_USE_3DNOW 16 #ifdef CONFIG_X86_USE_3DNOW
17 17
18 #include <asm/mmx.h> 18 #include <asm/mmx.h>
19 19
20 #define clear_page(page) mmx_clear_page((void *)(page)) 20 #define clear_page(page) mmx_clear_page((void *)(page))
21 #define copy_page(to,from) mmx_copy_page(to,from) 21 #define copy_page(to,from) mmx_copy_page(to,from)
22 22
23 #else 23 #else
24 24
25 /* 25 /*
26 * On older X86 processors it's not a win to use MMX here it seems. 26 * On older X86 processors it's not a win to use MMX here it seems.
27 * Maybe the K6-III ? 27 * Maybe the K6-III ?
28 */ 28 */
29 29
30 #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) 30 #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
31 #define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) 31 #define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE)
32 32
33 #endif 33 #endif
34 34
35 #define clear_user_page(page, vaddr, pg) clear_page(page) 35 #define clear_user_page(page, vaddr, pg) clear_page(page)
36 #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) 36 #define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
37 37
38 #define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr) 38 #define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr)
39 #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE 39 #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
40 40
41 /* 41 /*
42 * These are used to make use of C type-checking.. 42 * These are used to make use of C type-checking..
43 */ 43 */
44 extern int nx_enabled; 44 extern int nx_enabled;
45 #ifdef CONFIG_X86_PAE 45 #ifdef CONFIG_X86_PAE
46 extern unsigned long long __supported_pte_mask; 46 extern unsigned long long __supported_pte_mask;
47 typedef struct { unsigned long pte_low, pte_high; } pte_t; 47 typedef struct { unsigned long pte_low, pte_high; } pte_t;
48 typedef struct { unsigned long long pmd; } pmd_t; 48 typedef struct { unsigned long long pmd; } pmd_t;
49 typedef struct { unsigned long long pgd; } pgd_t; 49 typedef struct { unsigned long long pgd; } pgd_t;
50 typedef struct { unsigned long long pgprot; } pgprot_t; 50 typedef struct { unsigned long long pgprot; } pgprot_t;
51 #define pmd_val(x) ((x).pmd) 51 #define pmd_val(x) ((x).pmd)
52 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) 52 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
53 #define __pmd(x) ((pmd_t) { (x) } ) 53 #define __pmd(x) ((pmd_t) { (x) } )
54 #define HPAGE_SHIFT 21 54 #define HPAGE_SHIFT 21
55 #include <asm-generic/pgtable-nopud.h> 55 #include <asm-generic/pgtable-nopud.h>
56 #else 56 #else
57 typedef struct { unsigned long pte_low; } pte_t; 57 typedef struct { unsigned long pte_low; } pte_t;
58 typedef struct { unsigned long pgd; } pgd_t; 58 typedef struct { unsigned long pgd; } pgd_t;
59 typedef struct { unsigned long pgprot; } pgprot_t; 59 typedef struct { unsigned long pgprot; } pgprot_t;
60 #define boot_pte_t pte_t /* or would you rather have a typedef */ 60 #define boot_pte_t pte_t /* or would you rather have a typedef */
61 #define pte_val(x) ((x).pte_low) 61 #define pte_val(x) ((x).pte_low)
62 #define HPAGE_SHIFT 22 62 #define HPAGE_SHIFT 22
63 #include <asm-generic/pgtable-nopmd.h> 63 #include <asm-generic/pgtable-nopmd.h>
64 #endif 64 #endif
65 #define PTE_MASK PAGE_MASK 65 #define PTE_MASK PAGE_MASK
66 66
67 #ifdef CONFIG_HUGETLB_PAGE 67 #ifdef CONFIG_HUGETLB_PAGE
68 #define HPAGE_SIZE ((1UL) << HPAGE_SHIFT) 68 #define HPAGE_SIZE ((1UL) << HPAGE_SHIFT)
69 #define HPAGE_MASK (~(HPAGE_SIZE - 1)) 69 #define HPAGE_MASK (~(HPAGE_SIZE - 1))
70 #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) 70 #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
71 #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA 71 #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
72 #endif 72 #endif
73 73
74 #define pgd_val(x) ((x).pgd) 74 #define pgd_val(x) ((x).pgd)
75 #define pgprot_val(x) ((x).pgprot) 75 #define pgprot_val(x) ((x).pgprot)
76 76
77 #define __pte(x) ((pte_t) { (x) } ) 77 #define __pte(x) ((pte_t) { (x) } )
78 #define __pgd(x) ((pgd_t) { (x) } ) 78 #define __pgd(x) ((pgd_t) { (x) } )
79 #define __pgprot(x) ((pgprot_t) { (x) } ) 79 #define __pgprot(x) ((pgprot_t) { (x) } )
80 80
81 #endif /* !__ASSEMBLY__ */ 81 #endif /* !__ASSEMBLY__ */
82 82
83 /* to align the pointer to the (next) page boundary */ 83 /* to align the pointer to the (next) page boundary */
84 #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) 84 #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
85 85
86 /* 86 /*
87 * This handles the memory map.. We could make this a config 87 * This handles the memory map.. We could make this a config
88 * option, but too many people screw it up, and too few need 88 * option, but too many people screw it up, and too few need
89 * it. 89 * it.
90 * 90 *
91 * A __PAGE_OFFSET of 0xC0000000 means that the kernel has 91 * A __PAGE_OFFSET of 0xC0000000 means that the kernel has
92 * a virtual address space of one gigabyte, which limits the 92 * a virtual address space of one gigabyte, which limits the
93 * amount of physical memory you can use to about 950MB. 93 * amount of physical memory you can use to about 950MB.
94 * 94 *
95 * If you want more physical memory than this then see the CONFIG_HIGHMEM4G 95 * If you want more physical memory than this then see the CONFIG_HIGHMEM4G
96 * and CONFIG_HIGHMEM64G options in the kernel configuration. 96 * and CONFIG_HIGHMEM64G options in the kernel configuration.
97 */ 97 */
98 98
99 #ifndef __ASSEMBLY__ 99 #ifndef __ASSEMBLY__
100 100
101 struct vm_area_struct; 101 struct vm_area_struct;
102 102
103 /* 103 /*
104 * This much address space is reserved for vmalloc() and iomap() 104 * This much address space is reserved for vmalloc() and iomap()
105 * as well as fixmap mappings. 105 * as well as fixmap mappings.
106 */ 106 */
107 extern unsigned int __VMALLOC_RESERVE; 107 extern unsigned int __VMALLOC_RESERVE;
108 108
109 extern int sysctl_legacy_va_layout; 109 extern int sysctl_legacy_va_layout;
110 110
111 extern int page_is_ram(unsigned long pagenr); 111 extern int page_is_ram(unsigned long pagenr);
112 112
113 #endif /* __ASSEMBLY__ */ 113 #endif /* __ASSEMBLY__ */
114 114
115 #ifdef __ASSEMBLY__ 115 #ifdef __ASSEMBLY__
116 #define __PAGE_OFFSET CONFIG_PAGE_OFFSET 116 #define __PAGE_OFFSET CONFIG_PAGE_OFFSET
117 #else 117 #else
118 #define __PAGE_OFFSET ((unsigned long)CONFIG_PAGE_OFFSET) 118 #define __PAGE_OFFSET ((unsigned long)CONFIG_PAGE_OFFSET)
119 #endif 119 #endif
120 120
121 121
122 #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) 122 #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
123 #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE) 123 #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE)
124 #define MAXMEM (-__PAGE_OFFSET-__VMALLOC_RESERVE) 124 #define MAXMEM (-__PAGE_OFFSET-__VMALLOC_RESERVE)
125 #define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) 125 #define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
126 /* __pa_symbol should be used for C visible symbols. 126 /* __pa_symbol should be used for C visible symbols.
127 This seems to be the official gcc blessed way to do such arithmetic. */ 127 This seems to be the official gcc blessed way to do such arithmetic. */
128 #define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x),0)) 128 #define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x),0))
129 #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) 129 #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
130 #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) 130 #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
131 #ifdef CONFIG_FLATMEM 131 #ifdef CONFIG_FLATMEM
132 #define pfn_valid(pfn) ((pfn) < max_mapnr) 132 #define pfn_valid(pfn) ((pfn) < max_mapnr)
133 #endif /* CONFIG_FLATMEM */ 133 #endif /* CONFIG_FLATMEM */
134 #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) 134 #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
135 135
136 #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) 136 #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
137 137
138 #define VM_DATA_DEFAULT_FLAGS \ 138 #define VM_DATA_DEFAULT_FLAGS \
139 (VM_READ | VM_WRITE | \ 139 (VM_READ | VM_WRITE | \
140 ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ 140 ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
141 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) 141 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
142 142
143 #include <asm-generic/memory_model.h> 143 #include <asm-generic/memory_model.h>
144 #include <asm-generic/page.h> 144 #include <asm-generic/page.h>
145 145
146 #ifndef CONFIG_COMPAT_VDSO
146 #define __HAVE_ARCH_GATE_AREA 1 147 #define __HAVE_ARCH_GATE_AREA 1
148 #endif
147 #endif /* __KERNEL__ */ 149 #endif /* __KERNEL__ */
148 150
149 #endif /* _I386_PAGE_H */ 151 #endif /* _I386_PAGE_H */
150 152