--- 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;