Skip to content

Commit 3f5159a

Browse files
dvlasenkIngo Molnar
authored and
Ingo Molnar
committed
x86/asm/entry/32: Update -ENOSYS handling to match the 64-bit logic
Recently Andy changed the 64-bit syscall logic so that pt_regs->ax is initially set to -ENOSYS, and on syscall exit, it is updated with the actual return value. This simplified the logic there. This patch does the same for 32-bit syscall entry points. The check for %rax being too big is moved to be just before the call instruction which dispatches execution through the syscall table. There is no way to accidentally skip this check now by jumping to a label after it. This allows us to remove redundant checks after ptrace et al. If %rax is too big, we just skip over the (call, write %rax to pt_regs->ax) instruction pair. pt_regs->ax remains set to -ENOSYS, and it gets returned to userspace. Similar to 64-bit code, this eliminates the "ia32_badsys" code path. Run-tested. Signed-off-by: Denys Vlasenko <[email protected]> Cc: Alexei Starovoitov <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Frederic Weisbecker <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Kees Cook <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Oleg Nesterov <[email protected]> Cc: Steven Rostedt <[email protected]> Cc: Will Drewry <[email protected]> Link: http://lkml.kernel.org/r/[email protected] [ Changelog massage. ] Signed-off-by: Ingo Molnar <[email protected]>
1 parent ac7f5df commit 3f5159a

File tree

1 file changed

+14
-28
lines changed

1 file changed

+14
-28
lines changed

arch/x86/ia32/ia32entry.S

+14-28
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ ENTRY(ia32_sysenter_target)
136136
pushq_cfi_reg rsi /* pt_regs->si */
137137
pushq_cfi_reg rdx /* pt_regs->dx */
138138
pushq_cfi_reg rcx /* pt_regs->cx */
139-
pushq_cfi_reg rax /* pt_regs->ax */
139+
pushq_cfi $-ENOSYS /* pt_regs->ax */
140140
cld
141141
sub $(10*8),%rsp /* pt_regs->r8-11,bp,bx,r12-15 not saved */
142142
CFI_ADJUST_CFA_OFFSET 10*8
@@ -163,8 +163,6 @@ sysenter_flags_fixed:
163163
testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
164164
CFI_REMEMBER_STATE
165165
jnz sysenter_tracesys
166-
cmpq $(IA32_NR_syscalls-1),%rax
167-
ja ia32_badsys
168166
sysenter_do_call:
169167
/* 32bit syscall -> 64bit C ABI argument conversion */
170168
movl %edi,%r8d /* arg5 */
@@ -173,8 +171,11 @@ sysenter_do_call:
173171
movl %ebx,%edi /* arg1 */
174172
movl %edx,%edx /* arg3 (zero extension) */
175173
sysenter_dispatch:
174+
cmpq $(IA32_NR_syscalls-1),%rax
175+
ja 1f
176176
call *ia32_sys_call_table(,%rax,8)
177177
movq %rax,RAX(%rsp)
178+
1:
178179
DISABLE_INTERRUPTS(CLBR_NONE)
179180
TRACE_IRQS_OFF
180181
testl $_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
@@ -241,9 +242,7 @@ sysexit_from_sys_call:
241242
movl %ebx,%esi /* 2nd arg: 1st syscall arg */
242243
movl %eax,%edi /* 1st arg: syscall number */
243244
call __audit_syscall_entry
244-
movl RAX(%rsp),%eax /* reload syscall number */
245-
cmpq $(IA32_NR_syscalls-1),%rax
246-
ja ia32_badsys
245+
movl ORIG_RAX(%rsp),%eax /* reload syscall number */
247246
movl %ebx,%edi /* reload 1st syscall arg */
248247
movl RCX(%rsp),%esi /* reload 2nd syscall arg */
249248
movl RDX(%rsp),%edx /* reload 3rd syscall arg */
@@ -294,13 +293,10 @@ sysenter_tracesys:
294293
#endif
295294
SAVE_EXTRA_REGS
296295
CLEAR_RREGS
297-
movq $-ENOSYS,RAX(%rsp)/* ptrace can change this for a bad syscall */
298296
movq %rsp,%rdi /* &pt_regs -> arg1 */
299297
call syscall_trace_enter
300298
LOAD_ARGS32 /* reload args from stack in case ptrace changed it */
301299
RESTORE_EXTRA_REGS
302-
cmpq $(IA32_NR_syscalls-1),%rax
303-
ja int_ret_from_sys_call /* sysenter_tracesys has set RAX(%rsp) */
304300
jmp sysenter_do_call
305301
CFI_ENDPROC
306302
ENDPROC(ia32_sysenter_target)
@@ -370,7 +366,7 @@ ENTRY(ia32_cstar_target)
370366
pushq_cfi_reg rdx /* pt_regs->dx */
371367
pushq_cfi_reg rbp /* pt_regs->cx */
372368
movl %ebp,%ecx
373-
pushq_cfi_reg rax /* pt_regs->ax */
369+
pushq_cfi $-ENOSYS /* pt_regs->ax */
374370
sub $(10*8),%rsp /* pt_regs->r8-11,bp,bx,r12-15 not saved */
375371
CFI_ADJUST_CFA_OFFSET 10*8
376372

