diff -u -p -L linux-2.2.12/arch/i386/kernel/entry.S.orig linux-2.2.12/arch/i386/kernel/entry.S
--- linux-2.2.12/arch/i386/kernel/entry.S
+++ linux-2.2.12/arch/i386/kernel/entry.S	Mon Aug 28 07:08:46 2000
@@ -562,6 +562,9 @@ ENTRY(sys_call_table)
 	.long SYMBOL_NAME(sys_ni_syscall)		/* streams1 */
 	.long SYMBOL_NAME(sys_ni_syscall)		/* streams2 */
 	.long SYMBOL_NAME(sys_vfork)            /* 190 */
+	.long SYMBOL_NAME(sys_smp_processor)
+	.long SYMBOL_NAME(sys_smp_lockto)
+	.long SYMBOL_NAME(sys_smp_num_cpus)	/* 193 */
 
 	/*
 	 * NOTE!! This doesn't have to be exact - we just have
@@ -569,6 +572,6 @@ ENTRY(sys_call_table)
 	 * entries. Don't panic if you notice that this hasn't
 	 * been shrunk every time we add a new system call.
 	 */
-	.rept NR_syscalls-190
+	.rept NR_syscalls-193
 		.long SYMBOL_NAME(sys_ni_syscall)
 	.endr
diff -u -p -L linux-2.2.12/include/asm-i386/unistd.h.orig linux-2.2.12/include/asm-i386/unistd.h
--- linux-2.2.12/include/asm-i386/unistd.h
+++ linux-2.2.12/include/asm-i386/unistd.h	Mon Aug 28 07:15:51 2000
@@ -195,6 +195,9 @@
 #define __NR_getpmsg		188	/* some people actually want streams */
 #define __NR_putpmsg		189	/* some people actually want streams */
 #define __NR_vfork		190
+#define __NR_smp_processor	191	/* Running on processor x */
+#define __NR_smp_lockto		192	/* Lock to specific processor */
+#define __NR_smp_num_cpus	193	/* Number of processors */
 
 /* user-visible error numbers are in the range -1 - -122: see <asm-i386/errno.h> */
 
diff -u -p -L linux-2.2.12/include/linux/sched.h.orig linux-2.2.12/include/linux/sched.h
--- linux-2.2.12/include/linux/sched.h
+++ linux-2.2.12/include/linux/sched.h	Mon Aug 28 07:15:02 2000
@@ -248,6 +248,7 @@ struct task_struct {
 	int processor;
 	int last_processor;
 	int lock_depth;		/* Lock depth. We can context switch in and out of holding a syscall kernel lock... */	
+	int locked_processor;
 	struct task_struct *next_task, *prev_task;
 	struct task_struct *next_run,  *prev_run;
 
@@ -360,7 +361,7 @@ struct task_struct {
 #define INIT_TASK \
 /* state etc */	{ 0,0,0,KERNEL_DS,&default_exec_domain,0, \
 /* counter */	DEF_PRIORITY,DEF_PRIORITY,0, \
-/* SMP */	0,0,0,-1, \
+/* SMP */	0,0,0,-1,-1, \
 /* schedlink */	&init_task,&init_task, &init_task, &init_task, \
 /* binfmt */	NULL, \
 /* ec,brk... */	0,0,0,0,0,0, \
diff -u -p -L linux-2.2.12/kernel/fork.c.orig linux-2.2.12/kernel/fork.c
--- linux-2.2.12/kernel/fork.c
+++ linux-2.2.12/kernel/fork.c	Mon Aug 28 07:19:49 2000
@@ -656,6 +656,7 @@ int do_fork(unsigned long clone_flags, u
 		int i;
 		p->has_cpu = 0;
 		p->processor = current->processor;
+		p->locked_processor = -1;
 		/* ?? should we just memset this ?? */
 		for(i = 0; i < smp_num_cpus; i++)
 			p->per_cpu_utime[i] = p->per_cpu_stime[i] = 0;
diff -u -p -L linux-2.2.12/kernel/sched.c.orig linux-2.2.12/kernel/sched.c
--- linux-2.2.12/kernel/sched.c
+++ linux-2.2.12/kernel/sched.c	Mon Aug 28 07:07:50 2000
@@ -15,6 +15,7 @@
  *				Copyright (C) 1998  Andrea Arcangeli
  *  1998-12-28  Implemented better SMP scheduling by Ingo Molnar
  *  1999-03-10	Improved NTP compatibility by Ulrich Windl
+ *  1999-07-24	SMP locking processes to processors.  Fred Barnes, 1999.
  */
 
 /*
@@ -171,6 +172,13 @@ static inline int goodness (struct task_
 	/* (this is equivalent to penalizing other processors) */
 	if (p->processor == this_cpu)
 		weight += PROC_CHANGE_PENALTY;
+	/*
+	 *	If process is locked to a processor, never select it.
+	 */
+	if( (p->locked_processor > -1) && (p->locked_processor != this_cpu) ) {
+		weight = -1000;
+		goto out;
+	}
 #endif
 
 	/* .. and a slight advantage to the current MM */
@@ -280,7 +288,15 @@ static inline void reschedule_idle_slow(
 	 * shortcut if the woken up task's last CPU is
 	 * idle now.
 	 */
-	best_cpu = p->processor;
+
+	/*
+	 * If process is locked, preferred CPU is that one
+	 */
+	if( p->locked_processor > -1 ) {
+		best_cpu = p->locked_processor;
+	} else {
+		best_cpu = p->processor;
+	}
 	target_tsk = idle_task(best_cpu);
 	if (cpu_curr(best_cpu) == target_tsk)
 		goto send_now;
@@ -298,11 +314,20 @@ static inline void reschedule_idle_slow(
 		}
 	}
 
+
 	/*
 	 * found any suitable CPU?
 	 */
-	if (!target_tsk)
+	if (!target_tsk) {
 		goto out_no_target;
+	} else {
+		/*
+		 *	Avoid scheduling on another processor
+		 */
+		if( (p->locked_processor > -1) && (p->locked_processor != target_tsk->processor) ) {
+			goto out_no_target;
+		}
+	}
 		
 send_now:
 	target_cpu = target_tsk->processor;
@@ -2048,6 +2073,7 @@ void __init sched_init(void)
 	int nr = NR_TASKS;
 
 	init_task.processor=cpu;
+	init_task.locked_processor = -1;
 
 	/* Init task array free list and pidhash table. */
 	while(--nr > 0)
diff -u -p -L linux-2.2.12/kernel/sys.c.orig linux-2.2.12/kernel/sys.c
--- linux-2.2.12/kernel/sys.c
+++ linux-2.2.12/kernel/sys.c	Mon Aug 28 07:21:22 2000
@@ -1002,3 +1002,40 @@ asmlinkage int sys_prctl(int option, uns
 	return error;
 }
 
+
+/*
+ *	SMP stuff for 2.2.10
+ */
+asmlinkage int sys_smp_num_cpus (void)
+{
+#ifdef __SMP__
+	return smp_num_cpus;
+#else
+	return -ENOSYS;
+#endif
+}
+
+asmlinkage int sys_smp_processor (void)
+{
+#ifdef __SMP__
+	return smp_processor_id ();
+#else
+	return -ENOSYS;
+#endif
+}
+
+asmlinkage int sys_smp_lockto (int proc_id)
+{
+#ifdef __SMP__
+	if ((proc_id != -1) && (proc_id >= smp_num_cpus)) {
+		return -EINVAL;
+	}
+	current->locked_processor = proc_id;
+	return 0;
+#else
+	return -ENOSYS;
+#endif
+}
+
+
+

