# From: Bodo Stroesser # # s390 syscalls might be done by a "svc X" instruction (2 bytes # in size) or a "exec X,Y" instruction (4 bytes in size). # There is no way to read the size of the instruction via ptrace, # so UML/s390 can't do syscall-restarting by resetting instruction # pointer to the value before the syscall. # Also, in most cases syscall number is hardcoded in the "SVC X" # instruction, so there is no way to handle ERESTART_RESTARTBLOCK # correctly by *really* restarting the syscall. # s390 host has implemented TIF_RESTART_SVC-flag to handle the # latter case. # In UML we have to use TIF_RESTART_SVC for both cases. # This patch implements TIF_RESTART_SVC in UML. # # Signed-off-by: Bodo Stroesser Index: linux-2.6.17/arch/um/include/kern_util.h =================================================================== --- linux-2.6.17.orig/arch/um/include/kern_util.h 2007-10-24 10:04:50.000000000 -0400 +++ linux-2.6.17/arch/um/include/kern_util.h 2007-11-19 11:13:31.000000000 -0500 @@ -65,7 +65,7 @@ extern void init_flush_vm(void); extern void *syscall_sp(void *t); extern void syscall_trace(struct uml_pt_regs *regs, int entryexit); extern unsigned int do_IRQ(int irq, struct uml_pt_regs *regs); -extern void interrupt_end(void); +extern int interrupt_end(void); extern void initial_thread_cb(void (*proc)(void *), void *arg); extern int debugger_signal(int status, int pid); extern void debugger_parent_signal(int status, int pid); Index: linux-2.6.17/arch/um/os-Linux/skas/process.c =================================================================== --- linux-2.6.17.orig/arch/um/os-Linux/skas/process.c 2007-10-24 10:04:50.000000000 -0400 +++ linux-2.6.17/arch/um/os-Linux/skas/process.c 2007-11-19 11:12:54.000000000 -0500 @@ -367,8 +367,12 @@ void userspace(struct uml_pt_regs *regs) printk(UM_KERN_ERR "userspace - child stopped " "with signal %d\n", sig); } +again: pid = userspace_pid[0]; - interrupt_end(); + if(interrupt_end()){ + handle_syscall(regs); + goto again; + } /* Avoid -ERESTARTSYS handling in host */ if (PT_SYSCALL_NR_OFFSET != PT_SYSCALL_RET_OFFSET) Index: linux-2.6.17/arch/um/kernel/process.c =================================================================== --- linux-2.6.17.orig/arch/um/kernel/process.c 2007-10-24 10:04:50.000000000 -0400 +++ linux-2.6.17/arch/um/kernel/process.c 2007-11-19 11:14:10.000000000 -0500 @@ -111,12 +111,17 @@ void *_switch_to(void *prev, void *next, } -void interrupt_end(void) +int interrupt_end(void) { if (need_resched()) schedule(); if (test_tsk_thread_flag(current, TIF_SIGPENDING)) do_signal(); +#ifdef TIF_RESTART_SVC + return test_and_clear_tsk_thread_flag(current, TIF_RESTART_SVC); +#else + return 0; +#endif } void exit_thread(void)