Merge branch master from git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Pick up the spectre documentation so the Grand Schemozzle can be added.
Cette révision appartient à :
@@ -360,3 +360,9 @@ For 32-bit we have the following conventions - kernel is built with
|
||||
.Lafter_call_\@:
|
||||
#endif
|
||||
.endm
|
||||
|
||||
#ifdef CONFIG_PARAVIRT_XXL
|
||||
#define GET_CR2_INTO(reg) GET_CR2_INTO_AX ; _ASM_MOV %_ASM_AX, reg
|
||||
#else
|
||||
#define GET_CR2_INTO(reg) _ASM_MOV %cr2, reg
|
||||
#endif
|
||||
|
@@ -294,9 +294,11 @@
|
||||
.Lfinished_frame_\@:
|
||||
.endm
|
||||
|
||||
.macro SAVE_ALL pt_regs_ax=%eax switch_stacks=0
|
||||
.macro SAVE_ALL pt_regs_ax=%eax switch_stacks=0 skip_gs=0
|
||||
cld
|
||||
.if \skip_gs == 0
|
||||
PUSH_GS
|
||||
.endif
|
||||
FIXUP_FRAME
|
||||
pushl %fs
|
||||
pushl %es
|
||||
@@ -313,13 +315,13 @@
|
||||
movl %edx, %es
|
||||
movl $(__KERNEL_PERCPU), %edx
|
||||
movl %edx, %fs
|
||||
.if \skip_gs == 0
|
||||
SET_KERNEL_GS %edx
|
||||
|
||||
.endif
|
||||
/* Switch to kernel stack if necessary */
|
||||
.if \switch_stacks > 0
|
||||
SWITCH_TO_KERNEL_STACK
|
||||
.endif
|
||||
|
||||
.endm
|
||||
|
||||
.macro SAVE_ALL_NMI cr3_reg:req
|
||||
@@ -1189,7 +1191,7 @@ common_spurious:
|
||||
movl %esp, %eax
|
||||
call smp_spurious_interrupt
|
||||
jmp ret_from_intr
|
||||
ENDPROC(common_interrupt)
|
||||
ENDPROC(common_spurious)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -1442,38 +1444,50 @@ BUILD_INTERRUPT3(hv_stimer0_callback_vector, HYPERV_STIMER0_VECTOR,
|
||||
ENTRY(page_fault)
|
||||
ASM_CLAC
|
||||
pushl $do_page_fault
|
||||
ALIGN
|
||||
jmp common_exception
|
||||
jmp common_exception_read_cr2
|
||||
END(page_fault)
|
||||
|
||||
common_exception_read_cr2:
|
||||
/* the function address is in %gs's slot on the stack */
|
||||
SAVE_ALL switch_stacks=1 skip_gs=1
|
||||
|
||||
ENCODE_FRAME_POINTER
|
||||
UNWIND_ESPFIX_STACK
|
||||
|
||||
/* fixup %gs */
|
||||
GS_TO_REG %ecx
|
||||
movl PT_GS(%esp), %edi
|
||||
REG_TO_PTGS %ecx
|
||||
SET_KERNEL_GS %ecx
|
||||
|
||||
GET_CR2_INTO(%ecx) # might clobber %eax
|
||||
|
||||
/* fixup orig %eax */
|
||||
movl PT_ORIG_EAX(%esp), %edx # get the error code
|
||||
movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
|
||||
|
||||
TRACE_IRQS_OFF
|
||||
movl %esp, %eax # pt_regs pointer
|
||||
CALL_NOSPEC %edi
|
||||
jmp ret_from_exception
|
||||
END(common_exception_read_cr2)
|
||||
|
||||
common_exception:
|
||||
/* the function address is in %gs's slot on the stack */
|
||||
FIXUP_FRAME
|
||||
pushl %fs
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl %eax
|
||||
movl $(__USER_DS), %eax
|
||||
movl %eax, %ds
|
||||
movl %eax, %es
|
||||
movl $(__KERNEL_PERCPU), %eax
|
||||
movl %eax, %fs
|
||||
pushl %ebp
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
pushl %edx
|
||||
pushl %ecx
|
||||
pushl %ebx
|
||||
SWITCH_TO_KERNEL_STACK
|
||||
SAVE_ALL switch_stacks=1 skip_gs=1
|
||||
ENCODE_FRAME_POINTER
|
||||
cld
|
||||
UNWIND_ESPFIX_STACK
|
||||
|
||||
/* fixup %gs */
|
||||
GS_TO_REG %ecx
|
||||
movl PT_GS(%esp), %edi # get the function address
|
||||
movl PT_ORIG_EAX(%esp), %edx # get the error code
|
||||
movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
|
||||
REG_TO_PTGS %ecx
|
||||
SET_KERNEL_GS %ecx
|
||||
|
||||
/* fixup orig %eax */
|
||||
movl PT_ORIG_EAX(%esp), %edx # get the error code
|
||||
movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
|
||||
|
||||
TRACE_IRQS_OFF
|
||||
movl %esp, %eax # pt_regs pointer
|
||||
CALL_NOSPEC %edi
|
||||
@@ -1586,7 +1600,7 @@ END(general_protection)
|
||||
ENTRY(async_page_fault)
|
||||
ASM_CLAC
|
||||
pushl $do_async_page_fault
|
||||
jmp common_exception
|
||||
jmp common_exception_read_cr2
|
||||
END(async_page_fault)
|
||||
#endif
|
||||
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* entry.S contains the system-call and fault low-level handling routines.
|
||||
*
|
||||
* Some of this is documented in Documentation/x86/entry_64.txt
|
||||
* Some of this is documented in Documentation/x86/entry_64.rst
|
||||
*
|
||||
* A note on terminology:
|
||||
* - iret frame: Architecture defined interrupt frame from SS to RIP
|
||||
@@ -866,18 +866,84 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt
|
||||
*/
|
||||
#define CPU_TSS_IST(x) PER_CPU_VAR(cpu_tss_rw) + (TSS_ist + (x) * 8)
|
||||
|
||||
.macro idtentry_part do_sym, has_error_code:req, read_cr2:req, paranoid:req, shift_ist=-1, ist_offset=0
|
||||
|
||||
.if \paranoid
|
||||
call paranoid_entry
|
||||
/* returned flag: ebx=0: need swapgs on exit, ebx=1: don't need it */
|
||||
.else
|
||||
call error_entry
|
||||
.endif
|
||||
UNWIND_HINT_REGS
|
||||
|
||||
.if \read_cr2
|
||||
/*
|
||||
* Store CR2 early so subsequent faults cannot clobber it. Use R12 as
|
||||
* intermediate storage as RDX can be clobbered in enter_from_user_mode().
|
||||
* GET_CR2_INTO can clobber RAX.
|
||||
*/
|
||||
GET_CR2_INTO(%r12);
|
||||
.endif
|
||||
|
||||
.if \shift_ist != -1
|
||||
TRACE_IRQS_OFF_DEBUG /* reload IDT in case of recursion */
|
||||
.else
|
||||
TRACE_IRQS_OFF
|
||||
.endif
|
||||
|
||||
.if \paranoid == 0
|
||||
testb $3, CS(%rsp)
|
||||
jz .Lfrom_kernel_no_context_tracking_\@
|
||||
CALL_enter_from_user_mode
|
||||
.Lfrom_kernel_no_context_tracking_\@:
|
||||
.endif
|
||||
|
||||
movq %rsp, %rdi /* pt_regs pointer */
|
||||
|
||||
.if \has_error_code
|
||||
movq ORIG_RAX(%rsp), %rsi /* get error code */
|
||||
movq $-1, ORIG_RAX(%rsp) /* no syscall to restart */
|
||||
.else
|
||||
xorl %esi, %esi /* no error code */
|
||||
.endif
|
||||
|
||||
.if \shift_ist != -1
|
||||
subq $\ist_offset, CPU_TSS_IST(\shift_ist)
|
||||
.endif
|
||||
|
||||
.if \read_cr2
|
||||
movq %r12, %rdx /* Move CR2 into 3rd argument */
|
||||
.endif
|
||||
|
||||
call \do_sym
|
||||
|
||||
.if \shift_ist != -1
|
||||
addq $\ist_offset, CPU_TSS_IST(\shift_ist)
|
||||
.endif
|
||||
|
||||
.if \paranoid
|
||||
/* this procedure expect "no swapgs" flag in ebx */
|
||||
jmp paranoid_exit
|
||||
.else
|
||||
jmp error_exit
|
||||
.endif
|
||||
|
||||
.endm
|
||||
|
||||
/**
|
||||
* idtentry - Generate an IDT entry stub
|
||||
* @sym: Name of the generated entry point
|
||||
* @do_sym: C function to be called
|
||||
* @has_error_code: True if this IDT vector has an error code on the stack
|
||||
* @paranoid: non-zero means that this vector may be invoked from
|
||||
* @do_sym: C function to be called
|
||||
* @has_error_code: True if this IDT vector has an error code on the stack
|
||||
* @paranoid: non-zero means that this vector may be invoked from
|
||||
* kernel mode with user GSBASE and/or user CR3.
|
||||
* 2 is special -- see below.
|
||||
* @shift_ist: Set to an IST index if entries from kernel mode should
|
||||
* decrement the IST stack so that nested entries get a
|
||||
* decrement the IST stack so that nested entries get a
|
||||
* fresh stack. (This is for #DB, which has a nasty habit
|
||||
* of recursing.)
|
||||
* of recursing.)
|
||||
* @create_gap: create a 6-word stack gap when coming from kernel mode.
|
||||
* @read_cr2: load CR2 into the 3rd argument; done before calling any C code
|
||||
*
|
||||
* idtentry generates an IDT stub that sets up a usable kernel context,
|
||||
* creates struct pt_regs, and calls @do_sym. The stub has the following
|
||||
@@ -902,15 +968,19 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt
|
||||
* @paranoid == 2 is special: the stub will never switch stacks. This is for
|
||||
* #DF: if the thread stack is somehow unusable, we'll still get a useful OOPS.
|
||||
*/
|
||||
.macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1 ist_offset=0 create_gap=0
|
||||
.macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1 ist_offset=0 create_gap=0 read_cr2=0
|
||||
ENTRY(\sym)
|
||||
UNWIND_HINT_IRET_REGS offset=\has_error_code*8
|
||||
|
||||
/* Sanity check */
|
||||
.if \shift_ist != -1 && \paranoid == 0
|
||||
.if \shift_ist != -1 && \paranoid != 1
|
||||
.error "using shift_ist requires paranoid=1"
|
||||
.endif
|
||||
|
||||
.if \create_gap && \paranoid
|
||||
.error "using create_gap requires paranoid=0"
|
||||
.endif
|
||||
|
||||
ASM_CLAC
|
||||
|
||||
.if \has_error_code == 0
|
||||
@@ -936,47 +1006,7 @@ ENTRY(\sym)
|
||||
.Lfrom_usermode_no_gap_\@:
|
||||
.endif
|
||||
|
||||
.if \paranoid
|
||||
call paranoid_entry
|
||||
.else
|
||||
call error_entry
|
||||
.endif
|
||||
UNWIND_HINT_REGS
|
||||
/* returned flag: ebx=0: need swapgs on exit, ebx=1: don't need it */
|
||||
|
||||
.if \paranoid
|
||||
.if \shift_ist != -1
|
||||
TRACE_IRQS_OFF_DEBUG /* reload IDT in case of recursion */
|
||||
.else
|
||||
TRACE_IRQS_OFF
|
||||
.endif
|
||||
.endif
|
||||
|
||||
movq %rsp, %rdi /* pt_regs pointer */
|
||||
|
||||
.if \has_error_code
|
||||
movq ORIG_RAX(%rsp), %rsi /* get error code */
|
||||
movq $-1, ORIG_RAX(%rsp) /* no syscall to restart */
|
||||
.else
|
||||
xorl %esi, %esi /* no error code */
|
||||
.endif
|
||||
|
||||
.if \shift_ist != -1
|
||||
subq $\ist_offset, CPU_TSS_IST(\shift_ist)
|
||||
.endif
|
||||
|
||||
call \do_sym
|
||||
|
||||
.if \shift_ist != -1
|
||||
addq $\ist_offset, CPU_TSS_IST(\shift_ist)
|
||||
.endif
|
||||
|
||||
/* these procedures expect "no swapgs" flag in ebx */
|
||||
.if \paranoid
|
||||
jmp paranoid_exit
|
||||
.else
|
||||
jmp error_exit
|
||||
.endif
|
||||
idtentry_part \do_sym, \has_error_code, \read_cr2, \paranoid, \shift_ist, \ist_offset
|
||||
|
||||
.if \paranoid == 1
|
||||
/*
|
||||
@@ -985,21 +1015,9 @@ ENTRY(\sym)
|
||||
* run in real process context if user_mode(regs).
|
||||
*/
|
||||
.Lfrom_usermode_switch_stack_\@:
|
||||
call error_entry
|
||||
|
||||
movq %rsp, %rdi /* pt_regs pointer */
|
||||
|
||||
.if \has_error_code
|
||||
movq ORIG_RAX(%rsp), %rsi /* get error code */
|
||||
movq $-1, ORIG_RAX(%rsp) /* no syscall to restart */
|
||||
.else
|
||||
xorl %esi, %esi /* no error code */
|
||||
idtentry_part \do_sym, \has_error_code, \read_cr2, paranoid=0
|
||||
.endif
|
||||
|
||||
call \do_sym
|
||||
|
||||
jmp error_exit
|
||||
.endif
|
||||
_ASM_NOKPROBE(\sym)
|
||||
END(\sym)
|
||||
.endm
|
||||
@@ -1009,7 +1027,7 @@ idtentry overflow do_overflow has_error_code=0
|
||||
idtentry bounds do_bounds has_error_code=0
|
||||
idtentry invalid_op do_invalid_op has_error_code=0
|
||||
idtentry device_not_available do_device_not_available has_error_code=0
|
||||
idtentry double_fault do_double_fault has_error_code=1 paranoid=2
|
||||
idtentry double_fault do_double_fault has_error_code=1 paranoid=2 read_cr2=1
|
||||
idtentry coprocessor_segment_overrun do_coprocessor_segment_overrun has_error_code=0
|
||||
idtentry invalid_TSS do_invalid_TSS has_error_code=1
|
||||
idtentry segment_not_present do_segment_not_present has_error_code=1
|
||||
@@ -1178,14 +1196,13 @@ idtentry stack_segment do_stack_segment has_error_code=1
|
||||
#ifdef CONFIG_XEN_PV
|
||||
idtentry xennmi do_nmi has_error_code=0
|
||||
idtentry xendebug do_debug has_error_code=0
|
||||
idtentry xenint3 do_int3 has_error_code=0
|
||||
#endif
|
||||
|
||||
idtentry general_protection do_general_protection has_error_code=1
|
||||
idtentry page_fault do_page_fault has_error_code=1
|
||||
idtentry page_fault do_page_fault has_error_code=1 read_cr2=1
|
||||
|
||||
#ifdef CONFIG_KVM_GUEST
|
||||
idtentry async_page_fault do_async_page_fault has_error_code=1
|
||||
idtentry async_page_fault do_async_page_fault has_error_code=1 read_cr2=1
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_MCE
|
||||
@@ -1292,20 +1309,11 @@ ENTRY(error_entry)
|
||||
movq %rax, %rsp /* switch stack */
|
||||
ENCODE_FRAME_POINTER
|
||||
pushq %r12
|
||||
|
||||
/*
|
||||
* We need to tell lockdep that IRQs are off. We can't do this until
|
||||
* we fix gsbase, and we should do it before enter_from_user_mode
|
||||
* (which can take locks).
|
||||
*/
|
||||
TRACE_IRQS_OFF
|
||||
CALL_enter_from_user_mode
|
||||
ret
|
||||
|
||||
.Lerror_entry_done_lfence:
|
||||
FENCE_SWAPGS_KERNEL_ENTRY
|
||||
.Lerror_entry_done:
|
||||
TRACE_IRQS_OFF
|
||||
ret
|
||||
|
||||
/*
|
||||
|
@@ -438,3 +438,5 @@
|
||||
431 i386 fsconfig sys_fsconfig __ia32_sys_fsconfig
|
||||
432 i386 fsmount sys_fsmount __ia32_sys_fsmount
|
||||
433 i386 fspick sys_fspick __ia32_sys_fspick
|
||||
434 i386 pidfd_open sys_pidfd_open __ia32_sys_pidfd_open
|
||||
435 i386 clone3 sys_clone3 __ia32_sys_clone3
|
||||
|
@@ -355,6 +355,8 @@
|
||||
431 common fsconfig __x64_sys_fsconfig
|
||||
432 common fsmount __x64_sys_fsmount
|
||||
433 common fspick __x64_sys_fspick
|
||||
434 common pidfd_open __x64_sys_pidfd_open
|
||||
435 common clone3 __x64_sys_clone3/ptregs
|
||||
|
||||
#
|
||||
# x32-specific system call numbers start at 512 to avoid cache impact
|
||||
|
@@ -12,9 +12,7 @@
|
||||
|
||||
/* rdi: arg1 ... normal C conventions. rax is saved/restored. */
|
||||
.macro THUNK name, func, put_ret_addr_in_rdi=0
|
||||
.globl \name
|
||||
.type \name, @function
|
||||
\name:
|
||||
ENTRY(\name)
|
||||
pushq %rbp
|
||||
movq %rsp, %rbp
|
||||
|
||||
@@ -35,6 +33,7 @@
|
||||
|
||||
call \func
|
||||
jmp .L_restore
|
||||
ENDPROC(\name)
|
||||
_ASM_NOKPROBE(\name)
|
||||
.endm
|
||||
|
||||
|
@@ -56,8 +56,7 @@ VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -soname linux-vdso.so.1 --no-undefined \
|
||||
-z max-page-size=4096
|
||||
|
||||
$(obj)/vdso64.so.dbg: $(obj)/vdso.lds $(vobjs) FORCE
|
||||
$(call if_changed,vdso)
|
||||
$(call if_changed,vdso_check)
|
||||
$(call if_changed,vdso_and_check)
|
||||
|
||||
HOST_EXTRACFLAGS += -I$(srctree)/tools/include -I$(srctree)/include/uapi -I$(srctree)/arch/$(SUBARCH)/include/uapi
|
||||
hostprogs-y += vdso2c
|
||||
@@ -127,8 +126,7 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
$(obj)/vdsox32.so.dbg: $(obj)/vdsox32.lds $(vobjx32s) FORCE
|
||||
$(call if_changed,vdso)
|
||||
$(call if_changed,vdso_check)
|
||||
$(call if_changed,vdso_and_check)
|
||||
|
||||
CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds)
|
||||
VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -soname linux-gate.so.1
|
||||
@@ -167,8 +165,7 @@ $(obj)/vdso32.so.dbg: FORCE \
|
||||
$(obj)/vdso32/note.o \
|
||||
$(obj)/vdso32/system_call.o \
|
||||
$(obj)/vdso32/sigreturn.o
|
||||
$(call if_changed,vdso)
|
||||
$(call if_changed,vdso_check)
|
||||
$(call if_changed,vdso_and_check)
|
||||
|
||||
#
|
||||
# The DSO images are built using a special linker script.
|
||||
@@ -179,11 +176,13 @@ quiet_cmd_vdso = VDSO $@
|
||||
-T $(filter %.lds,$^) $(filter %.o,$^) && \
|
||||
sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
|
||||
|
||||
VDSO_LDFLAGS = -shared $(call ld-option, --hash-style=both) \
|
||||
$(call ld-option, --build-id) $(call ld-option, --eh-frame-hdr) \
|
||||
-Bsymbolic
|
||||
VDSO_LDFLAGS = -shared --hash-style=both --build-id \
|
||||
$(call ld-option, --eh-frame-hdr) -Bsymbolic
|
||||
GCOV_PROFILE := n
|
||||
|
||||
quiet_cmd_vdso_and_check = VDSO $@
|
||||
cmd_vdso_and_check = $(cmd_vdso); $(cmd_vdso_check)
|
||||
|
||||
#
|
||||
# Install the unstripped copies of vdso*.so. If our toolchain supports
|
||||
# build-id, install .build-id links as well.
|
||||
|
@@ -65,9 +65,6 @@ subsys_initcall(sysenter_setup);
|
||||
/* Register vsyscall32 into the ABI table */
|
||||
#include <linux/sysctl.h>
|
||||
|
||||
static const int zero;
|
||||
static const int one = 1;
|
||||
|
||||
static struct ctl_table abi_table2[] = {
|
||||
{
|
||||
.procname = "vsyscall32",
|
||||
@@ -75,8 +72,8 @@ static struct ctl_table abi_table2[] = {
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.extra1 = (int *)&zero,
|
||||
.extra2 = (int *)&one,
|
||||
.extra1 = SYSCTL_ZERO,
|
||||
.extra2 = SYSCTL_ONE,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
@@ -110,7 +110,7 @@ static bool write_ok_or_segv(unsigned long ptr, size_t size)
|
||||
thread->cr2 = ptr;
|
||||
thread->trap_nr = X86_TRAP_PF;
|
||||
|
||||
force_sig_fault(SIGSEGV, SEGV_MAPERR, (void __user *)ptr, current);
|
||||
force_sig_fault(SIGSEGV, SEGV_MAPERR, (void __user *)ptr);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
@@ -289,7 +289,7 @@ do_ret:
|
||||
return true;
|
||||
|
||||
sigsegv:
|
||||
force_sig(SIGSEGV, current);
|
||||
force_sig(SIGSEGV);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Référencer dans un nouveau ticket
Bloquer un utilisateur