]> Pileus Git - ~andy/linux/blobdiff - arch/x86/kernel/entry_32.S
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
[~andy/linux] / arch / x86 / kernel / entry_32.S
index b6bb6923929631106bf8562787b2daf396551b10..8f9ed1afde8f28565a9e9325e4ecc3f61a3fc089 100644 (file)
@@ -57,6 +57,7 @@
 #include <asm/cpufeature.h>
 #include <asm/alternative-asm.h>
 #include <asm/asm.h>
+#include <asm/smap.h>
 
 /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this.  */
 #include <linux/elf-em.h>
@@ -413,7 +414,9 @@ sysenter_past_esp:
  */
        cmpl $__PAGE_OFFSET-3,%ebp
        jae syscall_fault
+       ASM_STAC
 1:     movl (%ebp),%ebp
+       ASM_CLAC
        movl %ebp,PT_EBP(%esp)
        _ASM_EXTABLE(1b,syscall_fault)
 
@@ -494,6 +497,7 @@ ENDPROC(ia32_sysenter_target)
        # system call handler stub
 ENTRY(system_call)
        RING0_INT_FRAME                 # can't unwind into user space anyway
+       ASM_CLAC
        pushl_cfi %eax                  # save orig_eax
        SAVE_ALL
        GET_THREAD_INFO(%ebp)
@@ -676,6 +680,7 @@ END(syscall_exit_work)
 
        RING0_INT_FRAME                 # can't unwind into user space anyway
 syscall_fault:
+       ASM_CLAC
        GET_THREAD_INFO(%ebp)
        movl $-EFAULT,PT_EAX(%esp)
        jmp resume_userspace
@@ -830,6 +835,7 @@ END(interrupt)
  */
        .p2align CONFIG_X86_L1_CACHE_SHIFT
 common_interrupt:
+       ASM_CLAC
        addl $-0x80,(%esp)      /* Adjust vector into the [-256,-1] range */
        SAVE_ALL
        TRACE_IRQS_OFF
@@ -846,6 +852,7 @@ ENDPROC(common_interrupt)
 #define BUILD_INTERRUPT3(name, nr, fn) \
 ENTRY(name)                            \
        RING0_INT_FRAME;                \
+       ASM_CLAC;                       \
        pushl_cfi $~(nr);               \
        SAVE_ALL;                       \
        TRACE_IRQS_OFF                  \
@@ -862,6 +869,7 @@ ENDPROC(name)
 
 ENTRY(coprocessor_error)
        RING0_INT_FRAME
+       ASM_CLAC
        pushl_cfi $0
        pushl_cfi $do_coprocessor_error
        jmp error_code
@@ -870,6 +878,7 @@ END(coprocessor_error)
 
 ENTRY(simd_coprocessor_error)
        RING0_INT_FRAME
+       ASM_CLAC
        pushl_cfi $0
 #ifdef CONFIG_X86_INVD_BUG
        /* AMD 486 bug: invd from userspace calls exception 19 instead of #GP */
@@ -891,6 +900,7 @@ END(simd_coprocessor_error)
 
 ENTRY(device_not_available)
        RING0_INT_FRAME
+       ASM_CLAC
        pushl_cfi $-1                   # mark this as an int
        pushl_cfi $do_device_not_available
        jmp error_code
@@ -911,6 +921,7 @@ END(native_irq_enable_sysexit)
 
 ENTRY(overflow)
        RING0_INT_FRAME
+       ASM_CLAC
        pushl_cfi $0
        pushl_cfi $do_overflow
        jmp error_code
@@ -919,6 +930,7 @@ END(overflow)
 
 ENTRY(bounds)
        RING0_INT_FRAME
+       ASM_CLAC
        pushl_cfi $0
        pushl_cfi $do_bounds
        jmp error_code
@@ -927,6 +939,7 @@ END(bounds)
 
 ENTRY(invalid_op)
        RING0_INT_FRAME
+       ASM_CLAC
        pushl_cfi $0
        pushl_cfi $do_invalid_op
        jmp error_code
@@ -935,6 +948,7 @@ END(invalid_op)
 
 ENTRY(coprocessor_segment_overrun)
        RING0_INT_FRAME
+       ASM_CLAC
        pushl_cfi $0
        pushl_cfi $do_coprocessor_segment_overrun
        jmp error_code
@@ -943,6 +957,7 @@ END(coprocessor_segment_overrun)
 
 ENTRY(invalid_TSS)
        RING0_EC_FRAME
+       ASM_CLAC
        pushl_cfi $do_invalid_TSS
        jmp error_code
        CFI_ENDPROC
@@ -950,6 +965,7 @@ END(invalid_TSS)
 
 ENTRY(segment_not_present)
        RING0_EC_FRAME
+       ASM_CLAC
        pushl_cfi $do_segment_not_present
        jmp error_code
        CFI_ENDPROC
@@ -957,6 +973,7 @@ END(segment_not_present)
 
 ENTRY(stack_segment)
        RING0_EC_FRAME
+       ASM_CLAC
        pushl_cfi $do_stack_segment
        jmp error_code
        CFI_ENDPROC
@@ -964,6 +981,7 @@ END(stack_segment)
 
 ENTRY(alignment_check)
        RING0_EC_FRAME
+       ASM_CLAC
        pushl_cfi $do_alignment_check
        jmp error_code
        CFI_ENDPROC
@@ -971,6 +989,7 @@ END(alignment_check)
 
 ENTRY(divide_error)
        RING0_INT_FRAME
+       ASM_CLAC
        pushl_cfi $0                    # no error code
        pushl_cfi $do_divide_error
        jmp error_code
