--- fs/ext2/file.c.~1~	Mon Dec 21 23:22:54 1998
+++ fs/ext2/file.c	Tue Jan 12 17:46:33 1999
@@ -30,6 +30,7 @@
 #include <linux/locks.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
+#include <linux/smp_lock.h>
 
 #define	NBUF	32
 
@@ -257,7 +258,9 @@
 				break;
 			}
 		}
+		unlock_kernel();
 		c -= copy_from_user (bh->b_data + offset, buf, c);
+		lock_kernel();
 		if (!c) {
 			brelse(bh);
 			if (!written)
--- mm/filemap.c.~1~	Thu Jan  7 00:04:38 1999
+++ mm/filemap.c	Wed Jan 13 16:33:14 1999
@@ -212,10 +212,21 @@
 
 		if (len > count)
 			len = count;
+	retry:
 		page = find_page(inode, pos);
 		if (page) {
-			wait_on_page(page);
+			if (PageLocked(page)) {
+				wait_on_page(page);
+				release_page(page);
+				goto retry;
+			}
+			set_bit(PG_locked, &page->flags);
+			unlock_kernel();
 			memcpy((void *) (offset + page_address(page)), buf, len);
+			lock_kernel();
+			clear_bit(PG_locked, &page->flags);
+			if (waitqueue_active(&page->wait))
+				wake_up(&page->wait);
 			release_page(page);
 		}
 		count -= len;
@@ -753,7 +764,9 @@
 
 	if (size > count)
 		size = count;
+	unlock_kernel();
 	left = __copy_to_user(desc->buf, area, size);
+	lock_kernel();
 	if (left) {
 		size -= left;
 		desc->error = -EFAULT;
--- ./fs/pipe.c.~1~	Sun Jan  3 07:03:03 1999
+++ ./fs/pipe.c	Fri Jan 22 06:26:19 1999
@@ -7,6 +7,7 @@
 #include <linux/mm.h>
 #include <linux/file.h>
 #include <linux/poll.h>
+#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 
@@ -68,7 +69,9 @@ static ssize_t pipe_read(struct file * f
 		PIPE_START(*inode) &= (PIPE_BUF-1);
 		PIPE_LEN(*inode) -= chars;
 		count -= chars;
+		unlock_kernel();
 		copy_to_user(buf, pipebuf, chars );
+		lock_kernel();
 		buf += chars;
 	}
 	PIPE_LOCK(*inode)--;
@@ -134,7 +137,9 @@ static ssize_t pipe_write(struct file * 
 			written += chars;
 			PIPE_LEN(*inode) += chars;
 			count -= chars;
+			unlock_kernel();
 			copy_from_user(pipebuf, buf, chars );
+			lock_kernel();
 			buf += chars;
 		}
 		PIPE_LOCK(*inode)--;
--- ./mm/memory.c.~1~	Mon Jan 18 18:48:34 1999
+++ ./mm/memory.c	Fri Jan 22 05:42:08 1999
@@ -545,19 +545,6 @@ int remap_page_range(unsigned long from,
 }
 
 /*
- * sanity-check function..
- */
-static void put_page(pte_t * page_table, pte_t pte)
-{
-	if (!pte_none(*page_table)) {
-		free_page_and_swap_cache(pte_page(pte));
-		return;
-	}
-/* no need for flush_tlb */
-	set_pte(page_table, pte);
-}
-
-/*
  * This routine is used to map in a page into an address space: needed by
  * execve() for the initial stack and environment pages.
  */
@@ -817,7 +804,8 @@ static int do_anonymous_page(struct task
 		tsk->min_flt++;
 		flush_page_to_ram(page);
 	}
-	put_page(page_table, entry);
+	wmb();
+	set_pte(page_table, entry);
 	return 1;
 }
 
@@ -875,7 +863,8 @@ static int do_no_page(struct task_struct
 	} else if (atomic_read(&mem_map[MAP_NR(page)].count) > 1 &&
 		   !(vma->vm_flags & VM_SHARED))
 		entry = pte_wrprotect(entry);
-	put_page(page_table, entry);
+	wmb();
+	set_pte(page_table, entry);
 	/* no need to invalidate: a not-present page shouldn't be cached */
 	return 1;
 }
