diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/i386/Kconfig ./arch/i386/Kconfig
--- src-orig/arch/i386/Kconfig	2006-09-27 16:14:42.000000000 -0600
+++ ./arch/i386/Kconfig	2006-08-23 09:16:48.000000000 -0600
@@ -1089,6 +1089,8 @@
 
 source "crypto/Kconfig"
 
+source "hpc/Kconfig"
+
 source "lib/Kconfig"
 
 #
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/i386/kernel/asm-offsets.c ./arch/i386/kernel/asm-offsets.c
--- src-orig/arch/i386/kernel/asm-offsets.c	2006-09-27 16:14:42.000000000 -0600
+++ ./arch/i386/kernel/asm-offsets.c	2006-08-23 09:16:48.000000000 -0600
@@ -13,6 +13,7 @@
 #include <asm/fixmap.h>
 #include <asm/processor.h>
 #include <asm/thread_info.h>
+#include <hpc/task.h>
 
 #define DEFINE(sym, val) \
         asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -69,4 +70,13 @@
 
 	DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
 	DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL));
+
+#ifdef CONFIG_OPENMOSIX
+	OFFSET(TASK_om, task_struct, om);
+	OFFSET(OM_dflags, openmosix_task, dflags);
+	BLANK();
+
+	DEFINE(DDEPUTY, DDEPUTY);
+	DEFINE(DREMOTE, DREMOTE);
+#endif /* CONFIG_OPENMOSIX */
 }
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/i386/kernel/entry.S ./arch/i386/kernel/entry.S
--- src-orig/arch/i386/kernel/entry.S	2006-09-27 16:14:42.000000000 -0600
+++ ./arch/i386/kernel/entry.S	2006-08-23 09:16:48.000000000 -0600
@@ -50,6 +50,11 @@
 #include <asm/desc.h>
 #include "irq_vectors.h"
 
+#ifdef CONFIG_OPENMOSIX
+#include <asm/asm-offsets.h>
+#include "omasm.h"
+#endif /* CONFIG_OPENMOSIX */
+
 #define nr_syscalls ((syscall_table_size)/4)
 
 EBX		= 0x00
@@ -130,6 +135,19 @@
 	popl %eax
 	jmp syscall_exit
 
+#ifdef CONFIG_OPENMOSIX
+ENTRY(ret_from_deputy_fork)
+	pushl %eax
+	call schedule_tail
+	GET_THREAD_INFO(%ebp)
+	popl %eax
+	jmp syscall_exit
+
+ENTRY(ret_from_kickstart)
+	GET_THREAD_INFO(%ebp)
+	jmp syscall_exit
+#endif /* CONFIG OPENMOSIX */
+
 /*
  * Return to user mode is not as complex as all this looks,
  * but we want the default path for a system call return to
@@ -155,6 +173,9 @@
 	andl $_TIF_WORK_MASK, %ecx	# is there any work to be done on
 					# int/exception return?
 	jne work_pending
+#ifdef CONFIG_OPENMOSIX
+	call openmosix_pre_usermode
+#endif /* CONFIG_OPENMOSIX */
 	jmp restore_all
 
 #ifdef CONFIG_PREEMPT
@@ -207,8 +228,23 @@
 	jnz syscall_trace_entry
 	cmpl $(nr_syscalls), %eax
 	jae syscall_badsys
+#ifdef CONFIG_OPENMOSIX
+remote_or_local_sysenter:
+	movl TI_task(%ebp), %ebp
+	testl $DREMOTE, TASK_om+OM_dflags(%ebp)	# is this a DREMOTE task ?
+	jz sysenter_syscall_call
+sysenter_remote_syscall_call:
+	call *remote_sys_call_table(,%eax,4)
+	movl %eax,EAX(%esp)		# store the return value
+	jmp sysenter_exit
+sysenter_syscall_call:
+#endif /* CONFIG_OPENMOSIX */
 	call *sys_call_table(,%eax,4)
 	movl %eax,EAX(%esp)
+#ifdef CONFIG_OPENMOSIX
+sysenter_exit:
+	GET_THREAD_INFO(%ebp)
+#endif /* CONFIG_OPENMOSIX */
 	cli
 	movl TI_flags(%ebp), %ecx
 	testw $_TIF_ALLWORK_MASK, %cx
@@ -236,10 +272,21 @@
 	jnz syscall_trace_entry
 	cmpl $(nr_syscalls), %eax
 	jae syscall_badsys
+#ifdef CONFIG_OPENMOSIX
+remote_or_local_syscall:
+	movl TI_task(%ebp), %ebp
+	testl $DREMOTE, TASK_om+OM_dflags(%ebp)	# is this a DREMOTE task ?
+	jz syscall_call
+remote_syscall_call:
+	call *remote_sys_call_table(,%eax,4)
+	movl %eax,EAX(%esp)		# store the return value
+	jmp syscall_exit
+#endif /* CONFIG_OPENMOSIX */
 syscall_call:
 	call *sys_call_table(,%eax,4)
 	movl %eax,EAX(%esp)		# store the return value
 syscall_exit:
+	GET_THREAD_INFO(%ebp)
 	cli				# make sure we don't miss an interrupt
 					# setting need_resched or sigpending
 					# between sampling and the iret
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/i386/kernel/i387.c ./arch/i386/kernel/i387.c
--- src-orig/arch/i386/kernel/i387.c	2006-09-27 16:14:42.000000000 -0600
+++ ./arch/i386/kernel/i387.c	2006-08-23 09:16:48.000000000 -0600
@@ -86,7 +86,7 @@
  * FPU tag word conversions.
  */
 
-static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
+OM_NSTATIC inline unsigned short twd_i387_to_fxsr( unsigned short twd )
 {
 	unsigned int tmp; /* to avoid 16 bit prefixes in the code */
  
@@ -100,7 +100,7 @@
         return tmp;
 }
 
-static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave )
+OM_NSTATIC inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave )
 {
 	struct _fpxreg *st = NULL;
 	unsigned long tos = (fxsave->swd >> 11) & 7;
@@ -534,6 +534,13 @@
 	return fpvalid;
 }
 
