diff -Naur -X exclude-files ac_cur/arch/um/drivers/ethertap_user.c ac/arch/um/drivers/ethertap_user.c
--- ac_cur/arch/um/drivers/ethertap_user.c	Mon Jun 25 13:30:40 2001
+++ ac/arch/um/drivers/ethertap_user.c	Mon Jun 25 13:34:27 2001
@@ -90,6 +90,28 @@
 	char addr[sizeof("255.255.255.255\0")], ether[6];
 
 	dev_ip_addr(pri->dev, addr, &ether[2]);
+	if(pri->gate_addr != NULL){
+		int uml_addr[4], tap_addr[4];
+		if(sscanf(addr, "%d.%d.%d.%d", &uml_addr[0], &uml_addr[1], 
+			  &uml_addr[2], &uml_addr[3]) != 4){
+			printk("Invalid UML IP address - '%s'\n", addr);
+			return(-EINVAL);
+		}
+		if(sscanf(pri->gate_addr, "%d.%d.%d.%d", &tap_addr[0], 
+			  &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){
+			printk("Invalid tap IP address - '%s'\n", 
+			       pri->gate_addr);
+			return(-EINVAL);
+		}
+		if((uml_addr[0] == tap_addr[0]) && 
+		   (uml_addr[1] == tap_addr[1]) && 
+		   (uml_addr[2] == tap_addr[2]) && 
+		   (uml_addr[3] == tap_addr[3])){
+			printk("The tap IP address and the UML eth IP address"
+			       " must be different\n");
+			return(-EINVAL);
+		}
+	}
 	if(!pri->hw_setup){
 		ether[0] = 0xfe;
 		ether[1] = 0xfd;
diff -Naur -X exclude-files ac_cur/arch/um/include/kern_util.h ac/arch/um/include/kern_util.h
--- ac_cur/arch/um/include/kern_util.h	Mon Jun 25 13:30:40 2001
+++ ac/arch/um/include/kern_util.h	Mon Jun 25 13:43:13 2001
@@ -116,6 +116,7 @@
 extern void *round_up(unsigned long addr);
 extern void *round_down(unsigned long addr);
 extern void bad_segv(unsigned long address, unsigned long ip, int is_write);
+extern void handling_signal(void *t);
 #endif
 
 /*
diff -Naur -X exclude-files ac_cur/arch/um/kernel/exec_kern.c ac/arch/um/kernel/exec_kern.c
--- ac_cur/arch/um/kernel/exec_kern.c	Mon Jun 25 13:30:40 2001
+++ ac/arch/um/kernel/exec_kern.c	Mon Jun 25 13:36:36 2001
@@ -76,7 +76,6 @@
 	stack_protections(stack + 2 * PAGE_SIZE, 2 * PAGE_SIZE);
 	force_flush_all();
 	check_brk(brk_start);
-	current->thread.mm_changes = 0;
 	unblock_signals();
 }
 
diff -Naur -X exclude-files ac_cur/arch/um/kernel/process_kern.c ac/arch/um/kernel/process_kern.c
--- ac_cur/arch/um/kernel/process_kern.c	Mon Jun 25 13:30:40 2001
+++ ac/arch/um/kernel/process_kern.c	Mon Jun 25 13:44:00 2001
@@ -236,7 +236,8 @@
 	if(task == NULL) task = current;
 	do_bh();
 	if(task->need_resched) schedule();
-	if((task->sigpending != 0) && (task->thread.npending == 0)){
+	if((task->sigpending != 0) && 
+	   (task->thread.signal.state == SIGNAL_NONE)){
 		block_signals();
 		do_signal(task, NULL, NULL);
 		unblock_signals();
@@ -621,13 +622,20 @@
 {
 }
 
+void handling_signal(void *t)
+{
+	struct task_struct *task = t;
+
+	task->thread.signal.state = SIGNAL_HANDLING;
+}
+
 int have_signals(void *t, int altstack)
 {
 	struct task_struct *task;
 
 	if(t == NULL) task = current;
 	else task = t;
-	if(task->thread.npending == 1){
+	if(task->thread.signal.state == SIGNAL_PENDING){
 		if((altstack && (task->thread.signal.sp != 0)) ||
 		    (!altstack && (task->thread.signal.sp == 0)))
 			return(1);
@@ -656,8 +664,9 @@
 void interrupt_end(void)
 {
 	if(current->need_resched) schedule();
-	if(current->thread.npending == 0) do_signal(current, NULL, NULL);
-	if(current->thread.npending > 0) 
+	if(current->thread.signal.state == SIGNAL_NONE)
+		do_signal(current, NULL, NULL);
+	if(current->thread.signal.state > SIGNAL_PENDING) 
 		probe_stack(UM_SP(&current->thread.process_regs));
 }
 
diff -Naur -X exclude-files ac_cur/arch/um/kernel/signal_kern.c ac/arch/um/kernel/signal_kern.c
--- ac_cur/arch/um/kernel/signal_kern.c	Mon Jun 25 13:30:40 2001
+++ ac/arch/um/kernel/signal_kern.c	Mon Jun 25 13:44:24 2001
@@ -102,7 +102,8 @@
 		spin_unlock_irq(&task->sigmask_lock);
 	}
 
-	if(task->thread.npending == 1) panic("Too many queued signals");
+	if(task->thread.signal.state != SIGNAL_NONE)
+		panic("Too many queued signals");
 	task->thread.signal.signal = signr;
 	task->thread.signal.sp = 0;
 	if (ka->sa.sa_flags & SA_ONSTACK) {
@@ -112,7 +113,7 @@
 	}
 
 	task->thread.signal.handler = (unsigned long) handler;
-	task->thread.npending = 1;
+	task->thread.signal.state = SIGNAL_PENDING;
 	task->thread.saved_sigs = save;
 
 	return(ret);
@@ -315,7 +316,7 @@
 	sigs = task->thread.saved_sigs;
 	signal = task->thread.signal.signal;
 	handler = task->thread.signal.handler;
-	task->thread.npending = 0;
+	task->thread.signal.state = SIGNAL_NONE;
 	signal_handler(task, handler, signal);
 	task->thread.process_regs = regs;
 	task->thread.repeat_syscall = repeat;
diff -Naur -X exclude-files ac_cur/arch/um/kernel/syscall_kern.c ac/arch/um/kernel/syscall_kern.c
--- ac_cur/arch/um/kernel/syscall_kern.c	Mon Jun 25 13:30:40 2001
+++ ac/arch/um/kernel/syscall_kern.c	Mon Jun 25 13:38:20 2001
@@ -304,8 +304,9 @@
 	int old_size = current->sas_ss_size, res;
 
 	res = do_sigaltstack(uss, uoss, UM_SP(&current->thread.process_regs));
-	if((res == 0) || (current->sas_ss_sp != old_sp) || 
-	   (current->sas_ss_size != old_size)){
+	if((res == 0) && (current->sas_ss_sp != 0) && 
+	   ((current->sas_ss_sp != old_sp) || 
+	    (current->sas_ss_size != old_size))){
 	        res = setup_altstack(current->sas_ss_sp, 
 				     current->sas_ss_size);
 	}
diff -Naur -X exclude-files ac_cur/arch/um/kernel/syscall_user.c ac/arch/um/kernel/syscall_user.c
--- ac_cur/arch/um/kernel/syscall_user.c	Mon Jun 25 13:30:40 2001
+++ ac/arch/um/kernel/syscall_user.c	Mon Jun 25 13:45:45 2001
@@ -106,14 +106,19 @@
 	again = get_repeat_syscall(task);
 	set_repeat_syscall(0);
 	restore = get_restore_regs(task);
+	regs = process_state(task, NULL, NULL);
 	if(restore){
-		regs = process_state(task, NULL, NULL);
 		if(ptrace_setregs(pid, regs) < 0)
 			tracer_panic("Couldn't restore registers");
 	}
-	if(have_signals(task, 0))
+	if(have_signals(task, 0)){
+		handling_signal(task);
+		if(!restore) ptrace_getregs(pid, regs);
 		*signal_out = SIGUSR2;
+	}
 	else if(have_signals(task, 1)){
+		handling_signal(task);
+		if(!restore) ptrace_getregs(pid, regs);
 		regs = altstack_state(task, &stack, &n);
 		if(ptrace_setregs(pid, regs) < 0)
 			panic("Couldn't set alternate stack state");
diff -Naur -X exclude-files ac_cur/include/asm-um/pgtable.h ac/include/asm-um/pgtable.h
--- ac_cur/include/asm-um/pgtable.h	Mon Jun 25 13:31:09 2001
+++ ac/include/asm-um/pgtable.h	Mon Jun 25 13:48:24 2001
@@ -82,10 +82,10 @@
  * memory. 
  */
 #define _PAGE_PRESENT	0x001
-#define _PAGE_RW	0x002
-#define _PAGE_USER	0x004
-#define _PAGE_PCD       0x008
-#define _PAGE_NEWPAGE	0x010
+#define _PAGE_NEWPAGE	0x002
+#define _PAGE_RW	0x004
+#define _PAGE_USER	0x008
+#define _PAGE_PCD       0x010
 #define _PAGE_ACCESSED	0x020
 #define _PAGE_DIRTY	0x040
 #define _PAGE_NEWPROT   0x100
@@ -163,9 +163,9 @@
 #define PAGE_PTR(address) \
 ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
 
-#define pte_none(x)	!(pte_val(x))
+#define pte_none(x)	!(pte_val(x) & ~_PAGE_NEWPAGE)
 #define pte_present(x)	(pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE))
-#define pte_clear(xp)	do { pte_val(*(xp)) = 0; } while (0)
+#define pte_clear(xp)	do { pte_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
 
 #define pmd_none(x)	(!(pmd_val(x) & ~_PAGE_NEWPAGE))
 #define	pmd_bad(x)	((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
@@ -351,9 +351,9 @@
 #define update_mmu_cache(vma,address,pte) do ; while (0)
 
 /* Encode and de-code a swap entry */
-#define SWP_TYPE(x)			(((x).val >> 1) & 0x3f)
-#define SWP_OFFSET(x)			((x).val >> 8)
-#define SWP_ENTRY(type, offset)		((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
+#define SWP_TYPE(x)			(((x).val >> 2) & 0x3f)
+#define SWP_OFFSET(x)			((x).val >> 9)
+#define SWP_ENTRY(type, offset)		((swp_entry_t) { ((type) << 2) | ((offset) << 9) })
 #define pte_to_swp_entry(pte)		((swp_entry_t) { pte_val(pte) })
 #define swp_entry_to_pte(x)		((pte_t) { (x).val })
 
diff -Naur -X exclude-files ac_cur/include/asm-um/processor.h ac/include/asm-um/processor.h
--- ac_cur/include/asm-um/processor.h	Mon Jun 25 13:31:09 2001
+++ ac/include/asm-um/processor.h	Mon Jun 25 13:48:24 2001
@@ -18,17 +18,21 @@
 
 #define current_text_addr() ((void *) 0)
 
+#define SIGNAL_NONE 0
+#define SIGNAL_PENDING 1
+#define SIGNAL_HANDLING 2
+
 struct thread_struct {
 	int extern_pid;
 	int tracing;
 	int forking;
 	unsigned long kernel_stack;
 	struct {
+		int state;
 		int signal;
 		unsigned long sp;
 		unsigned long handler;
 	} signal;
-	int npending;
 	sigset_t saved_sigs;
 	int nsyscalls;
 	struct sys_pt_regs process_regs;
@@ -39,7 +43,6 @@
 	unsigned long cr2;
 	int err;
 	int repeat_syscall;
-	int mm_changes;
 	void *fault_addr;
 	void *fault_catcher;
 	void *brk;
@@ -136,11 +139,11 @@
 	forking:	0, \
 	kernel_stack:	0, \
 	signal: { \
+                state:	SIGNAL_NONE, \
 		signal: 0, \
 		sp:	0, \
 		handler:0 \
 	}, \
-	npending:	0, \
         saved_sigs:     { { 0 } }, \
 	nsyscalls:	0, \
         process_regs:   EMPTY_REGS, \
@@ -151,7 +154,6 @@
 	cr2:		0, \
 	err:		0, \
 	repeat_syscall:	0, \
-        mm_changes:     0, \
 	fault_addr:	NULL, \
 	brk:		NULL, \
 	sigreturn_syscall: 0, \