···18181919 - system_call: syscall instruction from 64-bit code.20202121- - ia32_syscall: int 0x80 from 32-bit or 64-bit code; compat syscall2121+ - entry_INT80_compat: int 0x80 from 32-bit or 64-bit code; compat syscall2222 either way.23232424- - ia32_syscall, ia32_sysenter: syscall and sysenter from 32-bit2424+ - entry_INT80_compat, ia32_sysenter: syscall and sysenter from 32-bit2525 code26262727 - interrupt: An array of entries. Every IDT vector that doesn't
···11+#22+# Makefile for the x86 low level entry code33+#44+obj-y := entry_$(BITS).o thunk_$(BITS).o syscall_$(BITS).o55+66+obj-y += vdso/77+obj-y += vsyscall/88+99+obj-$(CONFIG_IA32_EMULATION) += entry_64_compat.o syscall_32.o1010+
+1248
arch/x86/entry/entry_32.S
···11+/*22+ * Copyright (C) 1991,1992 Linus Torvalds33+ *44+ * entry_32.S contains the system-call and low-level fault and trap handling routines.55+ *66+ * Stack layout in 'syscall_exit':77+ * ptrace needs to have all registers on the stack.88+ * If the order here is changed, it needs to be99+ * updated in fork.c:copy_process(), signal.c:do_signal(),1010+ * ptrace.c and ptrace.h1111+ *1212+ * 0(%esp) - %ebx1313+ * 4(%esp) - %ecx1414+ * 8(%esp) - %edx1515+ * C(%esp) - %esi1616+ * 10(%esp) - %edi1717+ * 14(%esp) - %ebp1818+ * 18(%esp) - %eax1919+ * 1C(%esp) - %ds2020+ * 20(%esp) - %es2121+ * 24(%esp) - %fs2222+ * 28(%esp) - %gs saved iff !CONFIG_X86_32_LAZY_GS2323+ * 2C(%esp) - orig_eax2424+ * 30(%esp) - %eip2525+ * 34(%esp) - %cs2626+ * 38(%esp) - %eflags2727+ * 3C(%esp) - %oldesp2828+ * 40(%esp) - %oldss2929+ */3030+3131+#include <linux/linkage.h>3232+#include <linux/err.h>3333+#include <asm/thread_info.h>3434+#include <asm/irqflags.h>3535+#include <asm/errno.h>3636+#include <asm/segment.h>3737+#include <asm/smp.h>3838+#include <asm/page_types.h>3939+#include <asm/percpu.h>4040+#include <asm/processor-flags.h>4141+#include <asm/ftrace.h>4242+#include <asm/irq_vectors.h>4343+#include <asm/cpufeature.h>4444+#include <asm/alternative-asm.h>4545+#include <asm/asm.h>4646+#include <asm/smap.h>4747+4848+/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */4949+#include <linux/elf-em.h>5050+#define AUDIT_ARCH_I386 (EM_386|__AUDIT_ARCH_LE)5151+#define __AUDIT_ARCH_LE 0x400000005252+5353+#ifndef CONFIG_AUDITSYSCALL5454+# define sysenter_audit syscall_trace_entry5555+# define sysexit_audit syscall_exit_work5656+#endif5757+5858+ .section .entry.text, "ax"5959+6060+/*6161+ * We use macros for low-level operations which need to be overridden6262+ * for paravirtualization. The following will never clobber any registers:6363+ * INTERRUPT_RETURN (aka. "iret")6464+ * GET_CR0_INTO_EAX (aka. "movl %cr0, %eax")6565+ * ENABLE_INTERRUPTS_SYSEXIT (aka "sti; sysexit").6666+ *6767+ * For DISABLE_INTERRUPTS/ENABLE_INTERRUPTS (aka "cli"/"sti"), you must6868+ * specify what registers can be overwritten (CLBR_NONE, CLBR_EAX/EDX/ECX/ANY).6969+ * Allowing a register to be clobbered can shrink the paravirt replacement7070+ * enough to patch inline, increasing performance.7171+ */7272+7373+#ifdef CONFIG_PREEMPT7474+# define preempt_stop(clobbers) DISABLE_INTERRUPTS(clobbers); TRACE_IRQS_OFF7575+#else7676+# define preempt_stop(clobbers)7777+# define resume_kernel restore_all7878+#endif7979+8080+.macro TRACE_IRQS_IRET8181+#ifdef CONFIG_TRACE_IRQFLAGS8282+ testl $X86_EFLAGS_IF, PT_EFLAGS(%esp) # interrupts off?8383+ jz 1f8484+ TRACE_IRQS_ON8585+1:8686+#endif8787+.endm8888+8989+/*9090+ * User gs save/restore9191+ *9292+ * %gs is used for userland TLS and kernel only uses it for stack9393+ * canary which is required to be at %gs:20 by gcc. Read the comment9494+ * at the top of stackprotector.h for more info.9595+ *9696+ * Local labels 98 and 99 are used.9797+ */9898+#ifdef CONFIG_X86_32_LAZY_GS9999+100100+ /* unfortunately push/pop can't be no-op */101101+.macro PUSH_GS102102+ pushl $0103103+.endm104104+.macro POP_GS pop=0105105+ addl $(4 + \pop), %esp106106+.endm107107+.macro POP_GS_EX108108+.endm109109+110110+ /* all the rest are no-op */111111+.macro PTGS_TO_GS112112+.endm113113+.macro PTGS_TO_GS_EX114114+.endm115115+.macro GS_TO_REG reg116116+.endm117117+.macro REG_TO_PTGS reg118118+.endm119119+.macro SET_KERNEL_GS reg120120+.endm121121+122122+#else /* CONFIG_X86_32_LAZY_GS */123123+124124+.macro PUSH_GS125125+ pushl %gs126126+.endm127127+128128+.macro POP_GS pop=0129129+98: popl %gs130130+ .if \pop <> 0131131+ add $\pop, %esp132132+ .endif133133+.endm134134+.macro POP_GS_EX135135+.pushsection .fixup, "ax"136136+99: movl $0, (%esp)137137+ jmp 98b138138+.popsection139139+ _ASM_EXTABLE(98b, 99b)140140+.endm141141+142142+.macro PTGS_TO_GS143143+98: mov PT_GS(%esp), %gs144144+.endm145145+.macro PTGS_TO_GS_EX146146+.pushsection .fixup, "ax"147147+99: movl $0, PT_GS(%esp)148148+ jmp 98b149149+.popsection150150+ _ASM_EXTABLE(98b, 99b)151151+.endm152152+153153+.macro GS_TO_REG reg154154+ movl %gs, \reg155155+.endm156156+.macro REG_TO_PTGS reg157157+ movl \reg, PT_GS(%esp)158158+.endm159159+.macro SET_KERNEL_GS reg160160+ movl $(__KERNEL_STACK_CANARY), \reg161161+ movl \reg, %gs162162+.endm163163+164164+#endif /* CONFIG_X86_32_LAZY_GS */165165+166166+.macro SAVE_ALL167167+ cld168168+ PUSH_GS169169+ pushl %fs170170+ pushl %es171171+ pushl %ds172172+ pushl %eax173173+ pushl %ebp174174+ pushl %edi175175+ pushl %esi176176+ pushl %edx177177+ pushl %ecx178178+ pushl %ebx179179+ movl $(__USER_DS), %edx180180+ movl %edx, %ds181181+ movl %edx, %es182182+ movl $(__KERNEL_PERCPU), %edx183183+ movl %edx, %fs184184+ SET_KERNEL_GS %edx185185+.endm186186+187187+.macro RESTORE_INT_REGS188188+ popl %ebx189189+ popl %ecx190190+ popl %edx191191+ popl %esi192192+ popl %edi193193+ popl %ebp194194+ popl %eax195195+.endm196196+197197+.macro RESTORE_REGS pop=0198198+ RESTORE_INT_REGS199199+1: popl %ds200200+2: popl %es201201+3: popl %fs202202+ POP_GS \pop203203+.pushsection .fixup, "ax"204204+4: movl $0, (%esp)205205+ jmp 1b206206+5: movl $0, (%esp)207207+ jmp 2b208208+6: movl $0, (%esp)209209+ jmp 3b210210+.popsection211211+ _ASM_EXTABLE(1b, 4b)212212+ _ASM_EXTABLE(2b, 5b)213213+ _ASM_EXTABLE(3b, 6b)214214+ POP_GS_EX215215+.endm216216+217217+ENTRY(ret_from_fork)218218+ pushl %eax219219+ call schedule_tail220220+ GET_THREAD_INFO(%ebp)221221+ popl %eax222222+ pushl $0x0202 # Reset kernel eflags223223+ popfl224224+ jmp syscall_exit225225+END(ret_from_fork)226226+227227+ENTRY(ret_from_kernel_thread)228228+ pushl %eax229229+ call schedule_tail230230+ GET_THREAD_INFO(%ebp)231231+ popl %eax232232+ pushl $0x0202 # Reset kernel eflags233233+ popfl234234+ movl PT_EBP(%esp), %eax235235+ call *PT_EBX(%esp)236236+ movl $0, PT_EAX(%esp)237237+ jmp syscall_exit238238+ENDPROC(ret_from_kernel_thread)239239+240240+/*241241+ * Return to user mode is not as complex as all this looks,242242+ * but we want the default path for a system call return to243243+ * go as quickly as possible which is why some of this is244244+ * less clear than it otherwise should be.245245+ */246246+247247+ # userspace resumption stub bypassing syscall exit tracing248248+ ALIGN249249+ret_from_exception:250250+ preempt_stop(CLBR_ANY)251251+ret_from_intr:252252+ GET_THREAD_INFO(%ebp)253253+#ifdef CONFIG_VM86254254+ movl PT_EFLAGS(%esp), %eax # mix EFLAGS and CS255255+ movb PT_CS(%esp), %al256256+ andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax257257+#else258258+ /*259259+ * We can be coming here from child spawned by kernel_thread().260260+ */261261+ movl PT_CS(%esp), %eax262262+ andl $SEGMENT_RPL_MASK, %eax263263+#endif264264+ cmpl $USER_RPL, %eax265265+ jb resume_kernel # not returning to v8086 or userspace266266+267267+ENTRY(resume_userspace)268268+ LOCKDEP_SYS_EXIT269269+ DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt270270+ # setting need_resched or sigpending271271+ # between sampling and the iret272272+ TRACE_IRQS_OFF273273+ movl TI_flags(%ebp), %ecx274274+ andl $_TIF_WORK_MASK, %ecx # is there any work to be done on275275+ # int/exception return?276276+ jne work_pending277277+ jmp restore_all278278+END(ret_from_exception)279279+280280+#ifdef CONFIG_PREEMPT281281+ENTRY(resume_kernel)282282+ DISABLE_INTERRUPTS(CLBR_ANY)283283+need_resched:284284+ cmpl $0, PER_CPU_VAR(__preempt_count)285285+ jnz restore_all286286+ testl $X86_EFLAGS_IF, PT_EFLAGS(%esp) # interrupts off (exception path) ?287287+ jz restore_all288288+ call preempt_schedule_irq289289+ jmp need_resched290290+END(resume_kernel)291291+#endif292292+293293+/*294294+ * SYSENTER_RETURN points to after the SYSENTER instruction295295+ * in the vsyscall page. See vsyscall-sysentry.S, which defines296296+ * the symbol.297297+ */298298+299299+ # SYSENTER call handler stub300300+ENTRY(entry_SYSENTER_32)301301+ movl TSS_sysenter_sp0(%esp), %esp302302+sysenter_past_esp:303303+ /*304304+ * Interrupts are disabled here, but we can't trace it until305305+ * enough kernel state to call TRACE_IRQS_OFF can be called - but306306+ * we immediately enable interrupts at that point anyway.307307+ */308308+ pushl $__USER_DS309309+ pushl %ebp310310+ pushfl311311+ orl $X86_EFLAGS_IF, (%esp)312312+ pushl $__USER_CS313313+ /*314314+ * Push current_thread_info()->sysenter_return to the stack.315315+ * A tiny bit of offset fixup is necessary: TI_sysenter_return316316+ * is relative to thread_info, which is at the bottom of the317317+ * kernel stack page. 4*4 means the 4 words pushed above;318318+ * TOP_OF_KERNEL_STACK_PADDING takes us to the top of the stack;319319+ * and THREAD_SIZE takes us to the bottom.320320+ */321321+ pushl ((TI_sysenter_return) - THREAD_SIZE + TOP_OF_KERNEL_STACK_PADDING + 4*4)(%esp)322322+323323+ pushl %eax324324+ SAVE_ALL325325+ ENABLE_INTERRUPTS(CLBR_NONE)326326+327327+/*328328+ * Load the potential sixth argument from user stack.329329+ * Careful about security.330330+ */331331+ cmpl $__PAGE_OFFSET-3, %ebp332332+ jae syscall_fault333333+ ASM_STAC334334+1: movl (%ebp), %ebp335335+ ASM_CLAC336336+ movl %ebp, PT_EBP(%esp)337337+ _ASM_EXTABLE(1b, syscall_fault)338338+339339+ GET_THREAD_INFO(%ebp)340340+341341+ testl $_TIF_WORK_SYSCALL_ENTRY, TI_flags(%ebp)342342+ jnz sysenter_audit343343+sysenter_do_call:344344+ cmpl $(NR_syscalls), %eax345345+ jae sysenter_badsys346346+ call *sys_call_table(, %eax, 4)347347+sysenter_after_call:348348+ movl %eax, PT_EAX(%esp)349349+ LOCKDEP_SYS_EXIT350350+ DISABLE_INTERRUPTS(CLBR_ANY)351351+ TRACE_IRQS_OFF352352+ movl TI_flags(%ebp), %ecx353353+ testl $_TIF_ALLWORK_MASK, %ecx354354+ jnz sysexit_audit355355+sysenter_exit:356356+/* if something modifies registers it must also disable sysexit */357357+ movl PT_EIP(%esp), %edx358358+ movl PT_OLDESP(%esp), %ecx359359+ xorl %ebp, %ebp360360+ TRACE_IRQS_ON361361+1: mov PT_FS(%esp), %fs362362+ PTGS_TO_GS363363+ ENABLE_INTERRUPTS_SYSEXIT364364+365365+#ifdef CONFIG_AUDITSYSCALL366366+sysenter_audit:367367+ testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT), TI_flags(%ebp)368368+ jnz syscall_trace_entry369369+ /* movl PT_EAX(%esp), %eax already set, syscall number: 1st arg to audit */370370+ movl PT_EBX(%esp), %edx /* ebx/a0: 2nd arg to audit */371371+ /* movl PT_ECX(%esp), %ecx already set, a1: 3nd arg to audit */372372+ pushl PT_ESI(%esp) /* a3: 5th arg */373373+ pushl PT_EDX+4(%esp) /* a2: 4th arg */374374+ call __audit_syscall_entry375375+ popl %ecx /* get that remapped edx off the stack */376376+ popl %ecx /* get that remapped esi off the stack */377377+ movl PT_EAX(%esp), %eax /* reload syscall number */378378+ jmp sysenter_do_call379379+380380+sysexit_audit:381381+ testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %ecx382382+ jnz syscall_exit_work383383+ TRACE_IRQS_ON384384+ ENABLE_INTERRUPTS(CLBR_ANY)385385+ movl %eax, %edx /* second arg, syscall return value */386386+ cmpl $-MAX_ERRNO, %eax /* is it an error ? */387387+ setbe %al /* 1 if so, 0 if not */388388+ movzbl %al, %eax /* zero-extend that */389389+ call __audit_syscall_exit390390+ DISABLE_INTERRUPTS(CLBR_ANY)391391+ TRACE_IRQS_OFF392392+ movl TI_flags(%ebp), %ecx393393+ testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %ecx394394+ jnz syscall_exit_work395395+ movl PT_EAX(%esp), %eax /* reload syscall return value */396396+ jmp sysenter_exit397397+#endif398398+399399+.pushsection .fixup, "ax"400400+2: movl $0, PT_FS(%esp)401401+ jmp 1b402402+.popsection403403+ _ASM_EXTABLE(1b, 2b)404404+ PTGS_TO_GS_EX405405+ENDPROC(entry_SYSENTER_32)406406+407407+ # system call handler stub408408+ENTRY(entry_INT80_32)409409+ ASM_CLAC410410+ pushl %eax # save orig_eax411411+ SAVE_ALL412412+ GET_THREAD_INFO(%ebp)413413+ # system call tracing in operation / emulation414414+ testl $_TIF_WORK_SYSCALL_ENTRY, TI_flags(%ebp)415415+ jnz syscall_trace_entry416416+ cmpl $(NR_syscalls), %eax417417+ jae syscall_badsys418418+syscall_call:419419+ call *sys_call_table(, %eax, 4)420420+syscall_after_call:421421+ movl %eax, PT_EAX(%esp) # store the return value422422+syscall_exit:423423+ LOCKDEP_SYS_EXIT424424+ DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt425425+ # setting need_resched or sigpending426426+ # between sampling and the iret427427+ TRACE_IRQS_OFF428428+ movl TI_flags(%ebp), %ecx429429+ testl $_TIF_ALLWORK_MASK, %ecx # current->work430430+ jnz syscall_exit_work431431+432432+restore_all:433433+ TRACE_IRQS_IRET434434+restore_all_notrace:435435+#ifdef CONFIG_X86_ESPFIX32436436+ movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS437437+ /*438438+ * Warning: PT_OLDSS(%esp) contains the wrong/random values if we439439+ * are returning to the kernel.440440+ * See comments in process.c:copy_thread() for details.441441+ */442442+ movb PT_OLDSS(%esp), %ah443443+ movb PT_CS(%esp), %al444444+ andl $(X86_EFLAGS_VM | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax445445+ cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax446446+ je ldt_ss # returning to user-space with LDT SS447447+#endif448448+restore_nocheck:449449+ RESTORE_REGS 4 # skip orig_eax/error_code450450+irq_return:451451+ INTERRUPT_RETURN452452+.section .fixup, "ax"453453+ENTRY(iret_exc )454454+ pushl $0 # no error code455455+ pushl $do_iret_error456456+ jmp error_code457457+.previous458458+ _ASM_EXTABLE(irq_return, iret_exc)459459+460460+#ifdef CONFIG_X86_ESPFIX32461461+ldt_ss:462462+#ifdef CONFIG_PARAVIRT463463+ /*464464+ * The kernel can't run on a non-flat stack if paravirt mode465465+ * is active. Rather than try to fixup the high bits of466466+ * ESP, bypass this code entirely. This may break DOSemu467467+ * and/or Wine support in a paravirt VM, although the option468468+ * is still available to implement the setting of the high469469+ * 16-bits in the INTERRUPT_RETURN paravirt-op.470470+ */471471+ cmpl $0, pv_info+PARAVIRT_enabled472472+ jne restore_nocheck473473+#endif474474+475475+/*476476+ * Setup and switch to ESPFIX stack477477+ *478478+ * We're returning to userspace with a 16 bit stack. The CPU will not479479+ * restore the high word of ESP for us on executing iret... This is an480480+ * "official" bug of all the x86-compatible CPUs, which we can work481481+ * around to make dosemu and wine happy. We do this by preloading the482482+ * high word of ESP with the high word of the userspace ESP while483483+ * compensating for the offset by changing to the ESPFIX segment with484484+ * a base address that matches for the difference.485485+ */486486+#define GDT_ESPFIX_SS PER_CPU_VAR(gdt_page) + (GDT_ENTRY_ESPFIX_SS * 8)487487+ mov %esp, %edx /* load kernel esp */488488+ mov PT_OLDESP(%esp), %eax /* load userspace esp */489489+ mov %dx, %ax /* eax: new kernel esp */490490+ sub %eax, %edx /* offset (low word is 0) */491491+ shr $16, %edx492492+ mov %dl, GDT_ESPFIX_SS + 4 /* bits 16..23 */493493+ mov %dh, GDT_ESPFIX_SS + 7 /* bits 24..31 */494494+ pushl $__ESPFIX_SS495495+ pushl %eax /* new kernel esp */496496+ /*497497+ * Disable interrupts, but do not irqtrace this section: we498498+ * will soon execute iret and the tracer was already set to499499+ * the irqstate after the IRET:500500+ */501501+ DISABLE_INTERRUPTS(CLBR_EAX)502502+ lss (%esp), %esp /* switch to espfix segment */503503+ jmp restore_nocheck504504+#endif505505+ENDPROC(entry_INT80_32)506506+507507+ # perform work that needs to be done immediately before resumption508508+ ALIGN509509+work_pending:510510+ testb $_TIF_NEED_RESCHED, %cl511511+ jz work_notifysig512512+work_resched:513513+ call schedule514514+ LOCKDEP_SYS_EXIT515515+ DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt516516+ # setting need_resched or sigpending517517+ # between sampling and the iret518518+ TRACE_IRQS_OFF519519+ movl TI_flags(%ebp), %ecx520520+ andl $_TIF_WORK_MASK, %ecx # is there any work to be done other521521+ # than syscall tracing?522522+ jz restore_all523523+ testb $_TIF_NEED_RESCHED, %cl524524+ jnz work_resched525525+526526+work_notifysig: # deal with pending signals and527527+ # notify-resume requests528528+#ifdef CONFIG_VM86529529+ testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)530530+ movl %esp, %eax531531+ jnz work_notifysig_v86 # returning to kernel-space or532532+ # vm86-space533533+1:534534+#else535535+ movl %esp, %eax536536+#endif537537+ TRACE_IRQS_ON538538+ ENABLE_INTERRUPTS(CLBR_NONE)539539+ movb PT_CS(%esp), %bl540540+ andb $SEGMENT_RPL_MASK, %bl541541+ cmpb $USER_RPL, %bl542542+ jb resume_kernel543543+ xorl %edx, %edx544544+ call do_notify_resume545545+ jmp resume_userspace546546+547547+#ifdef CONFIG_VM86548548+ ALIGN549549+work_notifysig_v86:550550+ pushl %ecx # save ti_flags for do_notify_resume551551+ call save_v86_state # %eax contains pt_regs pointer552552+ popl %ecx553553+ movl %eax, %esp554554+ jmp 1b555555+#endif556556+END(work_pending)557557+558558+ # perform syscall exit tracing559559+ ALIGN560560+syscall_trace_entry:561561+ movl $-ENOSYS, PT_EAX(%esp)562562+ movl %esp, %eax563563+ call syscall_trace_enter564564+ /* What it returned is what we'll actually use. */565565+ cmpl $(NR_syscalls), %eax566566+ jnae syscall_call567567+ jmp syscall_exit568568+END(syscall_trace_entry)569569+570570+ # perform syscall exit tracing571571+ ALIGN572572+syscall_exit_work:573573+ testl $_TIF_WORK_SYSCALL_EXIT, %ecx574574+ jz work_pending575575+ TRACE_IRQS_ON576576+ ENABLE_INTERRUPTS(CLBR_ANY) # could let syscall_trace_leave() call577577+ # schedule() instead578578+ movl %esp, %eax579579+ call syscall_trace_leave580580+ jmp resume_userspace581581+END(syscall_exit_work)582582+583583+syscall_fault:584584+ ASM_CLAC585585+ GET_THREAD_INFO(%ebp)586586+ movl $-EFAULT, PT_EAX(%esp)587587+ jmp resume_userspace588588+END(syscall_fault)589589+590590+syscall_badsys:591591+ movl $-ENOSYS, %eax592592+ jmp syscall_after_call593593+END(syscall_badsys)594594+595595+sysenter_badsys:596596+ movl $-ENOSYS, %eax597597+ jmp sysenter_after_call598598+END(sysenter_badsys)599599+600600+.macro FIXUP_ESPFIX_STACK601601+/*602602+ * Switch back for ESPFIX stack to the normal zerobased stack603603+ *604604+ * We can't call C functions using the ESPFIX stack. This code reads605605+ * the high word of the segment base from the GDT and swiches to the606606+ * normal stack and adjusts ESP with the matching offset.607607+ */608608+#ifdef CONFIG_X86_ESPFIX32609609+ /* fixup the stack */610610+ mov GDT_ESPFIX_SS + 4, %al /* bits 16..23 */611611+ mov GDT_ESPFIX_SS + 7, %ah /* bits 24..31 */612612+ shl $16, %eax613613+ addl %esp, %eax /* the adjusted stack pointer */614614+ pushl $__KERNEL_DS615615+ pushl %eax616616+ lss (%esp), %esp /* switch to the normal stack segment */617617+#endif618618+.endm619619+.macro UNWIND_ESPFIX_STACK620620+#ifdef CONFIG_X86_ESPFIX32621621+ movl %ss, %eax622622+ /* see if on espfix stack */623623+ cmpw $__ESPFIX_SS, %ax624624+ jne 27f625625+ movl $__KERNEL_DS, %eax626626+ movl %eax, %ds627627+ movl %eax, %es628628+ /* switch to normal stack */629629+ FIXUP_ESPFIX_STACK630630+27:631631+#endif632632+.endm633633+634634+/*635635+ * Build the entry stubs with some assembler magic.636636+ * We pack 1 stub into every 8-byte block.637637+ */638638+ .align 8639639+ENTRY(irq_entries_start)640640+ vector=FIRST_EXTERNAL_VECTOR641641+ .rept (FIRST_SYSTEM_VECTOR - FIRST_EXTERNAL_VECTOR)642642+ pushl $(~vector+0x80) /* Note: always in signed byte range */643643+ vector=vector+1644644+ jmp common_interrupt645645+ .align 8646646+ .endr647647+END(irq_entries_start)648648+649649+/*650650+ * the CPU automatically disables interrupts when executing an IRQ vector,651651+ * so IRQ-flags tracing has to follow that:652652+ */653653+ .p2align CONFIG_X86_L1_CACHE_SHIFT654654+common_interrupt:655655+ ASM_CLAC656656+ addl $-0x80, (%esp) /* Adjust vector into the [-256, -1] range */657657+ SAVE_ALL658658+ TRACE_IRQS_OFF659659+ movl %esp, %eax660660+ call do_IRQ661661+ jmp ret_from_intr662662+ENDPROC(common_interrupt)663663+664664+#define BUILD_INTERRUPT3(name, nr, fn) \665665+ENTRY(name) \666666+ ASM_CLAC; \667667+ pushl $~(nr); \668668+ SAVE_ALL; \669669+ TRACE_IRQS_OFF \670670+ movl %esp, %eax; \671671+ call fn; \672672+ jmp ret_from_intr; \673673+ENDPROC(name)674674+675675+676676+#ifdef CONFIG_TRACING677677+# define TRACE_BUILD_INTERRUPT(name, nr) BUILD_INTERRUPT3(trace_##name, nr, smp_trace_##name)678678+#else679679+# define TRACE_BUILD_INTERRUPT(name, nr)680680+#endif681681+682682+#define BUILD_INTERRUPT(name, nr) \683683+ BUILD_INTERRUPT3(name, nr, smp_##name); \684684+ TRACE_BUILD_INTERRUPT(name, nr)685685+686686+/* The include is where all of the SMP etc. interrupts come from */687687+#include <asm/entry_arch.h>688688+689689+ENTRY(coprocessor_error)690690+ ASM_CLAC691691+ pushl $0692692+ pushl $do_coprocessor_error693693+ jmp error_code694694+END(coprocessor_error)695695+696696+ENTRY(simd_coprocessor_error)697697+ ASM_CLAC698698+ pushl $0699699+#ifdef CONFIG_X86_INVD_BUG700700+ /* AMD 486 bug: invd from userspace calls exception 19 instead of #GP */701701+ ALTERNATIVE "pushl $do_general_protection", \702702+ "pushl $do_simd_coprocessor_error", \703703+ X86_FEATURE_XMM704704+#else705705+ pushl $do_simd_coprocessor_error706706+#endif707707+ jmp error_code708708+END(simd_coprocessor_error)709709+710710+ENTRY(device_not_available)711711+ ASM_CLAC712712+ pushl $-1 # mark this as an int713713+ pushl $do_device_not_available714714+ jmp error_code715715+END(device_not_available)716716+717717+#ifdef CONFIG_PARAVIRT718718+ENTRY(native_iret)719719+ iret720720+ _ASM_EXTABLE(native_iret, iret_exc)721721+END(native_iret)722722+723723+ENTRY(native_irq_enable_sysexit)724724+ sti725725+ sysexit726726+END(native_irq_enable_sysexit)727727+#endif728728+729729+ENTRY(overflow)730730+ ASM_CLAC731731+ pushl $0732732+ pushl $do_overflow733733+ jmp error_code734734+END(overflow)735735+736736+ENTRY(bounds)737737+ ASM_CLAC738738+ pushl $0739739+ pushl $do_bounds740740+ jmp error_code741741+END(bounds)742742+743743+ENTRY(invalid_op)744744+ ASM_CLAC745745+ pushl $0746746+ pushl $do_invalid_op747747+ jmp error_code748748+END(invalid_op)749749+750750+ENTRY(coprocessor_segment_overrun)751751+ ASM_CLAC752752+ pushl $0753753+ pushl $do_coprocessor_segment_overrun754754+ jmp error_code755755+END(coprocessor_segment_overrun)756756+757757+ENTRY(invalid_TSS)758758+ ASM_CLAC759759+ pushl $do_invalid_TSS760760+ jmp error_code761761+END(invalid_TSS)762762+763763+ENTRY(segment_not_present)764764+ ASM_CLAC765765+ pushl $do_segment_not_present766766+ jmp error_code767767+END(segment_not_present)768768+769769+ENTRY(stack_segment)770770+ ASM_CLAC771771+ pushl $do_stack_segment772772+ jmp error_code773773+END(stack_segment)774774+775775+ENTRY(alignment_check)776776+ ASM_CLAC777777+ pushl $do_alignment_check778778+ jmp error_code779779+END(alignment_check)780780+781781+ENTRY(divide_error)782782+ ASM_CLAC783783+ pushl $0 # no error code784784+ pushl $do_divide_error785785+ jmp error_code786786+END(divide_error)787787+788788+#ifdef CONFIG_X86_MCE789789+ENTRY(machine_check)790790+ ASM_CLAC791791+ pushl $0792792+ pushl machine_check_vector793793+ jmp error_code794794+END(machine_check)795795+#endif796796+797797+ENTRY(spurious_interrupt_bug)798798+ ASM_CLAC799799+ pushl $0800800+ pushl $do_spurious_interrupt_bug801801+ jmp error_code802802+END(spurious_interrupt_bug)803803+804804+#ifdef CONFIG_XEN805805+/*806806+ * Xen doesn't set %esp to be precisely what the normal SYSENTER807807+ * entry point expects, so fix it up before using the normal path.808808+ */809809+ENTRY(xen_sysenter_target)810810+ addl $5*4, %esp /* remove xen-provided frame */811811+ jmp sysenter_past_esp812812+813813+ENTRY(xen_hypervisor_callback)814814+ pushl $-1 /* orig_ax = -1 => not a system call */815815+ SAVE_ALL816816+ TRACE_IRQS_OFF817817+818818+ /*819819+ * Check to see if we got the event in the critical820820+ * region in xen_iret_direct, after we've reenabled821821+ * events and checked for pending events. This simulates822822+ * iret instruction's behaviour where it delivers a823823+ * pending interrupt when enabling interrupts:824824+ */825825+ movl PT_EIP(%esp), %eax826826+ cmpl $xen_iret_start_crit, %eax827827+ jb 1f828828+ cmpl $xen_iret_end_crit, %eax829829+ jae 1f830830+831831+ jmp xen_iret_crit_fixup832832+833833+ENTRY(xen_do_upcall)834834+1: mov %esp, %eax835835+ call xen_evtchn_do_upcall836836+#ifndef CONFIG_PREEMPT837837+ call xen_maybe_preempt_hcall838838+#endif839839+ jmp ret_from_intr840840+ENDPROC(xen_hypervisor_callback)841841+842842+/*843843+ * Hypervisor uses this for application faults while it executes.844844+ * We get here for two reasons:845845+ * 1. Fault while reloading DS, ES, FS or GS846846+ * 2. Fault while executing IRET847847+ * Category 1 we fix up by reattempting the load, and zeroing the segment848848+ * register if the load fails.849849+ * Category 2 we fix up by jumping to do_iret_error. We cannot use the850850+ * normal Linux return path in this case because if we use the IRET hypercall851851+ * to pop the stack frame we end up in an infinite loop of failsafe callbacks.852852+ * We distinguish between categories by maintaining a status value in EAX.853853+ */854854+ENTRY(xen_failsafe_callback)855855+ pushl %eax856856+ movl $1, %eax857857+1: mov 4(%esp), %ds858858+2: mov 8(%esp), %es859859+3: mov 12(%esp), %fs860860+4: mov 16(%esp), %gs861861+ /* EAX == 0 => Category 1 (Bad segment)862862+ EAX != 0 => Category 2 (Bad IRET) */863863+ testl %eax, %eax864864+ popl %eax865865+ lea 16(%esp), %esp866866+ jz 5f867867+ jmp iret_exc868868+5: pushl $-1 /* orig_ax = -1 => not a system call */869869+ SAVE_ALL870870+ jmp ret_from_exception871871+872872+.section .fixup, "ax"873873+6: xorl %eax, %eax874874+ movl %eax, 4(%esp)875875+ jmp 1b876876+7: xorl %eax, %eax877877+ movl %eax, 8(%esp)878878+ jmp 2b879879+8: xorl %eax, %eax880880+ movl %eax, 12(%esp)881881+ jmp 3b882882+9: xorl %eax, %eax883883+ movl %eax, 16(%esp)884884+ jmp 4b885885+.previous886886+ _ASM_EXTABLE(1b, 6b)887887+ _ASM_EXTABLE(2b, 7b)888888+ _ASM_EXTABLE(3b, 8b)889889+ _ASM_EXTABLE(4b, 9b)890890+ENDPROC(xen_failsafe_callback)891891+892892+BUILD_INTERRUPT3(xen_hvm_callback_vector, HYPERVISOR_CALLBACK_VECTOR,893893+ xen_evtchn_do_upcall)894894+895895+#endif /* CONFIG_XEN */896896+897897+#if IS_ENABLED(CONFIG_HYPERV)898898+899899+BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR,900900+ hyperv_vector_handler)901901+902902+#endif /* CONFIG_HYPERV */903903+904904+#ifdef CONFIG_FUNCTION_TRACER905905+#ifdef CONFIG_DYNAMIC_FTRACE906906+907907+ENTRY(mcount)908908+ ret909909+END(mcount)910910+911911+ENTRY(ftrace_caller)912912+ pushl %eax913913+ pushl %ecx914914+ pushl %edx915915+ pushl $0 /* Pass NULL as regs pointer */916916+ movl 4*4(%esp), %eax917917+ movl 0x4(%ebp), %edx918918+ movl function_trace_op, %ecx919919+ subl $MCOUNT_INSN_SIZE, %eax920920+921921+.globl ftrace_call922922+ftrace_call:923923+ call ftrace_stub924924+925925+ addl $4, %esp /* skip NULL pointer */926926+ popl %edx927927+ popl %ecx928928+ popl %eax929929+ftrace_ret:930930+#ifdef CONFIG_FUNCTION_GRAPH_TRACER931931+.globl ftrace_graph_call932932+ftrace_graph_call:933933+ jmp ftrace_stub934934+#endif935935+936936+.globl ftrace_stub937937+ftrace_stub:938938+ ret939939+END(ftrace_caller)940940+941941+ENTRY(ftrace_regs_caller)942942+ pushf /* push flags before compare (in cs location) */943943+944944+ /*945945+ * i386 does not save SS and ESP when coming from kernel.946946+ * Instead, to get sp, ®s->sp is used (see ptrace.h).947947+ * Unfortunately, that means eflags must be at the same location948948+ * as the current return ip is. We move the return ip into the949949+ * ip location, and move flags into the return ip location.950950+ */951951+ pushl 4(%esp) /* save return ip into ip slot */952952+953953+ pushl $0 /* Load 0 into orig_ax */954954+ pushl %gs955955+ pushl %fs956956+ pushl %es957957+ pushl %ds958958+ pushl %eax959959+ pushl %ebp960960+ pushl %edi961961+ pushl %esi962962+ pushl %edx963963+ pushl %ecx964964+ pushl %ebx965965+966966+ movl 13*4(%esp), %eax /* Get the saved flags */967967+ movl %eax, 14*4(%esp) /* Move saved flags into regs->flags location */968968+ /* clobbering return ip */969969+ movl $__KERNEL_CS, 13*4(%esp)970970+971971+ movl 12*4(%esp), %eax /* Load ip (1st parameter) */972972+ subl $MCOUNT_INSN_SIZE, %eax /* Adjust ip */973973+ movl 0x4(%ebp), %edx /* Load parent ip (2nd parameter) */974974+ movl function_trace_op, %ecx /* Save ftrace_pos in 3rd parameter */975975+ pushl %esp /* Save pt_regs as 4th parameter */976976+977977+GLOBAL(ftrace_regs_call)978978+ call ftrace_stub979979+980980+ addl $4, %esp /* Skip pt_regs */981981+ movl 14*4(%esp), %eax /* Move flags back into cs */982982+ movl %eax, 13*4(%esp) /* Needed to keep addl from modifying flags */983983+ movl 12*4(%esp), %eax /* Get return ip from regs->ip */984984+ movl %eax, 14*4(%esp) /* Put return ip back for ret */985985+986986+ popl %ebx987987+ popl %ecx988988+ popl %edx989989+ popl %esi990990+ popl %edi991991+ popl %ebp992992+ popl %eax993993+ popl %ds994994+ popl %es995995+ popl %fs996996+ popl %gs997997+ addl $8, %esp /* Skip orig_ax and ip */998998+ popf /* Pop flags at end (no addl to corrupt flags) */999999+ jmp ftrace_ret10001000+10011001+ popf10021002+ jmp ftrace_stub10031003+#else /* ! CONFIG_DYNAMIC_FTRACE */10041004+10051005+ENTRY(mcount)10061006+ cmpl $__PAGE_OFFSET, %esp10071007+ jb ftrace_stub /* Paging not enabled yet? */10081008+10091009+ cmpl $ftrace_stub, ftrace_trace_function10101010+ jnz trace10111011+#ifdef CONFIG_FUNCTION_GRAPH_TRACER10121012+ cmpl $ftrace_stub, ftrace_graph_return10131013+ jnz ftrace_graph_caller10141014+10151015+ cmpl $ftrace_graph_entry_stub, ftrace_graph_entry10161016+ jnz ftrace_graph_caller10171017+#endif10181018+.globl ftrace_stub10191019+ftrace_stub:10201020+ ret10211021+10221022+ /* taken from glibc */10231023+trace:10241024+ pushl %eax10251025+ pushl %ecx10261026+ pushl %edx10271027+ movl 0xc(%esp), %eax10281028+ movl 0x4(%ebp), %edx10291029+ subl $MCOUNT_INSN_SIZE, %eax10301030+10311031+ call *ftrace_trace_function10321032+10331033+ popl %edx10341034+ popl %ecx10351035+ popl %eax10361036+ jmp ftrace_stub10371037+END(mcount)10381038+#endif /* CONFIG_DYNAMIC_FTRACE */10391039+#endif /* CONFIG_FUNCTION_TRACER */10401040+10411041+#ifdef CONFIG_FUNCTION_GRAPH_TRACER10421042+ENTRY(ftrace_graph_caller)10431043+ pushl %eax10441044+ pushl %ecx10451045+ pushl %edx10461046+ movl 0xc(%esp), %eax10471047+ lea 0x4(%ebp), %edx10481048+ movl (%ebp), %ecx10491049+ subl $MCOUNT_INSN_SIZE, %eax10501050+ call prepare_ftrace_return10511051+ popl %edx10521052+ popl %ecx10531053+ popl %eax10541054+ ret10551055+END(ftrace_graph_caller)10561056+10571057+.globl return_to_handler10581058+return_to_handler:10591059+ pushl %eax10601060+ pushl %edx10611061+ movl %ebp, %eax10621062+ call ftrace_return_to_handler10631063+ movl %eax, %ecx10641064+ popl %edx10651065+ popl %eax10661066+ jmp *%ecx10671067+#endif10681068+10691069+#ifdef CONFIG_TRACING10701070+ENTRY(trace_page_fault)10711071+ ASM_CLAC10721072+ pushl $trace_do_page_fault10731073+ jmp error_code10741074+END(trace_page_fault)10751075+#endif10761076+10771077+ENTRY(page_fault)10781078+ ASM_CLAC10791079+ pushl $do_page_fault10801080+ ALIGN10811081+error_code:10821082+ /* the function address is in %gs's slot on the stack */10831083+ pushl %fs10841084+ pushl %es10851085+ pushl %ds10861086+ pushl %eax10871087+ pushl %ebp10881088+ pushl %edi10891089+ pushl %esi10901090+ pushl %edx10911091+ pushl %ecx10921092+ pushl %ebx10931093+ cld10941094+ movl $(__KERNEL_PERCPU), %ecx10951095+ movl %ecx, %fs10961096+ UNWIND_ESPFIX_STACK10971097+ GS_TO_REG %ecx10981098+ movl PT_GS(%esp), %edi # get the function address10991099+ movl PT_ORIG_EAX(%esp), %edx # get the error code11001100+ movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart11011101+ REG_TO_PTGS %ecx11021102+ SET_KERNEL_GS %ecx11031103+ movl $(__USER_DS), %ecx11041104+ movl %ecx, %ds11051105+ movl %ecx, %es11061106+ TRACE_IRQS_OFF11071107+ movl %esp, %eax # pt_regs pointer11081108+ call *%edi11091109+ jmp ret_from_exception11101110+END(page_fault)11111111+11121112+/*11131113+ * Debug traps and NMI can happen at the one SYSENTER instruction11141114+ * that sets up the real kernel stack. Check here, since we can't11151115+ * allow the wrong stack to be used.11161116+ *11171117+ * "TSS_sysenter_sp0+12" is because the NMI/debug handler will have11181118+ * already pushed 3 words if it hits on the sysenter instruction:11191119+ * eflags, cs and eip.11201120+ *11211121+ * We just load the right stack, and push the three (known) values11221122+ * by hand onto the new stack - while updating the return eip past11231123+ * the instruction that would have done it for sysenter.11241124+ */11251125+.macro FIX_STACK offset ok label11261126+ cmpw $__KERNEL_CS, 4(%esp)11271127+ jne \ok11281128+\label:11291129+ movl TSS_sysenter_sp0 + \offset(%esp), %esp11301130+ pushfl11311131+ pushl $__KERNEL_CS11321132+ pushl $sysenter_past_esp11331133+.endm11341134+11351135+ENTRY(debug)11361136+ ASM_CLAC11371137+ cmpl $entry_SYSENTER_32, (%esp)11381138+ jne debug_stack_correct11391139+ FIX_STACK 12, debug_stack_correct, debug_esp_fix_insn11401140+debug_stack_correct:11411141+ pushl $-1 # mark this as an int11421142+ SAVE_ALL11431143+ TRACE_IRQS_OFF11441144+ xorl %edx, %edx # error code 011451145+ movl %esp, %eax # pt_regs pointer11461146+ call do_debug11471147+ jmp ret_from_exception11481148+END(debug)11491149+11501150+/*11511151+ * NMI is doubly nasty. It can happen _while_ we're handling11521152+ * a debug fault, and the debug fault hasn't yet been able to11531153+ * clear up the stack. So we first check whether we got an11541154+ * NMI on the sysenter entry path, but after that we need to11551155+ * check whether we got an NMI on the debug path where the debug11561156+ * fault happened on the sysenter path.11571157+ */11581158+ENTRY(nmi)11591159+ ASM_CLAC11601160+#ifdef CONFIG_X86_ESPFIX3211611161+ pushl %eax11621162+ movl %ss, %eax11631163+ cmpw $__ESPFIX_SS, %ax11641164+ popl %eax11651165+ je nmi_espfix_stack11661166+#endif11671167+ cmpl $entry_SYSENTER_32, (%esp)11681168+ je nmi_stack_fixup11691169+ pushl %eax11701170+ movl %esp, %eax11711171+ /*11721172+ * Do not access memory above the end of our stack page,11731173+ * it might not exist.11741174+ */11751175+ andl $(THREAD_SIZE-1), %eax11761176+ cmpl $(THREAD_SIZE-20), %eax11771177+ popl %eax11781178+ jae nmi_stack_correct11791179+ cmpl $entry_SYSENTER_32, 12(%esp)11801180+ je nmi_debug_stack_check11811181+nmi_stack_correct:11821182+ pushl %eax11831183+ SAVE_ALL11841184+ xorl %edx, %edx # zero error code11851185+ movl %esp, %eax # pt_regs pointer11861186+ call do_nmi11871187+ jmp restore_all_notrace11881188+11891189+nmi_stack_fixup:11901190+ FIX_STACK 12, nmi_stack_correct, 111911191+ jmp nmi_stack_correct11921192+11931193+nmi_debug_stack_check:11941194+ cmpw $__KERNEL_CS, 16(%esp)11951195+ jne nmi_stack_correct11961196+ cmpl $debug, (%esp)11971197+ jb nmi_stack_correct11981198+ cmpl $debug_esp_fix_insn, (%esp)11991199+ ja nmi_stack_correct12001200+ FIX_STACK 24, nmi_stack_correct, 112011201+ jmp nmi_stack_correct12021202+12031203+#ifdef CONFIG_X86_ESPFIX3212041204+nmi_espfix_stack:12051205+ /*12061206+ * create the pointer to lss back12071207+ */12081208+ pushl %ss12091209+ pushl %esp12101210+ addl $4, (%esp)12111211+ /* copy the iret frame of 12 bytes */12121212+ .rept 312131213+ pushl 16(%esp)12141214+ .endr12151215+ pushl %eax12161216+ SAVE_ALL12171217+ FIXUP_ESPFIX_STACK # %eax == %esp12181218+ xorl %edx, %edx # zero error code12191219+ call do_nmi12201220+ RESTORE_REGS12211221+ lss 12+4(%esp), %esp # back to espfix stack12221222+ jmp irq_return12231223+#endif12241224+END(nmi)12251225+12261226+ENTRY(int3)12271227+ ASM_CLAC12281228+ pushl $-1 # mark this as an int12291229+ SAVE_ALL12301230+ TRACE_IRQS_OFF12311231+ xorl %edx, %edx # zero error code12321232+ movl %esp, %eax # pt_regs pointer12331233+ call do_int312341234+ jmp ret_from_exception12351235+END(int3)12361236+12371237+ENTRY(general_protection)12381238+ pushl $do_general_protection12391239+ jmp error_code12401240+END(general_protection)12411241+12421242+#ifdef CONFIG_KVM_GUEST12431243+ENTRY(async_page_fault)12441244+ ASM_CLAC12451245+ pushl $do_async_page_fault12461246+ jmp error_code12471247+END(async_page_fault)12481248+#endif
+547
arch/x86/entry/entry_64_compat.S
···11+/*22+ * Compatibility mode system call entry point for x86-64.33+ *44+ * Copyright 2000-2002 Andi Kleen, SuSE Labs.55+ */66+#include "calling.h"77+#include <asm/asm-offsets.h>88+#include <asm/current.h>99+#include <asm/errno.h>1010+#include <asm/ia32_unistd.h>1111+#include <asm/thread_info.h>1212+#include <asm/segment.h>1313+#include <asm/irqflags.h>1414+#include <asm/asm.h>1515+#include <asm/smap.h>1616+#include <linux/linkage.h>1717+#include <linux/err.h>1818+1919+/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */2020+#include <linux/elf-em.h>2121+#define AUDIT_ARCH_I386 (EM_386|__AUDIT_ARCH_LE)2222+#define __AUDIT_ARCH_LE 0x400000002323+2424+#ifndef CONFIG_AUDITSYSCALL2525+# define sysexit_audit ia32_ret_from_sys_call2626+# define sysretl_audit ia32_ret_from_sys_call2727+#endif2828+2929+ .section .entry.text, "ax"3030+3131+#ifdef CONFIG_PARAVIRT3232+ENTRY(native_usergs_sysret32)3333+ swapgs3434+ sysretl3535+ENDPROC(native_usergs_sysret32)3636+#endif3737+3838+/*3939+ * 32-bit SYSENTER instruction entry.4040+ *4141+ * SYSENTER loads ss, rsp, cs, and rip from previously programmed MSRs.4242+ * IF and VM in rflags are cleared (IOW: interrupts are off).4343+ * SYSENTER does not save anything on the stack,4444+ * and does not save old rip (!!!) and rflags.4545+ *4646+ * Arguments:4747+ * eax system call number4848+ * ebx arg14949+ * ecx arg25050+ * edx arg35151+ * esi arg45252+ * edi arg55353+ * ebp user stack5454+ * 0(%ebp) arg65555+ *5656+ * This is purely a fast path. For anything complicated we use the int 0x805757+ * path below. We set up a complete hardware stack frame to share code5858+ * with the int 0x80 path.5959+ */6060+ENTRY(entry_SYSENTER_compat)6161+ /*6262+ * Interrupts are off on entry.6363+ * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON,6464+ * it is too small to ever cause noticeable irq latency.6565+ */6666+ SWAPGS_UNSAFE_STACK6767+ movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp6868+ ENABLE_INTERRUPTS(CLBR_NONE)6969+7070+ /* Zero-extending 32-bit regs, do not remove */7171+ movl %ebp, %ebp7272+ movl %eax, %eax7373+7474+ movl ASM_THREAD_INFO(TI_sysenter_return, %rsp, 0), %r10d7575+7676+ /* Construct struct pt_regs on stack */7777+ pushq $__USER32_DS /* pt_regs->ss */7878+ pushq %rbp /* pt_regs->sp */7979+ pushfq /* pt_regs->flags */8080+ pushq $__USER32_CS /* pt_regs->cs */8181+ pushq %r10 /* pt_regs->ip = thread_info->sysenter_return */8282+ pushq %rax /* pt_regs->orig_ax */8383+ pushq %rdi /* pt_regs->di */8484+ pushq %rsi /* pt_regs->si */8585+ pushq %rdx /* pt_regs->dx */8686+ pushq %rcx /* pt_regs->cx */8787+ pushq $-ENOSYS /* pt_regs->ax */8888+ cld8989+ sub $(10*8), %rsp /* pt_regs->r8-11, bp, bx, r12-15 not saved */9090+9191+ /*9292+ * no need to do an access_ok check here because rbp has been9393+ * 32-bit zero extended9494+ */9595+ ASM_STAC9696+1: movl (%rbp), %ebp9797+ _ASM_EXTABLE(1b, ia32_badarg)9898+ ASM_CLAC9999+100100+ /*101101+ * Sysenter doesn't filter flags, so we need to clear NT102102+ * ourselves. To save a few cycles, we can check whether103103+ * NT was set instead of doing an unconditional popfq.104104+ */105105+ testl $X86_EFLAGS_NT, EFLAGS(%rsp)106106+ jnz sysenter_fix_flags107107+sysenter_flags_fixed:108108+109109+ orl $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)110110+ testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)111111+ jnz sysenter_tracesys112112+113113+sysenter_do_call:114114+ /* 32-bit syscall -> 64-bit C ABI argument conversion */115115+ movl %edi, %r8d /* arg5 */116116+ movl %ebp, %r9d /* arg6 */117117+ xchg %ecx, %esi /* rsi:arg2, rcx:arg4 */118118+ movl %ebx, %edi /* arg1 */119119+ movl %edx, %edx /* arg3 (zero extension) */120120+sysenter_dispatch:121121+ cmpq $(IA32_NR_syscalls-1), %rax122122+ ja 1f123123+ call *ia32_sys_call_table(, %rax, 8)124124+ movq %rax, RAX(%rsp)125125+1:126126+ DISABLE_INTERRUPTS(CLBR_NONE)127127+ TRACE_IRQS_OFF128128+ testl $_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)129129+ jnz sysexit_audit130130+sysexit_from_sys_call:131131+ /*132132+ * NB: SYSEXIT is not obviously safe for 64-bit kernels -- an133133+ * NMI between STI and SYSEXIT has poorly specified behavior,134134+ * and and NMI followed by an IRQ with usergs is fatal. So135135+ * we just pretend we're using SYSEXIT but we really use136136+ * SYSRETL instead.137137+ *138138+ * This code path is still called 'sysexit' because it pairs139139+ * with 'sysenter' and it uses the SYSENTER calling convention.140140+ */141141+ andl $~TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)142142+ movl RIP(%rsp), %ecx /* User %eip */143143+ RESTORE_RSI_RDI144144+ xorl %edx, %edx /* Do not leak kernel information */145145+ xorq %r8, %r8146146+ xorq %r9, %r9147147+ xorq %r10, %r10148148+ movl EFLAGS(%rsp), %r11d /* User eflags */149149+ TRACE_IRQS_ON150150+151151+ /*152152+ * SYSRETL works even on Intel CPUs. Use it in preference to SYSEXIT,153153+ * since it avoids a dicey window with interrupts enabled.154154+ */155155+ movl RSP(%rsp), %esp156156+157157+ /*158158+ * USERGS_SYSRET32 does:159159+ * gsbase = user's gs base160160+ * eip = ecx161161+ * rflags = r11162162+ * cs = __USER32_CS163163+ * ss = __USER_DS164164+ *165165+ * The prologue set RIP(%rsp) to VDSO32_SYSENTER_RETURN, which does:166166+ *167167+ * pop %ebp168168+ * pop %edx169169+ * pop %ecx170170+ *171171+ * Therefore, we invoke SYSRETL with EDX and R8-R10 zeroed to172172+ * avoid info leaks. R11 ends up with VDSO32_SYSENTER_RETURN's173173+ * address (already known to user code), and R12-R15 are174174+ * callee-saved and therefore don't contain any interesting175175+ * kernel data.176176+ */177177+ USERGS_SYSRET32178178+179179+#ifdef CONFIG_AUDITSYSCALL180180+ .macro auditsys_entry_common181181+ movl %esi, %r8d /* 5th arg: 4th syscall arg */182182+ movl %ecx, %r9d /* swap with edx */183183+ movl %edx, %ecx /* 4th arg: 3rd syscall arg */184184+ movl %r9d, %edx /* 3rd arg: 2nd syscall arg */185185+ movl %ebx, %esi /* 2nd arg: 1st syscall arg */186186+ movl %eax, %edi /* 1st arg: syscall number */187187+ call __audit_syscall_entry188188+ movl ORIG_RAX(%rsp), %eax /* reload syscall number */189189+ movl %ebx, %edi /* reload 1st syscall arg */190190+ movl RCX(%rsp), %esi /* reload 2nd syscall arg */191191+ movl RDX(%rsp), %edx /* reload 3rd syscall arg */192192+ movl RSI(%rsp), %ecx /* reload 4th syscall arg */193193+ movl RDI(%rsp), %r8d /* reload 5th syscall arg */194194+ .endm195195+196196+ .macro auditsys_exit exit197197+ testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)198198+ jnz ia32_ret_from_sys_call199199+ TRACE_IRQS_ON200200+ ENABLE_INTERRUPTS(CLBR_NONE)201201+ movl %eax, %esi /* second arg, syscall return value */202202+ cmpl $-MAX_ERRNO, %eax /* is it an error ? */203203+ jbe 1f204204+ movslq %eax, %rsi /* if error sign extend to 64 bits */205205+1: setbe %al /* 1 if error, 0 if not */206206+ movzbl %al, %edi /* zero-extend that into %edi */207207+ call __audit_syscall_exit208208+ movq RAX(%rsp), %rax /* reload syscall return value */209209+ movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %edi210210+ DISABLE_INTERRUPTS(CLBR_NONE)211211+ TRACE_IRQS_OFF212212+ testl %edi, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)213213+ jz \exit214214+ xorl %eax, %eax /* Do not leak kernel information */215215+ movq %rax, R11(%rsp)216216+ movq %rax, R10(%rsp)217217+ movq %rax, R9(%rsp)218218+ movq %rax, R8(%rsp)219219+ jmp int_with_check220220+ .endm221221+222222+sysenter_auditsys:223223+ auditsys_entry_common224224+ movl %ebp, %r9d /* reload 6th syscall arg */225225+ jmp sysenter_dispatch226226+227227+sysexit_audit:228228+ auditsys_exit sysexit_from_sys_call229229+#endif230230+231231+sysenter_fix_flags:232232+ pushq $(X86_EFLAGS_IF|X86_EFLAGS_FIXED)233233+ popfq234234+ jmp sysenter_flags_fixed235235+236236+sysenter_tracesys:237237+#ifdef CONFIG_AUDITSYSCALL238238+ testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT), ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)239239+ jz sysenter_auditsys240240+#endif241241+ SAVE_EXTRA_REGS242242+ xorl %eax, %eax /* Do not leak kernel information */243243+ movq %rax, R11(%rsp)244244+ movq %rax, R10(%rsp)245245+ movq %rax, R9(%rsp)246246+ movq %rax, R8(%rsp)247247+ movq %rsp, %rdi /* &pt_regs -> arg1 */248248+ call syscall_trace_enter249249+250250+ /* Reload arg registers from stack. (see sysenter_tracesys) */251251+ movl RCX(%rsp), %ecx252252+ movl RDX(%rsp), %edx253253+ movl RSI(%rsp), %esi254254+ movl RDI(%rsp), %edi255255+ movl %eax, %eax /* zero extension */256256+257257+ RESTORE_EXTRA_REGS258258+ jmp sysenter_do_call259259+ENDPROC(entry_SYSENTER_compat)260260+261261+/*262262+ * 32-bit SYSCALL instruction entry.263263+ *264264+ * 32-bit SYSCALL saves rip to rcx, clears rflags.RF, then saves rflags to r11,265265+ * then loads new ss, cs, and rip from previously programmed MSRs.266266+ * rflags gets masked by a value from another MSR (so CLD and CLAC267267+ * are not needed). SYSCALL does not save anything on the stack268268+ * and does not change rsp.269269+ *270270+ * Note: rflags saving+masking-with-MSR happens only in Long mode271271+ * (in legacy 32-bit mode, IF, RF and VM bits are cleared and that's it).272272+ * Don't get confused: rflags saving+masking depends on Long Mode Active bit273273+ * (EFER.LMA=1), NOT on bitness of userspace where SYSCALL executes274274+ * or target CS descriptor's L bit (SYSCALL does not read segment descriptors).275275+ *276276+ * Arguments:277277+ * eax system call number278278+ * ecx return address279279+ * ebx arg1280280+ * ebp arg2 (note: not saved in the stack frame, should not be touched)281281+ * edx arg3282282+ * esi arg4283283+ * edi arg5284284+ * esp user stack285285+ * 0(%esp) arg6286286+ *287287+ * This is purely a fast path. For anything complicated we use the int 0x80288288+ * path below. We set up a complete hardware stack frame to share code289289+ * with the int 0x80 path.290290+ */291291+ENTRY(entry_SYSCALL_compat)292292+ /*293293+ * Interrupts are off on entry.294294+ * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON,295295+ * it is too small to ever cause noticeable irq latency.296296+ */297297+ SWAPGS_UNSAFE_STACK298298+ movl %esp, %r8d299299+ movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp300300+ ENABLE_INTERRUPTS(CLBR_NONE)301301+302302+ /* Zero-extending 32-bit regs, do not remove */303303+ movl %eax, %eax304304+305305+ /* Construct struct pt_regs on stack */306306+ pushq $__USER32_DS /* pt_regs->ss */307307+ pushq %r8 /* pt_regs->sp */308308+ pushq %r11 /* pt_regs->flags */309309+ pushq $__USER32_CS /* pt_regs->cs */310310+ pushq %rcx /* pt_regs->ip */311311+ pushq %rax /* pt_regs->orig_ax */312312+ pushq %rdi /* pt_regs->di */313313+ pushq %rsi /* pt_regs->si */314314+ pushq %rdx /* pt_regs->dx */315315+ pushq %rbp /* pt_regs->cx */316316+ movl %ebp, %ecx317317+ pushq $-ENOSYS /* pt_regs->ax */318318+ sub $(10*8), %rsp /* pt_regs->r8-11, bp, bx, r12-15 not saved */319319+320320+ /*321321+ * No need to do an access_ok check here because r8 has been322322+ * 32-bit zero extended:323323+ */324324+ ASM_STAC325325+1: movl (%r8), %ebp326326+ _ASM_EXTABLE(1b, ia32_badarg)327327+ ASM_CLAC328328+ orl $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)329329+ testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)330330+ jnz cstar_tracesys331331+332332+cstar_do_call:333333+ /* 32-bit syscall -> 64-bit C ABI argument conversion */334334+ movl %edi, %r8d /* arg5 */335335+ movl %ebp, %r9d /* arg6 */336336+ xchg %ecx, %esi /* rsi:arg2, rcx:arg4 */337337+ movl %ebx, %edi /* arg1 */338338+ movl %edx, %edx /* arg3 (zero extension) */339339+340340+cstar_dispatch:341341+ cmpq $(IA32_NR_syscalls-1), %rax342342+ ja 1f343343+344344+ call *ia32_sys_call_table(, %rax, 8)345345+ movq %rax, RAX(%rsp)346346+1:347347+ DISABLE_INTERRUPTS(CLBR_NONE)348348+ TRACE_IRQS_OFF349349+ testl $_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)350350+ jnz sysretl_audit351351+352352+sysretl_from_sys_call:353353+ andl $~TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)354354+ movl RCX(%rsp), %ebp355355+ RESTORE_RSI_RDI_RDX356356+ movl RIP(%rsp), %ecx357357+ movl EFLAGS(%rsp), %r11d358358+ xorq %r10, %r10359359+ xorq %r9, %r9360360+ xorq %r8, %r8361361+ TRACE_IRQS_ON362362+ movl RSP(%rsp), %esp363363+ /*364364+ * 64-bit->32-bit SYSRET restores eip from ecx,365365+ * eflags from r11 (but RF and VM bits are forced to 0),366366+ * cs and ss are loaded from MSRs.367367+ * (Note: 32-bit->32-bit SYSRET is different: since r11368368+ * does not exist, it merely sets eflags.IF=1).369369+ *370370+ * NB: On AMD CPUs with the X86_BUG_SYSRET_SS_ATTRS bug, the ss371371+ * descriptor is not reinitialized. This means that we must372372+ * avoid SYSRET with SS == NULL, which could happen if we schedule,373373+ * exit the kernel, and re-enter using an interrupt vector. (All374374+ * interrupt entries on x86_64 set SS to NULL.) We prevent that375375+ * from happening by reloading SS in __switch_to.376376+ */377377+ USERGS_SYSRET32378378+379379+#ifdef CONFIG_AUDITSYSCALL380380+cstar_auditsys:381381+ auditsys_entry_common382382+ movl %ebp, %r9d /* reload 6th syscall arg */383383+ jmp cstar_dispatch384384+385385+sysretl_audit:386386+ auditsys_exit sysretl_from_sys_call387387+#endif388388+389389+cstar_tracesys:390390+#ifdef CONFIG_AUDITSYSCALL391391+ testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT), ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)392392+ jz cstar_auditsys393393+#endif394394+ SAVE_EXTRA_REGS395395+ xorl %eax, %eax /* Do not leak kernel information */396396+ movq %rax, R11(%rsp)397397+ movq %rax, R10(%rsp)398398+ movq %rax, R9(%rsp)399399+ movq %rax, R8(%rsp)400400+ movq %rsp, %rdi /* &pt_regs -> arg1 */401401+ call syscall_trace_enter402402+403403+ /* Reload arg registers from stack. (see sysenter_tracesys) */404404+ movl RCX(%rsp), %ecx405405+ movl RDX(%rsp), %edx406406+ movl RSI(%rsp), %esi407407+ movl RDI(%rsp), %edi408408+ movl %eax, %eax /* zero extension */409409+410410+ RESTORE_EXTRA_REGS411411+ jmp cstar_do_call412412+END(entry_SYSCALL_compat)413413+414414+ia32_badarg:415415+ ASM_CLAC416416+ movq $-EFAULT, %rax417417+ jmp ia32_sysret418418+419419+ia32_ret_from_sys_call:420420+ xorl %eax, %eax /* Do not leak kernel information */421421+ movq %rax, R11(%rsp)422422+ movq %rax, R10(%rsp)423423+ movq %rax, R9(%rsp)424424+ movq %rax, R8(%rsp)425425+ jmp int_ret_from_sys_call426426+427427+/*428428+ * Emulated IA32 system calls via int 0x80.429429+ *430430+ * Arguments:431431+ * eax system call number432432+ * ebx arg1433433+ * ecx arg2434434+ * edx arg3435435+ * esi arg4436436+ * edi arg5437437+ * ebp arg6 (note: not saved in the stack frame, should not be touched)438438+ *439439+ * Notes:440440+ * Uses the same stack frame as the x86-64 version.441441+ * All registers except eax must be saved (but ptrace may violate that).442442+ * Arguments are zero extended. For system calls that want sign extension and443443+ * take long arguments a wrapper is needed. Most calls can just be called444444+ * directly.445445+ * Assumes it is only called from user space and entered with interrupts off.446446+ */447447+448448+ENTRY(entry_INT80_compat)449449+ /*450450+ * Interrupts are off on entry.451451+ * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON,452452+ * it is too small to ever cause noticeable irq latency.453453+ */454454+ PARAVIRT_ADJUST_EXCEPTION_FRAME455455+ SWAPGS456456+ ENABLE_INTERRUPTS(CLBR_NONE)457457+458458+ /* Zero-extending 32-bit regs, do not remove */459459+ movl %eax, %eax460460+461461+ /* Construct struct pt_regs on stack (iret frame is already on stack) */462462+ pushq %rax /* pt_regs->orig_ax */463463+ pushq %rdi /* pt_regs->di */464464+ pushq %rsi /* pt_regs->si */465465+ pushq %rdx /* pt_regs->dx */466466+ pushq %rcx /* pt_regs->cx */467467+ pushq $-ENOSYS /* pt_regs->ax */468468+ pushq $0 /* pt_regs->r8 */469469+ pushq $0 /* pt_regs->r9 */470470+ pushq $0 /* pt_regs->r10 */471471+ pushq $0 /* pt_regs->r11 */472472+ cld473473+ sub $(6*8), %rsp /* pt_regs->bp, bx, r12-15 not saved */474474+475475+ orl $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)476476+ testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)477477+ jnz ia32_tracesys478478+479479+ia32_do_call:480480+ /* 32-bit syscall -> 64-bit C ABI argument conversion */481481+ movl %edi, %r8d /* arg5 */482482+ movl %ebp, %r9d /* arg6 */483483+ xchg %ecx, %esi /* rsi:arg2, rcx:arg4 */484484+ movl %ebx, %edi /* arg1 */485485+ movl %edx, %edx /* arg3 (zero extension) */486486+ cmpq $(IA32_NR_syscalls-1), %rax487487+ ja 1f488488+489489+ call *ia32_sys_call_table(, %rax, 8) /* RIP relative */490490+491491+ia32_sysret:492492+ movq %rax, RAX(%rsp)493493+1:494494+ jmp int_ret_from_sys_call495495+496496+ia32_tracesys:497497+ SAVE_EXTRA_REGS498498+ movq %rsp, %rdi /* &pt_regs -> arg1 */499499+ call syscall_trace_enter500500+ /*501501+ * Reload arg registers from stack in case ptrace changed them.502502+ * Don't reload %eax because syscall_trace_enter() returned503503+ * the %rax value we should see. But do truncate it to 32 bits.504504+ * If it's -1 to make us punt the syscall, then (u32)-1 is still505505+ * an appropriately invalid value.506506+ */507507+ movl RCX(%rsp), %ecx508508+ movl RDX(%rsp), %edx509509+ movl RSI(%rsp), %esi510510+ movl RDI(%rsp), %edi511511+ movl %eax, %eax /* zero extension */512512+ RESTORE_EXTRA_REGS513513+ jmp ia32_do_call514514+END(entry_INT80_compat)515515+516516+ .macro PTREGSCALL label, func517517+ ALIGN518518+GLOBAL(\label)519519+ leaq \func(%rip), %rax520520+ jmp ia32_ptregs_common521521+ .endm522522+523523+ PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn524524+ PTREGSCALL stub32_sigreturn, sys32_sigreturn525525+ PTREGSCALL stub32_fork, sys_fork526526+ PTREGSCALL stub32_vfork, sys_vfork527527+528528+ ALIGN529529+GLOBAL(stub32_clone)530530+ leaq sys_clone(%rip), %rax531531+ /*532532+ * The 32-bit clone ABI is: clone(..., int tls_val, int *child_tidptr).533533+ * The 64-bit clone ABI is: clone(..., int *child_tidptr, int tls_val).534534+ *535535+ * The native 64-bit kernel's sys_clone() implements the latter,536536+ * so we need to swap arguments here before calling it:537537+ */538538+ xchg %r8, %rcx539539+ jmp ia32_ptregs_common540540+541541+ ALIGN542542+ia32_ptregs_common:543543+ SAVE_EXTRA_REGS 8544544+ call *%rax545545+ RESTORE_EXTRA_REGS 8546546+ ret547547+END(ia32_ptregs_common)
+7
arch/x86/entry/vsyscall/Makefile
···11+#22+# Makefile for the x86 low level vsyscall code33+#44+obj-y := vsyscall_gtod.o55+66+obj-$(CONFIG_X86_VSYSCALL_EMULATION) += vsyscall_64.o vsyscall_emu_64.o77+
+1-1
arch/x86/ia32/Makefile
···22# Makefile for the ia32 kernel emulation subsystem.33#4455-obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_signal.o55+obj-$(CONFIG_IA32_EMULATION) := sys_ia32.o ia32_signal.o6677obj-$(CONFIG_IA32_AOUT) += ia32_aout.o88
-591
arch/x86/ia32/ia32entry.S
···11-/*22- * Compatibility mode system call entry point for x86-64. 33- * 44- * Copyright 2000-2002 Andi Kleen, SuSE Labs.55- */ 66-77-#include <asm/dwarf2.h>88-#include <asm/calling.h>99-#include <asm/asm-offsets.h>1010-#include <asm/current.h>1111-#include <asm/errno.h>1212-#include <asm/ia32_unistd.h> 1313-#include <asm/thread_info.h> 1414-#include <asm/segment.h>1515-#include <asm/irqflags.h>1616-#include <asm/asm.h>1717-#include <asm/smap.h>1818-#include <linux/linkage.h>1919-#include <linux/err.h>2020-2121-/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */2222-#include <linux/elf-em.h>2323-#define AUDIT_ARCH_I386 (EM_386|__AUDIT_ARCH_LE)2424-#define __AUDIT_ARCH_LE 0x400000002525-2626-#ifndef CONFIG_AUDITSYSCALL2727-#define sysexit_audit ia32_ret_from_sys_call2828-#define sysretl_audit ia32_ret_from_sys_call2929-#endif3030-3131- .section .entry.text, "ax"3232-3333- /* clobbers %rax */3434- .macro CLEAR_RREGS _r9=rax3535- xorl %eax,%eax3636- movq %rax,R11(%rsp)3737- movq %rax,R10(%rsp)3838- movq %\_r9,R9(%rsp)3939- movq %rax,R8(%rsp)4040- .endm4141-4242- /*4343- * Reload arg registers from stack in case ptrace changed them.4444- * We don't reload %eax because syscall_trace_enter() returned4545- * the %rax value we should see. Instead, we just truncate that4646- * value to 32 bits again as we did on entry from user mode.4747- * If it's a new value set by user_regset during entry tracing,4848- * this matches the normal truncation of the user-mode value.4949- * If it's -1 to make us punt the syscall, then (u32)-1 is still5050- * an appropriately invalid value.5151- */5252- .macro LOAD_ARGS32 _r9=05353- .if \_r95454- movl R9(%rsp),%r9d5555- .endif5656- movl RCX(%rsp),%ecx5757- movl RDX(%rsp),%edx5858- movl RSI(%rsp),%esi5959- movl RDI(%rsp),%edi6060- movl %eax,%eax /* zero extension */6161- .endm6262-6363- .macro CFI_STARTPROC32 simple6464- CFI_STARTPROC \simple6565- CFI_UNDEFINED r86666- CFI_UNDEFINED r96767- CFI_UNDEFINED r106868- CFI_UNDEFINED r116969- CFI_UNDEFINED r127070- CFI_UNDEFINED r137171- CFI_UNDEFINED r147272- CFI_UNDEFINED r157373- .endm7474-7575-#ifdef CONFIG_PARAVIRT7676-ENTRY(native_usergs_sysret32)7777- swapgs7878- sysretl7979-ENDPROC(native_usergs_sysret32)8080-#endif8181-8282-/*8383- * 32bit SYSENTER instruction entry.8484- *8585- * SYSENTER loads ss, rsp, cs, and rip from previously programmed MSRs.8686- * IF and VM in rflags are cleared (IOW: interrupts are off).8787- * SYSENTER does not save anything on the stack,8888- * and does not save old rip (!!!) and rflags.8989- *9090- * Arguments:9191- * eax system call number9292- * ebx arg19393- * ecx arg29494- * edx arg39595- * esi arg49696- * edi arg59797- * ebp user stack9898- * 0(%ebp) arg69999- *100100- * This is purely a fast path. For anything complicated we use the int 0x80101101- * path below. We set up a complete hardware stack frame to share code102102- * with the int 0x80 path.103103- */104104-ENTRY(ia32_sysenter_target)105105- CFI_STARTPROC32 simple106106- CFI_SIGNAL_FRAME107107- CFI_DEF_CFA rsp,0108108- CFI_REGISTER rsp,rbp109109-110110- /*111111- * Interrupts are off on entry.112112- * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON,113113- * it is too small to ever cause noticeable irq latency.114114- */115115- SWAPGS_UNSAFE_STACK116116- movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp117117- ENABLE_INTERRUPTS(CLBR_NONE)118118-119119- /* Zero-extending 32-bit regs, do not remove */120120- movl %ebp, %ebp121121- movl %eax, %eax122122-123123- movl ASM_THREAD_INFO(TI_sysenter_return, %rsp, 0), %r10d124124- CFI_REGISTER rip,r10125125-126126- /* Construct struct pt_regs on stack */127127- pushq_cfi $__USER32_DS /* pt_regs->ss */128128- pushq_cfi %rbp /* pt_regs->sp */129129- CFI_REL_OFFSET rsp,0130130- pushfq_cfi /* pt_regs->flags */131131- pushq_cfi $__USER32_CS /* pt_regs->cs */132132- pushq_cfi %r10 /* pt_regs->ip = thread_info->sysenter_return */133133- CFI_REL_OFFSET rip,0134134- pushq_cfi_reg rax /* pt_regs->orig_ax */135135- pushq_cfi_reg rdi /* pt_regs->di */136136- pushq_cfi_reg rsi /* pt_regs->si */137137- pushq_cfi_reg rdx /* pt_regs->dx */138138- pushq_cfi_reg rcx /* pt_regs->cx */139139- pushq_cfi $-ENOSYS /* pt_regs->ax */140140- cld141141- sub $(10*8),%rsp /* pt_regs->r8-11,bp,bx,r12-15 not saved */142142- CFI_ADJUST_CFA_OFFSET 10*8143143-144144- /*145145- * no need to do an access_ok check here because rbp has been146146- * 32bit zero extended147147- */148148- ASM_STAC149149-1: movl (%rbp),%ebp150150- _ASM_EXTABLE(1b,ia32_badarg)151151- ASM_CLAC152152-153153- /*154154- * Sysenter doesn't filter flags, so we need to clear NT155155- * ourselves. To save a few cycles, we can check whether156156- * NT was set instead of doing an unconditional popfq.157157- */158158- testl $X86_EFLAGS_NT,EFLAGS(%rsp)159159- jnz sysenter_fix_flags160160-sysenter_flags_fixed:161161-162162- orl $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)163163- testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)164164- CFI_REMEMBER_STATE165165- jnz sysenter_tracesys166166-sysenter_do_call:167167- /* 32bit syscall -> 64bit C ABI argument conversion */168168- movl %edi,%r8d /* arg5 */169169- movl %ebp,%r9d /* arg6 */170170- xchg %ecx,%esi /* rsi:arg2, rcx:arg4 */171171- movl %ebx,%edi /* arg1 */172172- movl %edx,%edx /* arg3 (zero extension) */173173-sysenter_dispatch:174174- cmpq $(IA32_NR_syscalls-1),%rax175175- ja 1f176176- call *ia32_sys_call_table(,%rax,8)177177- movq %rax,RAX(%rsp)178178-1:179179- DISABLE_INTERRUPTS(CLBR_NONE)180180- TRACE_IRQS_OFF181181- testl $_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)182182- jnz sysexit_audit183183-sysexit_from_sys_call:184184- /*185185- * NB: SYSEXIT is not obviously safe for 64-bit kernels -- an186186- * NMI between STI and SYSEXIT has poorly specified behavior,187187- * and and NMI followed by an IRQ with usergs is fatal. So188188- * we just pretend we're using SYSEXIT but we really use189189- * SYSRETL instead.190190- *191191- * This code path is still called 'sysexit' because it pairs192192- * with 'sysenter' and it uses the SYSENTER calling convention.193193- */194194- andl $~TS_COMPAT,ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)195195- movl RIP(%rsp),%ecx /* User %eip */196196- CFI_REGISTER rip,rcx197197- RESTORE_RSI_RDI198198- xorl %edx,%edx /* avoid info leaks */199199- xorq %r8,%r8200200- xorq %r9,%r9201201- xorq %r10,%r10202202- movl EFLAGS(%rsp),%r11d /* User eflags */203203- /*CFI_RESTORE rflags*/204204- TRACE_IRQS_ON205205-206206- /*207207- * SYSRETL works even on Intel CPUs. Use it in preference to SYSEXIT,208208- * since it avoids a dicey window with interrupts enabled.209209- */210210- movl RSP(%rsp),%esp211211-212212- /*213213- * USERGS_SYSRET32 does:214214- * gsbase = user's gs base215215- * eip = ecx216216- * rflags = r11217217- * cs = __USER32_CS218218- * ss = __USER_DS219219- *220220- * The prologue set RIP(%rsp) to VDSO32_SYSENTER_RETURN, which does:221221- *222222- * pop %ebp223223- * pop %edx224224- * pop %ecx225225- *226226- * Therefore, we invoke SYSRETL with EDX and R8-R10 zeroed to227227- * avoid info leaks. R11 ends up with VDSO32_SYSENTER_RETURN's228228- * address (already known to user code), and R12-R15 are229229- * callee-saved and therefore don't contain any interesting230230- * kernel data.231231- */232232- USERGS_SYSRET32233233-234234- CFI_RESTORE_STATE235235-236236-#ifdef CONFIG_AUDITSYSCALL237237- .macro auditsys_entry_common238238- movl %esi,%r8d /* 5th arg: 4th syscall arg */239239- movl %ecx,%r9d /*swap with edx*/240240- movl %edx,%ecx /* 4th arg: 3rd syscall arg */241241- movl %r9d,%edx /* 3rd arg: 2nd syscall arg */242242- movl %ebx,%esi /* 2nd arg: 1st syscall arg */243243- movl %eax,%edi /* 1st arg: syscall number */244244- call __audit_syscall_entry245245- movl ORIG_RAX(%rsp),%eax /* reload syscall number */246246- movl %ebx,%edi /* reload 1st syscall arg */247247- movl RCX(%rsp),%esi /* reload 2nd syscall arg */248248- movl RDX(%rsp),%edx /* reload 3rd syscall arg */249249- movl RSI(%rsp),%ecx /* reload 4th syscall arg */250250- movl RDI(%rsp),%r8d /* reload 5th syscall arg */251251- .endm252252-253253- .macro auditsys_exit exit254254- testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)255255- jnz ia32_ret_from_sys_call256256- TRACE_IRQS_ON257257- ENABLE_INTERRUPTS(CLBR_NONE)258258- movl %eax,%esi /* second arg, syscall return value */259259- cmpl $-MAX_ERRNO,%eax /* is it an error ? */260260- jbe 1f261261- movslq %eax, %rsi /* if error sign extend to 64 bits */262262-1: setbe %al /* 1 if error, 0 if not */263263- movzbl %al,%edi /* zero-extend that into %edi */264264- call __audit_syscall_exit265265- movq RAX(%rsp),%rax /* reload syscall return value */266266- movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),%edi267267- DISABLE_INTERRUPTS(CLBR_NONE)268268- TRACE_IRQS_OFF269269- testl %edi, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)270270- jz \exit271271- CLEAR_RREGS272272- jmp int_with_check273273- .endm274274-275275-sysenter_auditsys:276276- auditsys_entry_common277277- movl %ebp,%r9d /* reload 6th syscall arg */278278- jmp sysenter_dispatch279279-280280-sysexit_audit:281281- auditsys_exit sysexit_from_sys_call282282-#endif283283-284284-sysenter_fix_flags:285285- pushq_cfi $(X86_EFLAGS_IF|X86_EFLAGS_FIXED)286286- popfq_cfi287287- jmp sysenter_flags_fixed288288-289289-sysenter_tracesys:290290-#ifdef CONFIG_AUDITSYSCALL291291- testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT), ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)292292- jz sysenter_auditsys293293-#endif294294- SAVE_EXTRA_REGS295295- CLEAR_RREGS296296- movq %rsp,%rdi /* &pt_regs -> arg1 */297297- call syscall_trace_enter298298- LOAD_ARGS32 /* reload args from stack in case ptrace changed it */299299- RESTORE_EXTRA_REGS300300- jmp sysenter_do_call301301- CFI_ENDPROC302302-ENDPROC(ia32_sysenter_target)303303-304304-/*305305- * 32bit SYSCALL instruction entry.306306- *307307- * 32bit SYSCALL saves rip to rcx, clears rflags.RF, then saves rflags to r11,308308- * then loads new ss, cs, and rip from previously programmed MSRs.309309- * rflags gets masked by a value from another MSR (so CLD and CLAC310310- * are not needed). SYSCALL does not save anything on the stack311311- * and does not change rsp.312312- *313313- * Note: rflags saving+masking-with-MSR happens only in Long mode314314- * (in legacy 32bit mode, IF, RF and VM bits are cleared and that's it).315315- * Don't get confused: rflags saving+masking depends on Long Mode Active bit316316- * (EFER.LMA=1), NOT on bitness of userspace where SYSCALL executes317317- * or target CS descriptor's L bit (SYSCALL does not read segment descriptors).318318- *319319- * Arguments:320320- * eax system call number321321- * ecx return address322322- * ebx arg1323323- * ebp arg2 (note: not saved in the stack frame, should not be touched)324324- * edx arg3325325- * esi arg4326326- * edi arg5327327- * esp user stack328328- * 0(%esp) arg6329329- *330330- * This is purely a fast path. For anything complicated we use the int 0x80331331- * path below. We set up a complete hardware stack frame to share code332332- * with the int 0x80 path.333333- */334334-ENTRY(ia32_cstar_target)335335- CFI_STARTPROC32 simple336336- CFI_SIGNAL_FRAME337337- CFI_DEF_CFA rsp,0338338- CFI_REGISTER rip,rcx339339- /*CFI_REGISTER rflags,r11*/340340-341341- /*342342- * Interrupts are off on entry.343343- * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON,344344- * it is too small to ever cause noticeable irq latency.345345- */346346- SWAPGS_UNSAFE_STACK347347- movl %esp,%r8d348348- CFI_REGISTER rsp,r8349349- movq PER_CPU_VAR(cpu_current_top_of_stack),%rsp350350- ENABLE_INTERRUPTS(CLBR_NONE)351351-352352- /* Zero-extending 32-bit regs, do not remove */353353- movl %eax,%eax354354-355355- /* Construct struct pt_regs on stack */356356- pushq_cfi $__USER32_DS /* pt_regs->ss */357357- pushq_cfi %r8 /* pt_regs->sp */358358- CFI_REL_OFFSET rsp,0359359- pushq_cfi %r11 /* pt_regs->flags */360360- pushq_cfi $__USER32_CS /* pt_regs->cs */361361- pushq_cfi %rcx /* pt_regs->ip */362362- CFI_REL_OFFSET rip,0363363- pushq_cfi_reg rax /* pt_regs->orig_ax */364364- pushq_cfi_reg rdi /* pt_regs->di */365365- pushq_cfi_reg rsi /* pt_regs->si */366366- pushq_cfi_reg rdx /* pt_regs->dx */367367- pushq_cfi_reg rbp /* pt_regs->cx */368368- movl %ebp,%ecx369369- pushq_cfi $-ENOSYS /* pt_regs->ax */370370- sub $(10*8),%rsp /* pt_regs->r8-11,bp,bx,r12-15 not saved */371371- CFI_ADJUST_CFA_OFFSET 10*8372372-373373- /*374374- * no need to do an access_ok check here because r8 has been375375- * 32bit zero extended376376- */377377- ASM_STAC378378-1: movl (%r8),%r9d379379- _ASM_EXTABLE(1b,ia32_badarg)380380- ASM_CLAC381381- orl $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)382382- testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)383383- CFI_REMEMBER_STATE384384- jnz cstar_tracesys385385-cstar_do_call:386386- /* 32bit syscall -> 64bit C ABI argument conversion */387387- movl %edi,%r8d /* arg5 */388388- /* r9 already loaded */ /* arg6 */389389- xchg %ecx,%esi /* rsi:arg2, rcx:arg4 */390390- movl %ebx,%edi /* arg1 */391391- movl %edx,%edx /* arg3 (zero extension) */392392-cstar_dispatch:393393- cmpq $(IA32_NR_syscalls-1),%rax394394- ja 1f395395- call *ia32_sys_call_table(,%rax,8)396396- movq %rax,RAX(%rsp)397397-1:398398- DISABLE_INTERRUPTS(CLBR_NONE)399399- TRACE_IRQS_OFF400400- testl $_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)401401- jnz sysretl_audit402402-sysretl_from_sys_call:403403- andl $~TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)404404- RESTORE_RSI_RDI_RDX405405- movl RIP(%rsp),%ecx406406- CFI_REGISTER rip,rcx407407- movl EFLAGS(%rsp),%r11d408408- /*CFI_REGISTER rflags,r11*/409409- xorq %r10,%r10410410- xorq %r9,%r9411411- xorq %r8,%r8412412- TRACE_IRQS_ON413413- movl RSP(%rsp),%esp414414- CFI_RESTORE rsp415415- /*416416- * 64bit->32bit SYSRET restores eip from ecx,417417- * eflags from r11 (but RF and VM bits are forced to 0),418418- * cs and ss are loaded from MSRs.419419- * (Note: 32bit->32bit SYSRET is different: since r11420420- * does not exist, it merely sets eflags.IF=1).421421- *422422- * NB: On AMD CPUs with the X86_BUG_SYSRET_SS_ATTRS bug, the ss423423- * descriptor is not reinitialized. This means that we must424424- * avoid SYSRET with SS == NULL, which could happen if we schedule,425425- * exit the kernel, and re-enter using an interrupt vector. (All426426- * interrupt entries on x86_64 set SS to NULL.) We prevent that427427- * from happening by reloading SS in __switch_to.428428- */429429- USERGS_SYSRET32430430-431431-#ifdef CONFIG_AUDITSYSCALL432432-cstar_auditsys:433433- CFI_RESTORE_STATE434434- movl %r9d,R9(%rsp) /* register to be clobbered by call */435435- auditsys_entry_common436436- movl R9(%rsp),%r9d /* reload 6th syscall arg */437437- jmp cstar_dispatch438438-439439-sysretl_audit:440440- auditsys_exit sysretl_from_sys_call441441-#endif442442-443443-cstar_tracesys:444444-#ifdef CONFIG_AUDITSYSCALL445445- testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT), ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)446446- jz cstar_auditsys447447-#endif448448- xchgl %r9d,%ebp449449- SAVE_EXTRA_REGS450450- CLEAR_RREGS r9451451- movq %rsp,%rdi /* &pt_regs -> arg1 */452452- call syscall_trace_enter453453- LOAD_ARGS32 1 /* reload args from stack in case ptrace changed it */454454- RESTORE_EXTRA_REGS455455- xchgl %ebp,%r9d456456- jmp cstar_do_call457457-END(ia32_cstar_target)458458-459459-ia32_badarg:460460- ASM_CLAC461461- movq $-EFAULT,%rax462462- jmp ia32_sysret463463- CFI_ENDPROC464464-465465-/*466466- * Emulated IA32 system calls via int 0x80.467467- *468468- * Arguments:469469- * eax system call number470470- * ebx arg1471471- * ecx arg2472472- * edx arg3473473- * esi arg4474474- * edi arg5475475- * ebp arg6 (note: not saved in the stack frame, should not be touched)476476- *477477- * Notes:478478- * Uses the same stack frame as the x86-64 version.479479- * All registers except eax must be saved (but ptrace may violate that).480480- * Arguments are zero extended. For system calls that want sign extension and481481- * take long arguments a wrapper is needed. Most calls can just be called482482- * directly.483483- * Assumes it is only called from user space and entered with interrupts off.484484- */485485-486486-ENTRY(ia32_syscall)487487- CFI_STARTPROC32 simple488488- CFI_SIGNAL_FRAME489489- CFI_DEF_CFA rsp,5*8490490- /*CFI_REL_OFFSET ss,4*8 */491491- CFI_REL_OFFSET rsp,3*8492492- /*CFI_REL_OFFSET rflags,2*8 */493493- /*CFI_REL_OFFSET cs,1*8 */494494- CFI_REL_OFFSET rip,0*8495495-496496- /*497497- * Interrupts are off on entry.498498- * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON,499499- * it is too small to ever cause noticeable irq latency.500500- */501501- PARAVIRT_ADJUST_EXCEPTION_FRAME502502- SWAPGS503503- ENABLE_INTERRUPTS(CLBR_NONE)504504-505505- /* Zero-extending 32-bit regs, do not remove */506506- movl %eax,%eax507507-508508- /* Construct struct pt_regs on stack (iret frame is already on stack) */509509- pushq_cfi_reg rax /* pt_regs->orig_ax */510510- pushq_cfi_reg rdi /* pt_regs->di */511511- pushq_cfi_reg rsi /* pt_regs->si */512512- pushq_cfi_reg rdx /* pt_regs->dx */513513- pushq_cfi_reg rcx /* pt_regs->cx */514514- pushq_cfi $-ENOSYS /* pt_regs->ax */515515- cld516516- sub $(10*8),%rsp /* pt_regs->r8-11,bp,bx,r12-15 not saved */517517- CFI_ADJUST_CFA_OFFSET 10*8518518-519519- orl $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)520520- testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)521521- jnz ia32_tracesys522522-ia32_do_call:523523- /* 32bit syscall -> 64bit C ABI argument conversion */524524- movl %edi,%r8d /* arg5 */525525- movl %ebp,%r9d /* arg6 */526526- xchg %ecx,%esi /* rsi:arg2, rcx:arg4 */527527- movl %ebx,%edi /* arg1 */528528- movl %edx,%edx /* arg3 (zero extension) */529529- cmpq $(IA32_NR_syscalls-1),%rax530530- ja 1f531531- call *ia32_sys_call_table(,%rax,8) # xxx: rip relative532532-ia32_sysret:533533- movq %rax,RAX(%rsp)534534-1:535535-ia32_ret_from_sys_call:536536- CLEAR_RREGS537537- jmp int_ret_from_sys_call538538-539539-ia32_tracesys:540540- SAVE_EXTRA_REGS541541- CLEAR_RREGS542542- movq %rsp,%rdi /* &pt_regs -> arg1 */543543- call syscall_trace_enter544544- LOAD_ARGS32 /* reload args from stack in case ptrace changed it */545545- RESTORE_EXTRA_REGS546546- jmp ia32_do_call547547- CFI_ENDPROC548548-END(ia32_syscall)549549-550550- .macro PTREGSCALL label, func551551- ALIGN552552-GLOBAL(\label)553553- leaq \func(%rip),%rax554554- jmp ia32_ptregs_common 555555- .endm556556-557557- CFI_STARTPROC32558558-559559- PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn560560- PTREGSCALL stub32_sigreturn, sys32_sigreturn561561- PTREGSCALL stub32_fork, sys_fork562562- PTREGSCALL stub32_vfork, sys_vfork563563-564564- ALIGN565565-GLOBAL(stub32_clone)566566- leaq sys_clone(%rip),%rax567567- mov %r8, %rcx568568- jmp ia32_ptregs_common 569569-570570- ALIGN571571-ia32_ptregs_common:572572- CFI_ENDPROC573573- CFI_STARTPROC32 simple574574- CFI_SIGNAL_FRAME575575- CFI_DEF_CFA rsp,SIZEOF_PTREGS576576- CFI_REL_OFFSET rax,RAX577577- CFI_REL_OFFSET rcx,RCX578578- CFI_REL_OFFSET rdx,RDX579579- CFI_REL_OFFSET rsi,RSI580580- CFI_REL_OFFSET rdi,RDI581581- CFI_REL_OFFSET rip,RIP582582-/* CFI_REL_OFFSET cs,CS*/583583-/* CFI_REL_OFFSET rflags,EFLAGS*/584584- CFI_REL_OFFSET rsp,RSP585585-/* CFI_REL_OFFSET ss,SS*/586586- SAVE_EXTRA_REGS 8587587- call *%rax588588- RESTORE_EXTRA_REGS 8589589- ret590590- CFI_ENDPROC591591-END(ia32_ptregs_common)
···11-#ifndef _ASM_X86_DWARF2_H22-#define _ASM_X86_DWARF2_H33-44-#ifndef __ASSEMBLY__55-#warning "asm/dwarf2.h should be only included in pure assembly files"66-#endif77-88-/*99- * Macros for dwarf2 CFI unwind table entries.1010- * See "as.info" for details on these pseudo ops. Unfortunately1111- * they are only supported in very new binutils, so define them1212- * away for older version.1313- */1414-1515-#ifdef CONFIG_AS_CFI1616-1717-#define CFI_STARTPROC .cfi_startproc1818-#define CFI_ENDPROC .cfi_endproc1919-#define CFI_DEF_CFA .cfi_def_cfa2020-#define CFI_DEF_CFA_REGISTER .cfi_def_cfa_register2121-#define CFI_DEF_CFA_OFFSET .cfi_def_cfa_offset2222-#define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset2323-#define CFI_OFFSET .cfi_offset2424-#define CFI_REL_OFFSET .cfi_rel_offset2525-#define CFI_REGISTER .cfi_register2626-#define CFI_RESTORE .cfi_restore2727-#define CFI_REMEMBER_STATE .cfi_remember_state2828-#define CFI_RESTORE_STATE .cfi_restore_state2929-#define CFI_UNDEFINED .cfi_undefined3030-#define CFI_ESCAPE .cfi_escape3131-3232-#ifdef CONFIG_AS_CFI_SIGNAL_FRAME3333-#define CFI_SIGNAL_FRAME .cfi_signal_frame3434-#else3535-#define CFI_SIGNAL_FRAME3636-#endif3737-3838-#if defined(CONFIG_AS_CFI_SECTIONS) && defined(__ASSEMBLY__)3939- /*4040- * Emit CFI data in .debug_frame sections, not .eh_frame sections.4141- * The latter we currently just discard since we don't do DWARF4242- * unwinding at runtime. So only the offline DWARF information is4343- * useful to anyone. Note we should not use this directive if this4444- * file is used in the vDSO assembly, or if vmlinux.lds.S gets4545- * changed so it doesn't discard .eh_frame.4646- */4747- .cfi_sections .debug_frame4848-#endif4949-5050-#else5151-5252-/*5353- * Due to the structure of pre-exisiting code, don't use assembler line5454- * comment character # to ignore the arguments. Instead, use a dummy macro.5555- */5656-.macro cfi_ignore a=0, b=0, c=0, d=05757-.endm5858-5959-#define CFI_STARTPROC cfi_ignore6060-#define CFI_ENDPROC cfi_ignore6161-#define CFI_DEF_CFA cfi_ignore6262-#define CFI_DEF_CFA_REGISTER cfi_ignore6363-#define CFI_DEF_CFA_OFFSET cfi_ignore6464-#define CFI_ADJUST_CFA_OFFSET cfi_ignore6565-#define CFI_OFFSET cfi_ignore6666-#define CFI_REL_OFFSET cfi_ignore6767-#define CFI_REGISTER cfi_ignore6868-#define CFI_RESTORE cfi_ignore6969-#define CFI_REMEMBER_STATE cfi_ignore7070-#define CFI_RESTORE_STATE cfi_ignore7171-#define CFI_UNDEFINED cfi_ignore7272-#define CFI_ESCAPE cfi_ignore7373-#define CFI_SIGNAL_FRAME cfi_ignore7474-7575-#endif7676-7777-/*7878- * An attempt to make CFI annotations more or less7979- * correct and shorter. It is implied that you know8080- * what you're doing if you use them.8181- */8282-#ifdef __ASSEMBLY__8383-#ifdef CONFIG_X86_648484- .macro pushq_cfi reg8585- pushq \reg8686- CFI_ADJUST_CFA_OFFSET 88787- .endm8888-8989- .macro pushq_cfi_reg reg9090- pushq %\reg9191- CFI_ADJUST_CFA_OFFSET 89292- CFI_REL_OFFSET \reg, 09393- .endm9494-9595- .macro popq_cfi reg9696- popq \reg9797- CFI_ADJUST_CFA_OFFSET -89898- .endm9999-100100- .macro popq_cfi_reg reg101101- popq %\reg102102- CFI_ADJUST_CFA_OFFSET -8103103- CFI_RESTORE \reg104104- .endm105105-106106- .macro pushfq_cfi107107- pushfq108108- CFI_ADJUST_CFA_OFFSET 8109109- .endm110110-111111- .macro popfq_cfi112112- popfq113113- CFI_ADJUST_CFA_OFFSET -8114114- .endm115115-116116- .macro movq_cfi reg offset=0117117- movq %\reg, \offset(%rsp)118118- CFI_REL_OFFSET \reg, \offset119119- .endm120120-121121- .macro movq_cfi_restore offset reg122122- movq \offset(%rsp), %\reg123123- CFI_RESTORE \reg124124- .endm125125-#else /*!CONFIG_X86_64*/126126- .macro pushl_cfi reg127127- pushl \reg128128- CFI_ADJUST_CFA_OFFSET 4129129- .endm130130-131131- .macro pushl_cfi_reg reg132132- pushl %\reg133133- CFI_ADJUST_CFA_OFFSET 4134134- CFI_REL_OFFSET \reg, 0135135- .endm136136-137137- .macro popl_cfi reg138138- popl \reg139139- CFI_ADJUST_CFA_OFFSET -4140140- .endm141141-142142- .macro popl_cfi_reg reg143143- popl %\reg144144- CFI_ADJUST_CFA_OFFSET -4145145- CFI_RESTORE \reg146146- .endm147147-148148- .macro pushfl_cfi149149- pushfl150150- CFI_ADJUST_CFA_OFFSET 4151151- .endm152152-153153- .macro popfl_cfi154154- popfl155155- CFI_ADJUST_CFA_OFFSET -4156156- .endm157157-158158- .macro movl_cfi reg offset=0159159- movl %\reg, \offset(%esp)160160- CFI_REL_OFFSET \reg, \offset161161- .endm162162-163163- .macro movl_cfi_restore offset reg164164- movl \offset(%esp), %\reg165165- CFI_RESTORE \reg166166- .endm167167-#endif /*!CONFIG_X86_64*/168168-#endif /*__ASSEMBLY__*/169169-170170-#endif /* _ASM_X86_DWARF2_H */
+2-5
arch/x86/include/asm/frame.h
···11#ifdef __ASSEMBLY__2233#include <asm/asm.h>44-#include <asm/dwarf2.h>5465/* The annotation hides the frame from the unwinder and makes it look76 like a ordinary ebp save/restore. This avoids some special cases for87 frame pointer later */98#ifdef CONFIG_FRAME_POINTER109 .macro FRAME1111- __ASM_SIZE(push,_cfi) %__ASM_REG(bp)1212- CFI_REL_OFFSET __ASM_REG(bp), 01010+ __ASM_SIZE(push,) %__ASM_REG(bp)1311 __ASM_SIZE(mov) %__ASM_REG(sp), %__ASM_REG(bp)1412 .endm1513 .macro ENDFRAME1616- __ASM_SIZE(pop,_cfi) %__ASM_REG(bp)1717- CFI_RESTORE __ASM_REG(bp)1414+ __ASM_SIZE(pop,) %__ASM_REG(bp)1815 .endm1916#else2017 .macro FRAME
···231231#define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES* 8)232232233233#ifdef __KERNEL__234234+235235+/*236236+ * early_idt_handler_array is an array of entry points referenced in the237237+ * early IDT. For simplicity, it's a real array with one entry point238238+ * every nine bytes. That leaves room for an optional 'push $0' if the239239+ * vector has no error code (two bytes), a 'push $vector_number' (two240240+ * bytes), and a jump to the common entry code (up to five bytes).241241+ */242242+#define EARLY_IDT_HANDLER_SIZE 9243243+234244#ifndef __ASSEMBLY__235245236236-extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][2+2+5];246246+extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE];237247#ifdef CONFIG_TRACING238238-# define trace_early_idt_handlers early_idt_handlers248248+# define trace_early_idt_handler_array early_idt_handler_array239249#endif240250241251/*
···10261026 (unsigned long)tss + offsetofend(struct tss_struct, SYSENTER_stack),10271027 0);1028102810291029- wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long)ia32_sysenter_target, 0);10291029+ wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long)entry_SYSENTER_32, 0);1030103010311031out:10321032 put_cpu();···12041204 * set CS/DS but only a 32bit target. LSTAR sets the 64bit rip.12051205 */12061206 wrmsrl(MSR_STAR, ((u64)__USER32_CS)<<48 | ((u64)__KERNEL_CS)<<32);12071207- wrmsrl(MSR_LSTAR, system_call);12071207+ wrmsrl(MSR_LSTAR, entry_SYSCALL_64);1208120812091209#ifdef CONFIG_IA32_EMULATION12101210- wrmsrl(MSR_CSTAR, ia32_cstar_target);12101210+ wrmsrl(MSR_CSTAR, entry_SYSCALL_compat);12111211 /*12121212 * This only works on Intel CPUs.12131213 * On AMD CPUs these MSRs are 32-bit, CPU truncates MSR_IA32_SYSENTER_EIP.···12161216 */12171217 wrmsrl_safe(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS);12181218 wrmsrl_safe(MSR_IA32_SYSENTER_ESP, 0ULL);12191219- wrmsrl_safe(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target);12191219+ wrmsrl_safe(MSR_IA32_SYSENTER_EIP, (u64)entry_SYSENTER_compat);12201220#else12211221 wrmsrl(MSR_CSTAR, ignore_sysret);12221222 wrmsrl_safe(MSR_IA32_SYSENTER_CS, (u64)GDT_ENTRY_INVALID_SEG);
-1401
arch/x86/kernel/entry_32.S
···11-/*22- *33- * Copyright (C) 1991, 1992 Linus Torvalds44- */55-66-/*77- * entry.S contains the system-call and fault low-level handling routines.88- * This also contains the timer-interrupt handler, as well as all interrupts99- * and faults that can result in a task-switch.1010- *1111- * NOTE: This code handles signal-recognition, which happens every time1212- * after a timer-interrupt and after each system call.1313- *1414- * I changed all the .align's to 4 (16 byte alignment), as that's faster1515- * on a 486.1616- *1717- * Stack layout in 'syscall_exit':1818- * ptrace needs to have all regs on the stack.1919- * if the order here is changed, it needs to be2020- * updated in fork.c:copy_process, signal.c:do_signal,2121- * ptrace.c and ptrace.h2222- *2323- * 0(%esp) - %ebx2424- * 4(%esp) - %ecx2525- * 8(%esp) - %edx2626- * C(%esp) - %esi2727- * 10(%esp) - %edi2828- * 14(%esp) - %ebp2929- * 18(%esp) - %eax3030- * 1C(%esp) - %ds3131- * 20(%esp) - %es3232- * 24(%esp) - %fs3333- * 28(%esp) - %gs saved iff !CONFIG_X86_32_LAZY_GS3434- * 2C(%esp) - orig_eax3535- * 30(%esp) - %eip3636- * 34(%esp) - %cs3737- * 38(%esp) - %eflags3838- * 3C(%esp) - %oldesp3939- * 40(%esp) - %oldss4040- *4141- * "current" is in register %ebx during any slow entries.4242- */4343-4444-#include <linux/linkage.h>4545-#include <linux/err.h>4646-#include <asm/thread_info.h>4747-#include <asm/irqflags.h>4848-#include <asm/errno.h>4949-#include <asm/segment.h>5050-#include <asm/smp.h>5151-#include <asm/page_types.h>5252-#include <asm/percpu.h>5353-#include <asm/dwarf2.h>5454-#include <asm/processor-flags.h>5555-#include <asm/ftrace.h>5656-#include <asm/irq_vectors.h>5757-#include <asm/cpufeature.h>5858-#include <asm/alternative-asm.h>5959-#include <asm/asm.h>6060-#include <asm/smap.h>6161-6262-/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */6363-#include <linux/elf-em.h>6464-#define AUDIT_ARCH_I386 (EM_386|__AUDIT_ARCH_LE)6565-#define __AUDIT_ARCH_LE 0x400000006666-6767-#ifndef CONFIG_AUDITSYSCALL6868-#define sysenter_audit syscall_trace_entry6969-#define sysexit_audit syscall_exit_work7070-#endif7171-7272- .section .entry.text, "ax"7373-7474-/*7575- * We use macros for low-level operations which need to be overridden7676- * for paravirtualization. The following will never clobber any registers:7777- * INTERRUPT_RETURN (aka. "iret")7878- * GET_CR0_INTO_EAX (aka. "movl %cr0, %eax")7979- * ENABLE_INTERRUPTS_SYSEXIT (aka "sti; sysexit").8080- *8181- * For DISABLE_INTERRUPTS/ENABLE_INTERRUPTS (aka "cli"/"sti"), you must8282- * specify what registers can be overwritten (CLBR_NONE, CLBR_EAX/EDX/ECX/ANY).8383- * Allowing a register to be clobbered can shrink the paravirt replacement8484- * enough to patch inline, increasing performance.8585- */8686-8787-#ifdef CONFIG_PREEMPT8888-#define preempt_stop(clobbers) DISABLE_INTERRUPTS(clobbers); TRACE_IRQS_OFF8989-#else9090-#define preempt_stop(clobbers)9191-#define resume_kernel restore_all9292-#endif9393-9494-.macro TRACE_IRQS_IRET9595-#ifdef CONFIG_TRACE_IRQFLAGS9696- testl $X86_EFLAGS_IF,PT_EFLAGS(%esp) # interrupts off?9797- jz 1f9898- TRACE_IRQS_ON9999-1:100100-#endif101101-.endm102102-103103-/*104104- * User gs save/restore105105- *106106- * %gs is used for userland TLS and kernel only uses it for stack107107- * canary which is required to be at %gs:20 by gcc. Read the comment108108- * at the top of stackprotector.h for more info.109109- *110110- * Local labels 98 and 99 are used.111111- */112112-#ifdef CONFIG_X86_32_LAZY_GS113113-114114- /* unfortunately push/pop can't be no-op */115115-.macro PUSH_GS116116- pushl_cfi $0117117-.endm118118-.macro POP_GS pop=0119119- addl $(4 + \pop), %esp120120- CFI_ADJUST_CFA_OFFSET -(4 + \pop)121121-.endm122122-.macro POP_GS_EX123123-.endm124124-125125- /* all the rest are no-op */126126-.macro PTGS_TO_GS127127-.endm128128-.macro PTGS_TO_GS_EX129129-.endm130130-.macro GS_TO_REG reg131131-.endm132132-.macro REG_TO_PTGS reg133133-.endm134134-.macro SET_KERNEL_GS reg135135-.endm136136-137137-#else /* CONFIG_X86_32_LAZY_GS */138138-139139-.macro PUSH_GS140140- pushl_cfi %gs141141- /*CFI_REL_OFFSET gs, 0*/142142-.endm143143-144144-.macro POP_GS pop=0145145-98: popl_cfi %gs146146- /*CFI_RESTORE gs*/147147- .if \pop <> 0148148- add $\pop, %esp149149- CFI_ADJUST_CFA_OFFSET -\pop150150- .endif151151-.endm152152-.macro POP_GS_EX153153-.pushsection .fixup, "ax"154154-99: movl $0, (%esp)155155- jmp 98b156156-.popsection157157- _ASM_EXTABLE(98b,99b)158158-.endm159159-160160-.macro PTGS_TO_GS161161-98: mov PT_GS(%esp), %gs162162-.endm163163-.macro PTGS_TO_GS_EX164164-.pushsection .fixup, "ax"165165-99: movl $0, PT_GS(%esp)166166- jmp 98b167167-.popsection168168- _ASM_EXTABLE(98b,99b)169169-.endm170170-171171-.macro GS_TO_REG reg172172- movl %gs, \reg173173- /*CFI_REGISTER gs, \reg*/174174-.endm175175-.macro REG_TO_PTGS reg176176- movl \reg, PT_GS(%esp)177177- /*CFI_REL_OFFSET gs, PT_GS*/178178-.endm179179-.macro SET_KERNEL_GS reg180180- movl $(__KERNEL_STACK_CANARY), \reg181181- movl \reg, %gs182182-.endm183183-184184-#endif /* CONFIG_X86_32_LAZY_GS */185185-186186-.macro SAVE_ALL187187- cld188188- PUSH_GS189189- pushl_cfi %fs190190- /*CFI_REL_OFFSET fs, 0;*/191191- pushl_cfi %es192192- /*CFI_REL_OFFSET es, 0;*/193193- pushl_cfi %ds194194- /*CFI_REL_OFFSET ds, 0;*/195195- pushl_cfi %eax196196- CFI_REL_OFFSET eax, 0197197- pushl_cfi %ebp198198- CFI_REL_OFFSET ebp, 0199199- pushl_cfi %edi200200- CFI_REL_OFFSET edi, 0201201- pushl_cfi %esi202202- CFI_REL_OFFSET esi, 0203203- pushl_cfi %edx204204- CFI_REL_OFFSET edx, 0205205- pushl_cfi %ecx206206- CFI_REL_OFFSET ecx, 0207207- pushl_cfi %ebx208208- CFI_REL_OFFSET ebx, 0209209- movl $(__USER_DS), %edx210210- movl %edx, %ds211211- movl %edx, %es212212- movl $(__KERNEL_PERCPU), %edx213213- movl %edx, %fs214214- SET_KERNEL_GS %edx215215-.endm216216-217217-.macro RESTORE_INT_REGS218218- popl_cfi %ebx219219- CFI_RESTORE ebx220220- popl_cfi %ecx221221- CFI_RESTORE ecx222222- popl_cfi %edx223223- CFI_RESTORE edx224224- popl_cfi %esi225225- CFI_RESTORE esi226226- popl_cfi %edi227227- CFI_RESTORE edi228228- popl_cfi %ebp229229- CFI_RESTORE ebp230230- popl_cfi %eax231231- CFI_RESTORE eax232232-.endm233233-234234-.macro RESTORE_REGS pop=0235235- RESTORE_INT_REGS236236-1: popl_cfi %ds237237- /*CFI_RESTORE ds;*/238238-2: popl_cfi %es239239- /*CFI_RESTORE es;*/240240-3: popl_cfi %fs241241- /*CFI_RESTORE fs;*/242242- POP_GS \pop243243-.pushsection .fixup, "ax"244244-4: movl $0, (%esp)245245- jmp 1b246246-5: movl $0, (%esp)247247- jmp 2b248248-6: movl $0, (%esp)249249- jmp 3b250250-.popsection251251- _ASM_EXTABLE(1b,4b)252252- _ASM_EXTABLE(2b,5b)253253- _ASM_EXTABLE(3b,6b)254254- POP_GS_EX255255-.endm256256-257257-.macro RING0_INT_FRAME258258- CFI_STARTPROC simple259259- CFI_SIGNAL_FRAME260260- CFI_DEF_CFA esp, 3*4261261- /*CFI_OFFSET cs, -2*4;*/262262- CFI_OFFSET eip, -3*4263263-.endm264264-265265-.macro RING0_EC_FRAME266266- CFI_STARTPROC simple267267- CFI_SIGNAL_FRAME268268- CFI_DEF_CFA esp, 4*4269269- /*CFI_OFFSET cs, -2*4;*/270270- CFI_OFFSET eip, -3*4271271-.endm272272-273273-.macro RING0_PTREGS_FRAME274274- CFI_STARTPROC simple275275- CFI_SIGNAL_FRAME276276- CFI_DEF_CFA esp, PT_OLDESP-PT_EBX277277- /*CFI_OFFSET cs, PT_CS-PT_OLDESP;*/278278- CFI_OFFSET eip, PT_EIP-PT_OLDESP279279- /*CFI_OFFSET es, PT_ES-PT_OLDESP;*/280280- /*CFI_OFFSET ds, PT_DS-PT_OLDESP;*/281281- CFI_OFFSET eax, PT_EAX-PT_OLDESP282282- CFI_OFFSET ebp, PT_EBP-PT_OLDESP283283- CFI_OFFSET edi, PT_EDI-PT_OLDESP284284- CFI_OFFSET esi, PT_ESI-PT_OLDESP285285- CFI_OFFSET edx, PT_EDX-PT_OLDESP286286- CFI_OFFSET ecx, PT_ECX-PT_OLDESP287287- CFI_OFFSET ebx, PT_EBX-PT_OLDESP288288-.endm289289-290290-ENTRY(ret_from_fork)291291- CFI_STARTPROC292292- pushl_cfi %eax293293- call schedule_tail294294- GET_THREAD_INFO(%ebp)295295- popl_cfi %eax296296- pushl_cfi $0x0202 # Reset kernel eflags297297- popfl_cfi298298- jmp syscall_exit299299- CFI_ENDPROC300300-END(ret_from_fork)301301-302302-ENTRY(ret_from_kernel_thread)303303- CFI_STARTPROC304304- pushl_cfi %eax305305- call schedule_tail306306- GET_THREAD_INFO(%ebp)307307- popl_cfi %eax308308- pushl_cfi $0x0202 # Reset kernel eflags309309- popfl_cfi310310- movl PT_EBP(%esp),%eax311311- call *PT_EBX(%esp)312312- movl $0,PT_EAX(%esp)313313- jmp syscall_exit314314- CFI_ENDPROC315315-ENDPROC(ret_from_kernel_thread)316316-317317-/*318318- * Return to user mode is not as complex as all this looks,319319- * but we want the default path for a system call return to320320- * go as quickly as possible which is why some of this is321321- * less clear than it otherwise should be.322322- */323323-324324- # userspace resumption stub bypassing syscall exit tracing325325- ALIGN326326- RING0_PTREGS_FRAME327327-ret_from_exception:328328- preempt_stop(CLBR_ANY)329329-ret_from_intr:330330- GET_THREAD_INFO(%ebp)331331-#ifdef CONFIG_VM86332332- movl PT_EFLAGS(%esp), %eax # mix EFLAGS and CS333333- movb PT_CS(%esp), %al334334- andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax335335-#else336336- /*337337- * We can be coming here from child spawned by kernel_thread().338338- */339339- movl PT_CS(%esp), %eax340340- andl $SEGMENT_RPL_MASK, %eax341341-#endif342342- cmpl $USER_RPL, %eax343343- jb resume_kernel # not returning to v8086 or userspace344344-345345-ENTRY(resume_userspace)346346- LOCKDEP_SYS_EXIT347347- DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt348348- # setting need_resched or sigpending349349- # between sampling and the iret350350- TRACE_IRQS_OFF351351- movl TI_flags(%ebp), %ecx352352- andl $_TIF_WORK_MASK, %ecx # is there any work to be done on353353- # int/exception return?354354- jne work_pending355355- jmp restore_all356356-END(ret_from_exception)357357-358358-#ifdef CONFIG_PREEMPT359359-ENTRY(resume_kernel)360360- DISABLE_INTERRUPTS(CLBR_ANY)361361-need_resched:362362- cmpl $0,PER_CPU_VAR(__preempt_count)363363- jnz restore_all364364- testl $X86_EFLAGS_IF,PT_EFLAGS(%esp) # interrupts off (exception path) ?365365- jz restore_all366366- call preempt_schedule_irq367367- jmp need_resched368368-END(resume_kernel)369369-#endif370370- CFI_ENDPROC371371-372372-/* SYSENTER_RETURN points to after the "sysenter" instruction in373373- the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */374374-375375- # sysenter call handler stub376376-ENTRY(ia32_sysenter_target)377377- CFI_STARTPROC simple378378- CFI_SIGNAL_FRAME379379- CFI_DEF_CFA esp, 0380380- CFI_REGISTER esp, ebp381381- movl TSS_sysenter_sp0(%esp),%esp382382-sysenter_past_esp:383383- /*384384- * Interrupts are disabled here, but we can't trace it until385385- * enough kernel state to call TRACE_IRQS_OFF can be called - but386386- * we immediately enable interrupts at that point anyway.387387- */388388- pushl_cfi $__USER_DS389389- /*CFI_REL_OFFSET ss, 0*/390390- pushl_cfi %ebp391391- CFI_REL_OFFSET esp, 0392392- pushfl_cfi393393- orl $X86_EFLAGS_IF, (%esp)394394- pushl_cfi $__USER_CS395395- /*CFI_REL_OFFSET cs, 0*/396396- /*397397- * Push current_thread_info()->sysenter_return to the stack.398398- * A tiny bit of offset fixup is necessary: TI_sysenter_return399399- * is relative to thread_info, which is at the bottom of the400400- * kernel stack page. 4*4 means the 4 words pushed above;401401- * TOP_OF_KERNEL_STACK_PADDING takes us to the top of the stack;402402- * and THREAD_SIZE takes us to the bottom.403403- */404404- pushl_cfi ((TI_sysenter_return) - THREAD_SIZE + TOP_OF_KERNEL_STACK_PADDING + 4*4)(%esp)405405- CFI_REL_OFFSET eip, 0406406-407407- pushl_cfi %eax408408- SAVE_ALL409409- ENABLE_INTERRUPTS(CLBR_NONE)410410-411411-/*412412- * Load the potential sixth argument from user stack.413413- * Careful about security.414414- */415415- cmpl $__PAGE_OFFSET-3,%ebp416416- jae syscall_fault417417- ASM_STAC418418-1: movl (%ebp),%ebp419419- ASM_CLAC420420- movl %ebp,PT_EBP(%esp)421421- _ASM_EXTABLE(1b,syscall_fault)422422-423423- GET_THREAD_INFO(%ebp)424424-425425- testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)426426- jnz sysenter_audit427427-sysenter_do_call:428428- cmpl $(NR_syscalls), %eax429429- jae sysenter_badsys430430- call *sys_call_table(,%eax,4)431431-sysenter_after_call:432432- movl %eax,PT_EAX(%esp)433433- LOCKDEP_SYS_EXIT434434- DISABLE_INTERRUPTS(CLBR_ANY)435435- TRACE_IRQS_OFF436436- movl TI_flags(%ebp), %ecx437437- testl $_TIF_ALLWORK_MASK, %ecx438438- jnz sysexit_audit439439-sysenter_exit:440440-/* if something modifies registers it must also disable sysexit */441441- movl PT_EIP(%esp), %edx442442- movl PT_OLDESP(%esp), %ecx443443- xorl %ebp,%ebp444444- TRACE_IRQS_ON445445-1: mov PT_FS(%esp), %fs446446- PTGS_TO_GS447447- ENABLE_INTERRUPTS_SYSEXIT448448-449449-#ifdef CONFIG_AUDITSYSCALL450450-sysenter_audit:451451- testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%ebp)452452- jnz syscall_trace_entry453453- /* movl PT_EAX(%esp), %eax already set, syscall number: 1st arg to audit */454454- movl PT_EBX(%esp), %edx /* ebx/a0: 2nd arg to audit */455455- /* movl PT_ECX(%esp), %ecx already set, a1: 3nd arg to audit */456456- pushl_cfi PT_ESI(%esp) /* a3: 5th arg */457457- pushl_cfi PT_EDX+4(%esp) /* a2: 4th arg */458458- call __audit_syscall_entry459459- popl_cfi %ecx /* get that remapped edx off the stack */460460- popl_cfi %ecx /* get that remapped esi off the stack */461461- movl PT_EAX(%esp),%eax /* reload syscall number */462462- jmp sysenter_do_call463463-464464-sysexit_audit:465465- testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %ecx466466- jnz syscall_exit_work467467- TRACE_IRQS_ON468468- ENABLE_INTERRUPTS(CLBR_ANY)469469- movl %eax,%edx /* second arg, syscall return value */470470- cmpl $-MAX_ERRNO,%eax /* is it an error ? */471471- setbe %al /* 1 if so, 0 if not */472472- movzbl %al,%eax /* zero-extend that */473473- call __audit_syscall_exit474474- DISABLE_INTERRUPTS(CLBR_ANY)475475- TRACE_IRQS_OFF476476- movl TI_flags(%ebp), %ecx477477- testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %ecx478478- jnz syscall_exit_work479479- movl PT_EAX(%esp),%eax /* reload syscall return value */480480- jmp sysenter_exit481481-#endif482482-483483- CFI_ENDPROC484484-.pushsection .fixup,"ax"485485-2: movl $0,PT_FS(%esp)486486- jmp 1b487487-.popsection488488- _ASM_EXTABLE(1b,2b)489489- PTGS_TO_GS_EX490490-ENDPROC(ia32_sysenter_target)491491-492492- # system call handler stub493493-ENTRY(system_call)494494- RING0_INT_FRAME # can't unwind into user space anyway495495- ASM_CLAC496496- pushl_cfi %eax # save orig_eax497497- SAVE_ALL498498- GET_THREAD_INFO(%ebp)499499- # system call tracing in operation / emulation500500- testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)501501- jnz syscall_trace_entry502502- cmpl $(NR_syscalls), %eax503503- jae syscall_badsys504504-syscall_call:505505- call *sys_call_table(,%eax,4)506506-syscall_after_call:507507- movl %eax,PT_EAX(%esp) # store the return value508508-syscall_exit:509509- LOCKDEP_SYS_EXIT510510- DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt511511- # setting need_resched or sigpending512512- # between sampling and the iret513513- TRACE_IRQS_OFF514514- movl TI_flags(%ebp), %ecx515515- testl $_TIF_ALLWORK_MASK, %ecx # current->work516516- jnz syscall_exit_work517517-518518-restore_all:519519- TRACE_IRQS_IRET520520-restore_all_notrace:521521-#ifdef CONFIG_X86_ESPFIX32522522- movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS523523- # Warning: PT_OLDSS(%esp) contains the wrong/random values if we524524- # are returning to the kernel.525525- # See comments in process.c:copy_thread() for details.526526- movb PT_OLDSS(%esp), %ah527527- movb PT_CS(%esp), %al528528- andl $(X86_EFLAGS_VM | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax529529- cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax530530- CFI_REMEMBER_STATE531531- je ldt_ss # returning to user-space with LDT SS532532-#endif533533-restore_nocheck:534534- RESTORE_REGS 4 # skip orig_eax/error_code535535-irq_return:536536- INTERRUPT_RETURN537537-.section .fixup,"ax"538538-ENTRY(iret_exc)539539- pushl $0 # no error code540540- pushl $do_iret_error541541- jmp error_code542542-.previous543543- _ASM_EXTABLE(irq_return,iret_exc)544544-545545-#ifdef CONFIG_X86_ESPFIX32546546- CFI_RESTORE_STATE547547-ldt_ss:548548-#ifdef CONFIG_PARAVIRT549549- /*550550- * The kernel can't run on a non-flat stack if paravirt mode551551- * is active. Rather than try to fixup the high bits of552552- * ESP, bypass this code entirely. This may break DOSemu553553- * and/or Wine support in a paravirt VM, although the option554554- * is still available to implement the setting of the high555555- * 16-bits in the INTERRUPT_RETURN paravirt-op.556556- */557557- cmpl $0, pv_info+PARAVIRT_enabled558558- jne restore_nocheck559559-#endif560560-561561-/*562562- * Setup and switch to ESPFIX stack563563- *564564- * We're returning to userspace with a 16 bit stack. The CPU will not565565- * restore the high word of ESP for us on executing iret... This is an566566- * "official" bug of all the x86-compatible CPUs, which we can work567567- * around to make dosemu and wine happy. We do this by preloading the568568- * high word of ESP with the high word of the userspace ESP while569569- * compensating for the offset by changing to the ESPFIX segment with570570- * a base address that matches for the difference.571571- */572572-#define GDT_ESPFIX_SS PER_CPU_VAR(gdt_page) + (GDT_ENTRY_ESPFIX_SS * 8)573573- mov %esp, %edx /* load kernel esp */574574- mov PT_OLDESP(%esp), %eax /* load userspace esp */575575- mov %dx, %ax /* eax: new kernel esp */576576- sub %eax, %edx /* offset (low word is 0) */577577- shr $16, %edx578578- mov %dl, GDT_ESPFIX_SS + 4 /* bits 16..23 */579579- mov %dh, GDT_ESPFIX_SS + 7 /* bits 24..31 */580580- pushl_cfi $__ESPFIX_SS581581- pushl_cfi %eax /* new kernel esp */582582- /* Disable interrupts, but do not irqtrace this section: we583583- * will soon execute iret and the tracer was already set to584584- * the irqstate after the iret */585585- DISABLE_INTERRUPTS(CLBR_EAX)586586- lss (%esp), %esp /* switch to espfix segment */587587- CFI_ADJUST_CFA_OFFSET -8588588- jmp restore_nocheck589589-#endif590590- CFI_ENDPROC591591-ENDPROC(system_call)592592-593593- # perform work that needs to be done immediately before resumption594594- ALIGN595595- RING0_PTREGS_FRAME # can't unwind into user space anyway596596-work_pending:597597- testb $_TIF_NEED_RESCHED, %cl598598- jz work_notifysig599599-work_resched:600600- call schedule601601- LOCKDEP_SYS_EXIT602602- DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt603603- # setting need_resched or sigpending604604- # between sampling and the iret605605- TRACE_IRQS_OFF606606- movl TI_flags(%ebp), %ecx607607- andl $_TIF_WORK_MASK, %ecx # is there any work to be done other608608- # than syscall tracing?609609- jz restore_all610610- testb $_TIF_NEED_RESCHED, %cl611611- jnz work_resched612612-613613-work_notifysig: # deal with pending signals and614614- # notify-resume requests615615-#ifdef CONFIG_VM86616616- testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)617617- movl %esp, %eax618618- jnz work_notifysig_v86 # returning to kernel-space or619619- # vm86-space620620-1:621621-#else622622- movl %esp, %eax623623-#endif624624- TRACE_IRQS_ON625625- ENABLE_INTERRUPTS(CLBR_NONE)626626- movb PT_CS(%esp), %bl627627- andb $SEGMENT_RPL_MASK, %bl628628- cmpb $USER_RPL, %bl629629- jb resume_kernel630630- xorl %edx, %edx631631- call do_notify_resume632632- jmp resume_userspace633633-634634-#ifdef CONFIG_VM86635635- ALIGN636636-work_notifysig_v86:637637- pushl_cfi %ecx # save ti_flags for do_notify_resume638638- call save_v86_state # %eax contains pt_regs pointer639639- popl_cfi %ecx640640- movl %eax, %esp641641- jmp 1b642642-#endif643643-END(work_pending)644644-645645- # perform syscall exit tracing646646- ALIGN647647-syscall_trace_entry:648648- movl $-ENOSYS,PT_EAX(%esp)649649- movl %esp, %eax650650- call syscall_trace_enter651651- /* What it returned is what we'll actually use. */652652- cmpl $(NR_syscalls), %eax653653- jnae syscall_call654654- jmp syscall_exit655655-END(syscall_trace_entry)656656-657657- # perform syscall exit tracing658658- ALIGN659659-syscall_exit_work:660660- testl $_TIF_WORK_SYSCALL_EXIT, %ecx661661- jz work_pending662662- TRACE_IRQS_ON663663- ENABLE_INTERRUPTS(CLBR_ANY) # could let syscall_trace_leave() call664664- # schedule() instead665665- movl %esp, %eax666666- call syscall_trace_leave667667- jmp resume_userspace668668-END(syscall_exit_work)669669- CFI_ENDPROC670670-671671- RING0_INT_FRAME # can't unwind into user space anyway672672-syscall_fault:673673- ASM_CLAC674674- GET_THREAD_INFO(%ebp)675675- movl $-EFAULT,PT_EAX(%esp)676676- jmp resume_userspace677677-END(syscall_fault)678678-679679-syscall_badsys:680680- movl $-ENOSYS,%eax681681- jmp syscall_after_call682682-END(syscall_badsys)683683-684684-sysenter_badsys:685685- movl $-ENOSYS,%eax686686- jmp sysenter_after_call687687-END(sysenter_badsys)688688- CFI_ENDPROC689689-690690-.macro FIXUP_ESPFIX_STACK691691-/*692692- * Switch back for ESPFIX stack to the normal zerobased stack693693- *694694- * We can't call C functions using the ESPFIX stack. This code reads695695- * the high word of the segment base from the GDT and swiches to the696696- * normal stack and adjusts ESP with the matching offset.697697- */698698-#ifdef CONFIG_X86_ESPFIX32699699- /* fixup the stack */700700- mov GDT_ESPFIX_SS + 4, %al /* bits 16..23 */701701- mov GDT_ESPFIX_SS + 7, %ah /* bits 24..31 */702702- shl $16, %eax703703- addl %esp, %eax /* the adjusted stack pointer */704704- pushl_cfi $__KERNEL_DS705705- pushl_cfi %eax706706- lss (%esp), %esp /* switch to the normal stack segment */707707- CFI_ADJUST_CFA_OFFSET -8708708-#endif709709-.endm710710-.macro UNWIND_ESPFIX_STACK711711-#ifdef CONFIG_X86_ESPFIX32712712- movl %ss, %eax713713- /* see if on espfix stack */714714- cmpw $__ESPFIX_SS, %ax715715- jne 27f716716- movl $__KERNEL_DS, %eax717717- movl %eax, %ds718718- movl %eax, %es719719- /* switch to normal stack */720720- FIXUP_ESPFIX_STACK721721-27:722722-#endif723723-.endm724724-725725-/*726726- * Build the entry stubs with some assembler magic.727727- * We pack 1 stub into every 8-byte block.728728- */729729- .align 8730730-ENTRY(irq_entries_start)731731- RING0_INT_FRAME732732- vector=FIRST_EXTERNAL_VECTOR733733- .rept (FIRST_SYSTEM_VECTOR - FIRST_EXTERNAL_VECTOR)734734- pushl_cfi $(~vector+0x80) /* Note: always in signed byte range */735735- vector=vector+1736736- jmp common_interrupt737737- CFI_ADJUST_CFA_OFFSET -4738738- .align 8739739- .endr740740-END(irq_entries_start)741741-742742-/*743743- * the CPU automatically disables interrupts when executing an IRQ vector,744744- * so IRQ-flags tracing has to follow that:745745- */746746- .p2align CONFIG_X86_L1_CACHE_SHIFT747747-common_interrupt:748748- ASM_CLAC749749- addl $-0x80,(%esp) /* Adjust vector into the [-256,-1] range */750750- SAVE_ALL751751- TRACE_IRQS_OFF752752- movl %esp,%eax753753- call do_IRQ754754- jmp ret_from_intr755755-ENDPROC(common_interrupt)756756- CFI_ENDPROC757757-758758-#define BUILD_INTERRUPT3(name, nr, fn) \759759-ENTRY(name) \760760- RING0_INT_FRAME; \761761- ASM_CLAC; \762762- pushl_cfi $~(nr); \763763- SAVE_ALL; \764764- TRACE_IRQS_OFF \765765- movl %esp,%eax; \766766- call fn; \767767- jmp ret_from_intr; \768768- CFI_ENDPROC; \769769-ENDPROC(name)770770-771771-772772-#ifdef CONFIG_TRACING773773-#define TRACE_BUILD_INTERRUPT(name, nr) \774774- BUILD_INTERRUPT3(trace_##name, nr, smp_trace_##name)775775-#else776776-#define TRACE_BUILD_INTERRUPT(name, nr)777777-#endif778778-779779-#define BUILD_INTERRUPT(name, nr) \780780- BUILD_INTERRUPT3(name, nr, smp_##name); \781781- TRACE_BUILD_INTERRUPT(name, nr)782782-783783-/* The include is where all of the SMP etc. interrupts come from */784784-#include <asm/entry_arch.h>785785-786786-ENTRY(coprocessor_error)787787- RING0_INT_FRAME788788- ASM_CLAC789789- pushl_cfi $0790790- pushl_cfi $do_coprocessor_error791791- jmp error_code792792- CFI_ENDPROC793793-END(coprocessor_error)794794-795795-ENTRY(simd_coprocessor_error)796796- RING0_INT_FRAME797797- ASM_CLAC798798- pushl_cfi $0799799-#ifdef CONFIG_X86_INVD_BUG800800- /* AMD 486 bug: invd from userspace calls exception 19 instead of #GP */801801- ALTERNATIVE "pushl_cfi $do_general_protection", \802802- "pushl $do_simd_coprocessor_error", \803803- X86_FEATURE_XMM804804-#else805805- pushl_cfi $do_simd_coprocessor_error806806-#endif807807- jmp error_code808808- CFI_ENDPROC809809-END(simd_coprocessor_error)810810-811811-ENTRY(device_not_available)812812- RING0_INT_FRAME813813- ASM_CLAC814814- pushl_cfi $-1 # mark this as an int815815- pushl_cfi $do_device_not_available816816- jmp error_code817817- CFI_ENDPROC818818-END(device_not_available)819819-820820-#ifdef CONFIG_PARAVIRT821821-ENTRY(native_iret)822822- iret823823- _ASM_EXTABLE(native_iret, iret_exc)824824-END(native_iret)825825-826826-ENTRY(native_irq_enable_sysexit)827827- sti828828- sysexit829829-END(native_irq_enable_sysexit)830830-#endif831831-832832-ENTRY(overflow)833833- RING0_INT_FRAME834834- ASM_CLAC835835- pushl_cfi $0836836- pushl_cfi $do_overflow837837- jmp error_code838838- CFI_ENDPROC839839-END(overflow)840840-841841-ENTRY(bounds)842842- RING0_INT_FRAME843843- ASM_CLAC844844- pushl_cfi $0845845- pushl_cfi $do_bounds846846- jmp error_code847847- CFI_ENDPROC848848-END(bounds)849849-850850-ENTRY(invalid_op)851851- RING0_INT_FRAME852852- ASM_CLAC853853- pushl_cfi $0854854- pushl_cfi $do_invalid_op855855- jmp error_code856856- CFI_ENDPROC857857-END(invalid_op)858858-859859-ENTRY(coprocessor_segment_overrun)860860- RING0_INT_FRAME861861- ASM_CLAC862862- pushl_cfi $0863863- pushl_cfi $do_coprocessor_segment_overrun864864- jmp error_code865865- CFI_ENDPROC866866-END(coprocessor_segment_overrun)867867-868868-ENTRY(invalid_TSS)869869- RING0_EC_FRAME870870- ASM_CLAC871871- pushl_cfi $do_invalid_TSS872872- jmp error_code873873- CFI_ENDPROC874874-END(invalid_TSS)875875-876876-ENTRY(segment_not_present)877877- RING0_EC_FRAME878878- ASM_CLAC879879- pushl_cfi $do_segment_not_present880880- jmp error_code881881- CFI_ENDPROC882882-END(segment_not_present)883883-884884-ENTRY(stack_segment)885885- RING0_EC_FRAME886886- ASM_CLAC887887- pushl_cfi $do_stack_segment888888- jmp error_code889889- CFI_ENDPROC890890-END(stack_segment)891891-892892-ENTRY(alignment_check)893893- RING0_EC_FRAME894894- ASM_CLAC895895- pushl_cfi $do_alignment_check896896- jmp error_code897897- CFI_ENDPROC898898-END(alignment_check)899899-900900-ENTRY(divide_error)901901- RING0_INT_FRAME902902- ASM_CLAC903903- pushl_cfi $0 # no error code904904- pushl_cfi $do_divide_error905905- jmp error_code906906- CFI_ENDPROC907907-END(divide_error)908908-909909-#ifdef CONFIG_X86_MCE910910-ENTRY(machine_check)911911- RING0_INT_FRAME912912- ASM_CLAC913913- pushl_cfi $0914914- pushl_cfi machine_check_vector915915- jmp error_code916916- CFI_ENDPROC917917-END(machine_check)918918-#endif919919-920920-ENTRY(spurious_interrupt_bug)921921- RING0_INT_FRAME922922- ASM_CLAC923923- pushl_cfi $0924924- pushl_cfi $do_spurious_interrupt_bug925925- jmp error_code926926- CFI_ENDPROC927927-END(spurious_interrupt_bug)928928-929929-#ifdef CONFIG_XEN930930-/* Xen doesn't set %esp to be precisely what the normal sysenter931931- entrypoint expects, so fix it up before using the normal path. */932932-ENTRY(xen_sysenter_target)933933- RING0_INT_FRAME934934- addl $5*4, %esp /* remove xen-provided frame */935935- CFI_ADJUST_CFA_OFFSET -5*4936936- jmp sysenter_past_esp937937- CFI_ENDPROC938938-939939-ENTRY(xen_hypervisor_callback)940940- CFI_STARTPROC941941- pushl_cfi $-1 /* orig_ax = -1 => not a system call */942942- SAVE_ALL943943- TRACE_IRQS_OFF944944-945945- /* Check to see if we got the event in the critical946946- region in xen_iret_direct, after we've reenabled947947- events and checked for pending events. This simulates948948- iret instruction's behaviour where it delivers a949949- pending interrupt when enabling interrupts. */950950- movl PT_EIP(%esp),%eax951951- cmpl $xen_iret_start_crit,%eax952952- jb 1f953953- cmpl $xen_iret_end_crit,%eax954954- jae 1f955955-956956- jmp xen_iret_crit_fixup957957-958958-ENTRY(xen_do_upcall)959959-1: mov %esp, %eax960960- call xen_evtchn_do_upcall961961-#ifndef CONFIG_PREEMPT962962- call xen_maybe_preempt_hcall963963-#endif964964- jmp ret_from_intr965965- CFI_ENDPROC966966-ENDPROC(xen_hypervisor_callback)967967-968968-# Hypervisor uses this for application faults while it executes.969969-# We get here for two reasons:970970-# 1. Fault while reloading DS, ES, FS or GS971971-# 2. Fault while executing IRET972972-# Category 1 we fix up by reattempting the load, and zeroing the segment973973-# register if the load fails.974974-# Category 2 we fix up by jumping to do_iret_error. We cannot use the975975-# normal Linux return path in this case because if we use the IRET hypercall976976-# to pop the stack frame we end up in an infinite loop of failsafe callbacks.977977-# We distinguish between categories by maintaining a status value in EAX.978978-ENTRY(xen_failsafe_callback)979979- CFI_STARTPROC980980- pushl_cfi %eax981981- movl $1,%eax982982-1: mov 4(%esp),%ds983983-2: mov 8(%esp),%es984984-3: mov 12(%esp),%fs985985-4: mov 16(%esp),%gs986986- /* EAX == 0 => Category 1 (Bad segment)987987- EAX != 0 => Category 2 (Bad IRET) */988988- testl %eax,%eax989989- popl_cfi %eax990990- lea 16(%esp),%esp991991- CFI_ADJUST_CFA_OFFSET -16992992- jz 5f993993- jmp iret_exc994994-5: pushl_cfi $-1 /* orig_ax = -1 => not a system call */995995- SAVE_ALL996996- jmp ret_from_exception997997- CFI_ENDPROC998998-999999-.section .fixup,"ax"10001000-6: xorl %eax,%eax10011001- movl %eax,4(%esp)10021002- jmp 1b10031003-7: xorl %eax,%eax10041004- movl %eax,8(%esp)10051005- jmp 2b10061006-8: xorl %eax,%eax10071007- movl %eax,12(%esp)10081008- jmp 3b10091009-9: xorl %eax,%eax10101010- movl %eax,16(%esp)10111011- jmp 4b10121012-.previous10131013- _ASM_EXTABLE(1b,6b)10141014- _ASM_EXTABLE(2b,7b)10151015- _ASM_EXTABLE(3b,8b)10161016- _ASM_EXTABLE(4b,9b)10171017-ENDPROC(xen_failsafe_callback)10181018-10191019-BUILD_INTERRUPT3(xen_hvm_callback_vector, HYPERVISOR_CALLBACK_VECTOR,10201020- xen_evtchn_do_upcall)10211021-10221022-#endif /* CONFIG_XEN */10231023-10241024-#if IS_ENABLED(CONFIG_HYPERV)10251025-10261026-BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR,10271027- hyperv_vector_handler)10281028-10291029-#endif /* CONFIG_HYPERV */10301030-10311031-#ifdef CONFIG_FUNCTION_TRACER10321032-#ifdef CONFIG_DYNAMIC_FTRACE10331033-10341034-ENTRY(mcount)10351035- ret10361036-END(mcount)10371037-10381038-ENTRY(ftrace_caller)10391039- pushl %eax10401040- pushl %ecx10411041- pushl %edx10421042- pushl $0 /* Pass NULL as regs pointer */10431043- movl 4*4(%esp), %eax10441044- movl 0x4(%ebp), %edx10451045- movl function_trace_op, %ecx10461046- subl $MCOUNT_INSN_SIZE, %eax10471047-10481048-.globl ftrace_call10491049-ftrace_call:10501050- call ftrace_stub10511051-10521052- addl $4,%esp /* skip NULL pointer */10531053- popl %edx10541054- popl %ecx10551055- popl %eax10561056-ftrace_ret:10571057-#ifdef CONFIG_FUNCTION_GRAPH_TRACER10581058-.globl ftrace_graph_call10591059-ftrace_graph_call:10601060- jmp ftrace_stub10611061-#endif10621062-10631063-.globl ftrace_stub10641064-ftrace_stub:10651065- ret10661066-END(ftrace_caller)10671067-10681068-ENTRY(ftrace_regs_caller)10691069- pushf /* push flags before compare (in cs location) */10701070-10711071- /*10721072- * i386 does not save SS and ESP when coming from kernel.10731073- * Instead, to get sp, ®s->sp is used (see ptrace.h).10741074- * Unfortunately, that means eflags must be at the same location10751075- * as the current return ip is. We move the return ip into the10761076- * ip location, and move flags into the return ip location.10771077- */10781078- pushl 4(%esp) /* save return ip into ip slot */10791079-10801080- pushl $0 /* Load 0 into orig_ax */10811081- pushl %gs10821082- pushl %fs10831083- pushl %es10841084- pushl %ds10851085- pushl %eax10861086- pushl %ebp10871087- pushl %edi10881088- pushl %esi10891089- pushl %edx10901090- pushl %ecx10911091- pushl %ebx10921092-10931093- movl 13*4(%esp), %eax /* Get the saved flags */10941094- movl %eax, 14*4(%esp) /* Move saved flags into regs->flags location */10951095- /* clobbering return ip */10961096- movl $__KERNEL_CS,13*4(%esp)10971097-10981098- movl 12*4(%esp), %eax /* Load ip (1st parameter) */10991099- subl $MCOUNT_INSN_SIZE, %eax /* Adjust ip */11001100- movl 0x4(%ebp), %edx /* Load parent ip (2nd parameter) */11011101- movl function_trace_op, %ecx /* Save ftrace_pos in 3rd parameter */11021102- pushl %esp /* Save pt_regs as 4th parameter */11031103-11041104-GLOBAL(ftrace_regs_call)11051105- call ftrace_stub11061106-11071107- addl $4, %esp /* Skip pt_regs */11081108- movl 14*4(%esp), %eax /* Move flags back into cs */11091109- movl %eax, 13*4(%esp) /* Needed to keep addl from modifying flags */11101110- movl 12*4(%esp), %eax /* Get return ip from regs->ip */11111111- movl %eax, 14*4(%esp) /* Put return ip back for ret */11121112-11131113- popl %ebx11141114- popl %ecx11151115- popl %edx11161116- popl %esi11171117- popl %edi11181118- popl %ebp11191119- popl %eax11201120- popl %ds11211121- popl %es11221122- popl %fs11231123- popl %gs11241124- addl $8, %esp /* Skip orig_ax and ip */11251125- popf /* Pop flags at end (no addl to corrupt flags) */11261126- jmp ftrace_ret11271127-11281128- popf11291129- jmp ftrace_stub11301130-#else /* ! CONFIG_DYNAMIC_FTRACE */11311131-11321132-ENTRY(mcount)11331133- cmpl $__PAGE_OFFSET, %esp11341134- jb ftrace_stub /* Paging not enabled yet? */11351135-11361136- cmpl $ftrace_stub, ftrace_trace_function11371137- jnz trace11381138-#ifdef CONFIG_FUNCTION_GRAPH_TRACER11391139- cmpl $ftrace_stub, ftrace_graph_return11401140- jnz ftrace_graph_caller11411141-11421142- cmpl $ftrace_graph_entry_stub, ftrace_graph_entry11431143- jnz ftrace_graph_caller11441144-#endif11451145-.globl ftrace_stub11461146-ftrace_stub:11471147- ret11481148-11491149- /* taken from glibc */11501150-trace:11511151- pushl %eax11521152- pushl %ecx11531153- pushl %edx11541154- movl 0xc(%esp), %eax11551155- movl 0x4(%ebp), %edx11561156- subl $MCOUNT_INSN_SIZE, %eax11571157-11581158- call *ftrace_trace_function11591159-11601160- popl %edx11611161- popl %ecx11621162- popl %eax11631163- jmp ftrace_stub11641164-END(mcount)11651165-#endif /* CONFIG_DYNAMIC_FTRACE */11661166-#endif /* CONFIG_FUNCTION_TRACER */11671167-11681168-#ifdef CONFIG_FUNCTION_GRAPH_TRACER11691169-ENTRY(ftrace_graph_caller)11701170- pushl %eax11711171- pushl %ecx11721172- pushl %edx11731173- movl 0xc(%esp), %eax11741174- lea 0x4(%ebp), %edx11751175- movl (%ebp), %ecx11761176- subl $MCOUNT_INSN_SIZE, %eax11771177- call prepare_ftrace_return11781178- popl %edx11791179- popl %ecx11801180- popl %eax11811181- ret11821182-END(ftrace_graph_caller)11831183-11841184-.globl return_to_handler11851185-return_to_handler:11861186- pushl %eax11871187- pushl %edx11881188- movl %ebp, %eax11891189- call ftrace_return_to_handler11901190- movl %eax, %ecx11911191- popl %edx11921192- popl %eax11931193- jmp *%ecx11941194-#endif11951195-11961196-#ifdef CONFIG_TRACING11971197-ENTRY(trace_page_fault)11981198- RING0_EC_FRAME11991199- ASM_CLAC12001200- pushl_cfi $trace_do_page_fault12011201- jmp error_code12021202- CFI_ENDPROC12031203-END(trace_page_fault)12041204-#endif12051205-12061206-ENTRY(page_fault)12071207- RING0_EC_FRAME12081208- ASM_CLAC12091209- pushl_cfi $do_page_fault12101210- ALIGN12111211-error_code:12121212- /* the function address is in %gs's slot on the stack */12131213- pushl_cfi %fs12141214- /*CFI_REL_OFFSET fs, 0*/12151215- pushl_cfi %es12161216- /*CFI_REL_OFFSET es, 0*/12171217- pushl_cfi %ds12181218- /*CFI_REL_OFFSET ds, 0*/12191219- pushl_cfi_reg eax12201220- pushl_cfi_reg ebp12211221- pushl_cfi_reg edi12221222- pushl_cfi_reg esi12231223- pushl_cfi_reg edx12241224- pushl_cfi_reg ecx12251225- pushl_cfi_reg ebx12261226- cld12271227- movl $(__KERNEL_PERCPU), %ecx12281228- movl %ecx, %fs12291229- UNWIND_ESPFIX_STACK12301230- GS_TO_REG %ecx12311231- movl PT_GS(%esp), %edi # get the function address12321232- movl PT_ORIG_EAX(%esp), %edx # get the error code12331233- movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart12341234- REG_TO_PTGS %ecx12351235- SET_KERNEL_GS %ecx12361236- movl $(__USER_DS), %ecx12371237- movl %ecx, %ds12381238- movl %ecx, %es12391239- TRACE_IRQS_OFF12401240- movl %esp,%eax # pt_regs pointer12411241- call *%edi12421242- jmp ret_from_exception12431243- CFI_ENDPROC12441244-END(page_fault)12451245-12461246-/*12471247- * Debug traps and NMI can happen at the one SYSENTER instruction12481248- * that sets up the real kernel stack. Check here, since we can't12491249- * allow the wrong stack to be used.12501250- *12511251- * "TSS_sysenter_sp0+12" is because the NMI/debug handler will have12521252- * already pushed 3 words if it hits on the sysenter instruction:12531253- * eflags, cs and eip.12541254- *12551255- * We just load the right stack, and push the three (known) values12561256- * by hand onto the new stack - while updating the return eip past12571257- * the instruction that would have done it for sysenter.12581258- */12591259-.macro FIX_STACK offset ok label12601260- cmpw $__KERNEL_CS, 4(%esp)12611261- jne \ok12621262-\label:12631263- movl TSS_sysenter_sp0 + \offset(%esp), %esp12641264- CFI_DEF_CFA esp, 012651265- CFI_UNDEFINED eip12661266- pushfl_cfi12671267- pushl_cfi $__KERNEL_CS12681268- pushl_cfi $sysenter_past_esp12691269- CFI_REL_OFFSET eip, 012701270-.endm12711271-12721272-ENTRY(debug)12731273- RING0_INT_FRAME12741274- ASM_CLAC12751275- cmpl $ia32_sysenter_target,(%esp)12761276- jne debug_stack_correct12771277- FIX_STACK 12, debug_stack_correct, debug_esp_fix_insn12781278-debug_stack_correct:12791279- pushl_cfi $-1 # mark this as an int12801280- SAVE_ALL12811281- TRACE_IRQS_OFF12821282- xorl %edx,%edx # error code 012831283- movl %esp,%eax # pt_regs pointer12841284- call do_debug12851285- jmp ret_from_exception12861286- CFI_ENDPROC12871287-END(debug)12881288-12891289-/*12901290- * NMI is doubly nasty. It can happen _while_ we're handling12911291- * a debug fault, and the debug fault hasn't yet been able to12921292- * clear up the stack. So we first check whether we got an12931293- * NMI on the sysenter entry path, but after that we need to12941294- * check whether we got an NMI on the debug path where the debug12951295- * fault happened on the sysenter path.12961296- */12971297-ENTRY(nmi)12981298- RING0_INT_FRAME12991299- ASM_CLAC13001300-#ifdef CONFIG_X86_ESPFIX3213011301- pushl_cfi %eax13021302- movl %ss, %eax13031303- cmpw $__ESPFIX_SS, %ax13041304- popl_cfi %eax13051305- je nmi_espfix_stack13061306-#endif13071307- cmpl $ia32_sysenter_target,(%esp)13081308- je nmi_stack_fixup13091309- pushl_cfi %eax13101310- movl %esp,%eax13111311- /* Do not access memory above the end of our stack page,13121312- * it might not exist.13131313- */13141314- andl $(THREAD_SIZE-1),%eax13151315- cmpl $(THREAD_SIZE-20),%eax13161316- popl_cfi %eax13171317- jae nmi_stack_correct13181318- cmpl $ia32_sysenter_target,12(%esp)13191319- je nmi_debug_stack_check13201320-nmi_stack_correct:13211321- /* We have a RING0_INT_FRAME here */13221322- pushl_cfi %eax13231323- SAVE_ALL13241324- xorl %edx,%edx # zero error code13251325- movl %esp,%eax # pt_regs pointer13261326- call do_nmi13271327- jmp restore_all_notrace13281328- CFI_ENDPROC13291329-13301330-nmi_stack_fixup:13311331- RING0_INT_FRAME13321332- FIX_STACK 12, nmi_stack_correct, 113331333- jmp nmi_stack_correct13341334-13351335-nmi_debug_stack_check:13361336- /* We have a RING0_INT_FRAME here */13371337- cmpw $__KERNEL_CS,16(%esp)13381338- jne nmi_stack_correct13391339- cmpl $debug,(%esp)13401340- jb nmi_stack_correct13411341- cmpl $debug_esp_fix_insn,(%esp)13421342- ja nmi_stack_correct13431343- FIX_STACK 24, nmi_stack_correct, 113441344- jmp nmi_stack_correct13451345-13461346-#ifdef CONFIG_X86_ESPFIX3213471347-nmi_espfix_stack:13481348- /* We have a RING0_INT_FRAME here.13491349- *13501350- * create the pointer to lss back13511351- */13521352- pushl_cfi %ss13531353- pushl_cfi %esp13541354- addl $4, (%esp)13551355- /* copy the iret frame of 12 bytes */13561356- .rept 313571357- pushl_cfi 16(%esp)13581358- .endr13591359- pushl_cfi %eax13601360- SAVE_ALL13611361- FIXUP_ESPFIX_STACK # %eax == %esp13621362- xorl %edx,%edx # zero error code13631363- call do_nmi13641364- RESTORE_REGS13651365- lss 12+4(%esp), %esp # back to espfix stack13661366- CFI_ADJUST_CFA_OFFSET -2413671367- jmp irq_return13681368-#endif13691369- CFI_ENDPROC13701370-END(nmi)13711371-13721372-ENTRY(int3)13731373- RING0_INT_FRAME13741374- ASM_CLAC13751375- pushl_cfi $-1 # mark this as an int13761376- SAVE_ALL13771377- TRACE_IRQS_OFF13781378- xorl %edx,%edx # zero error code13791379- movl %esp,%eax # pt_regs pointer13801380- call do_int313811381- jmp ret_from_exception13821382- CFI_ENDPROC13831383-END(int3)13841384-13851385-ENTRY(general_protection)13861386- RING0_EC_FRAME13871387- pushl_cfi $do_general_protection13881388- jmp error_code13891389- CFI_ENDPROC13901390-END(general_protection)13911391-13921392-#ifdef CONFIG_KVM_GUEST13931393-ENTRY(async_page_fault)13941394- RING0_EC_FRAME13951395- ASM_CLAC13961396- pushl_cfi $do_async_page_fault13971397- jmp error_code13981398- CFI_ENDPROC13991399-END(async_page_fault)14001400-#endif14011401-
···1919 * at the top of the kernel process stack.2020 *2121 * Some macro usage:2222- * - CFI macros are used to generate dwarf2 unwind information for better2323- * backtraces. They don't change any code.2422 * - ENTRY/END Define functions in the symbol table.2523 * - TRACE_IRQ_* - Trace hard interrupt state for lock debugging.2624 * - idtentry - Define exception entry points.···2830#include <asm/segment.h>2931#include <asm/cache.h>3032#include <asm/errno.h>3131-#include <asm/dwarf2.h>3232-#include <asm/calling.h>3333+#include "calling.h"3334#include <asm/asm-offsets.h>3435#include <asm/msr.h>3536#include <asm/unistd.h>···110113#endif111114112115/*113113- * empty frame114114- */115115- .macro EMPTY_FRAME start=1 offset=0116116- .if \start117117- CFI_STARTPROC simple118118- CFI_SIGNAL_FRAME119119- CFI_DEF_CFA rsp,8+\offset120120- .else121121- CFI_DEF_CFA_OFFSET 8+\offset122122- .endif123123- .endm124124-125125-/*126126- * initial frame state for interrupts (and exceptions without error code)127127- */128128- .macro INTR_FRAME start=1 offset=0129129- EMPTY_FRAME \start, 5*8+\offset130130- /*CFI_REL_OFFSET ss, 4*8+\offset*/131131- CFI_REL_OFFSET rsp, 3*8+\offset132132- /*CFI_REL_OFFSET rflags, 2*8+\offset*/133133- /*CFI_REL_OFFSET cs, 1*8+\offset*/134134- CFI_REL_OFFSET rip, 0*8+\offset135135- .endm136136-137137-/*138138- * initial frame state for exceptions with error code (and interrupts139139- * with vector already pushed)140140- */141141- .macro XCPT_FRAME start=1 offset=0142142- INTR_FRAME \start, 1*8+\offset143143- .endm144144-145145-/*146146- * frame that enables passing a complete pt_regs to a C function.147147- */148148- .macro DEFAULT_FRAME start=1 offset=0149149- XCPT_FRAME \start, ORIG_RAX+\offset150150- CFI_REL_OFFSET rdi, RDI+\offset151151- CFI_REL_OFFSET rsi, RSI+\offset152152- CFI_REL_OFFSET rdx, RDX+\offset153153- CFI_REL_OFFSET rcx, RCX+\offset154154- CFI_REL_OFFSET rax, RAX+\offset155155- CFI_REL_OFFSET r8, R8+\offset156156- CFI_REL_OFFSET r9, R9+\offset157157- CFI_REL_OFFSET r10, R10+\offset158158- CFI_REL_OFFSET r11, R11+\offset159159- CFI_REL_OFFSET rbx, RBX+\offset160160- CFI_REL_OFFSET rbp, RBP+\offset161161- CFI_REL_OFFSET r12, R12+\offset162162- CFI_REL_OFFSET r13, R13+\offset163163- CFI_REL_OFFSET r14, R14+\offset164164- CFI_REL_OFFSET r15, R15+\offset165165- .endm166166-167167-/*168116 * 64bit SYSCALL instruction entry. Up to 6 arguments in registers.169117 *170118 * 64bit SYSCALL saves rip to rcx, clears rflags.RF, then saves rflags to r11,···137195 * with them due to bugs in both AMD and Intel CPUs.138196 */139197140140-ENTRY(system_call)141141- CFI_STARTPROC simple142142- CFI_SIGNAL_FRAME143143- CFI_DEF_CFA rsp,0144144- CFI_REGISTER rip,rcx145145- /*CFI_REGISTER rflags,r11*/146146-198198+ENTRY(entry_SYSCALL_64)147199 /*148200 * Interrupts are off on entry.149201 * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON,···149213 * after the swapgs, so that it can do the swapgs150214 * for the guest and jump here on syscall.151215 */152152-GLOBAL(system_call_after_swapgs)216216+GLOBAL(entry_SYSCALL_64_after_swapgs)153217154218 movq %rsp,PER_CPU_VAR(rsp_scratch)155219 movq PER_CPU_VAR(cpu_current_top_of_stack),%rsp156220157221 /* Construct struct pt_regs on stack */158158- pushq_cfi $__USER_DS /* pt_regs->ss */159159- pushq_cfi PER_CPU_VAR(rsp_scratch) /* pt_regs->sp */222222+ pushq $__USER_DS /* pt_regs->ss */223223+ pushq PER_CPU_VAR(rsp_scratch) /* pt_regs->sp */160224 /*161225 * Re-enable interrupts.162226 * We use 'rsp_scratch' as a scratch space, hence irq-off block above···165229 * with using rsp_scratch:166230 */167231 ENABLE_INTERRUPTS(CLBR_NONE)168168- pushq_cfi %r11 /* pt_regs->flags */169169- pushq_cfi $__USER_CS /* pt_regs->cs */170170- pushq_cfi %rcx /* pt_regs->ip */171171- CFI_REL_OFFSET rip,0172172- pushq_cfi_reg rax /* pt_regs->orig_ax */173173- pushq_cfi_reg rdi /* pt_regs->di */174174- pushq_cfi_reg rsi /* pt_regs->si */175175- pushq_cfi_reg rdx /* pt_regs->dx */176176- pushq_cfi_reg rcx /* pt_regs->cx */177177- pushq_cfi $-ENOSYS /* pt_regs->ax */178178- pushq_cfi_reg r8 /* pt_regs->r8 */179179- pushq_cfi_reg r9 /* pt_regs->r9 */180180- pushq_cfi_reg r10 /* pt_regs->r10 */181181- pushq_cfi_reg r11 /* pt_regs->r11 */232232+ pushq %r11 /* pt_regs->flags */233233+ pushq $__USER_CS /* pt_regs->cs */234234+ pushq %rcx /* pt_regs->ip */235235+ pushq %rax /* pt_regs->orig_ax */236236+ pushq %rdi /* pt_regs->di */237237+ pushq %rsi /* pt_regs->si */238238+ pushq %rdx /* pt_regs->dx */239239+ pushq %rcx /* pt_regs->cx */240240+ pushq $-ENOSYS /* pt_regs->ax */241241+ pushq %r8 /* pt_regs->r8 */242242+ pushq %r9 /* pt_regs->r9 */243243+ pushq %r10 /* pt_regs->r10 */244244+ pushq %r11 /* pt_regs->r11 */182245 sub $(6*8),%rsp /* pt_regs->bp,bx,r12-15 not saved */183183- CFI_ADJUST_CFA_OFFSET 6*8184246185247 testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)186248 jnz tracesys187187-system_call_fastpath:249249+entry_SYSCALL_64_fastpath:188250#if __SYSCALL_MASK == ~0189251 cmpq $__NR_syscall_max,%rax190252#else···216282 testl $_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)217283 jnz int_ret_from_sys_call_irqs_off /* Go to the slow path */218284219219- CFI_REMEMBER_STATE220220-221285 RESTORE_C_REGS_EXCEPT_RCX_R11222286 movq RIP(%rsp),%rcx223223- CFI_REGISTER rip,rcx224287 movq EFLAGS(%rsp),%r11225225- /*CFI_REGISTER rflags,r11*/226288 movq RSP(%rsp),%rsp227289 /*228290 * 64bit SYSRET restores rip from rcx,···237307 */238308 USERGS_SYSRET64239309240240- CFI_RESTORE_STATE241241-242310 /* Do syscall entry tracing */243311tracesys:244312 movq %rsp, %rdi···246318 jnz tracesys_phase2 /* if needed, run the slow path */247319 RESTORE_C_REGS_EXCEPT_RAX /* else restore clobbered regs */248320 movq ORIG_RAX(%rsp), %rax249249- jmp system_call_fastpath /* and return to the fast path */321321+ jmp entry_SYSCALL_64_fastpath /* and return to the fast path */250322251323tracesys_phase2:252324 SAVE_EXTRA_REGS···302374 jnc int_very_careful303375 TRACE_IRQS_ON304376 ENABLE_INTERRUPTS(CLBR_NONE)305305- pushq_cfi %rdi377377+ pushq %rdi306378 SCHEDULE_USER307307- popq_cfi %rdi379379+ popq %rdi308380 DISABLE_INTERRUPTS(CLBR_NONE)309381 TRACE_IRQS_OFF310382 jmp int_with_check···317389 /* Check for syscall exit trace */318390 testl $_TIF_WORK_SYSCALL_EXIT,%edx319391 jz int_signal320320- pushq_cfi %rdi392392+ pushq %rdi321393 leaq 8(%rsp),%rdi # &ptregs -> arg1322394 call syscall_trace_leave323323- popq_cfi %rdi395395+ popq %rdi324396 andl $~(_TIF_WORK_SYSCALL_EXIT|_TIF_SYSCALL_EMU),%edi325397 jmp int_restore_rest326398···403475 * perf profiles. Nothing jumps here.404476 */405477syscall_return_via_sysret:406406- CFI_REMEMBER_STATE407478 /* rcx and r11 are already restored (see code above) */408479 RESTORE_C_REGS_EXCEPT_RCX_R11409480 movq RSP(%rsp),%rsp410481 USERGS_SYSRET64411411- CFI_RESTORE_STATE412482413483opportunistic_sysret_failed:414484 SWAPGS415485 jmp restore_c_regs_and_iret416416- CFI_ENDPROC417417-END(system_call)486486+END(entry_SYSCALL_64)418487419488420489 .macro FORK_LIKE func421490ENTRY(stub_\func)422422- CFI_STARTPROC423423- DEFAULT_FRAME 0, 8 /* offset 8: return address */424491 SAVE_EXTRA_REGS 8425492 jmp sys_\func426426- CFI_ENDPROC427493END(stub_\func)428494 .endm429495···426504 FORK_LIKE vfork427505428506ENTRY(stub_execve)429429- CFI_STARTPROC430430- DEFAULT_FRAME 0, 8431507 call sys_execve432508return_from_execve:433509 testl %eax, %eax···4355151:436516 /* must use IRET code path (pt_regs->cs may have changed) */437517 addq $8, %rsp438438- CFI_ADJUST_CFA_OFFSET -8439518 ZERO_EXTRA_REGS440519 movq %rax,RAX(%rsp)441520 jmp int_ret_from_sys_call442442- CFI_ENDPROC443521END(stub_execve)444522/*445523 * Remaining execve stubs are only 7 bytes long.···445527 */446528 .align 8447529GLOBAL(stub_execveat)448448- CFI_STARTPROC449449- DEFAULT_FRAME 0, 8450530 call sys_execveat451531 jmp return_from_execve452452- CFI_ENDPROC453532END(stub_execveat)454533455534#if defined(CONFIG_X86_X32_ABI) || defined(CONFIG_IA32_EMULATION)456535 .align 8457536GLOBAL(stub_x32_execve)458537GLOBAL(stub32_execve)459459- CFI_STARTPROC460460- DEFAULT_FRAME 0, 8461538 call compat_sys_execve462539 jmp return_from_execve463463- CFI_ENDPROC464540END(stub32_execve)465541END(stub_x32_execve)466542 .align 8467543GLOBAL(stub_x32_execveat)468544GLOBAL(stub32_execveat)469469- CFI_STARTPROC470470- DEFAULT_FRAME 0, 8471545 call compat_sys_execveat472546 jmp return_from_execve473473- CFI_ENDPROC474547END(stub32_execveat)475548END(stub_x32_execveat)476549#endif···471562 * This cannot be done with SYSRET, so use the IRET return path instead.472563 */473564ENTRY(stub_rt_sigreturn)474474- CFI_STARTPROC475475- DEFAULT_FRAME 0, 8476565 /*477566 * SAVE_EXTRA_REGS result is not normally needed:478567 * sigreturn overwrites all pt_regs->GPREGS.···482575 call sys_rt_sigreturn483576return_from_stub:484577 addq $8, %rsp485485- CFI_ADJUST_CFA_OFFSET -8486578 RESTORE_EXTRA_REGS487579 movq %rax,RAX(%rsp)488580 jmp int_ret_from_sys_call489489- CFI_ENDPROC490581END(stub_rt_sigreturn)491582492583#ifdef CONFIG_X86_X32_ABI493584ENTRY(stub_x32_rt_sigreturn)494494- CFI_STARTPROC495495- DEFAULT_FRAME 0, 8496585 SAVE_EXTRA_REGS 8497586 call sys32_x32_rt_sigreturn498587 jmp return_from_stub499499- CFI_ENDPROC500588END(stub_x32_rt_sigreturn)501589#endif502590···501599 * rdi: prev task we switched from502600 */503601ENTRY(ret_from_fork)504504- DEFAULT_FRAME505602506603 LOCK ; btr $TIF_FORK,TI_flags(%r8)507604508508- pushq_cfi $0x0002509509- popfq_cfi # reset kernel eflags605605+ pushq $0x0002606606+ popfq # reset kernel eflags510607511608 call schedule_tail # rdi: 'prev' task parameter512609···516615 /*517616 * By the time we get here, we have no idea whether our pt_regs,518617 * ti flags, and ti status came from the 64-bit SYSCALL fast path,519519- * the slow path, or one of the ia32entry paths.618618+ * the slow path, or one of the 32-bit compat paths.520619 * Use IRET code path to return, since it can safely handle521620 * all of the above.522621 */···529628 movl $0, RAX(%rsp)530629 RESTORE_EXTRA_REGS531630 jmp int_ret_from_sys_call532532- CFI_ENDPROC533631END(ret_from_fork)534632535633/*···537637 */538638 .align 8539639ENTRY(irq_entries_start)540540- INTR_FRAME541640 vector=FIRST_EXTERNAL_VECTOR542641 .rept (FIRST_SYSTEM_VECTOR - FIRST_EXTERNAL_VECTOR)543543- pushq_cfi $(~vector+0x80) /* Note: always in signed byte range */642642+ pushq $(~vector+0x80) /* Note: always in signed byte range */544643 vector=vector+1545644 jmp common_interrupt546546- CFI_ADJUST_CFA_OFFSET -8547645 .align 8548646 .endr549549- CFI_ENDPROC550647END(irq_entries_start)551648552649/*···585688 movq %rsp, %rsi586689 incl PER_CPU_VAR(irq_count)587690 cmovzq PER_CPU_VAR(irq_stack_ptr),%rsp588588- CFI_DEF_CFA_REGISTER rsi589691 pushq %rsi590590- /*591591- * For debugger:592592- * "CFA (Current Frame Address) is the value on stack + offset"593593- */594594- CFI_ESCAPE 0x0f /* DW_CFA_def_cfa_expression */, 6, \595595- 0x77 /* DW_OP_breg7 (rsp) */, 0, \596596- 0x06 /* DW_OP_deref */, \597597- 0x08 /* DW_OP_const1u */, SIZEOF_PTREGS-RBP, \598598- 0x22 /* DW_OP_plus */599692 /* We entered an interrupt context - irqs are off: */600693 TRACE_IRQS_OFF601694···598711 */599712 .p2align CONFIG_X86_L1_CACHE_SHIFT600713common_interrupt:601601- XCPT_FRAME602714 ASM_CLAC603715 addq $-0x80,(%rsp) /* Adjust vector to [-256,-1] range */604716 interrupt do_IRQ···609723610724 /* Restore saved previous stack */611725 popq %rsi612612- CFI_DEF_CFA rsi,SIZEOF_PTREGS-RBP /* reg/off reset after def_cfa_expr */613726 /* return code expects complete pt_regs - adjust rsp accordingly: */614727 leaq -RBP(%rsi),%rsp615615- CFI_DEF_CFA_REGISTER rsp616616- CFI_ADJUST_CFA_OFFSET RBP617728618729 testb $3, CS(%rsp)619730 jz retint_kernel620731 /* Interrupt came from user space */621621-732732+retint_user:622733 GET_THREAD_INFO(%rcx)623734 /*624735 * %rcx: thread info. Interrupts off.···626743 LOCKDEP_SYS_EXIT_IRQ627744 movl TI_flags(%rcx),%edx628745 andl %edi,%edx629629- CFI_REMEMBER_STATE630746 jnz retint_careful631747632748retint_swapgs: /* return to user-space */···663781restore_c_regs_and_iret:664782 RESTORE_C_REGS665783 REMOVE_PT_GPREGS_FROM_STACK 8666666-667667-irq_return:668784 INTERRUPT_RETURN669785670786ENTRY(native_iret)···687807688808#ifdef CONFIG_X86_ESPFIX64689809native_irq_return_ldt:690690- pushq_cfi %rax691691- pushq_cfi %rdi810810+ pushq %rax811811+ pushq %rdi692812 SWAPGS693813 movq PER_CPU_VAR(espfix_waddr),%rdi694814 movq %rax,(0*8)(%rdi) /* RAX */···703823 movq (5*8)(%rsp),%rax /* RSP */704824 movq %rax,(4*8)(%rdi)705825 andl $0xffff0000,%eax706706- popq_cfi %rdi826826+ popq %rdi707827 orq PER_CPU_VAR(espfix_stack),%rax708828 SWAPGS709829 movq %rax,%rsp710710- popq_cfi %rax830830+ popq %rax711831 jmp native_irq_return_iret712832#endif713833714834 /* edi: workmask, edx: work */715835retint_careful:716716- CFI_RESTORE_STATE717836 bt $TIF_NEED_RESCHED,%edx718837 jnc retint_signal719838 TRACE_IRQS_ON720839 ENABLE_INTERRUPTS(CLBR_NONE)721721- pushq_cfi %rdi840840+ pushq %rdi722841 SCHEDULE_USER723723- popq_cfi %rdi842842+ popq %rdi724843 GET_THREAD_INFO(%rcx)725844 DISABLE_INTERRUPTS(CLBR_NONE)726845 TRACE_IRQS_OFF···741862 GET_THREAD_INFO(%rcx)742863 jmp retint_with_reschedule743864744744- CFI_ENDPROC745865END(common_interrupt)746866747867/*···748870 */749871.macro apicinterrupt3 num sym do_sym750872ENTRY(\sym)751751- INTR_FRAME752873 ASM_CLAC753753- pushq_cfi $~(\num)874874+ pushq $~(\num)754875.Lcommon_\sym:755876 interrupt \do_sym756877 jmp ret_from_intr757757- CFI_ENDPROC758878END(\sym)759879.endm760880···842966 .error "using shift_ist requires paranoid=1"843967 .endif844968845845- .if \has_error_code846846- XCPT_FRAME847847- .else848848- INTR_FRAME849849- .endif850850-851969 ASM_CLAC852970 PARAVIRT_ADJUST_EXCEPTION_FRAME853971854972 .ifeq \has_error_code855855- pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */973973+ pushq $-1 /* ORIG_RAX: no syscall to restart */856974 .endif857975858976 ALLOC_PT_GPREGS_ON_STACK859977860978 .if \paranoid861979 .if \paranoid == 1862862- CFI_REMEMBER_STATE863980 testb $3, CS(%rsp) /* If coming from userspace, switch */864981 jnz 1f /* stacks. */865982 .endif···861992 call error_entry862993 .endif863994 /* returned flag: ebx=0: need swapgs on exit, ebx=1: don't need it */864864-865865- DEFAULT_FRAME 0866995867996 .if \paranoid868997 .if \shift_ist != -1···8971030 .endif89810318991032 .if \paranoid == 1900900- CFI_RESTORE_STATE9011033 /*9021034 * Paranoid entry from userspace. Switch stacks and treat it9031035 * as a normal entry. This means that paranoid handlers···90510391:9061040 call error_entry9071041908908- DEFAULT_FRAME 090910429101043 movq %rsp,%rdi /* pt_regs pointer */9111044 call sync_regs···92310589241059 jmp error_exit /* %ebx: no swapgs flag */9251060 .endif926926-927927- CFI_ENDPROC9281061END(\sym)9291062.endm9301063···9551092 /* Reload gs selector with exception handling */9561093 /* edi: new selector */9571094ENTRY(native_load_gs_index)958958- CFI_STARTPROC959959- pushfq_cfi10951095+ pushfq9601096 DISABLE_INTERRUPTS(CLBR_ANY & ~CLBR_RDI)9611097 SWAPGS9621098gs_change:9631099 movl %edi,%gs96411002: mfence /* workaround */9651101 SWAPGS966966- popfq_cfi11021102+ popfq9671103 ret968968- CFI_ENDPROC9691104END(native_load_gs_index)97011059711106 _ASM_EXTABLE(gs_change,bad_gs)···97811179791118/* Call softirq on interrupt stack. Interrupts are off. */9801119ENTRY(do_softirq_own_stack)981981- CFI_STARTPROC982982- pushq_cfi %rbp983983- CFI_REL_OFFSET rbp,011201120+ pushq %rbp9841121 mov %rsp,%rbp985985- CFI_DEF_CFA_REGISTER rbp9861122 incl PER_CPU_VAR(irq_count)9871123 cmove PER_CPU_VAR(irq_stack_ptr),%rsp9881124 push %rbp # backlink for old unwinder9891125 call __do_softirq9901126 leaveq991991- CFI_RESTORE rbp992992- CFI_DEF_CFA_REGISTER rsp993993- CFI_ADJUST_CFA_OFFSET -89941127 decl PER_CPU_VAR(irq_count)9951128 ret996996- CFI_ENDPROC9971129END(do_softirq_own_stack)99811309991131#ifdef CONFIG_XEN···10061152 * activation and restart the handler using the previous one.10071153 */10081154ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs)10091009- CFI_STARTPROC10101155/*10111156 * Since we don't modify %rdi, evtchn_do_upall(struct *pt_regs) will10121157 * see the correct pointer to the pt_regs10131158 */10141159 movq %rdi, %rsp # we don't return, adjust the stack frame10151015- CFI_ENDPROC10161016- DEFAULT_FRAME1017116011: incl PER_CPU_VAR(irq_count)10181161 movq %rsp,%rbp10191019- CFI_DEF_CFA_REGISTER rbp10201162 cmovzq PER_CPU_VAR(irq_stack_ptr),%rsp10211163 pushq %rbp # backlink for old unwinder10221164 call xen_evtchn_do_upcall10231165 popq %rsp10241024- CFI_DEF_CFA_REGISTER rsp10251166 decl PER_CPU_VAR(irq_count)10261167#ifndef CONFIG_PREEMPT10271168 call xen_maybe_preempt_hcall10281169#endif10291170 jmp error_exit10301030- CFI_ENDPROC10311171END(xen_do_hypervisor_callback)1032117210331173/*···10381190 * with its current contents: any discrepancy means we in category 1.10391191 */10401192ENTRY(xen_failsafe_callback)10411041- INTR_FRAME 1 (6*8)10421042- /*CFI_REL_OFFSET gs,GS*/10431043- /*CFI_REL_OFFSET fs,FS*/10441044- /*CFI_REL_OFFSET es,ES*/10451045- /*CFI_REL_OFFSET ds,DS*/10461046- CFI_REL_OFFSET r11,810471047- CFI_REL_OFFSET rcx,010481193 movl %ds,%ecx10491194 cmpw %cx,0x10(%rsp)10501050- CFI_REMEMBER_STATE10511195 jne 1f10521196 movl %es,%ecx10531197 cmpw %cx,0x18(%rsp)···10521212 jne 1f10531213 /* All segments match their saved values => Category 2 (Bad IRET). */10541214 movq (%rsp),%rcx10551055- CFI_RESTORE rcx10561215 movq 8(%rsp),%r1110571057- CFI_RESTORE r1110581216 addq $0x30,%rsp10591059- CFI_ADJUST_CFA_OFFSET -0x3010601060- pushq_cfi $0 /* RIP */10611061- pushq_cfi %r1110621062- pushq_cfi %rcx12171217+ pushq $0 /* RIP */12181218+ pushq %r1112191219+ pushq %rcx10631220 jmp general_protection10641064- CFI_RESTORE_STATE106512211: /* Segment mismatch => Category 1 (Bad segment). Retry the IRET. */10661222 movq (%rsp),%rcx10671067- CFI_RESTORE rcx10681223 movq 8(%rsp),%r1110691069- CFI_RESTORE r1110701224 addq $0x30,%rsp10711071- CFI_ADJUST_CFA_OFFSET -0x3010721072- pushq_cfi $-1 /* orig_ax = -1 => not a system call */12251225+ pushq $-1 /* orig_ax = -1 => not a system call */10731226 ALLOC_PT_GPREGS_ON_STACK10741227 SAVE_C_REGS10751228 SAVE_EXTRA_REGS10761229 jmp error_exit10771077- CFI_ENDPROC10781230END(xen_failsafe_callback)1079123110801232apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \···11021270 * Return: ebx=0: need swapgs on exit, ebx=1: otherwise11031271 */11041272ENTRY(paranoid_entry)11051105- XCPT_FRAME 1 15*811061273 cld11071274 SAVE_C_REGS 811081275 SAVE_EXTRA_REGS 8···11131282 SWAPGS11141283 xorl %ebx,%ebx111512841: ret11161116- CFI_ENDPROC11171285END(paranoid_entry)1118128611191287/*···11271297 */11281298/* On entry, ebx is "no swapgs" flag (1: don't need swapgs, 0: need it) */11291299ENTRY(paranoid_exit)11301130- DEFAULT_FRAME11311300 DISABLE_INTERRUPTS(CLBR_NONE)11321301 TRACE_IRQS_OFF_DEBUG11331302 testl %ebx,%ebx /* swapgs needed? */···11411312 RESTORE_C_REGS11421313 REMOVE_PT_GPREGS_FROM_STACK 811431314 INTERRUPT_RETURN11441144- CFI_ENDPROC11451315END(paranoid_exit)1146131611471317/*···11481320 * Return: ebx=0: need swapgs on exit, ebx=1: otherwise11491321 */11501322ENTRY(error_entry)11511151- XCPT_FRAME 1 15*811521323 cld11531324 SAVE_C_REGS 811541325 SAVE_EXTRA_REGS 8···11671340 * for these here too.11681341 */11691342error_kernelspace:11701170- CFI_REL_OFFSET rcx, RCX+811711343 incl %ebx11721344 leaq native_irq_return_iret(%rip),%rcx11731345 cmpq %rcx,RIP+8(%rsp)···11901364 mov %rax,%rsp11911365 decl %ebx /* Return to usergs */11921366 jmp error_sti11931193- CFI_ENDPROC11941367END(error_entry)119513681196136911971370/* On entry, ebx is "no swapgs" flag (1: don't need swapgs, 0: need it) */11981371ENTRY(error_exit)11991199- DEFAULT_FRAME12001372 movl %ebx,%eax12011373 RESTORE_EXTRA_REGS12021374 DISABLE_INTERRUPTS(CLBR_NONE)12031375 TRACE_IRQS_OFF12041204- GET_THREAD_INFO(%rcx)12051376 testl %eax,%eax12061377 jnz retint_kernel12071207- LOCKDEP_SYS_EXIT_IRQ12081208- movl TI_flags(%rcx),%edx12091209- movl $_TIF_WORK_MASK,%edi12101210- andl %edi,%edx12111211- jnz retint_careful12121212- jmp retint_swapgs12131213- CFI_ENDPROC13781378+ jmp retint_user12141379END(error_exit)1215138012161381/* Runs on exception stack */12171382ENTRY(nmi)12181218- INTR_FRAME12191383 PARAVIRT_ADJUST_EXCEPTION_FRAME12201384 /*12211385 * We allow breakpoints in NMIs. If a breakpoint occurs, then···12401424 */1241142512421426 /* Use %rdx as our temp variable throughout */12431243- pushq_cfi %rdx12441244- CFI_REL_OFFSET rdx, 014271427+ pushq %rdx1245142812461429 /*12471430 * If %cs was not the kernel segment, then the NMI triggered in user···12741459 jb first_nmi12751460 /* Ah, it is within the NMI stack, treat it as nested */1276146112771277- CFI_REMEMBER_STATE12781278-12791462nested_nmi:12801463 /*12811464 * Do nothing if we interrupted the fixup in repeat_nmi.···12911478 /* Set up the interrupted NMIs stack to jump to repeat_nmi */12921479 leaq -1*8(%rsp), %rdx12931480 movq %rdx, %rsp12941294- CFI_ADJUST_CFA_OFFSET 1*812951481 leaq -10*8(%rsp), %rdx12961296- pushq_cfi $__KERNEL_DS12971297- pushq_cfi %rdx12981298- pushfq_cfi12991299- pushq_cfi $__KERNEL_CS13001300- pushq_cfi $repeat_nmi14821482+ pushq $__KERNEL_DS14831483+ pushq %rdx14841484+ pushfq14851485+ pushq $__KERNEL_CS14861486+ pushq $repeat_nmi1301148713021488 /* Put stack back */13031489 addq $(6*8), %rsp13041304- CFI_ADJUST_CFA_OFFSET -6*81305149013061491nested_nmi_out:13071307- popq_cfi %rdx13081308- CFI_RESTORE rdx14921492+ popq %rdx1309149313101494 /* No need to check faults here */13111495 INTERRUPT_RETURN1312149613131313- CFI_RESTORE_STATE13141497first_nmi:13151498 /*13161499 * Because nested NMIs will use the pushed location that we···13451536 */13461537 /* Do not pop rdx, nested NMIs will corrupt that part of the stack */13471538 movq (%rsp), %rdx13481348- CFI_RESTORE rdx1349153913501540 /* Set the NMI executing variable on the stack. */13511351- pushq_cfi $115411541+ pushq $11352154213531543 /*13541544 * Leave room for the "copied" frame13551545 */13561546 subq $(5*8), %rsp13571357- CFI_ADJUST_CFA_OFFSET 5*81358154713591548 /* Copy the stack frame to the Saved frame */13601549 .rept 513611361- pushq_cfi 11*8(%rsp)15501550+ pushq 11*8(%rsp)13621551 .endr13631363- CFI_DEF_CFA_OFFSET 5*81364155213651553 /* Everything up to here is safe from nested NMIs */13661554···1380157413811575 /* Make another copy, this one may be modified by nested NMIs */13821576 addq $(10*8), %rsp13831383- CFI_ADJUST_CFA_OFFSET -10*813841577 .rept 513851385- pushq_cfi -6*8(%rsp)15781578+ pushq -6*8(%rsp)13861579 .endr13871580 subq $(5*8), %rsp13881388- CFI_DEF_CFA_OFFSET 5*813891581end_repeat_nmi:1390158213911583 /*···13911587 * NMI if the first NMI took an exception and reset our iret stack13921588 * so that we repeat another NMI.13931589 */13941394- pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */15901590+ pushq $-1 /* ORIG_RAX: no syscall to restart */13951591 ALLOC_PT_GPREGS_ON_STACK1396159213971593 /*···14021598 * exceptions might do.14031599 */14041600 call paranoid_entry14051405- DEFAULT_FRAME 01406160114071602 /*14081603 * Save off the CR2 register. If we take a page fault in the NMI then···1437163414381635 /* Clear the NMI executing stack variable */14391636 movq $0, 5*8(%rsp)14401440- jmp irq_return14411441- CFI_ENDPROC16371637+ INTERRUPT_RETURN14421638END(nmi)1443163914441640ENTRY(ignore_sysret)14451445- CFI_STARTPROC14461641 mov $-ENOSYS,%eax14471642 sysret14481448- CFI_ENDPROC14491643END(ignore_sysret)14501644
+1-1
arch/x86/kernel/head64.c
···167167 clear_bss();168168169169 for (i = 0; i < NUM_EXCEPTION_VECTORS; i++)170170- set_intr_gate(i, early_idt_handlers[i]);170170+ set_intr_gate(i, early_idt_handler_array[i]);171171 load_idt((const struct desc_ptr *)&idt_descr);172172173173 copy_bootdata(__va(real_mode_data));
+18-15
arch/x86/kernel/head_32.S
···478478__INIT479479setup_once:480480 /*481481- * Set up a idt with 256 entries pointing to ignore_int,482482- * interrupt gates. It doesn't actually load idt - that needs483483- * to be done on each CPU. Interrupts are enabled elsewhere,484484- * when we can be relatively sure everything is ok.481481+ * Set up a idt with 256 interrupt gates that push zero if there482482+ * is no error code and then jump to early_idt_handler_common.483483+ * It doesn't actually load the idt - that needs to be done on484484+ * each CPU. Interrupts are enabled elsewhere, when we can be485485+ * relatively sure everything is ok.485486 */486487487488 movl $idt_table,%edi488488- movl $early_idt_handlers,%eax489489+ movl $early_idt_handler_array,%eax489490 movl $NUM_EXCEPTION_VECTORS,%ecx4904911:491492 movl %eax,(%edi)492493 movl %eax,4(%edi)493494 /* interrupt gate, dpl=0, present */494495 movl $(0x8E000000 + __KERNEL_CS),2(%edi)495495- addl $9,%eax496496+ addl $EARLY_IDT_HANDLER_SIZE,%eax496497 addl $8,%edi497498 loop 1b498499···525524 andl $0,setup_once_ref /* Once is enough, thanks */526525 ret527526528528-ENTRY(early_idt_handlers)527527+ENTRY(early_idt_handler_array)529528 # 36(%esp) %eflags530529 # 32(%esp) %cs531530 # 28(%esp) %eip532531 # 24(%rsp) error code533532 i = 0534533 .rept NUM_EXCEPTION_VECTORS535535- .if (EXCEPTION_ERRCODE_MASK >> i) & 1536536- ASM_NOP2537537- .else534534+ .ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1538535 pushl $0 # Dummy error code, to make stack frame uniform539536 .endif540537 pushl $i # 20(%esp) Vector number541541- jmp early_idt_handler538538+ jmp early_idt_handler_common542539 i = i + 1540540+ .fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc543541 .endr544544-ENDPROC(early_idt_handlers)542542+ENDPROC(early_idt_handler_array)545543546546- /* This is global to keep gas from relaxing the jumps */547547-ENTRY(early_idt_handler)544544+early_idt_handler_common:545545+ /*546546+ * The stack is the hardware frame, an error code or zero, and the547547+ * vector number.548548+ */548549 cld549550550551 cmpl $2,(%esp) # X86_TRAP_NMI···606603.Lis_nmi:607604 addl $8,%esp /* drop vector number and error code */608605 iret609609-ENDPROC(early_idt_handler)606606+ENDPROC(early_idt_handler_common)610607611608/* This is the default interrupt "handler" :-) */612609 ALIGN
+11-9
arch/x86/kernel/head_64.S
···321321 jmp bad_address322322323323 __INIT324324- .globl early_idt_handlers325325-early_idt_handlers:324324+ENTRY(early_idt_handler_array)326325 # 104(%rsp) %rflags327326 # 96(%rsp) %cs328327 # 88(%rsp) %rip329328 # 80(%rsp) error code330329 i = 0331330 .rept NUM_EXCEPTION_VECTORS332332- .if (EXCEPTION_ERRCODE_MASK >> i) & 1333333- ASM_NOP2334334- .else331331+ .ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1335332 pushq $0 # Dummy error code, to make stack frame uniform336333 .endif337334 pushq $i # 72(%rsp) Vector number338338- jmp early_idt_handler335335+ jmp early_idt_handler_common339336 i = i + 1337337+ .fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc340338 .endr339339+ENDPROC(early_idt_handler_array)341340342342-/* This is global to keep gas from relaxing the jumps */343343-ENTRY(early_idt_handler)341341+early_idt_handler_common:342342+ /*343343+ * The stack is the hardware frame, an error code or zero, and the344344+ * vector number.345345+ */344346 cld345347346348 cmpl $2,(%rsp) # X86_TRAP_NMI···414412.Lis_nmi:415413 addq $16,%rsp # drop vector number and error code416414 INTERRUPT_RETURN417417-ENDPROC(early_idt_handler)415415+ENDPROC(early_idt_handler_common)418416419417 __INITDATA420418
···7272#else7373#include <asm/processor-flags.h>7474#include <asm/setup.h>7575-7676-asmlinkage int system_call(void);7575+#include <asm/proto.h>7776#endif78777978/* Must be page-aligned because the real IDT is used in a fixmap. */···979980 set_bit(i, used_vectors);980981981982#ifdef CONFIG_IA32_EMULATION982982- set_system_intr_gate(IA32_SYSCALL_VECTOR, ia32_syscall);983983+ set_system_intr_gate(IA32_SYSCALL_VECTOR, entry_INT80_compat);983984 set_bit(IA32_SYSCALL_VECTOR, used_vectors);984985#endif985986986987#ifdef CONFIG_X86_32987987- set_system_trap_gate(IA32_SYSCALL_VECTOR, &system_call);988988+ set_system_trap_gate(IA32_SYSCALL_VECTOR, entry_INT80_32);988989 set_bit(IA32_SYSCALL_VECTOR, used_vectors);989990#endif990991
···1111 * return value.1212 */1313#include <linux/linkage.h>1414-#include <asm/dwarf2.h>1514#include <asm/thread_info.h>1615#include <asm/errno.h>1716#include <asm/asm.h>···2930 * as they get called from within inline assembly.3031 */31323232-#define ENTER CFI_STARTPROC ; \3333- GET_THREAD_INFO(%_ASM_BX)3333+#define ENTER GET_THREAD_INFO(%_ASM_BX)3434#define EXIT ASM_CLAC ; \3535- ret ; \3636- CFI_ENDPROC3535+ ret37363837.text3938ENTRY(__put_user_1)···8487ENDPROC(__put_user_8)85888689bad_put_user:8787- CFI_STARTPROC8890 movl $-EFAULT,%eax8991 EXIT9092END(bad_put_user)