+#ifdef CONFIG_OPENMOSIX
+int cpu_feature_has_fxsr(void)
+{
+	return cpu_has_fxsr;
+}
+#endif /* CONFIG_OPENMOSIX */
+
 int dump_task_extended_fpu(struct task_struct *tsk, struct user_fxsr_struct *fpu)
 {
 	int fpvalid = tsk_used_math(tsk) && cpu_has_fxsr;
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/i386/kernel/omasm.h ./arch/i386/kernel/omasm.h
--- src-orig/arch/i386/kernel/omasm.h	1969-12-31 17:00:00.000000000 -0700
+++ ./arch/i386/kernel/omasm.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,301 @@
+.data
+
+ENTRY(remote_sys_call_table)
+	.long om_sys_remote		/* 0 - old "setup()" system call, used for restarting */
+	.long om_sys_remote		/* sys_exit */
+	.long om_sys_fork		/* sys_fork */
+	.long om_sys_remote		/* sys_read */
+	.long om_sys_remote		/* sys_write */
+	.long om_sys_remote		/* sys_open */
+	.long om_sys_remote		/* sys_close */
+	.long om_sys_remote		/* sys_waitpid */
+	.long om_sys_remote		/* sys_creat */
+	.long om_sys_remote		/* sys_link */
+	.long om_sys_remote		/* sys_unlink */
+	.long om_sys_execve		/* sys_execve */
+	.long om_sys_remote		/* sys_chdir */
+	.long om_sys_remote		/* sys_time */
+	.long om_sys_remote		/* sys_mknod */
+	.long om_sys_remote		/* sys_chmod */
+	.long om_sys_remote		/* sys_lchown16 */
+	.long sys_ni_syscall
+	.long om_sys_remote		/* sys_stat */
+	.long om_sys_remote		/* sys_lseek */
+	.long om_sys_getpid		/* sys_getpid */
+	.long om_sys_remote		/* sys_mount */
+	.long om_sys_remote		/* sys_oldumount */
+	.long om_sys_local		/* sys_setuid16 */
+	.long om_sys_local		/* sys_getuid16 */
+	.long om_sys_remote		/* sys_stime */
+	.long om_sys_remote		/* sys_ptrace */
+	.long om_sys_remote		/* sys_alarm */
+	.long om_sys_remote		/* sys_fstat */
+	.long om_sys_local		/* sys_pause */
+	.long om_sys_remote		/* sys_utime */
+	.long sys_ni_syscall
+	.long sys_ni_syscall
+	.long om_sys_remote		/* sys_access */
+	.long om_sys_remote		/* sys_nice */
+	.long sys_ni_syscall
+	.long om_sys_remote		/* sys_sync */
+	.long om_sys_remote		/* sys_kill */
+	.long om_sys_remote		/* sys_rename */
+	.long om_sys_remote		/* sys_mkdir */
+	.long om_sys_remote		/* sys_rmdir */
+	.long om_sys_remote		/* sys_dup */
+	.long om_sys_remote		/* sys_pipe */
+	.long om_sys_remote		/* sys_times */
+	.long sys_ni_syscall
+	.long om_sys_local		/* sys_brk */
+	.long om_sys_local		/* sys_setgid16 */
+	.long om_sys_local		/* sys_getgid16 */
+	.long om_sys_local		/* sys_signal */
+	.long om_sys_local		/* sys_geteuid16 */
+	.long om_sys_local		/* sys_getegid16 */
+	.long om_sys_remote		/* sys_acct */
+	.long om_sys_remote		/* sys_umount */
+	.long sys_ni_syscall
+	.long om_sys_remote		/* sys_ioctl */
+	.long om_sys_remote		/* sys_fcntl */
+	.long sys_ni_syscall
+	.long om_sys_remote		/* sys_setpgid */
+	.long sys_ni_syscall
+	.long om_sys_remote		/* sys_olduname */
+	.long om_sys_remote		/* sys_umask */
+	.long om_sys_remote		/* sys_chroot */
+	.long om_sys_remote		/* sys_ustat */
+	.long om_sys_remote		/* sys_dup2 */
+	.long om_sys_remote		/* sys_getppid */
+	.long om_sys_remote		/* sys_getpgrp */
+	.long om_sys_remote		/* sys_setsid */
+	.long om_sys_local		/* sys_sigaction */
+	.long om_sys_remote		/* sys_sgetmask */
+	.long om_sys_remote		/* sys_ssetmask */
+	.long om_sys_local		/* sys_setreuid16 */
+	.long om_sys_local		/* sys_setregid16 */
+	.long om_sys_local		/* sys_sigsuspend */
+	.long om_sys_local		/* sys_sigpending */
+	.long om_sys_remote		/* sys_sethostname */
+	.long om_sys_remote		/* sys_setrlimit */
+	.long om_sys_remote		/* sys_old_getrlimit */
+	.long om_sys_remote		/* sys_getrusage */
+	.long om_sys_remote		/* sys_gettimeofday */
+	.long om_sys_remote		/* sys_settimeofday */
+	.long om_sys_remote		/* sys_getgroups16 */
+	.long om_sys_remote		/* sys_setgroups16 */
+	.long om_sys_remote		/* old_select */
+	.long om_sys_remote		/* sys_symlink */
+	.long om_sys_remote		/* sys_lstat */
+	.long om_sys_remote		/* sys_readlink */
+	.long om_sys_remote		/* sys_uselib */
+	.long om_sys_remote		/* sys_swapon */
+	.long om_sys_remote		/* sys_reboot */
+	.long om_sys_remote		/* old_readdir */
+	.long om_sys_local		/* old_mmap */
+	.long om_sys_local		/* sys_munmap */
+	.long om_sys_remote		/* sys_truncate */
+	.long om_sys_remote		/* sys_ftruncate */
+	.long om_sys_remote		/* sys_fchmod */
+	.long om_sys_remote		/* sys_fchown16 */
+	.long om_sys_remote		/* sys_getpriority */
+	.long om_sys_remote		/* sys_setpriority */
+	.long sys_ni_syscall
+	.long om_sys_remote		/* sys_statfs */
+	.long om_sys_remote		/* sys_fstatfs */
+	.long om_sys_remote		/* sys_ioperm */
+	.long om_sys_remote		/* sys_socketcall */
+	.long om_sys_remote		/* sys_syslog */
+	.long om_sys_remote		/* sys_setitimer */
+	.long om_sys_remote		/* sys_getitimer */
+	.long om_sys_remote		/* sys_newstat */
+	.long om_sys_remote		/* sys_newlstat */
+	.long om_sys_remote		/* sys_newfstat */
+	.long om_sys_remote		/* sys_uname */
+	.long om_sys_remote		/* sys_iopl */
+	.long om_sys_remote		/* sys_vhangup */
+	.long sys_ni_syscall
+	.long om_sys_remote		/* sys_vm86old */
+	.long om_sys_remote		/* sys_wait4 */
+	.long om_sys_remote		/* sys_swapoff */
+	.long om_sys_remote		/* sys_sysinfo */
+	.long om_sys_remote		/* sys_ipc */
+	.long om_sys_remote		/* sys_fsync */
+	.long om_sys_local		/* sys_sigreturn */
+	.long om_sys_clone		/* sys_clone */
+	.long om_sys_remote		/* sys_setdomainname */
+	.long om_sys_remote		/* sys_newuname */
+	.long om_sys_local		/* sys_modify_ldt */
+	.long om_sys_remote		/* sys_adjtimex */
+	.long om_sys_local		/* sys_mprotect */
+	.long om_sys_local		/* sys_sigprocmask */
+	.long sys_ni_syscall 
+	.long om_sys_remote		/* sys_init_module */
+	.long om_sys_remote		/* sys_delete_module */
+	.long sys_ni_syscall
+	.long om_sys_remote		/* sys_quotactl */
+	.long om_sys_remote		/* sys_getpgid */
+	.long om_sys_remote		/* sys_fchdir */
+	.long om_sys_remote		/* sys_bdflush */
+	.long om_sys_remote		/* sys_sysfs */
+	.long om_sys_remote		/* sys_personality */
+	.long sys_ni_syscall
+	.long om_sys_local		/* sys_setfsuid16 */
+	.long om_sys_local		/* sys_setfsgid16 */
+	.long om_sys_remote		/* sys_llseek */
+	.long om_sys_remote		/* sys_getdents */
+	.long om_sys_remote		/* sys_select */
+	.long om_sys_remote		/* sys_flock */
+	.long om_sys_remote		/* sys_msync */
+	.long om_sys_remote		/* sys_readv */
+	.long om_sys_remote		/* sys_writev */
+	.long om_sys_local		/* sys_getsid */
+	.long om_sys_remote		/* sys_fdatasync */
+	.long om_sys_remote		/* sys_sysctl */
+	.long om_sys_remote		/* sys_mlock */
+	.long om_sys_remote		/* sys_munlock */
+	.long om_sys_remote		/* sys_mlockall */
+	.long om_sys_remote		/* sys_munlockall */
+	.long om_sys_remote		/* sys_sched_setparam */
+	.long om_sys_remote		/* sys_sched_getparam */
+	.long om_sys_remote		/* sys_sched_setscheduler */
+	.long om_sys_remote		/* sys_sched_getscheduler */
+	.long om_sys_local		/* sys_sched_yield */
+	.long om_sys_remote		/* sys_sched_get_priority_max */
+	.long om_sys_remote		/* sys_sched_get_priority_min */
+	.long om_sys_remote		/* sys_sched_rr_get_interval */
+	.long om_sys_local		/* sys_nanosleep */
+	.long om_sys_local		/* sys_mremap */
+	.long om_sys_local		/* sys_setresuid16 */
+	.long om_sys_local		/* sys_getresuid16 */
+	.long om_sys_remote		/* sys_vm86 */
+	.long sys_ni_syscall
+	.long om_sys_remote		/* sys_poll */
+	.long om_sys_remote		/* sys_nfsservctl */
+	.long om_sys_local		/* sys_setresgid16 */
+	.long om_sys_local		/* sys_getresgid16 */
+	.long om_sys_remote		/* sys_prctl */
+	.long om_sys_local		/* sys_rt_sigreturn */
+	.long om_sys_local		/* sys_rt_sigaction */
+	.long om_sys_local		/* sys_rt_sigprocmask */
+	.long om_sys_local		/* sys_rt_sigpending */
+	.long om_sys_local		/* sys_rt_sigtimedwait */
+	.long om_sys_local		/* sys_rt_sigqueueinfo */
+	.long om_sys_local		/* sys_rt_sigsuspend */
+	.long om_sys_remote		/* sys_pread64 */
+	.long om_sys_remote		/* sys_pwrite64 */
+	.long om_sys_remote		/* sys_chown16 */
+	.long om_sys_remote		/* sys_getcwd */
+	.long om_sys_remote		/* sys_capget */
+	.long om_sys_remote		/* sys_capset */
+	.long om_sys_local		/* sys_sigaltstack */
+	.long om_sys_remote		/* sys_sendfile */
+	.long sys_ni_syscall
+	.long sys_ni_syscall
+	.long om_sys_remote		/* sys_vfork */
+	.long om_sys_remote		/* sys_getrlimit */
+	.long om_sys_local		/* sys_mmap2 */
+	.long om_sys_remote		/* sys_truncate64 */
+	.long om_sys_remote		/* sys_ftruncate64 */
+	.long om_sys_remote		/* sys_stat64 */
+	.long om_sys_remote		/* sys_lstat64 */
+	.long om_sys_remote		/* sys_fstat64 */
+	.long om_sys_remote		/* sys_lchown */
+	.long om_sys_local		/* sys_getuid */
+	.long om_sys_local		/* sys_getgid */
+	.long om_sys_local		/* sys_geteuid */
+	.long om_sys_local		/* sys_getegid */
+	.long om_sys_local		/* sys_setreuid */
+	.long om_sys_local		/* sys_setregid */
+	.long om_sys_remote		/* sys_getgroups */
+	.long om_sys_remote		/* sys_setgroups */
+	.long om_sys_remote		/* sys_fchown */
+	.long om_sys_local		/* sys_setresuid */
+	.long om_sys_local		/* sys_getresuid */
+	.long om_sys_local		/* sys_setresgid */
+	.long om_sys_local		/* sys_getresgid */
+	.long om_sys_remote		/* sys_chown */
+	.long om_sys_local		/* sys_setuid */
+	.long om_sys_local		/* sys_setgid */
+	.long om_sys_local		/* sys_setfsuid */
+	.long om_sys_local		/* sys_setfsgid */
+	.long om_sys_remote		/* sys_pivot_root */
+	.long om_sys_local		/* sys_mincore */
+	.long om_sys_local		/* sys_madvise */
+	.long om_sys_remote		/* sys_getdents64 */
+	.long om_sys_remote		/* sys_fcntl64 */
+	.long sys_ni_syscall
+	.long sys_ni_syscall
+	.long om_sys_gettid		/* sys_gettid */
+	.long om_sys_remote		/* sys_readahead */
+	.long om_sys_remote		/* sys_setxattr */
+	.long om_sys_remote		/* sys_lsetxattr */
+	.long om_sys_remote		/* sys_fsetxattr */
+	.long om_sys_remote		/* sys_getxattr */
+	.long om_sys_remote		/* sys_lgetxattr */
+	.long om_sys_remote		/* sys_fgetxattr */
+	.long om_sys_remote		/* sys_listxattr */
+	.long om_sys_remote		/* sys_llistxattr */
+	.long om_sys_remote		/* sys_flistxattr */
+	.long om_sys_remote		/* sys_removexattr */
+	.long om_sys_remote		/* sys_lremovexattr */
+	.long om_sys_remote		/* sys_fremovexattr */
+	.long om_sys_remote		/* sys_tkill */
+	.long om_sys_remote		/* sys_sendfile64 */
+	.long om_sys_local		/* sys_futex */
+	.long om_sys_remote		/* sys_sched_setaffinity */
+	.long om_sys_remote		/* sys_sched_getaffinity */
+	.long om_sys_remote		/* sys_set_thread_area */
+	.long om_sys_remote		/* sys_get_thread_area */
+	.long om_sys_remote		/* sys_io_setup */
+	.long om_sys_remote		/* sys_io_destroy */
+	.long om_sys_remote		/* sys_io_getevents */
+	.long om_sys_remote		/* sys_io_submit */
+	.long om_sys_remote		/* sys_io_cancel */
+	.long om_sys_remote		/* sys_fadvise64 */
+	.long sys_ni_syscall
+	.long om_sys_remote		/* sys_exit_group */
+	.long om_sys_remote		/* sys_lookup_dcookie */
+	.long om_sys_remote		/* sys_epoll_create */
+	.long om_sys_remote		/* sys_epoll_ctl */
+	.long om_sys_remote		/* sys_epoll_wait */
+	.long om_sys_remote		/* sys_remap_file_pages */
+	.long om_sys_remote		/* sys_set_tid_address */
+	.long om_sys_remote		/* sys_timer_create */
+	.long om_sys_remote		/* sys_timer_settime */
+	.long om_sys_remote		/* sys_timer_gettime */
+	.long om_sys_remote		/* sys_timer_getoverrun */
+	.long om_sys_remote		/* sys_timer_delete */
+	.long om_sys_remote		/* sys_clock_settime */
+	.long om_sys_remote		/* sys_clock_gettime */
+	.long om_sys_remote		/* sys_clock_getres */
+	.long om_sys_remote		/* sys_clock_nanosleep */
+	.long om_sys_remote		/* sys_statfs64 */
+	.long om_sys_remote		/* sys_fstatfs64 */	
+	.long om_sys_remote		/* sys_tgkill */
+	.long om_sys_remote		/* sys_utimes */
+	.long om_sys_remote		/* sys_fadvise64_64 */
+	.long sys_ni_syscall
+	.long om_sys_local		/* sys_mbind */
+	.long om_sys_remote		/* sys_get_mempolicy */
+	.long om_sys_remote		/* sys_set_mempolicy */
+	.long om_sys_remote		/* sys_mq_open */
+	.long om_sys_remote		/* sys_mq_unlink */
+	.long om_sys_remote		/* sys_mq_timedsend */
+	.long om_sys_remote		/* sys_mq_timedreceive */
+	.long om_sys_remote		/* sys_mq_notify */
+	.long om_sys_remote		/* sys_mq_getsetattr */
+	.long om_sys_remote		/* sys_kexec_load */
+	.long om_sys_remote		/* sys_waitid */
+	.long sys_ni_syscall
+	.long om_sys_remote		/* sys_add_key */
+	.long om_sys_remote		/* sys_request_key */
+	.long om_sys_remote		/* sys_keyctl */
+	.long om_sys_remote		/* sys_ioprio_set */
+	.long om_sys_remote		/* sys_ioprio_get */
+	.long om_sys_remote		/* sys_inotify_init */
+	.long om_sys_remote		/* sys_inotify_add_watch */
+	.long om_sys_remote		/* sys_inotify_rm_watch */
+
+remote_syscall_table_size=(.-remote_sys_call_table)
+.text
+
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/i386/kernel/process.c ./arch/i386/kernel/process.c
--- src-orig/arch/i386/kernel/process.c	2006-09-27 16:14:42.000000000 -0600
+++ ./arch/i386/kernel/process.c	2006-08-23 09:16:48.000000000 -0600
@@ -54,10 +54,13 @@
 
 #include <linux/err.h>
 
+#include <linux/hpc.h>
+
 #include <asm/tlbflush.h>
 #include <asm/cpu.h>
 
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+asmlinkage void ret_from_deputy_fork(void) __asm__("ret_from_deputy_fork");
 
 static int hlt_counter;
 
@@ -323,6 +326,10 @@
 extern void kernel_thread_helper(void);
 __asm__(".section .text\n"
 	".align 4\n"
+#ifdef CONFIG_OPENMOSIX
+	"user_thread_helper:\n\t"
+	"subl $60,%esp\n\t"
+#endif
 	"kernel_thread_helper:\n\t"
 	"movl %edx,%eax\n\t"
 	"pushl %edx\n\t"
@@ -355,6 +362,32 @@
 }
 EXPORT_SYMBOL(kernel_thread);
 
+#ifdef CONFIG_OPENMOSIX
+extern void user_thread_helper(void);
+/*
+ * Create an user thread
+ * difference from kernel_thread are: no CLONE_VM, SIGCHLD, and leave space
+ * on the stack for user registers pt_regs.
+ */
+int user_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+	struct pt_regs regs;
+
+	memset(&regs, 0, sizeof(regs));
+	regs.ebx = (unsigned long) fn;
+	regs.edx = (unsigned long) arg;
+	regs.xds = __USER_DS;
+	regs.xes = __USER_DS;
+	regs.orig_eax = -1;
+	regs.eip = (unsigned long) user_thread_helper;
+	regs.xcs = __KERNEL_CS;
+	regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
+	
+	/* Ok, create the new process.. */
+	return do_fork(flags | SIGCHLD | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
+}
+#endif /* CONFIG_OPENMOSIX */
+
 /*
  * Free current thread data structures etc..
  */
@@ -427,6 +460,10 @@
 	p->thread.esp0 = (unsigned long) (childregs+1);
 
 	p->thread.eip = (unsigned long) ret_from_fork;
+#ifdef CONFIG_OPENMOSIX
+	if (task_test_dflags(current, DDEPUTY))
+		p->thread.eip = (unsigned long) ret_from_deputy_fork;
+#endif /* CONFIG_OPENMOSIX */
 
 	savesegment(fs,p->thread.fs);
 	savesegment(gs,p->thread.gs);
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/i386/kernel/signal.c ./arch/i386/kernel/signal.c
--- src-orig/arch/i386/kernel/signal.c	2006-09-27 16:14:42.000000000 -0600
+++ ./arch/i386/kernel/signal.c	2006-08-23 09:16:48.000000000 -0600
@@ -565,7 +565,7 @@
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
  */
-static void fastcall do_signal(struct pt_regs *regs)
+OM_NSTATIC void fastcall do_signal(struct pt_regs *regs)
 {
 	siginfo_t info;
 	int signr;
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/i386/kernel/sys_i386.c ./arch/i386/kernel/sys_i386.c
--- src-orig/arch/i386/kernel/sys_i386.c	2006-09-27 16:14:42.000000000 -0600
+++ ./arch/i386/kernel/sys_i386.c	2006-08-23 09:16:48.000000000 -0600
@@ -23,6 +23,8 @@
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
 
+#include <linux/hpc.h>
+
 /*
  * sys_pipe() is the normal C calling standard for creating
  * a pipe. It's not the way Unix traditionally does this, though.
@@ -50,6 +52,10 @@
 
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 	if (!(flags & MAP_ANONYMOUS)) {
+#ifdef CONFIG_OPENMOSIX
+		if (task_test_dflags(current, DREMOTE))
+			return remote_do_mmap(addr, len, prot, flags, fd, pgoff);
+#endif
 		file = fget(fd);
 		if (!file)
 			goto out;
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/i386/kernel/vm86.c ./arch/i386/kernel/vm86.c
--- src-orig/arch/i386/kernel/vm86.c	2006-09-27 16:14:42.000000000 -0600
+++ ./arch/i386/kernel/vm86.c	2006-08-23 09:16:48.000000000 -0600
@@ -50,6 +50,8 @@
 #include <asm/tlbflush.h>
 #include <asm/irq.h>
 
+#include <linux/hpc.h>
+
 /*
  * Known problems:
  *
@@ -133,6 +135,11 @@
 	loadsegment(fs, current->thread.saved_fs);
 	loadsegment(gs, current->thread.saved_gs);
 	ret = KVM86->regs32;
+#ifdef CONFIG_OPENMOSIX
+	task_lock(current);
+	task_clear_stay(current, DSTAY_86);
+	task_unlock(current);
+#endif /* CONFIG_OPENMOSIX */
 	return ret;
 }
 
@@ -181,6 +188,13 @@
 	struct task_struct *tsk;
 	int tmp, ret = -EPERM;
 
+#ifdef CONFIG_OPENMOSIX
+	ret = -ENOMEM;
+	if (!task_go_home_for_reason(current, DSTAY_86))
+		goto out;
+	ret = -EPERM;
+#endif /* CONFIG_OPENMOSIX */
+
 	tsk = current;
 	if (tsk->thread.saved_esp0)
 		goto out;
@@ -240,6 +254,11 @@
 	ret = -EFAULT;
 	if (tmp)
 		goto out;
+#ifdef CONFIG_OPENMOSIX
+	ret = -ENOMEM;
+	if (!task_go_home_for_reason(current, DSTAY_86))
+		goto out;
+#endif /* CONFIG_OPENMOSIX */
 	info.regs32 = &regs;
 	info.vm86plus.is_vm86pus = 1;
 	tsk->thread.vm86_info = (struct vm86_struct __user *)v86;
@@ -329,6 +348,11 @@
 
 	regs32 = save_v86_state(regs16);
 	regs32->eax = retval;
+#ifdef CONFIG_OPENMOSIX
+	task_lock(current); 
+	task_clear_stay(current, DSTAY_86);
+	task_unlock(current);
+#endif /* CONFIG_OPENMOSIX */
 	__asm__ __volatile__("movl %0,%%esp\n\t"
 		"movl %1,%%ebp\n\t"
 		"jmp resume_userspace"
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/i386/lib/usercopy.c ./arch/i386/lib/usercopy.c
--- src-orig/arch/i386/lib/usercopy.c	2006-09-27 16:14:42.000000000 -0600
+++ ./arch/i386/lib/usercopy.c	2006-08-23 09:16:48.000000000 -0600
@@ -196,7 +196,10 @@
 	unsigned long res, tmp;
 
 	might_sleep();
-
+#ifdef CONFIG_OPENMOSIX
+	if (openmosix_memory_away())
+		return deputy_strnlen_user(s, n);
+#endif
 	__asm__ __volatile__(
 		"	testl %0, %0\n"
 		"	jz 3f\n"
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/ppc/Kconfig ./arch/ppc/Kconfig
--- src-orig/arch/ppc/Kconfig	2006-09-27 16:14:42.000000000 -0600
+++ ./arch/ppc/Kconfig	2006-08-23 09:16:48.000000000 -0600
@@ -1417,3 +1417,5 @@
 source "security/Kconfig"
 
 source "crypto/Kconfig"
+
+source "hpc/Kconfig"
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/ppc/kernel/asm-offsets.c ./arch/ppc/kernel/asm-offsets.c
--- src-orig/arch/ppc/kernel/asm-offsets.c	2006-09-27 16:14:42.000000000 -0600
+++ ./arch/ppc/kernel/asm-offsets.c	2006-08-23 09:16:48.000000000 -0600
@@ -26,6 +26,7 @@
 #include <asm/cputable.h>
 #include <asm/thread_info.h>
 #include <asm/vdso_datapage.h>
+#include <hpc/task.h>
 
 #define DEFINE(sym, val) \
 	asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -171,5 +172,12 @@
 	DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
 	DEFINE(CLOCK_REALTIME_RES, TICK_NSEC);
 
+#ifdef CONFIG_OPENMOSIX
+	DEFINE(TASK_om, offsetof(struct task_struct, om));
+	DEFINE(OM_dflags, offsetof(struct openmosix_task, dflags));
+	BLANK();
+	DEFINE(DDEPUTY, DDEPUTY);
+	DEFINE(DREMOTE, DREMOTE);
+#endif /* CONFIG_OPENMOSIX */
 	return 0;
 }
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/ppc/kernel/entry.S ./arch/ppc/kernel/entry.S
--- src-orig/arch/ppc/kernel/entry.S	2006-09-27 16:14:42.000000000 -0600
+++ ./arch/ppc/kernel/entry.S	2006-08-23 09:16:48.000000000 -0600
@@ -207,11 +207,25 @@
 	andi.	r11,r11,_TIF_SYSCALL_T_OR_A
 	bne-	syscall_dotrace
 syscall_dotrace_cont:
+#ifdef CONFIG_OPENMOSIX
+	lwz	r11, TASK_om+OM_dflags(r2)
+	andi.	r11, r11, DREMOTE
+	beq	local_syscall_load
+remote_syscall_load:
+	cmplwi	0,r0,NR_syscalls
+	lis	r10,remote_sys_call_table@h
+	ori	r10,r10,remote_sys_call_table@l
+	slwi	r0,r0,2
+	bge-	66f
+	b	fetch_syscall
+local_syscall_load:
+#endif /* CONFIG_OPENMOSIX */
 	cmplwi	0,r0,NR_syscalls
 	lis	r10,sys_call_table@h
 	ori	r10,r10,sys_call_table@l
 	slwi	r0,r0,2
 	bge-	66f
+fetch_syscall:
 	lwzx	r10,r10,r0	/* Fetch system call handler [ptr] */
 	mtlr	r10
 	addi	r9,r1,STACK_FRAME_OVERHEAD
@@ -271,6 +285,12 @@
 	li	r3,0
 	b	ret_from_syscall
 
+#ifdef CONFIG_OPENMOSIX
+	.globl	ret_from_kickstart
+ret_from_kickstart:
+	b	ret_from_syscall
+#endif /* CONFIG_OPENMOSIX */
+
 /* Traced system call support */
 syscall_dotrace:
 	SAVE_NVGPRS(r1)
@@ -643,6 +663,9 @@
 	bne	do_work
 
 restore_user:
+#ifdef CONFIG_OPENMOSIX
+	bl	openmosix_pre_usermode
+#endif /* CONFIG_OPENMOSIX */
 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
 	/* Check whether this process has its own DBCR0 value.  The single
 	   step bit tells us that dbcr0 should be loaded. */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/ppc/kernel/misc.S ./arch/ppc/kernel/misc.S
--- src-orig/arch/ppc/kernel/misc.S	2006-09-27 16:14:42.000000000 -0600
+++ ./arch/ppc/kernel/misc.S	2006-08-23 09:16:48.000000000 -0600
@@ -25,6 +25,11 @@
 #include <asm/thread_info.h>
 #include <asm/asm-offsets.h>
 
+#ifdef CONFIG_OPENMOSIX
+/* FIXME */
+#define SIGCHLD 17
+#endif /* CONFIG_OPENMOSIX */
+
 #ifdef CONFIG_8xx
 #define ISYNC_8xx isync
 #else
@@ -1031,6 +1036,39 @@
 	addi	r1,r1,16
 	blr
 
+#ifdef CONFIG_OPENMOSIX
+/*
+ * Create an user thread
+ *   user_thread(fn, arg, flags)
+ */
+_GLOBAL(user_thread)
+	stwu	r1,-16(r1)
+	stw	r30,8(r1)
+	stw	r31,12(r1)
+	mr	r30,r3		/* function */
+	mr	r31,r4		/* argument */
+	ori	r3,r5,SIGCHLD	/* flags */
+	oris	r3,r3,CLONE_UNTRACED>>16
+	li	r4,0		/* new sp (unused) */
+	li	r0,__NR_clone
+	sc
+	cmpi	0,r3,0		/* parent or child? */
+	bne	1f		/* return if parent */
+	li	r0,0		/* make top-level stack frame */
+	stwu	r0,-16(r1)
+	addi	r1,r1,-172	/* substract sizeof pt_regs to stack */
+	mtlr	r30		/* fn addr in lr */
+	mr	r3,r31		/* load arg and call fn */
+	blrl
+	li	r0,__NR_exit	/* exit if function returns */
+	li	r3,0
+	sc
+1:	lwz	r30,8(r1)
+	lwz	r31,12(r1)
+	addi	r1,r1,16
+	blr
+#endif /* CONFIG_OPENMOSIX */
+
 /*
  * This routine is just here to keep GCC happy - sigh...
  */
@@ -1048,3 +1086,283 @@
 	blr
 
 SYSCALL(execve)
+
+#ifdef CONFIG_OPENMOSIX
+	.data
+	.align 4
+_GLOBAL(remote_sys_call_table)
+	.long om_sys_remote	/* sys_restart_syscall */
+	.long om_sys_remote	/* sys_exit */
+	.long om_sys_remote	/* ppc_fork */
+	.long om_sys_remote	/* sys_read */
+	.long om_sys_remote	/* sys_write */
+	.long om_sys_remote	/* sys_open */
+	.long om_sys_remote	/* sys_close */
+	.long om_sys_remote	/* sys_waitpid */
+	.long om_sys_remote	/* sys_creat */
+	.long om_sys_remote	/* sys_link */
+	.long om_sys_remote	/* sys_unlink */
+	.long om_sys_remote	/* sys_execve */
+	.long om_sys_remote	/* sys_chdir */
+	.long om_sys_remote	/* sys_time */
+	.long om_sys_remote	/* sys_mknod */
+	.long om_sys_remote	/* sys_chmod */
+	.long om_sys_remote	/* sys_lchown */
+	.long sys_ni_syscall
+	.long om_sys_remote	/* sys_stat */
+	.long om_sys_remote	/* sys_lseek */
+	.long om_sys_getpid	/* sys_getpid */
+	.long om_sys_remote	/* sys_mount */
+	.long om_sys_remote	/* sys_oldumount */
+	.long om_sys_local	/* sys_setuid */
+	.long om_sys_local	/* sys_getuid */
+	.long om_sys_remote	/* sys_stime */
+	.long om_sys_remote	/* sys_ptrace */
+	.long om_sys_remote	/* sys_alarm */
+	.long om_sys_remote	/* sys_fstat */
+	.long om_sys_local	/* sys_pause */
+	.long om_sys_remote	/* sys_utime */
+	.long sys_ni_syscall
+	.long sys_ni_syscall
+	.long om_sys_remote	/* sys_access */
+	.long om_sys_remote	/* sys_nice */
+	.long sys_ni_syscall
+	.long om_sys_remote	/* sys_sync */
+	.long om_sys_remote	/* sys_kill */
+	.long om_sys_remote	/* sys_rename */
+	.long om_sys_remote	/* sys_mkdir */
+	.long om_sys_remote	/* sys_rmdir */
+	.long om_sys_remote	/* sys_dup */
+	.long om_sys_remote	/* sys_pipe */
+	.long om_sys_remote	/* sys_times */
+	.long sys_ni_syscall
+	.long om_sys_local	/* sys_brk */
+	.long om_sys_local	/* sys_setgid */
+	.long om_sys_local	/* sys_getgid */
+	.long om_sys_remote	/* sys_signal */
+	.long om_sys_local	/* sys_geteuid */
+	.long om_sys_local	/* sys_getegid */
+	.long om_sys_remote	/* sys_acct */
+	.long om_sys_remote	/* sys_umount  recycled never used phys()  */
+	.long sys_ni_syscall
+	.long om_sys_remote	/* sys_ioctl */
+	.long om_sys_remote	/* sys_fcntl */
+	.long sys_ni_syscall
+	.long om_sys_remote	/* sys_setpgid */
+	.long sys_ni_syscall
+	.long om_sys_remote	/* sys_olduname */
+	.long om_sys_remote	/* sys_umask */
+	.long om_sys_remote	/* sys_chroot */
+	.long om_sys_remote	/* sys_ustat */
+	.long om_sys_remote	/* sys_dup2 */
+	.long om_sys_remote	/* sys_getppid */
+	.long om_sys_remote	/* sys_getpgrp */
+	.long om_sys_remote	/* sys_setsid */
+	.long om_sys_remote	/* sys_sigaction */
+	.long om_sys_remote	/* sys_sgetmask */
+	.long om_sys_remote	/* sys_ssetmask */
+	.long om_sys_remote	/* sys_setreuid */
+	.long om_sys_remote	/* sys_setregid */
+	.long om_sys_remote	/* ppc_sigsuspend */
+	.long om_sys_remote	/* sys_sigpending */
+	.long om_sys_remote	/* sys_sethostname */
+	.long om_sys_remote	/* sys_setrlimit */
+	.long om_sys_remote	/* sys_old_getrlimit */
+	.long om_sys_remote	/* sys_getrusage */
+	.long om_sys_remote	/* sys_gettimeofday */
+	.long om_sys_remote	/* sys_settimeofday */
+	.long om_sys_remote	/* sys_getgroups */
+	.long om_sys_remote	/* sys_setgroups */
+	.long om_sys_remote	/* ppc_select */
+	.long om_sys_remote	/* sys_symlink */
+	.long om_sys_remote	/* sys_lstat */
+	.long om_sys_remote	/* sys_readlink */
+	.long om_sys_remote	/* sys_uselib */
+	.long om_sys_remote	/* sys_swapon */
+	.long om_sys_remote	/* sys_reboot */
+	.long om_sys_remote	/* old_readdir */
+	.long om_sys_local	/* sys_mmap */
+	.long om_sys_local	/* sys_munmap */
+	.long om_sys_remote	/* sys_truncate */
+	.long om_sys_remote	/* sys_ftruncate */
+	.long om_sys_remote	/* sys_fchmod */
+	.long om_sys_remote	/* sys_fchown */
+	.long om_sys_remote	/* sys_getpriority */
+	.long om_sys_remote	/* sys_setpriority */
+	.long sys_ni_syscall
+	.long om_sys_remote	/* sys_statfs */
+	.long om_sys_remote	/* sys_fstatfs */
+	.long sys_ni_syscall
+	.long om_sys_remote	/* sys_socketcall */
+	.long om_sys_remote	/* sys_syslog */
+	.long om_sys_remote	/* sys_setitimer */
+	.long om_sys_remote	/* sys_getitimer */
+	.long om_sys_remote	/* sys_newstat */
+	.long om_sys_remote	/* sys_newlstat */
+	.long om_sys_remote	/* sys_newfstat */
+	.long om_sys_remote	/* sys_uname */
+	.long sys_ni_syscall
+	.long om_sys_remote	/* sys_vhangup */
+	.long sys_ni_syscall
+	.long sys_ni_syscall
+	.long om_sys_remote	/* sys_wait4 */
+	.long om_sys_remote	/* sys_swapoff */
+	.long om_sys_remote	/* sys_sysinfo */
+	.long om_sys_remote	/* sys_ipc */
+	.long om_sys_remote	/* sys_fsync */
+	.long om_sys_remote	/* sys_sigreturn */
+	.long om_sys_remote	/* ppc_clone */
+	.long om_sys_remote	/* sys_setdomainname */
+	.long om_sys_remote	/* sys_newuname */
+	.long sys_ni_syscall
+	.long om_sys_remote	/* sys_adjtimex */
+	.long om_sys_remote	/* sys_mprotect */
+	.long om_sys_remote	/* sys_sigprocmask */
+	.long sys_ni_syscall
+	.long om_sys_remote	/* sys_init_module */
+	.long om_sys_remote	/* sys_delete_module */
+	.long sys_ni_syscall
+	.long om_sys_remote	/* sys_quotactl */
+	.long om_sys_remote	/* sys_getpgid */
+	.long om_sys_remote	/* sys_fchdir */
+	.long om_sys_remote	/* sys_bdflush */
+	.long om_sys_remote	/* sys_sysfs */
+	.long om_sys_remote	/* sys_personality */
+	.long sys_ni_syscall
+	.long om_sys_local	/* sys_setfsuid */
+	.long om_sys_local	/* sys_setfsgid */
+	.long om_sys_remote	/* sys_llseek */
+	.long om_sys_remote	/* sys_getdents */
+	.long om_sys_remote	/* ppc_select */
+	.long om_sys_remote	/* sys_flock */
+	.long om_sys_local	/* sys_msync */
+	.long om_sys_remote	/* sys_readv */
+	.long om_sys_remote	/* sys_writev */
+	.long om_sys_remote	/* sys_getsid */
+	.long om_sys_remote	/* sys_fdatasync */
+	.long om_sys_remote	/* sys_sysctl */
+	.long om_sys_remote	/* sys_mlock */
+	.long om_sys_remote	/* sys_munlock */
+	.long om_sys_remote	/* sys_mlockall */
+	.long om_sys_remote	/* sys_munlockall */
+	.long om_sys_remote	/* sys_sched_setparam */
+	.long om_sys_remote	/* sys_sched_getparam */
+	.long om_sys_remote	/* sys_sched_setscheduler */
+	.long om_sys_remote	/* sys_sched_getscheduler */
+	.long om_sys_local	/* sys_sched_yield */
+	.long om_sys_remote	/* sys_sched_get_priority_max */
+	.long om_sys_remote	/* sys_sched_get_priority_min */
+	.long om_sys_remote	/* sys_sched_rr_get_interval */
+	.long om_sys_local	/* sys_nanosleep */
+	.long om_sys_local	/* sys_mremap */
+	.long om_sys_local	/* sys_setresuid */
+	.long om_sys_local	/* sys_getresuid */
+	.long sys_ni_syscall
+	.long om_sys_remote	/* sys_poll */
+	.long om_sys_remote	/* sys_nfsservctl */
+	.long om_sys_local	/* sys_setresgid */
+	.long om_sys_local	/* sys_getresgid */
+	.long om_sys_remote	/* sys_prctl */
+	.long om_sys_remote	/* sys_rt_sigreturn */
+	.long om_sys_remote	/* sys_rt_sigaction */
+	.long om_sys_remote	/* sys_rt_sigprocmask */
+	.long om_sys_remote	/* sys_rt_sigpending */
+	.long om_sys_remote	/* sys_rt_sigtimedwait */
+	.long om_sys_remote	/* sys_rt_sigqueueinfo */
+	.long om_sys_remote	/* ppc_rt_sigsuspend */
+	.long om_sys_remote	/* sys_pread64 */
+	.long om_sys_remote	/* sys_pwrite64 */
+	.long om_sys_remote	/* sys_chown */
+	.long om_sys_remote	/* sys_getcwd */
+	.long om_sys_remote	/* sys_capget */
+	.long om_sys_remote	/* sys_capset */
+	.long om_sys_remote	/* sys_sigaltstack */
+	.long om_sys_remote	/* sys_sendfile */
+	.long sys_ni_syscall
+	.long sys_ni_syscall
+	.long om_sys_remote	/* ppc_vfork */
+	.long om_sys_remote	/* sys_getrlimit */
+	.long om_sys_remote	/* sys_readahead */
+	.long om_sys_local	/* sys_mmap2 */
+	.long om_sys_remote	/* sys_truncate64 */
+	.long om_sys_remote	/* sys_ftruncate64 */
+	.long om_sys_remote	/* sys_stat64 */
+	.long om_sys_remote	/* sys_lstat64 */
+	.long om_sys_remote	/* sys_fstat64 */
+	.long om_sys_remote	/* sys_pciconfig_read */
+	.long om_sys_remote	/* sys_pciconfig_write */
+	.long om_sys_remote	/* sys_pciconfig_iobase */
+	.long sys_ni_syscall
+	.long om_sys_remote	/* sys_getdents64 */
+	.long om_sys_remote	/* sys_pivot_root */
+	.long om_sys_remote	/* sys_fcntl64 */
+	.long om_sys_local	/* sys_madvise */
+	.long om_sys_local	/* sys_mincore */
+	.long om_sys_gettid	/* sys_gettid */
+	.long om_sys_remote	/* sys_tkill */
+	.long om_sys_remote	/* sys_setxattr */
+	.long om_sys_remote	/* sys_lsetxattr */
+	.long om_sys_remote	/* sys_fsetxattr */
+	.long om_sys_remote	/* sys_getxattr */
+	.long om_sys_remote	/* sys_lgetxattr */
+	.long om_sys_remote	/* sys_fgetxattr */
+	.long om_sys_remote	/* sys_listxattr */
+	.long om_sys_remote	/* sys_llistxattr */
+	.long om_sys_remote	/* sys_flistxattr */
+	.long om_sys_remote	/* sys_removexattr */
+	.long om_sys_remote	/* sys_lremovexattr */
+	.long om_sys_remote	/* sys_fremovexattr */
+	.long om_sys_remote	/* sys_futex */
+	.long om_sys_remote	/* sys_sched_setaffinity */
+	.long om_sys_remote	/* sys_sched_getaffinity */
+	.long sys_ni_syscall
+	.long sys_ni_syscall
+	.long om_sys_remote	/* sys_sendfile64 */
+	.long om_sys_remote	/* sys_io_setup */
+	.long om_sys_remote	/* sys_io_destroy */
+	.long om_sys_remote	/* sys_io_getevents */
+	.long om_sys_remote	/* sys_io_submit */
+	.long om_sys_remote	/* sys_io_cancel */
+	.long om_sys_remote	/* sys_set_tid_address */
+	.long om_sys_remote	/* sys_fadvise64 */
+	.long om_sys_remote	/* sys_exit_group */
+	.long om_sys_remote	/* sys_lookup_dcookie */
+	.long om_sys_remote	/* sys_epoll_create */
+	.long om_sys_remote	/* sys_epoll_ctl */
+	.long om_sys_remote	/* sys_epoll_wait */
+	.long om_sys_remote	/* sys_remap_file_pages */
+	.long om_sys_remote	/* sys_timer_create */
+	.long om_sys_remote	/* sys_timer_settime */
+	.long om_sys_remote	/* sys_timer_gettime */
+	.long om_sys_remote	/* sys_timer_getoverrun */
+	.long om_sys_remote	/* sys_timer_delete */
+	.long om_sys_remote	/* sys_clock_settime */
+	.long om_sys_remote	/* sys_clock_gettime */
+	.long om_sys_remote	/* sys_clock_getres */
+	.long om_sys_remote	/* sys_clock_nanosleep */
+	.long om_sys_remote	/* ppc_swapcontext */
+	.long om_sys_remote	/* sys_tgkill */
+	.long om_sys_remote	/* sys_utimes */
+	.long om_sys_remote	/* sys_statfs64 */
+	.long om_sys_remote	/* sys_fstatfs64 */
+	.long om_sys_remote	/* ppc_fadvise64_64 */
+	.long sys_ni_syscall
+	.long sys_ni_syscall
+	.long sys_ni_syscall
+	.long sys_ni_syscall
+	.long sys_ni_syscall
+	.long sys_ni_syscall
+	.long sys_ni_syscall
+	.long om_sys_remote	/* sys_mq_open */
+	.long om_sys_remote	/* sys_mq_unlink */
+	.long om_sys_remote	/* sys_mq_timedsend */
+	.long om_sys_remote	/* sys_mq_timedreceive */
+	.long om_sys_remote	/* sys_mq_notify */
+	.long om_sys_remote	/* sys_mq_getsetattr */
+	.long sys_ni_syscall
+	.long om_sys_remote	/* sys_add_key */
+	.long om_sys_remote	/* sys_request_key */
+	.long om_sys_remote	/* sys_keyctl */
+	.long om_sys_remote	/* sys_waitid */
+
+#endif /* CONFIG_OPENMOSIX */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/x86_64/Kconfig ./arch/x86_64/Kconfig
--- src-orig/arch/x86_64/Kconfig	2006-09-27 16:14:42.000000000 -0600
+++ ./arch/x86_64/Kconfig	2006-08-23 09:16:48.000000000 -0600
@@ -619,4 +619,6 @@
 
 source "crypto/Kconfig"
 
+source "hpc/Kconfig"
+
 source "lib/Kconfig"
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/x86_64/kernel/asm-offsets.c ./arch/x86_64/kernel/asm-offsets.c
--- src-orig/arch/x86_64/kernel/asm-offsets.c	2006-09-27 16:14:42.000000000 -0600
+++ ./arch/x86_64/kernel/asm-offsets.c	2006-08-23 09:16:48.000000000 -0600
@@ -14,6 +14,9 @@
 #include <asm/segment.h>
 #include <asm/thread_info.h>
 #include <asm/ia32.h>
+#ifdef CONFIG_OPENMOSIX
+#include <hpc/task.h>
+#endif
 
 #define DEFINE(sym, val) \
         asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -27,9 +30,13 @@
 	ENTRY(flags); 
 	ENTRY(thread); 
 	ENTRY(pid);
+#ifdef CONFIG_OPENMOSIX
+	DEFINE(TASK_om, offsetof(struct task_struct, om));
+#endif /* CONFIG_OPENMOSIX */
 	BLANK();
 #undef ENTRY
 #define ENTRY(entry) DEFINE(threadinfo_ ## entry, offsetof(struct thread_info, entry))
+	ENTRY(task);
 	ENTRY(flags);
 	ENTRY(addr_limit);
 	ENTRY(preempt_count);
@@ -68,5 +75,11 @@
 	DEFINE(pbe_next, offsetof(struct pbe, next));
 	BLANK();
 	DEFINE(TSS_ist, offsetof(struct tss_struct, ist));
+#ifdef CONFIG_OPENMOSIX
+	DEFINE(OM_dflags, offsetof(struct openmosix_task, dflags));
+	BLANK();
+	DEFINE(DDEPUTY, DDEPUTY);
+	DEFINE(DREMOTE, DREMOTE);
+#endif /* CONFIG_OPENMOSIX */
 	return 0;
 }
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/x86_64/kernel/entry.S ./arch/x86_64/kernel/entry.S
--- src-orig/arch/x86_64/kernel/entry.S	2006-09-27 16:14:42.000000000 -0600
+++ ./arch/x86_64/kernel/entry.S	2006-08-23 09:16:48.000000000 -0600
@@ -43,6 +43,10 @@
 #include <asm/hw_irq.h>
 #include <asm/page.h>
 
+#ifdef CONFIG_OPENMOSIX
+#include "omasm.h"
+#endif /* CONFIG_OPENMOSIX */
+
 	.code64
 
 #ifndef CONFIG_PREEMPT
@@ -155,6 +159,15 @@
 	jmp rff_action
 	CFI_ENDPROC
 
+#ifdef CONFIG_OPENMOSIX
+ENTRY(ret_from_kickstart)
+	CFI_STARTPROC
+	swapgs
+	RESTORE_ALL 8
+	iretq
+	CFI_ENDPROC
+#endif /* CONFIG OPENMOSIX */
+
 /*
  * System call entry. Upto 6 arguments in registers are supported.
  *
@@ -205,6 +218,20 @@
 	jnz tracesys
 	cmpq $__NR_syscall_max,%rax
 	ja badsys
+#ifdef CONFIG_OPENMOSIX
+remote_or_local_syscall:
+	movq threadinfo_task(%rcx), %rcx
+	testq $DREMOTE, TASK_om+OM_dflags(%rcx) # is this a DREMOTE task ?
+	jz syscall_call
+remote_syscall_call:
+	movq %r10,%rcx
+	subq $6*8, %rsp
+	call *remote_sys_call_table(,%rax,8)
+	addq $6*8, %rsp
+	movq %rax,RAX-ARGOFFSET(%rsp)
+	jmp ret_from_sys_call
+syscall_call:
+#endif /* CONFIG_OPENMOSIX */
 	movq %r10,%rcx
 	call *sys_call_table(,%rax,8)  # XXX:	 rip relative
 	movq %rax,RAX-ARGOFFSET(%rsp)
@@ -370,6 +397,13 @@
  */ 								
 	
 	.macro PTREGSCALL label,func,arg
+#ifdef CONFIG_OPENMOSIX
+	.globl om_\label
+om_\label:
+	leaq	om_\func(%rip),%rax
+	leaq    -ARGOFFSET+8(%rsp),\arg /* 8 for return address */
+	jmp	om_ptregscall_common
+#endif
 	.globl \label
 \label:
 	leaq	\func(%rip),%rax
@@ -405,6 +439,26 @@
 	ret
 	CFI_ENDPROC
 	
+#ifdef CONFIG_OPENMOSIX
+ENTRY(om_ptregscall_common)
+	CFI_STARTPROC
+	addq $6*8, %rsp
+	popq %r11
+	CFI_ADJUST_CFA_OFFSET	-8
+	SAVE_REST
+	movq %r11, %r15
+	FIXUP_TOP_OF_STACK %r11
+	call *%rax
+	RESTORE_TOP_OF_STACK %r11
+	movq %r15, %r11
+	RESTORE_REST
+	pushq %r11
+	subq $6*8, %rsp
+	CFI_ADJUST_CFA_OFFSET	8
+	ret
+	CFI_ENDPROC
+#endif
+
 ENTRY(stub_execve)
 	CFI_STARTPROC
 	popq %r11
@@ -418,6 +472,27 @@
 	RESTORE_REST
 	jmp int_ret_from_sys_call
 	CFI_ENDPROC
+
+#ifdef CONFIG_OPENMOSIX
+ENTRY(om_stub_execve)
+	CFI_STARTPROC
+	popq %r11
+	CFI_ADJUST_CFA_OFFSET	-8
+	SAVE_REST
+	movq %r11, %r15
+	FIXUP_TOP_OF_STACK %r11
+	call remote_do_execve
+	GET_THREAD_INFO(%rcx)
+	# FIXME om doesn't support remote 32 bits tasks yet
+	#bt $TIF_IA32,threadinfo_flags(%rcx)
+	#jc exec_32bit
+	RESTORE_TOP_OF_STACK %r11
+	movq %r15, %r11
+	RESTORE_REST
+	push %r11
+	ret
+	CFI_ENDPROC
+#endif
 	
 /*
  * sigreturn is special because it needs to restore all registers on return.
@@ -551,6 +626,11 @@
 	bt    $TIF_NEED_RESCHED,%edx
 	jnc   retint_signal
 	sti
+#ifdef CONFIG_OPENMOSIX
+	SAVE_REST
+	call openmosix_pre_usermode
+	RESTORE_REST
+#endif /* CONFIG_OPENMOSIX */
 	pushq %rdi
 	CFI_ADJUST_CFA_OFFSET	8
 	call  schedule
@@ -861,6 +941,43 @@
 	xorl %edi, %edi
 	call do_exit
 
+#ifdef CONFIG_OPENMOSIX
+ENTRY(user_thread)
+	CFI_STARTPROC
+	FAKE_STACK_FRAME $user_child_rip
+	SAVE_ALL
+
+	# rdi: flags, rsi: usp, rdx: will be &pt_regs
+	movq %rdx,%rdi
+	orq  kernel_thread_flags(%rip),%rdi
+	movq $-1, %rsi
+	movq %rsp, %rdx
+
+	xorl %r8d,%r8d
+	xorl %r9d,%r9d
+	
+	# clone now
+	call do_fork
+	movq %rax,RAX(%rsp)
+	xorl %edi,%edi
+
+	/*
+	 * It isn't worth to check for reschedule here,
+	 * so internally to the x86_64 port you can rely on kernel_thread()
+	 * not to reschedule the child before returning, this avoids the need
+	 * of hacks for example to fork off the per-CPU idle tasks.
+         * [Hopefully no generic code relies on the reschedule -AK]	
+	 */
+	RESTORE_ALL
+	UNFAKE_STACK_FRAME
+	ret
+	CFI_ENDPROC
+
+user_child_rip:
+	subq $168, %rsp
+	jmp child_rip
+#endif /* CONFIG_OPENMOSIX */
+
 /*
  * execve(). This function needs to use IRET, not SYSRET, to set up all state properly.
  *
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/x86_64/kernel/omasm.h ./arch/x86_64/kernel/omasm.h
--- src-orig/arch/x86_64/kernel/omasm.h	1969-12-31 17:00:00.000000000 -0700
+++ ./arch/x86_64/kernel/omasm.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,263 @@
+.data
+
+ENTRY(remote_sys_call_table)
+	.quad om_sys_remote		/* 0 sys_read */
+	.quad om_sys_remote		/* 1 sys_write */
+	.quad om_sys_remote		/* 2 sys_open */
+	.quad om_sys_remote		/* 3 sys_close */
+	.quad om_sys_remote		/* 4 sys_newstat */
+	.quad om_sys_remote		/* 5 sys_newfstat */
+	.quad om_sys_remote		/* 6 sys_newlstat */
+	.quad om_sys_remote		/* 7 sys_poll */
+	.quad om_sys_remote		/* 8 sys_lseek */
+	.quad sys_mmap			/* 9 sys_mmap */
+	.quad om_sys_local		/* 10 sys_mprotect */
+	.quad om_sys_local		/* 11 sys_munmap */
+	.quad om_sys_local		/* 12 sys_brk */
+	.quad om_sys_local		/* 13 sys_rt_sigaction */
+	.quad om_sys_local		/* 14 sys_rt_sigprocmask */
+	.quad stub_rt_sigreturn		/* 15 stub_rt_sigreturn */
+	.quad om_sys_remote		/* 16 sys_ioctl */
+	.quad om_sys_remote		/* 17 sys_pread64 */
+	.quad om_sys_remote		/* 18 sys_pwrite64 */
+	.quad om_sys_remote		/* 19 sys_readv */
+	.quad om_sys_remote		/* 20 sys_writev */
+	.quad om_sys_remote		/* 21 sys_access */
+	.quad om_sys_remote		/* 22 sys_pipe */
+	.quad om_sys_remote		/* 23 sys_select */
+	.quad om_sys_remote		/* 24 sys_sched_yield */
+	.quad om_sys_local		/* 25 sys_mremap */
+	.quad om_sys_local		/* 26 sys_msync */
+	.quad om_sys_local		/* 27 sys_mincore */
+	.quad om_sys_local		/* 28 sys_madvise */
+	.quad om_sys_remote		/* 29 sys_shmget */
+	.quad om_sys_remote		/* 30 wrap_sys_shmat */
+	.quad om_sys_remote		/* 31 sys_shmctl */
+	.quad om_sys_remote		/* 32 sys_dup */
+	.quad om_sys_remote		/* 33 sys_dup2 */
+	.quad om_sys_local		/* 34 sys_pause */
+	.quad om_sys_local		/* 35 sys_nanosleep */
+	.quad om_sys_remote		/* 36 sys_getitimer */
+	.quad om_sys_remote		/* 37 sys_alarm */
+	.quad om_sys_remote		/* 38 sys_setitimer */
+	.quad om_sys_getpid		/* 39 sys_getpid */
+	.quad om_sys_remote		/* 40 sys_sendfile64 */
+	.quad om_sys_remote		/* 41 sys_socket */
+	.quad om_sys_remote		/* 42 sys_connect */
+	.quad om_sys_remote		/* 43 sys_accept */
+	.quad om_sys_remote		/* 44 sys_sendto */
+	.quad om_sys_remote		/* 45 sys_recvfrom */
+	.quad om_sys_remote		/* 46 sys_sendmsg */
+	.quad om_sys_remote		/* 47 sys_recvmsg */
+	.quad om_sys_remote		/* 48 sys_shutdown */
+	.quad om_sys_remote		/* 49 sys_bind */
+	.quad om_sys_remote		/* 50 sys_listen */
+	.quad om_sys_remote		/* 51 sys_getsockname */
+	.quad om_sys_remote		/* 52 sys_getpeername */
+	.quad om_sys_remote		/* 53 sys_socketpair */
+	.quad om_sys_remote		/* 54 sys_setsockopt */
+	.quad om_sys_remote		/* 55 sys_getsockopt */
+	.quad om_stub_clone		/* 56 stub_clone */
+	.quad om_stub_fork		/* 57 stub_fork */
+	.quad om_stub_vfork		/* 58 stub_vfork */
+	.quad om_stub_execve		/* 59 stub_execve */
+	.quad om_sys_remote		/* 60 sys_exit */
+	.quad om_sys_remote		/* 61 sys_wait4 */
+	.quad om_sys_remote		/* 62 sys_kill */
+	.quad om_sys_remote		/* 63 sys_uname */
+	.quad om_sys_remote		/* 64 sys_semget */
+	.quad om_sys_remote		/* 65 sys_semop */
+	.quad om_sys_remote		/* 66 sys_semctl */
+	.quad om_sys_remote		/* 67 sys_shmdt */
+	.quad om_sys_remote		/* 68 sys_msgget */
+	.quad om_sys_remote		/* 69 sys_msgsnd */
+	.quad om_sys_remote		/* 70 sys_msgrcv */
+	.quad om_sys_remote		/* 71 sys_msgctl */
+	.quad om_sys_remote		/* 72 sys_fcntl */
+	.quad om_sys_remote		/* 73 sys_flock */
+	.quad om_sys_remote		/* 74 sys_fsync */
+	.quad om_sys_remote		/* 75 sys_fdatasync */
+	.quad om_sys_remote		/* 76 sys_truncate */
+	.quad om_sys_remote		/* 77 sys_ftruncate */
+	.quad om_sys_remote		/* 78 sys_getdents */
+	.quad om_sys_remote		/* 79 sys_getcwd */
+	.quad om_sys_remote		/* 80 sys_chdir */
+	.quad om_sys_remote		/* 81 sys_fchdir */
+	.quad om_sys_remote		/* 82 sys_rename */
+	.quad om_sys_remote		/* 83 sys_mkdir */
+	.quad om_sys_remote		/* 84 sys_rmdir */
+	.quad om_sys_remote		/* 85 sys_creat */
+	.quad om_sys_remote		/* 86 sys_link */
+	.quad om_sys_remote		/* 87 sys_unlink */
+	.quad om_sys_remote		/* 88 sys_symlink */
+	.quad om_sys_remote		/* 89 sys_readlink */
+	.quad om_sys_remote		/* 90 sys_chmod */
+	.quad om_sys_remote		/* 91 sys_fchmod */
+	.quad om_sys_remote		/* 92 sys_chown */
+	.quad om_sys_remote		/* 93 sys_fchown */
+	.quad om_sys_remote		/* 94 sys_lchown */
+	.quad om_sys_remote		/* 95 sys_umask */
+	.quad om_sys_remote		/* 96 sys_gettimeofday */
+	.quad om_sys_remote		/* 97 sys_getrlimit */
+	.quad om_sys_remote		/* 98 sys_getrusage */
+	.quad om_sys_remote		/* 99 sys_sysinfo */
+	.quad om_sys_remote		/* 100 sys_times */
+	.quad om_sys_remote		/* 101 sys_ptrace */
+	.quad om_sys_remote		/* 102 sys_getuid */
+	.quad om_sys_remote		/* 103 sys_syslog */
+	.quad om_sys_remote		/* 104 sys_getgid */
+	.quad om_sys_remote		/* 105 sys_setuid */
+	.quad om_sys_remote		/* 106 sys_setgid */
+	.quad om_sys_remote		/* 107 sys_geteuid */
+	.quad om_sys_remote		/* 108 sys_getegid */
+	.quad om_sys_remote		/* 109 sys_setpgid */
+	.quad om_sys_remote		/* 110 sys_getppid */
+	.quad om_sys_remote		/* 111 sys_getpgrp */
+	.quad om_sys_remote		/* 112 sys_setsid */
+	.quad om_sys_remote		/* 113 sys_setreuid */
+	.quad om_sys_remote		/* 114 sys_setregid */
+	.quad om_sys_remote		/* 115 sys_getgroups */
+	.quad om_sys_remote		/* 116 sys_setgroups */
+	.quad om_sys_remote		/* 117 sys_setresuid */
+	.quad om_sys_remote		/* 118 sys_getresuid */
+	.quad om_sys_local		/* 119 sys_setresgid */
+	.quad om_sys_local		/* 120 sys_getresgid */
+	.quad om_sys_remote		/* 121 sys_getpgid */
+	.quad om_sys_local		/* 122 sys_setfsuid */
+	.quad om_sys_local		/* 123 sys_setfsgid */
+	.quad om_sys_local		/* 124 sys_getsid */
+	.quad om_sys_remote		/* 125 sys_capget */
+	.quad om_sys_remote		/* 126 sys_capset */
+	.quad om_sys_local		/* 127 sys_rt_sigpending */
+	.quad om_sys_local		/* 128 sys_rt_sigtimedwait */
+	.quad om_sys_local		/* 129 sys_rt_sigqueueinfo */
+	.quad om_stub_rt_sigsuspend	/* 130 stub_rt_sigsuspend */
+	.quad om_stub_sigaltstack	/* 131 stub_sigaltstack */
+	.quad om_sys_remote		/* 132 sys_utime */
+	.quad om_sys_remote		/* 133 sys_mknod */
+	.quad om_sys_remote		/* 134 sys_uselib */
+	.quad om_sys_remote		/* 135 sys_personality */
+	.quad om_sys_remote		/* 136 sys_ustat */
+	.quad om_sys_remote		/* 137 sys_statfs */
+	.quad om_sys_remote		/* 138 sys_fstatfs */
+	.quad om_sys_remote		/* 139 sys_sysfs */
+	.quad om_sys_remote		/* 140 sys_getpriority */
+	.quad om_sys_remote		/* 141 sys_setpriority */
+	.quad om_sys_remote		/* 142 sys_sched_setparam */
+	.quad om_sys_remote		/* 143 sys_sched_getparam */
+	.quad om_sys_remote		/* 144 sys_sched_setscheduler */
+	.quad om_sys_remote		/* 145 sys_sched_getscheduler */
+	.quad om_sys_remote		/* 146 sys_sched_get_priority_max */
+	.quad om_sys_remote		/* 147 sys_sched_get_priority_min */
+	.quad om_sys_remote		/* 148 sys_sched_rr_get_interval */
+	.quad om_sys_remote		/* 149 sys_mlock */
+	.quad om_sys_remote		/* 150 sys_munlock */
+	.quad om_sys_remote		/* 151 sys_mlockall */
+	.quad om_sys_remote		/* 152 sys_munlockall */
+	.quad om_sys_remote		/* 153 sys_vhangup */
+	.quad om_sys_remote		/* 154 sys_modify_ldt */
+	.quad om_sys_remote		/* 155 sys_pivot_root */
+	.quad om_sys_remote		/* 156 sys_sysctl */
+	.quad om_sys_remote		/* 157 sys_prctl */
+	.quad om_sys_remote		/* 158 sys_arch_prctl */
+	.quad om_sys_remote		/* 159 sys_adjtimex */
+	.quad om_sys_remote		/* 160 sys_setrlimit */
+	.quad om_sys_remote		/* 161 sys_chroot */
+	.quad om_sys_remote		/* 162 sys_sync */
+	.quad om_sys_remote		/* 163 sys_acct */
+	.quad om_sys_remote		/* 164 sys_settimeofday */
+	.quad om_sys_remote		/* 165 sys_mount */
+	.quad om_sys_remote		/* 166 sys_umount */
+	.quad om_sys_remote		/* 167 sys_swapon */
+	.quad om_sys_remote		/* 168 sys_swapoff */
+	.quad om_sys_remote		/* 169 sys_reboot */
+	.quad om_sys_remote		/* 170 sys_sethostname */
+	.quad om_sys_remote		/* 171 sys_setdomainname */
+	.quad om_sys_remote		/* 172 stub_iopl */
+	.quad om_sys_remote		/* 173 sys_ioperm */
+	.quad sys_ni_syscall		/* 174 */
+	.quad om_sys_remote		/* 175 sys_init_module */
+	.quad om_sys_remote		/* 176 sys_delete_module */
+	.quad sys_ni_syscall		/* 177 */
+	.quad sys_ni_syscall		/* 178 */
+	.quad om_sys_remote		/* 179 sys_quotactl */
+	.quad om_sys_remote		/* 180 sys_nfsservctl */
+	.quad sys_ni_syscall		/* 181 */
+	.quad sys_ni_syscall		/* 182 */
+	.quad sys_ni_syscall		/* 183 */
+	.quad sys_ni_syscall		/* 184 */
+	.quad sys_ni_syscall		/* 185 */
+	.quad om_sys_gettid		/* 186 sys_gettid */
+	.quad om_sys_remote		/* 187 sys_readahead */
+	.quad om_sys_remote		/* 188 sys_setxattr */
+	.quad om_sys_remote		/* 189 sys_lsetxattr */
+	.quad om_sys_remote		/* 190 sys_fsetxattr */
+	.quad om_sys_remote		/* 191 sys_getxattr */
+	.quad om_sys_remote		/* 192 sys_lgetxattr */
+	.quad om_sys_remote		/* 193 sys_fgetxattr */
+	.quad om_sys_remote		/* 194 sys_listxattr */
+	.quad om_sys_remote		/* 195 sys_llistxattr */
+	.quad om_sys_remote		/* 196 sys_flistxattr */
+	.quad om_sys_remote		/* 197 sys_removexattr */
+	.quad om_sys_remote		/* 198 sys_lremovexattr */
+	.quad om_sys_remote		/* 199 sys_fremovexattr */
+	.quad om_sys_remote		/* 200 sys_tkill */
+	.quad om_sys_remote		/* 201 sys_time64 */
+	.quad om_sys_remote		/* 202 sys_futex */
+	.quad om_sys_remote	 	/* 203 sys_sched_setaffinity */
+	.quad om_sys_remote		/* 204 sys_sched_getaffinity */
+	.quad sys_ni_syscall		/* 205 */
+	.quad om_sys_remote		/* 206 sys_io_setup */
+	.quad om_sys_remote		/* 207 sys_io_destroy */
+	.quad om_sys_remote		/* 208 sys_io_getevents */
+	.quad om_sys_remote		/* 209 sys_io_submit */
+	.quad om_sys_remote		/* 210 sys_io_cancel */
+	.quad sys_ni_syscall		/* 211 */
+	.quad om_sys_remote		/* 212 sys_lookup_dcookie */
+	.quad om_sys_remote		/* 213 sys_epoll_create */
+	.quad sys_ni_syscall		/* 214 */
+	.quad sys_ni_syscall		/* 215 */
+	.quad om_sys_remote		/* 216 sys_remap_file_pages */
+	.quad om_sys_remote		/* 217 sys_getdents64 */
+	.quad om_sys_remote		/* 218 sys_set_tid_address */
+	.quad om_sys_remote		/* 219 sys_restart_syscall */
+	.quad om_sys_remote		/* 220 sys_semtimedop */
+	.quad om_sys_remote		/* 221 sys_fadvise64 */
+	.quad om_sys_remote		/* 222 sys_timer_create */
+	.quad om_sys_remote		/* 223 sys_timer_settime */
+	.quad om_sys_remote		/* 224 sys_timer_gettime */
+	.quad om_sys_remote		/* 225 sys_timer_getoverrun */
+	.quad om_sys_remote		/* 226 sys_timer_delete */
+	.quad om_sys_remote		/* 227 sys_clock_settime */
+	.quad om_sys_remote		/* 228 sys_clock_gettime */
+	.quad om_sys_remote		/* 229 sys_clock_getres */
+	.quad om_sys_remote		/* 230 sys_clock_nanosleep */
+	.quad om_sys_remote		/* 231 sys_exit_group */
+	.quad om_sys_remote		/* 232 sys_epoll_wait */
+	.quad om_sys_remote		/* 233 sys_epoll_ctl */
+	.quad om_sys_remote		/* 234 sys_tgkill */
+	.quad om_sys_remote		/* 235 sys_utimes */
+	.quad sys_ni_syscall		/* 236 */
+	.quad sys_ni_syscall		/* 236 */
+	.quad om_sys_local		/* 237 sys_mbind */
+	.quad om_sys_local		/* 238 sys_set_mempolicy */
+	.quad om_sys_local		/* 239 sys_get_mempolicy */
+	.quad om_sys_remote		/* 240 sys_mq_open */
+	.quad om_sys_remote		/* 241 sys_mq_unlink */
+	.quad om_sys_remote		/* 242 sys_mq_timedsend */
+	.quad om_sys_remote		/* 243 sys_mq_timedreceive */
+	.quad om_sys_remote		/* 244 sys_mq_notify */
+	.quad om_sys_remote		/* 245 sys_mq_getsetattr */
+	.quad om_sys_remote		/* 246 sys_kexec_load */
+	.quad om_sys_remote		/* 247 sys_waitid */
+	.quad om_sys_remote		/* 248 sys_add_key */
+	.quad om_sys_remote		/* 249 sys_request_key */
+	.quad om_sys_remote		/* 250 sys_keyctl */
+	.quad om_sys_remote		/* 251 sys_ioprio_set */
+	.quad om_sys_remote		/* 252 sys_ioprio_get */
+	.quad om_sys_remote		/* 253 sys_inotify_init */
+	.quad om_sys_remote		/* 254 sys_inotify_add_watch */
+	.quad om_sys_remote		/* 255 sys_inotify_rm_watch */
+
+remote_syscall_table_size=(.-remote_sys_call_table)
+.text
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/x86_64/kernel/sys_x86_64.c ./arch/x86_64/kernel/sys_x86_64.c
--- src-orig/arch/x86_64/kernel/sys_x86_64.c	2006-09-27 16:14:42.000000000 -0600
+++ ./arch/x86_64/kernel/sys_x86_64.c	2006-08-23 09:16:48.000000000 -0600
@@ -20,6 +20,8 @@
 #include <asm/uaccess.h>
 #include <asm/ia32.h>
 
+#include <linux/hpc.h>
+
 /*
  * sys_pipe() is the normal C calling standard for creating
  * a pipe. It's not the way Unix traditionally does this, though.
@@ -51,6 +53,10 @@
 	file = NULL;
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 	if (!(flags & MAP_ANONYMOUS)) {
+#ifdef CONFIG_OPENMOSIX
+		if (task_test_dflags(current, DREMOTE))
+			return remote_do_mmap(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
+#endif
 		file = fget(fd);
 		if (!file)
 			goto out;
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/x86_64/lib/copy_user.S ./arch/x86_64/lib/copy_user.S
--- src-orig/arch/x86_64/lib/copy_user.S	2006-09-27 16:14:42.000000000 -0600
+++ ./arch/x86_64/lib/copy_user.S	2006-08-23 09:16:48.000000000 -0600
@@ -21,6 +21,15 @@
 	jc  bad_to_user
 	cmpq threadinfo_addr_limit(%rax),%rcx
 	jae bad_to_user
+#ifdef CONFIG_OPENMOSIX
+	/* openmosix_memory_away inlined */
+	cmpq $0xffffffffffffffff,threadinfo_addr_limit(%rax) /* compare to kernel DS */
+	je 2f
+	movq threadinfo_task(%rax), %rax
+	testq $DDEPUTY, TASK_om+OM_dflags(%rax) # is this a DDEPUTY task ?
+	jz 2f
+	jmp deputy_copy_to_user
+#endif
 2:
 	.byte 0xe9	/* 32bit jump */
 	.long .Lcug-1f
@@ -49,6 +58,16 @@
 	jc  bad_from_user
 	cmpq threadinfo_addr_limit(%rax),%rcx
 	jae  bad_from_user
+#ifdef CONFIG_OPENMOSIX
+	/* openmosix_memory_away inlined */
+	cmpq $0xffffffffffffffff,threadinfo_addr_limit(%rax) /* compare to kernel DS */
+	je 2901f
+	movq threadinfo_task(%rax), %rax
+	testq $DDEPUTY, TASK_om+OM_dflags(%rax) # is this a DDEPUTY task ?
+	jz 2901f
+	jmp deputy_copy_from_user
+2901:
+#endif
 	/* FALL THROUGH to copy_user_generic */
 	
 	.section .fixup,"ax"
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/arch/x86_64/lib/usercopy.c ./arch/x86_64/lib/usercopy.c
--- src-orig/arch/x86_64/lib/usercopy.c	2006-09-27 16:14:42.000000000 -0600
+++ ./arch/x86_64/lib/usercopy.c	2006-08-23 09:16:48.000000000 -0600
@@ -44,6 +44,10 @@
 __strncpy_from_user(char *dst, const char __user *src, long count)
 {
 	long res;
+#ifdef CONFIG_OPENMOSIX
+	if (openmosix_memory_away())
+		return deputy_strncpy_from_user(dst, src, count);
+#endif
 	__do_strncpy_from_user(dst, src, count, res);
 	return res;
 }
@@ -52,6 +56,10 @@
 strncpy_from_user(char *dst, const char __user *src, long count)
 {
 	long res = -EFAULT;
+#ifdef CONFIG_OPENMOSIX
+	if (openmosix_memory_away())
+		return deputy_strncpy_from_user(dst, src, count);
+#endif
 	if (access_ok(VERIFY_READ, src, 1))
 		__do_strncpy_from_user(dst, src, count, res);
 	return res;
@@ -114,6 +122,10 @@
 	long res = 0;
 	char c;
 
+#ifdef CONFIG_OPENMOSIX
+	if (openmosix_memory_away())
+		return deputy_strnlen_user(s, n);
+#endif
 	while (1) {
 		if (res>n)
 			return n+1;
@@ -138,6 +150,10 @@
 	long res = 0;
 	char c;
 
+#ifdef CONFIG_OPENMOSIX
+	if (openmosix_memory_away())
+		return deputy_strnlen_user(s, 0);
+#endif
 	for (;;) {
 		if (get_user(c, s))
 			return 0;
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/fs/namei.c ./fs/namei.c
--- src-orig/fs/namei.c	2006-09-27 16:14:42.000000000 -0600
+++ ./fs/namei.c	2006-08-23 09:16:48.000000000 -0600
@@ -143,6 +143,12 @@
 
 	result = ERR_PTR(-ENOMEM);
 	tmp = __getname();
+#ifdef CONFIG_OPENMOSIX
+	if (tmp && openmosix_memory_away()) {
+		deputy_strncpy_from_user(tmp, filename, PATH_MAX);
+		return tmp;
+	}
+#endif
 	if (tmp)  {
 		int retval = do_getname(filename, tmp);
 
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/fs/proc/base.c ./fs/proc/base.c
--- src-orig/fs/proc/base.c	2006-09-27 16:14:42.000000000 -0600
+++ ./fs/proc/base.c	2006-08-23 09:16:48.000000000 -0600
@@ -74,6 +74,10 @@
 #include <linux/poll.h>
 #include "internal.h"
 
+#ifdef CONFIG_OPENMOSIX
+#include <hpc/hpc.h>
+#endif
+
 /*
  * For hysterical raisins we keep the same inumbers as in the old procfs.
  * Feel free to change the macro below - just keep the range distinct from
@@ -125,6 +129,12 @@
 #ifdef CONFIG_AUDITSYSCALL
 	PROC_TGID_LOGINUID,
 #endif
+#ifdef CONFIG_OPENMOSIX
+	PROC_TGID_OPENMOSIX,
+	PROC_TGID_OPENMOSIX_WHERE,
+	PROC_TGID_OPENMOSIX_STAY,
+	PROC_TGID_OPENMOSIX_DEBUG,
+#endif
 	PROC_TGID_OOM_SCORE,
 	PROC_TGID_OOM_ADJUST,
 	PROC_TID_INO,
@@ -166,6 +176,12 @@
 #ifdef CONFIG_AUDITSYSCALL
 	PROC_TID_LOGINUID,
 #endif
+#ifdef CONFIG_OPENMOSIX
+	PROC_TID_OPENMOSIX,
+	PROC_TID_OPENMOSIX_WHERE,
+	PROC_TID_OPENMOSIX_STAY,
+	PROC_TID_OPENMOSIX_DEBUG,
+#endif
 	PROC_TID_OOM_SCORE,
 	PROC_TID_OOM_ADJUST,
 
@@ -210,6 +226,9 @@
 #ifdef CONFIG_SECURITY
 	E(PROC_TGID_ATTR,      "attr",    S_IFDIR|S_IRUGO|S_IXUGO),
 #endif
+#ifdef CONFIG_OPENMOSIX
+	E(PROC_TGID_OPENMOSIX, "om",      S_IFDIR|S_IRUGO|S_IXUGO),
+#endif
 #ifdef CONFIG_KALLSYMS
 	E(PROC_TGID_WCHAN,     "wchan",   S_IFREG|S_IRUGO),
 #endif
@@ -252,6 +271,9 @@
 #ifdef CONFIG_SECURITY
 	E(PROC_TID_ATTR,       "attr",    S_IFDIR|S_IRUGO|S_IXUGO),
 #endif
+#ifdef CONFIG_OPENMOSIX
+	E(PROC_TID_OPENMOSIX,  "om",      S_IFDIR|S_IRUGO|S_IXUGO),
+#endif
 #ifdef CONFIG_KALLSYMS
 	E(PROC_TID_WCHAN,      "wchan",   S_IFREG|S_IRUGO),
 #endif
@@ -286,6 +308,21 @@
 };
 #endif
 
+#ifdef CONFIG_OPENMOSIX
+static struct pid_entry tgid_openmosix_stuff[] = {
+	E(PROC_TGID_OPENMOSIX_WHERE, "where",  S_IFREG|S_IRUGO|S_IWUGO),
+	E(PROC_TGID_OPENMOSIX_STAY,  "stay",   S_IFREG|S_IRUGO|S_IWUGO),
+	E(PROC_TGID_OPENMOSIX_DEBUG, "debug",   S_IFREG|S_IRUGO|S_IWUGO),
+	{0,0,NULL,0}
+};
+static struct pid_entry tid_openmosix_stuff[] = {
+	E(PROC_TID_OPENMOSIX_WHERE,  "where",  S_IFREG|S_IRUGO|S_IWUGO),
+	E(PROC_TID_OPENMOSIX_STAY,   "stay",   S_IFREG|S_IRUGO|S_IWUGO),
+	E(PROC_TID_OPENMOSIX_DEBUG,  "debug",   S_IFREG|S_IRUGO|S_IWUGO),
+	{0,0,NULL,0}
+};
+#endif
+
 #undef E
 
 static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
@@ -1647,6 +1684,84 @@
 static struct inode_operations proc_tgid_attr_inode_operations;
 #endif
 
+#ifdef CONFIG_OPENMOSIX
+static ssize_t proc_pid_openmosix_read(struct file * file, char * buf,
+				  size_t count, loff_t *ppos)
+{
+	struct inode * inode = file->f_dentry->d_inode;
+	unsigned long page;
+	ssize_t length;
+	ssize_t end;
+	struct task_struct *task = proc_task(inode);
+
+	if (count > PAGE_SIZE)
+		count = PAGE_SIZE;
+	if (!(page = __get_free_page(GFP_KERNEL)))
+		return -ENOMEM;
+
+	length = openmosix_proc_pid_getattr(task,
+				      (char*)file->f_dentry->d_name.name,
+				      (void*)page, count);
+	if (length < 0) {
+		free_page(page);
+		return length;
+	}
+	/* Static 4kB (or whatever) block capacity */
+	if (*ppos >= length) {
+		free_page(page);
+		return 0;
+	}
+	if (count + *ppos > length)
+		count = length - *ppos;
+	end = count + *ppos;
+	if (copy_to_user(buf, (char *) page + *ppos, count))
+		count = -EFAULT;
+	else
+		*ppos = end;
+	free_page(page);
+	return count;
+}
+
+static ssize_t proc_pid_openmosix_write(struct file * file, const char * buf,
+				   size_t count, loff_t *ppos)
+{
+	struct inode * inode = file->f_dentry->d_inode;
+	char *page;
+	ssize_t length;
+	struct task_struct *task = proc_task(inode);
+
+	if (count > PAGE_SIZE)
+		count = PAGE_SIZE;
+	if (*ppos != 0) {
+		/* No partial writes. */
+		return -EINVAL;
+	}
+	page = (char*)__get_free_page(GFP_USER);
+	if (!page)
+		return -ENOMEM;
+	length = -EFAULT; 
+	if (copy_from_user(page, buf, count)) 
+		goto out;
+
+	length = openmosix_proc_pid_setattr(task,
+				      (char*)file->f_dentry->d_name.name,
+				      (void*)page, count);
+out:
+	free_page((unsigned long) page);
+	return length;
+} 
+
+static struct file_operations proc_pid_openmosix_operations = {
+	.read		= proc_pid_openmosix_read,
+	.write		= proc_pid_openmosix_write,
+};
+
+static struct file_operations proc_tid_openmosix_operations;
+static struct inode_operations proc_tid_openmosix_inode_operations;
+static struct file_operations proc_tgid_openmosix_operations;
+static struct inode_operations proc_tgid_openmosix_inode_operations;
+#endif /* CONFIG_OPENMOSIX */
+
 static int get_tid_list(int index, unsigned int *tids, struct inode *dir);
 
 /* SMP-safe */
@@ -1803,6 +1918,26 @@
 			inode->i_fop = &proc_pid_attr_operations;
 			break;
 #endif
+#ifdef CONFIG_OPENMOSIX
+		case PROC_TID_OPENMOSIX:
+			inode->i_nlink = 2;
+			inode->i_op = &proc_tid_openmosix_inode_operations;
+			inode->i_fop = &proc_tid_openmosix_operations;
+			break;
+		case PROC_TGID_OPENMOSIX:
+			inode->i_nlink = 2;
+			inode->i_op = &proc_tgid_openmosix_inode_operations;
+			inode->i_fop = &proc_tgid_openmosix_operations;
+			break;
+		case PROC_TID_OPENMOSIX_WHERE:
+		case PROC_TGID_OPENMOSIX_WHERE:
+		case PROC_TID_OPENMOSIX_STAY:
+		case PROC_TGID_OPENMOSIX_STAY:
+		case PROC_TID_OPENMOSIX_DEBUG:
+		case PROC_TGID_OPENMOSIX_DEBUG:
+			inode->i_fop = &proc_pid_openmosix_operations;
+			break;
+#endif
 #ifdef CONFIG_KALLSYMS
 		case PROC_TID_WCHAN:
 		case PROC_TGID_WCHAN:
@@ -1923,6 +2058,54 @@
 };
 #endif
 
+#ifdef CONFIG_OPENMOSIX
+static int proc_tgid_openmosix_readdir(struct file * filp,
+			     void * dirent, filldir_t filldir)
+{
+	return proc_pident_readdir(filp,dirent,filldir,
+				   tgid_openmosix_stuff,
+				   ARRAY_SIZE(tgid_openmosix_stuff));
+}
+
+static int proc_tid_openmosix_readdir(struct file * filp,
+			     void * dirent, filldir_t filldir)
+{
+	return proc_pident_readdir(filp,dirent,filldir,
+				   tid_openmosix_stuff,
+				   ARRAY_SIZE(tid_openmosix_stuff));
+}
+
+static struct file_operations proc_tgid_openmosix_operations = {
+	.read		= generic_read_dir,
+	.readdir	= proc_tgid_openmosix_readdir,
+};
+
+static struct file_operations proc_tid_openmosix_operations = {
+	.read		= generic_read_dir,
+	.readdir	= proc_tid_openmosix_readdir,
+};
+
+static struct dentry *proc_tgid_openmosix_lookup(struct inode *dir,
+				struct dentry *dentry, struct nameidata *nd)
+{
+	return proc_pident_lookup(dir, dentry, tgid_openmosix_stuff);
+}
+
+static struct dentry *proc_tid_openmosix_lookup(struct inode *dir,
+				struct dentry *dentry, struct nameidata *nd)
+{
+	return proc_pident_lookup(dir, dentry, tid_openmosix_stuff);
+}
+
+static struct inode_operations proc_tgid_openmosix_inode_operations = {
+	.lookup		= proc_tgid_openmosix_lookup,
+};
+
+static struct inode_operations proc_tid_openmosix_inode_operations = {
+	.lookup		= proc_tid_openmosix_lookup,
+};
+#endif /* CONFIG_OPENMOSIX */
+
 /*
  * /proc/self:
  */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/fs/proc/root.c ./fs/proc/root.c
--- src-orig/fs/proc/root.c	2006-09-27 16:14:42.000000000 -0600
+++ ./fs/proc/root.c	2006-08-23 09:16:48.000000000 -0600
@@ -18,6 +18,10 @@
 #include <linux/bitops.h>
 #include <linux/smp_lock.h>
 
+#ifdef CONFIG_OPENMOSIX
+#include <hpc/hpc.h>
+#endif
+
 #include "internal.h"
 
 struct proc_dir_entry *proc_net, *proc_net_stat, *proc_bus, *proc_root_fs, *proc_root_driver;
@@ -62,6 +66,9 @@
 #ifdef CONFIG_SYSCTL
 	proc_sys_root = proc_mkdir("sys", NULL);
 #endif
+#ifdef CONFIG_OPENMOSIX
+	openmosix_proc_init();
+#endif
 #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
 	proc_mkdir("sys/fs", NULL);
 	proc_mkdir("sys/fs/binfmt_misc", NULL);
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/fs/select.c ./fs/select.c
--- src-orig/fs/select.c	2006-09-27 16:14:42.000000000 -0600
+++ ./fs/select.c	2006-08-23 09:16:48.000000000 -0600
@@ -294,6 +294,9 @@
 
 	return retval;
 }
+#ifdef CONFIG_KCOMD
+EXPORT_SYMBOL_GPL(do_select);
+#endif
 
 /*
  * We can actually return ERESTARTSYS instead of EINTR, but I'd
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/arch-i386.c ./hpc/arch-i386.c
--- src-orig/hpc/arch-i386.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/arch-i386.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,275 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/kallsyms.h>
+#include <linux/sched.h>
+#include <hpc/debug.h>
+#include <hpc/protocol.h>
+#include <hpc/arch.h>
+#include <hpc/task.h>
+#include <hpc/hpc.h>
+#include <hpc/prototype.h>
+#include <asm/uaccess.h>
+#include <asm/ptrace.h>
+#include <asm/desc.h>
+#include <asm/i387.h>
+
+unsigned long twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave);
+unsigned short twd_i387_to_fxsr(unsigned short twd);
+
+static void fxsave_to_fsave(union i387_union *from, union i387_union *to)
+{
+	u8 *fcp, *tcp;
+	int i;
+
+	to->fsave.cwd = from->fxsave.cwd;
+	to->fsave.swd = from->fxsave.swd;
+	to->fsave.twd = twd_fxsr_to_i387(&from->fxsave);
+	to->fsave.fip = from->fxsave.fip;
+	to->fsave.fcs = from->fxsave.fcs;
+	to->fsave.foo = from->fxsave.foo;
+	to->fsave.fos = from->fxsave.fos;
+	to->fxsave.padding[0] = from->fxsave.fop;
+	to->fxsave.padding[1] = from->fxsave.mxcsr;
+
+	fcp = (u8 *) from->fxsave.st_space;
+	tcp = (u8 *) to->fsave.st_space;
+
+	/* 8 registers of 16 bytes to copy to 10 bytes */
+	for (i = 0; i < 8; i++, tcp += 10, fcp += 16)
+		memcpy(tcp, fcp, 10);
+
+	memcpy(to->fxsave.xmm_space, from->fxsave.xmm_space,
+					sizeof(to->fxsave.xmm_space));
+}
+
+static void fsave_to_fxsave(union i387_union *from, union i387_union *to)
+{
+	u8 *fcp, *tcp;
+	int i;
+
+	to->fxsave.cwd = from->fsave.cwd;
+	to->fxsave.swd = from->fsave.swd;
+	to->fxsave.twd = twd_i387_to_fxsr(from->fsave.twd);
+	to->fxsave.fop = from->fxsave.padding[0];
+	to->fxsave.fip = from->fsave.fip;
+	to->fxsave.fcs = from->fsave.fcs;
+	to->fxsave.foo = from->fsave.foo;
+	to->fxsave.mxcsr = from->fxsave.padding[1];
+	to->fxsave.fos = from->fsave.fos;
+
+	fcp = (u8 *) from->fsave.st_space;
+	tcp = (u8 *) to->fxsave.st_space;
+
+	/* 8 registers of 10 bytes to copy to 16 bytes */
+	for (i = 0; i < 8; i++, tcp += 16, fcp += 10)
+		memcpy(tcp, fcp, 10);
+
+	memcpy(to->fxsave.xmm_space, from->fxsave.xmm_space,
+					sizeof(from->fxsave.xmm_space));
+}
+
+
+/*****************************************************************************/
+/* receive part */
+
+int arch_mig_receive_specific(task_t *p, struct omp_mig_arch *m)
+{
+	switch (m->type)
+	{
+		case MIG_ARCH_I386_LDT:
+			printk(KERN_WARNING "oM: mig arch ldt not handle yet.\n");
+			break;
+		default:
+			printk(KERN_ERR "oM: mig arch type not handle.\n");
+			return 1;
+	}
+	return 0;
+}
+
+int arch_mig_receive_proc_context(task_t *p, struct omp_mig_task *m)
+{
+	struct pt_regs *regs;
+	int i;
+
+	/* copy pt_regs */
+	regs = ARCH_TASK_GET_USER_REGS(p);
+	memcpy(regs, &m->regs, sizeof(struct pt_regs));
+
+	/* debugs regs */
+	memcpy((caddr_t) p->thread.debugreg, (caddr_t) m->arch.debugreg,
+						sizeof(m->arch.debugreg));
+
+	/* copy some segmentation registers */
+	p->thread.fs = m->arch.fs;
+	p->thread.gs = m->arch.gs;
+	for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
+		p->thread.tls_array[i] = m->arch.tls_array[i];
+
+	return 0;
+}
+
+void arch_mig_receive_fp(task_t *p, struct omp_mig_fp *fp)
+{
+	unlazy_fpu(p);
+
+	/* if same kind of cpu we just memcpy the structure */
+	if ((cpu_feature_has_fxsr() && fp->has_fxsr)
+	|| (!cpu_feature_has_fxsr() && !fp->has_fxsr))
+	{
+		memcpy(&p->thread.i387, &fp->data, sizeof(union i387_union));
+		return;
+	}
+
+	if (fp->has_fxsr)
+		fxsave_to_fsave(&fp->data, &p->thread.i387);
+	else
+		fsave_to_fxsave(&fp->data, &p->thread.i387);
+
+}
+
+/*****************************************************************************/
+/* send part */
+
+void arch_mig_send_pre(task_t *p)
+{
+	if (p->mm->context.ldt)
+		clear_LDT();
+}
+
+void arch_mig_send_post(task_t *p)
+{
+	if (p->mm->context.ldt)
+		load_LDT(&p->mm->context);
+}
+
+int arch_mig_send_specific(task_t *p)
+{
+	mm_context_t *pc = &p->mm->context;
+
+	if (pc->size)
+		printk(KERN_WARNING "process has specific ldt\n");
+	return 0;
+}
+
+int arch_mig_send_fp(task_t *p, struct omp_mig_fp *fp)
+{
+	unlazy_fpu(p);
+	fp->has_fxsr = cpu_feature_has_fxsr();
+	memcpy(&fp->data, &p->thread.i387, sizeof(p->thread.i387));
+	return 0;
+}
+
+int arch_mig_send_proc_context(task_t *p, struct omp_mig_task *m)
+{
+	struct pt_regs *regs;
+	int i;
+
+	/* copy pt_regs */
+	regs = ARCH_TASK_GET_USER_REGS(p);
+	memcpy(&m->regs, regs, sizeof(struct pt_regs));
+
+	/* copy some segmentation registers */
+	m->arch.fs = p->thread.fs;
+	m->arch.gs = p->thread.gs;
+
+	for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
+		m->arch.tls_array[i] = p->thread.tls_array[i];
+
+	/* copy debugregs */
+	memcpy((caddr_t)m->arch.debugreg, (caddr_t)p->thread.debugreg,
+					sizeof(m->arch.debugreg));
+
+	if (task_test_dflags(p, DDEPUTY))
+		memcpy(m->arch.features, boot_cpu_data.x86_capability,
+					sizeof(m->arch.features));
+
+	return 0;
+}
+
+
+asmlinkage void ret_from_kickstart(void) __asm__("ret_from_kickstart");
+
+NORET_TYPE void arch_kickstart(struct task_struct *p)
+{
+	struct pt_regs *regs;
+	regs = ARCH_TASK_GET_USER_REGS(p);
+
+	if (p->thread.debugreg[7]) {
+		set_debugreg(p->thread.debugreg[0], 0);
+		set_debugreg(p->thread.debugreg[1], 1);
+		set_debugreg(p->thread.debugreg[2], 2);
+		set_debugreg(p->thread.debugreg[3], 3);
+		set_debugreg(p->thread.debugreg[6], 6);
+		set_debugreg(p->thread.debugreg[7], 7);
+	}
+
+	load_TLS(&p->thread, smp_processor_id());
+
+	loadsegment(fs, p->thread.fs);
+	loadsegment(gs, p->thread.gs);
+
+	regs->xcs = __USER_CS;
+
+	/* FIXME: not sure about this one */
+	flush_signals(p);
+
+	asm(	"movl %0,%%esp\n\t"
+		"jmp ret_from_kickstart\n\t"
+		: /**/ : "r"(regs));
+}
+
+/*****************************************************************************/
+#include <hpc/syscalls.h>
+#include <asm/unistd.h>
+
+long arch_exec_syscall(int n, syscall_parameter_t * args)
+{
+	syscall_func_t fct;
+	extern void * sys_call_table[];
+
+	OMDEBUG_SYS(4, "exec_sys[%d](%lx, %lx, %lx, %lx, %lx, %lx)\n", n,
+			args->arg[0], args->arg[1], args->arg[2],
+			args->arg[3], args->arg[4], args->arg[5]);
+	fct = (syscall_func_t) sys_call_table[n];
+	return fct(*((syscall_parameter_t *) args));
+}
+
+asmlinkage long om_sys_fork(struct pt_regs regs)
+{
+	return remote_do_fork(SIGCHLD, regs.esp, &regs, 0, NULL, NULL);
+}
+
+asmlinkage long om_sys_clone(struct pt_regs regs)
+{
+	unsigned long clone_flags;
+	unsigned long newsp;
+	int __user *parent_tidptr, *child_tidptr;
+	int retval;
+
+	clone_flags = regs.ebx;
+	newsp = regs.ecx;
+	parent_tidptr = (int __user *)regs.edx;
+	child_tidptr = (int __user *)regs.edi;
+	if (!newsp)
+		newsp = regs.esp;
+	retval = remote_do_fork(clone_flags, newsp, &regs, 0, parent_tidptr, child_tidptr);
+	return retval;
+}
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/arch-ppc.c ./hpc/arch-ppc.c
--- src-orig/hpc/arch-ppc.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/arch-ppc.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,112 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#include <asm/uaccess.h>
+#include <linux/kallsyms.h>
+#include <linux/sched.h>
+#include <hpc/debug.h>
+#include <asm/ptrace.h>
+#include <hpc/prototype.h>
+#include <asm/processor.h>
+#include <hpc/protocol.h>
+#include <hpc/arch.h>
+
+/*****************************************************************************/
+/* receive part */
+
+int arch_mig_receive_specific(task_t *p, struct omp_mig_arch *m)
+{
+	return 0;
+}
+
+int arch_mig_receive_proc_context(task_t *p, struct omp_mig_task *m)
+{
+	struct pt_regs *regs;
+
+	regs = ARCH_TASK_GET_USER_REGS(p);
+	memcpy(regs, &m->regs, sizeof(struct pt_regs));
+	return 0;
+}
+
+void arch_mig_receive_fp(task_t *p, struct omp_mig_fp *fp)
+{
+	struct thread_struct *th = &p->thread;
+
+	memcpy(th->fpr, fp->fpr, sizeof(th->fpr));
+
+	th->fpscr_pad = fp->fpscr_pad; /* FIXME: not sure this one is needed */
+	th->fpscr = fp->fpscr;
+
+}
+
+/*****************************************************************************/
+/* send part */
+
+void arch_mig_send_pre(task_t *p)
+{
+}
+
+void arch_mig_send_post(task_t *p)
+{
+}
+
+int arch_mig_send_specific(task_t *p)
+{
+	return 0;
+}
+
+int arch_mig_send_fp(task_t *p, struct omp_mig_fp *fp)
+{
+	struct thread_struct *th = &p->thread;
+
+	memcpy(fp->fpr, th->fpr, sizeof(fp->fpr));
+
+	fp->fpscr_pad = th->fpscr_pad; /* FIXME: not sure this one is needed */
+	fp->fpscr = th->fpscr;
+	return 0;
+}
+
+int arch_mig_send_proc_context(task_t *p, struct omp_mig_task *m)
+{
+	struct pt_regs *regs;
+
+	regs = ARCH_TASK_GET_USER_REGS(p);
+	memcpy(&m->regs, &regs, sizeof(struct pt_regs));
+	return 0;
+}
+
+
+void arch_kickstart(struct task_struct *p)
+{
+	struct pt_regs *regs;
+
+	regs = ARCH_TASK_GET_USER_REGS(p);
+	asm (	"mr 1, %0\n\t"
+		"b ret_from_kickstart\n\t"
+		: /**/ : "r"(regs));
+}
+
+long arch_exec_syscall(int n, syscall_parameter_t * args)
+{
+	syscall_func_t fct;
+	extern void * sys_call_table[];
+
+	fct = (syscall_func_t) sys_call_table[n];
+	return fct(*((syscall_parameter_t *) args));
+}
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/arch-x86_64.c ./hpc/arch-x86_64.c
--- src-orig/hpc/arch-x86_64.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/arch-x86_64.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,191 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#include <asm/uaccess.h>
+#include <linux/kernel.h>
+#include <linux/kallsyms.h>
+#include <linux/sched.h>
+#include <hpc/debug.h>
+#include <asm/ptrace.h>
+#include <asm/desc.h>
+#include <asm/i387.h>
+#include <hpc/protocol.h>
+#include <hpc/arch.h>
+#include <hpc/task.h>
+#include <hpc/syscalls.h>
+#include <hpc/prototype.h>
+
+/*****************************************************************************/
+/* receive part */
+
+int arch_mig_receive_specific(task_t *p, struct omp_mig_arch *m)
+{
+	return 0;
+}
+
+int arch_mig_receive_proc_context(task_t *p, struct omp_mig_task *m)
+{
+	struct pt_regs *regs;
+
+	regs = ARCH_TASK_GET_USER_REGS(p);
+
+	memcpy(regs, &m->regs, sizeof(struct pt_regs));
+
+	p->thread.ds = m->arch.ds;
+	p->thread.es = m->arch.es;
+	p->thread.fs = m->arch.fs;
+	p->thread.gs = m->arch.gs;
+	p->thread.fsindex = m->arch.fsindex;
+	p->thread.gsindex = m->arch.gsindex;
+	p->thread.userrsp = m->arch.userrsp;
+	write_pda(oldrsp, m->arch.userrsp);
+
+	return 0;
+}
+
+void arch_mig_receive_fp(task_t *p, struct omp_mig_fp *fp)
+{
+	unlazy_fpu(p);
+
+	/* all opterons got same fp feature */
+	memcpy(&p->thread.i387, &fp->data, sizeof(union i387_union));
+}
+
+/*****************************************************************************/
+/* send part */
+
+void arch_mig_send_pre(task_t *p)
+{
+	if (p->mm->context.ldt)
+		clear_LDT();
+}
+
+void arch_mig_send_post(task_t *p)
+{
+	if (p->mm->context.ldt)
+		load_LDT(&p->mm->context);
+}
+
+int arch_mig_send_specific(task_t *p)
+{
+	return 0;
+}
+
+int arch_mig_send_fp(task_t *p, struct omp_mig_fp *fp)
+{
+	unlazy_fpu(p);
+	memcpy(&fp->data, &p->thread.i387, sizeof(p->thread.i387));
+	return 0;
+}
+
+int arch_mig_send_proc_context(task_t *p, struct omp_mig_task *m)
+{
+	struct pt_regs *regs;
+	int i;
+
+	regs = ARCH_TASK_GET_USER_REGS(p);
+
+	memcpy(&m->regs, regs, sizeof(struct pt_regs));
+
+	for (i = 0; i < TLS_SIZE; i++)
+		m->arch.tls_array[i] = p->thread.tls_array[i];
+
+	m->arch.ds = p->thread.ds;
+	m->arch.es = p->thread.es;
+	m->arch.fs = p->thread.fs;
+	m->arch.gs = p->thread.gs;
+	m->arch.fsindex = p->thread.fsindex;
+	m->arch.gsindex = p->thread.gsindex;
+	m->arch.userrsp = read_pda(oldrsp);
+
+	return 0;
+}
+
+
+asmlinkage void ret_from_kickstart(void) __asm__("ret_from_kickstart");
+
+void arch_kickstart(struct task_struct *p)
+{
+	struct pt_regs *regs;
+	regs = ARCH_TASK_GET_USER_REGS(p);
+
+	if (p->thread.debugreg7) {
+		set_debugreg(p->thread.debugreg0, 0);
+		set_debugreg(p->thread.debugreg1, 1);
+		set_debugreg(p->thread.debugreg2, 2);
+		set_debugreg(p->thread.debugreg3, 3);
+		set_debugreg(p->thread.debugreg6, 6);
+		set_debugreg(p->thread.debugreg7, 7);
+	}
+
+	/*
+	load_TLS(&p->thread, smp_processor_id());
+	*/
+
+	if (p->thread.ds)
+		loadsegment(ds, p->thread.ds);
+	if (p->thread.es)
+		loadsegment(es, p->thread.es);
+	if (p->thread.fsindex)
+		loadsegment(fs, p->thread.fsindex);
+	if (p->thread.gsindex)
+		load_gs_index(p->thread.gsindex);
+
+	regs->cs = __USER_CS;
+	regs->ss = __USER_DS;
+	set_fs(USER_DS);
+
+	/* FIXME: not sure about this one */
+	flush_signals(p);
+
+	asm(	"movq %0,%%rsp\n\t"
+		"jmp ret_from_kickstart\n\t"
+		: /**/ : "r"(regs));
+}
+
+long arch_exec_syscall(int n, syscall_parameter_t * args)
+{
+	long ret;
+
+	asm (	"movq %5, %%r8\n\t"
+		"movq %6, %%r9\n\t"
+		"call *sys_call_table(,%%rax,8)\n\t"
+		: "=a" (ret)
+		: "D" (args->arg[0]), "S" (args->arg[1]), "d" (args->arg[2]),
+		  "c" (args->arg[3]), "g" (args->arg[4]), "g" (args->arg[5]),
+		  "a" (n)
+		: "memory", "r8", "r9");
+
+	return ret;
+}
+
+asmlinkage long om_sys_fork(struct pt_regs regs)
+{
+	return remote_do_fork(SIGCHLD, regs.rsp, &regs, 0, NULL, NULL);
+}
+
+#define NOT_IMPLEMENTED(fct)					\
+asmlinkage long fct(struct pt_regs regs)			\
+{ printk(KERN_ERR #fct "not yet implemented\n"); return -1; }
+
+NOT_IMPLEMENTED(om_sys_iopl)
+NOT_IMPLEMENTED(om_sys_vfork)
+NOT_IMPLEMENTED(om_sys_clone)
+NOT_IMPLEMENTED(om_sys_rt_sigsuspend)
+NOT_IMPLEMENTED(om_sys_sigaltstack)
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/comm.c ./hpc/comm.c
--- src-orig/hpc/comm.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/comm.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,530 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+#include <linux/sched.h>
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/net.h>
+#include <net/sock.h>
+#include <net/tcp.h>
+#include <asm/uaccess.h>
+#include <hpc/mig.h>
+#include <hpc/debug.h>
+#include <hpc/comm.h>
+#include <hpc/task.h>
+#include <hpc/prototype.h>
+
+#define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR)
+
+unsigned long comm_remote_timo = COMM_REMOTE_TIMO;	/* for remote accept */
+unsigned long comm_connect_timo = COMM_CONNECT_TIMO;	/* for connection */
+unsigned long comm_reconn_timo = COMM_RECONN_TIMO;	/* for reconnection */
+
+/**
+ * comm_shutdown - shutdown socket
+ * @mlink:	openMosix link to shutdown
+ **/
+static void comm_shutdown(struct socket *sock)
+{
+	if (sock && sock->ops)
+		sock->ops->shutdown(sock, SEND_SHUTDOWN);
+}
+
+/**
+ * comm_getname - get the name of socket
+ * @mlink:	openMosix link to query
+ * @address:	the sockaddr to fill
+ * @peer:	get peer name instead?
+ **/
+int comm_getname(struct socket *sock, struct sockaddr *address, int peer)
+{
+	int val, ret;
+
+	val = sizeof(struct sockaddr);
+	if (!sock->ops || !sock->ops->getname)
+		return -1;
+	ret = sock->ops->getname(sock, address, &val, peer);
+	if (ret)
+		return -1;
+	return val;
+}
+
+/**
+ * comm_data_ready - Wake the socket when data are ready
+ * @sk:	socket to wake up
+ * @len:	unneeded
+ **/
+void comm_data_ready(struct sock *sk, int len)
+{
+	wake_up_interruptible(sk->sk_sleep);
+}
+
+static int comm_setup_tcp(struct socket *sock)
+{
+	int val;
+	char __user *pval;
+	int error;
+	mm_segment_t oldfs;
+
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+
+	pval = (char __user *) &val;
+
+	/* old TOADDR/ACCEPT */
+	val = 1;
+	error = sock_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
+	                        pval, sizeof(val));
+	if (error)
+		goto fail;
+	/* FIXME: check on these, old COMM_MIGD */
+	val = OPENMOSIX_CONNECTION_KEEPALIVE_INTERVAL;
+	error = sock->ops->setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL,
+	                              pval, sizeof(val));
+	if (error)
+		goto fail;
+
+	val = OPENMOSIX_CONNECTION_KEEPALIVE_MAXTRIES;
+	error = sock->ops->setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT,
+	                              pval, sizeof(val));
+	if (error)
+		goto fail;
+
+	val = OPENMOSIX_CONNECTION_KEEPALIVE_TOTAL;
+	error = sock->ops->setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE,
+	                              pval, sizeof(val));
+	if (error)
+		goto fail;
+
+	val = 1;
+	error = sock->ops->setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
+	                              pval, sizeof(val));
+	if (error)
+		goto fail;
+
+fail:
+	set_fs(oldfs);
+	return error;
+}
+
+
+struct socket * comm_socket(int family, int type, int proto)
+{
+	int error;
+	struct socket *sock;
+
+	error = sock_create(family, type, proto, &sock);
+	if (error < 0)
+		return NULL;
+	return sock;
+}
+
+
+int comm_bind(struct socket *sock, struct sockaddr *saddr)
+{
+	int error;
+
+	error = sock->ops->bind(sock, saddr, sizeof(*saddr));
+	if (error == -EADDRINUSE)
+		printk("comm_bind() Already in use\n");
+
+	return error;
+}
+
+static int comm_listen(struct socket *sock)
+{
+	int error;
+
+	error = sock->ops->listen(sock, SOMAXCONN);
+
+	return error;
+}
+
+
+int comm_connect(struct socket *sock, struct sockaddr *saddr, unsigned long timo)
+{
+	int error;
+	DECLARE_WAITQUEUE(wait, current);
+
+	if (!timo)
+		timo = MAX_SCHEDULE_TIMEOUT;
+
+	error = sock->ops->connect(sock, saddr, sizeof(*saddr), O_NONBLOCK);
+
+	add_wait_queue(sock->sk->sk_sleep, &wait);
+	while (sock->state != SS_CONNECTED) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		error = sock->ops->connect(sock, saddr, sizeof(*saddr),
+						O_NONBLOCK);
+		if (error != -EALREADY || (error = sock_error(sock->sk)))
+			break;
+
+		timo = schedule_timeout(timo);
+		if (timo <= 0) {
+			error = -EAGAIN;
+			break;
+		}
+	}
+	remove_wait_queue(sock->sk->sk_sleep, &wait);
+	set_current_state(TASK_RUNNING);
+
+	if (error) {
+		OMBUG("failed to connect\n");
+		return error;
+	}
+
+	if (sock->sk->sk_err) {
+		error = sock_error(sock->sk);	/* cleans error.. */
+		OMBUG("sk_err\n");
+		return error;
+	}
+
+	return 0;
+}
+
+
+/**
+ * comm_close - close an openMosix communication socket
+ * @mlink:	openMosix link
+ **/
+void comm_close(struct socket *sock)
+{
+	BUG_ON(!sock);
+
+	sock_release(sock);
+}
+
+/**
+ * comm_peek - peek the socket looking for data pending
+ **/
+int comm_peek(struct socket *sock)
+{
+	int mask;
+
+	mask = sock->ops->poll(NULL, sock, NULL);
+	return (mask & POLLIN_SET) ? 1 : 0;
+}
+
+
+/**
+ * comm_poll - wait for a communication event, interrupt or openMosix event
+ * @sock:		socket to poll
+ * @mask:		polling mask
+ * @interruptible:	is the task interruptible
+ * @timo:		timeout (0 = MAX_SCHEDULE_TIMEOUT)
+ *
+ * Description:
+ *	returns 1 on communication events, and 0 otherwise
+ */
+static int comm_poll(struct socket *sock, int mask, int interruptible, unsigned long timo)
+{
+	int pollmask;
+	static struct file sighfile = {.f_count = ATOMIC_INIT(1)};
+	DECLARE_WAITQUEUE(wait, current);
+
+	/*
+	 * sighfile: we are required to supply a file to "hold" while we poll.
+	 * a bit ridiculous in this context, but nobody will notice because
+	 * f_count will never drop to 0
+	 */
+	if (!timo)
+		timo = MAX_SCHEDULE_TIMEOUT;
+	add_wait_queue(sock->sk->sk_sleep, &wait);
+	for (;;)
+	{
+		set_current_state(TASK_INTERRUPTIBLE);
+		pollmask = sock->ops->poll(&sighfile, sock, NULL);
+		if ((pollmask & mask) || (interruptible &&
+					 (signal_pending(current)
+					 || task_test_dreqs(current, ~0))))
+			break;
+
+		timo = schedule_timeout(timo);
+		if (timo <= 0)
+			break;
+	}
+	remove_wait_queue(sock->sk->sk_sleep, &wait);
+	set_current_state(TASK_RUNNING);
+
+	return (pollmask & mask) ? 1 : 0;
+}
+
+
+/**
+ * comm_wait - wait for a message, or some other openMosix event
+ *
+ * Description:
+ *	return 1 if there is a message, 0 if another event occured first.
+ **/
+int comm_wait(struct socket *sock)
+{
+	return comm_poll(sock, POLLIN_SET, 1, 0UL);
+}
+
+
+/**
+ * comm_accept - accept a connection on openMosix socket
+ * @ml:		the socket that receive a connection
+ * @mlp:	the new link opened will be assigned here
+ * @saddr:	source address of the connection
+ * @timeout:	timeout (0 = MAX_SCHEDULE_TIMEOUT)
+ **/
+int comm_accept(struct socket *ml, struct socket **mlp, struct sockaddr *saddr,
+		unsigned long timeout)
+{
+	struct socket *sock;
+	int error = -EMFILE;
+
+	*mlp = NULL;
+
+	sock = sock_alloc();
+	if (!sock)
+		return error;
+
+	sock->type = ml->type;
+	sock->ops = ml->ops;
+
+	if (timeout && !comm_poll(ml, POLLIN | POLLRDNORM, 0, timeout)) {
+		error = -EAGAIN;
+		goto failed;
+	}
+
+	error = ml->ops->accept(ml, sock, 0);
+	if (error)
+		goto failed;
+
+	/* set up connection options */
+	error = comm_setup_tcp(sock);
+	if (error)
+		goto failed;
+
+	*mlp = sock;
+	return error;
+
+failed:
+	sock_release(sock);
+	return error;
+}
+
+/**
+ * comm_dorecv - Reliable read data from socket
+ * @sock:	socket to read from
+ * @msg:	fill with data
+ * @len:	lenght of the data
+ *
+ * Description:
+ *	reliably read data on success, or if
+ *	error == -EFAULT: returns number of bytes received otherwise
+ *	(any other error): returns negative error.
+ **/
+static int comm_dorecv(struct socket *sock, struct msghdr *msg, int len)
+{
+	int n = 0;
+	int left = len;
+
+	do {
+		n = sock_recvmsg(sock, msg, left, msg->msg_flags);
+		if (n <= 0) {
+			/* if we already got -EFAULT, we must report */
+			if (n == -EFAULT)
+			{
+				for ( ; msg->msg_iovlen; msg->msg_iov++) {
+					msg->msg_iovlen--;
+					len -= msg->msg_iov->iov_len;
+				}
+				return len;
+			}
+
+			/* .. otherwise - it is fatal - return error */
+			if (n < 0)
+				return n;
+			return -EPIPE;
+		}
+
+		left -= n;
+		if (left) {
+			/* ...->recvmsg() updated iovec, we update msg */
+			while (!msg->msg_iov->iov_len)
+			{
+				msg->msg_iov++;
+				msg->msg_iovlen--;
+			}
+		}
+	} while (left);
+	return len;
+}
+
+
+/**
+ * comm_recv - receive a message of size @len
+ * @mlink:	socket we're using
+ * @data:	pointer to buffer to write message into
+ * @len:	length of data we want
+ **/
+int comm_recv(struct socket *mlink, void *data, int len)
+{
+	struct iovec iov;
+	struct msghdr msg = { NULL, 0, &iov, 1, NULL, 0, MSG_WAITALL | MSG_NOSIGNAL };
+	mm_segment_t oldfs;
+	int error = -1;
+
+	BUG_ON(len > PAGE_SIZE);
+	BUG_ON(!mlink);
+
+	iov.iov_base = data;
+	iov.iov_len = len;
+
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+
+	error = comm_dorecv(mlink, &msg, len);
+	if (error != len) {
+		OMBUG("got %d of %d\n", error, len);
+		if (error >= 0)
+			error = -EFAULT;
+		comm_shutdown(mlink);
+	}
+
+	set_fs(oldfs);
+
+	return error;
+}
+
+
+
+/**
+ * comm_send - send data and returns the bytes number of data sent
+ * @mlink:	socket we're using
+ * @data:	data to send
+ * @len:	length of data
+ **/
+int comm_send(struct socket *mlink, void *data, int len)
+{
+	struct iovec iov;
+	struct msghdr msg = { NULL, 0, &iov, 1, NULL, 0, MSG_NOSIGNAL };
+	mm_segment_t oldfs;
+	int error;
+
+	BUG_ON(!mlink);
+
+	iov.iov_base = data;
+	iov.iov_len  = len;
+
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+
+	error = sock_sendmsg(mlink, &msg, len);
+	if (error != len)
+		printk("sock_sendmsg: sent %d of %d\n", error, len);
+
+	set_fs(oldfs);
+
+	return error;
+}
+
+/* ---------- openmosix specifics start here ------------ */
+#include <hpc/protocol.h>
+
+void set_our_addr(int type, struct sockaddr *sa, int port)
+{
+	struct sockaddr_in *sa_in;
+	struct sockaddr_in6 *sa_in6;
+
+	switch (type) {
+	case AF_INET:
+		sa_in = (struct sockaddr_in *) sa;
+		sa_in->sin_family = type;
+		sa_in->sin_addr.s_addr = INADDR_ANY;
+		sa_in->sin_port = port;
+		return;
+	case AF_INET6:
+		sa_in6 = (struct sockaddr_in6 *) sa;
+		return;
+	}
+}
+
+/* lazy helper functions */
+struct socket * comm_setup_listen(struct sockaddr *sa)
+{
+	struct socket *link;
+	int error;
+
+	link = comm_socket(sa->sa_family, SOCK_STREAM, IPPROTO_TCP);
+	if (!link)
+		return NULL;
+
+	error = comm_bind(link, sa);
+	if (error < 0)
+		goto fail;
+
+	error = comm_listen(link);
+	if (error < 0)
+		goto fail;
+
+	return link;
+
+fail:
+	comm_close(link);
+	return NULL;
+}
+
+struct socket * comm_setup_connect(struct sockaddr *sa, int timo)
+{
+	struct socket *link;
+
+	link = comm_socket(sa->sa_family, SOCK_STREAM, IPPROTO_TCP);
+	if (!link)
+		return NULL;
+
+	if (comm_connect(link, sa, timo))
+		goto fail;
+
+	return link;
+
+fail:
+	comm_close(link);
+	return NULL;
+}
+
+int comm_send_hd(struct socket *link, int type, void *data, int dlen)
+{
+	struct omp_req req;
+	int error;
+
+	req.type = type;
+	req.dlen = dlen;
+
+	error = comm_send(link, &req, sizeof(req));
+	if (error < 0)
+		return -1;
+
+	error = comm_send(link, data, dlen);
+	if (error < 0)
+		return -1;
+
+	return 0;
+}
+
+
+int comm_send_req(struct socket *link, int type)
+{
+	struct omp_req req;
+	req.type = type;
+	return comm_send(link, &req, sizeof(req));
+}
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/copyuser.c ./hpc/copyuser.c
--- src-orig/hpc/copyuser.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/copyuser.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,427 @@
+/*
+ *	Copyright (C) 2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/sched.h>
+#include <hpc/protocol.h>
+#include <hpc/debug.h>
+#include <hpc/prototype.h>
+#include <hpc/hpc.h>
+
+/********** DEPUTY PART **********/
+
+/**
+ * deputy_copy_from_user - Copy from remote when running on deputy
+ **/
+unsigned long deputy_copy_from_user(void *to, const void __user *from, unsigned long n)
+{
+	struct omp_usercopy_req u;
+	int error;
+
+	if (in_atomic())
+		return n;
+
+	u.addr = (unsigned long) from;
+	u.len = n;
+
+	OMDEBUG_CPYUSER(1, "copy user[0x%p]->[0x%p][%ld]\n", from, to, n);
+
+	error = comm_send_hd(current->om.contact, DEP_COPY_FROM_USER, &u, sizeof(u));
+	if (error < 0)
+		goto error;
+
+	error = comm_recv(current->om.contact, to, n);
+	if (error < 0)
+		goto error;
+
+	return 0;
+error:
+	OMBUG("error %d\n", error);
+	return -1;
+}
+EXPORT_SYMBOL(deputy_copy_from_user);
+
+/**
+ * deputy_strncpy_from_user - strncpy on remote when running on deputy
+ **/
+unsigned long deputy_strncpy_from_user(char *dst, const char __user *src,
+							long count)
+{
+	struct omp_usercopy_req u;
+	int error;
+
+	OMDEBUG_CPYUSER(1, "strcpy user[0x%p]->[0x%p][%ld]\n", src, dst, count);
+	u.addr = (unsigned long) src;
+	u.len = count;
+	error = comm_send_hd(current->om.contact, DEP_STRNCPY_FROM_USER, &u,
+								sizeof(u));
+	if (error < 0)
+		goto error;
+
+	error = comm_recv(current->om.contact, dst, count);
+	if (error < 0)
+		goto error;
+
+	return 0;
+error:
+	OMBUG("error %d\n", error);
+	return -1;
+}
+
+/**
+ * deputy_copy_to_user - copy to remote when running on deputy
+ **/
+unsigned long deputy_copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+	struct omp_usercopy_req u;
+	int error;
+
+	if (in_atomic())
+		return n;
+
+	OMDEBUG_CPYUSER(1, "copy [0x%p]->user[0x%p][%ld]\n", from, to, n);
+	u.addr = (unsigned long) to;
+	u.len = n;
+
+	error = comm_send_hd(current->om.contact, DEP_COPY_TO_USER, &u,
+							sizeof(u));
+	if (error < 0)
+		goto error;
+
+	error = comm_send(current->om.contact, (void *) from, n);
+	if (error < 0)
+		goto error;
+
+	return 0;
+error:
+	OMBUG("error %d\n", error);
+	return -1;
+}
+EXPORT_SYMBOL(deputy_copy_to_user);
+
+/**
+ * deputy_strnlen_user - strnlen on remote when running on deputy
+ **/
+unsigned long deputy_strnlen_user(const char *s, long n)
+{
+	struct omp_usercopy_req u;
+	int error;
+	long ret;
+
+	OMDEBUG_CPYUSER(1, "strlen user[0x%p][%ld]\n", s, n);
+	u.addr = (unsigned long) s;
+	u.len = n;
+
+	error = comm_send_hd(current->om.contact, DEP_STRNLEN_USER, &u, sizeof(u));
+	if (error < 0)
+		goto out;
+
+	error = comm_recv(current->om.contact, &ret, sizeof(ret));
+	if (error < 0)
+		goto out;
+
+	return ret;
+out:
+	OMBUG("error %d\n", error);
+	return 0;
+}
+EXPORT_SYMBOL(deputy_strnlen_user);
+
+/**
+ * deputy_put_userX - put a value of 64 bit or less to remote
+ **/
+static inline long deputy_put_userX(s64 value, const void *addr, size_t size)
+{
+	struct omp_usercopy_emb u;
+	int error;
+
+	OMDEBUG_CPYUSER(1, "put (%lld)->user[0x%p][%zd]\n", value, addr, size);
+
+	u.addr = (unsigned long) addr;
+	u.len = size;
+	u.val = value;
+
+	error = comm_send_hd(current->om.contact, DEP_PUT_USER, &u, sizeof(u));
+	if (error < 0)
+		goto out;
+	return 0;
+out:
+	OMBUG("error %d\n", error);
+	return -EFAULT;
+}
+
+/**
+ * deputy_put_user - put a long value to remote
+ **/
+long deputy_put_user(long value, const void *addr, size_t size)
+{
+	BUG_ON(size > sizeof(long));
+	return deputy_put_userX((s64) value, addr, size);
+}
+EXPORT_SYMBOL(deputy_put_user);
+
+#if BITS_PER_LONG < 64
+/**
+ * deputy_put_user - put a 64 bit value to remote
+ **/
+long deputy_put_user64(s64 value, const void *addr)
+{
+	return deputy_put_userX(value, addr, 8);
+}
+EXPORT_SYMBOL(deputy_put_user64);
+#endif
+
+/**
+ * deputy_get_userX - get a value of 64 bit or less from remote
+ **/
+static inline long deputy_get_userX(s64 *value, const void *addr, size_t size)
+{
+	struct omp_usercopy_req u;
+	int error;
+	s64 ret;
+
+	OMDEBUG_CPYUSER(1, "get user[0x%p][%zd]\n", addr, size);
+	u.addr = (unsigned long) addr;
+	u.len = size;
+
+	error = comm_send_hd(current->om.contact, DEP_GET_USER, &u, sizeof(u));
+	if (error < 0)
+		goto out;
+
+	error = comm_recv(current->om.contact, &ret, sizeof(ret));
+	if (error < 0)
+		goto out;
+
+	switch (size) {
+	case 1: { s8 *v = (s8 *) value; *v = (s8) ret; break; }
+	case 2: { s16 *v = (s16 *) value; *v = (s16) ret; break; }
+	case 4: { s32 *v = (s32 *) value; *v = (s32) ret; break; }
+	case 8: *value = ret; break;
+	}
+	return 0;
+out:
+	OMBUG("error %d\n", error);
+	return -EFAULT;
+}
+
+/**
+ * deputy_get_user - get a long value from remote
+ **/
+long deputy_get_user(long *value, const void *addr, size_t size)
+{
+	BUG_ON(size > sizeof(long));
+	return deputy_get_userX((u64 *) value, addr, size);
+}
+EXPORT_SYMBOL(deputy_get_user);
+
+#if BITS_PER_LONG < 64
+/**
+ * deputy_get_user - get a 64 bit value from remote
+ **/
+long deputy_get_user64(s64 *value, const void *addr)
+{
+	return deputy_get_userX(value, addr, 8);
+}
+EXPORT_SYMBOL(deputy_get_user64);
+#endif
+
+/********** REMOTE PART **********/
+
+/**
+ * remote_copy_user - Copy to or from user for deputy
+ **/
+static int remote_copy_user(task_t *p, int request)
+{
+	struct omp_usercopy_req u;
+	void *buf = NULL;
+	int error;
+
+	error = comm_recv(p->om.contact, &u, sizeof(u));
+	if (error < 0)
+		goto out;
+
+	buf = kmalloc(u.len, GFP_KERNEL);
+	if (!buf)
+		goto out;
+
+	switch (request) {
+	case DEP_COPY_FROM_USER:
+		copy_from_user(buf, (const void __user *) u.addr, u.len);
+
+		error = comm_send(p->om.contact, buf, u.len);
+		if (error < 0)
+			goto out;
+		break;
+	case DEP_COPY_TO_USER:
+		error = comm_recv(p->om.contact, buf, u.len);
+		if (error < 0)
+			goto out;
+
+		copy_to_user((void __user *) u.addr, buf, u.len);
+		break;
+	}
+out:
+	kfree(buf);
+	return error;
+}
+
+/**
+ * remote_strncpy_from_user - strncpy from user for deputy
+ **/
+static int remote_strncpy_from_user(task_t *p)
+{
+	struct omp_usercopy_req u;
+	void *buf = NULL;
+	int error;
+
+	error = comm_recv(p->om.contact, &u, sizeof(u));
+	if (error < 0)
+		goto out;
+
+	buf = kmalloc(u.len, GFP_KERNEL);
+	if (!buf)
+		goto out;
+
+	strncpy_from_user(buf, (const char __user *) u.addr, u.len);
+
+	error = comm_send(p->om.contact, buf, u.len);
+	if (error < 0)
+		goto out;
+
+out:
+	kfree(buf);
+	return error;
+}
+
+/**
+ * remote_strnlen_from_user - strnlen from user for deputy
+ **/
+static int remote_strnlen_user(task_t *p)
+{
+	struct omp_usercopy_req u;
+	long ret;
+	int error;
+
+	error = comm_recv(p->om.contact, &u, sizeof(u));
+	if (error < 0)
+		goto out;
+
+	ret = (u.len)
+		? strnlen_user((const char __user *) u.addr, u.len)
+		: strlen_user((const char __user *) u.addr);
+
+	error = comm_send(p->om.contact, &ret, sizeof(ret));
+	if (error < 0)
+		goto out;
+out:
+	return error;
+}
+
+/**
+ * remote_put_user - put user for deputy
+ **/
+static int remote_put_user(task_t *p)
+{
+	struct omp_usercopy_emb u;
+	long ret;
+	int error;
+
+	error = comm_recv(p->om.contact, &u, sizeof(u));
+	if (error < 0)
+		goto out;
+
+	switch (u.len) {
+	case 1: ret = put_user(u.val, (u8 *) u.addr); break;
+	case 2: ret = put_user(u.val, (u16 *) u.addr); break;
+	case 4: ret = put_user(u.val, (u32 *) u.addr); break;
+	case 8: ret = put_user(u.val, (u64 *) u.addr); break;
+	default: ret = -EFAULT;
+	}
+	return ret;
+out:
+	return error;
+}
+
+/**
+ * remote_get_user - get user for deputy
+ **/
+static int remote_get_user(task_t *p)
+{
+	struct omp_usercopy_req u;
+	s64 ret;
+	int error;
+
+	error = comm_recv(p->om.contact, &u, sizeof(u));
+	if (error < 0)
+		goto out;
+
+	switch (u.len) {
+	case 1: get_user(ret, (u8 *) u.addr); break;
+	case 2: get_user(ret, (u16 *) u.addr); break;
+	case 4: get_user(ret, (u32 *) u.addr); break;
+#if BITS_PER_LONG == 64
+	case 8: get_user(ret, (u64 *) u.addr); break;
+#endif
+	}
+
+	error = comm_send(p->om.contact, &ret, sizeof(ret));
+	if (error < 0)
+		goto out;
+out:
+	return error;
+}
+
+
+/**
+ * remote_handle_user - Handle user copy until receiving @endtype
+ **/
+int remote_handle_user(task_t *p, int endtype)
+{
+	struct omp_req req;
+	int ret = 1;
+	int error;
+
+	while (ret != 0) {
+		error = comm_recv(p->om.contact, &req, sizeof(req));
+		if (error < 0)
+			return error;
+		if (req.type == endtype) {
+			ret = 0;
+			break;
+		}
+
+		switch (req.type) {
+		case DEP_COPY_FROM_USER:
+		case DEP_COPY_TO_USER:
+			remote_copy_user(p, req.type);
+			break;
+		case DEP_STRNCPY_FROM_USER:
+			remote_strncpy_from_user(p);
+			break;
+		case DEP_STRNLEN_USER:
+			remote_strnlen_user(p);
+			break;
+		case DEP_PUT_USER:
+			remote_put_user(p);
+			break;
+		case DEP_GET_USER:
+			remote_get_user(p);
+			break;
+		default:
+			OMBUG("unexpected type [%x]\n", req.type);
+			remote_disappear();
+			break;
+		}
+	}
+	return ret;
+}
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/ctrlfs.c ./hpc/ctrlfs.c
--- src-orig/hpc/ctrlfs.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/ctrlfs.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,60 @@
+/*
+ *	Copyright (C) 2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
+
+#define CTRLFS_MAGIC	0x29012508
+
+static struct vfsmount *ctrlfs_mount;
+static int ctrlfs_mount_count;
+
+static int ctrlfs_fill_super(struct super_block *sb, void *data, int silent)
+{
+	static struct tree_descr debug_files[] = {{""}};
+
+	return simple_fill_super(sb, CTRLFS_MAGIC, debug_files);
+}
+
+static struct super_block *ctrlfs_get_sb(struct file_system_type *fs_type,
+                                         int flags, const char *dev_name,
+                                         void *data)
+{
+	return get_sb_single(fs_type, flags, data, ctrlfs_fill_super);
+}
+
+static struct file_system_type ctrl_fs_type = {
+	.owner =	THIS_MODULE,
+	.name =		"omctrlfs",
+	.get_sb =	ctrlfs_get_sb,
+	.kill_sb =	kill_litter_super,
+};
+
+int __init om_ctrlfs_init(void)
+{
+	return register_filesystem(&ctrl_fs_type);
+}
+
+void __exit om_ctrlfs_exit(void)
+{
+	simple_release_fs(&ctrlfs_mount, &ctrlfs_mount_count);
+	unregister_filesystem(&ctrl_fs_type);
+}
+
+module_init(om_ctrlfs_init);
+module_exit(om_ctrlfs_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Vincent Hanquez");
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/debug.c ./hpc/debug.c
--- src-orig/hpc/debug.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/debug.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,69 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#include <asm/uaccess.h>
+#include <linux/kallsyms.h>
+#include <linux/sched.h>
+#include <linux/config.h>
+#include <hpc/debug.h>
+#include <hpc/protocol.h>
+#include <hpc/comm.h>
+
+void debug_mlink(struct socket *sock)
+{
+	printk("mlink: socket @ = %p\n", sock);
+}
+
+
+void debug_page(unsigned long addr)
+{
+	unsigned long digest = 0;
+	char *ptr = (char *) addr;
+	int i;
+
+	for (i = 0; i < 4096; i++)
+		digest += ptr[i] * i;
+
+	printk("sum of 0x%p is %lu\n", (void *) addr, digest);
+}
+
+void debug_vmas(struct mm_struct *mm)
+{
+	struct vm_area_struct *vma;
+
+	if (!mm) {
+		printk(KERN_ERR "debug_vma(): no mm !\n");
+		return;
+	}
+
+	printk(KERN_ERR "======== [LISTING VMA] ========\n");
+	for (vma = mm->mmap; vma; vma = vma->vm_next) {
+		printk(KERN_ERR "vma: [%.8lx:%.8lx]\n", vma->vm_start,
+							vma->vm_end);
+	}
+}
+
+void debug_signals(struct task_struct *p)
+{
+	struct signal_struct *signal;
+
+	signal = p->signal;
+
+	printk(KERN_ERR "=========== [DEBUG SIGNALS] ========\n");
+}
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/debugfs.c ./hpc/debugfs.c
--- src-orig/hpc/debugfs.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/debugfs.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,62 @@
+/*
+ *	Copyright (C) 2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/debugfs.h>
+#include <hpc/hpc.h>
+
+static struct dentry *om_debugfs_dir;
+
+static struct {
+	char *name;
+	int mode;
+	void *ptr;
+} file_entries[] = {
+	{ "migration", 0644, &om_opts.debug_mig },
+	{ "syscall", 0644, &om_opts.debug_sys },
+	{ "rinode", 0644, &om_opts.debug_rino },
+	{ "copyuser", 0644, &om_opts.debug_copyuser },
+};
+
+static struct dentry * dfs_dentries[4];
+
+int __init om_debugfs_init(void)
+{
+	int i;
+
+	om_debugfs_dir = debugfs_create_dir("om", NULL);
+	if (!om_debugfs_dir)
+		return 1;
+
+	for (i = 0; i < ARRAY_SIZE(file_entries); i++)
+		dfs_dentries[i] = debugfs_create_u8(file_entries[i].name,
+		                                    file_entries[i].mode,
+		                                    om_debugfs_dir,
+		                                    file_entries[i].ptr);
+	return 0;
+}
+
+void __exit om_debugfs_exit(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(file_entries); i++)
+		debugfs_remove(dfs_dentries[i]);
+	debugfs_remove(om_debugfs_dir);
+}
+
+module_init(om_debugfs_init);
+module_exit(om_debugfs_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Vincent Hanquez");
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/debug-i386.c ./hpc/debug-i386.c
--- src-orig/hpc/debug-i386.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/debug-i386.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,115 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#include <asm/uaccess.h>
+#include <linux/kallsyms.h>
+#include <linux/sched.h>
+#include <hpc/debug.h>
+#include <asm/ptrace.h>
+#include <asm/desc.h>
+#include <asm/i387.h>
+#include <asm/uaccess.h>
+#include <asm/ptrace.h>
+#include <hpc/protocol.h>
+#include <hpc/arch.h>
+#include <hpc/task.h>
+
+void om_debug_regs(struct pt_regs *myreg)
+{
+	struct pt_regs *reg;
+
+	reg = (myreg) ? myreg : ARCH_TASK_GET_USER_REGS(current);
+
+	printk("pt_regs:\n");
+	printk("ebx: 0x%lx, ecx: 0x%lx, edx: 0x%lx\n", reg->ebx, reg->ecx, reg->edx);
+	printk("esi: 0x%lx, edi: 0x%lx, ebp: 0x%lx\n", reg->esi, reg->edi, reg->ebp);
+	printk("eax: 0x%lx, xds: 0x%x, xes: 0x%x\n", reg->eax, reg->xds, reg->xes);
+	printk("orig_eax: 0x%lx, eip: 0x%lx, xcs: 0x%x\n", reg->orig_eax, reg->eip, reg->xcs);
+        printk("eflags: 0x%lx, esp: 0x%lx, xss: 0x%x\n", reg->eflags, reg->esp, reg->xss);
+}
+
+
+void inline debug_thread(struct thread_struct *t)
+{
+	printk("thread_struct:\n");
+	printk("esp0: 0x%lx, sysenter_cs: 0x%lx\n",t->esp0, t->sysenter_cs);
+	printk("eip: 0x%lx, esp: 0x%lx", t->eip, t->esp);
+
+}
+
+/* shamelessly stolen, this is useful to debug a user space
+ * process when it dies on remote */
+void show_user_registers(task_t *p)
+{
+	int i;
+	unsigned long esp;
+	unsigned short ss;
+	unsigned long prev_code;
+	struct pt_regs *regs;
+
+	if (!p->mm) {
+		printk(KERN_ERR "show_user_registers(): no mm !\n");
+		return;
+	}
+	regs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
+
+	esp = regs->esp;
+	ss = regs->xss & 0xffff;
+
+	printk("CPU:    %d\nEIP:    %04x:[<%08lx>]    %s\nEFLAGS: %08lx\n",
+		smp_processor_id(), 0xffff & regs->xcs, regs->eip, print_tainted(), regs->eflags);
+	print_symbol("EIP is at %s\n", regs->eip);
+	printk("eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
+		regs->eax, regs->ebx, regs->ecx, regs->edx);
+	printk("esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
+		regs->esi, regs->edi, regs->ebp, esp);
+	printk("ds: %04x   es: %04x   ss: %04x\n",
+		regs->xds & 0xffff, regs->xes & 0xffff, ss);
+	printk("Process %s (pid: %d, BOGUSthreadinfo=%p task=%p)",
+		p->comm, p->pid, current_thread_info(), p);
+
+	printk("\nStack: ");
+	show_stack(NULL, (unsigned long*)esp);
+
+	prev_code = regs->eip - 20;
+
+	printk("code before eip: ");
+	for(i = 0; i < 20 ; i++)
+	{
+		unsigned char c;
+		if(__get_user(c, &((unsigned char*)prev_code)[i]))
+			break;
+		printk("%02x ", c);
+	}
+	printk("\n");
+
+
+	printk("Code: ");
+	for(i = 0; i < 20 ; i++)
+	{
+		unsigned char c;
+		if(__get_user(c, &((unsigned char*)regs->eip)[i])) {
+			printk(" Bad EIP value.");
+			break;
+		}
+		printk("%02x ", c);
+	}
+	printk("\n");
+}
+
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/debug-ppc.c ./hpc/debug-ppc.c
--- src-orig/hpc/debug-ppc.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/debug-ppc.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,64 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#include <asm/uaccess.h>
+#include <linux/kallsyms.h>
+#include <linux/sched.h>
+#include <hpc/debug.h>
+#include <asm/ptrace.h>
+#include <asm/uaccess.h>
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#include <hpc/protocol.h>
+#include <hpc/arch.h>
+
+void om_debug_regs(struct pt_regs * myreg)
+{
+	struct pt_regs *regs;
+	int i;
+
+	regs = (myreg) ? myreg : ARCH_TASK_GET_USER_REGS(current);
+
+	printk("NIP: %08lX LR: %08lX SP: %08lX REGS: %p TRAP: %04lx\n",
+	       regs->nip, regs->link, regs->gpr[1], regs, regs->trap);
+	printk("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
+	       regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
+	       regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
+	       regs->msr & MSR_IR ? 1 : 0,
+	       regs->msr & MSR_DR ? 1 : 0);
+
+	for (i = 0; i < 32; i += 4) {
+		printk(KERN_ERR "GPR%02d: %08lx %08lx %08lx %08lx\n",
+					i, regs->gpr[i], regs->gpr[i + 1],
+					regs->gpr[i + 2], regs->gpr[i + 3]);
+	}
+
+}
+
+
+void inline debug_thread(struct thread_struct *t)
+{
+}
+
+
+/* shamelessly stolen, this is useful to debug a user space
+ * process when it dies on remote */
+void show_user_registers(task_t *p)
+{
+}
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/debug-x86_64.c ./hpc/debug-x86_64.c
--- src-orig/hpc/debug-x86_64.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/debug-x86_64.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,57 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#include <asm/uaccess.h>
+#include <linux/kallsyms.h>
+#include <linux/sched.h>
+#include <hpc/debug.h>
+#include <asm/ptrace.h>
+#include <asm/desc.h>
+#include <asm/i387.h>
+#include <asm/uaccess.h>
+#include <asm/ptrace.h>
+#include <hpc/protocol.h>
+#include <hpc/arch.h>
+#include <hpc/task.h>
+
+void om_debug_regs(struct pt_regs *myreg)
+{
+	struct pt_regs *reg;
+	reg = (myreg) ? myreg : ARCH_TASK_GET_USER_REGS(current);
+
+	printk("pt_regs:\n");
+	printk("r15: 0x%lx, r14: 0x%lx, r13: 0x%lx\n", reg->r15, reg->r14, reg->r13);
+	printk("r12: 0x%lx, rbp: 0x%lx, rbx: 0x%lx\n", reg->r12, reg->rbp, reg->rbx);
+	printk("r11: 0x%lx, r10: 0x%lx, r09: 0x%lx\n", reg->r11, reg->r10, reg->r9);
+	printk("r08: 0x%lx, rax: 0x%lx, rcx: 0x%lx\n", reg->r8, reg->rax, reg->rcx);
+	printk("rdx: 0x%lx, rsi: 0x%lx, rdi: 0x%lx\n", reg->rdx, reg->rsi, reg->rdi);
+	printk("orig_rax: 0x%lx, rip: 0x%lx,  cs: 0x%lx\n", reg->orig_rax, reg->rip, reg->cs);
+        printk("eflags: 0x%lx, rsp: 0x%lx,  ss: 0x%lx\n", reg->eflags, reg->rsp, reg->ss);
+}
+
+
+void inline debug_thread(struct thread_struct *t)
+{
+	printk("thread_struct:\n");
+}
+
+
+void show_user_registers(task_t *p)
+{
+}
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/deputy.c ./hpc/deputy.c
--- src-orig/hpc/deputy.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/deputy.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,487 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/file.h>
+#include <linux/mount.h>
+#include <linux/acct.h>
+#include <asm/mmu_context.h>
+#include <hpc/comm.h>
+#include <hpc/task.h>
+#include <hpc/mig.h>
+#include <hpc/arch.h>
+#include <hpc/syscalls.h>
+#include <hpc/debug.h>
+#include <hpc/prototype.h>
+#include <hpc/hpc.h>
+
+NORET_TYPE void deputy_die_on_communication(void)
+{
+	printk(KERN_ERR "deputy communication died.\n");
+	do_exit(SIGKILL);
+}
+
+/**
+ * deputy_do_syscall - process a syscall coming from remote
+ **/
+static int deputy_do_syscall(task_t *p)
+{
+	struct omp_syscall_req s;
+	struct omp_syscall_ret r;
+	int error;
+	
+	error = comm_recv(p->om.contact, &s, sizeof(s));
+	if (error < 0)
+		return -1;
+
+	OMDEBUG_SYS(1, "[deputy] receive syscall %d\n", s.n);
+
+	/* do the syscall and put reply in r */
+	r.ret = arch_exec_syscall(s.n, (syscall_parameter_t *) &s.arg);
+	
+	error = comm_send_hd(p->om.contact, REM_SYSCALL | REPLY, &r, sizeof(r));
+	if (error < 0)
+		return -1;
+
+	OMDEBUG_SYS(2, "[deputy] replied to syscall %d\n", s.n);
+
+	return 0;
+}
+
+/**
+ * deputy_do_fork - process a fork coming from remote
+ **/
+static int deputy_do_fork(task_t *p)
+{
+	int error;
+	struct omp_fork_req m;
+	struct omp_fork_ret r;
+	task_t *child;
+	struct socket *childsock;
+
+	error = comm_recv(p->om.contact, &m, sizeof(m));
+	if (error < 0)
+		return -1;
+
+	childsock = comm_setup_connect(&m.sockaddr, 0);
+	if (!childsock)
+		return -1;
+
+	r.pid = do_fork(m.clone_flags, m.stack_start, &m.regs, m.stack_size,
+						0, 0);
+
+	child = find_task_by_pid(r.pid);
+	if (!child) {
+		printk(KERN_ERR "error: child %d not found\n", r.pid);
+		return -1;
+	}
+	r.tgid = child->tgid;
+	task_set_comm(child, childsock);
+
+	error = comm_send_hd(p->om.contact, REM_FORK | REPLY, &r, sizeof(r));
+	if (error < 0)
+		return -1;
+
+	return 0;
+}
+
+/**
+ * deputy_do_readpage - process request a specific page
+ **/
+static int deputy_do_readpage(task_t *p)
+{
+	struct omp_page_req m;
+	struct page *page = NULL;
+	struct vm_area_struct vma = { };
+	struct om_held_file *heldfile;
+	void *kmpage;
+	int error;
+
+	error = comm_recv(p->om.contact, &m, sizeof(m));
+	if (error < 0)
+		goto out;
+
+	heldfile = task_heldfiles_find(p, m.file);
+	if (!heldfile) {
+		OMBUG("file not found\n");
+		goto out;
+	}
+		
+	memset(&vma, 0, sizeof(struct vm_area_struct));
+	vma.vm_end = m.offset + PAGE_SIZE;
+	vma.vm_file = (struct file *) m.file;
+
+	page = heldfile->nopage(&vma, m.offset, NULL);
+	kmpage = kmap(page);
+
+	error = comm_send(p->om.contact, kmpage, PAGE_SIZE);
+	if (error < 0)
+		goto out;
+out:
+	if (page) {
+		kunmap(page);
+		__free_page(page);
+	}
+	return error;
+}
+
+/**
+ * deputy_do_mmap_pgoff - really do a mmap on deputy
+ **/
+unsigned long deputy_do_mmap_pgoff(struct file * file, unsigned long addr,
+				unsigned long len, unsigned long prot,
+				unsigned long flags, unsigned long pgoff)
+{
+	int error;
+	struct vm_area_struct *vma;
+
+	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+	if (!vma) {
+		error = -ENOMEM;
+		goto out;
+	}
+	memset(vma, 0, sizeof(*vma));
+
+	vma->vm_mm = current->mm;
+	vma->vm_start = addr;
+	vma->vm_end = addr + len;
+	vma->vm_flags = flags;
+	vma->vm_page_prot = protection_map[flags & 0x0f];
+	vma->vm_pgoff = pgoff;
+	vma->vm_file = file;
+
+	error = file->f_op->mmap(file, vma);
+	if (error < 0)
+		goto out_freevma;
+
+	error = task_heldfiles_add(current, file, vma->vm_ops);
+
+	/* FIXME insert the vma ! */
+	return 0;
+out_freevma:
+	kmem_cache_free(vm_area_cachep, vma);
+out:
+	return error;
+}
+
+/**
+ * deputy_do_mmap - process request to mmap a file
+ **/
+static int deputy_do_mmap(task_t *p)
+{
+	struct omp_mmap_req m;
+	struct omp_mmap_ret r;
+	struct file *file;
+	int error;
+
+	error = comm_recv(p->om.contact, &m, sizeof(m));
+	if (error < 0)
+		goto error;
+
+	error = -EBADF;
+	file = fget(m.fd);
+	if (!file)
+		goto out;
+	
+	error = do_mmap_pgoff(file, m.addr, m.len, m.prot, m.flags, m.pgoff);
+	
+	r.file = file;
+	r.isize = file->f_dentry->d_inode->i_size;
+	fput(file);
+out:
+	r.ret = error;
+	
+	error = comm_send(p->om.contact, &r, sizeof(r));
+	if (error < 0)
+		goto error;
+	return 0;
+error:
+	return -1;
+}
+
+static void bprm_drop(struct linux_binprm *bprm)
+{
+	int i;
+
+	if (!bprm)
+		return;
+	for (i = 0; i < MAX_ARG_PAGES; i++) {
+		struct page * page = bprm->page[i];
+		if (page)
+			__free_page(page);
+	}
+	if (bprm->security)
+		security_bprm_free(bprm);
+	if (bprm->mm)
+		mmdrop(bprm->mm);
+	if (bprm->file) {
+		allow_write_access(bprm->file);
+		fput(bprm->file);
+	}
+	kfree(bprm);
+}
+
+static int __deputy_do_execve(struct linux_binprm *bprm,
+                              struct pt_regs * regs)
+{
+	int retval;
+
+	retval = search_binary_handler(bprm,regs);
+	if (retval >= 0) {
+		// FIXME free_arg_pages(bprm);
+
+		/* execve success */
+		security_bprm_free(bprm);
+		acct_update_integrals(current);
+		kfree(bprm);
+		return retval;
+	}
+
+	bprm_drop(bprm);
+	return retval;
+}
+
+struct linux_binprm *deputy_setup_bprm(char * filename,
+                              int argc, char **argv,
+                              int envc, char **envp)
+{
+	struct linux_binprm *bprm;
+	struct file *file;
+	int retval;
+
+	bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
+	if (!bprm)
+		return ERR_PTR(-ENOMEM);
+
+	file = open_exec(filename);
+	retval = PTR_ERR(file);
+	if (IS_ERR(file))
+		goto out;
+
+	bprm->p = PAGE_SIZE * MAX_ARG_PAGES - sizeof(void *);
+
+	bprm->file = file;
+	bprm->filename = filename;
+	bprm->interp = filename;
+	bprm->mm = mm_alloc();
+	retval = -ENOMEM;
+	if (!bprm->mm)
+		goto out;
+
+	retval = init_new_context(current, bprm->mm);
+	if (retval < 0)
+		goto out;
+
+	retval = bprm->argc = argc;
+	if (retval < 0)
+		goto out;
+
+	retval = bprm->envc = envc;
+	if (retval < 0)
+		goto out;
+
+	retval = security_bprm_alloc(bprm);
+	if (retval)
+		goto out;
+
+	retval = prepare_binprm(bprm);
+	if (retval < 0)
+		goto out;
+
+	retval = copy_strings_kernel(1, &bprm->filename, bprm);
+	if (retval < 0)
+		goto out;
+
+	bprm->exec = bprm->p;
+	retval = copy_strings_kernel(bprm->envc, envp, bprm);
+	if (retval < 0)
+		goto out;
+
+	retval = copy_strings_kernel(bprm->argc, argv, bprm);
+	if (retval < 0)
+		goto out;
+
+	return bprm;
+out:
+	bprm_drop(bprm);
+	return ERR_PTR(retval);
+}
+
+/**
+ * deputy_do_execve - process request to execve a new executable
+ **/
+static int deputy_do_execve(task_t *p)
+{
+	struct omp_execve_req m;
+	struct omp_execve_ret r;
+	int error;
+	char *filename;
+	char **argv, **envp;
+	struct linux_binprm *bprm;
+	int sz;
+	char *data = NULL;
+
+	error = comm_recv(p->om.contact, &m, sizeof(m));
+	if (error < 0)
+		goto error;
+
+	sz = m.filelen + m.argvlen + m.envplen + 3;
+	data = kmalloc(sz, GFP_KERNEL);
+	if (!data)
+		/* FIXME must reply to remote */
+		return -ENOMEM;
+	
+	error = comm_recv(p->om.contact, data, sz);
+	if (error < 0)
+		goto error;
+
+	filename = data;
+	argv = (char **) (data + m.filelen + 1);
+	envp = (char **) (data + m.filelen + m.argvlen + 2);
+
+	bprm = deputy_setup_bprm(filename, m.argc, argv,
+	                         m.envc, envp);
+	if (!bprm)
+		goto error;
+	
+	error = __deputy_do_execve(bprm, &m.regs);
+	if (error < 0)
+		goto error;
+
+	comm_send_hd(p->om.contact, REM_EXECVE | REPLY, &r, sizeof(r));
+
+	
+error:
+	kfree(data);
+	return error;
+}
+
+/**
+ * deputy_do_sigpending - process signal pending
+ **/
+static inline void deputy_do_sigpending(task_t *p)
+{
+	siginfo_t info;
+	struct omp_signal s;
+	int signr, error;
+
+	do_signal(ARCH_TASK_GET_USER_REGS(p), NULL);
+	
+	return;
+	
+	for (;;) {
+		signr = dequeue_signal(p, &p->blocked, &info);
+		if (!signr)
+			break;
+
+		s.signr = signr;
+		memcpy(&s.siginfo, &info, sizeof(siginfo_t));
+
+		error = comm_send_hd(p->om.contact, DEP_SIGNAL, &s, sizeof(s));
+		if (error < 0)
+			OMBUG("error %d\n", error);
+	}
+}
+
+/**
+ * deputy_process_misc - process has receive an interrupt in communication
+ **/
+static void deputy_process_misc(task_t *p)
+{
+	if (task_dreqs_pending(p))
+		task_do_request();
+
+	if (test_tsk_thread_flag(p, TIF_SIGPENDING)) {
+		deputy_do_sigpending(p);
+	}
+}
+
+/**
+ * deputy_process_communication - process has receive communication in deputy
+ **/
+static void deputy_process_communication(task_t *p)
+{
+	struct omp_req req;
+	int error;
+	
+	error = comm_recv(p->om.contact, &req, sizeof(req));
+	if (error < 0)
+		deputy_die_on_communication();
+
+	switch (req.type)
+	{
+	case 0:
+		deputy_die_on_communication();
+		break;
+	case REM_BRING_HOME:
+		error = task_go_home(p);
+		break;
+	case REM_SYSCALL:
+		error = deputy_do_syscall(p);
+		break;
+	case REM_FORK:
+		error = deputy_do_fork(p);
+		break;
+	case REM_PAGE:
+		error = deputy_do_readpage(p);
+		break;
+	case REM_MMAP:
+		error = deputy_do_mmap(p);
+		break;
+	case REM_EXECVE:
+		error = deputy_do_execve(p);
+		break;
+	default:
+		OMBUG("received unexpected [%x]\n", req.type);
+		error = -1;
+	}
+	if (error < 0)
+		deputy_die_on_communication();
+}
+
+/**
+ * deputy_main_loop - process loop when process is deputy
+ **/
+void deputy_main_loop(void)
+{
+	int has_communication;
+	
+	while (task_test_dflags(current, DDEPUTY))
+	{
+		has_communication = comm_wait(current->om.contact);
+		if (has_communication)
+			deputy_process_communication(current);
+		deputy_process_misc(current);
+	}
+}
+
+void exit_mm(task_t *);
+
+/**
+ * deputy_startup - startup deputy process
+ **/
+void deputy_startup(task_t *p)
+{
+	task_set_dflags(p, DDEPUTY);
+	/* FIXME it should not be necessary, but actually process got a
+	 * SIGKILL on his sigqueue for unknown reasons */
+	flush_signals(p);
+	exit_mm(p);
+}
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/files.c ./hpc/files.c
--- src-orig/hpc/files.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/files.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,284 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/sched.h>
+#include <linux/file.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/mm.h>
+#include <hpc/comm.h>
+#include <hpc/prototype.h>
+#include <hpc/debug.h>
+
+struct address_space_operations remote_aops = { .readpage = remote_readpage, };
+struct file_operations remote_file_operations = { .mmap = remote_file_mmap, };
+
+int task_heldfiles_add(task_t *p, struct file *file,
+				struct vm_operations_struct *vm_ops)
+{
+	struct om_held_file *rfile;
+
+	rfile = kmalloc(sizeof(struct om_held_file), GFP_KERNEL);
+	if (!rfile)
+		return -ENOMEM;
+
+	OMDEBUG_RINO(2, "process [%d] adding file [0x%p], nopage [0x%p]\n",
+			p->pid, file, (void *) vm_ops->nopage);
+
+	get_file(file);
+	rfile->file = file;
+	rfile->nb = (unsigned long) file; /* FIXME */
+	rfile->nopage = vm_ops->nopage;
+	list_add(&rfile->list, &p->om.rfiles);
+	return 0;
+}
+
+void task_heldfiles_clear(task_t *p)
+{
+	struct om_held_file *rfile, *next;
+
+	list_for_each_entry_safe(rfile, next, &p->om.rfiles, list) {
+		fput(rfile->file);
+		kfree(rfile);
+	}
+}
+
+struct om_held_file *task_heldfiles_find(task_t *p, struct file *file)
+{
+	struct om_held_file *heldfile;
+
+	OMDEBUG_RINO(3, "process [%d] searching file [0x%p]\n", p->pid, file);
+
+	list_for_each_entry(heldfile, &p->om.rfiles, list) {
+		if (heldfile->file == file)
+			return heldfile;
+	}
+	printk(KERN_ERR "heldfile: file not found\n");
+	return NULL;
+}
+
+#if 0
+static struct backing_dev_info remote_backing_dev_info = {
+        .ra_pages       = 0,    /* No readahead */
+        .memory_backed  = 1,    /* Does not contribute to dirty memory */
+};
+#endif
+
+/*****************************************************************************/
+struct om_remote_dentry
+{
+	struct list_head list;
+	struct dentry *dentry;
+};
+
+spinlock_t remote_dentries_lock = SPIN_LOCK_UNLOCKED;
+struct list_head remote_dentries = LIST_HEAD_INIT(remote_dentries);
+
+int rdentry_delete(struct dentry *dentry)
+{
+	struct list_head *ptr;
+	int ret = -ENOENT;
+
+	spin_lock(&remote_dentries_lock);
+	list_for_each(ptr, &remote_dentries) {
+		struct om_remote_dentry *rd = list_entry(ptr, struct om_remote_dentry, list);
+
+		if (rd->dentry == dentry) {
+			list_del(ptr);
+			kfree(rd);
+			ret = 0;
+		}
+	}
+	spin_unlock(&remote_dentries_lock);
+	if (ret)
+		BUG();
+	return ret;
+}
+
+void rdentry_iput(struct dentry *dentry, struct inode *inode)
+{
+	kfree(inode->u.generic_ip);
+	iput(inode);
+}
+
+struct dentry_operations remote_dentry_ops = {
+	.d_delete = rdentry_delete,
+	.d_iput = rdentry_iput,
+};
+
+struct super_operations rfile_dummy_block_ops = { };
+
+struct super_block rfiles_dummy_block =
+{
+	.s_op = &rfile_dummy_block_ops,
+	.s_inodes = LIST_HEAD_INIT(rfiles_dummy_block.s_inodes),
+};
+
+struct vfsmount remote_file_vfsmnt =
+{
+	.mnt_count = ATOMIC_INIT(1),
+	.mnt_hash = LIST_HEAD_INIT(remote_file_vfsmnt.mnt_hash),
+	.mnt_child = LIST_HEAD_INIT(remote_file_vfsmnt.mnt_child),
+	.mnt_mounts = LIST_HEAD_INIT(remote_file_vfsmnt.mnt_mounts),
+	.mnt_list = LIST_HEAD_INIT(remote_file_vfsmnt.mnt_list),
+	.mnt_expire = LIST_HEAD_INIT(remote_file_vfsmnt.mnt_expire),
+	.mnt_parent = &remote_file_vfsmnt,
+};
+
+static int rdentry_add_entry(struct dentry *dentry)
+{
+	struct om_remote_dentry *rdentry;
+
+	rdentry = kmalloc(sizeof(struct om_remote_dentry), GFP_KERNEL);
+	if (!rdentry)
+		return -ENOMEM;
+
+	rdentry->dentry = dentry;
+	spin_lock(&remote_dentries_lock);
+	list_add(&rdentry->list, &remote_dentries);
+	spin_unlock(&remote_dentries_lock);
+	return 0;
+}
+
+static struct dentry * rdentry_create_dentry(struct rfile_inode_data *data)
+{
+	struct dentry *dentry;
+	struct inode *inode;
+	struct rfile_inode_data *tmp;
+
+	inode = new_inode(&rfiles_dummy_block);
+	if (!inode)
+		return NULL;
+
+	tmp = kmalloc(sizeof(struct rfile_inode_data), GFP_KERNEL);
+	if (!tmp)
+		goto error;
+
+	memcpy(tmp, data, sizeof(struct rfile_inode_data));
+
+	inode->u.generic_ip = tmp;
+
+	inode->i_mode = S_IFREG;
+	inode->i_size = data->isize;
+	inode->i_fop = &remote_file_operations;
+	inode->i_mapping->a_ops = &remote_aops;
+
+	dentry = d_alloc(NULL, &(const struct qstr){ .name = "/", .len = 1 });
+	if (!dentry)
+		goto error;
+
+	dentry->d_inode = inode;
+	dentry->d_parent = dentry;
+
+	rdentry_add_entry(dentry);
+
+	return dentry;
+error:
+	kfree(data);
+	iput(inode);
+	return NULL;
+}
+
+static inline struct rfile_inode_data * rfile_inode_get_data(struct inode *inode)
+{
+	return (struct rfile_inode_data *) inode->u.generic_ip;
+}
+
+struct file * rfiles_inode_get_file(struct inode *inode)
+{
+	return rfile_inode_get_data(inode)->file;
+}
+
+static inline int rfiles_inode_compare(struct inode *inode,
+					struct rfile_inode_data *data)
+{
+	return memcmp(inode->u.generic_ip, data, sizeof(*data)) == 0;
+}
+
+static struct dentry * rdentry_find(struct rfile_inode_data *data)
+{
+	struct om_remote_dentry *ptr;
+	struct dentry *dentry = NULL;
+
+	spin_lock(&remote_dentries_lock);
+	list_for_each_entry(ptr, &remote_dentries, list) {
+		dentry = ptr->dentry;
+
+		if (rfiles_inode_compare(dentry->d_inode, data))
+			break;
+	}
+	spin_unlock(&remote_dentries_lock);
+	return dentry;
+}
+
+static struct file * rdentry_create_file(struct rfile_inode_data *data)
+{
+	struct file *file;
+	struct dentry *dentry;
+
+	file = get_empty_filp();
+	if (!file)
+		return NULL;
+
+	dentry = dget(rdentry_find(data));
+	if (!dentry) {
+		dentry = rdentry_create_dentry(data);
+		if (!dentry)
+			goto error;
+	}
+
+	file->f_mapping = dentry->d_inode->i_mapping;
+	file->f_dentry = dentry;
+	file->f_op = &remote_file_operations;
+	file->f_mode = FMODE_READ;
+	file->f_vfsmnt = &remote_file_vfsmnt;
+
+	return file;
+error:
+	put_filp(file);
+	return NULL;
+}
+
+struct file * task_rfiles_get(task_t *p, struct file *origfile,
+				unsigned long node, loff_t isize)
+{
+	struct vm_area_struct *vma;
+	struct file *file;
+	struct rfile_inode_data rdata;
+
+	rdata.file = origfile;
+	rdata.node = node;
+	rdata.isize = isize;
+
+	for (vma = p->mm->mmap; vma; vma = vma->vm_next)
+	{
+		if (!vma->vm_file)
+			continue;
+		file = vma->vm_file;
+		if (rfiles_inode_compare(file->f_dentry->d_inode, &rdata)) {
+			get_file(file);
+			return file;
+		}
+	}
+
+	file = rdentry_create_file(&rdata);
+	return file;
+}
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/kcomd.c ./hpc/kcomd.c
--- src-orig/hpc/kcomd.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/kcomd.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,446 @@
+/*
+ *	Copyright (C) 2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/net.h>
+#include <linux/syscalls.h>
+#include <net/sock.h>
+#include <net/tcp.h>
+
+static int socket_listen(struct sockaddr *saddr, struct socket **res)
+{
+	struct socket *sock;
+	int ret, fd;
+	
+	ret = sock_create(saddr->sa_family, SOCK_STREAM, IPPROTO_TCP, &sock);
+	if (ret < 0)
+		return -1;
+
+	fd = sock_map_fd(sock);
+	if (fd < 0)
+		goto err;
+
+	ret = sock->ops->bind(sock, saddr, sizeof(*saddr));
+	if (ret < 0)
+		goto err_fd;
+
+	ret = sock->ops->listen(sock, SOMAXCONN);
+	if (ret < 0)
+		goto err_fd;
+	*res = sock;
+	return fd;
+err_fd:
+	sys_close(fd);
+err:
+	sock_release(sock);
+	*res = NULL;
+	return -1;
+}
+
+static int socket_listen_ip4(int port, struct socket **res)
+{
+	struct sockaddr_in saddr4 = {
+		.sin_family = AF_INET,
+		.sin_addr.s_addr = INADDR_ANY,
+		.sin_port = htons(port),
+	};
+
+	return socket_listen((struct sockaddr *) &saddr4, res);
+}
+
+static int socket_listen_ip6(int port, struct socket **res)
+{
+	struct sockaddr_in6 saddr6 = {
+		.sin6_family = AF_INET6,
+		.sin6_port = htons(port),
+	};
+
+	return socket_listen((struct sockaddr *) &saddr6, res);
+}
+
+struct kcom_pkt
+{
+	pid_t pid;    /* pid of the process */
+	int len;      /* len of data */
+	int type;     /* type of data */
+	char *data;   /* ptr of data */
+	struct list_head list;
+};
+
+struct kcom_node
+{
+	int fd;                 /* fd to send packet */
+	struct socket *sock;    /* socket */
+	struct sockaddr addr;   /* addr of this node */
+	spinlock_t tasks_lock;  /* lock for the list */
+	struct list_head tasks; /* list of task */
+	struct list_head list; /* list of nodes */
+};
+
+struct kcom_task
+{
+	pid_t pid;              /* pid of the process owning this struct */
+	struct kcom_node *node; /* node of the process to send/recv */
+	struct list_head list;  /* list of process using some node */
+	
+	struct list_head out_packs;
+	struct kcom_pkt in_packs;
+};
+
+static DEFINE_SPINLOCK(kcom_nodes_lock);
+struct list_head kcom_nodes = LIST_HEAD_INIT(kcom_nodes);
+
+fd_set_bits sockets_fds;
+char *sockets_fds_bitmap = NULL;
+int maxfds = -1;
+
+static int alloc_fd_bitmap(int fd4, int fd6)
+{
+	struct kcom_node *node;
+	int n, size;
+
+	n = max(fd4, fd6);
+
+	spin_lock(&kcom_nodes_lock);
+	list_for_each_entry(node, &kcom_nodes, list)
+		n = max(node->fd, n);
+	spin_unlock(&kcom_nodes_lock);
+
+	/* we don't need to reallocate the bitmap */
+	if (n <= maxfds)
+		return 0;
+	maxfds = n;
+
+	kfree(sockets_fds_bitmap);
+
+	size = FDS_BYTES(n);
+	sockets_fds_bitmap = kmalloc(6 * size, GFP_KERNEL);
+	if (!sockets_fds_bitmap)
+		return ENOMEM;
+
+	sockets_fds.in      = (unsigned long *)  sockets_fds_bitmap;
+	sockets_fds.out     = (unsigned long *) (sockets_fds_bitmap +   size);
+	sockets_fds.ex      = (unsigned long *) (sockets_fds_bitmap + 2*size);
+	sockets_fds.res_in  = (unsigned long *) (sockets_fds_bitmap + 3*size);
+	sockets_fds.res_out = (unsigned long *) (sockets_fds_bitmap + 4*size);
+	sockets_fds.res_ex  = (unsigned long *) (sockets_fds_bitmap + 5*size);
+
+	return 0;
+}
+
+struct kcom_pkt *kcom_pkt_create(int len, int type, char *data)
+{
+	struct kcom_pkt *pkt;
+	pkt = kzalloc(sizeof(struct kcom_pkt), GFP_KERNEL);
+	if (pkt) {
+		pkt->len = len;
+		pkt->type = type;
+		pkt->data = data;
+	}
+	return pkt;
+}
+
+struct kcom_node *__kcom_node_find(struct sockaddr *saddr)
+{
+	struct kcom_node *tmp;
+
+	list_for_each_entry(tmp, &kcom_nodes, list) {
+		/* FIXME compare fields, no memcmp */
+		if (memcmp(saddr, tmp, sizeof(struct sockaddr)) == 0)
+			return tmp;
+	}
+	return NULL;
+}
+
+struct kcom_node *kcom_node_find(struct sockaddr *saddr)
+{
+	struct kcom_node *node;
+
+	spin_lock(&kcom_nodes_lock);
+	node = __kcom_node_find(saddr);
+	spin_unlock(&kcom_nodes_lock);
+	return node;
+}
+
+int kcom_node_add(int fd, struct socket *sock)
+{
+	struct kcom_node *node;
+
+	node = kzalloc(sizeof(struct kcom_node), GFP_KERNEL);
+	if (!node)
+		return -ENOMEM;
+	INIT_LIST_HEAD(&node->list);
+	node->sock = sock;
+	node->fd = fd;
+	/*
+	if (!sock->ops || !sock->ops->getname)
+		goto err;
+
+	ret = sock->ops->getname
+	check if it's already in node list.
+	*/
+	
+	spin_lock(&kcom_nodes_lock);
+	list_add(&node->list, &kcom_nodes);
+	spin_unlock(&kcom_nodes_lock);
+	return 0;
+}
+
+int kcom_node_del(struct sockaddr *addr)
+{
+	struct kcom_node *node;
+
+	/* remove the node from the list */
+	spin_lock(&kcom_nodes_lock);
+	node = __kcom_node_find(addr);
+	if (!node) {
+		spin_unlock(&kcom_nodes_lock);
+		return -ENOENT;
+	}
+	list_del(&node->list);
+	spin_unlock(&kcom_nodes_lock);
+
+	/* release and free structure */
+	sys_close(node->fd);
+	sock_release(node->sock);
+	kfree(node);
+	return 0;
+}
+
+int comm_simple(int type, char * data)
+{
+	return 0;
+}
+int comm_ack(void);
+int comm_iovec(void);
+int comm_iovec_ack(void);
+
+static int accept_connection(struct socket *lsock)
+{
+	struct socket *sock;
+	int ret, fd;
+
+	sock = sock_alloc();
+	if (!sock)
+		return -1;
+
+	ret = lsock->ops->accept(lsock, sock, 0);
+	if (ret)
+		goto err;
+	/*
+	if (!sock->ops || !sock->ops->getname)
+		goto err;
+
+	ret = sock->ops->getname
+	check if it's already in node list.
+	*/
+
+	fd = sock_map_fd(sock);
+	if (fd < 0)
+		goto err;
+
+	ret = kcom_node_add(fd, sock);
+	if (ret < 0)
+		goto errfd;
+	return fd;
+errfd:
+	sys_close(fd);
+err:
+	sock_release(sock);
+	return -1;
+}
+
+int data_read(struct kcom_node *node)
+{
+	return 0;
+}
+
+int data_write(struct kcom_node *node)
+{
+	return 0;
+}
+
+int dispatch(struct kcom_node *node)
+{
+	return 0;
+}
+
+struct kcom_task *kcom_task_create(struct kcom_node *node, int pid)
+{
+	struct kcom_task *kctask;
+
+	kctask = kzalloc(sizeof(struct kcom_task), GFP_KERNEL);
+	if (kctask) {
+		kctask->pid = pid;
+		kctask->node = node;
+		INIT_LIST_HEAD(&kctask->list);
+		
+		list_add(&kctask->list, &node->tasks);
+	}
+	return kctask;
+}
+
+int kcom_task_delete(int pid)
+{
+	struct kcom_node *tmp;
+	struct kcom_task *tmp2;
+
+	list_for_each_entry(tmp, &kcom_nodes, list)
+		list_for_each_entry(tmp2, &tmp->tasks, list)
+			if (tmp2->pid == pid) {
+				list_del(&tmp2->list);
+				kfree(tmp2);
+				break;
+			}
+	return 0;
+}
+
+struct kcom_task *__kcom_task_find(int pid)
+{
+	struct kcom_node *tmp;
+	struct kcom_task *tmp2;
+
+	list_for_each_entry(tmp, &kcom_nodes, list)
+		list_for_each_entry(tmp2, &tmp->tasks, list)
+			if (tmp2->pid == pid)
+				return tmp2;
+	return NULL;
+}
+
+struct kcom_task *kcom_task_find(int pid)
+{
+	struct kcom_task *tmp;
+
+	tmp = __kcom_task_find(pid);
+	return tmp;
+}
+
+int kcom_task_send(int pid, int type, char *data)
+{
+	struct kcom_task *tsk;
+	struct kcom_pkt *pkt;
+
+	tsk = kcom_task_find(pid);
+	if (!tsk)
+		return -ENODEV;
+	
+	/* put pkt in kcom_task */
+	pkt = kcom_pkt_create(0, 0, NULL);
+	if (!pkt)
+		return -1;
+	list_add(&pkt->list, &tsk->out_packs);
+
+	/* go to sleep */
+	/* wait reply */
+	
+	return 0;
+}
+
+
+static int kcomd_thread(void *nothing)
+{
+	int ret;
+	struct socket *lsock4, *lsock6;
+	int fd4, fd6;
+
+	printk(KERN_INFO "kcomd: init\n");
+	daemonize("kcomd", 0);
+
+retry_listen:
+	fd4 = socket_listen_ip4(0xb55, &lsock4);
+	fd6 = socket_listen_ip6(0xb56, &lsock6);
+
+	if (fd4 == -1 && fd6 == -1) {
+		schedule_timeout_interruptible(HZ);
+		goto retry_listen;
+	}
+
+	while (1)
+	{
+		s64 timeout = -1;
+		int n = -1;
+		struct kcom_node *node;
+
+		alloc_fd_bitmap(fd4, fd6);
+		n = maxfds;
+
+		zero_fd_set(n, sockets_fds.in);
+		zero_fd_set(n, sockets_fds.out);
+		zero_fd_set(n, sockets_fds.ex);
+	
+		/* add listening sockets to the set */
+		set_bit(fd4, sockets_fds.in);
+		set_bit(fd6, sockets_fds.in);
+
+		/* for each nodes (set fds.in && fds.out) */
+		spin_lock(&kcom_nodes_lock);
+		list_for_each_entry(node, &kcom_nodes, list) {
+			struct kcom_task *task;
+
+			if (node->fd == -1 || node->fd > maxfds)
+				continue;
+			set_bit(node->fd, sockets_fds.in);
+			list_for_each_entry(task, &node->tasks, list)
+				if (!list_empty(&task->out_packs))
+					set_bit(node->fd, sockets_fds.out);
+		}
+		spin_unlock(&kcom_nodes_lock);
+
+		zero_fd_set(n, sockets_fds.res_in);
+		zero_fd_set(n, sockets_fds.res_out);
+		zero_fd_set(n, sockets_fds.res_ex);
+
+		ret = do_select(n + 1, &sockets_fds, &timeout);
+		if (ret < 0)
+			continue;
+
+		/* test listening sockets */
+		if (fd4 != -1 && test_bit(fd4, sockets_fds.res_in))
+			accept_connection(lsock4);
+		if (fd6 != -1 && test_bit(fd6, sockets_fds.res_in))
+			accept_connection(lsock6);
+
+		/* for each nodes { test bit, in, out and do stuff } */
+		spin_lock(&kcom_nodes_lock);
+		list_for_each_entry(node, &kcom_nodes, list) {
+			if (test_bit(node->fd, sockets_fds.res_in))
+				data_read(node);
+			if (test_bit(node->fd, sockets_fds.res_out))
+				data_write(node);
+		}
+		spin_unlock(&kcom_nodes_lock);
+	}
+
+	return -1;
+}
+
+static int __init kcomd_init(void)
+{
+	long ret;
+
+	ret = kernel_thread(kcomd_thread, NULL, 0);
+	return ret;
+}
+
+static void __exit kcomd_exit(void)
+{
+}
+
+module_init(kcomd_init);
+module_exit(kcomd_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Vincent Hanquez");
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/Kconfig ./hpc/Kconfig
--- src-orig/hpc/Kconfig	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/Kconfig	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,58 @@
+#
+# HPC configuration 
+#
+
+menu "HPC options"
+
+config KCOMD
+	tristate "HPC Communication daemon"
+	help
+          Say Y will add support for the communication daemon
+
+config OPENMOSIX
+	bool "Enable OpenMosix clustering"
+	depends KCOMD
+	help
+	  Say Y to support process migration within a cluster
+
+config OPENMOSIX_VERBOSE
+	bool "Enable OpenMosix to be more verbose"
+	depends OPENMOSIX
+	default n
+
+config OPENMOSIX_MIGRATION_VERBOSE
+	bool "Add some message when migrating"
+	depends OPENMOSIX_VERBOSE
+	default n
+	help
+	  Say Y will throw message about migration into syslog
+
+config OPENMOSIX_DEBUG
+	bool "Enable OpenMosix debug"
+	depends OPENMOSIX
+	default n
+
+config OPENMOSIX_MIGRATION_DEBUG
+	bool "Add lots of message and print step when migrating"
+	depends OPENMOSIX_DEBUG
+	default n
+	help
+	  Say Y will throw lot of debug message about migration into syslog
+
+config OPENMOSIX_DEBUG_FS
+	tristate "Add debug files on debugfs"
+	depends OPENMOSIX_DEBUG
+	select DEBUG_FS
+	default n
+	help
+	  Export some variables through an om directory in debugfs for debugging
+
+config OPENMOSIX_CTRL_FS
+	tristate "control filesystem for openMosix"
+	depends OPENMOSIX
+	default y
+	help
+	  Add a omctrlfs to control openMosix features and have statistics
+	  about tasks.
+
+endmenu
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/kernel.c ./hpc/kernel.c
--- src-orig/hpc/kernel.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/kernel.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,214 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#include <linux/smp_lock.h>
+#include <linux/mm.h>
+#include <asm/mmu_context.h>
+#include <hpc/prototype.h>
+#include <hpc/hpc.h>
+#include <hpc/task.h>
+#include <hpc/comm.h>
+#include <hpc/mig.h>
+
+struct openmosix_options om_opts;
+EXPORT_SYMBOL_GPL(om_opts);
+
+/* kernel calls hooks */
+int openmosix_pre_clone(int flags)
+{
+	task_t *p = current;
+	struct mm_struct *mm = p->mm;
+
+	if (!(flags & CLONE_VM))
+		return 0;
+	if (mm)
+		atomic_inc(&mm->mm_realusers);
+
+	task_set_stay(p, DSTAY_CLONE);
+	return 0;
+}
+
+void openmosix_post_clone(int flags)
+{
+	task_t *p = current;
+	struct mm_struct *mm = p->mm;
+
+	if (!(flags & CLONE_VM))
+		return;
+	if (mm && atomic_read(&mm->mm_realusers) == 1)
+		task_clear_stay(p, DSTAY_CLONE);
+}
+
+/**
+ * task_maps_inode - Check if a task @p maps the inode @ip
+ **/
+int task_maps_inode(struct task_struct *p, struct inode *ip)
+{
+	return 0;
+}
+
+void openmosix_no_longer_monkey(struct inode *ip)
+{
+	task_t *p;
+
+	read_lock(&tasklist_lock);
+	for_each_process(p)
+		if (task_maps_inode(p, ip))
+			task_set_dreqs(p, DREQ_CHECKSTAY);
+	read_unlock(&tasklist_lock);
+}
+
+int stay_me_and_my_clones(int reasons)
+{
+	task_t *p, *me = current;
+	struct mm_struct *mm = me->mm;
+
+	task_lock(me);
+	task_set_stay(me, reasons);
+	task_unlock(me);
+	if (atomic_read(&mm->mm_realusers) > 1) {
+		read_lock(&tasklist_lock);
+		for_each_process(p) {
+			if (p->mm == mm && p != me) {
+				task_lock(p);
+				task_set_stay(p, reasons);
+				task_unlock(p);
+			}
+		}
+		read_unlock(&tasklist_lock);
+	}
+	return 0;
+}
+
+/**
+ * obtain_mm - obtain an mm context
+ *
+ * Description:
+ * Get an mm_struct and initialize it. Associate
+ * with our process.
+ **/
+int obtain_mm(task_t *p)
+{
+	struct mm_struct *mm, *active_mm;
+	int err;
+
+	if (p->mm && !task_test_dflags(p, DDEPUTY))
+		panic("openmosix: process->mm context had already");
+	/*
+	if (p->mm && task_test_dflags(p, DDEPUTY))
+		exit_mm(p);
+	*/
+	mm = mm_alloc();
+	if (!mm)
+		return -ENOMEM;
+	err = init_new_context(p, mm);
+	if (err) {
+		task_unlock(p);
+		mmdrop(mm);
+		return err;
+	}
+
+	spin_lock(&mmlist_lock);
+	list_add(&mm->mmlist, &init_mm.mmlist);
+	spin_unlock(&mmlist_lock);
+
+	task_lock(p);
+	active_mm = p->active_mm;
+	p->mm = mm;
+	p->active_mm = mm;
+	task_unlock(p);
+
+	activate_mm(active_mm, mm);
+	mmdrop(active_mm);
+	return 0;
+}
+
+void unstay_mm(struct mm_struct *mm)
+{
+	task_t *p;
+
+	if (atomic_read(&mm->mm_realusers) == 1 && mm == current->mm)
+	{
+		task_set_dreqs(current, DREQ_CHECKSTAY);
+		return;
+	}
+	read_lock(&tasklist_lock);
+	for_each_process(p)
+		if (p->mm == mm)
+			task_set_dreqs(p, DREQ_CHECKSTAY);
+	read_unlock(&tasklist_lock);
+}
+
+static inline int remote_pre_usermode(void)
+{
+	task_t *p = current;
+
+	if (p->om.contact && comm_peek(p->om.contact))
+		remote_do_comm(p);
+	return 0;
+}
+
+static inline int deputy_pre_usermode(void)
+{
+	deputy_main_loop();
+	return 0;
+}
+
+/**
+ * openmosix_pre_usermode - process some pre usermode events for current
+ **/
+asmlinkage int openmosix_pre_usermode(struct pt_regs regs)
+{
+	unsigned long flags;
+
+	if (task_test_dreqs(current, ~0)) {
+		local_save_flags(flags);
+		local_irq_enable();
+
+		task_do_request();
+
+		local_irq_restore(flags);
+	}
+
+	if (task_test_dflags(current, DMIGRATED)) {
+		local_save_flags(flags);
+		local_irq_enable();
+
+		if (task_test_dflags(current, DREMOTE))
+			return remote_pre_usermode();
+		if (task_test_dflags(current, DDEPUTY))
+			return deputy_pre_usermode();
+
+		local_irq_restore(flags);
+	}
+	return 0;
+}
+
+/**
+ * openmosix_init - Init all global variables and subsystem at boot
+ **/
+static int __init openmosix_init(void)
+{
+	/* kick off the kernel threads: */
+	kernel_thread(openmosix_mig_daemon, NULL, 0);
+
+	return 0;
+}
+
+subsys_initcall(openmosix_init);
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/Makefile ./hpc/Makefile
--- src-orig/hpc/Makefile	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/Makefile	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,19 @@
+# communication part
+obj-$(CONFIG_KCOMD)     += kcomd.o
+
+# core part
+obj-$(CONFIG_OPENMOSIX)		+= kernel.o task.o comm.o
+obj-$(CONFIG_OPENMOSIX)		+= remote.o deputy.o copyuser.o files.o syscalls.o
+obj-$(CONFIG_OPENMOSIX)		+= migrecv.o migsend.o migctrl.o
+obj-$(CONFIG_OPENMOSIX)		+= service.o
+obj-$(CONFIG_OPENMOSIX)		+= arch-$(ARCH).o
+
+# legacy
+obj-$(CONFIG_OPENMOSIX)		+= proc.o
+
+# new ctrl fs
+obj-$(CONFIG_OPENMOSIX_CTRL_FS)	+= ctrlfs.o
+
+# debug
+obj-$(CONFIG_OPENMOSIX_DEBUG)	+= debug.o debug-$(ARCH).o
+obj-$(CONFIG_OPENMOSIX_DEBUG_FS)+= debugfs.o
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/migctrl.c ./hpc/migctrl.c
--- src-orig/hpc/migctrl.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/migctrl.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,254 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <hpc/comm.h>
+#include <hpc/task.h>
+#include <hpc/hpc.h>
+#include <hpc/debug.h>
+#include <hpc/service.h>
+#include <hpc/prototype.h>
+#include <hpc/mig.h>
+#include <hpc/protocol.h>
+
+/**
+ * task_remote_expel - call from REMOTE to send a task to DEPUTY
+ * @p:		task which will come back
+ **/
+int task_remote_expel(task_t *p)
+{
+	struct socket *link;
+
+	BUG_ON(!task_test_dflags(p, DREMOTE));
+
+	if (mig_send_hshake(p, p->om.contact, HSHAKE_MIG_REQUEST))
+		goto failed;
+
+	if (mig_do_send(p)) {
+		goto failed;
+	}
+
+	link = task_set_comm(p, NULL);
+	comm_close(link);
+
+	do_exit(SIGKILL);
+	return 0;
+failed:
+	OMBUG("failed\n");
+	return -1;
+}
+
+/**
+ * task_remote_wait_expel - call from REMOTE to send a task to DEPUTY
+ * @p:		task which will come back
+ **/
+int task_remote_wait_expel(task_t *p)
+{
+	int error;
+	struct omp_req req;
+
+	comm_send_req(p->om.contact, REM_BRING_HOME);
+
+	error = comm_recv(p->om.contact, &req, sizeof(req));
+	if (error < 0)
+		return -1;
+	if (req.type != DEP_COMING_HOME) {
+		OMBUG("!DEP_COMING_HOME\n");
+		return -1;
+	}
+
+	return task_remote_expel(p);
+}
+
+/**
+ * task_local_send - Send a local task to remote
+ * @p:		task to send
+ * @whereto:	destination sockaddr
+ * @reason:	reason to send there (if any)
+ **/
+static int task_local_send(task_t *p, struct sockaddr *whereto, int reason)
+{
+	struct socket *mlink;
+	int error = 0;
+
+	if (task_test_dflags(p, DDEPUTY))
+		return 0;
+	sockaddr_setup_port(whereto, REMOTE_DAEMON_PORT);
+	mlink = comm_setup_connect(whereto, 0);
+	if (!mlink) {
+		OMBUG("error\n");
+
+		error = -1;
+		goto failed;
+	}
+
+	task_set_comm(p, mlink);
+	task_set_dflags(p, DDEPUTY);
+
+	/* see if other part is with on this */
+	if (mig_send_hshake(p, mlink, HSHAKE_MIG_REQUEST))
+		goto failed;
+
+	if (mig_do_send(p)) {
+		error = -1;
+		goto failed;
+	}
+
+	deputy_startup(p);
+	return 0;
+
+failed:
+	OMBUG("failed\n");
+	task_clear_dflags(p, DDEPUTY);
+	if (mlink)
+		comm_close(mlink);
+	return error;
+}
+
+
+
+/**
+ * task_local_bring - Receive task back in the deputy stub
+ * @p:		deputy task to receive
+ * @reason:	reason to send (if any)
+ **/
+static int task_local_bring(task_t *p, int reason)
+{
+	int error;
+	struct socket *link;
+
+	if (!task_test_dflags(p, DDEPUTY))
+		return 0;
+	if (obtain_mm(p)) {
+		printk(KERN_ERR "unable to obtain mm\n");
+		goto failed;
+	}
+
+	/* send remote request */
+	comm_send_req(p->om.contact, DEP_COMING_HOME);
+
+	/* see if other part is with on this */
+	if (mig_recv_hshake(p->om.contact))
+		goto failed;
+
+	/* receive the process back */
+	error = mig_do_receive(p);
+	if (error)
+		goto failed;
+
+	task_clear_dflags(p, DDEPUTY);
+	link = task_set_comm(p, NULL);
+	comm_close(link);
+
+	return 0;
+failed:
+	OMBUG("failed\n");
+	return -1;
+}
+
+/**
+ * task_move_remote2remote - migrate a task from remote to remote
+ * @p:		task to send
+ * @whereto:	whereto
+ * @reason:	reason to send (if any)
+ **/
+static int task_move_remote2remote(task_t *p, struct sockaddr * whereto,
+								int reason)
+{
+	OMBUG("not implemented.\n");
+	return 0;
+}
+
+/**
+ * task_move_to_node - send a task to a node
+ * @p:		task to send
+ * @whereto:	destination sockaddr
+ * @reason:	why
+ **/
+static int __task_move_to_node(struct task_struct *p,
+                               struct sockaddr * whereto,
+                               int reason)
+{
+	int error;
+
+	task_set_dflags(p, DPASSING);
+
+	error = (task_test_dflags(p, DREMOTE))
+		? (whereto)
+			? task_move_remote2remote(p, whereto, reason)
+			: task_remote_wait_expel(p)
+		: (whereto)
+			? task_local_send(p, whereto, reason)
+			: task_local_bring(p, reason);
+
+	task_clear_dflags(p, DPASSING);
+
+	return error;
+}
+
+int task_move_to_node(struct task_struct *p, struct sockaddr * whereto,
+                      int reason)
+{
+	if (task_test_stay(p, DSTAY)) {
+		printk(KERN_DEBUG "oM: Task can't move. check stay reason\n");
+		return -1;
+	}
+	__task_move_to_node(p, whereto, reason);
+	return 0;
+}
+
+/**
+ * task_go_home - Migrate task to home
+ **/
+int task_go_home(task_t *p)
+{
+	if (!task_test_dflags(p, DMIGRATED)) {
+		printk(KERN_INFO "oM: task %d at home: ignoring request.\n",
+				p->pid);
+		return -1;
+	}
+
+	__task_move_to_node(p, NULL, 0);
+
+	if (task_test_dflags(p, DMIGRATED))
+		printk(KERN_ERR "oM: task %d fail to go back home\n", p->pid);
+	return 0;
+}
+
+/**
+ * task_go_home_for_reason - Migrate back a task for a reason
+ **/
+int task_go_home_for_reason(task_t *p, int reason)
+{
+	int ret;
+
+	if (task_test_stay(p, reason) && task_test_dflags(p, DMIGRATED))
+		printk(KERN_ERR "oM: task should had migrated back earlier\n");
+	task_set_stay(p, reason);
+
+	if (!task_test_dflags(p, DMIGRATED))
+		return 0;
+	ret = __task_move_to_node(p, NULL, 0);
+	if (!ret)
+		task_clear_stay(p, reason);
+	return ret;
+}
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/migrecv.c ./hpc/migrecv.c
--- src-orig/hpc/migrecv.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/migrecv.c	2006-08-29 14:52:40.000000000 -0600
@@ -0,0 +1,411 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/rmap.h>
+#include <linux/mman.h>
+#include <linux/stddef.h>
+#include <linux/highmem.h>
+#include <linux/personality.h>
+#include <asm/mmu_context.h>
+#include <asm/tlbflush.h>
+#include <hpc/comm.h>
+#include <hpc/task.h>
+#include <hpc/hpc.h>
+#include <hpc/service.h>
+#include <hpc/mig.h>
+#include <hpc/debug.h>
+#include <hpc/protocol.h>
+#include <hpc/prototype.h>
+#include <hpc/version.h>
+#include <hpc/arch.h>
+
+/* handshake with the remote part */
+int mig_recv_hshake(struct socket *mlink)
+{
+	int error;
+	struct omp_mig_handshake hshake;
+
+	/* receive request of whatever */
+	error = comm_recv(mlink, &hshake, sizeof(hshake));
+	if (error < 0) {
+		OMBUG("recv failed %d\n", error);
+		return -1;
+	}
+
+	/* FIXME: sanity checks here */
+
+	/* reply of mig_requests */
+	hshake.type = hshake.type | HSHAKE_REPLY;
+	hshake.version = OPENMOSIX_VERSION;
+
+	error = comm_send(mlink, &hshake, sizeof(hshake));
+	if (error < 0) {
+		OMBUG("send failed %d\n", error);
+		return -1;
+	}
+
+	return 0;
+}
+
+/*****************************************************************************/
+
+/**
+ * mig_do_receive_mig_mm - Receive some parameters for a mm
+ **/
+static void mig_do_receive_mm(task_t *p, struct omp_mig_mm *s)
+{
+	OMDEBUG_MIG(2, "MIG_MM\n");
+	/* copy all mm's parameter from start_code to env_end */
+	memcpy(&p->mm->start_code, s, sizeof(*s));
+}
+
+/**
+ * mig_do_receive_mm_area - Set up an mmap
+ **/
+static int mig_do_receive_vma(task_t *p, struct omp_mig_vma *a)
+{
+	unsigned long result, prot, flags;
+	struct file *file = NULL;
+	extern asmlinkage long sys_madvise(unsigned long, size_t, int);
+
+	OMDEBUG_MIG(2, "MIG_VMA [%lx, %ld]\n", a->vm_start, a->vm_size);
+
+	/* FIXME : Temporary disabled */
+	if (0 && a->vm_file) {
+		file = (task_test_dflags(p, DREMOTE))
+			? task_rfiles_get(p, a->vm_file, -1, a->i_size)
+			: a->vm_file;
+	}
+
+	/* unconvert prot+flags: */
+	flags = MAP_FIXED | MAP_PRIVATE;
+	prot = 0;
+	if (a->vm_flags & VM_GROWSDOWN)
+		flags |= MAP_GROWSDOWN;
+	if (a->vm_flags & VM_DENYWRITE)
+		flags |= MAP_DENYWRITE;
+	if (a->vm_flags & VM_EXECUTABLE)
+		flags |= MAP_EXECUTABLE;
+
+	/* copy VM_(READ|WRITE|EXEC) bits to prot */
+	prot |= (a->vm_flags & (VM_READ | VM_WRITE | VM_EXEC));
+
+	/* mmap stuff */
+	result = do_mmap_pgoff(file, a->vm_start, a->vm_size, prot,
+						flags, a->vm_pgoff);
+	if (IS_ERR((const void *) result))
+		return PTR_ERR((const void *) result);
+
+	if (a->vm_flags & VM_READHINTMASK) {
+		int behavior = (a->vm_flags & VM_SEQ_READ)
+				? MADV_RANDOM
+				: MADV_SEQUENTIAL;
+		sys_madvise(a->vm_start, a->vm_size, behavior);
+	}
+	return 0;
+}
+
+
+/**
+ * mig_do_receive_page - Receive one page
+ **/
+static int mig_do_receive_page(task_t *p, unsigned long addr)
+{
+	struct mm_struct *mm = p->mm;
+	struct vm_area_struct *vma;
+	struct page *recv_page = NULL;
+	void *kmpage; /* kmapped page */
+	int error;
+	pgd_t * pgd;
+	pud_t * pud;
+	pmd_t * pmd;
+	pte_t * pte;
+
+	OMDEBUG_MIG(3, "MIG_PAGE [%lx]\n", addr);
+
+	vma = find_vma(mm, addr);
+	if (!vma) {
+		OMBUG("vma not found (addr: %p)\n", (void *) addr);
+		return -1;
+	}
+
+	/* check if enough memory */
+
+	/* alloc page */
+	recv_page = alloc_page(GFP_HIGHUSER);
+	if (!recv_page) {
+		OMBUG("unable to allocate page\n");
+		return -ENOMEM;
+	}
+
+	kmpage = kmap(recv_page);
+
+	/* receive the data into the page */
+	error = comm_recv(p->om.contact, kmpage, PAGE_SIZE);
+
+	kunmap(recv_page);
+	if (error < 0) {
+		OMBUG("failed to receive data\n");
+		goto out;
+	}
+
+	/* add the page at correct place */
+	pgd = pgd_offset(mm, addr);
+	pud = pud_alloc(mm, pgd, addr);
+	if (!pud)
+		goto out;
+	pmd = pmd_alloc(mm, pud, addr);
+	if (!pmd)
+		goto out;
+	pte = pte_alloc_map(mm, pmd, addr);
+	if (!pte)
+		goto out;
+	if (!pte_none(*pte))
+		OMBUG("double page at addr %p\n", (void *) addr);
+
+	set_pte(pte, pte_mkdirty(mk_pte(recv_page, vma->vm_page_prot)));
+	pte_unmap(pte);
+	page_dup_rmap(recv_page);
+	inc_mm_counter(mm, file_rss);
+
+	return 0;
+out:
+	OMBUG("receive page failed at addr %p\n", (void *) addr);
+	__free_page(recv_page);
+	return -1;
+}
+
+/**
+ * mig_do_receive_fp - Receive floating points registers
+ * @p:		task
+ * @fpr:	floating point registers
+ **/
+static void mig_do_receive_fp(task_t *p, struct omp_mig_fp *fp)
+{
+	OMDEBUG_MIG(2, "MIG_FP\n");
+	set_used_math();
+	arch_mig_receive_fp(p, fp);
+}
+
+/**
+ * mig_do_receive_misc - Receive normal registers, limits
+ **/
+static void mig_do_receive_proc_context(task_t *p, struct omp_mig_task *m)
+{
+	OMDEBUG_MIG(1, "MIG_TASK\n");
+	/* arch specific proc receive context */
+	arch_mig_receive_proc_context(p, m);
+
+	/* copy id */
+	p->om.pid = m->pid;
+	p->om.tgid = m->tgid;
+
+	/* copy credentials */
+	p->uid = m->uid;
+	p->euid = m->euid;
+	p->suid = m->suid;
+	p->fsuid = m->fsuid;
+
+	p->gid = m->gid;
+	p->egid = m->egid;
+	p->sgid = m->sgid;
+	p->fsgid = m->fsgid;
+
+	/* signals stuffs */
+	p->blocked = m->blocked;
+	p->real_blocked = m->real_blocked;
+	p->sas_ss_sp = m->sas_ss_sp;
+	p->sas_ss_size = m->sas_ss_size;
+	memcpy(p->sighand->action, m->sighand, sizeof(struct k_sigaction)
+								* _NSIG);
+
+	/* FIXME we don't trust the other node anyway so copy rlimit from node[nr] */
+
+	memcpy(p->comm, m->comm, sizeof(m->comm));
+
+	p->personality = m->personality;
+	arch_pick_mmap_layout(p->mm);
+}
+
+/**
+ * mig_do_receive - Receive all process stuff (mm, pages, fpr, ..)
+ **/
+int mig_do_receive(task_t *p)
+{
+	int error;
+	unsigned int got_not_coming = 0;
+	unsigned long data;
+	struct omp_req req;
+
+	data = __get_free_page(GFP_KERNEL);
+	if (!data)
+		goto fail;
+
+	task_set_dflags(p, DINCOMING);
+	clear_used_math();
+
+	while (1) {
+		error = comm_recv(p->om.contact, &req, sizeof(req));
+		if (error < 0)
+			goto fail;
+
+		BUG_ON(req.dlen > PAGE_SIZE);
+		error = comm_recv(p->om.contact, (void *) data, req.dlen);
+		if (error < 0)
+			goto fail;
+
+		switch (req.type) {
+		case MIG_MM:
+			mig_do_receive_mm(p, (struct omp_mig_mm *) data);
+			break;
+		case MIG_VMA:
+			if (mig_do_receive_vma(p, (struct omp_mig_vma *) data))
+				goto fail;
+			break;
+		case MIG_PAGE:
+			if (mig_do_receive_page(p, *((unsigned long *) data)))
+				goto fail;
+			break;
+		case MIG_FP:
+			mig_do_receive_fp(p, (struct omp_mig_fp *) data);
+			break;
+		case MIG_ARCH:
+			if (arch_mig_receive_specific(p, (struct omp_mig_arch *) data))
+				goto fail;
+			break;
+		/* this is the last thing we do in the chain of receiving,
+		 * so return 0 after we're done */
+		case MIG_TASK:
+			mig_do_receive_proc_context(p, (struct omp_mig_task *) data);
+			comm_send_req(p->om.contact, MIG_TASK | REPLY);
+			task_clear_dflags(p, DINCOMING);
+
+			flush_tlb_mm(p->mm); /* for all the new pages */
+			return 0;
+		case MIG_ABORT:
+			printk("mig_do_recv(): got MIG_ABORT\n");
+			got_not_coming = 1;
+			goto fail;
+		default:
+			printk("mig_do_recv(): got default\n");
+			goto fail;
+		}
+	}
+fail:
+	task_clear_dflags(p, DINCOMING);
+	free_page(data);
+
+	OMBUG("failed\n");
+	return -1;
+}
+
+static NORET_TYPE int mig_handle_migration(void *ptr)
+{
+	task_t *p = current;
+	/* link against the other end */
+	struct socket *link = (struct socket *) ptr;
+	int error;
+
+	OM_VERBOSE_MIG("[OM] receiving new process\n");
+
+	task_set_comm(p, link);
+
+	error = obtain_mm(p);
+	if (error)
+		goto fail;
+	if (mig_recv_hshake(link))
+		goto fail;
+
+	error = mig_do_receive(p);
+
+	if (error)
+		goto fail;
+
+	OM_VERBOSE_MIG("[OM] starting process(%d)\n", p->pid);
+	reparent_to_init();
+	arch_kickstart(p);
+	/*NOTREACHED*/
+
+fail:
+	OMBUG("failed\n");
+	do_exit(SIGKILL);
+	/*NOTREACHED*/
+}
+
+/**
+ * openmosix_mig_daemon - openMosix migration daemon
+ * @nothing:	unused
+ *
+ * Description:
+ * 	start the migration daemon.
+ * 	wait for communication, and if it is a remote request
+ * 	then start a user-thread with the new program to run
+ **/
+int openmosix_mig_daemon(void *nothing)
+{
+	task_t *p = current;
+	int error;
+	struct socket *mlink;
+	struct sockaddr saddr;
+
+	om_daemonize("omkmigd", 0);
+
+	task_set_dflags(p, DREMOTEDAEMON);
+
+	set_our_addr(AF_INET, &saddr, REMOTE_DAEMON_PORT);
+
+restart:
+	if (!p->om.contact) {
+		p->om.contact = comm_setup_listen(&saddr);
+		if (!p->om.contact) {
+			printk(KERN_WARNING
+				"omkmigd: failed to open mig service\n");
+			flush_signals(p);
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(HZ);
+			goto restart;
+		}
+	}
+
+	/* migration daemon loop */
+	while (1)
+	{
+		error = comm_accept(p->om.contact, &mlink, &saddr, 0UL);
+		if (error == -EINTR || error == -ERESTART || error == -EAGAIN
+		   || error == -ERESTARTSYS)
+		{
+			if (sigismember(&(p->pending.signal), SIGCHLD)) {
+				printk("omigd: SIGCHLD caught\n");
+			}
+			flush_signals(p);
+			continue;
+		} else if (error) {
+			OMBUG("failed to accept\n");
+			comm_close(mlink);
+			goto restart;
+		}
+
+		error = user_thread(mig_handle_migration, (void *) mlink, 0);
+		if (error < 0)
+			comm_close(mlink);
+	}
+}
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/migsend.c ./hpc/migsend.c
--- src-orig/hpc/migsend.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/migsend.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,241 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/stddef.h>
+#include <linux/highmem.h>
+#include <linux/personality.h>
+#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
+#include <hpc/comm.h>
+#include <hpc/task.h>
+#include <hpc/hpc.h>
+#include <hpc/debug.h>
+#include <hpc/service.h>
+#include <hpc/prototype.h>
+#include <hpc/mig.h>
+#include <hpc/protocol.h>
+#include <hpc/version.h>
+#include <hpc/arch.h>
+
+/* handle sending of migration request, and check answer */
+int mig_send_hshake(task_t *p, struct socket *mlink, int type)
+{
+	struct omp_mig_handshake hshake, hshake_recv;
+	int error;
+
+	hshake.type = type;
+	hshake.version = OPENMOSIX_VERSION;
+	hshake.personality = p->personality;
+
+	error = comm_send(mlink, &hshake, sizeof(hshake));
+        if (error < 0) {
+		OMBUG("send failed: %d\n", error);
+		return -1;
+	}
+
+	error = comm_recv(mlink, &hshake_recv, sizeof(hshake_recv));
+        if (error < 0) {
+		OMBUG("recv failed %d\n", error);
+                return -1;
+        }
+
+	if (hshake_recv.type != (hshake.type | HSHAKE_REPLY)) {
+		/* it's a no go ... */
+		OMBUG("no go\n");
+		return -1;
+	}			
+
+	return 0;
+}
+
+static int mig_send_fp(task_t *p)
+{
+	struct omp_mig_fp m;
+
+	if (!used_math())
+		return 0;
+
+	arch_mig_send_fp(p, &m);
+	return comm_send_hd(p->om.contact, MIG_FP, &m, sizeof(m));
+}
+
+
+static int mig_send_mm(task_t *p)
+{
+	struct omp_mig_mm s;
+
+	memcpy(&s, &p->mm->start_code, sizeof(s));
+
+	return comm_send_hd(p->om.contact, MIG_MM, &s, sizeof(s));
+}
+
+static inline void mig_send_vma_file(task_t *p, struct vm_area_struct *vma,
+							struct omp_mig_vma *m)
+{
+	struct inode *inode = vma->vm_file->f_dentry->d_inode;
+
+	m->vm_pgoff = vma->vm_pgoff;
+	m->i_size = inode->i_size;
+
+	if (task_test_dflags(p, DREMOTE)) {
+		struct rfile_inode_data *data;
+
+		data = (struct rfile_inode_data *) inode->u.generic_ip;
+		m->vm_file = data->file;
+	} else {
+		m->vm_file = vma->vm_file;
+		m->f_dentry = vma->vm_file->f_dentry;
+	}
+}
+
+static int mig_send_vmas(task_t *p)
+{
+	struct vm_area_struct *vma;
+	struct omp_mig_vma m;
+	int ret = 0;
+
+	for (vma = p->mm->mmap; vma; vma = vma->vm_next)
+	{
+		m.vm_start= vma->vm_start;
+		m.vm_size = vma->vm_end - vma->vm_start;
+		m.vm_flags = vma->vm_flags;
+		m.vm_file = vma->vm_file;
+		m.vm_pgoff = 0;
+		if (vma->vm_file)
+			mig_send_vma_file(p, vma, &m);
+
+		ret = comm_send_hd(p->om.contact, MIG_VMA, &m, sizeof(m));
+		if (ret < 0) {
+			OMBUG("send vma failed\n");
+			break;
+		}
+
+	}
+	return ret;
+}
+
+
+static int mig_send_pages(task_t *p)
+{
+	struct vm_area_struct * vma;
+	unsigned long addr;
+	int error;
+
+	for (vma = p->mm->mmap; vma; vma = vma->vm_next)
+	{
+		if (!(vma->vm_flags & VM_READ))
+			continue;
+		for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE)
+		{
+			error = comm_send_hd(p->om.contact, MIG_PAGE, &addr,
+								sizeof(addr));
+			if (error < 0)
+				goto fail;
+
+			error = comm_send(p->om.contact, (void *) addr,
+								PAGE_SIZE);
+			if (error < 0)
+				goto fail;
+		}
+	}
+	return 0;
+fail:
+	OMBUG("failed (addr: %p)\n", (void *) addr);
+	return -1;
+}
+
+
+static int mig_send_proc_context(task_t *p)
+{
+	struct omp_mig_task m;
+	struct omp_req req;
+	int error;
+
+	m.ptrace = p->ptrace;
+
+	m.pid = p->pid;
+	m.tgid = p->tgid;
+
+	/* credentials */
+	m.uid = p->uid;
+	m.euid = p->euid;
+	m.suid = p->suid;
+	m.fsuid = p->fsuid;
+
+	m.gid = p->gid;
+	m.egid = p->egid;
+	m.sgid = p->sgid;
+	m.fsgid = p->fsgid;
+
+	/* signals */
+	m.blocked = p->blocked;
+	m.real_blocked = p->real_blocked;
+	m.sas_ss_sp = p->sas_ss_sp;
+	m.sas_ss_size = p->sas_ss_size;
+	memcpy(m.sighand, p->sighand->action, sizeof(struct k_sigaction)
+								* _NSIG);
+
+	/* others */
+	m.nice = task_nice(p);
+	m.caps = p->cap_effective;
+	p->om.remote_caps = m.caps;
+
+	m.personality = p->personality;
+
+	memcpy(m.comm, p->comm, sizeof(m.comm));
+
+	arch_mig_send_proc_context(p, &m);
+
+	error = comm_send_hd(p->om.contact, MIG_TASK, &m, sizeof(m));
+	if (error < 0)
+		goto fail;
+
+	error = comm_recv(p->om.contact, &req, sizeof(req));
+
+	if (req.type == (MIG_TASK | REPLY))
+		return 0; /* commit point */
+
+fail:
+	OMBUG("failed\n");
+	return -1;
+}
+
+int mig_do_send(task_t *p)
+{
+	arch_mig_send_pre(p);
+
+	if (mig_send_mm(p)) goto fail_mig;
+	if (mig_send_vmas(p)) goto fail_mig;
+	if (mig_send_pages(p)) goto fail_mig;
+	if (mig_send_fp(p)) goto fail_mig;
+	if (arch_mig_send_specific(p)) goto fail_mig;
+	if (mig_send_proc_context(p)) goto fail_mig;
+
+	arch_mig_send_post(p);
+
+	return 0;
+fail_mig:
+	OMBUG("failed\n");
+	comm_send_req(p->om.contact, MIG_ABORT);
+	return -1;
+}
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/proc.c ./hpc/proc.c
--- src-orig/hpc/proc.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/proc.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,384 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/socket.h>
+#include <linux/ctype.h>
+#include <asm/uaccess.h>
+#include <hpc/hpc.h>
+#include <hpc/proc.h>
+#include <hpc/version.h>
+#include <hpc/service.h>
+#include <hpc/prototype.h>
+#include <hpc/task.h>
+#include <hpc/debug.h>
+#include <hpc/mig.h>
+
+/*
+ *	PID set/get accessor
+ */
+static int proc_pid_set_where(struct task_struct *p, char *buf, size_t size)
+{
+	int ret;
+	struct sockaddr destination;
+
+	if (size >= 4 && strnicmp(buf, "home", 4) == 0) {
+		printk("HOME detected\n");
+		ret = task_register_migration(p, NULL);
+	} else {
+		ret = string_to_sockaddr(buf, &destination);
+		if (ret >= 0)
+			task_register_migration(p, &destination);
+	}
+	return size;
+}
+
+static int proc_pid_get_where(struct task_struct *p, char *buf, size_t size)
+{
+	int length;
+	struct sockaddr address;
+
+	if (p->om.contact && task_test_dflags(p, DMIGRATED)) {
+		comm_getname(p->om.contact, &address, 1);
+		length = sockaddr_to_string(&address, buf);
+		length += sprintf(buf + length, "\n");
+	} else
+		length = sprintf(buf, "home\n");
+
+	return length;
+}
+
+static char *stayreason_string[32] = {
+	"monkey",	"mmap_dev",	"VM86_mode",	NULL,
+	"priv_inst",	"mem_lock",	"clone_vm",	"rt_sched",
+	"direct_io",	"system",	NULL,		NULL,
+	NULL,		NULL,		NULL,		NULL,
+	NULL,		NULL,		NULL,		NULL,
+	NULL,		NULL,		NULL,		NULL,
+	"extern_1",	"extern_2",	"extern_3",	"extern_4",
+	NULL,		NULL,		NULL,		"user_lock"
+};
+
+static int proc_pid_get_stay(struct task_struct *p, char *buf, size_t size)
+{
+	int length, i;
+
+	length = 0;
+	for (i = 0; i < 31; i++)
+		if (task_test_stay(p, 1 << i))
+			length += snprintf(buf + length, size - length,
+					"%s\n", stayreason_string[i]);
+	if (!length)
+		buf[0] = 0;
+	return length;
+}
+
+static int proc_pid_get_debug(struct task_struct *p, char *buf, size_t size)
+{
+	int length;
+
+	length = sprintf(buf, "debug: dflags: 0x%.8x\n", p->om.dflags);
+	return length;
+}
+
+static int proc_admin_set_bring(char *buf, size_t size)
+{
+	printk(KERN_DEBUG "oM: proc: set bring");
+	return size;
+}
+
+static int proc_admin_set_expel(char *buf, size_t size)
+{
+	printk(KERN_DEBUG "oM: proc: set expel");
+	return size;
+}
+
+static int proc_admin_get_version(char *buf, size_t size)
+{
+	int length;
+
+	length = sprintf(buf, "openMosix version: %d.%d.%d\n",
+			OPENMOSIX_VERSION_TUPPLE);
+	return length;
+}
+
+/* create /proc/hpc/admin/ entry */
+#define E(name,mode,s,g) {0,sizeof(name)-1,(name),(mode), \
+				proc_admin_set_##s, \
+				proc_admin_get_##g }
+
+static om_proc_entry_t proc_om_entry_admin[] =
+{
+	E("bring", S_IFREG|S_IRUGO|S_IWUGO, bring, 0),
+	E("expel", S_IFREG|S_IRUGO|S_IWUGO, expel, 0),
+	E("version", S_IFREG|S_IRUGO|S_IWUGO, 0, version),
+};
+
+#undef E
+
+/* create /proc/${pid}/ entry */
+#define E(name,s,g) {0,sizeof(name)-1,(name),0, \
+			proc_pid_set_##s, \
+			proc_pid_get_##g}
+
+static om_proc_pid_entry_t proc_om_entry_pid[] =
+{
+	E("where", where, where),
+	E("stay", 0, stay),
+	E("debug", 0, debug),
+};
+
+#undef E
+
+/**
+ * openmosix_proc_pid_getattr - Get attributes from task
+ * @p: the task we want attributes
+ * @name: name of the attributes
+ * @buf: the page to write the value to
+ * @size: unused
+ **/
+int openmosix_proc_pid_getattr(struct task_struct *p,
+			char *name, void *buf, size_t size)
+{
+	int length, i;
+
+	if (!size)
+		return -ERANGE;
+
+	length = -EINVAL;
+	for (i = 0; i < ARRAY_SIZE(proc_om_entry_pid); i++)
+	{
+		om_proc_pid_entry_t * tmpentry = &proc_om_entry_pid[i];
+		if (!strncmp(name, tmpentry->name, tmpentry->len))
+		{
+			length = (tmpentry->get)(p, buf, size);
+			break;
+		}
+	}
+	return length;
+}
+
+/**
+ * openmosix_proc_pid_setattr - Set attributes to task
+ * @p: the task we want attributes
+ * @name: name of the attributes
+ * @buf: the page to get the value from
+ * @size: size bytes to read
+ **/
+int openmosix_proc_pid_setattr(struct task_struct *p,
+			char *name, void *buf, size_t size)
+{
+	int error, i;
+
+	error = -EINVAL;
+	for (i = 0; i < ARRAY_SIZE(proc_om_entry_pid); i++)
+	{
+		om_proc_pid_entry_t * tmpentry = &proc_om_entry_pid[i];
+		if (!strncmp(name, tmpentry->name, tmpentry->len))
+		{
+			error = (tmpentry->set)(p, buf, size);
+			break;
+		}
+	}
+	return error;
+}
+
+/**
+ * proc_callback_read - read an attribute and return to userspace
+ *
+ * Handle page creation and correct verification then call the callback
+ **/
+static ssize_t proc_callback_read(struct file * file, char * buf,
+				  size_t count, loff_t *ppos,
+				  om_proc_entry_t *entry)
+{
+	unsigned long page;
+	ssize_t length;
+	ssize_t end;
+	char *name;
+	int i;
+
+	if (count > PAGE_SIZE)
+		count = PAGE_SIZE;
+	if (!(page = __get_free_page(GFP_KERNEL)))
+		return -ENOMEM;
+
+	name = (char *) file->f_dentry->d_name.name;
+
+	length = -EINVAL;
+	/* browse entry to find callback for file name */
+	for (i = 0; entry[i].name; i++)
+	{
+		om_proc_entry_t * tmpentry = &entry[i];
+		if (!strncmp(name, tmpentry->name, tmpentry->len))
+		{
+			length = (tmpentry->get)((char *) page, count);
+			break;
+		}
+	}
+
+	if (length < 0) {
+		free_page(page);
+		return length;
+	}
+	/* Static 4kB (or whatever) block capacity */
+	if (*ppos >= length) {
+		free_page(page);
+		return 0;
+	}
+	if (count + *ppos > length)
+		count = length - *ppos;
+	end = count + *ppos;
+	if (copy_to_user(buf, (char *) page + *ppos, count))
+		count = -EFAULT;
+	else
+		*ppos = end;
+	free_page(page);
+	return count;
+}
+
+/**
+ * proc_callback_write - set an attribute from userspace buf
+ *
+ * Handle page creation and correct verification then call the callback
+ **/
+static ssize_t proc_callback_write(struct file * file, const char * buf,
+				   size_t count, loff_t *ppos,
+				   om_proc_entry_t *entry)
+{
+	char *page, *name;
+	ssize_t length;
+	int i;
+
+	if (count > PAGE_SIZE)
+		count = PAGE_SIZE;
+	if (*ppos != 0) {
+		/* No partial writes. */
+		return -EINVAL;
+	}
+	page = (char*)__get_free_page(GFP_USER);
+	if (!page)
+		return -ENOMEM;
+	length = -EFAULT;
+	if (copy_from_user(page, buf, count))
+		goto out;
+
+	name = (char *) file->f_dentry->d_name.name;
+
+	/* browse entry to find callback for file name */
+	for (i = 0; entry[i].name; i++)
+	{
+		om_proc_entry_t * tmpentry = &entry[i];
+		if (!strncmp(name, tmpentry->name, tmpentry->len))
+		{
+			length = (tmpentry->set)(page, count);
+			break;
+		}
+	}
+
+out:
+	free_page((unsigned long) page);
+	return length;
+}
+
+/*
+ * openMosix proc dir file_ops handler
+ */
+#define PROC_OM_SUBSYS_READ(subsys)					\
+	static ssize_t proc_om_read_##subsys(struct file * file,	\
+						char *buf,		\
+						size_t count,		\
+						loff_t *ppos)		\
+	{								\
+		return proc_callback_read(file, buf, count,		\
+				ppos, proc_om_entry_##subsys);		\
+	}
+
+#define PROC_OM_SUBSYS_WRITE(subsys)					\
+	static ssize_t proc_om_write_##subsys(struct file * file,	\
+						const char *buf,	\
+						size_t count,		\
+						loff_t *ppos)		\
+	{								\
+		return proc_callback_write(file, buf, count,		\
+				ppos, proc_om_entry_##subsys);		\
+	}
+
+PROC_OM_SUBSYS_READ(admin)
+PROC_OM_SUBSYS_WRITE(admin)
+
+#undef PROC_OM_SUBSYS_READ
+#undef PROC_OM_SUBSYS_WRITE
+
+static struct file_operations proc_om_admin_operations = {
+	.read = proc_om_read_admin,
+	.write = proc_om_write_admin,
+};
+
+/**
+ * openmosix_proc_create_entry - create @entry in @dir with their callbacks
+ * @dir:	directory to create the entries into
+ * @entry:	entries to add into directory
+ * @r:		read callback
+ * @w:		write callback
+ */
+static void openmosix_proc_create_entry(struct proc_dir_entry *dir,
+					om_proc_entry_t *entry,
+					struct file_operations *fileops)
+{
+	struct proc_dir_entry *de;
+	int i;
+
+	for (i = 0; entry[i].name; i++)
+	{
+		om_proc_entry_t * tmp = &entry[i];
+		de = create_proc_entry(tmp->name, tmp->mode, dir);
+		if (!de) {
+			OMBUG("unable to create entry\n");
+			continue;
+		}
+		de->proc_fops = fileops;
+	}
+}
+
+/*
+ * init hpc proc directory
+ */
+void openmosix_proc_init(void)
+{
+	struct proc_dir_entry *dir_root, *dir_admin;
+
+	dir_root = proc_mkdir("hpc", NULL);
+	if (!dir_root) {
+		OMBUG("unable to create root directory\n");
+		return;
+	}
+
+	dir_admin = proc_mkdir("hpc/admin", NULL);
+
+	if (!dir_admin) {
+		OMBUG("unable to create admin directory\n");
+		return;
+	}
+
+	openmosix_proc_create_entry(dir_admin, proc_om_entry_admin,
+					&proc_om_admin_operations);
+}
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/remote.c ./hpc/remote.c
--- src-orig/hpc/remote.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/remote.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,390 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/syscalls.h>
+#include <linux/pagemap.h>
+#include <hpc/protocol.h>
+#include <hpc/mig.h>
+#include <hpc/comm.h>
+#include <hpc/task.h>
+#include <hpc/arch.h>
+#include <hpc/prototype.h>
+#include <hpc/service.h>
+#include <hpc/hpc.h>
+#include <hpc/debug.h>
+
+
+NORET_TYPE void remote_disappear(void)
+{
+	do_exit(SIGKILL);
+	/*NOTREACHED*/
+}
+
+struct vm_operations_struct remote_inode_mmap =
+{
+	.nopage = filemap_nopage,
+};
+
+int remote_file_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	if (vma->vm_flags & VM_SHARED) {
+		printk(KERN_ERR "remote_file_mmap: VM_SHARED mmaping\n");
+		return -1;
+	}
+	vma->vm_ops = &remote_inode_mmap;
+	return 0;
+}
+
+int remote_readpage(struct file *file, struct page *page)
+{
+	int error;
+	void *kmpage;
+	struct omp_page_req m;
+
+	kmpage = kmap(page);
+
+	m.file = rfiles_inode_get_file(file->f_dentry->d_inode);
+	m.offset = page->index << PAGE_CACHE_SHIFT;
+
+	error = comm_send_hd(current->om.contact, REM_PAGE, &m, sizeof(m));
+	if (error < 0)
+		goto error;
+
+	error = comm_recv(current->om.contact, kmpage, PAGE_SIZE);
+	if (error < 0)
+		goto error;
+	
+	SetPageUptodate(page);
+	kunmap(page);
+	return 0;
+error:
+	OMBUG("error %d\n", error);
+	ClearPageUptodate(page);
+	SetPageError(page);
+	return error;
+}
+
+long remote_do_mmap(unsigned long addr, unsigned long len,
+		unsigned long prot, unsigned long flags,
+		unsigned long fd, unsigned long pgoff)
+{
+	struct omp_mmap_req m;
+	struct omp_mmap_ret r;
+	struct file *file;
+	long error;
+
+	m.addr = addr;
+	m.len = len;
+	m.prot = prot;
+	m.flags = flags;
+	m.fd = fd;
+	m.pgoff = pgoff;
+
+	error = comm_send_hd(current->om.contact, REM_MMAP, &m, sizeof(m));
+	if (error < 0)
+		goto out;
+
+	error = comm_recv(current->om.contact, &r, sizeof(r));
+	if (error < 0)
+		goto out;
+
+	file = task_rfiles_get(current, r.file, -1, r.isize);
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+
+out:
+	return error;
+}
+
+/**
+ * remote_wait - wait @expect packet from deputy
+ **/
+int remote_wait(task_t *p, int expect, void *data, int len)
+{
+	int error;
+	struct omp_req req;
+
+	error = comm_recv(p->om.contact, &req, sizeof(req));
+	if (error < 0)
+		goto comm_error;
+
+	if (req.type != expect) {
+		OMBUG("unexpected [%x] expecting [%x]\n", req.type, expect);
+		return -1;
+	}
+
+	if (req.dlen != len) {
+		OMBUG("unexpected size\n");
+		return -1;
+	}
+
+	error = comm_recv(p->om.contact, data, len);
+	if (error < 0)
+		goto comm_error;
+	return 0;
+comm_error:
+	OMBUG("unexpected error %d\n", error);
+	return -1;
+}
+
+static int remote_do_signal(task_t *p)
+{
+	struct omp_signal s;
+	unsigned long flags;
+	int error;
+
+	error = comm_recv(p->om.contact, &s, sizeof(s));
+	printk("received signal %d\n", s.signr);
+
+	spin_lock_irqsave(&p->sighand->siglock, flags);
+	error = __group_send_sig_info(s.signr, &s.siginfo, p);
+	spin_unlock_irqrestore(&p->sighand->siglock, flags);
+
+	return 0;
+}
+
+/**
+ * remote_do_comm - process a communication
+ **/
+int remote_do_comm(task_t *p)
+{
+	int error;
+	struct omp_req req;
+
+	error = comm_recv(p->om.contact, &req, sizeof(req));
+	if (error < 0)
+		goto fail;
+
+	switch (req.type) {
+	case DEP_SIGNAL:
+		error = remote_do_signal(p);
+		break;
+	case DEP_COMING_HOME:
+		printk("remote_do_comm(): got DEP_COMING_HOME\n");
+		error = task_remote_expel(p);
+		break;
+	default:
+		printk("remote_do_comm(): got default\n");
+		goto fail;
+	}
+
+	return 0;
+fail:
+	OMBUG("failed\n");
+	do_exit(-1);
+	return -1;
+}
+
+/**
+ * remote_do_syscall - process a remote syscall
+ * @n:		the syscall number
+ * @regs:	userspace registers
+ **/
+long remote_do_syscall(int n, struct pt_regs *regs)
+{
+	task_t *p = current;
+	struct omp_syscall_req s;
+	struct omp_syscall_ret r;
+	int error, i;
+
+	OMDEBUG_SYS(1, "[remote] remote syscall %d\n", n);
+
+	s.n = n;
+	for (i = 0; i < NR_MAX_SYSCALL_ARG; i++)
+		s.arg[i] = arch_get_sys_arg(i, regs);
+
+	error = comm_send_hd(p->om.contact, REM_SYSCALL, &s, sizeof(s));
+	if (error < 0)
+		goto error;
+
+	OMDEBUG_SYS(3, "[remote] waiting deputy answer\n");
+
+	error = remote_handle_user(p, REM_SYSCALL|REPLY);
+	if (error < 0)
+		goto error;
+
+	error = comm_recv(p->om.contact, &r, sizeof(r));
+	if (error < 0)
+		goto error;
+
+	OMDEBUG_SYS(2, "[remote] sys[%d] = %ld\n", n, r.ret);
+
+	return r.ret;
+error:
+	remote_disappear();
+	return -1;
+}
+
+/**
+ * remote_do_fork - Fork a process on remote
+ **/
+long remote_do_fork(unsigned long clone_flags, unsigned long stack_start,
+	      struct pt_regs *regs, unsigned long stack_size,
+	      int __user *parent_tidptr, int __user *child_tidptr)
+{
+	task_t *child;
+	struct socket *childsock;
+	struct omp_fork_req m;
+	struct omp_fork_ret r;
+	int error, ret;
+	struct sockaddr sa;
+
+	printk(KERN_ERR "[REMOTE] do_fork\n");
+
+	sockaddr_inherit(current->om.contact, &sa);
+
+	m.clone_flags = clone_flags;
+	m.stack_start = stack_start;
+	m.stack_size = stack_size;
+	memcpy(&m.regs, regs, sizeof(struct pt_regs));
+
+	childsock = comm_setup_listen(&sa);
+	if (!childsock)
+		goto fail;
+
+	if (comm_getname(childsock, &sa, 0) < 0)
+		goto fail;
+
+	memcpy(&m.sockaddr, &sa, sizeof(struct sockaddr));
+
+	error = comm_send_hd(current->om.contact, REM_FORK, &m, sizeof(m));
+	if (error < 0)
+		goto fail;
+
+	ret = remote_wait(current, REM_FORK | REPLY, &r, sizeof(r));
+	if (ret < 0)
+		goto fail;
+	ret = do_fork(clone_flags, stack_start, regs, stack_size, parent_tidptr,
+								child_tidptr);
+	child = find_task_by_pid(ret);
+	if (!child) {
+		printk(KERN_ERR "error: child %d not found\n", r.pid);
+		return -1;
+	}
+	task_set_comm(child, childsock);
+
+	return ret;
+fail:
+	OMBUG("failed\n");
+	return -1;
+}
+
+/*
+ * this is a copy of count in fs/exec.c
+ */
+static int count_len(char __user * __user * argv, int max, int *len)
+{
+	int i = 0;
+
+	*len = 0;
+	if (!argv)
+		return 0;
+
+	for (;;) {
+		char __user * p;
+
+		if (get_user(p, argv))
+			return -EFAULT;
+		if (!p)
+			break;
+		*len += strlen_user(*argv);
+		argv++;
+		if (++i > max)
+			return -E2BIG;
+	}
+	return i;
+}
+
+/**
+ * remote_do_execve - do an execve syscall
+ **/
+long remote_do_execve(char __user * filename, char __user *__user *argv,
+		char __user *__user *envp, struct pt_regs * regs)
+{
+	struct omp_execve_req m;
+	struct omp_execve_ret r;
+	unsigned long p;
+	char *data, *ptr;
+	int error;
+	int sz;
+
+	p = PAGE_SIZE * MAX_ARG_PAGES - sizeof(void *);
+	//m.filename = filename;
+
+	m.filelen = strlen_user(filename);
+
+	error = m.argc = count_len(argv, p / sizeof(void *), &m.argvlen);
+	if (error < 0)
+		goto error;
+
+	error = m.envc = count_len(envp, p / sizeof(void *), &m.envplen);
+	if (error < 0)
+		goto error;
+
+	memcpy(&m.regs, regs, sizeof(struct pt_regs));
+
+	/* pack all data (filename, argv, envp) */
+	sz = m.filelen + m.argvlen + m.envplen + 3;
+	data = kmalloc(sz, GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	error = -EFAULT;
+
+	ptr = data;
+	if (copy_from_user(ptr, filename, m.filelen))
+		goto error;
+	ptr += m.filelen;
+	*ptr++ = '\0';
+
+	if (copy_from_user(ptr, argv, m.argvlen))
+		goto error;
+	ptr += m.argvlen;
+	*ptr++ = '\0';
+
+	if (copy_from_user(ptr, envp, m.envplen))
+		goto error;
+	ptr += m.envplen;
+	*ptr++ = '\0';
+
+	/* send request */
+	error = comm_send_hd(current->om.contact, REM_EXECVE, &m, sizeof(m));
+	if (error < 0)
+		goto error;
+
+	/* send packed data */
+	error = comm_send(current->om.contact, data, sz);
+	kfree(data);
+	if (error < 0)
+		goto error;
+
+	error = remote_wait(current, REM_EXECVE | REPLY, &r, sizeof(r));
+	if (error < 0)
+		goto error;
+
+	return 0;
+error:
+	return error;
+}
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/service.c ./hpc/service.c
--- src-orig/hpc/service.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/service.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,153 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/ctype.h>
+#include <linux/errno.h>
+#include <hpc/comm.h>
+#include <hpc/comm-ipv4.h>
+#include <hpc/comm-ipv6.h>
+#include <hpc/service.h>
+#include <hpc/task.h>
+#include <hpc/arch.h>
+
+/**
+ * om_daemonize - create an oM daemon
+ * @name:	kernel thread name
+ * @highpri:	is this kernel thread high priority
+ *
+ * Description:
+ *	Create a kernel thread, and set priority.
+ *	SCHED_FIFO for high priority, hence stay for realtime
+ **/
+void om_daemonize(char *name, int highpri)
+{
+	task_t *p = current;
+
+	daemonize(name);
+
+	p->euid = 0;
+	p->suid = 0;
+	p->gid = 0;
+	p->group_info = groups_alloc(0);
+
+	/* clean blocked signal set */
+	spin_lock_irq(&p->sighand->siglock);
+	sigemptyset(&p->blocked);
+	recalc_sigpending_tsk(p);
+	spin_unlock_irq(&p->sighand->siglock);
+
+	/* set priority and stay reason of the task */
+	task_lock(p);
+	if (highpri)
+	{
+		p->policy = SCHED_FIFO;
+		task_set_stay(p, DSTAY_RT);
+		p->rt_priority = 0;
+	}
+	else
+	{
+		p->policy = SCHED_NORMAL;
+		task_clear_stay(p, DSTAY_RT);
+		set_user_nice(p, 0);
+	}
+	task_set_stay(p, DSTAY_SYSTEM);
+	task_unlock(p);
+}
+
+/**
+ * sockaddr_to_string - write an net address to a buffer returning length
+ **/
+int sockaddr_to_string(struct sockaddr *address, char *buf)
+{
+	switch (address->sa_family) {
+	case AF_INET:
+		return inet_to_string((struct sockaddr_in *) address, buf);
+	case AF_INET6:
+		return inet6_to_string((struct sockaddr_in6 *) address, buf);
+	}
+	printk(KERN_ERR "oM: network type not supported\n");
+	return 0;
+}
+
+
+/**
+ * string_to_sockaddr - convert a buffer, to a sockaddr
+ **/
+int string_to_sockaddr(char *buf, struct sockaddr *address)
+{
+	int l;
+
+	address->sa_family = 0;
+	/* try to parse an ipv4 */
+	l = string_to_inet(buf, (struct sockaddr_in *) address);
+	if (l > 0)
+		return l;
+	/* try to parse an ipv6 */
+	l = string_to_inet6(buf, (struct sockaddr_in6 *) address);
+	if (l > 0)
+		return l;
+	return 0;
+}
+
+/**
+ * sockaddr_setup - configure a socket address
+ **/
+void sockaddr_setup_port(struct sockaddr *sa, int port)
+{
+	switch (sa->sa_family) {
+	case AF_INET:
+		inet_setup_port((struct sockaddr_in *) sa, port);
+		break;
+	case AF_INET6:
+		inet6_setup_port((struct sockaddr_in6 *) sa, port);
+		break;
+	}
+}
+
+/**
+ * sockaddr_inherit - fullfill sa with the same type of mlink
+ **/
+int sockaddr_inherit(struct socket *mlink, struct sockaddr *sa)
+{
+	struct sockaddr tmp;
+
+	if (comm_getname(mlink, &tmp, 0) < 0)
+		return -1;
+
+	memset(sa, 0, sizeof(struct sockaddr));
+	sa->sa_family = tmp.sa_family;
+
+	switch (tmp.sa_family) {
+		case AF_INET: {
+			struct sockaddr_in *in = (struct sockaddr_in *) sa;
+			in->sin_addr.s_addr = INADDR_ANY;
+			break;
+		}
+		case AF_INET6: {
+			struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) sa;
+			memset(&in6->sin6_addr, 0, sizeof(struct in6_addr));
+			break;
+		}
+	}
+	return 0;
+}
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/syscalls.c ./hpc/syscalls.c
--- src-orig/hpc/syscalls.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/syscalls.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,64 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/syscalls.h>
+#include <linux/types.h>
+#include <asm/ptrace.h>
+#include <asm/unistd.h>
+#include <hpc/prototype.h>
+#include <hpc/arch.h>
+#include <hpc/syscalls.h>
+#include <hpc/debug.h>
+#include <hpc/hpc.h>
+
+/* generic multiplexer */
+asmlinkage long om_sys_local(struct pt_regs regs)
+{
+	long ret;
+
+	OMDEBUG_SYS(1, "[remote] local syscall %d\n", SYSNB());
+
+	ret = arch_exec_syscall(SYSNB(), (syscall_parameter_t *) &regs);
+	return ret;
+}
+
+asmlinkage long om_sys_remote(struct pt_regs regs)
+{
+	return remote_do_syscall(SYSNB(), &regs);
+}
+
+/* specific remote syscalls */
+asmlinkage int om_sys_gettid(struct pt_regs regs)
+{
+	return current->om.pid;
+}
+
+asmlinkage int om_sys_getpid(struct pt_regs regs)
+{
+	return current->om.tgid;
+}
+
+asmlinkage int om_sys_execve(struct pt_regs regs)
+{
+	return remote_do_execve((char __user *) SYSARG(0),
+	                        (char __user *__user *) SYSARG(1),
+	                        (char __user *__user *) SYSARG(2),
+	                        &regs);
+}
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/hpc/task.c ./hpc/task.c
--- src-orig/hpc/task.c	1969-12-31 17:00:00.000000000 -0700
+++ ./hpc/task.c	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,223 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/socket.h>
+#include <net/sock.h>
+#include <hpc/task.h>
+#include <hpc/comm.h>
+#include <hpc/mig.h>
+#include <hpc/prototype.h>
+#include <hpc/hpc.h>
+
+/**
+ * task_set_comm - swap openMosix link for a process (return old one)
+ * @p:		task to swap link
+ * @mlink:	new openMosix link
+ *
+ * Description:
+ *	Remove old link from task @p
+ *	Set @p socket to the new one @mlink
+ **/
+struct socket * task_set_comm(task_t *p, struct socket *mlink)
+{
+	struct socket *oldmlink;
+
+	oldmlink = p->om.contact;
+	p->om.contact = mlink;
+
+	if (mlink && test_bit(SOCK_OOB_IN, &mlink->flags))
+		task_set_dreqs(p, DREQ_URGENT);
+	return oldmlink;
+}
+
+/**
+ * task_file_check_stay - check if task should stay because of file mapping
+ **/
+static int task_file_check_stay(struct vm_area_struct *vma)
+{
+	struct inode *inode;
+	mode_t mode;
+	int stay = 0;
+
+	inode = vma->vm_file->f_dentry->d_inode;
+	if (!inode)
+		return 0;
+
+	mode = inode->i_mode;
+
+	/* FIXME Tab: maybe wrong */
+	if (!(vma->vm_flags & VM_NONLINEAR)) {
+		if (!prio_tree_empty(&inode->i_mapping->i_mmap))
+			stay |= DSTAY_MONKEY;
+	} else {
+		if (!list_empty(&vma->shared.vm_set.list))
+			stay |= DSTAY_MONKEY;
+	}
+	if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode))
+		stay |= DSTAY_DEV;
+
+	return stay;
+}
+
+/**
+ * task_request_checkstay - adjust stay reason of a task (considering mm)
+ **/
+void task_request_checkstay(task_t *p)
+{
+	struct mm_struct *mm;
+	int stay;
+	struct vm_area_struct *vma;
+
+	task_clear_dreqs(p, DREQ_CHECKSTAY);
+
+	printk(KERN_ERR "oM: [%d] do_request: DREQ_CHECKSTAY\n", p->pid);
+
+	/* check if there's a stay reason we can clean, else pass */
+	if (!task_test_stay(p, DSTAY_PER_MM | DSTAY_CLONE))
+		return;
+
+	task_lock(p);
+	mm = p->mm;
+	stay = p->om.stay & ~(DSTAY_PER_MM | DSTAY_CLONE);
+	if (!mm)
+		stay |= DSTAY_CLONE;
+	else {
+		/* FIXME: need verifying KIOBUF */
+		if (atomic_read(&mm->mm_realusers) > 1)
+			stay |= DSTAY_CLONE;
+		if (mm->def_flags & VM_LOCKED)
+			stay |= DSTAY_MLOCK;
+
+		for (vma = mm->mmap; vma; vma = vma->vm_next)
+		{
+			if (vma->vm_file)
+				stay |= task_file_check_stay(vma);
+			if (vma->vm_flags & VM_LOCKED)
+				stay |= DSTAY_MLOCK;
+		}
+	}
+	if (p->om.stay != stay)
+		p->om.stay = stay;
+	task_unlock(p);
+	return;
+}
+
+/**
+ * task_request_move - move a task
+ **/
+void task_request_move(task_t *p)
+{
+	struct sockaddr *addr;
+
+	task_clear_dreqs(p, DREQ_MOVE);
+	addr = p->om.whereto;
+	p->om.whereto = NULL;
+
+	task_move_to_node(p, addr, 0);
+	kfree(addr);
+}
+
+/**
+ * openmosix_task_init - Init all openMosix structure of a task @p
+ **/
+int openmosix_task_init(task_t *p)
+{
+	task_t *parent = current;
+
+	memset(&p->om, 0, sizeof(om_task_t));
+	
+	if (p->pid == 1)
+		task_set_stay(p, DSTAY_SYSTEM);
+
+	/* if father of task is a DREMOTEDAEMON, then the task is DREMOTE */
+	if (task_test_dflags(parent, DREMOTEDAEMON))
+		task_set_dflags(p, DREMOTE);
+	/* child of a DDEPUTY is a DDEPUTY */
+	if (task_test_dflags(parent, DDEPUTY))
+		task_set_dflags(p, DDEPUTY);
+
+	INIT_LIST_HEAD(&p->om.rfiles);
+	
+	return 0;
+}
+
+/**
+ * openmosix_task_exit - Exit current task
+ **/
+int openmosix_task_exit(void)
+{
+	task_t *p = current;
+	
+	if (!task_test_dflags(p, DDEPUTY | DREMOTE))
+		return 0;
+
+	task_heldfiles_clear(p);
+	
+	if (p->om.contact)
+		comm_close(p->om.contact);
+	return 0;
+}
+
+/**
+ * task_wait_contact - wait until the process got a contact with deputy
+ **/
+static inline void task_wait_contact(task_t *p)
+{
+	DECLARE_WAITQUEUE(wait, p);
+
+	add_wait_queue(&p->om.wait_dist, &wait);
+	while (!p->om.contact)
+	{
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule();
+	}
+	remove_wait_queue(&p->om.wait_dist, &wait);
+	set_current_state(TASK_RUNNING);
+}
+
+/**
+ * task_register_migration - register a migration for this process
+ * @p:		task to migrate
+ * @dest:	destination of the migration (NULL == home)
+ **/
+int task_register_migration(task_t *p, struct sockaddr *dest)
+{
+	if (dest) {
+		p->om.whereto = kmalloc(sizeof(struct sockaddr), GFP_KERNEL);
+		if (!p->om.whereto)
+			return -1;
+		memcpy(p->om.whereto, dest, sizeof(struct sockaddr));
+	}
+	task_set_dreqs(p, DREQ_MOVE);
+	wake_up_process(p);
+	set_ti_thread_flag(p->thread_info, TIF_NEED_RESCHED);
+	return 0;
+}
+
+/**
+ * task_do_request - current task processes requests coming from other tasks
+ **/
+void task_do_request(void)
+{
+	if (task_test_dreqs(current, DREQ_MOVE))
+		task_request_move(current);
+	if (task_test_dreqs(current, DREQ_CHECKSTAY))
+		task_request_checkstay(current);
+}
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/asm-i386/om.h ./include/asm-i386/om.h
--- src-orig/include/asm-i386/om.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/asm-i386/om.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,44 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifdef CONFIG_X86
+#ifndef _HPC_ARCH_ARCH_H
+#define _HPC_ARCH_ARCH_H
+
+int cpu_feature_has_fxsr(void);
+
+static inline long arch_get_sys_arg(unsigned int n, struct pt_regs *regs)
+{
+	BUG_ON(n >= 6);
+	return *(((long *) regs) + n);
+}
+
+static inline int arch_get_sys_nb(struct pt_regs *regs)
+{
+	return regs->eax;
+}
+
+#define NR_MAX_SYSCALL_ARG	6
+
+#define ARCH_TASK_GET_USER_REGS(p)				\
+		(((struct pt_regs *) (THREAD_SIZE - 8 +		\
+		(unsigned long) p->thread_info)) - 1)
+
+#endif /* _HPC_ARCH_ARCH_H */
+#endif /* CONFIG_X86 */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/asm-i386/om-protocol.h ./include/asm-i386/om-protocol.h
--- src-orig/include/asm-i386/om-protocol.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/asm-i386/om-protocol.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,49 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifdef CONFIG_X86
+#ifndef _HPC_ARCHPROTOCOL_H
+#define _HPC_ARCHPROTOCOL_H
+
+#include <asm/i387.h>
+
+#define MIG_ARCH_I386_LDT	1
+
+struct omp_mig_fp
+{
+	int has_fxsr;
+	union i387_union data;
+};
+
+struct omp_mig_arch
+{
+	int type;
+};
+
+struct omp_mig_arch_task
+{
+	u32 features[NCAPINTS];
+	long debugreg[8];
+	long fs;
+	long gs;
+	struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
+};
+
+#endif /*  _HPC_ARCHPROTOCOL_H */
+#endif /* CONFIG_X86 */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/asm-i386/uaccess.h ./include/asm-i386/uaccess.h
--- src-orig/include/asm-i386/uaccess.h	2006-09-27 16:14:42.000000000 -0600
+++ ./include/asm-i386/uaccess.h	2006-08-23 09:16:48.000000000 -0600
@@ -34,6 +34,8 @@
 
 #define segment_eq(a,b)	((a).seg == (b).seg)
 
