diff options
Diffstat (limited to 'arch/x86/kernel/entry_32.S')
-rw-r--r-- | arch/x86/kernel/entry_32.S | 84 |
1 files changed, 79 insertions, 5 deletions
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 2a609dc3271c..6bc07f0f1202 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
@@ -51,14 +51,15 @@ | |||
51 | #include <asm/percpu.h> | 51 | #include <asm/percpu.h> |
52 | #include <asm/dwarf2.h> | 52 | #include <asm/dwarf2.h> |
53 | #include <asm/processor-flags.h> | 53 | #include <asm/processor-flags.h> |
54 | #include "irq_vectors.h" | 54 | #include <asm/ftrace.h> |
55 | #include <asm/irq_vectors.h> | ||
55 | 56 | ||
56 | /* | 57 | /* |
57 | * We use macros for low-level operations which need to be overridden | 58 | * We use macros for low-level operations which need to be overridden |
58 | * for paravirtualization. The following will never clobber any registers: | 59 | * for paravirtualization. The following will never clobber any registers: |
59 | * INTERRUPT_RETURN (aka. "iret") | 60 | * INTERRUPT_RETURN (aka. "iret") |
60 | * GET_CR0_INTO_EAX (aka. "movl %cr0, %eax") | 61 | * GET_CR0_INTO_EAX (aka. "movl %cr0, %eax") |
61 | * ENABLE_INTERRUPTS_SYSCALL_RET (aka "sti; sysexit"). | 62 | * ENABLE_INTERRUPTS_SYSEXIT (aka "sti; sysexit"). |
62 | * | 63 | * |
63 | * For DISABLE_INTERRUPTS/ENABLE_INTERRUPTS (aka "cli"/"sti"), you must | 64 | * For DISABLE_INTERRUPTS/ENABLE_INTERRUPTS (aka "cli"/"sti"), you must |
64 | * specify what registers can be overwritten (CLBR_NONE, CLBR_EAX/EDX/ECX/ANY). | 65 | * specify what registers can be overwritten (CLBR_NONE, CLBR_EAX/EDX/ECX/ANY). |
@@ -248,6 +249,7 @@ ENTRY(resume_userspace) | |||
248 | DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt | 249 | DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt |
249 | # setting need_resched or sigpending | 250 | # setting need_resched or sigpending |
250 | # between sampling and the iret | 251 | # between sampling and the iret |
252 | TRACE_IRQS_OFF | ||
251 | movl TI_flags(%ebp), %ecx | 253 | movl TI_flags(%ebp), %ecx |
252 | andl $_TIF_WORK_MASK, %ecx # is there any work to be done on | 254 | andl $_TIF_WORK_MASK, %ecx # is there any work to be done on |
253 | # int/exception return? | 255 | # int/exception return? |
@@ -348,7 +350,7 @@ sysenter_past_esp: | |||
348 | xorl %ebp,%ebp | 350 | xorl %ebp,%ebp |
349 | TRACE_IRQS_ON | 351 | TRACE_IRQS_ON |
350 | 1: mov PT_FS(%esp), %fs | 352 | 1: mov PT_FS(%esp), %fs |
351 | ENABLE_INTERRUPTS_SYSCALL_RET | 353 | ENABLE_INTERRUPTS_SYSEXIT |
352 | CFI_ENDPROC | 354 | CFI_ENDPROC |
353 | .pushsection .fixup,"ax" | 355 | .pushsection .fixup,"ax" |
354 | 2: movl $0,PT_FS(%esp) | 356 | 2: movl $0,PT_FS(%esp) |
@@ -873,10 +875,10 @@ ENTRY(native_iret) | |||
873 | .previous | 875 | .previous |
874 | END(native_iret) | 876 | END(native_iret) |
875 | 877 | ||
876 | ENTRY(native_irq_enable_syscall_ret) | 878 | ENTRY(native_irq_enable_sysexit) |
877 | sti | 879 | sti |
878 | sysexit | 880 | sysexit |
879 | END(native_irq_enable_syscall_ret) | 881 | END(native_irq_enable_sysexit) |
880 | #endif | 882 | #endif |
881 | 883 | ||
882 | KPROBE_ENTRY(int3) | 884 | KPROBE_ENTRY(int3) |
@@ -1023,6 +1025,7 @@ ENTRY(xen_sysenter_target) | |||
1023 | RING0_INT_FRAME | 1025 | RING0_INT_FRAME |
1024 | addl $5*4, %esp /* remove xen-provided frame */ | 1026 | addl $5*4, %esp /* remove xen-provided frame */ |
1025 | jmp sysenter_past_esp | 1027 | jmp sysenter_past_esp |
1028 | CFI_ENDPROC | ||
1026 | 1029 | ||
1027 | ENTRY(xen_hypervisor_callback) | 1030 | ENTRY(xen_hypervisor_callback) |
1028 | CFI_STARTPROC | 1031 | CFI_STARTPROC |
@@ -1109,6 +1112,77 @@ ENDPROC(xen_failsafe_callback) | |||
1109 | 1112 | ||
1110 | #endif /* CONFIG_XEN */ | 1113 | #endif /* CONFIG_XEN */ |
1111 | 1114 | ||
1115 | #ifdef CONFIG_FTRACE | ||
1116 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
1117 | |||
1118 | ENTRY(mcount) | ||
1119 | pushl %eax | ||
1120 | pushl %ecx | ||
1121 | pushl %edx | ||
1122 | movl 0xc(%esp), %eax | ||
1123 | subl $MCOUNT_INSN_SIZE, %eax | ||
1124 | |||
1125 | .globl mcount_call | ||
1126 | mcount_call: | ||
1127 | call ftrace_stub | ||
1128 | |||
1129 | popl %edx | ||
1130 | popl %ecx | ||
1131 | popl %eax | ||
1132 | |||
1133 | ret | ||
1134 | END(mcount) | ||
1135 | |||
1136 | ENTRY(ftrace_caller) | ||
1137 | pushl %eax | ||
1138 | pushl %ecx | ||
1139 | pushl %edx | ||
1140 | movl 0xc(%esp), %eax | ||
1141 | movl 0x4(%ebp), %edx | ||
1142 | subl $MCOUNT_INSN_SIZE, %eax | ||
1143 | |||
1144 | .globl ftrace_call | ||
1145 | ftrace_call: | ||
1146 | call ftrace_stub | ||
1147 | |||
1148 | popl %edx | ||
1149 | popl %ecx | ||
1150 | popl %eax | ||
1151 | |||
1152 | .globl ftrace_stub | ||
1153 | ftrace_stub: | ||
1154 | ret | ||
1155 | END(ftrace_caller) | ||
1156 | |||
1157 | #else /* ! CONFIG_DYNAMIC_FTRACE */ | ||
1158 | |||
1159 | ENTRY(mcount) | ||
1160 | cmpl $ftrace_stub, ftrace_trace_function | ||
1161 | jnz trace | ||
1162 | .globl ftrace_stub | ||
1163 | ftrace_stub: | ||
1164 | ret | ||
1165 | |||
1166 | /* taken from glibc */ | ||
1167 | trace: | ||
1168 | pushl %eax | ||
1169 | pushl %ecx | ||
1170 | pushl %edx | ||
1171 | movl 0xc(%esp), %eax | ||
1172 | movl 0x4(%ebp), %edx | ||
1173 | subl $MCOUNT_INSN_SIZE, %eax | ||
1174 | |||
1175 | call *ftrace_trace_function | ||
1176 | |||
1177 | popl %edx | ||
1178 | popl %ecx | ||
1179 | popl %eax | ||
1180 | |||
1181 | jmp ftrace_stub | ||
1182 | END(mcount) | ||
1183 | #endif /* CONFIG_DYNAMIC_FTRACE */ | ||
1184 | #endif /* CONFIG_FTRACE */ | ||
1185 | |||
1112 | .section .rodata,"a" | 1186 | .section .rodata,"a" |
1113 | #include "syscall_table_32.S" | 1187 | #include "syscall_table_32.S" |
1114 | 1188 | ||