--- ./net/ipv4/tcp.c.~1~	Sat Jan  9 03:20:07 1999
+++ ./net/ipv4/tcp.c	Fri Jan 22 06:26:32 1999
@@ -415,6 +415,7 @@
 #include <linux/types.h>
 #include <linux/fcntl.h>
 #include <linux/poll.h>
+#include <linux/smp_lock.h>
 #include <linux/init.h>
 
 #include <net/icmp.h>
@@ -891,6 +892,8 @@ int tcp_do_sendmsg(struct sock *sk, int 
 				continue;
 			}
 
+			unlock_kernel();
+
 			seglen -= copy;
 
 			/* Prepare control bits for TCP header creation engine. */
@@ -909,8 +912,10 @@ int tcp_do_sendmsg(struct sock *sk, int 
 			 * Reserve header space and checksum the data.
 			 */
 			skb_reserve(skb, MAX_HEADER + sk->prot->max_header);
+
 			skb->csum = csum_and_copy_from_user(from,
 					skb_put(skb, copy), copy, 0, &err);
+			lock_kernel();
 
 			if (err)
 				goto do_fault;
@@ -1261,7 +1266,11 @@ int tcp_recvmsg(struct sock *sk, struct 
 		 *	do a second read it relies on the skb->users to avoid
 		 *	a crash when cleanup_rbuf() gets called.
 		 */
+
+		unlock_kernel();
 		err = memcpy_toiovec(msg->msg_iov, ((unsigned char *)skb->h.th) + skb->h.th->doff*4 + offset, used);
+		lock_kernel();
+
 		if (err) {
 			/* Exception. Bailout! */
 			atomic_dec(&skb->users);
--- ./net/ipv4/udp.c.~1~	Sun Jan  3 07:56:15 1999
+++ ./net/ipv4/udp.c	Fri Jan 22 08:08:06 1999
@@ -105,6 +105,7 @@
 #include <linux/config.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
+#include <linux/smp_lock.h>
 #include <net/snmp.h>
 #include <net/ip.h>
 #include <net/protocol.h>
@@ -585,10 +586,14 @@ struct udpfakehdr 
 static int udp_getfrag(const void *p, char * to, unsigned int offset, unsigned int fraglen) 
 {
 	struct udpfakehdr *ufh = (struct udpfakehdr *)p;
+	int err = 0;
+
+	unlock_kernel();
 	if (offset==0) {
+		err = -EFAULT;
 		if (csum_partial_copy_fromiovecend(to+sizeof(struct udphdr), ufh->iov, offset,
 						   fraglen-sizeof(struct udphdr), &ufh->wcheck))
-			return -EFAULT;
+			goto out;
  		ufh->wcheck = csum_partial((char *)ufh, sizeof(struct udphdr),
 					   ufh->wcheck);
 		ufh->uh.check = csum_tcpudp_magic(ufh->saddr, ufh->daddr, 
@@ -597,12 +602,14 @@ static int udp_getfrag(const void *p, ch
 		if (ufh->uh.check == 0)
 			ufh->uh.check = -1;
 		memcpy(to, ufh, sizeof(struct udphdr));
-		return 0;
-	}
-	if (csum_partial_copy_fromiovecend(to, ufh->iov, offset-sizeof(struct udphdr),
-					   fraglen, &ufh->wcheck))
-		return -EFAULT;
-	return 0;
+		err = 0;
+	} else if (csum_partial_copy_fromiovecend(to, ufh->iov,
+						  offset-sizeof(struct udphdr),
+						  fraglen, &ufh->wcheck))
+		err = -EFAULT;
+out:
+	lock_kernel();
+	return err;
 }
 
 /*
@@ -615,14 +622,19 @@ static int udp_getfrag(const void *p, ch
 static int udp_getfrag_nosum(const void *p, char * to, unsigned int offset, unsigned int fraglen) 
 {
 	struct udpfakehdr *ufh = (struct udpfakehdr *)p;
+	int ret;
 
+	unlock_kernel();
 	if (offset==0) {
 		memcpy(to, ufh, sizeof(struct udphdr));
-		return memcpy_fromiovecend(to+sizeof(struct udphdr), ufh->iov, offset,
-					   fraglen-sizeof(struct udphdr));
-	}
-	return memcpy_fromiovecend(to, ufh->iov, offset-sizeof(struct udphdr),
-				   fraglen);
+		ret = memcpy_fromiovecend(to+sizeof(struct udphdr), ufh->iov, offset,
+					  fraglen-sizeof(struct udphdr));
+	} else
+		ret = memcpy_fromiovecend(to, ufh->iov, offset-sizeof(struct udphdr),
+					  fraglen);
+	lock_kernel();
+
+	return ret;
 }
 
 int udp_sendmsg(struct sock *sk, struct msghdr *msg, int len)
@@ -887,24 +899,32 @@ int udp_recvmsg(struct sock *sk, struct 
 	}
 
 #ifndef CONFIG_UDP_DELAY_CSUM
+	unlock_kernel();
 	err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
 					copied);
+	lock_kernel();
 #else
 	if (sk->no_check || skb->ip_summed==CHECKSUM_UNNECESSARY) {
+		unlock_kernel();
 		err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
 					      copied);
+		lock_kernel();
 	} else if (copied > msg->msg_iov[0].iov_len || (msg->msg_flags&MSG_TRUNC)) {
 		if (csum_fold(csum_partial(skb->h.raw, ntohs(skb->h.uh->len), skb->csum))) 
 			goto csum_copy_err;
+		unlock_kernel();
 		err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
 					      copied);
+		lock_kernel();
 	} else {
 		unsigned int csum;
 
 		err = 0;
+		unlock_kernel();
 		csum = csum_partial(skb->h.raw, sizeof(struct udphdr), skb->csum);
 		csum = csum_and_copy_to_user((char*)&skb->h.uh[1], msg->msg_iov[0].iov_base, 
 					     copied, csum, &err);
+		lock_kernel();
 		if (err)
 			goto out_free;
 		if (csum_fold(csum)) 
--- ./net/unix/af_unix.c.~1~	Thu Jan 14 22:54:23 1999
+++ ./net/unix/af_unix.c	Fri Jan 22 06:26:45 1999
@@ -93,6 +93,7 @@
 #include <net/scm.h>
 #include <linux/init.h>
 #include <linux/poll.h>
+#include <linux/smp_lock.h>
 
 #include <asm/checksum.h>
 
@@ -936,7 +937,11 @@ static int unix_dgram_sendmsg(struct soc
 		unix_attach_fds(scm, skb);
 
 	skb->h.raw = skb->data;
+
+	unlock_kernel();
 	err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
+	lock_kernel();
+
 	if (err)
 		goto out_free;
 
@@ -1068,11 +1073,19 @@ static int unix_stream_sendmsg(struct so
 		if (scm->fp)
 			unix_attach_fds(scm, skb);
 
-		if (memcpy_fromiovec(skb_put(skb,size), msg->msg_iov, size)) {
-			kfree_skb(skb);
-			if (sent)
-				goto out;
-			return -EFAULT;
+		{
+			int err;
+
+			unlock_kernel();
+			err = memcpy_fromiovec(skb_put(skb,size), msg->msg_iov, size);
+			lock_kernel();
+
+			if(err) {
+				kfree_skb(skb);
+				if (sent)
+					goto out;
+				return -EFAULT;
+			}
 		}
 
 		other=unix_peer(sk);
@@ -1143,7 +1156,10 @@ static int unix_dgram_recvmsg(struct soc
 	else if (size < skb->len)
 		msg->msg_flags |= MSG_TRUNC;
 
+	unlock_kernel();
 	err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size);
+	lock_kernel();
+
 	if (err)
 		goto out_free;
 
@@ -1263,11 +1279,19 @@ static int unix_stream_recvmsg(struct so
 		}
 
 		chunk = min(skb->len, size);
-		if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
-			skb_queue_head(&sk->receive_queue, skb);
-			if (copied == 0)
-				copied = -EFAULT;
-			break;
+		{
+			int err;
+
+			unlock_kernel();
+			err = memcpy_toiovec(msg->msg_iov, skb->data, chunk);
+			lock_kernel();
+
+			if(err) {
+				skb_queue_head(&sk->receive_queue, skb);
+				if (copied == 0)
+					copied = -EFAULT;
+				break;
+			}
 		}
 		copied += chunk;
 		size -= chunk;