@@ -386,8 +382,6 @@ ENTRY(ia32_cstar_target)
386382
testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
387383
CFI_REMEMBER_STATE
388384
jnz cstar_tracesys
389-
cmpq $IA32_NR_syscalls-1,%rax
390-
ja ia32_badsys
391385
cstar_do_call:
392386
/* 32bit syscall -> 64bit C ABI argument conversion */
393387
movl %edi,%r8d /* arg5 */
@@ -396,8 +390,11 @@ cstar_do_call:
396390
movl %ebx,%edi /* arg1 */
397391
movl %edx,%edx /* arg3 (zero extension) */
398392
cstar_dispatch:
393+
cmpq $(IA32_NR_syscalls-1),%rax
394+
ja 1f
399395
call *ia32_sys_call_table(,%rax,8)
400396
movq %rax,RAX(%rsp)
397+
1:
401398
DISABLE_INTERRUPTS(CLBR_NONE)
402399
TRACE_IRQS_OFF
403400
testl $_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
@@ -444,14 +441,11 @@ cstar_tracesys:
444441
xchgl %r9d,%ebp
445442
SAVE_EXTRA_REGS
446443
CLEAR_RREGS r9
447-
movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */
448444
movq %rsp,%rdi /* &pt_regs -> arg1 */
449445
call syscall_trace_enter
450446
LOAD_ARGS32 1 /* reload args from stack in case ptrace changed it */
451447
RESTORE_EXTRA_REGS
452448
xchgl %ebp,%r9d
453-
cmpq $(IA32_NR_syscalls-1),%rax
454-
ja int_ret_from_sys_call /* cstar_tracesys has set RAX(%rsp) */
455449
jmp cstar_do_call
456450
END(ia32_cstar_target)
457451

@@ -510,50 +504,42 @@ ENTRY(ia32_syscall)
510504
pushq_cfi_reg rsi /* pt_regs->si */
511505
pushq_cfi_reg rdx /* pt_regs->dx */
512506
pushq_cfi_reg rcx /* pt_regs->cx */
513-
pushq_cfi_reg rax /* pt_regs->ax */
507+
pushq_cfi $-ENOSYS /* pt_regs->ax */
514508
cld
515509
sub $(10*8),%rsp /* pt_regs->r8-11,bp,bx,r12-15 not saved */
516510
CFI_ADJUST_CFA_OFFSET 10*8
517511

518512
orl $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)
519513
testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
520514
jnz ia32_tracesys
521-
cmpq $(IA32_NR_syscalls-1),%rax
522-
ja ia32_badsys
523515
ia32_do_call:
524516
/* 32bit syscall -> 64bit C ABI argument conversion */
525517
movl %edi,%r8d /* arg5 */
526518
movl %ebp,%r9d /* arg6 */
527519
xchg %ecx,%esi /* rsi:arg2, rcx:arg4 */
528520
movl %ebx,%edi /* arg1 */
529521
movl %edx,%edx /* arg3 (zero extension) */
522+
cmpq $(IA32_NR_syscalls-1),%rax
523+
ja 1f
530524
call *ia32_sys_call_table(,%rax,8) # xxx: rip relative
531525
ia32_sysret:
532526
movq %rax,RAX(%rsp)
527+
1:
533528
ia32_ret_from_sys_call:
534529
CLEAR_RREGS
535530
jmp int_ret_from_sys_call
536531

537532
ia32_tracesys:
538533
SAVE_EXTRA_REGS
539534
CLEAR_RREGS
540-
movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */
541535
movq %rsp,%rdi /* &pt_regs -> arg1 */
542536
call syscall_trace_enter
543537
LOAD_ARGS32 /* reload args from stack in case ptrace changed it */
544538
RESTORE_EXTRA_REGS
545-
cmpq $(IA32_NR_syscalls-1),%rax
546-
ja int_ret_from_sys_call /* ia32_tracesys has set RAX(%rsp) */
547539
jmp ia32_do_call
540+
CFI_ENDPROC
548541
END(ia32_syscall)
549542

550-
ia32_badsys:
551-
movq $0,ORIG_RAX(%rsp)
552-
movq $-ENOSYS,%rax
553-
jmp ia32_sysret
554-
555-
CFI_ENDPROC
556-
557543
.macro PTREGSCALL label, func
558544
ALIGN
559545
GLOBAL(\label)

0 commit comments

Comments
 (0)