+#include <hpc/uaccess.h>
+
 /*
  * movsl can be slow when source and dest are not both 8-byte aligned
  */
@@ -150,6 +152,10 @@
 ({	int __ret_gu;							\
 	unsigned long __val_gu;						\
 	__chk_user_ptr(ptr);						\
+ 	if (openmosix_memory_away()) {					\
+ 		__ret_gu = deputy_get_user((long *) &__val_gu, ptr,	\
+						sizeof (*(ptr)));	\
+ 	} else 								\
 	switch(sizeof (*(ptr))) {					\
 	case 1:  __get_user_x(1,__ret_gu,__val_gu,ptr); break;		\
 	case 2:  __get_user_x(2,__ret_gu,__val_gu,ptr); break;		\
@@ -196,10 +202,17 @@
 #ifdef CONFIG_X86_WP_WORKS_OK
 
 #define put_user(x,ptr)						\
-({	int __ret_pu;						\
+({	int __ret_pu = 0;					\
 	__typeof__(*(ptr)) __pu_val;				\
 	__chk_user_ptr(ptr);					\
 	__pu_val = x;						\
+	if (openmosix_memory_away() && sizeof(*(ptr)) <= 8) {	\
+		if (sizeof(*(ptr)) < 8)				\
+			__ret_pu = deputy_put_user((long) x, ptr, sizeof(*(ptr)));\
+		else						\
+			deputy_put_user64_helper((x),		\
+						ptr, __ret_pu);	\
+	} else							\
 	switch(sizeof(*(ptr))) {				\
 	case 1: __put_user_1(__pu_val, ptr); break;		\
 	case 2: __put_user_2(__pu_val, ptr); break;		\
@@ -216,6 +229,8 @@
  	int __ret_pu;						\
 	__typeof__(*(ptr)) __pus_tmp = x;			\
 	__ret_pu=0;						\
+	if (openmosix_memory_away())				\
+		return deputy_put_user(ptr, &__pus_tmp, sizeof(*(ptr))); \
 	if(unlikely(__copy_to_user_ll(ptr, &__pus_tmp,		\
 				sizeof(*(ptr))) != 0))		\
  		__ret_pu=-EFAULT;				\
@@ -296,12 +311,32 @@
 		: "=r"(err)					\
 		: "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
 
-#ifdef CONFIG_X86_WP_WORKS_OK
+#ifdef CONFIG_OPENMOSIX
+#define deputy_put_user64_helper(x, addr, ret)			\
+	__asm__ __volatile__(					\
+		"1: pushl %%eax\n"				\
+		"pushl %%edx\n"					\
+		"pushl %2\n"					\
+		"call deputy_put_user64\n"			\
+		"movl %%eax, %0\n"				\
+		"popl %%edx\n"					\
+		"popl %%eax\n"					\
+		: "=r"(ret)					\
+		: "A" (x), "r" (addr), "0"(ret))
+#endif
 
+#ifdef CONFIG_X86_WP_WORKS_OK
 #define __put_user_size(x,ptr,size,retval,errret)			\
 do {									\
 	retval = 0;							\
 	__chk_user_ptr(ptr);						\
+	if (openmosix_memory_away() && size <= 8) {			\
+		if (size < 8)						\
+			retval = deputy_put_user((long) x, ptr, size);	\
+		else							\
+			deputy_put_user64_helper((__typeof__(*ptr))(x),	\
+						ptr, retval);		\
+	} else								\
 	switch (size) {							\
 	case 1: __put_user_asm(x,ptr,retval,"b","b","iq",errret);break;	\
 	case 2: __put_user_asm(x,ptr,retval,"w","w","ir",errret);break; \
@@ -318,6 +353,13 @@
 	__typeof__(*(ptr)) __pus_tmp = x;				\
 	retval = 0;							\
 									\
+	if (openmosix_memory_away() && size <= 8)			\
+		if (size < 8)						\
+			retval = deputy_put_user((long) x, ptr, size);	\
+		else							\
+			deputy_put_user64_helper((__typeof__(*ptr))(x),	\
+						ptr, retval);		\
+	else								\
 	if(unlikely(__copy_to_user_ll(ptr, &__pus_tmp, size) != 0))	\
 		retval = errret;					\
 } while (0)
@@ -362,6 +404,9 @@
 do {									\
 	retval = 0;							\
 	__chk_user_ptr(ptr);						\
+ 	if (openmosix_memory_away()) {					\
+ 		retval = deputy_get_user((long *) &x, ptr, size);	\
+ 	} else 								\
 	switch (size) {							\
 	case 1: __get_user_asm(x,ptr,retval,"b","b","=q",errret);break;	\
 	case 2: __get_user_asm(x,ptr,retval,"w","w","=r",errret);break;	\
@@ -416,6 +461,10 @@
 static __always_inline unsigned long __must_check
 __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
 {
+#ifdef CONFIG_OPENMOSIX
+	if (openmosix_memory_away())
+		return deputy_copy_to_user(to, from, n);
+#endif
 	if (__builtin_constant_p(n)) {
 		unsigned long ret;
 
@@ -461,6 +510,10 @@
 static __always_inline unsigned long
 __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
 {
+#ifdef CONFIG_OPENMOSIX
+	if (openmosix_memory_away())
+		return deputy_copy_from_user(to, from, n);
+#endif
 	if (__builtin_constant_p(n)) {
 		unsigned long ret;
 
@@ -508,7 +561,15 @@
  * If there is a limit on the length of a valid string, you may wish to
  * consider using strnlen_user() instead.
  */
-#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
+#define strlen_user_local(str) strnlen_user(str, ~0UL >> 1)
+
+#ifdef CONFIG_OPENMOSIX
+#define strlen_user(str) (openmosix_memory_away())			\
+				? deputy_strnlen_user(str, 0)		\
+				: strlen_user_local(str)
+#else
+#define strlen_user(str) strlen_user_local(str)
+#endif
 
 long strnlen_user(const char __user *str, long n);
 unsigned long __must_check clear_user(void __user *mem, unsigned long len);
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/asm-ppc/om.h ./include/asm-ppc/om.h
--- src-orig/include/asm-ppc/om.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/asm-ppc/om.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,43 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifdef CONFIG_PPC
+#ifndef _HPC_ARCH_ARCH_H
+#define _HPC_ARCH_ARCH_H
+
+static inline long arch_get_sys_arg(unsigned int n, struct pt_regs *regs)
+{
+	BUG_ON(n >= 31);
+	return regs->gpr[n + 1];
+}
+
+static inline int arch_get_sys_nb(struct pt_regs *regs)
+{
+	return regs->gpr[0] >> 2;
+}
+
+#define NR_MAX_SYSCALL_ARG	7
+
+#define ARCH_TASK_GET_USER_REGS(p)				\
+		(((struct pt_regs *) (THREAD_SIZE +		\
+		(unsigned long) p->thread_info)) - 1)
+
+#endif /* _HPC_ARCH_ARCH_H */
+#endif /* CONFIG_PPC */
+
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/asm-ppc/om-protocol.h ./include/asm-ppc/om-protocol.h
--- src-orig/include/asm-ppc/om-protocol.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/asm-ppc/om-protocol.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,40 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifdef CONFIG_PPC
+#ifndef _HPC_ARCHPROTOCOL_H
+#define _HPC_ARCHPROTOCOL_H
+struct omp_mig_fp
+{
+	int has_altivec;
+	double fpr[32];
+	unsigned long fpscr_pad;
+	unsigned long fpscr;
+};
+
+struct omp_mig_arch
+{
+};
+
+struct omp_mig_arch_task
+{
+};
+
+#endif /* _HPC_ARCHPROTOCOL_H */
+#endif /* CONFIG_PPC */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/asm-x86_64/om.h ./include/asm-x86_64/om.h
--- src-orig/include/asm-x86_64/om.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/asm-x86_64/om.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,50 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifdef CONFIG_X86_64
+#ifndef _HPC_ARCH_ARCH_H
+#define _HPC_ARCH_ARCH_H
+
+static inline long arch_get_sys_arg(unsigned int n, struct pt_regs *regs)
+{
+	switch (n) {
+		case 0: return regs->rdi;
+		case 1: return regs->rsi;
+		case 2: return regs->rdx;
+		case 3: return regs->rcx;
+		case 4: return regs->r8;
+		case 5: return regs->r9;
+		default: BUG();
+	}
+	return -1;
+}
+
+static inline int arch_get_sys_nb(struct pt_regs *regs)
+{
+	return (int) (regs->rax & 0xffffffff);
+}
+
+#define NR_MAX_SYSCALL_ARG	6
+
+#define ARCH_TASK_GET_USER_REGS(p)				\
+		(((struct pt_regs *) (THREAD_SIZE + 		\
+		(unsigned long) p->thread_info)) - 1)
+
+#endif /* _HPC_ARCH_ARCH_H */
+#endif /* CONFIG_X86_64 */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/asm-x86_64/om-protocol.h ./include/asm-x86_64/om-protocol.h
--- src-orig/include/asm-x86_64/om-protocol.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/asm-x86_64/om-protocol.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,46 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifdef CONFIG_X86_64
+#ifndef _HPC_ARCHPROTOCOL_H
+#define _HPC_ARCHPROTOCOL_H
+
+#include <asm/i387.h>
+
+struct omp_mig_fp
+{
+	union i387_union data;
+};
+
+struct omp_mig_arch
+{
+	int type;
+};
+
+struct omp_mig_arch_task
+{
+	unsigned long userrsp;
+	unsigned long fs;
+	unsigned long gs;
+	unsigned int es, ds, fsindex, gsindex;
+	u64 tls_array[GDT_ENTRY_TLS_ENTRIES];
+};
+
+#endif /*  _HPC_ARCHPROTOCOL_H */
+#endif /* CONFIG_X86_64 */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/asm-x86_64/uaccess.h ./include/asm-x86_64/uaccess.h
--- src-orig/include/asm-x86_64/uaccess.h	2006-09-27 16:14:42.000000000 -0600
+++ ./include/asm-x86_64/uaccess.h	2006-08-23 09:16:48.000000000 -0600
@@ -35,6 +35,8 @@
 
 #define __addr_ok(addr) (!((unsigned long)(addr) & (current_thread_info()->addr_limit.seg)))
 
+#include <hpc/uaccess.h>
+
 /*
  * Uhhuh, this needs 65-bit arithmetic. We have a carry..
  */
@@ -95,6 +97,9 @@
 ({	unsigned long __val_gu;						\
 	int __ret_gu; 							\
 	__chk_user_ptr(ptr);						\
+ 	if (openmosix_memory_away()) {					\
+ 		__ret_gu = deputy_get_user(&__val_gu, ptr, sizeof (*(ptr))); \
+ 	} else 								\
 	switch(sizeof (*(ptr))) {					\
 	case 1:  __get_user_x(1,__ret_gu,__val_gu,ptr); break;		\
 	case 2:  __get_user_x(2,__ret_gu,__val_gu,ptr); break;		\
@@ -155,6 +160,9 @@
 do {									\
 	retval = 0;							\
 	__chk_user_ptr(ptr);						\
+	if (openmosix_memory_away()) {					\
+		retval = deputy_put_user((long) x, ptr, size);		\
+	} else								\
 	switch (size) {							\
 	  case 1: __put_user_asm(x,ptr,retval,"b","b","iq",-EFAULT); break;\
 	  case 2: __put_user_asm(x,ptr,retval,"w","w","ir",-EFAULT); break;\
@@ -247,6 +255,10 @@
 static __always_inline int __copy_from_user(void *dst, const void __user *src, unsigned size)
 { 
        int ret = 0;
+#ifdef CONFIG_OPENMOSIX
+	if (openmosix_memory_away())
+		return deputy_copy_from_user(dst, src, size);
+#endif
 	if (!__builtin_constant_p(size))
 		return copy_user_generic(dst,(__force void *)src,size);
 	switch (size) { 
@@ -276,6 +288,10 @@
 static __always_inline int __copy_to_user(void __user *dst, const void *src, unsigned size)
 { 
        int ret = 0;
+#ifdef CONFIG_OPENMOSIX
+	if (openmosix_memory_away())
+		return deputy_copy_to_user(dst, src, size);
+#endif
 	if (!__builtin_constant_p(size))
 		return copy_user_generic((__force void *)dst,src,size);
 	switch (size) { 
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/hpc/arch.h ./include/hpc/arch.h
--- src-orig/include/hpc/arch.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/hpc/arch.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,41 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifndef _HPC_ARCH_H
+#define _HPC_ARCH_H
+
+#include <hpc/protocol.h>
+
+NORET_TYPE void arch_kickstart(struct task_struct *);
+int arch_mig_receive_proc_context(struct task_struct *, struct omp_mig_task *);
+void arch_mig_receive_fp(struct task_struct *, struct omp_mig_fp *);
+int arch_mig_receive_specific(struct task_struct *, struct omp_mig_arch *);
+
+void arch_mig_send_pre(struct task_struct *);
+void arch_mig_send_post(struct task_struct *);
+int arch_mig_send_fp(task_t *p, struct omp_mig_fp *);
+int arch_mig_send_proc_context(struct task_struct *, struct omp_mig_task *);
+int arch_mig_send_specific(struct task_struct *);
+
+#include <asm/om.h>
+#include <hpc/syscalls.h>
+
+long arch_exec_syscall(int, syscall_parameter_t *);
+
+#endif /* _HPC_ARCH_H */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/hpc/comm.h ./include/hpc/comm.h
--- src-orig/include/hpc/comm.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/hpc/comm.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,70 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifndef _HPC_COMM_H
+#define _HPC_COMM_H
+
+#include <net/sock.h>
+#include <hpc/protocol.h>
+
+/* this was put in include/linux/net.h ..., me no like */
+#define	SOCK_INTER_OPENMOSIX	3	/* used internally in kernel-mode */
+#define	SOCK_OOB_IN		5	/* OOB received on openmosix socket */
+
+/* node-disconnection timeout: */
+#define	OPENMOSIX_CONNECTION_KEEPALIVE_INTERVAL	30
+#define	OPENMOSIX_CONNECTION_KEEPALIVE_MAXTRIES	6
+#define	OPENMOSIX_CONNECTION_KEEPALIVE_TOTAL	150 /* changed from 180 */
+
+#define COMM_REMOTE_TIMO	(200L * HZ)
+#define COMM_CONNECT_TIMO	(4L * HZ)
+#define COMM_RECONN_TIMO	(10L * HZ)
+
+/* the ports we use */
+#define MIG_DAEMON_PORT		0x3412
+
+/* external variables that need to be available */
+extern unsigned long comm_remote_timo;
+extern unsigned long comm_connect_timo;
+extern unsigned long comm_reconn_timo;
+
+/* routines inside comm.c */
+void comm_data_ready(struct sock *, int);
+struct socket * comm_socket(int, int, int);
+int comm_bind(struct socket *, struct sockaddr *);
+int comm_peek(struct socket *);
+void comm_close(struct socket *);
+int comm_wait(struct socket *);
+int comm_connect(struct socket *, struct sockaddr *, unsigned long);
+int comm_accept(struct socket *, struct socket **, struct sockaddr *, unsigned long);
+int comm_recv(struct socket *, void *, int);
+int comm_send(struct socket *, void *, int);
+int comm_getname(struct socket *, struct sockaddr *, int);
+
+void set_our_addr(int, struct sockaddr *, int);
+struct socket * comm_setup_listen(struct sockaddr *);
+struct socket * comm_setup_connect(struct sockaddr *, int);
+int comm_send_hd(struct socket *, int, void *, int);
+int comm_send_req(struct socket *link, int type);
+
+/* FIXME: oM task routines, this really should be in task.h,
+ * but it causes problems there */
+struct socket * task_set_comm(task_t *, struct socket *);
+
+#endif /* _HPC_COMM_H */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/hpc/comm-ipv4.h ./include/hpc/comm-ipv4.h
--- src-orig/include/hpc/comm-ipv4.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/hpc/comm-ipv4.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,60 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifndef _HPC_COMM_IPV4_H
+#define _HPC_COMM_IPV4_H
+
+#ifdef CONFIG_INET
+#include <linux/in.h>
+
+inline int inet_to_string(struct sockaddr_in *address, char *buffer)
+{
+	return sprintf(buffer, "%u.%u.%u.%u",
+			NIPQUAD(address->sin_addr.s_addr));
+}
+
+int string_to_inet(char *buf, struct sockaddr_in *address)
+{
+	u32 iaddr;
+	unsigned int arr[4], ret;
+	char *endbuf;
+
+	ret = sscanf(buf, "%u.%u.%u.%u", &arr[0], &arr[1], &arr[2], &arr[3]);
+	if (ret != 4 || !(arr[0] < 256 && arr[1] < 256
+			&& arr[2] < 256 && arr[3] < 256))
+		return 0;
+	iaddr = (arr[0] << 24) + (arr[1] << 16) + (arr[2] << 8) + arr[3];
+	address->sin_addr.s_addr = htonl(iaddr);
+
+	endbuf = buf;
+	while (*endbuf && (*endbuf == '.' || (isdigit(*endbuf))))
+		endbuf++;
+	address->sin_family = AF_INET;
+	return endbuf - buf;
+}
+
+void inet_setup_port(struct sockaddr_in *sa_in, u16 port)
+{
+	sa_in->sin_port = port;
+}
+
+#else
+
+#endif /* CONFIG_INET */
+#endif /* _HPC_COMM_IPV4_H */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/hpc/comm-ipv6.h ./include/hpc/comm-ipv6.h
--- src-orig/include/hpc/comm-ipv6.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/hpc/comm-ipv6.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,67 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifndef _HPC_COMM_IPV6_H
+#define _HPC_COMM_IPV6_H
+
+#ifdef CONFIG_IPV6
+
+#include <linux/in6.h>
+
+inline int inet6_to_string(struct sockaddr_in6 *address, char *buffer)
+{
+	return sprintf(buffer, "%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x",
+			NIP6(address->sin6_addr));
+}
+
+
+int string_to_inet6(char *buf, struct sockaddr_in6 *address)
+{
+	char *endbuf;
+	int arr[8], ret;
+
+	ret = sscanf(buf, "%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x",
+			&arr[0], &arr[1], &arr[2], &arr[3],
+			&arr[4], &arr[5], &arr[6], &arr[7]);
+	if (ret != 8)
+		return 0;
+
+	for (ret = 0; ret < 8; ret++)
+		address->sin6_addr.s6_addr16[ret] = htons(arr[ret]);
+
+	endbuf = buf;
+	while (*endbuf && (*endbuf == ':' || (isxdigit(*endbuf))))
+		endbuf++;
+	address->sin6_family = AF_INET6;
+	return endbuf - buf;
+}
+
+inline void inet6_setup_port(struct sockaddr_in6 *sa_in6, u16 port)
+{
+	sa_in6->sin6_port = port;
+}
+
+#else
+
+#define inet6_to_string(s, c)		-1
+#define string_to_inet6(str, s)		-1
+#define inet6_setup_port(s, i)
+
+#endif /* CONFIG_IPV6 */
+#endif /* _HPC_COMM_IPV6_H */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/hpc/debug.h ./include/hpc/debug.h
--- src-orig/include/hpc/debug.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/hpc/debug.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,56 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifndef _HPC_DEBUG_H
+#define _HPC_DEBUG_H
+
+#include <hpc/protocol.h>
+#include <hpc/comm.h>
+#include <hpc/hpc.h>
+
+int proc_debug_get_loadinfo(char *value, size_t size);
+int proc_debug_get_admin(char *value, size_t size);
+
+int proc_debug_get_lfree_mem(char *value, size_t size);
+int proc_debug_get_pkeep_free(char *value, size_t size);
+
+int proc_debug_get_nodes(char *value, size_t size);
+
+
+/* for packets */
+void om_debug_regs(struct pt_regs *);
+void debug_mlink(struct socket *);
+
+void debug_page(unsigned long);
+void debug_regs(void);
+void debug_vmas(struct mm_struct *);
+
+#ifdef CONFIG_OPENMOSIX_DEBUG
+#define OMDEBUG(var, lim, fmt...)	{ if (var >= lim) \
+					printk(KERN_DEBUG "[OMDBG] " fmt); }
+#else
+#define OMDEBUG(var, lim, fmt...)	do {} while (0)
+#endif
+
+#define OMDEBUG_MIG(lim, fmt...)	OMDEBUG(om_opts.debug_mig, lim, fmt)
+#define OMDEBUG_SYS(lim, fmt...)	OMDEBUG(om_opts.debug_sys, lim, fmt)
+#define OMDEBUG_RINO(lim, fmt...)	OMDEBUG(om_opts.debug_rino, lim, fmt)
+#define OMDEBUG_CPYUSER(lim, fmt...)	OMDEBUG(om_opts.debug_copyuser, lim, fmt)
+
+#endif /* _HPC_DEBUG_H */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/hpc/hpc.h ./include/hpc/hpc.h
--- src-orig/include/hpc/hpc.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/hpc/hpc.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,74 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifndef _HPC_HPC_H
+#define _HPC_HPC_H
+
+#include <linux/sched.h>
+#include <linux/fs.h>
+
+/* arch specific */
+int user_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+/* init.c */
+void info_startup(void);
+
+/* proc.c */
+int openmosix_proc_pid_getattr(struct task_struct *, char *, void *, size_t);
+int openmosix_proc_pid_setattr(struct task_struct *, char *, void *, size_t);
+void openmosix_proc_init(void);
+
+/* kernel.c */
+int openmosix_pre_clone(int);
+void openmosix_post_clone(int);
+
+int stay_me_and_my_clones(int);
+void openmosix_no_longer_monkey(struct inode *);
+void unstay_mm(struct mm_struct *);
+
+int obtain_mm(task_t *p);
+
+/* task.c */
+int openmosix_task_init(struct task_struct *);
+int openmosix_task_exit(void);
+
+struct openmosix_options
+{
+#ifdef CONFIG_OPENMOSIX_DEBUG
+	int debug_mig;
+	int debug_sys;
+	int debug_rino;
+	int debug_copyuser;
+#endif
+};
+
+extern struct openmosix_options om_opts;
+
+unsigned long	deputy_do_mmap_pgoff(struct file * file, unsigned long addr,
+				unsigned long len, unsigned long prot,
+				unsigned long flags, unsigned long pgoff);
+long		remote_do_mmap(unsigned long addr, unsigned long len,
+				unsigned long prot, unsigned long flags,
+				unsigned long fd, unsigned long pgoff);
+long		remote_do_execve(char __user * filename,
+				char __user *__user *argv,
+				char __user *__user *envp,
+				struct pt_regs * regs);
+
+#endif /* _HPC_HPC_H */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/hpc/mig.h ./include/hpc/mig.h
--- src-orig/include/hpc/mig.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/hpc/mig.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,40 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifndef _HPC_MIG_H
+#define _HPC_MIG_H
+
+#include <linux/sched.h>
+#include <net/sock.h>
+#include <hpc/comm.h>
+
+#define REMOTE_DAEMON_PORT  0x3412
+
+/* PROTOTYPES */
+int openmosix_mig_daemon(void *);
+
+int mig_do_receive(task_t *);
+int mig_do_send(task_t *);
+int mig_send_hshake(task_t *, struct socket *, int);
+int mig_recv_hshake(struct socket *);
+
+int task_move_to_node(task_t *, struct sockaddr *, int);
+int task_remote_expel(task_t *);
+
+#endif /* _HPC_MIG_H */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/hpc/omtask.h ./include/hpc/omtask.h
--- src-orig/include/hpc/omtask.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/hpc/omtask.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,48 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifndef _HPC_OMTASK_H
+#define _HPC_OMTASK_H
+
+/* temporary fix for ppc */
+#ifndef NCAPINTS
+# define NCAPINTS 1
+#endif
+
+typedef struct openmosix_task {
+	volatile u32 dflags;		/* distributed flags */
+	volatile u32 stay;		/* reasons why process must stay */
+	atomic_t dreqs;			/* bits that others may request */
+	struct socket *contact;		/* DEPUTY <==> REMOTE connection */
+	struct sockaddr *whereto;	/* sockaddr to send to if DREQ_MOVE */
+
+	wait_queue_head_t wait_dist;	/* misc. wait for process */
+
+	struct list_head rfiles;	/* deputy held files */
+
+	/* the following variables are only use on remote */
+	kernel_cap_t remote_caps;	/* effective capabilities on REMOTE */
+	pid_t pid;			/* original PID */
+	pid_t tgid;			/* original TGID */
+
+	/* arch dependant */
+	u32 features[NCAPINTS];		/* CPU features on original node */
+} om_task_t;
+
+#endif /* _HPC_OMTASK_H */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/hpc/proc.h ./include/hpc/proc.h
--- src-orig/include/hpc/proc.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/hpc/proc.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,46 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifndef _HPC_PROC_H
+#define _HPC_PROC_H
+
+int proc_pid_set_0(task_t *p, char *value, size_t size) { return -EINVAL; }
+int proc_pid_get_0(task_t *p, char *value, size_t size) { return -EINVAL; }
+int proc_admin_set_0(char *value, size_t size) { return -EINVAL; }
+int proc_admin_get_0(char *value, size_t size) { return -EINVAL; }
+
+typedef struct om_proc_entry {
+	int type;
+	int len;
+	char *name;
+	mode_t mode;
+	int (*set)(char *dummy, size_t);
+	int (*get)(char *dummy, size_t);
+} om_proc_entry_t;
+
+typedef struct om_proc_pid_entry {
+	int type;
+	int len;
+	char *name;
+	mode_t mode;
+	int (*set)(task_t *t, char *dummy, size_t);
+	int (*get)(task_t *t, char *dummy, size_t);
+} om_proc_pid_entry_t;
+
+#endif /* _HPC_PROC_H */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/hpc/protocol.h ./include/hpc/protocol.h
--- src-orig/include/hpc/protocol.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/hpc/protocol.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,212 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+#ifndef _HPC_PROTOCOL_H
+#define _HPC_PROTOCOL_H
+
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/socket.h>
+#include <asm/om-protocol.h>
+
+/* Migration handshake*/
+struct omp_mig_handshake
+{
+	int type;		/* which type (look below) */
+	long version;		/* openmosix version */
+	int reason;		/* reason for mig or command */
+	int personality;	/* of process to be sent */
+};
+/* handshake types */
+#define HSHAKE_MIG_REQUEST	0x01
+#define HSHAKE_DEPUTY_PROBE	0x02
+#define HSHAKE_REPLY		0x04
+#define HSHAKE_NOTOK		0x08
+
+
+/* main structure for passing messages between
+ * DEPUTY and REMOTE. Denotes the type of request,
+ * and the length of it */
+struct omp_req
+{
+	int type;
+	int dlen;
+};
+
+#define DEP_FLG		0x100
+#define MIG_FLG		0x200
+#define REM_FLG		0x400
+#define REPLY		0x800
+
+/* commands sent during migration */
+#define MIG_MM		(MIG_FLG | 0x10)
+#define MIG_VMA		(MIG_FLG | 0x11)
+#define MIG_PAGE	(MIG_FLG | 0x12)
+#define MIG_FP		(MIG_FLG | 0x13)
+#define MIG_ARCH	(MIG_FLG | 0x14)
+#define MIG_TASK	(MIG_FLG | 0x15)
+#define MIG_ABORT	(MIG_FLG | 0x16)
+
+/* commands sent by deputy to remote */
+#define DEP_COPY_FROM_USER	(DEP_FLG | 0x01)
+#define DEP_COPY_TO_USER	(DEP_FLG | 0x02)
+#define DEP_STRNCPY_FROM_USER	(DEP_FLG | 0x03)
+#define DEP_STRNLEN_USER	(DEP_FLG | 0x04)
+#define DEP_GET_USER		(DEP_FLG | 0x05)
+#define DEP_PUT_USER		(DEP_FLG | 0x06)
+#define DEP_SIGNAL		(DEP_FLG | 0x07)
+#define DEP_COMING_HOME		(DEP_FLG | 0x10)
+
+/* commands sent by remote to deputy */
+#define REM_BRING_HOME	(REM_FLG | 0x10)
+#define REM_PAGE	(REM_FLG | 0x11)
+#define REM_SYSCALL	(REM_FLG | 0x12)
+#define REM_FORK	(REM_FLG | 0x14)
+#define REM_MMAP	(REM_FLG | 0x15)
+#define REM_EXECVE	(REM_FLG | 0x16)
+
+/* task_struct values that need to be passed */
+struct omp_mig_task
+{
+	unsigned long ptrace;
+	long nice;
+
+	kernel_cap_t caps;
+	struct rlimit rlim_cpu, rlim_data, rlim_stack, rlim_rss, rlim_as;
+
+	pid_t pid, tgid;
+	unsigned long personality;
+
+	/* process credentials */
+	uid_t uid, euid, suid, fsuid;
+	gid_t gid, egid, sgid, fsgid;
+
+	/* signals */
+	sigset_t blocked, real_blocked;
+	struct k_sigaction sighand[_NSIG];
+	unsigned long sas_ss_sp;
+	size_t sas_ss_size;
+
+	/* saved user space regs */
+	struct pt_regs regs;
+
+	struct omp_mig_arch_task arch;
+	char comm[TASK_COMM_LEN]; 
+};
+
+/* mm_struct values */
+struct omp_mig_mm
+{
+	unsigned long start_code, end_code, start_data, end_data;
+	unsigned long start_brk, brk, start_stack;
+	unsigned long arg_start, arg_end, env_start, env_end;
+};
+
+struct omp_mig_vma
+{
+	unsigned long vm_start;
+	unsigned long vm_size;
+	unsigned long vm_flags;
+	unsigned long vm_pgoff;
+	struct file *vm_file;
+	struct dentry *f_dentry;
+	loff_t i_size;
+};
+
+struct omp_syscall_req
+{
+	int n;			/* syscall number */
+	unsigned long arg[7];	/* array of arguments */
+};
+
+struct omp_syscall_ret
+{
+	long ret;		/* syscall return value */
+};
+
+struct omp_fork_req
+{
+	unsigned long clone_flags;
+	struct pt_regs regs;
+	struct sockaddr sockaddr;
+	unsigned long stack_start;
+	unsigned long stack_size;
+};
+
+struct omp_fork_ret
+{
+	pid_t pid, tgid;	/* child pid and tgid */
+};
+
+struct omp_usercopy_req
+{
+	unsigned long addr;
+	unsigned long len;
+};
+
+struct omp_usercopy_emb
+{
+	unsigned long addr;
+	unsigned long len;
+	s64 val;
+};
+
+struct omp_page_req
+{
+	struct file * file;
+	unsigned long offset;
+};
+
+struct omp_mmap_req
+{
+	unsigned long addr;
+	unsigned long len;
+	unsigned long flags;
+	unsigned long prot;
+	unsigned long fd;
+	unsigned long pgoff;
+};
+
+struct omp_execve_req
+{
+	int filelen;
+	int argc, envc;
+	int argvlen, envplen;
+	struct pt_regs regs;
+};
+
+struct omp_execve_ret
+{
+	int ret;
+};
+
+struct omp_mmap_ret
+{
+	long ret;
+	struct file * file;
+	unsigned long isize;
+};
+
+struct omp_signal
+{
+	int signr;
+	siginfo_t siginfo;
+};
+
+#endif /*  _HPC_PROTOCOL_H */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/hpc/prototype.h ./include/hpc/prototype.h
--- src-orig/include/hpc/prototype.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/hpc/prototype.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,86 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifndef _HPC_PROTOTYPE_H
+#define _HPC_PROTOTYPE_H
+
+#ifdef CONFIG_OPENMOSIX_MIGRATION_VERBOSE
+#define OM_VERBOSE_MIG(fmt...)	printk(KERN_NOTICE fmt)
+#else
+#define OM_VERBOSE_MIG(fmt...)	do { } while (0)
+#endif
+
+#define OMBUG(f, a...)	printk(KERN_ERR "[OMBUG] %s: " f, __FUNCTION__, ## a)
+
+
+NORET_TYPE void		deputy_die_on_communication(void);
+void			deputy_main_loop(void);
+void			deputy_startup(task_t *p);
+
+/*****************************************************************************/
+
+struct om_held_file
+{
+	struct list_head list;
+	struct file *file;
+	unsigned long nb;
+	struct page *(*nopage)(struct vm_area_struct *, unsigned long, int *);
+};
+
+struct rfile_inode_data
+{
+	struct file *file;
+	unsigned long node;
+	loff_t isize;
+};
+
+struct vm_operations_struct; /* forward declaration */
+
+int			task_heldfiles_add(task_t *p, struct file *file,
+					struct vm_operations_struct *vm_ops);
+void			task_heldfiles_clear(task_t *p);
+struct om_held_file *	task_heldfiles_find(task_t *p, struct file *file);
+
+struct file *		task_rfiles_get(task_t *p, struct file *file,
+					unsigned long node, loff_t isize);
+
+struct file *		rfiles_inode_get_file(struct inode *inode);
+
+/*****************************************************************************/
+
+struct omp_mig_vma; /* forward declaration */
+
+NORET_TYPE void	remote_disappear(void);
+int		remote_mmap(struct omp_mig_vma *, int);
+long		remote_do_syscall(int, struct pt_regs *);
+int		remote_do_comm(task_t *);
+long		remote_do_fork(unsigned long clone_flags,
+				unsigned long stack_start,
+				struct pt_regs *regs,
+				unsigned long stack_size,
+				int __user *parent_tidptr,
+				int __user *child_tidptr);
+long		remote_do_mmap(unsigned long addr, unsigned long len,
+				unsigned long prot, unsigned long flags,
+				unsigned long fd, unsigned long pgoff);
+int		remote_file_mmap(struct file *file,
+				struct vm_area_struct *vma);
+int		remote_readpage(struct file *file, struct page *page);
+
+#endif /* _HPC_PROTOTYPE_H */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/hpc/service.h ./include/hpc/service.h
--- src-orig/include/hpc/service.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/hpc/service.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,33 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifndef _HPC_SERVICE_H
+#define _HPC_SERVICE_H
+
+#include <linux/types.h>
+#include <linux/socket.h>
+
+int sockaddr_to_string(struct sockaddr *address, char *buffer);
+int string_to_sockaddr(char *buf, struct sockaddr *address);
+void sockaddr_setup_port(struct sockaddr *, int port);
+int sockaddr_inherit(struct socket *mlink, struct sockaddr *sa);
+
+void om_daemonize(char *, int);
+
+#endif /* _HPC_SERVICE_H */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/hpc/syscalls.h ./include/hpc/syscalls.h
--- src-orig/include/hpc/syscalls.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/hpc/syscalls.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,30 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifndef _HPC_SYSCALL_H
+#define _HPC_SYSCALL_H
+
+#define SYSARG(n)	arch_get_sys_arg(n, &regs)
+#define SYSNB()		arch_get_sys_nb(&regs)
+
+typedef struct syscall_parameter_t { long arg[NR_MAX_SYSCALL_ARG]; }
+						syscall_parameter_t;
+typedef long (*syscall_func_t)(syscall_parameter_t);
+
+#endif /* _HPC_SYSCALL_H */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/hpc/task.h ./include/hpc/task.h
--- src-orig/include/hpc/task.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/hpc/task.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,156 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifndef _HPC_TASK_H
+#define _HPC_TASK_H
+
+#ifdef CONFIG_OPENMOSIX
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <asm/atomic.h>
+
+#define OPENMOSIX_INIT_TASK(tsk) .om = {	\
+	.dflags = 0,				\
+	.dreqs = ATOMIC_INIT(0),                \
+	.rfiles = LIST_HEAD_INIT(tsk.om.rfiles),\
+}
+
+
+#define OPENMOSIX_INIT_MM()			\
+	.mm_realusers = ATOMIC_INIT(1),		\
+
+/*
+ * distributed flags (dflags):
+ * that are *ONLY* set by the process itself, but may be read by others:
+ */
+#define	DDEPUTY		0x00000001	/* process is a DEPUTY stub */
+#define	DREMOTE		0x00000002	/* process is running remotely */
+#define	DINCOMING	0x00000040	/* process coming here */
+#define	DPASSING	0x00000080	/* process is in migration */
+#define	DFINISHED	0x00000200	/* wants to become zombie */
+#define	DREMOTEDAEMON	0x00000400	/* set DREMOTE on "fork" */
+
+#define	DMIGRATED	(DDEPUTY | DREMOTE) /* if task has been migrated */
+
+/*
+ * distributed request (dreqs):
+ * Thoses flags are set by any process to interact with the process.
+ */
+#define DREQ_MOVE	(1 << 0)	/* the process has to move */
+#define	DREQ_CHECKSTAY	(1 << 1)	/* check whether still stay */
+#define	DREQ_URGENT	(1 << 2)	/* something urgent (R=>D) */
+
+/*
+ * stay reason (dstay):
+ */
+#define	DSTAY_MONKEY	(1 << 0)	/* using monkey vnode */
+#define	DSTAY_DEV	(1 << 1)	/* mapping a device */
+#define	DSTAY_86	(1 << 2)	/* running in 86 mode */
+#define	DSTAY_PRIV	(1 << 4)	/* privilleged inst. access (in/out) */
+#define	DSTAY_MLOCK	(1 << 5)	/* has locked memory */
+#define	DSTAY_CLONE	(1 << 6)	/* shared VM, eliminate this once DSM*/
+#define	DSTAY_RT	(1 << 7)	/* Real-Time scheduling */
+#define	DSTAY_IOPL	(1 << 8)	/* direct I/O permission */
+#define	DSTAY_SYSTEM	(1 << 9)	/* init process */
+#define	DSTAY_OTHER1	(1 << 24)	/* external reason for stay (1) */
+#define	DSTAY_OTHER2	(1 << 25)	/* external reason for stay (2) */
+#define	DSTAY_OTHER3	(1 << 26)	/* external reason for stay (3) */
+#define	DSTAY_OTHER4	(1 << 27)	/* external reason for stay (4) */
+#define	DNOMIGRATE	(1 << 31)	/* user requested no auto-migrations */
+
+#define	DSTAY		(~DNOMIGRATE)
+#define	DSTAY_PER_MM	(DSTAY_MONKEY|DSTAY_DEV|DSTAY_MLOCK)
+
+int task_set_where(struct task_struct *p, int value);
+int task_get_where(struct task_struct *p);
+
+/* dreqs */
+static inline void task_set_dreqs(struct task_struct *p, unsigned int val)
+{
+	atomic_set_mask(val, &p->om.dreqs);
+}
+
+static inline void task_clear_dreqs(struct task_struct *p, unsigned int val)
+{
+	atomic_clear_mask(val, &p->om.dreqs);
+}
+
+static inline int task_test_dreqs(struct task_struct *p, unsigned int val)
+{
+	return atomic_read(&p->om.dreqs) & val;
+}
+
+/* dflags */
+
+static inline void task_set_dflags(struct task_struct *p, unsigned int val)
+{
+	p->om.dflags |= val;
+}
+
+static inline void task_clear_dflags(struct task_struct *p, unsigned int val)
+{
+	p->om.dflags &= ~val;
+}
+
+static inline int task_test_dflags(struct task_struct *p, unsigned int val)
+{
+	return (p->om.dflags & val);
+}
+
+/* stay */
+
+static inline void task_set_stay(struct task_struct *p, unsigned int val)
+{
+	p->om.stay |= val;
+}
+
+static inline void task_clear_stay(struct task_struct *p, unsigned int val)
+{
+	p->om.stay &= ~val;
+}
+
+static inline int task_test_stay(struct task_struct *p, unsigned int val)
+{
+	return (p->om.stay & val);
+}
+
+#define task_dreqs_pending(p)	task_test_dreqs(p, ~0)
+
+void task_add_balance_reason(struct task_struct *p, int w);
+
+int task_go_home(struct task_struct *p);
+int task_go_home_for_reason(struct task_struct *p, int reason);
+
+int task_check_stay(struct task_struct *p);
+void task_do_request(void);
+
+struct sockaddr;
+int task_register_migration(task_t *p, struct sockaddr *);
+
+struct inode;
+int task_maps_inode(task_t *p, struct inode *);
+
+#else
+
+#define OPENMOSIX_INIT_TASK(tsk)	/* */
+#define OPENMOSIX_INIT_MM()		/* */
+
+#endif
+#endif /* _HPC_HPCTASK_H */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/hpc/uaccess.h ./include/hpc/uaccess.h
--- src-orig/include/hpc/uaccess.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/hpc/uaccess.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,64 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifndef _HPC_UACCESS_H
+#define _HPC_UACCESS_H
+
+#ifdef CONFIG_OPENMOSIX
+#include <hpc/task.h>
+
+unsigned long	deputy_copy_from_user(void *to,
+					const void __user *from,
+					unsigned long n);
+unsigned long	deputy_copy_to_user(void __user *to,
+					const void *from,
+					unsigned long n);
+unsigned long	deputy_strncpy_from_user(char *dst, const char __user *src,
+							long count);
+unsigned long	deputy_strnlen_user(const char *s, long n);
+
+long		deputy_put_user(long value, const void *addr, size_t size);
+long		deputy_get_user(long *value, const void *addr, size_t size);
+
+#if BITS_PER_LONG < 64
+long		deputy_get_user64(s64 *value, const void *addr);
+long		deputy_put_user64(s64 value, const void *addr);
+#endif
+
+/**
+ * openmosix_memory_away - Test is memory is here
+ **/
+static inline int openmosix_memory_away(void)
+{
+	if (segment_eq(get_fs(), KERNEL_DS))
+		return 0;
+	if (task_test_dflags(current, DDEPUTY))
+		return 1;
+	return 0;
+}
+
+#else
+
+#define openmosix_memory_away() 0
+#define deputy_put_user(a, b, c) 0
+#define deputy_get_user(a, b, c) 0
+
+#endif
+
+#endif /* _HPC_UACCESS_H */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/hpc/version.h ./include/hpc/version.h
--- src-orig/include/hpc/version.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/hpc/version.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,40 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *	Copyright (C) 2005-2006 Vincent Hanquez <vincent@snarc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg
+ *
+ */
+
+#ifndef _HPC_VERSION_H
+#define _HPC_VERSION_H
+
+#define OPENMOSIX_VERSION_MAJOR		0
+#define OPENMOSIX_VERSION_MINOR		0
+#define OPENMOSIX_VERSION_MICRO		0
+
+#define OPENMOSIX_VERSION	(OPENMOSIX_VERSION_MAJOR * 10000) + \
+				(OPENMOSIX_VERSION_MINOR * 100) + \
+				(OPENMOSIX_VERSION_MICRO)
+
+#define OPENMOSIX_VERSION_TUPPLE \
+				OPENMOSIX_VERSION_MAJOR, \
+				OPENMOSIX_VERSION_MINOR, \
+				OPENMOSIX_VERSION_MICRO
+
+/* FIXME : need to create a scheme about version handling */
+#define OPENMOSIX_VERSION_BALANCE	0x1L
+#define OPENMOSIX_VERSION_MIGRATION	0x1L
+
+#endif /* _HPC_VERSION_H */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/linux/compiler.h ./include/linux/compiler.h
--- src-orig/include/linux/compiler.h	2006-09-27 16:14:42.000000000 -0600
+++ ./include/linux/compiler.h	2006-08-23 09:16:48.000000000 -0600
@@ -36,6 +36,18 @@
 
 #ifdef __KERNEL__
 
+#ifdef CONFIG_OPENMOSIX
+#define OM_NSTATIC
+#else
+#define OM_NSTATIC static
+#endif
+
+#ifdef CONFIG_KCOMD
+#define KCOMD_NSTATIC
+#else
+#define KCOMD_NSTATIC static
+#endif
+
 #if __GNUC__ > 4
 #error no compiler-gcc.h file for this gcc version
 #elif __GNUC__ == 4
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/linux/hpc.h ./include/linux/hpc.h
--- src-orig/include/linux/hpc.h	1969-12-31 17:00:00.000000000 -0700
+++ ./include/linux/hpc.h	2006-08-23 09:16:48.000000000 -0600
@@ -0,0 +1,31 @@
+/*
+ *	Copyright (C) 2002-2004 Moshe Bar <moshe@moshebar.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh
+ *
+ * Changes for 2.6 by Vincent Hanquez
+ *
+ */
+
+#ifndef _LINUX_HPC_H
+#define _LINUX_HPC_H
+
+#ifdef CONFIG_OPENMOSIX
+#include <hpc/hpc.h>
+#include <hpc/task.h>
+#define OM_MM(task)		(task->mm)
+#else
+#define OM_MM(task)		(1)
+
+#endif
+
+#endif /* _LINUX_HPC_H */
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/linux/init_task.h ./include/linux/init_task.h
--- src-orig/include/linux/init_task.h	2006-09-27 16:14:42.000000000 -0600
+++ ./include/linux/init_task.h	2006-08-23 09:16:48.000000000 -0600
@@ -3,9 +3,10 @@
 
 #include <linux/file.h>
 #include <linux/rcupdate.h>
+#include <hpc/task.h>
 
 #define INIT_FDTABLE \
-{							\
+{ 							\
 	.max_fds	= NR_OPEN_DEFAULT, 		\
 	.max_fdset	= EMBEDDED_FD_SET_SIZE,		\
 	.fd		= &init_files.fd_array[0], 	\
@@ -51,6 +52,7 @@
 	.page_table_lock =  SPIN_LOCK_UNLOCKED, 		\
 	.mmlist		= LIST_HEAD_INIT(name.mmlist),		\
 	.cpu_vm_mask	= CPU_MASK_ALL,				\
+	OPENMOSIX_INIT_MM()					\
 }
 
 #define INIT_SIGNALS(sig) {	\
@@ -123,6 +125,7 @@
 	.journal_info	= NULL,						\
 	.cpu_timers	= INIT_CPU_TIMERS(tsk.cpu_timers),		\
 	.fs_excl	= ATOMIC_INIT(0),				\
+	OPENMOSIX_INIT_TASK(tsk)					\
 }
 
 
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/linux/net.h ./include/linux/net.h
--- src-orig/include/linux/net.h	2006-09-27 16:14:42.000000000 -0600
+++ ./include/linux/net.h	2006-08-23 09:16:48.000000000 -0600
@@ -183,6 +183,9 @@
 extern int	     sock_wake_async(struct socket *sk, int how, int band);
 extern int	     sock_register(struct net_proto_family *fam);
 extern int	     sock_unregister(int family);
+#ifdef CONFIG_KCOMD
+extern struct socket *sock_alloc(void);
+#endif
 extern int	     sock_create(int family, int type, int proto,
 				 struct socket **res);
 extern int	     sock_create_kern(int family, int type, int proto,
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/linux/sched.h ./include/linux/sched.h
--- src-orig/include/linux/sched.h	2006-09-27 16:14:42.000000000 -0600
+++ ./include/linux/sched.h	2006-08-23 09:16:48.000000000 -0600
@@ -37,6 +37,10 @@
 #include <linux/rcupdate.h>
 #include <linux/futex.h>
 
+#ifdef CONFIG_OPENMOSIX
+#include <hpc/omtask.h>
+#endif /* CONFIG_OPENMOSIX */
+
 #include <linux/auxvec.h>	/* For AT_VECTOR_SIZE */
 
 struct exec_domain;
@@ -350,6 +354,10 @@
 	/* aio bits */
 	rwlock_t		ioctx_list_lock;
 	struct kioctx		*ioctx_list;
+
+#ifdef CONFIG_OPENMOSIX
+	atomic_t mm_realusers;		/* nb of processes that uses this mm */
+#endif /* CONFIG_MOSIX */
 };
 
 struct sighand_struct {
@@ -866,6 +874,9 @@
 	u64 acct_vm_mem1;	/* accumulated virtual memory usage */
 	clock_t acct_stimexpd;	/* clock_t-converted stime since last update */
 #endif
+#ifdef CONFIG_OPENMOSIX
+	om_task_t om;
+#endif /* CONFIG_OPENMOSIX */
 #ifdef CONFIG_NUMA
   	struct mempolicy *mempolicy;
 	short il_next;
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/include/linux/signal.h ./include/linux/signal.h
--- src-orig/include/linux/signal.h	2006-09-27 16:14:42.000000000 -0600
+++ ./include/linux/signal.h	2006-08-23 09:16:48.000000000 -0600
@@ -260,7 +260,7 @@
 }
 
 extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p);
-extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
+extern int __group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p);
 extern long do_sigpending(void __user *, unsigned long);
 extern int sigprocmask(int, sigset_t *, sigset_t *);
 
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/kernel/exit.c ./kernel/exit.c
--- src-orig/kernel/exit.c	2006-09-27 16:14:42.000000000 -0600
+++ ./kernel/exit.c	2006-08-23 09:16:48.000000000 -0600
@@ -1,4 +1,5 @@
 /*
+
  *  linux/kernel/exit.c
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
@@ -42,13 +43,15 @@
 #include <asm/pgtable.h>
 #include <asm/mmu_context.h>
 
+#include <linux/hpc.h>
+
+OM_NSTATIC void exit_mm(struct task_struct * tsk);
+
 extern void sem_exit (void);
 extern struct task_struct *child_reaper;
 
 int getrusage(struct task_struct *, int, struct rusage __user *);
 
-static void exit_mm(struct task_struct * tsk);
-
 static void __unhash_process(struct task_struct *p)
 {
 	nr_threads--;
@@ -283,7 +286,7 @@
  *
  * NOTE that reparent_to_init() gives the caller full capabilities.
  */
-static void reparent_to_init(void)
+OM_NSTATIC void reparent_to_init(void)
 {
 	write_lock_irq(&tasklist_lock);
 
@@ -553,10 +556,13 @@
  * Turn us into a lazy TLB process if we
  * aren't already..
  */
-static void exit_mm(struct task_struct * tsk)
+OM_NSTATIC void exit_mm(struct task_struct * tsk)
 {
 	struct mm_struct *mm = tsk->mm;
 
+#ifdef CONFIG_OPENMOSIX
+	if (!task_test_dflags(tsk, DDEPUTY))
+#endif
 	mm_release(tsk, mm);
 	if (!mm)
 		return;
@@ -891,6 +897,9 @@
 		update_hiwater_rss(tsk->mm);
 		update_hiwater_vm(tsk->mm);
 	}
+#ifdef CONFIG_OPENMOSIX
+	openmosix_task_exit();
+#endif
 	group_dead = atomic_dec_and_test(&tsk->signal->live);
 	if (group_dead) {
  		hrtimer_cancel(&tsk->signal->real_timer);
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/kernel/fork.c ./kernel/fork.c
--- src-orig/kernel/fork.c	2006-09-27 16:14:42.000000000 -0600
+++ ./kernel/fork.c	2006-08-23 09:16:48.000000000 -0600
@@ -52,6 +52,8 @@
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
+#include <linux/hpc.h>
+
 /*
  * Protected counters by write_lock_irq(&tasklist_lock)
  */
@@ -315,6 +317,9 @@
 {
 	atomic_set(&mm->mm_users, 1);
 	atomic_set(&mm->mm_count, 1);
+#ifdef CONFIG_OPENMOSIX
+	atomic_set(&mm->mm_realusers, 1);
+#endif /* CONFIG_OPENMOSIX */
 	init_rwsem(&mm->mmap_sem);
 	INIT_LIST_HEAD(&mm->mmlist);
 	mm->core_waiters = 0;
@@ -473,6 +478,9 @@
 	err = dup_mmap(mm, oldmm);
 	if (err)
 		goto free_pt;
+#ifdef CONFIG_OPENMOSIX
+	task_clear_stay(tsk, DSTAY_CLONE);
+#endif /* CONFIG_OPENMOSIX */
 
 	mm->hiwater_rss = get_mm_rss(mm);
 	mm->hiwater_vm = mm->total_vm;
@@ -517,6 +525,9 @@
 
 	if (clone_flags & CLONE_VM) {
 		atomic_inc(&oldmm->mm_users);
+#ifdef CONFIG_OPENMOSIX
+		atomic_inc(&oldmm->mm_realusers);
+#endif /* CONFIG_OPENMOSIX */
 		mm = oldmm;
 		goto good_mm;
 	}
@@ -1045,6 +1056,10 @@
 		goto bad_fork_cleanup_policy;
 	if ((retval = audit_alloc(p)))
 		goto bad_fork_cleanup_security;
+#ifdef CONFIG_OPENMOSIX
+	if ((retval = openmosix_task_init(p)))
+		goto bad_fork_cleanup_audit;
+#endif /* CONFIG_OPENMOSIX */
 	/* copy all the process information */
 	if ((retval = copy_semundo(clone_flags, p)))
 		goto bad_fork_cleanup_audit;
@@ -1308,17 +1323,20 @@
 {
 	struct task_struct *p;
 	int trace = 0;
-	struct pid *pid = alloc_pid();
-	long nr;
-
-	if (!pid)
+ 	struct pid *pid = alloc_pid();
+ 	long nr;
+ 
+ 	if (!pid)
 		return -EAGAIN;
-	nr = pid->nr;
+ 	nr = pid->nr;
 	if (unlikely(current->ptrace)) {
 		trace = fork_traceflag (clone_flags);
 		if (trace)
 			clone_flags |= CLONE_PTRACE;
 	}
+#ifdef CONFIG_OPENMOSIX
+	openmosix_pre_clone(clone_flags);
+#endif
 
 	p = copy_process(clone_flags, stack_start, regs, stack_size, parent_tidptr, child_tidptr, nr);
 	/*
@@ -1360,6 +1378,9 @@
 		free_pid(pid);
 		nr = PTR_ERR(p);
 	}
+#ifdef CONFIG_OPENMOSIX
+	openmosix_post_clone(clone_flags);
+#endif
 	return nr;
 }
 
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/kernel/sched.c ./kernel/sched.c
--- src-orig/kernel/sched.c	2006-09-27 16:14:42.000000000 -0600
+++ ./kernel/sched.c	2006-08-23 09:16:48.000000000 -0600
@@ -355,7 +355,7 @@
  * interrupts.  Note the ordering: we can safely lookup the task_rq without
  * explicitly disabling preemption.
  */
-static inline runqueue_t *task_rq_lock(task_t *p, unsigned long *flags)
+OM_NSTATIC runqueue_t *task_rq_lock(task_t *p, unsigned long *flags)
 	__acquires(rq->lock)
 {
 	struct runqueue *rq;
@@ -371,7 +371,7 @@
 	return rq;
 }
 
-static inline void task_rq_unlock(runqueue_t *rq, unsigned long *flags)
+OM_NSTATIC inline void task_rq_unlock(runqueue_t *rq, unsigned long *flags)
 	__releases(rq->lock)
 {
 	spin_unlock_irqrestore(&rq->lock, *flags);
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/MAINTAINERS ./MAINTAINERS
--- src-orig/MAINTAINERS	2006-09-27 16:14:42.000000000 -0600
+++ ./MAINTAINERS	2006-08-23 09:16:48.000000000 -0600
@@ -2081,6 +2081,15 @@
 L:	linux-scsi@vger.kernel.org
 S:	Maintained
 
+OPENMOSIX
+P:	Vincent Hanquez
+M:	tab@snarc.org
+P:	Alexander Nyberg
+M:	alexn@telia.com
+L:	openmosix-general@lists.sourceforge.net
+W:	http://openmosix.sourceforge.net/
+S:	Maintained
+
 OPL3-SA2, SA3, and SAx DRIVER
 P:	Zwane Mwaikambo
 M:	zwane@arm.linux.org.uk
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/Makefile ./Makefile
--- src-orig/Makefile	2006-09-27 16:14:42.000000000 -0600
+++ ./Makefile	2006-08-23 09:16:48.000000000 -0600
@@ -311,7 +311,7 @@
 
 # Read KERNELRELEASE from .kernelrelease (if it exists)
 KERNELRELEASE = $(shell cat .kernelrelease 2> /dev/null)
-KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
+KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)-om
 
 export	VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION \
 	ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
@@ -463,6 +463,9 @@
 # Defaults vmlinux but it is usually overriden in the arch makefile
 all: vmlinux
 
+unsparse:
+	scripts/unsparse
+
 ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
 CFLAGS		+= -Os
 else
@@ -518,7 +521,7 @@
 
 
 ifeq ($(KBUILD_EXTMOD),)
-core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/ block/
+core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/ block/ hpc/
 
 vmlinux-dirs	:= $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
 		     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/mm/mlock.c ./mm/mlock.c
--- src-orig/mm/mlock.c	2006-09-27 16:14:42.000000000 -0600
+++ ./mm/mlock.c	2006-08-23 09:16:48.000000000 -0600
@@ -11,6 +11,7 @@
 #include <linux/mempolicy.h>
 #include <linux/syscalls.h>
 
+#include <linux/hpc.h>
 
 static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
 	unsigned long start, unsigned long end, unsigned int newflags)
@@ -20,7 +21,7 @@
 	int pages;
 	int ret = 0;
 
-	if (newflags == vma->vm_flags) {
+ 	if (newflags == vma->vm_flags) {
 		*prev = vma;
 		goto out;
 	}
@@ -143,6 +144,10 @@
 	/* check against resource limits */
 	if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
 		error = do_mlock(start, len, 1);
+#ifdef CONFIG_OPENMOSIX
+	if (!error) /* FIXME len == 0 shouldn't DSTAY MLOCK current & clones */
+		stay_me_and_my_clones(DSTAY_MLOCK);
+#endif /* CONFIG_OPENMOSIX */
 	up_write(&current->mm->mmap_sem);
 	return error;
 }
@@ -156,6 +161,10 @@
 	start &= PAGE_MASK;
 	ret = do_mlock(start, len, 0);
 	up_write(&current->mm->mmap_sem);
+#ifdef CONFIG_OPENMOSIX
+	if (ret)
+		unstay_mm(current->mm);
+#endif /* CONFIG_OPENMOSIX */
 	return ret;
 }
 
@@ -205,6 +214,10 @@
 	if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
 	    capable(CAP_IPC_LOCK))
 		ret = do_mlockall(flags);
+#ifdef CONFIG_OPENMOSIX
+	if (!ret)
+		stay_me_and_my_clones(DSTAY_MLOCK);
+#endif /* CONFIG_OPENMOSIX */
 	up_write(&current->mm->mmap_sem);
 out:
 	return ret;
@@ -217,9 +230,12 @@
 	down_write(&current->mm->mmap_sem);
 	ret = do_mlockall(0);
 	up_write(&current->mm->mmap_sem);
+#ifdef CONFIG_OPENMOSIX
+	if (ret)
+		unstay_mm(current->mm);
+#endif /* CONFIG_OPENMOSIX */
 	return ret;
 }
-
 /*
  * Objects with different lifetime than processes (SHM_LOCK and SHM_HUGETLB
  * shm segments) get accounted against the user_struct instead.
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/mm/mmap.c ./mm/mmap.c
--- src-orig/mm/mmap.c	2006-09-27 16:14:42.000000000 -0600
+++ ./mm/mmap.c	2006-08-23 09:16:48.000000000 -0600
@@ -30,6 +30,8 @@
 #include <asm/cacheflush.h>
 #include <asm/tlb.h>
 
+#include <linux/hpc.h>
+
 static void unmap_region(struct mm_struct *mm,
 		struct vm_area_struct *vma, struct vm_area_struct *prev,
 		unsigned long start, unsigned long end);
@@ -183,9 +185,22 @@
 
 	flush_dcache_mmap_lock(mapping);
 	if (unlikely(vma->vm_flags & VM_NONLINEAR))
+	{
 		list_del_init(&vma->shared.vm_set.list);
+#ifdef CONFIG_OPENMOSIX
+		if (list_empty(&vma->shared.vm_set.list))
+			openmosix_no_longer_monkey(file->f_dentry->d_inode);
+#endif /* CONFIG_OPENMOSIX */
+	}
 	else
+	{
 		vma_prio_tree_remove(vma, &mapping->i_mmap);
+#ifdef CONFIG_OPENMOSIX
+		/* FIXME tab: maybe wrong ! */
+		if (vma->shared.vm_set.parent && vma->shared.vm_set.head)
+			openmosix_no_longer_monkey(file->f_dentry->d_inode);
+#endif /* CONFIG_OPENMOSIX */
+	}
 	flush_dcache_mmap_unlock(mapping);
 }
 
@@ -888,6 +903,9 @@
 	struct rb_node ** rb_link, * rb_parent;
 	int accountable = 1;
 	unsigned long charged = 0, reqprot = prot;
+#ifdef CONFIG_OPENMOSIX
+	int stay_reason = 0;
+#endif /* CONFIG_OPENMOSIX */
 
 	if (file) {
 		if (is_file_hugepages(file))
@@ -923,7 +941,7 @@
                return -EOVERFLOW;
 
 	/* Too many mappings? */
-	if (mm->map_count > sysctl_max_map_count)
+	if (OM_MM(current) && mm->map_count > sysctl_max_map_count)
 		return -ENOMEM;
 
 	/* Obtain the address to map to. we verify (or select) it and ensure
@@ -938,7 +956,7 @@
 	 * of the memory object, so we don't do any here.
 	 */
 	vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
-			mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
+			(OM_MM(current) ? mm->def_flags : 0) | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
 
 	if (flags & MAP_LOCKED) {
 		if (!can_do_mlock())
@@ -946,7 +964,7 @@
 		vm_flags |= VM_LOCKED;
 	}
 	/* mlock MCL_FUTURE? */
-	if (vm_flags & VM_LOCKED) {
+	if (OM_MM(current) && vm_flags & VM_LOCKED) {
 		unsigned long locked, lock_limit;
 		locked = len >> PAGE_SHIFT;
 		locked += mm->locked_vm;
@@ -980,9 +998,19 @@
 			vm_flags |= VM_SHARED | VM_MAYSHARE;
 			if (!(file->f_mode & FMODE_WRITE))
 				vm_flags &= ~(VM_MAYWRITE | VM_SHARED);
+#ifdef CONFIG_OPENMOSIX
+			if (file->f_mode & FMODE_WRITE)
+				stay_reason |= DSTAY_MONKEY;
+#endif /* CONFIG_OPENMOSIX */
 
 			/* fall through */
 		case MAP_PRIVATE:
+#ifdef CONFIG_OPENMOSIX
+			if (inode && inode->i_mapping->i_mmap_writable != 0)
+				stay_reason |= DSTAY_MONKEY;
+			if (S_ISCHR(file->f_dentry->d_inode->i_mode))
+				stay_reason |= DSTAY_DEV;
+#endif /* CONFIG_OPENMOSIX */
 			if (!(file->f_mode & FMODE_READ))
 				return -EACCES;
 			break;
@@ -1009,6 +1037,10 @@
 	error = security_file_mmap(file, reqprot, prot, flags);
 	if (error)
 		return error;
+#ifdef CONFIG_OPENMOSIX
+	if (file && task_test_dflags(current, DDEPUTY))
+		return deputy_do_mmap_pgoff(file, addr, len, prot, vm_flags, pgoff);
+#endif
 		
 	/* Clear old maps */
 	error = -ENOMEM;
@@ -1128,6 +1160,10 @@
 		mm->locked_vm += len >> PAGE_SHIFT;
 		make_pages_present(addr, addr + len);
 	}
+#ifdef CONFIG_OPENMOSIX
+	if (stay_reason)
+		stay_me_and_my_clones(stay_reason);
+#endif /* CONFIG_OPENMOSIX */
 	if (flags & MAP_POPULATE) {
 		up_write(&mm->mmap_sem);
 		sys_remap_file_pages(addr, len, 0,
@@ -1339,18 +1375,22 @@
 		unsigned long pgoff, unsigned long flags)
 {
 	unsigned long ret;
-
+  
 	if (!(flags & MAP_FIXED)) {
 		unsigned long (*get_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
-
+  
 		get_area = current->mm->get_unmapped_area;
+#ifdef CONFIG_OPENMOSIX
+		if (task_test_dflags(current, DDEPUTY))
+			return PAGE_ALIGN(addr);
+#endif
 		if (file && file->f_op && file->f_op->get_unmapped_area)
 			get_area = file->f_op->get_unmapped_area;
 		addr = get_area(file, addr, len, pgoff, flags);
 		if (IS_ERR_VALUE(addr))
 			return addr;
 	}
-
+  
 	if (addr > TASK_SIZE - len)
 		return -ENOMEM;
 	if (addr & ~PAGE_MASK)
diff -urN -x src-orig -x '*\.patch' -x unsparse -x '\.git' -x '\.svn' -x '\.git' -x '\.cvs/' src-orig/net/socket.c ./net/socket.c
--- src-orig/net/socket.c	2006-09-27 16:14:42.000000000 -0600
+++ ./net/socket.c	2006-08-23 09:16:48.000000000 -0600
@@ -511,7 +511,7 @@
  *	NULL is returned.
  */
 
-static struct socket *sock_alloc(void)
+KCOMD_NSTATIC struct socket *sock_alloc(void)
 {
 	struct inode * inode;
 	struct socket * sock;
@@ -530,6 +530,9 @@
 	put_cpu_var(sockets_in_use);
 	return sock;
 }
+#ifdef CONFIG_KCOMD
+EXPORT_SYMBOL_GPL(sock_alloc);
+#endif
 
 /*
  *	In theory you can't get an open on this inode, but /proc provides
