1 diff -Naur a/arch/um/config.release b/arch/um/config.release
2 --- a/arch/um/config.release 2004-02-11 12:16:48.000000000 -0500
3 +++ b/arch/um/config.release 2004-02-11 12:29:03.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-02-11 12:16:02.000000000 -0500
14 +++ b/arch/um/defconfig 2004-02-11 12:27:57.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-02-11 12:16:50.000000000 -0500
405 +++ b/arch/um/drivers/chan_kern.c 2004-02-11 12:29:06.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-02-11 12:14:14.000000000 -0500
456 +++ b/arch/um/drivers/chan_user.c 2004-02-11 12:25:42.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-02-11 12:26:08.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-02-11 12:29:06.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 + i,
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-02-11 12:27:42.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-02-11 12:27:36.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-02-11 12:15:11.000000000 -0500
1766 +++ b/arch/um/drivers/daemon_user.c 2004-02-11 12:26:57.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-02-11 12:16:47.000000000 -0500
1837 +++ b/arch/um/drivers/fd.c 2004-02-11 12:29:01.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-02-11 12:14:38.000000000 -0500
1850 +++ b/arch/um/drivers/harddog_user.c 2004-02-11 12:26:41.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-02-11 12:16:48.000000000 -0500
1969 +++ b/arch/um/drivers/hostaudio_kern.c 2004-02-11 12:29:03.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-02-11 12:16:08.000000000 -0500
2151 +++ b/arch/um/drivers/hostaudio_user.c 2004-02-11 12:28:04.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,
2180 size_t count, loff_t *ppos)
2185 printk("hostaudio: write_user called, count = %d\n", count);
2188 - ret = write(state->fd, buffer, count);
2190 - if(ret < 0) return(-errno);
2192 + return(os_write_file(state->fd, buffer, count));
2195 int hostaudio_ioctl_user(struct hostaudio_state *state, unsigned int cmd,
2200 printk("hostaudio: ioctl_user called, cmd = %u\n", cmd);
2203 - ret = ioctl(state->fd, cmd, arg);
2205 - if(ret < 0) return(-errno);
2207 + return(os_ioctl_generic(state->fd, cmd, arg));
2210 int hostaudio_open_user(struct hostaudio_state *state, int r, int w, char *dsp)
2212 printk("hostaudio: open_user called\n");
2215 - state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
2217 - if(state->fd >= 0) return(0);
2218 + state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
2220 - printk("hostaudio_open_user failed to open '%s', errno = %d\n",
2222 + if(state->fd < 0) {
2223 + printk("hostaudio_open_user failed to open '%s', err = %d\n",
2225 + return(state->fd);
2232 int hostaudio_release_user(struct hostaudio_state *state)
2235 printk("hostaudio: release called\n");
2237 - if(state->fd >= 0){
2241 + if(state->fd >= 0){
2242 + os_close_file(state->fd);
2249 int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state,
2250 unsigned int cmd, unsigned long arg)
2254 printk("hostmixer: ioctl_user called cmd = %u\n",cmd);
2257 - ret = ioctl(state->fd, cmd, arg);
2261 + return(os_ioctl_generic(state->fd, cmd, arg));
2264 int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, int w,
2265 @@ -115,12 +95,13 @@
2267 state->fd = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
2269 - if(state->fd >= 0) return(0);
2271 - printk("hostaudio_open_mixdev_user failed to open '%s', errno = %d\n",
2273 + if(state->fd < 0) {
2274 + printk("hostaudio_open_mixdev_user failed to open '%s', "
2275 + "err = %d\n", mixer, state->fd);
2276 + return(state->fd);
2283 int hostmixer_release_mixdev_user(struct hostmixer_state *state)
2289 + os_close_file(state->fd);
2293 diff -Naur a/arch/um/drivers/line.c b/arch/um/drivers/line.c
2294 --- a/arch/um/drivers/line.c 2004-02-11 12:16:38.000000000 -0500
2295 +++ b/arch/um/drivers/line.c 2004-02-11 12:28:38.000000000 -0500
2297 #include "linux/sched.h"
2298 #include "linux/slab.h"
2299 #include "linux/list.h"
2300 +#include "linux/interrupt.h"
2301 #include "linux/devfs_fs_kernel.h"
2302 -#include "asm/irq.h"
2303 #include "asm/uaccess.h"
2304 #include "chan_kern.h"
2305 #include "irq_user.h"
2307 #include "user_util.h"
2308 #include "kern_util.h"
2310 +#include "irq_kern.h"
2312 #define LINE_BUFSIZE 4096
2314 -void line_interrupt(int irq, void *data, struct pt_regs *unused)
2315 +static irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused)
2317 struct line *dev = data;
2320 chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq,
2322 + return IRQ_HANDLED;
2325 -void line_timer_cb(void *arg)
2326 +static void line_timer_cb(void *arg)
2328 struct line *dev = arg;
2330 line_interrupt(dev->driver->read_irq, dev, NULL);
2333 -static void buffer_data(struct line *line, const char *buf, int len)
2334 +static int write_room(struct line *dev)
2339 + if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
2341 + n = dev->head - dev->tail;
2342 + if(n <= 0) n = LINE_BUFSIZE + n;
2346 +static int buffer_data(struct line *line, const char *buf, int len)
2350 if(line->buffer == NULL){
2351 line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC);
2352 if(line->buffer == NULL){
2353 printk("buffer_data - atomic allocation failed\n");
2357 line->head = line->buffer;
2358 line->tail = line->buffer;
2361 + room = write_room(line);
2362 + len = (len > room) ? room : len;
2364 end = line->buffer + LINE_BUFSIZE - line->tail;
2366 memcpy(line->tail, buf, len);
2368 memcpy(line->buffer, buf, len);
2369 line->tail = line->buffer + len;
2375 static int flush_buffer(struct line *line)
2379 unsigned long flags;
2381 + int n, err, i, ret = 0;
2383 if(tty->stopped) return 0;
2385 @@ -104,9 +123,13 @@
2388 n = copy_from_user(new, buf, len);
2401 @@ -115,41 +138,50 @@
2403 if(line->head != line->tail){
2404 local_irq_save(flags);
2405 - buffer_data(line, buf, len);
2406 + ret += buffer_data(line, buf, len);
2407 err = flush_buffer(line);
2408 local_irq_restore(flags);
2414 n = write_chan(&line->chan_list, buf, len,
2415 line->driver->write_irq);
2423 - buffer_data(line, buf + n, len - n);
2428 + ret += buffer_data(line, buf + n, len);
2440 -void line_write_interrupt(int irq, void *data, struct pt_regs *unused)
2441 +static irqreturn_t line_write_interrupt(int irq, void *data,
2442 + struct pt_regs *unused)
2444 struct line *dev = data;
2445 struct tty_struct *tty = dev->tty;
2448 err = flush_buffer(dev);
2449 - if(err == 0) return;
2453 dev->head = dev->buffer;
2454 dev->tail = dev->buffer;
2457 - if(tty == NULL) return;
2461 if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
2462 (tty->ldisc.write_wakeup != NULL))
2463 @@ -161,21 +193,9 @@
2467 - if (waitqueue_active(&tty->write_wait))
2468 + if(waitqueue_active(&tty->write_wait))
2469 wake_up_interruptible(&tty->write_wait);
2473 -int line_write_room(struct tty_struct *tty)
2475 - struct line *dev = tty->driver_data;
2478 - if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
2480 - n = dev->head - dev->tail;
2481 - if(n <= 0) n = LINE_BUFSIZE + n;
2483 + return(IRQ_HANDLED);
2486 int line_setup_irq(int fd, int input, int output, void *data)
2489 printk(KERN_ERR "line_setup failed to parse \"%s\"\n",
2496 @@ -313,12 +333,12 @@
2497 if((n >= 0) && (n >= num)){
2498 printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
2504 if(lines[n].count > 0){
2505 printk("line_setup - device %d is open\n", n);
2509 if(lines[n].init_pri <= INIT_ONE){
2510 lines[n].init_pri = INIT_ONE;
2512 else if(!all_allowed){
2513 printk("line_setup - can't configure all devices from "
2519 for(i = 0; i < num; i++){
2528 int line_config(struct line *lines, int num, char *str)
2530 printk("line_config - uml_strdup failed\n");
2533 - return(line_setup(lines, num, new, 0));
2534 + return(!line_setup(lines, num, new, 0));
2537 int line_get_config(char *name, struct line *lines, int num, char *str,
2540 dev = simple_strtoul(name, &end, 0);
2541 if((*end != '\0') || (end == name)){
2542 - *error_out = "line_setup failed to parse device number";
2543 + *error_out = "line_get_config failed to parse device number";
2547 @@ -379,15 +399,15 @@
2555 CONFIG_CHUNK(str, size, n, "none", 1);
2556 else if(line->count == 0)
2557 CONFIG_CHUNK(str, size, n, line->init_str, 1);
2558 else n = chan_config_string(&line->chan_list, str, size, error_out);
2565 @@ -396,7 +416,14 @@
2566 char config[sizeof("conxxxx=none\0")];
2568 sprintf(config, "%s=none", str);
2569 - return(line_setup(lines, num, config, 0));
2570 + return(!line_setup(lines, num, config, 0));
2573 +int line_write_room(struct tty_struct *tty)
2575 + struct line *dev = tty->driver_data;
2577 + return(write_room(dev));
2580 struct tty_driver *line_register_devfs(struct lines *set,
2584 driver->driver_name = line_driver->name;
2585 - driver->name = line_driver->devfs_name;
2586 + driver->name = line_driver->device_name;
2587 + driver->devfs_name = line_driver->devfs_name;
2588 driver->major = line_driver->major;
2589 driver->minor_start = line_driver->minor_start;
2590 driver->type = line_driver->type;
2593 for(i = 0; i < nlines; i++){
2595 - tty_unregister_devfs(driver, i);
2596 + tty_unregister_device(driver, i);
2599 mconsole_register_dev(&line_driver->mc);
2600 @@ -465,24 +493,25 @@
2604 -void winch_interrupt(int irq, void *data, struct pt_regs *unused)
2605 +irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
2607 struct winch *winch = data;
2608 struct tty_struct *tty;
2612 - err = generic_read(winch->fd, &c, NULL);
2614 - if(err != -EAGAIN){
2615 - printk("winch_interrupt : read failed, errno = %d\n",
2617 - printk("fd %d is losing SIGWINCH support\n",
2619 - free_irq(irq, data);
2621 + if(winch->fd != -1){
2622 + err = generic_read(winch->fd, &c, NULL);
2624 + if(err != -EAGAIN){
2625 + printk("winch_interrupt : read failed, "
2626 + "errno = %d\n", -err);
2627 + printk("fd %d is losing SIGWINCH support\n",
2629 + return(IRQ_HANDLED);
2635 tty = winch->line->tty;
2638 kill_pg(tty->pgrp, SIGWINCH, 1);
2641 - reactivate_fd(winch->fd, WINCH_IRQ);
2642 + if(winch->fd != -1)
2643 + reactivate_fd(winch->fd, WINCH_IRQ);
2644 + return(IRQ_HANDLED);
2647 DECLARE_MUTEX(winch_handler_sem);
2648 @@ -529,7 +560,10 @@
2650 list_for_each(ele, &winch_handlers){
2651 winch = list_entry(ele, struct winch, list);
2653 + if(winch->fd != -1){
2654 + deactivate_fd(winch->fd, WINCH_IRQ);
2655 + os_close_file(winch->fd);
2657 if(winch->pid != -1)
2658 os_kill_process(winch->pid, 1);
2660 diff -Naur a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
2661 --- a/arch/um/drivers/Makefile 2004-02-11 12:15:52.000000000 -0500
2662 +++ b/arch/um/drivers/Makefile 2004-02-11 12:27:45.000000000 -0500
2665 -# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
2666 +# Copyright (C) 2000, 2002, 2003 Jeff Dike (jdike@karaya.com)
2667 # Licensed under the GPL
2671 obj-$(CONFIG_TTY_CHAN) += tty.o
2672 obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
2673 obj-$(CONFIG_UML_WATCHDOG) += harddog.o
2674 +obj-$(CONFIG_BLK_DEV_COW) += cow_kern.o
2675 +obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
2677 obj-y += stdio_console.o $(CHAN_OBJS)
2681 USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \
2682 null.o pty.o tty.o xterm.o
2683 -USER_OBJS := $(foreach file,$(USER_OBJS),arch/um/drivers/$(file))
2684 +USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
2686 $(USER_OBJS) : %.o: %.c
2687 $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
2697 -archmrproper: clean
2699 diff -Naur a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
2700 --- a/arch/um/drivers/mcast_user.c 2004-02-11 12:15:46.000000000 -0500
2701 +++ b/arch/um/drivers/mcast_user.c 2004-02-11 12:27:37.000000000 -0500
2703 #include "kern_util.h"
2704 #include "user_util.h"
2708 #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
2714 - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
2715 + fd = socket(AF_INET, SOCK_DGRAM, 0);
2717 printk("mcast_open : data socket failed, errno = %d\n",
2721 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
2722 printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
2725 + os_close_file(fd);
2730 sizeof(pri->ttl)) < 0) {
2731 printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
2734 + os_close_file(fd);
2739 if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
2740 printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
2743 + os_close_file(fd);
2748 /* bind socket to mcast address */
2749 if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
2750 printk("mcast_open : data bind failed, errno = %d\n", errno);
2752 + os_close_file(fd);
2757 "interface on the host.\n");
2758 printk("eth0 should be configured in order to use the "
2759 "multicast transport.\n");
2761 + os_close_file(fd);
2770 + os_close_file(fd);
2773 int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
2774 diff -Naur a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
2775 --- a/arch/um/drivers/mconsole_kern.c 2004-02-11 12:14:15.000000000 -0500
2776 +++ b/arch/um/drivers/mconsole_kern.c 2004-02-11 12:25:42.000000000 -0500
2779 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
2780 - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
2781 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
2782 * Licensed under the GPL
2786 #include "linux/sysrq.h"
2787 #include "linux/workqueue.h"
2788 #include "linux/module.h"
2789 +#include "linux/file.h"
2790 +#include "linux/fs.h"
2791 +#include "linux/namei.h"
2792 #include "linux/proc_fs.h"
2793 #include "asm/irq.h"
2794 #include "asm/uaccess.h"
2799 +#include "irq_kern.h"
2801 static int do_unlink_socket(struct notifier_block *notifier,
2802 unsigned long what, void *data)
2805 DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
2807 -void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2808 +irqreturn_t mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2811 struct mconsole_entry *new;
2815 while (mconsole_get_request(fd, &req)){
2816 - if(req.cmd->as_interrupt) (*req.cmd->handler)(&req);
2817 + if(req.cmd->context == MCONSOLE_INTR)
2818 + (*req.cmd->handler)(&req);
2820 - new = kmalloc(sizeof(req), GFP_ATOMIC);
2821 + new = kmalloc(sizeof(*new), GFP_ATOMIC);
2823 mconsole_reply(&req, "Out of memory", 1, 0);
2827 if(!list_empty(&mc_requests)) schedule_work(&mconsole_work);
2828 reactivate_fd(fd, MCONSOLE_IRQ);
2829 + return(IRQ_HANDLED);
2832 void mconsole_version(struct mc_request *req)
2833 @@ -100,20 +106,110 @@
2834 mconsole_reply(req, version, 0, 0);
2837 +void mconsole_log(struct mc_request *req)
2840 + char *ptr = req->request.data;
2842 + ptr += strlen("log");
2843 + while(isspace(*ptr)) ptr++;
2845 + len = req->len - (ptr - req->request.data);
2846 + printk("%.*s", len, ptr);
2847 + mconsole_reply(req, "", 0, 0);
2850 +void mconsole_proc(struct mc_request *req)
2852 + struct nameidata nd;
2853 + struct file_system_type *proc;
2854 + struct super_block *super;
2855 + struct file *file;
2857 + char *ptr = req->request.data, *buf;
2859 + ptr += strlen("proc");
2860 + while(isspace(*ptr)) ptr++;
2862 + proc = get_fs_type("proc");
2864 + mconsole_reply(req, "procfs not registered", 1, 0);
2868 + super = (*proc->get_sb)(proc, 0, NULL, NULL);
2869 + put_filesystem(proc);
2870 + if(super == NULL){
2871 + mconsole_reply(req, "Failed to get procfs superblock", 1, 0);
2874 + up_write(&super->s_umount);
2876 + nd.dentry = super->s_root;
2878 + nd.flags = O_RDONLY + 1;
2879 + nd.last_type = LAST_ROOT;
2881 + err = link_path_walk(ptr, &nd);
2883 + mconsole_reply(req, "Failed to look up file", 1, 0);
2887 + file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
2889 + mconsole_reply(req, "Failed to open file", 1, 0);
2893 + buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
2895 + mconsole_reply(req, "Failed to allocate buffer", 1, 0);
2899 + if((file->f_op != NULL) && (file->f_op->read != NULL)){
2901 + n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1,
2905 + mconsole_reply(req, buf, 0, (n > 0));
2908 + mconsole_reply(req, "Read of file failed",
2914 + else mconsole_reply(req, "", 0, 0);
2921 + deactivate_super(super);
2925 #define UML_MCONSOLE_HELPTEXT \
2927 - version - Get kernel version
2928 - help - Print this message
2930 - reboot - Reboot UML
2931 - config <dev>=<config> - Add a new device to UML;
2932 - same syntax as command line
2933 - config <dev> - Query the configuration of a device
2934 - remove <dev> - Remove a device from UML
2935 - sysrq <letter> - Performs the SysRq action controlled by the letter
2936 - cad - invoke the Ctl-Alt-Del handler
2937 - stop - pause the UML; it will do nothing until it receives a 'go'
2938 - go - continue the UML after a 'stop'
2940 + version - Get kernel version \n\
2941 + help - Print this message \n\
2942 + halt - Halt UML \n\
2943 + reboot - Reboot UML \n\
2944 + config <dev>=<config> - Add a new device to UML; \n\
2945 + same syntax as command line \n\
2946 + config <dev> - Query the configuration of a device \n\
2947 + remove <dev> - Remove a device from UML \n\
2948 + sysrq <letter> - Performs the SysRq action controlled by the letter \n\
2949 + cad - invoke the Ctl-Alt-Del handler \n\
2950 + stop - pause the UML; it will do nothing until it receives a 'go' \n\
2951 + go - continue the UML after a 'stop' \n\
2952 + log <string> - make UML enter <string> into the kernel log\n\
2953 + proc <file> - returns the contents of the UML's /proc/<file>\n\
2956 void mconsole_help(struct mc_request *req)
2958 if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
2959 snprintf(mconsole_socket_name, sizeof(file), "%s", file);
2961 - sock = create_unix_socket(file, sizeof(file));
2962 + sock = os_create_unix_socket(file, sizeof(file), 1);
2964 printk("Failed to initialize management console\n");
2966 @@ -344,11 +440,16 @@
2970 - if(copy_from_user(buf, buffer, count))
2972 + if(copy_from_user(buf, buffer, count)){
2979 mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count);
2985 diff -Naur a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
2986 --- a/arch/um/drivers/mconsole_user.c 2004-02-11 12:14:27.000000000 -0500
2987 +++ b/arch/um/drivers/mconsole_user.c 2004-02-11 12:26:08.000000000 -0500
2990 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
2991 - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
2992 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
2993 * Licensed under the GPL
2999 static struct mconsole_command commands[] = {
3000 - { "version", mconsole_version, 1 },
3001 - { "halt", mconsole_halt, 0 },
3002 - { "reboot", mconsole_reboot, 0 },
3003 - { "config", mconsole_config, 0 },
3004 - { "remove", mconsole_remove, 0 },
3005 - { "sysrq", mconsole_sysrq, 1 },
3006 - { "help", mconsole_help, 1 },
3007 - { "cad", mconsole_cad, 1 },
3008 - { "stop", mconsole_stop, 0 },
3009 - { "go", mconsole_go, 1 },
3010 + { "version", mconsole_version, MCONSOLE_INTR },
3011 + { "halt", mconsole_halt, MCONSOLE_PROC },
3012 + { "reboot", mconsole_reboot, MCONSOLE_PROC },
3013 + { "config", mconsole_config, MCONSOLE_PROC },
3014 + { "remove", mconsole_remove, MCONSOLE_PROC },
3015 + { "sysrq", mconsole_sysrq, MCONSOLE_INTR },
3016 + { "help", mconsole_help, MCONSOLE_INTR },
3017 + { "cad", mconsole_cad, MCONSOLE_INTR },
3018 + { "stop", mconsole_stop, MCONSOLE_PROC },
3019 + { "go", mconsole_go, MCONSOLE_INTR },
3020 + { "log", mconsole_log, MCONSOLE_INTR },
3021 + { "proc", mconsole_proc, MCONSOLE_PROC },
3024 /* Initialized in mconsole_init, which is an initcall */
3026 memcpy(reply.data, str, len);
3027 reply.data[len] = '\0';
3030 reply.len = len + 1;
3032 len = sizeof(reply) + reply.len - sizeof(reply.data);
3033 diff -Naur a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
3034 --- a/arch/um/drivers/mmapper_kern.c 2004-02-11 12:14:23.000000000 -0500
3035 +++ b/arch/um/drivers/mmapper_kern.c 2004-02-11 12:26:07.000000000 -0500
3036 @@ -120,7 +120,10 @@
3037 printk(KERN_INFO "Mapper v0.1\n");
3039 v_buf = (char *) find_iomem("mmapper", &mmapper_size);
3040 - if(mmapper_size == 0) return(0);
3041 + if(mmapper_size == 0){
3042 + printk(KERN_ERR "mmapper_init - find_iomem failed\n");
3046 p_buf = __pa(v_buf);
3048 diff -Naur a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
3049 --- a/arch/um/drivers/net_kern.c 2004-02-11 12:15:23.000000000 -0500
3050 +++ b/arch/um/drivers/net_kern.c 2004-02-11 12:27:11.000000000 -0500
3052 #include "mconsole_kern.h"
3054 #include "irq_user.h"
3055 +#include "irq_kern.h"
3057 static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
3060 struct sk_buff *skb;
3062 /* If we can't allocate memory, try again next round. */
3063 - if ((skb = dev_alloc_skb(dev->mtu)) == NULL) {
3064 + skb = dev_alloc_skb(dev->mtu);
3065 + if (skb == NULL) {
3066 lp->stats.rx_dropped++;
3073 -void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
3074 +irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
3076 struct net_device *dev = dev_id;
3077 struct uml_net_private *lp = dev->priv;
3080 if(!netif_running(dev))
3084 spin_lock(&lp->lock);
3085 while((err = uml_net_rx(dev)) > 0) ;
3089 spin_unlock(&lp->lock);
3090 + return(IRQ_HANDLED);
3093 static int uml_net_open(struct net_device *dev)
3094 @@ -252,37 +255,6 @@
3099 - * default do nothing hard header packet routines for struct net_device init.
3100 - * real ethernet transports will overwrite with real routines.
3102 -static int uml_net_hard_header(struct sk_buff *skb, struct net_device *dev,
3103 - unsigned short type, void *daddr, void *saddr, unsigned len)
3105 - return(0); /* no change */
3108 -static int uml_net_rebuild_header(struct sk_buff *skb)
3110 - return(0); /* ignore */
3113 -static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh)
3115 - return(-1); /* fail */
3118 -static void uml_net_header_cache_update(struct hh_cache *hh,
3119 - struct net_device *dev, unsigned char * haddr)
3124 -static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr)
3126 - return(0); /* nothing */
3129 static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
3130 static struct list_head devices = LIST_HEAD_INIT(devices);
3133 struct uml_net *device;
3134 struct net_device *dev;
3135 struct uml_net_private *lp;
3137 + int save, err, size;
3139 size = transport->private_size + sizeof(struct uml_net_private) +
3140 sizeof(((struct uml_net_private *) 0)->user);
3141 @@ -334,12 +306,6 @@
3142 snprintf(dev->name, sizeof(dev->name), "eth%d", n);
3145 - dev->hard_header = uml_net_hard_header;
3146 - dev->rebuild_header = uml_net_rebuild_header;
3147 - dev->hard_header_cache = uml_net_header_cache;
3148 - dev->header_cache_update= uml_net_header_cache_update;
3149 - dev->hard_header_parse = uml_net_header_parse;
3151 (*transport->kern->init)(dev, init);
3153 dev->mtu = transport->user->max_packet;
3154 @@ -362,21 +328,29 @@
3158 - INIT_LIST_HEAD(&lp->list);
3159 - spin_lock_init(&lp->lock);
3162 - lp->mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0 };
3163 - lp->have_mac = device->have_mac;
3164 - lp->protocol = transport->kern->protocol;
3165 - lp->open = transport->user->open;
3166 - lp->close = transport->user->close;
3167 - lp->remove = transport->user->remove;
3168 - lp->read = transport->kern->read;
3169 - lp->write = transport->kern->write;
3170 - lp->add_address = transport->user->add_address;
3171 - lp->delete_address = transport->user->delete_address;
3172 - lp->set_mtu = transport->user->set_mtu;
3173 + /* lp.user is the first four bytes of the transport data, which
3174 + * has already been initialized. This structure assignment will
3175 + * overwrite that, so we make sure that .user gets overwritten with
3176 + * what it already has.
3178 + save = lp->user[0];
3179 + *lp = ((struct uml_net_private)
3180 + { .list = LIST_HEAD_INIT(lp->list),
3181 + .lock = SPIN_LOCK_UNLOCKED,
3184 + .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
3185 + .have_mac = device->have_mac,
3186 + .protocol = transport->kern->protocol,
3187 + .open = transport->user->open,
3188 + .close = transport->user->close,
3189 + .remove = transport->user->remove,
3190 + .read = transport->kern->read,
3191 + .write = transport->kern->write,
3192 + .add_address = transport->user->add_address,
3193 + .delete_address = transport->user->delete_address,
3194 + .set_mtu = transport->user->set_mtu,
3195 + .user = { save } });
3197 init_timer(&lp->tl);
3198 lp->tl.function = uml_net_user_timer_expire;
3200 unregister_netdev(dev);
3202 list_del(&device->list);
3203 - free_netdev(device);
3209 diff -Naur a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
3210 --- a/arch/um/drivers/net_user.c 2004-02-11 12:14:28.000000000 -0500
3211 +++ b/arch/um/drivers/net_user.c 2004-02-11 12:26:11.000000000 -0500
3213 if(gate_addr == NULL) return(0);
3214 if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
3215 &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){
3216 - printk("Invalid tap IP address - '%s'\n",
3218 + printk("Invalid tap IP address - '%s'\n", gate_addr);
3226 - if(read(fd, &remain, sizeof(remain)) != sizeof(remain)){
3227 - printk("read_output - read of length failed, errno = %d\n",
3229 + n = os_read_file(fd, &remain, sizeof(remain));
3230 + if(n != sizeof(remain)){
3231 + printk("read_output - read of length failed, err = %d\n", -n);
3236 n = (remain < len) ? remain : len;
3237 - actual = read(fd, output, n);
3238 + actual = os_read_file(fd, output, n);
3240 printk("read_output - read of data failed, "
3241 - "errno = %d\n", errno);
3242 + "err = %d\n", -actual);
3250 - while(((n = read(fd, buf, len)) < 0) && (errno == EINTR)) ;
3251 + n = os_read_file(fd, buf, len);
3254 - if(errno == EAGAIN) return(0);
3257 - else if(n == 0) return(-ENOTCONN);
3261 + return(-ENOTCONN);
3265 @@ -112,13 +110,13 @@
3269 - while(((n = write(fd, buf, len)) < 0) && (errno == EINTR)) ;
3271 - if(errno == EAGAIN) return(0);
3274 - else if(n == 0) return(-ENOTCONN);
3276 + n = os_write_file(fd, buf, len);
3281 + return(-ENOTCONN);
3285 int net_send(int fd, void *buf, int len)
3288 struct change_pre_exec_data *data = arg;
3290 - close(data->close_me);
3291 + os_close_file(data->close_me);
3292 dup2(data->stdout, 1);
3295 @@ -167,15 +165,15 @@
3296 struct change_pre_exec_data pe_data;
3298 err = os_pipe(fds, 1, 0);
3300 - printk("change_tramp - pipe failed, errno = %d\n", -err);
3302 + printk("change_tramp - pipe failed, err = %d\n", -err);
3305 pe_data.close_me = fds[0];
3306 pe_data.stdout = fds[1];
3307 pid = run_helper(change_pre_exec, &pe_data, argv, NULL);
3310 + os_close_file(fds[1]);
3311 read_output(fds[0], output, output_len);
3312 waitpid(pid, NULL, 0);
3314 diff -Naur a/arch/um/drivers/null.c b/arch/um/drivers/null.c
3315 --- a/arch/um/drivers/null.c 2004-02-11 12:14:21.000000000 -0500
3316 +++ b/arch/um/drivers/null.c 2004-02-11 12:26:02.000000000 -0500
3322 #include "chan_user.h"
3325 diff -Naur a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
3326 --- a/arch/um/drivers/port_kern.c 2004-02-11 12:14:18.000000000 -0500
3327 +++ b/arch/um/drivers/port_kern.c 2004-02-11 12:26:00.000000000 -0500
3329 #include "linux/list.h"
3330 #include "linux/sched.h"
3331 #include "linux/slab.h"
3332 +#include "linux/interrupt.h"
3333 #include "linux/irq.h"
3334 #include "linux/spinlock.h"
3335 #include "linux/errno.h"
3337 #include "kern_util.h"
3339 #include "irq_user.h"
3340 +#include "irq_kern.h"
3346 struct list_head list;
3352 struct port_list *port;
3355 -static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
3356 +static irqreturn_t pipe_interrupt(int irq, void *data, struct pt_regs *regs)
3358 struct connection *conn = data;
3361 - fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
3362 + fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
3368 printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n",
3371 list_add(&conn->list, &conn->port->connections);
3373 up(&conn->port->sem);
3374 + return(IRQ_HANDLED);
3377 static int port_accept(struct port_list *port)
3381 list_add(&conn->list, &port->pending);
3388 @@ -138,12 +140,13 @@
3390 DECLARE_WORK(port_work, port_work_proc, NULL);
3392 -static void port_interrupt(int irq, void *data, struct pt_regs *regs)
3393 +static irqreturn_t port_interrupt(int irq, void *data, struct pt_regs *regs)
3395 struct port_list *port = data;
3397 port->has_connection = 1;
3398 schedule_work(&port_work);
3399 + return(IRQ_HANDLED);
3402 void *port_data(int port_num)
3403 diff -Naur a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
3404 --- a/arch/um/drivers/port_user.c 2004-02-11 12:15:59.000000000 -0500
3405 +++ b/arch/um/drivers/port_user.c 2004-02-11 12:27:52.000000000 -0500
3410 - if((kern_data = port_data(port)) == NULL)
3411 + kern_data = port_data(port);
3412 + if(kern_data == NULL)
3415 - if((data = um_kmalloc(sizeof(*data))) == NULL)
3416 + data = um_kmalloc(sizeof(*data));
3420 *data = ((struct port_chan) { .raw = opts->raw,
3422 struct port_chan *data = d;
3424 port_remove_dev(data->kernel_data);
3426 + os_close_file(fd);
3429 int port_console_write(int fd, const char *buf, int n, void *d)
3430 @@ -130,11 +132,15 @@
3434 - if((listen(fd, 1) < 0) || (os_set_fd_block(fd, 0))){
3435 + if(listen(fd, 1) < 0){
3440 + err = os_set_fd_block(fd, 0);
3447 @@ -153,10 +159,10 @@
3448 dup2(data->sock_fd, 0);
3449 dup2(data->sock_fd, 1);
3450 dup2(data->sock_fd, 2);
3451 - close(data->sock_fd);
3452 + os_close_file(data->sock_fd);
3453 dup2(data->pipe_fd, 3);
3454 os_shutdown_socket(3, 1, 0);
3455 - close(data->pipe_fd);
3456 + os_close_file(data->pipe_fd);
3459 int port_connection(int fd, int *socket, int *pid_out)
3460 @@ -166,11 +172,12 @@
3461 "/usr/lib/uml/port-helper", NULL };
3462 struct port_pre_exec_data data;
3464 - if((new = os_accept_connection(fd)) < 0)
3466 + new = os_accept_connection(fd);
3470 err = os_pipe(socket, 0, 0);
3475 data = ((struct port_pre_exec_data)
3476 @@ -186,11 +193,11 @@
3479 os_shutdown_socket(socket[0], 1, 1);
3481 + os_close_file(socket[0]);
3482 os_shutdown_socket(socket[1], 1, 1);
3484 + os_close_file(socket[1]);
3487 + os_close_file(new);
3491 diff -Naur a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
3492 --- a/arch/um/drivers/pty.c 2004-02-11 12:16:37.000000000 -0500
3493 +++ b/arch/um/drivers/pty.c 2004-02-11 12:28:37.000000000 -0500
3499 #include <termios.h>
3500 #include "chan_user.h"
3502 #include "user_util.h"
3503 #include "kern_util.h"
3507 void (*announce)(char *dev_name, int dev);
3510 struct pty_chan *data;
3512 - if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL);
3513 + data = um_kmalloc(sizeof(*data));
3514 + if(data == NULL) return(NULL);
3515 *data = ((struct pty_chan) { .announce = opts->announce,
3517 .raw = opts->raw });
3522 - if((fd = get_pty()) < 0){
3525 printk("open_pts : Failed to open pts\n");
3530 int getmaster(char *line)
3533 char *pty, *bank, *cp;
3537 pty = &line[strlen("/dev/ptyp")];
3538 for (bank = "pqrs"; *bank; bank++) {
3539 line[strlen("/dev/pty")] = *bank;
3541 - if (stat(line, &stb) < 0)
3542 + if (os_stat_file(line, NULL) < 0)
3544 for (cp = "0123456789abcdef"; *cp; cp++) {
3546 - master = open(line, O_RDWR);
3547 + master = os_open_file(line, of_rdwr(OPENFLAGS()), 0);
3549 char *tp = &line[strlen("/dev/")];
3552 /* verify slave side is usable */
3554 - ok = access(line, R_OK|W_OK) == 0;
3555 + err = os_access(line, OS_ACC_RW_OK);
3557 - if (ok) return(master);
3558 - (void) close(master);
3559 + if(err == 0) return(master);
3560 + (void) os_close_file(master);
3564 diff -Naur a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
3565 --- a/arch/um/drivers/slip_user.c 2004-02-11 12:16:37.000000000 -0500
3566 +++ b/arch/um/drivers/slip_user.c 2004-02-11 12:28:37.000000000 -0500
3571 -#include <sys/fcntl.h>
3572 #include <sys/errno.h>
3573 #include <sys/termios.h>
3574 #include <sys/wait.h>
3575 -#include <sys/ioctl.h>
3576 #include <sys/signal.h>
3577 #include "user_util.h"
3578 #include "kern_util.h"
3581 struct slip_pre_exec_data *data = arg;
3583 - if(data->stdin != -1) dup2(data->stdin, 0);
3584 + if(data->stdin >= 0) dup2(data->stdin, 0);
3585 dup2(data->stdout, 1);
3586 - if(data->close_me != -1) close(data->close_me);
3587 + if(data->close_me >= 0) os_close_file(data->close_me);
3590 static int slip_tramp(char **argv, int fd)
3592 int status, pid, fds[2], err, output_len;
3594 err = os_pipe(fds, 1, 0);
3596 - printk("slip_tramp : pipe failed, errno = %d\n", -err);
3598 + printk("slip_tramp : pipe failed, err = %d\n", -err);
3603 printk("slip_tramp : failed to allocate output "
3607 + os_close_file(fds[1]);
3608 read_output(fds[0], output, output_len);
3610 printk("%s", output);
3612 if(waitpid(pid, &status, 0) < 0) err = errno;
3613 else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
3614 printk("'%s' didn't exit with status 0\n", argv[0]);
3620 @@ -118,15 +116,17 @@
3621 char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
3622 char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf,
3624 - int sfd, mfd, disc, sencap, err;
3625 + int sfd, mfd, err;
3627 - if((mfd = get_pty()) < 0){
3628 - printk("umn : Failed to open pty\n");
3632 + printk("umn : Failed to open pty, err = %d\n", -mfd);
3635 - if((sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0)) < 0){
3636 - printk("Couldn't open tty for slip line\n");
3638 + sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
3640 + printk("Couldn't open tty for slip line, err = %d\n", -sfd);
3643 if(set_up_tty(sfd)) return(-1);
3645 @@ -138,28 +138,23 @@
3647 err = slip_tramp(argv, sfd);
3650 - printk("slip_tramp failed - errno = %d\n", err);
3653 + printk("slip_tramp failed - err = %d\n", -err);
3656 - if(ioctl(pri->slave, SIOCGIFNAME, pri->name) < 0){
3657 - printk("SIOCGIFNAME failed, errno = %d\n", errno);
3659 + err = os_get_ifname(pri->slave, pri->name);
3661 + printk("get_ifname failed, err = %d\n", -err);
3664 iter_addresses(pri->dev, open_addr, pri->name);
3668 - if(ioctl(sfd, TIOCSETD, &disc) < 0){
3669 - printk("Failed to set slip line discipline - "
3670 - "errno = %d\n", errno);
3674 - if(ioctl(sfd, SIOCSIFENCAP, &sencap) < 0){
3675 - printk("Failed to set slip encapsulation - "
3676 - "errno = %d\n", errno);
3678 + err = os_set_slip(sfd);
3680 + printk("Failed to set slip discipline encapsulation - "
3681 + "err = %d\n", -err);
3687 err = slip_tramp(argv, -1);
3690 - printk("slip_tramp failed - errno = %d\n", err);
3692 - close(pri->slave);
3693 + printk("slip_tramp failed - errno = %d\n", -err);
3694 + os_close_file(fd);
3695 + os_close_file(pri->slave);
3701 struct slip_data *pri = data;
3703 - if(pri->slave == -1) return;
3704 + if(pri->slave < 0) return;
3705 open_addr(addr, netmask, pri->name);
3710 struct slip_data *pri = data;
3712 - if(pri->slave == -1) return;
3713 + if(pri->slave < 0) return;
3714 close_addr(addr, netmask, pri->name);
3717 diff -Naur a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
3718 --- a/arch/um/drivers/slirp_user.c 2004-02-11 12:16:03.000000000 -0500
3719 +++ b/arch/um/drivers/slirp_user.c 2004-02-11 12:27:58.000000000 -0500
3724 -#include <sys/fcntl.h>
3725 #include <sys/errno.h>
3726 #include <sys/wait.h>
3727 #include <sys/signal.h>
3734 +/* XXX This is just a trivial wrapper around os_pipe */
3735 static int slirp_datachan(int *mfd, int *sfd)
3739 err = os_pipe(fds, 1, 1);
3741 - printk("slirp_datachan: Failed to open pipe, errno = %d\n",
3744 + printk("slirp_datachan: Failed to open pipe, err = %d\n", -err);
3749 pid = slirp_tramp(pri->argw.argv, sfd);
3752 - printk("slirp_tramp failed - errno = %d\n", pid);
3753 + printk("slirp_tramp failed - errno = %d\n", -pid);
3758 struct slirp_data *pri = data;
3762 - close(pri->slave);
3763 + os_close_file(fd);
3764 + os_close_file(pri->slave);
3768 diff -Naur a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
3769 --- a/arch/um/drivers/ssl.c 2004-02-11 12:15:28.000000000 -0500
3770 +++ b/arch/um/drivers/ssl.c 2004-02-11 12:27:17.000000000 -0500
3772 #include "linux/major.h"
3773 #include "linux/mm.h"
3774 #include "linux/init.h"
3775 +#include "linux/console.h"
3776 #include "asm/termbits.h"
3777 #include "asm/irq.h"
3781 static struct line_driver driver = {
3782 .name = "UML serial line",
3783 - .devfs_name = "tts/%d",
3784 - .major = TTYAUX_MAJOR,
3785 + .device_name = "ttS",
3786 + .devfs_name = "tts/",
3787 + .major = TTY_MAJOR,
3789 .type = TTY_DRIVER_TYPE_SERIAL,
3801 @@ -212,6 +217,37 @@
3803 static int ssl_init_done = 0;
3805 +static void ssl_console_write(struct console *c, const char *string,
3808 + struct line *line = &serial_lines[c->index];
3811 + console_write_chan(&line->chan_list, string, len);
3816 +static struct tty_driver *ssl_console_device(struct console *c, int *index)
3818 + *index = c->index;
3819 + return ssl_driver;
3822 +static int ssl_console_setup(struct console *co, char *options)
3827 +static struct console ssl_cons = {
3829 + write: ssl_console_write,
3830 + device: ssl_console_device,
3831 + setup: ssl_console_setup,
3832 + flags: CON_PRINTBUFFER,
3839 @@ -227,17 +263,18 @@
3840 new_title = add_xterm_umid(opts.xterm_title);
3841 if(new_title != NULL) opts.xterm_title = new_title;
3843 + register_console(&ssl_cons);
3848 -__initcall(ssl_init);
3849 +late_initcall(ssl_init);
3851 static int ssl_chan_setup(char *str)
3853 - line_setup(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]),
3856 + return(line_setup(serial_lines,
3857 + sizeof(serial_lines)/sizeof(serial_lines[0]),
3861 __setup("ssl", ssl_chan_setup);
3862 diff -Naur a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
3863 --- a/arch/um/drivers/stdio_console.c 2004-02-11 12:14:32.000000000 -0500
3864 +++ b/arch/um/drivers/stdio_console.c 2004-02-11 12:26:14.000000000 -0500
3867 static struct line_driver driver = {
3868 .name = "UML console",
3869 - .devfs_name = "vc/%d",
3870 + .device_name = "tty",
3871 + .devfs_name = "vc/",
3874 .type = TTY_DRIVER_TYPE_CONSOLE,
3875 @@ -159,6 +160,15 @@
3877 static int con_init_done = 0;
3879 +static struct tty_operations console_ops = {
3881 + .close = con_close,
3882 + .write = con_write,
3883 + .chars_in_buffer = chars_in_buffer,
3884 + .set_termios = set_termios,
3885 + .write_room = line_write_room,
3888 int stdio_init(void)
3892 printk(KERN_INFO "Initializing stdio console driver\n");
3894 console_driver = line_register_devfs(&console_lines, &driver,
3895 - &console_ops, vts, sizeof(vts)/sizeof(vts[0]));
3896 + &console_ops, vts,
3897 + sizeof(vts)/sizeof(vts[0]));
3899 lines_init(vts, sizeof(vts)/sizeof(vts[0]));
3901 @@ -178,24 +189,19 @@
3905 -__initcall(stdio_init);
3906 +late_initcall(stdio_init);
3908 static void console_write(struct console *console, const char *string,
3911 - if(con_init_done) down(&vts[console->index].sem);
3912 - console_write_chan(&vts[console->index].chan_list, string, len);
3913 - if(con_init_done) up(&vts[console->index].sem);
3915 + struct line *line = &vts[console->index];
3917 -static struct tty_operations console_ops = {
3919 - .close = con_close,
3920 - .write = con_write,
3921 - .chars_in_buffer = chars_in_buffer,
3922 - .set_termios = set_termios,
3923 - .write_room = line_write_room,
3927 + console_write_chan(&line->chan_list, string, len);
3932 static struct tty_driver *console_device(struct console *c, int *index)
3934 @@ -208,22 +214,28 @@
3938 -static struct console stdiocons = INIT_CONSOLE("tty", console_write,
3939 - console_device, console_setup,
3941 +static struct console stdiocons = {
3943 + write: console_write,
3944 + device: console_device,
3945 + setup: console_setup,
3946 + flags: CON_PRINTBUFFER,
3950 -static void __init stdio_console_init(void)
3951 +static int __init stdio_console_init(void)
3953 INIT_LIST_HEAD(&vts[0].chan_list);
3954 list_add(&init_console_chan.list, &vts[0].chan_list);
3955 register_console(&stdiocons);
3959 console_initcall(stdio_console_init);
3961 static int console_chan_setup(char *str)
3963 - line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1);
3965 + return(line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1));
3968 __setup("con", console_chan_setup);
3969 diff -Naur a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
3970 --- a/arch/um/drivers/tty.c 2004-02-11 12:15:02.000000000 -0500
3971 +++ b/arch/um/drivers/tty.c 2004-02-11 12:26:51.000000000 -0500
3975 #include <termios.h>
3979 #include "chan_user.h"
3984 - if((data = um_kmalloc(sizeof(*data))) == NULL)
3985 + data = um_kmalloc(sizeof(*data));
3988 *data = ((struct tty_chan) { .dev = str,
3989 .raw = opts->raw });
3990 diff -Naur a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
3991 --- a/arch/um/drivers/ubd_kern.c 2004-02-11 12:15:25.000000000 -0500
3992 +++ b/arch/um/drivers/ubd_kern.c 2004-02-11 12:27:12.000000000 -0500
3994 * old style ubd by setting UBD_SHIFT to 0
3995 * 2002-09-27...2002-10-18 massive tinkering for 2.5
3996 * partitions have changed in 2.5
3997 + * 2003-01-29 more tinkering for 2.5.59-1
3998 + * This should now address the sysfs problems and has
3999 + * the symlink for devfs to allow for booting with
4000 + * the common /dev/ubd/discX/... names rather than
4001 + * only /dev/ubdN/discN this version also has lots of
4002 + * clean ups preparing for ubd-many.
4006 #define MAJOR_NR UBD_MAJOR
4008 #include "mconsole_kern.h"
4010 #include "irq_user.h"
4011 +#include "irq_kern.h"
4012 #include "ubd_user.h"
4013 #include "2_5compat.h"
4016 +#include "mem_kern.h"
4018 static spinlock_t ubd_io_lock = SPIN_LOCK_UNLOCKED;
4019 static spinlock_t ubd_lock = SPIN_LOCK_UNLOCKED;
4024 +/* Changed in early boot */
4025 +static int ubd_do_mmap = 0;
4026 +#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE
4028 static struct block_device_operations ubd_blops = {
4029 .owner = THIS_MODULE,
4032 static request_queue_t *ubd_queue;
4034 /* Protected by ubd_lock */
4035 -static int fake_major = 0;
4036 +static int fake_major = MAJOR_NR;
4038 static struct gendisk *ubd_gendisk[MAX_DEV];
4039 static struct gendisk *fake_gendisk[MAX_DEV];
4040 @@ -96,13 +110,19 @@
4048 struct openflags boot_openflags;
4049 struct openflags openflags;
4060 #define DEFAULT_COW { \
4061 @@ -115,21 +135,28 @@
4063 #define DEFAULT_UBD { \
4069 .boot_openflags = OPEN_FLAGS, \
4070 .openflags = OPEN_FLAGS, \
4072 .cow = DEFAULT_COW, \
4073 + .map_writes = 0, \
4075 + .nomap_writes = 0, \
4076 + .nomap_reads = 0, \
4077 + .write_maps = 0, \
4080 struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
4082 static int ubd0_init(void)
4084 - if(ubd_dev[0].file == NULL)
4085 - ubd_dev[0].file = "root_fs";
4086 + struct ubd *dev = &ubd_dev[0];
4088 + if(dev->file == NULL)
4089 + dev->file = "root_fs";
4093 @@ -196,19 +223,46 @@
4094 " Create ide0 entries that map onto ubd devices.\n\n"
4097 +static int parse_unit(char **ptr)
4099 + char *str = *ptr, *end;
4102 + if(isdigit(*str)) {
4103 + n = simple_strtoul(str, &end, 0);
4108 + else if (('a' <= *str) && (*str <= 'h')) {
4116 static int ubd_setup_common(char *str, int *index_out)
4119 struct openflags flags = global_openflags;
4123 if(index_out) *index_out = -1;
4127 - static int fake_major_allowed = 1;
4132 + if(!strcmp(str, "mmap")){
4133 + CHOOSE_MODE(printk("mmap not supported by the ubd "
4134 + "driver in tt mode\n"),
4139 if(!strcmp(str, "sync")){
4140 global_openflags.s = 1;
4142 @@ -220,20 +274,14 @@
4146 - if(!fake_major_allowed){
4147 - printk(KERN_ERR "Can't assign a fake major twice\n");
4152 spin_lock(&ubd_lock);
4153 - if(!fake_major_allowed){
4154 + if(fake_major != MAJOR_NR){
4155 printk(KERN_ERR "Can't assign a fake major twice\n");
4160 - fake_major_allowed = 0;
4162 printk(KERN_INFO "Setting extra ubd major number to %d\n",
4164 @@ -243,25 +291,23 @@
4169 - printk(KERN_ERR "ubd_setup : index out of range\n"); }
4171 - if((n >= '0') && (n <= '9')) n -= '0';
4172 - else if((n >= 'a') && (n <= 'z')) n -= 'a';
4174 - printk(KERN_ERR "ubd_setup : device syntax invalid\n");
4175 + n = parse_unit(&str);
4177 + printk(KERN_ERR "ubd_setup : couldn't parse unit number "
4182 - printk(KERN_ERR "ubd_setup : index out of range "
4183 - "(%d devices)\n", MAX_DEV);
4184 + printk(KERN_ERR "ubd_setup : index %d out of range "
4185 + "(%d devices)\n", n, MAX_DEV);
4190 spin_lock(&ubd_lock);
4192 - if(ubd_dev[n].file != NULL){
4193 + dev = &ubd_dev[n];
4194 + if(dev->file != NULL){
4195 printk(KERN_ERR "ubd_setup : device already configured\n");
4198 @@ -276,6 +322,11 @@
4208 printk(KERN_ERR "ubd_setup : Expected '='\n");
4210 @@ -284,14 +335,17 @@
4212 backing_file = strchr(str, ',');
4214 - *backing_file = '\0';
4217 + printk(KERN_ERR "Can't specify both 'd' and a "
4220 + *backing_file = '\0';
4224 - ubd_dev[n].file = str;
4225 - if(ubd_is_dir(ubd_dev[n].file))
4226 - ubd_dev[n].is_dir = 1;
4227 - ubd_dev[n].cow.file = backing_file;
4228 - ubd_dev[n].boot_openflags = flags;
4230 + dev->cow.file = backing_file;
4231 + dev->boot_openflags = flags;
4233 spin_unlock(&ubd_lock);
4236 static int fakehd_set = 0;
4237 static int fakehd(char *str)
4240 - "fakehd : Changing ubd name to \"hd\".\n");
4241 + printk(KERN_INFO "fakehd : Changing ubd name to \"hd\".\n");
4245 @@ -368,32 +421,42 @@
4247 struct io_thread_req req;
4248 struct request *rq = elv_next_request(ubd_queue);
4254 n = read_ubd_fs(thread_fd, &req, sizeof(req));
4255 if(n != sizeof(req)){
4256 printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
4257 - "errno = %d\n", os_getpid(), -n);
4258 + "err = %d\n", os_getpid(), -n);
4259 spin_lock(&ubd_io_lock);
4261 spin_unlock(&ubd_io_lock);
4265 - if((req.offset != ((__u64) (rq->sector)) << 9) ||
4266 - (req.length != (rq->current_nr_sectors) << 9))
4267 + if((req.op != UBD_MMAP) &&
4268 + ((req.offset != ((__u64) (rq->sector)) << 9) ||
4269 + (req.length != (rq->current_nr_sectors) << 9)))
4270 panic("I/O op mismatch");
4272 + if(req.map_fd != -1){
4273 + err = physmem_subst_mapping(req.buffer, req.map_fd,
4274 + req.map_offset, 1);
4276 + printk("ubd_handler - physmem_subst_mapping failed, "
4277 + "err = %d\n", -err);
4280 ubd_finish(rq, req.error);
4281 reactivate_fd(thread_fd, UBD_IRQ);
4282 do_ubd_request(ubd_queue);
4285 -static void ubd_intr(int irq, void *dev, struct pt_regs *unused)
4286 +static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused)
4289 + return(IRQ_HANDLED);
4292 /* Only changed by ubd_init, which is an initcall. */
4293 @@ -417,10 +480,14 @@
4295 static void ubd_close(struct ubd *dev)
4298 + physmem_forget_descriptor(dev->fd);
4299 os_close_file(dev->fd);
4300 if(dev->cow.file == NULL)
4304 + physmem_forget_descriptor(dev->cow.fd);
4305 os_close_file(dev->cow.fd);
4306 vfree(dev->cow.bitmap);
4307 dev->cow.bitmap = NULL;
4308 @@ -429,18 +496,20 @@
4309 static int ubd_open_dev(struct ubd *dev)
4311 struct openflags flags;
4312 - int err, n, create_cow, *create_ptr;
4314 + int err, create_cow, *create_ptr;
4316 + dev->openflags = dev->boot_openflags;
4318 create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
4319 - dev->fd = open_ubd_file(dev->file, &dev->openflags, &dev->cow.file,
4320 + back_ptr = dev->no_cow ? NULL : &dev->cow.file;
4321 + dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr,
4322 &dev->cow.bitmap_offset, &dev->cow.bitmap_len,
4323 &dev->cow.data_offset, create_ptr);
4325 if((dev->fd == -ENOENT) && create_cow){
4326 - n = dev - ubd_dev;
4327 dev->fd = create_cow_file(dev->file, dev->cow.file,
4328 - dev->openflags, 1 << 9,
4329 + dev->openflags, 1 << 9, PAGE_SIZE,
4330 &dev->cow.bitmap_offset,
4331 &dev->cow.bitmap_len,
4332 &dev->cow.data_offset);
4333 @@ -455,13 +524,17 @@
4334 if(dev->cow.file != NULL){
4336 dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
4337 - if(dev->cow.bitmap == NULL) goto error;
4338 + if(dev->cow.bitmap == NULL){
4339 + printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
4342 flush_tlb_kernel_vm();
4344 err = read_cow_bitmap(dev->fd, dev->cow.bitmap,
4345 dev->cow.bitmap_offset,
4346 dev->cow.bitmap_len);
4347 - if(err) goto error;
4351 flags = dev->openflags;
4353 @@ -481,17 +554,31 @@
4356 struct gendisk *disk;
4357 + char from[sizeof("ubd/nnnnn\0")], to[sizeof("discnnnnn/disc\0")];
4360 disk = alloc_disk(1 << UBD_SHIFT);
4366 disk->major = major;
4367 disk->first_minor = unit << UBD_SHIFT;
4368 disk->fops = &ubd_blops;
4369 set_capacity(disk, size / 512);
4370 - sprintf(disk->disk_name, "ubd");
4371 - sprintf(disk->devfs_name, "ubd/disc%d", unit);
4372 + if(major == MAJOR_NR){
4373 + sprintf(disk->disk_name, "ubd%c", 'a' + unit);
4374 + sprintf(disk->devfs_name, "ubd/disc%d", unit);
4375 + sprintf(from, "ubd/%d", unit);
4376 + sprintf(to, "disc%d/disc", unit);
4377 + err = devfs_mk_symlink(from, to);
4379 + printk("ubd_new_disk failed to make link from %s to "
4380 + "%s, error = %d\n", from, to, err);
4383 + sprintf(disk->disk_name, "ubd_fake%d", unit);
4384 + sprintf(disk->devfs_name, "ubd_fake/disc%d", unit);
4387 disk->private_data = &ubd_dev[unit];
4388 disk->queue = ubd_queue;
4389 @@ -506,24 +593,21 @@
4390 struct ubd *dev = &ubd_dev[n];
4397 + if(dev->file == NULL)
4400 if (ubd_open_dev(dev))
4403 err = ubd_file_size(dev, &dev->size);
4408 err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
4413 + if(fake_major != MAJOR_NR)
4414 ubd_new_disk(fake_major, dev->size, n,
4417 @@ -561,42 +645,42 @@
4421 -static int ubd_get_config(char *dev, char *str, int size, char **error_out)
4422 +static int ubd_get_config(char *name, char *str, int size, char **error_out)
4430 - major = simple_strtoul(dev, &end, 0);
4431 - if((*end != '\0') || (end == dev)){
4432 - *error_out = "ubd_get_config : didn't parse major number";
4433 + n = simple_strtoul(name, &end, 0);
4434 + if((*end != '\0') || (end == name)){
4435 + *error_out = "ubd_get_config : didn't parse device number";
4439 - if((major >= MAX_DEV) || (major < 0)){
4440 - *error_out = "ubd_get_config : major number out of range";
4441 + if((n >= MAX_DEV) || (n < 0)){
4442 + *error_out = "ubd_get_config : device number out of range";
4446 - ubd = &ubd_dev[major];
4447 + dev = &ubd_dev[n];
4448 spin_lock(&ubd_lock);
4450 - if(ubd->file == NULL){
4451 - CONFIG_CHUNK(str, size, n, "", 1);
4452 + if(dev->file == NULL){
4453 + CONFIG_CHUNK(str, size, len, "", 1);
4457 - CONFIG_CHUNK(str, size, n, ubd->file, 0);
4458 + CONFIG_CHUNK(str, size, len, dev->file, 0);
4460 - if(ubd->cow.file != NULL){
4461 - CONFIG_CHUNK(str, size, n, ",", 0);
4462 - CONFIG_CHUNK(str, size, n, ubd->cow.file, 1);
4463 + if(dev->cow.file != NULL){
4464 + CONFIG_CHUNK(str, size, len, ",", 0);
4465 + CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
4467 - else CONFIG_CHUNK(str, size, n, "", 1);
4468 + else CONFIG_CHUNK(str, size, len, "", 1);
4471 spin_unlock(&ubd_lock);
4476 static int ubd_remove(char *str)
4477 @@ -604,11 +688,9 @@
4479 int n, err = -ENODEV;
4481 - if(!isdigit(*str))
4482 - return(err); /* it should be a number 0-7/a-h */
4483 + n = parse_unit(&str);
4487 + if((n < 0) || (n >= MAX_DEV))
4493 elevator_init(ubd_queue, &elevator_noop);
4495 - if (fake_major != 0) {
4496 + if (fake_major != MAJOR_NR) {
4497 char name[sizeof("ubd_nnn\0")];
4499 snprintf(name, sizeof(name), "ubd_%d", fake_major);
4501 io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
4506 "ubd : Failed to start I/O thread (errno = %d) - "
4507 "falling back to synchronous I/O\n", -io_pid);
4510 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
4511 SA_INTERRUPT, "ubd", ubd_dev);
4512 - if(err != 0) printk(KERN_ERR
4513 - "um_request_irq failed - errno = %d\n", -err);
4515 + printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
4519 @@ -714,15 +797,9 @@
4521 struct gendisk *disk = inode->i_bdev->bd_disk;
4522 struct ubd *dev = disk->private_data;
4523 - int err = -EISDIR;
4525 - if(dev->is_dir == 1)
4530 if(dev->count == 0){
4531 - dev->openflags = dev->boot_openflags;
4533 err = ubd_open_dev(dev);
4535 printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
4536 @@ -749,62 +826,156 @@
4540 -void cowify_req(struct io_thread_req *req, struct ubd *dev)
4541 +static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
4542 + __u64 *cow_offset, unsigned long *bitmap,
4543 + __u64 bitmap_offset, unsigned long *bitmap_words,
4546 + __u64 sector = io_offset >> 9;
4547 + int i, update_bitmap = 0;
4549 + for(i = 0; i < length >> 9; i++){
4550 + if(cow_mask != NULL)
4551 + ubd_set_bit(i, (unsigned char *) cow_mask);
4552 + if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
4555 + update_bitmap = 1;
4556 + ubd_set_bit(sector + i, (unsigned char *) bitmap);
4559 + if(!update_bitmap)
4562 + *cow_offset = sector / (sizeof(unsigned long) * 8);
4564 + /* This takes care of the case where we're exactly at the end of the
4565 + * device, and *cow_offset + 1 is off the end. So, just back it up
4566 + * by one word. Thanks to Lynn Kerby for the fix and James McMechan
4567 + * for the original diagnosis.
4569 + if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) /
4570 + sizeof(unsigned long) - 1))
4573 + bitmap_words[0] = bitmap[*cow_offset];
4574 + bitmap_words[1] = bitmap[*cow_offset + 1];
4576 + *cow_offset *= sizeof(unsigned long);
4577 + *cow_offset += bitmap_offset;
4580 +static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
4581 + __u64 bitmap_offset, __u64 bitmap_len)
4583 - int i, update_bitmap, sector = req->offset >> 9;
4584 + __u64 sector = req->offset >> 9;
4587 if(req->length > (sizeof(req->sector_mask) * 8) << 9)
4588 panic("Operation too long");
4590 if(req->op == UBD_READ) {
4591 for(i = 0; i < req->length >> 9; i++){
4592 - if(ubd_test_bit(sector + i, (unsigned char *)
4593 - dev->cow.bitmap)){
4594 + if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
4595 ubd_set_bit(i, (unsigned char *)
4601 - update_bitmap = 0;
4602 - for(i = 0; i < req->length >> 9; i++){
4603 - ubd_set_bit(i, (unsigned char *)
4604 - &req->sector_mask);
4605 - if(!ubd_test_bit(sector + i, (unsigned char *)
4607 - update_bitmap = 1;
4608 - ubd_set_bit(sector + i, (unsigned char *)
4611 - if(update_bitmap){
4612 - req->cow_offset = sector / (sizeof(unsigned long) * 8);
4613 - req->bitmap_words[0] =
4614 - dev->cow.bitmap[req->cow_offset];
4615 - req->bitmap_words[1] =
4616 - dev->cow.bitmap[req->cow_offset + 1];
4617 - req->cow_offset *= sizeof(unsigned long);
4618 - req->cow_offset += dev->cow.bitmap_offset;
4620 + else cowify_bitmap(req->offset, req->length, &req->sector_mask,
4621 + &req->cow_offset, bitmap, bitmap_offset,
4622 + req->bitmap_words, bitmap_len);
4625 +static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset)
4628 + unsigned char *bitmap;
4631 + /* mmap must have been requested on the command line */
4635 + /* The buffer must be page aligned */
4636 + if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0)
4639 + /* The request must be a page long */
4640 + if((req->current_nr_sectors << 9) != PAGE_SIZE)
4643 + if(dev->cow.file == NULL)
4646 + sector = offset >> 9;
4647 + bitmap = (unsigned char *) dev->cow.bitmap;
4648 + bit = ubd_test_bit(sector, bitmap);
4650 + for(i = 1; i < req->current_nr_sectors; i++){
4651 + if(ubd_test_bit(sector + i, bitmap) != bit)
4655 + if(bit || (rq_data_dir(req) == WRITE))
4656 + offset += dev->cow.data_offset;
4658 + /* The data on disk must be page aligned */
4659 + if((offset % UBD_MMAP_BLOCK_SIZE) != 0)
4662 + return(bit ? dev->fd : dev->cow.fd);
4665 +static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset,
4666 + struct request *req,
4667 + struct io_thread_req *io_req)
4671 + if(rq_data_dir(req) == WRITE){
4672 + /* Writes are almost no-ops since the new data is already in the
4675 + dev->map_writes++;
4676 + if(dev->cow.file != NULL)
4677 + cowify_bitmap(io_req->offset, io_req->length,
4678 + &io_req->sector_mask, &io_req->cow_offset,
4679 + dev->cow.bitmap, dev->cow.bitmap_offset,
4680 + io_req->bitmap_words,
4681 + dev->cow.bitmap_len);
4686 + if((dev->cow.file != NULL) && (fd == dev->cow.fd))
4688 + else w = dev->openflags.w;
4690 + if((dev->cow.file != NULL) && (fd == dev->fd))
4691 + offset += dev->cow.data_offset;
4693 + err = physmem_subst_mapping(req->buffer, fd, offset, w);
4695 + printk("physmem_subst_mapping failed, err = %d\n",
4701 + io_req->op = UBD_MMAP;
4702 + io_req->buffer = req->buffer;
4706 static int prepare_request(struct request *req, struct io_thread_req *io_req)
4708 struct gendisk *disk = req->rq_disk;
4709 struct ubd *dev = disk->private_data;
4715 if(req->rq_status == RQ_INACTIVE) return(1);
4718 - strcpy(req->buffer, "HOSTFS:");
4719 - strcat(req->buffer, dev->file);
4720 - spin_lock(&ubd_io_lock);
4721 - end_request(req, 1);
4722 - spin_unlock(&ubd_io_lock);
4726 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
4727 printk("Write attempted on readonly ubd device %s\n",
4729 @@ -814,23 +985,49 @@
4733 - block = req->sector;
4734 - nsect = req->current_nr_sectors;
4735 + offset = ((__u64) req->sector) << 9;
4736 + len = req->current_nr_sectors << 9;
4738 - io_req->op = rq_data_dir(req) == READ ? UBD_READ : UBD_WRITE;
4739 io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
4740 io_req->fds[1] = dev->fd;
4741 + io_req->map_fd = -1;
4742 + io_req->cow_offset = -1;
4743 + io_req->offset = offset;
4744 + io_req->length = len;
4745 + io_req->error = 0;
4746 + io_req->sector_mask = 0;
4748 + fd = mmap_fd(req, dev, io_req->offset);
4750 + /* If mmapping is otherwise OK, but the first access to the
4751 + * page is a write, then it's not mapped in yet. So we have
4752 + * to write the data to disk first, then we can map the disk
4753 + * page in and continue normally from there.
4755 + if((rq_data_dir(req) == WRITE) && !is_remapped(req->buffer)){
4756 + io_req->map_fd = dev->fd;
4757 + io_req->map_offset = io_req->offset +
4758 + dev->cow.data_offset;
4759 + dev->write_maps++;
4761 + else return(prepare_mmap_request(dev, fd, io_req->offset, req,
4765 + if(rq_data_dir(req) == READ)
4766 + dev->nomap_reads++;
4767 + else dev->nomap_writes++;
4769 + io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
4770 io_req->offsets[0] = 0;
4771 io_req->offsets[1] = dev->cow.data_offset;
4772 - io_req->offset = ((__u64) block) << 9;
4773 - io_req->length = nsect << 9;
4774 io_req->buffer = req->buffer;
4775 io_req->sectorsize = 1 << 9;
4776 - io_req->sector_mask = 0;
4777 - io_req->cow_offset = -1;
4778 - io_req->error = 0;
4780 - if(dev->cow.file != NULL) cowify_req(io_req, dev);
4781 + if(dev->cow.file != NULL)
4782 + cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset,
4783 + dev->cow.bitmap_len);
4788 @@ -841,7 +1038,7 @@
4791 if(thread_fd == -1){
4792 - while(!list_empty(&q->queue_head)){
4793 + while(!elv_queue_empty(q)){
4794 req = elv_next_request(q);
4795 err = prepare_request(req, &io_req);
4797 @@ -851,7 +1048,8 @@
4801 - if(do_ubd || list_empty(&q->queue_head)) return;
4802 + if(do_ubd || elv_queue_empty(q))
4804 req = elv_next_request(q);
4805 err = prepare_request(req, &io_req);
4807 @@ -885,7 +1083,7 @@
4810 g.cylinders = dev->size / (128 * 32 * 512);
4812 + g.start = get_start_sect(inode->i_bdev);
4813 return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0);
4815 case HDIO_SET_UNMASKINTR:
4816 @@ -935,6 +1133,142 @@
4820 +static int ubd_check_remapped(int fd, unsigned long address, int is_write,
4823 + __u64 bitmap_offset;
4824 + unsigned long new_bitmap[2];
4827 + /* If it's not a write access, we can't do anything about it */
4831 + /* We have a write */
4832 + for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){
4833 + struct ubd *dev = &ubd_dev[i];
4835 + if((dev->fd != fd) && (dev->cow.fd != fd))
4838 + /* It's a write to a ubd device */
4840 + if(!dev->openflags.w){
4841 + /* It's a write access on a read-only device - probably
4842 + * shouldn't happen. If the kernel is trying to change
4843 + * something with no intention of writing it back out,
4844 + * then this message will clue us in that this needs
4847 + printk("Write access to mapped page from readonly ubd "
4848 + "device %d\n", i);
4852 + /* It's a write to a writeable ubd device - it must be COWed
4853 + * because, otherwise, the page would have been mapped in
4857 + if(!dev->cow.file)
4858 + panic("Write fault on writeable non-COW ubd device %d",
4861 + /* It should also be an access to the backing file since the
4862 + * COW pages should be mapped in read-write
4866 + panic("Write fault on a backing page of ubd "
4867 + "device %d\n", i);
4869 + /* So, we do the write, copying the backing data to the COW
4873 + err = os_seek_file(dev->fd, offset + dev->cow.data_offset);
4875 + panic("Couldn't seek to %lld in COW file of ubd "
4876 + "device %d, err = %d",
4877 + offset + dev->cow.data_offset, i, -err);
4879 + n = os_write_file(dev->fd, (void *) address, PAGE_SIZE);
4880 + if(n != PAGE_SIZE)
4881 + panic("Couldn't copy data to COW file of ubd "
4882 + "device %d, err = %d", i, -n);
4884 + /* ... updating the COW bitmap... */
4886 + cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset,
4887 + dev->cow.bitmap, dev->cow.bitmap_offset,
4888 + new_bitmap, dev->cow.bitmap_len);
4890 + err = os_seek_file(dev->fd, bitmap_offset);
4892 + panic("Couldn't seek to %lld in COW file of ubd "
4893 + "device %d, err = %d", bitmap_offset, i, -err);
4895 + n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap));
4896 + if(n != sizeof(new_bitmap))
4897 + panic("Couldn't update bitmap of ubd device %d, "
4898 + "err = %d", i, -n);
4900 + /* Maybe we can map the COW page in, and maybe we can't. If
4901 + * it is a pre-V3 COW file, we can't, since the alignment will
4902 + * be wrong. If it is a V3 or later COW file which has been
4903 + * moved to a system with a larger page size, then maybe we
4904 + * can't, depending on the exact location of the page.
4907 + offset += dev->cow.data_offset;
4909 + /* Remove the remapping, putting the original anonymous page
4910 + * back. If the COW file can be mapped in, that is done.
4911 + * Otherwise, the COW page is read in.
4914 + if(!physmem_remove_mapping((void *) address))
4915 + panic("Address 0x%lx not remapped by ubd device %d",
4917 + if((offset % UBD_MMAP_BLOCK_SIZE) == 0)
4918 + physmem_subst_mapping((void *) address, dev->fd,
4921 + err = os_seek_file(dev->fd, offset);
4923 + panic("Couldn't seek to %lld in COW file of "
4924 + "ubd device %d, err = %d", offset, i,
4927 + n = os_read_file(dev->fd, (void *) address, PAGE_SIZE);
4928 + if(n != PAGE_SIZE)
4929 + panic("Failed to read page from offset %llx of "
4930 + "COW file of ubd device %d, err = %d",
4937 + /* It's not a write on a ubd device */
4941 +static struct remapper ubd_remapper = {
4942 + .list = LIST_HEAD_INIT(ubd_remapper.list),
4943 + .proc = ubd_check_remapped,
4946 +static int ubd_remapper_setup(void)
4949 + register_remapper(&ubd_remapper);
4954 +__initcall(ubd_remapper_setup);
4957 * Overrides for Emacs so that we follow Linus's tabbing style.
4958 * Emacs will notice this stuff at the end of the file and automatically
4959 diff -Naur a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
4960 --- a/arch/um/drivers/ubd_user.c 2004-02-11 12:14:32.000000000 -0500
4961 +++ b/arch/um/drivers/ubd_user.c 2004-02-11 12:26:14.000000000 -0500
4965 #include <netinet/in.h>
4966 -#include <sys/stat.h>
4967 #include <sys/time.h>
4968 -#include <sys/fcntl.h>
4969 #include <sys/socket.h>
4970 -#include <string.h>
4971 #include <sys/mman.h>
4972 #include <sys/param.h>
4973 #include "asm/types.h"
4974 @@ -24,146 +21,30 @@
4976 #include "ubd_user.h"
4981 #include <byteswap.h>
4982 -#if __BYTE_ORDER == __BIG_ENDIAN
4983 -# define ntohll(x) (x)
4984 -# define htonll(x) (x)
4985 -#elif __BYTE_ORDER == __LITTLE_ENDIAN
4986 -# define ntohll(x) bswap_64(x)
4987 -# define htonll(x) bswap_64(x)
4989 -#error "__BYTE_ORDER not defined"
4992 -#define PATH_LEN_V1 256
4994 -struct cow_header_v1 {
4997 - char backing_file[PATH_LEN_V1];
5003 -#define PATH_LEN_V2 MAXPATHLEN
5005 -struct cow_header_v2 {
5006 - unsigned long magic;
5007 - unsigned long version;
5008 - char backing_file[PATH_LEN_V2];
5015 - struct cow_header_v1 v1;
5016 - struct cow_header_v2 v2;
5019 -#define COW_MAGIC 0x4f4f4f4d /* MOOO */
5020 -#define COW_VERSION 2
5022 -static void sizes(__u64 size, int sectorsize, int bitmap_offset,
5023 - unsigned long *bitmap_len_out, int *data_offset_out)
5025 - *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
5027 - *data_offset_out = bitmap_offset + *bitmap_len_out;
5028 - *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
5029 - *data_offset_out *= sectorsize;
5032 -static int read_cow_header(int fd, int *magic_out, char **backing_file_out,
5033 - time_t *mtime_out, __u64 *size_out,
5034 - int *sectorsize_out, int *bitmap_offset_out)
5036 - union cow_header *header;
5039 - unsigned long version, magic;
5041 - header = um_kmalloc(sizeof(*header));
5042 - if(header == NULL){
5043 - printk("read_cow_header - Failed to allocate header\n");
5047 - n = read(fd, header, sizeof(*header));
5048 - if(n < offsetof(typeof(header->v1), backing_file)){
5049 - printk("read_cow_header - short header\n");
5053 - magic = header->v1.magic;
5054 - if(magic == COW_MAGIC) {
5055 - version = header->v1.version;
5057 - else if(magic == ntohl(COW_MAGIC)){
5058 - version = ntohl(header->v1.version);
5062 - *magic_out = COW_MAGIC;
5065 - if(n < sizeof(header->v1)){
5066 - printk("read_cow_header - failed to read V1 header\n");
5069 - *mtime_out = header->v1.mtime;
5070 - *size_out = header->v1.size;
5071 - *sectorsize_out = header->v1.sectorsize;
5072 - *bitmap_offset_out = sizeof(header->v1);
5073 - file = header->v1.backing_file;
5075 - else if(version == 2){
5076 - if(n < sizeof(header->v2)){
5077 - printk("read_cow_header - failed to read V2 header\n");
5080 - *mtime_out = ntohl(header->v2.mtime);
5081 - *size_out = ntohll(header->v2.size);
5082 - *sectorsize_out = ntohl(header->v2.sectorsize);
5083 - *bitmap_offset_out = sizeof(header->v2);
5084 - file = header->v2.backing_file;
5087 - printk("read_cow_header - invalid COW version\n");
5091 - *backing_file_out = uml_strdup(file);
5092 - if(*backing_file_out == NULL){
5093 - printk("read_cow_header - failed to allocate backing file\n");
5102 static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
5104 - struct stat buf1, buf2;
5105 + struct uml_stat buf1, buf2;
5108 if(from_cmdline == NULL) return(1);
5109 if(!strcmp(from_cmdline, from_cow)) return(1);
5111 - if(stat(from_cmdline, &buf1) < 0){
5112 - printk("Couldn't stat '%s', errno = %d\n", from_cmdline,
5114 + err = os_stat_file(from_cmdline, &buf1);
5116 + printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
5119 - if(stat(from_cow, &buf2) < 0){
5120 - printk("Couldn't stat '%s', errno = %d\n", from_cow, errno);
5121 + err = os_stat_file(from_cow, &buf2);
5123 + printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
5126 - if((buf1.st_dev == buf2.st_dev) && (buf1.st_ino == buf2.st_ino))
5127 + if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
5130 printk("Backing file mismatch - \"%s\" requested,\n"
5131 @@ -174,20 +55,21 @@
5133 static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
5135 - struct stat64 buf;
5136 + unsigned long modtime;
5140 - if(stat64(file, &buf) < 0){
5141 - printk("Failed to stat backing file \"%s\", errno = %d\n",
5144 + err = os_file_modtime(file, &modtime);
5146 + printk("Failed to get modification time of backing file "
5147 + "\"%s\", err = %d\n", file, -err);
5151 err = os_file_size(file, &actual);
5154 printk("Failed to get size of backing file \"%s\", "
5155 - "errno = %d\n", file, -err);
5156 + "err = %d\n", file, -err);
5161 "file\n", size, actual);
5164 - if(buf.st_mtime != mtime){
5165 + if(modtime != mtime){
5166 printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
5167 - "file\n", mtime, buf.st_mtime);
5168 + "file\n", mtime, modtime);
5172 @@ -209,124 +91,16 @@
5175 err = os_seek_file(fd, offset);
5176 - if(err != 0) return(-errno);
5177 - err = read(fd, buf, len);
5178 - if(err < 0) return(-errno);
5184 -static int absolutize(char *to, int size, char *from)
5186 - char save_cwd[256], *slash;
5188 + err = os_read_file(fd, buf, len);
5192 - if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
5193 - printk("absolutize : unable to get cwd - errno = %d\n", errno);
5196 - slash = strrchr(from, '/');
5197 - if(slash != NULL){
5201 - printk("absolutize : Can't cd to '%s' - errno = %d\n",
5206 - if(getcwd(to, size) == NULL){
5207 - printk("absolutize : unable to get cwd of '%s' - "
5208 - "errno = %d\n", from, errno);
5211 - remaining = size - strlen(to);
5212 - if(strlen(slash) + 1 > remaining){
5213 - printk("absolutize : unable to fit '%s' into %d "
5214 - "chars\n", from, size);
5217 - strcat(to, slash);
5220 - if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
5221 - printk("absolutize : unable to fit '%s' into %d "
5222 - "chars\n", from, size);
5225 - strcpy(to, save_cwd);
5233 -static int write_cow_header(char *cow_file, int fd, char *backing_file,
5234 - int sectorsize, long long *size)
5236 - struct cow_header_v2 *header;
5237 - struct stat64 buf;
5240 - err = os_seek_file(fd, 0);
5242 - printk("write_cow_header - lseek failed, errno = %d\n", errno);
5247 - header = um_kmalloc(sizeof(*header));
5248 - if(header == NULL){
5249 - printk("Failed to allocate COW V2 header\n");
5252 - header->magic = htonl(COW_MAGIC);
5253 - header->version = htonl(COW_VERSION);
5256 - if(strlen(backing_file) > sizeof(header->backing_file) - 1){
5257 - printk("Backing file name \"%s\" is too long - names are "
5258 - "limited to %d characters\n", backing_file,
5259 - sizeof(header->backing_file) - 1);
5263 - if(absolutize(header->backing_file, sizeof(header->backing_file),
5267 - err = stat64(header->backing_file, &buf);
5269 - printk("Stat of backing file '%s' failed, errno = %d\n",
5270 - header->backing_file, errno);
5275 - err = os_file_size(header->backing_file, size);
5277 - printk("Couldn't get size of backing file '%s', errno = %d\n",
5278 - header->backing_file, -*size);
5282 - header->mtime = htonl(buf.st_mtime);
5283 - header->size = htonll(*size);
5284 - header->sectorsize = htonl(sectorsize);
5286 - err = write(fd, header, sizeof(*header));
5287 - if(err != sizeof(*header)){
5288 - printk("Write of header to new COW file '%s' failed, "
5289 - "errno = %d\n", cow_file, errno);
5299 int open_ubd_file(char *file, struct openflags *openflags,
5300 char **backing_file_out, int *bitmap_offset_out,
5301 unsigned long *bitmap_len_out, int *data_offset_out,
5302 @@ -334,26 +108,36 @@
5306 + __u32 version, align;
5308 - int fd, err, sectorsize, magic, same, mode = 0644;
5309 + int fd, err, sectorsize, same, mode = 0644;
5311 - if((fd = os_open_file(file, *openflags, mode)) < 0){
5312 + fd = os_open_file(file, *openflags, mode);
5314 if((fd == -ENOENT) && (create_cow_out != NULL))
5315 *create_cow_out = 1;
5317 ((errno != EROFS) && (errno != EACCES))) return(-errno);
5319 - if((fd = os_open_file(file, *openflags, mode)) < 0)
5320 + fd = os_open_file(file, *openflags, mode);
5325 + err = os_lock_file(fd, openflags->w);
5327 + printk("Failed to lock '%s', err = %d\n", file, -err);
5331 if(backing_file_out == NULL) return(fd);
5333 - err = read_cow_header(fd, &magic, &backing_file, &mtime, &size,
5334 - §orsize, bitmap_offset_out);
5335 + err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
5336 + &size, §orsize, &align, bitmap_offset_out);
5337 if(err && (*backing_file_out != NULL)){
5338 printk("Failed to read COW header from COW file \"%s\", "
5339 - "errno = %d\n", file, err);
5341 + "errno = %d\n", file, -err);
5346 @@ -363,36 +147,33 @@
5348 if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){
5349 printk("Switching backing file to '%s'\n", *backing_file_out);
5350 - err = write_cow_header(file, fd, *backing_file_out,
5351 - sectorsize, &size);
5352 + err = write_cow_header(file, fd, *backing_file_out,
5353 + sectorsize, align, &size);
5355 - printk("Switch failed, errno = %d\n", err);
5356 + printk("Switch failed, errno = %d\n", -err);
5361 *backing_file_out = backing_file;
5362 err = backing_file_mismatch(*backing_file_out, size, mtime);
5363 - if(err) goto error;
5364 + if(err) goto out_close;
5367 - sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out,
5369 + cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
5370 + bitmap_len_out, data_offset_out);
5376 + os_close_file(fd);
5380 int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
5381 - int sectorsize, int *bitmap_offset_out,
5382 + int sectorsize, int alignment, int *bitmap_offset_out,
5383 unsigned long *bitmap_len_out, int *data_offset_out)
5392 fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
5393 @@ -403,57 +184,49 @@
5397 - err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
5398 - if(err) goto out_close;
5400 - blocks = (size + sectorsize - 1) / sectorsize;
5401 - blocks = (blocks + sizeof(long) * 8 - 1) / (sizeof(long) * 8);
5403 - for(i = 0; i < blocks; i++){
5404 - err = write(fd, &zero, sizeof(zero));
5405 - if(err != sizeof(zero)){
5406 - printk("Write of bitmap to new COW file '%s' failed, "
5407 - "errno = %d\n", cow_file, errno);
5412 - sizes(size, sectorsize, sizeof(struct cow_header_v2),
5413 - bitmap_len_out, data_offset_out);
5414 - *bitmap_offset_out = sizeof(struct cow_header_v2);
5420 + err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
5421 + bitmap_offset_out, bitmap_len_out,
5425 + os_close_file(fd);
5430 +/* XXX Just trivial wrappers around os_read_file and os_write_file */
5431 int read_ubd_fs(int fd, void *buffer, int len)
5435 - n = read(fd, buffer, len);
5436 - if(n < 0) return(-errno);
5438 + return(os_read_file(fd, buffer, len));
5441 int write_ubd_fs(int fd, char *buffer, int len)
5445 - n = write(fd, buffer, len);
5446 - if(n < 0) return(-errno);
5448 + return(os_write_file(fd, buffer, len));
5451 -int ubd_is_dir(char *file)
5452 +static int update_bitmap(struct io_thread_req *req)
5454 - struct stat64 buf;
5457 + if(req->cow_offset == -1)
5460 + n = os_seek_file(req->fds[1], req->cow_offset);
5462 + printk("do_io - bitmap lseek failed : err = %d\n", -n);
5466 + n = os_write_file(req->fds[1], &req->bitmap_words,
5467 + sizeof(req->bitmap_words));
5468 + if(n != sizeof(req->bitmap_words)){
5469 + printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
5474 - if(stat64(file, &buf) < 0) return(0);
5475 - return(S_ISDIR(buf.st_mode));
5479 void do_io(struct io_thread_req *req)
5480 @@ -461,8 +234,18 @@
5483 int n, nsectors, start, end, bit;
5487 + if(req->op == UBD_MMAP){
5488 + /* Touch the page to force the host to do any necessary IO to
5489 + * get it into memory
5491 + n = *((volatile int *) req->buffer);
5492 + req->error = update_bitmap(req);
5496 nsectors = req->length / req->sectorsize;
5499 @@ -473,15 +256,14 @@
5500 &req->sector_mask) == bit))
5503 - if(end != nsectors)
5504 - printk("end != nsectors\n");
5505 off = req->offset + req->offsets[bit] +
5506 start * req->sectorsize;
5507 len = (end - start) * req->sectorsize;
5508 buf = &req->buffer[start * req->sectorsize];
5510 - if(os_seek_file(req->fds[bit], off) != 0){
5511 - printk("do_io - lseek failed : errno = %d\n", errno);
5512 + err = os_seek_file(req->fds[bit], off);
5514 + printk("do_io - lseek failed : err = %d\n", -err);
5518 @@ -490,11 +272,10 @@
5522 - n = read(req->fds[bit], buf, len);
5523 + n = os_read_file(req->fds[bit], buf, len);
5525 - printk("do_io - read returned %d : "
5526 - "errno = %d fd = %d\n", n,
5527 - errno, req->fds[bit]);
5528 + printk("do_io - read failed, err = %d "
5529 + "fd = %d\n", -n, req->fds[bit]);
5533 @@ -502,11 +283,10 @@
5534 if (n < len) memset(&buf[n], 0, len - n);
5537 - n = write(req->fds[bit], buf, len);
5538 + n = os_write_file(req->fds[bit], buf, len);
5540 - printk("do_io - write returned %d : "
5541 - "errno = %d fd = %d\n", n,
5542 - errno, req->fds[bit]);
5543 + printk("do_io - write failed err = %d "
5544 + "fd = %d\n", -n, req->fds[bit]);
5548 @@ -515,24 +295,7 @@
5550 } while(start < nsectors);
5552 - if(req->cow_offset != -1){
5553 - if(os_seek_file(req->fds[1], req->cow_offset) != 0){
5554 - printk("do_io - bitmap lseek failed : errno = %d\n",
5559 - n = write(req->fds[1], &req->bitmap_words,
5560 - sizeof(req->bitmap_words));
5561 - if(n != sizeof(req->bitmap_words)){
5562 - printk("do_io - bitmap update returned %d : "
5563 - "errno = %d fd = %d\n", n, errno, req->fds[1]);
5570 + req->error = update_bitmap(req);
5573 /* Changed in start_io_thread, which is serialized by being called only
5574 @@ -550,19 +313,23 @@
5576 signal(SIGWINCH, SIG_IGN);
5578 - n = read(kernel_fd, &req, sizeof(req));
5579 - if(n < 0) printk("io_thread - read returned %d, errno = %d\n",
5581 - else if(n < sizeof(req)){
5582 - printk("io_thread - short read : length = %d\n", n);
5583 + n = os_read_file(kernel_fd, &req, sizeof(req));
5584 + if(n != sizeof(req)){
5586 + printk("io_thread - read failed, fd = %d, "
5587 + "err = %d\n", kernel_fd, -n);
5589 + printk("io_thread - short read, fd = %d, "
5590 + "length = %d\n", kernel_fd, n);
5596 - n = write(kernel_fd, &req, sizeof(req));
5597 + n = os_write_file(kernel_fd, &req, sizeof(req));
5598 if(n != sizeof(req))
5599 - printk("io_thread - write failed, errno = %d\n",
5601 + printk("io_thread - write failed, fd = %d, err = %d\n",
5606 @@ -571,10 +338,11 @@
5607 int pid, fds[2], err;
5609 err = os_pipe(fds, 1, 1);
5611 - printk("start_io_thread - os_pipe failed, errno = %d\n", -err);
5614 + printk("start_io_thread - os_pipe failed, err = %d\n", -err);
5621 @@ -582,32 +350,19 @@
5624 printk("start_io_thread - clone failed : errno = %d\n", errno);
5632 -int start_io_thread(unsigned long sp, int *fd_out)
5636 - if((kernel_fd = get_pty()) < 0) return(-1);
5637 - raw(kernel_fd, 0);
5638 - if((*fd_out = open(ptsname(kernel_fd), O_RDWR)) < 0){
5639 - printk("Couldn't open tty for IO\n");
5643 - pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
5646 - printk("start_io_thread - clone failed : errno = %d\n", errno);
5652 + os_close_file(fds[0]);
5653 + os_close_file(fds[1]);
5662 * Overrides for Emacs so that we follow Linus's tabbing style.
5663 diff -Naur a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
5664 --- a/arch/um/drivers/xterm.c 2004-02-11 12:14:17.000000000 -0500
5665 +++ b/arch/um/drivers/xterm.c 2004-02-11 12:26:00.000000000 -0500
5671 #include <termios.h>
5676 struct xterm_chan *data;
5678 - if((data = malloc(sizeof(*data))) == NULL) return(NULL);
5679 + data = malloc(sizeof(*data));
5680 + if(data == NULL) return(NULL);
5681 *data = ((struct xterm_chan) { .pid = -1,
5685 "/usr/lib/uml/port-helper", "-uml-socket",
5688 - if(access(argv[4], X_OK))
5689 + if(os_access(argv[4], OS_ACC_X_OK) < 0)
5690 argv[4] = "port-helper";
5693 @@ -106,13 +106,13 @@
5694 printk("xterm_open : unlink failed, errno = %d\n", errno);
5698 + os_close_file(fd);
5700 - fd = create_unix_socket(file, sizeof(file));
5701 + fd = os_create_unix_socket(file, sizeof(file), 1);
5703 printk("xterm_open : create_unix_socket failed, errno = %d\n",
5709 sprintf(title, data->title, data->device);
5710 @@ -128,15 +128,16 @@
5711 if(data->direct_rcv)
5712 new = os_rcv_fd(fd, &data->helper_pid);
5714 - if((err = os_set_fd_block(fd, 0)) != 0){
5715 + err = os_set_fd_block(fd, 0);
5717 printk("xterm_open : failed to set descriptor "
5718 - "non-blocking, errno = %d\n", err);
5719 + "non-blocking, err = %d\n", -err);
5722 new = xterm_fd(fd, &data->helper_pid);
5725 - printk("xterm_open : os_rcv_fd failed, errno = %d\n", -new);
5726 + printk("xterm_open : os_rcv_fd failed, err = %d\n", -new);
5731 if(data->helper_pid != -1)
5732 os_kill_process(data->helper_pid, 0);
5733 data->helper_pid = -1;
5735 + os_close_file(fd);
5738 void xterm_free(void *d)
5739 diff -Naur a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
5740 --- a/arch/um/drivers/xterm_kern.c 2004-02-11 12:16:10.000000000 -0500
5741 +++ b/arch/um/drivers/xterm_kern.c 2004-02-11 12:28:20.000000000 -0500
5744 #include "linux/errno.h"
5745 #include "linux/slab.h"
5746 +#include "linux/signal.h"
5747 +#include "linux/interrupt.h"
5748 #include "asm/semaphore.h"
5749 #include "asm/irq.h"
5750 #include "irq_user.h"
5751 +#include "irq_kern.h"
5752 #include "kern_util.h"
5759 -static void xterm_interrupt(int irq, void *data, struct pt_regs *regs)
5760 +static irqreturn_t xterm_interrupt(int irq, void *data, struct pt_regs *regs)
5762 struct xterm_wait *xterm = data;
5765 fd = os_rcv_fd(xterm->fd, &xterm->pid);
5772 + return(IRQ_HANDLED);
5775 int xterm_fd(int socket, int *pid_out)
5778 printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
5789 *pid_out = data->pid;
5794 diff -Naur a/arch/um/dyn.lds.S b/arch/um/dyn.lds.S
5795 --- a/arch/um/dyn.lds.S 2004-02-11 12:15:45.000000000 -0500
5796 +++ b/arch/um/dyn.lds.S 2004-02-11 12:27:35.000000000 -0500
5799 . = START + SIZEOF_HEADERS;
5800 .interp : { *(.interp) }
5803 . = ALIGN(4096); /* Init code and data */
5806 - .text.init : { *(.text.init) }
5817 #include "asm/common.lds.S"
5819 - .data.init : { *(.data.init) }
5820 + init.data : { *(.init.data) }
5822 /* Ensure the __preinit_array_start label is properly aligned. We
5823 could instead move the label definition inside the section, but
5824 diff -Naur a/arch/um/include/2_5compat.h b/arch/um/include/2_5compat.h
5825 --- a/arch/um/include/2_5compat.h 2004-02-11 12:15:23.000000000 -0500
5826 +++ b/arch/um/include/2_5compat.h 2004-02-11 12:27:10.000000000 -0500
5828 #ifndef __2_5_COMPAT_H__
5829 #define __2_5_COMPAT_H__
5831 -#include "linux/version.h"
5833 -#define INIT_CONSOLE(dev_name, write_proc, device_proc, setup_proc, f) { \
5834 - name : dev_name, \
5835 - write : write_proc, \
5837 - device : device_proc, \
5838 - setup : setup_proc, \
5845 #define INIT_HARDSECT(arr, maj, sizes)
5847 #define SET_PRI(task) do ; while(0)
5848 diff -Naur a/arch/um/include/irq_kern.h b/arch/um/include/irq_kern.h
5849 --- a/arch/um/include/irq_kern.h 1969-12-31 19:00:00.000000000 -0500
5850 +++ b/arch/um/include/irq_kern.h 2004-02-11 12:27:15.000000000 -0500
5853 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
5854 + * Licensed under the GPL
5857 +#ifndef __IRQ_KERN_H__
5858 +#define __IRQ_KERN_H__
5860 +#include "linux/interrupt.h"
5862 +extern int um_request_irq(unsigned int irq, int fd, int type,
5863 + irqreturn_t (*handler)(int, void *,
5864 + struct pt_regs *),
5865 + unsigned long irqflags, const char * devname,
5871 + * Overrides for Emacs so that we follow Linus's tabbing style.
5872 + * Emacs will notice this stuff at the end of the file and automatically
5873 + * adjust the settings for this buffer only. This must remain at the end
5875 + * ---------------------------------------------------------------------------
5876 + * Local variables:
5877 + * c-file-style: "linux"
5880 diff -Naur a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
5881 --- a/arch/um/include/kern_util.h 2004-02-11 12:15:00.000000000 -0500
5882 +++ b/arch/um/include/kern_util.h 2004-02-11 12:26:51.000000000 -0500
5884 extern void *syscall_sp(void *t);
5885 extern void syscall_trace(void);
5886 extern int hz(void);
5887 -extern void idle_timer(void);
5888 +extern void uml_idle_timer(void);
5889 extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
5890 extern int external_pid(void *t);
5891 -extern int pid_to_processor_id(int pid);
5892 extern void boot_timer_handler(int sig);
5893 extern void interrupt_end(void);
5894 extern void initial_thread_cb(void (*proc)(void *), void *arg);
5896 extern char *uml_strdup(char *string);
5897 extern void unprotect_kernel_mem(void);
5898 extern void protect_kernel_mem(void);
5899 -extern void set_kmem_end(unsigned long);
5900 extern void uml_cleanup(void);
5901 -extern int pid_to_processor_id(int pid);
5902 extern void set_current(void *t);
5903 extern void lock_signalled_task(void *t);
5904 extern void IPI_handler(int cpu);
5906 extern int clear_user_proc(void *buf, int size);
5907 extern int copy_to_user_proc(void *to, void *from, int size);
5908 extern int copy_from_user_proc(void *to, void *from, int size);
5909 +extern int strlen_user_proc(char *str);
5910 extern void bus_handler(int sig, union uml_pt_regs *regs);
5911 +extern void winch(int sig, union uml_pt_regs *regs);
5912 extern long execute_syscall(void *r);
5913 extern int smp_sigio_handler(void);
5914 extern void *get_current(void);
5916 extern void free_irq(unsigned int, void *);
5917 extern int um_in_interrupt(void);
5918 extern int cpu(void);
5919 +extern unsigned long long time_stamp(void);
5924 diff -Naur a/arch/um/include/line.h b/arch/um/include/line.h
5925 --- a/arch/um/include/line.h 2004-02-11 12:16:27.000000000 -0500
5926 +++ b/arch/um/include/line.h 2004-02-11 12:28:24.000000000 -0500
5928 #include "linux/list.h"
5929 #include "linux/workqueue.h"
5930 #include "linux/tty.h"
5931 +#include "linux/interrupt.h"
5932 #include "asm/semaphore.h"
5933 #include "chan_user.h"
5934 #include "mconsole_kern.h"
5936 struct line_driver {
5938 + char *device_name;
5944 #define LINES_INIT(n) { num : n }
5946 -extern void line_interrupt(int irq, void *data, struct pt_regs *unused);
5947 -extern void line_write_interrupt(int irq, void *data, struct pt_regs *unused);
5948 extern void line_close(struct line *lines, struct tty_struct *tty);
5949 extern int line_open(struct line *lines, struct tty_struct *tty,
5950 struct chan_opts *opts);
5951 diff -Naur a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
5952 --- a/arch/um/include/mconsole.h 2004-02-11 12:15:15.000000000 -0500
5953 +++ b/arch/um/include/mconsole.h 2004-02-11 12:27:02.000000000 -0500
5958 +enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC };
5960 struct mconsole_command
5963 void (*handler)(struct mc_request *req);
5965 + enum mc_context context;
5970 extern void mconsole_cad(struct mc_request *req);
5971 extern void mconsole_stop(struct mc_request *req);
5972 extern void mconsole_go(struct mc_request *req);
5973 +extern void mconsole_log(struct mc_request *req);
5974 +extern void mconsole_proc(struct mc_request *req);
5976 extern int mconsole_get_request(int fd, struct mc_request *req);
5977 extern int mconsole_notify(char *sock_name, int type, const void *data,
5978 diff -Naur a/arch/um/include/mem.h b/arch/um/include/mem.h
5979 --- a/arch/um/include/mem.h 2004-02-11 12:17:08.000000000 -0500
5980 +++ b/arch/um/include/mem.h 2004-02-11 12:29:12.000000000 -0500
5983 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
5984 + * Copyright (C) 2002, 2003 Jeff Dike (jdike@addtoit.com)
5985 * Licensed under the GPL
5991 -struct vm_reserved {
5992 - struct list_head list;
5993 - unsigned long start;
5994 - unsigned long end;
5996 +#include "linux/types.h"
5998 -extern void set_usable_vm(unsigned long start, unsigned long end);
5999 -extern void set_kmem_end(unsigned long new);
6000 +extern int phys_mapping(unsigned long phys, __u64 *offset_out);
6001 +extern int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w);
6002 +extern int is_remapped(void *virt);
6003 +extern int physmem_remove_mapping(void *virt);
6004 +extern void physmem_forget_descriptor(int fd);
6008 diff -Naur a/arch/um/include/mem_kern.h b/arch/um/include/mem_kern.h
6009 --- a/arch/um/include/mem_kern.h 1969-12-31 19:00:00.000000000 -0500
6010 +++ b/arch/um/include/mem_kern.h 2004-02-11 12:27:40.000000000 -0500
6013 + * Copyright (C) 2003 Jeff Dike (jdike@addtoit.com)
6014 + * Licensed under the GPL
6017 +#ifndef __MEM_KERN_H__
6018 +#define __MEM_KERN_H__
6020 +#include "linux/list.h"
6021 +#include "linux/types.h"
6024 + struct list_head list;
6025 + int (*proc)(int, unsigned long, int, __u64);
6028 +extern void register_remapper(struct remapper *info);
6033 + * Overrides for Emacs so that we follow Linus's tabbing style.
6034 + * Emacs will notice this stuff at the end of the file and automatically
6035 + * adjust the settings for this buffer only. This must remain at the end
6037 + * ---------------------------------------------------------------------------
6038 + * Local variables:
6039 + * c-file-style: "linux"
6042 diff -Naur a/arch/um/include/mem_user.h b/arch/um/include/mem_user.h
6043 --- a/arch/um/include/mem_user.h 2004-02-11 12:16:03.000000000 -0500
6044 +++ b/arch/um/include/mem_user.h 2004-02-11 12:27:57.000000000 -0500
6049 -struct mem_region {
6050 +struct iomem_region {
6051 + struct iomem_region *next;
6053 - unsigned long start_pfn;
6054 - unsigned long start;
6055 - unsigned long len;
6059 + unsigned long phys;
6060 + unsigned long virt;
6063 -extern struct mem_region *regions[];
6064 -extern struct mem_region physmem_region;
6065 +extern struct iomem_region *iomem_regions;
6066 +extern int iomem_size;
6068 #define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
6070 extern unsigned long host_task_size;
6071 extern unsigned long task_size;
6073 +extern void check_devanon(void);
6074 extern int init_mem_user(void);
6075 extern int create_mem_file(unsigned long len);
6076 -extern void setup_range(int fd, char *driver, unsigned long start,
6077 - unsigned long pfn, unsigned long total, int need_vm,
6078 - struct mem_region *region, void *reserved);
6079 extern void setup_memory(void *entry);
6080 extern unsigned long find_iomem(char *driver, unsigned long *len_out);
6081 -extern int init_maps(struct mem_region *region);
6082 -extern int nregions(void);
6083 -extern int reserve_vm(unsigned long start, unsigned long end, void *e);
6084 +extern int init_maps(unsigned long physmem, unsigned long iomem,
6085 + unsigned long highmem);
6086 extern unsigned long get_vm(unsigned long len);
6087 extern void setup_physmem(unsigned long start, unsigned long usable,
6088 - unsigned long len);
6089 -extern int setup_region(struct mem_region *region, void *entry);
6090 + unsigned long len, unsigned long highmem);
6091 extern void add_iomem(char *name, int fd, unsigned long size);
6092 -extern struct mem_region *phys_region(unsigned long phys);
6093 extern unsigned long phys_offset(unsigned long phys);
6094 extern void unmap_physmem(void);
6095 -extern int map_memory(unsigned long virt, unsigned long phys,
6096 - unsigned long len, int r, int w, int x);
6097 +extern void map_memory(unsigned long virt, unsigned long phys,
6098 + unsigned long len, int r, int w, int x);
6099 extern int protect_memory(unsigned long addr, unsigned long len,
6100 int r, int w, int x, int must_succeed);
6101 extern unsigned long get_kmem_end(void);
6102 diff -Naur a/arch/um/include/os.h b/arch/um/include/os.h
6103 --- a/arch/um/include/os.h 2004-02-11 12:14:31.000000000 -0500
6104 +++ b/arch/um/include/os.h 2004-02-11 12:26:12.000000000 -0500
6106 #define OS_TYPE_FIFO 6
6107 #define OS_TYPE_SOCK 7
6109 +/* os_access() flags */
6110 +#define OS_ACC_F_OK 0 /* Test for existence. */
6111 +#define OS_ACC_X_OK 1 /* Test for execute permission. */
6112 +#define OS_ACC_W_OK 2 /* Test for write permission. */
6113 +#define OS_ACC_R_OK 4 /* Test for read permission. */
6114 +#define OS_ACC_RW_OK (OS_ACC_W_OK | OS_ACC_R_OK) /* Test for RW permission */
6117 + * types taken from stat_file() in hostfs_user.c
6118 + * (if they are wrong here, they are wrong there...).
6121 + int ust_dev; /* device */
6122 + unsigned long long ust_ino; /* inode */
6123 + int ust_mode; /* protection */
6124 + int ust_nlink; /* number of hard links */
6125 + int ust_uid; /* user ID of owner */
6126 + int ust_gid; /* group ID of owner */
6127 + unsigned long long ust_size; /* total size, in bytes */
6128 + int ust_blksize; /* blocksize for filesystem I/O */
6129 + unsigned long long ust_blocks; /* number of blocks allocated */
6130 + unsigned long ust_atime; /* time of last access */
6131 + unsigned long ust_mtime; /* time of last modification */
6132 + unsigned long ust_ctime; /* time of last change */
6138 @@ -84,29 +110,47 @@
6144 static inline struct openflags of_cloexec(struct openflags flags)
6150 +extern int os_stat_file(const char *file_name, struct uml_stat *buf);
6151 +extern int os_stat_fd(const int fd, struct uml_stat *buf);
6152 +extern int os_access(const char *file, int mode);
6153 +extern void os_print_error(int error, const char* str);
6154 +extern int os_get_exec_close(int fd, int *close_on_exec);
6155 +extern int os_set_exec_close(int fd, int close_on_exec);
6156 +extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg);
6157 +extern int os_window_size(int fd, int *rows, int *cols);
6158 +extern int os_new_tty_pgrp(int fd, int pid);
6159 +extern int os_get_ifname(int fd, char *namebuf);
6160 +extern int os_set_slip(int fd);
6161 +extern int os_set_owner(int fd, int pid);
6162 +extern int os_sigio_async(int master, int slave);
6163 +extern int os_mode_fd(int fd, int mode);
6165 extern int os_seek_file(int fd, __u64 offset);
6166 extern int os_open_file(char *file, struct openflags flags, int mode);
6167 extern int os_read_file(int fd, void *buf, int len);
6168 -extern int os_write_file(int fd, void *buf, int count);
6169 +extern int os_write_file(int fd, const void *buf, int count);
6170 extern int os_file_size(char *file, long long *size_out);
6171 +extern int os_file_modtime(char *file, unsigned long *modtime);
6172 extern int os_pipe(int *fd, int stream, int close_on_exec);
6173 extern int os_set_fd_async(int fd, int owner);
6174 extern int os_set_fd_block(int fd, int blocking);
6175 extern int os_accept_connection(int fd);
6176 +extern int os_create_unix_socket(char *file, int len, int close_on_exec);
6177 extern int os_shutdown_socket(int fd, int r, int w);
6178 extern void os_close_file(int fd);
6179 extern int os_rcv_fd(int fd, int *helper_pid_out);
6180 -extern int create_unix_socket(char *file, int len);
6181 +extern int create_unix_socket(char *file, int len, int close_on_exec);
6182 extern int os_connect_socket(char *name);
6183 extern int os_file_type(char *file);
6184 extern int os_file_mode(char *file, struct openflags *mode_out);
6185 +extern int os_lock_file(int fd, int excl);
6187 extern unsigned long os_process_pc(int pid);
6188 extern int os_process_parent(int pid);
6189 @@ -115,11 +159,12 @@
6190 extern void os_usr1_process(int pid);
6191 extern int os_getpid(void);
6193 -extern int os_map_memory(void *virt, int fd, unsigned long off,
6194 +extern int os_map_memory(void *virt, int fd, unsigned long long off,
6195 unsigned long len, int r, int w, int x);
6196 extern int os_protect_memory(void *addr, unsigned long len,
6197 int r, int w, int x);
6198 extern int os_unmap_memory(void *addr, int len);
6199 +extern void os_flush_stdout(void);
6203 diff -Naur a/arch/um/include/skas_ptrace.h b/arch/um/include/skas_ptrace.h
6204 --- a/arch/um/include/skas_ptrace.h 2004-02-11 12:16:37.000000000 -0500
6205 +++ b/arch/um/include/skas_ptrace.h 2004-02-11 12:28:37.000000000 -0500
6208 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
6209 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
6210 * Licensed under the GPL
6213 diff -Naur a/arch/um/include/sysdep-i386/frame_user.h b/arch/um/include/sysdep-i386/frame_user.h
6214 --- a/arch/um/include/sysdep-i386/frame_user.h 2004-02-11 12:16:44.000000000 -0500
6215 +++ b/arch/um/include/sysdep-i386/frame_user.h 2004-02-11 12:29:00.000000000 -0500
6217 * it would have to be __builtin_frame_address(1).
6220 -static inline unsigned long frame_restorer(void)
6222 - unsigned long *fp;
6224 - fp = __builtin_frame_address(0);
6225 - return((unsigned long) (fp + 1));
6227 +#define frame_restorer() \
6229 + unsigned long *fp; \
6231 + fp = __builtin_frame_address(0); \
6232 + ((unsigned long) (fp + 1)); \
6235 /* Similarly, this returns the value of sp when the handler was first
6236 * entered. This is used to calculate the proper sp when delivering
6240 -static inline unsigned long frame_sp(void)
6242 - unsigned long *fp;
6244 - fp = __builtin_frame_address(0);
6245 - return((unsigned long) (fp + 1));
6247 +#define frame_sp() \
6249 + unsigned long *fp; \
6251 + fp = __builtin_frame_address(0); \
6252 + ((unsigned long) (fp + 1)); \
6257 diff -Naur a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h
6258 --- a/arch/um/include/sysdep-i386/sigcontext.h 2004-02-11 12:16:08.000000000 -0500
6259 +++ b/arch/um/include/sysdep-i386/sigcontext.h 2004-02-11 12:28:19.000000000 -0500
6262 #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
6264 -/* These are General Protection and Page Fault */
6265 -#define SEGV_IS_FIXABLE(trap) ((trap == 13) || (trap == 14))
6266 +/* This is Page Fault */
6267 +#define SEGV_IS_FIXABLE(trap) (trap == 14)
6269 #define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
6271 diff -Naur a/arch/um/include/ubd_user.h b/arch/um/include/ubd_user.h
6272 --- a/arch/um/include/ubd_user.h 2004-02-11 12:15:48.000000000 -0500
6273 +++ b/arch/um/include/ubd_user.h 2004-02-11 12:27:41.000000000 -0500
6278 -enum ubd_req { UBD_READ, UBD_WRITE };
6279 +enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
6281 struct io_thread_req {
6286 unsigned long sector_mask;
6287 - unsigned long cow_offset;
6288 + unsigned long long cow_offset;
6289 unsigned long bitmap_words[2];
6291 + unsigned long long map_offset;
6296 int *create_cow_out);
6297 extern int create_cow_file(char *cow_file, char *backing_file,
6298 struct openflags flags, int sectorsize,
6299 - int *bitmap_offset_out,
6300 + int alignment, int *bitmap_offset_out,
6301 unsigned long *bitmap_len_out,
6302 int *data_offset_out);
6303 extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
6305 extern int write_ubd_fs(int fd, char *buffer, int len);
6306 extern int start_io_thread(unsigned long sp, int *fds_out);
6307 extern void do_io(struct io_thread_req *req);
6308 -extern int ubd_is_dir(char *file);
6310 static inline int ubd_test_bit(__u64 bit, unsigned char *data)
6312 diff -Naur a/arch/um/include/um_uaccess.h b/arch/um/include/um_uaccess.h
6313 --- a/arch/um/include/um_uaccess.h 2004-02-11 12:16:07.000000000 -0500
6314 +++ b/arch/um/include/um_uaccess.h 2004-02-11 12:28:02.000000000 -0500
6320 + * strncpy_from_user: - Copy a NUL terminated string from userspace.
6321 + * @dst: Destination address, in kernel space. This buffer must be at
6322 + * least @count bytes long.
6323 + * @src: Source address, in user space.
6324 + * @count: Maximum number of bytes to copy, including the trailing NUL.
6326 + * Copies a NUL-terminated string from userspace to kernel space.
6328 + * On success, returns the length of the string (not including the trailing
6331 + * If access to userspace fails, returns -EFAULT (some data may have been
6334 + * If @count is smaller than the length of the string, copies @count bytes
6335 + * and returns @count.
6338 static inline int strncpy_from_user(char *dst, const char *src, int count)
6340 return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas,
6345 + * __clear_user: - Zero a block of memory in user space, with less checking.
6346 + * @to: Destination address, in user space.
6347 + * @n: Number of bytes to zero.
6349 + * Zero a block of memory in user space. Caller must check
6350 + * the specified block with access_ok() before calling this function.
6352 + * Returns number of bytes that could not be cleared.
6353 + * On success, this will be zero.
6355 static inline int __clear_user(void *mem, int len)
6357 return(CHOOSE_MODE_PROC(__clear_user_tt, __clear_user_skas, mem, len));
6361 + * clear_user: - Zero a block of memory in user space.
6362 + * @to: Destination address, in user space.
6363 + * @n: Number of bytes to zero.
6365 + * Zero a block of memory in user space.
6367 + * Returns number of bytes that could not be cleared.
6368 + * On success, this will be zero.
6370 static inline int clear_user(void *mem, int len)
6372 return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len));
6376 + * strlen_user: - Get the size of a string in user space.
6377 + * @str: The string to measure.
6378 + * @n: The maximum valid length
6380 + * Get the size of a NUL-terminated string in user space.
6382 + * Returns the size of the string INCLUDING the terminating NUL.
6383 + * On exception, returns 0.
6384 + * If the string is too long, returns a value greater than @n.
6386 static inline int strnlen_user(const void *str, int len)
6388 return(CHOOSE_MODE_PROC(strnlen_user_tt, strnlen_user_skas, str, len));
6389 diff -Naur a/arch/um/include/user.h b/arch/um/include/user.h
6390 --- a/arch/um/include/user.h 2004-02-11 12:14:17.000000000 -0500
6391 +++ b/arch/um/include/user.h 2004-02-11 12:26:00.000000000 -0500
6393 extern void kfree(void *ptr);
6394 extern int in_aton(char *str);
6395 extern int open_gdb_chan(void);
6396 +extern int strlcpy(char *, const char *, int);
6400 diff -Naur a/arch/um/include/user_util.h b/arch/um/include/user_util.h
6401 --- a/arch/um/include/user_util.h 2004-02-11 12:14:23.000000000 -0500
6402 +++ b/arch/um/include/user_util.h 2004-02-11 12:26:06.000000000 -0500
6404 extern int unlockpt(int __fd);
6405 extern char *ptsname(int __fd);
6407 -enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
6413 extern void *add_signal_handler(int sig, void (*handler)(int));
6414 extern int start_fork_tramp(void *arg, unsigned long temp_stack,
6415 int clone_flags, int (*tramp)(void *));
6416 -extern int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags);
6417 extern int linux_main(int argc, char **argv);
6418 extern void set_cmdline(char *cmd);
6419 extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
6421 extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
6422 extern void write_sigio_workaround(void);
6423 extern void arch_check_bugs(void);
6424 +extern int cpu_feature(char *what, char *buf, int len);
6425 extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
6426 extern int arch_fixup(unsigned long address, void *sc_ptr);
6427 extern void forward_pending_sigio(int target);
6428 extern int can_do_skas(void);
6430 +extern void arch_init_thread(void);
6435 diff -Naur a/arch/um/Kconfig b/arch/um/Kconfig
6436 --- a/arch/um/Kconfig 2004-02-11 12:15:26.000000000 -0500
6437 +++ b/arch/um/Kconfig 2004-02-11 12:27:15.000000000 -0500
6441 bool "Networking support"
6443 + Unless you really know what you are doing, you should say Y here.
6444 + The reason is that some programs need kernel networking support even
6445 + when running on a stand-alone machine that isn't connected to any
6446 + other computer. If you are upgrading from an older kernel, you
6447 + should consider updating your networking tools too because changes
6448 + in the kernel and the tools often go hand in hand. The tools are
6449 + contained in the package net-tools, the location and version number
6450 + of which are given in Documentation/Changes.
6452 + For a general introduction to Linux networking, it is highly
6453 + recommended to read the NET-HOWTO, available from
6454 + <http://www.tldp.org/docs.html#howto>.
6457 source "fs/Kconfig.binfmt"
6460 If you'd like to be able to work with files stored on the host,
6461 say Y or M here; otherwise say N.
6464 + tristate "HoneyPot ProcFS"
6466 + hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
6467 + entries to be overridden, removed, or fabricated from the host.
6468 + Its purpose is to allow a UML to appear to be a physical machine
6469 + by removing or changing anything in /proc which gives away the
6470 + identity of a UML.
6472 + See http://user-mode-linux.sf.net/hppfs.html for more information.
6474 + You only need this if you are setting up a UML honeypot. Otherwise,
6475 + it is safe to say 'N' here.
6478 bool "Management console"
6479 @@ -105,6 +132,16 @@
6481 bool "Magic SysRq key"
6484 + If you say Y here, you will have some control over the system even
6485 + if the system crashes for example during kernel debugging (e.g., you
6486 + will be able to flush the buffer cache to disk, reboot the system
6487 + immediately or dump some status information). This is accomplished
6488 + by pressing various keys while holding SysRq (Alt+PrintScreen). It
6489 + also works on a serial console (on PC hardware at least), if you
6490 + send a BREAK and then within 5 seconds a command keypress. The
6491 + keys are documented in Documentation/sysrq.txt. Don't say Y
6492 + unless you really know what this hack does.
6495 bool "2G/2G host address space split"
6498 bool "Highmem support"
6501 + bool "/proc/mm support"
6503 config KERNEL_STACK_ORDER
6504 int "Kernel stack size order"
6506 @@ -168,6 +208,17 @@
6507 be 1 << order pages. The default is OK unless you're running Valgrind
6508 on UML, in which case, set this to 3.
6510 +config UML_REAL_TIME_CLOCK
6511 + bool "Real-time Clock"
6514 + This option makes UML time deltas match wall clock deltas. This should
6515 + normally be enabled. The exception would be if you are debugging with
6516 + UML and spend long times with UML stopped at a breakpoint. In this
6517 + case, when UML is restarted, it will call the timer enough times to make
6518 + up for the time spent at the breakpoint. This could result in a
6519 + noticable lag. If this is a problem, then disable this option.
6523 source "init/Kconfig"
6524 @@ -240,6 +291,10 @@
6526 bool "Enable ptrace proxy"
6527 depends on XTERM_CHAN && DEBUG_INFO
6529 + This option enables a debugging interface which allows gdb to debug
6530 + the kernel without needing to actually attach to kernel threads.
6531 + If you want to do kernel debugging, say Y here; otherwise say N.
6534 bool "Enable gprof support"
6535 diff -Naur a/arch/um/Kconfig_block b/arch/um/Kconfig_block
6536 --- a/arch/um/Kconfig_block 2004-02-11 12:16:04.000000000 -0500
6537 +++ b/arch/um/Kconfig_block 2004-02-11 12:28:00.000000000 -0500
6539 wise choice too. In all other cases (for example, if you're just
6540 playing around with User-Mode Linux) you can choose N.
6542 +# Turn this back on when the driver actually works
6544 +#config BLK_DEV_COW
6545 +# tristate "COW block device"
6547 +# This is a layered driver which sits above two other block devices.
6548 +# One is read-only, and the other is a read-write layer which stores
6549 +# all changes. This provides the illusion that the read-only layer
6550 +# can be mounted read-write and changed.
6552 +config BLK_DEV_COW_COMMON
6554 + default BLK_DEV_COW || BLK_DEV_UBD
6557 tristate "Loopback device support"
6559 diff -Naur a/arch/um/Kconfig_net b/arch/um/Kconfig_net
6560 --- a/arch/um/Kconfig_net 2004-02-11 12:15:54.000000000 -0500
6561 +++ b/arch/um/Kconfig_net 2004-02-11 12:27:47.000000000 -0500
6564 -menu "Network Devices"
6565 +menu "UML Network Devices"
6568 # UML virtual driver
6569 @@ -176,73 +176,5 @@
6571 Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
6574 -# Below are hardware-independent drivers mirrored from
6575 -# drivers/net/Config.in. It would be nice if Linux
6576 -# had HW independent drivers separated from the other
6577 -# but it does not. Until then each non-ISA/PCI arch
6578 -# needs to provide it's own menu of network drivers
6580 - tristate "Dummy net driver support"
6583 - tristate "Bonding driver support"
6586 - tristate "EQL (serial line load balancing) support"
6589 - tristate "Universal TUN/TAP device driver support"
6592 - tristate "Ethertap network tap (OBSOLETE)"
6593 - depends on EXPERIMENTAL && NETLINK
6596 - tristate "PPP (point-to-point protocol) support"
6598 -config PPP_MULTILINK
6599 - bool "PPP multilink support (EXPERIMENTAL)"
6600 - depends on PPP && EXPERIMENTAL
6603 - bool "PPP filtering"
6604 - depends on PPP && FILTER
6607 - tristate "PPP support for async serial ports"
6610 -config PPP_SYNC_TTY
6611 - tristate "PPP support for sync tty ports"
6615 - tristate "PPP Deflate compression"
6619 - tristate "PPP BSD-Compress compression"
6623 - tristate "PPP over Ethernet (EXPERIMENTAL)"
6624 - depends on PPP && EXPERIMENTAL
6627 - tristate "SLIP (serial line) support"
6629 -config SLIP_COMPRESSED
6630 - bool "CSLIP compressed headers"
6634 - bool "Keepalive and linefill"
6637 -config SLIP_MODE_SLIP6
6638 - bool "Six bit SLIP encapsulation"
6643 diff -Naur a/arch/um/kernel/config.c.in b/arch/um/kernel/config.c.in
6644 --- a/arch/um/kernel/config.c.in 2004-02-11 12:16:10.000000000 -0500
6645 +++ b/arch/um/kernel/config.c.in 2004-02-11 12:28:20.000000000 -0500
6650 -static __initdata char *config = "
6653 +static __initdata char *config = "CONFIG";
6655 static int __init print_config(char *line, int *add)
6657 diff -Naur a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec_kern.c
6658 --- a/arch/um/kernel/exec_kern.c 2004-02-11 12:14:34.000000000 -0500
6659 +++ b/arch/um/kernel/exec_kern.c 2004-02-11 12:26:17.000000000 -0500
6661 CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
6664 +extern void log_exec(char **argv, void *tty);
6666 static int execve1(char *file, char **argv, char **env)
6670 +#ifdef CONFIG_TTY_LOG
6671 + log_exec(argv, current->tty);
6673 error = do_execve(file, argv, env, ¤t->thread.regs);
6675 current->ptrace &= ~PT_DTRACE;
6676 diff -Naur a/arch/um/kernel/frame.c b/arch/um/kernel/frame.c
6677 --- a/arch/um/kernel/frame.c 2004-02-11 12:14:57.000000000 -0500
6678 +++ b/arch/um/kernel/frame.c 2004-02-11 12:26:47.000000000 -0500
6680 struct sc_frame_raw raw_sc;
6681 struct si_frame_raw raw_si;
6682 void *stack, *sigstack;
6683 - unsigned long top, sig_top, base;
6684 + unsigned long top, base;
6686 stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
6687 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
6691 top = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
6692 - sig_top = (unsigned long) sigstack + PAGE_SIZE;
6694 /* Get the sigcontext, no sigrestorer layout */
6695 raw_sc.restorer = 0;
6696 diff -Naur a/arch/um/kernel/frame_kern.c b/arch/um/kernel/frame_kern.c
6697 --- a/arch/um/kernel/frame_kern.c 2004-02-11 12:17:12.000000000 -0500
6698 +++ b/arch/um/kernel/frame_kern.c 2004-02-11 12:29:17.000000000 -0500
6700 #include "asm/ptrace.h"
6701 #include "asm/uaccess.h"
6702 #include "asm/signal.h"
6703 -#include "asm/uaccess.h"
6704 #include "asm/ucontext.h"
6705 #include "frame_kern.h"
6706 #include "sigcontext.h"
6711 +extern int userspace_pid[];
6713 static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from,
6714 struct arch_frame_data *arch)
6716 return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
6718 - copy_sc_to_user_skas(to, fp, &from->regs,
6719 + copy_sc_to_user_skas(userspace_pid[0], to, fp,
6721 current->thread.cr2,
6722 current->thread.err)));
6724 diff -Naur a/arch/um/kernel/helper.c b/arch/um/kernel/helper.c
6725 --- a/arch/um/kernel/helper.c 2004-02-11 12:15:26.000000000 -0500
6726 +++ b/arch/um/kernel/helper.c 2004-02-11 12:27:13.000000000 -0500
6733 #include <sys/signal.h>
6734 #include <sys/wait.h>
6737 struct helper_data *data = arg;
6738 char **argv = data->argv;
6742 signal(SIGHUP, helper_hup);
6744 if(data->pre_exec != NULL)
6745 (*data->pre_exec)(data->pre_data);
6746 execvp(argv[0], argv);
6748 printk("execvp of '%s' failed - errno = %d\n", argv[0], errno);
6749 - write(data->fd, &errno, sizeof(errno));
6750 + os_write_file(data->fd, &errval, sizeof(errval));
6751 os_kill_process(os_getpid(), 0);
6755 if((stack_out != NULL) && (*stack_out != 0))
6757 else stack = alloc_stack(0, um_in_interrupt());
6758 - if(stack == 0) return(-ENOMEM);
6762 err = os_pipe(fds, 1, 0);
6764 - printk("run_helper : pipe failed, errno = %d\n", -err);
6767 + printk("run_helper : pipe failed, err = %d\n", -err);
6770 - if(fcntl(fds[1], F_SETFD, 1) != 0){
6771 - printk("run_helper : setting FD_CLOEXEC failed, errno = %d\n",
6775 + err = os_set_exec_close(fds[1], 1);
6777 + printk("run_helper : setting FD_CLOEXEC failed, err = %d\n",
6782 sp = stack + page_size() - sizeof(void *);
6784 pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
6786 printk("run_helper : clone failed, errno = %d\n", errno);
6792 - n = read(fds[0], &err, sizeof(err));
6794 + os_close_file(fds[1]);
6795 + n = os_read_file(fds[0], &err, sizeof(err));
6797 - printk("run_helper : read on pipe failed, errno = %d\n",
6800 + printk("run_helper : read on pipe failed, err = %d\n", -n);
6805 waitpid(pid, NULL, 0);
6810 if(stack_out == NULL) free_stack(stack, 0);
6811 else *stack_out = stack;
6815 + os_kill_process(pid, 1);
6817 + os_close_file(fds[0]);
6818 + os_close_file(fds[1]);
6820 + free_stack(stack, 0);
6824 int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
6825 @@ -117,9 +132,11 @@
6827 if(stack_out == NULL){
6828 pid = waitpid(pid, &status, 0);
6831 printk("run_helper_thread - wait failed, errno = %d\n",
6836 if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
6837 printk("run_helper_thread - thread returned status "
6839 diff -Naur a/arch/um/kernel/initrd_user.c b/arch/um/kernel/initrd_user.c
6840 --- a/arch/um/kernel/initrd_user.c 2004-02-11 12:14:28.000000000 -0500
6841 +++ b/arch/um/kernel/initrd_user.c 2004-02-11 12:26:11.000000000 -0500
6844 #include <sys/types.h>
6845 #include <sys/stat.h>
6849 #include "user_util.h"
6854 - if((fd = os_open_file(filename, of_read(OPENFLAGS()), 0)) < 0){
6855 - printk("Opening '%s' failed - errno = %d\n", filename, errno);
6856 + fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
6858 + printk("Opening '%s' failed - err = %d\n", filename, -fd);
6861 - if((n = read(fd, buf, size)) != size){
6862 - printk("Read of %d bytes from '%s' returned %d, errno = %d\n",
6863 - size, filename, n, errno);
6864 + n = os_read_file(fd, buf, size);
6866 + printk("Read of %d bytes from '%s' failed, err = %d\n", size,
6871 diff -Naur a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c
6872 --- a/arch/um/kernel/init_task.c 2004-02-11 12:17:10.000000000 -0500
6873 +++ b/arch/um/kernel/init_task.c 2004-02-11 12:29:16.000000000 -0500
6875 #include "linux/module.h"
6876 #include "linux/sched.h"
6877 #include "linux/init_task.h"
6878 -#include "linux/version.h"
6879 #include "asm/uaccess.h"
6880 #include "asm/pgtable.h"
6881 #include "user_util.h"
6883 struct mm_struct init_mm = INIT_MM(init_mm);
6884 static struct files_struct init_files = INIT_FILES;
6885 static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
6887 +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
6888 EXPORT_SYMBOL(init_mm);
6892 __attribute__((__section__(".data.init_task"))) =
6893 { INIT_THREAD_INFO(init_task) };
6895 -struct task_struct *alloc_task_struct(void)
6897 - return((struct task_struct *)
6898 - __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
6901 void unprotect_stack(unsigned long stack)
6903 protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE,
6907 -void free_task_struct(struct task_struct *task)
6909 - /* free_pages decrements the page counter and only actually frees
6910 - * the pages if they are now not accessed by anything.
6912 - free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
6916 * Overrides for Emacs so that we follow Linus's tabbing style.
6917 * Emacs will notice this stuff at the end of the file and automatically
6918 diff -Naur a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
6919 --- a/arch/um/kernel/irq.c 2004-02-11 12:16:32.000000000 -0500
6920 +++ b/arch/um/kernel/irq.c 2004-02-11 12:28:31.000000000 -0500
6922 #include "user_util.h"
6923 #include "kern_util.h"
6924 #include "irq_user.h"
6925 +#include "irq_kern.h"
6927 static void register_irq_proc (unsigned int irq);
6934 -volatile unsigned long irq_err_count;
6937 * Generic, controller-independent functions:
6940 -int get_irq_list(char *buf)
6941 +int show_interrupts(struct seq_file *p, void *v)
6944 - unsigned long flags;
6945 + int i = *(loff_t *) v, j;
6946 struct irqaction * action;
6948 + unsigned long flags;
6950 - p += sprintf(p, " ");
6951 - for (j=0; j<num_online_cpus(); j++)
6952 - p += sprintf(p, "CPU%d ",j);
6955 + seq_printf(p, " ");
6956 + for (j=0; j<NR_CPUS; j++)
6957 + if (cpu_online(j))
6958 + seq_printf(p, "CPU%d ",j);
6959 + seq_putc(p, '\n');
6962 - for (i = 0 ; i < NR_IRQS ; i++) {
6963 + if (i < NR_IRQS) {
6964 spin_lock_irqsave(&irq_desc[i].lock, flags);
6965 action = irq_desc[i].action;
6968 - p += sprintf(p, "%3d: ",i);
6970 + seq_printf(p, "%3d: ",i);
6972 - p += sprintf(p, "%10u ", kstat_irqs(i));
6973 + seq_printf(p, "%10u ", kstat_irqs(i));
6975 - for (j = 0; j < num_online_cpus(); j++)
6976 - p += sprintf(p, "%10u ",
6977 - kstat_cpu(cpu_logical_map(j)).irqs[i]);
6978 + for (j = 0; j < NR_CPUS; j++)
6979 + if (cpu_online(j))
6980 + seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
6982 - p += sprintf(p, " %14s", irq_desc[i].handler->typename);
6983 - p += sprintf(p, " %s", action->name);
6984 + seq_printf(p, " %14s", irq_desc[i].handler->typename);
6985 + seq_printf(p, " %s", action->name);
6987 for (action=action->next; action; action = action->next)
6988 - p += sprintf(p, ", %s", action->name);
6991 + seq_printf(p, ", %s", action->name);
6993 + seq_putc(p, '\n');
6995 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
6996 + } else if (i == NR_IRQS) {
6997 + seq_printf(p, "NMI: ");
6998 + for (j = 0; j < NR_CPUS; j++)
6999 + if (cpu_online(j))
7000 + seq_printf(p, "%10u ", nmi_count(j));
7001 + seq_putc(p, '\n');
7003 - p += sprintf(p, "\n");
7006 - p += sprintf(p, "LOC: ");
7007 - for (j = 0; j < num_online_cpus(); j++)
7008 - p += sprintf(p, "%10u ",
7009 - apic_timer_irqs[cpu_logical_map(j)]);
7010 - p += sprintf(p, "\n");
7013 - p += sprintf(p, "ERR: %10lu\n", irq_err_count);
7018 -int show_interrupts(struct seq_file *p, void *v)
7025 @@ -230,8 +221,11 @@
7027 void disable_irq(unsigned int irq)
7029 + irq_desc_t *desc = irq_desc + irq;
7031 disable_irq_nosync(irq);
7032 - synchronize_irq(irq);
7034 + synchronize_irq(irq);
7039 spin_lock_irqsave(&desc->lock, flags);
7040 switch (desc->depth) {
7042 - unsigned int status = desc->status & ~IRQ_DISABLED;
7043 + unsigned int status = desc->status & IRQ_DISABLED;
7044 desc->status = status;
7045 if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
7046 desc->status = status | IRQ_REPLAY;
7047 @@ -282,13 +276,12 @@
7048 * 0 return value means that this irq is already being
7049 * handled by some other CPU. (or is disabled)
7051 - int cpu = smp_processor_id();
7052 irq_desc_t *desc = irq_desc + irq;
7053 struct irqaction * action;
7054 unsigned int status;
7057 - kstat_cpu(cpu).irqs[irq]++;
7058 + kstat_this_cpu.irqs[irq]++;
7059 spin_lock(&desc->lock);
7060 desc->handler->ack(irq);
7065 int request_irq(unsigned int irq,
7066 - void (*handler)(int, void *, struct pt_regs *),
7067 + irqreturn_t (*handler)(int, void *, struct pt_regs *),
7068 unsigned long irqflags,
7069 const char * devname,
7071 @@ -433,15 +426,19 @@
7072 EXPORT_SYMBOL(request_irq);
7074 int um_request_irq(unsigned int irq, int fd, int type,
7075 - void (*handler)(int, void *, struct pt_regs *),
7076 + irqreturn_t (*handler)(int, void *, struct pt_regs *),
7077 unsigned long irqflags, const char * devname,
7083 - retval = request_irq(irq, handler, irqflags, devname, dev_id);
7084 - if(retval) return(retval);
7085 - return(activate_fd(irq, fd, type, dev_id));
7086 + err = request_irq(irq, handler, irqflags, devname, dev_id);
7091 + err = activate_fd(irq, fd, type, dev_id);
7095 /* this was setup_x86_irq but it seems pretty generic */
7098 spin_lock_irqsave(&desc->lock,flags);
7100 - if ((old = *p) != NULL) {
7102 + if (old != NULL) {
7103 /* Can't share interrupts unless both agree to */
7104 if (!(old->flags & new->flags & SA_SHIRQ)) {
7105 spin_unlock_irqrestore(&desc->lock,flags);
7106 @@ -586,12 +584,14 @@
7107 unsigned long count, void *data)
7109 int irq = (long) data, full_count = count, err;
7110 - cpumask_t new_value, tmp;
7111 + cpumask_t new_value;
7113 if (!irq_desc[irq].handler->set_affinity)
7116 err = cpumask_parse(buffer, count, new_value);
7122 @@ -599,9 +599,11 @@
7123 * way to make the system unusable accidentally :-) At least
7124 * one online CPU still has to be targeted.
7126 - cpus_and(tmp, new_value, cpu_online_map);
7127 - if (cpus_empty(tmp))
7129 + cpus_and(tmp, new_value, cpu_online_map);
7130 + if (cpus_empty(tmp))
7135 irq_affinity[irq] = new_value;
7137 int count, int *eof, void *data)
7139 int len = cpumask_snprintf(page, count, *(cpumask_t *)data);
7141 if (count - len < 2)
7143 len += sprintf(page + len, "\n");
7144 diff -Naur a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c
7145 --- a/arch/um/kernel/irq_user.c 2004-02-11 12:15:17.000000000 -0500
7146 +++ b/arch/um/kernel/irq_user.c 2004-02-11 12:27:06.000000000 -0500
7154 #include <sys/poll.h>
7157 if(smp_sigio_handler()) return;
7159 - if((n = poll(pollfds, pollfds_num, 0)) < 0){
7160 + n = poll(pollfds, pollfds_num, 0);
7162 if(errno == EINTR) continue;
7163 printk("sigio_handler : poll returned %d, "
7164 "errno = %d\n", n, errno);
7165 @@ -366,34 +366,31 @@
7167 void forward_ipi(int fd, int pid)
7169 - if(fcntl(fd, F_SETOWN, pid) < 0){
7170 - int save_errno = errno;
7171 - if(fcntl(fd, F_GETOWN, 0) != pid){
7172 - printk("forward_ipi: F_SETOWN failed, fd = %d, "
7173 - "me = %d, target = %d, errno = %d\n", fd,
7174 - os_getpid(), pid, save_errno);
7179 + err = os_set_owner(fd, pid);
7181 + printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
7182 + "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
7185 void forward_interrupts(int pid)
7188 unsigned long flags;
7192 for(irq=active_fds;irq != NULL;irq = irq->next){
7193 - if(fcntl(irq->fd, F_SETOWN, pid) < 0){
7194 - int save_errno = errno;
7195 - if(fcntl(irq->fd, F_GETOWN, 0) != pid){
7196 - /* XXX Just remove the irq rather than
7197 - * print out an infinite stream of these
7199 - printk("Failed to forward %d to pid %d, "
7200 - "errno = %d\n", irq->fd, pid,
7203 + err = os_set_owner(irq->fd, pid);
7205 + /* XXX Just remove the irq rather than
7206 + * print out an infinite stream of these
7208 + printk("Failed to forward %d to pid %d, err = %d\n",
7209 + irq->fd, pid, -err);
7215 diff -Naur a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
7216 --- a/arch/um/kernel/ksyms.c 2004-02-11 12:14:17.000000000 -0500
7217 +++ b/arch/um/kernel/ksyms.c 2004-02-11 12:26:00.000000000 -0500
7220 - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
7221 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
7222 * Licensed under the GPL
7226 EXPORT_SYMBOL(flush_tlb_range);
7227 EXPORT_SYMBOL(host_task_size);
7228 EXPORT_SYMBOL(arch_validate);
7229 +EXPORT_SYMBOL(get_kmem_end);
7231 -EXPORT_SYMBOL(region_pa);
7232 -EXPORT_SYMBOL(region_va);
7233 -EXPORT_SYMBOL(phys_mem_map);
7234 -EXPORT_SYMBOL(page_mem_map);
7235 EXPORT_SYMBOL(page_to_phys);
7236 EXPORT_SYMBOL(phys_to_page);
7237 EXPORT_SYMBOL(high_physmem);
7238 EXPORT_SYMBOL(empty_zero_page);
7239 EXPORT_SYMBOL(um_virt_to_phys);
7240 +EXPORT_SYMBOL(__virt_to_page);
7241 +EXPORT_SYMBOL(to_phys);
7242 +EXPORT_SYMBOL(to_virt);
7243 EXPORT_SYMBOL(mode_tt);
7244 EXPORT_SYMBOL(handle_page_fault);
7246 +#ifdef CONFIG_MODE_TT
7247 +EXPORT_SYMBOL(copy_from_user_tt);
7248 +EXPORT_SYMBOL(copy_to_user_tt);
7251 +#ifdef CONFIG_MODE_SKAS
7252 +EXPORT_SYMBOL(copy_to_user_skas);
7253 +EXPORT_SYMBOL(copy_from_user_skas);
7256 +EXPORT_SYMBOL(os_stat_fd);
7257 +EXPORT_SYMBOL(os_stat_file);
7258 +EXPORT_SYMBOL(os_access);
7259 +EXPORT_SYMBOL(os_print_error);
7260 +EXPORT_SYMBOL(os_get_exec_close);
7261 +EXPORT_SYMBOL(os_set_exec_close);
7262 EXPORT_SYMBOL(os_getpid);
7263 EXPORT_SYMBOL(os_open_file);
7264 EXPORT_SYMBOL(os_read_file);
7265 EXPORT_SYMBOL(os_write_file);
7266 EXPORT_SYMBOL(os_seek_file);
7267 +EXPORT_SYMBOL(os_lock_file);
7268 +EXPORT_SYMBOL(os_ioctl_generic);
7269 EXPORT_SYMBOL(os_pipe);
7270 EXPORT_SYMBOL(os_file_type);
7271 +EXPORT_SYMBOL(os_file_mode);
7272 +EXPORT_SYMBOL(os_file_size);
7273 +EXPORT_SYMBOL(os_flush_stdout);
7274 EXPORT_SYMBOL(os_close_file);
7275 +EXPORT_SYMBOL(os_set_fd_async);
7276 +EXPORT_SYMBOL(os_set_fd_block);
7277 EXPORT_SYMBOL(helper_wait);
7278 EXPORT_SYMBOL(os_shutdown_socket);
7279 +EXPORT_SYMBOL(os_create_unix_socket);
7280 EXPORT_SYMBOL(os_connect_socket);
7281 +EXPORT_SYMBOL(os_accept_connection);
7282 +EXPORT_SYMBOL(os_rcv_fd);
7283 EXPORT_SYMBOL(run_helper);
7284 EXPORT_SYMBOL(start_thread);
7285 EXPORT_SYMBOL(dump_thread);
7287 +EXPORT_SYMBOL(do_gettimeofday);
7288 +EXPORT_SYMBOL(do_settimeofday);
7290 /* This is here because UML expands open to sys_open, not to a system
7294 EXPORT_SYMBOL(kmap_atomic_to_page);
7298 + * Overrides for Emacs so that we follow Linus's tabbing style.
7299 + * Emacs will notice this stuff at the end of the file and automatically
7300 + * adjust the settings for this buffer only. This must remain at the end
7302 + * ---------------------------------------------------------------------------
7303 + * Local variables:
7304 + * c-file-style: "linux"
7307 diff -Naur a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
7308 --- a/arch/um/kernel/Makefile 2004-02-11 12:16:04.000000000 -0500
7309 +++ b/arch/um/kernel/Makefile 2004-02-11 12:28:00.000000000 -0500
7312 obj-y = checksum.o config.o exec_kern.o exitcode.o frame_kern.o frame.o \
7313 helper.o init_task.o irq.o irq_user.o ksyms.o mem.o mem_user.o \
7314 - process.o process_kern.o ptrace.o reboot.o resource.o sigio_user.o \
7315 - sigio_kern.o signal_kern.o signal_user.o smp.o syscall_kern.o \
7316 - syscall_user.o sysrq.o sys_call_table.o tempfile.o time.o \
7317 - time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o \
7318 - umid.o user_syms.o user_util.o
7319 + physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \
7320 + sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \
7321 + syscall_kern.o syscall_user.o sysrq.o sys_call_table.o tempfile.o \
7322 + time.o time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o \
7323 + um_arch.o umid.o user_syms.o user_util.o
7325 obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
7326 obj-$(CONFIG_GPROF) += gprof_syms.o
7329 CFLAGS_frame.o := $(patsubst -fomit-frame-pointer,,$(USER_CFLAGS))
7331 -$(USER_OBJS) : %.o: %.c
7332 - $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
7334 # This has to be separate because it needs be compiled with frame pointers
7335 # regardless of how the rest of the kernel is built.
7337 $(obj)/frame.o: $(src)/frame.c
7338 $(CC) $(CFLAGS_$(notdir $@)) -c -o $@ $<
7340 -QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
7341 +$(USER_OBJS) : %.o: %.c
7342 + $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
7344 -$(obj)/config.c : $(src)/config.c.in $(TOPDIR)/.config
7345 - $(PERL) -e $(QUOTE) < $(src)/config.c.in > $@
7346 +QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
7348 $(obj)/config.o : $(obj)/config.c
7352 - for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
7360 -archmrproper: clean
7361 +quiet_cmd_quote = QUOTE $@
7362 +cmd_quote = $(PERL) -e $(QUOTE) < $< > $@
7364 +targets += config.c
7365 +$(obj)/config.c : $(src)/config.c.in $(TOPDIR)/.config FORCE
7366 + $(call if_changed,quote)
7367 diff -Naur a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
7368 --- a/arch/um/kernel/mem.c 2004-02-11 12:15:11.000000000 -0500
7369 +++ b/arch/um/kernel/mem.c 2004-02-11 12:26:57.000000000 -0500
7372 - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
7373 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
7374 * Licensed under the GPL
7377 -#include "linux/config.h"
7378 -#include "linux/module.h"
7379 -#include "linux/types.h"
7380 +#include "linux/stddef.h"
7381 +#include "linux/kernel.h"
7382 #include "linux/mm.h"
7383 -#include "linux/fs.h"
7384 -#include "linux/init.h"
7385 #include "linux/bootmem.h"
7386 #include "linux/swap.h"
7387 -#include "linux/slab.h"
7388 -#include "linux/vmalloc.h"
7389 #include "linux/highmem.h"
7390 +#include "linux/gfp.h"
7391 #include "asm/page.h"
7392 -#include "asm/pgtable.h"
7393 +#include "asm/fixmap.h"
7394 #include "asm/pgalloc.h"
7395 -#include "asm/bitops.h"
7396 -#include "asm/uaccess.h"
7397 -#include "asm/tlb.h"
7398 #include "user_util.h"
7399 #include "kern_util.h"
7400 -#include "mem_user.h"
7405 -#include "mode_kern.h"
7406 +#include "mem_user.h"
7407 #include "uml_uaccess.h"
7410 +extern char __binary_start;
7412 /* Changed during early boot */
7413 -pgd_t swapper_pg_dir[1024];
7414 -unsigned long high_physmem;
7415 -unsigned long vm_start;
7416 -unsigned long vm_end;
7417 -unsigned long highmem;
7418 unsigned long *empty_zero_page = NULL;
7419 unsigned long *empty_bad_page = NULL;
7422 -const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n";
7424 -extern char __init_begin, __init_end;
7425 -extern long physmem_size;
7427 -/* Not changed by UML */
7428 -DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
7430 -/* Changed during early boot */
7431 +pgd_t swapper_pg_dir[1024];
7432 +unsigned long highmem;
7435 -#define NREGIONS (phys_region_index(0xffffffff) - phys_region_index(0x0) + 1)
7436 -struct mem_region *regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] = NULL };
7437 -#define REGION_SIZE ((0xffffffff & ~REGION_MASK) + 1)
7439 -/* Changed during early boot */
7440 static unsigned long brk_end;
7442 +void unmap_physmem(void)
7444 + os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
7447 static void map_cb(void *unused)
7449 map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0);
7452 -void unmap_physmem(void)
7453 +#ifdef CONFIG_HIGHMEM
7454 +static void setup_highmem(unsigned long highmem_start,
7455 + unsigned long highmem_len)
7457 - os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
7459 + struct page *page;
7460 + unsigned long highmem_pfn;
7463 -extern char __binary_start;
7464 + highmem_start_page = virt_to_page(highmem_start);
7466 + highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT;
7467 + for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){
7468 + page = &mem_map[highmem_pfn + i];
7469 + ClearPageReserved(page);
7470 + set_bit(PG_highmem, &page->flags);
7471 + atomic_set(&page->count, 1);
7472 + __free_page(page);
7479 @@ -103,50 +95,15 @@
7480 totalhigh_pages = highmem >> PAGE_SHIFT;
7481 totalram_pages += totalhigh_pages;
7482 num_physpages = totalram_pages;
7483 - max_mapnr = totalram_pages;
7484 max_pfn = totalram_pages;
7485 printk(KERN_INFO "Memory: %luk available\n",
7486 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10));
7490 -/* Changed during early boot */
7491 -static unsigned long kmem_top = 0;
7493 -unsigned long get_kmem_end(void)
7496 - kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
7500 -void set_kmem_end(unsigned long new)
7505 #ifdef CONFIG_HIGHMEM
7506 -/* Changed during early boot */
7508 -pgprot_t kmap_prot;
7510 -EXPORT_SYMBOL(kmap_prot);
7511 -EXPORT_SYMBOL(kmap_pte);
7513 -#define kmap_get_fixmap_pte(vaddr) \
7514 - pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
7516 -void __init kmap_init(void)
7518 - unsigned long kmap_vstart;
7520 - /* cache the first kmap pte */
7521 - kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
7522 - kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
7524 - kmap_prot = PAGE_KERNEL;
7525 + setup_highmem(end_iomem, highmem);
7528 -#endif /* CONFIG_HIGHMEM */
7530 static void __init fixrange_init(unsigned long start, unsigned long end,
7532 @@ -178,76 +135,24 @@
7536 -int init_maps(struct mem_region *region)
7538 - struct page *p, *map;
7541 - if(region == &physmem_region){
7542 - region->mem_map = mem_map;
7545 - else if(region->mem_map != NULL) return(0);
7547 - n = region->len >> PAGE_SHIFT;
7548 - len = n * sizeof(struct page);
7550 - map = kmalloc(len, GFP_KERNEL);
7551 - if(map == NULL) map = vmalloc(len);
7553 - else map = alloc_bootmem_low_pages(len);
7557 - for(i = 0; i < n; i++){
7559 - set_page_count(p, 0);
7560 - SetPageReserved(p);
7561 - INIT_LIST_HEAD(&p->list);
7563 - region->mem_map = map;
7568 +pgprot_t kmap_prot;
7570 -DECLARE_MUTEX(regions_sem);
7571 +#define kmap_get_fixmap_pte(vaddr) \
7572 + pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
7574 -static int setup_one_range(int fd, char *driver, unsigned long start,
7575 - unsigned long pfn, int len,
7576 - struct mem_region *region)
7577 +void __init kmap_init(void)
7581 - down(®ions_sem);
7582 - for(i = 0; i < NREGIONS; i++){
7583 - if(regions[i] == NULL) break;
7585 - if(i == NREGIONS){
7586 - printk("setup_range : no free regions\n");
7592 - fd = create_mem_file(len);
7593 + unsigned long kmap_vstart;
7595 - if(region == NULL){
7596 - region = alloc_bootmem_low_pages(sizeof(*region));
7597 - if(region == NULL)
7598 - panic("Failed to allocating mem_region");
7600 + /* cache the first kmap pte */
7601 + kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
7602 + kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
7604 - *region = ((struct mem_region) { .driver = driver,
7609 - regions[i] = region;
7613 + kmap_prot = PAGE_KERNEL;
7616 -#ifdef CONFIG_HIGHMEM
7617 static void init_highmem(void)
7620 @@ -268,63 +173,20 @@
7625 -void setup_highmem(unsigned long len)
7627 - struct mem_region *region;
7628 - struct page *page, *map;
7629 - unsigned long phys;
7630 - int i, cur, index;
7632 - phys = physmem_size;
7634 - cur = min(len, (unsigned long) REGION_SIZE);
7635 - i = setup_one_range(-1, NULL, -1, phys >> PAGE_SHIFT, cur,
7638 - printk("setup_highmem - setup_one_range failed\n");
7641 - region = regions[i];
7642 - index = phys / PAGE_SIZE;
7643 - region->mem_map = &mem_map[index];
7645 - map = region->mem_map;
7646 - for(i = 0; i < (cur >> PAGE_SHIFT); i++){
7648 - ClearPageReserved(page);
7649 - set_bit(PG_highmem, &page->flags);
7650 - atomic_set(&page->count, 1);
7651 - __free_page(page);
7658 +#endif /* CONFIG_HIGHMEM */
7660 void paging_init(void)
7662 - struct mem_region *region;
7663 - unsigned long zones_size[MAX_NR_ZONES], start, end, vaddr;
7665 + unsigned long zones_size[MAX_NR_ZONES], vaddr;
7668 empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
7669 empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
7670 for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++)
7672 - zones_size[0] = (high_physmem >> PAGE_SHIFT) -
7673 - (uml_physmem >> PAGE_SHIFT);
7674 + zones_size[0] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT);
7675 zones_size[2] = highmem >> PAGE_SHIFT;
7676 free_area_init(zones_size);
7677 - start = phys_region_index(__pa(uml_physmem));
7678 - end = phys_region_index(__pa(high_physmem - 1));
7679 - for(i = start; i <= end; i++){
7680 - region = regions[i];
7681 - index = (region->start - uml_physmem) / PAGE_SIZE;
7682 - region->mem_map = &mem_map[index];
7683 - if(i > start) free_bootmem(__pa(region->start), region->len);
7687 * Fixed mappings, only the page table structure has to be
7688 @@ -335,15 +197,33 @@
7690 #ifdef CONFIG_HIGHMEM
7692 - setup_highmem(highmem);
7696 -pte_t __bad_page(void)
7697 +struct page *arch_validate(struct page *page, int mask, int order)
7699 - clear_page(empty_bad_page);
7700 - return pte_mkdirty(mk_pte((struct page *) empty_bad_page,
7702 + unsigned long addr, zero = 0;
7706 + if(page == NULL) return(page);
7707 + if(PageHighMem(page)) return(page);
7709 + addr = (unsigned long) page_address(page);
7710 + for(i = 0; i < (1 << order); i++){
7711 + current->thread.fault_addr = (void *) addr;
7712 + if(__do_copy_to_user((void *) addr, &zero,
7714 + ¤t->thread.fault_addr,
7715 + ¤t->thread.fault_catcher)){
7716 + if(!(mask & __GFP_WAIT)) return(NULL);
7719 + addr += PAGE_SIZE;
7721 + if(i == (1 << order)) return(page);
7722 + page = alloc_pages(mask, order);
7726 /* This can't do anything because nothing in the kernel image can be freed
7727 @@ -401,395 +281,6 @@
7728 printk("%d pages swap cached\n", cached);
7731 -static int __init uml_mem_setup(char *line, int *add)
7734 - physmem_size = memparse(line,&retptr);
7737 -__uml_setup("mem=", uml_mem_setup,
7738 -"mem=<Amount of desired ram>\n"
7739 -" This controls how much \"physical\" memory the kernel allocates\n"
7740 -" for the system. The size is specified as a number followed by\n"
7741 -" one of 'k', 'K', 'm', 'M', which have the obvious meanings.\n"
7742 -" This is not related to the amount of memory in the physical\n"
7743 -" machine. It can be more, and the excess, if it's ever used, will\n"
7744 -" just be swapped out.\n Example: mem=64M\n\n"
7747 -struct page *arch_validate(struct page *page, int mask, int order)
7749 - unsigned long addr, zero = 0;
7753 - if(page == NULL) return(page);
7754 - if(PageHighMem(page)) return(page);
7756 - addr = (unsigned long) page_address(page);
7757 - for(i = 0; i < (1 << order); i++){
7758 - current->thread.fault_addr = (void *) addr;
7759 - if(__do_copy_to_user((void *) addr, &zero,
7761 - ¤t->thread.fault_addr,
7762 - ¤t->thread.fault_catcher)){
7763 - if(!(mask & __GFP_WAIT)) return(NULL);
7766 - addr += PAGE_SIZE;
7768 - if(i == (1 << order)) return(page);
7769 - page = alloc_pages(mask, order);
7773 -DECLARE_MUTEX(vm_reserved_sem);
7774 -static struct list_head vm_reserved = LIST_HEAD_INIT(vm_reserved);
7776 -/* Static structures, linked in to the list in early boot */
7777 -static struct vm_reserved head = {
7778 - .list = LIST_HEAD_INIT(head.list),
7783 -static struct vm_reserved tail = {
7784 - .list = LIST_HEAD_INIT(tail.list),
7789 -void set_usable_vm(unsigned long start, unsigned long end)
7791 - list_add(&head.list, &vm_reserved);
7792 - list_add(&tail.list, &head.list);
7797 -int reserve_vm(unsigned long start, unsigned long end, void *e)
7800 - struct vm_reserved *entry = e, *reserved, *prev;
7801 - struct list_head *ele;
7804 - down(&vm_reserved_sem);
7805 - list_for_each(ele, &vm_reserved){
7806 - reserved = list_entry(ele, struct vm_reserved, list);
7807 - if(reserved->start >= end) goto found;
7809 - panic("Reserved vm out of range");
7811 - prev = list_entry(ele->prev, struct vm_reserved, list);
7812 - if(prev->end > start)
7813 - panic("Can't reserve vm");
7815 - entry = kmalloc(sizeof(*entry), GFP_KERNEL);
7816 - if(entry == NULL){
7817 - printk("reserve_vm : Failed to allocate entry\n");
7821 - *entry = ((struct vm_reserved)
7822 - { .list = LIST_HEAD_INIT(entry->list),
7825 - list_add(&entry->list, &prev->list);
7828 - up(&vm_reserved_sem);
7832 -unsigned long get_vm(unsigned long len)
7834 - struct vm_reserved *this, *next;
7835 - struct list_head *ele;
7836 - unsigned long start;
7839 - down(&vm_reserved_sem);
7840 - list_for_each(ele, &vm_reserved){
7841 - this = list_entry(ele, struct vm_reserved, list);
7842 - next = list_entry(ele->next, struct vm_reserved, list);
7843 - if((this->start < next->start) &&
7844 - (this->end + len + PAGE_SIZE <= next->start))
7847 - up(&vm_reserved_sem);
7850 - up(&vm_reserved_sem);
7851 - start = (unsigned long) UML_ROUND_UP(this->end) + PAGE_SIZE;
7852 - err = reserve_vm(start, start + len, NULL);
7853 - if(err) return(0);
7862 -void setup_range(int fd, char *driver, unsigned long start, unsigned long pfn,
7863 - unsigned long len, int need_vm, struct mem_region *region,
7869 - cur = min(len, (unsigned long) REGION_SIZE);
7870 - i = setup_one_range(fd, driver, start, pfn, cur, region);
7871 - region = regions[i];
7872 - if(need_vm && setup_region(region, reserved)){
7874 - regions[i] = NULL;
7878 - if(pfn != -1) pfn += cur;
7886 - unsigned long size;
7889 -/* iomem regions can only be added on the command line at the moment.
7890 - * Locking will be needed when they can be added via mconsole.
7893 -struct iomem iomem_regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] =
7898 -int num_iomem_regions = 0;
7900 -void add_iomem(char *name, int fd, unsigned long size)
7902 - if(num_iomem_regions == sizeof(iomem_regions)/sizeof(iomem_regions[0]))
7904 - size = (size + PAGE_SIZE - 1) & PAGE_MASK;
7905 - iomem_regions[num_iomem_regions++] =
7906 - ((struct iomem) { .name = name,
7911 -int setup_iomem(void)
7913 - struct iomem *iomem;
7916 - for(i = 0; i < num_iomem_regions; i++){
7917 - iomem = &iomem_regions[i];
7918 - setup_range(iomem->fd, iomem->name, -1, -1, iomem->size, 1,
7924 -__initcall(setup_iomem);
7926 -#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
7927 -#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
7929 -/* Changed during early boot */
7930 -static struct mem_region physmem_region;
7931 -static struct vm_reserved physmem_reserved;
7933 -void setup_physmem(unsigned long start, unsigned long reserve_end,
7934 - unsigned long len)
7936 - struct mem_region *region = &physmem_region;
7937 - struct vm_reserved *reserved = &physmem_reserved;
7938 - unsigned long cur, pfn = 0;
7939 - int do_free = 1, bootmap_size;
7942 - cur = min(len, (unsigned long) REGION_SIZE);
7943 - if(region == NULL)
7944 - region = alloc_bootmem_low_pages(sizeof(*region));
7945 - if(reserved == NULL)
7946 - reserved = alloc_bootmem_low_pages(sizeof(*reserved));
7947 - if((region == NULL) || (reserved == NULL))
7948 - panic("Couldn't allocate physmem region or vm "
7950 - setup_range(-1, NULL, start, pfn, cur, 1, region, reserved);
7953 - unsigned long reserve = reserve_end - start;
7954 - int pfn = PFN_UP(__pa(reserve_end));
7955 - int delta = (len - reserve) >> PAGE_SHIFT;
7957 - bootmap_size = init_bootmem(pfn, pfn + delta);
7958 - free_bootmem(__pa(reserve_end) + bootmap_size,
7959 - cur - bootmap_size - reserve);
7963 - pfn += cur >> PAGE_SHIFT;
7970 -struct mem_region *phys_region(unsigned long phys)
7972 - unsigned int n = phys_region_index(phys);
7974 - if(regions[n] == NULL)
7975 - panic("Physical address in uninitialized region");
7976 - return(regions[n]);
7979 -unsigned long phys_offset(unsigned long phys)
7981 - return(phys_addr(phys));
7984 -struct page *phys_mem_map(unsigned long phys)
7986 - return((struct page *) phys_region(phys)->mem_map);
7989 -struct page *pte_mem_map(pte_t pte)
7991 - return(phys_mem_map(pte_val(pte)));
7994 -struct mem_region *page_region(struct page *page, int *index_out)
7997 - struct mem_region *region;
8000 - for(i = 0; i < NREGIONS; i++){
8001 - region = regions[i];
8002 - if(region == NULL) continue;
8003 - map = region->mem_map;
8004 - if((page >= map) && (page < &map[region->len >> PAGE_SHIFT])){
8005 - if(index_out != NULL) *index_out = i;
8009 - panic("No region found for page");
8013 -unsigned long page_to_pfn(struct page *page)
8015 - struct mem_region *region = page_region(page, NULL);
8017 - return(region->start_pfn + (page - (struct page *) region->mem_map));
8020 -struct mem_region *pfn_to_region(unsigned long pfn, int *index_out)
8022 - struct mem_region *region;
8025 - for(i = 0; i < NREGIONS; i++){
8026 - region = regions[i];
8027 - if(region == NULL)
8030 - if((region->start_pfn <= pfn) &&
8031 - (region->start_pfn + (region->len >> PAGE_SHIFT) > pfn)){
8032 - if(index_out != NULL)
8040 -struct page *pfn_to_page(unsigned long pfn)
8042 - struct mem_region *region = pfn_to_region(pfn, NULL);
8043 - struct page *mem_map = (struct page *) region->mem_map;
8045 - return(&mem_map[pfn - region->start_pfn]);
8048 -unsigned long phys_to_pfn(unsigned long p)
8050 - struct mem_region *region = regions[phys_region_index(p)];
8052 - return(region->start_pfn + (phys_addr(p) >> PAGE_SHIFT));
8055 -unsigned long pfn_to_phys(unsigned long pfn)
8058 - struct mem_region *region = pfn_to_region(pfn, &n);
8060 - return(mk_phys((pfn - region->start_pfn) << PAGE_SHIFT, n));
8063 -struct page *page_mem_map(struct page *page)
8065 - return((struct page *) page_region(page, NULL)->mem_map);
8068 -extern unsigned long region_pa(void *virt)
8070 - struct mem_region *region;
8071 - unsigned long addr = (unsigned long) virt;
8074 - for(i = 0; i < NREGIONS; i++){
8075 - region = regions[i];
8076 - if(region == NULL) continue;
8077 - if((region->start <= addr) &&
8078 - (addr <= region->start + region->len))
8079 - return(mk_phys(addr - region->start, i));
8081 - panic("region_pa : no region for virtual address");
8085 -extern void *region_va(unsigned long phys)
8087 - return((void *) (phys_region(phys)->start + phys_addr(phys)));
8090 -unsigned long page_to_phys(struct page *page)
8093 - struct mem_region *region = page_region(page, &n);
8094 - struct page *map = region->mem_map;
8095 - return(mk_phys((page - map) << PAGE_SHIFT, n));
8098 -struct page *phys_to_page(unsigned long phys)
8100 - struct page *mem_map;
8102 - mem_map = phys_mem_map(phys);
8103 - return(mem_map + (phys_offset(phys) >> PAGE_SHIFT));
8106 -static int setup_mem_maps(void)
8108 - struct mem_region *region;
8111 - for(i = 0; i < NREGIONS; i++){
8112 - region = regions[i];
8113 - if((region != NULL) && (region->fd > 0)) init_maps(region);
8118 -__initcall(setup_mem_maps);
8121 * Allocate and free page tables.
8123 diff -Naur a/arch/um/kernel/mem_user.c b/arch/um/kernel/mem_user.c
8124 --- a/arch/um/kernel/mem_user.c 2004-02-11 12:15:47.000000000 -0500
8125 +++ b/arch/um/kernel/mem_user.c 2004-02-11 12:27:38.000000000 -0500
8133 -#include <sys/stat.h>
8135 #include <sys/types.h>
8136 #include <sys/mman.h>
8137 #include "kern_util.h"
8138 @@ -47,105 +46,145 @@
8141 #include "tempfile.h"
8142 +#include "kern_constants.h"
8144 extern struct mem_region physmem_region;
8146 #define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
8148 -int create_mem_file(unsigned long len)
8149 +static int create_tmp_file(unsigned long len)
8155 fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
8156 - if (fchmod(fd, 0777) < 0){
8159 + os_print_error(fd, "make_tempfile");
8163 + err = os_mode_fd(fd, 0777);
8165 + os_print_error(err, "os_mode_fd");
8168 - if(os_seek_file(fd, len) < 0){
8170 + err = os_seek_file(fd, len);
8172 + os_print_error(err, "os_seek_file");
8176 - if(write(fd, &zero, 1) != 1){
8178 + err = os_write_file(fd, &zero, 1);
8180 + os_print_error(err, "os_write_file");
8183 - if(fcntl(fd, F_SETFD, 1) != 0)
8184 - perror("Setting FD_CLOEXEC failed");
8189 -int setup_region(struct mem_region *region, void *entry)
8190 +static int have_devanon = 0;
8192 +void check_devanon(void)
8196 + printk("Checking for /dev/anon on the host...");
8197 + fd = open("/dev/anon", O_RDWR);
8199 + printk("Not available (open failed with errno %d)\n", errno);
8207 +static int create_anon_file(unsigned long len)
8209 - void *loc, *start;
8213 - if(region->start != -1){
8214 - err = reserve_vm(region->start,
8215 - region->start + region->len, entry);
8217 - printk("setup_region : failed to reserve "
8218 - "0x%x - 0x%x for driver '%s'\n",
8220 - region->start + region->len,
8225 - else region->start = get_vm(region->len);
8226 - if(region->start == 0){
8227 - if(region->driver == NULL) driver = "physmem";
8228 - else driver = region->driver;
8229 - printk("setup_region : failed to find vm for "
8230 - "driver '%s' (length %d)\n", driver, region->len);
8233 - if(region->start == uml_physmem){
8234 - start = (void *) uml_reserved;
8235 - offset = uml_reserved - uml_physmem;
8238 - start = (void *) region->start;
8242 - loc = mmap(start, region->len - offset, PROT_READ | PROT_WRITE,
8243 - MAP_SHARED | MAP_FIXED, region->fd, offset);
8245 - perror("Mapping memory");
8249 + fd = open("/dev/anon", O_RDWR);
8251 + os_print_error(fd, "opening /dev/anon");
8256 + addr = mmap(NULL, len, PROT_READ | PROT_WRITE , MAP_PRIVATE, fd, 0);
8257 + if(addr == MAP_FAILED){
8258 + os_print_error((int) addr, "mapping physmem file");
8261 + munmap(addr, len);
8266 +int create_mem_file(unsigned long len)
8271 + fd = create_anon_file(len);
8272 + else fd = create_tmp_file(len);
8274 + err = os_set_exec_close(fd, 1);
8276 + os_print_error(err, "exec_close");
8280 +struct iomem_region *iomem_regions = NULL;
8281 +int iomem_size = 0;
8283 static int __init parse_iomem(char *str, int *add)
8286 + struct iomem_region *new;
8287 + struct uml_stat buf;
8288 char *file, *driver;
8293 file = strchr(str,',');
8295 - printk("parse_iomem : failed to parse iomem\n");
8297 + printf("parse_iomem : failed to parse iomem\n");
8302 fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
8304 - printk("parse_iomem - Couldn't open io file, errno = %d\n",
8308 - if(fstat(fd, &buf) < 0) {
8309 - printk("parse_iomem - cannot fstat file, errno = %d\n", errno);
8311 + os_print_error(fd, "parse_iomem - Couldn't open io file");
8314 - add_iomem(driver, fd, buf.st_size);
8316 + err = os_stat_fd(fd, &buf);
8318 + os_print_error(err, "parse_iomem - cannot stat_fd file");
8322 + new = malloc(sizeof(*new));
8324 + perror("Couldn't allocate iomem_region struct");
8328 + *new = ((struct iomem_region) { .next = iomem_regions,
8331 + .size = buf.ust_size,
8334 + iomem_regions = new;
8335 + iomem_size += new->size + UM_KERN_PAGE_SIZE;
8339 + os_close_file(fd);
8344 __uml_setup("iomem=", parse_iomem,
8345 @@ -153,73 +192,20 @@
8346 " Configure <file> as an IO memory region named <name>.\n\n"
8351 -int logging_fd = -1;
8353 -int logging_line = 0;
8354 -char logging_buf[256];
8356 -void log(char *fmt, ...)
8359 - struct timeval tv;
8360 - struct openflags flags;
8362 - if(logging == 0) return;
8363 - if(logging_fd < 0){
8364 - flags = of_create(of_trunc(of_rdrw(OPENFLAGS())));
8365 - logging_fd = os_open_file("log", flags, 0644);
8367 - gettimeofday(&tv, NULL);
8368 - sprintf(logging_buf, "%d\t %u.%u ", logging_line++, tv.tv_sec,
8370 - va_start(ap, fmt);
8371 - vsprintf(&logging_buf[strlen(logging_buf)], fmt, ap);
8373 - write(logging_fd, logging_buf, strlen(logging_buf));
8377 -int map_memory(unsigned long virt, unsigned long phys, unsigned long len,
8378 - int r, int w, int x)
8380 - struct mem_region *region = phys_region(phys);
8382 - return(os_map_memory((void *) virt, region->fd, phys_offset(phys), len,
8386 int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
8389 - if(os_protect_memory((void *) addr, len, r, w, x) < 0){
8392 + err = os_protect_memory((void *) addr, len, r, w, x);
8395 - panic("protect failed, errno = %d", errno);
8396 - else return(-errno);
8397 + panic("protect failed, err = %d", -err);
8403 -unsigned long find_iomem(char *driver, unsigned long *len_out)
8405 - struct mem_region *region;
8409 - for(i = 0; i < n; i++){
8410 - region = regions[i];
8411 - if(region == NULL) continue;
8412 - if((region->driver != NULL) &&
8413 - !strcmp(region->driver, driver)){
8414 - *len_out = region->len;
8415 - return(region->start);
8423 * Overrides for Emacs so that we follow Linus's tabbing style.
8424 * Emacs will notice this stuff at the end of the file and automatically
8425 diff -Naur a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
8426 --- a/arch/um/kernel/physmem.c 1969-12-31 19:00:00.000000000 -0500
8427 +++ b/arch/um/kernel/physmem.c 2004-02-11 12:26:07.000000000 -0500
8430 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
8431 + * Licensed under the GPL
8434 +#include "linux/mm.h"
8435 +#include "linux/ghash.h"
8436 +#include "linux/slab.h"
8437 +#include "linux/vmalloc.h"
8438 +#include "linux/bootmem.h"
8439 +#include "asm/types.h"
8440 +#include "asm/pgtable.h"
8441 +#include "kern_util.h"
8442 +#include "user_util.h"
8443 +#include "mode_kern.h"
8445 +#include "mem_user.h"
8451 +static pgd_t physmem_pgd[PTRS_PER_PGD];
8453 +static struct phys_desc *lookup_mapping(void *addr)
8455 + pgd = &physmem_pgd[pgd_index(addr)];
8459 + pmd = pmd_offset(pgd, addr);
8463 + pte = pte_offset_kernel(pmd, addr);
8464 + return((struct phys_desc *) pte_val(pte));
8467 +static struct add_mapping(void *addr, struct phys_desc *new)
8472 +#define PHYS_HASHSIZE (8192)
8476 +DEF_HASH_STRUCTS(virtmem, PHYS_HASHSIZE, struct phys_desc);
8479 + struct virtmem_ptrs virt_ptrs;
8483 + unsigned long phys;
8484 + struct list_head list;
8487 +struct virtmem_table virtmem_hash;
8489 +static int virt_cmp(void *virt1, void *virt2)
8491 + return(virt1 != virt2);
8494 +static int virt_hash(void *virt)
8496 + unsigned long addr = ((unsigned long) virt) >> PAGE_SHIFT;
8497 + return(addr % PHYS_HASHSIZE);
8500 +DEF_HASH(static, virtmem, struct phys_desc, virt_ptrs, void *, virt, virt_cmp,
8503 +LIST_HEAD(descriptor_mappings);
8505 +struct desc_mapping {
8507 + struct list_head list;
8508 + struct list_head pages;
8511 +static struct desc_mapping *find_mapping(int fd)
8513 + struct desc_mapping *desc;
8514 + struct list_head *ele;
8516 + list_for_each(ele, &descriptor_mappings){
8517 + desc = list_entry(ele, struct desc_mapping, list);
8518 + if(desc->fd == fd)
8525 +static struct desc_mapping *descriptor_mapping(int fd)
8527 + struct desc_mapping *desc;
8529 + desc = find_mapping(fd);
8533 + desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
8537 + *desc = ((struct desc_mapping)
8539 + .list = LIST_HEAD_INIT(desc->list),
8540 + .pages = LIST_HEAD_INIT(desc->pages) });
8541 + list_add(&desc->list, &descriptor_mappings);
8546 +int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w)
8548 + struct desc_mapping *fd_maps;
8549 + struct phys_desc *desc;
8550 + unsigned long phys;
8553 + fd_maps = descriptor_mapping(fd);
8554 + if(fd_maps == NULL)
8557 + phys = __pa(virt);
8558 + if(find_virtmem_hash(&virtmem_hash, virt) != NULL)
8559 + panic("Address 0x%p is already substituted\n", virt);
8562 + desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
8566 + *desc = ((struct phys_desc)
8567 + { .virt_ptrs = { NULL, NULL },
8571 + .phys = __pa(virt),
8572 + .list = LIST_HEAD_INIT(desc->list) });
8573 + insert_virtmem_hash(&virtmem_hash, desc);
8575 + list_add(&desc->list, &fd_maps->pages);
8577 + virt = (void *) ((unsigned long) virt & PAGE_MASK);
8578 + err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0);
8582 + remove_virtmem_hash(&virtmem_hash, desc);
8588 +static int physmem_fd = -1;
8590 +static void remove_mapping(struct phys_desc *desc)
8592 + void *virt = desc->virt;
8595 + remove_virtmem_hash(&virtmem_hash, desc);
8596 + list_del(&desc->list);
8599 + err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0);
8601 + panic("Failed to unmap block device page from physical memory, "
8602 + "errno = %d", -err);
8605 +int physmem_remove_mapping(void *virt)
8607 + struct phys_desc *desc;
8609 + virt = (void *) ((unsigned long) virt & PAGE_MASK);
8610 + desc = find_virtmem_hash(&virtmem_hash, virt);
8614 + remove_mapping(desc);
8618 +void physmem_forget_descriptor(int fd)
8620 + struct desc_mapping *desc;
8621 + struct phys_desc *page;
8622 + struct list_head *ele, *next;
8627 + desc = find_mapping(fd);
8631 + list_for_each_safe(ele, next, &desc->pages){
8632 + page = list_entry(ele, struct phys_desc, list);
8633 + offset = page->offset;
8634 + addr = page->virt;
8635 + remove_mapping(page);
8636 + err = os_seek_file(fd, offset);
8638 + panic("physmem_forget_descriptor - failed to seek "
8639 + "to %lld in fd %d, error = %d\n",
8640 + offset, fd, -err);
8641 + err = os_read_file(fd, addr, PAGE_SIZE);
8643 + panic("physmem_forget_descriptor - failed to read "
8644 + "from fd %d to 0x%p, error = %d\n",
8648 + list_del(&desc->list);
8652 +void arch_free_page(struct page *page, int order)
8657 + for(i = 0; i < (1 << order); i++){
8658 + virt = __va(page_to_phys(page + i));
8659 + physmem_remove_mapping(virt);
8663 +int is_remapped(void *virt)
8665 + return(find_virtmem_hash(&virtmem_hash, virt) != NULL);
8668 +/* Changed during early boot */
8669 +unsigned long high_physmem;
8671 +extern unsigned long physmem_size;
8673 +void *to_virt(unsigned long phys)
8675 + return((void *) uml_physmem + phys);
8678 +unsigned long to_phys(void *virt)
8680 + return(((unsigned long) virt) - uml_physmem);
8683 +int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem)
8685 + struct page *p, *map;
8686 + unsigned long phys_len, phys_pages, highmem_len, highmem_pages;
8687 + unsigned long iomem_len, iomem_pages, total_len, total_pages;
8690 + phys_pages = physmem >> PAGE_SHIFT;
8691 + phys_len = phys_pages * sizeof(struct page);
8693 + iomem_pages = iomem >> PAGE_SHIFT;
8694 + iomem_len = iomem_pages * sizeof(struct page);
8696 + highmem_pages = highmem >> PAGE_SHIFT;
8697 + highmem_len = highmem_pages * sizeof(struct page);
8699 + total_pages = phys_pages + iomem_pages + highmem_pages;
8700 + total_len = phys_len + iomem_pages + highmem_len;
8703 + map = kmalloc(total_len, GFP_KERNEL);
8705 + map = vmalloc(total_len);
8707 + else map = alloc_bootmem_low_pages(total_len);
8712 + for(i = 0; i < total_pages; i++){
8714 + set_page_count(p, 0);
8715 + SetPageReserved(p);
8716 + INIT_LIST_HEAD(&p->list);
8720 + max_mapnr = total_pages;
8724 +struct page *phys_to_page(const unsigned long phys)
8726 + return(&mem_map[phys >> PAGE_SHIFT]);
8729 +struct page *__virt_to_page(const unsigned long virt)
8731 + return(&mem_map[__pa(virt) >> PAGE_SHIFT]);
8734 +unsigned long page_to_phys(struct page *page)
8736 + return((page - mem_map) << PAGE_SHIFT);
8739 +pte_t mk_pte(struct page *page, pgprot_t pgprot)
8743 + pte_val(pte) = page_to_phys(page) + pgprot_val(pgprot);
8744 + if(pte_present(pte)) pte_mknewprot(pte_mknewpage(pte));
8748 +/* Changed during early boot */
8749 +static unsigned long kmem_top = 0;
8751 +unsigned long get_kmem_end(void)
8754 + kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
8758 +void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
8759 + int r, int w, int x)
8764 + fd = phys_mapping(phys, &offset);
8765 + err = os_map_memory((void *) virt, fd, offset, len, r, w, x);
8767 + panic("map_memory(0x%lx, %d, 0x%llx, %ld, %d, %d, %d) failed, "
8768 + "err = %d\n", virt, fd, offset, len, r, w, x, err);
8771 +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
8773 +void setup_physmem(unsigned long start, unsigned long reserve_end,
8774 + unsigned long len, unsigned long highmem)
8776 + unsigned long reserve = reserve_end - start;
8777 + int pfn = PFN_UP(__pa(reserve_end));
8778 + int delta = (len - reserve) >> PAGE_SHIFT;
8779 + int err, offset, bootmap_size;
8781 + physmem_fd = create_mem_file(len + highmem);
8783 + offset = uml_reserved - uml_physmem;
8784 + err = os_map_memory((void *) uml_reserved, physmem_fd, offset,
8785 + len - offset, 1, 1, 0);
8787 + os_print_error(err, "Mapping memory");
8791 + bootmap_size = init_bootmem(pfn, pfn + delta);
8792 + free_bootmem(__pa(reserve_end) + bootmap_size,
8793 + len - bootmap_size - reserve);
8796 +int phys_mapping(unsigned long phys, __u64 *offset_out)
8798 + struct phys_desc *desc = find_virtmem_hash(&virtmem_hash,
8799 + __va(phys & PAGE_MASK));
8804 + *offset_out = desc->offset;
8806 + else if(phys < physmem_size){
8808 + *offset_out = phys;
8810 + else if(phys < __pa(end_iomem)){
8811 + struct iomem_region *region = iomem_regions;
8813 + while(region != NULL){
8814 + if((phys >= region->phys) &&
8815 + (phys < region->phys + region->size)){
8817 + *offset_out = phys - region->phys;
8820 + region = region->next;
8823 + else if(phys < __pa(end_iomem) + highmem){
8825 + *offset_out = phys - iomem_size;
8831 +static int __init uml_mem_setup(char *line, int *add)
8834 + physmem_size = memparse(line,&retptr);
8837 +__uml_setup("mem=", uml_mem_setup,
8838 +"mem=<Amount of desired ram>\n"
8839 +" This controls how much \"physical\" memory the kernel allocates\n"
8840 +" for the system. The size is specified as a number followed by\n"
8841 +" one of 'k', 'K', 'm', 'M', which have the obvious meanings.\n"
8842 +" This is not related to the amount of memory in the host. It can\n"
8843 +" be more, and the excess, if it's ever used, will just be swapped out.\n"
8844 +" Example: mem=64M\n\n"
8847 +unsigned long find_iomem(char *driver, unsigned long *len_out)
8849 + struct iomem_region *region = iomem_regions;
8851 + while(region != NULL){
8852 + if(!strcmp(region->driver, driver)){
8853 + *len_out = region->size;
8854 + return(region->virt);
8861 +int setup_iomem(void)
8863 + struct iomem_region *region = iomem_regions;
8864 + unsigned long iomem_start = high_physmem + PAGE_SIZE;
8867 + while(region != NULL){
8868 + err = os_map_memory((void *) iomem_start, region->fd, 0,
8869 + region->size, 1, 1, 0);
8871 + printk("Mapping iomem region for driver '%s' failed, "
8872 + "errno = %d\n", region->driver, -err);
8874 + region->virt = iomem_start;
8875 + region->phys = __pa(region->virt);
8878 + iomem_start += region->size + PAGE_SIZE;
8879 + region = region->next;
8885 +__initcall(setup_iomem);
8888 + * Overrides for Emacs so that we follow Linus's tabbing style.
8889 + * Emacs will notice this stuff at the end of the file and automatically
8890 + * adjust the settings for this buffer only. This must remain at the end
8892 + * ---------------------------------------------------------------------------
8893 + * Local variables:
8894 + * c-file-style: "linux"
8897 diff -Naur a/arch/um/kernel/process.c b/arch/um/kernel/process.c
8898 --- a/arch/um/kernel/process.c 2004-02-11 12:16:36.000000000 -0500
8899 +++ b/arch/um/kernel/process.c 2004-02-11 12:28:35.000000000 -0500
8907 #include <sys/time.h>
8908 #include <sys/ptrace.h>
8909 -#include <sys/ioctl.h>
8910 #include <sys/wait.h>
8911 #include <sys/mman.h>
8912 #include <asm/ptrace.h>
8915 int flags = altstack ? SA_ONSTACK : 0;
8917 - set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags,
8918 + /* NODEFER is set here because SEGV isn't turned back on when the
8919 + * handler is ready to receive signals. This causes any segfault
8920 + * during a copy_user to kill the process because the fault is blocked.
8922 + set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags | SA_NODEFER,
8923 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
8924 set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags,
8925 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
8927 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
8928 set_handler(SIGUSR2, (__sighandler_t) sig_handler,
8929 SA_NOMASK | flags, -1);
8930 - (void) CHOOSE_MODE(signal(SIGCHLD, SIG_IGN), (void *) 0);
8931 signal(SIGHUP, SIG_IGN);
8933 init_irq_signals(altstack);
8934 @@ -123,11 +124,12 @@
8935 /* Start the process and wait for it to kill itself */
8936 new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg);
8937 if(new_pid < 0) return(-errno);
8938 - while((err = waitpid(new_pid, &status, 0) < 0) && (errno == EINTR)) ;
8939 + while(((err = waitpid(new_pid, &status, 0)) < 0) && (errno == EINTR)) ;
8940 if(err < 0) panic("Waiting for outer trampoline failed - errno = %d",
8942 if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
8943 - panic("outer trampoline didn't exit with SIGKILL");
8944 + panic("outer trampoline didn't exit with SIGKILL, "
8945 + "status = %d", status);
8951 os_stop_process(os_getpid());
8953 - if(read(fd, &c, sizeof(c)) != sizeof(c))
8954 + if(os_read_file(fd, &c, sizeof(c)) != sizeof(c))
8955 panic("read failed in suspend_new_thread");
8963 + n = sigsetjmp(buf, 1);
8968 stop_ptraced_child(pid, stack, 1);
8970 printf("Checking for /proc/mm...");
8971 - if(access("/proc/mm", W_OK)){
8972 + if(os_access("/proc/mm", OS_ACC_W_OK) < 0){
8973 printf("not found\n");
8976 diff -Naur a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
8977 --- a/arch/um/kernel/process_kern.c 2004-02-11 12:15:46.000000000 -0500
8978 +++ b/arch/um/kernel/process_kern.c 2004-02-11 12:27:37.000000000 -0500
8980 #include "linux/module.h"
8981 #include "linux/init.h"
8982 #include "linux/capability.h"
8983 +#include "linux/spinlock.h"
8984 #include "asm/unistd.h"
8985 #include "asm/mman.h"
8986 #include "asm/segment.h"
8988 #include "asm/pgtable.h"
8989 #include "asm/processor.h"
8990 #include "asm/tlbflush.h"
8991 -#include "asm/spinlock.h"
8992 #include "asm/uaccess.h"
8993 #include "asm/user.h"
8994 #include "user_util.h"
8997 struct task_struct *get_task(int pid, int require)
8999 - struct task_struct *task, *ret;
9000 + struct task_struct *ret;
9003 read_lock(&tasklist_lock);
9004 - for_each_process(task){
9005 - if(task->pid == pid){
9010 + ret = find_task_by_pid(pid);
9011 read_unlock(&tasklist_lock);
9013 if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
9017 int flags = GFP_KERNEL;
9019 if(atomic) flags |= GFP_ATOMIC;
9020 - if((page = __get_free_pages(flags, order)) == 0)
9021 + page = __get_free_pages(flags, order);
9024 stack_protections(page);
9026 @@ -103,13 +99,15 @@
9028 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
9030 - struct task_struct *p;
9033 current->thread.request.u.thread.proc = fn;
9034 current->thread.request.u.thread.arg = arg;
9035 - p = do_fork(CLONE_VM | flags, 0, NULL, 0, NULL, NULL);
9036 - if(IS_ERR(p)) panic("do_fork failed in kernel_thread");
9038 + pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, NULL, 0, NULL,
9041 + panic("do_fork failed in kernel_thread, errno = %d", pid);
9045 void switch_mm(struct mm_struct *prev, struct mm_struct *next,
9047 { external_pid(task), task });
9050 -void *switch_to(void *prev, void *next, void *last)
9051 +void *_switch_to(void *prev, void *next, void *last)
9053 return(CHOOSE_MODE(switch_to_tt(prev, next),
9054 switch_to_skas(prev, next)));
9056 void exit_thread(void)
9058 CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
9059 - unprotect_stack((unsigned long) current->thread_info);
9060 + unprotect_stack((unsigned long) current_thread);
9063 void *get_current(void)
9064 @@ -157,6 +155,10 @@
9068 +void prepare_to_copy(struct task_struct *tsk)
9072 int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
9073 unsigned long stack_top, struct task_struct * p,
9074 struct pt_regs *regs)
9077 void default_idle(void)
9082 atomic_inc(&init_mm.mm_count);
9083 current->mm = &init_mm;
9084 @@ -367,10 +369,15 @@
9085 return(clear_user(buf, size));
9088 +int strlen_user_proc(char *str)
9090 + return(strlen_user(str));
9093 int smp_sigio_handler(void)
9096 - int cpu = current->thread_info->cpu;
9097 + int cpu = current_thread->cpu;
9105 - return(current->thread_info->cpu);
9106 + return(current_thread->cpu);
9110 diff -Naur a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
9111 --- a/arch/um/kernel/ptrace.c 2004-02-11 12:14:24.000000000 -0500
9112 +++ b/arch/um/kernel/ptrace.c 2004-02-11 12:26:07.000000000 -0500
9113 @@ -311,11 +311,8 @@
9115 /* the 0x80 provides a way for the tracing parent to distinguish
9116 between a syscall stop and SIGTRAP delivery */
9117 - current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
9119 - current->state = TASK_STOPPED;
9120 - notify_parent(current, SIGCHLD);
9122 + ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
9126 * this isn't the same as continuing with a signal, but it will do
9127 diff -Naur a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
9128 --- a/arch/um/kernel/reboot.c 2004-02-11 12:15:45.000000000 -0500
9129 +++ b/arch/um/kernel/reboot.c 2004-02-11 12:27:36.000000000 -0500
9132 static void kill_idlers(int me)
9134 +#ifdef CONFIG_MODE_TT
9135 struct task_struct *p;
9139 if((p != NULL) && (p->thread.mode.tt.extern_pid != me))
9140 os_kill_process(p->thread.mode.tt.extern_pid, 0);
9146 diff -Naur a/arch/um/kernel/sigio_kern.c b/arch/um/kernel/sigio_kern.c
9147 --- a/arch/um/kernel/sigio_kern.c 2004-02-11 12:14:33.000000000 -0500
9148 +++ b/arch/um/kernel/sigio_kern.c 2004-02-11 12:26:17.000000000 -0500
9150 #include "linux/kernel.h"
9151 #include "linux/list.h"
9152 #include "linux/slab.h"
9153 -#include "asm/irq.h"
9154 +#include "linux/signal.h"
9155 +#include "linux/interrupt.h"
9158 #include "irq_user.h"
9159 +#include "irq_kern.h"
9161 /* Protected by sigio_lock() called from write_sigio_workaround */
9162 static int sigio_irq_fd = -1;
9164 -void sigio_interrupt(int irq, void *data, struct pt_regs *unused)
9165 +irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused)
9167 read_sigio_fd(sigio_irq_fd);
9168 reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
9169 + return(IRQ_HANDLED);
9172 int write_sigio_irq(int fd)
9173 diff -Naur a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
9174 --- a/arch/um/kernel/sigio_user.c 2004-02-11 12:16:48.000000000 -0500
9175 +++ b/arch/um/kernel/sigio_user.c 2004-02-11 12:29:02.000000000 -0500
9178 #include <termios.h>
9185 int pty_close_sigio = 0;
9187 /* Used as a flag during SIGIO testing early in boot */
9188 -static int got_sigio = 0;
9189 +static volatile int got_sigio = 0;
9191 void __init handler(int sig)
9196 if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
9197 - info->err = errno;
9198 + info->err = -errno;
9201 void __init check_one_sigio(void (*proc)(int, int))
9203 struct sigaction old, new;
9205 struct openpty_arg pty = { .master = -1, .slave = -1 };
9206 - int master, slave, flags;
9207 + int master, slave, err;
9209 initial_thread_cb(openpty_cb, &pty);
9211 - printk("openpty failed, errno = %d\n", pty.err);
9212 + printk("openpty failed, errno = %d\n", -pty.err);
9220 + /* XXX These can fail with EINTR */
9221 if(tcgetattr(master, &tt) < 0)
9222 panic("check_sigio : tcgetattr failed, errno = %d\n", errno);
9224 if(tcsetattr(master, TCSADRAIN, &tt) < 0)
9225 panic("check_sigio : tcsetattr failed, errno = %d\n", errno);
9227 - if((flags = fcntl(master, F_GETFL)) < 0)
9228 - panic("tty_fds : fcntl F_GETFL failed, errno = %d\n", errno);
9230 - if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
9231 - (fcntl(master, F_SETOWN, os_getpid()) < 0))
9232 - panic("check_sigio : fcntl F_SETFL or F_SETOWN failed, "
9233 - "errno = %d\n", errno);
9235 - if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
9236 - panic("check_sigio : fcntl F_SETFL failed, errno = %d\n",
9238 + err = os_sigio_async(master, slave);
9240 + panic("tty_fds : sigio_async failed, err = %d\n", -err);
9242 if(sigaction(SIGIO, NULL, &old) < 0)
9243 panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
9246 (*proc)(master, slave);
9250 + os_close_file(master);
9251 + os_close_file(slave);
9253 if(sigaction(SIGIO, &old, NULL) < 0)
9254 panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
9255 @@ -112,25 +104,25 @@
9256 printk("Checking that host ptys support output SIGIO...");
9258 memset(buf, 0, sizeof(buf));
9259 - while(write(master, buf, sizeof(buf)) > 0) ;
9261 + while(os_write_file(master, buf, sizeof(buf)) > 0) ;
9263 panic("check_sigio : write failed, errno = %d\n", errno);
9265 - while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
9266 + while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
9270 pty_output_sigio = 1;
9272 - else if(errno == EAGAIN) printk("No, enabling workaround\n");
9273 - else panic("check_sigio : read failed, errno = %d\n", errno);
9274 + else if(n == -EAGAIN) printk("No, enabling workaround\n");
9275 + else panic("check_sigio : read failed, err = %d\n", n);
9278 static void tty_close(int master, int slave)
9280 printk("Checking that host ptys support SIGIO on close...");
9283 + os_close_file(slave);
9286 pty_close_sigio = 1;
9289 void __init check_sigio(void)
9291 - if(access("/dev/ptmx", R_OK) && access("/dev/ptyp0", R_OK)){
9292 + if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
9293 + (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
9294 printk("No pseudo-terminals available - skipping pty SIGIO "
9297 @@ -201,11 +194,10 @@
9299 if(p->revents == 0) continue;
9300 if(p->fd == sigio_private[1]){
9301 - n = read(sigio_private[1], &c, sizeof(c));
9302 + n = os_read_file(sigio_private[1], &c, sizeof(c));
9304 printk("write_sigio_thread : "
9305 - "read failed, errno = %d\n",
9307 + "read failed, err = %d\n", -n);
9309 current_poll = next_poll;
9311 @@ -218,10 +210,10 @@
9312 (fds->used - i) * sizeof(*fds->poll));
9315 - n = write(respond_fd, &c, sizeof(c));
9316 + n = os_write_file(respond_fd, &c, sizeof(c));
9318 printk("write_sigio_thread : write failed, "
9319 - "errno = %d\n", errno);
9320 + "err = %d\n", -n);
9324 @@ -252,15 +244,15 @@
9327 flags = set_signals(0);
9328 - n = write(sigio_private[0], &c, sizeof(c));
9329 + n = os_write_file(sigio_private[0], &c, sizeof(c));
9331 - printk("update_thread : write failed, errno = %d\n", errno);
9332 + printk("update_thread : write failed, err = %d\n", -n);
9336 - n = read(sigio_private[0], &c, sizeof(c));
9337 + n = os_read_file(sigio_private[0], &c, sizeof(c));
9339 - printk("update_thread : read failed, errno = %d\n", errno);
9340 + printk("update_thread : read failed, err = %d\n", -n);
9344 @@ -271,10 +263,10 @@
9345 if(write_sigio_pid != -1)
9346 os_kill_process(write_sigio_pid, 1);
9347 write_sigio_pid = -1;
9348 - close(sigio_private[0]);
9349 - close(sigio_private[1]);
9350 - close(write_sigio_fds[0]);
9351 - close(write_sigio_fds[1]);
9352 + os_close_file(sigio_private[0]);
9353 + os_close_file(sigio_private[1]);
9354 + os_close_file(write_sigio_fds[0]);
9355 + os_close_file(write_sigio_fds[1]);
9359 @@ -369,15 +361,15 @@
9362 err = os_pipe(write_sigio_fds, 1, 1);
9365 printk("write_sigio_workaround - os_pipe 1 failed, "
9366 - "errno = %d\n", -err);
9367 + "err = %d\n", -err);
9370 err = os_pipe(sigio_private, 1, 1);
9373 printk("write_sigio_workaround - os_pipe 2 failed, "
9374 - "errno = %d\n", -err);
9375 + "err = %d\n", -err);
9378 if(setup_initial_poll(sigio_private[1]))
9379 @@ -399,11 +391,11 @@
9380 os_kill_process(write_sigio_pid, 1);
9381 write_sigio_pid = -1;
9383 - close(sigio_private[0]);
9384 - close(sigio_private[1]);
9385 + os_close_file(sigio_private[0]);
9386 + os_close_file(sigio_private[1]);
9388 - close(write_sigio_fds[0]);
9389 - close(write_sigio_fds[1]);
9390 + os_close_file(write_sigio_fds[0]);
9391 + os_close_file(write_sigio_fds[1]);
9395 @@ -412,10 +404,16 @@
9399 - n = read(fd, &c, sizeof(c));
9400 + n = os_read_file(fd, &c, sizeof(c));
9402 - printk("read_sigio_fd - read failed, errno = %d\n", errno);
9405 + printk("read_sigio_fd - read failed, err = %d\n", -n);
9409 + printk("read_sigio_fd - short read, bytes = %d\n", n);
9415 diff -Naur a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c
9416 --- a/arch/um/kernel/signal_kern.c 2004-02-11 12:15:52.000000000 -0500
9417 +++ b/arch/um/kernel/signal_kern.c 2004-02-11 12:27:44.000000000 -0500
9420 struct k_sigaction *ka;
9422 - ka = ¤t->sig->action[SIGSEGV - 1];
9423 + ka = ¤t->sighand->action[SIGSEGV - 1];
9424 ka->sa.sa_handler = SIG_DFL;
9426 force_sig(SIGSEGV, current);
9431 + /* Always make any pending restarted system calls return -EINTR */
9432 + current_thread_info()->restart_block.fn = do_no_restart_syscall;
9434 case -ERESTART_RESTARTBLOCK:
9435 - current_thread_info()->restart_block.fn =
9436 - do_no_restart_syscall;
9437 case -ERESTARTNOHAND:
9443 /* Whee! Actually deliver the signal. */
9444 - ka = ¤t->sig->action[sig -1 ];
9445 + ka = ¤t->sighand->action[sig -1 ];
9446 err = handle_signal(regs, sig, ka, &info, oldset, error);
9453 -int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
9454 +int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
9456 sigset_t saveset, newset;
9458 @@ -227,20 +227,59 @@
9462 +int sys_sigaction(int sig, const struct old_sigaction __user *act,
9463 + struct old_sigaction __user *oact)
9465 + struct k_sigaction new_ka, old_ka;
9469 + old_sigset_t mask;
9470 + if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
9471 + __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
9472 + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
9474 + __get_user(new_ka.sa.sa_flags, &act->sa_flags);
9475 + __get_user(mask, &act->sa_mask);
9476 + siginitset(&new_ka.sa.sa_mask, mask);
9479 + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
9481 + if (!ret && oact) {
9482 + if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
9483 + __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
9484 + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
9486 + __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
9487 + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
9493 +int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
9495 + return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs)));
9498 +extern int userspace_pid[];
9500 static int copy_sc_from_user(struct pt_regs *to, void *from,
9501 struct arch_frame_data *arch)
9505 ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, arch),
9506 - copy_sc_from_user_skas(&to->regs, from));
9507 + copy_sc_from_user_skas(userspace_pid[0],
9508 + &to->regs, from));
9512 int sys_sigreturn(struct pt_regs regs)
9514 - void *sc = sp_to_sc(PT_REGS_SP(¤t->thread.regs));
9515 - void *mask = sp_to_mask(PT_REGS_SP(¤t->thread.regs));
9516 + void __user *sc = sp_to_sc(PT_REGS_SP(¤t->thread.regs));
9517 + void __user *mask = sp_to_mask(PT_REGS_SP(¤t->thread.regs));
9518 int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
9520 spin_lock_irq(¤t->sighand->siglock);
9523 int sys_rt_sigreturn(struct pt_regs regs)
9525 - struct ucontext *uc = sp_to_uc(PT_REGS_SP(¤t->thread.regs));
9527 + unsigned long sp = PT_REGS_SP(¤t->thread.regs);
9528 + struct ucontext __user *uc = sp_to_uc(sp);
9529 int sig_size = _NSIG_WORDS * sizeof(unsigned long);
9531 spin_lock_irq(¤t->sighand->siglock);
9533 sigdelsetmask(¤t->blocked, ~_BLOCKABLE);
9534 recalc_sigpending();
9535 spin_unlock_irq(¤t->sighand->siglock);
9536 - fp = (void *) (((unsigned long) uc) + sizeof(struct ucontext));
9537 copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext,
9538 &signal_frame_si.common.arch);
9539 return(PT_REGS_SYSCALL_RET(¤t->thread.regs));
9540 diff -Naur a/arch/um/kernel/skas/include/mode.h b/arch/um/kernel/skas/include/mode.h
9541 --- a/arch/um/kernel/skas/include/mode.h 2004-02-11 12:15:48.000000000 -0500
9542 +++ b/arch/um/kernel/skas/include/mode.h 2004-02-11 12:27:41.000000000 -0500
9544 extern int have_fpx_regs;
9546 extern void user_time_init_skas(void);
9547 -extern int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr);
9548 -extern int copy_sc_to_user_skas(void *to_ptr, void *fp,
9549 +extern int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs,
9551 +extern int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp,
9552 union uml_pt_regs *regs,
9553 unsigned long fault_addr, int fault_type);
9554 extern void sig_handler_common_skas(int sig, void *sc_ptr);
9555 extern void halt_skas(void);
9556 extern void reboot_skas(void);
9557 extern void kill_off_processes_skas(void);
9558 +extern int is_skas_winch(int pid, int fd, void *data);
9562 diff -Naur a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h
9563 --- a/arch/um/kernel/skas/include/skas.h 2004-02-11 12:14:37.000000000 -0500
9564 +++ b/arch/um/kernel/skas/include/skas.h 2004-02-11 12:26:22.000000000 -0500
9567 #include "sysdep/ptrace.h"
9569 -extern int userspace_pid;
9570 +extern int userspace_pid[];
9572 extern void switch_threads(void *me, void *next);
9573 extern void thread_wait(void *sw, void *fb);
9575 extern int new_mm(int from);
9576 extern void save_registers(union uml_pt_regs *regs);
9577 extern void restore_registers(union uml_pt_regs *regs);
9578 -extern void start_userspace(void);
9579 +extern void start_userspace(int cpu);
9580 extern void init_registers(int pid);
9583 diff -Naur a/arch/um/kernel/skas/include/uaccess.h b/arch/um/kernel/skas/include/uaccess.h
9584 --- a/arch/um/kernel/skas/include/uaccess.h 2004-02-11 12:15:17.000000000 -0500
9585 +++ b/arch/um/kernel/skas/include/uaccess.h 2004-02-11 12:27:05.000000000 -0500
9587 #ifndef __SKAS_UACCESS_H
9588 #define __SKAS_UACCESS_H
9590 -#include "linux/string.h"
9591 -#include "linux/sched.h"
9592 -#include "linux/err.h"
9593 -#include "asm/processor.h"
9594 -#include "asm/pgtable.h"
9595 #include "asm/errno.h"
9596 -#include "asm/current.h"
9597 -#include "asm/a.out.h"
9598 -#include "kern_util.h"
9600 #define access_ok_skas(type, addr, size) \
9601 ((segment_eq(get_fs(), KERNEL_DS)) || \
9602 (((unsigned long) (addr) < TASK_SIZE) && \
9603 - ((unsigned long) (addr) + (size) < TASK_SIZE)))
9604 + ((unsigned long) (addr) + (size) <= TASK_SIZE)))
9606 static inline int verify_area_skas(int type, const void * addr,
9608 @@ -27,197 +19,12 @@
9609 return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
9612 -static inline unsigned long maybe_map(unsigned long virt, int is_write)
9616 - void *phys = um_virt_to_phys(current, virt, &pte);
9619 - if(IS_ERR(phys) || (is_write && !pte_write(pte))){
9620 - if(handle_page_fault(virt, 0, is_write, 0, &dummy_code))
9622 - phys = um_virt_to_phys(current, virt, NULL);
9624 - return((unsigned long) __va((unsigned long) phys));
9627 -static inline int buffer_op(unsigned long addr, int len,
9628 - int (*op)(unsigned long addr, int len, void *arg),
9631 - int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
9632 - int remain = len, n;
9634 - n = (*op)(addr, size, arg);
9636 - return(n < 0 ? remain : 0);
9643 - while(addr < ((addr + remain) & PAGE_MASK)){
9644 - n = (*op)(addr, PAGE_SIZE, arg);
9646 - return(n < 0 ? remain : 0);
9648 - addr += PAGE_SIZE;
9649 - remain -= PAGE_SIZE;
9654 - n = (*op)(addr, remain, arg);
9656 - return(n < 0 ? remain : 0);
9660 -static inline int copy_chunk_from_user(unsigned long from, int len, void *arg)
9662 - unsigned long *to_ptr = arg, to = *to_ptr;
9664 - from = maybe_map(from, 0);
9668 - memcpy((void *) to, (void *) from, len);
9673 -static inline int copy_from_user_skas(void *to, const void *from, int n)
9675 - if(segment_eq(get_fs(), KERNEL_DS)){
9676 - memcpy(to, from, n);
9680 - return(access_ok_skas(VERIFY_READ, from, n) ?
9681 - buffer_op((unsigned long) from, n, copy_chunk_from_user, &to) :
9685 -static inline int copy_chunk_to_user(unsigned long to, int len, void *arg)
9687 - unsigned long *from_ptr = arg, from = *from_ptr;
9689 - to = maybe_map(to, 1);
9693 - memcpy((void *) to, (void *) from, len);
9698 -static inline int copy_to_user_skas(void *to, const void *from, int n)
9700 - if(segment_eq(get_fs(), KERNEL_DS)){
9701 - memcpy(to, from, n);
9705 - return(access_ok_skas(VERIFY_WRITE, to, n) ?
9706 - buffer_op((unsigned long) to, n, copy_chunk_to_user, &from) :
9710 -static inline int strncpy_chunk_from_user(unsigned long from, int len,
9713 - char **to_ptr = arg, *to = *to_ptr;
9716 - from = maybe_map(from, 0);
9720 - strncpy(to, (void *) from, len);
9721 - n = strnlen(to, len);
9729 -static inline int strncpy_from_user_skas(char *dst, const char *src, int count)
9734 - if(segment_eq(get_fs(), KERNEL_DS)){
9735 - strncpy(dst, src, count);
9736 - return(strnlen(dst, count));
9739 - if(!access_ok_skas(VERIFY_READ, src, 1))
9742 - n = buffer_op((unsigned long) src, count, strncpy_chunk_from_user,
9746 - return(strnlen(dst, count));
9749 -static inline int clear_chunk(unsigned long addr, int len, void *unused)
9751 - addr = maybe_map(addr, 1);
9755 - memset((void *) addr, 0, len);
9759 -static inline int __clear_user_skas(void *mem, int len)
9761 - return(buffer_op((unsigned long) mem, len, clear_chunk, NULL));
9764 -static inline int clear_user_skas(void *mem, int len)
9766 - if(segment_eq(get_fs(), KERNEL_DS)){
9767 - memset(mem, 0, len);
9771 - return(access_ok_skas(VERIFY_WRITE, mem, len) ?
9772 - buffer_op((unsigned long) mem, len, clear_chunk, NULL) : len);
9775 -static inline int strnlen_chunk(unsigned long str, int len, void *arg)
9777 - int *len_ptr = arg, n;
9779 - str = maybe_map(str, 0);
9783 - n = strnlen((void *) str, len);
9791 -static inline int strnlen_user_skas(const void *str, int len)
9795 - if(segment_eq(get_fs(), KERNEL_DS))
9796 - return(strnlen(str, len) + 1);
9798 - n = buffer_op((unsigned long) str, len, strnlen_chunk, &count);
9800 - return(count + 1);
9803 +extern int copy_from_user_skas(void *to, const void *from, int n);
9804 +extern int copy_to_user_skas(void *to, const void *from, int n);
9805 +extern int strncpy_from_user_skas(char *dst, const char *src, int count);
9806 +extern int __clear_user_skas(void *mem, int len);
9807 +extern int clear_user_skas(void *mem, int len);
9808 +extern int strnlen_user_skas(const void *str, int len);
9812 diff -Naur a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
9813 --- a/arch/um/kernel/skas/Makefile 2004-02-11 12:14:38.000000000 -0500
9814 +++ b/arch/um/kernel/skas/Makefile 2004-02-11 12:26:41.000000000 -0500
9817 obj-y = exec_kern.o exec_user.o mem.o mem_user.o mmu.o process.o \
9818 process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o \
9820 + uaccess.o sys-$(SUBARCH)/
9822 +host-progs := util/mk_ptregs
9823 +clean-files := include/skas_ptregs.h
9825 USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
9826 USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
9828 -include/skas_ptregs.h : util/mk_ptregs
9829 - util/mk_ptregs > $@
9833 +$(TOPDIR)/arch/um/include/skas_ptregs.h : $(src)/util/mk_ptregs
9834 + @echo -n ' Generating $@'
9836 + @if [ -r $@ ] && cmp -s $@ $@.tmp; then \
9837 + echo ' (unchanged)'; \
9840 + echo ' (updated)'; \
9841 + mv -f $@.tmp $@; \
9844 $(USER_OBJS) : %.o: %.c
9845 $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
9848 - $(MAKE) -C util clean
9849 - $(RM) -f include/skas_ptregs.h
9850 diff -Naur a/arch/um/kernel/skas/mem_user.c b/arch/um/kernel/skas/mem_user.c
9851 --- a/arch/um/kernel/skas/mem_user.c 2004-02-11 12:14:58.000000000 -0500
9852 +++ b/arch/um/kernel/skas/mem_user.c 2004-02-11 12:26:50.000000000 -0500
9854 #include <sys/mman.h>
9855 #include <sys/ptrace.h>
9856 #include "mem_user.h"
9860 #include "proc_mm.h"
9862 int r, int w, int x)
9864 struct proc_mm_op map;
9865 - struct mem_region *region;
9868 + int prot, n, phys_fd;
9870 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
9871 (x ? PROT_EXEC : 0);
9872 - region = phys_region(phys);
9873 + phys_fd = phys_mapping(phys, &offset);
9875 map = ((struct proc_mm_op) { .op = MM_MMAP,
9879 .flags = MAP_SHARED |
9882 - .offset = phys_offset(phys)
9886 n = os_write_file(fd, &map, sizeof(map));
9887 if(n != sizeof(map))
9888 - printk("map : /proc/mm map failed, errno = %d\n", errno);
9889 + printk("map : /proc/mm map failed, err = %d\n", -n);
9892 int unmap(int fd, void *addr, int len)
9894 { .addr = (unsigned long) addr,
9896 n = os_write_file(fd, &unmap, sizeof(unmap));
9897 - if((n != 0) && (n != sizeof(unmap)))
9899 + if(n != sizeof(unmap)) {
9910 .prot = prot } } } );
9912 n = os_write_file(fd, &protect, sizeof(protect));
9913 - if((n != 0) && (n != sizeof(protect))){
9914 + if(n != sizeof(protect)) {
9915 + if(n == 0) return(0);
9918 - panic("protect failed, errno = %d", errno);
9920 + panic("protect failed, err = %d", -n);
9928 diff -Naur a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
9929 --- a/arch/um/kernel/skas/mmu.c 2004-02-11 12:17:12.000000000 -0500
9930 +++ b/arch/um/kernel/skas/mmu.c 2004-02-11 12:29:17.000000000 -0500
9934 mm->context.skas.mm_fd = new_mm(from);
9935 - if(mm->context.skas.mm_fd < 0)
9936 - panic("init_new_context_skas - new_mm failed, errno = %d\n",
9937 - mm->context.skas.mm_fd);
9938 + if(mm->context.skas.mm_fd < 0){
9939 + printk("init_new_context_skas - new_mm failed, errno = %d\n",
9940 + mm->context.skas.mm_fd);
9941 + return(mm->context.skas.mm_fd);
9946 diff -Naur a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
9947 --- a/arch/um/kernel/skas/process.c 2004-02-11 12:16:47.000000000 -0500
9948 +++ b/arch/um/kernel/skas/process.c 2004-02-11 12:29:02.000000000 -0500
9953 +#include <unistd.h>
9959 #include "proc_mm.h"
9960 #include "skas_ptrace.h"
9961 +#include "chan_user.h"
9963 +int is_skas_winch(int pid, int fd, void *data)
9965 + if(pid != getpid())
9968 + register_winch_irq(-1, fd, -1, data);
9972 +/* These are set once at boot time and not changed thereafter */
9974 unsigned long exec_regs[FRAME_SIZE];
9975 unsigned long exec_fp_regs[HOST_FP_SIZE];
9977 int err, syscall_nr, status;
9979 syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
9980 + UPT_SYSCALL_NR(regs) = syscall_nr;
9982 relay_signal(SIGTRAP, regs);
9985 - UPT_SYSCALL_NR(regs) = syscall_nr;
9987 err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
9990 handle_syscall(regs);
9995 static int userspace_tramp(void *arg)
9997 init_new_thread_signals(0);
10002 -void start_userspace(void)
10003 +/* Each element set once, and only accessed by a single processor anyway */
10005 +int userspace_pid[NR_CPUS];
10007 +void start_userspace(int cpu)
10011 @@ -114,21 +129,21 @@
10012 if(munmap(stack, PAGE_SIZE) < 0)
10013 panic("start_userspace : munmap failed, errno = %d\n", errno);
10015 - userspace_pid = pid;
10016 + userspace_pid[cpu] = pid;
10019 void userspace(union uml_pt_regs *regs)
10021 - int err, status, op;
10022 + int err, status, op, pid = userspace_pid[0];
10024 restore_registers(regs);
10026 - err = ptrace(PTRACE_SYSCALL, userspace_pid, 0, 0);
10027 + err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
10029 panic("userspace - PTRACE_SYSCALL failed, errno = %d\n",
10032 - err = waitpid(userspace_pid, &status, WUNTRACED);
10033 + err = waitpid(pid, &status, WUNTRACED);
10035 panic("userspace - waitpid failed, errno = %d\n",
10037 @@ -139,16 +154,17 @@
10038 if(WIFSTOPPED(status)){
10039 switch(WSTOPSIG(status)){
10041 - handle_segv(userspace_pid);
10042 + handle_segv(pid);
10045 - handle_trap(userspace_pid, regs);
10046 + handle_trap(pid, regs);
10054 user_signal(WSTOPSIG(status), regs);
10057 @@ -162,7 +178,7 @@
10059 op = singlestepping_skas() ? PTRACE_SINGLESTEP :
10061 - err = ptrace(op, userspace_pid, 0, 0);
10062 + err = ptrace(op, pid, 0, 0);
10064 panic("userspace - PTRACE_SYSCALL failed, "
10065 "errno = %d\n", errno);
10066 @@ -177,7 +193,7 @@
10067 *switch_buf_ptr = &switch_buf;
10068 *fork_buf_ptr = &fork_buf;
10070 - if(setjmp(fork_buf) == 0)
10071 + if(sigsetjmp(fork_buf, 1) == 0)
10072 new_thread_proc(stack, handler);
10075 @@ -189,16 +205,16 @@
10077 *switch_buf = &buf;
10079 - if(setjmp(buf) == 0)
10080 - longjmp(*fork_buf, 1);
10081 + if(sigsetjmp(buf, 1) == 0)
10082 + siglongjmp(*fork_buf, 1);
10085 -static int move_registers(int int_op, int fp_op, union uml_pt_regs *regs,
10086 - unsigned long *fp_regs)
10087 +static int move_registers(int pid, int int_op, int fp_op,
10088 + union uml_pt_regs *regs, unsigned long *fp_regs)
10090 - if(ptrace(int_op, userspace_pid, 0, regs->skas.regs) < 0)
10091 + if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
10093 - if(ptrace(fp_op, userspace_pid, 0, fp_regs) < 0)
10094 + if(ptrace(fp_op, pid, 0, fp_regs) < 0)
10098 @@ -217,10 +233,11 @@
10099 fp_regs = regs->skas.fp;
10102 - err = move_registers(PTRACE_GETREGS, fp_op, regs, fp_regs);
10103 + err = move_registers(userspace_pid[0], PTRACE_GETREGS, fp_op, regs,
10106 panic("save_registers - saving registers failed, errno = %d\n",
10111 void restore_registers(union uml_pt_regs *regs)
10112 @@ -237,10 +254,11 @@
10113 fp_regs = regs->skas.fp;
10116 - err = move_registers(PTRACE_SETREGS, fp_op, regs, fp_regs);
10117 + err = move_registers(userspace_pid[0], PTRACE_SETREGS, fp_op, regs,
10120 panic("restore_registers - saving registers failed, "
10121 - "errno = %d\n", err);
10122 + "errno = %d\n", -err);
10125 void switch_threads(void *me, void *next)
10126 @@ -248,8 +266,8 @@
10127 jmp_buf my_buf, **me_ptr = me, *next_buf = next;
10130 - if(setjmp(my_buf) == 0)
10131 - longjmp(*next_buf, 1);
10132 + if(sigsetjmp(my_buf, 1) == 0)
10133 + siglongjmp(*next_buf, 1);
10136 static jmp_buf initial_jmpbuf;
10137 @@ -265,14 +283,14 @@
10140 *fork_buf_ptr = &initial_jmpbuf;
10141 - n = setjmp(initial_jmpbuf);
10142 + n = sigsetjmp(initial_jmpbuf, 1);
10144 new_thread_proc((void *) stack, new_thread_handler);
10148 (*cb_proc)(cb_arg);
10149 - longjmp(*cb_back, 1);
10150 + siglongjmp(*cb_back, 1);
10154 @@ -282,7 +300,7 @@
10158 - longjmp(**switch_buf, 1);
10159 + siglongjmp(**switch_buf, 1);
10162 void remove_sigstack(void)
10163 @@ -304,8 +322,8 @@
10167 - if(setjmp(here) == 0)
10168 - longjmp(initial_jmpbuf, 2);
10169 + if(sigsetjmp(here, 1) == 0)
10170 + siglongjmp(initial_jmpbuf, 2);
10174 @@ -316,22 +334,23 @@
10175 void halt_skas(void)
10178 - longjmp(initial_jmpbuf, 3);
10179 + siglongjmp(initial_jmpbuf, 3);
10182 void reboot_skas(void)
10185 - longjmp(initial_jmpbuf, 4);
10186 + siglongjmp(initial_jmpbuf, 4);
10189 int new_mm(int from)
10191 struct proc_mm_op copy;
10192 - int n, fd = os_open_file("/proc/mm", of_write(OPENFLAGS()), 0);
10193 + int n, fd = os_open_file("/proc/mm",
10194 + of_cloexec(of_write(OPENFLAGS())), 0);
10201 copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS,
10202 @@ -340,8 +359,9 @@
10203 n = os_write_file(fd, ©, sizeof(copy));
10204 if(n != sizeof(copy))
10205 printk("new_mm : /proc/mm copy_segments failed, "
10206 - "errno = %d\n", errno);
10207 + "err = %d\n", -n);
10213 @@ -349,7 +369,8 @@
10217 - err = ptrace(PTRACE_SWITCH_MM, userspace_pid, 0, mm_fd);
10218 +#warning need cpu pid in switch_mm_skas
10219 + err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, mm_fd);
10221 panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n",
10223 @@ -357,7 +378,8 @@
10225 void kill_off_processes_skas(void)
10227 - os_kill_process(userspace_pid, 1);
10228 +#warning need to loop over userspace_pids in kill_off_processes_skas
10229 + os_kill_process(userspace_pid[0], 1);
10232 void init_registers(int pid)
10233 diff -Naur a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
10234 --- a/arch/um/kernel/skas/process_kern.c 2004-02-11 12:14:33.000000000 -0500
10235 +++ b/arch/um/kernel/skas/process_kern.c 2004-02-11 12:26:15.000000000 -0500
10236 @@ -61,11 +61,13 @@
10237 thread_wait(¤t->thread.mode.skas.switch_buf,
10238 current->thread.mode.skas.fork_buf);
10241 - schedule_tail(NULL);
10243 + if(current->thread.prev_sched != NULL)
10244 + schedule_tail(current->thread.prev_sched);
10245 current->thread.prev_sched = NULL;
10247 + /* The return value is 1 if the kernel thread execs a process,
10248 + * 0 if it just exits
10250 n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf);
10252 userspace(¤t->thread.regs.regs);
10254 current->thread.mode.skas.fork_buf);
10258 - schedule_tail(current->thread.prev_sched);
10260 + if(current->thread.prev_sched != NULL)
10261 + schedule_tail(current->thread.prev_sched);
10262 current->thread.prev_sched = NULL;
10265 @@ -136,7 +137,7 @@
10267 void init_idle_skas(void)
10269 - cpu_tasks[current->thread_info->cpu].pid = os_getpid();
10270 + cpu_tasks[current_thread->cpu].pid = os_getpid();
10274 @@ -160,11 +161,11 @@
10276 int start_uml_skas(void)
10278 - start_userspace();
10279 + start_userspace(0);
10280 capture_signal_stack();
10281 + uml_idle_timer();
10283 init_new_thread_signals(1);
10286 init_task.thread.request.u.thread.proc = start_kernel_proc;
10287 init_task.thread.request.u.thread.arg = NULL;
10288 @@ -175,12 +176,14 @@
10290 int external_pid_skas(struct task_struct *task)
10292 - return(userspace_pid);
10293 +#warning Need to look up userspace_pid by cpu
10294 + return(userspace_pid[0]);
10297 int thread_pid_skas(struct task_struct *task)
10299 - return(userspace_pid);
10300 +#warning Need to look up userspace_pid by cpu
10301 + return(userspace_pid[0]);
10305 diff -Naur a/arch/um/kernel/skas/syscall_kern.c b/arch/um/kernel/skas/syscall_kern.c
10306 --- a/arch/um/kernel/skas/syscall_kern.c 2004-02-11 12:15:58.000000000 -0500
10307 +++ b/arch/um/kernel/skas/syscall_kern.c 2004-02-11 12:27:51.000000000 -0500
10310 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
10311 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
10312 * Licensed under the GPL
10315 diff -Naur a/arch/um/kernel/skas/sys-i386/Makefile b/arch/um/kernel/skas/sys-i386/Makefile
10316 --- a/arch/um/kernel/skas/sys-i386/Makefile 2004-02-11 12:16:38.000000000 -0500
10317 +++ b/arch/um/kernel/skas/sys-i386/Makefile 2004-02-11 12:28:37.000000000 -0500
10320 $(USER_OBJS) : %.o: %.c
10321 $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
10324 diff -Naur a/arch/um/kernel/skas/sys-i386/sigcontext.c b/arch/um/kernel/skas/sys-i386/sigcontext.c
10325 --- a/arch/um/kernel/skas/sys-i386/sigcontext.c 2004-02-11 12:14:18.000000000 -0500
10326 +++ b/arch/um/kernel/skas/sys-i386/sigcontext.c 2004-02-11 12:26:01.000000000 -0500
10328 #include "kern_util.h"
10330 #include "sigcontext.h"
10333 -extern int userspace_pid;
10335 -int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr)
10336 +int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, void *from_ptr)
10338 struct sigcontext sc, *from = from_ptr;
10339 unsigned long fpregs[FP_FRAME_SIZE];
10340 @@ -41,13 +40,12 @@
10341 regs->skas.regs[EIP] = sc.eip;
10342 regs->skas.regs[CS] = sc.cs;
10343 regs->skas.regs[EFL] = sc.eflags;
10344 - regs->skas.regs[UESP] = sc.esp_at_signal;
10345 regs->skas.regs[SS] = sc.ss;
10346 regs->skas.fault_addr = sc.cr2;
10347 regs->skas.fault_type = FAULT_WRITE(sc.err);
10348 regs->skas.trap_type = sc.trapno;
10350 - err = ptrace(PTRACE_SETFPREGS, userspace_pid, 0, fpregs);
10351 + err = ptrace(PTRACE_SETFPREGS, pid, 0, fpregs);
10353 printk("copy_sc_to_user - PTRACE_SETFPREGS failed, "
10354 "errno = %d\n", errno);
10359 -int copy_sc_to_user_skas(void *to_ptr, void *fp, union uml_pt_regs *regs,
10360 - unsigned long fault_addr, int fault_type)
10361 +int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp,
10362 + union uml_pt_regs *regs, unsigned long fault_addr,
10365 struct sigcontext sc, *to = to_ptr;
10366 struct _fpstate *to_fp;
10368 sc.err = TO_SC_ERR(fault_type);
10369 sc.trapno = regs->skas.trap_type;
10371 - err = ptrace(PTRACE_GETFPREGS, userspace_pid, 0, fpregs);
10372 + err = ptrace(PTRACE_GETFPREGS, pid, 0, fpregs);
10374 printk("copy_sc_to_user - PTRACE_GETFPREGS failed, "
10375 "errno = %d\n", errno);
10376 diff -Naur a/arch/um/kernel/skas/trap_user.c b/arch/um/kernel/skas/trap_user.c
10377 --- a/arch/um/kernel/skas/trap_user.c 2004-02-11 12:15:17.000000000 -0500
10378 +++ b/arch/um/kernel/skas/trap_user.c 2004-02-11 12:27:06.000000000 -0500
10381 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
10382 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
10383 * Licensed under the GPL
10388 struct signal_info *info;
10390 - if(sig == SIGVTALRM)
10391 - missed_ticks[cpu()]++;
10392 regs->skas.is_user = 1;
10393 regs->skas.fault_addr = 0;
10394 regs->skas.fault_type = 0;
10395 diff -Naur a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
10396 --- a/arch/um/kernel/skas/uaccess.c 1969-12-31 19:00:00.000000000 -0500
10397 +++ b/arch/um/kernel/skas/uaccess.c 2004-02-11 12:28:20.000000000 -0500
10400 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
10401 + * Licensed under the GPL
10404 +#include "linux/stddef.h"
10405 +#include "linux/kernel.h"
10406 +#include "linux/string.h"
10407 +#include "linux/fs.h"
10408 +#include "linux/highmem.h"
10409 +#include "asm/page.h"
10410 +#include "asm/pgtable.h"
10411 +#include "asm/uaccess.h"
10412 +#include "kern_util.h"
10414 +extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
10417 +static unsigned long maybe_map(unsigned long virt, int is_write)
10422 + void *phys = um_virt_to_phys(current, virt, &pte);
10425 + if(IS_ERR(phys) || (is_write && !pte_write(pte))){
10426 + err = handle_page_fault(virt, 0, is_write, 0, &dummy_code);
10429 + phys = um_virt_to_phys(current, virt, NULL);
10431 + return((unsigned long) phys);
10434 +static int do_op(unsigned long addr, int len, int is_write,
10435 + int (*op)(unsigned long addr, int len, void *arg), void *arg)
10437 + struct page *page;
10440 + addr = maybe_map(addr, is_write);
10444 + page = phys_to_page(addr);
10445 + addr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK);
10446 + n = (*op)(addr, len, arg);
10452 +static int buffer_op(unsigned long addr, int len, int is_write,
10453 + int (*op)(unsigned long addr, int len, void *arg),
10456 + int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
10457 + int remain = len, n;
10459 + n = do_op(addr, size, is_write, op, arg);
10461 + return(n < 0 ? remain : 0);
10468 + while(addr < ((addr + remain) & PAGE_MASK)){
10469 + n = do_op(addr, PAGE_SIZE, is_write, op, arg);
10471 + return(n < 0 ? remain : 0);
10473 + addr += PAGE_SIZE;
10474 + remain -= PAGE_SIZE;
10479 + n = do_op(addr, remain, is_write, op, arg);
10481 + return(n < 0 ? remain : 0);
10485 +static int copy_chunk_from_user(unsigned long from, int len, void *arg)
10487 + unsigned long *to_ptr = arg, to = *to_ptr;
10489 + memcpy((void *) to, (void *) from, len);
10494 +int copy_from_user_skas(void *to, const void *from, int n)
10496 + if(segment_eq(get_fs(), KERNEL_DS)){
10497 + memcpy(to, from, n);
10501 + return(access_ok_skas(VERIFY_READ, from, n) ?
10502 + buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
10506 +static int copy_chunk_to_user(unsigned long to, int len, void *arg)
10508 + unsigned long *from_ptr = arg, from = *from_ptr;
10510 + memcpy((void *) to, (void *) from, len);
10511 + *from_ptr += len;
10515 +int copy_to_user_skas(void *to, const void *from, int n)
10517 + if(segment_eq(get_fs(), KERNEL_DS)){
10518 + memcpy(to, from, n);
10522 + return(access_ok_skas(VERIFY_WRITE, to, n) ?
10523 + buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
10527 +static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
10529 + char **to_ptr = arg, *to = *to_ptr;
10532 + strncpy(to, (void *) from, len);
10533 + n = strnlen(to, len);
10541 +int strncpy_from_user_skas(char *dst, const char *src, int count)
10546 + if(segment_eq(get_fs(), KERNEL_DS)){
10547 + strncpy(dst, src, count);
10548 + return(strnlen(dst, count));
10551 + if(!access_ok_skas(VERIFY_READ, src, 1))
10554 + n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user,
10558 + return(strnlen(dst, count));
10561 +static int clear_chunk(unsigned long addr, int len, void *unused)
10563 + memset((void *) addr, 0, len);
10567 +int __clear_user_skas(void *mem, int len)
10569 + return(buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL));
10572 +int clear_user_skas(void *mem, int len)
10574 + if(segment_eq(get_fs(), KERNEL_DS)){
10575 + memset(mem, 0, len);
10579 + return(access_ok_skas(VERIFY_WRITE, mem, len) ?
10580 + buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len);
10583 +static int strnlen_chunk(unsigned long str, int len, void *arg)
10585 + int *len_ptr = arg, n;
10587 + n = strnlen((void *) str, len);
10595 +int strnlen_user_skas(const void *str, int len)
10597 + int count = 0, n;
10599 + if(segment_eq(get_fs(), KERNEL_DS))
10600 + return(strnlen(str, len) + 1);
10602 + n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count);
10604 + return(count + 1);
10609 + * Overrides for Emacs so that we follow Linus's tabbing style.
10610 + * Emacs will notice this stuff at the end of the file and automatically
10611 + * adjust the settings for this buffer only. This must remain at the end
10613 + * ---------------------------------------------------------------------------
10614 + * Local variables:
10615 + * c-file-style: "linux"
10618 diff -Naur a/arch/um/kernel/skas/util/Makefile b/arch/um/kernel/skas/util/Makefile
10619 --- a/arch/um/kernel/skas/util/Makefile 2004-02-11 12:16:34.000000000 -0500
10620 +++ b/arch/um/kernel/skas/util/Makefile 2004-02-11 12:28:33.000000000 -0500
10624 mk_ptregs : mk_ptregs.o
10625 - $(CC) -o mk_ptregs mk_ptregs.o
10626 + $(HOSTCC) -o mk_ptregs mk_ptregs.o
10628 mk_ptregs.o : mk_ptregs.c
10633 - $(RM) -f mk_ptregs *.o *~
10634 +clean-files := mk_ptregs *.o *~
10635 diff -Naur a/arch/um/kernel/skas/util/mk_ptregs.c b/arch/um/kernel/skas/util/mk_ptregs.c
10636 --- a/arch/um/kernel/skas/util/mk_ptregs.c 2004-02-11 12:15:12.000000000 -0500
10637 +++ b/arch/um/kernel/skas/util/mk_ptregs.c 2004-02-11 12:27:00.000000000 -0500
10639 +#include <stdio.h>
10640 #include <asm/ptrace.h>
10641 #include <asm/user.h>
10643 diff -Naur a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
10644 --- a/arch/um/kernel/smp.c 2004-02-11 12:14:32.000000000 -0500
10645 +++ b/arch/um/kernel/smp.c 2004-02-11 12:26:13.000000000 -0500
10648 - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
10649 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
10650 * Licensed under the GPL
10653 #include "linux/config.h"
10654 +#include "linux/percpu.h"
10655 +#include "asm/pgalloc.h"
10656 +#include "asm/tlb.h"
10658 +/* For some reason, mmu_gathers are referenced when CONFIG_SMP is off. */
10659 +DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
10666 /* CPU online map, set by smp_boot_cpus */
10667 -unsigned long cpu_online_map = cpumask_of_cpu(0);
10668 +unsigned long cpu_online_map = CPU_MASK_NONE;
10670 EXPORT_SYMBOL(cpu_online_map);
10674 void smp_send_reschedule(int cpu)
10676 - write(cpu_data[cpu].ipi_pipe[1], "R", 1);
10677 + os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1);
10678 num_reschedules_sent++;
10681 @@ -100,35 +106,34 @@
10683 printk(KERN_INFO "Stopping all CPUs...");
10684 for(i = 0; i < num_online_cpus(); i++){
10685 - if(i == current->thread_info->cpu)
10686 + if(i == current_thread->cpu)
10688 - write(cpu_data[i].ipi_pipe[1], "S", 1);
10689 + os_write_file(cpu_data[i].ipi_pipe[1], "S", 1);
10694 -static cpumask_t smp_commenced_mask;
10695 -static cpumask_t smp_callin_map = CPU_MASK_NONE;
10696 +static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
10697 +static cpumask_t cpu_callin_map = CPU_MASK_NONE;
10699 static int idle_proc(void *cpup)
10701 int cpu = (int) cpup, err;
10703 err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
10705 - panic("CPU#%d failed to create IPI pipe, errno = %d", cpu,
10708 + panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);
10710 activate_ipi(cpu_data[cpu].ipi_pipe[0],
10711 current->thread.mode.tt.extern_pid);
10714 - if (cpu_test_and_set(cpu, &smp_callin_map)) {
10715 + if (cpu_test_and_set(cpu, cpu_callin_map)) {
10716 printk("huh, CPU#%d already present??\n", cpu);
10720 - while (!cpu_isset(cpu, &smp_commenced_mask))
10721 + while (!cpu_isset(cpu, smp_commenced_mask))
10724 cpu_set(cpu, cpu_online_map);
10725 @@ -143,16 +148,20 @@
10727 current->thread.request.u.thread.proc = idle_proc;
10728 current->thread.request.u.thread.arg = (void *) cpu;
10729 - new_task = do_fork(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, NULL);
10730 - if(IS_ERR(new_task)) panic("do_fork failed in idle_thread");
10731 + new_task = copy_process(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL,
10733 + if(IS_ERR(new_task))
10734 + panic("copy_process failed in idle_thread, error = %ld",
10735 + PTR_ERR(new_task));
10737 cpu_tasks[cpu] = ((struct cpu_task)
10738 { .pid = new_task->thread.mode.tt.extern_pid,
10739 .task = new_task } );
10740 idle_threads[cpu] = new_task;
10741 - CHOOSE_MODE(write(new_task->thread.mode.tt.switch_pipe[1], &c,
10742 + CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c,
10744 ({ panic("skas mode doesn't support SMP"); }));
10745 + wake_up_forked_process(new_task);
10749 @@ -160,15 +169,17 @@
10751 struct task_struct *idle;
10752 unsigned long waittime;
10754 + int err, cpu, me = smp_processor_id();
10756 - cpu_set(0, cpu_online_map);
10757 - cpu_set(0, smp_callin_map);
10758 + cpu_clear(me, cpu_online_map);
10759 + cpu_set(me, cpu_online_map);
10760 + cpu_set(me, cpu_callin_map);
10762 - err = os_pipe(cpu_data[0].ipi_pipe, 1, 1);
10763 - if(err) panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
10764 + err = os_pipe(cpu_data[me].ipi_pipe, 1, 1);
10766 + panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
10768 - activate_ipi(cpu_data[0].ipi_pipe[0],
10769 + activate_ipi(cpu_data[me].ipi_pipe[0],
10770 current->thread.mode.tt.extern_pid);
10772 for(cpu = 1; cpu < ncpus; cpu++){
10773 @@ -180,10 +191,10 @@
10774 unhash_process(idle);
10776 waittime = 200000000;
10777 - while (waittime-- && !cpu_isset(cpu, smp_callin_map))
10778 + while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
10781 - if (cpu_isset(cpu, smp_callin_map))
10782 + if (cpu_isset(cpu, cpu_callin_map))
10784 else printk("failed\n");
10786 @@ -216,7 +227,7 @@
10789 fd = cpu_data[cpu].ipi_pipe[0];
10790 - while (read(fd, &c, 1) == 1) {
10791 + while (os_read_file(fd, &c, 1) == 1) {
10794 smp_call_function_slave(cpu);
10795 @@ -273,9 +284,9 @@
10798 for (i=0;i<NR_CPUS;i++)
10799 - if((i != current->thread_info->cpu) &&
10800 + if((i != current_thread->cpu) &&
10801 cpu_isset(i, cpu_online_map))
10802 - write(cpu_data[i].ipi_pipe[1], "C", 1);
10803 + os_write_file(cpu_data[i].ipi_pipe[1], "C", 1);
10805 while (atomic_read(&scf_started) != cpus)
10807 diff -Naur a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c
10808 --- a/arch/um/kernel/syscall_kern.c 2004-02-11 12:16:08.000000000 -0500
10809 +++ b/arch/um/kernel/syscall_kern.c 2004-02-11 12:28:04.000000000 -0500
10812 - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
10813 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
10814 * Licensed under the GPL
10817 @@ -35,39 +35,40 @@
10819 long sys_fork(void)
10821 - struct task_struct *p;
10824 current->thread.forking = 1;
10825 - p = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
10826 + ret = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
10827 current->thread.forking = 0;
10828 - return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
10832 -long sys_clone(unsigned long clone_flags, unsigned long newsp)
10833 +long sys_clone(unsigned long clone_flags, unsigned long newsp,
10834 + int *parent_tid, int *child_tid)
10836 - struct task_struct *p;
10839 current->thread.forking = 1;
10840 - p = do_fork(clone_flags, newsp, NULL, 0, NULL, NULL);
10841 + ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid);
10842 current->thread.forking = 0;
10843 - return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
10847 long sys_vfork(void)
10849 - struct task_struct *p;
10852 current->thread.forking = 1;
10853 - p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, NULL);
10854 + ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL,
10856 current->thread.forking = 0;
10857 - return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
10861 /* common code for old and new mmaps */
10862 -static inline long do_mmap2(
10863 - unsigned long addr, unsigned long len,
10864 - unsigned long prot, unsigned long flags,
10865 - unsigned long fd, unsigned long pgoff)
10866 +long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len,
10867 + unsigned long prot, unsigned long flags, unsigned long fd,
10868 + unsigned long pgoff)
10870 int error = -EBADF;
10871 struct file * file = NULL;
10876 - down_write(¤t->mm->mmap_sem);
10877 - error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
10878 - up_write(¤t->mm->mmap_sem);
10879 + down_write(&mm->mmap_sem);
10880 + error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
10881 + up_write(&mm->mmap_sem);
10886 unsigned long prot, unsigned long flags,
10887 unsigned long fd, unsigned long pgoff)
10889 - return do_mmap2(addr, len, prot, flags, fd, pgoff);
10890 + return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
10894 @@ -120,7 +121,8 @@
10895 if (offset & ~PAGE_MASK)
10898 - err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
10899 + err = do_mmap2(current->mm, addr, len, prot, flags, fd,
10900 + offset >> PAGE_SHIFT);
10904 @@ -135,43 +137,12 @@
10906 error = do_pipe(fd);
10908 - if (copy_to_user(fildes, fd, 2*sizeof(int)))
10909 + if (copy_to_user(fildes, fd, sizeof(fd)))
10915 -int sys_sigaction(int sig, const struct old_sigaction *act,
10916 - struct old_sigaction *oact)
10918 - struct k_sigaction new_ka, old_ka;
10922 - old_sigset_t mask;
10923 - if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
10924 - __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
10925 - __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
10927 - __get_user(new_ka.sa.sa_flags, &act->sa_flags);
10928 - __get_user(mask, &act->sa_mask);
10929 - siginitset(&new_ka.sa.sa_mask, mask);
10932 - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
10934 - if (!ret && oact) {
10935 - if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
10936 - __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
10937 - __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
10939 - __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
10940 - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
10947 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
10949 @@ -253,7 +224,7 @@
10950 return sys_shmctl (first, second,
10951 (struct shmid_ds *) ptr);
10958 @@ -302,11 +273,6 @@
10962 -int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
10964 - return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs)));
10967 long execute_syscall(void *r)
10969 return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
10970 diff -Naur a/arch/um/kernel/sys_call_table.c b/arch/um/kernel/sys_call_table.c
10971 --- a/arch/um/kernel/sys_call_table.c 2004-02-11 12:16:34.000000000 -0500
10972 +++ b/arch/um/kernel/sys_call_table.c 2004-02-11 12:28:33.000000000 -0500
10975 #include "linux/config.h"
10976 #include "linux/unistd.h"
10977 -#include "linux/version.h"
10978 #include "linux/sys.h"
10979 #include "linux/swap.h"
10980 #include "linux/sysctl.h"
10981 @@ -219,15 +218,30 @@
10982 extern syscall_handler_t sys_gettid;
10983 extern syscall_handler_t sys_readahead;
10984 extern syscall_handler_t sys_tkill;
10985 +extern syscall_handler_t sys_setxattr;
10986 +extern syscall_handler_t sys_lsetxattr;
10987 +extern syscall_handler_t sys_fsetxattr;
10988 +extern syscall_handler_t sys_getxattr;
10989 +extern syscall_handler_t sys_lgetxattr;
10990 +extern syscall_handler_t sys_fgetxattr;
10991 +extern syscall_handler_t sys_listxattr;
10992 +extern syscall_handler_t sys_llistxattr;
10993 +extern syscall_handler_t sys_flistxattr;
10994 +extern syscall_handler_t sys_removexattr;
10995 +extern syscall_handler_t sys_lremovexattr;
10996 +extern syscall_handler_t sys_fremovexattr;
10997 extern syscall_handler_t sys_sendfile64;
10998 extern syscall_handler_t sys_futex;
10999 extern syscall_handler_t sys_sched_setaffinity;
11000 extern syscall_handler_t sys_sched_getaffinity;
11001 +extern syscall_handler_t sys_set_thread_area;
11002 +extern syscall_handler_t sys_get_thread_area;
11003 extern syscall_handler_t sys_io_setup;
11004 extern syscall_handler_t sys_io_destroy;
11005 extern syscall_handler_t sys_io_getevents;
11006 extern syscall_handler_t sys_io_submit;
11007 extern syscall_handler_t sys_io_cancel;
11008 +extern syscall_handler_t sys_fadvise64;
11009 extern syscall_handler_t sys_exit_group;
11010 extern syscall_handler_t sys_lookup_dcookie;
11011 extern syscall_handler_t sys_epoll_create;
11012 @@ -235,6 +249,20 @@
11013 extern syscall_handler_t sys_epoll_wait;
11014 extern syscall_handler_t sys_remap_file_pages;
11015 extern syscall_handler_t sys_set_tid_address;
11016 +extern syscall_handler_t sys_timer_create;
11017 +extern syscall_handler_t sys_timer_settime;
11018 +extern syscall_handler_t sys_timer_gettime;
11019 +extern syscall_handler_t sys_timer_getoverrun;
11020 +extern syscall_handler_t sys_timer_delete;
11021 +extern syscall_handler_t sys_clock_settime;
11022 +extern syscall_handler_t sys_clock_gettime;
11023 +extern syscall_handler_t sys_clock_getres;
11024 +extern syscall_handler_t sys_clock_nanosleep;
11025 +extern syscall_handler_t sys_statfs64;
11026 +extern syscall_handler_t sys_fstatfs64;
11027 +extern syscall_handler_t sys_tgkill;
11028 +extern syscall_handler_t sys_utimes;
11029 +extern syscall_handler_t sys_fadvise64_64;
11032 #define NFSSERVCTL sys_nfsservctl
11033 @@ -246,7 +274,7 @@
11034 extern syscall_handler_t um_time;
11035 extern syscall_handler_t um_stime;
11037 -#define LAST_GENERIC_SYSCALL __NR_set_tid_address
11038 +#define LAST_GENERIC_SYSCALL __NR_vserver
11040 #if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
11041 #define LAST_SYSCALL LAST_GENERIC_SYSCALL
11042 @@ -455,32 +483,37 @@
11043 [ __NR_stat64 ] = sys_stat64,
11044 [ __NR_lstat64 ] = sys_lstat64,
11045 [ __NR_fstat64 ] = sys_fstat64,
11046 - [ __NR_fcntl64 ] = sys_fcntl64,
11047 [ __NR_getdents64 ] = sys_getdents64,
11048 + [ __NR_fcntl64 ] = sys_fcntl64,
11049 + [ 223 ] = sys_ni_syscall,
11050 [ __NR_gettid ] = sys_gettid,
11051 [ __NR_readahead ] = sys_readahead,
11052 - [ __NR_setxattr ] = sys_ni_syscall,
11053 - [ __NR_lsetxattr ] = sys_ni_syscall,
11054 - [ __NR_fsetxattr ] = sys_ni_syscall,
11055 - [ __NR_getxattr ] = sys_ni_syscall,
11056 - [ __NR_lgetxattr ] = sys_ni_syscall,
11057 - [ __NR_fgetxattr ] = sys_ni_syscall,
11058 - [ __NR_listxattr ] = sys_ni_syscall,
11059 - [ __NR_llistxattr ] = sys_ni_syscall,
11060 - [ __NR_flistxattr ] = sys_ni_syscall,
11061 - [ __NR_removexattr ] = sys_ni_syscall,
11062 - [ __NR_lremovexattr ] = sys_ni_syscall,
11063 - [ __NR_fremovexattr ] = sys_ni_syscall,
11064 + [ __NR_setxattr ] = sys_setxattr,
11065 + [ __NR_lsetxattr ] = sys_lsetxattr,
11066 + [ __NR_fsetxattr ] = sys_fsetxattr,
11067 + [ __NR_getxattr ] = sys_getxattr,
11068 + [ __NR_lgetxattr ] = sys_lgetxattr,
11069 + [ __NR_fgetxattr ] = sys_fgetxattr,
11070 + [ __NR_listxattr ] = sys_listxattr,
11071 + [ __NR_llistxattr ] = sys_llistxattr,
11072 + [ __NR_flistxattr ] = sys_flistxattr,
11073 + [ __NR_removexattr ] = sys_removexattr,
11074 + [ __NR_lremovexattr ] = sys_lremovexattr,
11075 + [ __NR_fremovexattr ] = sys_fremovexattr,
11076 [ __NR_tkill ] = sys_tkill,
11077 [ __NR_sendfile64 ] = sys_sendfile64,
11078 [ __NR_futex ] = sys_futex,
11079 [ __NR_sched_setaffinity ] = sys_sched_setaffinity,
11080 [ __NR_sched_getaffinity ] = sys_sched_getaffinity,
11081 + [ __NR_set_thread_area ] = sys_ni_syscall,
11082 + [ __NR_get_thread_area ] = sys_ni_syscall,
11083 [ __NR_io_setup ] = sys_io_setup,
11084 [ __NR_io_destroy ] = sys_io_destroy,
11085 [ __NR_io_getevents ] = sys_io_getevents,
11086 [ __NR_io_submit ] = sys_io_submit,
11087 [ __NR_io_cancel ] = sys_io_cancel,
11088 + [ __NR_fadvise64 ] = sys_fadvise64,
11089 + [ 251 ] = sys_ni_syscall,
11090 [ __NR_exit_group ] = sys_exit_group,
11091 [ __NR_lookup_dcookie ] = sys_lookup_dcookie,
11092 [ __NR_epoll_create ] = sys_epoll_create,
11093 @@ -488,6 +521,21 @@
11094 [ __NR_epoll_wait ] = sys_epoll_wait,
11095 [ __NR_remap_file_pages ] = sys_remap_file_pages,
11096 [ __NR_set_tid_address ] = sys_set_tid_address,
11097 + [ __NR_timer_create ] = sys_timer_create,
11098 + [ __NR_timer_settime ] = sys_timer_settime,
11099 + [ __NR_timer_gettime ] = sys_timer_gettime,
11100 + [ __NR_timer_getoverrun ] = sys_timer_getoverrun,
11101 + [ __NR_timer_delete ] = sys_timer_delete,
11102 + [ __NR_clock_settime ] = sys_clock_settime,
11103 + [ __NR_clock_gettime ] = sys_clock_gettime,
11104 + [ __NR_clock_getres ] = sys_clock_getres,
11105 + [ __NR_clock_nanosleep ] = sys_clock_nanosleep,
11106 + [ __NR_statfs64 ] = sys_statfs64,
11107 + [ __NR_fstatfs64 ] = sys_fstatfs64,
11108 + [ __NR_tgkill ] = sys_tgkill,
11109 + [ __NR_utimes ] = sys_utimes,
11110 + [ __NR_fadvise64_64 ] = sys_fadvise64_64,
11111 + [ __NR_vserver ] = sys_ni_syscall,
11114 [ LAST_SYSCALL + 1 ... NR_syscalls ] =
11115 diff -Naur a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
11116 --- a/arch/um/kernel/sysrq.c 2004-02-11 12:14:56.000000000 -0500
11117 +++ b/arch/um/kernel/sysrq.c 2004-02-11 12:26:47.000000000 -0500
11119 show_trace((unsigned long *)esp);
11122 +void show_stack(struct task_struct *task, unsigned long *sp)
11125 + show_trace_task(task);
11131 * Overrides for Emacs so that we follow Linus's tabbing style.
11132 * Emacs will notice this stuff at the end of the file and automatically
11133 diff -Naur a/arch/um/kernel/tempfile.c b/arch/um/kernel/tempfile.c
11134 --- a/arch/um/kernel/tempfile.c 2004-02-11 12:15:48.000000000 -0500
11135 +++ b/arch/um/kernel/tempfile.c 2004-02-11 12:27:41.000000000 -0500
11138 if((dir == NULL) || (*dir == '\0'))
11141 tempdir = malloc(strlen(dir) + 2);
11142 if(tempdir == NULL){
11143 fprintf(stderr, "Failed to malloc tempdir, "
11147 strcat(tempname, template);
11148 - if((fd = mkstemp(tempname)) < 0){
11149 + fd = mkstemp(tempname);
11151 fprintf(stderr, "open - cannot create %s: %s\n", tempname,
11158 - if((*out_tempname = strdup(tempname)) == NULL){
11159 + *out_tempname = strdup(tempname);
11160 + if(*out_tempname == NULL){
11164 diff -Naur a/arch/um/kernel/time.c b/arch/um/kernel/time.c
11165 --- a/arch/um/kernel/time.c 2004-02-11 12:14:28.000000000 -0500
11166 +++ b/arch/um/kernel/time.c 2004-02-11 12:26:11.000000000 -0500
11171 +#include <stdlib.h>
11172 #include <unistd.h>
11174 #include <sys/time.h>
11175 #include <signal.h>
11177 -#include "linux/module.h"
11178 #include "user_util.h"
11179 #include "kern_util.h"
11181 #include "process.h"
11182 #include "signal_user.h"
11183 #include "time_user.h"
11184 +#include "kern_constants.h"
11186 +/* XXX This really needs to be declared and initialized in a kernel file since
11187 + * it's in <linux/time.h>
11189 +extern struct timespec wall_to_monotonic;
11191 extern struct timeval xtime;
11193 +struct timeval local_offset = { 0, 0 };
11197 gettimeofday(&xtime, NULL);
11198 + timeradd(&xtime, &local_offset, &xtime);
11201 void set_interval(int timer_type)
11206 -void idle_timer(void)
11207 +void uml_idle_timer(void)
11209 if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
11210 panic("Couldn't unset SIGVTALRM handler");
11211 @@ -76,14 +85,56 @@
11212 set_interval(ITIMER_REAL);
11215 +static unsigned long long get_host_hz(void)
11217 + char mhzline[16], *end;
11218 + int ret, mult, mhz, rest, len;
11220 + ret = cpu_feature("cpu MHz", mhzline,
11221 + sizeof(mhzline) / sizeof(mhzline[0]));
11223 + panic ("Could not get host MHZ");
11225 + mhz = strtoul(mhzline, &end, 10);
11227 + /* This business is to parse a floating point number without using
11228 + * floating types.
11235 + len = strlen(end);
11240 + rest = strtoul(end, NULL, 10);
11241 + while(mult-- > 0)
11245 + return(1000000 * mhz + rest);
11248 +unsigned long long host_hz = 0;
11250 +extern int do_posix_clock_monotonic_gettime(struct timespec *tp);
11252 void time_init(void)
11254 + struct timespec now;
11256 + host_hz = get_host_hz();
11257 if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
11258 panic("Couldn't set SIGVTALRM handler");
11259 set_interval(ITIMER_VIRTUAL);
11262 -struct timeval local_offset = { 0, 0 };
11263 + do_posix_clock_monotonic_gettime(&now);
11264 + wall_to_monotonic.tv_sec = -now.tv_sec;
11265 + wall_to_monotonic.tv_nsec = -now.tv_nsec;
11268 void do_gettimeofday(struct timeval *tv)
11270 @@ -95,15 +146,13 @@
11271 time_unlock(flags);
11274 -EXPORT_SYMBOL(do_gettimeofday);
11276 int do_settimeofday(struct timespec *tv)
11278 struct timeval now;
11279 unsigned long flags;
11280 struct timeval tv_in;
11282 - if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
11283 + if ((unsigned long) tv->tv_nsec >= UM_NSEC_PER_SEC)
11286 tv_in.tv_sec = tv->tv_sec;
11287 @@ -113,9 +162,9 @@
11288 gettimeofday(&now, NULL);
11289 timersub(&tv_in, &now, &local_offset);
11290 time_unlock(flags);
11293 -EXPORT_SYMBOL(do_settimeofday);
11297 void idle_sleep(int secs)
11299 diff -Naur a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
11300 --- a/arch/um/kernel/time_kern.c 2004-02-11 12:15:59.000000000 -0500
11301 +++ b/arch/um/kernel/time_kern.c 2004-02-11 12:27:52.000000000 -0500
11307 + * Scheduler clock - returns current time in nanosec units.
11309 +unsigned long long sched_clock(void)
11311 + return (unsigned long long)jiffies_64 * (1000000000 / HZ);
11314 /* Changed at early boot */
11315 int timer_irq_inited = 0;
11317 @@ -39,13 +47,47 @@
11319 int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS];
11321 +static int first_tick;
11322 +static unsigned long long prev_tsc;
11323 +static long long delta; /* Deviation per interval */
11325 +extern unsigned long long host_hz;
11327 void timer_irq(union uml_pt_regs *regs)
11329 - int cpu = current->thread_info->cpu, ticks = missed_ticks[cpu];
11330 + unsigned long long ticks = 0;
11332 + if(!timer_irq_inited){
11333 + /* This is to ensure that ticks don't pile up when
11334 + * the timer handler is suspended */
11340 +#if defined(CONFIG_UML_REAL_TIME_CLOCK)
11341 + unsigned long long tsc;
11342 + /* We've had 1 tick */
11343 + tsc = time_stamp();
11345 + delta += tsc - prev_tsc;
11348 + ticks += (delta * HZ) / host_hz;
11349 + delta -= (ticks * host_hz) / HZ;
11355 + prev_tsc = time_stamp();
11359 - if(!timer_irq_inited) return;
11360 - missed_ticks[cpu] = 0;
11361 - while(ticks--) do_IRQ(TIMER_IRQ, regs);
11362 + while(ticks > 0){
11363 + do_IRQ(TIMER_IRQ, regs);
11368 void boot_timer_handler(int sig)
11369 @@ -58,12 +100,13 @@
11373 -void um_timer(int irq, void *dev, struct pt_regs *regs)
11374 +irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
11377 - write_seqlock(&xtime_lock);
11378 + write_seqlock_irq(&xtime_lock);
11380 - write_sequnlock(&xtime_lock);
11381 + write_sequnlock_irq(&xtime_lock);
11382 + return(IRQ_HANDLED);
11385 long um_time(int * tloc)
11386 @@ -81,12 +124,12 @@
11387 long um_stime(int * tptr)
11390 - struct timeval new;
11391 + struct timespec new;
11393 if (get_user(value, tptr))
11395 new.tv_sec = value;
11398 do_settimeofday(&new);
11401 @@ -125,9 +168,11 @@
11402 void timer_handler(int sig, union uml_pt_regs *regs)
11405 + local_irq_disable();
11406 update_process_times(user_context(UPT_SP(regs)));
11407 + local_irq_enable();
11409 - if(current->thread_info->cpu == 0)
11410 + if(current_thread->cpu == 0)
11414 @@ -136,6 +181,7 @@
11415 unsigned long time_lock(void)
11417 unsigned long flags;
11419 spin_lock_irqsave(&timer_spinlock, flags);
11422 @@ -150,8 +196,8 @@
11425 CHOOSE_MODE(user_time_init_tt(), user_time_init_skas());
11426 - if((err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer",
11428 + err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL);
11430 printk(KERN_ERR "timer_init : request_irq failed - "
11431 "errno = %d\n", -err);
11432 timer_irq_inited = 1;
11433 @@ -160,7 +206,6 @@
11435 __initcall(timer_init);
11439 * Overrides for Emacs so that we follow Linus's tabbing style.
11440 * Emacs will notice this stuff at the end of the file and automatically
11441 diff -Naur a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
11442 --- a/arch/um/kernel/trap_kern.c 2004-02-11 12:14:18.000000000 -0500
11443 +++ b/arch/um/kernel/trap_kern.c 2004-02-11 12:26:00.000000000 -0500
11444 @@ -16,12 +16,15 @@
11445 #include "asm/tlbflush.h"
11446 #include "asm/a.out.h"
11447 #include "asm/current.h"
11448 +#include "asm/irq.h"
11449 #include "user_util.h"
11450 #include "kern_util.h"
11452 #include "chan_kern.h"
11453 #include "mconsole_kern.h"
11454 #include "2_5compat.h"
11456 +#include "mem_kern.h"
11458 int handle_page_fault(unsigned long address, unsigned long ip,
11459 int is_write, int is_user, int *code_out)
11460 @@ -51,12 +54,12 @@
11461 if(is_write && !(vma->vm_flags & VM_WRITE))
11463 page = address & PAGE_MASK;
11464 - if(page == (unsigned long) current->thread_info + PAGE_SIZE)
11465 + if(page == (unsigned long) current_thread + PAGE_SIZE)
11466 panic("Kernel stack overflow");
11467 pgd = pgd_offset(mm, page);
11468 pmd = pmd_offset(pgd, page);
11472 switch (handle_mm_fault(mm, vma, address, is_write)){
11473 case VM_FAULT_MINOR:
11474 current->min_flt++;
11475 @@ -71,14 +74,20 @@
11477 goto out_of_memory;
11480 + if (current->pid == 1) {
11481 + up_read(&mm->mmap_sem);
11483 + down_read(&mm->mmap_sem);
11488 pte = pte_offset_kernel(pmd, page);
11489 } while(!pte_present(*pte));
11491 *pte = pte_mkyoung(*pte);
11492 if(pte_write(*pte)) *pte = pte_mkdirty(*pte);
11493 flush_tlb_page(vma, page);
11496 up_read(&mm->mmap_sem);
11498 @@ -98,6 +107,33 @@
11502 +LIST_HEAD(physmem_remappers);
11504 +void register_remapper(struct remapper *info)
11506 + list_add(&info->list, &physmem_remappers);
11509 +static int check_remapped_addr(unsigned long address, int is_write)
11511 + struct remapper *remapper;
11512 + struct list_head *ele;
11516 + fd = phys_mapping(__pa(address), &offset);
11520 + list_for_each(ele, &physmem_remappers){
11521 + remapper = list_entry(ele, struct remapper, list);
11522 + if((*remapper->proc)(fd, address, is_write, offset))
11529 unsigned long segv(unsigned long address, unsigned long ip, int is_write,
11530 int is_user, void *sc)
11532 @@ -109,7 +145,9 @@
11533 flush_tlb_kernel_vm();
11536 - if(current->mm == NULL)
11537 + else if(check_remapped_addr(address & PAGE_MASK, is_write))
11539 + else if(current->mm == NULL)
11540 panic("Segfault with no mm");
11541 err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
11543 @@ -120,9 +158,8 @@
11544 current->thread.fault_addr = (void *) address;
11545 do_longjmp(catcher, 1);
11547 - else if(current->thread.fault_addr != NULL){
11548 + else if(current->thread.fault_addr != NULL)
11549 panic("fault_addr set but no fault catcher");
11551 else if(arch_fixup(ip, sc))
11554 @@ -155,8 +192,6 @@
11558 - printk(KERN_ERR "Unfixable SEGV in '%s' (pid %d) at 0x%lx "
11559 - "(ip 0x%lx)\n", current->comm, current->pid, address, ip);
11560 si.si_signo = SIGSEGV;
11561 si.si_code = SEGV_ACCERR;
11562 si.si_addr = (void *) address;
11563 @@ -180,6 +215,11 @@
11564 else relay_signal(sig, regs);
11567 +void winch(int sig, union uml_pt_regs *regs)
11569 + do_IRQ(WINCH_IRQ, regs);
11572 void trap_init(void)
11575 diff -Naur a/arch/um/kernel/trap_user.c b/arch/um/kernel/trap_user.c
11576 --- a/arch/um/kernel/trap_user.c 2004-02-11 12:15:23.000000000 -0500
11577 +++ b/arch/um/kernel/trap_user.c 2004-02-11 12:27:10.000000000 -0500
11580 #include <stdlib.h>
11582 -#include <fcntl.h>
11583 #include <setjmp.h>
11584 #include <signal.h>
11585 #include <sys/time.h>
11586 -#include <sys/ioctl.h>
11587 #include <sys/ptrace.h>
11588 #include <sys/wait.h>
11589 #include <asm/page.h>
11592 [ SIGILL ] { .handler = relay_signal,
11594 + [ SIGWINCH ] { .handler = winch,
11596 [ SIGBUS ] { .handler = bus_handler,
11598 [ SIGSEGV] { .handler = segv_handler,
11599 @@ -123,7 +123,7 @@
11603 - longjmp(*buf, val);
11604 + siglongjmp(*buf, val);
11608 diff -Naur a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c
11609 --- a/arch/um/kernel/tt/exec_kern.c 2004-02-11 12:14:28.000000000 -0500
11610 +++ b/arch/um/kernel/tt/exec_kern.c 2004-02-11 12:26:11.000000000 -0500
11612 #include "mem_user.h"
11617 static int exec_tramp(void *sig_stack)
11619 @@ -47,17 +48,17 @@
11623 - if(current->thread_info->cpu == 0)
11624 + if(current_thread->cpu == 0)
11625 forward_interrupts(new_pid);
11626 current->thread.request.op = OP_EXEC;
11627 current->thread.request.u.exec.pid = new_pid;
11628 - unprotect_stack((unsigned long) current->thread_info);
11629 + unprotect_stack((unsigned long) current_thread);
11630 os_usr1_process(os_getpid());
11634 protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
11635 - task_protections((unsigned long) current->thread_info);
11636 + task_protections((unsigned long) current_thread);
11640 diff -Naur a/arch/um/kernel/tt/include/mode.h b/arch/um/kernel/tt/include/mode.h
11641 --- a/arch/um/kernel/tt/include/mode.h 2004-02-11 12:16:01.000000000 -0500
11642 +++ b/arch/um/kernel/tt/include/mode.h 2004-02-11 12:27:56.000000000 -0500
11645 #include "sysdep/ptrace.h"
11647 +enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
11649 extern int tracing_pid;
11651 extern int tracer(int (*init_proc)(void *), void *sp);
11652 diff -Naur a/arch/um/kernel/tt/include/uaccess.h b/arch/um/kernel/tt/include/uaccess.h
11653 --- a/arch/um/kernel/tt/include/uaccess.h 2004-02-11 12:16:02.000000000 -0500
11654 +++ b/arch/um/kernel/tt/include/uaccess.h 2004-02-11 12:27:56.000000000 -0500
11657 - * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
11658 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
11659 * Licensed under the GPL
11662 @@ -43,65 +43,19 @@
11664 extern int __do_copy_from_user(void *to, const void *from, int n,
11665 void **fault_addr, void **fault_catcher);
11667 -static inline int copy_from_user_tt(void *to, const void *from, int n)
11669 - return(access_ok_tt(VERIFY_READ, from, n) ?
11670 - __do_copy_from_user(to, from, n,
11671 - ¤t->thread.fault_addr,
11672 - ¤t->thread.fault_catcher) : n);
11675 -static inline int copy_to_user_tt(void *to, const void *from, int n)
11677 - return(access_ok_tt(VERIFY_WRITE, to, n) ?
11678 - __do_copy_to_user(to, from, n,
11679 - ¤t->thread.fault_addr,
11680 - ¤t->thread.fault_catcher) : n);
11683 extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
11684 void **fault_addr, void **fault_catcher);
11686 -static inline int strncpy_from_user_tt(char *dst, const char *src, int count)
11690 - if(!access_ok_tt(VERIFY_READ, src, 1)) return(-EFAULT);
11691 - n = __do_strncpy_from_user(dst, src, count,
11692 - ¤t->thread.fault_addr,
11693 - ¤t->thread.fault_catcher);
11694 - if(n < 0) return(-EFAULT);
11698 extern int __do_clear_user(void *mem, size_t len, void **fault_addr,
11699 void **fault_catcher);
11701 -static inline int __clear_user_tt(void *mem, int len)
11703 - return(__do_clear_user(mem, len,
11704 - ¤t->thread.fault_addr,
11705 - ¤t->thread.fault_catcher));
11708 -static inline int clear_user_tt(void *mem, int len)
11710 - return(access_ok_tt(VERIFY_WRITE, mem, len) ?
11711 - __do_clear_user(mem, len,
11712 - ¤t->thread.fault_addr,
11713 - ¤t->thread.fault_catcher) : len);
11716 extern int __do_strnlen_user(const char *str, unsigned long n,
11717 void **fault_addr, void **fault_catcher);
11719 -static inline int strnlen_user_tt(const void *str, int len)
11721 - return(__do_strnlen_user(str, len,
11722 - ¤t->thread.fault_addr,
11723 - ¤t->thread.fault_catcher));
11725 +extern int copy_from_user_tt(void *to, const void *from, int n);
11726 +extern int copy_to_user_tt(void *to, const void *from, int n);
11727 +extern int strncpy_from_user_tt(char *dst, const char *src, int count);
11728 +extern int __clear_user_tt(void *mem, int len);
11729 +extern int clear_user_tt(void *mem, int len);
11730 +extern int strnlen_user_tt(const void *str, int len);
11734 diff -Naur a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile
11735 --- a/arch/um/kernel/tt/Makefile 2004-02-11 12:15:45.000000000 -0500
11736 +++ b/arch/um/kernel/tt/Makefile 2004-02-11 12:27:36.000000000 -0500
11739 -# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
11740 +# Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
11741 # Licensed under the GPL
11746 obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
11747 syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \
11748 - uaccess_user.o sys-$(SUBARCH)/
11749 + uaccess.o uaccess_user.o sys-$(SUBARCH)/
11751 obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/
11755 $(obj)/unmap_fin.o : $(src)/unmap.o
11756 ld -r -o $@ $< -lc -L/usr/lib
11759 diff -Naur a/arch/um/kernel/tt/mem_user.c b/arch/um/kernel/tt/mem_user.c
11760 --- a/arch/um/kernel/tt/mem_user.c 2004-02-11 12:14:34.000000000 -0500
11761 +++ b/arch/um/kernel/tt/mem_user.c 2004-02-11 12:26:17.000000000 -0500
11762 @@ -25,14 +25,13 @@
11763 size = (unsigned long) segment_end -
11764 (unsigned long) segment_start;
11765 data = create_mem_file(size);
11766 - if((addr = mmap(NULL, size, PROT_WRITE | PROT_READ,
11767 - MAP_SHARED, data, 0)) == MAP_FAILED){
11768 + addr = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, data, 0);
11769 + if(addr == MAP_FAILED){
11770 perror("mapping new data segment");
11773 memcpy(addr, segment_start, size);
11774 - if(switcheroo(data, prot, addr, segment_start,
11776 + if(switcheroo(data, prot, addr, segment_start, size) < 0){
11777 printf("switcheroo failed\n");
11780 diff -Naur a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
11781 --- a/arch/um/kernel/tt/process_kern.c 2004-02-11 12:16:33.000000000 -0500
11782 +++ b/arch/um/kernel/tt/process_kern.c 2004-02-11 12:28:32.000000000 -0500
11785 err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
11786 if(err != sizeof(c))
11787 - panic("write of switch_pipe failed, errno = %d", -err);
11788 + panic("write of switch_pipe failed, err = %d", -err);
11791 if((from->state == TASK_ZOMBIE) || (from->state == TASK_DEAD))
11792 @@ -104,48 +104,72 @@
11794 void release_thread_tt(struct task_struct *task)
11796 - os_kill_process(task->thread.mode.tt.extern_pid, 0);
11797 + int pid = task->thread.mode.tt.extern_pid;
11799 + if(os_getpid() != pid)
11800 + os_kill_process(pid, 0);
11803 void exit_thread_tt(void)
11805 - close(current->thread.mode.tt.switch_pipe[0]);
11806 - close(current->thread.mode.tt.switch_pipe[1]);
11807 + os_close_file(current->thread.mode.tt.switch_pipe[0]);
11808 + os_close_file(current->thread.mode.tt.switch_pipe[1]);
11811 void schedule_tail(task_t *prev);
11813 static void new_thread_handler(int sig)
11815 + unsigned long disable;
11819 fn = current->thread.request.u.thread.proc;
11820 arg = current->thread.request.u.thread.arg;
11822 UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1);
11823 + disable = (1 << (SIGVTALRM - 1)) | (1 << (SIGALRM - 1)) |
11824 + (1 << (SIGIO - 1)) | (1 << (SIGPROF - 1));
11825 + SC_SIGMASK(UPT_SC(¤t->thread.regs.regs)) &= ~disable;
11827 suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
11830 + force_flush_all();
11831 + if(current->thread.prev_sched != NULL)
11832 + schedule_tail(current->thread.prev_sched);
11833 + current->thread.prev_sched = NULL;
11835 init_new_thread_signals(1);
11837 - schedule_tail(current->thread.prev_sched);
11840 free_page(current->thread.temp_stack);
11841 set_cmdline("(kernel thread)");
11842 - force_flush_all();
11844 - current->thread.prev_sched = NULL;
11845 change_sig(SIGUSR1, 1);
11846 change_sig(SIGVTALRM, 1);
11847 change_sig(SIGPROF, 1);
11848 - unblock_signals();
11849 + local_irq_enable();
11850 if(!run_kernel_thread(fn, arg, ¤t->thread.exec_buf))
11854 static int new_thread_proc(void *stack)
11856 + /* local_irq_disable is needed to block out signals until this thread is
11857 + * properly scheduled. Otherwise, the tracing thread will get mighty
11858 + * upset about any signals that arrive before that.
11859 + * This has the complication that it sets the saved signal mask in
11860 + * the sigcontext to block signals. This gets restored when this
11861 + * thread (or a descendant, since they get a copy of this sigcontext)
11862 + * returns to userspace.
11863 + * So, this is compensated for elsewhere.
11864 + * XXX There is still a small window until local_irq_disable() actually
11865 + * finishes where signals are possible - shouldn't be a problem in
11866 + * practice since SIGIO hasn't been forwarded here yet, and the
11867 + * local_irq_disable should finish before a SIGVTALRM has time to be
11871 + local_irq_disable();
11872 init_new_thread_stack(stack, new_thread_handler);
11873 os_usr1_process(os_getpid());
11875 @@ -156,7 +180,7 @@
11876 * itself with a SIGUSR1. set_user_mode has to be run with SIGUSR1 off,
11877 * so it is blocked before it's called. They are re-enabled on sigreturn
11878 * despite the fact that they were blocked when the SIGUSR1 was issued because
11879 - * copy_thread copies the parent's signcontext, including the signal mask
11880 + * copy_thread copies the parent's sigcontext, including the signal mask
11881 * onto the signal frame.
11884 @@ -165,35 +189,32 @@
11885 UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1);
11886 suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
11889 - schedule_tail(NULL);
11891 + force_flush_all();
11892 + if(current->thread.prev_sched != NULL)
11893 + schedule_tail(current->thread.prev_sched);
11894 + current->thread.prev_sched = NULL;
11897 change_sig(SIGVTALRM, 1);
11898 local_irq_enable();
11899 - force_flush_all();
11900 if(current->mm != current->parent->mm)
11901 protect_memory(uml_reserved, high_physmem - uml_reserved, 1,
11903 - task_protections((unsigned long) current->thread_info);
11905 - current->thread.prev_sched = NULL;
11906 + task_protections((unsigned long) current_thread);
11908 free_page(current->thread.temp_stack);
11909 + local_irq_disable();
11910 change_sig(SIGUSR1, 0);
11911 set_user_mode(current);
11914 -static int sigusr1 = SIGUSR1;
11916 int fork_tramp(void *stack)
11918 - int sig = sigusr1;
11920 local_irq_disable();
11921 + arch_init_thread();
11922 init_new_thread_stack(stack, finish_fork_handler);
11924 - kill(os_getpid(), sig);
11925 + os_usr1_process(os_getpid());
11929 @@ -213,8 +234,8 @@
11932 err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1);
11934 - printk("copy_thread : pipe failed, errno = %d\n", -err);
11936 + printk("copy_thread : pipe failed, err = %d\n", -err);
11940 @@ -377,8 +398,8 @@
11942 pages = (1 << CONFIG_KERNEL_STACK_ORDER);
11944 - start = (unsigned long) current->thread_info + PAGE_SIZE;
11945 - end = (unsigned long) current + PAGE_SIZE * pages;
11946 + start = (unsigned long) current_thread + PAGE_SIZE;
11947 + end = (unsigned long) current_thread + PAGE_SIZE * pages;
11948 protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1);
11949 protect_memory(end, high_physmem - end, 1, w, 1, 1);
11951 @@ -454,8 +475,9 @@
11953 init_task.thread.mode.tt.extern_pid = pid;
11954 err = os_pipe(init_task.thread.mode.tt.switch_pipe, 1, 1);
11955 - if(err) panic("Can't create switch pipe for init_task, errno = %d",
11958 + panic("Can't create switch pipe for init_task, errno = %d",
11962 int singlestepping_tt(void *t)
11963 diff -Naur a/arch/um/kernel/tt/ptproxy/Makefile b/arch/um/kernel/tt/ptproxy/Makefile
11964 --- a/arch/um/kernel/tt/ptproxy/Makefile 2004-02-11 12:15:11.000000000 -0500
11965 +++ b/arch/um/kernel/tt/ptproxy/Makefile 2004-02-11 12:26:57.000000000 -0500
11968 $(USER_OBJS) : %.o: %.c
11969 $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
11972 diff -Naur a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c
11973 --- a/arch/um/kernel/tt/ptproxy/proxy.c 2004-02-11 12:15:57.000000000 -0500
11974 +++ b/arch/um/kernel/tt/ptproxy/proxy.c 2004-02-11 12:27:50.000000000 -0500
11976 #include <unistd.h>
11977 #include <signal.h>
11978 #include <string.h>
11979 -#include <fcntl.h>
11980 #include <termios.h>
11981 #include <sys/wait.h>
11982 #include <sys/types.h>
11983 @@ -293,10 +292,10 @@
11986 char gdb_init_string[] =
11990 -handle SIGWINCH nostop noprint pass
11994 +handle SIGWINCH nostop noprint pass \n\
11997 int start_debugger(char *prog, int startup, int stop, int *fd_out)
11998 @@ -304,7 +303,8 @@
12001 slave = open_gdb_chan();
12002 - if((child = fork()) == 0){
12005 char *tempname = NULL;
12008 @@ -327,18 +327,19 @@
12012 - if((fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0)) < 0){
12013 - printk("start_debugger : make_tempfile failed, errno = %d\n",
12015 + fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0);
12017 + printk("start_debugger : make_tempfile failed,"
12018 + "err = %d\n", -fd);
12021 - write(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
12022 + os_write_file(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
12025 - write(fd, "b start_kernel\n",
12026 + os_write_file(fd, "b start_kernel\n",
12027 strlen("b start_kernel\n"));
12029 - write(fd, "c\n", strlen("c\n"));
12030 + os_write_file(fd, "c\n", strlen("c\n"));
12032 if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
12033 printk("start_debugger : PTRACE_TRACEME failed, "
12034 diff -Naur a/arch/um/kernel/tt/ptproxy/sysdep.c b/arch/um/kernel/tt/ptproxy/sysdep.c
12035 --- a/arch/um/kernel/tt/ptproxy/sysdep.c 2004-02-11 12:16:27.000000000 -0500
12036 +++ b/arch/um/kernel/tt/ptproxy/sysdep.c 2004-02-11 12:28:24.000000000 -0500
12038 #include <string.h>
12039 #include <stdlib.h>
12040 #include <signal.h>
12041 +#include <errno.h>
12042 #include <sys/types.h>
12043 #include <sys/ptrace.h>
12044 #include <asm/ptrace.h>
12045 diff -Naur a/arch/um/kernel/tt/ptproxy/wait.c b/arch/um/kernel/tt/ptproxy/wait.c
12046 --- a/arch/um/kernel/tt/ptproxy/wait.c 2004-02-11 12:16:37.000000000 -0500
12047 +++ b/arch/um/kernel/tt/ptproxy/wait.c 2004-02-11 12:28:37.000000000 -0500
12048 @@ -56,21 +56,23 @@
12049 int real_wait_return(struct debugger *debugger)
12055 pid = debugger->pid;
12057 ip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
12058 - ip = IP_RESTART_SYSCALL(ip);
12059 - err = ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip);
12060 + IP_RESTART_SYSCALL(ip);
12062 if(ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip) < 0)
12063 tracer_panic("real_wait_return : Failed to restart system "
12064 - "call, errno = %d\n");
12065 + "call, errno = %d\n", errno);
12067 if((ptrace(PTRACE_SYSCALL, debugger->pid, 0, SIGCHLD) < 0) ||
12068 (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
12069 (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
12070 debugger_normal_return(debugger, -1))
12071 tracer_panic("real_wait_return : gdb failed to wait, "
12073 + "errno = %d\n", errno);
12077 diff -Naur a/arch/um/kernel/tt/syscall_kern.c b/arch/um/kernel/tt/syscall_kern.c
12078 --- a/arch/um/kernel/tt/syscall_kern.c 2004-02-11 12:14:00.000000000 -0500
12079 +++ b/arch/um/kernel/tt/syscall_kern.c 2004-02-11 12:25:40.000000000 -0500
12082 - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
12083 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
12084 * Licensed under the GPL
12087 diff -Naur a/arch/um/kernel/tt/sys-i386/Makefile b/arch/um/kernel/tt/sys-i386/Makefile
12088 --- a/arch/um/kernel/tt/sys-i386/Makefile 2004-02-11 12:15:17.000000000 -0500
12089 +++ b/arch/um/kernel/tt/sys-i386/Makefile 2004-02-11 12:27:05.000000000 -0500
12092 $(USER_OBJS) : %.o: %.c
12093 $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
12096 diff -Naur a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c
12097 --- a/arch/um/kernel/tt/tlb.c 2004-02-11 12:14:18.000000000 -0500
12098 +++ b/arch/um/kernel/tt/tlb.c 2004-02-11 12:26:01.000000000 -0500
12100 #include "asm/page.h"
12101 #include "asm/pgtable.h"
12102 #include "asm/uaccess.h"
12103 +#include "asm/tlbflush.h"
12104 #include "user_util.h"
12105 #include "mem_user.h"
12107 diff -Naur a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
12108 --- a/arch/um/kernel/tt/tracer.c 2004-02-11 12:14:16.000000000 -0500
12109 +++ b/arch/um/kernel/tt/tracer.c 2004-02-11 12:25:59.000000000 -0500
12110 @@ -39,16 +39,17 @@
12113 register_winch_irq(tracer_winch[0], fd, -1, data);
12118 static void tracer_winch_handler(int sig)
12123 - if(write(tracer_winch[1], &c, sizeof(c)) != sizeof(c))
12124 - printk("tracer_winch_handler - write failed, errno = %d\n",
12126 + n = os_write_file(tracer_winch[1], &c, sizeof(c));
12127 + if(n != sizeof(c))
12128 + printk("tracer_winch_handler - write failed, err = %d\n", -n);
12131 /* Called only by the tracing thread during initialization */
12135 err = os_pipe(tracer_winch, 1, 1);
12137 - printk("setup_tracer_winch : os_pipe failed, errno = %d\n",
12140 + printk("setup_tracer_winch : os_pipe failed, err = %d\n", -err);
12143 signal(SIGWINCH, tracer_winch_handler);
12144 @@ -130,8 +130,8 @@
12146 if(ptrace(PTRACE_CONT, pid, 0, sig) < 0)
12147 tracer_panic("sleeping_process_signal : Failed to "
12148 - "continue pid %d, errno = %d\n", pid,
12150 + "continue pid %d, signal = %d, "
12151 + "errno = %d\n", pid, sig, errno);
12154 /* This happens when the debugger (e.g. strace) is doing system call
12155 @@ -145,7 +145,7 @@
12156 if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
12157 tracer_panic("sleeping_process_signal : Failed to "
12158 "PTRACE_SYSCALL pid %d, errno = %d\n",
12164 @@ -218,7 +218,7 @@
12165 err = attach(debugger_parent);
12167 printf("Failed to attach debugger parent %d, "
12168 - "errno = %d\n", debugger_parent, err);
12169 + "errno = %d\n", debugger_parent, -err);
12170 debugger_parent = -1;
12173 @@ -233,7 +233,8 @@
12175 set_cmdline("(tracing thread)");
12177 - if((pid = waitpid(-1, &status, WUNTRACED)) <= 0){
12178 + pid = waitpid(-1, &status, WUNTRACED);
12180 if(errno != ECHILD){
12181 printf("wait failed - errno = %d\n", errno);
12183 @@ -401,7 +402,7 @@
12185 if(!strcmp(line, "go")) debug_stop = 0;
12186 else if(!strcmp(line, "parent")) debug_parent = 1;
12187 - else printk("Unknown debug option : '%s'\n", line);
12188 + else printf("Unknown debug option : '%s'\n", line);
12192 diff -Naur a/arch/um/kernel/tt/uaccess.c b/arch/um/kernel/tt/uaccess.c
12193 --- a/arch/um/kernel/tt/uaccess.c 1969-12-31 19:00:00.000000000 -0500
12194 +++ b/arch/um/kernel/tt/uaccess.c 2004-02-11 12:25:43.000000000 -0500
12197 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
12198 + * Licensed under the GPL
12201 +#include "linux/sched.h"
12202 +#include "asm/uaccess.h"
12204 +int copy_from_user_tt(void *to, const void *from, int n)
12206 + if(!access_ok_tt(VERIFY_READ, from, n))
12209 + return(__do_copy_from_user(to, from, n, ¤t->thread.fault_addr,
12210 + ¤t->thread.fault_catcher));
12213 +int copy_to_user_tt(void *to, const void *from, int n)
12215 + if(!access_ok_tt(VERIFY_WRITE, to, n))
12218 + return(__do_copy_to_user(to, from, n, ¤t->thread.fault_addr,
12219 + ¤t->thread.fault_catcher));
12222 +int strncpy_from_user_tt(char *dst, const char *src, int count)
12226 + if(!access_ok_tt(VERIFY_READ, src, 1))
12229 + n = __do_strncpy_from_user(dst, src, count,
12230 + ¤t->thread.fault_addr,
12231 + ¤t->thread.fault_catcher);
12232 + if(n < 0) return(-EFAULT);
12236 +int __clear_user_tt(void *mem, int len)
12238 + return(__do_clear_user(mem, len,
12239 + ¤t->thread.fault_addr,
12240 + ¤t->thread.fault_catcher));
12243 +int clear_user_tt(void *mem, int len)
12245 + if(!access_ok_tt(VERIFY_WRITE, mem, len))
12248 + return(__do_clear_user(mem, len, ¤t->thread.fault_addr,
12249 + ¤t->thread.fault_catcher));
12252 +int strnlen_user_tt(const void *str, int len)
12254 + return(__do_strnlen_user(str, len,
12255 + ¤t->thread.fault_addr,
12256 + ¤t->thread.fault_catcher));
12260 + * Overrides for Emacs so that we follow Linus's tabbing style.
12261 + * Emacs will notice this stuff at the end of the file and automatically
12262 + * adjust the settings for this buffer only. This must remain at the end
12264 + * ---------------------------------------------------------------------------
12265 + * Local variables:
12266 + * c-file-style: "linux"
12269 diff -Naur a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c
12270 --- a/arch/um/kernel/tt/uaccess_user.c 2004-02-11 12:14:38.000000000 -0500
12271 +++ b/arch/um/kernel/tt/uaccess_user.c 2004-02-11 12:26:42.000000000 -0500
12273 #include <string.h>
12274 #include "user_util.h"
12275 #include "uml_uaccess.h"
12277 +#include "kern_util.h"
12279 int __do_copy_from_user(void *to, const void *from, int n,
12280 void **fault_addr, void **fault_catcher)
12282 + struct tt_regs save = TASK_REGS(get_current())->tt;
12283 unsigned long fault;
12286 fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
12287 __do_copy, &faulted);
12288 + TASK_REGS(get_current())->tt = save;
12290 if(!faulted) return(0);
12291 else return(n - (fault - (unsigned long) from));
12293 @@ -29,11 +34,14 @@
12294 int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
12295 void **fault_addr, void **fault_catcher)
12297 + struct tt_regs save = TASK_REGS(get_current())->tt;
12298 unsigned long fault;
12301 fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
12302 __do_strncpy, &faulted);
12303 + TASK_REGS(get_current())->tt = save;
12305 if(!faulted) return(strlen(dst));
12308 @@ -46,11 +54,14 @@
12309 int __do_clear_user(void *mem, unsigned long len,
12310 void **fault_addr, void **fault_catcher)
12312 + struct tt_regs save = TASK_REGS(get_current())->tt;
12313 unsigned long fault;
12316 fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
12317 __do_clear, &faulted);
12318 + TASK_REGS(get_current())->tt = save;
12320 if(!faulted) return(0);
12321 else return(len - (fault - (unsigned long) mem));
12323 @@ -58,19 +69,20 @@
12324 int __do_strnlen_user(const char *str, unsigned long n,
12325 void **fault_addr, void **fault_catcher)
12327 + struct tt_regs save = TASK_REGS(get_current())->tt;
12329 unsigned long *faddrp = (unsigned long *)fault_addr;
12332 *fault_catcher = &jbuf;
12333 - if(setjmp(jbuf) == 0){
12334 + if(sigsetjmp(jbuf, 1) == 0)
12335 ret = strlen(str) + 1;
12338 - ret = *faddrp - (unsigned long) str;
12340 + else ret = *faddrp - (unsigned long) str;
12342 *fault_addr = NULL;
12343 *fault_catcher = NULL;
12345 + TASK_REGS(get_current())->tt = save;
12349 diff -Naur a/arch/um/kernel/tt/unmap.c b/arch/um/kernel/tt/unmap.c
12350 --- a/arch/um/kernel/tt/unmap.c 2004-02-11 12:16:26.000000000 -0500
12351 +++ b/arch/um/kernel/tt/unmap.c 2004-02-11 12:28:22.000000000 -0500
12353 * Licensed under the GPL
12356 -#include <stdio.h>
12357 -#include <errno.h>
12358 #include <sys/mman.h>
12361 int switcheroo(int fd, int prot, void *from, void *to, int size)
12363 diff -Naur a/arch/um/kernel/tty_log.c b/arch/um/kernel/tty_log.c
12364 --- a/arch/um/kernel/tty_log.c 2004-02-11 12:15:58.000000000 -0500
12365 +++ b/arch/um/kernel/tty_log.c 2004-02-11 12:27:51.000000000 -0500
12368 #include <stdlib.h>
12369 #include <unistd.h>
12370 -#include <fcntl.h>
12371 #include <sys/time.h>
12374 +#include "kern_util.h"
12377 #define TTY_LOG_DIR "./"
12378 @@ -24,29 +24,40 @@
12379 #define TTY_LOG_OPEN 1
12380 #define TTY_LOG_CLOSE 2
12381 #define TTY_LOG_WRITE 3
12382 +#define TTY_LOG_EXEC 4
12384 +#define TTY_READ 1
12385 +#define TTY_WRITE 2
12387 struct tty_log_buf {
12392 + unsigned long sec;
12393 + unsigned long usec;
12396 -int open_tty_log(void *tty)
12397 +int open_tty_log(void *tty, void *current_tty)
12400 struct tty_log_buf data;
12401 char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
12404 + gettimeofday(&tv, NULL);
12405 if(tty_log_fd != -1){
12406 - data = ((struct tty_log_buf) { what : TTY_LOG_OPEN,
12407 - tty : (unsigned long) tty,
12409 - write(tty_log_fd, &data, sizeof(data));
12410 + data = ((struct tty_log_buf) { .what = TTY_LOG_OPEN,
12411 + .tty = (unsigned long) tty,
12412 + .len = sizeof(current_tty),
12414 + .sec = tv.tv_sec,
12415 + .usec = tv.tv_usec } );
12416 + os_write_file(tty_log_fd, &data, sizeof(data));
12417 + os_write_file(tty_log_fd, ¤t_tty, data.len);
12418 return(tty_log_fd);
12421 - gettimeofday(&tv, NULL);
12422 sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec,
12423 (unsigned int) tv.tv_usec);
12425 @@ -62,30 +73,117 @@
12426 void close_tty_log(int fd, void *tty)
12428 struct tty_log_buf data;
12429 + struct timeval tv;
12431 if(tty_log_fd != -1){
12432 - data = ((struct tty_log_buf) { what : TTY_LOG_CLOSE,
12433 - tty : (unsigned long) tty,
12435 - write(tty_log_fd, &data, sizeof(data));
12436 + gettimeofday(&tv, NULL);
12437 + data = ((struct tty_log_buf) { .what = TTY_LOG_CLOSE,
12438 + .tty = (unsigned long) tty,
12441 + .sec = tv.tv_sec,
12442 + .usec = tv.tv_usec } );
12443 + os_write_file(tty_log_fd, &data, sizeof(data));
12447 + os_close_file(fd);
12450 -int write_tty_log(int fd, char *buf, int len, void *tty)
12451 +static int log_chunk(int fd, const char *buf, int len)
12453 + int total = 0, try, missed, n;
12457 + try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
12458 + missed = copy_from_user_proc(chunk, (char *) buf, try);
12460 + n = os_write_file(fd, chunk, try);
12477 +int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
12479 + struct timeval tv;
12480 struct tty_log_buf data;
12483 if(fd == tty_log_fd){
12484 - data = ((struct tty_log_buf) { what : TTY_LOG_WRITE,
12485 - tty : (unsigned long) tty,
12487 - write(tty_log_fd, &data, sizeof(data));
12488 + gettimeofday(&tv, NULL);
12489 + direction = is_read ? TTY_READ : TTY_WRITE;
12490 + data = ((struct tty_log_buf) { .what = TTY_LOG_WRITE,
12491 + .tty = (unsigned long) tty,
12493 + .direction = direction,
12494 + .sec = tv.tv_sec,
12495 + .usec = tv.tv_usec } );
12496 + os_write_file(tty_log_fd, &data, sizeof(data));
12498 - return(write(fd, buf, len));
12500 + return(log_chunk(fd, buf, len));
12503 +void log_exec(char **argv, void *tty)
12505 + struct timeval tv;
12506 + struct tty_log_buf data;
12510 + if(tty_log_fd == -1) return;
12512 + gettimeofday(&tv, NULL);
12515 + for(ptr = argv; ; ptr++){
12516 + if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
12518 + if(arg == NULL) break;
12519 + len += strlen_user_proc(arg);
12522 + data = ((struct tty_log_buf) { .what = TTY_LOG_EXEC,
12523 + .tty = (unsigned long) tty,
12526 + .sec = tv.tv_sec,
12527 + .usec = tv.tv_usec } );
12528 + os_write_file(tty_log_fd, &data, sizeof(data));
12530 + for(ptr = argv; ; ptr++){
12531 + if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
12533 + if(arg == NULL) break;
12534 + log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
12538 +extern void register_tty_logger(int (*opener)(void *, void *),
12539 + int (*writer)(int, const char *, int,
12541 + void (*closer)(int, void *));
12543 +static int register_logger(void)
12545 + register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
12549 +__uml_initcall(register_logger);
12551 static int __init set_tty_log_dir(char *name, int *add)
12553 tty_log_dir = name;
12554 @@ -104,7 +202,7 @@
12556 tty_log_fd = strtoul(name, &end, 0);
12557 if((*end != '\0') || (end == name)){
12558 - printk("set_tty_log_fd - strtoul failed on '%s'\n", name);
12559 + printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
12563 diff -Naur a/arch/um/kernel/uaccess_user.c b/arch/um/kernel/uaccess_user.c
12564 --- a/arch/um/kernel/uaccess_user.c 2004-02-11 12:16:09.000000000 -0500
12565 +++ b/arch/um/kernel/uaccess_user.c 2004-02-11 12:28:20.000000000 -0500
12569 *fault_catcher = &jbuf;
12570 - if(setjmp(jbuf) == 0){
12571 + if(sigsetjmp(jbuf, 1) == 0){
12572 (*op)(to, from, n);
12575 diff -Naur a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
12576 --- a/arch/um/kernel/um_arch.c 2004-02-11 12:16:29.000000000 -0500
12577 +++ b/arch/um/kernel/um_arch.c 2004-02-11 12:28:28.000000000 -0500
12578 @@ -38,13 +38,18 @@
12579 #include "mode_kern.h"
12582 -#define DEFAULT_COMMAND_LINE "root=6200"
12583 +#define DEFAULT_COMMAND_LINE "root=98:0"
12585 struct cpuinfo_um boot_cpu_data = {
12586 .loops_per_jiffy = 0,
12587 .ipi_pipe = { -1, -1 }
12590 +/* Placeholder to make UML link until the vsyscall stuff is actually
12593 +void *__kernel_vsyscall;
12595 unsigned long thread_saved_pc(struct task_struct *task)
12597 return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
12598 @@ -53,18 +58,22 @@
12600 static int show_cpuinfo(struct seq_file *m, void *v)
12605 - index = (struct cpuinfo_um *)v - cpu_data;
12607 + index = (struct cpuinfo_um *) v - cpu_data;
12608 if (!cpu_online(index))
12612 - seq_printf(m, "bogomips\t: %lu.%02lu\n",
12613 + seq_printf(m, "processor\t: %d\n", index);
12614 + seq_printf(m, "vendor_id\t: User Mode Linux\n");
12615 + seq_printf(m, "model name\t: UML\n");
12616 + seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas"));
12617 + seq_printf(m, "host\t\t: %s\n", host_info);
12618 + seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
12619 loops_per_jiffy/(500000/HZ),
12620 (loops_per_jiffy/(5000/HZ)) % 100);
12621 - seq_printf(m, "host\t\t: %s\n", host_info);
12625 @@ -134,12 +143,12 @@
12627 snprintf(argv1_begin,
12628 (argv1_end - argv1_begin) * sizeof(*ptr),
12631 ptr = &argv1_begin[strlen(argv1_begin)];
12633 else ptr = argv1_begin;
12635 - snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), " [%s]", cmd);
12636 + snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
12637 memset(argv1_begin + strlen(argv1_begin), '\0',
12638 argv1_end - argv1_begin - strlen(argv1_begin));
12640 @@ -179,7 +188,7 @@
12641 static int __init uml_ncpus_setup(char *line, int *add)
12643 if (!sscanf(line, "%d", &ncpus)) {
12644 - printk("Couldn't parse [%s]\n", line);
12645 + printf("Couldn't parse [%s]\n", line);
12649 @@ -210,7 +219,7 @@
12651 static int __init mode_tt_setup(char *line, int *add)
12653 - printk("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
12654 + printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
12658 @@ -221,7 +230,7 @@
12660 static int __init mode_tt_setup(char *line, int *add)
12662 - printk("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
12663 + printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
12667 @@ -291,7 +300,7 @@
12669 /* Set during early boot */
12670 unsigned long brk_start;
12671 -static struct vm_reserved kernel_vm_reserved;
12672 +unsigned long end_iomem;
12674 #define MIN_VMALLOC (32 * 1024 * 1024)
12676 @@ -299,7 +308,7 @@
12678 unsigned long avail;
12679 unsigned long virtmem_size, max_physmem;
12680 - unsigned int i, add, err;
12681 + unsigned int i, add;
12683 for (i = 1; i < argc; i++){
12684 if((i == 1) && (argv[i][0] == ' ')) continue;
12685 @@ -328,12 +337,16 @@
12686 argv1_end = &argv[1][strlen(argv[1])];
12689 - set_usable_vm(uml_physmem, get_kmem_end());
12692 - max_physmem = get_kmem_end() - uml_physmem - MIN_VMALLOC;
12693 - if(physmem_size > max_physmem){
12694 - highmem = physmem_size - max_physmem;
12695 + iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
12696 + max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC;
12698 + /* Zones have to begin on a 1 << MAX_ORDER page boundary,
12699 + * so this makes sure that's true for highmem
12701 + max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1);
12702 + if(physmem_size + iomem_size > max_physmem){
12703 + highmem = physmem_size + iomem_size - max_physmem;
12704 physmem_size -= highmem;
12705 #ifndef CONFIG_HIGHMEM
12707 @@ -343,11 +356,19 @@
12710 high_physmem = uml_physmem + physmem_size;
12711 - high_memory = (void *) high_physmem;
12712 + end_iomem = high_physmem + iomem_size;
12713 + high_memory = (void *) end_iomem;
12715 start_vm = VMALLOC_START;
12717 - setup_physmem(uml_physmem, uml_reserved, physmem_size);
12718 + setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
12719 + if(init_maps(physmem_size, iomem_size, highmem)){
12720 + printf("Failed to allocate mem_map for %ld bytes of physical "
12721 + "memory and %ld bytes of highmem\n", physmem_size,
12726 virtmem_size = physmem_size;
12727 avail = get_kmem_end() - start_vm;
12728 if(physmem_size > avail) virtmem_size = avail;
12729 @@ -357,18 +378,13 @@
12730 printf("Kernel virtual memory size shrunk to %ld bytes\n",
12733 - err = reserve_vm(high_physmem, end_vm, &kernel_vm_reserved);
12735 - printf("Failed to reserve VM area for kernel VM\n");
12741 init_task.thread.kernel_stack = (unsigned long) &init_thread_info +
12744 task_protections((unsigned long) &init_thread_info);
12745 + os_flush_stdout();
12747 return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
12749 @@ -377,7 +393,7 @@
12752 #ifdef CONFIG_MAGIC_SYSRQ
12753 - handle_sysrq('p', ¤t->thread.regs, NULL, NULL);
12754 + handle_sysrq('p', ¤t->thread.regs, NULL);
12758 @@ -403,6 +419,11 @@
12765 +void apply_alternatives(void *start, void *end)
12770 diff -Naur a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c
12771 --- a/arch/um/kernel/umid.c 2004-02-11 12:16:43.000000000 -0500
12772 +++ b/arch/um/kernel/umid.c 2004-02-11 12:28:42.000000000 -0500
12776 #include <unistd.h>
12777 -#include <fcntl.h>
12779 #include <string.h>
12780 #include <stdlib.h>
12781 @@ -33,18 +32,19 @@
12782 static int umid_is_random = 1;
12783 static int umid_inited = 0;
12785 -static int make_umid(void);
12786 +static int make_umid(int (*printer)(const char *fmt, ...));
12788 -static int __init set_umid(char *name, int is_random)
12789 +static int __init set_umid(char *name, int is_random,
12790 + int (*printer)(const char *fmt, ...))
12793 - printk("Unique machine name can't be set twice\n");
12794 + (*printer)("Unique machine name can't be set twice\n");
12798 if(strlen(name) > UMID_LEN - 1)
12799 - printk("Unique machine name is being truncated to %s "
12800 - "characters\n", UMID_LEN);
12801 + (*printer)("Unique machine name is being truncated to %s "
12802 + "characters\n", UMID_LEN);
12803 strlcpy(umid, name, sizeof(umid));
12805 umid_is_random = is_random;
12808 static int __init set_umid_arg(char *name, int *add)
12810 - return(set_umid(name, 0));
12811 + return(set_umid(name, 0, printf));
12814 __uml_setup("umid=", set_umid_arg,
12819 - if(!umid_inited && make_umid()) return(-1);
12820 + if(!umid_inited && make_umid(printk)) return(-1);
12822 n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
12824 @@ -85,22 +85,23 @@
12826 char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
12827 char pid[sizeof("nnnnn\0")];
12831 if(umid_file_name("pid", file, sizeof(file))) return 0;
12833 fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))),
12836 - printk("Open of machine pid file \"%s\" failed - "
12837 - "errno = %d\n", file, -fd);
12838 + printf("Open of machine pid file \"%s\" failed - "
12839 + "err = %d\n", file, -fd);
12843 sprintf(pid, "%d\n", os_getpid());
12844 - if(write(fd, pid, strlen(pid)) != strlen(pid))
12845 - printk("Write of pid file failed - errno = %d\n", errno);
12847 + n = os_write_file(fd, pid, strlen(pid));
12848 + if(n != strlen(pid))
12849 + printf("Write of pid file failed - err = %d\n", -n);
12850 + os_close_file(fd);
12854 @@ -111,7 +112,8 @@
12858 - if((directory = opendir(dir)) == NULL){
12859 + directory = opendir(dir);
12860 + if(directory == NULL){
12861 printk("actually_do_remove : couldn't open directory '%s', "
12862 "errno = %d\n", dir, errno);
12864 @@ -160,22 +162,24 @@
12866 char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
12867 char pid[sizeof("nnnnn\0")], *end;
12869 + int dead, fd, p, n;
12871 sprintf(file, "%s/pid", dir);
12873 - if((fd = os_open_file(file, of_read(OPENFLAGS()), 0)) < 0){
12874 + fd = os_open_file(file, of_read(OPENFLAGS()), 0);
12877 printk("not_dead_yet : couldn't open pid file '%s', "
12878 - "errno = %d\n", file, -fd);
12879 + "err = %d\n", file, -fd);
12885 - if(read(fd, pid, sizeof(pid)) < 0){
12886 + n = os_read_file(fd, pid, sizeof(pid));
12888 printk("not_dead_yet : couldn't read pid file '%s', "
12889 - "errno = %d\n", file, errno);
12890 + "err = %d\n", file, -n);
12893 p = strtoul(pid, &end, 0);
12894 @@ -197,7 +201,7 @@
12895 if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
12896 uml_dir = malloc(strlen(name) + 1);
12897 if(uml_dir == NULL){
12898 - printk("Failed to malloc uml_dir - error = %d\n",
12899 + printf("Failed to malloc uml_dir - error = %d\n",
12903 @@ -217,7 +221,7 @@
12904 char *home = getenv("HOME");
12907 - printk("make_uml_dir : no value in environment for "
12908 + printf("make_uml_dir : no value in environment for "
12912 @@ -232,57 +236,59 @@
12913 dir[len + 1] = '\0';
12916 - if((uml_dir = malloc(strlen(dir) + 1)) == NULL){
12917 + uml_dir = malloc(strlen(dir) + 1);
12918 + if(uml_dir == NULL){
12919 printf("make_uml_dir : malloc failed, errno = %d\n", errno);
12922 strcpy(uml_dir, dir);
12924 if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
12925 - printk("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
12926 + printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
12932 -static int __init make_umid(void)
12933 +static int __init make_umid(int (*printer)(const char *fmt, ...))
12936 char tmp[strlen(uml_dir) + UMID_LEN + 1];
12938 strlcpy(tmp, uml_dir, sizeof(tmp));
12941 + if(!umid_inited){
12942 strcat(tmp, "XXXXXX");
12945 - printk("make_umid - mkstemp failed, errno = %d\n",
12947 + (*printer)("make_umid - mkstemp failed, errno = %d\n",
12953 + os_close_file(fd);
12954 /* There's a nice tiny little race between this unlink and
12955 * the mkdir below. It'd be nice if there were a mkstemp
12959 - set_umid(&tmp[strlen(uml_dir)], 1);
12960 + set_umid(&tmp[strlen(uml_dir)], 1, printer);
12963 sprintf(tmp, "%s%s", uml_dir, umid);
12965 - if((err = mkdir(tmp, 0777)) < 0){
12966 + err = mkdir(tmp, 0777);
12968 if(errno == EEXIST){
12969 if(not_dead_yet(tmp)){
12970 - printk("umid '%s' is in use\n", umid);
12971 + (*printer)("umid '%s' is in use\n", umid);
12974 err = mkdir(tmp, 0777);
12978 - printk("Failed to create %s - errno = %d\n", umid, errno);
12979 + (*printer)("Failed to create %s - errno = %d\n", umid, errno);
12983 @@ -295,7 +301,13 @@
12986 __uml_postsetup(make_uml_dir);
12987 -__uml_postsetup(make_umid);
12989 +static int __init make_umid_setup(void)
12991 + return(make_umid(printf));
12994 +__uml_postsetup(make_umid_setup);
12995 __uml_postsetup(create_pid_file);
12998 diff -Naur a/arch/um/kernel/user_syms.c b/arch/um/kernel/user_syms.c
12999 --- a/arch/um/kernel/user_syms.c 2004-02-11 12:16:42.000000000 -0500
13000 +++ b/arch/um/kernel/user_syms.c 2004-02-11 12:28:41.000000000 -0500
13003 #include <unistd.h>
13004 -#include <fcntl.h>
13005 #include <dirent.h>
13006 +#include <fcntl.h>
13009 #include <string.h>
13010 @@ -16,46 +16,61 @@
13011 * since this includes various user-level headers.
13014 -struct module_symbol
13015 +/* Had to update this: this changed in late 2.5 to add CRC and other beasts
13016 + * and was never updated here- 13 Dec 2003-Blaisorblade
13019 +/* v850 toolchain uses a `_' prefix for all user symbols */
13020 +#ifndef MODULE_SYMBOL_PREFIX
13021 +#define MODULE_SYMBOL_PREFIX ""
13024 +struct kernel_symbol
13026 unsigned long value;
13030 -/* Indirect stringification. */
13032 -#define __MODULE_STRING_1(x) #x
13033 -#define __MODULE_STRING(x) __MODULE_STRING_1(x)
13035 -#if !defined(__AUTOCONF_INCLUDED__)
13037 -#define __EXPORT_SYMBOL(sym,str) error config_must_be_included_before_module
13038 -#define EXPORT_SYMBOL(var) error config_must_be_included_before_module
13039 -#define EXPORT_SYMBOL_NOVERS(var) error config_must_be_included_before_module
13041 -#elif !defined(UML_CONFIG_MODULES)
13042 +#if !defined(UML_CONFIG_MODULES)
13043 +#define EXPORT_SYMBOL(sym)
13044 +#define EXPORT_SYMBOL_GPL(sym)
13045 +#define EXPORT_SYMBOL_NOVERS(sym)
13047 +#else /*UML_CONFIG_MODULES*/
13048 +#ifndef __GENKSYMS__
13049 +#ifdef UML_CONFIG_MODVERSIONS
13050 +/* Mark the CRC weak since genksyms apparently decides not to
13051 + * generate a checksums for some symbols */
13052 +#define __CRC_SYMBOL(sym, sec) \
13053 + extern void *__crc_##sym __attribute__((weak)); \
13054 + static const unsigned long __kcrctab_##sym \
13055 + __attribute__((section("__kcrctab" sec), unused)) \
13056 + = (unsigned long) &__crc_##sym;
13058 +#define __CRC_SYMBOL(sym, sec)
13061 -#define __EXPORT_SYMBOL(sym,str)
13062 -#define EXPORT_SYMBOL(var)
13063 -#define EXPORT_SYMBOL_NOVERS(var)
13064 +/* For every exported symbol, place a struct in the __ksymtab section */
13065 +#define __EXPORT_SYMBOL(sym, sec) \
13066 + __CRC_SYMBOL(sym, sec) \
13067 + static const char __kstrtab_##sym[] \
13068 + __attribute__((section("__ksymtab_strings"))) \
13069 + = MODULE_SYMBOL_PREFIX #sym; \
13070 + static const struct kernel_symbol __ksymtab_##sym \
13071 + __attribute__((section("__ksymtab" sec), unused)) \
13072 + = { (unsigned long)&sym, __kstrtab_##sym }
13075 +#define EXPORT_SYMBOL(sym) \
13076 + __EXPORT_SYMBOL(sym, "")
13078 -#define __EXPORT_SYMBOL(sym, str) \
13079 -const char __kstrtab_##sym[] \
13080 -__attribute__((section(".kstrtab"))) = str; \
13081 -const struct module_symbol __ksymtab_##sym \
13082 -__attribute__((section("__ksymtab"))) = \
13083 -{ (unsigned long)&sym, __kstrtab_##sym }
13084 +#define EXPORT_SYMBOL_GPL(sym) \
13085 + __EXPORT_SYMBOL(sym, "_gpl")
13087 -#if defined(__MODVERSIONS__) || !defined(UML_CONFIG_MODVERSIONS)
13088 -#define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var))
13090 -#define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(__VERSIONED_SYMBOL(var)))
13093 -#define EXPORT_SYMBOL_NOVERS(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var))
13095 +/* We don't mangle the actual symbol anymore, so no need for
13096 + * special casing EXPORT_SYMBOL_NOVERS. FIXME: Deprecated */
13097 +#define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym)
13100 EXPORT_SYMBOL(__errno_location);
13101 @@ -109,5 +124,18 @@
13103 EXPORT_SYMBOL(memset);
13104 EXPORT_SYMBOL(strstr);
13105 +EXPORT_SYMBOL(printf);
13106 +EXPORT_SYMBOL(strlen);
13108 EXPORT_SYMBOL(find_iomem);
13111 + * Overrides for Emacs so that we follow Linus's tabbing style.
13112 + * Emacs will notice this stuff at the end of the file and automatically
13113 + * adjust the settings for this buffer only. This must remain at the end
13115 + * ---------------------------------------------------------------------------
13116 + * Local variables:
13117 + * c-file-style: "linux"
13120 diff -Naur a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c
13121 --- a/arch/um/kernel/user_util.c 2004-02-11 12:14:27.000000000 -0500
13122 +++ b/arch/um/kernel/user_util.c 2004-02-11 12:26:09.000000000 -0500
13126 #include <stdlib.h>
13127 -#include <fcntl.h>
13128 #include <unistd.h>
13129 #include <limits.h>
13130 #include <sys/mman.h>
13135 - if(((ret = waitpid(pid, &status, WUNTRACED)) < 0) ||
13136 + ret = waitpid(pid, &status, WUNTRACED);
13138 !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
13140 if(errno == EINTR) continue;
13141 @@ -119,17 +119,6 @@
13145 -int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags)
13149 - pid = clone(fn, sp, flags, arg);
13150 - if(pid < 0) return(-1);
13151 - wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
13152 - ptrace(PTRACE_CONT, pid, 0, 0);
13156 int raw(int fd, int complain)
13159 diff -Naur a/arch/um/main.c b/arch/um/main.c
13160 --- a/arch/um/main.c 2004-02-11 12:16:28.000000000 -0500
13161 +++ b/arch/um/main.c 2004-02-11 12:28:27.000000000 -0500
13163 #include <stdlib.h>
13164 #include <string.h>
13165 #include <signal.h>
13166 +#include <errno.h>
13167 #include <sys/resource.h>
13168 #include <sys/mman.h>
13169 #include <sys/user.h>
13170 @@ -123,12 +124,14 @@
13174 - if((new_argv = malloc((argc + 1) * sizeof(char *))) == NULL){
13175 + new_argv = malloc((argc + 1) * sizeof(char *));
13176 + if(new_argv == NULL){
13177 perror("Mallocing argv");
13180 for(i=0;i<argc;i++){
13181 - if((new_argv[i] = strdup(argv[i])) == NULL){
13182 + new_argv[i] = strdup(argv[i]);
13183 + if(new_argv[i] == NULL){
13184 perror("Mallocing an arg");
13187 diff -Naur a/arch/um/Makefile b/arch/um/Makefile
13188 --- a/arch/um/Makefile 2004-02-11 12:15:58.000000000 -0500
13189 +++ b/arch/um/Makefile 2004-02-11 12:27:51.000000000 -0500
13190 @@ -22,17 +22,21 @@
13191 $(ARCH_DIR)/sys-$(SUBARCH)/
13193 # Have to precede the include because the included Makefiles reference them.
13194 -SYMLINK_HEADERS = include/asm-um/archparam.h include/asm-um/system.h \
13195 - include/asm-um/sigcontext.h include/asm-um/processor.h \
13196 - include/asm-um/ptrace.h include/asm-um/arch-signal.h
13197 +SYMLINK_HEADERS = archparam.h system.h sigcontext.h processor.h ptrace.h \
13198 + arch-signal.h module.h
13199 +SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
13201 ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
13202 $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
13204 GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
13206 -include $(ARCH_DIR)/Makefile-$(SUBARCH)
13207 -include $(ARCH_DIR)/Makefile-os-$(OS)
13208 +# This target adds dependencies to "prepare". They are defined in the included
13209 +# Makefiles (see Makefile-i386).
13211 +.PHONY: sys_prepare
13215 MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
13216 MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
13218 include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
13221 +include $(ARCH_DIR)/Makefile-$(SUBARCH)
13222 +include $(ARCH_DIR)/Makefile-os-$(OS)
13224 EXTRAVERSION := $(EXTRAVERSION)-1um
13226 ARCH_INCLUDE = -I$(ARCH_DIR)/include
13227 @@ -52,14 +59,20 @@
13229 CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
13230 -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
13232 + -Dsigprocmask=kernel_sigprocmask $(MODE_INCLUDE)
13234 LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
13236 +# These are needed for clean and mrproper, since in that case .config is not
13237 +# included; the values here are meaningless
13239 +CONFIG_NEST_LEVEL ?= 0
13240 +CONFIG_KERNEL_HALF_GIGS ?= 0
13242 SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
13244 ifeq ($(CONFIG_MODE_SKAS), y)
13245 -$(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
13246 +$(SYS_HEADERS) : $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
13249 include/linux/version.h: arch/$(ARCH)/Makefile
13250 @@ -98,17 +111,17 @@
13251 CONFIG_KERNEL_STACK_ORDER ?= 2
13252 STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
13254 -AFLAGS_vmlinux.lds.o = -U$(SUBARCH) \
13255 +AFLAGS_vmlinux.lds.o = $(shell echo -U$(SUBARCH) \
13256 -DSTART=$$(($(TOP_ADDR) - $(SIZE))) -DELF_ARCH=$(ELF_ARCH) \
13257 -DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE_TT) \
13258 - -DKERNEL_STACK_SIZE=$(STACK_SIZE)
13259 + -DKERNEL_STACK_SIZE=$(STACK_SIZE))
13261 -AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum
13262 +export AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum
13264 LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y)
13266 -$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE
13267 - $(call if_changed_dep,as_s_S)
13268 +#$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE
13269 +# $(call if_changed_dep,as_s_S)
13271 linux: vmlinux $(LD_SCRIPT-y)
13272 $(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \
13273 @@ -116,37 +129,47 @@
13275 USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
13276 USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS))
13277 +USER_CFLAGS := $(patsubst -Dsigprocmask=kernel_sigprocmask,,$(USER_CFLAGS))
13278 USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
13281 # To get a definition of F_SETSIG
13282 USER_CFLAGS += -D_GNU_SOURCE
13284 +# From main Makefile, these options are set after including the ARCH makefile.
13285 +# So copy them here.
13287 +ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
13288 +USER_CFLAGS += -Os
13290 +USER_CFLAGS += -O2
13293 +ifndef CONFIG_FRAME_POINTER
13294 +USER_CFLAGS += -fomit-frame-pointer
13297 +ifdef CONFIG_DEBUG_INFO
13301 CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/uml.lds.s \
13302 - $(ARCH_DIR)/dyn_link.ld.s $(GEN_HEADERS)
13303 + $(ARCH_DIR)/dyn_link.ld.s $(ARCH_DIR)/include/uml-config.h \
13306 -$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c
13307 - $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
13308 +MRPROPER_FILES += $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) \
13309 + $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS))
13311 +$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c sys_prepare
13312 + @ echo ' MAIN $@'
13313 + @ $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
13316 - for d in $(ARCH_SUBDIRS) $(ARCH_DIR)/util; \
13318 - $(MAKE) -C $$d archmrproper; \
13320 - rm -f $(CLEAN_FILES) $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) include/asm \
13321 - $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS))
13323 -archclean: sysclean
13324 - for d in $(ARCH_SUBDIRS) $(ARCH_DIR)/util; \
13326 - $(MAKE) -C $$d clean; \
13328 - find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
13329 - -o -name '*.gcov' \) -type f -print | xargs rm -f
13330 - rm -f linux x.i gmon.out $(ARCH_DIR)/link.ld $(GEN_HEADERS)
13334 - for d in $(ARCH_SUBDIRS); do $(MAKE) -C $$d fastdep; done
13336 + @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
13337 + -o -name '*.gcov' \) -type f -print | xargs rm -f
13339 $(SYMLINK_HEADERS):
13340 cd $(TOPDIR)/$(dir $@) ; \
13341 @@ -161,19 +184,26 @@
13343 cd $(ARCH_DIR) && ln -sf os-$(OS) os
13345 -$(ARCH_DIR)/include/uml-config.h :
13346 - sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@
13348 +define filechk_umlconfig
13349 + sed 's/ CONFIG/ UML_CONFIG/'
13352 +$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h
13353 + $(call filechk,umlconfig)
13355 +filechk_gen_header = $<
13357 $(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
13359 + $(call filechk,gen_header)
13361 $(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
13363 + $(call filechk,gen_header)
13365 -$(ARCH_DIR)/util/mk_task : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h \
13366 - $(ARCH_DIR)/util FORCE ;
13367 +$(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants : $(ARCH_DIR)/util \
13368 + sys_prepare FORCE ;
13370 $(ARCH_DIR)/util: FORCE
13371 - @$(call descend,$@,)
13372 + $(Q)$(MAKE) $(build)=$@
13374 -export SUBARCH USER_CFLAGS OS
13375 +export SUBARCH USER_CFLAGS OS
13376 diff -Naur a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
13377 --- a/arch/um/Makefile-i386 2004-02-11 12:16:28.000000000 -0500
13378 +++ b/arch/um/Makefile-i386 2004-02-11 12:28:27.000000000 -0500
13379 @@ -16,22 +16,27 @@
13381 SYS_HEADERS = $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
13383 +sys_prepare: $(SYS_DIR)/sc.h
13385 prepare: $(SYS_HEADERS)
13387 +filechk_$(SYS_DIR)/sc.h := $(SYS_UTIL_DIR)/mk_sc
13389 $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
13391 + $(call filechk,$@)
13393 +filechk_$(SYS_DIR)/thread.h := $(SYS_UTIL_DIR)/mk_thread
13395 $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
13397 + $(call filechk,$@)
13399 -$(SYS_UTIL_DIR)/mk_sc: FORCE ;
13400 - @$(call descend,$(SYS_UTIL_DIR),$@)
13401 +$(SYS_UTIL_DIR)/mk_sc: scripts/fixdep include/config/MARKER FORCE ;
13402 + $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
13404 -$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE ;
13405 - @$(call descend,$(SYS_UTIL_DIR),$@)
13406 +$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) sys_prepare FORCE ;
13407 + $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
13409 $(SYS_UTIL_DIR): include/asm FORCE
13410 - @$(call descend,$@,)
13411 + $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR)
13414 - rm -f $(SYS_HEADERS)
13415 +CLEAN_FILES += $(SYS_HEADERS)
13416 diff -Naur a/arch/um/Makefile-skas b/arch/um/Makefile-skas
13417 --- a/arch/um/Makefile-skas 2004-02-11 12:15:22.000000000 -0500
13418 +++ b/arch/um/Makefile-skas 2004-02-11 12:27:10.000000000 -0500
13420 LINK_SKAS = -Wl,-rpath,/lib
13421 LD_SCRIPT_SKAS = dyn.lds.s
13423 -GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
13424 +GEN_HEADERS += $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
13426 -$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h :
13427 - $(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h
13428 +$(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h :
13429 + $(Q)$(MAKE) $(build)=$(ARCH_DIR)/kernel/skas $@
13430 diff -Naur a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c
13431 --- a/arch/um/os-Linux/drivers/ethertap_kern.c 2004-02-11 12:14:17.000000000 -0500
13432 +++ b/arch/um/os-Linux/drivers/ethertap_kern.c 2004-02-11 12:26:00.000000000 -0500
13434 #include "linux/init.h"
13435 #include "linux/netdevice.h"
13436 #include "linux/etherdevice.h"
13437 -#include "linux/init.h"
13438 #include "net_kern.h"
13439 #include "net_user.h"
13441 diff -Naur a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
13442 --- a/arch/um/os-Linux/drivers/ethertap_user.c 2004-02-11 12:15:29.000000000 -0500
13443 +++ b/arch/um/os-Linux/drivers/ethertap_user.c 2004-02-11 12:27:17.000000000 -0500
13446 #include <unistd.h>
13447 #include <stddef.h>
13448 -#include <fcntl.h>
13449 #include <stdlib.h>
13450 #include <sys/errno.h>
13451 #include <sys/socket.h>
13452 @@ -42,13 +41,14 @@
13454 struct addr_change change;
13459 memcpy(change.addr, addr, sizeof(change.addr));
13460 memcpy(change.netmask, netmask, sizeof(change.netmask));
13461 - if(write(fd, &change, sizeof(change)) != sizeof(change))
13462 - printk("etap_change - request failed, errno = %d\n",
13464 + n = os_write_file(fd, &change, sizeof(change));
13465 + if(n != sizeof(change))
13466 + printk("etap_change - request failed, err = %d\n", -n);
13467 output = um_kmalloc(page_size());
13469 printk("etap_change : Failed to allocate output buffer\n");
13470 @@ -82,15 +82,15 @@
13471 struct etap_pre_exec_data *data = arg;
13473 dup2(data->control_remote, 1);
13474 - close(data->data_me);
13475 - close(data->control_me);
13476 + os_close_file(data->data_me);
13477 + os_close_file(data->control_me);
13480 static int etap_tramp(char *dev, char *gate, int control_me,
13481 int control_remote, int data_me, int data_remote)
13483 struct etap_pre_exec_data pe_data;
13484 - int pid, status, err;
13485 + int pid, status, err, n;
13486 char version_buf[sizeof("nnnnn\0")];
13487 char data_fd_buf[sizeof("nnnnnn\0")];
13488 char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
13489 @@ -114,21 +114,21 @@
13490 pe_data.data_me = data_me;
13491 pid = run_helper(etap_pre_exec, &pe_data, args, NULL);
13493 - if(pid < 0) err = errno;
13494 - close(data_remote);
13495 - close(control_remote);
13496 - if(read(control_me, &c, sizeof(c)) != sizeof(c)){
13497 - printk("etap_tramp : read of status failed, errno = %d\n",
13500 + if(pid < 0) err = pid;
13501 + os_close_file(data_remote);
13502 + os_close_file(control_remote);
13503 + n = os_read_file(control_me, &c, sizeof(c));
13504 + if(n != sizeof(c)){
13505 + printk("etap_tramp : read of status failed, err = %d\n", -n);
13509 printk("etap_tramp : uml_net failed\n");
13511 - if(waitpid(pid, &status, 0) < 0) err = errno;
13512 - else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)){
13514 + if(waitpid(pid, &status, 0) < 0)
13516 + else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
13517 printk("uml_net didn't exit with status 1\n");
13522 @@ -143,14 +143,14 @@
13523 if(err) return(err);
13525 err = os_pipe(data_fds, 0, 0);
13527 - printk("data os_pipe failed - errno = %d\n", -err);
13529 + printk("data os_pipe failed - err = %d\n", -err);
13533 err = os_pipe(control_fds, 1, 0);
13535 - printk("control os_pipe failed - errno = %d\n", -err);
13537 + printk("control os_pipe failed - err = %d\n", -err);
13541 @@ -167,9 +167,9 @@
13546 - printk("etap_tramp failed - errno = %d\n", err);
13549 + printk("etap_tramp failed - err = %d\n", -err);
13553 pri->data_fd = data_fds[0];
13554 @@ -183,11 +183,11 @@
13555 struct ethertap_data *pri = data;
13557 iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
13559 + os_close_file(fd);
13560 os_shutdown_socket(pri->data_fd, 1, 1);
13561 - close(pri->data_fd);
13562 + os_close_file(pri->data_fd);
13564 - close(pri->control_fd);
13565 + os_close_file(pri->control_fd);
13566 pri->control_fd = -1;
13569 diff -Naur a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
13570 --- a/arch/um/os-Linux/drivers/tuntap_user.c 2004-02-11 12:17:08.000000000 -0500
13571 +++ b/arch/um/os-Linux/drivers/tuntap_user.c 2004-02-11 12:29:13.000000000 -0500
13573 #include <stdlib.h>
13574 #include <unistd.h>
13576 -#include <fcntl.h>
13577 #include <sys/wait.h>
13578 #include <sys/socket.h>
13579 #include <sys/un.h>
13581 struct tuntap_pre_exec_data *data = arg;
13583 dup2(data->stdout, 1);
13584 - close(data->close_me);
13585 + os_close_file(data->close_me);
13588 static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
13591 if(pid < 0) return(-pid);
13594 + os_close_file(remote);
13596 msg.msg_name = NULL;
13597 msg.msg_namelen = 0;
13598 @@ -107,19 +106,19 @@
13600 printk("tuntap_open_tramp : recvmsg failed - errno = %d\n",
13605 waitpid(pid, NULL, 0);
13607 cmsg = CMSG_FIRSTHDR(&msg);
13609 printk("tuntap_open_tramp : didn't receive a message\n");
13613 if((cmsg->cmsg_level != SOL_SOCKET) ||
13614 (cmsg->cmsg_type != SCM_RIGHTS)){
13615 printk("tuntap_open_tramp : didn't receive a descriptor\n");
13619 *fd_out = ((int *) CMSG_DATA(cmsg))[0];
13621 @@ -133,27 +132,29 @@
13622 int err, fds[2], len, used;
13624 err = tap_open_common(pri->dev, pri->gate_addr);
13625 - if(err) return(err);
13629 if(pri->fixed_config){
13630 - if((pri->fd = open("/dev/net/tun", O_RDWR)) < 0){
13631 - printk("Failed to open /dev/net/tun, errno = %d\n",
13634 + pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0);
13636 + printk("Failed to open /dev/net/tun, err = %d\n",
13640 memset(&ifr, 0, sizeof(ifr));
13641 - ifr.ifr_flags = IFF_TAP;
13642 + ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
13643 strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
13644 if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
13645 - printk("TUNSETIFF failed, errno = %d", errno);
13647 + printk("TUNSETIFF failed, errno = %d\n", errno);
13648 + os_close_file(pri->fd);
13653 err = os_pipe(fds, 0, 0);
13655 - printk("tuntap_open : os_pipe failed - errno = %d\n",
13657 + printk("tuntap_open : os_pipe failed - err = %d\n",
13661 @@ -166,19 +167,19 @@
13662 fds[1], buffer, len, &used);
13666 - pri->dev_name = uml_strdup(buffer);
13667 - output += IFNAMSIZ;
13669 - free_output_buffer(buffer);
13674 + printk("%s", output);
13675 free_output_buffer(buffer);
13676 - printk("tuntap_open_tramp failed - errno = %d\n", err);
13678 + printk("tuntap_open_tramp failed - err = %d\n", -err);
13683 + pri->dev_name = uml_strdup(buffer);
13684 + output += IFNAMSIZ;
13685 + printk("%s", output);
13686 + free_output_buffer(buffer);
13688 + os_close_file(fds[0]);
13689 iter_addresses(pri->dev, open_addr, pri->dev_name);
13692 @@ -191,7 +192,7 @@
13694 if(!pri->fixed_config)
13695 iter_addresses(pri->dev, close_addr, pri->dev_name);
13697 + os_close_file(fd);
13701 diff -Naur a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
13702 --- a/arch/um/os-Linux/file.c 2004-02-11 12:17:07.000000000 -0500
13703 +++ b/arch/um/os-Linux/file.c 2004-02-11 12:29:09.000000000 -0500
13707 #include <signal.h>
13708 +#include <sys/types.h>
13709 +#include <sys/stat.h>
13710 #include <sys/socket.h>
13711 #include <sys/un.h>
13712 #include <sys/ioctl.h>
13713 @@ -17,33 +19,235 @@
13715 #include "kern_util.h"
13717 -int os_file_type(char *file)
13718 +static void copy_stat(struct uml_stat *dst, struct stat64 *src)
13720 + *dst = ((struct uml_stat) {
13721 + .ust_dev = src->st_dev, /* device */
13722 + .ust_ino = src->st_ino, /* inode */
13723 + .ust_mode = src->st_mode, /* protection */
13724 + .ust_nlink = src->st_nlink, /* number of hard links */
13725 + .ust_uid = src->st_uid, /* user ID of owner */
13726 + .ust_gid = src->st_gid, /* group ID of owner */
13727 + .ust_size = src->st_size, /* total size, in bytes */
13728 + .ust_blksize = src->st_blksize, /* blocksize for filesys I/O */
13729 + .ust_blocks = src->st_blocks, /* number of blocks allocated */
13730 + .ust_atime = src->st_atime, /* time of last access */
13731 + .ust_mtime = src->st_mtime, /* time of last modification */
13732 + .ust_ctime = src->st_ctime, /* time of last change */
13736 +int os_stat_fd(const int fd, struct uml_stat *ubuf)
13738 + struct stat64 sbuf;
13742 + err = fstat64(fd, &sbuf);
13743 + } while((err < 0) && (errno == EINTR)) ;
13749 + copy_stat(ubuf, &sbuf);
13753 +int os_stat_file(const char *file_name, struct uml_stat *ubuf)
13755 + struct stat64 sbuf;
13759 + err = stat64(file_name, &sbuf);
13760 + } while((err < 0) && (errno == EINTR)) ;
13766 + copy_stat(ubuf, &sbuf);
13770 +int os_access(const char* file, int mode)
13774 + amode=(mode&OS_ACC_R_OK ? R_OK : 0) | (mode&OS_ACC_W_OK ? W_OK : 0) |
13775 + (mode&OS_ACC_X_OK ? X_OK : 0) | (mode&OS_ACC_F_OK ? F_OK : 0) ;
13777 + err = access(file, amode);
13784 +void os_print_error(int error, const char* str)
13786 + errno = error < 0 ? -error : error;
13791 +/* FIXME? required only by hostaudio (because it passes ioctls verbatim) */
13792 +int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
13796 + err = ioctl(fd, cmd, arg);
13803 +int os_window_size(int fd, int *rows, int *cols)
13805 + struct winsize size;
13807 + if(ioctl(fd, TIOCGWINSZ, &size) < 0)
13810 + *rows = size.ws_row;
13811 + *cols = size.ws_col;
13816 +int os_new_tty_pgrp(int fd, int pid)
13818 - struct stat64 buf;
13819 + if(ioctl(fd, TIOCSCTTY, 0) < 0){
13820 + printk("TIOCSCTTY failed, errno = %d\n", errno);
13824 + if(tcsetpgrp(fd, pid) < 0){
13825 + printk("tcsetpgrp failed, errno = %d\n", errno);
13832 +/* FIXME: ensure namebuf in os_get_if_name is big enough */
13833 +int os_get_ifname(int fd, char* namebuf)
13835 + if(ioctl(fd, SIOCGIFNAME, namebuf) < 0)
13841 +int os_set_slip(int fd)
13843 + int disc, sencap;
13846 + if(ioctl(fd, TIOCSETD, &disc) < 0){
13847 + printk("Failed to set slip line discipline - "
13848 + "errno = %d\n", errno);
13853 + if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0){
13854 + printk("Failed to set slip encapsulation - "
13855 + "errno = %d\n", errno);
13862 +int os_set_owner(int fd, int pid)
13864 + if(fcntl(fd, F_SETOWN, pid) < 0){
13865 + int save_errno = errno;
13867 + if(fcntl(fd, F_GETOWN, 0) != pid)
13868 + return(-save_errno);
13874 +/* FIXME? moved wholesale from sigio_user.c to get fcntls out of that file */
13875 +int os_sigio_async(int master, int slave)
13879 - if(stat64(file, &buf) == -1)
13880 + flags = fcntl(master, F_GETFL);
13882 + printk("fcntl F_GETFL failed, errno = %d\n", errno);
13886 + if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
13887 + (fcntl(master, F_SETOWN, os_getpid()) < 0)){
13888 + printk("fcntl F_SETFL or F_SETOWN failed, errno = %d\n", errno);
13892 + if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)){
13893 + printk("fcntl F_SETFL failed, errno = %d\n", errno);
13897 - if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
13898 - else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
13899 - else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
13900 - else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
13901 - else if(S_ISFIFO(buf.st_mode)) return(OS_TYPE_FIFO);
13902 - else if(S_ISSOCK(buf.st_mode)) return(OS_TYPE_SOCK);
13906 +int os_mode_fd(int fd, int mode)
13911 + err = fchmod(fd, mode);
13912 + } while((err < 0) && (errno==EINTR)) ;
13920 +int os_file_type(char *file)
13922 + struct uml_stat buf;
13925 + err = os_stat_file(file, &buf);
13929 + if(S_ISDIR(buf.ust_mode)) return(OS_TYPE_DIR);
13930 + else if(S_ISLNK(buf.ust_mode)) return(OS_TYPE_SYMLINK);
13931 + else if(S_ISCHR(buf.ust_mode)) return(OS_TYPE_CHARDEV);
13932 + else if(S_ISBLK(buf.ust_mode)) return(OS_TYPE_BLOCKDEV);
13933 + else if(S_ISFIFO(buf.ust_mode)) return(OS_TYPE_FIFO);
13934 + else if(S_ISSOCK(buf.ust_mode)) return(OS_TYPE_SOCK);
13935 else return(OS_TYPE_FILE);
13938 int os_file_mode(char *file, struct openflags *mode_out)
13942 *mode_out = OPENFLAGS();
13944 - if(!access(file, W_OK)) *mode_out = of_write(*mode_out);
13945 - else if(errno != EACCES)
13947 + err = os_access(file, OS_ACC_W_OK);
13948 + if((err < 0) && (err != -EACCES))
13951 - if(!access(file, R_OK)) *mode_out = of_read(*mode_out);
13952 - else if(errno != EACCES)
13954 + *mode_out = of_write(*mode_out);
13956 + err = os_access(file, OS_ACC_R_OK);
13957 + if((err < 0) && (err != -EACCES))
13960 + *mode_out = of_read(*mode_out);
13964 @@ -63,16 +267,14 @@
13965 if(flags.e) f |= O_EXCL;
13967 fd = open64(file, f, mode);
13968 - if(fd < 0) return(-errno);
13971 - if(fcntl(fd, F_SETFD, 1)){
13978 + if(flags.cl && fcntl(fd, F_SETFD, 1)){
13979 + os_close_file(fd);
13989 err = connect(fd, (struct sockaddr *) &sock, sizeof(sock));
13996 @@ -109,88 +311,162 @@
14000 -int os_read_file(int fd, void *buf, int len)
14001 +static int fault_buffer(void *start, int len,
14002 + int (*copy_proc)(void *addr, void *buf, int len))
14005 + int page = getpagesize(), i;
14008 - /* Force buf into memory if it's not already. */
14009 + for(i = 0; i < len; i += page){
14010 + if((*copy_proc)(start + i, &c, sizeof(c)))
14013 + if((len % page) != 0){
14014 + if((*copy_proc)(start + len - 1, &c, sizeof(c)))
14020 - /* XXX This fails if buf is kernel memory */
14022 - if(copy_to_user_proc(buf, &c, sizeof(c)))
14025 +static int file_io(int fd, void *buf, int len,
14026 + int (*io_proc)(int fd, void *buf, int len),
14027 + int (*copy_user_proc)(void *addr, void *buf, int len))
14032 + n = (*io_proc)(fd, buf, len);
14033 + if((n < 0) && (errno == EFAULT)){
14034 + err = fault_buffer(buf, len, copy_user_proc);
14037 + n = (*io_proc)(fd, buf, len);
14039 + } while((n < 0) && (errno == EINTR));
14041 - n = read(fd, buf, len);
14047 -int os_write_file(int fd, void *buf, int count)
14048 +int os_read_file(int fd, void *buf, int len)
14052 - /* Force buf into memory if it's not already. */
14054 - /* XXX This fails if buf is kernel memory */
14056 - if(copy_to_user_proc(buf, buf, buf[0]))
14059 + return(file_io(fd, buf, len, (int (*)(int, void *, int)) read,
14060 + copy_from_user_proc));
14063 - n = write(fd, buf, count);
14067 +int os_write_file(int fd, const void *buf, int len)
14069 + return(file_io(fd, (void *) buf, len,
14070 + (int (*)(int, void *, int)) write, copy_to_user_proc));
14073 int os_file_size(char *file, long long *size_out)
14075 - struct stat64 buf;
14076 + struct uml_stat buf;
14079 - if(stat64(file, &buf) == -1){
14080 - printk("Couldn't stat \"%s\" : errno = %d\n", file, errno);
14082 + err = os_stat_file(file, &buf);
14084 + printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
14087 - if(S_ISBLK(buf.st_mode)){
14089 + if(S_ISBLK(buf.ust_mode)){
14092 - if((fd = open64(file, O_RDONLY)) < 0){
14093 - printk("Couldn't open \"%s\", errno = %d\n", file,
14096 + fd = os_open_file(file, of_read(OPENFLAGS()), 0);
14098 + printk("Couldn't open \"%s\", errno = %d\n", file, -fd);
14101 if(ioctl(fd, BLKGETSIZE, &blocks) < 0){
14102 printk("Couldn't get the block size of \"%s\", "
14103 "errno = %d\n", file, errno);
14107 + os_close_file(fd);
14110 *size_out = ((long long) blocks) * 512;
14112 + os_close_file(fd);
14115 - *size_out = buf.st_size;
14116 + *size_out = buf.ust_size;
14120 +int os_file_modtime(char *file, unsigned long *modtime)
14122 + struct uml_stat buf;
14125 + err = os_stat_file(file, &buf);
14127 + printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
14131 + *modtime = buf.ust_mtime;
14135 +int os_get_exec_close(int fd, int* close_on_exec)
14140 + ret = fcntl(fd, F_GETFD);
14141 + } while((ret < 0) && (errno == EINTR)) ;
14146 + *close_on_exec = (ret&FD_CLOEXEC) ? 1 : 0;
14150 +int os_set_exec_close(int fd, int close_on_exec)
14154 + if(close_on_exec) flag = FD_CLOEXEC;
14158 + err = fcntl(fd, F_SETFD, flag);
14159 + } while((err < 0) && (errno == EINTR)) ;
14166 int os_pipe(int *fds, int stream, int close_on_exec)
14168 int err, type = stream ? SOCK_STREAM : SOCK_DGRAM;
14170 err = socketpair(AF_UNIX, type, 0, fds);
14178 - if((fcntl(fds[0], F_SETFD, 1) < 0) || (fcntl(fds[1], F_SETFD, 1) < 0))
14179 - printk("os_pipe : Setting FD_CLOEXEC failed, errno = %d",
14181 + err = os_set_exec_close(fds[0], 1);
14185 + err = os_set_exec_close(fds[1], 1);
14192 + printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err);
14193 + os_close_file(fds[1]);
14194 + os_close_file(fds[0]);
14198 int os_set_fd_async(int fd, int owner)
14199 @@ -270,7 +546,7 @@
14202 err = shutdown(fd, what);
14208 @@ -315,7 +591,7 @@
14212 -int create_unix_socket(char *file, int len)
14213 +int os_create_unix_socket(char *file, int len, int close_on_exec)
14215 struct sockaddr_un addr;
14217 @@ -327,6 +603,13 @@
14221 + if(close_on_exec) {
14222 + err = os_set_exec_close(sock, 1);
14224 + printk("create_unix_socket : close_on_exec failed, "
14225 + "err = %d", -err);
14228 addr.sun_family = AF_UNIX;
14230 /* XXX Be more careful about overflow */
14231 @@ -334,14 +617,45 @@
14233 err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
14235 - printk("create_listening_socket - bind failed, errno = %d\n",
14237 + printk("create_listening_socket at '%s' - bind failed, "
14238 + "errno = %d\n", file, errno);
14245 +void os_flush_stdout(void)
14250 +int os_lock_file(int fd, int excl)
14252 + int type = excl ? F_WRLCK : F_RDLCK;
14253 + struct flock lock = ((struct flock) { .l_type = type,
14254 + .l_whence = SEEK_SET,
14259 + err = fcntl(fd, F_SETLK, &lock);
14264 + err = fcntl(fd, F_GETLK, &lock);
14270 + printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
14277 * Overrides for Emacs so that we follow Linus's tabbing style.
14278 * Emacs will notice this stuff at the end of the file and automatically
14279 diff -Naur a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
14280 --- a/arch/um/os-Linux/Makefile 2004-02-11 12:15:56.000000000 -0500
14281 +++ b/arch/um/os-Linux/Makefile 2004-02-11 12:27:48.000000000 -0500
14284 $(USER_OBJS) : %.o: %.c
14285 $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
14290 diff -Naur a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
14291 --- a/arch/um/os-Linux/process.c 2004-02-11 12:14:23.000000000 -0500
14292 +++ b/arch/um/os-Linux/process.c 2004-02-11 12:26:04.000000000 -0500
14295 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14296 + * Copyright (C) 2002 Jeff Dike (jdike@addtoit.com)
14297 * Licensed under the GPL
14303 #include <signal.h>
14304 +#include <linux/unistd.h>
14305 #include <sys/mman.h>
14306 #include <sys/wait.h>
14310 +#define ARBITRARY_ADDR -1
14311 +#define FAILURE_PID -1
14313 unsigned long os_process_pc(int pid)
14315 char proc_stat[sizeof("/proc/#####/stat\0")], buf[256];
14320 sprintf(proc_stat, "/proc/%d/stat", pid);
14321 fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0);
14323 - printk("os_process_pc - couldn't open '%s', errno = %d\n",
14324 - proc_stat, errno);
14326 + printk("os_process_pc - couldn't open '%s', err = %d\n",
14328 + return(ARBITRARY_ADDR);
14330 - if(read(fd, buf, sizeof(buf)) < 0){
14331 - printk("os_process_pc - couldn't read '%s', errno = %d\n",
14332 - proc_stat, errno);
14335 + err = os_read_file(fd, buf, sizeof(buf));
14337 + printk("os_process_pc - couldn't read '%s', err = %d\n",
14338 + proc_stat, -err);
14339 + os_close_file(fd);
14340 + return(ARBITRARY_ADDR);
14344 + os_close_file(fd);
14345 + pc = ARBITRARY_ADDR;
14346 if(sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*d %*d %*d "
14347 "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
14348 "%*d %*d %*d %*d %ld", &pc) != 1){
14349 @@ -52,22 +57,23 @@
14350 snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
14351 fd = os_open_file(stat, of_read(OPENFLAGS()), 0);
14353 - printk("Couldn't open '%s', errno = %d\n", stat, -fd);
14355 + printk("Couldn't open '%s', err = %d\n", stat, -fd);
14356 + return(FAILURE_PID);
14359 - n = read(fd, data, sizeof(data));
14361 + n = os_read_file(fd, data, sizeof(data));
14362 + os_close_file(fd);
14365 - printk("Couldn't read '%s', errno = %d\n", stat);
14367 + printk("Couldn't read '%s', err = %d\n", stat, -n);
14368 + return(FAILURE_PID);
14372 + parent = FAILURE_PID;
14373 /* XXX This will break if there is a space in the command */
14374 n = sscanf(data, "%*d %*s %*c %d", &parent);
14375 - if(n != 1) printk("Failed to scan '%s'\n", data);
14377 + printk("Failed to scan '%s'\n", data);
14383 void os_usr1_process(int pid)
14385 - kill(pid, SIGUSR1);
14386 + syscall(__NR_tkill, pid, SIGUSR1);
14387 + /* kill(pid, SIGUSR1); */
14390 int os_getpid(void)
14395 -int os_map_memory(void *virt, int fd, unsigned long off, unsigned long len,
14396 +int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
14397 int r, int w, int x)
14400 @@ -104,8 +111,8 @@
14401 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
14402 (x ? PROT_EXEC : 0);
14404 - loc = mmap((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
14406 + loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
14408 if(loc == MAP_FAILED)
14411 @@ -126,7 +133,8 @@
14414 err = munmap(addr, len);
14415 - if(err < 0) return(-errno);
14421 diff -Naur a/arch/um/os-Linux/tty.c b/arch/um/os-Linux/tty.c
14422 --- a/arch/um/os-Linux/tty.c 2004-02-11 12:15:53.000000000 -0500
14423 +++ b/arch/um/os-Linux/tty.c 2004-02-11 12:27:46.000000000 -0500
14424 @@ -28,10 +28,10 @@
14425 struct grantpt_info info;
14428 - if((fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0)) < 0){
14429 - printk("get_pty : Couldn't open /dev/ptmx - errno = %d\n",
14432 + fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0);
14434 + printk("get_pty : Couldn't open /dev/ptmx - err = %d\n", -fd);
14442 printk("get_pty : Couldn't grant pty - errno = %d\n",
14447 if(unlockpt(fd) < 0){
14448 diff -Naur a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c
14449 --- a/arch/um/sys-i386/bugs.c 2004-02-11 12:16:28.000000000 -0500
14450 +++ b/arch/um/sys-i386/bugs.c 2004-02-11 12:28:27.000000000 -0500
14454 #include <unistd.h>
14455 -#include <fcntl.h>
14457 #include <string.h>
14458 #include <sys/signal.h>
14459 +#include <asm/ldt.h>
14460 #include "kern_util.h"
14462 #include "sysdep/ptrace.h"
14466 #define MAXTOKEN 64
14468 /* Set during early boot */
14469 -int cpu_has_cmov = 1;
14470 -int cpu_has_xmm = 0;
14471 +int host_has_cmov = 1;
14472 +int host_has_xmm = 0;
14474 static char token(int fd, char *buf, int len, char stop)
14476 @@ -27,13 +28,15 @@
14480 - n = read(fd, ptr, sizeof(*ptr));
14481 + n = os_read_file(fd, ptr, sizeof(*ptr));
14483 - if(n == 0) return(0);
14484 - else if(n != sizeof(*ptr)){
14485 - printk("Reading /proc/cpuinfo failed, "
14486 - "errno = %d\n", errno);
14488 + if(n != sizeof(*ptr)){
14489 + if(n == 0) return(0);
14490 + printk("Reading /proc/cpuinfo failed, err = %d\n", -n);
14496 } while((c != '\n') && (c != stop) && (ptr < end));
14498 @@ -45,45 +48,79 @@
14502 -static int check_cpu_feature(char *feature, int *have_it)
14503 +static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
14505 - char buf[MAXTOKEN], c;
14506 - int fd, len = sizeof(buf)/sizeof(buf[0]), n;
14508 - printk("Checking for host processor %s support...", feature);
14509 - fd = open("/proc/cpuinfo", O_RDONLY);
14511 - printk("Couldn't open /proc/cpuinfo, errno = %d\n", errno);
14518 - buf[len - 1] = '\0';
14519 + scratch[len - 1] = '\0';
14521 - c = token(fd, buf, len - 1, ':');
14522 - if(c <= 0) goto out;
14523 + c = token(fd, scratch, len - 1, ':');
14527 printk("Failed to find ':' in /proc/cpuinfo\n");
14532 - if(!strncmp(buf, "flags", strlen("flags"))) break;
14533 + if(!strncmp(scratch, key, strlen(key)))
14537 - n = read(fd, &c, sizeof(c));
14538 + n = os_read_file(fd, &c, sizeof(c));
14539 if(n != sizeof(c)){
14540 printk("Failed to find newline in "
14541 - "/proc/cpuinfo, n = %d, errno = %d\n",
14544 + "/proc/cpuinfo, err = %d\n", -n);
14547 } while(c != '\n');
14552 +int cpu_feature(char *what, char *buf, int len)
14556 + fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
14558 + printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
14562 + if(!find_cpuinfo_line(fd, what, buf, len)){
14563 + printk("Couldn't find '%s' line in /proc/cpuinfo\n", what);
14567 + token(fd, buf, len, '\n');
14571 + os_close_file(fd);
14575 +static int check_cpu_flag(char *feature, int *have_it)
14577 + char buf[MAXTOKEN], c;
14578 + int fd, len = sizeof(buf)/sizeof(buf[0]);
14580 + printk("Checking for host processor %s support...", feature);
14581 + fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
14583 + printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
14588 + if(!find_cpuinfo_line(fd, "flags", buf, sizeof(buf) / sizeof(buf[0])))
14591 c = token(fd, buf, len - 1, ' ');
14592 if(c < 0) goto out;
14594 - printk("Failed to find ':' in /proc/cpuinfo\n");
14595 + printk("Failed to find ' ' in /proc/cpuinfo\n");
14599 @@ -100,21 +137,48 @@
14601 if(*have_it == 0) printk("No\n");
14602 else if(*have_it == 1) printk("Yes\n");
14604 + os_close_file(fd);
14608 +#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems
14609 + * for some people.
14611 +static void disable_lcall(void)
14613 + struct modify_ldt_ldt_s ldt;
14616 + bzero(&ldt, sizeof(ldt));
14617 + ldt.entry_number = 7;
14618 + ldt.base_addr = 0;
14620 + err = modify_ldt(1, &ldt, sizeof(ldt));
14622 + printk("Failed to disable lcall7 - errno = %d\n", errno);
14626 +void arch_init_thread(void)
14633 void arch_check_bugs(void)
14637 - if(access("/proc/cpuinfo", R_OK)){
14638 + if(os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0){
14639 printk("/proc/cpuinfo not available - skipping CPU capability "
14643 - if(check_cpu_feature("cmov", &have_it)) cpu_has_cmov = have_it;
14644 - if(check_cpu_feature("xmm", &have_it)) cpu_has_xmm = have_it;
14645 + if(check_cpu_flag("cmov", &have_it))
14646 + host_has_cmov = have_it;
14647 + if(check_cpu_flag("xmm", &have_it))
14648 + host_has_xmm = have_it;
14651 int arch_handle_signal(int sig, union uml_pt_regs *regs)
14652 @@ -130,18 +194,18 @@
14653 if((*((char *) ip) != 0x0f) || ((*((char *) (ip + 1)) & 0xf0) != 0x40))
14656 - if(cpu_has_cmov == 0)
14657 + if(host_has_cmov == 0)
14658 panic("SIGILL caused by cmov, which this processor doesn't "
14659 "implement, boot a filesystem compiled for older "
14661 - else if(cpu_has_cmov == 1)
14662 + else if(host_has_cmov == 1)
14663 panic("SIGILL caused by cmov, which this processor claims to "
14665 - else if(cpu_has_cmov == -1)
14666 + else if(host_has_cmov == -1)
14667 panic("SIGILL caused by cmov, couldn't tell if this processor "
14668 "implements it, boot a filesystem compiled for older "
14670 - else panic("Bad value for cpu_has_cmov (%d)", cpu_has_cmov);
14671 + else panic("Bad value for host_has_cmov (%d)", host_has_cmov);
14675 diff -Naur a/arch/um/sys-i386/extable.c b/arch/um/sys-i386/extable.c
14676 --- a/arch/um/sys-i386/extable.c 2004-02-11 12:16:45.000000000 -0500
14677 +++ b/arch/um/sys-i386/extable.c 1969-12-31 19:00:00.000000000 -0500
14680 - * linux/arch/i386/mm/extable.c
14683 -#include <linux/config.h>
14684 -#include <linux/module.h>
14685 -#include <linux/spinlock.h>
14686 -#include <asm/uaccess.h>
14688 -/* Simple binary search */
14689 -const struct exception_table_entry *
14690 -search_extable(const struct exception_table_entry *first,
14691 - const struct exception_table_entry *last,
14692 - unsigned long value)
14694 - while (first <= last) {
14695 - const struct exception_table_entry *mid;
14698 - mid = (last - first) / 2 + first;
14699 - diff = mid->insn - value;
14702 - else if (diff < 0)
14709 diff -Naur a/arch/um/sys-i386/fault.c b/arch/um/sys-i386/fault.c
14710 --- a/arch/um/sys-i386/fault.c 2004-02-11 12:15:44.000000000 -0500
14711 +++ b/arch/um/sys-i386/fault.c 2004-02-11 12:27:19.000000000 -0500
14714 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14715 + * Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com)
14716 * Licensed under the GPL
14720 #include "sysdep/ptrace.h"
14721 #include "sysdep/sigcontext.h"
14723 -extern unsigned long search_exception_table(unsigned long addr);
14724 +/* These two are from asm-um/uaccess.h and linux/module.h, check them. */
14725 +struct exception_table_entry
14727 + unsigned long insn;
14728 + unsigned long fixup;
14731 +const struct exception_table_entry *search_exception_tables(unsigned long add);
14733 +/* Compare this to arch/i386/mm/extable.c:fixup_exception() */
14734 int arch_fixup(unsigned long address, void *sc_ptr)
14736 struct sigcontext *sc = sc_ptr;
14737 - unsigned long fixup;
14738 + const struct exception_table_entry *fixup;
14740 fixup = search_exception_tables(address);
14743 + sc->eip = fixup->fixup;
14747 diff -Naur a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
14748 --- a/arch/um/sys-i386/Makefile 2004-02-11 12:14:27.000000000 -0500
14749 +++ b/arch/um/sys-i386/Makefile 2004-02-11 12:26:08.000000000 -0500
14751 -obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o module.o \
14752 - ptrace.o ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
14753 +obj-y = bugs.o checksum.o fault.o ksyms.o ldt.o ptrace.o ptrace_user.o \
14754 + semaphore.o sigcontext.o syscalls.o sysrq.o time.o
14756 obj-$(CONFIG_HIGHMEM) += highmem.o
14757 +obj-$(CONFIG_MODULES) += module.o
14759 USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
14760 USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
14762 SYMLINKS = semaphore.c highmem.c module.c
14763 SYMLINKS := $(foreach f,$(SYMLINKS),$(src)/$f)
14765 +clean-files := $(SYMLINKS)
14767 semaphore.c-dir = kernel
14769 module.c-dir = kernel
14772 $(call make_link,$@)
14775 - $(MAKE) -C util clean
14782 - rm -f $(SYMLINKS)
14791 diff -Naur a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c
14792 --- a/arch/um/sys-i386/ptrace_user.c 2004-02-11 12:14:33.000000000 -0500
14793 +++ b/arch/um/sys-i386/ptrace_user.c 2004-02-11 12:26:15.000000000 -0500
14794 @@ -39,10 +39,10 @@
14795 nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
14796 for(i = 0; i < nregs; i++){
14797 if((i == 4) || (i == 5)) continue;
14798 - if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i],
14799 + if(ptrace(PTRACE_POKEUSER, pid, &dummy->u_debugreg[i],
14801 - printk("write_debugregs - ptrace failed, "
14802 - "errno = %d\n", errno);
14803 + printk("write_debugregs - ptrace failed on "
14804 + "register %d, errno = %d\n", errno);
14810 nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
14811 for(i = 0; i < nregs; i++){
14812 - regs[i] = ptrace(PTRACE_PEEKUSR, pid,
14813 + regs[i] = ptrace(PTRACE_PEEKUSER, pid,
14814 &dummy->u_debugreg[i], 0);
14817 diff -Naur a/arch/um/sys-i386/time.c b/arch/um/sys-i386/time.c
14818 --- a/arch/um/sys-i386/time.c 1969-12-31 19:00:00.000000000 -0500
14819 +++ b/arch/um/sys-i386/time.c 2004-02-11 12:26:16.000000000 -0500
14822 + * sys-i386/time.c
14823 + * Created 25.9.2002 Sapan Bhatia
14827 +unsigned long long time_stamp(void)
14829 + unsigned long low, high;
14831 + asm("rdtsc" : "=a" (low), "=d" (high));
14832 + return((((unsigned long long) high) << 32) + low);
14836 + * Overrides for Emacs so that we follow Linus's tabbing style.
14837 + * Emacs will notice this stuff at the end of the file and automatically
14838 + * adjust the settings for this buffer only. This must remain at the end
14840 + * ---------------------------------------------------------------------------
14841 + * Local variables:
14842 + * c-file-style: "linux"
14845 diff -Naur a/arch/um/sys-i386/util/Makefile b/arch/um/sys-i386/util/Makefile
14846 --- a/arch/um/sys-i386/util/Makefile 2004-02-11 12:16:48.000000000 -0500
14847 +++ b/arch/um/sys-i386/util/Makefile 2004-02-11 12:29:04.000000000 -0500
14849 +host-progs := mk_sc mk_thread
14850 +always := $(host-progs)
14852 -host-progs := mk_sc
14853 -always := $(host-progs) mk_thread
14854 -targets := mk_thread_kern.o mk_thread_user.o
14855 +mk_thread-objs := mk_thread_kern.o mk_thread_user.o
14857 -mk_sc-objs := mk_sc.o
14859 -$(obj)/mk_thread : $(obj)/mk_thread_kern.o $(obj)/mk_thread_user.o
14860 - $(CC) $(CFLAGS) -o $@ $^
14862 -$(obj)/mk_thread_user.o : $(src)/mk_thread_user.c
14863 - $(CC) $(USER_CFLAGS) -c -o $@ $<
14864 +HOSTCFLAGS_mk_thread_kern.o := $(CFLAGS)
14865 +HOSTCFLAGS_mk_thread_user.o := $(USER_CFLAGS)
14868 $(RM) -f $(build-targets)
14869 diff -Naur a/arch/um/sys-i386/util/mk_sc.c b/arch/um/sys-i386/util/mk_sc.c
14870 --- a/arch/um/sys-i386/util/mk_sc.c 2004-02-11 12:16:38.000000000 -0500
14871 +++ b/arch/um/sys-i386/util/mk_sc.c 2004-02-11 12:28:37.000000000 -0500
14873 SC_OFFSET("SC_ERR", err);
14874 SC_OFFSET("SC_CR2", cr2);
14875 SC_OFFSET("SC_FPSTATE", fpstate);
14876 + SC_OFFSET("SC_SIGMASK", oldmask);
14877 SC_FP_OFFSET("SC_FP_CW", cw);
14878 SC_FP_OFFSET("SC_FP_SW", sw);
14879 SC_FP_OFFSET("SC_FP_TAG", tag);
14880 diff -Naur a/arch/um/sys-ia64/Makefile b/arch/um/sys-ia64/Makefile
14881 --- a/arch/um/sys-ia64/Makefile 2004-02-11 12:14:16.000000000 -0500
14882 +++ b/arch/um/sys-ia64/Makefile 2004-02-11 12:25:43.000000000 -0500
14886 $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
14896 - @$(MAKEBOOT) clean
14902 +clean-files := $(OBJS) link.ld
14903 diff -Naur a/arch/um/sys-ppc/Makefile b/arch/um/sys-ppc/Makefile
14904 --- a/arch/um/sys-ppc/Makefile 2004-02-11 12:15:23.000000000 -0500
14905 +++ b/arch/um/sys-ppc/Makefile 2004-02-11 12:27:11.000000000 -0500
14907 $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
14913 - rm -f checksum.S semaphore.c mk_defs.c
14920 +clean-files := $(OBJS) ppc_defs.h checksum.S semaphore.c mk_defs.c
14921 diff -Naur a/arch/um/uml.lds.S b/arch/um/uml.lds.S
14922 --- a/arch/um/uml.lds.S 2004-02-11 12:15:21.000000000 -0500
14923 +++ b/arch/um/uml.lds.S 2004-02-11 12:27:08.000000000 -0500
14926 . = START + SIZEOF_HEADERS;
14929 __binary_start = .;
14931 .thread_private : {
14933 . = ALIGN(4096); /* Init code and data */
14936 - .text.init : { *(.text.init) }
14947 #include "asm/common.lds.S"
14949 - .data.init : { *(.data.init) }
14950 + init.data : { *(init.data) }
14953 . = ALIGN(KERNEL_STACK_SIZE); /* init_task */
14954 diff -Naur a/arch/um/util/Makefile b/arch/um/util/Makefile
14955 --- a/arch/um/util/Makefile 2004-02-11 12:17:07.000000000 -0500
14956 +++ b/arch/um/util/Makefile 2004-02-11 12:29:10.000000000 -0500
14958 -always := mk_task mk_constants
14959 -targets := mk_task_user.o mk_task_kern.o \
14960 - mk_constants_user.o mk_constants_kern.o
14961 +host-progs := mk_task mk_constants
14962 +always := $(host-progs)
14964 -$(obj)/mk_task: $(obj)/mk_task_user.o $(obj)/mk_task_kern.o
14966 +mk_task-objs := mk_task_user.o mk_task_kern.o
14967 +mk_constants-objs := mk_constants_user.o mk_constants_kern.o
14969 -$(obj)/mk_task_user.o: $(src)/mk_task_user.c
14970 - $(CC) -o $@ -c $<
14972 -$(obj)/mk_constants : $(obj)/mk_constants_user.o $(obj)/mk_constants_kern.o
14975 -$(obj)/mk_constants_user.o : $(src)/mk_constants_user.c
14976 - $(CC) -c $< -o $@
14978 -$(obj)/mk_constants_kern.o : $(src)/mk_constants_kern.c
14979 - $(CC) $(CFLAGS) -c $< -o $@
14982 - $(RM) $(build-targets)
14985 +HOSTCFLAGS_mk_task_kern.o := $(CFLAGS)
14986 +HOSTCFLAGS_mk_constants_kern.o := $(CFLAGS)
14987 diff -Naur a/arch/um/util/mk_constants_kern.c b/arch/um/util/mk_constants_kern.c
14988 --- a/arch/um/util/mk_constants_kern.c 2004-02-11 12:14:19.000000000 -0500
14989 +++ b/arch/um/util/mk_constants_kern.c 2004-02-11 12:26:02.000000000 -0500
14991 #include "linux/kernel.h"
14992 #include "linux/stringify.h"
14993 +#include "linux/time.h"
14994 #include "asm/page.h"
14996 extern void print_head(void);
15000 print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
15002 print_constant_str("UM_KERN_EMERG", KERN_EMERG);
15003 print_constant_str("UM_KERN_ALERT", KERN_ALERT);
15004 print_constant_str("UM_KERN_CRIT", KERN_CRIT);
15006 print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
15007 print_constant_str("UM_KERN_INFO", KERN_INFO);
15008 print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
15010 + print_constant_int("UM_NSEC_PER_SEC", NSEC_PER_SEC);
15014 diff -Naur a/drivers/base/Makefile b/drivers/base/Makefile
15015 --- a/drivers/base/Makefile 2004-02-11 12:16:32.000000000 -0500
15016 +++ b/drivers/base/Makefile 2004-02-11 12:28:31.000000000 -0500
15019 obj-y := core.o sys.o interface.o bus.o \
15020 driver.o class.o class_simple.o platform.o \
15021 - cpu.o firmware.o init.o map.o dmapool.o
15022 + cpu.o firmware.o init.o map.o
15024 obj-$(CONFIG_FW_LOADER) += firmware_class.o
15025 obj-$(CONFIG_NUMA) += node.o
15026 +obj-$(CONFIG_PCI) += dmapool.o
15027 diff -Naur a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
15028 --- a/fs/hostfs/hostfs.h 1969-12-31 19:00:00.000000000 -0500
15029 +++ b/fs/hostfs/hostfs.h 2004-02-11 12:25:42.000000000 -0500
15031 +#ifndef __UM_FS_HOSTFS
15032 +#define __UM_FS_HOSTFS
15036 +/* These are exactly the same definitions as in fs.h, but the names are
15037 + * changed so that this file can be included in both kernel and user files.
15040 +#define HOSTFS_ATTR_MODE 1
15041 +#define HOSTFS_ATTR_UID 2
15042 +#define HOSTFS_ATTR_GID 4
15043 +#define HOSTFS_ATTR_SIZE 8
15044 +#define HOSTFS_ATTR_ATIME 16
15045 +#define HOSTFS_ATTR_MTIME 32
15046 +#define HOSTFS_ATTR_CTIME 64
15047 +#define HOSTFS_ATTR_ATIME_SET 128
15048 +#define HOSTFS_ATTR_MTIME_SET 256
15049 +#define HOSTFS_ATTR_FORCE 512 /* Not a change, but a change it */
15050 +#define HOSTFS_ATTR_ATTR_FLAG 1024
15052 +struct hostfs_iattr {
15053 + unsigned int ia_valid;
15058 + struct timespec ia_atime;
15059 + struct timespec ia_mtime;
15060 + struct timespec ia_ctime;
15061 + unsigned int ia_attr_flags;
15064 +extern int stat_file(const char *path, unsigned long long *inode_out,
15065 + int *mode_out, int *nlink_out, int *uid_out, int *gid_out,
15066 + unsigned long long *size_out, struct timespec *atime_out,
15067 + struct timespec *mtime_out, struct timespec *ctime_out,
15068 + int *blksize_out, unsigned long long *blocks_out);
15069 +extern int access_file(char *path, int r, int w, int x);
15070 +extern int open_file(char *path, int r, int w, int append);
15071 +extern int file_type(const char *path, int *rdev);
15072 +extern void *open_dir(char *path, int *err_out);
15073 +extern char *read_dir(void *stream, unsigned long long *pos,
15074 + unsigned long long *ino_out, int *len_out);
15075 +extern void close_file(void *stream);
15076 +extern void close_dir(void *stream);
15077 +extern int read_file(int fd, unsigned long long *offset, char *buf, int len);
15078 +extern int write_file(int fd, unsigned long long *offset, const char *buf,
15080 +extern int lseek_file(int fd, long long offset, int whence);
15081 +extern int file_create(char *name, int ur, int uw, int ux, int gr,
15082 + int gw, int gx, int or, int ow, int ox);
15083 +extern int set_attr(const char *file, struct hostfs_iattr *attrs);
15084 +extern int make_symlink(const char *from, const char *to);
15085 +extern int unlink_file(const char *file);
15086 +extern int do_mkdir(const char *file, int mode);
15087 +extern int do_rmdir(const char *file);
15088 +extern int do_mknod(const char *file, int mode, int dev);
15089 +extern int link_file(const char *from, const char *to);
15090 +extern int do_readlink(char *file, char *buf, int size);
15091 +extern int rename_file(char *from, char *to);
15092 +extern int do_statfs(char *root, long *bsize_out, long long *blocks_out,
15093 + long long *bfree_out, long long *bavail_out,
15094 + long long *files_out, long long *ffree_out,
15095 + void *fsid_out, int fsid_size, long *namelen_out,
15096 + long *spare_out);
15101 + * Overrides for Emacs so that we follow Linus's tabbing style.
15102 + * Emacs will notice this stuff at the end of the file and automatically
15103 + * adjust the settings for this buffer only. This must remain at the end
15105 + * ---------------------------------------------------------------------------
15106 + * Local variables:
15107 + * c-file-style: "linux"
15110 diff -Naur a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
15111 --- a/fs/hostfs/hostfs_kern.c 1969-12-31 19:00:00.000000000 -0500
15112 +++ b/fs/hostfs/hostfs_kern.c 2004-02-11 12:25:59.000000000 -0500
15115 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
15116 + * Licensed under the GPL
15118 + * Ported the filesystem routines to 2.5.
15119 + * 2003-02-10 Petr Baudis <pasky@ucw.cz>
15122 +#include <linux/stddef.h>
15123 +#include <linux/fs.h>
15124 +#include <linux/version.h>
15125 +#include <linux/module.h>
15126 +#include <linux/init.h>
15127 +#include <linux/slab.h>
15128 +#include <linux/pagemap.h>
15129 +#include <linux/blkdev.h>
15130 +#include <linux/list.h>
15131 +#include <linux/buffer_head.h>
15132 +#include <linux/root_dev.h>
15133 +#include <linux/statfs.h>
15134 +#include <asm/uaccess.h>
15135 +#include "hostfs.h"
15136 +#include "kern_util.h"
15138 +#include "user_util.h"
15139 +#include "2_5compat.h"
15142 +struct hostfs_inode_info {
15143 + char *host_filename;
15146 + struct inode vfs_inode;
15149 +static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
15151 + return(list_entry(inode, struct hostfs_inode_info, vfs_inode));
15154 +#define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_dentry->d_inode)
15156 +int hostfs_d_delete(struct dentry *dentry)
15161 +struct dentry_operations hostfs_dentry_ops = {
15162 + .d_delete = hostfs_d_delete,
15165 +/* Changed in hostfs_args before the kernel starts running */
15166 +static char *root_ino = "/";
15167 +static int append = 0;
15169 +#define HOSTFS_SUPER_MAGIC 0x00c0ffee
15171 +static struct inode_operations hostfs_iops;
15172 +static struct inode_operations hostfs_dir_iops;
15173 +static struct address_space_operations hostfs_link_aops;
15175 +static int __init hostfs_args(char *options, int *add)
15179 + ptr = strchr(options, ',');
15182 + if(*options != '\0')
15183 + root_ino = options;
15187 + ptr = strchr(options, ',');
15190 + if(*options != '\0'){
15191 + if(!strcmp(options, "append"))
15193 + else printf("hostfs_args - unsupported option - %s\n",
15201 +__uml_setup("hostfs=", hostfs_args,
15202 +"hostfs=<root dir>,<flags>,...\n"
15203 +" This is used to set hostfs parameters. The root directory argument\n"
15204 +" is used to confine all hostfs mounts to within the specified directory\n"
15205 +" tree on the host. If this isn't specified, then a user inside UML can\n"
15206 +" mount anything on the host that's accessible to the user that's running\n"
15208 +" The only flag currently supported is 'append', which specifies that all\n"
15209 +" files opened by hostfs will be opened in append mode.\n\n"
15212 +static char *dentry_name(struct dentry *dentry, int extra)
15214 + struct dentry *parent;
15215 + char *root, *name;
15220 + while(parent->d_parent != parent){
15221 + len += parent->d_name.len + 1;
15222 + parent = parent->d_parent;
15225 + root = HOSTFS_I(parent->d_inode)->host_filename;
15226 + len += strlen(root);
15227 + name = kmalloc(len + extra + 1, GFP_KERNEL);
15228 + if(name == NULL) return(NULL);
15230 + name[len] = '\0';
15232 + while(parent->d_parent != parent){
15233 + len -= parent->d_name.len + 1;
15235 + strncpy(&name[len + 1], parent->d_name.name,
15236 + parent->d_name.len);
15237 + parent = parent->d_parent;
15239 + strncpy(name, root, strlen(root));
15243 +static char *inode_name(struct inode *ino, int extra)
15245 + struct dentry *dentry;
15247 + dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
15248 + return(dentry_name(dentry, extra));
15251 +static int read_name(struct inode *ino, char *name)
15253 + /* The non-int inode fields are copied into ints by stat_file and
15254 + * then copied into the inode because passing the actual pointers
15255 + * in and having them treated as int * breaks on big-endian machines
15258 + int i_mode, i_nlink, i_blksize;
15259 + unsigned long long i_size;
15260 + unsigned long long i_ino;
15261 + unsigned long long i_blocks;
15263 + err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid,
15264 + &ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime,
15265 + &ino->i_ctime, &i_blksize, &i_blocks);
15269 + ino->i_ino = i_ino;
15270 + ino->i_mode = i_mode;
15271 + ino->i_nlink = i_nlink;
15272 + ino->i_size = i_size;
15273 + ino->i_blksize = i_blksize;
15274 + ino->i_blocks = i_blocks;
15275 + if((ino->i_sb->s_dev == ROOT_DEV) && (ino->i_uid == getuid()))
15280 +static char *follow_link(char *link)
15283 + char *name, *resolved, *end;
15288 + name = kmalloc(len, GFP_KERNEL);
15292 + n = do_readlink(link, name, len);
15304 + end = strrchr(link, '/');
15308 + *(end + 1) = '\0';
15309 + len = strlen(link) + strlen(name) + 1;
15311 + resolved = kmalloc(len, GFP_KERNEL);
15312 + if(resolved == NULL){
15317 + sprintf(resolved, "%s%s", link, name);
15320 + return(resolved);
15325 + return(ERR_PTR(n));
15328 +static int read_inode(struct inode *ino)
15333 + /* Unfortunately, we are called from iget() when we don't have a dentry
15336 + if(list_empty(&ino->i_dentry))
15340 + name = inode_name(ino, 0);
15344 + if(file_type(name, NULL) == OS_TYPE_SYMLINK){
15345 + name = follow_link(name);
15346 + if(IS_ERR(name)){
15347 + err = PTR_ERR(name);
15352 + err = read_name(ino, name);
15358 +int hostfs_statfs(struct super_block *sb, struct kstatfs *sf)
15360 + /* do_statfs uses struct statfs64 internally, but the linux kernel
15361 + * struct statfs still has 32-bit versions for most of these fields,
15362 + * so we convert them here
15365 + long long f_blocks;
15366 + long long f_bfree;
15367 + long long f_bavail;
15368 + long long f_files;
15369 + long long f_ffree;
15371 + err = do_statfs(HOSTFS_I(sb->s_root->d_inode)->host_filename,
15372 + &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
15373 + &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid),
15374 + &sf->f_namelen, sf->f_spare);
15375 + if(err) return(err);
15376 + sf->f_blocks = f_blocks;
15377 + sf->f_bfree = f_bfree;
15378 + sf->f_bavail = f_bavail;
15379 + sf->f_files = f_files;
15380 + sf->f_ffree = f_ffree;
15381 + sf->f_type = HOSTFS_SUPER_MAGIC;
15385 +static struct inode *hostfs_alloc_inode(struct super_block *sb)
15387 + struct hostfs_inode_info *hi;
15389 + hi = kmalloc(sizeof(*hi), GFP_KERNEL);
15393 + *hi = ((struct hostfs_inode_info) { .host_filename = NULL,
15396 + inode_init_once(&hi->vfs_inode);
15397 + return(&hi->vfs_inode);
15400 +static void hostfs_destroy_inode(struct inode *inode)
15402 + if(HOSTFS_I(inode)->host_filename)
15403 + kfree(HOSTFS_I(inode)->host_filename);
15405 + if(HOSTFS_I(inode)->fd != -1)
15406 + close_file(&HOSTFS_I(inode)->fd);
15408 + kfree(HOSTFS_I(inode));
15411 +static void hostfs_read_inode(struct inode *inode)
15413 + read_inode(inode);
15416 +static struct super_operations hostfs_sbops = {
15417 + .alloc_inode = hostfs_alloc_inode,
15418 + .destroy_inode = hostfs_destroy_inode,
15419 + .read_inode = hostfs_read_inode,
15420 + .statfs = hostfs_statfs,
15423 +int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
15427 + unsigned long long next, ino;
15430 + name = dentry_name(file->f_dentry, 0);
15431 + if(name == NULL) return(-ENOMEM);
15432 + dir = open_dir(name, &error);
15434 + if(dir == NULL) return(-error);
15435 + next = file->f_pos;
15436 + while((name = read_dir(dir, &next, &ino, &len)) != NULL){
15437 + error = (*filldir)(ent, name, len, file->f_pos,
15438 + ino, DT_UNKNOWN);
15440 + file->f_pos = next;
15446 +int hostfs_file_open(struct inode *ino, struct file *file)
15449 + int mode = 0, r = 0, w = 0, fd;
15451 + mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
15452 + if((mode & HOSTFS_I(ino)->mode) == mode)
15455 + /* The file may already have been opened, but with the wrong access,
15456 + * so this resets things and reopens the file with the new access.
15458 + if(HOSTFS_I(ino)->fd != -1){
15459 + close_file(&HOSTFS_I(ino)->fd);
15460 + HOSTFS_I(ino)->fd = -1;
15463 + HOSTFS_I(ino)->mode |= mode;
15464 + if(HOSTFS_I(ino)->mode & FMODE_READ)
15466 + if(HOSTFS_I(ino)->mode & FMODE_WRITE)
15471 + name = dentry_name(file->f_dentry, 0);
15475 + fd = open_file(name, r, w, append);
15477 + if(fd < 0) return(fd);
15478 + FILE_HOSTFS_I(file)->fd = fd;
15483 +int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
15488 +static struct file_operations hostfs_file_fops = {
15489 + .llseek = generic_file_llseek,
15490 + .read = generic_file_read,
15491 + .write = generic_file_write,
15492 + .mmap = generic_file_mmap,
15493 + .open = hostfs_file_open,
15495 + .fsync = hostfs_fsync,
15498 +static struct file_operations hostfs_dir_fops = {
15499 + .readdir = hostfs_readdir,
15500 + .read = generic_read_dir,
15503 +int hostfs_writepage(struct page *page, struct writeback_control *wbc)
15505 + struct address_space *mapping = page->mapping;
15506 + struct inode *inode = mapping->host;
15508 + unsigned long long base;
15509 + int count = PAGE_CACHE_SIZE;
15510 + int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
15513 + if (page->index >= end_index)
15514 + count = inode->i_size & (PAGE_CACHE_SIZE-1);
15516 + buffer = kmap(page);
15517 + base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
15519 + err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
15520 + if(err != count){
15521 + ClearPageUptodate(page);
15525 + if (base > inode->i_size)
15526 + inode->i_size = base;
15528 + if (PageError(page))
15529 + ClearPageError(page);
15535 + unlock_page(page);
15539 +int hostfs_readpage(struct file *file, struct page *page)
15545 + start = (long long) page->index << PAGE_CACHE_SHIFT;
15546 + buffer = kmap(page);
15547 + err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
15548 + PAGE_CACHE_SIZE);
15549 + if(err < 0) goto out;
15551 + memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
15553 + flush_dcache_page(page);
15554 + SetPageUptodate(page);
15555 + if (PageError(page)) ClearPageError(page);
15559 + unlock_page(page);
15563 +int hostfs_prepare_write(struct file *file, struct page *page,
15564 + unsigned int from, unsigned int to)
15567 + long long start, tmp;
15570 + start = (long long) page->index << PAGE_CACHE_SHIFT;
15571 + buffer = kmap(page);
15574 + err = read_file(FILE_HOSTFS_I(file)->fd, &tmp, buffer,
15576 + if(err < 0) goto out;
15578 + if(to != PAGE_CACHE_SIZE){
15580 + err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer + to,
15581 + PAGE_CACHE_SIZE - to);
15582 + if(err < 0) goto out;
15590 +int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
15593 + struct address_space *mapping = page->mapping;
15594 + struct inode *inode = mapping->host;
15599 + start = (long long) (page->index << PAGE_CACHE_SHIFT) + from;
15600 + buffer = kmap(page);
15601 + err = write_file(FILE_HOSTFS_I(file)->fd, &start, buffer + from,
15603 + if(err > 0) err = 0;
15604 + if(!err && (start > inode->i_size))
15605 + inode->i_size = start;
15611 +static struct address_space_operations hostfs_aops = {
15612 + .writepage = hostfs_writepage,
15613 + .readpage = hostfs_readpage,
15614 +/* .set_page_dirty = __set_page_dirty_nobuffers, */
15615 + .prepare_write = hostfs_prepare_write,
15616 + .commit_write = hostfs_commit_write
15619 +static int init_inode(struct inode *inode, struct dentry *dentry)
15622 + int type, err = -ENOMEM, rdev;
15625 + name = dentry_name(dentry, 0);
15628 + type = file_type(name, &rdev);
15631 + else type = OS_TYPE_DIR;
15634 + if(type == OS_TYPE_SYMLINK)
15635 + inode->i_op = &page_symlink_inode_operations;
15636 + else if(type == OS_TYPE_DIR)
15637 + inode->i_op = &hostfs_dir_iops;
15638 + else inode->i_op = &hostfs_iops;
15640 + if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
15641 + else inode->i_fop = &hostfs_file_fops;
15643 + if(type == OS_TYPE_SYMLINK)
15644 + inode->i_mapping->a_ops = &hostfs_link_aops;
15645 + else inode->i_mapping->a_ops = &hostfs_aops;
15648 + case OS_TYPE_CHARDEV:
15649 + init_special_inode(inode, S_IFCHR, rdev);
15651 + case OS_TYPE_BLOCKDEV:
15652 + init_special_inode(inode, S_IFBLK, rdev);
15654 + case OS_TYPE_FIFO:
15655 + init_special_inode(inode, S_IFIFO, 0);
15657 + case OS_TYPE_SOCK:
15658 + init_special_inode(inode, S_IFSOCK, 0);
15665 +int hostfs_create(struct inode *dir, struct dentry *dentry, int mode,
15666 + struct nameidata *nd)
15668 + struct inode *inode;
15673 + inode = iget(dir->i_sb, 0);
15674 + if(inode == NULL) goto out;
15676 + error = init_inode(inode, dentry);
15681 + name = dentry_name(dentry, 0);
15685 + fd = file_create(name,
15686 + mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR,
15687 + mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP,
15688 + mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
15691 + else error = read_name(inode, name);
15697 + HOSTFS_I(inode)->fd = fd;
15698 + HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
15699 + d_instantiate(dentry, inode);
15708 +struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
15709 + struct nameidata *nd)
15711 + struct inode *inode;
15716 + inode = iget(ino->i_sb, 0);
15717 + if(inode == NULL)
15720 + err = init_inode(inode, dentry);
15725 + name = dentry_name(dentry, 0);
15729 + err = read_name(inode, name);
15731 + if(err == -ENOENT){
15738 + d_add(dentry, inode);
15739 + dentry->d_op = &hostfs_dentry_ops;
15745 + return(ERR_PTR(err));
15748 +static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
15753 + file = inode_name(ino, dentry->d_name.len + 1);
15754 + if(file == NULL) return(NULL);
15755 + strcat(file, "/");
15756 + len = strlen(file);
15757 + strncat(file, dentry->d_name.name, dentry->d_name.len);
15758 + file[len + dentry->d_name.len] = '\0';
15762 +int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
15764 + char *from_name, *to_name;
15767 + if((from_name = inode_dentry_name(ino, from)) == NULL)
15769 + to_name = dentry_name(to, 0);
15770 + if(to_name == NULL){
15771 + kfree(from_name);
15774 + err = link_file(to_name, from_name);
15775 + kfree(from_name);
15780 +int hostfs_unlink(struct inode *ino, struct dentry *dentry)
15785 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
15789 + err = unlink_file(file);
15794 +int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
15799 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
15800 + err = make_symlink(file, to);
15805 +int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
15810 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
15811 + err = do_mkdir(file, mode);
15816 +int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
15821 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
15822 + err = do_rmdir(file);
15827 +int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
15829 + struct inode *inode;
15831 + int err = -ENOMEM;
15833 + inode = iget(dir->i_sb, 0);
15834 + if(inode == NULL)
15837 + err = init_inode(inode, dentry);
15842 + name = dentry_name(dentry, 0);
15846 + init_special_inode(inode, mode, dev);
15847 + err = do_mknod(name, mode, dev);
15851 + err = read_name(inode, name);
15856 + d_instantiate(dentry, inode);
15867 +int hostfs_rename(struct inode *from_ino, struct dentry *from,
15868 + struct inode *to_ino, struct dentry *to)
15870 + char *from_name, *to_name;
15873 + if((from_name = inode_dentry_name(from_ino, from)) == NULL)
15875 + if((to_name = inode_dentry_name(to_ino, to)) == NULL){
15876 + kfree(from_name);
15879 + err = rename_file(from_name, to_name);
15880 + kfree(from_name);
15885 +void hostfs_truncate(struct inode *ino)
15887 + not_implemented();
15890 +int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
15893 + int r = 0, w = 0, x = 0, err;
15895 + if(desired & MAY_READ) r = 1;
15896 + if(desired & MAY_WRITE) w = 1;
15897 + if(desired & MAY_EXEC) x = 1;
15898 + name = inode_name(ino, 0);
15899 + if(name == NULL) return(-ENOMEM);
15900 + err = access_file(name, r, w, x);
15902 + if(!err) err = vfs_permission(ino, desired);
15906 +int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
15908 + struct hostfs_iattr attrs;
15913 + attr->ia_valid &= ~ATTR_SIZE;
15915 + attrs.ia_valid = 0;
15916 + if(attr->ia_valid & ATTR_MODE){
15917 + attrs.ia_valid |= HOSTFS_ATTR_MODE;
15918 + attrs.ia_mode = attr->ia_mode;
15920 + if(attr->ia_valid & ATTR_UID){
15921 + if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) &&
15922 + (attr->ia_uid == 0))
15923 + attr->ia_uid = getuid();
15924 + attrs.ia_valid |= HOSTFS_ATTR_UID;
15925 + attrs.ia_uid = attr->ia_uid;
15927 + if(attr->ia_valid & ATTR_GID){
15928 + if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) &&
15929 + (attr->ia_gid == 0))
15930 + attr->ia_gid = getuid();
15931 + attrs.ia_valid |= HOSTFS_ATTR_GID;
15932 + attrs.ia_gid = attr->ia_gid;
15934 + if(attr->ia_valid & ATTR_SIZE){
15935 + attrs.ia_valid |= HOSTFS_ATTR_SIZE;
15936 + attrs.ia_size = attr->ia_size;
15938 + if(attr->ia_valid & ATTR_ATIME){
15939 + attrs.ia_valid |= HOSTFS_ATTR_ATIME;
15940 + attrs.ia_atime = attr->ia_atime;
15942 + if(attr->ia_valid & ATTR_MTIME){
15943 + attrs.ia_valid |= HOSTFS_ATTR_MTIME;
15944 + attrs.ia_mtime = attr->ia_mtime;
15946 + if(attr->ia_valid & ATTR_CTIME){
15947 + attrs.ia_valid |= HOSTFS_ATTR_CTIME;
15948 + attrs.ia_ctime = attr->ia_ctime;
15950 + if(attr->ia_valid & ATTR_ATIME_SET){
15951 + attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
15953 + if(attr->ia_valid & ATTR_MTIME_SET){
15954 + attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
15956 + name = dentry_name(dentry, 0);
15957 + if(name == NULL) return(-ENOMEM);
15958 + err = set_attr(name, &attrs);
15963 + return(inode_setattr(dentry->d_inode, attr));
15966 +int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
15967 + struct kstat *stat)
15969 + generic_fillattr(dentry->d_inode, stat);
15973 +static struct inode_operations hostfs_iops = {
15974 + .create = hostfs_create,
15975 + .link = hostfs_link,
15976 + .unlink = hostfs_unlink,
15977 + .symlink = hostfs_symlink,
15978 + .mkdir = hostfs_mkdir,
15979 + .rmdir = hostfs_rmdir,
15980 + .mknod = hostfs_mknod,
15981 + .rename = hostfs_rename,
15982 + .truncate = hostfs_truncate,
15983 + .permission = hostfs_permission,
15984 + .setattr = hostfs_setattr,
15985 + .getattr = hostfs_getattr,
15988 +static struct inode_operations hostfs_dir_iops = {
15989 + .create = hostfs_create,
15990 + .lookup = hostfs_lookup,
15991 + .link = hostfs_link,
15992 + .unlink = hostfs_unlink,
15993 + .symlink = hostfs_symlink,
15994 + .mkdir = hostfs_mkdir,
15995 + .rmdir = hostfs_rmdir,
15996 + .mknod = hostfs_mknod,
15997 + .rename = hostfs_rename,
15998 + .truncate = hostfs_truncate,
15999 + .permission = hostfs_permission,
16000 + .setattr = hostfs_setattr,
16001 + .getattr = hostfs_getattr,
16004 +int hostfs_link_readpage(struct file *file, struct page *page)
16006 + char *buffer, *name;
16010 + start = page->index << PAGE_CACHE_SHIFT;
16011 + buffer = kmap(page);
16012 + name = inode_name(page->mapping->host, 0);
16013 + if(name == NULL) return(-ENOMEM);
16014 + err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
16016 + if(err == PAGE_CACHE_SIZE)
16018 + else if(err > 0){
16019 + flush_dcache_page(page);
16020 + SetPageUptodate(page);
16021 + if (PageError(page)) ClearPageError(page);
16025 + unlock_page(page);
16029 +static struct address_space_operations hostfs_link_aops = {
16030 + .readpage = hostfs_link_readpage,
16033 +static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
16035 + struct inode *root_inode;
16036 + char *name, *data = d;
16039 + sb->s_blocksize = 1024;
16040 + sb->s_blocksize_bits = 10;
16041 + sb->s_magic = HOSTFS_SUPER_MAGIC;
16042 + sb->s_op = &hostfs_sbops;
16044 + if((data == NULL) || (*data == '\0'))
16048 + name = kmalloc(strlen(data) + 1, GFP_KERNEL);
16052 + strcpy(name, data);
16054 + root_inode = iget(sb, 0);
16055 + if(root_inode == NULL)
16058 + err = init_inode(root_inode, NULL);
16062 + HOSTFS_I(root_inode)->host_filename = name;
16065 + sb->s_root = d_alloc_root(root_inode);
16066 + if(sb->s_root == NULL)
16069 + err = read_inode(root_inode);
16076 + iput(root_inode);
16083 +static struct super_block *hostfs_read_sb(struct file_system_type *type,
16084 + int flags, const char *dev_name,
16087 + return(get_sb_nodev(type, flags, data, hostfs_fill_sb_common));
16090 +static struct file_system_type hostfs_type = {
16091 + .owner = THIS_MODULE,
16092 + .name = "hostfs",
16093 + .get_sb = hostfs_read_sb,
16094 + .kill_sb = kill_anon_super,
16098 +static int __init init_hostfs(void)
16100 + return(register_filesystem(&hostfs_type));
16103 +static void __exit exit_hostfs(void)
16105 + unregister_filesystem(&hostfs_type);
16108 +module_init(init_hostfs)
16109 +module_exit(exit_hostfs)
16110 +MODULE_LICENSE("GPL");
16113 + * Overrides for Emacs so that we follow Linus's tabbing style.
16114 + * Emacs will notice this stuff at the end of the file and automatically
16115 + * adjust the settings for this buffer only. This must remain at the end
16117 + * ---------------------------------------------------------------------------
16118 + * Local variables:
16119 + * c-file-style: "linux"
16122 diff -Naur a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
16123 --- a/fs/hostfs/hostfs_user.c 1969-12-31 19:00:00.000000000 -0500
16124 +++ b/fs/hostfs/hostfs_user.c 2004-02-11 12:26:11.000000000 -0500
16127 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16128 + * Licensed under the GPL
16131 +#include <unistd.h>
16132 +#include <stdio.h>
16133 +#include <fcntl.h>
16134 +#include <dirent.h>
16135 +#include <errno.h>
16136 +#include <utime.h>
16137 +#include <string.h>
16138 +#include <sys/stat.h>
16139 +#include <sys/time.h>
16140 +#include <sys/vfs.h>
16141 +#include "hostfs.h"
16142 +#include "kern_util.h"
16145 +int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
16146 + int *nlink_out, int *uid_out, int *gid_out,
16147 + unsigned long long *size_out, struct timespec *atime_out,
16148 + struct timespec *mtime_out, struct timespec *ctime_out,
16149 + int *blksize_out, unsigned long long *blocks_out)
16151 + struct stat64 buf;
16153 + if(lstat64(path, &buf) < 0)
16156 + /* See the Makefile for why STAT64_INO_FIELD is passed in
16159 + if(inode_out != NULL) *inode_out = buf.STAT64_INO_FIELD;
16160 + if(mode_out != NULL) *mode_out = buf.st_mode;
16161 + if(nlink_out != NULL) *nlink_out = buf.st_nlink;
16162 + if(uid_out != NULL) *uid_out = buf.st_uid;
16163 + if(gid_out != NULL) *gid_out = buf.st_gid;
16164 + if(size_out != NULL) *size_out = buf.st_size;
16165 + if(atime_out != NULL) {
16166 + atime_out->tv_sec = buf.st_atime;
16167 + atime_out->tv_nsec = 0;
16169 + if(mtime_out != NULL) {
16170 + mtime_out->tv_sec = buf.st_mtime;
16171 + mtime_out->tv_nsec = 0;
16173 + if(ctime_out != NULL) {
16174 + ctime_out->tv_sec = buf.st_ctime;
16175 + ctime_out->tv_nsec = 0;
16177 + if(blksize_out != NULL) *blksize_out = buf.st_blksize;
16178 + if(blocks_out != NULL) *blocks_out = buf.st_blocks;
16182 +int file_type(const char *path, int *rdev)
16184 + struct stat64 buf;
16186 + if(lstat64(path, &buf) < 0)
16189 + *rdev = buf.st_rdev;
16191 + if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
16192 + else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
16193 + else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
16194 + else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
16195 + else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO);
16196 + else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK);
16197 + else return(OS_TYPE_FILE);
16200 +int access_file(char *path, int r, int w, int x)
16204 + if(r) mode = R_OK;
16205 + if(w) mode |= W_OK;
16206 + if(x) mode |= X_OK;
16207 + if(access(path, mode) != 0) return(-errno);
16211 +int open_file(char *path, int r, int w, int append)
16213 + int mode = 0, fd;
16221 + else panic("Impossible mode in open_file");
16224 + mode |= O_APPEND;
16225 + fd = open64(path, mode);
16226 + if(fd < 0) return(-errno);
16230 +void *open_dir(char *path, int *err_out)
16234 + dir = opendir(path);
16235 + *err_out = errno;
16236 + if(dir == NULL) return(NULL);
16240 +char *read_dir(void *stream, unsigned long long *pos,
16241 + unsigned long long *ino_out, int *len_out)
16243 + DIR *dir = stream;
16244 + struct dirent *ent;
16246 + seekdir(dir, *pos);
16247 + ent = readdir(dir);
16248 + if(ent == NULL) return(NULL);
16249 + *len_out = strlen(ent->d_name);
16250 + *ino_out = ent->d_ino;
16251 + *pos = telldir(dir);
16252 + return(ent->d_name);
16255 +int read_file(int fd, unsigned long long *offset, char *buf, int len)
16259 + n = pread64(fd, buf, len, *offset);
16260 + if(n < 0) return(-errno);
16265 +int write_file(int fd, unsigned long long *offset, const char *buf, int len)
16269 + n = pwrite64(fd, buf, len, *offset);
16270 + if(n < 0) return(-errno);
16275 +int lseek_file(int fd, long long offset, int whence)
16279 + ret = lseek64(fd, offset, whence);
16280 + if(ret < 0) return(-errno);
16284 +void close_file(void *stream)
16286 + close(*((int *) stream));
16289 +void close_dir(void *stream)
16291 + closedir(stream);
16294 +int file_create(char *name, int ur, int uw, int ux, int gr,
16295 + int gw, int gx, int or, int ow, int ox)
16300 + mode |= ur ? S_IRUSR : 0;
16301 + mode |= uw ? S_IWUSR : 0;
16302 + mode |= ux ? S_IXUSR : 0;
16303 + mode |= gr ? S_IRGRP : 0;
16304 + mode |= gw ? S_IWGRP : 0;
16305 + mode |= gx ? S_IXGRP : 0;
16306 + mode |= or ? S_IROTH : 0;
16307 + mode |= ow ? S_IWOTH : 0;
16308 + mode |= ox ? S_IXOTH : 0;
16309 + fd = open64(name, O_CREAT | O_RDWR, mode);
16315 +int set_attr(const char *file, struct hostfs_iattr *attrs)
16317 + struct utimbuf buf;
16320 + if(attrs->ia_valid & HOSTFS_ATTR_MODE){
16321 + if(chmod(file, attrs->ia_mode) != 0) return(-errno);
16323 + if(attrs->ia_valid & HOSTFS_ATTR_UID){
16324 + if(chown(file, attrs->ia_uid, -1)) return(-errno);
16326 + if(attrs->ia_valid & HOSTFS_ATTR_GID){
16327 + if(chown(file, -1, attrs->ia_gid)) return(-errno);
16329 + if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
16330 + if(truncate(file, attrs->ia_size)) return(-errno);
16332 + ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET;
16333 + if((attrs->ia_valid & ma) == ma){
16334 + buf.actime = attrs->ia_atime.tv_sec;
16335 + buf.modtime = attrs->ia_mtime.tv_sec;
16336 + if(utime(file, &buf) != 0) return(-errno);
16339 + struct timespec ts;
16341 + if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){
16342 + err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
16343 + NULL, NULL, &ts, NULL, NULL, NULL);
16346 + buf.actime = attrs->ia_atime.tv_sec;
16347 + buf.modtime = ts.tv_sec;
16348 + if(utime(file, &buf) != 0)
16351 + if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){
16352 + err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
16353 + NULL, &ts, NULL, NULL, NULL, NULL);
16356 + buf.actime = ts.tv_sec;
16357 + buf.modtime = attrs->ia_mtime.tv_sec;
16358 + if(utime(file, &buf) != 0)
16362 + if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
16363 + if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
16364 + err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL,
16365 + &attrs->ia_atime, &attrs->ia_mtime, NULL,
16367 + if(err != 0) return(err);
16372 +int make_symlink(const char *from, const char *to)
16376 + err = symlink(to, from);
16377 + if(err) return(-errno);
16381 +int unlink_file(const char *file)
16385 + err = unlink(file);
16386 + if(err) return(-errno);
16390 +int do_mkdir(const char *file, int mode)
16394 + err = mkdir(file, mode);
16395 + if(err) return(-errno);
16399 +int do_rmdir(const char *file)
16403 + err = rmdir(file);
16404 + if(err) return(-errno);
16408 +int do_mknod(const char *file, int mode, int dev)
16412 + err = mknod(file, mode, dev);
16413 + if(err) return(-errno);
16417 +int link_file(const char *to, const char *from)
16421 + err = link(to, from);
16422 + if(err) return(-errno);
16426 +int do_readlink(char *file, char *buf, int size)
16430 + n = readlink(file, buf, size);
16438 +int rename_file(char *from, char *to)
16442 + err = rename(from, to);
16443 + if(err < 0) return(-errno);
16447 +int do_statfs(char *root, long *bsize_out, long long *blocks_out,
16448 + long long *bfree_out, long long *bavail_out,
16449 + long long *files_out, long long *ffree_out,
16450 + void *fsid_out, int fsid_size, long *namelen_out,
16453 + struct statfs64 buf;
16456 + err = statfs64(root, &buf);
16457 + if(err < 0) return(-errno);
16458 + *bsize_out = buf.f_bsize;
16459 + *blocks_out = buf.f_blocks;
16460 + *bfree_out = buf.f_bfree;
16461 + *bavail_out = buf.f_bavail;
16462 + *files_out = buf.f_files;
16463 + *ffree_out = buf.f_ffree;
16464 + memcpy(fsid_out, &buf.f_fsid,
16465 + sizeof(buf.f_fsid) > fsid_size ? fsid_size :
16466 + sizeof(buf.f_fsid));
16467 + *namelen_out = buf.f_namelen;
16468 + spare_out[0] = buf.f_spare[0];
16469 + spare_out[1] = buf.f_spare[1];
16470 + spare_out[2] = buf.f_spare[2];
16471 + spare_out[3] = buf.f_spare[3];
16472 + spare_out[4] = buf.f_spare[4];
16473 + spare_out[5] = buf.f_spare[5];
16478 + * Overrides for Emacs so that we follow Linus's tabbing style.
16479 + * Emacs will notice this stuff at the end of the file and automatically
16480 + * adjust the settings for this buffer only. This must remain at the end
16482 + * ---------------------------------------------------------------------------
16483 + * Local variables:
16484 + * c-file-style: "linux"
16487 diff -Naur a/fs/hostfs/Makefile b/fs/hostfs/Makefile
16488 --- a/fs/hostfs/Makefile 1969-12-31 19:00:00.000000000 -0500
16489 +++ b/fs/hostfs/Makefile 2004-02-11 12:25:42.000000000 -0500
16492 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16493 +# Licensed under the GPL
16496 +# struct stat64 changed the inode field name between 2.2 and 2.4 from st_ino
16497 +# to __st_ino. It stayed in the same place, so as long as the correct name
16498 +# is used, hostfs compiled on 2.2 should work on 2.4 and vice versa.
16500 +STAT64_INO_FIELD := $(shell grep -q __st_ino /usr/include/bits/stat.h && \
16503 +hostfs-objs := hostfs_kern.o hostfs_user.o
16506 +obj-$(CONFIG_HOSTFS) += hostfs.o
16508 +SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
16510 +USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(SINGLE_OBJS))
16511 +USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
16513 +USER_CFLAGS += -DSTAT64_INO_FIELD=$(STAT64_INO_FIELD)
16515 +$(USER_OBJS) : %.o: %.c
16516 + $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
16517 diff -Naur a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
16518 --- a/fs/hppfs/hppfs_kern.c 1969-12-31 19:00:00.000000000 -0500
16519 +++ b/fs/hppfs/hppfs_kern.c 2004-02-11 12:27:10.000000000 -0500
16522 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16523 + * Licensed under the GPL
16526 +#include <linux/fs.h>
16527 +#include <linux/module.h>
16528 +#include <linux/init.h>
16529 +#include <linux/slab.h>
16530 +#include <linux/list.h>
16531 +#include <linux/kernel.h>
16532 +#include <linux/ctype.h>
16533 +#include <linux/dcache.h>
16534 +#include <linux/statfs.h>
16535 +#include <asm/uaccess.h>
16536 +#include <asm/fcntl.h>
16539 +static int init_inode(struct inode *inode, struct dentry *dentry);
16541 +struct hppfs_data {
16542 + struct list_head list;
16543 + char contents[PAGE_SIZE - sizeof(struct list_head)];
16546 +struct hppfs_private {
16547 + struct file proc_file;
16550 + struct hppfs_data *contents;
16553 +struct hppfs_inode_info {
16554 + struct dentry *proc_dentry;
16555 + struct inode vfs_inode;
16558 +static inline struct hppfs_inode_info *HPPFS_I(struct inode *inode)
16560 + return(list_entry(inode, struct hppfs_inode_info, vfs_inode));
16563 +#define HPPFS_SUPER_MAGIC 0xb00000ee
16565 +static struct super_operations hppfs_sbops;
16567 +static int is_pid(struct dentry *dentry)
16569 + struct super_block *sb;
16572 + sb = dentry->d_sb;
16573 + if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
16576 + for(i = 0; i < dentry->d_name.len; i++){
16577 + if(!isdigit(dentry->d_name.name[i]))
16583 +static char *dentry_name(struct dentry *dentry, int extra)
16585 + struct dentry *parent;
16586 + char *root, *name;
16587 + const char *seg_name;
16588 + int len, seg_len;
16592 + while(parent->d_parent != parent){
16593 + if(is_pid(parent))
16594 + len += strlen("pid") + 1;
16595 + else len += parent->d_name.len + 1;
16596 + parent = parent->d_parent;
16600 + len += strlen(root);
16601 + name = kmalloc(len + extra + 1, GFP_KERNEL);
16602 + if(name == NULL) return(NULL);
16604 + name[len] = '\0';
16606 + while(parent->d_parent != parent){
16607 + if(is_pid(parent)){
16608 + seg_name = "pid";
16609 + seg_len = strlen("pid");
16612 + seg_name = parent->d_name.name;
16613 + seg_len = parent->d_name.len;
16616 + len -= seg_len + 1;
16618 + strncpy(&name[len + 1], seg_name, seg_len);
16619 + parent = parent->d_parent;
16621 + strncpy(name, root, strlen(root));
16625 +struct dentry_operations hppfs_dentry_ops = {
16628 +static int file_removed(struct dentry *dentry, const char *file)
16634 + if(file != NULL) extra += strlen(file) + 1;
16636 + host_file = dentry_name(dentry, extra + strlen("/remove"));
16637 + if(host_file == NULL){
16638 + printk("file_removed : allocation failed\n");
16642 + if(file != NULL){
16643 + strcat(host_file, "/");
16644 + strcat(host_file, file);
16646 + strcat(host_file, "/remove");
16648 + fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
16649 + kfree(host_file);
16651 + os_close_file(fd);
16657 +static void hppfs_read_inode(struct inode *ino)
16659 + struct inode *proc_ino;
16661 + if(HPPFS_I(ino)->proc_dentry == NULL)
16664 + proc_ino = HPPFS_I(ino)->proc_dentry->d_inode;
16665 + ino->i_uid = proc_ino->i_uid;
16666 + ino->i_gid = proc_ino->i_gid;
16667 + ino->i_atime = proc_ino->i_atime;
16668 + ino->i_mtime = proc_ino->i_mtime;
16669 + ino->i_ctime = proc_ino->i_ctime;
16670 + ino->i_ino = proc_ino->i_ino;
16671 + ino->i_mode = proc_ino->i_mode;
16672 + ino->i_nlink = proc_ino->i_nlink;
16673 + ino->i_size = proc_ino->i_size;
16674 + ino->i_blksize = proc_ino->i_blksize;
16675 + ino->i_blocks = proc_ino->i_blocks;
16678 +static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry,
16679 + struct nameidata *nd)
16681 + struct dentry *proc_dentry, *new, *parent;
16682 + struct inode *inode;
16683 + int err, deleted;
16685 + deleted = file_removed(dentry, NULL);
16687 + return(ERR_PTR(deleted));
16689 + return(ERR_PTR(-ENOENT));
16692 + parent = HPPFS_I(ino)->proc_dentry;
16693 + down(&parent->d_inode->i_sem);
16694 + proc_dentry = d_lookup(parent, &dentry->d_name);
16695 + if(proc_dentry == NULL){
16696 + proc_dentry = d_alloc(parent, &dentry->d_name);
16697 + if(proc_dentry == NULL){
16698 + up(&parent->d_inode->i_sem);
16701 + new = (*parent->d_inode->i_op->lookup)(parent->d_inode,
16702 + proc_dentry, NULL);
16704 + dput(proc_dentry);
16705 + proc_dentry = new;
16708 + up(&parent->d_inode->i_sem);
16710 + if(IS_ERR(proc_dentry))
16711 + return(proc_dentry);
16713 + inode = iget(ino->i_sb, 0);
16714 + if(inode == NULL)
16717 + err = init_inode(inode, proc_dentry);
16721 + hppfs_read_inode(inode);
16723 + d_add(dentry, inode);
16724 + dentry->d_op = &hppfs_dentry_ops;
16730 + dput(proc_dentry);
16732 + return(ERR_PTR(err));
16735 +static struct inode_operations hppfs_file_iops = {
16738 +static ssize_t read_proc(struct file *file, char *buf, ssize_t count,
16739 + loff_t *ppos, int is_user)
16741 + ssize_t (*read)(struct file *, char *, size_t, loff_t *);
16744 + read = file->f_dentry->d_inode->i_fop->read;
16747 + set_fs(KERNEL_DS);
16749 + n = (*read)(file, buf, count, &file->f_pos);
16754 + if(ppos) *ppos = file->f_pos;
16758 +static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
16765 + new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
16766 + if(new_buf == NULL){
16767 + printk("hppfs_read_file : kmalloc failed\n");
16771 + while(count > 0){
16772 + cur = min_t(ssize_t, count, PAGE_SIZE);
16773 + err = os_read_file(fd, new_buf, cur);
16775 + printk("hppfs_read : read failed, errno = %d\n",
16780 + else if(err == 0)
16783 + if(copy_to_user(buf, new_buf, err)){
16796 +static ssize_t hppfs_read(struct file *file, char *buf, size_t count,
16799 + struct hppfs_private *hppfs = file->private_data;
16800 + struct hppfs_data *data;
16804 + if(hppfs->contents != NULL){
16805 + if(*ppos >= hppfs->len) return(0);
16807 + data = hppfs->contents;
16809 + while(off >= sizeof(data->contents)){
16810 + data = list_entry(data->list.next, struct hppfs_data,
16812 + off -= sizeof(data->contents);
16815 + if(off + count > hppfs->len)
16816 + count = hppfs->len - off;
16817 + copy_to_user(buf, &data->contents[off], count);
16820 + else if(hppfs->host_fd != -1){
16821 + err = os_seek_file(hppfs->host_fd, *ppos);
16823 + printk("hppfs_read : seek failed, errno = %d\n", err);
16826 + count = hppfs_read_file(hppfs->host_fd, buf, count);
16830 + else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1);
16835 +static ssize_t hppfs_write(struct file *file, const char *buf, size_t len,
16838 + struct hppfs_private *data = file->private_data;
16839 + struct file *proc_file = &data->proc_file;
16840 + ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
16843 + write = proc_file->f_dentry->d_inode->i_fop->write;
16845 + proc_file->f_pos = file->f_pos;
16846 + err = (*write)(proc_file, buf, len, &proc_file->f_pos);
16847 + file->f_pos = proc_file->f_pos;
16852 +static int open_host_sock(char *host_file, int *filter_out)
16857 + end = &host_file[strlen(host_file)];
16858 + strcpy(end, "/rw");
16860 + fd = os_connect_socket(host_file);
16864 + strcpy(end, "/r");
16866 + fd = os_connect_socket(host_file);
16870 +static void free_contents(struct hppfs_data *head)
16872 + struct hppfs_data *data;
16873 + struct list_head *ele, *next;
16875 + if(head == NULL) return;
16877 + list_for_each_safe(ele, next, &head->list){
16878 + data = list_entry(ele, struct hppfs_data, list);
16884 +static struct hppfs_data *hppfs_get_data(int fd, int filter,
16885 + struct file *proc_file,
16886 + struct file *hppfs_file,
16887 + loff_t *size_out)
16889 + struct hppfs_data *data, *new, *head;
16893 + data = kmalloc(sizeof(*data), GFP_KERNEL);
16894 + if(data == NULL){
16895 + printk("hppfs_get_data : head allocation failed\n");
16899 + INIT_LIST_HEAD(&data->list);
16905 + while((n = read_proc(proc_file, data->contents,
16906 + sizeof(data->contents), NULL, 0)) > 0)
16907 + os_write_file(fd, data->contents, n);
16908 + err = os_shutdown_socket(fd, 0, 1);
16910 + printk("hppfs_get_data : failed to shut down "
16912 + goto failed_free;
16916 + n = os_read_file(fd, data->contents, sizeof(data->contents));
16919 + printk("hppfs_get_data : read failed, errno = %d\n",
16921 + goto failed_free;
16928 + if(n < sizeof(data->contents))
16931 + new = kmalloc(sizeof(*data), GFP_KERNEL);
16933 + printk("hppfs_get_data : data allocation failed\n");
16935 + goto failed_free;
16938 + INIT_LIST_HEAD(&new->list);
16939 + list_add(&new->list, &data->list);
16945 + free_contents(head);
16947 + return(ERR_PTR(err));
16950 +static struct hppfs_private *hppfs_data(void)
16952 + struct hppfs_private *data;
16954 + data = kmalloc(sizeof(*data), GFP_KERNEL);
16958 + *data = ((struct hppfs_private ) { .host_fd = -1,
16960 + .contents = NULL } );
16964 +static int file_mode(int fmode)
16966 + if(fmode == (FMODE_READ | FMODE_WRITE))
16968 + if(fmode == FMODE_READ)
16969 + return(O_RDONLY);
16970 + if(fmode == FMODE_WRITE)
16971 + return(O_WRONLY);
16975 +static int hppfs_open(struct inode *inode, struct file *file)
16977 + struct hppfs_private *data;
16978 + struct dentry *proc_dentry;
16980 + int err, fd, type, filter;
16983 + data = hppfs_data();
16987 + host_file = dentry_name(file->f_dentry, strlen("/rw"));
16988 + if(host_file == NULL)
16991 + proc_dentry = HPPFS_I(inode)->proc_dentry;
16993 + /* XXX This isn't closed anywhere */
16994 + err = open_private_file(&data->proc_file, proc_dentry,
16995 + file_mode(file->f_mode));
16999 + type = os_file_type(host_file);
17000 + if(type == OS_TYPE_FILE){
17001 + fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
17003 + data->host_fd = fd;
17004 + else printk("hppfs_open : failed to open '%s', errno = %d\n",
17007 + data->contents = NULL;
17009 + else if(type == OS_TYPE_DIR){
17010 + fd = open_host_sock(host_file, &filter);
17012 + data->contents = hppfs_get_data(fd, filter,
17013 + &data->proc_file,
17014 + file, &data->len);
17015 + if(!IS_ERR(data->contents))
17016 + data->host_fd = fd;
17018 + else printk("hppfs_open : failed to open a socket in "
17019 + "'%s', errno = %d\n", host_file, -fd);
17021 + kfree(host_file);
17023 + file->private_data = data;
17027 + kfree(host_file);
17029 + free_contents(data->contents);
17035 +static int hppfs_dir_open(struct inode *inode, struct file *file)
17037 + struct hppfs_private *data;
17038 + struct dentry *proc_dentry;
17042 + data = hppfs_data();
17046 + proc_dentry = HPPFS_I(inode)->proc_dentry;
17047 + err = open_private_file(&data->proc_file, proc_dentry,
17048 + file_mode(file->f_mode));
17052 + file->private_data = data;
17061 +static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
17063 + struct hppfs_private *data = file->private_data;
17064 + struct file *proc_file = &data->proc_file;
17065 + loff_t (*llseek)(struct file *, loff_t, int);
17068 + llseek = proc_file->f_dentry->d_inode->i_fop->llseek;
17069 + if(llseek != NULL){
17070 + ret = (*llseek)(proc_file, off, where);
17075 + return(default_llseek(file, off, where));
17078 +static struct file_operations hppfs_file_fops = {
17080 + .llseek = hppfs_llseek,
17081 + .read = hppfs_read,
17082 + .write = hppfs_write,
17083 + .open = hppfs_open,
17086 +struct hppfs_dirent {
17087 + void *vfs_dirent;
17088 + filldir_t filldir;
17089 + struct dentry *dentry;
17092 +static int hppfs_filldir(void *d, const char *name, int size,
17093 + loff_t offset, ino_t inode, unsigned int type)
17095 + struct hppfs_dirent *dirent = d;
17097 + if(file_removed(dirent->dentry, name))
17100 + return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset,
17104 +static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
17106 + struct hppfs_private *data = file->private_data;
17107 + struct file *proc_file = &data->proc_file;
17108 + int (*readdir)(struct file *, void *, filldir_t);
17109 + struct hppfs_dirent dirent = ((struct hppfs_dirent)
17110 + { .vfs_dirent = ent,
17111 + .filldir = filldir,
17112 + .dentry = file->f_dentry } );
17115 + readdir = proc_file->f_dentry->d_inode->i_fop->readdir;
17117 + proc_file->f_pos = file->f_pos;
17118 + err = (*readdir)(proc_file, &dirent, hppfs_filldir);
17119 + file->f_pos = proc_file->f_pos;
17124 +static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
17129 +static struct file_operations hppfs_dir_fops = {
17131 + .readdir = hppfs_readdir,
17132 + .open = hppfs_dir_open,
17133 + .fsync = hppfs_fsync,
17136 +static int hppfs_statfs(struct super_block *sb, struct kstatfs *sf)
17138 + sf->f_blocks = 0;
17140 + sf->f_bavail = 0;
17143 + sf->f_type = HPPFS_SUPER_MAGIC;
17147 +static struct inode *hppfs_alloc_inode(struct super_block *sb)
17149 + struct hppfs_inode_info *hi;
17151 + hi = kmalloc(sizeof(*hi), GFP_KERNEL);
17155 + *hi = ((struct hppfs_inode_info) { .proc_dentry = NULL });
17156 + inode_init_once(&hi->vfs_inode);
17157 + return(&hi->vfs_inode);
17160 +void hppfs_delete_inode(struct inode *ino)
17162 + clear_inode(ino);
17165 +static void hppfs_destroy_inode(struct inode *inode)
17167 + kfree(HPPFS_I(inode));
17170 +static struct super_operations hppfs_sbops = {
17171 + .alloc_inode = hppfs_alloc_inode,
17172 + .destroy_inode = hppfs_destroy_inode,
17173 + .read_inode = hppfs_read_inode,
17174 + .delete_inode = hppfs_delete_inode,
17175 + .statfs = hppfs_statfs,
17178 +static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen)
17180 + struct file proc_file;
17181 + struct dentry *proc_dentry;
17182 + int (*readlink)(struct dentry *, char *, int);
17185 + proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
17186 + err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
17190 + readlink = proc_dentry->d_inode->i_op->readlink;
17191 + n = (*readlink)(proc_dentry, buffer, buflen);
17193 + close_private_file(&proc_file);
17198 +static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
17200 + struct file proc_file;
17201 + struct dentry *proc_dentry;
17202 + int (*follow_link)(struct dentry *, struct nameidata *);
17205 + proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
17206 + err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
17210 + follow_link = proc_dentry->d_inode->i_op->follow_link;
17211 + n = (*follow_link)(proc_dentry, nd);
17213 + close_private_file(&proc_file);
17218 +static struct inode_operations hppfs_dir_iops = {
17219 + .lookup = hppfs_lookup,
17222 +static struct inode_operations hppfs_link_iops = {
17223 + .readlink = hppfs_readlink,
17224 + .follow_link = hppfs_follow_link,
17227 +static int init_inode(struct inode *inode, struct dentry *dentry)
17229 + if(S_ISDIR(dentry->d_inode->i_mode)){
17230 + inode->i_op = &hppfs_dir_iops;
17231 + inode->i_fop = &hppfs_dir_fops;
17233 + else if(S_ISLNK(dentry->d_inode->i_mode)){
17234 + inode->i_op = &hppfs_link_iops;
17235 + inode->i_fop = &hppfs_file_fops;
17238 + inode->i_op = &hppfs_file_iops;
17239 + inode->i_fop = &hppfs_file_fops;
17242 + HPPFS_I(inode)->proc_dentry = dentry;
17247 +static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
17249 + struct inode *root_inode;
17250 + struct file_system_type *procfs;
17251 + struct super_block *proc_sb;
17255 + procfs = get_fs_type("proc");
17256 + if(procfs == NULL)
17259 + if(list_empty(&procfs->fs_supers))
17262 + proc_sb = list_entry(procfs->fs_supers.next, struct super_block,
17265 + sb->s_blocksize = 1024;
17266 + sb->s_blocksize_bits = 10;
17267 + sb->s_magic = HPPFS_SUPER_MAGIC;
17268 + sb->s_op = &hppfs_sbops;
17270 + root_inode = iget(sb, 0);
17271 + if(root_inode == NULL)
17274 + err = init_inode(root_inode, proc_sb->s_root);
17279 + sb->s_root = d_alloc_root(root_inode);
17280 + if(sb->s_root == NULL)
17283 + hppfs_read_inode(root_inode);
17288 + iput(root_inode);
17293 +static struct super_block *hppfs_read_super(struct file_system_type *type,
17294 + int flags, const char *dev_name,
17297 + return(get_sb_nodev(type, flags, data, hppfs_fill_super));
17300 +static struct file_system_type hppfs_type = {
17301 + .owner = THIS_MODULE,
17303 + .get_sb = hppfs_read_super,
17304 + .kill_sb = kill_anon_super,
17308 +static int __init init_hppfs(void)
17310 + return(register_filesystem(&hppfs_type));
17313 +static void __exit exit_hppfs(void)
17315 + unregister_filesystem(&hppfs_type);
17318 +module_init(init_hppfs)
17319 +module_exit(exit_hppfs)
17320 +MODULE_LICENSE("GPL");
17323 + * Overrides for Emacs so that we follow Linus's tabbing style.
17324 + * Emacs will notice this stuff at the end of the file and automatically
17325 + * adjust the settings for this buffer only. This must remain at the end
17327 + * ---------------------------------------------------------------------------
17328 + * Local variables:
17329 + * c-file-style: "linux"
17332 diff -Naur a/fs/hppfs/Makefile b/fs/hppfs/Makefile
17333 --- a/fs/hppfs/Makefile 1969-12-31 19:00:00.000000000 -0500
17334 +++ b/fs/hppfs/Makefile 2004-02-11 12:27:35.000000000 -0500
17337 +# Copyright (C) 2002, 2003 Jeff Dike (jdike@karaya.com)
17338 +# Licensed under the GPL
17341 +hppfs-objs := hppfs_kern.o
17344 +obj-$(CONFIG_HPPFS) += hppfs.o
17354 +archmrproper: clean
17355 diff -Naur a/fs/Makefile b/fs/Makefile
17356 --- a/fs/Makefile 2004-02-11 12:15:52.000000000 -0500
17357 +++ b/fs/Makefile 2004-02-11 12:27:45.000000000 -0500
17359 obj-$(CONFIG_XFS_FS) += xfs/
17360 obj-$(CONFIG_AFS_FS) += afs/
17361 obj-$(CONFIG_BEFS_FS) += befs/
17362 +obj-$(CONFIG_HOSTFS) += hostfs/
17363 +obj-$(CONFIG_HPPFS) += hppfs/
17364 diff -Naur a/include/asm-um/archparam-i386.h b/include/asm-um/archparam-i386.h
17365 --- a/include/asm-um/archparam-i386.h 2004-02-11 12:16:32.000000000 -0500
17366 +++ b/include/asm-um/archparam-i386.h 2004-02-11 12:28:31.000000000 -0500
17369 - * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
17370 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
17371 * Licensed under the GPL
17375 pr_reg[16] = PT_REGS_SS(regs); \
17378 +#if 0 /* Turn this back on when UML has VSYSCALL working */
17379 +#define VSYSCALL_BASE (__fix_to_virt(FIX_VSYSCALL))
17381 +#define VSYSCALL_BASE NULL
17384 +#define VSYSCALL_EHDR ((const struct elfhdr *) VSYSCALL_BASE)
17385 +#define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
17386 +extern void *__kernel_vsyscall;
17389 + * Architecture-neutral AT_ values in 0-17, leave some room
17390 + * for more of them, start the x86-specific ones at 32.
17392 +#define AT_SYSINFO 32
17393 +#define AT_SYSINFO_EHDR 33
17395 +#define ARCH_DLINFO \
17397 + NEW_AUX_ENT(AT_SYSINFO, VSYSCALL_ENTRY); \
17398 + NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE); \
17402 + * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
17403 + * extra segments containing the vsyscall DSO contents. Dumping its
17404 + * contents makes post-mortem fully interpretable later without matching up
17405 + * the same kernel and hardware config to see what PC values meant.
17406 + * Dumping its extra ELF program headers includes all the other information
17407 + * a debugger needs to easily find how the vsyscall DSO was being used.
17409 +#define ELF_CORE_EXTRA_PHDRS (VSYSCALL_EHDR->e_phnum)
17410 +#define ELF_CORE_WRITE_EXTRA_PHDRS \
17412 + const struct elf_phdr *const vsyscall_phdrs = \
17413 + (const struct elf_phdr *) (VSYSCALL_BASE \
17414 + + VSYSCALL_EHDR->e_phoff); \
17416 + Elf32_Off ofs = 0; \
17417 + for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) { \
17418 + struct elf_phdr phdr = vsyscall_phdrs[i]; \
17419 + if (phdr.p_type == PT_LOAD) { \
17420 + ofs = phdr.p_offset = offset; \
17421 + offset += phdr.p_filesz; \
17424 + phdr.p_offset += ofs; \
17425 + phdr.p_paddr = 0; /* match other core phdrs */ \
17426 + DUMP_WRITE(&phdr, sizeof(phdr)); \
17429 +#define ELF_CORE_WRITE_EXTRA_DATA \
17431 + const struct elf_phdr *const vsyscall_phdrs = \
17432 + (const struct elf_phdr *) (VSYSCALL_BASE \
17433 + + VSYSCALL_EHDR->e_phoff); \
17435 + for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) { \
17436 + if (vsyscall_phdrs[i].p_type == PT_LOAD) \
17437 + DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr, \
17438 + vsyscall_phdrs[i].p_filesz); \
17442 +#define R_386_NONE 0
17443 +#define R_386_32 1
17444 +#define R_386_PC32 2
17445 +#define R_386_GOT32 3
17446 +#define R_386_PLT32 4
17447 +#define R_386_COPY 5
17448 +#define R_386_GLOB_DAT 6
17449 +#define R_386_JMP_SLOT 7
17450 +#define R_386_RELATIVE 8
17451 +#define R_386_GOTOFF 9
17452 +#define R_386_GOTPC 10
17453 +#define R_386_NUM 11
17455 /********* Bits for asm-um/delay.h **********/
17457 typedef unsigned long um_udelay_t;
17458 diff -Naur a/include/asm-um/common.lds.S b/include/asm-um/common.lds.S
17459 --- a/include/asm-um/common.lds.S 2004-02-11 12:14:28.000000000 -0500
17460 +++ b/include/asm-um/common.lds.S 2004-02-11 12:26:11.000000000 -0500
17462 +#include <asm-generic/vmlinux.lds.h>
17464 .fini : { *(.fini) } =0x9090
17466 PROVIDE (etext = .);
17471 - __start___ksymtab = .; /* Kernel symbol table */
17472 - __ksymtab : { *(__ksymtab) }
17473 - __stop___ksymtab = .;
17475 - __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only symbols */
17476 - __gpl_ksymtab : { *(__gpl_ksymtab) }
17477 - __stop___gpl_ksymtab = .;
17479 - __start___kallsyms = .; /* All kernel symbols */
17480 - __kallsyms : { *(__kallsyms) }
17481 - __stop___kallsyms = .;
17483 .unprotected : { *(.unprotected) }
17485 PROVIDE (_unprotected_end = .);
17486 @@ -67,11 +57,17 @@
17488 __initcall_end = .;
17490 + __con_initcall_start = .;
17491 + .con_initcall.init : { *(.con_initcall.init) }
17492 + __con_initcall_end = .;
17494 __uml_initcall_start = .;
17495 .uml.initcall.init : { *(.uml.initcall.init) }
17496 __uml_initcall_end = .;
17501 __exitcall_begin = .;
17502 .exitcall : { *(.exitcall.exit) }
17503 __exitcall_end = .;
17505 .uml.exitcall : { *(.uml.exitcall.exit) }
17506 __uml_exitcall_end = .;
17510 + __alt_instructions = .;
17511 + .altinstructions : { *(.altinstructions) }
17512 + __alt_instructions_end = .;
17513 + .altinstr_replacement : { *(.altinstr_replacement) }
17514 + /* .exit.text is discard at runtime, not link time, to deal with references
17515 + from .altinstructions and .eh_frame */
17516 + .exit.text : { *(.exit.text) }
17517 + .exit.data : { *(.exit.data) }
17519 + __preinit_array_start = .;
17520 + .preinit_array : { *(.preinit_array) }
17521 + __preinit_array_end = .;
17522 + __init_array_start = .;
17523 + .init_array : { *(.init_array) }
17524 + __init_array_end = .;
17525 + __fini_array_start = .;
17526 + .fini_array : { *(.fini_array) }
17527 + __fini_array_end = .;
17530 __initramfs_start = .;
17531 .init.ramfs : { *(.init.ramfs) }
17532 __initramfs_end = .;
17534 + /* Sections to be discarded */
17536 + *(.exitcall.exit)
17539 diff -Naur a/include/asm-um/cpufeature.h b/include/asm-um/cpufeature.h
17540 --- a/include/asm-um/cpufeature.h 1969-12-31 19:00:00.000000000 -0500
17541 +++ b/include/asm-um/cpufeature.h 2004-02-11 12:25:42.000000000 -0500
17543 +#ifndef __UM_CPUFEATURE_H
17544 +#define __UM_CPUFEATURE_H
17546 +#include "asm/arch/cpufeature.h"
17549 diff -Naur a/include/asm-um/current.h b/include/asm-um/current.h
17550 --- a/include/asm-um/current.h 2004-02-11 12:14:18.000000000 -0500
17551 +++ b/include/asm-um/current.h 2004-02-11 12:26:01.000000000 -0500
17553 #define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & \
17554 (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
17556 -#define current ({ int dummy; \
17557 - ((struct thread_info *) CURRENT_THREAD(dummy))->task; })
17558 +#define current_thread \
17559 + ({ int dummy; ((struct thread_info *) CURRENT_THREAD(dummy)); })
17561 +#define current (current_thread->task)
17563 #endif /* __ASSEMBLY__ */
17565 diff -Naur a/include/asm-um/elf.h b/include/asm-um/elf.h
17566 --- a/include/asm-um/elf.h 2004-02-11 12:16:01.000000000 -0500
17567 +++ b/include/asm-um/elf.h 2004-02-11 12:27:55.000000000 -0500
17570 #define USE_ELF_CORE_DUMP
17572 +#define R_386_NONE 0
17573 +#define R_386_32 1
17574 +#define R_386_PC32 2
17575 +#define R_386_GOT32 3
17576 +#define R_386_PLT32 4
17577 +#define R_386_COPY 5
17578 +#define R_386_GLOB_DAT 6
17579 +#define R_386_JMP_SLOT 7
17580 +#define R_386_RELATIVE 8
17581 +#define R_386_GOTOFF 9
17582 +#define R_386_GOTPC 10
17583 +#define R_386_NUM 11
17586 diff -Naur a/include/asm-um/fixmap.h b/include/asm-um/fixmap.h
17587 --- a/include/asm-um/fixmap.h 2004-02-11 12:16:42.000000000 -0500
17588 +++ b/include/asm-um/fixmap.h 2004-02-11 12:28:41.000000000 -0500
17590 FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
17591 FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
17594 __end_of_fixed_addresses
17598 #define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
17599 #define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
17602 + * This is the range that is readable by user mode, and things
17603 + * acting like user mode such as get_user_pages.
17605 +#define FIXADDR_USER_START (__fix_to_virt(FIX_VSYSCALL))
17606 +#define FIXADDR_USER_END (FIXADDR_USER_START + PAGE_SIZE)
17608 extern void __this_fixmap_does_not_exist(void);
17611 diff -Naur a/include/asm-um/irq.h b/include/asm-um/irq.h
17612 --- a/include/asm-um/irq.h 2004-02-11 12:17:06.000000000 -0500
17613 +++ b/include/asm-um/irq.h 2004-02-11 12:29:07.000000000 -0500
17618 -/* The i386 irq.h has a struct task_struct in a prototype without including
17619 - * sched.h. This forward declaration kills the resulting warning.
17621 -struct task_struct;
17623 -#include "asm/ptrace.h"
17627 #define TIMER_IRQ 0
17629 #define CONSOLE_IRQ 2
17631 #define LAST_IRQ XTERM_IRQ
17632 #define NR_IRQS (LAST_IRQ + 1)
17634 -extern int um_request_irq(unsigned int irq, int fd, int type,
17635 - void (*handler)(int, void *, struct pt_regs *),
17636 - unsigned long irqflags, const char * devname,
17639 diff -Naur a/include/asm-um/local.h b/include/asm-um/local.h
17640 --- a/include/asm-um/local.h 1969-12-31 19:00:00.000000000 -0500
17641 +++ b/include/asm-um/local.h 2004-02-11 12:27:52.000000000 -0500
17643 +#ifndef __UM_LOCAL_H
17644 +#define __UM_LOCAL_H
17646 +#include "asm/arch/local.h"
17649 diff -Naur a/include/asm-um/module-generic.h b/include/asm-um/module-generic.h
17650 --- a/include/asm-um/module-generic.h 1969-12-31 19:00:00.000000000 -0500
17651 +++ b/include/asm-um/module-generic.h 2004-02-11 12:27:42.000000000 -0500
17653 +#ifndef __UM_MODULE_GENERIC_H
17654 +#define __UM_MODULE_GENERIC_H
17656 +#include "asm/arch/module.h"
17659 diff -Naur a/include/asm-um/module-i386.h b/include/asm-um/module-i386.h
17660 --- a/include/asm-um/module-i386.h 1969-12-31 19:00:00.000000000 -0500
17661 +++ b/include/asm-um/module-i386.h 2004-02-11 12:27:42.000000000 -0500
17663 +#ifndef __UM_MODULE_I386_H
17664 +#define __UM_MODULE_I386_H
17666 +/* UML is simple */
17667 +struct mod_arch_specific
17671 +#define Elf_Shdr Elf32_Shdr
17672 +#define Elf_Sym Elf32_Sym
17673 +#define Elf_Ehdr Elf32_Ehdr
17676 diff -Naur a/include/asm-um/page.h b/include/asm-um/page.h
17677 --- a/include/asm-um/page.h 2004-02-11 12:15:52.000000000 -0500
17678 +++ b/include/asm-um/page.h 2004-02-11 12:27:45.000000000 -0500
17681 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
17682 + * Licensed under the GPL
17685 #ifndef __UM_PAGE_H
17686 #define __UM_PAGE_H
17690 #include "asm/arch/page.h"
17691 -#include "asm/bug.h"
17695 @@ -24,25 +28,36 @@
17697 #define __va_space (8*1024*1024)
17699 -extern unsigned long region_pa(void *virt);
17700 -extern void *region_va(unsigned long phys);
17702 -#define __pa(virt) region_pa((void *) (virt))
17703 -#define __va(phys) region_va((unsigned long) (phys))
17705 -extern unsigned long page_to_pfn(struct page *page);
17706 -extern struct page *pfn_to_page(unsigned long pfn);
17707 +extern unsigned long to_phys(void *virt);
17708 +extern void *to_virt(unsigned long phys);
17710 -extern struct page *phys_to_page(unsigned long phys);
17711 +#define __pa(virt) to_phys((void *) virt)
17712 +#define __va(phys) to_virt((unsigned long) phys)
17714 -#define virt_to_page(v) (phys_to_page(__pa(v)))
17715 +#define page_to_pfn(page) ((page) - mem_map)
17716 +#define pfn_to_page(pfn) (mem_map + (pfn))
17718 -extern struct page *page_mem_map(struct page *page);
17719 +#define phys_to_pfn(p) ((p) >> PAGE_SHIFT)
17720 +#define pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)
17722 -#define pfn_valid(pfn) (page_mem_map(pfn_to_page(pfn)) != NULL)
17723 -#define virt_addr_valid(v) pfn_valid(__pa(v) >> PAGE_SHIFT)
17724 +#define pfn_valid(pfn) ((pfn) < max_mapnr)
17725 +#define virt_addr_valid(v) pfn_valid(phys_to_pfn(__pa(v)))
17727 extern struct page *arch_validate(struct page *page, int mask, int order);
17728 #define HAVE_ARCH_VALIDATE
17730 +extern void arch_free_page(struct page *page, int order);
17731 +#define HAVE_ARCH_FREE_PAGE
17736 + * Overrides for Emacs so that we follow Linus's tabbing style.
17737 + * Emacs will notice this stuff at the end of the file and automatically
17738 + * adjust the settings for this buffer only. This must remain at the end
17740 + * ---------------------------------------------------------------------------
17741 + * Local variables:
17742 + * c-file-style: "linux"
17745 diff -Naur a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h
17746 --- a/include/asm-um/pgtable.h 2004-02-11 12:17:12.000000000 -0500
17747 +++ b/include/asm-um/pgtable.h 2004-02-11 12:29:17.000000000 -0500
17749 #include "asm/page.h"
17750 #include "asm/fixmap.h"
17752 -extern pgd_t swapper_pg_dir[1024];
17754 extern void *um_virt_to_phys(struct task_struct *task, unsigned long virt,
17758 #define pgd_ERROR(e) \
17759 printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
17761 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
17764 * pgd entries used up by user/kernel:
17766 @@ -65,10 +65,10 @@
17767 * area for the same reason. ;)
17770 -extern unsigned long high_physmem;
17771 +extern unsigned long end_iomem;
17773 #define VMALLOC_OFFSET (__va_space)
17774 -#define VMALLOC_START (((unsigned long) high_physmem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
17775 +#define VMALLOC_START ((end_iomem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
17777 #ifdef CONFIG_HIGHMEM
17778 # define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
17779 @@ -78,12 +78,13 @@
17781 #define _PAGE_PRESENT 0x001
17782 #define _PAGE_NEWPAGE 0x002
17783 -#define _PAGE_PROTNONE 0x004 /* If not present */
17784 -#define _PAGE_RW 0x008
17785 -#define _PAGE_USER 0x010
17786 -#define _PAGE_ACCESSED 0x020
17787 -#define _PAGE_DIRTY 0x040
17788 -#define _PAGE_NEWPROT 0x080
17789 +#define _PAGE_NEWPROT 0x004
17790 +#define _PAGE_FILE 0x008 /* set:pagecache unset:swap */
17791 +#define _PAGE_PROTNONE 0x010 /* If not present */
17792 +#define _PAGE_RW 0x020
17793 +#define _PAGE_USER 0x040
17794 +#define _PAGE_ACCESSED 0x080
17795 +#define _PAGE_DIRTY 0x100
17797 #define REGION_MASK 0xf0000000
17798 #define REGION_SHIFT 28
17799 @@ -143,7 +144,8 @@
17801 #define BAD_PAGETABLE __bad_pagetable()
17802 #define BAD_PAGE __bad_page()
17803 -#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
17805 +#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
17807 /* number of bits that fit into a memory pointer */
17808 #define BITS_PER_PTR (8*sizeof(unsigned long))
17809 @@ -164,9 +166,6 @@
17811 #define pte_clear(xp) do { pte_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
17813 -#define phys_region_index(x) (((x) & REGION_MASK) >> REGION_SHIFT)
17814 -#define pte_region_index(x) phys_region_index(pte_val(x))
17816 #define pmd_none(x) (!(pmd_val(x) & ~_PAGE_NEWPAGE))
17817 #define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
17818 #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
17819 @@ -188,19 +187,25 @@
17821 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
17823 -extern struct page *pte_mem_map(pte_t pte);
17824 -extern struct page *phys_mem_map(unsigned long phys);
17825 -extern unsigned long phys_to_pfn(unsigned long p);
17826 -extern unsigned long pfn_to_phys(unsigned long pfn);
17828 -#define pte_page(x) pfn_to_page(pte_pfn(x))
17829 -#define pte_address(x) (__va(pte_val(x) & PAGE_MASK))
17830 -#define mk_phys(a, r) ((a) + (r << REGION_SHIFT))
17831 -#define phys_addr(p) ((p) & ~REGION_MASK)
17832 -#define phys_page(p) (phys_mem_map(p) + ((phys_addr(p)) >> PAGE_SHIFT))
17833 +#define pte_page(pte) phys_to_page(pte_val(pte))
17834 +#define pmd_page(pmd) phys_to_page(pmd_val(pmd) & PAGE_MASK)
17836 #define pte_pfn(x) phys_to_pfn(pte_val(x))
17837 #define pfn_pte(pfn, prot) __pte(pfn_to_phys(pfn) | pgprot_val(prot))
17838 -#define pfn_pmd(pfn, prot) __pmd(pfn_to_phys(pfn) | pgprot_val(prot))
17840 +extern struct page *phys_to_page(const unsigned long phys);
17841 +extern struct page *__virt_to_page(const unsigned long virt);
17842 +#define virt_to_page(addr) __virt_to_page((const unsigned long) addr)
17845 + * Bits 0 through 3 are taken
17847 +#define PTE_FILE_MAX_BITS 28
17849 +#define pte_to_pgoff(pte) ((pte).pte_low >> 4)
17851 +#define pgoff_to_pte(off) \
17852 + ((pte_t) { ((off) << 4) + _PAGE_FILE })
17854 static inline pte_t pte_mknewprot(pte_t pte)
17856 @@ -235,6 +240,12 @@
17857 * The following only work if pte_present() is true.
17858 * Undefined behaviour if not..
17860 +static inline int pte_user(pte_t pte)
17862 + return((pte_val(pte) & _PAGE_USER) &&
17863 + !(pte_val(pte) & _PAGE_PROTNONE));
17866 static inline int pte_read(pte_t pte)
17868 return((pte_val(pte) & _PAGE_USER) &&
17869 @@ -252,6 +263,14 @@
17870 !(pte_val(pte) & _PAGE_PROTNONE));
17874 + * The following only works if pte_present() is not true.
17876 +static inline int pte_file(pte_t pte)
17878 + return (pte).pte_low & _PAGE_FILE;
17881 static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
17882 static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
17883 static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; }
17884 @@ -334,14 +353,7 @@
17885 * and a page entry and page directory to the page they refer to.
17888 -#define mk_pte(page, pgprot) \
17892 - pte_val(__pte) = page_to_phys(page) + pgprot_val(pgprot);\
17893 - if(pte_present(__pte)) pte_mknewprot(pte_mknewpage(__pte)); \
17896 +extern pte_t mk_pte(struct page *page, pgprot_t pgprot);
17898 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
17900 @@ -351,17 +363,27 @@
17903 #define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
17904 -#define pmd_page(pmd) (phys_mem_map(pmd_val(pmd) & PAGE_MASK) + \
17905 - ((phys_addr(pmd_val(pmd)) >> PAGE_SHIFT)))
17907 -/* to find an entry in a page-table-directory. */
17909 + * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
17911 + * this macro returns the index of the entry in the pgd page which would
17912 + * control the given virtual address
17914 #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
17916 -/* to find an entry in a page-table-directory */
17918 + * pgd_offset() returns a (pgd_t *)
17919 + * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
17921 #define pgd_offset(mm, address) \
17922 ((mm)->pgd + ((address) >> PGDIR_SHIFT))
17924 -/* to find an entry in a kernel page-table-directory */
17927 + * a shortcut which implies the use of the kernel's pgd, instead
17930 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
17932 #define pmd_index(address) \
17933 @@ -373,7 +395,12 @@
17934 return (pmd_t *) dir;
17937 -/* Find an entry in the third-level page table.. */
17939 + * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
17941 + * this macro returns the index of the entry in the pte page which would
17942 + * control the given virtual address
17944 #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
17945 #define pte_offset_kernel(dir, address) \
17946 ((pte_t *) pmd_page_kernel(*(dir)) + pte_index(address))
17947 @@ -399,11 +426,11 @@
17948 #define update_mmu_cache(vma,address,pte) do ; while (0)
17950 /* Encode and de-code a swap entry */
17951 -#define __swp_type(x) (((x).val >> 3) & 0x7f)
17952 -#define __swp_offset(x) ((x).val >> 10)
17953 +#define __swp_type(x) (((x).val >> 4) & 0x3f)
17954 +#define __swp_offset(x) ((x).val >> 11)
17956 #define __swp_entry(type, offset) \
17957 - ((swp_entry_t) { ((type) << 3) | ((offset) << 10) })
17958 + ((swp_entry_t) { ((type) << 4) | ((offset) << 11) })
17959 #define __pte_to_swp_entry(pte) \
17960 ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
17961 #define __swp_entry_to_pte(x) ((pte_t) { (x).val })
17962 diff -Naur a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h
17963 --- a/include/asm-um/processor-generic.h 2004-02-11 12:14:28.000000000 -0500
17964 +++ b/include/asm-um/processor-generic.h 2004-02-11 12:26:10.000000000 -0500
17966 struct task_struct;
17968 #include "linux/config.h"
17969 -#include "linux/signal.h"
17970 #include "asm/ptrace.h"
17971 -#include "asm/siginfo.h"
17972 #include "choose-mode.h"
17977 #define cpu_relax() do ; while (0)
17979 -#ifdef CONFIG_MODE_TT
17980 -struct proc_tt_mode {
17983 - int switch_pipe[2];
17984 - int singlestep_syscall;
17989 -#ifdef CONFIG_MODE_SKAS
17990 -struct proc_skas_mode {
17991 - void *switch_buf;
17996 struct thread_struct {
17998 unsigned long kernel_stack;
18000 struct pt_regs regs;
18003 + unsigned long trap_no;
18005 void *fault_catcher;
18006 struct task_struct *prev_sched;
18007 @@ -54,10 +36,20 @@
18008 struct arch_thread arch;
18010 #ifdef CONFIG_MODE_TT
18011 - struct proc_tt_mode tt;
18015 + int switch_pipe[2];
18016 + int singlestep_syscall;
18020 #ifdef CONFIG_MODE_SKAS
18021 - struct proc_skas_mode skas;
18023 + void *switch_buf;
18030 @@ -101,14 +93,19 @@
18033 extern struct task_struct *alloc_task_struct(void);
18034 -extern void free_task_struct(struct task_struct *task);
18036 extern void release_thread(struct task_struct *);
18037 extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
18038 extern void dump_thread(struct pt_regs *regs, struct user *u);
18039 +extern void prepare_to_copy(struct task_struct *tsk);
18041 extern unsigned long thread_saved_pc(struct task_struct *t);
18043 +static inline void mm_copy_segments(struct mm_struct *from_mm,
18044 + struct mm_struct *new_mm)
18048 #define init_stack (init_thread_union.stack)
18051 diff -Naur a/include/asm-um/processor-i386.h b/include/asm-um/processor-i386.h
18052 --- a/include/asm-um/processor-i386.h 2004-02-11 12:14:17.000000000 -0500
18053 +++ b/include/asm-um/processor-i386.h 2004-02-11 12:26:00.000000000 -0500
18055 #ifndef __UM_PROCESSOR_I386_H
18056 #define __UM_PROCESSOR_I386_H
18058 -extern int cpu_has_xmm;
18059 -extern int cpu_has_cmov;
18060 +extern int host_has_xmm;
18061 +extern int host_has_cmov;
18063 struct arch_thread {
18064 unsigned long debugregs[8];
18065 diff -Naur a/include/asm-um/sections.h b/include/asm-um/sections.h
18066 --- a/include/asm-um/sections.h 1969-12-31 19:00:00.000000000 -0500
18067 +++ b/include/asm-um/sections.h 2004-02-11 12:27:57.000000000 -0500
18069 +#ifndef _UM_SECTIONS_H
18070 +#define _UM_SECTIONS_H
18072 +/* nothing to see, move along */
18073 +#include <asm-generic/sections.h>
18076 diff -Naur a/include/asm-um/smp.h b/include/asm-um/smp.h
18077 --- a/include/asm-um/smp.h 2004-02-11 12:14:12.000000000 -0500
18078 +++ b/include/asm-um/smp.h 2004-02-11 12:25:41.000000000 -0500
18081 extern cpumask_t cpu_online_map;
18083 -#define smp_processor_id() (current->thread_info->cpu)
18084 +#define smp_processor_id() (current_thread->cpu)
18085 #define cpu_logical_map(n) (n)
18086 #define cpu_number_map(n) (n)
18087 #define PROC_CHANGE_PENALTY 15 /* Pick a number, any number */
18088 diff -Naur a/include/asm-um/smplock.h b/include/asm-um/smplock.h
18089 --- a/include/asm-um/smplock.h 2004-02-11 12:14:27.000000000 -0500
18090 +++ b/include/asm-um/smplock.h 1969-12-31 19:00:00.000000000 -0500
18092 -#ifndef __UM_SMPLOCK_H
18093 -#define __UM_SMPLOCK_H
18095 -#include "asm/arch/smplock.h"
18098 diff -Naur a/include/asm-um/spinlock.h b/include/asm-um/spinlock.h
18099 --- a/include/asm-um/spinlock.h 2004-02-11 12:16:39.000000000 -0500
18100 +++ b/include/asm-um/spinlock.h 1969-12-31 19:00:00.000000000 -0500
18102 -#ifndef __UM_SPINLOCK_H
18103 -#define __UM_SPINLOCK_H
18105 -#include "linux/config.h"
18108 -#include "asm/arch/spinlock.h"
18112 diff -Naur a/include/asm-um/system-generic.h b/include/asm-um/system-generic.h
18113 --- a/include/asm-um/system-generic.h 2004-02-11 12:17:08.000000000 -0500
18114 +++ b/include/asm-um/system-generic.h 2004-02-11 12:29:12.000000000 -0500
18116 extern void block_signals(void);
18117 extern void unblock_signals(void);
18119 -#define local_save_flags(flags) do { (flags) = get_signals(); } while(0)
18120 -#define local_irq_restore(flags) do { set_signals(flags); } while(0)
18121 +#define local_save_flags(flags) do { typecheck(unsigned long, flags); \
18122 + (flags) = get_signals(); } while(0)
18123 +#define local_irq_restore(flags) do { typecheck(unsigned long, flags); \
18124 + set_signals(flags); } while(0)
18126 #define local_irq_save(flags) do { local_save_flags(flags); \
18127 local_irq_disable(); } while(0)
18132 +extern void *_switch_to(void *prev, void *next, void *last);
18133 +#define switch_to(prev, next, last) prev = _switch_to(prev, next, last)
18136 diff -Naur a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h
18137 --- a/include/asm-um/thread_info.h 2004-02-11 12:14:39.000000000 -0500
18138 +++ b/include/asm-um/thread_info.h 2004-02-11 12:26:45.000000000 -0500
18140 #ifndef __ASSEMBLY__
18142 #include <asm/processor.h>
18143 +#include <asm/types.h>
18145 struct thread_info {
18146 struct task_struct *task; /* main task structure */
18147 @@ -43,15 +44,18 @@
18148 static inline struct thread_info *current_thread_info(void)
18150 struct thread_info *ti;
18151 - __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~16383UL));
18152 + unsigned long mask = PAGE_SIZE *
18153 + (1 << CONFIG_KERNEL_STACK_ORDER) - 1;
18154 + __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~mask));
18158 /* thread information allocation */
18159 -#define THREAD_SIZE (4*PAGE_SIZE)
18160 -#define alloc_thread_info(tsk) ((struct thread_info *) \
18161 - __get_free_pages(GFP_KERNEL,2))
18162 -#define free_thread_info(ti) free_pages((unsigned long) (ti), 2)
18163 +#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
18164 +#define alloc_thread_info(tsk) \
18165 + ((struct thread_info *) kmalloc(THREAD_SIZE, GFP_KERNEL))
18166 +#define free_thread_info(ti) kfree(ti)
18168 #define get_thread_info(ti) get_task_struct((ti)->task)
18169 #define put_thread_info(ti) put_task_struct((ti)->task)
18171 @@ -65,11 +69,13 @@
18172 #define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling
18175 +#define TIF_RESTART_BLOCK 4
18177 #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
18178 #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
18179 #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
18180 #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
18181 +#define _TIF_RESTART_BLOCK (1 << TIF_RESTART_BLOCK)
18185 diff -Naur a/include/asm-um/timex.h b/include/asm-um/timex.h
18186 --- a/include/asm-um/timex.h 2004-02-11 12:16:00.000000000 -0500
18187 +++ b/include/asm-um/timex.h 2004-02-11 12:27:53.000000000 -0500
18189 #ifndef __UM_TIMEX_H
18190 #define __UM_TIMEX_H
18192 -#include "linux/time.h"
18194 typedef unsigned long cycles_t;
18196 #define cacheflush_time (0)
18197 diff -Naur a/include/asm-um/uaccess.h b/include/asm-um/uaccess.h
18198 --- a/include/asm-um/uaccess.h 2004-02-11 12:16:04.000000000 -0500
18199 +++ b/include/asm-um/uaccess.h 2004-02-11 12:28:00.000000000 -0500
18201 #ifndef __UM_UACCESS_H
18202 #define __UM_UACCESS_H
18204 +#include "linux/sched.h"
18206 #define VERIFY_READ 0
18207 #define VERIFY_WRITE 1
18209 diff -Naur a/include/asm-um/unistd.h b/include/asm-um/unistd.h
18210 --- a/include/asm-um/unistd.h 2004-02-11 12:16:33.000000000 -0500
18211 +++ b/include/asm-um/unistd.h 2004-02-11 12:28:32.000000000 -0500
18213 set_fs(KERNEL_DS); \
18219 + errno = -(long)ret; \
18222 static inline long open(const char *pathname, int flags, int mode)
18224 diff -Naur a/include/linux/gfp.h b/include/linux/gfp.h
18225 --- a/include/linux/gfp.h 2004-02-11 12:14:33.000000000 -0500
18226 +++ b/include/linux/gfp.h 2004-02-11 12:26:16.000000000 -0500
18228 * For the normal case of non-DISCONTIGMEM systems the NODE_DATA() gets
18229 * optimized to &contig_page_data at compile-time.
18232 +#ifndef HAVE_ARCH_FREE_PAGE
18233 +static inline void arch_free_page(struct page *page, int order) { }
18236 extern struct page * FASTCALL(__alloc_pages(unsigned int, unsigned int, struct zonelist *));
18237 static inline struct page * alloc_pages_node(int nid, unsigned int gfp_mask, unsigned int order)
18239 diff -Naur a/include/linux/ghash.h b/include/linux/ghash.h
18240 --- a/include/linux/ghash.h 1969-12-31 19:00:00.000000000 -0500
18241 +++ b/include/linux/ghash.h 2004-02-11 12:26:13.000000000 -0500
18244 + * include/linux/ghash.h -- generic hashing with fuzzy retrieval
18246 + * (C) 1997 Thomas Schoebel-Theuer
18248 + * The algorithms implemented here seem to be a completely new invention,
18249 + * and I'll publish the fundamentals in a paper.
18254 +/* HASHSIZE _must_ be a power of two!!! */
18257 +#define DEF_HASH_FUZZY_STRUCTS(NAME,HASHSIZE,TYPE) \
18259 +struct NAME##_table {\
18260 + TYPE * hashtable[HASHSIZE];\
18261 + TYPE * sorted_list;\
18265 +struct NAME##_ptrs {\
18266 + TYPE * next_hash;\
18267 + TYPE * prev_hash;\
18268 + TYPE * next_sorted;\
18269 + TYPE * prev_sorted;\
18272 +#define DEF_HASH_FUZZY(LINKAGE,NAME,HASHSIZE,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,KEYEQ,HASHFN)\
18274 +LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
18276 + int ix = HASHFN(elem->KEY);\
18277 + TYPE ** base = &tbl->hashtable[ix];\
18278 + TYPE * ptr = *base;\
18279 + TYPE * prev = NULL;\
18281 + tbl->nr_entries++;\
18282 + while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\
18283 + base = &ptr->PTRS.next_hash;\
18287 + elem->PTRS.next_hash = ptr;\
18288 + elem->PTRS.prev_hash = prev;\
18290 + ptr->PTRS.prev_hash = elem;\
18296 + ptr = tbl->sorted_list;\
18299 + prev = ptr->PTRS.prev_sorted;\
18302 + TYPE * next = ptr->PTRS.next_hash;\
18303 + if(next && KEYCMP(next->KEY, elem->KEY)) {\
18306 + } else if(KEYCMP(ptr->KEY, elem->KEY)) {\
18308 + ptr = ptr->PTRS.next_sorted;\
18312 + elem->PTRS.next_sorted = ptr;\
18313 + elem->PTRS.prev_sorted = prev;\
18315 + ptr->PTRS.prev_sorted = elem;\
18318 + prev->PTRS.next_sorted = elem;\
18320 + tbl->sorted_list = elem;\
18324 +LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
18326 + TYPE * next = elem->PTRS.next_hash;\
18327 + TYPE * prev = elem->PTRS.prev_hash;\
18329 + tbl->nr_entries--;\
18331 + next->PTRS.prev_hash = prev;\
18333 + prev->PTRS.next_hash = next;\
18335 + int ix = HASHFN(elem->KEY);\
18336 + tbl->hashtable[ix] = next;\
18339 + next = elem->PTRS.next_sorted;\
18340 + prev = elem->PTRS.prev_sorted;\
18342 + next->PTRS.prev_sorted = prev;\
18344 + prev->PTRS.next_sorted = next;\
18346 + tbl->sorted_list = next;\
18349 +LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
18351 + int ix = hashfn(pos);\
18352 + TYPE * ptr = tbl->hashtable[ix];\
18353 + while(ptr && KEYCMP(ptr->KEY, pos))\
18354 + ptr = ptr->PTRS.next_hash;\
18355 + if(ptr && !KEYEQ(ptr->KEY, pos))\
18360 +LINKAGE TYPE * find_##NAME##_hash_fuzzy(struct NAME##_table * tbl, KEYTYPE pos)\
18367 + ptr = tbl->sorted_list;\
18368 + if(!ptr || KEYCMP(pos, ptr->KEY))\
18370 + ix = HASHFN(pos);\
18371 + offset = HASHSIZE;\
18374 + next = tbl->hashtable[(ix+offset) & ((HASHSIZE)-1)];\
18375 + if(next && (KEYCMP(next->KEY, pos) || KEYEQ(next->KEY, pos))\
18376 + && KEYCMP(ptr->KEY, next->KEY))\
18378 + } while(offset);\
18381 + next = ptr->PTRS.next_hash;\
18383 + if(KEYCMP(next->KEY, pos)) {\
18388 + next = ptr->PTRS.next_sorted;\
18389 + if(next && KEYCMP(next->KEY, pos)) {\
18398 +/* LINKAGE - empty or "static", depending on whether you want the definitions to
18399 + * be public or not
18400 + * NAME - a string to stick in names to make this hash table type distinct from
18402 + * HASHSIZE - number of buckets
18403 + * TYPE - type of data contained in the buckets - must be a structure, one
18404 + * field is of type NAME_ptrs, another is the hash key
18405 + * PTRS - TYPE must contain a field of type NAME_ptrs, PTRS is the name of that
18407 + * KEYTYPE - type of the key field within TYPE
18408 + * KEY - name of the key field within TYPE
18409 + * KEYCMP - pointer to function that compares KEYTYPEs to each other - the
18410 + * prototype is int KEYCMP(KEYTYPE, KEYTYPE), it returns zero for equal,
18411 + * non-zero for not equal
18412 + * HASHFN - the hash function - the prototype is int HASHFN(KEYTYPE),
18413 + * it returns a number in the range 0 ... HASHSIZE - 1
18414 + * Call DEF_HASH_STRUCTS, define your hash table as a NAME_table, then call
18418 +#define DEF_HASH_STRUCTS(NAME,HASHSIZE,TYPE) \
18420 +struct NAME##_table {\
18421 + TYPE * hashtable[HASHSIZE];\
18425 +struct NAME##_ptrs {\
18426 + TYPE * next_hash;\
18427 + TYPE * prev_hash;\
18430 +#define DEF_HASH(LINKAGE,NAME,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,HASHFN)\
18432 +LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
18434 + int ix = HASHFN(elem->KEY);\
18435 + TYPE ** base = &tbl->hashtable[ix];\
18436 + TYPE * ptr = *base;\
18437 + TYPE * prev = NULL;\
18439 + tbl->nr_entries++;\
18440 + while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\
18441 + base = &ptr->PTRS.next_hash;\
18445 + elem->PTRS.next_hash = ptr;\
18446 + elem->PTRS.prev_hash = prev;\
18448 + ptr->PTRS.prev_hash = elem;\
18453 +LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
18455 + TYPE * next = elem->PTRS.next_hash;\
18456 + TYPE * prev = elem->PTRS.prev_hash;\
18458 + tbl->nr_entries--;\
18460 + next->PTRS.prev_hash = prev;\
18462 + prev->PTRS.next_hash = next;\
18464 + int ix = HASHFN(elem->KEY);\
18465 + tbl->hashtable[ix] = next;\
18469 +LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
18471 + int ix = HASHFN(pos);\
18472 + TYPE * ptr = tbl->hashtable[ix];\
18473 + while(ptr && KEYCMP(ptr->KEY, pos))\
18474 + ptr = ptr->PTRS.next_hash;\
18479 diff -Naur a/include/linux/mm.h b/include/linux/mm.h
18480 --- a/include/linux/mm.h 2004-02-11 12:14:17.000000000 -0500
18481 +++ b/include/linux/mm.h 2004-02-11 12:26:00.000000000 -0500
18482 @@ -507,6 +507,9 @@
18483 return __set_page_dirty_buffers(page);
18486 +extern long do_mprotect(struct mm_struct *mm, unsigned long start,
18487 + size_t len, unsigned long prot);
18490 * On a two-level page table, this ends up being trivial. Thus the
18491 * inlining and the symmetry break with pte_alloc_map() that does all
18492 @@ -537,9 +540,10 @@
18494 extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
18496 -extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
18497 - unsigned long len, unsigned long prot,
18498 - unsigned long flag, unsigned long pgoff);
18499 +extern unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file *file,
18500 + unsigned long addr, unsigned long len,
18501 + unsigned long prot, unsigned long flag,
18502 + unsigned long pgoff);
18504 static inline unsigned long do_mmap(struct file *file, unsigned long addr,
18505 unsigned long len, unsigned long prot,
18506 @@ -549,7 +553,8 @@
18507 if ((offset + PAGE_ALIGN(len)) < offset)
18509 if (!(offset & ~PAGE_MASK))
18510 - ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
18511 + ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag,
18512 + offset >> PAGE_SHIFT);
18516 diff -Naur a/include/linux/proc_mm.h b/include/linux/proc_mm.h
18517 --- a/include/linux/proc_mm.h 1969-12-31 19:00:00.000000000 -0500
18518 +++ b/include/linux/proc_mm.h 2004-02-11 12:25:40.000000000 -0500
18521 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18522 + * Licensed under the GPL
18525 +#ifndef __PROC_MM_H
18526 +#define __PROC_MM_H
18528 +#include "linux/sched.h"
18530 +#define MM_MMAP 54
18531 +#define MM_MUNMAP 55
18532 +#define MM_MPROTECT 56
18533 +#define MM_COPY_SEGMENTS 57
18536 + unsigned long addr;
18537 + unsigned long len;
18538 + unsigned long prot;
18539 + unsigned long flags;
18540 + unsigned long fd;
18541 + unsigned long offset;
18544 +struct mm_munmap {
18545 + unsigned long addr;
18546 + unsigned long len;
18549 +struct mm_mprotect {
18550 + unsigned long addr;
18551 + unsigned long len;
18552 + unsigned int prot;
18555 +struct proc_mm_op {
18558 + struct mm_mmap mmap;
18559 + struct mm_munmap munmap;
18560 + struct mm_mprotect mprotect;
18561 + int copy_segments;
18565 +extern struct mm_struct *proc_mm_get_mm(int fd);
18568 diff -Naur a/include/linux/time.h b/include/linux/time.h
18569 --- a/include/linux/time.h 2004-02-11 12:15:59.000000000 -0500
18570 +++ b/include/linux/time.h 2004-02-11 12:27:52.000000000 -0500
18572 * Have the 32 bit jiffies value wrap 5 minutes after boot
18573 * so jiffies wrap bugs show up earlier.
18575 -#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))
18576 +#define INITIAL_JIFFIES ((unsigned long)(0))
18579 * Change timeval to jiffies, trying to avoid the
18580 diff -Naur a/mm/Makefile b/mm/Makefile
18581 --- a/mm/Makefile 2004-02-11 12:15:59.000000000 -0500
18582 +++ b/mm/Makefile 2004-02-11 12:27:53.000000000 -0500
18584 slab.o swap.o truncate.o vmscan.o $(mmu-y)
18586 obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o
18587 +obj-$(CONFIG_PROC_MM) += proc_mm.o
18589 diff -Naur a/mm/mmap.c b/mm/mmap.c
18590 --- a/mm/mmap.c 2004-02-11 12:15:58.000000000 -0500
18591 +++ b/mm/mmap.c 2004-02-11 12:27:51.000000000 -0500
18592 @@ -460,11 +460,11 @@
18593 * The caller must hold down_write(current->mm->mmap_sem).
18596 -unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
18597 - unsigned long len, unsigned long prot,
18598 - unsigned long flags, unsigned long pgoff)
18599 +unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file * file,
18600 + unsigned long addr, unsigned long len,
18601 + unsigned long prot, unsigned long flags,
18602 + unsigned long pgoff)
18604 - struct mm_struct * mm = current->mm;
18605 struct vm_area_struct * vma, * prev;
18606 struct inode *inode;
18607 unsigned int vm_flags;
18608 diff -Naur a/mm/mprotect.c b/mm/mprotect.c
18609 --- a/mm/mprotect.c 2004-02-11 12:15:11.000000000 -0500
18610 +++ b/mm/mprotect.c 2004-02-11 12:26:58.000000000 -0500
18611 @@ -222,7 +222,8 @@
18615 -sys_mprotect(unsigned long start, size_t len, unsigned long prot)
18616 +do_mprotect(struct mm_struct *mm, unsigned long start, size_t len,
18617 + unsigned long prot)
18619 unsigned long vm_flags, nstart, end, tmp;
18620 struct vm_area_struct * vma, * next, * prev;
18621 @@ -245,9 +246,9 @@
18623 vm_flags = calc_vm_prot_bits(prot);
18625 - down_write(¤t->mm->mmap_sem);
18626 + down_write(&mm->mmap_sem);
18628 - vma = find_vma_prev(current->mm, start, &prev);
18629 + vma = find_vma_prev(mm, start, &prev);
18633 @@ -326,6 +327,11 @@
18634 prev->vm_mm->map_count--;
18637 - up_write(¤t->mm->mmap_sem);
18638 + up_write(&mm->mmap_sem);
18642 +asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
18644 + return(do_mprotect(current->mm, start, len, prot));
18646 diff -Naur a/mm/page_alloc.c b/mm/page_alloc.c
18647 --- a/mm/page_alloc.c 2004-02-11 12:14:18.000000000 -0500
18648 +++ b/mm/page_alloc.c 2004-02-11 12:26:01.000000000 -0500
18649 @@ -268,6 +268,8 @@
18653 + arch_free_page(page, order);
18655 mod_page_state(pgfree, 1 << order);
18656 for (i = 0 ; i < (1 << order) ; ++i)
18657 free_pages_check(__FUNCTION__, page + i);
18658 @@ -449,6 +451,8 @@
18659 struct per_cpu_pages *pcp;
18660 unsigned long flags;
18662 + arch_free_page(page, 0);
18664 kernel_map_pages(page, 1, 0);
18665 inc_page_state(pgfree);
18666 free_pages_check(__FUNCTION__, page);
18667 diff -Naur a/mm/proc_mm.c b/mm/proc_mm.c
18668 --- a/mm/proc_mm.c 1969-12-31 19:00:00.000000000 -0500
18669 +++ b/mm/proc_mm.c 2004-02-11 12:27:05.000000000 -0500
18672 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18673 + * Licensed under the GPL
18676 +#include "linux/mm.h"
18677 +#include "linux/init.h"
18678 +#include "linux/proc_fs.h"
18679 +#include "linux/proc_mm.h"
18680 +#include "linux/file.h"
18681 +#include "asm/uaccess.h"
18682 +#include "asm/mmu_context.h"
18684 +static struct file_operations proc_mm_fops;
18686 +struct mm_struct *proc_mm_get_mm(int fd)
18688 + struct mm_struct *ret = ERR_PTR(-EBADF);
18689 + struct file *file;
18695 + ret = ERR_PTR(-EINVAL);
18696 + if(file->f_op != &proc_mm_fops)
18699 + ret = file->private_data;
18706 +extern long do_mmap2(struct mm_struct *mm, unsigned long addr,
18707 + unsigned long len, unsigned long prot,
18708 + unsigned long flags, unsigned long fd,
18709 + unsigned long pgoff);
18711 +static ssize_t write_proc_mm(struct file *file, const char *buffer,
18712 + size_t count, loff_t *ppos)
18714 + struct mm_struct *mm = file->private_data;
18715 + struct proc_mm_op req;
18718 + if(count > sizeof(req))
18721 + n = copy_from_user(&req, buffer, count);
18728 + struct mm_mmap *map = &req.u.mmap;
18730 + ret = do_mmap2(mm, map->addr, map->len, map->prot,
18731 + map->flags, map->fd, map->offset >> PAGE_SHIFT);
18732 + if((ret & ~PAGE_MASK) == 0)
18737 + case MM_MUNMAP: {
18738 + struct mm_munmap *unmap = &req.u.munmap;
18740 + down_write(&mm->mmap_sem);
18741 + ret = do_munmap(mm, unmap->addr, unmap->len);
18742 + up_write(&mm->mmap_sem);
18748 + case MM_MPROTECT: {
18749 + struct mm_mprotect *protect = &req.u.mprotect;
18751 + ret = do_mprotect(mm, protect->addr, protect->len,
18758 + case MM_COPY_SEGMENTS: {
18759 + struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
18761 + if(IS_ERR(from)){
18762 + ret = PTR_ERR(from);
18766 + mm_copy_segments(from, mm);
18777 +static int open_proc_mm(struct inode *inode, struct file *file)
18779 + struct mm_struct *mm = mm_alloc();
18786 + ret = init_new_context(current, mm);
18790 + spin_lock(&mmlist_lock);
18791 + list_add(&mm->mmlist, ¤t->mm->mmlist);
18793 + spin_unlock(&mmlist_lock);
18795 + file->private_data = mm;
18805 +static int release_proc_mm(struct inode *inode, struct file *file)
18807 + struct mm_struct *mm = file->private_data;
18813 +static struct file_operations proc_mm_fops = {
18814 + .open = open_proc_mm,
18815 + .release = release_proc_mm,
18816 + .write = write_proc_mm,
18819 +static int make_proc_mm(void)
18821 + struct proc_dir_entry *ent;
18823 + ent = create_proc_entry("mm", 0222, &proc_root);
18825 + printk("make_proc_mm : Failed to register /proc/mm\n");
18828 + ent->proc_fops = &proc_mm_fops;
18833 +__initcall(make_proc_mm);
18836 + * Overrides for Emacs so that we follow Linus's tabbing style.
18837 + * Emacs will notice this stuff at the end of the file and automatically
18838 + * adjust the settings for this buffer only. This must remain at the end
18840 + * ---------------------------------------------------------------------------
18841 + * Local variables:
18842 + * c-file-style: "linux"