handling.
Update x86 to use the new infrastructure.
#include <linux/string.h>
#include <linux/bitops.h>
#include <linux/smp.h>
+#include <linux/thread_info.h>
+
#include <asm/processor.h>
-#include <asm/thread_info.h>
#include <asm/msr.h>
#include <asm/uaccess.h>
#include <linux/kernel.h>
#include <linux/config.h>
#include <linux/smp.h>
+#include <linux/thread_info.h>
+
#include <asm/processor.h>
#include <asm/system.h>
-#include <asm/thread_info.h>
#include "mce.h"
.data
ENTRY(sys_call_table)
- .long sys_ni_syscall /* 0 - old "setup()" system call*/
+ .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
.long sys_exit
.long sys_fork
.long sys_read
if (regs->orig_eax >= 0) {
/* If so, check system call restarting.. */
switch (regs->eax) {
+ case -ERESTART_RESTARTBLOCK:
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
case -ERESTARTNOHAND:
regs->eax = -EINTR;
break;
regs->eax = regs->orig_eax;
regs->eip -= 2;
}
+ if (regs->eax == -ERESTART_RESTARTBLOCK){
+ regs->eax = __NR_restart_syscall;
+ regs->eip -= 2;
+ }
}
return 0;
}
#include <linux/smp.h>
#include <linux/oprofile.h>
#include <linux/pm.h>
-#include <asm/thread_info.h>
+#include <linux/thread_info.h>
#include <asm/nmi.h>
#include <asm/ptrace.h>
#include <asm/msr.h>
#ifndef _I386_CURRENT_H
#define _I386_CURRENT_H
-#include <asm/thread_info.h>
+#include <linux/thread_info.h>
struct task_struct;
* - if the contents of this structure are changed, the assembly constants must also be changed
*/
#ifndef __ASSEMBLY__
+
struct thread_info {
struct task_struct *task; /* main task structure */
struct exec_domain *exec_domain; /* execution domain */
0-0xBFFFFFFF for user-thead
0-0xFFFFFFFF for kernel-thread
*/
+ struct restart_block restart_block;
__u8 supervisor_stack[0];
};
#define TI_CPU 0x0000000C
#define TI_PRE_COUNT 0x00000010
#define TI_ADDR_LIMIT 0x00000014
+#define TI_RESTART_BLOCK 0x0000018
#endif
* preempt_count needs to be 1 initially, until the scheduler is functional.
*/
#ifndef __ASSEMBLY__
+
#define INIT_THREAD_INFO(tsk) \
{ \
.task = &tsk, \
.cpu = 0, \
.preempt_count = 1, \
.addr_limit = KERNEL_DS, \
+ .restart_block = { \
+ .fn = do_no_restart_syscall, \
+ }, \
}
#define init_thread_info (init_thread_union.thread_info)
* This file contains the system call numbers.
*/
+#define __NR_restart_syscall 0
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define ERESTARTNOINTR 513
#define ERESTARTNOHAND 514 /* restart if no handler.. */
#define ENOIOCTLCMD 515 /* No ioctl command */
+#define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */
/* Defined for the NFSv3 protocol */
#define EBADHANDLE 521 /* Illegal NFS file handle */
#ifndef _LINUX_THREAD_INFO_H
#define _LINUX_THREAD_INFO_H
+/*
+ * System call restart block.
+ */
+struct restart_block {
+ long (*fn)(struct restart_block *);
+ unsigned long arg0, arg1, arg2;
+};
+
+extern long do_no_restart_syscall(struct restart_block *parm);
+
#include <linux/bitops.h>
#include <asm/thread_info.h>
* System call entry points.
*/
+asmlinkage long sys_restart_syscall(void)
+{
+ struct thread_info *thread = current_thread_info();
+ return thread->restart_block.fn(&thread->restart_block);
+}
+
+long do_no_restart_syscall(struct restart_block *param)
+{
+ return -EINTR;
+}
+
+
/*
* We don't need to get the kernel lock - this is all local to this
* particular thread.. (and that's good, because this is _heavily_