@@ -980,6 +999,7 @@ END(divide_error)
 #ifdef CONFIG_X86_MCE
 ENTRY(machine_check)
        RING0_INT_FRAME
+       ASM_CLAC
        pushl_cfi $0
        pushl_cfi machine_check_vector
        jmp error_code
@@ -989,6 +1009,7 @@ END(machine_check)
 
 ENTRY(spurious_interrupt_bug)
        RING0_INT_FRAME
+       ASM_CLAC
        pushl_cfi $0
        pushl_cfi $do_spurious_interrupt_bug
        jmp error_code
@@ -1119,17 +1140,21 @@ ENTRY(ftrace_caller)
        pushl %eax
        pushl %ecx
        pushl %edx
-       movl 0xc(%esp), %eax
+       pushl $0        /* Pass NULL as regs pointer */
+       movl 4*4(%esp), %eax
        movl 0x4(%ebp), %edx
+       leal function_trace_op, %ecx
        subl $MCOUNT_INSN_SIZE, %eax
 
 .globl ftrace_call
 ftrace_call:
        call ftrace_stub
 
+       addl $4,%esp    /* skip NULL pointer */
        popl %edx
        popl %ecx
        popl %eax
+ftrace_ret:
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 .globl ftrace_graph_call
 ftrace_graph_call:
@@ -1141,6 +1166,71 @@ ftrace_stub:
        ret
 END(ftrace_caller)
 
+ENTRY(ftrace_regs_caller)
+       pushf   /* push flags before compare (in cs location) */
+       cmpl $0, function_trace_stop
+       jne ftrace_restore_flags
+
+       /*
+        * i386 does not save SS and ESP when coming from kernel.
+        * Instead, to get sp, &regs->sp is used (see ptrace.h).
+        * Unfortunately, that means eflags must be at the same location
+        * as the current return ip is. We move the return ip into the
+        * ip location, and move flags into the return ip location.
+        */
+       pushl 4(%esp)   /* save return ip into ip slot */
+
+       pushl $0        /* Load 0 into orig_ax */
+       pushl %gs
+       pushl %fs
+       pushl %es
+       pushl %ds
+       pushl %eax
+       pushl %ebp
+       pushl %edi
+       pushl %esi
+       pushl %edx
+       pushl %ecx
+       pushl %ebx
+
+       movl 13*4(%esp), %eax   /* Get the saved flags */
+       movl %eax, 14*4(%esp)   /* Move saved flags into regs->flags location */
+                               /* clobbering return ip */
+       movl $__KERNEL_CS,13*4(%esp)
+
+       movl 12*4(%esp), %eax   /* Load ip (1st parameter) */
+       subl $MCOUNT_INSN_SIZE, %eax    /* Adjust ip */
+       movl 0x4(%ebp), %edx    /* Load parent ip (2nd parameter) */
+       leal function_trace_op, %ecx /* Save ftrace_pos in 3rd parameter */
+       pushl %esp              /* Save pt_regs as 4th parameter */
+
+GLOBAL(ftrace_regs_call)
+       call ftrace_stub
+
+       addl $4, %esp           /* Skip pt_regs */
+       movl 14*4(%esp), %eax   /* Move flags back into cs */
+       movl %eax, 13*4(%esp)   /* Needed to keep addl from modifying flags */
+       movl 12*4(%esp), %eax   /* Get return ip from regs->ip */
+       movl %eax, 14*4(%esp)   /* Put return ip back for ret */
+
+       popl %ebx
+       popl %ecx
+       popl %edx
+       popl %esi
+       popl %edi
+       popl %ebp
+       popl %eax
+       popl %ds
+       popl %es
+       popl %fs
+       popl %gs
+       addl $8, %esp           /* Skip orig_ax and ip */
+       popf                    /* Pop flags at end (no addl to corrupt flags) */
+       jmp ftrace_ret
+
+ftrace_restore_flags:
+       popf
+       jmp  ftrace_stub
 #else /* ! CONFIG_DYNAMIC_FTRACE */
 
 ENTRY(mcount)
@@ -1181,9 +1271,6 @@ END(mcount)
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 ENTRY(ftrace_graph_caller)
-       cmpl $0, function_trace_stop
-       jne ftrace_stub
-
        pushl %eax
        pushl %ecx
        pushl %edx
@@ -1217,6 +1304,7 @@ return_to_handler:
 
 ENTRY(page_fault)
        RING0_EC_FRAME
+       ASM_CLAC
        pushl_cfi $do_page_fault
        ALIGN
 error_code:
@@ -1289,6 +1377,7 @@ END(page_fault)
 
 ENTRY(debug)
        RING0_INT_FRAME
+       ASM_CLAC
        cmpl $ia32_sysenter_target,(%esp)
        jne debug_stack_correct
        FIX_STACK 12, debug_stack_correct, debug_esp_fix_insn
@@ -1313,6 +1402,7 @@ END(debug)
  */
 ENTRY(nmi)
        RING0_INT_FRAME
+       ASM_CLAC
        pushl_cfi %eax
        movl %ss, %eax
        cmpw $__ESPFIX_SS, %ax
@@ -1383,6 +1473,7 @@ END(nmi)
 
 ENTRY(int3)
        RING0_INT_FRAME
+       ASM_CLAC
        pushl_cfi $-1                   # mark this as an int
        SAVE_ALL
        TRACE_IRQS_OFF
@@ -1403,6 +1494,7 @@ END(general_protection)
 #ifdef CONFIG_KVM_GUEST
 ENTRY(async_page_fault)
        RING0_EC_FRAME
+       ASM_CLAC
        pushl_cfi $do_async_page_fault
        jmp error_code
        CFI_ENDPROC