diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h
index 1552ecca8520..db8465f5fabb 100644
--- a/arch/alpha/include/asm/thread_info.h
+++ b/arch/alpha/include/asm/thread_info.h
@@ -67,6 +67,7 @@ register unsigned long *current_stack_pointer __asm__ ("$30");
#define TIF_NOTIFY_SIGNAL 5 /* signal notifications exist */
#define TIF_SECCOMP 6 /* seccomp syscall filtering active */
#define TIF_SYSCALL_TRACEPOINT 7 /* syscall tracepoint instrumentation */
+#define TIF_FD_SLOTS 8 /* syscall prepared descriptors */
#define TIF_DIE_IF_KERNEL 9 /* dik recursion lock */
#define TIF_MEMDIE 13 /* is terminating due to OOM killer */
#define TIF_POLLING_NRFLAG 14 /* idle is polling for TIF_NEED_RESCHED */@@ -80,6 +81,7 @@ register unsigned long *current_stack_pointer __asm__ ("$30");
#define _TIF_SECCOMP (1<<TIF_SECCOMP)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
+#define _TIF_FD_SLOTS (1<<TIF_FD_SLOTS)
/*
* Work to do on syscall entry (in entry.S).diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index 9f2608de2544..20372e926359 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -569,6 +569,13 @@ entSys:
$ret_success:
stq $0, 0($sp)
stq $31, 72($sp) /* a3=0 => no error */
+$syscall_exit:
+ /* Descriptors reserved by the syscall are committed in
+ syscall_trace_leave, off the return path interrupts share. */
+ ldl $17, TI_FLAGS($8)
+ lda $2, _TIF_FD_SLOTS
+ and $17, $2, $2
+ bne $2, $fd_slots_exit
.align 4
.globl ret_from_sys_call
@@ -612,7 +619,7 @@ $syscall_error:
stq $0, 0($sp)
mov $31, $26 /* tell "ret_from_sys_call" we can restart */
stq $1, 72($sp) /* a3 for return */
- br ret_from_sys_call
+ br $syscall_exit
/*
* Do all cleanup when returning from all interrupts and system calls.
@@ -648,6 +655,21 @@ $work_notifysig:
UNDO_SWITCH_STACK
br restore_all
+ .align 4
+$fd_slots_exit:
+ /* Keep the return address and the syscall restart state in
+ $26/$18/$19 across the call. */
+ DO_SWITCH_STACK
+ mov $26, $9
+ mov $18, $10
+ mov $19, $11
+ jsr $26, syscall_trace_leave
+ mov $9, $26
+ mov $10, $18
+ mov $11, $19
+ UNDO_SWITCH_STACK
+ br ret_from_sys_call
+
/*
* PTRACE syscall handler
*/
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index fc8f6cedbb28..736218b34601 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -6,6 +6,7 @@
/* more mutilation by David Mosberger (davidm@azstarnet.com) */
#include <linux/kernel.h>
+#include <linux/file.h>
#include <linux/sched.h>
#include <linux/sched/task_stack.h>
#include <linux/mm.h>
@@ -507,6 +508,8 @@ asmlinkage unsigned long syscall_trace_enter(void)
asmlinkage void
syscall_trace_leave(void)
{
+ if (test_thread_flag(TIF_FD_SLOTS))
+ fd_slots_commit(current_pt_regs());
audit_syscall_exit(current_pt_regs());
if (test_thread_flag(TIF_SYSCALL_TRACE))
ptrace_report_syscall_exit(current_pt_regs(), 0);
--
2.53.0