Whamcloud - gitweb
smash the HEAD with the contents of b_cmd. HEAD_PRE_CMD_SMASH and
[fs/lustre-release.git] / lustre / kernel_patches / patches / uml-patch-2.6.0-1.patch
1 diff -Naur a/arch/um/config.release b/arch/um/config.release
2 --- a/arch/um/config.release    2004-01-08 22:31:37.000000000 -0500
3 +++ b/arch/um/config.release    2004-01-08 22:36:18.000000000 -0500
4 @@ -228,7 +228,6 @@
5  CONFIG_EXT2_FS=y
6  CONFIG_SYSV_FS=m
7  CONFIG_UDF_FS=m
8 -# CONFIG_UDF_RW is not set
9  CONFIG_UFS_FS=m
10  # CONFIG_UFS_FS_WRITE is not set
11  
12 diff -Naur a/arch/um/defconfig b/arch/um/defconfig
13 --- a/arch/um/defconfig 2004-01-08 22:24:41.000000000 -0500
14 +++ b/arch/um/defconfig 2004-01-08 22:32:17.000000000 -0500
15 @@ -3,29 +3,19 @@
16  #
17  CONFIG_USERMODE=y
18  CONFIG_MMU=y
19 -CONFIG_SWAP=y
20  CONFIG_UID16=y
21  CONFIG_RWSEM_GENERIC_SPINLOCK=y
22 -CONFIG_CONFIG_LOG_BUF_SHIFT=14
23  
24  #
25 -# Code maturity level options
26 -#
27 -CONFIG_EXPERIMENTAL=y
28 -
29 -#
30 -# General Setup
31 +# UML-specific options
32  #
33  CONFIG_MODE_TT=y
34  CONFIG_MODE_SKAS=y
35  CONFIG_NET=y
36 -CONFIG_SYSVIPC=y
37 -CONFIG_BSD_PROCESS_ACCT=y
38 -CONFIG_SYSCTL=y
39 -CONFIG_BINFMT_AOUT=y
40  CONFIG_BINFMT_ELF=y
41  CONFIG_BINFMT_MISC=y
42  CONFIG_HOSTFS=y
43 +CONFIG_HPPFS=y
44  CONFIG_MCONSOLE=y
45  CONFIG_MAGIC_SYSRQ=y
46  # CONFIG_HOST_2G_2G is not set
47 @@ -36,12 +26,41 @@
48  # CONFIG_HIGHMEM is not set
49  CONFIG_PROC_MM=y
50  CONFIG_KERNEL_STACK_ORDER=2
51 +CONFIG_UML_REAL_TIME_CLOCK=y
52 +
53 +#
54 +# Code maturity level options
55 +#
56 +CONFIG_EXPERIMENTAL=y
57 +CONFIG_CLEAN_COMPILE=y
58 +CONFIG_STANDALONE=y
59 +CONFIG_BROKEN_ON_SMP=y
60 +
61 +#
62 +# General setup
63 +#
64 +CONFIG_SWAP=y
65 +CONFIG_SYSVIPC=y
66 +CONFIG_BSD_PROCESS_ACCT=y
67 +CONFIG_SYSCTL=y
68 +CONFIG_LOG_BUF_SHIFT=14
69 +# CONFIG_IKCONFIG is not set
70 +# CONFIG_EMBEDDED is not set
71 +CONFIG_KALLSYMS=y
72 +CONFIG_FUTEX=y
73 +CONFIG_EPOLL=y
74 +CONFIG_IOSCHED_NOOP=y
75 +CONFIG_IOSCHED_AS=y
76 +CONFIG_IOSCHED_DEADLINE=y
77  
78  #
79  # Loadable module support
80  #
81 -CONFIG_MODULES=y
82 -# CONFIG_KMOD is not set
83 +# CONFIG_MODULES is not set
84 +
85 +#
86 +# Generic Driver Options
87 +#
88  
89  #
90  # Character Devices
91 @@ -69,6 +88,7 @@
92  #
93  CONFIG_BLK_DEV_UBD=y
94  # CONFIG_BLK_DEV_UBD_SYNC is not set
95 +CONFIG_BLK_DEV_COW_COMMON=y
96  CONFIG_BLK_DEV_LOOP=y
97  CONFIG_BLK_DEV_NBD=y
98  CONFIG_BLK_DEV_RAM=y
99 @@ -78,7 +98,7 @@
100  CONFIG_NETDEVICES=y
101  
102  #
103 -# Network Devices
104 +# UML Network Devices
105  #
106  CONFIG_UML_NET=y
107  CONFIG_UML_NET_ETHERTAP=y
108 @@ -88,22 +108,6 @@
109  CONFIG_UML_NET_MCAST=y
110  # CONFIG_UML_NET_PCAP is not set
111  CONFIG_UML_NET_SLIRP=y
112 -CONFIG_DUMMY=y
113 -# CONFIG_BONDING is not set
114 -# CONFIG_EQUALIZER is not set
115 -CONFIG_TUN=y
116 -# CONFIG_ETHERTAP is not set
117 -CONFIG_PPP=y
118 -# CONFIG_PPP_MULTILINK is not set
119 -# CONFIG_PPP_ASYNC is not set
120 -# CONFIG_PPP_SYNC_TTY is not set
121 -# CONFIG_PPP_DEFLATE is not set
122 -# CONFIG_PPP_BSDCOMP is not set
123 -# CONFIG_PPPOE is not set
124 -CONFIG_SLIP=y
125 -# CONFIG_SLIP_COMPRESSED is not set
126 -# CONFIG_SLIP_SMART is not set
127 -# CONFIG_SLIP_MODE_SLIP6 is not set
128  
129  #
130  # Networking support
131 @@ -115,8 +119,6 @@
132  CONFIG_PACKET=y
133  CONFIG_PACKET_MMAP=y
134  # CONFIG_NETLINK_DEV is not set
135 -# CONFIG_NETFILTER is not set
136 -# CONFIG_FILTER is not set
137  CONFIG_UNIX=y
138  # CONFIG_NET_KEY is not set
139  CONFIG_INET=y
140 @@ -130,8 +132,11 @@
141  # CONFIG_SYN_COOKIES is not set
142  # CONFIG_INET_AH is not set
143  # CONFIG_INET_ESP is not set
144 -# CONFIG_XFRM_USER is not set
145 +# CONFIG_INET_IPCOMP is not set
146  # CONFIG_IPV6 is not set
147 +# CONFIG_DECNET is not set
148 +# CONFIG_BRIDGE is not set
149 +# CONFIG_NETFILTER is not set
150  
151  #
152  # SCTP Configuration (EXPERIMENTAL)
153 @@ -140,9 +145,9 @@
154  # CONFIG_IP_SCTP is not set
155  # CONFIG_ATM is not set
156  # CONFIG_VLAN_8021Q is not set
157 -# CONFIG_LLC is not set
158 -# CONFIG_DECNET is not set
159 -# CONFIG_BRIDGE is not set
160 +# CONFIG_LLC2 is not set
161 +# CONFIG_IPX is not set
162 +# CONFIG_ATALK is not set
163  # CONFIG_X25 is not set
164  # CONFIG_LAPB is not set
165  # CONFIG_NET_DIVERT is not set
166 @@ -160,6 +165,10 @@
167  # Network testing
168  #
169  # CONFIG_NET_PKTGEN is not set
170 +CONFIG_DUMMY=y
171 +# CONFIG_BONDING is not set
172 +# CONFIG_EQUALIZER is not set
173 +CONFIG_TUN=y
174  
175  #
176  # Ethernet (10 or 100Mbit)
177 @@ -171,12 +180,28 @@
178  #
179  
180  #
181 +# Ethernet (10000 Mbit)
182 +#
183 +CONFIG_PPP=y
184 +# CONFIG_PPP_MULTILINK is not set
185 +# CONFIG_PPP_FILTER is not set
186 +# CONFIG_PPP_ASYNC is not set
187 +# CONFIG_PPP_SYNC_TTY is not set
188 +# CONFIG_PPP_DEFLATE is not set
189 +# CONFIG_PPP_BSDCOMP is not set
190 +# CONFIG_PPPOE is not set
191 +CONFIG_SLIP=y
192 +# CONFIG_SLIP_COMPRESSED is not set
193 +# CONFIG_SLIP_SMART is not set
194 +# CONFIG_SLIP_MODE_SLIP6 is not set
195 +
196 +#
197  # Wireless LAN (non-hamradio)
198  #
199  # CONFIG_NET_RADIO is not set
200  
201  #
202 -# Token Ring devices (depends on LLC=y)
203 +# Token Ring devices
204  #
205  # CONFIG_SHAPER is not set
206  
207 @@ -186,68 +211,101 @@
208  # CONFIG_WAN is not set
209  
210  #
211 +# Amateur Radio support
212 +#
213 +# CONFIG_HAMRADIO is not set
214 +
215 +#
216 +# IrDA (infrared) support
217 +#
218 +# CONFIG_IRDA is not set
219 +
220 +#
221 +# Bluetooth support
222 +#
223 +# CONFIG_BT is not set
224 +
225 +#
226  # File systems
227  #
228 +CONFIG_EXT2_FS=y
229 +# CONFIG_EXT2_FS_XATTR is not set
230 +# CONFIG_EXT3_FS is not set
231 +# CONFIG_JBD is not set
232 +CONFIG_REISERFS_FS=y
233 +# CONFIG_REISERFS_CHECK is not set
234 +# CONFIG_REISERFS_PROC_INFO is not set
235 +# CONFIG_JFS_FS is not set
236 +# CONFIG_XFS_FS is not set
237 +CONFIG_MINIX_FS=y
238 +# CONFIG_ROMFS_FS is not set
239  CONFIG_QUOTA=y
240  # CONFIG_QFMT_V1 is not set
241  # CONFIG_QFMT_V2 is not set
242  CONFIG_QUOTACTL=y
243 -CONFIG_AUTOFS_FS=m
244 -CONFIG_AUTOFS4_FS=m
245 -CONFIG_REISERFS_FS=m
246 -# CONFIG_REISERFS_CHECK is not set
247 -# CONFIG_REISERFS_PROC_INFO is not set
248 +CONFIG_AUTOFS_FS=y
249 +CONFIG_AUTOFS4_FS=y
250 +
251 +#
252 +# CD-ROM/DVD Filesystems
253 +#
254 +CONFIG_ISO9660_FS=y
255 +# CONFIG_JOLIET is not set
256 +# CONFIG_ZISOFS is not set
257 +# CONFIG_UDF_FS is not set
258 +
259 +#
260 +# DOS/FAT/NT Filesystems
261 +#
262 +CONFIG_FAT_FS=y
263 +CONFIG_MSDOS_FS=y
264 +CONFIG_VFAT_FS=y
265 +# CONFIG_NTFS_FS is not set
266 +
267 +#
268 +# Pseudo filesystems
269 +#
270 +CONFIG_PROC_FS=y
271 +CONFIG_PROC_KCORE=y
272 +CONFIG_DEVFS_FS=y
273 +CONFIG_DEVFS_MOUNT=y
274 +# CONFIG_DEVFS_DEBUG is not set
275 +CONFIG_DEVPTS_FS=y
276 +# CONFIG_DEVPTS_FS_XATTR is not set
277 +# CONFIG_TMPFS is not set
278 +# CONFIG_HUGETLB_PAGE is not set
279 +CONFIG_RAMFS=y
280 +
281 +#
282 +# Miscellaneous filesystems
283 +#
284  # CONFIG_ADFS_FS is not set
285  # CONFIG_AFFS_FS is not set
286  # CONFIG_HFS_FS is not set
287  # CONFIG_BEFS_FS is not set
288  # CONFIG_BFS_FS is not set
289 -# CONFIG_EXT3_FS is not set
290 -# CONFIG_JBD is not set
291 -CONFIG_FAT_FS=m
292 -CONFIG_MSDOS_FS=m
293 -CONFIG_VFAT_FS=m
294  # CONFIG_EFS_FS is not set
295  CONFIG_JFFS_FS=y
296  CONFIG_JFFS_FS_VERBOSE=0
297 -CONFIG_JFFS_PROC_FS=y
298  # CONFIG_JFFS2_FS is not set
299  # CONFIG_CRAMFS is not set
300 -# CONFIG_TMPFS is not set
301 -CONFIG_RAMFS=y
302 -CONFIG_ISO9660_FS=m
303 -# CONFIG_JOLIET is not set
304 -# CONFIG_ZISOFS is not set
305 -# CONFIG_JFS_FS is not set
306 -CONFIG_MINIX_FS=m
307  # CONFIG_VXFS_FS is not set
308 -# CONFIG_NTFS_FS is not set
309  # CONFIG_HPFS_FS is not set
310 -CONFIG_PROC_FS=y
311 -CONFIG_DEVFS_FS=y
312 -CONFIG_DEVFS_MOUNT=y
313 -# CONFIG_DEVFS_DEBUG is not set
314 -CONFIG_DEVPTS_FS=y
315  # CONFIG_QNX4FS_FS is not set
316 -# CONFIG_ROMFS_FS is not set
317 -CONFIG_EXT2_FS=y
318 -# CONFIG_EXT2_FS_XATTR is not set
319  # CONFIG_SYSV_FS is not set
320 -# CONFIG_UDF_FS is not set
321  # CONFIG_UFS_FS is not set
322 -# CONFIG_XFS_FS is not set
323  
324  #
325  # Network File Systems
326  #
327 -# CONFIG_CODA_FS is not set
328 -# CONFIG_INTERMEZZO_FS is not set
329  # CONFIG_NFS_FS is not set
330  # CONFIG_NFSD is not set
331  # CONFIG_EXPORTFS is not set
332 -# CONFIG_CIFS is not set
333  # CONFIG_SMB_FS is not set
334 +# CONFIG_CIFS is not set
335  # CONFIG_NCP_FS is not set
336 +# CONFIG_CODA_FS is not set
337 +# CONFIG_INTERMEZZO_FS is not set
338  # CONFIG_AFS_FS is not set
339  
340  #
341 @@ -317,28 +375,7 @@
342  #
343  # SCSI support
344  #
345 -CONFIG_SCSI=y
346 -CONFIG_GENERIC_ISA_DMA=y
347 -
348 -#
349 -# SCSI support type (disk, tape, CD-ROM)
350 -#
351 -CONFIG_BLK_DEV_SD=y
352 -CONFIG_SD_EXTRA_DEVS=40
353 -CONFIG_CHR_DEV_ST=y
354 -CONFIG_BLK_DEV_SR=y
355 -CONFIG_BLK_DEV_SR_VENDOR=y
356 -CONFIG_SR_EXTRA_DEVS=2
357 -CONFIG_CHR_DEV_SG=y
358 -
359 -#
360 -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
361 -#
362 -CONFIG_SCSI_DEBUG_QUEUES=y
363 -CONFIG_SCSI_MULTI_LUN=y
364 -CONFIG_SCSI_CONSTANTS=y
365 -CONFIG_SCSI_LOGGING=y
366 -CONFIG_SCSI_DEBUG=y
367 +# CONFIG_SCSI is not set
368  
369  #
370  # Multi-device support (RAID and LVM)
371 @@ -360,6 +397,7 @@
372  CONFIG_MTD_BLOCK=y
373  # CONFIG_FTL is not set
374  # CONFIG_NFTL is not set
375 +# CONFIG_INFTL is not set
376  
377  #
378  # RAM/ROM/Flash chip drivers
379 @@ -374,20 +412,21 @@
380  #
381  # Mapping drivers for chip access
382  #
383 +# CONFIG_MTD_COMPLEX_MAPPINGS is not set
384  
385  #
386  # Self-contained MTD device drivers
387  #
388  # CONFIG_MTD_SLRAM is not set
389  # CONFIG_MTD_MTDRAM is not set
390 -CONFIG_MTD_BLKMTD=m
391 +CONFIG_MTD_BLKMTD=y
392  
393  #
394  # Disk-On-Chip Device Drivers
395  #
396 -# CONFIG_MTD_DOC1000 is not set
397  # CONFIG_MTD_DOC2000 is not set
398  # CONFIG_MTD_DOC2001 is not set
399 +# CONFIG_MTD_DOC2001PLUS is not set
400  
401  #
402  # NAND Flash Device Drivers
403 diff -Naur a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
404 --- a/arch/um/drivers/chan_kern.c       2004-01-08 22:32:12.000000000 -0500
405 +++ b/arch/um/drivers/chan_kern.c       2004-01-08 22:36:26.000000000 -0500
406 @@ -8,6 +8,7 @@
407  #include <linux/list.h>
408  #include <linux/slab.h>
409  #include <linux/tty.h>
410 +#include <linux/string.h>
411  #include <linux/tty_flip.h>
412  #include <asm/irq.h>
413  #include "chan_kern.h"
414 @@ -265,6 +266,11 @@
415  {
416         int n = 0;
417  
418 +       if(chan == NULL){
419 +               CONFIG_CHUNK(str, size, n, "none", 1);
420 +               return(n);
421 +       }
422 +
423         CONFIG_CHUNK(str, size, n, chan->ops->type, 0);
424  
425         if(chan->dev == NULL){
426 @@ -420,7 +426,8 @@
427                 INIT_LIST_HEAD(chans);
428         }
429  
430 -       if((out = strchr(str, ',')) != NULL){
431 +       out = strchr(str, ',');
432 +       if(out != NULL){
433                 in = str;
434                 *out = '\0';
435                 out++;
436 @@ -475,12 +482,15 @@
437                                 goto out;
438                         }
439                         err = chan->ops->read(chan->fd, &c, chan->data);
440 -                       if(err > 0) tty_receive_char(tty, c);
441 +                       if(err > 0) 
442 +                               tty_receive_char(tty, c);
443                 } while(err > 0);
444 +
445                 if(err == 0) reactivate_fd(chan->fd, irq);
446                 if(err == -EIO){
447                         if(chan->primary){
448 -                               if(tty != NULL) tty_hangup(tty);
449 +                               if(tty != NULL) 
450 +                                       tty_hangup(tty);
451                                 line_disable(dev, irq);
452                                 close_chan(chans);
453                                 free_chan(chans);
454 diff -Naur a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
455 --- a/arch/um/drivers/chan_user.c       2004-01-08 22:13:40.000000000 -0500
456 +++ b/arch/um/drivers/chan_user.c       2004-01-08 22:17:53.000000000 -0500
457 @@ -1,5 +1,5 @@
458  /* 
459 - * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
460 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
461   * Licensed under the GPL
462   */
463  
464 @@ -7,7 +7,6 @@
465  #include <stdlib.h>
466  #include <errno.h>
467  #include <termios.h>
468 -#include <fcntl.h>
469  #include <string.h>
470  #include <signal.h>
471  #include <sys/stat.h>
472 @@ -24,29 +23,27 @@
473  
474  void generic_close(int fd, void *unused)
475  {
476 -       close(fd);
477 +       os_close_file(fd);
478  }
479  
480  int generic_read(int fd, char *c_out, void *unused)
481  {
482         int n;
483  
484 -       n = read(fd, c_out, sizeof(*c_out));
485 -       if(n < 0){
486 -               if(errno == EAGAIN) return(0);
487 -               return(-errno);
488 -       }
489 -       else if(n == 0) return(-EIO);
490 -       return(1);
491 +       n = os_read_file(fd, c_out, sizeof(*c_out));
492 +
493 +       if(n == -EAGAIN) 
494 +               return(0);
495 +       else if(n == 0) 
496 +               return(-EIO);
497 +       return(n);
498  }
499  
500 +/* XXX Trivial wrapper around os_write_file */
501 +
502  int generic_write(int fd, const char *buf, int n, void *unused)
503  {
504 -       int count;
505 -
506 -       count = write(fd, buf, n);
507 -       if(count < 0) return(-errno);
508 -       return(count);
509 +       return(os_write_file(fd, buf, n));
510  }
511  
512  int generic_console_write(int fd, const char *buf, int n, void *unused)
513 @@ -68,15 +65,18 @@
514  int generic_window_size(int fd, void *unused, unsigned short *rows_out,
515                         unsigned short *cols_out)
516  {
517 -       struct winsize size;
518 -       int ret = 0;
519 +       int rows, cols;
520 +       int ret;
521 +
522 +       ret = os_window_size(fd, &rows, &cols);
523 +       if(ret < 0)
524 +               return(ret);
525 +
526 +       ret = ((*rows_out != rows) || (*cols_out != cols));
527 +
528 +       *rows_out = rows;
529 +       *cols_out = cols;
530  
531 -       if(ioctl(fd, TIOCGWINSZ, &size) == 0){
532 -               ret = ((*rows_out != size.ws_row) || 
533 -                      (*cols_out != size.ws_col));
534 -               *rows_out = size.ws_row;
535 -               *cols_out = size.ws_col;
536 -       }
537         return(ret);
538  }
539  
540 @@ -100,14 +100,16 @@
541         struct winch_data *data = arg;
542         sigset_t sigs;
543         int pty_fd, pipe_fd;
544 +       int count, err;
545         char c = 1;
546  
547 -       close(data->close_me);
548 +       os_close_file(data->close_me);
549         pty_fd = data->pty_fd;
550         pipe_fd = data->pipe_fd;
551 -       if(write(pipe_fd, &c, sizeof(c)) != sizeof(c))
552 +       count = os_write_file(pipe_fd, &c, sizeof(c));
553 +       if(count != sizeof(c))
554                 printk("winch_thread : failed to write synchronization "
555 -                      "byte, errno = %d\n", errno);
556 +                      "byte, err = %d\n", -count);
557  
558         signal(SIGWINCH, winch_handler);
559         sigfillset(&sigs);
560 @@ -123,26 +125,24 @@
561                 exit(1);
562         }
563  
564 -       if(ioctl(pty_fd, TIOCSCTTY, 0) < 0){
565 -               printk("winch_thread : TIOCSCTTY failed, errno = %d\n", errno);
566 -               exit(1);
567 -       }
568 -       if(tcsetpgrp(pty_fd, os_getpid()) < 0){
569 -               printk("winch_thread : tcsetpgrp failed, errno = %d\n", errno);
570 +       err = os_new_tty_pgrp(pty_fd, os_getpid());
571 +       if(err < 0){
572 +               printk("winch_thread : new_tty_pgrp failed, err = %d\n", -err);
573                 exit(1);
574         }
575  
576 -       if(read(pipe_fd, &c, sizeof(c)) != sizeof(c))
577 +       count = os_read_file(pipe_fd, &c, sizeof(c));
578 +       if(count != sizeof(c))
579                 printk("winch_thread : failed to read synchronization byte, "
580 -                      "errno = %d\n", errno);
581 +                      "err = %d\n", -count);
582  
583         while(1){
584                 pause();
585  
586 -               if(write(pipe_fd, &c, sizeof(c)) != sizeof(c)){
587 -                       printk("winch_thread : write failed, errno = %d\n",
588 -                              errno);
589 -               }
590 +               count = os_write_file(pipe_fd, &c, sizeof(c));
591 +               if(count != sizeof(c))
592 +                       printk("winch_thread : write failed, err = %d\n",
593 +                              -count);
594         }
595  }
596  
597 @@ -154,8 +154,8 @@
598         char c;
599  
600         err = os_pipe(fds, 1, 1);
601 -       if(err){
602 -               printk("winch_tramp : os_pipe failed, errno = %d\n", -err);
603 +       if(err < 0){
604 +               printk("winch_tramp : os_pipe failed, err = %d\n", -err);
605                 return(err);
606         }
607  
608 @@ -168,12 +168,12 @@
609                 return(pid);
610         }
611  
612 -       close(fds[1]);
613 +       os_close_file(fds[1]);
614         *fd_out = fds[0];
615 -       n = read(fds[0], &c, sizeof(c));
616 +       n = os_read_file(fds[0], &c, sizeof(c));
617         if(n != sizeof(c)){
618                 printk("winch_tramp : failed to read synchronization byte\n");
619 -               printk("read returned %d, errno = %d\n", n, errno);
620 +               printk("read failed, err = %d\n", -n);
621                 printk("fd %d will not support SIGWINCH\n", fd);
622                 *fd_out = -1;
623         }
624 @@ -183,20 +183,24 @@
625  void register_winch(int fd, void *device_data)
626  {
627         int pid, thread, thread_fd;
628 +       int count;
629         char c = 1;
630  
631 -       if(!isatty(fd)) return;
632 +       if(!isatty(fd)) 
633 +               return;
634  
635         pid = tcgetpgrp(fd);
636 -       if(!CHOOSE_MODE(is_tracer_winch(pid, fd, device_data), 0) && 
637 -          (pid == -1)){
638 +       if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, 
639 +                            device_data) && (pid == -1)){
640                 thread = winch_tramp(fd, device_data, &thread_fd);
641                 if(fd != -1){
642                         register_winch_irq(thread_fd, fd, thread, device_data);
643  
644 -                       if(write(thread_fd, &c, sizeof(c)) != sizeof(c))
645 +                       count = os_write_file(thread_fd, &c, sizeof(c));
646 +                       if(count != sizeof(c))
647                                 printk("register_winch : failed to write "
648 -                                      "synchronization byte\n");
649 +                                      "synchronization byte, err = %d\n",
650 +                                       -count);
651                 }
652         }
653  }
654 diff -Naur a/arch/um/drivers/cow.h b/arch/um/drivers/cow.h
655 --- a/arch/um/drivers/cow.h     1969-12-31 19:00:00.000000000 -0500
656 +++ b/arch/um/drivers/cow.h     2004-01-08 22:20:48.000000000 -0500
657 @@ -0,0 +1,41 @@
658 +#ifndef __COW_H__
659 +#define __COW_H__
660 +
661 +#include <asm/types.h>
662 +
663 +#if __BYTE_ORDER == __BIG_ENDIAN
664 +# define ntohll(x) (x)
665 +# define htonll(x) (x)
666 +#elif __BYTE_ORDER == __LITTLE_ENDIAN
667 +# define ntohll(x)  bswap_64(x)
668 +# define htonll(x)  bswap_64(x)
669 +#else
670 +#error "__BYTE_ORDER not defined"
671 +#endif
672 +
673 +extern int init_cow_file(int fd, char *cow_file, char *backing_file, 
674 +                        int sectorsize, int alignment, int *bitmap_offset_out, 
675 +                        unsigned long *bitmap_len_out, int *data_offset_out);
676 +
677 +extern int file_reader(__u64 offset, char *buf, int len, void *arg);
678 +extern int read_cow_header(int (*reader)(__u64, char *, int, void *), 
679 +                          void *arg, __u32 *version_out, 
680 +                          char **backing_file_out, time_t *mtime_out, 
681 +                          __u64 *size_out, int *sectorsize_out, 
682 +                          __u32 *align_out, int *bitmap_offset_out);
683 +
684 +extern int write_cow_header(char *cow_file, int fd, char *backing_file, 
685 +                           int sectorsize, int alignment, long long *size);
686 +
687 +extern void cow_sizes(int version, __u64 size, int sectorsize, int align,
688 +                     int bitmap_offset, unsigned long *bitmap_len_out, 
689 +                     int *data_offset_out);
690 +
691 +#endif
692 +
693 +/*
694 + * ---------------------------------------------------------------------------
695 + * Local variables:
696 + * c-file-style: "linux"
697 + * End:
698 + */
699 diff -Naur a/arch/um/drivers/cow_kern.c b/arch/um/drivers/cow_kern.c
700 --- a/arch/um/drivers/cow_kern.c        1969-12-31 19:00:00.000000000 -0500
701 +++ b/arch/um/drivers/cow_kern.c        2004-01-08 22:36:26.000000000 -0500
702 @@ -0,0 +1,630 @@
703 +#define COW_MAJOR 60
704 +#define MAJOR_NR COW_MAJOR
705 +
706 +#include <linux/stddef.h>
707 +#include <linux/kernel.h>
708 +#include <linux/ctype.h>
709 +#include <linux/stat.h>
710 +#include <linux/vmalloc.h>
711 +#include <linux/blkdev.h>
712 +#include <linux/blk.h>
713 +#include <linux/fs.h>
714 +#include <linux/genhd.h>
715 +#include <linux/devfs_fs.h>
716 +#include <asm/uaccess.h>
717 +#include "2_5compat.h"
718 +#include "cow.h"
719 +#include "ubd_user.h"
720 +
721 +#define COW_SHIFT 4
722 +
723 +struct cow {
724 +       int count;
725 +       char *cow_path;
726 +       dev_t cow_dev;
727 +       struct block_device *cow_bdev;
728 +       char *backing_path;
729 +       dev_t backing_dev;
730 +       struct block_device *backing_bdev;
731 +       int sectorsize;
732 +       unsigned long *bitmap;
733 +       unsigned long bitmap_len;
734 +       int bitmap_offset;
735 +       int data_offset;
736 +       devfs_handle_t devfs;
737 +       struct semaphore sem;
738 +       struct semaphore io_sem;
739 +       atomic_t working;
740 +       spinlock_t io_lock;
741 +       struct buffer_head *bh;
742 +       struct buffer_head *bhtail;
743 +       void *end_io;
744 +};
745 +
746 +#define DEFAULT_COW { \
747 +       .count                  = 0, \
748 +       .cow_path               = NULL, \
749 +       .cow_dev                = 0, \
750 +       .backing_path           = NULL, \
751 +       .backing_dev            = 0, \
752 +        .bitmap                        = NULL, \
753 +       .bitmap_len             = 0, \
754 +       .bitmap_offset          = 0, \
755 +        .data_offset           = 0, \
756 +       .devfs                  = NULL, \
757 +       .working                = ATOMIC_INIT(0), \
758 +       .io_lock                = SPIN_LOCK_UNLOCKED, \
759 +}
760 +
761 +#define MAX_DEV (8)
762 +#define MAX_MINOR (MAX_DEV << COW_SHIFT)
763 +
764 +struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW };
765 +
766 +/* Not modified by this driver */
767 +static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE };
768 +static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 };
769 +
770 +/* Protected by cow_lock */
771 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
772 +
773 +static struct hd_struct        cow_part[MAX_MINOR] =
774 +       { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
775 +
776 +/* Protected by io_request_lock */
777 +static request_queue_t *cow_queue;
778 +
779 +static int cow_open(struct inode *inode, struct file *filp);
780 +static int cow_release(struct inode * inode, struct file * file);
781 +static int cow_ioctl(struct inode * inode, struct file * file,
782 +                    unsigned int cmd, unsigned long arg);
783 +static int cow_revalidate(kdev_t rdev);
784 +
785 +static struct block_device_operations cow_blops = {
786 +       .open           = cow_open,
787 +       .release        = cow_release,
788 +       .ioctl          = cow_ioctl,
789 +       .revalidate     = cow_revalidate,
790 +};
791 +
792 +/* Initialized in an initcall, and unchanged thereafter */
793 +devfs_handle_t cow_dir_handle;
794 +
795 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
796 +{ \
797 +       .major          = maj, \
798 +       .major_name     = name, \
799 +       .minor_shift    = shift, \
800 +       .max_p          = 1 << shift, \
801 +       .part           = parts, \
802 +       .sizes          = bsizes, \
803 +       .nr_real        = max, \
804 +       .real_devices   = NULL, \
805 +       .next           = NULL, \
806 +       .fops           = blops, \
807 +       .de_arr         = NULL, \
808 +       .flags          = 0 \
809 +}
810 +
811 +static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED;
812 +
813 +static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part,
814 +                                                COW_SHIFT, sizes, MAX_DEV, 
815 +                                                &cow_blops);
816 +
817 +static int cow_add(int n)
818 +{
819 +       struct cow *dev = &cow_dev[n];
820 +       char name[sizeof("nnnnnn\0")];
821 +       int err = -ENODEV;
822 +
823 +       if(dev->cow_path == NULL)
824 +               goto out;
825 +
826 +       sprintf(name, "%d", n);
827 +       dev->devfs = devfs_register(cow_dir_handle, name, DEVFS_FL_REMOVABLE,
828 +                                   MAJOR_NR, n << COW_SHIFT, S_IFBLK | 
829 +                                   S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
830 +                                   &cow_blops, NULL);
831 +
832 +       init_MUTEX_LOCKED(&dev->sem);
833 +       init_MUTEX(&dev->io_sem);
834 +
835 +       return(0);
836 +
837 +out:
838 +       return(err);
839 +}
840 +
841 +/*
842 +* Add buffer_head to back of pending list
843 +*/
844 +static void cow_add_bh(struct cow *cow, struct buffer_head *bh)
845 +{
846 +       unsigned long flags;
847 +
848 +       spin_lock_irqsave(&cow->io_lock, flags);
849 +       if(cow->bhtail != NULL){
850 +               cow->bhtail->b_reqnext = bh;
851 +               cow->bhtail = bh;
852 +       }
853 +       else {
854 +               cow->bh = bh;
855 +               cow->bhtail = bh;
856 +       }
857 +       spin_unlock_irqrestore(&cow->io_lock, flags);
858 +}
859 +
860 +/*
861 +* Grab first pending buffer
862 +*/
863 +static struct buffer_head *cow_get_bh(struct cow *cow)
864 +{
865 +       struct buffer_head *bh;
866 +
867 +       spin_lock_irq(&cow->io_lock);
868 +       bh = cow->bh;
869 +       if(bh != NULL){
870 +               if(bh == cow->bhtail)
871 +                       cow->bhtail = NULL;
872 +               cow->bh = bh->b_reqnext;
873 +               bh->b_reqnext = NULL;
874 +       }
875 +       spin_unlock_irq(&cow->io_lock);
876 +
877 +       return(bh);
878 +}
879 +
880 +static void cow_handle_bh(struct cow *cow, struct buffer_head *bh, 
881 +                         struct buffer_head **cow_bh, int ncow_bh)
882 +{
883 +       int i;
884 +
885 +       if(ncow_bh > 0)
886 +               ll_rw_block(WRITE, ncow_bh, cow_bh);
887 +
888 +       for(i = 0; i < ncow_bh ; i++){
889 +               wait_on_buffer(cow_bh[i]);
890 +               brelse(cow_bh[i]);
891 +       }
892 +
893 +       ll_rw_block(WRITE, 1, &bh);
894 +       brelse(bh);
895 +}
896 +
897 +static struct buffer_head *cow_new_bh(struct cow *dev, int sector)
898 +{
899 +       struct buffer_head *bh;
900 +
901 +       sector = (dev->bitmap_offset + sector / 8) / dev->sectorsize;
902 +       bh = getblk(dev->cow_dev, sector, dev->sectorsize);
903 +       memcpy(bh->b_data, dev->bitmap + sector / (8 * sizeof(dev->bitmap[0])),
904 +              dev->sectorsize);
905 +       return(bh);
906 +}
907 +
908 +/* Copied from loop.c, needed to avoid deadlocking in make_request. */
909 +
910 +static int cow_thread(void *data)
911 +{
912 +       struct cow *dev = data;
913 +       struct buffer_head *bh;
914 +
915 +       daemonize();
916 +       exit_files(current);
917 +
918 +       sprintf(current->comm, "cow%d", dev - cow_dev);
919 +
920 +       spin_lock_irq(&current->sigmask_lock);
921 +       sigfillset(&current->blocked);
922 +       flush_signals(current);
923 +       spin_unlock_irq(&current->sigmask_lock);
924 +
925 +       atomic_inc(&dev->working);
926 +
927 +       current->policy = SCHED_OTHER;
928 +       current->nice = -20;
929 +
930 +       current->flags |= PF_NOIO;
931 +
932 +       /*
933 +        * up sem, we are running
934 +        */
935 +       up(&dev->sem);
936 +
937 +       for(;;){
938 +               int start, len, nbh, i, update_bitmap = 0;
939 +               struct buffer_head *cow_bh[2];
940 +
941 +               down_interruptible(&dev->io_sem);
942 +               /*
943 +                * could be upped because of tear-down, not because of
944 +                * pending work
945 +                */
946 +               if(!atomic_read(&dev->working))
947 +                       break;
948 +
949 +               bh = cow_get_bh(dev);
950 +               if(bh == NULL){
951 +                       printk(KERN_ERR "cow: missing bh\n");
952 +                       continue;
953 +               }
954 +
955 +               start = bh->b_blocknr * bh->b_size / dev->sectorsize;
956 +               len = bh->b_size / dev->sectorsize;
957 +               for(i = 0; i < len ; i++){
958 +                       if(ubd_test_bit(start +ni, 
959 +                                       (unsigned char *) dev->bitmap))
960 +                               continue;
961 +
962 +                       update_bitmap = 1;
963 +                       ubd_set_bit(start + i, (unsigned char *) dev->bitmap);
964 +               }
965 +
966 +               cow_bh[0] = NULL;
967 +               cow_bh[1] = NULL;
968 +               nbh = 0;
969 +               if(update_bitmap){
970 +                       cow_bh[0] = cow_new_bh(dev, start);
971 +                       nbh++;
972 +                       if(start / dev->sectorsize != 
973 +                          (start + len) / dev->sectorsize){
974 +                               cow_bh[1] = cow_new_bh(dev, start + len);
975 +                               nbh++;
976 +                       }
977 +               }
978 +               
979 +               bh->b_dev = dev->cow_dev;
980 +               bh->b_blocknr += dev->data_offset / dev->sectorsize;
981 +
982 +               cow_handle_bh(dev, bh, cow_bh, nbh);
983 +
984 +               /*
985 +                * upped both for pending work and tear-down, lo_pending
986 +                * will hit zero then
987 +                */
988 +               if(atomic_dec_and_test(&dev->working))
989 +                       break;
990 +       }
991 +
992 +       up(&dev->sem);
993 +       return(0);
994 +}
995 +
996 +static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh)
997 +{
998 +       struct cow *dev;
999 +       int n, minor;
1000 +
1001 +       minor = MINOR(bh->b_rdev);
1002 +       n = minor >> COW_SHIFT;
1003 +       dev = &cow_dev[n];
1004 +
1005 +       dev->end_io = NULL;
1006 +       if(ubd_test_bit(bh->b_rsector, (unsigned char *) dev->bitmap)){
1007 +               bh->b_rdev = dev->cow_dev;
1008 +               bh->b_rsector += dev->data_offset / dev->sectorsize;
1009 +       }
1010 +       else if(rw == WRITE){
1011 +               bh->b_dev = dev->cow_dev;
1012 +               bh->b_blocknr += dev->data_offset / dev->sectorsize;
1013 +
1014 +               cow_add_bh(dev, bh);
1015 +               up(&dev->io_sem);
1016 +               return(0);
1017 +       }
1018 +       else {
1019 +               bh->b_rdev = dev->backing_dev;
1020 +       }
1021 +
1022 +       return(1);
1023 +}
1024 +
1025 +int cow_init(void)
1026 +{
1027 +       int i;
1028 +
1029 +       cow_dir_handle = devfs_mk_dir (NULL, "cow", NULL);
1030 +       if (devfs_register_blkdev(MAJOR_NR, "cow", &cow_blops)) {
1031 +               printk(KERN_ERR "cow: unable to get major %d\n", MAJOR_NR);
1032 +               return -1;
1033 +       }
1034 +       read_ahead[MAJOR_NR] = 8;               /* 8 sector (4kB) read-ahead */
1035 +       blksize_size[MAJOR_NR] = blk_sizes;
1036 +       blk_size[MAJOR_NR] = sizes;
1037 +       INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes);
1038 +
1039 +       cow_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
1040 +       blk_init_queue(cow_queue, NULL);
1041 +       INIT_ELV(cow_queue, &cow_queue->elevator);
1042 +       blk_queue_make_request(cow_queue, cow_make_request);
1043 +
1044 +       add_gendisk(&cow_gendisk);
1045 +
1046 +       for(i=0;i<MAX_DEV;i++) 
1047 +               cow_add(i);
1048 +
1049 +       return(0);
1050 +}
1051 +
1052 +__initcall(cow_init);
1053 +
1054 +static int reader(__u64 start, char *buf, int count, void *arg)
1055 +{
1056 +       dev_t dev = *((dev_t *) arg);
1057 +       struct buffer_head *bh;
1058 +       __u64 block;
1059 +       int cur, offset, left, n, blocksize = get_hardsect_size(dev);
1060 +
1061 +       if(blocksize == 0)
1062 +               panic("Zero blocksize");
1063 +
1064 +       block = start / blocksize;
1065 +       offset = start % blocksize;
1066 +       left = count;
1067 +       cur = 0;
1068 +       while(left > 0){
1069 +               n = (left > blocksize) ? blocksize : left;
1070 +
1071 +               bh = bread(dev, block, (n < 512) ? 512 : n);
1072 +               if(bh == NULL)
1073 +                       return(-EIO);
1074 +
1075 +               n -= offset;
1076 +               memcpy(&buf[cur], bh->b_data + offset, n);
1077 +               block++;
1078 +               left -= n;
1079 +               cur += n;
1080 +               offset = 0;
1081 +               brelse(bh);
1082 +       }
1083 +
1084 +       return(count);
1085 +}
1086 +
1087 +static int cow_open(struct inode *inode, struct file *filp)
1088 +{
1089 +       int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
1090 +                        unsigned long);
1091 +       mm_segment_t fs;
1092 +       struct cow *dev;
1093 +       __u64 size;
1094 +       __u32 version, align;
1095 +       time_t mtime;
1096 +       char *backing_file;
1097 +       int n, offset, err = 0;
1098 +
1099 +       n = DEVICE_NR(inode->i_rdev);
1100 +       if(n >= MAX_DEV)
1101 +               return(-ENODEV);
1102 +       dev = &cow_dev[n];
1103 +       offset = n << COW_SHIFT;
1104 +
1105 +       spin_lock(&cow_lock);
1106 +
1107 +       if(dev->count == 0){
1108 +               dev->cow_dev = name_to_kdev_t(dev->cow_path);
1109 +               if(dev->cow_dev == 0){
1110 +                       printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
1111 +                              "failed\n", dev->cow_path);
1112 +                       err = -ENODEV;
1113 +               }
1114 +
1115 +               dev->backing_dev = name_to_kdev_t(dev->backing_path);
1116 +               if(dev->backing_dev == 0){
1117 +                       printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
1118 +                              "failed\n", dev->backing_path);
1119 +                       err = -ENODEV;
1120 +               }
1121 +
1122 +               if(err) 
1123 +                       goto out;
1124 +
1125 +               dev->cow_bdev = bdget(dev->cow_dev);
1126 +               if(dev->cow_bdev == NULL){
1127 +                       printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", 
1128 +                              dev->cow_path);
1129 +                       err = -ENOMEM;
1130 +               }
1131 +               dev->backing_bdev = bdget(dev->backing_dev);
1132 +               if(dev->backing_bdev == NULL){
1133 +                       printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", 
1134 +                              dev->backing_path);
1135 +                       err = -ENOMEM;
1136 +               }
1137 +
1138 +               if(err) 
1139 +                       goto out;
1140 +
1141 +               err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0, 
1142 +                                BDEV_RAW);
1143 +               if(err){
1144 +                       printk("cow_open - blkdev_get of COW device failed, "
1145 +                              "error = %d\n", err);
1146 +                       goto out;
1147 +               }
1148 +               
1149 +               err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW);
1150 +               if(err){
1151 +                       printk("cow_open - blkdev_get of backing device "
1152 +                              "failed, error = %d\n", err);
1153 +                       goto out;
1154 +               }
1155 +               
1156 +               err = read_cow_header(reader, &dev->cow_dev, &version, 
1157 +                                     &backing_file, &mtime, &size,
1158 +                                     &dev->sectorsize, &align, 
1159 +                                     &dev->bitmap_offset);
1160 +               if(err){
1161 +                       printk(KERN_ERR "cow_open - read_cow_header failed, "
1162 +                              "err = %d\n", err);
1163 +                       goto out;
1164 +               }
1165 +
1166 +               cow_sizes(version, size, dev->sectorsize, align, 
1167 +                         dev->bitmap_offset, &dev->bitmap_len, 
1168 +                         &dev->data_offset);
1169 +               dev->bitmap = (void *) vmalloc(dev->bitmap_len);
1170 +               if(dev->bitmap == NULL){
1171 +                       err = -ENOMEM;
1172 +                       printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
1173 +                       goto out;
1174 +               }
1175 +               flush_tlb_kernel_vm();
1176 +               
1177 +               err = reader(dev->bitmap_offset, (char *) dev->bitmap, 
1178 +                            dev->bitmap_len, &dev->cow_dev);
1179 +               if(err < 0){
1180 +                       printk(KERN_ERR "Failed to read COW bitmap\n");
1181 +                       vfree(dev->bitmap);
1182 +                       goto out;
1183 +               }
1184 +
1185 +               dev_ioctl = dev->backing_bdev->bd_op->ioctl;
1186 +               fs = get_fs();
1187 +               set_fs(KERNEL_DS);
1188 +               err = (*dev_ioctl)(inode, filp, BLKGETSIZE, 
1189 +                                  (unsigned long) &sizes[offset]);
1190 +               set_fs(fs);
1191 +               if(err){
1192 +                       printk(KERN_ERR "cow_open - BLKGETSIZE failed, "
1193 +                              "error = %d\n", err);
1194 +                       goto out;
1195 +               }
1196 +
1197 +               kernel_thread(cow_thread, dev, 
1198 +                             CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
1199 +               down(&dev->sem);
1200 +       }
1201 +       dev->count++;
1202 +out:
1203 +       spin_unlock(&cow_lock);
1204 +       return(err);
1205 +}
1206 +
1207 +static int cow_release(struct inode * inode, struct file * file)
1208 +{
1209 +       struct cow *dev;
1210 +       int n, err;
1211 +
1212 +       n = DEVICE_NR(inode->i_rdev);
1213 +       if(n >= MAX_DEV)
1214 +               return(-ENODEV);
1215 +       dev = &cow_dev[n];
1216 +
1217 +       spin_lock(&cow_lock);
1218 +
1219 +       if(--dev->count > 0)
1220 +               goto out;
1221 +
1222 +       err = blkdev_put(dev->cow_bdev, BDEV_RAW);
1223 +       if(err)
1224 +               printk("cow_release - blkdev_put of cow device failed, "
1225 +                      "error = %d\n", err);
1226 +       bdput(dev->cow_bdev);
1227 +       dev->cow_bdev = 0;
1228 +
1229 +       err = blkdev_put(dev->backing_bdev, BDEV_RAW);
1230 +       if(err)
1231 +               printk("cow_release - blkdev_put of backing device failed, "
1232 +                      "error = %d\n", err);
1233 +       bdput(dev->backing_bdev);
1234 +       dev->backing_bdev = 0;
1235 +
1236 +out:
1237 +       spin_unlock(&cow_lock);
1238 +       return(0);
1239 +}
1240 +
1241 +static int cow_ioctl(struct inode * inode, struct file * file,
1242 +                    unsigned int cmd, unsigned long arg)
1243 +{
1244 +       struct cow *dev;
1245 +       int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
1246 +                        unsigned long);
1247 +       int n;
1248 +
1249 +       n = DEVICE_NR(inode->i_rdev);
1250 +       if(n >= MAX_DEV)
1251 +               return(-ENODEV);
1252 +       dev = &cow_dev[n];
1253 +
1254 +       dev_ioctl = dev->backing_bdev->bd_op->ioctl;
1255 +       return((*dev_ioctl)(inode, file, cmd, arg));
1256 +}
1257 +
1258 +static int cow_revalidate(kdev_t rdev)
1259 +{
1260 +       printk(KERN_ERR "Need to implement cow_revalidate\n");
1261 +       return(0);
1262 +}
1263 +
1264 +static int parse_unit(char **ptr)
1265 +{
1266 +       char *str = *ptr, *end;
1267 +       int n = -1;
1268 +
1269 +       if(isdigit(*str)) {
1270 +               n = simple_strtoul(str, &end, 0);
1271 +               if(end == str)
1272 +                       return(-1);
1273 +               *ptr = end;
1274 +       }
1275 +       else if (('a' <= *str) && (*str <= 'h')) {
1276 +               n = *str - 'a';
1277 +               str++;
1278 +               *ptr = str;
1279 +       }
1280 +       return(n);
1281 +}
1282 +
1283 +static int cow_setup(char *str)
1284 +{
1285 +       struct cow *dev;
1286 +       char *cow_name, *backing_name;
1287 +       int unit;
1288 +
1289 +       unit = parse_unit(&str);
1290 +       if(unit < 0){
1291 +               printk(KERN_ERR "cow_setup - Couldn't parse unit number\n");
1292 +               return(1);
1293 +       }
1294 +
1295 +       if(*str != '='){
1296 +               printk(KERN_ERR "cow_setup - Missing '=' after unit "
1297 +                      "number\n");
1298 +               return(1);
1299 +       }
1300 +       str++;
1301 +
1302 +       cow_name = str;
1303 +       backing_name = strchr(str, ',');
1304 +       if(backing_name == NULL){
1305 +               printk(KERN_ERR "cow_setup - missing backing device name\n");
1306 +               return(0);
1307 +       }
1308 +       *backing_name = '\0';
1309 +       backing_name++;
1310 +
1311 +       spin_lock(&cow_lock);
1312 +
1313 +       dev = &cow_dev[unit];
1314 +       dev->cow_path = cow_name;
1315 +       dev->backing_path = backing_name;
1316 +       
1317 +       spin_unlock(&cow_lock);
1318 +       return(0);
1319 +}
1320 +
1321 +__setup("cow", cow_setup);
1322 +
1323 +/*
1324 + * Overrides for Emacs so that we follow Linus's tabbing style.
1325 + * Emacs will notice this stuff at the end of the file and automatically
1326 + * adjust the settings for this buffer only.  This must remain at the end
1327 + * of the file.
1328 + * ---------------------------------------------------------------------------
1329 + * Local variables:
1330 + * c-file-style: "linux"
1331 + * End:
1332 + */
1333 diff -Naur a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h
1334 --- a/arch/um/drivers/cow_sys.h 1969-12-31 19:00:00.000000000 -0500
1335 +++ b/arch/um/drivers/cow_sys.h 2004-01-08 22:29:45.000000000 -0500
1336 @@ -0,0 +1,48 @@
1337 +#ifndef __COW_SYS_H__
1338 +#define __COW_SYS_H__
1339 +
1340 +#include "kern_util.h"
1341 +#include "user_util.h"
1342 +#include "os.h"
1343 +#include "user.h"
1344 +
1345 +static inline void *cow_malloc(int size)
1346 +{
1347 +       return(um_kmalloc(size));
1348 +}
1349 +
1350 +static inline void cow_free(void *ptr)
1351 +{
1352 +       kfree(ptr);
1353 +}
1354 +
1355 +#define cow_printf printk
1356 +
1357 +static inline char *cow_strdup(char *str)
1358 +{
1359 +       return(uml_strdup(str));
1360 +}
1361 +
1362 +static inline int cow_seek_file(int fd, __u64 offset)
1363 +{
1364 +       return(os_seek_file(fd, offset));
1365 +}
1366 +
1367 +static inline int cow_file_size(char *file, __u64 *size_out)
1368 +{
1369 +       return(os_file_size(file, size_out));
1370 +}
1371 +
1372 +static inline int cow_write_file(int fd, char *buf, int size)
1373 +{
1374 +       return(os_write_file(fd, buf, size));
1375 +}
1376 +
1377 +#endif
1378 +
1379 +/*
1380 + * ---------------------------------------------------------------------------
1381 + * Local variables:
1382 + * c-file-style: "linux"
1383 + * End:
1384 + */
1385 diff -Naur a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c
1386 --- a/arch/um/drivers/cow_user.c        1969-12-31 19:00:00.000000000 -0500
1387 +++ b/arch/um/drivers/cow_user.c        2004-01-08 22:28:43.000000000 -0500
1388 @@ -0,0 +1,375 @@
1389 +#include <stddef.h>
1390 +#include <string.h>
1391 +#include <errno.h>
1392 +#include <unistd.h>
1393 +#include <byteswap.h>
1394 +#include <sys/time.h>
1395 +#include <sys/param.h>
1396 +#include <sys/user.h>
1397 +#include <netinet/in.h>
1398 +
1399 +#include "os.h"
1400 +
1401 +#include "cow.h"
1402 +#include "cow_sys.h"
1403 +
1404 +#define PATH_LEN_V1 256
1405 +
1406 +struct cow_header_v1 {
1407 +       int magic;
1408 +       int version;
1409 +       char backing_file[PATH_LEN_V1];
1410 +       time_t mtime;
1411 +       __u64 size;
1412 +       int sectorsize;
1413 +};
1414 +
1415 +#define PATH_LEN_V2 MAXPATHLEN
1416 +
1417 +struct cow_header_v2 {
1418 +       unsigned long magic;
1419 +       unsigned long version;
1420 +       char backing_file[PATH_LEN_V2];
1421 +       time_t mtime;
1422 +       __u64 size;
1423 +       int sectorsize;
1424 +};
1425 +
1426 +/* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in 
1427 + * case other systems have different values for MAXPATHLEN
1428 + */
1429 +#define PATH_LEN_V3 4096
1430 +
1431 +/* Changes from V2 - 
1432 + *     PATH_LEN_V3 as described above
1433 + *     Explicitly specify field bit lengths for systems with different
1434 + *             lengths for the usual C types.  Not sure whether char or
1435 + *             time_t should be changed, this can be changed later without
1436 + *             breaking compatibility
1437 + *     Add alignment field so that different alignments can be used for the
1438 + *             bitmap and data
1439 + *     Add cow_format field to allow for the possibility of different ways
1440 + *             of specifying the COW blocks.  For now, the only value is 0,
1441 + *             for the traditional COW bitmap.
1442 + *     Move the backing_file field to the end of the header.  This allows
1443 + *             for the possibility of expanding it into the padding required
1444 + *             by the bitmap alignment.
1445 + *     The bitmap and data portions of the file will be aligned as specified
1446 + *             by the alignment field.  This is to allow COW files to be
1447 + *             put on devices with restrictions on access alignments, such as
1448 + *             /dev/raw, with a 512 byte alignment restriction.  This also
1449 + *             allows the data to be more aligned more strictly than on
1450 + *             sector boundaries.  This is needed for ubd-mmap, which needs
1451 + *             the data to be page aligned.
1452 + *     Fixed (finally!) the rounding bug
1453 + */
1454 +
1455 +struct cow_header_v3 {
1456 +       __u32 magic;
1457 +       __u32 version;
1458 +       time_t mtime;
1459 +       __u64 size;
1460 +       __u32 sectorsize;
1461 +       __u32 alignment;
1462 +       __u32 cow_format;
1463 +       char backing_file[PATH_LEN_V3];
1464 +};
1465 +
1466 +/* COW format definitions - for now, we have only the usual COW bitmap */
1467 +#define COW_BITMAP 0
1468 +
1469 +union cow_header {
1470 +       struct cow_header_v1 v1;
1471 +       struct cow_header_v2 v2;
1472 +       struct cow_header_v3 v3;
1473 +};
1474 +
1475 +#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
1476 +#define COW_VERSION 3
1477 +
1478 +#define DIV_ROUND(x, len) (((x) + (len) - 1) / (len))
1479 +#define ROUND_UP(x, align) DIV_ROUND(x, align) * (align)
1480 +
1481 +void cow_sizes(int version, __u64 size, int sectorsize, int align, 
1482 +              int bitmap_offset, unsigned long *bitmap_len_out, 
1483 +              int *data_offset_out)
1484 +{
1485 +       if(version < 3){
1486 +               *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
1487 +
1488 +               *data_offset_out = bitmap_offset + *bitmap_len_out;
1489 +               *data_offset_out = (*data_offset_out + sectorsize - 1) / 
1490 +                       sectorsize;
1491 +               *data_offset_out *= sectorsize;
1492 +       }
1493 +       else {
1494 +               *bitmap_len_out = DIV_ROUND(size, sectorsize);
1495 +               *bitmap_len_out = DIV_ROUND(*bitmap_len_out, 8);
1496 +
1497 +               *data_offset_out = bitmap_offset + *bitmap_len_out;
1498 +               *data_offset_out = ROUND_UP(*data_offset_out, align);
1499 +       }
1500 +}
1501 +
1502 +static int absolutize(char *to, int size, char *from)
1503 +{
1504 +       char save_cwd[256], *slash;
1505 +       int remaining;
1506 +
1507 +       if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
1508 +               cow_printf("absolutize : unable to get cwd - errno = %d\n", 
1509 +                          errno);
1510 +               return(-1);
1511 +       }
1512 +       slash = strrchr(from, '/');
1513 +       if(slash != NULL){
1514 +               *slash = '\0';
1515 +               if(chdir(from)){
1516 +                       *slash = '/';
1517 +                       cow_printf("absolutize : Can't cd to '%s' - " 
1518 +                                  "errno = %d\n", from, errno);
1519 +                       return(-1);
1520 +               }
1521 +               *slash = '/';
1522 +               if(getcwd(to, size) == NULL){
1523 +                       cow_printf("absolutize : unable to get cwd of '%s' - "
1524 +                              "errno = %d\n", from, errno);
1525 +                       return(-1);
1526 +               }
1527 +               remaining = size - strlen(to);
1528 +               if(strlen(slash) + 1 > remaining){
1529 +                       cow_printf("absolutize : unable to fit '%s' into %d "
1530 +                              "chars\n", from, size);
1531 +                       return(-1);
1532 +               }
1533 +               strcat(to, slash);
1534 +       }
1535 +       else {
1536 +               if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
1537 +                       cow_printf("absolutize : unable to fit '%s' into %d "
1538 +                              "chars\n", from, size);
1539 +                       return(-1);
1540 +               }
1541 +               strcpy(to, save_cwd);
1542 +               strcat(to, "/");
1543 +               strcat(to, from);
1544 +       }
1545 +       chdir(save_cwd);
1546 +       return(0);
1547 +}
1548 +
1549 +int write_cow_header(char *cow_file, int fd, char *backing_file, 
1550 +                    int sectorsize, int alignment, long long *size)
1551 +{
1552 +       struct cow_header_v3 *header;
1553 +       unsigned long modtime;
1554 +       int err;
1555 +
1556 +       err = cow_seek_file(fd, 0);
1557 +       if(err < 0){
1558 +               cow_printf("write_cow_header - lseek failed, err = %d\n", -err);
1559 +               goto out;
1560 +       }
1561 +
1562 +       err = -ENOMEM;
1563 +       header = cow_malloc(sizeof(*header));
1564 +       if(header == NULL){
1565 +               cow_printf("Failed to allocate COW V3 header\n");
1566 +               goto out;
1567 +       }
1568 +       header->magic = htonl(COW_MAGIC);
1569 +       header->version = htonl(COW_VERSION);
1570 +
1571 +       err = -EINVAL;
1572 +       if(strlen(backing_file) > sizeof(header->backing_file) - 1){
1573 +               cow_printf("Backing file name \"%s\" is too long - names are "
1574 +                          "limited to %d characters\n", backing_file, 
1575 +                          sizeof(header->backing_file) - 1);
1576 +               goto out_free;
1577 +       }
1578 +
1579 +       if(absolutize(header->backing_file, sizeof(header->backing_file), 
1580 +                     backing_file))
1581 +               goto out_free;
1582 +
1583 +       err = os_file_modtime(header->backing_file, &modtime);
1584 +       if(err < 0){
1585 +               cow_printf("Backing file '%s' mtime request failed, "
1586 +                          "err = %d\n", header->backing_file, -err);
1587 +               goto out_free;
1588 +       }
1589 +
1590 +       err = cow_file_size(header->backing_file, size);
1591 +       if(err < 0){
1592 +               cow_printf("Couldn't get size of backing file '%s', "
1593 +                          "err = %d\n", header->backing_file, -err);
1594 +               goto out_free;
1595 +       }
1596 +
1597 +       header->mtime = htonl(modtime);
1598 +       header->size = htonll(*size);
1599 +       header->sectorsize = htonl(sectorsize);
1600 +       header->alignment = htonl(alignment);
1601 +       header->cow_format = COW_BITMAP;
1602 +
1603 +       err = os_write_file(fd, header, sizeof(*header));
1604 +       if(err != sizeof(*header)){
1605 +               cow_printf("Write of header to new COW file '%s' failed, "
1606 +                          "err = %d\n", cow_file, -err);
1607 +               goto out_free;
1608 +       }
1609 +       err = 0;
1610 + out_free:
1611 +       cow_free(header);
1612 + out:
1613 +       return(err);
1614 +}
1615 +
1616 +int file_reader(__u64 offset, char *buf, int len, void *arg)
1617 +{
1618 +       int fd = *((int *) arg);
1619 +
1620 +       return(pread(fd, buf, len, offset));
1621 +}
1622 +
1623 +/* XXX Need to sanity-check the values read from the header */
1624 +
1625 +int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, 
1626 +                   __u32 *version_out, char **backing_file_out, 
1627 +                   time_t *mtime_out, __u64 *size_out, 
1628 +                   int *sectorsize_out, __u32 *align_out, 
1629 +                   int *bitmap_offset_out)
1630 +{
1631 +       union cow_header *header;
1632 +       char *file;
1633 +       int err, n;
1634 +       unsigned long version, magic;
1635 +
1636 +       header = cow_malloc(sizeof(*header));
1637 +       if(header == NULL){
1638 +               cow_printf("read_cow_header - Failed to allocate header\n");
1639 +               return(-ENOMEM);
1640 +       }
1641 +       err = -EINVAL;
1642 +       n = (*reader)(0, (char *) header, sizeof(*header), arg);
1643 +       if(n < offsetof(typeof(header->v1), backing_file)){
1644 +               cow_printf("read_cow_header - short header\n");
1645 +               goto out;
1646 +       }
1647 +
1648 +       magic = header->v1.magic;
1649 +       if(magic == COW_MAGIC) {
1650 +               version = header->v1.version;
1651 +       }
1652 +       else if(magic == ntohl(COW_MAGIC)){
1653 +               version = ntohl(header->v1.version);
1654 +       }
1655 +       /* No error printed because the non-COW case comes through here */
1656 +       else goto out;
1657 +
1658 +       *version_out = version;
1659 +
1660 +       if(version == 1){
1661 +               if(n < sizeof(header->v1)){
1662 +                       cow_printf("read_cow_header - failed to read V1 "
1663 +                                  "header\n");
1664 +                       goto out;
1665 +               }
1666 +               *mtime_out = header->v1.mtime;
1667 +               *size_out = header->v1.size;
1668 +               *sectorsize_out = header->v1.sectorsize;
1669 +               *bitmap_offset_out = sizeof(header->v1);
1670 +               *align_out = *sectorsize_out;
1671 +               file = header->v1.backing_file;
1672 +       }
1673 +       else if(version == 2){
1674 +               if(n < sizeof(header->v2)){
1675 +                       cow_printf("read_cow_header - failed to read V2 "
1676 +                                  "header\n");
1677 +                       goto out;
1678 +               }
1679 +               *mtime_out = ntohl(header->v2.mtime);
1680 +               *size_out = ntohll(header->v2.size);
1681 +               *sectorsize_out = ntohl(header->v2.sectorsize);
1682 +               *bitmap_offset_out = sizeof(header->v2);
1683 +               *align_out = *sectorsize_out;
1684 +               file = header->v2.backing_file;
1685 +       }
1686 +       else if(version == 3){
1687 +               if(n < sizeof(header->v3)){
1688 +                       cow_printf("read_cow_header - failed to read V2 "
1689 +                                  "header\n");
1690 +                       goto out;
1691 +               }
1692 +               *mtime_out = ntohl(header->v3.mtime);
1693 +               *size_out = ntohll(header->v3.size);
1694 +               *sectorsize_out = ntohl(header->v3.sectorsize);
1695 +               *align_out = ntohl(header->v3.alignment);
1696 +               *bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out);
1697 +               file = header->v3.backing_file;
1698 +       }
1699 +       else {
1700 +               cow_printf("read_cow_header - invalid COW version\n");
1701 +               goto out;               
1702 +       }
1703 +       err = -ENOMEM;
1704 +       *backing_file_out = cow_strdup(file);
1705 +       if(*backing_file_out == NULL){
1706 +               cow_printf("read_cow_header - failed to allocate backing "
1707 +                          "file\n");
1708 +               goto out;
1709 +       }
1710 +       err = 0;
1711 + out:
1712 +       cow_free(header);
1713 +       return(err);
1714 +}
1715 +
1716 +int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
1717 +                 int alignment, int *bitmap_offset_out, 
1718 +                 unsigned long *bitmap_len_out, int *data_offset_out)
1719 +{
1720 +       __u64 size, offset;
1721 +       char zero = 0;
1722 +       int err;
1723 +
1724 +       err = write_cow_header(cow_file, fd, backing_file, sectorsize, 
1725 +                              alignment, &size);
1726 +       if(err) 
1727 +               goto out;
1728 +       
1729 +       *bitmap_offset_out = ROUND_UP(sizeof(struct cow_header_v3), alignment);
1730 +       cow_sizes(COW_VERSION, size, sectorsize, alignment, *bitmap_offset_out,
1731 +                 bitmap_len_out, data_offset_out);
1732 +
1733 +       offset = *data_offset_out + size - sizeof(zero);
1734 +       err = cow_seek_file(fd, offset);
1735 +       if(err < 0){
1736 +               cow_printf("cow bitmap lseek failed : err = %d\n", -err);
1737 +               goto out;
1738 +       }
1739 +
1740 +       /* does not really matter how much we write it is just to set EOF 
1741 +        * this also sets the entire COW bitmap
1742 +        * to zero without having to allocate it 
1743 +        */
1744 +       err = cow_write_file(fd, &zero, sizeof(zero));
1745 +       if(err != sizeof(zero)){
1746 +               cow_printf("Write of bitmap to new COW file '%s' failed, "
1747 +                          "err = %d\n", cow_file, -err);
1748 +               err = -EINVAL;
1749 +               goto out;
1750 +       }
1751 +
1752 +       return(0);
1753 +
1754 + out:
1755 +       return(err);
1756 +}
1757 +
1758 +/*
1759 + * ---------------------------------------------------------------------------
1760 + * Local variables:
1761 + * c-file-style: "linux"
1762 + * End:
1763 + */
1764 diff -Naur a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
1765 --- a/arch/um/drivers/daemon_user.c     2004-01-08 22:19:18.000000000 -0500
1766 +++ b/arch/um/drivers/daemon_user.c     2004-01-08 22:25:32.000000000 -0500
1767 @@ -53,7 +53,8 @@
1768         struct request_v3 req;
1769         int fd, n, err;
1770  
1771 -       if((pri->control = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
1772 +       pri->control = socket(AF_UNIX, SOCK_STREAM, 0);
1773 +       if(pri->control < 0){
1774                 printk("daemon_open : control socket failed, errno = %d\n", 
1775                        errno);          
1776                 return(-errno);
1777 @@ -67,7 +68,8 @@
1778                 goto out;
1779         }
1780  
1781 -       if((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0){
1782 +       fd = socket(AF_UNIX, SOCK_DGRAM, 0);
1783 +       if(fd < 0){
1784                 printk("daemon_open : data socket failed, errno = %d\n", 
1785                        errno);
1786                 err = -errno;
1787 @@ -91,18 +93,18 @@
1788         req.version = SWITCH_VERSION;
1789         req.type = REQ_NEW_CONTROL;
1790         req.sock = *local_addr;
1791 -       n = write(pri->control, &req, sizeof(req));
1792 +       n = os_write_file(pri->control, &req, sizeof(req));
1793         if(n != sizeof(req)){
1794 -               printk("daemon_open : control setup request returned %d, "
1795 -                      "errno = %d\n", n, errno);
1796 +               printk("daemon_open : control setup request failed, err = %d\n",
1797 +                      -n);
1798                 err = -ENOTCONN;
1799                 goto out;               
1800         }
1801  
1802 -       n = read(pri->control, sun, sizeof(*sun));
1803 +       n = os_read_file(pri->control, sun, sizeof(*sun));
1804         if(n != sizeof(*sun)){
1805 -               printk("daemon_open : read of data socket returned %d, "
1806 -                      "errno = %d\n", n, errno);
1807 +               printk("daemon_open : read of data socket failed, err = %d\n", 
1808 +                      -n);
1809                 err = -ENOTCONN;
1810                 goto out_close;         
1811         }
1812 @@ -111,9 +113,9 @@
1813         return(fd);
1814  
1815   out_close:
1816 -       close(fd);
1817 +       os_close_file(fd);
1818   out:
1819 -       close(pri->control);
1820 +       os_close_file(pri->control);
1821         return(err);
1822  }
1823  
1824 @@ -153,8 +155,8 @@
1825  {
1826         struct daemon_data *pri = data;
1827  
1828 -       close(pri->fd);
1829 -       close(pri->control);
1830 +       os_close_file(pri->fd);
1831 +       os_close_file(pri->control);
1832         if(pri->data_addr != NULL) kfree(pri->data_addr);
1833         if(pri->ctl_addr != NULL) kfree(pri->ctl_addr);
1834         if(pri->local_addr != NULL) kfree(pri->local_addr);
1835 diff -Naur a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
1836 --- a/arch/um/drivers/fd.c      2004-01-08 22:31:17.000000000 -0500
1837 +++ b/arch/um/drivers/fd.c      2004-01-08 22:35:52.000000000 -0500
1838 @@ -35,7 +35,8 @@
1839                 printk("fd_init : couldn't parse file descriptor '%s'\n", str);
1840                 return(NULL);
1841         }
1842 -       if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL);
1843 +       data = um_kmalloc(sizeof(*data));
1844 +       if(data == NULL) return(NULL);
1845         *data = ((struct fd_chan) { .fd         = n,
1846                                     .raw        = opts->raw });
1847         return(data);
1848 diff -Naur a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c
1849 --- a/arch/um/drivers/harddog_user.c    2004-01-08 22:17:52.000000000 -0500
1850 +++ b/arch/um/drivers/harddog_user.c    2004-01-08 22:23:56.000000000 -0500
1851 @@ -27,10 +27,10 @@
1852         dup2(data->stdin, 0);
1853         dup2(data->stdout, 1);
1854         dup2(data->stdout, 2);
1855 -       close(data->stdin);
1856 -       close(data->stdout);
1857 -       close(data->close_me[0]);
1858 -       close(data->close_me[1]);
1859 +       os_close_file(data->stdin);
1860 +       os_close_file(data->stdout);
1861 +       os_close_file(data->close_me[0]);
1862 +       os_close_file(data->close_me[1]);
1863  }
1864  
1865  int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
1866 @@ -44,15 +44,15 @@
1867         char **args = NULL;
1868  
1869         err = os_pipe(in_fds, 1, 0);
1870 -       if(err){
1871 -               printk("harddog_open - os_pipe failed, errno = %d\n", -err);
1872 -               return(err);
1873 +       if(err < 0){
1874 +               printk("harddog_open - os_pipe failed, err = %d\n", -err);
1875 +               goto out;
1876         }
1877  
1878         err = os_pipe(out_fds, 1, 0);
1879 -       if(err){
1880 -               printk("harddog_open - os_pipe failed, errno = %d\n", -err);
1881 -               return(err);
1882 +       if(err < 0){
1883 +               printk("harddog_open - os_pipe failed, err = %d\n", -err);
1884 +               goto out_close_in;
1885         }
1886  
1887         data.stdin = out_fds[0];
1888 @@ -72,42 +72,47 @@
1889  
1890         pid = run_helper(pre_exec, &data, args, NULL);
1891  
1892 -       close(out_fds[0]);
1893 -       close(in_fds[1]);
1894 +       os_close_file(out_fds[0]);
1895 +       os_close_file(in_fds[1]);
1896  
1897         if(pid < 0){
1898                 err = -pid;
1899 -               printk("harddog_open - run_helper failed, errno = %d\n", err);
1900 -               goto out;
1901 +               printk("harddog_open - run_helper failed, errno = %d\n", -err);
1902 +               goto out_close_out;
1903         }
1904  
1905 -       n = read(in_fds[0], &c, sizeof(c));
1906 +       n = os_read_file(in_fds[0], &c, sizeof(c));
1907         if(n == 0){
1908                 printk("harddog_open - EOF on watchdog pipe\n");
1909                 helper_wait(pid);
1910                 err = -EIO;
1911 -               goto out;
1912 +               goto out_close_out;
1913         }
1914         else if(n < 0){
1915                 printk("harddog_open - read of watchdog pipe failed, "
1916 -                      "errno = %d\n", errno);
1917 +                      "err = %d\n", -n);
1918                 helper_wait(pid);
1919 -               err = -errno;
1920 -               goto out;
1921 +               err = n;
1922 +               goto out_close_out;
1923         }
1924         *in_fd_ret = in_fds[0];
1925         *out_fd_ret = out_fds[1];
1926         return(0);
1927 +
1928 + out_close_in:
1929 +       os_close_file(in_fds[0]);
1930 +       os_close_file(in_fds[1]);
1931 + out_close_out:
1932 +       os_close_file(out_fds[0]);
1933 +       os_close_file(out_fds[1]);
1934   out:
1935 -       close(out_fds[1]);
1936 -       close(in_fds[0]);
1937         return(err);
1938  }
1939  
1940  void stop_watchdog(int in_fd, int out_fd)
1941  {
1942 -       close(in_fd);
1943 -       close(out_fd);
1944 +       os_close_file(in_fd);
1945 +       os_close_file(out_fd);
1946  }
1947  
1948  int ping_watchdog(int fd)
1949 @@ -115,11 +120,12 @@
1950         int n;
1951         char c = '\n';
1952  
1953 -       n = write(fd, &c, sizeof(c));
1954 -       if(n < sizeof(c)){
1955 -               printk("ping_watchdog - write failed, errno = %d\n",
1956 -                      errno);
1957 -               return(-errno);
1958 +       n = os_write_file(fd, &c, sizeof(c));
1959 +       if(n != sizeof(c)){
1960 +               printk("ping_watchdog - write failed, err = %d\n", -n);
1961 +               if(n < 0) 
1962 +                       return(n);
1963 +               return(-EIO);
1964         }
1965         return 1;
1966  
1967 diff -Naur a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
1968 --- a/arch/um/drivers/hostaudio_kern.c  2004-01-08 22:31:38.000000000 -0500
1969 +++ b/arch/um/drivers/hostaudio_kern.c  2004-01-08 22:36:17.000000000 -0500
1970 @@ -5,12 +5,12 @@
1971  
1972  #include "linux/config.h"
1973  #include "linux/module.h"
1974 -#include "linux/version.h"
1975  #include "linux/init.h"
1976  #include "linux/slab.h"
1977  #include "linux/fs.h"
1978  #include "linux/sound.h"
1979  #include "linux/soundcard.h"
1980 +#include "asm/uaccess.h"
1981  #include "kern_util.h"
1982  #include "init.h"
1983  #include "hostaudio.h"
1984 @@ -19,30 +19,39 @@
1985  char *dsp = HOSTAUDIO_DEV_DSP;
1986  char *mixer = HOSTAUDIO_DEV_MIXER;
1987  
1988 +#define DSP_HELP \
1989 +"    This is used to specify the host dsp device to the hostaudio driver.\n" \
1990 +"    The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n"
1991 +
1992 +#define MIXER_HELP \
1993 +"    This is used to specify the host mixer device to the hostaudio driver.\n" \
1994 +"    The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n"
1995 +
1996  #ifndef MODULE
1997  static int set_dsp(char *name, int *add)
1998  {
1999 -       dsp = uml_strdup(name);
2000 +       dsp = name;
2001         return(0);
2002  }
2003  
2004 -__uml_setup("dsp=", set_dsp,
2005 -"dsp=<dsp device>\n"
2006 -"    This is used to specify the host dsp device to the hostaudio driver.\n"
2007 -"    The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n"
2008 -);
2009 +__uml_setup("dsp=", set_dsp, "dsp=<dsp device>\n" DSP_HELP);
2010  
2011  static int set_mixer(char *name, int *add)
2012  {
2013 -       mixer = uml_strdup(name);
2014 +       mixer = name;
2015         return(0);
2016  }
2017  
2018 -__uml_setup("mixer=", set_mixer,
2019 -"mixer=<mixer device>\n"
2020 -"    This is used to specify the host mixer device to the hostaudio driver.\n"
2021 -"    The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n"
2022 -);
2023 +__uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP);
2024 +
2025 +#else /*MODULE*/
2026 +
2027 +MODULE_PARM(dsp, "s");
2028 +MODULE_PARM_DESC(dsp, DSP_HELP);
2029 +
2030 +MODULE_PARM(mixer, "s");
2031 +MODULE_PARM_DESC(mixer, MIXER_HELP);
2032 +
2033  #endif
2034  
2035  /* /dev/dsp file operations */
2036 @@ -51,23 +60,55 @@
2037                               loff_t *ppos)
2038  {
2039          struct hostaudio_state *state = file->private_data;
2040 +       void *kbuf;
2041 +       int err;
2042  
2043  #ifdef DEBUG
2044          printk("hostaudio: read called, count = %d\n", count);
2045  #endif
2046  
2047 -        return(hostaudio_read_user(state, buffer, count, ppos));
2048 +       kbuf = kmalloc(count, GFP_KERNEL);
2049 +       if(kbuf == NULL)
2050 +               return(-ENOMEM);
2051 +
2052 +        err = hostaudio_read_user(state, kbuf, count, ppos);
2053 +       if(err < 0)
2054 +               goto out;
2055 +
2056 +       if(copy_to_user(buffer, kbuf, err))
2057 +               err = -EFAULT;
2058 +
2059 + out:
2060 +       kfree(kbuf);
2061 +       return(err);
2062  }
2063  
2064  static ssize_t hostaudio_write(struct file *file, const char *buffer, 
2065                                size_t count, loff_t *ppos)
2066  {
2067          struct hostaudio_state *state = file->private_data;
2068 +       void *kbuf;
2069 +       int err;
2070  
2071  #ifdef DEBUG
2072          printk("hostaudio: write called, count = %d\n", count);
2073  #endif
2074 -        return(hostaudio_write_user(state, buffer, count, ppos));
2075 +
2076 +       kbuf = kmalloc(count, GFP_KERNEL);
2077 +       if(kbuf == NULL)
2078 +               return(-ENOMEM);
2079 +
2080 +       err = -EFAULT;
2081 +       if(copy_from_user(kbuf, buffer, count))
2082 +               goto out;
2083 +
2084 +        err = hostaudio_write_user(state, kbuf, count, ppos);
2085 +       if(err < 0)
2086 +               goto out;
2087 +
2088 + out:
2089 +       kfree(kbuf);
2090 +       return(err);
2091  }
2092  
2093  static unsigned int hostaudio_poll(struct file *file, 
2094 @@ -86,12 +127,43 @@
2095                            unsigned int cmd, unsigned long arg)
2096  {
2097          struct hostaudio_state *state = file->private_data;
2098 +       unsigned long data = 0;
2099 +       int err;
2100  
2101  #ifdef DEBUG
2102          printk("hostaudio: ioctl called, cmd = %u\n", cmd);
2103  #endif
2104 +       switch(cmd){
2105 +       case SNDCTL_DSP_SPEED:
2106 +       case SNDCTL_DSP_STEREO:
2107 +       case SNDCTL_DSP_GETBLKSIZE:
2108 +       case SNDCTL_DSP_CHANNELS:
2109 +       case SNDCTL_DSP_SUBDIVIDE:
2110 +       case SNDCTL_DSP_SETFRAGMENT:
2111 +               if(get_user(data, (int *) arg))
2112 +                       return(-EFAULT);
2113 +               break;
2114 +       default:
2115 +               break;
2116 +       }
2117 +
2118 +        err = hostaudio_ioctl_user(state, cmd, (unsigned long) &data);
2119 +
2120 +       switch(cmd){
2121 +       case SNDCTL_DSP_SPEED:
2122 +       case SNDCTL_DSP_STEREO:
2123 +       case SNDCTL_DSP_GETBLKSIZE:
2124 +       case SNDCTL_DSP_CHANNELS:
2125 +       case SNDCTL_DSP_SUBDIVIDE:
2126 +       case SNDCTL_DSP_SETFRAGMENT:
2127 +               if(put_user(data, (int *) arg))
2128 +                       return(-EFAULT);
2129 +               break;
2130 +       default:
2131 +               break;
2132 +       }
2133  
2134 -        return(hostaudio_ioctl_user(state, cmd, arg));
2135 +       return(err);
2136  }
2137  
2138  static int hostaudio_open(struct inode *inode, struct file *file)
2139 @@ -225,7 +297,8 @@
2140  
2141  static int __init hostaudio_init_module(void)
2142  {
2143 -        printk(KERN_INFO "UML Audio Relay\n");
2144 +        printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
2145 +              dsp, mixer);
2146  
2147         module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
2148          if(module_data.dev_audio < 0){
2149 diff -Naur a/arch/um/drivers/hostaudio_user.c b/arch/um/drivers/hostaudio_user.c
2150 --- a/arch/um/drivers/hostaudio_user.c  2004-01-08 22:26:01.000000000 -0500
2151 +++ b/arch/um/drivers/hostaudio_user.c  2004-01-08 22:33:41.000000000 -0500
2152 @@ -4,9 +4,6 @@
2153   */
2154  
2155  #include <sys/types.h>
2156 -#include <sys/stat.h>
2157 -#include <sys/ioctl.h>
2158 -#include <fcntl.h>
2159  #include <unistd.h>
2160  #include <errno.h>
2161  #include "hostaudio.h"
2162 @@ -20,16 +17,11 @@
2163  ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer, 
2164                             size_t count, loff_t *ppos)
2165  {
2166 -       ssize_t ret;
2167 -
2168  #ifdef DEBUG
2169          printk("hostaudio: read_user called, count = %d\n", count);
2170  #endif
2171  
2172 -        ret = read(state->fd, buffer, count);
2173 -
2174 -        if(ret < 0) return(-errno);
2175 -        return(ret);
2176 +       return(os_read_file(state->fd, buffer, count));
2177  }
2178  
2179  ssize_t hostaudio_write_user(struct hostaudio_state *state, const char *buffer,
2180 @@ -41,24 +33,19 @@
2181          printk("hostaudio: write_user called, count = %d\n", count);
2182  #endif
2183  
2184 -        ret = write(state->fd, buffer, count);
2185 +       return(os_write_file(state->fd, buffer, count));
2186  
2187 -        if(ret < 0) return(-errno);
2188          return(ret);
2189  }
2190  
2191  int hostaudio_ioctl_user(struct hostaudio_state *state, unsigned int cmd, 
2192                          unsigned long arg)
2193  {
2194 -       int ret;
2195  #ifdef DEBUG
2196          printk("hostaudio: ioctl_user called, cmd = %u\n", cmd);
2197  #endif
2198  
2199 -        ret = ioctl(state->fd, cmd, arg);
2200 -       
2201 -        if(ret < 0) return(-errno);
2202 -        return(ret);
2203 +       return(os_ioctl_generic(state->fd, cmd, arg));
2204  }
2205  
2206  int hostaudio_open_user(struct hostaudio_state *state, int r, int w, char *dsp)
2207 @@ -69,12 +56,13 @@
2208  
2209          state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
2210  
2211 -        if(state->fd >= 0) return(0);
2212 -
2213 -        printk("hostaudio_open_user failed to open '%s', errno = %d\n",
2214 -              dsp, errno);
2215 +       if(state->fd < 0) {
2216 +               printk("hostaudio_open_user failed to open '%s', err = %d\n",
2217 +                      dsp, -state->fd);
2218 +               return(state->fd); 
2219 +       }
2220          
2221 -        return(-errno); 
2222 +       return(0);
2223  }
2224  
2225  int hostaudio_release_user(struct hostaudio_state *state)
2226 @@ -83,8 +71,8 @@
2227          printk("hostaudio: release called\n");
2228  #endif
2229          if(state->fd >= 0){
2230 -               close(state->fd);
2231 -               state->fd=-1;
2232 +               os_close_file(state->fd);
2233 +               state->fd = -1;
2234          }
2235  
2236          return(0);
2237 @@ -95,15 +83,11 @@
2238  int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state, 
2239                                 unsigned int cmd, unsigned long arg)
2240  {
2241 -       int ret;
2242  #ifdef DEBUG
2243          printk("hostmixer: ioctl_user called cmd = %u\n",cmd);
2244  #endif
2245  
2246 -        ret = ioctl(state->fd, cmd, arg);
2247 -       if(ret < 0) 
2248 -               return(-errno);
2249 -       return(ret);
2250 +       return(os_ioctl_generic(state->fd, cmd, arg));
2251  }
2252  
2253  int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, int w,
2254 @@ -115,12 +99,13 @@
2255  
2256          state->fd = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
2257  
2258 -        if(state->fd >= 0) return(0);
2259 -
2260 -        printk("hostaudio_open_mixdev_user failed to open '%s', errno = %d\n",
2261 -              mixer, errno);
2262 +       if(state->fd < 0) {
2263 +               printk("hostaudio_open_mixdev_user failed to open '%s', "
2264 +                      "err = %d\n", mixer, state->fd);
2265 +               return(state->fd); 
2266 +       }
2267          
2268 -        return(-errno); 
2269 +       return(0);
2270  }
2271  
2272  int hostmixer_release_mixdev_user(struct hostmixer_state *state)
2273 @@ -130,7 +115,7 @@
2274  #endif
2275  
2276          if(state->fd >= 0){
2277 -               close(state->fd);
2278 +               os_close_file(state->fd);
2279                 state->fd = -1;
2280          }
2281  
2282 diff -Naur a/arch/um/drivers/line.c b/arch/um/drivers/line.c
2283 --- a/arch/um/drivers/line.c    2004-01-08 22:29:48.000000000 -0500
2284 +++ b/arch/um/drivers/line.c    2004-01-08 22:35:21.000000000 -0500
2285 @@ -6,8 +6,8 @@
2286  #include "linux/sched.h"
2287  #include "linux/slab.h"
2288  #include "linux/list.h"
2289 +#include "linux/interrupt.h"
2290  #include "linux/devfs_fs_kernel.h"
2291 -#include "asm/irq.h"
2292  #include "asm/uaccess.h"
2293  #include "chan_kern.h"
2294  #include "irq_user.h"
2295 @@ -16,38 +16,55 @@
2296  #include "user_util.h"
2297  #include "kern_util.h"
2298  #include "os.h"
2299 +#include "irq_kern.h"
2300  
2301  #define LINE_BUFSIZE 4096
2302  
2303 -void line_interrupt(int irq, void *data, struct pt_regs *unused)
2304 +static irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused)
2305  {
2306         struct line *dev = data;
2307  
2308         if(dev->count > 0) 
2309                 chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq, 
2310                                dev);
2311 +       return IRQ_HANDLED;
2312  }
2313  
2314 -void line_timer_cb(void *arg)
2315 +static void line_timer_cb(void *arg)
2316  {
2317         struct line *dev = arg;
2318  
2319         line_interrupt(dev->driver->read_irq, dev, NULL);
2320  }
2321  
2322 -static void buffer_data(struct line *line, const char *buf, int len)
2323 +static int write_room(struct line *dev)
2324  {
2325 -       int end;
2326 +       int n;
2327 +
2328 +       if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
2329 +
2330 +       n = dev->head - dev->tail;
2331 +       if(n <= 0) n = LINE_BUFSIZE + n;
2332 +       return(n - 1);
2333 +}
2334 +
2335 +static int buffer_data(struct line *line, const char *buf, int len)
2336 +{
2337 +       int end, room;
2338  
2339         if(line->buffer == NULL){
2340                 line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC);
2341                 if(line->buffer == NULL){
2342                         printk("buffer_data - atomic allocation failed\n");
2343 -                       return;
2344 +                       return(0);
2345                 }
2346                 line->head = line->buffer;
2347                 line->tail = line->buffer;
2348         }
2349 +
2350 +       room = write_room(line);
2351 +       len = (len > room) ? room : len;
2352 +
2353         end = line->buffer + LINE_BUFSIZE - line->tail;
2354         if(len < end){
2355                 memcpy(line->tail, buf, len);
2356 @@ -60,6 +77,8 @@
2357                 memcpy(line->buffer, buf, len);
2358                 line->tail = line->buffer + len;
2359         }
2360 +
2361 +       return(len);
2362  }
2363  
2364  static int flush_buffer(struct line *line)
2365 @@ -95,7 +114,7 @@
2366         struct line *line;
2367         char *new;
2368         unsigned long flags;
2369 -       int n, err, i;
2370 +       int n, err, i, ret = 0;
2371  
2372         if(tty->stopped) return 0;
2373  
2374 @@ -104,9 +123,13 @@
2375                 if(new == NULL)
2376                         return(0);
2377                 n = copy_from_user(new, buf, len);
2378 -               if(n == len)
2379 -                       return(-EFAULT);
2380                 buf = new;
2381 +               if(n == len){
2382 +                       len = -EFAULT;
2383 +                       goto out_free;
2384 +               }
2385 +
2386 +               len -= n;
2387         }
2388  
2389         i = tty->index;
2390 @@ -115,41 +138,50 @@
2391         down(&line->sem);
2392         if(line->head != line->tail){
2393                 local_irq_save(flags);
2394 -               buffer_data(line, buf, len);
2395 +               ret += buffer_data(line, buf, len);
2396                 err = flush_buffer(line);
2397                 local_irq_restore(flags);
2398                 if(err <= 0)
2399 -                       goto out;
2400 +                       goto out_up;
2401         }
2402         else {
2403                 n = write_chan(&line->chan_list, buf, len, 
2404                                line->driver->write_irq);
2405                 if(n < 0){
2406 -                       len = n;
2407 -                       goto out;
2408 +                       ret = n;
2409 +                       goto out_up;
2410                 }
2411 -               if(n < len)
2412 -                       buffer_data(line, buf + n, len - n);
2413 +
2414 +               len -= n;
2415 +               ret += n;
2416 +               if(len > 0)
2417 +                       ret += buffer_data(line, buf + n, len);
2418         }
2419 - out:
2420 + out_up:
2421         up(&line->sem);
2422 -       return(len);
2423 + out_free:
2424 +       if(from_user)
2425 +               kfree(buf);
2426 +       return(ret);
2427  }
2428  
2429 -void line_write_interrupt(int irq, void *data, struct pt_regs *unused)
2430 +static irqreturn_t line_write_interrupt(int irq, void *data, 
2431 +                                       struct pt_regs *unused)
2432  {
2433         struct line *dev = data;
2434         struct tty_struct *tty = dev->tty;
2435         int err;
2436  
2437         err = flush_buffer(dev);
2438 -       if(err == 0) return;
2439 +       if(err == 0) 
2440 +               return(IRQ_NONE);
2441         else if(err < 0){
2442                 dev->head = dev->buffer;
2443                 dev->tail = dev->buffer;
2444         }
2445  
2446 -       if(tty == NULL) return;
2447 +       if(tty == NULL) 
2448 +               return(IRQ_NONE);
2449  
2450         if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
2451            (tty->ldisc.write_wakeup != NULL))
2452 @@ -161,21 +193,9 @@
2453          * writes.
2454          */
2455  
2456 -       if (waitqueue_active(&tty->write_wait))
2457 +       if(waitqueue_active(&tty->write_wait))
2458                 wake_up_interruptible(&tty->write_wait);
2459 -
2460 -}
2461 -
2462 -int line_write_room(struct tty_struct *tty)
2463 -{
2464 -       struct line *dev = tty->driver_data;
2465 -       int n;
2466 -
2467 -       if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
2468 -
2469 -       n = dev->head - dev->tail;
2470 -       if(n <= 0) n = LINE_BUFSIZE + n;
2471 -       return(n - 1);
2472 +       return(IRQ_HANDLED);
2473  }
2474  
2475  int line_setup_irq(int fd, int input, int output, void *data)
2476 @@ -305,7 +325,7 @@
2477                 if(*end != '='){
2478                         printk(KERN_ERR "line_setup failed to parse \"%s\"\n", 
2479                                init);
2480 -                       return(1);
2481 +                       return(0);
2482                 }
2483                 init = end;
2484         }
2485 @@ -313,12 +333,12 @@
2486         if((n >= 0) && (n >= num)){
2487                 printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
2488                        n, num);
2489 -               return(1);
2490 +               return(0);
2491         }
2492         else if(n >= 0){
2493                 if(lines[n].count > 0){
2494                         printk("line_setup - device %d is open\n", n);
2495 -                       return(1);
2496 +                       return(0);
2497                 }
2498                 if(lines[n].init_pri <= INIT_ONE){
2499                         lines[n].init_pri = INIT_ONE;
2500 @@ -332,7 +352,7 @@
2501         else if(!all_allowed){
2502                 printk("line_setup - can't configure all devices from "
2503                        "mconsole\n");
2504 -               return(1);
2505 +               return(0);
2506         }
2507         else {
2508                 for(i = 0; i < num; i++){
2509 @@ -346,7 +366,7 @@
2510                         }
2511                 }
2512         }
2513 -       return(0);
2514 +       return(1);
2515  }
2516  
2517  int line_config(struct line *lines, int num, char *str)
2518 @@ -357,7 +377,7 @@
2519                 printk("line_config - uml_strdup failed\n");
2520                 return(-ENOMEM);
2521         }
2522 -       return(line_setup(lines, num, new, 0));
2523 +       return(!line_setup(lines, num, new, 0));
2524  }
2525  
2526  int line_get_config(char *name, struct line *lines, int num, char *str, 
2527 @@ -369,7 +389,7 @@
2528  
2529         dev = simple_strtoul(name, &end, 0);
2530         if((*end != '\0') || (end == name)){
2531 -               *error_out = "line_setup failed to parse device number";
2532 +               *error_out = "line_get_config failed to parse device number";
2533                 return(0);
2534         }
2535  
2536 @@ -379,15 +399,15 @@
2537         }
2538  
2539         line = &lines[dev];
2540 +
2541         down(&line->sem);
2542 -       
2543         if(!line->valid)
2544                 CONFIG_CHUNK(str, size, n, "none", 1);
2545         else if(line->count == 0)
2546                 CONFIG_CHUNK(str, size, n, line->init_str, 1);
2547         else n = chan_config_string(&line->chan_list, str, size, error_out);
2548 -
2549         up(&line->sem);
2550 +
2551         return(n);
2552  }
2553  
2554 @@ -396,7 +416,14 @@
2555         char config[sizeof("conxxxx=none\0")];
2556  
2557         sprintf(config, "%s=none", str);
2558 -       return(line_setup(lines, num, config, 0));
2559 +       return(!line_setup(lines, num, config, 0));
2560 +}
2561 +
2562 +int line_write_room(struct tty_struct *tty)
2563 +{
2564 +       struct line *dev = tty->driver_data;
2565 +
2566 +       return(write_room(dev));
2567  }
2568  
2569  struct tty_driver *line_register_devfs(struct lines *set,
2570 @@ -412,7 +439,8 @@
2571                 return NULL;
2572  
2573         driver->driver_name = line_driver->name;
2574 -       driver->name = line_driver->devfs_name;
2575 +       driver->name = line_driver->device_name;
2576 +       driver->devfs_name = line_driver->devfs_name;
2577         driver->major = line_driver->major;
2578         driver->minor_start = line_driver->minor_start;
2579         driver->type = line_driver->type;
2580 @@ -432,7 +460,7 @@
2581  
2582         for(i = 0; i < nlines; i++){
2583                 if(!lines[i].valid) 
2584 -                       tty_unregister_devfs(driver, i);
2585 +                       tty_unregister_device(driver, i);
2586         }
2587  
2588         mconsole_register_dev(&line_driver->mc);
2589 @@ -465,24 +493,25 @@
2590         struct line *line;
2591  };
2592  
2593 -void winch_interrupt(int irq, void *data, struct pt_regs *unused)
2594 +irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
2595  {
2596         struct winch *winch = data;
2597         struct tty_struct *tty;
2598         int err;
2599         char c;
2600  
2601 -       err = generic_read(winch->fd, &c, NULL);
2602 -       if(err < 0){
2603 -               if(err != -EAGAIN){
2604 -                       printk("winch_interrupt : read failed, errno = %d\n", 
2605 -                              -err);
2606 -                       printk("fd %d is losing SIGWINCH support\n", 
2607 -                              winch->tty_fd);
2608 -                       free_irq(irq, data);
2609 -                       return;
2610 +       if(winch->fd != -1){
2611 +               err = generic_read(winch->fd, &c, NULL);
2612 +               if(err < 0){
2613 +                       if(err != -EAGAIN){
2614 +                               printk("winch_interrupt : read failed, "
2615 +                                      "errno = %d\n", -err);
2616 +                               printk("fd %d is losing SIGWINCH support\n", 
2617 +                                      winch->tty_fd);
2618 +                               return(IRQ_HANDLED);
2619 +                       }
2620 +                       goto out;
2621                 }
2622 -               goto out;
2623         }
2624         tty = winch->line->tty;
2625         if(tty != NULL){
2626 @@ -492,7 +521,9 @@
2627                 kill_pg(tty->pgrp, SIGWINCH, 1);
2628         }
2629   out:
2630 -       reactivate_fd(winch->fd, WINCH_IRQ);
2631 +       if(winch->fd != -1)
2632 +               reactivate_fd(winch->fd, WINCH_IRQ);
2633 +       return(IRQ_HANDLED);
2634  }
2635  
2636  DECLARE_MUTEX(winch_handler_sem);
2637 @@ -529,7 +560,10 @@
2638  
2639         list_for_each(ele, &winch_handlers){
2640                 winch = list_entry(ele, struct winch, list);
2641 -               close(winch->fd);
2642 +               if(winch->fd != -1){
2643 +                       deactivate_fd(winch->fd, WINCH_IRQ);
2644 +                       os_close_file(winch->fd);
2645 +               }
2646                 if(winch->pid != -1) 
2647                         os_kill_process(winch->pid, 1);
2648         }
2649 diff -Naur a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
2650 --- a/arch/um/drivers/Makefile  2004-01-08 22:23:04.000000000 -0500
2651 +++ b/arch/um/drivers/Makefile  2004-01-08 22:30:06.000000000 -0500
2652 @@ -1,5 +1,5 @@
2653  # 
2654 -# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
2655 +# Copyright (C) 2000, 2002, 2003 Jeff Dike (jdike@karaya.com)
2656  # Licensed under the GPL
2657  #
2658  
2659 @@ -39,6 +39,8 @@
2660  obj-$(CONFIG_TTY_CHAN) += tty.o 
2661  obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
2662  obj-$(CONFIG_UML_WATCHDOG) += harddog.o
2663 +obj-$(CONFIG_BLK_DEV_COW) += cow_kern.o
2664 +obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
2665  
2666  obj-y += stdio_console.o $(CHAN_OBJS)
2667  
2668 @@ -46,7 +48,7 @@
2669  
2670  USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \
2671         null.o pty.o tty.o xterm.o
2672 -USER_OBJS := $(foreach file,$(USER_OBJS),arch/um/drivers/$(file))
2673 +USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
2674  
2675  $(USER_OBJS) : %.o: %.c
2676         $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
2677 diff -Naur a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
2678 --- a/arch/um/drivers/mcast_user.c      2004-01-08 22:22:02.000000000 -0500
2679 +++ b/arch/um/drivers/mcast_user.c      2004-01-08 22:28:53.000000000 -0500
2680 @@ -23,6 +23,7 @@
2681  #include "kern_util.h"
2682  #include "user_util.h"
2683  #include "user.h"
2684 +#include "os.h"
2685  
2686  #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
2687  
2688 @@ -62,7 +63,8 @@
2689                 goto out;
2690         }
2691  
2692 -       if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
2693 +       fd = socket(AF_INET, SOCK_DGRAM, 0);
2694 +       if (fd < 0){
2695                 printk("mcast_open : data socket failed, errno = %d\n", 
2696                        errno);
2697                 fd = -ENOMEM;
2698 @@ -72,7 +74,7 @@
2699         if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
2700                 printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
2701                         errno);
2702 -               close(fd);
2703 +               os_close_file(fd);
2704                 fd = -EINVAL;
2705                 goto out;
2706         }
2707 @@ -82,7 +84,7 @@
2708                        sizeof(pri->ttl)) < 0) {
2709                 printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
2710                         errno);
2711 -               close(fd);
2712 +               os_close_file(fd);
2713                 fd = -EINVAL;
2714                 goto out;
2715         }
2716 @@ -91,7 +93,7 @@
2717         if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
2718                 printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
2719                         errno);
2720 -               close(fd);
2721 +               os_close_file(fd);
2722                 fd = -EINVAL;
2723                 goto out;
2724         }
2725 @@ -99,7 +101,7 @@
2726         /* bind socket to mcast address */
2727         if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
2728                 printk("mcast_open : data bind failed, errno = %d\n", errno);
2729 -               close(fd);
2730 +               os_close_file(fd);
2731                 fd = -EINVAL;
2732                 goto out;
2733         }               
2734 @@ -115,7 +117,7 @@
2735                        "interface on the host.\n");
2736                 printk("eth0 should be configured in order to use the "
2737                        "multicast transport.\n");
2738 -               close(fd);
2739 +               os_close_file(fd);
2740                 fd = -EINVAL;
2741         }
2742  
2743 @@ -137,7 +139,7 @@
2744                         errno);
2745         }
2746  
2747 -       close(fd);
2748 +       os_close_file(fd);
2749  }
2750  
2751  int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
2752 diff -Naur a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
2753 --- a/arch/um/drivers/mconsole_kern.c   2004-01-08 22:13:41.000000000 -0500
2754 +++ b/arch/um/drivers/mconsole_kern.c   2004-01-08 22:17:57.000000000 -0500
2755 @@ -1,6 +1,6 @@
2756  /*
2757   * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
2758 - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
2759 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
2760   * Licensed under the GPL
2761   */
2762  
2763 @@ -15,6 +15,9 @@
2764  #include "linux/sysrq.h"
2765  #include "linux/workqueue.h"
2766  #include "linux/module.h"
2767 +#include "linux/file.h"
2768 +#include "linux/fs.h"
2769 +#include "linux/namei.h"
2770  #include "linux/proc_fs.h"
2771  #include "asm/irq.h"
2772  #include "asm/uaccess.h"
2773 @@ -27,6 +30,7 @@
2774  #include "init.h"
2775  #include "os.h"
2776  #include "umid.h"
2777 +#include "irq_kern.h"
2778  
2779  static int do_unlink_socket(struct notifier_block *notifier, 
2780                             unsigned long what, void *data)
2781 @@ -67,7 +71,7 @@
2782  
2783  DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
2784  
2785 -void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2786 +irqreturn_t mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2787  {
2788         int fd;
2789         struct mconsole_entry *new;
2790 @@ -75,9 +79,10 @@
2791  
2792         fd = (int) dev_id;
2793         while (mconsole_get_request(fd, &req)){
2794 -               if(req.cmd->as_interrupt) (*req.cmd->handler)(&req);
2795 +               if(req.cmd->context == MCONSOLE_INTR) 
2796 +                       (*req.cmd->handler)(&req);
2797                 else {
2798 -                       new = kmalloc(sizeof(req), GFP_ATOMIC);
2799 +                       new = kmalloc(sizeof(*new), GFP_ATOMIC);
2800                         if(new == NULL)
2801                                 mconsole_reply(&req, "Out of memory", 1, 0);
2802                         else {
2803 @@ -88,6 +93,7 @@
2804         }
2805         if(!list_empty(&mc_requests)) schedule_work(&mconsole_work);
2806         reactivate_fd(fd, MCONSOLE_IRQ);
2807 +       return(IRQ_HANDLED);
2808  }
2809  
2810  void mconsole_version(struct mc_request *req)
2811 @@ -100,20 +106,110 @@
2812         mconsole_reply(req, version, 0, 0);
2813  }
2814  
2815 +void mconsole_log(struct mc_request *req)
2816 +{
2817 +       int len;
2818 +       char *ptr = req->request.data;
2819 +       
2820 +       ptr += strlen("log");
2821 +       while(isspace(*ptr)) ptr++;
2822 +
2823 +       len = req->len - (ptr - req->request.data);
2824 +       printk("%.*s", len, ptr);
2825 +       mconsole_reply(req, "", 0, 0);
2826 +}
2827 +
2828 +void mconsole_proc(struct mc_request *req)
2829 +{
2830 +       struct nameidata nd;
2831 +       struct file_system_type *proc;
2832 +       struct super_block *super;
2833 +       struct file *file;
2834 +       int n, err;
2835 +       char *ptr = req->request.data, *buf;
2836 +       
2837 +       ptr += strlen("proc");
2838 +       while(isspace(*ptr)) ptr++;
2839 +
2840 +       proc = get_fs_type("proc");
2841 +       if(proc == NULL){
2842 +               mconsole_reply(req, "procfs not registered", 1, 0);
2843 +               goto out;
2844 +       }
2845 +
2846 +       super = (*proc->get_sb)(proc, 0, NULL, NULL);
2847 +       put_filesystem(proc);
2848 +       if(super == NULL){
2849 +               mconsole_reply(req, "Failed to get procfs superblock", 1, 0);
2850 +               goto out;
2851 +       }
2852 +       up_write(&super->s_umount);
2853 +
2854 +       nd.dentry = super->s_root;
2855 +       nd.mnt = NULL;
2856 +       nd.flags = O_RDONLY + 1;
2857 +       nd.last_type = LAST_ROOT;
2858 +
2859 +       err = link_path_walk(ptr, &nd);
2860 +       if(err){
2861 +               mconsole_reply(req, "Failed to look up file", 1, 0);
2862 +               goto out_kill;
2863 +       }
2864 +
2865 +       file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
2866 +       if(IS_ERR(file)){
2867 +               mconsole_reply(req, "Failed to open file", 1, 0);
2868 +               goto out_kill;
2869 +       }
2870 +
2871 +       buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
2872 +       if(buf == NULL){
2873 +               mconsole_reply(req, "Failed to allocate buffer", 1, 0);
2874 +               goto out_fput;
2875 +       }
2876 +
2877 +       if((file->f_op != NULL) && (file->f_op->read != NULL)){
2878 +               do {
2879 +                       n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1, 
2880 +                                               &file->f_pos);
2881 +                       if(n >= 0){
2882 +                               buf[n] = '\0';
2883 +                               mconsole_reply(req, buf, 0, (n > 0));
2884 +                       }
2885 +                       else {
2886 +                               mconsole_reply(req, "Read of file failed", 
2887 +                                              1, 0);
2888 +                               goto out_free;
2889 +                       }
2890 +               } while(n > 0);
2891 +       }
2892 +       else mconsole_reply(req, "", 0, 0);
2893 +
2894 + out_free:
2895 +       kfree(buf);
2896 + out_fput:
2897 +       fput(file);
2898 + out_kill:
2899 +       deactivate_super(super);
2900 + out: ;
2901 +}
2902 +
2903  #define UML_MCONSOLE_HELPTEXT \
2904 -"Commands:
2905 -    version - Get kernel version
2906 -    help - Print this message
2907 -    halt - Halt UML
2908 -    reboot - Reboot UML
2909 -    config <dev>=<config> - Add a new device to UML; 
2910 -       same syntax as command line
2911 -    config <dev> - Query the configuration of a device
2912 -    remove <dev> - Remove a device from UML
2913 -    sysrq <letter> - Performs the SysRq action controlled by the letter
2914 -    cad - invoke the Ctl-Alt-Del handler
2915 -    stop - pause the UML; it will do nothing until it receives a 'go'
2916 -    go - continue the UML after a 'stop'
2917 +"Commands: \n\
2918 +    version - Get kernel version \n\
2919 +    help - Print this message \n\
2920 +    halt - Halt UML \n\
2921 +    reboot - Reboot UML \n\
2922 +    config <dev>=<config> - Add a new device to UML;  \n\
2923 +       same syntax as command line \n\
2924 +    config <dev> - Query the configuration of a device \n\
2925 +    remove <dev> - Remove a device from UML \n\
2926 +    sysrq <letter> - Performs the SysRq action controlled by the letter \n\
2927 +    cad - invoke the Ctl-Alt-Del handler \n\
2928 +    stop - pause the UML; it will do nothing until it receives a 'go' \n\
2929 +    go - continue the UML after a 'stop' \n\
2930 +    log <string> - make UML enter <string> into the kernel log\n\
2931 +    proc <file> - returns the contents of the UML's /proc/<file>\n\
2932  "
2933  
2934  void mconsole_help(struct mc_request *req)
2935 @@ -302,7 +398,7 @@
2936         if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
2937         snprintf(mconsole_socket_name, sizeof(file), "%s", file);
2938  
2939 -       sock = create_unix_socket(file, sizeof(file));
2940 +       sock = os_create_unix_socket(file, sizeof(file), 1);
2941         if (sock < 0){
2942                 printk("Failed to initialize management console\n");
2943                 return(1);
2944 @@ -344,11 +440,16 @@
2945         if(buf == NULL) 
2946                 return(-ENOMEM);
2947  
2948 -       if(copy_from_user(buf, buffer, count))
2949 -               return(-EFAULT);
2950 +       if(copy_from_user(buf, buffer, count)){
2951 +               count = -EFAULT;
2952 +               goto out;
2953 +       }
2954 +
2955         buf[count] = '\0';
2956  
2957         mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count);
2958 + out:
2959 +       kfree(buf);
2960         return(count);
2961  }
2962  
2963 diff -Naur a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
2964 --- a/arch/um/drivers/mconsole_user.c   2004-01-08 22:15:23.000000000 -0500
2965 +++ b/arch/um/drivers/mconsole_user.c   2004-01-08 22:21:13.000000000 -0500
2966 @@ -1,6 +1,6 @@
2967  /*
2968   * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
2969 - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
2970 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
2971   * Licensed under the GPL
2972   */
2973  
2974 @@ -18,16 +18,18 @@
2975  #include "umid.h"
2976  
2977  static struct mconsole_command commands[] = {
2978 -       { "version", mconsole_version, 1 },
2979 -       { "halt", mconsole_halt, 0 },
2980 -       { "reboot", mconsole_reboot, 0 },
2981 -       { "config", mconsole_config, 0 },
2982 -       { "remove", mconsole_remove, 0 },
2983 -       { "sysrq", mconsole_sysrq, 1 },
2984 -       { "help", mconsole_help, 1 },
2985 -       { "cad", mconsole_cad, 1 },
2986 -       { "stop", mconsole_stop, 0 },
2987 -       { "go", mconsole_go, 1 },
2988 +       { "version", mconsole_version, MCONSOLE_INTR },
2989 +       { "halt", mconsole_halt, MCONSOLE_PROC },
2990 +       { "reboot", mconsole_reboot, MCONSOLE_PROC },
2991 +       { "config", mconsole_config, MCONSOLE_PROC },
2992 +       { "remove", mconsole_remove, MCONSOLE_PROC },
2993 +       { "sysrq", mconsole_sysrq, MCONSOLE_INTR },
2994 +       { "help", mconsole_help, MCONSOLE_INTR },
2995 +       { "cad", mconsole_cad, MCONSOLE_INTR },
2996 +       { "stop", mconsole_stop, MCONSOLE_PROC },
2997 +       { "go", mconsole_go, MCONSOLE_INTR },
2998 +       { "log", mconsole_log, MCONSOLE_INTR },
2999 +       { "proc", mconsole_proc, MCONSOLE_PROC },
3000  };
3001  
3002  /* Initialized in mconsole_init, which is an initcall */
3003 @@ -139,6 +141,7 @@
3004                 memcpy(reply.data, str, len);
3005                 reply.data[len] = '\0';
3006                 total -= len;
3007 +               str += len;
3008                 reply.len = len + 1;
3009  
3010                 len = sizeof(reply) + reply.len - sizeof(reply.data);
3011 diff -Naur a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
3012 --- a/arch/um/drivers/mmapper_kern.c    2004-01-08 22:14:57.000000000 -0500
3013 +++ b/arch/um/drivers/mmapper_kern.c    2004-01-08 22:20:27.000000000 -0500
3014 @@ -120,7 +120,10 @@
3015         printk(KERN_INFO "Mapper v0.1\n");
3016  
3017         v_buf = (char *) find_iomem("mmapper", &mmapper_size);
3018 -       if(mmapper_size == 0) return(0);
3019 +       if(mmapper_size == 0){
3020 +               printk(KERN_ERR "mmapper_init - find_iomem failed\n");
3021 +               return(0);
3022 +       }
3023  
3024         p_buf = __pa(v_buf);
3025  
3026 diff -Naur a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
3027 --- a/arch/um/drivers/net_kern.c        2004-01-08 22:20:39.000000000 -0500
3028 +++ b/arch/um/drivers/net_kern.c        2004-01-08 22:27:13.000000000 -0500
3029 @@ -26,6 +26,7 @@
3030  #include "mconsole_kern.h"
3031  #include "init.h"
3032  #include "irq_user.h"
3033 +#include "irq_kern.h"
3034  
3035  static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
3036  LIST_HEAD(opened);
3037 @@ -37,7 +38,8 @@
3038         struct sk_buff *skb;
3039  
3040         /* If we can't allocate memory, try again next round. */
3041 -       if ((skb = dev_alloc_skb(dev->mtu)) == NULL) {
3042 +       skb = dev_alloc_skb(dev->mtu);
3043 +       if (skb == NULL) {
3044                 lp->stats.rx_dropped++;
3045                 return 0;
3046         }
3047 @@ -61,14 +63,14 @@
3048         return pkt_len;
3049  }
3050  
3051 -void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
3052 +irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
3053  {
3054         struct net_device *dev = dev_id;
3055         struct uml_net_private *lp = dev->priv;
3056         int err;
3057  
3058         if(!netif_running(dev))
3059 -               return;
3060 +               return(IRQ_NONE);
3061  
3062         spin_lock(&lp->lock);
3063         while((err = uml_net_rx(dev)) > 0) ;
3064 @@ -83,6 +85,7 @@
3065  
3066   out:
3067         spin_unlock(&lp->lock);
3068 +       return(IRQ_HANDLED);
3069  }
3070  
3071  static int uml_net_open(struct net_device *dev)
3072 @@ -252,37 +255,6 @@
3073  #endif
3074  }
3075  
3076 -/*
3077 - * default do nothing hard header packet routines for struct net_device init.
3078 - * real ethernet transports will overwrite with real routines.
3079 - */
3080 -static int uml_net_hard_header(struct sk_buff *skb, struct net_device *dev,
3081 -                 unsigned short type, void *daddr, void *saddr, unsigned len)
3082 -{
3083 -       return(0); /* no change */
3084 -}
3085 -
3086 -static int uml_net_rebuild_header(struct sk_buff *skb)
3087 -{
3088 -       return(0); /* ignore */ 
3089 -}
3090 -
3091 -static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh)
3092 -{
3093 -       return(-1); /* fail */
3094 -}
3095 -
3096 -static void uml_net_header_cache_update(struct hh_cache *hh,
3097 -                 struct net_device *dev, unsigned char * haddr)
3098 -{
3099 -       /* ignore */
3100 -}
3101 -
3102 -static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr)
3103 -{
3104 -       return(0); /* nothing */
3105 -}
3106 -
3107  static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
3108  static struct list_head devices = LIST_HEAD_INIT(devices);
3109  
3110 @@ -292,7 +264,7 @@
3111         struct uml_net *device;
3112         struct net_device *dev;
3113         struct uml_net_private *lp;
3114 -       int err, size;
3115 +       int save, err, size;
3116  
3117         size = transport->private_size + sizeof(struct uml_net_private) + 
3118                 sizeof(((struct uml_net_private *) 0)->user);
3119 @@ -334,12 +306,6 @@
3120         snprintf(dev->name, sizeof(dev->name), "eth%d", n);
3121         device->dev = dev;
3122  
3123 -        dev->hard_header = uml_net_hard_header;
3124 -        dev->rebuild_header = uml_net_rebuild_header;
3125 -        dev->hard_header_cache = uml_net_header_cache;
3126 -        dev->header_cache_update= uml_net_header_cache_update;
3127 -        dev->hard_header_parse = uml_net_header_parse;
3128 -
3129         (*transport->kern->init)(dev, init);
3130  
3131         dev->mtu = transport->user->max_packet;
3132 @@ -362,21 +328,29 @@
3133                 return 1;
3134         lp = dev->priv;
3135  
3136 -       INIT_LIST_HEAD(&lp->list);
3137 -       spin_lock_init(&lp->lock);
3138 -       lp->dev = dev;
3139 -       lp->fd = -1;
3140 -       lp->mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0 };
3141 -       lp->have_mac = device->have_mac;
3142 -       lp->protocol = transport->kern->protocol;
3143 -       lp->open = transport->user->open;
3144 -       lp->close = transport->user->close;
3145 -       lp->remove = transport->user->remove;
3146 -       lp->read = transport->kern->read;
3147 -       lp->write = transport->kern->write;
3148 -       lp->add_address = transport->user->add_address;
3149 -       lp->delete_address = transport->user->delete_address;
3150 -       lp->set_mtu = transport->user->set_mtu;
3151 +       /* lp.user is the first four bytes of the transport data, which
3152 +        * has already been initialized.  This structure assignment will
3153 +        * overwrite that, so we make sure that .user gets overwritten with
3154 +        * what it already has.
3155 +        */
3156 +       save = lp->user[0];
3157 +       *lp = ((struct uml_net_private) 
3158 +               { .list                 = LIST_HEAD_INIT(lp->list),
3159 +                 .lock                 = SPIN_LOCK_UNLOCKED,
3160 +                 .dev                  = dev,
3161 +                 .fd                   = -1,
3162 +                 .mac                  = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
3163 +                 .have_mac             = device->have_mac,
3164 +                 .protocol             = transport->kern->protocol,
3165 +                 .open                 = transport->user->open,
3166 +                 .close                = transport->user->close,
3167 +                 .remove               = transport->user->remove,
3168 +                 .read                 = transport->kern->read,
3169 +                 .write                = transport->kern->write,
3170 +                 .add_address          = transport->user->add_address,
3171 +                 .delete_address       = transport->user->delete_address,
3172 +                 .set_mtu              = transport->user->set_mtu,
3173 +                 .user                 = { save } });
3174  
3175         init_timer(&lp->tl);
3176         lp->tl.function = uml_net_user_timer_expire;
3177 @@ -609,7 +583,8 @@
3178         unregister_netdev(dev);
3179  
3180         list_del(&device->list);
3181 -       free_netdev(device);
3182 +       kfree(device);
3183 +       free_netdev(dev);
3184         return(0);
3185  }
3186  
3187 diff -Naur a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
3188 --- a/arch/um/drivers/net_user.c        2004-01-08 22:16:01.000000000 -0500
3189 +++ b/arch/um/drivers/net_user.c        2004-01-08 22:21:37.000000000 -0500
3190 @@ -26,8 +26,7 @@
3191         if(gate_addr == NULL) return(0);
3192         if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], 
3193                   &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){
3194 -               printk("Invalid tap IP address - '%s'\n", 
3195 -                      gate_addr);
3196 +               printk("Invalid tap IP address - '%s'\n", gate_addr);
3197                 return(-EINVAL);
3198         }
3199         return(0);
3200 @@ -60,18 +59,18 @@
3201         }
3202                 
3203         *output = '\0';
3204 -       if(read(fd, &remain, sizeof(remain)) != sizeof(remain)){
3205 -               printk("read_output - read of length failed, errno = %d\n",
3206 -                      errno);
3207 +       n = os_read_file(fd, &remain, sizeof(remain));
3208 +       if(n != sizeof(remain)){
3209 +               printk("read_output - read of length failed, err = %d\n", -n);
3210                 return;
3211         }
3212  
3213         while(remain != 0){
3214                 n = (remain < len) ? remain : len;
3215 -               actual = read(fd, output, n);
3216 +               actual = os_read_file(fd, output, n);
3217                 if(actual != n){
3218                         printk("read_output - read of data failed, "
3219 -                              "errno = %d\n", errno);
3220 +                              "err = %d\n", -actual);
3221                         return;
3222                 }
3223                 remain -= actual;
3224 @@ -83,13 +82,12 @@
3225  {
3226         int n;
3227  
3228 -       while(((n = read(fd,  buf,  len)) < 0) && (errno == EINTR)) ;
3229 +       n = os_read_file(fd,  buf,  len);
3230  
3231 -       if(n < 0){
3232 -               if(errno == EAGAIN) return(0);
3233 -               return(-errno);
3234 -       }
3235 -       else if(n == 0) return(-ENOTCONN);
3236 +       if(n == -EAGAIN) 
3237 +               return(0);
3238 +       else if(n == 0) 
3239 +               return(-ENOTCONN);
3240         return(n);
3241  }
3242  
3243 @@ -112,13 +110,13 @@
3244  {
3245         int n;
3246  
3247 -       while(((n = write(fd, buf, len)) < 0) && (errno == EINTR)) ;
3248 -       if(n < 0){
3249 -               if(errno == EAGAIN) return(0);
3250 -               return(-errno);
3251 -       }
3252 -       else if(n == 0) return(-ENOTCONN);
3253 -       return(n);      
3254 +       n = os_write_file(fd, buf, len);
3255 +
3256 +       if(n == -EAGAIN) 
3257 +               return(0);
3258 +       else if(n == 0) 
3259 +               return(-ENOTCONN);
3260 +       return(n);
3261  }
3262  
3263  int net_send(int fd, void *buf, int len)
3264 @@ -157,7 +155,7 @@
3265  {
3266         struct change_pre_exec_data *data = arg;
3267  
3268 -       close(data->close_me);
3269 +       os_close_file(data->close_me);
3270         dup2(data->stdout, 1);
3271  }
3272  
3273 @@ -167,15 +165,15 @@
3274         struct change_pre_exec_data pe_data;
3275  
3276         err = os_pipe(fds, 1, 0);
3277 -       if(err){
3278 -               printk("change_tramp - pipe failed, errno = %d\n", -err);
3279 +       if(err < 0){
3280 +               printk("change_tramp - pipe failed, err = %d\n", -err);
3281                 return(err);
3282         }
3283         pe_data.close_me = fds[0];
3284         pe_data.stdout = fds[1];
3285         pid = run_helper(change_pre_exec, &pe_data, argv, NULL);
3286  
3287 -       close(fds[1]);
3288 +       os_close_file(fds[1]);
3289         read_output(fds[0], output, output_len);
3290         waitpid(pid, NULL, 0);  
3291         return(pid);
3292 diff -Naur a/arch/um/drivers/null.c b/arch/um/drivers/null.c
3293 --- a/arch/um/drivers/null.c    2004-01-08 22:14:29.000000000 -0500
3294 +++ b/arch/um/drivers/null.c    2004-01-08 22:19:28.000000000 -0500
3295 @@ -5,7 +5,6 @@
3296  
3297  #include <stdlib.h>
3298  #include <errno.h>
3299 -#include <fcntl.h>
3300  #include "chan_user.h"
3301  #include "os.h"
3302  
3303 diff -Naur a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
3304 --- a/arch/um/drivers/port_kern.c       2004-01-08 22:13:51.000000000 -0500
3305 +++ b/arch/um/drivers/port_kern.c       2004-01-08 22:18:54.000000000 -0500
3306 @@ -6,6 +6,7 @@
3307  #include "linux/list.h"
3308  #include "linux/sched.h"
3309  #include "linux/slab.h"
3310 +#include "linux/interrupt.h"
3311  #include "linux/irq.h"
3312  #include "linux/spinlock.h"
3313  #include "linux/errno.h"
3314 @@ -14,6 +15,7 @@
3315  #include "kern_util.h"
3316  #include "kern.h"
3317  #include "irq_user.h"
3318 +#include "irq_kern.h"
3319  #include "port.h"
3320  #include "init.h"
3321  #include "os.h"
3322 @@ -44,7 +46,7 @@
3323         struct port_list *port;
3324  };
3325  
3326 -static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
3327 +static irqreturn_t pipe_interrupt(int irq, void *data, struct pt_regs *regs)
3328  {
3329         struct connection *conn = data;
3330         int fd;
3331 @@ -52,7 +54,7 @@
3332         fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
3333         if(fd < 0){
3334                 if(fd == -EAGAIN)
3335 -                       return;
3336 +                       return(IRQ_NONE);
3337  
3338                 printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", 
3339                        -fd);
3340 @@ -65,6 +67,7 @@
3341         list_add(&conn->list, &conn->port->connections);
3342  
3343         up(&conn->port->sem);
3344 +       return(IRQ_HANDLED);
3345  }
3346  
3347  static int port_accept(struct port_list *port)
3348 @@ -138,12 +141,13 @@
3349  
3350  DECLARE_WORK(port_work, port_work_proc, NULL);
3351  
3352 -static void port_interrupt(int irq, void *data, struct pt_regs *regs)
3353 +static irqreturn_t port_interrupt(int irq, void *data, struct pt_regs *regs)
3354  {
3355         struct port_list *port = data;
3356  
3357         port->has_connection = 1;
3358         schedule_work(&port_work);
3359 +       return(IRQ_HANDLED);
3360  } 
3361  
3362  void *port_data(int port_num)
3363 diff -Naur a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
3364 --- a/arch/um/drivers/port_user.c       2004-01-08 22:24:12.000000000 -0500
3365 +++ b/arch/um/drivers/port_user.c       2004-01-08 22:31:27.000000000 -0500
3366 @@ -47,10 +47,12 @@
3367                 return(NULL);
3368         }
3369  
3370 -       if((kern_data = port_data(port)) == NULL) 
3371 +       kern_data = port_data(port);
3372 +       if(kern_data == NULL) 
3373                 return(NULL);
3374  
3375 -       if((data = um_kmalloc(sizeof(*data))) == NULL) 
3376 +       data = um_kmalloc(sizeof(*data));
3377 +       if(data == NULL) 
3378                 goto err;
3379  
3380         *data = ((struct port_chan) { .raw              = opts->raw,
3381 @@ -90,7 +92,7 @@
3382         struct port_chan *data = d;
3383  
3384         port_remove_dev(data->kernel_data);
3385 -       close(fd);
3386 +       os_close_file(fd);
3387  }
3388  
3389  int port_console_write(int fd, const char *buf, int n, void *d)
3390 @@ -130,11 +132,15 @@
3391                 goto out;
3392         }
3393    
3394 -       if((listen(fd, 1) < 0) || (os_set_fd_block(fd, 0))){
3395 +       if(listen(fd, 1) < 0){
3396                 err = -errno;
3397                 goto out;
3398         }
3399  
3400 +       err = os_set_fd_block(fd, 0);
3401 +       if(err < 0)
3402 +               goto out;
3403 +
3404         return(fd);
3405   out:
3406         os_close_file(fd);
3407 @@ -153,10 +159,10 @@
3408         dup2(data->sock_fd, 0);
3409         dup2(data->sock_fd, 1);
3410         dup2(data->sock_fd, 2);
3411 -       close(data->sock_fd);
3412 +       os_close_file(data->sock_fd);
3413         dup2(data->pipe_fd, 3);
3414         os_shutdown_socket(3, 1, 0);
3415 -       close(data->pipe_fd);
3416 +       os_close_file(data->pipe_fd);
3417  }
3418  
3419  int port_connection(int fd, int *socket, int *pid_out)
3420 @@ -166,11 +172,12 @@
3421                          "/usr/lib/uml/port-helper", NULL };
3422         struct port_pre_exec_data data;
3423  
3424 -       if((new = os_accept_connection(fd)) < 0)
3425 -               return(-errno);
3426 +       new = os_accept_connection(fd);
3427 +       if(new < 0)
3428 +               return(new);
3429  
3430         err = os_pipe(socket, 0, 0);
3431 -       if(err) 
3432 +       if(err < 0) 
3433                 goto out_close;
3434  
3435         data = ((struct port_pre_exec_data)
3436 @@ -186,11 +193,11 @@
3437  
3438   out_shutdown:
3439         os_shutdown_socket(socket[0], 1, 1);
3440 -       close(socket[0]);
3441 +       os_close_file(socket[0]);
3442         os_shutdown_socket(socket[1], 1, 1);    
3443 -       close(socket[1]);
3444 +       os_close_file(socket[1]);
3445   out_close:
3446 -       close(new);
3447 +       os_close_file(new);
3448         return(err);
3449  }
3450  
3451 diff -Naur a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
3452 --- a/arch/um/drivers/pty.c     2004-01-08 22:29:41.000000000 -0500
3453 +++ b/arch/um/drivers/pty.c     2004-01-08 22:35:17.000000000 -0500
3454 @@ -7,12 +7,12 @@
3455  #include <unistd.h>
3456  #include <string.h>
3457  #include <errno.h>
3458 -#include <fcntl.h>
3459  #include <termios.h>
3460  #include "chan_user.h"
3461  #include "user.h"
3462  #include "user_util.h"
3463  #include "kern_util.h"
3464 +#include "os.h"
3465  
3466  struct pty_chan {
3467         void (*announce)(char *dev_name, int dev);
3468 @@ -26,7 +26,8 @@
3469  {
3470         struct pty_chan *data;
3471  
3472 -       if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL);
3473 +       data = um_kmalloc(sizeof(*data));
3474 +       if(data == NULL) return(NULL);
3475         *data = ((struct pty_chan) { .announce          = opts->announce, 
3476                                      .dev               = device,
3477                                      .raw               = opts->raw });
3478 @@ -39,7 +40,8 @@
3479         char *dev;
3480         int fd;
3481  
3482 -       if((fd = get_pty()) < 0){
3483 +       fd = get_pty();
3484 +       if(fd < 0){
3485                 printk("open_pts : Failed to open pts\n");
3486                 return(-errno);
3487         }
3488 @@ -57,29 +59,27 @@
3489  
3490  int getmaster(char *line)
3491  {
3492 -       struct stat stb;
3493         char *pty, *bank, *cp;
3494 -       int master;
3495 +       int master, err;
3496  
3497         pty = &line[strlen("/dev/ptyp")];
3498         for (bank = "pqrs"; *bank; bank++) {
3499                 line[strlen("/dev/pty")] = *bank;
3500                 *pty = '0';
3501 -               if (stat(line, &stb) < 0)
3502 +               if (os_stat_file(line, NULL) < 0)
3503                         break;
3504                 for (cp = "0123456789abcdef"; *cp; cp++) {
3505                         *pty = *cp;
3506 -                       master = open(line, O_RDWR);
3507 +                       master = os_open_file(line, of_rdwr(OPENFLAGS()), 0);
3508                         if (master >= 0) {
3509                                 char *tp = &line[strlen("/dev/")];
3510 -                               int ok;
3511  
3512                                 /* verify slave side is usable */
3513                                 *tp = 't';
3514 -                               ok = access(line, R_OK|W_OK) == 0;
3515 +                               err = os_access(line, OS_ACC_RW_OK);
3516                                 *tp = 'p';
3517 -                               if (ok) return(master);
3518 -                               (void) close(master);
3519 +                               if(err == 0) return(master);
3520 +                               (void) os_close_file(master);
3521                         }
3522                 }
3523         }
3524 diff -Naur a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
3525 --- a/arch/um/drivers/slip_user.c       2004-01-08 22:29:41.000000000 -0500
3526 +++ b/arch/um/drivers/slip_user.c       2004-01-08 22:35:17.000000000 -0500
3527 @@ -4,11 +4,9 @@
3528  #include <stddef.h>
3529  #include <sched.h>
3530  #include <string.h>
3531 -#include <sys/fcntl.h>
3532  #include <sys/errno.h>
3533  #include <sys/termios.h>
3534  #include <sys/wait.h>
3535 -#include <sys/ioctl.h>
3536  #include <sys/signal.h>
3537  #include "user_util.h"
3538  #include "kern_util.h"
3539 @@ -65,9 +63,9 @@
3540  {
3541         struct slip_pre_exec_data *data = arg;
3542  
3543 -       if(data->stdin != -1) dup2(data->stdin, 0);
3544 +       if(data->stdin >= 0) dup2(data->stdin, 0);
3545         dup2(data->stdout, 1);
3546 -       if(data->close_me != -1) close(data->close_me);
3547 +       if(data->close_me >= 0) os_close_file(data->close_me);
3548  }
3549  
3550  static int slip_tramp(char **argv, int fd)
3551 @@ -77,8 +75,8 @@
3552         int status, pid, fds[2], err, output_len;
3553  
3554         err = os_pipe(fds, 1, 0);
3555 -       if(err){
3556 -               printk("slip_tramp : pipe failed, errno = %d\n", -err);
3557 +       if(err < 0){
3558 +               printk("slip_tramp : pipe failed, err = %d\n", -err);
3559                 return(err);
3560         }
3561  
3562 @@ -96,7 +94,7 @@
3563                         printk("slip_tramp : failed to allocate output "
3564                                "buffer\n");
3565  
3566 -               close(fds[1]);
3567 +               os_close_file(fds[1]);
3568                 read_output(fds[0], output, output_len);
3569                 if(output != NULL){
3570                         printk("%s", output);
3571 @@ -105,7 +103,7 @@
3572                 if(waitpid(pid, &status, 0) < 0) err = errno;
3573                 else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
3574                         printk("'%s' didn't exit with status 0\n", argv[0]);
3575 -                       err = EINVAL;
3576 +                       err = -EINVAL;
3577                 }
3578         }
3579         return(err);
3580 @@ -118,15 +116,17 @@
3581         char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
3582         char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf, 
3583                          NULL };
3584 -       int sfd, mfd, disc, sencap, err;
3585 +       int sfd, mfd, err;
3586  
3587 -       if((mfd = get_pty()) < 0){
3588 -               printk("umn : Failed to open pty\n");
3589 -               return(-1);
3590 +       mfd = get_pty();
3591 +       if(mfd < 0){
3592 +               printk("umn : Failed to open pty, err = %d\n", -mfd);
3593 +               return(mfd);
3594         }
3595 -       if((sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0)) < 0){
3596 -               printk("Couldn't open tty for slip line\n");
3597 -               return(-1);
3598 +       sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
3599 +       if(sfd < 0){
3600 +               printk("Couldn't open tty for slip line, err = %d\n", -sfd);
3601 +               return(sfd);
3602         }
3603         if(set_up_tty(sfd)) return(-1);
3604         pri->slave = sfd;
3605 @@ -138,28 +138,23 @@
3606  
3607                 err = slip_tramp(argv, sfd);
3608  
3609 -               if(err != 0){
3610 -                       printk("slip_tramp failed - errno = %d\n", err);
3611 -                       return(-err);
3612 +               if(err < 0){
3613 +                       printk("slip_tramp failed - err = %d\n", -err);
3614 +                       return(err);
3615                 }
3616 -               if(ioctl(pri->slave, SIOCGIFNAME, pri->name) < 0){
3617 -                       printk("SIOCGIFNAME failed, errno = %d\n", errno);
3618 -                       return(-errno);
3619 +               err = os_get_ifname(pri->slave, pri->name);
3620 +               if(err < 0){
3621 +                       printk("get_ifname failed, err = %d\n", -err);
3622 +                       return(err);
3623                 }
3624                 iter_addresses(pri->dev, open_addr, pri->name);
3625         }
3626         else {
3627 -               disc = N_SLIP;
3628 -               if(ioctl(sfd, TIOCSETD, &disc) < 0){
3629 -                       printk("Failed to set slip line discipline - "
3630 -                              "errno = %d\n", errno);
3631 -                       return(-errno);
3632 -               }
3633 -               sencap = 0;
3634 -               if(ioctl(sfd, SIOCSIFENCAP, &sencap) < 0){
3635 -                       printk("Failed to set slip encapsulation - "
3636 -                              "errno = %d\n", errno);
3637 -                       return(-errno);
3638 +               err = os_set_slip(sfd);
3639 +               if(err < 0){
3640 +                       printk("Failed to set slip discipline encapsulation - "
3641 +                              "err = %d\n", -err);
3642 +                       return(err);
3643                 }
3644         }
3645         return(mfd);
3646 @@ -181,9 +176,9 @@
3647         err = slip_tramp(argv, -1);
3648  
3649         if(err != 0)
3650 -               printk("slip_tramp failed - errno = %d\n", err);
3651 -       close(fd);
3652 -       close(pri->slave);
3653 +               printk("slip_tramp failed - errno = %d\n", -err);
3654 +       os_close_file(fd);
3655 +       os_close_file(pri->slave);
3656         pri->slave = -1;
3657  }
3658  
3659 @@ -243,7 +238,7 @@
3660  {
3661         struct slip_data *pri = data;
3662  
3663 -       if(pri->slave == -1) return;
3664 +       if(pri->slave < 0) return;
3665         open_addr(addr, netmask, pri->name);
3666  }
3667  
3668 @@ -252,7 +247,7 @@
3669  {
3670         struct slip_data *pri = data;
3671  
3672 -       if(pri->slave == -1) return;
3673 +       if(pri->slave < 0) return;
3674         close_addr(addr, netmask, pri->name);
3675  }
3676  
3677 diff -Naur a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
3678 --- a/arch/um/drivers/slirp_user.c      2004-01-08 22:25:11.000000000 -0500
3679 +++ b/arch/um/drivers/slirp_user.c      2004-01-08 22:32:27.000000000 -0500
3680 @@ -4,7 +4,6 @@
3681  #include <stddef.h>
3682  #include <sched.h>
3683  #include <string.h>
3684 -#include <sys/fcntl.h>
3685  #include <sys/errno.h>
3686  #include <sys/wait.h>
3687  #include <sys/signal.h>
3688 @@ -48,15 +47,15 @@
3689  
3690         return(pid);
3691  }
3692
3693 +
3694 +/* XXX This is just a trivial wrapper around os_pipe */ 
3695  static int slirp_datachan(int *mfd, int *sfd)
3696  {
3697         int fds[2], err;
3698  
3699         err = os_pipe(fds, 1, 1);
3700 -       if(err){
3701 -               printk("slirp_datachan: Failed to open pipe, errno = %d\n",
3702 -                      -err);
3703 +       if(err < 0){
3704 +               printk("slirp_datachan: Failed to open pipe, err = %d\n", -err);
3705                 return(err);
3706         }
3707  
3708 @@ -77,7 +76,7 @@
3709         pid = slirp_tramp(pri->argw.argv, sfd);
3710  
3711         if(pid < 0){
3712 -               printk("slirp_tramp failed - errno = %d\n", pid);
3713 +               printk("slirp_tramp failed - errno = %d\n", -pid);
3714                 os_close_file(sfd);     
3715                 os_close_file(mfd);     
3716                 return(pid);
3717 @@ -97,8 +96,8 @@
3718         struct slirp_data *pri = data;
3719         int status,err;
3720  
3721 -       close(fd);
3722 -       close(pri->slave);
3723 +       os_close_file(fd);
3724 +       os_close_file(pri->slave);
3725  
3726         pri->slave = -1;
3727  
3728 diff -Naur a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
3729 --- a/arch/um/drivers/ssl.c     2004-01-08 22:21:29.000000000 -0500
3730 +++ b/arch/um/drivers/ssl.c     2004-01-08 22:28:16.000000000 -0500
3731 @@ -10,6 +10,7 @@
3732  #include "linux/major.h"
3733  #include "linux/mm.h"
3734  #include "linux/init.h"
3735 +#include "linux/console.h"
3736  #include "asm/termbits.h"
3737  #include "asm/irq.h"
3738  #include "line.h"
3739 @@ -53,8 +54,9 @@
3740  
3741  static struct line_driver driver = {
3742         .name                   = "UML serial line",
3743 -       .devfs_name             = "tts/%d",
3744 -       .major                  = TTYAUX_MAJOR,
3745 +       .device_name            = "ttS",
3746 +       .devfs_name             = "tts/",
3747 +       .major                  = TTY_MAJOR,
3748         .minor_start            = 64,
3749         .type                   = TTY_DRIVER_TYPE_SERIAL,
3750         .subtype                = 0,
3751 @@ -149,6 +151,9 @@
3752         case TCSETSW:
3753         case TCGETA:
3754         case TIOCMGET:
3755 +       case TCSBRK:
3756 +       case TCSBRKP:
3757 +       case TIOCMSET:
3758                 ret = -ENOIOCTLCMD;
3759                 break;
3760         default:
3761 @@ -212,6 +217,39 @@
3762   */
3763  static int ssl_init_done = 0;
3764  
3765 +extern int tty_init(void);
3766 +
3767 +static void ssl_console_write(struct console *c, const char *string, 
3768 +                             unsigned len)
3769 +{
3770 +       struct line *line = &serial_lines[c->index];
3771 +       if(ssl_init_done)
3772 +               down(&line->sem);
3773 +       console_write_chan(&line->chan_list, string, len);
3774 +       if(ssl_init_done)
3775 +               up(&line->sem);
3776 +}
3777 +
3778 +static struct tty_driver *ssl_console_device(struct console *c, int *index)
3779 +{
3780 +       *index = c->index;
3781 +       return ssl_driver;
3782 +}
3783 +
3784 +static int ssl_console_setup(struct console *co, char *options)
3785 +{
3786 +       return(0);
3787 +}
3788 +
3789 +static struct console ssl_cons = {
3790 +       name:           "ttyS",
3791 +       write:          ssl_console_write,
3792 +       device:         ssl_console_device,
3793 +       setup:          ssl_console_setup,
3794 +       flags:          CON_PRINTBUFFER,
3795 +       index:          -1,
3796 +};
3797 +
3798  int ssl_init(void)
3799  {
3800         char *new_title;
3801 @@ -219,6 +257,8 @@
3802         printk(KERN_INFO "Initializing software serial port version %d\n", 
3803                ssl_version);
3804  
3805 +       tty_init();
3806 +
3807         ssl_driver = line_register_devfs(&lines, &driver, &ssl_ops,
3808                 serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]));
3809  
3810 @@ -227,6 +267,7 @@
3811         new_title = add_xterm_umid(opts.xterm_title);
3812         if(new_title != NULL) opts.xterm_title = new_title;
3813  
3814 +       register_console(&ssl_cons);
3815         ssl_init_done = 1;
3816         return(0);
3817  }
3818 @@ -235,9 +276,9 @@
3819  
3820  static int ssl_chan_setup(char *str)
3821  {
3822 -       line_setup(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]),
3823 -                  str, 1);
3824 -       return(1);
3825 +       return(line_setup(serial_lines, 
3826 +                         sizeof(serial_lines)/sizeof(serial_lines[0]), 
3827 +                         str, 1));
3828  }
3829  
3830  __setup("ssl", ssl_chan_setup);
3831 diff -Naur a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
3832 --- a/arch/um/drivers/stdio_console.c   2004-01-08 22:16:37.000000000 -0500
3833 +++ b/arch/um/drivers/stdio_console.c   2004-01-08 22:22:42.000000000 -0500
3834 @@ -83,7 +83,8 @@
3835  
3836  static struct line_driver driver = {
3837         .name                   = "UML console",
3838 -       .devfs_name             = "vc/%d",
3839 +       .device_name            = "tty",
3840 +       .devfs_name             = "vc/",
3841         .major                  = TTY_MAJOR,
3842         .minor_start            = 0,
3843         .type                   = TTY_DRIVER_TYPE_CONSOLE,
3844 @@ -159,14 +160,28 @@
3845  
3846  static int con_init_done = 0;
3847  
3848 +static struct tty_operations console_ops = {
3849 +       .open                   = con_open,
3850 +       .close                  = con_close,
3851 +       .write                  = con_write,
3852 +       .chars_in_buffer        = chars_in_buffer,
3853 +       .set_termios            = set_termios,
3854 +       .write_room             = line_write_room,
3855 +};
3856 +
3857 +extern int tty_init(void);
3858 +
3859  int stdio_init(void)
3860  {
3861         char *new_title;
3862  
3863         printk(KERN_INFO "Initializing stdio console driver\n");
3864  
3865 +       tty_init();
3866 +
3867         console_driver = line_register_devfs(&console_lines, &driver,
3868 -                               &console_ops, vts, sizeof(vts)/sizeof(vts[0]));
3869 +                                            &console_ops, vts,
3870 +                                            sizeof(vts)/sizeof(vts[0]));
3871  
3872         lines_init(vts, sizeof(vts)/sizeof(vts[0]));
3873  
3874 @@ -183,19 +198,14 @@
3875  static void console_write(struct console *console, const char *string, 
3876                           unsigned len)
3877  {
3878 -       if(con_init_done) down(&vts[console->index].sem);
3879 -       console_write_chan(&vts[console->index].chan_list, string, len);
3880 -       if(con_init_done) up(&vts[console->index].sem);
3881 -}
3882 +       struct line *line = &vts[console->index];
3883  
3884 -static struct tty_operations console_ops = {
3885 -       .open                   = con_open,
3886 -       .close                  = con_close,
3887 -       .write                  = con_write,
3888 -       .chars_in_buffer        = chars_in_buffer,
3889 -       .set_termios            = set_termios,
3890 -       .write_room             = line_write_room,
3891 -};
3892 +       if(con_init_done)
3893 +               down(&line->sem);
3894 +       console_write_chan(&line->chan_list, string, len);
3895 +       if(con_init_done)
3896 +               up(&line->sem);
3897 +}
3898  
3899  static struct tty_driver *console_device(struct console *c, int *index)
3900  {
3901 @@ -208,22 +218,28 @@
3902         return(0);
3903  }
3904  
3905 -static struct console stdiocons = INIT_CONSOLE("tty", console_write, 
3906 -                                              console_device, console_setup,
3907 -                                              CON_PRINTBUFFER);
3908 +static struct console stdiocons = {
3909 +       name:           "tty",
3910 +       write:          console_write,
3911 +       device:         console_device,
3912 +       setup:          console_setup,
3913 +       flags:          CON_PRINTBUFFER,
3914 +       index:          -1,
3915 +};
3916  
3917 -static void __init stdio_console_init(void)
3918 +static int __init stdio_console_init(void)
3919  {
3920         INIT_LIST_HEAD(&vts[0].chan_list);
3921         list_add(&init_console_chan.list, &vts[0].chan_list);
3922         register_console(&stdiocons);
3923 +       return(0);
3924  }
3925 +
3926  console_initcall(stdio_console_init);
3927  
3928  static int console_chan_setup(char *str)
3929  {
3930 -       line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1);
3931 -       return(1);
3932 +       return(line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1));
3933  }
3934  
3935  __setup("con", console_chan_setup);
3936 diff -Naur a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
3937 --- a/arch/um/drivers/tty.c     2004-01-08 22:18:51.000000000 -0500
3938 +++ b/arch/um/drivers/tty.c     2004-01-08 22:24:43.000000000 -0500
3939 @@ -5,7 +5,6 @@
3940  
3941  #include <stdio.h>
3942  #include <termios.h>
3943 -#include <fcntl.h>
3944  #include <errno.h>
3945  #include <unistd.h>
3946  #include "chan_user.h"
3947 @@ -30,7 +29,8 @@
3948         }
3949         str++;
3950  
3951 -       if((data = um_kmalloc(sizeof(*data))) == NULL) 
3952 +       data = um_kmalloc(sizeof(*data)); 
3953 +       if(data == NULL) 
3954                 return(NULL);
3955         *data = ((struct tty_chan) { .dev       = str,
3956                                      .raw       = opts->raw });
3957 diff -Naur a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
3958 --- a/arch/um/drivers/ubd_kern.c        2004-01-08 22:21:09.000000000 -0500
3959 +++ b/arch/um/drivers/ubd_kern.c        2004-01-08 22:27:27.000000000 -0500
3960 @@ -8,6 +8,13 @@
3961   * old style ubd by setting UBD_SHIFT to 0
3962   * 2002-09-27...2002-10-18 massive tinkering for 2.5
3963   * partitions have changed in 2.5
3964 + * 2003-01-29 more tinkering for 2.5.59-1
3965 + * This should now address the sysfs problems and has
3966 + * the symlink for devfs to allow for booting with
3967 + * the common /dev/ubd/discX/... names rather than
3968 + * only /dev/ubdN/discN this version also has lots of
3969 + * clean ups preparing for ubd-many.
3970 + * James McMechan
3971   */
3972  
3973  #define MAJOR_NR UBD_MAJOR
3974 @@ -40,9 +47,12 @@
3975  #include "mconsole_kern.h"
3976  #include "init.h"
3977  #include "irq_user.h"
3978 +#include "irq_kern.h"
3979  #include "ubd_user.h"
3980  #include "2_5compat.h"
3981  #include "os.h"
3982 +#include "mem.h"
3983 +#include "mem_kern.h"
3984  
3985  static spinlock_t ubd_io_lock = SPIN_LOCK_UNLOCKED;
3986  static spinlock_t ubd_lock = SPIN_LOCK_UNLOCKED;
3987 @@ -56,6 +66,10 @@
3988  
3989  #define MAX_DEV (8)
3990  
3991 +/* Changed in early boot */
3992 +static int ubd_do_mmap = 0;
3993 +#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE
3994 +
3995  static struct block_device_operations ubd_blops = {
3996          .owner         = THIS_MODULE,
3997          .open          = ubd_open,
3998 @@ -67,7 +81,7 @@
3999  static request_queue_t *ubd_queue;
4000  
4001  /* Protected by ubd_lock */
4002 -static int fake_major = 0;
4003 +static int fake_major = MAJOR_NR;
4004  
4005  static struct gendisk *ubd_gendisk[MAX_DEV];
4006  static struct gendisk *fake_gendisk[MAX_DEV];
4007 @@ -96,13 +110,19 @@
4008  
4009  struct ubd {
4010         char *file;
4011 -       int is_dir;
4012         int count;
4013         int fd;
4014         __u64 size;
4015         struct openflags boot_openflags;
4016         struct openflags openflags;
4017 +       int no_cow;
4018         struct cow cow;
4019 +
4020 +       int map_writes;
4021 +       int map_reads;
4022 +       int nomap_writes;
4023 +       int nomap_reads;
4024 +       int write_maps;
4025  };
4026  
4027  #define DEFAULT_COW { \
4028 @@ -115,21 +135,28 @@
4029  
4030  #define DEFAULT_UBD { \
4031         .file =                 NULL, \
4032 -       .is_dir =               0, \
4033         .count =                0, \
4034         .fd =                   -1, \
4035         .size =                 -1, \
4036         .boot_openflags =       OPEN_FLAGS, \
4037         .openflags =            OPEN_FLAGS, \
4038 +        .no_cow =               0, \
4039          .cow =                 DEFAULT_COW, \
4040 +       .map_writes             = 0, \
4041 +       .map_reads              = 0, \
4042 +       .nomap_writes           = 0, \
4043 +       .nomap_reads            = 0, \
4044 +       .write_maps             = 0, \
4045  }
4046  
4047  struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
4048  
4049  static int ubd0_init(void)
4050  {
4051 -       if(ubd_dev[0].file == NULL)
4052 -               ubd_dev[0].file = "root_fs";
4053 +       struct ubd *dev = &ubd_dev[0];
4054 +
4055 +       if(dev->file == NULL)
4056 +               dev->file = "root_fs";
4057         return(0);
4058  }
4059  
4060 @@ -196,19 +223,46 @@
4061  "    Create ide0 entries that map onto ubd devices.\n\n"
4062  );
4063  
4064 +static int parse_unit(char **ptr)
4065 +{
4066 +       char *str = *ptr, *end;
4067 +       int n = -1;
4068 +
4069 +       if(isdigit(*str)) {
4070 +               n = simple_strtoul(str, &end, 0);
4071 +               if(end == str)
4072 +                       return(-1);
4073 +               *ptr = end;
4074 +       }
4075 +       else if (('a' <= *str) && (*str <= 'h')) {
4076 +               n = *str - 'a';
4077 +               str++;
4078 +               *ptr = str;
4079 +       }
4080 +       return(n);
4081 +}
4082 +
4083  static int ubd_setup_common(char *str, int *index_out)
4084  {
4085 +       struct ubd *dev;
4086         struct openflags flags = global_openflags;
4087         char *backing_file;
4088         int n, err;
4089  
4090         if(index_out) *index_out = -1;
4091 -       n = *str++;
4092 +       n = *str;
4093         if(n == '='){
4094 -               static int fake_major_allowed = 1;
4095                 char *end;
4096                 int major;
4097  
4098 +               str++;
4099 +               if(!strcmp(str, "mmap")){
4100 +                       CHOOSE_MODE(printk("mmap not supported by the ubd "
4101 +                                          "driver in tt mode\n"),
4102 +                                   ubd_do_mmap = 1);
4103 +                       return(0);
4104 +               }
4105 +
4106                 if(!strcmp(str, "sync")){
4107                         global_openflags.s = 1;
4108                         return(0);
4109 @@ -220,20 +274,14 @@
4110                         return(1);
4111                 }
4112  
4113 -               if(!fake_major_allowed){
4114 -                       printk(KERN_ERR "Can't assign a fake major twice\n");
4115 -                       return(1);
4116 -               }
4117 -
4118                 err = 1;
4119                 spin_lock(&ubd_lock);
4120 -               if(!fake_major_allowed){
4121 +               if(fake_major != MAJOR_NR){
4122                         printk(KERN_ERR "Can't assign a fake major twice\n");
4123                         goto out1;
4124                 }
4125   
4126                 fake_major = major;
4127 -               fake_major_allowed = 0;
4128  
4129                 printk(KERN_INFO "Setting extra ubd major number to %d\n",
4130                        major);
4131 @@ -243,25 +291,23 @@
4132                 return(err);
4133         }
4134  
4135 -       if(n < '0'){
4136 -               printk(KERN_ERR "ubd_setup : index out of range\n"); }
4137 -
4138 -       if((n >= '0') && (n <= '9')) n -= '0';
4139 -       else if((n >= 'a') && (n <= 'z')) n -= 'a';
4140 -       else {
4141 -               printk(KERN_ERR "ubd_setup : device syntax invalid\n");
4142 +       n = parse_unit(&str);
4143 +       if(n < 0){
4144 +               printk(KERN_ERR "ubd_setup : couldn't parse unit number "
4145 +                      "'%s'\n", str);
4146                 return(1);
4147         }
4148         if(n >= MAX_DEV){
4149 -               printk(KERN_ERR "ubd_setup : index out of range "
4150 -                      "(%d devices)\n", MAX_DEV);      
4151 +               printk(KERN_ERR "ubd_setup : index %d out of range "
4152 +                      "(%d devices)\n", n, MAX_DEV);
4153                 return(1);
4154         }
4155  
4156         err = 1;
4157         spin_lock(&ubd_lock);
4158  
4159 -       if(ubd_dev[n].file != NULL){
4160 +       dev = &ubd_dev[n];
4161 +       if(dev->file != NULL){
4162                 printk(KERN_ERR "ubd_setup : device already configured\n");
4163                 goto out2;
4164         }
4165 @@ -276,6 +322,11 @@
4166                 flags.s = 1;
4167                 str++;
4168         }
4169 +       if (*str == 'd'){
4170 +               dev->no_cow = 1;
4171 +               str++;
4172 +       }
4173 +
4174         if(*str++ != '='){
4175                 printk(KERN_ERR "ubd_setup : Expected '='\n");
4176                 goto out2;
4177 @@ -284,14 +335,17 @@
4178         err = 0;
4179         backing_file = strchr(str, ',');
4180         if(backing_file){
4181 -               *backing_file = '\0';
4182 -               backing_file++;
4183 +               if(dev->no_cow)
4184 +                       printk(KERN_ERR "Can't specify both 'd' and a "
4185 +                              "cow file\n");
4186 +               else {
4187 +                       *backing_file = '\0';
4188 +                       backing_file++;
4189 +               }
4190         }
4191 -       ubd_dev[n].file = str;
4192 -       if(ubd_is_dir(ubd_dev[n].file))
4193 -               ubd_dev[n].is_dir = 1;
4194 -       ubd_dev[n].cow.file = backing_file;
4195 -       ubd_dev[n].boot_openflags = flags;
4196 +       dev->file = str;
4197 +       dev->cow.file = backing_file;
4198 +       dev->boot_openflags = flags;
4199   out2:
4200         spin_unlock(&ubd_lock);
4201         return(err);
4202 @@ -321,8 +375,7 @@
4203  static int fakehd_set = 0;
4204  static int fakehd(char *str)
4205  {
4206 -       printk(KERN_INFO 
4207 -              "fakehd : Changing ubd name to \"hd\".\n");
4208 +       printk(KERN_INFO "fakehd : Changing ubd name to \"hd\".\n");
4209         fakehd_set = 1;
4210         return 1;
4211  }
4212 @@ -368,32 +421,42 @@
4213  {
4214         struct io_thread_req req;
4215         struct request *rq = elv_next_request(ubd_queue);
4216 -       int n;
4217 +       int n, err;
4218  
4219         do_ubd = NULL;
4220         intr_count++;
4221         n = read_ubd_fs(thread_fd, &req, sizeof(req));
4222         if(n != sizeof(req)){
4223                 printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
4224 -                      "errno = %d\n", os_getpid(), -n);
4225 +                      "err = %d\n", os_getpid(), -n);
4226                 spin_lock(&ubd_io_lock);
4227                 end_request(rq, 0);
4228                 spin_unlock(&ubd_io_lock);
4229                 return;
4230         }
4231          
4232 -        if((req.offset != ((__u64) (rq->sector)) << 9) ||
4233 -          (req.length != (rq->current_nr_sectors) << 9))
4234 +       if((req.op != UBD_MMAP) && 
4235 +          ((req.offset != ((__u64) (rq->sector)) << 9) ||
4236 +           (req.length != (rq->current_nr_sectors) << 9)))
4237                 panic("I/O op mismatch");
4238         
4239 +       if(req.map_fd != -1){
4240 +               err = physmem_subst_mapping(req.buffer, req.map_fd, 
4241 +                                           req.map_offset, 1);
4242 +               if(err)
4243 +                       printk("ubd_handler - physmem_subst_mapping failed, "
4244 +                              "err = %d\n", -err);
4245 +       }
4246 +
4247         ubd_finish(rq, req.error);
4248         reactivate_fd(thread_fd, UBD_IRQ);      
4249         do_ubd_request(ubd_queue);
4250  }
4251  
4252 -static void ubd_intr(int irq, void *dev, struct pt_regs *unused)
4253 +static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused)
4254  {
4255         ubd_handler();
4256 +       return(IRQ_HANDLED);
4257  }
4258  
4259  /* Only changed by ubd_init, which is an initcall. */
4260 @@ -429,18 +492,20 @@
4261  static int ubd_open_dev(struct ubd *dev)
4262  {
4263         struct openflags flags;
4264 -       int err, n, create_cow, *create_ptr;
4265 +       char **back_ptr;
4266 +       int err, create_cow, *create_ptr;
4267  
4268 +       dev->openflags = dev->boot_openflags;
4269         create_cow = 0;
4270         create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
4271 -       dev->fd = open_ubd_file(dev->file, &dev->openflags, &dev->cow.file,
4272 +       back_ptr = dev->no_cow ? NULL : &dev->cow.file;
4273 +       dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr,
4274                                 &dev->cow.bitmap_offset, &dev->cow.bitmap_len, 
4275                                 &dev->cow.data_offset, create_ptr);
4276  
4277         if((dev->fd == -ENOENT) && create_cow){
4278 -               n = dev - ubd_dev;
4279                 dev->fd = create_cow_file(dev->file, dev->cow.file, 
4280 -                                         dev->openflags, 1 << 9,
4281 +                                         dev->openflags, 1 << 9, PAGE_SIZE,
4282                                           &dev->cow.bitmap_offset, 
4283                                           &dev->cow.bitmap_len,
4284                                           &dev->cow.data_offset);
4285 @@ -455,13 +520,17 @@
4286         if(dev->cow.file != NULL){
4287                 err = -ENOMEM;
4288                 dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
4289 -               if(dev->cow.bitmap == NULL) goto error;
4290 +               if(dev->cow.bitmap == NULL){
4291 +                       printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
4292 +                       goto error;
4293 +               }
4294                 flush_tlb_kernel_vm();
4295  
4296                 err = read_cow_bitmap(dev->fd, dev->cow.bitmap, 
4297                                       dev->cow.bitmap_offset, 
4298                                       dev->cow.bitmap_len);
4299 -               if(err) goto error;
4300 +               if(err < 0)
4301 +                       goto error;
4302  
4303                 flags = dev->openflags;
4304                 flags.w = 0;
4305 @@ -481,17 +550,31 @@
4306                         
4307  {
4308         struct gendisk *disk;
4309 +       char from[sizeof("ubd/nnnnn\0")], to[sizeof("discnnnnn/disc\0")];
4310 +       int err;
4311  
4312         disk = alloc_disk(1 << UBD_SHIFT);
4313 -       if (!disk)
4314 -               return -ENOMEM;
4315 +       if(disk == NULL)
4316 +               return(-ENOMEM);
4317  
4318         disk->major = major;
4319         disk->first_minor = unit << UBD_SHIFT;
4320         disk->fops = &ubd_blops;
4321         set_capacity(disk, size / 512);
4322 -       sprintf(disk->disk_name, "ubd");
4323 -       sprintf(disk->devfs_name, "ubd/disc%d", unit);
4324 +       if(major == MAJOR_NR){
4325 +               sprintf(disk->disk_name, "ubd%c", 'a' + unit);
4326 +               sprintf(disk->devfs_name, "ubd/disc%d", unit);
4327 +               sprintf(from, "ubd/%d", unit);
4328 +               sprintf(to, "disc%d/disc", unit);
4329 +               err = devfs_mk_symlink(from, to);
4330 +               if(err)
4331 +                       printk("ubd_new_disk failed to make link from %s to "
4332 +                              "%s, error = %d\n", from, to, err);
4333 +       }
4334 +       else {
4335 +               sprintf(disk->disk_name, "ubd_fake%d", unit);
4336 +               sprintf(disk->devfs_name, "ubd_fake/disc%d", unit);
4337 +       }
4338  
4339         disk->private_data = &ubd_dev[unit];
4340         disk->queue = ubd_queue;
4341 @@ -506,24 +589,21 @@
4342         struct ubd *dev = &ubd_dev[n];
4343         int err;
4344  
4345 -       if(dev->is_dir)
4346 -               return(-EISDIR);
4347 -
4348 -       if (!dev->file)
4349 +       if(dev->file == NULL)
4350                 return(-ENODEV);
4351  
4352         if (ubd_open_dev(dev))
4353                 return(-ENODEV);
4354  
4355         err = ubd_file_size(dev, &dev->size);
4356 -       if(err)
4357 +       if(err < 0)
4358                 return(err);
4359  
4360         err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
4361         if(err) 
4362                 return(err);
4363   
4364 -       if(fake_major)
4365 +       if(fake_major != MAJOR_NR)
4366                 ubd_new_disk(fake_major, dev->size, n, 
4367                              &fake_gendisk[n]);
4368  
4369 @@ -561,42 +641,42 @@
4370         return(err);
4371  }
4372  
4373 -static int ubd_get_config(char *dev, char *str, int size, char **error_out)
4374 +static int ubd_get_config(char *name, char *str, int size, char **error_out)
4375  {
4376 -       struct ubd *ubd;
4377 +       struct ubd *dev;
4378         char *end;
4379 -       int major, n = 0;
4380 +       int n, len = 0;
4381  
4382 -       major = simple_strtoul(dev, &end, 0);
4383 -       if((*end != '\0') || (end == dev)){
4384 -               *error_out = "ubd_get_config : didn't parse major number";
4385 +       n = simple_strtoul(name, &end, 0);
4386 +       if((*end != '\0') || (end == name)){
4387 +               *error_out = "ubd_get_config : didn't parse device number";
4388                 return(-1);
4389         }
4390  
4391 -       if((major >= MAX_DEV) || (major < 0)){
4392 -               *error_out = "ubd_get_config : major number out of range";
4393 +       if((n >= MAX_DEV) || (n < 0)){
4394 +               *error_out = "ubd_get_config : device number out of range";
4395                 return(-1);
4396         }
4397  
4398 -       ubd = &ubd_dev[major];
4399 +       dev = &ubd_dev[n];
4400         spin_lock(&ubd_lock);
4401  
4402 -       if(ubd->file == NULL){
4403 -               CONFIG_CHUNK(str, size, n, "", 1);
4404 +       if(dev->file == NULL){
4405 +               CONFIG_CHUNK(str, size, len, "", 1);
4406                 goto out;
4407         }
4408  
4409 -       CONFIG_CHUNK(str, size, n, ubd->file, 0);
4410 +       CONFIG_CHUNK(str, size, len, dev->file, 0);
4411  
4412 -       if(ubd->cow.file != NULL){
4413 -               CONFIG_CHUNK(str, size, n, ",", 0);
4414 -               CONFIG_CHUNK(str, size, n, ubd->cow.file, 1);
4415 +       if(dev->cow.file != NULL){
4416 +               CONFIG_CHUNK(str, size, len, ",", 0);
4417 +               CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
4418         }
4419 -       else CONFIG_CHUNK(str, size, n, "", 1);
4420 +       else CONFIG_CHUNK(str, size, len, "", 1);
4421  
4422   out:
4423         spin_unlock(&ubd_lock);
4424 -       return(n);
4425 +       return(len);
4426  }
4427  
4428  static int ubd_remove(char *str)
4429 @@ -604,11 +684,9 @@
4430         struct ubd *dev;
4431         int n, err = -ENODEV;
4432  
4433 -       if(!isdigit(*str))
4434 -               return(err);    /* it should be a number 0-7/a-h */
4435 +       n = parse_unit(&str);
4436  
4437 -       n = *str - '0';
4438 -       if(n >= MAX_DEV) 
4439 +       if((n < 0) || (n >= MAX_DEV))
4440                 return(err);
4441  
4442         dev = &ubd_dev[n];
4443 @@ -669,7 +747,7 @@
4444                 
4445         elevator_init(ubd_queue, &elevator_noop);
4446  
4447 -       if (fake_major != 0) {
4448 +       if (fake_major != MAJOR_NR) {
4449                 char name[sizeof("ubd_nnn\0")];
4450  
4451                 snprintf(name, sizeof(name), "ubd_%d", fake_major);
4452 @@ -696,6 +774,7 @@
4453         io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *), 
4454                                  &thread_fd);
4455         if(io_pid < 0){
4456 +               io_pid = -1;
4457                 printk(KERN_ERR 
4458                        "ubd : Failed to start I/O thread (errno = %d) - "
4459                        "falling back to synchronous I/O\n", -io_pid);
4460 @@ -703,8 +782,8 @@
4461         }
4462         err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, 
4463                              SA_INTERRUPT, "ubd", ubd_dev);
4464 -       if(err != 0) printk(KERN_ERR 
4465 -                           "um_request_irq failed - errno = %d\n", -err);
4466 +       if(err != 0) 
4467 +               printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
4468         return(err);
4469  }
4470  
4471 @@ -714,15 +793,9 @@
4472  {
4473         struct gendisk *disk = inode->i_bdev->bd_disk;
4474         struct ubd *dev = disk->private_data;
4475 -       int err = -EISDIR;
4476 -
4477 -       if(dev->is_dir == 1)
4478 -               goto out;
4479 +       int err = 0;
4480  
4481 -       err = 0;
4482         if(dev->count == 0){
4483 -               dev->openflags = dev->boot_openflags;
4484 -
4485                 err = ubd_open_dev(dev);
4486                 if(err){
4487                         printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
4488 @@ -749,62 +822,156 @@
4489         return(0);
4490  }
4491  
4492 -void cowify_req(struct io_thread_req *req, struct ubd *dev)
4493 +static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask, 
4494 +                         __u64 *cow_offset, unsigned long *bitmap, 
4495 +                         __u64 bitmap_offset, unsigned long *bitmap_words,
4496 +                         __u64 bitmap_len)
4497 +{
4498 +       __u64 sector = io_offset >> 9;
4499 +       int i, update_bitmap = 0;
4500 +
4501 +       for(i = 0; i < length >> 9; i++){
4502 +               if(cow_mask != NULL)
4503 +                       ubd_set_bit(i, (unsigned char *) cow_mask);
4504 +               if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
4505 +                       continue;
4506 +
4507 +               update_bitmap = 1;
4508 +               ubd_set_bit(sector + i, (unsigned char *) bitmap);
4509 +       }
4510 +
4511 +       if(!update_bitmap)
4512 +               return;
4513 +
4514 +       *cow_offset = sector / (sizeof(unsigned long) * 8);
4515 +
4516 +       /* This takes care of the case where we're exactly at the end of the
4517 +        * device, and *cow_offset + 1 is off the end.  So, just back it up
4518 +        * by one word.  Thanks to Lynn Kerby for the fix and James McMechan
4519 +        * for the original diagnosis.
4520 +        */
4521 +       if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) / 
4522 +                          sizeof(unsigned long) - 1))
4523 +               (*cow_offset)--;
4524 +
4525 +       bitmap_words[0] = bitmap[*cow_offset];
4526 +       bitmap_words[1] = bitmap[*cow_offset + 1];
4527 +
4528 +       *cow_offset *= sizeof(unsigned long);
4529 +       *cow_offset += bitmap_offset;
4530 +}
4531 +
4532 +static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, 
4533 +                      __u64 bitmap_offset, __u64 bitmap_len)
4534  {
4535 -        int i, update_bitmap, sector = req->offset >> 9;
4536 +       __u64 sector = req->offset >> 9;
4537 +       int i;
4538  
4539         if(req->length > (sizeof(req->sector_mask) * 8) << 9)
4540                 panic("Operation too long");
4541 +
4542         if(req->op == UBD_READ) {
4543                 for(i = 0; i < req->length >> 9; i++){
4544 -                       if(ubd_test_bit(sector + i, (unsigned char *) 
4545 -                                       dev->cow.bitmap)){
4546 +                       if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
4547                                 ubd_set_bit(i, (unsigned char *) 
4548                                             &req->sector_mask);
4549 -                       }
4550                  }
4551 -        } 
4552 -        else {
4553 -               update_bitmap = 0;
4554 -               for(i = 0; i < req->length >> 9; i++){
4555 -                       ubd_set_bit(i, (unsigned char *) 
4556 -                                   &req->sector_mask);
4557 -                       if(!ubd_test_bit(sector + i, (unsigned char *) 
4558 -                                        dev->cow.bitmap))
4559 -                               update_bitmap = 1;
4560 -                       ubd_set_bit(sector + i, (unsigned char *) 
4561 -                                   dev->cow.bitmap);
4562 -               }
4563 -               if(update_bitmap){
4564 -                       req->cow_offset = sector / (sizeof(unsigned long) * 8);
4565 -                       req->bitmap_words[0] = 
4566 -                               dev->cow.bitmap[req->cow_offset];
4567 -                       req->bitmap_words[1] = 
4568 -                               dev->cow.bitmap[req->cow_offset + 1];
4569 -                       req->cow_offset *= sizeof(unsigned long);
4570 -                       req->cow_offset += dev->cow.bitmap_offset;
4571 +       }
4572 +       else cowify_bitmap(req->offset, req->length, &req->sector_mask,
4573 +                          &req->cow_offset, bitmap, bitmap_offset, 
4574 +                          req->bitmap_words, bitmap_len);
4575 +}
4576 +
4577 +static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset)
4578 +{
4579 +       __u64 sector;
4580 +       unsigned char *bitmap;
4581 +       int bit, i;
4582 +
4583 +       /* mmap must have been requested on the command line */
4584 +       if(!ubd_do_mmap)
4585 +               return(-1);
4586 +
4587 +       /* The buffer must be page aligned */
4588 +       if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0)
4589 +               return(-1);
4590 +
4591 +       /* The request must be a page long */
4592 +       if((req->current_nr_sectors << 9) != PAGE_SIZE)
4593 +               return(-1);
4594 +
4595 +       if(dev->cow.file == NULL)
4596 +               return(dev->fd);
4597 +
4598 +       sector = offset >> 9;
4599 +       bitmap = (unsigned char *) dev->cow.bitmap;
4600 +       bit = ubd_test_bit(sector, bitmap);
4601 +
4602 +       for(i = 1; i < req->current_nr_sectors; i++){
4603 +               if(ubd_test_bit(sector + i, bitmap) != bit)
4604 +                       return(-1);
4605 +       }
4606 +
4607 +       if(bit || (rq_data_dir(req) == WRITE))
4608 +               offset += dev->cow.data_offset;
4609 +
4610 +       /* The data on disk must be page aligned */
4611 +       if((offset % UBD_MMAP_BLOCK_SIZE) != 0)
4612 +               return(-1);
4613 +
4614 +       return(bit ? dev->fd : dev->cow.fd);
4615 +}
4616 +
4617 +static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset, 
4618 +                               struct request *req, 
4619 +                               struct io_thread_req *io_req)
4620 +{
4621 +       int err;
4622 +
4623 +       if(rq_data_dir(req) == WRITE){
4624 +               /* Writes are almost no-ops since the new data is already in the
4625 +                * host page cache
4626 +                */
4627 +               dev->map_writes++;
4628 +               if(dev->cow.file != NULL)
4629 +                       cowify_bitmap(io_req->offset, io_req->length, 
4630 +                                     &io_req->sector_mask, &io_req->cow_offset,
4631 +                                     dev->cow.bitmap, dev->cow.bitmap_offset,
4632 +                                     io_req->bitmap_words, 
4633 +                                     dev->cow.bitmap_len);
4634 +       }
4635 +       else {
4636 +               int w;
4637 +
4638 +               if((dev->cow.file != NULL) && (fd == dev->cow.fd))
4639 +                       w = 0;
4640 +               else w = dev->openflags.w;
4641 +
4642 +               if((dev->cow.file != NULL) && (fd == dev->fd))
4643 +                       offset += dev->cow.data_offset;
4644 +
4645 +               err = physmem_subst_mapping(req->buffer, fd, offset, w);
4646 +               if(err){
4647 +                       printk("physmem_subst_mapping failed, err = %d\n", 
4648 +                              -err);
4649 +                       return(1);
4650                 }
4651 +               dev->map_reads++;
4652         }
4653 +       io_req->op = UBD_MMAP;
4654 +       io_req->buffer = req->buffer;
4655 +       return(0);
4656  }
4657  
4658  static int prepare_request(struct request *req, struct io_thread_req *io_req)
4659  {
4660         struct gendisk *disk = req->rq_disk;
4661         struct ubd *dev = disk->private_data;
4662 -       __u64 block;
4663 -       int nsect;
4664 +       __u64 offset;
4665 +       int len, fd;
4666  
4667         if(req->rq_status == RQ_INACTIVE) return(1);
4668  
4669 -       if(dev->is_dir){
4670 -               strcpy(req->buffer, "HOSTFS:");
4671 -               strcat(req->buffer, dev->file);
4672 -               spin_lock(&ubd_io_lock);
4673 -               end_request(req, 1);
4674 -               spin_unlock(&ubd_io_lock);
4675 -               return(1);
4676 -       }
4677 -
4678         if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
4679                 printk("Write attempted on readonly ubd device %s\n", 
4680                        disk->disk_name);
4681 @@ -814,23 +981,49 @@
4682                 return(1);
4683         }
4684  
4685 -        block = req->sector;
4686 -        nsect = req->current_nr_sectors;
4687 +       offset = ((__u64) req->sector) << 9;
4688 +       len = req->current_nr_sectors << 9;
4689  
4690 -       io_req->op = rq_data_dir(req) == READ ? UBD_READ : UBD_WRITE;
4691         io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
4692         io_req->fds[1] = dev->fd;
4693 +       io_req->map_fd = -1;
4694 +       io_req->cow_offset = -1;
4695 +       io_req->offset = offset;
4696 +       io_req->length = len;
4697 +       io_req->error = 0;
4698 +       io_req->sector_mask = 0;
4699 +
4700 +       fd = mmap_fd(req, dev, io_req->offset);
4701 +       if(fd > 0){
4702 +               /* If mmapping is otherwise OK, but the first access to the 
4703 +                * page is a write, then it's not mapped in yet.  So we have 
4704 +                * to write the data to disk first, then we can map the disk
4705 +                * page in and continue normally from there.
4706 +                */
4707 +               if((rq_data_dir(req) == WRITE) && !is_remapped(req->buffer)){
4708 +                       io_req->map_fd = dev->fd;
4709 +                       io_req->map_offset = io_req->offset + 
4710 +                               dev->cow.data_offset;
4711 +                       dev->write_maps++;
4712 +               }
4713 +               else return(prepare_mmap_request(dev, fd, io_req->offset, req, 
4714 +                                                io_req));
4715 +       }
4716 +
4717 +       if(rq_data_dir(req) == READ)
4718 +               dev->nomap_reads++;
4719 +       else dev->nomap_writes++;
4720 +
4721 +       io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
4722         io_req->offsets[0] = 0;
4723         io_req->offsets[1] = dev->cow.data_offset;
4724 -       io_req->offset = ((__u64) block) << 9;
4725 -       io_req->length = nsect << 9;
4726         io_req->buffer = req->buffer;
4727         io_req->sectorsize = 1 << 9;
4728 -       io_req->sector_mask = 0;
4729 -       io_req->cow_offset = -1;
4730 -       io_req->error = 0;
4731  
4732 -        if(dev->cow.file != NULL) cowify_req(io_req, dev);
4733 +       if(dev->cow.file != NULL) 
4734 +               cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset,
4735 +                          dev->cow.bitmap_len);
4736 +
4737         return(0);
4738  }
4739  
4740 @@ -885,7 +1078,7 @@
4741                 g.heads = 128;
4742                 g.sectors = 32;
4743                 g.cylinders = dev->size / (128 * 32 * 512);
4744 -               g.start = 2;
4745 +               g.start = get_start_sect(inode->i_bdev);
4746                 return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0);
4747  
4748         case HDIO_SET_UNMASKINTR:
4749 @@ -935,6 +1128,142 @@
4750         return(-EINVAL);
4751  }
4752  
4753 +static int ubd_check_remapped(int fd, unsigned long address, int is_write,
4754 +                             __u64 offset)
4755 +{
4756 +       __u64 bitmap_offset;
4757 +       unsigned long new_bitmap[2];
4758 +       int i, err, n;
4759 +
4760 +       /* If it's not a write access, we can't do anything about it */
4761 +       if(!is_write)
4762 +               return(0);
4763 +
4764 +       /* We have a write */
4765 +       for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){
4766 +               struct ubd *dev = &ubd_dev[i];
4767 +
4768 +               if((dev->fd != fd) && (dev->cow.fd != fd))
4769 +                       continue;
4770 +
4771 +               /* It's a write to a ubd device */
4772 +
4773 +               if(!dev->openflags.w){
4774 +                       /* It's a write access on a read-only device - probably
4775 +                        * shouldn't happen.  If the kernel is trying to change
4776 +                        * something with no intention of writing it back out,
4777 +                        * then this message will clue us in that this needs
4778 +                        * fixing
4779 +                        */
4780 +                       printk("Write access to mapped page from readonly ubd "
4781 +                              "device %d\n", i);
4782 +                       return(0);
4783 +               }
4784 +
4785 +               /* It's a write to a writeable ubd device - it must be COWed
4786 +                * because, otherwise, the page would have been mapped in 
4787 +                * writeable
4788 +                */
4789 +
4790 +               if(!dev->cow.file)
4791 +                       panic("Write fault on writeable non-COW ubd device %d",
4792 +                             i);
4793 +
4794 +               /* It should also be an access to the backing file since the 
4795 +                * COW pages should be mapped in read-write
4796 +                */
4797 +
4798 +               if(fd == dev->fd)
4799 +                       panic("Write fault on a backing page of ubd "
4800 +                             "device %d\n", i);
4801 +
4802 +               /* So, we do the write, copying the backing data to the COW 
4803 +                * file... 
4804 +                */
4805 +
4806 +               err = os_seek_file(dev->fd, offset + dev->cow.data_offset);
4807 +               if(err < 0)
4808 +                       panic("Couldn't seek to %lld in COW file of ubd "
4809 +                             "device %d, err = %d", 
4810 +                             offset + dev->cow.data_offset, i, -err);
4811 +
4812 +               n = os_write_file(dev->fd, (void *) address, PAGE_SIZE);
4813 +               if(n != PAGE_SIZE)
4814 +                       panic("Couldn't copy data to COW file of ubd "
4815 +                             "device %d, err = %d", i, -n);
4816 +
4817 +               /* ... updating the COW bitmap... */
4818 +
4819 +               cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset, 
4820 +                             dev->cow.bitmap, dev->cow.bitmap_offset, 
4821 +                             new_bitmap, dev->cow.bitmap_len);
4822 +
4823 +               err = os_seek_file(dev->fd, bitmap_offset);
4824 +               if(err < 0)
4825 +                       panic("Couldn't seek to %lld in COW file of ubd "
4826 +                             "device %d, err = %d", bitmap_offset, i, -err);
4827 +
4828 +               n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap));
4829 +               if(n != sizeof(new_bitmap))
4830 +                       panic("Couldn't update bitmap  of ubd device %d, "
4831 +                             "err = %d", i, -n);
4832 +               
4833 +               /* Maybe we can map the COW page in, and maybe we can't.  If
4834 +                * it is a pre-V3 COW file, we can't, since the alignment will 
4835 +                * be wrong.  If it is a V3 or later COW file which has been 
4836 +                * moved to a system with a larger page size, then maybe we 
4837 +                * can't, depending on the exact location of the page.
4838 +                */
4839 +
4840 +               offset += dev->cow.data_offset;
4841 +
4842 +               /* Remove the remapping, putting the original anonymous page
4843 +                * back.  If the COW file can be mapped in, that is done.
4844 +                * Otherwise, the COW page is read in.
4845 +                */
4846 +
4847 +               if(!physmem_remove_mapping((void *) address))
4848 +                       panic("Address 0x%lx not remapped by ubd device %d", 
4849 +                             address, i);
4850 +               if((offset % UBD_MMAP_BLOCK_SIZE) == 0)
4851 +                       physmem_subst_mapping((void *) address, dev->fd, 
4852 +                                             offset, 1);
4853 +               else {
4854 +                       err = os_seek_file(dev->fd, offset);
4855 +                       if(err < 0)
4856 +                               panic("Couldn't seek to %lld in COW file of "
4857 +                                     "ubd device %d, err = %d", offset, i, 
4858 +                                     -err);
4859 +
4860 +                       n = os_read_file(dev->fd, (void *) address, PAGE_SIZE);
4861 +                       if(n != PAGE_SIZE)
4862 +                               panic("Failed to read page from offset %llx of "
4863 +                                     "COW file of ubd device %d, err = %d",
4864 +                                     offset, i, -n);
4865 +               }
4866 +
4867 +               return(1);
4868 +       }
4869 +
4870 +       /* It's not a write on a ubd device */
4871 +       return(0);
4872 +}
4873 +
4874 +static struct remapper ubd_remapper = {
4875 +       .list   = LIST_HEAD_INIT(ubd_remapper.list),
4876 +       .proc   = ubd_check_remapped,
4877 +};
4878 +
4879 +static int ubd_remapper_setup(void)
4880 +{
4881 +       if(ubd_do_mmap)
4882 +               register_remapper(&ubd_remapper);
4883 +
4884 +       return(0);
4885 +}
4886 +
4887 +__initcall(ubd_remapper_setup);
4888 +
4889  /*
4890   * Overrides for Emacs so that we follow Linus's tabbing style.
4891   * Emacs will notice this stuff at the end of the file and automatically
4892 diff -Naur a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
4893 --- a/arch/um/drivers/ubd_user.c        2004-01-08 22:16:38.000000000 -0500
4894 +++ b/arch/um/drivers/ubd_user.c        2004-01-08 22:22:42.000000000 -0500
4895 @@ -11,11 +11,8 @@
4896  #include <signal.h>
4897  #include <string.h>
4898  #include <netinet/in.h>
4899 -#include <sys/stat.h>
4900  #include <sys/time.h>
4901 -#include <sys/fcntl.h>
4902  #include <sys/socket.h>
4903 -#include <string.h>
4904  #include <sys/mman.h>
4905  #include <sys/param.h>
4906  #include "asm/types.h"
4907 @@ -24,146 +21,30 @@
4908  #include "user.h"
4909  #include "ubd_user.h"
4910  #include "os.h"
4911 +#include "cow.h"
4912  
4913  #include <endian.h>
4914  #include <byteswap.h>
4915 -#if __BYTE_ORDER == __BIG_ENDIAN
4916 -# define ntohll(x) (x)
4917 -# define htonll(x) (x)
4918 -#elif __BYTE_ORDER == __LITTLE_ENDIAN
4919 -# define ntohll(x)  bswap_64(x)
4920 -# define htonll(x)  bswap_64(x)
4921 -#else
4922 -#error "__BYTE_ORDER not defined"
4923 -#endif
4924 -
4925 -#define PATH_LEN_V1 256
4926 -
4927 -struct cow_header_v1 {
4928 -       int magic;
4929 -       int version;
4930 -       char backing_file[PATH_LEN_V1];
4931 -       time_t mtime;
4932 -       __u64 size;
4933 -       int sectorsize;
4934 -};
4935 -
4936 -#define PATH_LEN_V2 MAXPATHLEN
4937 -
4938 -struct cow_header_v2 {
4939 -       unsigned long magic;
4940 -       unsigned long version;
4941 -       char backing_file[PATH_LEN_V2];
4942 -       time_t mtime;
4943 -       __u64 size;
4944 -       int sectorsize;
4945 -};
4946 -
4947 -union cow_header {
4948 -       struct cow_header_v1 v1;
4949 -       struct cow_header_v2 v2;
4950 -};
4951 -
4952 -#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
4953 -#define COW_VERSION 2
4954 -
4955 -static void sizes(__u64 size, int sectorsize, int bitmap_offset, 
4956 -                 unsigned long *bitmap_len_out, int *data_offset_out)
4957 -{
4958 -       *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
4959 -
4960 -       *data_offset_out = bitmap_offset + *bitmap_len_out;
4961 -       *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
4962 -       *data_offset_out *= sectorsize;
4963 -}
4964 -
4965 -static int read_cow_header(int fd, int *magic_out, char **backing_file_out, 
4966 -                          time_t *mtime_out, __u64 *size_out, 
4967 -                          int *sectorsize_out, int *bitmap_offset_out)
4968 -{
4969 -       union cow_header *header;
4970 -       char *file;
4971 -       int err, n;
4972 -       unsigned long version, magic;
4973 -
4974 -       header = um_kmalloc(sizeof(*header));
4975 -       if(header == NULL){
4976 -               printk("read_cow_header - Failed to allocate header\n");
4977 -               return(-ENOMEM);
4978 -       }
4979 -       err = -EINVAL;
4980 -       n = read(fd, header, sizeof(*header));
4981 -       if(n < offsetof(typeof(header->v1), backing_file)){
4982 -               printk("read_cow_header - short header\n");
4983 -               goto out;
4984 -       }
4985 -
4986 -       magic = header->v1.magic;
4987 -       if(magic == COW_MAGIC) {
4988 -               version = header->v1.version;
4989 -       }
4990 -       else if(magic == ntohl(COW_MAGIC)){
4991 -               version = ntohl(header->v1.version);
4992 -       }
4993 -       else goto out;
4994 -
4995 -       *magic_out = COW_MAGIC;
4996 -
4997 -       if(version == 1){
4998 -               if(n < sizeof(header->v1)){
4999 -                       printk("read_cow_header - failed to read V1 header\n");
5000 -                       goto out;
5001 -               }
5002 -               *mtime_out = header->v1.mtime;
5003 -               *size_out = header->v1.size;
5004 -               *sectorsize_out = header->v1.sectorsize;
5005 -               *bitmap_offset_out = sizeof(header->v1);
5006 -               file = header->v1.backing_file;
5007 -       }
5008 -       else if(version == 2){
5009 -               if(n < sizeof(header->v2)){
5010 -                       printk("read_cow_header - failed to read V2 header\n");
5011 -                       goto out;
5012 -               }
5013 -               *mtime_out = ntohl(header->v2.mtime);
5014 -               *size_out = ntohll(header->v2.size);
5015 -               *sectorsize_out = ntohl(header->v2.sectorsize);
5016 -               *bitmap_offset_out = sizeof(header->v2);
5017 -               file = header->v2.backing_file;
5018 -       }
5019 -       else {
5020 -               printk("read_cow_header - invalid COW version\n");
5021 -               goto out;
5022 -       }
5023 -       err = -ENOMEM;
5024 -       *backing_file_out = uml_strdup(file);
5025 -       if(*backing_file_out == NULL){
5026 -               printk("read_cow_header - failed to allocate backing file\n");
5027 -               goto out;
5028 -       }
5029 -       err = 0;
5030 - out:
5031 -       kfree(header);
5032 -       return(err);
5033 -}
5034  
5035  static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
5036  {
5037 -       struct stat buf1, buf2;
5038 +       struct uml_stat buf1, buf2;
5039 +       int err;
5040  
5041         if(from_cmdline == NULL) return(1);
5042         if(!strcmp(from_cmdline, from_cow)) return(1);
5043  
5044 -       if(stat(from_cmdline, &buf1) < 0){
5045 -               printk("Couldn't stat '%s', errno = %d\n", from_cmdline, 
5046 -                      errno);
5047 +       err = os_stat_file(from_cmdline, &buf1);
5048 +       if(err < 0){
5049 +               printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
5050                 return(1);
5051         }
5052 -       if(stat(from_cow, &buf2) < 0){
5053 -               printk("Couldn't stat '%s', errno = %d\n", from_cow, errno);
5054 +       err = os_stat_file(from_cow, &buf2);
5055 +       if(err < 0){
5056 +               printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
5057                 return(1);
5058         }
5059 -       if((buf1.st_dev == buf2.st_dev) && (buf1.st_ino == buf2.st_ino))
5060 +       if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
5061                 return(1);
5062  
5063         printk("Backing file mismatch - \"%s\" requested,\n"
5064 @@ -174,20 +55,21 @@
5065  
5066  static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
5067  {
5068 -       struct stat64 buf;
5069 +       unsigned long modtime;
5070         long long actual;
5071         int err;
5072  
5073 -       if(stat64(file, &buf) < 0){
5074 -               printk("Failed to stat backing file \"%s\", errno = %d\n",
5075 -                      file, errno);
5076 -               return(-errno);
5077 +       err = os_file_modtime(file, &modtime);
5078 +       if(err < 0){
5079 +               printk("Failed to get modification time of backing file "
5080 +                      "\"%s\", err = %d\n", file, -err);
5081 +               return(err);
5082         }
5083  
5084         err = os_file_size(file, &actual);
5085 -       if(err){
5086 +       if(err < 0){
5087                 printk("Failed to get size of backing file \"%s\", "
5088 -                      "errno = %d\n", file, -err);
5089 +                      "err = %d\n", file, -err);
5090                 return(err);
5091         }
5092  
5093 @@ -196,9 +78,9 @@
5094                        "file\n", size, actual);
5095                 return(-EINVAL);
5096         }
5097 -       if(buf.st_mtime != mtime){
5098 +       if(modtime != mtime){
5099                 printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
5100 -                      "file\n", mtime, buf.st_mtime);
5101 +                      "file\n", mtime, modtime);
5102                 return(-EINVAL);
5103         }
5104         return(0);
5105 @@ -209,124 +91,16 @@
5106         int err;
5107  
5108         err = os_seek_file(fd, offset);
5109 -       if(err != 0) return(-errno);
5110 -       err = read(fd, buf, len);
5111 -       if(err < 0) return(-errno);
5112 -       return(0);
5113 -}
5114 +       if(err < 0) 
5115 +               return(err);
5116  
5117 -static int absolutize(char *to, int size, char *from)
5118 -{
5119 -       char save_cwd[256], *slash;
5120 -       int remaining;
5121 +       err = os_read_file(fd, buf, len);
5122 +       if(err < 0) 
5123 +               return(err);
5124  
5125 -       if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
5126 -               printk("absolutize : unable to get cwd - errno = %d\n", errno);
5127 -               return(-1);
5128 -       }
5129 -       slash = strrchr(from, '/');
5130 -       if(slash != NULL){
5131 -               *slash = '\0';
5132 -               if(chdir(from)){
5133 -                       *slash = '/';
5134 -                       printk("absolutize : Can't cd to '%s' - errno = %d\n",
5135 -                              from, errno);
5136 -                       return(-1);
5137 -               }
5138 -               *slash = '/';
5139 -               if(getcwd(to, size) == NULL){
5140 -                       printk("absolutize : unable to get cwd of '%s' - "
5141 -                              "errno = %d\n", from, errno);
5142 -                       return(-1);
5143 -               }
5144 -               remaining = size - strlen(to);
5145 -               if(strlen(slash) + 1 > remaining){
5146 -                       printk("absolutize : unable to fit '%s' into %d "
5147 -                              "chars\n", from, size);
5148 -                       return(-1);
5149 -               }
5150 -               strcat(to, slash);
5151 -       }
5152 -       else {
5153 -               if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
5154 -                       printk("absolutize : unable to fit '%s' into %d "
5155 -                              "chars\n", from, size);
5156 -                       return(-1);
5157 -               }
5158 -               strcpy(to, save_cwd);
5159 -               strcat(to, "/");
5160 -               strcat(to, from);
5161 -       }
5162 -       chdir(save_cwd);
5163         return(0);
5164  }
5165  
5166 -static int write_cow_header(char *cow_file, int fd, char *backing_file, 
5167 -                           int sectorsize, long long *size)
5168 -{
5169 -        struct cow_header_v2 *header;
5170 -       struct stat64 buf;
5171 -       int err;
5172 -
5173 -       err = os_seek_file(fd, 0);
5174 -       if(err != 0){
5175 -               printk("write_cow_header - lseek failed, errno = %d\n", errno);
5176 -               return(-errno);
5177 -       }
5178 -
5179 -       err = -ENOMEM;
5180 -       header = um_kmalloc(sizeof(*header));
5181 -       if(header == NULL){
5182 -               printk("Failed to allocate COW V2 header\n");
5183 -               goto out;
5184 -       }
5185 -       header->magic = htonl(COW_MAGIC);
5186 -       header->version = htonl(COW_VERSION);
5187 -
5188 -       err = -EINVAL;
5189 -       if(strlen(backing_file) > sizeof(header->backing_file) - 1){
5190 -               printk("Backing file name \"%s\" is too long - names are "
5191 -                      "limited to %d characters\n", backing_file, 
5192 -                      sizeof(header->backing_file) - 1);
5193 -               goto out_free;
5194 -       }
5195 -
5196 -       if(absolutize(header->backing_file, sizeof(header->backing_file), 
5197 -                     backing_file))
5198 -               goto out_free;
5199 -
5200 -       err = stat64(header->backing_file, &buf);
5201 -       if(err < 0){
5202 -               printk("Stat of backing file '%s' failed, errno = %d\n",
5203 -                      header->backing_file, errno);
5204 -               err = -errno;
5205 -               goto out_free;
5206 -       }
5207 -
5208 -       err = os_file_size(header->backing_file, size);
5209 -       if(err){
5210 -               printk("Couldn't get size of backing file '%s', errno = %d\n",
5211 -                      header->backing_file, -*size);
5212 -               goto out_free;
5213 -       }
5214 -
5215 -       header->mtime = htonl(buf.st_mtime);
5216 -       header->size = htonll(*size);
5217 -       header->sectorsize = htonl(sectorsize);
5218 -
5219 -       err = write(fd, header, sizeof(*header));
5220 -       if(err != sizeof(*header)){
5221 -               printk("Write of header to new COW file '%s' failed, "
5222 -                      "errno = %d\n", cow_file, errno);
5223 -               goto out_free;
5224 -       }
5225 -       err = 0;
5226 - out_free:
5227 -       kfree(header);
5228 - out:
5229 -       return(err);
5230 -}
5231 -
5232  int open_ubd_file(char *file, struct openflags *openflags, 
5233                   char **backing_file_out, int *bitmap_offset_out, 
5234                   unsigned long *bitmap_len_out, int *data_offset_out, 
5235 @@ -334,26 +108,36 @@
5236  {
5237         time_t mtime;
5238         __u64 size;
5239 +       __u32 version, align;
5240         char *backing_file;
5241 -        int fd, err, sectorsize, magic, same, mode = 0644;
5242 +       int fd, err, sectorsize, same, mode = 0644;
5243  
5244 -        if((fd = os_open_file(file, *openflags, mode)) < 0){
5245 +       fd = os_open_file(file, *openflags, mode);
5246 +       if(fd < 0){
5247                 if((fd == -ENOENT) && (create_cow_out != NULL))
5248                         *create_cow_out = 1;
5249                  if(!openflags->w ||
5250                     ((errno != EROFS) && (errno != EACCES))) return(-errno);
5251                 openflags->w = 0;
5252 -                if((fd = os_open_file(file, *openflags, mode)) < 0) 
5253 +               fd = os_open_file(file, *openflags, mode); 
5254 +               if(fd < 0) 
5255                         return(fd);
5256          }
5257 +
5258 +       err = os_lock_file(fd, openflags->w);
5259 +       if(err < 0){
5260 +               printk("Failed to lock '%s', err = %d\n", file, -err);
5261 +               goto out_close;
5262 +       }
5263 +       
5264         if(backing_file_out == NULL) return(fd);
5265  
5266 -       err = read_cow_header(fd, &magic, &backing_file, &mtime, &size, 
5267 -                             &sectorsize, bitmap_offset_out);
5268 +       err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
5269 +                             &size, &sectorsize, &align, bitmap_offset_out);
5270         if(err && (*backing_file_out != NULL)){
5271                 printk("Failed to read COW header from COW file \"%s\", "
5272 -                      "errno = %d\n", file, err);
5273 -               goto error;
5274 +                      "errno = %d\n", file, -err);
5275 +               goto out_close;
5276         }
5277         if(err) return(fd);
5278  
5279 @@ -363,36 +147,33 @@
5280  
5281         if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){
5282                 printk("Switching backing file to '%s'\n", *backing_file_out);
5283 -               err = write_cow_header(file, fd, *backing_file_out, 
5284 -                                      sectorsize, &size);
5285 +               err = write_cow_header(file, fd, *backing_file_out,
5286 +                                      sectorsize, align, &size);
5287                 if(err){
5288 -                       printk("Switch failed, errno = %d\n", err);
5289 +                       printk("Switch failed, errno = %d\n", -err);
5290                         return(err);
5291                 }
5292         }
5293         else {
5294                 *backing_file_out = backing_file;
5295                 err = backing_file_mismatch(*backing_file_out, size, mtime);
5296 -               if(err) goto error;
5297 +               if(err) goto out_close;
5298         }
5299  
5300 -       sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out, 
5301 -             data_offset_out);
5302 +       cow_sizes(version, size, sectorsize, align, *bitmap_offset_out, 
5303 +                 bitmap_len_out, data_offset_out);
5304  
5305          return(fd);
5306 - error:
5307 -       close(fd);
5308 + out_close:
5309 +       os_close_file(fd);
5310         return(err);
5311  }
5312  
5313  int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
5314 -                   int sectorsize, int *bitmap_offset_out, 
5315 +                   int sectorsize, int alignment, int *bitmap_offset_out, 
5316                     unsigned long *bitmap_len_out, int *data_offset_out)
5317  {
5318 -       __u64 blocks;
5319 -       long zero;
5320 -       int err, fd, i;
5321 -       long long size;
5322 +       int err, fd;
5323  
5324         flags.c = 1;
5325         fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
5326 @@ -403,57 +184,49 @@
5327                 goto out;
5328         }
5329  
5330 -       err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
5331 -       if(err) goto out_close;
5332 -
5333 -       blocks = (size + sectorsize - 1) / sectorsize;
5334 -       blocks = (blocks + sizeof(long) * 8 - 1) / (sizeof(long) * 8);
5335 -       zero = 0;
5336 -       for(i = 0; i < blocks; i++){
5337 -               err = write(fd, &zero, sizeof(zero));
5338 -               if(err != sizeof(zero)){
5339 -                       printk("Write of bitmap to new COW file '%s' failed, "
5340 -                              "errno = %d\n", cow_file, errno);
5341 -                       goto out_close;
5342 -               }
5343 -       }
5344 -
5345 -       sizes(size, sectorsize, sizeof(struct cow_header_v2), 
5346 -             bitmap_len_out, data_offset_out);
5347 -       *bitmap_offset_out = sizeof(struct cow_header_v2);
5348 -
5349 -       return(fd);
5350 -
5351 - out_close:
5352 -       close(fd);
5353 +       err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
5354 +                           bitmap_offset_out, bitmap_len_out, 
5355 +                           data_offset_out);
5356 +       if(!err)
5357 +               return(fd);
5358 +       os_close_file(fd);
5359   out:
5360         return(err);
5361  }
5362  
5363 +/* XXX Just trivial wrappers around os_read_file and os_write_file */
5364  int read_ubd_fs(int fd, void *buffer, int len)
5365  {
5366 -       int n;
5367 -
5368 -       n = read(fd, buffer, len);
5369 -       if(n < 0) return(-errno);
5370 -       else return(n);
5371 +       return(os_read_file(fd, buffer, len));
5372  }
5373  
5374  int write_ubd_fs(int fd, char *buffer, int len)
5375  {
5376 -       int n;
5377 -
5378 -       n = write(fd, buffer, len);
5379 -       if(n < 0) return(-errno);
5380 -       else return(n);
5381 +       return(os_write_file(fd, buffer, len));
5382  }
5383  
5384 -int ubd_is_dir(char *file)
5385 +static int update_bitmap(struct io_thread_req *req)
5386  {
5387 -       struct stat64 buf;
5388 +       int n;
5389 +
5390 +       if(req->cow_offset == -1)
5391 +               return(0);
5392 +
5393 +       n = os_seek_file(req->fds[1], req->cow_offset);
5394 +       if(n < 0){
5395 +               printk("do_io - bitmap lseek failed : err = %d\n", -n);
5396 +               return(1);
5397 +       }
5398 +
5399 +       n = os_write_file(req->fds[1], &req->bitmap_words,
5400 +                         sizeof(req->bitmap_words));
5401 +       if(n != sizeof(req->bitmap_words)){
5402 +               printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
5403 +                      req->fds[1]);
5404 +               return(1);
5405 +       }
5406  
5407 -       if(stat64(file, &buf) < 0) return(0);
5408 -       return(S_ISDIR(buf.st_mode));
5409 +       return(0);
5410  }
5411  
5412  void do_io(struct io_thread_req *req)
5413 @@ -461,8 +234,18 @@
5414         char *buf;
5415         unsigned long len;
5416         int n, nsectors, start, end, bit;
5417 +       int err;
5418         __u64 off;
5419  
5420 +       if(req->op == UBD_MMAP){
5421 +               /* Touch the page to force the host to do any necessary IO to 
5422 +                * get it into memory 
5423 +                */
5424 +               n = *((volatile int *) req->buffer);
5425 +               req->error = update_bitmap(req);
5426 +               return;
5427 +       }
5428 +
5429         nsectors = req->length / req->sectorsize;
5430         start = 0;
5431         do {
5432 @@ -473,15 +256,14 @@
5433                                     &req->sector_mask) == bit))
5434                         end++;
5435  
5436 -               if(end != nsectors)
5437 -                       printk("end != nsectors\n");
5438                 off = req->offset + req->offsets[bit] + 
5439                         start * req->sectorsize;
5440                 len = (end - start) * req->sectorsize;
5441                 buf = &req->buffer[start * req->sectorsize];
5442  
5443 -               if(os_seek_file(req->fds[bit], off) != 0){
5444 -                       printk("do_io - lseek failed : errno = %d\n", errno);
5445 +               err = os_seek_file(req->fds[bit], off);
5446 +               if(err < 0){
5447 +                       printk("do_io - lseek failed : err = %d\n", -err);
5448                         req->error = 1;
5449                         return;
5450                 }
5451 @@ -490,11 +272,10 @@
5452                         do {
5453                                 buf = &buf[n];
5454                                 len -= n;
5455 -                               n = read(req->fds[bit], buf, len);
5456 +                               n = os_read_file(req->fds[bit], buf, len);
5457                                 if (n < 0) {
5458 -                                       printk("do_io - read returned %d : "
5459 -                                              "errno = %d fd = %d\n", n,
5460 -                                              errno, req->fds[bit]);
5461 +                                       printk("do_io - read failed, err = %d "
5462 +                                              "fd = %d\n", -n, req->fds[bit]);
5463                                         req->error = 1;
5464                                         return;
5465                                 }
5466 @@ -502,11 +283,10 @@
5467                         if (n < len) memset(&buf[n], 0, len - n);
5468                 }
5469                 else {
5470 -                       n = write(req->fds[bit], buf, len);
5471 +                       n = os_write_file(req->fds[bit], buf, len);
5472                         if(n != len){
5473 -                               printk("do_io - write returned %d : "
5474 -                                      "errno = %d fd = %d\n", n, 
5475 -                                      errno, req->fds[bit]);
5476 +                               printk("do_io - write failed err = %d "
5477 +                                      "fd = %d\n", -n, req->fds[bit]);
5478                                 req->error = 1;
5479                                 return;
5480                         }
5481 @@ -515,24 +295,7 @@
5482                 start = end;
5483         } while(start < nsectors);
5484  
5485 -       if(req->cow_offset != -1){
5486 -               if(os_seek_file(req->fds[1], req->cow_offset) != 0){
5487 -                       printk("do_io - bitmap lseek failed : errno = %d\n",
5488 -                              errno);
5489 -                       req->error = 1;
5490 -                       return;
5491 -               }
5492 -               n = write(req->fds[1], &req->bitmap_words, 
5493 -                         sizeof(req->bitmap_words));
5494 -               if(n != sizeof(req->bitmap_words)){
5495 -                       printk("do_io - bitmap update returned %d : "
5496 -                              "errno = %d fd = %d\n", n, errno, req->fds[1]);
5497 -                       req->error = 1;
5498 -                       return;
5499 -               }
5500 -       }
5501 -       req->error = 0;
5502 -       return;
5503 +       req->error = update_bitmap(req);
5504  }
5505  
5506  /* Changed in start_io_thread, which is serialized by being called only
5507 @@ -550,19 +313,23 @@
5508  
5509         signal(SIGWINCH, SIG_IGN);
5510         while(1){
5511 -               n = read(kernel_fd, &req, sizeof(req));
5512 -               if(n < 0) printk("io_thread - read returned %d, errno = %d\n",
5513 -                                n, errno);
5514 -               else if(n < sizeof(req)){
5515 -                       printk("io_thread - short read : length = %d\n", n);
5516 +               n = os_read_file(kernel_fd, &req, sizeof(req));
5517 +               if(n != sizeof(req)){
5518 +                       if(n < 0)
5519 +                               printk("io_thread - read failed, fd = %d, "
5520 +                                      "err = %d\n", kernel_fd, -n);
5521 +                       else {
5522 +                               printk("io_thread - short read, fd = %d, "
5523 +                                      "length = %d\n", kernel_fd, n);
5524 +                       }
5525                         continue;
5526                 }
5527                 io_count++;
5528                 do_io(&req);
5529 -               n = write(kernel_fd, &req, sizeof(req));
5530 +               n = os_write_file(kernel_fd, &req, sizeof(req));
5531                 if(n != sizeof(req))
5532 -                       printk("io_thread - write failed, errno = %d\n",
5533 -                              errno);
5534 +                       printk("io_thread - write failed, fd = %d, err = %d\n",
5535 +                              kernel_fd, -n);
5536         }
5537  }
5538  
5539 @@ -571,10 +338,11 @@
5540         int pid, fds[2], err;
5541  
5542         err = os_pipe(fds, 1, 1);
5543 -       if(err){
5544 -               printk("start_io_thread - os_pipe failed, errno = %d\n", -err);
5545 -               return(-1);
5546 +       if(err < 0){
5547 +               printk("start_io_thread - os_pipe failed, err = %d\n", -err);
5548 +               goto out;
5549         }
5550 +
5551         kernel_fd = fds[0];
5552         *fd_out = fds[1];
5553  
5554 @@ -582,32 +350,19 @@
5555                     NULL);
5556         if(pid < 0){
5557                 printk("start_io_thread - clone failed : errno = %d\n", errno);
5558 -               return(-errno);
5559 -       }
5560 -       return(pid);
5561 -}
5562 -
5563 -#ifdef notdef
5564 -int start_io_thread(unsigned long sp, int *fd_out)
5565 -{
5566 -       int pid;
5567 -
5568 -       if((kernel_fd = get_pty()) < 0) return(-1);
5569 -       raw(kernel_fd, 0);
5570 -       if((*fd_out = open(ptsname(kernel_fd), O_RDWR)) < 0){
5571 -               printk("Couldn't open tty for IO\n");
5572 -               return(-1);
5573 +               goto out_close;
5574         }
5575  
5576 -       pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
5577 -                   NULL);
5578 -       if(pid < 0){
5579 -               printk("start_io_thread - clone failed : errno = %d\n", errno);
5580 -               return(-errno);
5581 -       }
5582         return(pid);
5583 +
5584 + out_close:
5585 +       os_close_file(fds[0]);
5586 +       os_close_file(fds[1]);
5587 +       kernel_fd = -1;
5588 +       *fd_out = -1;
5589 +out:
5590 +       return(err);
5591  }
5592 -#endif
5593  
5594  /*
5595   * Overrides for Emacs so that we follow Linus's tabbing style.
5596 diff -Naur a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
5597 --- a/arch/um/drivers/xterm.c   2004-01-08 22:13:50.000000000 -0500
5598 +++ b/arch/um/drivers/xterm.c   2004-01-08 22:18:48.000000000 -0500
5599 @@ -8,7 +8,6 @@
5600  #include <unistd.h>
5601  #include <string.h>
5602  #include <errno.h>
5603 -#include <fcntl.h>
5604  #include <termios.h>
5605  #include <signal.h>
5606  #include <sched.h>
5607 @@ -36,7 +35,8 @@
5608  {
5609         struct xterm_chan *data;
5610  
5611 -       if((data = malloc(sizeof(*data))) == NULL) return(NULL);
5612 +       data = malloc(sizeof(*data));
5613 +       if(data == NULL) return(NULL);
5614         *data = ((struct xterm_chan) { .pid             = -1, 
5615                                        .helper_pid      = -1,
5616                                        .device          = device, 
5617 @@ -93,7 +93,7 @@
5618                          "/usr/lib/uml/port-helper", "-uml-socket",
5619                          file, NULL };
5620  
5621 -       if(access(argv[4], X_OK))
5622 +       if(os_access(argv[4], OS_ACC_X_OK) < 0)
5623                 argv[4] = "port-helper";
5624  
5625         fd = mkstemp(file);
5626 @@ -106,13 +106,13 @@
5627                 printk("xterm_open : unlink failed, errno = %d\n", errno);
5628                 return(-errno);
5629         }
5630 -       close(fd);
5631 +       os_close_file(fd);
5632  
5633 -       fd = create_unix_socket(file, sizeof(file));
5634 +       fd = os_create_unix_socket(file, sizeof(file), 1);
5635         if(fd < 0){
5636                 printk("xterm_open : create_unix_socket failed, errno = %d\n", 
5637                        -fd);
5638 -               return(-fd);
5639 +               return(fd);
5640         }
5641  
5642         sprintf(title, data->title, data->device);
5643 @@ -128,15 +128,16 @@
5644         if(data->direct_rcv)
5645                 new = os_rcv_fd(fd, &data->helper_pid);
5646         else {
5647 -               if((err = os_set_fd_block(fd, 0)) != 0){
5648 +               err = os_set_fd_block(fd, 0);
5649 +               if(err < 0){
5650                         printk("xterm_open : failed to set descriptor "
5651 -                              "non-blocking, errno = %d\n", err);
5652 +                              "non-blocking, err = %d\n", -err);
5653                         return(err);
5654                 }
5655                 new = xterm_fd(fd, &data->helper_pid);
5656         }
5657         if(new < 0){
5658 -               printk("xterm_open : os_rcv_fd failed, errno = %d\n", -new);
5659 +               printk("xterm_open : os_rcv_fd failed, err = %d\n", -new);
5660                 goto out;
5661         }
5662  
5663 @@ -160,7 +161,7 @@
5664         if(data->helper_pid != -1) 
5665                 os_kill_process(data->helper_pid, 0);
5666         data->helper_pid = -1;
5667 -       close(fd);
5668 +       os_close_file(fd);
5669  }
5670  
5671  void xterm_free(void *d)
5672 diff -Naur a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
5673 --- a/arch/um/drivers/xterm_kern.c      2004-01-08 22:26:26.000000000 -0500
5674 +++ b/arch/um/drivers/xterm_kern.c      2004-01-08 22:33:48.000000000 -0500
5675 @@ -5,9 +5,12 @@
5676  
5677  #include "linux/errno.h"
5678  #include "linux/slab.h"
5679 +#include "linux/signal.h"
5680 +#include "linux/interrupt.h"
5681  #include "asm/semaphore.h"
5682  #include "asm/irq.h"
5683  #include "irq_user.h"
5684 +#include "irq_kern.h"
5685  #include "kern_util.h"
5686  #include "os.h"
5687  #include "xterm.h"
5688 @@ -19,17 +22,18 @@
5689         int new_fd;
5690  };
5691  
5692 -static void xterm_interrupt(int irq, void *data, struct pt_regs *regs)
5693 +static irqreturn_t xterm_interrupt(int irq, void *data, struct pt_regs *regs)
5694  {
5695         struct xterm_wait *xterm = data;
5696         int fd;
5697  
5698         fd = os_rcv_fd(xterm->fd, &xterm->pid);
5699         if(fd == -EAGAIN)
5700 -               return;
5701 +               return(IRQ_NONE);
5702  
5703         xterm->new_fd = fd;
5704         up(&xterm->sem);
5705 +       return(IRQ_HANDLED);
5706  }
5707  
5708  int xterm_fd(int socket, int *pid_out)
5709 @@ -54,7 +58,8 @@
5710         if(err){
5711                 printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
5712                        "err = %d\n",  err);
5713 -               return(err);
5714 +               ret = err;
5715 +               goto out;
5716         }
5717         down(&data->sem);
5718  
5719 @@ -62,6 +67,7 @@
5720  
5721         ret = data->new_fd;
5722         *pid_out = data->pid;
5723 + out:
5724         kfree(data);
5725  
5726         return(ret);
5727 diff -Naur a/arch/um/dyn.lds.S b/arch/um/dyn.lds.S
5728 --- a/arch/um/dyn.lds.S 2004-01-08 22:21:42.000000000 -0500
5729 +++ b/arch/um/dyn.lds.S 2004-01-08 22:28:31.000000000 -0500
5730 @@ -10,12 +10,15 @@
5731  {
5732    . = START + SIZEOF_HEADERS;
5733    .interp         : { *(.interp) }
5734 -  . = ALIGN(4096);
5735    __binary_start = .;
5736    . = ALIGN(4096);             /* Init code and data */
5737    _stext = .;
5738    __init_begin = .;
5739 -  .text.init : { *(.text.init) }
5740 +  .init.text : { 
5741 +       _sinittext = .;
5742 +       *(.init.text)
5743 +       _einittext = .;
5744 +  }
5745  
5746    . = ALIGN(4096);
5747  
5748 @@ -67,7 +70,7 @@
5749  
5750    #include "asm/common.lds.S"
5751  
5752 -  .data.init : { *(.data.init) }
5753 +  init.data : { *(.init.data) }
5754  
5755    /* Ensure the __preinit_array_start label is properly aligned.  We
5756       could instead move the label definition inside the section, but
5757 diff -Naur a/arch/um/include/2_5compat.h b/arch/um/include/2_5compat.h
5758 --- a/arch/um/include/2_5compat.h       2004-01-08 22:20:37.000000000 -0500
5759 +++ b/arch/um/include/2_5compat.h       2004-01-08 22:27:07.000000000 -0500
5760 @@ -6,20 +6,6 @@
5761  #ifndef __2_5_COMPAT_H__
5762  #define __2_5_COMPAT_H__
5763  
5764 -#include "linux/version.h"
5765 -
5766 -#define INIT_CONSOLE(dev_name, write_proc, device_proc, setup_proc, f) { \
5767 -       name :          dev_name, \
5768 -       write :         write_proc, \
5769 -       read :          NULL, \
5770 -       device :        device_proc, \
5771 -       setup :         setup_proc, \
5772 -       flags :         f, \
5773 -       index :         -1, \
5774 -       cflag :         0, \
5775 -       next :          NULL \
5776 -}
5777 -
5778  #define INIT_HARDSECT(arr, maj, sizes)
5779  
5780  #define SET_PRI(task) do ; while(0)
5781 diff -Naur a/arch/um/include/irq_kern.h b/arch/um/include/irq_kern.h
5782 --- a/arch/um/include/irq_kern.h        1969-12-31 19:00:00.000000000 -0500
5783 +++ b/arch/um/include/irq_kern.h        2004-01-08 22:27:54.000000000 -0500
5784 @@ -0,0 +1,28 @@
5785 +/* 
5786 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
5787 + * Licensed under the GPL
5788 + */
5789 +
5790 +#ifndef __IRQ_KERN_H__
5791 +#define __IRQ_KERN_H__
5792 +
5793 +#include "linux/interrupt.h"
5794 +
5795 +extern int um_request_irq(unsigned int irq, int fd, int type,
5796 +                         irqreturn_t (*handler)(int, void *, 
5797 +                                                struct pt_regs *),
5798 +                         unsigned long irqflags,  const char * devname,
5799 +                         void *dev_id);
5800 +
5801 +#endif
5802 +
5803 +/*
5804 + * Overrides for Emacs so that we follow Linus's tabbing style.
5805 + * Emacs will notice this stuff at the end of the file and automatically
5806 + * adjust the settings for this buffer only.  This must remain at the end
5807 + * of the file.
5808 + * ---------------------------------------------------------------------------
5809 + * Local variables:
5810 + * c-file-style: "linux"
5811 + * End:
5812 + */
5813 diff -Naur a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
5814 --- a/arch/um/include/kern_util.h       2004-01-08 22:18:49.000000000 -0500
5815 +++ b/arch/um/include/kern_util.h       2004-01-08 22:24:38.000000000 -0500
5816 @@ -63,10 +63,9 @@
5817  extern void *syscall_sp(void *t);
5818  extern void syscall_trace(void);
5819  extern int hz(void);
5820 -extern void idle_timer(void);
5821 +extern void uml_idle_timer(void);
5822  extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
5823  extern int external_pid(void *t);
5824 -extern int pid_to_processor_id(int pid);
5825  extern void boot_timer_handler(int sig);
5826  extern void interrupt_end(void);
5827  extern void initial_thread_cb(void (*proc)(void *), void *arg);
5828 @@ -90,9 +89,7 @@
5829  extern char *uml_strdup(char *string);
5830  extern void unprotect_kernel_mem(void);
5831  extern void protect_kernel_mem(void);
5832 -extern void set_kmem_end(unsigned long);
5833  extern void uml_cleanup(void);
5834 -extern int pid_to_processor_id(int pid);
5835  extern void set_current(void *t);
5836  extern void lock_signalled_task(void *t);
5837  extern void IPI_handler(int cpu);
5838 @@ -101,7 +98,9 @@
5839  extern int clear_user_proc(void *buf, int size);
5840  extern int copy_to_user_proc(void *to, void *from, int size);
5841  extern int copy_from_user_proc(void *to, void *from, int size);
5842 +extern int strlen_user_proc(char *str);
5843  extern void bus_handler(int sig, union uml_pt_regs *regs);
5844 +extern void winch(int sig, union uml_pt_regs *regs);
5845  extern long execute_syscall(void *r);
5846  extern int smp_sigio_handler(void);
5847  extern void *get_current(void);
5848 @@ -112,6 +111,8 @@
5849  extern void free_irq(unsigned int, void *);
5850  extern int um_in_interrupt(void);
5851  extern int cpu(void);
5852 +extern unsigned long long time_stamp(void);
5853 +
5854  #endif
5855  
5856  /*
5857 diff -Naur a/arch/um/include/line.h b/arch/um/include/line.h
5858 --- a/arch/um/include/line.h    2004-01-08 22:27:12.000000000 -0500
5859 +++ b/arch/um/include/line.h    2004-01-08 22:34:07.000000000 -0500
5860 @@ -9,12 +9,14 @@
5861  #include "linux/list.h"
5862  #include "linux/workqueue.h"
5863  #include "linux/tty.h"
5864 +#include "linux/interrupt.h"
5865  #include "asm/semaphore.h"
5866  #include "chan_user.h"
5867  #include "mconsole_kern.h"
5868  
5869  struct line_driver {
5870         char *name;
5871 +       char *device_name;
5872         char *devfs_name;
5873         short major;
5874         short minor_start;
5875 @@ -67,8 +69,6 @@
5876  
5877  #define LINES_INIT(n) {  num :         n }
5878  
5879 -extern void line_interrupt(int irq, void *data, struct pt_regs *unused);
5880 -extern void line_write_interrupt(int irq, void *data, struct pt_regs *unused);
5881  extern void line_close(struct line *lines, struct tty_struct *tty);
5882  extern int line_open(struct line *lines, struct tty_struct *tty, 
5883                      struct chan_opts *opts);
5884 diff -Naur a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
5885 --- a/arch/um/include/mconsole.h        2004-01-08 22:19:58.000000000 -0500
5886 +++ b/arch/um/include/mconsole.h        2004-01-08 22:25:57.000000000 -0500
5887 @@ -41,11 +41,13 @@
5888  
5889  struct mc_request;
5890  
5891 +enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC };
5892 +
5893  struct mconsole_command
5894  {
5895         char *command;
5896         void (*handler)(struct mc_request *req);
5897 -       int as_interrupt;
5898 +       enum mc_context context;
5899  };
5900  
5901  struct mc_request
5902 @@ -77,6 +79,8 @@
5903  extern void mconsole_cad(struct mc_request *req);
5904  extern void mconsole_stop(struct mc_request *req);
5905  extern void mconsole_go(struct mc_request *req);
5906 +extern void mconsole_log(struct mc_request *req);
5907 +extern void mconsole_proc(struct mc_request *req);
5908  
5909  extern int mconsole_get_request(int fd, struct mc_request *req);
5910  extern int mconsole_notify(char *sock_name, int type, const void *data, 
5911 diff -Naur a/arch/um/include/mem.h b/arch/um/include/mem.h
5912 --- a/arch/um/include/mem.h     2004-01-08 22:32:37.000000000 -0500
5913 +++ b/arch/um/include/mem.h     2004-01-08 22:36:37.000000000 -0500
5914 @@ -1,19 +1,17 @@
5915  /* 
5916 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
5917 + * Copyright (C) 2002, 2003 Jeff Dike (jdike@addtoit.com)
5918   * Licensed under the GPL
5919   */
5920  
5921  #ifndef __MEM_H__
5922  #define __MEM_H__
5923  
5924 -struct vm_reserved {
5925 -       struct list_head list;
5926 -       unsigned long start;
5927 -       unsigned long end;
5928 -};
5929 +#include "linux/types.h"
5930  
5931 -extern void set_usable_vm(unsigned long start, unsigned long end);
5932 -extern void set_kmem_end(unsigned long new);
5933 +extern int phys_mapping(unsigned long phys, __u64 *offset_out);
5934 +extern int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w);
5935 +extern int is_remapped(void *virt);
5936 +extern int physmem_remove_mapping(void *virt);
5937  
5938  #endif
5939  
5940 diff -Naur a/arch/um/include/mem_kern.h b/arch/um/include/mem_kern.h
5941 --- a/arch/um/include/mem_kern.h        1969-12-31 19:00:00.000000000 -0500
5942 +++ b/arch/um/include/mem_kern.h        2004-01-08 22:29:31.000000000 -0500
5943 @@ -0,0 +1,30 @@
5944 +/* 
5945 + * Copyright (C) 2003 Jeff Dike (jdike@addtoit.com)
5946 + * Licensed under the GPL
5947 + */
5948 +
5949 +#ifndef __MEM_KERN_H__
5950 +#define __MEM_KERN_H__
5951 +
5952 +#include "linux/list.h"
5953 +#include "linux/types.h"
5954 +
5955 +struct remapper {
5956 +       struct list_head list;
5957 +       int (*proc)(int, unsigned long, int, __u64);
5958 +};
5959 +
5960 +extern void register_remapper(struct remapper *info);
5961 +
5962 +#endif
5963 +
5964 +/*
5965 + * Overrides for Emacs so that we follow Linus's tabbing style.
5966 + * Emacs will notice this stuff at the end of the file and automatically
5967 + * adjust the settings for this buffer only.  This must remain at the end
5968 + * of the file.
5969 + * ---------------------------------------------------------------------------
5970 + * Local variables:
5971 + * c-file-style: "linux"
5972 + * End:
5973 + */
5974 diff -Naur a/arch/um/include/mem_user.h b/arch/um/include/mem_user.h
5975 --- a/arch/um/include/mem_user.h        2004-01-08 22:25:06.000000000 -0500
5976 +++ b/arch/um/include/mem_user.h        2004-01-08 22:32:22.000000000 -0500
5977 @@ -32,43 +32,38 @@
5978  #ifndef _MEM_USER_H
5979  #define _MEM_USER_H
5980  
5981 -struct mem_region {
5982 +struct iomem_region {
5983 +       struct iomem_region *next;
5984         char *driver;
5985 -       unsigned long start_pfn;
5986 -       unsigned long start;
5987 -       unsigned long len;
5988 -       void *mem_map;
5989         int fd;
5990 +       int size;
5991 +       unsigned long phys;
5992 +       unsigned long virt;
5993  };
5994  
5995 -extern struct mem_region *regions[];
5996 -extern struct mem_region physmem_region;
5997 +extern struct iomem_region *iomem_regions;
5998 +extern int iomem_size;
5999  
6000  #define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
6001  
6002  extern unsigned long host_task_size;
6003  extern unsigned long task_size;
6004  
6005 +extern void check_devanon(void);
6006  extern int init_mem_user(void);
6007  extern int create_mem_file(unsigned long len);
6008 -extern void setup_range(int fd, char *driver, unsigned long start,
6009 -                       unsigned long pfn, unsigned long total, int need_vm, 
6010 -                       struct mem_region *region, void *reserved);
6011  extern void setup_memory(void *entry);
6012  extern unsigned long find_iomem(char *driver, unsigned long *len_out);
6013 -extern int init_maps(struct mem_region *region);
6014 -extern int nregions(void);
6015 -extern int reserve_vm(unsigned long start, unsigned long end, void *e);
6016 +extern int init_maps(unsigned long physmem, unsigned long iomem, 
6017 +                    unsigned long highmem);
6018  extern unsigned long get_vm(unsigned long len);
6019  extern void setup_physmem(unsigned long start, unsigned long usable,
6020 -                         unsigned long len);
6021 -extern int setup_region(struct mem_region *region, void *entry);
6022 +                         unsigned long len, unsigned long highmem);
6023  extern void add_iomem(char *name, int fd, unsigned long size);
6024 -extern struct mem_region *phys_region(unsigned long phys);
6025  extern unsigned long phys_offset(unsigned long phys);
6026  extern void unmap_physmem(void);
6027 -extern int map_memory(unsigned long virt, unsigned long phys, 
6028 -                     unsigned long len, int r, int w, int x);
6029 +extern void map_memory(unsigned long virt, unsigned long phys, 
6030 +                      unsigned long len, int r, int w, int x);
6031  extern int protect_memory(unsigned long addr, unsigned long len, 
6032                           int r, int w, int x, int must_succeed);
6033  extern unsigned long get_kmem_end(void);
6034 diff -Naur a/arch/um/include/os.h b/arch/um/include/os.h
6035 --- a/arch/um/include/os.h      2004-01-08 22:16:19.000000000 -0500
6036 +++ b/arch/um/include/os.h      2004-01-08 22:22:02.000000000 -0500
6037 @@ -17,6 +17,32 @@
6038  #define OS_TYPE_FIFO 6
6039  #define OS_TYPE_SOCK 7
6040  
6041 +/* os_access() flags */
6042 +#define OS_ACC_F_OK    0       /* Test for existence.  */
6043 +#define OS_ACC_X_OK    1       /* Test for execute permission.  */
6044 +#define OS_ACC_W_OK    2       /* Test for write permission.  */
6045 +#define OS_ACC_R_OK    4       /* Test for read permission.  */
6046 +#define OS_ACC_RW_OK   (OS_ACC_W_OK | OS_ACC_R_OK) /* Test for RW permission */
6047 +
6048 +/*
6049 + * types taken from stat_file() in hostfs_user.c
6050 + * (if they are wrong here, they are wrong there...).
6051 +`*/
6052 +struct uml_stat {
6053 +       int                ust_dev;        /* device */
6054 +       unsigned long long ust_ino;        /* inode */
6055 +       int                ust_mode;       /* protection */
6056 +       int                ust_nlink;      /* number of hard links */
6057 +       int                ust_uid;        /* user ID of owner */
6058 +       int                ust_gid;        /* group ID of owner */
6059 +       unsigned long long ust_size;       /* total size, in bytes */
6060 +       int                ust_blksize;    /* blocksize for filesystem I/O */
6061 +       unsigned long long ust_blocks;     /* number of blocks allocated */
6062 +       unsigned long      ust_atime;      /* time of last access */
6063 +       unsigned long      ust_mtime;      /* time of last modification */
6064 +       unsigned long      ust_ctime;      /* time of last change */
6065 +};
6066 +
6067  struct openflags {
6068         unsigned int r : 1;
6069         unsigned int w : 1;
6070 @@ -91,22 +117,40 @@
6071         return(flags); 
6072  }
6073    
6074 +extern int os_stat_file(const char *file_name, struct uml_stat *buf);
6075 +extern int os_stat_fd(const int fd, struct uml_stat *buf);
6076 +extern int os_access(const char *file, int mode);
6077 +extern void os_print_error(int error, const char* str);
6078 +extern int os_get_exec_close(int fd, int *close_on_exec);
6079 +extern int os_set_exec_close(int fd, int close_on_exec);
6080 +extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg);
6081 +extern int os_window_size(int fd, int *rows, int *cols);
6082 +extern int os_new_tty_pgrp(int fd, int pid);
6083 +extern int os_get_ifname(int fd, char *namebuf);
6084 +extern int os_set_slip(int fd);
6085 +extern int os_set_owner(int fd, int pid);
6086 +extern int os_sigio_async(int master, int slave);
6087 +extern int os_mode_fd(int fd, int mode);
6088 +
6089  extern int os_seek_file(int fd, __u64 offset);
6090  extern int os_open_file(char *file, struct openflags flags, int mode);
6091  extern int os_read_file(int fd, void *buf, int len);
6092 -extern int os_write_file(int fd, void *buf, int count);
6093 +extern int os_write_file(int fd, const void *buf, int count);
6094  extern int os_file_size(char *file, long long *size_out);
6095 +extern int os_file_modtime(char *file, unsigned long *modtime);
6096  extern int os_pipe(int *fd, int stream, int close_on_exec);
6097  extern int os_set_fd_async(int fd, int owner);
6098  extern int os_set_fd_block(int fd, int blocking);
6099  extern int os_accept_connection(int fd);
6100 +extern int os_create_unix_socket(char *file, int len, int close_on_exec);
6101  extern int os_shutdown_socket(int fd, int r, int w);
6102  extern void os_close_file(int fd);
6103  extern int os_rcv_fd(int fd, int *helper_pid_out);
6104 -extern int create_unix_socket(char *file, int len);
6105 +extern int create_unix_socket(char *file, int len, int close_on_exec);
6106  extern int os_connect_socket(char *name);
6107  extern int os_file_type(char *file);
6108  extern int os_file_mode(char *file, struct openflags *mode_out);
6109 +extern int os_lock_file(int fd, int excl);
6110  
6111  extern unsigned long os_process_pc(int pid);
6112  extern int os_process_parent(int pid);
6113 @@ -115,11 +159,12 @@
6114  extern void os_usr1_process(int pid);
6115  extern int os_getpid(void);
6116  
6117 -extern int os_map_memory(void *virt, int fd, unsigned long off, 
6118 +extern int os_map_memory(void *virt, int fd, unsigned long long off, 
6119                          unsigned long len, int r, int w, int x);
6120  extern int os_protect_memory(void *addr, unsigned long len, 
6121                              int r, int w, int x);
6122  extern int os_unmap_memory(void *addr, int len);
6123 +extern void os_flush_stdout(void);
6124  
6125  #endif
6126  
6127 diff -Naur a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h
6128 --- a/arch/um/include/sysdep-i386/sigcontext.h  2004-01-08 22:26:00.000000000 -0500
6129 +++ b/arch/um/include/sysdep-i386/sigcontext.h  2004-01-08 22:33:43.000000000 -0500
6130 @@ -28,8 +28,8 @@
6131   */
6132  #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
6133  
6134 -/* These are General Protection and Page Fault */
6135 -#define SEGV_IS_FIXABLE(trap) ((trap == 13) || (trap == 14))
6136 +/* This is Page Fault */
6137 +#define SEGV_IS_FIXABLE(trap) (trap == 14)
6138  
6139  #define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
6140  
6141 diff -Naur a/arch/um/include/ubd_user.h b/arch/um/include/ubd_user.h
6142 --- a/arch/um/include/ubd_user.h        2004-01-08 22:22:40.000000000 -0500
6143 +++ b/arch/um/include/ubd_user.h        2004-01-08 22:29:35.000000000 -0500
6144 @@ -9,7 +9,7 @@
6145  
6146  #include "os.h"
6147  
6148 -enum ubd_req { UBD_READ, UBD_WRITE };
6149 +enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
6150  
6151  struct io_thread_req {
6152         enum ubd_req op;
6153 @@ -20,8 +20,10 @@
6154         char *buffer;
6155         int sectorsize;
6156         unsigned long sector_mask;
6157 -       unsigned long cow_offset;
6158 +       unsigned long long cow_offset;
6159         unsigned long bitmap_words[2];
6160 +       int map_fd;
6161 +       unsigned long long map_offset;
6162         int error;
6163  };
6164  
6165 @@ -31,7 +33,7 @@
6166                          int *create_cow_out);
6167  extern int create_cow_file(char *cow_file, char *backing_file, 
6168                            struct openflags flags, int sectorsize, 
6169 -                          int *bitmap_offset_out, 
6170 +                          int alignment, int *bitmap_offset_out, 
6171                            unsigned long *bitmap_len_out,
6172                            int *data_offset_out);
6173  extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
6174 @@ -39,7 +41,6 @@
6175  extern int write_ubd_fs(int fd, char *buffer, int len);
6176  extern int start_io_thread(unsigned long sp, int *fds_out);
6177  extern void do_io(struct io_thread_req *req);
6178 -extern int ubd_is_dir(char *file);
6179  
6180  static inline int ubd_test_bit(__u64 bit, unsigned char *data)
6181  {
6182 diff -Naur a/arch/um/include/um_uaccess.h b/arch/um/include/um_uaccess.h
6183 --- a/arch/um/include/um_uaccess.h      2004-01-08 22:25:51.000000000 -0500
6184 +++ b/arch/um/include/um_uaccess.h      2004-01-08 22:33:28.000000000 -0500
6185 @@ -38,22 +38,73 @@
6186                                 from, n));
6187  }
6188  
6189 +/*
6190 + * strncpy_from_user: - Copy a NUL terminated string from userspace.
6191 + * @dst:   Destination address, in kernel space.  This buffer must be at
6192 + *         least @count bytes long.
6193 + * @src:   Source address, in user space.
6194 + * @count: Maximum number of bytes to copy, including the trailing NUL.
6195 + * 
6196 + * Copies a NUL-terminated string from userspace to kernel space.
6197 + *
6198 + * On success, returns the length of the string (not including the trailing
6199 + * NUL).
6200 + *
6201 + * If access to userspace fails, returns -EFAULT (some data may have been
6202 + * copied).
6203 + *
6204 + * If @count is smaller than the length of the string, copies @count bytes
6205 + * and returns @count.
6206 + */
6207 +
6208  static inline int strncpy_from_user(char *dst, const char *src, int count)
6209  {
6210         return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas,
6211                                 dst, src, count));
6212  }
6213  
6214 +/*
6215 + * __clear_user: - Zero a block of memory in user space, with less checking.
6216 + * @to:   Destination address, in user space.
6217 + * @n:    Number of bytes to zero.
6218 + *
6219 + * Zero a block of memory in user space.  Caller must check
6220 + * the specified block with access_ok() before calling this function.
6221 + *
6222 + * Returns number of bytes that could not be cleared.
6223 + * On success, this will be zero.
6224 + */
6225  static inline int __clear_user(void *mem, int len)
6226  {
6227         return(CHOOSE_MODE_PROC(__clear_user_tt, __clear_user_skas, mem, len));
6228  }
6229  
6230 +/*
6231 + * clear_user: - Zero a block of memory in user space.
6232 + * @to:   Destination address, in user space.
6233 + * @n:    Number of bytes to zero.
6234 + *
6235 + * Zero a block of memory in user space.
6236 + *
6237 + * Returns number of bytes that could not be cleared.
6238 + * On success, this will be zero.
6239 + */
6240  static inline int clear_user(void *mem, int len)
6241  {
6242         return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len));
6243  }
6244  
6245 +/*
6246 + * strlen_user: - Get the size of a string in user space.
6247 + * @str: The string to measure.
6248 + * @n:   The maximum valid length
6249 + *
6250 + * Get the size of a NUL-terminated string in user space.
6251 + *
6252 + * Returns the size of the string INCLUDING the terminating NUL.
6253 + * On exception, returns 0.
6254 + * If the string is too long, returns a value greater than @n.
6255 + */
6256  static inline int strnlen_user(const void *str, int len)
6257  {
6258         return(CHOOSE_MODE_PROC(strnlen_user_tt, strnlen_user_skas, str, len));
6259 diff -Naur a/arch/um/include/user.h b/arch/um/include/user.h
6260 --- a/arch/um/include/user.h    2004-01-08 22:13:48.000000000 -0500
6261 +++ b/arch/um/include/user.h    2004-01-08 22:18:35.000000000 -0500
6262 @@ -14,6 +14,7 @@
6263  extern void kfree(void *ptr);
6264  extern int in_aton(char *str);
6265  extern int open_gdb_chan(void);
6266 +extern int strlcpy(char *, const char *, int);
6267  
6268  #endif
6269  
6270 diff -Naur a/arch/um/include/user_util.h b/arch/um/include/user_util.h
6271 --- a/arch/um/include/user_util.h       2004-01-08 22:14:54.000000000 -0500
6272 +++ b/arch/um/include/user_util.h       2004-01-08 22:20:21.000000000 -0500
6273 @@ -14,8 +14,6 @@
6274  extern int unlockpt(int __fd);
6275  extern char *ptsname(int __fd);
6276  
6277 -enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
6278 -
6279  struct cpu_task {
6280         int pid;
6281         void *task;
6282 @@ -59,7 +57,6 @@
6283  extern void *add_signal_handler(int sig, void (*handler)(int));
6284  extern int start_fork_tramp(void *arg, unsigned long temp_stack, 
6285                             int clone_flags, int (*tramp)(void *));
6286 -extern int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags);
6287  extern int linux_main(int argc, char **argv);
6288  extern void set_cmdline(char *cmd);
6289  extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
6290 @@ -86,11 +83,13 @@
6291  extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
6292  extern void write_sigio_workaround(void);
6293  extern void arch_check_bugs(void);
6294 +extern int cpu_feature(char *what, char *buf, int len);
6295  extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
6296  extern int arch_fixup(unsigned long address, void *sc_ptr);
6297  extern void forward_pending_sigio(int target);
6298  extern int can_do_skas(void);
6299
6300 +extern void arch_init_thread(void);
6301 +
6302  #endif
6303  
6304  /*
6305 diff -Naur a/arch/um/Kconfig b/arch/um/Kconfig
6306 --- a/arch/um/Kconfig   2004-01-08 22:21:13.000000000 -0500
6307 +++ b/arch/um/Kconfig   2004-01-08 22:27:33.000000000 -0500
6308 @@ -61,6 +61,20 @@
6309  
6310  config NET
6311         bool "Networking support"
6312 +       help
6313 +       Unless you really know what you are doing, you should say Y here.
6314 +       The reason is that some programs need kernel networking support even
6315 +       when running on a stand-alone machine that isn't connected to any
6316 +       other computer. If you are upgrading from an older kernel, you
6317 +       should consider updating your networking tools too because changes
6318 +       in the kernel and the tools often go hand in hand. The tools are
6319 +       contained in the package net-tools, the location and version number
6320 +       of which are given in Documentation/Changes.
6321 +
6322 +       For a general introduction to Linux networking, it is highly
6323 +       recommended to read the NET-HOWTO, available from
6324 +       <http://www.tldp.org/docs.html#howto>.
6325 +
6326  
6327  source "fs/Kconfig.binfmt"
6328  
6329 @@ -85,6 +99,19 @@
6330          If you'd like to be able to work with files stored on the host, 
6331          say Y or M here; otherwise say N.
6332  
6333 +config HPPFS
6334 +       tristate "HoneyPot ProcFS"
6335 +       help
6336 +       hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc 
6337 +       entries to be overridden, removed, or fabricated from the host.
6338 +       Its purpose is to allow a UML to appear to be a physical machine
6339 +       by removing or changing anything in /proc which gives away the
6340 +       identity of a UML.
6341 +
6342 +       See http://user-mode-linux.sf.net/hppfs.html for more information.
6343 +
6344 +       You only need this if you are setting up a UML honeypot.  Otherwise,
6345 +       it is safe to say 'N' here.
6346  
6347  config MCONSOLE
6348         bool "Management console"
6349 @@ -105,6 +132,16 @@
6350  config MAGIC_SYSRQ
6351         bool "Magic SysRq key"
6352         depends on MCONSOLE
6353 +       help
6354 +       If you say Y here, you will have some control over the system even
6355 +       if the system crashes for example during kernel debugging (e.g., you
6356 +       will be able to flush the buffer cache to disk, reboot the system
6357 +       immediately or dump some status information). This is accomplished
6358 +       by pressing various keys while holding SysRq (Alt+PrintScreen). It
6359 +       also works on a serial console (on PC hardware at least), if you
6360 +       send a BREAK and then within 5 seconds a command keypress. The
6361 +       keys are documented in Documentation/sysrq.txt. Don't say Y
6362 +       unless you really know what this hack does.
6363  
6364  config HOST_2G_2G
6365         bool "2G/2G host address space split"
6366 @@ -159,6 +196,9 @@
6367  config HIGHMEM
6368         bool "Highmem support"
6369  
6370 +config PROC_MM
6371 +       bool "/proc/mm support"
6372 +
6373  config KERNEL_STACK_ORDER
6374         int "Kernel stack size order"
6375         default 2
6376 @@ -167,6 +207,17 @@
6377         be 1 << order pages.  The default is OK unless you're running Valgrind
6378         on UML, in which case, set this to 3.
6379  
6380 +config UML_REAL_TIME_CLOCK
6381 +       bool "Real-time Clock"
6382 +       default y
6383 +       help
6384 +       This option makes UML time deltas match wall clock deltas.  This should
6385 +       normally be enabled.  The exception would be if you are debugging with
6386 +       UML and spend long times with UML stopped at a breakpoint.  In this
6387 +       case, when UML is restarted, it will call the timer enough times to make
6388 +       up for the time spent at the breakpoint.  This could result in a 
6389 +       noticable lag.  If this is a problem, then disable this option.
6390 +
6391  endmenu
6392  
6393  source "init/Kconfig"
6394 @@ -239,6 +290,10 @@
6395  config PT_PROXY
6396         bool "Enable ptrace proxy"
6397         depends on XTERM_CHAN && DEBUG_INFO
6398 +       help
6399 +       This option enables a debugging interface which allows gdb to debug
6400 +       the kernel without needing to actually attach to kernel threads.
6401 +       If you want to do kernel debugging, say Y here; otherwise say N.
6402  
6403  config GPROF
6404         bool "Enable gprof support"
6405 diff -Naur a/arch/um/Kconfig_block b/arch/um/Kconfig_block
6406 --- a/arch/um/Kconfig_block     2004-01-08 22:25:21.000000000 -0500
6407 +++ b/arch/um/Kconfig_block     2004-01-08 22:32:41.000000000 -0500
6408 @@ -29,6 +29,20 @@
6409          wise choice too.  In all other cases (for example, if you're just
6410          playing around with User-Mode Linux) you can choose N.
6411  
6412 +# Turn this back on when the driver actually works
6413 +#
6414 +#config BLK_DEV_COW
6415 +#      tristate "COW block device"
6416 +#      help
6417 +#      This is a layered driver which sits above two other block devices.
6418 +#      One is read-only, and the other is a read-write layer which stores
6419 +#      all changes.  This provides the illusion that the read-only layer
6420 +#      can be mounted read-write and changed.
6421 +
6422 +config BLK_DEV_COW_COMMON
6423 +       bool
6424 +       default BLK_DEV_COW || BLK_DEV_UBD
6425 +
6426  config BLK_DEV_LOOP
6427         tristate "Loopback device support"
6428  
6429 diff -Naur a/arch/um/Kconfig_net b/arch/um/Kconfig_net
6430 --- a/arch/um/Kconfig_net       2004-01-08 22:23:21.000000000 -0500
6431 +++ b/arch/um/Kconfig_net       2004-01-08 22:30:48.000000000 -0500
6432 @@ -1,5 +1,5 @@
6433  
6434 -menu "Network Devices"
6435 +menu "UML Network Devices"
6436         depends on NET
6437  
6438  # UML virtual driver
6439 @@ -176,73 +176,5 @@
6440         
6441          Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
6442  
6443 -
6444 -# Below are hardware-independent drivers mirrored from
6445 -# drivers/net/Config.in. It would be nice if Linux
6446 -# had HW independent drivers separated from the other
6447 -# but it does not. Until then each non-ISA/PCI arch
6448 -# needs to provide it's own menu of network drivers
6449 -config DUMMY
6450 -       tristate "Dummy net driver support"
6451 -
6452 -config BONDING
6453 -       tristate "Bonding driver support"
6454 -
6455 -config EQUALIZER
6456 -       tristate "EQL (serial line load balancing) support"
6457 -
6458 -config TUN
6459 -       tristate "Universal TUN/TAP device driver support"
6460 -
6461 -config ETHERTAP
6462 -       tristate "Ethertap network tap (OBSOLETE)"
6463 -       depends on EXPERIMENTAL && NETLINK
6464 -
6465 -config PPP
6466 -       tristate "PPP (point-to-point protocol) support"
6467 -
6468 -config PPP_MULTILINK
6469 -       bool "PPP multilink support (EXPERIMENTAL)"
6470 -       depends on PPP && EXPERIMENTAL
6471 -
6472 -config PPP_FILTER
6473 -       bool "PPP filtering"
6474 -       depends on PPP && FILTER
6475 -
6476 -config PPP_ASYNC
6477 -       tristate "PPP support for async serial ports"
6478 -       depends on PPP
6479 -
6480 -config PPP_SYNC_TTY
6481 -       tristate "PPP support for sync tty ports"
6482 -       depends on PPP
6483 -
6484 -config PPP_DEFLATE
6485 -       tristate "PPP Deflate compression"
6486 -       depends on PPP
6487 -
6488 -config PPP_BSDCOMP
6489 -       tristate "PPP BSD-Compress compression"
6490 -       depends on PPP
6491 -
6492 -config PPPOE
6493 -       tristate "PPP over Ethernet (EXPERIMENTAL)"
6494 -       depends on PPP && EXPERIMENTAL
6495 -
6496 -config SLIP
6497 -       tristate "SLIP (serial line) support"
6498 -
6499 -config SLIP_COMPRESSED
6500 -       bool "CSLIP compressed headers"
6501 -       depends on SLIP=y
6502 -
6503 -config SLIP_SMART
6504 -       bool "Keepalive and linefill"
6505 -       depends on SLIP=y
6506 -
6507 -config SLIP_MODE_SLIP6
6508 -       bool "Six bit SLIP encapsulation"
6509 -       depends on SLIP=y
6510 -
6511  endmenu
6512  
6513 diff -Naur a/arch/um/kernel/config.c.in b/arch/um/kernel/config.c.in
6514 --- a/arch/um/kernel/config.c.in        2004-01-08 22:26:26.000000000 -0500
6515 +++ b/arch/um/kernel/config.c.in        2004-01-08 22:33:49.000000000 -0500
6516 @@ -7,9 +7,7 @@
6517  #include <stdlib.h>
6518  #include "init.h"
6519  
6520 -static __initdata char *config = "
6521 -CONFIG
6522 -";
6523 +static __initdata char *config = "CONFIG";
6524  
6525  static int __init print_config(char *line, int *add)
6526  {
6527 diff -Naur a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec_kern.c
6528 --- a/arch/um/kernel/exec_kern.c        2004-01-08 22:17:18.000000000 -0500
6529 +++ b/arch/um/kernel/exec_kern.c        2004-01-08 22:23:06.000000000 -0500
6530 @@ -32,10 +32,15 @@
6531         CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
6532  }
6533  
6534 +extern void log_exec(char **argv, void *tty);
6535 +
6536  static int execve1(char *file, char **argv, char **env)
6537  {
6538          int error;
6539  
6540 +#ifdef CONFIG_TTY_LOG
6541 +       log_exec(argv, current->tty);
6542 +#endif
6543          error = do_execve(file, argv, env, &current->thread.regs);
6544          if (error == 0){
6545                  current->ptrace &= ~PT_DTRACE;
6546 diff -Naur a/arch/um/kernel/frame.c b/arch/um/kernel/frame.c
6547 --- a/arch/um/kernel/frame.c    2004-01-08 22:18:38.000000000 -0500
6548 +++ b/arch/um/kernel/frame.c    2004-01-08 22:24:26.000000000 -0500
6549 @@ -279,7 +279,7 @@
6550         struct sc_frame_raw raw_sc;
6551         struct si_frame_raw raw_si;
6552         void *stack, *sigstack;
6553 -       unsigned long top, sig_top, base;
6554 +       unsigned long top, base;
6555  
6556         stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
6557                      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
6558 @@ -292,7 +292,6 @@
6559         }
6560  
6561         top = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
6562 -       sig_top = (unsigned long) sigstack + PAGE_SIZE;
6563  
6564         /* Get the sigcontext, no sigrestorer layout */
6565         raw_sc.restorer = 0;
6566 diff -Naur a/arch/um/kernel/frame_kern.c b/arch/um/kernel/frame_kern.c
6567 --- a/arch/um/kernel/frame_kern.c       2004-01-08 22:33:46.000000000 -0500
6568 +++ b/arch/um/kernel/frame_kern.c       2004-01-08 22:36:57.000000000 -0500
6569 @@ -6,7 +6,6 @@
6570  #include "asm/ptrace.h"
6571  #include "asm/uaccess.h"
6572  #include "asm/signal.h"
6573 -#include "asm/uaccess.h"
6574  #include "asm/ucontext.h"
6575  #include "frame_kern.h"
6576  #include "sigcontext.h"
6577 @@ -29,12 +28,15 @@
6578                             sizeof(restorer)));
6579  }
6580  
6581 +extern int userspace_pid[];
6582 +
6583  static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from, 
6584                            struct arch_frame_data *arch)
6585  {
6586         return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), 
6587                                               arch),
6588 -                          copy_sc_to_user_skas(to, fp, &from->regs,
6589 +                          copy_sc_to_user_skas(userspace_pid[0], to, fp, 
6590 +                                               &from->regs,
6591                                                 current->thread.cr2,
6592                                                 current->thread.err)));
6593  }
6594 diff -Naur a/arch/um/kernel/helper.c b/arch/um/kernel/helper.c
6595 --- a/arch/um/kernel/helper.c   2004-01-08 22:21:10.000000000 -0500
6596 +++ b/arch/um/kernel/helper.c   2004-01-08 22:27:27.000000000 -0500
6597 @@ -7,7 +7,6 @@
6598  #include <stdlib.h>
6599  #include <unistd.h>
6600  #include <errno.h>
6601 -#include <fcntl.h>
6602  #include <sched.h>
6603  #include <sys/signal.h>
6604  #include <sys/wait.h>
6605 @@ -33,6 +32,7 @@
6606  {
6607         struct helper_data *data = arg;
6608         char **argv = data->argv;
6609 +       int errval;
6610  
6611         if(helper_pause){
6612                 signal(SIGHUP, helper_hup);
6613 @@ -41,8 +41,9 @@
6614         if(data->pre_exec != NULL)
6615                 (*data->pre_exec)(data->pre_data);
6616         execvp(argv[0], argv);
6617 +       errval = errno;
6618         printk("execvp of '%s' failed - errno = %d\n", argv[0], errno);
6619 -       write(data->fd, &errno, sizeof(errno));
6620 +       os_write_file(data->fd, &errval, sizeof(errval));
6621         os_kill_process(os_getpid(), 0);
6622         return(0);
6623  }
6624 @@ -59,17 +60,20 @@
6625         if((stack_out != NULL) && (*stack_out != 0))
6626                 stack = *stack_out;
6627         else stack = alloc_stack(0, um_in_interrupt());
6628 -       if(stack == 0) return(-ENOMEM);
6629 +       if(stack == 0) 
6630 +               return(-ENOMEM);
6631  
6632         err = os_pipe(fds, 1, 0);
6633 -       if(err){
6634 -               printk("run_helper : pipe failed, errno = %d\n", -err);
6635 -               return(err);
6636 +       if(err < 0){
6637 +               printk("run_helper : pipe failed, err = %d\n", -err);
6638 +               goto out_free;
6639         }
6640 -       if(fcntl(fds[1], F_SETFD, 1) != 0){
6641 -               printk("run_helper : setting FD_CLOEXEC failed, errno = %d\n",
6642 -                      errno);
6643 -               return(-errno);
6644 +
6645 +       err = os_set_exec_close(fds[1], 1);
6646 +       if(err < 0){
6647 +               printk("run_helper : setting FD_CLOEXEC failed, err = %d\n",
6648 +                      -err);
6649 +               goto out_close;
6650         }
6651  
6652         sp = stack + page_size() - sizeof(void *);
6653 @@ -80,23 +84,34 @@
6654         pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
6655         if(pid < 0){
6656                 printk("run_helper : clone failed, errno = %d\n", errno);
6657 -               return(-errno);
6658 +               err = -errno;
6659 +               goto out_close;
6660         }
6661 -       close(fds[1]);
6662 -       n = read(fds[0], &err, sizeof(err));
6663 +
6664 +       os_close_file(fds[1]);
6665 +       n = os_read_file(fds[0], &err, sizeof(err));
6666         if(n < 0){
6667 -               printk("run_helper : read on pipe failed, errno = %d\n", 
6668 -                      errno);
6669 -               return(-errno);
6670 +               printk("run_helper : read on pipe failed, err = %d\n", -n);
6671 +               err = n;
6672 +               goto out_kill;
6673         }
6674         else if(n != 0){
6675                 waitpid(pid, NULL, 0);
6676 -               pid = -err;
6677 +               pid = -errno;
6678         }
6679  
6680         if(stack_out == NULL) free_stack(stack, 0);
6681          else *stack_out = stack;
6682         return(pid);
6683 +
6684 + out_kill:
6685 +       os_kill_process(pid, 1);
6686 + out_close:
6687 +       os_close_file(fds[0]);
6688 +       os_close_file(fds[1]);
6689 + out_free:
6690 +       free_stack(stack, 0);
6691 +       return(err);
6692  }
6693  
6694  int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, 
6695 @@ -117,9 +132,11 @@
6696         }
6697         if(stack_out == NULL){
6698                 pid = waitpid(pid, &status, 0);
6699 -               if(pid < 0)
6700 +               if(pid < 0){
6701                         printk("run_helper_thread - wait failed, errno = %d\n",
6702 -                              pid);
6703 +                              errno);
6704 +                       pid = -errno;
6705 +               }
6706                 if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
6707                         printk("run_helper_thread - thread returned status "
6708                                "0x%x\n", status);
6709 diff -Naur a/arch/um/kernel/initrd_user.c b/arch/um/kernel/initrd_user.c
6710 --- a/arch/um/kernel/initrd_user.c      2004-01-08 22:15:54.000000000 -0500
6711 +++ b/arch/um/kernel/initrd_user.c      2004-01-08 22:21:30.000000000 -0500
6712 @@ -6,7 +6,6 @@
6713  #include <unistd.h>
6714  #include <sys/types.h>
6715  #include <sys/stat.h>
6716 -#include <fcntl.h>
6717  #include <errno.h>
6718  
6719  #include "user_util.h"
6720 @@ -19,13 +18,15 @@
6721  {
6722         int fd, n;
6723  
6724 -       if((fd = os_open_file(filename, of_read(OPENFLAGS()), 0)) < 0){
6725 -               printk("Opening '%s' failed - errno = %d\n", filename, errno);
6726 +       fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
6727 +       if(fd < 0){
6728 +               printk("Opening '%s' failed - err = %d\n", filename, -fd);
6729                 return(-1);
6730         }
6731 -       if((n = read(fd, buf, size)) != size){
6732 -               printk("Read of %d bytes from '%s' returned %d, errno = %d\n",
6733 -                      size, filename, n, errno);
6734 +       n = os_read_file(fd, buf, size);
6735 +       if(n != size){
6736 +               printk("Read of %d bytes from '%s' failed, err = %d\n", size, 
6737 +                      filename, -n);
6738                 return(-1);
6739         }
6740         return(0);
6741 diff -Naur a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c
6742 --- a/arch/um/kernel/init_task.c        2004-01-08 22:32:58.000000000 -0500
6743 +++ b/arch/um/kernel/init_task.c        2004-01-08 22:36:48.000000000 -0500
6744 @@ -8,7 +8,6 @@
6745  #include "linux/module.h"
6746  #include "linux/sched.h"
6747  #include "linux/init_task.h"
6748 -#include "linux/version.h"
6749  #include "asm/uaccess.h"
6750  #include "asm/pgtable.h"
6751  #include "user_util.h"
6752 @@ -18,7 +17,7 @@
6753  struct mm_struct init_mm = INIT_MM(init_mm);
6754  static struct files_struct init_files = INIT_FILES;
6755  static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
6756 -
6757 +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
6758  EXPORT_SYMBOL(init_mm);
6759  
6760  /*
6761 @@ -43,26 +42,12 @@
6762  __attribute__((__section__(".data.init_task"))) = 
6763  { INIT_THREAD_INFO(init_task) };
6764  
6765 -struct task_struct *alloc_task_struct(void)
6766 -{
6767 -       return((struct task_struct *) 
6768 -              __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
6769 -}
6770 -
6771  void unprotect_stack(unsigned long stack)
6772  {
6773         protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE, 
6774                        1, 1, 0, 1);
6775  }
6776  
6777 -void free_task_struct(struct task_struct *task)
6778 -{
6779 -       /* free_pages decrements the page counter and only actually frees
6780 -        * the pages if they are now not accessed by anything.
6781 -        */
6782 -       free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
6783 -}
6784 -
6785  /*
6786   * Overrides for Emacs so that we follow Linus's tabbing style.
6787   * Emacs will notice this stuff at the end of the file and automatically
6788 diff -Naur a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
6789 --- a/arch/um/kernel/irq.c      2004-01-08 22:28:24.000000000 -0500
6790 +++ b/arch/um/kernel/irq.c      2004-01-08 22:34:33.000000000 -0500
6791 @@ -29,6 +29,7 @@
6792  #include "user_util.h"
6793  #include "kern_util.h"
6794  #include "irq_user.h"
6795 +#include "irq_kern.h"
6796  
6797  static void register_irq_proc (unsigned int irq);
6798  
6799 @@ -83,65 +84,52 @@
6800         end_none
6801  };
6802  
6803 -/* Not changed */
6804 -volatile unsigned long irq_err_count;
6805 -
6806  /*
6807   * Generic, controller-independent functions:
6808   */
6809  
6810 -int get_irq_list(char *buf)
6811 +int show_interrupts(struct seq_file *p, void *v)
6812  {
6813         int i, j;
6814 -       unsigned long flags;
6815         struct irqaction * action;
6816 -       char *p = buf;
6817 +       unsigned long flags;
6818  
6819 -       p += sprintf(p, "           ");
6820 -       for (j=0; j<num_online_cpus(); j++)
6821 -               p += sprintf(p, "CPU%d       ",j);
6822 -       *p++ = '\n';
6823 +       seq_printf(p, "           ");
6824 +       for (j=0; j<NR_CPUS; j++)
6825 +               if (cpu_online(j))
6826 +                       seq_printf(p, "CPU%d       ",j);
6827 +       seq_putc(p, '\n');
6828  
6829         for (i = 0 ; i < NR_IRQS ; i++) {
6830                 spin_lock_irqsave(&irq_desc[i].lock, flags);
6831                 action = irq_desc[i].action;
6832                 if (!action) 
6833 -                       goto end;
6834 -               p += sprintf(p, "%3d: ",i);
6835 +                       goto skip;
6836 +               seq_printf(p, "%3d: ",i);
6837  #ifndef CONFIG_SMP
6838 -               p += sprintf(p, "%10u ", kstat_irqs(i));
6839 +               seq_printf(p, "%10u ", kstat_irqs(i));
6840  #else
6841 -               for (j = 0; j < num_online_cpus(); j++)
6842 -                       p += sprintf(p, "%10u ",
6843 -                               kstat_cpu(cpu_logical_map(j)).irqs[i]);
6844 +               for (j = 0; j < NR_CPUS; j++)
6845 +                       if (cpu_online(j))
6846 +                               seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
6847  #endif
6848 -               p += sprintf(p, " %14s", irq_desc[i].handler->typename);
6849 -               p += sprintf(p, "  %s", action->name);
6850 +               seq_printf(p, " %14s", irq_desc[i].handler->typename);
6851 +               seq_printf(p, "  %s", action->name);
6852  
6853                 for (action=action->next; action; action = action->next)
6854 -                       p += sprintf(p, ", %s", action->name);
6855 -               *p++ = '\n';
6856 -       end:
6857 +                       seq_printf(p, ", %s", action->name);
6858 +
6859 +               seq_putc(p, '\n');
6860 +skip:
6861                 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
6862         }
6863 -       p += sprintf(p, "\n");
6864 -#ifdef notdef
6865 -#ifdef CONFIG_SMP
6866 -       p += sprintf(p, "LOC: ");
6867 -       for (j = 0; j < num_online_cpus(); j++)
6868 -               p += sprintf(p, "%10u ",
6869 -                       apic_timer_irqs[cpu_logical_map(j)]);
6870 -       p += sprintf(p, "\n");
6871 -#endif
6872 -#endif
6873 -       p += sprintf(p, "ERR: %10lu\n", irq_err_count);
6874 -       return p - buf;
6875 -}
6876 +       seq_printf(p, "NMI: ");
6877 +       for (j = 0; j < NR_CPUS; j++)
6878 +               if (cpu_online(j))
6879 +                       seq_printf(p, "%10u ", nmi_count(j));
6880 +       seq_putc(p, '\n');
6881  
6882 -
6883 -int show_interrupts(struct seq_file *p, void *v)
6884 -{
6885 -       return(0);
6886 +       return 0;
6887  }
6888  
6889  /*
6890 @@ -230,8 +218,11 @@
6891   
6892  void disable_irq(unsigned int irq)
6893  {
6894 +       irq_desc_t *desc = irq_desc + irq;
6895 +
6896         disable_irq_nosync(irq);
6897 -       synchronize_irq(irq);
6898 +       if(desc->action)
6899 +               synchronize_irq(irq);
6900  }
6901  
6902  /**
6903 @@ -252,7 +243,7 @@
6904         spin_lock_irqsave(&desc->lock, flags);
6905         switch (desc->depth) {
6906         case 1: {
6907 -               unsigned int status = desc->status & ~IRQ_DISABLED;
6908 +               unsigned int status = desc->status & IRQ_DISABLED;
6909                 desc->status = status;
6910                 if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
6911                         desc->status = status | IRQ_REPLAY;
6912 @@ -282,13 +273,12 @@
6913          * 0 return value means that this irq is already being
6914          * handled by some other CPU. (or is disabled)
6915          */
6916 -       int cpu = smp_processor_id();
6917         irq_desc_t *desc = irq_desc + irq;
6918         struct irqaction * action;
6919         unsigned int status;
6920  
6921         irq_enter();
6922 -       kstat_cpu(cpu).irqs[irq]++;
6923 +       kstat_this_cpu.irqs[irq]++;
6924         spin_lock(&desc->lock);
6925         desc->handler->ack(irq);
6926         /*
6927 @@ -385,7 +375,7 @@
6928   */
6929   
6930  int request_irq(unsigned int irq,
6931 -               void (*handler)(int, void *, struct pt_regs *),
6932 +               irqreturn_t (*handler)(int, void *, struct pt_regs *),
6933                 unsigned long irqflags, 
6934                 const char * devname,
6935                 void *dev_id)
6936 @@ -433,15 +423,19 @@
6937  EXPORT_SYMBOL(request_irq);
6938  
6939  int um_request_irq(unsigned int irq, int fd, int type,
6940 -                  void (*handler)(int, void *, struct pt_regs *),
6941 +                  irqreturn_t (*handler)(int, void *, struct pt_regs *),
6942                    unsigned long irqflags, const char * devname,
6943                    void *dev_id)
6944  {
6945 -       int retval;
6946 +       int err;
6947  
6948 -       retval = request_irq(irq, handler, irqflags, devname, dev_id);
6949 -       if(retval) return(retval);
6950 -       return(activate_fd(irq, fd, type, dev_id));
6951 +       err = request_irq(irq, handler, irqflags, devname, dev_id);
6952 +       if(err) 
6953 +               return(err);
6954 +
6955 +       if(fd != -1)
6956 +               err = activate_fd(irq, fd, type, dev_id);
6957 +       return(err);
6958  }
6959  
6960  /* this was setup_x86_irq but it seems pretty generic */
6961 @@ -474,7 +468,8 @@
6962          */
6963         spin_lock_irqsave(&desc->lock,flags);
6964         p = &desc->action;
6965 -       if ((old = *p) != NULL) {
6966 +       old = *p;
6967 +       if (old != NULL) {
6968                 /* Can't share interrupts unless both agree to */
6969                 if (!(old->flags & new->flags & SA_SHIRQ)) {
6970                         spin_unlock_irqrestore(&desc->lock,flags);
6971 @@ -597,8 +592,8 @@
6972                 return -EFAULT;
6973  
6974         /*
6975 -        * Parse the first 8 characters as a hex string, any non-hex char
6976 -        * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
6977 +        * Parse the first HEX_DIGITS characters as a hex string, any non-hex 
6978 +        * char is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
6979          */
6980  
6981         for (i = 0; i < count; i++) {
6982 @@ -625,12 +620,14 @@
6983                                         unsigned long count, void *data)
6984  {
6985         int irq = (long) data, full_count = count, err;
6986 -       cpumask_t new_value, tmp;
6987 +       cpumask_t new_value;
6988  
6989         if (!irq_desc[irq].handler->set_affinity)
6990                 return -EIO;
6991  
6992         err = parse_hex_value(buffer, count, &new_value);
6993 +       if(err)
6994 +               return(err);
6995  
6996  #ifdef CONFIG_SMP
6997         /*
6998 @@ -659,7 +656,7 @@
6999                 return -EINVAL;
7000         tmp = *mask;
7001         for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
7002 -               int j = sprintf(page, "%04hx", cpus_coerce(tmp));
7003 +               int j = sprintf(page, "%04hx", (short) cpus_coerce(tmp));
7004                 len += j;
7005                 page += j;
7006                 cpus_shift_right(tmp, tmp, 16);
7007 diff -Naur a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c
7008 --- a/arch/um/kernel/irq_user.c 2004-01-08 22:20:11.000000000 -0500
7009 +++ b/arch/um/kernel/irq_user.c 2004-01-08 22:26:28.000000000 -0500
7010 @@ -6,7 +6,6 @@
7011  #include <stdlib.h>
7012  #include <unistd.h>
7013  #include <errno.h>
7014 -#include <fcntl.h>
7015  #include <signal.h>
7016  #include <string.h>
7017  #include <sys/poll.h>
7018 @@ -49,7 +48,8 @@
7019  
7020         if(smp_sigio_handler()) return;
7021         while(1){
7022 -               if((n = poll(pollfds, pollfds_num, 0)) < 0){
7023 +               n = poll(pollfds, pollfds_num, 0);
7024 +               if(n < 0){
7025                         if(errno == EINTR) continue;
7026                         printk("sigio_handler : poll returned %d, "
7027                                "errno = %d\n", n, errno);
7028 @@ -366,34 +366,31 @@
7029  
7030  void forward_ipi(int fd, int pid)
7031  {
7032 -       if(fcntl(fd, F_SETOWN, pid) < 0){
7033 -               int save_errno = errno;
7034 -               if(fcntl(fd, F_GETOWN, 0) != pid){
7035 -                       printk("forward_ipi: F_SETOWN failed, fd = %d, "
7036 -                              "me = %d, target = %d, errno = %d\n", fd, 
7037 -                              os_getpid(), pid, save_errno);
7038 -               }
7039 -       }
7040 +       int err;
7041 +
7042 +       err = os_set_owner(fd, pid);
7043 +       if(err < 0)
7044 +               printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
7045 +                      "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
7046  }
7047  
7048  void forward_interrupts(int pid)
7049  {
7050         struct irq_fd *irq;
7051         unsigned long flags;
7052 +       int err;
7053  
7054         flags = irq_lock();
7055         for(irq=active_fds;irq != NULL;irq = irq->next){
7056 -               if(fcntl(irq->fd, F_SETOWN, pid) < 0){
7057 -                       int save_errno = errno;
7058 -                       if(fcntl(irq->fd, F_GETOWN, 0) != pid){
7059 -                               /* XXX Just remove the irq rather than
7060 -                                * print out an infinite stream of these
7061 -                                */
7062 -                               printk("Failed to forward %d to pid %d, "
7063 -                                      "errno = %d\n", irq->fd, pid, 
7064 -                                      save_errno);
7065 -                       }
7066 +               err = os_set_owner(irq->fd, pid);
7067 +               if(err < 0){
7068 +                       /* XXX Just remove the irq rather than
7069 +                        * print out an infinite stream of these
7070 +                        */
7071 +                       printk("Failed to forward %d to pid %d, err = %d\n",
7072 +                              irq->fd, pid, -err);
7073                 }
7074 +
7075                 irq->pid = pid;
7076         }
7077         irq_unlock(flags);
7078 diff -Naur a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
7079 --- a/arch/um/kernel/ksyms.c    2004-01-08 22:13:48.000000000 -0500
7080 +++ b/arch/um/kernel/ksyms.c    2004-01-08 22:18:39.000000000 -0500
7081 @@ -1,5 +1,5 @@
7082  /* 
7083 - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
7084 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
7085   * Licensed under the GPL
7086   */
7087  
7088 @@ -34,34 +34,62 @@
7089  EXPORT_SYMBOL(flush_tlb_range);
7090  EXPORT_SYMBOL(host_task_size);
7091  EXPORT_SYMBOL(arch_validate);
7092 +EXPORT_SYMBOL(get_kmem_end);
7093  
7094 -EXPORT_SYMBOL(region_pa);
7095 -EXPORT_SYMBOL(region_va);
7096 -EXPORT_SYMBOL(phys_mem_map);
7097 -EXPORT_SYMBOL(page_mem_map);
7098  EXPORT_SYMBOL(page_to_phys);
7099  EXPORT_SYMBOL(phys_to_page);
7100  EXPORT_SYMBOL(high_physmem);
7101  EXPORT_SYMBOL(empty_zero_page);
7102  EXPORT_SYMBOL(um_virt_to_phys);
7103 +EXPORT_SYMBOL(__virt_to_page);
7104 +EXPORT_SYMBOL(to_phys);
7105 +EXPORT_SYMBOL(to_virt);
7106  EXPORT_SYMBOL(mode_tt);
7107  EXPORT_SYMBOL(handle_page_fault);
7108  
7109 +#ifdef CONFIG_MODE_TT
7110 +EXPORT_SYMBOL(copy_from_user_tt);
7111 +EXPORT_SYMBOL(copy_to_user_tt);
7112 +#endif
7113 +
7114 +#ifdef CONFIG_MODE_SKAS
7115 +EXPORT_SYMBOL(copy_to_user_skas);
7116 +EXPORT_SYMBOL(copy_from_user_skas);
7117 +#endif
7118 +
7119 +EXPORT_SYMBOL(os_stat_fd);
7120 +EXPORT_SYMBOL(os_stat_file);
7121 +EXPORT_SYMBOL(os_access);
7122 +EXPORT_SYMBOL(os_print_error);
7123 +EXPORT_SYMBOL(os_get_exec_close);
7124 +EXPORT_SYMBOL(os_set_exec_close);
7125  EXPORT_SYMBOL(os_getpid);
7126  EXPORT_SYMBOL(os_open_file);
7127  EXPORT_SYMBOL(os_read_file);
7128  EXPORT_SYMBOL(os_write_file);
7129  EXPORT_SYMBOL(os_seek_file);
7130 +EXPORT_SYMBOL(os_lock_file);
7131  EXPORT_SYMBOL(os_pipe);
7132  EXPORT_SYMBOL(os_file_type);
7133 +EXPORT_SYMBOL(os_file_mode);
7134 +EXPORT_SYMBOL(os_file_size);
7135 +EXPORT_SYMBOL(os_flush_stdout);
7136  EXPORT_SYMBOL(os_close_file);
7137 +EXPORT_SYMBOL(os_set_fd_async);
7138 +EXPORT_SYMBOL(os_set_fd_block);
7139  EXPORT_SYMBOL(helper_wait);
7140  EXPORT_SYMBOL(os_shutdown_socket);
7141 +EXPORT_SYMBOL(os_create_unix_socket);
7142  EXPORT_SYMBOL(os_connect_socket);
7143 +EXPORT_SYMBOL(os_accept_connection);
7144 +EXPORT_SYMBOL(os_rcv_fd);
7145  EXPORT_SYMBOL(run_helper);
7146  EXPORT_SYMBOL(start_thread);
7147  EXPORT_SYMBOL(dump_thread);
7148  
7149 +EXPORT_SYMBOL(do_gettimeofday);
7150 +EXPORT_SYMBOL(do_settimeofday);
7151 +
7152  /* This is here because UML expands open to sys_open, not to a system
7153   * call instruction.
7154   */
7155 @@ -90,3 +118,13 @@
7156  EXPORT_SYMBOL(kmap_atomic_to_page);
7157  #endif
7158  
7159 +/*
7160 + * Overrides for Emacs so that we follow Linus's tabbing style.
7161 + * Emacs will notice this stuff at the end of the file and automatically
7162 + * adjust the settings for this buffer only.  This must remain at the end
7163 + * of the file.
7164 + * ---------------------------------------------------------------------------
7165 + * Local variables:
7166 + * c-file-style: "linux"
7167 + * End:
7168 + */
7169 diff -Naur a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
7170 --- a/arch/um/kernel/Makefile   2004-01-08 22:25:20.000000000 -0500
7171 +++ b/arch/um/kernel/Makefile   2004-01-08 22:32:41.000000000 -0500
7172 @@ -7,11 +7,11 @@
7173  
7174  obj-y = checksum.o config.o exec_kern.o exitcode.o frame_kern.o frame.o \
7175         helper.o init_task.o irq.o irq_user.o ksyms.o mem.o mem_user.o \
7176 -       process.o process_kern.o ptrace.o reboot.o resource.o sigio_user.o \
7177 -       sigio_kern.o signal_kern.o signal_user.o smp.o syscall_kern.o \
7178 -       syscall_user.o sysrq.o sys_call_table.o tempfile.o time.o \
7179 -       time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o \
7180 -       umid.o user_syms.o user_util.o
7181 +       physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \
7182 +       sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \
7183 +       syscall_kern.o syscall_user.o sysrq.o sys_call_table.o tempfile.o \
7184 +       time.o time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o \
7185 +       um_arch.o umid.o user_syms.o user_util.o
7186  
7187  obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
7188  obj-$(CONFIG_GPROF)    += gprof_syms.o
7189 @@ -21,6 +21,8 @@
7190  obj-$(CONFIG_MODE_TT) += tt/
7191  obj-$(CONFIG_MODE_SKAS) += skas/
7192  
7193 +clean-files    := config.c
7194 +
7195  user-objs-$(CONFIG_TTY_LOG) += tty_log.o
7196  
7197  USER_OBJS := $(filter %_user.o,$(obj-y))  $(user-objs-y) config.o helper.o \
7198 @@ -45,17 +47,13 @@
7199  $(obj)/frame.o: $(src)/frame.c
7200         $(CC) $(CFLAGS_$(notdir $@)) -c -o $@ $<
7201  
7202 -QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
7203 +QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
7204  
7205  $(obj)/config.c : $(src)/config.c.in $(TOPDIR)/.config
7206         $(PERL) -e $(QUOTE) < $(src)/config.c.in > $@
7207  
7208  $(obj)/config.o : $(obj)/config.c
7209  
7210 -clean:
7211 -       rm -f config.c
7212 -       for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
7213 -
7214  modules:
7215  
7216  fastdep:
7217 diff -Naur a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
7218 --- a/arch/um/kernel/mem.c      2004-01-08 22:19:21.000000000 -0500
7219 +++ b/arch/um/kernel/mem.c      2004-01-08 22:25:37.000000000 -0500
7220 @@ -1,74 +1,67 @@
7221  /* 
7222 - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
7223 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
7224   * Licensed under the GPL
7225   */
7226  
7227 -#include "linux/config.h"
7228 -#include "linux/module.h"
7229 -#include "linux/types.h"
7230 +#include "linux/stddef.h"
7231 +#include "linux/kernel.h"
7232  #include "linux/mm.h"
7233 -#include "linux/fs.h"
7234 -#include "linux/init.h"
7235  #include "linux/bootmem.h"
7236  #include "linux/swap.h"
7237 -#include "linux/slab.h"
7238 -#include "linux/vmalloc.h"
7239  #include "linux/highmem.h"
7240 +#include "linux/gfp.h"
7241  #include "asm/page.h"
7242 -#include "asm/pgtable.h"
7243 +#include "asm/fixmap.h"
7244  #include "asm/pgalloc.h"
7245 -#include "asm/bitops.h"
7246 -#include "asm/uaccess.h"
7247 -#include "asm/tlb.h"
7248  #include "user_util.h"
7249  #include "kern_util.h"
7250 -#include "mem_user.h"
7251 -#include "mem.h"
7252  #include "kern.h"
7253 -#include "init.h"
7254 -#include "os.h"
7255 -#include "mode_kern.h"
7256 +#include "mem_user.h"
7257  #include "uml_uaccess.h"
7258 +#include "os.h"
7259 +
7260 +extern char __binary_start;
7261  
7262  /* Changed during early boot */
7263 -pgd_t swapper_pg_dir[1024];
7264 -unsigned long high_physmem;
7265 -unsigned long vm_start;
7266 -unsigned long vm_end;
7267 -unsigned long highmem;
7268  unsigned long *empty_zero_page = NULL;
7269  unsigned long *empty_bad_page = NULL;
7270 -
7271 -/* Not modified */
7272 -const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n";
7273 -
7274 -extern char __init_begin, __init_end;
7275 -extern long physmem_size;
7276 -
7277 -/* Not changed by UML */
7278 -DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
7279 -
7280 -/* Changed during early boot */
7281 +pgd_t swapper_pg_dir[1024];
7282 +unsigned long highmem;
7283  int kmalloc_ok = 0;
7284  
7285 -#define NREGIONS (phys_region_index(0xffffffff) - phys_region_index(0x0) + 1)
7286 -struct mem_region *regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] = NULL };
7287 -#define REGION_SIZE ((0xffffffff & ~REGION_MASK) + 1)
7288 -
7289 -/* Changed during early boot */
7290  static unsigned long brk_end;
7291 +static unsigned long totalram_pages = 0;
7292 +
7293 +void unmap_physmem(void)
7294 +{
7295 +       os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
7296 +}
7297  
7298  static void map_cb(void *unused)
7299  {
7300         map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0);
7301  }
7302  
7303 -void unmap_physmem(void)
7304 +#ifdef CONFIG_HIGHMEM
7305 +static void setup_highmem(unsigned long highmem_start, 
7306 +                         unsigned long highmem_len)
7307  {
7308 -       os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
7309 -}
7310 +       struct page *page;
7311 +       unsigned long highmem_pfn;
7312 +       int i;
7313  
7314 -extern char __binary_start;
7315 +       highmem_start_page = virt_to_page(highmem_start);
7316 +
7317 +       highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT;
7318 +       for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){
7319 +               page = &mem_map[highmem_pfn + i];
7320 +               ClearPageReserved(page);
7321 +               set_bit(PG_highmem, &page->flags);
7322 +               atomic_set(&page->count, 1);
7323 +               __free_page(page);
7324 +       }
7325 +}
7326 +#endif
7327  
7328  void mem_init(void)
7329  {
7330 @@ -103,50 +96,15 @@
7331         totalhigh_pages = highmem >> PAGE_SHIFT;
7332         totalram_pages += totalhigh_pages;
7333         num_physpages = totalram_pages;
7334 -       max_mapnr = totalram_pages;
7335         max_pfn = totalram_pages;
7336         printk(KERN_INFO "Memory: %luk available\n", 
7337                (unsigned long) nr_free_pages() << (PAGE_SHIFT-10));
7338         kmalloc_ok = 1;
7339 -}
7340 -
7341 -/* Changed during early boot */
7342 -static unsigned long kmem_top = 0;
7343 -
7344 -unsigned long get_kmem_end(void)
7345 -{
7346 -       if(kmem_top == 0)
7347 -               kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
7348 -       return(kmem_top);
7349 -}
7350 -
7351 -void set_kmem_end(unsigned long new)
7352 -{
7353 -       kmem_top = new;
7354 -}
7355  
7356  #ifdef CONFIG_HIGHMEM
7357 -/* Changed during early boot */
7358 -pte_t *kmap_pte;
7359 -pgprot_t kmap_prot;
7360 -
7361 -EXPORT_SYMBOL(kmap_prot);
7362 -EXPORT_SYMBOL(kmap_pte);
7363 -
7364 -#define kmap_get_fixmap_pte(vaddr)                                     \
7365 -       pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
7366 -
7367 -void __init kmap_init(void)
7368 -{
7369 -       unsigned long kmap_vstart;
7370 -
7371 -       /* cache the first kmap pte */
7372 -       kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
7373 -       kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
7374 -
7375 -       kmap_prot = PAGE_KERNEL;
7376 +       setup_highmem(end_iomem, highmem);
7377 +#endif
7378  }
7379 -#endif /* CONFIG_HIGHMEM */
7380  
7381  static void __init fixrange_init(unsigned long start, unsigned long end, 
7382                                  pgd_t *pgd_base)
7383 @@ -178,76 +136,24 @@
7384         }
7385  }
7386  
7387 -int init_maps(struct mem_region *region)
7388 -{
7389 -       struct page *p, *map;
7390 -       int i, n, len;
7391 -
7392 -       if(region == &physmem_region){
7393 -               region->mem_map = mem_map;
7394 -               return(0);
7395 -       }
7396 -       else if(region->mem_map != NULL) return(0);
7397 -
7398 -       n = region->len >> PAGE_SHIFT;
7399 -       len = n * sizeof(struct page);
7400 -       if(kmalloc_ok){
7401 -               map = kmalloc(len, GFP_KERNEL);
7402 -               if(map == NULL) map = vmalloc(len);
7403 -       }
7404 -       else map = alloc_bootmem_low_pages(len);
7405 -
7406 -       if(map == NULL)
7407 -               return(-ENOMEM);
7408 -       for(i = 0; i < n; i++){
7409 -               p = &map[i];
7410 -               set_page_count(p, 0);
7411 -               SetPageReserved(p);
7412 -               INIT_LIST_HEAD(&p->list);
7413 -       }
7414 -       region->mem_map = map;
7415 -       return(0);
7416 -}
7417 +#if CONFIG_HIGHMEM
7418 +pte_t *kmap_pte;
7419 +pgprot_t kmap_prot;
7420  
7421 -DECLARE_MUTEX(regions_sem);
7422 +#define kmap_get_fixmap_pte(vaddr)                                     \
7423 +       pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
7424  
7425 -static int setup_one_range(int fd, char *driver, unsigned long start, 
7426 -                          unsigned long pfn, int len, 
7427 -                          struct mem_region *region)
7428 +void __init kmap_init(void)
7429  {
7430 -       int i;
7431 -
7432 -       down(&regions_sem);
7433 -       for(i = 0; i < NREGIONS; i++){
7434 -               if(regions[i] == NULL) break;           
7435 -       }
7436 -       if(i == NREGIONS){
7437 -               printk("setup_range : no free regions\n");
7438 -               i = -1;
7439 -               goto out;
7440 -       }
7441 -
7442 -       if(fd == -1)
7443 -               fd = create_mem_file(len);
7444 +       unsigned long kmap_vstart;
7445  
7446 -       if(region == NULL){
7447 -               region = alloc_bootmem_low_pages(sizeof(*region));
7448 -               if(region == NULL)
7449 -                       panic("Failed to allocating mem_region");
7450 -       }
7451 +       /* cache the first kmap pte */
7452 +       kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
7453 +       kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
7454  
7455 -       *region = ((struct mem_region) { .driver        = driver,
7456 -                                        .start_pfn     = pfn,
7457 -                                        .start         = start, 
7458 -                                        .len           = len, 
7459 -                                        .fd            = fd } );
7460 -       regions[i] = region;
7461 - out:
7462 -       up(&regions_sem);
7463 -       return(i);
7464 +       kmap_prot = PAGE_KERNEL;
7465  }
7466  
7467 -#ifdef CONFIG_HIGHMEM
7468  static void init_highmem(void)
7469  {
7470         pgd_t *pgd;
7471 @@ -268,63 +174,20 @@
7472  
7473         kmap_init();
7474  }
7475 -
7476 -void setup_highmem(unsigned long len)
7477 -{
7478 -       struct mem_region *region;
7479 -       struct page *page, *map;
7480 -       unsigned long phys;
7481 -       int i, cur, index;
7482 -
7483 -       phys = physmem_size;
7484 -       do {
7485 -               cur = min(len, (unsigned long) REGION_SIZE);
7486 -               i = setup_one_range(-1, NULL, -1, phys >> PAGE_SHIFT, cur, 
7487 -                                   NULL);
7488 -               if(i == -1){
7489 -                       printk("setup_highmem - setup_one_range failed\n");
7490 -                       return;
7491 -               }
7492 -               region = regions[i];
7493 -               index = phys / PAGE_SIZE;
7494 -               region->mem_map = &mem_map[index];
7495 -
7496 -               map = region->mem_map;
7497 -               for(i = 0; i < (cur >> PAGE_SHIFT); i++){
7498 -                       page = &map[i];
7499 -                       ClearPageReserved(page);
7500 -                       set_bit(PG_highmem, &page->flags);
7501 -                       atomic_set(&page->count, 1);
7502 -                       __free_page(page);
7503 -               }
7504 -               phys += cur;
7505 -               len -= cur;
7506 -       } while(len > 0);
7507 -}
7508 -#endif
7509 +#endif /* CONFIG_HIGHMEM */
7510  
7511  void paging_init(void)
7512  {
7513 -       struct mem_region *region;
7514 -       unsigned long zones_size[MAX_NR_ZONES], start, end, vaddr;
7515 -       int i, index;
7516 +       unsigned long zones_size[MAX_NR_ZONES], vaddr;
7517 +       int i;
7518  
7519         empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
7520         empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
7521         for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++) 
7522                 zones_size[i] = 0;
7523 -       zones_size[0] = (high_physmem >> PAGE_SHIFT) - 
7524 -               (uml_physmem >> PAGE_SHIFT);
7525 +       zones_size[0] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT);
7526         zones_size[2] = highmem >> PAGE_SHIFT;
7527         free_area_init(zones_size);
7528 -       start = phys_region_index(__pa(uml_physmem));
7529 -       end = phys_region_index(__pa(high_physmem - 1));
7530 -       for(i = start; i <= end; i++){
7531 -               region = regions[i];
7532 -               index = (region->start - uml_physmem) / PAGE_SIZE;
7533 -               region->mem_map = &mem_map[index];
7534 -               if(i > start) free_bootmem(__pa(region->start), region->len);
7535 -       }
7536  
7537         /*
7538          * Fixed mappings, only the page table structure has to be
7539 @@ -335,15 +198,33 @@
7540  
7541  #ifdef CONFIG_HIGHMEM
7542         init_highmem();
7543 -       setup_highmem(highmem);
7544  #endif
7545  }
7546  
7547 -pte_t __bad_page(void)
7548 +struct page *arch_validate(struct page *page, int mask, int order)
7549  {
7550 -       clear_page(empty_bad_page);
7551 -        return pte_mkdirty(mk_pte((struct page *) empty_bad_page, 
7552 -                                 PAGE_SHARED));
7553 +       unsigned long addr, zero = 0;
7554 +       int i;
7555 +
7556 + again:
7557 +       if(page == NULL) return(page);
7558 +       if(PageHighMem(page)) return(page);
7559 +
7560 +       addr = (unsigned long) page_address(page);
7561 +       for(i = 0; i < (1 << order); i++){
7562 +               current->thread.fault_addr = (void *) addr;
7563 +               if(__do_copy_to_user((void *) addr, &zero, 
7564 +                                    sizeof(zero),
7565 +                                    &current->thread.fault_addr,
7566 +                                    &current->thread.fault_catcher)){
7567 +                       if(!(mask & __GFP_WAIT)) return(NULL);
7568 +                       else break;
7569 +               }
7570 +               addr += PAGE_SIZE;
7571 +       }
7572 +       if(i == (1 << order)) return(page);
7573 +       page = alloc_pages(mask, order);
7574 +       goto again;
7575  }
7576  
7577  /* This can't do anything because nothing in the kernel image can be freed
7578 @@ -401,395 +282,6 @@
7579          printk("%d pages swap cached\n", cached);
7580  }
7581  
7582 -static int __init uml_mem_setup(char *line, int *add)
7583 -{
7584 -       char *retptr;
7585 -       physmem_size = memparse(line,&retptr);
7586 -       return 0;
7587 -}
7588 -__uml_setup("mem=", uml_mem_setup,
7589 -"mem=<Amount of desired ram>\n"
7590 -"    This controls how much \"physical\" memory the kernel allocates\n"
7591 -"    for the system. The size is specified as a number followed by\n"
7592 -"    one of 'k', 'K', 'm', 'M', which have the obvious meanings.\n"
7593 -"    This is not related to the amount of memory in the physical\n"
7594 -"    machine. It can be more, and the excess, if it's ever used, will\n"
7595 -"    just be swapped out.\n        Example: mem=64M\n\n"
7596 -);
7597 -
7598 -struct page *arch_validate(struct page *page, int mask, int order)
7599 -{
7600 -       unsigned long addr, zero = 0;
7601 -       int i;
7602 -
7603 - again:
7604 -       if(page == NULL) return(page);
7605 -       if(PageHighMem(page)) return(page);
7606 -
7607 -       addr = (unsigned long) page_address(page);
7608 -       for(i = 0; i < (1 << order); i++){
7609 -               current->thread.fault_addr = (void *) addr;
7610 -               if(__do_copy_to_user((void *) addr, &zero, 
7611 -                                    sizeof(zero),
7612 -                                    &current->thread.fault_addr,
7613 -                                    &current->thread.fault_catcher)){
7614 -                       if(!(mask & __GFP_WAIT)) return(NULL);
7615 -                       else break;
7616 -               }
7617 -               addr += PAGE_SIZE;
7618 -       }
7619 -       if(i == (1 << order)) return(page);
7620 -       page = alloc_pages(mask, order);
7621 -       goto again;
7622 -}
7623 -
7624 -DECLARE_MUTEX(vm_reserved_sem);
7625 -static struct list_head vm_reserved = LIST_HEAD_INIT(vm_reserved);
7626 -
7627 -/* Static structures, linked in to the list in early boot */
7628 -static struct vm_reserved head = {
7629 -       .list           = LIST_HEAD_INIT(head.list),
7630 -       .start          = 0,
7631 -       .end            = 0xffffffff
7632 -};
7633 -
7634 -static struct vm_reserved tail = {
7635 -       .list           = LIST_HEAD_INIT(tail.list),
7636 -       .start          = 0,
7637 -       .end            = 0xffffffff
7638 -};
7639 -
7640 -void set_usable_vm(unsigned long start, unsigned long end)
7641 -{
7642 -       list_add(&head.list, &vm_reserved);
7643 -       list_add(&tail.list, &head.list);
7644 -       head.end = start;
7645 -       tail.start = end;
7646 -}
7647 -
7648 -int reserve_vm(unsigned long start, unsigned long end, void *e)
7649 -              
7650 -{
7651 -       struct vm_reserved *entry = e, *reserved, *prev;
7652 -       struct list_head *ele;
7653 -       int err;
7654 -
7655 -       down(&vm_reserved_sem);
7656 -       list_for_each(ele, &vm_reserved){
7657 -               reserved = list_entry(ele, struct vm_reserved, list);
7658 -               if(reserved->start >= end) goto found;
7659 -       }
7660 -       panic("Reserved vm out of range");
7661 - found:
7662 -       prev = list_entry(ele->prev, struct vm_reserved, list);
7663 -       if(prev->end > start)
7664 -               panic("Can't reserve vm");
7665 -       if(entry == NULL)
7666 -               entry = kmalloc(sizeof(*entry), GFP_KERNEL);
7667 -       if(entry == NULL){
7668 -               printk("reserve_vm : Failed to allocate entry\n");
7669 -               err = -ENOMEM;
7670 -               goto out;
7671 -       }
7672 -       *entry = ((struct vm_reserved) 
7673 -               { .list         = LIST_HEAD_INIT(entry->list),
7674 -                 .start        = start,
7675 -                 .end          = end });
7676 -       list_add(&entry->list, &prev->list);
7677 -       err = 0;
7678 - out:
7679 -       up(&vm_reserved_sem);
7680 -       return(0);
7681 -}
7682 -
7683 -unsigned long get_vm(unsigned long len)
7684 -{
7685 -       struct vm_reserved *this, *next;
7686 -       struct list_head *ele;
7687 -       unsigned long start;
7688 -       int err;
7689 -       
7690 -       down(&vm_reserved_sem);
7691 -       list_for_each(ele, &vm_reserved){
7692 -               this = list_entry(ele, struct vm_reserved, list);
7693 -               next = list_entry(ele->next, struct vm_reserved, list);
7694 -               if((this->start < next->start) && 
7695 -                  (this->end + len + PAGE_SIZE <= next->start))
7696 -                       goto found;
7697 -       }
7698 -       up(&vm_reserved_sem);
7699 -       return(0);
7700 - found:
7701 -       up(&vm_reserved_sem);
7702 -       start = (unsigned long) UML_ROUND_UP(this->end) + PAGE_SIZE;
7703 -       err = reserve_vm(start, start + len, NULL);
7704 -       if(err) return(0);
7705 -       return(start);
7706 -}
7707 -
7708 -int nregions(void)
7709 -{
7710 -       return(NREGIONS);
7711 -}
7712 -
7713 -void setup_range(int fd, char *driver, unsigned long start, unsigned long pfn,
7714 -                unsigned long len, int need_vm, struct mem_region *region, 
7715 -                void *reserved)
7716 -{
7717 -       int i, cur;
7718 -
7719 -       do {
7720 -               cur = min(len, (unsigned long) REGION_SIZE);
7721 -               i = setup_one_range(fd, driver, start, pfn, cur, region);
7722 -               region = regions[i];
7723 -               if(need_vm && setup_region(region, reserved)){
7724 -                       kfree(region);
7725 -                       regions[i] = NULL;
7726 -                       return;
7727 -               }
7728 -               start += cur;
7729 -               if(pfn != -1) pfn += cur;
7730 -               len -= cur;
7731 -       } while(len > 0);
7732 -}
7733 -
7734 -struct iomem {
7735 -       char *name;
7736 -       int fd;
7737 -       unsigned long size;
7738 -};
7739 -
7740 -/* iomem regions can only be added on the command line at the moment.  
7741 - * Locking will be needed when they can be added via mconsole.
7742 - */
7743 -
7744 -struct iomem iomem_regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] =
7745 -                                        { .name        = NULL,
7746 -                                          .fd          = -1,
7747 -                                          .size        = 0 } };
7748 -
7749 -int num_iomem_regions = 0;
7750 -
7751 -void add_iomem(char *name, int fd, unsigned long size)
7752 -{
7753 -       if(num_iomem_regions == sizeof(iomem_regions)/sizeof(iomem_regions[0]))
7754 -               return;
7755 -       size = (size + PAGE_SIZE - 1) & PAGE_MASK;
7756 -       iomem_regions[num_iomem_regions++] = 
7757 -               ((struct iomem) { .name         = name,
7758 -                                 .fd           = fd,
7759 -                                 .size         = size } );
7760 -}
7761 -
7762 -int setup_iomem(void)
7763 -{
7764 -       struct iomem *iomem;
7765 -       int i;
7766 -
7767 -       for(i = 0; i < num_iomem_regions; i++){
7768 -               iomem = &iomem_regions[i];
7769 -               setup_range(iomem->fd, iomem->name, -1, -1, iomem->size, 1, 
7770 -                           NULL, NULL);
7771 -       }
7772 -       return(0);
7773 -}
7774 -
7775 -__initcall(setup_iomem);
7776 -
7777 -#define PFN_UP(x)      (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
7778 -#define PFN_DOWN(x)    ((x) >> PAGE_SHIFT)
7779 -
7780 -/* Changed during early boot */
7781 -static struct mem_region physmem_region;
7782 -static struct vm_reserved physmem_reserved;
7783 -
7784 -void setup_physmem(unsigned long start, unsigned long reserve_end,
7785 -                  unsigned long len)
7786 -{
7787 -       struct mem_region *region = &physmem_region;
7788 -       struct vm_reserved *reserved = &physmem_reserved;
7789 -       unsigned long cur, pfn = 0;
7790 -       int do_free = 1, bootmap_size;
7791 -
7792 -       do {
7793 -               cur = min(len, (unsigned long) REGION_SIZE);
7794 -               if(region == NULL) 
7795 -                       region = alloc_bootmem_low_pages(sizeof(*region));
7796 -               if(reserved == NULL) 
7797 -                       reserved = alloc_bootmem_low_pages(sizeof(*reserved));
7798 -               if((region == NULL) || (reserved == NULL))
7799 -                       panic("Couldn't allocate physmem region or vm "
7800 -                             "reservation\n");
7801 -               setup_range(-1, NULL, start, pfn, cur, 1, region, reserved);
7802 -
7803 -               if(do_free){
7804 -                       unsigned long reserve = reserve_end - start;
7805 -                       int pfn = PFN_UP(__pa(reserve_end));
7806 -                       int delta = (len - reserve) >> PAGE_SHIFT;
7807 -
7808 -                       bootmap_size = init_bootmem(pfn, pfn + delta);
7809 -                       free_bootmem(__pa(reserve_end) + bootmap_size,
7810 -                                    cur - bootmap_size - reserve);
7811 -                       do_free = 0;
7812 -               }
7813 -               start += cur;
7814 -               pfn += cur >> PAGE_SHIFT;
7815 -               len -= cur;
7816 -               region = NULL;
7817 -               reserved = NULL;
7818 -       } while(len > 0);
7819 -}
7820 -
7821 -struct mem_region *phys_region(unsigned long phys)
7822 -{
7823 -       unsigned int n = phys_region_index(phys);
7824 -
7825 -       if(regions[n] == NULL) 
7826 -               panic("Physical address in uninitialized region");
7827 -       return(regions[n]);
7828 -}
7829 -
7830 -unsigned long phys_offset(unsigned long phys)
7831 -{
7832 -       return(phys_addr(phys));
7833 -}
7834 -
7835 -struct page *phys_mem_map(unsigned long phys)
7836 -{
7837 -       return((struct page *) phys_region(phys)->mem_map);
7838 -}
7839 -
7840 -struct page *pte_mem_map(pte_t pte)
7841 -{
7842 -       return(phys_mem_map(pte_val(pte)));
7843 -}
7844 -
7845 -struct mem_region *page_region(struct page *page, int *index_out)
7846 -{
7847 -       int i;
7848 -       struct mem_region *region;
7849 -       struct page *map;
7850 -
7851 -       for(i = 0; i < NREGIONS; i++){
7852 -               region = regions[i];
7853 -               if(region == NULL) continue;
7854 -               map = region->mem_map;
7855 -               if((page >= map) && (page < &map[region->len >> PAGE_SHIFT])){
7856 -                       if(index_out != NULL) *index_out = i;
7857 -                       return(region);
7858 -               }
7859 -       }
7860 -       panic("No region found for page");
7861 -       return(NULL);
7862 -}
7863 -
7864 -unsigned long page_to_pfn(struct page *page)
7865 -{
7866 -       struct mem_region *region = page_region(page, NULL);
7867 -
7868 -       return(region->start_pfn + (page - (struct page *) region->mem_map));
7869 -}
7870 -
7871 -struct mem_region *pfn_to_region(unsigned long pfn, int *index_out)
7872 -{
7873 -       struct mem_region *region;
7874 -       int i;
7875 -
7876 -       for(i = 0; i < NREGIONS; i++){
7877 -               region = regions[i];
7878 -               if(region == NULL)
7879 -                       continue;
7880 -
7881 -               if((region->start_pfn <= pfn) &&
7882 -                  (region->start_pfn + (region->len >> PAGE_SHIFT) > pfn)){
7883 -                       if(index_out != NULL) 
7884 -                               *index_out = i;
7885 -                       return(region);
7886 -               }
7887 -       }
7888 -       return(NULL);
7889 -}
7890 -
7891 -struct page *pfn_to_page(unsigned long pfn)
7892 -{
7893 -       struct mem_region *region = pfn_to_region(pfn, NULL);
7894 -       struct page *mem_map = (struct page *) region->mem_map;
7895 -
7896 -       return(&mem_map[pfn - region->start_pfn]);
7897 -}
7898 -
7899 -unsigned long phys_to_pfn(unsigned long p)
7900 -{
7901 -       struct mem_region *region = regions[phys_region_index(p)];
7902 -
7903 -       return(region->start_pfn + (phys_addr(p) >> PAGE_SHIFT));
7904 -}
7905 -
7906 -unsigned long pfn_to_phys(unsigned long pfn)
7907 -{
7908 -       int n;
7909 -       struct mem_region *region = pfn_to_region(pfn, &n);
7910 -
7911 -       return(mk_phys((pfn - region->start_pfn) << PAGE_SHIFT, n));
7912 -}
7913 -
7914 -struct page *page_mem_map(struct page *page)
7915 -{
7916 -       return((struct page *) page_region(page, NULL)->mem_map);
7917 -}
7918 -
7919 -extern unsigned long region_pa(void *virt)
7920 -{
7921 -       struct mem_region *region;
7922 -       unsigned long addr = (unsigned long) virt;
7923 -       int i;
7924 -
7925 -       for(i = 0; i < NREGIONS; i++){
7926 -               region = regions[i];
7927 -               if(region == NULL) continue;
7928 -               if((region->start <= addr) && 
7929 -                  (addr <= region->start + region->len))
7930 -                       return(mk_phys(addr - region->start, i));
7931 -       }
7932 -       panic("region_pa : no region for virtual address");
7933 -       return(0);
7934 -}
7935 -
7936 -extern void *region_va(unsigned long phys)
7937 -{
7938 -       return((void *) (phys_region(phys)->start + phys_addr(phys)));
7939 -}
7940 -
7941 -unsigned long page_to_phys(struct page *page)
7942 -{
7943 -       int n;
7944 -       struct mem_region *region = page_region(page, &n);
7945 -       struct page *map = region->mem_map;
7946 -       return(mk_phys((page - map) << PAGE_SHIFT, n));
7947 -}
7948 -
7949 -struct page *phys_to_page(unsigned long phys)
7950 -{
7951 -       struct page *mem_map;
7952 -
7953 -       mem_map = phys_mem_map(phys);
7954 -       return(mem_map + (phys_offset(phys) >> PAGE_SHIFT));
7955 -}
7956 -
7957 -static int setup_mem_maps(void)
7958 -{
7959 -       struct mem_region *region;
7960 -       int i;
7961 -
7962 -       for(i = 0; i < NREGIONS; i++){
7963 -               region = regions[i];
7964 -               if((region != NULL) && (region->fd > 0)) init_maps(region);
7965 -       }
7966 -       return(0);
7967 -}
7968 -
7969 -__initcall(setup_mem_maps);
7970 -
7971  /*
7972   * Allocate and free page tables.
7973   */
7974 diff -Naur a/arch/um/kernel/mem_user.c b/arch/um/kernel/mem_user.c
7975 --- a/arch/um/kernel/mem_user.c 2004-01-08 22:22:10.000000000 -0500
7976 +++ b/arch/um/kernel/mem_user.c 2004-01-08 22:29:21.000000000 -0500
7977 @@ -34,10 +34,9 @@
7978  #include <stddef.h>
7979  #include <stdarg.h>
7980  #include <unistd.h>
7981 -#include <fcntl.h>
7982  #include <errno.h>
7983  #include <string.h>
7984 -#include <sys/stat.h>
7985 +#include <fcntl.h>
7986  #include <sys/types.h>
7987  #include <sys/mman.h>
7988  #include "kern_util.h"
7989 @@ -47,105 +46,145 @@
7990  #include "init.h"
7991  #include "os.h"
7992  #include "tempfile.h"
7993 +#include "kern_constants.h"
7994  
7995  extern struct mem_region physmem_region;
7996  
7997  #define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
7998  
7999 -int create_mem_file(unsigned long len)
8000 +static int create_tmp_file(unsigned long len)
8001  {
8002 -       int fd;
8003 +       int fd, err;
8004         char zero;
8005  
8006         fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
8007 -       if (fchmod(fd, 0777) < 0){
8008 -               perror("fchmod");
8009 +       if(fd < 0) {
8010 +               os_print_error(fd, "make_tempfile");
8011 +               exit(1);
8012 +       }
8013 +
8014 +       err = os_mode_fd(fd, 0777);
8015 +       if(err < 0){
8016 +               os_print_error(err, "os_mode_fd");
8017                 exit(1);
8018         }
8019 -       if(os_seek_file(fd, len) < 0){
8020 -               perror("lseek");
8021 +       err = os_seek_file(fd, len);
8022 +       if(err < 0){
8023 +               os_print_error(err, "os_seek_file");
8024                 exit(1);
8025         }
8026         zero = 0;
8027 -       if(write(fd, &zero, 1) != 1){
8028 -               perror("write");
8029 +       err = os_write_file(fd, &zero, 1);
8030 +       if(err != 1){
8031 +               os_print_error(err, "os_write_file");
8032                 exit(1);
8033         }
8034 -       if(fcntl(fd, F_SETFD, 1) != 0)
8035 -               perror("Setting FD_CLOEXEC failed");
8036 +
8037         return(fd);
8038  }
8039  
8040 -int setup_region(struct mem_region *region, void *entry)
8041 +static int have_devanon = 0;
8042 +
8043 +void check_devanon(void)
8044 +{
8045 +       int fd;
8046 +
8047 +       printk("Checking for /dev/anon on the host...");
8048 +       fd = open("/dev/anon", O_RDWR);
8049 +       if(fd < 0){
8050 +               printk("Not available (open failed with errno %d)\n", errno);
8051 +               return;
8052 +       }
8053 +
8054 +       printk("OK\n");
8055 +       have_devanon = 1;
8056 +}
8057 +
8058 +static int create_anon_file(unsigned long len)
8059  {
8060 -       void *loc, *start;
8061 -       char *driver;
8062 -       int err, offset;
8063 -
8064 -       if(region->start != -1){
8065 -               err = reserve_vm(region->start, 
8066 -                                region->start + region->len, entry);
8067 -               if(err){
8068 -                       printk("setup_region : failed to reserve "
8069 -                              "0x%x - 0x%x for driver '%s'\n",
8070 -                              region->start, 
8071 -                              region->start + region->len,
8072 -                              region->driver);
8073 -                       return(-1);
8074 -               }
8075 -       }
8076 -       else region->start = get_vm(region->len);
8077 -       if(region->start == 0){
8078 -               if(region->driver == NULL) driver = "physmem";
8079 -               else driver = region->driver;
8080 -               printk("setup_region : failed to find vm for "
8081 -                      "driver '%s' (length %d)\n", driver, region->len);
8082 -               return(-1);
8083 -       }
8084 -       if(region->start == uml_physmem){
8085 -               start = (void *) uml_reserved;
8086 -               offset = uml_reserved - uml_physmem;
8087 -       }
8088 -       else {
8089 -               start = (void *) region->start;
8090 -               offset = 0;
8091 -       }
8092 -
8093 -       loc = mmap(start, region->len - offset, PROT_READ | PROT_WRITE, 
8094 -                  MAP_SHARED | MAP_FIXED, region->fd, offset);
8095 -       if(loc != start){
8096 -               perror("Mapping memory");
8097 +       void *addr;
8098 +       int fd;
8099 +
8100 +       fd = open("/dev/anon", O_RDWR);
8101 +       if(fd < 0) {
8102 +               os_print_error(fd, "opening /dev/anon");
8103                 exit(1);
8104         }
8105 -       return(0);
8106 +
8107 +       addr = mmap(NULL, len, PROT_READ | PROT_WRITE , MAP_PRIVATE, fd, 0);
8108 +       if(addr == MAP_FAILED){
8109 +               os_print_error((int) addr, "mapping physmem file");
8110 +               exit(1);
8111 +       }
8112 +       munmap(addr, len);
8113 +
8114 +       return(fd);
8115 +}
8116 +
8117 +int create_mem_file(unsigned long len)
8118 +{
8119 +       int err, fd;
8120 +
8121 +       if(have_devanon)
8122 +               fd = create_anon_file(len);
8123 +       else fd = create_tmp_file(len);
8124 +
8125 +       err = os_set_exec_close(fd, 1);
8126 +       if(err < 0)
8127 +               os_print_error(err, "exec_close");
8128 +       return(fd);
8129  }
8130  
8131 +struct iomem_region *iomem_regions = NULL;
8132 +int iomem_size = 0;
8133 +
8134  static int __init parse_iomem(char *str, int *add)
8135  {
8136 -       struct stat buf;
8137 +       struct iomem_region *new;
8138 +       struct uml_stat buf;
8139         char *file, *driver;
8140 -       int fd;
8141 +       int fd, err;
8142  
8143         driver = str;
8144         file = strchr(str,',');
8145         if(file == NULL){
8146 -               printk("parse_iomem : failed to parse iomem\n");
8147 -               return(1);
8148 +               printf("parse_iomem : failed to parse iomem\n");
8149 +               goto out;
8150         }
8151         *file = '\0';
8152         file++;
8153         fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
8154         if(fd < 0){
8155 -               printk("parse_iomem - Couldn't open io file, errno = %d\n", 
8156 -                      errno);
8157 -               return(1);
8158 -       }
8159 -       if(fstat(fd, &buf) < 0) {
8160 -               printk("parse_iomem - cannot fstat file, errno = %d\n", errno);
8161 -               return(1);
8162 +               os_print_error(fd, "parse_iomem - Couldn't open io file");
8163 +               goto out;
8164         }
8165 -       add_iomem(driver, fd, buf.st_size);
8166 +
8167 +       err = os_stat_fd(fd, &buf);
8168 +       if(err < 0){
8169 +               os_print_error(err, "parse_iomem - cannot stat_fd file");
8170 +               goto out_close;
8171 +       }
8172 +
8173 +       new = malloc(sizeof(*new));
8174 +       if(new == NULL){
8175 +               perror("Couldn't allocate iomem_region struct");
8176 +               goto out_close;
8177 +       }
8178 +
8179 +       *new = ((struct iomem_region) { .next           = iomem_regions,
8180 +                                       .driver         = driver,
8181 +                                       .fd             = fd,
8182 +                                       .size           = buf.ust_size,
8183 +                                       .phys           = 0,
8184 +                                       .virt           = 0 });
8185 +       iomem_regions = new;
8186 +       iomem_size += new->size + UM_KERN_PAGE_SIZE;
8187 +
8188         return(0);
8189 + out_close:
8190 +       os_close_file(fd);
8191 + out:
8192 +       return(1);
8193  }
8194  
8195  __uml_setup("iomem=", parse_iomem,
8196 @@ -153,73 +192,20 @@
8197  "    Configure <file> as an IO memory region named <name>.\n\n"
8198  );
8199  
8200 -#ifdef notdef
8201 -int logging = 0;
8202 -int logging_fd = -1;
8203 -
8204 -int logging_line = 0;
8205 -char logging_buf[256];
8206 -
8207 -void log(char *fmt, ...)
8208 -{
8209 -       va_list ap;
8210 -       struct timeval tv;
8211 -       struct openflags flags;
8212 -
8213 -       if(logging == 0) return;
8214 -       if(logging_fd < 0){
8215 -               flags = of_create(of_trunc(of_rdrw(OPENFLAGS())));
8216 -               logging_fd = os_open_file("log", flags, 0644);
8217 -       }
8218 -       gettimeofday(&tv, NULL);
8219 -       sprintf(logging_buf, "%d\t %u.%u  ", logging_line++, tv.tv_sec, 
8220 -               tv.tv_usec);
8221 -       va_start(ap, fmt);
8222 -       vsprintf(&logging_buf[strlen(logging_buf)], fmt, ap);
8223 -       va_end(ap);
8224 -       write(logging_fd, logging_buf, strlen(logging_buf));
8225 -}
8226 -#endif
8227 -
8228 -int map_memory(unsigned long virt, unsigned long phys, unsigned long len, 
8229 -              int r, int w, int x)
8230 -{
8231 -       struct mem_region *region = phys_region(phys);
8232 -
8233 -       return(os_map_memory((void *) virt, region->fd, phys_offset(phys), len,
8234 -                            r, w, x));
8235 -}
8236 -
8237  int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
8238                    int must_succeed)
8239  {
8240 -       if(os_protect_memory((void *) addr, len, r, w, x) < 0){
8241 +       int err;
8242 +
8243 +       err = os_protect_memory((void *) addr, len, r, w, x);
8244 +       if(err < 0){
8245                  if(must_succeed)
8246 -                        panic("protect failed, errno = %d", errno);
8247 -                else return(-errno);
8248 +                       panic("protect failed, err = %d", -err);
8249 +               else return(err);
8250         }
8251         return(0);
8252  }
8253  
8254 -unsigned long find_iomem(char *driver, unsigned long *len_out)
8255 -{
8256 -       struct mem_region *region;
8257 -       int i, n;
8258 -
8259 -       n = nregions();
8260 -       for(i = 0; i < n; i++){
8261 -               region = regions[i];
8262 -               if(region == NULL) continue;
8263 -               if((region->driver != NULL) &&
8264 -                  !strcmp(region->driver, driver)){
8265 -                       *len_out = region->len;
8266 -                       return(region->start);
8267 -               }
8268 -       }
8269 -       *len_out = 0;
8270 -       return 0;
8271 -}
8272 -
8273  /*
8274   * Overrides for Emacs so that we follow Linus's tabbing style.
8275   * Emacs will notice this stuff at the end of the file and automatically
8276 diff -Naur a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
8277 --- a/arch/um/kernel/physmem.c  1969-12-31 19:00:00.000000000 -0500
8278 +++ b/arch/um/kernel/physmem.c  2004-01-08 22:20:43.000000000 -0500
8279 @@ -0,0 +1,349 @@
8280 +/* 
8281 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
8282 + * Licensed under the GPL
8283 + */
8284 +
8285 +#include "linux/mm.h"
8286 +#include "linux/ghash.h"
8287 +#include "linux/slab.h"
8288 +#include "linux/vmalloc.h"
8289 +#include "linux/bootmem.h"
8290 +#include "asm/types.h"
8291 +#include "asm/pgtable.h"
8292 +#include "kern_util.h"
8293 +#include "user_util.h"
8294 +#include "mode_kern.h"
8295 +#include "mem.h"
8296 +#include "mem_user.h"
8297 +#include "os.h"
8298 +#include "kern.h"
8299 +#include "init.h"
8300 +
8301 +#define PHYS_HASHSIZE (8192)
8302 +
8303 +struct phys_desc;
8304 +
8305 +DEF_HASH_STRUCTS(virtmem, PHYS_HASHSIZE, struct phys_desc);
8306 +
8307 +struct phys_desc {
8308 +       struct virtmem_ptrs virt_ptrs;
8309 +       int fd;
8310 +       __u64 offset;
8311 +       void *virt;
8312 +       unsigned long phys;
8313 +};
8314 +
8315 +struct virtmem_table virtmem_hash;
8316 +
8317 +static int virt_cmp(void *virt1, void *virt2)
8318 +{
8319 +       return(virt1 != virt2);
8320 +}
8321 +
8322 +static int virt_hash(void *virt)
8323 +{
8324 +       unsigned long addr = ((unsigned long) virt) >> PAGE_SHIFT;
8325 +       return(addr % PHYS_HASHSIZE);
8326 +}
8327 +
8328 +DEF_HASH(static, virtmem, struct phys_desc, virt_ptrs, void *, virt, virt_cmp, 
8329 +        virt_hash);
8330 +
8331 +int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w)
8332 +{
8333 +       struct phys_desc *desc;
8334 +       unsigned long phys;
8335 +       int err;
8336 +
8337 +       virt = (void *) ((unsigned long) virt & PAGE_MASK);
8338 +       err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0);
8339 +       if(err)
8340 +               goto out;
8341 +
8342 +       phys = __pa(virt);
8343 +       if(find_virtmem_hash(&virtmem_hash, virt) != NULL)
8344 +               panic("Address 0x%p is already substituted\n", virt);
8345 +
8346 +       err = -ENOMEM;
8347 +       desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
8348 +       if(desc == NULL)
8349 +               goto out;
8350 +
8351 +       *desc = ((struct phys_desc) { .virt_ptrs =      { NULL, NULL },
8352 +                                     .fd =             fd,
8353 +                                     .offset =         offset,
8354 +                                     .virt =           virt,
8355 +                                     .phys =           __pa(virt) });
8356 +       insert_virtmem_hash(&virtmem_hash, desc);
8357 +       err = 0;
8358 + out:
8359 +       return(err);
8360 +}
8361 +
8362 +static int physmem_fd = -1;
8363 +
8364 +int physmem_remove_mapping(void *virt)
8365 +{
8366 +       struct phys_desc *desc;
8367 +       int err;
8368 +
8369 +       virt = (void *) ((unsigned long) virt & PAGE_MASK);
8370 +       desc = find_virtmem_hash(&virtmem_hash, virt);
8371 +       if(desc == NULL)
8372 +               return(0);
8373 +
8374 +       remove_virtmem_hash(&virtmem_hash, desc);
8375 +       kfree(desc);
8376 +
8377 +       err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0);
8378 +       if(err)
8379 +               panic("Failed to unmap block device page from physical memory, "
8380 +                     "errno = %d", -err);
8381 +       return(1);
8382 +}
8383 +
8384 +void arch_free_page(struct page *page, int order)
8385 +{
8386 +       void *virt;
8387 +       int i;
8388 +
8389 +       for(i = 0; i < 1 << order; i++){
8390 +               virt = __va(page_to_phys(page + i));
8391 +               physmem_remove_mapping(virt);
8392 +       }
8393 +}
8394 +
8395 +int is_remapped(void *virt)
8396 +{
8397 +       return(find_virtmem_hash(&virtmem_hash, virt) != NULL);
8398 +}
8399 +
8400 +/* Changed during early boot */
8401 +unsigned long high_physmem;
8402 +
8403 +extern unsigned long physmem_size;
8404 +
8405 +void *to_virt(unsigned long phys)
8406 +{
8407 +       return((void *) uml_physmem + phys);
8408 +}
8409 +
8410 +unsigned long to_phys(void *virt)
8411 +{
8412 +       return(((unsigned long) virt) - uml_physmem);
8413 +}
8414 +
8415 +int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem)
8416 +{
8417 +       struct page *p, *map;
8418 +       unsigned long phys_len, phys_pages, highmem_len, highmem_pages;
8419 +       unsigned long iomem_len, iomem_pages, total_len, total_pages;
8420 +       int i;
8421 +
8422 +       phys_pages = physmem >> PAGE_SHIFT;
8423 +       phys_len = phys_pages * sizeof(struct page);
8424 +
8425 +       iomem_pages = iomem >> PAGE_SHIFT;
8426 +       iomem_len = iomem_pages * sizeof(struct page);
8427 +
8428 +       highmem_pages = highmem >> PAGE_SHIFT;
8429 +       highmem_len = highmem_pages * sizeof(struct page);
8430 +
8431 +       total_pages = phys_pages + iomem_pages + highmem_pages;
8432 +       total_len = phys_len + iomem_pages + highmem_len;
8433 +
8434 +       if(kmalloc_ok){
8435 +               map = kmalloc(total_len, GFP_KERNEL);
8436 +               if(map == NULL) 
8437 +                       map = vmalloc(total_len);
8438 +       }
8439 +       else map = alloc_bootmem_low_pages(total_len);
8440 +
8441 +       if(map == NULL)
8442 +               return(-ENOMEM);
8443 +
8444 +       for(i = 0; i < total_pages; i++){
8445 +               p = &map[i];
8446 +               set_page_count(p, 0);
8447 +               SetPageReserved(p);
8448 +               INIT_LIST_HEAD(&p->list);
8449 +       }
8450 +
8451 +       mem_map = map;
8452 +       max_mapnr = total_pages;
8453 +       return(0);
8454 +}
8455 +
8456 +struct page *phys_to_page(const unsigned long phys)
8457 +{
8458 +       return(&mem_map[phys >> PAGE_SHIFT]);
8459 +}
8460 +
8461 +struct page *__virt_to_page(const unsigned long virt)
8462 +{
8463 +       return(&mem_map[__pa(virt) >> PAGE_SHIFT]);
8464 +}
8465 +
8466 +unsigned long page_to_phys(struct page *page)
8467 +{
8468 +       return((page - mem_map) << PAGE_SHIFT);
8469 +}
8470 +
8471 +pte_t mk_pte(struct page *page, pgprot_t pgprot)
8472 +{
8473 +       pte_t pte;
8474 +
8475 +       pte_val(pte) = page_to_phys(page) + pgprot_val(pgprot);
8476 +       if(pte_present(pte)) pte_mknewprot(pte_mknewpage(pte));
8477 +       return(pte);
8478 +}
8479 +
8480 +/* Changed during early boot */
8481 +static unsigned long kmem_top = 0;
8482 +
8483 +unsigned long get_kmem_end(void)
8484 +{
8485 +       if(kmem_top == 0) 
8486 +               kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
8487 +       return(kmem_top);
8488 +}
8489 +
8490 +void map_memory(unsigned long virt, unsigned long phys, unsigned long len, 
8491 +               int r, int w, int x)
8492 +{
8493 +       __u64 offset;
8494 +       int fd, err;
8495 +
8496 +       fd = phys_mapping(phys, &offset);
8497 +       err = os_map_memory((void *) virt, fd, offset, len, r, w, x);
8498 +       if(err)
8499 +               panic("map_memory(0x%lx, %d, 0x%llx, %ld, %d, %d, %d) failed, "
8500 +                     "err = %d\n", virt, fd, offset, len, r, w, x, err);
8501 +}
8502 +
8503 +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
8504 +
8505 +void setup_physmem(unsigned long start, unsigned long reserve_end,
8506 +                  unsigned long len, unsigned long highmem)
8507 +{
8508 +       unsigned long reserve = reserve_end - start;
8509 +       int pfn = PFN_UP(__pa(reserve_end));
8510 +       int delta = (len - reserve) >> PAGE_SHIFT;
8511 +       int err, offset, bootmap_size;
8512 +
8513 +       physmem_fd = create_mem_file(len + highmem);
8514 +
8515 +       offset = uml_reserved - uml_physmem;
8516 +       err = os_map_memory((void *) uml_reserved, physmem_fd, offset, 
8517 +                           len - offset, 1, 1, 0);
8518 +       if(err < 0){
8519 +               os_print_error(err, "Mapping memory");
8520 +               exit(1);
8521 +       }
8522 +
8523 +       bootmap_size = init_bootmem(pfn, pfn + delta);
8524 +       free_bootmem(__pa(reserve_end) + bootmap_size,
8525 +                    len - bootmap_size - reserve);
8526 +}
8527 +
8528 +int phys_mapping(unsigned long phys, __u64 *offset_out)
8529 +{
8530 +       struct phys_desc *desc = find_virtmem_hash(&virtmem_hash, 
8531 +                                                  __va(phys & PAGE_MASK));
8532 +       int fd = -1;
8533 +
8534 +       if(desc != NULL){
8535 +               fd = desc->fd;
8536 +               *offset_out = desc->offset;
8537 +       }
8538 +       else if(phys < physmem_size){
8539 +               fd = physmem_fd;
8540 +               *offset_out = phys;
8541 +       }
8542 +       else if(phys < __pa(end_iomem)){
8543 +               struct iomem_region *region = iomem_regions;
8544 +       
8545 +               while(region != NULL){
8546 +                       if((phys >= region->phys) && 
8547 +                          (phys < region->phys + region->size)){
8548 +                               fd = region->fd;
8549 +                               *offset_out = phys - region->phys;
8550 +                               break;
8551 +                       }
8552 +                       region = region->next;
8553 +               }
8554 +       }
8555 +       else if(phys < __pa(end_iomem) + highmem){
8556 +               fd = physmem_fd;
8557 +               *offset_out = phys - iomem_size;
8558 +       }
8559 +
8560 +       return(fd);
8561 +}
8562 +
8563 +static int __init uml_mem_setup(char *line, int *add)
8564 +{
8565 +       char *retptr;
8566 +       physmem_size = memparse(line,&retptr);
8567 +       return 0;
8568 +}
8569 +__uml_setup("mem=", uml_mem_setup,
8570 +"mem=<Amount of desired ram>\n"
8571 +"    This controls how much \"physical\" memory the kernel allocates\n"
8572 +"    for the system. The size is specified as a number followed by\n"
8573 +"    one of 'k', 'K', 'm', 'M', which have the obvious meanings.\n"
8574 +"    This is not related to the amount of memory in the host.  It can\n"
8575 +"    be more, and the excess, if it's ever used, will just be swapped out.\n"
8576 +"      Example: mem=64M\n\n"
8577 +);
8578 +
8579 +unsigned long find_iomem(char *driver, unsigned long *len_out)
8580 +{
8581 +       struct iomem_region *region = iomem_regions;
8582 +       
8583 +       while(region != NULL){
8584 +               if(!strcmp(region->driver, driver)){
8585 +                       *len_out = region->size;
8586 +                       return(region->virt);
8587 +               }
8588 +       }
8589 +
8590 +       return(0);
8591 +}
8592 +
8593 +int setup_iomem(void)
8594 +{
8595 +       struct iomem_region *region = iomem_regions;
8596 +       unsigned long iomem_start = high_physmem + PAGE_SIZE;
8597 +       int err;
8598 +
8599 +       while(region != NULL){
8600 +               err = os_map_memory((void *) iomem_start, region->fd, 0, 
8601 +                                   region->size, 1, 1, 0);
8602 +               if(err)
8603 +                       printk("Mapping iomem region for driver '%s' failed, "
8604 +                              "errno = %d\n", region->driver, -err);
8605 +               else {
8606 +                       region->virt = iomem_start;
8607 +                       region->phys = __pa(region->virt);
8608 +               }
8609 +
8610 +               iomem_start += region->size + PAGE_SIZE;
8611 +               region = region->next;
8612 +       }
8613 +
8614 +       return(0);
8615 +}
8616 +
8617 +__initcall(setup_iomem);
8618 +
8619 +/*
8620 + * Overrides for Emacs so that we follow Linus's tabbing style.
8621 + * Emacs will notice this stuff at the end of the file and automatically
8622 + * adjust the settings for this buffer only.  This must remain at the end
8623 + * of the file.
8624 + * ---------------------------------------------------------------------------
8625 + * Local variables:
8626 + * c-file-style: "linux"
8627 + * End:
8628 + */
8629 diff -Naur a/arch/um/kernel/process.c b/arch/um/kernel/process.c
8630 --- a/arch/um/kernel/process.c  2004-01-08 22:29:24.000000000 -0500
8631 +++ b/arch/um/kernel/process.c  2004-01-08 22:35:08.000000000 -0500
8632 @@ -9,12 +9,10 @@
8633  #include <sched.h>
8634  #include <errno.h>
8635  #include <stdarg.h>
8636 -#include <fcntl.h>
8637  #include <stdlib.h>
8638  #include <setjmp.h>
8639  #include <sys/time.h>
8640  #include <sys/ptrace.h>
8641 -#include <sys/ioctl.h>
8642  #include <sys/wait.h>
8643  #include <sys/mman.h>
8644  #include <asm/ptrace.h>
8645 @@ -58,7 +56,11 @@
8646  {
8647         int flags = altstack ? SA_ONSTACK : 0;
8648  
8649 -       set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags,
8650 +       /* NODEFER is set here because SEGV isn't turned back on when the 
8651 +        * handler is ready to receive signals.  This causes any segfault
8652 +        * during a copy_user to kill the process because the fault is blocked.
8653 +        */
8654 +       set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags | SA_NODEFER,
8655                     SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
8656         set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags, 
8657                     SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
8658 @@ -72,7 +74,6 @@
8659                     SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
8660         set_handler(SIGUSR2, (__sighandler_t) sig_handler, 
8661                     SA_NOMASK | flags, -1);
8662 -       (void) CHOOSE_MODE(signal(SIGCHLD, SIG_IGN), (void *) 0);
8663         signal(SIGHUP, SIG_IGN);
8664  
8665         init_irq_signals(altstack);
8666 @@ -123,11 +124,12 @@
8667         /* Start the process and wait for it to kill itself */
8668         new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg);
8669         if(new_pid < 0) return(-errno);
8670 -       while((err = waitpid(new_pid, &status, 0) < 0) && (errno == EINTR)) ;
8671 +       while(((err = waitpid(new_pid, &status, 0)) < 0) && (errno == EINTR)) ;
8672         if(err < 0) panic("Waiting for outer trampoline failed - errno = %d", 
8673                           errno);
8674         if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
8675 -               panic("outer trampoline didn't exit with SIGKILL");
8676 +               panic("outer trampoline didn't exit with SIGKILL, "
8677 +                     "status = %d", status);
8678  
8679         return(arg.pid);
8680  }
8681 @@ -138,7 +140,7 @@
8682  
8683         os_stop_process(os_getpid());
8684  
8685 -       if(read(fd, &c, sizeof(c)) != sizeof(c))
8686 +       if(os_read_file(fd, &c, sizeof(c)) != sizeof(c))
8687                 panic("read failed in suspend_new_thread");
8688  }
8689  
8690 @@ -233,7 +235,7 @@
8691         int n;
8692  
8693         *jmp_ptr = &buf;
8694 -       n = setjmp(buf);
8695 +       n = sigsetjmp(buf, 1);
8696         if(n != 0)
8697                 return(n);
8698         (*fn)(arg);
8699 @@ -273,7 +275,7 @@
8700         stop_ptraced_child(pid, stack, 1);
8701  
8702         printf("Checking for /proc/mm...");
8703 -       if(access("/proc/mm", W_OK)){
8704 +       if(os_access("/proc/mm", OS_ACC_W_OK) < 0){
8705                 printf("not found\n");
8706                 ret = 0;
8707         }
8708 diff -Naur a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
8709 --- a/arch/um/kernel/process_kern.c     2004-01-08 22:21:59.000000000 -0500
8710 +++ b/arch/um/kernel/process_kern.c     2004-01-08 22:28:53.000000000 -0500
8711 @@ -16,6 +16,7 @@
8712  #include "linux/module.h"
8713  #include "linux/init.h"
8714  #include "linux/capability.h"
8715 +#include "linux/spinlock.h"
8716  #include "asm/unistd.h"
8717  #include "asm/mman.h"
8718  #include "asm/segment.h"
8719 @@ -23,7 +24,6 @@
8720  #include "asm/pgtable.h"
8721  #include "asm/processor.h"
8722  #include "asm/tlbflush.h"
8723 -#include "asm/spinlock.h"
8724  #include "asm/uaccess.h"
8725  #include "asm/user.h"
8726  #include "user_util.h"
8727 @@ -52,17 +52,12 @@
8728  
8729  struct task_struct *get_task(int pid, int require)
8730  {
8731 -        struct task_struct *task, *ret;
8732 +        struct task_struct *ret;
8733  
8734 -        ret = NULL;
8735          read_lock(&tasklist_lock);
8736 -        for_each_process(task){
8737 -                if(task->pid == pid){
8738 -                        ret = task;
8739 -                        break;
8740 -                }
8741 -        }
8742 +       ret = find_task_by_pid(pid);
8743          read_unlock(&tasklist_lock);
8744 +
8745          if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
8746          return(ret);
8747  }
8748 @@ -95,7 +90,8 @@
8749         int flags = GFP_KERNEL;
8750  
8751         if(atomic) flags |= GFP_ATOMIC;
8752 -       if((page = __get_free_pages(flags, order)) == 0)
8753 +       page = __get_free_pages(flags, order);
8754 +       if(page == 0)
8755                 return(0);
8756         stack_protections(page);
8757         return(page);
8758 @@ -103,13 +99,15 @@
8759  
8760  int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
8761  {
8762 -       struct task_struct *p;
8763 +       int pid;
8764  
8765         current->thread.request.u.thread.proc = fn;
8766         current->thread.request.u.thread.arg = arg;
8767 -       p = do_fork(CLONE_VM | flags, 0, NULL, 0, NULL, NULL);
8768 -       if(IS_ERR(p)) panic("do_fork failed in kernel_thread");
8769 -       return(p->pid);
8770 +       pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, NULL, 0, NULL, 
8771 +                     NULL);
8772 +       if(pid < 0)
8773 +               panic("do_fork failed in kernel_thread, errno = %d", pid);
8774 +       return(pid);
8775  }
8776  
8777  void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
8778 @@ -129,7 +127,7 @@
8779                 { external_pid(task), task });
8780  }
8781  
8782 -void *switch_to(void *prev, void *next, void *last)
8783 +void *_switch_to(void *prev, void *next, void *last)
8784  {
8785         return(CHOOSE_MODE(switch_to_tt(prev, next), 
8786                            switch_to_skas(prev, next)));
8787 @@ -149,7 +147,7 @@
8788  void exit_thread(void)
8789  {
8790         CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
8791 -       unprotect_stack((unsigned long) current->thread_info);
8792 +       unprotect_stack((unsigned long) current_thread);
8793  }
8794   
8795  void *get_current(void)
8796 @@ -157,6 +155,10 @@
8797         return(current);
8798  }
8799  
8800 +void prepare_to_copy(struct task_struct *tsk)
8801 +{
8802 +}
8803 +
8804  int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
8805                 unsigned long stack_top, struct task_struct * p, 
8806                 struct pt_regs *regs)
8807 @@ -190,7 +192,7 @@
8808  
8809  void default_idle(void)
8810  {
8811 -       idle_timer();
8812 +       uml_idle_timer();
8813  
8814         atomic_inc(&init_mm.mm_count);
8815         current->mm = &init_mm;
8816 @@ -367,10 +369,15 @@
8817         return(clear_user(buf, size));
8818  }
8819  
8820 +int strlen_user_proc(char *str)
8821 +{
8822 +       return(strlen_user(str));
8823 +}
8824 +
8825  int smp_sigio_handler(void)
8826  {
8827  #ifdef CONFIG_SMP
8828 -       int cpu = current->thread_info->cpu;
8829 +       int cpu = current_thread->cpu;
8830         IPI_handler(cpu);
8831         if(cpu != 0)
8832                 return(1);
8833 @@ -385,7 +392,7 @@
8834  
8835  int cpu(void)
8836  {
8837 -       return(current->thread_info->cpu);
8838 +       return(current_thread->cpu);
8839  }
8840  
8841  /*
8842 diff -Naur a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
8843 --- a/arch/um/kernel/ptrace.c   2004-01-08 22:15:02.000000000 -0500
8844 +++ b/arch/um/kernel/ptrace.c   2004-01-08 22:20:32.000000000 -0500
8845 @@ -311,11 +311,8 @@
8846  
8847         /* the 0x80 provides a way for the tracing parent to distinguish
8848            between a syscall stop and SIGTRAP delivery */
8849 -       current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
8850 -                                       ? 0x80 : 0);
8851 -       current->state = TASK_STOPPED;
8852 -       notify_parent(current, SIGCHLD);
8853 -       schedule();
8854 +       ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
8855 +                                ? 0x80 : 0));
8856  
8857         /*
8858          * this isn't the same as continuing with a signal, but it will do
8859 diff -Naur a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
8860 --- a/arch/um/kernel/reboot.c   2004-01-08 22:21:48.000000000 -0500
8861 +++ b/arch/um/kernel/reboot.c   2004-01-08 22:28:40.000000000 -0500
8862 @@ -15,6 +15,7 @@
8863  #ifdef CONFIG_SMP
8864  static void kill_idlers(int me)
8865  {
8866 +#ifdef CONFIG_MODE_TT
8867         struct task_struct *p;
8868         int i;
8869  
8870 @@ -23,6 +24,7 @@
8871                 if((p != NULL) && (p->thread.mode.tt.extern_pid != me))
8872                         os_kill_process(p->thread.mode.tt.extern_pid, 0);
8873         }
8874 +#endif
8875  }
8876  #endif
8877  
8878 diff -Naur a/arch/um/kernel/sigio_kern.c b/arch/um/kernel/sigio_kern.c
8879 --- a/arch/um/kernel/sigio_kern.c       2004-01-08 22:16:51.000000000 -0500
8880 +++ b/arch/um/kernel/sigio_kern.c       2004-01-08 22:22:53.000000000 -0500
8881 @@ -6,18 +6,21 @@
8882  #include "linux/kernel.h"
8883  #include "linux/list.h"
8884  #include "linux/slab.h"
8885 -#include "asm/irq.h"
8886 +#include "linux/signal.h"
8887 +#include "linux/interrupt.h"
8888  #include "init.h"
8889  #include "sigio.h"
8890  #include "irq_user.h"
8891 +#include "irq_kern.h"
8892  
8893  /* Protected by sigio_lock() called from write_sigio_workaround */
8894  static int sigio_irq_fd = -1;
8895  
8896 -void sigio_interrupt(int irq, void *data, struct pt_regs *unused)
8897 +irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused)
8898  {
8899         read_sigio_fd(sigio_irq_fd);
8900         reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
8901 +       return(IRQ_HANDLED);
8902  }
8903  
8904  int write_sigio_irq(int fd)
8905 diff -Naur a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
8906 --- a/arch/um/kernel/sigio_user.c       2004-01-08 22:31:33.000000000 -0500
8907 +++ b/arch/um/kernel/sigio_user.c       2004-01-08 22:36:15.000000000 -0500
8908 @@ -7,7 +7,6 @@
8909  #include <stdlib.h>
8910  #include <termios.h>
8911  #include <pty.h>
8912 -#include <fcntl.h>
8913  #include <signal.h>
8914  #include <errno.h>
8915  #include <string.h>
8916 @@ -26,7 +25,7 @@
8917  int pty_close_sigio = 0;
8918  
8919  /* Used as a flag during SIGIO testing early in boot */
8920 -static int got_sigio = 0;
8921 +static volatile int got_sigio = 0;
8922  
8923  void __init handler(int sig)
8924  {
8925 @@ -45,7 +44,7 @@
8926  
8927         info->err = 0;
8928         if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
8929 -               info->err = errno;
8930 +               info->err = -errno;
8931  }
8932  
8933  void __init check_one_sigio(void (*proc)(int, int))
8934 @@ -53,11 +52,11 @@
8935         struct sigaction old, new;
8936         struct termios tt;
8937         struct openpty_arg pty = { .master = -1, .slave = -1 };
8938 -       int master, slave, flags;
8939 +       int master, slave, err;
8940  
8941         initial_thread_cb(openpty_cb, &pty);
8942         if(pty.err){
8943 -               printk("openpty failed, errno = %d\n", pty.err);
8944 +               printk("openpty failed, errno = %d\n", -pty.err);
8945                 return;
8946         }
8947  
8948 @@ -69,23 +68,16 @@
8949                 return;
8950         }
8951  
8952 +       /* XXX These can fail with EINTR */
8953         if(tcgetattr(master, &tt) < 0)
8954                 panic("check_sigio : tcgetattr failed, errno = %d\n", errno);
8955         cfmakeraw(&tt);
8956         if(tcsetattr(master, TCSADRAIN, &tt) < 0)
8957                 panic("check_sigio : tcsetattr failed, errno = %d\n", errno);
8958  
8959 -       if((flags = fcntl(master, F_GETFL)) < 0)
8960 -               panic("tty_fds : fcntl F_GETFL failed, errno = %d\n", errno);
8961 -
8962 -       if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
8963 -          (fcntl(master, F_SETOWN, os_getpid()) < 0))
8964 -               panic("check_sigio : fcntl F_SETFL or F_SETOWN failed, "
8965 -                     "errno = %d\n", errno);
8966 -
8967 -       if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
8968 -               panic("check_sigio : fcntl F_SETFL failed, errno = %d\n", 
8969 -                     errno);
8970 +       err = os_sigio_async(master, slave);
8971 +       if(err < 0)
8972 +               panic("tty_fds : sigio_async failed, err = %d\n", -err);
8973  
8974         if(sigaction(SIGIO, NULL, &old) < 0)
8975                 panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
8976 @@ -97,8 +89,8 @@
8977         got_sigio = 0;
8978         (*proc)(master, slave);
8979                 
8980 -       close(master);
8981 -       close(slave);
8982 +       os_close_file(master);
8983 +       os_close_file(slave);
8984  
8985         if(sigaction(SIGIO, &old, NULL) < 0)
8986                 panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
8987 @@ -112,25 +104,25 @@
8988         printk("Checking that host ptys support output SIGIO...");
8989  
8990         memset(buf, 0, sizeof(buf));
8991 -       while(write(master, buf, sizeof(buf)) > 0) ;
8992 +
8993 +       while(os_write_file(master, buf, sizeof(buf)) > 0) ;
8994         if(errno != EAGAIN)
8995                 panic("check_sigio : write failed, errno = %d\n", errno);
8996 -
8997 -       while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
8998 +       while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
8999  
9000         if(got_sigio){
9001                 printk("Yes\n");
9002                 pty_output_sigio = 1;
9003         }
9004 -       else if(errno == EAGAIN) printk("No, enabling workaround\n");
9005 -       else panic("check_sigio : read failed, errno = %d\n", errno);
9006 +       else if(n == -EAGAIN) printk("No, enabling workaround\n");
9007 +       else panic("check_sigio : read failed, err = %d\n", n);
9008  }
9009  
9010  static void tty_close(int master, int slave)
9011  {
9012         printk("Checking that host ptys support SIGIO on close...");
9013  
9014 -       close(slave);
9015 +       os_close_file(slave);
9016         if(got_sigio){
9017                 printk("Yes\n");
9018                 pty_close_sigio = 1;
9019 @@ -140,7 +132,8 @@
9020  
9021  void __init check_sigio(void)
9022  {
9023 -       if(access("/dev/ptmx", R_OK) && access("/dev/ptyp0", R_OK)){
9024 +       if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
9025 +          (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
9026                 printk("No pseudo-terminals available - skipping pty SIGIO "
9027                        "check\n");
9028                 return;
9029 @@ -201,11 +194,10 @@
9030                         p = &fds->poll[i];
9031                         if(p->revents == 0) continue;
9032                         if(p->fd == sigio_private[1]){
9033 -                               n = read(sigio_private[1], &c, sizeof(c));
9034 +                               n = os_read_file(sigio_private[1], &c, sizeof(c));
9035                                 if(n != sizeof(c))
9036                                         printk("write_sigio_thread : "
9037 -                                              "read failed, errno = %d\n",
9038 -                                              errno);
9039 +                                              "read failed, err = %d\n", -n);
9040                                 tmp = current_poll;
9041                                 current_poll = next_poll;
9042                                 next_poll = tmp;
9043 @@ -218,10 +210,10 @@
9044                                         (fds->used - i) * sizeof(*fds->poll));
9045                         }
9046  
9047 -                       n = write(respond_fd, &c, sizeof(c));
9048 +                       n = os_write_file(respond_fd, &c, sizeof(c));
9049                         if(n != sizeof(c))
9050                                 printk("write_sigio_thread : write failed, "
9051 -                                      "errno = %d\n", errno);
9052 +                                      "err = %d\n", -n);
9053                 }
9054         }
9055  }
9056 @@ -252,15 +244,15 @@
9057         char c;
9058  
9059         flags = set_signals(0);
9060 -       n = write(sigio_private[0], &c, sizeof(c));
9061 +       n = os_write_file(sigio_private[0], &c, sizeof(c));
9062         if(n != sizeof(c)){
9063 -               printk("update_thread : write failed, errno = %d\n", errno);
9064 +               printk("update_thread : write failed, err = %d\n", -n);
9065                 goto fail;
9066         }
9067  
9068 -       n = read(sigio_private[0], &c, sizeof(c));
9069 +       n = os_read_file(sigio_private[0], &c, sizeof(c));
9070         if(n != sizeof(c)){
9071 -               printk("update_thread : read failed, errno = %d\n", errno);
9072 +               printk("update_thread : read failed, err = %d\n", -n);
9073                 goto fail;
9074         }
9075  
9076 @@ -271,10 +263,10 @@
9077         if(write_sigio_pid != -1) 
9078                 os_kill_process(write_sigio_pid, 1);
9079         write_sigio_pid = -1;
9080 -       close(sigio_private[0]);
9081 -       close(sigio_private[1]);        
9082 -       close(write_sigio_fds[0]);
9083 -       close(write_sigio_fds[1]);
9084 +       os_close_file(sigio_private[0]);
9085 +       os_close_file(sigio_private[1]);        
9086 +       os_close_file(write_sigio_fds[0]);
9087 +       os_close_file(write_sigio_fds[1]);
9088         sigio_unlock();
9089         set_signals(flags);
9090  }
9091 @@ -369,15 +361,15 @@
9092                 goto out;
9093  
9094         err = os_pipe(write_sigio_fds, 1, 1);
9095 -       if(err){
9096 +       if(err < 0){
9097                 printk("write_sigio_workaround - os_pipe 1 failed, "
9098 -                      "errno = %d\n", -err);
9099 +                      "err = %d\n", -err);
9100                 goto out;
9101         }
9102         err = os_pipe(sigio_private, 1, 1);
9103 -       if(err){
9104 +       if(err < 0){
9105                 printk("write_sigio_workaround - os_pipe 2 failed, "
9106 -                      "errno = %d\n", -err);
9107 +                      "err = %d\n", -err);
9108                 goto out_close1;
9109         }
9110         if(setup_initial_poll(sigio_private[1]))
9111 @@ -399,11 +391,11 @@
9112         os_kill_process(write_sigio_pid, 1);
9113         write_sigio_pid = -1;
9114   out_close2:
9115 -       close(sigio_private[0]);
9116 -       close(sigio_private[1]);        
9117 +       os_close_file(sigio_private[0]);
9118 +       os_close_file(sigio_private[1]);        
9119   out_close1:
9120 -       close(write_sigio_fds[0]);
9121 -       close(write_sigio_fds[1]);
9122 +       os_close_file(write_sigio_fds[0]);
9123 +       os_close_file(write_sigio_fds[1]);
9124         sigio_unlock();
9125  }
9126  
9127 @@ -412,10 +404,16 @@
9128         int n;
9129         char c;
9130  
9131 -       n = read(fd, &c, sizeof(c));
9132 +       n = os_read_file(fd, &c, sizeof(c));
9133         if(n != sizeof(c)){
9134 -               printk("read_sigio_fd - read failed, errno = %d\n", errno);
9135 -               return(-errno);
9136 +               if(n < 0) {
9137 +                       printk("read_sigio_fd - read failed, err = %d\n", -n);
9138 +                       return(n);
9139 +               } 
9140 +               else { 
9141 +                       printk("read_sigio_fd - short read, bytes = %d\n", n);
9142 +                       return(-EIO);
9143 +               }
9144         }
9145         return(n);
9146  }
9147 diff -Naur a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c
9148 --- a/arch/um/kernel/signal_kern.c      2004-01-08 22:22:59.000000000 -0500
9149 +++ b/arch/um/kernel/signal_kern.c      2004-01-08 22:29:59.000000000 -0500
9150 @@ -36,7 +36,7 @@
9151         if(sig == SIGSEGV){
9152                 struct k_sigaction *ka;
9153  
9154 -               ka = &current->sig->action[SIGSEGV - 1];
9155 +               ka = &current->sighand->action[SIGSEGV - 1];
9156                 ka->sa.sa_handler = SIG_DFL;
9157         }
9158         force_sig(SIGSEGV, current);
9159 @@ -60,10 +60,10 @@
9160         int err, ret;
9161  
9162         ret = 0;
9163 +       /* Always make any pending restarted system calls return -EINTR */
9164 +       current_thread_info()->restart_block.fn = do_no_restart_syscall;
9165         switch(error){
9166         case -ERESTART_RESTARTBLOCK:
9167 -               current_thread_info()->restart_block.fn = 
9168 -                       do_no_restart_syscall;
9169         case -ERESTARTNOHAND:
9170                 ret = -EINTR;
9171                 break;
9172 @@ -142,7 +142,7 @@
9173                 return(0);
9174  
9175         /* Whee!  Actually deliver the signal.  */
9176 -       ka = &current->sig->action[sig -1 ];
9177 +       ka = &current->sighand->action[sig -1 ];
9178         err = handle_signal(regs, sig, ka, &info, oldset, error);
9179         if(!err) return(1);
9180  
9181 @@ -201,7 +201,7 @@
9182         }
9183  }
9184  
9185 -int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
9186 +int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
9187  {
9188         sigset_t saveset, newset;
9189  
9190 @@ -227,20 +227,59 @@
9191         }
9192  }
9193  
9194 +int sys_sigaction(int sig, const struct old_sigaction __user *act,
9195 +                        struct old_sigaction __user *oact)
9196 +{
9197 +       struct k_sigaction new_ka, old_ka;
9198 +       int ret;
9199 +
9200 +       if (act) {
9201 +               old_sigset_t mask;
9202 +               if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
9203 +                   __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
9204 +                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
9205 +                       return -EFAULT;
9206 +               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
9207 +               __get_user(mask, &act->sa_mask);
9208 +               siginitset(&new_ka.sa.sa_mask, mask);
9209 +       }
9210 +
9211 +       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
9212 +
9213 +       if (!ret && oact) {
9214 +               if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
9215 +                   __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
9216 +                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
9217 +                       return -EFAULT;
9218 +               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
9219 +               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
9220 +       }
9221 +
9222 +       return ret;
9223 +}
9224 +
9225 +int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
9226 +{
9227 +       return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
9228 +}
9229 +
9230 +extern int userspace_pid[];
9231 +
9232  static int copy_sc_from_user(struct pt_regs *to, void *from, 
9233                              struct arch_frame_data *arch)
9234  {
9235         int ret;
9236  
9237         ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, arch),
9238 -                         copy_sc_from_user_skas(&to->regs, from));
9239 +                         copy_sc_from_user_skas(userspace_pid[0], 
9240 +                                                &to->regs, from));
9241         return(ret);
9242  }
9243  
9244  int sys_sigreturn(struct pt_regs regs)
9245  {
9246 -       void *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
9247 -       void *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
9248 +       void __user *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
9249 +       void __user *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
9250         int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
9251  
9252         spin_lock_irq(&current->sighand->siglock);
9253 @@ -257,8 +296,8 @@
9254  
9255  int sys_rt_sigreturn(struct pt_regs regs)
9256  {
9257 -       struct ucontext *uc = sp_to_uc(PT_REGS_SP(&current->thread.regs));
9258 -       void *fp;
9259 +       unsigned long sp = PT_REGS_SP(&current->thread.regs);
9260 +       struct ucontext __user *uc = sp_to_uc(sp);
9261         int sig_size = _NSIG_WORDS * sizeof(unsigned long);
9262  
9263         spin_lock_irq(&current->sighand->siglock);
9264 @@ -266,7 +305,6 @@
9265         sigdelsetmask(&current->blocked, ~_BLOCKABLE);
9266         recalc_sigpending();
9267         spin_unlock_irq(&current->sighand->siglock);
9268 -       fp = (void *) (((unsigned long) uc) + sizeof(struct ucontext));
9269         copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext,
9270                           &signal_frame_si.common.arch);
9271         return(PT_REGS_SYSCALL_RET(&current->thread.regs));
9272 diff -Naur a/arch/um/kernel/skas/include/mode.h b/arch/um/kernel/skas/include/mode.h
9273 --- a/arch/um/kernel/skas/include/mode.h        2004-01-08 22:22:40.000000000 -0500
9274 +++ b/arch/um/kernel/skas/include/mode.h        2004-01-08 22:29:35.000000000 -0500
9275 @@ -12,14 +12,16 @@
9276  extern int have_fpx_regs;
9277  
9278  extern void user_time_init_skas(void);
9279 -extern int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr);
9280 -extern int copy_sc_to_user_skas(void *to_ptr, void *fp, 
9281 +extern int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, 
9282 +                                 void *from_ptr);
9283 +extern int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp, 
9284                                 union uml_pt_regs *regs, 
9285                                 unsigned long fault_addr, int fault_type);
9286  extern void sig_handler_common_skas(int sig, void *sc_ptr);
9287  extern void halt_skas(void);
9288  extern void reboot_skas(void);
9289  extern void kill_off_processes_skas(void);
9290 +extern int is_skas_winch(int pid, int fd, void *data);
9291  
9292  #endif
9293  
9294 diff -Naur a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h
9295 --- a/arch/um/kernel/skas/include/skas.h        2004-01-08 22:17:37.000000000 -0500
9296 +++ b/arch/um/kernel/skas/include/skas.h        2004-01-08 22:23:23.000000000 -0500
9297 @@ -8,7 +8,7 @@
9298  
9299  #include "sysdep/ptrace.h"
9300  
9301 -extern int userspace_pid;
9302 +extern int userspace_pid[];
9303  
9304  extern void switch_threads(void *me, void *next);
9305  extern void thread_wait(void *sw, void *fb);
9306 @@ -32,7 +32,7 @@
9307  extern int new_mm(int from);
9308  extern void save_registers(union uml_pt_regs *regs);
9309  extern void restore_registers(union uml_pt_regs *regs);
9310 -extern void start_userspace(void);
9311 +extern void start_userspace(int cpu);
9312  extern void init_registers(int pid);
9313  
9314  #endif
9315 diff -Naur a/arch/um/kernel/skas/include/uaccess.h b/arch/um/kernel/skas/include/uaccess.h
9316 --- a/arch/um/kernel/skas/include/uaccess.h     2004-01-08 22:20:08.000000000 -0500
9317 +++ b/arch/um/kernel/skas/include/uaccess.h     2004-01-08 22:26:25.000000000 -0500
9318 @@ -6,20 +6,10 @@
9319  #ifndef __SKAS_UACCESS_H
9320  #define __SKAS_UACCESS_H
9321  
9322 -#include "linux/string.h"
9323 -#include "linux/sched.h"
9324 -#include "linux/err.h"
9325 -#include "asm/processor.h"
9326 -#include "asm/pgtable.h"
9327 -#include "asm/errno.h"
9328 -#include "asm/current.h"
9329 -#include "asm/a.out.h"
9330 -#include "kern_util.h"
9331 -
9332  #define access_ok_skas(type, addr, size) \
9333         ((segment_eq(get_fs(), KERNEL_DS)) || \
9334          (((unsigned long) (addr) < TASK_SIZE) && \
9335 -         ((unsigned long) (addr) + (size) < TASK_SIZE)))
9336 +         ((unsigned long) (addr) + (size) <= TASK_SIZE)))
9337  
9338  static inline int verify_area_skas(int type, const void * addr, 
9339                                    unsigned long size)
9340 @@ -27,197 +17,12 @@
9341         return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
9342  }
9343  
9344 -static inline unsigned long maybe_map(unsigned long virt, int is_write)
9345 -{
9346 -       pte_t pte;
9347 -
9348 -       void *phys = um_virt_to_phys(current, virt, &pte);
9349 -       int dummy_code;
9350 -
9351 -       if(IS_ERR(phys) || (is_write && !pte_write(pte))){
9352 -               if(handle_page_fault(virt, 0, is_write, 0, &dummy_code))
9353 -                       return(0);
9354 -               phys = um_virt_to_phys(current, virt, NULL);
9355 -       }
9356 -       return((unsigned long) __va((unsigned long) phys));
9357 -}
9358 -
9359 -static inline int buffer_op(unsigned long addr, int len, 
9360 -                           int (*op)(unsigned long addr, int len, void *arg),
9361 -                           void *arg)
9362 -{
9363 -       int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
9364 -       int remain = len, n;
9365 -
9366 -       n = (*op)(addr, size, arg);
9367 -       if(n != 0)
9368 -               return(n < 0 ? remain : 0);
9369 -
9370 -       addr += size;
9371 -       remain -= size;
9372 -       if(remain == 0) 
9373 -               return(0);
9374 -
9375 -       while(addr < ((addr + remain) & PAGE_MASK)){
9376 -               n = (*op)(addr, PAGE_SIZE, arg);
9377 -               if(n != 0)
9378 -                       return(n < 0 ? remain : 0);
9379 -
9380 -               addr += PAGE_SIZE;
9381 -               remain -= PAGE_SIZE;
9382 -       }
9383 -       if(remain == 0)
9384 -               return(0);
9385 -
9386 -       n = (*op)(addr, remain, arg);
9387 -       if(n != 0)
9388 -               return(n < 0 ? remain : 0);
9389 -       return(0);
9390 -}
9391 -
9392 -static inline int copy_chunk_from_user(unsigned long from, int len, void *arg)
9393 -{
9394 -       unsigned long *to_ptr = arg, to = *to_ptr;
9395 -
9396 -       from = maybe_map(from, 0);
9397 -       if(from == 0)
9398 -               return(-1);
9399 -
9400 -       memcpy((void *) to, (void *) from, len);
9401 -       *to_ptr += len;
9402 -       return(0);
9403 -}
9404 -
9405 -static inline int copy_from_user_skas(void *to, const void *from, int n)
9406 -{
9407 -       if(segment_eq(get_fs(), KERNEL_DS)){
9408 -               memcpy(to, from, n);
9409 -               return(0);
9410 -       }
9411 -
9412 -       return(access_ok_skas(VERIFY_READ, from, n) ?
9413 -              buffer_op((unsigned long) from, n, copy_chunk_from_user, &to) :
9414 -              n);
9415 -}
9416 -
9417 -static inline int copy_chunk_to_user(unsigned long to, int len, void *arg)
9418 -{
9419 -       unsigned long *from_ptr = arg, from = *from_ptr;
9420 -
9421 -       to = maybe_map(to, 1);
9422 -       if(to == 0)
9423 -               return(-1);
9424 -
9425 -       memcpy((void *) to, (void *) from, len);
9426 -       *from_ptr += len;
9427 -       return(0);
9428 -}
9429 -
9430 -static inline int copy_to_user_skas(void *to, const void *from, int n)
9431 -{
9432 -       if(segment_eq(get_fs(), KERNEL_DS)){
9433 -               memcpy(to, from, n);
9434 -               return(0);
9435 -       }
9436 -
9437 -       return(access_ok_skas(VERIFY_WRITE, to, n) ?
9438 -              buffer_op((unsigned long) to, n, copy_chunk_to_user, &from) :
9439 -              n);
9440 -}
9441 -
9442 -static inline int strncpy_chunk_from_user(unsigned long from, int len, 
9443 -                                         void *arg)
9444 -{
9445 -        char **to_ptr = arg, *to = *to_ptr;
9446 -       int n;
9447 -
9448 -       from = maybe_map(from, 0);
9449 -       if(from == 0)
9450 -               return(-1);
9451 -
9452 -       strncpy(to, (void *) from, len);
9453 -       n = strnlen(to, len);
9454 -       *to_ptr += n;
9455 -
9456 -       if(n < len) 
9457 -               return(1);
9458 -       return(0);
9459 -}
9460 -
9461 -static inline int strncpy_from_user_skas(char *dst, const char *src, int count)
9462 -{
9463 -       int n;
9464 -       char *ptr = dst;
9465 -
9466 -       if(segment_eq(get_fs(), KERNEL_DS)){
9467 -               strncpy(dst, src, count);
9468 -               return(strnlen(dst, count));
9469 -       }
9470 -
9471 -       if(!access_ok_skas(VERIFY_READ, src, 1))
9472 -               return(-EFAULT);
9473 -
9474 -       n = buffer_op((unsigned long) src, count, strncpy_chunk_from_user, 
9475 -                     &ptr);
9476 -       if(n != 0)
9477 -               return(-EFAULT);
9478 -       return(strnlen(dst, count));
9479 -}
9480 -
9481 -static inline int clear_chunk(unsigned long addr, int len, void *unused)
9482 -{
9483 -       addr = maybe_map(addr, 1);
9484 -       if(addr == 0) 
9485 -               return(-1);
9486 -
9487 -       memset((void *) addr, 0, len);
9488 -       return(0);
9489 -}
9490 -
9491 -static inline int __clear_user_skas(void *mem, int len)
9492 -{
9493 -       return(buffer_op((unsigned long) mem, len, clear_chunk, NULL));
9494 -}
9495 -
9496 -static inline int clear_user_skas(void *mem, int len)
9497 -{
9498 -       if(segment_eq(get_fs(), KERNEL_DS)){
9499 -               memset(mem, 0, len);
9500 -               return(0);
9501 -       }
9502 -
9503 -       return(access_ok_skas(VERIFY_WRITE, mem, len) ? 
9504 -              buffer_op((unsigned long) mem, len, clear_chunk, NULL) : len);
9505 -}
9506 -
9507 -static inline int strnlen_chunk(unsigned long str, int len, void *arg)
9508 -{
9509 -       int *len_ptr = arg, n;
9510 -
9511 -       str = maybe_map(str, 0);
9512 -       if(str == 0) 
9513 -               return(-1);
9514 -
9515 -       n = strnlen((void *) str, len);
9516 -       *len_ptr += n;
9517 -
9518 -       if(n < len)
9519 -               return(1);
9520 -       return(0);
9521 -}
9522 -
9523 -static inline int strnlen_user_skas(const void *str, int len)
9524 -{
9525 -       int count = 0, n;
9526 -
9527 -       if(segment_eq(get_fs(), KERNEL_DS))
9528 -               return(strnlen(str, len) + 1);
9529 -
9530 -       n = buffer_op((unsigned long) str, len, strnlen_chunk, &count);
9531 -       if(n == 0)
9532 -               return(count + 1);
9533 -       return(-EFAULT);
9534 -}
9535 +extern int copy_from_user_skas(void *to, const void *from, int n);
9536 +extern int copy_to_user_skas(void *to, const void *from, int n);
9537 +extern int strncpy_from_user_skas(char *dst, const char *src, int count);
9538 +extern int __clear_user_skas(void *mem, int len);
9539 +extern int clear_user_skas(void *mem, int len);
9540 +extern int strnlen_user_skas(const void *str, int len);
9541  
9542  #endif
9543  
9544 diff -Naur a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
9545 --- a/arch/um/kernel/skas/Makefile      2004-01-08 22:17:52.000000000 -0500
9546 +++ b/arch/um/kernel/skas/Makefile      2004-01-08 22:23:56.000000000 -0500
9547 @@ -5,20 +5,24 @@
9548  
9549  obj-y = exec_kern.o exec_user.o mem.o mem_user.o mmu.o process.o \
9550         process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o \
9551 -       sys-$(SUBARCH)/
9552 +       uaccess.o sys-$(SUBARCH)/
9553 +
9554 +host-progs     := util/mk_ptregs
9555 +clean-files    := include/skas_ptregs.h
9556  
9557  USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
9558  USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
9559  
9560 -include/skas_ptregs.h : util/mk_ptregs
9561 -       util/mk_ptregs > $@
9562 -
9563 -util/mk_ptregs :
9564 -       $(MAKE) -C util
9565 +$(TOPDIR)/arch/um/include/skas_ptregs.h : $(src)/util/mk_ptregs
9566 +       @echo -n '  Generating $@'
9567 +       @$< > $@.tmp
9568 +       @if [ -r $@ ] && cmp -s $@ $@.tmp; then \
9569 +               echo ' (unchanged)'; \
9570 +               rm -f $@.tmp; \
9571 +       else \
9572 +               echo ' (updated)'; \
9573 +               mv -f $@.tmp $@; \
9574 +       fi
9575  
9576  $(USER_OBJS) : %.o: %.c
9577         $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
9578 -
9579 -clean :
9580 -       $(MAKE) -C util clean
9581 -       $(RM) -f include/skas_ptregs.h
9582 diff -Naur a/arch/um/kernel/skas/mem_user.c b/arch/um/kernel/skas/mem_user.c
9583 --- a/arch/um/kernel/skas/mem_user.c    2004-01-08 22:18:42.000000000 -0500
9584 +++ b/arch/um/kernel/skas/mem_user.c    2004-01-08 22:24:31.000000000 -0500
9585 @@ -7,6 +7,7 @@
9586  #include <sys/mman.h>
9587  #include <sys/ptrace.h>
9588  #include "mem_user.h"
9589 +#include "mem.h"
9590  #include "user.h"
9591  #include "os.h"
9592  #include "proc_mm.h"
9593 @@ -15,12 +16,12 @@
9594          int r, int w, int x)
9595  {
9596         struct proc_mm_op map;
9597 -       struct mem_region *region;
9598 -       int prot, n;
9599 +       __u64 offset;
9600 +       int prot, n, phys_fd;
9601  
9602         prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
9603                 (x ? PROT_EXEC : 0);
9604 -       region = phys_region(phys);
9605 +       phys_fd = phys_mapping(phys, &offset);
9606  
9607         map = ((struct proc_mm_op) { .op        = MM_MMAP,
9608                                      .u         = 
9609 @@ -30,12 +31,12 @@
9610                                          .prot          = prot,
9611                                          .flags         = MAP_SHARED | 
9612                                                           MAP_FIXED,
9613 -                                        .fd            = region->fd,
9614 -                                        .offset        = phys_offset(phys)
9615 +                                        .fd            = phys_fd,
9616 +                                        .offset        = offset
9617                                        } } } );
9618         n = os_write_file(fd, &map, sizeof(map));
9619         if(n != sizeof(map)) 
9620 -               printk("map : /proc/mm map failed, errno = %d\n", errno);
9621 +               printk("map : /proc/mm map failed, err = %d\n", -n);
9622  }
9623  
9624  int unmap(int fd, void *addr, int len)
9625 @@ -49,8 +50,13 @@
9626                                          { .addr        = (unsigned long) addr,
9627                                            .len         = len } } } );
9628         n = os_write_file(fd, &unmap, sizeof(unmap));
9629 -       if((n != 0) && (n != sizeof(unmap)))
9630 -               return(-errno);
9631 +       if(n != sizeof(unmap)) {
9632 +               if(n < 0) 
9633 +                       return(n);
9634 +               else if(n > 0) 
9635 +                       return(-EIO);
9636 +       }
9637 +
9638         return(0);
9639  }
9640  
9641 @@ -71,11 +77,15 @@
9642                                            .prot        = prot } } } );
9643  
9644         n = os_write_file(fd, &protect, sizeof(protect));
9645 -       if((n != 0) && (n != sizeof(protect))){
9646 +       if(n != sizeof(protect)) {
9647 +               if(n == 0) return(0);
9648 +
9649                 if(must_succeed)
9650 -                       panic("protect failed, errno = %d", errno);
9651 -               return(-errno);
9652 +                       panic("protect failed, err = %d", -n);
9653 +
9654 +               return(-EIO);
9655         }
9656 +
9657         return(0);
9658  }
9659  
9660 diff -Naur a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
9661 --- a/arch/um/kernel/skas/mmu.c 2004-01-08 22:33:46.000000000 -0500
9662 +++ b/arch/um/kernel/skas/mmu.c 2004-01-08 22:36:57.000000000 -0500
9663 @@ -22,9 +22,11 @@
9664         else from = -1;
9665  
9666         mm->context.skas.mm_fd = new_mm(from);
9667 -       if(mm->context.skas.mm_fd < 0)
9668 -               panic("init_new_context_skas - new_mm failed, errno = %d\n",
9669 -                     mm->context.skas.mm_fd);
9670 +       if(mm->context.skas.mm_fd < 0){
9671 +               printk("init_new_context_skas - new_mm failed, errno = %d\n",
9672 +                      mm->context.skas.mm_fd);
9673 +               return(mm->context.skas.mm_fd);
9674 +       }
9675  
9676         return(0);
9677  }
9678 diff -Naur a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
9679 --- a/arch/um/kernel/skas/process.c     2004-01-08 22:31:21.000000000 -0500
9680 +++ b/arch/um/kernel/skas/process.c     2004-01-08 22:36:09.000000000 -0500
9681 @@ -4,6 +4,7 @@
9682   */
9683  
9684  #include <stdlib.h>
9685 +#include <unistd.h>
9686  #include <errno.h>
9687  #include <signal.h>
9688  #include <setjmp.h>
9689 @@ -24,6 +25,18 @@
9690  #include "os.h"
9691  #include "proc_mm.h"
9692  #include "skas_ptrace.h"
9693 +#include "chan_user.h"
9694 +
9695 +int is_skas_winch(int pid, int fd, void *data)
9696 +{
9697 +       if(pid != getpid())
9698 +               return(0);
9699 +
9700 +       register_winch_irq(-1, fd, -1, data);
9701 +       return(1);
9702 +}
9703 +
9704 +/* These are set once at boot time and not changed thereafter */
9705  
9706  unsigned long exec_regs[FRAME_SIZE];
9707  unsigned long exec_fp_regs[HOST_FP_SIZE];
9708 @@ -48,11 +61,11 @@
9709         int err, syscall_nr, status;
9710  
9711         syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
9712 +       UPT_SYSCALL_NR(regs) = syscall_nr;
9713         if(syscall_nr < 1){
9714                 relay_signal(SIGTRAP, regs);
9715                 return;
9716         }
9717 -       UPT_SYSCALL_NR(regs) = syscall_nr;
9718  
9719         err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
9720         if(err < 0)
9721 @@ -72,8 +85,6 @@
9722         handle_syscall(regs);
9723  }
9724  
9725 -int userspace_pid;
9726 -
9727  static int userspace_tramp(void *arg)
9728  {
9729         init_new_thread_signals(0);
9730 @@ -83,7 +94,11 @@
9731         return(0);
9732  }
9733  
9734 -void start_userspace(void)
9735 +/* Each element set once, and only accessed by a single processor anyway */
9736 +#define NR_CPUS 1
9737 +int userspace_pid[NR_CPUS];
9738 +
9739 +void start_userspace(int cpu)
9740  {
9741         void *stack;
9742         unsigned long sp;
9743 @@ -114,21 +129,21 @@
9744         if(munmap(stack, PAGE_SIZE) < 0)
9745                 panic("start_userspace : munmap failed, errno = %d\n", errno);
9746  
9747 -       userspace_pid = pid;
9748 +       userspace_pid[cpu] = pid;
9749  }
9750  
9751  void userspace(union uml_pt_regs *regs)
9752  {
9753 -       int err, status, op;
9754 +       int err, status, op, pid = userspace_pid[0];
9755  
9756         restore_registers(regs);
9757                 
9758 -       err = ptrace(PTRACE_SYSCALL, userspace_pid, 0, 0);
9759 +       err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
9760         if(err)
9761                 panic("userspace - PTRACE_SYSCALL failed, errno = %d\n", 
9762                        errno);
9763         while(1){
9764 -               err = waitpid(userspace_pid, &status, WUNTRACED);
9765 +               err = waitpid(pid, &status, WUNTRACED);
9766                 if(err < 0)
9767                         panic("userspace - waitpid failed, errno = %d\n", 
9768                               errno);
9769 @@ -139,16 +154,17 @@
9770                 if(WIFSTOPPED(status)){
9771                         switch(WSTOPSIG(status)){
9772                         case SIGSEGV:
9773 -                               handle_segv(userspace_pid);
9774 +                               handle_segv(pid);
9775                                 break;
9776                         case SIGTRAP:
9777 -                               handle_trap(userspace_pid, regs);
9778 +                               handle_trap(pid, regs);
9779                                 break;
9780                         case SIGIO:
9781                         case SIGVTALRM:
9782                         case SIGILL:
9783                         case SIGBUS:
9784                         case SIGFPE:
9785 +                       case SIGWINCH:
9786                                 user_signal(WSTOPSIG(status), regs);
9787                                 break;
9788                         default:
9789 @@ -162,7 +178,7 @@
9790  
9791                 op = singlestepping_skas() ? PTRACE_SINGLESTEP : 
9792                         PTRACE_SYSCALL;
9793 -               err = ptrace(op, userspace_pid, 0, 0);
9794 +               err = ptrace(op, pid, 0, 0);
9795                 if(err)
9796                         panic("userspace - PTRACE_SYSCALL failed, "
9797                               "errno = %d\n", errno);
9798 @@ -177,7 +193,7 @@
9799         *switch_buf_ptr = &switch_buf;
9800         *fork_buf_ptr = &fork_buf;
9801  
9802 -       if(setjmp(fork_buf) == 0)
9803 +       if(sigsetjmp(fork_buf, 1) == 0)
9804                 new_thread_proc(stack, handler);
9805  
9806         remove_sigstack();
9807 @@ -189,16 +205,16 @@
9808  
9809         *switch_buf = &buf;
9810         fork_buf = fb;
9811 -       if(setjmp(buf) == 0)
9812 -               longjmp(*fork_buf, 1);
9813 +       if(sigsetjmp(buf, 1) == 0)
9814 +               siglongjmp(*fork_buf, 1);
9815  }
9816  
9817 -static int move_registers(int int_op, int fp_op, union uml_pt_regs *regs,
9818 -                         unsigned long *fp_regs)
9819 +static int move_registers(int pid, int int_op, int fp_op, 
9820 +                         union uml_pt_regs *regs, unsigned long *fp_regs)
9821  {
9822 -       if(ptrace(int_op, userspace_pid, 0, regs->skas.regs) < 0)
9823 +       if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
9824                 return(-errno);
9825 -       if(ptrace(fp_op, userspace_pid, 0, fp_regs) < 0)
9826 +       if(ptrace(fp_op, pid, 0, fp_regs) < 0)
9827                 return(-errno);
9828         return(0);
9829  }
9830 @@ -217,10 +233,11 @@
9831                 fp_regs = regs->skas.fp;
9832         }
9833  
9834 -       err = move_registers(PTRACE_GETREGS, fp_op, regs, fp_regs);
9835 +       err = move_registers(userspace_pid[0], PTRACE_GETREGS, fp_op, regs, 
9836 +                            fp_regs);
9837         if(err)
9838                 panic("save_registers - saving registers failed, errno = %d\n",
9839 -                     err);
9840 +                     -err);
9841  }
9842  
9843  void restore_registers(union uml_pt_regs *regs)
9844 @@ -237,10 +254,11 @@
9845                 fp_regs = regs->skas.fp;
9846         }
9847  
9848 -       err = move_registers(PTRACE_SETREGS, fp_op, regs, fp_regs);
9849 +       err = move_registers(userspace_pid[0], PTRACE_SETREGS, fp_op, regs, 
9850 +                            fp_regs);
9851         if(err)
9852                 panic("restore_registers - saving registers failed, "
9853 -                     "errno = %d\n", err);
9854 +                     "errno = %d\n", -err);
9855  }
9856  
9857  void switch_threads(void *me, void *next)
9858 @@ -248,8 +266,8 @@
9859         jmp_buf my_buf, **me_ptr = me, *next_buf = next;
9860         
9861         *me_ptr = &my_buf;
9862 -       if(setjmp(my_buf) == 0)
9863 -               longjmp(*next_buf, 1);
9864 +       if(sigsetjmp(my_buf, 1) == 0)
9865 +               siglongjmp(*next_buf, 1);
9866  }
9867  
9868  static jmp_buf initial_jmpbuf;
9869 @@ -265,14 +283,14 @@
9870         int n;
9871  
9872         *fork_buf_ptr = &initial_jmpbuf;
9873 -       n = setjmp(initial_jmpbuf);
9874 +       n = sigsetjmp(initial_jmpbuf, 1);
9875         if(n == 0)
9876                 new_thread_proc((void *) stack, new_thread_handler);
9877         else if(n == 1)
9878                 remove_sigstack();
9879         else if(n == 2){
9880                 (*cb_proc)(cb_arg);
9881 -               longjmp(*cb_back, 1);
9882 +               siglongjmp(*cb_back, 1);
9883         }
9884         else if(n == 3){
9885                 kmalloc_ok = 0;
9886 @@ -282,7 +300,7 @@
9887                 kmalloc_ok = 0;
9888                 return(1);
9889         }
9890 -       longjmp(**switch_buf, 1);
9891 +       siglongjmp(**switch_buf, 1);
9892  }
9893  
9894  void remove_sigstack(void)
9895 @@ -304,8 +322,8 @@
9896         cb_back = &here;
9897  
9898         block_signals();
9899 -       if(setjmp(here) == 0)
9900 -               longjmp(initial_jmpbuf, 2);
9901 +       if(sigsetjmp(here, 1) == 0)
9902 +               siglongjmp(initial_jmpbuf, 2);
9903         unblock_signals();
9904  
9905         cb_proc = NULL;
9906 @@ -316,22 +334,23 @@
9907  void halt_skas(void)
9908  {
9909         block_signals();
9910 -       longjmp(initial_jmpbuf, 3);
9911 +       siglongjmp(initial_jmpbuf, 3);
9912  }
9913  
9914  void reboot_skas(void)
9915  {
9916         block_signals();
9917 -       longjmp(initial_jmpbuf, 4);
9918 +       siglongjmp(initial_jmpbuf, 4);
9919  }
9920  
9921  int new_mm(int from)
9922  {
9923         struct proc_mm_op copy;
9924 -       int n, fd = os_open_file("/proc/mm", of_write(OPENFLAGS()), 0);
9925 +       int n, fd = os_open_file("/proc/mm", 
9926 +                                of_cloexec(of_write(OPENFLAGS())), 0);
9927  
9928         if(fd < 0)
9929 -               return(-errno);
9930 +               return(fd);
9931  
9932         if(from != -1){
9933                 copy = ((struct proc_mm_op) { .op       = MM_COPY_SEGMENTS,
9934 @@ -340,8 +359,9 @@
9935                 n = os_write_file(fd, &copy, sizeof(copy));
9936                 if(n != sizeof(copy)) 
9937                         printk("new_mm : /proc/mm copy_segments failed, "
9938 -                              "errno = %d\n", errno);
9939 +                              "err = %d\n", -n);
9940         }
9941 +
9942         return(fd);
9943  }
9944  
9945 @@ -349,7 +369,8 @@
9946  {
9947         int err;
9948  
9949 -       err = ptrace(PTRACE_SWITCH_MM, userspace_pid, 0, mm_fd);
9950 +#warning need cpu pid in switch_mm_skas
9951 +       err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, mm_fd);
9952         if(err)
9953                 panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n",
9954                       errno);
9955 @@ -357,7 +378,8 @@
9956  
9957  void kill_off_processes_skas(void)
9958  {
9959 -       os_kill_process(userspace_pid, 1);
9960 +#warning need to loop over userspace_pids in kill_off_processes_skas
9961 +       os_kill_process(userspace_pid[0], 1);
9962  }
9963  
9964  void init_registers(int pid)
9965 diff -Naur a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
9966 --- a/arch/um/kernel/skas/process_kern.c        2004-01-08 22:16:41.000000000 -0500
9967 +++ b/arch/um/kernel/skas/process_kern.c        2004-01-08 22:22:45.000000000 -0500
9968 @@ -61,11 +61,13 @@
9969         thread_wait(&current->thread.mode.skas.switch_buf, 
9970                     current->thread.mode.skas.fork_buf);
9971  
9972 -#ifdef CONFIG_SMP
9973 -       schedule_tail(NULL);
9974 -#endif
9975 +       if(current->thread.prev_sched != NULL)
9976 +               schedule_tail(current->thread.prev_sched);
9977         current->thread.prev_sched = NULL;
9978  
9979 +       /* The return value is 1 if the kernel thread execs a process,
9980 +        * 0 if it just exits
9981 +        */
9982         n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
9983         if(n == 1)
9984                 userspace(&current->thread.regs.regs);
9985 @@ -93,9 +95,8 @@
9986                     current->thread.mode.skas.fork_buf);
9987         
9988         force_flush_all();
9989 -#ifdef CONFIG_SMP
9990 -       schedule_tail(current->thread.prev_sched);
9991 -#endif
9992 +       if(current->thread.prev_sched != NULL)
9993 +               schedule_tail(current->thread.prev_sched);
9994         current->thread.prev_sched = NULL;
9995         unblock_signals();
9996  
9997 @@ -136,7 +137,7 @@
9998  
9999  void init_idle_skas(void)
10000  {
10001 -       cpu_tasks[current->thread_info->cpu].pid = os_getpid();
10002 +       cpu_tasks[current_thread->cpu].pid = os_getpid();
10003         default_idle();
10004  }
10005  
10006 @@ -160,11 +161,11 @@
10007  
10008  int start_uml_skas(void)
10009  {
10010 -       start_userspace();
10011 +       start_userspace(0);
10012         capture_signal_stack();
10013 +       uml_idle_timer();
10014  
10015         init_new_thread_signals(1);
10016 -       idle_timer();
10017  
10018         init_task.thread.request.u.thread.proc = start_kernel_proc;
10019         init_task.thread.request.u.thread.arg = NULL;
10020 @@ -175,12 +176,14 @@
10021  
10022  int external_pid_skas(struct task_struct *task)
10023  {
10024 -       return(userspace_pid);
10025 +#warning Need to look up userspace_pid by cpu  
10026 +       return(userspace_pid[0]);
10027  }
10028  
10029  int thread_pid_skas(struct task_struct *task)
10030  {
10031 -       return(userspace_pid);
10032 +#warning Need to look up userspace_pid by cpu  
10033 +       return(userspace_pid[0]);
10034  }
10035  
10036  /*
10037 diff -Naur a/arch/um/kernel/skas/syscall_kern.c b/arch/um/kernel/skas/syscall_kern.c
10038 --- a/arch/um/kernel/skas/syscall_kern.c        2004-01-08 22:24:03.000000000 -0500
10039 +++ b/arch/um/kernel/skas/syscall_kern.c        2004-01-08 22:31:17.000000000 -0500
10040 @@ -1,5 +1,5 @@
10041  /* 
10042 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
10043 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
10044   * Licensed under the GPL
10045   */
10046  
10047 diff -Naur a/arch/um/kernel/skas/sys-i386/sigcontext.c b/arch/um/kernel/skas/sys-i386/sigcontext.c
10048 --- a/arch/um/kernel/skas/sys-i386/sigcontext.c 2004-01-08 22:13:52.000000000 -0500
10049 +++ b/arch/um/kernel/skas/sys-i386/sigcontext.c 2004-01-08 22:18:57.000000000 -0500
10050 @@ -12,10 +12,9 @@
10051  #include "kern_util.h"
10052  #include "user.h"
10053  #include "sigcontext.h"
10054 +#include "mode.h"
10055  
10056 -extern int userspace_pid;
10057 -
10058 -int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr)
10059 +int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, void *from_ptr)
10060  {
10061         struct sigcontext sc, *from = from_ptr;
10062         unsigned long fpregs[FP_FRAME_SIZE];
10063 @@ -41,13 +40,12 @@
10064         regs->skas.regs[EIP] = sc.eip;
10065         regs->skas.regs[CS] = sc.cs;
10066         regs->skas.regs[EFL] = sc.eflags;
10067 -       regs->skas.regs[UESP] = sc.esp_at_signal;
10068         regs->skas.regs[SS] = sc.ss;
10069         regs->skas.fault_addr = sc.cr2;
10070         regs->skas.fault_type = FAULT_WRITE(sc.err);
10071         regs->skas.trap_type = sc.trapno;
10072  
10073 -       err = ptrace(PTRACE_SETFPREGS, userspace_pid, 0, fpregs);
10074 +       err = ptrace(PTRACE_SETFPREGS, pid, 0, fpregs);
10075         if(err < 0){
10076                 printk("copy_sc_to_user - PTRACE_SETFPREGS failed, "
10077                        "errno = %d\n", errno);
10078 @@ -57,8 +55,9 @@
10079         return(0);
10080  }
10081  
10082 -int copy_sc_to_user_skas(void *to_ptr, void *fp, union uml_pt_regs *regs, 
10083 -                        unsigned long fault_addr, int fault_type)
10084 +int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp, 
10085 +                        union uml_pt_regs *regs, unsigned long fault_addr, 
10086 +                        int fault_type)
10087  {
10088         struct sigcontext sc, *to = to_ptr;
10089         struct _fpstate *to_fp;
10090 @@ -86,7 +85,7 @@
10091         sc.err = TO_SC_ERR(fault_type);
10092         sc.trapno = regs->skas.trap_type;
10093  
10094 -       err = ptrace(PTRACE_GETFPREGS, userspace_pid, 0, fpregs);
10095 +       err = ptrace(PTRACE_GETFPREGS, pid, 0, fpregs);
10096         if(err < 0){
10097                 printk("copy_sc_to_user - PTRACE_GETFPREGS failed, "
10098                        "errno = %d\n", errno);
10099 diff -Naur a/arch/um/kernel/skas/trap_user.c b/arch/um/kernel/skas/trap_user.c
10100 --- a/arch/um/kernel/skas/trap_user.c   2004-01-08 22:20:11.000000000 -0500
10101 +++ b/arch/um/kernel/skas/trap_user.c   2004-01-08 22:26:28.000000000 -0500
10102 @@ -1,5 +1,5 @@
10103  /* 
10104 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
10105 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
10106   * Licensed under the GPL
10107   */
10108  
10109 @@ -41,8 +41,6 @@
10110  {
10111         struct signal_info *info;
10112  
10113 -       if(sig == SIGVTALRM)
10114 -               missed_ticks[cpu()]++;
10115         regs->skas.is_user = 1;
10116         regs->skas.fault_addr = 0;
10117         regs->skas.fault_type = 0;
10118 diff -Naur a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
10119 --- a/arch/um/kernel/skas/uaccess.c     1969-12-31 19:00:00.000000000 -0500
10120 +++ b/arch/um/kernel/skas/uaccess.c     2004-01-08 22:33:48.000000000 -0500
10121 @@ -0,0 +1,219 @@
10122 +/* 
10123 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
10124 + * Licensed under the GPL
10125 + */
10126 +
10127 +#include "linux/stddef.h"
10128 +#include "linux/kernel.h"
10129 +#include "linux/string.h"
10130 +#include "linux/fs.h"
10131 +#include "linux/highmem.h"
10132 +#include "asm/page.h"
10133 +#include "asm/pgtable.h"
10134 +#include "asm/uaccess.h"
10135 +#include "kern_util.h"
10136 +
10137 +extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr, 
10138 +                            pte_t *pte_out);
10139 +
10140 +static unsigned long maybe_map(unsigned long virt, int is_write)
10141 +{
10142 +       pte_t pte;
10143 +       int err;
10144 +
10145 +       void *phys = um_virt_to_phys(current, virt, &pte);
10146 +       int dummy_code;
10147 +
10148 +       if(IS_ERR(phys) || (is_write && !pte_write(pte))){
10149 +               err = handle_page_fault(virt, 0, is_write, 0, &dummy_code);
10150 +               if(err)
10151 +                       return(0);
10152 +               phys = um_virt_to_phys(current, virt, NULL);
10153 +       }
10154 +       return((unsigned long) phys);
10155 +}
10156 +
10157 +static int do_op(unsigned long addr, int len, int is_write, 
10158 +                int (*op)(unsigned long addr, int len, void *arg), void *arg)
10159 +{
10160 +       struct page *page;
10161 +       int n;
10162 +
10163 +       addr = maybe_map(addr, is_write);
10164 +       if(addr == -1)
10165 +               return(-1);
10166 +
10167 +       page = phys_to_page(addr);
10168 +       addr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK);
10169 +       n = (*op)(addr, len, arg);
10170 +       kunmap(page);
10171 +
10172 +       return(n);
10173 +}
10174 +
10175 +static int buffer_op(unsigned long addr, int len, int is_write,
10176 +                    int (*op)(unsigned long addr, int len, void *arg),
10177 +                    void *arg)
10178 +{
10179 +       int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
10180 +       int remain = len, n;
10181 +
10182 +       n = do_op(addr, size, is_write, op, arg);
10183 +       if(n != 0)
10184 +               return(n < 0 ? remain : 0);
10185 +
10186 +       addr += size;
10187 +       remain -= size;
10188 +       if(remain == 0) 
10189 +               return(0);
10190 +
10191 +       while(addr < ((addr + remain) & PAGE_MASK)){
10192 +               n = do_op(addr, PAGE_SIZE, is_write, op, arg);
10193 +               if(n != 0)
10194 +                       return(n < 0 ? remain : 0);
10195 +
10196 +               addr += PAGE_SIZE;
10197 +               remain -= PAGE_SIZE;
10198 +       }
10199 +       if(remain == 0)
10200 +               return(0);
10201 +
10202 +       n = do_op(addr, remain, is_write, op, arg);
10203 +       if(n != 0)
10204 +               return(n < 0 ? remain : 0);
10205 +       return(0);
10206 +}
10207 +
10208 +static int copy_chunk_from_user(unsigned long from, int len, void *arg)
10209 +{
10210 +       unsigned long *to_ptr = arg, to = *to_ptr;
10211 +
10212 +       memcpy((void *) to, (void *) from, len);
10213 +       *to_ptr += len;
10214 +       return(0);
10215 +}
10216 +
10217 +int copy_from_user_skas(void *to, const void *from, int n)
10218 +{
10219 +       if(segment_eq(get_fs(), KERNEL_DS)){
10220 +               memcpy(to, from, n);
10221 +               return(0);
10222 +       }
10223 +
10224 +       return(access_ok_skas(VERIFY_READ, from, n) ?
10225 +              buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
10226 +              n);
10227 +}
10228 +
10229 +static int copy_chunk_to_user(unsigned long to, int len, void *arg)
10230 +{
10231 +       unsigned long *from_ptr = arg, from = *from_ptr;
10232 +
10233 +       memcpy((void *) to, (void *) from, len);
10234 +       *from_ptr += len;
10235 +       return(0);
10236 +}
10237 +
10238 +int copy_to_user_skas(void *to, const void *from, int n)
10239 +{
10240 +       if(segment_eq(get_fs(), KERNEL_DS)){
10241 +               memcpy(to, from, n);
10242 +               return(0);
10243 +       }
10244 +
10245 +       return(access_ok_skas(VERIFY_WRITE, to, n) ?
10246 +              buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
10247 +              n);
10248 +}
10249 +
10250 +static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
10251 +{
10252 +       char **to_ptr = arg, *to = *to_ptr;
10253 +       int n;
10254 +
10255 +       strncpy(to, (void *) from, len);
10256 +       n = strnlen(to, len);
10257 +       *to_ptr += n;
10258 +
10259 +       if(n < len) 
10260 +               return(1);
10261 +       return(0);
10262 +}
10263 +
10264 +int strncpy_from_user_skas(char *dst, const char *src, int count)
10265 +{
10266 +       int n;
10267 +       char *ptr = dst;
10268 +
10269 +       if(segment_eq(get_fs(), KERNEL_DS)){
10270 +               strncpy(dst, src, count);
10271 +               return(strnlen(dst, count));
10272 +       }
10273 +
10274 +       if(!access_ok_skas(VERIFY_READ, src, 1))
10275 +               return(-EFAULT);
10276 +
10277 +       n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user, 
10278 +                     &ptr);
10279 +       if(n != 0)
10280 +               return(-EFAULT);
10281 +       return(strnlen(dst, count));
10282 +}
10283 +
10284 +static int clear_chunk(unsigned long addr, int len, void *unused)
10285 +{
10286 +       memset((void *) addr, 0, len);
10287 +       return(0);
10288 +}
10289 +
10290 +int __clear_user_skas(void *mem, int len)
10291 +{
10292 +       return(buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL));
10293 +}
10294 +
10295 +int clear_user_skas(void *mem, int len)
10296 +{
10297 +       if(segment_eq(get_fs(), KERNEL_DS)){
10298 +               memset(mem, 0, len);
10299 +               return(0);
10300 +       }
10301 +
10302 +       return(access_ok_skas(VERIFY_WRITE, mem, len) ? 
10303 +              buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len);
10304 +}
10305 +
10306 +static int strnlen_chunk(unsigned long str, int len, void *arg)
10307 +{
10308 +       int *len_ptr = arg, n;
10309 +
10310 +       n = strnlen((void *) str, len);
10311 +       *len_ptr += n;
10312 +
10313 +       if(n < len)
10314 +               return(1);
10315 +       return(0);
10316 +}
10317 +
10318 +int strnlen_user_skas(const void *str, int len)
10319 +{
10320 +       int count = 0, n;
10321 +
10322 +       if(segment_eq(get_fs(), KERNEL_DS))
10323 +               return(strnlen(str, len) + 1);
10324 +
10325 +       n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count);
10326 +       if(n == 0)
10327 +               return(count + 1);
10328 +       return(-EFAULT);
10329 +}
10330 +
10331 +/*
10332 + * Overrides for Emacs so that we follow Linus's tabbing style.
10333 + * Emacs will notice this stuff at the end of the file and automatically
10334 + * adjust the settings for this buffer only.  This must remain at the end
10335 + * of the file.
10336 + * ---------------------------------------------------------------------------
10337 + * Local variables:
10338 + * c-file-style: "linux"
10339 + * End:
10340 + */
10341 diff -Naur a/arch/um/kernel/skas/util/Makefile b/arch/um/kernel/skas/util/Makefile
10342 --- a/arch/um/kernel/skas/util/Makefile 2004-01-08 22:28:48.000000000 -0500
10343 +++ b/arch/um/kernel/skas/util/Makefile 2004-01-08 22:35:00.000000000 -0500
10344 @@ -1,10 +1,10 @@
10345  all: mk_ptregs
10346  
10347  mk_ptregs : mk_ptregs.o
10348 -       $(CC) -o mk_ptregs mk_ptregs.o
10349 +       $(HOSTCC) -o mk_ptregs mk_ptregs.o
10350  
10351  mk_ptregs.o : mk_ptregs.c
10352 -       $(CC) -c $< 
10353 +       $(HOSTCC) -c $< 
10354  
10355  clean : 
10356         $(RM) -f mk_ptregs *.o *~
10357 diff -Naur a/arch/um/kernel/skas/util/mk_ptregs.c b/arch/um/kernel/skas/util/mk_ptregs.c
10358 --- a/arch/um/kernel/skas/util/mk_ptregs.c      2004-01-08 22:19:28.000000000 -0500
10359 +++ b/arch/um/kernel/skas/util/mk_ptregs.c      2004-01-08 22:25:46.000000000 -0500
10360 @@ -1,3 +1,4 @@
10361 +#include <stdio.h>
10362  #include <asm/ptrace.h>
10363  #include <asm/user.h>
10364  
10365 diff -Naur a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
10366 --- a/arch/um/kernel/smp.c      2004-01-08 22:16:25.000000000 -0500
10367 +++ b/arch/um/kernel/smp.c      2004-01-08 22:22:29.000000000 -0500
10368 @@ -1,9 +1,15 @@
10369  /* 
10370 - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
10371 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
10372   * Licensed under the GPL
10373   */
10374  
10375  #include "linux/config.h"
10376 +#include "linux/percpu.h"
10377 +#include "asm/pgalloc.h"
10378 +#include "asm/tlb.h"
10379 +
10380 +/* For some reason, mmu_gathers are referenced when CONFIG_SMP is off. */
10381 +DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
10382  
10383  #ifdef CONFIG_SMP
10384  
10385 @@ -23,7 +29,7 @@
10386  #include "os.h"
10387  
10388  /* CPU online map, set by smp_boot_cpus */
10389 -unsigned long cpu_online_map = cpumask_of_cpu(0);
10390 +unsigned long cpu_online_map = CPU_MASK_NONE;
10391  
10392  EXPORT_SYMBOL(cpu_online_map);
10393  
10394 @@ -55,7 +61,7 @@
10395  
10396  void smp_send_reschedule(int cpu)
10397  {
10398 -       write(cpu_data[cpu].ipi_pipe[1], "R", 1);
10399 +       os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1);
10400         num_reschedules_sent++;
10401  }
10402  
10403 @@ -100,35 +106,34 @@
10404  
10405         printk(KERN_INFO "Stopping all CPUs...");
10406         for(i = 0; i < num_online_cpus(); i++){
10407 -               if(i == current->thread_info->cpu)
10408 +               if(i == current_thread->cpu)
10409                         continue;
10410 -               write(cpu_data[i].ipi_pipe[1], "S", 1);
10411 +               os_write_file(cpu_data[i].ipi_pipe[1], "S", 1);
10412         }
10413         printk("done\n");
10414  }
10415  
10416 -static cpumask_t smp_commenced_mask;
10417 -static cpumask_t smp_callin_map = CPU_MASK_NONE;
10418 +static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
10419 +static cpumask_t cpu_callin_map = CPU_MASK_NONE;
10420  
10421  static int idle_proc(void *cpup)
10422  {
10423         int cpu = (int) cpup, err;
10424  
10425         err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
10426 -       if(err)
10427 -               panic("CPU#%d failed to create IPI pipe, errno = %d", cpu, 
10428 -                     -err);
10429 +       if(err < 0)
10430 +               panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);
10431  
10432         activate_ipi(cpu_data[cpu].ipi_pipe[0], 
10433                      current->thread.mode.tt.extern_pid);
10434   
10435         wmb();
10436 -       if (cpu_test_and_set(cpu, &smp_callin_map)) {
10437 +       if (cpu_test_and_set(cpu, cpu_callin_map)) {
10438                 printk("huh, CPU#%d already present??\n", cpu);
10439                 BUG();
10440         }
10441  
10442 -       while (!cpu_isset(cpu, &smp_commenced_mask))
10443 +       while (!cpu_isset(cpu, smp_commenced_mask))
10444                 cpu_relax();
10445  
10446         cpu_set(cpu, cpu_online_map);
10447 @@ -143,16 +148,20 @@
10448  
10449          current->thread.request.u.thread.proc = idle_proc;
10450          current->thread.request.u.thread.arg = (void *) cpu;
10451 -       new_task = do_fork(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, NULL);
10452 -       if(IS_ERR(new_task)) panic("do_fork failed in idle_thread");
10453 +       new_task = copy_process(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, 
10454 +                               NULL);
10455 +       if(IS_ERR(new_task)) 
10456 +               panic("copy_process failed in idle_thread, error = %ld",
10457 +                     PTR_ERR(new_task));
10458  
10459         cpu_tasks[cpu] = ((struct cpu_task) 
10460                           { .pid =      new_task->thread.mode.tt.extern_pid,
10461                             .task =     new_task } );
10462         idle_threads[cpu] = new_task;
10463 -       CHOOSE_MODE(write(new_task->thread.mode.tt.switch_pipe[1], &c, 
10464 +       CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c, 
10465                           sizeof(c)),
10466                     ({ panic("skas mode doesn't support SMP"); }));
10467 +       wake_up_forked_process(new_task);
10468         return(new_task);
10469  }
10470  
10471 @@ -160,15 +169,17 @@
10472  {
10473         struct task_struct *idle;
10474         unsigned long waittime;
10475 -       int err, cpu;
10476 +       int err, cpu, me = smp_processor_id();
10477  
10478 -       cpu_set(0, cpu_online_map);
10479 -       cpu_set(0, smp_callin_map);
10480 +       cpu_clear(me, cpu_online_map);
10481 +       cpu_set(me, cpu_online_map);
10482 +       cpu_set(me, cpu_callin_map);
10483  
10484 -       err = os_pipe(cpu_data[0].ipi_pipe, 1, 1);
10485 -       if(err) panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
10486 +       err = os_pipe(cpu_data[me].ipi_pipe, 1, 1);
10487 +       if(err < 0)
10488 +               panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
10489  
10490 -       activate_ipi(cpu_data[0].ipi_pipe[0], 
10491 +       activate_ipi(cpu_data[me].ipi_pipe[0], 
10492                      current->thread.mode.tt.extern_pid);
10493  
10494         for(cpu = 1; cpu < ncpus; cpu++){
10495 @@ -180,10 +191,10 @@
10496                 unhash_process(idle);
10497  
10498                 waittime = 200000000;
10499 -               while (waittime-- && !cpu_isset(cpu, smp_callin_map))
10500 +               while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
10501                         cpu_relax();
10502  
10503 -               if (cpu_isset(cpu, smp_callin_map))
10504 +               if (cpu_isset(cpu, cpu_callin_map))
10505                         printk("done\n");
10506                 else printk("failed\n");
10507         }
10508 @@ -216,7 +227,7 @@
10509         int fd;
10510  
10511         fd = cpu_data[cpu].ipi_pipe[0];
10512 -       while (read(fd, &c, 1) == 1) {
10513 +       while (os_read_file(fd, &c, 1) == 1) {
10514                 switch (c) {
10515                 case 'C':
10516                         smp_call_function_slave(cpu);
10517 @@ -273,9 +284,9 @@
10518         info = _info;
10519  
10520         for (i=0;i<NR_CPUS;i++)
10521 -               if((i != current->thread_info->cpu) && 
10522 +               if((i != current_thread->cpu) && 
10523                    cpu_isset(i, cpu_online_map))
10524 -                       write(cpu_data[i].ipi_pipe[1], "C", 1);
10525 +                       os_write_file(cpu_data[i].ipi_pipe[1], "C", 1);
10526  
10527         while (atomic_read(&scf_started) != cpus)
10528                 barrier();
10529 diff -Naur a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c
10530 --- a/arch/um/kernel/syscall_kern.c     2004-01-08 22:26:00.000000000 -0500
10531 +++ b/arch/um/kernel/syscall_kern.c     2004-01-08 22:33:41.000000000 -0500
10532 @@ -1,5 +1,5 @@
10533  /* 
10534 - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
10535 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
10536   * Licensed under the GPL
10537   */
10538  
10539 @@ -35,39 +35,40 @@
10540  
10541  long sys_fork(void)
10542  {
10543 -       struct task_struct *p;
10544 +       long ret;
10545  
10546         current->thread.forking = 1;
10547 -        p = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
10548 +        ret = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
10549         current->thread.forking = 0;
10550 -       return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
10551 +       return(ret);
10552  }
10553  
10554 -long sys_clone(unsigned long clone_flags, unsigned long newsp)
10555 +long sys_clone(unsigned long clone_flags, unsigned long newsp, 
10556 +              int *parent_tid, int *child_tid)
10557  {
10558 -       struct task_struct *p;
10559 +       long ret;
10560  
10561         current->thread.forking = 1;
10562 -       p = do_fork(clone_flags, newsp, NULL, 0, NULL, NULL);
10563 +       ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid);
10564         current->thread.forking = 0;
10565 -       return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
10566 +       return(ret);
10567  }
10568  
10569  long sys_vfork(void)
10570  {
10571 -       struct task_struct *p;
10572 +       long ret;
10573  
10574         current->thread.forking = 1;
10575 -       p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, NULL);
10576 +       ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, 
10577 +                     NULL);
10578         current->thread.forking = 0;
10579 -       return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
10580 +       return(ret);
10581  }
10582  
10583  /* common code for old and new mmaps */
10584 -static inline long do_mmap2(
10585 -       unsigned long addr, unsigned long len,
10586 -       unsigned long prot, unsigned long flags,
10587 -       unsigned long fd, unsigned long pgoff)
10588 +long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len,
10589 +             unsigned long prot, unsigned long flags, unsigned long fd,
10590 +             unsigned long pgoff)
10591  {
10592         int error = -EBADF;
10593         struct file * file = NULL;
10594 @@ -79,9 +80,9 @@
10595                         goto out;
10596         }
10597  
10598 -       down_write(&current->mm->mmap_sem);
10599 -       error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
10600 -       up_write(&current->mm->mmap_sem);
10601 +       down_write(&mm->mmap_sem);
10602 +       error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
10603 +       up_write(&mm->mmap_sem);
10604  
10605         if (file)
10606                 fput(file);
10607 @@ -93,7 +94,7 @@
10608                unsigned long prot, unsigned long flags,
10609                unsigned long fd, unsigned long pgoff)
10610  {
10611 -       return do_mmap2(addr, len, prot, flags, fd, pgoff);
10612 +       return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
10613  }
10614  
10615  /*
10616 @@ -120,7 +121,8 @@
10617         if (offset & ~PAGE_MASK)
10618                 goto out;
10619  
10620 -       err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
10621 +       err = do_mmap2(current->mm, addr, len, prot, flags, fd, 
10622 +                      offset >> PAGE_SHIFT);
10623   out:
10624         return err;
10625  }
10626 @@ -135,43 +137,12 @@
10627  
10628          error = do_pipe(fd);
10629          if (!error) {
10630 -                if (copy_to_user(fildes, fd, 2*sizeof(int)))
10631 +               if (copy_to_user(fildes, fd, sizeof(fd)))
10632                          error = -EFAULT;
10633          }
10634          return error;
10635  }
10636  
10637 -int sys_sigaction(int sig, const struct old_sigaction *act,
10638 -                        struct old_sigaction *oact)
10639 -{
10640 -       struct k_sigaction new_ka, old_ka;
10641 -       int ret;
10642 -
10643 -       if (act) {
10644 -               old_sigset_t mask;
10645 -               if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
10646 -                   __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
10647 -                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
10648 -                       return -EFAULT;
10649 -               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
10650 -               __get_user(mask, &act->sa_mask);
10651 -               siginitset(&new_ka.sa.sa_mask, mask);
10652 -       }
10653 -
10654 -       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
10655 -
10656 -       if (!ret && oact) {
10657 -               if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
10658 -                   __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
10659 -                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
10660 -                       return -EFAULT;
10661 -               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
10662 -               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
10663 -       }
10664 -
10665 -       return ret;
10666 -}
10667 -
10668  /*
10669   * sys_ipc() is the de-multiplexer for the SysV IPC calls..
10670   *
10671 @@ -253,7 +224,7 @@
10672                 return sys_shmctl (first, second,
10673                                    (struct shmid_ds *) ptr);
10674         default:
10675 -               return -EINVAL;
10676 +               return -ENOSYS;
10677         }
10678  }
10679  
10680 @@ -302,11 +273,6 @@
10681         return error;
10682  }
10683  
10684 -int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
10685 -{
10686 -       return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
10687 -}
10688 -
10689  long execute_syscall(void *r)
10690  {
10691         return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
10692 diff -Naur a/arch/um/kernel/sys_call_table.c b/arch/um/kernel/sys_call_table.c
10693 --- a/arch/um/kernel/sys_call_table.c   2004-01-08 22:28:47.000000000 -0500
10694 +++ b/arch/um/kernel/sys_call_table.c   2004-01-08 22:35:00.000000000 -0500
10695 @@ -5,7 +5,6 @@
10696  
10697  #include "linux/config.h"
10698  #include "linux/unistd.h"
10699 -#include "linux/version.h"
10700  #include "linux/sys.h"
10701  #include "linux/swap.h"
10702  #include "linux/sysctl.h"
10703 @@ -219,15 +218,30 @@
10704  extern syscall_handler_t sys_gettid;
10705  extern syscall_handler_t sys_readahead;
10706  extern syscall_handler_t sys_tkill;
10707 +extern syscall_handler_t sys_setxattr;
10708 +extern syscall_handler_t sys_lsetxattr;
10709 +extern syscall_handler_t sys_fsetxattr;
10710 +extern syscall_handler_t sys_getxattr;
10711 +extern syscall_handler_t sys_lgetxattr;
10712 +extern syscall_handler_t sys_fgetxattr;
10713 +extern syscall_handler_t sys_listxattr;
10714 +extern syscall_handler_t sys_llistxattr;
10715 +extern syscall_handler_t sys_flistxattr;
10716 +extern syscall_handler_t sys_removexattr;
10717 +extern syscall_handler_t sys_lremovexattr;
10718 +extern syscall_handler_t sys_fremovexattr;
10719  extern syscall_handler_t sys_sendfile64;
10720  extern syscall_handler_t sys_futex;
10721  extern syscall_handler_t sys_sched_setaffinity;
10722  extern syscall_handler_t sys_sched_getaffinity;
10723 +extern syscall_handler_t sys_set_thread_area;
10724 +extern syscall_handler_t sys_get_thread_area;
10725  extern syscall_handler_t sys_io_setup;
10726  extern syscall_handler_t sys_io_destroy;
10727  extern syscall_handler_t sys_io_getevents;
10728  extern syscall_handler_t sys_io_submit;
10729  extern syscall_handler_t sys_io_cancel;
10730 +extern syscall_handler_t sys_fadvise64;
10731  extern syscall_handler_t sys_exit_group;
10732  extern syscall_handler_t sys_lookup_dcookie;
10733  extern syscall_handler_t sys_epoll_create;
10734 @@ -235,6 +249,20 @@
10735  extern syscall_handler_t sys_epoll_wait;
10736  extern syscall_handler_t sys_remap_file_pages;
10737  extern syscall_handler_t sys_set_tid_address;
10738 +extern syscall_handler_t sys_timer_create;
10739 +extern syscall_handler_t sys_timer_settime;
10740 +extern syscall_handler_t sys_timer_gettime;
10741 +extern syscall_handler_t sys_timer_getoverrun;
10742 +extern syscall_handler_t sys_timer_delete;
10743 +extern syscall_handler_t sys_clock_settime;
10744 +extern syscall_handler_t sys_clock_gettime;
10745 +extern syscall_handler_t sys_clock_getres;
10746 +extern syscall_handler_t sys_clock_nanosleep;
10747 +extern syscall_handler_t sys_statfs64;
10748 +extern syscall_handler_t sys_fstatfs64;
10749 +extern syscall_handler_t sys_tgkill;
10750 +extern syscall_handler_t sys_utimes;
10751 +extern syscall_handler_t sys_fadvise64_64;
10752  
10753  #ifdef CONFIG_NFSD
10754  #define NFSSERVCTL sys_nfsservctl
10755 @@ -246,7 +274,7 @@
10756  extern syscall_handler_t um_time;
10757  extern syscall_handler_t um_stime;
10758  
10759 -#define LAST_GENERIC_SYSCALL __NR_set_tid_address
10760 +#define LAST_GENERIC_SYSCALL __NR_vserver
10761  
10762  #if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
10763  #define LAST_SYSCALL LAST_GENERIC_SYSCALL
10764 @@ -455,32 +483,37 @@
10765         [ __NR_stat64 ] = sys_stat64,
10766         [ __NR_lstat64 ] = sys_lstat64,
10767         [ __NR_fstat64 ] = sys_fstat64,
10768 -       [ __NR_fcntl64 ] = sys_fcntl64,
10769         [ __NR_getdents64 ] = sys_getdents64,
10770 +       [ __NR_fcntl64 ] = sys_fcntl64,
10771 +       [ 223 ] = sys_ni_syscall,
10772         [ __NR_gettid ] = sys_gettid,
10773         [ __NR_readahead ] = sys_readahead,
10774 -       [ __NR_setxattr ] = sys_ni_syscall,
10775 -       [ __NR_lsetxattr ] = sys_ni_syscall,
10776 -       [ __NR_fsetxattr ] = sys_ni_syscall,
10777 -       [ __NR_getxattr ] = sys_ni_syscall,
10778 -       [ __NR_lgetxattr ] = sys_ni_syscall,
10779 -       [ __NR_fgetxattr ] = sys_ni_syscall,
10780 -       [ __NR_listxattr ] = sys_ni_syscall,
10781 -       [ __NR_llistxattr ] = sys_ni_syscall,
10782 -       [ __NR_flistxattr ] = sys_ni_syscall,
10783 -       [ __NR_removexattr ] = sys_ni_syscall,
10784 -       [ __NR_lremovexattr ] = sys_ni_syscall,
10785 -       [ __NR_fremovexattr ] = sys_ni_syscall,
10786 +       [ __NR_setxattr ] = sys_setxattr,
10787 +       [ __NR_lsetxattr ] = sys_lsetxattr,
10788 +       [ __NR_fsetxattr ] = sys_fsetxattr,
10789 +       [ __NR_getxattr ] = sys_getxattr,
10790 +       [ __NR_lgetxattr ] = sys_lgetxattr,
10791 +       [ __NR_fgetxattr ] = sys_fgetxattr,
10792 +       [ __NR_listxattr ] = sys_listxattr,
10793 +       [ __NR_llistxattr ] = sys_llistxattr,
10794 +       [ __NR_flistxattr ] = sys_flistxattr,
10795 +       [ __NR_removexattr ] = sys_removexattr,
10796 +       [ __NR_lremovexattr ] = sys_lremovexattr,
10797 +       [ __NR_fremovexattr ] = sys_fremovexattr,
10798         [ __NR_tkill ] = sys_tkill,
10799         [ __NR_sendfile64 ] = sys_sendfile64,
10800         [ __NR_futex ] = sys_futex,
10801         [ __NR_sched_setaffinity ] = sys_sched_setaffinity,
10802         [ __NR_sched_getaffinity ] = sys_sched_getaffinity,
10803 +       [ __NR_set_thread_area ] = sys_ni_syscall,
10804 +       [ __NR_get_thread_area ] = sys_ni_syscall,
10805         [ __NR_io_setup ] = sys_io_setup,
10806         [ __NR_io_destroy ] = sys_io_destroy,
10807         [ __NR_io_getevents ] = sys_io_getevents,
10808         [ __NR_io_submit ] = sys_io_submit,
10809         [ __NR_io_cancel ] = sys_io_cancel,
10810 +       [ __NR_fadvise64 ] = sys_fadvise64,
10811 +       [ 251 ] = sys_ni_syscall,
10812         [ __NR_exit_group ] = sys_exit_group,
10813         [ __NR_lookup_dcookie ] = sys_lookup_dcookie,
10814         [ __NR_epoll_create ] = sys_epoll_create,
10815 @@ -488,6 +521,21 @@
10816         [ __NR_epoll_wait ] = sys_epoll_wait,
10817          [ __NR_remap_file_pages ] = sys_remap_file_pages,
10818          [ __NR_set_tid_address ] = sys_set_tid_address,
10819 +       [ __NR_timer_create ] = sys_timer_create,
10820 +       [ __NR_timer_settime ] = sys_timer_settime,
10821 +       [ __NR_timer_gettime ] = sys_timer_gettime,
10822 +       [ __NR_timer_getoverrun ] = sys_timer_getoverrun,
10823 +       [ __NR_timer_delete ] = sys_timer_delete,
10824 +       [ __NR_clock_settime ] = sys_clock_settime,
10825 +       [ __NR_clock_gettime ] = sys_clock_gettime,
10826 +       [ __NR_clock_getres ] = sys_clock_getres,
10827 +       [ __NR_clock_nanosleep ] = sys_clock_nanosleep,
10828 +       [ __NR_statfs64 ] = sys_statfs64,
10829 +       [ __NR_fstatfs64 ] = sys_fstatfs64,
10830 +       [ __NR_tgkill ] = sys_tgkill,
10831 +       [ __NR_utimes ] = sys_utimes,
10832 +       [ __NR_fadvise64_64 ] = sys_fadvise64_64,
10833 +       [ __NR_vserver ] = sys_ni_syscall,
10834  
10835         ARCH_SYSCALLS
10836         [ LAST_SYSCALL + 1 ... NR_syscalls ] = 
10837 diff -Naur a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
10838 --- a/arch/um/kernel/sysrq.c    2004-01-08 22:18:31.000000000 -0500
10839 +++ b/arch/um/kernel/sysrq.c    2004-01-08 22:24:21.000000000 -0500
10840 @@ -55,6 +55,14 @@
10841         show_trace((unsigned long *)esp);
10842  }
10843  
10844 +void show_stack(struct task_struct *task, unsigned long *sp)
10845 +{
10846 +       if(task)
10847 +               show_trace_task(task);
10848 +       else
10849 +               show_trace(sp);
10850 +}
10851 +
10852  /*
10853   * Overrides for Emacs so that we follow Linus's tabbing style.
10854   * Emacs will notice this stuff at the end of the file and automatically
10855 diff -Naur a/arch/um/kernel/tempfile.c b/arch/um/kernel/tempfile.c
10856 --- a/arch/um/kernel/tempfile.c 2004-01-08 22:22:40.000000000 -0500
10857 +++ b/arch/um/kernel/tempfile.c 2004-01-08 22:29:35.000000000 -0500
10858 @@ -28,6 +28,7 @@
10859         }
10860         if((dir == NULL) || (*dir == '\0')) 
10861                 dir = "/tmp";
10862 +
10863         tempdir = malloc(strlen(dir) + 2);
10864         if(tempdir == NULL){
10865                 fprintf(stderr, "Failed to malloc tempdir, "
10866 @@ -49,7 +50,8 @@
10867         else
10868                 *tempname = 0;
10869         strcat(tempname, template);
10870 -       if((fd = mkstemp(tempname)) < 0){
10871 +       fd = mkstemp(tempname);
10872 +       if(fd < 0){
10873                 fprintf(stderr, "open - cannot create %s: %s\n", tempname, 
10874                         strerror(errno));
10875                 return -1;
10876 @@ -59,7 +61,8 @@
10877                 return -1;
10878         }
10879         if(out_tempname){
10880 -               if((*out_tempname = strdup(tempname)) == NULL){
10881 +               *out_tempname = strdup(tempname);
10882 +               if(*out_tempname == NULL){
10883                         perror("strdup");
10884                         return -1;
10885                 }
10886 diff -Naur a/arch/um/kernel/time.c b/arch/um/kernel/time.c
10887 --- a/arch/um/kernel/time.c     2004-01-08 22:16:05.000000000 -0500
10888 +++ b/arch/um/kernel/time.c     2004-01-08 22:21:46.000000000 -0500
10889 @@ -4,24 +4,33 @@
10890   */
10891  
10892  #include <stdio.h>
10893 +#include <stdlib.h>
10894  #include <unistd.h>
10895  #include <time.h>
10896  #include <sys/time.h>
10897  #include <signal.h>
10898  #include <errno.h>
10899 -#include "linux/module.h"
10900  #include "user_util.h"
10901  #include "kern_util.h"
10902  #include "user.h"
10903  #include "process.h"
10904  #include "signal_user.h"
10905  #include "time_user.h"
10906 +#include "kern_constants.h"
10907 +
10908 +/* XXX This really needs to be declared and initialized in a kernel file since 
10909 + * it's in <linux/time.h>
10910 + */
10911 +extern struct timespec wall_to_monotonic;
10912  
10913  extern struct timeval xtime;
10914  
10915 +struct timeval local_offset = { 0, 0 };
10916 +
10917  void timer(void)
10918  {
10919         gettimeofday(&xtime, NULL);
10920 +       timeradd(&xtime, &local_offset, &xtime);
10921  }
10922  
10923  void set_interval(int timer_type)
10924 @@ -66,7 +75,7 @@
10925                        errno);
10926  }
10927  
10928 -void idle_timer(void)
10929 +void uml_idle_timer(void)
10930  {
10931         if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
10932                 panic("Couldn't unset SIGVTALRM handler");
10933 @@ -76,14 +85,54 @@
10934         set_interval(ITIMER_REAL);
10935  }
10936  
10937 +static unsigned long long get_host_hz(void)
10938 +{
10939 +       char mhzline[16], *end;
10940 +       int ret, mult, mhz, rest, len;
10941 +
10942 +       ret = cpu_feature("cpu MHz", mhzline, 
10943 +                         sizeof(mhzline) / sizeof(mhzline[0]));
10944 +       if(!ret)
10945 +               panic ("Could not get host MHZ");
10946 +
10947 +       mhz = strtoul(mhzline, &end, 10);
10948 +
10949 +       /* This business is to parse a floating point number without using
10950 +        * floating types.
10951 +        */
10952 +
10953 +       rest = 0;
10954 +       mult = 0;
10955 +       if(*end == '.'){
10956 +               end++;
10957 +               len = strlen(end);
10958 +               if(len < 6)
10959 +                       mult = 6 - len;
10960 +               else if(len > 6)
10961 +                       end[6] = '\0';
10962 +               rest = strtoul(end, NULL, 10);
10963 +               while(mult-- > 0)
10964 +                       rest *= 10;
10965 +       }
10966 +
10967 +       return(1000000 * mhz + rest);
10968 +}
10969 +
10970 +unsigned long long host_hz = 0;
10971 +
10972  void time_init(void)
10973  {
10974 +       struct timespec now;
10975
10976 +       host_hz = get_host_hz();
10977         if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
10978                 panic("Couldn't set SIGVTALRM handler");
10979         set_interval(ITIMER_VIRTUAL);
10980 -}
10981  
10982 -struct timeval local_offset = { 0, 0 };
10983 +       do_posix_clock_monotonic_gettime(&now);
10984 +       wall_to_monotonic.tv_sec = -now.tv_sec;
10985 +       wall_to_monotonic.tv_nsec = -now.tv_nsec;
10986 +}
10987  
10988  void do_gettimeofday(struct timeval *tv)
10989  {
10990 @@ -95,15 +144,13 @@
10991         time_unlock(flags);
10992  }
10993  
10994 -EXPORT_SYMBOL(do_gettimeofday);
10995 -
10996  int do_settimeofday(struct timespec *tv)
10997  {
10998         struct timeval now;
10999         unsigned long flags;
11000         struct timeval tv_in;
11001  
11002 -       if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
11003 +       if ((unsigned long) tv->tv_nsec >= UM_NSEC_PER_SEC)
11004                 return -EINVAL;
11005  
11006         tv_in.tv_sec = tv->tv_sec;
11007 @@ -113,9 +160,9 @@
11008         gettimeofday(&now, NULL);
11009         timersub(&tv_in, &now, &local_offset);
11010         time_unlock(flags);
11011 -}
11012  
11013 -EXPORT_SYMBOL(do_settimeofday);
11014 +       return(0);
11015 +}
11016  
11017  void idle_sleep(int secs)
11018  {
11019 diff -Naur a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
11020 --- a/arch/um/kernel/time_kern.c        2004-01-08 22:24:10.000000000 -0500
11021 +++ b/arch/um/kernel/time_kern.c        2004-01-08 22:31:27.000000000 -0500
11022 @@ -30,6 +30,14 @@
11023         return(HZ);
11024  }
11025  
11026 +/*
11027 + * Scheduler clock - returns current time in nanosec units.
11028 + */
11029 +unsigned long long sched_clock(void)
11030 +{
11031 +       return (unsigned long long)jiffies_64 * (1000000000 / HZ);
11032 +}
11033 +
11034  /* Changed at early boot */
11035  int timer_irq_inited = 0;
11036  
11037 @@ -39,13 +47,47 @@
11038   */
11039  int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS];
11040  
11041 +static int first_tick;
11042 +static unsigned long long prev_tsc;
11043 +static long long delta;                /* Deviation per interval */
11044 +
11045 +extern unsigned long long host_hz;
11046 +
11047  void timer_irq(union uml_pt_regs *regs)
11048  {
11049 -       int cpu = current->thread_info->cpu, ticks = missed_ticks[cpu];
11050 +       unsigned long long ticks = 0;
11051 +
11052 +       if(!timer_irq_inited){
11053 +               /* This is to ensure that ticks don't pile up when
11054 +                * the timer handler is suspended */
11055 +               first_tick = 0;
11056 +               return;
11057 +       }
11058 +
11059 +       if(first_tick){
11060 +#if defined(CONFIG_UML_REAL_TIME_CLOCK)
11061 +               unsigned long long tsc;
11062 +               /* We've had 1 tick */
11063 +               tsc = time_stamp();
11064 +
11065 +               delta += tsc - prev_tsc;
11066 +               prev_tsc = tsc;
11067 +
11068 +               ticks += (delta * HZ) / host_hz;
11069 +               delta -= (ticks * host_hz) / HZ;
11070 +#else
11071 +               ticks = 1;
11072 +#endif
11073 +       }
11074 +       else {
11075 +               prev_tsc = time_stamp();
11076 +               first_tick = 1;
11077 +       }
11078  
11079 -        if(!timer_irq_inited) return;
11080 -       missed_ticks[cpu] = 0;
11081 -       while(ticks--) do_IRQ(TIMER_IRQ, regs);
11082 +       while(ticks > 0){
11083 +               do_IRQ(TIMER_IRQ, regs);
11084 +               ticks--;
11085 +       }
11086  }
11087  
11088  void boot_timer_handler(int sig)
11089 @@ -58,12 +100,13 @@
11090         do_timer(&regs);
11091  }
11092  
11093 -void um_timer(int irq, void *dev, struct pt_regs *regs)
11094 +irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
11095  {
11096         do_timer(regs);
11097 -       write_seqlock(&xtime_lock);
11098 +       write_seqlock_irq(&xtime_lock);
11099         timer();
11100 -       write_sequnlock(&xtime_lock);
11101 +       write_sequnlock_irq(&xtime_lock);
11102 +       return(IRQ_HANDLED);
11103  }
11104  
11105  long um_time(int * tloc)
11106 @@ -81,12 +124,12 @@
11107  long um_stime(int * tptr)
11108  {
11109         int value;
11110 -       struct timeval new;
11111 +       struct timespec new;
11112  
11113         if (get_user(value, tptr))
11114                  return -EFAULT;
11115         new.tv_sec = value;
11116 -       new.tv_usec = 0;
11117 +       new.tv_nsec = 0;
11118         do_settimeofday(&new);
11119         return 0;
11120  }
11121 @@ -125,9 +168,11 @@
11122  void timer_handler(int sig, union uml_pt_regs *regs)
11123  {
11124  #ifdef CONFIG_SMP
11125 +       local_irq_disable();
11126         update_process_times(user_context(UPT_SP(regs)));
11127 +       local_irq_enable();
11128  #endif
11129 -       if(current->thread_info->cpu == 0)
11130 +       if(current_thread->cpu == 0)
11131                 timer_irq(regs);
11132  }
11133  
11134 @@ -136,6 +181,7 @@
11135  unsigned long time_lock(void)
11136  {
11137         unsigned long flags;
11138 +
11139         spin_lock_irqsave(&timer_spinlock, flags);
11140         return(flags);
11141  }
11142 @@ -150,8 +196,8 @@
11143         int err;
11144  
11145         CHOOSE_MODE(user_time_init_tt(), user_time_init_skas());
11146 -       if((err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", 
11147 -                             NULL)) != 0)
11148 +       err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL);
11149 +       if(err != 0)
11150                 printk(KERN_ERR "timer_init : request_irq failed - "
11151                        "errno = %d\n", -err);
11152         timer_irq_inited = 1;
11153 @@ -160,7 +206,6 @@
11154  
11155  __initcall(timer_init);
11156  
11157 -
11158  /*
11159   * Overrides for Emacs so that we follow Linus's tabbing style.
11160   * Emacs will notice this stuff at the end of the file and automatically
11161 diff -Naur a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
11162 --- a/arch/um/kernel/trap_kern.c        2004-01-08 22:13:51.000000000 -0500
11163 +++ b/arch/um/kernel/trap_kern.c        2004-01-08 22:18:52.000000000 -0500
11164 @@ -16,12 +16,15 @@
11165  #include "asm/tlbflush.h"
11166  #include "asm/a.out.h"
11167  #include "asm/current.h"
11168 +#include "asm/irq.h"
11169  #include "user_util.h"
11170  #include "kern_util.h"
11171  #include "kern.h"
11172  #include "chan_kern.h"
11173  #include "mconsole_kern.h"
11174  #include "2_5compat.h"
11175 +#include "mem.h"
11176 +#include "mem_kern.h"
11177  
11178  int handle_page_fault(unsigned long address, unsigned long ip, 
11179                       int is_write, int is_user, int *code_out)
11180 @@ -51,12 +54,12 @@
11181         if(is_write && !(vma->vm_flags & VM_WRITE)) 
11182                 goto out;
11183         page = address & PAGE_MASK;
11184 -       if(page == (unsigned long) current->thread_info + PAGE_SIZE)
11185 +       if(page == (unsigned long) current_thread + PAGE_SIZE)
11186                 panic("Kernel stack overflow");
11187         pgd = pgd_offset(mm, page);
11188         pmd = pmd_offset(pgd, page);
11189 - survive:
11190         do {
11191 + survive:
11192                 switch (handle_mm_fault(mm, vma, address, is_write)){
11193                 case VM_FAULT_MINOR:
11194                         current->min_flt++;
11195 @@ -71,14 +74,20 @@
11196                         err = -ENOMEM;
11197                         goto out_of_memory;
11198                 default:
11199 -                       BUG();
11200 +                       if (current->pid == 1) {
11201 +                               up_read(&mm->mmap_sem);
11202 +                               yield();
11203 +                               down_read(&mm->mmap_sem);
11204 +                               goto survive;
11205 +                       }
11206 +                       goto out;
11207                 }
11208                 pte = pte_offset_kernel(pmd, page);
11209         } while(!pte_present(*pte));
11210 +       err = 0;
11211         *pte = pte_mkyoung(*pte);
11212         if(pte_write(*pte)) *pte = pte_mkdirty(*pte);
11213         flush_tlb_page(vma, page);
11214 -       err = 0;
11215   out:
11216         up_read(&mm->mmap_sem);
11217         return(err);
11218 @@ -98,6 +107,33 @@
11219         goto out;
11220  }
11221  
11222 +LIST_HEAD(physmem_remappers);
11223 +
11224 +void register_remapper(struct remapper *info)
11225 +{
11226 +       list_add(&info->list, &physmem_remappers);
11227 +}
11228 +
11229 +static int check_remapped_addr(unsigned long address, int is_write)
11230 +{
11231 +       struct remapper *remapper;
11232 +       struct list_head *ele;
11233 +       __u64 offset;
11234 +       int fd;
11235 +
11236 +       fd = phys_mapping(__pa(address), &offset);
11237 +       if(fd == -1)
11238 +               return(0);
11239 +
11240 +       list_for_each(ele, &physmem_remappers){
11241 +               remapper = list_entry(ele, struct remapper, list);
11242 +               if((*remapper->proc)(fd, address, is_write, offset))
11243 +                       return(1);
11244 +       }
11245 +
11246 +       return(0);
11247 +}
11248 +
11249  unsigned long segv(unsigned long address, unsigned long ip, int is_write, 
11250                    int is_user, void *sc)
11251  {
11252 @@ -109,7 +145,9 @@
11253                  flush_tlb_kernel_vm();
11254                  return(0);
11255          }
11256 -        if(current->mm == NULL)
11257 +       else if(check_remapped_addr(address & PAGE_MASK, is_write))
11258 +               return(0);
11259 +       else if(current->mm == NULL)
11260                 panic("Segfault with no mm");
11261         err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
11262  
11263 @@ -120,9 +158,8 @@
11264                 current->thread.fault_addr = (void *) address;
11265                 do_longjmp(catcher, 1);
11266         } 
11267 -       else if(current->thread.fault_addr != NULL){
11268 +       else if(current->thread.fault_addr != NULL)
11269                 panic("fault_addr set but no fault catcher");
11270 -       }
11271         else if(arch_fixup(ip, sc))
11272                 return(0);
11273  
11274 @@ -155,8 +192,6 @@
11275  {
11276         struct siginfo si;
11277  
11278 -       printk(KERN_ERR "Unfixable SEGV in '%s' (pid %d) at 0x%lx "
11279 -              "(ip 0x%lx)\n", current->comm, current->pid, address, ip);
11280         si.si_signo = SIGSEGV;
11281         si.si_code = SEGV_ACCERR;
11282         si.si_addr = (void *) address;
11283 @@ -180,6 +215,11 @@
11284         else relay_signal(sig, regs);
11285  }
11286  
11287 +void winch(int sig, union uml_pt_regs *regs)
11288 +{
11289 +       do_IRQ(WINCH_IRQ, regs);
11290 +}
11291 +
11292  void trap_init(void)
11293  {
11294  }
11295 diff -Naur a/arch/um/kernel/trap_user.c b/arch/um/kernel/trap_user.c
11296 --- a/arch/um/kernel/trap_user.c        2004-01-08 22:20:37.000000000 -0500
11297 +++ b/arch/um/kernel/trap_user.c        2004-01-08 22:27:07.000000000 -0500
11298 @@ -5,11 +5,9 @@
11299  
11300  #include <stdlib.h>
11301  #include <errno.h>
11302 -#include <fcntl.h>
11303  #include <setjmp.h>
11304  #include <signal.h>
11305  #include <sys/time.h>
11306 -#include <sys/ioctl.h>
11307  #include <sys/ptrace.h>
11308  #include <sys/wait.h>
11309  #include <asm/page.h>
11310 @@ -82,6 +80,8 @@
11311                      .is_irq            = 0 },
11312         [ SIGILL ] { .handler           = relay_signal,
11313                      .is_irq            = 0 },
11314 +       [ SIGWINCH ] { .handler         = winch,
11315 +                      .is_irq          = 1 },
11316         [ SIGBUS ] { .handler           = bus_handler,
11317                      .is_irq            = 0 },
11318         [ SIGSEGV] { .handler           = segv_handler,
11319 @@ -123,7 +123,7 @@
11320  {
11321         jmp_buf *buf = b;
11322  
11323 -       longjmp(*buf, val);
11324 +       siglongjmp(*buf, val);
11325  }
11326  
11327  /*
11328 diff -Naur a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c
11329 --- a/arch/um/kernel/tt/exec_kern.c     2004-01-08 22:16:01.000000000 -0500
11330 +++ b/arch/um/kernel/tt/exec_kern.c     2004-01-08 22:21:37.000000000 -0500
11331 @@ -17,6 +17,7 @@
11332  #include "mem_user.h"
11333  #include "os.h"
11334  #include "tlb.h"
11335 +#include "mode.h"
11336  
11337  static int exec_tramp(void *sig_stack)
11338  {
11339 @@ -47,17 +48,17 @@
11340                 do_exit(SIGKILL);
11341         }
11342  
11343 -       if(current->thread_info->cpu == 0)
11344 +       if(current_thread->cpu == 0)
11345                 forward_interrupts(new_pid);
11346         current->thread.request.op = OP_EXEC;
11347         current->thread.request.u.exec.pid = new_pid;
11348 -       unprotect_stack((unsigned long) current->thread_info);
11349 +       unprotect_stack((unsigned long) current_thread);
11350         os_usr1_process(os_getpid());
11351  
11352         enable_timer();
11353         free_page(stack);
11354         protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
11355 -       task_protections((unsigned long) current->thread_info);
11356 +       task_protections((unsigned long) current_thread);
11357         force_flush_all();
11358         unblock_signals();
11359  }
11360 diff -Naur a/arch/um/kernel/tt/include/mode.h b/arch/um/kernel/tt/include/mode.h
11361 --- a/arch/um/kernel/tt/include/mode.h  2004-01-08 22:24:28.000000000 -0500
11362 +++ b/arch/um/kernel/tt/include/mode.h  2004-01-08 22:32:04.000000000 -0500
11363 @@ -8,6 +8,8 @@
11364  
11365  #include "sysdep/ptrace.h"
11366  
11367 +enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
11368 +
11369  extern int tracing_pid;
11370  
11371  extern int tracer(int (*init_proc)(void *), void *sp);
11372 diff -Naur a/arch/um/kernel/tt/include/uaccess.h b/arch/um/kernel/tt/include/uaccess.h
11373 --- a/arch/um/kernel/tt/include/uaccess.h       2004-01-08 22:24:32.000000000 -0500
11374 +++ b/arch/um/kernel/tt/include/uaccess.h       2004-01-08 22:32:07.000000000 -0500
11375 @@ -1,5 +1,5 @@
11376  /* 
11377 - * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
11378 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
11379   * Licensed under the GPL
11380   */
11381  
11382 @@ -43,65 +43,19 @@
11383  
11384  extern int __do_copy_from_user(void *to, const void *from, int n,
11385                                void **fault_addr, void **fault_catcher);
11386 -
11387 -static inline int copy_from_user_tt(void *to, const void *from, int n)
11388 -{
11389 -       return(access_ok_tt(VERIFY_READ, from, n) ?
11390 -              __do_copy_from_user(to, from, n, 
11391 -                                  &current->thread.fault_addr,
11392 -                                  &current->thread.fault_catcher) : n);
11393 -}
11394 -
11395 -static inline int copy_to_user_tt(void *to, const void *from, int n)
11396 -{
11397 -       return(access_ok_tt(VERIFY_WRITE, to, n) ?
11398 -              __do_copy_to_user(to, from, n, 
11399 -                                  &current->thread.fault_addr,
11400 -                                  &current->thread.fault_catcher) : n);
11401 -}
11402 -
11403  extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
11404                                   void **fault_addr, void **fault_catcher);
11405 -
11406 -static inline int strncpy_from_user_tt(char *dst, const char *src, int count)
11407 -{
11408 -       int n;
11409 -
11410 -       if(!access_ok_tt(VERIFY_READ, src, 1)) return(-EFAULT);
11411 -       n = __do_strncpy_from_user(dst, src, count, 
11412 -                                  &current->thread.fault_addr,
11413 -                                  &current->thread.fault_catcher);
11414 -       if(n < 0) return(-EFAULT);
11415 -       return(n);
11416 -}
11417 -
11418  extern int __do_clear_user(void *mem, size_t len, void **fault_addr,
11419                            void **fault_catcher);
11420 -
11421 -static inline int __clear_user_tt(void *mem, int len)
11422 -{
11423 -       return(__do_clear_user(mem, len,
11424 -                              &current->thread.fault_addr,
11425 -                              &current->thread.fault_catcher));
11426 -}
11427 -
11428 -static inline int clear_user_tt(void *mem, int len)
11429 -{
11430 -       return(access_ok_tt(VERIFY_WRITE, mem, len) ? 
11431 -              __do_clear_user(mem, len, 
11432 -                              &current->thread.fault_addr,
11433 -                              &current->thread.fault_catcher) : len);
11434 -}
11435 -
11436  extern int __do_strnlen_user(const char *str, unsigned long n,
11437                              void **fault_addr, void **fault_catcher);
11438  
11439 -static inline int strnlen_user_tt(const void *str, int len)
11440 -{
11441 -       return(__do_strnlen_user(str, len,
11442 -                                &current->thread.fault_addr,
11443 -                                &current->thread.fault_catcher));
11444 -}
11445 +extern int copy_from_user_tt(void *to, const void *from, int n);
11446 +extern int copy_to_user_tt(void *to, const void *from, int n);
11447 +extern int strncpy_from_user_tt(char *dst, const char *src, int count);
11448 +extern int __clear_user_tt(void *mem, int len);
11449 +extern int clear_user_tt(void *mem, int len);
11450 +extern int strnlen_user_tt(const void *str, int len);
11451  
11452  #endif
11453  
11454 diff -Naur a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile
11455 --- a/arch/um/kernel/tt/Makefile        2004-01-08 22:21:51.000000000 -0500
11456 +++ b/arch/um/kernel/tt/Makefile        2004-01-08 22:28:40.000000000 -0500
11457 @@ -1,5 +1,5 @@
11458  # 
11459 -# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
11460 +# Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
11461  # Licensed under the GPL
11462  #
11463  
11464 @@ -7,7 +7,7 @@
11465  
11466  obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
11467         syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \
11468 -       uaccess_user.o sys-$(SUBARCH)/
11469 +       uaccess.o uaccess_user.o sys-$(SUBARCH)/
11470  
11471  obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/
11472  
11473 diff -Naur a/arch/um/kernel/tt/mem_user.c b/arch/um/kernel/tt/mem_user.c
11474 --- a/arch/um/kernel/tt/mem_user.c      2004-01-08 22:17:23.000000000 -0500
11475 +++ b/arch/um/kernel/tt/mem_user.c      2004-01-08 22:23:10.000000000 -0500
11476 @@ -25,14 +25,13 @@
11477         size = (unsigned long) segment_end - 
11478                 (unsigned long) segment_start;
11479         data = create_mem_file(size);
11480 -       if((addr = mmap(NULL, size, PROT_WRITE | PROT_READ, 
11481 -                       MAP_SHARED, data, 0)) == MAP_FAILED){
11482 +       addr = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, data, 0);
11483 +       if(addr == MAP_FAILED){
11484                 perror("mapping new data segment");
11485                 exit(1);
11486         }
11487         memcpy(addr, segment_start, size);
11488 -       if(switcheroo(data, prot, addr, segment_start, 
11489 -                     size) < 0){
11490 +       if(switcheroo(data, prot, addr, segment_start, size) < 0){
11491                 printf("switcheroo failed\n");
11492                 exit(1);
11493         }
11494 diff -Naur a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
11495 --- a/arch/um/kernel/tt/process_kern.c  2004-01-08 22:28:38.000000000 -0500
11496 +++ b/arch/um/kernel/tt/process_kern.c  2004-01-08 22:34:56.000000000 -0500
11497 @@ -62,7 +62,7 @@
11498         reading = 0;
11499         err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
11500         if(err != sizeof(c))
11501 -               panic("write of switch_pipe failed, errno = %d", -err);
11502 +               panic("write of switch_pipe failed, err = %d", -err);
11503  
11504         reading = 1;
11505         if((from->state == TASK_ZOMBIE) || (from->state == TASK_DEAD))
11506 @@ -104,48 +104,72 @@
11507  
11508  void release_thread_tt(struct task_struct *task)
11509  {
11510 -       os_kill_process(task->thread.mode.tt.extern_pid, 0);
11511 +       int pid = task->thread.mode.tt.extern_pid;
11512 +
11513 +       if(os_getpid() != pid)
11514 +               os_kill_process(pid, 0);
11515  }
11516  
11517  void exit_thread_tt(void)
11518  {
11519 -       close(current->thread.mode.tt.switch_pipe[0]);
11520 -       close(current->thread.mode.tt.switch_pipe[1]);
11521 +       os_close_file(current->thread.mode.tt.switch_pipe[0]);
11522 +       os_close_file(current->thread.mode.tt.switch_pipe[1]);
11523  }
11524  
11525  void schedule_tail(task_t *prev);
11526  
11527  static void new_thread_handler(int sig)
11528  {
11529 +       unsigned long disable;
11530         int (*fn)(void *);
11531         void *arg;
11532  
11533         fn = current->thread.request.u.thread.proc;
11534         arg = current->thread.request.u.thread.arg;
11535 +
11536         UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
11537 +       disable = (1 << (SIGVTALRM - 1)) | (1 << (SIGALRM - 1)) |
11538 +               (1 << (SIGIO - 1)) | (1 << (SIGPROF - 1));
11539 +       SC_SIGMASK(UPT_SC(&current->thread.regs.regs)) &= ~disable;
11540 +
11541         suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
11542  
11543 -       block_signals();
11544 +       force_flush_all();
11545 +       if(current->thread.prev_sched != NULL)
11546 +               schedule_tail(current->thread.prev_sched);
11547 +       current->thread.prev_sched = NULL;
11548 +
11549         init_new_thread_signals(1);
11550 -#ifdef CONFIG_SMP
11551 -       schedule_tail(current->thread.prev_sched);
11552 -#endif
11553         enable_timer();
11554         free_page(current->thread.temp_stack);
11555         set_cmdline("(kernel thread)");
11556 -       force_flush_all();
11557  
11558 -       current->thread.prev_sched = NULL;
11559         change_sig(SIGUSR1, 1);
11560         change_sig(SIGVTALRM, 1);
11561         change_sig(SIGPROF, 1);
11562 -       unblock_signals();
11563 +       local_irq_enable();
11564         if(!run_kernel_thread(fn, arg, &current->thread.exec_buf))
11565                 do_exit(0);
11566  }
11567  
11568  static int new_thread_proc(void *stack)
11569  {
11570 +       /* local_irq_disable is needed to block out signals until this thread is
11571 +        * properly scheduled.  Otherwise, the tracing thread will get mighty 
11572 +        * upset about any signals that arrive before that.  
11573 +        * This has the complication that it sets the saved signal mask in
11574 +        * the sigcontext to block signals.  This gets restored when this
11575 +        * thread (or a descendant, since they get a copy of this sigcontext)
11576 +        * returns to userspace.
11577 +        * So, this is compensated for elsewhere.
11578 +        * XXX There is still a small window until local_irq_disable() actually 
11579 +        * finishes where signals are possible - shouldn't be a problem in 
11580 +        * practice since SIGIO hasn't been forwarded here yet, and the 
11581 +        * local_irq_disable should finish before a SIGVTALRM has time to be 
11582 +        * delivered.
11583 +        */
11584 +
11585 +       local_irq_disable();
11586         init_new_thread_stack(stack, new_thread_handler);
11587         os_usr1_process(os_getpid());
11588         return(0);
11589 @@ -156,7 +180,7 @@
11590   * itself with a SIGUSR1.  set_user_mode has to be run with SIGUSR1 off,
11591   * so it is blocked before it's called.  They are re-enabled on sigreturn
11592   * despite the fact that they were blocked when the SIGUSR1 was issued because
11593 - * copy_thread copies the parent's signcontext, including the signal mask
11594 + * copy_thread copies the parent's sigcontext, including the signal mask
11595   * onto the signal frame.
11596   */
11597  
11598 @@ -165,35 +189,32 @@
11599         UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
11600         suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
11601  
11602 -#ifdef CONFIG_SMP      
11603 -       schedule_tail(NULL);
11604 -#endif
11605 +       force_flush_all();
11606 +       if(current->thread.prev_sched != NULL)
11607 +               schedule_tail(current->thread.prev_sched);
11608 +       current->thread.prev_sched = NULL;
11609 +
11610         enable_timer();
11611         change_sig(SIGVTALRM, 1);
11612         local_irq_enable();
11613 -       force_flush_all();
11614         if(current->mm != current->parent->mm)
11615                 protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 
11616                                1, 0, 1);
11617 -       task_protections((unsigned long) current->thread_info);
11618 -
11619 -       current->thread.prev_sched = NULL;
11620 +       task_protections((unsigned long) current_thread);
11621  
11622         free_page(current->thread.temp_stack);
11623 +       local_irq_disable();
11624         change_sig(SIGUSR1, 0);
11625         set_user_mode(current);
11626  }
11627  
11628 -static int sigusr1 = SIGUSR1;
11629 -
11630  int fork_tramp(void *stack)
11631  {
11632 -       int sig = sigusr1;
11633 -
11634         local_irq_disable();
11635 +       arch_init_thread();
11636         init_new_thread_stack(stack, finish_fork_handler);
11637  
11638 -       kill(os_getpid(), sig);
11639 +       os_usr1_process(os_getpid());
11640         return(0);
11641  }
11642  
11643 @@ -213,8 +234,8 @@
11644         }
11645  
11646         err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1);
11647 -       if(err){
11648 -               printk("copy_thread : pipe failed, errno = %d\n", -err);
11649 +       if(err < 0){
11650 +               printk("copy_thread : pipe failed, err = %d\n", -err);
11651                 return(err);
11652         }
11653  
11654 @@ -377,8 +398,8 @@
11655  
11656         pages = (1 << CONFIG_KERNEL_STACK_ORDER);
11657  
11658 -       start = (unsigned long) current->thread_info + PAGE_SIZE;
11659 -       end = (unsigned long) current + PAGE_SIZE * pages;
11660 +       start = (unsigned long) current_thread + PAGE_SIZE;
11661 +       end = (unsigned long) current_thread + PAGE_SIZE * pages;
11662         protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1);
11663         protect_memory(end, high_physmem - end, 1, w, 1, 1);
11664  
11665 @@ -454,8 +475,9 @@
11666  
11667         init_task.thread.mode.tt.extern_pid = pid;
11668         err = os_pipe(init_task.thread.mode.tt.switch_pipe, 1, 1);
11669 -       if(err) panic("Can't create switch pipe for init_task, errno = %d", 
11670 -                     err);
11671 +       if(err) 
11672 +               panic("Can't create switch pipe for init_task, errno = %d", 
11673 +                     -err);
11674  }
11675  
11676  int singlestepping_tt(void *t)
11677 diff -Naur a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c
11678 --- a/arch/um/kernel/tt/ptproxy/proxy.c 2004-01-08 22:23:52.000000000 -0500
11679 +++ b/arch/um/kernel/tt/ptproxy/proxy.c 2004-01-08 22:31:01.000000000 -0500
11680 @@ -15,7 +15,6 @@
11681  #include <unistd.h>
11682  #include <signal.h>
11683  #include <string.h>
11684 -#include <fcntl.h>
11685  #include <termios.h>
11686  #include <sys/wait.h>
11687  #include <sys/types.h>
11688 @@ -293,10 +292,10 @@
11689  }
11690  
11691  char gdb_init_string[] = 
11692 -"att 1
11693 -b panic
11694 -b stop
11695 -handle SIGWINCH nostop noprint pass
11696 +"att 1 \n\
11697 +b panic \n\
11698 +b stop \n\
11699 +handle SIGWINCH nostop noprint pass \n\
11700  ";
11701  
11702  int start_debugger(char *prog, int startup, int stop, int *fd_out)
11703 @@ -304,7 +303,8 @@
11704         int slave, child;
11705  
11706         slave = open_gdb_chan();
11707 -       if((child = fork()) == 0){
11708 +       child = fork();
11709 +       if(child == 0){
11710                 char *tempname = NULL;
11711                 int fd;
11712  
11713 @@ -327,18 +327,19 @@
11714                         exit(1);
11715  #endif
11716                 }
11717 -               if((fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0)) < 0){
11718 -                       printk("start_debugger : make_tempfile failed, errno = %d\n",
11719 -                              errno);
11720 +               fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0);
11721 +               if(fd < 0){
11722 +                       printk("start_debugger : make_tempfile failed,"
11723 +                              "err = %d\n", -fd);
11724                         exit(1);
11725                 }
11726 -               write(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
11727 +               os_write_file(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
11728                 if(startup){
11729                         if(stop){
11730 -                               write(fd, "b start_kernel\n",
11731 +                               os_write_file(fd, "b start_kernel\n",
11732                                       strlen("b start_kernel\n"));
11733                         }
11734 -                       write(fd, "c\n", strlen("c\n"));
11735 +                       os_write_file(fd, "c\n", strlen("c\n"));
11736                 }
11737                 if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
11738                         printk("start_debugger :  PTRACE_TRACEME failed, "
11739 diff -Naur a/arch/um/kernel/tt/ptproxy/sysdep.c b/arch/um/kernel/tt/ptproxy/sysdep.c
11740 --- a/arch/um/kernel/tt/ptproxy/sysdep.c        2004-01-08 22:27:13.000000000 -0500
11741 +++ b/arch/um/kernel/tt/ptproxy/sysdep.c        2004-01-08 22:34:07.000000000 -0500
11742 @@ -9,6 +9,7 @@
11743  #include <string.h>
11744  #include <stdlib.h>
11745  #include <signal.h>
11746 +#include <errno.h>
11747  #include <sys/types.h>
11748  #include <sys/ptrace.h>
11749  #include <asm/ptrace.h>
11750 diff -Naur a/arch/um/kernel/tt/ptproxy/wait.c b/arch/um/kernel/tt/ptproxy/wait.c
11751 --- a/arch/um/kernel/tt/ptproxy/wait.c  2004-01-08 22:29:38.000000000 -0500
11752 +++ b/arch/um/kernel/tt/ptproxy/wait.c  2004-01-08 22:35:16.000000000 -0500
11753 @@ -56,21 +56,23 @@
11754  int real_wait_return(struct debugger *debugger)
11755  {
11756         unsigned long ip;
11757 -       int err, pid;
11758 +       int pid;
11759  
11760         pid = debugger->pid;
11761 +
11762         ip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
11763         ip = IP_RESTART_SYSCALL(ip);
11764 -       err = ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip);
11765 +
11766         if(ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip) < 0)
11767                 tracer_panic("real_wait_return : Failed to restart system "
11768 -                            "call, errno = %d\n");
11769 +                            "call, errno = %d\n", errno);
11770 +
11771         if((ptrace(PTRACE_SYSCALL, debugger->pid, 0, SIGCHLD) < 0) ||
11772            (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
11773            (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
11774            debugger_normal_return(debugger, -1))
11775                 tracer_panic("real_wait_return : gdb failed to wait, "
11776 -                            "errno = %d\n");
11777 +                            "errno = %d\n", errno);
11778         return(0);
11779  }
11780  
11781 diff -Naur a/arch/um/kernel/tt/syscall_kern.c b/arch/um/kernel/tt/syscall_kern.c
11782 --- a/arch/um/kernel/tt/syscall_kern.c  2004-01-08 22:13:31.000000000 -0500
11783 +++ b/arch/um/kernel/tt/syscall_kern.c  2004-01-08 22:17:14.000000000 -0500
11784 @@ -1,5 +1,5 @@
11785  /* 
11786 - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
11787 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
11788   * Licensed under the GPL
11789   */
11790  
11791 diff -Naur a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
11792 --- a/arch/um/kernel/tt/tracer.c        2004-01-08 22:13:44.000000000 -0500
11793 +++ b/arch/um/kernel/tt/tracer.c        2004-01-08 22:18:08.000000000 -0500
11794 @@ -39,16 +39,17 @@
11795                 return(0);
11796  
11797         register_winch_irq(tracer_winch[0], fd, -1, data);
11798 -       return(0);
11799 +       return(1);
11800  }
11801  
11802  static void tracer_winch_handler(int sig)
11803  {
11804 +       int n;
11805         char c = 1;
11806  
11807 -       if(write(tracer_winch[1], &c, sizeof(c)) != sizeof(c))
11808 -               printk("tracer_winch_handler - write failed, errno = %d\n",
11809 -                      errno);
11810 +       n = os_write_file(tracer_winch[1], &c, sizeof(c));
11811 +       if(n != sizeof(c))
11812 +               printk("tracer_winch_handler - write failed, err = %d\n", -n);
11813  }
11814  
11815  /* Called only by the tracing thread during initialization */
11816 @@ -58,9 +59,8 @@
11817         int err;
11818  
11819         err = os_pipe(tracer_winch, 1, 1);
11820 -       if(err){
11821 -               printk("setup_tracer_winch : os_pipe failed, errno = %d\n", 
11822 -                      -err);
11823 +       if(err < 0){
11824 +               printk("setup_tracer_winch : os_pipe failed, err = %d\n", -err);
11825                 return;
11826         }
11827         signal(SIGWINCH, tracer_winch_handler);
11828 @@ -130,8 +130,8 @@
11829         case SIGTSTP:
11830                 if(ptrace(PTRACE_CONT, pid, 0, sig) < 0)
11831                         tracer_panic("sleeping_process_signal : Failed to "
11832 -                                    "continue pid %d, errno = %d\n", pid,
11833 -                                    sig);
11834 +                                    "continue pid %d, signal = %d, "
11835 +                                    "errno = %d\n", pid, sig, errno);
11836                 break;
11837  
11838         /* This happens when the debugger (e.g. strace) is doing system call 
11839 @@ -145,7 +145,7 @@
11840                 if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
11841                         tracer_panic("sleeping_process_signal : Failed to "
11842                                      "PTRACE_SYSCALL pid %d, errno = %d\n",
11843 -                                    pid, sig);
11844 +                                    pid, errno);
11845                 break;
11846         case SIGSTOP:
11847                 break;
11848 @@ -218,7 +218,7 @@
11849                         err = attach(debugger_parent);
11850                         if(err){
11851                                 printf("Failed to attach debugger parent %d, "
11852 -                                      "errno = %d\n", debugger_parent, err);
11853 +                                      "errno = %d\n", debugger_parent, -err);
11854                                 debugger_parent = -1;
11855                         }
11856                         else {
11857 @@ -233,7 +233,8 @@
11858         }
11859         set_cmdline("(tracing thread)");
11860         while(1){
11861 -               if((pid = waitpid(-1, &status, WUNTRACED)) <= 0){
11862 +               pid = waitpid(-1, &status, WUNTRACED);
11863 +               if(pid <= 0){
11864                         if(errno != ECHILD){
11865                                 printf("wait failed - errno = %d\n", errno);
11866                         }
11867 @@ -401,7 +402,7 @@
11868                 
11869                 if(!strcmp(line, "go")) debug_stop = 0;
11870                 else if(!strcmp(line, "parent")) debug_parent = 1;
11871 -               else printk("Unknown debug option : '%s'\n", line);
11872 +               else printf("Unknown debug option : '%s'\n", line);
11873  
11874                 line = next;
11875         }
11876 diff -Naur a/arch/um/kernel/tt/uaccess.c b/arch/um/kernel/tt/uaccess.c
11877 --- a/arch/um/kernel/tt/uaccess.c       1969-12-31 19:00:00.000000000 -0500
11878 +++ b/arch/um/kernel/tt/uaccess.c       2004-01-08 22:18:04.000000000 -0500
11879 @@ -0,0 +1,73 @@
11880 +/* 
11881 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
11882 + * Licensed under the GPL
11883 + */
11884 +
11885 +#include "linux/sched.h"
11886 +#include "asm/uaccess.h"
11887 +
11888 +int copy_from_user_tt(void *to, const void *from, int n)
11889 +{
11890 +       if(!access_ok_tt(VERIFY_READ, from, n)) 
11891 +               return(n);
11892 +
11893 +       return(__do_copy_from_user(to, from, n, &current->thread.fault_addr,
11894 +                                  &current->thread.fault_catcher));
11895 +}
11896 +
11897 +int copy_to_user_tt(void *to, const void *from, int n)
11898 +{
11899 +       if(!access_ok_tt(VERIFY_WRITE, to, n))
11900 +               return(n);
11901 +               
11902 +       return(__do_copy_to_user(to, from, n, &current->thread.fault_addr,
11903 +                                &current->thread.fault_catcher));
11904 +}
11905 +
11906 +int strncpy_from_user_tt(char *dst, const char *src, int count)
11907 +{
11908 +       int n;
11909 +
11910 +       if(!access_ok_tt(VERIFY_READ, src, 1)) 
11911 +               return(-EFAULT);
11912 +
11913 +       n = __do_strncpy_from_user(dst, src, count, 
11914 +                                  &current->thread.fault_addr,
11915 +                                  &current->thread.fault_catcher);
11916 +       if(n < 0) return(-EFAULT);
11917 +       return(n);
11918 +}
11919 +
11920 +int __clear_user_tt(void *mem, int len)
11921 +{
11922 +       return(__do_clear_user(mem, len,
11923 +                              &current->thread.fault_addr,
11924 +                              &current->thread.fault_catcher));
11925 +}
11926 +
11927 +int clear_user_tt(void *mem, int len)
11928 +{
11929 +       if(!access_ok_tt(VERIFY_WRITE, mem, len))
11930 +               return(len);
11931 +
11932 +       return(__do_clear_user(mem, len, &current->thread.fault_addr,
11933 +                              &current->thread.fault_catcher));
11934 +}
11935 +
11936 +int strnlen_user_tt(const void *str, int len)
11937 +{
11938 +       return(__do_strnlen_user(str, len,
11939 +                                &current->thread.fault_addr,
11940 +                                &current->thread.fault_catcher));
11941 +}
11942 +
11943 +/*
11944 + * Overrides for Emacs so that we follow Linus's tabbing style.
11945 + * Emacs will notice this stuff at the end of the file and automatically
11946 + * adjust the settings for this buffer only.  This must remain at the end
11947 + * of the file.
11948 + * ---------------------------------------------------------------------------
11949 + * Local variables:
11950 + * c-file-style: "linux"
11951 + * End:
11952 + */
11953 diff -Naur a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c
11954 --- a/arch/um/kernel/tt/uaccess_user.c  2004-01-08 22:17:56.000000000 -0500
11955 +++ b/arch/um/kernel/tt/uaccess_user.c  2004-01-08 22:24:00.000000000 -0500
11956 @@ -8,15 +8,20 @@
11957  #include <string.h>
11958  #include "user_util.h"
11959  #include "uml_uaccess.h"
11960 +#include "task.h"
11961 +#include "kern_util.h"
11962  
11963  int __do_copy_from_user(void *to, const void *from, int n,
11964                         void **fault_addr, void **fault_catcher)
11965  {
11966 +       struct tt_regs save = TASK_REGS(get_current())->tt;
11967         unsigned long fault;
11968         int faulted;
11969  
11970         fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
11971                                __do_copy, &faulted);
11972 +       TASK_REGS(get_current())->tt = save;
11973 +
11974         if(!faulted) return(0);
11975         else return(n - (fault - (unsigned long) from));
11976  }
11977 @@ -29,11 +34,14 @@
11978  int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
11979                            void **fault_addr, void **fault_catcher)
11980  {
11981 +       struct tt_regs save = TASK_REGS(get_current())->tt;
11982         unsigned long fault;
11983         int faulted;
11984  
11985         fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
11986                                __do_strncpy, &faulted);
11987 +       TASK_REGS(get_current())->tt = save;
11988 +
11989         if(!faulted) return(strlen(dst));
11990         else return(-1);
11991  }
11992 @@ -46,11 +54,14 @@
11993  int __do_clear_user(void *mem, unsigned long len,
11994                     void **fault_addr, void **fault_catcher)
11995  {
11996 +       struct tt_regs save = TASK_REGS(get_current())->tt;
11997         unsigned long fault;
11998         int faulted;
11999  
12000         fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
12001                                __do_clear, &faulted);
12002 +       TASK_REGS(get_current())->tt = save;
12003 +
12004         if(!faulted) return(0);
12005         else return(len - (fault - (unsigned long) mem));
12006  }
12007 @@ -58,19 +69,20 @@
12008  int __do_strnlen_user(const char *str, unsigned long n,
12009                       void **fault_addr, void **fault_catcher)
12010  {
12011 +       struct tt_regs save = TASK_REGS(get_current())->tt;
12012         int ret;
12013         unsigned long *faddrp = (unsigned long *)fault_addr;
12014         jmp_buf jbuf;
12015  
12016         *fault_catcher = &jbuf;
12017 -       if(setjmp(jbuf) == 0){
12018 +       if(sigsetjmp(jbuf, 1) == 0)
12019                 ret = strlen(str) + 1;
12020 -       } 
12021 -       else {
12022 -               ret = *faddrp - (unsigned long) str;
12023 -       }
12024 +       else ret = *faddrp - (unsigned long) str;
12025 +
12026         *fault_addr = NULL;
12027         *fault_catcher = NULL;
12028 +
12029 +       TASK_REGS(get_current())->tt = save;
12030         return ret;
12031  }
12032  
12033 diff -Naur a/arch/um/kernel/tty_log.c b/arch/um/kernel/tty_log.c
12034 --- a/arch/um/kernel/tty_log.c  2004-01-08 22:23:59.000000000 -0500
12035 +++ b/arch/um/kernel/tty_log.c  2004-01-08 22:31:12.000000000 -0500
12036 @@ -9,10 +9,10 @@
12037  #include <stdio.h>
12038  #include <stdlib.h>
12039  #include <unistd.h>
12040 -#include <fcntl.h>
12041  #include <sys/time.h>
12042  #include "init.h"
12043  #include "user.h"
12044 +#include "kern_util.h"
12045  #include "os.h"
12046  
12047  #define TTY_LOG_DIR "./"
12048 @@ -24,29 +24,40 @@
12049  #define TTY_LOG_OPEN 1
12050  #define TTY_LOG_CLOSE 2
12051  #define TTY_LOG_WRITE 3
12052 +#define TTY_LOG_EXEC 4
12053 +
12054 +#define TTY_READ 1
12055 +#define TTY_WRITE 2
12056  
12057  struct tty_log_buf {
12058         int what;
12059         unsigned long tty;
12060         int len;
12061 +       int direction;
12062 +       unsigned long sec;
12063 +       unsigned long usec;
12064  };
12065  
12066 -int open_tty_log(void *tty)
12067 +int open_tty_log(void *tty, void *current_tty)
12068  {
12069         struct timeval tv;
12070         struct tty_log_buf data;
12071         char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
12072         int fd;
12073  
12074 +       gettimeofday(&tv, NULL);
12075         if(tty_log_fd != -1){
12076 -               data = ((struct tty_log_buf) { what :   TTY_LOG_OPEN,
12077 -                                              tty : (unsigned long) tty,
12078 -                                              len : 0 });
12079 -               write(tty_log_fd, &data, sizeof(data));
12080 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_OPEN,
12081 +                                              .tty  = (unsigned long) tty,
12082 +                                              .len  = sizeof(current_tty),
12083 +                                              .direction = 0,
12084 +                                              .sec = tv.tv_sec,
12085 +                                              .usec = tv.tv_usec } );
12086 +               os_write_file(tty_log_fd, &data, sizeof(data));
12087 +               os_write_file(tty_log_fd, &current_tty, data.len);
12088                 return(tty_log_fd);
12089         }
12090  
12091 -       gettimeofday(&tv, NULL);
12092         sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, 
12093                 (unsigned int) tv.tv_usec);
12094  
12095 @@ -62,30 +73,117 @@
12096  void close_tty_log(int fd, void *tty)
12097  {
12098         struct tty_log_buf data;
12099 +       struct timeval tv;
12100  
12101         if(tty_log_fd != -1){
12102 -               data = ((struct tty_log_buf) { what :   TTY_LOG_CLOSE,
12103 -                                              tty : (unsigned long) tty,
12104 -                                              len : 0 });
12105 -               write(tty_log_fd, &data, sizeof(data));
12106 +               gettimeofday(&tv, NULL);
12107 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_CLOSE,
12108 +                                              .tty  = (unsigned long) tty,
12109 +                                              .len  = 0,
12110 +                                              .direction = 0,
12111 +                                              .sec = tv.tv_sec,
12112 +                                              .usec = tv.tv_usec } );
12113 +               os_write_file(tty_log_fd, &data, sizeof(data));
12114                 return;
12115         }
12116 -       close(fd);
12117 +       os_close_file(fd);
12118  }
12119  
12120 -int write_tty_log(int fd, char *buf, int len, void *tty)
12121 +static int log_chunk(int fd, const char *buf, int len)
12122  {
12123 +       int total = 0, try, missed, n;
12124 +       char chunk[64];
12125 +
12126 +       while(len > 0){
12127 +               try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
12128 +               missed = copy_from_user_proc(chunk, (char *) buf, try);
12129 +               try -= missed;
12130 +               n = os_write_file(fd, chunk, try);
12131 +               if(n != try) {
12132 +                       if(n < 0) 
12133 +                               return(n);
12134 +                       return(-EIO);
12135 +               }
12136 +               if(missed != 0)
12137 +                       return(-EFAULT);
12138 +
12139 +               len -= try;
12140 +               total += try;
12141 +               buf += try;
12142 +       }
12143 +
12144 +       return(total);
12145 +}
12146 +
12147 +int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
12148 +{
12149 +       struct timeval tv;
12150         struct tty_log_buf data;
12151 +       int direction;
12152  
12153         if(fd == tty_log_fd){
12154 -               data = ((struct tty_log_buf) { what :   TTY_LOG_WRITE,
12155 -                                              tty : (unsigned long) tty,
12156 -                                              len : len });
12157 -               write(tty_log_fd, &data, sizeof(data));
12158 +               gettimeofday(&tv, NULL);
12159 +               direction = is_read ? TTY_READ : TTY_WRITE;
12160 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_WRITE,
12161 +                                              .tty  = (unsigned long) tty,
12162 +                                              .len  = len,
12163 +                                              .direction = direction,
12164 +                                              .sec = tv.tv_sec,
12165 +                                              .usec = tv.tv_usec } );
12166 +               os_write_file(tty_log_fd, &data, sizeof(data));
12167         }
12168 -       return(write(fd, buf, len));
12169 +
12170 +       return(log_chunk(fd, buf, len));
12171  }
12172  
12173 +void log_exec(char **argv, void *tty)
12174 +{
12175 +       struct timeval tv;
12176 +       struct tty_log_buf data;
12177 +       char **ptr,*arg;
12178 +       int len;
12179 +       
12180 +       if(tty_log_fd == -1) return;
12181 +
12182 +       gettimeofday(&tv, NULL);
12183 +
12184 +       len = 0;
12185 +       for(ptr = argv; ; ptr++){
12186 +               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
12187 +                       return;
12188 +               if(arg == NULL) break;
12189 +               len += strlen_user_proc(arg);
12190 +       }
12191 +
12192 +       data = ((struct tty_log_buf) { .what    = TTY_LOG_EXEC,
12193 +                                      .tty  = (unsigned long) tty,
12194 +                                      .len  = len,
12195 +                                      .direction = 0,
12196 +                                      .sec = tv.tv_sec,
12197 +                                      .usec = tv.tv_usec } );
12198 +       os_write_file(tty_log_fd, &data, sizeof(data));
12199 +
12200 +       for(ptr = argv; ; ptr++){
12201 +               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
12202 +                       return;
12203 +               if(arg == NULL) break;
12204 +               log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
12205 +       }
12206 +}
12207 +
12208 +extern void register_tty_logger(int (*opener)(void *, void *),
12209 +                               int (*writer)(int, const char *, int, 
12210 +                                             void *, int),
12211 +                               void (*closer)(int, void *));
12212 +
12213 +static int register_logger(void)
12214 +{
12215 +       register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
12216 +       return(0);
12217 +}
12218 +
12219 +__uml_initcall(register_logger);
12220 +
12221  static int __init set_tty_log_dir(char *name, int *add)
12222  {
12223         tty_log_dir = name;
12224 @@ -104,7 +202,7 @@
12225  
12226         tty_log_fd = strtoul(name, &end, 0);
12227         if((*end != '\0') || (end == name)){
12228 -               printk("set_tty_log_fd - strtoul failed on '%s'\n", name);
12229 +               printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
12230                 tty_log_fd = -1;
12231         }
12232         return 0;
12233 diff -Naur a/arch/um/kernel/uaccess_user.c b/arch/um/kernel/uaccess_user.c
12234 --- a/arch/um/kernel/uaccess_user.c     2004-01-08 22:26:03.000000000 -0500
12235 +++ b/arch/um/kernel/uaccess_user.c     2004-01-08 22:33:46.000000000 -0500
12236 @@ -20,7 +20,7 @@
12237  
12238         jmp_buf jbuf;
12239         *fault_catcher = &jbuf;
12240 -       if(setjmp(jbuf) == 0){
12241 +       if(sigsetjmp(jbuf, 1) == 0){
12242                 (*op)(to, from, n);
12243                 ret = 0;
12244                 *faulted_out = 0;
12245 diff -Naur a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
12246 --- a/arch/um/kernel/um_arch.c  2004-01-08 22:28:03.000000000 -0500
12247 +++ b/arch/um/kernel/um_arch.c  2004-01-08 22:34:23.000000000 -0500
12248 @@ -38,13 +38,18 @@
12249  #include "mode_kern.h"
12250  #include "mode.h"
12251  
12252 -#define DEFAULT_COMMAND_LINE "root=6200"
12253 +#define DEFAULT_COMMAND_LINE "root=98:0"
12254  
12255  struct cpuinfo_um boot_cpu_data = { 
12256         .loops_per_jiffy        = 0,
12257         .ipi_pipe               = { -1, -1 }
12258  };
12259  
12260 +/* Placeholder to make UML link until the vsyscall stuff is actually 
12261 + * implemented
12262 + */
12263 +void *__kernel_vsyscall;
12264 +
12265  unsigned long thread_saved_pc(struct task_struct *task)
12266  {
12267         return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
12268 @@ -53,18 +58,22 @@
12269  
12270  static int show_cpuinfo(struct seq_file *m, void *v)
12271  {
12272 -       int index;
12273 +       int index = 0;
12274  
12275 -       index = (struct cpuinfo_um *)v - cpu_data;
12276  #ifdef CONFIG_SMP
12277 +       index = (struct cpuinfo_um *) v - cpu_data;
12278         if (!cpu_online(index))
12279                 return 0;
12280  #endif
12281  
12282 -       seq_printf(m, "bogomips\t: %lu.%02lu\n",
12283 +       seq_printf(m, "processor\t: %d\n", index);
12284 +       seq_printf(m, "vendor_id\t: User Mode Linux\n");
12285 +       seq_printf(m, "model name\t: UML\n");
12286 +       seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas"));
12287 +       seq_printf(m, "host\t\t: %s\n", host_info);
12288 +       seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
12289                    loops_per_jiffy/(500000/HZ),
12290                    (loops_per_jiffy/(5000/HZ)) % 100);
12291 -       seq_printf(m, "host\t\t: %s\n", host_info);
12292  
12293         return(0);
12294  }
12295 @@ -134,12 +143,12 @@
12296         if(umid != NULL){
12297                 snprintf(argv1_begin, 
12298                          (argv1_end - argv1_begin) * sizeof(*ptr), 
12299 -                        "(%s)", umid);
12300 +                        "(%s) ", umid);
12301                 ptr = &argv1_begin[strlen(argv1_begin)];
12302         }
12303         else ptr = argv1_begin;
12304  
12305 -       snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), " [%s]", cmd);
12306 +       snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
12307         memset(argv1_begin + strlen(argv1_begin), '\0', 
12308                argv1_end - argv1_begin - strlen(argv1_begin));
12309  #endif
12310 @@ -179,7 +188,7 @@
12311  static int __init uml_ncpus_setup(char *line, int *add)
12312  {
12313         if (!sscanf(line, "%d", &ncpus)) {
12314 -               printk("Couldn't parse [%s]\n", line);
12315 +               printf("Couldn't parse [%s]\n", line);
12316                 return -1;
12317         }
12318  
12319 @@ -210,7 +219,7 @@
12320  
12321  static int __init mode_tt_setup(char *line, int *add)
12322  {
12323 -       printk("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
12324 +       printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
12325         return(0);
12326  }
12327  
12328 @@ -221,7 +230,7 @@
12329  
12330  static int __init mode_tt_setup(char *line, int *add)
12331  {
12332 -       printk("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
12333 +       printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
12334         return(0);
12335  }
12336  
12337 @@ -291,7 +300,7 @@
12338  
12339  /* Set during early boot */
12340  unsigned long brk_start;
12341 -static struct vm_reserved kernel_vm_reserved;
12342 +unsigned long end_iomem;
12343  
12344  #define MIN_VMALLOC (32 * 1024 * 1024)
12345  
12346 @@ -299,7 +308,7 @@
12347  {
12348         unsigned long avail;
12349         unsigned long virtmem_size, max_physmem;
12350 -       unsigned int i, add, err;
12351 +       unsigned int i, add;
12352  
12353         for (i = 1; i < argc; i++){
12354                 if((i == 1) && (argv[i][0] == ' ')) continue;
12355 @@ -328,12 +337,16 @@
12356         argv1_end = &argv[1][strlen(argv[1])];
12357  #endif
12358    
12359 -       set_usable_vm(uml_physmem, get_kmem_end());
12360 -
12361         highmem = 0;
12362 -       max_physmem = get_kmem_end() - uml_physmem - MIN_VMALLOC;
12363 -       if(physmem_size > max_physmem){
12364 -               highmem = physmem_size - max_physmem;
12365 +       iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
12366 +       max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC;
12367 +
12368 +       /* Zones have to begin on a 1 << MAX_ORDER page boundary,
12369 +        * so this makes sure that's true for highmem
12370 +        */
12371 +       max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1);
12372 +       if(physmem_size + iomem_size > max_physmem){
12373 +               highmem = physmem_size + iomem_size - max_physmem;
12374                 physmem_size -= highmem;
12375  #ifndef CONFIG_HIGHMEM
12376                 highmem = 0;
12377 @@ -343,11 +356,19 @@
12378         }
12379  
12380         high_physmem = uml_physmem + physmem_size;
12381 -       high_memory = (void *) high_physmem;
12382 +       end_iomem = high_physmem + iomem_size;
12383 +       high_memory = (void *) end_iomem;
12384  
12385         start_vm = VMALLOC_START;
12386  
12387 -       setup_physmem(uml_physmem, uml_reserved, physmem_size);
12388 +       setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
12389 +       if(init_maps(physmem_size, iomem_size, highmem)){
12390 +               printf("Failed to allocate mem_map for %ld bytes of physical "
12391 +                      "memory and %ld bytes of highmem\n", physmem_size,
12392 +                      highmem);
12393 +               exit(1);
12394 +       }
12395 +
12396         virtmem_size = physmem_size;
12397         avail = get_kmem_end() - start_vm;
12398         if(physmem_size > avail) virtmem_size = avail;
12399 @@ -357,18 +378,13 @@
12400                 printf("Kernel virtual memory size shrunk to %ld bytes\n",
12401                        virtmem_size);
12402  
12403 -       err = reserve_vm(high_physmem, end_vm, &kernel_vm_reserved);
12404 -       if(err){
12405 -               printf("Failed to reserve VM area for kernel VM\n");
12406 -               exit(1);
12407 -       }
12408 -
12409         uml_postsetup();
12410  
12411         init_task.thread.kernel_stack = (unsigned long) &init_thread_info + 
12412                 2 * PAGE_SIZE;
12413  
12414         task_protections((unsigned long) &init_thread_info);
12415 +       os_flush_stdout();
12416  
12417         return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
12418  }
12419 @@ -403,6 +419,7 @@
12420         arch_check_bugs();
12421         check_ptrace();
12422         check_sigio();
12423 +       check_devanon();
12424  }
12425  
12426  /*
12427 diff -Naur a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c
12428 --- a/arch/um/kernel/umid.c     2004-01-08 22:30:24.000000000 -0500
12429 +++ b/arch/um/kernel/umid.c     2004-01-08 22:35:37.000000000 -0500
12430 @@ -5,7 +5,6 @@
12431  
12432  #include <stdio.h>
12433  #include <unistd.h>
12434 -#include <fcntl.h>
12435  #include <errno.h>
12436  #include <string.h>
12437  #include <stdlib.h>
12438 @@ -33,18 +32,19 @@
12439  static int umid_is_random = 1;
12440  static int umid_inited = 0;
12441  
12442 -static int make_umid(void);
12443 +static int make_umid(int (*printer)(const char *fmt, ...));
12444  
12445 -static int __init set_umid(char *name, int is_random)
12446 +static int __init set_umid(char *name, int is_random, 
12447 +                          int (*printer)(const char *fmt, ...))
12448  {
12449         if(umid_inited){
12450 -               printk("Unique machine name can't be set twice\n");
12451 +               (*printer)("Unique machine name can't be set twice\n");
12452                 return(-1);
12453         }
12454  
12455         if(strlen(name) > UMID_LEN - 1)
12456 -               printk("Unique machine name is being truncated to %s "
12457 -                      "characters\n", UMID_LEN);
12458 +               (*printer)("Unique machine name is being truncated to %s "
12459 +                          "characters\n", UMID_LEN);
12460         strlcpy(umid, name, sizeof(umid));
12461  
12462         umid_is_random = is_random;
12463 @@ -54,7 +54,7 @@
12464  
12465  static int __init set_umid_arg(char *name, int *add)
12466  {
12467 -       return(set_umid(name, 0));
12468 +       return(set_umid(name, 0, printf));
12469  }
12470  
12471  __uml_setup("umid=", set_umid_arg,
12472 @@ -67,7 +67,7 @@
12473  {
12474         int n;
12475  
12476 -       if(!umid_inited && make_umid()) return(-1);
12477 +       if(!umid_inited && make_umid(printk)) return(-1);
12478  
12479         n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
12480         if(n > len){
12481 @@ -85,22 +85,23 @@
12482  {
12483         char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
12484         char pid[sizeof("nnnnn\0")];
12485 -       int fd;
12486 +       int fd, n;
12487  
12488         if(umid_file_name("pid", file, sizeof(file))) return 0;
12489  
12490         fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 
12491                           0644);
12492         if(fd < 0){
12493 -               printk("Open of machine pid file \"%s\" failed - "
12494 -                      "errno = %d\n", file, -fd);
12495 +               printf("Open of machine pid file \"%s\" failed - "
12496 +                      "err = %d\n", file, -fd);
12497                 return 0;
12498         }
12499  
12500         sprintf(pid, "%d\n", os_getpid());
12501 -       if(write(fd, pid, strlen(pid)) != strlen(pid))
12502 -               printk("Write of pid file failed - errno = %d\n", errno);
12503 -       close(fd);
12504 +       n = os_write_file(fd, pid, strlen(pid));
12505 +       if(n != strlen(pid))
12506 +               printf("Write of pid file failed - err = %d\n", -n);
12507 +       os_close_file(fd);
12508         return 0;
12509  }
12510  
12511 @@ -111,7 +112,8 @@
12512         int len;
12513         char file[256];
12514  
12515 -       if((directory = opendir(dir)) == NULL){
12516 +       directory = opendir(dir);
12517 +       if(directory == NULL){
12518                 printk("actually_do_remove : couldn't open directory '%s', "
12519                        "errno = %d\n", dir, errno);
12520                 return(1);
12521 @@ -160,22 +162,24 @@
12522  {
12523         char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
12524         char pid[sizeof("nnnnn\0")], *end;
12525 -       int dead, fd, p;
12526 +       int dead, fd, p, n;
12527  
12528         sprintf(file, "%s/pid", dir);
12529         dead = 0;
12530 -       if((fd = os_open_file(file, of_read(OPENFLAGS()), 0)) < 0){
12531 +       fd = os_open_file(file, of_read(OPENFLAGS()), 0);
12532 +       if(fd < 0){
12533                 if(fd != -ENOENT){
12534                         printk("not_dead_yet : couldn't open pid file '%s', "
12535 -                              "errno = %d\n", file, -fd);
12536 +                              "err = %d\n", file, -fd);
12537                         return(1);
12538                 }
12539                 dead = 1;
12540         }
12541         if(fd > 0){
12542 -               if(read(fd, pid, sizeof(pid)) < 0){
12543 +               n = os_read_file(fd, pid, sizeof(pid));
12544 +               if(n < 0){
12545                         printk("not_dead_yet : couldn't read pid file '%s', "
12546 -                              "errno = %d\n", file, errno);
12547 +                              "err = %d\n", file, -n);
12548                         return(1);
12549                 }
12550                 p = strtoul(pid, &end, 0);
12551 @@ -197,7 +201,7 @@
12552         if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
12553                 uml_dir = malloc(strlen(name) + 1);
12554                 if(uml_dir == NULL){
12555 -                       printk("Failed to malloc uml_dir - error = %d\n",
12556 +                       printf("Failed to malloc uml_dir - error = %d\n",
12557                                errno);
12558                         uml_dir = name;
12559                         return(0);
12560 @@ -217,7 +221,7 @@
12561                 char *home = getenv("HOME");
12562  
12563                 if(home == NULL){
12564 -                       printk("make_uml_dir : no value in environment for "
12565 +                       printf("make_uml_dir : no value in environment for "
12566                                "$HOME\n");
12567                         exit(1);
12568                 }
12569 @@ -232,57 +236,59 @@
12570                 dir[len + 1] = '\0';
12571         }
12572  
12573 -       if((uml_dir = malloc(strlen(dir) + 1)) == NULL){
12574 +       uml_dir = malloc(strlen(dir) + 1);
12575 +       if(uml_dir == NULL){
12576                 printf("make_uml_dir : malloc failed, errno = %d\n", errno);
12577                 exit(1);
12578         }
12579         strcpy(uml_dir, dir);
12580         
12581         if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
12582 -               printk("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
12583 +               printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
12584                 return(-1);
12585         }
12586         return 0;
12587  }
12588  
12589 -static int __init make_umid(void)
12590 +static int __init make_umid(int (*printer)(const char *fmt, ...))
12591  {
12592         int fd, err;
12593         char tmp[strlen(uml_dir) + UMID_LEN + 1];
12594  
12595         strlcpy(tmp, uml_dir, sizeof(tmp));
12596  
12597 -       if(*umid == 0){
12598 +       if(!umid_inited){
12599                 strcat(tmp, "XXXXXX");
12600                 fd = mkstemp(tmp);
12601                 if(fd < 0){
12602 -                       printk("make_umid - mkstemp failed, errno = %d\n",
12603 -                              errno);
12604 +                       (*printer)("make_umid - mkstemp failed, errno = %d\n",
12605 +                                  errno);
12606                         return(1);
12607                 }
12608  
12609 -               close(fd);
12610 +               os_close_file(fd);
12611                 /* There's a nice tiny little race between this unlink and
12612                  * the mkdir below.  It'd be nice if there were a mkstemp
12613                  * for directories.
12614                  */
12615                 unlink(tmp);
12616 -               set_umid(&tmp[strlen(uml_dir)], 1);
12617 +               set_umid(&tmp[strlen(uml_dir)], 1, printer);
12618         }
12619         
12620         sprintf(tmp, "%s%s", uml_dir, umid);
12621  
12622 -       if((err = mkdir(tmp, 0777)) < 0){
12623 +       err = mkdir(tmp, 0777);
12624 +       if(err < 0){
12625                 if(errno == EEXIST){
12626                         if(not_dead_yet(tmp)){
12627 -                               printk("umid '%s' is in use\n", umid);
12628 +                               (*printer)("umid '%s' is in use\n", umid);
12629                                 return(-1);
12630                         }
12631                         err = mkdir(tmp, 0777);
12632                 }
12633         }
12634         if(err < 0){
12635 -               printk("Failed to create %s - errno = %d\n", umid, errno);
12636 +               (*printer)("Failed to create %s - errno = %d\n", umid, errno);
12637                 return(-1);
12638         }
12639  
12640 @@ -295,7 +301,13 @@
12641  );
12642  
12643  __uml_postsetup(make_uml_dir);
12644 -__uml_postsetup(make_umid);
12645 +
12646 +static int __init make_umid_setup(void)
12647 +{
12648 +       return(make_umid(printf));
12649 +}
12650 +
12651 +__uml_postsetup(make_umid_setup);
12652  __uml_postsetup(create_pid_file);
12653  
12654  /*
12655 diff -Naur a/arch/um/kernel/user_syms.c b/arch/um/kernel/user_syms.c
12656 --- a/arch/um/kernel/user_syms.c        2004-01-08 22:30:12.000000000 -0500
12657 +++ b/arch/um/kernel/user_syms.c        2004-01-08 22:35:31.000000000 -0500
12658 @@ -1,7 +1,7 @@
12659  #include <stdio.h>
12660  #include <unistd.h>
12661 -#include <fcntl.h>
12662  #include <dirent.h>
12663 +#include <fcntl.h>
12664  #include <errno.h>
12665  #include <utime.h>
12666  #include <string.h>
12667 @@ -27,7 +27,7 @@
12668  #define __MODULE_STRING_1(x)   #x
12669  #define __MODULE_STRING(x)     __MODULE_STRING_1(x)
12670  
12671 -#if !defined(__AUTOCONF_INCLUDED__)
12672 +#if !defined(AUTOCONF_INCLUDED)
12673  
12674  #define __EXPORT_SYMBOL(sym,str)   error config_must_be_included_before_module
12675  #define EXPORT_SYMBOL(var)        error config_must_be_included_before_module
12676 diff -Naur a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c
12677 --- a/arch/um/kernel/user_util.c        2004-01-08 22:15:27.000000000 -0500
12678 +++ b/arch/um/kernel/user_util.c        2004-01-08 22:21:18.000000000 -0500
12679 @@ -5,7 +5,6 @@
12680  
12681  #include <stdio.h>
12682  #include <stdlib.h>
12683 -#include <fcntl.h>
12684  #include <unistd.h>
12685  #include <limits.h>
12686  #include <sys/mman.h> 
12687 @@ -82,7 +81,8 @@
12688         int status, ret;
12689  
12690         while(1){
12691 -               if(((ret = waitpid(pid, &status, WUNTRACED)) < 0) ||
12692 +               ret = waitpid(pid, &status, WUNTRACED);
12693 +               if((ret < 0) ||
12694                    !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
12695                         if(ret < 0){
12696                                 if(errno == EINTR) continue;
12697 @@ -119,17 +119,6 @@
12698         }
12699  }
12700  
12701 -int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags)
12702 -{
12703 -       int pid;
12704 -
12705 -       pid = clone(fn, sp, flags, arg);
12706 -       if(pid < 0) return(-1);
12707 -       wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
12708 -       ptrace(PTRACE_CONT, pid, 0, 0);
12709 -       return(pid);
12710 -}
12711 -
12712  int raw(int fd, int complain)
12713  {
12714         struct termios tt;
12715 diff -Naur a/arch/um/main.c b/arch/um/main.c
12716 --- a/arch/um/main.c    2004-01-08 22:28:01.000000000 -0500
12717 +++ b/arch/um/main.c    2004-01-08 22:34:21.000000000 -0500
12718 @@ -8,6 +8,7 @@
12719  #include <stdlib.h>
12720  #include <string.h>
12721  #include <signal.h>
12722 +#include <errno.h>
12723  #include <sys/resource.h>
12724  #include <sys/mman.h>
12725  #include <sys/user.h>
12726 @@ -123,12 +124,14 @@
12727  
12728         set_stklim();
12729  
12730 -       if((new_argv = malloc((argc + 1) * sizeof(char *))) == NULL){
12731 +       new_argv = malloc((argc + 1) * sizeof(char *));
12732 +       if(new_argv == NULL){
12733                 perror("Mallocing argv");
12734                 exit(1);
12735         }
12736         for(i=0;i<argc;i++){
12737 -               if((new_argv[i] = strdup(argv[i])) == NULL){
12738 +               new_argv[i] = strdup(argv[i]);
12739 +               if(new_argv[i] == NULL){
12740                         perror("Mallocing an arg");
12741                         exit(1);
12742                 }
12743 diff -Naur a/arch/um/Makefile b/arch/um/Makefile
12744 --- a/arch/um/Makefile  2004-01-08 22:24:07.000000000 -0500
12745 +++ b/arch/um/Makefile  2004-01-08 22:31:23.000000000 -0500
12746 @@ -24,15 +24,17 @@
12747  # Have to precede the include because the included Makefiles reference them.
12748  SYMLINK_HEADERS = include/asm-um/archparam.h include/asm-um/system.h \
12749         include/asm-um/sigcontext.h include/asm-um/processor.h \
12750 -       include/asm-um/ptrace.h include/asm-um/arch-signal.h
12751 +       include/asm-um/ptrace.h include/asm-um/arch-signal.h \
12752 +       include/asm-um/module.h
12753  
12754  ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
12755         $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
12756  
12757  GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
12758  
12759 -include $(ARCH_DIR)/Makefile-$(SUBARCH)
12760 -include $(ARCH_DIR)/Makefile-os-$(OS)
12761 +.PHONY: sys_prepare
12762 +sys_prepare:
12763 +       @:
12764  
12765  MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
12766  MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
12767 @@ -41,6 +43,9 @@
12768    include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
12769  endif
12770  
12771 +include $(ARCH_DIR)/Makefile-$(SUBARCH)
12772 +include $(ARCH_DIR)/Makefile-os-$(OS)
12773 +
12774  EXTRAVERSION := $(EXTRAVERSION)-1um
12775  
12776  ARCH_INCLUDE = -I$(ARCH_DIR)/include
12777 @@ -52,14 +57,20 @@
12778  
12779  CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
12780         -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
12781 -       $(MODE_INCLUDE)
12782 +       -Dsigprocmask=kernel_sigprocmask $(MODE_INCLUDE)
12783  
12784  LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
12785  
12786 +# These are needed for clean and mrproper, since in that case .config is not
12787 +# included; the values here are meaningless
12788 +
12789 +CONFIG_NEST_LEVEL ?= 0
12790 +CONFIG_KERNEL_HALF_GIGS ?=  0
12791 +
12792  SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
12793  
12794  ifeq ($(CONFIG_MODE_SKAS), y)
12795 -$(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
12796 +$(SYS_HEADERS) : $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
12797  endif
12798  
12799  include/linux/version.h: arch/$(ARCH)/Makefile
12800 @@ -98,17 +109,17 @@
12801  CONFIG_KERNEL_STACK_ORDER ?= 2
12802  STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
12803  
12804 -AFLAGS_vmlinux.lds.o = -U$(SUBARCH) \
12805 +AFLAGS_vmlinux.lds.o = $(shell echo -U$(SUBARCH) \
12806         -DSTART=$$(($(TOP_ADDR) - $(SIZE))) -DELF_ARCH=$(ELF_ARCH) \
12807         -DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE_TT) \
12808 -       -DKERNEL_STACK_SIZE=$(STACK_SIZE)
12809 +       -DKERNEL_STACK_SIZE=$(STACK_SIZE))
12810  
12811 -AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum
12812 +export AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum
12813  
12814  LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y)
12815  
12816 -$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE
12817 -       $(call if_changed_dep,as_s_S)
12818 +#$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE
12819 +#      $(call if_changed_dep,as_s_S)
12820  
12821  linux: vmlinux $(LD_SCRIPT-y)
12822         $(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \
12823 @@ -116,16 +127,22 @@
12824  
12825  USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
12826  USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS))
12827 +USER_CFLAGS := $(patsubst -Dsigprocmask=kernel_sigprocmask,,$(USER_CFLAGS))
12828  USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
12829         $(MODE_INCLUDE)
12830  
12831  # To get a definition of F_SETSIG
12832  USER_CFLAGS += -D_GNU_SOURCE
12833  
12834 +ifdef CONFIG_DEBUG_INFO
12835 +USER_CFLAGS          += -g
12836 +endif
12837 +
12838  CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/uml.lds.s \
12839 -       $(ARCH_DIR)/dyn_link.ld.s $(GEN_HEADERS)
12840 +       $(ARCH_DIR)/dyn_link.ld.s $(ARCH_DIR)/include/uml-config.h \
12841 +       $(GEN_HEADERS)
12842  
12843 -$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c
12844 +$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c sys_prepare
12845         $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
12846  
12847  archmrproper:
12848 @@ -161,19 +178,23 @@
12849  $(ARCH_DIR)/os:
12850         cd $(ARCH_DIR) && ln -sf os-$(OS) os
12851  
12852 -$(ARCH_DIR)/include/uml-config.h :
12853 +$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h
12854         sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@
12855  
12856 +filechk_$(ARCH_DIR)/include/task.h := $(ARCH_DIR)/util/mk_task
12857 +
12858  $(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
12859 -       $< > $@
12860 +       $(call filechk,$@)
12861 +
12862 +filechk_$(ARCH_DIR)/include/kern_constants.h := $(ARCH_DIR)/util/mk_constants
12863  
12864  $(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
12865 -       $< > $@
12866 +       $(call filechk,$@)
12867  
12868 -$(ARCH_DIR)/util/mk_task : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h \
12869 -       $(ARCH_DIR)/util FORCE ;
12870 +$(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants : $(ARCH_DIR)/util \
12871 +       sys_prepare FORCE ;
12872  
12873  $(ARCH_DIR)/util: FORCE
12874 -       @$(call descend,$@,)
12875 +       $(MAKE) -f scripts/Makefile.build obj=$@
12876  
12877 -export SUBARCH USER_CFLAGS OS
12878 +export SUBARCH USER_CFLAGS OS 
12879 diff -Naur a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
12880 --- a/arch/um/Makefile-i386     2004-01-08 22:28:01.000000000 -0500
12881 +++ b/arch/um/Makefile-i386     2004-01-08 22:34:22.000000000 -0500
12882 @@ -16,22 +16,28 @@
12883  
12884  SYS_HEADERS = $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
12885  
12886 +sys_prepare: $(SYS_DIR)/sc.h
12887 +
12888  prepare: $(SYS_HEADERS)
12889  
12890 +filechk_$(SYS_DIR)/sc.h := $(SYS_UTIL_DIR)/mk_sc
12891 +
12892  $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
12893 -       $< > $@
12894 +       $(call filechk,$@)
12895 +
12896 +filechk_$(SYS_DIR)/thread.h := $(SYS_UTIL_DIR)/mk_thread 
12897  
12898  $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread 
12899 -       $< > $@
12900 +       $(call filechk,$@)
12901  
12902 -$(SYS_UTIL_DIR)/mk_sc: FORCE ; 
12903 -       @$(call descend,$(SYS_UTIL_DIR),$@)
12904 +$(SYS_UTIL_DIR)/mk_sc: scripts/fixdep include/config/MARKER FORCE ; 
12905 +       +@$(call descend,$(SYS_UTIL_DIR),$@)
12906  
12907 -$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE ; 
12908 -       @$(call descend,$(SYS_UTIL_DIR),$@)
12909 +$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) sys_prepare FORCE ; 
12910 +       +@$(call descend,$(SYS_UTIL_DIR),$@)
12911  
12912  $(SYS_UTIL_DIR): include/asm FORCE
12913 -       @$(call descend,$@,)
12914 +       +@$(call descend,$@,)
12915  
12916  sysclean :
12917         rm -f $(SYS_HEADERS)
12918 diff -Naur a/arch/um/Makefile-skas b/arch/um/Makefile-skas
12919 --- a/arch/um/Makefile-skas     2004-01-08 22:20:33.000000000 -0500
12920 +++ b/arch/um/Makefile-skas     2004-01-08 22:27:05.000000000 -0500
12921 @@ -14,7 +14,7 @@
12922  LINK_SKAS = -Wl,-rpath,/lib 
12923  LD_SCRIPT_SKAS = dyn.lds.s
12924  
12925 -GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
12926 +GEN_HEADERS += $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
12927  
12928 -$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h :
12929 -       $(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h
12930 +$(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h :
12931 +       $(call descend,$(ARCH_DIR)/kernel/skas,$@)
12932 diff -Naur a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c
12933 --- a/arch/um/os-Linux/drivers/ethertap_kern.c  2004-01-08 22:13:47.000000000 -0500
12934 +++ b/arch/um/os-Linux/drivers/ethertap_kern.c  2004-01-08 22:18:35.000000000 -0500
12935 @@ -8,7 +8,6 @@
12936  #include "linux/init.h"
12937  #include "linux/netdevice.h"
12938  #include "linux/etherdevice.h"
12939 -#include "linux/init.h"
12940  #include "net_kern.h"
12941  #include "net_user.h"
12942  #include "etap.h"
12943 diff -Naur a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
12944 --- a/arch/um/os-Linux/drivers/ethertap_user.c  2004-01-08 22:21:31.000000000 -0500
12945 +++ b/arch/um/os-Linux/drivers/ethertap_user.c  2004-01-08 22:28:16.000000000 -0500
12946 @@ -8,7 +8,6 @@
12947  #include <stdio.h>
12948  #include <unistd.h>
12949  #include <stddef.h>
12950 -#include <fcntl.h>
12951  #include <stdlib.h>
12952  #include <sys/errno.h>
12953  #include <sys/socket.h>
12954 @@ -42,13 +41,14 @@
12955  {
12956         struct addr_change change;
12957         void *output;
12958 +       int n;
12959  
12960         change.what = op;
12961         memcpy(change.addr, addr, sizeof(change.addr));
12962         memcpy(change.netmask, netmask, sizeof(change.netmask));
12963 -       if(write(fd, &change, sizeof(change)) != sizeof(change))
12964 -               printk("etap_change - request failed, errno = %d\n",
12965 -                      errno);
12966 +       n = os_write_file(fd, &change, sizeof(change));
12967 +       if(n != sizeof(change))
12968 +               printk("etap_change - request failed, err = %d\n", -n);
12969         output = um_kmalloc(page_size());
12970         if(output == NULL)
12971                 printk("etap_change : Failed to allocate output buffer\n");
12972 @@ -82,15 +82,15 @@
12973         struct etap_pre_exec_data *data = arg;
12974  
12975         dup2(data->control_remote, 1);
12976 -       close(data->data_me);
12977 -       close(data->control_me);
12978 +       os_close_file(data->data_me);
12979 +       os_close_file(data->control_me);
12980  }
12981  
12982  static int etap_tramp(char *dev, char *gate, int control_me, 
12983                       int control_remote, int data_me, int data_remote)
12984  {
12985         struct etap_pre_exec_data pe_data;
12986 -       int pid, status, err;
12987 +       int pid, status, err, n;
12988         char version_buf[sizeof("nnnnn\0")];
12989         char data_fd_buf[sizeof("nnnnnn\0")];
12990         char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
12991 @@ -114,21 +114,21 @@
12992         pe_data.data_me = data_me;
12993         pid = run_helper(etap_pre_exec, &pe_data, args, NULL);
12994  
12995 -       if(pid < 0) err = errno;
12996 -       close(data_remote);
12997 -       close(control_remote);
12998 -       if(read(control_me, &c, sizeof(c)) != sizeof(c)){
12999 -               printk("etap_tramp : read of status failed, errno = %d\n",
13000 -                      errno);
13001 -               return(EINVAL);
13002 +       if(pid < 0) err = pid;
13003 +       os_close_file(data_remote);
13004 +       os_close_file(control_remote);
13005 +       n = os_read_file(control_me, &c, sizeof(c));
13006 +       if(n != sizeof(c)){
13007 +               printk("etap_tramp : read of status failed, err = %d\n", -n);
13008 +               return(-EINVAL);
13009         }
13010         if(c != 1){
13011                 printk("etap_tramp : uml_net failed\n");
13012 -               err = EINVAL;
13013 -               if(waitpid(pid, &status, 0) < 0) err = errno;
13014 -               else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)){
13015 +               err = -EINVAL;
13016 +               if(waitpid(pid, &status, 0) < 0)
13017 +                       err = -errno;
13018 +               else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
13019                         printk("uml_net didn't exit with status 1\n");
13020 -               }
13021         }
13022         return(err);
13023  }
13024 @@ -143,14 +143,14 @@
13025         if(err) return(err);
13026  
13027         err = os_pipe(data_fds, 0, 0);
13028 -       if(err){
13029 -               printk("data os_pipe failed - errno = %d\n", -err);
13030 +       if(err < 0){
13031 +               printk("data os_pipe failed - err = %d\n", -err);
13032                 return(err);
13033         }
13034  
13035         err = os_pipe(control_fds, 1, 0);
13036 -       if(err){
13037 -               printk("control os_pipe failed - errno = %d\n", -err);
13038 +       if(err < 0){
13039 +               printk("control os_pipe failed - err = %d\n", -err);
13040                 return(err);
13041         }
13042         
13043 @@ -167,9 +167,9 @@
13044                 kfree(output);
13045         }
13046  
13047 -       if(err != 0){
13048 -               printk("etap_tramp failed - errno = %d\n", err);
13049 -               return(-err);
13050 +       if(err < 0){
13051 +               printk("etap_tramp failed - err = %d\n", -err);
13052 +               return(err);
13053         }
13054  
13055         pri->data_fd = data_fds[0];
13056 @@ -183,11 +183,11 @@
13057         struct ethertap_data *pri = data;
13058  
13059         iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
13060 -       close(fd);
13061 +       os_close_file(fd);
13062         os_shutdown_socket(pri->data_fd, 1, 1);
13063 -       close(pri->data_fd);
13064 +       os_close_file(pri->data_fd);
13065         pri->data_fd = -1;
13066 -       close(pri->control_fd);
13067 +       os_close_file(pri->control_fd);
13068         pri->control_fd = -1;
13069  }
13070  
13071 diff -Naur a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
13072 --- a/arch/um/os-Linux/drivers/tuntap_user.c    2004-01-08 22:32:42.000000000 -0500
13073 +++ b/arch/um/os-Linux/drivers/tuntap_user.c    2004-01-08 22:36:41.000000000 -0500
13074 @@ -8,7 +8,6 @@
13075  #include <stdlib.h>
13076  #include <unistd.h>
13077  #include <errno.h>
13078 -#include <fcntl.h>
13079  #include <sys/wait.h>
13080  #include <sys/socket.h>
13081  #include <sys/un.h>
13082 @@ -61,7 +60,7 @@
13083         struct tuntap_pre_exec_data *data = arg;
13084         
13085         dup2(data->stdout, 1);
13086 -       close(data->close_me);
13087 +       os_close_file(data->close_me);
13088  }
13089  
13090  static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
13091 @@ -86,7 +85,7 @@
13092  
13093         if(pid < 0) return(-pid);
13094  
13095 -       close(remote);
13096 +       os_close_file(remote);
13097  
13098         msg.msg_name = NULL;
13099         msg.msg_namelen = 0;
13100 @@ -107,19 +106,19 @@
13101         if(n < 0){
13102                 printk("tuntap_open_tramp : recvmsg failed - errno = %d\n", 
13103                        errno);
13104 -               return(errno);
13105 +               return(-errno);
13106         }
13107         waitpid(pid, NULL, 0);
13108  
13109         cmsg = CMSG_FIRSTHDR(&msg);
13110         if(cmsg == NULL){
13111                 printk("tuntap_open_tramp : didn't receive a message\n");
13112 -               return(EINVAL);
13113 +               return(-EINVAL);
13114         }
13115         if((cmsg->cmsg_level != SOL_SOCKET) || 
13116            (cmsg->cmsg_type != SCM_RIGHTS)){
13117                 printk("tuntap_open_tramp : didn't receive a descriptor\n");
13118 -               return(EINVAL);
13119 +               return(-EINVAL);
13120         }
13121         *fd_out = ((int *) CMSG_DATA(cmsg))[0];
13122         return(0);
13123 @@ -133,27 +132,29 @@
13124         int err, fds[2], len, used;
13125  
13126         err = tap_open_common(pri->dev, pri->gate_addr);
13127 -       if(err) return(err);
13128 +       if(err < 0) 
13129 +               return(err);
13130  
13131         if(pri->fixed_config){
13132 -               if((pri->fd = open("/dev/net/tun", O_RDWR)) < 0){
13133 -                       printk("Failed to open /dev/net/tun, errno = %d\n",
13134 -                              errno);
13135 -                       return(-errno);
13136 -               }
13137 +               pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0);
13138 +               if(pri->fd < 0){
13139 +                       printk("Failed to open /dev/net/tun, err = %d\n",
13140 +                              -pri->fd);
13141 +                       return(pri->fd);
13142 +               } 
13143                 memset(&ifr, 0, sizeof(ifr));
13144 -               ifr.ifr_flags = IFF_TAP;
13145 +               ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
13146                 strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
13147                 if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
13148 -                       printk("TUNSETIFF failed, errno = %d", errno);
13149 -                       close(pri->fd);
13150 +                       printk("TUNSETIFF failed, errno = %d\n", errno);
13151 +                       os_close_file(pri->fd);
13152                         return(-errno);
13153                 }
13154         }
13155         else {
13156                 err = os_pipe(fds, 0, 0);
13157 -               if(err){
13158 -                       printk("tuntap_open : os_pipe failed - errno = %d\n",
13159 +               if(err < 0){
13160 +                       printk("tuntap_open : os_pipe failed - err = %d\n",
13161                                -err);
13162                         return(err);
13163                 }
13164 @@ -166,19 +167,19 @@
13165                                         fds[1], buffer, len, &used);
13166  
13167                 output = buffer;
13168 -               if(err == 0){
13169 -                       pri->dev_name = uml_strdup(buffer);
13170 -                       output += IFNAMSIZ;
13171 -                       printk(output);
13172 -                       free_output_buffer(buffer);
13173 -               }
13174 -               else {
13175 -                       printk(output);
13176 +               if(err < 0) {
13177 +                       printk("%s", output);
13178                         free_output_buffer(buffer);
13179 -                       printk("tuntap_open_tramp failed - errno = %d\n", err);
13180 -                       return(-err);
13181 +                       printk("tuntap_open_tramp failed - err = %d\n", -err);
13182 +                       return(err);
13183                 }
13184 -               close(fds[0]);
13185 +
13186 +               pri->dev_name = uml_strdup(buffer);
13187 +               output += IFNAMSIZ;
13188 +               printk("%s", output);
13189 +               free_output_buffer(buffer);
13190 +
13191 +               os_close_file(fds[0]);
13192                 iter_addresses(pri->dev, open_addr, pri->dev_name);
13193         }
13194  
13195 @@ -191,7 +192,7 @@
13196  
13197         if(!pri->fixed_config) 
13198                 iter_addresses(pri->dev, close_addr, pri->dev_name);
13199 -       close(fd);
13200 +       os_close_file(fd);
13201         pri->fd = -1;
13202  }
13203  
13204 diff -Naur a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
13205 --- a/arch/um/os-Linux/file.c   2004-01-08 22:32:23.000000000 -0500
13206 +++ b/arch/um/os-Linux/file.c   2004-01-08 22:36:32.000000000 -0500
13207 @@ -8,6 +8,8 @@
13208  #include <errno.h>
13209  #include <fcntl.h>
13210  #include <signal.h>
13211 +#include <sys/types.h>
13212 +#include <sys/stat.h>
13213  #include <sys/socket.h>
13214  #include <sys/un.h>
13215  #include <sys/ioctl.h>
13216 @@ -17,33 +19,236 @@
13217  #include "user.h"
13218  #include "kern_util.h"
13219  
13220 -int os_file_type(char *file)
13221 +static void copy_stat(struct uml_stat *dst, struct stat64 *src)
13222 +{
13223 +       *dst = ((struct uml_stat) {
13224 +               .ust_dev     = src->st_dev,     /* device */
13225 +               .ust_ino     = src->st_ino,     /* inode */
13226 +               .ust_mode    = src->st_mode,    /* protection */
13227 +               .ust_nlink   = src->st_nlink,   /* number of hard links */
13228 +               .ust_uid     = src->st_uid,     /* user ID of owner */
13229 +               .ust_gid     = src->st_gid,     /* group ID of owner */
13230 +               .ust_size    = src->st_size,    /* total size, in bytes */
13231 +               .ust_blksize = src->st_blksize, /* blocksize for filesys I/O */
13232 +               .ust_blocks  = src->st_blocks,  /* number of blocks allocated */
13233 +               .ust_atime   = src->st_atime,   /* time of last access */
13234 +               .ust_mtime   = src->st_mtime,   /* time of last modification */
13235 +               .ust_ctime   = src->st_ctime,   /* time of last change */
13236 +       });
13237 +}
13238 +
13239 +int os_stat_fd(const int fd, struct uml_stat *ubuf)
13240 +{
13241 +       struct stat64 sbuf;
13242 +       int err;
13243 +
13244 +       do {
13245 +               err = fstat64(fd, &sbuf);
13246 +       } while((err < 0) && (errno == EINTR)) ;
13247 +
13248 +       if(err < 0) 
13249 +               return(-errno);
13250 +
13251 +       if(ubuf != NULL)
13252 +               copy_stat(ubuf, &sbuf);
13253 +       return(err);
13254 +}
13255 +
13256 +int os_stat_file(const char *file_name, struct uml_stat *ubuf)
13257 +{
13258 +       struct stat64 sbuf;
13259 +       int err;
13260 +
13261 +       do {
13262 +               err = stat64(file_name, &sbuf);
13263 +       } while((err < 0) && (errno == EINTR)) ;
13264 +
13265 +       if(err < 0) 
13266 +               return(-errno);
13267 +
13268 +       if(ubuf != NULL)
13269 +               copy_stat(ubuf, &sbuf);
13270 +       return(err);
13271 +}
13272 +
13273 +int os_access(const char* file, int mode)
13274 +{
13275 +       int amode, err;
13276 +
13277 +       amode=(mode&OS_ACC_R_OK ? R_OK : 0) | (mode&OS_ACC_W_OK ? W_OK : 0) |
13278 +             (mode&OS_ACC_X_OK ? X_OK : 0) | (mode&OS_ACC_F_OK ? F_OK : 0) ;
13279 +
13280 +       err = access(file, amode);
13281 +       if(err < 0)
13282 +               return(-errno);
13283 +
13284 +       return(0);
13285 +}
13286 +
13287 +void os_print_error(int error, const char* str)
13288 +{
13289 +       errno = error < 0 ? -error : error;
13290 +
13291 +       perror(str);
13292 +}
13293 +
13294 +/* FIXME? required only by hostaudio (because it passes ioctls verbatim) */
13295 +int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
13296 +{
13297 +       int err;
13298 +
13299 +       err = ioctl(fd, cmd, arg);
13300 +       if(err < 0)
13301 +               return(-errno);
13302 +
13303 +       return(err);
13304 +}
13305 +
13306 +int os_window_size(int fd, int *rows, int *cols)
13307 +{
13308 +       struct winsize size;
13309 +
13310 +       if(ioctl(fd, TIOCGWINSZ, &size) < 0)
13311 +               return(-errno);
13312 +
13313 +       *rows = size.ws_row;
13314 +       *cols = size.ws_col;
13315 +
13316 +       return(0);
13317 +}
13318 +
13319 +int os_new_tty_pgrp(int fd, int pid)
13320  {
13321 -       struct stat64 buf;
13322 +       if(ioctl(fd, TIOCSCTTY, 0) < 0){
13323 +               printk("TIOCSCTTY failed, errno = %d\n", errno);
13324 +               return(-errno);
13325 +       }
13326 +
13327 +       if(tcsetpgrp(fd, pid) < 0){
13328 +               printk("tcsetpgrp failed, errno = %d\n", errno);
13329 +               return(-errno);
13330 +       }
13331 +
13332 +       return(0);
13333 +}
13334 +
13335 +/* FIXME: ensure namebuf in os_get_if_name is big enough */
13336 +int os_get_ifname(int fd, char* namebuf)
13337 +{
13338 +       if(ioctl(fd, SIOCGIFNAME, namebuf) < 0)
13339 +               return(-errno);
13340 +
13341 +       return(0);
13342 +}
13343 +
13344 +int os_set_slip(int fd)
13345 +{
13346 +       int disc, sencap;
13347 +
13348 +       disc = N_SLIP;
13349 +       if(ioctl(fd, TIOCSETD, &disc) < 0){
13350 +               printk("Failed to set slip line discipline - "
13351 +                      "errno = %d\n", errno);
13352 +               return(-errno);
13353 +       }
13354 +
13355 +       sencap = 0;
13356 +       if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0){
13357 +               printk("Failed to set slip encapsulation - "
13358 +                      "errno = %d\n", errno);
13359 +               return(-errno);
13360 +       }
13361 +
13362 +       return(0);
13363 +}
13364 +
13365 +int os_set_owner(int fd, int pid)
13366 +{
13367 +       if(fcntl(fd, F_SETOWN, pid) < 0){
13368 +               int save_errno = errno;
13369 +
13370 +               if(fcntl(fd, F_GETOWN, 0) != pid){
13371 +                       return(-save_errno);
13372 +               }
13373 +       }
13374 +
13375 +       return(0);
13376 +}
13377 +
13378 +/* FIXME? moved wholesale from sigio_user.c to get fcntls out of that file */ 
13379 +int os_sigio_async(int master, int slave)
13380 +{
13381 +       int flags;
13382  
13383 -       if(stat64(file, &buf) == -1)
13384 +       flags = fcntl(master, F_GETFL);
13385 +       if(flags < 0) {
13386 +               printk("fcntl F_GETFL failed, errno = %d\n", errno);
13387                 return(-errno);
13388 +       }
13389  
13390 -       if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
13391 -       else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
13392 -       else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
13393 -       else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
13394 -       else if(S_ISFIFO(buf.st_mode)) return(OS_TYPE_FIFO);
13395 -       else if(S_ISSOCK(buf.st_mode)) return(OS_TYPE_SOCK);
13396 +       if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
13397 +          (fcntl(master, F_SETOWN, os_getpid()) < 0)){
13398 +               printk("fcntl F_SETFL or F_SETOWN failed, errno = %d\n", errno);
13399 +               return(-errno);
13400 +       }
13401 +
13402 +       if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)){
13403 +               printk("fcntl F_SETFL failed, errno = %d\n", errno);
13404 +               return(-errno);
13405 +       }
13406 +
13407 +       return(0);
13408 +}
13409 +
13410 +int os_mode_fd(int fd, int mode)
13411 +{
13412 +       int err;
13413 +
13414 +       do {
13415 +               err = fchmod(fd, mode);
13416 +       } while((err < 0) && (errno==EINTR)) ;
13417 +
13418 +       if(err < 0)
13419 +               return(-errno);
13420 +
13421 +       return(0);
13422 +}
13423 +
13424 +int os_file_type(char *file)
13425 +{
13426 +       struct uml_stat buf;
13427 +       int err;
13428 +
13429 +       err = os_stat_file(file, &buf);
13430 +       if(err < 0)
13431 +               return(err);
13432 +
13433 +       if(S_ISDIR(buf.ust_mode)) return(OS_TYPE_DIR);
13434 +       else if(S_ISLNK(buf.ust_mode)) return(OS_TYPE_SYMLINK);
13435 +       else if(S_ISCHR(buf.ust_mode)) return(OS_TYPE_CHARDEV);
13436 +       else if(S_ISBLK(buf.ust_mode)) return(OS_TYPE_BLOCKDEV);
13437 +       else if(S_ISFIFO(buf.ust_mode)) return(OS_TYPE_FIFO);
13438 +       else if(S_ISSOCK(buf.ust_mode)) return(OS_TYPE_SOCK);
13439         else return(OS_TYPE_FILE);
13440  }
13441  
13442  int os_file_mode(char *file, struct openflags *mode_out)
13443  {
13444 +       int err;
13445 +
13446         *mode_out = OPENFLAGS();
13447  
13448 -       if(!access(file, W_OK)) *mode_out = of_write(*mode_out);
13449 -       else if(errno != EACCES) 
13450 -               return(-errno);
13451 +       err = os_access(file, OS_ACC_W_OK);
13452 +       if((err < 0) && (err != -EACCES))
13453 +               return(err);
13454  
13455 -       if(!access(file, R_OK)) *mode_out = of_read(*mode_out);
13456 -       else if(errno != EACCES) 
13457 -               return(-errno);
13458 +       *mode_out = of_write(*mode_out);
13459 +
13460 +       err = os_access(file, OS_ACC_R_OK);
13461 +       if((err < 0) && (err != -EACCES))
13462 +               return(err);
13463 +
13464 +       *mode_out = of_read(*mode_out);
13465  
13466         return(0);
13467  }
13468 @@ -63,16 +268,14 @@
13469         if(flags.e) f |= O_EXCL;
13470  
13471         fd = open64(file, f, mode);
13472 -       if(fd < 0) return(-errno);
13473 +       if(fd < 0) 
13474 +               return(-errno);
13475         
13476 -       if(flags.cl){
13477 -               if(fcntl(fd, F_SETFD, 1)){
13478 -                       close(fd);
13479 -                       return(-errno);
13480 -               }
13481 +       if(flags.cl && fcntl(fd, F_SETFD, 1)){
13482 +               os_close_file(fd);
13483 +               return(-errno);
13484         }
13485  
13486 -       return(fd);
13487         return(fd);
13488  }
13489  
13490 @@ -90,7 +293,7 @@
13491  
13492         err = connect(fd, (struct sockaddr *) &sock, sizeof(sock));
13493         if(err)
13494 -               return(err);
13495 +               return(-errno);
13496  
13497         return(fd);
13498  }
13499 @@ -109,88 +312,162 @@
13500         return(0);
13501  }
13502  
13503 -int os_read_file(int fd, void *buf, int len)
13504 +static int fault_buffer(void *start, int len, 
13505 +                       int (*copy_proc)(void *addr, void *buf, int len))
13506  {
13507 -       int n;
13508 +       int page = getpagesize(), i;
13509 +       char c;
13510  
13511 -       /* Force buf into memory if it's not already. */
13512 +       for(i = 0; i < len; i += page){
13513 +               if((*copy_proc)(start + i, &c, sizeof(c)))
13514 +                       return(-EFAULT);
13515 +       }
13516 +       if((len % page) != 0){
13517 +               if((*copy_proc)(start + len - 1, &c, sizeof(c)))
13518 +                       return(-EFAULT);
13519 +       }
13520 +       return(0);
13521 +}
13522  
13523 -       /* XXX This fails if buf is kernel memory */
13524 -#ifdef notdef
13525 -       if(copy_to_user_proc(buf, &c, sizeof(c)))
13526 -               return(-EFAULT);
13527 -#endif
13528 +static int file_io(int fd, void *buf, int len,
13529 +                  int (*io_proc)(int fd, void *buf, int len),
13530 +                  int (*copy_user_proc)(void *addr, void *buf, int len))
13531 +{
13532 +       int n, err;
13533 +
13534 +       do {
13535 +               n = (*io_proc)(fd, buf, len);
13536 +               if((n < 0) && (errno == EFAULT)){
13537 +                       err = fault_buffer(buf, len, copy_user_proc);
13538 +                       if(err)
13539 +                               return(err);
13540 +                       n = (*io_proc)(fd, buf, len);
13541 +               }
13542 +       } while((n < 0) && (errno == EINTR));
13543  
13544 -       n = read(fd, buf, len);
13545         if(n < 0)
13546                 return(-errno);
13547         return(n);
13548  }
13549  
13550 -int os_write_file(int fd, void *buf, int count)
13551 +int os_read_file(int fd, void *buf, int len)
13552  {
13553 -       int n;
13554 -
13555 -       /* Force buf into memory if it's not already. */
13556 -       
13557 -       /* XXX This fails if buf is kernel memory */
13558 -#ifdef notdef
13559 -       if(copy_to_user_proc(buf, buf, buf[0]))
13560 -               return(-EFAULT);
13561 -#endif
13562 +       return(file_io(fd, buf, len, (int (*)(int, void *, int)) read, 
13563 +                      copy_from_user_proc));
13564 +}
13565  
13566 -       n = write(fd, buf, count);
13567 -       if(n < 0)
13568 -               return(-errno);
13569 -       return(n);
13570 +int os_write_file(int fd, const void *buf, int len)
13571 +{
13572 +       return(file_io(fd, (void *) buf, len, 
13573 +                      (int (*)(int, void *, int)) write, copy_to_user_proc));
13574  }
13575  
13576  int os_file_size(char *file, long long *size_out)
13577  {
13578 -       struct stat64 buf;
13579 +       struct uml_stat buf;
13580 +       int err;
13581  
13582 -       if(stat64(file, &buf) == -1){
13583 -               printk("Couldn't stat \"%s\" : errno = %d\n", file, errno);
13584 -               return(-errno);
13585 +       err = os_stat_file(file, &buf);
13586 +       if(err < 0){
13587 +               printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
13588 +               return(err);
13589         }
13590 -       if(S_ISBLK(buf.st_mode)){
13591 +
13592 +       if(S_ISBLK(buf.ust_mode)){
13593                 int fd, blocks;
13594  
13595 -               if((fd = open64(file, O_RDONLY)) < 0){
13596 -                       printk("Couldn't open \"%s\", errno = %d\n", file,
13597 -                              errno);
13598 -                       return(-errno);
13599 +               fd = os_open_file(file, of_read(OPENFLAGS()), 0);
13600 +               if(fd < 0){
13601 +                       printk("Couldn't open \"%s\", errno = %d\n", file, -fd);
13602 +                       return(fd);
13603                 }
13604                 if(ioctl(fd, BLKGETSIZE, &blocks) < 0){
13605                         printk("Couldn't get the block size of \"%s\", "
13606                                "errno = %d\n", file, errno);
13607 -                       close(fd);
13608 -                       return(-errno);
13609 +                       err = -errno;
13610 +                       os_close_file(fd);
13611 +                       return(err);
13612                 }
13613                 *size_out = ((long long) blocks) * 512;
13614 -               close(fd);
13615 +               os_close_file(fd);
13616                 return(0);
13617         }
13618 -       *size_out = buf.st_size;
13619 +       *size_out = buf.ust_size;
13620 +       return(0);
13621 +}
13622 +
13623 +int os_file_modtime(char *file, unsigned long *modtime)
13624 +{
13625 +       struct uml_stat buf;
13626 +       int err;
13627 +
13628 +       err = os_stat_file(file, &buf);
13629 +       if(err < 0){
13630 +               printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
13631 +               return(err);
13632 +       }
13633 +
13634 +       *modtime = buf.ust_mtime;
13635         return(0);
13636  }
13637  
13638 +int os_get_exec_close(int fd, int* close_on_exec)
13639 +{
13640 +       int ret;
13641 +
13642 +       do {
13643 +               ret = fcntl(fd, F_GETFD);
13644 +       } while((ret < 0) && (errno == EINTR)) ;
13645 +
13646 +       if(ret < 0)
13647 +               return(-errno);
13648 +
13649 +       *close_on_exec = (ret&FD_CLOEXEC) ? 1 : 0;
13650 +       return(ret);
13651 +}
13652 +
13653 +int os_set_exec_close(int fd, int close_on_exec)
13654 +{
13655 +       int flag, err;
13656 +
13657 +       if(close_on_exec) flag = FD_CLOEXEC;
13658 +       else flag = 0;
13659 +
13660 +       do {
13661 +               err = fcntl(fd, F_SETFD, flag);
13662 +       } while((err < 0) && (errno == EINTR)) ;
13663 +
13664 +       if(err < 0)
13665 +               return(-errno);
13666 +       return(err);
13667 +}
13668 +
13669  int os_pipe(int *fds, int stream, int close_on_exec)
13670  {
13671         int err, type = stream ? SOCK_STREAM : SOCK_DGRAM;
13672  
13673         err = socketpair(AF_UNIX, type, 0, fds);
13674 -       if(err) 
13675 +       if(err < 0) 
13676                 return(-errno);
13677  
13678         if(!close_on_exec)
13679                 return(0);
13680  
13681 -       if((fcntl(fds[0], F_SETFD, 1) < 0) || (fcntl(fds[1], F_SETFD, 1) < 0))
13682 -               printk("os_pipe : Setting FD_CLOEXEC failed, errno = %d", 
13683 -                      errno);
13684 +       err = os_set_exec_close(fds[0], 1);
13685 +       if(err < 0)
13686 +               goto error;
13687 +
13688 +       err = os_set_exec_close(fds[1], 1);
13689 +       if(err < 0)
13690 +               goto error;
13691  
13692         return(0);
13693 +
13694 + error:
13695 +       printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err);
13696 +       os_close_file(fds[1]);
13697 +       os_close_file(fds[0]);
13698 +       return(err);
13699  }
13700  
13701  int os_set_fd_async(int fd, int owner)
13702 @@ -270,7 +547,7 @@
13703                 return(-EINVAL);
13704         }
13705         err = shutdown(fd, what);
13706 -       if(err)
13707 +       if(err < 0)
13708                 return(-errno);
13709         return(0);
13710  }
13711 @@ -315,7 +592,7 @@
13712         return(new);
13713  }
13714  
13715 -int create_unix_socket(char *file, int len)
13716 +int os_create_unix_socket(char *file, int len, int close_on_exec)
13717  {
13718         struct sockaddr_un addr;
13719         int sock, err;
13720 @@ -327,6 +604,13 @@
13721                 return(-errno);
13722         }
13723  
13724 +       if(close_on_exec) {
13725 +               err = os_set_exec_close(sock, 1);
13726 +               if(err < 0)
13727 +                       printk("create_unix_socket : close_on_exec failed, "
13728 +                      "err = %d", -err);
13729 +       }
13730 +
13731         addr.sun_family = AF_UNIX;
13732  
13733         /* XXX Be more careful about overflow */
13734 @@ -334,14 +618,45 @@
13735  
13736         err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
13737         if (err < 0){
13738 -               printk("create_listening_socket - bind failed, errno = %d\n",
13739 -                      errno);
13740 +               printk("create_listening_socket at '%s' - bind failed, "
13741 +                      "errno = %d\n", file, errno);
13742                 return(-errno);
13743         }
13744  
13745         return(sock);
13746  }
13747  
13748 +void os_flush_stdout(void)
13749 +{
13750 +       fflush(stdout);
13751 +}
13752 +
13753 +int os_lock_file(int fd, int excl)
13754 +{
13755 +       int type = excl ? F_WRLCK : F_RDLCK;
13756 +       struct flock lock = ((struct flock) { .l_type   = type,
13757 +                                             .l_whence = SEEK_SET,
13758 +                                             .l_start  = 0,
13759 +                                             .l_len    = 0 } );
13760 +       int err, save;
13761 +
13762 +       err = fcntl(fd, F_SETLK, &lock);
13763 +       if(!err)
13764 +               goto out;
13765 +
13766 +       save = -errno;
13767 +       err = fcntl(fd, F_GETLK, &lock);
13768 +       if(err){
13769 +               err = -errno;
13770 +               goto out;
13771 +       }
13772 +       
13773 +       printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
13774 +       err = save;
13775 + out:
13776 +       return(err);
13777 +}
13778 +
13779  /*
13780   * Overrides for Emacs so that we follow Linus's tabbing style.
13781   * Emacs will notice this stuff at the end of the file and automatically
13782 diff -Naur a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
13783 --- a/arch/um/os-Linux/process.c        2004-01-08 22:14:47.000000000 -0500
13784 +++ b/arch/um/os-Linux/process.c        2004-01-08 22:20:12.000000000 -0500
13785 @@ -1,5 +1,5 @@
13786  /* 
13787 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13788 + * Copyright (C) 2002 Jeff Dike (jdike@addtoit.com)
13789   * Licensed under the GPL
13790   */
13791  
13792 @@ -7,32 +7,37 @@
13793  #include <stdio.h>
13794  #include <errno.h>
13795  #include <signal.h>
13796 +#include <linux/unistd.h>
13797  #include <sys/mman.h>
13798  #include <sys/wait.h>
13799  #include "os.h"
13800  #include "user.h"
13801  
13802 +#define ARBITRARY_ADDR -1
13803 +#define FAILURE_PID    -1
13804 +
13805  unsigned long os_process_pc(int pid)
13806  {
13807         char proc_stat[sizeof("/proc/#####/stat\0")], buf[256];
13808         unsigned long pc;
13809 -       int fd;
13810 +       int fd, err;
13811  
13812         sprintf(proc_stat, "/proc/%d/stat", pid);
13813         fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0);
13814         if(fd < 0){
13815 -               printk("os_process_pc - couldn't open '%s', errno = %d\n", 
13816 -                      proc_stat, errno);
13817 -               return(-1);
13818 +               printk("os_process_pc - couldn't open '%s', err = %d\n", 
13819 +                      proc_stat, -fd);
13820 +               return(ARBITRARY_ADDR);
13821         }
13822 -       if(read(fd, buf, sizeof(buf)) < 0){
13823 -               printk("os_process_pc - couldn't read '%s', errno = %d\n", 
13824 -                      proc_stat, errno);
13825 -               close(fd);
13826 -               return(-1);
13827 +       err = os_read_file(fd, buf, sizeof(buf));
13828 +       if(err < 0){
13829 +               printk("os_process_pc - couldn't read '%s', err = %d\n", 
13830 +                      proc_stat, -err);
13831 +               os_close_file(fd);
13832 +               return(ARBITRARY_ADDR);
13833         }
13834 -       close(fd);
13835 -       pc = -1;
13836 +       os_close_file(fd);
13837 +       pc = ARBITRARY_ADDR;
13838         if(sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*d %*d %*d "
13839                   "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
13840                   "%*d %*d %*d %*d %ld", &pc) != 1){
13841 @@ -52,22 +57,23 @@
13842         snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
13843         fd = os_open_file(stat, of_read(OPENFLAGS()), 0);
13844         if(fd < 0){
13845 -               printk("Couldn't open '%s', errno = %d\n", stat, -fd);
13846 -               return(-1);
13847 +               printk("Couldn't open '%s', err = %d\n", stat, -fd);
13848 +               return(FAILURE_PID);
13849         }
13850  
13851 -       n = read(fd, data, sizeof(data));
13852 -       close(fd);
13853 +       n = os_read_file(fd, data, sizeof(data));
13854 +       os_close_file(fd);
13855  
13856         if(n < 0){
13857 -               printk("Couldn't read '%s', errno = %d\n", stat);
13858 -               return(-1);
13859 +               printk("Couldn't read '%s', err = %d\n", stat, -n);
13860 +               return(FAILURE_PID);
13861         }
13862  
13863 -       parent = -1;
13864 +       parent = FAILURE_PID;
13865         /* XXX This will break if there is a space in the command */
13866         n = sscanf(data, "%*d %*s %*c %d", &parent);
13867 -       if(n != 1) printk("Failed to scan '%s'\n", data);
13868 +       if(n != 1) 
13869 +               printk("Failed to scan '%s'\n", data);
13870  
13871         return(parent);
13872  }
13873 @@ -87,7 +93,8 @@
13874  
13875  void os_usr1_process(int pid)
13876  {
13877 -       kill(pid, SIGUSR1);
13878 +       syscall(__NR_tkill, pid, SIGUSR1); 
13879 +       /* kill(pid, SIGUSR1); */
13880  }
13881  
13882  int os_getpid(void)
13883 @@ -95,7 +102,7 @@
13884         return(getpid());
13885  }
13886  
13887 -int os_map_memory(void *virt, int fd, unsigned long off, unsigned long len, 
13888 +int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
13889                   int r, int w, int x)
13890  {
13891         void *loc;
13892 @@ -104,8 +111,8 @@
13893         prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
13894                 (x ? PROT_EXEC : 0);
13895  
13896 -       loc = mmap((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, 
13897 -                  fd, off);
13898 +       loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, 
13899 +                    fd, off);
13900         if(loc == MAP_FAILED)
13901                 return(-errno);
13902         return(0);
13903 @@ -126,7 +133,8 @@
13904          int err;
13905  
13906          err = munmap(addr, len);
13907 -        if(err < 0) return(-errno);
13908 +       if(err < 0) 
13909 +               return(-errno);
13910          return(0);
13911  }
13912  
13913 diff -Naur a/arch/um/os-Linux/tty.c b/arch/um/os-Linux/tty.c
13914 --- a/arch/um/os-Linux/tty.c    2004-01-08 22:23:12.000000000 -0500
13915 +++ b/arch/um/os-Linux/tty.c    2004-01-08 22:30:17.000000000 -0500
13916 @@ -28,10 +28,10 @@
13917         struct grantpt_info info;
13918         int fd;
13919  
13920 -       if((fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0)) < 0){
13921 -               printk("get_pty : Couldn't open /dev/ptmx - errno = %d\n",
13922 -                      errno);
13923 -               return(-1);
13924 +       fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0);
13925 +       if(fd < 0){
13926 +               printk("get_pty : Couldn't open /dev/ptmx - err = %d\n", -fd);
13927 +               return(fd);
13928         }
13929  
13930         info.fd = fd;
13931 @@ -39,7 +39,7 @@
13932  
13933         if(info.res < 0){
13934                 printk("get_pty : Couldn't grant pty - errno = %d\n", 
13935 -                      info.err);
13936 +                      -info.err);
13937                 return(-1);
13938         }
13939         if(unlockpt(fd) < 0){
13940 diff -Naur a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c
13941 --- a/arch/um/sys-i386/bugs.c   2004-01-08 22:27:56.000000000 -0500
13942 +++ b/arch/um/sys-i386/bugs.c   2004-01-08 22:34:17.000000000 -0500
13943 @@ -4,20 +4,21 @@
13944   */
13945  
13946  #include <unistd.h>
13947 -#include <fcntl.h>
13948  #include <errno.h>
13949  #include <string.h>
13950  #include <sys/signal.h>
13951 +#include <asm/ldt.h>
13952  #include "kern_util.h"
13953  #include "user.h"
13954  #include "sysdep/ptrace.h"
13955  #include "task.h"
13956 +#include "os.h"
13957  
13958  #define MAXTOKEN 64
13959  
13960  /* Set during early boot */
13961 -int cpu_has_cmov = 1;
13962 -int cpu_has_xmm = 0;
13963 +int host_has_cmov = 1;
13964 +int host_has_xmm = 0;
13965  
13966  static char token(int fd, char *buf, int len, char stop)
13967  {
13968 @@ -27,13 +28,15 @@
13969         ptr = buf;
13970         end = &buf[len];
13971         do {
13972 -               n = read(fd, ptr, sizeof(*ptr));
13973 +               n = os_read_file(fd, ptr, sizeof(*ptr));
13974                 c = *ptr++;
13975 -               if(n == 0) return(0);
13976 -               else if(n != sizeof(*ptr)){
13977 -                       printk("Reading /proc/cpuinfo failed, "
13978 -                              "errno = %d\n", errno);
13979 -                       return(-errno);
13980 +               if(n != sizeof(*ptr)){
13981 +                       if(n == 0) return(0);
13982 +                       printk("Reading /proc/cpuinfo failed, err = %d\n", -n);
13983 +                       if(n < 0) 
13984 +                               return(n);
13985 +                       else 
13986 +                               return(-EIO);
13987                 }
13988         } while((c != '\n') && (c != stop) && (ptr < end));
13989  
13990 @@ -45,45 +48,79 @@
13991         return(c);
13992  }
13993  
13994 -static int check_cpu_feature(char *feature, int *have_it)
13995 +static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
13996  {
13997 -       char buf[MAXTOKEN], c;
13998 -       int fd, len = sizeof(buf)/sizeof(buf[0]), n;
13999 -
14000 -       printk("Checking for host processor %s support...", feature);
14001 -       fd = open("/proc/cpuinfo", O_RDONLY);
14002 -       if(fd < 0){
14003 -               printk("Couldn't open /proc/cpuinfo, errno = %d\n", errno);
14004 -               return(0);
14005 -       }
14006 +       int n;
14007 +       char c;
14008  
14009 -       *have_it = 0;
14010 -       buf[len - 1] = '\0';
14011 +       scratch[len - 1] = '\0';
14012         while(1){
14013 -               c = token(fd, buf, len - 1, ':');
14014 -               if(c <= 0) goto out;
14015 +               c = token(fd, scratch, len - 1, ':');
14016 +               if(c <= 0)
14017 +                       return(0);
14018                 else if(c != ':'){
14019                         printk("Failed to find ':' in /proc/cpuinfo\n");
14020 -                       goto out;
14021 +                       return(0);
14022                 }
14023  
14024 -               if(!strncmp(buf, "flags", strlen("flags"))) break;
14025 +               if(!strncmp(scratch, key, strlen(key))) 
14026 +                       return(1);
14027  
14028                 do {
14029 -                       n = read(fd, &c, sizeof(c));
14030 +                       n = os_read_file(fd, &c, sizeof(c));
14031                         if(n != sizeof(c)){
14032                                 printk("Failed to find newline in "
14033 -                                      "/proc/cpuinfo, n = %d, errno = %d\n",
14034 -                                      n, errno);
14035 -                               goto out;
14036 +                                      "/proc/cpuinfo, err = %d\n", -n);
14037 +                               return(0);
14038                         }
14039                 } while(c != '\n');
14040         }
14041 +       return(0);
14042 +}
14043 +
14044 +int cpu_feature(char *what, char *buf, int len)
14045 +{
14046 +       int fd, ret = 0;
14047 +
14048 +       fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
14049 +       if(fd < 0){
14050 +               printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
14051 +               return(0);
14052 +       }
14053 +
14054 +       if(!find_cpuinfo_line(fd, what, buf, len)){
14055 +               printk("Couldn't find '%s' line in /proc/cpuinfo\n", what);
14056 +               goto out_close;
14057 +       }
14058 +
14059 +       token(fd, buf, len, '\n');
14060 +       ret = 1;
14061 +
14062 + out_close:
14063 +       os_close_file(fd);
14064 +       return(ret);
14065 +}
14066 +
14067 +static int check_cpu_flag(char *feature, int *have_it)
14068 +{
14069 +       char buf[MAXTOKEN], c;
14070 +       int fd, len = sizeof(buf)/sizeof(buf[0]);
14071 +
14072 +       printk("Checking for host processor %s support...", feature);
14073 +       fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
14074 +       if(fd < 0){
14075 +               printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
14076 +               return(0);
14077 +       }
14078 +
14079 +       *have_it = 0;
14080 +       if(!find_cpuinfo_line(fd, "flags", buf, sizeof(buf) / sizeof(buf[0])))
14081 +               goto out;
14082  
14083         c = token(fd, buf, len - 1, ' ');
14084         if(c < 0) goto out;
14085         else if(c != ' '){
14086 -               printk("Failed to find ':' in /proc/cpuinfo\n");
14087 +               printk("Failed to find ' ' in /proc/cpuinfo\n");
14088                 goto out;
14089         }
14090  
14091 @@ -100,21 +137,48 @@
14092   out:
14093         if(*have_it == 0) printk("No\n");
14094         else if(*have_it == 1) printk("Yes\n");
14095 -       close(fd);
14096 +       os_close_file(fd);
14097         return(1);
14098  }
14099  
14100 +#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems
14101 +       * for some people.
14102 +       */
14103 +static void disable_lcall(void)
14104 +{
14105 +       struct modify_ldt_ldt_s ldt;
14106 +       int err;
14107 +
14108 +       bzero(&ldt, sizeof(ldt));
14109 +       ldt.entry_number = 7;
14110 +       ldt.base_addr = 0;
14111 +       ldt.limit = 0;
14112 +       err = modify_ldt(1, &ldt, sizeof(ldt));
14113 +       if(err)
14114 +               printk("Failed to disable lcall7 - errno = %d\n", errno);
14115 +}
14116 +#endif
14117 +
14118 +void arch_init_thread(void)
14119 +{
14120 +#if 0
14121 +       disable_lcall();
14122 +#endif
14123 +}
14124 +
14125  void arch_check_bugs(void)
14126  {
14127         int have_it;
14128  
14129 -       if(access("/proc/cpuinfo", R_OK)){
14130 +       if(os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0){
14131                 printk("/proc/cpuinfo not available - skipping CPU capability "
14132                        "checks\n");
14133                 return;
14134         }
14135 -       if(check_cpu_feature("cmov", &have_it)) cpu_has_cmov = have_it;
14136 -       if(check_cpu_feature("xmm", &have_it)) cpu_has_xmm = have_it;
14137 +       if(check_cpu_flag("cmov", &have_it)) 
14138 +               host_has_cmov = have_it;
14139 +       if(check_cpu_flag("xmm", &have_it)) 
14140 +               host_has_xmm = have_it;
14141  }
14142  
14143  int arch_handle_signal(int sig, union uml_pt_regs *regs)
14144 @@ -130,18 +194,18 @@
14145         if((*((char *) ip) != 0x0f) || ((*((char *) (ip + 1)) & 0xf0) != 0x40))
14146                 return(0);
14147  
14148 -       if(cpu_has_cmov == 0)
14149 +       if(host_has_cmov == 0)
14150                 panic("SIGILL caused by cmov, which this processor doesn't "
14151                       "implement, boot a filesystem compiled for older "
14152                       "processors");
14153 -       else if(cpu_has_cmov == 1)
14154 +       else if(host_has_cmov == 1)
14155                 panic("SIGILL caused by cmov, which this processor claims to "
14156                       "implement");
14157 -       else if(cpu_has_cmov == -1)
14158 +       else if(host_has_cmov == -1)
14159                 panic("SIGILL caused by cmov, couldn't tell if this processor "
14160                       "implements it, boot a filesystem compiled for older "
14161                       "processors");
14162 -       else panic("Bad value for cpu_has_cmov (%d)", cpu_has_cmov);
14163 +       else panic("Bad value for host_has_cmov (%d)", host_has_cmov);
14164         return(0);
14165  }
14166  
14167 diff -Naur a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
14168 --- a/arch/um/sys-i386/Makefile 2004-01-08 22:15:20.000000000 -0500
14169 +++ b/arch/um/sys-i386/Makefile 2004-01-08 22:21:10.000000000 -0500
14170 @@ -1,7 +1,8 @@
14171 -obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o module.o \
14172 -       ptrace.o ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
14173 +obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o ptrace.o \
14174 +       ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o time.o
14175  
14176  obj-$(CONFIG_HIGHMEM) += highmem.o
14177 +obj-$(CONFIG_MODULES) += module.o
14178  
14179  USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
14180  USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
14181 @@ -9,6 +10,8 @@
14182  SYMLINKS = semaphore.c highmem.c module.c
14183  SYMLINKS := $(foreach f,$(SYMLINKS),$(src)/$f)
14184  
14185 +clean-files := $(SYMLINKS)
14186 +
14187  semaphore.c-dir = kernel
14188  highmem.c-dir = mm
14189  module.c-dir = kernel
14190 @@ -24,8 +27,7 @@
14191  $(SYMLINKS): 
14192         $(call make_link,$@)
14193  
14194 -clean:
14195 -       $(MAKE) -C util clean
14196 +subdir- := util
14197  
14198  fastdep:
14199  
14200 diff -Naur a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c
14201 --- a/arch/um/sys-i386/ptrace_user.c    2004-01-08 22:16:43.000000000 -0500
14202 +++ b/arch/um/sys-i386/ptrace_user.c    2004-01-08 22:22:45.000000000 -0500
14203 @@ -39,10 +39,10 @@
14204         nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
14205         for(i = 0; i < nregs; i++){
14206                 if((i == 4) || (i == 5)) continue;
14207 -               if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i],
14208 +               if(ptrace(PTRACE_POKEUSER, pid, &dummy->u_debugreg[i],
14209                           regs[i]) < 0)
14210 -                       printk("write_debugregs - ptrace failed, "
14211 -                              "errno = %d\n", errno);
14212 +                       printk("write_debugregs - ptrace failed on "
14213 +                              "register %d, errno = %d\n", errno);
14214         }
14215  }
14216  
14217 @@ -54,7 +54,7 @@
14218         dummy = NULL;
14219         nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
14220         for(i = 0; i < nregs; i++){
14221 -               regs[i] = ptrace(PTRACE_PEEKUSR, pid, 
14222 +               regs[i] = ptrace(PTRACE_PEEKUSER, pid, 
14223                                  &dummy->u_debugreg[i], 0);
14224         }
14225  }
14226 diff -Naur a/arch/um/sys-i386/time.c b/arch/um/sys-i386/time.c
14227 --- a/arch/um/sys-i386/time.c   1969-12-31 19:00:00.000000000 -0500
14228 +++ b/arch/um/sys-i386/time.c   2004-01-08 22:22:53.000000000 -0500
14229 @@ -0,0 +1,24 @@
14230 +/*
14231 + * sys-i386/time.c 
14232 + * Created             25.9.2002       Sapan Bhatia
14233 + *
14234 + */
14235 +
14236 +unsigned long long time_stamp(void)
14237 +{
14238 +       unsigned long low, high;
14239 +
14240 +       asm("rdtsc" : "=a" (low), "=d" (high));
14241 +       return((((unsigned long long) high) << 32) + low);
14242 +}
14243 +
14244 +/*
14245 + * Overrides for Emacs so that we follow Linus's tabbing style.
14246 + * Emacs will notice this stuff at the end of the file and automatically
14247 + * adjust the settings for this buffer only.  This must remain at the end
14248 + * of the file.
14249 + * ---------------------------------------------------------------------------
14250 + * Local variables:
14251 + * c-file-style: "linux"
14252 + * End:
14253 + */
14254 diff -Naur a/arch/um/sys-i386/util/Makefile b/arch/um/sys-i386/util/Makefile
14255 --- a/arch/um/sys-i386/util/Makefile    2004-01-08 22:31:42.000000000 -0500
14256 +++ b/arch/um/sys-i386/util/Makefile    2004-01-08 22:36:19.000000000 -0500
14257 @@ -6,10 +6,10 @@
14258  mk_sc-objs     := mk_sc.o
14259  
14260  $(obj)/mk_thread : $(obj)/mk_thread_kern.o $(obj)/mk_thread_user.o
14261 -       $(CC) $(CFLAGS) -o $@ $^
14262 +       $(HOSTCC) $(CFLAGS) -o $@ $^
14263  
14264  $(obj)/mk_thread_user.o : $(src)/mk_thread_user.c
14265 -       $(CC) $(USER_CFLAGS) -c -o $@ $<
14266 +       $(HOSTCC) $(USER_CFLAGS) -c -o $@ $<
14267  
14268  clean :
14269         $(RM) -f $(build-targets)
14270 diff -Naur a/arch/um/sys-i386/util/mk_sc.c b/arch/um/sys-i386/util/mk_sc.c
14271 --- a/arch/um/sys-i386/util/mk_sc.c     2004-01-08 22:29:42.000000000 -0500
14272 +++ b/arch/um/sys-i386/util/mk_sc.c     2004-01-08 22:35:17.000000000 -0500
14273 @@ -38,6 +38,7 @@
14274    SC_OFFSET("SC_ERR", err);
14275    SC_OFFSET("SC_CR2", cr2);
14276    SC_OFFSET("SC_FPSTATE", fpstate);
14277 +  SC_OFFSET("SC_SIGMASK", oldmask);
14278    SC_FP_OFFSET("SC_FP_CW", cw);
14279    SC_FP_OFFSET("SC_FP_SW", sw);
14280    SC_FP_OFFSET("SC_FP_TAG", tag);
14281 diff -Naur a/arch/um/uml.lds.S b/arch/um/uml.lds.S
14282 --- a/arch/um/uml.lds.S 2004-01-08 22:20:26.000000000 -0500
14283 +++ b/arch/um/uml.lds.S 2004-01-08 22:26:51.000000000 -0500
14284 @@ -9,7 +9,6 @@
14285  {
14286    . = START + SIZEOF_HEADERS;
14287  
14288 -  . = ALIGN(4096);
14289    __binary_start = .;
14290  #ifdef MODE_TT
14291    .thread_private : {
14292 @@ -26,7 +25,11 @@
14293    . = ALIGN(4096);             /* Init code and data */
14294    _stext = .;
14295    __init_begin = .;
14296 -  .text.init : { *(.text.init) }
14297 +  .init.text : { 
14298 +       _sinittext = .;
14299 +       *(.init.text)
14300 +       _einittext = .;
14301 +  }
14302    . = ALIGN(4096);
14303    .text      :
14304    {
14305 @@ -38,7 +41,7 @@
14306  
14307    #include "asm/common.lds.S"
14308  
14309 -  .data.init : { *(.data.init) }
14310 +  init.data : { *(init.data) }
14311    .data    :
14312    {
14313      . = ALIGN(KERNEL_STACK_SIZE);              /* init_task */
14314 diff -Naur a/arch/um/util/Makefile b/arch/um/util/Makefile
14315 --- a/arch/um/util/Makefile     2004-01-08 22:32:28.000000000 -0500
14316 +++ b/arch/um/util/Makefile     2004-01-08 22:36:33.000000000 -0500
14317 @@ -3,19 +3,19 @@
14318                    mk_constants_user.o mk_constants_kern.o
14319  
14320  $(obj)/mk_task: $(obj)/mk_task_user.o $(obj)/mk_task_kern.o
14321 -       $(CC) -o $@ $^
14322 +       $(HOSTCC) -o $@ $^
14323  
14324  $(obj)/mk_task_user.o: $(src)/mk_task_user.c
14325 -       $(CC) -o $@ -c $< 
14326 +       $(HOSTCC) -o $@ -c $< 
14327  
14328  $(obj)/mk_constants : $(obj)/mk_constants_user.o $(obj)/mk_constants_kern.o
14329 -       $(CC) -o $@ $^
14330 +       $(HOSTCC) -o $@ $^
14331  
14332  $(obj)/mk_constants_user.o : $(src)/mk_constants_user.c
14333 -       $(CC) -c $< -o $@
14334 +       $(HOSTCC) -c $< -o $@
14335  
14336  $(obj)/mk_constants_kern.o : $(src)/mk_constants_kern.c
14337 -       $(CC) $(CFLAGS) -c $< -o $@
14338 +       $(HOSTCC) $(CFLAGS) -c $< -o $@
14339  
14340  clean:
14341         $(RM) $(build-targets)
14342 diff -Naur a/arch/um/util/mk_constants_kern.c b/arch/um/util/mk_constants_kern.c
14343 --- a/arch/um/util/mk_constants_kern.c  2004-01-08 22:14:20.000000000 -0500
14344 +++ b/arch/um/util/mk_constants_kern.c  2004-01-08 22:19:17.000000000 -0500
14345 @@ -1,5 +1,6 @@
14346  #include "linux/kernel.h"
14347  #include "linux/stringify.h"
14348 +#include "linux/time.h"
14349  #include "asm/page.h"
14350  
14351  extern void print_head(void);
14352 @@ -11,6 +12,7 @@
14353  {
14354    print_head();
14355    print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
14356 +
14357    print_constant_str("UM_KERN_EMERG", KERN_EMERG);
14358    print_constant_str("UM_KERN_ALERT", KERN_ALERT);
14359    print_constant_str("UM_KERN_CRIT", KERN_CRIT);
14360 @@ -19,6 +21,8 @@
14361    print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
14362    print_constant_str("UM_KERN_INFO", KERN_INFO);
14363    print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
14364 +
14365 +  print_constant_int("UM_NSEC_PER_SEC", NSEC_PER_SEC);
14366    print_tail();
14367    return(0);
14368  }
14369 diff -Naur a/drivers/char/tty_io.c b/drivers/char/tty_io.c
14370 --- a/drivers/char/tty_io.c     2004-01-08 22:23:22.000000000 -0500
14371 +++ b/drivers/char/tty_io.c     2004-01-08 22:30:52.000000000 -0500
14372 @@ -2419,12 +2419,18 @@
14373  static struct cdev vc0_cdev;
14374  #endif
14375  
14376 +static int tty_initialized;
14377 +
14378  /*
14379   * Ok, now we can initialize the rest of the tty devices and can count
14380   * on memory allocations, interrupts etc..
14381   */
14382 -static int __init tty_init(void)
14383 +int __init tty_init(void)
14384  {
14385 +        if (tty_initialized)
14386 +                return 0;
14387 +       tty_initialized = 1;
14388 +
14389         strcpy(tty_cdev.kobj.name, "dev.tty");
14390         cdev_init(&tty_cdev, &tty_fops);
14391         if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
14392 diff -Naur a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
14393 --- a/fs/hostfs/hostfs.h        1969-12-31 19:00:00.000000000 -0500
14394 +++ b/fs/hostfs/hostfs.h        2004-01-08 22:17:40.000000000 -0500
14395 @@ -0,0 +1,79 @@
14396 +#ifndef __UM_FS_HOSTFS
14397 +#define __UM_FS_HOSTFS
14398 +
14399 +#include "os.h"
14400 +
14401 +/* These are exactly the same definitions as in fs.h, but the names are 
14402 + * changed so that this file can be included in both kernel and user files.
14403 + */
14404 +
14405 +#define HOSTFS_ATTR_MODE       1
14406 +#define HOSTFS_ATTR_UID        2
14407 +#define HOSTFS_ATTR_GID        4
14408 +#define HOSTFS_ATTR_SIZE       8
14409 +#define HOSTFS_ATTR_ATIME      16
14410 +#define HOSTFS_ATTR_MTIME      32
14411 +#define HOSTFS_ATTR_CTIME      64
14412 +#define HOSTFS_ATTR_ATIME_SET  128
14413 +#define HOSTFS_ATTR_MTIME_SET  256
14414 +#define HOSTFS_ATTR_FORCE      512     /* Not a change, but a change it */
14415 +#define HOSTFS_ATTR_ATTR_FLAG  1024
14416 +
14417 +struct hostfs_iattr {
14418 +       unsigned int    ia_valid;
14419 +       mode_t          ia_mode;
14420 +       uid_t           ia_uid;
14421 +       gid_t           ia_gid;
14422 +       loff_t          ia_size;
14423 +       struct timespec ia_atime;
14424 +       struct timespec ia_mtime;
14425 +       struct timespec ia_ctime;
14426 +       unsigned int    ia_attr_flags;
14427 +};
14428 +
14429 +extern int stat_file(const char *path, unsigned long long *inode_out, 
14430 +                    int *mode_out, int *nlink_out, int *uid_out, int *gid_out,
14431 +                    unsigned long long *size_out, struct timespec *atime_out, 
14432 +                    struct timespec *mtime_out, struct timespec *ctime_out, 
14433 +                    int *blksize_out, unsigned long long *blocks_out);
14434 +extern int access_file(char *path, int r, int w, int x);
14435 +extern int open_file(char *path, int r, int w, int append);
14436 +extern int file_type(const char *path, int *rdev);
14437 +extern void *open_dir(char *path, int *err_out);
14438 +extern char *read_dir(void *stream, unsigned long long *pos, 
14439 +                     unsigned long long *ino_out, int *len_out);
14440 +extern void close_file(void *stream);
14441 +extern void close_dir(void *stream);
14442 +extern int read_file(int fd, unsigned long long *offset, char *buf, int len);
14443 +extern int write_file(int fd, unsigned long long *offset, const char *buf,
14444 +                     int len);
14445 +extern int lseek_file(int fd, long long offset, int whence);
14446 +extern int file_create(char *name, int ur, int uw, int ux, int gr, 
14447 +                      int gw, int gx, int or, int ow, int ox);
14448 +extern int set_attr(const char *file, struct hostfs_iattr *attrs);
14449 +extern int make_symlink(const char *from, const char *to);
14450 +extern int unlink_file(const char *file);
14451 +extern int do_mkdir(const char *file, int mode);
14452 +extern int do_rmdir(const char *file);
14453 +extern int do_mknod(const char *file, int mode, int dev);
14454 +extern int link_file(const char *from, const char *to);
14455 +extern int do_readlink(char *file, char *buf, int size);
14456 +extern int rename_file(char *from, char *to);
14457 +extern int do_statfs(char *root, long *bsize_out, long long *blocks_out, 
14458 +                    long long *bfree_out, long long *bavail_out, 
14459 +                    long long *files_out, long long *ffree_out, 
14460 +                    void *fsid_out, int fsid_size, long *namelen_out, 
14461 +                    long *spare_out);
14462 +
14463 +#endif
14464 +
14465 +/*
14466 + * Overrides for Emacs so that we follow Linus's tabbing style.
14467 + * Emacs will notice this stuff at the end of the file and automatically
14468 + * adjust the settings for this buffer only.  This must remain at the end
14469 + * of the file.
14470 + * ---------------------------------------------------------------------------
14471 + * Local variables:
14472 + * c-file-style: "linux"
14473 + * End:
14474 + */
14475 diff -Naur a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
14476 --- a/fs/hostfs/hostfs_kern.c   1969-12-31 19:00:00.000000000 -0500
14477 +++ b/fs/hostfs/hostfs_kern.c   2004-01-08 22:18:32.000000000 -0500
14478 @@ -0,0 +1,1008 @@
14479 +/* 
14480 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
14481 + * Licensed under the GPL
14482 + *
14483 + * Ported the filesystem routines to 2.5.
14484 + * 2003-02-10 Petr Baudis <pasky@ucw.cz>
14485 + */
14486 +
14487 +#include <linux/stddef.h>
14488 +#include <linux/fs.h>
14489 +#include <linux/version.h>
14490 +#include <linux/module.h>
14491 +#include <linux/init.h>
14492 +#include <linux/slab.h>
14493 +#include <linux/pagemap.h>
14494 +#include <linux/blkdev.h>
14495 +#include <linux/list.h>
14496 +#include <linux/buffer_head.h>
14497 +#include <linux/root_dev.h>
14498 +#include <linux/statfs.h>
14499 +#include <asm/uaccess.h>
14500 +#include "hostfs.h"
14501 +#include "kern_util.h"
14502 +#include "kern.h"
14503 +#include "user_util.h"
14504 +#include "2_5compat.h"
14505 +#include "init.h"
14506 +
14507 +struct hostfs_inode_info {
14508 +       char *host_filename;
14509 +       int fd;
14510 +       int mode;
14511 +       struct inode vfs_inode;
14512 +};
14513 +
14514 +static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
14515 +{
14516 +       return(list_entry(inode, struct hostfs_inode_info, vfs_inode));
14517 +}
14518 +
14519 +#define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_dentry->d_inode)
14520 +
14521 +int hostfs_d_delete(struct dentry *dentry)
14522 +{
14523 +       return(1);
14524 +}
14525 +
14526 +struct dentry_operations hostfs_dentry_ops = {
14527 +       .d_delete               = hostfs_d_delete,
14528 +};
14529 +
14530 +/* Changed in hostfs_args before the kernel starts running */
14531 +static char *root_ino = "/";
14532 +static int append = 0;
14533 +
14534 +#define HOSTFS_SUPER_MAGIC 0x00c0ffee
14535 +
14536 +static struct inode_operations hostfs_iops;
14537 +static struct inode_operations hostfs_dir_iops;
14538 +static struct address_space_operations hostfs_link_aops;
14539 +
14540 +static int __init hostfs_args(char *options, int *add)
14541 +{
14542 +       char *ptr;
14543 +
14544 +       ptr = strchr(options, ',');
14545 +       if(ptr != NULL)
14546 +               *ptr++ = '\0';
14547 +       if(*options != '\0')
14548 +               root_ino = options;
14549 +
14550 +       options = ptr;
14551 +       while(options){
14552 +               ptr = strchr(options, ',');
14553 +               if(ptr != NULL)
14554 +                       *ptr++ = '\0';
14555 +               if(*options != '\0'){
14556 +                       if(!strcmp(options, "append"))
14557 +                               append = 1;
14558 +                       else printf("hostfs_args - unsupported option - %s\n",
14559 +                                   options);
14560 +               }
14561 +               options = ptr;
14562 +       }
14563 +       return(0);
14564 +}
14565 +
14566 +__uml_setup("hostfs=", hostfs_args,
14567 +"hostfs=<root dir>,<flags>,...\n"
14568 +"    This is used to set hostfs parameters.  The root directory argument\n"
14569 +"    is used to confine all hostfs mounts to within the specified directory\n"
14570 +"    tree on the host.  If this isn't specified, then a user inside UML can\n"
14571 +"    mount anything on the host that's accessible to the user that's running\n"
14572 +"    it.\n"
14573 +"    The only flag currently supported is 'append', which specifies that all\n"
14574 +"    files opened by hostfs will be opened in append mode.\n\n"
14575 +);
14576 +
14577 +static char *dentry_name(struct dentry *dentry, int extra)
14578 +{
14579 +       struct dentry *parent;
14580 +       char *root, *name;
14581 +       int len;
14582 +
14583 +       len = 0;
14584 +       parent = dentry;
14585 +       while(parent->d_parent != parent){
14586 +               len += parent->d_name.len + 1;
14587 +               parent = parent->d_parent;
14588 +       }
14589 +       
14590 +       root = HOSTFS_I(parent->d_inode)->host_filename;
14591 +       len += strlen(root);
14592 +       name = kmalloc(len + extra + 1, GFP_KERNEL);
14593 +       if(name == NULL) return(NULL);
14594 +
14595 +       name[len] = '\0';
14596 +       parent = dentry;
14597 +       while(parent->d_parent != parent){
14598 +               len -= parent->d_name.len + 1;
14599 +               name[len] = '/';
14600 +               strncpy(&name[len + 1], parent->d_name.name, 
14601 +                       parent->d_name.len);
14602 +               parent = parent->d_parent;
14603 +       }
14604 +       strncpy(name, root, strlen(root));
14605 +       return(name);
14606 +}
14607 +
14608 +static char *inode_name(struct inode *ino, int extra)
14609 +{
14610 +       struct dentry *dentry;
14611 +
14612 +       dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
14613 +       return(dentry_name(dentry, extra));
14614 +}
14615 +
14616 +static int read_name(struct inode *ino, char *name)
14617 +{
14618 +       /* The non-int inode fields are copied into ints by stat_file and
14619 +        * then copied into the inode because passing the actual pointers
14620 +        * in and having them treated as int * breaks on big-endian machines
14621 +        */
14622 +       int err;
14623 +       int i_mode, i_nlink, i_blksize;
14624 +       unsigned long long i_size;
14625 +       unsigned long long i_ino;
14626 +       unsigned long long i_blocks;
14627 +
14628 +       err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid, 
14629 +                       &ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime, 
14630 +                       &ino->i_ctime, &i_blksize, &i_blocks);
14631 +       if(err) 
14632 +               return(err);
14633 +
14634 +       ino->i_ino = i_ino;
14635 +       ino->i_mode = i_mode;
14636 +       ino->i_nlink = i_nlink;
14637 +       ino->i_size = i_size;
14638 +       ino->i_blksize = i_blksize;
14639 +       ino->i_blocks = i_blocks;
14640 +       if((ino->i_sb->s_dev == ROOT_DEV) && (ino->i_uid == getuid()))
14641 +               ino->i_uid = 0;
14642 +       return(0);
14643 +}
14644 +
14645 +static char *follow_link(char *link)
14646 +{
14647 +       int len, n;
14648 +       char *name, *resolved, *end;
14649 +
14650 +       len = 64;
14651 +       while(1){
14652 +               n = -ENOMEM;
14653 +               name = kmalloc(len, GFP_KERNEL);
14654 +               if(name == NULL)
14655 +                       goto out;
14656 +
14657 +               n = do_readlink(link, name, len);
14658 +               if(n < len)
14659 +                       break;
14660 +               len *= 2;
14661 +               kfree(name);
14662 +       }
14663 +       if(n < 0)
14664 +               goto out_free;
14665 +
14666 +       if(*name == '/')
14667 +               return(name);
14668 +
14669 +       end = strrchr(link, '/');
14670 +       if(end == NULL)
14671 +               return(name);
14672 +
14673 +       *(end + 1) = '\0';
14674 +       len = strlen(link) + strlen(name) + 1;
14675 +
14676 +       resolved = kmalloc(len, GFP_KERNEL);
14677 +       if(resolved == NULL){
14678 +               n = -ENOMEM;
14679 +               goto out_free;
14680 +       }
14681 +
14682 +       sprintf(resolved, "%s%s", link, name);
14683 +       kfree(name);
14684 +       kfree(link);
14685 +       return(resolved);
14686 +
14687 + out_free:
14688 +       kfree(name);
14689 + out:
14690 +       return(ERR_PTR(n));
14691 +}
14692 +
14693 +static int read_inode(struct inode *ino)
14694 +{
14695 +       char *name;
14696 +       int err = 0;
14697 +
14698 +       /* Unfortunately, we are called from iget() when we don't have a dentry
14699 +        * allocated yet.
14700 +        */
14701 +       if(list_empty(&ino->i_dentry))
14702 +               goto out;
14703
14704 +       err = -ENOMEM;
14705 +       name = inode_name(ino, 0);
14706 +       if(name == NULL) 
14707 +               goto out;
14708 +
14709 +       if(file_type(name, NULL) == OS_TYPE_SYMLINK){
14710 +               name = follow_link(name);
14711 +               if(IS_ERR(name)){
14712 +                       err = PTR_ERR(name);
14713 +                       goto out;
14714 +               }
14715 +       }
14716 +       
14717 +       err = read_name(ino, name);
14718 +       kfree(name);
14719 + out:
14720 +       return(err);
14721 +}
14722 +
14723 +int hostfs_statfs(struct super_block *sb, struct kstatfs *sf)
14724 +{
14725 +       /* do_statfs uses struct statfs64 internally, but the linux kernel
14726 +        * struct statfs still has 32-bit versions for most of these fields,
14727 +        * so we convert them here
14728 +        */
14729 +       int err;
14730 +       long long f_blocks;
14731 +       long long f_bfree;
14732 +       long long f_bavail;
14733 +       long long f_files;
14734 +       long long f_ffree;
14735 +
14736 +       err = do_statfs(HOSTFS_I(sb->s_root->d_inode)->host_filename,
14737 +                       &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
14738 +                       &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), 
14739 +                       &sf->f_namelen, sf->f_spare);
14740 +       if(err) return(err);
14741 +       sf->f_blocks = f_blocks;
14742 +       sf->f_bfree = f_bfree;
14743 +       sf->f_bavail = f_bavail;
14744 +       sf->f_files = f_files;
14745 +       sf->f_ffree = f_ffree;
14746 +       sf->f_type = HOSTFS_SUPER_MAGIC;
14747 +       return(0);
14748 +}
14749 +
14750 +static struct inode *hostfs_alloc_inode(struct super_block *sb)
14751 +{
14752 +       struct hostfs_inode_info *hi;
14753 +
14754 +       hi = kmalloc(sizeof(*hi), GFP_KERNEL);
14755 +       if(hi == NULL) 
14756 +               return(NULL);
14757 +
14758 +       *hi = ((struct hostfs_inode_info) { .host_filename      = NULL,
14759 +                                           .fd                 = -1,
14760 +                                           .mode               = 0 });
14761 +       inode_init_once(&hi->vfs_inode);
14762 +       return(&hi->vfs_inode);
14763 +}
14764 +
14765 +static void hostfs_destroy_inode(struct inode *inode)
14766 +{
14767 +       if(HOSTFS_I(inode)->host_filename) 
14768 +               kfree(HOSTFS_I(inode)->host_filename);
14769 +
14770 +       if(HOSTFS_I(inode)->fd != -1) 
14771 +               close_file(&HOSTFS_I(inode)->fd);
14772 +
14773 +       kfree(HOSTFS_I(inode));
14774 +}
14775 +
14776 +static void hostfs_read_inode(struct inode *inode)
14777 +{
14778 +       read_inode(inode);
14779 +}
14780 +
14781 +static struct super_operations hostfs_sbops = { 
14782 +       .alloc_inode    = hostfs_alloc_inode,
14783 +       .destroy_inode  = hostfs_destroy_inode,
14784 +       .read_inode     = hostfs_read_inode,
14785 +       .statfs         = hostfs_statfs,
14786 +};
14787 +
14788 +int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
14789 +{
14790 +       void *dir;
14791 +       char *name;
14792 +       unsigned long long next, ino;
14793 +       int error, len;
14794 +
14795 +       name = dentry_name(file->f_dentry, 0);
14796 +       if(name == NULL) return(-ENOMEM);
14797 +       dir = open_dir(name, &error);
14798 +       kfree(name);
14799 +       if(dir == NULL) return(-error);
14800 +       next = file->f_pos;
14801 +       while((name = read_dir(dir, &next, &ino, &len)) != NULL){
14802 +               error = (*filldir)(ent, name, len, file->f_pos, 
14803 +                                  ino, DT_UNKNOWN);
14804 +               if(error) break;
14805 +               file->f_pos = next;
14806 +       }
14807 +       close_dir(dir);
14808 +       return(0);
14809 +}
14810 +
14811 +int hostfs_file_open(struct inode *ino, struct file *file)
14812 +{
14813 +       char *name;
14814 +       int mode = 0, r = 0, w = 0, fd;
14815 +
14816 +       mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
14817 +       if((mode & HOSTFS_I(ino)->mode) == mode)
14818 +               return(0);
14819 +
14820 +       /* The file may already have been opened, but with the wrong access,
14821 +        * so this resets things and reopens the file with the new access.
14822 +        */
14823 +       if(HOSTFS_I(ino)->fd != -1){
14824 +               close_file(&HOSTFS_I(ino)->fd);
14825 +               HOSTFS_I(ino)->fd = -1;
14826 +       }
14827 +
14828 +       HOSTFS_I(ino)->mode |= mode;
14829 +       if(HOSTFS_I(ino)->mode & FMODE_READ) 
14830 +               r = 1;
14831 +       if(HOSTFS_I(ino)->mode & FMODE_WRITE) 
14832 +               w = 1;
14833 +       if(w) 
14834 +               r = 1;
14835 +
14836 +       name = dentry_name(file->f_dentry, 0);
14837 +       if(name == NULL) 
14838 +               return(-ENOMEM);
14839 +
14840 +       fd = open_file(name, r, w, append);
14841 +       kfree(name);
14842 +       if(fd < 0) return(fd);
14843 +       FILE_HOSTFS_I(file)->fd = fd;
14844 +
14845 +       return(0);
14846 +}
14847 +
14848 +int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
14849 +{
14850 +       return(0);
14851 +}
14852 +
14853 +static struct file_operations hostfs_file_fops = {
14854 +       .llseek         = generic_file_llseek,
14855 +       .read           = generic_file_read,
14856 +       .write          = generic_file_write,
14857 +       .mmap           = generic_file_mmap,
14858 +       .open           = hostfs_file_open,
14859 +       .release        = NULL,
14860 +       .fsync          = hostfs_fsync,
14861 +};
14862 +
14863 +static struct file_operations hostfs_dir_fops = {
14864 +       .readdir        = hostfs_readdir,
14865 +       .read           = generic_read_dir,
14866 +};
14867 +
14868 +int hostfs_writepage(struct page *page, struct writeback_control *wbc)
14869 +{
14870 +       struct address_space *mapping = page->mapping;
14871 +       struct inode *inode = mapping->host;
14872 +       char *buffer;
14873 +       unsigned long long base;
14874 +       int count = PAGE_CACHE_SIZE;
14875 +       int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
14876 +       int err;
14877 +
14878 +       if (page->index >= end_index)
14879 +               count = inode->i_size & (PAGE_CACHE_SIZE-1);
14880 +
14881 +       buffer = kmap(page);
14882 +       base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
14883 +
14884 +       err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
14885 +       if(err != count){
14886 +               ClearPageUptodate(page);
14887 +               goto out;
14888 +       }
14889 +
14890 +       if (base > inode->i_size)
14891 +               inode->i_size = base;
14892 +
14893 +       if (PageError(page))
14894 +               ClearPageError(page);   
14895 +       err = 0;
14896 +
14897 + out:  
14898 +       kunmap(page);
14899 +
14900 +       unlock_page(page);
14901 +       return err; 
14902 +}
14903 +
14904 +int hostfs_readpage(struct file *file, struct page *page)
14905 +{
14906 +       char *buffer;
14907 +       long long start;
14908 +       int err = 0;
14909 +
14910 +       start = (long long) page->index << PAGE_CACHE_SHIFT;
14911 +       buffer = kmap(page);
14912 +       err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
14913 +                       PAGE_CACHE_SIZE);
14914 +       if(err < 0) goto out;
14915 +
14916 +       memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
14917 +
14918 +       flush_dcache_page(page);
14919 +       SetPageUptodate(page);
14920 +       if (PageError(page)) ClearPageError(page);
14921 +       err = 0;
14922 + out:
14923 +       kunmap(page);
14924 +       unlock_page(page);
14925 +       return(err);
14926 +}
14927 +
14928 +int hostfs_prepare_write(struct file *file, struct page *page, 
14929 +                        unsigned int from, unsigned int to)
14930 +{
14931 +       char *buffer;
14932 +       long long start, tmp;
14933 +       int err;
14934 +
14935 +       start = (long long) page->index << PAGE_CACHE_SHIFT;
14936 +       buffer = kmap(page);
14937 +       if(from != 0){
14938 +               tmp = start;
14939 +               err = read_file(FILE_HOSTFS_I(file)->fd, &tmp, buffer,
14940 +                               from);
14941 +               if(err < 0) goto out;
14942 +       }
14943 +       if(to != PAGE_CACHE_SIZE){
14944 +               start += to;
14945 +               err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer + to,
14946 +                               PAGE_CACHE_SIZE - to);
14947 +               if(err < 0) goto out;           
14948 +       }
14949 +       err = 0;
14950 + out:
14951 +       kunmap(page);
14952 +       return(err);
14953 +}
14954 +
14955 +int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
14956 +                unsigned to)
14957 +{
14958 +       struct address_space *mapping = page->mapping;
14959 +       struct inode *inode = mapping->host;
14960 +       char *buffer;
14961 +       long long start;
14962 +       int err = 0;
14963 +
14964 +       start = (long long) (page->index << PAGE_CACHE_SHIFT) + from;
14965 +       buffer = kmap(page);
14966 +       err = write_file(FILE_HOSTFS_I(file)->fd, &start, buffer + from, 
14967 +                        to - from);
14968 +       if(err > 0) err = 0;
14969 +       if(!err && (start > inode->i_size))
14970 +               inode->i_size = start;
14971 +
14972 +       kunmap(page);
14973 +       return(err);
14974 +}
14975 +
14976 +static struct address_space_operations hostfs_aops = {
14977 +       .writepage      = hostfs_writepage,
14978 +       .readpage       = hostfs_readpage,
14979 +/*     .set_page_dirty = __set_page_dirty_nobuffers, */
14980 +       .prepare_write  = hostfs_prepare_write,
14981 +       .commit_write   = hostfs_commit_write
14982 +};
14983 +
14984 +static int init_inode(struct inode *inode, struct dentry *dentry)
14985 +{
14986 +       char *name;
14987 +       int type, err = -ENOMEM, rdev;
14988 +
14989 +       if(dentry){
14990 +               name = dentry_name(dentry, 0);
14991 +               if(name == NULL)
14992 +                       goto out;
14993 +               type = file_type(name, &rdev);
14994 +               kfree(name);
14995 +       }
14996 +       else type = OS_TYPE_DIR;
14997 +
14998 +       err = 0;
14999 +       if(type == OS_TYPE_SYMLINK)
15000 +               inode->i_op = &page_symlink_inode_operations;
15001 +       else if(type == OS_TYPE_DIR)
15002 +               inode->i_op = &hostfs_dir_iops;
15003 +       else inode->i_op = &hostfs_iops;
15004 +
15005 +       if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
15006 +       else inode->i_fop = &hostfs_file_fops;
15007 +
15008 +       if(type == OS_TYPE_SYMLINK) 
15009 +               inode->i_mapping->a_ops = &hostfs_link_aops;
15010 +       else inode->i_mapping->a_ops = &hostfs_aops;
15011 +
15012 +       switch (type) {
15013 +       case OS_TYPE_CHARDEV:
15014 +               init_special_inode(inode, S_IFCHR, rdev);
15015 +               break;
15016 +       case OS_TYPE_BLOCKDEV:
15017 +               init_special_inode(inode, S_IFBLK, rdev);
15018 +               break;
15019 +       case OS_TYPE_FIFO:
15020 +               init_special_inode(inode, S_IFIFO, 0);
15021 +               break;
15022 +       case OS_TYPE_SOCK:
15023 +               init_special_inode(inode, S_IFSOCK, 0);
15024 +               break;
15025 +       }
15026 + out:
15027 +       return(err);
15028 +}
15029 +
15030 +int hostfs_create(struct inode *dir, struct dentry *dentry, int mode, 
15031 +                 struct nameidata *nd)
15032 +{
15033 +       struct inode *inode;
15034 +       char *name;
15035 +       int error, fd;
15036 +
15037 +       error = -ENOMEM;
15038 +       inode = iget(dir->i_sb, 0);
15039 +       if(inode == NULL) goto out;
15040 +
15041 +       error = init_inode(inode, dentry);
15042 +       if(error) 
15043 +               goto out_put;
15044 +       
15045 +       error = -ENOMEM;
15046 +       name = dentry_name(dentry, 0);
15047 +       if(name == NULL)
15048 +               goto out_put;
15049 +
15050 +       fd = file_create(name, 
15051 +                        mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR, 
15052 +                        mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP, 
15053 +                        mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
15054 +       if(fd < 0) 
15055 +               error = fd;
15056 +       else error = read_name(inode, name);
15057 +
15058 +       kfree(name);
15059 +       if(error)
15060 +               goto out_put;
15061 +
15062 +       HOSTFS_I(inode)->fd = fd;
15063 +       HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
15064 +       d_instantiate(dentry, inode);
15065 +       return(0);
15066 +
15067 + out_put:
15068 +       iput(inode);
15069 + out:
15070 +       return(error);
15071 +}
15072 +
15073 +struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry, 
15074 +                            struct nameidata *nd)
15075 +{
15076 +       struct inode *inode;
15077 +       char *name;
15078 +       int err;
15079 +
15080 +       err = -ENOMEM;
15081 +       inode = iget(ino->i_sb, 0);
15082 +       if(inode == NULL) 
15083 +               goto out;
15084
15085 +       err = init_inode(inode, dentry);
15086 +       if(err) 
15087 +               goto out_put;
15088 +
15089 +       err = -ENOMEM;
15090 +       name = dentry_name(dentry, 0);
15091 +       if(name == NULL)
15092 +               goto out_put;
15093 +
15094 +       err = read_name(inode, name);
15095 +       kfree(name);
15096 +       if(err == -ENOENT){
15097 +               iput(inode);
15098 +               inode = NULL;
15099 +       }
15100 +       else if(err)
15101 +               goto out_put;
15102 +
15103 +       d_add(dentry, inode);
15104 +       dentry->d_op = &hostfs_dentry_ops;
15105 +       return(NULL);
15106 +
15107 + out_put:
15108 +       iput(inode);
15109 + out:
15110 +       return(ERR_PTR(err));
15111 +}
15112 +
15113 +static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
15114 +{
15115 +        char *file;
15116 +       int len;
15117 +
15118 +       file = inode_name(ino, dentry->d_name.len + 1);
15119 +       if(file == NULL) return(NULL);
15120 +        strcat(file, "/");
15121 +       len = strlen(file);
15122 +        strncat(file, dentry->d_name.name, dentry->d_name.len);
15123 +       file[len + dentry->d_name.len] = '\0';
15124 +        return(file);
15125 +}
15126 +
15127 +int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
15128 +{
15129 +        char *from_name, *to_name;
15130 +        int err;
15131 +
15132 +        if((from_name = inode_dentry_name(ino, from)) == NULL) 
15133 +                return(-ENOMEM);
15134 +        to_name = dentry_name(to, 0);
15135 +       if(to_name == NULL){
15136 +               kfree(from_name);
15137 +               return(-ENOMEM);
15138 +       }
15139 +        err = link_file(to_name, from_name);
15140 +        kfree(from_name);
15141 +        kfree(to_name);
15142 +        return(err);
15143 +}
15144 +
15145 +int hostfs_unlink(struct inode *ino, struct dentry *dentry)
15146 +{
15147 +       char *file;
15148 +       int err;
15149 +
15150 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
15151 +       if(append)
15152 +               return(-EPERM);
15153 +
15154 +       err = unlink_file(file);
15155 +       kfree(file);
15156 +       return(err);
15157 +}
15158 +
15159 +int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
15160 +{
15161 +       char *file;
15162 +       int err;
15163 +
15164 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
15165 +       err = make_symlink(file, to);
15166 +       kfree(file);
15167 +       return(err);
15168 +}
15169 +
15170 +int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
15171 +{
15172 +       char *file;
15173 +       int err;
15174 +
15175 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
15176 +       err = do_mkdir(file, mode);
15177 +       kfree(file);
15178 +       return(err);
15179 +}
15180 +
15181 +int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
15182 +{
15183 +       char *file;
15184 +       int err;
15185 +
15186 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
15187 +       err = do_rmdir(file);
15188 +       kfree(file);
15189 +       return(err);
15190 +}
15191 +
15192 +int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
15193 +{
15194 +       struct inode *inode;
15195 +       char *name;
15196 +       int err = -ENOMEM;
15197
15198 +       inode = iget(dir->i_sb, 0);
15199 +       if(inode == NULL) 
15200 +               goto out;
15201 +
15202 +       err = init_inode(inode, dentry);
15203 +       if(err) 
15204 +               goto out_put;
15205 +
15206 +       err = -ENOMEM;
15207 +       name = dentry_name(dentry, 0);
15208 +       if(name == NULL)
15209 +               goto out_put;
15210 +
15211 +       init_special_inode(inode, mode, dev);
15212 +       err = do_mknod(name, mode, dev);
15213 +       if(err)
15214 +               goto out_free;
15215 +
15216 +       err = read_name(inode, name);
15217 +       kfree(name);
15218 +       if(err)
15219 +               goto out_put;
15220 +
15221 +       d_instantiate(dentry, inode);
15222 +       return(0);
15223 +
15224 + out_free:
15225 +       kfree(name);
15226 + out_put:
15227 +       iput(inode);
15228 + out:
15229 +       return(err);
15230 +}
15231 +
15232 +int hostfs_rename(struct inode *from_ino, struct dentry *from,
15233 +                 struct inode *to_ino, struct dentry *to)
15234 +{
15235 +       char *from_name, *to_name;
15236 +       int err;
15237 +
15238 +       if((from_name = inode_dentry_name(from_ino, from)) == NULL)
15239 +               return(-ENOMEM);
15240 +       if((to_name = inode_dentry_name(to_ino, to)) == NULL){
15241 +               kfree(from_name);
15242 +               return(-ENOMEM);
15243 +       }
15244 +       err = rename_file(from_name, to_name);
15245 +       kfree(from_name);
15246 +       kfree(to_name);
15247 +       return(err);
15248 +}
15249 +
15250 +void hostfs_truncate(struct inode *ino)
15251 +{
15252 +       not_implemented();
15253 +}
15254 +
15255 +int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
15256 +{
15257 +       char *name;
15258 +       int r = 0, w = 0, x = 0, err;
15259 +
15260 +       if(desired & MAY_READ) r = 1;
15261 +       if(desired & MAY_WRITE) w = 1;
15262 +       if(desired & MAY_EXEC) x = 1;
15263 +       name = inode_name(ino, 0);
15264 +       if(name == NULL) return(-ENOMEM);
15265 +       err = access_file(name, r, w, x);
15266 +       kfree(name);
15267 +       if(!err) err = vfs_permission(ino, desired);
15268 +       return(err);
15269 +}
15270 +
15271 +int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
15272 +{
15273 +       struct hostfs_iattr attrs;
15274 +       char *name;
15275 +       int err;
15276 +       
15277 +       if(append) 
15278 +               attr->ia_valid &= ~ATTR_SIZE;
15279 +
15280 +       attrs.ia_valid = 0;
15281 +       if(attr->ia_valid & ATTR_MODE){
15282 +               attrs.ia_valid |= HOSTFS_ATTR_MODE;
15283 +               attrs.ia_mode = attr->ia_mode;
15284 +       }
15285 +       if(attr->ia_valid & ATTR_UID){
15286 +               if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) && 
15287 +                  (attr->ia_uid == 0))
15288 +                       attr->ia_uid = getuid();
15289 +               attrs.ia_valid |= HOSTFS_ATTR_UID;
15290 +               attrs.ia_uid = attr->ia_uid;
15291 +       }
15292 +       if(attr->ia_valid & ATTR_GID){
15293 +               if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) && 
15294 +                  (attr->ia_gid == 0))
15295 +                       attr->ia_gid = getuid();
15296 +               attrs.ia_valid |= HOSTFS_ATTR_GID;
15297 +               attrs.ia_gid = attr->ia_gid;
15298 +       }
15299 +       if(attr->ia_valid & ATTR_SIZE){
15300 +               attrs.ia_valid |= HOSTFS_ATTR_SIZE;
15301 +               attrs.ia_size = attr->ia_size;
15302 +       }
15303 +       if(attr->ia_valid & ATTR_ATIME){
15304 +               attrs.ia_valid |= HOSTFS_ATTR_ATIME;
15305 +               attrs.ia_atime = attr->ia_atime;
15306 +       }
15307 +       if(attr->ia_valid & ATTR_MTIME){
15308 +               attrs.ia_valid |= HOSTFS_ATTR_MTIME;
15309 +               attrs.ia_mtime = attr->ia_mtime;
15310 +       }
15311 +       if(attr->ia_valid & ATTR_CTIME){
15312 +               attrs.ia_valid |= HOSTFS_ATTR_CTIME;
15313 +               attrs.ia_ctime = attr->ia_ctime;
15314 +       }
15315 +       if(attr->ia_valid & ATTR_ATIME_SET){
15316 +               attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
15317 +       }
15318 +       if(attr->ia_valid & ATTR_MTIME_SET){
15319 +               attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
15320 +       }
15321 +       name = dentry_name(dentry, 0);
15322 +       if(name == NULL) return(-ENOMEM);
15323 +       err = set_attr(name, &attrs);
15324 +       kfree(name);
15325 +       if(err)
15326 +               return(err);
15327 +
15328 +       return(inode_setattr(dentry->d_inode, attr));
15329 +}
15330 +
15331 +int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry, 
15332 +          struct kstat *stat)
15333 +{
15334 +       generic_fillattr(dentry->d_inode, stat);
15335 +       return(0);
15336 +}
15337 +
15338 +static struct inode_operations hostfs_iops = {
15339 +       .create         = hostfs_create,
15340 +       .link           = hostfs_link,
15341 +       .unlink         = hostfs_unlink,
15342 +       .symlink        = hostfs_symlink,
15343 +       .mkdir          = hostfs_mkdir,
15344 +       .rmdir          = hostfs_rmdir,
15345 +       .mknod          = hostfs_mknod,
15346 +       .rename         = hostfs_rename,
15347 +       .truncate       = hostfs_truncate,
15348 +       .permission     = hostfs_permission,
15349 +       .setattr        = hostfs_setattr,
15350 +       .getattr        = hostfs_getattr,
15351 +};
15352 +
15353 +static struct inode_operations hostfs_dir_iops = {
15354 +       .create         = hostfs_create,
15355 +       .lookup         = hostfs_lookup,
15356 +       .link           = hostfs_link,
15357 +       .unlink         = hostfs_unlink,
15358 +       .symlink        = hostfs_symlink,
15359 +       .mkdir          = hostfs_mkdir,
15360 +       .rmdir          = hostfs_rmdir,
15361 +       .mknod          = hostfs_mknod,
15362 +       .rename         = hostfs_rename,
15363 +       .truncate       = hostfs_truncate,
15364 +       .permission     = hostfs_permission,
15365 +       .setattr        = hostfs_setattr,
15366 +       .getattr        = hostfs_getattr,
15367 +};
15368 +
15369 +int hostfs_link_readpage(struct file *file, struct page *page)
15370 +{
15371 +       char *buffer, *name;
15372 +       long long start;
15373 +       int err;
15374 +
15375 +       start = page->index << PAGE_CACHE_SHIFT;
15376 +       buffer = kmap(page);
15377 +       name = inode_name(page->mapping->host, 0);
15378 +       if(name == NULL) return(-ENOMEM);
15379 +       err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
15380 +       kfree(name);
15381 +       if(err == PAGE_CACHE_SIZE)
15382 +               err = -E2BIG;
15383 +       else if(err > 0){
15384 +               flush_dcache_page(page);
15385 +               SetPageUptodate(page);
15386 +               if (PageError(page)) ClearPageError(page);
15387 +               err = 0;
15388 +       }
15389 +       kunmap(page);
15390 +       unlock_page(page);
15391 +       return(err);
15392 +}
15393 +
15394 +static struct address_space_operations hostfs_link_aops = {
15395 +       .readpage       = hostfs_link_readpage,
15396 +};
15397 +
15398 +static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
15399 +{
15400 +       struct inode *root_inode;
15401 +       char *name, *data = d;
15402 +       int err;
15403 +
15404 +       sb->s_blocksize = 1024;
15405 +       sb->s_blocksize_bits = 10;
15406 +       sb->s_magic = HOSTFS_SUPER_MAGIC;
15407 +       sb->s_op = &hostfs_sbops;
15408 +
15409 +       if((data == NULL) || (*data == '\0')) 
15410 +               data = root_ino;
15411 +
15412 +       err = -ENOMEM;
15413 +       name = kmalloc(strlen(data) + 1, GFP_KERNEL);
15414 +       if(name == NULL) 
15415 +               goto out;
15416 +
15417 +       strcpy(name, data);
15418 +
15419 +       root_inode = iget(sb, 0);
15420 +       if(root_inode == NULL)
15421 +               goto out_free;
15422 +
15423 +       err = init_inode(root_inode, NULL);
15424 +       if(err)
15425 +               goto out_put;
15426 +
15427 +       HOSTFS_I(root_inode)->host_filename = name;
15428 +
15429 +       err = -ENOMEM;
15430 +       sb->s_root = d_alloc_root(root_inode);
15431 +       if(sb->s_root == NULL)
15432 +               goto out_put;
15433 +
15434 +       err = read_inode(root_inode);
15435 +       if(err)
15436 +               goto out_put;
15437 +
15438 +       return(0);
15439 +
15440 + out_put:
15441 +       iput(root_inode);
15442 + out_free:
15443 +       kfree(name);
15444 + out:
15445 +       return(err);
15446 +}
15447 +
15448 +static struct super_block *hostfs_read_sb(struct file_system_type *type,
15449 +                                            int flags, const char *dev_name,
15450 +                                            void *data)
15451 +{
15452 +       return(get_sb_nodev(type, flags, data, hostfs_fill_sb_common));
15453 +}
15454 +
15455 +static struct file_system_type hostfs_type = {
15456 +       .owner          = THIS_MODULE,
15457 +       .name           = "hostfs",
15458 +       .get_sb         = hostfs_read_sb,
15459 +       .kill_sb        = kill_anon_super,
15460 +       .fs_flags       = 0,
15461 +};
15462 +
15463 +static int __init init_hostfs(void)
15464 +{
15465 +       return(register_filesystem(&hostfs_type));
15466 +}
15467 +
15468 +static void __exit exit_hostfs(void)
15469 +{
15470 +       unregister_filesystem(&hostfs_type);
15471 +}
15472 +
15473 +module_init(init_hostfs)
15474 +module_exit(exit_hostfs)
15475 +MODULE_LICENSE("GPL");
15476 +
15477 +/*
15478 + * Overrides for Emacs so that we follow Linus's tabbing style.
15479 + * Emacs will notice this stuff at the end of the file and automatically
15480 + * adjust the settings for this buffer only.  This must remain at the end
15481 + * of the file.
15482 + * ---------------------------------------------------------------------------
15483 + * Local variables:
15484 + * c-file-style: "linux"
15485 + * End:
15486 + */
15487 diff -Naur a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
15488 --- a/fs/hostfs/hostfs_user.c   1969-12-31 19:00:00.000000000 -0500
15489 +++ b/fs/hostfs/hostfs_user.c   2004-01-08 22:21:31.000000000 -0500
15490 @@ -0,0 +1,361 @@
15491 +/* 
15492 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
15493 + * Licensed under the GPL
15494 + */
15495 +
15496 +#include <unistd.h>
15497 +#include <stdio.h>
15498 +#include <fcntl.h>
15499 +#include <dirent.h>
15500 +#include <errno.h>
15501 +#include <utime.h>
15502 +#include <string.h>
15503 +#include <sys/stat.h>
15504 +#include <sys/time.h>
15505 +#include <sys/vfs.h>
15506 +#include "hostfs.h"
15507 +#include "kern_util.h"
15508 +#include "user.h"
15509 +
15510 +int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
15511 +             int *nlink_out, int *uid_out, int *gid_out, 
15512 +             unsigned long long *size_out, struct timespec *atime_out,
15513 +             struct timespec *mtime_out, struct timespec *ctime_out,
15514 +             int *blksize_out, unsigned long long *blocks_out)
15515 +{
15516 +       struct stat64 buf;
15517 +
15518 +       if(lstat64(path, &buf) < 0) 
15519 +               return(-errno);
15520 +
15521 +       /* See the Makefile for why STAT64_INO_FIELD is passed in
15522 +        * by the build
15523 +        */
15524 +       if(inode_out != NULL) *inode_out = buf.STAT64_INO_FIELD;
15525 +       if(mode_out != NULL) *mode_out = buf.st_mode;
15526 +       if(nlink_out != NULL) *nlink_out = buf.st_nlink;
15527 +       if(uid_out != NULL) *uid_out = buf.st_uid;
15528 +       if(gid_out != NULL) *gid_out = buf.st_gid;
15529 +       if(size_out != NULL) *size_out = buf.st_size;
15530 +       if(atime_out != NULL) {
15531 +               atime_out->tv_sec = buf.st_atime;
15532 +               atime_out->tv_nsec = 0;
15533 +       }
15534 +       if(mtime_out != NULL) {
15535 +               mtime_out->tv_sec = buf.st_mtime;
15536 +               mtime_out->tv_nsec = 0;
15537 +       }
15538 +       if(ctime_out != NULL) {
15539 +               ctime_out->tv_sec = buf.st_ctime;
15540 +               ctime_out->tv_nsec = 0;
15541 +       }
15542 +       if(blksize_out != NULL) *blksize_out = buf.st_blksize;
15543 +       if(blocks_out != NULL) *blocks_out = buf.st_blocks;
15544 +       return(0);
15545 +}
15546 +
15547 +int file_type(const char *path, int *rdev)
15548 +{
15549 +       struct stat64 buf;
15550 +
15551 +       if(lstat64(path, &buf) < 0) 
15552 +               return(-errno);
15553 +       if(rdev != NULL) 
15554 +               *rdev = buf.st_rdev;
15555 +
15556 +       if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
15557 +       else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
15558 +       else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
15559 +       else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
15560 +       else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO);
15561 +       else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK);
15562 +       else return(OS_TYPE_FILE);
15563 +}
15564 +
15565 +int access_file(char *path, int r, int w, int x)
15566 +{
15567 +       int mode = 0;
15568 +
15569 +       if(r) mode = R_OK;
15570 +       if(w) mode |= W_OK;
15571 +       if(x) mode |= X_OK;
15572 +       if(access(path, mode) != 0) return(-errno);
15573 +       else return(0);
15574 +}
15575 +
15576 +int open_file(char *path, int r, int w, int append)
15577 +{
15578 +       int mode = 0, fd;
15579 +
15580 +       if(r && !w) 
15581 +               mode = O_RDONLY;
15582 +       else if(!r && w) 
15583 +               mode = O_WRONLY;
15584 +       else if(r && w) 
15585 +               mode = O_RDWR;
15586 +       else panic("Impossible mode in open_file");
15587 +
15588 +       if(append)
15589 +               mode |= O_APPEND;
15590 +       fd = open64(path, mode);
15591 +       if(fd < 0) return(-errno);
15592 +       else return(fd);
15593 +}
15594 +
15595 +void *open_dir(char *path, int *err_out)
15596 +{
15597 +       DIR *dir;
15598 +
15599 +       dir = opendir(path);
15600 +       *err_out = errno;
15601 +       if(dir == NULL) return(NULL);
15602 +       return(dir);
15603 +}
15604 +
15605 +char *read_dir(void *stream, unsigned long long *pos, 
15606 +              unsigned long long *ino_out, int *len_out)
15607 +{
15608 +       DIR *dir = stream;
15609 +       struct dirent *ent;
15610 +
15611 +       seekdir(dir, *pos);
15612 +       ent = readdir(dir);
15613 +       if(ent == NULL) return(NULL);
15614 +       *len_out = strlen(ent->d_name);
15615 +       *ino_out = ent->d_ino;
15616 +       *pos = telldir(dir);
15617 +       return(ent->d_name);
15618 +}
15619 +
15620 +int read_file(int fd, unsigned long long *offset, char *buf, int len)
15621 +{
15622 +       int n;
15623 +
15624 +       n = pread64(fd, buf, len, *offset);
15625 +       if(n < 0) return(-errno);
15626 +       *offset += n;
15627 +       return(n);
15628 +}
15629 +
15630 +int write_file(int fd, unsigned long long *offset, const char *buf, int len)
15631 +{
15632 +       int n;
15633 +
15634 +       n = pwrite64(fd, buf, len, *offset);
15635 +       if(n < 0) return(-errno);
15636 +       *offset += n;
15637 +       return(n);
15638 +}
15639 +
15640 +int lseek_file(int fd, long long offset, int whence)
15641 +{
15642 +       int ret;
15643 +
15644 +       ret = lseek64(fd, offset, whence);
15645 +       if(ret < 0) return(-errno);
15646 +       return(0);
15647 +}
15648 +
15649 +void close_file(void *stream)
15650 +{
15651 +       close(*((int *) stream));
15652 +}
15653 +
15654 +void close_dir(void *stream)
15655 +{
15656 +       closedir(stream);
15657 +}
15658 +
15659 +int file_create(char *name, int ur, int uw, int ux, int gr, 
15660 +               int gw, int gx, int or, int ow, int ox)
15661 +{
15662 +       int mode, fd;
15663 +
15664 +       mode = 0;
15665 +       mode |= ur ? S_IRUSR : 0;
15666 +       mode |= uw ? S_IWUSR : 0;
15667 +       mode |= ux ? S_IXUSR : 0;
15668 +       mode |= gr ? S_IRGRP : 0;
15669 +       mode |= gw ? S_IWGRP : 0;
15670 +       mode |= gx ? S_IXGRP : 0;
15671 +       mode |= or ? S_IROTH : 0;
15672 +       mode |= ow ? S_IWOTH : 0;
15673 +       mode |= ox ? S_IXOTH : 0;
15674 +       fd = open64(name, O_CREAT | O_RDWR, mode);
15675 +       if(fd < 0) 
15676 +               return(-errno);
15677 +       return(fd);
15678 +}
15679 +
15680 +int set_attr(const char *file, struct hostfs_iattr *attrs)
15681 +{
15682 +       struct utimbuf buf;
15683 +       int err, ma;
15684 +
15685 +       if(attrs->ia_valid & HOSTFS_ATTR_MODE){
15686 +               if(chmod(file, attrs->ia_mode) != 0) return(-errno);
15687 +       }
15688 +       if(attrs->ia_valid & HOSTFS_ATTR_UID){
15689 +               if(chown(file, attrs->ia_uid, -1)) return(-errno);
15690 +       }
15691 +       if(attrs->ia_valid & HOSTFS_ATTR_GID){
15692 +               if(chown(file, -1, attrs->ia_gid)) return(-errno);
15693 +       }
15694 +       if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
15695 +               if(truncate(file, attrs->ia_size)) return(-errno);
15696 +       }
15697 +       ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET;
15698 +       if((attrs->ia_valid & ma) == ma){
15699 +               buf.actime = attrs->ia_atime.tv_sec;
15700 +               buf.modtime = attrs->ia_mtime.tv_sec;
15701 +               if(utime(file, &buf) != 0) return(-errno);
15702 +       }
15703 +       else {
15704 +               struct timespec ts;
15705 +
15706 +               if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){
15707 +                       err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
15708 +                                       NULL, NULL, &ts, NULL, NULL, NULL);
15709 +                       if(err != 0) 
15710 +                               return(err);
15711 +                       buf.actime = attrs->ia_atime.tv_sec;
15712 +                       buf.modtime = ts.tv_sec;
15713 +                       if(utime(file, &buf) != 0) 
15714 +                               return(-errno);
15715 +               }
15716 +               if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){
15717 +                       err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
15718 +                                       NULL, &ts, NULL, NULL, NULL, NULL);
15719 +                       if(err != 0) 
15720 +                               return(err);
15721 +                       buf.actime = ts.tv_sec;
15722 +                       buf.modtime = attrs->ia_mtime.tv_sec;
15723 +                       if(utime(file, &buf) != 0) 
15724 +                               return(-errno);
15725 +               }
15726 +       }
15727 +       if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
15728 +       if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
15729 +               err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL, 
15730 +                               &attrs->ia_atime, &attrs->ia_mtime, NULL, 
15731 +                               NULL, NULL);
15732 +               if(err != 0) return(err);
15733 +       }
15734 +       return(0);
15735 +}
15736 +
15737 +int make_symlink(const char *from, const char *to)
15738 +{
15739 +       int err;
15740 +
15741 +       err = symlink(to, from);
15742 +       if(err) return(-errno);
15743 +       return(0);
15744 +}
15745 +
15746 +int unlink_file(const char *file)
15747 +{
15748 +       int err;
15749 +
15750 +       err = unlink(file);
15751 +       if(err) return(-errno);
15752 +       return(0);
15753 +}
15754 +
15755 +int do_mkdir(const char *file, int mode)
15756 +{
15757 +       int err;
15758 +
15759 +       err = mkdir(file, mode);
15760 +       if(err) return(-errno);
15761 +       return(0);
15762 +}
15763 +
15764 +int do_rmdir(const char *file)
15765 +{
15766 +       int err;
15767 +
15768 +       err = rmdir(file);
15769 +       if(err) return(-errno);
15770 +       return(0);
15771 +}
15772 +
15773 +int do_mknod(const char *file, int mode, int dev)
15774 +{
15775 +       int err;
15776 +
15777 +       err = mknod(file, mode, dev);
15778 +       if(err) return(-errno);
15779 +       return(0);
15780 +}
15781 +
15782 +int link_file(const char *to, const char *from)
15783 +{
15784 +       int err;
15785 +
15786 +       err = link(to, from);
15787 +       if(err) return(-errno);
15788 +       return(0);
15789 +}
15790 +
15791 +int do_readlink(char *file, char *buf, int size)
15792 +{
15793 +       int n;
15794 +
15795 +       n = readlink(file, buf, size);
15796 +       if(n < 0) 
15797 +               return(-errno);
15798 +       if(n < size) 
15799 +               buf[n] = '\0';
15800 +       return(n);
15801 +}
15802 +
15803 +int rename_file(char *from, char *to)
15804 +{
15805 +       int err;
15806 +
15807 +       err = rename(from, to);
15808 +       if(err < 0) return(-errno);
15809 +       return(0);      
15810 +}
15811 +
15812 +int do_statfs(char *root, long *bsize_out, long long *blocks_out, 
15813 +             long long *bfree_out, long long *bavail_out, 
15814 +             long long *files_out, long long *ffree_out,
15815 +             void *fsid_out, int fsid_size, long *namelen_out, 
15816 +             long *spare_out)
15817 +{
15818 +       struct statfs64 buf;
15819 +       int err;
15820 +
15821 +       err = statfs64(root, &buf);
15822 +       if(err < 0) return(-errno);
15823 +       *bsize_out = buf.f_bsize;
15824 +       *blocks_out = buf.f_blocks;
15825 +       *bfree_out = buf.f_bfree;
15826 +       *bavail_out = buf.f_bavail;
15827 +       *files_out = buf.f_files;
15828 +       *ffree_out = buf.f_ffree;
15829 +       memcpy(fsid_out, &buf.f_fsid, 
15830 +              sizeof(buf.f_fsid) > fsid_size ? fsid_size : 
15831 +              sizeof(buf.f_fsid));
15832 +       *namelen_out = buf.f_namelen;
15833 +       spare_out[0] = buf.f_spare[0];
15834 +       spare_out[1] = buf.f_spare[1];
15835 +       spare_out[2] = buf.f_spare[2];
15836 +       spare_out[3] = buf.f_spare[3];
15837 +       spare_out[4] = buf.f_spare[4];
15838 +       spare_out[5] = buf.f_spare[5];
15839 +       return(0);
15840 +}
15841 +
15842 +/*
15843 + * Overrides for Emacs so that we follow Linus's tabbing style.
15844 + * Emacs will notice this stuff at the end of the file and automatically
15845 + * adjust the settings for this buffer only.  This must remain at the end
15846 + * of the file.
15847 + * ---------------------------------------------------------------------------
15848 + * Local variables:
15849 + * c-file-style: "linux"
15850 + * End:
15851 + */
15852 diff -Naur a/fs/hostfs/Makefile b/fs/hostfs/Makefile
15853 --- a/fs/hostfs/Makefile        1969-12-31 19:00:00.000000000 -0500
15854 +++ b/fs/hostfs/Makefile        2004-01-08 22:17:43.000000000 -0500
15855 @@ -0,0 +1,36 @@
15856 +# 
15857 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
15858 +# Licensed under the GPL
15859 +#
15860 +
15861 +# struct stat64 changed the inode field name between 2.2 and 2.4 from st_ino
15862 +# to __st_ino.  It stayed in the same place, so as long as the correct name
15863 +# is used, hostfs compiled on 2.2 should work on 2.4 and vice versa.
15864 +
15865 +STAT64_INO_FIELD := $(shell grep -q __st_ino /usr/include/bits/stat.h && \
15866 +                               echo __)st_ino
15867 +
15868 +hostfs-objs := hostfs_kern.o hostfs_user.o
15869 +
15870 +obj-y = 
15871 +obj-$(CONFIG_HOSTFS) += hostfs.o
15872 +
15873 +SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
15874 +
15875 +USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(SINGLE_OBJS))
15876 +USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
15877 +
15878 +USER_CFLAGS += -DSTAT64_INO_FIELD=$(STAT64_INO_FIELD)
15879 +
15880 +$(USER_OBJS) : %.o: %.c
15881 +       $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
15882 +
15883 +clean:
15884 +
15885 +modules:
15886 +
15887 +fastdep:
15888 +
15889 +dep:
15890 +
15891 +archmrproper: clean
15892 diff -Naur a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
15893 --- a/fs/hppfs/hppfs_kern.c     1969-12-31 19:00:00.000000000 -0500
15894 +++ b/fs/hppfs/hppfs_kern.c     2004-01-08 22:27:11.000000000 -0500
15895 @@ -0,0 +1,811 @@
15896 +/* 
15897 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15898 + * Licensed under the GPL
15899 + */
15900 +
15901 +#include <linux/fs.h>
15902 +#include <linux/module.h>
15903 +#include <linux/init.h>
15904 +#include <linux/slab.h>
15905 +#include <linux/list.h>
15906 +#include <linux/kernel.h>
15907 +#include <linux/ctype.h>
15908 +#include <linux/dcache.h>
15909 +#include <linux/statfs.h>
15910 +#include <asm/uaccess.h>
15911 +#include <asm/fcntl.h>
15912 +#include "os.h"
15913 +
15914 +static int init_inode(struct inode *inode, struct dentry *dentry);
15915 +
15916 +struct hppfs_data {
15917 +       struct list_head list;
15918 +       char contents[PAGE_SIZE - sizeof(struct list_head)];
15919 +};
15920 +
15921 +struct hppfs_private {
15922 +       struct file proc_file;
15923 +       int host_fd;
15924 +       loff_t len;
15925 +       struct hppfs_data *contents;
15926 +};
15927 +
15928 +struct hppfs_inode_info {
15929 +        struct dentry *proc_dentry;
15930 +       struct inode vfs_inode;
15931 +};
15932 +
15933 +static inline struct hppfs_inode_info *HPPFS_I(struct inode *inode)
15934 +{
15935 +       return(list_entry(inode, struct hppfs_inode_info, vfs_inode));
15936 +}
15937 +
15938 +#define HPPFS_SUPER_MAGIC 0xb00000ee
15939 +
15940 +static struct super_operations hppfs_sbops;
15941 +
15942 +static int is_pid(struct dentry *dentry)
15943 +{
15944 +       struct super_block *sb;
15945 +       int i;
15946 +
15947 +       sb = dentry->d_sb;
15948 +       if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
15949 +               return(0);
15950 +
15951 +       for(i = 0; i < dentry->d_name.len; i++){
15952 +               if(!isdigit(dentry->d_name.name[i]))
15953 +                       return(0);
15954 +       }
15955 +       return(1);
15956 +}
15957 +
15958 +static char *dentry_name(struct dentry *dentry, int extra)
15959 +{
15960 +       struct dentry *parent;
15961 +       char *root, *name;
15962 +       const char *seg_name;
15963 +       int len, seg_len;
15964 +
15965 +       len = 0;
15966 +       parent = dentry;
15967 +       while(parent->d_parent != parent){
15968 +               if(is_pid(parent))
15969 +                       len += strlen("pid") + 1;
15970 +               else len += parent->d_name.len + 1;
15971 +               parent = parent->d_parent;
15972 +       }
15973 +       
15974 +       root = "proc";
15975 +       len += strlen(root);
15976 +       name = kmalloc(len + extra + 1, GFP_KERNEL);
15977 +       if(name == NULL) return(NULL);
15978 +
15979 +       name[len] = '\0';
15980 +       parent = dentry;
15981 +       while(parent->d_parent != parent){
15982 +               if(is_pid(parent)){
15983 +                       seg_name = "pid";
15984 +                       seg_len = strlen("pid");
15985 +               }
15986 +               else {
15987 +                       seg_name = parent->d_name.name;
15988 +                       seg_len = parent->d_name.len;
15989 +               }
15990 +
15991 +               len -= seg_len + 1;
15992 +               name[len] = '/';
15993 +               strncpy(&name[len + 1], seg_name, seg_len);
15994 +               parent = parent->d_parent;
15995 +       }
15996 +       strncpy(name, root, strlen(root));
15997 +       return(name);
15998 +}
15999 +
16000 +struct dentry_operations hppfs_dentry_ops = {
16001 +};
16002 +
16003 +static int file_removed(struct dentry *dentry, const char *file)
16004 +{
16005 +       char *host_file;
16006 +       int extra, fd;
16007 +
16008 +       extra = 0;
16009 +       if(file != NULL) extra += strlen(file) + 1;
16010 +
16011 +       host_file = dentry_name(dentry, extra + strlen("/remove"));
16012 +       if(host_file == NULL){
16013 +               printk("file_removed : allocation failed\n");
16014 +               return(-ENOMEM);
16015 +       }
16016 +
16017 +       if(file != NULL){
16018 +               strcat(host_file, "/");
16019 +               strcat(host_file, file);
16020 +       }
16021 +       strcat(host_file, "/remove");
16022 +
16023 +       fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
16024 +       kfree(host_file);
16025 +       if(fd > 0){
16026 +               os_close_file(fd);
16027 +               return(1);
16028 +       }
16029 +       return(0);
16030 +}
16031 +
16032 +static void hppfs_read_inode(struct inode *ino)
16033 +{
16034 +       struct inode *proc_ino;
16035 +
16036 +       if(HPPFS_I(ino)->proc_dentry == NULL)
16037 +               return;
16038 +
16039 +       proc_ino = HPPFS_I(ino)->proc_dentry->d_inode;
16040 +       ino->i_uid = proc_ino->i_uid;
16041 +       ino->i_gid = proc_ino->i_gid;
16042 +       ino->i_atime = proc_ino->i_atime;
16043 +       ino->i_mtime = proc_ino->i_mtime;
16044 +       ino->i_ctime = proc_ino->i_ctime;
16045 +       ino->i_ino = proc_ino->i_ino;
16046 +       ino->i_mode = proc_ino->i_mode;
16047 +       ino->i_nlink = proc_ino->i_nlink;
16048 +       ino->i_size = proc_ino->i_size;
16049 +       ino->i_blksize = proc_ino->i_blksize;
16050 +       ino->i_blocks = proc_ino->i_blocks;
16051 +}
16052 +
16053 +static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, 
16054 +                                  struct nameidata *nd)
16055 +{
16056 +       struct dentry *proc_dentry, *new, *parent;
16057 +       struct inode *inode;
16058 +       int err, deleted;
16059 +
16060 +       deleted = file_removed(dentry, NULL);
16061 +       if(deleted < 0)
16062 +               return(ERR_PTR(deleted));
16063 +       else if(deleted)
16064 +               return(ERR_PTR(-ENOENT));
16065 +
16066 +       err = -ENOMEM;
16067 +       parent = HPPFS_I(ino)->proc_dentry;
16068 +       down(&parent->d_inode->i_sem);
16069 +       proc_dentry = d_lookup(parent, &dentry->d_name);
16070 +       if(proc_dentry == NULL){
16071 +               proc_dentry = d_alloc(parent, &dentry->d_name);
16072 +               if(proc_dentry == NULL){
16073 +                       up(&parent->d_inode->i_sem);
16074 +                       goto out;
16075 +               }
16076 +               new = (*parent->d_inode->i_op->lookup)(parent->d_inode, 
16077 +                                                      proc_dentry, NULL);
16078 +               if(new){
16079 +                       dput(proc_dentry);
16080 +                       proc_dentry = new;
16081 +               }
16082 +       }
16083 +       up(&parent->d_inode->i_sem);
16084 +
16085 +       if(IS_ERR(proc_dentry))
16086 +               return(proc_dentry);
16087 +
16088 +       inode = iget(ino->i_sb, 0);
16089 +       if(inode == NULL) 
16090 +               goto out_dput;
16091 +
16092 +       err = init_inode(inode, proc_dentry);
16093 +       if(err) 
16094 +               goto out_put;
16095 +       
16096 +       hppfs_read_inode(inode);
16097 +
16098 +       d_add(dentry, inode);
16099 +       dentry->d_op = &hppfs_dentry_ops;
16100 +       return(NULL);
16101 +
16102 + out_put:
16103 +       iput(inode);
16104 + out_dput:
16105 +       dput(proc_dentry);
16106 + out:
16107 +       return(ERR_PTR(err));
16108 +}
16109 +
16110 +static struct inode_operations hppfs_file_iops = {
16111 +};
16112 +
16113 +static ssize_t read_proc(struct file *file, char *buf, ssize_t count, 
16114 +                        loff_t *ppos, int is_user)
16115 +{
16116 +       ssize_t (*read)(struct file *, char *, size_t, loff_t *);
16117 +       ssize_t n;
16118 +
16119 +       read = file->f_dentry->d_inode->i_fop->read;
16120 +
16121 +       if(!is_user)
16122 +               set_fs(KERNEL_DS);
16123 +               
16124 +       n = (*read)(file, buf, count, &file->f_pos);
16125 +
16126 +       if(!is_user)
16127 +               set_fs(USER_DS);
16128 +
16129 +       if(ppos) *ppos = file->f_pos;
16130 +       return(n);
16131 +}
16132 +
16133 +static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
16134 +{
16135 +       ssize_t n;
16136 +       int cur, err;
16137 +       char *new_buf;
16138 +
16139 +       n = -ENOMEM;
16140 +       new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
16141 +       if(new_buf == NULL){
16142 +               printk("hppfs_read_file : kmalloc failed\n");
16143 +               goto out;
16144 +       }
16145 +       n = 0;
16146 +       while(count > 0){
16147 +               cur = min_t(ssize_t, count, PAGE_SIZE);
16148 +               err = os_read_file(fd, new_buf, cur);
16149 +               if(err < 0){
16150 +                       printk("hppfs_read : read failed, errno = %d\n",
16151 +                              count);
16152 +                       n = err;
16153 +                       goto out_free;
16154 +               }
16155 +               else if(err == 0)
16156 +                       break;
16157 +
16158 +               if(copy_to_user(buf, new_buf, err)){
16159 +                       n = -EFAULT;
16160 +                       goto out_free;
16161 +               }
16162 +               n += err;
16163 +               count -= err;
16164 +       }
16165 + out_free:
16166 +       kfree(new_buf);
16167 + out:
16168 +       return(n);
16169 +}
16170 +
16171 +static ssize_t hppfs_read(struct file *file, char *buf, size_t count, 
16172 +                         loff_t *ppos)
16173 +{
16174 +       struct hppfs_private *hppfs = file->private_data;
16175 +       struct hppfs_data *data;
16176 +       loff_t off;
16177 +       int err;
16178 +
16179 +       if(hppfs->contents != NULL){
16180 +               if(*ppos >= hppfs->len) return(0);
16181 +
16182 +               data = hppfs->contents;
16183 +               off = *ppos;
16184 +               while(off >= sizeof(data->contents)){
16185 +                       data = list_entry(data->list.next, struct hppfs_data,
16186 +                                         list);
16187 +                       off -= sizeof(data->contents);
16188 +               }
16189 +
16190 +               if(off + count > hppfs->len)
16191 +                       count = hppfs->len - off;
16192 +               copy_to_user(buf, &data->contents[off], count);
16193 +               *ppos += count;
16194 +       }
16195 +       else if(hppfs->host_fd != -1){
16196 +               err = os_seek_file(hppfs->host_fd, *ppos);
16197 +               if(err){
16198 +                       printk("hppfs_read : seek failed, errno = %d\n", err);
16199 +                       return(err);
16200 +               }
16201 +               count = hppfs_read_file(hppfs->host_fd, buf, count);
16202 +               if(count > 0)
16203 +                       *ppos += count;
16204 +       }
16205 +       else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1);
16206 +
16207 +       return(count);
16208 +}
16209 +
16210 +static ssize_t hppfs_write(struct file *file, const char *buf, size_t len, 
16211 +                          loff_t *ppos)
16212 +{
16213 +       struct hppfs_private *data = file->private_data;
16214 +       struct file *proc_file = &data->proc_file;
16215 +       ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
16216 +       int err;
16217 +
16218 +       write = proc_file->f_dentry->d_inode->i_fop->write;
16219 +
16220 +       proc_file->f_pos = file->f_pos;
16221 +       err = (*write)(proc_file, buf, len, &proc_file->f_pos);
16222 +       file->f_pos = proc_file->f_pos;
16223 +
16224 +       return(err);
16225 +}
16226 +
16227 +static int open_host_sock(char *host_file, int *filter_out)
16228 +{
16229 +       char *end;
16230 +       int fd;
16231 +
16232 +       end = &host_file[strlen(host_file)];
16233 +       strcpy(end, "/rw");
16234 +       *filter_out = 1;
16235 +       fd = os_connect_socket(host_file);
16236 +       if(fd > 0)
16237 +               return(fd);
16238 +
16239 +       strcpy(end, "/r");
16240 +       *filter_out = 0;
16241 +       fd = os_connect_socket(host_file);
16242 +       return(fd);
16243 +}
16244 +
16245 +static void free_contents(struct hppfs_data *head)
16246 +{
16247 +       struct hppfs_data *data;
16248 +       struct list_head *ele, *next;
16249 +
16250 +       if(head == NULL) return;
16251 +
16252 +       list_for_each_safe(ele, next, &head->list){
16253 +               data = list_entry(ele, struct hppfs_data, list);
16254 +               kfree(data);
16255 +       }
16256 +       kfree(head);
16257 +}
16258 +
16259 +static struct hppfs_data *hppfs_get_data(int fd, int filter, 
16260 +                                        struct file *proc_file, 
16261 +                                        struct file *hppfs_file, 
16262 +                                        loff_t *size_out)
16263 +{
16264 +       struct hppfs_data *data, *new, *head;
16265 +       int n, err;
16266 +
16267 +       err = -ENOMEM;
16268 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
16269 +       if(data == NULL){
16270 +               printk("hppfs_get_data : head allocation failed\n");
16271 +               goto failed;
16272 +       }
16273 +
16274 +       INIT_LIST_HEAD(&data->list);
16275 +
16276 +       head = data;
16277 +       *size_out = 0;
16278 +
16279 +       if(filter){
16280 +               while((n = read_proc(proc_file, data->contents,
16281 +                                    sizeof(data->contents), NULL, 0)) > 0)
16282 +                       os_write_file(fd, data->contents, n);
16283 +               err = os_shutdown_socket(fd, 0, 1);
16284 +               if(err){
16285 +                       printk("hppfs_get_data : failed to shut down "
16286 +                              "socket\n");
16287 +                       goto failed_free;
16288 +               }
16289 +       }
16290 +       while(1){
16291 +               n = os_read_file(fd, data->contents, sizeof(data->contents));
16292 +               if(n < 0){
16293 +                       err = n;
16294 +                       printk("hppfs_get_data : read failed, errno = %d\n",
16295 +                              err);
16296 +                       goto failed_free;
16297 +               }
16298 +               else if(n == 0)
16299 +                       break;
16300 +
16301 +               *size_out += n;
16302 +
16303 +               if(n < sizeof(data->contents))
16304 +                       break;
16305 +
16306 +               new = kmalloc(sizeof(*data), GFP_KERNEL);
16307 +               if(new == 0){
16308 +                       printk("hppfs_get_data : data allocation failed\n");
16309 +                       err = -ENOMEM;
16310 +                       goto failed_free;
16311 +               }
16312 +       
16313 +               INIT_LIST_HEAD(&new->list);
16314 +               list_add(&new->list, &data->list);
16315 +               data = new;
16316 +       }
16317 +       return(head);
16318 +
16319 + failed_free:
16320 +       free_contents(head);
16321 + failed:               
16322 +       return(ERR_PTR(err));
16323 +}
16324 +
16325 +static struct hppfs_private *hppfs_data(void)
16326 +{
16327 +       struct hppfs_private *data;
16328 +
16329 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
16330 +       if(data == NULL)
16331 +               return(data);
16332 +
16333 +       *data = ((struct hppfs_private ) { .host_fd             = -1,
16334 +                                          .len                 = -1,
16335 +                                          .contents            = NULL } );
16336 +       return(data);
16337 +}
16338 +
16339 +static int file_mode(int fmode)
16340 +{
16341 +       if(fmode == (FMODE_READ | FMODE_WRITE))
16342 +               return(O_RDWR);
16343 +       if(fmode == FMODE_READ)
16344 +               return(O_RDONLY);
16345 +       if(fmode == FMODE_WRITE)
16346 +               return(O_WRONLY);
16347 +       return(0);
16348 +}
16349 +
16350 +static int hppfs_open(struct inode *inode, struct file *file)
16351 +{
16352 +       struct hppfs_private *data;
16353 +       struct dentry *proc_dentry;
16354 +       char *host_file;
16355 +       int err, fd, type, filter;
16356 +
16357 +       err = -ENOMEM;
16358 +       data = hppfs_data();
16359 +       if(data == NULL)
16360 +               goto out;
16361 +
16362 +       host_file = dentry_name(file->f_dentry, strlen("/rw"));
16363 +       if(host_file == NULL)
16364 +               goto out_free2;
16365 +
16366 +       proc_dentry = HPPFS_I(inode)->proc_dentry;
16367 +
16368 +       /* XXX This isn't closed anywhere */
16369 +       err = open_private_file(&data->proc_file, proc_dentry, 
16370 +                               file_mode(file->f_mode));
16371 +       if(err)
16372 +               goto out_free1;
16373 +
16374 +       type = os_file_type(host_file);
16375 +       if(type == OS_TYPE_FILE){
16376 +               fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
16377 +               if(fd >= 0) 
16378 +                       data->host_fd = fd;
16379 +               else printk("hppfs_open : failed to open '%s', errno = %d\n",
16380 +                           host_file, -fd);
16381 +
16382 +               data->contents = NULL;
16383 +       }
16384 +       else if(type == OS_TYPE_DIR){
16385 +               fd = open_host_sock(host_file, &filter);
16386 +               if(fd > 0){
16387 +                       data->contents = hppfs_get_data(fd, filter, 
16388 +                                                       &data->proc_file, 
16389 +                                                       file, &data->len);
16390 +                       if(!IS_ERR(data->contents))
16391 +                               data->host_fd = fd;
16392 +               }
16393 +               else printk("hppfs_open : failed to open a socket in "
16394 +                           "'%s', errno = %d\n", host_file, -fd);
16395 +       }
16396 +       kfree(host_file);
16397 +
16398 +       file->private_data = data;
16399 +       return(0);
16400 +
16401 + out_free1:
16402 +       kfree(host_file);
16403 + out_free2:
16404 +       free_contents(data->contents);
16405 +       kfree(data);
16406 + out:
16407 +       return(err);
16408 +}
16409 +
16410 +static int hppfs_dir_open(struct inode *inode, struct file *file)
16411 +{
16412 +       struct hppfs_private *data;
16413 +       struct dentry *proc_dentry;
16414 +       int err;
16415 +
16416 +       err = -ENOMEM;
16417 +       data = hppfs_data();
16418 +       if(data == NULL)
16419 +               goto out;
16420 +
16421 +       proc_dentry = HPPFS_I(inode)->proc_dentry;
16422 +       err = open_private_file(&data->proc_file, proc_dentry, 
16423 +                               file_mode(file->f_mode));
16424 +       if(err)
16425 +               goto out_free;
16426 +
16427 +       file->private_data = data;
16428 +       return(0);
16429 +
16430 + out_free:
16431 +       kfree(data);
16432 + out:
16433 +       return(err);
16434 +}
16435 +
16436 +static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
16437 +{
16438 +       struct hppfs_private *data = file->private_data;
16439 +       struct file *proc_file = &data->proc_file;
16440 +       loff_t (*llseek)(struct file *, loff_t, int);
16441 +       loff_t ret;
16442 +
16443 +       llseek = proc_file->f_dentry->d_inode->i_fop->llseek;
16444 +       if(llseek != NULL){
16445 +               ret = (*llseek)(proc_file, off, where);
16446 +               if(ret < 0)
16447 +                       return(ret);
16448 +       }
16449 +
16450 +       return(default_llseek(file, off, where));
16451 +}
16452 +
16453 +static struct file_operations hppfs_file_fops = {
16454 +       .owner          = NULL,
16455 +       .llseek         = hppfs_llseek,
16456 +       .read           = hppfs_read,
16457 +       .write          = hppfs_write,
16458 +       .open           = hppfs_open,
16459 +};
16460 +
16461 +struct hppfs_dirent {
16462 +       void *vfs_dirent;
16463 +       filldir_t filldir;
16464 +       struct dentry *dentry;
16465 +};
16466 +
16467 +static int hppfs_filldir(void *d, const char *name, int size, 
16468 +                        loff_t offset, ino_t inode, unsigned int type)
16469 +{
16470 +       struct hppfs_dirent *dirent = d;
16471 +
16472 +       if(file_removed(dirent->dentry, name))
16473 +               return(0);
16474 +
16475 +       return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset, 
16476 +                                 inode, type));
16477 +}
16478 +
16479 +static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
16480 +{
16481 +       struct hppfs_private *data = file->private_data;
16482 +       struct file *proc_file = &data->proc_file;
16483 +       int (*readdir)(struct file *, void *, filldir_t);
16484 +       struct hppfs_dirent dirent = ((struct hppfs_dirent)
16485 +                                     { .vfs_dirent     = ent,
16486 +                                       .filldir        = filldir,
16487 +                                       .dentry         = file->f_dentry } );
16488 +       int err;
16489 +
16490 +       readdir = proc_file->f_dentry->d_inode->i_fop->readdir;
16491 +
16492 +       proc_file->f_pos = file->f_pos;
16493 +       err = (*readdir)(proc_file, &dirent, hppfs_filldir);
16494 +       file->f_pos = proc_file->f_pos;
16495 +
16496 +       return(err);
16497 +}
16498 +
16499 +static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
16500 +{
16501 +       return(0);
16502 +}
16503 +
16504 +static struct file_operations hppfs_dir_fops = {
16505 +       .owner          = NULL,
16506 +       .readdir        = hppfs_readdir,
16507 +       .open           = hppfs_dir_open,
16508 +       .fsync          = hppfs_fsync,
16509 +};
16510 +
16511 +static int hppfs_statfs(struct super_block *sb, struct kstatfs *sf)
16512 +{
16513 +       sf->f_blocks = 0;
16514 +       sf->f_bfree = 0;
16515 +       sf->f_bavail = 0;
16516 +       sf->f_files = 0;
16517 +       sf->f_ffree = 0;
16518 +       sf->f_type = HPPFS_SUPER_MAGIC;
16519 +       return(0);
16520 +}
16521 +
16522 +static struct inode *hppfs_alloc_inode(struct super_block *sb)
16523 +{
16524 +       struct hppfs_inode_info *hi;
16525 +
16526 +       hi = kmalloc(sizeof(*hi), GFP_KERNEL);
16527 +       if(hi == NULL) 
16528 +               return(NULL);
16529 +
16530 +       *hi = ((struct hppfs_inode_info) { .proc_dentry = NULL });
16531 +       inode_init_once(&hi->vfs_inode);
16532 +       return(&hi->vfs_inode);
16533 +}
16534 +
16535 +void hppfs_delete_inode(struct inode *ino)
16536 +{
16537 +       clear_inode(ino);
16538 +}
16539 +
16540 +static void hppfs_destroy_inode(struct inode *inode)
16541 +{
16542 +       kfree(HPPFS_I(inode));
16543 +}
16544 +
16545 +static struct super_operations hppfs_sbops = { 
16546 +       .alloc_inode    = hppfs_alloc_inode,
16547 +       .destroy_inode  = hppfs_destroy_inode,
16548 +       .read_inode     = hppfs_read_inode,
16549 +       .delete_inode   = hppfs_delete_inode,
16550 +       .statfs         = hppfs_statfs,
16551 +};
16552 +
16553 +static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen)
16554 +{
16555 +       struct file proc_file;
16556 +       struct dentry *proc_dentry;
16557 +       int (*readlink)(struct dentry *, char *, int);
16558 +       int err, n;
16559 +
16560 +       proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
16561 +       err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
16562 +       if(err) 
16563 +               return(err);
16564 +
16565 +       readlink = proc_dentry->d_inode->i_op->readlink;
16566 +       n = (*readlink)(proc_dentry, buffer, buflen);
16567 +
16568 +       close_private_file(&proc_file);
16569 +       
16570 +       return(n);
16571 +}
16572 +
16573 +static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
16574 +{
16575 +       struct file proc_file;
16576 +       struct dentry *proc_dentry;
16577 +       int (*follow_link)(struct dentry *, struct nameidata *);
16578 +       int err, n;
16579 +
16580 +       proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
16581 +       err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
16582 +       if(err) 
16583 +               return(err);
16584 +
16585 +       follow_link = proc_dentry->d_inode->i_op->follow_link;
16586 +       n = (*follow_link)(proc_dentry, nd);
16587 +
16588 +       close_private_file(&proc_file);
16589 +       
16590 +       return(n);
16591 +}
16592 +
16593 +static struct inode_operations hppfs_dir_iops = {
16594 +       .lookup         = hppfs_lookup,
16595 +};
16596 +
16597 +static struct inode_operations hppfs_link_iops = {
16598 +       .readlink       = hppfs_readlink,
16599 +       .follow_link    = hppfs_follow_link,
16600 +};
16601 +
16602 +static int init_inode(struct inode *inode, struct dentry *dentry)
16603 +{
16604 +       if(S_ISDIR(dentry->d_inode->i_mode)){
16605 +               inode->i_op = &hppfs_dir_iops;
16606 +               inode->i_fop = &hppfs_dir_fops;
16607 +       }
16608 +       else if(S_ISLNK(dentry->d_inode->i_mode)){
16609 +               inode->i_op = &hppfs_link_iops;
16610 +               inode->i_fop = &hppfs_file_fops;
16611 +       }
16612 +       else {
16613 +               inode->i_op = &hppfs_file_iops;
16614 +               inode->i_fop = &hppfs_file_fops;
16615 +       }
16616 +
16617 +       HPPFS_I(inode)->proc_dentry = dentry;
16618 +
16619 +       return(0);
16620 +}
16621 +
16622 +static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
16623 +{
16624 +       struct inode *root_inode;
16625 +       struct file_system_type *procfs;
16626 +       struct super_block *proc_sb;
16627 +       int err;
16628 +
16629 +       err = -ENOENT;
16630 +       procfs = get_fs_type("proc");
16631 +       if(procfs == NULL) 
16632 +               goto out;
16633 +
16634 +       if(list_empty(&procfs->fs_supers))
16635 +               goto out;
16636 +
16637 +       proc_sb = list_entry(procfs->fs_supers.next, struct super_block,
16638 +                            s_instances);
16639 +       
16640 +       sb->s_blocksize = 1024;
16641 +       sb->s_blocksize_bits = 10;
16642 +       sb->s_magic = HPPFS_SUPER_MAGIC;
16643 +       sb->s_op = &hppfs_sbops;
16644 +
16645 +       root_inode = iget(sb, 0);
16646 +       if(root_inode == NULL)
16647 +               goto out;
16648 +
16649 +       err = init_inode(root_inode, proc_sb->s_root);
16650 +       if(err)
16651 +               goto out_put;
16652 +
16653 +       err = -ENOMEM;
16654 +       sb->s_root = d_alloc_root(root_inode);
16655 +       if(sb->s_root == NULL)
16656 +               goto out_put;
16657 +
16658 +       hppfs_read_inode(root_inode);
16659 +
16660 +       return(0);
16661 +
16662 + out_put:
16663 +       iput(root_inode);
16664 + out:
16665 +       return(err);
16666 +}
16667 +
16668 +static struct super_block *hppfs_read_super(struct file_system_type *type,
16669 +                                            int flags, const char *dev_name,
16670 +                                            void *data)
16671 +{
16672 +       return(get_sb_nodev(type, flags, data, hppfs_fill_super));
16673 +}
16674 +
16675 +static struct file_system_type hppfs_type = {
16676 +       .owner          = THIS_MODULE,
16677 +       .name           = "hppfs",
16678 +       .get_sb         = hppfs_read_super,
16679 +       .kill_sb        = kill_anon_super,
16680 +       .fs_flags       = 0,
16681 +};
16682 +
16683 +static int __init init_hppfs(void)
16684 +{
16685 +       return(register_filesystem(&hppfs_type));
16686 +}
16687 +
16688 +static void __exit exit_hppfs(void)
16689 +{
16690 +       unregister_filesystem(&hppfs_type);
16691 +}
16692 +
16693 +module_init(init_hppfs)
16694 +module_exit(exit_hppfs)
16695 +MODULE_LICENSE("GPL");
16696 +
16697 +/*
16698 + * Overrides for Emacs so that we follow Linus's tabbing style.
16699 + * Emacs will notice this stuff at the end of the file and automatically
16700 + * adjust the settings for this buffer only.  This must remain at the end
16701 + * of the file.
16702 + * ---------------------------------------------------------------------------
16703 + * Local variables:
16704 + * c-file-style: "linux"
16705 + * End:
16706 + */
16707 diff -Naur a/fs/hppfs/Makefile b/fs/hppfs/Makefile
16708 --- a/fs/hppfs/Makefile 1969-12-31 19:00:00.000000000 -0500
16709 +++ b/fs/hppfs/Makefile 2004-01-08 22:28:32.000000000 -0500
16710 @@ -0,0 +1,19 @@
16711 +# 
16712 +# Copyright (C) 2002, 2003 Jeff Dike (jdike@karaya.com)
16713 +# Licensed under the GPL
16714 +#
16715 +
16716 +hppfs-objs := hppfs_kern.o
16717 +
16718 +obj-y = 
16719 +obj-$(CONFIG_HPPFS) += hppfs.o
16720 +
16721 +clean:
16722 +
16723 +modules:
16724 +
16725 +fastdep:
16726 +
16727 +dep:
16728 +
16729 +archmrproper: clean
16730 diff -Naur a/fs/Makefile b/fs/Makefile
16731 --- a/fs/Makefile       2004-01-08 22:23:07.000000000 -0500
16732 +++ b/fs/Makefile       2004-01-08 22:30:15.000000000 -0500
16733 @@ -91,3 +91,5 @@
16734  obj-$(CONFIG_XFS_FS)           += xfs/
16735  obj-$(CONFIG_AFS_FS)           += afs/
16736  obj-$(CONFIG_BEFS_FS)          += befs/
16737 +obj-$(CONFIG_HOSTFS)           += hostfs/
16738 +obj-$(CONFIG_HPPFS)            += hppfs/
16739 diff -Naur a/include/asm-um/archparam-i386.h b/include/asm-um/archparam-i386.h
16740 --- a/include/asm-um/archparam-i386.h   2004-01-08 22:28:22.000000000 -0500
16741 +++ b/include/asm-um/archparam-i386.h   2004-01-08 22:34:31.000000000 -0500
16742 @@ -1,5 +1,5 @@
16743  /* 
16744 - * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
16745 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
16746   * Licensed under the GPL
16747   */
16748  
16749 @@ -56,6 +56,65 @@
16750         pr_reg[16] = PT_REGS_SS(regs);          \
16751  } while(0);
16752  
16753 +#define VSYSCALL_BASE  (__fix_to_virt(FIX_VSYSCALL))
16754 +#define VSYSCALL_EHDR  ((const struct elfhdr *) VSYSCALL_BASE)
16755 +#define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
16756 +extern void *__kernel_vsyscall;
16757 +
16758 +/*
16759 + * Architecture-neutral AT_ values in 0-17, leave some room
16760 + * for more of them, start the x86-specific ones at 32.
16761 + */
16762 +#define AT_SYSINFO             32
16763 +#define AT_SYSINFO_EHDR                33
16764 +
16765 +#define ARCH_DLINFO                                            \
16766 +do {                                                           \
16767 +               NEW_AUX_ENT(AT_SYSINFO, VSYSCALL_ENTRY);        \
16768 +               NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE);    \
16769 +} while (0)
16770 +
16771 +/*
16772 + * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
16773 + * extra segments containing the vsyscall DSO contents.  Dumping its
16774 + * contents makes post-mortem fully interpretable later without matching up
16775 + * the same kernel and hardware config to see what PC values meant.
16776 + * Dumping its extra ELF program headers includes all the other information
16777 + * a debugger needs to easily find how the vsyscall DSO was being used.
16778 + */
16779 +#define ELF_CORE_EXTRA_PHDRS           (VSYSCALL_EHDR->e_phnum)
16780 +#define ELF_CORE_WRITE_EXTRA_PHDRS                                           \
16781 +do {                                                                         \
16782 +       const struct elf_phdr *const vsyscall_phdrs =                         \
16783 +               (const struct elf_phdr *) (VSYSCALL_BASE                      \
16784 +                                          + VSYSCALL_EHDR->e_phoff);         \
16785 +       int i;                                                                \
16786 +       Elf32_Off ofs = 0;                                                    \
16787 +       for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {                        \
16788 +               struct elf_phdr phdr = vsyscall_phdrs[i];                     \
16789 +               if (phdr.p_type == PT_LOAD) {                                 \
16790 +                       ofs = phdr.p_offset = offset;                         \
16791 +                       offset += phdr.p_filesz;                              \
16792 +               }                                                             \
16793 +               else                                                          \
16794 +                       phdr.p_offset += ofs;                                 \
16795 +               phdr.p_paddr = 0; /* match other core phdrs */                \
16796 +               DUMP_WRITE(&phdr, sizeof(phdr));                              \
16797 +       }                                                                     \
16798 +} while (0)
16799 +#define ELF_CORE_WRITE_EXTRA_DATA                                            \
16800 +do {                                                                         \
16801 +       const struct elf_phdr *const vsyscall_phdrs =                         \
16802 +               (const struct elf_phdr *) (VSYSCALL_BASE                      \
16803 +                                          + VSYSCALL_EHDR->e_phoff);         \
16804 +       int i;                                                                \
16805 +       for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {                        \
16806 +               if (vsyscall_phdrs[i].p_type == PT_LOAD)                      \
16807 +                       DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr,        \
16808 +                                  vsyscall_phdrs[i].p_filesz);               \
16809 +       }                                                                     \
16810 +} while (0)
16811 +
16812  /********* Bits for asm-um/delay.h **********/
16813  
16814  typedef unsigned long um_udelay_t;
16815 diff -Naur a/include/asm-um/common.lds.S b/include/asm-um/common.lds.S
16816 --- a/include/asm-um/common.lds.S       2004-01-08 22:16:07.000000000 -0500
16817 +++ b/include/asm-um/common.lds.S       2004-01-08 22:21:49.000000000 -0500
16818 @@ -1,3 +1,5 @@
16819 +#include <asm-generic/vmlinux.lds.h>
16820 +
16821    .fini      : { *(.fini)    } =0x9090
16822    _etext = .;
16823    PROVIDE (etext = .);
16824 @@ -67,6 +69,10 @@
16825    }
16826    __initcall_end = .;
16827  
16828 +  __con_initcall_start = .;
16829 +  .con_initcall.init : { *(.con_initcall.init) }
16830 +  __con_initcall_end = .;
16831 +
16832    __uml_initcall_start = .;
16833    .uml.initcall.init : { *(.uml.initcall.init) }
16834    __uml_initcall_end = .;
16835 @@ -80,7 +86,33 @@
16836    .uml.exitcall : { *(.uml.exitcall.exit) }
16837    __uml_exitcall_end = .;
16838  
16839 -  . = ALIGN(4096);
16840 +  . = ALIGN(4);
16841 +  __alt_instructions = .;
16842 +  .altinstructions : { *(.altinstructions) } 
16843 +  __alt_instructions_end = .; 
16844 +  .altinstr_replacement : { *(.altinstr_replacement) } 
16845 +  /* .exit.text is discard at runtime, not link time, to deal with references
16846 +     from .altinstructions and .eh_frame */
16847 +  .exit.text : { *(.exit.text) }
16848 +  .exit.data : { *(.exit.data) }
16849
16850 +  __preinit_array_start = .;
16851 +  .preinit_array : { *(.preinit_array) }
16852 +  __preinit_array_end = .;
16853 +  __init_array_start = .;
16854 +  .init_array : { *(.init_array) }
16855 +  __init_array_end = .;
16856 +  __fini_array_start = .;
16857 +  .fini_array : { *(.fini_array) }
16858 +  __fini_array_end = .;
16859 +
16860 +   . = ALIGN(4096);
16861    __initramfs_start = .;
16862    .init.ramfs : { *(.init.ramfs) }
16863    __initramfs_end = .;
16864 +
16865 +  /* Sections to be discarded */
16866 +  /DISCARD/ : {
16867 +       *(.exitcall.exit)
16868 +  }
16869
16870 diff -Naur a/include/asm-um/cpufeature.h b/include/asm-um/cpufeature.h
16871 --- a/include/asm-um/cpufeature.h       1969-12-31 19:00:00.000000000 -0500
16872 +++ b/include/asm-um/cpufeature.h       2004-01-08 22:17:48.000000000 -0500
16873 @@ -0,0 +1,6 @@
16874 +#ifndef __UM_CPUFEATURE_H
16875 +#define __UM_CPUFEATURE_H
16876 +
16877 +#include "asm/arch/cpufeature.h"
16878 +
16879 +#endif
16880 diff -Naur a/include/asm-um/current.h b/include/asm-um/current.h
16881 --- a/include/asm-um/current.h  2004-01-08 22:14:14.000000000 -0500
16882 +++ b/include/asm-um/current.h  2004-01-08 22:19:07.000000000 -0500
16883 @@ -16,8 +16,10 @@
16884  #define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & \
16885                                 (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
16886  
16887 -#define current ({ int dummy; \
16888 -                   ((struct thread_info *) CURRENT_THREAD(dummy))->task; })
16889 +#define current_thread \
16890 +       ({ int dummy; ((struct thread_info *) CURRENT_THREAD(dummy)); })
16891 +
16892 +#define current (current_thread->task)
16893  
16894  #endif /* __ASSEMBLY__ */
16895  
16896 diff -Naur a/include/asm-um/fixmap.h b/include/asm-um/fixmap.h
16897 --- a/include/asm-um/fixmap.h   2004-01-08 22:30:17.000000000 -0500
16898 +++ b/include/asm-um/fixmap.h   2004-01-08 22:35:33.000000000 -0500
16899 @@ -34,6 +34,7 @@
16900         FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
16901         FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
16902  #endif
16903 +       FIX_VSYSCALL,
16904         __end_of_fixed_addresses
16905  };
16906  
16907 @@ -63,6 +64,13 @@
16908  #define __fix_to_virt(x)       (FIXADDR_TOP - ((x) << PAGE_SHIFT))
16909  #define __virt_to_fix(x)      ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
16910  
16911 +/*
16912 + * This is the range that is readable by user mode, and things
16913 + * acting like user mode such as get_user_pages.
16914 + */
16915 +#define FIXADDR_USER_START     (__fix_to_virt(FIX_VSYSCALL))
16916 +#define FIXADDR_USER_END       (FIXADDR_USER_START + PAGE_SIZE)
16917 +
16918  extern void __this_fixmap_does_not_exist(void);
16919  
16920  /*
16921 diff -Naur a/include/asm-um/irq.h b/include/asm-um/irq.h
16922 --- a/include/asm-um/irq.h      2004-01-08 22:32:16.000000000 -0500
16923 +++ b/include/asm-um/irq.h      2004-01-08 22:36:27.000000000 -0500
16924 @@ -1,15 +1,6 @@
16925  #ifndef __UM_IRQ_H
16926  #define __UM_IRQ_H
16927  
16928 -/* The i386 irq.h has a struct task_struct in a prototype without including
16929 - * sched.h.  This forward declaration kills the resulting warning.
16930 - */
16931 -struct task_struct;
16932 -
16933 -#include "asm/ptrace.h"
16934 -
16935 -#undef NR_IRQS
16936 -
16937  #define TIMER_IRQ              0
16938  #define UMN_IRQ                        1
16939  #define CONSOLE_IRQ            2
16940 @@ -28,8 +19,4 @@
16941  #define LAST_IRQ XTERM_IRQ
16942  #define NR_IRQS (LAST_IRQ + 1)
16943  
16944 -extern int um_request_irq(unsigned int irq, int fd, int type,
16945 -                         void (*handler)(int, void *, struct pt_regs *),
16946 -                         unsigned long irqflags,  const char * devname,
16947 -                         void *dev_id);
16948  #endif
16949 diff -Naur a/include/asm-um/local.h b/include/asm-um/local.h
16950 --- a/include/asm-um/local.h    1969-12-31 19:00:00.000000000 -0500
16951 +++ b/include/asm-um/local.h    2004-01-08 22:31:28.000000000 -0500
16952 @@ -0,0 +1,6 @@
16953 +#ifndef __UM_LOCAL_H
16954 +#define __UM_LOCAL_H
16955 +
16956 +#include "asm/arch/local.h"
16957 +
16958 +#endif
16959 diff -Naur a/include/asm-um/module-generic.h b/include/asm-um/module-generic.h
16960 --- a/include/asm-um/module-generic.h   1969-12-31 19:00:00.000000000 -0500
16961 +++ b/include/asm-um/module-generic.h   2004-01-08 22:29:52.000000000 -0500
16962 @@ -0,0 +1,6 @@
16963 +#ifndef __UM_MODULE_GENERIC_H
16964 +#define __UM_MODULE_GENERIC_H
16965 +
16966 +#include "asm/arch/module.h"
16967 +
16968 +#endif
16969 diff -Naur a/include/asm-um/module-i386.h b/include/asm-um/module-i386.h
16970 --- a/include/asm-um/module-i386.h      1969-12-31 19:00:00.000000000 -0500
16971 +++ b/include/asm-um/module-i386.h      2004-01-08 22:29:46.000000000 -0500
16972 @@ -0,0 +1,13 @@
16973 +#ifndef __UM_MODULE_I386_H
16974 +#define __UM_MODULE_I386_H
16975 +
16976 +/* UML is simple */
16977 +struct mod_arch_specific
16978 +{
16979 +};
16980 +
16981 +#define Elf_Shdr Elf32_Shdr
16982 +#define Elf_Sym Elf32_Sym
16983 +#define Elf_Ehdr Elf32_Ehdr
16984 +
16985 +#endif
16986 diff -Naur a/include/asm-um/page.h b/include/asm-um/page.h
16987 --- a/include/asm-um/page.h     2004-01-08 22:23:04.000000000 -0500
16988 +++ b/include/asm-um/page.h     2004-01-08 22:30:06.000000000 -0500
16989 @@ -1,10 +1,14 @@
16990 +/* 
16991 + *  Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
16992 + * Licensed under the GPL
16993 + */
16994 +
16995  #ifndef __UM_PAGE_H
16996  #define __UM_PAGE_H
16997  
16998  struct page;
16999  
17000  #include "asm/arch/page.h"
17001 -#include "asm/bug.h"
17002  
17003  #undef __pa
17004  #undef __va
17005 @@ -24,25 +28,36 @@
17006  
17007  #define __va_space (8*1024*1024)
17008  
17009 -extern unsigned long region_pa(void *virt);
17010 -extern void *region_va(unsigned long phys);
17011 -
17012 -#define __pa(virt) region_pa((void *) (virt))
17013 -#define __va(phys) region_va((unsigned long) (phys))
17014 -
17015 -extern unsigned long page_to_pfn(struct page *page);
17016 -extern struct page *pfn_to_page(unsigned long pfn);
17017 +extern unsigned long to_phys(void *virt);
17018 +extern void *to_virt(unsigned long phys);
17019  
17020 -extern struct page *phys_to_page(unsigned long phys);
17021 +#define __pa(virt) to_phys((void *) virt)
17022 +#define __va(phys) to_virt((unsigned long) phys)
17023  
17024 -#define virt_to_page(v) (phys_to_page(__pa(v)))
17025 +#define page_to_pfn(page) ((page) - mem_map)
17026 +#define pfn_to_page(pfn) (mem_map + (pfn))
17027  
17028 -extern struct page *page_mem_map(struct page *page);
17029 +#define phys_to_pfn(p) ((p) >> PAGE_SHIFT)
17030 +#define pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)
17031  
17032 -#define pfn_valid(pfn) (page_mem_map(pfn_to_page(pfn)) != NULL)
17033 -#define virt_addr_valid(v) pfn_valid(__pa(v) >> PAGE_SHIFT)
17034 +#define pfn_valid(pfn) ((pfn) < max_mapnr)
17035 +#define virt_addr_valid(v) pfn_valid(phys_to_pfn(__pa(v)))
17036  
17037  extern struct page *arch_validate(struct page *page, int mask, int order);
17038  #define HAVE_ARCH_VALIDATE
17039  
17040 +extern void arch_free_page(struct page *page, int order);
17041 +#define HAVE_ARCH_FREE_PAGE
17042 +
17043  #endif
17044 +
17045 +/*
17046 + * Overrides for Emacs so that we follow Linus's tabbing style.
17047 + * Emacs will notice this stuff at the end of the file and automatically
17048 + * adjust the settings for this buffer only.  This must remain at the end
17049 + * of the file.
17050 + * ---------------------------------------------------------------------------
17051 + * Local variables:
17052 + * c-file-style: "linux"
17053 + * End:
17054 + */
17055 diff -Naur a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h
17056 --- a/include/asm-um/pgtable.h  2004-01-08 22:33:43.000000000 -0500
17057 +++ b/include/asm-um/pgtable.h  2004-01-08 22:36:57.000000000 -0500
17058 @@ -65,10 +65,10 @@
17059   * area for the same reason. ;)
17060   */
17061  
17062 -extern unsigned long high_physmem;
17063 +extern unsigned long end_iomem;
17064  
17065  #define VMALLOC_OFFSET (__va_space)
17066 -#define VMALLOC_START  (((unsigned long) high_physmem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
17067 +#define VMALLOC_START  ((end_iomem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
17068  
17069  #ifdef CONFIG_HIGHMEM
17070  # define VMALLOC_END   (PKMAP_BASE-2*PAGE_SIZE)
17071 @@ -78,12 +78,13 @@
17072  
17073  #define _PAGE_PRESENT  0x001
17074  #define _PAGE_NEWPAGE  0x002
17075 -#define _PAGE_PROTNONE 0x004   /* If not present */
17076 -#define _PAGE_RW       0x008
17077 -#define _PAGE_USER     0x010
17078 -#define _PAGE_ACCESSED 0x020
17079 -#define _PAGE_DIRTY    0x040
17080 -#define _PAGE_NEWPROT   0x080
17081 +#define _PAGE_NEWPROT   0x004
17082 +#define _PAGE_FILE     0x008   /* set:pagecache unset:swap */
17083 +#define _PAGE_PROTNONE 0x010   /* If not present */
17084 +#define _PAGE_RW       0x020
17085 +#define _PAGE_USER     0x040
17086 +#define _PAGE_ACCESSED 0x080
17087 +#define _PAGE_DIRTY    0x100
17088  
17089  #define REGION_MASK    0xf0000000
17090  #define REGION_SHIFT   28
17091 @@ -143,7 +144,8 @@
17092  
17093  #define BAD_PAGETABLE __bad_pagetable()
17094  #define BAD_PAGE __bad_page()
17095 -#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
17096 +
17097 +#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
17098  
17099  /* number of bits that fit into a memory pointer */
17100  #define BITS_PER_PTR                   (8*sizeof(unsigned long))
17101 @@ -164,9 +166,6 @@
17102  
17103  #define pte_clear(xp)  do { pte_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
17104  
17105 -#define phys_region_index(x) (((x) & REGION_MASK) >> REGION_SHIFT)
17106 -#define pte_region_index(x) phys_region_index(pte_val(x))
17107 -
17108  #define pmd_none(x)    (!(pmd_val(x) & ~_PAGE_NEWPAGE))
17109  #define        pmd_bad(x)      ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
17110  #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
17111 @@ -188,19 +187,25 @@
17112  
17113  #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
17114  
17115 -extern struct page *pte_mem_map(pte_t pte);
17116 -extern struct page *phys_mem_map(unsigned long phys);
17117 -extern unsigned long phys_to_pfn(unsigned long p);
17118 -extern unsigned long pfn_to_phys(unsigned long pfn);
17119 -
17120 -#define pte_page(x) pfn_to_page(pte_pfn(x))
17121 -#define pte_address(x) (__va(pte_val(x) & PAGE_MASK))
17122 -#define mk_phys(a, r) ((a) + (r << REGION_SHIFT))
17123 -#define phys_addr(p) ((p) & ~REGION_MASK)
17124 -#define phys_page(p) (phys_mem_map(p) + ((phys_addr(p)) >> PAGE_SHIFT))
17125 +#define pte_page(pte) phys_to_page(pte_val(pte))
17126 +#define pmd_page(pmd) phys_to_page(pmd_val(pmd) & PAGE_MASK)
17127 +
17128  #define pte_pfn(x) phys_to_pfn(pte_val(x))
17129  #define pfn_pte(pfn, prot) __pte(pfn_to_phys(pfn) | pgprot_val(prot))
17130 -#define pfn_pmd(pfn, prot) __pmd(pfn_to_phys(pfn) | pgprot_val(prot))
17131 +
17132 +extern struct page *phys_to_page(const unsigned long phys);
17133 +extern struct page *__virt_to_page(const unsigned long virt);
17134 +#define virt_to_page(addr) __virt_to_page((const unsigned long) addr)
17135 +  
17136 +/*
17137 + * Bits 0 through 3 are taken
17138 + */
17139 +#define PTE_FILE_MAX_BITS      28
17140 +
17141 +#define pte_to_pgoff(pte) ((pte).pte_low >> 4)
17142 +
17143 +#define pgoff_to_pte(off) \
17144 +       ((pte_t) { ((off) << 4) + _PAGE_FILE })
17145  
17146  static inline pte_t pte_mknewprot(pte_t pte)
17147  {
17148 @@ -235,6 +240,12 @@
17149   * The following only work if pte_present() is true.
17150   * Undefined behaviour if not..
17151   */
17152 +static inline int pte_user(pte_t pte)
17153 +{ 
17154 +       return((pte_val(pte) & _PAGE_USER) && 
17155 +              !(pte_val(pte) & _PAGE_PROTNONE));
17156 +}
17157 +
17158  static inline int pte_read(pte_t pte)
17159  { 
17160         return((pte_val(pte) & _PAGE_USER) && 
17161 @@ -252,6 +263,14 @@
17162                !(pte_val(pte) & _PAGE_PROTNONE));
17163  }
17164  
17165 +/*
17166 + * The following only works if pte_present() is not true.
17167 + */
17168 +static inline int pte_file(pte_t pte)
17169 +{ 
17170 +       return (pte).pte_low & _PAGE_FILE; 
17171 +}
17172 +
17173  static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
17174  static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
17175  static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; }
17176 @@ -334,14 +353,7 @@
17177   * and a page entry and page directory to the page they refer to.
17178   */
17179  
17180 -#define mk_pte(page, pgprot) \
17181 -({                                     \
17182 -       pte_t __pte;                    \
17183 -                                        \
17184 -       pte_val(__pte) = page_to_phys(page) + pgprot_val(pgprot);\
17185 -       if(pte_present(__pte)) pte_mknewprot(pte_mknewpage(__pte)); \
17186 -       __pte;                          \
17187 -})
17188 +extern pte_t mk_pte(struct page *page, pgprot_t pgprot);
17189  
17190  static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
17191  {
17192 @@ -351,17 +363,27 @@
17193  }
17194  
17195  #define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
17196 -#define pmd_page(pmd) (phys_mem_map(pmd_val(pmd) & PAGE_MASK) + \
17197 -                      ((phys_addr(pmd_val(pmd)) >> PAGE_SHIFT)))
17198  
17199 -/* to find an entry in a page-table-directory. */
17200 +/*
17201 + * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
17202 + *
17203 + * this macro returns the index of the entry in the pgd page which would
17204 + * control the given virtual address
17205 + */
17206  #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
17207  
17208 -/* to find an entry in a page-table-directory */
17209 +/*
17210 + * pgd_offset() returns a (pgd_t *)
17211 + * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
17212 + */
17213  #define pgd_offset(mm, address) \
17214  ((mm)->pgd + ((address) >> PGDIR_SHIFT))
17215  
17216 -/* to find an entry in a kernel page-table-directory */
17217 +
17218 +/*
17219 + * a shortcut which implies the use of the kernel's pgd, instead
17220 + * of a process's
17221 + */
17222  #define pgd_offset_k(address) pgd_offset(&init_mm, address)
17223  
17224  #define pmd_index(address) \
17225 @@ -373,7 +395,12 @@
17226         return (pmd_t *) dir;
17227  }
17228  
17229 -/* Find an entry in the third-level page table.. */ 
17230 +/*
17231 + * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
17232 + *
17233 + * this macro returns the index of the entry in the pte page which would
17234 + * control the given virtual address
17235 + */
17236  #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
17237  #define pte_offset_kernel(dir, address) \
17238         ((pte_t *) pmd_page_kernel(*(dir)) +  pte_index(address))
17239 @@ -399,11 +426,11 @@
17240  #define update_mmu_cache(vma,address,pte) do ; while (0)
17241  
17242  /* Encode and de-code a swap entry */
17243 -#define __swp_type(x)                  (((x).val >> 3) & 0x7f)
17244 -#define __swp_offset(x)                        ((x).val >> 10)
17245 +#define __swp_type(x)                  (((x).val >> 4) & 0x3f)
17246 +#define __swp_offset(x)                        ((x).val >> 11)
17247  
17248  #define __swp_entry(type, offset) \
17249 -       ((swp_entry_t) { ((type) << 3) | ((offset) << 10) })
17250 +       ((swp_entry_t) { ((type) << 4) | ((offset) << 11) })
17251  #define __pte_to_swp_entry(pte) \
17252         ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
17253  #define __swp_entry_to_pte(x)          ((pte_t) { (x).val })
17254 diff -Naur a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h
17255 --- a/include/asm-um/processor-generic.h        2004-01-08 22:15:51.000000000 -0500
17256 +++ b/include/asm-um/processor-generic.h        2004-01-08 22:21:26.000000000 -0500
17257 @@ -11,9 +11,7 @@
17258  struct task_struct;
17259  
17260  #include "linux/config.h"
17261 -#include "linux/signal.h"
17262  #include "asm/ptrace.h"
17263 -#include "asm/siginfo.h"
17264  #include "choose-mode.h"
17265  
17266  struct mm_struct;
17267 @@ -22,23 +20,6 @@
17268  
17269  #define cpu_relax()    do ; while (0)
17270  
17271 -#ifdef CONFIG_MODE_TT
17272 -struct proc_tt_mode {
17273 -       int extern_pid;
17274 -       int tracing;
17275 -       int switch_pipe[2];
17276 -       int singlestep_syscall;
17277 -       int vm_seq;
17278 -};
17279 -#endif
17280 -
17281 -#ifdef CONFIG_MODE_SKAS
17282 -struct proc_skas_mode {
17283 -       void *switch_buf;
17284 -       void *fork_buf;
17285 -};
17286 -#endif
17287 -
17288  struct thread_struct {
17289         int forking;
17290         unsigned long kernel_stack;
17291 @@ -46,6 +27,7 @@
17292         struct pt_regs regs;
17293         unsigned long cr2;
17294         int err;
17295 +       unsigned long trap_no;
17296         void *fault_addr;
17297         void *fault_catcher;
17298         struct task_struct *prev_sched;
17299 @@ -54,10 +36,20 @@
17300         struct arch_thread arch;
17301         union {
17302  #ifdef CONFIG_MODE_TT
17303 -               struct proc_tt_mode tt;
17304 +               struct {
17305 +                       int extern_pid;
17306 +                       int tracing;
17307 +                       int switch_pipe[2];
17308 +                       int singlestep_syscall;
17309 +                       int vm_seq;
17310 +               } tt;
17311  #endif
17312  #ifdef CONFIG_MODE_SKAS
17313 -               struct proc_skas_mode skas;
17314 +               struct {
17315 +                       void *switch_buf;
17316 +                       void *fork_buf;
17317 +                       int mm_count;
17318 +               } skas;
17319  #endif
17320         } mode;
17321         struct {
17322 @@ -101,14 +93,19 @@
17323  } mm_segment_t;
17324  
17325  extern struct task_struct *alloc_task_struct(void);
17326 -extern void free_task_struct(struct task_struct *task);
17327  
17328  extern void release_thread(struct task_struct *);
17329  extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
17330  extern void dump_thread(struct pt_regs *regs, struct user *u);
17331 +extern void prepare_to_copy(struct task_struct *tsk);
17332  
17333  extern unsigned long thread_saved_pc(struct task_struct *t);
17334  
17335 +static inline void mm_copy_segments(struct mm_struct *from_mm, 
17336 +                                   struct mm_struct *new_mm)
17337 +{
17338 +}
17339 +
17340  #define init_stack     (init_thread_union.stack)
17341  
17342  /*
17343 diff -Naur a/include/asm-um/processor-i386.h b/include/asm-um/processor-i386.h
17344 --- a/include/asm-um/processor-i386.h   2004-01-08 22:13:50.000000000 -0500
17345 +++ b/include/asm-um/processor-i386.h   2004-01-08 22:18:50.000000000 -0500
17346 @@ -6,8 +6,8 @@
17347  #ifndef __UM_PROCESSOR_I386_H
17348  #define __UM_PROCESSOR_I386_H
17349  
17350 -extern int cpu_has_xmm;
17351 -extern int cpu_has_cmov;
17352 +extern int host_has_xmm;
17353 +extern int host_has_cmov;
17354  
17355  struct arch_thread {
17356         unsigned long debugregs[8];
17357 diff -Naur a/include/asm-um/sections.h b/include/asm-um/sections.h
17358 --- a/include/asm-um/sections.h 1969-12-31 19:00:00.000000000 -0500
17359 +++ b/include/asm-um/sections.h 2004-01-08 22:32:18.000000000 -0500
17360 @@ -0,0 +1,7 @@
17361 +#ifndef _UM_SECTIONS_H
17362 +#define _UM_SECTIONS_H
17363 +
17364 +/* nothing to see, move along */
17365 +#include <asm-generic/sections.h>
17366 +
17367 +#endif
17368 diff -Naur a/include/asm-um/smp.h b/include/asm-um/smp.h
17369 --- a/include/asm-um/smp.h      2004-01-08 22:13:34.000000000 -0500
17370 +++ b/include/asm-um/smp.h      2004-01-08 22:17:25.000000000 -0500
17371 @@ -10,7 +10,7 @@
17372  
17373  extern cpumask_t cpu_online_map;
17374  
17375 -#define smp_processor_id() (current->thread_info->cpu)
17376 +#define smp_processor_id() (current_thread->cpu)
17377  #define cpu_logical_map(n) (n)
17378  #define cpu_number_map(n) (n)
17379  #define PROC_CHANGE_PENALTY    15 /* Pick a number, any number */
17380 diff -Naur a/include/asm-um/spinlock.h b/include/asm-um/spinlock.h
17381 --- a/include/asm-um/spinlock.h 2004-01-08 22:29:58.000000000 -0500
17382 +++ b/include/asm-um/spinlock.h 1969-12-31 19:00:00.000000000 -0500
17383 @@ -1,10 +0,0 @@
17384 -#ifndef __UM_SPINLOCK_H
17385 -#define __UM_SPINLOCK_H
17386 -
17387 -#include "linux/config.h"
17388 -
17389 -#ifdef CONFIG_SMP
17390 -#include "asm/arch/spinlock.h"
17391 -#endif
17392 -
17393 -#endif
17394 diff -Naur a/include/asm-um/system-generic.h b/include/asm-um/system-generic.h
17395 --- a/include/asm-um/system-generic.h   2004-01-08 22:32:37.000000000 -0500
17396 +++ b/include/asm-um/system-generic.h   2004-01-08 22:36:38.000000000 -0500
17397 @@ -23,8 +23,10 @@
17398  extern void block_signals(void);
17399  extern void unblock_signals(void);
17400  
17401 -#define local_save_flags(flags) do { (flags) = get_signals(); } while(0)
17402 -#define local_irq_restore(flags) do { set_signals(flags); } while(0)
17403 +#define local_save_flags(flags) do { typecheck(unsigned long, flags); \
17404 +                                    (flags) = get_signals(); } while(0)
17405 +#define local_irq_restore(flags) do { typecheck(unsigned long, flags); \
17406 +                                     set_signals(flags); } while(0)
17407  
17408  #define local_irq_save(flags) do { local_save_flags(flags); \
17409                                     local_irq_disable(); } while(0)
17410 @@ -39,4 +41,7 @@
17411          (flags == 0);                   \
17412  })
17413  
17414 +extern void *_switch_to(void *prev, void *next, void *last);
17415 +#define switch_to(prev, next, last) prev = _switch_to(prev, next, last)
17416 +
17417  #endif
17418 diff -Naur a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h
17419 --- a/include/asm-um/thread_info.h      2004-01-08 22:18:02.000000000 -0500
17420 +++ b/include/asm-um/thread_info.h      2004-01-08 22:24:10.000000000 -0500
17421 @@ -9,6 +9,7 @@
17422  #ifndef __ASSEMBLY__
17423  
17424  #include <asm/processor.h>
17425 +#include <asm/types.h>
17426  
17427  struct thread_info {
17428         struct task_struct      *task;          /* main task structure */
17429 @@ -43,15 +44,18 @@
17430  static inline struct thread_info *current_thread_info(void)
17431  {
17432         struct thread_info *ti;
17433 -       __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~16383UL));
17434 +       unsigned long mask = PAGE_SIZE * 
17435 +               (1 << CONFIG_KERNEL_STACK_ORDER) - 1;
17436 +       __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~mask));
17437         return ti;
17438  }
17439  
17440  /* thread information allocation */
17441 -#define THREAD_SIZE (4*PAGE_SIZE)
17442 -#define alloc_thread_info(tsk) ((struct thread_info *) \
17443 -       __get_free_pages(GFP_KERNEL,2))
17444 -#define free_thread_info(ti) free_pages((unsigned long) (ti), 2)
17445 +#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
17446 +#define alloc_thread_info(tsk) \
17447 +       ((struct thread_info *) kmalloc(THREAD_SIZE, GFP_KERNEL))
17448 +#define free_thread_info(ti) kfree(ti)
17449 +       
17450  #define get_thread_info(ti) get_task_struct((ti)->task)
17451  #define put_thread_info(ti) put_task_struct((ti)->task)
17452  
17453 @@ -65,11 +69,13 @@
17454  #define TIF_POLLING_NRFLAG      3       /* true if poll_idle() is polling 
17455                                          * TIF_NEED_RESCHED 
17456                                          */
17457 +#define TIF_RESTART_BLOCK      4
17458  
17459  #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
17460  #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
17461  #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
17462  #define _TIF_POLLING_NRFLAG     (1 << TIF_POLLING_NRFLAG)
17463 +#define _TIF_RESTART_BLOCK     (1 << TIF_RESTART_BLOCK)
17464  
17465  #endif
17466  
17467 diff -Naur a/include/asm-um/timex.h b/include/asm-um/timex.h
17468 --- a/include/asm-um/timex.h    2004-01-08 22:24:16.000000000 -0500
17469 +++ b/include/asm-um/timex.h    2004-01-08 22:31:33.000000000 -0500
17470 @@ -1,8 +1,6 @@
17471  #ifndef __UM_TIMEX_H
17472  #define __UM_TIMEX_H
17473  
17474 -#include "linux/time.h"
17475 -
17476  typedef unsigned long cycles_t;
17477  
17478  #define cacheflush_time (0)
17479 diff -Naur a/include/asm-um/uaccess.h b/include/asm-um/uaccess.h
17480 --- a/include/asm-um/uaccess.h  2004-01-08 22:25:21.000000000 -0500
17481 +++ b/include/asm-um/uaccess.h  2004-01-08 22:32:41.000000000 -0500
17482 @@ -6,6 +6,8 @@
17483  #ifndef __UM_UACCESS_H
17484  #define __UM_UACCESS_H
17485  
17486 +#include "linux/sched.h"
17487 +
17488  #define VERIFY_READ 0
17489  #define VERIFY_WRITE 1
17490  
17491 diff -Naur a/include/asm-um/unistd.h b/include/asm-um/unistd.h
17492 --- a/include/asm-um/unistd.h   2004-01-08 22:28:40.000000000 -0500
17493 +++ b/include/asm-um/unistd.h   2004-01-08 22:34:56.000000000 -0500
17494 @@ -33,7 +33,10 @@
17495         set_fs(KERNEL_DS);                      \
17496         ret = sys(args);                        \
17497         set_fs(fs);                             \
17498 -       return ret;
17499 +       if (ret >= 0)                           \
17500 +               return ret;                     \
17501 +       errno = -(long)ret;                     \
17502 +       return -1;
17503  
17504  static inline long open(const char *pathname, int flags, int mode) 
17505  {
17506 diff -Naur a/include/linux/gfp.h b/include/linux/gfp.h
17507 --- a/include/linux/gfp.h       2004-01-08 22:16:45.000000000 -0500
17508 +++ b/include/linux/gfp.h       2004-01-08 22:22:50.000000000 -0500
17509 @@ -63,6 +63,11 @@
17510   * For the normal case of non-DISCONTIGMEM systems the NODE_DATA() gets
17511   * optimized to &contig_page_data at compile-time.
17512   */
17513 +
17514 +#ifndef HAVE_ARCH_FREE_PAGE
17515 +static inline void arch_free_page(struct page *page, int order) { }
17516 +#endif
17517 +
17518  extern struct page * FASTCALL(__alloc_pages(unsigned int, unsigned int, struct zonelist *));
17519  static inline struct page * alloc_pages_node(int nid, unsigned int gfp_mask, unsigned int order)
17520  {
17521 diff -Naur a/include/linux/ghash.h b/include/linux/ghash.h
17522 --- a/include/linux/ghash.h     1969-12-31 19:00:00.000000000 -0500
17523 +++ b/include/linux/ghash.h     2004-01-08 22:22:33.000000000 -0500
17524 @@ -0,0 +1,236 @@
17525 +/*
17526 + * include/linux/ghash.h -- generic hashing with fuzzy retrieval
17527 + *
17528 + * (C) 1997 Thomas Schoebel-Theuer
17529 + *
17530 + * The algorithms implemented here seem to be a completely new invention,
17531 + * and I'll publish the fundamentals in a paper.
17532 + */
17533 +
17534 +#ifndef _GHASH_H
17535 +#define _GHASH_H
17536 +/* HASHSIZE _must_ be a power of two!!! */
17537 +
17538 +
17539 +#define DEF_HASH_FUZZY_STRUCTS(NAME,HASHSIZE,TYPE) \
17540 +\
17541 +struct NAME##_table {\
17542 +       TYPE * hashtable[HASHSIZE];\
17543 +       TYPE * sorted_list;\
17544 +       int nr_entries;\
17545 +};\
17546 +\
17547 +struct NAME##_ptrs {\
17548 +       TYPE * next_hash;\
17549 +       TYPE * prev_hash;\
17550 +       TYPE * next_sorted;\
17551 +       TYPE * prev_sorted;\
17552 +};
17553 +
17554 +#define DEF_HASH_FUZZY(LINKAGE,NAME,HASHSIZE,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,KEYEQ,HASHFN)\
17555 +\
17556 +LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
17557 +{\
17558 +       int ix = HASHFN(elem->KEY);\
17559 +       TYPE ** base = &tbl->hashtable[ix];\
17560 +       TYPE * ptr = *base;\
17561 +       TYPE * prev = NULL;\
17562 +\
17563 +       tbl->nr_entries++;\
17564 +       while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\
17565 +               base = &ptr->PTRS.next_hash;\
17566 +               prev = ptr;\
17567 +               ptr = *base;\
17568 +       }\
17569 +       elem->PTRS.next_hash = ptr;\
17570 +       elem->PTRS.prev_hash = prev;\
17571 +       if(ptr) {\
17572 +               ptr->PTRS.prev_hash = elem;\
17573 +       }\
17574 +       *base = elem;\
17575 +\
17576 +       ptr = prev;\
17577 +       if(!ptr) {\
17578 +               ptr = tbl->sorted_list;\
17579 +               prev = NULL;\
17580 +       } else {\
17581 +               prev = ptr->PTRS.prev_sorted;\
17582 +       }\
17583 +       while(ptr) {\
17584 +               TYPE * next = ptr->PTRS.next_hash;\
17585 +               if(next && KEYCMP(next->KEY, elem->KEY)) {\
17586 +                       prev = ptr;\
17587 +                       ptr = next;\
17588 +               } else if(KEYCMP(ptr->KEY, elem->KEY)) {\
17589 +                       prev = ptr;\
17590 +                       ptr = ptr->PTRS.next_sorted;\
17591 +               } else\
17592 +                       break;\
17593 +       }\
17594 +       elem->PTRS.next_sorted = ptr;\
17595 +       elem->PTRS.prev_sorted = prev;\
17596 +       if(ptr) {\
17597 +               ptr->PTRS.prev_sorted = elem;\
17598 +       }\
17599 +       if(prev) {\
17600 +               prev->PTRS.next_sorted = elem;\
17601 +       } else {\
17602 +               tbl->sorted_list = elem;\
17603 +       }\
17604 +}\
17605 +\
17606 +LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
17607 +{\
17608 +       TYPE * next = elem->PTRS.next_hash;\
17609 +       TYPE * prev = elem->PTRS.prev_hash;\
17610 +\
17611 +       tbl->nr_entries--;\
17612 +       if(next)\
17613 +               next->PTRS.prev_hash = prev;\
17614 +       if(prev)\
17615 +               prev->PTRS.next_hash = next;\
17616 +       else {\
17617 +               int ix = HASHFN(elem->KEY);\
17618 +               tbl->hashtable[ix] = next;\
17619 +       }\
17620 +\
17621 +       next = elem->PTRS.next_sorted;\
17622 +       prev = elem->PTRS.prev_sorted;\
17623 +       if(next)\
17624 +               next->PTRS.prev_sorted = prev;\
17625 +       if(prev)\
17626 +               prev->PTRS.next_sorted = next;\
17627 +       else\
17628 +               tbl->sorted_list = next;\
17629 +}\
17630 +\
17631 +LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
17632 +{\
17633 +       int ix = hashfn(pos);\
17634 +       TYPE * ptr = tbl->hashtable[ix];\
17635 +       while(ptr && KEYCMP(ptr->KEY, pos))\
17636 +               ptr = ptr->PTRS.next_hash;\
17637 +       if(ptr && !KEYEQ(ptr->KEY, pos))\
17638 +               ptr = NULL;\
17639 +       return ptr;\
17640 +}\
17641 +\
17642 +LINKAGE TYPE * find_##NAME##_hash_fuzzy(struct NAME##_table * tbl, KEYTYPE pos)\
17643 +{\
17644 +       int ix;\
17645 +       int offset;\
17646 +       TYPE * ptr;\
17647 +       TYPE * next;\
17648 +\
17649 +       ptr = tbl->sorted_list;\
17650 +       if(!ptr || KEYCMP(pos, ptr->KEY))\
17651 +               return NULL;\
17652 +       ix = HASHFN(pos);\
17653 +       offset = HASHSIZE;\
17654 +       do {\
17655 +               offset >>= 1;\
17656 +               next = tbl->hashtable[(ix+offset) & ((HASHSIZE)-1)];\
17657 +               if(next && (KEYCMP(next->KEY, pos) || KEYEQ(next->KEY, pos))\
17658 +                  && KEYCMP(ptr->KEY, next->KEY))\
17659 +                       ptr = next;\
17660 +       } while(offset);\
17661 +\
17662 +       for(;;) {\
17663 +               next = ptr->PTRS.next_hash;\
17664 +               if(next) {\
17665 +                       if(KEYCMP(next->KEY, pos)) {\
17666 +                               ptr = next;\
17667 +                               continue;\
17668 +                       }\
17669 +               }\
17670 +               next = ptr->PTRS.next_sorted;\
17671 +               if(next && KEYCMP(next->KEY, pos)) {\
17672 +                       ptr = next;\
17673 +                       continue;\
17674 +               }\
17675 +               return ptr;\
17676 +       }\
17677 +       return NULL;\
17678 +}
17679 +
17680 +/* LINKAGE - empty or "static", depending on whether you want the definitions to
17681 + *     be public or not
17682 + * NAME - a string to stick in names to make this hash table type distinct from
17683 + *     any others
17684 + * HASHSIZE - number of buckets
17685 + * TYPE - type of data contained in the buckets - must be a structure, one 
17686 + *     field is of type NAME_ptrs, another is the hash key
17687 + * PTRS - TYPE must contain a field of type NAME_ptrs, PTRS is the name of that
17688 + *     field
17689 + * KEYTYPE - type of the key field within TYPE
17690 + * KEY - name of the key field within TYPE
17691 + * KEYCMP - pointer to function that compares KEYTYPEs to each other - the
17692 + *     prototype is int KEYCMP(KEYTYPE, KEYTYPE), it returns zero for equal, 
17693 + *     non-zero for not equal
17694 + * HASHFN - the hash function - the prototype is int HASHFN(KEYTYPE),
17695 + *     it returns a number in the range 0 ... HASHSIZE - 1
17696 + * Call DEF_HASH_STRUCTS, define your hash table as a NAME_table, then call
17697 + * DEF_HASH.
17698 + */
17699 +
17700 +#define DEF_HASH_STRUCTS(NAME,HASHSIZE,TYPE) \
17701 +\
17702 +struct NAME##_table {\
17703 +       TYPE * hashtable[HASHSIZE];\
17704 +       int nr_entries;\
17705 +};\
17706 +\
17707 +struct NAME##_ptrs {\
17708 +       TYPE * next_hash;\
17709 +       TYPE * prev_hash;\
17710 +};
17711 +
17712 +#define DEF_HASH(LINKAGE,NAME,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,HASHFN)\
17713 +\
17714 +LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
17715 +{\
17716 +       int ix = HASHFN(elem->KEY);\
17717 +       TYPE ** base = &tbl->hashtable[ix];\
17718 +       TYPE * ptr = *base;\
17719 +       TYPE * prev = NULL;\
17720 +\
17721 +       tbl->nr_entries++;\
17722 +       while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\
17723 +               base = &ptr->PTRS.next_hash;\
17724 +               prev = ptr;\
17725 +               ptr = *base;\
17726 +       }\
17727 +       elem->PTRS.next_hash = ptr;\
17728 +       elem->PTRS.prev_hash = prev;\
17729 +       if(ptr) {\
17730 +               ptr->PTRS.prev_hash = elem;\
17731 +       }\
17732 +       *base = elem;\
17733 +}\
17734 +\
17735 +LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
17736 +{\
17737 +       TYPE * next = elem->PTRS.next_hash;\
17738 +       TYPE * prev = elem->PTRS.prev_hash;\
17739 +\
17740 +       tbl->nr_entries--;\
17741 +       if(next)\
17742 +               next->PTRS.prev_hash = prev;\
17743 +       if(prev)\
17744 +               prev->PTRS.next_hash = next;\
17745 +       else {\
17746 +               int ix = HASHFN(elem->KEY);\
17747 +               tbl->hashtable[ix] = next;\
17748 +       }\
17749 +}\
17750 +\
17751 +LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
17752 +{\
17753 +       int ix = HASHFN(pos);\
17754 +       TYPE * ptr = tbl->hashtable[ix];\
17755 +       while(ptr && KEYCMP(ptr->KEY, pos))\
17756 +               ptr = ptr->PTRS.next_hash;\
17757 +       return ptr;\
17758 +}
17759 +
17760 +#endif
17761 diff -Naur a/include/linux/mm.h b/include/linux/mm.h
17762 --- a/include/linux/mm.h        2004-01-08 22:13:47.000000000 -0500
17763 +++ b/include/linux/mm.h        2004-01-08 22:18:35.000000000 -0500
17764 @@ -487,6 +487,9 @@
17765         return __set_page_dirty_buffers(page);
17766  }
17767  
17768 +extern long do_mprotect(struct mm_struct *mm, unsigned long start, 
17769 +                       size_t len, unsigned long prot);
17770 +
17771  /*
17772   * On a two-level page table, this ends up being trivial. Thus the
17773   * inlining and the symmetry break with pte_alloc_map() that does all
17774 @@ -517,9 +520,10 @@
17775  
17776  extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
17777  
17778 -extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
17779 -       unsigned long len, unsigned long prot,
17780 -       unsigned long flag, unsigned long pgoff);
17781 +extern unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file *file, 
17782 +                                  unsigned long addr, unsigned long len,
17783 +                                  unsigned long prot, unsigned long flag,
17784 +                                  unsigned long pgoff);
17785  
17786  static inline unsigned long do_mmap(struct file *file, unsigned long addr,
17787         unsigned long len, unsigned long prot,
17788 @@ -529,7 +533,8 @@
17789         if ((offset + PAGE_ALIGN(len)) < offset)
17790                 goto out;
17791         if (!(offset & ~PAGE_MASK))
17792 -               ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
17793 +               ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag, 
17794 +                                   offset >> PAGE_SHIFT);
17795  out:
17796         return ret;
17797  }
17798 diff -Naur a/include/linux/proc_mm.h b/include/linux/proc_mm.h
17799 --- a/include/linux/proc_mm.h   1969-12-31 19:00:00.000000000 -0500
17800 +++ b/include/linux/proc_mm.h   2004-01-08 22:16:52.000000000 -0500
17801 @@ -0,0 +1,48 @@
17802 +/* 
17803 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17804 + * Licensed under the GPL
17805 + */
17806 +
17807 +#ifndef __PROC_MM_H
17808 +#define __PROC_MM_H
17809 +
17810 +#include "linux/sched.h"
17811 +
17812 +#define MM_MMAP 54
17813 +#define MM_MUNMAP 55
17814 +#define MM_MPROTECT 56
17815 +#define MM_COPY_SEGMENTS 57
17816 +
17817 +struct mm_mmap {
17818 +       unsigned long addr;
17819 +       unsigned long len;
17820 +       unsigned long prot;
17821 +       unsigned long flags;
17822 +       unsigned long fd;
17823 +       unsigned long offset;
17824 +};
17825 +
17826 +struct mm_munmap {
17827 +       unsigned long addr;
17828 +       unsigned long len;      
17829 +};
17830 +
17831 +struct mm_mprotect {
17832 +       unsigned long addr;
17833 +       unsigned long len;
17834 +        unsigned int prot;
17835 +};
17836 +
17837 +struct proc_mm_op {
17838 +       int op;
17839 +       union {
17840 +               struct mm_mmap mmap;
17841 +               struct mm_munmap munmap;
17842 +               struct mm_mprotect mprotect;
17843 +               int copy_segments;
17844 +       } u;
17845 +};
17846 +
17847 +extern struct mm_struct *proc_mm_get_mm(int fd);
17848 +
17849 +#endif
17850 diff -Naur a/mm/Makefile b/mm/Makefile
17851 --- a/mm/Makefile       2004-01-08 22:24:14.000000000 -0500
17852 +++ b/mm/Makefile       2004-01-08 22:31:33.000000000 -0500
17853 @@ -12,3 +12,5 @@
17854                            slab.o swap.o truncate.o vmscan.o $(mmu-y)
17855  
17856  obj-$(CONFIG_SWAP)     += page_io.o swap_state.o swapfile.o
17857 +obj-$(CONFIG_PROC_MM)  += proc_mm.o
17858 +
17859 diff -Naur a/mm/memory.c b/mm/memory.c
17860 --- a/mm/memory.c       2004-01-08 22:20:23.000000000 -0500
17861 +++ b/mm/memory.c       2004-01-08 22:26:51.000000000 -0500
17862 @@ -44,6 +44,7 @@
17863  #include <linux/highmem.h>
17864  #include <linux/pagemap.h>
17865  #include <linux/rmap-locking.h>
17866 +#include <linux/init.h>
17867  #include <linux/module.h>
17868  
17869  #include <asm/pgalloc.h>
17870 @@ -680,6 +681,24 @@
17871  }
17872  
17873  
17874 +static struct vm_area_struct fixmap_vma = {
17875 +       /* Catch users - if there are any valid
17876 +          ones, we can make this be "&init_mm" or
17877 +          something.  */
17878 +       .vm_mm = NULL,
17879 +       .vm_page_prot = PAGE_READONLY,
17880 +       .vm_flags = VM_READ | VM_EXEC,
17881 +};
17882 +
17883 +static int init_fixmap_vma(void)
17884 +{
17885 +       fixmap_vma.vm_start = FIXADDR_START;
17886 +       fixmap_vma.vm_end = FIXADDR_TOP;
17887 +       return(0);
17888 +}
17889 +
17890 +__initcall(init_fixmap_vma);
17891 +
17892  int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
17893                 unsigned long start, int len, int write, int force,
17894                 struct page **pages, struct vm_area_struct **vmas)
17895 @@ -700,19 +719,8 @@
17896  
17897                 vma = find_extend_vma(mm, start);
17898  
17899 -#ifdef FIXADDR_USER_START
17900 -               if (!vma &&
17901 -                   start >= FIXADDR_USER_START && start < FIXADDR_USER_END) {
17902 -                       static struct vm_area_struct fixmap_vma = {
17903 -                               /* Catch users - if there are any valid
17904 -                                  ones, we can make this be "&init_mm" or
17905 -                                  something.  */
17906 -                               .vm_mm = NULL,
17907 -                               .vm_start = FIXADDR_USER_START,
17908 -                               .vm_end = FIXADDR_USER_END,
17909 -                               .vm_page_prot = PAGE_READONLY,
17910 -                               .vm_flags = VM_READ | VM_EXEC,
17911 -                       };
17912 +#ifdef FIXADDR_START
17913 +               if (!vma && start >= FIXADDR_START && start < FIXADDR_TOP) {
17914                         unsigned long pg = start & PAGE_MASK;
17915                         pgd_t *pgd;
17916                         pmd_t *pmd;
17917 diff -Naur a/mm/mmap.c b/mm/mmap.c
17918 --- a/mm/mmap.c 2004-01-08 22:24:04.000000000 -0500
17919 +++ b/mm/mmap.c 2004-01-08 22:31:23.000000000 -0500
17920 @@ -462,11 +462,11 @@
17921   * The caller must hold down_write(current->mm->mmap_sem).
17922   */
17923  
17924 -unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
17925 -                       unsigned long len, unsigned long prot,
17926 -                       unsigned long flags, unsigned long pgoff)
17927 +unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file * file, 
17928 +                           unsigned long addr, unsigned long len,
17929 +                           unsigned long prot, unsigned long flags,
17930 +                           unsigned long pgoff)
17931  {
17932 -       struct mm_struct * mm = current->mm;
17933         struct vm_area_struct * vma, * prev;
17934         struct inode *inode;
17935         unsigned int vm_flags;
17936 diff -Naur a/mm/mprotect.c b/mm/mprotect.c
17937 --- a/mm/mprotect.c     2004-01-08 22:19:21.000000000 -0500
17938 +++ b/mm/mprotect.c     2004-01-08 22:25:37.000000000 -0500
17939 @@ -222,7 +222,8 @@
17940  }
17941  
17942  asmlinkage long
17943 -sys_mprotect(unsigned long start, size_t len, unsigned long prot)
17944 +do_mprotect(struct mm_struct *mm, unsigned long start, size_t len, 
17945 +            unsigned long prot)
17946  {
17947         unsigned long vm_flags, nstart, end, tmp;
17948         struct vm_area_struct * vma, * next, * prev;
17949 @@ -245,9 +246,9 @@
17950  
17951         vm_flags = calc_vm_prot_bits(prot);
17952  
17953 -       down_write(&current->mm->mmap_sem);
17954 +       down_write(&mm->mmap_sem);
17955  
17956 -       vma = find_vma_prev(current->mm, start, &prev);
17957 +       vma = find_vma_prev(mm, start, &prev);
17958         error = -ENOMEM;
17959         if (!vma)
17960                 goto out;
17961 @@ -326,6 +327,11 @@
17962                 prev->vm_mm->map_count--;
17963         }
17964  out:
17965 -       up_write(&current->mm->mmap_sem);
17966 +       up_write(&mm->mmap_sem);
17967         return error;
17968  }
17969 +
17970 +asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
17971 +{
17972 +        return(do_mprotect(current->mm, start, len, prot));
17973 +}
17974 diff -Naur a/mm/page_alloc.c b/mm/page_alloc.c
17975 --- a/mm/page_alloc.c   2004-01-08 22:13:53.000000000 -0500
17976 +++ b/mm/page_alloc.c   2004-01-08 22:19:05.000000000 -0500
17977 @@ -268,6 +268,8 @@
17978  {
17979         LIST_HEAD(list);
17980  
17981 +       arch_free_page(page, order);
17982 +
17983         mod_page_state(pgfree, 1 << order);
17984         free_pages_check(__FUNCTION__, page);
17985         list_add(&page->list, &list);
17986 diff -Naur a/mm/proc_mm.c b/mm/proc_mm.c
17987 --- a/mm/proc_mm.c      1969-12-31 19:00:00.000000000 -0500
17988 +++ b/mm/proc_mm.c      2004-01-08 22:26:26.000000000 -0500
17989 @@ -0,0 +1,174 @@
17990 +/* 
17991 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17992 + * Licensed under the GPL
17993 + */
17994 +
17995 +#include "linux/mm.h"
17996 +#include "linux/init.h"
17997 +#include "linux/proc_fs.h"
17998 +#include "linux/proc_mm.h"
17999 +#include "linux/file.h"
18000 +#include "asm/uaccess.h"
18001 +#include "asm/mmu_context.h"
18002 +
18003 +static struct file_operations proc_mm_fops;
18004 +
18005 +struct mm_struct *proc_mm_get_mm(int fd)
18006 +{
18007 +       struct mm_struct *ret = ERR_PTR(-EBADF);
18008 +       struct file *file;
18009 +
18010 +       file = fget(fd);
18011 +       if (!file)
18012 +               goto out;
18013 +
18014 +       ret = ERR_PTR(-EINVAL);
18015 +       if(file->f_op != &proc_mm_fops)
18016 +               goto out_fput;
18017 +
18018 +       ret = file->private_data;
18019 + out_fput:
18020 +       fput(file);
18021 + out:
18022 +       return(ret);
18023 +}
18024 +
18025 +extern long do_mmap2(struct mm_struct *mm, unsigned long addr, 
18026 +                    unsigned long len, unsigned long prot, 
18027 +                    unsigned long flags, unsigned long fd,
18028 +                    unsigned long pgoff);
18029 +
18030 +static ssize_t write_proc_mm(struct file *file, const char *buffer,
18031 +                            size_t count, loff_t *ppos)
18032 +{
18033 +       struct mm_struct *mm = file->private_data;
18034 +       struct proc_mm_op req;
18035 +       int n, ret;
18036 +
18037 +       if(count > sizeof(req))
18038 +               return(-EINVAL);
18039 +
18040 +       n = copy_from_user(&req, buffer, count);
18041 +       if(n != 0)
18042 +               return(-EFAULT);
18043 +
18044 +       ret = count;
18045 +       switch(req.op){
18046 +       case MM_MMAP: {
18047 +               struct mm_mmap *map = &req.u.mmap;
18048 +
18049 +               ret = do_mmap2(mm, map->addr, map->len, map->prot, 
18050 +                              map->flags, map->fd, map->offset >> PAGE_SHIFT);
18051 +               if((ret & ~PAGE_MASK) == 0)
18052 +                       ret = count;
18053 +       
18054 +               break;
18055 +       }
18056 +       case MM_MUNMAP: {
18057 +               struct mm_munmap *unmap = &req.u.munmap;
18058 +
18059 +               down_write(&mm->mmap_sem);
18060 +               ret = do_munmap(mm, unmap->addr, unmap->len);
18061 +               up_write(&mm->mmap_sem);
18062 +
18063 +               if(ret == 0)
18064 +                       ret = count;
18065 +               break;
18066 +       }
18067 +       case MM_MPROTECT: {
18068 +               struct mm_mprotect *protect = &req.u.mprotect;
18069 +
18070 +               ret = do_mprotect(mm, protect->addr, protect->len, 
18071 +                                 protect->prot);
18072 +               if(ret == 0)
18073 +                       ret = count;
18074 +               break;
18075 +       }
18076 +
18077 +       case MM_COPY_SEGMENTS: {
18078 +               struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
18079 +
18080 +               if(IS_ERR(from)){
18081 +                       ret = PTR_ERR(from);
18082 +                       break;
18083 +               }
18084 +
18085 +               mm_copy_segments(from, mm);
18086 +               break;
18087 +       }
18088 +       default:
18089 +               ret = -EINVAL;
18090 +               break;
18091 +       }
18092 +
18093 +       return(ret);
18094 +}
18095 +
18096 +static int open_proc_mm(struct inode *inode, struct file *file)
18097 +{
18098 +       struct mm_struct *mm = mm_alloc();
18099 +       int ret;
18100 +
18101 +       ret = -ENOMEM;
18102 +       if(mm == NULL)
18103 +               goto out_mem;
18104 +
18105 +       ret = init_new_context(current, mm);
18106 +       if(ret)
18107 +               goto out_free;
18108 +
18109 +       spin_lock(&mmlist_lock);
18110 +       list_add(&mm->mmlist, &current->mm->mmlist);
18111 +       mmlist_nr++;
18112 +       spin_unlock(&mmlist_lock);
18113 +
18114 +       file->private_data = mm;
18115 +
18116 +       return(0);
18117 +
18118 + out_free:
18119 +       mmput(mm);
18120 + out_mem:
18121 +       return(ret);
18122 +}
18123 +
18124 +static int release_proc_mm(struct inode *inode, struct file *file)
18125 +{
18126 +       struct mm_struct *mm = file->private_data;
18127 +
18128 +       mmput(mm);
18129 +       return(0);
18130 +}
18131 +
18132 +static struct file_operations proc_mm_fops = {
18133 +       .open           = open_proc_mm,
18134 +       .release        = release_proc_mm,
18135 +       .write          = write_proc_mm,
18136 +};
18137 +
18138 +static int make_proc_mm(void)
18139 +{
18140 +       struct proc_dir_entry *ent;
18141 +
18142 +       ent = create_proc_entry("mm", 0222, &proc_root);
18143 +       if(ent == NULL){
18144 +               printk("make_proc_mm : Failed to register /proc/mm\n");
18145 +               return(0);
18146 +       }
18147 +       ent->proc_fops = &proc_mm_fops;
18148 +
18149 +       return(0);
18150 +}
18151 +
18152 +__initcall(make_proc_mm);
18153 +
18154 +/*
18155 + * Overrides for Emacs so that we follow Linus's tabbing style.
18156 + * Emacs will notice this stuff at the end of the file and automatically
18157 + * adjust the settings for this buffer only.  This must remain at the end
18158 + * of the file.
18159 + * ---------------------------------------------------------------------------
18160 + * Local variables:
18161 + * c-file-style: "linux"
18162 + * End:
18163 + */