1 Index: uml-2.6.7/arch/um/kernel/skas/trap_user.c
2 ===================================================================
3 --- uml-2.6.7.orig/arch/um/kernel/skas/trap_user.c 2004-07-16 19:36:33.534048512 +0300
4 +++ uml-2.6.7/arch/um/kernel/skas/trap_user.c 2004-07-16 19:47:23.734203064 +0300
7 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
8 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
9 * Licensed under the GPL
16 -extern int missed_ticks[];
18 void user_signal(int sig, union uml_pt_regs *regs)
20 struct signal_info *info;
22 - if(sig == SIGVTALRM)
23 - missed_ticks[cpu()]++;
24 regs->skas.is_user = 1;
25 regs->skas.fault_addr = 0;
26 regs->skas.fault_type = 0;
27 Index: uml-2.6.7/arch/um/kernel/irq.c
28 ===================================================================
29 --- uml-2.6.7.orig/arch/um/kernel/irq.c 2004-07-16 19:37:20.013982488 +0300
30 +++ uml-2.6.7/arch/um/kernel/irq.c 2004-07-16 19:47:23.717205648 +0300
32 #include "user_util.h"
33 #include "kern_util.h"
35 +#include "irq_kern.h"
37 static void register_irq_proc (unsigned int irq);
44 -volatile unsigned long irq_err_count;
47 * Generic, controller-independent functions:
50 -int get_irq_list(char *buf)
51 +int show_interrupts(struct seq_file *p, void *v)
54 - unsigned long flags;
55 + int i = *(loff_t *) v, j;
56 struct irqaction * action;
58 + unsigned long flags;
60 - p += sprintf(p, " ");
61 - for (j=0; j<num_online_cpus(); j++)
62 - p += sprintf(p, "CPU%d ",j);
66 + for (j=0; j<NR_CPUS; j++)
68 + seq_printf(p, "CPU%d ",j);
72 - for (i = 0 ; i < NR_IRQS ; i++) {
74 spin_lock_irqsave(&irq_desc[i].lock, flags);
75 action = irq_desc[i].action;
78 - p += sprintf(p, "%3d: ",i);
80 + seq_printf(p, "%3d: ",i);
82 - p += sprintf(p, "%10u ", kstat_irqs(i));
83 + seq_printf(p, "%10u ", kstat_irqs(i));
85 - for (j = 0; j < num_online_cpus(); j++)
86 - p += sprintf(p, "%10u ",
87 - kstat_cpu(cpu_logical_map(j)).irqs[i]);
88 + for (j = 0; j < NR_CPUS; j++)
90 + seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
92 - p += sprintf(p, " %14s", irq_desc[i].handler->typename);
93 - p += sprintf(p, " %s", action->name);
94 + seq_printf(p, " %14s", irq_desc[i].handler->typename);
95 + seq_printf(p, " %s", action->name);
97 for (action=action->next; action; action = action->next)
98 - p += sprintf(p, ", %s", action->name);
101 + seq_printf(p, ", %s", action->name);
105 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
106 + } else if (i == NR_IRQS) {
107 + seq_printf(p, "NMI: ");
108 + for (j = 0; j < NR_CPUS; j++)
110 + seq_printf(p, "%10u ", nmi_count(j));
113 - p += sprintf(p, "\n");
116 - p += sprintf(p, "LOC: ");
117 - for (j = 0; j < num_online_cpus(); j++)
118 - p += sprintf(p, "%10u ",
119 - apic_timer_irqs[cpu_logical_map(j)]);
120 - p += sprintf(p, "\n");
123 - p += sprintf(p, "ERR: %10lu\n", irq_err_count);
128 -int show_interrupts(struct seq_file *p, void *v)
135 @@ -282,13 +273,12 @@
136 * 0 return value means that this irq is already being
137 * handled by some other CPU. (or is disabled)
139 - int cpu = smp_processor_id();
140 irq_desc_t *desc = irq_desc + irq;
141 struct irqaction * action;
145 - kstat_cpu(cpu).irqs[irq]++;
146 + kstat_this_cpu.irqs[irq]++;
147 spin_lock(&desc->lock);
148 desc->handler->ack(irq);
153 int request_irq(unsigned int irq,
154 - void (*handler)(int, void *, struct pt_regs *),
155 + irqreturn_t (*handler)(int, void *, struct pt_regs *),
156 unsigned long irqflags,
157 const char * devname,
159 @@ -433,15 +423,19 @@
160 EXPORT_SYMBOL(request_irq);
162 int um_request_irq(unsigned int irq, int fd, int type,
163 - void (*handler)(int, void *, struct pt_regs *),
164 + irqreturn_t (*handler)(int, void *, struct pt_regs *),
165 unsigned long irqflags, const char * devname,
171 - retval = request_irq(irq, handler, irqflags, devname, dev_id);
172 - if(retval) return(retval);
173 - return(activate_fd(irq, fd, type, dev_id));
174 + err = request_irq(irq, handler, irqflags, devname, dev_id);
179 + err = activate_fd(irq, fd, type, dev_id);
183 /* this was setup_x86_irq but it seems pretty generic */
186 spin_lock_irqsave(&desc->lock,flags);
188 - if ((old = *p) != NULL) {
191 /* Can't share interrupts unless both agree to */
192 if (!(old->flags & new->flags & SA_SHIRQ)) {
193 spin_unlock_irqrestore(&desc->lock,flags);
194 @@ -586,12 +581,14 @@
195 unsigned long count, void *data)
197 int irq = (long) data, full_count = count, err;
198 - cpumask_t new_value, tmp;
199 + cpumask_t new_value;
201 if (!irq_desc[irq].handler->set_affinity)
204 err = cpumask_parse(buffer, count, new_value);
211 * way to make the system unusable accidentally :-) At least
212 * one online CPU still has to be targeted.
214 - cpus_and(tmp, new_value, cpu_online_map);
215 - if (cpus_empty(tmp))
218 + cpus_and(tmp, new_value, cpu_online_map);
219 + if (cpus_empty(tmp))
224 irq_affinity[irq] = new_value;
225 Index: uml-2.6.7/arch/um/drivers/chan_user.c
226 ===================================================================
227 --- uml-2.6.7.orig/arch/um/drivers/chan_user.c 2004-07-16 19:35:52.587273368 +0300
228 +++ uml-2.6.7/arch/um/drivers/chan_user.c 2004-07-16 19:47:24.392103048 +0300
231 - * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
232 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
233 * Licensed under the GPL
243 #include <sys/stat.h>
245 #include "choose-mode.h"
248 -void generic_close(int fd, void *unused)
253 -int generic_read(int fd, char *c_out, void *unused)
257 - n = read(fd, c_out, sizeof(*c_out));
259 - if(errno == EAGAIN) return(0);
262 - else if(n == 0) return(-EIO);
266 -int generic_write(int fd, const char *buf, int n, void *unused)
270 - count = write(fd, buf, n);
271 - if(count < 0) return(-errno);
275 int generic_console_write(int fd, const char *buf, int n, void *unused)
277 struct termios save, new;
282 -int generic_window_size(int fd, void *unused, unsigned short *rows_out,
283 - unsigned short *cols_out)
285 - struct winsize size;
288 - if(ioctl(fd, TIOCGWINSZ, &size) == 0){
289 - ret = ((*rows_out != size.ws_row) ||
290 - (*cols_out != size.ws_col));
291 - *rows_out = size.ws_row;
292 - *cols_out = size.ws_col;
297 -void generic_free(void *data)
302 static void winch_handler(int sig)
306 struct winch_data *data = arg;
312 - close(data->close_me);
313 + os_close_file(data->close_me);
314 pty_fd = data->pty_fd;
315 pipe_fd = data->pipe_fd;
316 - if(write(pipe_fd, &c, sizeof(c)) != sizeof(c))
317 + count = os_write_file(pipe_fd, &c, sizeof(c));
318 + if(count != sizeof(c))
319 printk("winch_thread : failed to write synchronization "
320 - "byte, errno = %d\n", errno);
321 + "byte, err = %d\n", -count);
323 signal(SIGWINCH, winch_handler);
329 - if(ioctl(pty_fd, TIOCSCTTY, 0) < 0){
330 - printk("winch_thread : TIOCSCTTY failed, errno = %d\n", errno);
333 - if(tcsetpgrp(pty_fd, os_getpid()) < 0){
334 - printk("winch_thread : tcsetpgrp failed, errno = %d\n", errno);
335 + err = os_new_tty_pgrp(pty_fd, os_getpid());
337 + printk("winch_thread : new_tty_pgrp failed, err = %d\n", -err);
341 - if(read(pipe_fd, &c, sizeof(c)) != sizeof(c))
342 + count = os_read_file(pipe_fd, &c, sizeof(c));
343 + if(count != sizeof(c))
344 printk("winch_thread : failed to read synchronization byte, "
345 - "errno = %d\n", errno);
346 + "err = %d\n", -count);
351 - if(write(pipe_fd, &c, sizeof(c)) != sizeof(c)){
352 - printk("winch_thread : write failed, errno = %d\n",
355 + count = os_write_file(pipe_fd, &c, sizeof(c));
356 + if(count != sizeof(c))
357 + printk("winch_thread : write failed, err = %d\n",
365 err = os_pipe(fds, 1, 1);
367 - printk("winch_tramp : os_pipe failed, errno = %d\n", -err);
369 + printk("winch_tramp : os_pipe failed, err = %d\n", -err);
373 @@ -168,12 +120,12 @@
378 + os_close_file(fds[1]);
380 - n = read(fds[0], &c, sizeof(c));
381 + n = os_read_file(fds[0], &c, sizeof(c));
383 printk("winch_tramp : failed to read synchronization byte\n");
384 - printk("read returned %d, errno = %d\n", n, errno);
385 + printk("read failed, err = %d\n", -n);
386 printk("fd %d will not support SIGWINCH\n", fd);
389 @@ -183,20 +135,24 @@
390 void register_winch(int fd, void *device_data)
392 int pid, thread, thread_fd;
396 - if(!isatty(fd)) return;
401 - if(!CHOOSE_MODE(is_tracer_winch(pid, fd, device_data), 0) &&
403 + if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd,
404 + device_data) && (pid == -1)){
405 thread = winch_tramp(fd, device_data, &thread_fd);
407 register_winch_irq(thread_fd, fd, thread, device_data);
409 - if(write(thread_fd, &c, sizeof(c)) != sizeof(c))
410 + count = os_write_file(thread_fd, &c, sizeof(c));
411 + if(count != sizeof(c))
412 printk("register_winch : failed to write "
413 - "synchronization byte\n");
414 + "synchronization byte, err = %d\n",
419 Index: uml-2.6.7/arch/um/drivers/cow_user.c
420 ===================================================================
421 --- uml-2.6.7.orig/arch/um/drivers/cow_user.c 2004-07-16 19:47:23.608222216 +0300
422 +++ uml-2.6.7/arch/um/drivers/cow_user.c 2004-07-16 19:47:23.680211272 +0300
428 +#include <byteswap.h>
429 +#include <sys/time.h>
430 +#include <sys/param.h>
431 +#include <sys/user.h>
432 +#include <netinet/in.h>
437 +#include "cow_sys.h"
439 +#define PATH_LEN_V1 256
441 +struct cow_header_v1 {
444 + char backing_file[PATH_LEN_V1];
450 +#define PATH_LEN_V2 MAXPATHLEN
452 +struct cow_header_v2 {
453 + unsigned long magic;
454 + unsigned long version;
455 + char backing_file[PATH_LEN_V2];
461 +/* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in
462 + * case other systems have different values for MAXPATHLEN
464 +#define PATH_LEN_V3 4096
466 +/* Changes from V2 -
467 + * PATH_LEN_V3 as described above
468 + * Explicitly specify field bit lengths for systems with different
469 + * lengths for the usual C types. Not sure whether char or
470 + * time_t should be changed, this can be changed later without
471 + * breaking compatibility
472 + * Add alignment field so that different alignments can be used for the
474 + * Add cow_format field to allow for the possibility of different ways
475 + * of specifying the COW blocks. For now, the only value is 0,
476 + * for the traditional COW bitmap.
477 + * Move the backing_file field to the end of the header. This allows
478 + * for the possibility of expanding it into the padding required
479 + * by the bitmap alignment.
480 + * The bitmap and data portions of the file will be aligned as specified
481 + * by the alignment field. This is to allow COW files to be
482 + * put on devices with restrictions on access alignments, such as
483 + * /dev/raw, with a 512 byte alignment restriction. This also
484 + * allows the data to be more aligned more strictly than on
485 + * sector boundaries. This is needed for ubd-mmap, which needs
486 + * the data to be page aligned.
487 + * Fixed (finally!) the rounding bug
490 +struct cow_header_v3 {
498 + char backing_file[PATH_LEN_V3];
501 +/* COW format definitions - for now, we have only the usual COW bitmap */
502 +#define COW_BITMAP 0
505 + struct cow_header_v1 v1;
506 + struct cow_header_v2 v2;
507 + struct cow_header_v3 v3;
510 +#define COW_MAGIC 0x4f4f4f4d /* MOOO */
511 +#define COW_VERSION 3
513 +#define DIV_ROUND(x, len) (((x) + (len) - 1) / (len))
514 +#define ROUND_UP(x, align) DIV_ROUND(x, align) * (align)
516 +void cow_sizes(int version, __u64 size, int sectorsize, int align,
517 + int bitmap_offset, unsigned long *bitmap_len_out,
518 + int *data_offset_out)
521 + *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
523 + *data_offset_out = bitmap_offset + *bitmap_len_out;
524 + *data_offset_out = (*data_offset_out + sectorsize - 1) /
526 + *data_offset_out *= sectorsize;
529 + *bitmap_len_out = DIV_ROUND(size, sectorsize);
530 + *bitmap_len_out = DIV_ROUND(*bitmap_len_out, 8);
532 + *data_offset_out = bitmap_offset + *bitmap_len_out;
533 + *data_offset_out = ROUND_UP(*data_offset_out, align);
537 +static int absolutize(char *to, int size, char *from)
539 + char save_cwd[256], *slash;
542 + if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
543 + cow_printf("absolutize : unable to get cwd - errno = %d\n",
547 + slash = strrchr(from, '/');
552 + cow_printf("absolutize : Can't cd to '%s' - "
553 + "errno = %d\n", from, errno);
557 + if(getcwd(to, size) == NULL){
558 + cow_printf("absolutize : unable to get cwd of '%s' - "
559 + "errno = %d\n", from, errno);
562 + remaining = size - strlen(to);
563 + if(strlen(slash) + 1 > remaining){
564 + cow_printf("absolutize : unable to fit '%s' into %d "
565 + "chars\n", from, size);
571 + if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
572 + cow_printf("absolutize : unable to fit '%s' into %d "
573 + "chars\n", from, size);
576 + strcpy(to, save_cwd);
584 +int write_cow_header(char *cow_file, int fd, char *backing_file,
585 + int sectorsize, int alignment, long long *size)
587 + struct cow_header_v3 *header;
588 + unsigned long modtime;
591 + err = cow_seek_file(fd, 0);
593 + cow_printf("write_cow_header - lseek failed, err = %d\n", -err);
598 + header = cow_malloc(sizeof(*header));
599 + if(header == NULL){
600 + cow_printf("Failed to allocate COW V3 header\n");
603 + header->magic = htonl(COW_MAGIC);
604 + header->version = htonl(COW_VERSION);
607 + if(strlen(backing_file) > sizeof(header->backing_file) - 1){
608 + cow_printf("Backing file name \"%s\" is too long - names are "
609 + "limited to %d characters\n", backing_file,
610 + sizeof(header->backing_file) - 1);
614 + if(absolutize(header->backing_file, sizeof(header->backing_file),
618 + err = os_file_modtime(header->backing_file, &modtime);
620 + cow_printf("Backing file '%s' mtime request failed, "
621 + "err = %d\n", header->backing_file, -err);
625 + err = cow_file_size(header->backing_file, size);
627 + cow_printf("Couldn't get size of backing file '%s', "
628 + "err = %d\n", header->backing_file, -err);
632 + header->mtime = htonl(modtime);
633 + header->size = htonll(*size);
634 + header->sectorsize = htonl(sectorsize);
635 + header->alignment = htonl(alignment);
636 + header->cow_format = COW_BITMAP;
638 + err = os_write_file(fd, header, sizeof(*header));
639 + if(err != sizeof(*header)){
640 + cow_printf("Write of header to new COW file '%s' failed, "
641 + "err = %d\n", cow_file, -err);
651 +int file_reader(__u64 offset, char *buf, int len, void *arg)
653 + int fd = *((int *) arg);
655 + return(pread(fd, buf, len, offset));
658 +/* XXX Need to sanity-check the values read from the header */
660 +int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
661 + __u32 *version_out, char **backing_file_out,
662 + time_t *mtime_out, __u64 *size_out,
663 + int *sectorsize_out, __u32 *align_out,
664 + int *bitmap_offset_out)
666 + union cow_header *header;
669 + unsigned long version, magic;
671 + header = cow_malloc(sizeof(*header));
672 + if(header == NULL){
673 + cow_printf("read_cow_header - Failed to allocate header\n");
677 + n = (*reader)(0, (char *) header, sizeof(*header), arg);
678 + if(n < offsetof(typeof(header->v1), backing_file)){
679 + cow_printf("read_cow_header - short header\n");
683 + magic = header->v1.magic;
684 + if(magic == COW_MAGIC) {
685 + version = header->v1.version;
687 + else if(magic == ntohl(COW_MAGIC)){
688 + version = ntohl(header->v1.version);
690 + /* No error printed because the non-COW case comes through here */
693 + *version_out = version;
696 + if(n < sizeof(header->v1)){
697 + cow_printf("read_cow_header - failed to read V1 "
701 + *mtime_out = header->v1.mtime;
702 + *size_out = header->v1.size;
703 + *sectorsize_out = header->v1.sectorsize;
704 + *bitmap_offset_out = sizeof(header->v1);
705 + *align_out = *sectorsize_out;
706 + file = header->v1.backing_file;
708 + else if(version == 2){
709 + if(n < sizeof(header->v2)){
710 + cow_printf("read_cow_header - failed to read V2 "
714 + *mtime_out = ntohl(header->v2.mtime);
715 + *size_out = ntohll(header->v2.size);
716 + *sectorsize_out = ntohl(header->v2.sectorsize);
717 + *bitmap_offset_out = sizeof(header->v2);
718 + *align_out = *sectorsize_out;
719 + file = header->v2.backing_file;
721 + else if(version == 3){
722 + if(n < sizeof(header->v3)){
723 + cow_printf("read_cow_header - failed to read V2 "
727 + *mtime_out = ntohl(header->v3.mtime);
728 + *size_out = ntohll(header->v3.size);
729 + *sectorsize_out = ntohl(header->v3.sectorsize);
730 + *align_out = ntohl(header->v3.alignment);
731 + *bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out);
732 + file = header->v3.backing_file;
735 + cow_printf("read_cow_header - invalid COW version\n");
739 + *backing_file_out = cow_strdup(file);
740 + if(*backing_file_out == NULL){
741 + cow_printf("read_cow_header - failed to allocate backing "
751 +int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
752 + int alignment, int *bitmap_offset_out,
753 + unsigned long *bitmap_len_out, int *data_offset_out)
755 + __u64 size, offset;
759 + err = write_cow_header(cow_file, fd, backing_file, sectorsize,
764 + *bitmap_offset_out = ROUND_UP(sizeof(struct cow_header_v3), alignment);
765 + cow_sizes(COW_VERSION, size, sectorsize, alignment, *bitmap_offset_out,
766 + bitmap_len_out, data_offset_out);
768 + offset = *data_offset_out + size - sizeof(zero);
769 + err = cow_seek_file(fd, offset);
771 + cow_printf("cow bitmap lseek failed : err = %d\n", -err);
775 + /* does not really matter how much we write it is just to set EOF
776 + * this also sets the entire COW bitmap
777 + * to zero without having to allocate it
779 + err = cow_write_file(fd, &zero, sizeof(zero));
780 + if(err != sizeof(zero)){
781 + cow_printf("Write of bitmap to new COW file '%s' failed, "
782 + "err = %d\n", cow_file, -err);
794 + * ---------------------------------------------------------------------------
796 + * c-file-style: "linux"
799 Index: uml-2.6.7/arch/um/drivers/chan_kern.c
800 ===================================================================
801 --- uml-2.6.7.orig/arch/um/drivers/chan_kern.c 2004-07-16 19:37:43.028483752 +0300
802 +++ uml-2.6.7/arch/um/drivers/chan_kern.c 2004-07-16 19:47:24.392103048 +0300
804 #include <linux/list.h>
805 #include <linux/slab.h>
806 #include <linux/tty.h>
807 +#include <linux/string.h>
808 #include <linux/tty_flip.h>
810 #include "chan_kern.h"
812 #include "irq_user.h"
817 static void *not_configged_init(char *str, int device, struct chan_opts *opts)
823 +void generic_close(int fd, void *unused)
828 +int generic_read(int fd, char *c_out, void *unused)
832 + n = os_read_file(fd, c_out, sizeof(*c_out));
841 +int generic_write(int fd, const char *buf, int n, void *unused)
843 + return(os_write_file(fd, buf, n));
846 +int generic_window_size(int fd, void *unused, unsigned short *rows_out,
847 + unsigned short *cols_out)
852 + ret = os_window_size(fd, &rows, &cols);
856 + ret = ((*rows_out != rows) || (*cols_out != cols));
864 +void generic_free(void *data)
869 static void tty_receive_char(struct tty_struct *tty, char ch)
871 if(tty == NULL) return;
877 + CONFIG_CHUNK(str, size, n, "none", 1);
881 CONFIG_CHUNK(str, size, n, chan->ops->type, 0);
883 if(chan->dev == NULL){
885 INIT_LIST_HEAD(chans);
888 - if((out = strchr(str, ',')) != NULL){
889 + out = strchr(str, ',');
894 @@ -475,12 +529,15 @@
897 err = chan->ops->read(chan->fd, &c, chan->data);
898 - if(err > 0) tty_receive_char(tty, c);
900 + tty_receive_char(tty, c);
903 if(err == 0) reactivate_fd(chan->fd, irq);
906 - if(tty != NULL) tty_hangup(tty);
909 line_disable(dev, irq);
912 Index: uml-2.6.7/arch/um/drivers/cow_kern.c
913 ===================================================================
914 --- uml-2.6.7.orig/arch/um/drivers/cow_kern.c 2004-07-16 19:47:23.608222216 +0300
915 +++ uml-2.6.7/arch/um/drivers/cow_kern.c 2004-07-16 19:47:23.679211424 +0300
917 +#define COW_MAJOR 60
918 +#define MAJOR_NR COW_MAJOR
920 +#include <linux/stddef.h>
921 +#include <linux/kernel.h>
922 +#include <linux/ctype.h>
923 +#include <linux/stat.h>
924 +#include <linux/vmalloc.h>
925 +#include <linux/blkdev.h>
926 +#include <linux/blk.h>
927 +#include <linux/fs.h>
928 +#include <linux/genhd.h>
929 +#include <linux/devfs_fs.h>
930 +#include <asm/uaccess.h>
931 +#include "2_5compat.h"
933 +#include "ubd_user.h"
941 + struct block_device *cow_bdev;
942 + char *backing_path;
944 + struct block_device *backing_bdev;
946 + unsigned long *bitmap;
947 + unsigned long bitmap_len;
950 + devfs_handle_t devfs;
951 + struct semaphore sem;
952 + struct semaphore io_sem;
954 + spinlock_t io_lock;
955 + struct buffer_head *bh;
956 + struct buffer_head *bhtail;
960 +#define DEFAULT_COW { \
962 + .cow_path = NULL, \
964 + .backing_path = NULL, \
965 + .backing_dev = 0, \
968 + .bitmap_offset = 0, \
969 + .data_offset = 0, \
971 + .working = ATOMIC_INIT(0), \
972 + .io_lock = SPIN_LOCK_UNLOCKED, \
976 +#define MAX_MINOR (MAX_DEV << COW_SHIFT)
978 +struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW };
980 +/* Not modified by this driver */
981 +static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE };
982 +static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 };
984 +/* Protected by cow_lock */
985 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
987 +static struct hd_struct cow_part[MAX_MINOR] =
988 + { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
990 +/* Protected by io_request_lock */
991 +static request_queue_t *cow_queue;
993 +static int cow_open(struct inode *inode, struct file *filp);
994 +static int cow_release(struct inode * inode, struct file * file);
995 +static int cow_ioctl(struct inode * inode, struct file * file,
996 + unsigned int cmd, unsigned long arg);
997 +static int cow_revalidate(kdev_t rdev);
999 +static struct block_device_operations cow_blops = {
1001 + .release = cow_release,
1002 + .ioctl = cow_ioctl,
1003 + .revalidate = cow_revalidate,
1006 +/* Initialized in an initcall, and unchanged thereafter */
1007 +devfs_handle_t cow_dir_handle;
1009 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
1012 + .major_name = name, \
1013 + .minor_shift = shift, \
1014 + .max_p = 1 << shift, \
1016 + .sizes = bsizes, \
1018 + .real_devices = NULL, \
1025 +static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED;
1027 +static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part,
1028 + COW_SHIFT, sizes, MAX_DEV,
1031 +static int cow_add(int n)
1033 + struct cow *dev = &cow_dev[n];
1034 + char name[sizeof("nnnnnn\0")];
1035 + int err = -ENODEV;
1037 + if(dev->cow_path == NULL)
1040 + sprintf(name, "%d", n);
1041 + dev->devfs = devfs_register(cow_dir_handle, name, DEVFS_FL_REMOVABLE,
1042 + MAJOR_NR, n << COW_SHIFT, S_IFBLK |
1043 + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
1044 + &cow_blops, NULL);
1046 + init_MUTEX_LOCKED(&dev->sem);
1047 + init_MUTEX(&dev->io_sem);
1056 + * Add buffer_head to back of pending list
1058 +static void cow_add_bh(struct cow *cow, struct buffer_head *bh)
1060 + unsigned long flags;
1062 + spin_lock_irqsave(&cow->io_lock, flags);
1063 + if(cow->bhtail != NULL){
1064 + cow->bhtail->b_reqnext = bh;
1071 + spin_unlock_irqrestore(&cow->io_lock, flags);
1075 +* Grab first pending buffer
1077 +static struct buffer_head *cow_get_bh(struct cow *cow)
1079 + struct buffer_head *bh;
1081 + spin_lock_irq(&cow->io_lock);
1084 + if(bh == cow->bhtail)
1085 + cow->bhtail = NULL;
1086 + cow->bh = bh->b_reqnext;
1087 + bh->b_reqnext = NULL;
1089 + spin_unlock_irq(&cow->io_lock);
1094 +static void cow_handle_bh(struct cow *cow, struct buffer_head *bh,
1095 + struct buffer_head **cow_bh, int ncow_bh)
1100 + ll_rw_block(WRITE, ncow_bh, cow_bh);
1102 + for(i = 0; i < ncow_bh ; i++){
1103 + wait_on_buffer(cow_bh[i]);
1104 + brelse(cow_bh[i]);
1107 + ll_rw_block(WRITE, 1, &bh);
1111 +static struct buffer_head *cow_new_bh(struct cow *dev, int sector)
1113 + struct buffer_head *bh;
1115 + sector = (dev->bitmap_offset + sector / 8) / dev->sectorsize;
1116 + bh = getblk(dev->cow_dev, sector, dev->sectorsize);
1117 + memcpy(bh->b_data, dev->bitmap + sector / (8 * sizeof(dev->bitmap[0])),
1122 +/* Copied from loop.c, needed to avoid deadlocking in make_request. */
1124 +static int cow_thread(void *data)
1126 + struct cow *dev = data;
1127 + struct buffer_head *bh;
1130 + exit_files(current);
1132 + sprintf(current->comm, "cow%d", dev - cow_dev);
1134 + spin_lock_irq(¤t->sigmask_lock);
1135 + sigfillset(¤t->blocked);
1136 + flush_signals(current);
1137 + spin_unlock_irq(¤t->sigmask_lock);
1139 + atomic_inc(&dev->working);
1141 + current->policy = SCHED_OTHER;
1142 + current->nice = -20;
1144 + current->flags |= PF_NOIO;
1147 + * up sem, we are running
1152 + int start, len, nbh, i, update_bitmap = 0;
1153 + struct buffer_head *cow_bh[2];
1155 + down_interruptible(&dev->io_sem);
1157 + * could be upped because of tear-down, not because of
1160 + if(!atomic_read(&dev->working))
1163 + bh = cow_get_bh(dev);
1165 + printk(KERN_ERR "cow: missing bh\n");
1169 + start = bh->b_blocknr * bh->b_size / dev->sectorsize;
1170 + len = bh->b_size / dev->sectorsize;
1171 + for(i = 0; i < len ; i++){
1172 + if(ubd_test_bit(start + i,
1173 + (unsigned char *) dev->bitmap))
1176 + update_bitmap = 1;
1177 + ubd_set_bit(start + i, (unsigned char *) dev->bitmap);
1183 + if(update_bitmap){
1184 + cow_bh[0] = cow_new_bh(dev, start);
1186 + if(start / dev->sectorsize !=
1187 + (start + len) / dev->sectorsize){
1188 + cow_bh[1] = cow_new_bh(dev, start + len);
1193 + bh->b_dev = dev->cow_dev;
1194 + bh->b_blocknr += dev->data_offset / dev->sectorsize;
1196 + cow_handle_bh(dev, bh, cow_bh, nbh);
1199 + * upped both for pending work and tear-down, lo_pending
1200 + * will hit zero then
1202 + if(atomic_dec_and_test(&dev->working))
1210 +static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh)
1215 + minor = MINOR(bh->b_rdev);
1216 + n = minor >> COW_SHIFT;
1217 + dev = &cow_dev[n];
1219 + dev->end_io = NULL;
1220 + if(ubd_test_bit(bh->b_rsector, (unsigned char *) dev->bitmap)){
1221 + bh->b_rdev = dev->cow_dev;
1222 + bh->b_rsector += dev->data_offset / dev->sectorsize;
1224 + else if(rw == WRITE){
1225 + bh->b_dev = dev->cow_dev;
1226 + bh->b_blocknr += dev->data_offset / dev->sectorsize;
1228 + cow_add_bh(dev, bh);
1233 + bh->b_rdev = dev->backing_dev;
1243 + cow_dir_handle = devfs_mk_dir (NULL, "cow", NULL);
1244 + if (devfs_register_blkdev(MAJOR_NR, "cow", &cow_blops)) {
1245 + printk(KERN_ERR "cow: unable to get major %d\n", MAJOR_NR);
1248 + read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read-ahead */
1249 + blksize_size[MAJOR_NR] = blk_sizes;
1250 + blk_size[MAJOR_NR] = sizes;
1251 + INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes);
1253 + cow_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
1254 + blk_init_queue(cow_queue, NULL);
1255 + INIT_ELV(cow_queue, &cow_queue->elevator);
1256 + blk_queue_make_request(cow_queue, cow_make_request);
1258 + add_gendisk(&cow_gendisk);
1260 + for(i=0;i<MAX_DEV;i++)
1266 +__initcall(cow_init);
1268 +static int reader(__u64 start, char *buf, int count, void *arg)
1270 + dev_t dev = *((dev_t *) arg);
1271 + struct buffer_head *bh;
1273 + int cur, offset, left, n, blocksize = get_hardsect_size(dev);
1275 + if(blocksize == 0)
1276 + panic("Zero blocksize");
1278 + block = start / blocksize;
1279 + offset = start % blocksize;
1283 + n = (left > blocksize) ? blocksize : left;
1285 + bh = bread(dev, block, (n < 512) ? 512 : n);
1290 + memcpy(&buf[cur], bh->b_data + offset, n);
1301 +static int cow_open(struct inode *inode, struct file *filp)
1303 + int (*dev_ioctl)(struct inode *, struct file *, unsigned int,
1308 + __u32 version, align;
1310 + char *backing_file;
1311 + int n, offset, err = 0;
1313 + n = DEVICE_NR(inode->i_rdev);
1316 + dev = &cow_dev[n];
1317 + offset = n << COW_SHIFT;
1319 + spin_lock(&cow_lock);
1321 + if(dev->count == 0){
1322 + dev->cow_dev = name_to_kdev_t(dev->cow_path);
1323 + if(dev->cow_dev == 0){
1324 + printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
1325 + "failed\n", dev->cow_path);
1329 + dev->backing_dev = name_to_kdev_t(dev->backing_path);
1330 + if(dev->backing_dev == 0){
1331 + printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
1332 + "failed\n", dev->backing_path);
1339 + dev->cow_bdev = bdget(dev->cow_dev);
1340 + if(dev->cow_bdev == NULL){
1341 + printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n",
1345 + dev->backing_bdev = bdget(dev->backing_dev);
1346 + if(dev->backing_bdev == NULL){
1347 + printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n",
1348 + dev->backing_path);
1355 + err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0,
1358 + printk("cow_open - blkdev_get of COW device failed, "
1359 + "error = %d\n", err);
1363 + err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW);
1365 + printk("cow_open - blkdev_get of backing device "
1366 + "failed, error = %d\n", err);
1370 + err = read_cow_header(reader, &dev->cow_dev, &version,
1371 + &backing_file, &mtime, &size,
1372 + &dev->sectorsize, &align,
1373 + &dev->bitmap_offset);
1375 + printk(KERN_ERR "cow_open - read_cow_header failed, "
1376 + "err = %d\n", err);
1380 + cow_sizes(version, size, dev->sectorsize, align,
1381 + dev->bitmap_offset, &dev->bitmap_len,
1382 + &dev->data_offset);
1383 + dev->bitmap = (void *) vmalloc(dev->bitmap_len);
1384 + if(dev->bitmap == NULL){
1386 + printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
1389 + flush_tlb_kernel_vm();
1391 + err = reader(dev->bitmap_offset, (char *) dev->bitmap,
1392 + dev->bitmap_len, &dev->cow_dev);
1394 + printk(KERN_ERR "Failed to read COW bitmap\n");
1395 + vfree(dev->bitmap);
1399 + dev_ioctl = dev->backing_bdev->bd_op->ioctl;
1401 + set_fs(KERNEL_DS);
1402 + err = (*dev_ioctl)(inode, filp, BLKGETSIZE,
1403 + (unsigned long) &sizes[offset]);
1406 + printk(KERN_ERR "cow_open - BLKGETSIZE failed, "
1407 + "error = %d\n", err);
1411 + kernel_thread(cow_thread, dev,
1412 + CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
1417 + spin_unlock(&cow_lock);
1421 +static int cow_release(struct inode * inode, struct file * file)
1426 + n = DEVICE_NR(inode->i_rdev);
1429 + dev = &cow_dev[n];
1431 + spin_lock(&cow_lock);
1433 + if(--dev->count > 0)
1436 + err = blkdev_put(dev->cow_bdev, BDEV_RAW);
1438 + printk("cow_release - blkdev_put of cow device failed, "
1439 + "error = %d\n", err);
1440 + bdput(dev->cow_bdev);
1441 + dev->cow_bdev = 0;
1443 + err = blkdev_put(dev->backing_bdev, BDEV_RAW);
1445 + printk("cow_release - blkdev_put of backing device failed, "
1446 + "error = %d\n", err);
1447 + bdput(dev->backing_bdev);
1448 + dev->backing_bdev = 0;
1451 + spin_unlock(&cow_lock);
1455 +static int cow_ioctl(struct inode * inode, struct file * file,
1456 + unsigned int cmd, unsigned long arg)
1459 + int (*dev_ioctl)(struct inode *, struct file *, unsigned int,
1463 + n = DEVICE_NR(inode->i_rdev);
1466 + dev = &cow_dev[n];
1468 + dev_ioctl = dev->backing_bdev->bd_op->ioctl;
1469 + return((*dev_ioctl)(inode, file, cmd, arg));
1472 +static int cow_revalidate(kdev_t rdev)
1474 + printk(KERN_ERR "Need to implement cow_revalidate\n");
1478 +static int parse_unit(char **ptr)
1480 + char *str = *ptr, *end;
1483 + if(isdigit(*str)) {
1484 + n = simple_strtoul(str, &end, 0);
1489 + else if (('a' <= *str) && (*str <= 'h')) {
1497 +static int cow_setup(char *str)
1500 + char *cow_name, *backing_name;
1503 + unit = parse_unit(&str);
1505 + printk(KERN_ERR "cow_setup - Couldn't parse unit number\n");
1510 + printk(KERN_ERR "cow_setup - Missing '=' after unit "
1517 + backing_name = strchr(str, ',');
1518 + if(backing_name == NULL){
1519 + printk(KERN_ERR "cow_setup - missing backing device name\n");
1522 + *backing_name = '\0';
1525 + spin_lock(&cow_lock);
1527 + dev = &cow_dev[unit];
1528 + dev->cow_path = cow_name;
1529 + dev->backing_path = backing_name;
1531 + spin_unlock(&cow_lock);
1535 +__setup("cow", cow_setup);
1538 + * Overrides for Emacs so that we follow Linus's tabbing style.
1539 + * Emacs will notice this stuff at the end of the file and automatically
1540 + * adjust the settings for this buffer only. This must remain at the end
1542 + * ---------------------------------------------------------------------------
1543 + * Local variables:
1544 + * c-file-style: "linux"
1547 Index: uml-2.6.7/arch/um/main.c
1548 ===================================================================
1549 --- uml-2.6.7.orig/arch/um/main.c 2004-07-16 19:37:17.425376016 +0300
1550 +++ uml-2.6.7/arch/um/main.c 2004-07-16 19:47:23.762198808 +0300
1556 #include <sys/resource.h>
1557 #include <sys/mman.h>
1558 #include <sys/user.h>
1559 @@ -123,12 +124,14 @@
1563 - if((new_argv = malloc((argc + 1) * sizeof(char *))) == NULL){
1564 + new_argv = malloc((argc + 1) * sizeof(char *));
1565 + if(new_argv == NULL){
1566 perror("Mallocing argv");
1569 for(i=0;i<argc;i++){
1570 - if((new_argv[i] = strdup(argv[i])) == NULL){
1571 + new_argv[i] = strdup(argv[i]);
1572 + if(new_argv[i] == NULL){
1573 perror("Mallocing an arg");
1576 Index: uml-2.6.7/arch/um/kernel/tt/uaccess_user.c
1577 ===================================================================
1578 --- uml-2.6.7.orig/arch/um/kernel/tt/uaccess_user.c 2004-07-16 19:36:22.358747416 +0300
1579 +++ uml-2.6.7/arch/um/kernel/tt/uaccess_user.c 2004-07-16 19:47:23.752200328 +0300
1582 #include "user_util.h"
1583 #include "uml_uaccess.h"
1585 +#include "kern_util.h"
1587 int __do_copy_from_user(void *to, const void *from, int n,
1588 void **fault_addr, void **fault_catcher)
1590 + struct tt_regs save = TASK_REGS(get_current())->tt;
1591 unsigned long fault;
1594 fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
1595 __do_copy, &faulted);
1596 + TASK_REGS(get_current())->tt = save;
1598 if(!faulted) return(0);
1599 else return(n - (fault - (unsigned long) from));
1602 int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
1603 void **fault_addr, void **fault_catcher)
1605 + struct tt_regs save = TASK_REGS(get_current())->tt;
1606 unsigned long fault;
1609 fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
1610 __do_strncpy, &faulted);
1611 + TASK_REGS(get_current())->tt = save;
1613 if(!faulted) return(strlen(dst));
1617 int __do_clear_user(void *mem, unsigned long len,
1618 void **fault_addr, void **fault_catcher)
1620 + struct tt_regs save = TASK_REGS(get_current())->tt;
1621 unsigned long fault;
1624 fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
1625 __do_clear, &faulted);
1626 + TASK_REGS(get_current())->tt = save;
1628 if(!faulted) return(0);
1629 else return(len - (fault - (unsigned long) mem));
1632 int __do_strnlen_user(const char *str, unsigned long n,
1633 void **fault_addr, void **fault_catcher)
1635 + struct tt_regs save = TASK_REGS(get_current())->tt;
1637 unsigned long *faddrp = (unsigned long *)fault_addr;
1640 *fault_catcher = &jbuf;
1641 - if(setjmp(jbuf) == 0){
1642 + if(sigsetjmp(jbuf, 1) == 0)
1643 ret = strlen(str) + 1;
1646 - ret = *faddrp - (unsigned long) str;
1648 + else ret = *faddrp - (unsigned long) str;
1651 *fault_catcher = NULL;
1653 + TASK_REGS(get_current())->tt = save;
1657 Index: uml-2.6.7/arch/um/kernel/syscall_kern.c
1658 ===================================================================
1659 --- uml-2.6.7.orig/arch/um/kernel/syscall_kern.c 2004-07-16 19:37:08.748695072 +0300
1660 +++ uml-2.6.7/arch/um/kernel/syscall_kern.c 2004-07-16 19:47:23.737202608 +0300
1663 - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
1664 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
1665 * Licensed under the GPL
1672 - struct task_struct *p;
1675 current->thread.forking = 1;
1676 - p = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
1677 + ret = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
1678 current->thread.forking = 0;
1679 - return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
1683 -long sys_clone(unsigned long clone_flags, unsigned long newsp)
1684 +long sys_clone(unsigned long clone_flags, unsigned long newsp,
1685 + int *parent_tid, int *child_tid)
1687 - struct task_struct *p;
1690 current->thread.forking = 1;
1691 - p = do_fork(clone_flags, newsp, NULL, 0, NULL, NULL);
1692 + ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid);
1693 current->thread.forking = 0;
1694 - return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
1698 long sys_vfork(void)
1700 - struct task_struct *p;
1703 current->thread.forking = 1;
1704 - p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, NULL);
1705 + ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL,
1707 current->thread.forking = 0;
1708 - return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
1712 /* common code for old and new mmaps */
1713 @@ -136,43 +138,12 @@
1715 error = do_pipe(fd);
1717 - if (copy_to_user(fildes, fd, 2*sizeof(int)))
1718 + if (copy_to_user(fildes, fd, sizeof(fd)))
1724 -int sys_sigaction(int sig, const struct old_sigaction *act,
1725 - struct old_sigaction *oact)
1727 - struct k_sigaction new_ka, old_ka;
1731 - old_sigset_t mask;
1732 - if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
1733 - __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
1734 - __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
1736 - __get_user(new_ka.sa.sa_flags, &act->sa_flags);
1737 - __get_user(mask, &act->sa_mask);
1738 - siginitset(&new_ka.sa.sa_mask, mask);
1741 - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
1743 - if (!ret && oact) {
1744 - if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
1745 - __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
1746 - __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
1748 - __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
1749 - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
1756 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
1759 return sys_shmctl (first, second,
1760 (struct shmid_ds *) ptr);
1767 @@ -303,11 +274,6 @@
1771 -int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
1773 - return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs)));
1776 long execute_syscall(void *r)
1778 return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
1779 Index: uml-2.6.7/arch/um/kernel/skas/util/mk_ptregs.c
1780 ===================================================================
1781 --- uml-2.6.7.orig/arch/um/kernel/skas/util/mk_ptregs.c 2004-07-16 19:36:30.635489160 +0300
1782 +++ uml-2.6.7/arch/um/kernel/skas/util/mk_ptregs.c 2004-07-16 19:47:23.736202760 +0300
1785 #include <asm/ptrace.h>
1786 #include <asm/user.h>
1788 Index: uml-2.6.7/arch/um/kernel/skas/Makefile
1789 ===================================================================
1790 --- uml-2.6.7.orig/arch/um/kernel/skas/Makefile 2004-07-16 19:36:22.285758512 +0300
1791 +++ uml-2.6.7/arch/um/kernel/skas/Makefile 2004-07-16 19:47:23.729203824 +0300
1794 obj-y = exec_kern.o exec_user.o mem.o mem_user.o mmu.o process.o \
1795 process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o \
1797 + uaccess.o sys-$(SUBARCH)/
1799 +host-progs := util/mk_ptregs
1800 +clean-files := include/skas_ptregs.h
1802 USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
1803 USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
1805 -include/skas_ptregs.h : util/mk_ptregs
1806 - util/mk_ptregs > $@
1810 +$(TOPDIR)/arch/um/include/skas_ptregs.h : $(src)/util/mk_ptregs
1811 + @echo -n ' Generating $@'
1813 + @if [ -r $@ ] && cmp -s $@ $@.tmp; then \
1814 + echo ' (unchanged)'; \
1817 + echo ' (updated)'; \
1818 + mv -f $@.tmp $@; \
1821 $(USER_OBJS) : %.o: %.c
1822 $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
1825 - $(MAKE) -C util clean
1826 - $(RM) -f include/skas_ptregs.h
1827 Index: uml-2.6.7/include/asm-um/irq.h
1828 ===================================================================
1829 --- uml-2.6.7.orig/include/asm-um/irq.h 2004-07-16 19:37:43.396427816 +0300
1830 +++ uml-2.6.7/include/asm-um/irq.h 2004-07-16 19:47:23.790194552 +0300
1835 -/* The i386 irq.h has a struct task_struct in a prototype without including
1836 - * sched.h. This forward declaration kills the resulting warning.
1838 -struct task_struct;
1840 -#include "asm/ptrace.h"
1846 #define CONSOLE_IRQ 2
1848 #define LAST_IRQ XTERM_IRQ
1849 #define NR_IRQS (LAST_IRQ + 1)
1851 -extern int um_request_irq(unsigned int irq, int fd, int type,
1852 - void (*handler)(int, void *, struct pt_regs *),
1853 - unsigned long irqflags, const char * devname,
1858 -int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
1861 Index: uml-2.6.7/arch/um/drivers/line.c
1862 ===================================================================
1863 --- uml-2.6.7.orig/arch/um/drivers/line.c 2004-07-16 19:37:26.186044192 +0300
1864 +++ uml-2.6.7/arch/um/drivers/line.c 2004-07-16 19:47:23.685210512 +0300
1866 #include "linux/sched.h"
1867 #include "linux/slab.h"
1868 #include "linux/list.h"
1869 +#include "linux/interrupt.h"
1870 #include "linux/devfs_fs_kernel.h"
1871 -#include "asm/irq.h"
1872 #include "asm/uaccess.h"
1873 #include "chan_kern.h"
1874 #include "irq_user.h"
1876 #include "user_util.h"
1877 #include "kern_util.h"
1879 +#include "irq_kern.h"
1881 #define LINE_BUFSIZE 4096
1883 -void line_interrupt(int irq, void *data, struct pt_regs *unused)
1884 +static irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused)
1886 struct line *dev = data;
1889 chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq,
1891 + return IRQ_HANDLED;
1894 -void line_timer_cb(void *arg)
1895 +static void line_timer_cb(void *arg)
1897 struct line *dev = arg;
1899 line_interrupt(dev->driver->read_irq, dev, NULL);
1902 -static void buffer_data(struct line *line, const char *buf, int len)
1903 +static int write_room(struct line *dev)
1908 + if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
1910 + n = dev->head - dev->tail;
1911 + if(n <= 0) n = LINE_BUFSIZE + n;
1915 +static int buffer_data(struct line *line, const char *buf, int len)
1919 if(line->buffer == NULL){
1920 line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC);
1921 if(line->buffer == NULL){
1922 printk("buffer_data - atomic allocation failed\n");
1926 line->head = line->buffer;
1927 line->tail = line->buffer;
1930 + room = write_room(line);
1931 + len = (len > room) ? room : len;
1933 end = line->buffer + LINE_BUFSIZE - line->tail;
1935 memcpy(line->tail, buf, len);
1937 memcpy(line->buffer, buf, len);
1938 line->tail = line->buffer + len;
1944 static int flush_buffer(struct line *line)
1948 unsigned long flags;
1950 + int n, err, i, ret = 0;
1952 if(tty->stopped) return 0;
1954 @@ -104,9 +123,13 @@
1957 n = copy_from_user(new, buf, len);
1970 @@ -115,41 +138,50 @@
1972 if(line->head != line->tail){
1973 local_irq_save(flags);
1974 - buffer_data(line, buf, len);
1975 + ret += buffer_data(line, buf, len);
1976 err = flush_buffer(line);
1977 local_irq_restore(flags);
1983 n = write_chan(&line->chan_list, buf, len,
1984 line->driver->write_irq);
1992 - buffer_data(line, buf + n, len - n);
1997 + ret += buffer_data(line, buf + n, len);
2009 -void line_write_interrupt(int irq, void *data, struct pt_regs *unused)
2010 +static irqreturn_t line_write_interrupt(int irq, void *data,
2011 + struct pt_regs *unused)
2013 struct line *dev = data;
2014 struct tty_struct *tty = dev->tty;
2017 err = flush_buffer(dev);
2018 - if(err == 0) return;
2022 dev->head = dev->buffer;
2023 dev->tail = dev->buffer;
2026 - if(tty == NULL) return;
2030 if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
2031 (tty->ldisc.write_wakeup != NULL))
2032 @@ -161,21 +193,9 @@
2036 - if (waitqueue_active(&tty->write_wait))
2037 + if(waitqueue_active(&tty->write_wait))
2038 wake_up_interruptible(&tty->write_wait);
2042 -int line_write_room(struct tty_struct *tty)
2044 - struct line *dev = tty->driver_data;
2047 - if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
2049 - n = dev->head - dev->tail;
2050 - if(n <= 0) n = LINE_BUFSIZE + n;
2052 + return(IRQ_HANDLED);
2055 int line_setup_irq(int fd, int input, int output, void *data)
2058 printk(KERN_ERR "line_setup failed to parse \"%s\"\n",
2065 @@ -313,12 +333,12 @@
2066 if((n >= 0) && (n >= num)){
2067 printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
2073 if(lines[n].count > 0){
2074 printk("line_setup - device %d is open\n", n);
2078 if(lines[n].init_pri <= INIT_ONE){
2079 lines[n].init_pri = INIT_ONE;
2081 else if(!all_allowed){
2082 printk("line_setup - can't configure all devices from "
2088 for(i = 0; i < num; i++){
2097 int line_config(struct line *lines, int num, char *str)
2099 printk("line_config - uml_strdup failed\n");
2102 - return(line_setup(lines, num, new, 0));
2103 + return(!line_setup(lines, num, new, 0));
2106 int line_get_config(char *name, struct line *lines, int num, char *str,
2109 dev = simple_strtoul(name, &end, 0);
2110 if((*end != '\0') || (end == name)){
2111 - *error_out = "line_setup failed to parse device number";
2112 + *error_out = "line_get_config failed to parse device number";
2116 @@ -379,15 +399,15 @@
2124 CONFIG_CHUNK(str, size, n, "none", 1);
2125 else if(line->count == 0)
2126 CONFIG_CHUNK(str, size, n, line->init_str, 1);
2127 else n = chan_config_string(&line->chan_list, str, size, error_out);
2134 @@ -396,7 +416,14 @@
2135 char config[sizeof("conxxxx=none\0")];
2137 sprintf(config, "%s=none", str);
2138 - return(line_setup(lines, num, config, 0));
2139 + return(!line_setup(lines, num, config, 0));
2142 +int line_write_room(struct tty_struct *tty)
2144 + struct line *dev = tty->driver_data;
2146 + return(write_room(dev));
2149 struct tty_driver *line_register_devfs(struct lines *set,
2153 driver->driver_name = line_driver->name;
2154 - driver->name = line_driver->devfs_name;
2155 + driver->name = line_driver->device_name;
2156 + driver->devfs_name = line_driver->devfs_name;
2157 driver->major = line_driver->major;
2158 driver->minor_start = line_driver->minor_start;
2159 driver->type = line_driver->type;
2162 for(i = 0; i < nlines; i++){
2164 - tty_unregister_devfs(driver, i);
2165 + tty_unregister_device(driver, i);
2168 mconsole_register_dev(&line_driver->mc);
2169 @@ -465,24 +493,25 @@
2173 -void winch_interrupt(int irq, void *data, struct pt_regs *unused)
2174 +irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
2176 struct winch *winch = data;
2177 struct tty_struct *tty;
2181 - err = generic_read(winch->fd, &c, NULL);
2183 - if(err != -EAGAIN){
2184 - printk("winch_interrupt : read failed, errno = %d\n",
2186 - printk("fd %d is losing SIGWINCH support\n",
2188 - free_irq(irq, data);
2190 + if(winch->fd != -1){
2191 + err = generic_read(winch->fd, &c, NULL);
2193 + if(err != -EAGAIN){
2194 + printk("winch_interrupt : read failed, "
2195 + "errno = %d\n", -err);
2196 + printk("fd %d is losing SIGWINCH support\n",
2198 + return(IRQ_HANDLED);
2204 tty = winch->line->tty;
2207 kill_pg(tty->pgrp, SIGWINCH, 1);
2210 - reactivate_fd(winch->fd, WINCH_IRQ);
2211 + if(winch->fd != -1)
2212 + reactivate_fd(winch->fd, WINCH_IRQ);
2213 + return(IRQ_HANDLED);
2216 DECLARE_MUTEX(winch_handler_sem);
2217 @@ -529,7 +560,10 @@
2219 list_for_each(ele, &winch_handlers){
2220 winch = list_entry(ele, struct winch, list);
2222 + if(winch->fd != -1){
2223 + deactivate_fd(winch->fd, WINCH_IRQ);
2224 + os_close_file(winch->fd);
2226 if(winch->pid != -1)
2227 os_kill_process(winch->pid, 1);
2229 Index: uml-2.6.7/arch/um/kernel/tt/process_kern.c
2230 ===================================================================
2231 --- uml-2.6.7.orig/arch/um/kernel/tt/process_kern.c 2004-07-16 19:37:20.233949048 +0300
2232 +++ uml-2.6.7/arch/um/kernel/tt/process_kern.c 2004-07-16 19:47:23.746201240 +0300
2235 err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
2236 if(err != sizeof(c))
2237 - panic("write of switch_pipe failed, errno = %d", -err);
2238 + panic("write of switch_pipe failed, err = %d", -err);
2241 if((from->state == TASK_ZOMBIE) || (from->state == TASK_DEAD))
2242 @@ -104,48 +104,72 @@
2244 void release_thread_tt(struct task_struct *task)
2246 - os_kill_process(task->thread.mode.tt.extern_pid, 0);
2247 + int pid = task->thread.mode.tt.extern_pid;
2249 + if(os_getpid() != pid)
2250 + os_kill_process(pid, 0);
2253 void exit_thread_tt(void)
2255 - close(current->thread.mode.tt.switch_pipe[0]);
2256 - close(current->thread.mode.tt.switch_pipe[1]);
2257 + os_close_file(current->thread.mode.tt.switch_pipe[0]);
2258 + os_close_file(current->thread.mode.tt.switch_pipe[1]);
2261 void schedule_tail(task_t *prev);
2263 static void new_thread_handler(int sig)
2265 + unsigned long disable;
2269 fn = current->thread.request.u.thread.proc;
2270 arg = current->thread.request.u.thread.arg;
2272 UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1);
2273 + disable = (1 << (SIGVTALRM - 1)) | (1 << (SIGALRM - 1)) |
2274 + (1 << (SIGIO - 1)) | (1 << (SIGPROF - 1));
2275 + SC_SIGMASK(UPT_SC(¤t->thread.regs.regs)) &= ~disable;
2277 suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
2280 + force_flush_all();
2281 + if(current->thread.prev_sched != NULL)
2282 + schedule_tail(current->thread.prev_sched);
2283 + current->thread.prev_sched = NULL;
2285 init_new_thread_signals(1);
2287 - schedule_tail(current->thread.prev_sched);
2290 free_page(current->thread.temp_stack);
2291 set_cmdline("(kernel thread)");
2292 - force_flush_all();
2294 - current->thread.prev_sched = NULL;
2295 change_sig(SIGUSR1, 1);
2296 change_sig(SIGVTALRM, 1);
2297 change_sig(SIGPROF, 1);
2298 - unblock_signals();
2299 + local_irq_enable();
2300 if(!run_kernel_thread(fn, arg, ¤t->thread.exec_buf))
2304 static int new_thread_proc(void *stack)
2306 + /* local_irq_disable is needed to block out signals until this thread is
2307 + * properly scheduled. Otherwise, the tracing thread will get mighty
2308 + * upset about any signals that arrive before that.
2309 + * This has the complication that it sets the saved signal mask in
2310 + * the sigcontext to block signals. This gets restored when this
2311 + * thread (or a descendant, since they get a copy of this sigcontext)
2312 + * returns to userspace.
2313 + * So, this is compensated for elsewhere.
2314 + * XXX There is still a small window until local_irq_disable() actually
2315 + * finishes where signals are possible - shouldn't be a problem in
2316 + * practice since SIGIO hasn't been forwarded here yet, and the
2317 + * local_irq_disable should finish before a SIGVTALRM has time to be
2321 + local_irq_disable();
2322 init_new_thread_stack(stack, new_thread_handler);
2323 os_usr1_process(os_getpid());
2326 * itself with a SIGUSR1. set_user_mode has to be run with SIGUSR1 off,
2327 * so it is blocked before it's called. They are re-enabled on sigreturn
2328 * despite the fact that they were blocked when the SIGUSR1 was issued because
2329 - * copy_thread copies the parent's signcontext, including the signal mask
2330 + * copy_thread copies the parent's sigcontext, including the signal mask
2331 * onto the signal frame.
2334 @@ -165,35 +189,32 @@
2335 UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1);
2336 suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
2339 - schedule_tail(NULL);
2341 + force_flush_all();
2342 + if(current->thread.prev_sched != NULL)
2343 + schedule_tail(current->thread.prev_sched);
2344 + current->thread.prev_sched = NULL;
2347 change_sig(SIGVTALRM, 1);
2349 - force_flush_all();
2350 if(current->mm != current->parent->mm)
2351 protect_memory(uml_reserved, high_physmem - uml_reserved, 1,
2353 - task_protections((unsigned long) current->thread_info);
2355 - current->thread.prev_sched = NULL;
2356 + task_protections((unsigned long) current_thread);
2358 free_page(current->thread.temp_stack);
2359 + local_irq_disable();
2360 change_sig(SIGUSR1, 0);
2361 set_user_mode(current);
2364 -static int sigusr1 = SIGUSR1;
2366 int fork_tramp(void *stack)
2368 - int sig = sigusr1;
2370 local_irq_disable();
2371 + arch_init_thread();
2372 init_new_thread_stack(stack, finish_fork_handler);
2374 - kill(os_getpid(), sig);
2375 + os_usr1_process(os_getpid());
2382 err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1);
2384 - printk("copy_thread : pipe failed, errno = %d\n", -err);
2386 + printk("copy_thread : pipe failed, err = %d\n", -err);
2392 pages = (1 << CONFIG_KERNEL_STACK_ORDER);
2394 - start = (unsigned long) current->thread_info + PAGE_SIZE;
2395 - end = (unsigned long) current + PAGE_SIZE * pages;
2396 + start = (unsigned long) current_thread + PAGE_SIZE;
2397 + end = (unsigned long) current_thread + PAGE_SIZE * pages;
2398 protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1);
2399 protect_memory(end, high_physmem - end, 1, w, 1, 1);
2403 init_task.thread.mode.tt.extern_pid = pid;
2404 err = os_pipe(init_task.thread.mode.tt.switch_pipe, 1, 1);
2405 - if(err) panic("Can't create switch pipe for init_task, errno = %d",
2408 + panic("Can't create switch pipe for init_task, errno = %d",
2412 int singlestepping_tt(void *t)
2413 Index: uml-2.6.7/arch/um/include/2_5compat.h
2414 ===================================================================
2415 --- uml-2.6.7.orig/arch/um/include/2_5compat.h 2004-07-16 19:36:37.163496752 +0300
2416 +++ uml-2.6.7/arch/um/include/2_5compat.h 2004-07-16 19:47:23.700208232 +0300
2418 #ifndef __2_5_COMPAT_H__
2419 #define __2_5_COMPAT_H__
2421 -#include "linux/version.h"
2423 -#define INIT_CONSOLE(dev_name, write_proc, device_proc, setup_proc, f) { \
2424 - name : dev_name, \
2425 - write : write_proc, \
2427 - device : device_proc, \
2428 - setup : setup_proc, \
2435 #define INIT_HARDSECT(arr, maj, sizes)
2437 #define SET_PRI(task) do ; while(0)
2438 Index: uml-2.6.7/fs/hostfs/Makefile
2439 ===================================================================
2440 --- uml-2.6.7.orig/fs/hostfs/Makefile 2004-07-16 19:47:23.631218720 +0300
2441 +++ uml-2.6.7/fs/hostfs/Makefile 2004-07-16 19:47:23.784195464 +0300
2444 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
2445 +# Licensed under the GPL
2448 +# struct stat64 changed the inode field name between 2.2 and 2.4 from st_ino
2449 +# to __st_ino. It stayed in the same place, so as long as the correct name
2450 +# is used, hostfs compiled on 2.2 should work on 2.4 and vice versa.
2452 +STAT64_INO_FIELD := $(shell grep -q __st_ino /usr/include/bits/stat.h && \
2455 +hostfs-objs := hostfs_kern.o hostfs_user.o
2458 +obj-$(CONFIG_HOSTFS) += hostfs.o
2460 +SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
2462 +USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(SINGLE_OBJS))
2463 +USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
2465 +USER_CFLAGS += -DSTAT64_INO_FIELD=$(STAT64_INO_FIELD)
2467 +$(USER_OBJS) : %.o: %.c
2468 + $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
2469 Index: uml-2.6.7/arch/um/kernel/skas/mmu.c
2470 ===================================================================
2471 --- uml-2.6.7.orig/arch/um/kernel/skas/mmu.c 2004-07-16 19:37:51.994120768 +0300
2472 +++ uml-2.6.7/arch/um/kernel/skas/mmu.c 2004-07-16 19:47:23.730203672 +0300
2476 mm->context.skas.mm_fd = new_mm(from);
2477 - if(mm->context.skas.mm_fd < 0)
2478 - panic("init_new_context_skas - new_mm failed, errno = %d\n",
2479 - mm->context.skas.mm_fd);
2480 + if(mm->context.skas.mm_fd < 0){
2481 + printk("init_new_context_skas - new_mm failed, errno = %d\n",
2482 + mm->context.skas.mm_fd);
2483 + return(mm->context.skas.mm_fd);
2488 Index: uml-2.6.7/arch/um/kernel/skas/sys-i386/sigcontext.c
2489 ===================================================================
2490 --- uml-2.6.7.orig/arch/um/kernel/skas/sys-i386/sigcontext.c 2004-07-16 19:35:56.079742432 +0300
2491 +++ uml-2.6.7/arch/um/kernel/skas/sys-i386/sigcontext.c 2004-07-16 19:47:23.733203216 +0300
2493 #include "kern_util.h"
2495 #include "sigcontext.h"
2498 -extern int userspace_pid;
2500 -int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr)
2501 +int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, void *from_ptr)
2503 struct sigcontext sc, *from = from_ptr;
2504 unsigned long fpregs[FP_FRAME_SIZE];
2506 regs->skas.regs[EIP] = sc.eip;
2507 regs->skas.regs[CS] = sc.cs;
2508 regs->skas.regs[EFL] = sc.eflags;
2509 - regs->skas.regs[UESP] = sc.esp_at_signal;
2510 regs->skas.regs[SS] = sc.ss;
2511 regs->skas.fault_addr = sc.cr2;
2512 regs->skas.fault_type = FAULT_WRITE(sc.err);
2513 regs->skas.trap_type = sc.trapno;
2515 - err = ptrace(PTRACE_SETFPREGS, userspace_pid, 0, fpregs);
2516 + err = ptrace(PTRACE_SETFPREGS, pid, 0, fpregs);
2518 printk("copy_sc_to_user - PTRACE_SETFPREGS failed, "
2519 "errno = %d\n", errno);
2524 -int copy_sc_to_user_skas(void *to_ptr, void *fp, union uml_pt_regs *regs,
2525 - unsigned long fault_addr, int fault_type)
2526 +int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp,
2527 + union uml_pt_regs *regs, unsigned long fault_addr,
2530 struct sigcontext sc, *to = to_ptr;
2531 struct _fpstate *to_fp;
2533 sc.err = TO_SC_ERR(fault_type);
2534 sc.trapno = regs->skas.trap_type;
2536 - err = ptrace(PTRACE_GETFPREGS, userspace_pid, 0, fpregs);
2537 + err = ptrace(PTRACE_GETFPREGS, pid, 0, fpregs);
2539 printk("copy_sc_to_user - PTRACE_GETFPREGS failed, "
2540 "errno = %d\n", errno);
2541 Index: uml-2.6.7/arch/um/kernel/skas/process.c
2542 ===================================================================
2543 --- uml-2.6.7.orig/arch/um/kernel/skas/process.c 2004-07-16 19:37:38.120229920 +0300
2544 +++ uml-2.6.7/arch/um/kernel/skas/process.c 2004-07-16 19:47:24.793042096 +0300
2549 +#include <unistd.h>
2555 #include "proc_mm.h"
2556 #include "skas_ptrace.h"
2557 +#include "chan_user.h"
2558 +#include "signal_user.h"
2560 +int is_skas_winch(int pid, int fd, void *data)
2562 + if(pid != getpid())
2565 + register_winch_irq(-1, fd, -1, data);
2569 +/* These are set once at boot time and not changed thereafter */
2571 unsigned long exec_regs[FRAME_SIZE];
2572 unsigned long exec_fp_regs[HOST_FP_SIZE];
2574 segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL);
2577 -static void handle_trap(int pid, union uml_pt_regs *regs)
2578 +/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/
2579 +static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu)
2581 int err, syscall_nr, status;
2583 syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
2584 + UPT_SYSCALL_NR(regs) = syscall_nr;
2586 relay_signal(SIGTRAP, regs);
2589 - UPT_SYSCALL_NR(regs) = syscall_nr;
2591 - err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
2593 - panic("handle_trap - nullifying syscall failed errno = %d\n",
2595 + if (!local_using_sysemu)
2597 + err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
2599 + panic("handle_trap - nullifying syscall failed errno = %d\n",
2602 - err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
2604 - panic("handle_trap - continuing to end of syscall failed, "
2605 - "errno = %d\n", errno);
2607 - err = waitpid(pid, &status, WUNTRACED);
2608 - if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
2609 - panic("handle_trap - failed to wait at end of syscall, "
2610 - "errno = %d, status = %d\n", errno, status);
2611 + err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
2613 + panic("handle_trap - continuing to end of syscall failed, "
2614 + "errno = %d\n", errno);
2616 + CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
2617 + if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
2618 + panic("handle_trap - failed to wait at end of syscall, "
2619 + "errno = %d, status = %d\n", errno, status);
2622 handle_syscall(regs);
2627 static int userspace_tramp(void *arg)
2629 init_new_thread_signals(0);
2634 -void start_userspace(void)
2635 +/* Each element set once, and only accessed by a single processor anyway */
2637 +int userspace_pid[NR_CPUS];
2639 +void start_userspace(int cpu)
2644 panic("start_userspace : clone failed, errno = %d", errno);
2647 - n = waitpid(pid, &status, WUNTRACED);
2648 + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
2650 panic("start_userspace : wait failed, errno = %d",
2652 @@ -114,21 +134,27 @@
2653 if(munmap(stack, PAGE_SIZE) < 0)
2654 panic("start_userspace : munmap failed, errno = %d\n", errno);
2656 - userspace_pid = pid;
2657 + userspace_pid[cpu] = pid;
2660 void userspace(union uml_pt_regs *regs)
2662 - int err, status, op;
2663 + int err, status, op, pid = userspace_pid[0];
2664 + int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/
2666 restore_registers(regs);
2668 - err = ptrace(PTRACE_SYSCALL, userspace_pid, 0, 0);
2669 + local_using_sysemu = get_using_sysemu();
2671 + if (local_using_sysemu)
2672 + err = ptrace(PTRACE_SYSEMU, pid, 0, 0);
2674 + err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
2676 panic("userspace - PTRACE_SYSCALL failed, errno = %d\n",
2679 - err = waitpid(userspace_pid, &status, WUNTRACED);
2680 + CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
2682 panic("userspace - waitpid failed, errno = %d\n",
2684 @@ -139,16 +165,17 @@
2685 if(WIFSTOPPED(status)){
2686 switch(WSTOPSIG(status)){
2688 - handle_segv(userspace_pid);
2692 - handle_trap(userspace_pid, regs);
2693 + handle_trap(pid, regs, local_using_sysemu);
2701 user_signal(WSTOPSIG(status), regs);
2704 @@ -160,9 +187,17 @@
2706 restore_registers(regs);
2708 - op = singlestepping_skas() ? PTRACE_SINGLESTEP :
2710 - err = ptrace(op, userspace_pid, 0, 0);
2711 + /*Now we ended the syscall, so re-read local_using_sysemu.*/
2712 + local_using_sysemu = get_using_sysemu();
2714 + if (local_using_sysemu)
2715 + op = singlestepping_skas() ? PTRACE_SINGLESTEP :
2718 + op = singlestepping_skas() ? PTRACE_SINGLESTEP :
2721 + err = ptrace(op, pid, 0, 0);
2723 panic("userspace - PTRACE_SYSCALL failed, "
2724 "errno = %d\n", errno);
2725 @@ -172,13 +207,25 @@
2726 void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
2727 void (*handler)(int))
2729 + unsigned long flags;
2730 jmp_buf switch_buf, fork_buf;
2732 *switch_buf_ptr = &switch_buf;
2733 *fork_buf_ptr = &fork_buf;
2735 - if(setjmp(fork_buf) == 0)
2736 + /* Somewhat subtle - siglongjmp restores the signal mask before doing
2737 + * the longjmp. This means that when jumping from one stack to another
2738 + * when the target stack has interrupts enabled, an interrupt may occur
2739 + * on the source stack. This is bad when starting up a process because
2740 + * it's not supposed to get timer ticks until it has been scheduled.
2741 + * So, we disable interrupts around the sigsetjmp to ensure that
2742 + * they can't happen until we get back here where they are safe.
2744 + flags = get_signals();
2746 + if(sigsetjmp(fork_buf, 1) == 0)
2747 new_thread_proc(stack, handler);
2748 + set_signals(flags);
2752 @@ -189,16 +236,16 @@
2756 - if(setjmp(buf) == 0)
2757 - longjmp(*fork_buf, 1);
2758 + if(sigsetjmp(buf, 1) == 0)
2759 + siglongjmp(*fork_buf, 1);
2762 -static int move_registers(int int_op, int fp_op, union uml_pt_regs *regs,
2763 - unsigned long *fp_regs)
2764 +static int move_registers(int pid, int int_op, int fp_op,
2765 + union uml_pt_regs *regs, unsigned long *fp_regs)
2767 - if(ptrace(int_op, userspace_pid, 0, regs->skas.regs) < 0)
2768 + if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
2770 - if(ptrace(fp_op, userspace_pid, 0, fp_regs) < 0)
2771 + if(ptrace(fp_op, pid, 0, fp_regs) < 0)
2775 @@ -217,10 +264,11 @@
2776 fp_regs = regs->skas.fp;
2779 - err = move_registers(PTRACE_GETREGS, fp_op, regs, fp_regs);
2780 + err = move_registers(userspace_pid[0], PTRACE_GETREGS, fp_op, regs,
2783 panic("save_registers - saving registers failed, errno = %d\n",
2788 void restore_registers(union uml_pt_regs *regs)
2789 @@ -237,10 +285,11 @@
2790 fp_regs = regs->skas.fp;
2793 - err = move_registers(PTRACE_SETREGS, fp_op, regs, fp_regs);
2794 + err = move_registers(userspace_pid[0], PTRACE_SETREGS, fp_op, regs,
2797 panic("restore_registers - saving registers failed, "
2798 - "errno = %d\n", err);
2799 + "errno = %d\n", -err);
2802 void switch_threads(void *me, void *next)
2804 jmp_buf my_buf, **me_ptr = me, *next_buf = next;
2807 - if(setjmp(my_buf) == 0)
2808 - longjmp(*next_buf, 1);
2809 + if(sigsetjmp(my_buf, 1) == 0)
2810 + siglongjmp(*next_buf, 1);
2813 static jmp_buf initial_jmpbuf;
2814 @@ -265,14 +314,14 @@
2817 *fork_buf_ptr = &initial_jmpbuf;
2818 - n = setjmp(initial_jmpbuf);
2819 + n = sigsetjmp(initial_jmpbuf, 1);
2821 new_thread_proc((void *) stack, new_thread_handler);
2826 - longjmp(*cb_back, 1);
2827 + siglongjmp(*cb_back, 1);
2835 - longjmp(**switch_buf, 1);
2836 + siglongjmp(**switch_buf, 1);
2839 void remove_sigstack(void)
2844 - if(setjmp(here) == 0)
2845 - longjmp(initial_jmpbuf, 2);
2846 + if(sigsetjmp(here, 1) == 0)
2847 + siglongjmp(initial_jmpbuf, 2);
2851 @@ -316,22 +365,23 @@
2852 void halt_skas(void)
2855 - longjmp(initial_jmpbuf, 3);
2856 + siglongjmp(initial_jmpbuf, 3);
2859 void reboot_skas(void)
2862 - longjmp(initial_jmpbuf, 4);
2863 + siglongjmp(initial_jmpbuf, 4);
2866 int new_mm(int from)
2868 struct proc_mm_op copy;
2869 - int n, fd = os_open_file("/proc/mm", of_write(OPENFLAGS()), 0);
2870 + int n, fd = os_open_file("/proc/mm",
2871 + of_cloexec(of_write(OPENFLAGS())), 0);
2878 copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS,
2880 n = os_write_file(fd, ©, sizeof(copy));
2881 if(n != sizeof(copy))
2882 printk("new_mm : /proc/mm copy_segments failed, "
2883 - "errno = %d\n", errno);
2884 + "err = %d\n", -n);
2894 - err = ptrace(PTRACE_SWITCH_MM, userspace_pid, 0, mm_fd);
2895 +#warning need cpu pid in switch_mm_skas
2896 + err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, mm_fd);
2898 panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n",
2902 void kill_off_processes_skas(void)
2904 - os_kill_process(userspace_pid, 1);
2905 +#warning need to loop over userspace_pids in kill_off_processes_skas
2906 + os_kill_process(userspace_pid[0], 1);
2909 void init_registers(int pid)
2910 Index: uml-2.6.7/arch/um/os-Linux/tty.c
2911 ===================================================================
2912 --- uml-2.6.7.orig/arch/um/os-Linux/tty.c 2004-07-16 19:36:54.138916096 +0300
2913 +++ uml-2.6.7/arch/um/os-Linux/tty.c 2004-07-16 19:47:23.769197744 +0300
2915 struct grantpt_info info;
2918 - if((fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0)) < 0){
2919 - printk("get_pty : Couldn't open /dev/ptmx - errno = %d\n",
2922 + fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0);
2924 + printk("get_pty : Couldn't open /dev/ptmx - err = %d\n", -fd);
2932 printk("get_pty : Couldn't grant pty - errno = %d\n",
2937 if(unlockpt(fd) < 0){
2938 Index: uml-2.6.7/arch/um/sys-ia64/Makefile
2939 ===================================================================
2940 --- uml-2.6.7.orig/arch/um/sys-ia64/Makefile 2004-07-16 19:35:55.505829680 +0300
2941 +++ uml-2.6.7/arch/um/sys-ia64/Makefile 2004-07-16 19:47:23.778196376 +0300
2945 $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
2955 - @$(MAKEBOOT) clean
2961 +clean-files := $(OBJS) link.ld
2962 Index: uml-2.6.7/arch/um/sys-i386/util/mk_sc.c
2963 ===================================================================
2964 --- uml-2.6.7.orig/arch/um/sys-i386/util/mk_sc.c 2004-07-16 19:37:26.086059392 +0300
2965 +++ uml-2.6.7/arch/um/sys-i386/util/mk_sc.c 2004-07-16 19:47:23.778196376 +0300
2967 SC_OFFSET("SC_ERR", err);
2968 SC_OFFSET("SC_CR2", cr2);
2969 SC_OFFSET("SC_FPSTATE", fpstate);
2970 + SC_OFFSET("SC_SIGMASK", oldmask);
2971 SC_FP_OFFSET("SC_FP_CW", cw);
2972 SC_FP_OFFSET("SC_FP_SW", sw);
2973 SC_FP_OFFSET("SC_FP_TAG", tag);
2974 Index: uml-2.6.7/arch/um/sys-i386/Makefile
2975 ===================================================================
2976 --- uml-2.6.7.orig/arch/um/sys-i386/Makefile 2004-07-16 19:36:05.106370176 +0300
2977 +++ uml-2.6.7/arch/um/sys-i386/Makefile 2004-07-16 19:47:23.772197288 +0300
2979 -obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o module.o \
2980 - ptrace.o ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
2981 +obj-y = bugs.o checksum.o fault.o ksyms.o ldt.o ptrace.o ptrace_user.o \
2982 + semaphore.o sigcontext.o syscalls.o sysrq.o time.o
2984 obj-$(CONFIG_HIGHMEM) += highmem.o
2985 +obj-$(CONFIG_MODULES) += module.o
2987 USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
2988 USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
2990 SYMLINKS = semaphore.c highmem.c module.c
2991 SYMLINKS := $(foreach f,$(SYMLINKS),$(src)/$f)
2993 +clean-files := $(SYMLINKS)
2995 semaphore.c-dir = kernel
2997 module.c-dir = kernel
3000 $(call make_link,$@)
3003 - $(MAKE) -C util clean
3019 Index: uml-2.6.7/arch/um/kernel/signal_kern.c
3020 ===================================================================
3021 --- uml-2.6.7.orig/arch/um/kernel/signal_kern.c 2004-07-16 19:36:51.321344432 +0300
3022 +++ uml-2.6.7/arch/um/kernel/signal_kern.c 2004-07-16 19:47:23.726204280 +0300
3025 struct k_sigaction *ka;
3027 - ka = ¤t->sig->action[SIGSEGV - 1];
3028 + ka = ¤t->sighand->action[SIGSEGV - 1];
3029 ka->sa.sa_handler = SIG_DFL;
3031 force_sig(SIGSEGV, current);
3036 + /* Always make any pending restarted system calls return -EINTR */
3037 + current_thread_info()->restart_block.fn = do_no_restart_syscall;
3039 case -ERESTART_RESTARTBLOCK:
3040 - current_thread_info()->restart_block.fn =
3041 - do_no_restart_syscall;
3042 case -ERESTARTNOHAND:
3048 /* Whee! Actually deliver the signal. */
3049 - ka = ¤t->sig->action[sig -1 ];
3050 + ka = ¤t->sighand->action[sig -1 ];
3051 err = handle_signal(regs, sig, ka, &info, oldset, error);
3058 -int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
3059 +int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
3061 sigset_t saveset, newset;
3063 @@ -227,20 +227,59 @@
3067 +int sys_sigaction(int sig, const struct old_sigaction __user *act,
3068 + struct old_sigaction __user *oact)
3070 + struct k_sigaction new_ka, old_ka;
3074 + old_sigset_t mask;
3075 + if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
3076 + __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
3077 + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
3079 + __get_user(new_ka.sa.sa_flags, &act->sa_flags);
3080 + __get_user(mask, &act->sa_mask);
3081 + siginitset(&new_ka.sa.sa_mask, mask);
3084 + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
3086 + if (!ret && oact) {
3087 + if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
3088 + __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
3089 + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
3091 + __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
3092 + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
3098 +int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
3100 + return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs)));
3103 +extern int userspace_pid[];
3105 static int copy_sc_from_user(struct pt_regs *to, void *from,
3106 struct arch_frame_data *arch)
3110 ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, arch),
3111 - copy_sc_from_user_skas(&to->regs, from));
3112 + copy_sc_from_user_skas(userspace_pid[0],
3113 + &to->regs, from));
3117 int sys_sigreturn(struct pt_regs regs)
3119 - void *sc = sp_to_sc(PT_REGS_SP(¤t->thread.regs));
3120 - void *mask = sp_to_mask(PT_REGS_SP(¤t->thread.regs));
3121 + void __user *sc = sp_to_sc(PT_REGS_SP(¤t->thread.regs));
3122 + void __user *mask = sp_to_mask(PT_REGS_SP(¤t->thread.regs));
3123 int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
3125 spin_lock_irq(¤t->sighand->siglock);
3128 int sys_rt_sigreturn(struct pt_regs regs)
3130 - struct ucontext *uc = sp_to_uc(PT_REGS_SP(¤t->thread.regs));
3132 + unsigned long sp = PT_REGS_SP(¤t->thread.regs);
3133 + struct ucontext __user *uc = sp_to_uc(sp);
3134 int sig_size = _NSIG_WORDS * sizeof(unsigned long);
3136 spin_lock_irq(¤t->sighand->siglock);
3138 sigdelsetmask(¤t->blocked, ~_BLOCKABLE);
3139 recalc_sigpending();
3140 spin_unlock_irq(¤t->sighand->siglock);
3141 - fp = (void *) (((unsigned long) uc) + sizeof(struct ucontext));
3142 copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext,
3143 &signal_frame_si.common.arch);
3144 return(PT_REGS_SYSCALL_RET(¤t->thread.regs));
3145 Index: uml-2.6.7/arch/um/kernel/sysrq.c
3146 ===================================================================
3147 --- uml-2.6.7.orig/arch/um/kernel/sysrq.c 2004-07-16 19:36:24.697391888 +0300
3148 +++ uml-2.6.7/arch/um/kernel/sysrq.c 2004-07-16 19:47:23.739202304 +0300
3151 EXPORT_SYMBOL(dump_stack);
3153 +void show_stack(struct task_struct *task, unsigned long *sp)
3159 * Overrides for Emacs so that we follow Linus's tabbing style.
3160 * Emacs will notice this stuff at the end of the file and automatically
3161 Index: uml-2.6.7/arch/um/include/sysdep-i386/syscalls.h
3162 ===================================================================
3163 --- uml-2.6.7.orig/arch/um/include/sysdep-i386/syscalls.h 2004-07-16 19:36:04.873405592 +0300
3164 +++ uml-2.6.7/arch/um/include/sysdep-i386/syscalls.h 2004-07-16 19:47:23.708207016 +0300
3166 #define EXECUTE_SYSCALL(syscall, regs) \
3167 ((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs))
3169 -extern syscall_handler_t sys_modify_ldt;
3170 -extern syscall_handler_t old_mmap_i386;
3171 -extern syscall_handler_t old_select;
3172 -extern syscall_handler_t sys_ni_syscall;
3174 #define ARCH_SYSCALLS \
3175 - [ __NR_mmap ] = old_mmap_i386, \
3176 - [ __NR_select ] = old_select, \
3177 - [ __NR_vm86old ] = sys_ni_syscall, \
3178 - [ __NR_modify_ldt ] = sys_modify_ldt, \
3179 - [ __NR_lchown32 ] = sys_lchown, \
3180 - [ __NR_getuid32 ] = sys_getuid, \
3181 - [ __NR_getgid32 ] = sys_getgid, \
3182 - [ __NR_geteuid32 ] = sys_geteuid, \
3183 - [ __NR_getegid32 ] = sys_getegid, \
3184 - [ __NR_setreuid32 ] = sys_setreuid, \
3185 - [ __NR_setregid32 ] = sys_setregid, \
3186 - [ __NR_getgroups32 ] = sys_getgroups, \
3187 - [ __NR_setgroups32 ] = sys_setgroups, \
3188 - [ __NR_fchown32 ] = sys_fchown, \
3189 - [ __NR_setresuid32 ] = sys_setresuid, \
3190 - [ __NR_getresuid32 ] = sys_getresuid, \
3191 - [ __NR_setresgid32 ] = sys_setresgid, \
3192 - [ __NR_getresgid32 ] = sys_getresgid, \
3193 - [ __NR_chown32 ] = sys_chown, \
3194 - [ __NR_setuid32 ] = sys_setuid, \
3195 - [ __NR_setgid32 ] = sys_setgid, \
3196 - [ __NR_setfsuid32 ] = sys_setfsuid, \
3197 - [ __NR_setfsgid32 ] = sys_setfsgid, \
3198 - [ __NR_pivot_root ] = sys_pivot_root, \
3199 - [ __NR_mincore ] = sys_mincore, \
3200 - [ __NR_madvise ] = sys_madvise, \
3201 - [ 222 ] = sys_ni_syscall,
3202 + [ __NR_mmap ] = (syscall_handler_t *) old_mmap_i386, \
3203 + [ __NR_select ] = (syscall_handler_t *) old_select, \
3204 + [ __NR_vm86old ] = (syscall_handler_t *) sys_ni_syscall, \
3205 + [ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \
3206 + [ __NR_lchown32 ] = (syscall_handler_t *) sys_lchown, \
3207 + [ __NR_getuid32 ] = (syscall_handler_t *) sys_getuid, \
3208 + [ __NR_getgid32 ] = (syscall_handler_t *) sys_getgid, \
3209 + [ __NR_geteuid32 ] = (syscall_handler_t *) sys_geteuid, \
3210 + [ __NR_getegid32 ] = (syscall_handler_t *) sys_getegid, \
3211 + [ __NR_setreuid32 ] = (syscall_handler_t *) sys_setreuid, \
3212 + [ __NR_setregid32 ] = (syscall_handler_t *) sys_setregid, \
3213 + [ __NR_getgroups32 ] = (syscall_handler_t *) sys_getgroups, \
3214 + [ __NR_setgroups32 ] = (syscall_handler_t *) sys_setgroups, \
3215 + [ __NR_fchown32 ] = (syscall_handler_t *) sys_fchown, \
3216 + [ __NR_setresuid32 ] = (syscall_handler_t *) sys_setresuid, \
3217 + [ __NR_getresuid32 ] = (syscall_handler_t *) sys_getresuid, \
3218 + [ __NR_setresgid32 ] = (syscall_handler_t *) sys_setresgid, \
3219 + [ __NR_getresgid32 ] = (syscall_handler_t *) sys_getresgid, \
3220 + [ __NR_chown32 ] = (syscall_handler_t *) sys_chown, \
3221 + [ __NR_setuid32 ] = (syscall_handler_t *) sys_setuid, \
3222 + [ __NR_setgid32 ] = (syscall_handler_t *) sys_setgid, \
3223 + [ __NR_setfsuid32 ] = (syscall_handler_t *) sys_setfsuid, \
3224 + [ __NR_setfsgid32 ] = (syscall_handler_t *) sys_setfsgid, \
3225 + [ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \
3226 + [ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \
3227 + [ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \
3228 + [ 222 ] = (syscall_handler_t *) sys_ni_syscall,
3230 /* 222 doesn't yet have a name in include/asm-i386/unistd.h */
3232 Index: uml-2.6.7/include/linux/time.h
3233 ===================================================================
3234 --- uml-2.6.7.orig/include/linux/time.h 2004-07-16 19:36:57.136460400 +0300
3235 +++ uml-2.6.7/include/linux/time.h 2004-07-16 19:47:23.805192272 +0300
3237 * Have the 32 bit jiffies value wrap 5 minutes after boot
3238 * so jiffies wrap bugs show up earlier.
3240 -#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))
3241 +#define INITIAL_JIFFIES ((unsigned long)(0))
3244 * Change timeval to jiffies, trying to avoid the
3245 Index: uml-2.6.7/include/asm-um/page.h
3246 ===================================================================
3247 --- uml-2.6.7.orig/include/asm-um/page.h 2004-07-16 19:36:51.390333944 +0300
3248 +++ uml-2.6.7/include/asm-um/page.h 2004-07-16 19:47:23.792194248 +0300
3251 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
3252 + * Licensed under the GPL
3260 #include "asm/arch/page.h"
3261 -#include "asm/bug.h"
3267 #define __va_space (8*1024*1024)
3269 -extern unsigned long region_pa(void *virt);
3270 -extern void *region_va(unsigned long phys);
3272 -#define __pa(virt) region_pa((void *) (virt))
3273 -#define __va(phys) region_va((unsigned long) (phys))
3275 -extern unsigned long page_to_pfn(struct page *page);
3276 -extern struct page *pfn_to_page(unsigned long pfn);
3277 +extern unsigned long to_phys(void *virt);
3278 +extern void *to_virt(unsigned long phys);
3280 -extern struct page *phys_to_page(unsigned long phys);
3281 +#define __pa(virt) to_phys((void *) virt)
3282 +#define __va(phys) to_virt((unsigned long) phys)
3284 -#define virt_to_page(v) (phys_to_page(__pa(v)))
3285 +#define page_to_pfn(page) ((page) - mem_map)
3286 +#define pfn_to_page(pfn) (mem_map + (pfn))
3288 -extern struct page *page_mem_map(struct page *page);
3289 +#define phys_to_pfn(p) ((p) >> PAGE_SHIFT)
3290 +#define pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)
3292 -#define pfn_valid(pfn) (page_mem_map(pfn_to_page(pfn)) != NULL)
3293 -#define virt_addr_valid(v) pfn_valid(__pa(v) >> PAGE_SHIFT)
3294 +#define pfn_valid(pfn) ((pfn) < max_mapnr)
3295 +#define virt_addr_valid(v) pfn_valid(phys_to_pfn(__pa(v)))
3297 extern struct page *arch_validate(struct page *page, int mask, int order);
3298 #define HAVE_ARCH_VALIDATE
3300 +extern void arch_free_page(struct page *page, int order);
3301 +#define HAVE_ARCH_FREE_PAGE
3306 + * Overrides for Emacs so that we follow Linus's tabbing style.
3307 + * Emacs will notice this stuff at the end of the file and automatically
3308 + * adjust the settings for this buffer only. This must remain at the end
3310 + * ---------------------------------------------------------------------------
3311 + * Local variables:
3312 + * c-file-style: "linux"
3315 Index: uml-2.6.7/arch/um/include/signal_user.h
3316 ===================================================================
3317 --- uml-2.6.7.orig/arch/um/include/signal_user.h 2004-07-16 19:35:55.511828768 +0300
3318 +++ uml-2.6.7/arch/um/include/signal_user.h 2004-07-16 19:47:23.705207472 +0300
3320 extern int change_sig(int signal, int on);
3321 extern void set_sigstack(void *stack, int size);
3322 extern void set_handler(int sig, void (*handler)(int), int flags, ...);
3323 +extern int set_signals(int enable);
3324 +extern int get_signals(void);
3328 Index: uml-2.6.7/include/asm-um/local.h
3329 ===================================================================
3330 --- uml-2.6.7.orig/include/asm-um/local.h 2004-07-16 19:47:23.633218416 +0300
3331 +++ uml-2.6.7/include/asm-um/local.h 2004-07-16 19:47:23.791194400 +0300
3333 +#ifndef __UM_LOCAL_H
3334 +#define __UM_LOCAL_H
3336 +#include "asm/arch/local.h"
3339 Index: uml-2.6.7/include/asm-um/thread_info.h
3340 ===================================================================
3341 --- uml-2.6.7.orig/include/asm-um/thread_info.h 2004-07-16 19:36:22.451733280 +0300
3342 +++ uml-2.6.7/include/asm-um/thread_info.h 2004-07-16 19:47:23.803192576 +0300
3344 #ifndef __ASSEMBLY__
3346 #include <asm/processor.h>
3347 +#include <asm/types.h>
3349 struct thread_info {
3350 struct task_struct *task; /* main task structure */
3352 static inline struct thread_info *current_thread_info(void)
3354 struct thread_info *ti;
3355 - __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~16383UL));
3356 + unsigned long mask = PAGE_SIZE *
3357 + (1 << CONFIG_KERNEL_STACK_ORDER) - 1;
3358 + __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~mask));
3362 /* thread information allocation */
3363 -#define THREAD_SIZE (4*PAGE_SIZE)
3364 -#define alloc_thread_info(tsk) ((struct thread_info *) \
3365 - __get_free_pages(GFP_KERNEL,2))
3366 -#define free_thread_info(ti) free_pages((unsigned long) (ti), 2)
3367 +#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
3368 +#define alloc_thread_info(tsk) \
3369 + ((struct thread_info *) kmalloc(THREAD_SIZE, GFP_KERNEL))
3370 +#define free_thread_info(ti) kfree(ti)
3372 #define get_thread_info(ti) get_task_struct((ti)->task)
3373 #define put_thread_info(ti) put_task_struct((ti)->task)
3376 #define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling
3379 +#define TIF_RESTART_BLOCK 4
3381 #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
3382 #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
3383 #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
3384 #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
3385 +#define _TIF_RESTART_BLOCK (1 << TIF_RESTART_BLOCK)
3389 Index: uml-2.6.7/include/asm-um/dma-mapping.h
3390 ===================================================================
3391 --- uml-2.6.7.orig/include/asm-um/dma-mapping.h 2004-07-16 19:36:02.148819792 +0300
3392 +++ uml-2.6.7/include/asm-um/dma-mapping.h 2004-07-16 19:47:23.789194704 +0300
3394 -#include <asm-generic/dma-mapping.h>
3395 +#ifndef _ASM_DMA_MAPPING_H
3396 +#define _ASM_DMA_MAPPING_H
3399 +dma_supported(struct device *dev, u64 mask)
3406 +dma_set_mask(struct device *dev, u64 dma_mask)
3412 +static inline void *
3413 +dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
3417 + return((void *) 0);
3421 +dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
3422 + dma_addr_t dma_handle)
3427 +static inline dma_addr_t
3428 +dma_map_single(struct device *dev, void *cpu_addr, size_t size,
3429 + enum dma_data_direction direction)
3436 +dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
3437 + enum dma_data_direction direction)
3442 +static inline dma_addr_t
3443 +dma_map_page(struct device *dev, struct page *page,
3444 + unsigned long offset, size_t size,
3445 + enum dma_data_direction direction)
3452 +dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
3453 + enum dma_data_direction direction)
3459 +dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
3460 + enum dma_data_direction direction)
3467 +dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
3468 + enum dma_data_direction direction)
3474 +dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size,
3475 + enum dma_data_direction direction)
3481 +dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems,
3482 + enum dma_data_direction direction)
3487 +#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
3488 +#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
3489 +#define dma_is_consistent(d) (1)
3492 +dma_get_cache_alignment(void)
3499 +dma_sync_single_range(struct device *dev, dma_addr_t dma_handle,
3500 + unsigned long offset, size_t size,
3501 + enum dma_data_direction direction)
3507 +dma_cache_sync(void *vaddr, size_t size,
3508 + enum dma_data_direction direction)
3514 Index: uml-2.6.7/arch/um/kernel/skas/syscall_user.c
3515 ===================================================================
3516 --- uml-2.6.7.orig/arch/um/kernel/skas/syscall_user.c 2004-07-16 19:37:35.225669960 +0300
3517 +++ uml-2.6.7/arch/um/kernel/skas/syscall_user.c 2004-07-16 19:47:23.732203368 +0300
3520 index = record_syscall_start(UPT_SYSCALL_NR(regs));
3523 + syscall_trace(regs, 1);
3524 result = execute_syscall(regs);
3526 REGS_SET_SYSCALL_RETURN(regs->skas.regs, result);
3528 (result == -ERESTARTNOINTR))
3532 + syscall_trace(regs, 0);
3533 record_syscall_end(index, result);
3536 Index: uml-2.6.7/arch/um/kernel/process.c
3537 ===================================================================
3538 --- uml-2.6.7.orig/arch/um/kernel/process.c 2004-07-16 19:37:22.968533328 +0300
3539 +++ uml-2.6.7/arch/um/kernel/process.c 2004-07-16 19:47:24.795041792 +0300
3547 #include <sys/time.h>
3548 #include <sys/ptrace.h>
3549 -#include <sys/ioctl.h>
3550 #include <sys/wait.h>
3551 #include <sys/mman.h>
3552 #include <asm/ptrace.h>
3553 #include <asm/sigcontext.h>
3554 #include <asm/unistd.h>
3555 #include <asm/page.h>
3556 +#include <asm/user.h>
3557 #include "user_util.h"
3558 #include "kern_util.h"
3562 int flags = altstack ? SA_ONSTACK : 0;
3564 - set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags,
3565 + /* NODEFER is set here because SEGV isn't turned back on when the
3566 + * handler is ready to receive signals. This causes any segfault
3567 + * during a copy_user to kill the process because the fault is blocked.
3569 + set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags | SA_NODEFER,
3570 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
3571 set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags,
3572 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
3574 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
3575 set_handler(SIGUSR2, (__sighandler_t) sig_handler,
3576 SA_NOMASK | flags, -1);
3577 - (void) CHOOSE_MODE(signal(SIGCHLD, SIG_IGN), (void *) 0);
3578 signal(SIGHUP, SIG_IGN);
3580 init_irq_signals(altstack);
3581 @@ -123,11 +125,12 @@
3582 /* Start the process and wait for it to kill itself */
3583 new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg);
3584 if(new_pid < 0) return(-errno);
3585 - while((err = waitpid(new_pid, &status, 0) < 0) && (errno == EINTR)) ;
3586 + CATCH_EINTR(err = waitpid(new_pid, &status, 0));
3587 if(err < 0) panic("Waiting for outer trampoline failed - errno = %d",
3589 if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
3590 - panic("outer trampoline didn't exit with SIGKILL");
3591 + panic("outer trampoline didn't exit with SIGKILL, "
3592 + "status = %d", status);
3598 os_stop_process(os_getpid());
3600 - if(read(fd, &c, sizeof(c)) != sizeof(c))
3601 + if(os_read_file(fd, &c, sizeof(c)) != sizeof(c))
3602 panic("read failed in suspend_new_thread");
3606 pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
3608 panic("check_ptrace : clone failed, errno = %d", errno);
3609 - n = waitpid(pid, &status, WUNTRACED);
3610 + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
3612 panic("check_ptrace : wait failed, errno = %d", errno);
3613 if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
3616 if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
3617 panic("check_ptrace : ptrace failed, errno = %d", errno);
3618 - n = waitpid(pid, &status, 0);
3619 + CATCH_EINTR(n = waitpid(pid, &status, 0));
3620 if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode))
3621 panic("check_ptrace : child exited with status 0x%x", status);
3623 @@ -193,6 +196,22 @@
3624 panic("check_ptrace : munmap failed, errno = %d", errno);
3627 +static int force_sysemu_disabled = 0;
3629 +static int __init nosysemu_cmd_param(char *str, int* add)
3631 + force_sysemu_disabled = 1;
3635 +__uml_setup("nosysemu", nosysemu_cmd_param,
3637 + " Turns off syscall emulation patch for ptrace (SYSEMU) on.\n"
3638 + " SYSEMU is a performance-patch introduced by Laurent Vivier. It changes\n"
3639 + " behaviour of ptrace() and helps reducing host context switch rate.\n"
3640 + " To make it working, you need a kernel patch for your host, too.\n"
3641 + " See http://perso.wanadoo.fr/laurent.vivier/UML/ for further information.\n");
3643 void __init check_ptrace(void)
3647 if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
3648 panic("check_ptrace : ptrace failed, errno = %d",
3650 - n = waitpid(pid, &status, WUNTRACED);
3651 + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
3653 panic("check_ptrace : wait failed, errno = %d", errno);
3654 if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
3655 @@ -225,6 +244,45 @@
3657 stop_ptraced_child(pid, stack, 0);
3660 +#ifdef UML_CONFIG_MODE_SKAS
3661 + printk("Checking syscall emulation patch for ptrace...");
3662 + set_using_sysemu(0);
3663 + pid = start_ptraced_child(&stack);
3664 + if(ptrace(PTRACE_SYSEMU, pid, 0, 0) >= 0) {
3665 + struct user_regs_struct regs;
3667 + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
3669 + panic("check_ptrace : wait failed, errno = %d", errno);
3670 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
3671 + panic("check_ptrace : expected SIGTRAP, "
3672 + "got status = %d", status);
3674 + if (ptrace(PTRACE_GETREGS, pid, 0, ®s) < 0)
3675 + panic("check_ptrace : failed to read child "
3676 + "registers, errno = %d", errno);
3677 + regs.orig_eax = pid;
3678 + if (ptrace(PTRACE_SETREGS, pid, 0, ®s) < 0)
3679 + panic("check_ptrace : failed to modify child "
3680 + "registers, errno = %d", errno);
3682 + stop_ptraced_child(pid, stack, 0);
3684 + if (!force_sysemu_disabled) {
3685 + printk("found\n");
3686 + set_using_sysemu(1);
3688 + printk("found but disabled\n");
3693 + printk("missing\n");
3694 + stop_ptraced_child(pid, stack, 1);
3700 int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
3706 + n = sigsetjmp(buf, 1);
3711 stop_ptraced_child(pid, stack, 1);
3713 printf("Checking for /proc/mm...");
3714 - if(access("/proc/mm", W_OK)){
3715 + if(os_access("/proc/mm", OS_ACC_W_OK) < 0){
3716 printf("not found\n");
3719 Index: uml-2.6.7/arch/um/drivers/stdio_console.c
3720 ===================================================================
3721 --- uml-2.6.7.orig/arch/um/drivers/stdio_console.c 2004-07-16 19:36:13.845041696 +0300
3722 +++ uml-2.6.7/arch/um/drivers/stdio_console.c 2004-07-16 19:47:23.694209144 +0300
3725 static struct line_driver driver = {
3726 .name = "UML console",
3727 - .devfs_name = "vc/%d",
3728 + .device_name = "tty",
3729 + .devfs_name = "vc/",
3732 .type = TTY_DRIVER_TYPE_CONSOLE,
3733 @@ -159,6 +160,15 @@
3735 static int con_init_done = 0;
3737 +static struct tty_operations console_ops = {
3739 + .close = con_close,
3740 + .write = con_write,
3741 + .chars_in_buffer = chars_in_buffer,
3742 + .set_termios = set_termios,
3743 + .write_room = line_write_room,
3746 int stdio_init(void)
3750 printk(KERN_INFO "Initializing stdio console driver\n");
3752 console_driver = line_register_devfs(&console_lines, &driver,
3753 - &console_ops, vts, sizeof(vts)/sizeof(vts[0]));
3754 + &console_ops, vts,
3755 + sizeof(vts)/sizeof(vts[0]));
3757 lines_init(vts, sizeof(vts)/sizeof(vts[0]));
3759 @@ -178,24 +189,19 @@
3763 -__initcall(stdio_init);
3764 +late_initcall(stdio_init);
3766 static void console_write(struct console *console, const char *string,
3769 - if(con_init_done) down(&vts[console->index].sem);
3770 - console_write_chan(&vts[console->index].chan_list, string, len);
3771 - if(con_init_done) up(&vts[console->index].sem);
3773 + struct line *line = &vts[console->index];
3775 -static struct tty_operations console_ops = {
3777 - .close = con_close,
3778 - .write = con_write,
3779 - .chars_in_buffer = chars_in_buffer,
3780 - .set_termios = set_termios,
3781 - .write_room = line_write_room,
3785 + console_write_chan(&line->chan_list, string, len);
3790 static struct tty_driver *console_device(struct console *c, int *index)
3792 @@ -208,22 +214,28 @@
3796 -static struct console stdiocons = INIT_CONSOLE("tty", console_write,
3797 - console_device, console_setup,
3799 +static struct console stdiocons = {
3801 + write: console_write,
3802 + device: console_device,
3803 + setup: console_setup,
3804 + flags: CON_PRINTBUFFER,
3808 -static void __init stdio_console_init(void)
3809 +static int __init stdio_console_init(void)
3811 INIT_LIST_HEAD(&vts[0].chan_list);
3812 list_add(&init_console_chan.list, &vts[0].chan_list);
3813 register_console(&stdiocons);
3817 console_initcall(stdio_console_init);
3819 static int console_chan_setup(char *str)
3821 - line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1);
3823 + return(line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1));
3826 __setup("con", console_chan_setup);
3827 Index: uml-2.6.7/arch/um/os-Linux/Makefile
3828 ===================================================================
3829 --- uml-2.6.7.orig/arch/um/os-Linux/Makefile 2004-07-16 19:36:54.369880984 +0300
3830 +++ uml-2.6.7/arch/um/os-Linux/Makefile 2004-07-16 19:47:23.768197896 +0300
3832 # Licensed under the GPL
3835 -obj-y = file.o process.o tty.o drivers/
3836 +obj-y = file.o process.o tty.o user_syms.o drivers/
3838 USER_OBJS := $(foreach file,file.o process.o tty.o,$(obj)/$(file))
3840 $(USER_OBJS) : %.o: %.c
3841 $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
3846 Index: uml-2.6.7/arch/um/kernel/skas/syscall_kern.c
3847 ===================================================================
3848 --- uml-2.6.7.orig/arch/um/kernel/skas/syscall_kern.c 2004-07-16 19:36:57.006480160 +0300
3849 +++ uml-2.6.7/arch/um/kernel/skas/syscall_kern.c 2004-07-16 19:47:23.732203368 +0300
3852 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3853 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
3854 * Licensed under the GPL
3857 Index: uml-2.6.7/arch/um/drivers/pty.c
3858 ===================================================================
3859 --- uml-2.6.7.orig/arch/um/drivers/pty.c 2004-07-16 19:37:26.082060000 +0300
3860 +++ uml-2.6.7/arch/um/drivers/pty.c 2004-07-16 19:47:23.692209448 +0300
3866 #include <termios.h>
3867 #include "chan_user.h"
3869 #include "user_util.h"
3870 #include "kern_util.h"
3874 void (*announce)(char *dev_name, int dev);
3877 struct pty_chan *data;
3879 - if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL);
3880 + data = um_kmalloc(sizeof(*data));
3881 + if(data == NULL) return(NULL);
3882 *data = ((struct pty_chan) { .announce = opts->announce,
3884 .raw = opts->raw });
3889 - if((fd = get_pty()) < 0){
3892 printk("open_pts : Failed to open pts\n");
3897 int getmaster(char *line)
3900 char *pty, *bank, *cp;
3904 pty = &line[strlen("/dev/ptyp")];
3905 for (bank = "pqrs"; *bank; bank++) {
3906 line[strlen("/dev/pty")] = *bank;
3908 - if (stat(line, &stb) < 0)
3909 + if (os_stat_file(line, NULL) < 0)
3911 for (cp = "0123456789abcdef"; *cp; cp++) {
3913 - master = open(line, O_RDWR);
3914 + master = os_open_file(line, of_rdwr(OPENFLAGS()), 0);
3916 char *tp = &line[strlen("/dev/")];
3919 /* verify slave side is usable */
3921 - ok = access(line, R_OK|W_OK) == 0;
3922 + err = os_access(line, OS_ACC_RW_OK);
3924 - if (ok) return(master);
3925 - (void) close(master);
3926 + if(err == 0) return(master);
3927 + (void) os_close_file(master);
3931 Index: uml-2.6.7/arch/um/util/mk_constants_kern.c
3932 ===================================================================
3933 --- uml-2.6.7.orig/arch/um/util/mk_constants_kern.c 2004-07-16 19:35:59.020295400 +0300
3934 +++ uml-2.6.7/arch/um/util/mk_constants_kern.c 2004-07-16 19:47:23.781195920 +0300
3936 #include "linux/kernel.h"
3937 #include "linux/stringify.h"
3938 +#include "linux/time.h"
3939 #include "asm/page.h"
3941 extern void print_head(void);
3945 print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
3947 print_constant_str("UM_KERN_EMERG", KERN_EMERG);
3948 print_constant_str("UM_KERN_ALERT", KERN_ALERT);
3949 print_constant_str("UM_KERN_CRIT", KERN_CRIT);
3951 print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
3952 print_constant_str("UM_KERN_INFO", KERN_INFO);
3953 print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
3955 + print_constant_int("UM_NSEC_PER_SEC", NSEC_PER_SEC);
3959 Index: uml-2.6.7/arch/um/drivers/port_user.c
3960 ===================================================================
3961 --- uml-2.6.7.orig/arch/um/drivers/port_user.c 2004-07-16 19:36:57.124462224 +0300
3962 +++ uml-2.6.7/arch/um/drivers/port_user.c 2004-07-16 19:47:23.691209600 +0300
3967 - if((kern_data = port_data(port)) == NULL)
3968 + kern_data = port_data(port);
3969 + if(kern_data == NULL)
3972 - if((data = um_kmalloc(sizeof(*data))) == NULL)
3973 + data = um_kmalloc(sizeof(*data));
3977 *data = ((struct port_chan) { .raw = opts->raw,
3979 struct port_chan *data = d;
3981 port_remove_dev(data->kernel_data);
3983 + os_close_file(fd);
3986 int port_console_write(int fd, const char *buf, int n, void *d)
3987 @@ -130,11 +132,15 @@
3991 - if((listen(fd, 1) < 0) || (os_set_fd_block(fd, 0))){
3992 + if(listen(fd, 1) < 0){
3997 + err = os_set_fd_block(fd, 0);
4004 @@ -153,10 +159,10 @@
4005 dup2(data->sock_fd, 0);
4006 dup2(data->sock_fd, 1);
4007 dup2(data->sock_fd, 2);
4008 - close(data->sock_fd);
4009 + os_close_file(data->sock_fd);
4010 dup2(data->pipe_fd, 3);
4011 os_shutdown_socket(3, 1, 0);
4012 - close(data->pipe_fd);
4013 + os_close_file(data->pipe_fd);
4016 int port_connection(int fd, int *socket, int *pid_out)
4017 @@ -166,11 +172,12 @@
4018 "/usr/lib/uml/port-helper", NULL };
4019 struct port_pre_exec_data data;
4021 - if((new = os_accept_connection(fd)) < 0)
4023 + new = os_accept_connection(fd);
4027 err = os_pipe(socket, 0, 0);
4032 data = ((struct port_pre_exec_data)
4033 @@ -186,11 +193,11 @@
4036 os_shutdown_socket(socket[0], 1, 1);
4038 + os_close_file(socket[0]);
4039 os_shutdown_socket(socket[1], 1, 1);
4041 + os_close_file(socket[1]);
4044 + os_close_file(new);
4048 Index: uml-2.6.7/arch/um/drivers/port_kern.c
4049 ===================================================================
4050 --- uml-2.6.7.orig/arch/um/drivers/port_kern.c 2004-07-16 19:35:56.025750640 +0300
4051 +++ uml-2.6.7/arch/um/drivers/port_kern.c 2004-07-16 19:47:23.690209752 +0300
4053 #include "linux/list.h"
4054 #include "linux/sched.h"
4055 #include "linux/slab.h"
4056 +#include "linux/interrupt.h"
4057 #include "linux/irq.h"
4058 #include "linux/spinlock.h"
4059 #include "linux/errno.h"
4061 #include "kern_util.h"
4063 #include "irq_user.h"
4064 +#include "irq_kern.h"
4070 struct list_head list;
4076 struct port_list *port;
4079 -static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
4080 +static irqreturn_t pipe_interrupt(int irq, void *data, struct pt_regs *regs)
4082 struct connection *conn = data;
4085 - fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
4086 + fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
4092 printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n",
4095 list_add(&conn->list, &conn->port->connections);
4097 up(&conn->port->sem);
4098 + return(IRQ_HANDLED);
4101 static int port_accept(struct port_list *port)
4105 list_add(&conn->list, &port->pending);
4112 @@ -138,12 +140,13 @@
4114 DECLARE_WORK(port_work, port_work_proc, NULL);
4116 -static void port_interrupt(int irq, void *data, struct pt_regs *regs)
4117 +static irqreturn_t port_interrupt(int irq, void *data, struct pt_regs *regs)
4119 struct port_list *port = data;
4121 port->has_connection = 1;
4122 schedule_work(&port_work);
4123 + return(IRQ_HANDLED);
4126 void *port_data(int port_num)
4127 Index: uml-2.6.7/arch/um/sys-i386/ptrace_user.c
4128 ===================================================================
4129 --- uml-2.6.7.orig/arch/um/sys-i386/ptrace_user.c 2004-07-16 19:37:52.078108000 +0300
4130 +++ uml-2.6.7/arch/um/sys-i386/ptrace_user.c 2004-07-16 19:47:23.772197288 +0300
4132 nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
4133 for(i = 0; i < nregs; i++){
4134 if((i == 4) || (i == 5)) continue;
4135 - if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i],
4136 + if(ptrace(PTRACE_POKEUSER, pid, &dummy->u_debugreg[i],
4138 - printk("write_debugregs - ptrace failed, "
4139 - "errno = %d\n", errno);
4140 + printk("write_debugregs - ptrace failed on "
4141 + "register %d, errno = %d\n", errno);
4147 nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
4148 for(i = 0; i < nregs; i++){
4149 - regs[i] = ptrace(PTRACE_PEEKUSR, pid,
4150 + regs[i] = ptrace(PTRACE_PEEKUSER, pid,
4151 &dummy->u_debugreg[i], 0);
4154 Index: uml-2.6.7/arch/um/os-Linux/drivers/tuntap_user.c
4155 ===================================================================
4156 --- uml-2.6.7.orig/arch/um/os-Linux/drivers/tuntap_user.c 2004-07-16 19:37:46.493956920 +0300
4157 +++ uml-2.6.7/arch/um/os-Linux/drivers/tuntap_user.c 2004-07-16 19:47:24.802040728 +0300
4163 #include <sys/wait.h>
4164 #include <sys/socket.h>
4167 #include "net_user.h"
4169 #include "kern_util.h"
4170 +#include "user_util.h"
4175 struct tuntap_pre_exec_data *data = arg;
4177 dup2(data->stdout, 1);
4178 - close(data->close_me);
4179 + os_close_file(data->close_me);
4182 static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
4185 if(pid < 0) return(-pid);
4188 + os_close_file(remote);
4190 msg.msg_name = NULL;
4191 msg.msg_namelen = 0;
4192 @@ -107,19 +107,19 @@
4194 printk("tuntap_open_tramp : recvmsg failed - errno = %d\n",
4199 - waitpid(pid, NULL, 0);
4200 + CATCH_EINTR(waitpid(pid, NULL, 0));
4202 cmsg = CMSG_FIRSTHDR(&msg);
4204 printk("tuntap_open_tramp : didn't receive a message\n");
4208 if((cmsg->cmsg_level != SOL_SOCKET) ||
4209 (cmsg->cmsg_type != SCM_RIGHTS)){
4210 printk("tuntap_open_tramp : didn't receive a descriptor\n");
4214 *fd_out = ((int *) CMSG_DATA(cmsg))[0];
4216 @@ -133,27 +133,29 @@
4217 int err, fds[2], len, used;
4219 err = tap_open_common(pri->dev, pri->gate_addr);
4220 - if(err) return(err);
4224 if(pri->fixed_config){
4225 - if((pri->fd = open("/dev/net/tun", O_RDWR)) < 0){
4226 - printk("Failed to open /dev/net/tun, errno = %d\n",
4229 + pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0);
4231 + printk("Failed to open /dev/net/tun, err = %d\n",
4235 memset(&ifr, 0, sizeof(ifr));
4236 - ifr.ifr_flags = IFF_TAP;
4237 + ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
4238 strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
4239 if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
4240 - printk("TUNSETIFF failed, errno = %d", errno);
4242 + printk("TUNSETIFF failed, errno = %d\n", errno);
4243 + os_close_file(pri->fd);
4248 err = os_pipe(fds, 0, 0);
4250 - printk("tuntap_open : os_pipe failed - errno = %d\n",
4252 + printk("tuntap_open : os_pipe failed - err = %d\n",
4256 @@ -166,19 +168,19 @@
4257 fds[1], buffer, len, &used);
4261 - pri->dev_name = uml_strdup(buffer);
4262 - output += IFNAMSIZ;
4264 - free_output_buffer(buffer);
4269 + printk("%s", output);
4270 free_output_buffer(buffer);
4271 - printk("tuntap_open_tramp failed - errno = %d\n", err);
4273 + printk("tuntap_open_tramp failed - err = %d\n", -err);
4278 + pri->dev_name = uml_strdup(buffer);
4279 + output += IFNAMSIZ;
4280 + printk("%s", output);
4281 + free_output_buffer(buffer);
4283 + os_close_file(fds[0]);
4284 iter_addresses(pri->dev, open_addr, pri->dev_name);
4289 if(!pri->fixed_config)
4290 iter_addresses(pri->dev, close_addr, pri->dev_name);
4292 + os_close_file(fd);
4296 Index: uml-2.6.7/arch/um/kernel/um_arch.c
4297 ===================================================================
4298 --- uml-2.6.7.orig/arch/um/kernel/um_arch.c 2004-07-16 19:37:17.463370240 +0300
4299 +++ uml-2.6.7/arch/um/kernel/um_arch.c 2004-07-16 19:47:23.755199872 +0300
4301 #include "mode_kern.h"
4304 -#define DEFAULT_COMMAND_LINE "root=6200"
4305 +#define DEFAULT_COMMAND_LINE "root=98:0"
4307 struct cpuinfo_um boot_cpu_data = {
4308 .loops_per_jiffy = 0,
4309 .ipi_pipe = { -1, -1 }
4312 +/* Placeholder to make UML link until the vsyscall stuff is actually
4315 +void *__kernel_vsyscall;
4317 unsigned long thread_saved_pc(struct task_struct *task)
4319 return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
4322 static int show_cpuinfo(struct seq_file *m, void *v)
4327 - index = (struct cpuinfo_um *)v - cpu_data;
4329 + index = (struct cpuinfo_um *) v - cpu_data;
4330 if (!cpu_online(index))
4334 - seq_printf(m, "bogomips\t: %lu.%02lu\n",
4335 + seq_printf(m, "processor\t: %d\n", index);
4336 + seq_printf(m, "vendor_id\t: User Mode Linux\n");
4337 + seq_printf(m, "model name\t: UML\n");
4338 + seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas"));
4339 + seq_printf(m, "host\t\t: %s\n", host_info);
4340 + seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
4341 loops_per_jiffy/(500000/HZ),
4342 (loops_per_jiffy/(5000/HZ)) % 100);
4343 - seq_printf(m, "host\t\t: %s\n", host_info);
4347 @@ -134,12 +143,12 @@
4349 snprintf(argv1_begin,
4350 (argv1_end - argv1_begin) * sizeof(*ptr),
4353 ptr = &argv1_begin[strlen(argv1_begin)];
4355 else ptr = argv1_begin;
4357 - snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), " [%s]", cmd);
4358 + snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
4359 memset(argv1_begin + strlen(argv1_begin), '\0',
4360 argv1_end - argv1_begin - strlen(argv1_begin));
4363 static int __init uml_ncpus_setup(char *line, int *add)
4365 if (!sscanf(line, "%d", &ncpus)) {
4366 - printk("Couldn't parse [%s]\n", line);
4367 + printf("Couldn't parse [%s]\n", line);
4373 static int __init mode_tt_setup(char *line, int *add)
4375 - printk("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
4376 + printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
4382 static int __init mode_tt_setup(char *line, int *add)
4384 - printk("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
4385 + printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
4391 /* Set during early boot */
4392 unsigned long brk_start;
4393 -static struct vm_reserved kernel_vm_reserved;
4394 +unsigned long end_iomem;
4396 #define MIN_VMALLOC (32 * 1024 * 1024)
4400 unsigned long avail;
4401 unsigned long virtmem_size, max_physmem;
4402 - unsigned int i, add, err;
4403 + unsigned int i, add;
4405 for (i = 1; i < argc; i++){
4406 if((i == 1) && (argv[i][0] == ' ')) continue;
4407 @@ -328,12 +337,16 @@
4408 argv1_end = &argv[1][strlen(argv[1])];
4411 - set_usable_vm(uml_physmem, get_kmem_end());
4414 - max_physmem = get_kmem_end() - uml_physmem - MIN_VMALLOC;
4415 - if(physmem_size > max_physmem){
4416 - highmem = physmem_size - max_physmem;
4417 + iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
4418 + max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC;
4420 + /* Zones have to begin on a 1 << MAX_ORDER page boundary,
4421 + * so this makes sure that's true for highmem
4423 + max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1);
4424 + if(physmem_size + iomem_size > max_physmem){
4425 + highmem = physmem_size + iomem_size - max_physmem;
4426 physmem_size -= highmem;
4427 #ifndef CONFIG_HIGHMEM
4429 @@ -343,11 +356,19 @@
4432 high_physmem = uml_physmem + physmem_size;
4433 - high_memory = (void *) high_physmem;
4434 + end_iomem = high_physmem + iomem_size;
4435 + high_memory = (void *) end_iomem;
4437 start_vm = VMALLOC_START;
4439 - setup_physmem(uml_physmem, uml_reserved, physmem_size);
4440 + setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
4441 + if(init_maps(physmem_size, iomem_size, highmem)){
4442 + printf("Failed to allocate mem_map for %ld bytes of physical "
4443 + "memory and %ld bytes of highmem\n", physmem_size,
4448 virtmem_size = physmem_size;
4449 avail = get_kmem_end() - start_vm;
4450 if(physmem_size > avail) virtmem_size = avail;
4451 @@ -357,28 +378,26 @@
4452 printf("Kernel virtual memory size shrunk to %ld bytes\n",
4455 - err = reserve_vm(high_physmem, end_vm, &kernel_vm_reserved);
4457 - printf("Failed to reserve VM area for kernel VM\n");
4463 init_task.thread.kernel_stack = (unsigned long) &init_thread_info +
4466 task_protections((unsigned long) &init_thread_info);
4467 + os_flush_stdout();
4469 return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
4472 +extern int uml_exitcode;
4474 static int panic_exit(struct notifier_block *self, unsigned long unused1,
4477 #ifdef CONFIG_MAGIC_SYSRQ
4478 - handle_sysrq('p', ¤t->thread.regs, NULL, NULL);
4479 + handle_sysrq('p', ¤t->thread.regs, NULL);
4485 @@ -403,6 +422,11 @@
4492 +void apply_alternatives(void *start, void *end)
4497 Index: uml-2.6.7/arch/um/kernel/mem.c
4498 ===================================================================
4499 --- uml-2.6.7.orig/arch/um/kernel/mem.c 2004-07-16 19:36:30.355531720 +0300
4500 +++ uml-2.6.7/arch/um/kernel/mem.c 2004-07-16 19:47:23.720205192 +0300
4503 - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
4504 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
4505 * Licensed under the GPL
4508 -#include "linux/config.h"
4509 -#include "linux/module.h"
4510 -#include "linux/types.h"
4511 +#include "linux/stddef.h"
4512 +#include "linux/kernel.h"
4513 #include "linux/mm.h"
4514 -#include "linux/fs.h"
4515 -#include "linux/init.h"
4516 #include "linux/bootmem.h"
4517 #include "linux/swap.h"
4518 -#include "linux/slab.h"
4519 -#include "linux/vmalloc.h"
4520 #include "linux/highmem.h"
4521 +#include "linux/gfp.h"
4522 #include "asm/page.h"
4523 -#include "asm/pgtable.h"
4524 +#include "asm/fixmap.h"
4525 #include "asm/pgalloc.h"
4526 -#include "asm/bitops.h"
4527 -#include "asm/uaccess.h"
4528 -#include "asm/tlb.h"
4529 #include "user_util.h"
4530 #include "kern_util.h"
4531 -#include "mem_user.h"
4536 -#include "mode_kern.h"
4537 +#include "mem_user.h"
4538 #include "uml_uaccess.h"
4541 +extern char __binary_start;
4543 /* Changed during early boot */
4544 -pgd_t swapper_pg_dir[1024];
4545 -unsigned long high_physmem;
4546 -unsigned long vm_start;
4547 -unsigned long vm_end;
4548 -unsigned long highmem;
4549 unsigned long *empty_zero_page = NULL;
4550 unsigned long *empty_bad_page = NULL;
4553 -const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n";
4555 -extern char __init_begin, __init_end;
4556 -extern long physmem_size;
4558 -/* Not changed by UML */
4559 -DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
4561 -/* Changed during early boot */
4562 +pgd_t swapper_pg_dir[1024];
4563 +unsigned long highmem;
4566 -#define NREGIONS (phys_region_index(0xffffffff) - phys_region_index(0x0) + 1)
4567 -struct mem_region *regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] = NULL };
4568 -#define REGION_SIZE ((0xffffffff & ~REGION_MASK) + 1)
4570 -/* Changed during early boot */
4571 static unsigned long brk_end;
4573 +void unmap_physmem(void)
4575 + os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
4578 static void map_cb(void *unused)
4580 map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0);
4583 -void unmap_physmem(void)
4584 +#ifdef CONFIG_HIGHMEM
4585 +static void setup_highmem(unsigned long highmem_start,
4586 + unsigned long highmem_len)
4588 - os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
4590 + struct page *page;
4591 + unsigned long highmem_pfn;
4594 -extern char __binary_start;
4595 + highmem_start_page = virt_to_page(highmem_start);
4597 + highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT;
4598 + for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){
4599 + page = &mem_map[highmem_pfn + i];
4600 + ClearPageReserved(page);
4601 + set_bit(PG_highmem, &page->flags);
4602 + set_page_count(page, 1);
4603 + __free_page(page);
4610 @@ -103,50 +95,15 @@
4611 totalhigh_pages = highmem >> PAGE_SHIFT;
4612 totalram_pages += totalhigh_pages;
4613 num_physpages = totalram_pages;
4614 - max_mapnr = totalram_pages;
4615 max_pfn = totalram_pages;
4616 printk(KERN_INFO "Memory: %luk available\n",
4617 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10));
4621 -/* Changed during early boot */
4622 -static unsigned long kmem_top = 0;
4624 -unsigned long get_kmem_end(void)
4627 - kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
4631 -void set_kmem_end(unsigned long new)
4636 #ifdef CONFIG_HIGHMEM
4637 -/* Changed during early boot */
4639 -pgprot_t kmap_prot;
4641 -EXPORT_SYMBOL(kmap_prot);
4642 -EXPORT_SYMBOL(kmap_pte);
4644 -#define kmap_get_fixmap_pte(vaddr) \
4645 - pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
4647 -void __init kmap_init(void)
4649 - unsigned long kmap_vstart;
4651 - /* cache the first kmap pte */
4652 - kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
4653 - kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
4655 - kmap_prot = PAGE_KERNEL;
4656 + setup_highmem(end_iomem, highmem);
4659 -#endif /* CONFIG_HIGHMEM */
4661 static void __init fixrange_init(unsigned long start, unsigned long end,
4663 @@ -178,76 +135,24 @@
4667 -int init_maps(struct mem_region *region)
4669 - struct page *p, *map;
4672 - if(region == &physmem_region){
4673 - region->mem_map = mem_map;
4676 - else if(region->mem_map != NULL) return(0);
4678 - n = region->len >> PAGE_SHIFT;
4679 - len = n * sizeof(struct page);
4681 - map = kmalloc(len, GFP_KERNEL);
4682 - if(map == NULL) map = vmalloc(len);
4684 - else map = alloc_bootmem_low_pages(len);
4688 - for(i = 0; i < n; i++){
4690 - set_page_count(p, 0);
4691 - SetPageReserved(p);
4692 - INIT_LIST_HEAD(&p->list);
4694 - region->mem_map = map;
4699 +pgprot_t kmap_prot;
4701 -DECLARE_MUTEX(regions_sem);
4702 +#define kmap_get_fixmap_pte(vaddr) \
4703 + pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
4705 -static int setup_one_range(int fd, char *driver, unsigned long start,
4706 - unsigned long pfn, int len,
4707 - struct mem_region *region)
4708 +void __init kmap_init(void)
4712 - down(®ions_sem);
4713 - for(i = 0; i < NREGIONS; i++){
4714 - if(regions[i] == NULL) break;
4716 - if(i == NREGIONS){
4717 - printk("setup_range : no free regions\n");
4723 - fd = create_mem_file(len);
4724 + unsigned long kmap_vstart;
4726 - if(region == NULL){
4727 - region = alloc_bootmem_low_pages(sizeof(*region));
4728 - if(region == NULL)
4729 - panic("Failed to allocating mem_region");
4731 + /* cache the first kmap pte */
4732 + kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
4733 + kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
4735 - *region = ((struct mem_region) { .driver = driver,
4740 - regions[i] = region;
4744 + kmap_prot = PAGE_KERNEL;
4747 -#ifdef CONFIG_HIGHMEM
4748 static void init_highmem(void)
4751 @@ -268,63 +173,20 @@
4756 -void setup_highmem(unsigned long len)
4758 - struct mem_region *region;
4759 - struct page *page, *map;
4760 - unsigned long phys;
4761 - int i, cur, index;
4763 - phys = physmem_size;
4765 - cur = min(len, (unsigned long) REGION_SIZE);
4766 - i = setup_one_range(-1, NULL, -1, phys >> PAGE_SHIFT, cur,
4769 - printk("setup_highmem - setup_one_range failed\n");
4772 - region = regions[i];
4773 - index = phys / PAGE_SIZE;
4774 - region->mem_map = &mem_map[index];
4776 - map = region->mem_map;
4777 - for(i = 0; i < (cur >> PAGE_SHIFT); i++){
4779 - ClearPageReserved(page);
4780 - set_bit(PG_highmem, &page->flags);
4781 - set_page_count(page, 1);
4782 - __free_page(page);
4789 +#endif /* CONFIG_HIGHMEM */
4791 void paging_init(void)
4793 - struct mem_region *region;
4794 - unsigned long zones_size[MAX_NR_ZONES], start, end, vaddr;
4796 + unsigned long zones_size[MAX_NR_ZONES], vaddr;
4799 empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
4800 empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
4801 for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++)
4803 - zones_size[0] = (high_physmem >> PAGE_SHIFT) -
4804 - (uml_physmem >> PAGE_SHIFT);
4805 + zones_size[0] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT);
4806 zones_size[2] = highmem >> PAGE_SHIFT;
4807 free_area_init(zones_size);
4808 - start = phys_region_index(__pa(uml_physmem));
4809 - end = phys_region_index(__pa(high_physmem - 1));
4810 - for(i = start; i <= end; i++){
4811 - region = regions[i];
4812 - index = (region->start - uml_physmem) / PAGE_SIZE;
4813 - region->mem_map = &mem_map[index];
4814 - if(i > start) free_bootmem(__pa(region->start), region->len);
4818 * Fixed mappings, only the page table structure has to be
4819 @@ -335,15 +197,33 @@
4821 #ifdef CONFIG_HIGHMEM
4823 - setup_highmem(highmem);
4827 -pte_t __bad_page(void)
4828 +struct page *arch_validate(struct page *page, int mask, int order)
4830 - clear_page(empty_bad_page);
4831 - return pte_mkdirty(mk_pte((struct page *) empty_bad_page,
4833 + unsigned long addr, zero = 0;
4837 + if(page == NULL) return(page);
4838 + if(PageHighMem(page)) return(page);
4840 + addr = (unsigned long) page_address(page);
4841 + for(i = 0; i < (1 << order); i++){
4842 + current->thread.fault_addr = (void *) addr;
4843 + if(__do_copy_to_user((void *) addr, &zero,
4845 + ¤t->thread.fault_addr,
4846 + ¤t->thread.fault_catcher)){
4847 + if(!(mask & __GFP_WAIT)) return(NULL);
4850 + addr += PAGE_SIZE;
4852 + if(i == (1 << order)) return(page);
4853 + page = alloc_pages(mask, order);
4857 /* This can't do anything because nothing in the kernel image can be freed
4858 @@ -401,395 +281,6 @@
4859 printk("%d pages swap cached\n", cached);
4862 -static int __init uml_mem_setup(char *line, int *add)
4865 - physmem_size = memparse(line,&retptr);
4868 -__uml_setup("mem=", uml_mem_setup,
4869 -"mem=<Amount of desired ram>\n"
4870 -" This controls how much \"physical\" memory the kernel allocates\n"
4871 -" for the system. The size is specified as a number followed by\n"
4872 -" one of 'k', 'K', 'm', 'M', which have the obvious meanings.\n"
4873 -" This is not related to the amount of memory in the physical\n"
4874 -" machine. It can be more, and the excess, if it's ever used, will\n"
4875 -" just be swapped out.\n Example: mem=64M\n\n"
4878 -struct page *arch_validate(struct page *page, int mask, int order)
4880 - unsigned long addr, zero = 0;
4884 - if(page == NULL) return(page);
4885 - if(PageHighMem(page)) return(page);
4887 - addr = (unsigned long) page_address(page);
4888 - for(i = 0; i < (1 << order); i++){
4889 - current->thread.fault_addr = (void *) addr;
4890 - if(__do_copy_to_user((void *) addr, &zero,
4892 - ¤t->thread.fault_addr,
4893 - ¤t->thread.fault_catcher)){
4894 - if(!(mask & __GFP_WAIT)) return(NULL);
4897 - addr += PAGE_SIZE;
4899 - if(i == (1 << order)) return(page);
4900 - page = alloc_pages(mask, order);
4904 -DECLARE_MUTEX(vm_reserved_sem);
4905 -static struct list_head vm_reserved = LIST_HEAD_INIT(vm_reserved);
4907 -/* Static structures, linked in to the list in early boot */
4908 -static struct vm_reserved head = {
4909 - .list = LIST_HEAD_INIT(head.list),
4914 -static struct vm_reserved tail = {
4915 - .list = LIST_HEAD_INIT(tail.list),
4920 -void set_usable_vm(unsigned long start, unsigned long end)
4922 - list_add(&head.list, &vm_reserved);
4923 - list_add(&tail.list, &head.list);
4928 -int reserve_vm(unsigned long start, unsigned long end, void *e)
4931 - struct vm_reserved *entry = e, *reserved, *prev;
4932 - struct list_head *ele;
4935 - down(&vm_reserved_sem);
4936 - list_for_each(ele, &vm_reserved){
4937 - reserved = list_entry(ele, struct vm_reserved, list);
4938 - if(reserved->start >= end) goto found;
4940 - panic("Reserved vm out of range");
4942 - prev = list_entry(ele->prev, struct vm_reserved, list);
4943 - if(prev->end > start)
4944 - panic("Can't reserve vm");
4946 - entry = kmalloc(sizeof(*entry), GFP_KERNEL);
4947 - if(entry == NULL){
4948 - printk("reserve_vm : Failed to allocate entry\n");
4952 - *entry = ((struct vm_reserved)
4953 - { .list = LIST_HEAD_INIT(entry->list),
4956 - list_add(&entry->list, &prev->list);
4959 - up(&vm_reserved_sem);
4963 -unsigned long get_vm(unsigned long len)
4965 - struct vm_reserved *this, *next;
4966 - struct list_head *ele;
4967 - unsigned long start;
4970 - down(&vm_reserved_sem);
4971 - list_for_each(ele, &vm_reserved){
4972 - this = list_entry(ele, struct vm_reserved, list);
4973 - next = list_entry(ele->next, struct vm_reserved, list);
4974 - if((this->start < next->start) &&
4975 - (this->end + len + PAGE_SIZE <= next->start))
4978 - up(&vm_reserved_sem);
4981 - up(&vm_reserved_sem);
4982 - start = (unsigned long) UML_ROUND_UP(this->end) + PAGE_SIZE;
4983 - err = reserve_vm(start, start + len, NULL);
4984 - if(err) return(0);
4993 -void setup_range(int fd, char *driver, unsigned long start, unsigned long pfn,
4994 - unsigned long len, int need_vm, struct mem_region *region,
5000 - cur = min(len, (unsigned long) REGION_SIZE);
5001 - i = setup_one_range(fd, driver, start, pfn, cur, region);
5002 - region = regions[i];
5003 - if(need_vm && setup_region(region, reserved)){
5005 - regions[i] = NULL;
5009 - if(pfn != -1) pfn += cur;
5017 - unsigned long size;
5020 -/* iomem regions can only be added on the command line at the moment.
5021 - * Locking will be needed when they can be added via mconsole.
5024 -struct iomem iomem_regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] =
5029 -int num_iomem_regions = 0;
5031 -void add_iomem(char *name, int fd, unsigned long size)
5033 - if(num_iomem_regions == sizeof(iomem_regions)/sizeof(iomem_regions[0]))
5035 - size = (size + PAGE_SIZE - 1) & PAGE_MASK;
5036 - iomem_regions[num_iomem_regions++] =
5037 - ((struct iomem) { .name = name,
5042 -int setup_iomem(void)
5044 - struct iomem *iomem;
5047 - for(i = 0; i < num_iomem_regions; i++){
5048 - iomem = &iomem_regions[i];
5049 - setup_range(iomem->fd, iomem->name, -1, -1, iomem->size, 1,
5055 -__initcall(setup_iomem);
5057 -#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
5058 -#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
5060 -/* Changed during early boot */
5061 -static struct mem_region physmem_region;
5062 -static struct vm_reserved physmem_reserved;
5064 -void setup_physmem(unsigned long start, unsigned long reserve_end,
5065 - unsigned long len)
5067 - struct mem_region *region = &physmem_region;
5068 - struct vm_reserved *reserved = &physmem_reserved;
5069 - unsigned long cur, pfn = 0;
5070 - int do_free = 1, bootmap_size;
5073 - cur = min(len, (unsigned long) REGION_SIZE);
5074 - if(region == NULL)
5075 - region = alloc_bootmem_low_pages(sizeof(*region));
5076 - if(reserved == NULL)
5077 - reserved = alloc_bootmem_low_pages(sizeof(*reserved));
5078 - if((region == NULL) || (reserved == NULL))
5079 - panic("Couldn't allocate physmem region or vm "
5081 - setup_range(-1, NULL, start, pfn, cur, 1, region, reserved);
5084 - unsigned long reserve = reserve_end - start;
5085 - int pfn = PFN_UP(__pa(reserve_end));
5086 - int delta = (len - reserve) >> PAGE_SHIFT;
5088 - bootmap_size = init_bootmem(pfn, pfn + delta);
5089 - free_bootmem(__pa(reserve_end) + bootmap_size,
5090 - cur - bootmap_size - reserve);
5094 - pfn += cur >> PAGE_SHIFT;
5101 -struct mem_region *phys_region(unsigned long phys)
5103 - unsigned int n = phys_region_index(phys);
5105 - if(regions[n] == NULL)
5106 - panic("Physical address in uninitialized region");
5107 - return(regions[n]);
5110 -unsigned long phys_offset(unsigned long phys)
5112 - return(phys_addr(phys));
5115 -struct page *phys_mem_map(unsigned long phys)
5117 - return((struct page *) phys_region(phys)->mem_map);
5120 -struct page *pte_mem_map(pte_t pte)
5122 - return(phys_mem_map(pte_val(pte)));
5125 -struct mem_region *page_region(struct page *page, int *index_out)
5128 - struct mem_region *region;
5131 - for(i = 0; i < NREGIONS; i++){
5132 - region = regions[i];
5133 - if(region == NULL) continue;
5134 - map = region->mem_map;
5135 - if((page >= map) && (page < &map[region->len >> PAGE_SHIFT])){
5136 - if(index_out != NULL) *index_out = i;
5140 - panic("No region found for page");
5144 -unsigned long page_to_pfn(struct page *page)
5146 - struct mem_region *region = page_region(page, NULL);
5148 - return(region->start_pfn + (page - (struct page *) region->mem_map));
5151 -struct mem_region *pfn_to_region(unsigned long pfn, int *index_out)
5153 - struct mem_region *region;
5156 - for(i = 0; i < NREGIONS; i++){
5157 - region = regions[i];
5158 - if(region == NULL)
5161 - if((region->start_pfn <= pfn) &&
5162 - (region->start_pfn + (region->len >> PAGE_SHIFT) > pfn)){
5163 - if(index_out != NULL)
5171 -struct page *pfn_to_page(unsigned long pfn)
5173 - struct mem_region *region = pfn_to_region(pfn, NULL);
5174 - struct page *mem_map = (struct page *) region->mem_map;
5176 - return(&mem_map[pfn - region->start_pfn]);
5179 -unsigned long phys_to_pfn(unsigned long p)
5181 - struct mem_region *region = regions[phys_region_index(p)];
5183 - return(region->start_pfn + (phys_addr(p) >> PAGE_SHIFT));
5186 -unsigned long pfn_to_phys(unsigned long pfn)
5189 - struct mem_region *region = pfn_to_region(pfn, &n);
5191 - return(mk_phys((pfn - region->start_pfn) << PAGE_SHIFT, n));
5194 -struct page *page_mem_map(struct page *page)
5196 - return((struct page *) page_region(page, NULL)->mem_map);
5199 -extern unsigned long region_pa(void *virt)
5201 - struct mem_region *region;
5202 - unsigned long addr = (unsigned long) virt;
5205 - for(i = 0; i < NREGIONS; i++){
5206 - region = regions[i];
5207 - if(region == NULL) continue;
5208 - if((region->start <= addr) &&
5209 - (addr <= region->start + region->len))
5210 - return(mk_phys(addr - region->start, i));
5212 - panic("region_pa : no region for virtual address");
5216 -extern void *region_va(unsigned long phys)
5218 - return((void *) (phys_region(phys)->start + phys_addr(phys)));
5221 -unsigned long page_to_phys(struct page *page)
5224 - struct mem_region *region = page_region(page, &n);
5225 - struct page *map = region->mem_map;
5226 - return(mk_phys((page - map) << PAGE_SHIFT, n));
5229 -struct page *phys_to_page(unsigned long phys)
5231 - struct page *mem_map;
5233 - mem_map = phys_mem_map(phys);
5234 - return(mem_map + (phys_offset(phys) >> PAGE_SHIFT));
5237 -static int setup_mem_maps(void)
5239 - struct mem_region *region;
5242 - for(i = 0; i < NREGIONS; i++){
5243 - region = regions[i];
5244 - if((region != NULL) && (region->fd > 0)) init_maps(region);
5249 -__initcall(setup_mem_maps);
5252 * Allocate and free page tables.
5254 Index: uml-2.6.7/mm/page_alloc.c
5255 ===================================================================
5256 --- uml-2.6.7.orig/mm/page_alloc.c 2004-07-16 19:35:58.508373224 +0300
5257 +++ uml-2.6.7/mm/page_alloc.c 2004-07-16 19:47:23.806192120 +0300
5262 + arch_free_page(page, order);
5264 mod_page_state(pgfree, 1 << order);
5265 for (i = 0 ; i < (1 << order) ; ++i)
5266 free_pages_check(__FUNCTION__, page + i);
5268 struct per_cpu_pages *pcp;
5269 unsigned long flags;
5271 + arch_free_page(page, 0);
5273 kernel_map_pages(page, 1, 0);
5274 inc_page_state(pgfree);
5275 free_pages_check(__FUNCTION__, page);
5276 Index: uml-2.6.7/arch/um/kernel/skas/uaccess.c
5277 ===================================================================
5278 --- uml-2.6.7.orig/arch/um/kernel/skas/uaccess.c 2004-07-16 19:47:23.621220240 +0300
5279 +++ uml-2.6.7/arch/um/kernel/skas/uaccess.c 2004-07-16 19:47:23.735202912 +0300
5282 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
5283 + * Licensed under the GPL
5286 +#include "linux/stddef.h"
5287 +#include "linux/kernel.h"
5288 +#include "linux/string.h"
5289 +#include "linux/fs.h"
5290 +#include "linux/highmem.h"
5291 +#include "asm/page.h"
5292 +#include "asm/pgtable.h"
5293 +#include "asm/uaccess.h"
5294 +#include "kern_util.h"
5296 +extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
5299 +static unsigned long maybe_map(unsigned long virt, int is_write)
5304 + void *phys = um_virt_to_phys(current, virt, &pte);
5307 + if(IS_ERR(phys) || (is_write && !pte_write(pte))){
5308 + err = handle_page_fault(virt, 0, is_write, 0, &dummy_code);
5311 + phys = um_virt_to_phys(current, virt, NULL);
5313 + return((unsigned long) phys);
5316 +static int do_op(unsigned long addr, int len, int is_write,
5317 + int (*op)(unsigned long addr, int len, void *arg), void *arg)
5319 + struct page *page;
5322 + addr = maybe_map(addr, is_write);
5326 + page = phys_to_page(addr);
5327 + addr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK);
5328 + n = (*op)(addr, len, arg);
5334 +static int buffer_op(unsigned long addr, int len, int is_write,
5335 + int (*op)(unsigned long addr, int len, void *arg),
5338 + int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
5339 + int remain = len, n;
5341 + n = do_op(addr, size, is_write, op, arg);
5343 + return(n < 0 ? remain : 0);
5350 + while(addr < ((addr + remain) & PAGE_MASK)){
5351 + n = do_op(addr, PAGE_SIZE, is_write, op, arg);
5353 + return(n < 0 ? remain : 0);
5355 + addr += PAGE_SIZE;
5356 + remain -= PAGE_SIZE;
5361 + n = do_op(addr, remain, is_write, op, arg);
5363 + return(n < 0 ? remain : 0);
5367 +static int copy_chunk_from_user(unsigned long from, int len, void *arg)
5369 + unsigned long *to_ptr = arg, to = *to_ptr;
5371 + memcpy((void *) to, (void *) from, len);
5376 +int copy_from_user_skas(void *to, const void *from, int n)
5378 + if(segment_eq(get_fs(), KERNEL_DS)){
5379 + memcpy(to, from, n);
5383 + return(access_ok_skas(VERIFY_READ, from, n) ?
5384 + buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
5388 +static int copy_chunk_to_user(unsigned long to, int len, void *arg)
5390 + unsigned long *from_ptr = arg, from = *from_ptr;
5392 + memcpy((void *) to, (void *) from, len);
5397 +int copy_to_user_skas(void *to, const void *from, int n)
5399 + if(segment_eq(get_fs(), KERNEL_DS)){
5400 + memcpy(to, from, n);
5404 + return(access_ok_skas(VERIFY_WRITE, to, n) ?
5405 + buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
5409 +static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
5411 + char **to_ptr = arg, *to = *to_ptr;
5414 + strncpy(to, (void *) from, len);
5415 + n = strnlen(to, len);
5423 +int strncpy_from_user_skas(char *dst, const char *src, int count)
5428 + if(segment_eq(get_fs(), KERNEL_DS)){
5429 + strncpy(dst, src, count);
5430 + return(strnlen(dst, count));
5433 + if(!access_ok_skas(VERIFY_READ, src, 1))
5436 + n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user,
5440 + return(strnlen(dst, count));
5443 +static int clear_chunk(unsigned long addr, int len, void *unused)
5445 + memset((void *) addr, 0, len);
5449 +int __clear_user_skas(void *mem, int len)
5451 + return(buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL));
5454 +int clear_user_skas(void *mem, int len)
5456 + if(segment_eq(get_fs(), KERNEL_DS)){
5457 + memset(mem, 0, len);
5461 + return(access_ok_skas(VERIFY_WRITE, mem, len) ?
5462 + buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len);
5465 +static int strnlen_chunk(unsigned long str, int len, void *arg)
5467 + int *len_ptr = arg, n;
5469 + n = strnlen((void *) str, len);
5477 +int strnlen_user_skas(const void *str, int len)
5481 + if(segment_eq(get_fs(), KERNEL_DS))
5482 + return(strnlen(str, len) + 1);
5484 + n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count);
5486 + return(count + 1);
5491 + * Overrides for Emacs so that we follow Linus's tabbing style.
5492 + * Emacs will notice this stuff at the end of the file and automatically
5493 + * adjust the settings for this buffer only. This must remain at the end
5495 + * ---------------------------------------------------------------------------
5496 + * Local variables:
5497 + * c-file-style: "linux"
5500 Index: uml-2.6.7/arch/um/Makefile
5501 ===================================================================
5502 --- uml-2.6.7.orig/arch/um/Makefile 2004-07-16 19:36:57.056472560 +0300
5503 +++ uml-2.6.7/arch/um/Makefile 2004-07-16 19:47:24.132142568 +0300
5505 $(ARCH_DIR)/sys-$(SUBARCH)/
5507 # Have to precede the include because the included Makefiles reference them.
5508 -SYMLINK_HEADERS = include/asm-um/archparam.h include/asm-um/system.h \
5509 - include/asm-um/sigcontext.h include/asm-um/processor.h \
5510 - include/asm-um/ptrace.h include/asm-um/arch-signal.h
5511 +SYMLINK_HEADERS = archparam.h system.h sigcontext.h processor.h ptrace.h \
5512 + arch-signal.h module.h
5513 +SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
5515 ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
5516 $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
5518 GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
5520 -include $(ARCH_DIR)/Makefile-$(SUBARCH)
5521 -include $(ARCH_DIR)/Makefile-os-$(OS)
5522 +# This target adds dependencies to "prepare". They are defined in the included
5523 +# Makefiles (see Makefile-i386).
5525 +.PHONY: sys_prepare
5529 MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
5530 MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
5532 include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
5535 +include $(ARCH_DIR)/Makefile-$(SUBARCH)
5536 +include $(ARCH_DIR)/Makefile-os-$(OS)
5538 EXTRAVERSION := $(EXTRAVERSION)-1um
5540 ARCH_INCLUDE = -I$(ARCH_DIR)/include
5543 CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
5544 -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
5546 + -Dsigprocmask=kernel_sigprocmask $(MODE_INCLUDE)
5548 +CFLAGS += $(call check_gcc,-fno-unit-at-a-time,)
5550 LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
5552 +# These are needed for clean and mrproper, since in that case .config is not
5553 +# included; the values here are meaningless
5555 +CONFIG_NEST_LEVEL ?= 0
5556 +CONFIG_KERNEL_HALF_GIGS ?= 0
5558 SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
5560 ifeq ($(CONFIG_MODE_SKAS), y)
5561 -$(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
5562 +$(SYS_HEADERS) : $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
5565 include/linux/version.h: arch/$(ARCH)/Makefile
5566 @@ -98,17 +113,17 @@
5567 CONFIG_KERNEL_STACK_ORDER ?= 2
5568 STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
5570 -AFLAGS_vmlinux.lds.o = -U$(SUBARCH) \
5571 +AFLAGS_vmlinux.lds.o = $(shell echo -U$(SUBARCH) \
5572 -DSTART=$$(($(TOP_ADDR) - $(SIZE))) -DELF_ARCH=$(ELF_ARCH) \
5573 -DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE_TT) \
5574 - -DKERNEL_STACK_SIZE=$(STACK_SIZE)
5575 + -DKERNEL_STACK_SIZE=$(STACK_SIZE))
5577 -AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum
5578 +export AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum
5580 LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y)
5582 -$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE
5583 - $(call if_changed_dep,as_s_S)
5584 +#$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE
5585 +# $(call if_changed_dep,as_s_S)
5587 linux: vmlinux $(LD_SCRIPT-y)
5588 $(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \
5589 @@ -116,37 +131,47 @@
5591 USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
5592 USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS))
5593 +USER_CFLAGS := $(patsubst -Dsigprocmask=kernel_sigprocmask,,$(USER_CFLAGS))
5594 USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
5597 # To get a definition of F_SETSIG
5598 USER_CFLAGS += -D_GNU_SOURCE
5600 +# From main Makefile, these options are set after including the ARCH makefile.
5601 +# So copy them here.
5603 +ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
5609 +ifndef CONFIG_FRAME_POINTER
5610 +USER_CFLAGS += -fomit-frame-pointer
5613 +ifdef CONFIG_DEBUG_INFO
5617 CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/uml.lds.s \
5618 - $(ARCH_DIR)/dyn_link.ld.s $(GEN_HEADERS)
5619 + $(ARCH_DIR)/dyn_link.ld.s $(ARCH_DIR)/include/uml-config.h \
5622 +MRPROPER_FILES += $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) \
5623 + $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS))
5625 -$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c
5626 - $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
5627 +$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c sys_prepare
5629 + @ $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
5632 - for d in $(ARCH_SUBDIRS) $(ARCH_DIR)/util; \
5634 - $(MAKE) -C $$d archmrproper; \
5636 - rm -f $(CLEAN_FILES) $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) include/asm \
5637 - $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS))
5639 -archclean: sysclean
5640 - for d in $(ARCH_SUBDIRS) $(ARCH_DIR)/util; \
5642 - $(MAKE) -C $$d clean; \
5644 - find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
5645 - -o -name '*.gcov' \) -type f -print | xargs rm -f
5646 - rm -f linux x.i gmon.out $(ARCH_DIR)/link.ld $(GEN_HEADERS)
5650 - for d in $(ARCH_SUBDIRS); do $(MAKE) -C $$d fastdep; done
5652 + @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
5653 + -o -name '*.gcov' \) -type f -print | xargs rm -f
5656 cd $(TOPDIR)/$(dir $@) ; \
5657 @@ -161,19 +186,32 @@
5659 cd $(ARCH_DIR) && ln -sf os-$(OS) os
5661 -$(ARCH_DIR)/include/uml-config.h :
5662 - sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@
5664 +define filechk_umlconfig
5665 + sed 's/ CONFIG/ UML_CONFIG/'
5668 +$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h
5669 + $(call filechk,umlconfig)
5671 +filechk_gen_header = $<
5673 $(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
5675 + $(call filechk,gen_header)
5677 $(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
5679 + $(call filechk,gen_header)
5681 -$(ARCH_DIR)/util/mk_task : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h \
5682 - $(ARCH_DIR)/util FORCE ;
5683 +$(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants : $(ARCH_DIR)/util \
5684 + sys_prepare FORCE ;
5686 $(ARCH_DIR)/util: FORCE
5687 - @$(call descend,$@,)
5688 + $(Q)$(MAKE) $(build)=$@
5690 +export SUBARCH USER_CFLAGS OS
5694 -export SUBARCH USER_CFLAGS OS
5696 + echo '* linux - Binary kernel image (./linux)'
5698 Index: uml-2.6.7/arch/um/kernel/tt/unmap.c
5699 ===================================================================
5700 --- uml-2.6.7.orig/arch/um/kernel/tt/unmap.c 2004-07-16 19:37:13.584959848 +0300
5701 +++ uml-2.6.7/arch/um/kernel/tt/unmap.c 2004-07-16 19:47:23.753200176 +0300
5703 * Licensed under the GPL
5708 #include <sys/mman.h>
5711 int switcheroo(int fd, int prot, void *from, void *to, int size)
5713 Index: uml-2.6.7/arch/um/kernel/tt/ptproxy/Makefile
5714 ===================================================================
5715 --- uml-2.6.7.orig/arch/um/kernel/tt/ptproxy/Makefile 2004-07-16 19:36:30.113568504 +0300
5716 +++ uml-2.6.7/arch/um/kernel/tt/ptproxy/Makefile 2004-07-16 19:47:23.746201240 +0300
5719 $(USER_OBJS) : %.o: %.c
5720 $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
5723 Index: uml-2.6.7/arch/um/kernel/mem_user.c
5724 ===================================================================
5725 --- uml-2.6.7.orig/arch/um/kernel/mem_user.c 2004-07-16 19:36:47.959855456 +0300
5726 +++ uml-2.6.7/arch/um/kernel/mem_user.c 2004-07-16 19:47:23.721205040 +0300
5734 -#include <sys/stat.h>
5736 #include <sys/types.h>
5737 #include <sys/mman.h>
5738 #include "kern_util.h"
5739 @@ -47,105 +46,145 @@
5742 #include "tempfile.h"
5743 +#include "kern_constants.h"
5745 extern struct mem_region physmem_region;
5747 #define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
5749 -int create_mem_file(unsigned long len)
5750 +static int create_tmp_file(unsigned long len)
5756 fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
5757 - if (fchmod(fd, 0777) < 0){
5760 + os_print_error(fd, "make_tempfile");
5764 + err = os_mode_fd(fd, 0777);
5766 + os_print_error(err, "os_mode_fd");
5769 - if(os_seek_file(fd, len) < 0){
5771 + err = os_seek_file(fd, len);
5773 + os_print_error(err, "os_seek_file");
5777 - if(write(fd, &zero, 1) != 1){
5779 + err = os_write_file(fd, &zero, 1);
5781 + os_print_error(err, "os_write_file");
5784 - if(fcntl(fd, F_SETFD, 1) != 0)
5785 - perror("Setting FD_CLOEXEC failed");
5790 -int setup_region(struct mem_region *region, void *entry)
5791 +static int have_devanon = 0;
5793 +void check_devanon(void)
5797 + printk("Checking for /dev/anon on the host...");
5798 + fd = open("/dev/anon", O_RDWR);
5800 + printk("Not available (open failed with errno %d)\n", errno);
5808 +static int create_anon_file(unsigned long len)
5810 - void *loc, *start;
5814 - if(region->start != -1){
5815 - err = reserve_vm(region->start,
5816 - region->start + region->len, entry);
5818 - printk("setup_region : failed to reserve "
5819 - "0x%x - 0x%x for driver '%s'\n",
5821 - region->start + region->len,
5826 - else region->start = get_vm(region->len);
5827 - if(region->start == 0){
5828 - if(region->driver == NULL) driver = "physmem";
5829 - else driver = region->driver;
5830 - printk("setup_region : failed to find vm for "
5831 - "driver '%s' (length %d)\n", driver, region->len);
5834 - if(region->start == uml_physmem){
5835 - start = (void *) uml_reserved;
5836 - offset = uml_reserved - uml_physmem;
5839 - start = (void *) region->start;
5843 - loc = mmap(start, region->len - offset, PROT_READ | PROT_WRITE,
5844 - MAP_SHARED | MAP_FIXED, region->fd, offset);
5846 - perror("Mapping memory");
5850 + fd = open("/dev/anon", O_RDWR);
5852 + os_print_error(fd, "opening /dev/anon");
5857 + addr = mmap(NULL, len, PROT_READ | PROT_WRITE , MAP_PRIVATE, fd, 0);
5858 + if(addr == MAP_FAILED){
5859 + os_print_error((int) addr, "mapping physmem file");
5862 + munmap(addr, len);
5867 +int create_mem_file(unsigned long len)
5872 + fd = create_anon_file(len);
5873 + else fd = create_tmp_file(len);
5875 + err = os_set_exec_close(fd, 1);
5877 + os_print_error(err, "exec_close");
5881 +struct iomem_region *iomem_regions = NULL;
5882 +int iomem_size = 0;
5884 static int __init parse_iomem(char *str, int *add)
5887 + struct iomem_region *new;
5888 + struct uml_stat buf;
5889 char *file, *driver;
5894 file = strchr(str,',');
5896 - printk("parse_iomem : failed to parse iomem\n");
5898 + printf("parse_iomem : failed to parse iomem\n");
5903 fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
5905 - printk("parse_iomem - Couldn't open io file, errno = %d\n",
5909 - if(fstat(fd, &buf) < 0) {
5910 - printk("parse_iomem - cannot fstat file, errno = %d\n", errno);
5912 + os_print_error(fd, "parse_iomem - Couldn't open io file");
5915 - add_iomem(driver, fd, buf.st_size);
5917 + err = os_stat_fd(fd, &buf);
5919 + os_print_error(err, "parse_iomem - cannot stat_fd file");
5923 + new = malloc(sizeof(*new));
5925 + perror("Couldn't allocate iomem_region struct");
5929 + *new = ((struct iomem_region) { .next = iomem_regions,
5932 + .size = buf.ust_size,
5935 + iomem_regions = new;
5936 + iomem_size += new->size + UM_KERN_PAGE_SIZE;
5940 + os_close_file(fd);
5945 __uml_setup("iomem=", parse_iomem,
5946 @@ -153,73 +192,20 @@
5947 " Configure <file> as an IO memory region named <name>.\n\n"
5952 -int logging_fd = -1;
5954 -int logging_line = 0;
5955 -char logging_buf[256];
5957 -void log(char *fmt, ...)
5960 - struct timeval tv;
5961 - struct openflags flags;
5963 - if(logging == 0) return;
5964 - if(logging_fd < 0){
5965 - flags = of_create(of_trunc(of_rdrw(OPENFLAGS())));
5966 - logging_fd = os_open_file("log", flags, 0644);
5968 - gettimeofday(&tv, NULL);
5969 - sprintf(logging_buf, "%d\t %u.%u ", logging_line++, tv.tv_sec,
5971 - va_start(ap, fmt);
5972 - vsprintf(&logging_buf[strlen(logging_buf)], fmt, ap);
5974 - write(logging_fd, logging_buf, strlen(logging_buf));
5978 -int map_memory(unsigned long virt, unsigned long phys, unsigned long len,
5979 - int r, int w, int x)
5981 - struct mem_region *region = phys_region(phys);
5983 - return(os_map_memory((void *) virt, region->fd, phys_offset(phys), len,
5987 int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
5990 - if(os_protect_memory((void *) addr, len, r, w, x) < 0){
5993 + err = os_protect_memory((void *) addr, len, r, w, x);
5996 - panic("protect failed, errno = %d", errno);
5997 - else return(-errno);
5998 + panic("protect failed, err = %d", -err);
6004 -unsigned long find_iomem(char *driver, unsigned long *len_out)
6006 - struct mem_region *region;
6010 - for(i = 0; i < n; i++){
6011 - region = regions[i];
6012 - if(region == NULL) continue;
6013 - if((region->driver != NULL) &&
6014 - !strcmp(region->driver, driver)){
6015 - *len_out = region->len;
6016 - return(region->start);
6024 * Overrides for Emacs so that we follow Linus's tabbing style.
6025 * Emacs will notice this stuff at the end of the file and automatically
6026 Index: uml-2.6.7/arch/um/kernel/init_task.c
6027 ===================================================================
6028 --- uml-2.6.7.orig/arch/um/kernel/init_task.c 2004-07-16 19:37:49.384517488 +0300
6029 +++ uml-2.6.7/arch/um/kernel/init_task.c 2004-07-16 19:47:23.716205800 +0300
6031 #include "linux/module.h"
6032 #include "linux/sched.h"
6033 #include "linux/init_task.h"
6034 -#include "linux/version.h"
6035 #include "asm/uaccess.h"
6036 #include "asm/pgtable.h"
6037 #include "user_util.h"
6039 struct mm_struct init_mm = INIT_MM(init_mm);
6040 static struct files_struct init_files = INIT_FILES;
6041 static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
6043 +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
6044 EXPORT_SYMBOL(init_mm);
6048 __attribute__((__section__(".data.init_task"))) =
6049 { INIT_THREAD_INFO(init_task) };
6051 -struct task_struct *alloc_task_struct(void)
6053 - return((struct task_struct *)
6054 - __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
6057 void unprotect_stack(unsigned long stack)
6059 protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE,
6063 -void free_task_struct(struct task_struct *task)
6065 - /* free_pages decrements the page counter and only actually frees
6066 - * the pages if they are now not accessed by anything.
6068 - free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
6072 * Overrides for Emacs so that we follow Linus's tabbing style.
6073 * Emacs will notice this stuff at the end of the file and automatically
6074 Index: uml-2.6.7/arch/um/kernel/tty_log.c
6075 ===================================================================
6076 --- uml-2.6.7.orig/arch/um/kernel/tty_log.c 2004-07-16 19:36:56.920493232 +0300
6077 +++ uml-2.6.7/arch/um/kernel/tty_log.c 2004-07-16 19:47:23.753200176 +0300
6083 #include <sys/time.h>
6086 +#include "kern_util.h"
6089 #define TTY_LOG_DIR "./"
6091 #define TTY_LOG_OPEN 1
6092 #define TTY_LOG_CLOSE 2
6093 #define TTY_LOG_WRITE 3
6094 +#define TTY_LOG_EXEC 4
6097 +#define TTY_WRITE 2
6099 struct tty_log_buf {
6104 + unsigned long sec;
6105 + unsigned long usec;
6108 -int open_tty_log(void *tty)
6109 +int open_tty_log(void *tty, void *current_tty)
6112 struct tty_log_buf data;
6113 char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
6116 + gettimeofday(&tv, NULL);
6117 if(tty_log_fd != -1){
6118 - data = ((struct tty_log_buf) { what : TTY_LOG_OPEN,
6119 - tty : (unsigned long) tty,
6121 - write(tty_log_fd, &data, sizeof(data));
6122 + data = ((struct tty_log_buf) { .what = TTY_LOG_OPEN,
6123 + .tty = (unsigned long) tty,
6124 + .len = sizeof(current_tty),
6127 + .usec = tv.tv_usec } );
6128 + os_write_file(tty_log_fd, &data, sizeof(data));
6129 + os_write_file(tty_log_fd, ¤t_tty, data.len);
6133 - gettimeofday(&tv, NULL);
6134 sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec,
6135 (unsigned int) tv.tv_usec);
6137 @@ -62,30 +73,117 @@
6138 void close_tty_log(int fd, void *tty)
6140 struct tty_log_buf data;
6141 + struct timeval tv;
6143 if(tty_log_fd != -1){
6144 - data = ((struct tty_log_buf) { what : TTY_LOG_CLOSE,
6145 - tty : (unsigned long) tty,
6147 - write(tty_log_fd, &data, sizeof(data));
6148 + gettimeofday(&tv, NULL);
6149 + data = ((struct tty_log_buf) { .what = TTY_LOG_CLOSE,
6150 + .tty = (unsigned long) tty,
6154 + .usec = tv.tv_usec } );
6155 + os_write_file(tty_log_fd, &data, sizeof(data));
6159 + os_close_file(fd);
6162 -int write_tty_log(int fd, char *buf, int len, void *tty)
6163 +static int log_chunk(int fd, const char *buf, int len)
6165 + int total = 0, try, missed, n;
6169 + try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
6170 + missed = copy_from_user_proc(chunk, (char *) buf, try);
6172 + n = os_write_file(fd, chunk, try);
6189 +int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
6191 + struct timeval tv;
6192 struct tty_log_buf data;
6195 if(fd == tty_log_fd){
6196 - data = ((struct tty_log_buf) { what : TTY_LOG_WRITE,
6197 - tty : (unsigned long) tty,
6199 - write(tty_log_fd, &data, sizeof(data));
6200 + gettimeofday(&tv, NULL);
6201 + direction = is_read ? TTY_READ : TTY_WRITE;
6202 + data = ((struct tty_log_buf) { .what = TTY_LOG_WRITE,
6203 + .tty = (unsigned long) tty,
6205 + .direction = direction,
6207 + .usec = tv.tv_usec } );
6208 + os_write_file(tty_log_fd, &data, sizeof(data));
6210 - return(write(fd, buf, len));
6212 + return(log_chunk(fd, buf, len));
6215 +void log_exec(char **argv, void *tty)
6217 + struct timeval tv;
6218 + struct tty_log_buf data;
6222 + if(tty_log_fd == -1) return;
6224 + gettimeofday(&tv, NULL);
6227 + for(ptr = argv; ; ptr++){
6228 + if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
6230 + if(arg == NULL) break;
6231 + len += strlen_user_proc(arg);
6234 + data = ((struct tty_log_buf) { .what = TTY_LOG_EXEC,
6235 + .tty = (unsigned long) tty,
6239 + .usec = tv.tv_usec } );
6240 + os_write_file(tty_log_fd, &data, sizeof(data));
6242 + for(ptr = argv; ; ptr++){
6243 + if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
6245 + if(arg == NULL) break;
6246 + log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
6250 +extern void register_tty_logger(int (*opener)(void *, void *),
6251 + int (*writer)(int, const char *, int,
6253 + void (*closer)(int, void *));
6255 +static int register_logger(void)
6257 + register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
6261 +__uml_initcall(register_logger);
6263 static int __init set_tty_log_dir(char *name, int *add)
6268 tty_log_fd = strtoul(name, &end, 0);
6269 if((*end != '\0') || (end == name)){
6270 - printk("set_tty_log_fd - strtoul failed on '%s'\n", name);
6271 + printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
6275 Index: uml-2.6.7/arch/um/kernel/process_kern.c
6276 ===================================================================
6277 --- uml-2.6.7.orig/arch/um/kernel/process_kern.c 2004-07-16 19:36:45.946161584 +0300
6278 +++ uml-2.6.7/arch/um/kernel/process_kern.c 2004-07-16 19:47:23.723204736 +0300
6280 #include "linux/module.h"
6281 #include "linux/init.h"
6282 #include "linux/capability.h"
6283 +#include "linux/spinlock.h"
6284 #include "asm/unistd.h"
6285 #include "asm/mman.h"
6286 #include "asm/segment.h"
6288 #include "asm/pgtable.h"
6289 #include "asm/processor.h"
6290 #include "asm/tlbflush.h"
6291 -#include "asm/spinlock.h"
6292 #include "asm/uaccess.h"
6293 #include "asm/user.h"
6294 #include "user_util.h"
6297 struct task_struct *get_task(int pid, int require)
6299 - struct task_struct *task, *ret;
6300 + struct task_struct *ret;
6303 read_lock(&tasklist_lock);
6304 - for_each_process(task){
6305 - if(task->pid == pid){
6310 + ret = find_task_by_pid(pid);
6311 read_unlock(&tasklist_lock);
6313 if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
6317 int flags = GFP_KERNEL;
6319 if(atomic) flags |= GFP_ATOMIC;
6320 - if((page = __get_free_pages(flags, order)) == 0)
6321 + page = __get_free_pages(flags, order);
6324 stack_protections(page);
6326 @@ -103,13 +99,15 @@
6328 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
6330 - struct task_struct *p;
6333 current->thread.request.u.thread.proc = fn;
6334 current->thread.request.u.thread.arg = arg;
6335 - p = do_fork(CLONE_VM | flags, 0, NULL, 0, NULL, NULL);
6336 - if(IS_ERR(p)) panic("do_fork failed in kernel_thread");
6338 + pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, NULL, 0, NULL,
6341 + panic("do_fork failed in kernel_thread, errno = %d", pid);
6345 void switch_mm(struct mm_struct *prev, struct mm_struct *next,
6347 { external_pid(task), task });
6350 -void *switch_to(void *prev, void *next, void *last)
6351 +void *_switch_to(void *prev, void *next, void *last)
6353 return(CHOOSE_MODE(switch_to_tt(prev, next),
6354 switch_to_skas(prev, next)));
6356 void exit_thread(void)
6358 CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
6359 - unprotect_stack((unsigned long) current->thread_info);
6360 + unprotect_stack((unsigned long) current_thread);
6363 void *get_current(void)
6364 @@ -157,6 +155,10 @@
6368 +void prepare_to_copy(struct task_struct *tsk)
6372 int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
6373 unsigned long stack_top, struct task_struct * p,
6374 struct pt_regs *regs)
6377 void default_idle(void)
6382 atomic_inc(&init_mm.mm_count);
6383 current->mm = &init_mm;
6384 @@ -367,10 +369,15 @@
6385 return(clear_user(buf, size));
6388 +int strlen_user_proc(char *str)
6390 + return(strlen_user(str));
6393 int smp_sigio_handler(void)
6396 - int cpu = current->thread_info->cpu;
6397 + int cpu = current_thread->cpu;
6405 - return(current->thread_info->cpu);
6406 + return(current_thread->cpu);
6410 Index: uml-2.6.7/arch/um/config.release
6411 ===================================================================
6412 --- uml-2.6.7.orig/arch/um/config.release 2004-07-16 19:37:40.174917560 +0300
6413 +++ uml-2.6.7/arch/um/config.release 2004-07-16 19:47:23.675212032 +0300
6418 -# CONFIG_UDF_RW is not set
6420 # CONFIG_UFS_FS_WRITE is not set
6422 Index: uml-2.6.7/fs/hostfs/hostfs_kern.c
6423 ===================================================================
6424 --- uml-2.6.7.orig/fs/hostfs/hostfs_kern.c 2004-07-16 19:47:23.631218720 +0300
6425 +++ uml-2.6.7/fs/hostfs/hostfs_kern.c 2004-07-16 19:47:24.263122656 +0300
6428 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
6429 + * Licensed under the GPL
6431 + * Ported the filesystem routines to 2.5.
6432 + * 2003-02-10 Petr Baudis <pasky@ucw.cz>
6435 +#include <linux/stddef.h>
6436 +#include <linux/fs.h>
6437 +#include <linux/version.h>
6438 +#include <linux/module.h>
6439 +#include <linux/init.h>
6440 +#include <linux/slab.h>
6441 +#include <linux/pagemap.h>
6442 +#include <linux/blkdev.h>
6443 +#include <linux/list.h>
6444 +#include <linux/buffer_head.h>
6445 +#include <linux/root_dev.h>
6446 +#include <linux/statfs.h>
6447 +#include <asm/uaccess.h>
6448 +#include "hostfs.h"
6449 +#include "kern_util.h"
6451 +#include "user_util.h"
6452 +#include "2_5compat.h"
6455 +struct hostfs_inode_info {
6456 + char *host_filename;
6459 + struct inode vfs_inode;
6462 +static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
6464 + return(list_entry(inode, struct hostfs_inode_info, vfs_inode));
6467 +#define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_dentry->d_inode)
6469 +int hostfs_d_delete(struct dentry *dentry)
6474 +struct dentry_operations hostfs_dentry_ops = {
6475 + .d_delete = hostfs_d_delete,
6478 +/* Changed in hostfs_args before the kernel starts running */
6479 +static char *root_ino = "/";
6480 +static int append = 0;
6482 +#define HOSTFS_SUPER_MAGIC 0x00c0ffee
6484 +static struct inode_operations hostfs_iops;
6485 +static struct inode_operations hostfs_dir_iops;
6486 +static struct address_space_operations hostfs_link_aops;
6489 +static int __init hostfs_args(char *options, int *add)
6493 + ptr = strchr(options, ',');
6496 + if(*options != '\0')
6497 + root_ino = options;
6501 + ptr = strchr(options, ',');
6504 + if(*options != '\0'){
6505 + if(!strcmp(options, "append"))
6507 + else printf("hostfs_args - unsupported option - %s\n",
6515 +__uml_setup("hostfs=", hostfs_args,
6516 +"hostfs=<root dir>,<flags>,...\n"
6517 +" This is used to set hostfs parameters. The root directory argument\n"
6518 +" is used to confine all hostfs mounts to within the specified directory\n"
6519 +" tree on the host. If this isn't specified, then a user inside UML can\n"
6520 +" mount anything on the host that's accessible to the user that's running\n"
6522 +" The only flag currently supported is 'append', which specifies that all\n"
6523 +" files opened by hostfs will be opened in append mode.\n\n"
6527 +static char *dentry_name(struct dentry *dentry, int extra)
6529 + struct dentry *parent;
6530 + char *root, *name;
6535 + while(parent->d_parent != parent){
6536 + len += parent->d_name.len + 1;
6537 + parent = parent->d_parent;
6540 + root = HOSTFS_I(parent->d_inode)->host_filename;
6541 + len += strlen(root);
6542 + name = kmalloc(len + extra + 1, GFP_KERNEL);
6543 + if(name == NULL) return(NULL);
6547 + while(parent->d_parent != parent){
6548 + len -= parent->d_name.len + 1;
6550 + strncpy(&name[len + 1], parent->d_name.name,
6551 + parent->d_name.len);
6552 + parent = parent->d_parent;
6554 + strncpy(name, root, strlen(root));
6558 +static char *inode_name(struct inode *ino, int extra)
6560 + struct dentry *dentry;
6562 + dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
6563 + return(dentry_name(dentry, extra));
6566 +static int read_name(struct inode *ino, char *name)
6568 + /* The non-int inode fields are copied into ints by stat_file and
6569 + * then copied into the inode because passing the actual pointers
6570 + * in and having them treated as int * breaks on big-endian machines
6573 + int i_mode, i_nlink, i_blksize;
6574 + unsigned long long i_size;
6575 + unsigned long long i_ino;
6576 + unsigned long long i_blocks;
6578 + err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid,
6579 + &ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime,
6580 + &ino->i_ctime, &i_blksize, &i_blocks);
6584 + ino->i_ino = i_ino;
6585 + ino->i_mode = i_mode;
6586 + ino->i_nlink = i_nlink;
6587 + ino->i_size = i_size;
6588 + ino->i_blksize = i_blksize;
6589 + ino->i_blocks = i_blocks;
6590 + if((ino->i_sb->s_dev == ROOT_DEV) && (ino->i_uid == getuid()))
6595 +static char *follow_link(char *link)
6598 + char *name, *resolved, *end;
6603 + name = kmalloc(len, GFP_KERNEL);
6607 + n = do_readlink(link, name, len);
6619 + end = strrchr(link, '/');
6623 + *(end + 1) = '\0';
6624 + len = strlen(link) + strlen(name) + 1;
6626 + resolved = kmalloc(len, GFP_KERNEL);
6627 + if(resolved == NULL){
6632 + sprintf(resolved, "%s%s", link, name);
6640 + return(ERR_PTR(n));
6643 +static int read_inode(struct inode *ino)
6648 + /* Unfortunately, we are called from iget() when we don't have a dentry
6651 + if(list_empty(&ino->i_dentry))
6655 + name = inode_name(ino, 0);
6659 + if(file_type(name, NULL) == OS_TYPE_SYMLINK){
6660 + name = follow_link(name);
6662 + err = PTR_ERR(name);
6667 + err = read_name(ino, name);
6673 +int hostfs_statfs(struct super_block *sb, struct kstatfs *sf)
6675 + /* do_statfs uses struct statfs64 internally, but the linux kernel
6676 + * struct statfs still has 32-bit versions for most of these fields,
6677 + * so we convert them here
6680 + long long f_blocks;
6681 + long long f_bfree;
6682 + long long f_bavail;
6683 + long long f_files;
6684 + long long f_ffree;
6686 + err = do_statfs(HOSTFS_I(sb->s_root->d_inode)->host_filename,
6687 + &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
6688 + &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid),
6689 + &sf->f_namelen, sf->f_spare);
6690 + if(err) return(err);
6691 + sf->f_blocks = f_blocks;
6692 + sf->f_bfree = f_bfree;
6693 + sf->f_bavail = f_bavail;
6694 + sf->f_files = f_files;
6695 + sf->f_ffree = f_ffree;
6696 + sf->f_type = HOSTFS_SUPER_MAGIC;
6700 +static struct inode *hostfs_alloc_inode(struct super_block *sb)
6702 + struct hostfs_inode_info *hi;
6704 + hi = kmalloc(sizeof(*hi), GFP_KERNEL);
6708 + *hi = ((struct hostfs_inode_info) { .host_filename = NULL,
6711 + inode_init_once(&hi->vfs_inode);
6712 + return(&hi->vfs_inode);
6715 +static void hostfs_delete_inode(struct inode *inode)
6717 + if(HOSTFS_I(inode)->fd != -1) {
6718 + close_file(&HOSTFS_I(inode)->fd);
6719 + printk("Closing host fd in .delete_inode\n");
6720 + HOSTFS_I(inode)->fd = -1;
6722 + clear_inode(inode);
6725 +static void hostfs_destroy_inode(struct inode *inode)
6727 + if(HOSTFS_I(inode)->host_filename)
6728 + kfree(HOSTFS_I(inode)->host_filename);
6730 + if(HOSTFS_I(inode)->fd != -1) {
6731 + close_file(&HOSTFS_I(inode)->fd);
6732 + printk("Closing host fd in .destroy_inode\n");
6735 + kfree(HOSTFS_I(inode));
6738 +static void hostfs_read_inode(struct inode *inode)
6740 + read_inode(inode);
6743 +static struct super_operations hostfs_sbops = {
6744 + .alloc_inode = hostfs_alloc_inode,
6745 + .drop_inode = generic_delete_inode,
6746 + .delete_inode = hostfs_delete_inode,
6747 + .destroy_inode = hostfs_destroy_inode,
6748 + .read_inode = hostfs_read_inode,
6749 + .statfs = hostfs_statfs,
6752 +int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
6756 + unsigned long long next, ino;
6759 + name = dentry_name(file->f_dentry, 0);
6760 + if(name == NULL) return(-ENOMEM);
6761 + dir = open_dir(name, &error);
6763 + if(dir == NULL) return(-error);
6764 + next = file->f_pos;
6765 + while((name = read_dir(dir, &next, &ino, &len)) != NULL){
6766 + error = (*filldir)(ent, name, len, file->f_pos,
6769 + file->f_pos = next;
6775 +int hostfs_file_open(struct inode *ino, struct file *file)
6778 + int mode = 0, r = 0, w = 0, fd;
6780 + mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
6781 + if((mode & HOSTFS_I(ino)->mode) == mode)
6784 + /* The file may already have been opened, but with the wrong access,
6785 + * so this resets things and reopens the file with the new access.
6787 + if(HOSTFS_I(ino)->fd != -1){
6788 + close_file(&HOSTFS_I(ino)->fd);
6789 + HOSTFS_I(ino)->fd = -1;
6792 + HOSTFS_I(ino)->mode |= mode;
6793 + if(HOSTFS_I(ino)->mode & FMODE_READ)
6795 + if(HOSTFS_I(ino)->mode & FMODE_WRITE)
6800 + name = dentry_name(file->f_dentry, 0);
6804 + fd = open_file(name, r, w, append);
6806 + if(fd < 0) return(fd);
6807 + FILE_HOSTFS_I(file)->fd = fd;
6812 +int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
6817 +static struct file_operations hostfs_file_fops = {
6818 + .llseek = generic_file_llseek,
6819 + .read = generic_file_read,
6820 + .write = generic_file_write,
6821 + .mmap = generic_file_mmap,
6822 + .open = hostfs_file_open,
6824 + .fsync = hostfs_fsync,
6827 +static struct file_operations hostfs_dir_fops = {
6828 + .readdir = hostfs_readdir,
6829 + .read = generic_read_dir,
6832 +int hostfs_writepage(struct page *page, struct writeback_control *wbc)
6834 + struct address_space *mapping = page->mapping;
6835 + struct inode *inode = mapping->host;
6837 + unsigned long long base;
6838 + int count = PAGE_CACHE_SIZE;
6839 + int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
6842 + if (page->index >= end_index)
6843 + count = inode->i_size & (PAGE_CACHE_SIZE-1);
6845 + buffer = kmap(page);
6846 + base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
6848 + err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
6850 + ClearPageUptodate(page);
6854 + if (base > inode->i_size)
6855 + inode->i_size = base;
6857 + if (PageError(page))
6858 + ClearPageError(page);
6864 + unlock_page(page);
6868 +int hostfs_readpage(struct file *file, struct page *page)
6874 + start = (long long) page->index << PAGE_CACHE_SHIFT;
6875 + buffer = kmap(page);
6876 + err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
6878 + if(err < 0) goto out;
6880 + memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
6882 + flush_dcache_page(page);
6883 + SetPageUptodate(page);
6884 + if (PageError(page)) ClearPageError(page);
6888 + unlock_page(page);
6892 +int hostfs_prepare_write(struct file *file, struct page *page,
6893 + unsigned int from, unsigned int to)
6896 + long long start, tmp;
6899 + start = (long long) page->index << PAGE_CACHE_SHIFT;
6900 + buffer = kmap(page);
6903 + err = read_file(FILE_HOSTFS_I(file)->fd, &tmp, buffer,
6905 + if(err < 0) goto out;
6907 + if(to != PAGE_CACHE_SIZE){
6909 + err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer + to,
6910 + PAGE_CACHE_SIZE - to);
6911 + if(err < 0) goto out;
6919 +int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
6922 + struct address_space *mapping = page->mapping;
6923 + struct inode *inode = mapping->host;
6928 + start = (long long) (page->index << PAGE_CACHE_SHIFT) + from;
6929 + buffer = kmap(page);
6930 + err = write_file(FILE_HOSTFS_I(file)->fd, &start, buffer + from,
6932 + if(err > 0) err = 0;
6933 + if(!err && (start > inode->i_size))
6934 + inode->i_size = start;
6940 +static struct address_space_operations hostfs_aops = {
6941 + .writepage = hostfs_writepage,
6942 + .readpage = hostfs_readpage,
6943 +/* .set_page_dirty = __set_page_dirty_nobuffers, */
6944 + .prepare_write = hostfs_prepare_write,
6945 + .commit_write = hostfs_commit_write
6948 +static int init_inode(struct inode *inode, struct dentry *dentry)
6951 + int type, err = -ENOMEM, rdev;
6954 + name = dentry_name(dentry, 0);
6957 + type = file_type(name, &rdev);
6960 + else type = OS_TYPE_DIR;
6963 + if(type == OS_TYPE_SYMLINK)
6964 + inode->i_op = &page_symlink_inode_operations;
6965 + else if(type == OS_TYPE_DIR)
6966 + inode->i_op = &hostfs_dir_iops;
6967 + else inode->i_op = &hostfs_iops;
6969 + if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
6970 + else inode->i_fop = &hostfs_file_fops;
6972 + if(type == OS_TYPE_SYMLINK)
6973 + inode->i_mapping->a_ops = &hostfs_link_aops;
6974 + else inode->i_mapping->a_ops = &hostfs_aops;
6977 + case OS_TYPE_CHARDEV:
6978 + init_special_inode(inode, S_IFCHR, rdev);
6980 + case OS_TYPE_BLOCKDEV:
6981 + init_special_inode(inode, S_IFBLK, rdev);
6983 + case OS_TYPE_FIFO:
6984 + init_special_inode(inode, S_IFIFO, 0);
6986 + case OS_TYPE_SOCK:
6987 + init_special_inode(inode, S_IFSOCK, 0);
6994 +int hostfs_create(struct inode *dir, struct dentry *dentry, int mode,
6995 + struct nameidata *nd)
6997 + struct inode *inode;
7002 + inode = iget(dir->i_sb, 0);
7003 + if(inode == NULL) goto out;
7005 + error = init_inode(inode, dentry);
7010 + name = dentry_name(dentry, 0);
7014 + fd = file_create(name,
7015 + mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR,
7016 + mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP,
7017 + mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
7020 + else error = read_name(inode, name);
7026 + HOSTFS_I(inode)->fd = fd;
7027 + HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
7028 + d_instantiate(dentry, inode);
7037 +struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
7038 + struct nameidata *nd)
7040 + struct inode *inode;
7045 + inode = iget(ino->i_sb, 0);
7049 + err = init_inode(inode, dentry);
7054 + name = dentry_name(dentry, 0);
7058 + err = read_name(inode, name);
7060 + if(err == -ENOENT){
7067 + d_add(dentry, inode);
7068 + dentry->d_op = &hostfs_dentry_ops;
7074 + return(ERR_PTR(err));
7077 +static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
7082 + file = inode_name(ino, dentry->d_name.len + 1);
7083 + if(file == NULL) return(NULL);
7084 + strcat(file, "/");
7085 + len = strlen(file);
7086 + strncat(file, dentry->d_name.name, dentry->d_name.len);
7087 + file[len + dentry->d_name.len] = '\0';
7091 +int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
7093 + char *from_name, *to_name;
7096 + if((from_name = inode_dentry_name(ino, from)) == NULL)
7098 + to_name = dentry_name(to, 0);
7099 + if(to_name == NULL){
7103 + err = link_file(to_name, from_name);
7109 +int hostfs_unlink(struct inode *ino, struct dentry *dentry)
7114 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
7118 + err = unlink_file(file);
7123 +int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
7128 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
7129 + err = make_symlink(file, to);
7134 +int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
7139 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
7140 + err = do_mkdir(file, mode);
7145 +int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
7150 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
7151 + err = do_rmdir(file);
7156 +int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
7158 + struct inode *inode;
7160 + int err = -ENOMEM;
7162 + inode = iget(dir->i_sb, 0);
7166 + err = init_inode(inode, dentry);
7171 + name = dentry_name(dentry, 0);
7175 + init_special_inode(inode, mode, dev);
7176 + err = do_mknod(name, mode, dev);
7180 + err = read_name(inode, name);
7185 + d_instantiate(dentry, inode);
7196 +int hostfs_rename(struct inode *from_ino, struct dentry *from,
7197 + struct inode *to_ino, struct dentry *to)
7199 + char *from_name, *to_name;
7202 + if((from_name = inode_dentry_name(from_ino, from)) == NULL)
7204 + if((to_name = inode_dentry_name(to_ino, to)) == NULL){
7208 + err = rename_file(from_name, to_name);
7214 +void hostfs_truncate(struct inode *ino)
7216 + not_implemented();
7219 +int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
7222 + int r = 0, w = 0, x = 0, err;
7224 + if(desired & MAY_READ) r = 1;
7225 + if(desired & MAY_WRITE) w = 1;
7226 + if(desired & MAY_EXEC) x = 1;
7227 + name = inode_name(ino, 0);
7228 + if(name == NULL) return(-ENOMEM);
7229 + err = access_file(name, r, w, x);
7231 + if(!err) err = vfs_permission(ino, desired);
7235 +int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
7237 + struct hostfs_iattr attrs;
7242 + attr->ia_valid &= ~ATTR_SIZE;
7244 + attrs.ia_valid = 0;
7245 + if(attr->ia_valid & ATTR_MODE){
7246 + attrs.ia_valid |= HOSTFS_ATTR_MODE;
7247 + attrs.ia_mode = attr->ia_mode;
7249 + if(attr->ia_valid & ATTR_UID){
7250 + if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) &&
7251 + (attr->ia_uid == 0))
7252 + attr->ia_uid = getuid();
7253 + attrs.ia_valid |= HOSTFS_ATTR_UID;
7254 + attrs.ia_uid = attr->ia_uid;
7256 + if(attr->ia_valid & ATTR_GID){
7257 + if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) &&
7258 + (attr->ia_gid == 0))
7259 + attr->ia_gid = getuid();
7260 + attrs.ia_valid |= HOSTFS_ATTR_GID;
7261 + attrs.ia_gid = attr->ia_gid;
7263 + if(attr->ia_valid & ATTR_SIZE){
7264 + attrs.ia_valid |= HOSTFS_ATTR_SIZE;
7265 + attrs.ia_size = attr->ia_size;
7267 + if(attr->ia_valid & ATTR_ATIME){
7268 + attrs.ia_valid |= HOSTFS_ATTR_ATIME;
7269 + attrs.ia_atime = attr->ia_atime;
7271 + if(attr->ia_valid & ATTR_MTIME){
7272 + attrs.ia_valid |= HOSTFS_ATTR_MTIME;
7273 + attrs.ia_mtime = attr->ia_mtime;
7275 + if(attr->ia_valid & ATTR_CTIME){
7276 + attrs.ia_valid |= HOSTFS_ATTR_CTIME;
7277 + attrs.ia_ctime = attr->ia_ctime;
7279 + if(attr->ia_valid & ATTR_ATIME_SET){
7280 + attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
7282 + if(attr->ia_valid & ATTR_MTIME_SET){
7283 + attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
7285 + name = dentry_name(dentry, 0);
7286 + if(name == NULL) return(-ENOMEM);
7287 + err = set_attr(name, &attrs);
7292 + return(inode_setattr(dentry->d_inode, attr));
7295 +int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
7296 + struct kstat *stat)
7298 + generic_fillattr(dentry->d_inode, stat);
7302 +static struct inode_operations hostfs_iops = {
7303 + .create = hostfs_create,
7304 + .link = hostfs_link,
7305 + .unlink = hostfs_unlink,
7306 + .symlink = hostfs_symlink,
7307 + .mkdir = hostfs_mkdir,
7308 + .rmdir = hostfs_rmdir,
7309 + .mknod = hostfs_mknod,
7310 + .rename = hostfs_rename,
7311 + .truncate = hostfs_truncate,
7312 + .permission = hostfs_permission,
7313 + .setattr = hostfs_setattr,
7314 + .getattr = hostfs_getattr,
7317 +static struct inode_operations hostfs_dir_iops = {
7318 + .create = hostfs_create,
7319 + .lookup = hostfs_lookup,
7320 + .link = hostfs_link,
7321 + .unlink = hostfs_unlink,
7322 + .symlink = hostfs_symlink,
7323 + .mkdir = hostfs_mkdir,
7324 + .rmdir = hostfs_rmdir,
7325 + .mknod = hostfs_mknod,
7326 + .rename = hostfs_rename,
7327 + .truncate = hostfs_truncate,
7328 + .permission = hostfs_permission,
7329 + .setattr = hostfs_setattr,
7330 + .getattr = hostfs_getattr,
7333 +int hostfs_link_readpage(struct file *file, struct page *page)
7335 + char *buffer, *name;
7339 + start = page->index << PAGE_CACHE_SHIFT;
7340 + buffer = kmap(page);
7341 + name = inode_name(page->mapping->host, 0);
7342 + if(name == NULL) return(-ENOMEM);
7343 + err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
7345 + if(err == PAGE_CACHE_SIZE)
7348 + flush_dcache_page(page);
7349 + SetPageUptodate(page);
7350 + if (PageError(page)) ClearPageError(page);
7354 + unlock_page(page);
7358 +static struct address_space_operations hostfs_link_aops = {
7359 + .readpage = hostfs_link_readpage,
7362 +static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
7364 + struct inode *root_inode;
7365 + char *name, *data = d;
7368 + sb->s_blocksize = 1024;
7369 + sb->s_blocksize_bits = 10;
7370 + sb->s_magic = HOSTFS_SUPER_MAGIC;
7371 + sb->s_op = &hostfs_sbops;
7373 + if((data == NULL) || (*data == '\0'))
7377 + name = kmalloc(strlen(data) + 1, GFP_KERNEL);
7381 + strcpy(name, data);
7383 + root_inode = iget(sb, 0);
7384 + if(root_inode == NULL)
7387 + err = init_inode(root_inode, NULL);
7391 + HOSTFS_I(root_inode)->host_filename = name;
7394 + sb->s_root = d_alloc_root(root_inode);
7395 + if(sb->s_root == NULL)
7398 + err = read_inode(root_inode);
7412 +static struct super_block *hostfs_read_sb(struct file_system_type *type,
7413 + int flags, const char *dev_name,
7416 + return(get_sb_nodev(type, flags, data, hostfs_fill_sb_common));
7419 +static struct file_system_type hostfs_type = {
7420 + .owner = THIS_MODULE,
7422 + .get_sb = hostfs_read_sb,
7423 + .kill_sb = kill_anon_super,
7427 +static int __init init_hostfs(void)
7429 + return(register_filesystem(&hostfs_type));
7432 +static void __exit exit_hostfs(void)
7434 + unregister_filesystem(&hostfs_type);
7437 +module_init(init_hostfs)
7438 +module_exit(exit_hostfs)
7439 +MODULE_LICENSE("GPL");
7442 + * Overrides for Emacs so that we follow Linus's tabbing style.
7443 + * Emacs will notice this stuff at the end of the file and automatically
7444 + * adjust the settings for this buffer only. This must remain at the end
7446 + * ---------------------------------------------------------------------------
7447 + * Local variables:
7448 + * c-file-style: "linux"
7451 Index: uml-2.6.7/include/asm-um/module-generic.h
7452 ===================================================================
7453 --- uml-2.6.7.orig/include/asm-um/module-generic.h 2004-07-16 19:47:23.634218264 +0300
7454 +++ uml-2.6.7/include/asm-um/module-generic.h 2004-07-16 19:47:23.791194400 +0300
7456 +#ifndef __UM_MODULE_GENERIC_H
7457 +#define __UM_MODULE_GENERIC_H
7459 +#include "asm/arch/module.h"
7462 Index: uml-2.6.7/arch/um/include/user_util.h
7463 ===================================================================
7464 --- uml-2.6.7.orig/arch/um/include/user_util.h 2004-07-16 19:36:02.218809152 +0300
7465 +++ uml-2.6.7/arch/um/include/user_util.h 2004-07-16 19:47:24.794041944 +0300
7467 extern int unlockpt(int __fd);
7468 extern char *ptsname(int __fd);
7470 -enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
7476 extern void *add_signal_handler(int sig, void (*handler)(int));
7477 extern int start_fork_tramp(void *arg, unsigned long temp_stack,
7478 int clone_flags, int (*tramp)(void *));
7479 -extern int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags);
7480 extern int linux_main(int argc, char **argv);
7481 extern void set_cmdline(char *cmd);
7482 extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
7483 extern int get_pty(void);
7484 extern void *um_kmalloc(int size);
7485 -extern int raw(int fd, int complain);
7486 extern int switcheroo(int fd, int prot, void *from, void *to, int size);
7487 extern void setup_machinename(char *machine_out);
7488 extern void setup_hostinfo(void);
7490 extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
7491 extern void write_sigio_workaround(void);
7492 extern void arch_check_bugs(void);
7493 +extern int cpu_feature(char *what, char *buf, int len);
7494 extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
7495 extern int arch_fixup(unsigned long address, void *sc_ptr);
7496 extern void forward_pending_sigio(int target);
7497 extern int can_do_skas(void);
7499 +extern void arch_init_thread(void);
7501 +extern int __raw(int fd, int complain, int now);
7502 +#define raw(fd, complain) __raw((fd), (complain), 1)
7504 +#define CATCH_EINTR(expr) while ( ((expr) < 0) && errno == EINTR)
7508 Index: uml-2.6.7/include/asm-um/cpufeature.h
7509 ===================================================================
7510 --- uml-2.6.7.orig/include/asm-um/cpufeature.h 2004-07-16 19:47:23.633218416 +0300
7511 +++ uml-2.6.7/include/asm-um/cpufeature.h 2004-07-16 19:47:23.788194856 +0300
7513 +#ifndef __UM_CPUFEATURE_H
7514 +#define __UM_CPUFEATURE_H
7516 +#include "asm/arch/cpufeature.h"
7519 Index: uml-2.6.7/arch/um/kernel/uaccess_user.c
7520 ===================================================================
7521 --- uml-2.6.7.orig/arch/um/kernel/uaccess_user.c 2004-07-16 19:37:08.883674552 +0300
7522 +++ uml-2.6.7/arch/um/kernel/uaccess_user.c 2004-07-16 19:47:23.754200024 +0300
7526 *fault_catcher = &jbuf;
7527 - if(setjmp(jbuf) == 0){
7528 + if(sigsetjmp(jbuf, 1) == 0){
7532 Index: uml-2.6.7/arch/um/kernel/tt/exec_kern.c
7533 ===================================================================
7534 --- uml-2.6.7.orig/arch/um/kernel/tt/exec_kern.c 2004-07-16 19:36:10.502549832 +0300
7535 +++ uml-2.6.7/arch/um/kernel/tt/exec_kern.c 2004-07-16 19:47:23.743201696 +0300
7537 #include "mem_user.h"
7542 static int exec_tramp(void *sig_stack)
7548 - if(current->thread_info->cpu == 0)
7549 + if(current_thread->cpu == 0)
7550 forward_interrupts(new_pid);
7551 current->thread.request.op = OP_EXEC;
7552 current->thread.request.u.exec.pid = new_pid;
7553 - unprotect_stack((unsigned long) current->thread_info);
7554 + unprotect_stack((unsigned long) current_thread);
7555 os_usr1_process(os_getpid());
7559 protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
7560 - task_protections((unsigned long) current->thread_info);
7561 + task_protections((unsigned long) current_thread);
7565 Index: uml-2.6.7/arch/um/kernel/frame.c
7566 ===================================================================
7567 --- uml-2.6.7.orig/arch/um/kernel/frame.c 2004-07-16 19:36:25.094331544 +0300
7568 +++ uml-2.6.7/arch/um/kernel/frame.c 2004-07-16 19:47:24.796041640 +0300
7570 #include "sysdep/sigcontext.h"
7571 #include "frame_user.h"
7572 #include "kern_util.h"
7573 +#include "user_util.h"
7574 #include "ptrace_user.h"
7578 /* Wait for it to stop itself and continue it with a SIGUSR1 to force
7579 * it into the signal handler.
7581 - n = waitpid(pid, &status, WUNTRACED);
7582 + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
7584 printf("capture_stack : waitpid failed - errno = %d\n", errno);
7587 * At this point, the handler has stuffed the addresses of
7588 * sig, sc, and SA_RESTORER in raw.
7590 - n = waitpid(pid, &status, WUNTRACED);
7591 + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
7593 printf("capture_stack : waitpid failed - errno = %d\n", errno);
7599 - if(waitpid(pid, &status, 0) < 0){
7600 + CATCH_EINTR(n = waitpid(pid, &status, 0));
7602 printf("capture_stack : waitpid failed - errno = %d\n", errno);
7606 struct sc_frame_raw raw_sc;
7607 struct si_frame_raw raw_si;
7608 void *stack, *sigstack;
7609 - unsigned long top, sig_top, base;
7610 + unsigned long top, base;
7612 stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
7613 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
7617 top = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
7618 - sig_top = (unsigned long) sigstack + PAGE_SIZE;
7620 /* Get the sigcontext, no sigrestorer layout */
7621 raw_sc.restorer = 0;
7622 Index: uml-2.6.7/include/asm-um/unistd.h
7623 ===================================================================
7624 --- uml-2.6.7.orig/include/asm-um/unistd.h 2004-07-16 19:37:20.150961664 +0300
7625 +++ uml-2.6.7/include/asm-um/unistd.h 2004-07-16 19:47:23.804192424 +0300
7627 set_fs(KERNEL_DS); \
7633 + errno = -(long)ret; \
7636 static inline long open(const char *pathname, int flags, int mode)
7638 Index: uml-2.6.7/arch/um/include/mem_kern.h
7639 ===================================================================
7640 --- uml-2.6.7.orig/arch/um/include/mem_kern.h 2004-07-16 19:47:23.613221456 +0300
7641 +++ uml-2.6.7/arch/um/include/mem_kern.h 2004-07-16 19:47:23.704207624 +0300
7644 + * Copyright (C) 2003 Jeff Dike (jdike@addtoit.com)
7645 + * Licensed under the GPL
7648 +#ifndef __MEM_KERN_H__
7649 +#define __MEM_KERN_H__
7651 +#include "linux/list.h"
7652 +#include "linux/types.h"
7655 + struct list_head list;
7656 + int (*proc)(int, unsigned long, int, __u64);
7659 +extern void register_remapper(struct remapper *info);
7664 + * Overrides for Emacs so that we follow Linus's tabbing style.
7665 + * Emacs will notice this stuff at the end of the file and automatically
7666 + * adjust the settings for this buffer only. This must remain at the end
7668 + * ---------------------------------------------------------------------------
7669 + * Local variables:
7670 + * c-file-style: "linux"
7673 Index: uml-2.6.7/arch/um/dyn.lds.S
7674 ===================================================================
7675 --- uml-2.6.7.orig/arch/um/dyn.lds.S 2004-07-16 19:36:43.059600408 +0300
7676 +++ uml-2.6.7/arch/um/dyn.lds.S 2004-07-16 19:47:23.700208232 +0300
7678 +#include <asm-generic/vmlinux.lds.h>
7680 OUTPUT_FORMAT(ELF_FORMAT)
7681 OUTPUT_ARCH(ELF_ARCH)
7685 . = START + SIZEOF_HEADERS;
7686 .interp : { *(.interp) }
7689 . = ALIGN(4096); /* Init code and data */
7692 - .text.init : { *(.text.init) }
7705 - *(.text .stub .text.* .gnu.linkonce.t.*)
7708 + *(.stub .text.* .gnu.linkonce.t.*)
7709 /* .gnu.warning sections are handled specially by elf32.em. */
7714 #include "asm/common.lds.S"
7716 - .data.init : { *(.data.init) }
7717 + init.data : { *(.init.data) }
7719 /* Ensure the __preinit_array_start label is properly aligned. We
7720 could instead move the label definition inside the section, but
7721 Index: uml-2.6.7/arch/um/kernel/trap_user.c
7722 ===================================================================
7723 --- uml-2.6.7.orig/arch/um/kernel/trap_user.c 2004-07-16 19:36:37.162496904 +0300
7724 +++ uml-2.6.7/arch/um/kernel/trap_user.c 2004-07-16 19:47:24.799041184 +0300
7732 #include <sys/time.h>
7733 -#include <sys/ioctl.h>
7734 #include <sys/ptrace.h>
7735 #include <sys/wait.h>
7736 #include <asm/page.h>
7741 - while(waitpid(pid, NULL, 0) > 0) kill(pid, SIGCONT);
7744 + CATCH_EINTR(n = waitpid(pid, NULL, 0));
7746 + kill(pid, SIGCONT);
7752 /* Unlocked - don't care if this is a bit off */
7755 [ SIGILL ] { .handler = relay_signal,
7757 + [ SIGWINCH ] { .handler = winch,
7759 [ SIGBUS ] { .handler = bus_handler,
7761 [ SIGSEGV] { .handler = segv_handler,
7762 @@ -102,12 +109,11 @@
7766 -extern int timer_irq_inited, missed_ticks[];
7767 +extern int timer_irq_inited;
7769 void alarm_handler(int sig, struct sigcontext sc)
7771 if(!timer_irq_inited) return;
7772 - missed_ticks[cpu()]++;
7780 - longjmp(*buf, val);
7781 + siglongjmp(*buf, val);
7785 Index: uml-2.6.7/arch/um/Kconfig_net
7786 ===================================================================
7787 --- uml-2.6.7.orig/arch/um/Kconfig_net 2004-07-16 19:36:54.256898160 +0300
7788 +++ uml-2.6.7/arch/um/Kconfig_net 2004-07-16 19:47:23.712206408 +0300
7791 -menu "Network Devices"
7792 +menu "UML Network Devices"
7795 # UML virtual driver
7796 @@ -176,73 +176,5 @@
7798 Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
7801 -# Below are hardware-independent drivers mirrored from
7802 -# drivers/net/Config.in. It would be nice if Linux
7803 -# had HW independent drivers separated from the other
7804 -# but it does not. Until then each non-ISA/PCI arch
7805 -# needs to provide it's own menu of network drivers
7807 - tristate "Dummy net driver support"
7810 - tristate "Bonding driver support"
7813 - tristate "EQL (serial line load balancing) support"
7816 - tristate "Universal TUN/TAP device driver support"
7819 - tristate "Ethertap network tap (OBSOLETE)"
7820 - depends on EXPERIMENTAL && NETLINK
7823 - tristate "PPP (point-to-point protocol) support"
7825 -config PPP_MULTILINK
7826 - bool "PPP multilink support (EXPERIMENTAL)"
7827 - depends on PPP && EXPERIMENTAL
7830 - bool "PPP filtering"
7831 - depends on PPP && FILTER
7834 - tristate "PPP support for async serial ports"
7837 -config PPP_SYNC_TTY
7838 - tristate "PPP support for sync tty ports"
7842 - tristate "PPP Deflate compression"
7846 - tristate "PPP BSD-Compress compression"
7850 - tristate "PPP over Ethernet (EXPERIMENTAL)"
7851 - depends on PPP && EXPERIMENTAL
7854 - tristate "SLIP (serial line) support"
7856 -config SLIP_COMPRESSED
7857 - bool "CSLIP compressed headers"
7861 - bool "Keepalive and linefill"
7864 -config SLIP_MODE_SLIP6
7865 - bool "Six bit SLIP encapsulation"
7870 Index: uml-2.6.7/fs/hppfs/Makefile
7871 ===================================================================
7872 --- uml-2.6.7.orig/fs/hppfs/Makefile 2004-07-16 19:47:23.632218568 +0300
7873 +++ uml-2.6.7/fs/hppfs/Makefile 2004-07-16 19:47:23.786195160 +0300
7876 +# Copyright (C) 2002, 2003 Jeff Dike (jdike@karaya.com)
7877 +# Licensed under the GPL
7880 +hppfs-objs := hppfs_kern.o
7883 +obj-$(CONFIG_HPPFS) += hppfs.o
7893 +archmrproper: clean
7894 Index: uml-2.6.7/arch/um/kernel/trap_kern.c
7895 ===================================================================
7896 --- uml-2.6.7.orig/arch/um/kernel/trap_kern.c 2004-07-16 19:35:56.026750488 +0300
7897 +++ uml-2.6.7/arch/um/kernel/trap_kern.c 2004-07-16 19:47:23.742201848 +0300
7899 #include "asm/tlbflush.h"
7900 #include "asm/a.out.h"
7901 #include "asm/current.h"
7902 +#include "asm/irq.h"
7903 #include "user_util.h"
7904 #include "kern_util.h"
7906 #include "chan_kern.h"
7907 #include "mconsole_kern.h"
7908 #include "2_5compat.h"
7910 +#include "mem_kern.h"
7912 int handle_page_fault(unsigned long address, unsigned long ip,
7913 int is_write, int is_user, int *code_out)
7915 if(is_write && !(vma->vm_flags & VM_WRITE))
7917 page = address & PAGE_MASK;
7918 - if(page == (unsigned long) current->thread_info + PAGE_SIZE)
7919 + if(page == (unsigned long) current_thread + PAGE_SIZE)
7920 panic("Kernel stack overflow");
7921 pgd = pgd_offset(mm, page);
7922 pmd = pmd_offset(pgd, page);
7926 switch (handle_mm_fault(mm, vma, address, is_write)){
7927 case VM_FAULT_MINOR:
7934 + if (current->pid == 1) {
7935 + up_read(&mm->mmap_sem);
7937 + down_read(&mm->mmap_sem);
7942 pte = pte_offset_kernel(pmd, page);
7943 } while(!pte_present(*pte));
7945 *pte = pte_mkyoung(*pte);
7946 if(pte_write(*pte)) *pte = pte_mkdirty(*pte);
7947 flush_tlb_page(vma, page);
7950 up_read(&mm->mmap_sem);
7956 +LIST_HEAD(physmem_remappers);
7958 +void register_remapper(struct remapper *info)
7960 + list_add(&info->list, &physmem_remappers);
7963 +static int check_remapped_addr(unsigned long address, int is_write)
7965 + struct remapper *remapper;
7966 + struct list_head *ele;
7970 + fd = phys_mapping(__pa(address), &offset);
7974 + list_for_each(ele, &physmem_remappers){
7975 + remapper = list_entry(ele, struct remapper, list);
7976 + if((*remapper->proc)(fd, address, is_write, offset))
7983 unsigned long segv(unsigned long address, unsigned long ip, int is_write,
7984 int is_user, void *sc)
7987 flush_tlb_kernel_vm();
7990 - if(current->mm == NULL)
7991 + else if(check_remapped_addr(address & PAGE_MASK, is_write))
7993 + else if(current->mm == NULL)
7994 panic("Segfault with no mm");
7995 err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
7998 current->thread.fault_addr = (void *) address;
7999 do_longjmp(catcher, 1);
8001 - else if(current->thread.fault_addr != NULL){
8002 + else if(current->thread.fault_addr != NULL)
8003 panic("fault_addr set but no fault catcher");
8005 else if(arch_fixup(ip, sc))
8012 - printk(KERN_ERR "Unfixable SEGV in '%s' (pid %d) at 0x%lx "
8013 - "(ip 0x%lx)\n", current->comm, current->pid, address, ip);
8014 si.si_signo = SIGSEGV;
8015 si.si_code = SEGV_ACCERR;
8016 si.si_addr = (void *) address;
8017 @@ -180,6 +215,11 @@
8018 else relay_signal(sig, regs);
8021 +void winch(int sig, union uml_pt_regs *regs)
8023 + do_IRQ(WINCH_IRQ, regs);
8026 void trap_init(void)
8029 Index: uml-2.6.7/arch/um/drivers/cow_sys.h
8030 ===================================================================
8031 --- uml-2.6.7.orig/arch/um/drivers/cow_sys.h 2004-07-16 19:47:23.608222216 +0300
8032 +++ uml-2.6.7/arch/um/drivers/cow_sys.h 2004-07-16 19:47:23.679211424 +0300
8034 +#ifndef __COW_SYS_H__
8035 +#define __COW_SYS_H__
8037 +#include "kern_util.h"
8038 +#include "user_util.h"
8042 +static inline void *cow_malloc(int size)
8044 + return(um_kmalloc(size));
8047 +static inline void cow_free(void *ptr)
8052 +#define cow_printf printk
8054 +static inline char *cow_strdup(char *str)
8056 + return(uml_strdup(str));
8059 +static inline int cow_seek_file(int fd, __u64 offset)
8061 + return(os_seek_file(fd, offset));
8064 +static inline int cow_file_size(char *file, __u64 *size_out)
8066 + return(os_file_size(file, size_out));
8069 +static inline int cow_write_file(int fd, char *buf, int size)
8071 + return(os_write_file(fd, buf, size));
8077 + * ---------------------------------------------------------------------------
8078 + * Local variables:
8079 + * c-file-style: "linux"
8082 Index: uml-2.6.7/arch/um/drivers/harddog_user.c
8083 ===================================================================
8084 --- uml-2.6.7.orig/arch/um/drivers/harddog_user.c 2004-07-16 19:36:22.284758664 +0300
8085 +++ uml-2.6.7/arch/um/drivers/harddog_user.c 2004-07-16 19:47:23.682210968 +0300
8087 dup2(data->stdin, 0);
8088 dup2(data->stdout, 1);
8089 dup2(data->stdout, 2);
8090 - close(data->stdin);
8091 - close(data->stdout);
8092 - close(data->close_me[0]);
8093 - close(data->close_me[1]);
8094 + os_close_file(data->stdin);
8095 + os_close_file(data->stdout);
8096 + os_close_file(data->close_me[0]);
8097 + os_close_file(data->close_me[1]);
8100 int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
8104 err = os_pipe(in_fds, 1, 0);
8106 - printk("harddog_open - os_pipe failed, errno = %d\n", -err);
8109 + printk("harddog_open - os_pipe failed, err = %d\n", -err);
8113 err = os_pipe(out_fds, 1, 0);
8115 - printk("harddog_open - os_pipe failed, errno = %d\n", -err);
8118 + printk("harddog_open - os_pipe failed, err = %d\n", -err);
8119 + goto out_close_in;
8122 data.stdin = out_fds[0];
8125 pid = run_helper(pre_exec, &data, args, NULL);
8127 - close(out_fds[0]);
8129 + os_close_file(out_fds[0]);
8130 + os_close_file(in_fds[1]);
8134 - printk("harddog_open - run_helper failed, errno = %d\n", err);
8136 + printk("harddog_open - run_helper failed, errno = %d\n", -err);
8137 + goto out_close_out;
8140 - n = read(in_fds[0], &c, sizeof(c));
8141 + n = os_read_file(in_fds[0], &c, sizeof(c));
8143 printk("harddog_open - EOF on watchdog pipe\n");
8147 + goto out_close_out;
8150 printk("harddog_open - read of watchdog pipe failed, "
8151 - "errno = %d\n", errno);
8152 + "err = %d\n", -n);
8157 + goto out_close_out;
8159 *in_fd_ret = in_fds[0];
8160 *out_fd_ret = out_fds[1];
8164 + os_close_file(in_fds[0]);
8165 + os_close_file(in_fds[1]);
8167 + os_close_file(out_fds[0]);
8168 + os_close_file(out_fds[1]);
8170 - close(out_fds[1]);
8175 void stop_watchdog(int in_fd, int out_fd)
8179 + os_close_file(in_fd);
8180 + os_close_file(out_fd);
8183 int ping_watchdog(int fd)
8184 @@ -115,11 +120,12 @@
8188 - n = write(fd, &c, sizeof(c));
8189 - if(n < sizeof(c)){
8190 - printk("ping_watchdog - write failed, errno = %d\n",
8193 + n = os_write_file(fd, &c, sizeof(c));
8194 + if(n != sizeof(c)){
8195 + printk("ping_watchdog - write failed, err = %d\n", -n);
8202 Index: uml-2.6.7/fs/hostfs/hostfs_user.c
8203 ===================================================================
8204 --- uml-2.6.7.orig/fs/hostfs/hostfs_user.c 2004-07-16 19:47:23.631218720 +0300
8205 +++ uml-2.6.7/fs/hostfs/hostfs_user.c 2004-07-16 19:47:23.783195616 +0300
8208 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
8209 + * Licensed under the GPL
8212 +#include <unistd.h>
8215 +#include <dirent.h>
8218 +#include <string.h>
8219 +#include <sys/stat.h>
8220 +#include <sys/time.h>
8221 +#include <sys/vfs.h>
8222 +#include "hostfs.h"
8223 +#include "kern_util.h"
8226 +int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
8227 + int *nlink_out, int *uid_out, int *gid_out,
8228 + unsigned long long *size_out, struct timespec *atime_out,
8229 + struct timespec *mtime_out, struct timespec *ctime_out,
8230 + int *blksize_out, unsigned long long *blocks_out)
8232 + struct stat64 buf;
8234 + if(lstat64(path, &buf) < 0)
8237 + /* See the Makefile for why STAT64_INO_FIELD is passed in
8240 + if(inode_out != NULL) *inode_out = buf.STAT64_INO_FIELD;
8241 + if(mode_out != NULL) *mode_out = buf.st_mode;
8242 + if(nlink_out != NULL) *nlink_out = buf.st_nlink;
8243 + if(uid_out != NULL) *uid_out = buf.st_uid;
8244 + if(gid_out != NULL) *gid_out = buf.st_gid;
8245 + if(size_out != NULL) *size_out = buf.st_size;
8246 + if(atime_out != NULL) {
8247 + atime_out->tv_sec = buf.st_atime;
8248 + atime_out->tv_nsec = 0;
8250 + if(mtime_out != NULL) {
8251 + mtime_out->tv_sec = buf.st_mtime;
8252 + mtime_out->tv_nsec = 0;
8254 + if(ctime_out != NULL) {
8255 + ctime_out->tv_sec = buf.st_ctime;
8256 + ctime_out->tv_nsec = 0;
8258 + if(blksize_out != NULL) *blksize_out = buf.st_blksize;
8259 + if(blocks_out != NULL) *blocks_out = buf.st_blocks;
8263 +int file_type(const char *path, int *rdev)
8265 + struct stat64 buf;
8267 + if(lstat64(path, &buf) < 0)
8270 + *rdev = buf.st_rdev;
8272 + if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
8273 + else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
8274 + else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
8275 + else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
8276 + else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO);
8277 + else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK);
8278 + else return(OS_TYPE_FILE);
8281 +int access_file(char *path, int r, int w, int x)
8285 + if(r) mode = R_OK;
8286 + if(w) mode |= W_OK;
8287 + if(x) mode |= X_OK;
8288 + if(access(path, mode) != 0) return(-errno);
8292 +int open_file(char *path, int r, int w, int append)
8302 + else panic("Impossible mode in open_file");
8306 + fd = open64(path, mode);
8307 + if(fd < 0) return(-errno);
8311 +void *open_dir(char *path, int *err_out)
8315 + dir = opendir(path);
8317 + if(dir == NULL) return(NULL);
8321 +char *read_dir(void *stream, unsigned long long *pos,
8322 + unsigned long long *ino_out, int *len_out)
8324 + DIR *dir = stream;
8325 + struct dirent *ent;
8327 + seekdir(dir, *pos);
8328 + ent = readdir(dir);
8329 + if(ent == NULL) return(NULL);
8330 + *len_out = strlen(ent->d_name);
8331 + *ino_out = ent->d_ino;
8332 + *pos = telldir(dir);
8333 + return(ent->d_name);
8336 +int read_file(int fd, unsigned long long *offset, char *buf, int len)
8340 + n = pread64(fd, buf, len, *offset);
8341 + if(n < 0) return(-errno);
8346 +int write_file(int fd, unsigned long long *offset, const char *buf, int len)
8350 + n = pwrite64(fd, buf, len, *offset);
8351 + if(n < 0) return(-errno);
8356 +int lseek_file(int fd, long long offset, int whence)
8360 + ret = lseek64(fd, offset, whence);
8361 + if(ret < 0) return(-errno);
8365 +void close_file(void *stream)
8367 + close(*((int *) stream));
8370 +void close_dir(void *stream)
8375 +int file_create(char *name, int ur, int uw, int ux, int gr,
8376 + int gw, int gx, int or, int ow, int ox)
8381 + mode |= ur ? S_IRUSR : 0;
8382 + mode |= uw ? S_IWUSR : 0;
8383 + mode |= ux ? S_IXUSR : 0;
8384 + mode |= gr ? S_IRGRP : 0;
8385 + mode |= gw ? S_IWGRP : 0;
8386 + mode |= gx ? S_IXGRP : 0;
8387 + mode |= or ? S_IROTH : 0;
8388 + mode |= ow ? S_IWOTH : 0;
8389 + mode |= ox ? S_IXOTH : 0;
8390 + fd = open64(name, O_CREAT | O_RDWR, mode);
8396 +int set_attr(const char *file, struct hostfs_iattr *attrs)
8398 + struct utimbuf buf;
8401 + if(attrs->ia_valid & HOSTFS_ATTR_MODE){
8402 + if(chmod(file, attrs->ia_mode) != 0) return(-errno);
8404 + if(attrs->ia_valid & HOSTFS_ATTR_UID){
8405 + if(chown(file, attrs->ia_uid, -1)) return(-errno);
8407 + if(attrs->ia_valid & HOSTFS_ATTR_GID){
8408 + if(chown(file, -1, attrs->ia_gid)) return(-errno);
8410 + if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
8411 + if(truncate(file, attrs->ia_size)) return(-errno);
8413 + ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET;
8414 + if((attrs->ia_valid & ma) == ma){
8415 + buf.actime = attrs->ia_atime.tv_sec;
8416 + buf.modtime = attrs->ia_mtime.tv_sec;
8417 + if(utime(file, &buf) != 0) return(-errno);
8420 + struct timespec ts;
8422 + if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){
8423 + err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
8424 + NULL, NULL, &ts, NULL, NULL, NULL);
8427 + buf.actime = attrs->ia_atime.tv_sec;
8428 + buf.modtime = ts.tv_sec;
8429 + if(utime(file, &buf) != 0)
8432 + if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){
8433 + err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
8434 + NULL, &ts, NULL, NULL, NULL, NULL);
8437 + buf.actime = ts.tv_sec;
8438 + buf.modtime = attrs->ia_mtime.tv_sec;
8439 + if(utime(file, &buf) != 0)
8443 + if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
8444 + if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
8445 + err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL,
8446 + &attrs->ia_atime, &attrs->ia_mtime, NULL,
8448 + if(err != 0) return(err);
8453 +int make_symlink(const char *from, const char *to)
8457 + err = symlink(to, from);
8458 + if(err) return(-errno);
8462 +int unlink_file(const char *file)
8466 + err = unlink(file);
8467 + if(err) return(-errno);
8471 +int do_mkdir(const char *file, int mode)
8475 + err = mkdir(file, mode);
8476 + if(err) return(-errno);
8480 +int do_rmdir(const char *file)
8484 + err = rmdir(file);
8485 + if(err) return(-errno);
8489 +int do_mknod(const char *file, int mode, int dev)
8493 + err = mknod(file, mode, dev);
8494 + if(err) return(-errno);
8498 +int link_file(const char *to, const char *from)
8502 + err = link(to, from);
8503 + if(err) return(-errno);
8507 +int do_readlink(char *file, char *buf, int size)
8511 + n = readlink(file, buf, size);
8519 +int rename_file(char *from, char *to)
8523 + err = rename(from, to);
8524 + if(err < 0) return(-errno);
8528 +int do_statfs(char *root, long *bsize_out, long long *blocks_out,
8529 + long long *bfree_out, long long *bavail_out,
8530 + long long *files_out, long long *ffree_out,
8531 + void *fsid_out, int fsid_size, long *namelen_out,
8534 + struct statfs64 buf;
8537 + err = statfs64(root, &buf);
8538 + if(err < 0) return(-errno);
8539 + *bsize_out = buf.f_bsize;
8540 + *blocks_out = buf.f_blocks;
8541 + *bfree_out = buf.f_bfree;
8542 + *bavail_out = buf.f_bavail;
8543 + *files_out = buf.f_files;
8544 + *ffree_out = buf.f_ffree;
8545 + memcpy(fsid_out, &buf.f_fsid,
8546 + sizeof(buf.f_fsid) > fsid_size ? fsid_size :
8547 + sizeof(buf.f_fsid));
8548 + *namelen_out = buf.f_namelen;
8549 + spare_out[0] = buf.f_spare[0];
8550 + spare_out[1] = buf.f_spare[1];
8551 + spare_out[2] = buf.f_spare[2];
8552 + spare_out[3] = buf.f_spare[3];
8553 + spare_out[4] = buf.f_spare[4];
8554 + spare_out[5] = buf.f_spare[5];
8559 + * Overrides for Emacs so that we follow Linus's tabbing style.
8560 + * Emacs will notice this stuff at the end of the file and automatically
8561 + * adjust the settings for this buffer only. This must remain at the end
8563 + * ---------------------------------------------------------------------------
8564 + * Local variables:
8565 + * c-file-style: "linux"
8568 Index: uml-2.6.7/arch/um/kernel/skas/mem_user.c
8569 ===================================================================
8570 --- uml-2.6.7.orig/arch/um/kernel/skas/mem_user.c 2004-07-16 19:36:25.158321816 +0300
8571 +++ uml-2.6.7/arch/um/kernel/skas/mem_user.c 2004-07-16 19:47:23.729203824 +0300
8573 #include <sys/mman.h>
8574 #include <sys/ptrace.h>
8575 #include "mem_user.h"
8579 #include "proc_mm.h"
8581 int r, int w, int x)
8583 struct proc_mm_op map;
8584 - struct mem_region *region;
8587 + int prot, n, phys_fd;
8589 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
8590 (x ? PROT_EXEC : 0);
8591 - region = phys_region(phys);
8592 + phys_fd = phys_mapping(phys, &offset);
8594 map = ((struct proc_mm_op) { .op = MM_MMAP,
8598 .flags = MAP_SHARED |
8601 - .offset = phys_offset(phys)
8605 n = os_write_file(fd, &map, sizeof(map));
8606 if(n != sizeof(map))
8607 - printk("map : /proc/mm map failed, errno = %d\n", errno);
8608 + printk("map : /proc/mm map failed, err = %d\n", -n);
8611 int unmap(int fd, void *addr, int len)
8613 { .addr = (unsigned long) addr,
8615 n = os_write_file(fd, &unmap, sizeof(unmap));
8616 - if((n != 0) && (n != sizeof(unmap)))
8618 + if(n != sizeof(unmap)) {
8629 .prot = prot } } } );
8631 n = os_write_file(fd, &protect, sizeof(protect));
8632 - if((n != 0) && (n != sizeof(protect))){
8633 + if(n != sizeof(protect)) {
8634 + if(n == 0) return(0);
8637 - panic("protect failed, errno = %d", errno);
8639 + panic("protect failed, err = %d", -n);
8647 Index: uml-2.6.7/arch/um/kernel/skas/include/ptrace-skas.h
8648 ===================================================================
8649 --- uml-2.6.7.orig/arch/um/kernel/skas/include/ptrace-skas.h 2004-07-16 19:36:04.873405592 +0300
8650 +++ uml-2.6.7/arch/um/kernel/skas/include/ptrace-skas.h 2004-07-16 19:47:24.724052584 +0300
8653 #ifdef UML_CONFIG_MODE_SKAS
8655 +/* syscall emulation path in ptrace */
8657 +#ifndef PTRACE_SYSEMU
8658 +#define PTRACE_SYSEMU 31
8661 +void set_using_sysemu(int value);
8662 +int get_using_sysemu(void);
8664 #include "skas_ptregs.h"
8666 #define HOST_FRAME_SIZE 17
8667 Index: uml-2.6.7/include/asm-um/archparam-i386.h
8668 ===================================================================
8669 --- uml-2.6.7.orig/include/asm-um/archparam-i386.h 2004-07-16 19:37:19.977987960 +0300
8670 +++ uml-2.6.7/include/asm-um/archparam-i386.h 2004-07-16 19:47:23.787195008 +0300
8673 - * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
8674 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
8675 * Licensed under the GPL
8679 pr_reg[16] = PT_REGS_SS(regs); \
8682 +#if 0 /* Turn this back on when UML has VSYSCALL working */
8683 +#define VSYSCALL_BASE (__fix_to_virt(FIX_VSYSCALL))
8685 +#define VSYSCALL_BASE 0
8688 +#define VSYSCALL_EHDR ((const struct elfhdr *) VSYSCALL_BASE)
8689 +#define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
8690 +extern void *__kernel_vsyscall;
8693 + * Architecture-neutral AT_ values in 0-17, leave some room
8694 + * for more of them, start the x86-specific ones at 32.
8696 +#define AT_SYSINFO 32
8697 +#define AT_SYSINFO_EHDR 33
8699 +#define ARCH_DLINFO \
8701 + NEW_AUX_ENT(AT_SYSINFO, VSYSCALL_ENTRY); \
8702 + NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE); \
8706 + * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
8707 + * extra segments containing the vsyscall DSO contents. Dumping its
8708 + * contents makes post-mortem fully interpretable later without matching up
8709 + * the same kernel and hardware config to see what PC values meant.
8710 + * Dumping its extra ELF program headers includes all the other information
8711 + * a debugger needs to easily find how the vsyscall DSO was being used.
8714 +#define ELF_CORE_EXTRA_PHDRS (VSYSCALL_EHDR->e_phnum)
8717 +#undef ELF_CORE_EXTRA_PHDRS
8720 +#define ELF_CORE_WRITE_EXTRA_PHDRS \
8722 + const struct elf_phdr *const vsyscall_phdrs = \
8723 + (const struct elf_phdr *) (VSYSCALL_BASE \
8724 + + VSYSCALL_EHDR->e_phoff); \
8726 + Elf32_Off ofs = 0; \
8727 + for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) { \
8728 + struct elf_phdr phdr = vsyscall_phdrs[i]; \
8729 + if (phdr.p_type == PT_LOAD) { \
8730 + ofs = phdr.p_offset = offset; \
8731 + offset += phdr.p_filesz; \
8734 + phdr.p_offset += ofs; \
8735 + phdr.p_paddr = 0; /* match other core phdrs */ \
8736 + DUMP_WRITE(&phdr, sizeof(phdr)); \
8739 +#define ELF_CORE_WRITE_EXTRA_DATA \
8741 + const struct elf_phdr *const vsyscall_phdrs = \
8742 + (const struct elf_phdr *) (VSYSCALL_BASE \
8743 + + VSYSCALL_EHDR->e_phoff); \
8745 + for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) { \
8746 + if (vsyscall_phdrs[i].p_type == PT_LOAD) \
8747 + DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr, \
8748 + vsyscall_phdrs[i].p_filesz); \
8753 +#undef ELF_CORE_WRITE_EXTRA_PHDRS
8754 +#undef ELF_CORE_WRITE_EXTRA_DATA
8756 +#define R_386_NONE 0
8758 +#define R_386_PC32 2
8759 +#define R_386_GOT32 3
8760 +#define R_386_PLT32 4
8761 +#define R_386_COPY 5
8762 +#define R_386_GLOB_DAT 6
8763 +#define R_386_JMP_SLOT 7
8764 +#define R_386_RELATIVE 8
8765 +#define R_386_GOTOFF 9
8766 +#define R_386_GOTPC 10
8767 +#define R_386_NUM 11
8769 /********* Bits for asm-um/delay.h **********/
8771 typedef unsigned long um_udelay_t;
8772 Index: uml-2.6.7/arch/um/kernel/skas/process_kern.c
8773 ===================================================================
8774 --- uml-2.6.7.orig/arch/um/kernel/skas/process_kern.c 2004-07-16 19:37:52.070109216 +0300
8775 +++ uml-2.6.7/arch/um/kernel/skas/process_kern.c 2004-07-16 19:47:24.725052432 +0300
8777 #include "linux/sched.h"
8778 #include "linux/slab.h"
8779 #include "linux/ptrace.h"
8780 +#include "linux/proc_fs.h"
8781 +#include "linux/file.h"
8782 +#include "linux/errno.h"
8783 +#include "linux/init.h"
8784 +#include "asm/uaccess.h"
8785 +#include "asm/atomic.h"
8786 #include "kern_util.h"
8787 #include "time_user.h"
8788 #include "signal_user.h"
8793 +#ifdef PTRACE_SYSEMU
8794 +static atomic_t using_sysemu;
8797 +void set_using_sysemu(int value)
8799 + atomic_set(&using_sysemu, value);
8802 +int get_using_sysemu(void)
8804 + return atomic_read(&using_sysemu);
8807 +int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data)
8809 + if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size) /*No overflow*/
8812 + return strlen(buf);
8815 +int proc_write_sysemu(struct file *file,const char *buf, unsigned long count,void *data)
8819 + if (copy_from_user(tmp, buf, 1))
8822 + if (tmp[0] == '0' || tmp[0] == '1')
8823 + set_using_sysemu(tmp[0] - '0');
8824 + return count; /*We use the first char, but pretend to write everything*/
8827 +int __init make_proc_sysemu(void)
8829 + struct proc_dir_entry *ent;
8831 + ent = create_proc_entry("sysemu", 00600, &proc_root);
8832 + ent->read_proc = proc_read_sysemu;
8833 + ent->write_proc = proc_write_sysemu;
8837 + printk("Failed to register /proc/sysemu\n");
8844 +late_initcall(make_proc_sysemu);
8846 int singlestepping_skas(void)
8848 int ret = current->ptrace & PT_DTRACE;
8849 @@ -61,11 +120,13 @@
8850 thread_wait(¤t->thread.mode.skas.switch_buf,
8851 current->thread.mode.skas.fork_buf);
8854 - schedule_tail(NULL);
8856 + if(current->thread.prev_sched != NULL)
8857 + schedule_tail(current->thread.prev_sched);
8858 current->thread.prev_sched = NULL;
8860 + /* The return value is 1 if the kernel thread execs a process,
8861 + * 0 if it just exits
8863 n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf);
8865 userspace(¤t->thread.regs.regs);
8866 @@ -93,11 +154,11 @@
8867 current->thread.mode.skas.fork_buf);
8871 + if(current->thread.prev_sched == NULL)
8874 schedule_tail(current->thread.prev_sched);
8876 current->thread.prev_sched = NULL;
8877 - unblock_signals();
8879 userspace(¤t->thread.regs.regs);
8883 void init_idle_skas(void)
8885 - cpu_tasks[current->thread_info->cpu].pid = os_getpid();
8886 + cpu_tasks[current_thread->cpu].pid = os_getpid();
8890 @@ -160,11 +221,11 @@
8892 int start_uml_skas(void)
8894 - start_userspace();
8895 + start_userspace(0);
8896 capture_signal_stack();
8899 init_new_thread_signals(1);
8902 init_task.thread.request.u.thread.proc = start_kernel_proc;
8903 init_task.thread.request.u.thread.arg = NULL;
8904 @@ -175,12 +236,14 @@
8906 int external_pid_skas(struct task_struct *task)
8908 - return(userspace_pid);
8909 +#warning Need to look up userspace_pid by cpu
8910 + return(userspace_pid[0]);
8913 int thread_pid_skas(struct task_struct *task)
8915 - return(userspace_pid);
8916 +#warning Need to look up userspace_pid by cpu
8917 + return(userspace_pid[0]);
8921 Index: uml-2.6.7/arch/um/kernel/helper.c
8922 ===================================================================
8923 --- uml-2.6.7.orig/arch/um/kernel/helper.c 2004-07-16 19:36:40.052057624 +0300
8924 +++ uml-2.6.7/arch/um/kernel/helper.c 2004-07-16 19:47:24.798041336 +0300
8931 #include <sys/signal.h>
8932 #include <sys/wait.h>
8934 #include "kern_util.h"
8935 +#include "user_util.h"
8938 struct helper_data {
8941 struct helper_data *data = arg;
8942 char **argv = data->argv;
8946 signal(SIGHUP, helper_hup);
8948 if(data->pre_exec != NULL)
8949 (*data->pre_exec)(data->pre_data);
8950 execvp(argv[0], argv);
8952 printk("execvp of '%s' failed - errno = %d\n", argv[0], errno);
8953 - write(data->fd, &errno, sizeof(errno));
8954 + os_write_file(data->fd, &errval, sizeof(errval));
8955 os_kill_process(os_getpid(), 0);
8959 if((stack_out != NULL) && (*stack_out != 0))
8961 else stack = alloc_stack(0, um_in_interrupt());
8962 - if(stack == 0) return(-ENOMEM);
8966 err = os_pipe(fds, 1, 0);
8968 - printk("run_helper : pipe failed, errno = %d\n", -err);
8971 + printk("run_helper : pipe failed, err = %d\n", -err);
8974 - if(fcntl(fds[1], F_SETFD, 1) != 0){
8975 - printk("run_helper : setting FD_CLOEXEC failed, errno = %d\n",
8979 + err = os_set_exec_close(fds[1], 1);
8981 + printk("run_helper : setting FD_CLOEXEC failed, err = %d\n",
8986 sp = stack + page_size() - sizeof(void *);
8988 pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
8990 printk("run_helper : clone failed, errno = %d\n", errno);
8996 - n = read(fds[0], &err, sizeof(err));
8998 + os_close_file(fds[1]);
8999 + n = os_read_file(fds[0], &err, sizeof(err));
9001 - printk("run_helper : read on pipe failed, errno = %d\n",
9004 + printk("run_helper : read on pipe failed, err = %d\n", -n);
9009 - waitpid(pid, NULL, 0);
9011 + CATCH_EINTR(n = waitpid(pid, NULL, 0));
9015 if(stack_out == NULL) free_stack(stack, 0);
9016 else *stack_out = stack;
9020 + os_kill_process(pid, 1);
9022 + os_close_file(fds[0]);
9023 + os_close_file(fds[1]);
9025 + free_stack(stack, 0);
9029 int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
9030 @@ -117,9 +133,11 @@
9032 if(stack_out == NULL){
9033 pid = waitpid(pid, &status, 0);
9036 printk("run_helper_thread - wait failed, errno = %d\n",
9041 if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
9042 printk("run_helper_thread - thread returned status "
9044 Index: uml-2.6.7/arch/um/drivers/fd.c
9045 ===================================================================
9046 --- uml-2.6.7.orig/arch/um/drivers/fd.c 2004-07-16 19:37:38.077236456 +0300
9047 +++ uml-2.6.7/arch/um/drivers/fd.c 2004-07-16 19:47:23.681211120 +0300
9049 printk("fd_init : couldn't parse file descriptor '%s'\n", str);
9052 - if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL);
9053 + data = um_kmalloc(sizeof(*data));
9054 + if(data == NULL) return(NULL);
9055 *data = ((struct fd_chan) { .fd = n,
9056 .raw = opts->raw });
9058 Index: uml-2.6.7/arch/um/include/kern_util.h
9059 ===================================================================
9060 --- uml-2.6.7.orig/arch/um/include/kern_util.h 2004-07-16 19:36:25.260306312 +0300
9061 +++ uml-2.6.7/arch/um/include/kern_util.h 2004-07-16 19:47:23.702207928 +0300
9063 extern void paging_init(void);
9064 extern void init_flush_vm(void);
9065 extern void *syscall_sp(void *t);
9066 -extern void syscall_trace(void);
9067 +extern void syscall_trace(union uml_pt_regs *regs, int entryexit);
9068 extern int hz(void);
9069 -extern void idle_timer(void);
9070 +extern void uml_idle_timer(void);
9071 extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
9072 extern int external_pid(void *t);
9073 -extern int pid_to_processor_id(int pid);
9074 extern void boot_timer_handler(int sig);
9075 extern void interrupt_end(void);
9076 extern void initial_thread_cb(void (*proc)(void *), void *arg);
9078 extern char *uml_strdup(char *string);
9079 extern void unprotect_kernel_mem(void);
9080 extern void protect_kernel_mem(void);
9081 -extern void set_kmem_end(unsigned long);
9082 extern void uml_cleanup(void);
9083 -extern int pid_to_processor_id(int pid);
9084 extern void set_current(void *t);
9085 extern void lock_signalled_task(void *t);
9086 extern void IPI_handler(int cpu);
9088 extern int clear_user_proc(void *buf, int size);
9089 extern int copy_to_user_proc(void *to, void *from, int size);
9090 extern int copy_from_user_proc(void *to, void *from, int size);
9091 +extern int strlen_user_proc(char *str);
9092 extern void bus_handler(int sig, union uml_pt_regs *regs);
9093 +extern void winch(int sig, union uml_pt_regs *regs);
9094 extern long execute_syscall(void *r);
9095 extern int smp_sigio_handler(void);
9096 extern void *get_current(void);
9098 extern void free_irq(unsigned int, void *);
9099 extern int um_in_interrupt(void);
9100 extern int cpu(void);
9101 +extern unsigned long long time_stamp(void);
9106 Index: uml-2.6.7/include/asm-um/sections.h
9107 ===================================================================
9108 --- uml-2.6.7.orig/include/asm-um/sections.h 2004-07-16 19:47:23.634218264 +0300
9109 +++ uml-2.6.7/include/asm-um/sections.h 2004-07-16 19:47:23.795193792 +0300
9111 +#ifndef _UM_SECTIONS_H
9112 +#define _UM_SECTIONS_H
9114 +/* nothing to see, move along */
9115 +#include <asm-generic/sections.h>
9118 Index: uml-2.6.7/include/asm-um/pgtable.h
9119 ===================================================================
9120 --- uml-2.6.7.orig/include/asm-um/pgtable.h 2004-07-16 19:37:51.945128216 +0300
9121 +++ uml-2.6.7/include/asm-um/pgtable.h 2004-07-16 19:47:23.793194096 +0300
9123 #include "asm/page.h"
9124 #include "asm/fixmap.h"
9126 -extern pgd_t swapper_pg_dir[1024];
9128 extern void *um_virt_to_phys(struct task_struct *task, unsigned long virt,
9132 #define pgd_ERROR(e) \
9133 printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
9135 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
9138 * pgd entries used up by user/kernel:
9141 * area for the same reason. ;)
9144 -extern unsigned long high_physmem;
9145 +extern unsigned long end_iomem;
9147 #define VMALLOC_OFFSET (__va_space)
9148 -#define VMALLOC_START (((unsigned long) high_physmem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
9149 +#define VMALLOC_START ((end_iomem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
9151 #ifdef CONFIG_HIGHMEM
9152 # define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
9155 #define _PAGE_PRESENT 0x001
9156 #define _PAGE_NEWPAGE 0x002
9157 -#define _PAGE_PROTNONE 0x004 /* If not present */
9158 -#define _PAGE_RW 0x008
9159 -#define _PAGE_USER 0x010
9160 -#define _PAGE_ACCESSED 0x020
9161 -#define _PAGE_DIRTY 0x040
9162 -#define _PAGE_NEWPROT 0x080
9163 +#define _PAGE_NEWPROT 0x004
9164 +#define _PAGE_FILE 0x008 /* set:pagecache unset:swap */
9165 +#define _PAGE_PROTNONE 0x010 /* If not present */
9166 +#define _PAGE_RW 0x020
9167 +#define _PAGE_USER 0x040
9168 +#define _PAGE_ACCESSED 0x080
9169 +#define _PAGE_DIRTY 0x100
9171 #define REGION_MASK 0xf0000000
9172 #define REGION_SHIFT 28
9175 #define BAD_PAGETABLE __bad_pagetable()
9176 #define BAD_PAGE __bad_page()
9177 -#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
9179 +#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
9181 /* number of bits that fit into a memory pointer */
9182 #define BITS_PER_PTR (8*sizeof(unsigned long))
9185 #define pte_clear(xp) do { pte_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
9187 -#define phys_region_index(x) (((x) & REGION_MASK) >> REGION_SHIFT)
9188 -#define pte_region_index(x) phys_region_index(pte_val(x))
9190 #define pmd_none(x) (!(pmd_val(x) & ~_PAGE_NEWPAGE))
9191 #define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
9192 #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
9193 @@ -188,19 +187,25 @@
9195 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
9197 -extern struct page *pte_mem_map(pte_t pte);
9198 -extern struct page *phys_mem_map(unsigned long phys);
9199 -extern unsigned long phys_to_pfn(unsigned long p);
9200 -extern unsigned long pfn_to_phys(unsigned long pfn);
9202 -#define pte_page(x) pfn_to_page(pte_pfn(x))
9203 -#define pte_address(x) (__va(pte_val(x) & PAGE_MASK))
9204 -#define mk_phys(a, r) ((a) + (r << REGION_SHIFT))
9205 -#define phys_addr(p) ((p) & ~REGION_MASK)
9206 -#define phys_page(p) (phys_mem_map(p) + ((phys_addr(p)) >> PAGE_SHIFT))
9207 +#define pte_page(pte) phys_to_page(pte_val(pte))
9208 +#define pmd_page(pmd) phys_to_page(pmd_val(pmd) & PAGE_MASK)
9210 #define pte_pfn(x) phys_to_pfn(pte_val(x))
9211 #define pfn_pte(pfn, prot) __pte(pfn_to_phys(pfn) | pgprot_val(prot))
9212 -#define pfn_pmd(pfn, prot) __pmd(pfn_to_phys(pfn) | pgprot_val(prot))
9214 +extern struct page *phys_to_page(const unsigned long phys);
9215 +extern struct page *__virt_to_page(const unsigned long virt);
9216 +#define virt_to_page(addr) __virt_to_page((const unsigned long) addr)
9219 + * Bits 0 through 3 are taken
9221 +#define PTE_FILE_MAX_BITS 28
9223 +#define pte_to_pgoff(pte) ((pte).pte_low >> 4)
9225 +#define pgoff_to_pte(off) \
9226 + ((pte_t) { ((off) << 4) + _PAGE_FILE })
9228 static inline pte_t pte_mknewprot(pte_t pte)
9230 @@ -235,6 +240,12 @@
9231 * The following only work if pte_present() is true.
9232 * Undefined behaviour if not..
9234 +static inline int pte_user(pte_t pte)
9236 + return((pte_val(pte) & _PAGE_USER) &&
9237 + !(pte_val(pte) & _PAGE_PROTNONE));
9240 static inline int pte_read(pte_t pte)
9242 return((pte_val(pte) & _PAGE_USER) &&
9243 @@ -252,6 +263,14 @@
9244 !(pte_val(pte) & _PAGE_PROTNONE));
9248 + * The following only works if pte_present() is not true.
9250 +static inline int pte_file(pte_t pte)
9252 + return (pte).pte_low & _PAGE_FILE;
9255 static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
9256 static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
9257 static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; }
9258 @@ -334,14 +353,7 @@
9259 * and a page entry and page directory to the page they refer to.
9262 -#define mk_pte(page, pgprot) \
9266 - pte_val(__pte) = page_to_phys(page) + pgprot_val(pgprot);\
9267 - if(pte_present(__pte)) pte_mknewprot(pte_mknewpage(__pte)); \
9270 +extern pte_t mk_pte(struct page *page, pgprot_t pgprot);
9272 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
9274 @@ -351,17 +363,27 @@
9277 #define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
9278 -#define pmd_page(pmd) (phys_mem_map(pmd_val(pmd) & PAGE_MASK) + \
9279 - ((phys_addr(pmd_val(pmd)) >> PAGE_SHIFT)))
9281 -/* to find an entry in a page-table-directory. */
9283 + * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
9285 + * this macro returns the index of the entry in the pgd page which would
9286 + * control the given virtual address
9288 #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
9290 -/* to find an entry in a page-table-directory */
9292 + * pgd_offset() returns a (pgd_t *)
9293 + * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
9295 #define pgd_offset(mm, address) \
9296 ((mm)->pgd + ((address) >> PGDIR_SHIFT))
9298 -/* to find an entry in a kernel page-table-directory */
9301 + * a shortcut which implies the use of the kernel's pgd, instead
9304 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
9306 #define pmd_index(address) \
9307 @@ -373,7 +395,12 @@
9308 return (pmd_t *) dir;
9311 -/* Find an entry in the third-level page table.. */
9313 + * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
9315 + * this macro returns the index of the entry in the pte page which would
9316 + * control the given virtual address
9318 #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
9319 #define pte_offset_kernel(dir, address) \
9320 ((pte_t *) pmd_page_kernel(*(dir)) + pte_index(address))
9321 @@ -387,11 +414,11 @@
9322 #define update_mmu_cache(vma,address,pte) do ; while (0)
9324 /* Encode and de-code a swap entry */
9325 -#define __swp_type(x) (((x).val >> 3) & 0x7f)
9326 -#define __swp_offset(x) ((x).val >> 10)
9327 +#define __swp_type(x) (((x).val >> 4) & 0x3f)
9328 +#define __swp_offset(x) ((x).val >> 11)
9330 #define __swp_entry(type, offset) \
9331 - ((swp_entry_t) { ((type) << 3) | ((offset) << 10) })
9332 + ((swp_entry_t) { ((type) << 4) | ((offset) << 11) })
9333 #define __pte_to_swp_entry(pte) \
9334 ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
9335 #define __swp_entry_to_pte(x) ((pte_t) { (x).val })
9336 Index: uml-2.6.7/arch/um/Kconfig_char
9337 ===================================================================
9338 --- uml-2.6.7.orig/arch/um/Kconfig_char 2004-07-16 19:36:33.679026472 +0300
9339 +++ uml-2.6.7/arch/um/Kconfig_char 2004-07-16 19:47:24.069152144 +0300
9340 @@ -108,11 +108,60 @@
9343 bool "Unix98 PTY support"
9345 -config UNIX98_PTY_COUNT
9346 - int "Maximum number of Unix98 PTYs in use (0-2048)"
9347 - depends on UNIX98_PTYS
9349 + A pseudo terminal (PTY) is a software device consisting of two
9350 + halves: a master and a slave. The slave device behaves identical to
9351 + a physical terminal; the master device is used by a process to
9352 + read data from and write data to the slave, thereby emulating a
9353 + terminal. Typical programs for the master side are telnet servers
9356 + Linux has traditionally used the BSD-like names /dev/ptyxx for
9357 + masters and /dev/ttyxx for slaves of pseudo terminals. This scheme
9358 + has a number of problems. The GNU C library glibc 2.1 and later,
9359 + however, supports the Unix98 naming standard: in order to acquire a
9360 + pseudo terminal, a process opens /dev/ptmx; the number of the pseudo
9361 + terminal is then made available to the process and the pseudo
9362 + terminal slave can be accessed as /dev/pts/<number>. What was
9363 + traditionally /dev/ttyp2 will then be /dev/pts/2, for example.
9365 + All modern Linux systems use the Unix98 ptys. Say Y unless
9366 + you're on an embedded system and want to conserve memory.
9369 + bool "Legacy (BSD) PTY support"
9372 + A pseudo terminal (PTY) is a software device consisting of two
9373 + halves: a master and a slave. The slave device behaves identical to
9374 + a physical terminal; the master device is used by a process to
9375 + read data from and write data to the slave, thereby emulating a
9376 + terminal. Typical programs for the master side are telnet servers
9379 + Linux has traditionally used the BSD-like names /dev/ptyxx
9380 + for masters and /dev/ttyxx for slaves of pseudo
9381 + terminals. This scheme has a number of problems, including
9382 + security. This option enables these legacy devices; on most
9383 + systems, it is safe to say N.
9386 +config LEGACY_PTY_COUNT
9387 + int "Maximum number of legacy PTY in use"
9388 + depends on LEGACY_PTYS
9391 + The maximum number of legacy PTYs that can be used at any one time.
9392 + The default is 256, and should be more than enough. Embedded
9393 + systems may want to reduce this to save memory.
9395 + When not in use, each legacy PTY occupies 12 bytes on 32-bit
9396 + architectures and 24 bytes on 64-bit architectures.
9398 +#config UNIX98_PTY_COUNT
9399 +# int "Maximum number of Unix98 PTYs in use (0-2048)"
9400 +# depends on UNIX98_PTYS
9404 bool "Watchdog Timer Support"
9405 Index: uml-2.6.7/arch/um/kernel/user_util.c
9406 ===================================================================
9407 --- uml-2.6.7.orig/arch/um/kernel/user_util.c 2004-07-16 19:36:07.233046872 +0300
9408 +++ uml-2.6.7/arch/um/kernel/user_util.c 2004-07-16 19:47:24.794041944 +0300
9416 #include <sys/mman.h>
9421 - if(((ret = waitpid(pid, &status, WUNTRACED)) < 0) ||
9422 + CATCH_EINTR(ret = waitpid(pid, &status, WUNTRACED));
9424 !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
9426 - if(errno == EINTR) continue;
9427 printk("wait failed, errno = %d\n",
9430 @@ -119,29 +118,36 @@
9434 -int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags)
9438 - pid = clone(fn, sp, flags, arg);
9439 - if(pid < 0) return(-1);
9440 - wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
9441 - ptrace(PTRACE_CONT, pid, 0, 0);
9445 -int raw(int fd, int complain)
9446 +int __raw(int fd, int complain, int now)
9452 + CATCH_EINTR(err = tcgetattr(fd, &tt));
9456 + printk("tcgetattr failed, errno = %d\n", errno);
9460 - tcgetattr(fd, &tt);
9462 - err = tcsetattr(fd, TCSANOW, &tt);
9463 - if((err < 0) && complain){
9464 - printk("tcsetattr failed, errno = %d\n", errno);
9471 + CATCH_EINTR(err = tcsetattr(fd, when, &tt));
9475 + printk("tcsetattr failed, errno = %d\n", errno);
9478 + /*XXX: tcsetattr could have applied only some changes
9479 + * (and cfmakeraw() is a set of changes) */
9483 Index: uml-2.6.7/arch/um/kernel/umid.c
9484 ===================================================================
9485 --- uml-2.6.7.orig/arch/um/kernel/umid.c 2004-07-16 19:37:31.857182048 +0300
9486 +++ uml-2.6.7/arch/um/kernel/umid.c 2004-07-16 19:47:23.756199720 +0300
9496 static int umid_is_random = 1;
9497 static int umid_inited = 0;
9499 -static int make_umid(void);
9500 +static int make_umid(int (*printer)(const char *fmt, ...));
9502 -static int __init set_umid(char *name, int is_random)
9503 +static int __init set_umid(char *name, int is_random,
9504 + int (*printer)(const char *fmt, ...))
9507 - printk("Unique machine name can't be set twice\n");
9508 + (*printer)("Unique machine name can't be set twice\n");
9512 if(strlen(name) > UMID_LEN - 1)
9513 - printk("Unique machine name is being truncated to %s "
9514 - "characters\n", UMID_LEN);
9515 + (*printer)("Unique machine name is being truncated to %s "
9516 + "characters\n", UMID_LEN);
9517 strlcpy(umid, name, sizeof(umid));
9519 umid_is_random = is_random;
9522 static int __init set_umid_arg(char *name, int *add)
9524 - return(set_umid(name, 0));
9525 + return(set_umid(name, 0, printf));
9528 __uml_setup("umid=", set_umid_arg,
9533 - if(!umid_inited && make_umid()) return(-1);
9534 + if(!umid_inited && make_umid(printk)) return(-1);
9536 n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
9540 char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
9541 char pid[sizeof("nnnnn\0")];
9545 if(umid_file_name("pid", file, sizeof(file))) return 0;
9547 fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))),
9550 - printk("Open of machine pid file \"%s\" failed - "
9551 - "errno = %d\n", file, -fd);
9552 + printf("Open of machine pid file \"%s\" failed - "
9553 + "err = %d\n", file, -fd);
9557 sprintf(pid, "%d\n", os_getpid());
9558 - if(write(fd, pid, strlen(pid)) != strlen(pid))
9559 - printk("Write of pid file failed - errno = %d\n", errno);
9561 + n = os_write_file(fd, pid, strlen(pid));
9562 + if(n != strlen(pid))
9563 + printf("Write of pid file failed - err = %d\n", -n);
9564 + os_close_file(fd);
9572 - if((directory = opendir(dir)) == NULL){
9573 + directory = opendir(dir);
9574 + if(directory == NULL){
9575 printk("actually_do_remove : couldn't open directory '%s', "
9576 "errno = %d\n", dir, errno);
9578 @@ -160,22 +162,24 @@
9580 char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
9581 char pid[sizeof("nnnnn\0")], *end;
9583 + int dead, fd, p, n;
9585 sprintf(file, "%s/pid", dir);
9587 - if((fd = os_open_file(file, of_read(OPENFLAGS()), 0)) < 0){
9588 + fd = os_open_file(file, of_read(OPENFLAGS()), 0);
9591 printk("not_dead_yet : couldn't open pid file '%s', "
9592 - "errno = %d\n", file, -fd);
9593 + "err = %d\n", file, -fd);
9599 - if(read(fd, pid, sizeof(pid)) < 0){
9600 + n = os_read_file(fd, pid, sizeof(pid));
9602 printk("not_dead_yet : couldn't read pid file '%s', "
9603 - "errno = %d\n", file, errno);
9604 + "err = %d\n", file, -n);
9607 p = strtoul(pid, &end, 0);
9609 if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
9610 uml_dir = malloc(strlen(name) + 1);
9611 if(uml_dir == NULL){
9612 - printk("Failed to malloc uml_dir - error = %d\n",
9613 + printf("Failed to malloc uml_dir - error = %d\n",
9618 char *home = getenv("HOME");
9621 - printk("make_uml_dir : no value in environment for "
9622 + printf("make_uml_dir : no value in environment for "
9626 @@ -232,57 +236,59 @@
9627 dir[len + 1] = '\0';
9630 - if((uml_dir = malloc(strlen(dir) + 1)) == NULL){
9631 + uml_dir = malloc(strlen(dir) + 1);
9632 + if(uml_dir == NULL){
9633 printf("make_uml_dir : malloc failed, errno = %d\n", errno);
9636 strcpy(uml_dir, dir);
9638 if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
9639 - printk("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
9640 + printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
9646 -static int __init make_umid(void)
9647 +static int __init make_umid(int (*printer)(const char *fmt, ...))
9650 char tmp[strlen(uml_dir) + UMID_LEN + 1];
9652 strlcpy(tmp, uml_dir, sizeof(tmp));
9656 strcat(tmp, "XXXXXX");
9659 - printk("make_umid - mkstemp failed, errno = %d\n",
9661 + (*printer)("make_umid - mkstemp failed, errno = %d\n",
9667 + os_close_file(fd);
9668 /* There's a nice tiny little race between this unlink and
9669 * the mkdir below. It'd be nice if there were a mkstemp
9673 - set_umid(&tmp[strlen(uml_dir)], 1);
9674 + set_umid(&tmp[strlen(uml_dir)], 1, printer);
9677 sprintf(tmp, "%s%s", uml_dir, umid);
9679 - if((err = mkdir(tmp, 0777)) < 0){
9680 + err = mkdir(tmp, 0777);
9682 if(errno == EEXIST){
9683 if(not_dead_yet(tmp)){
9684 - printk("umid '%s' is in use\n", umid);
9685 + (*printer)("umid '%s' is in use\n", umid);
9688 err = mkdir(tmp, 0777);
9692 - printk("Failed to create %s - errno = %d\n", umid, errno);
9693 + (*printer)("Failed to create %s - errno = %d\n", umid, errno);
9697 @@ -295,7 +301,13 @@
9700 __uml_postsetup(make_uml_dir);
9701 -__uml_postsetup(make_umid);
9703 +static int __init make_umid_setup(void)
9705 + return(make_umid(printf));
9708 +__uml_postsetup(make_umid_setup);
9709 __uml_postsetup(create_pid_file);
9712 Index: uml-2.6.7/include/linux/ghash.h
9713 ===================================================================
9714 --- uml-2.6.7.orig/include/linux/ghash.h 2004-07-16 19:47:23.863183456 +0300
9715 +++ uml-2.6.7/include/linux/ghash.h 2004-07-16 19:47:23.875181632 +0300
9718 + * include/linux/ghash.h -- generic hashing with fuzzy retrieval
9720 + * (C) 1997 Thomas Schoebel-Theuer
9722 + * The algorithms implemented here seem to be a completely new invention,
9723 + * and I'll publish the fundamentals in a paper.
9728 +/* HASHSIZE _must_ be a power of two!!! */
9731 +#define DEF_HASH_FUZZY_STRUCTS(NAME,HASHSIZE,TYPE) \
9733 +struct NAME##_table {\
9734 + TYPE * hashtable[HASHSIZE];\
9735 + TYPE * sorted_list;\
9739 +struct NAME##_ptrs {\
9740 + TYPE * next_hash;\
9741 + TYPE * prev_hash;\
9742 + TYPE * next_sorted;\
9743 + TYPE * prev_sorted;\
9746 +#define DEF_HASH_FUZZY(LINKAGE,NAME,HASHSIZE,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,KEYEQ,HASHFN)\
9748 +LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
9750 + int ix = HASHFN(elem->KEY);\
9751 + TYPE ** base = &tbl->hashtable[ix];\
9752 + TYPE * ptr = *base;\
9753 + TYPE * prev = NULL;\
9755 + tbl->nr_entries++;\
9756 + while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\
9757 + base = &ptr->PTRS.next_hash;\
9761 + elem->PTRS.next_hash = ptr;\
9762 + elem->PTRS.prev_hash = prev;\
9764 + ptr->PTRS.prev_hash = elem;\
9770 + ptr = tbl->sorted_list;\
9773 + prev = ptr->PTRS.prev_sorted;\
9776 + TYPE * next = ptr->PTRS.next_hash;\
9777 + if(next && KEYCMP(next->KEY, elem->KEY)) {\
9780 + } else if(KEYCMP(ptr->KEY, elem->KEY)) {\
9782 + ptr = ptr->PTRS.next_sorted;\
9786 + elem->PTRS.next_sorted = ptr;\
9787 + elem->PTRS.prev_sorted = prev;\
9789 + ptr->PTRS.prev_sorted = elem;\
9792 + prev->PTRS.next_sorted = elem;\
9794 + tbl->sorted_list = elem;\
9798 +LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
9800 + TYPE * next = elem->PTRS.next_hash;\
9801 + TYPE * prev = elem->PTRS.prev_hash;\
9803 + tbl->nr_entries--;\
9805 + next->PTRS.prev_hash = prev;\
9807 + prev->PTRS.next_hash = next;\
9809 + int ix = HASHFN(elem->KEY);\
9810 + tbl->hashtable[ix] = next;\
9813 + next = elem->PTRS.next_sorted;\
9814 + prev = elem->PTRS.prev_sorted;\
9816 + next->PTRS.prev_sorted = prev;\
9818 + prev->PTRS.next_sorted = next;\
9820 + tbl->sorted_list = next;\
9823 +LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
9825 + int ix = hashfn(pos);\
9826 + TYPE * ptr = tbl->hashtable[ix];\
9827 + while(ptr && KEYCMP(ptr->KEY, pos))\
9828 + ptr = ptr->PTRS.next_hash;\
9829 + if(ptr && !KEYEQ(ptr->KEY, pos))\
9834 +LINKAGE TYPE * find_##NAME##_hash_fuzzy(struct NAME##_table * tbl, KEYTYPE pos)\
9841 + ptr = tbl->sorted_list;\
9842 + if(!ptr || KEYCMP(pos, ptr->KEY))\
9844 + ix = HASHFN(pos);\
9845 + offset = HASHSIZE;\
9848 + next = tbl->hashtable[(ix+offset) & ((HASHSIZE)-1)];\
9849 + if(next && (KEYCMP(next->KEY, pos) || KEYEQ(next->KEY, pos))\
9850 + && KEYCMP(ptr->KEY, next->KEY))\
9855 + next = ptr->PTRS.next_hash;\
9857 + if(KEYCMP(next->KEY, pos)) {\
9862 + next = ptr->PTRS.next_sorted;\
9863 + if(next && KEYCMP(next->KEY, pos)) {\
9872 +/* LINKAGE - empty or "static", depending on whether you want the definitions to
9873 + * be public or not
9874 + * NAME - a string to stick in names to make this hash table type distinct from
9876 + * HASHSIZE - number of buckets
9877 + * TYPE - type of data contained in the buckets - must be a structure, one
9878 + * field is of type NAME_ptrs, another is the hash key
9879 + * PTRS - TYPE must contain a field of type NAME_ptrs, PTRS is the name of that
9881 + * KEYTYPE - type of the key field within TYPE
9882 + * KEY - name of the key field within TYPE
9883 + * KEYCMP - pointer to function that compares KEYTYPEs to each other - the
9884 + * prototype is int KEYCMP(KEYTYPE, KEYTYPE), it returns zero for equal,
9885 + * non-zero for not equal
9886 + * HASHFN - the hash function - the prototype is int HASHFN(KEYTYPE),
9887 + * it returns a number in the range 0 ... HASHSIZE - 1
9888 + * Call DEF_HASH_STRUCTS, define your hash table as a NAME_table, then call
9892 +#define DEF_HASH_STRUCTS(NAME,HASHSIZE,TYPE) \
9894 +struct NAME##_table {\
9895 + TYPE * hashtable[HASHSIZE];\
9899 +struct NAME##_ptrs {\
9900 + TYPE * next_hash;\
9901 + TYPE * prev_hash;\
9904 +#define DEF_HASH(LINKAGE,NAME,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,HASHFN)\
9906 +LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
9908 + int ix = HASHFN(elem->KEY);\
9909 + TYPE ** base = &tbl->hashtable[ix];\
9910 + TYPE * ptr = *base;\
9911 + TYPE * prev = NULL;\
9913 + tbl->nr_entries++;\
9914 + while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\
9915 + base = &ptr->PTRS.next_hash;\
9919 + elem->PTRS.next_hash = ptr;\
9920 + elem->PTRS.prev_hash = prev;\
9922 + ptr->PTRS.prev_hash = elem;\
9927 +LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
9929 + TYPE * next = elem->PTRS.next_hash;\
9930 + TYPE * prev = elem->PTRS.prev_hash;\
9932 + tbl->nr_entries--;\
9934 + next->PTRS.prev_hash = prev;\
9936 + prev->PTRS.next_hash = next;\
9938 + int ix = HASHFN(elem->KEY);\
9939 + tbl->hashtable[ix] = next;\
9943 +LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
9945 + int ix = HASHFN(pos);\
9946 + TYPE * ptr = tbl->hashtable[ix];\
9947 + while(ptr && KEYCMP(ptr->KEY, pos))\
9948 + ptr = ptr->PTRS.next_hash;\
9953 Index: uml-2.6.7/arch/um/kernel/tt/include/mode.h
9954 ===================================================================
9955 --- uml-2.6.7.orig/arch/um/kernel/tt/include/mode.h 2004-07-16 19:36:59.998025376 +0300
9956 +++ uml-2.6.7/arch/um/kernel/tt/include/mode.h 2004-07-16 19:47:23.743201696 +0300
9959 #include "sysdep/ptrace.h"
9961 +enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
9963 extern int tracing_pid;
9965 extern int tracer(int (*init_proc)(void *), void *sp);
9966 Index: uml-2.6.7/arch/um/include/os.h
9967 ===================================================================
9968 --- uml-2.6.7.orig/arch/um/include/os.h 2004-07-16 19:36:10.807503472 +0300
9969 +++ uml-2.6.7/arch/um/include/os.h 2004-07-16 19:47:23.705207472 +0300
9971 #define OS_TYPE_FIFO 6
9972 #define OS_TYPE_SOCK 7
9974 +/* os_access() flags */
9975 +#define OS_ACC_F_OK 0 /* Test for existence. */
9976 +#define OS_ACC_X_OK 1 /* Test for execute permission. */
9977 +#define OS_ACC_W_OK 2 /* Test for write permission. */
9978 +#define OS_ACC_R_OK 4 /* Test for read permission. */
9979 +#define OS_ACC_RW_OK (OS_ACC_W_OK | OS_ACC_R_OK) /* Test for RW permission */
9982 + * types taken from stat_file() in hostfs_user.c
9983 + * (if they are wrong here, they are wrong there...).
9986 + int ust_dev; /* device */
9987 + unsigned long long ust_ino; /* inode */
9988 + int ust_mode; /* protection */
9989 + int ust_nlink; /* number of hard links */
9990 + int ust_uid; /* user ID of owner */
9991 + int ust_gid; /* group ID of owner */
9992 + unsigned long long ust_size; /* total size, in bytes */
9993 + int ust_blksize; /* blocksize for filesystem I/O */
9994 + unsigned long long ust_blocks; /* number of blocks allocated */
9995 + unsigned long ust_atime; /* time of last access */
9996 + unsigned long ust_mtime; /* time of last modification */
9997 + unsigned long ust_ctime; /* time of last change */
10001 unsigned int r : 1;
10002 unsigned int w : 1;
10003 @@ -84,29 +110,47 @@
10009 static inline struct openflags of_cloexec(struct openflags flags)
10015 +extern int os_stat_file(const char *file_name, struct uml_stat *buf);
10016 +extern int os_stat_fd(const int fd, struct uml_stat *buf);
10017 +extern int os_access(const char *file, int mode);
10018 +extern void os_print_error(int error, const char* str);
10019 +extern int os_get_exec_close(int fd, int *close_on_exec);
10020 +extern int os_set_exec_close(int fd, int close_on_exec);
10021 +extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg);
10022 +extern int os_window_size(int fd, int *rows, int *cols);
10023 +extern int os_new_tty_pgrp(int fd, int pid);
10024 +extern int os_get_ifname(int fd, char *namebuf);
10025 +extern int os_set_slip(int fd);
10026 +extern int os_set_owner(int fd, int pid);
10027 +extern int os_sigio_async(int master, int slave);
10028 +extern int os_mode_fd(int fd, int mode);
10030 extern int os_seek_file(int fd, __u64 offset);
10031 extern int os_open_file(char *file, struct openflags flags, int mode);
10032 extern int os_read_file(int fd, void *buf, int len);
10033 -extern int os_write_file(int fd, void *buf, int count);
10034 +extern int os_write_file(int fd, const void *buf, int count);
10035 extern int os_file_size(char *file, long long *size_out);
10036 +extern int os_file_modtime(char *file, unsigned long *modtime);
10037 extern int os_pipe(int *fd, int stream, int close_on_exec);
10038 extern int os_set_fd_async(int fd, int owner);
10039 extern int os_set_fd_block(int fd, int blocking);
10040 extern int os_accept_connection(int fd);
10041 +extern int os_create_unix_socket(char *file, int len, int close_on_exec);
10042 extern int os_shutdown_socket(int fd, int r, int w);
10043 extern void os_close_file(int fd);
10044 extern int os_rcv_fd(int fd, int *helper_pid_out);
10045 -extern int create_unix_socket(char *file, int len);
10046 +extern int create_unix_socket(char *file, int len, int close_on_exec);
10047 extern int os_connect_socket(char *name);
10048 extern int os_file_type(char *file);
10049 extern int os_file_mode(char *file, struct openflags *mode_out);
10050 +extern int os_lock_file(int fd, int excl);
10052 extern unsigned long os_process_pc(int pid);
10053 extern int os_process_parent(int pid);
10054 @@ -115,11 +159,12 @@
10055 extern void os_usr1_process(int pid);
10056 extern int os_getpid(void);
10058 -extern int os_map_memory(void *virt, int fd, unsigned long off,
10059 +extern int os_map_memory(void *virt, int fd, unsigned long long off,
10060 unsigned long len, int r, int w, int x);
10061 extern int os_protect_memory(void *addr, unsigned long len,
10062 int r, int w, int x);
10063 extern int os_unmap_memory(void *addr, int len);
10064 +extern void os_flush_stdout(void);
10068 Index: uml-2.6.7/arch/um/kernel/tt/exec_user.c
10069 ===================================================================
10070 --- uml-2.6.7.orig/arch/um/kernel/tt/exec_user.c 2004-07-16 19:37:20.241947832 +0300
10071 +++ uml-2.6.7/arch/um/kernel/tt/exec_user.c 2004-07-16 19:47:24.799041184 +0300
10072 @@ -19,13 +19,18 @@
10073 void do_exec(int old_pid, int new_pid)
10075 unsigned long regs[FRAME_SIZE];
10078 if((ptrace(PTRACE_ATTACH, new_pid, 0, 0) < 0) ||
10079 - (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0) ||
10080 - (waitpid(new_pid, 0, WUNTRACED) < 0))
10081 + (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0))
10082 tracer_panic("do_exec failed to attach proc - errno = %d",
10085 + CATCH_EINTR(err = waitpid(new_pid, 0, WUNTRACED));
10087 + tracer_panic("do_exec failed to attach proc in waitpid - errno = %d",
10090 if(ptrace_getregs(old_pid, regs) < 0)
10091 tracer_panic("do_exec failed to get registers - errno = %d",
10093 Index: uml-2.6.7/include/asm-um/timex.h
10094 ===================================================================
10095 --- uml-2.6.7.orig/include/asm-um/timex.h 2004-07-16 19:36:59.398116576 +0300
10096 +++ uml-2.6.7/include/asm-um/timex.h 2004-07-16 19:47:23.803192576 +0300
10098 #ifndef __UM_TIMEX_H
10099 #define __UM_TIMEX_H
10101 -#include "linux/time.h"
10103 typedef unsigned long cycles_t;
10105 #define cacheflush_time (0)
10106 Index: uml-2.6.7/arch/um/kernel/skas/include/skas.h
10107 ===================================================================
10108 --- uml-2.6.7.orig/arch/um/kernel/skas/include/skas.h 2004-07-16 19:36:19.759142616 +0300
10109 +++ uml-2.6.7/arch/um/kernel/skas/include/skas.h 2004-07-16 19:47:23.727204128 +0300
10112 #include "sysdep/ptrace.h"
10114 -extern int userspace_pid;
10115 +extern int userspace_pid[];
10117 extern void switch_threads(void *me, void *next);
10118 extern void thread_wait(void *sw, void *fb);
10120 extern int new_mm(int from);
10121 extern void save_registers(union uml_pt_regs *regs);
10122 extern void restore_registers(union uml_pt_regs *regs);
10123 -extern void start_userspace(void);
10124 +extern void start_userspace(int cpu);
10125 extern void init_registers(int pid);
10128 Index: uml-2.6.7/arch/um/drivers/mmapper_kern.c
10129 ===================================================================
10130 --- uml-2.6.7.orig/arch/um/drivers/mmapper_kern.c 2004-07-16 19:36:04.585449368 +0300
10131 +++ uml-2.6.7/arch/um/drivers/mmapper_kern.c 2004-07-16 19:47:23.688210056 +0300
10132 @@ -120,7 +120,10 @@
10133 printk(KERN_INFO "Mapper v0.1\n");
10135 v_buf = (char *) find_iomem("mmapper", &mmapper_size);
10136 - if(mmapper_size == 0) return(0);
10137 + if(mmapper_size == 0){
10138 + printk(KERN_ERR "mmapper_init - find_iomem failed\n");
10142 p_buf = __pa(v_buf);
10144 Index: uml-2.6.7/arch/um/os-Linux/process.c
10145 ===================================================================
10146 --- uml-2.6.7.orig/arch/um/os-Linux/process.c 2004-07-16 19:36:02.092828304 +0300
10147 +++ uml-2.6.7/arch/um/os-Linux/process.c 2004-07-16 19:47:24.802040728 +0300
10150 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
10151 + * Copyright (C) 2002 Jeff Dike (jdike@addtoit.com)
10152 * Licensed under the GPL
10158 #include <signal.h>
10159 +#include <linux/unistd.h>
10160 #include <sys/mman.h>
10161 #include <sys/wait.h>
10164 +#include "user_util.h"
10166 +#define ARBITRARY_ADDR -1
10167 +#define FAILURE_PID -1
10169 unsigned long os_process_pc(int pid)
10171 char proc_stat[sizeof("/proc/#####/stat\0")], buf[256];
10176 sprintf(proc_stat, "/proc/%d/stat", pid);
10177 fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0);
10179 - printk("os_process_pc - couldn't open '%s', errno = %d\n",
10180 - proc_stat, errno);
10182 + printk("os_process_pc - couldn't open '%s', err = %d\n",
10184 + return(ARBITRARY_ADDR);
10186 - if(read(fd, buf, sizeof(buf)) < 0){
10187 - printk("os_process_pc - couldn't read '%s', errno = %d\n",
10188 - proc_stat, errno);
10191 + err = os_read_file(fd, buf, sizeof(buf));
10193 + printk("os_process_pc - couldn't read '%s', err = %d\n",
10194 + proc_stat, -err);
10195 + os_close_file(fd);
10196 + return(ARBITRARY_ADDR);
10200 + os_close_file(fd);
10201 + pc = ARBITRARY_ADDR;
10202 if(sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*d %*d %*d "
10203 "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
10204 "%*d %*d %*d %*d %ld", &pc) != 1){
10205 @@ -52,22 +58,23 @@
10206 snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
10207 fd = os_open_file(stat, of_read(OPENFLAGS()), 0);
10209 - printk("Couldn't open '%s', errno = %d\n", stat, -fd);
10211 + printk("Couldn't open '%s', err = %d\n", stat, -fd);
10212 + return(FAILURE_PID);
10215 - n = read(fd, data, sizeof(data));
10217 + n = os_read_file(fd, data, sizeof(data));
10218 + os_close_file(fd);
10221 - printk("Couldn't read '%s', errno = %d\n", stat);
10223 + printk("Couldn't read '%s', err = %d\n", stat, -n);
10224 + return(FAILURE_PID);
10228 + parent = FAILURE_PID;
10229 /* XXX This will break if there is a space in the command */
10230 n = sscanf(data, "%*d %*s %*c %d", &parent);
10231 - if(n != 1) printk("Failed to scan '%s'\n", data);
10233 + printk("Failed to scan '%s'\n", data);
10237 @@ -81,13 +88,17 @@
10239 kill(pid, SIGKILL);
10241 - waitpid(pid, NULL, 0);
10242 + CATCH_EINTR(waitpid(pid, NULL, 0));
10246 void os_usr1_process(int pid)
10249 + syscall(__NR_tkill, pid, SIGUSR1);
10251 kill(pid, SIGUSR1);
10255 int os_getpid(void)
10260 -int os_map_memory(void *virt, int fd, unsigned long off, unsigned long len,
10261 +int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
10262 int r, int w, int x)
10265 @@ -104,8 +115,8 @@
10266 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
10267 (x ? PROT_EXEC : 0);
10269 - loc = mmap((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
10271 + loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
10273 if(loc == MAP_FAILED)
10276 @@ -126,7 +137,8 @@
10279 err = munmap(addr, len);
10280 - if(err < 0) return(-errno);
10286 Index: uml-2.6.7/arch/um/include/mem_user.h
10287 ===================================================================
10288 --- uml-2.6.7.orig/arch/um/include/mem_user.h 2004-07-16 19:37:02.661620448 +0300
10289 +++ uml-2.6.7/arch/um/include/mem_user.h 2004-07-16 19:47:23.704207624 +0300
10290 @@ -32,43 +32,38 @@
10291 #ifndef _MEM_USER_H
10292 #define _MEM_USER_H
10294 -struct mem_region {
10295 +struct iomem_region {
10296 + struct iomem_region *next;
10298 - unsigned long start_pfn;
10299 - unsigned long start;
10300 - unsigned long len;
10304 + unsigned long phys;
10305 + unsigned long virt;
10308 -extern struct mem_region *regions[];
10309 -extern struct mem_region physmem_region;
10310 +extern struct iomem_region *iomem_regions;
10311 +extern int iomem_size;
10313 #define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
10315 extern unsigned long host_task_size;
10316 extern unsigned long task_size;
10318 +extern void check_devanon(void);
10319 extern int init_mem_user(void);
10320 extern int create_mem_file(unsigned long len);
10321 -extern void setup_range(int fd, char *driver, unsigned long start,
10322 - unsigned long pfn, unsigned long total, int need_vm,
10323 - struct mem_region *region, void *reserved);
10324 extern void setup_memory(void *entry);
10325 extern unsigned long find_iomem(char *driver, unsigned long *len_out);
10326 -extern int init_maps(struct mem_region *region);
10327 -extern int nregions(void);
10328 -extern int reserve_vm(unsigned long start, unsigned long end, void *e);
10329 +extern int init_maps(unsigned long physmem, unsigned long iomem,
10330 + unsigned long highmem);
10331 extern unsigned long get_vm(unsigned long len);
10332 extern void setup_physmem(unsigned long start, unsigned long usable,
10333 - unsigned long len);
10334 -extern int setup_region(struct mem_region *region, void *entry);
10335 + unsigned long len, unsigned long highmem);
10336 extern void add_iomem(char *name, int fd, unsigned long size);
10337 -extern struct mem_region *phys_region(unsigned long phys);
10338 extern unsigned long phys_offset(unsigned long phys);
10339 extern void unmap_physmem(void);
10340 -extern int map_memory(unsigned long virt, unsigned long phys,
10341 - unsigned long len, int r, int w, int x);
10342 +extern void map_memory(unsigned long virt, unsigned long phys,
10343 + unsigned long len, int r, int w, int x);
10344 extern int protect_memory(unsigned long addr, unsigned long len,
10345 int r, int w, int x, int must_succeed);
10346 extern unsigned long get_kmem_end(void);
10347 Index: uml-2.6.7/arch/um/drivers/mcast_user.c
10348 ===================================================================
10349 --- uml-2.6.7.orig/arch/um/drivers/mcast_user.c 2004-07-16 19:36:45.956160064 +0300
10350 +++ uml-2.6.7/arch/um/drivers/mcast_user.c 2004-07-16 19:47:23.686210360 +0300
10352 #include "kern_util.h"
10353 #include "user_util.h"
10357 #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
10363 - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
10364 + fd = socket(AF_INET, SOCK_DGRAM, 0);
10366 printk("mcast_open : data socket failed, errno = %d\n",
10370 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
10371 printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
10374 + os_close_file(fd);
10379 sizeof(pri->ttl)) < 0) {
10380 printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
10383 + os_close_file(fd);
10388 if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
10389 printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
10392 + os_close_file(fd);
10397 /* bind socket to mcast address */
10398 if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
10399 printk("mcast_open : data bind failed, errno = %d\n", errno);
10401 + os_close_file(fd);
10405 @@ -115,7 +117,7 @@
10406 "interface on the host.\n");
10407 printk("eth0 should be configured in order to use the "
10408 "multicast transport.\n");
10410 + os_close_file(fd);
10414 @@ -137,7 +139,7 @@
10419 + os_close_file(fd);
10422 int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
10423 Index: uml-2.6.7/arch/um/drivers/slirp_user.c
10424 ===================================================================
10425 --- uml-2.6.7.orig/arch/um/drivers/slirp_user.c 2004-07-16 19:37:02.720611480 +0300
10426 +++ uml-2.6.7/arch/um/drivers/slirp_user.c 2004-07-16 19:47:24.797041488 +0300
10428 #include <stddef.h>
10430 #include <string.h>
10431 -#include <sys/fcntl.h>
10432 -#include <sys/errno.h>
10433 +#include <errno.h>
10434 #include <sys/wait.h>
10435 #include <sys/signal.h>
10436 #include "user_util.h"
10437 @@ -48,15 +47,15 @@
10443 +/* XXX This is just a trivial wrapper around os_pipe */
10444 static int slirp_datachan(int *mfd, int *sfd)
10448 err = os_pipe(fds, 1, 1);
10450 - printk("slirp_datachan: Failed to open pipe, errno = %d\n",
10453 + printk("slirp_datachan: Failed to open pipe, err = %d\n", -err);
10458 pid = slirp_tramp(pri->argw.argv, sfd);
10461 - printk("slirp_tramp failed - errno = %d\n", pid);
10462 + printk("slirp_tramp failed - errno = %d\n", -pid);
10463 os_close_file(sfd);
10464 os_close_file(mfd);
10467 struct slirp_data *pri = data;
10471 - close(pri->slave);
10472 + os_close_file(fd);
10473 + os_close_file(pri->slave);
10477 @@ -114,13 +113,13 @@
10481 - err = waitpid(pri->pid, &status, WNOHANG);
10483 + CATCH_EINTR(err = waitpid(pri->pid, &status, WNOHANG));
10485 printk("slirp_close: waitpid returned %d\n", errno);
10491 printk("slirp_close: process %d has not exited\n");
10494 Index: uml-2.6.7/arch/um/kernel/tempfile.c
10495 ===================================================================
10496 --- uml-2.6.7.orig/arch/um/kernel/tempfile.c 2004-07-16 19:36:48.252810920 +0300
10497 +++ uml-2.6.7/arch/um/kernel/tempfile.c 2004-07-16 19:47:23.740202152 +0300
10500 if((dir == NULL) || (*dir == '\0'))
10503 tempdir = malloc(strlen(dir) + 2);
10504 if(tempdir == NULL){
10505 fprintf(stderr, "Failed to malloc tempdir, "
10509 strcat(tempname, template);
10510 - if((fd = mkstemp(tempname)) < 0){
10511 + fd = mkstemp(tempname);
10513 fprintf(stderr, "open - cannot create %s: %s\n", tempname,
10520 - if((*out_tempname = strdup(tempname)) == NULL){
10521 + *out_tempname = strdup(tempname);
10522 + if(*out_tempname == NULL){
10526 Index: uml-2.6.7/arch/um/sys-i386/util/Makefile
10527 ===================================================================
10528 --- uml-2.6.7.orig/arch/um/sys-i386/util/Makefile 2004-07-16 19:37:40.976795656 +0300
10529 +++ uml-2.6.7/arch/um/sys-i386/util/Makefile 2004-07-16 19:47:23.773197136 +0300
10531 +host-progs := mk_sc mk_thread
10532 +always := $(host-progs)
10534 -host-progs := mk_sc
10535 -always := $(host-progs) mk_thread
10536 -targets := mk_thread_kern.o mk_thread_user.o
10537 +mk_thread-objs := mk_thread_kern.o mk_thread_user.o
10539 -mk_sc-objs := mk_sc.o
10541 -$(obj)/mk_thread : $(obj)/mk_thread_kern.o $(obj)/mk_thread_user.o
10542 - $(CC) $(CFLAGS) -o $@ $^
10544 -$(obj)/mk_thread_user.o : $(src)/mk_thread_user.c
10545 - $(CC) $(USER_CFLAGS) -c -o $@ $<
10546 +HOSTCFLAGS_mk_thread_kern.o := $(CFLAGS) $(CPPFLAGS)
10547 +HOSTCFLAGS_mk_thread_user.o := $(USER_CFLAGS)
10550 $(RM) -f $(build-targets)
10551 Index: uml-2.6.7/arch/um/kernel/tt/tracer.c
10552 ===================================================================
10553 --- uml-2.6.7.orig/arch/um/kernel/tt/tracer.c 2004-07-16 19:35:55.561821168 +0300
10554 +++ uml-2.6.7/arch/um/kernel/tt/tracer.c 2004-07-16 19:47:24.801040880 +0300
10555 @@ -39,16 +39,17 @@
10558 register_winch_irq(tracer_winch[0], fd, -1, data);
10563 static void tracer_winch_handler(int sig)
10568 - if(write(tracer_winch[1], &c, sizeof(c)) != sizeof(c))
10569 - printk("tracer_winch_handler - write failed, errno = %d\n",
10571 + n = os_write_file(tracer_winch[1], &c, sizeof(c));
10572 + if(n != sizeof(c))
10573 + printk("tracer_winch_handler - write failed, err = %d\n", -n);
10576 /* Called only by the tracing thread during initialization */
10580 err = os_pipe(tracer_winch, 1, 1);
10582 - printk("setup_tracer_winch : os_pipe failed, errno = %d\n",
10585 + printk("setup_tracer_winch : os_pipe failed, err = %d\n", -err);
10588 signal(SIGWINCH, tracer_winch_handler);
10589 @@ -130,8 +130,8 @@
10591 if(ptrace(PTRACE_CONT, pid, 0, sig) < 0)
10592 tracer_panic("sleeping_process_signal : Failed to "
10593 - "continue pid %d, errno = %d\n", pid,
10595 + "continue pid %d, signal = %d, "
10596 + "errno = %d\n", pid, sig, errno);
10599 /* This happens when the debugger (e.g. strace) is doing system call
10600 @@ -145,7 +145,7 @@
10601 if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
10602 tracer_panic("sleeping_process_signal : Failed to "
10603 "PTRACE_SYSCALL pid %d, errno = %d\n",
10609 @@ -192,7 +192,7 @@
10610 printf("tracing thread pid = %d\n", tracing_pid);
10612 pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc);
10613 - n = waitpid(pid, &status, WUNTRACED);
10614 + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
10616 printf("waitpid on idle thread failed, errno = %d\n", errno);
10618 @@ -218,7 +218,7 @@
10619 err = attach(debugger_parent);
10621 printf("Failed to attach debugger parent %d, "
10622 - "errno = %d\n", debugger_parent, err);
10623 + "errno = %d\n", debugger_parent, -err);
10624 debugger_parent = -1;
10627 @@ -233,7 +233,8 @@
10629 set_cmdline("(tracing thread)");
10631 - if((pid = waitpid(-1, &status, WUNTRACED)) <= 0){
10632 + CATCH_EINTR(pid = waitpid(-1, &status, WUNTRACED));
10634 if(errno != ECHILD){
10635 printf("wait failed - errno = %d\n", errno);
10637 @@ -401,7 +402,7 @@
10639 if(!strcmp(line, "go")) debug_stop = 0;
10640 else if(!strcmp(line, "parent")) debug_parent = 1;
10641 - else printk("Unknown debug option : '%s'\n", line);
10642 + else printf("Unknown debug option : '%s'\n", line);
10646 Index: uml-2.6.7/arch/um/drivers/Makefile
10647 ===================================================================
10648 --- uml-2.6.7.orig/arch/um/drivers/Makefile 2004-07-16 19:36:51.389334096 +0300
10649 +++ uml-2.6.7/arch/um/drivers/Makefile 2004-07-16 19:47:24.526082680 +0300
10652 -# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
10653 +# Copyright (C) 2000, 2002, 2003 Jeff Dike (jdike@karaya.com)
10654 # Licensed under the GPL
10658 #pcap-objs := pcap_kern.o pcap_user.o $(PCAP)
10659 net-objs := net_kern.o net_user.o
10660 mconsole-objs := mconsole_kern.o mconsole_user.o
10661 -hostaudio-objs := hostaudio_kern.o hostaudio_user.o
10662 +hostaudio-objs := hostaudio_kern.o
10663 ubd-objs := ubd_kern.o ubd_user.o
10664 port-objs := port_kern.o port_user.o
10665 harddog-objs := harddog_kern.o harddog_user.o
10667 obj-$(CONFIG_TTY_CHAN) += tty.o
10668 obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
10669 obj-$(CONFIG_UML_WATCHDOG) += harddog.o
10670 +obj-$(CONFIG_BLK_DEV_COW) += cow_kern.o
10671 +obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
10673 obj-y += stdio_console.o $(CHAN_OBJS)
10677 USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \
10678 null.o pty.o tty.o xterm.o
10679 -USER_OBJS := $(foreach file,$(USER_OBJS),arch/um/drivers/$(file))
10680 +USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
10682 $(USER_OBJS) : %.o: %.c
10683 $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
10693 -archmrproper: clean
10695 Index: uml-2.6.7/arch/um/kernel/tt/uaccess.c
10696 ===================================================================
10697 --- uml-2.6.7.orig/arch/um/kernel/tt/uaccess.c 2004-07-16 19:47:23.625219632 +0300
10698 +++ uml-2.6.7/arch/um/kernel/tt/uaccess.c 2004-07-16 19:47:23.751200480 +0300
10701 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
10702 + * Licensed under the GPL
10705 +#include "linux/sched.h"
10706 +#include "asm/uaccess.h"
10708 +int copy_from_user_tt(void *to, const void *from, int n)
10710 + if(!access_ok_tt(VERIFY_READ, from, n))
10713 + return(__do_copy_from_user(to, from, n, ¤t->thread.fault_addr,
10714 + ¤t->thread.fault_catcher));
10717 +int copy_to_user_tt(void *to, const void *from, int n)
10719 + if(!access_ok_tt(VERIFY_WRITE, to, n))
10722 + return(__do_copy_to_user(to, from, n, ¤t->thread.fault_addr,
10723 + ¤t->thread.fault_catcher));
10726 +int strncpy_from_user_tt(char *dst, const char *src, int count)
10730 + if(!access_ok_tt(VERIFY_READ, src, 1))
10733 + n = __do_strncpy_from_user(dst, src, count,
10734 + ¤t->thread.fault_addr,
10735 + ¤t->thread.fault_catcher);
10736 + if(n < 0) return(-EFAULT);
10740 +int __clear_user_tt(void *mem, int len)
10742 + return(__do_clear_user(mem, len,
10743 + ¤t->thread.fault_addr,
10744 + ¤t->thread.fault_catcher));
10747 +int clear_user_tt(void *mem, int len)
10749 + if(!access_ok_tt(VERIFY_WRITE, mem, len))
10752 + return(__do_clear_user(mem, len, ¤t->thread.fault_addr,
10753 + ¤t->thread.fault_catcher));
10756 +int strnlen_user_tt(const void *str, int len)
10758 + return(__do_strnlen_user(str, len,
10759 + ¤t->thread.fault_addr,
10760 + ¤t->thread.fault_catcher));
10764 + * Overrides for Emacs so that we follow Linus's tabbing style.
10765 + * Emacs will notice this stuff at the end of the file and automatically
10766 + * adjust the settings for this buffer only. This must remain at the end
10768 + * ---------------------------------------------------------------------------
10769 + * Local variables:
10770 + * c-file-style: "linux"
10773 Index: uml-2.6.7/arch/um/kernel/skas/util/Makefile
10774 ===================================================================
10775 --- uml-2.6.7.orig/arch/um/kernel/skas/util/Makefile 2004-07-16 19:37:20.411921992 +0300
10776 +++ uml-2.6.7/arch/um/kernel/skas/util/Makefile 2004-07-16 19:47:23.735202912 +0300
10780 mk_ptregs : mk_ptregs.o
10781 - $(CC) -o mk_ptregs mk_ptregs.o
10782 + $(HOSTCC) -o mk_ptregs mk_ptregs.o
10784 mk_ptregs.o : mk_ptregs.c
10789 - $(RM) -f mk_ptregs *.o *~
10790 +clean-files := mk_ptregs *.o *~
10791 Index: uml-2.6.7/arch/um/kernel/skas/sys-i386/Makefile
10792 ===================================================================
10793 --- uml-2.6.7.orig/arch/um/kernel/skas/sys-i386/Makefile 2004-07-16 19:37:26.083059848 +0300
10794 +++ uml-2.6.7/arch/um/kernel/skas/sys-i386/Makefile 2004-07-16 19:47:23.733203216 +0300
10797 $(USER_OBJS) : %.o: %.c
10798 $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
10801 Index: uml-2.6.7/arch/um/kernel/sigio_kern.c
10802 ===================================================================
10803 --- uml-2.6.7.orig/arch/um/kernel/sigio_kern.c 2004-07-16 19:36:16.630618224 +0300
10804 +++ uml-2.6.7/arch/um/kernel/sigio_kern.c 2004-07-16 19:47:23.725204432 +0300
10806 #include "linux/kernel.h"
10807 #include "linux/list.h"
10808 #include "linux/slab.h"
10809 -#include "asm/irq.h"
10810 +#include "linux/signal.h"
10811 +#include "linux/interrupt.h"
10814 #include "irq_user.h"
10815 +#include "irq_kern.h"
10817 /* Protected by sigio_lock() called from write_sigio_workaround */
10818 static int sigio_irq_fd = -1;
10820 -void sigio_interrupt(int irq, void *data, struct pt_regs *unused)
10821 +irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused)
10823 read_sigio_fd(sigio_irq_fd);
10824 reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
10825 + return(IRQ_HANDLED);
10828 int write_sigio_irq(int fd)
10829 Index: uml-2.6.7/include/asm-um/system-generic.h
10830 ===================================================================
10831 --- uml-2.6.7.orig/include/asm-um/system-generic.h 2004-07-16 19:37:46.190003128 +0300
10832 +++ uml-2.6.7/include/asm-um/system-generic.h 2004-07-16 19:47:23.802192728 +0300
10834 extern void block_signals(void);
10835 extern void unblock_signals(void);
10837 -#define local_save_flags(flags) do { (flags) = get_signals(); } while(0)
10838 -#define local_irq_restore(flags) do { set_signals(flags); } while(0)
10839 +#define local_save_flags(flags) do { typecheck(unsigned long, flags); \
10840 + (flags) = get_signals(); } while(0)
10841 +#define local_irq_restore(flags) do { typecheck(unsigned long, flags); \
10842 + set_signals(flags); } while(0)
10844 #define local_irq_save(flags) do { local_save_flags(flags); \
10845 local_irq_disable(); } while(0)
10850 +extern void *_switch_to(void *prev, void *next, void *last);
10851 +#define switch_to(prev, next, last) prev = _switch_to(prev, next, last)
10854 Index: uml-2.6.7/include/asm-um/uaccess.h
10855 ===================================================================
10856 --- uml-2.6.7.orig/include/asm-um/uaccess.h 2004-07-16 19:37:05.104249112 +0300
10857 +++ uml-2.6.7/include/asm-um/uaccess.h 2004-07-16 19:47:23.804192424 +0300
10859 #ifndef __UM_UACCESS_H
10860 #define __UM_UACCESS_H
10862 +#include "linux/sched.h"
10864 #define VERIFY_READ 0
10865 #define VERIFY_WRITE 1
10867 Index: uml-2.6.7/arch/um/util/Makefile
10868 ===================================================================
10869 --- uml-2.6.7.orig/arch/um/util/Makefile 2004-07-16 19:37:43.611395136 +0300
10870 +++ uml-2.6.7/arch/um/util/Makefile 2004-07-16 19:47:23.780196072 +0300
10872 -always := mk_task mk_constants
10873 -targets := mk_task_user.o mk_task_kern.o \
10874 - mk_constants_user.o mk_constants_kern.o
10875 +host-progs := mk_task mk_constants
10876 +always := $(host-progs)
10878 -$(obj)/mk_task: $(obj)/mk_task_user.o $(obj)/mk_task_kern.o
10880 +mk_task-objs := mk_task_user.o mk_task_kern.o
10881 +mk_constants-objs := mk_constants_user.o mk_constants_kern.o
10883 -$(obj)/mk_task_user.o: $(src)/mk_task_user.c
10884 - $(CC) -o $@ -c $<
10886 -$(obj)/mk_constants : $(obj)/mk_constants_user.o $(obj)/mk_constants_kern.o
10889 -$(obj)/mk_constants_user.o : $(src)/mk_constants_user.c
10890 - $(CC) -c $< -o $@
10892 -$(obj)/mk_constants_kern.o : $(src)/mk_constants_kern.c
10893 - $(CC) $(CFLAGS) -c $< -o $@
10896 - $(RM) $(build-targets)
10899 +HOSTCFLAGS_mk_task_kern.o := $(CFLAGS) $(CPPFLAGS)
10900 +HOSTCFLAGS_mk_constants_kern.o := $(CFLAGS) $(CPPFLAGS)
10901 Index: uml-2.6.7/arch/um/os-Linux/file.c
10902 ===================================================================
10903 --- uml-2.6.7.orig/arch/um/os-Linux/file.c 2004-07-16 19:37:43.530407448 +0300
10904 +++ uml-2.6.7/arch/um/os-Linux/file.c 2004-07-16 19:47:23.767198048 +0300
10908 #include <signal.h>
10909 +#include <sys/types.h>
10910 +#include <sys/stat.h>
10911 #include <sys/socket.h>
10912 #include <sys/un.h>
10913 #include <sys/ioctl.h>
10914 @@ -17,33 +19,235 @@
10916 #include "kern_util.h"
10918 -int os_file_type(char *file)
10919 +static void copy_stat(struct uml_stat *dst, struct stat64 *src)
10921 + *dst = ((struct uml_stat) {
10922 + .ust_dev = src->st_dev, /* device */
10923 + .ust_ino = src->st_ino, /* inode */
10924 + .ust_mode = src->st_mode, /* protection */
10925 + .ust_nlink = src->st_nlink, /* number of hard links */
10926 + .ust_uid = src->st_uid, /* user ID of owner */
10927 + .ust_gid = src->st_gid, /* group ID of owner */
10928 + .ust_size = src->st_size, /* total size, in bytes */
10929 + .ust_blksize = src->st_blksize, /* blocksize for filesys I/O */
10930 + .ust_blocks = src->st_blocks, /* number of blocks allocated */
10931 + .ust_atime = src->st_atime, /* time of last access */
10932 + .ust_mtime = src->st_mtime, /* time of last modification */
10933 + .ust_ctime = src->st_ctime, /* time of last change */
10937 +int os_stat_fd(const int fd, struct uml_stat *ubuf)
10939 + struct stat64 sbuf;
10943 + err = fstat64(fd, &sbuf);
10944 + } while((err < 0) && (errno == EINTR)) ;
10950 + copy_stat(ubuf, &sbuf);
10954 +int os_stat_file(const char *file_name, struct uml_stat *ubuf)
10956 + struct stat64 sbuf;
10960 + err = stat64(file_name, &sbuf);
10961 + } while((err < 0) && (errno == EINTR)) ;
10967 + copy_stat(ubuf, &sbuf);
10971 +int os_access(const char* file, int mode)
10975 + amode=(mode&OS_ACC_R_OK ? R_OK : 0) | (mode&OS_ACC_W_OK ? W_OK : 0) |
10976 + (mode&OS_ACC_X_OK ? X_OK : 0) | (mode&OS_ACC_F_OK ? F_OK : 0) ;
10978 + err = access(file, amode);
10985 +void os_print_error(int error, const char* str)
10987 + errno = error < 0 ? -error : error;
10992 +/* FIXME? required only by hostaudio (because it passes ioctls verbatim) */
10993 +int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
10997 + err = ioctl(fd, cmd, arg);
11004 +int os_window_size(int fd, int *rows, int *cols)
11006 + struct winsize size;
11008 + if(ioctl(fd, TIOCGWINSZ, &size) < 0)
11011 + *rows = size.ws_row;
11012 + *cols = size.ws_col;
11017 +int os_new_tty_pgrp(int fd, int pid)
11019 - struct stat64 buf;
11020 + if(ioctl(fd, TIOCSCTTY, 0) < 0){
11021 + printk("TIOCSCTTY failed, errno = %d\n", errno);
11025 + if(tcsetpgrp(fd, pid) < 0){
11026 + printk("tcsetpgrp failed, errno = %d\n", errno);
11033 +/* FIXME: ensure namebuf in os_get_if_name is big enough */
11034 +int os_get_ifname(int fd, char* namebuf)
11036 + if(ioctl(fd, SIOCGIFNAME, namebuf) < 0)
11042 +int os_set_slip(int fd)
11044 + int disc, sencap;
11047 + if(ioctl(fd, TIOCSETD, &disc) < 0){
11048 + printk("Failed to set slip line discipline - "
11049 + "errno = %d\n", errno);
11054 + if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0){
11055 + printk("Failed to set slip encapsulation - "
11056 + "errno = %d\n", errno);
11063 +int os_set_owner(int fd, int pid)
11065 + if(fcntl(fd, F_SETOWN, pid) < 0){
11066 + int save_errno = errno;
11068 + if(fcntl(fd, F_GETOWN, 0) != pid)
11069 + return(-save_errno);
11075 +/* FIXME? moved wholesale from sigio_user.c to get fcntls out of that file */
11076 +int os_sigio_async(int master, int slave)
11080 - if(stat64(file, &buf) == -1)
11081 + flags = fcntl(master, F_GETFL);
11083 + printk("fcntl F_GETFL failed, errno = %d\n", errno);
11087 + if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
11088 + (fcntl(master, F_SETOWN, os_getpid()) < 0)){
11089 + printk("fcntl F_SETFL or F_SETOWN failed, errno = %d\n", errno);
11093 + if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)){
11094 + printk("fcntl F_SETFL failed, errno = %d\n", errno);
11098 - if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
11099 - else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
11100 - else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
11101 - else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
11102 - else if(S_ISFIFO(buf.st_mode)) return(OS_TYPE_FIFO);
11103 - else if(S_ISSOCK(buf.st_mode)) return(OS_TYPE_SOCK);
11107 +int os_mode_fd(int fd, int mode)
11112 + err = fchmod(fd, mode);
11113 + } while((err < 0) && (errno==EINTR)) ;
11121 +int os_file_type(char *file)
11123 + struct uml_stat buf;
11126 + err = os_stat_file(file, &buf);
11130 + if(S_ISDIR(buf.ust_mode)) return(OS_TYPE_DIR);
11131 + else if(S_ISLNK(buf.ust_mode)) return(OS_TYPE_SYMLINK);
11132 + else if(S_ISCHR(buf.ust_mode)) return(OS_TYPE_CHARDEV);
11133 + else if(S_ISBLK(buf.ust_mode)) return(OS_TYPE_BLOCKDEV);
11134 + else if(S_ISFIFO(buf.ust_mode)) return(OS_TYPE_FIFO);
11135 + else if(S_ISSOCK(buf.ust_mode)) return(OS_TYPE_SOCK);
11136 else return(OS_TYPE_FILE);
11139 int os_file_mode(char *file, struct openflags *mode_out)
11143 *mode_out = OPENFLAGS();
11145 - if(!access(file, W_OK)) *mode_out = of_write(*mode_out);
11146 - else if(errno != EACCES)
11148 + err = os_access(file, OS_ACC_W_OK);
11149 + if((err < 0) && (err != -EACCES))
11152 - if(!access(file, R_OK)) *mode_out = of_read(*mode_out);
11153 - else if(errno != EACCES)
11155 + *mode_out = of_write(*mode_out);
11157 + err = os_access(file, OS_ACC_R_OK);
11158 + if((err < 0) && (err != -EACCES))
11161 + *mode_out = of_read(*mode_out);
11165 @@ -63,16 +267,14 @@
11166 if(flags.e) f |= O_EXCL;
11168 fd = open64(file, f, mode);
11169 - if(fd < 0) return(-errno);
11172 - if(fcntl(fd, F_SETFD, 1)){
11179 + if(flags.cl && fcntl(fd, F_SETFD, 1)){
11180 + os_close_file(fd);
11190 err = connect(fd, (struct sockaddr *) &sock, sizeof(sock));
11197 @@ -109,88 +311,162 @@
11201 -int os_read_file(int fd, void *buf, int len)
11202 +static int fault_buffer(void *start, int len,
11203 + int (*copy_proc)(void *addr, void *buf, int len))
11206 + int page = getpagesize(), i;
11209 - /* Force buf into memory if it's not already. */
11210 + for(i = 0; i < len; i += page){
11211 + if((*copy_proc)(start + i, &c, sizeof(c)))
11214 + if((len % page) != 0){
11215 + if((*copy_proc)(start + len - 1, &c, sizeof(c)))
11221 - /* XXX This fails if buf is kernel memory */
11223 - if(copy_to_user_proc(buf, &c, sizeof(c)))
11226 +static int file_io(int fd, void *buf, int len,
11227 + int (*io_proc)(int fd, void *buf, int len),
11228 + int (*copy_user_proc)(void *addr, void *buf, int len))
11233 + n = (*io_proc)(fd, buf, len);
11234 + if((n < 0) && (errno == EFAULT)){
11235 + err = fault_buffer(buf, len, copy_user_proc);
11238 + n = (*io_proc)(fd, buf, len);
11240 + } while((n < 0) && (errno == EINTR));
11242 - n = read(fd, buf, len);
11248 -int os_write_file(int fd, void *buf, int count)
11249 +int os_read_file(int fd, void *buf, int len)
11253 - /* Force buf into memory if it's not already. */
11255 - /* XXX This fails if buf is kernel memory */
11257 - if(copy_to_user_proc(buf, buf, buf[0]))
11260 + return(file_io(fd, buf, len, (int (*)(int, void *, int)) read,
11261 + copy_from_user_proc));
11264 - n = write(fd, buf, count);
11268 +int os_write_file(int fd, const void *buf, int len)
11270 + return(file_io(fd, (void *) buf, len,
11271 + (int (*)(int, void *, int)) write, copy_to_user_proc));
11274 int os_file_size(char *file, long long *size_out)
11276 - struct stat64 buf;
11277 + struct uml_stat buf;
11280 - if(stat64(file, &buf) == -1){
11281 - printk("Couldn't stat \"%s\" : errno = %d\n", file, errno);
11283 + err = os_stat_file(file, &buf);
11285 + printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
11288 - if(S_ISBLK(buf.st_mode)){
11290 + if(S_ISBLK(buf.ust_mode)){
11293 - if((fd = open64(file, O_RDONLY)) < 0){
11294 - printk("Couldn't open \"%s\", errno = %d\n", file,
11297 + fd = os_open_file(file, of_read(OPENFLAGS()), 0);
11299 + printk("Couldn't open \"%s\", errno = %d\n", file, -fd);
11302 if(ioctl(fd, BLKGETSIZE, &blocks) < 0){
11303 printk("Couldn't get the block size of \"%s\", "
11304 "errno = %d\n", file, errno);
11308 + os_close_file(fd);
11311 *size_out = ((long long) blocks) * 512;
11313 + os_close_file(fd);
11316 - *size_out = buf.st_size;
11317 + *size_out = buf.ust_size;
11321 +int os_file_modtime(char *file, unsigned long *modtime)
11323 + struct uml_stat buf;
11326 + err = os_stat_file(file, &buf);
11328 + printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
11332 + *modtime = buf.ust_mtime;
11336 +int os_get_exec_close(int fd, int* close_on_exec)
11341 + ret = fcntl(fd, F_GETFD);
11342 + } while((ret < 0) && (errno == EINTR)) ;
11347 + *close_on_exec = (ret&FD_CLOEXEC) ? 1 : 0;
11351 +int os_set_exec_close(int fd, int close_on_exec)
11355 + if(close_on_exec) flag = FD_CLOEXEC;
11359 + err = fcntl(fd, F_SETFD, flag);
11360 + } while((err < 0) && (errno == EINTR)) ;
11367 int os_pipe(int *fds, int stream, int close_on_exec)
11369 int err, type = stream ? SOCK_STREAM : SOCK_DGRAM;
11371 err = socketpair(AF_UNIX, type, 0, fds);
11379 - if((fcntl(fds[0], F_SETFD, 1) < 0) || (fcntl(fds[1], F_SETFD, 1) < 0))
11380 - printk("os_pipe : Setting FD_CLOEXEC failed, errno = %d",
11382 + err = os_set_exec_close(fds[0], 1);
11386 + err = os_set_exec_close(fds[1], 1);
11393 + printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err);
11394 + os_close_file(fds[1]);
11395 + os_close_file(fds[0]);
11399 int os_set_fd_async(int fd, int owner)
11400 @@ -270,7 +546,7 @@
11403 err = shutdown(fd, what);
11409 @@ -315,7 +591,7 @@
11413 -int create_unix_socket(char *file, int len)
11414 +int os_create_unix_socket(char *file, int len, int close_on_exec)
11416 struct sockaddr_un addr;
11418 @@ -327,6 +603,13 @@
11422 + if(close_on_exec) {
11423 + err = os_set_exec_close(sock, 1);
11425 + printk("create_unix_socket : close_on_exec failed, "
11426 + "err = %d", -err);
11429 addr.sun_family = AF_UNIX;
11431 /* XXX Be more careful about overflow */
11432 @@ -334,14 +617,45 @@
11434 err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
11436 - printk("create_listening_socket - bind failed, errno = %d\n",
11438 + printk("create_listening_socket at '%s' - bind failed, "
11439 + "errno = %d\n", file, errno);
11446 +void os_flush_stdout(void)
11451 +int os_lock_file(int fd, int excl)
11453 + int type = excl ? F_WRLCK : F_RDLCK;
11454 + struct flock lock = ((struct flock) { .l_type = type,
11455 + .l_whence = SEEK_SET,
11460 + err = fcntl(fd, F_SETLK, &lock);
11465 + err = fcntl(fd, F_GETLK, &lock);
11471 + printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
11478 * Overrides for Emacs so that we follow Linus's tabbing style.
11479 * Emacs will notice this stuff at the end of the file and automatically
11480 Index: uml-2.6.7/arch/um/kernel/tt/sys-i386/Makefile
11481 ===================================================================
11482 --- uml-2.6.7.orig/arch/um/kernel/tt/sys-i386/Makefile 2004-07-16 19:36:33.266089248 +0300
11483 +++ uml-2.6.7/arch/um/kernel/tt/sys-i386/Makefile 2004-07-16 19:47:23.750200632 +0300
11486 $(USER_OBJS) : %.o: %.c
11487 $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
11490 Index: uml-2.6.7/arch/um/kernel/skas/exec_user.c
11491 ===================================================================
11492 --- uml-2.6.7.orig/arch/um/kernel/skas/exec_user.c 2004-07-16 19:36:07.836955064 +0300
11493 +++ uml-2.6.7/arch/um/kernel/skas/exec_user.c 2004-07-16 19:47:24.798041336 +0300
11495 #include <sys/ptrace.h>
11497 #include "kern_util.h"
11498 +#include "user_util.h"
11500 #include "time_user.h"
11504 int user_thread(unsigned long stack, int flags)
11507 + int pid, status, err;
11509 pid = clone(user_thread_tramp, (void *) stack_sp(stack),
11510 flags | CLONE_FILES | SIGCHLD, NULL);
11515 - if(waitpid(pid, &status, WUNTRACED) < 0){
11516 + CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
11518 printk("user_thread - waitpid failed, errno = %d\n", errno);
11521 Index: uml-2.6.7/arch/um/kernel/tt/mem_user.c
11522 ===================================================================
11523 --- uml-2.6.7.orig/arch/um/kernel/tt/mem_user.c 2004-07-16 19:36:16.863582808 +0300
11524 +++ uml-2.6.7/arch/um/kernel/tt/mem_user.c 2004-07-16 19:47:23.745201392 +0300
11525 @@ -25,14 +25,13 @@
11526 size = (unsigned long) segment_end -
11527 (unsigned long) segment_start;
11528 data = create_mem_file(size);
11529 - if((addr = mmap(NULL, size, PROT_WRITE | PROT_READ,
11530 - MAP_SHARED, data, 0)) == MAP_FAILED){
11531 + addr = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, data, 0);
11532 + if(addr == MAP_FAILED){
11533 perror("mapping new data segment");
11536 memcpy(addr, segment_start, size);
11537 - if(switcheroo(data, prot, addr, segment_start,
11539 + if(switcheroo(data, prot, addr, segment_start, size) < 0){
11540 printf("switcheroo failed\n");
11543 Index: uml-2.6.7/arch/um/kernel/ksyms.c
11544 ===================================================================
11545 --- uml-2.6.7.orig/arch/um/kernel/ksyms.c 2004-07-16 19:35:55.815782560 +0300
11546 +++ uml-2.6.7/arch/um/kernel/ksyms.c 2004-07-16 19:47:24.866031000 +0300
11549 - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
11550 + * Copyright (C) 2001 - 2004 Jeff Dike (jdike@addtoit.com)
11551 * Licensed under the GPL
11555 #include "linux/string.h"
11556 #include "linux/smp_lock.h"
11557 #include "linux/spinlock.h"
11558 -#include <linux/highmem.h>
11559 +#include "linux/highmem.h"
11560 #include "asm/current.h"
11561 #include "asm/delay.h"
11562 #include "asm/processor.h"
11564 #include "asm/tlbflush.h"
11565 #include "kern_util.h"
11566 #include "user_util.h"
11567 +#include "mem_user.h"
11569 #include "helper.h"
11571 @@ -34,34 +35,66 @@
11572 EXPORT_SYMBOL(flush_tlb_range);
11573 EXPORT_SYMBOL(host_task_size);
11574 EXPORT_SYMBOL(arch_validate);
11575 +EXPORT_SYMBOL(get_kmem_end);
11577 -EXPORT_SYMBOL(region_pa);
11578 -EXPORT_SYMBOL(region_va);
11579 -EXPORT_SYMBOL(phys_mem_map);
11580 -EXPORT_SYMBOL(page_mem_map);
11581 EXPORT_SYMBOL(page_to_phys);
11582 EXPORT_SYMBOL(phys_to_page);
11583 EXPORT_SYMBOL(high_physmem);
11584 EXPORT_SYMBOL(empty_zero_page);
11585 EXPORT_SYMBOL(um_virt_to_phys);
11586 +EXPORT_SYMBOL(__virt_to_page);
11587 +EXPORT_SYMBOL(to_phys);
11588 +EXPORT_SYMBOL(to_virt);
11589 EXPORT_SYMBOL(mode_tt);
11590 EXPORT_SYMBOL(handle_page_fault);
11591 +EXPORT_SYMBOL(find_iomem);
11593 +#ifdef CONFIG_MODE_TT
11594 +EXPORT_SYMBOL(strncpy_from_user_tt);
11595 +EXPORT_SYMBOL(copy_from_user_tt);
11596 +EXPORT_SYMBOL(copy_to_user_tt);
11599 +#ifdef CONFIG_MODE_SKAS
11600 +EXPORT_SYMBOL(strncpy_from_user_skas);
11601 +EXPORT_SYMBOL(copy_to_user_skas);
11602 +EXPORT_SYMBOL(copy_from_user_skas);
11605 +EXPORT_SYMBOL(os_stat_fd);
11606 +EXPORT_SYMBOL(os_stat_file);
11607 +EXPORT_SYMBOL(os_access);
11608 +EXPORT_SYMBOL(os_print_error);
11609 +EXPORT_SYMBOL(os_get_exec_close);
11610 +EXPORT_SYMBOL(os_set_exec_close);
11611 EXPORT_SYMBOL(os_getpid);
11612 EXPORT_SYMBOL(os_open_file);
11613 EXPORT_SYMBOL(os_read_file);
11614 EXPORT_SYMBOL(os_write_file);
11615 EXPORT_SYMBOL(os_seek_file);
11616 +EXPORT_SYMBOL(os_lock_file);
11617 +EXPORT_SYMBOL(os_ioctl_generic);
11618 EXPORT_SYMBOL(os_pipe);
11619 EXPORT_SYMBOL(os_file_type);
11620 +EXPORT_SYMBOL(os_file_mode);
11621 +EXPORT_SYMBOL(os_file_size);
11622 +EXPORT_SYMBOL(os_flush_stdout);
11623 EXPORT_SYMBOL(os_close_file);
11624 +EXPORT_SYMBOL(os_set_fd_async);
11625 +EXPORT_SYMBOL(os_set_fd_block);
11626 EXPORT_SYMBOL(helper_wait);
11627 EXPORT_SYMBOL(os_shutdown_socket);
11628 +EXPORT_SYMBOL(os_create_unix_socket);
11629 EXPORT_SYMBOL(os_connect_socket);
11630 +EXPORT_SYMBOL(os_accept_connection);
11631 +EXPORT_SYMBOL(os_rcv_fd);
11632 EXPORT_SYMBOL(run_helper);
11633 EXPORT_SYMBOL(start_thread);
11634 EXPORT_SYMBOL(dump_thread);
11636 +EXPORT_SYMBOL(do_gettimeofday);
11637 +EXPORT_SYMBOL(do_settimeofday);
11639 /* This is here because UML expands open to sys_open, not to a system
11640 * call instruction.
11642 @@ -90,3 +123,13 @@
11643 EXPORT_SYMBOL(kmap_atomic_to_page);
11647 + * Overrides for Emacs so that we follow Linus's tabbing style.
11648 + * Emacs will notice this stuff at the end of the file and automatically
11649 + * adjust the settings for this buffer only. This must remain at the end
11651 + * ---------------------------------------------------------------------------
11652 + * Local variables:
11653 + * c-file-style: "linux"
11656 Index: uml-2.6.7/include/linux/gfp.h
11657 ===================================================================
11658 --- uml-2.6.7.orig/include/linux/gfp.h 2004-07-16 19:36:13.897033792 +0300
11659 +++ uml-2.6.7/include/linux/gfp.h 2004-07-16 19:47:23.805192272 +0300
11661 * For the normal case of non-DISCONTIGMEM systems the NODE_DATA() gets
11662 * optimized to &contig_page_data at compile-time.
11665 +#ifndef HAVE_ARCH_FREE_PAGE
11666 +static inline void arch_free_page(struct page *page, int order) { }
11669 extern struct page *
11670 FASTCALL(__alloc_pages(unsigned int, unsigned int, struct zonelist *));
11672 Index: uml-2.6.7/arch/um/defconfig
11673 ===================================================================
11674 --- uml-2.6.7.orig/arch/um/defconfig 2004-07-16 19:37:02.601629568 +0300
11675 +++ uml-2.6.7/arch/um/defconfig 2004-07-16 19:47:23.676211880 +0300
11682 CONFIG_RWSEM_GENERIC_SPINLOCK=y
11683 -CONFIG_CONFIG_LOG_BUF_SHIFT=14
11686 -# Code maturity level options
11688 -CONFIG_EXPERIMENTAL=y
11692 +# UML-specific options
11698 -CONFIG_BSD_PROCESS_ACCT=y
11700 -CONFIG_BINFMT_AOUT=y
11701 CONFIG_BINFMT_ELF=y
11702 CONFIG_BINFMT_MISC=y
11706 CONFIG_MAGIC_SYSRQ=y
11707 # CONFIG_HOST_2G_2G is not set
11708 @@ -36,12 +26,43 @@
11709 # CONFIG_HIGHMEM is not set
11711 CONFIG_KERNEL_STACK_ORDER=2
11712 +CONFIG_UML_REAL_TIME_CLOCK=y
11715 +# Code maturity level options
11717 +CONFIG_EXPERIMENTAL=y
11718 +CONFIG_CLEAN_COMPILE=y
11719 +CONFIG_STANDALONE=y
11720 +CONFIG_BROKEN_ON_SMP=y
11727 +CONFIG_BSD_PROCESS_ACCT=y
11729 +CONFIG_LOG_BUF_SHIFT=14
11730 +# CONFIG_HOTPLUG is not set
11731 +# CONFIG_IKCONFIG is not set
11732 +# CONFIG_EMBEDDED is not set
11736 +CONFIG_IOSCHED_NOOP=y
11737 +CONFIG_IOSCHED_AS=y
11738 +CONFIG_IOSCHED_DEADLINE=y
11739 +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
11742 # Loadable module support
11745 -# CONFIG_KMOD is not set
11746 +# CONFIG_MODULES is not set
11749 +# Generic Driver Options
11753 # Character Devices
11756 CONFIG_BLK_DEV_UBD=y
11757 # CONFIG_BLK_DEV_UBD_SYNC is not set
11758 +CONFIG_BLK_DEV_COW_COMMON=y
11759 CONFIG_BLK_DEV_LOOP=y
11760 CONFIG_BLK_DEV_NBD=y
11761 CONFIG_BLK_DEV_RAM=y
11763 CONFIG_NETDEVICES=y
11767 +# UML Network Devices
11770 CONFIG_UML_NET_ETHERTAP=y
11771 @@ -88,22 +110,6 @@
11772 CONFIG_UML_NET_MCAST=y
11773 # CONFIG_UML_NET_PCAP is not set
11774 CONFIG_UML_NET_SLIRP=y
11776 -# CONFIG_BONDING is not set
11777 -# CONFIG_EQUALIZER is not set
11779 -# CONFIG_ETHERTAP is not set
11781 -# CONFIG_PPP_MULTILINK is not set
11782 -# CONFIG_PPP_ASYNC is not set
11783 -# CONFIG_PPP_SYNC_TTY is not set
11784 -# CONFIG_PPP_DEFLATE is not set
11785 -# CONFIG_PPP_BSDCOMP is not set
11786 -# CONFIG_PPPOE is not set
11788 -# CONFIG_SLIP_COMPRESSED is not set
11789 -# CONFIG_SLIP_SMART is not set
11790 -# CONFIG_SLIP_MODE_SLIP6 is not set
11793 # Networking support
11794 @@ -115,8 +121,6 @@
11796 CONFIG_PACKET_MMAP=y
11797 # CONFIG_NETLINK_DEV is not set
11798 -# CONFIG_NETFILTER is not set
11799 -# CONFIG_FILTER is not set
11801 # CONFIG_NET_KEY is not set
11803 @@ -130,8 +134,11 @@
11804 # CONFIG_SYN_COOKIES is not set
11805 # CONFIG_INET_AH is not set
11806 # CONFIG_INET_ESP is not set
11807 -# CONFIG_XFRM_USER is not set
11808 +# CONFIG_INET_IPCOMP is not set
11809 # CONFIG_IPV6 is not set
11810 +# CONFIG_DECNET is not set
11811 +# CONFIG_BRIDGE is not set
11812 +# CONFIG_NETFILTER is not set
11815 # SCTP Configuration (EXPERIMENTAL)
11816 @@ -140,9 +147,9 @@
11817 # CONFIG_IP_SCTP is not set
11818 # CONFIG_ATM is not set
11819 # CONFIG_VLAN_8021Q is not set
11820 -# CONFIG_LLC is not set
11821 -# CONFIG_DECNET is not set
11822 -# CONFIG_BRIDGE is not set
11823 +# CONFIG_LLC2 is not set
11824 +# CONFIG_IPX is not set
11825 +# CONFIG_ATALK is not set
11826 # CONFIG_X25 is not set
11827 # CONFIG_LAPB is not set
11828 # CONFIG_NET_DIVERT is not set
11829 @@ -160,6 +167,10 @@
11832 # CONFIG_NET_PKTGEN is not set
11834 +# CONFIG_BONDING is not set
11835 +# CONFIG_EQUALIZER is not set
11839 # Ethernet (10 or 100Mbit)
11840 @@ -171,12 +182,28 @@
11844 +# Ethernet (10000 Mbit)
11847 +# CONFIG_PPP_MULTILINK is not set
11848 +# CONFIG_PPP_FILTER is not set
11849 +# CONFIG_PPP_ASYNC is not set
11850 +# CONFIG_PPP_SYNC_TTY is not set
11851 +# CONFIG_PPP_DEFLATE is not set
11852 +# CONFIG_PPP_BSDCOMP is not set
11853 +# CONFIG_PPPOE is not set
11855 +# CONFIG_SLIP_COMPRESSED is not set
11856 +# CONFIG_SLIP_SMART is not set
11857 +# CONFIG_SLIP_MODE_SLIP6 is not set
11860 # Wireless LAN (non-hamradio)
11862 # CONFIG_NET_RADIO is not set
11865 -# Token Ring devices (depends on LLC=y)
11866 +# Token Ring devices
11868 # CONFIG_SHAPER is not set
11870 @@ -186,68 +213,100 @@
11871 # CONFIG_WAN is not set
11874 +# Amateur Radio support
11876 +# CONFIG_HAMRADIO is not set
11879 +# IrDA (infrared) support
11881 +# CONFIG_IRDA is not set
11884 +# Bluetooth support
11886 +# CONFIG_BT is not set
11892 +# CONFIG_EXT2_FS_XATTR is not set
11893 +# CONFIG_EXT3_FS is not set
11894 +# CONFIG_JBD is not set
11895 +CONFIG_REISERFS_FS=y
11896 +# CONFIG_REISERFS_CHECK is not set
11897 +# CONFIG_REISERFS_PROC_INFO is not set
11898 +# CONFIG_JFS_FS is not set
11899 +# CONFIG_XFS_FS is not set
11901 +# CONFIG_ROMFS_FS is not set
11903 # CONFIG_QFMT_V1 is not set
11904 # CONFIG_QFMT_V2 is not set
11906 -CONFIG_AUTOFS_FS=m
11907 -CONFIG_AUTOFS4_FS=m
11908 -CONFIG_REISERFS_FS=m
11909 -# CONFIG_REISERFS_CHECK is not set
11910 -# CONFIG_REISERFS_PROC_INFO is not set
11911 +CONFIG_AUTOFS_FS=y
11912 +CONFIG_AUTOFS4_FS=y
11915 +# CD-ROM/DVD Filesystems
11917 +CONFIG_ISO9660_FS=y
11918 +# CONFIG_JOLIET is not set
11919 +# CONFIG_ZISOFS is not set
11920 +# CONFIG_UDF_FS is not set
11923 +# DOS/FAT/NT Filesystems
11928 +# CONFIG_NTFS_FS is not set
11931 +# Pseudo filesystems
11934 +CONFIG_PROC_KCORE=y
11936 +CONFIG_DEVFS_MOUNT=y
11937 +# CONFIG_DEVFS_DEBUG is not set
11938 +# CONFIG_DEVPTS_FS_XATTR is not set
11940 +# CONFIG_HUGETLB_PAGE is not set
11944 +# Miscellaneous filesystems
11946 # CONFIG_ADFS_FS is not set
11947 # CONFIG_AFFS_FS is not set
11948 # CONFIG_HFS_FS is not set
11949 +# CONFIG_HFSPLUS_FS is not set
11950 # CONFIG_BEFS_FS is not set
11951 # CONFIG_BFS_FS is not set
11952 -# CONFIG_EXT3_FS is not set
11953 -# CONFIG_JBD is not set
11957 # CONFIG_EFS_FS is not set
11959 CONFIG_JFFS_FS_VERBOSE=0
11960 -CONFIG_JFFS_PROC_FS=y
11961 # CONFIG_JFFS2_FS is not set
11962 # CONFIG_CRAMFS is not set
11963 -# CONFIG_TMPFS is not set
11965 -CONFIG_ISO9660_FS=m
11966 -# CONFIG_JOLIET is not set
11967 -# CONFIG_ZISOFS is not set
11968 -# CONFIG_JFS_FS is not set
11970 # CONFIG_VXFS_FS is not set
11971 -# CONFIG_NTFS_FS is not set
11972 # CONFIG_HPFS_FS is not set
11975 -CONFIG_DEVFS_MOUNT=y
11976 -# CONFIG_DEVFS_DEBUG is not set
11977 -CONFIG_DEVPTS_FS=y
11978 # CONFIG_QNX4FS_FS is not set
11979 -# CONFIG_ROMFS_FS is not set
11981 -# CONFIG_EXT2_FS_XATTR is not set
11982 # CONFIG_SYSV_FS is not set
11983 -# CONFIG_UDF_FS is not set
11984 # CONFIG_UFS_FS is not set
11985 -# CONFIG_XFS_FS is not set
11988 # Network File Systems
11990 -# CONFIG_CODA_FS is not set
11991 -# CONFIG_INTERMEZZO_FS is not set
11992 # CONFIG_NFS_FS is not set
11993 # CONFIG_NFSD is not set
11994 # CONFIG_EXPORTFS is not set
11995 -# CONFIG_CIFS is not set
11996 # CONFIG_SMB_FS is not set
11997 +# CONFIG_CIFS is not set
11998 # CONFIG_NCP_FS is not set
11999 +# CONFIG_CODA_FS is not set
12000 # CONFIG_AFS_FS is not set
12003 @@ -255,11 +314,11 @@
12005 # CONFIG_PARTITION_ADVANCED is not set
12006 CONFIG_MSDOS_PARTITION=y
12010 # Native Language Support
12013 CONFIG_NLS_DEFAULT="iso8859-1"
12014 # CONFIG_NLS_CODEPAGE_437 is not set
12015 # CONFIG_NLS_CODEPAGE_737 is not set
12016 @@ -317,28 +376,7 @@
12021 -CONFIG_GENERIC_ISA_DMA=y
12024 -# SCSI support type (disk, tape, CD-ROM)
12026 -CONFIG_BLK_DEV_SD=y
12027 -CONFIG_SD_EXTRA_DEVS=40
12028 -CONFIG_CHR_DEV_ST=y
12029 -CONFIG_BLK_DEV_SR=y
12030 -CONFIG_BLK_DEV_SR_VENDOR=y
12031 -CONFIG_SR_EXTRA_DEVS=2
12032 -CONFIG_CHR_DEV_SG=y
12035 -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
12037 -CONFIG_SCSI_DEBUG_QUEUES=y
12038 -CONFIG_SCSI_MULTI_LUN=y
12039 -CONFIG_SCSI_CONSTANTS=y
12040 -CONFIG_SCSI_LOGGING=y
12041 -CONFIG_SCSI_DEBUG=y
12042 +# CONFIG_SCSI is not set
12045 # Multi-device support (RAID and LVM)
12046 @@ -360,6 +398,7 @@
12048 # CONFIG_FTL is not set
12049 # CONFIG_NFTL is not set
12050 +# CONFIG_INFTL is not set
12053 # RAM/ROM/Flash chip drivers
12054 @@ -374,20 +413,21 @@
12056 # Mapping drivers for chip access
12058 +# CONFIG_MTD_COMPLEX_MAPPINGS is not set
12061 # Self-contained MTD device drivers
12063 # CONFIG_MTD_SLRAM is not set
12064 # CONFIG_MTD_MTDRAM is not set
12065 -CONFIG_MTD_BLKMTD=m
12066 +CONFIG_MTD_BLKMTD=y
12069 # Disk-On-Chip Device Drivers
12071 -# CONFIG_MTD_DOC1000 is not set
12072 # CONFIG_MTD_DOC2000 is not set
12073 # CONFIG_MTD_DOC2001 is not set
12074 +# CONFIG_MTD_DOC2001PLUS is not set
12077 # NAND Flash Device Drivers
12078 Index: uml-2.6.7/arch/um/kernel/physmem.c
12079 ===================================================================
12080 --- uml-2.6.7.orig/arch/um/kernel/physmem.c 2004-07-16 19:47:23.617220848 +0300
12081 +++ uml-2.6.7/arch/um/kernel/physmem.c 2004-07-16 19:47:23.722204888 +0300
12084 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
12085 + * Licensed under the GPL
12088 +#include "linux/mm.h"
12089 +#include "linux/ghash.h"
12090 +#include "linux/slab.h"
12091 +#include "linux/vmalloc.h"
12092 +#include "linux/bootmem.h"
12093 +#include "asm/types.h"
12094 +#include "asm/pgtable.h"
12095 +#include "kern_util.h"
12096 +#include "user_util.h"
12097 +#include "mode_kern.h"
12099 +#include "mem_user.h"
12105 +static pgd_t physmem_pgd[PTRS_PER_PGD];
12107 +static struct phys_desc *lookup_mapping(void *addr)
12109 + pgd = &physmem_pgd[pgd_index(addr)];
12110 + if(pgd_none(pgd))
12113 + pmd = pmd_offset(pgd, addr);
12114 + if(pmd_none(pmd))
12117 + pte = pte_offset_kernel(pmd, addr);
12118 + return((struct phys_desc *) pte_val(pte));
12121 +static struct add_mapping(void *addr, struct phys_desc *new)
12126 +#define PHYS_HASHSIZE (8192)
12130 +DEF_HASH_STRUCTS(virtmem, PHYS_HASHSIZE, struct phys_desc);
12132 +struct phys_desc {
12133 + struct virtmem_ptrs virt_ptrs;
12137 + unsigned long phys;
12138 + struct list_head list;
12141 +struct virtmem_table virtmem_hash;
12143 +static int virt_cmp(void *virt1, void *virt2)
12145 + return(virt1 != virt2);
12148 +static int virt_hash(void *virt)
12150 + unsigned long addr = ((unsigned long) virt) >> PAGE_SHIFT;
12151 + return(addr % PHYS_HASHSIZE);
12154 +DEF_HASH(static, virtmem, struct phys_desc, virt_ptrs, void *, virt, virt_cmp,
12157 +LIST_HEAD(descriptor_mappings);
12159 +struct desc_mapping {
12161 + struct list_head list;
12162 + struct list_head pages;
12165 +static struct desc_mapping *find_mapping(int fd)
12167 + struct desc_mapping *desc;
12168 + struct list_head *ele;
12170 + list_for_each(ele, &descriptor_mappings){
12171 + desc = list_entry(ele, struct desc_mapping, list);
12172 + if(desc->fd == fd)
12179 +static struct desc_mapping *descriptor_mapping(int fd)
12181 + struct desc_mapping *desc;
12183 + desc = find_mapping(fd);
12187 + desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
12191 + *desc = ((struct desc_mapping)
12193 + .list = LIST_HEAD_INIT(desc->list),
12194 + .pages = LIST_HEAD_INIT(desc->pages) });
12195 + list_add(&desc->list, &descriptor_mappings);
12200 +int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w)
12202 + struct desc_mapping *fd_maps;
12203 + struct phys_desc *desc;
12204 + unsigned long phys;
12207 + fd_maps = descriptor_mapping(fd);
12208 + if(fd_maps == NULL)
12211 + phys = __pa(virt);
12212 + if(find_virtmem_hash(&virtmem_hash, virt) != NULL)
12213 + panic("Address 0x%p is already substituted\n", virt);
12216 + desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
12220 + *desc = ((struct phys_desc)
12221 + { .virt_ptrs = { NULL, NULL },
12223 + .offset = offset,
12225 + .phys = __pa(virt),
12226 + .list = LIST_HEAD_INIT(desc->list) });
12227 + insert_virtmem_hash(&virtmem_hash, desc);
12229 + list_add(&desc->list, &fd_maps->pages);
12231 + virt = (void *) ((unsigned long) virt & PAGE_MASK);
12232 + err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0);
12236 + remove_virtmem_hash(&virtmem_hash, desc);
12242 +static int physmem_fd = -1;
12244 +static void remove_mapping(struct phys_desc *desc)
12246 + void *virt = desc->virt;
12249 + remove_virtmem_hash(&virtmem_hash, desc);
12250 + list_del(&desc->list);
12253 + err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0);
12255 + panic("Failed to unmap block device page from physical memory, "
12256 + "errno = %d", -err);
12259 +int physmem_remove_mapping(void *virt)
12261 + struct phys_desc *desc;
12263 + virt = (void *) ((unsigned long) virt & PAGE_MASK);
12264 + desc = find_virtmem_hash(&virtmem_hash, virt);
12268 + remove_mapping(desc);
12272 +void physmem_forget_descriptor(int fd)
12274 + struct desc_mapping *desc;
12275 + struct phys_desc *page;
12276 + struct list_head *ele, *next;
12281 + desc = find_mapping(fd);
12285 + list_for_each_safe(ele, next, &desc->pages){
12286 + page = list_entry(ele, struct phys_desc, list);
12287 + offset = page->offset;
12288 + addr = page->virt;
12289 + remove_mapping(page);
12290 + err = os_seek_file(fd, offset);
12292 + panic("physmem_forget_descriptor - failed to seek "
12293 + "to %lld in fd %d, error = %d\n",
12294 + offset, fd, -err);
12295 + err = os_read_file(fd, addr, PAGE_SIZE);
12297 + panic("physmem_forget_descriptor - failed to read "
12298 + "from fd %d to 0x%p, error = %d\n",
12302 + list_del(&desc->list);
12306 +void arch_free_page(struct page *page, int order)
12311 + for(i = 0; i < (1 << order); i++){
12312 + virt = __va(page_to_phys(page + i));
12313 + physmem_remove_mapping(virt);
12317 +int is_remapped(void *virt)
12319 + return(find_virtmem_hash(&virtmem_hash, virt) != NULL);
12322 +/* Changed during early boot */
12323 +unsigned long high_physmem;
12325 +extern unsigned long physmem_size;
12327 +void *to_virt(unsigned long phys)
12329 + return((void *) uml_physmem + phys);
12332 +unsigned long to_phys(void *virt)
12334 + return(((unsigned long) virt) - uml_physmem);
12337 +int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem)
12339 + struct page *p, *map;
12340 + unsigned long phys_len, phys_pages, highmem_len, highmem_pages;
12341 + unsigned long iomem_len, iomem_pages, total_len, total_pages;
12344 + phys_pages = physmem >> PAGE_SHIFT;
12345 + phys_len = phys_pages * sizeof(struct page);
12347 + iomem_pages = iomem >> PAGE_SHIFT;
12348 + iomem_len = iomem_pages * sizeof(struct page);
12350 + highmem_pages = highmem >> PAGE_SHIFT;
12351 + highmem_len = highmem_pages * sizeof(struct page);
12353 + total_pages = phys_pages + iomem_pages + highmem_pages;
12354 + total_len = phys_len + iomem_pages + highmem_len;
12357 + map = kmalloc(total_len, GFP_KERNEL);
12359 + map = vmalloc(total_len);
12361 + else map = alloc_bootmem_low_pages(total_len);
12366 + for(i = 0; i < total_pages; i++){
12368 + set_page_count(p, 0);
12369 + SetPageReserved(p);
12370 + INIT_LIST_HEAD(&p->lru);
12374 + max_mapnr = total_pages;
12378 +struct page *phys_to_page(const unsigned long phys)
12380 + return(&mem_map[phys >> PAGE_SHIFT]);
12383 +struct page *__virt_to_page(const unsigned long virt)
12385 + return(&mem_map[__pa(virt) >> PAGE_SHIFT]);
12388 +unsigned long page_to_phys(struct page *page)
12390 + return((page - mem_map) << PAGE_SHIFT);
12393 +pte_t mk_pte(struct page *page, pgprot_t pgprot)
12397 + pte_val(pte) = page_to_phys(page) + pgprot_val(pgprot);
12398 + if(pte_present(pte)) pte_mknewprot(pte_mknewpage(pte));
12402 +/* Changed during early boot */
12403 +static unsigned long kmem_top = 0;
12405 +unsigned long get_kmem_end(void)
12407 + if(kmem_top == 0)
12408 + kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
12409 + return(kmem_top);
12412 +void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
12413 + int r, int w, int x)
12418 + fd = phys_mapping(phys, &offset);
12419 + err = os_map_memory((void *) virt, fd, offset, len, r, w, x);
12421 + panic("map_memory(0x%lx, %d, 0x%llx, %ld, %d, %d, %d) failed, "
12422 + "err = %d\n", virt, fd, offset, len, r, w, x, err);
12425 +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
12427 +void setup_physmem(unsigned long start, unsigned long reserve_end,
12428 + unsigned long len, unsigned long highmem)
12430 + unsigned long reserve = reserve_end - start;
12431 + int pfn = PFN_UP(__pa(reserve_end));
12432 + int delta = (len - reserve) >> PAGE_SHIFT;
12433 + int err, offset, bootmap_size;
12435 + physmem_fd = create_mem_file(len + highmem);
12437 + offset = uml_reserved - uml_physmem;
12438 + err = os_map_memory((void *) uml_reserved, physmem_fd, offset,
12439 + len - offset, 1, 1, 0);
12441 + os_print_error(err, "Mapping memory");
12445 + bootmap_size = init_bootmem(pfn, pfn + delta);
12446 + free_bootmem(__pa(reserve_end) + bootmap_size,
12447 + len - bootmap_size - reserve);
12450 +int phys_mapping(unsigned long phys, __u64 *offset_out)
12452 + struct phys_desc *desc = find_virtmem_hash(&virtmem_hash,
12453 + __va(phys & PAGE_MASK));
12456 + if(desc != NULL){
12458 + *offset_out = desc->offset;
12460 + else if(phys < physmem_size){
12462 + *offset_out = phys;
12464 + else if(phys < __pa(end_iomem)){
12465 + struct iomem_region *region = iomem_regions;
12467 + while(region != NULL){
12468 + if((phys >= region->phys) &&
12469 + (phys < region->phys + region->size)){
12471 + *offset_out = phys - region->phys;
12474 + region = region->next;
12477 + else if(phys < __pa(end_iomem) + highmem){
12479 + *offset_out = phys - iomem_size;
12485 +static int __init uml_mem_setup(char *line, int *add)
12488 + physmem_size = memparse(line,&retptr);
12491 +__uml_setup("mem=", uml_mem_setup,
12492 +"mem=<Amount of desired ram>\n"
12493 +" This controls how much \"physical\" memory the kernel allocates\n"
12494 +" for the system. The size is specified as a number followed by\n"
12495 +" one of 'k', 'K', 'm', 'M', which have the obvious meanings.\n"
12496 +" This is not related to the amount of memory in the host. It can\n"
12497 +" be more, and the excess, if it's ever used, will just be swapped out.\n"
12498 +" Example: mem=64M\n\n"
12501 +unsigned long find_iomem(char *driver, unsigned long *len_out)
12503 + struct iomem_region *region = iomem_regions;
12505 + while(region != NULL){
12506 + if(!strcmp(region->driver, driver)){
12507 + *len_out = region->size;
12508 + return(region->virt);
12515 +int setup_iomem(void)
12517 + struct iomem_region *region = iomem_regions;
12518 + unsigned long iomem_start = high_physmem + PAGE_SIZE;
12521 + while(region != NULL){
12522 + err = os_map_memory((void *) iomem_start, region->fd, 0,
12523 + region->size, 1, 1, 0);
12525 + printk("Mapping iomem region for driver '%s' failed, "
12526 + "errno = %d\n", region->driver, -err);
12528 + region->virt = iomem_start;
12529 + region->phys = __pa(region->virt);
12532 + iomem_start += region->size + PAGE_SIZE;
12533 + region = region->next;
12539 +__initcall(setup_iomem);
12542 + * Overrides for Emacs so that we follow Linus's tabbing style.
12543 + * Emacs will notice this stuff at the end of the file and automatically
12544 + * adjust the settings for this buffer only. This must remain at the end
12546 + * ---------------------------------------------------------------------------
12547 + * Local variables:
12548 + * c-file-style: "linux"
12551 Index: uml-2.6.7/arch/um/kernel/irq_user.c
12552 ===================================================================
12553 --- uml-2.6.7.orig/arch/um/kernel/irq_user.c 2004-07-16 19:36:33.534048512 +0300
12554 +++ uml-2.6.7/arch/um/kernel/irq_user.c 2004-07-16 19:47:23.717205648 +0300
12556 #include <stdlib.h>
12557 #include <unistd.h>
12559 -#include <fcntl.h>
12560 #include <signal.h>
12561 #include <string.h>
12562 #include <sys/poll.h>
12565 if(smp_sigio_handler()) return;
12567 - if((n = poll(pollfds, pollfds_num, 0)) < 0){
12568 + n = poll(pollfds, pollfds_num, 0);
12570 if(errno == EINTR) continue;
12571 printk("sigio_handler : poll returned %d, "
12572 "errno = %d\n", n, errno);
12573 @@ -366,34 +366,31 @@
12575 void forward_ipi(int fd, int pid)
12577 - if(fcntl(fd, F_SETOWN, pid) < 0){
12578 - int save_errno = errno;
12579 - if(fcntl(fd, F_GETOWN, 0) != pid){
12580 - printk("forward_ipi: F_SETOWN failed, fd = %d, "
12581 - "me = %d, target = %d, errno = %d\n", fd,
12582 - os_getpid(), pid, save_errno);
12587 + err = os_set_owner(fd, pid);
12589 + printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
12590 + "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
12593 void forward_interrupts(int pid)
12595 struct irq_fd *irq;
12596 unsigned long flags;
12599 flags = irq_lock();
12600 for(irq=active_fds;irq != NULL;irq = irq->next){
12601 - if(fcntl(irq->fd, F_SETOWN, pid) < 0){
12602 - int save_errno = errno;
12603 - if(fcntl(irq->fd, F_GETOWN, 0) != pid){
12604 - /* XXX Just remove the irq rather than
12605 - * print out an infinite stream of these
12607 - printk("Failed to forward %d to pid %d, "
12608 - "errno = %d\n", irq->fd, pid,
12611 + err = os_set_owner(irq->fd, pid);
12613 + /* XXX Just remove the irq rather than
12614 + * print out an infinite stream of these
12616 + printk("Failed to forward %d to pid %d, err = %d\n",
12617 + irq->fd, pid, -err);
12623 Index: uml-2.6.7/arch/um/include/line.h
12624 ===================================================================
12625 --- uml-2.6.7.orig/arch/um/include/line.h 2004-07-16 19:37:13.937906192 +0300
12626 +++ uml-2.6.7/arch/um/include/line.h 2004-07-16 19:47:23.702207928 +0300
12628 #include "linux/list.h"
12629 #include "linux/workqueue.h"
12630 #include "linux/tty.h"
12631 +#include "linux/interrupt.h"
12632 #include "asm/semaphore.h"
12633 #include "chan_user.h"
12634 #include "mconsole_kern.h"
12636 struct line_driver {
12638 + char *device_name;
12644 #define LINES_INIT(n) { num : n }
12646 -extern void line_interrupt(int irq, void *data, struct pt_regs *unused);
12647 -extern void line_write_interrupt(int irq, void *data, struct pt_regs *unused);
12648 extern void line_close(struct line *lines, struct tty_struct *tty);
12649 extern int line_open(struct line *lines, struct tty_struct *tty,
12650 struct chan_opts *opts);
12651 Index: uml-2.6.7/arch/um/sys-i386/fault.c
12652 ===================================================================
12653 --- uml-2.6.7.orig/arch/um/sys-i386/fault.c 2004-07-16 19:36:42.987611352 +0300
12654 +++ uml-2.6.7/arch/um/sys-i386/fault.c 2004-07-16 19:47:23.771197440 +0300
12657 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
12658 + * Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com)
12659 * Licensed under the GPL
12663 #include "sysdep/ptrace.h"
12664 #include "sysdep/sigcontext.h"
12666 -extern unsigned long search_exception_table(unsigned long addr);
12667 +/* These two are from asm-um/uaccess.h and linux/module.h, check them. */
12668 +struct exception_table_entry
12670 + unsigned long insn;
12671 + unsigned long fixup;
12674 +const struct exception_table_entry *search_exception_tables(unsigned long add);
12676 +/* Compare this to arch/i386/mm/extable.c:fixup_exception() */
12677 int arch_fixup(unsigned long address, void *sc_ptr)
12679 struct sigcontext *sc = sc_ptr;
12680 - unsigned long fixup;
12681 + const struct exception_table_entry *fixup;
12683 fixup = search_exception_tables(address);
12686 + sc->eip = fixup->fixup;
12690 Index: uml-2.6.7/arch/um/kernel/smp.c
12691 ===================================================================
12692 --- uml-2.6.7.orig/arch/um/kernel/smp.c 2004-07-16 19:36:13.630074376 +0300
12693 +++ uml-2.6.7/arch/um/kernel/smp.c 2004-07-16 19:47:23.736202760 +0300
12696 - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
12697 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
12698 * Licensed under the GPL
12701 #include "linux/config.h"
12702 +#include "linux/percpu.h"
12703 +#include "asm/pgalloc.h"
12704 +#include "asm/tlb.h"
12706 +/* For some reason, mmu_gathers are referenced when CONFIG_SMP is off. */
12707 +DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
12714 /* CPU online map, set by smp_boot_cpus */
12715 -unsigned long cpu_online_map = cpumask_of_cpu(0);
12716 +unsigned long cpu_online_map = CPU_MASK_NONE;
12718 EXPORT_SYMBOL(cpu_online_map);
12722 void smp_send_reschedule(int cpu)
12724 - write(cpu_data[cpu].ipi_pipe[1], "R", 1);
12725 + os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1);
12726 num_reschedules_sent++;
12729 @@ -100,35 +106,34 @@
12731 printk(KERN_INFO "Stopping all CPUs...");
12732 for(i = 0; i < num_online_cpus(); i++){
12733 - if(i == current->thread_info->cpu)
12734 + if(i == current_thread->cpu)
12736 - write(cpu_data[i].ipi_pipe[1], "S", 1);
12737 + os_write_file(cpu_data[i].ipi_pipe[1], "S", 1);
12742 -static cpumask_t smp_commenced_mask;
12743 -static cpumask_t smp_callin_map = CPU_MASK_NONE;
12744 +static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
12745 +static cpumask_t cpu_callin_map = CPU_MASK_NONE;
12747 static int idle_proc(void *cpup)
12749 int cpu = (int) cpup, err;
12751 err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
12753 - panic("CPU#%d failed to create IPI pipe, errno = %d", cpu,
12756 + panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);
12758 activate_ipi(cpu_data[cpu].ipi_pipe[0],
12759 current->thread.mode.tt.extern_pid);
12762 - if (cpu_test_and_set(cpu, &smp_callin_map)) {
12763 + if (cpu_test_and_set(cpu, cpu_callin_map)) {
12764 printk("huh, CPU#%d already present??\n", cpu);
12768 - while (!cpu_isset(cpu, &smp_commenced_mask))
12769 + while (!cpu_isset(cpu, smp_commenced_mask))
12772 cpu_set(cpu, cpu_online_map);
12773 @@ -143,16 +148,20 @@
12775 current->thread.request.u.thread.proc = idle_proc;
12776 current->thread.request.u.thread.arg = (void *) cpu;
12777 - new_task = do_fork(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, NULL);
12778 - if(IS_ERR(new_task)) panic("do_fork failed in idle_thread");
12779 + new_task = copy_process(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL,
12781 + if(IS_ERR(new_task))
12782 + panic("copy_process failed in idle_thread, error = %ld",
12783 + PTR_ERR(new_task));
12785 cpu_tasks[cpu] = ((struct cpu_task)
12786 { .pid = new_task->thread.mode.tt.extern_pid,
12787 .task = new_task } );
12788 idle_threads[cpu] = new_task;
12789 - CHOOSE_MODE(write(new_task->thread.mode.tt.switch_pipe[1], &c,
12790 + CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c,
12792 ({ panic("skas mode doesn't support SMP"); }));
12793 + wake_up_forked_process(new_task);
12797 @@ -160,15 +169,17 @@
12799 struct task_struct *idle;
12800 unsigned long waittime;
12802 + int err, cpu, me = smp_processor_id();
12804 - cpu_set(0, cpu_online_map);
12805 - cpu_set(0, smp_callin_map);
12806 + cpu_clear(me, cpu_online_map);
12807 + cpu_set(me, cpu_online_map);
12808 + cpu_set(me, cpu_callin_map);
12810 - err = os_pipe(cpu_data[0].ipi_pipe, 1, 1);
12811 - if(err) panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
12812 + err = os_pipe(cpu_data[me].ipi_pipe, 1, 1);
12814 + panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
12816 - activate_ipi(cpu_data[0].ipi_pipe[0],
12817 + activate_ipi(cpu_data[me].ipi_pipe[0],
12818 current->thread.mode.tt.extern_pid);
12820 for(cpu = 1; cpu < ncpus; cpu++){
12821 @@ -180,10 +191,10 @@
12822 unhash_process(idle);
12824 waittime = 200000000;
12825 - while (waittime-- && !cpu_isset(cpu, smp_callin_map))
12826 + while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
12829 - if (cpu_isset(cpu, smp_callin_map))
12830 + if (cpu_isset(cpu, cpu_callin_map))
12832 else printk("failed\n");
12834 @@ -216,7 +227,7 @@
12837 fd = cpu_data[cpu].ipi_pipe[0];
12838 - while (read(fd, &c, 1) == 1) {
12839 + while (os_read_file(fd, &c, 1) == 1) {
12842 smp_call_function_slave(cpu);
12843 @@ -276,9 +287,9 @@
12846 for (i=0;i<NR_CPUS;i++)
12847 - if((i != current->thread_info->cpu) &&
12848 + if((i != current_thread->cpu) &&
12849 cpu_isset(i, cpu_online_map))
12850 - write(cpu_data[i].ipi_pipe[1], "C", 1);
12851 + os_write_file(cpu_data[i].ipi_pipe[1], "C", 1);
12853 while (atomic_read(&scf_started) != cpus)
12855 Index: uml-2.6.7/arch/um/drivers/slip_user.c
12856 ===================================================================
12857 --- uml-2.6.7.orig/arch/um/drivers/slip_user.c 2004-07-16 19:37:26.082060000 +0300
12858 +++ uml-2.6.7/arch/um/drivers/slip_user.c 2004-07-16 19:47:24.797041488 +0300
12860 #include <stddef.h>
12862 #include <string.h>
12863 -#include <sys/fcntl.h>
12864 -#include <sys/errno.h>
12865 +#include <errno.h>
12866 #include <sys/termios.h>
12867 #include <sys/wait.h>
12868 -#include <sys/ioctl.h>
12869 #include <sys/signal.h>
12870 #include "user_util.h"
12871 #include "kern_util.h"
12874 struct slip_pre_exec_data *data = arg;
12876 - if(data->stdin != -1) dup2(data->stdin, 0);
12877 + if(data->stdin >= 0) dup2(data->stdin, 0);
12878 dup2(data->stdout, 1);
12879 - if(data->close_me != -1) close(data->close_me);
12880 + if(data->close_me >= 0) os_close_file(data->close_me);
12883 static int slip_tramp(char **argv, int fd)
12885 int status, pid, fds[2], err, output_len;
12887 err = os_pipe(fds, 1, 0);
12889 - printk("slip_tramp : pipe failed, errno = %d\n", -err);
12891 + printk("slip_tramp : pipe failed, err = %d\n", -err);
12895 @@ -96,16 +94,18 @@
12896 printk("slip_tramp : failed to allocate output "
12900 + os_close_file(fds[1]);
12901 read_output(fds[0], output, output_len);
12902 if(output != NULL){
12903 printk("%s", output);
12906 - if(waitpid(pid, &status, 0) < 0) err = errno;
12907 + CATCH_EINTR(err = waitpid(pid, &status, 0));
12910 else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
12911 printk("'%s' didn't exit with status 0\n", argv[0]);
12917 @@ -118,15 +118,17 @@
12918 char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
12919 char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf,
12921 - int sfd, mfd, disc, sencap, err;
12922 + int sfd, mfd, err;
12924 - if((mfd = get_pty()) < 0){
12925 - printk("umn : Failed to open pty\n");
12929 + printk("umn : Failed to open pty, err = %d\n", -mfd);
12932 - if((sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0)) < 0){
12933 - printk("Couldn't open tty for slip line\n");
12935 + sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
12937 + printk("Couldn't open tty for slip line, err = %d\n", -sfd);
12940 if(set_up_tty(sfd)) return(-1);
12942 @@ -138,28 +140,23 @@
12944 err = slip_tramp(argv, sfd);
12947 - printk("slip_tramp failed - errno = %d\n", err);
12950 + printk("slip_tramp failed - err = %d\n", -err);
12953 - if(ioctl(pri->slave, SIOCGIFNAME, pri->name) < 0){
12954 - printk("SIOCGIFNAME failed, errno = %d\n", errno);
12956 + err = os_get_ifname(pri->slave, pri->name);
12958 + printk("get_ifname failed, err = %d\n", -err);
12961 iter_addresses(pri->dev, open_addr, pri->name);
12965 - if(ioctl(sfd, TIOCSETD, &disc) < 0){
12966 - printk("Failed to set slip line discipline - "
12967 - "errno = %d\n", errno);
12971 - if(ioctl(sfd, SIOCSIFENCAP, &sencap) < 0){
12972 - printk("Failed to set slip encapsulation - "
12973 - "errno = %d\n", errno);
12975 + err = os_set_slip(sfd);
12977 + printk("Failed to set slip discipline encapsulation - "
12978 + "err = %d\n", -err);
12983 @@ -181,9 +178,9 @@
12984 err = slip_tramp(argv, -1);
12987 - printk("slip_tramp failed - errno = %d\n", err);
12989 - close(pri->slave);
12990 + printk("slip_tramp failed - errno = %d\n", -err);
12991 + os_close_file(fd);
12992 + os_close_file(pri->slave);
12996 @@ -243,7 +240,7 @@
12998 struct slip_data *pri = data;
13000 - if(pri->slave == -1) return;
13001 + if(pri->slave < 0) return;
13002 open_addr(addr, netmask, pri->name);
13005 @@ -252,7 +249,7 @@
13007 struct slip_data *pri = data;
13009 - if(pri->slave == -1) return;
13010 + if(pri->slave < 0) return;
13011 close_addr(addr, netmask, pri->name);
13014 Index: uml-2.6.7/fs/hostfs/hostfs.h
13015 ===================================================================
13016 --- uml-2.6.7.orig/fs/hostfs/hostfs.h 2004-07-16 19:47:23.631218720 +0300
13017 +++ uml-2.6.7/fs/hostfs/hostfs.h 2004-07-16 19:47:23.781195920 +0300
13019 +#ifndef __UM_FS_HOSTFS
13020 +#define __UM_FS_HOSTFS
13024 +/* These are exactly the same definitions as in fs.h, but the names are
13025 + * changed so that this file can be included in both kernel and user files.
13028 +#define HOSTFS_ATTR_MODE 1
13029 +#define HOSTFS_ATTR_UID 2
13030 +#define HOSTFS_ATTR_GID 4
13031 +#define HOSTFS_ATTR_SIZE 8
13032 +#define HOSTFS_ATTR_ATIME 16
13033 +#define HOSTFS_ATTR_MTIME 32
13034 +#define HOSTFS_ATTR_CTIME 64
13035 +#define HOSTFS_ATTR_ATIME_SET 128
13036 +#define HOSTFS_ATTR_MTIME_SET 256
13037 +#define HOSTFS_ATTR_FORCE 512 /* Not a change, but a change it */
13038 +#define HOSTFS_ATTR_ATTR_FLAG 1024
13040 +struct hostfs_iattr {
13041 + unsigned int ia_valid;
13046 + struct timespec ia_atime;
13047 + struct timespec ia_mtime;
13048 + struct timespec ia_ctime;
13049 + unsigned int ia_attr_flags;
13052 +extern int stat_file(const char *path, unsigned long long *inode_out,
13053 + int *mode_out, int *nlink_out, int *uid_out, int *gid_out,
13054 + unsigned long long *size_out, struct timespec *atime_out,
13055 + struct timespec *mtime_out, struct timespec *ctime_out,
13056 + int *blksize_out, unsigned long long *blocks_out);
13057 +extern int access_file(char *path, int r, int w, int x);
13058 +extern int open_file(char *path, int r, int w, int append);
13059 +extern int file_type(const char *path, int *rdev);
13060 +extern void *open_dir(char *path, int *err_out);
13061 +extern char *read_dir(void *stream, unsigned long long *pos,
13062 + unsigned long long *ino_out, int *len_out);
13063 +extern void close_file(void *stream);
13064 +extern void close_dir(void *stream);
13065 +extern int read_file(int fd, unsigned long long *offset, char *buf, int len);
13066 +extern int write_file(int fd, unsigned long long *offset, const char *buf,
13068 +extern int lseek_file(int fd, long long offset, int whence);
13069 +extern int file_create(char *name, int ur, int uw, int ux, int gr,
13070 + int gw, int gx, int or, int ow, int ox);
13071 +extern int set_attr(const char *file, struct hostfs_iattr *attrs);
13072 +extern int make_symlink(const char *from, const char *to);
13073 +extern int unlink_file(const char *file);
13074 +extern int do_mkdir(const char *file, int mode);
13075 +extern int do_rmdir(const char *file);
13076 +extern int do_mknod(const char *file, int mode, int dev);
13077 +extern int link_file(const char *from, const char *to);
13078 +extern int do_readlink(char *file, char *buf, int size);
13079 +extern int rename_file(char *from, char *to);
13080 +extern int do_statfs(char *root, long *bsize_out, long long *blocks_out,
13081 + long long *bfree_out, long long *bavail_out,
13082 + long long *files_out, long long *ffree_out,
13083 + void *fsid_out, int fsid_size, long *namelen_out,
13084 + long *spare_out);
13089 + * Overrides for Emacs so that we follow Linus's tabbing style.
13090 + * Emacs will notice this stuff at the end of the file and automatically
13091 + * adjust the settings for this buffer only. This must remain at the end
13093 + * ---------------------------------------------------------------------------
13094 + * Local variables:
13095 + * c-file-style: "linux"
13098 Index: uml-2.6.7/arch/um/kernel/sigio_user.c
13099 ===================================================================
13100 --- uml-2.6.7.orig/arch/um/kernel/sigio_user.c 2004-07-16 19:37:38.307201496 +0300
13101 +++ uml-2.6.7/arch/um/kernel/sigio_user.c 2004-07-16 19:47:24.458093016 +0300
13103 #include <stdlib.h>
13104 #include <termios.h>
13106 -#include <fcntl.h>
13107 #include <signal.h>
13109 #include <string.h>
13113 #include "kern_util.h"
13114 +#include "user_util.h"
13116 #include "helper.h"
13119 int pty_close_sigio = 0;
13121 /* Used as a flag during SIGIO testing early in boot */
13122 -static int got_sigio = 0;
13123 +static volatile int got_sigio = 0;
13125 void __init handler(int sig)
13127 @@ -45,19 +45,18 @@
13130 if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
13131 - info->err = errno;
13132 + info->err = -errno;
13135 void __init check_one_sigio(void (*proc)(int, int))
13137 struct sigaction old, new;
13138 - struct termios tt;
13139 struct openpty_arg pty = { .master = -1, .slave = -1 };
13140 - int master, slave, flags;
13141 + int master, slave, err;
13143 initial_thread_cb(openpty_cb, &pty);
13145 - printk("openpty failed, errno = %d\n", pty.err);
13146 + printk("openpty failed, errno = %d\n", -pty.err);
13150 @@ -69,23 +68,13 @@
13154 - if(tcgetattr(master, &tt) < 0)
13155 - panic("check_sigio : tcgetattr failed, errno = %d\n", errno);
13157 - if(tcsetattr(master, TCSADRAIN, &tt) < 0)
13158 - panic("check_sigio : tcsetattr failed, errno = %d\n", errno);
13160 - if((flags = fcntl(master, F_GETFL)) < 0)
13161 - panic("tty_fds : fcntl F_GETFL failed, errno = %d\n", errno);
13163 - if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
13164 - (fcntl(master, F_SETOWN, os_getpid()) < 0))
13165 - panic("check_sigio : fcntl F_SETFL or F_SETOWN failed, "
13166 - "errno = %d\n", errno);
13168 - if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
13169 - panic("check_sigio : fcntl F_SETFL failed, errno = %d\n",
13171 + err = __raw(master, 1, 0); //Not now, but complain so we now where we failed.
13173 + panic("check_sigio : __raw failed, errno = %d\n", -err);
13175 + err = os_sigio_async(master, slave);
13177 + panic("tty_fds : sigio_async failed, err = %d\n", -err);
13179 if(sigaction(SIGIO, NULL, &old) < 0)
13180 panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
13183 (*proc)(master, slave);
13187 + os_close_file(master);
13188 + os_close_file(slave);
13190 if(sigaction(SIGIO, &old, NULL) < 0)
13191 panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
13192 @@ -112,25 +101,25 @@
13193 printk("Checking that host ptys support output SIGIO...");
13195 memset(buf, 0, sizeof(buf));
13196 - while(write(master, buf, sizeof(buf)) > 0) ;
13198 + while(os_write_file(master, buf, sizeof(buf)) > 0) ;
13199 if(errno != EAGAIN)
13200 panic("check_sigio : write failed, errno = %d\n", errno);
13202 - while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
13203 + while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
13207 pty_output_sigio = 1;
13209 - else if(errno == EAGAIN) printk("No, enabling workaround\n");
13210 - else panic("check_sigio : read failed, errno = %d\n", errno);
13211 + else if(n == -EAGAIN) printk("No, enabling workaround\n");
13212 + else panic("check_sigio : read failed, err = %d\n", n);
13215 static void tty_close(int master, int slave)
13217 printk("Checking that host ptys support SIGIO on close...");
13220 + os_close_file(slave);
13223 pty_close_sigio = 1;
13224 @@ -140,7 +129,8 @@
13226 void __init check_sigio(void)
13228 - if(access("/dev/ptmx", R_OK) && access("/dev/ptyp0", R_OK)){
13229 + if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
13230 + (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
13231 printk("No pseudo-terminals available - skipping pty SIGIO "
13234 @@ -201,11 +191,10 @@
13236 if(p->revents == 0) continue;
13237 if(p->fd == sigio_private[1]){
13238 - n = read(sigio_private[1], &c, sizeof(c));
13239 + n = os_read_file(sigio_private[1], &c, sizeof(c));
13241 printk("write_sigio_thread : "
13242 - "read failed, errno = %d\n",
13244 + "read failed, err = %d\n", -n);
13245 tmp = current_poll;
13246 current_poll = next_poll;
13248 @@ -218,10 +207,10 @@
13249 (fds->used - i) * sizeof(*fds->poll));
13252 - n = write(respond_fd, &c, sizeof(c));
13253 + n = os_write_file(respond_fd, &c, sizeof(c));
13255 printk("write_sigio_thread : write failed, "
13256 - "errno = %d\n", errno);
13257 + "err = %d\n", -n);
13261 @@ -252,15 +241,15 @@
13264 flags = set_signals(0);
13265 - n = write(sigio_private[0], &c, sizeof(c));
13266 + n = os_write_file(sigio_private[0], &c, sizeof(c));
13267 if(n != sizeof(c)){
13268 - printk("update_thread : write failed, errno = %d\n", errno);
13269 + printk("update_thread : write failed, err = %d\n", -n);
13273 - n = read(sigio_private[0], &c, sizeof(c));
13274 + n = os_read_file(sigio_private[0], &c, sizeof(c));
13275 if(n != sizeof(c)){
13276 - printk("update_thread : read failed, errno = %d\n", errno);
13277 + printk("update_thread : read failed, err = %d\n", -n);
13281 @@ -271,10 +260,10 @@
13282 if(write_sigio_pid != -1)
13283 os_kill_process(write_sigio_pid, 1);
13284 write_sigio_pid = -1;
13285 - close(sigio_private[0]);
13286 - close(sigio_private[1]);
13287 - close(write_sigio_fds[0]);
13288 - close(write_sigio_fds[1]);
13289 + os_close_file(sigio_private[0]);
13290 + os_close_file(sigio_private[1]);
13291 + os_close_file(write_sigio_fds[0]);
13292 + os_close_file(write_sigio_fds[1]);
13294 set_signals(flags);
13296 @@ -369,15 +358,15 @@
13299 err = os_pipe(write_sigio_fds, 1, 1);
13302 printk("write_sigio_workaround - os_pipe 1 failed, "
13303 - "errno = %d\n", -err);
13304 + "err = %d\n", -err);
13307 err = os_pipe(sigio_private, 1, 1);
13310 printk("write_sigio_workaround - os_pipe 2 failed, "
13311 - "errno = %d\n", -err);
13312 + "err = %d\n", -err);
13315 if(setup_initial_poll(sigio_private[1]))
13316 @@ -399,11 +388,11 @@
13317 os_kill_process(write_sigio_pid, 1);
13318 write_sigio_pid = -1;
13320 - close(sigio_private[0]);
13321 - close(sigio_private[1]);
13322 + os_close_file(sigio_private[0]);
13323 + os_close_file(sigio_private[1]);
13325 - close(write_sigio_fds[0]);
13326 - close(write_sigio_fds[1]);
13327 + os_close_file(write_sigio_fds[0]);
13328 + os_close_file(write_sigio_fds[1]);
13332 @@ -412,10 +401,16 @@
13336 - n = read(fd, &c, sizeof(c));
13337 + n = os_read_file(fd, &c, sizeof(c));
13338 if(n != sizeof(c)){
13339 - printk("read_sigio_fd - read failed, errno = %d\n", errno);
13342 + printk("read_sigio_fd - read failed, err = %d\n", -n);
13346 + printk("read_sigio_fd - short read, bytes = %d\n", n);
13352 Index: uml-2.6.7/include/asm-um/system-i386.h
13353 ===================================================================
13354 --- uml-2.6.7.orig/include/asm-um/system-i386.h 2004-07-16 19:36:25.160321512 +0300
13355 +++ uml-2.6.7/include/asm-um/system-i386.h 2004-07-16 19:47:23.802192728 +0300
13357 #define __UM_SYSTEM_I386_H
13359 #include "asm/system-generic.h"
13361 -static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
13362 - unsigned long new, int size)
13364 - unsigned long prev;
13367 - __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
13369 - : "q"(new), "m"(*__xg(ptr)), "0"(old)
13373 - __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
13375 - : "q"(new), "m"(*__xg(ptr)), "0"(old)
13379 - __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
13381 - : "q"(new), "m"(*__xg(ptr)), "0"(old)
13388 -#define cmpxchg(ptr,o,n)\
13389 - ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
13390 - (unsigned long)(n),sizeof(*(ptr))))
13393 Index: uml-2.6.7/arch/um/sys-i386/time.c
13394 ===================================================================
13395 --- uml-2.6.7.orig/arch/um/sys-i386/time.c 2004-07-16 19:47:23.629219024 +0300
13396 +++ uml-2.6.7/arch/um/sys-i386/time.c 2004-07-16 19:47:23.773197136 +0300
13399 + * sys-i386/time.c
13400 + * Created 25.9.2002 Sapan Bhatia
13404 +unsigned long long time_stamp(void)
13406 + unsigned long low, high;
13408 + asm("rdtsc" : "=a" (low), "=d" (high));
13409 + return((((unsigned long long) high) << 32) + low);
13413 + * Overrides for Emacs so that we follow Linus's tabbing style.
13414 + * Emacs will notice this stuff at the end of the file and automatically
13415 + * adjust the settings for this buffer only. This must remain at the end
13417 + * ---------------------------------------------------------------------------
13418 + * Local variables:
13419 + * c-file-style: "linux"
13422 Index: uml-2.6.7/arch/um/Makefile-i386
13423 ===================================================================
13424 --- uml-2.6.7.orig/arch/um/Makefile-i386 2004-07-16 19:37:17.426375864 +0300
13425 +++ uml-2.6.7/arch/um/Makefile-i386 2004-07-16 19:47:23.764198504 +0300
13426 @@ -16,22 +16,27 @@
13428 SYS_HEADERS = $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
13430 +sys_prepare: $(SYS_DIR)/sc.h
13432 prepare: $(SYS_HEADERS)
13434 +filechk_$(SYS_DIR)/sc.h := $(SYS_UTIL_DIR)/mk_sc
13436 $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
13438 + $(call filechk,$@)
13440 +filechk_$(SYS_DIR)/thread.h := $(SYS_UTIL_DIR)/mk_thread
13442 $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
13444 + $(call filechk,$@)
13446 -$(SYS_UTIL_DIR)/mk_sc: FORCE ;
13447 - @$(call descend,$(SYS_UTIL_DIR),$@)
13448 +$(SYS_UTIL_DIR)/mk_sc: scripts/basic/fixdep include/config/MARKER FORCE ;
13449 + $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
13451 -$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE ;
13452 - @$(call descend,$(SYS_UTIL_DIR),$@)
13453 +$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) sys_prepare FORCE ;
13454 + $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
13456 $(SYS_UTIL_DIR): include/asm FORCE
13457 - @$(call descend,$@,)
13458 + $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR)
13461 - rm -f $(SYS_HEADERS)
13462 +CLEAN_FILES += $(SYS_HEADERS)
13463 Index: uml-2.6.7/include/asm-um/smp.h
13464 ===================================================================
13465 --- uml-2.6.7.orig/include/asm-um/smp.h 2004-07-16 19:35:49.282775728 +0300
13466 +++ uml-2.6.7/include/asm-um/smp.h 2004-07-16 19:47:23.795193792 +0300
13469 extern cpumask_t cpu_online_map;
13471 -#define smp_processor_id() (current->thread_info->cpu)
13472 +#define smp_processor_id() (current_thread->cpu)
13473 #define cpu_logical_map(n) (n)
13474 #define cpu_number_map(n) (n)
13475 #define PROC_CHANGE_PENALTY 15 /* Pick a number, any number */
13476 Index: uml-2.6.7/arch/um/Kconfig_block
13477 ===================================================================
13478 --- uml-2.6.7.orig/arch/um/Kconfig_block 2004-07-16 19:37:05.104249112 +0300
13479 +++ uml-2.6.7/arch/um/Kconfig_block 2004-07-16 19:47:23.711206560 +0300
13481 wise choice too. In all other cases (for example, if you're just
13482 playing around with User-Mode Linux) you can choose N.
13484 +# Turn this back on when the driver actually works
13486 +#config BLK_DEV_COW
13487 +# tristate "COW block device"
13489 +# This is a layered driver which sits above two other block devices.
13490 +# One is read-only, and the other is a read-write layer which stores
13491 +# all changes. This provides the illusion that the read-only layer
13492 +# can be mounted read-write and changed.
13494 +config BLK_DEV_COW_COMMON
13496 + default BLK_DEV_COW || BLK_DEV_UBD
13498 config BLK_DEV_LOOP
13499 tristate "Loopback device support"
13501 Index: uml-2.6.7/arch/um/kernel/initrd_user.c
13502 ===================================================================
13503 --- uml-2.6.7.orig/arch/um/kernel/initrd_user.c 2004-07-16 19:36:07.784962968 +0300
13504 +++ uml-2.6.7/arch/um/kernel/initrd_user.c 2004-07-16 19:47:23.715205952 +0300
13506 #include <unistd.h>
13507 #include <sys/types.h>
13508 #include <sys/stat.h>
13509 -#include <fcntl.h>
13512 #include "user_util.h"
13513 @@ -19,13 +18,15 @@
13517 - if((fd = os_open_file(filename, of_read(OPENFLAGS()), 0)) < 0){
13518 - printk("Opening '%s' failed - errno = %d\n", filename, errno);
13519 + fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
13521 + printk("Opening '%s' failed - err = %d\n", filename, -fd);
13524 - if((n = read(fd, buf, size)) != size){
13525 - printk("Read of %d bytes from '%s' returned %d, errno = %d\n",
13526 - size, filename, n, errno);
13527 + n = os_read_file(fd, buf, size);
13529 + printk("Read of %d bytes from '%s' failed, err = %d\n", size,
13534 Index: uml-2.6.7/arch/um/include/sysdep-i386/frame_user.h
13535 ===================================================================
13536 --- uml-2.6.7.orig/arch/um/include/sysdep-i386/frame_user.h 2004-07-16 19:37:34.631760248 +0300
13537 +++ uml-2.6.7/arch/um/include/sysdep-i386/frame_user.h 2004-07-16 19:47:23.707207168 +0300
13538 @@ -56,26 +56,26 @@
13539 * it would have to be __builtin_frame_address(1).
13542 -static inline unsigned long frame_restorer(void)
13544 - unsigned long *fp;
13546 - fp = __builtin_frame_address(0);
13547 - return((unsigned long) (fp + 1));
13549 +#define frame_restorer() \
13551 + unsigned long *fp; \
13553 + fp = __builtin_frame_address(0); \
13554 + ((unsigned long) (fp + 1)); \
13557 /* Similarly, this returns the value of sp when the handler was first
13558 * entered. This is used to calculate the proper sp when delivering
13562 -static inline unsigned long frame_sp(void)
13564 - unsigned long *fp;
13566 - fp = __builtin_frame_address(0);
13567 - return((unsigned long) (fp + 1));
13569 +#define frame_sp() \
13571 + unsigned long *fp; \
13573 + fp = __builtin_frame_address(0); \
13574 + ((unsigned long) (fp + 1)); \
13579 Index: uml-2.6.7/arch/um/drivers/tty.c
13580 ===================================================================
13581 --- uml-2.6.7.orig/arch/um/drivers/tty.c 2004-07-16 19:36:25.316297800 +0300
13582 +++ uml-2.6.7/arch/um/drivers/tty.c 2004-07-16 19:47:23.695208992 +0300
13586 #include <termios.h>
13587 -#include <fcntl.h>
13589 #include <unistd.h>
13590 #include "chan_user.h"
13595 - if((data = um_kmalloc(sizeof(*data))) == NULL)
13596 + data = um_kmalloc(sizeof(*data));
13599 *data = ((struct tty_chan) { .dev = str,
13600 .raw = opts->raw });
13601 Index: uml-2.6.7/arch/um/drivers/net_kern.c
13602 ===================================================================
13603 --- uml-2.6.7.orig/arch/um/drivers/net_kern.c 2004-07-16 19:36:37.183493712 +0300
13604 +++ uml-2.6.7/arch/um/drivers/net_kern.c 2004-07-16 19:47:23.689209904 +0300
13606 #include "mconsole_kern.h"
13608 #include "irq_user.h"
13609 +#include "irq_kern.h"
13611 static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
13614 struct sk_buff *skb;
13616 /* If we can't allocate memory, try again next round. */
13617 - if ((skb = dev_alloc_skb(dev->mtu)) == NULL) {
13618 + skb = dev_alloc_skb(dev->mtu);
13619 + if (skb == NULL) {
13620 lp->stats.rx_dropped++;
13623 @@ -61,14 +63,14 @@
13627 -void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
13628 +irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
13630 struct net_device *dev = dev_id;
13631 struct uml_net_private *lp = dev->priv;
13634 if(!netif_running(dev))
13636 + return(IRQ_NONE);
13638 spin_lock(&lp->lock);
13639 while((err = uml_net_rx(dev)) > 0) ;
13643 spin_unlock(&lp->lock);
13644 + return(IRQ_HANDLED);
13647 static int uml_net_open(struct net_device *dev)
13648 @@ -250,37 +253,6 @@
13653 - * default do nothing hard header packet routines for struct net_device init.
13654 - * real ethernet transports will overwrite with real routines.
13656 -static int uml_net_hard_header(struct sk_buff *skb, struct net_device *dev,
13657 - unsigned short type, void *daddr, void *saddr, unsigned len)
13659 - return(0); /* no change */
13662 -static int uml_net_rebuild_header(struct sk_buff *skb)
13664 - return(0); /* ignore */
13667 -static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh)
13669 - return(-1); /* fail */
13672 -static void uml_net_header_cache_update(struct hh_cache *hh,
13673 - struct net_device *dev, unsigned char * haddr)
13678 -static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr)
13680 - return(0); /* nothing */
13683 static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
13684 static struct list_head devices = LIST_HEAD_INIT(devices);
13686 @@ -290,7 +262,7 @@
13687 struct uml_net *device;
13688 struct net_device *dev;
13689 struct uml_net_private *lp;
13691 + int save, err, size;
13693 size = transport->private_size + sizeof(struct uml_net_private) +
13694 sizeof(((struct uml_net_private *) 0)->user);
13695 @@ -332,12 +304,6 @@
13696 snprintf(dev->name, sizeof(dev->name), "eth%d", n);
13699 - dev->hard_header = uml_net_hard_header;
13700 - dev->rebuild_header = uml_net_rebuild_header;
13701 - dev->hard_header_cache = uml_net_header_cache;
13702 - dev->header_cache_update= uml_net_header_cache_update;
13703 - dev->hard_header_parse = uml_net_header_parse;
13705 (*transport->kern->init)(dev, init);
13707 dev->mtu = transport->user->max_packet;
13708 @@ -364,21 +330,29 @@
13712 - INIT_LIST_HEAD(&lp->list);
13713 - spin_lock_init(&lp->lock);
13716 - lp->mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0 };
13717 - lp->have_mac = device->have_mac;
13718 - lp->protocol = transport->kern->protocol;
13719 - lp->open = transport->user->open;
13720 - lp->close = transport->user->close;
13721 - lp->remove = transport->user->remove;
13722 - lp->read = transport->kern->read;
13723 - lp->write = transport->kern->write;
13724 - lp->add_address = transport->user->add_address;
13725 - lp->delete_address = transport->user->delete_address;
13726 - lp->set_mtu = transport->user->set_mtu;
13727 + /* lp.user is the first four bytes of the transport data, which
13728 + * has already been initialized. This structure assignment will
13729 + * overwrite that, so we make sure that .user gets overwritten with
13730 + * what it already has.
13732 + save = lp->user[0];
13733 + *lp = ((struct uml_net_private)
13734 + { .list = LIST_HEAD_INIT(lp->list),
13735 + .lock = SPIN_LOCK_UNLOCKED,
13738 + .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
13739 + .have_mac = device->have_mac,
13740 + .protocol = transport->kern->protocol,
13741 + .open = transport->user->open,
13742 + .close = transport->user->close,
13743 + .remove = transport->user->remove,
13744 + .read = transport->kern->read,
13745 + .write = transport->kern->write,
13746 + .add_address = transport->user->add_address,
13747 + .delete_address = transport->user->delete_address,
13748 + .set_mtu = transport->user->set_mtu,
13749 + .user = { save } });
13751 init_timer(&lp->tl);
13752 lp->tl.function = uml_net_user_timer_expire;
13753 @@ -611,7 +585,8 @@
13754 unregister_netdev(dev);
13756 list_del(&device->list);
13757 - free_netdev(device);
13759 + free_netdev(dev);
13763 Index: uml-2.6.7/arch/um/kernel/tt/syscall_kern.c
13764 ===================================================================
13765 --- uml-2.6.7.orig/arch/um/kernel/tt/syscall_kern.c 2004-07-16 19:35:49.170792752 +0300
13766 +++ uml-2.6.7/arch/um/kernel/tt/syscall_kern.c 2004-07-16 19:47:23.749200784 +0300
13769 - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
13770 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
13771 * Licensed under the GPL
13774 Index: uml-2.6.7/arch/um/kernel/config.c.in
13775 ===================================================================
13776 --- uml-2.6.7.orig/arch/um/kernel/config.c.in 2004-07-16 19:37:08.932667104 +0300
13777 +++ uml-2.6.7/arch/um/kernel/config.c.in 2004-07-16 19:47:23.712206408 +0300
13779 #include <stdlib.h>
13782 -static __initdata char *config = "
13785 +static __initdata char *config = "CONFIG";
13787 static int __init print_config(char *line, int *add)
13789 Index: uml-2.6.7/arch/um/include/mconsole.h
13790 ===================================================================
13791 --- uml-2.6.7.orig/arch/um/include/mconsole.h 2004-07-16 19:36:32.705174520 +0300
13792 +++ uml-2.6.7/arch/um/include/mconsole.h 2004-07-16 19:47:23.703207776 +0300
13793 @@ -41,11 +41,13 @@
13797 +enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC };
13799 struct mconsole_command
13802 void (*handler)(struct mc_request *req);
13803 - int as_interrupt;
13804 + enum mc_context context;
13809 extern void mconsole_cad(struct mc_request *req);
13810 extern void mconsole_stop(struct mc_request *req);
13811 extern void mconsole_go(struct mc_request *req);
13812 +extern void mconsole_log(struct mc_request *req);
13813 +extern void mconsole_proc(struct mc_request *req);
13815 extern int mconsole_get_request(int fd, struct mc_request *req);
13816 extern int mconsole_notify(char *sock_name, int type, const void *data,
13817 Index: uml-2.6.7/arch/um/kernel/Makefile
13818 ===================================================================
13819 --- uml-2.6.7.orig/arch/um/kernel/Makefile 2004-07-16 19:37:05.102249416 +0300
13820 +++ uml-2.6.7/arch/um/kernel/Makefile 2004-07-16 19:47:23.718205496 +0300
13823 obj-y = checksum.o config.o exec_kern.o exitcode.o frame_kern.o frame.o \
13824 helper.o init_task.o irq.o irq_user.o ksyms.o mem.o mem_user.o \
13825 - process.o process_kern.o ptrace.o reboot.o resource.o sigio_user.o \
13826 - sigio_kern.o signal_kern.o signal_user.o smp.o syscall_kern.o \
13827 - syscall_user.o sysrq.o sys_call_table.o tempfile.o time.o \
13828 - time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o \
13829 - umid.o user_syms.o user_util.o
13830 + physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \
13831 + sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \
13832 + syscall_kern.o syscall_user.o sysrq.o sys_call_table.o tempfile.o \
13833 + time.o time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o \
13834 + um_arch.o umid.o user_util.o
13836 obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
13837 obj-$(CONFIG_GPROF) += gprof_syms.o
13838 @@ -24,43 +24,27 @@
13839 user-objs-$(CONFIG_TTY_LOG) += tty_log.o
13841 USER_OBJS := $(filter %_user.o,$(obj-y)) $(user-objs-y) config.o helper.o \
13842 - process.o tempfile.o time.o tty_log.o umid.o user_util.o user_syms.o
13843 + process.o tempfile.o time.o tty_log.o umid.o user_util.o
13844 USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
13846 -DMODULES-$(CONFIG_MODULES) = -D__CONFIG_MODULES__
13847 -DMODVERSIONS-$(CONFIG_MODVERSIONS) = -D__CONFIG_MODVERSIONS__
13850 -CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES-y) $(DMODVERSIONS-y) \
13851 - -I/usr/include -I../include
13853 CFLAGS_frame.o := $(patsubst -fomit-frame-pointer,,$(USER_CFLAGS))
13855 -$(USER_OBJS) : %.o: %.c
13856 - $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
13858 # This has to be separate because it needs be compiled with frame pointers
13859 # regardless of how the rest of the kernel is built.
13861 $(obj)/frame.o: $(src)/frame.c
13862 $(CC) $(CFLAGS_$(notdir $@)) -c -o $@ $<
13864 -QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
13865 +$(USER_OBJS) : %.o: %.c
13866 + $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
13868 -$(obj)/config.c : $(src)/config.c.in $(TOPDIR)/.config
13869 - $(PERL) -e $(QUOTE) < $(src)/config.c.in > $@
13870 +QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
13872 $(obj)/config.o : $(obj)/config.c
13876 - for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
13884 -archmrproper: clean
13885 +quiet_cmd_quote = QUOTE $@
13886 +cmd_quote = $(PERL) -e $(QUOTE) < $< > $@
13888 +targets += config.c
13889 +$(obj)/config.c : $(src)/config.c.in $(TOPDIR)/.config FORCE
13890 + $(call if_changed,quote)
13891 Index: uml-2.6.7/arch/um/drivers/xterm_kern.c
13892 ===================================================================
13893 --- uml-2.6.7.orig/arch/um/drivers/xterm_kern.c 2004-07-16 19:37:08.927667864 +0300
13894 +++ uml-2.6.7/arch/um/drivers/xterm_kern.c 2004-07-16 19:47:23.699208384 +0300
13897 #include "linux/errno.h"
13898 #include "linux/slab.h"
13899 +#include "linux/signal.h"
13900 +#include "linux/interrupt.h"
13901 #include "asm/semaphore.h"
13902 #include "asm/irq.h"
13903 #include "irq_user.h"
13904 +#include "irq_kern.h"
13905 #include "kern_util.h"
13908 @@ -19,17 +22,18 @@
13912 -static void xterm_interrupt(int irq, void *data, struct pt_regs *regs)
13913 +static irqreturn_t xterm_interrupt(int irq, void *data, struct pt_regs *regs)
13915 struct xterm_wait *xterm = data;
13918 fd = os_rcv_fd(xterm->fd, &xterm->pid);
13921 + return(IRQ_NONE);
13923 xterm->new_fd = fd;
13925 + return(IRQ_HANDLED);
13928 int xterm_fd(int socket, int *pid_out)
13931 printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
13932 "err = %d\n", err);
13941 ret = data->new_fd;
13942 *pid_out = data->pid;
13947 Index: uml-2.6.7/arch/um/drivers/cow.h
13948 ===================================================================
13949 --- uml-2.6.7.orig/arch/um/drivers/cow.h 2004-07-16 19:47:23.607222368 +0300
13950 +++ uml-2.6.7/arch/um/drivers/cow.h 2004-07-16 19:47:23.678211576 +0300
13955 +#include <asm/types.h>
13957 +#if __BYTE_ORDER == __BIG_ENDIAN
13958 +# define ntohll(x) (x)
13959 +# define htonll(x) (x)
13960 +#elif __BYTE_ORDER == __LITTLE_ENDIAN
13961 +# define ntohll(x) bswap_64(x)
13962 +# define htonll(x) bswap_64(x)
13964 +#error "__BYTE_ORDER not defined"
13967 +extern int init_cow_file(int fd, char *cow_file, char *backing_file,
13968 + int sectorsize, int alignment, int *bitmap_offset_out,
13969 + unsigned long *bitmap_len_out, int *data_offset_out);
13971 +extern int file_reader(__u64 offset, char *buf, int len, void *arg);
13972 +extern int read_cow_header(int (*reader)(__u64, char *, int, void *),
13973 + void *arg, __u32 *version_out,
13974 + char **backing_file_out, time_t *mtime_out,
13975 + __u64 *size_out, int *sectorsize_out,
13976 + __u32 *align_out, int *bitmap_offset_out);
13978 +extern int write_cow_header(char *cow_file, int fd, char *backing_file,
13979 + int sectorsize, int alignment, long long *size);
13981 +extern void cow_sizes(int version, __u64 size, int sectorsize, int align,
13982 + int bitmap_offset, unsigned long *bitmap_len_out,
13983 + int *data_offset_out);
13988 + * ---------------------------------------------------------------------------
13989 + * Local variables:
13990 + * c-file-style: "linux"
13993 Index: uml-2.6.7/arch/um/sys-ppc/Makefile
13994 ===================================================================
13995 --- uml-2.6.7.orig/arch/um/sys-ppc/Makefile 2004-07-16 19:36:37.299476080 +0300
13996 +++ uml-2.6.7/arch/um/sys-ppc/Makefile 2004-07-16 19:47:23.779196224 +0300
13998 $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
14004 - rm -f checksum.S semaphore.c mk_defs.c
14011 +clean-files := $(OBJS) ppc_defs.h checksum.S semaphore.c mk_defs.c
14012 Index: uml-2.6.7/arch/um/os-Linux/user_syms.c
14013 ===================================================================
14014 --- uml-2.6.7.orig/arch/um/os-Linux/user_syms.c 2004-07-16 19:47:23.629219024 +0300
14015 +++ uml-2.6.7/arch/um/os-Linux/user_syms.c 2004-07-16 19:47:23.769197744 +0300
14017 +#include "linux/types.h"
14018 +#include "linux/module.h"
14020 +/* Some of this are builtin function (some are not but could in the future),
14021 + * so I *must* declare good prototypes for them and then EXPORT them.
14022 + * The kernel code uses the macro defined by include/linux/string.h,
14023 + * so I undef macros; the userspace code does not include that and I
14024 + * add an EXPORT for the glibc one.*/
14031 +extern size_t strlen(const char *);
14032 +extern void *memcpy(void *, const void *, size_t);
14033 +extern void *memset(void *, int, size_t);
14034 +extern int printf(const char *, ...);
14036 +EXPORT_SYMBOL(strlen);
14037 +EXPORT_SYMBOL(memcpy);
14038 +EXPORT_SYMBOL(memset);
14039 +EXPORT_SYMBOL(printf);
14041 +EXPORT_SYMBOL(strstr);
14043 +/* Here, instead, I can provide a fake prototype. Yes, someone cares: genksyms.
14044 + * However, the modules will use the CRC defined *here*, no matter if it is
14045 + * good; so the versions of these symbols will always match
14047 +#define EXPORT_SYMBOL_PROTO(sym) \
14049 + EXPORT_SYMBOL(sym);
14051 +EXPORT_SYMBOL_PROTO(__errno_location);
14053 +EXPORT_SYMBOL_PROTO(access);
14054 +EXPORT_SYMBOL_PROTO(open);
14055 +EXPORT_SYMBOL_PROTO(open64);
14056 +EXPORT_SYMBOL_PROTO(close);
14057 +EXPORT_SYMBOL_PROTO(read);
14058 +EXPORT_SYMBOL_PROTO(write);
14059 +EXPORT_SYMBOL_PROTO(dup2);
14060 +EXPORT_SYMBOL_PROTO(__xstat);
14061 +EXPORT_SYMBOL_PROTO(__lxstat);
14062 +EXPORT_SYMBOL_PROTO(__lxstat64);
14063 +EXPORT_SYMBOL_PROTO(lseek);
14064 +EXPORT_SYMBOL_PROTO(lseek64);
14065 +EXPORT_SYMBOL_PROTO(chown);
14066 +EXPORT_SYMBOL_PROTO(truncate);
14067 +EXPORT_SYMBOL_PROTO(utime);
14068 +EXPORT_SYMBOL_PROTO(chmod);
14069 +EXPORT_SYMBOL_PROTO(rename);
14070 +EXPORT_SYMBOL_PROTO(__xmknod);
14072 +EXPORT_SYMBOL_PROTO(symlink);
14073 +EXPORT_SYMBOL_PROTO(link);
14074 +EXPORT_SYMBOL_PROTO(unlink);
14075 +EXPORT_SYMBOL_PROTO(readlink);
14077 +EXPORT_SYMBOL_PROTO(mkdir);
14078 +EXPORT_SYMBOL_PROTO(rmdir);
14079 +EXPORT_SYMBOL_PROTO(opendir);
14080 +EXPORT_SYMBOL_PROTO(readdir);
14081 +EXPORT_SYMBOL_PROTO(closedir);
14082 +EXPORT_SYMBOL_PROTO(seekdir);
14083 +EXPORT_SYMBOL_PROTO(telldir);
14085 +EXPORT_SYMBOL_PROTO(ioctl);
14087 +EXPORT_SYMBOL_PROTO(pread64);
14088 +EXPORT_SYMBOL_PROTO(pwrite64);
14090 +EXPORT_SYMBOL_PROTO(statfs);
14091 +EXPORT_SYMBOL_PROTO(statfs64);
14093 +EXPORT_SYMBOL_PROTO(getuid);
14096 + * Overrides for Emacs so that we follow Linus's tabbing style.
14097 + * Emacs will notice this stuff at the end of the file and automatically
14098 + * adjust the settings for this buffer only. This must remain at the end
14100 + * ---------------------------------------------------------------------------
14101 + * Local variables:
14102 + * c-file-style: "linux"
14105 Index: uml-2.6.7/arch/um/include/irq_kern.h
14106 ===================================================================
14107 --- uml-2.6.7.orig/arch/um/include/irq_kern.h 2004-07-16 19:47:23.612221608 +0300
14108 +++ uml-2.6.7/arch/um/include/irq_kern.h 2004-07-16 19:47:23.701208080 +0300
14111 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
14112 + * Licensed under the GPL
14115 +#ifndef __IRQ_KERN_H__
14116 +#define __IRQ_KERN_H__
14118 +#include "linux/interrupt.h"
14120 +extern int um_request_irq(unsigned int irq, int fd, int type,
14121 + irqreturn_t (*handler)(int, void *,
14122 + struct pt_regs *),
14123 + unsigned long irqflags, const char * devname,
14129 + * Overrides for Emacs so that we follow Linus's tabbing style.
14130 + * Emacs will notice this stuff at the end of the file and automatically
14131 + * adjust the settings for this buffer only. This must remain at the end
14133 + * ---------------------------------------------------------------------------
14134 + * Local variables:
14135 + * c-file-style: "linux"
14138 Index: uml-2.6.7/fs/hppfs/hppfs_kern.c
14139 ===================================================================
14140 --- uml-2.6.7.orig/fs/hppfs/hppfs_kern.c 2004-07-16 19:47:23.632218568 +0300
14141 +++ uml-2.6.7/fs/hppfs/hppfs_kern.c 2004-07-16 19:47:23.785195312 +0300
14144 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14145 + * Licensed under the GPL
14148 +#include <linux/fs.h>
14149 +#include <linux/module.h>
14150 +#include <linux/init.h>
14151 +#include <linux/slab.h>
14152 +#include <linux/list.h>
14153 +#include <linux/kernel.h>
14154 +#include <linux/ctype.h>
14155 +#include <linux/dcache.h>
14156 +#include <linux/statfs.h>
14157 +#include <asm/uaccess.h>
14158 +#include <asm/fcntl.h>
14161 +static int init_inode(struct inode *inode, struct dentry *dentry);
14163 +struct hppfs_data {
14164 + struct list_head list;
14165 + char contents[PAGE_SIZE - sizeof(struct list_head)];
14168 +struct hppfs_private {
14169 + struct file proc_file;
14172 + struct hppfs_data *contents;
14175 +struct hppfs_inode_info {
14176 + struct dentry *proc_dentry;
14177 + struct inode vfs_inode;
14180 +static inline struct hppfs_inode_info *HPPFS_I(struct inode *inode)
14182 + return(list_entry(inode, struct hppfs_inode_info, vfs_inode));
14185 +#define HPPFS_SUPER_MAGIC 0xb00000ee
14187 +static struct super_operations hppfs_sbops;
14189 +static int is_pid(struct dentry *dentry)
14191 + struct super_block *sb;
14194 + sb = dentry->d_sb;
14195 + if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
14198 + for(i = 0; i < dentry->d_name.len; i++){
14199 + if(!isdigit(dentry->d_name.name[i]))
14205 +static char *dentry_name(struct dentry *dentry, int extra)
14207 + struct dentry *parent;
14208 + char *root, *name;
14209 + const char *seg_name;
14210 + int len, seg_len;
14214 + while(parent->d_parent != parent){
14215 + if(is_pid(parent))
14216 + len += strlen("pid") + 1;
14217 + else len += parent->d_name.len + 1;
14218 + parent = parent->d_parent;
14222 + len += strlen(root);
14223 + name = kmalloc(len + extra + 1, GFP_KERNEL);
14224 + if(name == NULL) return(NULL);
14226 + name[len] = '\0';
14228 + while(parent->d_parent != parent){
14229 + if(is_pid(parent)){
14230 + seg_name = "pid";
14231 + seg_len = strlen("pid");
14234 + seg_name = parent->d_name.name;
14235 + seg_len = parent->d_name.len;
14238 + len -= seg_len + 1;
14240 + strncpy(&name[len + 1], seg_name, seg_len);
14241 + parent = parent->d_parent;
14243 + strncpy(name, root, strlen(root));
14247 +struct dentry_operations hppfs_dentry_ops = {
14250 +static int file_removed(struct dentry *dentry, const char *file)
14256 + if(file != NULL) extra += strlen(file) + 1;
14258 + host_file = dentry_name(dentry, extra + strlen("/remove"));
14259 + if(host_file == NULL){
14260 + printk("file_removed : allocation failed\n");
14264 + if(file != NULL){
14265 + strcat(host_file, "/");
14266 + strcat(host_file, file);
14268 + strcat(host_file, "/remove");
14270 + fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
14271 + kfree(host_file);
14273 + os_close_file(fd);
14279 +static void hppfs_read_inode(struct inode *ino)
14281 + struct inode *proc_ino;
14283 + if(HPPFS_I(ino)->proc_dentry == NULL)
14286 + proc_ino = HPPFS_I(ino)->proc_dentry->d_inode;
14287 + ino->i_uid = proc_ino->i_uid;
14288 + ino->i_gid = proc_ino->i_gid;
14289 + ino->i_atime = proc_ino->i_atime;
14290 + ino->i_mtime = proc_ino->i_mtime;
14291 + ino->i_ctime = proc_ino->i_ctime;
14292 + ino->i_ino = proc_ino->i_ino;
14293 + ino->i_mode = proc_ino->i_mode;
14294 + ino->i_nlink = proc_ino->i_nlink;
14295 + ino->i_size = proc_ino->i_size;
14296 + ino->i_blksize = proc_ino->i_blksize;
14297 + ino->i_blocks = proc_ino->i_blocks;
14300 +static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry,
14301 + struct nameidata *nd)
14303 + struct dentry *proc_dentry, *new, *parent;
14304 + struct inode *inode;
14305 + int err, deleted;
14307 + deleted = file_removed(dentry, NULL);
14309 + return(ERR_PTR(deleted));
14311 + return(ERR_PTR(-ENOENT));
14314 + parent = HPPFS_I(ino)->proc_dentry;
14315 + down(&parent->d_inode->i_sem);
14316 + proc_dentry = d_lookup(parent, &dentry->d_name);
14317 + if(proc_dentry == NULL){
14318 + proc_dentry = d_alloc(parent, &dentry->d_name);
14319 + if(proc_dentry == NULL){
14320 + up(&parent->d_inode->i_sem);
14323 + new = (*parent->d_inode->i_op->lookup)(parent->d_inode,
14324 + proc_dentry, NULL);
14326 + dput(proc_dentry);
14327 + proc_dentry = new;
14330 + up(&parent->d_inode->i_sem);
14332 + if(IS_ERR(proc_dentry))
14333 + return(proc_dentry);
14335 + inode = iget(ino->i_sb, 0);
14336 + if(inode == NULL)
14339 + err = init_inode(inode, proc_dentry);
14343 + hppfs_read_inode(inode);
14345 + d_add(dentry, inode);
14346 + dentry->d_op = &hppfs_dentry_ops;
14352 + dput(proc_dentry);
14354 + return(ERR_PTR(err));
14357 +static struct inode_operations hppfs_file_iops = {
14360 +static ssize_t read_proc(struct file *file, char *buf, ssize_t count,
14361 + loff_t *ppos, int is_user)
14363 + ssize_t (*read)(struct file *, char *, size_t, loff_t *);
14366 + read = file->f_dentry->d_inode->i_fop->read;
14369 + set_fs(KERNEL_DS);
14371 + n = (*read)(file, buf, count, &file->f_pos);
14376 + if(ppos) *ppos = file->f_pos;
14380 +static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
14387 + new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
14388 + if(new_buf == NULL){
14389 + printk("hppfs_read_file : kmalloc failed\n");
14393 + while(count > 0){
14394 + cur = min_t(ssize_t, count, PAGE_SIZE);
14395 + err = os_read_file(fd, new_buf, cur);
14397 + printk("hppfs_read : read failed, errno = %d\n",
14402 + else if(err == 0)
14405 + if(copy_to_user(buf, new_buf, err)){
14418 +static ssize_t hppfs_read(struct file *file, char *buf, size_t count,
14421 + struct hppfs_private *hppfs = file->private_data;
14422 + struct hppfs_data *data;
14426 + if(hppfs->contents != NULL){
14427 + if(*ppos >= hppfs->len) return(0);
14429 + data = hppfs->contents;
14431 + while(off >= sizeof(data->contents)){
14432 + data = list_entry(data->list.next, struct hppfs_data,
14434 + off -= sizeof(data->contents);
14437 + if(off + count > hppfs->len)
14438 + count = hppfs->len - off;
14439 + copy_to_user(buf, &data->contents[off], count);
14442 + else if(hppfs->host_fd != -1){
14443 + err = os_seek_file(hppfs->host_fd, *ppos);
14445 + printk("hppfs_read : seek failed, errno = %d\n", err);
14448 + count = hppfs_read_file(hppfs->host_fd, buf, count);
14452 + else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1);
14457 +static ssize_t hppfs_write(struct file *file, const char *buf, size_t len,
14460 + struct hppfs_private *data = file->private_data;
14461 + struct file *proc_file = &data->proc_file;
14462 + ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
14465 + write = proc_file->f_dentry->d_inode->i_fop->write;
14467 + proc_file->f_pos = file->f_pos;
14468 + err = (*write)(proc_file, buf, len, &proc_file->f_pos);
14469 + file->f_pos = proc_file->f_pos;
14474 +static int open_host_sock(char *host_file, int *filter_out)
14479 + end = &host_file[strlen(host_file)];
14480 + strcpy(end, "/rw");
14482 + fd = os_connect_socket(host_file);
14486 + strcpy(end, "/r");
14488 + fd = os_connect_socket(host_file);
14492 +static void free_contents(struct hppfs_data *head)
14494 + struct hppfs_data *data;
14495 + struct list_head *ele, *next;
14497 + if(head == NULL) return;
14499 + list_for_each_safe(ele, next, &head->list){
14500 + data = list_entry(ele, struct hppfs_data, list);
14506 +static struct hppfs_data *hppfs_get_data(int fd, int filter,
14507 + struct file *proc_file,
14508 + struct file *hppfs_file,
14509 + loff_t *size_out)
14511 + struct hppfs_data *data, *new, *head;
14515 + data = kmalloc(sizeof(*data), GFP_KERNEL);
14516 + if(data == NULL){
14517 + printk("hppfs_get_data : head allocation failed\n");
14521 + INIT_LIST_HEAD(&data->list);
14527 + while((n = read_proc(proc_file, data->contents,
14528 + sizeof(data->contents), NULL, 0)) > 0)
14529 + os_write_file(fd, data->contents, n);
14530 + err = os_shutdown_socket(fd, 0, 1);
14532 + printk("hppfs_get_data : failed to shut down "
14534 + goto failed_free;
14538 + n = os_read_file(fd, data->contents, sizeof(data->contents));
14541 + printk("hppfs_get_data : read failed, errno = %d\n",
14543 + goto failed_free;
14550 + if(n < sizeof(data->contents))
14553 + new = kmalloc(sizeof(*data), GFP_KERNEL);
14555 + printk("hppfs_get_data : data allocation failed\n");
14557 + goto failed_free;
14560 + INIT_LIST_HEAD(&new->list);
14561 + list_add(&new->list, &data->list);
14567 + free_contents(head);
14569 + return(ERR_PTR(err));
14572 +static struct hppfs_private *hppfs_data(void)
14574 + struct hppfs_private *data;
14576 + data = kmalloc(sizeof(*data), GFP_KERNEL);
14580 + *data = ((struct hppfs_private ) { .host_fd = -1,
14582 + .contents = NULL } );
14586 +static int file_mode(int fmode)
14588 + if(fmode == (FMODE_READ | FMODE_WRITE))
14590 + if(fmode == FMODE_READ)
14591 + return(O_RDONLY);
14592 + if(fmode == FMODE_WRITE)
14593 + return(O_WRONLY);
14597 +static int hppfs_open(struct inode *inode, struct file *file)
14599 + struct hppfs_private *data;
14600 + struct dentry *proc_dentry;
14602 + int err, fd, type, filter;
14605 + data = hppfs_data();
14609 + host_file = dentry_name(file->f_dentry, strlen("/rw"));
14610 + if(host_file == NULL)
14613 + proc_dentry = HPPFS_I(inode)->proc_dentry;
14615 + /* XXX This isn't closed anywhere */
14616 + err = open_private_file(&data->proc_file, proc_dentry,
14617 + file_mode(file->f_mode));
14621 + type = os_file_type(host_file);
14622 + if(type == OS_TYPE_FILE){
14623 + fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
14625 + data->host_fd = fd;
14626 + else printk("hppfs_open : failed to open '%s', errno = %d\n",
14629 + data->contents = NULL;
14631 + else if(type == OS_TYPE_DIR){
14632 + fd = open_host_sock(host_file, &filter);
14634 + data->contents = hppfs_get_data(fd, filter,
14635 + &data->proc_file,
14636 + file, &data->len);
14637 + if(!IS_ERR(data->contents))
14638 + data->host_fd = fd;
14640 + else printk("hppfs_open : failed to open a socket in "
14641 + "'%s', errno = %d\n", host_file, -fd);
14643 + kfree(host_file);
14645 + file->private_data = data;
14649 + kfree(host_file);
14651 + free_contents(data->contents);
14657 +static int hppfs_dir_open(struct inode *inode, struct file *file)
14659 + struct hppfs_private *data;
14660 + struct dentry *proc_dentry;
14664 + data = hppfs_data();
14668 + proc_dentry = HPPFS_I(inode)->proc_dentry;
14669 + err = open_private_file(&data->proc_file, proc_dentry,
14670 + file_mode(file->f_mode));
14674 + file->private_data = data;
14683 +static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
14685 + struct hppfs_private *data = file->private_data;
14686 + struct file *proc_file = &data->proc_file;
14687 + loff_t (*llseek)(struct file *, loff_t, int);
14690 + llseek = proc_file->f_dentry->d_inode->i_fop->llseek;
14691 + if(llseek != NULL){
14692 + ret = (*llseek)(proc_file, off, where);
14697 + return(default_llseek(file, off, where));
14700 +static struct file_operations hppfs_file_fops = {
14702 + .llseek = hppfs_llseek,
14703 + .read = hppfs_read,
14704 + .write = hppfs_write,
14705 + .open = hppfs_open,
14708 +struct hppfs_dirent {
14709 + void *vfs_dirent;
14710 + filldir_t filldir;
14711 + struct dentry *dentry;
14714 +static int hppfs_filldir(void *d, const char *name, int size,
14715 + loff_t offset, ino_t inode, unsigned int type)
14717 + struct hppfs_dirent *dirent = d;
14719 + if(file_removed(dirent->dentry, name))
14722 + return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset,
14726 +static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
14728 + struct hppfs_private *data = file->private_data;
14729 + struct file *proc_file = &data->proc_file;
14730 + int (*readdir)(struct file *, void *, filldir_t);
14731 + struct hppfs_dirent dirent = ((struct hppfs_dirent)
14732 + { .vfs_dirent = ent,
14733 + .filldir = filldir,
14734 + .dentry = file->f_dentry } );
14737 + readdir = proc_file->f_dentry->d_inode->i_fop->readdir;
14739 + proc_file->f_pos = file->f_pos;
14740 + err = (*readdir)(proc_file, &dirent, hppfs_filldir);
14741 + file->f_pos = proc_file->f_pos;
14746 +static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
14751 +static struct file_operations hppfs_dir_fops = {
14753 + .readdir = hppfs_readdir,
14754 + .open = hppfs_dir_open,
14755 + .fsync = hppfs_fsync,
14758 +static int hppfs_statfs(struct super_block *sb, struct kstatfs *sf)
14760 + sf->f_blocks = 0;
14762 + sf->f_bavail = 0;
14765 + sf->f_type = HPPFS_SUPER_MAGIC;
14769 +static struct inode *hppfs_alloc_inode(struct super_block *sb)
14771 + struct hppfs_inode_info *hi;
14773 + hi = kmalloc(sizeof(*hi), GFP_KERNEL);
14777 + *hi = ((struct hppfs_inode_info) { .proc_dentry = NULL });
14778 + inode_init_once(&hi->vfs_inode);
14779 + return(&hi->vfs_inode);
14782 +void hppfs_delete_inode(struct inode *ino)
14784 + clear_inode(ino);
14787 +static void hppfs_destroy_inode(struct inode *inode)
14789 + kfree(HPPFS_I(inode));
14792 +static struct super_operations hppfs_sbops = {
14793 + .alloc_inode = hppfs_alloc_inode,
14794 + .destroy_inode = hppfs_destroy_inode,
14795 + .read_inode = hppfs_read_inode,
14796 + .delete_inode = hppfs_delete_inode,
14797 + .statfs = hppfs_statfs,
14800 +static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen)
14802 + struct file proc_file;
14803 + struct dentry *proc_dentry;
14804 + int (*readlink)(struct dentry *, char *, int);
14807 + proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
14808 + err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
14812 + readlink = proc_dentry->d_inode->i_op->readlink;
14813 + n = (*readlink)(proc_dentry, buffer, buflen);
14815 + close_private_file(&proc_file);
14820 +static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
14822 + struct file proc_file;
14823 + struct dentry *proc_dentry;
14824 + int (*follow_link)(struct dentry *, struct nameidata *);
14827 + proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
14828 + err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
14832 + follow_link = proc_dentry->d_inode->i_op->follow_link;
14833 + n = (*follow_link)(proc_dentry, nd);
14835 + close_private_file(&proc_file);
14840 +static struct inode_operations hppfs_dir_iops = {
14841 + .lookup = hppfs_lookup,
14844 +static struct inode_operations hppfs_link_iops = {
14845 + .readlink = hppfs_readlink,
14846 + .follow_link = hppfs_follow_link,
14849 +static int init_inode(struct inode *inode, struct dentry *dentry)
14851 + if(S_ISDIR(dentry->d_inode->i_mode)){
14852 + inode->i_op = &hppfs_dir_iops;
14853 + inode->i_fop = &hppfs_dir_fops;
14855 + else if(S_ISLNK(dentry->d_inode->i_mode)){
14856 + inode->i_op = &hppfs_link_iops;
14857 + inode->i_fop = &hppfs_file_fops;
14860 + inode->i_op = &hppfs_file_iops;
14861 + inode->i_fop = &hppfs_file_fops;
14864 + HPPFS_I(inode)->proc_dentry = dentry;
14869 +static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
14871 + struct inode *root_inode;
14872 + struct file_system_type *procfs;
14873 + struct super_block *proc_sb;
14877 + procfs = get_fs_type("proc");
14878 + if(procfs == NULL)
14881 + if(list_empty(&procfs->fs_supers))
14884 + proc_sb = list_entry(procfs->fs_supers.next, struct super_block,
14887 + sb->s_blocksize = 1024;
14888 + sb->s_blocksize_bits = 10;
14889 + sb->s_magic = HPPFS_SUPER_MAGIC;
14890 + sb->s_op = &hppfs_sbops;
14892 + root_inode = iget(sb, 0);
14893 + if(root_inode == NULL)
14896 + err = init_inode(root_inode, proc_sb->s_root);
14901 + sb->s_root = d_alloc_root(root_inode);
14902 + if(sb->s_root == NULL)
14905 + hppfs_read_inode(root_inode);
14910 + iput(root_inode);
14915 +static struct super_block *hppfs_read_super(struct file_system_type *type,
14916 + int flags, const char *dev_name,
14919 + return(get_sb_nodev(type, flags, data, hppfs_fill_super));
14922 +static struct file_system_type hppfs_type = {
14923 + .owner = THIS_MODULE,
14925 + .get_sb = hppfs_read_super,
14926 + .kill_sb = kill_anon_super,
14930 +static int __init init_hppfs(void)
14932 + return(register_filesystem(&hppfs_type));
14935 +static void __exit exit_hppfs(void)
14937 + unregister_filesystem(&hppfs_type);
14940 +module_init(init_hppfs)
14941 +module_exit(exit_hppfs)
14942 +MODULE_LICENSE("GPL");
14945 + * Overrides for Emacs so that we follow Linus's tabbing style.
14946 + * Emacs will notice this stuff at the end of the file and automatically
14947 + * adjust the settings for this buffer only. This must remain at the end
14949 + * ---------------------------------------------------------------------------
14950 + * Local variables:
14951 + * c-file-style: "linux"
14954 Index: uml-2.6.7/arch/um/drivers/ssl.c
14955 ===================================================================
14956 --- uml-2.6.7.orig/arch/um/drivers/ssl.c 2004-07-16 19:36:42.449693128 +0300
14957 +++ uml-2.6.7/arch/um/drivers/ssl.c 2004-07-16 19:47:23.694209144 +0300
14959 #include "linux/major.h"
14960 #include "linux/mm.h"
14961 #include "linux/init.h"
14962 +#include "linux/console.h"
14963 #include "asm/termbits.h"
14964 #include "asm/irq.h"
14968 static struct line_driver driver = {
14969 .name = "UML serial line",
14970 - .devfs_name = "tts/%d",
14971 - .major = TTYAUX_MAJOR,
14972 + .device_name = "ttS",
14973 + .devfs_name = "tts/",
14974 + .major = TTY_MAJOR,
14976 .type = TTY_DRIVER_TYPE_SERIAL,
14978 @@ -149,6 +151,9 @@
14985 ret = -ENOIOCTLCMD;
14988 @@ -212,6 +217,37 @@
14990 static int ssl_init_done = 0;
14992 +static void ssl_console_write(struct console *c, const char *string,
14995 + struct line *line = &serial_lines[c->index];
14996 + if(ssl_init_done)
14997 + down(&line->sem);
14998 + console_write_chan(&line->chan_list, string, len);
14999 + if(ssl_init_done)
15003 +static struct tty_driver *ssl_console_device(struct console *c, int *index)
15005 + *index = c->index;
15006 + return ssl_driver;
15009 +static int ssl_console_setup(struct console *co, char *options)
15014 +static struct console ssl_cons = {
15016 + write: ssl_console_write,
15017 + device: ssl_console_device,
15018 + setup: ssl_console_setup,
15019 + flags: CON_PRINTBUFFER,
15026 @@ -227,17 +263,18 @@
15027 new_title = add_xterm_umid(opts.xterm_title);
15028 if(new_title != NULL) opts.xterm_title = new_title;
15030 + register_console(&ssl_cons);
15035 -__initcall(ssl_init);
15036 +late_initcall(ssl_init);
15038 static int ssl_chan_setup(char *str)
15040 - line_setup(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]),
15043 + return(line_setup(serial_lines,
15044 + sizeof(serial_lines)/sizeof(serial_lines[0]),
15048 __setup("ssl", ssl_chan_setup);
15049 Index: uml-2.6.7/arch/um/kernel/tt/Makefile
15050 ===================================================================
15051 --- uml-2.6.7.orig/arch/um/kernel/tt/Makefile 2004-07-16 19:36:45.804183168 +0300
15052 +++ uml-2.6.7/arch/um/kernel/tt/Makefile 2004-07-16 19:47:23.744201544 +0300
15055 -# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15056 +# Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
15057 # Licensed under the GPL
15062 obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
15063 syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \
15064 - uaccess_user.o sys-$(SUBARCH)/
15065 + uaccess.o uaccess_user.o sys-$(SUBARCH)/
15067 obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/
15071 $(obj)/unmap_fin.o : $(src)/unmap.o
15072 ld -r -o $@ $< -lc -L/usr/lib
15075 Index: uml-2.6.7/fs/Makefile
15076 ===================================================================
15077 --- uml-2.6.7.orig/fs/Makefile 2004-07-16 19:36:51.434327256 +0300
15078 +++ uml-2.6.7/fs/Makefile 2004-07-16 19:47:23.786195160 +0300
15080 obj-$(CONFIG_XFS_FS) += xfs/
15081 obj-$(CONFIG_AFS_FS) += afs/
15082 obj-$(CONFIG_BEFS_FS) += befs/
15083 +obj-$(CONFIG_HOSTFS) += hostfs/
15084 +obj-$(CONFIG_HPPFS) += hppfs/
15085 Index: uml-2.6.7/arch/um/kernel/tt/tlb.c
15086 ===================================================================
15087 --- uml-2.6.7.orig/arch/um/kernel/tt/tlb.c 2004-07-16 19:35:58.497374896 +0300
15088 +++ uml-2.6.7/arch/um/kernel/tt/tlb.c 2004-07-16 19:47:23.750200632 +0300
15090 #include "asm/page.h"
15091 #include "asm/pgtable.h"
15092 #include "asm/uaccess.h"
15093 +#include "asm/tlbflush.h"
15094 #include "user_util.h"
15095 #include "mem_user.h"
15097 Index: uml-2.6.7/arch/um/kernel/reboot.c
15098 ===================================================================
15099 --- uml-2.6.7.orig/arch/um/kernel/reboot.c 2004-07-16 19:36:45.791185144 +0300
15100 +++ uml-2.6.7/arch/um/kernel/reboot.c 2004-07-16 19:47:23.724204584 +0300
15103 static void kill_idlers(int me)
15105 +#ifdef CONFIG_MODE_TT
15106 struct task_struct *p;
15110 if((p != NULL) && (p->thread.mode.tt.extern_pid != me))
15111 os_kill_process(p->thread.mode.tt.extern_pid, 0);
15117 Index: uml-2.6.7/arch/um/kernel/ptrace.c
15118 ===================================================================
15119 --- uml-2.6.7.orig/arch/um/kernel/ptrace.c 2004-07-16 19:36:04.815414408 +0300
15120 +++ uml-2.6.7/arch/um/kernel/ptrace.c 2004-07-16 19:47:23.724204584 +0300
15125 -extern long do_mmap2(struct task_struct *task, unsigned long addr,
15126 - unsigned long len, unsigned long prot,
15127 - unsigned long flags, unsigned long fd,
15128 - unsigned long pgoff);
15130 int sys_ptrace(long request, long pid, long addr, long data)
15132 struct task_struct *child;
15133 @@ -302,8 +297,17 @@
15137 -void syscall_trace(void)
15138 +void syscall_trace(union uml_pt_regs *regs, int entryexit)
15140 + if (unlikely(current->audit_context)) {
15142 + audit_syscall_entry(current, regs->orig_eax,
15143 + regs->ebx, regs->ecx,
15144 + regs->edx, regs->esi);
15146 + audit_syscall_exit(current, regs->eax);
15149 if (!test_thread_flag(TIF_SYSCALL_TRACE))
15151 if (!(current->ptrace & PT_PTRACED))
15152 @@ -311,11 +315,8 @@
15154 /* the 0x80 provides a way for the tracing parent to distinguish
15155 between a syscall stop and SIGTRAP delivery */
15156 - current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
15158 - current->state = TASK_STOPPED;
15159 - notify_parent(current, SIGCHLD);
15161 + ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
15165 * this isn't the same as continuing with a signal, but it will do
15166 Index: uml-2.6.7/arch/um/include/um_uaccess.h
15167 ===================================================================
15168 --- uml-2.6.7.orig/arch/um/include/um_uaccess.h 2004-07-16 19:37:08.610716048 +0300
15169 +++ uml-2.6.7/arch/um/include/um_uaccess.h 2004-07-16 19:47:23.709206864 +0300
15170 @@ -38,22 +38,73 @@
15175 + * strncpy_from_user: - Copy a NUL terminated string from userspace.
15176 + * @dst: Destination address, in kernel space. This buffer must be at
15177 + * least @count bytes long.
15178 + * @src: Source address, in user space.
15179 + * @count: Maximum number of bytes to copy, including the trailing NUL.
15181 + * Copies a NUL-terminated string from userspace to kernel space.
15183 + * On success, returns the length of the string (not including the trailing
15186 + * If access to userspace fails, returns -EFAULT (some data may have been
15189 + * If @count is smaller than the length of the string, copies @count bytes
15190 + * and returns @count.
15193 static inline int strncpy_from_user(char *dst, const char *src, int count)
15195 return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas,
15200 + * __clear_user: - Zero a block of memory in user space, with less checking.
15201 + * @to: Destination address, in user space.
15202 + * @n: Number of bytes to zero.
15204 + * Zero a block of memory in user space. Caller must check
15205 + * the specified block with access_ok() before calling this function.
15207 + * Returns number of bytes that could not be cleared.
15208 + * On success, this will be zero.
15210 static inline int __clear_user(void *mem, int len)
15212 return(CHOOSE_MODE_PROC(__clear_user_tt, __clear_user_skas, mem, len));
15216 + * clear_user: - Zero a block of memory in user space.
15217 + * @to: Destination address, in user space.
15218 + * @n: Number of bytes to zero.
15220 + * Zero a block of memory in user space.
15222 + * Returns number of bytes that could not be cleared.
15223 + * On success, this will be zero.
15225 static inline int clear_user(void *mem, int len)
15227 return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len));
15231 + * strlen_user: - Get the size of a string in user space.
15232 + * @str: The string to measure.
15233 + * @n: The maximum valid length
15235 + * Get the size of a NUL-terminated string in user space.
15237 + * Returns the size of the string INCLUDING the terminating NUL.
15238 + * On exception, returns 0.
15239 + * If the string is too long, returns a value greater than @n.
15241 static inline int strnlen_user(const void *str, int len)
15243 return(CHOOSE_MODE_PROC(strnlen_user_tt, strnlen_user_skas, str, len));
15244 Index: uml-2.6.7/include/asm-um/current.h
15245 ===================================================================
15246 --- uml-2.6.7.orig/include/asm-um/current.h 2004-07-16 19:35:58.909312272 +0300
15247 +++ uml-2.6.7/include/asm-um/current.h 2004-07-16 19:47:23.788194856 +0300
15249 #define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & \
15250 (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
15252 -#define current ({ int dummy; \
15253 - ((struct thread_info *) CURRENT_THREAD(dummy))->task; })
15254 +#define current_thread \
15255 + ({ int dummy; ((struct thread_info *) CURRENT_THREAD(dummy)); })
15257 +#define current (current_thread->task)
15259 #endif /* __ASSEMBLY__ */
15261 Index: uml-2.6.7/arch/um/sys-i386/bugs.c
15262 ===================================================================
15263 --- uml-2.6.7.orig/arch/um/sys-i386/bugs.c 2004-07-16 19:37:17.366384984 +0300
15264 +++ uml-2.6.7/arch/um/sys-i386/bugs.c 2004-07-16 19:47:23.770197592 +0300
15268 #include <unistd.h>
15269 -#include <fcntl.h>
15271 #include <string.h>
15272 #include <sys/signal.h>
15273 +#include <asm/ldt.h>
15274 #include "kern_util.h"
15276 #include "sysdep/ptrace.h"
15280 #define MAXTOKEN 64
15282 /* Set during early boot */
15283 -int cpu_has_cmov = 1;
15284 -int cpu_has_xmm = 0;
15285 +int host_has_cmov = 1;
15286 +int host_has_xmm = 0;
15288 static char token(int fd, char *buf, int len, char stop)
15290 @@ -27,13 +28,15 @@
15294 - n = read(fd, ptr, sizeof(*ptr));
15295 + n = os_read_file(fd, ptr, sizeof(*ptr));
15297 - if(n == 0) return(0);
15298 - else if(n != sizeof(*ptr)){
15299 - printk("Reading /proc/cpuinfo failed, "
15300 - "errno = %d\n", errno);
15302 + if(n != sizeof(*ptr)){
15303 + if(n == 0) return(0);
15304 + printk("Reading /proc/cpuinfo failed, err = %d\n", -n);
15310 } while((c != '\n') && (c != stop) && (ptr < end));
15312 @@ -45,45 +48,79 @@
15316 -static int check_cpu_feature(char *feature, int *have_it)
15317 +static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
15319 - char buf[MAXTOKEN], c;
15320 - int fd, len = sizeof(buf)/sizeof(buf[0]), n;
15322 - printk("Checking for host processor %s support...", feature);
15323 - fd = open("/proc/cpuinfo", O_RDONLY);
15325 - printk("Couldn't open /proc/cpuinfo, errno = %d\n", errno);
15332 - buf[len - 1] = '\0';
15333 + scratch[len - 1] = '\0';
15335 - c = token(fd, buf, len - 1, ':');
15336 - if(c <= 0) goto out;
15337 + c = token(fd, scratch, len - 1, ':');
15341 printk("Failed to find ':' in /proc/cpuinfo\n");
15346 - if(!strncmp(buf, "flags", strlen("flags"))) break;
15347 + if(!strncmp(scratch, key, strlen(key)))
15351 - n = read(fd, &c, sizeof(c));
15352 + n = os_read_file(fd, &c, sizeof(c));
15353 if(n != sizeof(c)){
15354 printk("Failed to find newline in "
15355 - "/proc/cpuinfo, n = %d, errno = %d\n",
15358 + "/proc/cpuinfo, err = %d\n", -n);
15361 } while(c != '\n');
15366 +int cpu_feature(char *what, char *buf, int len)
15370 + fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
15372 + printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
15376 + if(!find_cpuinfo_line(fd, what, buf, len)){
15377 + printk("Couldn't find '%s' line in /proc/cpuinfo\n", what);
15381 + token(fd, buf, len, '\n');
15385 + os_close_file(fd);
15389 +static int check_cpu_flag(char *feature, int *have_it)
15391 + char buf[MAXTOKEN], c;
15392 + int fd, len = sizeof(buf)/sizeof(buf[0]);
15394 + printk("Checking for host processor %s support...", feature);
15395 + fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
15397 + printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
15402 + if(!find_cpuinfo_line(fd, "flags", buf, sizeof(buf) / sizeof(buf[0])))
15405 c = token(fd, buf, len - 1, ' ');
15406 if(c < 0) goto out;
15408 - printk("Failed to find ':' in /proc/cpuinfo\n");
15409 + printk("Failed to find ' ' in /proc/cpuinfo\n");
15413 @@ -100,21 +137,48 @@
15415 if(*have_it == 0) printk("No\n");
15416 else if(*have_it == 1) printk("Yes\n");
15418 + os_close_file(fd);
15422 +#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems
15423 + * for some people.
15425 +static void disable_lcall(void)
15427 + struct modify_ldt_ldt_s ldt;
15430 + bzero(&ldt, sizeof(ldt));
15431 + ldt.entry_number = 7;
15432 + ldt.base_addr = 0;
15434 + err = modify_ldt(1, &ldt, sizeof(ldt));
15436 + printk("Failed to disable lcall7 - errno = %d\n", errno);
15440 +void arch_init_thread(void)
15447 void arch_check_bugs(void)
15451 - if(access("/proc/cpuinfo", R_OK)){
15452 + if(os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0){
15453 printk("/proc/cpuinfo not available - skipping CPU capability "
15457 - if(check_cpu_feature("cmov", &have_it)) cpu_has_cmov = have_it;
15458 - if(check_cpu_feature("xmm", &have_it)) cpu_has_xmm = have_it;
15459 + if(check_cpu_flag("cmov", &have_it))
15460 + host_has_cmov = have_it;
15461 + if(check_cpu_flag("xmm", &have_it))
15462 + host_has_xmm = have_it;
15465 int arch_handle_signal(int sig, union uml_pt_regs *regs)
15466 @@ -130,18 +194,18 @@
15467 if((*((char *) ip) != 0x0f) || ((*((char *) (ip + 1)) & 0xf0) != 0x40))
15470 - if(cpu_has_cmov == 0)
15471 + if(host_has_cmov == 0)
15472 panic("SIGILL caused by cmov, which this processor doesn't "
15473 "implement, boot a filesystem compiled for older "
15475 - else if(cpu_has_cmov == 1)
15476 + else if(host_has_cmov == 1)
15477 panic("SIGILL caused by cmov, which this processor claims to "
15479 - else if(cpu_has_cmov == -1)
15480 + else if(host_has_cmov == -1)
15481 panic("SIGILL caused by cmov, couldn't tell if this processor "
15482 "implements it, boot a filesystem compiled for older "
15484 - else panic("Bad value for cpu_has_cmov (%d)", cpu_has_cmov);
15485 + else panic("Bad value for host_has_cmov (%d)", host_has_cmov);
15489 Index: uml-2.6.7/arch/um/kernel/skas/include/mode.h
15490 ===================================================================
15491 --- uml-2.6.7.orig/arch/um/kernel/skas/include/mode.h 2004-07-16 19:36:48.253810768 +0300
15492 +++ uml-2.6.7/arch/um/kernel/skas/include/mode.h 2004-07-16 19:47:23.727204128 +0300
15493 @@ -12,14 +12,16 @@
15494 extern int have_fpx_regs;
15496 extern void user_time_init_skas(void);
15497 -extern int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr);
15498 -extern int copy_sc_to_user_skas(void *to_ptr, void *fp,
15499 +extern int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs,
15501 +extern int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp,
15502 union uml_pt_regs *regs,
15503 unsigned long fault_addr, int fault_type);
15504 extern void sig_handler_common_skas(int sig, void *sc_ptr);
15505 extern void halt_skas(void);
15506 extern void reboot_skas(void);
15507 extern void kill_off_processes_skas(void);
15508 +extern int is_skas_winch(int pid, int fd, void *data);
15512 Index: uml-2.6.7/arch/um/include/sysdep-i386/sigcontext.h
15513 ===================================================================
15514 --- uml-2.6.7.orig/arch/um/include/sysdep-i386/sigcontext.h 2004-07-16 19:37:08.763692792 +0300
15515 +++ uml-2.6.7/arch/um/include/sysdep-i386/sigcontext.h 2004-07-16 19:47:23.707207168 +0300
15518 #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
15520 -/* These are General Protection and Page Fault */
15521 -#define SEGV_IS_FIXABLE(trap) ((trap == 13) || (trap == 14))
15522 +/* This is Page Fault */
15523 +#define SEGV_IS_FIXABLE(trap) (trap == 14)
15525 #define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
15527 Index: uml-2.6.7/arch/um/drivers/net_user.c
15528 ===================================================================
15529 --- uml-2.6.7.orig/arch/um/drivers/net_user.c 2004-07-16 19:36:10.505549376 +0300
15530 +++ uml-2.6.7/arch/um/drivers/net_user.c 2004-07-16 19:47:24.796041640 +0300
15532 if(gate_addr == NULL) return(0);
15533 if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
15534 &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){
15535 - printk("Invalid tap IP address - '%s'\n",
15537 + printk("Invalid tap IP address - '%s'\n", gate_addr);
15541 @@ -60,18 +59,18 @@
15545 - if(read(fd, &remain, sizeof(remain)) != sizeof(remain)){
15546 - printk("read_output - read of length failed, errno = %d\n",
15548 + n = os_read_file(fd, &remain, sizeof(remain));
15549 + if(n != sizeof(remain)){
15550 + printk("read_output - read of length failed, err = %d\n", -n);
15554 while(remain != 0){
15555 n = (remain < len) ? remain : len;
15556 - actual = read(fd, output, n);
15557 + actual = os_read_file(fd, output, n);
15559 printk("read_output - read of data failed, "
15560 - "errno = %d\n", errno);
15561 + "err = %d\n", -actual);
15565 @@ -83,13 +82,12 @@
15569 - while(((n = read(fd, buf, len)) < 0) && (errno == EINTR)) ;
15570 + n = os_read_file(fd, buf, len);
15573 - if(errno == EAGAIN) return(0);
15576 - else if(n == 0) return(-ENOTCONN);
15580 + return(-ENOTCONN);
15584 @@ -112,13 +110,13 @@
15588 - while(((n = write(fd, buf, len)) < 0) && (errno == EINTR)) ;
15590 - if(errno == EAGAIN) return(0);
15593 - else if(n == 0) return(-ENOTCONN);
15595 + n = os_write_file(fd, buf, len);
15600 + return(-ENOTCONN);
15604 int net_send(int fd, void *buf, int len)
15605 @@ -157,7 +155,7 @@
15607 struct change_pre_exec_data *data = arg;
15609 - close(data->close_me);
15610 + os_close_file(data->close_me);
15611 dup2(data->stdout, 1);
15614 @@ -167,17 +165,18 @@
15615 struct change_pre_exec_data pe_data;
15617 err = os_pipe(fds, 1, 0);
15619 - printk("change_tramp - pipe failed, errno = %d\n", -err);
15621 + printk("change_tramp - pipe failed, err = %d\n", -err);
15624 pe_data.close_me = fds[0];
15625 pe_data.stdout = fds[1];
15626 pid = run_helper(change_pre_exec, &pe_data, argv, NULL);
15629 + os_close_file(fds[1]);
15630 read_output(fds[0], output, output_len);
15631 - waitpid(pid, NULL, 0);
15633 + CATCH_EINTR(err = waitpid(pid, NULL, 0));
15637 Index: uml-2.6.7/include/asm-um/processor-generic.h
15638 ===================================================================
15639 --- uml-2.6.7.orig/include/asm-um/processor-generic.h 2004-07-16 19:36:07.621987744 +0300
15640 +++ uml-2.6.7/include/asm-um/processor-generic.h 2004-07-16 19:47:23.794193944 +0300
15641 @@ -11,33 +11,14 @@
15642 struct task_struct;
15644 #include "linux/config.h"
15645 -#include "linux/signal.h"
15646 #include "asm/ptrace.h"
15647 -#include "asm/siginfo.h"
15648 #include "choose-mode.h"
15652 #define current_text_addr() ((void *) 0)
15654 -#define cpu_relax() do ; while (0)
15656 -#ifdef CONFIG_MODE_TT
15657 -struct proc_tt_mode {
15660 - int switch_pipe[2];
15661 - int singlestep_syscall;
15666 -#ifdef CONFIG_MODE_SKAS
15667 -struct proc_skas_mode {
15668 - void *switch_buf;
15672 +#define cpu_relax() barrier()
15674 struct thread_struct {
15677 struct pt_regs regs;
15680 + unsigned long trap_no;
15682 void *fault_catcher;
15683 struct task_struct *prev_sched;
15684 @@ -54,10 +36,20 @@
15685 struct arch_thread arch;
15687 #ifdef CONFIG_MODE_TT
15688 - struct proc_tt_mode tt;
15692 + int switch_pipe[2];
15693 + int singlestep_syscall;
15697 #ifdef CONFIG_MODE_SKAS
15698 - struct proc_skas_mode skas;
15700 + void *switch_buf;
15707 @@ -99,14 +91,19 @@
15710 extern struct task_struct *alloc_task_struct(void);
15711 -extern void free_task_struct(struct task_struct *task);
15713 extern void release_thread(struct task_struct *);
15714 extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
15715 extern void dump_thread(struct pt_regs *regs, struct user *u);
15716 +extern void prepare_to_copy(struct task_struct *tsk);
15718 extern unsigned long thread_saved_pc(struct task_struct *t);
15720 +static inline void mm_copy_segments(struct mm_struct *from_mm,
15721 + struct mm_struct *new_mm)
15725 #define init_stack (init_thread_union.stack)
15728 Index: uml-2.6.7/include/asm-um/fixmap.h
15729 ===================================================================
15730 --- uml-2.6.7.orig/include/asm-um/fixmap.h 2004-07-16 19:37:31.708204696 +0300
15731 +++ uml-2.6.7/include/asm-um/fixmap.h 2004-07-16 19:47:23.790194552 +0300
15733 FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
15734 FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
15737 __end_of_fixed_addresses
15741 #define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
15742 #define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
15745 + * This is the range that is readable by user mode, and things
15746 + * acting like user mode such as get_user_pages.
15748 +#define FIXADDR_USER_START (__fix_to_virt(FIX_VSYSCALL))
15749 +#define FIXADDR_USER_END (FIXADDR_USER_START + PAGE_SIZE)
15751 extern void __this_fixmap_does_not_exist(void);
15754 Index: uml-2.6.7/arch/um/os-Linux/drivers/ethertap_kern.c
15755 ===================================================================
15756 --- uml-2.6.7.orig/arch/um/os-Linux/drivers/ethertap_kern.c 2004-07-16 19:35:55.747792896 +0300
15757 +++ uml-2.6.7/arch/um/os-Linux/drivers/ethertap_kern.c 2004-07-16 19:47:23.765198352 +0300
15759 #include "linux/init.h"
15760 #include "linux/netdevice.h"
15761 #include "linux/etherdevice.h"
15762 -#include "linux/init.h"
15763 #include "net_kern.h"
15764 #include "net_user.h"
15766 Index: uml-2.6.7/arch/um/kernel/tt/syscall_user.c
15767 ===================================================================
15768 --- uml-2.6.7.orig/arch/um/kernel/tt/syscall_user.c 2004-07-16 19:37:02.608628504 +0300
15769 +++ uml-2.6.7/arch/um/kernel/tt/syscall_user.c 2004-07-16 19:47:23.749200784 +0300
15771 SC_START_SYSCALL(sc);
15773 index = record_syscall_start(syscall);
15775 + syscall_trace(regs, 1);
15776 result = execute_syscall(regs);
15778 /* regs->sc may have changed while the system call ran (there may
15780 (result == -ERESTARTNOINTR))
15784 + syscall_trace(regs, 0);
15785 record_syscall_end(index, result);
15788 Index: uml-2.6.7/arch/um/drivers/ubd_kern.c
15789 ===================================================================
15790 --- uml-2.6.7.orig/arch/um/drivers/ubd_kern.c 2004-07-16 19:36:39.996066136 +0300
15791 +++ uml-2.6.7/arch/um/drivers/ubd_kern.c 2004-07-16 19:47:23.697208688 +0300
15793 * old style ubd by setting UBD_SHIFT to 0
15794 * 2002-09-27...2002-10-18 massive tinkering for 2.5
15795 * partitions have changed in 2.5
15796 + * 2003-01-29 more tinkering for 2.5.59-1
15797 + * This should now address the sysfs problems and has
15798 + * the symlink for devfs to allow for booting with
15799 + * the common /dev/ubd/discX/... names rather than
15800 + * only /dev/ubdN/discN this version also has lots of
15801 + * clean ups preparing for ubd-many.
15805 #define MAJOR_NR UBD_MAJOR
15807 #include "mconsole_kern.h"
15809 #include "irq_user.h"
15810 +#include "irq_kern.h"
15811 #include "ubd_user.h"
15812 #include "2_5compat.h"
15815 +#include "mem_kern.h"
15817 static spinlock_t ubd_io_lock = SPIN_LOCK_UNLOCKED;
15818 static spinlock_t ubd_lock = SPIN_LOCK_UNLOCKED;
15821 #define MAX_DEV (8)
15823 +/* Changed in early boot */
15824 +static int ubd_do_mmap = 0;
15825 +#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE
15827 static struct block_device_operations ubd_blops = {
15828 .owner = THIS_MODULE,
15831 static request_queue_t *ubd_queue;
15833 /* Protected by ubd_lock */
15834 -static int fake_major = 0;
15835 +static int fake_major = MAJOR_NR;
15837 static struct gendisk *ubd_gendisk[MAX_DEV];
15838 static struct gendisk *fake_gendisk[MAX_DEV];
15839 @@ -96,13 +110,19 @@
15847 struct openflags boot_openflags;
15848 struct openflags openflags;
15854 + int nomap_writes;
15859 #define DEFAULT_COW { \
15860 @@ -115,21 +135,28 @@
15862 #define DEFAULT_UBD { \
15868 .boot_openflags = OPEN_FLAGS, \
15869 .openflags = OPEN_FLAGS, \
15871 .cow = DEFAULT_COW, \
15872 + .map_writes = 0, \
15873 + .map_reads = 0, \
15874 + .nomap_writes = 0, \
15875 + .nomap_reads = 0, \
15876 + .write_maps = 0, \
15879 struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
15881 static int ubd0_init(void)
15883 - if(ubd_dev[0].file == NULL)
15884 - ubd_dev[0].file = "root_fs";
15885 + struct ubd *dev = &ubd_dev[0];
15887 + if(dev->file == NULL)
15888 + dev->file = "root_fs";
15892 @@ -196,19 +223,46 @@
15893 " Create ide0 entries that map onto ubd devices.\n\n"
15896 +static int parse_unit(char **ptr)
15898 + char *str = *ptr, *end;
15901 + if(isdigit(*str)) {
15902 + n = simple_strtoul(str, &end, 0);
15907 + else if (('a' <= *str) && (*str <= 'h')) {
15915 static int ubd_setup_common(char *str, int *index_out)
15918 struct openflags flags = global_openflags;
15919 char *backing_file;
15922 if(index_out) *index_out = -1;
15926 - static int fake_major_allowed = 1;
15931 + if(!strcmp(str, "mmap")){
15932 + CHOOSE_MODE(printk("mmap not supported by the ubd "
15933 + "driver in tt mode\n"),
15934 + ubd_do_mmap = 1);
15938 if(!strcmp(str, "sync")){
15939 global_openflags.s = 1;
15941 @@ -220,20 +274,14 @@
15945 - if(!fake_major_allowed){
15946 - printk(KERN_ERR "Can't assign a fake major twice\n");
15951 spin_lock(&ubd_lock);
15952 - if(!fake_major_allowed){
15953 + if(fake_major != MAJOR_NR){
15954 printk(KERN_ERR "Can't assign a fake major twice\n");
15958 fake_major = major;
15959 - fake_major_allowed = 0;
15961 printk(KERN_INFO "Setting extra ubd major number to %d\n",
15963 @@ -243,25 +291,23 @@
15968 - printk(KERN_ERR "ubd_setup : index out of range\n"); }
15970 - if((n >= '0') && (n <= '9')) n -= '0';
15971 - else if((n >= 'a') && (n <= 'z')) n -= 'a';
15973 - printk(KERN_ERR "ubd_setup : device syntax invalid\n");
15974 + n = parse_unit(&str);
15976 + printk(KERN_ERR "ubd_setup : couldn't parse unit number "
15981 - printk(KERN_ERR "ubd_setup : index out of range "
15982 - "(%d devices)\n", MAX_DEV);
15983 + printk(KERN_ERR "ubd_setup : index %d out of range "
15984 + "(%d devices)\n", n, MAX_DEV);
15989 spin_lock(&ubd_lock);
15991 - if(ubd_dev[n].file != NULL){
15992 + dev = &ubd_dev[n];
15993 + if(dev->file != NULL){
15994 printk(KERN_ERR "ubd_setup : device already configured\n");
15997 @@ -276,6 +322,11 @@
16001 + if (*str == 'd'){
16007 printk(KERN_ERR "ubd_setup : Expected '='\n");
16009 @@ -284,14 +335,17 @@
16011 backing_file = strchr(str, ',');
16013 - *backing_file = '\0';
16016 + printk(KERN_ERR "Can't specify both 'd' and a "
16019 + *backing_file = '\0';
16023 - ubd_dev[n].file = str;
16024 - if(ubd_is_dir(ubd_dev[n].file))
16025 - ubd_dev[n].is_dir = 1;
16026 - ubd_dev[n].cow.file = backing_file;
16027 - ubd_dev[n].boot_openflags = flags;
16029 + dev->cow.file = backing_file;
16030 + dev->boot_openflags = flags;
16032 spin_unlock(&ubd_lock);
16034 @@ -321,8 +375,7 @@
16035 static int fakehd_set = 0;
16036 static int fakehd(char *str)
16039 - "fakehd : Changing ubd name to \"hd\".\n");
16040 + printk(KERN_INFO "fakehd : Changing ubd name to \"hd\".\n");
16044 @@ -368,32 +421,42 @@
16046 struct io_thread_req req;
16047 struct request *rq = elv_next_request(ubd_queue);
16053 n = read_ubd_fs(thread_fd, &req, sizeof(req));
16054 if(n != sizeof(req)){
16055 printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
16056 - "errno = %d\n", os_getpid(), -n);
16057 + "err = %d\n", os_getpid(), -n);
16058 spin_lock(&ubd_io_lock);
16059 end_request(rq, 0);
16060 spin_unlock(&ubd_io_lock);
16064 - if((req.offset != ((__u64) (rq->sector)) << 9) ||
16065 - (req.length != (rq->current_nr_sectors) << 9))
16066 + if((req.op != UBD_MMAP) &&
16067 + ((req.offset != ((__u64) (rq->sector)) << 9) ||
16068 + (req.length != (rq->current_nr_sectors) << 9)))
16069 panic("I/O op mismatch");
16071 + if(req.map_fd != -1){
16072 + err = physmem_subst_mapping(req.buffer, req.map_fd,
16073 + req.map_offset, 1);
16075 + printk("ubd_handler - physmem_subst_mapping failed, "
16076 + "err = %d\n", -err);
16079 ubd_finish(rq, req.error);
16080 reactivate_fd(thread_fd, UBD_IRQ);
16081 do_ubd_request(ubd_queue);
16084 -static void ubd_intr(int irq, void *dev, struct pt_regs *unused)
16085 +static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused)
16088 + return(IRQ_HANDLED);
16091 /* Only changed by ubd_init, which is an initcall. */
16092 @@ -417,10 +480,14 @@
16094 static void ubd_close(struct ubd *dev)
16097 + physmem_forget_descriptor(dev->fd);
16098 os_close_file(dev->fd);
16099 if(dev->cow.file == NULL)
16103 + physmem_forget_descriptor(dev->cow.fd);
16104 os_close_file(dev->cow.fd);
16105 vfree(dev->cow.bitmap);
16106 dev->cow.bitmap = NULL;
16107 @@ -429,18 +496,20 @@
16108 static int ubd_open_dev(struct ubd *dev)
16110 struct openflags flags;
16111 - int err, n, create_cow, *create_ptr;
16113 + int err, create_cow, *create_ptr;
16115 + dev->openflags = dev->boot_openflags;
16117 create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
16118 - dev->fd = open_ubd_file(dev->file, &dev->openflags, &dev->cow.file,
16119 + back_ptr = dev->no_cow ? NULL : &dev->cow.file;
16120 + dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr,
16121 &dev->cow.bitmap_offset, &dev->cow.bitmap_len,
16122 &dev->cow.data_offset, create_ptr);
16124 if((dev->fd == -ENOENT) && create_cow){
16125 - n = dev - ubd_dev;
16126 dev->fd = create_cow_file(dev->file, dev->cow.file,
16127 - dev->openflags, 1 << 9,
16128 + dev->openflags, 1 << 9, PAGE_SIZE,
16129 &dev->cow.bitmap_offset,
16130 &dev->cow.bitmap_len,
16131 &dev->cow.data_offset);
16132 @@ -455,13 +524,17 @@
16133 if(dev->cow.file != NULL){
16135 dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
16136 - if(dev->cow.bitmap == NULL) goto error;
16137 + if(dev->cow.bitmap == NULL){
16138 + printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
16141 flush_tlb_kernel_vm();
16143 err = read_cow_bitmap(dev->fd, dev->cow.bitmap,
16144 dev->cow.bitmap_offset,
16145 dev->cow.bitmap_len);
16146 - if(err) goto error;
16150 flags = dev->openflags;
16152 @@ -481,17 +554,31 @@
16155 struct gendisk *disk;
16156 + char from[sizeof("ubd/nnnnn\0")], to[sizeof("discnnnnn/disc\0")];
16159 disk = alloc_disk(1 << UBD_SHIFT);
16165 disk->major = major;
16166 disk->first_minor = unit << UBD_SHIFT;
16167 disk->fops = &ubd_blops;
16168 set_capacity(disk, size / 512);
16169 - sprintf(disk->disk_name, "ubd");
16170 - sprintf(disk->devfs_name, "ubd/disc%d", unit);
16171 + if(major == MAJOR_NR){
16172 + sprintf(disk->disk_name, "ubd%c", 'a' + unit);
16173 + sprintf(disk->devfs_name, "ubd/disc%d", unit);
16174 + sprintf(from, "ubd/%d", unit);
16175 + sprintf(to, "disc%d/disc", unit);
16176 + err = devfs_mk_symlink(from, to);
16178 + printk("ubd_new_disk failed to make link from %s to "
16179 + "%s, error = %d\n", from, to, err);
16182 + sprintf(disk->disk_name, "ubd_fake%d", unit);
16183 + sprintf(disk->devfs_name, "ubd_fake/disc%d", unit);
16186 disk->private_data = &ubd_dev[unit];
16187 disk->queue = ubd_queue;
16188 @@ -506,24 +593,21 @@
16189 struct ubd *dev = &ubd_dev[n];
16196 + if(dev->file == NULL)
16199 if (ubd_open_dev(dev))
16202 err = ubd_file_size(dev, &dev->size);
16207 err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
16212 + if(fake_major != MAJOR_NR)
16213 ubd_new_disk(fake_major, dev->size, n,
16216 @@ -561,42 +645,42 @@
16220 -static int ubd_get_config(char *dev, char *str, int size, char **error_out)
16221 +static int ubd_get_config(char *name, char *str, int size, char **error_out)
16226 - int major, n = 0;
16229 - major = simple_strtoul(dev, &end, 0);
16230 - if((*end != '\0') || (end == dev)){
16231 - *error_out = "ubd_get_config : didn't parse major number";
16232 + n = simple_strtoul(name, &end, 0);
16233 + if((*end != '\0') || (end == name)){
16234 + *error_out = "ubd_get_config : didn't parse device number";
16238 - if((major >= MAX_DEV) || (major < 0)){
16239 - *error_out = "ubd_get_config : major number out of range";
16240 + if((n >= MAX_DEV) || (n < 0)){
16241 + *error_out = "ubd_get_config : device number out of range";
16245 - ubd = &ubd_dev[major];
16246 + dev = &ubd_dev[n];
16247 spin_lock(&ubd_lock);
16249 - if(ubd->file == NULL){
16250 - CONFIG_CHUNK(str, size, n, "", 1);
16251 + if(dev->file == NULL){
16252 + CONFIG_CHUNK(str, size, len, "", 1);
16256 - CONFIG_CHUNK(str, size, n, ubd->file, 0);
16257 + CONFIG_CHUNK(str, size, len, dev->file, 0);
16259 - if(ubd->cow.file != NULL){
16260 - CONFIG_CHUNK(str, size, n, ",", 0);
16261 - CONFIG_CHUNK(str, size, n, ubd->cow.file, 1);
16262 + if(dev->cow.file != NULL){
16263 + CONFIG_CHUNK(str, size, len, ",", 0);
16264 + CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
16266 - else CONFIG_CHUNK(str, size, n, "", 1);
16267 + else CONFIG_CHUNK(str, size, len, "", 1);
16270 spin_unlock(&ubd_lock);
16275 static int ubd_remove(char *str)
16276 @@ -604,11 +688,9 @@
16278 int n, err = -ENODEV;
16280 - if(!isdigit(*str))
16281 - return(err); /* it should be a number 0-7/a-h */
16282 + n = parse_unit(&str);
16286 + if((n < 0) || (n >= MAX_DEV))
16290 @@ -669,7 +751,7 @@
16292 elevator_init(ubd_queue, &elevator_noop);
16294 - if (fake_major != 0) {
16295 + if (fake_major != MAJOR_NR) {
16296 char name[sizeof("ubd_nnn\0")];
16298 snprintf(name, sizeof(name), "ubd_%d", fake_major);
16299 @@ -696,6 +778,7 @@
16300 io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
16305 "ubd : Failed to start I/O thread (errno = %d) - "
16306 "falling back to synchronous I/O\n", -io_pid);
16307 @@ -703,8 +786,8 @@
16309 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
16310 SA_INTERRUPT, "ubd", ubd_dev);
16311 - if(err != 0) printk(KERN_ERR
16312 - "um_request_irq failed - errno = %d\n", -err);
16314 + printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
16318 @@ -714,15 +797,9 @@
16320 struct gendisk *disk = inode->i_bdev->bd_disk;
16321 struct ubd *dev = disk->private_data;
16322 - int err = -EISDIR;
16324 - if(dev->is_dir == 1)
16329 if(dev->count == 0){
16330 - dev->openflags = dev->boot_openflags;
16332 err = ubd_open_dev(dev);
16334 printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
16335 @@ -749,62 +826,156 @@
16339 -void cowify_req(struct io_thread_req *req, struct ubd *dev)
16340 +static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
16341 + __u64 *cow_offset, unsigned long *bitmap,
16342 + __u64 bitmap_offset, unsigned long *bitmap_words,
16343 + __u64 bitmap_len)
16345 + __u64 sector = io_offset >> 9;
16346 + int i, update_bitmap = 0;
16348 + for(i = 0; i < length >> 9; i++){
16349 + if(cow_mask != NULL)
16350 + ubd_set_bit(i, (unsigned char *) cow_mask);
16351 + if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
16354 + update_bitmap = 1;
16355 + ubd_set_bit(sector + i, (unsigned char *) bitmap);
16358 + if(!update_bitmap)
16361 + *cow_offset = sector / (sizeof(unsigned long) * 8);
16363 + /* This takes care of the case where we're exactly at the end of the
16364 + * device, and *cow_offset + 1 is off the end. So, just back it up
16365 + * by one word. Thanks to Lynn Kerby for the fix and James McMechan
16366 + * for the original diagnosis.
16368 + if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) /
16369 + sizeof(unsigned long) - 1))
16372 + bitmap_words[0] = bitmap[*cow_offset];
16373 + bitmap_words[1] = bitmap[*cow_offset + 1];
16375 + *cow_offset *= sizeof(unsigned long);
16376 + *cow_offset += bitmap_offset;
16379 +static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
16380 + __u64 bitmap_offset, __u64 bitmap_len)
16382 - int i, update_bitmap, sector = req->offset >> 9;
16383 + __u64 sector = req->offset >> 9;
16386 if(req->length > (sizeof(req->sector_mask) * 8) << 9)
16387 panic("Operation too long");
16389 if(req->op == UBD_READ) {
16390 for(i = 0; i < req->length >> 9; i++){
16391 - if(ubd_test_bit(sector + i, (unsigned char *)
16392 - dev->cow.bitmap)){
16393 + if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
16394 ubd_set_bit(i, (unsigned char *)
16395 &req->sector_mask);
16400 - update_bitmap = 0;
16401 - for(i = 0; i < req->length >> 9; i++){
16402 - ubd_set_bit(i, (unsigned char *)
16403 - &req->sector_mask);
16404 - if(!ubd_test_bit(sector + i, (unsigned char *)
16405 - dev->cow.bitmap))
16406 - update_bitmap = 1;
16407 - ubd_set_bit(sector + i, (unsigned char *)
16408 - dev->cow.bitmap);
16410 - if(update_bitmap){
16411 - req->cow_offset = sector / (sizeof(unsigned long) * 8);
16412 - req->bitmap_words[0] =
16413 - dev->cow.bitmap[req->cow_offset];
16414 - req->bitmap_words[1] =
16415 - dev->cow.bitmap[req->cow_offset + 1];
16416 - req->cow_offset *= sizeof(unsigned long);
16417 - req->cow_offset += dev->cow.bitmap_offset;
16419 + else cowify_bitmap(req->offset, req->length, &req->sector_mask,
16420 + &req->cow_offset, bitmap, bitmap_offset,
16421 + req->bitmap_words, bitmap_len);
16424 +static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset)
16427 + unsigned char *bitmap;
16430 + /* mmap must have been requested on the command line */
16434 + /* The buffer must be page aligned */
16435 + if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0)
16438 + /* The request must be a page long */
16439 + if((req->current_nr_sectors << 9) != PAGE_SIZE)
16442 + if(dev->cow.file == NULL)
16445 + sector = offset >> 9;
16446 + bitmap = (unsigned char *) dev->cow.bitmap;
16447 + bit = ubd_test_bit(sector, bitmap);
16449 + for(i = 1; i < req->current_nr_sectors; i++){
16450 + if(ubd_test_bit(sector + i, bitmap) != bit)
16454 + if(bit || (rq_data_dir(req) == WRITE))
16455 + offset += dev->cow.data_offset;
16457 + /* The data on disk must be page aligned */
16458 + if((offset % UBD_MMAP_BLOCK_SIZE) != 0)
16461 + return(bit ? dev->fd : dev->cow.fd);
16464 +static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset,
16465 + struct request *req,
16466 + struct io_thread_req *io_req)
16470 + if(rq_data_dir(req) == WRITE){
16471 + /* Writes are almost no-ops since the new data is already in the
16472 + * host page cache
16474 + dev->map_writes++;
16475 + if(dev->cow.file != NULL)
16476 + cowify_bitmap(io_req->offset, io_req->length,
16477 + &io_req->sector_mask, &io_req->cow_offset,
16478 + dev->cow.bitmap, dev->cow.bitmap_offset,
16479 + io_req->bitmap_words,
16480 + dev->cow.bitmap_len);
16485 + if((dev->cow.file != NULL) && (fd == dev->cow.fd))
16487 + else w = dev->openflags.w;
16489 + if((dev->cow.file != NULL) && (fd == dev->fd))
16490 + offset += dev->cow.data_offset;
16492 + err = physmem_subst_mapping(req->buffer, fd, offset, w);
16494 + printk("physmem_subst_mapping failed, err = %d\n",
16498 + dev->map_reads++;
16500 + io_req->op = UBD_MMAP;
16501 + io_req->buffer = req->buffer;
16505 static int prepare_request(struct request *req, struct io_thread_req *io_req)
16507 struct gendisk *disk = req->rq_disk;
16508 struct ubd *dev = disk->private_data;
16514 if(req->rq_status == RQ_INACTIVE) return(1);
16517 - strcpy(req->buffer, "HOSTFS:");
16518 - strcat(req->buffer, dev->file);
16519 - spin_lock(&ubd_io_lock);
16520 - end_request(req, 1);
16521 - spin_unlock(&ubd_io_lock);
16525 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
16526 printk("Write attempted on readonly ubd device %s\n",
16528 @@ -814,23 +985,49 @@
16532 - block = req->sector;
16533 - nsect = req->current_nr_sectors;
16534 + offset = ((__u64) req->sector) << 9;
16535 + len = req->current_nr_sectors << 9;
16537 - io_req->op = rq_data_dir(req) == READ ? UBD_READ : UBD_WRITE;
16538 io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
16539 io_req->fds[1] = dev->fd;
16540 + io_req->map_fd = -1;
16541 + io_req->cow_offset = -1;
16542 + io_req->offset = offset;
16543 + io_req->length = len;
16544 + io_req->error = 0;
16545 + io_req->sector_mask = 0;
16547 + fd = mmap_fd(req, dev, io_req->offset);
16549 + /* If mmapping is otherwise OK, but the first access to the
16550 + * page is a write, then it's not mapped in yet. So we have
16551 + * to write the data to disk first, then we can map the disk
16552 + * page in and continue normally from there.
16554 + if((rq_data_dir(req) == WRITE) && !is_remapped(req->buffer)){
16555 + io_req->map_fd = dev->fd;
16556 + io_req->map_offset = io_req->offset +
16557 + dev->cow.data_offset;
16558 + dev->write_maps++;
16560 + else return(prepare_mmap_request(dev, fd, io_req->offset, req,
16564 + if(rq_data_dir(req) == READ)
16565 + dev->nomap_reads++;
16566 + else dev->nomap_writes++;
16568 + io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
16569 io_req->offsets[0] = 0;
16570 io_req->offsets[1] = dev->cow.data_offset;
16571 - io_req->offset = ((__u64) block) << 9;
16572 - io_req->length = nsect << 9;
16573 io_req->buffer = req->buffer;
16574 io_req->sectorsize = 1 << 9;
16575 - io_req->sector_mask = 0;
16576 - io_req->cow_offset = -1;
16577 - io_req->error = 0;
16579 - if(dev->cow.file != NULL) cowify_req(io_req, dev);
16580 + if(dev->cow.file != NULL)
16581 + cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset,
16582 + dev->cow.bitmap_len);
16587 @@ -841,7 +1038,7 @@
16590 if(thread_fd == -1){
16591 - while(!list_empty(&q->queue_head)){
16592 + while(!elv_queue_empty(q)){
16593 req = elv_next_request(q);
16594 err = prepare_request(req, &io_req);
16596 @@ -851,7 +1048,8 @@
16600 - if(do_ubd || list_empty(&q->queue_head)) return;
16601 + if(do_ubd || elv_queue_empty(q))
16603 req = elv_next_request(q);
16604 err = prepare_request(req, &io_req);
16606 @@ -885,7 +1083,7 @@
16609 g.cylinders = dev->size / (128 * 32 * 512);
16611 + g.start = get_start_sect(inode->i_bdev);
16612 return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0);
16614 case HDIO_SET_UNMASKINTR:
16615 @@ -935,6 +1133,142 @@
16619 +static int ubd_check_remapped(int fd, unsigned long address, int is_write,
16622 + __u64 bitmap_offset;
16623 + unsigned long new_bitmap[2];
16626 + /* If it's not a write access, we can't do anything about it */
16630 + /* We have a write */
16631 + for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){
16632 + struct ubd *dev = &ubd_dev[i];
16634 + if((dev->fd != fd) && (dev->cow.fd != fd))
16637 + /* It's a write to a ubd device */
16639 + if(!dev->openflags.w){
16640 + /* It's a write access on a read-only device - probably
16641 + * shouldn't happen. If the kernel is trying to change
16642 + * something with no intention of writing it back out,
16643 + * then this message will clue us in that this needs
16646 + printk("Write access to mapped page from readonly ubd "
16647 + "device %d\n", i);
16651 + /* It's a write to a writeable ubd device - it must be COWed
16652 + * because, otherwise, the page would have been mapped in
16656 + if(!dev->cow.file)
16657 + panic("Write fault on writeable non-COW ubd device %d",
16660 + /* It should also be an access to the backing file since the
16661 + * COW pages should be mapped in read-write
16664 + if(fd == dev->fd)
16665 + panic("Write fault on a backing page of ubd "
16666 + "device %d\n", i);
16668 + /* So, we do the write, copying the backing data to the COW
16672 + err = os_seek_file(dev->fd, offset + dev->cow.data_offset);
16674 + panic("Couldn't seek to %lld in COW file of ubd "
16675 + "device %d, err = %d",
16676 + offset + dev->cow.data_offset, i, -err);
16678 + n = os_write_file(dev->fd, (void *) address, PAGE_SIZE);
16679 + if(n != PAGE_SIZE)
16680 + panic("Couldn't copy data to COW file of ubd "
16681 + "device %d, err = %d", i, -n);
16683 + /* ... updating the COW bitmap... */
16685 + cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset,
16686 + dev->cow.bitmap, dev->cow.bitmap_offset,
16687 + new_bitmap, dev->cow.bitmap_len);
16689 + err = os_seek_file(dev->fd, bitmap_offset);
16691 + panic("Couldn't seek to %lld in COW file of ubd "
16692 + "device %d, err = %d", bitmap_offset, i, -err);
16694 + n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap));
16695 + if(n != sizeof(new_bitmap))
16696 + panic("Couldn't update bitmap of ubd device %d, "
16697 + "err = %d", i, -n);
16699 + /* Maybe we can map the COW page in, and maybe we can't. If
16700 + * it is a pre-V3 COW file, we can't, since the alignment will
16701 + * be wrong. If it is a V3 or later COW file which has been
16702 + * moved to a system with a larger page size, then maybe we
16703 + * can't, depending on the exact location of the page.
16706 + offset += dev->cow.data_offset;
16708 + /* Remove the remapping, putting the original anonymous page
16709 + * back. If the COW file can be mapped in, that is done.
16710 + * Otherwise, the COW page is read in.
16713 + if(!physmem_remove_mapping((void *) address))
16714 + panic("Address 0x%lx not remapped by ubd device %d",
16716 + if((offset % UBD_MMAP_BLOCK_SIZE) == 0)
16717 + physmem_subst_mapping((void *) address, dev->fd,
16720 + err = os_seek_file(dev->fd, offset);
16722 + panic("Couldn't seek to %lld in COW file of "
16723 + "ubd device %d, err = %d", offset, i,
16726 + n = os_read_file(dev->fd, (void *) address, PAGE_SIZE);
16727 + if(n != PAGE_SIZE)
16728 + panic("Failed to read page from offset %llx of "
16729 + "COW file of ubd device %d, err = %d",
16736 + /* It's not a write on a ubd device */
16740 +static struct remapper ubd_remapper = {
16741 + .list = LIST_HEAD_INIT(ubd_remapper.list),
16742 + .proc = ubd_check_remapped,
16745 +static int ubd_remapper_setup(void)
16748 + register_remapper(&ubd_remapper);
16753 +__initcall(ubd_remapper_setup);
16756 * Overrides for Emacs so that we follow Linus's tabbing style.
16757 * Emacs will notice this stuff at the end of the file and automatically
16758 Index: uml-2.6.7/arch/um/drivers/xterm.c
16759 ===================================================================
16760 --- uml-2.6.7.orig/arch/um/drivers/xterm.c 2004-07-16 19:35:55.930765080 +0300
16761 +++ uml-2.6.7/arch/um/drivers/xterm.c 2004-07-16 19:47:23.699208384 +0300
16763 #include <unistd.h>
16764 #include <string.h>
16766 -#include <fcntl.h>
16767 #include <termios.h>
16768 #include <signal.h>
16772 struct xterm_chan *data;
16774 - if((data = malloc(sizeof(*data))) == NULL) return(NULL);
16775 + data = malloc(sizeof(*data));
16776 + if(data == NULL) return(NULL);
16777 *data = ((struct xterm_chan) { .pid = -1,
16781 "/usr/lib/uml/port-helper", "-uml-socket",
16784 - if(access(argv[4], X_OK))
16785 + if(os_access(argv[4], OS_ACC_X_OK) < 0)
16786 argv[4] = "port-helper";
16788 fd = mkstemp(file);
16789 @@ -106,13 +106,13 @@
16790 printk("xterm_open : unlink failed, errno = %d\n", errno);
16794 + os_close_file(fd);
16796 - fd = create_unix_socket(file, sizeof(file));
16797 + fd = os_create_unix_socket(file, sizeof(file), 1);
16799 printk("xterm_open : create_unix_socket failed, errno = %d\n",
16805 sprintf(title, data->title, data->device);
16806 @@ -128,15 +128,16 @@
16807 if(data->direct_rcv)
16808 new = os_rcv_fd(fd, &data->helper_pid);
16810 - if((err = os_set_fd_block(fd, 0)) != 0){
16811 + err = os_set_fd_block(fd, 0);
16813 printk("xterm_open : failed to set descriptor "
16814 - "non-blocking, errno = %d\n", err);
16815 + "non-blocking, err = %d\n", -err);
16818 new = xterm_fd(fd, &data->helper_pid);
16821 - printk("xterm_open : os_rcv_fd failed, errno = %d\n", -new);
16822 + printk("xterm_open : os_rcv_fd failed, err = %d\n", -new);
16826 @@ -160,7 +161,7 @@
16827 if(data->helper_pid != -1)
16828 os_kill_process(data->helper_pid, 0);
16829 data->helper_pid = -1;
16831 + os_close_file(fd);
16834 void xterm_free(void *d)
16835 Index: uml-2.6.7/arch/um/drivers/mconsole_kern.c
16836 ===================================================================
16837 --- uml-2.6.7.orig/arch/um/drivers/mconsole_kern.c 2004-07-16 19:35:52.654263184 +0300
16838 +++ uml-2.6.7/arch/um/drivers/mconsole_kern.c 2004-07-16 19:47:23.687210208 +0300
16841 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
16842 - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
16843 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
16844 * Licensed under the GPL
16848 #include "linux/sysrq.h"
16849 #include "linux/workqueue.h"
16850 #include "linux/module.h"
16851 +#include "linux/file.h"
16852 +#include "linux/fs.h"
16853 +#include "linux/namei.h"
16854 #include "linux/proc_fs.h"
16855 #include "asm/irq.h"
16856 #include "asm/uaccess.h"
16861 +#include "irq_kern.h"
16863 static int do_unlink_socket(struct notifier_block *notifier,
16864 unsigned long what, void *data)
16867 DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
16869 -void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
16870 +irqreturn_t mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
16873 struct mconsole_entry *new;
16877 while (mconsole_get_request(fd, &req)){
16878 - if(req.cmd->as_interrupt) (*req.cmd->handler)(&req);
16879 + if(req.cmd->context == MCONSOLE_INTR)
16880 + (*req.cmd->handler)(&req);
16882 - new = kmalloc(sizeof(req), GFP_ATOMIC);
16883 + new = kmalloc(sizeof(*new), GFP_ATOMIC);
16885 mconsole_reply(&req, "Out of memory", 1, 0);
16889 if(!list_empty(&mc_requests)) schedule_work(&mconsole_work);
16890 reactivate_fd(fd, MCONSOLE_IRQ);
16891 + return(IRQ_HANDLED);
16894 void mconsole_version(struct mc_request *req)
16895 @@ -100,20 +106,109 @@
16896 mconsole_reply(req, version, 0, 0);
16899 +void mconsole_log(struct mc_request *req)
16902 + char *ptr = req->request.data;
16904 + ptr += strlen("log ");
16906 + len = req->len - (ptr - req->request.data);
16907 + printk("%.*s", len, ptr);
16908 + mconsole_reply(req, "", 0, 0);
16911 +void mconsole_proc(struct mc_request *req)
16913 + struct nameidata nd;
16914 + struct file_system_type *proc;
16915 + struct super_block *super;
16916 + struct file *file;
16918 + char *ptr = req->request.data, *buf;
16920 + ptr += strlen("proc");
16921 + while(isspace(*ptr)) ptr++;
16923 + proc = get_fs_type("proc");
16924 + if(proc == NULL){
16925 + mconsole_reply(req, "procfs not registered", 1, 0);
16929 + super = (*proc->get_sb)(proc, 0, NULL, NULL);
16930 + put_filesystem(proc);
16931 + if(super == NULL){
16932 + mconsole_reply(req, "Failed to get procfs superblock", 1, 0);
16935 + up_write(&super->s_umount);
16937 + nd.dentry = super->s_root;
16939 + nd.flags = O_RDONLY + 1;
16940 + nd.last_type = LAST_ROOT;
16942 + err = link_path_walk(ptr, &nd);
16944 + mconsole_reply(req, "Failed to look up file", 1, 0);
16948 + file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
16949 + if(IS_ERR(file)){
16950 + mconsole_reply(req, "Failed to open file", 1, 0);
16954 + buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
16956 + mconsole_reply(req, "Failed to allocate buffer", 1, 0);
16960 + if((file->f_op != NULL) && (file->f_op->read != NULL)){
16962 + n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1,
16966 + mconsole_reply(req, buf, 0, (n > 0));
16969 + mconsole_reply(req, "Read of file failed",
16975 + else mconsole_reply(req, "", 0, 0);
16982 + deactivate_super(super);
16986 #define UML_MCONSOLE_HELPTEXT \
16988 - version - Get kernel version
16989 - help - Print this message
16991 - reboot - Reboot UML
16992 - config <dev>=<config> - Add a new device to UML;
16993 - same syntax as command line
16994 - config <dev> - Query the configuration of a device
16995 - remove <dev> - Remove a device from UML
16996 - sysrq <letter> - Performs the SysRq action controlled by the letter
16997 - cad - invoke the Ctl-Alt-Del handler
16998 - stop - pause the UML; it will do nothing until it receives a 'go'
16999 - go - continue the UML after a 'stop'
17001 + version - Get kernel version \n\
17002 + help - Print this message \n\
17003 + halt - Halt UML \n\
17004 + reboot - Reboot UML \n\
17005 + config <dev>=<config> - Add a new device to UML; \n\
17006 + same syntax as command line \n\
17007 + config <dev> - Query the configuration of a device \n\
17008 + remove <dev> - Remove a device from UML \n\
17009 + sysrq <letter> - Performs the SysRq action controlled by the letter \n\
17010 + cad - invoke the Ctl-Alt-Del handler \n\
17011 + stop - pause the UML; it will do nothing until it receives a 'go' \n\
17012 + go - continue the UML after a 'stop' \n\
17013 + log <string> - make UML enter <string> into the kernel log\n\
17014 + proc <file> - returns the contents of the UML's /proc/<file>\n\
17017 void mconsole_help(struct mc_request *req)
17018 @@ -302,7 +397,7 @@
17019 if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
17020 snprintf(mconsole_socket_name, sizeof(file), "%s", file);
17022 - sock = create_unix_socket(file, sizeof(file));
17023 + sock = os_create_unix_socket(file, sizeof(file), 1);
17025 printk("Failed to initialize management console\n");
17027 @@ -344,11 +439,16 @@
17031 - if(copy_from_user(buf, buffer, count))
17033 + if(copy_from_user(buf, buffer, count)){
17040 mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count);
17046 Index: uml-2.6.7/arch/um/Makefile-skas
17047 ===================================================================
17048 --- uml-2.6.7.orig/arch/um/Makefile-skas 2004-07-16 19:36:37.092507544 +0300
17049 +++ uml-2.6.7/arch/um/Makefile-skas 2004-07-16 19:47:23.764198504 +0300
17051 LINK_SKAS = -Wl,-rpath,/lib
17052 LD_SCRIPT_SKAS = dyn.lds.s
17054 -GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
17055 +GEN_HEADERS += $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
17057 -$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h :
17058 - $(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h
17059 +$(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h :
17060 + $(Q)$(MAKE) $(build)=$(ARCH_DIR)/kernel/skas $@
17061 Index: uml-2.6.7/arch/um/kernel/sys_call_table.c
17062 ===================================================================
17063 --- uml-2.6.7.orig/arch/um/kernel/sys_call_table.c 2004-07-16 19:37:20.386925792 +0300
17064 +++ uml-2.6.7/arch/um/kernel/sys_call_table.c 2004-07-16 19:47:23.739202304 +0300
17067 #include "linux/config.h"
17068 #include "linux/unistd.h"
17069 -#include "linux/version.h"
17070 #include "linux/sys.h"
17071 #include "linux/swap.h"
17072 #include "linux/syscalls.h"
17073 @@ -14,251 +13,50 @@
17074 #include "sysdep/syscalls.h"
17075 #include "kern_util.h"
17077 -extern syscall_handler_t sys_restart_syscall;
17078 -extern syscall_handler_t sys_ni_syscall;
17079 -extern syscall_handler_t sys_exit;
17080 +#ifdef CONFIG_NFSD
17081 +#define NFSSERVCTL sys_nfsservctl
17083 +#define NFSSERVCTL sys_ni_syscall
17086 +#define LAST_GENERIC_SYSCALL __NR_vserver
17088 +#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
17089 +#define LAST_SYSCALL LAST_GENERIC_SYSCALL
17091 +#define LAST_SYSCALL LAST_ARCH_SYSCALL
17094 extern syscall_handler_t sys_fork;
17095 -extern syscall_handler_t sys_creat;
17096 -extern syscall_handler_t sys_link;
17097 -extern syscall_handler_t sys_unlink;
17098 -extern syscall_handler_t sys_chdir;
17099 -extern syscall_handler_t sys_mknod;
17100 -extern syscall_handler_t sys_chmod;
17101 -extern syscall_handler_t sys_lchown16;
17102 -extern syscall_handler_t sys_ni_syscall;
17103 -extern syscall_handler_t sys_stat;
17104 -extern syscall_handler_t sys_getpid;
17105 -extern syscall_handler_t sys_oldumount;
17106 -extern syscall_handler_t sys_setuid16;
17107 -extern syscall_handler_t sys_getuid16;
17108 +extern syscall_handler_t sys_execve;
17109 +extern syscall_handler_t um_time;
17110 +extern syscall_handler_t um_mount;
17111 +extern syscall_handler_t um_stime;
17112 extern syscall_handler_t sys_ptrace;
17113 -extern syscall_handler_t sys_alarm;
17114 -extern syscall_handler_t sys_fstat;
17115 -extern syscall_handler_t sys_pause;
17116 -extern syscall_handler_t sys_utime;
17117 -extern syscall_handler_t sys_ni_syscall;
17118 -extern syscall_handler_t sys_ni_syscall;
17119 -extern syscall_handler_t sys_access;
17120 -extern syscall_handler_t sys_nice;
17121 -extern syscall_handler_t sys_ni_syscall;
17122 -extern syscall_handler_t sys_sync;
17123 -extern syscall_handler_t sys_kill;
17124 -extern syscall_handler_t sys_rename;
17125 -extern syscall_handler_t sys_mkdir;
17126 -extern syscall_handler_t sys_rmdir;
17127 extern syscall_handler_t sys_pipe;
17128 -extern syscall_handler_t sys_times;
17129 -extern syscall_handler_t sys_ni_syscall;
17130 -extern syscall_handler_t sys_brk;
17131 -extern syscall_handler_t sys_setgid16;
17132 -extern syscall_handler_t sys_getgid16;
17133 -extern syscall_handler_t sys_signal;
17134 -extern syscall_handler_t sys_geteuid16;
17135 -extern syscall_handler_t sys_getegid16;
17136 -extern syscall_handler_t sys_acct;
17137 -extern syscall_handler_t sys_umount;
17138 -extern syscall_handler_t sys_ni_syscall;
17139 -extern syscall_handler_t sys_ioctl;
17140 -extern syscall_handler_t sys_fcntl;
17141 -extern syscall_handler_t sys_ni_syscall;
17142 -extern syscall_handler_t sys_setpgid;
17143 -extern syscall_handler_t sys_ni_syscall;
17144 extern syscall_handler_t sys_olduname;
17145 -extern syscall_handler_t sys_umask;
17146 -extern syscall_handler_t sys_chroot;
17147 -extern syscall_handler_t sys_ustat;
17148 -extern syscall_handler_t sys_dup2;
17149 -extern syscall_handler_t sys_getppid;
17150 -extern syscall_handler_t sys_getpgrp;
17151 extern syscall_handler_t sys_sigaction;
17152 -extern syscall_handler_t sys_sgetmask;
17153 -extern syscall_handler_t sys_ssetmask;
17154 -extern syscall_handler_t sys_setreuid16;
17155 -extern syscall_handler_t sys_setregid16;
17156 extern syscall_handler_t sys_sigsuspend;
17157 -extern syscall_handler_t sys_sigpending;
17158 -extern syscall_handler_t sys_sethostname;
17159 -extern syscall_handler_t sys_setrlimit;
17160 -extern syscall_handler_t sys_old_getrlimit;
17161 -extern syscall_handler_t sys_getrusage;
17162 -extern syscall_handler_t sys_gettimeofday;
17163 -extern syscall_handler_t sys_settimeofday;
17164 -extern syscall_handler_t sys_getgroups16;
17165 -extern syscall_handler_t sys_setgroups16;
17166 -extern syscall_handler_t sys_symlink;
17167 -extern syscall_handler_t sys_lstat;
17168 -extern syscall_handler_t sys_readlink;
17169 -extern syscall_handler_t sys_swapon;
17170 -extern syscall_handler_t sys_uselib;
17171 -extern syscall_handler_t sys_reboot;
17172 extern syscall_handler_t old_readdir;
17173 -extern syscall_handler_t sys_munmap;
17174 -extern syscall_handler_t sys_truncate;
17175 -extern syscall_handler_t sys_ftruncate;
17176 -extern syscall_handler_t sys_fchmod;
17177 -extern syscall_handler_t sys_fchown16;
17178 -extern syscall_handler_t sys_getpriority;
17179 -extern syscall_handler_t sys_setpriority;
17180 -extern syscall_handler_t sys_ni_syscall;
17181 -extern syscall_handler_t sys_statfs;
17182 -extern syscall_handler_t sys_fstatfs;
17183 -extern syscall_handler_t sys_ni_syscall;
17184 -extern syscall_handler_t sys_socketcall;
17185 -extern syscall_handler_t sys_syslog;
17186 -extern syscall_handler_t sys_setitimer;
17187 -extern syscall_handler_t sys_getitimer;
17188 -extern syscall_handler_t sys_newstat;
17189 -extern syscall_handler_t sys_newlstat;
17190 -extern syscall_handler_t sys_newfstat;
17191 extern syscall_handler_t sys_uname;
17192 -extern syscall_handler_t sys_ni_syscall;
17193 -extern syscall_handler_t sys_vhangup;
17194 -extern syscall_handler_t sys_ni_syscall;
17195 -extern syscall_handler_t sys_ni_syscall;
17196 -extern syscall_handler_t sys_swapoff;
17197 -extern syscall_handler_t sys_sysinfo;
17198 extern syscall_handler_t sys_ipc;
17199 -extern syscall_handler_t sys_fsync;
17200 extern syscall_handler_t sys_sigreturn;
17201 -extern syscall_handler_t sys_rt_sigreturn;
17202 extern syscall_handler_t sys_clone;
17203 -extern syscall_handler_t sys_setdomainname;
17204 -extern syscall_handler_t sys_newuname;
17205 -extern syscall_handler_t sys_ni_syscall;
17206 -extern syscall_handler_t sys_adjtimex;
17207 -extern syscall_handler_t sys_mprotect;
17208 -extern syscall_handler_t sys_sigprocmask;
17209 -extern syscall_handler_t sys_init_module;
17210 -extern syscall_handler_t sys_delete_module;
17211 -extern syscall_handler_t sys_quotactl;
17212 -extern syscall_handler_t sys_getpgid;
17213 -extern syscall_handler_t sys_fchdir;
17214 -extern syscall_handler_t sys_bdflush;
17215 -extern syscall_handler_t sys_sysfs;
17216 -extern syscall_handler_t sys_personality;
17217 -extern syscall_handler_t sys_ni_syscall;
17218 -extern syscall_handler_t sys_setfsuid16;
17219 -extern syscall_handler_t sys_setfsgid16;
17220 -extern syscall_handler_t sys_llseek;
17221 -extern syscall_handler_t sys_getdents;
17222 -extern syscall_handler_t sys_flock;
17223 -extern syscall_handler_t sys_msync;
17224 -extern syscall_handler_t sys_readv;
17225 -extern syscall_handler_t sys_writev;
17226 -extern syscall_handler_t sys_getsid;
17227 -extern syscall_handler_t sys_fdatasync;
17228 -extern syscall_handler_t sys_mlock;
17229 -extern syscall_handler_t sys_munlock;
17230 -extern syscall_handler_t sys_mlockall;
17231 -extern syscall_handler_t sys_munlockall;
17232 -extern syscall_handler_t sys_sched_setparam;
17233 -extern syscall_handler_t sys_sched_getparam;
17234 -extern syscall_handler_t sys_sched_setscheduler;
17235 -extern syscall_handler_t sys_sched_getscheduler;
17236 -extern syscall_handler_t sys_sched_get_priority_max;
17237 -extern syscall_handler_t sys_sched_get_priority_min;
17238 -extern syscall_handler_t sys_sched_rr_get_interval;
17239 -extern syscall_handler_t sys_nanosleep;
17240 -extern syscall_handler_t sys_mremap;
17241 -extern syscall_handler_t sys_setresuid16;
17242 -extern syscall_handler_t sys_getresuid16;
17243 -extern syscall_handler_t sys_ni_syscall;
17244 -extern syscall_handler_t sys_poll;
17245 -extern syscall_handler_t sys_nfsservctl;
17246 -extern syscall_handler_t sys_setresgid16;
17247 -extern syscall_handler_t sys_getresgid16;
17248 -extern syscall_handler_t sys_prctl;
17249 -extern syscall_handler_t sys_ni_syscall;
17250 +extern syscall_handler_t sys_rt_sigreturn;
17251 extern syscall_handler_t sys_rt_sigaction;
17252 -extern syscall_handler_t sys_rt_sigprocmask;
17253 -extern syscall_handler_t sys_rt_sigpending;
17254 -extern syscall_handler_t sys_rt_sigtimedwait;
17255 -extern syscall_handler_t sys_rt_sigqueueinfo;
17256 -extern syscall_handler_t sys_rt_sigsuspend;
17257 -extern syscall_handler_t sys_pread64;
17258 -extern syscall_handler_t sys_pwrite64;
17259 -extern syscall_handler_t sys_chown16;
17260 -extern syscall_handler_t sys_getcwd;
17261 -extern syscall_handler_t sys_capget;
17262 -extern syscall_handler_t sys_capset;
17263 extern syscall_handler_t sys_sigaltstack;
17264 -extern syscall_handler_t sys_sendfile;
17265 -extern syscall_handler_t sys_ni_syscall;
17266 -extern syscall_handler_t sys_ni_syscall;
17267 extern syscall_handler_t sys_vfork;
17268 -extern syscall_handler_t sys_getrlimit;
17269 extern syscall_handler_t sys_mmap2;
17270 -extern syscall_handler_t sys_truncate64;
17271 -extern syscall_handler_t sys_ftruncate64;
17272 -extern syscall_handler_t sys_stat64;
17273 -extern syscall_handler_t sys_lstat64;
17274 -extern syscall_handler_t sys_fstat64;
17275 -extern syscall_handler_t sys_lchown;
17276 -extern syscall_handler_t sys_getuid;
17277 -extern syscall_handler_t sys_getgid;
17278 -extern syscall_handler_t sys_geteuid;
17279 -extern syscall_handler_t sys_getegid;
17280 -extern syscall_handler_t sys_setreuid;
17281 -extern syscall_handler_t sys_setregid;
17282 -extern syscall_handler_t sys_getgroups;
17283 -extern syscall_handler_t sys_setgroups;
17284 -extern syscall_handler_t sys_fchown;
17285 -extern syscall_handler_t sys_setresuid;
17286 -extern syscall_handler_t sys_getresuid;
17287 -extern syscall_handler_t sys_setresgid;
17288 -extern syscall_handler_t sys_getresgid;
17289 -extern syscall_handler_t sys_chown;
17290 -extern syscall_handler_t sys_setuid;
17291 -extern syscall_handler_t sys_setgid;
17292 -extern syscall_handler_t sys_setfsuid;
17293 -extern syscall_handler_t sys_setfsgid;
17294 -extern syscall_handler_t sys_pivot_root;
17295 -extern syscall_handler_t sys_mincore;
17296 -extern syscall_handler_t sys_madvise;
17297 -extern syscall_handler_t sys_fcntl64;
17298 -extern syscall_handler_t sys_getdents64;
17299 -extern syscall_handler_t sys_gettid;
17300 -extern syscall_handler_t sys_readahead;
17301 -extern syscall_handler_t sys_tkill;
17302 -extern syscall_handler_t sys_sendfile64;
17303 -extern syscall_handler_t sys_futex;
17304 -extern syscall_handler_t sys_sched_setaffinity;
17305 -extern syscall_handler_t sys_sched_getaffinity;
17306 -extern syscall_handler_t sys_io_setup;
17307 -extern syscall_handler_t sys_io_destroy;
17308 -extern syscall_handler_t sys_io_getevents;
17309 -extern syscall_handler_t sys_io_submit;
17310 -extern syscall_handler_t sys_io_cancel;
17311 -extern syscall_handler_t sys_exit_group;
17312 -extern syscall_handler_t sys_lookup_dcookie;
17313 -extern syscall_handler_t sys_epoll_create;
17314 -extern syscall_handler_t sys_epoll_ctl;
17315 -extern syscall_handler_t sys_epoll_wait;
17316 -extern syscall_handler_t sys_remap_file_pages;
17317 -extern syscall_handler_t sys_set_tid_address;
17319 -#ifdef CONFIG_NFSD
17320 -#define NFSSERVCTL sys_nfsservctl
17322 -#define NFSSERVCTL sys_ni_syscall
17325 -extern syscall_handler_t um_mount;
17326 -extern syscall_handler_t um_time;
17327 -extern syscall_handler_t um_stime;
17329 -#define LAST_GENERIC_SYSCALL __NR_set_tid_address
17331 -#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
17332 -#define LAST_SYSCALL LAST_GENERIC_SYSCALL
17334 -#define LAST_SYSCALL LAST_ARCH_SYSCALL
17336 +extern syscall_handler_t sys_timer_create;
17337 +extern syscall_handler_t old_mmap_i386;
17338 +extern syscall_handler_t old_select;
17339 +extern syscall_handler_t sys_modify_ldt;
17340 +extern syscall_handler_t sys_rt_sigsuspend;
17342 syscall_handler_t *sys_call_table[] = {
17343 - [ __NR_restart_syscall ] = sys_restart_syscall,
17344 - [ __NR_exit ] = sys_exit,
17345 - [ __NR_fork ] = sys_fork,
17346 + [ __NR_restart_syscall ] = (syscall_handler_t *) sys_restart_syscall,
17347 + [ __NR_exit ] (syscall_handler_t *) sys_exit,
17348 + [ __NR_fork ] (syscall_handler_t *) sys_fork,
17349 [ __NR_read ] = (syscall_handler_t *) sys_read,
17350 [ __NR_write ] = (syscall_handler_t *) sys_write,
17352 @@ -266,229 +64,249 @@
17353 [ __NR_open ] = (syscall_handler_t *) sys_open,
17354 [ __NR_close ] = (syscall_handler_t *) sys_close,
17355 [ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid,
17356 - [ __NR_creat ] = sys_creat,
17357 - [ __NR_link ] = sys_link,
17358 - [ __NR_unlink ] = sys_unlink,
17359 + [ __NR_creat ] (syscall_handler_t *) sys_creat,
17360 + [ __NR_link ] (syscall_handler_t *) sys_link,
17361 + [ __NR_unlink ] (syscall_handler_t *) sys_unlink,
17362 [ __NR_execve ] = (syscall_handler_t *) sys_execve,
17364 /* declared differently in kern_util.h */
17365 - [ __NR_chdir ] = sys_chdir,
17366 + [ __NR_chdir ] (syscall_handler_t *) sys_chdir,
17367 [ __NR_time ] = um_time,
17368 - [ __NR_mknod ] = sys_mknod,
17369 - [ __NR_chmod ] = sys_chmod,
17370 - [ __NR_lchown ] = sys_lchown16,
17371 - [ __NR_break ] = sys_ni_syscall,
17372 - [ __NR_oldstat ] = sys_stat,
17373 + [ __NR_mknod ] (syscall_handler_t *) sys_mknod,
17374 + [ __NR_chmod ] (syscall_handler_t *) sys_chmod,
17375 + [ __NR_lchown ] (syscall_handler_t *) sys_lchown16,
17376 + [ __NR_break ] (syscall_handler_t *) sys_ni_syscall,
17377 + [ __NR_oldstat ] (syscall_handler_t *) sys_stat,
17378 [ __NR_lseek ] = (syscall_handler_t *) sys_lseek,
17379 - [ __NR_getpid ] = sys_getpid,
17380 + [ __NR_getpid ] (syscall_handler_t *) sys_getpid,
17381 [ __NR_mount ] = um_mount,
17382 - [ __NR_umount ] = sys_oldumount,
17383 - [ __NR_setuid ] = sys_setuid16,
17384 - [ __NR_getuid ] = sys_getuid16,
17385 + [ __NR_umount ] (syscall_handler_t *) sys_oldumount,
17386 + [ __NR_setuid ] (syscall_handler_t *) sys_setuid16,
17387 + [ __NR_getuid ] (syscall_handler_t *) sys_getuid16,
17388 [ __NR_stime ] = um_stime,
17389 - [ __NR_ptrace ] = sys_ptrace,
17390 - [ __NR_alarm ] = sys_alarm,
17391 - [ __NR_oldfstat ] = sys_fstat,
17392 - [ __NR_pause ] = sys_pause,
17393 - [ __NR_utime ] = sys_utime,
17394 - [ __NR_stty ] = sys_ni_syscall,
17395 - [ __NR_gtty ] = sys_ni_syscall,
17396 - [ __NR_access ] = sys_access,
17397 - [ __NR_nice ] = sys_nice,
17398 - [ __NR_ftime ] = sys_ni_syscall,
17399 - [ __NR_sync ] = sys_sync,
17400 - [ __NR_kill ] = sys_kill,
17401 - [ __NR_rename ] = sys_rename,
17402 - [ __NR_mkdir ] = sys_mkdir,
17403 - [ __NR_rmdir ] = sys_rmdir,
17404 + [ __NR_ptrace ] (syscall_handler_t *) sys_ptrace,
17405 + [ __NR_alarm ] (syscall_handler_t *) sys_alarm,
17406 + [ __NR_oldfstat ] (syscall_handler_t *) sys_fstat,
17407 + [ __NR_pause ] (syscall_handler_t *) sys_pause,
17408 + [ __NR_utime ] (syscall_handler_t *) sys_utime,
17409 + [ __NR_stty ] (syscall_handler_t *) sys_ni_syscall,
17410 + [ __NR_gtty ] (syscall_handler_t *) sys_ni_syscall,
17411 + [ __NR_access ] (syscall_handler_t *) sys_access,
17412 + [ __NR_nice ] (syscall_handler_t *) sys_nice,
17413 + [ __NR_ftime ] (syscall_handler_t *) sys_ni_syscall,
17414 + [ __NR_sync ] (syscall_handler_t *) sys_sync,
17415 + [ __NR_kill ] (syscall_handler_t *) sys_kill,
17416 + [ __NR_rename ] (syscall_handler_t *) sys_rename,
17417 + [ __NR_mkdir ] (syscall_handler_t *) sys_mkdir,
17418 + [ __NR_rmdir ] (syscall_handler_t *) sys_rmdir,
17420 /* Declared differently in asm/unistd.h */
17421 [ __NR_dup ] = (syscall_handler_t *) sys_dup,
17422 - [ __NR_pipe ] = sys_pipe,
17423 - [ __NR_times ] = sys_times,
17424 - [ __NR_prof ] = sys_ni_syscall,
17425 - [ __NR_brk ] = sys_brk,
17426 - [ __NR_setgid ] = sys_setgid16,
17427 - [ __NR_getgid ] = sys_getgid16,
17428 - [ __NR_signal ] = sys_signal,
17429 - [ __NR_geteuid ] = sys_geteuid16,
17430 - [ __NR_getegid ] = sys_getegid16,
17431 - [ __NR_acct ] = sys_acct,
17432 - [ __NR_umount2 ] = sys_umount,
17433 - [ __NR_lock ] = sys_ni_syscall,
17434 - [ __NR_ioctl ] = sys_ioctl,
17435 - [ __NR_fcntl ] = sys_fcntl,
17436 - [ __NR_mpx ] = sys_ni_syscall,
17437 - [ __NR_setpgid ] = sys_setpgid,
17438 - [ __NR_ulimit ] = sys_ni_syscall,
17439 - [ __NR_oldolduname ] = sys_olduname,
17440 - [ __NR_umask ] = sys_umask,
17441 - [ __NR_chroot ] = sys_chroot,
17442 - [ __NR_ustat ] = sys_ustat,
17443 - [ __NR_dup2 ] = sys_dup2,
17444 - [ __NR_getppid ] = sys_getppid,
17445 - [ __NR_getpgrp ] = sys_getpgrp,
17446 + [ __NR_pipe ] (syscall_handler_t *) sys_pipe,
17447 + [ __NR_times ] (syscall_handler_t *) sys_times,
17448 + [ __NR_prof ] (syscall_handler_t *) sys_ni_syscall,
17449 + [ __NR_brk ] (syscall_handler_t *) sys_brk,
17450 + [ __NR_setgid ] (syscall_handler_t *) sys_setgid16,
17451 + [ __NR_getgid ] (syscall_handler_t *) sys_getgid16,
17452 + [ __NR_signal ] (syscall_handler_t *) sys_signal,
17453 + [ __NR_geteuid ] (syscall_handler_t *) sys_geteuid16,
17454 + [ __NR_getegid ] (syscall_handler_t *) sys_getegid16,
17455 + [ __NR_acct ] (syscall_handler_t *) sys_acct,
17456 + [ __NR_umount2 ] (syscall_handler_t *) sys_umount,
17457 + [ __NR_lock ] (syscall_handler_t *) sys_ni_syscall,
17458 + [ __NR_ioctl ] (syscall_handler_t *) sys_ioctl,
17459 + [ __NR_fcntl ] (syscall_handler_t *) sys_fcntl,
17460 + [ __NR_mpx ] (syscall_handler_t *) sys_ni_syscall,
17461 + [ __NR_setpgid ] (syscall_handler_t *) sys_setpgid,
17462 + [ __NR_ulimit ] (syscall_handler_t *) sys_ni_syscall,
17463 + [ __NR_oldolduname ] (syscall_handler_t *) sys_olduname,
17464 + [ __NR_umask ] (syscall_handler_t *) sys_umask,
17465 + [ __NR_chroot ] (syscall_handler_t *) sys_chroot,
17466 + [ __NR_ustat ] (syscall_handler_t *) sys_ustat,
17467 + [ __NR_dup2 ] (syscall_handler_t *) sys_dup2,
17468 + [ __NR_getppid ] (syscall_handler_t *) sys_getppid,
17469 + [ __NR_getpgrp ] (syscall_handler_t *) sys_getpgrp,
17470 [ __NR_setsid ] = (syscall_handler_t *) sys_setsid,
17471 - [ __NR_sigaction ] = sys_sigaction,
17472 - [ __NR_sgetmask ] = sys_sgetmask,
17473 - [ __NR_ssetmask ] = sys_ssetmask,
17474 - [ __NR_setreuid ] = sys_setreuid16,
17475 - [ __NR_setregid ] = sys_setregid16,
17476 - [ __NR_sigsuspend ] = sys_sigsuspend,
17477 - [ __NR_sigpending ] = sys_sigpending,
17478 - [ __NR_sethostname ] = sys_sethostname,
17479 - [ __NR_setrlimit ] = sys_setrlimit,
17480 - [ __NR_getrlimit ] = sys_old_getrlimit,
17481 - [ __NR_getrusage ] = sys_getrusage,
17482 - [ __NR_gettimeofday ] = sys_gettimeofday,
17483 - [ __NR_settimeofday ] = sys_settimeofday,
17484 - [ __NR_getgroups ] = sys_getgroups16,
17485 - [ __NR_setgroups ] = sys_setgroups16,
17486 - [ __NR_symlink ] = sys_symlink,
17487 - [ __NR_oldlstat ] = sys_lstat,
17488 - [ __NR_readlink ] = sys_readlink,
17489 - [ __NR_uselib ] = sys_uselib,
17490 + [ __NR_sigaction ] (syscall_handler_t *) sys_sigaction,
17491 + [ __NR_sgetmask ] (syscall_handler_t *) sys_sgetmask,
17492 + [ __NR_ssetmask ] (syscall_handler_t *) sys_ssetmask,
17493 + [ __NR_setreuid ] (syscall_handler_t *) sys_setreuid16,
17494 + [ __NR_setregid ] (syscall_handler_t *) sys_setregid16,
17495 + [ __NR_sigsuspend ] (syscall_handler_t *) sys_sigsuspend,
17496 + [ __NR_sigpending ] (syscall_handler_t *) sys_sigpending,
17497 + [ __NR_sethostname ] (syscall_handler_t *) sys_sethostname,
17498 + [ __NR_setrlimit ] (syscall_handler_t *) sys_setrlimit,
17499 + [ __NR_getrlimit ] (syscall_handler_t *) sys_old_getrlimit,
17500 + [ __NR_getrusage ] (syscall_handler_t *) sys_getrusage,
17501 + [ __NR_gettimeofday ] (syscall_handler_t *) sys_gettimeofday,
17502 + [ __NR_settimeofday ] (syscall_handler_t *) sys_settimeofday,
17503 + [ __NR_getgroups ] (syscall_handler_t *) sys_getgroups16,
17504 + [ __NR_setgroups ] (syscall_handler_t *) sys_setgroups16,
17505 + [ __NR_symlink ] (syscall_handler_t *) sys_symlink,
17506 + [ __NR_oldlstat ] (syscall_handler_t *) sys_lstat,
17507 + [ __NR_readlink ] (syscall_handler_t *) sys_readlink,
17508 + [ __NR_uselib ] (syscall_handler_t *) sys_uselib,
17509 [ __NR_swapon ] = (syscall_handler_t *) sys_swapon,
17510 - [ __NR_reboot ] = sys_reboot,
17511 + [ __NR_reboot ] (syscall_handler_t *) sys_reboot,
17512 [ __NR_readdir ] = old_readdir,
17513 - [ __NR_munmap ] = sys_munmap,
17514 - [ __NR_truncate ] = sys_truncate,
17515 - [ __NR_ftruncate ] = sys_ftruncate,
17516 - [ __NR_fchmod ] = sys_fchmod,
17517 - [ __NR_fchown ] = sys_fchown16,
17518 - [ __NR_getpriority ] = sys_getpriority,
17519 - [ __NR_setpriority ] = sys_setpriority,
17520 - [ __NR_profil ] = sys_ni_syscall,
17521 - [ __NR_statfs ] = sys_statfs,
17522 - [ __NR_fstatfs ] = sys_fstatfs,
17523 - [ __NR_ioperm ] = sys_ni_syscall,
17524 - [ __NR_socketcall ] = sys_socketcall,
17525 - [ __NR_syslog ] = sys_syslog,
17526 - [ __NR_setitimer ] = sys_setitimer,
17527 - [ __NR_getitimer ] = sys_getitimer,
17528 - [ __NR_stat ] = sys_newstat,
17529 - [ __NR_lstat ] = sys_newlstat,
17530 - [ __NR_fstat ] = sys_newfstat,
17531 - [ __NR_olduname ] = sys_uname,
17532 - [ __NR_iopl ] = sys_ni_syscall,
17533 - [ __NR_vhangup ] = sys_vhangup,
17534 - [ __NR_idle ] = sys_ni_syscall,
17535 + [ __NR_munmap ] (syscall_handler_t *) sys_munmap,
17536 + [ __NR_truncate ] (syscall_handler_t *) sys_truncate,
17537 + [ __NR_ftruncate ] (syscall_handler_t *) sys_ftruncate,
17538 + [ __NR_fchmod ] (syscall_handler_t *) sys_fchmod,
17539 + [ __NR_fchown ] (syscall_handler_t *) sys_fchown16,
17540 + [ __NR_getpriority ] (syscall_handler_t *) sys_getpriority,
17541 + [ __NR_setpriority ] (syscall_handler_t *) sys_setpriority,
17542 + [ __NR_profil ] (syscall_handler_t *) sys_ni_syscall,
17543 + [ __NR_statfs ] (syscall_handler_t *) sys_statfs,
17544 + [ __NR_fstatfs ] (syscall_handler_t *) sys_fstatfs,
17545 + [ __NR_ioperm ] (syscall_handler_t *) sys_ni_syscall,
17546 + [ __NR_socketcall ] (syscall_handler_t *) sys_socketcall,
17547 + [ __NR_syslog ] (syscall_handler_t *) sys_syslog,
17548 + [ __NR_setitimer ] (syscall_handler_t *) sys_setitimer,
17549 + [ __NR_getitimer ] (syscall_handler_t *) sys_getitimer,
17550 + [ __NR_stat ] (syscall_handler_t *) sys_newstat,
17551 + [ __NR_lstat ] (syscall_handler_t *) sys_newlstat,
17552 + [ __NR_fstat ] (syscall_handler_t *) sys_newfstat,
17553 + [ __NR_olduname ] (syscall_handler_t *) sys_uname,
17554 + [ __NR_iopl ] (syscall_handler_t *) sys_ni_syscall,
17555 + [ __NR_vhangup ] (syscall_handler_t *) sys_vhangup,
17556 + [ __NR_idle ] (syscall_handler_t *) sys_ni_syscall,
17557 [ __NR_wait4 ] = (syscall_handler_t *) sys_wait4,
17558 [ __NR_swapoff ] = (syscall_handler_t *) sys_swapoff,
17559 - [ __NR_sysinfo ] = sys_sysinfo,
17560 - [ __NR_ipc ] = sys_ipc,
17561 - [ __NR_fsync ] = sys_fsync,
17562 - [ __NR_sigreturn ] = sys_sigreturn,
17563 - [ __NR_clone ] = sys_clone,
17564 - [ __NR_setdomainname ] = sys_setdomainname,
17565 - [ __NR_uname ] = sys_newuname,
17566 - [ __NR_adjtimex ] = sys_adjtimex,
17567 - [ __NR_mprotect ] = sys_mprotect,
17568 - [ __NR_sigprocmask ] = sys_sigprocmask,
17569 - [ __NR_create_module ] = sys_ni_syscall,
17570 - [ __NR_init_module ] = sys_init_module,
17571 - [ __NR_delete_module ] = sys_delete_module,
17572 - [ __NR_get_kernel_syms ] = sys_ni_syscall,
17573 - [ __NR_quotactl ] = sys_quotactl,
17574 - [ __NR_getpgid ] = sys_getpgid,
17575 - [ __NR_fchdir ] = sys_fchdir,
17576 - [ __NR_bdflush ] = sys_bdflush,
17577 - [ __NR_sysfs ] = sys_sysfs,
17578 - [ __NR_personality ] = sys_personality,
17579 - [ __NR_afs_syscall ] = sys_ni_syscall,
17580 - [ __NR_setfsuid ] = sys_setfsuid16,
17581 - [ __NR_setfsgid ] = sys_setfsgid16,
17582 - [ __NR__llseek ] = sys_llseek,
17583 - [ __NR_getdents ] = sys_getdents,
17584 + [ __NR_sysinfo ] (syscall_handler_t *) sys_sysinfo,
17585 + [ __NR_ipc ] (syscall_handler_t *) sys_ipc,
17586 + [ __NR_fsync ] (syscall_handler_t *) sys_fsync,
17587 + [ __NR_sigreturn ] (syscall_handler_t *) sys_sigreturn,
17588 + [ __NR_clone ] (syscall_handler_t *) sys_clone,
17589 + [ __NR_setdomainname ] (syscall_handler_t *) sys_setdomainname,
17590 + [ __NR_uname ] (syscall_handler_t *) sys_newuname,
17591 + [ __NR_adjtimex ] (syscall_handler_t *) sys_adjtimex,
17592 + [ __NR_mprotect ] (syscall_handler_t *) sys_mprotect,
17593 + [ __NR_sigprocmask ] (syscall_handler_t *) sys_sigprocmask,
17594 + [ __NR_create_module ] (syscall_handler_t *) sys_ni_syscall,
17595 + [ __NR_init_module ] (syscall_handler_t *) sys_init_module,
17596 + [ __NR_delete_module ] (syscall_handler_t *) sys_delete_module,
17597 + [ __NR_get_kernel_syms ] (syscall_handler_t *) sys_ni_syscall,
17598 + [ __NR_quotactl ] (syscall_handler_t *) sys_quotactl,
17599 + [ __NR_getpgid ] (syscall_handler_t *) sys_getpgid,
17600 + [ __NR_fchdir ] (syscall_handler_t *) sys_fchdir,
17601 + [ __NR_bdflush ] (syscall_handler_t *) sys_bdflush,
17602 + [ __NR_sysfs ] (syscall_handler_t *) sys_sysfs,
17603 + [ __NR_personality ] (syscall_handler_t *) sys_personality,
17604 + [ __NR_afs_syscall ] (syscall_handler_t *) sys_ni_syscall,
17605 + [ __NR_setfsuid ] (syscall_handler_t *) sys_setfsuid16,
17606 + [ __NR_setfsgid ] (syscall_handler_t *) sys_setfsgid16,
17607 + [ __NR__llseek ] (syscall_handler_t *) sys_llseek,
17608 + [ __NR_getdents ] (syscall_handler_t *) sys_getdents,
17609 [ __NR__newselect ] = (syscall_handler_t *) sys_select,
17610 - [ __NR_flock ] = sys_flock,
17611 - [ __NR_msync ] = sys_msync,
17612 - [ __NR_readv ] = sys_readv,
17613 - [ __NR_writev ] = sys_writev,
17614 - [ __NR_getsid ] = sys_getsid,
17615 - [ __NR_fdatasync ] = sys_fdatasync,
17616 + [ __NR_flock ] (syscall_handler_t *) sys_flock,
17617 + [ __NR_msync ] (syscall_handler_t *) sys_msync,
17618 + [ __NR_readv ] (syscall_handler_t *) sys_readv,
17619 + [ __NR_writev ] (syscall_handler_t *) sys_writev,
17620 + [ __NR_getsid ] (syscall_handler_t *) sys_getsid,
17621 + [ __NR_fdatasync ] (syscall_handler_t *) sys_fdatasync,
17622 [ __NR__sysctl ] = (syscall_handler_t *) sys_sysctl,
17623 - [ __NR_mlock ] = sys_mlock,
17624 - [ __NR_munlock ] = sys_munlock,
17625 - [ __NR_mlockall ] = sys_mlockall,
17626 - [ __NR_munlockall ] = sys_munlockall,
17627 - [ __NR_sched_setparam ] = sys_sched_setparam,
17628 - [ __NR_sched_getparam ] = sys_sched_getparam,
17629 - [ __NR_sched_setscheduler ] = sys_sched_setscheduler,
17630 - [ __NR_sched_getscheduler ] = sys_sched_getscheduler,
17631 + [ __NR_mlock ] (syscall_handler_t *) sys_mlock,
17632 + [ __NR_munlock ] (syscall_handler_t *) sys_munlock,
17633 + [ __NR_mlockall ] (syscall_handler_t *) sys_mlockall,
17634 + [ __NR_munlockall ] (syscall_handler_t *) sys_munlockall,
17635 + [ __NR_sched_setparam ] (syscall_handler_t *) sys_sched_setparam,
17636 + [ __NR_sched_getparam ] (syscall_handler_t *) sys_sched_getparam,
17637 + [ __NR_sched_setscheduler ] (syscall_handler_t *) sys_sched_setscheduler,
17638 + [ __NR_sched_getscheduler ] (syscall_handler_t *) sys_sched_getscheduler,
17639 [ __NR_sched_yield ] = (syscall_handler_t *) yield,
17640 - [ __NR_sched_get_priority_max ] = sys_sched_get_priority_max,
17641 - [ __NR_sched_get_priority_min ] = sys_sched_get_priority_min,
17642 - [ __NR_sched_rr_get_interval ] = sys_sched_rr_get_interval,
17643 - [ __NR_nanosleep ] = sys_nanosleep,
17644 - [ __NR_mremap ] = sys_mremap,
17645 - [ __NR_setresuid ] = sys_setresuid16,
17646 - [ __NR_getresuid ] = sys_getresuid16,
17647 - [ __NR_vm86 ] = sys_ni_syscall,
17648 - [ __NR_query_module ] = sys_ni_syscall,
17649 - [ __NR_poll ] = sys_poll,
17650 - [ __NR_nfsservctl ] = NFSSERVCTL,
17651 - [ __NR_setresgid ] = sys_setresgid16,
17652 - [ __NR_getresgid ] = sys_getresgid16,
17653 - [ __NR_prctl ] = sys_prctl,
17654 - [ __NR_rt_sigreturn ] = sys_rt_sigreturn,
17655 - [ __NR_rt_sigaction ] = sys_rt_sigaction,
17656 - [ __NR_rt_sigprocmask ] = sys_rt_sigprocmask,
17657 - [ __NR_rt_sigpending ] = sys_rt_sigpending,
17658 - [ __NR_rt_sigtimedwait ] = sys_rt_sigtimedwait,
17659 - [ __NR_rt_sigqueueinfo ] = sys_rt_sigqueueinfo,
17660 - [ __NR_rt_sigsuspend ] = sys_rt_sigsuspend,
17661 - [ __NR_pread64 ] = sys_pread64,
17662 - [ __NR_pwrite64 ] = sys_pwrite64,
17663 - [ __NR_chown ] = sys_chown16,
17664 - [ __NR_getcwd ] = sys_getcwd,
17665 - [ __NR_capget ] = sys_capget,
17666 - [ __NR_capset ] = sys_capset,
17667 - [ __NR_sigaltstack ] = sys_sigaltstack,
17668 - [ __NR_sendfile ] = sys_sendfile,
17669 - [ __NR_getpmsg ] = sys_ni_syscall,
17670 - [ __NR_putpmsg ] = sys_ni_syscall,
17671 - [ __NR_vfork ] = sys_vfork,
17672 - [ __NR_ugetrlimit ] = sys_getrlimit,
17673 - [ __NR_mmap2 ] = sys_mmap2,
17674 - [ __NR_truncate64 ] = sys_truncate64,
17675 - [ __NR_ftruncate64 ] = sys_ftruncate64,
17676 - [ __NR_stat64 ] = sys_stat64,
17677 - [ __NR_lstat64 ] = sys_lstat64,
17678 - [ __NR_fstat64 ] = sys_fstat64,
17679 - [ __NR_fcntl64 ] = sys_fcntl64,
17680 - [ __NR_getdents64 ] = sys_getdents64,
17681 - [ __NR_gettid ] = sys_gettid,
17682 - [ __NR_readahead ] = sys_readahead,
17683 - [ __NR_setxattr ] = sys_ni_syscall,
17684 - [ __NR_lsetxattr ] = sys_ni_syscall,
17685 - [ __NR_fsetxattr ] = sys_ni_syscall,
17686 - [ __NR_getxattr ] = sys_ni_syscall,
17687 - [ __NR_lgetxattr ] = sys_ni_syscall,
17688 - [ __NR_fgetxattr ] = sys_ni_syscall,
17689 - [ __NR_listxattr ] = sys_ni_syscall,
17690 - [ __NR_llistxattr ] = sys_ni_syscall,
17691 - [ __NR_flistxattr ] = sys_ni_syscall,
17692 - [ __NR_removexattr ] = sys_ni_syscall,
17693 - [ __NR_lremovexattr ] = sys_ni_syscall,
17694 - [ __NR_fremovexattr ] = sys_ni_syscall,
17695 - [ __NR_tkill ] = sys_tkill,
17696 - [ __NR_sendfile64 ] = sys_sendfile64,
17697 - [ __NR_futex ] = sys_futex,
17698 - [ __NR_sched_setaffinity ] = sys_sched_setaffinity,
17699 - [ __NR_sched_getaffinity ] = sys_sched_getaffinity,
17700 - [ __NR_io_setup ] = sys_io_setup,
17701 - [ __NR_io_destroy ] = sys_io_destroy,
17702 - [ __NR_io_getevents ] = sys_io_getevents,
17703 - [ __NR_io_submit ] = sys_io_submit,
17704 - [ __NR_io_cancel ] = sys_io_cancel,
17705 - [ __NR_exit_group ] = sys_exit_group,
17706 - [ __NR_lookup_dcookie ] = sys_lookup_dcookie,
17707 - [ __NR_epoll_create ] = sys_epoll_create,
17708 - [ __NR_epoll_ctl ] = sys_epoll_ctl,
17709 - [ __NR_epoll_wait ] = sys_epoll_wait,
17710 - [ __NR_remap_file_pages ] = sys_remap_file_pages,
17711 - [ __NR_set_tid_address ] = sys_set_tid_address,
17712 + [ __NR_sched_get_priority_max ] (syscall_handler_t *) sys_sched_get_priority_max,
17713 + [ __NR_sched_get_priority_min ] (syscall_handler_t *) sys_sched_get_priority_min,
17714 + [ __NR_sched_rr_get_interval ] (syscall_handler_t *) sys_sched_rr_get_interval,
17715 + [ __NR_nanosleep ] (syscall_handler_t *) sys_nanosleep,
17716 + [ __NR_mremap ] (syscall_handler_t *) sys_mremap,
17717 + [ __NR_setresuid ] (syscall_handler_t *) sys_setresuid16,
17718 + [ __NR_getresuid ] (syscall_handler_t *) sys_getresuid16,
17719 + [ __NR_vm86 ] (syscall_handler_t *) sys_ni_syscall,
17720 + [ __NR_query_module ] (syscall_handler_t *) sys_ni_syscall,
17721 + [ __NR_poll ] (syscall_handler_t *) sys_poll,
17722 + [ __NR_nfsservctl ] = (syscall_handler_t *) NFSSERVCTL,
17723 + [ __NR_setresgid ] (syscall_handler_t *) sys_setresgid16,
17724 + [ __NR_getresgid ] (syscall_handler_t *) sys_getresgid16,
17725 + [ __NR_prctl ] (syscall_handler_t *) sys_prctl,
17726 + [ __NR_rt_sigreturn ] (syscall_handler_t *) sys_rt_sigreturn,
17727 + [ __NR_rt_sigaction ] (syscall_handler_t *) sys_rt_sigaction,
17728 + [ __NR_rt_sigprocmask ] (syscall_handler_t *) sys_rt_sigprocmask,
17729 + [ __NR_rt_sigpending ] (syscall_handler_t *) sys_rt_sigpending,
17730 + [ __NR_rt_sigtimedwait ] (syscall_handler_t *) sys_rt_sigtimedwait,
17731 + [ __NR_rt_sigqueueinfo ] (syscall_handler_t *) sys_rt_sigqueueinfo,
17732 + [ __NR_rt_sigsuspend ] (syscall_handler_t *) sys_rt_sigsuspend,
17733 + [ __NR_pread64 ] (syscall_handler_t *) sys_pread64,
17734 + [ __NR_pwrite64 ] (syscall_handler_t *) sys_pwrite64,
17735 + [ __NR_chown ] (syscall_handler_t *) sys_chown16,
17736 + [ __NR_getcwd ] (syscall_handler_t *) sys_getcwd,
17737 + [ __NR_capget ] (syscall_handler_t *) sys_capget,
17738 + [ __NR_capset ] (syscall_handler_t *) sys_capset,
17739 + [ __NR_sigaltstack ] (syscall_handler_t *) sys_sigaltstack,
17740 + [ __NR_sendfile ] (syscall_handler_t *) sys_sendfile,
17741 + [ __NR_getpmsg ] (syscall_handler_t *) sys_ni_syscall,
17742 + [ __NR_putpmsg ] (syscall_handler_t *) sys_ni_syscall,
17743 + [ __NR_vfork ] (syscall_handler_t *) sys_vfork,
17744 + [ __NR_ugetrlimit ] (syscall_handler_t *) sys_getrlimit,
17745 + [ __NR_mmap2 ] (syscall_handler_t *) sys_mmap2,
17746 + [ __NR_truncate64 ] (syscall_handler_t *) sys_truncate64,
17747 + [ __NR_ftruncate64 ] (syscall_handler_t *) sys_ftruncate64,
17748 + [ __NR_stat64 ] (syscall_handler_t *) sys_stat64,
17749 + [ __NR_lstat64 ] (syscall_handler_t *) sys_lstat64,
17750 + [ __NR_fstat64 ] (syscall_handler_t *) sys_fstat64,
17751 + [ __NR_getdents64 ] (syscall_handler_t *) sys_getdents64,
17752 + [ __NR_fcntl64 ] (syscall_handler_t *) sys_fcntl64,
17753 + [ 223 ] (syscall_handler_t *) sys_ni_syscall,
17754 + [ __NR_gettid ] (syscall_handler_t *) sys_gettid,
17755 + [ __NR_readahead ] (syscall_handler_t *) sys_readahead,
17756 + [ __NR_setxattr ] (syscall_handler_t *) sys_setxattr,
17757 + [ __NR_lsetxattr ] (syscall_handler_t *) sys_lsetxattr,
17758 + [ __NR_fsetxattr ] (syscall_handler_t *) sys_fsetxattr,
17759 + [ __NR_getxattr ] (syscall_handler_t *) sys_getxattr,
17760 + [ __NR_lgetxattr ] (syscall_handler_t *) sys_lgetxattr,
17761 + [ __NR_fgetxattr ] (syscall_handler_t *) sys_fgetxattr,
17762 + [ __NR_listxattr ] (syscall_handler_t *) sys_listxattr,
17763 + [ __NR_llistxattr ] (syscall_handler_t *) sys_llistxattr,
17764 + [ __NR_flistxattr ] (syscall_handler_t *) sys_flistxattr,
17765 + [ __NR_removexattr ] (syscall_handler_t *) sys_removexattr,
17766 + [ __NR_lremovexattr ] (syscall_handler_t *) sys_lremovexattr,
17767 + [ __NR_fremovexattr ] (syscall_handler_t *) sys_fremovexattr,
17768 + [ __NR_tkill ] (syscall_handler_t *) sys_tkill,
17769 + [ __NR_sendfile64 ] (syscall_handler_t *) sys_sendfile64,
17770 + [ __NR_futex ] (syscall_handler_t *) sys_futex,
17771 + [ __NR_sched_setaffinity ] (syscall_handler_t *) sys_sched_setaffinity,
17772 + [ __NR_sched_getaffinity ] (syscall_handler_t *) sys_sched_getaffinity,
17773 + [ __NR_set_thread_area ] (syscall_handler_t *) sys_ni_syscall,
17774 + [ __NR_get_thread_area ] (syscall_handler_t *) sys_ni_syscall,
17775 + [ __NR_io_setup ] (syscall_handler_t *) sys_io_setup,
17776 + [ __NR_io_destroy ] (syscall_handler_t *) sys_io_destroy,
17777 + [ __NR_io_getevents ] (syscall_handler_t *) sys_io_getevents,
17778 + [ __NR_io_submit ] (syscall_handler_t *) sys_io_submit,
17779 + [ __NR_io_cancel ] (syscall_handler_t *) sys_io_cancel,
17780 + [ __NR_fadvise64 ] (syscall_handler_t *) sys_fadvise64,
17781 + [ 251 ] (syscall_handler_t *) sys_ni_syscall,
17782 + [ __NR_exit_group ] (syscall_handler_t *) sys_exit_group,
17783 + [ __NR_lookup_dcookie ] (syscall_handler_t *) sys_lookup_dcookie,
17784 + [ __NR_epoll_create ] (syscall_handler_t *) sys_epoll_create,
17785 + [ __NR_epoll_ctl ] (syscall_handler_t *) sys_epoll_ctl,
17786 + [ __NR_epoll_wait ] (syscall_handler_t *) sys_epoll_wait,
17787 + [ __NR_remap_file_pages ] (syscall_handler_t *) sys_remap_file_pages,
17788 + [ __NR_set_tid_address ] (syscall_handler_t *) sys_set_tid_address,
17789 + [ __NR_timer_create ] (syscall_handler_t *) sys_timer_create,
17790 + [ __NR_timer_settime ] (syscall_handler_t *) sys_timer_settime,
17791 + [ __NR_timer_gettime ] (syscall_handler_t *) sys_timer_gettime,
17792 + [ __NR_timer_getoverrun ] (syscall_handler_t *) sys_timer_getoverrun,
17793 + [ __NR_timer_delete ] (syscall_handler_t *) sys_timer_delete,
17794 + [ __NR_clock_settime ] (syscall_handler_t *) sys_clock_settime,
17795 + [ __NR_clock_gettime ] (syscall_handler_t *) sys_clock_gettime,
17796 + [ __NR_clock_getres ] (syscall_handler_t *) sys_clock_getres,
17797 + [ __NR_clock_nanosleep ] (syscall_handler_t *) sys_clock_nanosleep,
17798 + [ __NR_statfs64 ] (syscall_handler_t *) sys_statfs64,
17799 + [ __NR_fstatfs64 ] (syscall_handler_t *) sys_fstatfs64,
17800 + [ __NR_tgkill ] (syscall_handler_t *) sys_tgkill,
17801 + [ __NR_utimes ] (syscall_handler_t *) sys_utimes,
17802 + [ __NR_fadvise64_64 ] (syscall_handler_t *) sys_fadvise64_64,
17803 + [ __NR_vserver ] (syscall_handler_t *) sys_ni_syscall,
17806 [ LAST_SYSCALL + 1 ... NR_syscalls ] =
17807 Index: uml-2.6.7/arch/um/kernel/exec_kern.c
17808 ===================================================================
17809 --- uml-2.6.7.orig/arch/um/kernel/exec_kern.c 2004-07-16 19:36:16.769597096 +0300
17810 +++ uml-2.6.7/arch/um/kernel/exec_kern.c 2004-07-16 19:47:23.713206256 +0300
17811 @@ -32,10 +32,15 @@
17812 CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
17815 +extern void log_exec(char **argv, void *tty);
17817 static int execve1(char *file, char **argv, char **env)
17821 +#ifdef CONFIG_TTY_LOG
17822 + log_exec(argv, current->tty);
17824 error = do_execve(file, argv, env, ¤t->thread.regs);
17826 current->ptrace &= ~PT_DTRACE;
17827 Index: uml-2.6.7/arch/um/drivers/daemon_user.c
17828 ===================================================================
17829 --- uml-2.6.7.orig/arch/um/drivers/daemon_user.c 2004-07-16 19:36:30.112568656 +0300
17830 +++ uml-2.6.7/arch/um/drivers/daemon_user.c 2004-07-16 19:47:23.681211120 +0300
17832 struct request_v3 req;
17835 - if((pri->control = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
17836 + pri->control = socket(AF_UNIX, SOCK_STREAM, 0);
17837 + if(pri->control < 0){
17838 printk("daemon_open : control socket failed, errno = %d\n",
17845 - if((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0){
17846 + fd = socket(AF_UNIX, SOCK_DGRAM, 0);
17848 printk("daemon_open : data socket failed, errno = %d\n",
17851 @@ -91,18 +93,18 @@
17852 req.version = SWITCH_VERSION;
17853 req.type = REQ_NEW_CONTROL;
17854 req.sock = *local_addr;
17855 - n = write(pri->control, &req, sizeof(req));
17856 + n = os_write_file(pri->control, &req, sizeof(req));
17857 if(n != sizeof(req)){
17858 - printk("daemon_open : control setup request returned %d, "
17859 - "errno = %d\n", n, errno);
17860 + printk("daemon_open : control setup request failed, err = %d\n",
17866 - n = read(pri->control, sun, sizeof(*sun));
17867 + n = os_read_file(pri->control, sun, sizeof(*sun));
17868 if(n != sizeof(*sun)){
17869 - printk("daemon_open : read of data socket returned %d, "
17870 - "errno = %d\n", n, errno);
17871 + printk("daemon_open : read of data socket failed, err = %d\n",
17876 @@ -111,9 +113,9 @@
17881 + os_close_file(fd);
17883 - close(pri->control);
17884 + os_close_file(pri->control);
17888 @@ -153,8 +155,8 @@
17890 struct daemon_data *pri = data;
17893 - close(pri->control);
17894 + os_close_file(pri->fd);
17895 + os_close_file(pri->control);
17896 if(pri->data_addr != NULL) kfree(pri->data_addr);
17897 if(pri->ctl_addr != NULL) kfree(pri->ctl_addr);
17898 if(pri->local_addr != NULL) kfree(pri->local_addr);
17899 Index: uml-2.6.7/include/asm-um/elf.h
17900 ===================================================================
17901 --- uml-2.6.7.orig/include/asm-um/elf.h 2004-07-16 19:37:00.001024920 +0300
17902 +++ uml-2.6.7/include/asm-um/elf.h 2004-07-16 19:47:23.789194704 +0300
17905 #define USE_ELF_CORE_DUMP
17907 +#define R_386_NONE 0
17908 +#define R_386_32 1
17909 +#define R_386_PC32 2
17910 +#define R_386_GOT32 3
17911 +#define R_386_PLT32 4
17912 +#define R_386_COPY 5
17913 +#define R_386_GLOB_DAT 6
17914 +#define R_386_JMP_SLOT 7
17915 +#define R_386_RELATIVE 8
17916 +#define R_386_GOTOFF 9
17917 +#define R_386_GOTPC 10
17918 +#define R_386_NUM 11
17921 Index: uml-2.6.7/arch/um/kernel/skas/include/uaccess.h
17922 ===================================================================
17923 --- uml-2.6.7.orig/arch/um/kernel/skas/include/uaccess.h 2004-07-16 19:36:33.265089400 +0300
17924 +++ uml-2.6.7/arch/um/kernel/skas/include/uaccess.h 2004-07-16 19:47:23.728203976 +0300
17926 #ifndef __SKAS_UACCESS_H
17927 #define __SKAS_UACCESS_H
17929 -#include "linux/string.h"
17930 -#include "linux/sched.h"
17931 -#include "linux/err.h"
17932 -#include "asm/processor.h"
17933 -#include "asm/pgtable.h"
17934 #include "asm/errno.h"
17935 -#include "asm/current.h"
17936 -#include "asm/a.out.h"
17937 -#include "kern_util.h"
17939 #define access_ok_skas(type, addr, size) \
17940 ((segment_eq(get_fs(), KERNEL_DS)) || \
17941 (((unsigned long) (addr) < TASK_SIZE) && \
17942 - ((unsigned long) (addr) + (size) < TASK_SIZE)))
17943 + ((unsigned long) (addr) + (size) <= TASK_SIZE)))
17945 static inline int verify_area_skas(int type, const void * addr,
17946 unsigned long size)
17947 @@ -27,197 +19,12 @@
17948 return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
17951 -static inline unsigned long maybe_map(unsigned long virt, int is_write)
17955 - void *phys = um_virt_to_phys(current, virt, &pte);
17958 - if(IS_ERR(phys) || (is_write && !pte_write(pte))){
17959 - if(handle_page_fault(virt, 0, is_write, 0, &dummy_code))
17961 - phys = um_virt_to_phys(current, virt, NULL);
17963 - return((unsigned long) __va((unsigned long) phys));
17966 -static inline int buffer_op(unsigned long addr, int len,
17967 - int (*op)(unsigned long addr, int len, void *arg),
17970 - int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
17971 - int remain = len, n;
17973 - n = (*op)(addr, size, arg);
17975 - return(n < 0 ? remain : 0);
17982 - while(addr < ((addr + remain) & PAGE_MASK)){
17983 - n = (*op)(addr, PAGE_SIZE, arg);
17985 - return(n < 0 ? remain : 0);
17987 - addr += PAGE_SIZE;
17988 - remain -= PAGE_SIZE;
17993 - n = (*op)(addr, remain, arg);
17995 - return(n < 0 ? remain : 0);
17999 -static inline int copy_chunk_from_user(unsigned long from, int len, void *arg)
18001 - unsigned long *to_ptr = arg, to = *to_ptr;
18003 - from = maybe_map(from, 0);
18007 - memcpy((void *) to, (void *) from, len);
18012 -static inline int copy_from_user_skas(void *to, const void *from, int n)
18014 - if(segment_eq(get_fs(), KERNEL_DS)){
18015 - memcpy(to, from, n);
18019 - return(access_ok_skas(VERIFY_READ, from, n) ?
18020 - buffer_op((unsigned long) from, n, copy_chunk_from_user, &to) :
18024 -static inline int copy_chunk_to_user(unsigned long to, int len, void *arg)
18026 - unsigned long *from_ptr = arg, from = *from_ptr;
18028 - to = maybe_map(to, 1);
18032 - memcpy((void *) to, (void *) from, len);
18033 - *from_ptr += len;
18037 -static inline int copy_to_user_skas(void *to, const void *from, int n)
18039 - if(segment_eq(get_fs(), KERNEL_DS)){
18040 - memcpy(to, from, n);
18044 - return(access_ok_skas(VERIFY_WRITE, to, n) ?
18045 - buffer_op((unsigned long) to, n, copy_chunk_to_user, &from) :
18049 -static inline int strncpy_chunk_from_user(unsigned long from, int len,
18052 - char **to_ptr = arg, *to = *to_ptr;
18055 - from = maybe_map(from, 0);
18059 - strncpy(to, (void *) from, len);
18060 - n = strnlen(to, len);
18068 -static inline int strncpy_from_user_skas(char *dst, const char *src, int count)
18073 - if(segment_eq(get_fs(), KERNEL_DS)){
18074 - strncpy(dst, src, count);
18075 - return(strnlen(dst, count));
18078 - if(!access_ok_skas(VERIFY_READ, src, 1))
18081 - n = buffer_op((unsigned long) src, count, strncpy_chunk_from_user,
18085 - return(strnlen(dst, count));
18088 -static inline int clear_chunk(unsigned long addr, int len, void *unused)
18090 - addr = maybe_map(addr, 1);
18094 - memset((void *) addr, 0, len);
18098 -static inline int __clear_user_skas(void *mem, int len)
18100 - return(buffer_op((unsigned long) mem, len, clear_chunk, NULL));
18103 -static inline int clear_user_skas(void *mem, int len)
18105 - if(segment_eq(get_fs(), KERNEL_DS)){
18106 - memset(mem, 0, len);
18110 - return(access_ok_skas(VERIFY_WRITE, mem, len) ?
18111 - buffer_op((unsigned long) mem, len, clear_chunk, NULL) : len);
18114 -static inline int strnlen_chunk(unsigned long str, int len, void *arg)
18116 - int *len_ptr = arg, n;
18118 - str = maybe_map(str, 0);
18122 - n = strnlen((void *) str, len);
18130 -static inline int strnlen_user_skas(const void *str, int len)
18132 - int count = 0, n;
18134 - if(segment_eq(get_fs(), KERNEL_DS))
18135 - return(strnlen(str, len) + 1);
18137 - n = buffer_op((unsigned long) str, len, strnlen_chunk, &count);
18139 - return(count + 1);
18142 +extern int copy_from_user_skas(void *to, const void *from, int n);
18143 +extern int copy_to_user_skas(void *to, const void *from, int n);
18144 +extern int strncpy_from_user_skas(char *dst, const char *src, int count);
18145 +extern int __clear_user_skas(void *mem, int len);
18146 +extern int clear_user_skas(void *mem, int len);
18147 +extern int strnlen_user_skas(const void *str, int len);
18151 Index: uml-2.6.7/arch/um/Kconfig
18152 ===================================================================
18153 --- uml-2.6.7.orig/arch/um/Kconfig 2004-07-16 19:36:40.087052304 +0300
18154 +++ uml-2.6.7/arch/um/Kconfig 2004-07-16 19:47:23.711206560 +0300
18158 bool "Networking support"
18160 + Unless you really know what you are doing, you should say Y here.
18161 + The reason is that some programs need kernel networking support even
18162 + when running on a stand-alone machine that isn't connected to any
18163 + other computer. If you are upgrading from an older kernel, you
18164 + should consider updating your networking tools too because changes
18165 + in the kernel and the tools often go hand in hand. The tools are
18166 + contained in the package net-tools, the location and version number
18167 + of which are given in Documentation/Changes.
18169 + For a general introduction to Linux networking, it is highly
18170 + recommended to read the NET-HOWTO, available from
18171 + <http://www.tldp.org/docs.html#howto>.
18174 source "fs/Kconfig.binfmt"
18177 If you'd like to be able to work with files stored on the host,
18178 say Y or M here; otherwise say N.
18181 + tristate "HoneyPot ProcFS"
18183 + hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
18184 + entries to be overridden, removed, or fabricated from the host.
18185 + Its purpose is to allow a UML to appear to be a physical machine
18186 + by removing or changing anything in /proc which gives away the
18187 + identity of a UML.
18189 + See http://user-mode-linux.sf.net/hppfs.html for more information.
18191 + You only need this if you are setting up a UML honeypot. Otherwise,
18192 + it is safe to say 'N' here.
18195 bool "Management console"
18196 @@ -105,6 +132,16 @@
18198 bool "Magic SysRq key"
18199 depends on MCONSOLE
18201 + If you say Y here, you will have some control over the system even
18202 + if the system crashes for example during kernel debugging (e.g., you
18203 + will be able to flush the buffer cache to disk, reboot the system
18204 + immediately or dump some status information). This is accomplished
18205 + by pressing various keys while holding SysRq (Alt+PrintScreen). It
18206 + also works on a serial console (on PC hardware at least), if you
18207 + send a BREAK and then within 5 seconds a command keypress. The
18208 + keys are documented in Documentation/sysrq.txt. Don't say Y
18209 + unless you really know what this hack does.
18212 bool "2G/2G host address space split"
18213 @@ -168,6 +205,17 @@
18214 be 1 << order pages. The default is OK unless you're running Valgrind
18215 on UML, in which case, set this to 3.
18217 +config UML_REAL_TIME_CLOCK
18218 + bool "Real-time Clock"
18221 + This option makes UML time deltas match wall clock deltas. This should
18222 + normally be enabled. The exception would be if you are debugging with
18223 + UML and spend long times with UML stopped at a breakpoint. In this
18224 + case, when UML is restarted, it will call the timer enough times to make
18225 + up for the time spent at the breakpoint. This could result in a
18226 + noticable lag. If this is a problem, then disable this option.
18230 source "init/Kconfig"
18231 @@ -240,6 +288,10 @@
18233 bool "Enable ptrace proxy"
18234 depends on XTERM_CHAN && DEBUG_INFO
18236 + This option enables a debugging interface which allows gdb to debug
18237 + the kernel without needing to actually attach to kernel threads.
18238 + If you want to do kernel debugging, say Y here; otherwise say N.
18241 bool "Enable gprof support"
18242 Index: uml-2.6.7/arch/um/drivers/hostaudio_kern.c
18243 ===================================================================
18244 --- uml-2.6.7.orig/arch/um/drivers/hostaudio_kern.c 2004-07-16 19:37:40.179916800 +0300
18245 +++ uml-2.6.7/arch/um/drivers/hostaudio_kern.c 2004-07-16 19:47:24.525082832 +0300
18248 #include "linux/config.h"
18249 #include "linux/module.h"
18250 -#include "linux/version.h"
18251 #include "linux/init.h"
18252 #include "linux/slab.h"
18253 #include "linux/fs.h"
18254 #include "linux/sound.h"
18255 #include "linux/soundcard.h"
18256 +#include "asm/uaccess.h"
18257 #include "kern_util.h"
18259 -#include "hostaudio.h"
18262 +struct hostaudio_state {
18266 +struct hostmixer_state {
18270 +#define HOSTAUDIO_DEV_DSP "/dev/sound/dsp"
18271 +#define HOSTAUDIO_DEV_MIXER "/dev/sound/mixer"
18273 /* Only changed from linux_main at boot time */
18274 char *dsp = HOSTAUDIO_DEV_DSP;
18275 char *mixer = HOSTAUDIO_DEV_MIXER;
18277 +#define DSP_HELP \
18278 +" This is used to specify the host dsp device to the hostaudio driver.\n" \
18279 +" The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n"
18281 +#define MIXER_HELP \
18282 +" This is used to specify the host mixer device to the hostaudio driver.\n" \
18283 +" The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n"
18286 static int set_dsp(char *name, int *add)
18288 - dsp = uml_strdup(name);
18293 -__uml_setup("dsp=", set_dsp,
18294 -"dsp=<dsp device>\n"
18295 -" This is used to specify the host dsp device to the hostaudio driver.\n"
18296 -" The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n"
18298 +__uml_setup("dsp=", set_dsp, "dsp=<dsp device>\n" DSP_HELP);
18300 static int set_mixer(char *name, int *add)
18302 - mixer = uml_strdup(name);
18307 -__uml_setup("mixer=", set_mixer,
18308 -"mixer=<mixer device>\n"
18309 -" This is used to specify the host mixer device to the hostaudio driver.\n"
18310 -" The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n"
18312 +__uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP);
18316 +MODULE_PARM(dsp, "s");
18317 +MODULE_PARM_DESC(dsp, DSP_HELP);
18319 +MODULE_PARM(mixer, "s");
18320 +MODULE_PARM_DESC(mixer, MIXER_HELP);
18324 /* /dev/dsp file operations */
18325 @@ -51,23 +71,55 @@
18328 struct hostaudio_state *state = file->private_data;
18333 printk("hostaudio: read called, count = %d\n", count);
18336 - return(hostaudio_read_user(state, buffer, count, ppos));
18337 + kbuf = kmalloc(count, GFP_KERNEL);
18341 + ret = os_read_file(state->fd, kbuf, count);
18345 + if(copy_to_user(buffer, kbuf, ret))
18353 static ssize_t hostaudio_write(struct file *file, const char *buffer,
18354 size_t count, loff_t *ppos)
18356 struct hostaudio_state *state = file->private_data;
18361 printk("hostaudio: write called, count = %d\n", count);
18363 - return(hostaudio_write_user(state, buffer, count, ppos));
18365 + kbuf = kmalloc(count, GFP_KERNEL);
18370 + if(copy_from_user(kbuf, buffer, count))
18373 + ret = os_write_file(state->fd, kbuf, count);
18382 static unsigned int hostaudio_poll(struct file *file,
18383 @@ -86,12 +138,43 @@
18384 unsigned int cmd, unsigned long arg)
18386 struct hostaudio_state *state = file->private_data;
18387 + unsigned long data = 0;
18391 printk("hostaudio: ioctl called, cmd = %u\n", cmd);
18394 + case SNDCTL_DSP_SPEED:
18395 + case SNDCTL_DSP_STEREO:
18396 + case SNDCTL_DSP_GETBLKSIZE:
18397 + case SNDCTL_DSP_CHANNELS:
18398 + case SNDCTL_DSP_SUBDIVIDE:
18399 + case SNDCTL_DSP_SETFRAGMENT:
18400 + if(get_user(data, (int *) arg))
18407 + ret = os_ioctl_generic(state->fd, cmd, (unsigned long) &data);
18410 + case SNDCTL_DSP_SPEED:
18411 + case SNDCTL_DSP_STEREO:
18412 + case SNDCTL_DSP_GETBLKSIZE:
18413 + case SNDCTL_DSP_CHANNELS:
18414 + case SNDCTL_DSP_SUBDIVIDE:
18415 + case SNDCTL_DSP_SETFRAGMENT:
18416 + if(put_user(data, (int *) arg))
18423 - return(hostaudio_ioctl_user(state, cmd, arg));
18427 static int hostaudio_open(struct inode *inode, struct file *file)
18428 @@ -110,12 +193,17 @@
18429 if(file->f_mode & FMODE_READ) r = 1;
18430 if(file->f_mode & FMODE_WRITE) w = 1;
18432 - ret = hostaudio_open_user(state, r, w, dsp);
18433 + ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
18436 + printk("hostaudio_open failed to open '%s', err = %d\n",
18444 file->private_data = state;
18447 @@ -123,16 +211,19 @@
18448 static int hostaudio_release(struct inode *inode, struct file *file)
18450 struct hostaudio_state *state = file->private_data;
18454 printk("hostaudio: release called\n");
18457 - ret = hostaudio_release_user(state);
18458 + if(state->fd >= 0){
18459 + os_close_file(state->fd);
18469 /* /dev/mixer file operations */
18470 @@ -146,7 +237,7 @@
18471 printk("hostmixer: ioctl called\n");
18474 - return(hostmixer_ioctl_mixdev_user(state, cmd, arg));
18475 + return(os_ioctl_generic(state->fd, cmd, arg));
18478 static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
18479 @@ -165,13 +256,17 @@
18480 if(file->f_mode & FMODE_READ) r = 1;
18481 if(file->f_mode & FMODE_WRITE) w = 1;
18483 - ret = hostmixer_open_mixdev_user(state, r, w, mixer);
18484 + ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
18487 + printk("hostaudio_open_mixdev failed to open '%s', err = %d\n",
18495 file->private_data = state;
18498 @@ -179,16 +274,18 @@
18499 static int hostmixer_release(struct inode *inode, struct file *file)
18501 struct hostmixer_state *state = file->private_data;
18505 printk("hostmixer: release called\n");
18508 - ret = hostmixer_release_mixdev_user(state);
18509 + if(state->fd >= 0){
18510 + os_close_file(state->fd);
18520 @@ -225,7 +322,8 @@
18522 static int __init hostaudio_init_module(void)
18524 - printk(KERN_INFO "UML Audio Relay\n");
18525 + printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
18528 module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
18529 if(module_data.dev_audio < 0){
18530 Index: uml-2.6.7/arch/um/include/user.h
18531 ===================================================================
18532 --- uml-2.6.7.orig/arch/um/include/user.h 2004-07-16 19:35:55.750792440 +0300
18533 +++ uml-2.6.7/arch/um/include/user.h 2004-07-16 19:47:23.709206864 +0300
18535 extern void kfree(void *ptr);
18536 extern int in_aton(char *str);
18537 extern int open_gdb_chan(void);
18538 +extern int strlcpy(char *, const char *, int);
18542 Index: uml-2.6.7/arch/um/include/skas_ptrace.h
18543 ===================================================================
18544 --- uml-2.6.7.orig/arch/um/include/skas_ptrace.h 2004-07-16 19:37:26.080060304 +0300
18545 +++ uml-2.6.7/arch/um/include/skas_ptrace.h 2004-07-16 19:47:23.706207320 +0300
18548 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18549 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
18550 * Licensed under the GPL
18553 Index: uml-2.6.7/arch/um/kernel/tt/ptproxy/sysdep.c
18554 ===================================================================
18555 --- uml-2.6.7.orig/arch/um/kernel/tt/ptproxy/sysdep.c 2004-07-16 19:37:13.940905736 +0300
18556 +++ uml-2.6.7/arch/um/kernel/tt/ptproxy/sysdep.c 2004-07-16 19:47:23.747201088 +0300
18558 #include <string.h>
18559 #include <stdlib.h>
18560 #include <signal.h>
18561 +#include <errno.h>
18562 #include <sys/types.h>
18563 #include <sys/ptrace.h>
18564 #include <asm/ptrace.h>
18565 Index: uml-2.6.7/arch/um/kernel/tt/ptproxy/proxy.c
18566 ===================================================================
18567 --- uml-2.6.7.orig/arch/um/kernel/tt/ptproxy/proxy.c 2004-07-16 19:36:56.795512232 +0300
18568 +++ uml-2.6.7/arch/um/kernel/tt/ptproxy/proxy.c 2004-07-16 19:47:24.800041032 +0300
18570 #include <unistd.h>
18571 #include <signal.h>
18572 #include <string.h>
18573 -#include <fcntl.h>
18574 #include <termios.h>
18575 #include <sys/wait.h>
18576 #include <sys/types.h>
18577 @@ -273,7 +272,7 @@
18579 child_proxy(1, W_EXITCODE(0, 0));
18580 while(debugger.waiting == 1){
18581 - pid = waitpid(debugger.pid, &status, WUNTRACED);
18582 + CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED));
18583 if(pid != debugger.pid){
18584 printk("fake_child_exit - waitpid failed, "
18585 "errno = %d\n", errno);
18586 @@ -281,7 +280,7 @@
18588 debugger_proxy(status, debugger.pid);
18590 - pid = waitpid(debugger.pid, &status, WUNTRACED);
18591 + CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED));
18592 if(pid != debugger.pid){
18593 printk("fake_child_exit - waitpid failed, "
18594 "errno = %d\n", errno);
18595 @@ -293,10 +292,10 @@
18598 char gdb_init_string[] =
18602 -handle SIGWINCH nostop noprint pass
18606 +handle SIGWINCH nostop noprint pass \n\
18609 int start_debugger(char *prog, int startup, int stop, int *fd_out)
18610 @@ -304,7 +303,8 @@
18613 slave = open_gdb_chan();
18614 - if((child = fork()) == 0){
18617 char *tempname = NULL;
18620 @@ -327,18 +327,19 @@
18624 - if((fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0)) < 0){
18625 - printk("start_debugger : make_tempfile failed, errno = %d\n",
18627 + fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0);
18629 + printk("start_debugger : make_tempfile failed,"
18630 + "err = %d\n", -fd);
18633 - write(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
18634 + os_write_file(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
18637 - write(fd, "b start_kernel\n",
18638 + os_write_file(fd, "b start_kernel\n",
18639 strlen("b start_kernel\n"));
18641 - write(fd, "c\n", strlen("c\n"));
18642 + os_write_file(fd, "c\n", strlen("c\n"));
18644 if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
18645 printk("start_debugger : PTRACE_TRACEME failed, "
18646 Index: uml-2.6.7/arch/um/kernel/tt/include/uaccess.h
18647 ===================================================================
18648 --- uml-2.6.7.orig/arch/um/kernel/tt/include/uaccess.h 2004-07-16 19:37:00.052017168 +0300
18649 +++ uml-2.6.7/arch/um/kernel/tt/include/uaccess.h 2004-07-16 19:47:23.744201544 +0300
18652 - * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
18653 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
18654 * Licensed under the GPL
18657 @@ -43,65 +43,19 @@
18659 extern int __do_copy_from_user(void *to, const void *from, int n,
18660 void **fault_addr, void **fault_catcher);
18662 -static inline int copy_from_user_tt(void *to, const void *from, int n)
18664 - return(access_ok_tt(VERIFY_READ, from, n) ?
18665 - __do_copy_from_user(to, from, n,
18666 - ¤t->thread.fault_addr,
18667 - ¤t->thread.fault_catcher) : n);
18670 -static inline int copy_to_user_tt(void *to, const void *from, int n)
18672 - return(access_ok_tt(VERIFY_WRITE, to, n) ?
18673 - __do_copy_to_user(to, from, n,
18674 - ¤t->thread.fault_addr,
18675 - ¤t->thread.fault_catcher) : n);
18678 extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
18679 void **fault_addr, void **fault_catcher);
18681 -static inline int strncpy_from_user_tt(char *dst, const char *src, int count)
18685 - if(!access_ok_tt(VERIFY_READ, src, 1)) return(-EFAULT);
18686 - n = __do_strncpy_from_user(dst, src, count,
18687 - ¤t->thread.fault_addr,
18688 - ¤t->thread.fault_catcher);
18689 - if(n < 0) return(-EFAULT);
18693 extern int __do_clear_user(void *mem, size_t len, void **fault_addr,
18694 void **fault_catcher);
18696 -static inline int __clear_user_tt(void *mem, int len)
18698 - return(__do_clear_user(mem, len,
18699 - ¤t->thread.fault_addr,
18700 - ¤t->thread.fault_catcher));
18703 -static inline int clear_user_tt(void *mem, int len)
18705 - return(access_ok_tt(VERIFY_WRITE, mem, len) ?
18706 - __do_clear_user(mem, len,
18707 - ¤t->thread.fault_addr,
18708 - ¤t->thread.fault_catcher) : len);
18711 extern int __do_strnlen_user(const char *str, unsigned long n,
18712 void **fault_addr, void **fault_catcher);
18714 -static inline int strnlen_user_tt(const void *str, int len)
18716 - return(__do_strnlen_user(str, len,
18717 - ¤t->thread.fault_addr,
18718 - ¤t->thread.fault_catcher));
18720 +extern int copy_from_user_tt(void *to, const void *from, int n);
18721 +extern int copy_to_user_tt(void *to, const void *from, int n);
18722 +extern int strncpy_from_user_tt(char *dst, const char *src, int count);
18723 +extern int __clear_user_tt(void *mem, int len);
18724 +extern int clear_user_tt(void *mem, int len);
18725 +extern int strnlen_user_tt(const void *str, int len);
18729 Index: uml-2.6.7/arch/um/drivers/null.c
18730 ===================================================================
18731 --- uml-2.6.7.orig/arch/um/drivers/null.c 2004-07-16 19:35:59.203267584 +0300
18732 +++ uml-2.6.7/arch/um/drivers/null.c 2004-07-16 19:47:23.690209752 +0300
18735 #include <stdlib.h>
18737 -#include <fcntl.h>
18738 #include "chan_user.h"
18741 Index: uml-2.6.7/arch/um/kernel/frame_kern.c
18742 ===================================================================
18743 --- uml-2.6.7.orig/arch/um/kernel/frame_kern.c 2004-07-16 19:37:51.994120768 +0300
18744 +++ uml-2.6.7/arch/um/kernel/frame_kern.c 2004-07-16 19:47:23.714206104 +0300
18746 #include "asm/ptrace.h"
18747 #include "asm/uaccess.h"
18748 #include "asm/signal.h"
18749 -#include "asm/uaccess.h"
18750 #include "asm/ucontext.h"
18751 #include "frame_kern.h"
18752 #include "sigcontext.h"
18753 @@ -29,12 +28,15 @@
18754 sizeof(restorer)));
18757 +extern int userspace_pid[];
18759 static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from,
18760 struct arch_frame_data *arch)
18762 return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
18764 - copy_sc_to_user_skas(to, fp, &from->regs,
18765 + copy_sc_to_user_skas(userspace_pid[0], to, fp,
18767 current->thread.cr2,
18768 current->thread.err)));
18770 Index: uml-2.6.7/arch/um/include/mem.h
18771 ===================================================================
18772 --- uml-2.6.7.orig/arch/um/include/mem.h 2004-07-16 19:37:46.189003280 +0300
18773 +++ uml-2.6.7/arch/um/include/mem.h 2004-07-16 19:47:23.703207776 +0300
18776 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18777 + * Copyright (C) 2002, 2003 Jeff Dike (jdike@addtoit.com)
18778 * Licensed under the GPL
18784 -struct vm_reserved {
18785 - struct list_head list;
18786 - unsigned long start;
18787 - unsigned long end;
18789 +#include "linux/types.h"
18791 -extern void set_usable_vm(unsigned long start, unsigned long end);
18792 -extern void set_kmem_end(unsigned long new);
18793 +extern int phys_mapping(unsigned long phys, __u64 *offset_out);
18794 +extern int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w);
18795 +extern int is_remapped(void *virt);
18796 +extern int physmem_remove_mapping(void *virt);
18797 +extern void physmem_forget_descriptor(int fd);
18801 Index: uml-2.6.7/arch/um/include/ubd_user.h
18802 ===================================================================
18803 --- uml-2.6.7.orig/arch/um/include/ubd_user.h 2004-07-16 19:36:48.255810464 +0300
18804 +++ uml-2.6.7/arch/um/include/ubd_user.h 2004-07-16 19:47:23.708207016 +0300
18809 -enum ubd_req { UBD_READ, UBD_WRITE };
18810 +enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
18812 struct io_thread_req {
18817 unsigned long sector_mask;
18818 - unsigned long cow_offset;
18819 + unsigned long long cow_offset;
18820 unsigned long bitmap_words[2];
18822 + unsigned long long map_offset;
18827 int *create_cow_out);
18828 extern int create_cow_file(char *cow_file, char *backing_file,
18829 struct openflags flags, int sectorsize,
18830 - int *bitmap_offset_out,
18831 + int alignment, int *bitmap_offset_out,
18832 unsigned long *bitmap_len_out,
18833 int *data_offset_out);
18834 extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
18836 extern int write_ubd_fs(int fd, char *buffer, int len);
18837 extern int start_io_thread(unsigned long sp, int *fds_out);
18838 extern void do_io(struct io_thread_req *req);
18839 -extern int ubd_is_dir(char *file);
18841 static inline int ubd_test_bit(__u64 bit, unsigned char *data)
18843 Index: uml-2.6.7/arch/um/uml.lds.S
18844 ===================================================================
18845 --- uml-2.6.7.orig/arch/um/uml.lds.S 2004-07-16 19:36:36.401612576 +0300
18846 +++ uml-2.6.7/arch/um/uml.lds.S 2004-07-16 19:47:23.780196072 +0300
18849 . = START + SIZEOF_HEADERS;
18852 __binary_start = .;
18854 .thread_private : {
18855 @@ -26,11 +25,16 @@
18856 . = ALIGN(4096); /* Init code and data */
18859 - .text.init : { *(.text.init) }
18870 /* .gnu.warning sections are handled specially by elf32.em. */
18872 *(.gnu.linkonce.t*)
18875 #include "asm/common.lds.S"
18877 - .data.init : { *(.data.init) }
18878 + init.data : { *(init.data) }
18881 . = ALIGN(KERNEL_STACK_SIZE); /* init_task */
18882 Index: uml-2.6.7/arch/um/os-Linux/drivers/ethertap_user.c
18883 ===================================================================
18884 --- uml-2.6.7.orig/arch/um/os-Linux/drivers/ethertap_user.c 2004-07-16 19:36:42.453692520 +0300
18885 +++ uml-2.6.7/arch/um/os-Linux/drivers/ethertap_user.c 2004-07-16 19:47:24.801040880 +0300
18888 #include <unistd.h>
18889 #include <stddef.h>
18890 -#include <fcntl.h>
18891 #include <stdlib.h>
18892 #include <sys/errno.h>
18893 #include <sys/socket.h>
18895 #include <net/if.h>
18897 #include "kern_util.h"
18898 +#include "user_util.h"
18899 #include "net_user.h"
18901 #include "helper.h"
18902 @@ -42,13 +42,14 @@
18904 struct addr_change change;
18909 memcpy(change.addr, addr, sizeof(change.addr));
18910 memcpy(change.netmask, netmask, sizeof(change.netmask));
18911 - if(write(fd, &change, sizeof(change)) != sizeof(change))
18912 - printk("etap_change - request failed, errno = %d\n",
18914 + n = os_write_file(fd, &change, sizeof(change));
18915 + if(n != sizeof(change))
18916 + printk("etap_change - request failed, err = %d\n", -n);
18917 output = um_kmalloc(page_size());
18919 printk("etap_change : Failed to allocate output buffer\n");
18920 @@ -82,15 +83,15 @@
18921 struct etap_pre_exec_data *data = arg;
18923 dup2(data->control_remote, 1);
18924 - close(data->data_me);
18925 - close(data->control_me);
18926 + os_close_file(data->data_me);
18927 + os_close_file(data->control_me);
18930 static int etap_tramp(char *dev, char *gate, int control_me,
18931 int control_remote, int data_me, int data_remote)
18933 struct etap_pre_exec_data pe_data;
18934 - int pid, status, err;
18935 + int pid, status, err, n;
18936 char version_buf[sizeof("nnnnn\0")];
18937 char data_fd_buf[sizeof("nnnnnn\0")];
18938 char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
18939 @@ -114,21 +115,22 @@
18940 pe_data.data_me = data_me;
18941 pid = run_helper(etap_pre_exec, &pe_data, args, NULL);
18943 - if(pid < 0) err = errno;
18944 - close(data_remote);
18945 - close(control_remote);
18946 - if(read(control_me, &c, sizeof(c)) != sizeof(c)){
18947 - printk("etap_tramp : read of status failed, errno = %d\n",
18950 + if(pid < 0) err = pid;
18951 + os_close_file(data_remote);
18952 + os_close_file(control_remote);
18953 + n = os_read_file(control_me, &c, sizeof(c));
18954 + if(n != sizeof(c)){
18955 + printk("etap_tramp : read of status failed, err = %d\n", -n);
18959 printk("etap_tramp : uml_net failed\n");
18961 - if(waitpid(pid, &status, 0) < 0) err = errno;
18962 - else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)){
18964 + CATCH_EINTR(n = waitpid(pid, &status, 0));
18967 + else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
18968 printk("uml_net didn't exit with status 1\n");
18973 @@ -143,14 +145,14 @@
18974 if(err) return(err);
18976 err = os_pipe(data_fds, 0, 0);
18978 - printk("data os_pipe failed - errno = %d\n", -err);
18980 + printk("data os_pipe failed - err = %d\n", -err);
18984 err = os_pipe(control_fds, 1, 0);
18986 - printk("control os_pipe failed - errno = %d\n", -err);
18988 + printk("control os_pipe failed - err = %d\n", -err);
18992 @@ -167,9 +169,9 @@
18997 - printk("etap_tramp failed - errno = %d\n", err);
19000 + printk("etap_tramp failed - err = %d\n", -err);
19004 pri->data_fd = data_fds[0];
19005 @@ -183,11 +185,11 @@
19006 struct ethertap_data *pri = data;
19008 iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
19010 + os_close_file(fd);
19011 os_shutdown_socket(pri->data_fd, 1, 1);
19012 - close(pri->data_fd);
19013 + os_close_file(pri->data_fd);
19015 - close(pri->control_fd);
19016 + os_close_file(pri->control_fd);
19017 pri->control_fd = -1;
19020 Index: uml-2.6.7/arch/um/drivers/ubd_user.c
19021 ===================================================================
19022 --- uml-2.6.7.orig/arch/um/drivers/ubd_user.c 2004-07-16 19:36:13.849041088 +0300
19023 +++ uml-2.6.7/arch/um/drivers/ubd_user.c 2004-07-16 19:47:23.698208536 +0300
19025 #include <signal.h>
19026 #include <string.h>
19027 #include <netinet/in.h>
19028 -#include <sys/stat.h>
19029 #include <sys/time.h>
19030 -#include <sys/fcntl.h>
19031 #include <sys/socket.h>
19032 -#include <string.h>
19033 #include <sys/mman.h>
19034 #include <sys/param.h>
19035 #include "asm/types.h"
19036 @@ -24,146 +21,30 @@
19038 #include "ubd_user.h"
19042 #include <endian.h>
19043 #include <byteswap.h>
19044 -#if __BYTE_ORDER == __BIG_ENDIAN
19045 -# define ntohll(x) (x)
19046 -# define htonll(x) (x)
19047 -#elif __BYTE_ORDER == __LITTLE_ENDIAN
19048 -# define ntohll(x) bswap_64(x)
19049 -# define htonll(x) bswap_64(x)
19051 -#error "__BYTE_ORDER not defined"
19054 -#define PATH_LEN_V1 256
19056 -struct cow_header_v1 {
19059 - char backing_file[PATH_LEN_V1];
19065 -#define PATH_LEN_V2 MAXPATHLEN
19067 -struct cow_header_v2 {
19068 - unsigned long magic;
19069 - unsigned long version;
19070 - char backing_file[PATH_LEN_V2];
19076 -union cow_header {
19077 - struct cow_header_v1 v1;
19078 - struct cow_header_v2 v2;
19081 -#define COW_MAGIC 0x4f4f4f4d /* MOOO */
19082 -#define COW_VERSION 2
19084 -static void sizes(__u64 size, int sectorsize, int bitmap_offset,
19085 - unsigned long *bitmap_len_out, int *data_offset_out)
19087 - *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
19089 - *data_offset_out = bitmap_offset + *bitmap_len_out;
19090 - *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
19091 - *data_offset_out *= sectorsize;
19094 -static int read_cow_header(int fd, int *magic_out, char **backing_file_out,
19095 - time_t *mtime_out, __u64 *size_out,
19096 - int *sectorsize_out, int *bitmap_offset_out)
19098 - union cow_header *header;
19101 - unsigned long version, magic;
19103 - header = um_kmalloc(sizeof(*header));
19104 - if(header == NULL){
19105 - printk("read_cow_header - Failed to allocate header\n");
19109 - n = read(fd, header, sizeof(*header));
19110 - if(n < offsetof(typeof(header->v1), backing_file)){
19111 - printk("read_cow_header - short header\n");
19115 - magic = header->v1.magic;
19116 - if(magic == COW_MAGIC) {
19117 - version = header->v1.version;
19119 - else if(magic == ntohl(COW_MAGIC)){
19120 - version = ntohl(header->v1.version);
19124 - *magic_out = COW_MAGIC;
19126 - if(version == 1){
19127 - if(n < sizeof(header->v1)){
19128 - printk("read_cow_header - failed to read V1 header\n");
19131 - *mtime_out = header->v1.mtime;
19132 - *size_out = header->v1.size;
19133 - *sectorsize_out = header->v1.sectorsize;
19134 - *bitmap_offset_out = sizeof(header->v1);
19135 - file = header->v1.backing_file;
19137 - else if(version == 2){
19138 - if(n < sizeof(header->v2)){
19139 - printk("read_cow_header - failed to read V2 header\n");
19142 - *mtime_out = ntohl(header->v2.mtime);
19143 - *size_out = ntohll(header->v2.size);
19144 - *sectorsize_out = ntohl(header->v2.sectorsize);
19145 - *bitmap_offset_out = sizeof(header->v2);
19146 - file = header->v2.backing_file;
19149 - printk("read_cow_header - invalid COW version\n");
19153 - *backing_file_out = uml_strdup(file);
19154 - if(*backing_file_out == NULL){
19155 - printk("read_cow_header - failed to allocate backing file\n");
19164 static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
19166 - struct stat buf1, buf2;
19167 + struct uml_stat buf1, buf2;
19170 if(from_cmdline == NULL) return(1);
19171 if(!strcmp(from_cmdline, from_cow)) return(1);
19173 - if(stat(from_cmdline, &buf1) < 0){
19174 - printk("Couldn't stat '%s', errno = %d\n", from_cmdline,
19176 + err = os_stat_file(from_cmdline, &buf1);
19178 + printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
19181 - if(stat(from_cow, &buf2) < 0){
19182 - printk("Couldn't stat '%s', errno = %d\n", from_cow, errno);
19183 + err = os_stat_file(from_cow, &buf2);
19185 + printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
19188 - if((buf1.st_dev == buf2.st_dev) && (buf1.st_ino == buf2.st_ino))
19189 + if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
19192 printk("Backing file mismatch - \"%s\" requested,\n"
19193 @@ -174,20 +55,21 @@
19195 static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
19197 - struct stat64 buf;
19198 + unsigned long modtime;
19202 - if(stat64(file, &buf) < 0){
19203 - printk("Failed to stat backing file \"%s\", errno = %d\n",
19206 + err = os_file_modtime(file, &modtime);
19208 + printk("Failed to get modification time of backing file "
19209 + "\"%s\", err = %d\n", file, -err);
19213 err = os_file_size(file, &actual);
19216 printk("Failed to get size of backing file \"%s\", "
19217 - "errno = %d\n", file, -err);
19218 + "err = %d\n", file, -err);
19223 "file\n", size, actual);
19226 - if(buf.st_mtime != mtime){
19227 + if(modtime != mtime){
19228 printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
19229 - "file\n", mtime, buf.st_mtime);
19230 + "file\n", mtime, modtime);
19234 @@ -209,124 +91,16 @@
19237 err = os_seek_file(fd, offset);
19238 - if(err != 0) return(-errno);
19239 - err = read(fd, buf, len);
19240 - if(err < 0) return(-errno);
19246 -static int absolutize(char *to, int size, char *from)
19248 - char save_cwd[256], *slash;
19250 + err = os_read_file(fd, buf, len);
19254 - if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
19255 - printk("absolutize : unable to get cwd - errno = %d\n", errno);
19258 - slash = strrchr(from, '/');
19259 - if(slash != NULL){
19263 - printk("absolutize : Can't cd to '%s' - errno = %d\n",
19268 - if(getcwd(to, size) == NULL){
19269 - printk("absolutize : unable to get cwd of '%s' - "
19270 - "errno = %d\n", from, errno);
19273 - remaining = size - strlen(to);
19274 - if(strlen(slash) + 1 > remaining){
19275 - printk("absolutize : unable to fit '%s' into %d "
19276 - "chars\n", from, size);
19279 - strcat(to, slash);
19282 - if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
19283 - printk("absolutize : unable to fit '%s' into %d "
19284 - "chars\n", from, size);
19287 - strcpy(to, save_cwd);
19289 - strcat(to, from);
19295 -static int write_cow_header(char *cow_file, int fd, char *backing_file,
19296 - int sectorsize, long long *size)
19298 - struct cow_header_v2 *header;
19299 - struct stat64 buf;
19302 - err = os_seek_file(fd, 0);
19304 - printk("write_cow_header - lseek failed, errno = %d\n", errno);
19309 - header = um_kmalloc(sizeof(*header));
19310 - if(header == NULL){
19311 - printk("Failed to allocate COW V2 header\n");
19314 - header->magic = htonl(COW_MAGIC);
19315 - header->version = htonl(COW_VERSION);
19318 - if(strlen(backing_file) > sizeof(header->backing_file) - 1){
19319 - printk("Backing file name \"%s\" is too long - names are "
19320 - "limited to %d characters\n", backing_file,
19321 - sizeof(header->backing_file) - 1);
19325 - if(absolutize(header->backing_file, sizeof(header->backing_file),
19329 - err = stat64(header->backing_file, &buf);
19331 - printk("Stat of backing file '%s' failed, errno = %d\n",
19332 - header->backing_file, errno);
19337 - err = os_file_size(header->backing_file, size);
19339 - printk("Couldn't get size of backing file '%s', errno = %d\n",
19340 - header->backing_file, -*size);
19344 - header->mtime = htonl(buf.st_mtime);
19345 - header->size = htonll(*size);
19346 - header->sectorsize = htonl(sectorsize);
19348 - err = write(fd, header, sizeof(*header));
19349 - if(err != sizeof(*header)){
19350 - printk("Write of header to new COW file '%s' failed, "
19351 - "errno = %d\n", cow_file, errno);
19361 int open_ubd_file(char *file, struct openflags *openflags,
19362 char **backing_file_out, int *bitmap_offset_out,
19363 unsigned long *bitmap_len_out, int *data_offset_out,
19364 @@ -334,26 +108,36 @@
19368 + __u32 version, align;
19369 char *backing_file;
19370 - int fd, err, sectorsize, magic, same, mode = 0644;
19371 + int fd, err, sectorsize, same, mode = 0644;
19373 - if((fd = os_open_file(file, *openflags, mode)) < 0){
19374 + fd = os_open_file(file, *openflags, mode);
19376 if((fd == -ENOENT) && (create_cow_out != NULL))
19377 *create_cow_out = 1;
19378 if(!openflags->w ||
19379 ((errno != EROFS) && (errno != EACCES))) return(-errno);
19381 - if((fd = os_open_file(file, *openflags, mode)) < 0)
19382 + fd = os_open_file(file, *openflags, mode);
19387 + err = os_lock_file(fd, openflags->w);
19389 + printk("Failed to lock '%s', err = %d\n", file, -err);
19393 if(backing_file_out == NULL) return(fd);
19395 - err = read_cow_header(fd, &magic, &backing_file, &mtime, &size,
19396 - §orsize, bitmap_offset_out);
19397 + err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
19398 + &size, §orsize, &align, bitmap_offset_out);
19399 if(err && (*backing_file_out != NULL)){
19400 printk("Failed to read COW header from COW file \"%s\", "
19401 - "errno = %d\n", file, err);
19403 + "errno = %d\n", file, -err);
19406 if(err) return(fd);
19408 @@ -363,36 +147,33 @@
19410 if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){
19411 printk("Switching backing file to '%s'\n", *backing_file_out);
19412 - err = write_cow_header(file, fd, *backing_file_out,
19413 - sectorsize, &size);
19414 + err = write_cow_header(file, fd, *backing_file_out,
19415 + sectorsize, align, &size);
19417 - printk("Switch failed, errno = %d\n", err);
19418 + printk("Switch failed, errno = %d\n", -err);
19423 *backing_file_out = backing_file;
19424 err = backing_file_mismatch(*backing_file_out, size, mtime);
19425 - if(err) goto error;
19426 + if(err) goto out_close;
19429 - sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out,
19430 - data_offset_out);
19431 + cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
19432 + bitmap_len_out, data_offset_out);
19438 + os_close_file(fd);
19442 int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
19443 - int sectorsize, int *bitmap_offset_out,
19444 + int sectorsize, int alignment, int *bitmap_offset_out,
19445 unsigned long *bitmap_len_out, int *data_offset_out)
19454 fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
19455 @@ -403,57 +184,49 @@
19459 - err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
19460 - if(err) goto out_close;
19462 - blocks = (size + sectorsize - 1) / sectorsize;
19463 - blocks = (blocks + sizeof(long) * 8 - 1) / (sizeof(long) * 8);
19465 - for(i = 0; i < blocks; i++){
19466 - err = write(fd, &zero, sizeof(zero));
19467 - if(err != sizeof(zero)){
19468 - printk("Write of bitmap to new COW file '%s' failed, "
19469 - "errno = %d\n", cow_file, errno);
19474 - sizes(size, sectorsize, sizeof(struct cow_header_v2),
19475 - bitmap_len_out, data_offset_out);
19476 - *bitmap_offset_out = sizeof(struct cow_header_v2);
19482 + err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
19483 + bitmap_offset_out, bitmap_len_out,
19484 + data_offset_out);
19487 + os_close_file(fd);
19492 +/* XXX Just trivial wrappers around os_read_file and os_write_file */
19493 int read_ubd_fs(int fd, void *buffer, int len)
19497 - n = read(fd, buffer, len);
19498 - if(n < 0) return(-errno);
19500 + return(os_read_file(fd, buffer, len));
19503 int write_ubd_fs(int fd, char *buffer, int len)
19507 - n = write(fd, buffer, len);
19508 - if(n < 0) return(-errno);
19510 + return(os_write_file(fd, buffer, len));
19513 -int ubd_is_dir(char *file)
19514 +static int update_bitmap(struct io_thread_req *req)
19516 - struct stat64 buf;
19519 + if(req->cow_offset == -1)
19522 + n = os_seek_file(req->fds[1], req->cow_offset);
19524 + printk("do_io - bitmap lseek failed : err = %d\n", -n);
19528 + n = os_write_file(req->fds[1], &req->bitmap_words,
19529 + sizeof(req->bitmap_words));
19530 + if(n != sizeof(req->bitmap_words)){
19531 + printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
19536 - if(stat64(file, &buf) < 0) return(0);
19537 - return(S_ISDIR(buf.st_mode));
19541 void do_io(struct io_thread_req *req)
19542 @@ -461,8 +234,18 @@
19545 int n, nsectors, start, end, bit;
19549 + if(req->op == UBD_MMAP){
19550 + /* Touch the page to force the host to do any necessary IO to
19551 + * get it into memory
19553 + n = *((volatile int *) req->buffer);
19554 + req->error = update_bitmap(req);
19558 nsectors = req->length / req->sectorsize;
19561 @@ -473,15 +256,14 @@
19562 &req->sector_mask) == bit))
19565 - if(end != nsectors)
19566 - printk("end != nsectors\n");
19567 off = req->offset + req->offsets[bit] +
19568 start * req->sectorsize;
19569 len = (end - start) * req->sectorsize;
19570 buf = &req->buffer[start * req->sectorsize];
19572 - if(os_seek_file(req->fds[bit], off) != 0){
19573 - printk("do_io - lseek failed : errno = %d\n", errno);
19574 + err = os_seek_file(req->fds[bit], off);
19576 + printk("do_io - lseek failed : err = %d\n", -err);
19580 @@ -490,11 +272,10 @@
19584 - n = read(req->fds[bit], buf, len);
19585 + n = os_read_file(req->fds[bit], buf, len);
19587 - printk("do_io - read returned %d : "
19588 - "errno = %d fd = %d\n", n,
19589 - errno, req->fds[bit]);
19590 + printk("do_io - read failed, err = %d "
19591 + "fd = %d\n", -n, req->fds[bit]);
19595 @@ -502,11 +283,10 @@
19596 if (n < len) memset(&buf[n], 0, len - n);
19599 - n = write(req->fds[bit], buf, len);
19600 + n = os_write_file(req->fds[bit], buf, len);
19602 - printk("do_io - write returned %d : "
19603 - "errno = %d fd = %d\n", n,
19604 - errno, req->fds[bit]);
19605 + printk("do_io - write failed err = %d "
19606 + "fd = %d\n", -n, req->fds[bit]);
19610 @@ -515,24 +295,7 @@
19612 } while(start < nsectors);
19614 - if(req->cow_offset != -1){
19615 - if(os_seek_file(req->fds[1], req->cow_offset) != 0){
19616 - printk("do_io - bitmap lseek failed : errno = %d\n",
19621 - n = write(req->fds[1], &req->bitmap_words,
19622 - sizeof(req->bitmap_words));
19623 - if(n != sizeof(req->bitmap_words)){
19624 - printk("do_io - bitmap update returned %d : "
19625 - "errno = %d fd = %d\n", n, errno, req->fds[1]);
19632 + req->error = update_bitmap(req);
19635 /* Changed in start_io_thread, which is serialized by being called only
19636 @@ -550,19 +313,23 @@
19638 signal(SIGWINCH, SIG_IGN);
19640 - n = read(kernel_fd, &req, sizeof(req));
19641 - if(n < 0) printk("io_thread - read returned %d, errno = %d\n",
19643 - else if(n < sizeof(req)){
19644 - printk("io_thread - short read : length = %d\n", n);
19645 + n = os_read_file(kernel_fd, &req, sizeof(req));
19646 + if(n != sizeof(req)){
19648 + printk("io_thread - read failed, fd = %d, "
19649 + "err = %d\n", kernel_fd, -n);
19651 + printk("io_thread - short read, fd = %d, "
19652 + "length = %d\n", kernel_fd, n);
19658 - n = write(kernel_fd, &req, sizeof(req));
19659 + n = os_write_file(kernel_fd, &req, sizeof(req));
19660 if(n != sizeof(req))
19661 - printk("io_thread - write failed, errno = %d\n",
19663 + printk("io_thread - write failed, fd = %d, err = %d\n",
19668 @@ -571,10 +338,11 @@
19669 int pid, fds[2], err;
19671 err = os_pipe(fds, 1, 1);
19673 - printk("start_io_thread - os_pipe failed, errno = %d\n", -err);
19676 + printk("start_io_thread - os_pipe failed, err = %d\n", -err);
19680 kernel_fd = fds[0];
19683 @@ -582,32 +350,19 @@
19686 printk("start_io_thread - clone failed : errno = %d\n", errno);
19694 -int start_io_thread(unsigned long sp, int *fd_out)
19698 - if((kernel_fd = get_pty()) < 0) return(-1);
19699 - raw(kernel_fd, 0);
19700 - if((*fd_out = open(ptsname(kernel_fd), O_RDWR)) < 0){
19701 - printk("Couldn't open tty for IO\n");
19705 - pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
19708 - printk("start_io_thread - clone failed : errno = %d\n", errno);
19714 + os_close_file(fds[0]);
19715 + os_close_file(fds[1]);
19724 * Overrides for Emacs so that we follow Linus's tabbing style.
19725 Index: uml-2.6.7/scripts/basic/fixdep.c
19726 ===================================================================
19727 --- uml-2.6.7.orig/scripts/basic/fixdep.c 2004-07-16 19:36:40.092051544 +0300
19728 +++ uml-2.6.7/scripts/basic/fixdep.c 2004-07-16 19:47:24.197132688 +0300
19730 * (Note: it'd be easy to port over the complete mkdep state machine,
19731 * but I don't think the added complexity is worth it)
19734 + * Note 2: if somebody writes HELLO_CONFIG_BOOM in a file, it will depend onto
19735 + * CONFIG_BOOM. This could seem a bug (not too hard to fix), but please do not
19736 + * fix it! Some UserModeLinux files (look at arch/um/) call CONFIG_BOOM as
19737 + * UML_CONFIG_BOOM, to avoid conflicts with /usr/include/linux/autoconf.h,
19738 + * through arch/um/include/uml-config.h; this fixdep "bug" makes sure that
19739 + * those files will have correct dependencies.
19742 #include <sys/types.h>
19743 #include <sys/stat.h>
19744 @@ -310,6 +318,7 @@
19746 memcpy(s, m, p-m); s[p-m] = 0;
19747 if (strrcmp(s, "include/linux/autoconf.h") &&
19748 + strrcmp(s, "arch/um/include/uml-config.h") &&
19749 strrcmp(s, ".ver")) {
19750 printf(" %s \\\n", s);
19752 Index: uml-2.6.7/include/asm-um/processor-i386.h
19753 ===================================================================
19754 --- uml-2.6.7.orig/include/asm-um/processor-i386.h 2004-07-16 19:35:55.931764928 +0300
19755 +++ uml-2.6.7/include/asm-um/processor-i386.h 2004-07-16 19:47:23.794193944 +0300
19757 #ifndef __UM_PROCESSOR_I386_H
19758 #define __UM_PROCESSOR_I386_H
19760 -extern int cpu_has_xmm;
19761 -extern int cpu_has_cmov;
19762 +extern int host_has_xmm;
19763 +extern int host_has_cmov;
19765 struct arch_thread {
19766 unsigned long debugregs[8];
19767 Index: uml-2.6.7/arch/um/kernel/time.c
19768 ===================================================================
19769 --- uml-2.6.7.orig/arch/um/kernel/time.c 2004-07-16 19:36:10.588536760 +0300
19770 +++ uml-2.6.7/arch/um/kernel/time.c 2004-07-16 19:47:24.262122808 +0300
19775 +#include <stdlib.h>
19776 #include <unistd.h>
19778 #include <sys/time.h>
19779 #include <signal.h>
19781 -#include "linux/module.h"
19782 +#include <string.h>
19783 #include "user_util.h"
19784 #include "kern_util.h"
19786 #include "process.h"
19787 #include "signal_user.h"
19788 #include "time_user.h"
19789 +#include "kern_constants.h"
19791 +/* XXX This really needs to be declared and initialized in a kernel file since
19792 + * it's in <linux/time.h>
19794 +extern struct timespec wall_to_monotonic;
19796 extern struct timeval xtime;
19798 +struct timeval local_offset = { 0, 0 };
19802 gettimeofday(&xtime, NULL);
19803 + timeradd(&xtime, &local_offset, &xtime);
19806 void set_interval(int timer_type)
19811 -void idle_timer(void)
19812 +void uml_idle_timer(void)
19814 if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
19815 panic("Couldn't unset SIGVTALRM handler");
19816 @@ -76,14 +86,60 @@
19817 set_interval(ITIMER_REAL);
19820 +static unsigned long long get_host_hz(void)
19822 + char mhzline[16], *end;
19823 + unsigned long long mhz;
19824 + int ret, mult, rest, len;
19826 + ret = cpu_feature("cpu MHz", mhzline,
19827 + sizeof(mhzline) / sizeof(mhzline[0]));
19829 + panic ("Could not get host MHZ");
19831 + mhz = strtoul(mhzline, &end, 10);
19833 + /* This business is to parse a floating point number without using
19834 + * floating types.
19841 + len = strlen(end);
19846 + rest = strtoul(end, NULL, 10);
19847 + while(mult-- > 0)
19851 + return(1000000 * mhz + rest);
19854 +unsigned long long host_hz = 0;
19856 +extern int do_posix_clock_monotonic_gettime(struct timespec *tp);
19858 void time_init(void)
19860 + struct timespec now;
19862 + host_hz = get_host_hz();
19863 if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
19864 panic("Couldn't set SIGVTALRM handler");
19865 set_interval(ITIMER_VIRTUAL);
19867 + do_posix_clock_monotonic_gettime(&now);
19868 + wall_to_monotonic.tv_sec = -now.tv_sec;
19869 + wall_to_monotonic.tv_nsec = -now.tv_nsec;
19872 -struct timeval local_offset = { 0, 0 };
19873 +/* Declared in linux/time.h, which can't be included here */
19874 +extern void clock_was_set(void);
19876 void do_gettimeofday(struct timeval *tv)
19878 @@ -96,15 +152,13 @@
19882 -EXPORT_SYMBOL(do_gettimeofday);
19884 int do_settimeofday(struct timespec *tv)
19886 struct timeval now;
19887 unsigned long flags;
19888 struct timeval tv_in;
19890 - if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
19891 + if ((unsigned long) tv->tv_nsec >= UM_NSEC_PER_SEC)
19894 tv_in.tv_sec = tv->tv_sec;
19895 @@ -114,9 +168,9 @@
19896 gettimeofday(&now, NULL);
19897 timersub(&tv_in, &now, &local_offset);
19898 time_unlock(flags);
19901 -EXPORT_SYMBOL(do_settimeofday);
19905 void idle_sleep(int secs)
19907 Index: uml-2.6.7/arch/um/drivers/mconsole_user.c
19908 ===================================================================
19909 --- uml-2.6.7.orig/arch/um/drivers/mconsole_user.c 2004-07-16 19:36:07.180054928 +0300
19910 +++ uml-2.6.7/arch/um/drivers/mconsole_user.c 2004-07-16 19:47:23.687210208 +0300
19913 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
19914 - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
19915 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
19916 * Licensed under the GPL
19919 @@ -18,16 +18,18 @@
19922 static struct mconsole_command commands[] = {
19923 - { "version", mconsole_version, 1 },
19924 - { "halt", mconsole_halt, 0 },
19925 - { "reboot", mconsole_reboot, 0 },
19926 - { "config", mconsole_config, 0 },
19927 - { "remove", mconsole_remove, 0 },
19928 - { "sysrq", mconsole_sysrq, 1 },
19929 - { "help", mconsole_help, 1 },
19930 - { "cad", mconsole_cad, 1 },
19931 - { "stop", mconsole_stop, 0 },
19932 - { "go", mconsole_go, 1 },
19933 + { "version", mconsole_version, MCONSOLE_INTR },
19934 + { "halt", mconsole_halt, MCONSOLE_PROC },
19935 + { "reboot", mconsole_reboot, MCONSOLE_PROC },
19936 + { "config", mconsole_config, MCONSOLE_PROC },
19937 + { "remove", mconsole_remove, MCONSOLE_PROC },
19938 + { "sysrq", mconsole_sysrq, MCONSOLE_INTR },
19939 + { "help", mconsole_help, MCONSOLE_INTR },
19940 + { "cad", mconsole_cad, MCONSOLE_INTR },
19941 + { "stop", mconsole_stop, MCONSOLE_PROC },
19942 + { "go", mconsole_go, MCONSOLE_INTR },
19943 + { "log", mconsole_log, MCONSOLE_INTR },
19944 + { "proc", mconsole_proc, MCONSOLE_PROC },
19947 /* Initialized in mconsole_init, which is an initcall */
19948 @@ -139,6 +141,7 @@
19949 memcpy(reply.data, str, len);
19950 reply.data[len] = '\0';
19953 reply.len = len + 1;
19955 len = sizeof(reply) + reply.len - sizeof(reply.data);
19956 Index: uml-2.6.7/include/asm-um/module-i386.h
19957 ===================================================================
19958 --- uml-2.6.7.orig/include/asm-um/module-i386.h 2004-07-16 19:47:23.634218264 +0300
19959 +++ uml-2.6.7/include/asm-um/module-i386.h 2004-07-16 19:47:23.792194248 +0300
19961 +#ifndef __UM_MODULE_I386_H
19962 +#define __UM_MODULE_I386_H
19964 +/* UML is simple */
19965 +struct mod_arch_specific
19969 +#define Elf_Shdr Elf32_Shdr
19970 +#define Elf_Sym Elf32_Sym
19971 +#define Elf_Ehdr Elf32_Ehdr
19974 Index: uml-2.6.7/arch/um/kernel/tt/ptproxy/wait.c
19975 ===================================================================
19976 --- uml-2.6.7.orig/arch/um/kernel/tt/ptproxy/wait.c 2004-07-16 19:37:26.029068056 +0300
19977 +++ uml-2.6.7/arch/um/kernel/tt/ptproxy/wait.c 2004-07-16 19:47:23.748200936 +0300
19978 @@ -56,21 +56,23 @@
19979 int real_wait_return(struct debugger *debugger)
19985 pid = debugger->pid;
19987 ip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
19988 - ip = IP_RESTART_SYSCALL(ip);
19989 - err = ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip);
19990 + IP_RESTART_SYSCALL(ip);
19992 if(ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip) < 0)
19993 tracer_panic("real_wait_return : Failed to restart system "
19994 - "call, errno = %d\n");
19995 + "call, errno = %d\n", errno);
19997 if((ptrace(PTRACE_SYSCALL, debugger->pid, 0, SIGCHLD) < 0) ||
19998 (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
19999 (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
20000 debugger_normal_return(debugger, -1))
20001 tracer_panic("real_wait_return : gdb failed to wait, "
20003 + "errno = %d\n", errno);
20007 Index: uml-2.6.7/include/asm-um/common.lds.S
20008 ===================================================================
20009 --- uml-2.6.7.orig/include/asm-um/common.lds.S 2004-07-16 19:36:10.607533872 +0300
20010 +++ uml-2.6.7/include/asm-um/common.lds.S 2004-07-16 19:47:23.787195008 +0300
20012 +#include <asm-generic/vmlinux.lds.h>
20014 .fini : { *(.fini) } =0x9090
20016 PROVIDE (etext = .);
20021 - __start___ksymtab = .; /* Kernel symbol table */
20022 - __ksymtab : { *(__ksymtab) }
20023 - __stop___ksymtab = .;
20025 - __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only symbols */
20026 - __gpl_ksymtab : { *(__gpl_ksymtab) }
20027 - __stop___gpl_ksymtab = .;
20029 - __start___kallsyms = .; /* All kernel symbols */
20030 - __kallsyms : { *(__kallsyms) }
20031 - __stop___kallsyms = .;
20033 .unprotected : { *(.unprotected) }
20035 PROVIDE (_unprotected_end = .);
20036 @@ -67,11 +57,17 @@
20038 __initcall_end = .;
20040 + __con_initcall_start = .;
20041 + .con_initcall.init : { *(.con_initcall.init) }
20042 + __con_initcall_end = .;
20044 __uml_initcall_start = .;
20045 .uml.initcall.init : { *(.uml.initcall.init) }
20046 __uml_initcall_end = .;
20051 __exitcall_begin = .;
20052 .exitcall : { *(.exitcall.exit) }
20053 __exitcall_end = .;
20055 .uml.exitcall : { *(.uml.exitcall.exit) }
20056 __uml_exitcall_end = .;
20060 + __alt_instructions = .;
20061 + .altinstructions : { *(.altinstructions) }
20062 + __alt_instructions_end = .;
20063 + .altinstr_replacement : { *(.altinstr_replacement) }
20064 + /* .exit.text is discard at runtime, not link time, to deal with references
20065 + from .altinstructions and .eh_frame */
20066 + .exit.text : { *(.exit.text) }
20067 + .exit.data : { *(.exit.data) }
20069 + __preinit_array_start = .;
20070 + .preinit_array : { *(.preinit_array) }
20071 + __preinit_array_end = .;
20072 + __init_array_start = .;
20073 + .init_array : { *(.init_array) }
20074 + __init_array_end = .;
20075 + __fini_array_start = .;
20076 + .fini_array : { *(.fini_array) }
20077 + __fini_array_end = .;
20080 __initramfs_start = .;
20081 .init.ramfs : { *(.init.ramfs) }
20082 __initramfs_end = .;
20084 + /* Sections to be discarded */
20086 + *(.exitcall.exit)
20089 Index: uml-2.6.7/arch/um/drivers/hostaudio_user.c
20090 ===================================================================
20091 --- uml-2.6.7.orig/arch/um/drivers/hostaudio_user.c 2004-07-16 19:37:08.767692184 +0300
20092 +++ uml-2.6.7/arch/um/drivers/hostaudio_user.c 1970-01-01 03:00:00.000000000 +0300
20095 - * Copyright (C) 2002 Steve Schmidtke
20096 - * Licensed under the GPL
20099 -#include <sys/types.h>
20100 -#include <sys/stat.h>
20101 -#include <sys/ioctl.h>
20102 -#include <fcntl.h>
20103 -#include <unistd.h>
20104 -#include <errno.h>
20105 -#include "hostaudio.h"
20106 -#include "user_util.h"
20107 -#include "kern_util.h"
20111 -/* /dev/dsp file operations */
20113 -ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer,
20114 - size_t count, loff_t *ppos)
20119 - printk("hostaudio: read_user called, count = %d\n", count);
20122 - ret = read(state->fd, buffer, count);
20124 - if(ret < 0) return(-errno);
20128 -ssize_t hostaudio_write_user(struct hostaudio_state *state, const char *buffer,
20129 - size_t count, loff_t *ppos)
20134 - printk("hostaudio: write_user called, count = %d\n", count);
20137 - ret = write(state->fd, buffer, count);
20139 - if(ret < 0) return(-errno);
20143 -int hostaudio_ioctl_user(struct hostaudio_state *state, unsigned int cmd,
20144 - unsigned long arg)
20148 - printk("hostaudio: ioctl_user called, cmd = %u\n", cmd);
20151 - ret = ioctl(state->fd, cmd, arg);
20153 - if(ret < 0) return(-errno);
20157 -int hostaudio_open_user(struct hostaudio_state *state, int r, int w, char *dsp)
20160 - printk("hostaudio: open_user called\n");
20163 - state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
20165 - if(state->fd >= 0) return(0);
20167 - printk("hostaudio_open_user failed to open '%s', errno = %d\n",
20173 -int hostaudio_release_user(struct hostaudio_state *state)
20176 - printk("hostaudio: release called\n");
20178 - if(state->fd >= 0){
20179 - close(state->fd);
20186 -/* /dev/mixer file operations */
20188 -int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state,
20189 - unsigned int cmd, unsigned long arg)
20193 - printk("hostmixer: ioctl_user called cmd = %u\n",cmd);
20196 - ret = ioctl(state->fd, cmd, arg);
20202 -int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, int w,
20206 - printk("hostmixer: open_user called\n");
20209 - state->fd = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
20211 - if(state->fd >= 0) return(0);
20213 - printk("hostaudio_open_mixdev_user failed to open '%s', errno = %d\n",
20219 -int hostmixer_release_mixdev_user(struct hostmixer_state *state)
20222 - printk("hostmixer: release_user called\n");
20225 - if(state->fd >= 0){
20226 - close(state->fd);
20234 - * Overrides for Emacs so that we follow Linus's tabbing style.
20235 - * Emacs will notice this stuff at the end of the file and automatically
20236 - * adjust the settings for this buffer only. This must remain at the end
20238 - * ---------------------------------------------------------------------------
20239 - * Local variables:
20240 - * c-file-style: "linux"
20243 Index: uml-2.6.7/arch/um/kernel/time_kern.c
20244 ===================================================================
20245 --- uml-2.6.7.orig/arch/um/kernel/time_kern.c 2004-07-16 19:36:57.116463440 +0300
20246 +++ uml-2.6.7/arch/um/kernel/time_kern.c 2004-07-16 19:47:24.262122808 +0300
20247 @@ -30,22 +30,60 @@
20252 + * Scheduler clock - returns current time in nanosec units.
20254 +unsigned long long sched_clock(void)
20256 + return (unsigned long long)jiffies_64 * (1000000000 / HZ);
20259 /* Changed at early boot */
20260 int timer_irq_inited = 0;
20262 -/* missed_ticks will be modified after kernel memory has been
20263 - * write-protected, so this puts it in a section which will be left
20266 -int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS];
20267 +static int first_tick;
20268 +static unsigned long long prev_tsc;
20269 +#ifdef CONFIG_UML_REAL_TIME_CLOCK
20270 +static long long delta; /* Deviation per interval */
20273 +extern unsigned long long host_hz;
20275 void timer_irq(union uml_pt_regs *regs)
20277 - int cpu = current->thread_info->cpu, ticks = missed_ticks[cpu];
20278 + unsigned long long ticks = 0;
20280 + if(!timer_irq_inited){
20281 + /* This is to ensure that ticks don't pile up when
20282 + * the timer handler is suspended */
20287 - if(!timer_irq_inited) return;
20288 - missed_ticks[cpu] = 0;
20289 - while(ticks--) do_IRQ(TIMER_IRQ, regs);
20291 +#ifdef CONFIG_UML_REAL_TIME_CLOCK
20292 + unsigned long long tsc;
20293 + /* We've had 1 tick */
20294 + tsc = time_stamp();
20296 + delta += tsc - prev_tsc;
20299 + ticks += (delta * HZ) / host_hz;
20300 + delta -= (ticks * host_hz) / HZ;
20306 + prev_tsc = time_stamp();
20310 + while(ticks > 0){
20311 + do_IRQ(TIMER_IRQ, regs);
20316 void boot_timer_handler(int sig)
20317 @@ -58,12 +96,15 @@
20321 -void um_timer(int irq, void *dev, struct pt_regs *regs)
20322 +irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
20324 + unsigned long flags;
20327 - write_seqlock(&xtime_lock);
20328 + write_seqlock_irqsave(&xtime_lock, flags);
20330 - write_sequnlock(&xtime_lock);
20331 + write_sequnlock_irqrestore(&xtime_lock, flags);
20332 + return(IRQ_HANDLED);
20335 long um_time(int * tloc)
20336 @@ -81,12 +122,12 @@
20337 long um_stime(int * tptr)
20340 - struct timeval new;
20341 + struct timespec new;
20343 if (get_user(value, tptr))
20345 new.tv_sec = value;
20348 do_settimeofday(&new);
20351 @@ -125,9 +166,11 @@
20352 void timer_handler(int sig, union uml_pt_regs *regs)
20355 + local_irq_disable();
20356 update_process_times(user_context(UPT_SP(regs)));
20357 + local_irq_enable();
20359 - if(current->thread_info->cpu == 0)
20360 + if(current_thread->cpu == 0)
20364 @@ -136,6 +179,7 @@
20365 unsigned long time_lock(void)
20367 unsigned long flags;
20369 spin_lock_irqsave(&timer_spinlock, flags);
20372 @@ -150,8 +194,8 @@
20375 CHOOSE_MODE(user_time_init_tt(), user_time_init_skas());
20376 - if((err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer",
20378 + err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL);
20380 printk(KERN_ERR "timer_init : request_irq failed - "
20381 "errno = %d\n", -err);
20382 timer_irq_inited = 1;
20383 @@ -160,7 +204,6 @@
20385 __initcall(timer_init);
20389 * Overrides for Emacs so that we follow Linus's tabbing style.
20390 * Emacs will notice this stuff at the end of the file and automatically