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
8 -# CONFIG_UDF_RW is not set
10 # CONFIG_UFS_FS_WRITE is not set
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
21 CONFIG_RWSEM_GENERIC_SPINLOCK=y
22 -CONFIG_CONFIG_LOG_BUF_SHIFT=14
25 -# Code maturity level options
27 -CONFIG_EXPERIMENTAL=y
31 +# UML-specific options
37 -CONFIG_BSD_PROCESS_ACCT=y
46 # CONFIG_HOST_2G_2G is not set
48 # CONFIG_HIGHMEM is not set
50 CONFIG_KERNEL_STACK_ORDER=2
51 +CONFIG_UML_REAL_TIME_CLOCK=y
54 +# Code maturity level options
56 +CONFIG_EXPERIMENTAL=y
57 +CONFIG_CLEAN_COMPILE=y
59 +CONFIG_BROKEN_ON_SMP=y
66 +CONFIG_BSD_PROCESS_ACCT=y
68 +CONFIG_LOG_BUF_SHIFT=14
69 +# CONFIG_IKCONFIG is not set
70 +# CONFIG_EMBEDDED is not set
74 +CONFIG_IOSCHED_NOOP=y
76 +CONFIG_IOSCHED_DEADLINE=y
79 # Loadable module support
82 -# CONFIG_KMOD is not set
83 +# CONFIG_MODULES is not set
86 +# Generic Driver Options
94 # CONFIG_BLK_DEV_UBD_SYNC is not set
95 +CONFIG_BLK_DEV_COW_COMMON=y
104 +# UML Network Devices
107 CONFIG_UML_NET_ETHERTAP=y
109 CONFIG_UML_NET_MCAST=y
110 # CONFIG_UML_NET_PCAP is not set
111 CONFIG_UML_NET_SLIRP=y
113 -# CONFIG_BONDING is not set
114 -# CONFIG_EQUALIZER is not set
116 -# CONFIG_ETHERTAP is not set
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
125 -# CONFIG_SLIP_COMPRESSED is not set
126 -# CONFIG_SLIP_SMART is not set
127 -# CONFIG_SLIP_MODE_SLIP6 is not set
134 # CONFIG_NETLINK_DEV is not set
135 -# CONFIG_NETFILTER is not set
136 -# CONFIG_FILTER is not set
138 # CONFIG_NET_KEY is not set
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
152 # SCTP Configuration (EXPERIMENTAL)
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
169 # CONFIG_NET_PKTGEN is not set
171 +# CONFIG_BONDING is not set
172 +# CONFIG_EQUALIZER is not set
176 # Ethernet (10 or 100Mbit)
177 @@ -171,12 +180,28 @@
181 +# Ethernet (10000 Mbit)
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
192 +# CONFIG_SLIP_COMPRESSED is not set
193 +# CONFIG_SLIP_SMART is not set
194 +# CONFIG_SLIP_MODE_SLIP6 is not set
197 # Wireless LAN (non-hamradio)
199 # CONFIG_NET_RADIO is not set
202 -# Token Ring devices (depends on LLC=y)
203 +# Token Ring devices
205 # CONFIG_SHAPER is not set
207 @@ -186,68 +211,101 @@
208 # CONFIG_WAN is not set
211 +# Amateur Radio support
213 +# CONFIG_HAMRADIO is not set
216 +# IrDA (infrared) support
218 +# CONFIG_IRDA is not set
223 +# CONFIG_BT is not set
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
238 +# CONFIG_ROMFS_FS is not set
240 # CONFIG_QFMT_V1 is not set
241 # CONFIG_QFMT_V2 is not set
245 -CONFIG_REISERFS_FS=m
246 -# CONFIG_REISERFS_CHECK is not set
247 -# CONFIG_REISERFS_PROC_INFO is not set
252 +# CD-ROM/DVD Filesystems
255 +# CONFIG_JOLIET is not set
256 +# CONFIG_ZISOFS is not set
257 +# CONFIG_UDF_FS is not set
260 +# DOS/FAT/NT Filesystems
265 +# CONFIG_NTFS_FS is not set
268 +# Pseudo filesystems
273 +CONFIG_DEVFS_MOUNT=y
274 +# CONFIG_DEVFS_DEBUG is not set
276 +# CONFIG_DEVPTS_FS_XATTR is not set
277 +# CONFIG_TMPFS is not set
278 +# CONFIG_HUGETLB_PAGE is not set
282 +# Miscellaneous filesystems
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
294 # CONFIG_EFS_FS is not set
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
303 -# CONFIG_JOLIET is not set
304 -# CONFIG_ZISOFS is not set
305 -# CONFIG_JFS_FS is not set
307 # CONFIG_VXFS_FS is not set
308 -# CONFIG_NTFS_FS is not set
309 # CONFIG_HPFS_FS is not set
312 -CONFIG_DEVFS_MOUNT=y
313 -# CONFIG_DEVFS_DEBUG is not set
315 # CONFIG_QNX4FS_FS is not set
316 -# CONFIG_ROMFS_FS is not set
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
325 # Network File Systems
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
346 -CONFIG_GENERIC_ISA_DMA=y
349 -# SCSI support type (disk, tape, CD-ROM)
352 -CONFIG_SD_EXTRA_DEVS=40
355 -CONFIG_BLK_DEV_SR_VENDOR=y
356 -CONFIG_SR_EXTRA_DEVS=2
360 -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
362 -CONFIG_SCSI_DEBUG_QUEUES=y
363 -CONFIG_SCSI_MULTI_LUN=y
364 -CONFIG_SCSI_CONSTANTS=y
365 -CONFIG_SCSI_LOGGING=y
367 +# CONFIG_SCSI is not set
370 # Multi-device support (RAID and LVM)
373 # CONFIG_FTL is not set
374 # CONFIG_NFTL is not set
375 +# CONFIG_INFTL is not set
378 # RAM/ROM/Flash chip drivers
379 @@ -374,20 +412,21 @@
381 # Mapping drivers for chip access
383 +# CONFIG_MTD_COMPLEX_MAPPINGS is not set
386 # Self-contained MTD device drivers
388 # CONFIG_MTD_SLRAM is not set
389 # CONFIG_MTD_MTDRAM is not set
394 # Disk-On-Chip Device Drivers
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
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
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>
413 #include "chan_kern.h"
419 + CONFIG_CHUNK(str, size, n, "none", 1);
423 CONFIG_CHUNK(str, size, n, chan->ops->type, 0);
425 if(chan->dev == NULL){
427 INIT_LIST_HEAD(chans);
430 - if((out = strchr(str, ',')) != NULL){
431 + out = strchr(str, ',');
436 @@ -475,12 +482,15 @@
439 err = chan->ops->read(chan->fd, &c, chan->data);
440 - if(err > 0) tty_receive_char(tty, c);
442 + tty_receive_char(tty, c);
445 if(err == 0) reactivate_fd(chan->fd, irq);
448 - if(tty != NULL) tty_hangup(tty);
451 line_disable(dev, irq);
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
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
471 #include <sys/stat.h>
474 void generic_close(int fd, void *unused)
480 int generic_read(int fd, char *c_out, void *unused)
484 - n = read(fd, c_out, sizeof(*c_out));
486 - if(errno == EAGAIN) return(0);
489 - else if(n == 0) return(-EIO);
491 + n = os_read_file(fd, c_out, sizeof(*c_out));
500 +/* XXX Trivial wrapper around os_write_file */
502 int generic_write(int fd, const char *buf, int n, void *unused)
506 - count = write(fd, buf, n);
507 - if(count < 0) return(-errno);
509 + return(os_write_file(fd, buf, n));
512 int generic_console_write(int fd, const char *buf, int n, void *unused)
514 int generic_window_size(int fd, void *unused, unsigned short *rows_out,
515 unsigned short *cols_out)
517 - struct winsize size;
522 + ret = os_window_size(fd, &rows, &cols);
526 + ret = ((*rows_out != rows) || (*cols_out != cols));
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;
540 @@ -100,14 +100,16 @@
541 struct winch_data *data = arg;
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);
558 signal(SIGWINCH, winch_handler);
560 @@ -123,26 +125,24 @@
564 - if(ioctl(pty_fd, TIOCSCTTY, 0) < 0){
565 - printk("winch_thread : TIOCSCTTY failed, errno = %d\n", errno);
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());
572 + printk("winch_thread : new_tty_pgrp failed, err = %d\n", -err);
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);
586 - if(write(pipe_fd, &c, sizeof(c)) != sizeof(c)){
587 - printk("winch_thread : write failed, errno = %d\n",
590 + count = os_write_file(pipe_fd, &c, sizeof(c));
591 + if(count != sizeof(c))
592 + printk("winch_thread : write failed, err = %d\n",
600 err = os_pipe(fds, 1, 1);
602 - printk("winch_tramp : os_pipe failed, errno = %d\n", -err);
604 + printk("winch_tramp : os_pipe failed, err = %d\n", -err);
608 @@ -168,12 +168,12 @@
613 + os_close_file(fds[1]);
615 - n = read(fds[0], &c, sizeof(c));
616 + n = os_read_file(fds[0], &c, 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);
624 @@ -183,20 +183,24 @@
625 void register_winch(int fd, void *device_data)
627 int pid, thread, thread_fd;
631 - if(!isatty(fd)) return;
636 - if(!CHOOSE_MODE(is_tracer_winch(pid, fd, device_data), 0) &&
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);
642 register_winch_irq(thread_fd, fd, thread, device_data);
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",
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
661 +#include <asm/types.h>
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)
670 +#error "__BYTE_ORDER not defined"
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);
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);
684 +extern int write_cow_header(char *cow_file, int fd, char *backing_file,
685 + int sectorsize, int alignment, long long *size);
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);
694 + * ---------------------------------------------------------------------------
696 + * c-file-style: "linux"
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
703 +#define COW_MAJOR 60
704 +#define MAJOR_NR COW_MAJOR
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"
719 +#include "ubd_user.h"
727 + struct block_device *cow_bdev;
728 + char *backing_path;
730 + struct block_device *backing_bdev;
732 + unsigned long *bitmap;
733 + unsigned long bitmap_len;
736 + devfs_handle_t devfs;
737 + struct semaphore sem;
738 + struct semaphore io_sem;
740 + spinlock_t io_lock;
741 + struct buffer_head *bh;
742 + struct buffer_head *bhtail;
746 +#define DEFAULT_COW { \
748 + .cow_path = NULL, \
750 + .backing_path = NULL, \
751 + .backing_dev = 0, \
754 + .bitmap_offset = 0, \
755 + .data_offset = 0, \
757 + .working = ATOMIC_INIT(0), \
758 + .io_lock = SPIN_LOCK_UNLOCKED, \
762 +#define MAX_MINOR (MAX_DEV << COW_SHIFT)
764 +struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW };
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 };
770 +/* Protected by cow_lock */
771 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
773 +static struct hd_struct cow_part[MAX_MINOR] =
774 + { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
776 +/* Protected by io_request_lock */
777 +static request_queue_t *cow_queue;
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);
785 +static struct block_device_operations cow_blops = {
787 + .release = cow_release,
788 + .ioctl = cow_ioctl,
789 + .revalidate = cow_revalidate,
792 +/* Initialized in an initcall, and unchanged thereafter */
793 +devfs_handle_t cow_dir_handle;
795 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
798 + .major_name = name, \
799 + .minor_shift = shift, \
800 + .max_p = 1 << shift, \
804 + .real_devices = NULL, \
811 +static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED;
813 +static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part,
814 + COW_SHIFT, sizes, MAX_DEV,
817 +static int cow_add(int n)
819 + struct cow *dev = &cow_dev[n];
820 + char name[sizeof("nnnnnn\0")];
823 + if(dev->cow_path == NULL)
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,
832 + init_MUTEX_LOCKED(&dev->sem);
833 + init_MUTEX(&dev->io_sem);
842 +* Add buffer_head to back of pending list
844 +static void cow_add_bh(struct cow *cow, struct buffer_head *bh)
846 + unsigned long flags;
848 + spin_lock_irqsave(&cow->io_lock, flags);
849 + if(cow->bhtail != NULL){
850 + cow->bhtail->b_reqnext = bh;
857 + spin_unlock_irqrestore(&cow->io_lock, flags);
861 +* Grab first pending buffer
863 +static struct buffer_head *cow_get_bh(struct cow *cow)
865 + struct buffer_head *bh;
867 + spin_lock_irq(&cow->io_lock);
870 + if(bh == cow->bhtail)
871 + cow->bhtail = NULL;
872 + cow->bh = bh->b_reqnext;
873 + bh->b_reqnext = NULL;
875 + spin_unlock_irq(&cow->io_lock);
880 +static void cow_handle_bh(struct cow *cow, struct buffer_head *bh,
881 + struct buffer_head **cow_bh, int ncow_bh)
886 + ll_rw_block(WRITE, ncow_bh, cow_bh);
888 + for(i = 0; i < ncow_bh ; i++){
889 + wait_on_buffer(cow_bh[i]);
893 + ll_rw_block(WRITE, 1, &bh);
897 +static struct buffer_head *cow_new_bh(struct cow *dev, int sector)
899 + struct buffer_head *bh;
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])),
908 +/* Copied from loop.c, needed to avoid deadlocking in make_request. */
910 +static int cow_thread(void *data)
912 + struct cow *dev = data;
913 + struct buffer_head *bh;
916 + exit_files(current);
918 + sprintf(current->comm, "cow%d", dev - cow_dev);
920 + spin_lock_irq(¤t->sigmask_lock);
921 + sigfillset(¤t->blocked);
922 + flush_signals(current);
923 + spin_unlock_irq(¤t->sigmask_lock);
925 + atomic_inc(&dev->working);
927 + current->policy = SCHED_OTHER;
928 + current->nice = -20;
930 + current->flags |= PF_NOIO;
933 + * up sem, we are running
938 + int start, len, nbh, i, update_bitmap = 0;
939 + struct buffer_head *cow_bh[2];
941 + down_interruptible(&dev->io_sem);
943 + * could be upped because of tear-down, not because of
946 + if(!atomic_read(&dev->working))
949 + bh = cow_get_bh(dev);
951 + printk(KERN_ERR "cow: missing bh\n");
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))
963 + ubd_set_bit(start + i, (unsigned char *) dev->bitmap);
970 + cow_bh[0] = cow_new_bh(dev, start);
972 + if(start / dev->sectorsize !=
973 + (start + len) / dev->sectorsize){
974 + cow_bh[1] = cow_new_bh(dev, start + len);
979 + bh->b_dev = dev->cow_dev;
980 + bh->b_blocknr += dev->data_offset / dev->sectorsize;
982 + cow_handle_bh(dev, bh, cow_bh, nbh);
985 + * upped both for pending work and tear-down, lo_pending
986 + * will hit zero then
988 + if(atomic_dec_and_test(&dev->working))
996 +static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh)
1001 + minor = MINOR(bh->b_rdev);
1002 + n = minor >> COW_SHIFT;
1003 + dev = &cow_dev[n];
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;
1010 + else if(rw == WRITE){
1011 + bh->b_dev = dev->cow_dev;
1012 + bh->b_blocknr += dev->data_offset / dev->sectorsize;
1014 + cow_add_bh(dev, bh);
1019 + bh->b_rdev = dev->backing_dev;
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);
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);
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);
1044 + add_gendisk(&cow_gendisk);
1046 + for(i=0;i<MAX_DEV;i++)
1052 +__initcall(cow_init);
1054 +static int reader(__u64 start, char *buf, int count, void *arg)
1056 + dev_t dev = *((dev_t *) arg);
1057 + struct buffer_head *bh;
1059 + int cur, offset, left, n, blocksize = get_hardsect_size(dev);
1061 + if(blocksize == 0)
1062 + panic("Zero blocksize");
1064 + block = start / blocksize;
1065 + offset = start % blocksize;
1069 + n = (left > blocksize) ? blocksize : left;
1071 + bh = bread(dev, block, (n < 512) ? 512 : n);
1076 + memcpy(&buf[cur], bh->b_data + offset, n);
1087 +static int cow_open(struct inode *inode, struct file *filp)
1089 + int (*dev_ioctl)(struct inode *, struct file *, unsigned int,
1094 + __u32 version, align;
1096 + char *backing_file;
1097 + int n, offset, err = 0;
1099 + n = DEVICE_NR(inode->i_rdev);
1102 + dev = &cow_dev[n];
1103 + offset = n << COW_SHIFT;
1105 + spin_lock(&cow_lock);
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);
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);
1125 + dev->cow_bdev = bdget(dev->cow_dev);
1126 + if(dev->cow_bdev == NULL){
1127 + printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n",
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);
1141 + err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0,
1144 + printk("cow_open - blkdev_get of COW device failed, "
1145 + "error = %d\n", err);
1149 + err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW);
1151 + printk("cow_open - blkdev_get of backing device "
1152 + "failed, error = %d\n", err);
1156 + err = read_cow_header(reader, &dev->cow_dev, &version,
1157 + &backing_file, &mtime, &size,
1158 + &dev->sectorsize, &align,
1159 + &dev->bitmap_offset);
1161 + printk(KERN_ERR "cow_open - read_cow_header failed, "
1162 + "err = %d\n", err);
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){
1172 + printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
1175 + flush_tlb_kernel_vm();
1177 + err = reader(dev->bitmap_offset, (char *) dev->bitmap,
1178 + dev->bitmap_len, &dev->cow_dev);
1180 + printk(KERN_ERR "Failed to read COW bitmap\n");
1181 + vfree(dev->bitmap);
1185 + dev_ioctl = dev->backing_bdev->bd_op->ioctl;
1187 + set_fs(KERNEL_DS);
1188 + err = (*dev_ioctl)(inode, filp, BLKGETSIZE,
1189 + (unsigned long) &sizes[offset]);
1192 + printk(KERN_ERR "cow_open - BLKGETSIZE failed, "
1193 + "error = %d\n", err);
1197 + kernel_thread(cow_thread, dev,
1198 + CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
1203 + spin_unlock(&cow_lock);
1207 +static int cow_release(struct inode * inode, struct file * file)
1212 + n = DEVICE_NR(inode->i_rdev);
1215 + dev = &cow_dev[n];
1217 + spin_lock(&cow_lock);
1219 + if(--dev->count > 0)
1222 + err = blkdev_put(dev->cow_bdev, BDEV_RAW);
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;
1229 + err = blkdev_put(dev->backing_bdev, BDEV_RAW);
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;
1237 + spin_unlock(&cow_lock);
1241 +static int cow_ioctl(struct inode * inode, struct file * file,
1242 + unsigned int cmd, unsigned long arg)
1245 + int (*dev_ioctl)(struct inode *, struct file *, unsigned int,
1249 + n = DEVICE_NR(inode->i_rdev);
1252 + dev = &cow_dev[n];
1254 + dev_ioctl = dev->backing_bdev->bd_op->ioctl;
1255 + return((*dev_ioctl)(inode, file, cmd, arg));
1258 +static int cow_revalidate(kdev_t rdev)
1260 + printk(KERN_ERR "Need to implement cow_revalidate\n");
1264 +static int parse_unit(char **ptr)
1266 + char *str = *ptr, *end;
1269 + if(isdigit(*str)) {
1270 + n = simple_strtoul(str, &end, 0);
1275 + else if (('a' <= *str) && (*str <= 'h')) {
1283 +static int cow_setup(char *str)
1286 + char *cow_name, *backing_name;
1289 + unit = parse_unit(&str);
1291 + printk(KERN_ERR "cow_setup - Couldn't parse unit number\n");
1296 + printk(KERN_ERR "cow_setup - Missing '=' after unit "
1303 + backing_name = strchr(str, ',');
1304 + if(backing_name == NULL){
1305 + printk(KERN_ERR "cow_setup - missing backing device name\n");
1308 + *backing_name = '\0';
1311 + spin_lock(&cow_lock);
1313 + dev = &cow_dev[unit];
1314 + dev->cow_path = cow_name;
1315 + dev->backing_path = backing_name;
1317 + spin_unlock(&cow_lock);
1321 +__setup("cow", cow_setup);
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
1328 + * ---------------------------------------------------------------------------
1329 + * Local variables:
1330 + * c-file-style: "linux"
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
1337 +#ifndef __COW_SYS_H__
1338 +#define __COW_SYS_H__
1340 +#include "kern_util.h"
1341 +#include "user_util.h"
1345 +static inline void *cow_malloc(int size)
1347 + return(um_kmalloc(size));
1350 +static inline void cow_free(void *ptr)
1355 +#define cow_printf printk
1357 +static inline char *cow_strdup(char *str)
1359 + return(uml_strdup(str));
1362 +static inline int cow_seek_file(int fd, __u64 offset)
1364 + return(os_seek_file(fd, offset));
1367 +static inline int cow_file_size(char *file, __u64 *size_out)
1369 + return(os_file_size(file, size_out));
1372 +static inline int cow_write_file(int fd, char *buf, int size)
1374 + return(os_write_file(fd, buf, size));
1380 + * ---------------------------------------------------------------------------
1381 + * Local variables:
1382 + * c-file-style: "linux"
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
1389 +#include <stddef.h>
1390 +#include <string.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>
1402 +#include "cow_sys.h"
1404 +#define PATH_LEN_V1 256
1406 +struct cow_header_v1 {
1409 + char backing_file[PATH_LEN_V1];
1415 +#define PATH_LEN_V2 MAXPATHLEN
1417 +struct cow_header_v2 {
1418 + unsigned long magic;
1419 + unsigned long version;
1420 + char backing_file[PATH_LEN_V2];
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
1429 +#define PATH_LEN_V3 4096
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
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
1455 +struct cow_header_v3 {
1463 + char backing_file[PATH_LEN_V3];
1466 +/* COW format definitions - for now, we have only the usual COW bitmap */
1467 +#define COW_BITMAP 0
1470 + struct cow_header_v1 v1;
1471 + struct cow_header_v2 v2;
1472 + struct cow_header_v3 v3;
1475 +#define COW_MAGIC 0x4f4f4f4d /* MOOO */
1476 +#define COW_VERSION 3
1478 +#define DIV_ROUND(x, len) (((x) + (len) - 1) / (len))
1479 +#define ROUND_UP(x, align) DIV_ROUND(x, align) * (align)
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)
1486 + *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
1488 + *data_offset_out = bitmap_offset + *bitmap_len_out;
1489 + *data_offset_out = (*data_offset_out + sectorsize - 1) /
1491 + *data_offset_out *= sectorsize;
1494 + *bitmap_len_out = DIV_ROUND(size, sectorsize);
1495 + *bitmap_len_out = DIV_ROUND(*bitmap_len_out, 8);
1497 + *data_offset_out = bitmap_offset + *bitmap_len_out;
1498 + *data_offset_out = ROUND_UP(*data_offset_out, align);
1502 +static int absolutize(char *to, int size, char *from)
1504 + char save_cwd[256], *slash;
1507 + if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
1508 + cow_printf("absolutize : unable to get cwd - errno = %d\n",
1512 + slash = strrchr(from, '/');
1513 + if(slash != NULL){
1517 + cow_printf("absolutize : Can't cd to '%s' - "
1518 + "errno = %d\n", from, errno);
1522 + if(getcwd(to, size) == NULL){
1523 + cow_printf("absolutize : unable to get cwd of '%s' - "
1524 + "errno = %d\n", from, errno);
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);
1533 + strcat(to, slash);
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);
1541 + strcpy(to, save_cwd);
1549 +int write_cow_header(char *cow_file, int fd, char *backing_file,
1550 + int sectorsize, int alignment, long long *size)
1552 + struct cow_header_v3 *header;
1553 + unsigned long modtime;
1556 + err = cow_seek_file(fd, 0);
1558 + cow_printf("write_cow_header - lseek failed, err = %d\n", -err);
1563 + header = cow_malloc(sizeof(*header));
1564 + if(header == NULL){
1565 + cow_printf("Failed to allocate COW V3 header\n");
1568 + header->magic = htonl(COW_MAGIC);
1569 + header->version = htonl(COW_VERSION);
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);
1579 + if(absolutize(header->backing_file, sizeof(header->backing_file),
1583 + err = os_file_modtime(header->backing_file, &modtime);
1585 + cow_printf("Backing file '%s' mtime request failed, "
1586 + "err = %d\n", header->backing_file, -err);
1590 + err = cow_file_size(header->backing_file, size);
1592 + cow_printf("Couldn't get size of backing file '%s', "
1593 + "err = %d\n", header->backing_file, -err);
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;
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);
1616 +int file_reader(__u64 offset, char *buf, int len, void *arg)
1618 + int fd = *((int *) arg);
1620 + return(pread(fd, buf, len, offset));
1623 +/* XXX Need to sanity-check the values read from the header */
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)
1631 + union cow_header *header;
1634 + unsigned long version, magic;
1636 + header = cow_malloc(sizeof(*header));
1637 + if(header == NULL){
1638 + cow_printf("read_cow_header - Failed to allocate header\n");
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");
1648 + magic = header->v1.magic;
1649 + if(magic == COW_MAGIC) {
1650 + version = header->v1.version;
1652 + else if(magic == ntohl(COW_MAGIC)){
1653 + version = ntohl(header->v1.version);
1655 + /* No error printed because the non-COW case comes through here */
1658 + *version_out = version;
1661 + if(n < sizeof(header->v1)){
1662 + cow_printf("read_cow_header - failed to read V1 "
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;
1673 + else if(version == 2){
1674 + if(n < sizeof(header->v2)){
1675 + cow_printf("read_cow_header - failed to read V2 "
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;
1686 + else if(version == 3){
1687 + if(n < sizeof(header->v3)){
1688 + cow_printf("read_cow_header - failed to read V2 "
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;
1700 + cow_printf("read_cow_header - invalid COW version\n");
1704 + *backing_file_out = cow_strdup(file);
1705 + if(*backing_file_out == NULL){
1706 + cow_printf("read_cow_header - failed to allocate backing "
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)
1720 + __u64 size, offset;
1724 + err = write_cow_header(cow_file, fd, backing_file, sectorsize,
1725 + alignment, &size);
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);
1733 + offset = *data_offset_out + size - sizeof(zero);
1734 + err = cow_seek_file(fd, offset);
1736 + cow_printf("cow bitmap lseek failed : err = %d\n", -err);
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
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);
1759 + * ---------------------------------------------------------------------------
1760 + * Local variables:
1761 + * c-file-style: "linux"
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
1768 struct request_v3 req;
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",
1781 - if((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0){
1782 + fd = socket(AF_UNIX, SOCK_DGRAM, 0);
1784 printk("daemon_open : data socket failed, errno = %d\n",
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",
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",
1817 + os_close_file(fd);
1819 - close(pri->control);
1820 + os_close_file(pri->control);
1826 struct daemon_data *pri = data;
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
1839 printk("fd_init : couldn't parse file descriptor '%s'\n", str);
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 });
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
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]);
1865 int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
1869 err = os_pipe(in_fds, 1, 0);
1871 - printk("harddog_open - os_pipe failed, errno = %d\n", -err);
1874 + printk("harddog_open - os_pipe failed, err = %d\n", -err);
1878 err = os_pipe(out_fds, 1, 0);
1880 - printk("harddog_open - os_pipe failed, errno = %d\n", -err);
1883 + printk("harddog_open - os_pipe failed, err = %d\n", -err);
1884 + goto out_close_in;
1887 data.stdin = out_fds[0];
1890 pid = run_helper(pre_exec, &data, args, NULL);
1892 - close(out_fds[0]);
1894 + os_close_file(out_fds[0]);
1895 + os_close_file(in_fds[1]);
1899 - printk("harddog_open - run_helper failed, errno = %d\n", err);
1901 + printk("harddog_open - run_helper failed, errno = %d\n", -err);
1902 + goto out_close_out;
1905 - n = read(in_fds[0], &c, sizeof(c));
1906 + n = os_read_file(in_fds[0], &c, sizeof(c));
1908 printk("harddog_open - EOF on watchdog pipe\n");
1912 + goto out_close_out;
1915 printk("harddog_open - read of watchdog pipe failed, "
1916 - "errno = %d\n", errno);
1917 + "err = %d\n", -n);
1922 + goto out_close_out;
1924 *in_fd_ret = in_fds[0];
1925 *out_fd_ret = out_fds[1];
1929 + os_close_file(in_fds[0]);
1930 + os_close_file(in_fds[1]);
1932 + os_close_file(out_fds[0]);
1933 + os_close_file(out_fds[1]);
1935 - close(out_fds[1]);
1940 void stop_watchdog(int in_fd, int out_fd)
1944 + os_close_file(in_fd);
1945 + os_close_file(out_fd);
1948 int ping_watchdog(int fd)
1949 @@ -115,11 +120,12 @@
1953 - n = write(fd, &c, sizeof(c));
1954 - if(n < sizeof(c)){
1955 - printk("ping_watchdog - write failed, errno = %d\n",
1958 + n = os_write_file(fd, &c, sizeof(c));
1959 + if(n != sizeof(c)){
1960 + printk("ping_watchdog - write failed, err = %d\n", -n);
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
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"
1983 #include "hostaudio.h"
1985 char *dsp = HOSTAUDIO_DEV_DSP;
1986 char *mixer = HOSTAUDIO_DEV_MIXER;
1989 +" This is used to specify the host dsp device to the hostaudio driver.\n" \
1990 +" The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n"
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"
1997 static int set_dsp(char *name, int *add)
1999 - dsp = uml_strdup(name);
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"
2009 +__uml_setup("dsp=", set_dsp, "dsp=<dsp device>\n" DSP_HELP);
2011 static int set_mixer(char *name, int *add)
2013 - mixer = uml_strdup(name);
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"
2023 +__uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP);
2027 +MODULE_PARM(dsp, "s");
2028 +MODULE_PARM_DESC(dsp, DSP_HELP);
2030 +MODULE_PARM(mixer, "s");
2031 +MODULE_PARM_DESC(mixer, MIXER_HELP);
2035 /* /dev/dsp file operations */
2039 struct hostaudio_state *state = file->private_data;
2044 printk("hostaudio: read called, count = %d\n", count);
2047 - return(hostaudio_read_user(state, buffer, count, ppos));
2048 + kbuf = kmalloc(count, GFP_KERNEL);
2052 + err = hostaudio_read_user(state, kbuf, count, ppos);
2056 + if(copy_to_user(buffer, kbuf, err))
2064 static ssize_t hostaudio_write(struct file *file, const char *buffer,
2065 size_t count, loff_t *ppos)
2067 struct hostaudio_state *state = file->private_data;
2072 printk("hostaudio: write called, count = %d\n", count);
2074 - return(hostaudio_write_user(state, buffer, count, ppos));
2076 + kbuf = kmalloc(count, GFP_KERNEL);
2081 + if(copy_from_user(kbuf, buffer, count))
2084 + err = hostaudio_write_user(state, kbuf, count, ppos);
2093 static unsigned int hostaudio_poll(struct file *file,
2094 @@ -86,12 +127,43 @@
2095 unsigned int cmd, unsigned long arg)
2097 struct hostaudio_state *state = file->private_data;
2098 + unsigned long data = 0;
2102 printk("hostaudio: ioctl called, cmd = %u\n", 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))
2118 + err = hostaudio_ioctl_user(state, cmd, (unsigned long) &data);
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))
2134 - return(hostaudio_ioctl_user(state, cmd, arg));
2138 static int hostaudio_open(struct inode *inode, struct file *file)
2141 static int __init hostaudio_init_module(void)
2143 - printk(KERN_INFO "UML Audio Relay\n");
2144 + printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
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
2155 #include <sys/types.h>
2156 -#include <sys/stat.h>
2157 -#include <sys/ioctl.h>
2161 #include "hostaudio.h"
2163 ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer,
2164 size_t count, loff_t *ppos)
2169 printk("hostaudio: read_user called, count = %d\n", count);
2172 - ret = read(state->fd, buffer, count);
2174 - if(ret < 0) return(-errno);
2176 + return(os_read_file(state->fd, buffer, count));
2179 ssize_t hostaudio_write_user(struct hostaudio_state *state, const char *buffer,
2181 printk("hostaudio: write_user called, count = %d\n", count);
2184 - ret = write(state->fd, buffer, count);
2185 + return(os_write_file(state->fd, buffer, count));
2187 - if(ret < 0) return(-errno);
2191 int hostaudio_ioctl_user(struct hostaudio_state *state, unsigned int cmd,
2196 printk("hostaudio: ioctl_user called, cmd = %u\n", cmd);
2199 - ret = ioctl(state->fd, cmd, arg);
2201 - if(ret < 0) return(-errno);
2203 + return(os_ioctl_generic(state->fd, cmd, arg));
2206 int hostaudio_open_user(struct hostaudio_state *state, int r, int w, char *dsp)
2209 state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
2211 - if(state->fd >= 0) return(0);
2213 - printk("hostaudio_open_user failed to open '%s', errno = %d\n",
2215 + if(state->fd < 0) {
2216 + printk("hostaudio_open_user failed to open '%s', err = %d\n",
2218 + return(state->fd);
2225 int hostaudio_release_user(struct hostaudio_state *state)
2227 printk("hostaudio: release called\n");
2232 + os_close_file(state->fd);
2238 int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state,
2239 unsigned int cmd, unsigned long arg)
2243 printk("hostmixer: ioctl_user called cmd = %u\n",cmd);
2246 - ret = ioctl(state->fd, cmd, arg);
2250 + return(os_ioctl_generic(state->fd, cmd, arg));
2253 int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, int w,
2254 @@ -115,12 +99,13 @@
2256 state->fd = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
2258 - if(state->fd >= 0) return(0);
2260 - printk("hostaudio_open_mixdev_user failed to open '%s', errno = %d\n",
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);
2272 int hostmixer_release_mixdev_user(struct hostmixer_state *state)
2278 + os_close_file(state->fd);
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
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"
2296 #include "user_util.h"
2297 #include "kern_util.h"
2299 +#include "irq_kern.h"
2301 #define LINE_BUFSIZE 4096
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)
2306 struct line *dev = data;
2309 chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq,
2311 + return IRQ_HANDLED;
2314 -void line_timer_cb(void *arg)
2315 +static void line_timer_cb(void *arg)
2317 struct line *dev = arg;
2319 line_interrupt(dev->driver->read_irq, dev, NULL);
2322 -static void buffer_data(struct line *line, const char *buf, int len)
2323 +static int write_room(struct line *dev)
2328 + if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
2330 + n = dev->head - dev->tail;
2331 + if(n <= 0) n = LINE_BUFSIZE + n;
2335 +static int buffer_data(struct line *line, const char *buf, int len)
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");
2346 line->head = line->buffer;
2347 line->tail = line->buffer;
2350 + room = write_room(line);
2351 + len = (len > room) ? room : len;
2353 end = line->buffer + LINE_BUFSIZE - line->tail;
2355 memcpy(line->tail, buf, len);
2357 memcpy(line->buffer, buf, len);
2358 line->tail = line->buffer + len;
2364 static int flush_buffer(struct line *line)
2368 unsigned long flags;
2370 + int n, err, i, ret = 0;
2372 if(tty->stopped) return 0;
2374 @@ -104,9 +123,13 @@
2377 n = copy_from_user(new, buf, len);
2390 @@ -115,41 +138,50 @@
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);
2403 n = write_chan(&line->chan_list, buf, len,
2404 line->driver->write_irq);
2412 - buffer_data(line, buf + n, len - n);
2417 + ret += buffer_data(line, buf + n, len);
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)
2433 struct line *dev = data;
2434 struct tty_struct *tty = dev->tty;
2437 err = flush_buffer(dev);
2438 - if(err == 0) return;
2442 dev->head = dev->buffer;
2443 dev->tail = dev->buffer;
2446 - if(tty == NULL) return;
2450 if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
2451 (tty->ldisc.write_wakeup != NULL))
2452 @@ -161,21 +193,9 @@
2456 - if (waitqueue_active(&tty->write_wait))
2457 + if(waitqueue_active(&tty->write_wait))
2458 wake_up_interruptible(&tty->write_wait);
2462 -int line_write_room(struct tty_struct *tty)
2464 - struct line *dev = tty->driver_data;
2467 - if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
2469 - n = dev->head - dev->tail;
2470 - if(n <= 0) n = LINE_BUFSIZE + n;
2472 + return(IRQ_HANDLED);
2475 int line_setup_irq(int fd, int input, int output, void *data)
2478 printk(KERN_ERR "line_setup failed to parse \"%s\"\n",
2485 @@ -313,12 +333,12 @@
2486 if((n >= 0) && (n >= num)){
2487 printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
2493 if(lines[n].count > 0){
2494 printk("line_setup - device %d is open\n", n);
2498 if(lines[n].init_pri <= INIT_ONE){
2499 lines[n].init_pri = INIT_ONE;
2501 else if(!all_allowed){
2502 printk("line_setup - can't configure all devices from "
2508 for(i = 0; i < num; i++){
2517 int line_config(struct line *lines, int num, char *str)
2519 printk("line_config - uml_strdup failed\n");
2522 - return(line_setup(lines, num, new, 0));
2523 + return(!line_setup(lines, num, new, 0));
2526 int line_get_config(char *name, struct line *lines, int num, char *str,
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";
2536 @@ -379,15 +399,15 @@
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);
2554 @@ -396,7 +416,14 @@
2555 char config[sizeof("conxxxx=none\0")];
2557 sprintf(config, "%s=none", str);
2558 - return(line_setup(lines, num, config, 0));
2559 + return(!line_setup(lines, num, config, 0));
2562 +int line_write_room(struct tty_struct *tty)
2564 + struct line *dev = tty->driver_data;
2566 + return(write_room(dev));
2569 struct tty_driver *line_register_devfs(struct lines *set,
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;
2582 for(i = 0; i < nlines; i++){
2584 - tty_unregister_devfs(driver, i);
2585 + tty_unregister_device(driver, i);
2588 mconsole_register_dev(&line_driver->mc);
2589 @@ -465,24 +493,25 @@
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)
2596 struct winch *winch = data;
2597 struct tty_struct *tty;
2601 - err = generic_read(winch->fd, &c, NULL);
2603 - if(err != -EAGAIN){
2604 - printk("winch_interrupt : read failed, errno = %d\n",
2606 - printk("fd %d is losing SIGWINCH support\n",
2608 - free_irq(irq, data);
2610 + if(winch->fd != -1){
2611 + err = generic_read(winch->fd, &c, NULL);
2613 + if(err != -EAGAIN){
2614 + printk("winch_interrupt : read failed, "
2615 + "errno = %d\n", -err);
2616 + printk("fd %d is losing SIGWINCH support\n",
2618 + return(IRQ_HANDLED);
2624 tty = winch->line->tty;
2627 kill_pg(tty->pgrp, SIGWINCH, 1);
2630 - reactivate_fd(winch->fd, WINCH_IRQ);
2631 + if(winch->fd != -1)
2632 + reactivate_fd(winch->fd, WINCH_IRQ);
2633 + return(IRQ_HANDLED);
2636 DECLARE_MUTEX(winch_handler_sem);
2637 @@ -529,7 +560,10 @@
2639 list_for_each(ele, &winch_handlers){
2640 winch = list_entry(ele, struct winch, list);
2642 + if(winch->fd != -1){
2643 + deactivate_fd(winch->fd, WINCH_IRQ);
2644 + os_close_file(winch->fd);
2646 if(winch->pid != -1)
2647 os_kill_process(winch->pid, 1);
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
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
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
2666 obj-y += stdio_console.o $(CHAN_OBJS)
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))
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
2681 #include "kern_util.h"
2682 #include "user_util.h"
2686 #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
2692 - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
2693 + fd = socket(AF_INET, SOCK_DGRAM, 0);
2695 printk("mcast_open : data socket failed, errno = %d\n",
2699 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
2700 printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
2703 + os_close_file(fd);
2708 sizeof(pri->ttl)) < 0) {
2709 printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
2712 + os_close_file(fd);
2717 if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
2718 printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
2721 + os_close_file(fd);
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);
2730 + os_close_file(fd);
2735 "interface on the host.\n");
2736 printk("eth0 should be configured in order to use the "
2737 "multicast transport.\n");
2739 + os_close_file(fd);
2748 + os_close_file(fd);
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
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
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"
2777 +#include "irq_kern.h"
2779 static int do_unlink_socket(struct notifier_block *notifier,
2780 unsigned long what, void *data)
2783 DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
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)
2789 struct mconsole_entry *new;
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);
2798 - new = kmalloc(sizeof(req), GFP_ATOMIC);
2799 + new = kmalloc(sizeof(*new), GFP_ATOMIC);
2801 mconsole_reply(&req, "Out of memory", 1, 0);
2805 if(!list_empty(&mc_requests)) schedule_work(&mconsole_work);
2806 reactivate_fd(fd, MCONSOLE_IRQ);
2807 + return(IRQ_HANDLED);
2810 void mconsole_version(struct mc_request *req)
2811 @@ -100,20 +106,110 @@
2812 mconsole_reply(req, version, 0, 0);
2815 +void mconsole_log(struct mc_request *req)
2818 + char *ptr = req->request.data;
2820 + ptr += strlen("log");
2821 + while(isspace(*ptr)) ptr++;
2823 + len = req->len - (ptr - req->request.data);
2824 + printk("%.*s", len, ptr);
2825 + mconsole_reply(req, "", 0, 0);
2828 +void mconsole_proc(struct mc_request *req)
2830 + struct nameidata nd;
2831 + struct file_system_type *proc;
2832 + struct super_block *super;
2833 + struct file *file;
2835 + char *ptr = req->request.data, *buf;
2837 + ptr += strlen("proc");
2838 + while(isspace(*ptr)) ptr++;
2840 + proc = get_fs_type("proc");
2842 + mconsole_reply(req, "procfs not registered", 1, 0);
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);
2852 + up_write(&super->s_umount);
2854 + nd.dentry = super->s_root;
2856 + nd.flags = O_RDONLY + 1;
2857 + nd.last_type = LAST_ROOT;
2859 + err = link_path_walk(ptr, &nd);
2861 + mconsole_reply(req, "Failed to look up file", 1, 0);
2865 + file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
2867 + mconsole_reply(req, "Failed to open file", 1, 0);
2871 + buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
2873 + mconsole_reply(req, "Failed to allocate buffer", 1, 0);
2877 + if((file->f_op != NULL) && (file->f_op->read != NULL)){
2879 + n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1,
2883 + mconsole_reply(req, buf, 0, (n > 0));
2886 + mconsole_reply(req, "Read of file failed",
2892 + else mconsole_reply(req, "", 0, 0);
2899 + deactivate_super(super);
2903 #define UML_MCONSOLE_HELPTEXT \
2905 - version - Get kernel version
2906 - help - Print this message
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'
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\
2934 void mconsole_help(struct mc_request *req)
2936 if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
2937 snprintf(mconsole_socket_name, sizeof(file), "%s", file);
2939 - sock = create_unix_socket(file, sizeof(file));
2940 + sock = os_create_unix_socket(file, sizeof(file), 1);
2942 printk("Failed to initialize management console\n");
2944 @@ -344,11 +440,16 @@
2948 - if(copy_from_user(buf, buffer, count))
2950 + if(copy_from_user(buf, buffer, count)){
2957 mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count);
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
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
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 },
3002 /* Initialized in mconsole_init, which is an initcall */
3004 memcpy(reply.data, str, len);
3005 reply.data[len] = '\0';
3008 reply.len = len + 1;
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");
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");
3024 p_buf = __pa(v_buf);
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
3030 #include "mconsole_kern.h"
3032 #include "irq_user.h"
3033 +#include "irq_kern.h"
3035 static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
3038 struct sk_buff *skb;
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++;
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)
3054 struct net_device *dev = dev_id;
3055 struct uml_net_private *lp = dev->priv;
3058 if(!netif_running(dev))
3062 spin_lock(&lp->lock);
3063 while((err = uml_net_rx(dev)) > 0) ;
3067 spin_unlock(&lp->lock);
3068 + return(IRQ_HANDLED);
3071 static int uml_net_open(struct net_device *dev)
3072 @@ -252,37 +255,6 @@
3077 - * default do nothing hard header packet routines for struct net_device init.
3078 - * real ethernet transports will overwrite with real routines.
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)
3083 - return(0); /* no change */
3086 -static int uml_net_rebuild_header(struct sk_buff *skb)
3088 - return(0); /* ignore */
3091 -static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh)
3093 - return(-1); /* fail */
3096 -static void uml_net_header_cache_update(struct hh_cache *hh,
3097 - struct net_device *dev, unsigned char * haddr)
3102 -static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr)
3104 - return(0); /* nothing */
3107 static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
3108 static struct list_head devices = LIST_HEAD_INIT(devices);
3111 struct uml_net *device;
3112 struct net_device *dev;
3113 struct uml_net_private *lp;
3115 + int save, err, size;
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);
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;
3129 (*transport->kern->init)(dev, init);
3131 dev->mtu = transport->user->max_packet;
3132 @@ -362,21 +328,29 @@
3136 - INIT_LIST_HEAD(&lp->list);
3137 - spin_lock_init(&lp->lock);
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.
3156 + save = lp->user[0];
3157 + *lp = ((struct uml_net_private)
3158 + { .list = LIST_HEAD_INIT(lp->list),
3159 + .lock = SPIN_LOCK_UNLOCKED,
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 } });
3175 init_timer(&lp->tl);
3176 lp->tl.function = uml_net_user_timer_expire;
3178 unregister_netdev(dev);
3180 list_del(&device->list);
3181 - free_netdev(device);
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
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",
3196 + printk("Invalid tap IP address - '%s'\n", gate_addr);
3204 - if(read(fd, &remain, sizeof(remain)) != sizeof(remain)){
3205 - printk("read_output - read of length failed, errno = %d\n",
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);
3214 n = (remain < len) ? remain : len;
3215 - actual = read(fd, output, n);
3216 + actual = os_read_file(fd, output, n);
3218 printk("read_output - read of data failed, "
3219 - "errno = %d\n", errno);
3220 + "err = %d\n", -actual);
3228 - while(((n = read(fd, buf, len)) < 0) && (errno == EINTR)) ;
3229 + n = os_read_file(fd, buf, len);
3232 - if(errno == EAGAIN) return(0);
3235 - else if(n == 0) return(-ENOTCONN);
3239 + return(-ENOTCONN);
3243 @@ -112,13 +110,13 @@
3247 - while(((n = write(fd, buf, len)) < 0) && (errno == EINTR)) ;
3249 - if(errno == EAGAIN) return(0);
3252 - else if(n == 0) return(-ENOTCONN);
3254 + n = os_write_file(fd, buf, len);
3259 + return(-ENOTCONN);
3263 int net_send(int fd, void *buf, int len)
3266 struct change_pre_exec_data *data = arg;
3268 - close(data->close_me);
3269 + os_close_file(data->close_me);
3270 dup2(data->stdout, 1);
3273 @@ -167,15 +165,15 @@
3274 struct change_pre_exec_data pe_data;
3276 err = os_pipe(fds, 1, 0);
3278 - printk("change_tramp - pipe failed, errno = %d\n", -err);
3280 + printk("change_tramp - pipe failed, err = %d\n", -err);
3283 pe_data.close_me = fds[0];
3284 pe_data.stdout = fds[1];
3285 pid = run_helper(change_pre_exec, &pe_data, argv, NULL);
3288 + os_close_file(fds[1]);
3289 read_output(fds[0], output, output_len);
3290 waitpid(pid, NULL, 0);
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
3300 #include "chan_user.h"
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
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"
3315 #include "kern_util.h"
3317 #include "irq_user.h"
3318 +#include "irq_kern.h"
3323 struct port_list *port;
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)
3329 struct connection *conn = data;
3332 fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
3338 printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n",
3341 list_add(&conn->list, &conn->port->connections);
3343 up(&conn->port->sem);
3344 + return(IRQ_HANDLED);
3347 static int port_accept(struct port_list *port)
3348 @@ -138,12 +141,13 @@
3350 DECLARE_WORK(port_work, port_work_proc, NULL);
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)
3355 struct port_list *port = data;
3357 port->has_connection = 1;
3358 schedule_work(&port_work);
3359 + return(IRQ_HANDLED);
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
3370 - if((kern_data = port_data(port)) == NULL)
3371 + kern_data = port_data(port);
3372 + if(kern_data == NULL)
3375 - if((data = um_kmalloc(sizeof(*data))) == NULL)
3376 + data = um_kmalloc(sizeof(*data));
3380 *data = ((struct port_chan) { .raw = opts->raw,
3382 struct port_chan *data = d;
3384 port_remove_dev(data->kernel_data);
3386 + os_close_file(fd);
3389 int port_console_write(int fd, const char *buf, int n, void *d)
3390 @@ -130,11 +132,15 @@
3394 - if((listen(fd, 1) < 0) || (os_set_fd_block(fd, 0))){
3395 + if(listen(fd, 1) < 0){
3400 + err = os_set_fd_block(fd, 0);
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);
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;
3424 - if((new = os_accept_connection(fd)) < 0)
3426 + new = os_accept_connection(fd);
3430 err = os_pipe(socket, 0, 0);
3435 data = ((struct port_pre_exec_data)
3436 @@ -186,11 +193,11 @@
3439 os_shutdown_socket(socket[0], 1, 1);
3441 + os_close_file(socket[0]);
3442 os_shutdown_socket(socket[1], 1, 1);
3444 + os_close_file(socket[1]);
3447 + os_close_file(new);
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
3459 #include <termios.h>
3460 #include "chan_user.h"
3462 #include "user_util.h"
3463 #include "kern_util.h"
3467 void (*announce)(char *dev_name, int dev);
3470 struct pty_chan *data;
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,
3477 .raw = opts->raw });
3482 - if((fd = get_pty()) < 0){
3485 printk("open_pts : Failed to open pts\n");
3490 int getmaster(char *line)
3493 char *pty, *bank, *cp;
3497 pty = &line[strlen("/dev/ptyp")];
3498 for (bank = "pqrs"; *bank; bank++) {
3499 line[strlen("/dev/pty")] = *bank;
3501 - if (stat(line, &stb) < 0)
3502 + if (os_stat_file(line, NULL) < 0)
3504 for (cp = "0123456789abcdef"; *cp; cp++) {
3506 - master = open(line, O_RDWR);
3507 + master = os_open_file(line, of_rdwr(OPENFLAGS()), 0);
3509 char *tp = &line[strlen("/dev/")];
3512 /* verify slave side is usable */
3514 - ok = access(line, R_OK|W_OK) == 0;
3515 + err = os_access(line, OS_ACC_RW_OK);
3517 - if (ok) return(master);
3518 - (void) close(master);
3519 + if(err == 0) return(master);
3520 + (void) os_close_file(master);
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
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"
3541 struct slip_pre_exec_data *data = arg;
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);
3550 static int slip_tramp(char **argv, int fd)
3552 int status, pid, fds[2], err, output_len;
3554 err = os_pipe(fds, 1, 0);
3556 - printk("slip_tramp : pipe failed, errno = %d\n", -err);
3558 + printk("slip_tramp : pipe failed, err = %d\n", -err);
3563 printk("slip_tramp : failed to allocate output "
3567 + os_close_file(fds[1]);
3568 read_output(fds[0], output, output_len);
3570 printk("%s", output);
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]);
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,
3584 - int sfd, mfd, disc, sencap, err;
3585 + int sfd, mfd, err;
3587 - if((mfd = get_pty()) < 0){
3588 - printk("umn : Failed to open pty\n");
3592 + printk("umn : Failed to open pty, err = %d\n", -mfd);
3595 - if((sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0)) < 0){
3596 - printk("Couldn't open tty for slip line\n");
3598 + sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
3600 + printk("Couldn't open tty for slip line, err = %d\n", -sfd);
3603 if(set_up_tty(sfd)) return(-1);
3605 @@ -138,28 +138,23 @@
3607 err = slip_tramp(argv, sfd);
3610 - printk("slip_tramp failed - errno = %d\n", err);
3613 + printk("slip_tramp failed - err = %d\n", -err);
3616 - if(ioctl(pri->slave, SIOCGIFNAME, pri->name) < 0){
3617 - printk("SIOCGIFNAME failed, errno = %d\n", errno);
3619 + err = os_get_ifname(pri->slave, pri->name);
3621 + printk("get_ifname failed, err = %d\n", -err);
3624 iter_addresses(pri->dev, open_addr, pri->name);
3628 - if(ioctl(sfd, TIOCSETD, &disc) < 0){
3629 - printk("Failed to set slip line discipline - "
3630 - "errno = %d\n", errno);
3634 - if(ioctl(sfd, SIOCSIFENCAP, &sencap) < 0){
3635 - printk("Failed to set slip encapsulation - "
3636 - "errno = %d\n", errno);
3638 + err = os_set_slip(sfd);
3640 + printk("Failed to set slip discipline encapsulation - "
3641 + "err = %d\n", -err);
3647 err = slip_tramp(argv, -1);
3650 - printk("slip_tramp failed - errno = %d\n", err);
3652 - close(pri->slave);
3653 + printk("slip_tramp failed - errno = %d\n", -err);
3654 + os_close_file(fd);
3655 + os_close_file(pri->slave);
3661 struct slip_data *pri = data;
3663 - if(pri->slave == -1) return;
3664 + if(pri->slave < 0) return;
3665 open_addr(addr, netmask, pri->name);
3670 struct slip_data *pri = data;
3672 - if(pri->slave == -1) return;
3673 + if(pri->slave < 0) return;
3674 close_addr(addr, netmask, pri->name);
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
3684 -#include <sys/fcntl.h>
3685 #include <sys/errno.h>
3686 #include <sys/wait.h>
3687 #include <sys/signal.h>
3694 +/* XXX This is just a trivial wrapper around os_pipe */
3695 static int slirp_datachan(int *mfd, int *sfd)
3699 err = os_pipe(fds, 1, 1);
3701 - printk("slirp_datachan: Failed to open pipe, errno = %d\n",
3704 + printk("slirp_datachan: Failed to open pipe, err = %d\n", -err);
3709 pid = slirp_tramp(pri->argw.argv, sfd);
3712 - printk("slirp_tramp failed - errno = %d\n", pid);
3713 + printk("slirp_tramp failed - errno = %d\n", -pid);
3718 struct slirp_data *pri = data;
3722 - close(pri->slave);
3723 + os_close_file(fd);
3724 + os_close_file(pri->slave);
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
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"
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,
3749 .type = TTY_DRIVER_TYPE_SERIAL,
3761 @@ -212,6 +217,39 @@
3763 static int ssl_init_done = 0;
3765 +extern int tty_init(void);
3767 +static void ssl_console_write(struct console *c, const char *string,
3770 + struct line *line = &serial_lines[c->index];
3773 + console_write_chan(&line->chan_list, string, len);
3778 +static struct tty_driver *ssl_console_device(struct console *c, int *index)
3780 + *index = c->index;
3781 + return ssl_driver;
3784 +static int ssl_console_setup(struct console *co, char *options)
3789 +static struct console ssl_cons = {
3791 + write: ssl_console_write,
3792 + device: ssl_console_device,
3793 + setup: ssl_console_setup,
3794 + flags: CON_PRINTBUFFER,
3802 printk(KERN_INFO "Initializing software serial port version %d\n",
3807 ssl_driver = line_register_devfs(&lines, &driver, &ssl_ops,
3808 serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]));
3811 new_title = add_xterm_umid(opts.xterm_title);
3812 if(new_title != NULL) opts.xterm_title = new_title;
3814 + register_console(&ssl_cons);
3820 static int ssl_chan_setup(char *str)
3822 - line_setup(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]),
3825 + return(line_setup(serial_lines,
3826 + sizeof(serial_lines)/sizeof(serial_lines[0]),
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
3836 static struct line_driver driver = {
3837 .name = "UML console",
3838 - .devfs_name = "vc/%d",
3839 + .device_name = "tty",
3840 + .devfs_name = "vc/",
3843 .type = TTY_DRIVER_TYPE_CONSOLE,
3844 @@ -159,14 +160,28 @@
3846 static int con_init_done = 0;
3848 +static struct tty_operations console_ops = {
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,
3857 +extern int tty_init(void);
3859 int stdio_init(void)
3863 printk(KERN_INFO "Initializing stdio console driver\n");
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]));
3872 lines_init(vts, sizeof(vts)/sizeof(vts[0]));
3874 @@ -183,19 +198,14 @@
3875 static void console_write(struct console *console, const char *string,
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);
3882 + struct line *line = &vts[console->index];
3884 -static struct tty_operations console_ops = {
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,
3894 + console_write_chan(&line->chan_list, string, len);
3899 static struct tty_driver *console_device(struct console *c, int *index)
3901 @@ -208,22 +218,28 @@
3905 -static struct console stdiocons = INIT_CONSOLE("tty", console_write,
3906 - console_device, console_setup,
3908 +static struct console stdiocons = {
3910 + write: console_write,
3911 + device: console_device,
3912 + setup: console_setup,
3913 + flags: CON_PRINTBUFFER,
3917 -static void __init stdio_console_init(void)
3918 +static int __init stdio_console_init(void)
3920 INIT_LIST_HEAD(&vts[0].chan_list);
3921 list_add(&init_console_chan.list, &vts[0].chan_list);
3922 register_console(&stdiocons);
3926 console_initcall(stdio_console_init);
3928 static int console_chan_setup(char *str)
3930 - line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1);
3932 + return(line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1));
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
3942 #include <termios.h>
3946 #include "chan_user.h"
3951 - if((data = um_kmalloc(sizeof(*data))) == NULL)
3952 + data = um_kmalloc(sizeof(*data));
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
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.
3973 #define MAJOR_NR UBD_MAJOR
3975 #include "mconsole_kern.h"
3977 #include "irq_user.h"
3978 +#include "irq_kern.h"
3979 #include "ubd_user.h"
3980 #include "2_5compat.h"
3983 +#include "mem_kern.h"
3985 static spinlock_t ubd_io_lock = SPIN_LOCK_UNLOCKED;
3986 static spinlock_t ubd_lock = SPIN_LOCK_UNLOCKED;
3991 +/* Changed in early boot */
3992 +static int ubd_do_mmap = 0;
3993 +#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE
3995 static struct block_device_operations ubd_blops = {
3996 .owner = THIS_MODULE,
3999 static request_queue_t *ubd_queue;
4001 /* Protected by ubd_lock */
4002 -static int fake_major = 0;
4003 +static int fake_major = MAJOR_NR;
4005 static struct gendisk *ubd_gendisk[MAX_DEV];
4006 static struct gendisk *fake_gendisk[MAX_DEV];
4007 @@ -96,13 +110,19 @@
4015 struct openflags boot_openflags;
4016 struct openflags openflags;
4027 #define DEFAULT_COW { \
4028 @@ -115,21 +135,28 @@
4030 #define DEFAULT_UBD { \
4036 .boot_openflags = OPEN_FLAGS, \
4037 .openflags = OPEN_FLAGS, \
4039 .cow = DEFAULT_COW, \
4040 + .map_writes = 0, \
4042 + .nomap_writes = 0, \
4043 + .nomap_reads = 0, \
4044 + .write_maps = 0, \
4047 struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
4049 static int ubd0_init(void)
4051 - if(ubd_dev[0].file == NULL)
4052 - ubd_dev[0].file = "root_fs";
4053 + struct ubd *dev = &ubd_dev[0];
4055 + if(dev->file == NULL)
4056 + dev->file = "root_fs";
4060 @@ -196,19 +223,46 @@
4061 " Create ide0 entries that map onto ubd devices.\n\n"
4064 +static int parse_unit(char **ptr)
4066 + char *str = *ptr, *end;
4069 + if(isdigit(*str)) {
4070 + n = simple_strtoul(str, &end, 0);
4075 + else if (('a' <= *str) && (*str <= 'h')) {
4083 static int ubd_setup_common(char *str, int *index_out)
4086 struct openflags flags = global_openflags;
4090 if(index_out) *index_out = -1;
4094 - static int fake_major_allowed = 1;
4099 + if(!strcmp(str, "mmap")){
4100 + CHOOSE_MODE(printk("mmap not supported by the ubd "
4101 + "driver in tt mode\n"),
4106 if(!strcmp(str, "sync")){
4107 global_openflags.s = 1;
4109 @@ -220,20 +274,14 @@
4113 - if(!fake_major_allowed){
4114 - printk(KERN_ERR "Can't assign a fake major twice\n");
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");
4127 - fake_major_allowed = 0;
4129 printk(KERN_INFO "Setting extra ubd major number to %d\n",
4131 @@ -243,25 +291,23 @@
4136 - printk(KERN_ERR "ubd_setup : index out of range\n"); }
4138 - if((n >= '0') && (n <= '9')) n -= '0';
4139 - else if((n >= 'a') && (n <= 'z')) n -= 'a';
4141 - printk(KERN_ERR "ubd_setup : device syntax invalid\n");
4142 + n = parse_unit(&str);
4144 + printk(KERN_ERR "ubd_setup : couldn't parse unit number "
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);
4157 spin_lock(&ubd_lock);
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");
4165 @@ -276,6 +322,11 @@
4175 printk(KERN_ERR "ubd_setup : Expected '='\n");
4177 @@ -284,14 +335,17 @@
4179 backing_file = strchr(str, ',');
4181 - *backing_file = '\0';
4184 + printk(KERN_ERR "Can't specify both 'd' and a "
4187 + *backing_file = '\0';
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;
4197 + dev->cow.file = backing_file;
4198 + dev->boot_openflags = flags;
4200 spin_unlock(&ubd_lock);
4203 static int fakehd_set = 0;
4204 static int fakehd(char *str)
4207 - "fakehd : Changing ubd name to \"hd\".\n");
4208 + printk(KERN_INFO "fakehd : Changing ubd name to \"hd\".\n");
4212 @@ -368,32 +421,42 @@
4214 struct io_thread_req req;
4215 struct request *rq = elv_next_request(ubd_queue);
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);
4228 spin_unlock(&ubd_io_lock);
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");
4239 + if(req.map_fd != -1){
4240 + err = physmem_subst_mapping(req.buffer, req.map_fd,
4241 + req.map_offset, 1);
4243 + printk("ubd_handler - physmem_subst_mapping failed, "
4244 + "err = %d\n", -err);
4247 ubd_finish(rq, req.error);
4248 reactivate_fd(thread_fd, UBD_IRQ);
4249 do_ubd_request(ubd_queue);
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)
4256 + return(IRQ_HANDLED);
4259 /* Only changed by ubd_init, which is an initcall. */
4260 @@ -429,18 +492,20 @@
4261 static int ubd_open_dev(struct ubd *dev)
4263 struct openflags flags;
4264 - int err, n, create_cow, *create_ptr;
4266 + int err, create_cow, *create_ptr;
4268 + dev->openflags = dev->boot_openflags;
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);
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){
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");
4294 flush_tlb_kernel_vm();
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;
4303 flags = dev->openflags;
4305 @@ -481,17 +550,31 @@
4308 struct gendisk *disk;
4309 + char from[sizeof("ubd/nnnnn\0")], to[sizeof("discnnnnn/disc\0")];
4312 disk = alloc_disk(1 << UBD_SHIFT);
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);
4331 + printk("ubd_new_disk failed to make link from %s to "
4332 + "%s, error = %d\n", from, to, err);
4335 + sprintf(disk->disk_name, "ubd_fake%d", unit);
4336 + sprintf(disk->devfs_name, "ubd_fake/disc%d", unit);
4339 disk->private_data = &ubd_dev[unit];
4340 disk->queue = ubd_queue;
4341 @@ -506,24 +589,21 @@
4342 struct ubd *dev = &ubd_dev[n];
4349 + if(dev->file == NULL)
4352 if (ubd_open_dev(dev))
4355 err = ubd_file_size(dev, &dev->size);
4360 err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
4365 + if(fake_major != MAJOR_NR)
4366 ubd_new_disk(fake_major, dev->size, n,
4369 @@ -561,42 +641,42 @@
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)
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";
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";
4398 - ubd = &ubd_dev[major];
4399 + dev = &ubd_dev[n];
4400 spin_lock(&ubd_lock);
4402 - if(ubd->file == NULL){
4403 - CONFIG_CHUNK(str, size, n, "", 1);
4404 + if(dev->file == NULL){
4405 + CONFIG_CHUNK(str, size, len, "", 1);
4409 - CONFIG_CHUNK(str, size, n, ubd->file, 0);
4410 + CONFIG_CHUNK(str, size, len, dev->file, 0);
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);
4419 - else CONFIG_CHUNK(str, size, n, "", 1);
4420 + else CONFIG_CHUNK(str, size, len, "", 1);
4423 spin_unlock(&ubd_lock);
4428 static int ubd_remove(char *str)
4429 @@ -604,11 +684,9 @@
4431 int n, err = -ENODEV;
4433 - if(!isdigit(*str))
4434 - return(err); /* it should be a number 0-7/a-h */
4435 + n = parse_unit(&str);
4439 + if((n < 0) || (n >= MAX_DEV))
4445 elevator_init(ubd_queue, &elevator_noop);
4447 - if (fake_major != 0) {
4448 + if (fake_major != MAJOR_NR) {
4449 char name[sizeof("ubd_nnn\0")];
4451 snprintf(name, sizeof(name), "ubd_%d", fake_major);
4453 io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
4458 "ubd : Failed to start I/O thread (errno = %d) - "
4459 "falling back to synchronous I/O\n", -io_pid);
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);
4467 + printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
4471 @@ -714,15 +793,9 @@
4473 struct gendisk *disk = inode->i_bdev->bd_disk;
4474 struct ubd *dev = disk->private_data;
4475 - int err = -EISDIR;
4477 - if(dev->is_dir == 1)
4482 if(dev->count == 0){
4483 - dev->openflags = dev->boot_openflags;
4485 err = ubd_open_dev(dev);
4487 printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
4488 @@ -749,62 +822,156 @@
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,
4498 + __u64 sector = io_offset >> 9;
4499 + int i, update_bitmap = 0;
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))
4507 + update_bitmap = 1;
4508 + ubd_set_bit(sector + i, (unsigned char *) bitmap);
4511 + if(!update_bitmap)
4514 + *cow_offset = sector / (sizeof(unsigned long) * 8);
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.
4521 + if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) /
4522 + sizeof(unsigned long) - 1))
4525 + bitmap_words[0] = bitmap[*cow_offset];
4526 + bitmap_words[1] = bitmap[*cow_offset + 1];
4528 + *cow_offset *= sizeof(unsigned long);
4529 + *cow_offset += bitmap_offset;
4532 +static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
4533 + __u64 bitmap_offset, __u64 bitmap_len)
4535 - int i, update_bitmap, sector = req->offset >> 9;
4536 + __u64 sector = req->offset >> 9;
4539 if(req->length > (sizeof(req->sector_mask) * 8) << 9)
4540 panic("Operation too long");
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 *)
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 *)
4559 - update_bitmap = 1;
4560 - ubd_set_bit(sector + i, (unsigned char *)
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;
4572 + else cowify_bitmap(req->offset, req->length, &req->sector_mask,
4573 + &req->cow_offset, bitmap, bitmap_offset,
4574 + req->bitmap_words, bitmap_len);
4577 +static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset)
4580 + unsigned char *bitmap;
4583 + /* mmap must have been requested on the command line */
4587 + /* The buffer must be page aligned */
4588 + if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0)
4591 + /* The request must be a page long */
4592 + if((req->current_nr_sectors << 9) != PAGE_SIZE)
4595 + if(dev->cow.file == NULL)
4598 + sector = offset >> 9;
4599 + bitmap = (unsigned char *) dev->cow.bitmap;
4600 + bit = ubd_test_bit(sector, bitmap);
4602 + for(i = 1; i < req->current_nr_sectors; i++){
4603 + if(ubd_test_bit(sector + i, bitmap) != bit)
4607 + if(bit || (rq_data_dir(req) == WRITE))
4608 + offset += dev->cow.data_offset;
4610 + /* The data on disk must be page aligned */
4611 + if((offset % UBD_MMAP_BLOCK_SIZE) != 0)
4614 + return(bit ? dev->fd : dev->cow.fd);
4617 +static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset,
4618 + struct request *req,
4619 + struct io_thread_req *io_req)
4623 + if(rq_data_dir(req) == WRITE){
4624 + /* Writes are almost no-ops since the new data is already in the
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);
4638 + if((dev->cow.file != NULL) && (fd == dev->cow.fd))
4640 + else w = dev->openflags.w;
4642 + if((dev->cow.file != NULL) && (fd == dev->fd))
4643 + offset += dev->cow.data_offset;
4645 + err = physmem_subst_mapping(req->buffer, fd, offset, w);
4647 + printk("physmem_subst_mapping failed, err = %d\n",
4653 + io_req->op = UBD_MMAP;
4654 + io_req->buffer = req->buffer;
4658 static int prepare_request(struct request *req, struct io_thread_req *io_req)
4660 struct gendisk *disk = req->rq_disk;
4661 struct ubd *dev = disk->private_data;
4667 if(req->rq_status == RQ_INACTIVE) return(1);
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);
4678 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
4679 printk("Write attempted on readonly ubd device %s\n",
4681 @@ -814,23 +981,49 @@
4685 - block = req->sector;
4686 - nsect = req->current_nr_sectors;
4687 + offset = ((__u64) req->sector) << 9;
4688 + len = req->current_nr_sectors << 9;
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;
4700 + fd = mmap_fd(req, dev, io_req->offset);
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.
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++;
4713 + else return(prepare_mmap_request(dev, fd, io_req->offset, req,
4717 + if(rq_data_dir(req) == READ)
4718 + dev->nomap_reads++;
4719 + else dev->nomap_writes++;
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;
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);
4740 @@ -885,7 +1078,7 @@
4743 g.cylinders = dev->size / (128 * 32 * 512);
4745 + g.start = get_start_sect(inode->i_bdev);
4746 return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0);
4748 case HDIO_SET_UNMASKINTR:
4749 @@ -935,6 +1128,142 @@
4753 +static int ubd_check_remapped(int fd, unsigned long address, int is_write,
4756 + __u64 bitmap_offset;
4757 + unsigned long new_bitmap[2];
4760 + /* If it's not a write access, we can't do anything about it */
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];
4768 + if((dev->fd != fd) && (dev->cow.fd != fd))
4771 + /* It's a write to a ubd device */
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
4780 + printk("Write access to mapped page from readonly ubd "
4781 + "device %d\n", i);
4785 + /* It's a write to a writeable ubd device - it must be COWed
4786 + * because, otherwise, the page would have been mapped in
4790 + if(!dev->cow.file)
4791 + panic("Write fault on writeable non-COW ubd device %d",
4794 + /* It should also be an access to the backing file since the
4795 + * COW pages should be mapped in read-write
4799 + panic("Write fault on a backing page of ubd "
4800 + "device %d\n", i);
4802 + /* So, we do the write, copying the backing data to the COW
4806 + err = os_seek_file(dev->fd, offset + dev->cow.data_offset);
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);
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);
4817 + /* ... updating the COW bitmap... */
4819 + cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset,
4820 + dev->cow.bitmap, dev->cow.bitmap_offset,
4821 + new_bitmap, dev->cow.bitmap_len);
4823 + err = os_seek_file(dev->fd, bitmap_offset);
4825 + panic("Couldn't seek to %lld in COW file of ubd "
4826 + "device %d, err = %d", bitmap_offset, i, -err);
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);
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.
4840 + offset += dev->cow.data_offset;
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.
4847 + if(!physmem_remove_mapping((void *) address))
4848 + panic("Address 0x%lx not remapped by ubd device %d",
4850 + if((offset % UBD_MMAP_BLOCK_SIZE) == 0)
4851 + physmem_subst_mapping((void *) address, dev->fd,
4854 + err = os_seek_file(dev->fd, offset);
4856 + panic("Couldn't seek to %lld in COW file of "
4857 + "ubd device %d, err = %d", offset, i,
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",
4870 + /* It's not a write on a ubd device */
4874 +static struct remapper ubd_remapper = {
4875 + .list = LIST_HEAD_INIT(ubd_remapper.list),
4876 + .proc = ubd_check_remapped,
4879 +static int ubd_remapper_setup(void)
4882 + register_remapper(&ubd_remapper);
4887 +__initcall(ubd_remapper_setup);
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
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 @@
4909 #include "ubd_user.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)
4922 -#error "__BYTE_ORDER not defined"
4925 -#define PATH_LEN_V1 256
4927 -struct cow_header_v1 {
4930 - char backing_file[PATH_LEN_V1];
4936 -#define PATH_LEN_V2 MAXPATHLEN
4938 -struct cow_header_v2 {
4939 - unsigned long magic;
4940 - unsigned long version;
4941 - char backing_file[PATH_LEN_V2];
4948 - struct cow_header_v1 v1;
4949 - struct cow_header_v2 v2;
4952 -#define COW_MAGIC 0x4f4f4f4d /* MOOO */
4953 -#define COW_VERSION 2
4955 -static void sizes(__u64 size, int sectorsize, int bitmap_offset,
4956 - unsigned long *bitmap_len_out, int *data_offset_out)
4958 - *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
4960 - *data_offset_out = bitmap_offset + *bitmap_len_out;
4961 - *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
4962 - *data_offset_out *= sectorsize;
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)
4969 - union cow_header *header;
4972 - unsigned long version, magic;
4974 - header = um_kmalloc(sizeof(*header));
4975 - if(header == NULL){
4976 - printk("read_cow_header - Failed to allocate header\n");
4980 - n = read(fd, header, sizeof(*header));
4981 - if(n < offsetof(typeof(header->v1), backing_file)){
4982 - printk("read_cow_header - short header\n");
4986 - magic = header->v1.magic;
4987 - if(magic == COW_MAGIC) {
4988 - version = header->v1.version;
4990 - else if(magic == ntohl(COW_MAGIC)){
4991 - version = ntohl(header->v1.version);
4995 - *magic_out = COW_MAGIC;
4998 - if(n < sizeof(header->v1)){
4999 - printk("read_cow_header - failed to read V1 header\n");
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;
5008 - else if(version == 2){
5009 - if(n < sizeof(header->v2)){
5010 - printk("read_cow_header - failed to read V2 header\n");
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;
5020 - printk("read_cow_header - invalid COW version\n");
5024 - *backing_file_out = uml_strdup(file);
5025 - if(*backing_file_out == NULL){
5026 - printk("read_cow_header - failed to allocate backing file\n");
5035 static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
5037 - struct stat buf1, buf2;
5038 + struct uml_stat buf1, buf2;
5041 if(from_cmdline == NULL) return(1);
5042 if(!strcmp(from_cmdline, from_cow)) return(1);
5044 - if(stat(from_cmdline, &buf1) < 0){
5045 - printk("Couldn't stat '%s', errno = %d\n", from_cmdline,
5047 + err = os_stat_file(from_cmdline, &buf1);
5049 + printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
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);
5056 + printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
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))
5063 printk("Backing file mismatch - \"%s\" requested,\n"
5064 @@ -174,20 +55,21 @@
5066 static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
5068 - struct stat64 buf;
5069 + unsigned long modtime;
5073 - if(stat64(file, &buf) < 0){
5074 - printk("Failed to stat backing file \"%s\", errno = %d\n",
5077 + err = os_file_modtime(file, &modtime);
5079 + printk("Failed to get modification time of backing file "
5080 + "\"%s\", err = %d\n", file, -err);
5084 err = os_file_size(file, &actual);
5087 printk("Failed to get size of backing file \"%s\", "
5088 - "errno = %d\n", file, -err);
5089 + "err = %d\n", file, -err);
5094 "file\n", size, actual);
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);
5105 @@ -209,124 +91,16 @@
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);
5117 -static int absolutize(char *to, int size, char *from)
5119 - char save_cwd[256], *slash;
5121 + err = os_read_file(fd, buf, len);
5125 - if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
5126 - printk("absolutize : unable to get cwd - errno = %d\n", errno);
5129 - slash = strrchr(from, '/');
5130 - if(slash != NULL){
5134 - printk("absolutize : Can't cd to '%s' - errno = %d\n",
5139 - if(getcwd(to, size) == NULL){
5140 - printk("absolutize : unable to get cwd of '%s' - "
5141 - "errno = %d\n", from, errno);
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);
5150 - strcat(to, slash);
5153 - if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
5154 - printk("absolutize : unable to fit '%s' into %d "
5155 - "chars\n", from, size);
5158 - strcpy(to, save_cwd);
5166 -static int write_cow_header(char *cow_file, int fd, char *backing_file,
5167 - int sectorsize, long long *size)
5169 - struct cow_header_v2 *header;
5170 - struct stat64 buf;
5173 - err = os_seek_file(fd, 0);
5175 - printk("write_cow_header - lseek failed, errno = %d\n", errno);
5180 - header = um_kmalloc(sizeof(*header));
5181 - if(header == NULL){
5182 - printk("Failed to allocate COW V2 header\n");
5185 - header->magic = htonl(COW_MAGIC);
5186 - header->version = htonl(COW_VERSION);
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);
5196 - if(absolutize(header->backing_file, sizeof(header->backing_file),
5200 - err = stat64(header->backing_file, &buf);
5202 - printk("Stat of backing file '%s' failed, errno = %d\n",
5203 - header->backing_file, errno);
5208 - err = os_file_size(header->backing_file, size);
5210 - printk("Couldn't get size of backing file '%s', errno = %d\n",
5211 - header->backing_file, -*size);
5215 - header->mtime = htonl(buf.st_mtime);
5216 - header->size = htonll(*size);
5217 - header->sectorsize = htonl(sectorsize);
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);
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 @@
5239 + __u32 version, align;
5241 - int fd, err, sectorsize, magic, same, mode = 0644;
5242 + int fd, err, sectorsize, same, mode = 0644;
5244 - if((fd = os_open_file(file, *openflags, mode)) < 0){
5245 + fd = os_open_file(file, *openflags, mode);
5247 if((fd == -ENOENT) && (create_cow_out != NULL))
5248 *create_cow_out = 1;
5250 ((errno != EROFS) && (errno != EACCES))) return(-errno);
5252 - if((fd = os_open_file(file, *openflags, mode)) < 0)
5253 + fd = os_open_file(file, *openflags, mode);
5258 + err = os_lock_file(fd, openflags->w);
5260 + printk("Failed to lock '%s', err = %d\n", file, -err);
5264 if(backing_file_out == NULL) return(fd);
5266 - err = read_cow_header(fd, &magic, &backing_file, &mtime, &size,
5267 - §orsize, bitmap_offset_out);
5268 + err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
5269 + &size, §orsize, &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);
5274 + "errno = %d\n", file, -err);
5279 @@ -363,36 +147,33 @@
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);
5288 - printk("Switch failed, errno = %d\n", err);
5289 + printk("Switch failed, errno = %d\n", -err);
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;
5300 - sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out,
5302 + cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
5303 + bitmap_len_out, data_offset_out);
5309 + os_close_file(fd);
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)
5325 fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
5326 @@ -403,57 +184,49 @@
5330 - err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
5331 - if(err) goto out_close;
5333 - blocks = (size + sectorsize - 1) / sectorsize;
5334 - blocks = (blocks + sizeof(long) * 8 - 1) / (sizeof(long) * 8);
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);
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);
5353 + err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
5354 + bitmap_offset_out, bitmap_len_out,
5358 + os_close_file(fd);
5363 +/* XXX Just trivial wrappers around os_read_file and os_write_file */
5364 int read_ubd_fs(int fd, void *buffer, int len)
5368 - n = read(fd, buffer, len);
5369 - if(n < 0) return(-errno);
5371 + return(os_read_file(fd, buffer, len));
5374 int write_ubd_fs(int fd, char *buffer, int len)
5378 - n = write(fd, buffer, len);
5379 - if(n < 0) return(-errno);
5381 + return(os_write_file(fd, buffer, len));
5384 -int ubd_is_dir(char *file)
5385 +static int update_bitmap(struct io_thread_req *req)
5387 - struct stat64 buf;
5390 + if(req->cow_offset == -1)
5393 + n = os_seek_file(req->fds[1], req->cow_offset);
5395 + printk("do_io - bitmap lseek failed : err = %d\n", -n);
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,
5407 - if(stat64(file, &buf) < 0) return(0);
5408 - return(S_ISDIR(buf.st_mode));
5412 void do_io(struct io_thread_req *req)
5413 @@ -461,8 +234,18 @@
5416 int n, nsectors, start, end, bit;
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
5424 + n = *((volatile int *) req->buffer);
5425 + req->error = update_bitmap(req);
5429 nsectors = req->length / req->sectorsize;
5432 @@ -473,15 +256,14 @@
5433 &req->sector_mask) == bit))
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];
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);
5447 + printk("do_io - lseek failed : err = %d\n", -err);
5451 @@ -490,11 +272,10 @@
5455 - n = read(req->fds[bit], buf, len);
5456 + n = os_read_file(req->fds[bit], buf, len);
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]);
5466 @@ -502,11 +283,10 @@
5467 if (n < len) memset(&buf[n], 0, len - n);
5470 - n = write(req->fds[bit], buf, len);
5471 + n = os_write_file(req->fds[bit], buf, 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]);
5481 @@ -515,24 +295,7 @@
5483 } while(start < nsectors);
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",
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]);
5503 + req->error = update_bitmap(req);
5506 /* Changed in start_io_thread, which is serialized by being called only
5507 @@ -550,19 +313,23 @@
5509 signal(SIGWINCH, SIG_IGN);
5511 - n = read(kernel_fd, &req, sizeof(req));
5512 - if(n < 0) printk("io_thread - read returned %d, errno = %d\n",
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)){
5519 + printk("io_thread - read failed, fd = %d, "
5520 + "err = %d\n", kernel_fd, -n);
5522 + printk("io_thread - short read, fd = %d, "
5523 + "length = %d\n", kernel_fd, n);
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",
5534 + printk("io_thread - write failed, fd = %d, err = %d\n",
5539 @@ -571,10 +338,11 @@
5540 int pid, fds[2], err;
5542 err = os_pipe(fds, 1, 1);
5544 - printk("start_io_thread - os_pipe failed, errno = %d\n", -err);
5547 + printk("start_io_thread - os_pipe failed, err = %d\n", -err);
5554 @@ -582,32 +350,19 @@
5557 printk("start_io_thread - clone failed : errno = %d\n", errno);
5564 -int start_io_thread(unsigned long sp, int *fd_out)
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");
5576 - pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
5579 - printk("start_io_thread - clone failed : errno = %d\n", errno);
5585 + os_close_file(fds[0]);
5586 + os_close_file(fds[1]);
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
5604 #include <termios.h>
5609 struct xterm_chan *data;
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,
5618 "/usr/lib/uml/port-helper", "-uml-socket",
5621 - if(access(argv[4], X_OK))
5622 + if(os_access(argv[4], OS_ACC_X_OK) < 0)
5623 argv[4] = "port-helper";
5626 @@ -106,13 +106,13 @@
5627 printk("xterm_open : unlink failed, errno = %d\n", errno);
5631 + os_close_file(fd);
5633 - fd = create_unix_socket(file, sizeof(file));
5634 + fd = os_create_unix_socket(file, sizeof(file), 1);
5636 printk("xterm_open : create_unix_socket failed, errno = %d\n",
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);
5647 - if((err = os_set_fd_block(fd, 0)) != 0){
5648 + err = os_set_fd_block(fd, 0);
5650 printk("xterm_open : failed to set descriptor "
5651 - "non-blocking, errno = %d\n", err);
5652 + "non-blocking, err = %d\n", -err);
5655 new = xterm_fd(fd, &data->helper_pid);
5658 - printk("xterm_open : os_rcv_fd failed, errno = %d\n", -new);
5659 + printk("xterm_open : os_rcv_fd failed, err = %d\n", -new);
5664 if(data->helper_pid != -1)
5665 os_kill_process(data->helper_pid, 0);
5666 data->helper_pid = -1;
5668 + os_close_file(fd);
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
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"
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)
5695 struct xterm_wait *xterm = data;
5698 fd = os_rcv_fd(xterm->fd, &xterm->pid);
5705 + return(IRQ_HANDLED);
5708 int xterm_fd(int socket, int *pid_out)
5711 printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
5722 *pid_out = data->pid;
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
5732 . = START + SIZEOF_HEADERS;
5733 .interp : { *(.interp) }
5736 . = ALIGN(4096); /* Init code and data */
5739 - .text.init : { *(.text.init) }
5750 #include "asm/common.lds.S"
5752 - .data.init : { *(.data.init) }
5753 + init.data : { *(.init.data) }
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
5761 #ifndef __2_5_COMPAT_H__
5762 #define __2_5_COMPAT_H__
5764 -#include "linux/version.h"
5766 -#define INIT_CONSOLE(dev_name, write_proc, device_proc, setup_proc, f) { \
5767 - name : dev_name, \
5768 - write : write_proc, \
5770 - device : device_proc, \
5771 - setup : setup_proc, \
5778 #define INIT_HARDSECT(arr, maj, sizes)
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
5786 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
5787 + * Licensed under the GPL
5790 +#ifndef __IRQ_KERN_H__
5791 +#define __IRQ_KERN_H__
5793 +#include "linux/interrupt.h"
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,
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
5808 + * ---------------------------------------------------------------------------
5809 + * Local variables:
5810 + * c-file-style: "linux"
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
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);
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);
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);
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);
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
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"
5869 struct line_driver {
5871 + char *device_name;
5877 #define LINES_INIT(n) { num : n }
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
5891 +enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC };
5893 struct mconsole_command
5896 void (*handler)(struct mc_request *req);
5898 + enum mc_context context;
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);
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
5916 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
5917 + * Copyright (C) 2002, 2003 Jeff Dike (jdike@addtoit.com)
5918 * Licensed under the GPL
5924 -struct vm_reserved {
5925 - struct list_head list;
5926 - unsigned long start;
5927 - unsigned long end;
5929 +#include "linux/types.h"
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);
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
5945 + * Copyright (C) 2003 Jeff Dike (jdike@addtoit.com)
5946 + * Licensed under the GPL
5949 +#ifndef __MEM_KERN_H__
5950 +#define __MEM_KERN_H__
5952 +#include "linux/list.h"
5953 +#include "linux/types.h"
5956 + struct list_head list;
5957 + int (*proc)(int, unsigned long, int, __u64);
5960 +extern void register_remapper(struct remapper *info);
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
5969 + * ---------------------------------------------------------------------------
5970 + * Local variables:
5971 + * c-file-style: "linux"
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
5981 -struct mem_region {
5982 +struct iomem_region {
5983 + struct iomem_region *next;
5985 - unsigned long start_pfn;
5986 - unsigned long start;
5987 - unsigned long len;
5991 + unsigned long phys;
5992 + unsigned long virt;
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;
6000 #define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
6002 extern unsigned long host_task_size;
6003 extern unsigned long task_size;
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
6038 #define OS_TYPE_FIFO 6
6039 #define OS_TYPE_SOCK 7
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 */
6049 + * types taken from stat_file() in hostfs_user.c
6050 + * (if they are wrong here, they are wrong there...).
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 */
6070 @@ -91,22 +117,40 @@
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);
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);
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);
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);
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
6132 #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
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)
6139 #define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
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
6148 -enum ubd_req { UBD_READ, UBD_WRITE };
6149 +enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
6151 struct io_thread_req {
6156 unsigned long sector_mask;
6157 - unsigned long cow_offset;
6158 + unsigned long long cow_offset;
6159 unsigned long bitmap_words[2];
6161 + unsigned long long map_offset;
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);
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);
6180 static inline int ubd_test_bit(__u64 bit, unsigned char *data)
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
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.
6196 + * Copies a NUL-terminated string from userspace to kernel space.
6198 + * On success, returns the length of the string (not including the trailing
6201 + * If access to userspace fails, returns -EFAULT (some data may have been
6204 + * If @count is smaller than the length of the string, copies @count bytes
6205 + * and returns @count.
6208 static inline int strncpy_from_user(char *dst, const char *src, int count)
6210 return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas,
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.
6219 + * Zero a block of memory in user space. Caller must check
6220 + * the specified block with access_ok() before calling this function.
6222 + * Returns number of bytes that could not be cleared.
6223 + * On success, this will be zero.
6225 static inline int __clear_user(void *mem, int len)
6227 return(CHOOSE_MODE_PROC(__clear_user_tt, __clear_user_skas, mem, len));
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.
6235 + * Zero a block of memory in user space.
6237 + * Returns number of bytes that could not be cleared.
6238 + * On success, this will be zero.
6240 static inline int clear_user(void *mem, int len)
6242 return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len));
6246 + * strlen_user: - Get the size of a string in user space.
6247 + * @str: The string to measure.
6248 + * @n: The maximum valid length
6250 + * Get the size of a NUL-terminated string in user space.
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.
6256 static inline int strnlen_user(const void *str, int len)
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
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);
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
6274 extern int unlockpt(int __fd);
6275 extern char *ptsname(int __fd);
6277 -enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
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);
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);
6300 +extern void arch_init_thread(void);
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
6311 bool "Networking support"
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.
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>.
6327 source "fs/Kconfig.binfmt"
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.
6334 + tristate "HoneyPot ProcFS"
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.
6342 + See http://user-mode-linux.sf.net/hppfs.html for more information.
6344 + You only need this if you are setting up a UML honeypot. Otherwise,
6345 + it is safe to say 'N' here.
6348 bool "Management console"
6349 @@ -105,6 +132,16 @@
6351 bool "Magic SysRq key"
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.
6365 bool "2G/2G host address space split"
6368 bool "Highmem support"
6371 + bool "/proc/mm support"
6373 config KERNEL_STACK_ORDER
6374 int "Kernel stack size order"
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.
6380 +config UML_REAL_TIME_CLOCK
6381 + bool "Real-time Clock"
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.
6393 source "init/Kconfig"
6394 @@ -239,6 +290,10 @@
6396 bool "Enable ptrace proxy"
6397 depends on XTERM_CHAN && DEBUG_INFO
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.
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
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.
6412 +# Turn this back on when the driver actually works
6414 +#config BLK_DEV_COW
6415 +# tristate "COW block device"
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.
6422 +config BLK_DEV_COW_COMMON
6424 + default BLK_DEV_COW || BLK_DEV_UBD
6427 tristate "Loopback device support"
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
6434 -menu "Network Devices"
6435 +menu "UML Network Devices"
6438 # UML virtual driver
6439 @@ -176,73 +176,5 @@
6441 Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
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
6450 - tristate "Dummy net driver support"
6453 - tristate "Bonding driver support"
6456 - tristate "EQL (serial line load balancing) support"
6459 - tristate "Universal TUN/TAP device driver support"
6462 - tristate "Ethertap network tap (OBSOLETE)"
6463 - depends on EXPERIMENTAL && NETLINK
6466 - tristate "PPP (point-to-point protocol) support"
6468 -config PPP_MULTILINK
6469 - bool "PPP multilink support (EXPERIMENTAL)"
6470 - depends on PPP && EXPERIMENTAL
6473 - bool "PPP filtering"
6474 - depends on PPP && FILTER
6477 - tristate "PPP support for async serial ports"
6480 -config PPP_SYNC_TTY
6481 - tristate "PPP support for sync tty ports"
6485 - tristate "PPP Deflate compression"
6489 - tristate "PPP BSD-Compress compression"
6493 - tristate "PPP over Ethernet (EXPERIMENTAL)"
6494 - depends on PPP && EXPERIMENTAL
6497 - tristate "SLIP (serial line) support"
6499 -config SLIP_COMPRESSED
6500 - bool "CSLIP compressed headers"
6504 - bool "Keepalive and linefill"
6507 -config SLIP_MODE_SLIP6
6508 - bool "Six bit SLIP encapsulation"
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
6520 -static __initdata char *config = "
6523 +static __initdata char *config = "CONFIG";
6525 static int __init print_config(char *line, int *add)
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
6531 CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
6534 +extern void log_exec(char **argv, void *tty);
6536 static int execve1(char *file, char **argv, char **env)
6540 +#ifdef CONFIG_TTY_LOG
6541 + log_exec(argv, current->tty);
6543 error = do_execve(file, argv, env, ¤t->thread.regs);
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
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;
6556 stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
6557 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
6561 top = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
6562 - sig_top = (unsigned long) sigstack + PAGE_SIZE;
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
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"
6581 +extern int userspace_pid[];
6583 static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from,
6584 struct arch_frame_data *arch)
6586 return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
6588 - copy_sc_to_user_skas(to, fp, &from->regs,
6589 + copy_sc_to_user_skas(userspace_pid[0], to, fp,
6591 current->thread.cr2,
6592 current->thread.err)));
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
6603 #include <sys/signal.h>
6604 #include <sys/wait.h>
6607 struct helper_data *data = arg;
6608 char **argv = data->argv;
6612 signal(SIGHUP, helper_hup);
6614 if(data->pre_exec != NULL)
6615 (*data->pre_exec)(data->pre_data);
6616 execvp(argv[0], argv);
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);
6625 if((stack_out != NULL) && (*stack_out != 0))
6627 else stack = alloc_stack(0, um_in_interrupt());
6628 - if(stack == 0) return(-ENOMEM);
6632 err = os_pipe(fds, 1, 0);
6634 - printk("run_helper : pipe failed, errno = %d\n", -err);
6637 + printk("run_helper : pipe failed, err = %d\n", -err);
6640 - if(fcntl(fds[1], F_SETFD, 1) != 0){
6641 - printk("run_helper : setting FD_CLOEXEC failed, errno = %d\n",
6645 + err = os_set_exec_close(fds[1], 1);
6647 + printk("run_helper : setting FD_CLOEXEC failed, err = %d\n",
6652 sp = stack + page_size() - sizeof(void *);
6654 pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
6656 printk("run_helper : clone failed, errno = %d\n", errno);
6662 - n = read(fds[0], &err, sizeof(err));
6664 + os_close_file(fds[1]);
6665 + n = os_read_file(fds[0], &err, sizeof(err));
6667 - printk("run_helper : read on pipe failed, errno = %d\n",
6670 + printk("run_helper : read on pipe failed, err = %d\n", -n);
6675 waitpid(pid, NULL, 0);
6680 if(stack_out == NULL) free_stack(stack, 0);
6681 else *stack_out = stack;
6685 + os_kill_process(pid, 1);
6687 + os_close_file(fds[0]);
6688 + os_close_file(fds[1]);
6690 + free_stack(stack, 0);
6694 int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
6695 @@ -117,9 +132,11 @@
6697 if(stack_out == NULL){
6698 pid = waitpid(pid, &status, 0);
6701 printk("run_helper_thread - wait failed, errno = %d\n",
6706 if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
6707 printk("run_helper_thread - thread returned 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
6714 #include <sys/types.h>
6715 #include <sys/stat.h>
6719 #include "user_util.h"
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);
6728 + printk("Opening '%s' failed - err = %d\n", filename, -fd);
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);
6736 + printk("Read of %d bytes from '%s' failed, err = %d\n", size,
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
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"
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);
6757 +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
6758 EXPORT_SYMBOL(init_mm);
6762 __attribute__((__section__(".data.init_task"))) =
6763 { INIT_THREAD_INFO(init_task) };
6765 -struct task_struct *alloc_task_struct(void)
6767 - return((struct task_struct *)
6768 - __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
6771 void unprotect_stack(unsigned long stack)
6773 protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE,
6777 -void free_task_struct(struct task_struct *task)
6779 - /* free_pages decrements the page counter and only actually frees
6780 - * the pages if they are now not accessed by anything.
6782 - free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
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
6792 #include "user_util.h"
6793 #include "kern_util.h"
6794 #include "irq_user.h"
6795 +#include "irq_kern.h"
6797 static void register_irq_proc (unsigned int irq);
6804 -volatile unsigned long irq_err_count;
6807 * Generic, controller-independent functions:
6810 -int get_irq_list(char *buf)
6811 +int show_interrupts(struct seq_file *p, void *v)
6814 - unsigned long flags;
6815 struct irqaction * action;
6817 + unsigned long flags;
6819 - p += sprintf(p, " ");
6820 - for (j=0; j<num_online_cpus(); j++)
6821 - p += sprintf(p, "CPU%d ",j);
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');
6829 for (i = 0 ; i < NR_IRQS ; i++) {
6830 spin_lock_irqsave(&irq_desc[i].lock, flags);
6831 action = irq_desc[i].action;
6834 - p += sprintf(p, "%3d: ",i);
6836 + seq_printf(p, "%3d: ",i);
6838 - p += sprintf(p, "%10u ", kstat_irqs(i));
6839 + seq_printf(p, "%10u ", kstat_irqs(i));
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]);
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);
6853 for (action=action->next; action; action = action->next)
6854 - p += sprintf(p, ", %s", action->name);
6857 + seq_printf(p, ", %s", action->name);
6859 + seq_putc(p, '\n');
6861 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
6863 - p += sprintf(p, "\n");
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");
6873 - p += sprintf(p, "ERR: %10lu\n", irq_err_count);
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');
6883 -int show_interrupts(struct seq_file *p, void *v)
6890 @@ -230,8 +218,11 @@
6892 void disable_irq(unsigned int irq)
6894 + irq_desc_t *desc = irq_desc + irq;
6896 disable_irq_nosync(irq);
6897 - synchronize_irq(irq);
6899 + synchronize_irq(irq);
6904 spin_lock_irqsave(&desc->lock, flags);
6905 switch (desc->depth) {
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)
6916 - int cpu = smp_processor_id();
6917 irq_desc_t *desc = irq_desc + irq;
6918 struct irqaction * action;
6919 unsigned int status;
6922 - kstat_cpu(cpu).irqs[irq]++;
6923 + kstat_this_cpu.irqs[irq]++;
6924 spin_lock(&desc->lock);
6925 desc->handler->ack(irq);
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,
6936 @@ -433,15 +423,19 @@
6937 EXPORT_SYMBOL(request_irq);
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,
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);
6956 + err = activate_fd(irq, fd, type, dev_id);
6960 /* this was setup_x86_irq but it seems pretty generic */
6963 spin_lock_irqsave(&desc->lock,flags);
6965 - if ((old = *p) != NULL) {
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);
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.
6981 for (i = 0; i < count; i++) {
6982 @@ -625,12 +620,14 @@
6983 unsigned long count, void *data)
6985 int irq = (long) data, full_count = count, err;
6986 - cpumask_t new_value, tmp;
6987 + cpumask_t new_value;
6989 if (!irq_desc[irq].handler->set_affinity)
6992 err = parse_hex_value(buffer, count, &new_value);
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));
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
7017 #include <sys/poll.h>
7020 if(smp_sigio_handler()) return;
7022 - if((n = poll(pollfds, pollfds_num, 0)) < 0){
7023 + n = poll(pollfds, pollfds_num, 0);
7025 if(errno == EINTR) continue;
7026 printk("sigio_handler : poll returned %d, "
7027 "errno = %d\n", n, errno);
7028 @@ -366,34 +366,31 @@
7030 void forward_ipi(int fd, int pid)
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);
7042 + err = os_set_owner(fd, pid);
7044 + printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
7045 + "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
7048 void forward_interrupts(int pid)
7051 unsigned long flags;
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
7062 - printk("Failed to forward %d to pid %d, "
7063 - "errno = %d\n", irq->fd, pid,
7066 + err = os_set_owner(irq->fd, pid);
7068 + /* XXX Just remove the irq rather than
7069 + * print out an infinite stream of these
7071 + printk("Failed to forward %d to pid %d, err = %d\n",
7072 + irq->fd, pid, -err);
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
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
7089 EXPORT_SYMBOL(flush_tlb_range);
7090 EXPORT_SYMBOL(host_task_size);
7091 EXPORT_SYMBOL(arch_validate);
7092 +EXPORT_SYMBOL(get_kmem_end);
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);
7109 +#ifdef CONFIG_MODE_TT
7110 +EXPORT_SYMBOL(copy_from_user_tt);
7111 +EXPORT_SYMBOL(copy_to_user_tt);
7114 +#ifdef CONFIG_MODE_SKAS
7115 +EXPORT_SYMBOL(copy_to_user_skas);
7116 +EXPORT_SYMBOL(copy_from_user_skas);
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);
7149 +EXPORT_SYMBOL(do_gettimeofday);
7150 +EXPORT_SYMBOL(do_settimeofday);
7152 /* This is here because UML expands open to sys_open, not to a system
7156 EXPORT_SYMBOL(kmap_atomic_to_page);
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
7164 + * ---------------------------------------------------------------------------
7165 + * Local variables:
7166 + * c-file-style: "linux"
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
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
7187 obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
7188 obj-$(CONFIG_GPROF) += gprof_syms.o
7190 obj-$(CONFIG_MODE_TT) += tt/
7191 obj-$(CONFIG_MODE_SKAS) += skas/
7193 +clean-files := config.c
7195 user-objs-$(CONFIG_TTY_LOG) += tty_log.o
7197 USER_OBJS := $(filter %_user.o,$(obj-y)) $(user-objs-y) config.o helper.o \
7199 $(obj)/frame.o: $(src)/frame.c
7200 $(CC) $(CFLAGS_$(notdir $@)) -c -o $@ $<
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 $$_ }'
7205 $(obj)/config.c : $(src)/config.c.in $(TOPDIR)/.config
7206 $(PERL) -e $(QUOTE) < $(src)/config.c.in > $@
7208 $(obj)/config.o : $(obj)/config.c
7212 - for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
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
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
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"
7255 -#include "mode_kern.h"
7256 +#include "mem_user.h"
7257 #include "uml_uaccess.h"
7260 +extern char __binary_start;
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;
7272 -const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n";
7274 -extern char __init_begin, __init_end;
7275 -extern long physmem_size;
7277 -/* Not changed by UML */
7278 -DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
7280 -/* Changed during early boot */
7281 +pgd_t swapper_pg_dir[1024];
7282 +unsigned long highmem;
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)
7289 -/* Changed during early boot */
7290 static unsigned long brk_end;
7291 +static unsigned long totalram_pages = 0;
7293 +void unmap_physmem(void)
7295 + os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
7298 static void map_cb(void *unused)
7300 map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0);
7303 -void unmap_physmem(void)
7304 +#ifdef CONFIG_HIGHMEM
7305 +static void setup_highmem(unsigned long highmem_start,
7306 + unsigned long highmem_len)
7308 - os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
7310 + struct page *page;
7311 + unsigned long highmem_pfn;
7314 -extern char __binary_start;
7315 + highmem_start_page = virt_to_page(highmem_start);
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);
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));
7341 -/* Changed during early boot */
7342 -static unsigned long kmem_top = 0;
7344 -unsigned long get_kmem_end(void)
7347 - kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
7351 -void set_kmem_end(unsigned long new)
7356 #ifdef CONFIG_HIGHMEM
7357 -/* Changed during early boot */
7359 -pgprot_t kmap_prot;
7361 -EXPORT_SYMBOL(kmap_prot);
7362 -EXPORT_SYMBOL(kmap_pte);
7364 -#define kmap_get_fixmap_pte(vaddr) \
7365 - pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
7367 -void __init kmap_init(void)
7369 - unsigned long kmap_vstart;
7371 - /* cache the first kmap pte */
7372 - kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
7373 - kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
7375 - kmap_prot = PAGE_KERNEL;
7376 + setup_highmem(end_iomem, highmem);
7379 -#endif /* CONFIG_HIGHMEM */
7381 static void __init fixrange_init(unsigned long start, unsigned long end,
7383 @@ -178,76 +136,24 @@
7387 -int init_maps(struct mem_region *region)
7389 - struct page *p, *map;
7392 - if(region == &physmem_region){
7393 - region->mem_map = mem_map;
7396 - else if(region->mem_map != NULL) return(0);
7398 - n = region->len >> PAGE_SHIFT;
7399 - len = n * sizeof(struct page);
7401 - map = kmalloc(len, GFP_KERNEL);
7402 - if(map == NULL) map = vmalloc(len);
7404 - else map = alloc_bootmem_low_pages(len);
7408 - for(i = 0; i < n; i++){
7410 - set_page_count(p, 0);
7411 - SetPageReserved(p);
7412 - INIT_LIST_HEAD(&p->list);
7414 - region->mem_map = map;
7419 +pgprot_t kmap_prot;
7421 -DECLARE_MUTEX(regions_sem);
7422 +#define kmap_get_fixmap_pte(vaddr) \
7423 + pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
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)
7432 - down(®ions_sem);
7433 - for(i = 0; i < NREGIONS; i++){
7434 - if(regions[i] == NULL) break;
7436 - if(i == NREGIONS){
7437 - printk("setup_range : no free regions\n");
7443 - fd = create_mem_file(len);
7444 + unsigned long kmap_vstart;
7446 - if(region == NULL){
7447 - region = alloc_bootmem_low_pages(sizeof(*region));
7448 - if(region == NULL)
7449 - panic("Failed to allocating mem_region");
7451 + /* cache the first kmap pte */
7452 + kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
7453 + kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
7455 - *region = ((struct mem_region) { .driver = driver,
7460 - regions[i] = region;
7464 + kmap_prot = PAGE_KERNEL;
7467 -#ifdef CONFIG_HIGHMEM
7468 static void init_highmem(void)
7471 @@ -268,63 +174,20 @@
7476 -void setup_highmem(unsigned long len)
7478 - struct mem_region *region;
7479 - struct page *page, *map;
7480 - unsigned long phys;
7481 - int i, cur, index;
7483 - phys = physmem_size;
7485 - cur = min(len, (unsigned long) REGION_SIZE);
7486 - i = setup_one_range(-1, NULL, -1, phys >> PAGE_SHIFT, cur,
7489 - printk("setup_highmem - setup_one_range failed\n");
7492 - region = regions[i];
7493 - index = phys / PAGE_SIZE;
7494 - region->mem_map = &mem_map[index];
7496 - map = region->mem_map;
7497 - for(i = 0; i < (cur >> PAGE_SHIFT); i++){
7499 - ClearPageReserved(page);
7500 - set_bit(PG_highmem, &page->flags);
7501 - atomic_set(&page->count, 1);
7502 - __free_page(page);
7509 +#endif /* CONFIG_HIGHMEM */
7511 void paging_init(void)
7513 - struct mem_region *region;
7514 - unsigned long zones_size[MAX_NR_ZONES], start, end, vaddr;
7516 + unsigned long zones_size[MAX_NR_ZONES], vaddr;
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++)
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);
7538 * Fixed mappings, only the page table structure has to be
7539 @@ -335,15 +198,33 @@
7541 #ifdef CONFIG_HIGHMEM
7543 - setup_highmem(highmem);
7547 -pte_t __bad_page(void)
7548 +struct page *arch_validate(struct page *page, int mask, int order)
7550 - clear_page(empty_bad_page);
7551 - return pte_mkdirty(mk_pte((struct page *) empty_bad_page,
7553 + unsigned long addr, zero = 0;
7557 + if(page == NULL) return(page);
7558 + if(PageHighMem(page)) return(page);
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,
7565 + ¤t->thread.fault_addr,
7566 + ¤t->thread.fault_catcher)){
7567 + if(!(mask & __GFP_WAIT)) return(NULL);
7570 + addr += PAGE_SIZE;
7572 + if(i == (1 << order)) return(page);
7573 + page = alloc_pages(mask, order);
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);
7582 -static int __init uml_mem_setup(char *line, int *add)
7585 - physmem_size = memparse(line,&retptr);
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"
7598 -struct page *arch_validate(struct page *page, int mask, int order)
7600 - unsigned long addr, zero = 0;
7604 - if(page == NULL) return(page);
7605 - if(PageHighMem(page)) return(page);
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,
7612 - ¤t->thread.fault_addr,
7613 - ¤t->thread.fault_catcher)){
7614 - if(!(mask & __GFP_WAIT)) return(NULL);
7617 - addr += PAGE_SIZE;
7619 - if(i == (1 << order)) return(page);
7620 - page = alloc_pages(mask, order);
7624 -DECLARE_MUTEX(vm_reserved_sem);
7625 -static struct list_head vm_reserved = LIST_HEAD_INIT(vm_reserved);
7627 -/* Static structures, linked in to the list in early boot */
7628 -static struct vm_reserved head = {
7629 - .list = LIST_HEAD_INIT(head.list),
7634 -static struct vm_reserved tail = {
7635 - .list = LIST_HEAD_INIT(tail.list),
7640 -void set_usable_vm(unsigned long start, unsigned long end)
7642 - list_add(&head.list, &vm_reserved);
7643 - list_add(&tail.list, &head.list);
7648 -int reserve_vm(unsigned long start, unsigned long end, void *e)
7651 - struct vm_reserved *entry = e, *reserved, *prev;
7652 - struct list_head *ele;
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;
7660 - panic("Reserved vm out of range");
7662 - prev = list_entry(ele->prev, struct vm_reserved, list);
7663 - if(prev->end > start)
7664 - panic("Can't reserve vm");
7666 - entry = kmalloc(sizeof(*entry), GFP_KERNEL);
7667 - if(entry == NULL){
7668 - printk("reserve_vm : Failed to allocate entry\n");
7672 - *entry = ((struct vm_reserved)
7673 - { .list = LIST_HEAD_INIT(entry->list),
7676 - list_add(&entry->list, &prev->list);
7679 - up(&vm_reserved_sem);
7683 -unsigned long get_vm(unsigned long len)
7685 - struct vm_reserved *this, *next;
7686 - struct list_head *ele;
7687 - unsigned long start;
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))
7698 - up(&vm_reserved_sem);
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);
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,
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)){
7725 - regions[i] = NULL;
7729 - if(pfn != -1) pfn += cur;
7737 - unsigned long size;
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.
7744 -struct iomem iomem_regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] =
7749 -int num_iomem_regions = 0;
7751 -void add_iomem(char *name, int fd, unsigned long size)
7753 - if(num_iomem_regions == sizeof(iomem_regions)/sizeof(iomem_regions[0]))
7755 - size = (size + PAGE_SIZE - 1) & PAGE_MASK;
7756 - iomem_regions[num_iomem_regions++] =
7757 - ((struct iomem) { .name = name,
7762 -int setup_iomem(void)
7764 - struct iomem *iomem;
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,
7775 -__initcall(setup_iomem);
7777 -#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
7778 -#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
7780 -/* Changed during early boot */
7781 -static struct mem_region physmem_region;
7782 -static struct vm_reserved physmem_reserved;
7784 -void setup_physmem(unsigned long start, unsigned long reserve_end,
7785 - unsigned long len)
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;
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 "
7801 - setup_range(-1, NULL, start, pfn, cur, 1, region, reserved);
7804 - unsigned long reserve = reserve_end - start;
7805 - int pfn = PFN_UP(__pa(reserve_end));
7806 - int delta = (len - reserve) >> PAGE_SHIFT;
7808 - bootmap_size = init_bootmem(pfn, pfn + delta);
7809 - free_bootmem(__pa(reserve_end) + bootmap_size,
7810 - cur - bootmap_size - reserve);
7814 - pfn += cur >> PAGE_SHIFT;
7821 -struct mem_region *phys_region(unsigned long phys)
7823 - unsigned int n = phys_region_index(phys);
7825 - if(regions[n] == NULL)
7826 - panic("Physical address in uninitialized region");
7827 - return(regions[n]);
7830 -unsigned long phys_offset(unsigned long phys)
7832 - return(phys_addr(phys));
7835 -struct page *phys_mem_map(unsigned long phys)
7837 - return((struct page *) phys_region(phys)->mem_map);
7840 -struct page *pte_mem_map(pte_t pte)
7842 - return(phys_mem_map(pte_val(pte)));
7845 -struct mem_region *page_region(struct page *page, int *index_out)
7848 - struct mem_region *region;
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;
7860 - panic("No region found for page");
7864 -unsigned long page_to_pfn(struct page *page)
7866 - struct mem_region *region = page_region(page, NULL);
7868 - return(region->start_pfn + (page - (struct page *) region->mem_map));
7871 -struct mem_region *pfn_to_region(unsigned long pfn, int *index_out)
7873 - struct mem_region *region;
7876 - for(i = 0; i < NREGIONS; i++){
7877 - region = regions[i];
7878 - if(region == NULL)
7881 - if((region->start_pfn <= pfn) &&
7882 - (region->start_pfn + (region->len >> PAGE_SHIFT) > pfn)){
7883 - if(index_out != NULL)
7891 -struct page *pfn_to_page(unsigned long pfn)
7893 - struct mem_region *region = pfn_to_region(pfn, NULL);
7894 - struct page *mem_map = (struct page *) region->mem_map;
7896 - return(&mem_map[pfn - region->start_pfn]);
7899 -unsigned long phys_to_pfn(unsigned long p)
7901 - struct mem_region *region = regions[phys_region_index(p)];
7903 - return(region->start_pfn + (phys_addr(p) >> PAGE_SHIFT));
7906 -unsigned long pfn_to_phys(unsigned long pfn)
7909 - struct mem_region *region = pfn_to_region(pfn, &n);
7911 - return(mk_phys((pfn - region->start_pfn) << PAGE_SHIFT, n));
7914 -struct page *page_mem_map(struct page *page)
7916 - return((struct page *) page_region(page, NULL)->mem_map);
7919 -extern unsigned long region_pa(void *virt)
7921 - struct mem_region *region;
7922 - unsigned long addr = (unsigned long) virt;
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));
7932 - panic("region_pa : no region for virtual address");
7936 -extern void *region_va(unsigned long phys)
7938 - return((void *) (phys_region(phys)->start + phys_addr(phys)));
7941 -unsigned long page_to_phys(struct page *page)
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));
7949 -struct page *phys_to_page(unsigned long phys)
7951 - struct page *mem_map;
7953 - mem_map = phys_mem_map(phys);
7954 - return(mem_map + (phys_offset(phys) >> PAGE_SHIFT));
7957 -static int setup_mem_maps(void)
7959 - struct mem_region *region;
7962 - for(i = 0; i < NREGIONS; i++){
7963 - region = regions[i];
7964 - if((region != NULL) && (region->fd > 0)) init_maps(region);
7969 -__initcall(setup_mem_maps);
7972 * Allocate and free page tables.
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
7984 -#include <sys/stat.h>
7986 #include <sys/types.h>
7987 #include <sys/mman.h>
7988 #include "kern_util.h"
7989 @@ -47,105 +46,145 @@
7992 #include "tempfile.h"
7993 +#include "kern_constants.h"
7995 extern struct mem_region physmem_region;
7997 #define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
7999 -int create_mem_file(unsigned long len)
8000 +static int create_tmp_file(unsigned long len)
8006 fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
8007 - if (fchmod(fd, 0777) < 0){
8010 + os_print_error(fd, "make_tempfile");
8014 + err = os_mode_fd(fd, 0777);
8016 + os_print_error(err, "os_mode_fd");
8019 - if(os_seek_file(fd, len) < 0){
8021 + err = os_seek_file(fd, len);
8023 + os_print_error(err, "os_seek_file");
8027 - if(write(fd, &zero, 1) != 1){
8029 + err = os_write_file(fd, &zero, 1);
8031 + os_print_error(err, "os_write_file");
8034 - if(fcntl(fd, F_SETFD, 1) != 0)
8035 - perror("Setting FD_CLOEXEC failed");
8040 -int setup_region(struct mem_region *region, void *entry)
8041 +static int have_devanon = 0;
8043 +void check_devanon(void)
8047 + printk("Checking for /dev/anon on the host...");
8048 + fd = open("/dev/anon", O_RDWR);
8050 + printk("Not available (open failed with errno %d)\n", errno);
8058 +static int create_anon_file(unsigned long len)
8060 - void *loc, *start;
8064 - if(region->start != -1){
8065 - err = reserve_vm(region->start,
8066 - region->start + region->len, entry);
8068 - printk("setup_region : failed to reserve "
8069 - "0x%x - 0x%x for driver '%s'\n",
8071 - region->start + region->len,
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);
8084 - if(region->start == uml_physmem){
8085 - start = (void *) uml_reserved;
8086 - offset = uml_reserved - uml_physmem;
8089 - start = (void *) region->start;
8093 - loc = mmap(start, region->len - offset, PROT_READ | PROT_WRITE,
8094 - MAP_SHARED | MAP_FIXED, region->fd, offset);
8096 - perror("Mapping memory");
8100 + fd = open("/dev/anon", O_RDWR);
8102 + os_print_error(fd, "opening /dev/anon");
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");
8112 + munmap(addr, len);
8117 +int create_mem_file(unsigned long len)
8122 + fd = create_anon_file(len);
8123 + else fd = create_tmp_file(len);
8125 + err = os_set_exec_close(fd, 1);
8127 + os_print_error(err, "exec_close");
8131 +struct iomem_region *iomem_regions = NULL;
8132 +int iomem_size = 0;
8134 static int __init parse_iomem(char *str, int *add)
8137 + struct iomem_region *new;
8138 + struct uml_stat buf;
8139 char *file, *driver;
8144 file = strchr(str,',');
8146 - printk("parse_iomem : failed to parse iomem\n");
8148 + printf("parse_iomem : failed to parse iomem\n");
8153 fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
8155 - printk("parse_iomem - Couldn't open io file, errno = %d\n",
8159 - if(fstat(fd, &buf) < 0) {
8160 - printk("parse_iomem - cannot fstat file, errno = %d\n", errno);
8162 + os_print_error(fd, "parse_iomem - Couldn't open io file");
8165 - add_iomem(driver, fd, buf.st_size);
8167 + err = os_stat_fd(fd, &buf);
8169 + os_print_error(err, "parse_iomem - cannot stat_fd file");
8173 + new = malloc(sizeof(*new));
8175 + perror("Couldn't allocate iomem_region struct");
8179 + *new = ((struct iomem_region) { .next = iomem_regions,
8182 + .size = buf.ust_size,
8185 + iomem_regions = new;
8186 + iomem_size += new->size + UM_KERN_PAGE_SIZE;
8190 + os_close_file(fd);
8195 __uml_setup("iomem=", parse_iomem,
8196 @@ -153,73 +192,20 @@
8197 " Configure <file> as an IO memory region named <name>.\n\n"
8202 -int logging_fd = -1;
8204 -int logging_line = 0;
8205 -char logging_buf[256];
8207 -void log(char *fmt, ...)
8210 - struct timeval tv;
8211 - struct openflags flags;
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);
8218 - gettimeofday(&tv, NULL);
8219 - sprintf(logging_buf, "%d\t %u.%u ", logging_line++, tv.tv_sec,
8221 - va_start(ap, fmt);
8222 - vsprintf(&logging_buf[strlen(logging_buf)], fmt, ap);
8224 - write(logging_fd, logging_buf, strlen(logging_buf));
8228 -int map_memory(unsigned long virt, unsigned long phys, unsigned long len,
8229 - int r, int w, int x)
8231 - struct mem_region *region = phys_region(phys);
8233 - return(os_map_memory((void *) virt, region->fd, phys_offset(phys), len,
8237 int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
8240 - if(os_protect_memory((void *) addr, len, r, w, x) < 0){
8243 + err = os_protect_memory((void *) addr, len, r, w, x);
8246 - panic("protect failed, errno = %d", errno);
8247 - else return(-errno);
8248 + panic("protect failed, err = %d", -err);
8254 -unsigned long find_iomem(char *driver, unsigned long *len_out)
8256 - struct mem_region *region;
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);
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
8281 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
8282 + * Licensed under the GPL
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"
8296 +#include "mem_user.h"
8301 +#define PHYS_HASHSIZE (8192)
8305 +DEF_HASH_STRUCTS(virtmem, PHYS_HASHSIZE, struct phys_desc);
8308 + struct virtmem_ptrs virt_ptrs;
8312 + unsigned long phys;
8315 +struct virtmem_table virtmem_hash;
8317 +static int virt_cmp(void *virt1, void *virt2)
8319 + return(virt1 != virt2);
8322 +static int virt_hash(void *virt)
8324 + unsigned long addr = ((unsigned long) virt) >> PAGE_SHIFT;
8325 + return(addr % PHYS_HASHSIZE);
8328 +DEF_HASH(static, virtmem, struct phys_desc, virt_ptrs, void *, virt, virt_cmp,
8331 +int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w)
8333 + struct phys_desc *desc;
8334 + unsigned long phys;
8337 + virt = (void *) ((unsigned long) virt & PAGE_MASK);
8338 + err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0);
8342 + phys = __pa(virt);
8343 + if(find_virtmem_hash(&virtmem_hash, virt) != NULL)
8344 + panic("Address 0x%p is already substituted\n", virt);
8347 + desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
8351 + *desc = ((struct phys_desc) { .virt_ptrs = { NULL, NULL },
8355 + .phys = __pa(virt) });
8356 + insert_virtmem_hash(&virtmem_hash, desc);
8362 +static int physmem_fd = -1;
8364 +int physmem_remove_mapping(void *virt)
8366 + struct phys_desc *desc;
8369 + virt = (void *) ((unsigned long) virt & PAGE_MASK);
8370 + desc = find_virtmem_hash(&virtmem_hash, virt);
8374 + remove_virtmem_hash(&virtmem_hash, desc);
8377 + err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0);
8379 + panic("Failed to unmap block device page from physical memory, "
8380 + "errno = %d", -err);
8384 +void arch_free_page(struct page *page, int order)
8389 + for(i = 0; i < 1 << order; i++){
8390 + virt = __va(page_to_phys(page + i));
8391 + physmem_remove_mapping(virt);
8395 +int is_remapped(void *virt)
8397 + return(find_virtmem_hash(&virtmem_hash, virt) != NULL);
8400 +/* Changed during early boot */
8401 +unsigned long high_physmem;
8403 +extern unsigned long physmem_size;
8405 +void *to_virt(unsigned long phys)
8407 + return((void *) uml_physmem + phys);
8410 +unsigned long to_phys(void *virt)
8412 + return(((unsigned long) virt) - uml_physmem);
8415 +int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem)
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;
8422 + phys_pages = physmem >> PAGE_SHIFT;
8423 + phys_len = phys_pages * sizeof(struct page);
8425 + iomem_pages = iomem >> PAGE_SHIFT;
8426 + iomem_len = iomem_pages * sizeof(struct page);
8428 + highmem_pages = highmem >> PAGE_SHIFT;
8429 + highmem_len = highmem_pages * sizeof(struct page);
8431 + total_pages = phys_pages + iomem_pages + highmem_pages;
8432 + total_len = phys_len + iomem_pages + highmem_len;
8435 + map = kmalloc(total_len, GFP_KERNEL);
8437 + map = vmalloc(total_len);
8439 + else map = alloc_bootmem_low_pages(total_len);
8444 + for(i = 0; i < total_pages; i++){
8446 + set_page_count(p, 0);
8447 + SetPageReserved(p);
8448 + INIT_LIST_HEAD(&p->list);
8452 + max_mapnr = total_pages;
8456 +struct page *phys_to_page(const unsigned long phys)
8458 + return(&mem_map[phys >> PAGE_SHIFT]);
8461 +struct page *__virt_to_page(const unsigned long virt)
8463 + return(&mem_map[__pa(virt) >> PAGE_SHIFT]);
8466 +unsigned long page_to_phys(struct page *page)
8468 + return((page - mem_map) << PAGE_SHIFT);
8471 +pte_t mk_pte(struct page *page, pgprot_t pgprot)
8475 + pte_val(pte) = page_to_phys(page) + pgprot_val(pgprot);
8476 + if(pte_present(pte)) pte_mknewprot(pte_mknewpage(pte));
8480 +/* Changed during early boot */
8481 +static unsigned long kmem_top = 0;
8483 +unsigned long get_kmem_end(void)
8486 + kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
8490 +void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
8491 + int r, int w, int x)
8496 + fd = phys_mapping(phys, &offset);
8497 + err = os_map_memory((void *) virt, fd, offset, len, r, w, x);
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);
8503 +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
8505 +void setup_physmem(unsigned long start, unsigned long reserve_end,
8506 + unsigned long len, unsigned long highmem)
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;
8513 + physmem_fd = create_mem_file(len + highmem);
8515 + offset = uml_reserved - uml_physmem;
8516 + err = os_map_memory((void *) uml_reserved, physmem_fd, offset,
8517 + len - offset, 1, 1, 0);
8519 + os_print_error(err, "Mapping memory");
8523 + bootmap_size = init_bootmem(pfn, pfn + delta);
8524 + free_bootmem(__pa(reserve_end) + bootmap_size,
8525 + len - bootmap_size - reserve);
8528 +int phys_mapping(unsigned long phys, __u64 *offset_out)
8530 + struct phys_desc *desc = find_virtmem_hash(&virtmem_hash,
8531 + __va(phys & PAGE_MASK));
8536 + *offset_out = desc->offset;
8538 + else if(phys < physmem_size){
8540 + *offset_out = phys;
8542 + else if(phys < __pa(end_iomem)){
8543 + struct iomem_region *region = iomem_regions;
8545 + while(region != NULL){
8546 + if((phys >= region->phys) &&
8547 + (phys < region->phys + region->size)){
8549 + *offset_out = phys - region->phys;
8552 + region = region->next;
8555 + else if(phys < __pa(end_iomem) + highmem){
8557 + *offset_out = phys - iomem_size;
8563 +static int __init uml_mem_setup(char *line, int *add)
8566 + physmem_size = memparse(line,&retptr);
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"
8579 +unsigned long find_iomem(char *driver, unsigned long *len_out)
8581 + struct iomem_region *region = iomem_regions;
8583 + while(region != NULL){
8584 + if(!strcmp(region->driver, driver)){
8585 + *len_out = region->size;
8586 + return(region->virt);
8593 +int setup_iomem(void)
8595 + struct iomem_region *region = iomem_regions;
8596 + unsigned long iomem_start = high_physmem + PAGE_SIZE;
8599 + while(region != NULL){
8600 + err = os_map_memory((void *) iomem_start, region->fd, 0,
8601 + region->size, 1, 1, 0);
8603 + printk("Mapping iomem region for driver '%s' failed, "
8604 + "errno = %d\n", region->driver, -err);
8606 + region->virt = iomem_start;
8607 + region->phys = __pa(region->virt);
8610 + iomem_start += region->size + PAGE_SIZE;
8611 + region = region->next;
8617 +__initcall(setup_iomem);
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
8624 + * ---------------------------------------------------------------------------
8625 + * Local variables:
8626 + * c-file-style: "linux"
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
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>
8647 int flags = altstack ? SA_ONSTACK : 0;
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.
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);
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);
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",
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);
8683 os_stop_process(os_getpid());
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");
8695 + n = sigsetjmp(buf, 1);
8700 stop_ptraced_child(pid, stack, 1);
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");
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
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"
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"
8729 struct task_struct *get_task(int pid, int require)
8731 - struct task_struct *task, *ret;
8732 + struct task_struct *ret;
8735 read_lock(&tasklist_lock);
8736 - for_each_process(task){
8737 - if(task->pid == pid){
8742 + ret = find_task_by_pid(pid);
8743 read_unlock(&tasklist_lock);
8745 if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
8749 int flags = GFP_KERNEL;
8751 if(atomic) flags |= GFP_ATOMIC;
8752 - if((page = __get_free_pages(flags, order)) == 0)
8753 + page = __get_free_pages(flags, order);
8756 stack_protections(page);
8758 @@ -103,13 +99,15 @@
8760 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
8762 - struct task_struct *p;
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");
8770 + pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, NULL, 0, NULL,
8773 + panic("do_fork failed in kernel_thread, errno = %d", pid);
8777 void switch_mm(struct mm_struct *prev, struct mm_struct *next,
8779 { external_pid(task), task });
8782 -void *switch_to(void *prev, void *next, void *last)
8783 +void *_switch_to(void *prev, void *next, void *last)
8785 return(CHOOSE_MODE(switch_to_tt(prev, next),
8786 switch_to_skas(prev, next)));
8788 void exit_thread(void)
8790 CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
8791 - unprotect_stack((unsigned long) current->thread_info);
8792 + unprotect_stack((unsigned long) current_thread);
8795 void *get_current(void)
8796 @@ -157,6 +155,10 @@
8800 +void prepare_to_copy(struct task_struct *tsk)
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)
8809 void default_idle(void)
8814 atomic_inc(&init_mm.mm_count);
8815 current->mm = &init_mm;
8816 @@ -367,10 +369,15 @@
8817 return(clear_user(buf, size));
8820 +int strlen_user_proc(char *str)
8822 + return(strlen_user(str));
8825 int smp_sigio_handler(void)
8828 - int cpu = current->thread_info->cpu;
8829 + int cpu = current_thread->cpu;
8837 - return(current->thread_info->cpu);
8838 + return(current_thread->cpu);
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 @@
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)
8851 - current->state = TASK_STOPPED;
8852 - notify_parent(current, SIGCHLD);
8854 + ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
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
8864 static void kill_idlers(int me)
8866 +#ifdef CONFIG_MODE_TT
8867 struct task_struct *p;
8871 if((p != NULL) && (p->thread.mode.tt.extern_pid != me))
8872 os_kill_process(p->thread.mode.tt.extern_pid, 0);
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
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"
8890 #include "irq_user.h"
8891 +#include "irq_kern.h"
8893 /* Protected by sigio_lock() called from write_sigio_workaround */
8894 static int sigio_irq_fd = -1;
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)
8899 read_sigio_fd(sigio_irq_fd);
8900 reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
8901 + return(IRQ_HANDLED);
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
8910 #include <termios.h>
8917 int pty_close_sigio = 0;
8919 /* Used as a flag during SIGIO testing early in boot */
8920 -static int got_sigio = 0;
8921 +static volatile int got_sigio = 0;
8923 void __init handler(int sig)
8928 if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
8929 - info->err = errno;
8930 + info->err = -errno;
8933 void __init check_one_sigio(void (*proc)(int, int))
8935 struct sigaction old, new;
8937 struct openpty_arg pty = { .master = -1, .slave = -1 };
8938 - int master, slave, flags;
8939 + int master, slave, err;
8941 initial_thread_cb(openpty_cb, &pty);
8943 - printk("openpty failed, errno = %d\n", pty.err);
8944 + printk("openpty failed, errno = %d\n", -pty.err);
8952 + /* XXX These can fail with EINTR */
8953 if(tcgetattr(master, &tt) < 0)
8954 panic("check_sigio : tcgetattr failed, errno = %d\n", errno);
8956 if(tcsetattr(master, TCSADRAIN, &tt) < 0)
8957 panic("check_sigio : tcsetattr failed, errno = %d\n", errno);
8959 - if((flags = fcntl(master, F_GETFL)) < 0)
8960 - panic("tty_fds : fcntl F_GETFL failed, errno = %d\n", errno);
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);
8967 - if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
8968 - panic("check_sigio : fcntl F_SETFL failed, errno = %d\n",
8970 + err = os_sigio_async(master, slave);
8972 + panic("tty_fds : sigio_async failed, err = %d\n", -err);
8974 if(sigaction(SIGIO, NULL, &old) < 0)
8975 panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
8978 (*proc)(master, slave);
8982 + os_close_file(master);
8983 + os_close_file(slave);
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...");
8990 memset(buf, 0, sizeof(buf));
8991 - while(write(master, buf, sizeof(buf)) > 0) ;
8993 + while(os_write_file(master, buf, sizeof(buf)) > 0) ;
8995 panic("check_sigio : write failed, errno = %d\n", errno);
8997 - while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
8998 + while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
9002 pty_output_sigio = 1;
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);
9010 static void tty_close(int master, int slave)
9012 printk("Checking that host ptys support SIGIO on close...");
9015 + os_close_file(slave);
9018 pty_close_sigio = 1;
9021 void __init check_sigio(void)
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 "
9029 @@ -201,11 +194,10 @@
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));
9036 printk("write_sigio_thread : "
9037 - "read failed, errno = %d\n",
9039 + "read failed, err = %d\n", -n);
9041 current_poll = next_poll;
9043 @@ -218,10 +210,10 @@
9044 (fds->used - i) * sizeof(*fds->poll));
9047 - n = write(respond_fd, &c, sizeof(c));
9048 + n = os_write_file(respond_fd, &c, sizeof(c));
9050 printk("write_sigio_thread : write failed, "
9051 - "errno = %d\n", errno);
9052 + "err = %d\n", -n);
9056 @@ -252,15 +244,15 @@
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));
9063 - printk("update_thread : write failed, errno = %d\n", errno);
9064 + printk("update_thread : write failed, err = %d\n", -n);
9068 - n = read(sigio_private[0], &c, sizeof(c));
9069 + n = os_read_file(sigio_private[0], &c, sizeof(c));
9071 - printk("update_thread : read failed, errno = %d\n", errno);
9072 + printk("update_thread : read failed, err = %d\n", -n);
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]);
9091 @@ -369,15 +361,15 @@
9094 err = os_pipe(write_sigio_fds, 1, 1);
9097 printk("write_sigio_workaround - os_pipe 1 failed, "
9098 - "errno = %d\n", -err);
9099 + "err = %d\n", -err);
9102 err = os_pipe(sigio_private, 1, 1);
9105 printk("write_sigio_workaround - os_pipe 2 failed, "
9106 - "errno = %d\n", -err);
9107 + "err = %d\n", -err);
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;
9115 - close(sigio_private[0]);
9116 - close(sigio_private[1]);
9117 + os_close_file(sigio_private[0]);
9118 + os_close_file(sigio_private[1]);
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]);
9127 @@ -412,10 +404,16 @@
9131 - n = read(fd, &c, sizeof(c));
9132 + n = os_read_file(fd, &c, sizeof(c));
9134 - printk("read_sigio_fd - read failed, errno = %d\n", errno);
9137 + printk("read_sigio_fd - read failed, err = %d\n", -n);
9141 + printk("read_sigio_fd - short read, bytes = %d\n", n);
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
9152 struct k_sigaction *ka;
9154 - ka = ¤t->sig->action[SIGSEGV - 1];
9155 + ka = ¤t->sighand->action[SIGSEGV - 1];
9156 ka->sa.sa_handler = SIG_DFL;
9158 force_sig(SIGSEGV, current);
9163 + /* Always make any pending restarted system calls return -EINTR */
9164 + current_thread_info()->restart_block.fn = do_no_restart_syscall;
9166 case -ERESTART_RESTARTBLOCK:
9167 - current_thread_info()->restart_block.fn =
9168 - do_no_restart_syscall;
9169 case -ERESTARTNOHAND:
9175 /* Whee! Actually deliver the signal. */
9176 - ka = ¤t->sig->action[sig -1 ];
9177 + ka = ¤t->sighand->action[sig -1 ];
9178 err = handle_signal(regs, sig, ka, &info, oldset, error);
9185 -int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
9186 +int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
9188 sigset_t saveset, newset;
9190 @@ -227,20 +227,59 @@
9194 +int sys_sigaction(int sig, const struct old_sigaction __user *act,
9195 + struct old_sigaction __user *oact)
9197 + struct k_sigaction new_ka, old_ka;
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))
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);
9211 + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
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))
9218 + __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
9219 + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
9225 +int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
9227 + return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs)));
9230 +extern int userspace_pid[];
9232 static int copy_sc_from_user(struct pt_regs *to, void *from,
9233 struct arch_frame_data *arch)
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));
9244 int sys_sigreturn(struct pt_regs regs)
9246 - void *sc = sp_to_sc(PT_REGS_SP(¤t->thread.regs));
9247 - void *mask = sp_to_mask(PT_REGS_SP(¤t->thread.regs));
9248 + void __user *sc = sp_to_sc(PT_REGS_SP(¤t->thread.regs));
9249 + void __user *mask = sp_to_mask(PT_REGS_SP(¤t->thread.regs));
9250 int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
9252 spin_lock_irq(¤t->sighand->siglock);
9255 int sys_rt_sigreturn(struct pt_regs regs)
9257 - struct ucontext *uc = sp_to_uc(PT_REGS_SP(¤t->thread.regs));
9259 + unsigned long sp = PT_REGS_SP(¤t->thread.regs);
9260 + struct ucontext __user *uc = sp_to_uc(sp);
9261 int sig_size = _NSIG_WORDS * sizeof(unsigned long);
9263 spin_lock_irq(¤t->sighand->siglock);
9265 sigdelsetmask(¤t->blocked, ~_BLOCKABLE);
9266 recalc_sigpending();
9267 spin_unlock_irq(¤t->sighand->siglock);
9268 - fp = (void *) (((unsigned long) uc) + sizeof(struct ucontext));
9269 copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext,
9270 &signal_frame_si.common.arch);
9271 return(PT_REGS_SYSCALL_RET(¤t->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
9276 extern int have_fpx_regs;
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,
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);
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
9299 #include "sysdep/ptrace.h"
9301 -extern int userspace_pid;
9302 +extern int userspace_pid[];
9304 extern void switch_threads(void *me, void *next);
9305 extern void thread_wait(void *sw, void *fb);
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);
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
9319 #ifndef __SKAS_UACCESS_H
9320 #define __SKAS_UACCESS_H
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"
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)))
9338 static inline int verify_area_skas(int type, const void * addr,
9340 @@ -27,197 +17,12 @@
9341 return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
9344 -static inline unsigned long maybe_map(unsigned long virt, int is_write)
9348 - void *phys = um_virt_to_phys(current, virt, &pte);
9351 - if(IS_ERR(phys) || (is_write && !pte_write(pte))){
9352 - if(handle_page_fault(virt, 0, is_write, 0, &dummy_code))
9354 - phys = um_virt_to_phys(current, virt, NULL);
9356 - return((unsigned long) __va((unsigned long) phys));
9359 -static inline int buffer_op(unsigned long addr, int len,
9360 - int (*op)(unsigned long addr, int len, void *arg),
9363 - int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
9364 - int remain = len, n;
9366 - n = (*op)(addr, size, arg);
9368 - return(n < 0 ? remain : 0);
9375 - while(addr < ((addr + remain) & PAGE_MASK)){
9376 - n = (*op)(addr, PAGE_SIZE, arg);
9378 - return(n < 0 ? remain : 0);
9380 - addr += PAGE_SIZE;
9381 - remain -= PAGE_SIZE;
9386 - n = (*op)(addr, remain, arg);
9388 - return(n < 0 ? remain : 0);
9392 -static inline int copy_chunk_from_user(unsigned long from, int len, void *arg)
9394 - unsigned long *to_ptr = arg, to = *to_ptr;
9396 - from = maybe_map(from, 0);
9400 - memcpy((void *) to, (void *) from, len);
9405 -static inline int copy_from_user_skas(void *to, const void *from, int n)
9407 - if(segment_eq(get_fs(), KERNEL_DS)){
9408 - memcpy(to, from, n);
9412 - return(access_ok_skas(VERIFY_READ, from, n) ?
9413 - buffer_op((unsigned long) from, n, copy_chunk_from_user, &to) :
9417 -static inline int copy_chunk_to_user(unsigned long to, int len, void *arg)
9419 - unsigned long *from_ptr = arg, from = *from_ptr;
9421 - to = maybe_map(to, 1);
9425 - memcpy((void *) to, (void *) from, len);
9430 -static inline int copy_to_user_skas(void *to, const void *from, int n)
9432 - if(segment_eq(get_fs(), KERNEL_DS)){
9433 - memcpy(to, from, n);
9437 - return(access_ok_skas(VERIFY_WRITE, to, n) ?
9438 - buffer_op((unsigned long) to, n, copy_chunk_to_user, &from) :
9442 -static inline int strncpy_chunk_from_user(unsigned long from, int len,
9445 - char **to_ptr = arg, *to = *to_ptr;
9448 - from = maybe_map(from, 0);
9452 - strncpy(to, (void *) from, len);
9453 - n = strnlen(to, len);
9461 -static inline int strncpy_from_user_skas(char *dst, const char *src, int count)
9466 - if(segment_eq(get_fs(), KERNEL_DS)){
9467 - strncpy(dst, src, count);
9468 - return(strnlen(dst, count));
9471 - if(!access_ok_skas(VERIFY_READ, src, 1))
9474 - n = buffer_op((unsigned long) src, count, strncpy_chunk_from_user,
9478 - return(strnlen(dst, count));
9481 -static inline int clear_chunk(unsigned long addr, int len, void *unused)
9483 - addr = maybe_map(addr, 1);
9487 - memset((void *) addr, 0, len);
9491 -static inline int __clear_user_skas(void *mem, int len)
9493 - return(buffer_op((unsigned long) mem, len, clear_chunk, NULL));
9496 -static inline int clear_user_skas(void *mem, int len)
9498 - if(segment_eq(get_fs(), KERNEL_DS)){
9499 - memset(mem, 0, len);
9503 - return(access_ok_skas(VERIFY_WRITE, mem, len) ?
9504 - buffer_op((unsigned long) mem, len, clear_chunk, NULL) : len);
9507 -static inline int strnlen_chunk(unsigned long str, int len, void *arg)
9509 - int *len_ptr = arg, n;
9511 - str = maybe_map(str, 0);
9515 - n = strnlen((void *) str, len);
9523 -static inline int strnlen_user_skas(const void *str, int len)
9527 - if(segment_eq(get_fs(), KERNEL_DS))
9528 - return(strnlen(str, len) + 1);
9530 - n = buffer_op((unsigned long) str, len, strnlen_chunk, &count);
9532 - return(count + 1);
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);
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
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 \
9552 + uaccess.o sys-$(SUBARCH)/
9554 +host-progs := util/mk_ptregs
9555 +clean-files := include/skas_ptregs.h
9557 USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
9558 USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
9560 -include/skas_ptregs.h : util/mk_ptregs
9561 - util/mk_ptregs > $@
9565 +$(TOPDIR)/arch/um/include/skas_ptregs.h : $(src)/util/mk_ptregs
9566 + @echo -n ' Generating $@'
9568 + @if [ -r $@ ] && cmp -s $@ $@.tmp; then \
9569 + echo ' (unchanged)'; \
9572 + echo ' (updated)'; \
9573 + mv -f $@.tmp $@; \
9576 $(USER_OBJS) : %.o: %.c
9577 $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
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
9586 #include <sys/mman.h>
9587 #include <sys/ptrace.h>
9588 #include "mem_user.h"
9592 #include "proc_mm.h"
9594 int r, int w, int x)
9596 struct proc_mm_op map;
9597 - struct mem_region *region;
9600 + int prot, n, phys_fd;
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);
9607 map = ((struct proc_mm_op) { .op = MM_MMAP,
9611 .flags = MAP_SHARED |
9614 - .offset = phys_offset(phys)
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);
9624 int unmap(int fd, void *addr, int len)
9626 { .addr = (unsigned long) addr,
9628 n = os_write_file(fd, &unmap, sizeof(unmap));
9629 - if((n != 0) && (n != sizeof(unmap)))
9631 + if(n != sizeof(unmap)) {
9642 .prot = prot } } } );
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);
9650 - panic("protect failed, errno = %d", errno);
9652 + panic("protect failed, err = %d", -n);
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
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);
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
9685 +#include <unistd.h>
9691 #include "proc_mm.h"
9692 #include "skas_ptrace.h"
9693 +#include "chan_user.h"
9695 +int is_skas_winch(int pid, int fd, void *data)
9697 + if(pid != getpid())
9700 + register_winch_irq(-1, fd, -1, data);
9704 +/* These are set once at boot time and not changed thereafter */
9706 unsigned long exec_regs[FRAME_SIZE];
9707 unsigned long exec_fp_regs[HOST_FP_SIZE];
9709 int err, syscall_nr, status;
9711 syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
9712 + UPT_SYSCALL_NR(regs) = syscall_nr;
9714 relay_signal(SIGTRAP, regs);
9717 - UPT_SYSCALL_NR(regs) = syscall_nr;
9719 err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
9722 handle_syscall(regs);
9727 static int userspace_tramp(void *arg)
9729 init_new_thread_signals(0);
9734 -void start_userspace(void)
9735 +/* Each element set once, and only accessed by a single processor anyway */
9737 +int userspace_pid[NR_CPUS];
9739 +void start_userspace(int cpu)
9743 @@ -114,21 +129,21 @@
9744 if(munmap(stack, PAGE_SIZE) < 0)
9745 panic("start_userspace : munmap failed, errno = %d\n", errno);
9747 - userspace_pid = pid;
9748 + userspace_pid[cpu] = pid;
9751 void userspace(union uml_pt_regs *regs)
9753 - int err, status, op;
9754 + int err, status, op, pid = userspace_pid[0];
9756 restore_registers(regs);
9758 - err = ptrace(PTRACE_SYSCALL, userspace_pid, 0, 0);
9759 + err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
9761 panic("userspace - PTRACE_SYSCALL failed, errno = %d\n",
9764 - err = waitpid(userspace_pid, &status, WUNTRACED);
9765 + err = waitpid(pid, &status, WUNTRACED);
9767 panic("userspace - waitpid failed, errno = %d\n",
9769 @@ -139,16 +154,17 @@
9770 if(WIFSTOPPED(status)){
9771 switch(WSTOPSIG(status)){
9773 - handle_segv(userspace_pid);
9777 - handle_trap(userspace_pid, regs);
9778 + handle_trap(pid, regs);
9786 user_signal(WSTOPSIG(status), regs);
9791 op = singlestepping_skas() ? PTRACE_SINGLESTEP :
9793 - err = ptrace(op, userspace_pid, 0, 0);
9794 + err = ptrace(op, pid, 0, 0);
9796 panic("userspace - PTRACE_SYSCALL failed, "
9797 "errno = %d\n", errno);
9799 *switch_buf_ptr = &switch_buf;
9800 *fork_buf_ptr = &fork_buf;
9802 - if(setjmp(fork_buf) == 0)
9803 + if(sigsetjmp(fork_buf, 1) == 0)
9804 new_thread_proc(stack, handler);
9807 @@ -189,16 +205,16 @@
9811 - if(setjmp(buf) == 0)
9812 - longjmp(*fork_buf, 1);
9813 + if(sigsetjmp(buf, 1) == 0)
9814 + siglongjmp(*fork_buf, 1);
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)
9822 - if(ptrace(int_op, userspace_pid, 0, regs->skas.regs) < 0)
9823 + if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
9825 - if(ptrace(fp_op, userspace_pid, 0, fp_regs) < 0)
9826 + if(ptrace(fp_op, pid, 0, fp_regs) < 0)
9830 @@ -217,10 +233,11 @@
9831 fp_regs = regs->skas.fp;
9834 - err = move_registers(PTRACE_GETREGS, fp_op, regs, fp_regs);
9835 + err = move_registers(userspace_pid[0], PTRACE_GETREGS, fp_op, regs,
9838 panic("save_registers - saving registers failed, errno = %d\n",
9843 void restore_registers(union uml_pt_regs *regs)
9844 @@ -237,10 +254,11 @@
9845 fp_regs = regs->skas.fp;
9848 - err = move_registers(PTRACE_SETREGS, fp_op, regs, fp_regs);
9849 + err = move_registers(userspace_pid[0], PTRACE_SETREGS, fp_op, regs,
9852 panic("restore_registers - saving registers failed, "
9853 - "errno = %d\n", err);
9854 + "errno = %d\n", -err);
9857 void switch_threads(void *me, void *next)
9859 jmp_buf my_buf, **me_ptr = me, *next_buf = next;
9862 - if(setjmp(my_buf) == 0)
9863 - longjmp(*next_buf, 1);
9864 + if(sigsetjmp(my_buf, 1) == 0)
9865 + siglongjmp(*next_buf, 1);
9868 static jmp_buf initial_jmpbuf;
9869 @@ -265,14 +283,14 @@
9872 *fork_buf_ptr = &initial_jmpbuf;
9873 - n = setjmp(initial_jmpbuf);
9874 + n = sigsetjmp(initial_jmpbuf, 1);
9876 new_thread_proc((void *) stack, new_thread_handler);
9881 - longjmp(*cb_back, 1);
9882 + siglongjmp(*cb_back, 1);
9890 - longjmp(**switch_buf, 1);
9891 + siglongjmp(**switch_buf, 1);
9894 void remove_sigstack(void)
9899 - if(setjmp(here) == 0)
9900 - longjmp(initial_jmpbuf, 2);
9901 + if(sigsetjmp(here, 1) == 0)
9902 + siglongjmp(initial_jmpbuf, 2);
9906 @@ -316,22 +334,23 @@
9907 void halt_skas(void)
9910 - longjmp(initial_jmpbuf, 3);
9911 + siglongjmp(initial_jmpbuf, 3);
9914 void reboot_skas(void)
9917 - longjmp(initial_jmpbuf, 4);
9918 + siglongjmp(initial_jmpbuf, 4);
9921 int new_mm(int from)
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);
9933 copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS,
9935 n = os_write_file(fd, ©, 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);
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);
9953 panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n",
9957 void kill_off_processes_skas(void)
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);
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
9969 thread_wait(¤t->thread.mode.skas.switch_buf,
9970 current->thread.mode.skas.fork_buf);
9973 - schedule_tail(NULL);
9975 + if(current->thread.prev_sched != NULL)
9976 + schedule_tail(current->thread.prev_sched);
9977 current->thread.prev_sched = NULL;
9979 + /* The return value is 1 if the kernel thread execs a process,
9980 + * 0 if it just exits
9982 n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf);
9984 userspace(¤t->thread.regs.regs);
9986 current->thread.mode.skas.fork_buf);
9990 - schedule_tail(current->thread.prev_sched);
9992 + if(current->thread.prev_sched != NULL)
9993 + schedule_tail(current->thread.prev_sched);
9994 current->thread.prev_sched = NULL;
9999 void init_idle_skas(void)
10001 - cpu_tasks[current->thread_info->cpu].pid = os_getpid();
10002 + cpu_tasks[current_thread->cpu].pid = os_getpid();
10006 @@ -160,11 +161,11 @@
10008 int start_uml_skas(void)
10010 - start_userspace();
10011 + start_userspace(0);
10012 capture_signal_stack();
10013 + uml_idle_timer();
10015 init_new_thread_signals(1);
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 @@
10022 int external_pid_skas(struct task_struct *task)
10024 - return(userspace_pid);
10025 +#warning Need to look up userspace_pid by cpu
10026 + return(userspace_pid[0]);
10029 int thread_pid_skas(struct task_struct *task)
10031 - return(userspace_pid);
10032 +#warning Need to look up userspace_pid by cpu
10033 + return(userspace_pid[0]);
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
10042 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
10043 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
10044 * Licensed under the GPL
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
10051 #include "kern_util.h"
10053 #include "sigcontext.h"
10056 -extern int userspace_pid;
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)
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;
10073 - err = ptrace(PTRACE_SETFPREGS, userspace_pid, 0, fpregs);
10074 + err = ptrace(PTRACE_SETFPREGS, pid, 0, fpregs);
10076 printk("copy_sc_to_user - PTRACE_SETFPREGS failed, "
10077 "errno = %d\n", errno);
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,
10088 struct sigcontext sc, *to = to_ptr;
10089 struct _fpstate *to_fp;
10091 sc.err = TO_SC_ERR(fault_type);
10092 sc.trapno = regs->skas.trap_type;
10094 - err = ptrace(PTRACE_GETFPREGS, userspace_pid, 0, fpregs);
10095 + err = ptrace(PTRACE_GETFPREGS, pid, 0, fpregs);
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
10104 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
10105 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
10106 * Licensed under the GPL
10111 struct signal_info *info;
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
10123 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
10124 + * Licensed under the GPL
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"
10137 +extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
10140 +static unsigned long maybe_map(unsigned long virt, int is_write)
10145 + void *phys = um_virt_to_phys(current, virt, &pte);
10148 + if(IS_ERR(phys) || (is_write && !pte_write(pte))){
10149 + err = handle_page_fault(virt, 0, is_write, 0, &dummy_code);
10152 + phys = um_virt_to_phys(current, virt, NULL);
10154 + return((unsigned long) phys);
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)
10160 + struct page *page;
10163 + addr = maybe_map(addr, is_write);
10167 + page = phys_to_page(addr);
10168 + addr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK);
10169 + n = (*op)(addr, len, arg);
10175 +static int buffer_op(unsigned long addr, int len, int is_write,
10176 + int (*op)(unsigned long addr, int len, void *arg),
10179 + int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
10180 + int remain = len, n;
10182 + n = do_op(addr, size, is_write, op, arg);
10184 + return(n < 0 ? remain : 0);
10191 + while(addr < ((addr + remain) & PAGE_MASK)){
10192 + n = do_op(addr, PAGE_SIZE, is_write, op, arg);
10194 + return(n < 0 ? remain : 0);
10196 + addr += PAGE_SIZE;
10197 + remain -= PAGE_SIZE;
10202 + n = do_op(addr, remain, is_write, op, arg);
10204 + return(n < 0 ? remain : 0);
10208 +static int copy_chunk_from_user(unsigned long from, int len, void *arg)
10210 + unsigned long *to_ptr = arg, to = *to_ptr;
10212 + memcpy((void *) to, (void *) from, len);
10217 +int copy_from_user_skas(void *to, const void *from, int n)
10219 + if(segment_eq(get_fs(), KERNEL_DS)){
10220 + memcpy(to, from, n);
10224 + return(access_ok_skas(VERIFY_READ, from, n) ?
10225 + buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
10229 +static int copy_chunk_to_user(unsigned long to, int len, void *arg)
10231 + unsigned long *from_ptr = arg, from = *from_ptr;
10233 + memcpy((void *) to, (void *) from, len);
10234 + *from_ptr += len;
10238 +int copy_to_user_skas(void *to, const void *from, int n)
10240 + if(segment_eq(get_fs(), KERNEL_DS)){
10241 + memcpy(to, from, n);
10245 + return(access_ok_skas(VERIFY_WRITE, to, n) ?
10246 + buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
10250 +static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
10252 + char **to_ptr = arg, *to = *to_ptr;
10255 + strncpy(to, (void *) from, len);
10256 + n = strnlen(to, len);
10264 +int strncpy_from_user_skas(char *dst, const char *src, int count)
10269 + if(segment_eq(get_fs(), KERNEL_DS)){
10270 + strncpy(dst, src, count);
10271 + return(strnlen(dst, count));
10274 + if(!access_ok_skas(VERIFY_READ, src, 1))
10277 + n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user,
10281 + return(strnlen(dst, count));
10284 +static int clear_chunk(unsigned long addr, int len, void *unused)
10286 + memset((void *) addr, 0, len);
10290 +int __clear_user_skas(void *mem, int len)
10292 + return(buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL));
10295 +int clear_user_skas(void *mem, int len)
10297 + if(segment_eq(get_fs(), KERNEL_DS)){
10298 + memset(mem, 0, len);
10302 + return(access_ok_skas(VERIFY_WRITE, mem, len) ?
10303 + buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len);
10306 +static int strnlen_chunk(unsigned long str, int len, void *arg)
10308 + int *len_ptr = arg, n;
10310 + n = strnlen((void *) str, len);
10318 +int strnlen_user_skas(const void *str, int len)
10320 + int count = 0, n;
10322 + if(segment_eq(get_fs(), KERNEL_DS))
10323 + return(strnlen(str, len) + 1);
10325 + n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count);
10327 + return(count + 1);
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
10336 + * ---------------------------------------------------------------------------
10337 + * Local variables:
10338 + * c-file-style: "linux"
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
10347 mk_ptregs : mk_ptregs.o
10348 - $(CC) -o mk_ptregs mk_ptregs.o
10349 + $(HOSTCC) -o mk_ptregs mk_ptregs.o
10351 mk_ptregs.o : mk_ptregs.c
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
10361 +#include <stdio.h>
10362 #include <asm/ptrace.h>
10363 #include <asm/user.h>
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
10370 - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
10371 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
10372 * Licensed under the GPL
10375 #include "linux/config.h"
10376 +#include "linux/percpu.h"
10377 +#include "asm/pgalloc.h"
10378 +#include "asm/tlb.h"
10380 +/* For some reason, mmu_gathers are referenced when CONFIG_SMP is off. */
10381 +DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
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;
10392 EXPORT_SYMBOL(cpu_online_map);
10396 void smp_send_reschedule(int cpu)
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++;
10403 @@ -100,35 +106,34 @@
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)
10410 - write(cpu_data[i].ipi_pipe[1], "S", 1);
10411 + os_write_file(cpu_data[i].ipi_pipe[1], "S", 1);
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;
10421 static int idle_proc(void *cpup)
10423 int cpu = (int) cpup, err;
10425 err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
10427 - panic("CPU#%d failed to create IPI pipe, errno = %d", cpu,
10430 + panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);
10432 activate_ipi(cpu_data[cpu].ipi_pipe[0],
10433 current->thread.mode.tt.extern_pid);
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);
10442 - while (!cpu_isset(cpu, &smp_commenced_mask))
10443 + while (!cpu_isset(cpu, smp_commenced_mask))
10446 cpu_set(cpu, cpu_online_map);
10447 @@ -143,16 +148,20 @@
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,
10455 + if(IS_ERR(new_task))
10456 + panic("copy_process failed in idle_thread, error = %ld",
10457 + PTR_ERR(new_task));
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,
10466 ({ panic("skas mode doesn't support SMP"); }));
10467 + wake_up_forked_process(new_task);
10471 @@ -160,15 +169,17 @@
10473 struct task_struct *idle;
10474 unsigned long waittime;
10476 + int err, cpu, me = smp_processor_id();
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);
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);
10488 + panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
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);
10494 for(cpu = 1; cpu < ncpus; cpu++){
10495 @@ -180,10 +191,10 @@
10496 unhash_process(idle);
10498 waittime = 200000000;
10499 - while (waittime-- && !cpu_isset(cpu, smp_callin_map))
10500 + while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
10503 - if (cpu_isset(cpu, smp_callin_map))
10504 + if (cpu_isset(cpu, cpu_callin_map))
10506 else printk("failed\n");
10508 @@ -216,7 +227,7 @@
10511 fd = cpu_data[cpu].ipi_pipe[0];
10512 - while (read(fd, &c, 1) == 1) {
10513 + while (os_read_file(fd, &c, 1) == 1) {
10516 smp_call_function_slave(cpu);
10517 @@ -273,9 +284,9 @@
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);
10527 while (atomic_read(&scf_started) != cpus)
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
10534 - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
10535 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
10536 * Licensed under the GPL
10539 @@ -35,39 +35,40 @@
10541 long sys_fork(void)
10543 - struct task_struct *p;
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);
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)
10558 - struct task_struct *p;
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);
10569 long sys_vfork(void)
10571 - struct task_struct *p;
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,
10578 current->thread.forking = 0;
10579 - return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
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)
10592 int error = -EBADF;
10593 struct file * file = NULL;
10598 - down_write(¤t->mm->mmap_sem);
10599 - error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
10600 - up_write(¤t->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);
10608 unsigned long prot, unsigned long flags,
10609 unsigned long fd, unsigned long pgoff)
10611 - return do_mmap2(addr, len, prot, flags, fd, pgoff);
10612 + return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
10616 @@ -120,7 +121,8 @@
10617 if (offset & ~PAGE_MASK)
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);
10626 @@ -135,43 +137,12 @@
10628 error = do_pipe(fd);
10630 - if (copy_to_user(fildes, fd, 2*sizeof(int)))
10631 + if (copy_to_user(fildes, fd, sizeof(fd)))
10637 -int sys_sigaction(int sig, const struct old_sigaction *act,
10638 - struct old_sigaction *oact)
10640 - struct k_sigaction new_ka, old_ka;
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))
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);
10654 - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
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))
10661 - __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
10662 - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
10669 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
10671 @@ -253,7 +224,7 @@
10672 return sys_shmctl (first, second,
10673 (struct shmid_ds *) ptr);
10680 @@ -302,11 +273,6 @@
10684 -int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
10686 - return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs)));
10689 long execute_syscall(void *r)
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
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;
10754 #define NFSSERVCTL sys_nfsservctl
10755 @@ -246,7 +274,7 @@
10756 extern syscall_handler_t um_time;
10757 extern syscall_handler_t um_stime;
10759 -#define LAST_GENERIC_SYSCALL __NR_set_tid_address
10760 +#define LAST_GENERIC_SYSCALL __NR_vserver
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,
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
10841 show_trace((unsigned long *)esp);
10844 +void show_stack(struct task_struct *task, unsigned long *sp)
10847 + show_trace_task(task);
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
10860 if((dir == NULL) || (*dir == '\0'))
10863 tempdir = malloc(strlen(dir) + 2);
10864 if(tempdir == NULL){
10865 fprintf(stderr, "Failed to malloc tempdir, "
10869 strcat(tempname, template);
10870 - if((fd = mkstemp(tempname)) < 0){
10871 + fd = mkstemp(tempname);
10873 fprintf(stderr, "open - cannot create %s: %s\n", tempname,
10880 - if((*out_tempname = strdup(tempname)) == NULL){
10881 + *out_tempname = strdup(tempname);
10882 + if(*out_tempname == NULL){
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
10893 +#include <stdlib.h>
10894 #include <unistd.h>
10896 #include <sys/time.h>
10897 #include <signal.h>
10899 -#include "linux/module.h"
10900 #include "user_util.h"
10901 #include "kern_util.h"
10903 #include "process.h"
10904 #include "signal_user.h"
10905 #include "time_user.h"
10906 +#include "kern_constants.h"
10908 +/* XXX This really needs to be declared and initialized in a kernel file since
10909 + * it's in <linux/time.h>
10911 +extern struct timespec wall_to_monotonic;
10913 extern struct timeval xtime;
10915 +struct timeval local_offset = { 0, 0 };
10919 gettimeofday(&xtime, NULL);
10920 + timeradd(&xtime, &local_offset, &xtime);
10923 void set_interval(int timer_type)
10928 -void idle_timer(void)
10929 +void uml_idle_timer(void)
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);
10937 +static unsigned long long get_host_hz(void)
10939 + char mhzline[16], *end;
10940 + int ret, mult, mhz, rest, len;
10942 + ret = cpu_feature("cpu MHz", mhzline,
10943 + sizeof(mhzline) / sizeof(mhzline[0]));
10945 + panic ("Could not get host MHZ");
10947 + mhz = strtoul(mhzline, &end, 10);
10949 + /* This business is to parse a floating point number without using
10950 + * floating types.
10957 + len = strlen(end);
10962 + rest = strtoul(end, NULL, 10);
10963 + while(mult-- > 0)
10967 + return(1000000 * mhz + rest);
10970 +unsigned long long host_hz = 0;
10972 void time_init(void)
10974 + struct timespec now;
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);
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;
10988 void do_gettimeofday(struct timeval *tv)
10990 @@ -95,15 +144,13 @@
10991 time_unlock(flags);
10994 -EXPORT_SYMBOL(do_gettimeofday);
10996 int do_settimeofday(struct timespec *tv)
10998 struct timeval now;
10999 unsigned long flags;
11000 struct timeval tv_in;
11002 - if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
11003 + if ((unsigned long) tv->tv_nsec >= UM_NSEC_PER_SEC)
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);
11013 -EXPORT_SYMBOL(do_settimeofday);
11017 void idle_sleep(int secs)
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
11027 + * Scheduler clock - returns current time in nanosec units.
11029 +unsigned long long sched_clock(void)
11031 + return (unsigned long long)jiffies_64 * (1000000000 / HZ);
11034 /* Changed at early boot */
11035 int timer_irq_inited = 0;
11037 @@ -39,13 +47,47 @@
11039 int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS];
11041 +static int first_tick;
11042 +static unsigned long long prev_tsc;
11043 +static long long delta; /* Deviation per interval */
11045 +extern unsigned long long host_hz;
11047 void timer_irq(union uml_pt_regs *regs)
11049 - int cpu = current->thread_info->cpu, ticks = missed_ticks[cpu];
11050 + unsigned long long ticks = 0;
11052 + if(!timer_irq_inited){
11053 + /* This is to ensure that ticks don't pile up when
11054 + * the timer handler is suspended */
11060 +#if defined(CONFIG_UML_REAL_TIME_CLOCK)
11061 + unsigned long long tsc;
11062 + /* We've had 1 tick */
11063 + tsc = time_stamp();
11065 + delta += tsc - prev_tsc;
11068 + ticks += (delta * HZ) / host_hz;
11069 + delta -= (ticks * host_hz) / HZ;
11075 + prev_tsc = time_stamp();
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);
11088 void boot_timer_handler(int sig)
11089 @@ -58,12 +100,13 @@
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)
11097 - write_seqlock(&xtime_lock);
11098 + write_seqlock_irq(&xtime_lock);
11100 - write_sequnlock(&xtime_lock);
11101 + write_sequnlock_irq(&xtime_lock);
11102 + return(IRQ_HANDLED);
11105 long um_time(int * tloc)
11106 @@ -81,12 +124,12 @@
11107 long um_stime(int * tptr)
11110 - struct timeval new;
11111 + struct timespec new;
11113 if (get_user(value, tptr))
11115 new.tv_sec = value;
11118 do_settimeofday(&new);
11121 @@ -125,9 +168,11 @@
11122 void timer_handler(int sig, union uml_pt_regs *regs)
11125 + local_irq_disable();
11126 update_process_times(user_context(UPT_SP(regs)));
11127 + local_irq_enable();
11129 - if(current->thread_info->cpu == 0)
11130 + if(current_thread->cpu == 0)
11134 @@ -136,6 +181,7 @@
11135 unsigned long time_lock(void)
11137 unsigned long flags;
11139 spin_lock_irqsave(&timer_spinlock, flags);
11142 @@ -150,8 +196,8 @@
11145 CHOOSE_MODE(user_time_init_tt(), user_time_init_skas());
11146 - if((err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer",
11148 + err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL);
11150 printk(KERN_ERR "timer_init : request_irq failed - "
11151 "errno = %d\n", -err);
11152 timer_irq_inited = 1;
11153 @@ -160,7 +206,6 @@
11155 __initcall(timer_init);
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"
11172 #include "chan_kern.h"
11173 #include "mconsole_kern.h"
11174 #include "2_5compat.h"
11176 +#include "mem_kern.h"
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))
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);
11192 switch (handle_mm_fault(mm, vma, address, is_write)){
11193 case VM_FAULT_MINOR:
11194 current->min_flt++;
11195 @@ -71,14 +74,20 @@
11197 goto out_of_memory;
11200 + if (current->pid == 1) {
11201 + up_read(&mm->mmap_sem);
11203 + down_read(&mm->mmap_sem);
11208 pte = pte_offset_kernel(pmd, page);
11209 } while(!pte_present(*pte));
11211 *pte = pte_mkyoung(*pte);
11212 if(pte_write(*pte)) *pte = pte_mkdirty(*pte);
11213 flush_tlb_page(vma, page);
11216 up_read(&mm->mmap_sem);
11218 @@ -98,6 +107,33 @@
11222 +LIST_HEAD(physmem_remappers);
11224 +void register_remapper(struct remapper *info)
11226 + list_add(&info->list, &physmem_remappers);
11229 +static int check_remapped_addr(unsigned long address, int is_write)
11231 + struct remapper *remapper;
11232 + struct list_head *ele;
11236 + fd = phys_mapping(__pa(address), &offset);
11240 + list_for_each(ele, &physmem_remappers){
11241 + remapper = list_entry(ele, struct remapper, list);
11242 + if((*remapper->proc)(fd, address, is_write, offset))
11249 unsigned long segv(unsigned long address, unsigned long ip, int is_write,
11250 int is_user, void *sc)
11252 @@ -109,7 +145,9 @@
11253 flush_tlb_kernel_vm();
11256 - if(current->mm == NULL)
11257 + else if(check_remapped_addr(address & PAGE_MASK, is_write))
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);
11263 @@ -120,9 +158,8 @@
11264 current->thread.fault_addr = (void *) address;
11265 do_longjmp(catcher, 1);
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");
11271 else if(arch_fixup(ip, sc))
11274 @@ -155,8 +192,6 @@
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);
11287 +void winch(int sig, union uml_pt_regs *regs)
11289 + do_IRQ(WINCH_IRQ, regs);
11292 void trap_init(void)
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
11300 #include <stdlib.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>
11312 [ SIGILL ] { .handler = relay_signal,
11314 + [ SIGWINCH ] { .handler = winch,
11316 [ SIGBUS ] { .handler = bus_handler,
11318 [ SIGSEGV] { .handler = segv_handler,
11319 @@ -123,7 +123,7 @@
11323 - longjmp(*buf, val);
11324 + siglongjmp(*buf, val);
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
11332 #include "mem_user.h"
11337 static int exec_tramp(void *sig_stack)
11339 @@ -47,17 +48,17 @@
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());
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);
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
11365 #include "sysdep/ptrace.h"
11367 +enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
11369 extern int tracing_pid;
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
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
11382 @@ -43,65 +43,19 @@
11384 extern int __do_copy_from_user(void *to, const void *from, int n,
11385 void **fault_addr, void **fault_catcher);
11387 -static inline int copy_from_user_tt(void *to, const void *from, int n)
11389 - return(access_ok_tt(VERIFY_READ, from, n) ?
11390 - __do_copy_from_user(to, from, n,
11391 - ¤t->thread.fault_addr,
11392 - ¤t->thread.fault_catcher) : n);
11395 -static inline int copy_to_user_tt(void *to, const void *from, int n)
11397 - return(access_ok_tt(VERIFY_WRITE, to, n) ?
11398 - __do_copy_to_user(to, from, n,
11399 - ¤t->thread.fault_addr,
11400 - ¤t->thread.fault_catcher) : n);
11403 extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
11404 void **fault_addr, void **fault_catcher);
11406 -static inline int strncpy_from_user_tt(char *dst, const char *src, int count)
11410 - if(!access_ok_tt(VERIFY_READ, src, 1)) return(-EFAULT);
11411 - n = __do_strncpy_from_user(dst, src, count,
11412 - ¤t->thread.fault_addr,
11413 - ¤t->thread.fault_catcher);
11414 - if(n < 0) return(-EFAULT);
11418 extern int __do_clear_user(void *mem, size_t len, void **fault_addr,
11419 void **fault_catcher);
11421 -static inline int __clear_user_tt(void *mem, int len)
11423 - return(__do_clear_user(mem, len,
11424 - ¤t->thread.fault_addr,
11425 - ¤t->thread.fault_catcher));
11428 -static inline int clear_user_tt(void *mem, int len)
11430 - return(access_ok_tt(VERIFY_WRITE, mem, len) ?
11431 - __do_clear_user(mem, len,
11432 - ¤t->thread.fault_addr,
11433 - ¤t->thread.fault_catcher) : len);
11436 extern int __do_strnlen_user(const char *str, unsigned long n,
11437 void **fault_addr, void **fault_catcher);
11439 -static inline int strnlen_user_tt(const void *str, int len)
11441 - return(__do_strnlen_user(str, len,
11442 - ¤t->thread.fault_addr,
11443 - ¤t->thread.fault_catcher));
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);
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
11459 -# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
11460 +# Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
11461 # Licensed under the GPL
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)/
11471 obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/
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");
11487 memcpy(addr, segment_start, size);
11488 - if(switcheroo(data, prot, addr, segment_start,
11490 + if(switcheroo(data, prot, addr, segment_start, size) < 0){
11491 printf("switcheroo failed\n");
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
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);
11505 if((from->state == TASK_ZOMBIE) || (from->state == TASK_DEAD))
11506 @@ -104,48 +104,72 @@
11508 void release_thread_tt(struct task_struct *task)
11510 - os_kill_process(task->thread.mode.tt.extern_pid, 0);
11511 + int pid = task->thread.mode.tt.extern_pid;
11513 + if(os_getpid() != pid)
11514 + os_kill_process(pid, 0);
11517 void exit_thread_tt(void)
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]);
11525 void schedule_tail(task_t *prev);
11527 static void new_thread_handler(int sig)
11529 + unsigned long disable;
11533 fn = current->thread.request.u.thread.proc;
11534 arg = current->thread.request.u.thread.arg;
11536 UPT_SC(¤t->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(¤t->thread.regs.regs)) &= ~disable;
11541 suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
11544 + force_flush_all();
11545 + if(current->thread.prev_sched != NULL)
11546 + schedule_tail(current->thread.prev_sched);
11547 + current->thread.prev_sched = NULL;
11549 init_new_thread_signals(1);
11551 - schedule_tail(current->thread.prev_sched);
11554 free_page(current->thread.temp_stack);
11555 set_cmdline("(kernel thread)");
11556 - force_flush_all();
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, ¤t->thread.exec_buf))
11568 static int new_thread_proc(void *stack)
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
11585 + local_irq_disable();
11586 init_new_thread_stack(stack, new_thread_handler);
11587 os_usr1_process(os_getpid());
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.
11598 @@ -165,35 +189,32 @@
11599 UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1);
11600 suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
11603 - schedule_tail(NULL);
11605 + force_flush_all();
11606 + if(current->thread.prev_sched != NULL)
11607 + schedule_tail(current->thread.prev_sched);
11608 + current->thread.prev_sched = NULL;
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,
11617 - task_protections((unsigned long) current->thread_info);
11619 - current->thread.prev_sched = NULL;
11620 + task_protections((unsigned long) current_thread);
11622 free_page(current->thread.temp_stack);
11623 + local_irq_disable();
11624 change_sig(SIGUSR1, 0);
11625 set_user_mode(current);
11628 -static int sigusr1 = SIGUSR1;
11630 int fork_tramp(void *stack)
11632 - int sig = sigusr1;
11634 local_irq_disable();
11635 + arch_init_thread();
11636 init_new_thread_stack(stack, finish_fork_handler);
11638 - kill(os_getpid(), sig);
11639 + os_usr1_process(os_getpid());
11643 @@ -213,8 +234,8 @@
11646 err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1);
11648 - printk("copy_thread : pipe failed, errno = %d\n", -err);
11650 + printk("copy_thread : pipe failed, err = %d\n", -err);
11654 @@ -377,8 +398,8 @@
11656 pages = (1 << CONFIG_KERNEL_STACK_ORDER);
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);
11665 @@ -454,8 +475,9 @@
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",
11672 + panic("Can't create switch pipe for init_task, errno = %d",
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
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 @@
11691 char gdb_init_string[] =
11695 -handle SIGWINCH nostop noprint pass
11699 +handle SIGWINCH nostop noprint pass \n\
11702 int start_debugger(char *prog, int startup, int stop, int *fd_out)
11703 @@ -304,7 +303,8 @@
11706 slave = open_gdb_chan();
11707 - if((child = fork()) == 0){
11710 char *tempname = NULL;
11713 @@ -327,18 +327,19 @@
11717 - if((fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0)) < 0){
11718 - printk("start_debugger : make_tempfile failed, errno = %d\n",
11720 + fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0);
11722 + printk("start_debugger : make_tempfile failed,"
11723 + "err = %d\n", -fd);
11726 - write(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
11727 + os_write_file(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
11730 - write(fd, "b start_kernel\n",
11731 + os_write_file(fd, "b start_kernel\n",
11732 strlen("b start_kernel\n"));
11734 - write(fd, "c\n", strlen("c\n"));
11735 + os_write_file(fd, "c\n", strlen("c\n"));
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
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)
11760 pid = debugger->pid;
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);
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);
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, "
11777 + "errno = %d\n", errno);
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
11786 - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
11787 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
11788 * Licensed under the GPL
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 @@
11797 register_winch_irq(tracer_winch[0], fd, -1, data);
11802 static void tracer_winch_handler(int sig)
11807 - if(write(tracer_winch[1], &c, sizeof(c)) != sizeof(c))
11808 - printk("tracer_winch_handler - write failed, errno = %d\n",
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);
11815 /* Called only by the tracing thread during initialization */
11819 err = os_pipe(tracer_winch, 1, 1);
11821 - printk("setup_tracer_winch : os_pipe failed, errno = %d\n",
11824 + printk("setup_tracer_winch : os_pipe failed, err = %d\n", -err);
11827 signal(SIGWINCH, tracer_winch_handler);
11828 @@ -130,8 +130,8 @@
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,
11834 + "continue pid %d, signal = %d, "
11835 + "errno = %d\n", pid, sig, errno);
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",
11848 @@ -218,7 +218,7 @@
11849 err = attach(debugger_parent);
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;
11857 @@ -233,7 +233,8 @@
11859 set_cmdline("(tracing thread)");
11861 - if((pid = waitpid(-1, &status, WUNTRACED)) <= 0){
11862 + pid = waitpid(-1, &status, WUNTRACED);
11864 if(errno != ECHILD){
11865 printf("wait failed - errno = %d\n", errno);
11867 @@ -401,7 +402,7 @@
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);
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
11881 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
11882 + * Licensed under the GPL
11885 +#include "linux/sched.h"
11886 +#include "asm/uaccess.h"
11888 +int copy_from_user_tt(void *to, const void *from, int n)
11890 + if(!access_ok_tt(VERIFY_READ, from, n))
11893 + return(__do_copy_from_user(to, from, n, ¤t->thread.fault_addr,
11894 + ¤t->thread.fault_catcher));
11897 +int copy_to_user_tt(void *to, const void *from, int n)
11899 + if(!access_ok_tt(VERIFY_WRITE, to, n))
11902 + return(__do_copy_to_user(to, from, n, ¤t->thread.fault_addr,
11903 + ¤t->thread.fault_catcher));
11906 +int strncpy_from_user_tt(char *dst, const char *src, int count)
11910 + if(!access_ok_tt(VERIFY_READ, src, 1))
11913 + n = __do_strncpy_from_user(dst, src, count,
11914 + ¤t->thread.fault_addr,
11915 + ¤t->thread.fault_catcher);
11916 + if(n < 0) return(-EFAULT);
11920 +int __clear_user_tt(void *mem, int len)
11922 + return(__do_clear_user(mem, len,
11923 + ¤t->thread.fault_addr,
11924 + ¤t->thread.fault_catcher));
11927 +int clear_user_tt(void *mem, int len)
11929 + if(!access_ok_tt(VERIFY_WRITE, mem, len))
11932 + return(__do_clear_user(mem, len, ¤t->thread.fault_addr,
11933 + ¤t->thread.fault_catcher));
11936 +int strnlen_user_tt(const void *str, int len)
11938 + return(__do_strnlen_user(str, len,
11939 + ¤t->thread.fault_addr,
11940 + ¤t->thread.fault_catcher));
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
11948 + * ---------------------------------------------------------------------------
11949 + * Local variables:
11950 + * c-file-style: "linux"
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
11957 #include <string.h>
11958 #include "user_util.h"
11959 #include "uml_uaccess.h"
11961 +#include "kern_util.h"
11963 int __do_copy_from_user(void *to, const void *from, int n,
11964 void **fault_addr, void **fault_catcher)
11966 + struct tt_regs save = TASK_REGS(get_current())->tt;
11967 unsigned long fault;
11970 fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
11971 __do_copy, &faulted);
11972 + TASK_REGS(get_current())->tt = save;
11974 if(!faulted) return(0);
11975 else return(n - (fault - (unsigned long) from));
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)
11981 + struct tt_regs save = TASK_REGS(get_current())->tt;
11982 unsigned long fault;
11985 fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
11986 __do_strncpy, &faulted);
11987 + TASK_REGS(get_current())->tt = save;
11989 if(!faulted) return(strlen(dst));
11992 @@ -46,11 +54,14 @@
11993 int __do_clear_user(void *mem, unsigned long len,
11994 void **fault_addr, void **fault_catcher)
11996 + struct tt_regs save = TASK_REGS(get_current())->tt;
11997 unsigned long fault;
12000 fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
12001 __do_clear, &faulted);
12002 + TASK_REGS(get_current())->tt = save;
12004 if(!faulted) return(0);
12005 else return(len - (fault - (unsigned long) mem));
12007 @@ -58,19 +69,20 @@
12008 int __do_strnlen_user(const char *str, unsigned long n,
12009 void **fault_addr, void **fault_catcher)
12011 + struct tt_regs save = TASK_REGS(get_current())->tt;
12013 unsigned long *faddrp = (unsigned long *)fault_addr;
12016 *fault_catcher = &jbuf;
12017 - if(setjmp(jbuf) == 0){
12018 + if(sigsetjmp(jbuf, 1) == 0)
12019 ret = strlen(str) + 1;
12022 - ret = *faddrp - (unsigned long) str;
12024 + else ret = *faddrp - (unsigned long) str;
12026 *fault_addr = NULL;
12027 *fault_catcher = NULL;
12029 + TASK_REGS(get_current())->tt = save;
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
12038 #include <stdlib.h>
12039 #include <unistd.h>
12040 -#include <fcntl.h>
12041 #include <sys/time.h>
12044 +#include "kern_util.h"
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
12054 +#define TTY_READ 1
12055 +#define TTY_WRITE 2
12057 struct tty_log_buf {
12062 + unsigned long sec;
12063 + unsigned long usec;
12066 -int open_tty_log(void *tty)
12067 +int open_tty_log(void *tty, void *current_tty)
12070 struct tty_log_buf data;
12071 char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
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,
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),
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, ¤t_tty, data.len);
12088 return(tty_log_fd);
12091 - gettimeofday(&tv, NULL);
12092 sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec,
12093 (unsigned int) tv.tv_usec);
12095 @@ -62,30 +73,117 @@
12096 void close_tty_log(int fd, void *tty)
12098 struct tty_log_buf data;
12099 + struct timeval tv;
12101 if(tty_log_fd != -1){
12102 - data = ((struct tty_log_buf) { what : TTY_LOG_CLOSE,
12103 - tty : (unsigned long) tty,
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,
12111 + .sec = tv.tv_sec,
12112 + .usec = tv.tv_usec } );
12113 + os_write_file(tty_log_fd, &data, sizeof(data));
12117 + os_close_file(fd);
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)
12123 + int total = 0, try, missed, n;
12127 + try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
12128 + missed = copy_from_user_proc(chunk, (char *) buf, try);
12130 + n = os_write_file(fd, chunk, try);
12147 +int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
12149 + struct timeval tv;
12150 struct tty_log_buf data;
12153 if(fd == tty_log_fd){
12154 - data = ((struct tty_log_buf) { what : TTY_LOG_WRITE,
12155 - tty : (unsigned long) tty,
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,
12163 + .direction = direction,
12164 + .sec = tv.tv_sec,
12165 + .usec = tv.tv_usec } );
12166 + os_write_file(tty_log_fd, &data, sizeof(data));
12168 - return(write(fd, buf, len));
12170 + return(log_chunk(fd, buf, len));
12173 +void log_exec(char **argv, void *tty)
12175 + struct timeval tv;
12176 + struct tty_log_buf data;
12180 + if(tty_log_fd == -1) return;
12182 + gettimeofday(&tv, NULL);
12185 + for(ptr = argv; ; ptr++){
12186 + if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
12188 + if(arg == NULL) break;
12189 + len += strlen_user_proc(arg);
12192 + data = ((struct tty_log_buf) { .what = TTY_LOG_EXEC,
12193 + .tty = (unsigned long) tty,
12196 + .sec = tv.tv_sec,
12197 + .usec = tv.tv_usec } );
12198 + os_write_file(tty_log_fd, &data, sizeof(data));
12200 + for(ptr = argv; ; ptr++){
12201 + if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
12203 + if(arg == NULL) break;
12204 + log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
12208 +extern void register_tty_logger(int (*opener)(void *, void *),
12209 + int (*writer)(int, const char *, int,
12211 + void (*closer)(int, void *));
12213 +static int register_logger(void)
12215 + register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
12219 +__uml_initcall(register_logger);
12221 static int __init set_tty_log_dir(char *name, int *add)
12223 tty_log_dir = name;
12224 @@ -104,7 +202,7 @@
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);
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
12239 *fault_catcher = &jbuf;
12240 - if(setjmp(jbuf) == 0){
12241 + if(sigsetjmp(jbuf, 1) == 0){
12242 (*op)(to, from, n);
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"
12252 -#define DEFAULT_COMMAND_LINE "root=6200"
12253 +#define DEFAULT_COMMAND_LINE "root=98:0"
12255 struct cpuinfo_um boot_cpu_data = {
12256 .loops_per_jiffy = 0,
12257 .ipi_pipe = { -1, -1 }
12260 +/* Placeholder to make UML link until the vsyscall stuff is actually
12263 +void *__kernel_vsyscall;
12265 unsigned long thread_saved_pc(struct task_struct *task)
12267 return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
12268 @@ -53,18 +58,22 @@
12270 static int show_cpuinfo(struct seq_file *m, void *v)
12275 - index = (struct cpuinfo_um *)v - cpu_data;
12277 + index = (struct cpuinfo_um *) v - cpu_data;
12278 if (!cpu_online(index))
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);
12295 @@ -134,12 +143,12 @@
12297 snprintf(argv1_begin,
12298 (argv1_end - argv1_begin) * sizeof(*ptr),
12301 ptr = &argv1_begin[strlen(argv1_begin)];
12303 else ptr = argv1_begin;
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));
12310 @@ -179,7 +188,7 @@
12311 static int __init uml_ncpus_setup(char *line, int *add)
12313 if (!sscanf(line, "%d", &ncpus)) {
12314 - printk("Couldn't parse [%s]\n", line);
12315 + printf("Couldn't parse [%s]\n", line);
12319 @@ -210,7 +219,7 @@
12321 static int __init mode_tt_setup(char *line, int *add)
12323 - printk("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
12324 + printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
12328 @@ -221,7 +230,7 @@
12330 static int __init mode_tt_setup(char *line, int *add)
12332 - printk("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
12333 + printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
12337 @@ -291,7 +300,7 @@
12339 /* Set during early boot */
12340 unsigned long brk_start;
12341 -static struct vm_reserved kernel_vm_reserved;
12342 +unsigned long end_iomem;
12344 #define MIN_VMALLOC (32 * 1024 * 1024)
12346 @@ -299,7 +308,7 @@
12348 unsigned long avail;
12349 unsigned long virtmem_size, max_physmem;
12350 - unsigned int i, add, err;
12351 + unsigned int i, add;
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])];
12359 - set_usable_vm(uml_physmem, get_kmem_end());
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;
12368 + /* Zones have to begin on a 1 << MAX_ORDER page boundary,
12369 + * so this makes sure that's true for highmem
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
12377 @@ -343,11 +356,19 @@
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;
12385 start_vm = VMALLOC_START;
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,
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",
12403 - err = reserve_vm(high_physmem, end_vm, &kernel_vm_reserved);
12405 - printf("Failed to reserve VM area for kernel VM\n");
12411 init_task.thread.kernel_stack = (unsigned long) &init_thread_info +
12414 task_protections((unsigned long) &init_thread_info);
12415 + os_flush_stdout();
12417 return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
12419 @@ -403,6 +419,7 @@
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
12433 #include <unistd.h>
12434 -#include <fcntl.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;
12442 -static int make_umid(void);
12443 +static int make_umid(int (*printer)(const char *fmt, ...));
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, ...))
12450 - printk("Unique machine name can't be set twice\n");
12451 + (*printer)("Unique machine name can't be set twice\n");
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));
12462 umid_is_random = is_random;
12465 static int __init set_umid_arg(char *name, int *add)
12467 - return(set_umid(name, 0));
12468 + return(set_umid(name, 0, printf));
12471 __uml_setup("umid=", set_umid_arg,
12476 - if(!umid_inited && make_umid()) return(-1);
12477 + if(!umid_inited && make_umid(printk)) return(-1);
12479 n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
12481 @@ -85,22 +85,23 @@
12483 char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
12484 char pid[sizeof("nnnnn\0")];
12488 if(umid_file_name("pid", file, sizeof(file))) return 0;
12490 fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))),
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);
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);
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);
12511 @@ -111,7 +112,8 @@
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);
12521 @@ -160,22 +162,24 @@
12523 char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
12524 char pid[sizeof("nnnnn\0")], *end;
12526 + int dead, fd, p, n;
12528 sprintf(file, "%s/pid", dir);
12530 - if((fd = os_open_file(file, of_read(OPENFLAGS()), 0)) < 0){
12531 + fd = os_open_file(file, of_read(OPENFLAGS()), 0);
12534 printk("not_dead_yet : couldn't open pid file '%s', "
12535 - "errno = %d\n", file, -fd);
12536 + "err = %d\n", file, -fd);
12542 - if(read(fd, pid, sizeof(pid)) < 0){
12543 + n = os_read_file(fd, pid, sizeof(pid));
12545 printk("not_dead_yet : couldn't read pid file '%s', "
12546 - "errno = %d\n", file, errno);
12547 + "err = %d\n", file, -n);
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",
12560 @@ -217,7 +221,7 @@
12561 char *home = getenv("HOME");
12564 - printk("make_uml_dir : no value in environment for "
12565 + printf("make_uml_dir : no value in environment for "
12569 @@ -232,57 +236,59 @@
12570 dir[len + 1] = '\0';
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);
12579 strcpy(uml_dir, dir);
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);
12589 -static int __init make_umid(void)
12590 +static int __init make_umid(int (*printer)(const char *fmt, ...))
12593 char tmp[strlen(uml_dir) + UMID_LEN + 1];
12595 strlcpy(tmp, uml_dir, sizeof(tmp));
12598 + if(!umid_inited){
12599 strcat(tmp, "XXXXXX");
12602 - printk("make_umid - mkstemp failed, errno = %d\n",
12604 + (*printer)("make_umid - mkstemp failed, errno = %d\n",
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
12616 - set_umid(&tmp[strlen(uml_dir)], 1);
12617 + set_umid(&tmp[strlen(uml_dir)], 1, printer);
12620 sprintf(tmp, "%s%s", uml_dir, umid);
12622 - if((err = mkdir(tmp, 0777)) < 0){
12623 + err = mkdir(tmp, 0777);
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);
12631 err = mkdir(tmp, 0777);
12635 - printk("Failed to create %s - errno = %d\n", umid, errno);
12636 + (*printer)("Failed to create %s - errno = %d\n", umid, errno);
12640 @@ -295,7 +301,13 @@
12643 __uml_postsetup(make_uml_dir);
12644 -__uml_postsetup(make_umid);
12646 +static int __init make_umid_setup(void)
12648 + return(make_umid(printf));
12651 +__uml_postsetup(make_umid_setup);
12652 __uml_postsetup(create_pid_file);
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
12660 #include <unistd.h>
12661 -#include <fcntl.h>
12662 #include <dirent.h>
12663 +#include <fcntl.h>
12666 #include <string.h>
12668 #define __MODULE_STRING_1(x) #x
12669 #define __MODULE_STRING(x) __MODULE_STRING_1(x)
12671 -#if !defined(__AUTOCONF_INCLUDED__)
12672 +#if !defined(AUTOCONF_INCLUDED)
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
12682 #include <stdlib.h>
12683 -#include <fcntl.h>
12684 #include <unistd.h>
12685 #include <limits.h>
12686 #include <sys/mman.h>
12691 - if(((ret = waitpid(pid, &status, WUNTRACED)) < 0) ||
12692 + ret = waitpid(pid, &status, WUNTRACED);
12694 !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
12696 if(errno == EINTR) continue;
12697 @@ -119,17 +119,6 @@
12701 -int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags)
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);
12712 int raw(int fd, int complain)
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
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 @@
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");
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");
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
12754 ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
12755 $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
12757 GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
12759 -include $(ARCH_DIR)/Makefile-$(SUBARCH)
12760 -include $(ARCH_DIR)/Makefile-os-$(OS)
12761 +.PHONY: sys_prepare
12765 MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
12766 MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
12768 include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
12771 +include $(ARCH_DIR)/Makefile-$(SUBARCH)
12772 +include $(ARCH_DIR)/Makefile-os-$(OS)
12774 EXTRAVERSION := $(EXTRAVERSION)-1um
12776 ARCH_INCLUDE = -I$(ARCH_DIR)/include
12777 @@ -52,14 +57,20 @@
12779 CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
12780 -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
12782 + -Dsigprocmask=kernel_sigprocmask $(MODE_INCLUDE)
12784 LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
12786 +# These are needed for clean and mrproper, since in that case .config is not
12787 +# included; the values here are meaningless
12789 +CONFIG_NEST_LEVEL ?= 0
12790 +CONFIG_KERNEL_HALF_GIGS ?= 0
12792 SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
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
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)) ] )
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))
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
12814 LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y)
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)
12821 linux: vmlinux $(LD_SCRIPT-y)
12822 $(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \
12823 @@ -116,16 +127,22 @@
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) \
12831 # To get a definition of F_SETSIG
12832 USER_CFLAGS += -D_GNU_SOURCE
12834 +ifdef CONFIG_DEBUG_INFO
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 \
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 $@ $<
12848 @@ -161,19 +178,23 @@
12850 cd $(ARCH_DIR) && ln -sf os-$(OS) os
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 > $@
12856 +filechk_$(ARCH_DIR)/include/task.h := $(ARCH_DIR)/util/mk_task
12858 $(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
12860 + $(call filechk,$@)
12862 +filechk_$(ARCH_DIR)/include/kern_constants.h := $(ARCH_DIR)/util/mk_constants
12864 $(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
12866 + $(call filechk,$@)
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 ;
12873 $(ARCH_DIR)/util: FORCE
12874 - @$(call descend,$@,)
12875 + $(MAKE) -f scripts/Makefile.build obj=$@
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 @@
12884 SYS_HEADERS = $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
12886 +sys_prepare: $(SYS_DIR)/sc.h
12888 prepare: $(SYS_HEADERS)
12890 +filechk_$(SYS_DIR)/sc.h := $(SYS_UTIL_DIR)/mk_sc
12892 $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
12894 + $(call filechk,$@)
12896 +filechk_$(SYS_DIR)/thread.h := $(SYS_UTIL_DIR)/mk_thread
12898 $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
12900 + $(call filechk,$@)
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),$@)
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),$@)
12912 $(SYS_UTIL_DIR): include/asm FORCE
12913 - @$(call descend,$@,)
12914 + +@$(call descend,$@,)
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
12922 LINK_SKAS = -Wl,-rpath,/lib
12923 LD_SCRIPT_SKAS = dyn.lds.s
12925 -GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
12926 +GEN_HEADERS += $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
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
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"
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
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 @@
12956 struct addr_change change;
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",
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());
12971 printk("etap_change : Failed to allocate output buffer\n");
12972 @@ -82,15 +82,15 @@
12973 struct etap_pre_exec_data *data = arg;
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);
12982 static int etap_tramp(char *dev, char *gate, int control_me,
12983 int control_remote, int data_me, int data_remote)
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);
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",
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);
13011 printk("etap_tramp : uml_net failed\n");
13013 - if(waitpid(pid, &status, 0) < 0) err = errno;
13014 - else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)){
13016 + if(waitpid(pid, &status, 0) < 0)
13018 + else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
13019 printk("uml_net didn't exit with status 1\n");
13024 @@ -143,14 +143,14 @@
13025 if(err) return(err);
13027 err = os_pipe(data_fds, 0, 0);
13029 - printk("data os_pipe failed - errno = %d\n", -err);
13031 + printk("data os_pipe failed - err = %d\n", -err);
13035 err = os_pipe(control_fds, 1, 0);
13037 - printk("control os_pipe failed - errno = %d\n", -err);
13039 + printk("control os_pipe failed - err = %d\n", -err);
13043 @@ -167,9 +167,9 @@
13048 - printk("etap_tramp failed - errno = %d\n", err);
13051 + printk("etap_tramp failed - err = %d\n", -err);
13055 pri->data_fd = data_fds[0];
13056 @@ -183,11 +183,11 @@
13057 struct ethertap_data *pri = data;
13059 iter_addresses(pri->dev, etap_close_addr, &pri->control_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);
13066 - close(pri->control_fd);
13067 + os_close_file(pri->control_fd);
13068 pri->control_fd = -1;
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
13075 #include <stdlib.h>
13076 #include <unistd.h>
13078 -#include <fcntl.h>
13079 #include <sys/wait.h>
13080 #include <sys/socket.h>
13081 #include <sys/un.h>
13083 struct tuntap_pre_exec_data *data = arg;
13085 dup2(data->stdout, 1);
13086 - close(data->close_me);
13087 + os_close_file(data->close_me);
13090 static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
13093 if(pid < 0) return(-pid);
13096 + os_close_file(remote);
13098 msg.msg_name = NULL;
13099 msg.msg_namelen = 0;
13100 @@ -107,19 +106,19 @@
13102 printk("tuntap_open_tramp : recvmsg failed - errno = %d\n",
13107 waitpid(pid, NULL, 0);
13109 cmsg = CMSG_FIRSTHDR(&msg);
13111 printk("tuntap_open_tramp : didn't receive a message\n");
13115 if((cmsg->cmsg_level != SOL_SOCKET) ||
13116 (cmsg->cmsg_type != SCM_RIGHTS)){
13117 printk("tuntap_open_tramp : didn't receive a descriptor\n");
13121 *fd_out = ((int *) CMSG_DATA(cmsg))[0];
13123 @@ -133,27 +132,29 @@
13124 int err, fds[2], len, used;
13126 err = tap_open_common(pri->dev, pri->gate_addr);
13127 - if(err) return(err);
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",
13137 + pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0);
13139 + printk("Failed to open /dev/net/tun, err = %d\n",
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);
13150 + printk("TUNSETIFF failed, errno = %d\n", errno);
13151 + os_close_file(pri->fd);
13156 err = os_pipe(fds, 0, 0);
13158 - printk("tuntap_open : os_pipe failed - errno = %d\n",
13160 + printk("tuntap_open : os_pipe failed - err = %d\n",
13164 @@ -166,19 +167,19 @@
13165 fds[1], buffer, len, &used);
13169 - pri->dev_name = uml_strdup(buffer);
13170 - output += IFNAMSIZ;
13172 - free_output_buffer(buffer);
13177 + printk("%s", output);
13178 free_output_buffer(buffer);
13179 - printk("tuntap_open_tramp failed - errno = %d\n", err);
13181 + printk("tuntap_open_tramp failed - err = %d\n", -err);
13186 + pri->dev_name = uml_strdup(buffer);
13187 + output += IFNAMSIZ;
13188 + printk("%s", output);
13189 + free_output_buffer(buffer);
13191 + os_close_file(fds[0]);
13192 iter_addresses(pri->dev, open_addr, pri->dev_name);
13195 @@ -191,7 +192,7 @@
13197 if(!pri->fixed_config)
13198 iter_addresses(pri->dev, close_addr, pri->dev_name);
13200 + os_close_file(fd);
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
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 @@
13218 #include "kern_util.h"
13220 -int os_file_type(char *file)
13221 +static void copy_stat(struct uml_stat *dst, struct stat64 *src)
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 */
13239 +int os_stat_fd(const int fd, struct uml_stat *ubuf)
13241 + struct stat64 sbuf;
13245 + err = fstat64(fd, &sbuf);
13246 + } while((err < 0) && (errno == EINTR)) ;
13252 + copy_stat(ubuf, &sbuf);
13256 +int os_stat_file(const char *file_name, struct uml_stat *ubuf)
13258 + struct stat64 sbuf;
13262 + err = stat64(file_name, &sbuf);
13263 + } while((err < 0) && (errno == EINTR)) ;
13269 + copy_stat(ubuf, &sbuf);
13273 +int os_access(const char* file, int mode)
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) ;
13280 + err = access(file, amode);
13287 +void os_print_error(int error, const char* str)
13289 + errno = error < 0 ? -error : error;
13294 +/* FIXME? required only by hostaudio (because it passes ioctls verbatim) */
13295 +int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
13299 + err = ioctl(fd, cmd, arg);
13306 +int os_window_size(int fd, int *rows, int *cols)
13308 + struct winsize size;
13310 + if(ioctl(fd, TIOCGWINSZ, &size) < 0)
13313 + *rows = size.ws_row;
13314 + *cols = size.ws_col;
13319 +int os_new_tty_pgrp(int fd, int pid)
13321 - struct stat64 buf;
13322 + if(ioctl(fd, TIOCSCTTY, 0) < 0){
13323 + printk("TIOCSCTTY failed, errno = %d\n", errno);
13327 + if(tcsetpgrp(fd, pid) < 0){
13328 + printk("tcsetpgrp failed, errno = %d\n", errno);
13335 +/* FIXME: ensure namebuf in os_get_if_name is big enough */
13336 +int os_get_ifname(int fd, char* namebuf)
13338 + if(ioctl(fd, SIOCGIFNAME, namebuf) < 0)
13344 +int os_set_slip(int fd)
13346 + int disc, sencap;
13349 + if(ioctl(fd, TIOCSETD, &disc) < 0){
13350 + printk("Failed to set slip line discipline - "
13351 + "errno = %d\n", errno);
13356 + if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0){
13357 + printk("Failed to set slip encapsulation - "
13358 + "errno = %d\n", errno);
13365 +int os_set_owner(int fd, int pid)
13367 + if(fcntl(fd, F_SETOWN, pid) < 0){
13368 + int save_errno = errno;
13370 + if(fcntl(fd, F_GETOWN, 0) != pid){
13371 + return(-save_errno);
13378 +/* FIXME? moved wholesale from sigio_user.c to get fcntls out of that file */
13379 +int os_sigio_async(int master, int slave)
13383 - if(stat64(file, &buf) == -1)
13384 + flags = fcntl(master, F_GETFL);
13386 + printk("fcntl F_GETFL failed, errno = %d\n", errno);
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);
13402 + if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)){
13403 + printk("fcntl F_SETFL failed, errno = %d\n", errno);
13410 +int os_mode_fd(int fd, int mode)
13415 + err = fchmod(fd, mode);
13416 + } while((err < 0) && (errno==EINTR)) ;
13424 +int os_file_type(char *file)
13426 + struct uml_stat buf;
13429 + err = os_stat_file(file, &buf);
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);
13442 int os_file_mode(char *file, struct openflags *mode_out)
13446 *mode_out = OPENFLAGS();
13448 - if(!access(file, W_OK)) *mode_out = of_write(*mode_out);
13449 - else if(errno != EACCES)
13451 + err = os_access(file, OS_ACC_W_OK);
13452 + if((err < 0) && (err != -EACCES))
13455 - if(!access(file, R_OK)) *mode_out = of_read(*mode_out);
13456 - else if(errno != EACCES)
13458 + *mode_out = of_write(*mode_out);
13460 + err = os_access(file, OS_ACC_R_OK);
13461 + if((err < 0) && (err != -EACCES))
13464 + *mode_out = of_read(*mode_out);
13468 @@ -63,16 +268,14 @@
13469 if(flags.e) f |= O_EXCL;
13471 fd = open64(file, f, mode);
13472 - if(fd < 0) return(-errno);
13477 - if(fcntl(fd, F_SETFD, 1)){
13481 + if(flags.cl && fcntl(fd, F_SETFD, 1)){
13482 + os_close_file(fd);
13492 err = connect(fd, (struct sockaddr *) &sock, sizeof(sock));
13499 @@ -109,88 +312,162 @@
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))
13508 + int page = getpagesize(), i;
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)))
13516 + if((len % page) != 0){
13517 + if((*copy_proc)(start + len - 1, &c, sizeof(c)))
13523 - /* XXX This fails if buf is kernel memory */
13525 - if(copy_to_user_proc(buf, &c, sizeof(c)))
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))
13535 + n = (*io_proc)(fd, buf, len);
13536 + if((n < 0) && (errno == EFAULT)){
13537 + err = fault_buffer(buf, len, copy_user_proc);
13540 + n = (*io_proc)(fd, buf, len);
13542 + } while((n < 0) && (errno == EINTR));
13544 - n = read(fd, buf, len);
13550 -int os_write_file(int fd, void *buf, int count)
13551 +int os_read_file(int fd, void *buf, int len)
13555 - /* Force buf into memory if it's not already. */
13557 - /* XXX This fails if buf is kernel memory */
13559 - if(copy_to_user_proc(buf, buf, buf[0]))
13562 + return(file_io(fd, buf, len, (int (*)(int, void *, int)) read,
13563 + copy_from_user_proc));
13566 - n = write(fd, buf, count);
13570 +int os_write_file(int fd, const void *buf, int len)
13572 + return(file_io(fd, (void *) buf, len,
13573 + (int (*)(int, void *, int)) write, copy_to_user_proc));
13576 int os_file_size(char *file, long long *size_out)
13578 - struct stat64 buf;
13579 + struct uml_stat buf;
13582 - if(stat64(file, &buf) == -1){
13583 - printk("Couldn't stat \"%s\" : errno = %d\n", file, errno);
13585 + err = os_stat_file(file, &buf);
13587 + printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
13590 - if(S_ISBLK(buf.st_mode)){
13592 + if(S_ISBLK(buf.ust_mode)){
13595 - if((fd = open64(file, O_RDONLY)) < 0){
13596 - printk("Couldn't open \"%s\", errno = %d\n", file,
13599 + fd = os_open_file(file, of_read(OPENFLAGS()), 0);
13601 + printk("Couldn't open \"%s\", errno = %d\n", file, -fd);
13604 if(ioctl(fd, BLKGETSIZE, &blocks) < 0){
13605 printk("Couldn't get the block size of \"%s\", "
13606 "errno = %d\n", file, errno);
13610 + os_close_file(fd);
13613 *size_out = ((long long) blocks) * 512;
13615 + os_close_file(fd);
13618 - *size_out = buf.st_size;
13619 + *size_out = buf.ust_size;
13623 +int os_file_modtime(char *file, unsigned long *modtime)
13625 + struct uml_stat buf;
13628 + err = os_stat_file(file, &buf);
13630 + printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
13634 + *modtime = buf.ust_mtime;
13638 +int os_get_exec_close(int fd, int* close_on_exec)
13643 + ret = fcntl(fd, F_GETFD);
13644 + } while((ret < 0) && (errno == EINTR)) ;
13649 + *close_on_exec = (ret&FD_CLOEXEC) ? 1 : 0;
13653 +int os_set_exec_close(int fd, int close_on_exec)
13657 + if(close_on_exec) flag = FD_CLOEXEC;
13661 + err = fcntl(fd, F_SETFD, flag);
13662 + } while((err < 0) && (errno == EINTR)) ;
13669 int os_pipe(int *fds, int stream, int close_on_exec)
13671 int err, type = stream ? SOCK_STREAM : SOCK_DGRAM;
13673 err = socketpair(AF_UNIX, type, 0, fds);
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",
13684 + err = os_set_exec_close(fds[0], 1);
13688 + err = os_set_exec_close(fds[1], 1);
13695 + printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err);
13696 + os_close_file(fds[1]);
13697 + os_close_file(fds[0]);
13701 int os_set_fd_async(int fd, int owner)
13702 @@ -270,7 +547,7 @@
13705 err = shutdown(fd, what);
13711 @@ -315,7 +592,7 @@
13715 -int create_unix_socket(char *file, int len)
13716 +int os_create_unix_socket(char *file, int len, int close_on_exec)
13718 struct sockaddr_un addr;
13720 @@ -327,6 +604,13 @@
13724 + if(close_on_exec) {
13725 + err = os_set_exec_close(sock, 1);
13727 + printk("create_unix_socket : close_on_exec failed, "
13728 + "err = %d", -err);
13731 addr.sun_family = AF_UNIX;
13733 /* XXX Be more careful about overflow */
13734 @@ -334,14 +618,45 @@
13736 err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
13738 - printk("create_listening_socket - bind failed, errno = %d\n",
13740 + printk("create_listening_socket at '%s' - bind failed, "
13741 + "errno = %d\n", file, errno);
13748 +void os_flush_stdout(void)
13753 +int os_lock_file(int fd, int excl)
13755 + int type = excl ? F_WRLCK : F_RDLCK;
13756 + struct flock lock = ((struct flock) { .l_type = type,
13757 + .l_whence = SEEK_SET,
13762 + err = fcntl(fd, F_SETLK, &lock);
13767 + err = fcntl(fd, F_GETLK, &lock);
13773 + printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
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
13787 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13788 + * Copyright (C) 2002 Jeff Dike (jdike@addtoit.com)
13789 * Licensed under the GPL
13795 #include <signal.h>
13796 +#include <linux/unistd.h>
13797 #include <sys/mman.h>
13798 #include <sys/wait.h>
13802 +#define ARBITRARY_ADDR -1
13803 +#define FAILURE_PID -1
13805 unsigned long os_process_pc(int pid)
13807 char proc_stat[sizeof("/proc/#####/stat\0")], buf[256];
13812 sprintf(proc_stat, "/proc/%d/stat", pid);
13813 fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0);
13815 - printk("os_process_pc - couldn't open '%s', errno = %d\n",
13816 - proc_stat, errno);
13818 + printk("os_process_pc - couldn't open '%s', err = %d\n",
13820 + return(ARBITRARY_ADDR);
13822 - if(read(fd, buf, sizeof(buf)) < 0){
13823 - printk("os_process_pc - couldn't read '%s', errno = %d\n",
13824 - proc_stat, errno);
13827 + err = os_read_file(fd, buf, sizeof(buf));
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);
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);
13845 - printk("Couldn't open '%s', errno = %d\n", stat, -fd);
13847 + printk("Couldn't open '%s', err = %d\n", stat, -fd);
13848 + return(FAILURE_PID);
13851 - n = read(fd, data, sizeof(data));
13853 + n = os_read_file(fd, data, sizeof(data));
13854 + os_close_file(fd);
13857 - printk("Couldn't read '%s', errno = %d\n", stat);
13859 + printk("Couldn't read '%s', err = %d\n", stat, -n);
13860 + return(FAILURE_PID);
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);
13869 + printk("Failed to scan '%s'\n", data);
13875 void os_usr1_process(int pid)
13877 - kill(pid, SIGUSR1);
13878 + syscall(__NR_tkill, pid, SIGUSR1);
13879 + /* kill(pid, SIGUSR1); */
13882 int os_getpid(void)
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)
13892 @@ -104,8 +111,8 @@
13893 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
13894 (x ? PROT_EXEC : 0);
13896 - loc = mmap((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
13898 + loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
13900 if(loc == MAP_FAILED)
13903 @@ -126,7 +133,8 @@
13906 err = munmap(addr, len);
13907 - if(err < 0) return(-errno);
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;
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",
13924 + fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0);
13926 + printk("get_pty : Couldn't open /dev/ptmx - err = %d\n", -fd);
13934 printk("get_pty : Couldn't grant pty - errno = %d\n",
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
13946 #include <unistd.h>
13947 -#include <fcntl.h>
13949 #include <string.h>
13950 #include <sys/signal.h>
13951 +#include <asm/ldt.h>
13952 #include "kern_util.h"
13954 #include "sysdep/ptrace.h"
13958 #define MAXTOKEN 64
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;
13966 static char token(int fd, char *buf, int len, char stop)
13968 @@ -27,13 +28,15 @@
13972 - n = read(fd, ptr, sizeof(*ptr));
13973 + n = os_read_file(fd, ptr, sizeof(*ptr));
13975 - if(n == 0) return(0);
13976 - else if(n != sizeof(*ptr)){
13977 - printk("Reading /proc/cpuinfo failed, "
13978 - "errno = %d\n", errno);
13980 + if(n != sizeof(*ptr)){
13981 + if(n == 0) return(0);
13982 + printk("Reading /proc/cpuinfo failed, err = %d\n", -n);
13988 } while((c != '\n') && (c != stop) && (ptr < end));
13990 @@ -45,45 +48,79 @@
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)
13997 - char buf[MAXTOKEN], c;
13998 - int fd, len = sizeof(buf)/sizeof(buf[0]), n;
14000 - printk("Checking for host processor %s support...", feature);
14001 - fd = open("/proc/cpuinfo", O_RDONLY);
14003 - printk("Couldn't open /proc/cpuinfo, errno = %d\n", errno);
14010 - buf[len - 1] = '\0';
14011 + scratch[len - 1] = '\0';
14013 - c = token(fd, buf, len - 1, ':');
14014 - if(c <= 0) goto out;
14015 + c = token(fd, scratch, len - 1, ':');
14019 printk("Failed to find ':' in /proc/cpuinfo\n");
14024 - if(!strncmp(buf, "flags", strlen("flags"))) break;
14025 + if(!strncmp(scratch, key, strlen(key)))
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",
14036 + "/proc/cpuinfo, err = %d\n", -n);
14039 } while(c != '\n');
14044 +int cpu_feature(char *what, char *buf, int len)
14048 + fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
14050 + printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
14054 + if(!find_cpuinfo_line(fd, what, buf, len)){
14055 + printk("Couldn't find '%s' line in /proc/cpuinfo\n", what);
14059 + token(fd, buf, len, '\n');
14063 + os_close_file(fd);
14067 +static int check_cpu_flag(char *feature, int *have_it)
14069 + char buf[MAXTOKEN], c;
14070 + int fd, len = sizeof(buf)/sizeof(buf[0]);
14072 + printk("Checking for host processor %s support...", feature);
14073 + fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
14075 + printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
14080 + if(!find_cpuinfo_line(fd, "flags", buf, sizeof(buf) / sizeof(buf[0])))
14083 c = token(fd, buf, len - 1, ' ');
14084 if(c < 0) goto out;
14086 - printk("Failed to find ':' in /proc/cpuinfo\n");
14087 + printk("Failed to find ' ' in /proc/cpuinfo\n");
14091 @@ -100,21 +137,48 @@
14093 if(*have_it == 0) printk("No\n");
14094 else if(*have_it == 1) printk("Yes\n");
14096 + os_close_file(fd);
14100 +#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems
14101 + * for some people.
14103 +static void disable_lcall(void)
14105 + struct modify_ldt_ldt_s ldt;
14108 + bzero(&ldt, sizeof(ldt));
14109 + ldt.entry_number = 7;
14110 + ldt.base_addr = 0;
14112 + err = modify_ldt(1, &ldt, sizeof(ldt));
14114 + printk("Failed to disable lcall7 - errno = %d\n", errno);
14118 +void arch_init_thread(void)
14125 void arch_check_bugs(void)
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 "
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;
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))
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 "
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 "
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 "
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);
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
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
14176 obj-$(CONFIG_HIGHMEM) += highmem.o
14177 +obj-$(CONFIG_MODULES) += module.o
14179 USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
14180 USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
14182 SYMLINKS = semaphore.c highmem.c module.c
14183 SYMLINKS := $(foreach f,$(SYMLINKS),$(src)/$f)
14185 +clean-files := $(SYMLINKS)
14187 semaphore.c-dir = kernel
14189 module.c-dir = kernel
14192 $(call make_link,$@)
14195 - $(MAKE) -C util clean
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],
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);
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);
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
14231 + * sys-i386/time.c
14232 + * Created 25.9.2002 Sapan Bhatia
14236 +unsigned long long time_stamp(void)
14238 + unsigned long low, high;
14240 + asm("rdtsc" : "=a" (low), "=d" (high));
14241 + return((((unsigned long long) high) << 32) + low);
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
14249 + * ---------------------------------------------------------------------------
14250 + * Local variables:
14251 + * c-file-style: "linux"
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
14258 mk_sc-objs := mk_sc.o
14260 $(obj)/mk_thread : $(obj)/mk_thread_kern.o $(obj)/mk_thread_user.o
14261 - $(CC) $(CFLAGS) -o $@ $^
14262 + $(HOSTCC) $(CFLAGS) -o $@ $^
14264 $(obj)/mk_thread_user.o : $(src)/mk_thread_user.c
14265 - $(CC) $(USER_CFLAGS) -c -o $@ $<
14266 + $(HOSTCC) $(USER_CFLAGS) -c -o $@ $<
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
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
14286 . = START + SIZEOF_HEADERS;
14289 __binary_start = .;
14291 .thread_private : {
14293 . = ALIGN(4096); /* Init code and data */
14296 - .text.init : { *(.text.init) }
14307 #include "asm/common.lds.S"
14309 - .data.init : { *(.data.init) }
14310 + init.data : { *(init.data) }
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
14318 mk_constants_user.o mk_constants_kern.o
14320 $(obj)/mk_task: $(obj)/mk_task_user.o $(obj)/mk_task_kern.o
14322 + $(HOSTCC) -o $@ $^
14324 $(obj)/mk_task_user.o: $(src)/mk_task_user.c
14325 - $(CC) -o $@ -c $<
14326 + $(HOSTCC) -o $@ -c $<
14328 $(obj)/mk_constants : $(obj)/mk_constants_user.o $(obj)/mk_constants_kern.o
14330 + $(HOSTCC) -o $@ $^
14332 $(obj)/mk_constants_user.o : $(src)/mk_constants_user.c
14333 - $(CC) -c $< -o $@
14334 + $(HOSTCC) -c $< -o $@
14336 $(obj)/mk_constants_kern.o : $(src)/mk_constants_kern.c
14337 - $(CC) $(CFLAGS) -c $< -o $@
14338 + $(HOSTCC) $(CFLAGS) -c $< -o $@
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
14346 #include "linux/kernel.h"
14347 #include "linux/stringify.h"
14348 +#include "linux/time.h"
14349 #include "asm/page.h"
14351 extern void print_head(void);
14355 print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
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);
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);
14365 + print_constant_int("UM_NSEC_PER_SEC", NSEC_PER_SEC);
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;
14376 +static int tty_initialized;
14379 * Ok, now we can initialize the rest of the tty devices and can count
14380 * on memory allocations, interrupts etc..
14382 -static int __init tty_init(void)
14383 +int __init tty_init(void)
14385 + if (tty_initialized)
14387 + tty_initialized = 1;
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
14396 +#ifndef __UM_FS_HOSTFS
14397 +#define __UM_FS_HOSTFS
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.
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
14417 +struct hostfs_iattr {
14418 + unsigned int ia_valid;
14423 + struct timespec ia_atime;
14424 + struct timespec ia_mtime;
14425 + struct timespec ia_ctime;
14426 + unsigned int ia_attr_flags;
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,
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);
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
14470 + * ---------------------------------------------------------------------------
14471 + * Local variables:
14472 + * c-file-style: "linux"
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
14480 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
14481 + * Licensed under the GPL
14483 + * Ported the filesystem routines to 2.5.
14484 + * 2003-02-10 Petr Baudis <pasky@ucw.cz>
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"
14503 +#include "user_util.h"
14504 +#include "2_5compat.h"
14507 +struct hostfs_inode_info {
14508 + char *host_filename;
14511 + struct inode vfs_inode;
14514 +static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
14516 + return(list_entry(inode, struct hostfs_inode_info, vfs_inode));
14519 +#define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_dentry->d_inode)
14521 +int hostfs_d_delete(struct dentry *dentry)
14526 +struct dentry_operations hostfs_dentry_ops = {
14527 + .d_delete = hostfs_d_delete,
14530 +/* Changed in hostfs_args before the kernel starts running */
14531 +static char *root_ino = "/";
14532 +static int append = 0;
14534 +#define HOSTFS_SUPER_MAGIC 0x00c0ffee
14536 +static struct inode_operations hostfs_iops;
14537 +static struct inode_operations hostfs_dir_iops;
14538 +static struct address_space_operations hostfs_link_aops;
14540 +static int __init hostfs_args(char *options, int *add)
14544 + ptr = strchr(options, ',');
14547 + if(*options != '\0')
14548 + root_ino = options;
14552 + ptr = strchr(options, ',');
14555 + if(*options != '\0'){
14556 + if(!strcmp(options, "append"))
14558 + else printf("hostfs_args - unsupported option - %s\n",
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"
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"
14577 +static char *dentry_name(struct dentry *dentry, int extra)
14579 + struct dentry *parent;
14580 + char *root, *name;
14585 + while(parent->d_parent != parent){
14586 + len += parent->d_name.len + 1;
14587 + parent = parent->d_parent;
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);
14595 + name[len] = '\0';
14597 + while(parent->d_parent != parent){
14598 + len -= parent->d_name.len + 1;
14600 + strncpy(&name[len + 1], parent->d_name.name,
14601 + parent->d_name.len);
14602 + parent = parent->d_parent;
14604 + strncpy(name, root, strlen(root));
14608 +static char *inode_name(struct inode *ino, int extra)
14610 + struct dentry *dentry;
14612 + dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
14613 + return(dentry_name(dentry, extra));
14616 +static int read_name(struct inode *ino, char *name)
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
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;
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);
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()))
14645 +static char *follow_link(char *link)
14648 + char *name, *resolved, *end;
14653 + name = kmalloc(len, GFP_KERNEL);
14657 + n = do_readlink(link, name, len);
14669 + end = strrchr(link, '/');
14673 + *(end + 1) = '\0';
14674 + len = strlen(link) + strlen(name) + 1;
14676 + resolved = kmalloc(len, GFP_KERNEL);
14677 + if(resolved == NULL){
14682 + sprintf(resolved, "%s%s", link, name);
14685 + return(resolved);
14690 + return(ERR_PTR(n));
14693 +static int read_inode(struct inode *ino)
14698 + /* Unfortunately, we are called from iget() when we don't have a dentry
14701 + if(list_empty(&ino->i_dentry))
14705 + name = inode_name(ino, 0);
14709 + if(file_type(name, NULL) == OS_TYPE_SYMLINK){
14710 + name = follow_link(name);
14711 + if(IS_ERR(name)){
14712 + err = PTR_ERR(name);
14717 + err = read_name(ino, name);
14723 +int hostfs_statfs(struct super_block *sb, struct kstatfs *sf)
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
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;
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;
14750 +static struct inode *hostfs_alloc_inode(struct super_block *sb)
14752 + struct hostfs_inode_info *hi;
14754 + hi = kmalloc(sizeof(*hi), GFP_KERNEL);
14758 + *hi = ((struct hostfs_inode_info) { .host_filename = NULL,
14761 + inode_init_once(&hi->vfs_inode);
14762 + return(&hi->vfs_inode);
14765 +static void hostfs_destroy_inode(struct inode *inode)
14767 + if(HOSTFS_I(inode)->host_filename)
14768 + kfree(HOSTFS_I(inode)->host_filename);
14770 + if(HOSTFS_I(inode)->fd != -1)
14771 + close_file(&HOSTFS_I(inode)->fd);
14773 + kfree(HOSTFS_I(inode));
14776 +static void hostfs_read_inode(struct inode *inode)
14778 + read_inode(inode);
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,
14788 +int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
14792 + unsigned long long next, ino;
14795 + name = dentry_name(file->f_dentry, 0);
14796 + if(name == NULL) return(-ENOMEM);
14797 + dir = open_dir(name, &error);
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);
14805 + file->f_pos = next;
14811 +int hostfs_file_open(struct inode *ino, struct file *file)
14814 + int mode = 0, r = 0, w = 0, fd;
14816 + mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
14817 + if((mode & HOSTFS_I(ino)->mode) == mode)
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.
14823 + if(HOSTFS_I(ino)->fd != -1){
14824 + close_file(&HOSTFS_I(ino)->fd);
14825 + HOSTFS_I(ino)->fd = -1;
14828 + HOSTFS_I(ino)->mode |= mode;
14829 + if(HOSTFS_I(ino)->mode & FMODE_READ)
14831 + if(HOSTFS_I(ino)->mode & FMODE_WRITE)
14836 + name = dentry_name(file->f_dentry, 0);
14840 + fd = open_file(name, r, w, append);
14842 + if(fd < 0) return(fd);
14843 + FILE_HOSTFS_I(file)->fd = fd;
14848 +int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
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,
14860 + .fsync = hostfs_fsync,
14863 +static struct file_operations hostfs_dir_fops = {
14864 + .readdir = hostfs_readdir,
14865 + .read = generic_read_dir,
14868 +int hostfs_writepage(struct page *page, struct writeback_control *wbc)
14870 + struct address_space *mapping = page->mapping;
14871 + struct inode *inode = mapping->host;
14873 + unsigned long long base;
14874 + int count = PAGE_CACHE_SIZE;
14875 + int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
14878 + if (page->index >= end_index)
14879 + count = inode->i_size & (PAGE_CACHE_SIZE-1);
14881 + buffer = kmap(page);
14882 + base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
14884 + err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
14885 + if(err != count){
14886 + ClearPageUptodate(page);
14890 + if (base > inode->i_size)
14891 + inode->i_size = base;
14893 + if (PageError(page))
14894 + ClearPageError(page);
14900 + unlock_page(page);
14904 +int hostfs_readpage(struct file *file, struct page *page)
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;
14916 + memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
14918 + flush_dcache_page(page);
14919 + SetPageUptodate(page);
14920 + if (PageError(page)) ClearPageError(page);
14924 + unlock_page(page);
14928 +int hostfs_prepare_write(struct file *file, struct page *page,
14929 + unsigned int from, unsigned int to)
14932 + long long start, tmp;
14935 + start = (long long) page->index << PAGE_CACHE_SHIFT;
14936 + buffer = kmap(page);
14939 + err = read_file(FILE_HOSTFS_I(file)->fd, &tmp, buffer,
14941 + if(err < 0) goto out;
14943 + if(to != PAGE_CACHE_SIZE){
14945 + err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer + to,
14946 + PAGE_CACHE_SIZE - to);
14947 + if(err < 0) goto out;
14955 +int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
14958 + struct address_space *mapping = page->mapping;
14959 + struct inode *inode = mapping->host;
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,
14968 + if(err > 0) err = 0;
14969 + if(!err && (start > inode->i_size))
14970 + inode->i_size = start;
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
14984 +static int init_inode(struct inode *inode, struct dentry *dentry)
14987 + int type, err = -ENOMEM, rdev;
14990 + name = dentry_name(dentry, 0);
14993 + type = file_type(name, &rdev);
14996 + else type = OS_TYPE_DIR;
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;
15005 + if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
15006 + else inode->i_fop = &hostfs_file_fops;
15008 + if(type == OS_TYPE_SYMLINK)
15009 + inode->i_mapping->a_ops = &hostfs_link_aops;
15010 + else inode->i_mapping->a_ops = &hostfs_aops;
15013 + case OS_TYPE_CHARDEV:
15014 + init_special_inode(inode, S_IFCHR, rdev);
15016 + case OS_TYPE_BLOCKDEV:
15017 + init_special_inode(inode, S_IFBLK, rdev);
15019 + case OS_TYPE_FIFO:
15020 + init_special_inode(inode, S_IFIFO, 0);
15022 + case OS_TYPE_SOCK:
15023 + init_special_inode(inode, S_IFSOCK, 0);
15030 +int hostfs_create(struct inode *dir, struct dentry *dentry, int mode,
15031 + struct nameidata *nd)
15033 + struct inode *inode;
15038 + inode = iget(dir->i_sb, 0);
15039 + if(inode == NULL) goto out;
15041 + error = init_inode(inode, dentry);
15046 + name = dentry_name(dentry, 0);
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);
15056 + else error = read_name(inode, name);
15062 + HOSTFS_I(inode)->fd = fd;
15063 + HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
15064 + d_instantiate(dentry, inode);
15073 +struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
15074 + struct nameidata *nd)
15076 + struct inode *inode;
15081 + inode = iget(ino->i_sb, 0);
15082 + if(inode == NULL)
15085 + err = init_inode(inode, dentry);
15090 + name = dentry_name(dentry, 0);
15094 + err = read_name(inode, name);
15096 + if(err == -ENOENT){
15103 + d_add(dentry, inode);
15104 + dentry->d_op = &hostfs_dentry_ops;
15110 + return(ERR_PTR(err));
15113 +static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
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';
15127 +int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
15129 + char *from_name, *to_name;
15132 + if((from_name = inode_dentry_name(ino, from)) == NULL)
15134 + to_name = dentry_name(to, 0);
15135 + if(to_name == NULL){
15136 + kfree(from_name);
15139 + err = link_file(to_name, from_name);
15140 + kfree(from_name);
15145 +int hostfs_unlink(struct inode *ino, struct dentry *dentry)
15150 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
15154 + err = unlink_file(file);
15159 +int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
15164 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
15165 + err = make_symlink(file, to);
15170 +int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
15175 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
15176 + err = do_mkdir(file, mode);
15181 +int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
15186 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
15187 + err = do_rmdir(file);
15192 +int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
15194 + struct inode *inode;
15196 + int err = -ENOMEM;
15198 + inode = iget(dir->i_sb, 0);
15199 + if(inode == NULL)
15202 + err = init_inode(inode, dentry);
15207 + name = dentry_name(dentry, 0);
15211 + init_special_inode(inode, mode, dev);
15212 + err = do_mknod(name, mode, dev);
15216 + err = read_name(inode, name);
15221 + d_instantiate(dentry, inode);
15232 +int hostfs_rename(struct inode *from_ino, struct dentry *from,
15233 + struct inode *to_ino, struct dentry *to)
15235 + char *from_name, *to_name;
15238 + if((from_name = inode_dentry_name(from_ino, from)) == NULL)
15240 + if((to_name = inode_dentry_name(to_ino, to)) == NULL){
15241 + kfree(from_name);
15244 + err = rename_file(from_name, to_name);
15245 + kfree(from_name);
15250 +void hostfs_truncate(struct inode *ino)
15252 + not_implemented();
15255 +int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
15258 + int r = 0, w = 0, x = 0, err;
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);
15267 + if(!err) err = vfs_permission(ino, desired);
15271 +int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
15273 + struct hostfs_iattr attrs;
15278 + attr->ia_valid &= ~ATTR_SIZE;
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;
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;
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;
15299 + if(attr->ia_valid & ATTR_SIZE){
15300 + attrs.ia_valid |= HOSTFS_ATTR_SIZE;
15301 + attrs.ia_size = attr->ia_size;
15303 + if(attr->ia_valid & ATTR_ATIME){
15304 + attrs.ia_valid |= HOSTFS_ATTR_ATIME;
15305 + attrs.ia_atime = attr->ia_atime;
15307 + if(attr->ia_valid & ATTR_MTIME){
15308 + attrs.ia_valid |= HOSTFS_ATTR_MTIME;
15309 + attrs.ia_mtime = attr->ia_mtime;
15311 + if(attr->ia_valid & ATTR_CTIME){
15312 + attrs.ia_valid |= HOSTFS_ATTR_CTIME;
15313 + attrs.ia_ctime = attr->ia_ctime;
15315 + if(attr->ia_valid & ATTR_ATIME_SET){
15316 + attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
15318 + if(attr->ia_valid & ATTR_MTIME_SET){
15319 + attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
15321 + name = dentry_name(dentry, 0);
15322 + if(name == NULL) return(-ENOMEM);
15323 + err = set_attr(name, &attrs);
15328 + return(inode_setattr(dentry->d_inode, attr));
15331 +int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
15332 + struct kstat *stat)
15334 + generic_fillattr(dentry->d_inode, stat);
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,
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,
15369 +int hostfs_link_readpage(struct file *file, struct page *page)
15371 + char *buffer, *name;
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);
15381 + if(err == PAGE_CACHE_SIZE)
15383 + else if(err > 0){
15384 + flush_dcache_page(page);
15385 + SetPageUptodate(page);
15386 + if (PageError(page)) ClearPageError(page);
15390 + unlock_page(page);
15394 +static struct address_space_operations hostfs_link_aops = {
15395 + .readpage = hostfs_link_readpage,
15398 +static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
15400 + struct inode *root_inode;
15401 + char *name, *data = d;
15404 + sb->s_blocksize = 1024;
15405 + sb->s_blocksize_bits = 10;
15406 + sb->s_magic = HOSTFS_SUPER_MAGIC;
15407 + sb->s_op = &hostfs_sbops;
15409 + if((data == NULL) || (*data == '\0'))
15413 + name = kmalloc(strlen(data) + 1, GFP_KERNEL);
15417 + strcpy(name, data);
15419 + root_inode = iget(sb, 0);
15420 + if(root_inode == NULL)
15423 + err = init_inode(root_inode, NULL);
15427 + HOSTFS_I(root_inode)->host_filename = name;
15430 + sb->s_root = d_alloc_root(root_inode);
15431 + if(sb->s_root == NULL)
15434 + err = read_inode(root_inode);
15441 + iput(root_inode);
15448 +static struct super_block *hostfs_read_sb(struct file_system_type *type,
15449 + int flags, const char *dev_name,
15452 + return(get_sb_nodev(type, flags, data, hostfs_fill_sb_common));
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,
15463 +static int __init init_hostfs(void)
15465 + return(register_filesystem(&hostfs_type));
15468 +static void __exit exit_hostfs(void)
15470 + unregister_filesystem(&hostfs_type);
15473 +module_init(init_hostfs)
15474 +module_exit(exit_hostfs)
15475 +MODULE_LICENSE("GPL");
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
15482 + * ---------------------------------------------------------------------------
15483 + * Local variables:
15484 + * c-file-style: "linux"
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
15492 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
15493 + * Licensed under the GPL
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"
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)
15516 + struct stat64 buf;
15518 + if(lstat64(path, &buf) < 0)
15521 + /* See the Makefile for why STAT64_INO_FIELD is passed in
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;
15534 + if(mtime_out != NULL) {
15535 + mtime_out->tv_sec = buf.st_mtime;
15536 + mtime_out->tv_nsec = 0;
15538 + if(ctime_out != NULL) {
15539 + ctime_out->tv_sec = buf.st_ctime;
15540 + ctime_out->tv_nsec = 0;
15542 + if(blksize_out != NULL) *blksize_out = buf.st_blksize;
15543 + if(blocks_out != NULL) *blocks_out = buf.st_blocks;
15547 +int file_type(const char *path, int *rdev)
15549 + struct stat64 buf;
15551 + if(lstat64(path, &buf) < 0)
15554 + *rdev = buf.st_rdev;
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);
15565 +int access_file(char *path, int r, int w, int x)
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);
15576 +int open_file(char *path, int r, int w, int append)
15578 + int mode = 0, fd;
15586 + else panic("Impossible mode in open_file");
15589 + mode |= O_APPEND;
15590 + fd = open64(path, mode);
15591 + if(fd < 0) return(-errno);
15595 +void *open_dir(char *path, int *err_out)
15599 + dir = opendir(path);
15600 + *err_out = errno;
15601 + if(dir == NULL) return(NULL);
15605 +char *read_dir(void *stream, unsigned long long *pos,
15606 + unsigned long long *ino_out, int *len_out)
15608 + DIR *dir = stream;
15609 + struct dirent *ent;
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);
15620 +int read_file(int fd, unsigned long long *offset, char *buf, int len)
15624 + n = pread64(fd, buf, len, *offset);
15625 + if(n < 0) return(-errno);
15630 +int write_file(int fd, unsigned long long *offset, const char *buf, int len)
15634 + n = pwrite64(fd, buf, len, *offset);
15635 + if(n < 0) return(-errno);
15640 +int lseek_file(int fd, long long offset, int whence)
15644 + ret = lseek64(fd, offset, whence);
15645 + if(ret < 0) return(-errno);
15649 +void close_file(void *stream)
15651 + close(*((int *) stream));
15654 +void close_dir(void *stream)
15656 + closedir(stream);
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)
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);
15680 +int set_attr(const char *file, struct hostfs_iattr *attrs)
15682 + struct utimbuf buf;
15685 + if(attrs->ia_valid & HOSTFS_ATTR_MODE){
15686 + if(chmod(file, attrs->ia_mode) != 0) return(-errno);
15688 + if(attrs->ia_valid & HOSTFS_ATTR_UID){
15689 + if(chown(file, attrs->ia_uid, -1)) return(-errno);
15691 + if(attrs->ia_valid & HOSTFS_ATTR_GID){
15692 + if(chown(file, -1, attrs->ia_gid)) return(-errno);
15694 + if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
15695 + if(truncate(file, attrs->ia_size)) return(-errno);
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);
15704 + struct timespec ts;
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);
15711 + buf.actime = attrs->ia_atime.tv_sec;
15712 + buf.modtime = ts.tv_sec;
15713 + if(utime(file, &buf) != 0)
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);
15721 + buf.actime = ts.tv_sec;
15722 + buf.modtime = attrs->ia_mtime.tv_sec;
15723 + if(utime(file, &buf) != 0)
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,
15732 + if(err != 0) return(err);
15737 +int make_symlink(const char *from, const char *to)
15741 + err = symlink(to, from);
15742 + if(err) return(-errno);
15746 +int unlink_file(const char *file)
15750 + err = unlink(file);
15751 + if(err) return(-errno);
15755 +int do_mkdir(const char *file, int mode)
15759 + err = mkdir(file, mode);
15760 + if(err) return(-errno);
15764 +int do_rmdir(const char *file)
15768 + err = rmdir(file);
15769 + if(err) return(-errno);
15773 +int do_mknod(const char *file, int mode, int dev)
15777 + err = mknod(file, mode, dev);
15778 + if(err) return(-errno);
15782 +int link_file(const char *to, const char *from)
15786 + err = link(to, from);
15787 + if(err) return(-errno);
15791 +int do_readlink(char *file, char *buf, int size)
15795 + n = readlink(file, buf, size);
15803 +int rename_file(char *from, char *to)
15807 + err = rename(from, to);
15808 + if(err < 0) return(-errno);
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,
15818 + struct statfs64 buf;
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];
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
15847 + * ---------------------------------------------------------------------------
15848 + * Local variables:
15849 + * c-file-style: "linux"
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
15857 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
15858 +# Licensed under the GPL
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.
15865 +STAT64_INO_FIELD := $(shell grep -q __st_ino /usr/include/bits/stat.h && \
15868 +hostfs-objs := hostfs_kern.o hostfs_user.o
15871 +obj-$(CONFIG_HOSTFS) += hostfs.o
15873 +SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
15875 +USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(SINGLE_OBJS))
15876 +USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
15878 +USER_CFLAGS += -DSTAT64_INO_FIELD=$(STAT64_INO_FIELD)
15880 +$(USER_OBJS) : %.o: %.c
15881 + $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
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
15897 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15898 + * Licensed under the GPL
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>
15914 +static int init_inode(struct inode *inode, struct dentry *dentry);
15916 +struct hppfs_data {
15917 + struct list_head list;
15918 + char contents[PAGE_SIZE - sizeof(struct list_head)];
15921 +struct hppfs_private {
15922 + struct file proc_file;
15925 + struct hppfs_data *contents;
15928 +struct hppfs_inode_info {
15929 + struct dentry *proc_dentry;
15930 + struct inode vfs_inode;
15933 +static inline struct hppfs_inode_info *HPPFS_I(struct inode *inode)
15935 + return(list_entry(inode, struct hppfs_inode_info, vfs_inode));
15938 +#define HPPFS_SUPER_MAGIC 0xb00000ee
15940 +static struct super_operations hppfs_sbops;
15942 +static int is_pid(struct dentry *dentry)
15944 + struct super_block *sb;
15947 + sb = dentry->d_sb;
15948 + if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
15951 + for(i = 0; i < dentry->d_name.len; i++){
15952 + if(!isdigit(dentry->d_name.name[i]))
15958 +static char *dentry_name(struct dentry *dentry, int extra)
15960 + struct dentry *parent;
15961 + char *root, *name;
15962 + const char *seg_name;
15963 + int len, seg_len;
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;
15975 + len += strlen(root);
15976 + name = kmalloc(len + extra + 1, GFP_KERNEL);
15977 + if(name == NULL) return(NULL);
15979 + name[len] = '\0';
15981 + while(parent->d_parent != parent){
15982 + if(is_pid(parent)){
15983 + seg_name = "pid";
15984 + seg_len = strlen("pid");
15987 + seg_name = parent->d_name.name;
15988 + seg_len = parent->d_name.len;
15991 + len -= seg_len + 1;
15993 + strncpy(&name[len + 1], seg_name, seg_len);
15994 + parent = parent->d_parent;
15996 + strncpy(name, root, strlen(root));
16000 +struct dentry_operations hppfs_dentry_ops = {
16003 +static int file_removed(struct dentry *dentry, const char *file)
16009 + if(file != NULL) extra += strlen(file) + 1;
16011 + host_file = dentry_name(dentry, extra + strlen("/remove"));
16012 + if(host_file == NULL){
16013 + printk("file_removed : allocation failed\n");
16017 + if(file != NULL){
16018 + strcat(host_file, "/");
16019 + strcat(host_file, file);
16021 + strcat(host_file, "/remove");
16023 + fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
16024 + kfree(host_file);
16026 + os_close_file(fd);
16032 +static void hppfs_read_inode(struct inode *ino)
16034 + struct inode *proc_ino;
16036 + if(HPPFS_I(ino)->proc_dentry == NULL)
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;
16053 +static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry,
16054 + struct nameidata *nd)
16056 + struct dentry *proc_dentry, *new, *parent;
16057 + struct inode *inode;
16058 + int err, deleted;
16060 + deleted = file_removed(dentry, NULL);
16062 + return(ERR_PTR(deleted));
16064 + return(ERR_PTR(-ENOENT));
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);
16076 + new = (*parent->d_inode->i_op->lookup)(parent->d_inode,
16077 + proc_dentry, NULL);
16079 + dput(proc_dentry);
16080 + proc_dentry = new;
16083 + up(&parent->d_inode->i_sem);
16085 + if(IS_ERR(proc_dentry))
16086 + return(proc_dentry);
16088 + inode = iget(ino->i_sb, 0);
16089 + if(inode == NULL)
16092 + err = init_inode(inode, proc_dentry);
16096 + hppfs_read_inode(inode);
16098 + d_add(dentry, inode);
16099 + dentry->d_op = &hppfs_dentry_ops;
16105 + dput(proc_dentry);
16107 + return(ERR_PTR(err));
16110 +static struct inode_operations hppfs_file_iops = {
16113 +static ssize_t read_proc(struct file *file, char *buf, ssize_t count,
16114 + loff_t *ppos, int is_user)
16116 + ssize_t (*read)(struct file *, char *, size_t, loff_t *);
16119 + read = file->f_dentry->d_inode->i_fop->read;
16122 + set_fs(KERNEL_DS);
16124 + n = (*read)(file, buf, count, &file->f_pos);
16129 + if(ppos) *ppos = file->f_pos;
16133 +static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
16140 + new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
16141 + if(new_buf == NULL){
16142 + printk("hppfs_read_file : kmalloc failed\n");
16146 + while(count > 0){
16147 + cur = min_t(ssize_t, count, PAGE_SIZE);
16148 + err = os_read_file(fd, new_buf, cur);
16150 + printk("hppfs_read : read failed, errno = %d\n",
16155 + else if(err == 0)
16158 + if(copy_to_user(buf, new_buf, err)){
16171 +static ssize_t hppfs_read(struct file *file, char *buf, size_t count,
16174 + struct hppfs_private *hppfs = file->private_data;
16175 + struct hppfs_data *data;
16179 + if(hppfs->contents != NULL){
16180 + if(*ppos >= hppfs->len) return(0);
16182 + data = hppfs->contents;
16184 + while(off >= sizeof(data->contents)){
16185 + data = list_entry(data->list.next, struct hppfs_data,
16187 + off -= sizeof(data->contents);
16190 + if(off + count > hppfs->len)
16191 + count = hppfs->len - off;
16192 + copy_to_user(buf, &data->contents[off], count);
16195 + else if(hppfs->host_fd != -1){
16196 + err = os_seek_file(hppfs->host_fd, *ppos);
16198 + printk("hppfs_read : seek failed, errno = %d\n", err);
16201 + count = hppfs_read_file(hppfs->host_fd, buf, count);
16205 + else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1);
16210 +static ssize_t hppfs_write(struct file *file, const char *buf, size_t len,
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 *);
16218 + write = proc_file->f_dentry->d_inode->i_fop->write;
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;
16227 +static int open_host_sock(char *host_file, int *filter_out)
16232 + end = &host_file[strlen(host_file)];
16233 + strcpy(end, "/rw");
16235 + fd = os_connect_socket(host_file);
16239 + strcpy(end, "/r");
16241 + fd = os_connect_socket(host_file);
16245 +static void free_contents(struct hppfs_data *head)
16247 + struct hppfs_data *data;
16248 + struct list_head *ele, *next;
16250 + if(head == NULL) return;
16252 + list_for_each_safe(ele, next, &head->list){
16253 + data = list_entry(ele, struct hppfs_data, list);
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)
16264 + struct hppfs_data *data, *new, *head;
16268 + data = kmalloc(sizeof(*data), GFP_KERNEL);
16269 + if(data == NULL){
16270 + printk("hppfs_get_data : head allocation failed\n");
16274 + INIT_LIST_HEAD(&data->list);
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);
16285 + printk("hppfs_get_data : failed to shut down "
16287 + goto failed_free;
16291 + n = os_read_file(fd, data->contents, sizeof(data->contents));
16294 + printk("hppfs_get_data : read failed, errno = %d\n",
16296 + goto failed_free;
16303 + if(n < sizeof(data->contents))
16306 + new = kmalloc(sizeof(*data), GFP_KERNEL);
16308 + printk("hppfs_get_data : data allocation failed\n");
16310 + goto failed_free;
16313 + INIT_LIST_HEAD(&new->list);
16314 + list_add(&new->list, &data->list);
16320 + free_contents(head);
16322 + return(ERR_PTR(err));
16325 +static struct hppfs_private *hppfs_data(void)
16327 + struct hppfs_private *data;
16329 + data = kmalloc(sizeof(*data), GFP_KERNEL);
16333 + *data = ((struct hppfs_private ) { .host_fd = -1,
16335 + .contents = NULL } );
16339 +static int file_mode(int fmode)
16341 + if(fmode == (FMODE_READ | FMODE_WRITE))
16343 + if(fmode == FMODE_READ)
16344 + return(O_RDONLY);
16345 + if(fmode == FMODE_WRITE)
16346 + return(O_WRONLY);
16350 +static int hppfs_open(struct inode *inode, struct file *file)
16352 + struct hppfs_private *data;
16353 + struct dentry *proc_dentry;
16355 + int err, fd, type, filter;
16358 + data = hppfs_data();
16362 + host_file = dentry_name(file->f_dentry, strlen("/rw"));
16363 + if(host_file == NULL)
16366 + proc_dentry = HPPFS_I(inode)->proc_dentry;
16368 + /* XXX This isn't closed anywhere */
16369 + err = open_private_file(&data->proc_file, proc_dentry,
16370 + file_mode(file->f_mode));
16374 + type = os_file_type(host_file);
16375 + if(type == OS_TYPE_FILE){
16376 + fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
16378 + data->host_fd = fd;
16379 + else printk("hppfs_open : failed to open '%s', errno = %d\n",
16382 + data->contents = NULL;
16384 + else if(type == OS_TYPE_DIR){
16385 + fd = open_host_sock(host_file, &filter);
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;
16393 + else printk("hppfs_open : failed to open a socket in "
16394 + "'%s', errno = %d\n", host_file, -fd);
16396 + kfree(host_file);
16398 + file->private_data = data;
16402 + kfree(host_file);
16404 + free_contents(data->contents);
16410 +static int hppfs_dir_open(struct inode *inode, struct file *file)
16412 + struct hppfs_private *data;
16413 + struct dentry *proc_dentry;
16417 + data = hppfs_data();
16421 + proc_dentry = HPPFS_I(inode)->proc_dentry;
16422 + err = open_private_file(&data->proc_file, proc_dentry,
16423 + file_mode(file->f_mode));
16427 + file->private_data = data;
16436 +static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
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);
16443 + llseek = proc_file->f_dentry->d_inode->i_fop->llseek;
16444 + if(llseek != NULL){
16445 + ret = (*llseek)(proc_file, off, where);
16450 + return(default_llseek(file, off, where));
16453 +static struct file_operations hppfs_file_fops = {
16455 + .llseek = hppfs_llseek,
16456 + .read = hppfs_read,
16457 + .write = hppfs_write,
16458 + .open = hppfs_open,
16461 +struct hppfs_dirent {
16462 + void *vfs_dirent;
16463 + filldir_t filldir;
16464 + struct dentry *dentry;
16467 +static int hppfs_filldir(void *d, const char *name, int size,
16468 + loff_t offset, ino_t inode, unsigned int type)
16470 + struct hppfs_dirent *dirent = d;
16472 + if(file_removed(dirent->dentry, name))
16475 + return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset,
16479 +static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
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 } );
16490 + readdir = proc_file->f_dentry->d_inode->i_fop->readdir;
16492 + proc_file->f_pos = file->f_pos;
16493 + err = (*readdir)(proc_file, &dirent, hppfs_filldir);
16494 + file->f_pos = proc_file->f_pos;
16499 +static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
16504 +static struct file_operations hppfs_dir_fops = {
16506 + .readdir = hppfs_readdir,
16507 + .open = hppfs_dir_open,
16508 + .fsync = hppfs_fsync,
16511 +static int hppfs_statfs(struct super_block *sb, struct kstatfs *sf)
16513 + sf->f_blocks = 0;
16515 + sf->f_bavail = 0;
16518 + sf->f_type = HPPFS_SUPER_MAGIC;
16522 +static struct inode *hppfs_alloc_inode(struct super_block *sb)
16524 + struct hppfs_inode_info *hi;
16526 + hi = kmalloc(sizeof(*hi), GFP_KERNEL);
16530 + *hi = ((struct hppfs_inode_info) { .proc_dentry = NULL });
16531 + inode_init_once(&hi->vfs_inode);
16532 + return(&hi->vfs_inode);
16535 +void hppfs_delete_inode(struct inode *ino)
16537 + clear_inode(ino);
16540 +static void hppfs_destroy_inode(struct inode *inode)
16542 + kfree(HPPFS_I(inode));
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,
16553 +static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen)
16555 + struct file proc_file;
16556 + struct dentry *proc_dentry;
16557 + int (*readlink)(struct dentry *, char *, int);
16560 + proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
16561 + err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
16565 + readlink = proc_dentry->d_inode->i_op->readlink;
16566 + n = (*readlink)(proc_dentry, buffer, buflen);
16568 + close_private_file(&proc_file);
16573 +static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
16575 + struct file proc_file;
16576 + struct dentry *proc_dentry;
16577 + int (*follow_link)(struct dentry *, struct nameidata *);
16580 + proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
16581 + err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
16585 + follow_link = proc_dentry->d_inode->i_op->follow_link;
16586 + n = (*follow_link)(proc_dentry, nd);
16588 + close_private_file(&proc_file);
16593 +static struct inode_operations hppfs_dir_iops = {
16594 + .lookup = hppfs_lookup,
16597 +static struct inode_operations hppfs_link_iops = {
16598 + .readlink = hppfs_readlink,
16599 + .follow_link = hppfs_follow_link,
16602 +static int init_inode(struct inode *inode, struct dentry *dentry)
16604 + if(S_ISDIR(dentry->d_inode->i_mode)){
16605 + inode->i_op = &hppfs_dir_iops;
16606 + inode->i_fop = &hppfs_dir_fops;
16608 + else if(S_ISLNK(dentry->d_inode->i_mode)){
16609 + inode->i_op = &hppfs_link_iops;
16610 + inode->i_fop = &hppfs_file_fops;
16613 + inode->i_op = &hppfs_file_iops;
16614 + inode->i_fop = &hppfs_file_fops;
16617 + HPPFS_I(inode)->proc_dentry = dentry;
16622 +static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
16624 + struct inode *root_inode;
16625 + struct file_system_type *procfs;
16626 + struct super_block *proc_sb;
16630 + procfs = get_fs_type("proc");
16631 + if(procfs == NULL)
16634 + if(list_empty(&procfs->fs_supers))
16637 + proc_sb = list_entry(procfs->fs_supers.next, struct super_block,
16640 + sb->s_blocksize = 1024;
16641 + sb->s_blocksize_bits = 10;
16642 + sb->s_magic = HPPFS_SUPER_MAGIC;
16643 + sb->s_op = &hppfs_sbops;
16645 + root_inode = iget(sb, 0);
16646 + if(root_inode == NULL)
16649 + err = init_inode(root_inode, proc_sb->s_root);
16654 + sb->s_root = d_alloc_root(root_inode);
16655 + if(sb->s_root == NULL)
16658 + hppfs_read_inode(root_inode);
16663 + iput(root_inode);
16668 +static struct super_block *hppfs_read_super(struct file_system_type *type,
16669 + int flags, const char *dev_name,
16672 + return(get_sb_nodev(type, flags, data, hppfs_fill_super));
16675 +static struct file_system_type hppfs_type = {
16676 + .owner = THIS_MODULE,
16678 + .get_sb = hppfs_read_super,
16679 + .kill_sb = kill_anon_super,
16683 +static int __init init_hppfs(void)
16685 + return(register_filesystem(&hppfs_type));
16688 +static void __exit exit_hppfs(void)
16690 + unregister_filesystem(&hppfs_type);
16693 +module_init(init_hppfs)
16694 +module_exit(exit_hppfs)
16695 +MODULE_LICENSE("GPL");
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
16702 + * ---------------------------------------------------------------------------
16703 + * Local variables:
16704 + * c-file-style: "linux"
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
16712 +# Copyright (C) 2002, 2003 Jeff Dike (jdike@karaya.com)
16713 +# Licensed under the GPL
16716 +hppfs-objs := hppfs_kern.o
16719 +obj-$(CONFIG_HPPFS) += hppfs.o
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
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
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
16750 pr_reg[16] = PT_REGS_SS(regs); \
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;
16759 + * Architecture-neutral AT_ values in 0-17, leave some room
16760 + * for more of them, start the x86-specific ones at 32.
16762 +#define AT_SYSINFO 32
16763 +#define AT_SYSINFO_EHDR 33
16765 +#define ARCH_DLINFO \
16767 + NEW_AUX_ENT(AT_SYSINFO, VSYSCALL_ENTRY); \
16768 + NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE); \
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.
16779 +#define ELF_CORE_EXTRA_PHDRS (VSYSCALL_EHDR->e_phnum)
16780 +#define ELF_CORE_WRITE_EXTRA_PHDRS \
16782 + const struct elf_phdr *const vsyscall_phdrs = \
16783 + (const struct elf_phdr *) (VSYSCALL_BASE \
16784 + + VSYSCALL_EHDR->e_phoff); \
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; \
16794 + phdr.p_offset += ofs; \
16795 + phdr.p_paddr = 0; /* match other core phdrs */ \
16796 + DUMP_WRITE(&phdr, sizeof(phdr)); \
16799 +#define ELF_CORE_WRITE_EXTRA_DATA \
16801 + const struct elf_phdr *const vsyscall_phdrs = \
16802 + (const struct elf_phdr *) (VSYSCALL_BASE \
16803 + + VSYSCALL_EHDR->e_phoff); \
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); \
16812 /********* Bits for asm-um/delay.h **********/
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
16819 +#include <asm-generic/vmlinux.lds.h>
16821 .fini : { *(.fini) } =0x9090
16823 PROVIDE (etext = .);
16826 __initcall_end = .;
16828 + __con_initcall_start = .;
16829 + .con_initcall.init : { *(.con_initcall.init) }
16830 + __con_initcall_end = .;
16832 __uml_initcall_start = .;
16833 .uml.initcall.init : { *(.uml.initcall.init) }
16834 __uml_initcall_end = .;
16836 .uml.exitcall : { *(.uml.exitcall.exit) }
16837 __uml_exitcall_end = .;
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) }
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 = .;
16861 __initramfs_start = .;
16862 .init.ramfs : { *(.init.ramfs) }
16863 __initramfs_end = .;
16865 + /* Sections to be discarded */
16867 + *(.exitcall.exit)
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
16874 +#ifndef __UM_CPUFEATURE_H
16875 +#define __UM_CPUFEATURE_H
16877 +#include "asm/arch/cpufeature.h"
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
16884 #define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & \
16885 (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
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)); })
16892 +#define current (current_thread->task)
16894 #endif /* __ASSEMBLY__ */
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
16900 FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
16901 FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
16904 __end_of_fixed_addresses
16908 #define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
16909 #define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
16912 + * This is the range that is readable by user mode, and things
16913 + * acting like user mode such as get_user_pages.
16915 +#define FIXADDR_USER_START (__fix_to_virt(FIX_VSYSCALL))
16916 +#define FIXADDR_USER_END (FIXADDR_USER_START + PAGE_SIZE)
16918 extern void __this_fixmap_does_not_exist(void);
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
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.
16931 -struct task_struct;
16933 -#include "asm/ptrace.h"
16937 #define TIMER_IRQ 0
16939 #define CONSOLE_IRQ 2
16941 #define LAST_IRQ XTERM_IRQ
16942 #define NR_IRQS (LAST_IRQ + 1)
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,
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
16953 +#ifndef __UM_LOCAL_H
16954 +#define __UM_LOCAL_H
16956 +#include "asm/arch/local.h"
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
16963 +#ifndef __UM_MODULE_GENERIC_H
16964 +#define __UM_MODULE_GENERIC_H
16966 +#include "asm/arch/module.h"
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
16973 +#ifndef __UM_MODULE_I386_H
16974 +#define __UM_MODULE_I386_H
16976 +/* UML is simple */
16977 +struct mod_arch_specific
16981 +#define Elf_Shdr Elf32_Shdr
16982 +#define Elf_Sym Elf32_Sym
16983 +#define Elf_Ehdr Elf32_Ehdr
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
16991 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
16992 + * Licensed under the GPL
16995 #ifndef __UM_PAGE_H
16996 #define __UM_PAGE_H
17000 #include "asm/arch/page.h"
17001 -#include "asm/bug.h"
17005 @@ -24,25 +28,36 @@
17007 #define __va_space (8*1024*1024)
17009 -extern unsigned long region_pa(void *virt);
17010 -extern void *region_va(unsigned long phys);
17012 -#define __pa(virt) region_pa((void *) (virt))
17013 -#define __va(phys) region_va((unsigned long) (phys))
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);
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)
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))
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)
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)))
17037 extern struct page *arch_validate(struct page *page, int mask, int order);
17038 #define HAVE_ARCH_VALIDATE
17040 +extern void arch_free_page(struct page *page, int order);
17041 +#define HAVE_ARCH_FREE_PAGE
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
17050 + * ---------------------------------------------------------------------------
17051 + * Local variables:
17052 + * c-file-style: "linux"
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. ;)
17062 -extern unsigned long high_physmem;
17063 +extern unsigned long end_iomem;
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))
17069 #ifdef CONFIG_HIGHMEM
17070 # define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
17071 @@ -78,12 +78,13 @@
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
17089 #define REGION_MASK 0xf0000000
17090 #define REGION_SHIFT 28
17091 @@ -143,7 +144,8 @@
17093 #define BAD_PAGETABLE __bad_pagetable()
17094 #define BAD_PAGE __bad_page()
17095 -#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
17097 +#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
17099 /* number of bits that fit into a memory pointer */
17100 #define BITS_PER_PTR (8*sizeof(unsigned long))
17101 @@ -164,9 +166,6 @@
17103 #define pte_clear(xp) do { pte_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
17105 -#define phys_region_index(x) (((x) & REGION_MASK) >> REGION_SHIFT)
17106 -#define pte_region_index(x) phys_region_index(pte_val(x))
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 @@
17113 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
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);
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)
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))
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)
17137 + * Bits 0 through 3 are taken
17139 +#define PTE_FILE_MAX_BITS 28
17141 +#define pte_to_pgoff(pte) ((pte).pte_low >> 4)
17143 +#define pgoff_to_pte(off) \
17144 + ((pte_t) { ((off) << 4) + _PAGE_FILE })
17146 static inline pte_t pte_mknewprot(pte_t pte)
17148 @@ -235,6 +240,12 @@
17149 * The following only work if pte_present() is true.
17150 * Undefined behaviour if not..
17152 +static inline int pte_user(pte_t pte)
17154 + return((pte_val(pte) & _PAGE_USER) &&
17155 + !(pte_val(pte) & _PAGE_PROTNONE));
17158 static inline int pte_read(pte_t pte)
17160 return((pte_val(pte) & _PAGE_USER) &&
17161 @@ -252,6 +263,14 @@
17162 !(pte_val(pte) & _PAGE_PROTNONE));
17166 + * The following only works if pte_present() is not true.
17168 +static inline int pte_file(pte_t pte)
17170 + return (pte).pte_low & _PAGE_FILE;
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.
17180 -#define mk_pte(page, pgprot) \
17184 - pte_val(__pte) = page_to_phys(page) + pgprot_val(pgprot);\
17185 - if(pte_present(__pte)) pte_mknewprot(pte_mknewpage(__pte)); \
17188 +extern pte_t mk_pte(struct page *page, pgprot_t pgprot);
17190 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
17192 @@ -351,17 +363,27 @@
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)))
17199 -/* to find an entry in a page-table-directory. */
17201 + * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
17203 + * this macro returns the index of the entry in the pgd page which would
17204 + * control the given virtual address
17206 #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
17208 -/* to find an entry in a page-table-directory */
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;
17213 #define pgd_offset(mm, address) \
17214 ((mm)->pgd + ((address) >> PGDIR_SHIFT))
17216 -/* to find an entry in a kernel page-table-directory */
17219 + * a shortcut which implies the use of the kernel's pgd, instead
17222 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
17224 #define pmd_index(address) \
17225 @@ -373,7 +395,12 @@
17226 return (pmd_t *) dir;
17229 -/* Find an entry in the third-level page table.. */
17231 + * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
17233 + * this macro returns the index of the entry in the pte page which would
17234 + * control the given virtual address
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)
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)
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
17258 struct task_struct;
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"
17269 #define cpu_relax() do ; while (0)
17271 -#ifdef CONFIG_MODE_TT
17272 -struct proc_tt_mode {
17275 - int switch_pipe[2];
17276 - int singlestep_syscall;
17281 -#ifdef CONFIG_MODE_SKAS
17282 -struct proc_skas_mode {
17283 - void *switch_buf;
17288 struct thread_struct {
17290 unsigned long kernel_stack;
17292 struct pt_regs regs;
17295 + unsigned long trap_no;
17297 void *fault_catcher;
17298 struct task_struct *prev_sched;
17299 @@ -54,10 +36,20 @@
17300 struct arch_thread arch;
17302 #ifdef CONFIG_MODE_TT
17303 - struct proc_tt_mode tt;
17307 + int switch_pipe[2];
17308 + int singlestep_syscall;
17312 #ifdef CONFIG_MODE_SKAS
17313 - struct proc_skas_mode skas;
17315 + void *switch_buf;
17322 @@ -101,14 +93,19 @@
17325 extern struct task_struct *alloc_task_struct(void);
17326 -extern void free_task_struct(struct task_struct *task);
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);
17333 extern unsigned long thread_saved_pc(struct task_struct *t);
17335 +static inline void mm_copy_segments(struct mm_struct *from_mm,
17336 + struct mm_struct *new_mm)
17340 #define init_stack (init_thread_union.stack)
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
17347 #ifndef __UM_PROCESSOR_I386_H
17348 #define __UM_PROCESSOR_I386_H
17350 -extern int cpu_has_xmm;
17351 -extern int cpu_has_cmov;
17352 +extern int host_has_xmm;
17353 +extern int host_has_cmov;
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
17361 +#ifndef _UM_SECTIONS_H
17362 +#define _UM_SECTIONS_H
17364 +/* nothing to see, move along */
17365 +#include <asm-generic/sections.h>
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
17373 extern cpumask_t cpu_online_map;
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
17384 -#ifndef __UM_SPINLOCK_H
17385 -#define __UM_SPINLOCK_H
17387 -#include "linux/config.h"
17390 -#include "asm/arch/spinlock.h"
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
17398 extern void block_signals(void);
17399 extern void unblock_signals(void);
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)
17408 #define local_irq_save(flags) do { local_save_flags(flags); \
17409 local_irq_disable(); } while(0)
17414 +extern void *_switch_to(void *prev, void *next, void *last);
17415 +#define switch_to(prev, next, last) prev = _switch_to(prev, next, last)
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
17422 #ifndef __ASSEMBLY__
17424 #include <asm/processor.h>
17425 +#include <asm/types.h>
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)
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));
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)
17450 #define get_thread_info(ti) get_task_struct((ti)->task)
17451 #define put_thread_info(ti) put_task_struct((ti)->task)
17453 @@ -65,11 +69,13 @@
17454 #define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling
17457 +#define TIF_RESTART_BLOCK 4
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)
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
17471 #ifndef __UM_TIMEX_H
17472 #define __UM_TIMEX_H
17474 -#include "linux/time.h"
17476 typedef unsigned long cycles_t;
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
17483 #ifndef __UM_UACCESS_H
17484 #define __UM_UACCESS_H
17486 +#include "linux/sched.h"
17488 #define VERIFY_READ 0
17489 #define VERIFY_WRITE 1
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
17495 set_fs(KERNEL_DS); \
17501 + errno = -(long)ret; \
17504 static inline long open(const char *pathname, int flags, int mode)
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
17510 * For the normal case of non-DISCONTIGMEM systems the NODE_DATA() gets
17511 * optimized to &contig_page_data at compile-time.
17514 +#ifndef HAVE_ARCH_FREE_PAGE
17515 +static inline void arch_free_page(struct page *page, int order) { }
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)
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
17526 + * include/linux/ghash.h -- generic hashing with fuzzy retrieval
17528 + * (C) 1997 Thomas Schoebel-Theuer
17530 + * The algorithms implemented here seem to be a completely new invention,
17531 + * and I'll publish the fundamentals in a paper.
17536 +/* HASHSIZE _must_ be a power of two!!! */
17539 +#define DEF_HASH_FUZZY_STRUCTS(NAME,HASHSIZE,TYPE) \
17541 +struct NAME##_table {\
17542 + TYPE * hashtable[HASHSIZE];\
17543 + TYPE * sorted_list;\
17547 +struct NAME##_ptrs {\
17548 + TYPE * next_hash;\
17549 + TYPE * prev_hash;\
17550 + TYPE * next_sorted;\
17551 + TYPE * prev_sorted;\
17554 +#define DEF_HASH_FUZZY(LINKAGE,NAME,HASHSIZE,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,KEYEQ,HASHFN)\
17556 +LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
17558 + int ix = HASHFN(elem->KEY);\
17559 + TYPE ** base = &tbl->hashtable[ix];\
17560 + TYPE * ptr = *base;\
17561 + TYPE * prev = NULL;\
17563 + tbl->nr_entries++;\
17564 + while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\
17565 + base = &ptr->PTRS.next_hash;\
17569 + elem->PTRS.next_hash = ptr;\
17570 + elem->PTRS.prev_hash = prev;\
17572 + ptr->PTRS.prev_hash = elem;\
17578 + ptr = tbl->sorted_list;\
17581 + prev = ptr->PTRS.prev_sorted;\
17584 + TYPE * next = ptr->PTRS.next_hash;\
17585 + if(next && KEYCMP(next->KEY, elem->KEY)) {\
17588 + } else if(KEYCMP(ptr->KEY, elem->KEY)) {\
17590 + ptr = ptr->PTRS.next_sorted;\
17594 + elem->PTRS.next_sorted = ptr;\
17595 + elem->PTRS.prev_sorted = prev;\
17597 + ptr->PTRS.prev_sorted = elem;\
17600 + prev->PTRS.next_sorted = elem;\
17602 + tbl->sorted_list = elem;\
17606 +LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
17608 + TYPE * next = elem->PTRS.next_hash;\
17609 + TYPE * prev = elem->PTRS.prev_hash;\
17611 + tbl->nr_entries--;\
17613 + next->PTRS.prev_hash = prev;\
17615 + prev->PTRS.next_hash = next;\
17617 + int ix = HASHFN(elem->KEY);\
17618 + tbl->hashtable[ix] = next;\
17621 + next = elem->PTRS.next_sorted;\
17622 + prev = elem->PTRS.prev_sorted;\
17624 + next->PTRS.prev_sorted = prev;\
17626 + prev->PTRS.next_sorted = next;\
17628 + tbl->sorted_list = next;\
17631 +LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
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))\
17642 +LINKAGE TYPE * find_##NAME##_hash_fuzzy(struct NAME##_table * tbl, KEYTYPE pos)\
17649 + ptr = tbl->sorted_list;\
17650 + if(!ptr || KEYCMP(pos, ptr->KEY))\
17652 + ix = HASHFN(pos);\
17653 + offset = HASHSIZE;\
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))\
17660 + } while(offset);\
17663 + next = ptr->PTRS.next_hash;\
17665 + if(KEYCMP(next->KEY, pos)) {\
17670 + next = ptr->PTRS.next_sorted;\
17671 + if(next && KEYCMP(next->KEY, pos)) {\
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
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
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
17700 +#define DEF_HASH_STRUCTS(NAME,HASHSIZE,TYPE) \
17702 +struct NAME##_table {\
17703 + TYPE * hashtable[HASHSIZE];\
17707 +struct NAME##_ptrs {\
17708 + TYPE * next_hash;\
17709 + TYPE * prev_hash;\
17712 +#define DEF_HASH(LINKAGE,NAME,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,HASHFN)\
17714 +LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
17716 + int ix = HASHFN(elem->KEY);\
17717 + TYPE ** base = &tbl->hashtable[ix];\
17718 + TYPE * ptr = *base;\
17719 + TYPE * prev = NULL;\
17721 + tbl->nr_entries++;\
17722 + while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\
17723 + base = &ptr->PTRS.next_hash;\
17727 + elem->PTRS.next_hash = ptr;\
17728 + elem->PTRS.prev_hash = prev;\
17730 + ptr->PTRS.prev_hash = elem;\
17735 +LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
17737 + TYPE * next = elem->PTRS.next_hash;\
17738 + TYPE * prev = elem->PTRS.prev_hash;\
17740 + tbl->nr_entries--;\
17742 + next->PTRS.prev_hash = prev;\
17744 + prev->PTRS.next_hash = next;\
17746 + int ix = HASHFN(elem->KEY);\
17747 + tbl->hashtable[ix] = next;\
17751 +LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
17753 + int ix = HASHFN(pos);\
17754 + TYPE * ptr = tbl->hashtable[ix];\
17755 + while(ptr && KEYCMP(ptr->KEY, pos))\
17756 + ptr = ptr->PTRS.next_hash;\
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);
17768 +extern long do_mprotect(struct mm_struct *mm, unsigned long start,
17769 + size_t len, unsigned long prot);
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 @@
17776 extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
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);
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)
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);
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
17803 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17804 + * Licensed under the GPL
17807 +#ifndef __PROC_MM_H
17808 +#define __PROC_MM_H
17810 +#include "linux/sched.h"
17812 +#define MM_MMAP 54
17813 +#define MM_MUNMAP 55
17814 +#define MM_MPROTECT 56
17815 +#define MM_COPY_SEGMENTS 57
17818 + unsigned long addr;
17819 + unsigned long len;
17820 + unsigned long prot;
17821 + unsigned long flags;
17822 + unsigned long fd;
17823 + unsigned long offset;
17826 +struct mm_munmap {
17827 + unsigned long addr;
17828 + unsigned long len;
17831 +struct mm_mprotect {
17832 + unsigned long addr;
17833 + unsigned long len;
17834 + unsigned int prot;
17837 +struct proc_mm_op {
17840 + struct mm_mmap mmap;
17841 + struct mm_munmap munmap;
17842 + struct mm_mprotect mprotect;
17843 + int copy_segments;
17847 +extern struct mm_struct *proc_mm_get_mm(int fd);
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
17854 slab.o swap.o truncate.o vmscan.o $(mmu-y)
17856 obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o
17857 +obj-$(CONFIG_PROC_MM) += proc_mm.o
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
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>
17869 #include <asm/pgalloc.h>
17870 @@ -680,6 +681,24 @@
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
17879 + .vm_page_prot = PAGE_READONLY,
17880 + .vm_flags = VM_READ | VM_EXEC,
17883 +static int init_fixmap_vma(void)
17885 + fixmap_vma.vm_start = FIXADDR_START;
17886 + fixmap_vma.vm_end = FIXADDR_TOP;
17890 +__initcall(init_fixmap_vma);
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 @@
17897 vma = find_extend_vma(mm, start);
17899 -#ifdef FIXADDR_USER_START
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
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,
17912 +#ifdef FIXADDR_START
17913 + if (!vma && start >= FIXADDR_START && start < FIXADDR_TOP) {
17914 unsigned long pg = start & PAGE_MASK;
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).
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)
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 @@
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)
17947 unsigned long vm_flags, nstart, end, tmp;
17948 struct vm_area_struct * vma, * next, * prev;
17949 @@ -245,9 +246,9 @@
17951 vm_flags = calc_vm_prot_bits(prot);
17953 - down_write(¤t->mm->mmap_sem);
17954 + down_write(&mm->mmap_sem);
17956 - vma = find_vma_prev(current->mm, start, &prev);
17957 + vma = find_vma_prev(mm, start, &prev);
17961 @@ -326,6 +327,11 @@
17962 prev->vm_mm->map_count--;
17965 - up_write(¤t->mm->mmap_sem);
17966 + up_write(&mm->mmap_sem);
17970 +asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
17972 + return(do_mprotect(current->mm, start, len, prot));
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 @@
17981 + arch_free_page(page, order);
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
17991 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17992 + * Licensed under the GPL
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"
18003 +static struct file_operations proc_mm_fops;
18005 +struct mm_struct *proc_mm_get_mm(int fd)
18007 + struct mm_struct *ret = ERR_PTR(-EBADF);
18008 + struct file *file;
18014 + ret = ERR_PTR(-EINVAL);
18015 + if(file->f_op != &proc_mm_fops)
18018 + ret = file->private_data;
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);
18030 +static ssize_t write_proc_mm(struct file *file, const char *buffer,
18031 + size_t count, loff_t *ppos)
18033 + struct mm_struct *mm = file->private_data;
18034 + struct proc_mm_op req;
18037 + if(count > sizeof(req))
18040 + n = copy_from_user(&req, buffer, count);
18047 + struct mm_mmap *map = &req.u.mmap;
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)
18056 + case MM_MUNMAP: {
18057 + struct mm_munmap *unmap = &req.u.munmap;
18059 + down_write(&mm->mmap_sem);
18060 + ret = do_munmap(mm, unmap->addr, unmap->len);
18061 + up_write(&mm->mmap_sem);
18067 + case MM_MPROTECT: {
18068 + struct mm_mprotect *protect = &req.u.mprotect;
18070 + ret = do_mprotect(mm, protect->addr, protect->len,
18077 + case MM_COPY_SEGMENTS: {
18078 + struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
18080 + if(IS_ERR(from)){
18081 + ret = PTR_ERR(from);
18085 + mm_copy_segments(from, mm);
18096 +static int open_proc_mm(struct inode *inode, struct file *file)
18098 + struct mm_struct *mm = mm_alloc();
18105 + ret = init_new_context(current, mm);
18109 + spin_lock(&mmlist_lock);
18110 + list_add(&mm->mmlist, ¤t->mm->mmlist);
18112 + spin_unlock(&mmlist_lock);
18114 + file->private_data = mm;
18124 +static int release_proc_mm(struct inode *inode, struct file *file)
18126 + struct mm_struct *mm = file->private_data;
18132 +static struct file_operations proc_mm_fops = {
18133 + .open = open_proc_mm,
18134 + .release = release_proc_mm,
18135 + .write = write_proc_mm,
18138 +static int make_proc_mm(void)
18140 + struct proc_dir_entry *ent;
18142 + ent = create_proc_entry("mm", 0222, &proc_root);
18144 + printk("make_proc_mm : Failed to register /proc/mm\n");
18147 + ent->proc_fops = &proc_mm_fops;
18152 +__initcall(make_proc_mm);
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
18159 + * ---------------------------------------------------------------------------
18160 + * Local variables:
18161 + * c-file-style: "linux"