• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/arch/x86/kernel/
1/*
2 *
3 *  Copyright (C) 1991, 1992  Linus Torvalds
4 */
5
6/*
7 * entry.S contains the system-call and fault low-level handling routines.
8 * This also contains the timer-interrupt handler, as well as all interrupts
9 * and faults that can result in a task-switch.
10 *
11 * NOTE: This code handles signal-recognition, which happens every time
12 * after a timer-interrupt and after each system call.
13 *
14 * I changed all the .align's to 4 (16 byte alignment), as that's faster
15 * on a 486.
16 *
17 * Stack layout in 'syscall_exit':
18 * 	ptrace needs to have all regs on the stack.
19 *	if the order here is changed, it needs to be
20 *	updated in fork.c:copy_process, signal.c:do_signal,
21 *	ptrace.c and ptrace.h
22 *
23 *	 0(%esp) - %ebx
24 *	 4(%esp) - %ecx
25 *	 8(%esp) - %edx
26 *       C(%esp) - %esi
27 *	10(%esp) - %edi
28 *	14(%esp) - %ebp
29 *	18(%esp) - %eax
30 *	1C(%esp) - %ds
31 *	20(%esp) - %es
32 *	24(%esp) - %fs
33 *	28(%esp) - %gs		saved iff !CONFIG_X86_32_LAZY_GS
34 *	2C(%esp) - orig_eax
35 *	30(%esp) - %eip
36 *	34(%esp) - %cs
37 *	38(%esp) - %eflags
38 *	3C(%esp) - %oldesp
39 *	40(%esp) - %oldss
40 *
41 * "current" is in register %ebx during any slow entries.
42 */
43
44#include <linux/linkage.h>
45#include <asm/thread_info.h>
46#include <asm/irqflags.h>
47#include <asm/errno.h>
48#include <asm/segment.h>
49#include <asm/smp.h>
50#include <asm/page_types.h>
51#include <asm/percpu.h>
52#include <asm/dwarf2.h>
53#include <asm/processor-flags.h>
54#include <asm/ftrace.h>
55#include <asm/irq_vectors.h>
56#include <asm/cpufeature.h>
57
58/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this.  */
59#include <linux/elf-em.h>
60#define AUDIT_ARCH_I386		(EM_386|__AUDIT_ARCH_LE)
61#define __AUDIT_ARCH_LE	   0x40000000
62
63#ifndef CONFIG_AUDITSYSCALL
64#define sysenter_audit	syscall_trace_entry
65#define sysexit_audit	syscall_exit_work
66#endif
67
68/*
69 * We use macros for low-level operations which need to be overridden
70 * for paravirtualization.  The following will never clobber any registers:
71 *   INTERRUPT_RETURN (aka. "iret")
72 *   GET_CR0_INTO_EAX (aka. "movl %cr0, %eax")
73 *   ENABLE_INTERRUPTS_SYSEXIT (aka "sti; sysexit").
74 *
75 * For DISABLE_INTERRUPTS/ENABLE_INTERRUPTS (aka "cli"/"sti"), you must
76 * specify what registers can be overwritten (CLBR_NONE, CLBR_EAX/EDX/ECX/ANY).
77 * Allowing a register to be clobbered can shrink the paravirt replacement
78 * enough to patch inline, increasing performance.
79 */
80
81#define nr_syscalls ((syscall_table_size)/4)
82
83#ifdef CONFIG_PREEMPT
84#define preempt_stop(clobbers)	DISABLE_INTERRUPTS(clobbers); TRACE_IRQS_OFF
85#else
86#define preempt_stop(clobbers)
87#define resume_kernel		restore_all
88#endif
89
90.macro TRACE_IRQS_IRET
91#ifdef CONFIG_TRACE_IRQFLAGS
92	testl $X86_EFLAGS_IF,PT_EFLAGS(%esp)     # interrupts off?
93	jz 1f
94	TRACE_IRQS_ON
951:
96#endif
97.endm
98
99#ifdef CONFIG_VM86
100#define resume_userspace_sig	check_userspace
101#else
102#define resume_userspace_sig	resume_userspace
103#endif
104
105/*
106 * User gs save/restore
107 *
108 * %gs is used for userland TLS and kernel only uses it for stack
109 * canary which is required to be at %gs:20 by gcc.  Read the comment
110 * at the top of stackprotector.h for more info.
111 *
112 * Local labels 98 and 99 are used.
113 */
114#ifdef CONFIG_X86_32_LAZY_GS
115
116 /* unfortunately push/pop can't be no-op */
117.macro PUSH_GS
118	pushl $0
119	CFI_ADJUST_CFA_OFFSET 4
120.endm
121.macro POP_GS pop=0
122	addl $(4 + \pop), %esp
123	CFI_ADJUST_CFA_OFFSET -(4 + \pop)
124.endm
125.macro POP_GS_EX
126.endm
127
128 /* all the rest are no-op */
129.macro PTGS_TO_GS
130.endm
131.macro PTGS_TO_GS_EX
132.endm
133.macro GS_TO_REG reg
134.endm
135.macro REG_TO_PTGS reg
136.endm
137.macro SET_KERNEL_GS reg
138.endm
139
140#else	/* CONFIG_X86_32_LAZY_GS */
141
142.macro PUSH_GS
143	pushl %gs
144	CFI_ADJUST_CFA_OFFSET 4
145	/*CFI_REL_OFFSET gs, 0*/
146.endm
147
148.macro POP_GS pop=0
14998:	popl %gs
150	CFI_ADJUST_CFA_OFFSET -4
151	/*CFI_RESTORE gs*/
152  .if \pop <> 0
153	add $\pop, %esp
154	CFI_ADJUST_CFA_OFFSET -\pop
155  .endif
156.endm
157.macro POP_GS_EX
158.pushsection .fixup, "ax"
15999:	movl $0, (%esp)
160	jmp 98b
161.section __ex_table, "a"
162	.align 4
163	.long 98b, 99b
164.popsection
165.endm
166
167.macro PTGS_TO_GS
16898:	mov PT_GS(%esp), %gs
169.endm
170.macro PTGS_TO_GS_EX
171.pushsection .fixup, "ax"
17299:	movl $0, PT_GS(%esp)
173	jmp 98b
174.section __ex_table, "a"
175	.align 4
176	.long 98b, 99b
177.popsection
178.endm
179
180.macro GS_TO_REG reg
181	movl %gs, \reg
182	/*CFI_REGISTER gs, \reg*/
183.endm
184.macro REG_TO_PTGS reg
185	movl \reg, PT_GS(%esp)
186	/*CFI_REL_OFFSET gs, PT_GS*/
187.endm
188.macro SET_KERNEL_GS reg
189	movl $(__KERNEL_STACK_CANARY), \reg
190	movl \reg, %gs
191.endm
192
193#endif	/* CONFIG_X86_32_LAZY_GS */
194
195.macro SAVE_ALL
196	cld
197	PUSH_GS
198	pushl %fs
199	CFI_ADJUST_CFA_OFFSET 4
200	/*CFI_REL_OFFSET fs, 0;*/
201	pushl %es
202	CFI_ADJUST_CFA_OFFSET 4
203	/*CFI_REL_OFFSET es, 0;*/
204	pushl %ds
205	CFI_ADJUST_CFA_OFFSET 4
206	/*CFI_REL_OFFSET ds, 0;*/
207	pushl %eax
208	CFI_ADJUST_CFA_OFFSET 4
209	CFI_REL_OFFSET eax, 0
210	pushl %ebp
211	CFI_ADJUST_CFA_OFFSET 4
212	CFI_REL_OFFSET ebp, 0
213	pushl %edi
214	CFI_ADJUST_CFA_OFFSET 4
215	CFI_REL_OFFSET edi, 0
216	pushl %esi
217	CFI_ADJUST_CFA_OFFSET 4
218	CFI_REL_OFFSET esi, 0
219	pushl %edx
220	CFI_ADJUST_CFA_OFFSET 4
221	CFI_REL_OFFSET edx, 0
222	pushl %ecx
223	CFI_ADJUST_CFA_OFFSET 4
224	CFI_REL_OFFSET ecx, 0
225	pushl %ebx
226	CFI_ADJUST_CFA_OFFSET 4
227	CFI_REL_OFFSET ebx, 0
228	movl $(__USER_DS), %edx
229	movl %edx, %ds
230	movl %edx, %es
231	movl $(__KERNEL_PERCPU), %edx
232	movl %edx, %fs
233	SET_KERNEL_GS %edx
234.endm
235
236.macro RESTORE_INT_REGS
237	popl %ebx
238	CFI_ADJUST_CFA_OFFSET -4
239	CFI_RESTORE ebx
240	popl %ecx
241	CFI_ADJUST_CFA_OFFSET -4
242	CFI_RESTORE ecx
243	popl %edx
244	CFI_ADJUST_CFA_OFFSET -4
245	CFI_RESTORE edx
246	popl %esi
247	CFI_ADJUST_CFA_OFFSET -4
248	CFI_RESTORE esi
249	popl %edi
250	CFI_ADJUST_CFA_OFFSET -4
251	CFI_RESTORE edi
252	popl %ebp
253	CFI_ADJUST_CFA_OFFSET -4
254	CFI_RESTORE ebp
255	popl %eax
256	CFI_ADJUST_CFA_OFFSET -4
257	CFI_RESTORE eax
258.endm
259
260.macro RESTORE_REGS pop=0
261	RESTORE_INT_REGS
2621:	popl %ds
263	CFI_ADJUST_CFA_OFFSET -4
264	/*CFI_RESTORE ds;*/
2652:	popl %es
266	CFI_ADJUST_CFA_OFFSET -4
267	/*CFI_RESTORE es;*/
2683:	popl %fs
269	CFI_ADJUST_CFA_OFFSET -4
270	/*CFI_RESTORE fs;*/
271	POP_GS \pop
272.pushsection .fixup, "ax"
2734:	movl $0, (%esp)
274	jmp 1b
2755:	movl $0, (%esp)
276	jmp 2b
2776:	movl $0, (%esp)
278	jmp 3b
279.section __ex_table, "a"
280	.align 4
281	.long 1b, 4b
282	.long 2b, 5b
283	.long 3b, 6b
284.popsection
285	POP_GS_EX
286.endm
287
288.macro RING0_INT_FRAME
289	CFI_STARTPROC simple
290	CFI_SIGNAL_FRAME
291	CFI_DEF_CFA esp, 3*4
292	/*CFI_OFFSET cs, -2*4;*/
293	CFI_OFFSET eip, -3*4
294.endm
295
296.macro RING0_EC_FRAME
297	CFI_STARTPROC simple
298	CFI_SIGNAL_FRAME
299	CFI_DEF_CFA esp, 4*4
300	/*CFI_OFFSET cs, -2*4;*/
301	CFI_OFFSET eip, -3*4
302.endm
303
304.macro RING0_PTREGS_FRAME
305	CFI_STARTPROC simple
306	CFI_SIGNAL_FRAME
307	CFI_DEF_CFA esp, PT_OLDESP-PT_EBX
308	/*CFI_OFFSET cs, PT_CS-PT_OLDESP;*/
309	CFI_OFFSET eip, PT_EIP-PT_OLDESP
310	/*CFI_OFFSET es, PT_ES-PT_OLDESP;*/
311	/*CFI_OFFSET ds, PT_DS-PT_OLDESP;*/
312	CFI_OFFSET eax, PT_EAX-PT_OLDESP
313	CFI_OFFSET ebp, PT_EBP-PT_OLDESP
314	CFI_OFFSET edi, PT_EDI-PT_OLDESP
315	CFI_OFFSET esi, PT_ESI-PT_OLDESP
316	CFI_OFFSET edx, PT_EDX-PT_OLDESP
317	CFI_OFFSET ecx, PT_ECX-PT_OLDESP
318	CFI_OFFSET ebx, PT_EBX-PT_OLDESP
319.endm
320
321ENTRY(ret_from_fork)
322	CFI_STARTPROC
323	pushl %eax
324	CFI_ADJUST_CFA_OFFSET 4
325	call schedule_tail
326	GET_THREAD_INFO(%ebp)
327	popl %eax
328	CFI_ADJUST_CFA_OFFSET -4
329	pushl $0x0202			# Reset kernel eflags
330	CFI_ADJUST_CFA_OFFSET 4
331	popfl
332	CFI_ADJUST_CFA_OFFSET -4
333	jmp syscall_exit
334	CFI_ENDPROC
335END(ret_from_fork)
336
337/*
338 * Interrupt exit functions should be protected against kprobes
339 */
340	.pushsection .kprobes.text, "ax"
341/*
342 * Return to user mode is not as complex as all this looks,
343 * but we want the default path for a system call return to
344 * go as quickly as possible which is why some of this is
345 * less clear than it otherwise should be.
346 */
347
348	# userspace resumption stub bypassing syscall exit tracing
349	ALIGN
350	RING0_PTREGS_FRAME
351ret_from_exception:
352	preempt_stop(CLBR_ANY)
353ret_from_intr:
354	GET_THREAD_INFO(%ebp)
355check_userspace:
356	movl PT_EFLAGS(%esp), %eax	# mix EFLAGS and CS
357	movb PT_CS(%esp), %al
358	andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
359	cmpl $USER_RPL, %eax
360	jb resume_kernel		# not returning to v8086 or userspace
361
362ENTRY(resume_userspace)
363	LOCKDEP_SYS_EXIT
364 	DISABLE_INTERRUPTS(CLBR_ANY)	# make sure we don't miss an interrupt
365					# setting need_resched or sigpending
366					# between sampling and the iret
367	TRACE_IRQS_OFF
368	movl TI_flags(%ebp), %ecx
369	andl $_TIF_WORK_MASK, %ecx	# is there any work to be done on
370					# int/exception return?
371	jne work_pending
372	jmp restore_all
373END(ret_from_exception)
374
375#ifdef CONFIG_PREEMPT
376ENTRY(resume_kernel)
377	DISABLE_INTERRUPTS(CLBR_ANY)
378	cmpl $0,TI_preempt_count(%ebp)	# non-zero preempt_count ?
379	jnz restore_all
380need_resched:
381	movl TI_flags(%ebp), %ecx	# need_resched set ?
382	testb $_TIF_NEED_RESCHED, %cl
383	jz restore_all
384	testl $X86_EFLAGS_IF,PT_EFLAGS(%esp)	# interrupts off (exception path) ?
385	jz restore_all
386	call preempt_schedule_irq
387	jmp need_resched
388END(resume_kernel)
389#endif
390	CFI_ENDPROC
391/*
392 * End of kprobes section
393 */
394	.popsection
395
396/* SYSENTER_RETURN points to after the "sysenter" instruction in
397   the vsyscall page.  See vsyscall-sysentry.S, which defines the symbol.  */
398
399	# sysenter call handler stub
400ENTRY(ia32_sysenter_target)
401	CFI_STARTPROC simple
402	CFI_SIGNAL_FRAME
403	CFI_DEF_CFA esp, 0
404	CFI_REGISTER esp, ebp
405	movl TSS_sysenter_sp0(%esp),%esp
406sysenter_past_esp:
407	/*
408	 * Interrupts are disabled here, but we can't trace it until
409	 * enough kernel state to call TRACE_IRQS_OFF can be called - but
410	 * we immediately enable interrupts at that point anyway.
411	 */
412	pushl $(__USER_DS)
413	CFI_ADJUST_CFA_OFFSET 4
414	/*CFI_REL_OFFSET ss, 0*/
415	pushl %ebp
416	CFI_ADJUST_CFA_OFFSET 4
417	CFI_REL_OFFSET esp, 0
418	pushfl
419	orl $X86_EFLAGS_IF, (%esp)
420	CFI_ADJUST_CFA_OFFSET 4
421	pushl $(__USER_CS)
422	CFI_ADJUST_CFA_OFFSET 4
423	/*CFI_REL_OFFSET cs, 0*/
424	/*
425	 * Push current_thread_info()->sysenter_return to the stack.
426	 * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
427	 * pushed above; +8 corresponds to copy_thread's esp0 setting.
428	 */
429	pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
430	CFI_ADJUST_CFA_OFFSET 4
431	CFI_REL_OFFSET eip, 0
432
433	pushl %eax
434	CFI_ADJUST_CFA_OFFSET 4
435	SAVE_ALL
436	ENABLE_INTERRUPTS(CLBR_NONE)
437
438/*
439 * Load the potential sixth argument from user stack.
440 * Careful about security.
441 */
442	cmpl $__PAGE_OFFSET-3,%ebp
443	jae syscall_fault
4441:	movl (%ebp),%ebp
445	movl %ebp,PT_EBP(%esp)
446.section __ex_table,"a"
447	.align 4
448	.long 1b,syscall_fault
449.previous
450
451	GET_THREAD_INFO(%ebp)
452
453	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
454	jnz sysenter_audit
455sysenter_do_call:
456	cmpl $(nr_syscalls), %eax
457	jae syscall_badsys
458	call *sys_call_table(,%eax,4)
459	movl %eax,PT_EAX(%esp)
460	LOCKDEP_SYS_EXIT
461	DISABLE_INTERRUPTS(CLBR_ANY)
462	TRACE_IRQS_OFF
463	movl TI_flags(%ebp), %ecx
464	testl $_TIF_ALLWORK_MASK, %ecx
465	jne sysexit_audit
466sysenter_exit:
467/* if something modifies registers it must also disable sysexit */
468	movl PT_EIP(%esp), %edx
469	movl PT_OLDESP(%esp), %ecx
470	xorl %ebp,%ebp
471	TRACE_IRQS_ON
4721:	mov  PT_FS(%esp), %fs
473	PTGS_TO_GS
474	ENABLE_INTERRUPTS_SYSEXIT
475
476#ifdef CONFIG_AUDITSYSCALL
477sysenter_audit:
478	testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
479	jnz syscall_trace_entry
480	addl $4,%esp
481	CFI_ADJUST_CFA_OFFSET -4
482	/* %esi already in 8(%esp)	   6th arg: 4th syscall arg */
483	/* %edx already in 4(%esp)	   5th arg: 3rd syscall arg */
484	/* %ecx already in 0(%esp)	   4th arg: 2nd syscall arg */
485	movl %ebx,%ecx			/* 3rd arg: 1st syscall arg */
486	movl %eax,%edx			/* 2nd arg: syscall number */
487	movl $AUDIT_ARCH_I386,%eax	/* 1st arg: audit arch */
488	call audit_syscall_entry
489	pushl %ebx
490	CFI_ADJUST_CFA_OFFSET 4
491	movl PT_EAX(%esp),%eax		/* reload syscall number */
492	jmp sysenter_do_call
493
494sysexit_audit:
495	testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %ecx
496	jne syscall_exit_work
497	TRACE_IRQS_ON
498	ENABLE_INTERRUPTS(CLBR_ANY)
499	movl %eax,%edx		/* second arg, syscall return value */
500	cmpl $0,%eax		/* is it < 0? */
501	setl %al		/* 1 if so, 0 if not */
502	movzbl %al,%eax		/* zero-extend that */
503	inc %eax /* first arg, 0->1(AUDITSC_SUCCESS), 1->2(AUDITSC_FAILURE) */
504	call audit_syscall_exit
505	DISABLE_INTERRUPTS(CLBR_ANY)
506	TRACE_IRQS_OFF
507	movl TI_flags(%ebp), %ecx
508	testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %ecx
509	jne syscall_exit_work
510	movl PT_EAX(%esp),%eax	/* reload syscall return value */
511	jmp sysenter_exit
512#endif
513
514	CFI_ENDPROC
515.pushsection .fixup,"ax"
5162:	movl $0,PT_FS(%esp)
517	jmp 1b
518.section __ex_table,"a"
519	.align 4
520	.long 1b,2b
521.popsection
522	PTGS_TO_GS_EX
523ENDPROC(ia32_sysenter_target)
524
525/*
526 * syscall stub including irq exit should be protected against kprobes
527 */
528	.pushsection .kprobes.text, "ax"
529	# system call handler stub
530ENTRY(system_call)
531	RING0_INT_FRAME			# can't unwind into user space anyway
532	pushl %eax			# save orig_eax
533	CFI_ADJUST_CFA_OFFSET 4
534	SAVE_ALL
535	GET_THREAD_INFO(%ebp)
536					# system call tracing in operation / emulation
537	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
538	jnz syscall_trace_entry
539	cmpl $(nr_syscalls), %eax
540	jae syscall_badsys
541syscall_call:
542	call *sys_call_table(,%eax,4)
543	movl %eax,PT_EAX(%esp)		# store the return value
544syscall_exit:
545	LOCKDEP_SYS_EXIT
546	DISABLE_INTERRUPTS(CLBR_ANY)	# make sure we don't miss an interrupt
547					# setting need_resched or sigpending
548					# between sampling and the iret
549	TRACE_IRQS_OFF
550	movl TI_flags(%ebp), %ecx
551	testl $_TIF_ALLWORK_MASK, %ecx	# current->work
552	jne syscall_exit_work
553
554restore_all:
555	TRACE_IRQS_IRET
556restore_all_notrace:
557	movl PT_EFLAGS(%esp), %eax	# mix EFLAGS, SS and CS
558	# Warning: PT_OLDSS(%esp) contains the wrong/random values if we
559	# are returning to the kernel.
560	# See comments in process.c:copy_thread() for details.
561	movb PT_OLDSS(%esp), %ah
562	movb PT_CS(%esp), %al
563	andl $(X86_EFLAGS_VM | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax
564	cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax
565	CFI_REMEMBER_STATE
566	je ldt_ss			# returning to user-space with LDT SS
567restore_nocheck:
568	RESTORE_REGS 4			# skip orig_eax/error_code
569	CFI_ADJUST_CFA_OFFSET -4
570irq_return:
571	INTERRUPT_RETURN
572.section .fixup,"ax"
573ENTRY(iret_exc)
574	pushl $0			# no error code
575	pushl $do_iret_error
576	jmp error_code
577.previous
578.section __ex_table,"a"
579	.align 4
580	.long irq_return,iret_exc
581.previous
582
583	CFI_RESTORE_STATE
584ldt_ss:
585	larl PT_OLDSS(%esp), %eax
586	jnz restore_nocheck
587	testl $0x00400000, %eax		# returning to 32bit stack?
588	jnz restore_nocheck		# allright, normal return
589
590#ifdef CONFIG_PARAVIRT
591	/*
592	 * The kernel can't run on a non-flat stack if paravirt mode
593	 * is active.  Rather than try to fixup the high bits of
594	 * ESP, bypass this code entirely.  This may break DOSemu
595	 * and/or Wine support in a paravirt VM, although the option
596	 * is still available to implement the setting of the high
597	 * 16-bits in the INTERRUPT_RETURN paravirt-op.
598	 */
599	cmpl $0, pv_info+PARAVIRT_enabled
600	jne restore_nocheck
601#endif
602
603/*
604 * Setup and switch to ESPFIX stack
605 *
606 * We're returning to userspace with a 16 bit stack. The CPU will not
607 * restore the high word of ESP for us on executing iret... This is an
608 * "official" bug of all the x86-compatible CPUs, which we can work
609 * around to make dosemu and wine happy. We do this by preloading the
610 * high word of ESP with the high word of the userspace ESP while
611 * compensating for the offset by changing to the ESPFIX segment with
612 * a base address that matches for the difference.
613 */
614#define GDT_ESPFIX_SS PER_CPU_VAR(gdt_page) + (GDT_ENTRY_ESPFIX_SS * 8)
615	mov %esp, %edx			/* load kernel esp */
616	mov PT_OLDESP(%esp), %eax	/* load userspace esp */
617	mov %dx, %ax			/* eax: new kernel esp */
618	sub %eax, %edx			/* offset (low word is 0) */
619	shr $16, %edx
620	mov %dl, GDT_ESPFIX_SS + 4 /* bits 16..23 */
621	mov %dh, GDT_ESPFIX_SS + 7 /* bits 24..31 */
622	pushl $__ESPFIX_SS
623	CFI_ADJUST_CFA_OFFSET 4
624	push %eax			/* new kernel esp */
625	CFI_ADJUST_CFA_OFFSET 4
626	/* Disable interrupts, but do not irqtrace this section: we
627	 * will soon execute iret and the tracer was already set to
628	 * the irqstate after the iret */
629	DISABLE_INTERRUPTS(CLBR_EAX)
630	lss (%esp), %esp		/* switch to espfix segment */
631	CFI_ADJUST_CFA_OFFSET -8
632	jmp restore_nocheck
633	CFI_ENDPROC
634ENDPROC(system_call)
635
636	# perform work that needs to be done immediately before resumption
637	ALIGN
638	RING0_PTREGS_FRAME		# can't unwind into user space anyway
639work_pending:
640	testb $_TIF_NEED_RESCHED, %cl
641	jz work_notifysig
642work_resched:
643	call schedule
644	LOCKDEP_SYS_EXIT
645	DISABLE_INTERRUPTS(CLBR_ANY)	# make sure we don't miss an interrupt
646					# setting need_resched or sigpending
647					# between sampling and the iret
648	TRACE_IRQS_OFF
649	movl TI_flags(%ebp), %ecx
650	andl $_TIF_WORK_MASK, %ecx	# is there any work to be done other
651					# than syscall tracing?
652	jz restore_all
653	testb $_TIF_NEED_RESCHED, %cl
654	jnz work_resched
655
656work_notifysig:				# deal with pending signals and
657					# notify-resume requests
658#ifdef CONFIG_VM86
659	testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)
660	movl %esp, %eax
661	jne work_notifysig_v86		# returning to kernel-space or
662					# vm86-space
663	xorl %edx, %edx
664	call do_notify_resume
665	jmp resume_userspace_sig
666
667	ALIGN
668work_notifysig_v86:
669	pushl %ecx			# save ti_flags for do_notify_resume
670	CFI_ADJUST_CFA_OFFSET 4
671	call save_v86_state		# %eax contains pt_regs pointer
672	popl %ecx
673	CFI_ADJUST_CFA_OFFSET -4
674	movl %eax, %esp
675#else
676	movl %esp, %eax
677#endif
678	xorl %edx, %edx
679	call do_notify_resume
680	jmp resume_userspace_sig
681END(work_pending)
682
683	# perform syscall exit tracing
684	ALIGN
685syscall_trace_entry:
686	movl $-ENOSYS,PT_EAX(%esp)
687	movl %esp, %eax
688	call syscall_trace_enter
689	/* What it returned is what we'll actually use.  */
690	cmpl $(nr_syscalls), %eax
691	jnae syscall_call
692	jmp syscall_exit
693END(syscall_trace_entry)
694
695	# perform syscall exit tracing
696	ALIGN
697syscall_exit_work:
698	testl $_TIF_WORK_SYSCALL_EXIT, %ecx
699	jz work_pending
700	TRACE_IRQS_ON
701	ENABLE_INTERRUPTS(CLBR_ANY)	# could let syscall_trace_leave() call
702					# schedule() instead
703	movl %esp, %eax
704	call syscall_trace_leave
705	jmp resume_userspace
706END(syscall_exit_work)
707	CFI_ENDPROC
708
709	RING0_INT_FRAME			# can't unwind into user space anyway
710syscall_fault:
711	GET_THREAD_INFO(%ebp)
712	movl $-EFAULT,PT_EAX(%esp)
713	jmp resume_userspace
714END(syscall_fault)
715
716syscall_badsys:
717	movl $-ENOSYS,PT_EAX(%esp)
718	jmp resume_userspace
719END(syscall_badsys)
720	CFI_ENDPROC
721/*
722 * End of kprobes section
723 */
724	.popsection
725
726/*
727 * System calls that need a pt_regs pointer.
728 */
729#define PTREGSCALL0(name) \
730	ALIGN; \
731ptregs_##name: \
732	leal 4(%esp),%eax; \
733	jmp sys_##name;
734
735#define PTREGSCALL1(name) \
736	ALIGN; \
737ptregs_##name: \
738	leal 4(%esp),%edx; \
739	movl (PT_EBX+4)(%esp),%eax; \
740	jmp sys_##name;
741
742#define PTREGSCALL2(name) \
743	ALIGN; \
744ptregs_##name: \
745	leal 4(%esp),%ecx; \
746	movl (PT_ECX+4)(%esp),%edx; \
747	movl (PT_EBX+4)(%esp),%eax; \
748	jmp sys_##name;
749
750#define PTREGSCALL3(name) \
751	ALIGN; \
752ptregs_##name: \
753	leal 4(%esp),%eax; \
754	pushl %eax; \
755	movl PT_EDX(%eax),%ecx; \
756	movl PT_ECX(%eax),%edx; \
757	movl PT_EBX(%eax),%eax; \
758	call sys_##name; \
759	addl $4,%esp; \
760	ret
761
762PTREGSCALL1(iopl)
763PTREGSCALL0(fork)
764PTREGSCALL0(vfork)
765PTREGSCALL3(execve)
766PTREGSCALL2(sigaltstack)
767PTREGSCALL0(sigreturn)
768PTREGSCALL0(rt_sigreturn)
769PTREGSCALL2(vm86)
770PTREGSCALL1(vm86old)
771
772/* Clone is an oddball.  The 4th arg is in %edi */
773	ALIGN;
774ptregs_clone:
775	leal 4(%esp),%eax
776	pushl %eax
777	pushl PT_EDI(%eax)
778	movl PT_EDX(%eax),%ecx
779	movl PT_ECX(%eax),%edx
780	movl PT_EBX(%eax),%eax
781	call sys_clone
782	addl $8,%esp
783	ret
784
785.macro FIXUP_ESPFIX_STACK
786/*
787 * Switch back for ESPFIX stack to the normal zerobased stack
788 *
789 * We can't call C functions using the ESPFIX stack. This code reads
790 * the high word of the segment base from the GDT and swiches to the
791 * normal stack and adjusts ESP with the matching offset.
792 */
793	/* fixup the stack */
794	mov GDT_ESPFIX_SS + 4, %al /* bits 16..23 */
795	mov GDT_ESPFIX_SS + 7, %ah /* bits 24..31 */
796	shl $16, %eax
797	addl %esp, %eax			/* the adjusted stack pointer */
798	pushl $__KERNEL_DS
799	CFI_ADJUST_CFA_OFFSET 4
800	pushl %eax
801	CFI_ADJUST_CFA_OFFSET 4
802	lss (%esp), %esp		/* switch to the normal stack segment */
803	CFI_ADJUST_CFA_OFFSET -8
804.endm
805.macro UNWIND_ESPFIX_STACK
806	movl %ss, %eax
807	/* see if on espfix stack */
808	cmpw $__ESPFIX_SS, %ax
809	jne 27f
810	movl $__KERNEL_DS, %eax
811	movl %eax, %ds
812	movl %eax, %es
813	/* switch to normal stack */
814	FIXUP_ESPFIX_STACK
81527:
816.endm
817
818/*
819 * Build the entry stubs and pointer table with some assembler magic.
820 * We pack 7 stubs into a single 32-byte chunk, which will fit in a
821 * single cache line on all modern x86 implementations.
822 */
823.section .init.rodata,"a"
824ENTRY(interrupt)
825.text
826	.p2align 5
827	.p2align CONFIG_X86_L1_CACHE_SHIFT
828ENTRY(irq_entries_start)
829	RING0_INT_FRAME
830vector=FIRST_EXTERNAL_VECTOR
831.rept (NR_VECTORS-FIRST_EXTERNAL_VECTOR+6)/7
832	.balign 32
833  .rept	7
834    .if vector < NR_VECTORS
835      .if vector <> FIRST_EXTERNAL_VECTOR
836	CFI_ADJUST_CFA_OFFSET -4
837      .endif
8381:	pushl $(~vector+0x80)	/* Note: always in signed byte range */
839	CFI_ADJUST_CFA_OFFSET 4
840      .if ((vector-FIRST_EXTERNAL_VECTOR)%7) <> 6
841	jmp 2f
842      .endif
843      .previous
844	.long 1b
845      .text
846vector=vector+1
847    .endif
848  .endr
8492:	jmp common_interrupt
850.endr
851END(irq_entries_start)
852
853.previous
854END(interrupt)
855.previous
856
857/*
858 * the CPU automatically disables interrupts when executing an IRQ vector,
859 * so IRQ-flags tracing has to follow that:
860 */
861	.p2align CONFIG_X86_L1_CACHE_SHIFT
862common_interrupt:
863	addl $-0x80,(%esp)	/* Adjust vector into the [-256,-1] range */
864	SAVE_ALL
865	TRACE_IRQS_OFF
866	movl %esp,%eax
867	call do_IRQ
868	jmp ret_from_intr
869ENDPROC(common_interrupt)
870	CFI_ENDPROC
871
872/*
873 *  Irq entries should be protected against kprobes
874 */
875	.pushsection .kprobes.text, "ax"
876#define BUILD_INTERRUPT3(name, nr, fn)	\
877ENTRY(name)				\
878	RING0_INT_FRAME;		\
879	pushl $~(nr);			\
880	CFI_ADJUST_CFA_OFFSET 4;	\
881	SAVE_ALL;			\
882	TRACE_IRQS_OFF			\
883	movl %esp,%eax;			\
884	call fn;			\
885	jmp ret_from_intr;		\
886	CFI_ENDPROC;			\
887ENDPROC(name)
888
889#define BUILD_INTERRUPT(name, nr)	BUILD_INTERRUPT3(name, nr, smp_##name)
890
891/* The include is where all of the SMP etc. interrupts come from */
892#include <asm/entry_arch.h>
893
894ENTRY(coprocessor_error)
895	RING0_INT_FRAME
896	pushl $0
897	CFI_ADJUST_CFA_OFFSET 4
898	pushl $do_coprocessor_error
899	CFI_ADJUST_CFA_OFFSET 4
900	jmp error_code
901	CFI_ENDPROC
902END(coprocessor_error)
903
904ENTRY(simd_coprocessor_error)
905	RING0_INT_FRAME
906	pushl $0
907	CFI_ADJUST_CFA_OFFSET 4
908#ifdef CONFIG_X86_INVD_BUG
909	/* AMD 486 bug: invd from userspace calls exception 19 instead of #GP */
910661:	pushl $do_general_protection
911662:
912.section .altinstructions,"a"
913	.balign 4
914	.long 661b
915	.long 663f
916	.word X86_FEATURE_XMM
917	.byte 662b-661b
918	.byte 664f-663f
919.previous
920.section .altinstr_replacement,"ax"
921663:	pushl $do_simd_coprocessor_error
922664:
923.previous
924#else
925	pushl $do_simd_coprocessor_error
926#endif
927	CFI_ADJUST_CFA_OFFSET 4
928	jmp error_code
929	CFI_ENDPROC
930END(simd_coprocessor_error)
931
932ENTRY(device_not_available)
933	RING0_INT_FRAME
934	pushl $-1			# mark this as an int
935	CFI_ADJUST_CFA_OFFSET 4
936	pushl $do_device_not_available
937	CFI_ADJUST_CFA_OFFSET 4
938	jmp error_code
939	CFI_ENDPROC
940END(device_not_available)
941
942#ifdef CONFIG_PARAVIRT
943ENTRY(native_iret)
944	iret
945.section __ex_table,"a"
946	.align 4
947	.long native_iret, iret_exc
948.previous
949END(native_iret)
950
951ENTRY(native_irq_enable_sysexit)
952	sti
953	sysexit
954END(native_irq_enable_sysexit)
955#endif
956
957ENTRY(overflow)
958	RING0_INT_FRAME
959	pushl $0
960	CFI_ADJUST_CFA_OFFSET 4
961	pushl $do_overflow
962	CFI_ADJUST_CFA_OFFSET 4
963	jmp error_code
964	CFI_ENDPROC
965END(overflow)
966
967ENTRY(bounds)
968	RING0_INT_FRAME
969	pushl $0
970	CFI_ADJUST_CFA_OFFSET 4
971	pushl $do_bounds
972	CFI_ADJUST_CFA_OFFSET 4
973	jmp error_code
974	CFI_ENDPROC
975END(bounds)
976
977ENTRY(invalid_op)
978	RING0_INT_FRAME
979	pushl $0
980	CFI_ADJUST_CFA_OFFSET 4
981	pushl $do_invalid_op
982	CFI_ADJUST_CFA_OFFSET 4
983	jmp error_code
984	CFI_ENDPROC
985END(invalid_op)
986
987ENTRY(coprocessor_segment_overrun)
988	RING0_INT_FRAME
989	pushl $0
990	CFI_ADJUST_CFA_OFFSET 4
991	pushl $do_coprocessor_segment_overrun
992	CFI_ADJUST_CFA_OFFSET 4
993	jmp error_code
994	CFI_ENDPROC
995END(coprocessor_segment_overrun)
996
997ENTRY(invalid_TSS)
998	RING0_EC_FRAME
999	pushl $do_invalid_TSS
1000	CFI_ADJUST_CFA_OFFSET 4
1001	jmp error_code
1002	CFI_ENDPROC
1003END(invalid_TSS)
1004
1005ENTRY(segment_not_present)
1006	RING0_EC_FRAME
1007	pushl $do_segment_not_present
1008	CFI_ADJUST_CFA_OFFSET 4
1009	jmp error_code
1010	CFI_ENDPROC
1011END(segment_not_present)
1012
1013ENTRY(stack_segment)
1014	RING0_EC_FRAME
1015	pushl $do_stack_segment
1016	CFI_ADJUST_CFA_OFFSET 4
1017	jmp error_code
1018	CFI_ENDPROC
1019END(stack_segment)
1020
1021ENTRY(alignment_check)
1022	RING0_EC_FRAME
1023	pushl $do_alignment_check
1024	CFI_ADJUST_CFA_OFFSET 4
1025	jmp error_code
1026	CFI_ENDPROC
1027END(alignment_check)
1028
1029ENTRY(divide_error)
1030	RING0_INT_FRAME
1031	pushl $0			# no error code
1032	CFI_ADJUST_CFA_OFFSET 4
1033	pushl $do_divide_error
1034	CFI_ADJUST_CFA_OFFSET 4
1035	jmp error_code
1036	CFI_ENDPROC
1037END(divide_error)
1038
1039#ifdef CONFIG_X86_MCE
1040ENTRY(machine_check)
1041	RING0_INT_FRAME
1042	pushl $0
1043	CFI_ADJUST_CFA_OFFSET 4
1044	pushl machine_check_vector
1045	CFI_ADJUST_CFA_OFFSET 4
1046	jmp error_code
1047	CFI_ENDPROC
1048END(machine_check)
1049#endif
1050
1051ENTRY(spurious_interrupt_bug)
1052	RING0_INT_FRAME
1053	pushl $0
1054	CFI_ADJUST_CFA_OFFSET 4
1055	pushl $do_spurious_interrupt_bug
1056	CFI_ADJUST_CFA_OFFSET 4
1057	jmp error_code
1058	CFI_ENDPROC
1059END(spurious_interrupt_bug)
1060/*
1061 * End of kprobes section
1062 */
1063	.popsection
1064
1065ENTRY(kernel_thread_helper)
1066	pushl $0		# fake return address for unwinder
1067	CFI_STARTPROC
1068	movl %edi,%eax
1069	call *%esi
1070	call do_exit
1071	ud2			# padding for call trace
1072	CFI_ENDPROC
1073ENDPROC(kernel_thread_helper)
1074
1075#ifdef CONFIG_XEN
1076/* Xen doesn't set %esp to be precisely what the normal sysenter
1077   entrypoint expects, so fix it up before using the normal path. */
1078ENTRY(xen_sysenter_target)
1079	RING0_INT_FRAME
1080	addl $5*4, %esp		/* remove xen-provided frame */
1081	CFI_ADJUST_CFA_OFFSET -5*4
1082	jmp sysenter_past_esp
1083	CFI_ENDPROC
1084
1085ENTRY(xen_hypervisor_callback)
1086	CFI_STARTPROC
1087	pushl $0
1088	CFI_ADJUST_CFA_OFFSET 4
1089	SAVE_ALL
1090	TRACE_IRQS_OFF
1091
1092	/* Check to see if we got the event in the critical
1093	   region in xen_iret_direct, after we've reenabled
1094	   events and checked for pending events.  This simulates
1095	   iret instruction's behaviour where it delivers a
1096	   pending interrupt when enabling interrupts. */
1097	movl PT_EIP(%esp),%eax
1098	cmpl $xen_iret_start_crit,%eax
1099	jb   1f
1100	cmpl $xen_iret_end_crit,%eax
1101	jae  1f
1102
1103	jmp  xen_iret_crit_fixup
1104
1105ENTRY(xen_do_upcall)
11061:	mov %esp, %eax
1107	call xen_evtchn_do_upcall
1108	jmp  ret_from_intr
1109	CFI_ENDPROC
1110ENDPROC(xen_hypervisor_callback)
1111
1112# Hypervisor uses this for application faults while it executes.
1113# We get here for two reasons:
1114#  1. Fault while reloading DS, ES, FS or GS
1115#  2. Fault while executing IRET
1116# Category 1 we fix up by reattempting the load, and zeroing the segment
1117# register if the load fails.
1118# Category 2 we fix up by jumping to do_iret_error. We cannot use the
1119# normal Linux return path in this case because if we use the IRET hypercall
1120# to pop the stack frame we end up in an infinite loop of failsafe callbacks.
1121# We distinguish between categories by maintaining a status value in EAX.
1122ENTRY(xen_failsafe_callback)
1123	CFI_STARTPROC
1124	pushl %eax
1125	CFI_ADJUST_CFA_OFFSET 4
1126	movl $1,%eax
11271:	mov 4(%esp),%ds
11282:	mov 8(%esp),%es
11293:	mov 12(%esp),%fs
11304:	mov 16(%esp),%gs
1131	testl %eax,%eax
1132	popl %eax
1133	CFI_ADJUST_CFA_OFFSET -4
1134	lea 16(%esp),%esp
1135	CFI_ADJUST_CFA_OFFSET -16
1136	jz 5f
1137	addl $16,%esp
1138	jmp iret_exc		# EAX != 0 => Category 2 (Bad IRET)
11395:	pushl $0		# EAX == 0 => Category 1 (Bad segment)
1140	CFI_ADJUST_CFA_OFFSET 4
1141	SAVE_ALL
1142	jmp ret_from_exception
1143	CFI_ENDPROC
1144
1145.section .fixup,"ax"
11466:	xorl %eax,%eax
1147	movl %eax,4(%esp)
1148	jmp 1b
11497:	xorl %eax,%eax
1150	movl %eax,8(%esp)
1151	jmp 2b
11528:	xorl %eax,%eax
1153	movl %eax,12(%esp)
1154	jmp 3b
11559:	xorl %eax,%eax
1156	movl %eax,16(%esp)
1157	jmp 4b
1158.previous
1159.section __ex_table,"a"
1160	.align 4
1161	.long 1b,6b
1162	.long 2b,7b
1163	.long 3b,8b
1164	.long 4b,9b
1165.previous
1166ENDPROC(xen_failsafe_callback)
1167
1168BUILD_INTERRUPT3(xen_hvm_callback_vector, XEN_HVM_EVTCHN_CALLBACK,
1169		xen_evtchn_do_upcall)
1170
1171#endif	/* CONFIG_XEN */
1172
1173#ifdef CONFIG_FUNCTION_TRACER
1174#ifdef CONFIG_DYNAMIC_FTRACE
1175
1176ENTRY(mcount)
1177	ret
1178END(mcount)
1179
1180ENTRY(ftrace_caller)
1181	cmpl $0, function_trace_stop
1182	jne  ftrace_stub
1183
1184	pushl %eax
1185	pushl %ecx
1186	pushl %edx
1187	movl 0xc(%esp), %eax
1188	movl 0x4(%ebp), %edx
1189	subl $MCOUNT_INSN_SIZE, %eax
1190
1191.globl ftrace_call
1192ftrace_call:
1193	call ftrace_stub
1194
1195	popl %edx
1196	popl %ecx
1197	popl %eax
1198#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1199.globl ftrace_graph_call
1200ftrace_graph_call:
1201	jmp ftrace_stub
1202#endif
1203
1204.globl ftrace_stub
1205ftrace_stub:
1206	ret
1207END(ftrace_caller)
1208
1209#else /* ! CONFIG_DYNAMIC_FTRACE */
1210
1211ENTRY(mcount)
1212	cmpl $0, function_trace_stop
1213	jne  ftrace_stub
1214
1215	cmpl $ftrace_stub, ftrace_trace_function
1216	jnz trace
1217#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1218	cmpl $ftrace_stub, ftrace_graph_return
1219	jnz ftrace_graph_caller
1220
1221	cmpl $ftrace_graph_entry_stub, ftrace_graph_entry
1222	jnz ftrace_graph_caller
1223#endif
1224.globl ftrace_stub
1225ftrace_stub:
1226	ret
1227
1228	/* taken from glibc */
1229trace:
1230	pushl %eax
1231	pushl %ecx
1232	pushl %edx
1233	movl 0xc(%esp), %eax
1234	movl 0x4(%ebp), %edx
1235	subl $MCOUNT_INSN_SIZE, %eax
1236
1237	call *ftrace_trace_function
1238
1239	popl %edx
1240	popl %ecx
1241	popl %eax
1242	jmp ftrace_stub
1243END(mcount)
1244#endif /* CONFIG_DYNAMIC_FTRACE */
1245#endif /* CONFIG_FUNCTION_TRACER */
1246
1247#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1248ENTRY(ftrace_graph_caller)
1249	cmpl $0, function_trace_stop
1250	jne ftrace_stub
1251
1252	pushl %eax
1253	pushl %ecx
1254	pushl %edx
1255	movl 0xc(%esp), %edx
1256	lea 0x4(%ebp), %eax
1257	movl (%ebp), %ecx
1258	subl $MCOUNT_INSN_SIZE, %edx
1259	call prepare_ftrace_return
1260	popl %edx
1261	popl %ecx
1262	popl %eax
1263	ret
1264END(ftrace_graph_caller)
1265
1266.globl return_to_handler
1267return_to_handler:
1268	pushl %eax
1269	pushl %edx
1270	movl %ebp, %eax
1271	call ftrace_return_to_handler
1272	movl %eax, %ecx
1273	popl %edx
1274	popl %eax
1275	jmp *%ecx
1276#endif
1277
1278.section .rodata,"a"
1279#include "syscall_table_32.S"
1280
1281syscall_table_size=(.-sys_call_table)
1282
1283/*
1284 * Some functions should be protected against kprobes
1285 */
1286	.pushsection .kprobes.text, "ax"
1287
1288ENTRY(page_fault)
1289	RING0_EC_FRAME
1290	pushl $do_page_fault
1291	CFI_ADJUST_CFA_OFFSET 4
1292	ALIGN
1293error_code:
1294	/* the function address is in %gs's slot on the stack */
1295	pushl %fs
1296	CFI_ADJUST_CFA_OFFSET 4
1297	/*CFI_REL_OFFSET fs, 0*/
1298	pushl %es
1299	CFI_ADJUST_CFA_OFFSET 4
1300	/*CFI_REL_OFFSET es, 0*/
1301	pushl %ds
1302	CFI_ADJUST_CFA_OFFSET 4
1303	/*CFI_REL_OFFSET ds, 0*/
1304	pushl %eax
1305	CFI_ADJUST_CFA_OFFSET 4
1306	CFI_REL_OFFSET eax, 0
1307	pushl %ebp
1308	CFI_ADJUST_CFA_OFFSET 4
1309	CFI_REL_OFFSET ebp, 0
1310	pushl %edi
1311	CFI_ADJUST_CFA_OFFSET 4
1312	CFI_REL_OFFSET edi, 0
1313	pushl %esi
1314	CFI_ADJUST_CFA_OFFSET 4
1315	CFI_REL_OFFSET esi, 0
1316	pushl %edx
1317	CFI_ADJUST_CFA_OFFSET 4
1318	CFI_REL_OFFSET edx, 0
1319	pushl %ecx
1320	CFI_ADJUST_CFA_OFFSET 4
1321	CFI_REL_OFFSET ecx, 0
1322	pushl %ebx
1323	CFI_ADJUST_CFA_OFFSET 4
1324	CFI_REL_OFFSET ebx, 0
1325	cld
1326	movl $(__KERNEL_PERCPU), %ecx
1327	movl %ecx, %fs
1328	UNWIND_ESPFIX_STACK
1329	GS_TO_REG %ecx
1330	movl PT_GS(%esp), %edi		# get the function address
1331	movl PT_ORIG_EAX(%esp), %edx	# get the error code
1332	movl $-1, PT_ORIG_EAX(%esp)	# no syscall to restart
1333	REG_TO_PTGS %ecx
1334	SET_KERNEL_GS %ecx
1335	movl $(__USER_DS), %ecx
1336	movl %ecx, %ds
1337	movl %ecx, %es
1338	TRACE_IRQS_OFF
1339	movl %esp,%eax			# pt_regs pointer
1340	call *%edi
1341	jmp ret_from_exception
1342	CFI_ENDPROC
1343END(page_fault)
1344
1345/*
1346 * Debug traps and NMI can happen at the one SYSENTER instruction
1347 * that sets up the real kernel stack. Check here, since we can't
1348 * allow the wrong stack to be used.
1349 *
1350 * "TSS_sysenter_sp0+12" is because the NMI/debug handler will have
1351 * already pushed 3 words if it hits on the sysenter instruction:
1352 * eflags, cs and eip.
1353 *
1354 * We just load the right stack, and push the three (known) values
1355 * by hand onto the new stack - while updating the return eip past
1356 * the instruction that would have done it for sysenter.
1357 */
1358.macro FIX_STACK offset ok label
1359	cmpw $__KERNEL_CS, 4(%esp)
1360	jne \ok
1361\label:
1362	movl TSS_sysenter_sp0 + \offset(%esp), %esp
1363	CFI_DEF_CFA esp, 0
1364	CFI_UNDEFINED eip
1365	pushfl
1366	CFI_ADJUST_CFA_OFFSET 4
1367	pushl $__KERNEL_CS
1368	CFI_ADJUST_CFA_OFFSET 4
1369	pushl $sysenter_past_esp
1370	CFI_ADJUST_CFA_OFFSET 4
1371	CFI_REL_OFFSET eip, 0
1372.endm
1373
1374ENTRY(debug)
1375	RING0_INT_FRAME
1376	cmpl $ia32_sysenter_target,(%esp)
1377	jne debug_stack_correct
1378	FIX_STACK 12, debug_stack_correct, debug_esp_fix_insn
1379debug_stack_correct:
1380	pushl $-1			# mark this as an int
1381	CFI_ADJUST_CFA_OFFSET 4
1382	SAVE_ALL
1383	TRACE_IRQS_OFF
1384	xorl %edx,%edx			# error code 0
1385	movl %esp,%eax			# pt_regs pointer
1386	call do_debug
1387	jmp ret_from_exception
1388	CFI_ENDPROC
1389END(debug)
1390
1391/*
1392 * NMI is doubly nasty. It can happen _while_ we're handling
1393 * a debug fault, and the debug fault hasn't yet been able to
1394 * clear up the stack. So we first check whether we got  an
1395 * NMI on the sysenter entry path, but after that we need to
1396 * check whether we got an NMI on the debug path where the debug
1397 * fault happened on the sysenter path.
1398 */
1399ENTRY(nmi)
1400	RING0_INT_FRAME
1401	pushl %eax
1402	CFI_ADJUST_CFA_OFFSET 4
1403	movl %ss, %eax
1404	cmpw $__ESPFIX_SS, %ax
1405	popl %eax
1406	CFI_ADJUST_CFA_OFFSET -4
1407	je nmi_espfix_stack
1408	cmpl $ia32_sysenter_target,(%esp)
1409	je nmi_stack_fixup
1410	pushl %eax
1411	CFI_ADJUST_CFA_OFFSET 4
1412	movl %esp,%eax
1413	/* Do not access memory above the end of our stack page,
1414	 * it might not exist.
1415	 */
1416	andl $(THREAD_SIZE-1),%eax
1417	cmpl $(THREAD_SIZE-20),%eax
1418	popl %eax
1419	CFI_ADJUST_CFA_OFFSET -4
1420	jae nmi_stack_correct
1421	cmpl $ia32_sysenter_target,12(%esp)
1422	je nmi_debug_stack_check
1423nmi_stack_correct:
1424	/* We have a RING0_INT_FRAME here */
1425	pushl %eax
1426	CFI_ADJUST_CFA_OFFSET 4
1427	SAVE_ALL
1428	xorl %edx,%edx		# zero error code
1429	movl %esp,%eax		# pt_regs pointer
1430	call do_nmi
1431	jmp restore_all_notrace
1432	CFI_ENDPROC
1433
1434nmi_stack_fixup:
1435	RING0_INT_FRAME
1436	FIX_STACK 12, nmi_stack_correct, 1
1437	jmp nmi_stack_correct
1438
1439nmi_debug_stack_check:
1440	/* We have a RING0_INT_FRAME here */
1441	cmpw $__KERNEL_CS,16(%esp)
1442	jne nmi_stack_correct
1443	cmpl $debug,(%esp)
1444	jb nmi_stack_correct
1445	cmpl $debug_esp_fix_insn,(%esp)
1446	ja nmi_stack_correct
1447	FIX_STACK 24, nmi_stack_correct, 1
1448	jmp nmi_stack_correct
1449
1450nmi_espfix_stack:
1451	/* We have a RING0_INT_FRAME here.
1452	 *
1453	 * create the pointer to lss back
1454	 */
1455	pushl %ss
1456	CFI_ADJUST_CFA_OFFSET 4
1457	pushl %esp
1458	CFI_ADJUST_CFA_OFFSET 4
1459	addl $4, (%esp)
1460	/* copy the iret frame of 12 bytes */
1461	.rept 3
1462	pushl 16(%esp)
1463	CFI_ADJUST_CFA_OFFSET 4
1464	.endr
1465	pushl %eax
1466	CFI_ADJUST_CFA_OFFSET 4
1467	SAVE_ALL
1468	FIXUP_ESPFIX_STACK		# %eax == %esp
1469	xorl %edx,%edx			# zero error code
1470	call do_nmi
1471	RESTORE_REGS
1472	lss 12+4(%esp), %esp		# back to espfix stack
1473	CFI_ADJUST_CFA_OFFSET -24
1474	jmp irq_return
1475	CFI_ENDPROC
1476END(nmi)
1477
1478ENTRY(int3)
1479	RING0_INT_FRAME
1480	pushl $-1			# mark this as an int
1481	CFI_ADJUST_CFA_OFFSET 4
1482	SAVE_ALL
1483	TRACE_IRQS_OFF
1484	xorl %edx,%edx		# zero error code
1485	movl %esp,%eax		# pt_regs pointer
1486	call do_int3
1487	jmp ret_from_exception
1488	CFI_ENDPROC
1489END(int3)
1490
1491ENTRY(general_protection)
1492	RING0_EC_FRAME
1493	pushl $do_general_protection
1494	CFI_ADJUST_CFA_OFFSET 4
1495	jmp error_code
1496	CFI_ENDPROC
1497END(general_protection)
1498
1499/*
1500 * End of kprobes section
1501 */
1502	.popsection
1503