@@ -2346,9 +2346,10 @@ enum ptrace_syscall_dir {
23462346 PTRACE_SYSCALL_EXIT ,
23472347};
23482348
2349- static void report_syscall (struct pt_regs * regs , enum ptrace_syscall_dir dir )
2349+ static __always_inline unsigned long ptrace_save_reg (struct pt_regs * regs ,
2350+ enum ptrace_syscall_dir dir ,
2351+ int * regno )
23502352{
2351- int regno ;
23522353 unsigned long saved_reg ;
23532354
23542355 /*
@@ -2367,15 +2368,34 @@ static void report_syscall(struct pt_regs *regs, enum ptrace_syscall_dir dir)
23672368 * - Syscall stops behave differently to seccomp and pseudo-step traps
23682369 * (the latter do not nobble any registers).
23692370 */
2370- regno = (is_compat_task () ? 12 : 7 );
2371- saved_reg = regs -> regs [regno ];
2372- regs -> regs [regno ] = dir ;
2371+ * regno = (is_compat_task () ? 12 : 7 );
2372+ saved_reg = regs -> regs [* regno ];
2373+ regs -> regs [* regno ] = dir ;
23732374
2374- if (dir == PTRACE_SYSCALL_ENTER ) {
2375- if (ptrace_report_syscall_entry (regs ))
2376- forget_syscall (regs );
2377- regs -> regs [regno ] = saved_reg ;
2378- } else if (!test_thread_flag (TIF_SINGLESTEP )) {
2375+ return saved_reg ;
2376+ }
2377+
2378+ static int report_syscall_entry (struct pt_regs * regs )
2379+ {
2380+ unsigned long saved_reg ;
2381+ int regno , ret ;
2382+
2383+ saved_reg = ptrace_save_reg (regs , PTRACE_SYSCALL_ENTER , & regno );
2384+ ret = ptrace_report_syscall_entry (regs );
2385+ if (ret )
2386+ forget_syscall (regs );
2387+ regs -> regs [regno ] = saved_reg ;
2388+
2389+ return ret ;
2390+ }
2391+
2392+ static void report_syscall_exit (struct pt_regs * regs )
2393+ {
2394+ unsigned long saved_reg ;
2395+ int regno ;
2396+
2397+ saved_reg = ptrace_save_reg (regs , PTRACE_SYSCALL_EXIT , & regno );
2398+ if (!test_thread_flag (TIF_SINGLESTEP )) {
23792399 ptrace_report_syscall_exit (regs , 0 );
23802400 regs -> regs [regno ] = saved_reg ;
23812401 } else {
@@ -2393,10 +2413,11 @@ static void report_syscall(struct pt_regs *regs, enum ptrace_syscall_dir dir)
23932413int syscall_trace_enter (struct pt_regs * regs )
23942414{
23952415 unsigned long flags = read_thread_flags ();
2416+ int ret ;
23962417
23972418 if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE )) {
2398- report_syscall (regs , PTRACE_SYSCALL_ENTER );
2399- if (flags & _TIF_SYSCALL_EMU )
2419+ ret = report_syscall_entry (regs );
2420+ if (ret || ( flags & _TIF_SYSCALL_EMU ) )
24002421 return NO_SYSCALL ;
24012422 }
24022423
@@ -2423,7 +2444,7 @@ void syscall_trace_exit(struct pt_regs *regs)
24232444 trace_sys_exit (regs , syscall_get_return_value (current , regs ));
24242445
24252446 if (flags & (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP ))
2426- report_syscall (regs , PTRACE_SYSCALL_EXIT );
2447+ report_syscall_exit (regs );
24272448
24282449 rseq_syscall (regs );
24292450}
0 commit comments