diff options
Diffstat (limited to 'arch/x86_64/kernel/entry.S')
-rw-r--r-- | arch/x86_64/kernel/entry.S | 29 |
1 files changed, 11 insertions, 18 deletions
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 7c10e9009d61..22cb6ee074b9 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S | |||
@@ -178,6 +178,12 @@ rff_trace: | |||
178 | * Interrupts are off on entry. | 178 | * Interrupts are off on entry. |
179 | * Only called from user space. | 179 | * Only called from user space. |
180 | * | 180 | * |
181 | * EM64T CPUs have somewhat weird error reporting for non canonical RIPs in SYSRET. | ||
182 | * We can't handle any exceptions there because the exception handler would | ||
183 | * end up running on the user stack which is unsafe. To avoid problems | ||
184 | * any code that might end up with a user touched pt_regs should return | ||
185 | * using int_ret_from_syscall. | ||
186 | * | ||
181 | * XXX if we had a free scratch register we could save the RSP into the stack frame | 187 | * XXX if we had a free scratch register we could save the RSP into the stack frame |
182 | * and report it properly in ps. Unfortunately we haven't. | 188 | * and report it properly in ps. Unfortunately we haven't. |
183 | */ | 189 | */ |
@@ -254,7 +260,9 @@ sysret_signal: | |||
254 | xorl %esi,%esi # oldset -> arg2 | 260 | xorl %esi,%esi # oldset -> arg2 |
255 | call ptregscall_common | 261 | call ptregscall_common |
256 | 1: movl $_TIF_NEED_RESCHED,%edi | 262 | 1: movl $_TIF_NEED_RESCHED,%edi |
257 | jmp sysret_check | 263 | /* Stack frame might have been changed. The IRET path does |
264 | some additional checks to handle this */ | ||
265 | jmp int_with_check | ||
258 | 266 | ||
259 | badsys: | 267 | badsys: |
260 | movq $-ENOSYS,RAX-ARGOFFSET(%rsp) | 268 | movq $-ENOSYS,RAX-ARGOFFSET(%rsp) |
@@ -280,7 +288,8 @@ tracesys: | |||
280 | call syscall_trace_leave | 288 | call syscall_trace_leave |
281 | RESTORE_TOP_OF_STACK %rbx | 289 | RESTORE_TOP_OF_STACK %rbx |
282 | RESTORE_REST | 290 | RESTORE_REST |
283 | jmp ret_from_sys_call | 291 | /* Stack frame might have been changed. Use the more careful IRET path */ |
292 | jmp int_ret_from_sys_call | ||
284 | CFI_ENDPROC | 293 | CFI_ENDPROC |
285 | 294 | ||
286 | /* | 295 | /* |
@@ -408,25 +417,9 @@ ENTRY(stub_execve) | |||
408 | CFI_ADJUST_CFA_OFFSET -8 | 417 | CFI_ADJUST_CFA_OFFSET -8 |
409 | CFI_REGISTER rip, r11 | 418 | CFI_REGISTER rip, r11 |
410 | SAVE_REST | 419 | SAVE_REST |
411 | movq %r11, %r15 | ||
412 | CFI_REGISTER rip, r15 | ||
413 | FIXUP_TOP_OF_STACK %r11 | 420 | FIXUP_TOP_OF_STACK %r11 |
414 | call sys_execve | 421 | call sys_execve |
415 | GET_THREAD_INFO(%rcx) | ||
416 | bt $TIF_IA32,threadinfo_flags(%rcx) | ||
417 | CFI_REMEMBER_STATE | ||
418 | jc exec_32bit | ||
419 | RESTORE_TOP_OF_STACK %r11 | 422 | RESTORE_TOP_OF_STACK %r11 |
420 | movq %r15, %r11 | ||
421 | CFI_REGISTER rip, r11 | ||
422 | RESTORE_REST | ||
423 | pushq %r11 | ||
424 | CFI_ADJUST_CFA_OFFSET 8 | ||
425 | CFI_REL_OFFSET rip, 0 | ||
426 | ret | ||
427 | |||
428 | exec_32bit: | ||
429 | CFI_RESTORE_STATE | ||
430 | movq %rax,RAX(%rsp) | 423 | movq %rax,RAX(%rsp) |
431 | RESTORE_REST | 424 | RESTORE_REST |
432 | jmp int_ret_from_sys_call | 425 | jmp int_ret_from_sys_call |