Whamcloud - gitweb
Brach HEAD
[fs/lustre-release.git] / lustre / kernel_patches / patches / uml-2.6.7-01-bb2.patch
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
5 @@ -1,5 +1,5 @@
6  /* 
7 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
8 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
9   * Licensed under the GPL
10   */
11  
12 @@ -35,14 +35,10 @@
13         errno = save_errno;
14  }
15  
16 -extern int missed_ticks[];
17 -
18  void user_signal(int sig, union uml_pt_regs *regs)
19  {
20         struct signal_info *info;
21  
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
31 @@ -29,6 +29,7 @@
32  #include "user_util.h"
33  #include "kern_util.h"
34  #include "irq_user.h"
35 +#include "irq_kern.h"
36  
37  static void register_irq_proc (unsigned int irq);
38  
39 @@ -83,65 +84,55 @@
40         end_none
41  };
42  
43 -/* Not changed */
44 -volatile unsigned long irq_err_count;
45 -
46  /*
47   * Generic, controller-independent functions:
48   */
49  
50 -int get_irq_list(char *buf)
51 +int show_interrupts(struct seq_file *p, void *v)
52  {
53 -       int i, j;
54 -       unsigned long flags;
55 +       int i = *(loff_t *) v, j;
56         struct irqaction * action;
57 -       char *p = buf;
58 +       unsigned long flags;
59  
60 -       p += sprintf(p, "           ");
61 -       for (j=0; j<num_online_cpus(); j++)
62 -               p += sprintf(p, "CPU%d       ",j);
63 -       *p++ = '\n';
64 +       if (i == 0) {
65 +               seq_printf(p, "           ");
66 +               for (j=0; j<NR_CPUS; j++)
67 +                       if (cpu_online(j))
68 +                               seq_printf(p, "CPU%d       ",j);
69 +               seq_putc(p, '\n');
70 +       }
71  
72 -       for (i = 0 ; i < NR_IRQS ; i++) {
73 +       if (i < NR_IRQS) {
74                 spin_lock_irqsave(&irq_desc[i].lock, flags);
75                 action = irq_desc[i].action;
76                 if (!action) 
77 -                       goto end;
78 -               p += sprintf(p, "%3d: ",i);
79 +                       goto skip;
80 +               seq_printf(p, "%3d: ",i);
81  #ifndef CONFIG_SMP
82 -               p += sprintf(p, "%10u ", kstat_irqs(i));
83 +               seq_printf(p, "%10u ", kstat_irqs(i));
84  #else
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++)
89 +                       if (cpu_online(j))
90 +                               seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
91  #endif
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);
96  
97                 for (action=action->next; action; action = action->next)
98 -                       p += sprintf(p, ", %s", action->name);
99 -               *p++ = '\n';
100 -       end:
101 +                       seq_printf(p, ", %s", action->name);
102 +
103 +               seq_putc(p, '\n');
104 +skip:
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++)
109 +                       if (cpu_online(j))
110 +                               seq_printf(p, "%10u ", nmi_count(j));
111 +               seq_putc(p, '\n');
112         }
113 -       p += sprintf(p, "\n");
114 -#ifdef notdef
115 -#ifdef CONFIG_SMP
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");
121 -#endif
122 -#endif
123 -       p += sprintf(p, "ERR: %10lu\n", irq_err_count);
124 -       return p - buf;
125 -}
126 -
127  
128 -int show_interrupts(struct seq_file *p, void *v)
129 -{
130 -       return(0);
131 +       return 0;
132  }
133  
134  /*
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)
138          */
139 -       int cpu = smp_processor_id();
140         irq_desc_t *desc = irq_desc + irq;
141         struct irqaction * action;
142         unsigned int status;
143  
144         irq_enter();
145 -       kstat_cpu(cpu).irqs[irq]++;
146 +       kstat_this_cpu.irqs[irq]++;
147         spin_lock(&desc->lock);
148         desc->handler->ack(irq);
149         /*
150 @@ -385,7 +375,7 @@
151   */
152   
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,
158                 void *dev_id)
159 @@ -433,15 +423,19 @@
160  EXPORT_SYMBOL(request_irq);
161  
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,
166                    void *dev_id)
167  {
168 -       int retval;
169 +       int err;
170  
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);
175 +       if(err) 
176 +               return(err);
177 +
178 +       if(fd != -1)
179 +               err = activate_fd(irq, fd, type, dev_id);
180 +       return(err);
181  }
182  
183  /* this was setup_x86_irq but it seems pretty generic */
184 @@ -474,7 +468,8 @@
185          */
186         spin_lock_irqsave(&desc->lock,flags);
187         p = &desc->action;
188 -       if ((old = *p) != NULL) {
189 +       old = *p;
190 +       if (old != 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)
196  {
197         int irq = (long) data, full_count = count, err;
198 -       cpumask_t new_value, tmp;
199 +       cpumask_t new_value;
200  
201         if (!irq_desc[irq].handler->set_affinity)
202                 return -EIO;
203  
204         err = cpumask_parse(buffer, count, new_value);
205 +       if(err)
206 +               return(err);
207  
208  #ifdef CONFIG_SMP
209         /*
210 @@ -599,9 +596,11 @@
211          * way to make the system unusable accidentally :-) At least
212          * one online CPU still has to be targeted.
213          */
214 -       cpus_and(tmp, new_value, cpu_online_map);
215 -       if (cpus_empty(tmp))
216 -               return -EINVAL;
217 +       { cpumask_t tmp;
218 +         cpus_and(tmp, new_value, cpu_online_map);
219 +         if (cpus_empty(tmp))
220 +                 return -EINVAL;
221 +       }
222  #endif
223  
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
229 @@ -1,5 +1,5 @@
230  /* 
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
234   */
235  
236 @@ -7,7 +7,6 @@
237  #include <stdlib.h>
238  #include <errno.h>
239  #include <termios.h>
240 -#include <fcntl.h>
241  #include <string.h>
242  #include <signal.h>
243  #include <sys/stat.h>
244 @@ -22,33 +21,6 @@
245  #include "choose-mode.h"
246  #include "mode.h"
247  
248 -void generic_close(int fd, void *unused)
249 -{
250 -       close(fd);
251 -}
252 -
253 -int generic_read(int fd, char *c_out, void *unused)
254 -{
255 -       int n;
256 -
257 -       n = read(fd, c_out, sizeof(*c_out));
258 -       if(n < 0){
259 -               if(errno == EAGAIN) return(0);
260 -               return(-errno);
261 -       }
262 -       else if(n == 0) return(-EIO);
263 -       return(1);
264 -}
265 -
266 -int generic_write(int fd, const char *buf, int n, void *unused)
267 -{
268 -       int count;
269 -
270 -       count = write(fd, buf, n);
271 -       if(count < 0) return(-errno);
272 -       return(count);
273 -}
274 -
275  int generic_console_write(int fd, const char *buf, int n, void *unused)
276  {
277         struct termios save, new;
278 @@ -65,26 +37,6 @@
279         return(err);
280  }
281  
282 -int generic_window_size(int fd, void *unused, unsigned short *rows_out,
283 -                       unsigned short *cols_out)
284 -{
285 -       struct winsize size;
286 -       int ret = 0;
287 -
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;
293 -       }
294 -       return(ret);
295 -}
296 -
297 -void generic_free(void *data)
298 -{
299 -       kfree(data);
300 -}
301 -
302  static void winch_handler(int sig)
303  {
304  }
305 @@ -100,14 +52,16 @@
306         struct winch_data *data = arg;
307         sigset_t sigs;
308         int pty_fd, pipe_fd;
309 +       int count, err;
310         char c = 1;
311  
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);
322  
323         signal(SIGWINCH, winch_handler);
324         sigfillset(&sigs);
325 @@ -123,26 +77,24 @@
326                 exit(1);
327         }
328  
329 -       if(ioctl(pty_fd, TIOCSCTTY, 0) < 0){
330 -               printk("winch_thread : TIOCSCTTY failed, errno = %d\n", errno);
331 -               exit(1);
332 -       }
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());
336 +       if(err < 0){
337 +               printk("winch_thread : new_tty_pgrp failed, err = %d\n", -err);
338                 exit(1);
339         }
340  
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);
347  
348         while(1){
349                 pause();
350  
351 -               if(write(pipe_fd, &c, sizeof(c)) != sizeof(c)){
352 -                       printk("winch_thread : write failed, errno = %d\n",
353 -                              errno);
354 -               }
355 +               count = os_write_file(pipe_fd, &c, sizeof(c));
356 +               if(count != sizeof(c))
357 +                       printk("winch_thread : write failed, err = %d\n",
358 +                              -count);
359         }
360  }
361  
362 @@ -154,8 +106,8 @@
363         char c;
364  
365         err = os_pipe(fds, 1, 1);
366 -       if(err){
367 -               printk("winch_tramp : os_pipe failed, errno = %d\n", -err);
368 +       if(err < 0){
369 +               printk("winch_tramp : os_pipe failed, err = %d\n", -err);
370                 return(err);
371         }
372  
373 @@ -168,12 +120,12 @@
374                 return(pid);
375         }
376  
377 -       close(fds[1]);
378 +       os_close_file(fds[1]);
379         *fd_out = fds[0];
380 -       n = read(fds[0], &c, sizeof(c));
381 +       n = os_read_file(fds[0], &c, sizeof(c));
382         if(n != 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);
387                 *fd_out = -1;
388         }
389 @@ -183,20 +135,24 @@
390  void register_winch(int fd, void *device_data)
391  {
392         int pid, thread, thread_fd;
393 +       int count;
394         char c = 1;
395  
396 -       if(!isatty(fd)) return;
397 +       if(!isatty(fd)) 
398 +               return;
399  
400         pid = tcgetpgrp(fd);
401 -       if(!CHOOSE_MODE(is_tracer_winch(pid, fd, device_data), 0) && 
402 -          (pid == -1)){
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);
406                 if(fd != -1){
407                         register_winch_irq(thread_fd, fd, thread, device_data);
408  
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",
415 +                                       -count);
416                 }
417         }
418  }
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
423 @@ -0,0 +1,375 @@
424 +#include <stddef.h>
425 +#include <string.h>
426 +#include <errno.h>
427 +#include <unistd.h>
428 +#include <byteswap.h>
429 +#include <sys/time.h>
430 +#include <sys/param.h>
431 +#include <sys/user.h>
432 +#include <netinet/in.h>
433 +
434 +#include "os.h"
435 +
436 +#include "cow.h"
437 +#include "cow_sys.h"
438 +
439 +#define PATH_LEN_V1 256
440 +
441 +struct cow_header_v1 {
442 +       int magic;
443 +       int version;
444 +       char backing_file[PATH_LEN_V1];
445 +       time_t mtime;
446 +       __u64 size;
447 +       int sectorsize;
448 +};
449 +
450 +#define PATH_LEN_V2 MAXPATHLEN
451 +
452 +struct cow_header_v2 {
453 +       unsigned long magic;
454 +       unsigned long version;
455 +       char backing_file[PATH_LEN_V2];
456 +       time_t mtime;
457 +       __u64 size;
458 +       int sectorsize;
459 +};
460 +
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
463 + */
464 +#define PATH_LEN_V3 4096
465 +
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
473 + *             bitmap and data
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
488 + */
489 +
490 +struct cow_header_v3 {
491 +       __u32 magic;
492 +       __u32 version;
493 +       time_t mtime;
494 +       __u64 size;
495 +       __u32 sectorsize;
496 +       __u32 alignment;
497 +       __u32 cow_format;
498 +       char backing_file[PATH_LEN_V3];
499 +};
500 +
501 +/* COW format definitions - for now, we have only the usual COW bitmap */
502 +#define COW_BITMAP 0
503 +
504 +union cow_header {
505 +       struct cow_header_v1 v1;
506 +       struct cow_header_v2 v2;
507 +       struct cow_header_v3 v3;
508 +};
509 +
510 +#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
511 +#define COW_VERSION 3
512 +
513 +#define DIV_ROUND(x, len) (((x) + (len) - 1) / (len))
514 +#define ROUND_UP(x, align) DIV_ROUND(x, align) * (align)
515 +
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)
519 +{
520 +       if(version < 3){
521 +               *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
522 +
523 +               *data_offset_out = bitmap_offset + *bitmap_len_out;
524 +               *data_offset_out = (*data_offset_out + sectorsize - 1) / 
525 +                       sectorsize;
526 +               *data_offset_out *= sectorsize;
527 +       }
528 +       else {
529 +               *bitmap_len_out = DIV_ROUND(size, sectorsize);
530 +               *bitmap_len_out = DIV_ROUND(*bitmap_len_out, 8);
531 +
532 +               *data_offset_out = bitmap_offset + *bitmap_len_out;
533 +               *data_offset_out = ROUND_UP(*data_offset_out, align);
534 +       }
535 +}
536 +
537 +static int absolutize(char *to, int size, char *from)
538 +{
539 +       char save_cwd[256], *slash;
540 +       int remaining;
541 +
542 +       if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
543 +               cow_printf("absolutize : unable to get cwd - errno = %d\n", 
544 +                          errno);
545 +               return(-1);
546 +       }
547 +       slash = strrchr(from, '/');
548 +       if(slash != NULL){
549 +               *slash = '\0';
550 +               if(chdir(from)){
551 +                       *slash = '/';
552 +                       cow_printf("absolutize : Can't cd to '%s' - " 
553 +                                  "errno = %d\n", from, errno);
554 +                       return(-1);
555 +               }
556 +               *slash = '/';
557 +               if(getcwd(to, size) == NULL){
558 +                       cow_printf("absolutize : unable to get cwd of '%s' - "
559 +                              "errno = %d\n", from, errno);
560 +                       return(-1);
561 +               }
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);
566 +                       return(-1);
567 +               }
568 +               strcat(to, slash);
569 +       }
570 +       else {
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);
574 +                       return(-1);
575 +               }
576 +               strcpy(to, save_cwd);
577 +               strcat(to, "/");
578 +               strcat(to, from);
579 +       }
580 +       chdir(save_cwd);
581 +       return(0);
582 +}
583 +
584 +int write_cow_header(char *cow_file, int fd, char *backing_file, 
585 +                    int sectorsize, int alignment, long long *size)
586 +{
587 +       struct cow_header_v3 *header;
588 +       unsigned long modtime;
589 +       int err;
590 +
591 +       err = cow_seek_file(fd, 0);
592 +       if(err < 0){
593 +               cow_printf("write_cow_header - lseek failed, err = %d\n", -err);
594 +               goto out;
595 +       }
596 +
597 +       err = -ENOMEM;
598 +       header = cow_malloc(sizeof(*header));
599 +       if(header == NULL){
600 +               cow_printf("Failed to allocate COW V3 header\n");
601 +               goto out;
602 +       }
603 +       header->magic = htonl(COW_MAGIC);
604 +       header->version = htonl(COW_VERSION);
605 +
606 +       err = -EINVAL;
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);
611 +               goto out_free;
612 +       }
613 +
614 +       if(absolutize(header->backing_file, sizeof(header->backing_file), 
615 +                     backing_file))
616 +               goto out_free;
617 +
618 +       err = os_file_modtime(header->backing_file, &modtime);
619 +       if(err < 0){
620 +               cow_printf("Backing file '%s' mtime request failed, "
621 +                          "err = %d\n", header->backing_file, -err);
622 +               goto out_free;
623 +       }
624 +
625 +       err = cow_file_size(header->backing_file, size);
626 +       if(err < 0){
627 +               cow_printf("Couldn't get size of backing file '%s', "
628 +                          "err = %d\n", header->backing_file, -err);
629 +               goto out_free;
630 +       }
631 +
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;
637 +
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);
642 +               goto out_free;
643 +       }
644 +       err = 0;
645 + out_free:
646 +       cow_free(header);
647 + out:
648 +       return(err);
649 +}
650 +
651 +int file_reader(__u64 offset, char *buf, int len, void *arg)
652 +{
653 +       int fd = *((int *) arg);
654 +
655 +       return(pread(fd, buf, len, offset));
656 +}
657 +
658 +/* XXX Need to sanity-check the values read from the header */
659 +
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)
665 +{
666 +       union cow_header *header;
667 +       char *file;
668 +       int err, n;
669 +       unsigned long version, magic;
670 +
671 +       header = cow_malloc(sizeof(*header));
672 +       if(header == NULL){
673 +               cow_printf("read_cow_header - Failed to allocate header\n");
674 +               return(-ENOMEM);
675 +       }
676 +       err = -EINVAL;
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");
680 +               goto out;
681 +       }
682 +
683 +       magic = header->v1.magic;
684 +       if(magic == COW_MAGIC) {
685 +               version = header->v1.version;
686 +       }
687 +       else if(magic == ntohl(COW_MAGIC)){
688 +               version = ntohl(header->v1.version);
689 +       }
690 +       /* No error printed because the non-COW case comes through here */
691 +       else goto out;
692 +
693 +       *version_out = version;
694 +
695 +       if(version == 1){
696 +               if(n < sizeof(header->v1)){
697 +                       cow_printf("read_cow_header - failed to read V1 "
698 +                                  "header\n");
699 +                       goto out;
700 +               }
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;
707 +       }
708 +       else if(version == 2){
709 +               if(n < sizeof(header->v2)){
710 +                       cow_printf("read_cow_header - failed to read V2 "
711 +                                  "header\n");
712 +                       goto out;
713 +               }
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;
720 +       }
721 +       else if(version == 3){
722 +               if(n < sizeof(header->v3)){
723 +                       cow_printf("read_cow_header - failed to read V2 "
724 +                                  "header\n");
725 +                       goto out;
726 +               }
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;
733 +       }
734 +       else {
735 +               cow_printf("read_cow_header - invalid COW version\n");
736 +               goto out;               
737 +       }
738 +       err = -ENOMEM;
739 +       *backing_file_out = cow_strdup(file);
740 +       if(*backing_file_out == NULL){
741 +               cow_printf("read_cow_header - failed to allocate backing "
742 +                          "file\n");
743 +               goto out;
744 +       }
745 +       err = 0;
746 + out:
747 +       cow_free(header);
748 +       return(err);
749 +}
750 +
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)
754 +{
755 +       __u64 size, offset;
756 +       char zero = 0;
757 +       int err;
758 +
759 +       err = write_cow_header(cow_file, fd, backing_file, sectorsize, 
760 +                              alignment, &size);
761 +       if(err) 
762 +               goto out;
763 +       
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);
767 +
768 +       offset = *data_offset_out + size - sizeof(zero);
769 +       err = cow_seek_file(fd, offset);
770 +       if(err < 0){
771 +               cow_printf("cow bitmap lseek failed : err = %d\n", -err);
772 +               goto out;
773 +       }
774 +
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 
778 +        */
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);
783 +               err = -EINVAL;
784 +               goto out;
785 +       }
786 +
787 +       return(0);
788 +
789 + out:
790 +       return(err);
791 +}
792 +
793 +/*
794 + * ---------------------------------------------------------------------------
795 + * Local variables:
796 + * c-file-style: "linux"
797 + * End:
798 + */
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
803 @@ -8,6 +8,7 @@
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>
809  #include <asm/irq.h>
810  #include "chan_kern.h"
811 @@ -16,6 +17,7 @@
812  #include "irq_user.h"
813  #include "sigio.h"
814  #include "line.h"
815 +#include "os.h"
816  
817  static void *not_configged_init(char *str, int device, struct chan_opts *opts)
818  {
819 @@ -86,6 +88,52 @@
820         .winch          = 0,
821  };
822  
823 +void generic_close(int fd, void *unused)
824 +{
825 +       os_close_file(fd);
826 +}
827 +
828 +int generic_read(int fd, char *c_out, void *unused)
829 +{
830 +       int n;
831 +
832 +       n = os_read_file(fd, c_out, sizeof(*c_out));
833 +
834 +       if(n == -EAGAIN)
835 +               return(0);
836 +       else if(n == 0)
837 +               return(-EIO);
838 +       return(n);
839 +}
840 +
841 +int generic_write(int fd, const char *buf, int n, void *unused)
842 +{
843 +       return(os_write_file(fd, buf, n));
844 +}
845 +
846 +int generic_window_size(int fd, void *unused, unsigned short *rows_out,
847 +                       unsigned short *cols_out)
848 +{
849 +       int rows, cols;
850 +       int ret;
851 +
852 +       ret = os_window_size(fd, &rows, &cols);
853 +       if(ret < 0)
854 +               return(ret);
855 +
856 +       ret = ((*rows_out != rows) || (*cols_out != cols));
857 +
858 +       *rows_out = rows;
859 +       *cols_out = cols;
860 +
861 +       return(ret);
862 +}
863 +
864 +void generic_free(void *data)
865 +{
866 +       kfree(data);
867 +}
868 +
869  static void tty_receive_char(struct tty_struct *tty, char ch)
870  {
871         if(tty == NULL) return;
872 @@ -265,6 +313,11 @@
873  {
874         int n = 0;
875  
876 +       if(chan == NULL){
877 +               CONFIG_CHUNK(str, size, n, "none", 1);
878 +               return(n);
879 +       }
880 +
881         CONFIG_CHUNK(str, size, n, chan->ops->type, 0);
882  
883         if(chan->dev == NULL){
884 @@ -420,7 +473,8 @@
885                 INIT_LIST_HEAD(chans);
886         }
887  
888 -       if((out = strchr(str, ',')) != NULL){
889 +       out = strchr(str, ',');
890 +       if(out != NULL){
891                 in = str;
892                 *out = '\0';
893                 out++;
894 @@ -475,12 +529,15 @@
895                                 goto out;
896                         }
897                         err = chan->ops->read(chan->fd, &c, chan->data);
898 -                       if(err > 0) tty_receive_char(tty, c);
899 +                       if(err > 0) 
900 +                               tty_receive_char(tty, c);
901                 } while(err > 0);
902 +
903                 if(err == 0) reactivate_fd(chan->fd, irq);
904                 if(err == -EIO){
905                         if(chan->primary){
906 -                               if(tty != NULL) tty_hangup(tty);
907 +                               if(tty != NULL) 
908 +                                       tty_hangup(tty);
909                                 line_disable(dev, irq);
910                                 close_chan(chans);
911                                 free_chan(chans);
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
916 @@ -0,0 +1,630 @@
917 +#define COW_MAJOR 60
918 +#define MAJOR_NR COW_MAJOR
919 +
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"
932 +#include "cow.h"
933 +#include "ubd_user.h"
934 +
935 +#define COW_SHIFT 4
936 +
937 +struct cow {
938 +       int count;
939 +       char *cow_path;
940 +       dev_t cow_dev;
941 +       struct block_device *cow_bdev;
942 +       char *backing_path;
943 +       dev_t backing_dev;
944 +       struct block_device *backing_bdev;
945 +       int sectorsize;
946 +       unsigned long *bitmap;
947 +       unsigned long bitmap_len;
948 +       int bitmap_offset;
949 +       int data_offset;
950 +       devfs_handle_t devfs;
951 +       struct semaphore sem;
952 +       struct semaphore io_sem;
953 +       atomic_t working;
954 +       spinlock_t io_lock;
955 +       struct buffer_head *bh;
956 +       struct buffer_head *bhtail;
957 +       void *end_io;
958 +};
959 +
960 +#define DEFAULT_COW { \
961 +       .count                  = 0, \
962 +       .cow_path               = NULL, \
963 +       .cow_dev                = 0, \
964 +       .backing_path           = NULL, \
965 +       .backing_dev            = 0, \
966 +        .bitmap                        = NULL, \
967 +       .bitmap_len             = 0, \
968 +       .bitmap_offset          = 0, \
969 +        .data_offset           = 0, \
970 +       .devfs                  = NULL, \
971 +       .working                = ATOMIC_INIT(0), \
972 +       .io_lock                = SPIN_LOCK_UNLOCKED, \
973 +}
974 +
975 +#define MAX_DEV (8)
976 +#define MAX_MINOR (MAX_DEV << COW_SHIFT)
977 +
978 +struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW };
979 +
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 };
983 +
984 +/* Protected by cow_lock */
985 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
986 +
987 +static struct hd_struct        cow_part[MAX_MINOR] =
988 +       { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
989 +
990 +/* Protected by io_request_lock */
991 +static request_queue_t *cow_queue;
992 +
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);
998 +
999 +static struct block_device_operations cow_blops = {
1000 +       .open           = cow_open,
1001 +       .release        = cow_release,
1002 +       .ioctl          = cow_ioctl,
1003 +       .revalidate     = cow_revalidate,
1004 +};
1005 +
1006 +/* Initialized in an initcall, and unchanged thereafter */
1007 +devfs_handle_t cow_dir_handle;
1008 +
1009 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
1010 +{ \
1011 +       .major          = maj, \
1012 +       .major_name     = name, \
1013 +       .minor_shift    = shift, \
1014 +       .max_p          = 1 << shift, \
1015 +       .part           = parts, \
1016 +       .sizes          = bsizes, \
1017 +       .nr_real        = max, \
1018 +       .real_devices   = NULL, \
1019 +       .next           = NULL, \
1020 +       .fops           = blops, \
1021 +       .de_arr         = NULL, \
1022 +       .flags          = 0 \
1023 +}
1024 +
1025 +static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED;
1026 +
1027 +static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part,
1028 +                                                COW_SHIFT, sizes, MAX_DEV, 
1029 +                                                &cow_blops);
1030 +
1031 +static int cow_add(int n)
1032 +{
1033 +       struct cow *dev = &cow_dev[n];
1034 +       char name[sizeof("nnnnnn\0")];
1035 +       int err = -ENODEV;
1036 +
1037 +       if(dev->cow_path == NULL)
1038 +               goto out;
1039 +
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);
1045 +
1046 +       init_MUTEX_LOCKED(&dev->sem);
1047 +       init_MUTEX(&dev->io_sem);
1048 +
1049 +       return(0);
1050 +
1051 + out:
1052 +       return(err);
1053 +}
1054 +
1055 +/*
1056 + * Add buffer_head to back of pending list
1057 + */
1058 +static void cow_add_bh(struct cow *cow, struct buffer_head *bh)
1059 +{
1060 +       unsigned long flags;
1061 +
1062 +       spin_lock_irqsave(&cow->io_lock, flags);
1063 +       if(cow->bhtail != NULL){
1064 +               cow->bhtail->b_reqnext = bh;
1065 +               cow->bhtail = bh;
1066 +       }
1067 +       else {
1068 +               cow->bh = bh;
1069 +               cow->bhtail = bh;
1070 +       }
1071 +       spin_unlock_irqrestore(&cow->io_lock, flags);
1072 +}
1073 +
1074 +/*
1075 +* Grab first pending buffer
1076 +*/
1077 +static struct buffer_head *cow_get_bh(struct cow *cow)
1078 +{
1079 +       struct buffer_head *bh;
1080 +
1081 +       spin_lock_irq(&cow->io_lock);
1082 +       bh = cow->bh;
1083 +       if(bh != NULL){
1084 +               if(bh == cow->bhtail)
1085 +                       cow->bhtail = NULL;
1086 +               cow->bh = bh->b_reqnext;
1087 +               bh->b_reqnext = NULL;
1088 +       }
1089 +       spin_unlock_irq(&cow->io_lock);
1090 +
1091 +       return(bh);
1092 +}
1093 +
1094 +static void cow_handle_bh(struct cow *cow, struct buffer_head *bh, 
1095 +                         struct buffer_head **cow_bh, int ncow_bh)
1096 +{
1097 +       int i;
1098 +
1099 +       if(ncow_bh > 0)
1100 +               ll_rw_block(WRITE, ncow_bh, cow_bh);
1101 +
1102 +       for(i = 0; i < ncow_bh ; i++){
1103 +               wait_on_buffer(cow_bh[i]);
1104 +               brelse(cow_bh[i]);
1105 +       }
1106 +
1107 +       ll_rw_block(WRITE, 1, &bh);
1108 +       brelse(bh);
1109 +}
1110 +
1111 +static struct buffer_head *cow_new_bh(struct cow *dev, int sector)
1112 +{
1113 +       struct buffer_head *bh;
1114 +
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])),
1118 +              dev->sectorsize);
1119 +       return(bh);
1120 +}
1121 +
1122 +/* Copied from loop.c, needed to avoid deadlocking in make_request. */
1123 +
1124 +static int cow_thread(void *data)
1125 +{
1126 +       struct cow *dev = data;
1127 +       struct buffer_head *bh;
1128 +
1129 +       daemonize();
1130 +       exit_files(current);
1131 +
1132 +       sprintf(current->comm, "cow%d", dev - cow_dev);
1133 +
1134 +       spin_lock_irq(&current->sigmask_lock);
1135 +       sigfillset(&current->blocked);
1136 +       flush_signals(current);
1137 +       spin_unlock_irq(&current->sigmask_lock);
1138 +
1139 +       atomic_inc(&dev->working);
1140 +
1141 +       current->policy = SCHED_OTHER;
1142 +       current->nice = -20;
1143 +
1144 +       current->flags |= PF_NOIO;
1145 +
1146 +       /*
1147 +        * up sem, we are running
1148 +        */
1149 +       up(&dev->sem);
1150 +
1151 +       for(;;){
1152 +               int start, len, nbh, i, update_bitmap = 0;
1153 +               struct buffer_head *cow_bh[2];
1154 +
1155 +               down_interruptible(&dev->io_sem);
1156 +               /*
1157 +                * could be upped because of tear-down, not because of
1158 +                * pending work
1159 +                */
1160 +               if(!atomic_read(&dev->working))
1161 +                       break;
1162 +
1163 +               bh = cow_get_bh(dev);
1164 +               if(bh == NULL){
1165 +                       printk(KERN_ERR "cow: missing bh\n");
1166 +                       continue;
1167 +               }
1168 +
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))
1174 +                               continue;
1175 +
1176 +                       update_bitmap = 1;
1177 +                       ubd_set_bit(start + i, (unsigned char *) dev->bitmap);
1178 +               }
1179 +
1180 +               cow_bh[0] = NULL;
1181 +               cow_bh[1] = NULL;
1182 +               nbh = 0;
1183 +               if(update_bitmap){
1184 +                       cow_bh[0] = cow_new_bh(dev, start);
1185 +                       nbh++;
1186 +                       if(start / dev->sectorsize != 
1187 +                          (start + len) / dev->sectorsize){
1188 +                               cow_bh[1] = cow_new_bh(dev, start + len);
1189 +                               nbh++;
1190 +                       }
1191 +               }
1192 +               
1193 +               bh->b_dev = dev->cow_dev;
1194 +               bh->b_blocknr += dev->data_offset / dev->sectorsize;
1195 +
1196 +               cow_handle_bh(dev, bh, cow_bh, nbh);
1197 +
1198 +               /*
1199 +                * upped both for pending work and tear-down, lo_pending
1200 +                * will hit zero then
1201 +                */
1202 +               if(atomic_dec_and_test(&dev->working))
1203 +                       break;
1204 +       }
1205 +
1206 +       up(&dev->sem);
1207 +       return(0);
1208 +}
1209 +
1210 +static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh)
1211 +{
1212 +       struct cow *dev;
1213 +       int n, minor;
1214 +
1215 +       minor = MINOR(bh->b_rdev);
1216 +       n = minor >> COW_SHIFT;
1217 +       dev = &cow_dev[n];
1218 +
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;
1223 +       }
1224 +       else if(rw == WRITE){
1225 +               bh->b_dev = dev->cow_dev;
1226 +               bh->b_blocknr += dev->data_offset / dev->sectorsize;
1227 +
1228 +               cow_add_bh(dev, bh);
1229 +               up(&dev->io_sem);
1230 +               return(0);
1231 +       }
1232 +       else {
1233 +               bh->b_rdev = dev->backing_dev;
1234 +       }
1235 +
1236 +       return(1);
1237 +}
1238 +
1239 +int cow_init(void)
1240 +{
1241 +       int i;
1242 +
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);
1246 +               return -1;
1247 +       }
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);
1252 +
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);
1257 +
1258 +       add_gendisk(&cow_gendisk);
1259 +
1260 +       for(i=0;i<MAX_DEV;i++) 
1261 +               cow_add(i);
1262 +
1263 +       return(0);
1264 +}
1265 +
1266 +__initcall(cow_init);
1267 +
1268 +static int reader(__u64 start, char *buf, int count, void *arg)
1269 +{
1270 +       dev_t dev = *((dev_t *) arg);
1271 +       struct buffer_head *bh;
1272 +       __u64 block;
1273 +       int cur, offset, left, n, blocksize = get_hardsect_size(dev);
1274 +
1275 +       if(blocksize == 0)
1276 +               panic("Zero blocksize");
1277 +
1278 +       block = start / blocksize;
1279 +       offset = start % blocksize;
1280 +       left = count;
1281 +       cur = 0;
1282 +       while(left > 0){
1283 +               n = (left > blocksize) ? blocksize : left;
1284 +
1285 +               bh = bread(dev, block, (n < 512) ? 512 : n);
1286 +               if(bh == NULL)
1287 +                       return(-EIO);
1288 +
1289 +               n -= offset;
1290 +               memcpy(&buf[cur], bh->b_data + offset, n);
1291 +               block++;
1292 +               left -= n;
1293 +               cur += n;
1294 +               offset = 0;
1295 +               brelse(bh);
1296 +       }
1297 +
1298 +       return(count);
1299 +}
1300 +
1301 +static int cow_open(struct inode *inode, struct file *filp)
1302 +{
1303 +       int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
1304 +                        unsigned long);
1305 +       mm_segment_t fs;
1306 +       struct cow *dev;
1307 +       __u64 size;
1308 +       __u32 version, align;
1309 +       time_t mtime;
1310 +       char *backing_file;
1311 +       int n, offset, err = 0;
1312 +
1313 +       n = DEVICE_NR(inode->i_rdev);
1314 +       if(n >= MAX_DEV)
1315 +               return(-ENODEV);
1316 +       dev = &cow_dev[n];
1317 +       offset = n << COW_SHIFT;
1318 +
1319 +       spin_lock(&cow_lock);
1320 +
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);
1326 +                       err = -ENODEV;
1327 +               }
1328 +
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);
1333 +                       err = -ENODEV;
1334 +               }
1335 +
1336 +               if(err) 
1337 +                       goto out;
1338 +
1339 +               dev->cow_bdev = bdget(dev->cow_dev);
1340 +               if(dev->cow_bdev == NULL){
1341 +                       printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", 
1342 +                              dev->cow_path);
1343 +                       err = -ENOMEM;
1344 +               }
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);
1349 +                       err = -ENOMEM;
1350 +               }
1351 +
1352 +               if(err) 
1353 +                       goto out;
1354 +
1355 +               err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0, 
1356 +                                BDEV_RAW);
1357 +               if(err){
1358 +                       printk("cow_open - blkdev_get of COW device failed, "
1359 +                              "error = %d\n", err);
1360 +                       goto out;
1361 +               }
1362 +               
1363 +               err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW);
1364 +               if(err){
1365 +                       printk("cow_open - blkdev_get of backing device "
1366 +                              "failed, error = %d\n", err);
1367 +                       goto out;
1368 +               }
1369 +               
1370 +               err = read_cow_header(reader, &dev->cow_dev, &version, 
1371 +                                     &backing_file, &mtime, &size,
1372 +                                     &dev->sectorsize, &align, 
1373 +                                     &dev->bitmap_offset);
1374 +               if(err){
1375 +                       printk(KERN_ERR "cow_open - read_cow_header failed, "
1376 +                              "err = %d\n", err);
1377 +                       goto out;
1378 +               }
1379 +
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){
1385 +                       err = -ENOMEM;
1386 +                       printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
1387 +                       goto out;
1388 +               }
1389 +               flush_tlb_kernel_vm();
1390 +               
1391 +               err = reader(dev->bitmap_offset, (char *) dev->bitmap, 
1392 +                            dev->bitmap_len, &dev->cow_dev);
1393 +               if(err < 0){
1394 +                       printk(KERN_ERR "Failed to read COW bitmap\n");
1395 +                       vfree(dev->bitmap);
1396 +                       goto out;
1397 +               }
1398 +
1399 +               dev_ioctl = dev->backing_bdev->bd_op->ioctl;
1400 +               fs = get_fs();
1401 +               set_fs(KERNEL_DS);
1402 +               err = (*dev_ioctl)(inode, filp, BLKGETSIZE, 
1403 +                                  (unsigned long) &sizes[offset]);
1404 +               set_fs(fs);
1405 +               if(err){
1406 +                       printk(KERN_ERR "cow_open - BLKGETSIZE failed, "
1407 +                              "error = %d\n", err);
1408 +                       goto out;
1409 +               }
1410 +
1411 +               kernel_thread(cow_thread, dev, 
1412 +                             CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
1413 +               down(&dev->sem);
1414 +       }
1415 +       dev->count++;
1416 + out:
1417 +       spin_unlock(&cow_lock);
1418 +       return(err);
1419 +}
1420 +
1421 +static int cow_release(struct inode * inode, struct file * file)
1422 +{
1423 +       struct cow *dev;
1424 +       int n, err;
1425 +
1426 +       n = DEVICE_NR(inode->i_rdev);
1427 +       if(n >= MAX_DEV)
1428 +               return(-ENODEV);
1429 +       dev = &cow_dev[n];
1430 +
1431 +       spin_lock(&cow_lock);
1432 +
1433 +       if(--dev->count > 0)
1434 +               goto out;
1435 +
1436 +       err = blkdev_put(dev->cow_bdev, BDEV_RAW);
1437 +       if(err)
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;
1442 +
1443 +       err = blkdev_put(dev->backing_bdev, BDEV_RAW);
1444 +       if(err)
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;
1449 +
1450 + out:
1451 +       spin_unlock(&cow_lock);
1452 +       return(0);
1453 +}
1454 +
1455 +static int cow_ioctl(struct inode * inode, struct file * file,
1456 +                    unsigned int cmd, unsigned long arg)
1457 +{
1458 +       struct cow *dev;
1459 +       int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
1460 +                        unsigned long);
1461 +       int n;
1462 +
1463 +       n = DEVICE_NR(inode->i_rdev);
1464 +       if(n >= MAX_DEV)
1465 +               return(-ENODEV);
1466 +       dev = &cow_dev[n];
1467 +
1468 +       dev_ioctl = dev->backing_bdev->bd_op->ioctl;
1469 +       return((*dev_ioctl)(inode, file, cmd, arg));
1470 +}
1471 +
1472 +static int cow_revalidate(kdev_t rdev)
1473 +{
1474 +       printk(KERN_ERR "Need to implement cow_revalidate\n");
1475 +       return(0);
1476 +}
1477 +
1478 +static int parse_unit(char **ptr)
1479 +{
1480 +       char *str = *ptr, *end;
1481 +       int n = -1;
1482 +
1483 +       if(isdigit(*str)) {
1484 +               n = simple_strtoul(str, &end, 0);
1485 +               if(end == str)
1486 +                       return(-1);
1487 +               *ptr = end;
1488 +       }
1489 +       else if (('a' <= *str) && (*str <= 'h')) {
1490 +               n = *str - 'a';
1491 +               str++;
1492 +               *ptr = str;
1493 +       }
1494 +       return(n);
1495 +}
1496 +
1497 +static int cow_setup(char *str)
1498 +{
1499 +       struct cow *dev;
1500 +       char *cow_name, *backing_name;
1501 +       int unit;
1502 +
1503 +       unit = parse_unit(&str);
1504 +       if(unit < 0){
1505 +               printk(KERN_ERR "cow_setup - Couldn't parse unit number\n");
1506 +               return(1);
1507 +       }
1508 +
1509 +       if(*str != '='){
1510 +               printk(KERN_ERR "cow_setup - Missing '=' after unit "
1511 +                      "number\n");
1512 +               return(1);
1513 +       }
1514 +       str++;
1515 +
1516 +       cow_name = str;
1517 +       backing_name = strchr(str, ',');
1518 +       if(backing_name == NULL){
1519 +               printk(KERN_ERR "cow_setup - missing backing device name\n");
1520 +               return(0);
1521 +       }
1522 +       *backing_name = '\0';
1523 +       backing_name++;
1524 +
1525 +       spin_lock(&cow_lock);
1526 +
1527 +       dev = &cow_dev[unit];
1528 +       dev->cow_path = cow_name;
1529 +       dev->backing_path = backing_name;
1530 +       
1531 +       spin_unlock(&cow_lock);
1532 +       return(0);
1533 +}
1534 +
1535 +__setup("cow", cow_setup);
1536 +
1537 +/*
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
1541 + * of the file.
1542 + * ---------------------------------------------------------------------------
1543 + * Local variables:
1544 + * c-file-style: "linux"
1545 + * End:
1546 + */
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
1551 @@ -8,6 +8,7 @@
1552  #include <stdlib.h>
1553  #include <string.h>
1554  #include <signal.h>
1555 +#include <errno.h>
1556  #include <sys/resource.h>
1557  #include <sys/mman.h>
1558  #include <sys/user.h>
1559 @@ -123,12 +124,14 @@
1560  
1561         set_stklim();
1562  
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");
1567                 exit(1);
1568         }
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");
1574                         exit(1);
1575                 }
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
1580 @@ -8,15 +8,20 @@
1581  #include <string.h>
1582  #include "user_util.h"
1583  #include "uml_uaccess.h"
1584 +#include "task.h"
1585 +#include "kern_util.h"
1586  
1587  int __do_copy_from_user(void *to, const void *from, int n,
1588                         void **fault_addr, void **fault_catcher)
1589  {
1590 +       struct tt_regs save = TASK_REGS(get_current())->tt;
1591         unsigned long fault;
1592         int faulted;
1593  
1594         fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
1595                                __do_copy, &faulted);
1596 +       TASK_REGS(get_current())->tt = save;
1597 +
1598         if(!faulted) return(0);
1599         else return(n - (fault - (unsigned long) from));
1600  }
1601 @@ -29,11 +34,14 @@
1602  int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
1603                            void **fault_addr, void **fault_catcher)
1604  {
1605 +       struct tt_regs save = TASK_REGS(get_current())->tt;
1606         unsigned long fault;
1607         int faulted;
1608  
1609         fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
1610                                __do_strncpy, &faulted);
1611 +       TASK_REGS(get_current())->tt = save;
1612 +
1613         if(!faulted) return(strlen(dst));
1614         else return(-1);
1615  }
1616 @@ -46,11 +54,14 @@
1617  int __do_clear_user(void *mem, unsigned long len,
1618                     void **fault_addr, void **fault_catcher)
1619  {
1620 +       struct tt_regs save = TASK_REGS(get_current())->tt;
1621         unsigned long fault;
1622         int faulted;
1623  
1624         fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
1625                                __do_clear, &faulted);
1626 +       TASK_REGS(get_current())->tt = save;
1627 +
1628         if(!faulted) return(0);
1629         else return(len - (fault - (unsigned long) mem));
1630  }
1631 @@ -58,19 +69,20 @@
1632  int __do_strnlen_user(const char *str, unsigned long n,
1633                       void **fault_addr, void **fault_catcher)
1634  {
1635 +       struct tt_regs save = TASK_REGS(get_current())->tt;
1636         int ret;
1637         unsigned long *faddrp = (unsigned long *)fault_addr;
1638         jmp_buf jbuf;
1639  
1640         *fault_catcher = &jbuf;
1641 -       if(setjmp(jbuf) == 0){
1642 +       if(sigsetjmp(jbuf, 1) == 0)
1643                 ret = strlen(str) + 1;
1644 -       } 
1645 -       else {
1646 -               ret = *faddrp - (unsigned long) str;
1647 -       }
1648 +       else ret = *faddrp - (unsigned long) str;
1649 +
1650         *fault_addr = NULL;
1651         *fault_catcher = NULL;
1652 +
1653 +       TASK_REGS(get_current())->tt = save;
1654         return ret;
1655  }
1656  
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
1661 @@ -1,5 +1,5 @@
1662  /* 
1663 - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
1664 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
1665   * Licensed under the GPL
1666   */
1667  
1668 @@ -36,32 +36,34 @@
1669  
1670  long sys_fork(void)
1671  {
1672 -       struct task_struct *p;
1673 +       long ret;
1674  
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);
1680 +       return(ret);
1681  }
1682  
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)
1686  {
1687 -       struct task_struct *p;
1688 +       long ret;
1689  
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);
1695 +       return(ret);
1696  }
1697  
1698  long sys_vfork(void)
1699  {
1700 -       struct task_struct *p;
1701 +       long ret;
1702  
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, 
1706 +                     NULL);
1707         current->thread.forking = 0;
1708 -       return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
1709 +       return(ret);
1710  }
1711  
1712  /* common code for old and new mmaps */
1713 @@ -136,43 +138,12 @@
1714  
1715          error = do_pipe(fd);
1716          if (!error) {
1717 -                if (copy_to_user(fildes, fd, 2*sizeof(int)))
1718 +               if (copy_to_user(fildes, fd, sizeof(fd)))
1719                          error = -EFAULT;
1720          }
1721          return error;
1722  }
1723  
1724 -int sys_sigaction(int sig, const struct old_sigaction *act,
1725 -                        struct old_sigaction *oact)
1726 -{
1727 -       struct k_sigaction new_ka, old_ka;
1728 -       int ret;
1729 -
1730 -       if (act) {
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))
1735 -                       return -EFAULT;
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);
1739 -       }
1740 -
1741 -       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
1742 -
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))
1747 -                       return -EFAULT;
1748 -               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
1749 -               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
1750 -       }
1751 -
1752 -       return ret;
1753 -}
1754 -
1755  /*
1756   * sys_ipc() is the de-multiplexer for the SysV IPC calls..
1757   *
1758 @@ -254,7 +225,7 @@
1759                 return sys_shmctl (first, second,
1760                                    (struct shmid_ds *) ptr);
1761         default:
1762 -               return -EINVAL;
1763 +               return -ENOSYS;
1764         }
1765  }
1766  
1767 @@ -303,11 +274,6 @@
1768         return error;
1769  }
1770  
1771 -int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
1772 -{
1773 -       return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
1774 -}
1775 -
1776  long execute_syscall(void *r)
1777  {
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
1783 @@ -1,3 +1,4 @@
1784 +#include <stdio.h>
1785  #include <asm/ptrace.h>
1786  #include <asm/user.h>
1787  
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
1792 @@ -5,20 +5,24 @@
1793  
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 \
1796 -       sys-$(SUBARCH)/
1797 +       uaccess.o sys-$(SUBARCH)/
1798 +
1799 +host-progs     := util/mk_ptregs
1800 +clean-files    := include/skas_ptregs.h
1801  
1802  USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
1803  USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
1804  
1805 -include/skas_ptregs.h : util/mk_ptregs
1806 -       util/mk_ptregs > $@
1807 -
1808 -util/mk_ptregs :
1809 -       $(MAKE) -C util
1810 +$(TOPDIR)/arch/um/include/skas_ptregs.h : $(src)/util/mk_ptregs
1811 +       @echo -n '  Generating $@'
1812 +       @$< > $@.tmp
1813 +       @if [ -r $@ ] && cmp -s $@ $@.tmp; then \
1814 +               echo ' (unchanged)'; \
1815 +               rm -f $@.tmp; \
1816 +       else \
1817 +               echo ' (updated)'; \
1818 +               mv -f $@.tmp $@; \
1819 +       fi
1820  
1821  $(USER_OBJS) : %.o: %.c
1822         $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
1823 -
1824 -clean :
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
1831 @@ -1,15 +1,6 @@
1832  #ifndef __UM_IRQ_H
1833  #define __UM_IRQ_H
1834  
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.
1837 - */
1838 -struct task_struct;
1839 -
1840 -#include "asm/ptrace.h"
1841 -
1842 -#undef NR_IRQS
1843 -
1844  #define TIMER_IRQ              0
1845  #define UMN_IRQ                        1
1846  #define CONSOLE_IRQ            2
1847 @@ -28,13 +19,4 @@
1848  #define LAST_IRQ XTERM_IRQ
1849  #define NR_IRQS (LAST_IRQ + 1)
1850  
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,
1854 -                         void *dev_id);
1855 -
1856 -struct irqaction;
1857 -struct pt_regs;
1858 -int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
1859 -
1860  #endif
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
1865 @@ -6,8 +6,8 @@
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"
1875 @@ -16,38 +16,55 @@
1876  #include "user_util.h"
1877  #include "kern_util.h"
1878  #include "os.h"
1879 +#include "irq_kern.h"
1880  
1881  #define LINE_BUFSIZE 4096
1882  
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)
1885  {
1886         struct line *dev = data;
1887  
1888         if(dev->count > 0) 
1889                 chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq, 
1890                                dev);
1891 +       return IRQ_HANDLED;
1892  }
1893  
1894 -void line_timer_cb(void *arg)
1895 +static void line_timer_cb(void *arg)
1896  {
1897         struct line *dev = arg;
1898  
1899         line_interrupt(dev->driver->read_irq, dev, NULL);
1900  }
1901  
1902 -static void buffer_data(struct line *line, const char *buf, int len)
1903 +static int write_room(struct line *dev)
1904  {
1905 -       int end;
1906 +       int n;
1907 +
1908 +       if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
1909 +
1910 +       n = dev->head - dev->tail;
1911 +       if(n <= 0) n = LINE_BUFSIZE + n;
1912 +       return(n - 1);
1913 +}
1914 +
1915 +static int buffer_data(struct line *line, const char *buf, int len)
1916 +{
1917 +       int end, room;
1918  
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");
1923 -                       return;
1924 +                       return(0);
1925                 }
1926                 line->head = line->buffer;
1927                 line->tail = line->buffer;
1928         }
1929 +
1930 +       room = write_room(line);
1931 +       len = (len > room) ? room : len;
1932 +
1933         end = line->buffer + LINE_BUFSIZE - line->tail;
1934         if(len < end){
1935                 memcpy(line->tail, buf, len);
1936 @@ -60,6 +77,8 @@
1937                 memcpy(line->buffer, buf, len);
1938                 line->tail = line->buffer + len;
1939         }
1940 +
1941 +       return(len);
1942  }
1943  
1944  static int flush_buffer(struct line *line)
1945 @@ -95,7 +114,7 @@
1946         struct line *line;
1947         char *new;
1948         unsigned long flags;
1949 -       int n, err, i;
1950 +       int n, err, i, ret = 0;
1951  
1952         if(tty->stopped) return 0;
1953  
1954 @@ -104,9 +123,13 @@
1955                 if(new == NULL)
1956                         return(0);
1957                 n = copy_from_user(new, buf, len);
1958 -               if(n == len)
1959 -                       return(-EFAULT);
1960                 buf = new;
1961 +               if(n == len){
1962 +                       len = -EFAULT;
1963 +                       goto out_free;
1964 +               }
1965 +
1966 +               len -= n;
1967         }
1968  
1969         i = tty->index;
1970 @@ -115,41 +138,50 @@
1971         down(&line->sem);
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);
1978                 if(err <= 0)
1979 -                       goto out;
1980 +                       goto out_up;
1981         }
1982         else {
1983                 n = write_chan(&line->chan_list, buf, len, 
1984                                line->driver->write_irq);
1985                 if(n < 0){
1986 -                       len = n;
1987 -                       goto out;
1988 +                       ret = n;
1989 +                       goto out_up;
1990                 }
1991 -               if(n < len)
1992 -                       buffer_data(line, buf + n, len - n);
1993 +
1994 +               len -= n;
1995 +               ret += n;
1996 +               if(len > 0)
1997 +                       ret += buffer_data(line, buf + n, len);
1998         }
1999 - out:
2000 + out_up:
2001         up(&line->sem);
2002 -       return(len);
2003 + out_free:
2004 +       if(from_user)
2005 +               kfree(buf);
2006 +       return(ret);
2007  }
2008  
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)
2012  {
2013         struct line *dev = data;
2014         struct tty_struct *tty = dev->tty;
2015         int err;
2016  
2017         err = flush_buffer(dev);
2018 -       if(err == 0) return;
2019 +       if(err == 0) 
2020 +               return(IRQ_NONE);
2021         else if(err < 0){
2022                 dev->head = dev->buffer;
2023                 dev->tail = dev->buffer;
2024         }
2025  
2026 -       if(tty == NULL) return;
2027 +       if(tty == NULL) 
2028 +               return(IRQ_NONE);
2029  
2030         if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
2031            (tty->ldisc.write_wakeup != NULL))
2032 @@ -161,21 +193,9 @@
2033          * writes.
2034          */
2035  
2036 -       if (waitqueue_active(&tty->write_wait))
2037 +       if(waitqueue_active(&tty->write_wait))
2038                 wake_up_interruptible(&tty->write_wait);
2039 -
2040 -}
2041 -
2042 -int line_write_room(struct tty_struct *tty)
2043 -{
2044 -       struct line *dev = tty->driver_data;
2045 -       int n;
2046 -
2047 -       if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
2048 -
2049 -       n = dev->head - dev->tail;
2050 -       if(n <= 0) n = LINE_BUFSIZE + n;
2051 -       return(n - 1);
2052 +       return(IRQ_HANDLED);
2053  }
2054  
2055  int line_setup_irq(int fd, int input, int output, void *data)
2056 @@ -305,7 +325,7 @@
2057                 if(*end != '='){
2058                         printk(KERN_ERR "line_setup failed to parse \"%s\"\n", 
2059                                init);
2060 -                       return(1);
2061 +                       return(0);
2062                 }
2063                 init = end;
2064         }
2065 @@ -313,12 +333,12 @@
2066         if((n >= 0) && (n >= num)){
2067                 printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
2068                        n, num);
2069 -               return(1);
2070 +               return(0);
2071         }
2072         else if(n >= 0){
2073                 if(lines[n].count > 0){
2074                         printk("line_setup - device %d is open\n", n);
2075 -                       return(1);
2076 +                       return(0);
2077                 }
2078                 if(lines[n].init_pri <= INIT_ONE){
2079                         lines[n].init_pri = INIT_ONE;
2080 @@ -332,7 +352,7 @@
2081         else if(!all_allowed){
2082                 printk("line_setup - can't configure all devices from "
2083                        "mconsole\n");
2084 -               return(1);
2085 +               return(0);
2086         }
2087         else {
2088                 for(i = 0; i < num; i++){
2089 @@ -346,7 +366,7 @@
2090                         }
2091                 }
2092         }
2093 -       return(0);
2094 +       return(1);
2095  }
2096  
2097  int line_config(struct line *lines, int num, char *str)
2098 @@ -357,7 +377,7 @@
2099                 printk("line_config - uml_strdup failed\n");
2100                 return(-ENOMEM);
2101         }
2102 -       return(line_setup(lines, num, new, 0));
2103 +       return(!line_setup(lines, num, new, 0));
2104  }
2105  
2106  int line_get_config(char *name, struct line *lines, int num, char *str, 
2107 @@ -369,7 +389,7 @@
2108  
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";
2113                 return(0);
2114         }
2115  
2116 @@ -379,15 +399,15 @@
2117         }
2118  
2119         line = &lines[dev];
2120 +
2121         down(&line->sem);
2122 -       
2123         if(!line->valid)
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);
2128 -
2129         up(&line->sem);
2130 +
2131         return(n);
2132  }
2133  
2134 @@ -396,7 +416,14 @@
2135         char config[sizeof("conxxxx=none\0")];
2136  
2137         sprintf(config, "%s=none", str);
2138 -       return(line_setup(lines, num, config, 0));
2139 +       return(!line_setup(lines, num, config, 0));
2140 +}
2141 +
2142 +int line_write_room(struct tty_struct *tty)
2143 +{
2144 +       struct line *dev = tty->driver_data;
2145 +
2146 +       return(write_room(dev));
2147  }
2148  
2149  struct tty_driver *line_register_devfs(struct lines *set,
2150 @@ -412,7 +439,8 @@
2151                 return NULL;
2152  
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;
2160 @@ -432,7 +460,7 @@
2161  
2162         for(i = 0; i < nlines; i++){
2163                 if(!lines[i].valid) 
2164 -                       tty_unregister_devfs(driver, i);
2165 +                       tty_unregister_device(driver, i);
2166         }
2167  
2168         mconsole_register_dev(&line_driver->mc);
2169 @@ -465,24 +493,25 @@
2170         struct line *line;
2171  };
2172  
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)
2175  {
2176         struct winch *winch = data;
2177         struct tty_struct *tty;
2178         int err;
2179         char c;
2180  
2181 -       err = generic_read(winch->fd, &c, NULL);
2182 -       if(err < 0){
2183 -               if(err != -EAGAIN){
2184 -                       printk("winch_interrupt : read failed, errno = %d\n", 
2185 -                              -err);
2186 -                       printk("fd %d is losing SIGWINCH support\n", 
2187 -                              winch->tty_fd);
2188 -                       free_irq(irq, data);
2189 -                       return;
2190 +       if(winch->fd != -1){
2191 +               err = generic_read(winch->fd, &c, NULL);
2192 +               if(err < 0){
2193 +                       if(err != -EAGAIN){
2194 +                               printk("winch_interrupt : read failed, "
2195 +                                      "errno = %d\n", -err);
2196 +                               printk("fd %d is losing SIGWINCH support\n", 
2197 +                                      winch->tty_fd);
2198 +                               return(IRQ_HANDLED);
2199 +                       }
2200 +                       goto out;
2201                 }
2202 -               goto out;
2203         }
2204         tty = winch->line->tty;
2205         if(tty != NULL){
2206 @@ -492,7 +521,9 @@
2207                 kill_pg(tty->pgrp, SIGWINCH, 1);
2208         }
2209   out:
2210 -       reactivate_fd(winch->fd, WINCH_IRQ);
2211 +       if(winch->fd != -1)
2212 +               reactivate_fd(winch->fd, WINCH_IRQ);
2213 +       return(IRQ_HANDLED);
2214  }
2215  
2216  DECLARE_MUTEX(winch_handler_sem);
2217 @@ -529,7 +560,10 @@
2218  
2219         list_for_each(ele, &winch_handlers){
2220                 winch = list_entry(ele, struct winch, list);
2221 -               close(winch->fd);
2222 +               if(winch->fd != -1){
2223 +                       deactivate_fd(winch->fd, WINCH_IRQ);
2224 +                       os_close_file(winch->fd);
2225 +               }
2226                 if(winch->pid != -1) 
2227                         os_kill_process(winch->pid, 1);
2228         }
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
2233 @@ -62,7 +62,7 @@
2234         reading = 0;
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);
2239  
2240         reading = 1;
2241         if((from->state == TASK_ZOMBIE) || (from->state == TASK_DEAD))
2242 @@ -104,48 +104,72 @@
2243  
2244  void release_thread_tt(struct task_struct *task)
2245  {
2246 -       os_kill_process(task->thread.mode.tt.extern_pid, 0);
2247 +       int pid = task->thread.mode.tt.extern_pid;
2248 +
2249 +       if(os_getpid() != pid)
2250 +               os_kill_process(pid, 0);
2251  }
2252  
2253  void exit_thread_tt(void)
2254  {
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]);
2259  }
2260  
2261  void schedule_tail(task_t *prev);
2262  
2263  static void new_thread_handler(int sig)
2264  {
2265 +       unsigned long disable;
2266         int (*fn)(void *);
2267         void *arg;
2268  
2269         fn = current->thread.request.u.thread.proc;
2270         arg = current->thread.request.u.thread.arg;
2271 +
2272         UPT_SC(&current->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(&current->thread.regs.regs)) &= ~disable;
2276 +
2277         suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
2278  
2279 -       block_signals();
2280 +       force_flush_all();
2281 +       if(current->thread.prev_sched != NULL)
2282 +               schedule_tail(current->thread.prev_sched);
2283 +       current->thread.prev_sched = NULL;
2284 +
2285         init_new_thread_signals(1);
2286 -#ifdef CONFIG_SMP
2287 -       schedule_tail(current->thread.prev_sched);
2288 -#endif
2289         enable_timer();
2290         free_page(current->thread.temp_stack);
2291         set_cmdline("(kernel thread)");
2292 -       force_flush_all();
2293  
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, &current->thread.exec_buf))
2301                 do_exit(0);
2302  }
2303  
2304  static int new_thread_proc(void *stack)
2305  {
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 
2318 +        * delivered.
2319 +        */
2320 +
2321 +       local_irq_disable();
2322         init_new_thread_stack(stack, new_thread_handler);
2323         os_usr1_process(os_getpid());
2324         return(0);
2325 @@ -156,7 +180,7 @@
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.
2332   */
2333  
2334 @@ -165,35 +189,32 @@
2335         UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
2336         suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
2337  
2338 -#ifdef CONFIG_SMP      
2339 -       schedule_tail(NULL);
2340 -#endif
2341 +       force_flush_all();
2342 +       if(current->thread.prev_sched != NULL)
2343 +               schedule_tail(current->thread.prev_sched);
2344 +       current->thread.prev_sched = NULL;
2345 +
2346         enable_timer();
2347         change_sig(SIGVTALRM, 1);
2348         local_irq_enable();
2349 -       force_flush_all();
2350         if(current->mm != current->parent->mm)
2351                 protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 
2352                                1, 0, 1);
2353 -       task_protections((unsigned long) current->thread_info);
2354 -
2355 -       current->thread.prev_sched = NULL;
2356 +       task_protections((unsigned long) current_thread);
2357  
2358         free_page(current->thread.temp_stack);
2359 +       local_irq_disable();
2360         change_sig(SIGUSR1, 0);
2361         set_user_mode(current);
2362  }
2363  
2364 -static int sigusr1 = SIGUSR1;
2365 -
2366  int fork_tramp(void *stack)
2367  {
2368 -       int sig = sigusr1;
2369 -
2370         local_irq_disable();
2371 +       arch_init_thread();
2372         init_new_thread_stack(stack, finish_fork_handler);
2373  
2374 -       kill(os_getpid(), sig);
2375 +       os_usr1_process(os_getpid());
2376         return(0);
2377  }
2378  
2379 @@ -213,8 +234,8 @@
2380         }
2381  
2382         err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1);
2383 -       if(err){
2384 -               printk("copy_thread : pipe failed, errno = %d\n", -err);
2385 +       if(err < 0){
2386 +               printk("copy_thread : pipe failed, err = %d\n", -err);
2387                 return(err);
2388         }
2389  
2390 @@ -377,8 +398,8 @@
2391  
2392         pages = (1 << CONFIG_KERNEL_STACK_ORDER);
2393  
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);
2400  
2401 @@ -454,8 +475,9 @@
2402  
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", 
2406 -                     err);
2407 +       if(err) 
2408 +               panic("Can't create switch pipe for init_task, errno = %d", 
2409 +                     -err);
2410  }
2411  
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
2417 @@ -6,20 +6,6 @@
2418  #ifndef __2_5_COMPAT_H__
2419  #define __2_5_COMPAT_H__
2420  
2421 -#include "linux/version.h"
2422 -
2423 -#define INIT_CONSOLE(dev_name, write_proc, device_proc, setup_proc, f) { \
2424 -       name :          dev_name, \
2425 -       write :         write_proc, \
2426 -       read :          NULL, \
2427 -       device :        device_proc, \
2428 -       setup :         setup_proc, \
2429 -       flags :         f, \
2430 -       index :         -1, \
2431 -       cflag :         0, \
2432 -       next :          NULL \
2433 -}
2434 -
2435  #define INIT_HARDSECT(arr, maj, sizes)
2436  
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
2442 @@ -0,0 +1,26 @@
2443 +# 
2444 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
2445 +# Licensed under the GPL
2446 +#
2447 +
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.
2451 +
2452 +STAT64_INO_FIELD := $(shell grep -q __st_ino /usr/include/bits/stat.h && \
2453 +                               echo __)st_ino
2454 +
2455 +hostfs-objs := hostfs_kern.o hostfs_user.o
2456 +
2457 +obj-y = 
2458 +obj-$(CONFIG_HOSTFS) += hostfs.o
2459 +
2460 +SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
2461 +
2462 +USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(SINGLE_OBJS))
2463 +USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
2464 +
2465 +USER_CFLAGS += -DSTAT64_INO_FIELD=$(STAT64_INO_FIELD)
2466 +
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
2473 @@ -22,9 +22,11 @@
2474         else from = -1;
2475  
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);
2484 +       }
2485  
2486         return(0);
2487  }
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
2492 @@ -12,10 +12,9 @@
2493  #include "kern_util.h"
2494  #include "user.h"
2495  #include "sigcontext.h"
2496 +#include "mode.h"
2497  
2498 -extern int userspace_pid;
2499 -
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)
2502  {
2503         struct sigcontext sc, *from = from_ptr;
2504         unsigned long fpregs[FP_FRAME_SIZE];
2505 @@ -41,13 +40,12 @@
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;
2514  
2515 -       err = ptrace(PTRACE_SETFPREGS, userspace_pid, 0, fpregs);
2516 +       err = ptrace(PTRACE_SETFPREGS, pid, 0, fpregs);
2517         if(err < 0){
2518                 printk("copy_sc_to_user - PTRACE_SETFPREGS failed, "
2519                        "errno = %d\n", errno);
2520 @@ -57,8 +55,9 @@
2521         return(0);
2522  }
2523  
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, 
2528 +                        int fault_type)
2529  {
2530         struct sigcontext sc, *to = to_ptr;
2531         struct _fpstate *to_fp;
2532 @@ -86,7 +85,7 @@
2533         sc.err = TO_SC_ERR(fault_type);
2534         sc.trapno = regs->skas.trap_type;
2535  
2536 -       err = ptrace(PTRACE_GETFPREGS, userspace_pid, 0, fpregs);
2537 +       err = ptrace(PTRACE_GETFPREGS, pid, 0, fpregs);
2538         if(err < 0){
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
2545 @@ -4,6 +4,7 @@
2546   */
2547  
2548  #include <stdlib.h>
2549 +#include <unistd.h>
2550  #include <errno.h>
2551  #include <signal.h>
2552  #include <setjmp.h>
2553 @@ -24,6 +25,19 @@
2554  #include "os.h"
2555  #include "proc_mm.h"
2556  #include "skas_ptrace.h"
2557 +#include "chan_user.h"
2558 +#include "signal_user.h"
2559 +
2560 +int is_skas_winch(int pid, int fd, void *data)
2561 +{
2562 +       if(pid != getpid())
2563 +               return(0);
2564 +
2565 +       register_winch_irq(-1, fd, -1, data);
2566 +       return(1);
2567 +}
2568 +
2569 +/* These are set once at boot time and not changed thereafter */
2570  
2571  unsigned long exec_regs[FRAME_SIZE];
2572  unsigned long exec_fp_regs[HOST_FP_SIZE];
2573 @@ -43,37 +57,39 @@
2574         segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL);
2575  }
2576  
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)
2580  {
2581         int err, syscall_nr, status;
2582  
2583         syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
2584 +       UPT_SYSCALL_NR(regs) = syscall_nr;
2585         if(syscall_nr < 1){
2586                 relay_signal(SIGTRAP, regs);
2587                 return;
2588         }
2589 -       UPT_SYSCALL_NR(regs) = syscall_nr;
2590  
2591 -       err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
2592 -       if(err < 0)
2593 -               panic("handle_trap - nullifying syscall failed errno = %d\n", 
2594 -                     errno);
2595 +       if (!local_using_sysemu)
2596 +       {
2597 +               err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
2598 +               if(err < 0)
2599 +                       panic("handle_trap - nullifying syscall failed errno = %d\n",
2600 +                             errno);
2601  
2602 -       err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
2603 -       if(err < 0)
2604 -               panic("handle_trap - continuing to end of syscall failed, "
2605 -                     "errno = %d\n", errno);
2606 -
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);
2612 +               if(err < 0)
2613 +                       panic("handle_trap - continuing to end of syscall failed, "
2614 +                             "errno = %d\n", errno);
2615 +
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);
2620 +       }
2621  
2622         handle_syscall(regs);
2623  }
2624  
2625 -int userspace_pid;
2626 -
2627  static int userspace_tramp(void *arg)
2628  {
2629         init_new_thread_signals(0);
2630 @@ -83,7 +99,11 @@
2631         return(0);
2632  }
2633  
2634 -void start_userspace(void)
2635 +/* Each element set once, and only accessed by a single processor anyway */
2636 +#define NR_CPUS 1
2637 +int userspace_pid[NR_CPUS];
2638 +
2639 +void start_userspace(int cpu)
2640  {
2641         void *stack;
2642         unsigned long sp;
2643 @@ -101,7 +121,7 @@
2644                 panic("start_userspace : clone failed, errno = %d", errno);
2645  
2646         do {
2647 -               n = waitpid(pid, &status, WUNTRACED);
2648 +               CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
2649                 if(n < 0)
2650                         panic("start_userspace : wait failed, errno = %d", 
2651                               errno);
2652 @@ -114,21 +134,27 @@
2653         if(munmap(stack, PAGE_SIZE) < 0)
2654                 panic("start_userspace : munmap failed, errno = %d\n", errno);
2655  
2656 -       userspace_pid = pid;
2657 +       userspace_pid[cpu] = pid;
2658  }
2659  
2660  void userspace(union uml_pt_regs *regs)
2661  {
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.*/
2665  
2666         restore_registers(regs);
2667                 
2668 -       err = ptrace(PTRACE_SYSCALL, userspace_pid, 0, 0);
2669 +       local_using_sysemu = get_using_sysemu();
2670 +
2671 +       if (local_using_sysemu)
2672 +               err = ptrace(PTRACE_SYSEMU, pid, 0, 0);
2673 +       else
2674 +               err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
2675         if(err)
2676                 panic("userspace - PTRACE_SYSCALL failed, errno = %d\n", 
2677                        errno);
2678         while(1){
2679 -               err = waitpid(userspace_pid, &status, WUNTRACED);
2680 +               CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
2681                 if(err < 0)
2682                         panic("userspace - waitpid failed, errno = %d\n", 
2683                               errno);
2684 @@ -139,16 +165,17 @@
2685                 if(WIFSTOPPED(status)){
2686                         switch(WSTOPSIG(status)){
2687                         case SIGSEGV:
2688 -                               handle_segv(userspace_pid);
2689 +                               handle_segv(pid);
2690                                 break;
2691                         case SIGTRAP:
2692 -                               handle_trap(userspace_pid, regs);
2693 +                               handle_trap(pid, regs, local_using_sysemu);
2694                                 break;
2695                         case SIGIO:
2696                         case SIGVTALRM:
2697                         case SIGILL:
2698                         case SIGBUS:
2699                         case SIGFPE:
2700 +                       case SIGWINCH:
2701                                 user_signal(WSTOPSIG(status), regs);
2702                                 break;
2703                         default:
2704 @@ -160,9 +187,17 @@
2705  
2706                 restore_registers(regs);
2707  
2708 -               op = singlestepping_skas() ? PTRACE_SINGLESTEP : 
2709 -                       PTRACE_SYSCALL;
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();
2713 +
2714 +               if (local_using_sysemu)
2715 +                       op = singlestepping_skas() ? PTRACE_SINGLESTEP :
2716 +                               PTRACE_SYSEMU;
2717 +               else
2718 +                       op = singlestepping_skas() ? PTRACE_SINGLESTEP :
2719 +                               PTRACE_SYSCALL;
2720 +
2721 +               err = ptrace(op, pid, 0, 0);
2722                 if(err)
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))
2728  {
2729 +       unsigned long flags;
2730         jmp_buf switch_buf, fork_buf;
2731  
2732         *switch_buf_ptr = &switch_buf;
2733         *fork_buf_ptr = &fork_buf;
2734  
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.
2743 +        */
2744 +       flags = get_signals();
2745 +       block_signals();
2746 +       if(sigsetjmp(fork_buf, 1) == 0)
2747                 new_thread_proc(stack, handler);
2748 +       set_signals(flags);
2749  
2750         remove_sigstack();
2751  }
2752 @@ -189,16 +236,16 @@
2753  
2754         *switch_buf = &buf;
2755         fork_buf = fb;
2756 -       if(setjmp(buf) == 0)
2757 -               longjmp(*fork_buf, 1);
2758 +       if(sigsetjmp(buf, 1) == 0)
2759 +               siglongjmp(*fork_buf, 1);
2760  }
2761  
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)
2766  {
2767 -       if(ptrace(int_op, userspace_pid, 0, regs->skas.regs) < 0)
2768 +       if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
2769                 return(-errno);
2770 -       if(ptrace(fp_op, userspace_pid, 0, fp_regs) < 0)
2771 +       if(ptrace(fp_op, pid, 0, fp_regs) < 0)
2772                 return(-errno);
2773         return(0);
2774  }
2775 @@ -217,10 +264,11 @@
2776                 fp_regs = regs->skas.fp;
2777         }
2778  
2779 -       err = move_registers(PTRACE_GETREGS, fp_op, regs, fp_regs);
2780 +       err = move_registers(userspace_pid[0], PTRACE_GETREGS, fp_op, regs, 
2781 +                            fp_regs);
2782         if(err)
2783                 panic("save_registers - saving registers failed, errno = %d\n",
2784 -                     err);
2785 +                     -err);
2786  }
2787  
2788  void restore_registers(union uml_pt_regs *regs)
2789 @@ -237,10 +285,11 @@
2790                 fp_regs = regs->skas.fp;
2791         }
2792  
2793 -       err = move_registers(PTRACE_SETREGS, fp_op, regs, fp_regs);
2794 +       err = move_registers(userspace_pid[0], PTRACE_SETREGS, fp_op, regs, 
2795 +                            fp_regs);
2796         if(err)
2797                 panic("restore_registers - saving registers failed, "
2798 -                     "errno = %d\n", err);
2799 +                     "errno = %d\n", -err);
2800  }
2801  
2802  void switch_threads(void *me, void *next)
2803 @@ -248,8 +297,8 @@
2804         jmp_buf my_buf, **me_ptr = me, *next_buf = next;
2805         
2806         *me_ptr = &my_buf;
2807 -       if(setjmp(my_buf) == 0)
2808 -               longjmp(*next_buf, 1);
2809 +       if(sigsetjmp(my_buf, 1) == 0)
2810 +               siglongjmp(*next_buf, 1);
2811  }
2812  
2813  static jmp_buf initial_jmpbuf;
2814 @@ -265,14 +314,14 @@
2815         int n;
2816  
2817         *fork_buf_ptr = &initial_jmpbuf;
2818 -       n = setjmp(initial_jmpbuf);
2819 +       n = sigsetjmp(initial_jmpbuf, 1);
2820         if(n == 0)
2821                 new_thread_proc((void *) stack, new_thread_handler);
2822         else if(n == 1)
2823                 remove_sigstack();
2824         else if(n == 2){
2825                 (*cb_proc)(cb_arg);
2826 -               longjmp(*cb_back, 1);
2827 +               siglongjmp(*cb_back, 1);
2828         }
2829         else if(n == 3){
2830                 kmalloc_ok = 0;
2831 @@ -282,7 +331,7 @@
2832                 kmalloc_ok = 0;
2833                 return(1);
2834         }
2835 -       longjmp(**switch_buf, 1);
2836 +       siglongjmp(**switch_buf, 1);
2837  }
2838  
2839  void remove_sigstack(void)
2840 @@ -304,8 +353,8 @@
2841         cb_back = &here;
2842  
2843         block_signals();
2844 -       if(setjmp(here) == 0)
2845 -               longjmp(initial_jmpbuf, 2);
2846 +       if(sigsetjmp(here, 1) == 0)
2847 +               siglongjmp(initial_jmpbuf, 2);
2848         unblock_signals();
2849  
2850         cb_proc = NULL;
2851 @@ -316,22 +365,23 @@
2852  void halt_skas(void)
2853  {
2854         block_signals();
2855 -       longjmp(initial_jmpbuf, 3);
2856 +       siglongjmp(initial_jmpbuf, 3);
2857  }
2858  
2859  void reboot_skas(void)
2860  {
2861         block_signals();
2862 -       longjmp(initial_jmpbuf, 4);
2863 +       siglongjmp(initial_jmpbuf, 4);
2864  }
2865  
2866  int new_mm(int from)
2867  {
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);
2872  
2873         if(fd < 0)
2874 -               return(-errno);
2875 +               return(fd);
2876  
2877         if(from != -1){
2878                 copy = ((struct proc_mm_op) { .op       = MM_COPY_SEGMENTS,
2879 @@ -340,8 +390,9 @@
2880                 n = os_write_file(fd, &copy, 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);
2885         }
2886 +
2887         return(fd);
2888  }
2889  
2890 @@ -349,7 +400,8 @@
2891  {
2892         int err;
2893  
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);
2897         if(err)
2898                 panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n",
2899                       errno);
2900 @@ -357,7 +409,8 @@
2901  
2902  void kill_off_processes_skas(void)
2903  {
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);
2907  }
2908  
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
2914 @@ -28,10 +28,10 @@
2915         struct grantpt_info info;
2916         int fd;
2917  
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",
2920 -                      errno);
2921 -               return(-1);
2922 +       fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0);
2923 +       if(fd < 0){
2924 +               printk("get_pty : Couldn't open /dev/ptmx - err = %d\n", -fd);
2925 +               return(fd);
2926         }
2927  
2928         info.fd = fd;
2929 @@ -39,7 +39,7 @@
2930  
2931         if(info.res < 0){
2932                 printk("get_pty : Couldn't grant pty - errno = %d\n", 
2933 -                      info.err);
2934 +                      -info.err);
2935                 return(-1);
2936         }
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
2942 @@ -7,18 +7,5 @@
2943  $(OBJ): $(OBJS)
2944         rm -f $@
2945         $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
2946 -clean:
2947 -       rm -f $(OBJS)
2948  
2949 -fastdep:
2950 -
2951 -archmrproper:
2952 -
2953 -archclean:
2954 -       rm -f link.ld
2955 -       @$(MAKEBOOT) clean
2956 -
2957 -archdep:
2958 -       @$(MAKEBOOT) dep
2959 -
2960 -modules:
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
2966 @@ -38,6 +38,7 @@
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
2978 @@ -1,7 +1,8 @@
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
2983  
2984  obj-$(CONFIG_HIGHMEM) += highmem.o
2985 +obj-$(CONFIG_MODULES) += module.o
2986  
2987  USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
2988  USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
2989 @@ -9,6 +10,8 @@
2990  SYMLINKS = semaphore.c highmem.c module.c
2991  SYMLINKS := $(foreach f,$(SYMLINKS),$(src)/$f)
2992  
2993 +clean-files := $(SYMLINKS)
2994 +
2995  semaphore.c-dir = kernel
2996  highmem.c-dir = mm
2997  module.c-dir = kernel
2998 @@ -24,19 +27,4 @@
2999  $(SYMLINKS): 
3000         $(call make_link,$@)
3001  
3002 -clean:
3003 -       $(MAKE) -C util clean
3004 -
3005 -fastdep:
3006 -
3007 -dep:
3008 -
3009 -archmrproper:
3010 -       rm -f $(SYMLINKS)
3011 -
3012 -archclean:
3013 -
3014 -archdep:
3015 -
3016 -modules:
3017 -
3018 +subdir- := util
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
3023 @@ -36,7 +36,7 @@
3024         if(sig == SIGSEGV){
3025                 struct k_sigaction *ka;
3026  
3027 -               ka = &current->sig->action[SIGSEGV - 1];
3028 +               ka = &current->sighand->action[SIGSEGV - 1];
3029                 ka->sa.sa_handler = SIG_DFL;
3030         }
3031         force_sig(SIGSEGV, current);
3032 @@ -60,10 +60,10 @@
3033         int err, ret;
3034  
3035         ret = 0;
3036 +       /* Always make any pending restarted system calls return -EINTR */
3037 +       current_thread_info()->restart_block.fn = do_no_restart_syscall;
3038         switch(error){
3039         case -ERESTART_RESTARTBLOCK:
3040 -               current_thread_info()->restart_block.fn = 
3041 -                       do_no_restart_syscall;
3042         case -ERESTARTNOHAND:
3043                 ret = -EINTR;
3044                 break;
3045 @@ -142,7 +142,7 @@
3046                 return(0);
3047  
3048         /* Whee!  Actually deliver the signal.  */
3049 -       ka = &current->sig->action[sig -1 ];
3050 +       ka = &current->sighand->action[sig -1 ];
3051         err = handle_signal(regs, sig, ka, &info, oldset, error);
3052         if(!err) return(1);
3053  
3054 @@ -201,7 +201,7 @@
3055         }
3056  }
3057  
3058 -int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
3059 +int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
3060  {
3061         sigset_t saveset, newset;
3062  
3063 @@ -227,20 +227,59 @@
3064         }
3065  }
3066  
3067 +int sys_sigaction(int sig, const struct old_sigaction __user *act,
3068 +                        struct old_sigaction __user *oact)
3069 +{
3070 +       struct k_sigaction new_ka, old_ka;
3071 +       int ret;
3072 +
3073 +       if (act) {
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))
3078 +                       return -EFAULT;
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);
3082 +       }
3083 +
3084 +       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
3085 +
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))
3090 +                       return -EFAULT;
3091 +               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
3092 +               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
3093 +       }
3094 +
3095 +       return ret;
3096 +}
3097 +
3098 +int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
3099 +{
3100 +       return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
3101 +}
3102 +
3103 +extern int userspace_pid[];
3104 +
3105  static int copy_sc_from_user(struct pt_regs *to, void *from, 
3106                              struct arch_frame_data *arch)
3107  {
3108         int ret;
3109  
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));
3114         return(ret);
3115  }
3116  
3117  int sys_sigreturn(struct pt_regs regs)
3118  {
3119 -       void *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
3120 -       void *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
3121 +       void __user *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
3122 +       void __user *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
3123         int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
3124  
3125         spin_lock_irq(&current->sighand->siglock);
3126 @@ -257,8 +296,8 @@
3127  
3128  int sys_rt_sigreturn(struct pt_regs regs)
3129  {
3130 -       struct ucontext *uc = sp_to_uc(PT_REGS_SP(&current->thread.regs));
3131 -       void *fp;
3132 +       unsigned long sp = PT_REGS_SP(&current->thread.regs);
3133 +       struct ucontext __user *uc = sp_to_uc(sp);
3134         int sig_size = _NSIG_WORDS * sizeof(unsigned long);
3135  
3136         spin_lock_irq(&current->sighand->siglock);
3137 @@ -266,7 +305,6 @@
3138         sigdelsetmask(&current->blocked, ~_BLOCKABLE);
3139         recalc_sigpending();
3140         spin_unlock_irq(&current->sighand->siglock);
3141 -       fp = (void *) (((unsigned long) uc) + sizeof(struct ucontext));
3142         copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext,
3143                           &signal_frame_si.common.arch);
3144         return(PT_REGS_SYSCALL_RET(&current->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
3149 @@ -44,6 +44,11 @@
3150  }
3151  EXPORT_SYMBOL(dump_stack);
3152  
3153 +void show_stack(struct task_struct *task, unsigned long *sp)
3154 +{
3155 +       show_trace(sp);
3156 +}
3157 +
3158  /*
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
3165 @@ -11,39 +11,34 @@
3166  #define EXECUTE_SYSCALL(syscall, regs) \
3167         ((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs))
3168  
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;
3173 -
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, 
3229          
3230  /* 222 doesn't yet have a name in include/asm-i386/unistd.h */
3231  
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
3236 @@ -41,7 +41,7 @@
3237   * Have the 32 bit jiffies value wrap 5 minutes after boot
3238   * so jiffies wrap bugs show up earlier.
3239   */
3240 -#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))
3241 +#define INITIAL_JIFFIES ((unsigned long)(0))
3242  
3243  /*
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
3249 @@ -1,10 +1,14 @@
3250 +/* 
3251 + *  Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
3252 + * Licensed under the GPL
3253 + */
3254 +
3255  #ifndef __UM_PAGE_H
3256  #define __UM_PAGE_H
3257  
3258  struct page;
3259  
3260  #include "asm/arch/page.h"
3261 -#include "asm/bug.h"
3262  
3263  #undef __pa
3264  #undef __va
3265 @@ -24,25 +28,36 @@
3266  
3267  #define __va_space (8*1024*1024)
3268  
3269 -extern unsigned long region_pa(void *virt);
3270 -extern void *region_va(unsigned long phys);
3271 -
3272 -#define __pa(virt) region_pa((void *) (virt))
3273 -#define __va(phys) region_va((unsigned long) (phys))
3274 -
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);
3279  
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)
3283  
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))
3287  
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)
3291  
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)))
3296  
3297  extern struct page *arch_validate(struct page *page, int mask, int order);
3298  #define HAVE_ARCH_VALIDATE
3299  
3300 +extern void arch_free_page(struct page *page, int order);
3301 +#define HAVE_ARCH_FREE_PAGE
3302 +
3303  #endif
3304 +
3305 +/*
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
3309 + * of the file.
3310 + * ---------------------------------------------------------------------------
3311 + * Local variables:
3312 + * c-file-style: "linux"
3313 + * End:
3314 + */
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
3319 @@ -11,6 +11,8 @@
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);
3325  
3326  #endif
3327  
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
3332 @@ -0,0 +1,6 @@
3333 +#ifndef __UM_LOCAL_H
3334 +#define __UM_LOCAL_H
3335 +
3336 +#include "asm/arch/local.h"
3337 +
3338 +#endif
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
3343 @@ -9,6 +9,7 @@
3344  #ifndef __ASSEMBLY__
3345  
3346  #include <asm/processor.h>
3347 +#include <asm/types.h>
3348  
3349  struct thread_info {
3350         struct task_struct      *task;          /* main task structure */
3351 @@ -43,15 +44,18 @@
3352  static inline struct thread_info *current_thread_info(void)
3353  {
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));
3359         return ti;
3360  }
3361  
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)
3371 +       
3372  #define get_thread_info(ti) get_task_struct((ti)->task)
3373  #define put_thread_info(ti) put_task_struct((ti)->task)
3374  
3375 @@ -65,11 +69,13 @@
3376  #define TIF_POLLING_NRFLAG      3       /* true if poll_idle() is polling 
3377                                          * TIF_NEED_RESCHED 
3378                                          */
3379 +#define TIF_RESTART_BLOCK      4
3380  
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)
3386  
3387  #endif
3388  
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
3393 @@ -1 +1,119 @@
3394 -#include <asm-generic/dma-mapping.h>
3395 +#ifndef _ASM_DMA_MAPPING_H
3396 +#define _ASM_DMA_MAPPING_H
3397 +
3398 +static inline int
3399 +dma_supported(struct device *dev, u64 mask)
3400 +{
3401 +       BUG();
3402 +       return(0);
3403 +}
3404 +
3405 +static inline int
3406 +dma_set_mask(struct device *dev, u64 dma_mask)
3407 +{
3408 +       BUG();
3409 +       return(0);
3410 +}
3411 +
3412 +static inline void *
3413 +dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
3414 +                  int flag)
3415 +{
3416 +       BUG();
3417 +       return((void *) 0);
3418 +}
3419 +
3420 +static inline void
3421 +dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
3422 +                 dma_addr_t dma_handle)
3423 +{
3424 +       BUG();
3425 +}
3426 +
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)
3430 +{
3431 +       BUG();
3432 +       return(0);
3433 +}
3434 +
3435 +static inline void
3436 +dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
3437 +                enum dma_data_direction direction)
3438 +{
3439 +       BUG();
3440 +}
3441 +
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)
3446 +{
3447 +       BUG();
3448 +       return(0);
3449 +}
3450 +
3451 +static inline void
3452 +dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
3453 +              enum dma_data_direction direction)
3454 +{
3455 +       BUG();
3456 +}
3457 +
3458 +static inline int
3459 +dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
3460 +          enum dma_data_direction direction)
3461 +{
3462 +       BUG();
3463 +       return(0);
3464 +}
3465 +
3466 +static inline void
3467 +dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
3468 +            enum dma_data_direction direction)
3469 +{
3470 +       BUG();
3471 +}
3472 +
3473 +static inline void
3474 +dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size,
3475 +               enum dma_data_direction direction)
3476 +{
3477 +       BUG();
3478 +}
3479 +
3480 +static inline void
3481 +dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems,
3482 +           enum dma_data_direction direction)
3483 +{
3484 +       BUG();
3485 +}
3486 +
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)
3490 +
3491 +static inline int
3492 +dma_get_cache_alignment(void)
3493 +{
3494 +       BUG();
3495 +       return(0);
3496 +}
3497 +
3498 +static inline 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)
3502 +{
3503 +       BUG();
3504 +}
3505 +
3506 +static inline void
3507 +dma_cache_sync(void *vaddr, size_t size,
3508 +              enum dma_data_direction direction)
3509 +{
3510 +       BUG();
3511 +}
3512 +
3513 +#endif
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
3518 @@ -22,7 +22,7 @@
3519  
3520         index = record_syscall_start(UPT_SYSCALL_NR(regs));
3521  
3522 -       syscall_trace();
3523 +       syscall_trace(regs, 1);
3524         result = execute_syscall(regs);
3525  
3526         REGS_SET_SYSCALL_RETURN(regs->skas.regs, result);
3527 @@ -30,7 +30,7 @@
3528            (result == -ERESTARTNOINTR))
3529                 do_signal(result);
3530  
3531 -       syscall_trace();
3532 +       syscall_trace(regs, 0);
3533         record_syscall_end(index, result);
3534  }
3535  
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
3540 @@ -9,18 +9,17 @@
3541  #include <sched.h>
3542  #include <errno.h>
3543  #include <stdarg.h>
3544 -#include <fcntl.h>
3545  #include <stdlib.h>
3546  #include <setjmp.h>
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"
3559  #include "user.h"
3560 @@ -58,7 +57,11 @@
3561  {
3562         int flags = altstack ? SA_ONSTACK : 0;
3563  
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.
3568 +        */
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);
3573 @@ -72,7 +75,6 @@
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);
3579  
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", 
3588                           errno);
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);
3593  
3594         return(arg.pid);
3595  }
3596 @@ -138,7 +141,7 @@
3597  
3598         os_stop_process(os_getpid());
3599  
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");
3603  }
3604  
3605 @@ -168,7 +171,7 @@
3606         pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
3607         if(pid < 0)
3608                 panic("check_ptrace : clone failed, errno = %d", errno);
3609 -       n = waitpid(pid, &status, WUNTRACED);
3610 +       CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
3611         if(n < 0)
3612                 panic("check_ptrace : wait failed, errno = %d", errno);
3613         if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
3614 @@ -185,7 +188,7 @@
3615  
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);
3622  
3623 @@ -193,6 +196,22 @@
3624                 panic("check_ptrace : munmap failed, errno = %d", errno);
3625  }
3626  
3627 +static int force_sysemu_disabled = 0;
3628 +
3629 +static int __init nosysemu_cmd_param(char *str, int* add)
3630 +{
3631 +       force_sysemu_disabled = 1;
3632 +       return 0;
3633 +}
3634 +
3635 +__uml_setup("nosysemu", nosysemu_cmd_param,
3636 +               "nosysemu\n"
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");
3642 +
3643  void __init check_ptrace(void)
3644  {
3645         void *stack;
3646 @@ -205,7 +224,7 @@
3647                 if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
3648                         panic("check_ptrace : ptrace failed, errno = %d", 
3649                               errno);
3650 -               n = waitpid(pid, &status, WUNTRACED);
3651 +               CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
3652                 if(n < 0)
3653                         panic("check_ptrace : wait failed, errno = %d", errno);
3654                 if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
3655 @@ -225,6 +244,45 @@
3656         }
3657         stop_ptraced_child(pid, stack, 0);
3658         printk("OK\n");
3659 +
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;
3666 +
3667 +               CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
3668 +               if (n < 0)
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);
3673 +
3674 +               if (ptrace(PTRACE_GETREGS, pid, 0, &regs) < 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, &regs) < 0)
3679 +                       panic("check_ptrace : failed to modify child "
3680 +                             "registers, errno = %d", errno);
3681 +
3682 +               stop_ptraced_child(pid, stack, 0);
3683 +
3684 +               if (!force_sysemu_disabled) {
3685 +                       printk("found\n");
3686 +                       set_using_sysemu(1);
3687 +               } else {
3688 +                       printk("found but disabled\n");
3689 +               }
3690 +       }
3691 +       else
3692 +       {
3693 +               printk("missing\n");
3694 +               stop_ptraced_child(pid, stack, 1);
3695 +       }
3696 +#endif
3697 +
3698  }
3699  
3700  int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
3701 @@ -233,7 +289,7 @@
3702         int n;
3703  
3704         *jmp_ptr = &buf;
3705 -       n = setjmp(buf);
3706 +       n = sigsetjmp(buf, 1);
3707         if(n != 0)
3708                 return(n);
3709         (*fn)(arg);
3710 @@ -273,7 +329,7 @@
3711         stop_ptraced_child(pid, stack, 1);
3712  
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");
3717                 ret = 0;
3718         }
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
3723 @@ -83,7 +83,8 @@
3724  
3725  static struct line_driver driver = {
3726         .name                   = "UML console",
3727 -       .devfs_name             = "vc/%d",
3728 +       .device_name            = "tty",
3729 +       .devfs_name             = "vc/",
3730         .major                  = TTY_MAJOR,
3731         .minor_start            = 0,
3732         .type                   = TTY_DRIVER_TYPE_CONSOLE,
3733 @@ -159,6 +160,15 @@
3734  
3735  static int con_init_done = 0;
3736  
3737 +static struct tty_operations console_ops = {
3738 +       .open                   = con_open,
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,
3744 +};
3745 +
3746  int stdio_init(void)
3747  {
3748         char *new_title;
3749 @@ -166,7 +176,8 @@
3750         printk(KERN_INFO "Initializing stdio console driver\n");
3751  
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]));
3756  
3757         lines_init(vts, sizeof(vts)/sizeof(vts[0]));
3758  
3759 @@ -178,24 +189,19 @@
3760         return(0);
3761  }
3762  
3763 -__initcall(stdio_init);
3764 +late_initcall(stdio_init);
3765  
3766  static void console_write(struct console *console, const char *string, 
3767                           unsigned len)
3768  {
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);
3772 -}
3773 +       struct line *line = &vts[console->index];
3774  
3775 -static struct tty_operations console_ops = {
3776 -       .open                   = con_open,
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,
3782 -};
3783 +       if(con_init_done)
3784 +               down(&line->sem);
3785 +       console_write_chan(&line->chan_list, string, len);
3786 +       if(con_init_done)
3787 +               up(&line->sem);
3788 +}
3789  
3790  static struct tty_driver *console_device(struct console *c, int *index)
3791  {
3792 @@ -208,22 +214,28 @@
3793         return(0);
3794  }
3795  
3796 -static struct console stdiocons = INIT_CONSOLE("tty", console_write, 
3797 -                                              console_device, console_setup,
3798 -                                              CON_PRINTBUFFER);
3799 +static struct console stdiocons = {
3800 +       name:           "tty",
3801 +       write:          console_write,
3802 +       device:         console_device,
3803 +       setup:          console_setup,
3804 +       flags:          CON_PRINTBUFFER,
3805 +       index:          -1,
3806 +};
3807  
3808 -static void __init stdio_console_init(void)
3809 +static int __init stdio_console_init(void)
3810  {
3811         INIT_LIST_HEAD(&vts[0].chan_list);
3812         list_add(&init_console_chan.list, &vts[0].chan_list);
3813         register_console(&stdiocons);
3814 +       return(0);
3815  }
3816 +
3817  console_initcall(stdio_console_init);
3818  
3819  static int console_chan_setup(char *str)
3820  {
3821 -       line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1);
3822 -       return(1);
3823 +       return(line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1));
3824  }
3825  
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
3831 @@ -3,13 +3,9 @@
3832  # Licensed under the GPL
3833  #
3834  
3835 -obj-y = file.o process.o tty.o drivers/
3836 +obj-y = file.o process.o tty.o user_syms.o drivers/
3837  
3838  USER_OBJS := $(foreach file,file.o process.o tty.o,$(obj)/$(file))
3839  
3840  $(USER_OBJS) : %.o: %.c
3841         $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
3842 -
3843 -clean :
3844 -
3845 -archmrproper:
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
3850 @@ -1,5 +1,5 @@
3851  /* 
3852 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3853 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
3854   * Licensed under the GPL
3855   */
3856  
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
3861 @@ -7,12 +7,12 @@
3862  #include <unistd.h>
3863  #include <string.h>
3864  #include <errno.h>
3865 -#include <fcntl.h>
3866  #include <termios.h>
3867  #include "chan_user.h"
3868  #include "user.h"
3869  #include "user_util.h"
3870  #include "kern_util.h"
3871 +#include "os.h"
3872  
3873  struct pty_chan {
3874         void (*announce)(char *dev_name, int dev);
3875 @@ -26,7 +26,8 @@
3876  {
3877         struct pty_chan *data;
3878  
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, 
3883                                      .dev               = device,
3884                                      .raw               = opts->raw });
3885 @@ -39,7 +40,8 @@
3886         char *dev;
3887         int fd;
3888  
3889 -       if((fd = get_pty()) < 0){
3890 +       fd = get_pty();
3891 +       if(fd < 0){
3892                 printk("open_pts : Failed to open pts\n");
3893                 return(-errno);
3894         }
3895 @@ -57,29 +59,27 @@
3896  
3897  int getmaster(char *line)
3898  {
3899 -       struct stat stb;
3900         char *pty, *bank, *cp;
3901 -       int master;
3902 +       int master, err;
3903  
3904         pty = &line[strlen("/dev/ptyp")];
3905         for (bank = "pqrs"; *bank; bank++) {
3906                 line[strlen("/dev/pty")] = *bank;
3907                 *pty = '0';
3908 -               if (stat(line, &stb) < 0)
3909 +               if (os_stat_file(line, NULL) < 0)
3910                         break;
3911                 for (cp = "0123456789abcdef"; *cp; cp++) {
3912                         *pty = *cp;
3913 -                       master = open(line, O_RDWR);
3914 +                       master = os_open_file(line, of_rdwr(OPENFLAGS()), 0);
3915                         if (master >= 0) {
3916                                 char *tp = &line[strlen("/dev/")];
3917 -                               int ok;
3918  
3919                                 /* verify slave side is usable */
3920                                 *tp = 't';
3921 -                               ok = access(line, R_OK|W_OK) == 0;
3922 +                               err = os_access(line, OS_ACC_RW_OK);
3923                                 *tp = 'p';
3924 -                               if (ok) return(master);
3925 -                               (void) close(master);
3926 +                               if(err == 0) return(master);
3927 +                               (void) os_close_file(master);
3928                         }
3929                 }
3930         }
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
3935 @@ -1,5 +1,6 @@
3936  #include "linux/kernel.h"
3937  #include "linux/stringify.h"
3938 +#include "linux/time.h"
3939  #include "asm/page.h"
3940  
3941  extern void print_head(void);
3942 @@ -11,6 +12,7 @@
3943  {
3944    print_head();
3945    print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
3946 +
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);
3950 @@ -19,6 +21,8 @@
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);
3954 +
3955 +  print_constant_int("UM_NSEC_PER_SEC", NSEC_PER_SEC);
3956    print_tail();
3957    return(0);
3958  }
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
3963 @@ -47,10 +47,12 @@
3964                 return(NULL);
3965         }
3966  
3967 -       if((kern_data = port_data(port)) == NULL) 
3968 +       kern_data = port_data(port);
3969 +       if(kern_data == NULL) 
3970                 return(NULL);
3971  
3972 -       if((data = um_kmalloc(sizeof(*data))) == NULL) 
3973 +       data = um_kmalloc(sizeof(*data));
3974 +       if(data == NULL) 
3975                 goto err;
3976  
3977         *data = ((struct port_chan) { .raw              = opts->raw,
3978 @@ -90,7 +92,7 @@
3979         struct port_chan *data = d;
3980  
3981         port_remove_dev(data->kernel_data);
3982 -       close(fd);
3983 +       os_close_file(fd);
3984  }
3985  
3986  int port_console_write(int fd, const char *buf, int n, void *d)
3987 @@ -130,11 +132,15 @@
3988                 goto out;
3989         }
3990    
3991 -       if((listen(fd, 1) < 0) || (os_set_fd_block(fd, 0))){
3992 +       if(listen(fd, 1) < 0){
3993                 err = -errno;
3994                 goto out;
3995         }
3996  
3997 +       err = os_set_fd_block(fd, 0);
3998 +       if(err < 0)
3999 +               goto out;
4000 +
4001         return(fd);
4002   out:
4003         os_close_file(fd);
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);
4014  }
4015  
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;
4020  
4021 -       if((new = os_accept_connection(fd)) < 0)
4022 -               return(-errno);
4023 +       new = os_accept_connection(fd);
4024 +       if(new < 0)
4025 +               return(new);
4026  
4027         err = os_pipe(socket, 0, 0);
4028 -       if(err) 
4029 +       if(err < 0) 
4030                 goto out_close;
4031  
4032         data = ((struct port_pre_exec_data)
4033 @@ -186,11 +193,11 @@
4034  
4035   out_shutdown:
4036         os_shutdown_socket(socket[0], 1, 1);
4037 -       close(socket[0]);
4038 +       os_close_file(socket[0]);
4039         os_shutdown_socket(socket[1], 1, 1);    
4040 -       close(socket[1]);
4041 +       os_close_file(socket[1]);
4042   out_close:
4043 -       close(new);
4044 +       os_close_file(new);
4045         return(err);
4046  }
4047  
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
4052 @@ -6,6 +6,7 @@
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"
4060 @@ -14,6 +15,7 @@
4061  #include "kern_util.h"
4062  #include "kern.h"
4063  #include "irq_user.h"
4064 +#include "irq_kern.h"
4065  #include "port.h"
4066  #include "init.h"
4067  #include "os.h"
4068 @@ -38,21 +40,21 @@
4069  struct connection {
4070         struct list_head list;
4071         int fd;
4072 -       int helper_pid;
4073 +       int helper_pid;
4074         int socket[2];
4075         int telnetd_pid;
4076         struct port_list *port;
4077  };
4078  
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)
4081  {
4082         struct connection *conn = data;
4083         int fd;
4084  
4085 -       fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
4086 +       fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
4087         if(fd < 0){
4088                 if(fd == -EAGAIN)
4089 -                       return;
4090 +                       return(IRQ_NONE);
4091  
4092                 printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", 
4093                        -fd);
4094 @@ -65,6 +67,7 @@
4095         list_add(&conn->list, &conn->port->connections);
4096  
4097         up(&conn->port->sem);
4098 +       return(IRQ_HANDLED);
4099  }
4100  
4101  static int port_accept(struct port_list *port)
4102 @@ -102,8 +105,7 @@
4103         }
4104  
4105         list_add(&conn->list, &port->pending);
4106 -       ret = 1;
4107 -       goto out;
4108 +       return(1);
4109  
4110   out_free:
4111         kfree(conn);
4112 @@ -138,12 +140,13 @@
4113  
4114  DECLARE_WORK(port_work, port_work_proc, NULL);
4115  
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)
4118  {
4119         struct port_list *port = data;
4120  
4121         port->has_connection = 1;
4122         schedule_work(&port_work);
4123 +       return(IRQ_HANDLED);
4124  } 
4125  
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
4131 @@ -39,10 +39,10 @@
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],
4137                           regs[i]) < 0)
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);
4142         }
4143  }
4144  
4145 @@ -54,7 +54,7 @@
4146         dummy = NULL;
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);
4152         }
4153  }
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
4158 @@ -8,7 +8,6 @@
4159  #include <stdlib.h>
4160  #include <unistd.h>
4161  #include <errno.h>
4162 -#include <fcntl.h>
4163  #include <sys/wait.h>
4164  #include <sys/socket.h>
4165  #include <sys/un.h>
4166 @@ -19,6 +18,7 @@
4167  #include "net_user.h"
4168  #include "tuntap.h"
4169  #include "kern_util.h"
4170 +#include "user_util.h"
4171  #include "user.h"
4172  #include "helper.h"
4173  #include "os.h"
4174 @@ -61,7 +61,7 @@
4175         struct tuntap_pre_exec_data *data = arg;
4176         
4177         dup2(data->stdout, 1);
4178 -       close(data->close_me);
4179 +       os_close_file(data->close_me);
4180  }
4181  
4182  static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
4183 @@ -86,7 +86,7 @@
4184  
4185         if(pid < 0) return(-pid);
4186  
4187 -       close(remote);
4188 +       os_close_file(remote);
4189  
4190         msg.msg_name = NULL;
4191         msg.msg_namelen = 0;
4192 @@ -107,19 +107,19 @@
4193         if(n < 0){
4194                 printk("tuntap_open_tramp : recvmsg failed - errno = %d\n", 
4195                        errno);
4196 -               return(errno);
4197 +               return(-errno);
4198         }
4199 -       waitpid(pid, NULL, 0);
4200 +       CATCH_EINTR(waitpid(pid, NULL, 0));
4201  
4202         cmsg = CMSG_FIRSTHDR(&msg);
4203         if(cmsg == NULL){
4204                 printk("tuntap_open_tramp : didn't receive a message\n");
4205 -               return(EINVAL);
4206 +               return(-EINVAL);
4207         }
4208         if((cmsg->cmsg_level != SOL_SOCKET) || 
4209            (cmsg->cmsg_type != SCM_RIGHTS)){
4210                 printk("tuntap_open_tramp : didn't receive a descriptor\n");
4211 -               return(EINVAL);
4212 +               return(-EINVAL);
4213         }
4214         *fd_out = ((int *) CMSG_DATA(cmsg))[0];
4215         return(0);
4216 @@ -133,27 +133,29 @@
4217         int err, fds[2], len, used;
4218  
4219         err = tap_open_common(pri->dev, pri->gate_addr);
4220 -       if(err) return(err);
4221 +       if(err < 0) 
4222 +               return(err);
4223  
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",
4227 -                              errno);
4228 -                       return(-errno);
4229 +               pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0);
4230 +               if(pri->fd < 0){
4231 +                       printk("Failed to open /dev/net/tun, err = %d\n",
4232 +                              -pri->fd);
4233 +                       return(pri->fd);
4234                 }
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);
4241 -                       close(pri->fd);
4242 +                       printk("TUNSETIFF failed, errno = %d\n", errno);
4243 +                       os_close_file(pri->fd);
4244                         return(-errno);
4245                 }
4246         }
4247         else {
4248                 err = os_pipe(fds, 0, 0);
4249 -               if(err){
4250 -                       printk("tuntap_open : os_pipe failed - errno = %d\n",
4251 +               if(err < 0){
4252 +                       printk("tuntap_open : os_pipe failed - err = %d\n",
4253                                -err);
4254                         return(err);
4255                 }
4256 @@ -166,19 +168,19 @@
4257                                         fds[1], buffer, len, &used);
4258  
4259                 output = buffer;
4260 -               if(err == 0){
4261 -                       pri->dev_name = uml_strdup(buffer);
4262 -                       output += IFNAMSIZ;
4263 -                       printk(output);
4264 -                       free_output_buffer(buffer);
4265 -               }
4266 -               else {
4267 -                       printk(output);
4268 +               if(err < 0) {
4269 +                       printk("%s", output);
4270                         free_output_buffer(buffer);
4271 -                       printk("tuntap_open_tramp failed - errno = %d\n", err);
4272 -                       return(-err);
4273 +                       printk("tuntap_open_tramp failed - err = %d\n", -err);
4274 +                       return(err);
4275                 }
4276 -               close(fds[0]);
4277 +
4278 +               pri->dev_name = uml_strdup(buffer);
4279 +               output += IFNAMSIZ;
4280 +               printk("%s", output);
4281 +               free_output_buffer(buffer);
4282 +
4283 +               os_close_file(fds[0]);
4284                 iter_addresses(pri->dev, open_addr, pri->dev_name);
4285         }
4286  
4287 @@ -191,7 +193,7 @@
4288  
4289         if(!pri->fixed_config) 
4290                 iter_addresses(pri->dev, close_addr, pri->dev_name);
4291 -       close(fd);
4292 +       os_close_file(fd);
4293         pri->fd = -1;
4294  }
4295  
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
4300 @@ -38,13 +38,18 @@
4301  #include "mode_kern.h"
4302  #include "mode.h"
4303  
4304 -#define DEFAULT_COMMAND_LINE "root=6200"
4305 +#define DEFAULT_COMMAND_LINE "root=98:0"
4306  
4307  struct cpuinfo_um boot_cpu_data = { 
4308         .loops_per_jiffy        = 0,
4309         .ipi_pipe               = { -1, -1 }
4310  };
4311  
4312 +/* Placeholder to make UML link until the vsyscall stuff is actually 
4313 + * implemented
4314 + */
4315 +void *__kernel_vsyscall;
4316 +
4317  unsigned long thread_saved_pc(struct task_struct *task)
4318  {
4319         return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
4320 @@ -53,18 +58,22 @@
4321  
4322  static int show_cpuinfo(struct seq_file *m, void *v)
4323  {
4324 -       int index;
4325 +       int index = 0;
4326  
4327 -       index = (struct cpuinfo_um *)v - cpu_data;
4328  #ifdef CONFIG_SMP
4329 +       index = (struct cpuinfo_um *) v - cpu_data;
4330         if (!cpu_online(index))
4331                 return 0;
4332  #endif
4333  
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);
4344  
4345         return(0);
4346  }
4347 @@ -134,12 +143,12 @@
4348         if(umid != NULL){
4349                 snprintf(argv1_begin, 
4350                          (argv1_end - argv1_begin) * sizeof(*ptr), 
4351 -                        "(%s)", umid);
4352 +                        "(%s) ", umid);
4353                 ptr = &argv1_begin[strlen(argv1_begin)];
4354         }
4355         else ptr = argv1_begin;
4356  
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));
4361  #endif
4362 @@ -179,7 +188,7 @@
4363  static int __init uml_ncpus_setup(char *line, int *add)
4364  {
4365         if (!sscanf(line, "%d", &ncpus)) {
4366 -               printk("Couldn't parse [%s]\n", line);
4367 +               printf("Couldn't parse [%s]\n", line);
4368                 return -1;
4369         }
4370  
4371 @@ -210,7 +219,7 @@
4372  
4373  static int __init mode_tt_setup(char *line, int *add)
4374  {
4375 -       printk("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
4376 +       printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
4377         return(0);
4378  }
4379  
4380 @@ -221,7 +230,7 @@
4381  
4382  static int __init mode_tt_setup(char *line, int *add)
4383  {
4384 -       printk("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
4385 +       printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
4386         return(0);
4387  }
4388  
4389 @@ -291,7 +300,7 @@
4390  
4391  /* Set during early boot */
4392  unsigned long brk_start;
4393 -static struct vm_reserved kernel_vm_reserved;
4394 +unsigned long end_iomem;
4395  
4396  #define MIN_VMALLOC (32 * 1024 * 1024)
4397  
4398 @@ -299,7 +308,7 @@
4399  {
4400         unsigned long avail;
4401         unsigned long virtmem_size, max_physmem;
4402 -       unsigned int i, add, err;
4403 +       unsigned int i, add;
4404  
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])];
4409  #endif
4410    
4411 -       set_usable_vm(uml_physmem, get_kmem_end());
4412 -
4413         highmem = 0;
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;
4419 +
4420 +       /* Zones have to begin on a 1 << MAX_ORDER page boundary,
4421 +        * so this makes sure that's true for highmem
4422 +        */
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
4428                 highmem = 0;
4429 @@ -343,11 +356,19 @@
4430         }
4431  
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;
4436  
4437         start_vm = VMALLOC_START;
4438  
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,
4444 +                      highmem);
4445 +               exit(1);
4446 +       }
4447 +
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",
4453                        virtmem_size);
4454  
4455 -       err = reserve_vm(high_physmem, end_vm, &kernel_vm_reserved);
4456 -       if(err){
4457 -               printf("Failed to reserve VM area for kernel VM\n");
4458 -               exit(1);
4459 -       }
4460 -
4461         uml_postsetup();
4462  
4463         init_task.thread.kernel_stack = (unsigned long) &init_thread_info + 
4464                 2 * PAGE_SIZE;
4465  
4466         task_protections((unsigned long) &init_thread_info);
4467 +       os_flush_stdout();
4468  
4469         return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
4470  }
4471  
4472 +extern int uml_exitcode;
4473 +
4474  static int panic_exit(struct notifier_block *self, unsigned long unused1,
4475                       void *unused2)
4476  {
4477  #ifdef CONFIG_MAGIC_SYSRQ
4478 -       handle_sysrq('p', &current->thread.regs, NULL, NULL);
4479 +       handle_sysrq('p', &current->thread.regs, NULL);
4480  #endif
4481 +       uml_exitcode = 1;
4482         machine_halt();
4483         return(0);
4484  }
4485 @@ -403,6 +422,11 @@
4486         arch_check_bugs();
4487         check_ptrace();
4488         check_sigio();
4489 +       check_devanon();
4490 +}
4491 +
4492 +void apply_alternatives(void *start, void *end)
4493 +{
4494  }
4495  
4496  /*
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
4501 @@ -1,74 +1,66 @@
4502  /* 
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
4506   */
4507  
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"
4532 -#include "mem.h"
4533  #include "kern.h"
4534 -#include "init.h"
4535 -#include "os.h"
4536 -#include "mode_kern.h"
4537 +#include "mem_user.h"
4538  #include "uml_uaccess.h"
4539 +#include "os.h"
4540 +
4541 +extern char __binary_start;
4542  
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;
4551 -
4552 -/* Not modified */
4553 -const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n";
4554 -
4555 -extern char __init_begin, __init_end;
4556 -extern long physmem_size;
4557 -
4558 -/* Not changed by UML */
4559 -DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
4560 -
4561 -/* Changed during early boot */
4562 +pgd_t swapper_pg_dir[1024];
4563 +unsigned long highmem;
4564  int kmalloc_ok = 0;
4565  
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)
4569 -
4570 -/* Changed during early boot */
4571  static unsigned long brk_end;
4572  
4573 +void unmap_physmem(void)
4574 +{
4575 +       os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
4576 +}
4577 +
4578  static void map_cb(void *unused)
4579  {
4580         map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0);
4581  }
4582  
4583 -void unmap_physmem(void)
4584 +#ifdef CONFIG_HIGHMEM
4585 +static void setup_highmem(unsigned long highmem_start, 
4586 +                         unsigned long highmem_len)
4587  {
4588 -       os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
4589 -}
4590 +       struct page *page;
4591 +       unsigned long highmem_pfn;
4592 +       int i;
4593  
4594 -extern char __binary_start;
4595 +       highmem_start_page = virt_to_page(highmem_start);
4596 +
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);
4604 +       }
4605 +}
4606 +#endif
4607  
4608  void mem_init(void)
4609  {
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));
4618         kmalloc_ok = 1;
4619 -}
4620 -
4621 -/* Changed during early boot */
4622 -static unsigned long kmem_top = 0;
4623 -
4624 -unsigned long get_kmem_end(void)
4625 -{
4626 -       if(kmem_top == 0)
4627 -               kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
4628 -       return(kmem_top);
4629 -}
4630 -
4631 -void set_kmem_end(unsigned long new)
4632 -{
4633 -       kmem_top = new;
4634 -}
4635  
4636  #ifdef CONFIG_HIGHMEM
4637 -/* Changed during early boot */
4638 -pte_t *kmap_pte;
4639 -pgprot_t kmap_prot;
4640 -
4641 -EXPORT_SYMBOL(kmap_prot);
4642 -EXPORT_SYMBOL(kmap_pte);
4643 -
4644 -#define kmap_get_fixmap_pte(vaddr)                                     \
4645 -       pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
4646 -
4647 -void __init kmap_init(void)
4648 -{
4649 -       unsigned long kmap_vstart;
4650 -
4651 -       /* cache the first kmap pte */
4652 -       kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
4653 -       kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
4654 -
4655 -       kmap_prot = PAGE_KERNEL;
4656 +       setup_highmem(end_iomem, highmem);
4657 +#endif
4658  }
4659 -#endif /* CONFIG_HIGHMEM */
4660  
4661  static void __init fixrange_init(unsigned long start, unsigned long end, 
4662                                  pgd_t *pgd_base)
4663 @@ -178,76 +135,24 @@
4664         }
4665  }
4666  
4667 -int init_maps(struct mem_region *region)
4668 -{
4669 -       struct page *p, *map;
4670 -       int i, n, len;
4671 -
4672 -       if(region == &physmem_region){
4673 -               region->mem_map = mem_map;
4674 -               return(0);
4675 -       }
4676 -       else if(region->mem_map != NULL) return(0);
4677 -
4678 -       n = region->len >> PAGE_SHIFT;
4679 -       len = n * sizeof(struct page);
4680 -       if(kmalloc_ok){
4681 -               map = kmalloc(len, GFP_KERNEL);
4682 -               if(map == NULL) map = vmalloc(len);
4683 -       }
4684 -       else map = alloc_bootmem_low_pages(len);
4685 -
4686 -       if(map == NULL)
4687 -               return(-ENOMEM);
4688 -       for(i = 0; i < n; i++){
4689 -               p = &map[i];
4690 -               set_page_count(p, 0);
4691 -               SetPageReserved(p);
4692 -               INIT_LIST_HEAD(&p->list);
4693 -       }
4694 -       region->mem_map = map;
4695 -       return(0);
4696 -}
4697 +#if CONFIG_HIGHMEM
4698 +pte_t *kmap_pte;
4699 +pgprot_t kmap_prot;
4700  
4701 -DECLARE_MUTEX(regions_sem);
4702 +#define kmap_get_fixmap_pte(vaddr)                                     \
4703 +       pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
4704  
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)
4709  {
4710 -       int i;
4711 -
4712 -       down(&regions_sem);
4713 -       for(i = 0; i < NREGIONS; i++){
4714 -               if(regions[i] == NULL) break;           
4715 -       }
4716 -       if(i == NREGIONS){
4717 -               printk("setup_range : no free regions\n");
4718 -               i = -1;
4719 -               goto out;
4720 -       }
4721 -
4722 -       if(fd == -1)
4723 -               fd = create_mem_file(len);
4724 +       unsigned long kmap_vstart;
4725  
4726 -       if(region == NULL){
4727 -               region = alloc_bootmem_low_pages(sizeof(*region));
4728 -               if(region == NULL)
4729 -                       panic("Failed to allocating mem_region");
4730 -       }
4731 +       /* cache the first kmap pte */
4732 +       kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
4733 +       kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
4734  
4735 -       *region = ((struct mem_region) { .driver        = driver,
4736 -                                        .start_pfn     = pfn,
4737 -                                        .start         = start, 
4738 -                                        .len           = len, 
4739 -                                        .fd            = fd } );
4740 -       regions[i] = region;
4741 - out:
4742 -       up(&regions_sem);
4743 -       return(i);
4744 +       kmap_prot = PAGE_KERNEL;
4745  }
4746  
4747 -#ifdef CONFIG_HIGHMEM
4748  static void init_highmem(void)
4749  {
4750         pgd_t *pgd;
4751 @@ -268,63 +173,20 @@
4752  
4753         kmap_init();
4754  }
4755 -
4756 -void setup_highmem(unsigned long len)
4757 -{
4758 -       struct mem_region *region;
4759 -       struct page *page, *map;
4760 -       unsigned long phys;
4761 -       int i, cur, index;
4762 -
4763 -       phys = physmem_size;
4764 -       do {
4765 -               cur = min(len, (unsigned long) REGION_SIZE);
4766 -               i = setup_one_range(-1, NULL, -1, phys >> PAGE_SHIFT, cur, 
4767 -                                   NULL);
4768 -               if(i == -1){
4769 -                       printk("setup_highmem - setup_one_range failed\n");
4770 -                       return;
4771 -               }
4772 -               region = regions[i];
4773 -               index = phys / PAGE_SIZE;
4774 -               region->mem_map = &mem_map[index];
4775 -
4776 -               map = region->mem_map;
4777 -               for(i = 0; i < (cur >> PAGE_SHIFT); i++){
4778 -                       page = &map[i];
4779 -                       ClearPageReserved(page);
4780 -                       set_bit(PG_highmem, &page->flags);
4781 -                       set_page_count(page, 1);
4782 -                       __free_page(page);
4783 -               }
4784 -               phys += cur;
4785 -               len -= cur;
4786 -       } while(len > 0);
4787 -}
4788 -#endif
4789 +#endif /* CONFIG_HIGHMEM */
4790  
4791  void paging_init(void)
4792  {
4793 -       struct mem_region *region;
4794 -       unsigned long zones_size[MAX_NR_ZONES], start, end, vaddr;
4795 -       int i, index;
4796 +       unsigned long zones_size[MAX_NR_ZONES], vaddr;
4797 +       int i;
4798  
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++) 
4802                 zones_size[i] = 0;
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);
4815 -       }
4816  
4817         /*
4818          * Fixed mappings, only the page table structure has to be
4819 @@ -335,15 +197,33 @@
4820  
4821  #ifdef CONFIG_HIGHMEM
4822         init_highmem();
4823 -       setup_highmem(highmem);
4824  #endif
4825  }
4826  
4827 -pte_t __bad_page(void)
4828 +struct page *arch_validate(struct page *page, int mask, int order)
4829  {
4830 -       clear_page(empty_bad_page);
4831 -        return pte_mkdirty(mk_pte((struct page *) empty_bad_page, 
4832 -                                 PAGE_SHARED));
4833 +       unsigned long addr, zero = 0;
4834 +       int i;
4835 +
4836 + again:
4837 +       if(page == NULL) return(page);
4838 +       if(PageHighMem(page)) return(page);
4839 +
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, 
4844 +                                    sizeof(zero),
4845 +                                    &current->thread.fault_addr,
4846 +                                    &current->thread.fault_catcher)){
4847 +                       if(!(mask & __GFP_WAIT)) return(NULL);
4848 +                       else break;
4849 +               }
4850 +               addr += PAGE_SIZE;
4851 +       }
4852 +       if(i == (1 << order)) return(page);
4853 +       page = alloc_pages(mask, order);
4854 +       goto again;
4855  }
4856  
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);
4860  }
4861  
4862 -static int __init uml_mem_setup(char *line, int *add)
4863 -{
4864 -       char *retptr;
4865 -       physmem_size = memparse(line,&retptr);
4866 -       return 0;
4867 -}
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"
4876 -);
4877 -
4878 -struct page *arch_validate(struct page *page, int mask, int order)
4879 -{
4880 -       unsigned long addr, zero = 0;
4881 -       int i;
4882 -
4883 - again:
4884 -       if(page == NULL) return(page);
4885 -       if(PageHighMem(page)) return(page);
4886 -
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, 
4891 -                                    sizeof(zero),
4892 -                                    &current->thread.fault_addr,
4893 -                                    &current->thread.fault_catcher)){
4894 -                       if(!(mask & __GFP_WAIT)) return(NULL);
4895 -                       else break;
4896 -               }
4897 -               addr += PAGE_SIZE;
4898 -       }
4899 -       if(i == (1 << order)) return(page);
4900 -       page = alloc_pages(mask, order);
4901 -       goto again;
4902 -}
4903 -
4904 -DECLARE_MUTEX(vm_reserved_sem);
4905 -static struct list_head vm_reserved = LIST_HEAD_INIT(vm_reserved);
4906 -
4907 -/* Static structures, linked in to the list in early boot */
4908 -static struct vm_reserved head = {
4909 -       .list           = LIST_HEAD_INIT(head.list),
4910 -       .start          = 0,
4911 -       .end            = 0xffffffff
4912 -};
4913 -
4914 -static struct vm_reserved tail = {
4915 -       .list           = LIST_HEAD_INIT(tail.list),
4916 -       .start          = 0,
4917 -       .end            = 0xffffffff
4918 -};
4919 -
4920 -void set_usable_vm(unsigned long start, unsigned long end)
4921 -{
4922 -       list_add(&head.list, &vm_reserved);
4923 -       list_add(&tail.list, &head.list);
4924 -       head.end = start;
4925 -       tail.start = end;
4926 -}
4927 -
4928 -int reserve_vm(unsigned long start, unsigned long end, void *e)
4929 -              
4930 -{
4931 -       struct vm_reserved *entry = e, *reserved, *prev;
4932 -       struct list_head *ele;
4933 -       int err;
4934 -
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;
4939 -       }
4940 -       panic("Reserved vm out of range");
4941 - found:
4942 -       prev = list_entry(ele->prev, struct vm_reserved, list);
4943 -       if(prev->end > start)
4944 -               panic("Can't reserve vm");
4945 -       if(entry == NULL)
4946 -               entry = kmalloc(sizeof(*entry), GFP_KERNEL);
4947 -       if(entry == NULL){
4948 -               printk("reserve_vm : Failed to allocate entry\n");
4949 -               err = -ENOMEM;
4950 -               goto out;
4951 -       }
4952 -       *entry = ((struct vm_reserved) 
4953 -               { .list         = LIST_HEAD_INIT(entry->list),
4954 -                 .start        = start,
4955 -                 .end          = end });
4956 -       list_add(&entry->list, &prev->list);
4957 -       err = 0;
4958 - out:
4959 -       up(&vm_reserved_sem);
4960 -       return(0);
4961 -}
4962 -
4963 -unsigned long get_vm(unsigned long len)
4964 -{
4965 -       struct vm_reserved *this, *next;
4966 -       struct list_head *ele;
4967 -       unsigned long start;
4968 -       int err;
4969 -       
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))
4976 -                       goto found;
4977 -       }
4978 -       up(&vm_reserved_sem);
4979 -       return(0);
4980 - found:
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);
4985 -       return(start);
4986 -}
4987 -
4988 -int nregions(void)
4989 -{
4990 -       return(NREGIONS);
4991 -}
4992 -
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, 
4995 -                void *reserved)
4996 -{
4997 -       int i, cur;
4998 -
4999 -       do {
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)){
5004 -                       kfree(region);
5005 -                       regions[i] = NULL;
5006 -                       return;
5007 -               }
5008 -               start += cur;
5009 -               if(pfn != -1) pfn += cur;
5010 -               len -= cur;
5011 -       } while(len > 0);
5012 -}
5013 -
5014 -struct iomem {
5015 -       char *name;
5016 -       int fd;
5017 -       unsigned long size;
5018 -};
5019 -
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.
5022 - */
5023 -
5024 -struct iomem iomem_regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] =
5025 -                                        { .name        = NULL,
5026 -                                          .fd          = -1,
5027 -                                          .size        = 0 } };
5028 -
5029 -int num_iomem_regions = 0;
5030 -
5031 -void add_iomem(char *name, int fd, unsigned long size)
5032 -{
5033 -       if(num_iomem_regions == sizeof(iomem_regions)/sizeof(iomem_regions[0]))
5034 -               return;
5035 -       size = (size + PAGE_SIZE - 1) & PAGE_MASK;
5036 -       iomem_regions[num_iomem_regions++] = 
5037 -               ((struct iomem) { .name         = name,
5038 -                                 .fd           = fd,
5039 -                                 .size         = size } );
5040 -}
5041 -
5042 -int setup_iomem(void)
5043 -{
5044 -       struct iomem *iomem;
5045 -       int i;
5046 -
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, 
5050 -                           NULL, NULL);
5051 -       }
5052 -       return(0);
5053 -}
5054 -
5055 -__initcall(setup_iomem);
5056 -
5057 -#define PFN_UP(x)      (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
5058 -#define PFN_DOWN(x)    ((x) >> PAGE_SHIFT)
5059 -
5060 -/* Changed during early boot */
5061 -static struct mem_region physmem_region;
5062 -static struct vm_reserved physmem_reserved;
5063 -
5064 -void setup_physmem(unsigned long start, unsigned long reserve_end,
5065 -                  unsigned long len)
5066 -{
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;
5071 -
5072 -       do {
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 "
5080 -                             "reservation\n");
5081 -               setup_range(-1, NULL, start, pfn, cur, 1, region, reserved);
5082 -
5083 -               if(do_free){
5084 -                       unsigned long reserve = reserve_end - start;
5085 -                       int pfn = PFN_UP(__pa(reserve_end));
5086 -                       int delta = (len - reserve) >> PAGE_SHIFT;
5087 -
5088 -                       bootmap_size = init_bootmem(pfn, pfn + delta);
5089 -                       free_bootmem(__pa(reserve_end) + bootmap_size,
5090 -                                    cur - bootmap_size - reserve);
5091 -                       do_free = 0;
5092 -               }
5093 -               start += cur;
5094 -               pfn += cur >> PAGE_SHIFT;
5095 -               len -= cur;
5096 -               region = NULL;
5097 -               reserved = NULL;
5098 -       } while(len > 0);
5099 -}
5100 -
5101 -struct mem_region *phys_region(unsigned long phys)
5102 -{
5103 -       unsigned int n = phys_region_index(phys);
5104 -
5105 -       if(regions[n] == NULL) 
5106 -               panic("Physical address in uninitialized region");
5107 -       return(regions[n]);
5108 -}
5109 -
5110 -unsigned long phys_offset(unsigned long phys)
5111 -{
5112 -       return(phys_addr(phys));
5113 -}
5114 -
5115 -struct page *phys_mem_map(unsigned long phys)
5116 -{
5117 -       return((struct page *) phys_region(phys)->mem_map);
5118 -}
5119 -
5120 -struct page *pte_mem_map(pte_t pte)
5121 -{
5122 -       return(phys_mem_map(pte_val(pte)));
5123 -}
5124 -
5125 -struct mem_region *page_region(struct page *page, int *index_out)
5126 -{
5127 -       int i;
5128 -       struct mem_region *region;
5129 -       struct page *map;
5130 -
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;
5137 -                       return(region);
5138 -               }
5139 -       }
5140 -       panic("No region found for page");
5141 -       return(NULL);
5142 -}
5143 -
5144 -unsigned long page_to_pfn(struct page *page)
5145 -{
5146 -       struct mem_region *region = page_region(page, NULL);
5147 -
5148 -       return(region->start_pfn + (page - (struct page *) region->mem_map));
5149 -}
5150 -
5151 -struct mem_region *pfn_to_region(unsigned long pfn, int *index_out)
5152 -{
5153 -       struct mem_region *region;
5154 -       int i;
5155 -
5156 -       for(i = 0; i < NREGIONS; i++){
5157 -               region = regions[i];
5158 -               if(region == NULL)
5159 -                       continue;
5160 -
5161 -               if((region->start_pfn <= pfn) &&
5162 -                  (region->start_pfn + (region->len >> PAGE_SHIFT) > pfn)){
5163 -                       if(index_out != NULL) 
5164 -                               *index_out = i;
5165 -                       return(region);
5166 -               }
5167 -       }
5168 -       return(NULL);
5169 -}
5170 -
5171 -struct page *pfn_to_page(unsigned long pfn)
5172 -{
5173 -       struct mem_region *region = pfn_to_region(pfn, NULL);
5174 -       struct page *mem_map = (struct page *) region->mem_map;
5175 -
5176 -       return(&mem_map[pfn - region->start_pfn]);
5177 -}
5178 -
5179 -unsigned long phys_to_pfn(unsigned long p)
5180 -{
5181 -       struct mem_region *region = regions[phys_region_index(p)];
5182 -
5183 -       return(region->start_pfn + (phys_addr(p) >> PAGE_SHIFT));
5184 -}
5185 -
5186 -unsigned long pfn_to_phys(unsigned long pfn)
5187 -{
5188 -       int n;
5189 -       struct mem_region *region = pfn_to_region(pfn, &n);
5190 -
5191 -       return(mk_phys((pfn - region->start_pfn) << PAGE_SHIFT, n));
5192 -}
5193 -
5194 -struct page *page_mem_map(struct page *page)
5195 -{
5196 -       return((struct page *) page_region(page, NULL)->mem_map);
5197 -}
5198 -
5199 -extern unsigned long region_pa(void *virt)
5200 -{
5201 -       struct mem_region *region;
5202 -       unsigned long addr = (unsigned long) virt;
5203 -       int i;
5204 -
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));
5211 -       }
5212 -       panic("region_pa : no region for virtual address");
5213 -       return(0);
5214 -}
5215 -
5216 -extern void *region_va(unsigned long phys)
5217 -{
5218 -       return((void *) (phys_region(phys)->start + phys_addr(phys)));
5219 -}
5220 -
5221 -unsigned long page_to_phys(struct page *page)
5222 -{
5223 -       int n;
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));
5227 -}
5228 -
5229 -struct page *phys_to_page(unsigned long phys)
5230 -{
5231 -       struct page *mem_map;
5232 -
5233 -       mem_map = phys_mem_map(phys);
5234 -       return(mem_map + (phys_offset(phys) >> PAGE_SHIFT));
5235 -}
5236 -
5237 -static int setup_mem_maps(void)
5238 -{
5239 -       struct mem_region *region;
5240 -       int i;
5241 -
5242 -       for(i = 0; i < NREGIONS; i++){
5243 -               region = regions[i];
5244 -               if((region != NULL) && (region->fd > 0)) init_maps(region);
5245 -       }
5246 -       return(0);
5247 -}
5248 -
5249 -__initcall(setup_mem_maps);
5250 -
5251  /*
5252   * Allocate and free page tables.
5253   */
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
5258 @@ -279,6 +279,8 @@
5259         LIST_HEAD(list);
5260         int i;
5261  
5262 +       arch_free_page(page, order);
5263 +
5264         mod_page_state(pgfree, 1 << order);
5265         for (i = 0 ; i < (1 << order) ; ++i)
5266                 free_pages_check(__FUNCTION__, page + i);
5267 @@ -497,6 +499,8 @@
5268         struct per_cpu_pages *pcp;
5269         unsigned long flags;
5270  
5271 +       arch_free_page(page, 0);
5272 +
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
5280 @@ -0,0 +1,219 @@
5281 +/* 
5282 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
5283 + * Licensed under the GPL
5284 + */
5285 +
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"
5295 +
5296 +extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr, 
5297 +                            pte_t *pte_out);
5298 +
5299 +static unsigned long maybe_map(unsigned long virt, int is_write)
5300 +{
5301 +       pte_t pte;
5302 +       int err;
5303 +
5304 +       void *phys = um_virt_to_phys(current, virt, &pte);
5305 +       int dummy_code;
5306 +
5307 +       if(IS_ERR(phys) || (is_write && !pte_write(pte))){
5308 +               err = handle_page_fault(virt, 0, is_write, 0, &dummy_code);
5309 +               if(err)
5310 +                       return(0);
5311 +               phys = um_virt_to_phys(current, virt, NULL);
5312 +       }
5313 +       return((unsigned long) phys);
5314 +}
5315 +
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)
5318 +{
5319 +       struct page *page;
5320 +       int n;
5321 +
5322 +       addr = maybe_map(addr, is_write);
5323 +       if(addr == -1)
5324 +               return(-1);
5325 +
5326 +       page = phys_to_page(addr);
5327 +       addr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK);
5328 +       n = (*op)(addr, len, arg);
5329 +       kunmap(page);
5330 +
5331 +       return(n);
5332 +}
5333 +
5334 +static int buffer_op(unsigned long addr, int len, int is_write,
5335 +                    int (*op)(unsigned long addr, int len, void *arg),
5336 +                    void *arg)
5337 +{
5338 +       int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
5339 +       int remain = len, n;
5340 +
5341 +       n = do_op(addr, size, is_write, op, arg);
5342 +       if(n != 0)
5343 +               return(n < 0 ? remain : 0);
5344 +
5345 +       addr += size;
5346 +       remain -= size;
5347 +       if(remain == 0) 
5348 +               return(0);
5349 +
5350 +       while(addr < ((addr + remain) & PAGE_MASK)){
5351 +               n = do_op(addr, PAGE_SIZE, is_write, op, arg);
5352 +               if(n != 0)
5353 +                       return(n < 0 ? remain : 0);
5354 +
5355 +               addr += PAGE_SIZE;
5356 +               remain -= PAGE_SIZE;
5357 +       }
5358 +       if(remain == 0)
5359 +               return(0);
5360 +
5361 +       n = do_op(addr, remain, is_write, op, arg);
5362 +       if(n != 0)
5363 +               return(n < 0 ? remain : 0);
5364 +       return(0);
5365 +}
5366 +
5367 +static int copy_chunk_from_user(unsigned long from, int len, void *arg)
5368 +{
5369 +       unsigned long *to_ptr = arg, to = *to_ptr;
5370 +
5371 +       memcpy((void *) to, (void *) from, len);
5372 +       *to_ptr += len;
5373 +       return(0);
5374 +}
5375 +
5376 +int copy_from_user_skas(void *to, const void *from, int n)
5377 +{
5378 +       if(segment_eq(get_fs(), KERNEL_DS)){
5379 +               memcpy(to, from, n);
5380 +               return(0);
5381 +       }
5382 +
5383 +       return(access_ok_skas(VERIFY_READ, from, n) ?
5384 +              buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
5385 +              n);
5386 +}
5387 +
5388 +static int copy_chunk_to_user(unsigned long to, int len, void *arg)
5389 +{
5390 +       unsigned long *from_ptr = arg, from = *from_ptr;
5391 +
5392 +       memcpy((void *) to, (void *) from, len);
5393 +       *from_ptr += len;
5394 +       return(0);
5395 +}
5396 +
5397 +int copy_to_user_skas(void *to, const void *from, int n)
5398 +{
5399 +       if(segment_eq(get_fs(), KERNEL_DS)){
5400 +               memcpy(to, from, n);
5401 +               return(0);
5402 +       }
5403 +
5404 +       return(access_ok_skas(VERIFY_WRITE, to, n) ?
5405 +              buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
5406 +              n);
5407 +}
5408 +
5409 +static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
5410 +{
5411 +       char **to_ptr = arg, *to = *to_ptr;
5412 +       int n;
5413 +
5414 +       strncpy(to, (void *) from, len);
5415 +       n = strnlen(to, len);
5416 +       *to_ptr += n;
5417 +
5418 +       if(n < len) 
5419 +               return(1);
5420 +       return(0);
5421 +}
5422 +
5423 +int strncpy_from_user_skas(char *dst, const char *src, int count)
5424 +{
5425 +       int n;
5426 +       char *ptr = dst;
5427 +
5428 +       if(segment_eq(get_fs(), KERNEL_DS)){
5429 +               strncpy(dst, src, count);
5430 +               return(strnlen(dst, count));
5431 +       }
5432 +
5433 +       if(!access_ok_skas(VERIFY_READ, src, 1))
5434 +               return(-EFAULT);
5435 +
5436 +       n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user, 
5437 +                     &ptr);
5438 +       if(n != 0)
5439 +               return(-EFAULT);
5440 +       return(strnlen(dst, count));
5441 +}
5442 +
5443 +static int clear_chunk(unsigned long addr, int len, void *unused)
5444 +{
5445 +       memset((void *) addr, 0, len);
5446 +       return(0);
5447 +}
5448 +
5449 +int __clear_user_skas(void *mem, int len)
5450 +{
5451 +       return(buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL));
5452 +}
5453 +
5454 +int clear_user_skas(void *mem, int len)
5455 +{
5456 +       if(segment_eq(get_fs(), KERNEL_DS)){
5457 +               memset(mem, 0, len);
5458 +               return(0);
5459 +       }
5460 +
5461 +       return(access_ok_skas(VERIFY_WRITE, mem, len) ? 
5462 +              buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len);
5463 +}
5464 +
5465 +static int strnlen_chunk(unsigned long str, int len, void *arg)
5466 +{
5467 +       int *len_ptr = arg, n;
5468 +
5469 +       n = strnlen((void *) str, len);
5470 +       *len_ptr += n;
5471 +
5472 +       if(n < len)
5473 +               return(1);
5474 +       return(0);
5475 +}
5476 +
5477 +int strnlen_user_skas(const void *str, int len)
5478 +{
5479 +       int count = 0, n;
5480 +
5481 +       if(segment_eq(get_fs(), KERNEL_DS))
5482 +               return(strnlen(str, len) + 1);
5483 +
5484 +       n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count);
5485 +       if(n == 0)
5486 +               return(count + 1);
5487 +       return(-EFAULT);
5488 +}
5489 +
5490 +/*
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
5494 + * of the file.
5495 + * ---------------------------------------------------------------------------
5496 + * Local variables:
5497 + * c-file-style: "linux"
5498 + * End:
5499 + */
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
5504 @@ -22,17 +22,21 @@
5505                            $(ARCH_DIR)/sys-$(SUBARCH)/
5506  
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))
5514  
5515  ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
5516         $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
5517  
5518  GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
5519  
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).
5524 +
5525 +.PHONY: sys_prepare
5526 +sys_prepare:
5527 +       @:
5528  
5529  MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
5530  MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
5531 @@ -41,6 +45,9 @@
5532    include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
5533  endif
5534  
5535 +include $(ARCH_DIR)/Makefile-$(SUBARCH)
5536 +include $(ARCH_DIR)/Makefile-os-$(OS)
5537 +
5538  EXTRAVERSION := $(EXTRAVERSION)-1um
5539  
5540  ARCH_INCLUDE = -I$(ARCH_DIR)/include
5541 @@ -52,14 +59,22 @@
5542  
5543  CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
5544         -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
5545 -       $(MODE_INCLUDE)
5546 +       -Dsigprocmask=kernel_sigprocmask $(MODE_INCLUDE)
5547 +
5548 +CFLAGS += $(call check_gcc,-fno-unit-at-a-time,)
5549  
5550  LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
5551  
5552 +# These are needed for clean and mrproper, since in that case .config is not
5553 +# included; the values here are meaningless
5554 +
5555 +CONFIG_NEST_LEVEL ?= 0
5556 +CONFIG_KERNEL_HALF_GIGS ?=  0
5557 +
5558  SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
5559  
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
5563  endif
5564  
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)) ] )
5569  
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))
5576  
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
5579  
5580  LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y)
5581  
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)
5586  
5587  linux: vmlinux $(LD_SCRIPT-y)
5588         $(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \
5589 @@ -116,37 +131,47 @@
5590  
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) \
5595         $(MODE_INCLUDE)
5596  
5597  # To get a definition of F_SETSIG
5598  USER_CFLAGS += -D_GNU_SOURCE
5599  
5600 +# From main Makefile, these options are set after including the ARCH makefile.
5601 +# So copy them here.
5602 +
5603 +ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
5604 +USER_CFLAGS            += -Os
5605 +else
5606 +USER_CFLAGS            += -O2
5607 +endif
5608 +
5609 +ifndef CONFIG_FRAME_POINTER
5610 +USER_CFLAGS            += -fomit-frame-pointer
5611 +endif
5612 +
5613 +ifdef CONFIG_DEBUG_INFO
5614 +USER_CFLAGS            += -g
5615 +endif
5616 +
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 \
5620 +       $(GEN_HEADERS)
5621 +
5622 +MRPROPER_FILES += $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) \
5623 +       $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS))
5624  
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
5628 +       @ echo '  MAIN    $@'
5629 +       @ $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
5630  
5631  archmrproper:
5632 -       for d in $(ARCH_SUBDIRS) $(ARCH_DIR)/util; \
5633 -       do \
5634 -               $(MAKE) -C $$d archmrproper; \
5635 -       done
5636 -       rm -f $(CLEAN_FILES) $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) include/asm \
5637 -               $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS))
5638 -
5639 -archclean: sysclean
5640 -       for d in $(ARCH_SUBDIRS) $(ARCH_DIR)/util; \
5641 -       do \
5642 -               $(MAKE) -C $$d clean; \
5643 -       done
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)
5647 +       @:
5648  
5649 -archdep: 
5650 -       for d in $(ARCH_SUBDIRS); do $(MAKE) -C $$d fastdep; done
5651 +archclean:
5652 +       @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
5653 +               -o -name '*.gcov' \) -type f -print | xargs rm -f
5654  
5655  $(SYMLINK_HEADERS):
5656         cd $(TOPDIR)/$(dir $@) ; \
5657 @@ -161,19 +186,32 @@
5658  $(ARCH_DIR)/os:
5659         cd $(ARCH_DIR) && ln -sf os-$(OS) os
5660  
5661 -$(ARCH_DIR)/include/uml-config.h :
5662 -       sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@
5663 +# Generated files
5664 +define filechk_umlconfig
5665 +       sed 's/ CONFIG/ UML_CONFIG/'
5666 +endef
5667 +
5668 +$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h
5669 +       $(call filechk,umlconfig)
5670 +
5671 +filechk_gen_header = $<
5672  
5673  $(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
5674 -       $< > $@
5675 +       $(call filechk,gen_header)
5676  
5677  $(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
5678 -       $< > $@
5679 +       $(call filechk,gen_header)
5680  
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 ;
5685  
5686  $(ARCH_DIR)/util: FORCE
5687 -       @$(call descend,$@,)
5688 +       $(Q)$(MAKE) $(build)=$@
5689 +
5690 +export SUBARCH USER_CFLAGS OS 
5691 +
5692 +all: linux
5693  
5694 -export SUBARCH USER_CFLAGS OS
5695 +define archhelp
5696 +  echo  '* linux       - Binary kernel image (./linux)'
5697 +endef
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
5702 @@ -3,10 +3,7 @@
5703   * Licensed under the GPL
5704   */
5705  
5706 -#include <stdio.h>
5707 -#include <errno.h>
5708  #include <sys/mman.h>
5709 -#include "user.h"
5710  
5711  int switcheroo(int fd, int prot, void *from, void *to, int size)
5712  {
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
5717 @@ -9,5 +9,3 @@
5718  
5719  $(USER_OBJS) : %.o: %.c
5720         $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
5721 -
5722 -clean:
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
5727 @@ -34,10 +34,9 @@
5728  #include <stddef.h>
5729  #include <stdarg.h>
5730  #include <unistd.h>
5731 -#include <fcntl.h>
5732  #include <errno.h>
5733  #include <string.h>
5734 -#include <sys/stat.h>
5735 +#include <fcntl.h>
5736  #include <sys/types.h>
5737  #include <sys/mman.h>
5738  #include "kern_util.h"
5739 @@ -47,105 +46,145 @@
5740  #include "init.h"
5741  #include "os.h"
5742  #include "tempfile.h"
5743 +#include "kern_constants.h"
5744  
5745  extern struct mem_region physmem_region;
5746  
5747  #define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
5748  
5749 -int create_mem_file(unsigned long len)
5750 +static int create_tmp_file(unsigned long len)
5751  {
5752 -       int fd;
5753 +       int fd, err;
5754         char zero;
5755  
5756         fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
5757 -       if (fchmod(fd, 0777) < 0){
5758 -               perror("fchmod");
5759 +       if(fd < 0) {
5760 +               os_print_error(fd, "make_tempfile");
5761 +               exit(1);
5762 +       }
5763 +
5764 +       err = os_mode_fd(fd, 0777);
5765 +       if(err < 0){
5766 +               os_print_error(err, "os_mode_fd");
5767                 exit(1);
5768         }
5769 -       if(os_seek_file(fd, len) < 0){
5770 -               perror("lseek");
5771 +       err = os_seek_file(fd, len);
5772 +       if(err < 0){
5773 +               os_print_error(err, "os_seek_file");
5774                 exit(1);
5775         }
5776         zero = 0;
5777 -       if(write(fd, &zero, 1) != 1){
5778 -               perror("write");
5779 +       err = os_write_file(fd, &zero, 1);
5780 +       if(err != 1){
5781 +               os_print_error(err, "os_write_file");
5782                 exit(1);
5783         }
5784 -       if(fcntl(fd, F_SETFD, 1) != 0)
5785 -               perror("Setting FD_CLOEXEC failed");
5786 +
5787         return(fd);
5788  }
5789  
5790 -int setup_region(struct mem_region *region, void *entry)
5791 +static int have_devanon = 0;
5792 +
5793 +void check_devanon(void)
5794 +{
5795 +       int fd;
5796 +
5797 +       printk("Checking for /dev/anon on the host...");
5798 +       fd = open("/dev/anon", O_RDWR);
5799 +       if(fd < 0){
5800 +               printk("Not available (open failed with errno %d)\n", errno);
5801 +               return;
5802 +       }
5803 +
5804 +       printk("OK\n");
5805 +       have_devanon = 1;
5806 +}
5807 +
5808 +static int create_anon_file(unsigned long len)
5809  {
5810 -       void *loc, *start;
5811 -       char *driver;
5812 -       int err, offset;
5813 -
5814 -       if(region->start != -1){
5815 -               err = reserve_vm(region->start, 
5816 -                                region->start + region->len, entry);
5817 -               if(err){
5818 -                       printk("setup_region : failed to reserve "
5819 -                              "0x%x - 0x%x for driver '%s'\n",
5820 -                              region->start, 
5821 -                              region->start + region->len,
5822 -                              region->driver);
5823 -                       return(-1);
5824 -               }
5825 -       }
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);
5832 -               return(-1);
5833 -       }
5834 -       if(region->start == uml_physmem){
5835 -               start = (void *) uml_reserved;
5836 -               offset = uml_reserved - uml_physmem;
5837 -       }
5838 -       else {
5839 -               start = (void *) region->start;
5840 -               offset = 0;
5841 -       }
5842 -
5843 -       loc = mmap(start, region->len - offset, PROT_READ | PROT_WRITE, 
5844 -                  MAP_SHARED | MAP_FIXED, region->fd, offset);
5845 -       if(loc != start){
5846 -               perror("Mapping memory");
5847 +       void *addr;
5848 +       int fd;
5849 +
5850 +       fd = open("/dev/anon", O_RDWR);
5851 +       if(fd < 0) {
5852 +               os_print_error(fd, "opening /dev/anon");
5853                 exit(1);
5854         }
5855 -       return(0);
5856 +
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");
5860 +               exit(1);
5861 +       }
5862 +       munmap(addr, len);
5863 +
5864 +       return(fd);
5865 +}
5866 +
5867 +int create_mem_file(unsigned long len)
5868 +{
5869 +       int err, fd;
5870 +
5871 +       if(have_devanon)
5872 +               fd = create_anon_file(len);
5873 +       else fd = create_tmp_file(len);
5874 +
5875 +       err = os_set_exec_close(fd, 1);
5876 +       if(err < 0)
5877 +               os_print_error(err, "exec_close");
5878 +       return(fd);
5879  }
5880  
5881 +struct iomem_region *iomem_regions = NULL;
5882 +int iomem_size = 0;
5883 +
5884  static int __init parse_iomem(char *str, int *add)
5885  {
5886 -       struct stat buf;
5887 +       struct iomem_region *new;
5888 +       struct uml_stat buf;
5889         char *file, *driver;
5890 -       int fd;
5891 +       int fd, err;
5892  
5893         driver = str;
5894         file = strchr(str,',');
5895         if(file == NULL){
5896 -               printk("parse_iomem : failed to parse iomem\n");
5897 -               return(1);
5898 +               printf("parse_iomem : failed to parse iomem\n");
5899 +               goto out;
5900         }
5901         *file = '\0';
5902         file++;
5903         fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
5904         if(fd < 0){
5905 -               printk("parse_iomem - Couldn't open io file, errno = %d\n", 
5906 -                      errno);
5907 -               return(1);
5908 -       }
5909 -       if(fstat(fd, &buf) < 0) {
5910 -               printk("parse_iomem - cannot fstat file, errno = %d\n", errno);
5911 -               return(1);
5912 +               os_print_error(fd, "parse_iomem - Couldn't open io file");
5913 +               goto out;
5914         }
5915 -       add_iomem(driver, fd, buf.st_size);
5916 +
5917 +       err = os_stat_fd(fd, &buf);
5918 +       if(err < 0){
5919 +               os_print_error(err, "parse_iomem - cannot stat_fd file");
5920 +               goto out_close;
5921 +       }
5922 +
5923 +       new = malloc(sizeof(*new));
5924 +       if(new == NULL){
5925 +               perror("Couldn't allocate iomem_region struct");
5926 +               goto out_close;
5927 +       }
5928 +
5929 +       *new = ((struct iomem_region) { .next           = iomem_regions,
5930 +                                       .driver         = driver,
5931 +                                       .fd             = fd,
5932 +                                       .size           = buf.ust_size,
5933 +                                       .phys           = 0,
5934 +                                       .virt           = 0 });
5935 +       iomem_regions = new;
5936 +       iomem_size += new->size + UM_KERN_PAGE_SIZE;
5937 +
5938         return(0);
5939 + out_close:
5940 +       os_close_file(fd);
5941 + out:
5942 +       return(1);
5943  }
5944  
5945  __uml_setup("iomem=", parse_iomem,
5946 @@ -153,73 +192,20 @@
5947  "    Configure <file> as an IO memory region named <name>.\n\n"
5948  );
5949  
5950 -#ifdef notdef
5951 -int logging = 0;
5952 -int logging_fd = -1;
5953 -
5954 -int logging_line = 0;
5955 -char logging_buf[256];
5956 -
5957 -void log(char *fmt, ...)
5958 -{
5959 -       va_list ap;
5960 -       struct timeval tv;
5961 -       struct openflags flags;
5962 -
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);
5967 -       }
5968 -       gettimeofday(&tv, NULL);
5969 -       sprintf(logging_buf, "%d\t %u.%u  ", logging_line++, tv.tv_sec, 
5970 -               tv.tv_usec);
5971 -       va_start(ap, fmt);
5972 -       vsprintf(&logging_buf[strlen(logging_buf)], fmt, ap);
5973 -       va_end(ap);
5974 -       write(logging_fd, logging_buf, strlen(logging_buf));
5975 -}
5976 -#endif
5977 -
5978 -int map_memory(unsigned long virt, unsigned long phys, unsigned long len, 
5979 -              int r, int w, int x)
5980 -{
5981 -       struct mem_region *region = phys_region(phys);
5982 -
5983 -       return(os_map_memory((void *) virt, region->fd, phys_offset(phys), len,
5984 -                            r, w, x));
5985 -}
5986 -
5987  int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
5988                    int must_succeed)
5989  {
5990 -       if(os_protect_memory((void *) addr, len, r, w, x) < 0){
5991 +       int err;
5992 +
5993 +       err = os_protect_memory((void *) addr, len, r, w, x);
5994 +       if(err < 0){
5995                  if(must_succeed)
5996 -                        panic("protect failed, errno = %d", errno);
5997 -                else return(-errno);
5998 +                       panic("protect failed, err = %d", -err);
5999 +               else return(err);
6000         }
6001         return(0);
6002  }
6003  
6004 -unsigned long find_iomem(char *driver, unsigned long *len_out)
6005 -{
6006 -       struct mem_region *region;
6007 -       int i, n;
6008 -
6009 -       n = nregions();
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);
6017 -               }
6018 -       }
6019 -       *len_out = 0;
6020 -       return 0;
6021 -}
6022 -
6023  /*
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
6030 @@ -8,7 +8,6 @@
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"
6038 @@ -18,7 +17,7 @@
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);
6042 -
6043 +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
6044  EXPORT_SYMBOL(init_mm);
6045  
6046  /*
6047 @@ -43,26 +42,12 @@
6048  __attribute__((__section__(".data.init_task"))) = 
6049  { INIT_THREAD_INFO(init_task) };
6050  
6051 -struct task_struct *alloc_task_struct(void)
6052 -{
6053 -       return((struct task_struct *) 
6054 -              __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
6055 -}
6056 -
6057  void unprotect_stack(unsigned long stack)
6058  {
6059         protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE, 
6060                        1, 1, 0, 1);
6061  }
6062  
6063 -void free_task_struct(struct task_struct *task)
6064 -{
6065 -       /* free_pages decrements the page counter and only actually frees
6066 -        * the pages if they are now not accessed by anything.
6067 -        */
6068 -       free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
6069 -}
6070 -
6071  /*
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
6078 @@ -9,10 +9,10 @@
6079  #include <stdio.h>
6080  #include <stdlib.h>
6081  #include <unistd.h>
6082 -#include <fcntl.h>
6083  #include <sys/time.h>
6084  #include "init.h"
6085  #include "user.h"
6086 +#include "kern_util.h"
6087  #include "os.h"
6088  
6089  #define TTY_LOG_DIR "./"
6090 @@ -24,29 +24,40 @@
6091  #define TTY_LOG_OPEN 1
6092  #define TTY_LOG_CLOSE 2
6093  #define TTY_LOG_WRITE 3
6094 +#define TTY_LOG_EXEC 4
6095 +
6096 +#define TTY_READ 1
6097 +#define TTY_WRITE 2
6098  
6099  struct tty_log_buf {
6100         int what;
6101         unsigned long tty;
6102         int len;
6103 +       int direction;
6104 +       unsigned long sec;
6105 +       unsigned long usec;
6106  };
6107  
6108 -int open_tty_log(void *tty)
6109 +int open_tty_log(void *tty, void *current_tty)
6110  {
6111         struct timeval tv;
6112         struct tty_log_buf data;
6113         char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
6114         int fd;
6115  
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,
6120 -                                              len : 0 });
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),
6125 +                                              .direction = 0,
6126 +                                              .sec = tv.tv_sec,
6127 +                                              .usec = tv.tv_usec } );
6128 +               os_write_file(tty_log_fd, &data, sizeof(data));
6129 +               os_write_file(tty_log_fd, &current_tty, data.len);
6130                 return(tty_log_fd);
6131         }
6132  
6133 -       gettimeofday(&tv, NULL);
6134         sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, 
6135                 (unsigned int) tv.tv_usec);
6136  
6137 @@ -62,30 +73,117 @@
6138  void close_tty_log(int fd, void *tty)
6139  {
6140         struct tty_log_buf data;
6141 +       struct timeval tv;
6142  
6143         if(tty_log_fd != -1){
6144 -               data = ((struct tty_log_buf) { what :   TTY_LOG_CLOSE,
6145 -                                              tty : (unsigned long) tty,
6146 -                                              len : 0 });
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,
6151 +                                              .len  = 0,
6152 +                                              .direction = 0,
6153 +                                              .sec = tv.tv_sec,
6154 +                                              .usec = tv.tv_usec } );
6155 +               os_write_file(tty_log_fd, &data, sizeof(data));
6156                 return;
6157         }
6158 -       close(fd);
6159 +       os_close_file(fd);
6160  }
6161  
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)
6164  {
6165 +       int total = 0, try, missed, n;
6166 +       char chunk[64];
6167 +
6168 +       while(len > 0){
6169 +               try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
6170 +               missed = copy_from_user_proc(chunk, (char *) buf, try);
6171 +               try -= missed;
6172 +               n = os_write_file(fd, chunk, try);
6173 +               if(n != try) {
6174 +                       if(n < 0) 
6175 +                               return(n);
6176 +                       return(-EIO);
6177 +               }
6178 +               if(missed != 0)
6179 +                       return(-EFAULT);
6180 +
6181 +               len -= try;
6182 +               total += try;
6183 +               buf += try;
6184 +       }
6185 +
6186 +       return(total);
6187 +}
6188 +
6189 +int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
6190 +{
6191 +       struct timeval tv;
6192         struct tty_log_buf data;
6193 +       int direction;
6194  
6195         if(fd == tty_log_fd){
6196 -               data = ((struct tty_log_buf) { what :   TTY_LOG_WRITE,
6197 -                                              tty : (unsigned long) tty,
6198 -                                              len : len });
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,
6204 +                                              .len  = len,
6205 +                                              .direction = direction,
6206 +                                              .sec = tv.tv_sec,
6207 +                                              .usec = tv.tv_usec } );
6208 +               os_write_file(tty_log_fd, &data, sizeof(data));
6209         }
6210 -       return(write(fd, buf, len));
6211 +
6212 +       return(log_chunk(fd, buf, len));
6213  }
6214  
6215 +void log_exec(char **argv, void *tty)
6216 +{
6217 +       struct timeval tv;
6218 +       struct tty_log_buf data;
6219 +       char **ptr,*arg;
6220 +       int len;
6221 +       
6222 +       if(tty_log_fd == -1) return;
6223 +
6224 +       gettimeofday(&tv, NULL);
6225 +
6226 +       len = 0;
6227 +       for(ptr = argv; ; ptr++){
6228 +               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
6229 +                       return;
6230 +               if(arg == NULL) break;
6231 +               len += strlen_user_proc(arg);
6232 +       }
6233 +
6234 +       data = ((struct tty_log_buf) { .what    = TTY_LOG_EXEC,
6235 +                                      .tty  = (unsigned long) tty,
6236 +                                      .len  = len,
6237 +                                      .direction = 0,
6238 +                                      .sec = tv.tv_sec,
6239 +                                      .usec = tv.tv_usec } );
6240 +       os_write_file(tty_log_fd, &data, sizeof(data));
6241 +
6242 +       for(ptr = argv; ; ptr++){
6243 +               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
6244 +                       return;
6245 +               if(arg == NULL) break;
6246 +               log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
6247 +       }
6248 +}
6249 +
6250 +extern void register_tty_logger(int (*opener)(void *, void *),
6251 +                               int (*writer)(int, const char *, int, 
6252 +                                             void *, int),
6253 +                               void (*closer)(int, void *));
6254 +
6255 +static int register_logger(void)
6256 +{
6257 +       register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
6258 +       return(0);
6259 +}
6260 +
6261 +__uml_initcall(register_logger);
6262 +
6263  static int __init set_tty_log_dir(char *name, int *add)
6264  {
6265         tty_log_dir = name;
6266 @@ -104,7 +202,7 @@
6267  
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);
6272                 tty_log_fd = -1;
6273         }
6274         return 0;
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
6279 @@ -16,6 +16,7 @@
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"
6287 @@ -23,7 +24,6 @@
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"
6295 @@ -52,17 +52,12 @@
6296  
6297  struct task_struct *get_task(int pid, int require)
6298  {
6299 -        struct task_struct *task, *ret;
6300 +        struct task_struct *ret;
6301  
6302 -        ret = NULL;
6303          read_lock(&tasklist_lock);
6304 -        for_each_process(task){
6305 -                if(task->pid == pid){
6306 -                        ret = task;
6307 -                        break;
6308 -                }
6309 -        }
6310 +       ret = find_task_by_pid(pid);
6311          read_unlock(&tasklist_lock);
6312 +
6313          if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
6314          return(ret);
6315  }
6316 @@ -95,7 +90,8 @@
6317         int flags = GFP_KERNEL;
6318  
6319         if(atomic) flags |= GFP_ATOMIC;
6320 -       if((page = __get_free_pages(flags, order)) == 0)
6321 +       page = __get_free_pages(flags, order);
6322 +       if(page == 0)
6323                 return(0);
6324         stack_protections(page);
6325         return(page);
6326 @@ -103,13 +99,15 @@
6327  
6328  int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
6329  {
6330 -       struct task_struct *p;
6331 +       int pid;
6332  
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");
6337 -       return(p->pid);
6338 +       pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, NULL, 0, NULL, 
6339 +                     NULL);
6340 +       if(pid < 0)
6341 +               panic("do_fork failed in kernel_thread, errno = %d", pid);
6342 +       return(pid);
6343  }
6344  
6345  void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
6346 @@ -129,7 +127,7 @@
6347                 { external_pid(task), task });
6348  }
6349  
6350 -void *switch_to(void *prev, void *next, void *last)
6351 +void *_switch_to(void *prev, void *next, void *last)
6352  {
6353         return(CHOOSE_MODE(switch_to_tt(prev, next), 
6354                            switch_to_skas(prev, next)));
6355 @@ -149,7 +147,7 @@
6356  void exit_thread(void)
6357  {
6358         CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
6359 -       unprotect_stack((unsigned long) current->thread_info);
6360 +       unprotect_stack((unsigned long) current_thread);
6361  }
6362   
6363  void *get_current(void)
6364 @@ -157,6 +155,10 @@
6365         return(current);
6366  }
6367  
6368 +void prepare_to_copy(struct task_struct *tsk)
6369 +{
6370 +}
6371 +
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)
6375 @@ -190,7 +192,7 @@
6376  
6377  void default_idle(void)
6378  {
6379 -       idle_timer();
6380 +       uml_idle_timer();
6381  
6382         atomic_inc(&init_mm.mm_count);
6383         current->mm = &init_mm;
6384 @@ -367,10 +369,15 @@
6385         return(clear_user(buf, size));
6386  }
6387  
6388 +int strlen_user_proc(char *str)
6389 +{
6390 +       return(strlen_user(str));
6391 +}
6392 +
6393  int smp_sigio_handler(void)
6394  {
6395  #ifdef CONFIG_SMP
6396 -       int cpu = current->thread_info->cpu;
6397 +       int cpu = current_thread->cpu;
6398         IPI_handler(cpu);
6399         if(cpu != 0)
6400                 return(1);
6401 @@ -385,7 +392,7 @@
6402  
6403  int cpu(void)
6404  {
6405 -       return(current->thread_info->cpu);
6406 +       return(current_thread->cpu);
6407  }
6408  
6409  /*
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
6414 @@ -228,7 +228,6 @@
6415  CONFIG_EXT2_FS=y
6416  CONFIG_SYSV_FS=m
6417  CONFIG_UDF_FS=m
6418 -# CONFIG_UDF_RW is not set
6419  CONFIG_UFS_FS=m
6420  # CONFIG_UFS_FS_WRITE is not set
6421  
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
6426 @@ -0,0 +1,1022 @@
6427 +/* 
6428 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
6429 + * Licensed under the GPL
6430 + *
6431 + * Ported the filesystem routines to 2.5.
6432 + * 2003-02-10 Petr Baudis <pasky@ucw.cz>
6433 + */
6434 +
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"
6450 +#include "kern.h"
6451 +#include "user_util.h"
6452 +#include "2_5compat.h"
6453 +#include "init.h"
6454 +
6455 +struct hostfs_inode_info {
6456 +       char *host_filename;
6457 +       int fd;
6458 +       int mode;
6459 +       struct inode vfs_inode;
6460 +};
6461 +
6462 +static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
6463 +{
6464 +       return(list_entry(inode, struct hostfs_inode_info, vfs_inode));
6465 +}
6466 +
6467 +#define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_dentry->d_inode)
6468 +
6469 +int hostfs_d_delete(struct dentry *dentry)
6470 +{
6471 +       return(1);
6472 +}
6473 +
6474 +struct dentry_operations hostfs_dentry_ops = {
6475 +       .d_delete               = hostfs_d_delete,
6476 +};
6477 +
6478 +/* Changed in hostfs_args before the kernel starts running */
6479 +static char *root_ino = "/";
6480 +static int append = 0;
6481 +
6482 +#define HOSTFS_SUPER_MAGIC 0x00c0ffee
6483 +
6484 +static struct inode_operations hostfs_iops;
6485 +static struct inode_operations hostfs_dir_iops;
6486 +static struct address_space_operations hostfs_link_aops;
6487 +
6488 +#ifndef MODULE
6489 +static int __init hostfs_args(char *options, int *add)
6490 +{
6491 +       char *ptr;
6492 +
6493 +       ptr = strchr(options, ',');
6494 +       if(ptr != NULL)
6495 +               *ptr++ = '\0';
6496 +       if(*options != '\0')
6497 +               root_ino = options;
6498 +
6499 +       options = ptr;
6500 +       while(options){
6501 +               ptr = strchr(options, ',');
6502 +               if(ptr != NULL)
6503 +                       *ptr++ = '\0';
6504 +               if(*options != '\0'){
6505 +                       if(!strcmp(options, "append"))
6506 +                               append = 1;
6507 +                       else printf("hostfs_args - unsupported option - %s\n",
6508 +                                   options);
6509 +               }
6510 +               options = ptr;
6511 +       }
6512 +       return(0);
6513 +}
6514 +
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"
6521 +"    it.\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"
6524 +);
6525 +#endif
6526 +
6527 +static char *dentry_name(struct dentry *dentry, int extra)
6528 +{
6529 +       struct dentry *parent;
6530 +       char *root, *name;
6531 +       int len;
6532 +
6533 +       len = 0;
6534 +       parent = dentry;
6535 +       while(parent->d_parent != parent){
6536 +               len += parent->d_name.len + 1;
6537 +               parent = parent->d_parent;
6538 +       }
6539 +       
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);
6544 +
6545 +       name[len] = '\0';
6546 +       parent = dentry;
6547 +       while(parent->d_parent != parent){
6548 +               len -= parent->d_name.len + 1;
6549 +               name[len] = '/';
6550 +               strncpy(&name[len + 1], parent->d_name.name, 
6551 +                       parent->d_name.len);
6552 +               parent = parent->d_parent;
6553 +       }
6554 +       strncpy(name, root, strlen(root));
6555 +       return(name);
6556 +}
6557 +
6558 +static char *inode_name(struct inode *ino, int extra)
6559 +{
6560 +       struct dentry *dentry;
6561 +
6562 +       dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
6563 +       return(dentry_name(dentry, extra));
6564 +}
6565 +
6566 +static int read_name(struct inode *ino, char *name)
6567 +{
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
6571 +        */
6572 +       int err;
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;
6577 +
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);
6581 +       if(err) 
6582 +               return(err);
6583 +
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()))
6591 +               ino->i_uid = 0;
6592 +       return(0);
6593 +}
6594 +
6595 +static char *follow_link(char *link)
6596 +{
6597 +       int len, n;
6598 +       char *name, *resolved, *end;
6599 +
6600 +       len = 64;
6601 +       while(1){
6602 +               n = -ENOMEM;
6603 +               name = kmalloc(len, GFP_KERNEL);
6604 +               if(name == NULL)
6605 +                       goto out;
6606 +
6607 +               n = do_readlink(link, name, len);
6608 +               if(n < len)
6609 +                       break;
6610 +               len *= 2;
6611 +               kfree(name);
6612 +       }
6613 +       if(n < 0)
6614 +               goto out_free;
6615 +
6616 +       if(*name == '/')
6617 +               return(name);
6618 +
6619 +       end = strrchr(link, '/');
6620 +       if(end == NULL)
6621 +               return(name);
6622 +
6623 +       *(end + 1) = '\0';
6624 +       len = strlen(link) + strlen(name) + 1;
6625 +
6626 +       resolved = kmalloc(len, GFP_KERNEL);
6627 +       if(resolved == NULL){
6628 +               n = -ENOMEM;
6629 +               goto out_free;
6630 +       }
6631 +
6632 +       sprintf(resolved, "%s%s", link, name);
6633 +       kfree(name);
6634 +       kfree(link);
6635 +       return(resolved);
6636 +
6637 + out_free:
6638 +       kfree(name);
6639 + out:
6640 +       return(ERR_PTR(n));
6641 +}
6642 +
6643 +static int read_inode(struct inode *ino)
6644 +{
6645 +       char *name;
6646 +       int err = 0;
6647 +
6648 +       /* Unfortunately, we are called from iget() when we don't have a dentry
6649 +        * allocated yet.
6650 +        */
6651 +       if(list_empty(&ino->i_dentry))
6652 +               goto out;
6653
6654 +       err = -ENOMEM;
6655 +       name = inode_name(ino, 0);
6656 +       if(name == NULL) 
6657 +               goto out;
6658 +
6659 +       if(file_type(name, NULL) == OS_TYPE_SYMLINK){
6660 +               name = follow_link(name);
6661 +               if(IS_ERR(name)){
6662 +                       err = PTR_ERR(name);
6663 +                       goto out;
6664 +               }
6665 +       }
6666 +       
6667 +       err = read_name(ino, name);
6668 +       kfree(name);
6669 + out:
6670 +       return(err);
6671 +}
6672 +
6673 +int hostfs_statfs(struct super_block *sb, struct kstatfs *sf)
6674 +{
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
6678 +        */
6679 +       int err;
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;
6685 +
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;
6697 +       return(0);
6698 +}
6699 +
6700 +static struct inode *hostfs_alloc_inode(struct super_block *sb)
6701 +{
6702 +       struct hostfs_inode_info *hi;
6703 +
6704 +       hi = kmalloc(sizeof(*hi), GFP_KERNEL);
6705 +       if(hi == NULL) 
6706 +               return(NULL);
6707 +
6708 +       *hi = ((struct hostfs_inode_info) { .host_filename      = NULL,
6709 +                                           .fd                 = -1,
6710 +                                           .mode               = 0 });
6711 +       inode_init_once(&hi->vfs_inode);
6712 +       return(&hi->vfs_inode);
6713 +}
6714 +
6715 +static void hostfs_delete_inode(struct inode *inode)
6716 +{
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;
6721 +       }
6722 +       clear_inode(inode);
6723 +}
6724 +
6725 +static void hostfs_destroy_inode(struct inode *inode)
6726 +{
6727 +       if(HOSTFS_I(inode)->host_filename) 
6728 +               kfree(HOSTFS_I(inode)->host_filename);
6729 +
6730 +       if(HOSTFS_I(inode)->fd != -1) {
6731 +               close_file(&HOSTFS_I(inode)->fd);
6732 +               printk("Closing host fd in .destroy_inode\n");
6733 +       }
6734 +
6735 +       kfree(HOSTFS_I(inode));
6736 +}
6737 +
6738 +static void hostfs_read_inode(struct inode *inode)
6739 +{
6740 +       read_inode(inode);
6741 +}
6742 +
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,
6750 +};
6751 +
6752 +int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
6753 +{
6754 +       void *dir;
6755 +       char *name;
6756 +       unsigned long long next, ino;
6757 +       int error, len;
6758 +
6759 +       name = dentry_name(file->f_dentry, 0);
6760 +       if(name == NULL) return(-ENOMEM);
6761 +       dir = open_dir(name, &error);
6762 +       kfree(name);
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, 
6767 +                                  ino, DT_UNKNOWN);
6768 +               if(error) break;
6769 +               file->f_pos = next;
6770 +       }
6771 +       close_dir(dir);
6772 +       return(0);
6773 +}
6774 +
6775 +int hostfs_file_open(struct inode *ino, struct file *file)
6776 +{
6777 +       char *name;
6778 +       int mode = 0, r = 0, w = 0, fd;
6779 +
6780 +       mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
6781 +       if((mode & HOSTFS_I(ino)->mode) == mode)
6782 +               return(0);
6783 +
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.
6786 +        */
6787 +       if(HOSTFS_I(ino)->fd != -1){
6788 +               close_file(&HOSTFS_I(ino)->fd);
6789 +               HOSTFS_I(ino)->fd = -1;
6790 +       }
6791 +
6792 +       HOSTFS_I(ino)->mode |= mode;
6793 +       if(HOSTFS_I(ino)->mode & FMODE_READ) 
6794 +               r = 1;
6795 +       if(HOSTFS_I(ino)->mode & FMODE_WRITE) 
6796 +               w = 1;
6797 +       if(w) 
6798 +               r = 1;
6799 +
6800 +       name = dentry_name(file->f_dentry, 0);
6801 +       if(name == NULL) 
6802 +               return(-ENOMEM);
6803 +
6804 +       fd = open_file(name, r, w, append);
6805 +       kfree(name);
6806 +       if(fd < 0) return(fd);
6807 +       FILE_HOSTFS_I(file)->fd = fd;
6808 +
6809 +       return(0);
6810 +}
6811 +
6812 +int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
6813 +{
6814 +       return(0);
6815 +}
6816 +
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,
6823 +       .release        = NULL,
6824 +       .fsync          = hostfs_fsync,
6825 +};
6826 +
6827 +static struct file_operations hostfs_dir_fops = {
6828 +       .readdir        = hostfs_readdir,
6829 +       .read           = generic_read_dir,
6830 +};
6831 +
6832 +int hostfs_writepage(struct page *page, struct writeback_control *wbc)
6833 +{
6834 +       struct address_space *mapping = page->mapping;
6835 +       struct inode *inode = mapping->host;
6836 +       char *buffer;
6837 +       unsigned long long base;
6838 +       int count = PAGE_CACHE_SIZE;
6839 +       int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
6840 +       int err;
6841 +
6842 +       if (page->index >= end_index)
6843 +               count = inode->i_size & (PAGE_CACHE_SIZE-1);
6844 +
6845 +       buffer = kmap(page);
6846 +       base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
6847 +
6848 +       err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
6849 +       if(err != count){
6850 +               ClearPageUptodate(page);
6851 +               goto out;
6852 +       }
6853 +
6854 +       if (base > inode->i_size)
6855 +               inode->i_size = base;
6856 +
6857 +       if (PageError(page))
6858 +               ClearPageError(page);   
6859 +       err = 0;
6860 +
6861 + out:  
6862 +       kunmap(page);
6863 +
6864 +       unlock_page(page);
6865 +       return err; 
6866 +}
6867 +
6868 +int hostfs_readpage(struct file *file, struct page *page)
6869 +{
6870 +       char *buffer;
6871 +       long long start;
6872 +       int err = 0;
6873 +
6874 +       start = (long long) page->index << PAGE_CACHE_SHIFT;
6875 +       buffer = kmap(page);
6876 +       err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
6877 +                       PAGE_CACHE_SIZE);
6878 +       if(err < 0) goto out;
6879 +
6880 +       memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
6881 +
6882 +       flush_dcache_page(page);
6883 +       SetPageUptodate(page);
6884 +       if (PageError(page)) ClearPageError(page);
6885 +       err = 0;
6886 + out:
6887 +       kunmap(page);
6888 +       unlock_page(page);
6889 +       return(err);
6890 +}
6891 +
6892 +int hostfs_prepare_write(struct file *file, struct page *page, 
6893 +                        unsigned int from, unsigned int to)
6894 +{
6895 +       char *buffer;
6896 +       long long start, tmp;
6897 +       int err;
6898 +
6899 +       start = (long long) page->index << PAGE_CACHE_SHIFT;
6900 +       buffer = kmap(page);
6901 +       if(from != 0){
6902 +               tmp = start;
6903 +               err = read_file(FILE_HOSTFS_I(file)->fd, &tmp, buffer,
6904 +                               from);
6905 +               if(err < 0) goto out;
6906 +       }
6907 +       if(to != PAGE_CACHE_SIZE){
6908 +               start += to;
6909 +               err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer + to,
6910 +                               PAGE_CACHE_SIZE - to);
6911 +               if(err < 0) goto out;           
6912 +       }
6913 +       err = 0;
6914 + out:
6915 +       kunmap(page);
6916 +       return(err);
6917 +}
6918 +
6919 +int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
6920 +                unsigned to)
6921 +{
6922 +       struct address_space *mapping = page->mapping;
6923 +       struct inode *inode = mapping->host;
6924 +       char *buffer;
6925 +       long long start;
6926 +       int err = 0;
6927 +
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, 
6931 +                        to - from);
6932 +       if(err > 0) err = 0;
6933 +       if(!err && (start > inode->i_size))
6934 +               inode->i_size = start;
6935 +
6936 +       kunmap(page);
6937 +       return(err);
6938 +}
6939 +
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
6946 +};
6947 +
6948 +static int init_inode(struct inode *inode, struct dentry *dentry)
6949 +{
6950 +       char *name;
6951 +       int type, err = -ENOMEM, rdev;
6952 +
6953 +       if(dentry){
6954 +               name = dentry_name(dentry, 0);
6955 +               if(name == NULL)
6956 +                       goto out;
6957 +               type = file_type(name, &rdev);
6958 +               kfree(name);
6959 +       }
6960 +       else type = OS_TYPE_DIR;
6961 +
6962 +       err = 0;
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;
6968 +
6969 +       if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
6970 +       else inode->i_fop = &hostfs_file_fops;
6971 +
6972 +       if(type == OS_TYPE_SYMLINK) 
6973 +               inode->i_mapping->a_ops = &hostfs_link_aops;
6974 +       else inode->i_mapping->a_ops = &hostfs_aops;
6975 +
6976 +       switch (type) {
6977 +       case OS_TYPE_CHARDEV:
6978 +               init_special_inode(inode, S_IFCHR, rdev);
6979 +               break;
6980 +       case OS_TYPE_BLOCKDEV:
6981 +               init_special_inode(inode, S_IFBLK, rdev);
6982 +               break;
6983 +       case OS_TYPE_FIFO:
6984 +               init_special_inode(inode, S_IFIFO, 0);
6985 +               break;
6986 +       case OS_TYPE_SOCK:
6987 +               init_special_inode(inode, S_IFSOCK, 0);
6988 +               break;
6989 +       }
6990 + out:
6991 +       return(err);
6992 +}
6993 +
6994 +int hostfs_create(struct inode *dir, struct dentry *dentry, int mode, 
6995 +                 struct nameidata *nd)
6996 +{
6997 +       struct inode *inode;
6998 +       char *name;
6999 +       int error, fd;
7000 +
7001 +       error = -ENOMEM;
7002 +       inode = iget(dir->i_sb, 0);
7003 +       if(inode == NULL) goto out;
7004 +
7005 +       error = init_inode(inode, dentry);
7006 +       if(error) 
7007 +               goto out_put;
7008 +       
7009 +       error = -ENOMEM;
7010 +       name = dentry_name(dentry, 0);
7011 +       if(name == NULL)
7012 +               goto out_put;
7013 +
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);
7018 +       if(fd < 0) 
7019 +               error = fd;
7020 +       else error = read_name(inode, name);
7021 +
7022 +       kfree(name);
7023 +       if(error)
7024 +               goto out_put;
7025 +
7026 +       HOSTFS_I(inode)->fd = fd;
7027 +       HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
7028 +       d_instantiate(dentry, inode);
7029 +       return(0);
7030 +
7031 + out_put:
7032 +       iput(inode);
7033 + out:
7034 +       return(error);
7035 +}
7036 +
7037 +struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry, 
7038 +                            struct nameidata *nd)
7039 +{
7040 +       struct inode *inode;
7041 +       char *name;
7042 +       int err;
7043 +
7044 +       err = -ENOMEM;
7045 +       inode = iget(ino->i_sb, 0);
7046 +       if(inode == NULL) 
7047 +               goto out;
7048
7049 +       err = init_inode(inode, dentry);
7050 +       if(err) 
7051 +               goto out_put;
7052 +
7053 +       err = -ENOMEM;
7054 +       name = dentry_name(dentry, 0);
7055 +       if(name == NULL)
7056 +               goto out_put;
7057 +
7058 +       err = read_name(inode, name);
7059 +       kfree(name);
7060 +       if(err == -ENOENT){
7061 +               iput(inode);
7062 +               inode = NULL;
7063 +       }
7064 +       else if(err)
7065 +               goto out_put;
7066 +
7067 +       d_add(dentry, inode);
7068 +       dentry->d_op = &hostfs_dentry_ops;
7069 +       return(NULL);
7070 +
7071 + out_put:
7072 +       iput(inode);
7073 + out:
7074 +       return(ERR_PTR(err));
7075 +}
7076 +
7077 +static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
7078 +{
7079 +        char *file;
7080 +       int len;
7081 +
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';
7088 +        return(file);
7089 +}
7090 +
7091 +int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
7092 +{
7093 +        char *from_name, *to_name;
7094 +        int err;
7095 +
7096 +        if((from_name = inode_dentry_name(ino, from)) == NULL) 
7097 +                return(-ENOMEM);
7098 +        to_name = dentry_name(to, 0);
7099 +       if(to_name == NULL){
7100 +               kfree(from_name);
7101 +               return(-ENOMEM);
7102 +       }
7103 +        err = link_file(to_name, from_name);
7104 +        kfree(from_name);
7105 +        kfree(to_name);
7106 +        return(err);
7107 +}
7108 +
7109 +int hostfs_unlink(struct inode *ino, struct dentry *dentry)
7110 +{
7111 +       char *file;
7112 +       int err;
7113 +
7114 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
7115 +       if(append)
7116 +               return(-EPERM);
7117 +
7118 +       err = unlink_file(file);
7119 +       kfree(file);
7120 +       return(err);
7121 +}
7122 +
7123 +int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
7124 +{
7125 +       char *file;
7126 +       int err;
7127 +
7128 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
7129 +       err = make_symlink(file, to);
7130 +       kfree(file);
7131 +       return(err);
7132 +}
7133 +
7134 +int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
7135 +{
7136 +       char *file;
7137 +       int err;
7138 +
7139 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
7140 +       err = do_mkdir(file, mode);
7141 +       kfree(file);
7142 +       return(err);
7143 +}
7144 +
7145 +int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
7146 +{
7147 +       char *file;
7148 +       int err;
7149 +
7150 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
7151 +       err = do_rmdir(file);
7152 +       kfree(file);
7153 +       return(err);
7154 +}
7155 +
7156 +int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
7157 +{
7158 +       struct inode *inode;
7159 +       char *name;
7160 +       int err = -ENOMEM;
7161
7162 +       inode = iget(dir->i_sb, 0);
7163 +       if(inode == NULL) 
7164 +               goto out;
7165 +
7166 +       err = init_inode(inode, dentry);
7167 +       if(err) 
7168 +               goto out_put;
7169 +
7170 +       err = -ENOMEM;
7171 +       name = dentry_name(dentry, 0);
7172 +       if(name == NULL)
7173 +               goto out_put;
7174 +
7175 +       init_special_inode(inode, mode, dev);
7176 +       err = do_mknod(name, mode, dev);
7177 +       if(err)
7178 +               goto out_free;
7179 +
7180 +       err = read_name(inode, name);
7181 +       kfree(name);
7182 +       if(err)
7183 +               goto out_put;
7184 +
7185 +       d_instantiate(dentry, inode);
7186 +       return(0);
7187 +
7188 + out_free:
7189 +       kfree(name);
7190 + out_put:
7191 +       iput(inode);
7192 + out:
7193 +       return(err);
7194 +}
7195 +
7196 +int hostfs_rename(struct inode *from_ino, struct dentry *from,
7197 +                 struct inode *to_ino, struct dentry *to)
7198 +{
7199 +       char *from_name, *to_name;
7200 +       int err;
7201 +
7202 +       if((from_name = inode_dentry_name(from_ino, from)) == NULL)
7203 +               return(-ENOMEM);
7204 +       if((to_name = inode_dentry_name(to_ino, to)) == NULL){
7205 +               kfree(from_name);
7206 +               return(-ENOMEM);
7207 +       }
7208 +       err = rename_file(from_name, to_name);
7209 +       kfree(from_name);
7210 +       kfree(to_name);
7211 +       return(err);
7212 +}
7213 +
7214 +void hostfs_truncate(struct inode *ino)
7215 +{
7216 +       not_implemented();
7217 +}
7218 +
7219 +int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
7220 +{
7221 +       char *name;
7222 +       int r = 0, w = 0, x = 0, err;
7223 +
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);
7230 +       kfree(name);
7231 +       if(!err) err = vfs_permission(ino, desired);
7232 +       return(err);
7233 +}
7234 +
7235 +int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
7236 +{
7237 +       struct hostfs_iattr attrs;
7238 +       char *name;
7239 +       int err;
7240 +       
7241 +       if(append) 
7242 +               attr->ia_valid &= ~ATTR_SIZE;
7243 +
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;
7248 +       }
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;
7255 +       }
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;
7262 +       }
7263 +       if(attr->ia_valid & ATTR_SIZE){
7264 +               attrs.ia_valid |= HOSTFS_ATTR_SIZE;
7265 +               attrs.ia_size = attr->ia_size;
7266 +       }
7267 +       if(attr->ia_valid & ATTR_ATIME){
7268 +               attrs.ia_valid |= HOSTFS_ATTR_ATIME;
7269 +               attrs.ia_atime = attr->ia_atime;
7270 +       }
7271 +       if(attr->ia_valid & ATTR_MTIME){
7272 +               attrs.ia_valid |= HOSTFS_ATTR_MTIME;
7273 +               attrs.ia_mtime = attr->ia_mtime;
7274 +       }
7275 +       if(attr->ia_valid & ATTR_CTIME){
7276 +               attrs.ia_valid |= HOSTFS_ATTR_CTIME;
7277 +               attrs.ia_ctime = attr->ia_ctime;
7278 +       }
7279 +       if(attr->ia_valid & ATTR_ATIME_SET){
7280 +               attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
7281 +       }
7282 +       if(attr->ia_valid & ATTR_MTIME_SET){
7283 +               attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
7284 +       }
7285 +       name = dentry_name(dentry, 0);
7286 +       if(name == NULL) return(-ENOMEM);
7287 +       err = set_attr(name, &attrs);
7288 +       kfree(name);
7289 +       if(err)
7290 +               return(err);
7291 +
7292 +       return(inode_setattr(dentry->d_inode, attr));
7293 +}
7294 +
7295 +int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry, 
7296 +          struct kstat *stat)
7297 +{
7298 +       generic_fillattr(dentry->d_inode, stat);
7299 +       return(0);
7300 +}
7301 +
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,
7315 +};
7316 +
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,
7331 +};
7332 +
7333 +int hostfs_link_readpage(struct file *file, struct page *page)
7334 +{
7335 +       char *buffer, *name;
7336 +       long long start;
7337 +       int err;
7338 +
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);
7344 +       kfree(name);
7345 +       if(err == PAGE_CACHE_SIZE)
7346 +               err = -E2BIG;
7347 +       else if(err > 0){
7348 +               flush_dcache_page(page);
7349 +               SetPageUptodate(page);
7350 +               if (PageError(page)) ClearPageError(page);
7351 +               err = 0;
7352 +       }
7353 +       kunmap(page);
7354 +       unlock_page(page);
7355 +       return(err);
7356 +}
7357 +
7358 +static struct address_space_operations hostfs_link_aops = {
7359 +       .readpage       = hostfs_link_readpage,
7360 +};
7361 +
7362 +static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
7363 +{
7364 +       struct inode *root_inode;
7365 +       char *name, *data = d;
7366 +       int err;
7367 +
7368 +       sb->s_blocksize = 1024;
7369 +       sb->s_blocksize_bits = 10;
7370 +       sb->s_magic = HOSTFS_SUPER_MAGIC;
7371 +       sb->s_op = &hostfs_sbops;
7372 +
7373 +       if((data == NULL) || (*data == '\0')) 
7374 +               data = root_ino;
7375 +
7376 +       err = -ENOMEM;
7377 +       name = kmalloc(strlen(data) + 1, GFP_KERNEL);
7378 +       if(name == NULL) 
7379 +               goto out;
7380 +
7381 +       strcpy(name, data);
7382 +
7383 +       root_inode = iget(sb, 0);
7384 +       if(root_inode == NULL)
7385 +               goto out_free;
7386 +
7387 +       err = init_inode(root_inode, NULL);
7388 +       if(err)
7389 +               goto out_put;
7390 +
7391 +       HOSTFS_I(root_inode)->host_filename = name;
7392 +
7393 +       err = -ENOMEM;
7394 +       sb->s_root = d_alloc_root(root_inode);
7395 +       if(sb->s_root == NULL)
7396 +               goto out_put;
7397 +
7398 +       err = read_inode(root_inode);
7399 +       if(err)
7400 +               goto out_put;
7401 +
7402 +       return(0);
7403 +
7404 + out_put:
7405 +       iput(root_inode);
7406 + out_free:
7407 +       kfree(name);
7408 + out:
7409 +       return(err);
7410 +}
7411 +
7412 +static struct super_block *hostfs_read_sb(struct file_system_type *type,
7413 +                                            int flags, const char *dev_name,
7414 +                                            void *data)
7415 +{
7416 +       return(get_sb_nodev(type, flags, data, hostfs_fill_sb_common));
7417 +}
7418 +
7419 +static struct file_system_type hostfs_type = {
7420 +       .owner          = THIS_MODULE,
7421 +       .name           = "hostfs",
7422 +       .get_sb         = hostfs_read_sb,
7423 +       .kill_sb        = kill_anon_super,
7424 +       .fs_flags       = 0,
7425 +};
7426 +
7427 +static int __init init_hostfs(void)
7428 +{
7429 +       return(register_filesystem(&hostfs_type));
7430 +}
7431 +
7432 +static void __exit exit_hostfs(void)
7433 +{
7434 +       unregister_filesystem(&hostfs_type);
7435 +}
7436 +
7437 +module_init(init_hostfs)
7438 +module_exit(exit_hostfs)
7439 +MODULE_LICENSE("GPL");
7440 +
7441 +/*
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
7445 + * of the file.
7446 + * ---------------------------------------------------------------------------
7447 + * Local variables:
7448 + * c-file-style: "linux"
7449 + * End:
7450 + */
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
7455 @@ -0,0 +1,6 @@
7456 +#ifndef __UM_MODULE_GENERIC_H
7457 +#define __UM_MODULE_GENERIC_H
7458 +
7459 +#include "asm/arch/module.h"
7460 +
7461 +#endif
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
7466 @@ -14,8 +14,6 @@
7467  extern int unlockpt(int __fd);
7468  extern char *ptsname(int __fd);
7469  
7470 -enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
7471 -
7472  struct cpu_task {
7473         int pid;
7474         void *task;
7475 @@ -59,13 +57,11 @@
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);
7489 @@ -86,11 +82,17 @@
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);
7498
7499 +extern void arch_init_thread(void);
7500 +
7501 +extern int __raw(int fd, int complain, int now);
7502 +#define raw(fd, complain) __raw((fd), (complain), 1)
7503 +
7504 +#define CATCH_EINTR(expr) while ( ((expr) < 0) && errno == EINTR)
7505  #endif
7506  
7507  /*
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
7512 @@ -0,0 +1,6 @@
7513 +#ifndef __UM_CPUFEATURE_H
7514 +#define __UM_CPUFEATURE_H
7515 +
7516 +#include "asm/arch/cpufeature.h"
7517 +
7518 +#endif
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
7523 @@ -20,7 +20,7 @@
7524  
7525         jmp_buf jbuf;
7526         *fault_catcher = &jbuf;
7527 -       if(setjmp(jbuf) == 0){
7528 +       if(sigsetjmp(jbuf, 1) == 0){
7529                 (*op)(to, from, n);
7530                 ret = 0;
7531                 *faulted_out = 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
7536 @@ -17,6 +17,7 @@
7537  #include "mem_user.h"
7538  #include "os.h"
7539  #include "tlb.h"
7540 +#include "mode.h"
7541  
7542  static int exec_tramp(void *sig_stack)
7543  {
7544 @@ -47,17 +48,17 @@
7545                 do_exit(SIGKILL);
7546         }
7547  
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());
7556  
7557         enable_timer();
7558         free_page(stack);
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);
7562         force_flush_all();
7563         unblock_signals();
7564  }
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
7569 @@ -21,6 +21,7 @@
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"
7575  #include "os.h"
7576  
7577 @@ -40,7 +41,7 @@
7578         /* Wait for it to stop itself and continue it with a SIGUSR1 to force 
7579          * it into the signal handler.
7580          */
7581 -       n = waitpid(pid, &status, WUNTRACED);
7582 +       CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
7583         if(n < 0){
7584                 printf("capture_stack : waitpid failed - errno = %d\n", errno);
7585                 exit(1);
7586 @@ -60,7 +61,7 @@
7587          * At this point, the handler has stuffed the addresses of
7588          * sig, sc, and SA_RESTORER in raw.
7589          */
7590 -       n = waitpid(pid, &status, WUNTRACED);
7591 +       CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
7592         if(n < 0){
7593                 printf("capture_stack : waitpid failed - errno = %d\n", errno);
7594                 exit(1);
7595 @@ -82,7 +83,8 @@
7596                        errno);
7597                 exit(1);
7598         }
7599 -       if(waitpid(pid, &status, 0) < 0){
7600 +       CATCH_EINTR(n = waitpid(pid, &status, 0));
7601 +       if(n < 0){
7602                 printf("capture_stack : waitpid failed - errno = %d\n", errno);
7603                 exit(1);
7604         }
7605 @@ -279,7 +281,7 @@
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;
7611  
7612         stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
7613                      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
7614 @@ -292,7 +294,6 @@
7615         }
7616  
7617         top = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
7618 -       sig_top = (unsigned long) sigstack + PAGE_SIZE;
7619  
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
7626 @@ -48,7 +48,10 @@
7627         set_fs(KERNEL_DS);                      \
7628         ret = sys(args);                        \
7629         set_fs(fs);                             \
7630 -       return ret;
7631 +       if (ret >= 0)                           \
7632 +               return ret;                     \
7633 +       errno = -(long)ret;                     \
7634 +       return -1;
7635  
7636  static inline long open(const char *pathname, int flags, int mode) 
7637  {
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
7642 @@ -0,0 +1,30 @@
7643 +/* 
7644 + * Copyright (C) 2003 Jeff Dike (jdike@addtoit.com)
7645 + * Licensed under the GPL
7646 + */
7647 +
7648 +#ifndef __MEM_KERN_H__
7649 +#define __MEM_KERN_H__
7650 +
7651 +#include "linux/list.h"
7652 +#include "linux/types.h"
7653 +
7654 +struct remapper {
7655 +       struct list_head list;
7656 +       int (*proc)(int, unsigned long, int, __u64);
7657 +};
7658 +
7659 +extern void register_remapper(struct remapper *info);
7660 +
7661 +#endif
7662 +
7663 +/*
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
7667 + * of the file.
7668 + * ---------------------------------------------------------------------------
7669 + * Local variables:
7670 + * c-file-style: "linux"
7671 + * End:
7672 + */
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
7677 @@ -1,3 +1,5 @@
7678 +#include <asm-generic/vmlinux.lds.h>
7679 +
7680  OUTPUT_FORMAT(ELF_FORMAT)
7681  OUTPUT_ARCH(ELF_ARCH)
7682  ENTRY(_start)
7683 @@ -10,12 +12,15 @@
7684  {
7685    . = START + SIZEOF_HEADERS;
7686    .interp         : { *(.interp) }
7687 -  . = ALIGN(4096);
7688    __binary_start = .;
7689    . = ALIGN(4096);             /* Init code and data */
7690    _stext = .;
7691    __init_begin = .;
7692 -  .text.init : { *(.text.init) }
7693 +  .init.text : { 
7694 +       _sinittext = .;
7695 +       *(.init.text)
7696 +       _einittext = .;
7697 +  }
7698  
7699    . = ALIGN(4096);
7700  
7701 @@ -55,7 +60,9 @@
7702    } =0x90909090
7703    .plt            : { *(.plt) }
7704    .text           : {
7705 -    *(.text .stub .text.* .gnu.linkonce.t.*)
7706 +    *(.text)
7707 +    SCHED_TEXT
7708 +    *(.stub .text.* .gnu.linkonce.t.*)
7709      /* .gnu.warning sections are handled specially by elf32.em.  */
7710      *(.gnu.warning)
7711    } =0x90909090
7712 @@ -67,7 +74,7 @@
7713  
7714    #include "asm/common.lds.S"
7715  
7716 -  .data.init : { *(.data.init) }
7717 +  init.data : { *(.init.data) }
7718  
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
7725 @@ -5,11 +5,9 @@
7726  
7727  #include <stdlib.h>
7728  #include <errno.h>
7729 -#include <fcntl.h>
7730  #include <setjmp.h>
7731  #include <signal.h>
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>
7737 @@ -34,7 +32,14 @@
7738  {
7739         kill(pid, SIGKILL);
7740         kill(pid, SIGCONT);
7741 -       while(waitpid(pid, NULL, 0) > 0) kill(pid, SIGCONT);
7742 +       do {
7743 +               int n;
7744 +               CATCH_EINTR(n = waitpid(pid, NULL, 0));
7745 +               if (n > 0)
7746 +                       kill(pid, SIGCONT);
7747 +               else
7748 +                       break;
7749 +       } while(1);
7750  }
7751  
7752  /* Unlocked - don't care if this is a bit off */
7753 @@ -82,6 +87,8 @@
7754                      .is_irq            = 0 },
7755         [ SIGILL ] { .handler           = relay_signal,
7756                      .is_irq            = 0 },
7757 +       [ SIGWINCH ] { .handler         = winch,
7758 +                      .is_irq          = 1 },
7759         [ SIGBUS ] { .handler           = bus_handler,
7760                      .is_irq            = 0 },
7761         [ SIGSEGV] { .handler           = segv_handler,
7762 @@ -102,12 +109,11 @@
7763                          sig, &sc);
7764  }
7765  
7766 -extern int timer_irq_inited, missed_ticks[];
7767 +extern int timer_irq_inited;
7768  
7769  void alarm_handler(int sig, struct sigcontext sc)
7770  {
7771         if(!timer_irq_inited) return;
7772 -       missed_ticks[cpu()]++;
7773  
7774         if(sig == SIGALRM)
7775                 switch_timers(0);
7776 @@ -123,7 +129,7 @@
7777  {
7778         jmp_buf *buf = b;
7779  
7780 -       longjmp(*buf, val);
7781 +       siglongjmp(*buf, val);
7782  }
7783  
7784  /*
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
7789 @@ -1,5 +1,5 @@
7790  
7791 -menu "Network Devices"
7792 +menu "UML Network Devices"
7793         depends on NET
7794  
7795  # UML virtual driver
7796 @@ -176,73 +176,5 @@
7797         
7798          Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
7799  
7800 -
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
7806 -config DUMMY
7807 -       tristate "Dummy net driver support"
7808 -
7809 -config BONDING
7810 -       tristate "Bonding driver support"
7811 -
7812 -config EQUALIZER
7813 -       tristate "EQL (serial line load balancing) support"
7814 -
7815 -config TUN
7816 -       tristate "Universal TUN/TAP device driver support"
7817 -
7818 -config ETHERTAP
7819 -       tristate "Ethertap network tap (OBSOLETE)"
7820 -       depends on EXPERIMENTAL && NETLINK
7821 -
7822 -config PPP
7823 -       tristate "PPP (point-to-point protocol) support"
7824 -
7825 -config PPP_MULTILINK
7826 -       bool "PPP multilink support (EXPERIMENTAL)"
7827 -       depends on PPP && EXPERIMENTAL
7828 -
7829 -config PPP_FILTER
7830 -       bool "PPP filtering"
7831 -       depends on PPP && FILTER
7832 -
7833 -config PPP_ASYNC
7834 -       tristate "PPP support for async serial ports"
7835 -       depends on PPP
7836 -
7837 -config PPP_SYNC_TTY
7838 -       tristate "PPP support for sync tty ports"
7839 -       depends on PPP
7840 -
7841 -config PPP_DEFLATE
7842 -       tristate "PPP Deflate compression"
7843 -       depends on PPP
7844 -
7845 -config PPP_BSDCOMP
7846 -       tristate "PPP BSD-Compress compression"
7847 -       depends on PPP
7848 -
7849 -config PPPOE
7850 -       tristate "PPP over Ethernet (EXPERIMENTAL)"
7851 -       depends on PPP && EXPERIMENTAL
7852 -
7853 -config SLIP
7854 -       tristate "SLIP (serial line) support"
7855 -
7856 -config SLIP_COMPRESSED
7857 -       bool "CSLIP compressed headers"
7858 -       depends on SLIP=y
7859 -
7860 -config SLIP_SMART
7861 -       bool "Keepalive and linefill"
7862 -       depends on SLIP=y
7863 -
7864 -config SLIP_MODE_SLIP6
7865 -       bool "Six bit SLIP encapsulation"
7866 -       depends on SLIP=y
7867 -
7868  endmenu
7869  
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
7874 @@ -0,0 +1,19 @@
7875 +# 
7876 +# Copyright (C) 2002, 2003 Jeff Dike (jdike@karaya.com)
7877 +# Licensed under the GPL
7878 +#
7879 +
7880 +hppfs-objs := hppfs_kern.o
7881 +
7882 +obj-y = 
7883 +obj-$(CONFIG_HPPFS) += hppfs.o
7884 +
7885 +clean:
7886 +
7887 +modules:
7888 +
7889 +fastdep:
7890 +
7891 +dep:
7892 +
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
7898 @@ -16,12 +16,15 @@
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"
7905  #include "kern.h"
7906  #include "chan_kern.h"
7907  #include "mconsole_kern.h"
7908  #include "2_5compat.h"
7909 +#include "mem.h"
7910 +#include "mem_kern.h"
7911  
7912  int handle_page_fault(unsigned long address, unsigned long ip, 
7913                       int is_write, int is_user, int *code_out)
7914 @@ -51,12 +54,12 @@
7915         if(is_write && !(vma->vm_flags & VM_WRITE)) 
7916                 goto out;
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);
7923 - survive:
7924         do {
7925 + survive:
7926                 switch (handle_mm_fault(mm, vma, address, is_write)){
7927                 case VM_FAULT_MINOR:
7928                         current->min_flt++;
7929 @@ -71,14 +74,20 @@
7930                         err = -ENOMEM;
7931                         goto out_of_memory;
7932                 default:
7933 -                       BUG();
7934 +                       if (current->pid == 1) {
7935 +                               up_read(&mm->mmap_sem);
7936 +                               yield();
7937 +                               down_read(&mm->mmap_sem);
7938 +                               goto survive;
7939 +                       }
7940 +                       goto out;
7941                 }
7942                 pte = pte_offset_kernel(pmd, page);
7943         } while(!pte_present(*pte));
7944 +       err = 0;
7945         *pte = pte_mkyoung(*pte);
7946         if(pte_write(*pte)) *pte = pte_mkdirty(*pte);
7947         flush_tlb_page(vma, page);
7948 -       err = 0;
7949   out:
7950         up_read(&mm->mmap_sem);
7951         return(err);
7952 @@ -98,6 +107,33 @@
7953         goto out;
7954  }
7955  
7956 +LIST_HEAD(physmem_remappers);
7957 +
7958 +void register_remapper(struct remapper *info)
7959 +{
7960 +       list_add(&info->list, &physmem_remappers);
7961 +}
7962 +
7963 +static int check_remapped_addr(unsigned long address, int is_write)
7964 +{
7965 +       struct remapper *remapper;
7966 +       struct list_head *ele;
7967 +       __u64 offset;
7968 +       int fd;
7969 +
7970 +       fd = phys_mapping(__pa(address), &offset);
7971 +       if(fd == -1)
7972 +               return(0);
7973 +
7974 +       list_for_each(ele, &physmem_remappers){
7975 +               remapper = list_entry(ele, struct remapper, list);
7976 +               if((*remapper->proc)(fd, address, is_write, offset))
7977 +                       return(1);
7978 +       }
7979 +
7980 +       return(0);
7981 +}
7982 +
7983  unsigned long segv(unsigned long address, unsigned long ip, int is_write, 
7984                    int is_user, void *sc)
7985  {
7986 @@ -109,7 +145,9 @@
7987                  flush_tlb_kernel_vm();
7988                  return(0);
7989          }
7990 -        if(current->mm == NULL)
7991 +       else if(check_remapped_addr(address & PAGE_MASK, is_write))
7992 +               return(0);
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);
7996  
7997 @@ -120,9 +158,8 @@
7998                 current->thread.fault_addr = (void *) address;
7999                 do_longjmp(catcher, 1);
8000         } 
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");
8004 -       }
8005         else if(arch_fixup(ip, sc))
8006                 return(0);
8007  
8008 @@ -155,8 +192,6 @@
8009  {
8010         struct siginfo si;
8011  
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);
8019  }
8020  
8021 +void winch(int sig, union uml_pt_regs *regs)
8022 +{
8023 +       do_IRQ(WINCH_IRQ, regs);
8024 +}
8025 +
8026  void trap_init(void)
8027  {
8028  }
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
8033 @@ -0,0 +1,48 @@
8034 +#ifndef __COW_SYS_H__
8035 +#define __COW_SYS_H__
8036 +
8037 +#include "kern_util.h"
8038 +#include "user_util.h"
8039 +#include "os.h"
8040 +#include "user.h"
8041 +
8042 +static inline void *cow_malloc(int size)
8043 +{
8044 +       return(um_kmalloc(size));
8045 +}
8046 +
8047 +static inline void cow_free(void *ptr)
8048 +{
8049 +       kfree(ptr);
8050 +}
8051 +
8052 +#define cow_printf printk
8053 +
8054 +static inline char *cow_strdup(char *str)
8055 +{
8056 +       return(uml_strdup(str));
8057 +}
8058 +
8059 +static inline int cow_seek_file(int fd, __u64 offset)
8060 +{
8061 +       return(os_seek_file(fd, offset));
8062 +}
8063 +
8064 +static inline int cow_file_size(char *file, __u64 *size_out)
8065 +{
8066 +       return(os_file_size(file, size_out));
8067 +}
8068 +
8069 +static inline int cow_write_file(int fd, char *buf, int size)
8070 +{
8071 +       return(os_write_file(fd, buf, size));
8072 +}
8073 +
8074 +#endif
8075 +
8076 +/*
8077 + * ---------------------------------------------------------------------------
8078 + * Local variables:
8079 + * c-file-style: "linux"
8080 + * End:
8081 + */
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
8086 @@ -27,10 +27,10 @@
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]);
8098  }
8099  
8100  int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
8101 @@ -44,15 +44,15 @@
8102         char **args = NULL;
8103  
8104         err = os_pipe(in_fds, 1, 0);
8105 -       if(err){
8106 -               printk("harddog_open - os_pipe failed, errno = %d\n", -err);
8107 -               return(err);
8108 +       if(err < 0){
8109 +               printk("harddog_open - os_pipe failed, err = %d\n", -err);
8110 +               goto out;
8111         }
8112  
8113         err = os_pipe(out_fds, 1, 0);
8114 -       if(err){
8115 -               printk("harddog_open - os_pipe failed, errno = %d\n", -err);
8116 -               return(err);
8117 +       if(err < 0){
8118 +               printk("harddog_open - os_pipe failed, err = %d\n", -err);
8119 +               goto out_close_in;
8120         }
8121  
8122         data.stdin = out_fds[0];
8123 @@ -72,42 +72,47 @@
8124  
8125         pid = run_helper(pre_exec, &data, args, NULL);
8126  
8127 -       close(out_fds[0]);
8128 -       close(in_fds[1]);
8129 +       os_close_file(out_fds[0]);
8130 +       os_close_file(in_fds[1]);
8131  
8132         if(pid < 0){
8133                 err = -pid;
8134 -               printk("harddog_open - run_helper failed, errno = %d\n", err);
8135 -               goto out;
8136 +               printk("harddog_open - run_helper failed, errno = %d\n", -err);
8137 +               goto out_close_out;
8138         }
8139  
8140 -       n = read(in_fds[0], &c, sizeof(c));
8141 +       n = os_read_file(in_fds[0], &c, sizeof(c));
8142         if(n == 0){
8143                 printk("harddog_open - EOF on watchdog pipe\n");
8144                 helper_wait(pid);
8145                 err = -EIO;
8146 -               goto out;
8147 +               goto out_close_out;
8148         }
8149         else if(n < 0){
8150                 printk("harddog_open - read of watchdog pipe failed, "
8151 -                      "errno = %d\n", errno);
8152 +                      "err = %d\n", -n);
8153                 helper_wait(pid);
8154 -               err = -errno;
8155 -               goto out;
8156 +               err = n;
8157 +               goto out_close_out;
8158         }
8159         *in_fd_ret = in_fds[0];
8160         *out_fd_ret = out_fds[1];
8161         return(0);
8162 +
8163 + out_close_in:
8164 +       os_close_file(in_fds[0]);
8165 +       os_close_file(in_fds[1]);
8166 + out_close_out:
8167 +       os_close_file(out_fds[0]);
8168 +       os_close_file(out_fds[1]);
8169   out:
8170 -       close(out_fds[1]);
8171 -       close(in_fds[0]);
8172         return(err);
8173  }
8174  
8175  void stop_watchdog(int in_fd, int out_fd)
8176  {
8177 -       close(in_fd);
8178 -       close(out_fd);
8179 +       os_close_file(in_fd);
8180 +       os_close_file(out_fd);
8181  }
8182  
8183  int ping_watchdog(int fd)
8184 @@ -115,11 +120,12 @@
8185         int n;
8186         char c = '\n';
8187  
8188 -       n = write(fd, &c, sizeof(c));
8189 -       if(n < sizeof(c)){
8190 -               printk("ping_watchdog - write failed, errno = %d\n",
8191 -                      errno);
8192 -               return(-errno);
8193 +       n = os_write_file(fd, &c, sizeof(c));
8194 +       if(n != sizeof(c)){
8195 +               printk("ping_watchdog - write failed, err = %d\n", -n);
8196 +               if(n < 0) 
8197 +                       return(n);
8198 +               return(-EIO);
8199         }
8200         return 1;
8201  
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
8206 @@ -0,0 +1,361 @@
8207 +/* 
8208 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
8209 + * Licensed under the GPL
8210 + */
8211 +
8212 +#include <unistd.h>
8213 +#include <stdio.h>
8214 +#include <fcntl.h>
8215 +#include <dirent.h>
8216 +#include <errno.h>
8217 +#include <utime.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"
8224 +#include "user.h"
8225 +
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)
8231 +{
8232 +       struct stat64 buf;
8233 +
8234 +       if(lstat64(path, &buf) < 0) 
8235 +               return(-errno);
8236 +
8237 +       /* See the Makefile for why STAT64_INO_FIELD is passed in
8238 +        * by the build
8239 +        */
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;
8249 +       }
8250 +       if(mtime_out != NULL) {
8251 +               mtime_out->tv_sec = buf.st_mtime;
8252 +               mtime_out->tv_nsec = 0;
8253 +       }
8254 +       if(ctime_out != NULL) {
8255 +               ctime_out->tv_sec = buf.st_ctime;
8256 +               ctime_out->tv_nsec = 0;
8257 +       }
8258 +       if(blksize_out != NULL) *blksize_out = buf.st_blksize;
8259 +       if(blocks_out != NULL) *blocks_out = buf.st_blocks;
8260 +       return(0);
8261 +}
8262 +
8263 +int file_type(const char *path, int *rdev)
8264 +{
8265 +       struct stat64 buf;
8266 +
8267 +       if(lstat64(path, &buf) < 0) 
8268 +               return(-errno);
8269 +       if(rdev != NULL) 
8270 +               *rdev = buf.st_rdev;
8271 +
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);
8279 +}
8280 +
8281 +int access_file(char *path, int r, int w, int x)
8282 +{
8283 +       int mode = 0;
8284 +
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);
8289 +       else return(0);
8290 +}
8291 +
8292 +int open_file(char *path, int r, int w, int append)
8293 +{
8294 +       int mode = 0, fd;
8295 +
8296 +       if(r && !w) 
8297 +               mode = O_RDONLY;
8298 +       else if(!r && w) 
8299 +               mode = O_WRONLY;
8300 +       else if(r && w) 
8301 +               mode = O_RDWR;
8302 +       else panic("Impossible mode in open_file");
8303 +
8304 +       if(append)
8305 +               mode |= O_APPEND;
8306 +       fd = open64(path, mode);
8307 +       if(fd < 0) return(-errno);
8308 +       else return(fd);
8309 +}
8310 +
8311 +void *open_dir(char *path, int *err_out)
8312 +{
8313 +       DIR *dir;
8314 +
8315 +       dir = opendir(path);
8316 +       *err_out = errno;
8317 +       if(dir == NULL) return(NULL);
8318 +       return(dir);
8319 +}
8320 +
8321 +char *read_dir(void *stream, unsigned long long *pos, 
8322 +              unsigned long long *ino_out, int *len_out)
8323 +{
8324 +       DIR *dir = stream;
8325 +       struct dirent *ent;
8326 +
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);
8334 +}
8335 +
8336 +int read_file(int fd, unsigned long long *offset, char *buf, int len)
8337 +{
8338 +       int n;
8339 +
8340 +       n = pread64(fd, buf, len, *offset);
8341 +       if(n < 0) return(-errno);
8342 +       *offset += n;
8343 +       return(n);
8344 +}
8345 +
8346 +int write_file(int fd, unsigned long long *offset, const char *buf, int len)
8347 +{
8348 +       int n;
8349 +
8350 +       n = pwrite64(fd, buf, len, *offset);
8351 +       if(n < 0) return(-errno);
8352 +       *offset += n;
8353 +       return(n);
8354 +}
8355 +
8356 +int lseek_file(int fd, long long offset, int whence)
8357 +{
8358 +       int ret;
8359 +
8360 +       ret = lseek64(fd, offset, whence);
8361 +       if(ret < 0) return(-errno);
8362 +       return(0);
8363 +}
8364 +
8365 +void close_file(void *stream)
8366 +{
8367 +       close(*((int *) stream));
8368 +}
8369 +
8370 +void close_dir(void *stream)
8371 +{
8372 +       closedir(stream);
8373 +}
8374 +
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)
8377 +{
8378 +       int mode, fd;
8379 +
8380 +       mode = 0;
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);
8391 +       if(fd < 0) 
8392 +               return(-errno);
8393 +       return(fd);
8394 +}
8395 +
8396 +int set_attr(const char *file, struct hostfs_iattr *attrs)
8397 +{
8398 +       struct utimbuf buf;
8399 +       int err, ma;
8400 +
8401 +       if(attrs->ia_valid & HOSTFS_ATTR_MODE){
8402 +               if(chmod(file, attrs->ia_mode) != 0) return(-errno);
8403 +       }
8404 +       if(attrs->ia_valid & HOSTFS_ATTR_UID){
8405 +               if(chown(file, attrs->ia_uid, -1)) return(-errno);
8406 +       }
8407 +       if(attrs->ia_valid & HOSTFS_ATTR_GID){
8408 +               if(chown(file, -1, attrs->ia_gid)) return(-errno);
8409 +       }
8410 +       if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
8411 +               if(truncate(file, attrs->ia_size)) return(-errno);
8412 +       }
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);
8418 +       }
8419 +       else {
8420 +               struct timespec ts;
8421 +
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);
8425 +                       if(err != 0) 
8426 +                               return(err);
8427 +                       buf.actime = attrs->ia_atime.tv_sec;
8428 +                       buf.modtime = ts.tv_sec;
8429 +                       if(utime(file, &buf) != 0) 
8430 +                               return(-errno);
8431 +               }
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);
8435 +                       if(err != 0) 
8436 +                               return(err);
8437 +                       buf.actime = ts.tv_sec;
8438 +                       buf.modtime = attrs->ia_mtime.tv_sec;
8439 +                       if(utime(file, &buf) != 0) 
8440 +                               return(-errno);
8441 +               }
8442 +       }
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, 
8447 +                               NULL, NULL);
8448 +               if(err != 0) return(err);
8449 +       }
8450 +       return(0);
8451 +}
8452 +
8453 +int make_symlink(const char *from, const char *to)
8454 +{
8455 +       int err;
8456 +
8457 +       err = symlink(to, from);
8458 +       if(err) return(-errno);
8459 +       return(0);
8460 +}
8461 +
8462 +int unlink_file(const char *file)
8463 +{
8464 +       int err;
8465 +
8466 +       err = unlink(file);
8467 +       if(err) return(-errno);
8468 +       return(0);
8469 +}
8470 +
8471 +int do_mkdir(const char *file, int mode)
8472 +{
8473 +       int err;
8474 +
8475 +       err = mkdir(file, mode);
8476 +       if(err) return(-errno);
8477 +       return(0);
8478 +}
8479 +
8480 +int do_rmdir(const char *file)
8481 +{
8482 +       int err;
8483 +
8484 +       err = rmdir(file);
8485 +       if(err) return(-errno);
8486 +       return(0);
8487 +}
8488 +
8489 +int do_mknod(const char *file, int mode, int dev)
8490 +{
8491 +       int err;
8492 +
8493 +       err = mknod(file, mode, dev);
8494 +       if(err) return(-errno);
8495 +       return(0);
8496 +}
8497 +
8498 +int link_file(const char *to, const char *from)
8499 +{
8500 +       int err;
8501 +
8502 +       err = link(to, from);
8503 +       if(err) return(-errno);
8504 +       return(0);
8505 +}
8506 +
8507 +int do_readlink(char *file, char *buf, int size)
8508 +{
8509 +       int n;
8510 +
8511 +       n = readlink(file, buf, size);
8512 +       if(n < 0) 
8513 +               return(-errno);
8514 +       if(n < size) 
8515 +               buf[n] = '\0';
8516 +       return(n);
8517 +}
8518 +
8519 +int rename_file(char *from, char *to)
8520 +{
8521 +       int err;
8522 +
8523 +       err = rename(from, to);
8524 +       if(err < 0) return(-errno);
8525 +       return(0);      
8526 +}
8527 +
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, 
8532 +             long *spare_out)
8533 +{
8534 +       struct statfs64 buf;
8535 +       int err;
8536 +
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];
8555 +       return(0);
8556 +}
8557 +
8558 +/*
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
8562 + * of the file.
8563 + * ---------------------------------------------------------------------------
8564 + * Local variables:
8565 + * c-file-style: "linux"
8566 + * End:
8567 + */
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
8572 @@ -7,6 +7,7 @@
8573  #include <sys/mman.h>
8574  #include <sys/ptrace.h>
8575  #include "mem_user.h"
8576 +#include "mem.h"
8577  #include "user.h"
8578  #include "os.h"
8579  #include "proc_mm.h"
8580 @@ -15,12 +16,12 @@
8581          int r, int w, int x)
8582  {
8583         struct proc_mm_op map;
8584 -       struct mem_region *region;
8585 -       int prot, n;
8586 +       __u64 offset;
8587 +       int prot, n, phys_fd;
8588  
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);
8593  
8594         map = ((struct proc_mm_op) { .op        = MM_MMAP,
8595                                      .u         = 
8596 @@ -30,12 +31,12 @@
8597                                          .prot          = prot,
8598                                          .flags         = MAP_SHARED | 
8599                                                           MAP_FIXED,
8600 -                                        .fd            = region->fd,
8601 -                                        .offset        = phys_offset(phys)
8602 +                                        .fd            = phys_fd,
8603 +                                        .offset        = offset
8604                                        } } } );
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);
8609  }
8610  
8611  int unmap(int fd, void *addr, int len)
8612 @@ -49,8 +50,13 @@
8613                                          { .addr        = (unsigned long) addr,
8614                                            .len         = len } } } );
8615         n = os_write_file(fd, &unmap, sizeof(unmap));
8616 -       if((n != 0) && (n != sizeof(unmap)))
8617 -               return(-errno);
8618 +       if(n != sizeof(unmap)) {
8619 +               if(n < 0) 
8620 +                       return(n);
8621 +               else if(n > 0) 
8622 +                       return(-EIO);
8623 +       }
8624 +
8625         return(0);
8626  }
8627  
8628 @@ -71,11 +77,15 @@
8629                                            .prot        = prot } } } );
8630  
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);
8635 +
8636                 if(must_succeed)
8637 -                       panic("protect failed, errno = %d", errno);
8638 -               return(-errno);
8639 +                       panic("protect failed, err = %d", -n);
8640 +
8641 +               return(-EIO);
8642         }
8643 +
8644         return(0);
8645  }
8646  
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
8651 @@ -10,6 +10,15 @@
8652  
8653  #ifdef UML_CONFIG_MODE_SKAS
8654  
8655 +/* syscall emulation path in ptrace */
8656 +
8657 +#ifndef PTRACE_SYSEMU
8658 +#define PTRACE_SYSEMU 31
8659 +#endif
8660 +
8661 +void set_using_sysemu(int value);
8662 +int get_using_sysemu(void);
8663 +
8664  #include "skas_ptregs.h"
8665  
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
8671 @@ -1,5 +1,5 @@
8672  /* 
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
8676   */
8677  
8678 @@ -56,6 +56,93 @@
8679         pr_reg[16] = PT_REGS_SS(regs);          \
8680  } while(0);
8681  
8682 +#if 0 /* Turn this back on when UML has VSYSCALL working */
8683 +#define VSYSCALL_BASE  (__fix_to_virt(FIX_VSYSCALL))
8684 +#else
8685 +#define VSYSCALL_BASE  0
8686 +#endif
8687 +
8688 +#define VSYSCALL_EHDR  ((const struct elfhdr *) VSYSCALL_BASE)
8689 +#define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
8690 +extern void *__kernel_vsyscall;
8691 +
8692 +/*
8693 + * Architecture-neutral AT_ values in 0-17, leave some room
8694 + * for more of them, start the x86-specific ones at 32.
8695 + */
8696 +#define AT_SYSINFO             32
8697 +#define AT_SYSINFO_EHDR                33
8698 +
8699 +#define ARCH_DLINFO                                            \
8700 +do {                                                           \
8701 +               NEW_AUX_ENT(AT_SYSINFO, VSYSCALL_ENTRY);        \
8702 +               NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE);    \
8703 +} while (0)
8704 +
8705 +/*
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.
8712 + */
8713 +#if 0
8714 +#define ELF_CORE_EXTRA_PHDRS           (VSYSCALL_EHDR->e_phnum)
8715 +#endif
8716 +
8717 +#undef ELF_CORE_EXTRA_PHDRS
8718 +
8719 +#if 0
8720 +#define ELF_CORE_WRITE_EXTRA_PHDRS                                           \
8721 +do {                                                                         \
8722 +       const struct elf_phdr *const vsyscall_phdrs =                         \
8723 +               (const struct elf_phdr *) (VSYSCALL_BASE                      \
8724 +                                          + VSYSCALL_EHDR->e_phoff);         \
8725 +       int i;                                                                \
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;                              \
8732 +               }                                                             \
8733 +               else                                                          \
8734 +                       phdr.p_offset += ofs;                                 \
8735 +               phdr.p_paddr = 0; /* match other core phdrs */                \
8736 +               DUMP_WRITE(&phdr, sizeof(phdr));                              \
8737 +       }                                                                     \
8738 +} while (0)
8739 +#define ELF_CORE_WRITE_EXTRA_DATA                                            \
8740 +do {                                                                         \
8741 +       const struct elf_phdr *const vsyscall_phdrs =                         \
8742 +               (const struct elf_phdr *) (VSYSCALL_BASE                      \
8743 +                                          + VSYSCALL_EHDR->e_phoff);         \
8744 +       int i;                                                                \
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);               \
8749 +       }                                                                     \
8750 +} while (0)
8751 +#endif
8752 +
8753 +#undef ELF_CORE_WRITE_EXTRA_PHDRS
8754 +#undef ELF_CORE_WRITE_EXTRA_DATA
8755 +
8756 +#define R_386_NONE     0
8757 +#define R_386_32       1
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
8768 +
8769  /********* Bits for asm-um/delay.h **********/
8770  
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
8776 @@ -6,6 +6,12 @@
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"
8789 @@ -17,6 +23,59 @@
8790  #include "kern.h"
8791  #include "mode.h"
8792  
8793 +#ifdef PTRACE_SYSEMU
8794 +static atomic_t using_sysemu;
8795 +#endif
8796 +
8797 +void set_using_sysemu(int value)
8798 +{
8799 +       atomic_set(&using_sysemu, value);
8800 +}
8801 +
8802 +int get_using_sysemu(void)
8803 +{
8804 +       return atomic_read(&using_sysemu);
8805 +}
8806 +
8807 +int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data)
8808 +{
8809 +       if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size) /*No overflow*/
8810 +               *eof = 1;
8811 +
8812 +       return strlen(buf);
8813 +}
8814 +
8815 +int proc_write_sysemu(struct file *file,const char *buf, unsigned long count,void *data)
8816 +{
8817 +       char tmp[2];
8818 +
8819 +       if (copy_from_user(tmp, buf, 1))
8820 +               return -EFAULT;
8821 +
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*/
8825 +}
8826 +
8827 +int __init make_proc_sysemu(void)
8828 +{
8829 +       struct proc_dir_entry *ent;
8830 +
8831 +       ent = create_proc_entry("sysemu", 00600, &proc_root);
8832 +       ent->read_proc  = proc_read_sysemu;
8833 +       ent->write_proc = proc_write_sysemu;
8834 +
8835 +       if (ent == NULL)
8836 +       {
8837 +               printk("Failed to register /proc/sysemu\n");
8838 +               return(0);
8839 +       }
8840 +
8841 +       return 0;
8842 +}
8843 +
8844 +late_initcall(make_proc_sysemu);
8845 +
8846  int singlestepping_skas(void)
8847  {
8848         int ret = current->ptrace & PT_DTRACE;
8849 @@ -61,11 +120,13 @@
8850         thread_wait(&current->thread.mode.skas.switch_buf, 
8851                     current->thread.mode.skas.fork_buf);
8852  
8853 -#ifdef CONFIG_SMP
8854 -       schedule_tail(NULL);
8855 -#endif
8856 +       if(current->thread.prev_sched != NULL)
8857 +               schedule_tail(current->thread.prev_sched);
8858         current->thread.prev_sched = NULL;
8859  
8860 +       /* The return value is 1 if the kernel thread execs a process,
8861 +        * 0 if it just exits
8862 +        */
8863         n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
8864         if(n == 1)
8865                 userspace(&current->thread.regs.regs);
8866 @@ -93,11 +154,11 @@
8867                     current->thread.mode.skas.fork_buf);
8868         
8869         force_flush_all();
8870 -#ifdef CONFIG_SMP
8871 +       if(current->thread.prev_sched == NULL)
8872 +               panic("blech");
8873 +       
8874         schedule_tail(current->thread.prev_sched);
8875 -#endif
8876         current->thread.prev_sched = NULL;
8877 -       unblock_signals();
8878  
8879         userspace(&current->thread.regs.regs);
8880  }
8881 @@ -136,7 +197,7 @@
8882  
8883  void init_idle_skas(void)
8884  {
8885 -       cpu_tasks[current->thread_info->cpu].pid = os_getpid();
8886 +       cpu_tasks[current_thread->cpu].pid = os_getpid();
8887         default_idle();
8888  }
8889  
8890 @@ -160,11 +221,11 @@
8891  
8892  int start_uml_skas(void)
8893  {
8894 -       start_userspace();
8895 +       start_userspace(0);
8896         capture_signal_stack();
8897 +       uml_idle_timer();
8898  
8899         init_new_thread_signals(1);
8900 -       idle_timer();
8901  
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 @@
8905  
8906  int external_pid_skas(struct task_struct *task)
8907  {
8908 -       return(userspace_pid);
8909 +#warning Need to look up userspace_pid by cpu  
8910 +       return(userspace_pid[0]);
8911  }
8912  
8913  int thread_pid_skas(struct task_struct *task)
8914  {
8915 -       return(userspace_pid);
8916 +#warning Need to look up userspace_pid by cpu  
8917 +       return(userspace_pid[0]);
8918  }
8919  
8920  /*
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
8925 @@ -7,12 +7,12 @@
8926  #include <stdlib.h>
8927  #include <unistd.h>
8928  #include <errno.h>
8929 -#include <fcntl.h>
8930  #include <sched.h>
8931  #include <sys/signal.h>
8932  #include <sys/wait.h>
8933  #include "user.h"
8934  #include "kern_util.h"
8935 +#include "user_util.h"
8936  #include "os.h"
8937  
8938  struct helper_data {
8939 @@ -33,6 +33,7 @@
8940  {
8941         struct helper_data *data = arg;
8942         char **argv = data->argv;
8943 +       int errval;
8944  
8945         if(helper_pause){
8946                 signal(SIGHUP, helper_hup);
8947 @@ -41,8 +42,9 @@
8948         if(data->pre_exec != NULL)
8949                 (*data->pre_exec)(data->pre_data);
8950         execvp(argv[0], argv);
8951 +       errval = errno;
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);
8956         return(0);
8957  }
8958 @@ -59,17 +61,20 @@
8959         if((stack_out != NULL) && (*stack_out != 0))
8960                 stack = *stack_out;
8961         else stack = alloc_stack(0, um_in_interrupt());
8962 -       if(stack == 0) return(-ENOMEM);
8963 +       if(stack == 0) 
8964 +               return(-ENOMEM);
8965  
8966         err = os_pipe(fds, 1, 0);
8967 -       if(err){
8968 -               printk("run_helper : pipe failed, errno = %d\n", -err);
8969 -               return(err);
8970 +       if(err < 0){
8971 +               printk("run_helper : pipe failed, err = %d\n", -err);
8972 +               goto out_free;
8973         }
8974 -       if(fcntl(fds[1], F_SETFD, 1) != 0){
8975 -               printk("run_helper : setting FD_CLOEXEC failed, errno = %d\n",
8976 -                      errno);
8977 -               return(-errno);
8978 +
8979 +       err = os_set_exec_close(fds[1], 1);
8980 +       if(err < 0){
8981 +               printk("run_helper : setting FD_CLOEXEC failed, err = %d\n",
8982 +                      -err);
8983 +               goto out_close;
8984         }
8985  
8986         sp = stack + page_size() - sizeof(void *);
8987 @@ -80,23 +85,34 @@
8988         pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
8989         if(pid < 0){
8990                 printk("run_helper : clone failed, errno = %d\n", errno);
8991 -               return(-errno);
8992 +               err = -errno;
8993 +               goto out_close;
8994         }
8995 -       close(fds[1]);
8996 -       n = read(fds[0], &err, sizeof(err));
8997 +
8998 +       os_close_file(fds[1]);
8999 +       n = os_read_file(fds[0], &err, sizeof(err));
9000         if(n < 0){
9001 -               printk("run_helper : read on pipe failed, errno = %d\n", 
9002 -                      errno);
9003 -               return(-errno);
9004 +               printk("run_helper : read on pipe failed, err = %d\n", -n);
9005 +               err = n;
9006 +               goto out_kill;
9007         }
9008         else if(n != 0){
9009 -               waitpid(pid, NULL, 0);
9010 -               pid = -err;
9011 +               CATCH_EINTR(n = waitpid(pid, NULL, 0));
9012 +               pid = -errno;
9013         }
9014  
9015         if(stack_out == NULL) free_stack(stack, 0);
9016          else *stack_out = stack;
9017         return(pid);
9018 +
9019 + out_kill:
9020 +       os_kill_process(pid, 1);
9021 + out_close:
9022 +       os_close_file(fds[0]);
9023 +       os_close_file(fds[1]);
9024 + out_free:
9025 +       free_stack(stack, 0);
9026 +       return(err);
9027  }
9028  
9029  int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, 
9030 @@ -117,9 +133,11 @@
9031         }
9032         if(stack_out == NULL){
9033                 pid = waitpid(pid, &status, 0);
9034 -               if(pid < 0)
9035 +               if(pid < 0){
9036                         printk("run_helper_thread - wait failed, errno = %d\n",
9037 -                              pid);
9038 +                              errno);
9039 +                       pid = -errno;
9040 +               }
9041                 if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
9042                         printk("run_helper_thread - thread returned status "
9043                                "0x%x\n", 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
9048 @@ -35,7 +35,8 @@
9049                 printk("fd_init : couldn't parse file descriptor '%s'\n", str);
9050                 return(NULL);
9051         }
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 });
9057         return(data);
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
9062 @@ -60,12 +60,11 @@
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);
9077 @@ -89,9 +88,7 @@
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);
9087 @@ -100,7 +97,9 @@
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);
9097 @@ -111,6 +110,8 @@
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);
9102 +
9103  #endif
9104  
9105  /*
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
9110 @@ -0,0 +1,7 @@
9111 +#ifndef _UM_SECTIONS_H
9112 +#define _UM_SECTIONS_H
9113 +
9114 +/* nothing to see, move along */
9115 +#include <asm-generic/sections.h>
9116 +
9117 +#endif
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
9122 @@ -12,8 +12,6 @@
9123  #include "asm/page.h"
9124  #include "asm/fixmap.h"
9125  
9126 -extern pgd_t swapper_pg_dir[1024];
9127 -
9128  extern void *um_virt_to_phys(struct task_struct *task, unsigned long virt,
9129                              pte_t *pte_out);
9130  
9131 @@ -49,6 +47,8 @@
9132  #define pgd_ERROR(e) \
9133          printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
9134  
9135 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
9136 +
9137  /*
9138   * pgd entries used up by user/kernel:
9139   */
9140 @@ -65,10 +65,10 @@
9141   * area for the same reason. ;)
9142   */
9143  
9144 -extern unsigned long high_physmem;
9145 +extern unsigned long end_iomem;
9146  
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))
9150  
9151  #ifdef CONFIG_HIGHMEM
9152  # define VMALLOC_END   (PKMAP_BASE-2*PAGE_SIZE)
9153 @@ -78,12 +78,13 @@
9154  
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
9170  
9171  #define REGION_MASK    0xf0000000
9172  #define REGION_SHIFT   28
9173 @@ -143,7 +144,8 @@
9174  
9175  #define BAD_PAGETABLE __bad_pagetable()
9176  #define BAD_PAGE __bad_page()
9177 -#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
9178 +
9179 +#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
9180  
9181  /* number of bits that fit into a memory pointer */
9182  #define BITS_PER_PTR                   (8*sizeof(unsigned long))
9183 @@ -164,9 +166,6 @@
9184  
9185  #define pte_clear(xp)  do { pte_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
9186  
9187 -#define phys_region_index(x) (((x) & REGION_MASK) >> REGION_SHIFT)
9188 -#define pte_region_index(x) phys_region_index(pte_val(x))
9189 -
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 @@
9194  
9195  #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
9196  
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);
9201 -
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)
9209 +
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))
9213 +
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)
9217 +  
9218 +/*
9219 + * Bits 0 through 3 are taken
9220 + */
9221 +#define PTE_FILE_MAX_BITS      28
9222 +
9223 +#define pte_to_pgoff(pte) ((pte).pte_low >> 4)
9224 +
9225 +#define pgoff_to_pte(off) \
9226 +       ((pte_t) { ((off) << 4) + _PAGE_FILE })
9227  
9228  static inline pte_t pte_mknewprot(pte_t pte)
9229  {
9230 @@ -235,6 +240,12 @@
9231   * The following only work if pte_present() is true.
9232   * Undefined behaviour if not..
9233   */
9234 +static inline int pte_user(pte_t pte)
9235 +{ 
9236 +       return((pte_val(pte) & _PAGE_USER) && 
9237 +              !(pte_val(pte) & _PAGE_PROTNONE));
9238 +}
9239 +
9240  static inline int pte_read(pte_t pte)
9241  { 
9242         return((pte_val(pte) & _PAGE_USER) && 
9243 @@ -252,6 +263,14 @@
9244                !(pte_val(pte) & _PAGE_PROTNONE));
9245  }
9246  
9247 +/*
9248 + * The following only works if pte_present() is not true.
9249 + */
9250 +static inline int pte_file(pte_t pte)
9251 +{ 
9252 +       return (pte).pte_low & _PAGE_FILE; 
9253 +}
9254 +
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.
9260   */
9261  
9262 -#define mk_pte(page, pgprot) \
9263 -({                                     \
9264 -       pte_t __pte;                    \
9265 -                                        \
9266 -       pte_val(__pte) = page_to_phys(page) + pgprot_val(pgprot);\
9267 -       if(pte_present(__pte)) pte_mknewprot(pte_mknewpage(__pte)); \
9268 -       __pte;                          \
9269 -})
9270 +extern pte_t mk_pte(struct page *page, pgprot_t pgprot);
9271  
9272  static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
9273  {
9274 @@ -351,17 +363,27 @@
9275  }
9276  
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)))
9280  
9281 -/* to find an entry in a page-table-directory. */
9282 +/*
9283 + * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
9284 + *
9285 + * this macro returns the index of the entry in the pgd page which would
9286 + * control the given virtual address
9287 + */
9288  #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
9289  
9290 -/* to find an entry in a page-table-directory */
9291 +/*
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;
9294 + */
9295  #define pgd_offset(mm, address) \
9296  ((mm)->pgd + ((address) >> PGDIR_SHIFT))
9297  
9298 -/* to find an entry in a kernel page-table-directory */
9299 +
9300 +/*
9301 + * a shortcut which implies the use of the kernel's pgd, instead
9302 + * of a process's
9303 + */
9304  #define pgd_offset_k(address) pgd_offset(&init_mm, address)
9305  
9306  #define pmd_index(address) \
9307 @@ -373,7 +395,12 @@
9308         return (pmd_t *) dir;
9309  }
9310  
9311 -/* Find an entry in the third-level page table.. */ 
9312 +/*
9313 + * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
9314 + *
9315 + * this macro returns the index of the entry in the pte page which would
9316 + * control the given virtual address
9317 + */
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)
9323  
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)
9329  
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 @@
9341  
9342  config UNIX98_PTYS
9343         bool "Unix98 PTY support"
9344 -
9345 -config UNIX98_PTY_COUNT
9346 -       int "Maximum number of Unix98 PTYs in use (0-2048)"
9347 -       depends on UNIX98_PTYS
9348 +       ---help---
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
9354 +         and xterms.
9355 +
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.
9364 +
9365 +         All modern Linux systems use the Unix98 ptys.  Say Y unless
9366 +         you're on an embedded system and want to conserve memory.
9367 +
9368 +config LEGACY_PTYS
9369 +       bool "Legacy (BSD) PTY support"
9370 +       default y
9371 +       ---help---
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
9377 +         and xterms.
9378 +
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.
9384 +
9385 +
9386 +config LEGACY_PTY_COUNT
9387 +       int "Maximum number of legacy PTY in use"
9388 +       depends on LEGACY_PTYS
9389         default "256"
9390 +       ---help---
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.
9394 +
9395 +         When not in use, each legacy PTY occupies 12 bytes on 32-bit
9396 +         architectures and 24 bytes on 64-bit architectures.
9397 +
9398 +#config UNIX98_PTY_COUNT
9399 +#      int "Maximum number of Unix98 PTYs in use (0-2048)"
9400 +#      depends on UNIX98_PTYS
9401 +#      default "256"
9402  
9403  config WATCHDOG
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
9409 @@ -5,7 +5,6 @@
9410  
9411  #include <stdio.h>
9412  #include <stdlib.h>
9413 -#include <fcntl.h>
9414  #include <unistd.h>
9415  #include <limits.h>
9416  #include <sys/mman.h> 
9417 @@ -82,10 +81,10 @@
9418         int status, ret;
9419  
9420         while(1){
9421 -               if(((ret = waitpid(pid, &status, WUNTRACED)) < 0) ||
9422 +               CATCH_EINTR(ret = waitpid(pid, &status, WUNTRACED));
9423 +               if((ret < 0) ||
9424                    !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
9425                         if(ret < 0){
9426 -                               if(errno == EINTR) continue;
9427                                 printk("wait failed, errno = %d\n",
9428                                        errno);
9429                         }
9430 @@ -119,29 +118,36 @@
9431         }
9432  }
9433  
9434 -int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags)
9435 -{
9436 -       int pid;
9437 -
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);
9442 -       return(pid);
9443 -}
9444 -
9445 -int raw(int fd, int complain)
9446 +int __raw(int fd, int complain, int now)
9447  {
9448         struct termios tt;
9449         int err;
9450 +       int when;
9451 +
9452 +       CATCH_EINTR(err = tcgetattr(fd, &tt));
9453 +
9454 +       if (err < 0) {
9455 +               if (complain)
9456 +                       printk("tcgetattr failed, errno = %d\n", errno);
9457 +               return(-errno);
9458 +       }
9459  
9460 -       tcgetattr(fd, &tt);
9461         cfmakeraw(&tt);
9462 -       err = tcsetattr(fd, TCSANOW, &tt);
9463 -       if((err < 0) && complain){
9464 -               printk("tcsetattr failed, errno = %d\n", errno);
9465 +
9466 +       if (now)
9467 +               when = TCSANOW;
9468 +       else
9469 +               when = TCSADRAIN;
9470 +
9471 +       CATCH_EINTR(err = tcsetattr(fd, when, &tt));
9472 +
9473 +       if (err < 0) {
9474 +               if (complain)
9475 +                       printk("tcsetattr failed, errno = %d\n", errno);
9476                 return(-errno);
9477         }
9478 +       /*XXX: tcsetattr could have applied only some changes
9479 +        * (and cfmakeraw() is a set of changes) */
9480         return(0);
9481  }
9482  
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
9487 @@ -5,7 +5,6 @@
9488  
9489  #include <stdio.h>
9490  #include <unistd.h>
9491 -#include <fcntl.h>
9492  #include <errno.h>
9493  #include <string.h>
9494  #include <stdlib.h>
9495 @@ -33,18 +32,19 @@
9496  static int umid_is_random = 1;
9497  static int umid_inited = 0;
9498  
9499 -static int make_umid(void);
9500 +static int make_umid(int (*printer)(const char *fmt, ...));
9501  
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, ...))
9505  {
9506         if(umid_inited){
9507 -               printk("Unique machine name can't be set twice\n");
9508 +               (*printer)("Unique machine name can't be set twice\n");
9509                 return(-1);
9510         }
9511  
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));
9518  
9519         umid_is_random = is_random;
9520 @@ -54,7 +54,7 @@
9521  
9522  static int __init set_umid_arg(char *name, int *add)
9523  {
9524 -       return(set_umid(name, 0));
9525 +       return(set_umid(name, 0, printf));
9526  }
9527  
9528  __uml_setup("umid=", set_umid_arg,
9529 @@ -67,7 +67,7 @@
9530  {
9531         int n;
9532  
9533 -       if(!umid_inited && make_umid()) return(-1);
9534 +       if(!umid_inited && make_umid(printk)) return(-1);
9535  
9536         n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
9537         if(n > len){
9538 @@ -85,22 +85,23 @@
9539  {
9540         char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
9541         char pid[sizeof("nnnnn\0")];
9542 -       int fd;
9543 +       int fd, n;
9544  
9545         if(umid_file_name("pid", file, sizeof(file))) return 0;
9546  
9547         fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 
9548                           0644);
9549         if(fd < 0){
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);
9554                 return 0;
9555         }
9556  
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);
9560 -       close(fd);
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);
9565         return 0;
9566  }
9567  
9568 @@ -111,7 +112,8 @@
9569         int len;
9570         char file[256];
9571  
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);
9577                 return(1);
9578 @@ -160,22 +162,24 @@
9579  {
9580         char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
9581         char pid[sizeof("nnnnn\0")], *end;
9582 -       int dead, fd, p;
9583 +       int dead, fd, p, n;
9584  
9585         sprintf(file, "%s/pid", dir);
9586         dead = 0;
9587 -       if((fd = os_open_file(file, of_read(OPENFLAGS()), 0)) < 0){
9588 +       fd = os_open_file(file, of_read(OPENFLAGS()), 0);
9589 +       if(fd < 0){
9590                 if(fd != -ENOENT){
9591                         printk("not_dead_yet : couldn't open pid file '%s', "
9592 -                              "errno = %d\n", file, -fd);
9593 +                              "err = %d\n", file, -fd);
9594                         return(1);
9595                 }
9596                 dead = 1;
9597         }
9598         if(fd > 0){
9599 -               if(read(fd, pid, sizeof(pid)) < 0){
9600 +               n = os_read_file(fd, pid, sizeof(pid));
9601 +               if(n < 0){
9602                         printk("not_dead_yet : couldn't read pid file '%s', "
9603 -                              "errno = %d\n", file, errno);
9604 +                              "err = %d\n", file, -n);
9605                         return(1);
9606                 }
9607                 p = strtoul(pid, &end, 0);
9608 @@ -197,7 +201,7 @@
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",
9614                                errno);
9615                         uml_dir = name;
9616                         return(0);
9617 @@ -217,7 +221,7 @@
9618                 char *home = getenv("HOME");
9619  
9620                 if(home == NULL){
9621 -                       printk("make_uml_dir : no value in environment for "
9622 +                       printf("make_uml_dir : no value in environment for "
9623                                "$HOME\n");
9624                         exit(1);
9625                 }
9626 @@ -232,57 +236,59 @@
9627                 dir[len + 1] = '\0';
9628         }
9629  
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);
9634                 exit(1);
9635         }
9636         strcpy(uml_dir, dir);
9637         
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);
9641                 return(-1);
9642         }
9643         return 0;
9644  }
9645  
9646 -static int __init make_umid(void)
9647 +static int __init make_umid(int (*printer)(const char *fmt, ...))
9648  {
9649         int fd, err;
9650         char tmp[strlen(uml_dir) + UMID_LEN + 1];
9651  
9652         strlcpy(tmp, uml_dir, sizeof(tmp));
9653  
9654 -       if(*umid == 0){
9655 +       if(!umid_inited){
9656                 strcat(tmp, "XXXXXX");
9657                 fd = mkstemp(tmp);
9658                 if(fd < 0){
9659 -                       printk("make_umid - mkstemp failed, errno = %d\n",
9660 -                              errno);
9661 +                       (*printer)("make_umid - mkstemp failed, errno = %d\n",
9662 +                                  errno);
9663                         return(1);
9664                 }
9665  
9666 -               close(fd);
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
9670                  * for directories.
9671                  */
9672                 unlink(tmp);
9673 -               set_umid(&tmp[strlen(uml_dir)], 1);
9674 +               set_umid(&tmp[strlen(uml_dir)], 1, printer);
9675         }
9676         
9677         sprintf(tmp, "%s%s", uml_dir, umid);
9678  
9679 -       if((err = mkdir(tmp, 0777)) < 0){
9680 +       err = mkdir(tmp, 0777);
9681 +       if(err < 0){
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);
9686                                 return(-1);
9687                         }
9688                         err = mkdir(tmp, 0777);
9689                 }
9690         }
9691         if(err < 0){
9692 -               printk("Failed to create %s - errno = %d\n", umid, errno);
9693 +               (*printer)("Failed to create %s - errno = %d\n", umid, errno);
9694                 return(-1);
9695         }
9696  
9697 @@ -295,7 +301,13 @@
9698  );
9699  
9700  __uml_postsetup(make_uml_dir);
9701 -__uml_postsetup(make_umid);
9702 +
9703 +static int __init make_umid_setup(void)
9704 +{
9705 +       return(make_umid(printf));
9706 +}
9707 +
9708 +__uml_postsetup(make_umid_setup);
9709  __uml_postsetup(create_pid_file);
9710  
9711  /*
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
9716 @@ -0,0 +1,236 @@
9717 +/*
9718 + * include/linux/ghash.h -- generic hashing with fuzzy retrieval
9719 + *
9720 + * (C) 1997 Thomas Schoebel-Theuer
9721 + *
9722 + * The algorithms implemented here seem to be a completely new invention,
9723 + * and I'll publish the fundamentals in a paper.
9724 + */
9725 +
9726 +#ifndef _GHASH_H
9727 +#define _GHASH_H
9728 +/* HASHSIZE _must_ be a power of two!!! */
9729 +
9730 +
9731 +#define DEF_HASH_FUZZY_STRUCTS(NAME,HASHSIZE,TYPE) \
9732 +\
9733 +struct NAME##_table {\
9734 +       TYPE * hashtable[HASHSIZE];\
9735 +       TYPE * sorted_list;\
9736 +       int nr_entries;\
9737 +};\
9738 +\
9739 +struct NAME##_ptrs {\
9740 +       TYPE * next_hash;\
9741 +       TYPE * prev_hash;\
9742 +       TYPE * next_sorted;\
9743 +       TYPE * prev_sorted;\
9744 +};
9745 +
9746 +#define DEF_HASH_FUZZY(LINKAGE,NAME,HASHSIZE,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,KEYEQ,HASHFN)\
9747 +\
9748 +LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
9749 +{\
9750 +       int ix = HASHFN(elem->KEY);\
9751 +       TYPE ** base = &tbl->hashtable[ix];\
9752 +       TYPE * ptr = *base;\
9753 +       TYPE * prev = NULL;\
9754 +\
9755 +       tbl->nr_entries++;\
9756 +       while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\
9757 +               base = &ptr->PTRS.next_hash;\
9758 +               prev = ptr;\
9759 +               ptr = *base;\
9760 +       }\
9761 +       elem->PTRS.next_hash = ptr;\
9762 +       elem->PTRS.prev_hash = prev;\
9763 +       if(ptr) {\
9764 +               ptr->PTRS.prev_hash = elem;\
9765 +       }\
9766 +       *base = elem;\
9767 +\
9768 +       ptr = prev;\
9769 +       if(!ptr) {\
9770 +               ptr = tbl->sorted_list;\
9771 +               prev = NULL;\
9772 +       } else {\
9773 +               prev = ptr->PTRS.prev_sorted;\
9774 +       }\
9775 +       while(ptr) {\
9776 +               TYPE * next = ptr->PTRS.next_hash;\
9777 +               if(next && KEYCMP(next->KEY, elem->KEY)) {\
9778 +                       prev = ptr;\
9779 +                       ptr = next;\
9780 +               } else if(KEYCMP(ptr->KEY, elem->KEY)) {\
9781 +                       prev = ptr;\
9782 +                       ptr = ptr->PTRS.next_sorted;\
9783 +               } else\
9784 +                       break;\
9785 +       }\
9786 +       elem->PTRS.next_sorted = ptr;\
9787 +       elem->PTRS.prev_sorted = prev;\
9788 +       if(ptr) {\
9789 +               ptr->PTRS.prev_sorted = elem;\
9790 +       }\
9791 +       if(prev) {\
9792 +               prev->PTRS.next_sorted = elem;\
9793 +       } else {\
9794 +               tbl->sorted_list = elem;\
9795 +       }\
9796 +}\
9797 +\
9798 +LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
9799 +{\
9800 +       TYPE * next = elem->PTRS.next_hash;\
9801 +       TYPE * prev = elem->PTRS.prev_hash;\
9802 +\
9803 +       tbl->nr_entries--;\
9804 +       if(next)\
9805 +               next->PTRS.prev_hash = prev;\
9806 +       if(prev)\
9807 +               prev->PTRS.next_hash = next;\
9808 +       else {\
9809 +               int ix = HASHFN(elem->KEY);\
9810 +               tbl->hashtable[ix] = next;\
9811 +       }\
9812 +\
9813 +       next = elem->PTRS.next_sorted;\
9814 +       prev = elem->PTRS.prev_sorted;\
9815 +       if(next)\
9816 +               next->PTRS.prev_sorted = prev;\
9817 +       if(prev)\
9818 +               prev->PTRS.next_sorted = next;\
9819 +       else\
9820 +               tbl->sorted_list = next;\
9821 +}\
9822 +\
9823 +LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
9824 +{\
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))\
9830 +               ptr = NULL;\
9831 +       return ptr;\
9832 +}\
9833 +\
9834 +LINKAGE TYPE * find_##NAME##_hash_fuzzy(struct NAME##_table * tbl, KEYTYPE pos)\
9835 +{\
9836 +       int ix;\
9837 +       int offset;\
9838 +       TYPE * ptr;\
9839 +       TYPE * next;\
9840 +\
9841 +       ptr = tbl->sorted_list;\
9842 +       if(!ptr || KEYCMP(pos, ptr->KEY))\
9843 +               return NULL;\
9844 +       ix = HASHFN(pos);\
9845 +       offset = HASHSIZE;\
9846 +       do {\
9847 +               offset >>= 1;\
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))\
9851 +                       ptr = next;\
9852 +       } while(offset);\
9853 +\
9854 +       for(;;) {\
9855 +               next = ptr->PTRS.next_hash;\
9856 +               if(next) {\
9857 +                       if(KEYCMP(next->KEY, pos)) {\
9858 +                               ptr = next;\
9859 +                               continue;\
9860 +                       }\
9861 +               }\
9862 +               next = ptr->PTRS.next_sorted;\
9863 +               if(next && KEYCMP(next->KEY, pos)) {\
9864 +                       ptr = next;\
9865 +                       continue;\
9866 +               }\
9867 +               return ptr;\
9868 +       }\
9869 +       return NULL;\
9870 +}
9871 +
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
9875 + *     any others
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
9880 + *     field
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
9889 + * DEF_HASH.
9890 + */
9891 +
9892 +#define DEF_HASH_STRUCTS(NAME,HASHSIZE,TYPE) \
9893 +\
9894 +struct NAME##_table {\
9895 +       TYPE * hashtable[HASHSIZE];\
9896 +       int nr_entries;\
9897 +};\
9898 +\
9899 +struct NAME##_ptrs {\
9900 +       TYPE * next_hash;\
9901 +       TYPE * prev_hash;\
9902 +};
9903 +
9904 +#define DEF_HASH(LINKAGE,NAME,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,HASHFN)\
9905 +\
9906 +LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
9907 +{\
9908 +       int ix = HASHFN(elem->KEY);\
9909 +       TYPE ** base = &tbl->hashtable[ix];\
9910 +       TYPE * ptr = *base;\
9911 +       TYPE * prev = NULL;\
9912 +\
9913 +       tbl->nr_entries++;\
9914 +       while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\
9915 +               base = &ptr->PTRS.next_hash;\
9916 +               prev = ptr;\
9917 +               ptr = *base;\
9918 +       }\
9919 +       elem->PTRS.next_hash = ptr;\
9920 +       elem->PTRS.prev_hash = prev;\
9921 +       if(ptr) {\
9922 +               ptr->PTRS.prev_hash = elem;\
9923 +       }\
9924 +       *base = elem;\
9925 +}\
9926 +\
9927 +LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
9928 +{\
9929 +       TYPE * next = elem->PTRS.next_hash;\
9930 +       TYPE * prev = elem->PTRS.prev_hash;\
9931 +\
9932 +       tbl->nr_entries--;\
9933 +       if(next)\
9934 +               next->PTRS.prev_hash = prev;\
9935 +       if(prev)\
9936 +               prev->PTRS.next_hash = next;\
9937 +       else {\
9938 +               int ix = HASHFN(elem->KEY);\
9939 +               tbl->hashtable[ix] = next;\
9940 +       }\
9941 +}\
9942 +\
9943 +LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
9944 +{\
9945 +       int ix = HASHFN(pos);\
9946 +       TYPE * ptr = tbl->hashtable[ix];\
9947 +       while(ptr && KEYCMP(ptr->KEY, pos))\
9948 +               ptr = ptr->PTRS.next_hash;\
9949 +       return ptr;\
9950 +}
9951 +
9952 +#endif
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
9957 @@ -8,6 +8,8 @@
9958  
9959  #include "sysdep/ptrace.h"
9960  
9961 +enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
9962 +
9963  extern int tracing_pid;
9964  
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
9970 @@ -17,6 +17,32 @@
9971  #define OS_TYPE_FIFO 6
9972  #define OS_TYPE_SOCK 7
9973  
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 */
9980 +
9981 +/*
9982 + * types taken from stat_file() in hostfs_user.c
9983 + * (if they are wrong here, they are wrong there...).
9984 + */
9985 +struct uml_stat {
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 */
9998 +};
9999 +
10000  struct openflags {
10001         unsigned int r : 1;
10002         unsigned int w : 1;
10003 @@ -84,29 +110,47 @@
10004         flags.e = 1; 
10005         return(flags); 
10006  }
10007
10008 +
10009  static inline struct openflags of_cloexec(struct openflags flags)
10010  { 
10011         flags.cl = 1; 
10012         return(flags); 
10013  }
10014    
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);
10029 +
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);
10051  
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);
10057  
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);
10065  
10066  #endif
10067  
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)
10074  {
10075         unsigned long regs[FRAME_SIZE];
10076 +       int err;
10077  
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",
10083                              errno);
10084  
10085 +       CATCH_EINTR(err = waitpid(new_pid, 0, WUNTRACED));
10086 +       if (err < 0)
10087 +               tracer_panic("do_exec failed to attach proc in waitpid - errno = %d",
10088 +                            errno);
10089 +
10090         if(ptrace_getregs(old_pid, regs) < 0)
10091                 tracer_panic("do_exec failed to get registers - errno = %d",
10092                              errno);
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
10097 @@ -1,8 +1,6 @@
10098  #ifndef __UM_TIMEX_H
10099  #define __UM_TIMEX_H
10100  
10101 -#include "linux/time.h"
10102 -
10103  typedef unsigned long cycles_t;
10104  
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
10110 @@ -8,7 +8,7 @@
10111  
10112  #include "sysdep/ptrace.h"
10113  
10114 -extern int userspace_pid;
10115 +extern int userspace_pid[];
10116  
10117  extern void switch_threads(void *me, void *next);
10118  extern void thread_wait(void *sw, void *fb);
10119 @@ -32,7 +32,7 @@
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);
10126  
10127  #endif
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");
10134  
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");
10139 +               return(0);
10140 +       }
10141  
10142         p_buf = __pa(v_buf);
10143  
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
10148 @@ -1,5 +1,5 @@
10149  /* 
10150 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
10151 + * Copyright (C) 2002 Jeff Dike (jdike@addtoit.com)
10152   * Licensed under the GPL
10153   */
10154  
10155 @@ -7,32 +7,38 @@
10156  #include <stdio.h>
10157  #include <errno.h>
10158  #include <signal.h>
10159 +#include <linux/unistd.h>
10160  #include <sys/mman.h>
10161  #include <sys/wait.h>
10162  #include "os.h"
10163  #include "user.h"
10164 +#include "user_util.h"
10165 +
10166 +#define ARBITRARY_ADDR -1
10167 +#define FAILURE_PID    -1
10168  
10169  unsigned long os_process_pc(int pid)
10170  {
10171         char proc_stat[sizeof("/proc/#####/stat\0")], buf[256];
10172         unsigned long pc;
10173 -       int fd;
10174 +       int fd, err;
10175  
10176         sprintf(proc_stat, "/proc/%d/stat", pid);
10177         fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0);
10178         if(fd < 0){
10179 -               printk("os_process_pc - couldn't open '%s', errno = %d\n", 
10180 -                      proc_stat, errno);
10181 -               return(-1);
10182 +               printk("os_process_pc - couldn't open '%s', err = %d\n", 
10183 +                      proc_stat, -fd);
10184 +               return(ARBITRARY_ADDR);
10185         }
10186 -       if(read(fd, buf, sizeof(buf)) < 0){
10187 -               printk("os_process_pc - couldn't read '%s', errno = %d\n", 
10188 -                      proc_stat, errno);
10189 -               close(fd);
10190 -               return(-1);
10191 +       err = os_read_file(fd, buf, sizeof(buf));
10192 +       if(err < 0){
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);
10197         }
10198 -       close(fd);
10199 -       pc = -1;
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);
10208         if(fd < 0){
10209 -               printk("Couldn't open '%s', errno = %d\n", stat, -fd);
10210 -               return(-1);
10211 +               printk("Couldn't open '%s', err = %d\n", stat, -fd);
10212 +               return(FAILURE_PID);
10213         }
10214  
10215 -       n = read(fd, data, sizeof(data));
10216 -       close(fd);
10217 +       n = os_read_file(fd, data, sizeof(data));
10218 +       os_close_file(fd);
10219  
10220         if(n < 0){
10221 -               printk("Couldn't read '%s', errno = %d\n", stat);
10222 -               return(-1);
10223 +               printk("Couldn't read '%s', err = %d\n", stat, -n);
10224 +               return(FAILURE_PID);
10225         }
10226  
10227 -       parent = -1;
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);
10232 +       if(n != 1) 
10233 +               printk("Failed to scan '%s'\n", data);
10234  
10235         return(parent);
10236  }
10237 @@ -81,13 +88,17 @@
10238  {
10239         kill(pid, SIGKILL);
10240         if(reap_child)
10241 -               waitpid(pid, NULL, 0);
10242 +               CATCH_EINTR(waitpid(pid, NULL, 0));
10243                 
10244  }
10245  
10246  void os_usr1_process(int pid)
10247  {
10248 +#ifdef __NR_tkill
10249 +       syscall(__NR_tkill, pid, SIGUSR1); 
10250 +#else
10251         kill(pid, SIGUSR1);
10252 +#endif
10253  }
10254  
10255  int os_getpid(void)
10256 @@ -95,7 +106,7 @@
10257         return(getpid());
10258  }
10259  
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)
10263  {
10264         void *loc;
10265 @@ -104,8 +115,8 @@
10266         prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
10267                 (x ? PROT_EXEC : 0);
10268  
10269 -       loc = mmap((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, 
10270 -                  fd, off);
10271 +       loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, 
10272 +                    fd, off);
10273         if(loc == MAP_FAILED)
10274                 return(-errno);
10275         return(0);
10276 @@ -126,7 +137,8 @@
10277          int err;
10278  
10279          err = munmap(addr, len);
10280 -        if(err < 0) return(-errno);
10281 +       if(err < 0)
10282 +               return(-errno);
10283          return(0);
10284  }
10285  
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
10293  
10294 -struct mem_region {
10295 +struct iomem_region {
10296 +       struct iomem_region *next;
10297         char *driver;
10298 -       unsigned long start_pfn;
10299 -       unsigned long start;
10300 -       unsigned long len;
10301 -       void *mem_map;
10302         int fd;
10303 +       int size;
10304 +       unsigned long phys;
10305 +       unsigned long virt;
10306  };
10307  
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;
10312  
10313  #define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
10314  
10315  extern unsigned long host_task_size;
10316  extern unsigned long task_size;
10317  
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
10351 @@ -23,6 +23,7 @@
10352  #include "kern_util.h"
10353  #include "user_util.h"
10354  #include "user.h"
10355 +#include "os.h"
10356  
10357  #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
10358  
10359 @@ -62,7 +63,8 @@
10360                 goto out;
10361         }
10362  
10363 -       if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
10364 +       fd = socket(AF_INET, SOCK_DGRAM, 0);
10365 +       if (fd < 0){
10366                 printk("mcast_open : data socket failed, errno = %d\n", 
10367                        errno);
10368                 fd = -ENOMEM;
10369 @@ -72,7 +74,7 @@
10370         if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
10371                 printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
10372                         errno);
10373 -               close(fd);
10374 +               os_close_file(fd);
10375                 fd = -EINVAL;
10376                 goto out;
10377         }
10378 @@ -82,7 +84,7 @@
10379                        sizeof(pri->ttl)) < 0) {
10380                 printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
10381                         errno);
10382 -               close(fd);
10383 +               os_close_file(fd);
10384                 fd = -EINVAL;
10385                 goto out;
10386         }
10387 @@ -91,7 +93,7 @@
10388         if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
10389                 printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
10390                         errno);
10391 -               close(fd);
10392 +               os_close_file(fd);
10393                 fd = -EINVAL;
10394                 goto out;
10395         }
10396 @@ -99,7 +101,7 @@
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);
10400 -               close(fd);
10401 +               os_close_file(fd);
10402                 fd = -EINVAL;
10403                 goto out;
10404         }               
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");
10409 -               close(fd);
10410 +               os_close_file(fd);
10411                 fd = -EINVAL;
10412         }
10413  
10414 @@ -137,7 +139,7 @@
10415                         errno);
10416         }
10417  
10418 -       close(fd);
10419 +       os_close_file(fd);
10420  }
10421  
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
10427 @@ -4,8 +4,7 @@
10428  #include <stddef.h>
10429  #include <sched.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 @@
10438  
10439         return(pid);
10440  }
10441
10442 +
10443 +/* XXX This is just a trivial wrapper around os_pipe */ 
10444  static int slirp_datachan(int *mfd, int *sfd)
10445  {
10446         int fds[2], err;
10447  
10448         err = os_pipe(fds, 1, 1);
10449 -       if(err){
10450 -               printk("slirp_datachan: Failed to open pipe, errno = %d\n",
10451 -                      -err);
10452 +       if(err < 0){
10453 +               printk("slirp_datachan: Failed to open pipe, err = %d\n", -err);
10454                 return(err);
10455         }
10456  
10457 @@ -77,7 +76,7 @@
10458         pid = slirp_tramp(pri->argw.argv, sfd);
10459  
10460         if(pid < 0){
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);     
10465                 return(pid);
10466 @@ -97,8 +96,8 @@
10467         struct slirp_data *pri = data;
10468         int status,err;
10469  
10470 -       close(fd);
10471 -       close(pri->slave);
10472 +       os_close_file(fd);
10473 +       os_close_file(pri->slave);
10474  
10475         pri->slave = -1;
10476  
10477 @@ -114,13 +113,13 @@
10478         }
10479  #endif
10480  
10481 -       err = waitpid(pri->pid, &status, WNOHANG);
10482 -       if(err<0) {
10483 +       CATCH_EINTR(err = waitpid(pri->pid, &status, WNOHANG));
10484 +       if(err < 0) {
10485                 printk("slirp_close: waitpid returned %d\n", errno);
10486                 return;
10487         }
10488  
10489 -       if(err==0) {
10490 +       if(err == 0) {
10491                 printk("slirp_close: process %d has not exited\n");
10492                 return;
10493         }
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
10498 @@ -28,6 +28,7 @@
10499         }
10500         if((dir == NULL) || (*dir == '\0')) 
10501                 dir = "/tmp";
10502 +
10503         tempdir = malloc(strlen(dir) + 2);
10504         if(tempdir == NULL){
10505                 fprintf(stderr, "Failed to malloc tempdir, "
10506 @@ -49,7 +50,8 @@
10507         else
10508                 *tempname = 0;
10509         strcat(tempname, template);
10510 -       if((fd = mkstemp(tempname)) < 0){
10511 +       fd = mkstemp(tempname);
10512 +       if(fd < 0){
10513                 fprintf(stderr, "open - cannot create %s: %s\n", tempname, 
10514                         strerror(errno));
10515                 return -1;
10516 @@ -59,7 +61,8 @@
10517                 return -1;
10518         }
10519         if(out_tempname){
10520 -               if((*out_tempname = strdup(tempname)) == NULL){
10521 +               *out_tempname = strdup(tempname);
10522 +               if(*out_tempname == NULL){
10523                         perror("strdup");
10524                         return -1;
10525                 }
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
10530 @@ -1,15 +1,10 @@
10531 +host-progs     := mk_sc mk_thread
10532 +always         := $(host-progs)
10533  
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
10538  
10539 -mk_sc-objs     := mk_sc.o
10540 -
10541 -$(obj)/mk_thread : $(obj)/mk_thread_kern.o $(obj)/mk_thread_user.o
10542 -       $(CC) $(CFLAGS) -o $@ $^
10543 -
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)
10548  
10549  clean :
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 @@
10556                 return(0);
10557  
10558         register_winch_irq(tracer_winch[0], fd, -1, data);
10559 -       return(0);
10560 +       return(1);
10561  }
10562  
10563  static void tracer_winch_handler(int sig)
10564  {
10565 +       int n;
10566         char c = 1;
10567  
10568 -       if(write(tracer_winch[1], &c, sizeof(c)) != sizeof(c))
10569 -               printk("tracer_winch_handler - write failed, errno = %d\n",
10570 -                      errno);
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);
10574  }
10575  
10576  /* Called only by the tracing thread during initialization */
10577 @@ -58,9 +59,8 @@
10578         int err;
10579  
10580         err = os_pipe(tracer_winch, 1, 1);
10581 -       if(err){
10582 -               printk("setup_tracer_winch : os_pipe failed, errno = %d\n", 
10583 -                      -err);
10584 +       if(err < 0){
10585 +               printk("setup_tracer_winch : os_pipe failed, err = %d\n", -err);
10586                 return;
10587         }
10588         signal(SIGWINCH, tracer_winch_handler);
10589 @@ -130,8 +130,8 @@
10590         case SIGTSTP:
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,
10594 -                                    sig);
10595 +                                    "continue pid %d, signal = %d, "
10596 +                                    "errno = %d\n", pid, sig, errno);
10597                 break;
10598  
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",
10604 -                                    pid, sig);
10605 +                                    pid, errno);
10606                 break;
10607         case SIGSTOP:
10608                 break;
10609 @@ -192,7 +192,7 @@
10610         printf("tracing thread pid = %d\n", tracing_pid);
10611  
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));
10615         if(n < 0){
10616                 printf("waitpid on idle thread failed, errno = %d\n", errno);
10617                 exit(1);
10618 @@ -218,7 +218,7 @@
10619                         err = attach(debugger_parent);
10620                         if(err){
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;
10625                         }
10626                         else {
10627 @@ -233,7 +233,8 @@
10628         }
10629         set_cmdline("(tracing thread)");
10630         while(1){
10631 -               if((pid = waitpid(-1, &status, WUNTRACED)) <= 0){
10632 +               CATCH_EINTR(pid = waitpid(-1, &status, WUNTRACED));
10633 +               if(pid <= 0){
10634                         if(errno != ECHILD){
10635                                 printf("wait failed - errno = %d\n", errno);
10636                         }
10637 @@ -401,7 +402,7 @@
10638                 
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);
10643  
10644                 line = next;
10645         }
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
10650 @@ -1,5 +1,5 @@
10651  # 
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
10655  #
10656  
10657 @@ -15,7 +15,7 @@
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
10666 @@ -39,6 +39,8 @@
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
10672  
10673  obj-y += stdio_console.o $(CHAN_OBJS)
10674  
10675 @@ -46,18 +48,7 @@
10676  
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))
10681  
10682  $(USER_OBJS) : %.o: %.c
10683         $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
10684 -
10685 -clean:
10686 -
10687 -modules:
10688 -
10689 -fastdep:
10690 -
10691 -dep:
10692 -
10693 -archmrproper: clean
10694 -
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
10699 @@ -0,0 +1,73 @@
10700 +/* 
10701 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
10702 + * Licensed under the GPL
10703 + */
10704 +
10705 +#include "linux/sched.h"
10706 +#include "asm/uaccess.h"
10707 +
10708 +int copy_from_user_tt(void *to, const void *from, int n)
10709 +{
10710 +       if(!access_ok_tt(VERIFY_READ, from, n)) 
10711 +               return(n);
10712 +
10713 +       return(__do_copy_from_user(to, from, n, &current->thread.fault_addr,
10714 +                                  &current->thread.fault_catcher));
10715 +}
10716 +
10717 +int copy_to_user_tt(void *to, const void *from, int n)
10718 +{
10719 +       if(!access_ok_tt(VERIFY_WRITE, to, n))
10720 +               return(n);
10721 +               
10722 +       return(__do_copy_to_user(to, from, n, &current->thread.fault_addr,
10723 +                                &current->thread.fault_catcher));
10724 +}
10725 +
10726 +int strncpy_from_user_tt(char *dst, const char *src, int count)
10727 +{
10728 +       int n;
10729 +
10730 +       if(!access_ok_tt(VERIFY_READ, src, 1)) 
10731 +               return(-EFAULT);
10732 +
10733 +       n = __do_strncpy_from_user(dst, src, count, 
10734 +                                  &current->thread.fault_addr,
10735 +                                  &current->thread.fault_catcher);
10736 +       if(n < 0) return(-EFAULT);
10737 +       return(n);
10738 +}
10739 +
10740 +int __clear_user_tt(void *mem, int len)
10741 +{
10742 +       return(__do_clear_user(mem, len,
10743 +                              &current->thread.fault_addr,
10744 +                              &current->thread.fault_catcher));
10745 +}
10746 +
10747 +int clear_user_tt(void *mem, int len)
10748 +{
10749 +       if(!access_ok_tt(VERIFY_WRITE, mem, len))
10750 +               return(len);
10751 +
10752 +       return(__do_clear_user(mem, len, &current->thread.fault_addr,
10753 +                              &current->thread.fault_catcher));
10754 +}
10755 +
10756 +int strnlen_user_tt(const void *str, int len)
10757 +{
10758 +       return(__do_strnlen_user(str, len,
10759 +                                &current->thread.fault_addr,
10760 +                                &current->thread.fault_catcher));
10761 +}
10762 +
10763 +/*
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
10767 + * of the file.
10768 + * ---------------------------------------------------------------------------
10769 + * Local variables:
10770 + * c-file-style: "linux"
10771 + * End:
10772 + */
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
10777 @@ -1,10 +1,9 @@
10778  all: mk_ptregs
10779  
10780  mk_ptregs : mk_ptregs.o
10781 -       $(CC) -o mk_ptregs mk_ptregs.o
10782 +       $(HOSTCC) -o mk_ptregs mk_ptregs.o
10783  
10784  mk_ptregs.o : mk_ptregs.c
10785 -       $(CC) -c $< 
10786 +       $(HOSTCC) -c $< 
10787  
10788 -clean : 
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
10795 @@ -10,5 +10,3 @@
10796  
10797  $(USER_OBJS) : %.o: %.c
10798         $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
10799 -
10800 -clean :
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
10805 @@ -6,18 +6,21 @@
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"
10812  #include "init.h"
10813  #include "sigio.h"
10814  #include "irq_user.h"
10815 +#include "irq_kern.h"
10816  
10817  /* Protected by sigio_lock() called from write_sigio_workaround */
10818  static int sigio_irq_fd = -1;
10819  
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)
10822  {
10823         read_sigio_fd(sigio_irq_fd);
10824         reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
10825 +       return(IRQ_HANDLED);
10826  }
10827  
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
10833 @@ -23,8 +23,10 @@
10834  extern void block_signals(void);
10835  extern void unblock_signals(void);
10836  
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)
10843  
10844  #define local_irq_save(flags) do { local_save_flags(flags); \
10845                                     local_irq_disable(); } while(0)
10846 @@ -39,4 +41,7 @@
10847          (flags == 0);                   \
10848  })
10849  
10850 +extern void *_switch_to(void *prev, void *next, void *last);
10851 +#define switch_to(prev, next, last) prev = _switch_to(prev, next, last)
10852 +
10853  #endif
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
10858 @@ -6,6 +6,8 @@
10859  #ifndef __UM_UACCESS_H
10860  #define __UM_UACCESS_H
10861  
10862 +#include "linux/sched.h"
10863 +
10864  #define VERIFY_READ 0
10865  #define VERIFY_WRITE 1
10866  
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
10871 @@ -1,23 +1,8 @@
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)
10877  
10878 -$(obj)/mk_task: $(obj)/mk_task_user.o $(obj)/mk_task_kern.o
10879 -       $(CC) -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
10882  
10883 -$(obj)/mk_task_user.o: $(src)/mk_task_user.c
10884 -       $(CC) -o $@ -c $< 
10885 -
10886 -$(obj)/mk_constants : $(obj)/mk_constants_user.o $(obj)/mk_constants_kern.o
10887 -       $(CC) -o $@ $^
10888 -
10889 -$(obj)/mk_constants_user.o : $(src)/mk_constants_user.c
10890 -       $(CC) -c $< -o $@
10891 -
10892 -$(obj)/mk_constants_kern.o : $(src)/mk_constants_kern.c
10893 -       $(CC) $(CFLAGS) -c $< -o $@
10894 -
10895 -clean:
10896 -       $(RM) $(build-targets)
10897 -
10898 -archmrproper:
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
10905 @@ -8,6 +8,8 @@
10906  #include <errno.h>
10907  #include <fcntl.h>
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 @@
10915  #include "user.h"
10916  #include "kern_util.h"
10917  
10918 -int os_file_type(char *file)
10919 +static void copy_stat(struct uml_stat *dst, struct stat64 *src)
10920 +{
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 */
10934 +       });
10935 +}
10936 +
10937 +int os_stat_fd(const int fd, struct uml_stat *ubuf)
10938 +{
10939 +       struct stat64 sbuf;
10940 +       int err;
10941 +
10942 +       do {
10943 +               err = fstat64(fd, &sbuf);
10944 +       } while((err < 0) && (errno == EINTR)) ;
10945 +
10946 +       if(err < 0) 
10947 +               return(-errno);
10948 +
10949 +       if(ubuf != NULL)
10950 +               copy_stat(ubuf, &sbuf);
10951 +       return(err);
10952 +}
10953 +
10954 +int os_stat_file(const char *file_name, struct uml_stat *ubuf)
10955 +{
10956 +       struct stat64 sbuf;
10957 +       int err;
10958 +
10959 +       do {
10960 +               err = stat64(file_name, &sbuf);
10961 +       } while((err < 0) && (errno == EINTR)) ;
10962 +
10963 +       if(err < 0) 
10964 +               return(-errno);
10965 +
10966 +       if(ubuf != NULL)
10967 +               copy_stat(ubuf, &sbuf);
10968 +       return(err);
10969 +}
10970 +
10971 +int os_access(const char* file, int mode)
10972 +{
10973 +       int amode, err;
10974 +
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) ;
10977 +
10978 +       err = access(file, amode);
10979 +       if(err < 0)
10980 +               return(-errno);
10981 +
10982 +       return(0);
10983 +}
10984 +
10985 +void os_print_error(int error, const char* str)
10986 +{
10987 +       errno = error < 0 ? -error : error;
10988 +
10989 +       perror(str);
10990 +}
10991 +
10992 +/* FIXME? required only by hostaudio (because it passes ioctls verbatim) */
10993 +int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
10994 +{
10995 +       int err;
10996 +
10997 +       err = ioctl(fd, cmd, arg);
10998 +       if(err < 0)
10999 +               return(-errno);
11000 +
11001 +       return(err);
11002 +}
11003 +
11004 +int os_window_size(int fd, int *rows, int *cols)
11005 +{
11006 +       struct winsize size;
11007 +
11008 +       if(ioctl(fd, TIOCGWINSZ, &size) < 0)
11009 +               return(-errno);
11010 +
11011 +       *rows = size.ws_row;
11012 +       *cols = size.ws_col;
11013 +
11014 +       return(0);
11015 +}
11016 +
11017 +int os_new_tty_pgrp(int fd, int pid)
11018  {
11019 -       struct stat64 buf;
11020 +       if(ioctl(fd, TIOCSCTTY, 0) < 0){
11021 +               printk("TIOCSCTTY failed, errno = %d\n", errno);
11022 +               return(-errno);
11023 +       }
11024 +
11025 +       if(tcsetpgrp(fd, pid) < 0){
11026 +               printk("tcsetpgrp failed, errno = %d\n", errno);
11027 +               return(-errno);
11028 +       }
11029 +
11030 +       return(0);
11031 +}
11032 +
11033 +/* FIXME: ensure namebuf in os_get_if_name is big enough */
11034 +int os_get_ifname(int fd, char* namebuf)
11035 +{
11036 +       if(ioctl(fd, SIOCGIFNAME, namebuf) < 0)
11037 +               return(-errno);
11038 +
11039 +       return(0);
11040 +}
11041 +
11042 +int os_set_slip(int fd)
11043 +{
11044 +       int disc, sencap;
11045 +
11046 +       disc = N_SLIP;
11047 +       if(ioctl(fd, TIOCSETD, &disc) < 0){
11048 +               printk("Failed to set slip line discipline - "
11049 +                      "errno = %d\n", errno);
11050 +               return(-errno);
11051 +       }
11052 +
11053 +       sencap = 0;
11054 +       if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0){
11055 +               printk("Failed to set slip encapsulation - "
11056 +                      "errno = %d\n", errno);
11057 +               return(-errno);
11058 +       }
11059 +
11060 +       return(0);
11061 +}
11062 +
11063 +int os_set_owner(int fd, int pid)
11064 +{
11065 +       if(fcntl(fd, F_SETOWN, pid) < 0){
11066 +               int save_errno = errno;
11067 +
11068 +               if(fcntl(fd, F_GETOWN, 0) != pid)
11069 +                       return(-save_errno);
11070 +       }
11071 +
11072 +       return(0);
11073 +}
11074 +
11075 +/* FIXME? moved wholesale from sigio_user.c to get fcntls out of that file */ 
11076 +int os_sigio_async(int master, int slave)
11077 +{
11078 +       int flags;
11079  
11080 -       if(stat64(file, &buf) == -1)
11081 +       flags = fcntl(master, F_GETFL);
11082 +       if(flags < 0) {
11083 +               printk("fcntl F_GETFL failed, errno = %d\n", errno);
11084                 return(-errno);
11085 +       }
11086 +
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);
11090 +               return(-errno);
11091 +       }
11092 +
11093 +       if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)){
11094 +               printk("fcntl F_SETFL failed, errno = %d\n", errno);
11095 +               return(-errno);
11096 +       }
11097  
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);
11104 +       return(0);
11105 +}
11106 +
11107 +int os_mode_fd(int fd, int mode)
11108 +{
11109 +       int err;
11110 +
11111 +       do {
11112 +               err = fchmod(fd, mode);
11113 +       } while((err < 0) && (errno==EINTR)) ;
11114 +
11115 +       if(err < 0)
11116 +               return(-errno);
11117 +
11118 +       return(0);
11119 +}
11120 +
11121 +int os_file_type(char *file)
11122 +{
11123 +       struct uml_stat buf;
11124 +       int err;
11125 +
11126 +       err = os_stat_file(file, &buf);
11127 +       if(err < 0)
11128 +               return(err);
11129 +
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);
11137  }
11138  
11139  int os_file_mode(char *file, struct openflags *mode_out)
11140  {
11141 +       int err;
11142 +
11143         *mode_out = OPENFLAGS();
11144  
11145 -       if(!access(file, W_OK)) *mode_out = of_write(*mode_out);
11146 -       else if(errno != EACCES) 
11147 -               return(-errno);
11148 +       err = os_access(file, OS_ACC_W_OK);
11149 +       if((err < 0) && (err != -EACCES))
11150 +               return(err);
11151  
11152 -       if(!access(file, R_OK)) *mode_out = of_read(*mode_out);
11153 -       else if(errno != EACCES) 
11154 -               return(-errno);
11155 +       *mode_out = of_write(*mode_out);
11156 +
11157 +       err = os_access(file, OS_ACC_R_OK);
11158 +       if((err < 0) && (err != -EACCES))
11159 +               return(err);
11160 +
11161 +       *mode_out = of_read(*mode_out);
11162  
11163         return(0);
11164  }
11165 @@ -63,16 +267,14 @@
11166         if(flags.e) f |= O_EXCL;
11167  
11168         fd = open64(file, f, mode);
11169 -       if(fd < 0) return(-errno);
11170 -       
11171 -       if(flags.cl){
11172 -               if(fcntl(fd, F_SETFD, 1)){
11173 -                       close(fd);
11174 -                       return(-errno);
11175 -               }
11176 +       if(fd < 0)
11177 +               return(-errno);
11178 +
11179 +       if(flags.cl && fcntl(fd, F_SETFD, 1)){
11180 +               os_close_file(fd);
11181 +               return(-errno);
11182         }
11183  
11184 -       return(fd);
11185         return(fd);
11186  }
11187  
11188 @@ -90,7 +292,7 @@
11189  
11190         err = connect(fd, (struct sockaddr *) &sock, sizeof(sock));
11191         if(err)
11192 -               return(err);
11193 +               return(-errno);
11194  
11195         return(fd);
11196  }
11197 @@ -109,88 +311,162 @@
11198         return(0);
11199  }
11200  
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))
11204  {
11205 -       int n;
11206 +       int page = getpagesize(), i;
11207 +       char c;
11208  
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)))
11212 +                       return(-EFAULT);
11213 +       }
11214 +       if((len % page) != 0){
11215 +               if((*copy_proc)(start + len - 1, &c, sizeof(c)))
11216 +                       return(-EFAULT);
11217 +       }
11218 +       return(0);
11219 +}
11220  
11221 -       /* XXX This fails if buf is kernel memory */
11222 -#ifdef notdef
11223 -       if(copy_to_user_proc(buf, &c, sizeof(c)))
11224 -               return(-EFAULT);
11225 -#endif
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))
11229 +{
11230 +       int n, err;
11231 +
11232 +       do {
11233 +               n = (*io_proc)(fd, buf, len);
11234 +               if((n < 0) && (errno == EFAULT)){
11235 +                       err = fault_buffer(buf, len, copy_user_proc);
11236 +                       if(err)
11237 +                               return(err);
11238 +                       n = (*io_proc)(fd, buf, len);
11239 +               }
11240 +       } while((n < 0) && (errno == EINTR));
11241  
11242 -       n = read(fd, buf, len);
11243         if(n < 0)
11244                 return(-errno);
11245         return(n);
11246  }
11247  
11248 -int os_write_file(int fd, void *buf, int count)
11249 +int os_read_file(int fd, void *buf, int len)
11250  {
11251 -       int n;
11252 -
11253 -       /* Force buf into memory if it's not already. */
11254 -       
11255 -       /* XXX This fails if buf is kernel memory */
11256 -#ifdef notdef
11257 -       if(copy_to_user_proc(buf, buf, buf[0]))
11258 -               return(-EFAULT);
11259 -#endif
11260 +       return(file_io(fd, buf, len, (int (*)(int, void *, int)) read, 
11261 +                      copy_from_user_proc));
11262 +}
11263  
11264 -       n = write(fd, buf, count);
11265 -       if(n < 0)
11266 -               return(-errno);
11267 -       return(n);
11268 +int os_write_file(int fd, const void *buf, int len)
11269 +{
11270 +       return(file_io(fd, (void *) buf, len, 
11271 +                      (int (*)(int, void *, int)) write, copy_to_user_proc));
11272  }
11273  
11274  int os_file_size(char *file, long long *size_out)
11275  {
11276 -       struct stat64 buf;
11277 +       struct uml_stat buf;
11278 +       int err;
11279  
11280 -       if(stat64(file, &buf) == -1){
11281 -               printk("Couldn't stat \"%s\" : errno = %d\n", file, errno);
11282 -               return(-errno);
11283 +       err = os_stat_file(file, &buf);
11284 +       if(err < 0){
11285 +               printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
11286 +               return(err);
11287         }
11288 -       if(S_ISBLK(buf.st_mode)){
11289 +
11290 +       if(S_ISBLK(buf.ust_mode)){
11291                 int fd, blocks;
11292  
11293 -               if((fd = open64(file, O_RDONLY)) < 0){
11294 -                       printk("Couldn't open \"%s\", errno = %d\n", file,
11295 -                              errno);
11296 -                       return(-errno);
11297 +               fd = os_open_file(file, of_read(OPENFLAGS()), 0);
11298 +               if(fd < 0){
11299 +                       printk("Couldn't open \"%s\", errno = %d\n", file, -fd);
11300 +                       return(fd);
11301                 }
11302                 if(ioctl(fd, BLKGETSIZE, &blocks) < 0){
11303                         printk("Couldn't get the block size of \"%s\", "
11304                                "errno = %d\n", file, errno);
11305 -                       close(fd);
11306 -                       return(-errno);
11307 +                       err = -errno;
11308 +                       os_close_file(fd);
11309 +                       return(err);
11310                 }
11311                 *size_out = ((long long) blocks) * 512;
11312 -               close(fd);
11313 +               os_close_file(fd);
11314                 return(0);
11315         }
11316 -       *size_out = buf.st_size;
11317 +       *size_out = buf.ust_size;
11318 +       return(0);
11319 +}
11320 +
11321 +int os_file_modtime(char *file, unsigned long *modtime)
11322 +{
11323 +       struct uml_stat buf;
11324 +       int err;
11325 +
11326 +       err = os_stat_file(file, &buf);
11327 +       if(err < 0){
11328 +               printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
11329 +               return(err);
11330 +       }
11331 +
11332 +       *modtime = buf.ust_mtime;
11333         return(0);
11334  }
11335  
11336 +int os_get_exec_close(int fd, int* close_on_exec)
11337 +{
11338 +       int ret;
11339 +
11340 +       do {
11341 +               ret = fcntl(fd, F_GETFD);
11342 +       } while((ret < 0) && (errno == EINTR)) ;
11343 +
11344 +       if(ret < 0)
11345 +               return(-errno);
11346 +
11347 +       *close_on_exec = (ret&FD_CLOEXEC) ? 1 : 0;
11348 +       return(ret);
11349 +}
11350 +
11351 +int os_set_exec_close(int fd, int close_on_exec)
11352 +{
11353 +       int flag, err;
11354 +
11355 +       if(close_on_exec) flag = FD_CLOEXEC;
11356 +       else flag = 0;
11357 +
11358 +       do {
11359 +               err = fcntl(fd, F_SETFD, flag);
11360 +       } while((err < 0) && (errno == EINTR)) ;
11361 +
11362 +       if(err < 0)
11363 +               return(-errno);
11364 +       return(err);
11365 +}
11366 +
11367  int os_pipe(int *fds, int stream, int close_on_exec)
11368  {
11369         int err, type = stream ? SOCK_STREAM : SOCK_DGRAM;
11370  
11371         err = socketpair(AF_UNIX, type, 0, fds);
11372 -       if(err) 
11373 +       if(err < 0) 
11374                 return(-errno);
11375  
11376         if(!close_on_exec)
11377                 return(0);
11378  
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", 
11381 -                      errno);
11382 +       err = os_set_exec_close(fds[0], 1);
11383 +       if(err < 0)
11384 +               goto error;
11385 +
11386 +       err = os_set_exec_close(fds[1], 1);
11387 +       if(err < 0)
11388 +               goto error;
11389  
11390         return(0);
11391 +
11392 + error:
11393 +       printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err);
11394 +       os_close_file(fds[1]);
11395 +       os_close_file(fds[0]);
11396 +       return(err);
11397  }
11398  
11399  int os_set_fd_async(int fd, int owner)
11400 @@ -270,7 +546,7 @@
11401                 return(-EINVAL);
11402         }
11403         err = shutdown(fd, what);
11404 -       if(err)
11405 +       if(err < 0)
11406                 return(-errno);
11407         return(0);
11408  }
11409 @@ -315,7 +591,7 @@
11410         return(new);
11411  }
11412  
11413 -int create_unix_socket(char *file, int len)
11414 +int os_create_unix_socket(char *file, int len, int close_on_exec)
11415  {
11416         struct sockaddr_un addr;
11417         int sock, err;
11418 @@ -327,6 +603,13 @@
11419                 return(-errno);
11420         }
11421  
11422 +       if(close_on_exec) {
11423 +               err = os_set_exec_close(sock, 1);
11424 +               if(err < 0)
11425 +                       printk("create_unix_socket : close_on_exec failed, "
11426 +                      "err = %d", -err);
11427 +       }
11428 +
11429         addr.sun_family = AF_UNIX;
11430  
11431         /* XXX Be more careful about overflow */
11432 @@ -334,14 +617,45 @@
11433  
11434         err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
11435         if (err < 0){
11436 -               printk("create_listening_socket - bind failed, errno = %d\n",
11437 -                      errno);
11438 +               printk("create_listening_socket at '%s' - bind failed, "
11439 +                      "errno = %d\n", file, errno);
11440                 return(-errno);
11441         }
11442  
11443         return(sock);
11444  }
11445  
11446 +void os_flush_stdout(void)
11447 +{
11448 +       fflush(stdout);
11449 +}
11450 +
11451 +int os_lock_file(int fd, int excl)
11452 +{
11453 +       int type = excl ? F_WRLCK : F_RDLCK;
11454 +       struct flock lock = ((struct flock) { .l_type   = type,
11455 +                                             .l_whence = SEEK_SET,
11456 +                                             .l_start  = 0,
11457 +                                             .l_len    = 0 } );
11458 +       int err, save;
11459 +
11460 +       err = fcntl(fd, F_SETLK, &lock);
11461 +       if(!err)
11462 +               goto out;
11463 +
11464 +       save = -errno;
11465 +       err = fcntl(fd, F_GETLK, &lock);
11466 +       if(err){
11467 +               err = -errno;
11468 +               goto out;
11469 +       }
11470 +
11471 +       printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
11472 +       err = save;
11473 + out:
11474 +       return(err);
11475 +}
11476 +
11477  /*
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
11484 @@ -10,5 +10,3 @@
11485  
11486  $(USER_OBJS) : %.o: %.c
11487         $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
11488 -
11489 -clean :
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
11494 @@ -11,6 +11,7 @@
11495  #include <sys/ptrace.h>
11496  #include "user.h"
11497  #include "kern_util.h"
11498 +#include "user_util.h"
11499  #include "os.h"
11500  #include "time_user.h"
11501  
11502 @@ -26,7 +27,7 @@
11503  
11504  int user_thread(unsigned long stack, int flags)
11505  {
11506 -       int pid, status;
11507 +       int pid, status, err;
11508  
11509         pid = clone(user_thread_tramp, (void *) stack_sp(stack), 
11510                     flags | CLONE_FILES | SIGCHLD, NULL);
11511 @@ -35,7 +36,8 @@
11512                 return(pid);
11513         }
11514  
11515 -       if(waitpid(pid, &status, WUNTRACED) < 0){
11516 +       CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
11517 +       if(err < 0){
11518                 printk("user_thread - waitpid failed, errno = %d\n", errno);
11519                 return(-errno);
11520         }
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");
11534                 exit(1);
11535         }
11536         memcpy(addr, segment_start, size);
11537 -       if(switcheroo(data, prot, addr, segment_start, 
11538 -                     size) < 0){
11539 +       if(switcheroo(data, prot, addr, segment_start, size) < 0){
11540                 printf("switcheroo failed\n");
11541                 exit(1);
11542         }
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
11547 @@ -1,5 +1,5 @@
11548  /* 
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
11552   */
11553  
11554 @@ -8,7 +8,7 @@
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"
11563 @@ -19,6 +19,7 @@
11564  #include "asm/tlbflush.h"
11565  #include "kern_util.h"
11566  #include "user_util.h"
11567 +#include "mem_user.h"
11568  #include "os.h"
11569  #include "helper.h"
11570  
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);
11576  
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);
11592  
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);
11597 +#endif
11598 +
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);
11603 +#endif
11604 +
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);
11635  
11636 +EXPORT_SYMBOL(do_gettimeofday);
11637 +EXPORT_SYMBOL(do_settimeofday);
11638 +
11639  /* This is here because UML expands open to sys_open, not to a system
11640   * call instruction.
11641   */
11642 @@ -90,3 +123,13 @@
11643  EXPORT_SYMBOL(kmap_atomic_to_page);
11644  #endif
11645  
11646 +/*
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
11650 + * of the file.
11651 + * ---------------------------------------------------------------------------
11652 + * Local variables:
11653 + * c-file-style: "linux"
11654 + * End:
11655 + */
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
11660 @@ -73,6 +73,11 @@
11661   * For the normal case of non-DISCONTIGMEM systems the NODE_DATA() gets
11662   * optimized to &contig_page_data at compile-time.
11663   */
11664 +
11665 +#ifndef HAVE_ARCH_FREE_PAGE
11666 +static inline void arch_free_page(struct page *page, int order) { }
11667 +#endif
11668 +
11669  extern struct page *
11670  FASTCALL(__alloc_pages(unsigned int, unsigned int, struct zonelist *));
11671  
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
11676 @@ -3,29 +3,19 @@
11677  #
11678  CONFIG_USERMODE=y
11679  CONFIG_MMU=y
11680 -CONFIG_SWAP=y
11681  CONFIG_UID16=y
11682  CONFIG_RWSEM_GENERIC_SPINLOCK=y
11683 -CONFIG_CONFIG_LOG_BUF_SHIFT=14
11684  
11685  #
11686 -# Code maturity level options
11687 -#
11688 -CONFIG_EXPERIMENTAL=y
11689 -
11690 -#
11691 -# General Setup
11692 +# UML-specific options
11693  #
11694  CONFIG_MODE_TT=y
11695  CONFIG_MODE_SKAS=y
11696  CONFIG_NET=y
11697 -CONFIG_SYSVIPC=y
11698 -CONFIG_BSD_PROCESS_ACCT=y
11699 -CONFIG_SYSCTL=y
11700 -CONFIG_BINFMT_AOUT=y
11701  CONFIG_BINFMT_ELF=y
11702  CONFIG_BINFMT_MISC=y
11703  CONFIG_HOSTFS=y
11704 +CONFIG_HPPFS=y
11705  CONFIG_MCONSOLE=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
11710  CONFIG_PROC_MM=y
11711  CONFIG_KERNEL_STACK_ORDER=2
11712 +CONFIG_UML_REAL_TIME_CLOCK=y
11713 +
11714 +#
11715 +# Code maturity level options
11716 +#
11717 +CONFIG_EXPERIMENTAL=y
11718 +CONFIG_CLEAN_COMPILE=y
11719 +CONFIG_STANDALONE=y
11720 +CONFIG_BROKEN_ON_SMP=y
11721 +
11722 +#
11723 +# General setup
11724 +#
11725 +CONFIG_SWAP=y
11726 +CONFIG_SYSVIPC=y
11727 +CONFIG_BSD_PROCESS_ACCT=y
11728 +CONFIG_SYSCTL=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
11733 +CONFIG_KALLSYMS=y
11734 +CONFIG_FUTEX=y
11735 +CONFIG_EPOLL=y
11736 +CONFIG_IOSCHED_NOOP=y
11737 +CONFIG_IOSCHED_AS=y
11738 +CONFIG_IOSCHED_DEADLINE=y
11739 +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
11740  
11741  #
11742  # Loadable module support
11743  #
11744 -CONFIG_MODULES=y
11745 -# CONFIG_KMOD is not set
11746 +# CONFIG_MODULES is not set
11747 +
11748 +#
11749 +# Generic Driver Options
11750 +#
11751  
11752  #
11753  # Character Devices
11754 @@ -69,6 +90,7 @@
11755  #
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
11762 @@ -78,7 +100,7 @@
11763  CONFIG_NETDEVICES=y
11764  
11765  #
11766 -# Network Devices
11767 +# UML Network Devices
11768  #
11769  CONFIG_UML_NET=y
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
11775 -CONFIG_DUMMY=y
11776 -# CONFIG_BONDING is not set
11777 -# CONFIG_EQUALIZER is not set
11778 -CONFIG_TUN=y
11779 -# CONFIG_ETHERTAP is not set
11780 -CONFIG_PPP=y
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
11787 -CONFIG_SLIP=y
11788 -# CONFIG_SLIP_COMPRESSED is not set
11789 -# CONFIG_SLIP_SMART is not set
11790 -# CONFIG_SLIP_MODE_SLIP6 is not set
11791  
11792  #
11793  # Networking support
11794 @@ -115,8 +121,6 @@
11795  CONFIG_PACKET=y
11796  CONFIG_PACKET_MMAP=y
11797  # CONFIG_NETLINK_DEV is not set
11798 -# CONFIG_NETFILTER is not set
11799 -# CONFIG_FILTER is not set
11800  CONFIG_UNIX=y
11801  # CONFIG_NET_KEY is not set
11802  CONFIG_INET=y
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
11813  
11814  #
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 @@
11830  # Network testing
11831  #
11832  # CONFIG_NET_PKTGEN is not set
11833 +CONFIG_DUMMY=y
11834 +# CONFIG_BONDING is not set
11835 +# CONFIG_EQUALIZER is not set
11836 +CONFIG_TUN=y
11837  
11838  #
11839  # Ethernet (10 or 100Mbit)
11840 @@ -171,12 +182,28 @@
11841  #
11842  
11843  #
11844 +# Ethernet (10000 Mbit)
11845 +#
11846 +CONFIG_PPP=y
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
11854 +CONFIG_SLIP=y
11855 +# CONFIG_SLIP_COMPRESSED is not set
11856 +# CONFIG_SLIP_SMART is not set
11857 +# CONFIG_SLIP_MODE_SLIP6 is not set
11858 +
11859 +#
11860  # Wireless LAN (non-hamradio)
11861  #
11862  # CONFIG_NET_RADIO is not set
11863  
11864  #
11865 -# Token Ring devices (depends on LLC=y)
11866 +# Token Ring devices
11867  #
11868  # CONFIG_SHAPER is not set
11869  
11870 @@ -186,68 +213,100 @@
11871  # CONFIG_WAN is not set
11872  
11873  #
11874 +# Amateur Radio support
11875 +#
11876 +# CONFIG_HAMRADIO is not set
11877 +
11878 +#
11879 +# IrDA (infrared) support
11880 +#
11881 +# CONFIG_IRDA is not set
11882 +
11883 +#
11884 +# Bluetooth support
11885 +#
11886 +# CONFIG_BT is not set
11887 +
11888 +#
11889  # File systems
11890  #
11891 +CONFIG_EXT2_FS=y
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
11900 +CONFIG_MINIX_FS=y
11901 +# CONFIG_ROMFS_FS is not set
11902  CONFIG_QUOTA=y
11903  # CONFIG_QFMT_V1 is not set
11904  # CONFIG_QFMT_V2 is not set
11905  CONFIG_QUOTACTL=y
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
11913 +
11914 +#
11915 +# CD-ROM/DVD Filesystems
11916 +#
11917 +CONFIG_ISO9660_FS=y
11918 +# CONFIG_JOLIET is not set
11919 +# CONFIG_ZISOFS is not set
11920 +# CONFIG_UDF_FS is not set
11921 +
11922 +#
11923 +# DOS/FAT/NT Filesystems
11924 +#
11925 +CONFIG_FAT_FS=y
11926 +CONFIG_MSDOS_FS=y
11927 +CONFIG_VFAT_FS=y
11928 +# CONFIG_NTFS_FS is not set
11929 +
11930 +#
11931 +# Pseudo filesystems
11932 +#
11933 +CONFIG_PROC_FS=y
11934 +CONFIG_PROC_KCORE=y
11935 +CONFIG_DEVFS_FS=y
11936 +CONFIG_DEVFS_MOUNT=y
11937 +# CONFIG_DEVFS_DEBUG is not set
11938 +# CONFIG_DEVPTS_FS_XATTR is not set
11939 +CONFIG_TMPFS=y
11940 +# CONFIG_HUGETLB_PAGE is not set
11941 +CONFIG_RAMFS=y
11942 +
11943 +#
11944 +# Miscellaneous filesystems
11945 +#
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
11954 -CONFIG_FAT_FS=m
11955 -CONFIG_MSDOS_FS=m
11956 -CONFIG_VFAT_FS=m
11957  # CONFIG_EFS_FS is not set
11958  CONFIG_JFFS_FS=y
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
11964 -CONFIG_RAMFS=y
11965 -CONFIG_ISO9660_FS=m
11966 -# CONFIG_JOLIET is not set
11967 -# CONFIG_ZISOFS is not set
11968 -# CONFIG_JFS_FS is not set
11969 -CONFIG_MINIX_FS=m
11970  # CONFIG_VXFS_FS is not set
11971 -# CONFIG_NTFS_FS is not set
11972  # CONFIG_HPFS_FS is not set
11973 -CONFIG_PROC_FS=y
11974 -CONFIG_DEVFS_FS=y
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
11980 -CONFIG_EXT2_FS=y
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
11986  
11987  #
11988  # Network File Systems
11989  #
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
12001  
12002  #
12003 @@ -255,11 +314,11 @@
12004  #
12005  # CONFIG_PARTITION_ADVANCED is not set
12006  CONFIG_MSDOS_PARTITION=y
12007 -CONFIG_NLS=y
12008  
12009  #
12010  # Native Language Support
12011  #
12012 +CONFIG_NLS=y
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 @@
12017  #
12018  # SCSI support
12019  #
12020 -CONFIG_SCSI=y
12021 -CONFIG_GENERIC_ISA_DMA=y
12022 -
12023 -#
12024 -# SCSI support type (disk, tape, CD-ROM)
12025 -#
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
12033 -
12034 -#
12035 -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
12036 -#
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
12043  
12044  #
12045  # Multi-device support (RAID and LVM)
12046 @@ -360,6 +398,7 @@
12047  CONFIG_MTD_BLOCK=y
12048  # CONFIG_FTL is not set
12049  # CONFIG_NFTL is not set
12050 +# CONFIG_INFTL is not set
12051  
12052  #
12053  # RAM/ROM/Flash chip drivers
12054 @@ -374,20 +413,21 @@
12055  #
12056  # Mapping drivers for chip access
12057  #
12058 +# CONFIG_MTD_COMPLEX_MAPPINGS is not set
12059  
12060  #
12061  # Self-contained MTD device drivers
12062  #
12063  # CONFIG_MTD_SLRAM is not set
12064  # CONFIG_MTD_MTDRAM is not set
12065 -CONFIG_MTD_BLKMTD=m
12066 +CONFIG_MTD_BLKMTD=y
12067  
12068  #
12069  # Disk-On-Chip Device Drivers
12070  #
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
12075  
12076  #
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
12082 @@ -0,0 +1,468 @@
12083 +/* 
12084 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
12085 + * Licensed under the GPL
12086 + */
12087 +
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"
12098 +#include "mem.h"
12099 +#include "mem_user.h"
12100 +#include "os.h"
12101 +#include "kern.h"
12102 +#include "init.h"
12103 +
12104 +#if 0
12105 +static pgd_t physmem_pgd[PTRS_PER_PGD];
12106 +
12107 +static struct phys_desc *lookup_mapping(void *addr)
12108 +{
12109 +       pgd = &physmem_pgd[pgd_index(addr)];
12110 +       if(pgd_none(pgd))
12111 +               return(NULL);
12112 +
12113 +       pmd = pmd_offset(pgd, addr);
12114 +       if(pmd_none(pmd))
12115 +               return(NULL);
12116 +
12117 +       pte = pte_offset_kernel(pmd, addr);
12118 +       return((struct phys_desc *) pte_val(pte));
12119 +}
12120 +
12121 +static struct add_mapping(void *addr, struct phys_desc *new)
12122 +{
12123 +}
12124 +#endif
12125 +
12126 +#define PHYS_HASHSIZE (8192)
12127 +
12128 +struct phys_desc;
12129 +
12130 +DEF_HASH_STRUCTS(virtmem, PHYS_HASHSIZE, struct phys_desc);
12131 +
12132 +struct phys_desc {
12133 +       struct virtmem_ptrs virt_ptrs;
12134 +       int fd;
12135 +       __u64 offset;
12136 +       void *virt;
12137 +       unsigned long phys;
12138 +       struct list_head list;
12139 +};
12140 +
12141 +struct virtmem_table virtmem_hash;
12142 +
12143 +static int virt_cmp(void *virt1, void *virt2)
12144 +{
12145 +       return(virt1 != virt2);
12146 +}
12147 +
12148 +static int virt_hash(void *virt)
12149 +{
12150 +       unsigned long addr = ((unsigned long) virt) >> PAGE_SHIFT;
12151 +       return(addr % PHYS_HASHSIZE);
12152 +}
12153 +
12154 +DEF_HASH(static, virtmem, struct phys_desc, virt_ptrs, void *, virt, virt_cmp, 
12155 +        virt_hash);
12156 +
12157 +LIST_HEAD(descriptor_mappings);
12158 +
12159 +struct desc_mapping {
12160 +       int fd;
12161 +       struct list_head list;
12162 +       struct list_head pages;
12163 +};
12164 +
12165 +static struct desc_mapping *find_mapping(int fd)
12166 +{
12167 +       struct desc_mapping *desc;
12168 +       struct list_head *ele;
12169 +
12170 +       list_for_each(ele, &descriptor_mappings){
12171 +               desc = list_entry(ele, struct desc_mapping, list);
12172 +               if(desc->fd == fd)
12173 +                       return(desc);
12174 +       }
12175 +
12176 +       return(NULL);
12177 +}
12178 +
12179 +static struct desc_mapping *descriptor_mapping(int fd)
12180 +{
12181 +       struct desc_mapping *desc;
12182 +
12183 +       desc = find_mapping(fd);
12184 +       if(desc != NULL)
12185 +               return(desc);
12186 +
12187 +       desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
12188 +       if(desc == NULL)
12189 +               return(NULL);
12190 +
12191 +       *desc = ((struct desc_mapping) 
12192 +               { .fd =         fd,
12193 +                 .list =       LIST_HEAD_INIT(desc->list),
12194 +                 .pages =      LIST_HEAD_INIT(desc->pages) });
12195 +       list_add(&desc->list, &descriptor_mappings);
12196 +
12197 +       return(desc);
12198 +}
12199 +
12200 +int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w)
12201 +{
12202 +       struct desc_mapping *fd_maps;
12203 +       struct phys_desc *desc;
12204 +       unsigned long phys;
12205 +       int err;
12206 +
12207 +       fd_maps = descriptor_mapping(fd);
12208 +       if(fd_maps == NULL)
12209 +               return(-ENOMEM);
12210 +
12211 +       phys = __pa(virt);
12212 +       if(find_virtmem_hash(&virtmem_hash, virt) != NULL)
12213 +               panic("Address 0x%p is already substituted\n", virt);
12214 +
12215 +       err = -ENOMEM;
12216 +       desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
12217 +       if(desc == NULL)
12218 +               goto out;
12219 +
12220 +       *desc = ((struct phys_desc) 
12221 +               { .virt_ptrs =  { NULL, NULL },
12222 +                 .fd =         fd,
12223 +                 .offset =             offset,
12224 +                 .virt =               virt,
12225 +                 .phys =               __pa(virt),
12226 +                 .list =               LIST_HEAD_INIT(desc->list) });
12227 +       insert_virtmem_hash(&virtmem_hash, desc);
12228 +
12229 +       list_add(&desc->list, &fd_maps->pages);
12230 +
12231 +       virt = (void *) ((unsigned long) virt & PAGE_MASK);
12232 +       err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0);
12233 +       if(!err)
12234 +               goto out;
12235 +
12236 +       remove_virtmem_hash(&virtmem_hash, desc);
12237 +       kfree(desc);
12238 + out:
12239 +       return(err);
12240 +}
12241 +
12242 +static int physmem_fd = -1;
12243 +
12244 +static void remove_mapping(struct phys_desc *desc)
12245 +{
12246 +       void *virt = desc->virt;
12247 +       int err;
12248 +
12249 +       remove_virtmem_hash(&virtmem_hash, desc);
12250 +       list_del(&desc->list);
12251 +       kfree(desc);
12252 +
12253 +       err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0);
12254 +       if(err)
12255 +               panic("Failed to unmap block device page from physical memory, "
12256 +                     "errno = %d", -err);
12257 +}
12258 +
12259 +int physmem_remove_mapping(void *virt)
12260 +{
12261 +       struct phys_desc *desc;
12262 +
12263 +       virt = (void *) ((unsigned long) virt & PAGE_MASK);
12264 +       desc = find_virtmem_hash(&virtmem_hash, virt);
12265 +       if(desc == NULL)
12266 +               return(0);
12267 +
12268 +       remove_mapping(desc);
12269 +       return(1);
12270 +}
12271 +
12272 +void physmem_forget_descriptor(int fd)
12273 +{
12274 +       struct desc_mapping *desc;
12275 +       struct phys_desc *page;
12276 +       struct list_head *ele, *next;
12277 +       __u64 offset;
12278 +       void *addr;
12279 +       int err;
12280 +
12281 +       desc = find_mapping(fd);
12282 +       if(desc == NULL)
12283 +               return;
12284 +
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);
12291 +               if(err)
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);
12296 +               if(err < 0)
12297 +                       panic("physmem_forget_descriptor - failed to read "
12298 +                             "from fd %d to 0x%p, error = %d\n",
12299 +                             fd, addr, -err);
12300 +       }
12301 +
12302 +       list_del(&desc->list);
12303 +       kfree(desc);
12304 +}
12305 +
12306 +void arch_free_page(struct page *page, int order)
12307 +{
12308 +       void *virt;
12309 +       int i;
12310 +
12311 +       for(i = 0; i < (1 << order); i++){
12312 +               virt = __va(page_to_phys(page + i));
12313 +               physmem_remove_mapping(virt);
12314 +       }
12315 +}
12316 +
12317 +int is_remapped(void *virt)
12318 +{
12319 +       return(find_virtmem_hash(&virtmem_hash, virt) != NULL);
12320 +}
12321 +
12322 +/* Changed during early boot */
12323 +unsigned long high_physmem;
12324 +
12325 +extern unsigned long physmem_size;
12326 +
12327 +void *to_virt(unsigned long phys)
12328 +{
12329 +       return((void *) uml_physmem + phys);
12330 +}
12331 +
12332 +unsigned long to_phys(void *virt)
12333 +{
12334 +       return(((unsigned long) virt) - uml_physmem);
12335 +}
12336 +
12337 +int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem)
12338 +{
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;
12342 +       int i;
12343 +
12344 +       phys_pages = physmem >> PAGE_SHIFT;
12345 +       phys_len = phys_pages * sizeof(struct page);
12346 +
12347 +       iomem_pages = iomem >> PAGE_SHIFT;
12348 +       iomem_len = iomem_pages * sizeof(struct page);
12349 +
12350 +       highmem_pages = highmem >> PAGE_SHIFT;
12351 +       highmem_len = highmem_pages * sizeof(struct page);
12352 +
12353 +       total_pages = phys_pages + iomem_pages + highmem_pages;
12354 +       total_len = phys_len + iomem_pages + highmem_len;
12355 +
12356 +       if(kmalloc_ok){
12357 +               map = kmalloc(total_len, GFP_KERNEL);
12358 +               if(map == NULL) 
12359 +                       map = vmalloc(total_len);
12360 +       }
12361 +       else map = alloc_bootmem_low_pages(total_len);
12362 +
12363 +       if(map == NULL)
12364 +               return(-ENOMEM);
12365 +
12366 +       for(i = 0; i < total_pages; i++){
12367 +               p = &map[i];
12368 +               set_page_count(p, 0);
12369 +               SetPageReserved(p);
12370 +               INIT_LIST_HEAD(&p->lru);
12371 +       }
12372 +
12373 +       mem_map = map;
12374 +       max_mapnr = total_pages;
12375 +       return(0);
12376 +}
12377 +
12378 +struct page *phys_to_page(const unsigned long phys)
12379 +{
12380 +       return(&mem_map[phys >> PAGE_SHIFT]);
12381 +}
12382 +
12383 +struct page *__virt_to_page(const unsigned long virt)
12384 +{
12385 +       return(&mem_map[__pa(virt) >> PAGE_SHIFT]);
12386 +}
12387 +
12388 +unsigned long page_to_phys(struct page *page)
12389 +{
12390 +       return((page - mem_map) << PAGE_SHIFT);
12391 +}
12392 +
12393 +pte_t mk_pte(struct page *page, pgprot_t pgprot)
12394 +{
12395 +       pte_t pte;
12396 +
12397 +       pte_val(pte) = page_to_phys(page) + pgprot_val(pgprot);
12398 +       if(pte_present(pte)) pte_mknewprot(pte_mknewpage(pte));
12399 +       return(pte);
12400 +}
12401 +
12402 +/* Changed during early boot */
12403 +static unsigned long kmem_top = 0;
12404 +
12405 +unsigned long get_kmem_end(void)
12406 +{
12407 +       if(kmem_top == 0) 
12408 +               kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
12409 +       return(kmem_top);
12410 +}
12411 +
12412 +void map_memory(unsigned long virt, unsigned long phys, unsigned long len, 
12413 +               int r, int w, int x)
12414 +{
12415 +       __u64 offset;
12416 +       int fd, err;
12417 +
12418 +       fd = phys_mapping(phys, &offset);
12419 +       err = os_map_memory((void *) virt, fd, offset, len, r, w, x);
12420 +       if(err)
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);
12423 +}
12424 +
12425 +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
12426 +
12427 +void setup_physmem(unsigned long start, unsigned long reserve_end,
12428 +                  unsigned long len, unsigned long highmem)
12429 +{
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;
12434 +
12435 +       physmem_fd = create_mem_file(len + highmem);
12436 +
12437 +       offset = uml_reserved - uml_physmem;
12438 +       err = os_map_memory((void *) uml_reserved, physmem_fd, offset, 
12439 +                           len - offset, 1, 1, 0);
12440 +       if(err < 0){
12441 +               os_print_error(err, "Mapping memory");
12442 +               exit(1);
12443 +       }
12444 +
12445 +       bootmap_size = init_bootmem(pfn, pfn + delta);
12446 +       free_bootmem(__pa(reserve_end) + bootmap_size,
12447 +                    len - bootmap_size - reserve);
12448 +}
12449 +
12450 +int phys_mapping(unsigned long phys, __u64 *offset_out)
12451 +{
12452 +       struct phys_desc *desc = find_virtmem_hash(&virtmem_hash, 
12453 +                                                  __va(phys & PAGE_MASK));
12454 +       int fd = -1;
12455 +
12456 +       if(desc != NULL){
12457 +               fd = desc->fd;
12458 +               *offset_out = desc->offset;
12459 +       }
12460 +       else if(phys < physmem_size){
12461 +               fd = physmem_fd;
12462 +               *offset_out = phys;
12463 +       }
12464 +       else if(phys < __pa(end_iomem)){
12465 +               struct iomem_region *region = iomem_regions;
12466 +       
12467 +               while(region != NULL){
12468 +                       if((phys >= region->phys) && 
12469 +                          (phys < region->phys + region->size)){
12470 +                               fd = region->fd;
12471 +                               *offset_out = phys - region->phys;
12472 +                               break;
12473 +                       }
12474 +                       region = region->next;
12475 +               }
12476 +       }
12477 +       else if(phys < __pa(end_iomem) + highmem){
12478 +               fd = physmem_fd;
12479 +               *offset_out = phys - iomem_size;
12480 +       }
12481 +
12482 +       return(fd);
12483 +}
12484 +
12485 +static int __init uml_mem_setup(char *line, int *add)
12486 +{
12487 +       char *retptr;
12488 +       physmem_size = memparse(line,&retptr);
12489 +       return 0;
12490 +}
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"
12499 +);
12500 +
12501 +unsigned long find_iomem(char *driver, unsigned long *len_out)
12502 +{
12503 +       struct iomem_region *region = iomem_regions;
12504 +       
12505 +       while(region != NULL){
12506 +               if(!strcmp(region->driver, driver)){
12507 +                       *len_out = region->size;
12508 +                       return(region->virt);
12509 +               }
12510 +       }
12511 +
12512 +       return(0);
12513 +}
12514 +
12515 +int setup_iomem(void)
12516 +{
12517 +       struct iomem_region *region = iomem_regions;
12518 +       unsigned long iomem_start = high_physmem + PAGE_SIZE;
12519 +       int err;
12520 +
12521 +       while(region != NULL){
12522 +               err = os_map_memory((void *) iomem_start, region->fd, 0, 
12523 +                                   region->size, 1, 1, 0);
12524 +               if(err)
12525 +                       printk("Mapping iomem region for driver '%s' failed, "
12526 +                              "errno = %d\n", region->driver, -err);
12527 +               else {
12528 +                       region->virt = iomem_start;
12529 +                       region->phys = __pa(region->virt);
12530 +               }
12531 +
12532 +               iomem_start += region->size + PAGE_SIZE;
12533 +               region = region->next;
12534 +       }
12535 +
12536 +       return(0);
12537 +}
12538 +
12539 +__initcall(setup_iomem);
12540 +
12541 +/*
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
12545 + * of the file.
12546 + * ---------------------------------------------------------------------------
12547 + * Local variables:
12548 + * c-file-style: "linux"
12549 + * End:
12550 + */
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
12555 @@ -6,7 +6,6 @@
12556  #include <stdlib.h>
12557  #include <unistd.h>
12558  #include <errno.h>
12559 -#include <fcntl.h>
12560  #include <signal.h>
12561  #include <string.h>
12562  #include <sys/poll.h>
12563 @@ -49,7 +48,8 @@
12564  
12565         if(smp_sigio_handler()) return;
12566         while(1){
12567 -               if((n = poll(pollfds, pollfds_num, 0)) < 0){
12568 +               n = poll(pollfds, pollfds_num, 0);
12569 +               if(n < 0){
12570                         if(errno == EINTR) continue;
12571                         printk("sigio_handler : poll returned %d, "
12572                                "errno = %d\n", n, errno);
12573 @@ -366,34 +366,31 @@
12574  
12575  void forward_ipi(int fd, int pid)
12576  {
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);
12583 -               }
12584 -       }
12585 +       int err;
12586 +
12587 +       err = os_set_owner(fd, pid);
12588 +       if(err < 0)
12589 +               printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
12590 +                      "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
12591  }
12592  
12593  void forward_interrupts(int pid)
12594  {
12595         struct irq_fd *irq;
12596         unsigned long flags;
12597 +       int err;
12598  
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
12606 -                                */
12607 -                               printk("Failed to forward %d to pid %d, "
12608 -                                      "errno = %d\n", irq->fd, pid, 
12609 -                                      save_errno);
12610 -                       }
12611 +               err = os_set_owner(irq->fd, pid);
12612 +               if(err < 0){
12613 +                       /* XXX Just remove the irq rather than
12614 +                        * print out an infinite stream of these
12615 +                        */
12616 +                       printk("Failed to forward %d to pid %d, err = %d\n",
12617 +                              irq->fd, pid, -err);
12618                 }
12619 +
12620                 irq->pid = pid;
12621         }
12622         irq_unlock(flags);
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
12627 @@ -9,12 +9,14 @@
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"
12635  
12636  struct line_driver {
12637         char *name;
12638 +       char *device_name;
12639         char *devfs_name;
12640         short major;
12641         short minor_start;
12642 @@ -67,8 +69,6 @@
12643  
12644  #define LINES_INIT(n) {  num :         n }
12645  
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
12655 @@ -1,5 +1,5 @@
12656  /* 
12657 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
12658 + * Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com)
12659   * Licensed under the GPL
12660   */
12661  
12662 @@ -7,16 +7,24 @@
12663  #include "sysdep/ptrace.h"
12664  #include "sysdep/sigcontext.h"
12665  
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
12669 +{
12670 +       unsigned long insn;
12671 +       unsigned long fixup;
12672 +};
12673  
12674 +const struct exception_table_entry *search_exception_tables(unsigned long add);
12675
12676 +/* Compare this to arch/i386/mm/extable.c:fixup_exception() */
12677  int arch_fixup(unsigned long address, void *sc_ptr)
12678  {
12679         struct sigcontext *sc = sc_ptr;
12680 -       unsigned long fixup;
12681 +       const struct exception_table_entry *fixup;
12682  
12683         fixup = search_exception_tables(address);
12684         if(fixup != 0){
12685 -               sc->eip = fixup;
12686 +               sc->eip = fixup->fixup;
12687                 return(1);
12688         }
12689         return(0);
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
12694 @@ -1,9 +1,15 @@
12695  /* 
12696 - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
12697 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
12698   * Licensed under the GPL
12699   */
12700  
12701  #include "linux/config.h"
12702 +#include "linux/percpu.h"
12703 +#include "asm/pgalloc.h"
12704 +#include "asm/tlb.h"
12705 +
12706 +/* For some reason, mmu_gathers are referenced when CONFIG_SMP is off. */
12707 +DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
12708  
12709  #ifdef CONFIG_SMP
12710  
12711 @@ -23,7 +29,7 @@
12712  #include "os.h"
12713  
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;
12717  
12718  EXPORT_SYMBOL(cpu_online_map);
12719  
12720 @@ -55,7 +61,7 @@
12721  
12722  void smp_send_reschedule(int cpu)
12723  {
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++;
12727  }
12728  
12729 @@ -100,35 +106,34 @@
12730  
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)
12735                         continue;
12736 -               write(cpu_data[i].ipi_pipe[1], "S", 1);
12737 +               os_write_file(cpu_data[i].ipi_pipe[1], "S", 1);
12738         }
12739         printk("done\n");
12740  }
12741  
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;
12746  
12747  static int idle_proc(void *cpup)
12748  {
12749         int cpu = (int) cpup, err;
12750  
12751         err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
12752 -       if(err)
12753 -               panic("CPU#%d failed to create IPI pipe, errno = %d", cpu, 
12754 -                     -err);
12755 +       if(err < 0)
12756 +               panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);
12757  
12758         activate_ipi(cpu_data[cpu].ipi_pipe[0], 
12759                      current->thread.mode.tt.extern_pid);
12760   
12761         wmb();
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);
12765                 BUG();
12766         }
12767  
12768 -       while (!cpu_isset(cpu, &smp_commenced_mask))
12769 +       while (!cpu_isset(cpu, smp_commenced_mask))
12770                 cpu_relax();
12771  
12772         cpu_set(cpu, cpu_online_map);
12773 @@ -143,16 +148,20 @@
12774  
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, 
12780 +                               NULL);
12781 +       if(IS_ERR(new_task)) 
12782 +               panic("copy_process failed in idle_thread, error = %ld",
12783 +                     PTR_ERR(new_task));
12784  
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, 
12791                           sizeof(c)),
12792                     ({ panic("skas mode doesn't support SMP"); }));
12793 +       wake_up_forked_process(new_task);
12794         return(new_task);
12795  }
12796  
12797 @@ -160,15 +169,17 @@
12798  {
12799         struct task_struct *idle;
12800         unsigned long waittime;
12801 -       int err, cpu;
12802 +       int err, cpu, me = smp_processor_id();
12803  
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);
12809  
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);
12813 +       if(err < 0)
12814 +               panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
12815  
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);
12819  
12820         for(cpu = 1; cpu < ncpus; cpu++){
12821 @@ -180,10 +191,10 @@
12822                 unhash_process(idle);
12823  
12824                 waittime = 200000000;
12825 -               while (waittime-- && !cpu_isset(cpu, smp_callin_map))
12826 +               while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
12827                         cpu_relax();
12828  
12829 -               if (cpu_isset(cpu, smp_callin_map))
12830 +               if (cpu_isset(cpu, cpu_callin_map))
12831                         printk("done\n");
12832                 else printk("failed\n");
12833         }
12834 @@ -216,7 +227,7 @@
12835         int fd;
12836  
12837         fd = cpu_data[cpu].ipi_pipe[0];
12838 -       while (read(fd, &c, 1) == 1) {
12839 +       while (os_read_file(fd, &c, 1) == 1) {
12840                 switch (c) {
12841                 case 'C':
12842                         smp_call_function_slave(cpu);
12843 @@ -276,9 +287,9 @@
12844         info = _info;
12845  
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);
12852  
12853         while (atomic_read(&scf_started) != cpus)
12854                 barrier();
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
12859 @@ -4,11 +4,9 @@
12860  #include <stddef.h>
12861  #include <sched.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"
12872 @@ -65,9 +63,9 @@
12873  {
12874         struct slip_pre_exec_data *data = arg;
12875  
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);
12881  }
12882  
12883  static int slip_tramp(char **argv, int fd)
12884 @@ -77,8 +75,8 @@
12885         int status, pid, fds[2], err, output_len;
12886  
12887         err = os_pipe(fds, 1, 0);
12888 -       if(err){
12889 -               printk("slip_tramp : pipe failed, errno = %d\n", -err);
12890 +       if(err < 0){
12891 +               printk("slip_tramp : pipe failed, err = %d\n", -err);
12892                 return(err);
12893         }
12894  
12895 @@ -96,16 +94,18 @@
12896                         printk("slip_tramp : failed to allocate output "
12897                                "buffer\n");
12898  
12899 -               close(fds[1]);
12900 +               os_close_file(fds[1]);
12901                 read_output(fds[0], output, output_len);
12902                 if(output != NULL){
12903                         printk("%s", output);
12904                         kfree(output);
12905                 }
12906 -               if(waitpid(pid, &status, 0) < 0) err = errno;
12907 +               CATCH_EINTR(err = waitpid(pid, &status, 0));
12908 +               if(err < 0)
12909 +                       err = errno;
12910                 else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
12911                         printk("'%s' didn't exit with status 0\n", argv[0]);
12912 -                       err = EINVAL;
12913 +                       err = -EINVAL;
12914                 }
12915         }
12916         return(err);
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, 
12920                          NULL };
12921 -       int sfd, mfd, disc, sencap, err;
12922 +       int sfd, mfd, err;
12923  
12924 -       if((mfd = get_pty()) < 0){
12925 -               printk("umn : Failed to open pty\n");
12926 -               return(-1);
12927 +       mfd = get_pty();
12928 +       if(mfd < 0){
12929 +               printk("umn : Failed to open pty, err = %d\n", -mfd);
12930 +               return(mfd);
12931         }
12932 -       if((sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0)) < 0){
12933 -               printk("Couldn't open tty for slip line\n");
12934 -               return(-1);
12935 +       sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
12936 +       if(sfd < 0){
12937 +               printk("Couldn't open tty for slip line, err = %d\n", -sfd);
12938 +               return(sfd);
12939         }
12940         if(set_up_tty(sfd)) return(-1);
12941         pri->slave = sfd;
12942 @@ -138,28 +140,23 @@
12943  
12944                 err = slip_tramp(argv, sfd);
12945  
12946 -               if(err != 0){
12947 -                       printk("slip_tramp failed - errno = %d\n", err);
12948 -                       return(-err);
12949 +               if(err < 0){
12950 +                       printk("slip_tramp failed - err = %d\n", -err);
12951 +                       return(err);
12952                 }
12953 -               if(ioctl(pri->slave, SIOCGIFNAME, pri->name) < 0){
12954 -                       printk("SIOCGIFNAME failed, errno = %d\n", errno);
12955 -                       return(-errno);
12956 +               err = os_get_ifname(pri->slave, pri->name);
12957 +               if(err < 0){
12958 +                       printk("get_ifname failed, err = %d\n", -err);
12959 +                       return(err);
12960                 }
12961                 iter_addresses(pri->dev, open_addr, pri->name);
12962         }
12963         else {
12964 -               disc = N_SLIP;
12965 -               if(ioctl(sfd, TIOCSETD, &disc) < 0){
12966 -                       printk("Failed to set slip line discipline - "
12967 -                              "errno = %d\n", errno);
12968 -                       return(-errno);
12969 -               }
12970 -               sencap = 0;
12971 -               if(ioctl(sfd, SIOCSIFENCAP, &sencap) < 0){
12972 -                       printk("Failed to set slip encapsulation - "
12973 -                              "errno = %d\n", errno);
12974 -                       return(-errno);
12975 +               err = os_set_slip(sfd);
12976 +               if(err < 0){
12977 +                       printk("Failed to set slip discipline encapsulation - "
12978 +                              "err = %d\n", -err);
12979 +                       return(err);
12980                 }
12981         }
12982         return(mfd);
12983 @@ -181,9 +178,9 @@
12984         err = slip_tramp(argv, -1);
12985  
12986         if(err != 0)
12987 -               printk("slip_tramp failed - errno = %d\n", err);
12988 -       close(fd);
12989 -       close(pri->slave);
12990 +               printk("slip_tramp failed - errno = %d\n", -err);
12991 +       os_close_file(fd);
12992 +       os_close_file(pri->slave);
12993         pri->slave = -1;
12994  }
12995  
12996 @@ -243,7 +240,7 @@
12997  {
12998         struct slip_data *pri = data;
12999  
13000 -       if(pri->slave == -1) return;
13001 +       if(pri->slave < 0) return;
13002         open_addr(addr, netmask, pri->name);
13003  }
13004  
13005 @@ -252,7 +249,7 @@
13006  {
13007         struct slip_data *pri = data;
13008  
13009 -       if(pri->slave == -1) return;
13010 +       if(pri->slave < 0) return;
13011         close_addr(addr, netmask, pri->name);
13012  }
13013  
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
13018 @@ -0,0 +1,79 @@
13019 +#ifndef __UM_FS_HOSTFS
13020 +#define __UM_FS_HOSTFS
13021 +
13022 +#include "os.h"
13023 +
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.
13026 + */
13027 +
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
13039 +
13040 +struct hostfs_iattr {
13041 +       unsigned int    ia_valid;
13042 +       mode_t          ia_mode;
13043 +       uid_t           ia_uid;
13044 +       gid_t           ia_gid;
13045 +       loff_t          ia_size;
13046 +       struct timespec ia_atime;
13047 +       struct timespec ia_mtime;
13048 +       struct timespec ia_ctime;
13049 +       unsigned int    ia_attr_flags;
13050 +};
13051 +
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,
13067 +                     int len);
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);
13085 +
13086 +#endif
13087 +
13088 +/*
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
13092 + * of the file.
13093 + * ---------------------------------------------------------------------------
13094 + * Local variables:
13095 + * c-file-style: "linux"
13096 + * End:
13097 + */
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
13102 @@ -7,7 +7,6 @@
13103  #include <stdlib.h>
13104  #include <termios.h>
13105  #include <pty.h>
13106 -#include <fcntl.h>
13107  #include <signal.h>
13108  #include <errno.h>
13109  #include <string.h>
13110 @@ -17,6 +16,7 @@
13111  #include "init.h"
13112  #include "user.h"
13113  #include "kern_util.h"
13114 +#include "user_util.h"
13115  #include "sigio.h"
13116  #include "helper.h"
13117  #include "os.h"
13118 @@ -26,7 +26,7 @@
13119  int pty_close_sigio = 0;
13120  
13121  /* Used as a flag during SIGIO testing early in boot */
13122 -static int got_sigio = 0;
13123 +static volatile int got_sigio = 0;
13124  
13125  void __init handler(int sig)
13126  {
13127 @@ -45,19 +45,18 @@
13128  
13129         info->err = 0;
13130         if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
13131 -               info->err = errno;
13132 +               info->err = -errno;
13133  }
13134  
13135  void __init check_one_sigio(void (*proc)(int, int))
13136  {
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;
13142  
13143         initial_thread_cb(openpty_cb, &pty);
13144         if(pty.err){
13145 -               printk("openpty failed, errno = %d\n", pty.err);
13146 +               printk("openpty failed, errno = %d\n", -pty.err);
13147                 return;
13148         }
13149  
13150 @@ -69,23 +68,13 @@
13151                 return;
13152         }
13153  
13154 -       if(tcgetattr(master, &tt) < 0)
13155 -               panic("check_sigio : tcgetattr failed, errno = %d\n", errno);
13156 -       cfmakeraw(&tt);
13157 -       if(tcsetattr(master, TCSADRAIN, &tt) < 0)
13158 -               panic("check_sigio : tcsetattr failed, errno = %d\n", errno);
13159 -
13160 -       if((flags = fcntl(master, F_GETFL)) < 0)
13161 -               panic("tty_fds : fcntl F_GETFL failed, errno = %d\n", errno);
13162 -
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);
13167 -
13168 -       if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
13169 -               panic("check_sigio : fcntl F_SETFL failed, errno = %d\n", 
13170 -                     errno);
13171 +       err = __raw(master, 1, 0); //Not now, but complain so we now where we failed.
13172 +       if (err < 0)
13173 +               panic("check_sigio : __raw failed, errno = %d\n", -err);
13174 +
13175 +       err = os_sigio_async(master, slave);
13176 +       if(err < 0)
13177 +               panic("tty_fds : sigio_async failed, err = %d\n", -err);
13178  
13179         if(sigaction(SIGIO, NULL, &old) < 0)
13180                 panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
13181 @@ -97,8 +86,8 @@
13182         got_sigio = 0;
13183         (*proc)(master, slave);
13184                 
13185 -       close(master);
13186 -       close(slave);
13187 +       os_close_file(master);
13188 +       os_close_file(slave);
13189  
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...");
13194  
13195         memset(buf, 0, sizeof(buf));
13196 -       while(write(master, buf, sizeof(buf)) > 0) ;
13197 +
13198 +       while(os_write_file(master, buf, sizeof(buf)) > 0) ;
13199         if(errno != EAGAIN)
13200                 panic("check_sigio : write failed, errno = %d\n", errno);
13201 -
13202 -       while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
13203 +       while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
13204  
13205         if(got_sigio){
13206                 printk("Yes\n");
13207                 pty_output_sigio = 1;
13208         }
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);
13213  }
13214  
13215  static void tty_close(int master, int slave)
13216  {
13217         printk("Checking that host ptys support SIGIO on close...");
13218  
13219 -       close(slave);
13220 +       os_close_file(slave);
13221         if(got_sigio){
13222                 printk("Yes\n");
13223                 pty_close_sigio = 1;
13224 @@ -140,7 +129,8 @@
13225  
13226  void __init check_sigio(void)
13227  {
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 "
13232                        "check\n");
13233                 return;
13234 @@ -201,11 +191,10 @@
13235                         p = &fds->poll[i];
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));
13240                                 if(n != sizeof(c))
13241                                         printk("write_sigio_thread : "
13242 -                                              "read failed, errno = %d\n",
13243 -                                              errno);
13244 +                                              "read failed, err = %d\n", -n);
13245                                 tmp = current_poll;
13246                                 current_poll = next_poll;
13247                                 next_poll = tmp;
13248 @@ -218,10 +207,10 @@
13249                                         (fds->used - i) * sizeof(*fds->poll));
13250                         }
13251  
13252 -                       n = write(respond_fd, &c, sizeof(c));
13253 +                       n = os_write_file(respond_fd, &c, sizeof(c));
13254                         if(n != sizeof(c))
13255                                 printk("write_sigio_thread : write failed, "
13256 -                                      "errno = %d\n", errno);
13257 +                                      "err = %d\n", -n);
13258                 }
13259         }
13260  }
13261 @@ -252,15 +241,15 @@
13262         char c;
13263  
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);
13270                 goto fail;
13271         }
13272  
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);
13278                 goto fail;
13279         }
13280  
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]);
13293         sigio_unlock();
13294         set_signals(flags);
13295  }
13296 @@ -369,15 +358,15 @@
13297                 goto out;
13298  
13299         err = os_pipe(write_sigio_fds, 1, 1);
13300 -       if(err){
13301 +       if(err < 0){
13302                 printk("write_sigio_workaround - os_pipe 1 failed, "
13303 -                      "errno = %d\n", -err);
13304 +                      "err = %d\n", -err);
13305                 goto out;
13306         }
13307         err = os_pipe(sigio_private, 1, 1);
13308 -       if(err){
13309 +       if(err < 0){
13310                 printk("write_sigio_workaround - os_pipe 2 failed, "
13311 -                      "errno = %d\n", -err);
13312 +                      "err = %d\n", -err);
13313                 goto out_close1;
13314         }
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;
13319   out_close2:
13320 -       close(sigio_private[0]);
13321 -       close(sigio_private[1]);        
13322 +       os_close_file(sigio_private[0]);
13323 +       os_close_file(sigio_private[1]);        
13324   out_close1:
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]);
13329         sigio_unlock();
13330  }
13331  
13332 @@ -412,10 +401,16 @@
13333         int n;
13334         char c;
13335  
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);
13340 -               return(-errno);
13341 +               if(n < 0) {
13342 +                       printk("read_sigio_fd - read failed, err = %d\n", -n);
13343 +                       return(n);
13344 +               } 
13345 +               else { 
13346 +                       printk("read_sigio_fd - short read, bytes = %d\n", n);
13347 +                       return(-EIO);
13348 +               }
13349         }
13350         return(n);
13351  }
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
13356 @@ -2,36 +2,5 @@
13357  #define __UM_SYSTEM_I386_H
13358  
13359  #include "asm/system-generic.h"
13360 -
13361 -static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
13362 -                                     unsigned long new, int size)
13363 -{
13364 -       unsigned long prev;
13365 -       switch (size) {
13366 -       case 1:
13367 -               __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
13368 -                                    : "=a"(prev)
13369 -                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
13370 -                                    : "memory");
13371 -               return prev;
13372 -       case 2:
13373 -               __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
13374 -                                    : "=a"(prev)
13375 -                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
13376 -                                    : "memory");
13377 -               return prev;
13378 -       case 4:
13379 -               __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
13380 -                                    : "=a"(prev)
13381 -                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
13382 -                                    : "memory");
13383 -               return prev;
13384 -       }
13385 -       return old;
13386 -}
13387 -
13388 -#define cmpxchg(ptr,o,n)\
13389 -       ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
13390 -                                       (unsigned long)(n),sizeof(*(ptr))))
13391      
13392  #endif
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
13397 @@ -0,0 +1,24 @@
13398 +/*
13399 + * sys-i386/time.c 
13400 + * Created             25.9.2002       Sapan Bhatia
13401 + *
13402 + */
13403 +
13404 +unsigned long long time_stamp(void)
13405 +{
13406 +       unsigned long low, high;
13407 +
13408 +       asm("rdtsc" : "=a" (low), "=d" (high));
13409 +       return((((unsigned long long) high) << 32) + low);
13410 +}
13411 +
13412 +/*
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
13416 + * of the file.
13417 + * ---------------------------------------------------------------------------
13418 + * Local variables:
13419 + * c-file-style: "linux"
13420 + * End:
13421 + */
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 @@
13427  
13428  SYS_HEADERS = $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
13429  
13430 +sys_prepare: $(SYS_DIR)/sc.h
13431 +
13432  prepare: $(SYS_HEADERS)
13433  
13434 +filechk_$(SYS_DIR)/sc.h := $(SYS_UTIL_DIR)/mk_sc
13435 +
13436  $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
13437 -       $< > $@
13438 +       $(call filechk,$@)
13439 +
13440 +filechk_$(SYS_DIR)/thread.h := $(SYS_UTIL_DIR)/mk_thread 
13441  
13442  $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread 
13443 -       $< > $@
13444 +       $(call filechk,$@)
13445  
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) $@
13450  
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) $@
13455  
13456  $(SYS_UTIL_DIR): include/asm FORCE
13457 -       @$(call descend,$@,)
13458 +       $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR)
13459  
13460 -sysclean :
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
13467 @@ -10,7 +10,7 @@
13468  
13469  extern cpumask_t cpu_online_map;
13470  
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
13480 @@ -29,6 +29,20 @@
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.
13483  
13484 +# Turn this back on when the driver actually works
13485 +#
13486 +#config BLK_DEV_COW
13487 +#      tristate "COW block device"
13488 +#      help
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.
13493 +
13494 +config BLK_DEV_COW_COMMON
13495 +       bool
13496 +       default BLK_DEV_COW || BLK_DEV_UBD
13497 +
13498  config BLK_DEV_LOOP
13499         tristate "Loopback device support"
13500  
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
13505 @@ -6,7 +6,6 @@
13506  #include <unistd.h>
13507  #include <sys/types.h>
13508  #include <sys/stat.h>
13509 -#include <fcntl.h>
13510  #include <errno.h>
13511  
13512  #include "user_util.h"
13513 @@ -19,13 +18,15 @@
13514  {
13515         int fd, n;
13516  
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);
13520 +       if(fd < 0){
13521 +               printk("Opening '%s' failed - err = %d\n", filename, -fd);
13522                 return(-1);
13523         }
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);
13528 +       if(n != size){
13529 +               printk("Read of %d bytes from '%s' failed, err = %d\n", size, 
13530 +                      filename, -n);
13531                 return(-1);
13532         }
13533         return(0);
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).
13540   */
13541  
13542 -static inline unsigned long frame_restorer(void)
13543 -{
13544 -       unsigned long *fp;
13545 -
13546 -       fp = __builtin_frame_address(0);
13547 -       return((unsigned long) (fp + 1));
13548 -}
13549 +#define frame_restorer() \
13550 +({ \
13551 +       unsigned long *fp; \
13552 +\
13553 +       fp = __builtin_frame_address(0); \
13554 +       ((unsigned long) (fp + 1)); \
13555 +})
13556  
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
13559   * signals.
13560   */
13561  
13562 -static inline unsigned long frame_sp(void)
13563 -{
13564 -       unsigned long *fp;
13565 -
13566 -       fp = __builtin_frame_address(0);
13567 -       return((unsigned long) (fp + 1));
13568 -}
13569 +#define frame_sp() \
13570 +({ \
13571 +       unsigned long *fp; \
13572 +\
13573 +       fp = __builtin_frame_address(0); \
13574 +       ((unsigned long) (fp + 1)); \
13575 +})
13576  
13577  #endif
13578  
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
13583 @@ -5,7 +5,6 @@
13584  
13585  #include <stdio.h>
13586  #include <termios.h>
13587 -#include <fcntl.h>
13588  #include <errno.h>
13589  #include <unistd.h>
13590  #include "chan_user.h"
13591 @@ -30,7 +29,8 @@
13592         }
13593         str++;
13594  
13595 -       if((data = um_kmalloc(sizeof(*data))) == NULL) 
13596 +       data = um_kmalloc(sizeof(*data)); 
13597 +       if(data == NULL) 
13598                 return(NULL);
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
13605 @@ -26,6 +26,7 @@
13606  #include "mconsole_kern.h"
13607  #include "init.h"
13608  #include "irq_user.h"
13609 +#include "irq_kern.h"
13610  
13611  static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
13612  LIST_HEAD(opened);
13613 @@ -37,7 +38,8 @@
13614         struct sk_buff *skb;
13615  
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++;
13621                 return 0;
13622         }
13623 @@ -61,14 +63,14 @@
13624         return pkt_len;
13625  }
13626  
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)
13629  {
13630         struct net_device *dev = dev_id;
13631         struct uml_net_private *lp = dev->priv;
13632         int err;
13633  
13634         if(!netif_running(dev))
13635 -               return;
13636 +               return(IRQ_NONE);
13637  
13638         spin_lock(&lp->lock);
13639         while((err = uml_net_rx(dev)) > 0) ;
13640 @@ -83,6 +85,7 @@
13641  
13642   out:
13643         spin_unlock(&lp->lock);
13644 +       return(IRQ_HANDLED);
13645  }
13646  
13647  static int uml_net_open(struct net_device *dev)
13648 @@ -250,37 +253,6 @@
13649  #endif
13650  }
13651  
13652 -/*
13653 - * default do nothing hard header packet routines for struct net_device init.
13654 - * real ethernet transports will overwrite with real routines.
13655 - */
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)
13658 -{
13659 -       return(0); /* no change */
13660 -}
13661 -
13662 -static int uml_net_rebuild_header(struct sk_buff *skb)
13663 -{
13664 -       return(0); /* ignore */ 
13665 -}
13666 -
13667 -static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh)
13668 -{
13669 -       return(-1); /* fail */
13670 -}
13671 -
13672 -static void uml_net_header_cache_update(struct hh_cache *hh,
13673 -                 struct net_device *dev, unsigned char * haddr)
13674 -{
13675 -       /* ignore */
13676 -}
13677 -
13678 -static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr)
13679 -{
13680 -       return(0); /* nothing */
13681 -}
13682 -
13683  static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
13684  static struct list_head devices = LIST_HEAD_INIT(devices);
13685  
13686 @@ -290,7 +262,7 @@
13687         struct uml_net *device;
13688         struct net_device *dev;
13689         struct uml_net_private *lp;
13690 -       int err, size;
13691 +       int save, err, size;
13692  
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);
13697         device->dev = dev;
13698  
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;
13704 -
13705         (*transport->kern->init)(dev, init);
13706  
13707         dev->mtu = transport->user->max_packet;
13708 @@ -364,21 +330,29 @@
13709         }
13710         lp = dev->priv;
13711  
13712 -       INIT_LIST_HEAD(&lp->list);
13713 -       spin_lock_init(&lp->lock);
13714 -       lp->dev = dev;
13715 -       lp->fd = -1;
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.
13731 +        */
13732 +       save = lp->user[0];
13733 +       *lp = ((struct uml_net_private) 
13734 +               { .list                 = LIST_HEAD_INIT(lp->list),
13735 +                 .lock                 = SPIN_LOCK_UNLOCKED,
13736 +                 .dev                  = dev,
13737 +                 .fd                   = -1,
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 } });
13750  
13751         init_timer(&lp->tl);
13752         lp->tl.function = uml_net_user_timer_expire;
13753 @@ -611,7 +585,8 @@
13754         unregister_netdev(dev);
13755  
13756         list_del(&device->list);
13757 -       free_netdev(device);
13758 +       kfree(device);
13759 +       free_netdev(dev);
13760         return(0);
13761  }
13762  
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
13767 @@ -1,5 +1,5 @@
13768  /* 
13769 - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
13770 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
13771   * Licensed under the GPL
13772   */
13773  
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
13778 @@ -7,9 +7,7 @@
13779  #include <stdlib.h>
13780  #include "init.h"
13781  
13782 -static __initdata char *config = "
13783 -CONFIG
13784 -";
13785 +static __initdata char *config = "CONFIG";
13786  
13787  static int __init print_config(char *line, int *add)
13788  {
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 @@
13794  
13795  struct mc_request;
13796  
13797 +enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC };
13798 +
13799  struct mconsole_command
13800  {
13801         char *command;
13802         void (*handler)(struct mc_request *req);
13803 -       int as_interrupt;
13804 +       enum mc_context context;
13805  };
13806  
13807  struct mc_request
13808 @@ -77,6 +79,8 @@
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);
13814  
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
13821 @@ -7,11 +7,11 @@
13822  
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
13835  
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
13840  
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))
13845  
13846 -DMODULES-$(CONFIG_MODULES) = -D__CONFIG_MODULES__
13847 -DMODVERSIONS-$(CONFIG_MODVERSIONS) = -D__CONFIG_MODVERSIONS__
13848 -
13849 -
13850 -CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES-y) $(DMODVERSIONS-y) \
13851 -       -I/usr/include -I../include
13852 -
13853  CFLAGS_frame.o := $(patsubst -fomit-frame-pointer,,$(USER_CFLAGS))
13854  
13855 -$(USER_OBJS) : %.o: %.c
13856 -       $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
13857 -
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.
13860  
13861  $(obj)/frame.o: $(src)/frame.c
13862         $(CC) $(CFLAGS_$(notdir $@)) -c -o $@ $<
13863  
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 $@ $<
13867  
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 $$_ }'
13871  
13872  $(obj)/config.o : $(obj)/config.c
13873  
13874 -clean:
13875 -       rm -f config.c
13876 -       for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
13877 -
13878 -modules:
13879 -
13880 -fastdep:
13881 -
13882 -dep:
13883 -
13884 -archmrproper: clean
13885 +quiet_cmd_quote = QUOTE $@
13886 +cmd_quote = $(PERL) -e $(QUOTE) < $< > $@
13887  
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
13895 @@ -5,9 +5,12 @@
13896  
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"
13906  #include "os.h"
13907  #include "xterm.h"
13908 @@ -19,17 +22,18 @@
13909         int new_fd;
13910  };
13911  
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)
13914  {
13915         struct xterm_wait *xterm = data;
13916         int fd;
13917  
13918         fd = os_rcv_fd(xterm->fd, &xterm->pid);
13919         if(fd == -EAGAIN)
13920 -               return;
13921 +               return(IRQ_NONE);
13922  
13923         xterm->new_fd = fd;
13924         up(&xterm->sem);
13925 +       return(IRQ_HANDLED);
13926  }
13927  
13928  int xterm_fd(int socket, int *pid_out)
13929 @@ -54,7 +58,8 @@
13930         if(err){
13931                 printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
13932                        "err = %d\n",  err);
13933 -               return(err);
13934 +               ret = err;
13935 +               goto out;
13936         }
13937         down(&data->sem);
13938  
13939 @@ -62,6 +67,7 @@
13940  
13941         ret = data->new_fd;
13942         *pid_out = data->pid;
13943 + out:
13944         kfree(data);
13945  
13946         return(ret);
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
13951 @@ -0,0 +1,41 @@
13952 +#ifndef __COW_H__
13953 +#define __COW_H__
13954 +
13955 +#include <asm/types.h>
13956 +
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)
13963 +#else
13964 +#error "__BYTE_ORDER not defined"
13965 +#endif
13966 +
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);
13970 +
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);
13977 +
13978 +extern int write_cow_header(char *cow_file, int fd, char *backing_file, 
13979 +                           int sectorsize, int alignment, long long *size);
13980 +
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);
13984 +
13985 +#endif
13986 +
13987 +/*
13988 + * ---------------------------------------------------------------------------
13989 + * Local variables:
13990 + * c-file-style: "linux"
13991 + * End:
13992 + */
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
13997 @@ -66,13 +66,4 @@
13998         $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
13999         rm -f asm
14000  
14001 -clean:
14002 -       rm -f $(OBJS)
14003 -       rm -f ppc_defs.h
14004 -       rm -f checksum.S semaphore.c mk_defs.c
14005 -
14006 -fastdep:
14007 -
14008 -dep:
14009 -
14010 -modules:
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
14016 @@ -0,0 +1,88 @@
14017 +#include "linux/types.h"
14018 +#include "linux/module.h"
14019 +
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.*/
14025 +
14026 +#undef strlen
14027 +#undef strstr
14028 +#undef memcpy
14029 +#undef memset
14030 +
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 *, ...);
14035 +
14036 +EXPORT_SYMBOL(strlen);
14037 +EXPORT_SYMBOL(memcpy);
14038 +EXPORT_SYMBOL(memset);
14039 +EXPORT_SYMBOL(printf);
14040 +
14041 +EXPORT_SYMBOL(strstr);
14042 +
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
14046 + */
14047 +#define EXPORT_SYMBOL_PROTO(sym)       \
14048 +       int sym(void);                  \
14049 +       EXPORT_SYMBOL(sym);
14050 +
14051 +EXPORT_SYMBOL_PROTO(__errno_location);
14052 +
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);
14071 +
14072 +EXPORT_SYMBOL_PROTO(symlink);
14073 +EXPORT_SYMBOL_PROTO(link);
14074 +EXPORT_SYMBOL_PROTO(unlink);
14075 +EXPORT_SYMBOL_PROTO(readlink);
14076 +
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);
14084 +
14085 +EXPORT_SYMBOL_PROTO(ioctl);
14086 +
14087 +EXPORT_SYMBOL_PROTO(pread64);
14088 +EXPORT_SYMBOL_PROTO(pwrite64);
14089 +
14090 +EXPORT_SYMBOL_PROTO(statfs);
14091 +EXPORT_SYMBOL_PROTO(statfs64);
14092 +
14093 +EXPORT_SYMBOL_PROTO(getuid);
14094 +
14095 +/*
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
14099 + * of the file.
14100 + * ---------------------------------------------------------------------------
14101 + * Local variables:
14102 + * c-file-style: "linux"
14103 + * End:
14104 + */
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
14109 @@ -0,0 +1,28 @@
14110 +/* 
14111 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
14112 + * Licensed under the GPL
14113 + */
14114 +
14115 +#ifndef __IRQ_KERN_H__
14116 +#define __IRQ_KERN_H__
14117 +
14118 +#include "linux/interrupt.h"
14119 +
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,
14124 +                         void *dev_id);
14125 +
14126 +#endif
14127 +
14128 +/*
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
14132 + * of the file.
14133 + * ---------------------------------------------------------------------------
14134 + * Local variables:
14135 + * c-file-style: "linux"
14136 + * End:
14137 + */
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
14142 @@ -0,0 +1,811 @@
14143 +/* 
14144 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14145 + * Licensed under the GPL
14146 + */
14147 +
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>
14159 +#include "os.h"
14160 +
14161 +static int init_inode(struct inode *inode, struct dentry *dentry);
14162 +
14163 +struct hppfs_data {
14164 +       struct list_head list;
14165 +       char contents[PAGE_SIZE - sizeof(struct list_head)];
14166 +};
14167 +
14168 +struct hppfs_private {
14169 +       struct file proc_file;
14170 +       int host_fd;
14171 +       loff_t len;
14172 +       struct hppfs_data *contents;
14173 +};
14174 +
14175 +struct hppfs_inode_info {
14176 +        struct dentry *proc_dentry;
14177 +       struct inode vfs_inode;
14178 +};
14179 +
14180 +static inline struct hppfs_inode_info *HPPFS_I(struct inode *inode)
14181 +{
14182 +       return(list_entry(inode, struct hppfs_inode_info, vfs_inode));
14183 +}
14184 +
14185 +#define HPPFS_SUPER_MAGIC 0xb00000ee
14186 +
14187 +static struct super_operations hppfs_sbops;
14188 +
14189 +static int is_pid(struct dentry *dentry)
14190 +{
14191 +       struct super_block *sb;
14192 +       int i;
14193 +
14194 +       sb = dentry->d_sb;
14195 +       if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
14196 +               return(0);
14197 +
14198 +       for(i = 0; i < dentry->d_name.len; i++){
14199 +               if(!isdigit(dentry->d_name.name[i]))
14200 +                       return(0);
14201 +       }
14202 +       return(1);
14203 +}
14204 +
14205 +static char *dentry_name(struct dentry *dentry, int extra)
14206 +{
14207 +       struct dentry *parent;
14208 +       char *root, *name;
14209 +       const char *seg_name;
14210 +       int len, seg_len;
14211 +
14212 +       len = 0;
14213 +       parent = dentry;
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;
14219 +       }
14220 +       
14221 +       root = "proc";
14222 +       len += strlen(root);
14223 +       name = kmalloc(len + extra + 1, GFP_KERNEL);
14224 +       if(name == NULL) return(NULL);
14225 +
14226 +       name[len] = '\0';
14227 +       parent = dentry;
14228 +       while(parent->d_parent != parent){
14229 +               if(is_pid(parent)){
14230 +                       seg_name = "pid";
14231 +                       seg_len = strlen("pid");
14232 +               }
14233 +               else {
14234 +                       seg_name = parent->d_name.name;
14235 +                       seg_len = parent->d_name.len;
14236 +               }
14237 +
14238 +               len -= seg_len + 1;
14239 +               name[len] = '/';
14240 +               strncpy(&name[len + 1], seg_name, seg_len);
14241 +               parent = parent->d_parent;
14242 +       }
14243 +       strncpy(name, root, strlen(root));
14244 +       return(name);
14245 +}
14246 +
14247 +struct dentry_operations hppfs_dentry_ops = {
14248 +};
14249 +
14250 +static int file_removed(struct dentry *dentry, const char *file)
14251 +{
14252 +       char *host_file;
14253 +       int extra, fd;
14254 +
14255 +       extra = 0;
14256 +       if(file != NULL) extra += strlen(file) + 1;
14257 +
14258 +       host_file = dentry_name(dentry, extra + strlen("/remove"));
14259 +       if(host_file == NULL){
14260 +               printk("file_removed : allocation failed\n");
14261 +               return(-ENOMEM);
14262 +       }
14263 +
14264 +       if(file != NULL){
14265 +               strcat(host_file, "/");
14266 +               strcat(host_file, file);
14267 +       }
14268 +       strcat(host_file, "/remove");
14269 +
14270 +       fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
14271 +       kfree(host_file);
14272 +       if(fd > 0){
14273 +               os_close_file(fd);
14274 +               return(1);
14275 +       }
14276 +       return(0);
14277 +}
14278 +
14279 +static void hppfs_read_inode(struct inode *ino)
14280 +{
14281 +       struct inode *proc_ino;
14282 +
14283 +       if(HPPFS_I(ino)->proc_dentry == NULL)
14284 +               return;
14285 +
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;
14298 +}
14299 +
14300 +static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, 
14301 +                                  struct nameidata *nd)
14302 +{
14303 +       struct dentry *proc_dentry, *new, *parent;
14304 +       struct inode *inode;
14305 +       int err, deleted;
14306 +
14307 +       deleted = file_removed(dentry, NULL);
14308 +       if(deleted < 0)
14309 +               return(ERR_PTR(deleted));
14310 +       else if(deleted)
14311 +               return(ERR_PTR(-ENOENT));
14312 +
14313 +       err = -ENOMEM;
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);
14321 +                       goto out;
14322 +               }
14323 +               new = (*parent->d_inode->i_op->lookup)(parent->d_inode, 
14324 +                                                      proc_dentry, NULL);
14325 +               if(new){
14326 +                       dput(proc_dentry);
14327 +                       proc_dentry = new;
14328 +               }
14329 +       }
14330 +       up(&parent->d_inode->i_sem);
14331 +
14332 +       if(IS_ERR(proc_dentry))
14333 +               return(proc_dentry);
14334 +
14335 +       inode = iget(ino->i_sb, 0);
14336 +       if(inode == NULL) 
14337 +               goto out_dput;
14338 +
14339 +       err = init_inode(inode, proc_dentry);
14340 +       if(err) 
14341 +               goto out_put;
14342 +       
14343 +       hppfs_read_inode(inode);
14344 +
14345 +       d_add(dentry, inode);
14346 +       dentry->d_op = &hppfs_dentry_ops;
14347 +       return(NULL);
14348 +
14349 + out_put:
14350 +       iput(inode);
14351 + out_dput:
14352 +       dput(proc_dentry);
14353 + out:
14354 +       return(ERR_PTR(err));
14355 +}
14356 +
14357 +static struct inode_operations hppfs_file_iops = {
14358 +};
14359 +
14360 +static ssize_t read_proc(struct file *file, char *buf, ssize_t count, 
14361 +                        loff_t *ppos, int is_user)
14362 +{
14363 +       ssize_t (*read)(struct file *, char *, size_t, loff_t *);
14364 +       ssize_t n;
14365 +
14366 +       read = file->f_dentry->d_inode->i_fop->read;
14367 +
14368 +       if(!is_user)
14369 +               set_fs(KERNEL_DS);
14370 +               
14371 +       n = (*read)(file, buf, count, &file->f_pos);
14372 +
14373 +       if(!is_user)
14374 +               set_fs(USER_DS);
14375 +
14376 +       if(ppos) *ppos = file->f_pos;
14377 +       return(n);
14378 +}
14379 +
14380 +static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
14381 +{
14382 +       ssize_t n;
14383 +       int cur, err;
14384 +       char *new_buf;
14385 +
14386 +       n = -ENOMEM;
14387 +       new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
14388 +       if(new_buf == NULL){
14389 +               printk("hppfs_read_file : kmalloc failed\n");
14390 +               goto out;
14391 +       }
14392 +       n = 0;
14393 +       while(count > 0){
14394 +               cur = min_t(ssize_t, count, PAGE_SIZE);
14395 +               err = os_read_file(fd, new_buf, cur);
14396 +               if(err < 0){
14397 +                       printk("hppfs_read : read failed, errno = %d\n",
14398 +                              count);
14399 +                       n = err;
14400 +                       goto out_free;
14401 +               }
14402 +               else if(err == 0)
14403 +                       break;
14404 +
14405 +               if(copy_to_user(buf, new_buf, err)){
14406 +                       n = -EFAULT;
14407 +                       goto out_free;
14408 +               }
14409 +               n += err;
14410 +               count -= err;
14411 +       }
14412 + out_free:
14413 +       kfree(new_buf);
14414 + out:
14415 +       return(n);
14416 +}
14417 +
14418 +static ssize_t hppfs_read(struct file *file, char *buf, size_t count, 
14419 +                         loff_t *ppos)
14420 +{
14421 +       struct hppfs_private *hppfs = file->private_data;
14422 +       struct hppfs_data *data;
14423 +       loff_t off;
14424 +       int err;
14425 +
14426 +       if(hppfs->contents != NULL){
14427 +               if(*ppos >= hppfs->len) return(0);
14428 +
14429 +               data = hppfs->contents;
14430 +               off = *ppos;
14431 +               while(off >= sizeof(data->contents)){
14432 +                       data = list_entry(data->list.next, struct hppfs_data,
14433 +                                         list);
14434 +                       off -= sizeof(data->contents);
14435 +               }
14436 +
14437 +               if(off + count > hppfs->len)
14438 +                       count = hppfs->len - off;
14439 +               copy_to_user(buf, &data->contents[off], count);
14440 +               *ppos += count;
14441 +       }
14442 +       else if(hppfs->host_fd != -1){
14443 +               err = os_seek_file(hppfs->host_fd, *ppos);
14444 +               if(err){
14445 +                       printk("hppfs_read : seek failed, errno = %d\n", err);
14446 +                       return(err);
14447 +               }
14448 +               count = hppfs_read_file(hppfs->host_fd, buf, count);
14449 +               if(count > 0)
14450 +                       *ppos += count;
14451 +       }
14452 +       else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1);
14453 +
14454 +       return(count);
14455 +}
14456 +
14457 +static ssize_t hppfs_write(struct file *file, const char *buf, size_t len, 
14458 +                          loff_t *ppos)
14459 +{
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 *);
14463 +       int err;
14464 +
14465 +       write = proc_file->f_dentry->d_inode->i_fop->write;
14466 +
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;
14470 +
14471 +       return(err);
14472 +}
14473 +
14474 +static int open_host_sock(char *host_file, int *filter_out)
14475 +{
14476 +       char *end;
14477 +       int fd;
14478 +
14479 +       end = &host_file[strlen(host_file)];
14480 +       strcpy(end, "/rw");
14481 +       *filter_out = 1;
14482 +       fd = os_connect_socket(host_file);
14483 +       if(fd > 0)
14484 +               return(fd);
14485 +
14486 +       strcpy(end, "/r");
14487 +       *filter_out = 0;
14488 +       fd = os_connect_socket(host_file);
14489 +       return(fd);
14490 +}
14491 +
14492 +static void free_contents(struct hppfs_data *head)
14493 +{
14494 +       struct hppfs_data *data;
14495 +       struct list_head *ele, *next;
14496 +
14497 +       if(head == NULL) return;
14498 +
14499 +       list_for_each_safe(ele, next, &head->list){
14500 +               data = list_entry(ele, struct hppfs_data, list);
14501 +               kfree(data);
14502 +       }
14503 +       kfree(head);
14504 +}
14505 +
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)
14510 +{
14511 +       struct hppfs_data *data, *new, *head;
14512 +       int n, err;
14513 +
14514 +       err = -ENOMEM;
14515 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
14516 +       if(data == NULL){
14517 +               printk("hppfs_get_data : head allocation failed\n");
14518 +               goto failed;
14519 +       }
14520 +
14521 +       INIT_LIST_HEAD(&data->list);
14522 +
14523 +       head = data;
14524 +       *size_out = 0;
14525 +
14526 +       if(filter){
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);
14531 +               if(err){
14532 +                       printk("hppfs_get_data : failed to shut down "
14533 +                              "socket\n");
14534 +                       goto failed_free;
14535 +               }
14536 +       }
14537 +       while(1){
14538 +               n = os_read_file(fd, data->contents, sizeof(data->contents));
14539 +               if(n < 0){
14540 +                       err = n;
14541 +                       printk("hppfs_get_data : read failed, errno = %d\n",
14542 +                              err);
14543 +                       goto failed_free;
14544 +               }
14545 +               else if(n == 0)
14546 +                       break;
14547 +
14548 +               *size_out += n;
14549 +
14550 +               if(n < sizeof(data->contents))
14551 +                       break;
14552 +
14553 +               new = kmalloc(sizeof(*data), GFP_KERNEL);
14554 +               if(new == 0){
14555 +                       printk("hppfs_get_data : data allocation failed\n");
14556 +                       err = -ENOMEM;
14557 +                       goto failed_free;
14558 +               }
14559 +       
14560 +               INIT_LIST_HEAD(&new->list);
14561 +               list_add(&new->list, &data->list);
14562 +               data = new;
14563 +       }
14564 +       return(head);
14565 +
14566 + failed_free:
14567 +       free_contents(head);
14568 + failed:               
14569 +       return(ERR_PTR(err));
14570 +}
14571 +
14572 +static struct hppfs_private *hppfs_data(void)
14573 +{
14574 +       struct hppfs_private *data;
14575 +
14576 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
14577 +       if(data == NULL)
14578 +               return(data);
14579 +
14580 +       *data = ((struct hppfs_private ) { .host_fd             = -1,
14581 +                                          .len                 = -1,
14582 +                                          .contents            = NULL } );
14583 +       return(data);
14584 +}
14585 +
14586 +static int file_mode(int fmode)
14587 +{
14588 +       if(fmode == (FMODE_READ | FMODE_WRITE))
14589 +               return(O_RDWR);
14590 +       if(fmode == FMODE_READ)
14591 +               return(O_RDONLY);
14592 +       if(fmode == FMODE_WRITE)
14593 +               return(O_WRONLY);
14594 +       return(0);
14595 +}
14596 +
14597 +static int hppfs_open(struct inode *inode, struct file *file)
14598 +{
14599 +       struct hppfs_private *data;
14600 +       struct dentry *proc_dentry;
14601 +       char *host_file;
14602 +       int err, fd, type, filter;
14603 +
14604 +       err = -ENOMEM;
14605 +       data = hppfs_data();
14606 +       if(data == NULL)
14607 +               goto out;
14608 +
14609 +       host_file = dentry_name(file->f_dentry, strlen("/rw"));
14610 +       if(host_file == NULL)
14611 +               goto out_free2;
14612 +
14613 +       proc_dentry = HPPFS_I(inode)->proc_dentry;
14614 +
14615 +       /* XXX This isn't closed anywhere */
14616 +       err = open_private_file(&data->proc_file, proc_dentry, 
14617 +                               file_mode(file->f_mode));
14618 +       if(err)
14619 +               goto out_free1;
14620 +
14621 +       type = os_file_type(host_file);
14622 +       if(type == OS_TYPE_FILE){
14623 +               fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
14624 +               if(fd >= 0) 
14625 +                       data->host_fd = fd;
14626 +               else printk("hppfs_open : failed to open '%s', errno = %d\n",
14627 +                           host_file, -fd);
14628 +
14629 +               data->contents = NULL;
14630 +       }
14631 +       else if(type == OS_TYPE_DIR){
14632 +               fd = open_host_sock(host_file, &filter);
14633 +               if(fd > 0){
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;
14639 +               }
14640 +               else printk("hppfs_open : failed to open a socket in "
14641 +                           "'%s', errno = %d\n", host_file, -fd);
14642 +       }
14643 +       kfree(host_file);
14644 +
14645 +       file->private_data = data;
14646 +       return(0);
14647 +
14648 + out_free1:
14649 +       kfree(host_file);
14650 + out_free2:
14651 +       free_contents(data->contents);
14652 +       kfree(data);
14653 + out:
14654 +       return(err);
14655 +}
14656 +
14657 +static int hppfs_dir_open(struct inode *inode, struct file *file)
14658 +{
14659 +       struct hppfs_private *data;
14660 +       struct dentry *proc_dentry;
14661 +       int err;
14662 +
14663 +       err = -ENOMEM;
14664 +       data = hppfs_data();
14665 +       if(data == NULL)
14666 +               goto out;
14667 +
14668 +       proc_dentry = HPPFS_I(inode)->proc_dentry;
14669 +       err = open_private_file(&data->proc_file, proc_dentry, 
14670 +                               file_mode(file->f_mode));
14671 +       if(err)
14672 +               goto out_free;
14673 +
14674 +       file->private_data = data;
14675 +       return(0);
14676 +
14677 + out_free:
14678 +       kfree(data);
14679 + out:
14680 +       return(err);
14681 +}
14682 +
14683 +static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
14684 +{
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);
14688 +       loff_t ret;
14689 +
14690 +       llseek = proc_file->f_dentry->d_inode->i_fop->llseek;
14691 +       if(llseek != NULL){
14692 +               ret = (*llseek)(proc_file, off, where);
14693 +               if(ret < 0)
14694 +                       return(ret);
14695 +       }
14696 +
14697 +       return(default_llseek(file, off, where));
14698 +}
14699 +
14700 +static struct file_operations hppfs_file_fops = {
14701 +       .owner          = NULL,
14702 +       .llseek         = hppfs_llseek,
14703 +       .read           = hppfs_read,
14704 +       .write          = hppfs_write,
14705 +       .open           = hppfs_open,
14706 +};
14707 +
14708 +struct hppfs_dirent {
14709 +       void *vfs_dirent;
14710 +       filldir_t filldir;
14711 +       struct dentry *dentry;
14712 +};
14713 +
14714 +static int hppfs_filldir(void *d, const char *name, int size, 
14715 +                        loff_t offset, ino_t inode, unsigned int type)
14716 +{
14717 +       struct hppfs_dirent *dirent = d;
14718 +
14719 +       if(file_removed(dirent->dentry, name))
14720 +               return(0);
14721 +
14722 +       return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset, 
14723 +                                 inode, type));
14724 +}
14725 +
14726 +static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
14727 +{
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 } );
14735 +       int err;
14736 +
14737 +       readdir = proc_file->f_dentry->d_inode->i_fop->readdir;
14738 +
14739 +       proc_file->f_pos = file->f_pos;
14740 +       err = (*readdir)(proc_file, &dirent, hppfs_filldir);
14741 +       file->f_pos = proc_file->f_pos;
14742 +
14743 +       return(err);
14744 +}
14745 +
14746 +static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
14747 +{
14748 +       return(0);
14749 +}
14750 +
14751 +static struct file_operations hppfs_dir_fops = {
14752 +       .owner          = NULL,
14753 +       .readdir        = hppfs_readdir,
14754 +       .open           = hppfs_dir_open,
14755 +       .fsync          = hppfs_fsync,
14756 +};
14757 +
14758 +static int hppfs_statfs(struct super_block *sb, struct kstatfs *sf)
14759 +{
14760 +       sf->f_blocks = 0;
14761 +       sf->f_bfree = 0;
14762 +       sf->f_bavail = 0;
14763 +       sf->f_files = 0;
14764 +       sf->f_ffree = 0;
14765 +       sf->f_type = HPPFS_SUPER_MAGIC;
14766 +       return(0);
14767 +}
14768 +
14769 +static struct inode *hppfs_alloc_inode(struct super_block *sb)
14770 +{
14771 +       struct hppfs_inode_info *hi;
14772 +
14773 +       hi = kmalloc(sizeof(*hi), GFP_KERNEL);
14774 +       if(hi == NULL) 
14775 +               return(NULL);
14776 +
14777 +       *hi = ((struct hppfs_inode_info) { .proc_dentry = NULL });
14778 +       inode_init_once(&hi->vfs_inode);
14779 +       return(&hi->vfs_inode);
14780 +}
14781 +
14782 +void hppfs_delete_inode(struct inode *ino)
14783 +{
14784 +       clear_inode(ino);
14785 +}
14786 +
14787 +static void hppfs_destroy_inode(struct inode *inode)
14788 +{
14789 +       kfree(HPPFS_I(inode));
14790 +}
14791 +
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,
14798 +};
14799 +
14800 +static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen)
14801 +{
14802 +       struct file proc_file;
14803 +       struct dentry *proc_dentry;
14804 +       int (*readlink)(struct dentry *, char *, int);
14805 +       int err, n;
14806 +
14807 +       proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
14808 +       err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
14809 +       if(err) 
14810 +               return(err);
14811 +
14812 +       readlink = proc_dentry->d_inode->i_op->readlink;
14813 +       n = (*readlink)(proc_dentry, buffer, buflen);
14814 +
14815 +       close_private_file(&proc_file);
14816 +       
14817 +       return(n);
14818 +}
14819 +
14820 +static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
14821 +{
14822 +       struct file proc_file;
14823 +       struct dentry *proc_dentry;
14824 +       int (*follow_link)(struct dentry *, struct nameidata *);
14825 +       int err, n;
14826 +
14827 +       proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
14828 +       err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
14829 +       if(err) 
14830 +               return(err);
14831 +
14832 +       follow_link = proc_dentry->d_inode->i_op->follow_link;
14833 +       n = (*follow_link)(proc_dentry, nd);
14834 +
14835 +       close_private_file(&proc_file);
14836 +       
14837 +       return(n);
14838 +}
14839 +
14840 +static struct inode_operations hppfs_dir_iops = {
14841 +       .lookup         = hppfs_lookup,
14842 +};
14843 +
14844 +static struct inode_operations hppfs_link_iops = {
14845 +       .readlink       = hppfs_readlink,
14846 +       .follow_link    = hppfs_follow_link,
14847 +};
14848 +
14849 +static int init_inode(struct inode *inode, struct dentry *dentry)
14850 +{
14851 +       if(S_ISDIR(dentry->d_inode->i_mode)){
14852 +               inode->i_op = &hppfs_dir_iops;
14853 +               inode->i_fop = &hppfs_dir_fops;
14854 +       }
14855 +       else if(S_ISLNK(dentry->d_inode->i_mode)){
14856 +               inode->i_op = &hppfs_link_iops;
14857 +               inode->i_fop = &hppfs_file_fops;
14858 +       }
14859 +       else {
14860 +               inode->i_op = &hppfs_file_iops;
14861 +               inode->i_fop = &hppfs_file_fops;
14862 +       }
14863 +
14864 +       HPPFS_I(inode)->proc_dentry = dentry;
14865 +
14866 +       return(0);
14867 +}
14868 +
14869 +static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
14870 +{
14871 +       struct inode *root_inode;
14872 +       struct file_system_type *procfs;
14873 +       struct super_block *proc_sb;
14874 +       int err;
14875 +
14876 +       err = -ENOENT;
14877 +       procfs = get_fs_type("proc");
14878 +       if(procfs == NULL) 
14879 +               goto out;
14880 +
14881 +       if(list_empty(&procfs->fs_supers))
14882 +               goto out;
14883 +
14884 +       proc_sb = list_entry(procfs->fs_supers.next, struct super_block,
14885 +                            s_instances);
14886 +       
14887 +       sb->s_blocksize = 1024;
14888 +       sb->s_blocksize_bits = 10;
14889 +       sb->s_magic = HPPFS_SUPER_MAGIC;
14890 +       sb->s_op = &hppfs_sbops;
14891 +
14892 +       root_inode = iget(sb, 0);
14893 +       if(root_inode == NULL)
14894 +               goto out;
14895 +
14896 +       err = init_inode(root_inode, proc_sb->s_root);
14897 +       if(err)
14898 +               goto out_put;
14899 +
14900 +       err = -ENOMEM;
14901 +       sb->s_root = d_alloc_root(root_inode);
14902 +       if(sb->s_root == NULL)
14903 +               goto out_put;
14904 +
14905 +       hppfs_read_inode(root_inode);
14906 +
14907 +       return(0);
14908 +
14909 + out_put:
14910 +       iput(root_inode);
14911 + out:
14912 +       return(err);
14913 +}
14914 +
14915 +static struct super_block *hppfs_read_super(struct file_system_type *type,
14916 +                                            int flags, const char *dev_name,
14917 +                                            void *data)
14918 +{
14919 +       return(get_sb_nodev(type, flags, data, hppfs_fill_super));
14920 +}
14921 +
14922 +static struct file_system_type hppfs_type = {
14923 +       .owner          = THIS_MODULE,
14924 +       .name           = "hppfs",
14925 +       .get_sb         = hppfs_read_super,
14926 +       .kill_sb        = kill_anon_super,
14927 +       .fs_flags       = 0,
14928 +};
14929 +
14930 +static int __init init_hppfs(void)
14931 +{
14932 +       return(register_filesystem(&hppfs_type));
14933 +}
14934 +
14935 +static void __exit exit_hppfs(void)
14936 +{
14937 +       unregister_filesystem(&hppfs_type);
14938 +}
14939 +
14940 +module_init(init_hppfs)
14941 +module_exit(exit_hppfs)
14942 +MODULE_LICENSE("GPL");
14943 +
14944 +/*
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
14948 + * of the file.
14949 + * ---------------------------------------------------------------------------
14950 + * Local variables:
14951 + * c-file-style: "linux"
14952 + * End:
14953 + */
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
14958 @@ -10,6 +10,7 @@
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"
14965  #include "line.h"
14966 @@ -53,8 +54,9 @@
14967  
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,
14975         .minor_start            = 64,
14976         .type                   = TTY_DRIVER_TYPE_SERIAL,
14977         .subtype                = 0,
14978 @@ -149,6 +151,9 @@
14979         case TCSETSW:
14980         case TCGETA:
14981         case TIOCMGET:
14982 +       case TCSBRK:
14983 +       case TCSBRKP:
14984 +       case TIOCMSET:
14985                 ret = -ENOIOCTLCMD;
14986                 break;
14987         default:
14988 @@ -212,6 +217,37 @@
14989   */
14990  static int ssl_init_done = 0;
14991  
14992 +static void ssl_console_write(struct console *c, const char *string, 
14993 +                             unsigned len)
14994 +{
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)
15000 +               up(&line->sem);
15001 +}
15002 +
15003 +static struct tty_driver *ssl_console_device(struct console *c, int *index)
15004 +{
15005 +       *index = c->index;
15006 +       return ssl_driver;
15007 +}
15008 +
15009 +static int ssl_console_setup(struct console *co, char *options)
15010 +{
15011 +       return(0);
15012 +}
15013 +
15014 +static struct console ssl_cons = {
15015 +       name:           "ttyS",
15016 +       write:          ssl_console_write,
15017 +       device:         ssl_console_device,
15018 +       setup:          ssl_console_setup,
15019 +       flags:          CON_PRINTBUFFER,
15020 +       index:          -1,
15021 +};
15022 +
15023  int ssl_init(void)
15024  {
15025         char *new_title;
15026 @@ -227,17 +263,18 @@
15027         new_title = add_xterm_umid(opts.xterm_title);
15028         if(new_title != NULL) opts.xterm_title = new_title;
15029  
15030 +       register_console(&ssl_cons);
15031         ssl_init_done = 1;
15032         return(0);
15033  }
15034  
15035 -__initcall(ssl_init);
15036 +late_initcall(ssl_init);
15037  
15038  static int ssl_chan_setup(char *str)
15039  {
15040 -       line_setup(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]),
15041 -                  str, 1);
15042 -       return(1);
15043 +       return(line_setup(serial_lines, 
15044 +                         sizeof(serial_lines)/sizeof(serial_lines[0]), 
15045 +                         str, 1));
15046  }
15047  
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
15053 @@ -1,5 +1,5 @@
15054  # 
15055 -# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15056 +# Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
15057  # Licensed under the GPL
15058  #
15059  
15060 @@ -7,7 +7,7 @@
15061  
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)/
15066  
15067  obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/
15068  
15069 @@ -27,5 +27,3 @@
15070  
15071  $(obj)/unmap_fin.o : $(src)/unmap.o
15072         ld -r -o $@ $< -lc -L/usr/lib
15073 -
15074 -clean :
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
15079 @@ -91,3 +91,5 @@
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
15089 @@ -10,6 +10,7 @@
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"
15096  #include "os.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
15101 @@ -15,6 +15,7 @@
15102  #ifdef CONFIG_SMP
15103  static void kill_idlers(int me)
15104  {
15105 +#ifdef CONFIG_MODE_TT
15106         struct task_struct *p;
15107         int i;
15108  
15109 @@ -23,6 +24,7 @@
15110                 if((p != NULL) && (p->thread.mode.tt.extern_pid != me))
15111                         os_kill_process(p->thread.mode.tt.extern_pid, 0);
15112         }
15113 +#endif
15114  }
15115  #endif
15116  
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
15121 @@ -24,11 +24,6 @@
15122  { 
15123  }
15124  
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);
15129 -
15130  int sys_ptrace(long request, long pid, long addr, long data)
15131  {
15132         struct task_struct *child;
15133 @@ -302,8 +297,17 @@
15134         return ret;
15135  }
15136  
15137 -void syscall_trace(void)
15138 +void syscall_trace(union uml_pt_regs *regs, int entryexit)
15139  {
15140 +       if (unlikely(current->audit_context)) {
15141 +               if (!entryexit)
15142 +                       audit_syscall_entry(current, regs->orig_eax,
15143 +                                           regs->ebx, regs->ecx,
15144 +                                           regs->edx, regs->esi);
15145 +               else
15146 +                       audit_syscall_exit(current, regs->eax);
15147 +       }
15148 +
15149         if (!test_thread_flag(TIF_SYSCALL_TRACE))
15150                 return;
15151         if (!(current->ptrace & PT_PTRACED))
15152 @@ -311,11 +315,8 @@
15153  
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)
15157 -                                       ? 0x80 : 0);
15158 -       current->state = TASK_STOPPED;
15159 -       notify_parent(current, SIGCHLD);
15160 -       schedule();
15161 +       ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
15162 +                                ? 0x80 : 0));
15163  
15164         /*
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 @@
15171                                 from, n));
15172  }
15173  
15174 +/*
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.
15180 + * 
15181 + * Copies a NUL-terminated string from userspace to kernel space.
15182 + *
15183 + * On success, returns the length of the string (not including the trailing
15184 + * NUL).
15185 + *
15186 + * If access to userspace fails, returns -EFAULT (some data may have been
15187 + * copied).
15188 + *
15189 + * If @count is smaller than the length of the string, copies @count bytes
15190 + * and returns @count.
15191 + */
15192 +
15193  static inline int strncpy_from_user(char *dst, const char *src, int count)
15194  {
15195         return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas,
15196                                 dst, src, count));
15197  }
15198  
15199 +/*
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.
15203 + *
15204 + * Zero a block of memory in user space.  Caller must check
15205 + * the specified block with access_ok() before calling this function.
15206 + *
15207 + * Returns number of bytes that could not be cleared.
15208 + * On success, this will be zero.
15209 + */
15210  static inline int __clear_user(void *mem, int len)
15211  {
15212         return(CHOOSE_MODE_PROC(__clear_user_tt, __clear_user_skas, mem, len));
15213  }
15214  
15215 +/*
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.
15219 + *
15220 + * Zero a block of memory in user space.
15221 + *
15222 + * Returns number of bytes that could not be cleared.
15223 + * On success, this will be zero.
15224 + */
15225  static inline int clear_user(void *mem, int len)
15226  {
15227         return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len));
15228  }
15229  
15230 +/*
15231 + * strlen_user: - Get the size of a string in user space.
15232 + * @str: The string to measure.
15233 + * @n:   The maximum valid length
15234 + *
15235 + * Get the size of a NUL-terminated string in user space.
15236 + *
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.
15240 + */
15241  static inline int strnlen_user(const void *str, int len)
15242  {
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
15248 @@ -16,8 +16,10 @@
15249  #define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & \
15250                                 (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
15251  
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)); })
15256 +
15257 +#define current (current_thread->task)
15258  
15259  #endif /* __ASSEMBLY__ */
15260  
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
15265 @@ -4,20 +4,21 @@
15266   */
15267  
15268  #include <unistd.h>
15269 -#include <fcntl.h>
15270  #include <errno.h>
15271  #include <string.h>
15272  #include <sys/signal.h>
15273 +#include <asm/ldt.h>
15274  #include "kern_util.h"
15275  #include "user.h"
15276  #include "sysdep/ptrace.h"
15277  #include "task.h"
15278 +#include "os.h"
15279  
15280  #define MAXTOKEN 64
15281  
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;
15287  
15288  static char token(int fd, char *buf, int len, char stop)
15289  {
15290 @@ -27,13 +28,15 @@
15291         ptr = buf;
15292         end = &buf[len];
15293         do {
15294 -               n = read(fd, ptr, sizeof(*ptr));
15295 +               n = os_read_file(fd, ptr, sizeof(*ptr));
15296                 c = *ptr++;
15297 -               if(n == 0) return(0);
15298 -               else if(n != sizeof(*ptr)){
15299 -                       printk("Reading /proc/cpuinfo failed, "
15300 -                              "errno = %d\n", errno);
15301 -                       return(-errno);
15302 +               if(n != sizeof(*ptr)){
15303 +                       if(n == 0) return(0);
15304 +                       printk("Reading /proc/cpuinfo failed, err = %d\n", -n);
15305 +                       if(n < 0) 
15306 +                               return(n);
15307 +                       else 
15308 +                               return(-EIO);
15309                 }
15310         } while((c != '\n') && (c != stop) && (ptr < end));
15311  
15312 @@ -45,45 +48,79 @@
15313         return(c);
15314  }
15315  
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)
15318  {
15319 -       char buf[MAXTOKEN], c;
15320 -       int fd, len = sizeof(buf)/sizeof(buf[0]), n;
15321 -
15322 -       printk("Checking for host processor %s support...", feature);
15323 -       fd = open("/proc/cpuinfo", O_RDONLY);
15324 -       if(fd < 0){
15325 -               printk("Couldn't open /proc/cpuinfo, errno = %d\n", errno);
15326 -               return(0);
15327 -       }
15328 +       int n;
15329 +       char c;
15330  
15331 -       *have_it = 0;
15332 -       buf[len - 1] = '\0';
15333 +       scratch[len - 1] = '\0';
15334         while(1){
15335 -               c = token(fd, buf, len - 1, ':');
15336 -               if(c <= 0) goto out;
15337 +               c = token(fd, scratch, len - 1, ':');
15338 +               if(c <= 0)
15339 +                       return(0);
15340                 else if(c != ':'){
15341                         printk("Failed to find ':' in /proc/cpuinfo\n");
15342 -                       goto out;
15343 +                       return(0);
15344                 }
15345  
15346 -               if(!strncmp(buf, "flags", strlen("flags"))) break;
15347 +               if(!strncmp(scratch, key, strlen(key))) 
15348 +                       return(1);
15349  
15350                 do {
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",
15356 -                                      n, errno);
15357 -                               goto out;
15358 +                                      "/proc/cpuinfo, err = %d\n", -n);
15359 +                               return(0);
15360                         }
15361                 } while(c != '\n');
15362         }
15363 +       return(0);
15364 +}
15365 +
15366 +int cpu_feature(char *what, char *buf, int len)
15367 +{
15368 +       int fd, ret = 0;
15369 +
15370 +       fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
15371 +       if(fd < 0){
15372 +               printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
15373 +               return(0);
15374 +       }
15375 +
15376 +       if(!find_cpuinfo_line(fd, what, buf, len)){
15377 +               printk("Couldn't find '%s' line in /proc/cpuinfo\n", what);
15378 +               goto out_close;
15379 +       }
15380 +
15381 +       token(fd, buf, len, '\n');
15382 +       ret = 1;
15383 +
15384 + out_close:
15385 +       os_close_file(fd);
15386 +       return(ret);
15387 +}
15388 +
15389 +static int check_cpu_flag(char *feature, int *have_it)
15390 +{
15391 +       char buf[MAXTOKEN], c;
15392 +       int fd, len = sizeof(buf)/sizeof(buf[0]);
15393 +
15394 +       printk("Checking for host processor %s support...", feature);
15395 +       fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
15396 +       if(fd < 0){
15397 +               printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
15398 +               return(0);
15399 +       }
15400 +
15401 +       *have_it = 0;
15402 +       if(!find_cpuinfo_line(fd, "flags", buf, sizeof(buf) / sizeof(buf[0])))
15403 +               goto out;
15404  
15405         c = token(fd, buf, len - 1, ' ');
15406         if(c < 0) goto out;
15407         else if(c != ' '){
15408 -               printk("Failed to find ':' in /proc/cpuinfo\n");
15409 +               printk("Failed to find ' ' in /proc/cpuinfo\n");
15410                 goto out;
15411         }
15412  
15413 @@ -100,21 +137,48 @@
15414   out:
15415         if(*have_it == 0) printk("No\n");
15416         else if(*have_it == 1) printk("Yes\n");
15417 -       close(fd);
15418 +       os_close_file(fd);
15419         return(1);
15420  }
15421  
15422 +#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems
15423 +       * for some people.
15424 +       */
15425 +static void disable_lcall(void)
15426 +{
15427 +       struct modify_ldt_ldt_s ldt;
15428 +       int err;
15429 +
15430 +       bzero(&ldt, sizeof(ldt));
15431 +       ldt.entry_number = 7;
15432 +       ldt.base_addr = 0;
15433 +       ldt.limit = 0;
15434 +       err = modify_ldt(1, &ldt, sizeof(ldt));
15435 +       if(err)
15436 +               printk("Failed to disable lcall7 - errno = %d\n", errno);
15437 +}
15438 +#endif
15439 +
15440 +void arch_init_thread(void)
15441 +{
15442 +#if 0
15443 +       disable_lcall();
15444 +#endif
15445 +}
15446 +
15447  void arch_check_bugs(void)
15448  {
15449         int have_it;
15450  
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 "
15454                        "checks\n");
15455                 return;
15456         }
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;
15463  }
15464  
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))
15468                 return(0);
15469  
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 "
15474                       "processors");
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 "
15478                       "implement");
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 "
15483                       "processors");
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);
15486         return(0);
15487  }
15488  
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;
15495  
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, 
15500 +                                 void *from_ptr);
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);
15509  
15510  #endif
15511  
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
15516 @@ -28,8 +28,8 @@
15517   */
15518  #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
15519  
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)
15524  
15525  #define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
15526  
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
15531 @@ -26,8 +26,7 @@
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", 
15536 -                      gate_addr);
15537 +               printk("Invalid tap IP address - '%s'\n", gate_addr);
15538                 return(-EINVAL);
15539         }
15540         return(0);
15541 @@ -60,18 +59,18 @@
15542         }
15543                 
15544         *output = '\0';
15545 -       if(read(fd, &remain, sizeof(remain)) != sizeof(remain)){
15546 -               printk("read_output - read of length failed, errno = %d\n",
15547 -                      errno);
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);
15551                 return;
15552         }
15553  
15554         while(remain != 0){
15555                 n = (remain < len) ? remain : len;
15556 -               actual = read(fd, output, n);
15557 +               actual = os_read_file(fd, output, n);
15558                 if(actual != n){
15559                         printk("read_output - read of data failed, "
15560 -                              "errno = %d\n", errno);
15561 +                              "err = %d\n", -actual);
15562                         return;
15563                 }
15564                 remain -= actual;
15565 @@ -83,13 +82,12 @@
15566  {
15567         int n;
15568  
15569 -       while(((n = read(fd,  buf,  len)) < 0) && (errno == EINTR)) ;
15570 +       n = os_read_file(fd,  buf,  len);
15571  
15572 -       if(n < 0){
15573 -               if(errno == EAGAIN) return(0);
15574 -               return(-errno);
15575 -       }
15576 -       else if(n == 0) return(-ENOTCONN);
15577 +       if(n == -EAGAIN) 
15578 +               return(0);
15579 +       else if(n == 0) 
15580 +               return(-ENOTCONN);
15581         return(n);
15582  }
15583  
15584 @@ -112,13 +110,13 @@
15585  {
15586         int n;
15587  
15588 -       while(((n = write(fd, buf, len)) < 0) && (errno == EINTR)) ;
15589 -       if(n < 0){
15590 -               if(errno == EAGAIN) return(0);
15591 -               return(-errno);
15592 -       }
15593 -       else if(n == 0) return(-ENOTCONN);
15594 -       return(n);      
15595 +       n = os_write_file(fd, buf, len);
15596 +
15597 +       if(n == -EAGAIN) 
15598 +               return(0);
15599 +       else if(n == 0) 
15600 +               return(-ENOTCONN);
15601 +       return(n);
15602  }
15603  
15604  int net_send(int fd, void *buf, int len)
15605 @@ -157,7 +155,7 @@
15606  {
15607         struct change_pre_exec_data *data = arg;
15608  
15609 -       close(data->close_me);
15610 +       os_close_file(data->close_me);
15611         dup2(data->stdout, 1);
15612  }
15613  
15614 @@ -167,17 +165,18 @@
15615         struct change_pre_exec_data pe_data;
15616  
15617         err = os_pipe(fds, 1, 0);
15618 -       if(err){
15619 -               printk("change_tramp - pipe failed, errno = %d\n", -err);
15620 +       if(err < 0){
15621 +               printk("change_tramp - pipe failed, err = %d\n", -err);
15622                 return(err);
15623         }
15624         pe_data.close_me = fds[0];
15625         pe_data.stdout = fds[1];
15626         pid = run_helper(change_pre_exec, &pe_data, argv, NULL);
15627  
15628 -       close(fds[1]);
15629 +       os_close_file(fds[1]);
15630         read_output(fds[0], output, output_len);
15631 -       waitpid(pid, NULL, 0);  
15632 +
15633 +       CATCH_EINTR(err = waitpid(pid, NULL, 0));
15634         return(pid);
15635  }
15636  
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;
15643  
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"
15649  
15650  struct mm_struct;
15651  
15652  #define current_text_addr() ((void *) 0)
15653  
15654 -#define cpu_relax()    do ; while (0)
15655 -
15656 -#ifdef CONFIG_MODE_TT
15657 -struct proc_tt_mode {
15658 -       int extern_pid;
15659 -       int tracing;
15660 -       int switch_pipe[2];
15661 -       int singlestep_syscall;
15662 -       int vm_seq;
15663 -};
15664 -#endif
15665 -
15666 -#ifdef CONFIG_MODE_SKAS
15667 -struct proc_skas_mode {
15668 -       void *switch_buf;
15669 -       void *fork_buf;
15670 -};
15671 -#endif
15672 +#define cpu_relax()   barrier()
15673  
15674  struct thread_struct {
15675         int forking;
15676 @@ -46,6 +27,7 @@
15677         struct pt_regs regs;
15678         unsigned long cr2;
15679         int err;
15680 +       unsigned long trap_no;
15681         void *fault_addr;
15682         void *fault_catcher;
15683         struct task_struct *prev_sched;
15684 @@ -54,10 +36,20 @@
15685         struct arch_thread arch;
15686         union {
15687  #ifdef CONFIG_MODE_TT
15688 -               struct proc_tt_mode tt;
15689 +               struct {
15690 +                       int extern_pid;
15691 +                       int tracing;
15692 +                       int switch_pipe[2];
15693 +                       int singlestep_syscall;
15694 +                       int vm_seq;
15695 +               } tt;
15696  #endif
15697  #ifdef CONFIG_MODE_SKAS
15698 -               struct proc_skas_mode skas;
15699 +               struct {
15700 +                       void *switch_buf;
15701 +                       void *fork_buf;
15702 +                       int mm_count;
15703 +               } skas;
15704  #endif
15705         } mode;
15706         struct {
15707 @@ -99,14 +91,19 @@
15708  } mm_segment_t;
15709  
15710  extern struct task_struct *alloc_task_struct(void);
15711 -extern void free_task_struct(struct task_struct *task);
15712  
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);
15717  
15718  extern unsigned long thread_saved_pc(struct task_struct *t);
15719  
15720 +static inline void mm_copy_segments(struct mm_struct *from_mm, 
15721 +                                   struct mm_struct *new_mm)
15722 +{
15723 +}
15724 +
15725  #define init_stack     (init_thread_union.stack)
15726  
15727  /*
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
15732 @@ -34,6 +34,7 @@
15733         FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
15734         FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
15735  #endif
15736 +       FIX_VSYSCALL,
15737         __end_of_fixed_addresses
15738  };
15739  
15740 @@ -63,6 +64,13 @@
15741  #define __fix_to_virt(x)       (FIXADDR_TOP - ((x) << PAGE_SHIFT))
15742  #define __virt_to_fix(x)      ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
15743  
15744 +/*
15745 + * This is the range that is readable by user mode, and things
15746 + * acting like user mode such as get_user_pages.
15747 + */
15748 +#define FIXADDR_USER_START     (__fix_to_virt(FIX_VSYSCALL))
15749 +#define FIXADDR_USER_END       (FIXADDR_USER_START + PAGE_SIZE)
15750 +
15751  extern void __this_fixmap_does_not_exist(void);
15752  
15753  /*
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
15758 @@ -8,7 +8,6 @@
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"
15765  #include "etap.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
15770 @@ -33,7 +33,7 @@
15771         SC_START_SYSCALL(sc);
15772  
15773         index = record_syscall_start(syscall);
15774 -       syscall_trace();
15775 +       syscall_trace(regs, 1);
15776         result = execute_syscall(regs);
15777  
15778         /* regs->sc may have changed while the system call ran (there may
15779 @@ -46,7 +46,7 @@
15780            (result == -ERESTARTNOINTR))
15781                 do_signal(result);
15782  
15783 -       syscall_trace();
15784 +       syscall_trace(regs, 0);
15785         record_syscall_end(index, result);
15786  }
15787  
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
15792 @@ -8,6 +8,13 @@
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.
15802 + * James McMechan
15803   */
15804  
15805  #define MAJOR_NR UBD_MAJOR
15806 @@ -40,9 +47,12 @@
15807  #include "mconsole_kern.h"
15808  #include "init.h"
15809  #include "irq_user.h"
15810 +#include "irq_kern.h"
15811  #include "ubd_user.h"
15812  #include "2_5compat.h"
15813  #include "os.h"
15814 +#include "mem.h"
15815 +#include "mem_kern.h"
15816  
15817  static spinlock_t ubd_io_lock = SPIN_LOCK_UNLOCKED;
15818  static spinlock_t ubd_lock = SPIN_LOCK_UNLOCKED;
15819 @@ -56,6 +66,10 @@
15820  
15821  #define MAX_DEV (8)
15822  
15823 +/* Changed in early boot */
15824 +static int ubd_do_mmap = 0;
15825 +#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE
15826 +
15827  static struct block_device_operations ubd_blops = {
15828          .owner         = THIS_MODULE,
15829          .open          = ubd_open,
15830 @@ -67,7 +81,7 @@
15831  static request_queue_t *ubd_queue;
15832  
15833  /* Protected by ubd_lock */
15834 -static int fake_major = 0;
15835 +static int fake_major = MAJOR_NR;
15836  
15837  static struct gendisk *ubd_gendisk[MAX_DEV];
15838  static struct gendisk *fake_gendisk[MAX_DEV];
15839 @@ -96,13 +110,19 @@
15840  
15841  struct ubd {
15842         char *file;
15843 -       int is_dir;
15844         int count;
15845         int fd;
15846         __u64 size;
15847         struct openflags boot_openflags;
15848         struct openflags openflags;
15849 +       int no_cow;
15850         struct cow cow;
15851 +
15852 +       int map_writes;
15853 +       int map_reads;
15854 +       int nomap_writes;
15855 +       int nomap_reads;
15856 +       int write_maps;
15857  };
15858  
15859  #define DEFAULT_COW { \
15860 @@ -115,21 +135,28 @@
15861  
15862  #define DEFAULT_UBD { \
15863         .file =                 NULL, \
15864 -       .is_dir =               0, \
15865         .count =                0, \
15866         .fd =                   -1, \
15867         .size =                 -1, \
15868         .boot_openflags =       OPEN_FLAGS, \
15869         .openflags =            OPEN_FLAGS, \
15870 +        .no_cow =               0, \
15871          .cow =                 DEFAULT_COW, \
15872 +       .map_writes             = 0, \
15873 +       .map_reads              = 0, \
15874 +       .nomap_writes           = 0, \
15875 +       .nomap_reads            = 0, \
15876 +       .write_maps             = 0, \
15877  }
15878  
15879  struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
15880  
15881  static int ubd0_init(void)
15882  {
15883 -       if(ubd_dev[0].file == NULL)
15884 -               ubd_dev[0].file = "root_fs";
15885 +       struct ubd *dev = &ubd_dev[0];
15886 +
15887 +       if(dev->file == NULL)
15888 +               dev->file = "root_fs";
15889         return(0);
15890  }
15891  
15892 @@ -196,19 +223,46 @@
15893  "    Create ide0 entries that map onto ubd devices.\n\n"
15894  );
15895  
15896 +static int parse_unit(char **ptr)
15897 +{
15898 +       char *str = *ptr, *end;
15899 +       int n = -1;
15900 +
15901 +       if(isdigit(*str)) {
15902 +               n = simple_strtoul(str, &end, 0);
15903 +               if(end == str)
15904 +                       return(-1);
15905 +               *ptr = end;
15906 +       }
15907 +       else if (('a' <= *str) && (*str <= 'h')) {
15908 +               n = *str - 'a';
15909 +               str++;
15910 +               *ptr = str;
15911 +       }
15912 +       return(n);
15913 +}
15914 +
15915  static int ubd_setup_common(char *str, int *index_out)
15916  {
15917 +       struct ubd *dev;
15918         struct openflags flags = global_openflags;
15919         char *backing_file;
15920         int n, err;
15921  
15922         if(index_out) *index_out = -1;
15923 -       n = *str++;
15924 +       n = *str;
15925         if(n == '='){
15926 -               static int fake_major_allowed = 1;
15927                 char *end;
15928                 int major;
15929  
15930 +               str++;
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);
15935 +                       return(0);
15936 +               }
15937 +
15938                 if(!strcmp(str, "sync")){
15939                         global_openflags.s = 1;
15940                         return(0);
15941 @@ -220,20 +274,14 @@
15942                         return(1);
15943                 }
15944  
15945 -               if(!fake_major_allowed){
15946 -                       printk(KERN_ERR "Can't assign a fake major twice\n");
15947 -                       return(1);
15948 -               }
15949 -
15950                 err = 1;
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");
15955                         goto out1;
15956                 }
15957   
15958                 fake_major = major;
15959 -               fake_major_allowed = 0;
15960  
15961                 printk(KERN_INFO "Setting extra ubd major number to %d\n",
15962                        major);
15963 @@ -243,25 +291,23 @@
15964                 return(err);
15965         }
15966  
15967 -       if(n < '0'){
15968 -               printk(KERN_ERR "ubd_setup : index out of range\n"); }
15969 -
15970 -       if((n >= '0') && (n <= '9')) n -= '0';
15971 -       else if((n >= 'a') && (n <= 'z')) n -= 'a';
15972 -       else {
15973 -               printk(KERN_ERR "ubd_setup : device syntax invalid\n");
15974 +       n = parse_unit(&str);
15975 +       if(n < 0){
15976 +               printk(KERN_ERR "ubd_setup : couldn't parse unit number "
15977 +                      "'%s'\n", str);
15978                 return(1);
15979         }
15980         if(n >= MAX_DEV){
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);
15985                 return(1);
15986         }
15987  
15988         err = 1;
15989         spin_lock(&ubd_lock);
15990  
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");
15995                 goto out2;
15996         }
15997 @@ -276,6 +322,11 @@
15998                 flags.s = 1;
15999                 str++;
16000         }
16001 +       if (*str == 'd'){
16002 +               dev->no_cow = 1;
16003 +               str++;
16004 +       }
16005 +
16006         if(*str++ != '='){
16007                 printk(KERN_ERR "ubd_setup : Expected '='\n");
16008                 goto out2;
16009 @@ -284,14 +335,17 @@
16010         err = 0;
16011         backing_file = strchr(str, ',');
16012         if(backing_file){
16013 -               *backing_file = '\0';
16014 -               backing_file++;
16015 +               if(dev->no_cow)
16016 +                       printk(KERN_ERR "Can't specify both 'd' and a "
16017 +                              "cow file\n");
16018 +               else {
16019 +                       *backing_file = '\0';
16020 +                       backing_file++;
16021 +               }
16022         }
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;
16028 +       dev->file = str;
16029 +       dev->cow.file = backing_file;
16030 +       dev->boot_openflags = flags;
16031   out2:
16032         spin_unlock(&ubd_lock);
16033         return(err);
16034 @@ -321,8 +375,7 @@
16035  static int fakehd_set = 0;
16036  static int fakehd(char *str)
16037  {
16038 -       printk(KERN_INFO 
16039 -              "fakehd : Changing ubd name to \"hd\".\n");
16040 +       printk(KERN_INFO "fakehd : Changing ubd name to \"hd\".\n");
16041         fakehd_set = 1;
16042         return 1;
16043  }
16044 @@ -368,32 +421,42 @@
16045  {
16046         struct io_thread_req req;
16047         struct request *rq = elv_next_request(ubd_queue);
16048 -       int n;
16049 +       int n, err;
16050  
16051         do_ubd = NULL;
16052         intr_count++;
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);
16061                 return;
16062         }
16063          
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");
16070         
16071 +       if(req.map_fd != -1){
16072 +               err = physmem_subst_mapping(req.buffer, req.map_fd, 
16073 +                                           req.map_offset, 1);
16074 +               if(err)
16075 +                       printk("ubd_handler - physmem_subst_mapping failed, "
16076 +                              "err = %d\n", -err);
16077 +       }
16078 +
16079         ubd_finish(rq, req.error);
16080         reactivate_fd(thread_fd, UBD_IRQ);      
16081         do_ubd_request(ubd_queue);
16082  }
16083  
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)
16086  {
16087         ubd_handler();
16088 +       return(IRQ_HANDLED);
16089  }
16090  
16091  /* Only changed by ubd_init, which is an initcall. */
16092 @@ -417,10 +480,14 @@
16093  
16094  static void ubd_close(struct ubd *dev)
16095  {
16096 +       if(ubd_do_mmap)
16097 +               physmem_forget_descriptor(dev->fd);
16098         os_close_file(dev->fd);
16099         if(dev->cow.file == NULL)
16100                 return;
16101  
16102 +       if(ubd_do_mmap)
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)
16109  {
16110         struct openflags flags;
16111 -       int err, n, create_cow, *create_ptr;
16112 +       char **back_ptr;
16113 +       int err, create_cow, *create_ptr;
16114  
16115 +       dev->openflags = dev->boot_openflags;
16116         create_cow = 0;
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);
16123  
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){
16134                 err = -ENOMEM;
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");
16139 +                       goto error;
16140 +               }
16141                 flush_tlb_kernel_vm();
16142  
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;
16147 +               if(err < 0)
16148 +                       goto error;
16149  
16150                 flags = dev->openflags;
16151                 flags.w = 0;
16152 @@ -481,17 +554,31 @@
16153                         
16154  {
16155         struct gendisk *disk;
16156 +       char from[sizeof("ubd/nnnnn\0")], to[sizeof("discnnnnn/disc\0")];
16157 +       int err;
16158  
16159         disk = alloc_disk(1 << UBD_SHIFT);
16160 -       if (!disk)
16161 -               return -ENOMEM;
16162 +       if(disk == NULL)
16163 +               return(-ENOMEM);
16164  
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);
16177 +               if(err)
16178 +                       printk("ubd_new_disk failed to make link from %s to "
16179 +                              "%s, error = %d\n", from, to, err);
16180 +       }
16181 +       else {
16182 +               sprintf(disk->disk_name, "ubd_fake%d", unit);
16183 +               sprintf(disk->devfs_name, "ubd_fake/disc%d", unit);
16184 +       }
16185  
16186         disk->private_data = &ubd_dev[unit];
16187         disk->queue = ubd_queue;
16188 @@ -506,24 +593,21 @@
16189         struct ubd *dev = &ubd_dev[n];
16190         int err;
16191  
16192 -       if(dev->is_dir)
16193 -               return(-EISDIR);
16194 -
16195 -       if (!dev->file)
16196 +       if(dev->file == NULL)
16197                 return(-ENODEV);
16198  
16199         if (ubd_open_dev(dev))
16200                 return(-ENODEV);
16201  
16202         err = ubd_file_size(dev, &dev->size);
16203 -       if(err)
16204 +       if(err < 0)
16205                 return(err);
16206  
16207         err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
16208         if(err) 
16209                 return(err);
16210   
16211 -       if(fake_major)
16212 +       if(fake_major != MAJOR_NR)
16213                 ubd_new_disk(fake_major, dev->size, n, 
16214                              &fake_gendisk[n]);
16215  
16216 @@ -561,42 +645,42 @@
16217         return(err);
16218  }
16219  
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)
16222  {
16223 -       struct ubd *ubd;
16224 +       struct ubd *dev;
16225         char *end;
16226 -       int major, n = 0;
16227 +       int n, len = 0;
16228  
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";
16235                 return(-1);
16236         }
16237  
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";
16242                 return(-1);
16243         }
16244  
16245 -       ubd = &ubd_dev[major];
16246 +       dev = &ubd_dev[n];
16247         spin_lock(&ubd_lock);
16248  
16249 -       if(ubd->file == NULL){
16250 -               CONFIG_CHUNK(str, size, n, "", 1);
16251 +       if(dev->file == NULL){
16252 +               CONFIG_CHUNK(str, size, len, "", 1);
16253                 goto out;
16254         }
16255  
16256 -       CONFIG_CHUNK(str, size, n, ubd->file, 0);
16257 +       CONFIG_CHUNK(str, size, len, dev->file, 0);
16258  
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);
16265         }
16266 -       else CONFIG_CHUNK(str, size, n, "", 1);
16267 +       else CONFIG_CHUNK(str, size, len, "", 1);
16268  
16269   out:
16270         spin_unlock(&ubd_lock);
16271 -       return(n);
16272 +       return(len);
16273  }
16274  
16275  static int ubd_remove(char *str)
16276 @@ -604,11 +688,9 @@
16277         struct ubd *dev;
16278         int n, err = -ENODEV;
16279  
16280 -       if(!isdigit(*str))
16281 -               return(err);    /* it should be a number 0-7/a-h */
16282 +       n = parse_unit(&str);
16283  
16284 -       n = *str - '0';
16285 -       if(n >= MAX_DEV) 
16286 +       if((n < 0) || (n >= MAX_DEV))
16287                 return(err);
16288  
16289         dev = &ubd_dev[n];
16290 @@ -669,7 +751,7 @@
16291                 
16292         elevator_init(ubd_queue, &elevator_noop);
16293  
16294 -       if (fake_major != 0) {
16295 +       if (fake_major != MAJOR_NR) {
16296                 char name[sizeof("ubd_nnn\0")];
16297  
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 *), 
16301                                  &thread_fd);
16302         if(io_pid < 0){
16303 +               io_pid = -1;
16304                 printk(KERN_ERR 
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 @@
16308         }
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);
16313 +       if(err != 0) 
16314 +               printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
16315         return(err);
16316  }
16317  
16318 @@ -714,15 +797,9 @@
16319  {
16320         struct gendisk *disk = inode->i_bdev->bd_disk;
16321         struct ubd *dev = disk->private_data;
16322 -       int err = -EISDIR;
16323 -
16324 -       if(dev->is_dir == 1)
16325 -               goto out;
16326 +       int err = 0;
16327  
16328 -       err = 0;
16329         if(dev->count == 0){
16330 -               dev->openflags = dev->boot_openflags;
16331 -
16332                 err = ubd_open_dev(dev);
16333                 if(err){
16334                         printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
16335 @@ -749,62 +826,156 @@
16336         return(0);
16337  }
16338  
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)
16344 +{
16345 +       __u64 sector = io_offset >> 9;
16346 +       int i, update_bitmap = 0;
16347 +
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))
16352 +                       continue;
16353 +
16354 +               update_bitmap = 1;
16355 +               ubd_set_bit(sector + i, (unsigned char *) bitmap);
16356 +       }
16357 +
16358 +       if(!update_bitmap)
16359 +               return;
16360 +
16361 +       *cow_offset = sector / (sizeof(unsigned long) * 8);
16362 +
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.
16367 +        */
16368 +       if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) / 
16369 +                          sizeof(unsigned long) - 1))
16370 +               (*cow_offset)--;
16371 +
16372 +       bitmap_words[0] = bitmap[*cow_offset];
16373 +       bitmap_words[1] = bitmap[*cow_offset + 1];
16374 +
16375 +       *cow_offset *= sizeof(unsigned long);
16376 +       *cow_offset += bitmap_offset;
16377 +}
16378 +
16379 +static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, 
16380 +                      __u64 bitmap_offset, __u64 bitmap_len)
16381  {
16382 -        int i, update_bitmap, sector = req->offset >> 9;
16383 +       __u64 sector = req->offset >> 9;
16384 +       int i;
16385  
16386         if(req->length > (sizeof(req->sector_mask) * 8) << 9)
16387                 panic("Operation too long");
16388 +
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);
16396 -                       }
16397                  }
16398 -        } 
16399 -        else {
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);
16409 -               }
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;
16418 +       }
16419 +       else cowify_bitmap(req->offset, req->length, &req->sector_mask,
16420 +                          &req->cow_offset, bitmap, bitmap_offset, 
16421 +                          req->bitmap_words, bitmap_len);
16422 +}
16423 +
16424 +static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset)
16425 +{
16426 +       __u64 sector;
16427 +       unsigned char *bitmap;
16428 +       int bit, i;
16429 +
16430 +       /* mmap must have been requested on the command line */
16431 +       if(!ubd_do_mmap)
16432 +               return(-1);
16433 +
16434 +       /* The buffer must be page aligned */
16435 +       if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0)
16436 +               return(-1);
16437 +
16438 +       /* The request must be a page long */
16439 +       if((req->current_nr_sectors << 9) != PAGE_SIZE)
16440 +               return(-1);
16441 +
16442 +       if(dev->cow.file == NULL)
16443 +               return(dev->fd);
16444 +
16445 +       sector = offset >> 9;
16446 +       bitmap = (unsigned char *) dev->cow.bitmap;
16447 +       bit = ubd_test_bit(sector, bitmap);
16448 +
16449 +       for(i = 1; i < req->current_nr_sectors; i++){
16450 +               if(ubd_test_bit(sector + i, bitmap) != bit)
16451 +                       return(-1);
16452 +       }
16453 +
16454 +       if(bit || (rq_data_dir(req) == WRITE))
16455 +               offset += dev->cow.data_offset;
16456 +
16457 +       /* The data on disk must be page aligned */
16458 +       if((offset % UBD_MMAP_BLOCK_SIZE) != 0)
16459 +               return(-1);
16460 +
16461 +       return(bit ? dev->fd : dev->cow.fd);
16462 +}
16463 +
16464 +static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset, 
16465 +                               struct request *req, 
16466 +                               struct io_thread_req *io_req)
16467 +{
16468 +       int err;
16469 +
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
16473 +                */
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);
16481 +       }
16482 +       else {
16483 +               int w;
16484 +
16485 +               if((dev->cow.file != NULL) && (fd == dev->cow.fd))
16486 +                       w = 0;
16487 +               else w = dev->openflags.w;
16488 +
16489 +               if((dev->cow.file != NULL) && (fd == dev->fd))
16490 +                       offset += dev->cow.data_offset;
16491 +
16492 +               err = physmem_subst_mapping(req->buffer, fd, offset, w);
16493 +               if(err){
16494 +                       printk("physmem_subst_mapping failed, err = %d\n", 
16495 +                              -err);
16496 +                       return(1);
16497                 }
16498 +               dev->map_reads++;
16499         }
16500 +       io_req->op = UBD_MMAP;
16501 +       io_req->buffer = req->buffer;
16502 +       return(0);
16503  }
16504  
16505  static int prepare_request(struct request *req, struct io_thread_req *io_req)
16506  {
16507         struct gendisk *disk = req->rq_disk;
16508         struct ubd *dev = disk->private_data;
16509 -       __u64 block;
16510 -       int nsect;
16511 +       __u64 offset;
16512 +       int len, fd;
16513  
16514         if(req->rq_status == RQ_INACTIVE) return(1);
16515  
16516 -       if(dev->is_dir){
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);
16522 -               return(1);
16523 -       }
16524 -
16525         if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
16526                 printk("Write attempted on readonly ubd device %s\n", 
16527                        disk->disk_name);
16528 @@ -814,23 +985,49 @@
16529                 return(1);
16530         }
16531  
16532 -        block = req->sector;
16533 -        nsect = req->current_nr_sectors;
16534 +       offset = ((__u64) req->sector) << 9;
16535 +       len = req->current_nr_sectors << 9;
16536  
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;
16546 +
16547 +       fd = mmap_fd(req, dev, io_req->offset);
16548 +       if(fd > 0){
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.
16553 +                */
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++;
16559 +               }
16560 +               else return(prepare_mmap_request(dev, fd, io_req->offset, req, 
16561 +                                                io_req));
16562 +       }
16563 +
16564 +       if(rq_data_dir(req) == READ)
16565 +               dev->nomap_reads++;
16566 +       else dev->nomap_writes++;
16567 +
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;
16578  
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);
16583 +
16584         return(0);
16585  }
16586  
16587 @@ -841,7 +1038,7 @@
16588         int err, n;
16589  
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);
16595                         if(!err){
16596 @@ -851,7 +1048,8 @@
16597                 }
16598         }
16599         else {
16600 -               if(do_ubd || list_empty(&q->queue_head)) return;
16601 +               if(do_ubd || elv_queue_empty(q))
16602 +                       return;
16603                 req = elv_next_request(q);
16604                 err = prepare_request(req, &io_req);
16605                 if(!err){
16606 @@ -885,7 +1083,7 @@
16607                 g.heads = 128;
16608                 g.sectors = 32;
16609                 g.cylinders = dev->size / (128 * 32 * 512);
16610 -               g.start = 2;
16611 +               g.start = get_start_sect(inode->i_bdev);
16612                 return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0);
16613  
16614         case HDIO_SET_UNMASKINTR:
16615 @@ -935,6 +1133,142 @@
16616         return(-EINVAL);
16617  }
16618  
16619 +static int ubd_check_remapped(int fd, unsigned long address, int is_write,
16620 +                             __u64 offset)
16621 +{
16622 +       __u64 bitmap_offset;
16623 +       unsigned long new_bitmap[2];
16624 +       int i, err, n;
16625 +
16626 +       /* If it's not a write access, we can't do anything about it */
16627 +       if(!is_write)
16628 +               return(0);
16629 +
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];
16633 +
16634 +               if((dev->fd != fd) && (dev->cow.fd != fd))
16635 +                       continue;
16636 +
16637 +               /* It's a write to a ubd device */
16638 +
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
16644 +                        * fixing
16645 +                        */
16646 +                       printk("Write access to mapped page from readonly ubd "
16647 +                              "device %d\n", i);
16648 +                       return(0);
16649 +               }
16650 +
16651 +               /* It's a write to a writeable ubd device - it must be COWed
16652 +                * because, otherwise, the page would have been mapped in 
16653 +                * writeable
16654 +                */
16655 +
16656 +               if(!dev->cow.file)
16657 +                       panic("Write fault on writeable non-COW ubd device %d",
16658 +                             i);
16659 +
16660 +               /* It should also be an access to the backing file since the 
16661 +                * COW pages should be mapped in read-write
16662 +                */
16663 +
16664 +               if(fd == dev->fd)
16665 +                       panic("Write fault on a backing page of ubd "
16666 +                             "device %d\n", i);
16667 +
16668 +               /* So, we do the write, copying the backing data to the COW 
16669 +                * file... 
16670 +                */
16671 +
16672 +               err = os_seek_file(dev->fd, offset + dev->cow.data_offset);
16673 +               if(err < 0)
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);
16677 +
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);
16682 +
16683 +               /* ... updating the COW bitmap... */
16684 +
16685 +               cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset, 
16686 +                             dev->cow.bitmap, dev->cow.bitmap_offset, 
16687 +                             new_bitmap, dev->cow.bitmap_len);
16688 +
16689 +               err = os_seek_file(dev->fd, bitmap_offset);
16690 +               if(err < 0)
16691 +                       panic("Couldn't seek to %lld in COW file of ubd "
16692 +                             "device %d, err = %d", bitmap_offset, i, -err);
16693 +
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);
16698 +               
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.
16704 +                */
16705 +
16706 +               offset += dev->cow.data_offset;
16707 +
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.
16711 +                */
16712 +
16713 +               if(!physmem_remove_mapping((void *) address))
16714 +                       panic("Address 0x%lx not remapped by ubd device %d", 
16715 +                             address, i);
16716 +               if((offset % UBD_MMAP_BLOCK_SIZE) == 0)
16717 +                       physmem_subst_mapping((void *) address, dev->fd, 
16718 +                                             offset, 1);
16719 +               else {
16720 +                       err = os_seek_file(dev->fd, offset);
16721 +                       if(err < 0)
16722 +                               panic("Couldn't seek to %lld in COW file of "
16723 +                                     "ubd device %d, err = %d", offset, i, 
16724 +                                     -err);
16725 +
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",
16730 +                                     offset, i, -n);
16731 +               }
16732 +
16733 +               return(1);
16734 +       }
16735 +
16736 +       /* It's not a write on a ubd device */
16737 +       return(0);
16738 +}
16739 +
16740 +static struct remapper ubd_remapper = {
16741 +       .list   = LIST_HEAD_INIT(ubd_remapper.list),
16742 +       .proc   = ubd_check_remapped,
16743 +};
16744 +
16745 +static int ubd_remapper_setup(void)
16746 +{
16747 +       if(ubd_do_mmap)
16748 +               register_remapper(&ubd_remapper);
16749 +
16750 +       return(0);
16751 +}
16752 +
16753 +__initcall(ubd_remapper_setup);
16754 +
16755  /*
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
16762 @@ -8,7 +8,6 @@
16763  #include <unistd.h>
16764  #include <string.h>
16765  #include <errno.h>
16766 -#include <fcntl.h>
16767  #include <termios.h>
16768  #include <signal.h>
16769  #include <sched.h>
16770 @@ -36,7 +35,8 @@
16771  {
16772         struct xterm_chan *data;
16773  
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, 
16778                                        .helper_pid      = -1,
16779                                        .device          = device, 
16780 @@ -93,7 +93,7 @@
16781                          "/usr/lib/uml/port-helper", "-uml-socket",
16782                          file, NULL };
16783  
16784 -       if(access(argv[4], X_OK))
16785 +       if(os_access(argv[4], OS_ACC_X_OK) < 0)
16786                 argv[4] = "port-helper";
16787  
16788         fd = mkstemp(file);
16789 @@ -106,13 +106,13 @@
16790                 printk("xterm_open : unlink failed, errno = %d\n", errno);
16791                 return(-errno);
16792         }
16793 -       close(fd);
16794 +       os_close_file(fd);
16795  
16796 -       fd = create_unix_socket(file, sizeof(file));
16797 +       fd = os_create_unix_socket(file, sizeof(file), 1);
16798         if(fd < 0){
16799                 printk("xterm_open : create_unix_socket failed, errno = %d\n", 
16800                        -fd);
16801 -               return(-fd);
16802 +               return(fd);
16803         }
16804  
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);
16809         else {
16810 -               if((err = os_set_fd_block(fd, 0)) != 0){
16811 +               err = os_set_fd_block(fd, 0);
16812 +               if(err < 0){
16813                         printk("xterm_open : failed to set descriptor "
16814 -                              "non-blocking, errno = %d\n", err);
16815 +                              "non-blocking, err = %d\n", -err);
16816                         return(err);
16817                 }
16818                 new = xterm_fd(fd, &data->helper_pid);
16819         }
16820         if(new < 0){
16821 -               printk("xterm_open : os_rcv_fd failed, errno = %d\n", -new);
16822 +               printk("xterm_open : os_rcv_fd failed, err = %d\n", -new);
16823                 goto out;
16824         }
16825  
16826 @@ -160,7 +161,7 @@
16827         if(data->helper_pid != -1) 
16828                 os_kill_process(data->helper_pid, 0);
16829         data->helper_pid = -1;
16830 -       close(fd);
16831 +       os_close_file(fd);
16832  }
16833  
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
16839 @@ -1,6 +1,6 @@
16840  /*
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
16845   */
16846  
16847 @@ -15,6 +15,9 @@
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"
16857 @@ -27,6 +30,7 @@
16858  #include "init.h"
16859  #include "os.h"
16860  #include "umid.h"
16861 +#include "irq_kern.h"
16862  
16863  static int do_unlink_socket(struct notifier_block *notifier, 
16864                             unsigned long what, void *data)
16865 @@ -67,7 +71,7 @@
16866  
16867  DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
16868  
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)
16871  {
16872         int fd;
16873         struct mconsole_entry *new;
16874 @@ -75,9 +79,10 @@
16875  
16876         fd = (int) dev_id;
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);
16881                 else {
16882 -                       new = kmalloc(sizeof(req), GFP_ATOMIC);
16883 +                       new = kmalloc(sizeof(*new), GFP_ATOMIC);
16884                         if(new == NULL)
16885                                 mconsole_reply(&req, "Out of memory", 1, 0);
16886                         else {
16887 @@ -88,6 +93,7 @@
16888         }
16889         if(!list_empty(&mc_requests)) schedule_work(&mconsole_work);
16890         reactivate_fd(fd, MCONSOLE_IRQ);
16891 +       return(IRQ_HANDLED);
16892  }
16893  
16894  void mconsole_version(struct mc_request *req)
16895 @@ -100,20 +106,109 @@
16896         mconsole_reply(req, version, 0, 0);
16897  }
16898  
16899 +void mconsole_log(struct mc_request *req)
16900 +{
16901 +       int len;
16902 +       char *ptr = req->request.data;
16903 +       
16904 +       ptr += strlen("log ");
16905 +
16906 +       len = req->len - (ptr - req->request.data);
16907 +       printk("%.*s", len, ptr);
16908 +       mconsole_reply(req, "", 0, 0);
16909 +}
16910 +
16911 +void mconsole_proc(struct mc_request *req)
16912 +{
16913 +       struct nameidata nd;
16914 +       struct file_system_type *proc;
16915 +       struct super_block *super;
16916 +       struct file *file;
16917 +       int n, err;
16918 +       char *ptr = req->request.data, *buf;
16919 +       
16920 +       ptr += strlen("proc");
16921 +       while(isspace(*ptr)) ptr++;
16922 +
16923 +       proc = get_fs_type("proc");
16924 +       if(proc == NULL){
16925 +               mconsole_reply(req, "procfs not registered", 1, 0);
16926 +               goto out;
16927 +       }
16928 +
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);
16933 +               goto out;
16934 +       }
16935 +       up_write(&super->s_umount);
16936 +
16937 +       nd.dentry = super->s_root;
16938 +       nd.mnt = NULL;
16939 +       nd.flags = O_RDONLY + 1;
16940 +       nd.last_type = LAST_ROOT;
16941 +
16942 +       err = link_path_walk(ptr, &nd);
16943 +       if(err){
16944 +               mconsole_reply(req, "Failed to look up file", 1, 0);
16945 +               goto out_kill;
16946 +       }
16947 +
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);
16951 +               goto out_kill;
16952 +       }
16953 +
16954 +       buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
16955 +       if(buf == NULL){
16956 +               mconsole_reply(req, "Failed to allocate buffer", 1, 0);
16957 +               goto out_fput;
16958 +       }
16959 +
16960 +       if((file->f_op != NULL) && (file->f_op->read != NULL)){
16961 +               do {
16962 +                       n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1, 
16963 +                                               &file->f_pos);
16964 +                       if(n >= 0){
16965 +                               buf[n] = '\0';
16966 +                               mconsole_reply(req, buf, 0, (n > 0));
16967 +                       }
16968 +                       else {
16969 +                               mconsole_reply(req, "Read of file failed", 
16970 +                                              1, 0);
16971 +                               goto out_free;
16972 +                       }
16973 +               } while(n > 0);
16974 +       }
16975 +       else mconsole_reply(req, "", 0, 0);
16976 +
16977 + out_free:
16978 +       kfree(buf);
16979 + out_fput:
16980 +       fput(file);
16981 + out_kill:
16982 +       deactivate_super(super);
16983 + out: ;
16984 +}
16985 +
16986  #define UML_MCONSOLE_HELPTEXT \
16987 -"Commands:
16988 -    version - Get kernel version
16989 -    help - Print this message
16990 -    halt - Halt UML
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'
17000 +"Commands: \n\
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\
17015  "
17016  
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);
17021  
17022 -       sock = create_unix_socket(file, sizeof(file));
17023 +       sock = os_create_unix_socket(file, sizeof(file), 1);
17024         if (sock < 0){
17025                 printk("Failed to initialize management console\n");
17026                 return(1);
17027 @@ -344,11 +439,16 @@
17028         if(buf == NULL) 
17029                 return(-ENOMEM);
17030  
17031 -       if(copy_from_user(buf, buffer, count))
17032 -               return(-EFAULT);
17033 +       if(copy_from_user(buf, buffer, count)){
17034 +               count = -EFAULT;
17035 +               goto out;
17036 +       }
17037 +
17038         buf[count] = '\0';
17039  
17040         mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count);
17041 + out:
17042 +       kfree(buf);
17043         return(count);
17044  }
17045  
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
17050 @@ -14,7 +14,7 @@
17051  LINK_SKAS = -Wl,-rpath,/lib 
17052  LD_SCRIPT_SKAS = dyn.lds.s
17053  
17054 -GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
17055 +GEN_HEADERS += $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
17056  
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
17065 @@ -5,7 +5,6 @@
17066  
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"
17076  
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
17082 +#else
17083 +#define NFSSERVCTL sys_ni_syscall
17084 +#endif
17085 +
17086 +#define LAST_GENERIC_SYSCALL __NR_vserver
17087 +
17088 +#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
17089 +#define LAST_SYSCALL LAST_GENERIC_SYSCALL
17090 +#else
17091 +#define LAST_SYSCALL LAST_ARCH_SYSCALL
17092 +#endif
17093 +
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;
17318 -
17319 -#ifdef CONFIG_NFSD
17320 -#define NFSSERVCTL sys_nfsservctl
17321 -#else
17322 -#define NFSSERVCTL sys_ni_syscall
17323 -#endif
17324 -
17325 -extern syscall_handler_t um_mount;
17326 -extern syscall_handler_t um_time;
17327 -extern syscall_handler_t um_stime;
17328 -
17329 -#define LAST_GENERIC_SYSCALL __NR_set_tid_address
17330 -
17331 -#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
17332 -#define LAST_SYSCALL LAST_GENERIC_SYSCALL
17333 -#else
17334 -#define LAST_SYSCALL LAST_ARCH_SYSCALL
17335 -#endif
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;
17341  
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,
17351  
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,
17363  
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,
17419  
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,
17804  
17805         ARCH_SYSCALLS
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);
17813  }
17814  
17815 +extern void log_exec(char **argv, void *tty);
17816 +
17817  static int execve1(char *file, char **argv, char **env)
17818  {
17819          int error;
17820  
17821 +#ifdef CONFIG_TTY_LOG
17822 +       log_exec(argv, current->tty);
17823 +#endif
17824          error = do_execve(file, argv, env, &current->thread.regs);
17825          if (error == 0){
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
17831 @@ -53,7 +53,8 @@
17832         struct request_v3 req;
17833         int fd, n, err;
17834  
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", 
17839                        errno);          
17840                 return(-errno);
17841 @@ -67,7 +68,8 @@
17842                 goto out;
17843         }
17844  
17845 -       if((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0){
17846 +       fd = socket(AF_UNIX, SOCK_DGRAM, 0);
17847 +       if(fd < 0){
17848                 printk("daemon_open : data socket failed, errno = %d\n", 
17849                        errno);
17850                 err = -errno;
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",
17861 +                      -n);
17862                 err = -ENOTCONN;
17863                 goto out;               
17864         }
17865  
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", 
17872 +                      -n);
17873                 err = -ENOTCONN;
17874                 goto out_close;         
17875         }
17876 @@ -111,9 +113,9 @@
17877         return(fd);
17878  
17879   out_close:
17880 -       close(fd);
17881 +       os_close_file(fd);
17882   out:
17883 -       close(pri->control);
17884 +       os_close_file(pri->control);
17885         return(err);
17886  }
17887  
17888 @@ -153,8 +155,8 @@
17889  {
17890         struct daemon_data *pri = data;
17891  
17892 -       close(pri->fd);
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
17903 @@ -15,4 +15,17 @@
17904  
17905  #define USE_ELF_CORE_DUMP
17906  
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
17919 +
17920  #endif
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
17925 @@ -6,20 +6,12 @@
17926  #ifndef __SKAS_UACCESS_H
17927  #define __SKAS_UACCESS_H
17928  
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"
17938  
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)))
17944  
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);
17949  }
17950  
17951 -static inline unsigned long maybe_map(unsigned long virt, int is_write)
17952 -{
17953 -       pte_t pte;
17954 -
17955 -       void *phys = um_virt_to_phys(current, virt, &pte);
17956 -       int dummy_code;
17957 -
17958 -       if(IS_ERR(phys) || (is_write && !pte_write(pte))){
17959 -               if(handle_page_fault(virt, 0, is_write, 0, &dummy_code))
17960 -                       return(0);
17961 -               phys = um_virt_to_phys(current, virt, NULL);
17962 -       }
17963 -       return((unsigned long) __va((unsigned long) phys));
17964 -}
17965 -
17966 -static inline int buffer_op(unsigned long addr, int len, 
17967 -                           int (*op)(unsigned long addr, int len, void *arg),
17968 -                           void *arg)
17969 -{
17970 -       int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
17971 -       int remain = len, n;
17972 -
17973 -       n = (*op)(addr, size, arg);
17974 -       if(n != 0)
17975 -               return(n < 0 ? remain : 0);
17976 -
17977 -       addr += size;
17978 -       remain -= size;
17979 -       if(remain == 0) 
17980 -               return(0);
17981 -
17982 -       while(addr < ((addr + remain) & PAGE_MASK)){
17983 -               n = (*op)(addr, PAGE_SIZE, arg);
17984 -               if(n != 0)
17985 -                       return(n < 0 ? remain : 0);
17986 -
17987 -               addr += PAGE_SIZE;
17988 -               remain -= PAGE_SIZE;
17989 -       }
17990 -       if(remain == 0)
17991 -               return(0);
17992 -
17993 -       n = (*op)(addr, remain, arg);
17994 -       if(n != 0)
17995 -               return(n < 0 ? remain : 0);
17996 -       return(0);
17997 -}
17998 -
17999 -static inline int copy_chunk_from_user(unsigned long from, int len, void *arg)
18000 -{
18001 -       unsigned long *to_ptr = arg, to = *to_ptr;
18002 -
18003 -       from = maybe_map(from, 0);
18004 -       if(from == 0)
18005 -               return(-1);
18006 -
18007 -       memcpy((void *) to, (void *) from, len);
18008 -       *to_ptr += len;
18009 -       return(0);
18010 -}
18011 -
18012 -static inline int copy_from_user_skas(void *to, const void *from, int n)
18013 -{
18014 -       if(segment_eq(get_fs(), KERNEL_DS)){
18015 -               memcpy(to, from, n);
18016 -               return(0);
18017 -       }
18018 -
18019 -       return(access_ok_skas(VERIFY_READ, from, n) ?
18020 -              buffer_op((unsigned long) from, n, copy_chunk_from_user, &to) :
18021 -              n);
18022 -}
18023 -
18024 -static inline int copy_chunk_to_user(unsigned long to, int len, void *arg)
18025 -{
18026 -       unsigned long *from_ptr = arg, from = *from_ptr;
18027 -
18028 -       to = maybe_map(to, 1);
18029 -       if(to == 0)
18030 -               return(-1);
18031 -
18032 -       memcpy((void *) to, (void *) from, len);
18033 -       *from_ptr += len;
18034 -       return(0);
18035 -}
18036 -
18037 -static inline int copy_to_user_skas(void *to, const void *from, int n)
18038 -{
18039 -       if(segment_eq(get_fs(), KERNEL_DS)){
18040 -               memcpy(to, from, n);
18041 -               return(0);
18042 -       }
18043 -
18044 -       return(access_ok_skas(VERIFY_WRITE, to, n) ?
18045 -              buffer_op((unsigned long) to, n, copy_chunk_to_user, &from) :
18046 -              n);
18047 -}
18048 -
18049 -static inline int strncpy_chunk_from_user(unsigned long from, int len, 
18050 -                                         void *arg)
18051 -{
18052 -        char **to_ptr = arg, *to = *to_ptr;
18053 -       int n;
18054 -
18055 -       from = maybe_map(from, 0);
18056 -       if(from == 0)
18057 -               return(-1);
18058 -
18059 -       strncpy(to, (void *) from, len);
18060 -       n = strnlen(to, len);
18061 -       *to_ptr += n;
18062 -
18063 -       if(n < len) 
18064 -               return(1);
18065 -       return(0);
18066 -}
18067 -
18068 -static inline int strncpy_from_user_skas(char *dst, const char *src, int count)
18069 -{
18070 -       int n;
18071 -       char *ptr = dst;
18072 -
18073 -       if(segment_eq(get_fs(), KERNEL_DS)){
18074 -               strncpy(dst, src, count);
18075 -               return(strnlen(dst, count));
18076 -       }
18077 -
18078 -       if(!access_ok_skas(VERIFY_READ, src, 1))
18079 -               return(-EFAULT);
18080 -
18081 -       n = buffer_op((unsigned long) src, count, strncpy_chunk_from_user, 
18082 -                     &ptr);
18083 -       if(n != 0)
18084 -               return(-EFAULT);
18085 -       return(strnlen(dst, count));
18086 -}
18087 -
18088 -static inline int clear_chunk(unsigned long addr, int len, void *unused)
18089 -{
18090 -       addr = maybe_map(addr, 1);
18091 -       if(addr == 0) 
18092 -               return(-1);
18093 -
18094 -       memset((void *) addr, 0, len);
18095 -       return(0);
18096 -}
18097 -
18098 -static inline int __clear_user_skas(void *mem, int len)
18099 -{
18100 -       return(buffer_op((unsigned long) mem, len, clear_chunk, NULL));
18101 -}
18102 -
18103 -static inline int clear_user_skas(void *mem, int len)
18104 -{
18105 -       if(segment_eq(get_fs(), KERNEL_DS)){
18106 -               memset(mem, 0, len);
18107 -               return(0);
18108 -       }
18109 -
18110 -       return(access_ok_skas(VERIFY_WRITE, mem, len) ? 
18111 -              buffer_op((unsigned long) mem, len, clear_chunk, NULL) : len);
18112 -}
18113 -
18114 -static inline int strnlen_chunk(unsigned long str, int len, void *arg)
18115 -{
18116 -       int *len_ptr = arg, n;
18117 -
18118 -       str = maybe_map(str, 0);
18119 -       if(str == 0) 
18120 -               return(-1);
18121 -
18122 -       n = strnlen((void *) str, len);
18123 -       *len_ptr += n;
18124 -
18125 -       if(n < len)
18126 -               return(1);
18127 -       return(0);
18128 -}
18129 -
18130 -static inline int strnlen_user_skas(const void *str, int len)
18131 -{
18132 -       int count = 0, n;
18133 -
18134 -       if(segment_eq(get_fs(), KERNEL_DS))
18135 -               return(strnlen(str, len) + 1);
18136 -
18137 -       n = buffer_op((unsigned long) str, len, strnlen_chunk, &count);
18138 -       if(n == 0)
18139 -               return(count + 1);
18140 -       return(-EFAULT);
18141 -}
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);
18148  
18149  #endif
18150  
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
18155 @@ -61,6 +61,20 @@
18156  
18157  config NET
18158         bool "Networking support"
18159 +       help
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.
18168 +
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>.
18172 +
18173  
18174  source "fs/Kconfig.binfmt"
18175  
18176 @@ -85,6 +99,19 @@
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.
18179  
18180 +config HPPFS
18181 +       tristate "HoneyPot ProcFS"
18182 +       help
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.
18188 +
18189 +       See http://user-mode-linux.sf.net/hppfs.html for more information.
18190 +
18191 +       You only need this if you are setting up a UML honeypot.  Otherwise,
18192 +       it is safe to say 'N' here.
18193  
18194  config MCONSOLE
18195         bool "Management console"
18196 @@ -105,6 +132,16 @@
18197  config MAGIC_SYSRQ
18198         bool "Magic SysRq key"
18199         depends on MCONSOLE
18200 +       help
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.
18210  
18211  config HOST_2G_2G
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.
18216  
18217 +config UML_REAL_TIME_CLOCK
18218 +       bool "Real-time Clock"
18219 +       default y
18220 +       help
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.
18227 +
18228  endmenu
18229  
18230  source "init/Kconfig"
18231 @@ -240,6 +288,10 @@
18232  config PT_PROXY
18233         bool "Enable ptrace proxy"
18234         depends on XTERM_CHAN && DEBUG_INFO
18235 +       help
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.
18239  
18240  config GPROF
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
18246 @@ -5,44 +5,64 @@
18247  
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"
18258  #include "init.h"
18259 -#include "hostaudio.h"
18260 +#include "os.h"
18261 +
18262 +struct hostaudio_state {
18263 +  int fd;
18264 +};
18265 +
18266 +struct hostmixer_state {
18267 +  int fd;
18268 +};
18269 +
18270 +#define HOSTAUDIO_DEV_DSP "/dev/sound/dsp"
18271 +#define HOSTAUDIO_DEV_MIXER "/dev/sound/mixer"
18272  
18273  /* Only changed from linux_main at boot time */
18274  char *dsp = HOSTAUDIO_DEV_DSP;
18275  char *mixer = HOSTAUDIO_DEV_MIXER;
18276  
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"
18280 +
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"
18284 +
18285  #ifndef MODULE
18286  static int set_dsp(char *name, int *add)
18287  {
18288 -       dsp = uml_strdup(name);
18289 +       dsp = name;
18290         return(0);
18291  }
18292  
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"
18297 -);
18298 +__uml_setup("dsp=", set_dsp, "dsp=<dsp device>\n" DSP_HELP);
18299  
18300  static int set_mixer(char *name, int *add)
18301  {
18302 -       mixer = uml_strdup(name);
18303 +       mixer = name;
18304         return(0);
18305  }
18306  
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"
18311 -);
18312 +__uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP);
18313 +
18314 +#else /*MODULE*/
18315 +
18316 +MODULE_PARM(dsp, "s");
18317 +MODULE_PARM_DESC(dsp, DSP_HELP);
18318 +
18319 +MODULE_PARM(mixer, "s");
18320 +MODULE_PARM_DESC(mixer, MIXER_HELP);
18321 +
18322  #endif
18323  
18324  /* /dev/dsp file operations */
18325 @@ -51,23 +71,55 @@
18326                               loff_t *ppos)
18327  {
18328          struct hostaudio_state *state = file->private_data;
18329 +       void *kbuf;
18330 +       int ret;
18331  
18332  #ifdef DEBUG
18333          printk("hostaudio: read called, count = %d\n", count);
18334  #endif
18335  
18336 -        return(hostaudio_read_user(state, buffer, count, ppos));
18337 +       kbuf = kmalloc(count, GFP_KERNEL);
18338 +       if(kbuf == NULL)
18339 +               return(-ENOMEM);
18340 +
18341 +       ret = os_read_file(state->fd, kbuf, count);
18342 +       if(ret < 0)
18343 +               goto out;
18344 +
18345 +       if(copy_to_user(buffer, kbuf, ret))
18346 +               ret = -EFAULT;
18347 +
18348 + out:
18349 +       kfree(kbuf);
18350 +       return(ret);
18351  }
18352  
18353  static ssize_t hostaudio_write(struct file *file, const char *buffer, 
18354                                size_t count, loff_t *ppos)
18355  {
18356          struct hostaudio_state *state = file->private_data;
18357 +       void *kbuf;
18358 +       int ret;
18359  
18360  #ifdef DEBUG
18361          printk("hostaudio: write called, count = %d\n", count);
18362  #endif
18363 -        return(hostaudio_write_user(state, buffer, count, ppos));
18364 +
18365 +       kbuf = kmalloc(count, GFP_KERNEL);
18366 +       if(kbuf == NULL)
18367 +               return(-ENOMEM);
18368 +
18369 +       ret = -EFAULT;
18370 +       if(copy_from_user(kbuf, buffer, count))
18371 +               goto out;
18372 +
18373 +       ret = os_write_file(state->fd, kbuf, count);
18374 +       if(ret < 0)
18375 +               goto out;
18376 +
18377 + out:
18378 +       kfree(kbuf);
18379 +       return(ret);
18380  }
18381  
18382  static unsigned int hostaudio_poll(struct file *file, 
18383 @@ -86,12 +138,43 @@
18384                            unsigned int cmd, unsigned long arg)
18385  {
18386          struct hostaudio_state *state = file->private_data;
18387 +       unsigned long data = 0;
18388 +       int ret;
18389  
18390  #ifdef DEBUG
18391          printk("hostaudio: ioctl called, cmd = %u\n", cmd);
18392  #endif
18393 +       switch(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))
18401 +                       return(-EFAULT);
18402 +               break;
18403 +       default:
18404 +               break;
18405 +       }
18406 +
18407 +       ret = os_ioctl_generic(state->fd, cmd, (unsigned long) &data);
18408 +
18409 +       switch(cmd){
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))
18417 +                       return(-EFAULT);
18418 +               break;
18419 +       default:
18420 +               break;
18421 +       }
18422  
18423 -        return(hostaudio_ioctl_user(state, cmd, arg));
18424 +       return(ret);
18425  }
18426  
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;
18431  
18432 -        ret = hostaudio_open_user(state, r, w, dsp);
18433 +       ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
18434 +
18435          if(ret < 0){
18436 +               printk("hostaudio_open failed to open '%s', err = %d\n",
18437 +                      dsp, -ret);
18438                 kfree(state);
18439                 return(ret);
18440          }
18441  
18442 +       state->fd = ret;
18443 +
18444          file->private_data = state;
18445          return(0);
18446  }
18447 @@ -123,16 +211,19 @@
18448  static int hostaudio_release(struct inode *inode, struct file *file)
18449  {
18450          struct hostaudio_state *state = file->private_data;
18451 -        int ret;
18452  
18453  #ifdef DEBUG
18454          printk("hostaudio: release called\n");
18455  #endif
18456  
18457 -        ret = hostaudio_release_user(state);
18458 +       if(state->fd >= 0){
18459 +               os_close_file(state->fd);
18460 +               state->fd = -1;
18461 +       }
18462 +
18463          kfree(state);
18464  
18465 -        return(ret);
18466 +       return(0);
18467  }
18468  
18469  /* /dev/mixer file operations */
18470 @@ -146,7 +237,7 @@
18471          printk("hostmixer: ioctl called\n");
18472  #endif
18473  
18474 -        return(hostmixer_ioctl_mixdev_user(state, cmd, arg));
18475 +       return(os_ioctl_generic(state->fd, cmd, arg));
18476  }
18477  
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;
18482  
18483 -        ret = hostmixer_open_mixdev_user(state, r, w, mixer);
18484 +       ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
18485          
18486          if(ret < 0){
18487 +               printk("hostaudio_open_mixdev failed to open '%s', err = %d\n",
18488 +                      dsp, -ret);
18489                 kfree(state);
18490                 return(ret);
18491          }
18492  
18493 +       state->fd = ret;
18494 +
18495          file->private_data = state;
18496          return(0);
18497  }
18498 @@ -179,16 +274,18 @@
18499  static int hostmixer_release(struct inode *inode, struct file *file)
18500  {
18501          struct hostmixer_state *state = file->private_data;
18502 -       int ret;
18503  
18504  #ifdef DEBUG
18505          printk("hostmixer: release called\n");
18506  #endif
18507  
18508 -        ret = hostmixer_release_mixdev_user(state);
18509 +       if(state->fd >= 0){
18510 +               os_close_file(state->fd);
18511 +               state->fd = -1;
18512 +       }
18513          kfree(state);
18514  
18515 -        return(ret);
18516 +       return(0);
18517  }
18518  
18519  
18520 @@ -225,7 +322,8 @@
18521  
18522  static int __init hostaudio_init_module(void)
18523  {
18524 -        printk(KERN_INFO "UML Audio Relay\n");
18525 +        printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
18526 +              dsp, mixer);
18527  
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
18534 @@ -14,6 +14,7 @@
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);
18539  
18540  #endif
18541  
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
18546 @@ -1,5 +1,5 @@
18547  /* 
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
18551   */
18552  
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
18557 @@ -9,6 +9,7 @@
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
18569 @@ -15,7 +15,6 @@
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 @@
18578  
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 @@
18587                 }
18588                 debugger_proxy(status, debugger.pid);
18589         }
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 @@
18596  }
18597  
18598  char gdb_init_string[] = 
18599 -"att 1
18600 -b panic
18601 -b stop
18602 -handle SIGWINCH nostop noprint pass
18603 +"att 1 \n\
18604 +b panic \n\
18605 +b stop \n\
18606 +handle SIGWINCH nostop noprint pass \n\
18607  ";
18608  
18609  int start_debugger(char *prog, int startup, int stop, int *fd_out)
18610 @@ -304,7 +303,8 @@
18611         int slave, child;
18612  
18613         slave = open_gdb_chan();
18614 -       if((child = fork()) == 0){
18615 +       child = fork();
18616 +       if(child == 0){
18617                 char *tempname = NULL;
18618                 int fd;
18619  
18620 @@ -327,18 +327,19 @@
18621                         exit(1);
18622  #endif
18623                 }
18624 -               if((fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0)) < 0){
18625 -                       printk("start_debugger : make_tempfile failed, errno = %d\n",
18626 -                              errno);
18627 +               fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0);
18628 +               if(fd < 0){
18629 +                       printk("start_debugger : make_tempfile failed,"
18630 +                              "err = %d\n", -fd);
18631                         exit(1);
18632                 }
18633 -               write(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
18634 +               os_write_file(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
18635                 if(startup){
18636                         if(stop){
18637 -                               write(fd, "b start_kernel\n",
18638 +                               os_write_file(fd, "b start_kernel\n",
18639                                       strlen("b start_kernel\n"));
18640                         }
18641 -                       write(fd, "c\n", strlen("c\n"));
18642 +                       os_write_file(fd, "c\n", strlen("c\n"));
18643                 }
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
18650 @@ -1,5 +1,5 @@
18651  /* 
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
18655   */
18656  
18657 @@ -43,65 +43,19 @@
18658  
18659  extern int __do_copy_from_user(void *to, const void *from, int n,
18660                                void **fault_addr, void **fault_catcher);
18661 -
18662 -static inline int copy_from_user_tt(void *to, const void *from, int n)
18663 -{
18664 -       return(access_ok_tt(VERIFY_READ, from, n) ?
18665 -              __do_copy_from_user(to, from, n, 
18666 -                                  &current->thread.fault_addr,
18667 -                                  &current->thread.fault_catcher) : n);
18668 -}
18669 -
18670 -static inline int copy_to_user_tt(void *to, const void *from, int n)
18671 -{
18672 -       return(access_ok_tt(VERIFY_WRITE, to, n) ?
18673 -              __do_copy_to_user(to, from, n, 
18674 -                                  &current->thread.fault_addr,
18675 -                                  &current->thread.fault_catcher) : n);
18676 -}
18677 -
18678  extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
18679                                   void **fault_addr, void **fault_catcher);
18680 -
18681 -static inline int strncpy_from_user_tt(char *dst, const char *src, int count)
18682 -{
18683 -       int n;
18684 -
18685 -       if(!access_ok_tt(VERIFY_READ, src, 1)) return(-EFAULT);
18686 -       n = __do_strncpy_from_user(dst, src, count, 
18687 -                                  &current->thread.fault_addr,
18688 -                                  &current->thread.fault_catcher);
18689 -       if(n < 0) return(-EFAULT);
18690 -       return(n);
18691 -}
18692 -
18693  extern int __do_clear_user(void *mem, size_t len, void **fault_addr,
18694                            void **fault_catcher);
18695 -
18696 -static inline int __clear_user_tt(void *mem, int len)
18697 -{
18698 -       return(__do_clear_user(mem, len,
18699 -                              &current->thread.fault_addr,
18700 -                              &current->thread.fault_catcher));
18701 -}
18702 -
18703 -static inline int clear_user_tt(void *mem, int len)
18704 -{
18705 -       return(access_ok_tt(VERIFY_WRITE, mem, len) ? 
18706 -              __do_clear_user(mem, len, 
18707 -                              &current->thread.fault_addr,
18708 -                              &current->thread.fault_catcher) : len);
18709 -}
18710 -
18711  extern int __do_strnlen_user(const char *str, unsigned long n,
18712                              void **fault_addr, void **fault_catcher);
18713  
18714 -static inline int strnlen_user_tt(const void *str, int len)
18715 -{
18716 -       return(__do_strnlen_user(str, len,
18717 -                                &current->thread.fault_addr,
18718 -                                &current->thread.fault_catcher));
18719 -}
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);
18726  
18727  #endif
18728  
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
18733 @@ -5,7 +5,6 @@
18734  
18735  #include <stdlib.h>
18736  #include <errno.h>
18737 -#include <fcntl.h>
18738  #include "chan_user.h"
18739  #include "os.h"
18740  
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
18745 @@ -6,7 +6,6 @@
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)));
18755  }
18756  
18757 +extern int userspace_pid[];
18758 +
18759  static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from, 
18760                            struct arch_frame_data *arch)
18761  {
18762         return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), 
18763                                               arch),
18764 -                          copy_sc_to_user_skas(to, fp, &from->regs,
18765 +                          copy_sc_to_user_skas(userspace_pid[0], to, fp, 
18766 +                                               &from->regs,
18767                                                 current->thread.cr2,
18768                                                 current->thread.err)));
18769  }
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
18774 @@ -1,19 +1,18 @@
18775  /* 
18776 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18777 + * Copyright (C) 2002, 2003 Jeff Dike (jdike@addtoit.com)
18778   * Licensed under the GPL
18779   */
18780  
18781  #ifndef __MEM_H__
18782  #define __MEM_H__
18783  
18784 -struct vm_reserved {
18785 -       struct list_head list;
18786 -       unsigned long start;
18787 -       unsigned long end;
18788 -};
18789 +#include "linux/types.h"
18790  
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);
18798  
18799  #endif
18800  
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
18805 @@ -9,7 +9,7 @@
18806  
18807  #include "os.h"
18808  
18809 -enum ubd_req { UBD_READ, UBD_WRITE };
18810 +enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
18811  
18812  struct io_thread_req {
18813         enum ubd_req op;
18814 @@ -20,8 +20,10 @@
18815         char *buffer;
18816         int sectorsize;
18817         unsigned long sector_mask;
18818 -       unsigned long cow_offset;
18819 +       unsigned long long cow_offset;
18820         unsigned long bitmap_words[2];
18821 +       int map_fd;
18822 +       unsigned long long map_offset;
18823         int error;
18824  };
18825  
18826 @@ -31,7 +33,7 @@
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);
18835 @@ -39,7 +41,6 @@
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);
18840  
18841  static inline int ubd_test_bit(__u64 bit, unsigned char *data)
18842  {
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
18847 @@ -9,7 +9,6 @@
18848  {
18849    . = START + SIZEOF_HEADERS;
18850  
18851 -  . = ALIGN(4096);
18852    __binary_start = .;
18853  #ifdef MODE_TT
18854    .thread_private : {
18855 @@ -26,11 +25,16 @@
18856    . = ALIGN(4096);             /* Init code and data */
18857    _stext = .;
18858    __init_begin = .;
18859 -  .text.init : { *(.text.init) }
18860 +  .init.text : { 
18861 +       _sinittext = .;
18862 +       *(.init.text)
18863 +       _einittext = .;
18864 +  }
18865    . = ALIGN(4096);
18866    .text      :
18867    {
18868      *(.text)
18869 +    SCHED_TEXT
18870      /* .gnu.warning sections are handled specially by elf32.em.  */
18871      *(.gnu.warning)
18872      *(.gnu.linkonce.t*)
18873 @@ -38,7 +42,7 @@
18874  
18875    #include "asm/common.lds.S"
18876  
18877 -  .data.init : { *(.data.init) }
18878 +  init.data : { *(init.data) }
18879    .data    :
18880    {
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
18886 @@ -8,7 +8,6 @@
18887  #include <stdio.h>
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>
18894 @@ -17,6 +16,7 @@
18895  #include <net/if.h>
18896  #include "user.h"
18897  #include "kern_util.h"
18898 +#include "user_util.h"
18899  #include "net_user.h"
18900  #include "etap.h"
18901  #include "helper.h"
18902 @@ -42,13 +42,14 @@
18903  {
18904         struct addr_change change;
18905         void *output;
18906 +       int n;
18907  
18908         change.what = op;
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",
18913 -                      errno);
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());
18918         if(output == NULL)
18919                 printk("etap_change : Failed to allocate output buffer\n");
18920 @@ -82,15 +83,15 @@
18921         struct etap_pre_exec_data *data = arg;
18922  
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);
18928  }
18929  
18930  static int etap_tramp(char *dev, char *gate, int control_me, 
18931                       int control_remote, int data_me, int data_remote)
18932  {
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);
18942  
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",
18948 -                      errno);
18949 -               return(EINVAL);
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);
18956 +               return(-EINVAL);
18957         }
18958         if(c != 1){
18959                 printk("etap_tramp : uml_net failed\n");
18960 -               err = EINVAL;
18961 -               if(waitpid(pid, &status, 0) < 0) err = errno;
18962 -               else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)){
18963 +               err = -EINVAL;
18964 +               CATCH_EINTR(n = waitpid(pid, &status, 0));
18965 +               if(n < 0)
18966 +                       err = -errno;
18967 +               else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
18968                         printk("uml_net didn't exit with status 1\n");
18969 -               }
18970         }
18971         return(err);
18972  }
18973 @@ -143,14 +145,14 @@
18974         if(err) return(err);
18975  
18976         err = os_pipe(data_fds, 0, 0);
18977 -       if(err){
18978 -               printk("data os_pipe failed - errno = %d\n", -err);
18979 +       if(err < 0){
18980 +               printk("data os_pipe failed - err = %d\n", -err);
18981                 return(err);
18982         }
18983  
18984         err = os_pipe(control_fds, 1, 0);
18985 -       if(err){
18986 -               printk("control os_pipe failed - errno = %d\n", -err);
18987 +       if(err < 0){
18988 +               printk("control os_pipe failed - err = %d\n", -err);
18989                 return(err);
18990         }
18991         
18992 @@ -167,9 +169,9 @@
18993                 kfree(output);
18994         }
18995  
18996 -       if(err != 0){
18997 -               printk("etap_tramp failed - errno = %d\n", err);
18998 -               return(-err);
18999 +       if(err < 0){
19000 +               printk("etap_tramp failed - err = %d\n", -err);
19001 +               return(err);
19002         }
19003  
19004         pri->data_fd = data_fds[0];
19005 @@ -183,11 +185,11 @@
19006         struct ethertap_data *pri = data;
19007  
19008         iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
19009 -       close(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);
19014         pri->data_fd = -1;
19015 -       close(pri->control_fd);
19016 +       os_close_file(pri->control_fd);
19017         pri->control_fd = -1;
19018  }
19019  
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
19024 @@ -11,11 +11,8 @@
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 @@
19037  #include "user.h"
19038  #include "ubd_user.h"
19039  #include "os.h"
19040 +#include "cow.h"
19041  
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)
19050 -#else
19051 -#error "__BYTE_ORDER not defined"
19052 -#endif
19053 -
19054 -#define PATH_LEN_V1 256
19055 -
19056 -struct cow_header_v1 {
19057 -       int magic;
19058 -       int version;
19059 -       char backing_file[PATH_LEN_V1];
19060 -       time_t mtime;
19061 -       __u64 size;
19062 -       int sectorsize;
19063 -};
19064 -
19065 -#define PATH_LEN_V2 MAXPATHLEN
19066 -
19067 -struct cow_header_v2 {
19068 -       unsigned long magic;
19069 -       unsigned long version;
19070 -       char backing_file[PATH_LEN_V2];
19071 -       time_t mtime;
19072 -       __u64 size;
19073 -       int sectorsize;
19074 -};
19075 -
19076 -union cow_header {
19077 -       struct cow_header_v1 v1;
19078 -       struct cow_header_v2 v2;
19079 -};
19080 -
19081 -#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
19082 -#define COW_VERSION 2
19083 -
19084 -static void sizes(__u64 size, int sectorsize, int bitmap_offset, 
19085 -                 unsigned long *bitmap_len_out, int *data_offset_out)
19086 -{
19087 -       *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
19088 -
19089 -       *data_offset_out = bitmap_offset + *bitmap_len_out;
19090 -       *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
19091 -       *data_offset_out *= sectorsize;
19092 -}
19093 -
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)
19097 -{
19098 -       union cow_header *header;
19099 -       char *file;
19100 -       int err, n;
19101 -       unsigned long version, magic;
19102 -
19103 -       header = um_kmalloc(sizeof(*header));
19104 -       if(header == NULL){
19105 -               printk("read_cow_header - Failed to allocate header\n");
19106 -               return(-ENOMEM);
19107 -       }
19108 -       err = -EINVAL;
19109 -       n = read(fd, header, sizeof(*header));
19110 -       if(n < offsetof(typeof(header->v1), backing_file)){
19111 -               printk("read_cow_header - short header\n");
19112 -               goto out;
19113 -       }
19114 -
19115 -       magic = header->v1.magic;
19116 -       if(magic == COW_MAGIC) {
19117 -               version = header->v1.version;
19118 -       }
19119 -       else if(magic == ntohl(COW_MAGIC)){
19120 -               version = ntohl(header->v1.version);
19121 -       }
19122 -       else goto out;
19123 -
19124 -       *magic_out = COW_MAGIC;
19125 -
19126 -       if(version == 1){
19127 -               if(n < sizeof(header->v1)){
19128 -                       printk("read_cow_header - failed to read V1 header\n");
19129 -                       goto out;
19130 -               }
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;
19136 -       }
19137 -       else if(version == 2){
19138 -               if(n < sizeof(header->v2)){
19139 -                       printk("read_cow_header - failed to read V2 header\n");
19140 -                       goto out;
19141 -               }
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;
19147 -       }
19148 -       else {
19149 -               printk("read_cow_header - invalid COW version\n");
19150 -               goto out;
19151 -       }
19152 -       err = -ENOMEM;
19153 -       *backing_file_out = uml_strdup(file);
19154 -       if(*backing_file_out == NULL){
19155 -               printk("read_cow_header - failed to allocate backing file\n");
19156 -               goto out;
19157 -       }
19158 -       err = 0;
19159 - out:
19160 -       kfree(header);
19161 -       return(err);
19162 -}
19163  
19164  static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
19165  {
19166 -       struct stat buf1, buf2;
19167 +       struct uml_stat buf1, buf2;
19168 +       int err;
19169  
19170         if(from_cmdline == NULL) return(1);
19171         if(!strcmp(from_cmdline, from_cow)) return(1);
19172  
19173 -       if(stat(from_cmdline, &buf1) < 0){
19174 -               printk("Couldn't stat '%s', errno = %d\n", from_cmdline, 
19175 -                      errno);
19176 +       err = os_stat_file(from_cmdline, &buf1);
19177 +       if(err < 0){
19178 +               printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
19179                 return(1);
19180         }
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);
19184 +       if(err < 0){
19185 +               printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
19186                 return(1);
19187         }
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))
19190                 return(1);
19191  
19192         printk("Backing file mismatch - \"%s\" requested,\n"
19193 @@ -174,20 +55,21 @@
19194  
19195  static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
19196  {
19197 -       struct stat64 buf;
19198 +       unsigned long modtime;
19199         long long actual;
19200         int err;
19201  
19202 -       if(stat64(file, &buf) < 0){
19203 -               printk("Failed to stat backing file \"%s\", errno = %d\n",
19204 -                      file, errno);
19205 -               return(-errno);
19206 +       err = os_file_modtime(file, &modtime);
19207 +       if(err < 0){
19208 +               printk("Failed to get modification time of backing file "
19209 +                      "\"%s\", err = %d\n", file, -err);
19210 +               return(err);
19211         }
19212  
19213         err = os_file_size(file, &actual);
19214 -       if(err){
19215 +       if(err < 0){
19216                 printk("Failed to get size of backing file \"%s\", "
19217 -                      "errno = %d\n", file, -err);
19218 +                      "err = %d\n", file, -err);
19219                 return(err);
19220         }
19221  
19222 @@ -196,9 +78,9 @@
19223                        "file\n", size, actual);
19224                 return(-EINVAL);
19225         }
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);
19231                 return(-EINVAL);
19232         }
19233         return(0);
19234 @@ -209,124 +91,16 @@
19235         int err;
19236  
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);
19241 -       return(0);
19242 -}
19243 +       if(err < 0) 
19244 +               return(err);
19245  
19246 -static int absolutize(char *to, int size, char *from)
19247 -{
19248 -       char save_cwd[256], *slash;
19249 -       int remaining;
19250 +       err = os_read_file(fd, buf, len);
19251 +       if(err < 0) 
19252 +               return(err);
19253  
19254 -       if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
19255 -               printk("absolutize : unable to get cwd - errno = %d\n", errno);
19256 -               return(-1);
19257 -       }
19258 -       slash = strrchr(from, '/');
19259 -       if(slash != NULL){
19260 -               *slash = '\0';
19261 -               if(chdir(from)){
19262 -                       *slash = '/';
19263 -                       printk("absolutize : Can't cd to '%s' - errno = %d\n",
19264 -                              from, errno);
19265 -                       return(-1);
19266 -               }
19267 -               *slash = '/';
19268 -               if(getcwd(to, size) == NULL){
19269 -                       printk("absolutize : unable to get cwd of '%s' - "
19270 -                              "errno = %d\n", from, errno);
19271 -                       return(-1);
19272 -               }
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);
19277 -                       return(-1);
19278 -               }
19279 -               strcat(to, slash);
19280 -       }
19281 -       else {
19282 -               if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
19283 -                       printk("absolutize : unable to fit '%s' into %d "
19284 -                              "chars\n", from, size);
19285 -                       return(-1);
19286 -               }
19287 -               strcpy(to, save_cwd);
19288 -               strcat(to, "/");
19289 -               strcat(to, from);
19290 -       }
19291 -       chdir(save_cwd);
19292         return(0);
19293  }
19294  
19295 -static int write_cow_header(char *cow_file, int fd, char *backing_file, 
19296 -                           int sectorsize, long long *size)
19297 -{
19298 -        struct cow_header_v2 *header;
19299 -       struct stat64 buf;
19300 -       int err;
19301 -
19302 -       err = os_seek_file(fd, 0);
19303 -       if(err != 0){
19304 -               printk("write_cow_header - lseek failed, errno = %d\n", errno);
19305 -               return(-errno);
19306 -       }
19307 -
19308 -       err = -ENOMEM;
19309 -       header = um_kmalloc(sizeof(*header));
19310 -       if(header == NULL){
19311 -               printk("Failed to allocate COW V2 header\n");
19312 -               goto out;
19313 -       }
19314 -       header->magic = htonl(COW_MAGIC);
19315 -       header->version = htonl(COW_VERSION);
19316 -
19317 -       err = -EINVAL;
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);
19322 -               goto out_free;
19323 -       }
19324 -
19325 -       if(absolutize(header->backing_file, sizeof(header->backing_file), 
19326 -                     backing_file))
19327 -               goto out_free;
19328 -
19329 -       err = stat64(header->backing_file, &buf);
19330 -       if(err < 0){
19331 -               printk("Stat of backing file '%s' failed, errno = %d\n",
19332 -                      header->backing_file, errno);
19333 -               err = -errno;
19334 -               goto out_free;
19335 -       }
19336 -
19337 -       err = os_file_size(header->backing_file, size);
19338 -       if(err){
19339 -               printk("Couldn't get size of backing file '%s', errno = %d\n",
19340 -                      header->backing_file, -*size);
19341 -               goto out_free;
19342 -       }
19343 -
19344 -       header->mtime = htonl(buf.st_mtime);
19345 -       header->size = htonll(*size);
19346 -       header->sectorsize = htonl(sectorsize);
19347 -
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);
19352 -               goto out_free;
19353 -       }
19354 -       err = 0;
19355 - out_free:
19356 -       kfree(header);
19357 - out:
19358 -       return(err);
19359 -}
19360 -
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 @@
19365  {
19366         time_t mtime;
19367         __u64 size;
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;
19372  
19373 -        if((fd = os_open_file(file, *openflags, mode)) < 0){
19374 +       fd = os_open_file(file, *openflags, mode);
19375 +       if(fd < 0){
19376                 if((fd == -ENOENT) && (create_cow_out != NULL))
19377                         *create_cow_out = 1;
19378                  if(!openflags->w ||
19379                     ((errno != EROFS) && (errno != EACCES))) return(-errno);
19380                 openflags->w = 0;
19381 -                if((fd = os_open_file(file, *openflags, mode)) < 0) 
19382 +               fd = os_open_file(file, *openflags, mode); 
19383 +               if(fd < 0) 
19384                         return(fd);
19385          }
19386 +
19387 +       err = os_lock_file(fd, openflags->w);
19388 +       if(err < 0){
19389 +               printk("Failed to lock '%s', err = %d\n", file, -err);
19390 +               goto out_close;
19391 +       }
19392 +       
19393         if(backing_file_out == NULL) return(fd);
19394  
19395 -       err = read_cow_header(fd, &magic, &backing_file, &mtime, &size, 
19396 -                             &sectorsize, bitmap_offset_out);
19397 +       err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
19398 +                             &size, &sectorsize, &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);
19402 -               goto error;
19403 +                      "errno = %d\n", file, -err);
19404 +               goto out_close;
19405         }
19406         if(err) return(fd);
19407  
19408 @@ -363,36 +147,33 @@
19409  
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);
19416                 if(err){
19417 -                       printk("Switch failed, errno = %d\n", err);
19418 +                       printk("Switch failed, errno = %d\n", -err);
19419                         return(err);
19420                 }
19421         }
19422         else {
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;
19427         }
19428  
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);
19433  
19434          return(fd);
19435 - error:
19436 -       close(fd);
19437 + out_close:
19438 +       os_close_file(fd);
19439         return(err);
19440  }
19441  
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)
19446  {
19447 -       __u64 blocks;
19448 -       long zero;
19449 -       int err, fd, i;
19450 -       long long size;
19451 +       int err, fd;
19452  
19453         flags.c = 1;
19454         fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
19455 @@ -403,57 +184,49 @@
19456                 goto out;
19457         }
19458  
19459 -       err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
19460 -       if(err) goto out_close;
19461 -
19462 -       blocks = (size + sectorsize - 1) / sectorsize;
19463 -       blocks = (blocks + sizeof(long) * 8 - 1) / (sizeof(long) * 8);
19464 -       zero = 0;
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);
19470 -                       goto out_close;
19471 -               }
19472 -       }
19473 -
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);
19477 -
19478 -       return(fd);
19479 -
19480 - out_close:
19481 -       close(fd);
19482 +       err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
19483 +                           bitmap_offset_out, bitmap_len_out, 
19484 +                           data_offset_out);
19485 +       if(!err)
19486 +               return(fd);
19487 +       os_close_file(fd);
19488   out:
19489         return(err);
19490  }
19491  
19492 +/* XXX Just trivial wrappers around os_read_file and os_write_file */
19493  int read_ubd_fs(int fd, void *buffer, int len)
19494  {
19495 -       int n;
19496 -
19497 -       n = read(fd, buffer, len);
19498 -       if(n < 0) return(-errno);
19499 -       else return(n);
19500 +       return(os_read_file(fd, buffer, len));
19501  }
19502  
19503  int write_ubd_fs(int fd, char *buffer, int len)
19504  {
19505 -       int n;
19506 -
19507 -       n = write(fd, buffer, len);
19508 -       if(n < 0) return(-errno);
19509 -       else return(n);
19510 +       return(os_write_file(fd, buffer, len));
19511  }
19512  
19513 -int ubd_is_dir(char *file)
19514 +static int update_bitmap(struct io_thread_req *req)
19515  {
19516 -       struct stat64 buf;
19517 +       int n;
19518 +
19519 +       if(req->cow_offset == -1)
19520 +               return(0);
19521 +
19522 +       n = os_seek_file(req->fds[1], req->cow_offset);
19523 +       if(n < 0){
19524 +               printk("do_io - bitmap lseek failed : err = %d\n", -n);
19525 +               return(1);
19526 +       }
19527 +
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,
19532 +                      req->fds[1]);
19533 +               return(1);
19534 +       }
19535  
19536 -       if(stat64(file, &buf) < 0) return(0);
19537 -       return(S_ISDIR(buf.st_mode));
19538 +       return(0);
19539  }
19540  
19541  void do_io(struct io_thread_req *req)
19542 @@ -461,8 +234,18 @@
19543         char *buf;
19544         unsigned long len;
19545         int n, nsectors, start, end, bit;
19546 +       int err;
19547         __u64 off;
19548  
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 
19552 +                */
19553 +               n = *((volatile int *) req->buffer);
19554 +               req->error = update_bitmap(req);
19555 +               return;
19556 +       }
19557 +
19558         nsectors = req->length / req->sectorsize;
19559         start = 0;
19560         do {
19561 @@ -473,15 +256,14 @@
19562                                     &req->sector_mask) == bit))
19563                         end++;
19564  
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];
19571  
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);
19575 +               if(err < 0){
19576 +                       printk("do_io - lseek failed : err = %d\n", -err);
19577                         req->error = 1;
19578                         return;
19579                 }
19580 @@ -490,11 +272,10 @@
19581                         do {
19582                                 buf = &buf[n];
19583                                 len -= n;
19584 -                               n = read(req->fds[bit], buf, len);
19585 +                               n = os_read_file(req->fds[bit], buf, len);
19586                                 if (n < 0) {
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]);
19592                                         req->error = 1;
19593                                         return;
19594                                 }
19595 @@ -502,11 +283,10 @@
19596                         if (n < len) memset(&buf[n], 0, len - n);
19597                 }
19598                 else {
19599 -                       n = write(req->fds[bit], buf, len);
19600 +                       n = os_write_file(req->fds[bit], buf, len);
19601                         if(n != 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]);
19607                                 req->error = 1;
19608                                 return;
19609                         }
19610 @@ -515,24 +295,7 @@
19611                 start = end;
19612         } while(start < nsectors);
19613  
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",
19617 -                              errno);
19618 -                       req->error = 1;
19619 -                       return;
19620 -               }
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]);
19626 -                       req->error = 1;
19627 -                       return;
19628 -               }
19629 -       }
19630 -       req->error = 0;
19631 -       return;
19632 +       req->error = update_bitmap(req);
19633  }
19634  
19635  /* Changed in start_io_thread, which is serialized by being called only
19636 @@ -550,19 +313,23 @@
19637  
19638         signal(SIGWINCH, SIG_IGN);
19639         while(1){
19640 -               n = read(kernel_fd, &req, sizeof(req));
19641 -               if(n < 0) printk("io_thread - read returned %d, errno = %d\n",
19642 -                                n, errno);
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)){
19647 +                       if(n < 0)
19648 +                               printk("io_thread - read failed, fd = %d, "
19649 +                                      "err = %d\n", kernel_fd, -n);
19650 +                       else {
19651 +                               printk("io_thread - short read, fd = %d, "
19652 +                                      "length = %d\n", kernel_fd, n);
19653 +                       }
19654                         continue;
19655                 }
19656                 io_count++;
19657                 do_io(&req);
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",
19662 -                              errno);
19663 +                       printk("io_thread - write failed, fd = %d, err = %d\n",
19664 +                              kernel_fd, -n);
19665         }
19666  }
19667  
19668 @@ -571,10 +338,11 @@
19669         int pid, fds[2], err;
19670  
19671         err = os_pipe(fds, 1, 1);
19672 -       if(err){
19673 -               printk("start_io_thread - os_pipe failed, errno = %d\n", -err);
19674 -               return(-1);
19675 +       if(err < 0){
19676 +               printk("start_io_thread - os_pipe failed, err = %d\n", -err);
19677 +               goto out;
19678         }
19679 +
19680         kernel_fd = fds[0];
19681         *fd_out = fds[1];
19682  
19683 @@ -582,32 +350,19 @@
19684                     NULL);
19685         if(pid < 0){
19686                 printk("start_io_thread - clone failed : errno = %d\n", errno);
19687 -               return(-errno);
19688 +               goto out_close;
19689         }
19690 -       return(pid);
19691 -}
19692 -
19693 -#ifdef notdef
19694 -int start_io_thread(unsigned long sp, int *fd_out)
19695 -{
19696 -       int pid;
19697  
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");
19702 -               return(-1);
19703 -       }
19704 -
19705 -       pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
19706 -                   NULL);
19707 -       if(pid < 0){
19708 -               printk("start_io_thread - clone failed : errno = %d\n", errno);
19709 -               return(-errno);
19710 -       }
19711         return(pid);
19712 +
19713 + out_close:
19714 +       os_close_file(fds[0]);
19715 +       os_close_file(fds[1]);
19716 +       kernel_fd = -1;
19717 +       *fd_out = -1;
19718 + out:
19719 +       return(err);
19720  }
19721 -#endif
19722  
19723  /*
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
19729 @@ -93,6 +93,14 @@
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)
19732   */
19733 +/*
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.
19740 + */
19741  
19742  #include <sys/types.h>
19743  #include <sys/stat.h>
19744 @@ -310,6 +318,7 @@
19745                 }
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);
19751                         do_config_file(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
19756 @@ -6,8 +6,8 @@
19757  #ifndef __UM_PROCESSOR_I386_H
19758  #define __UM_PROCESSOR_I386_H
19759  
19760 -extern int cpu_has_xmm;
19761 -extern int cpu_has_cmov;
19762 +extern int host_has_xmm;
19763 +extern int host_has_cmov;
19764  
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
19771 @@ -4,24 +4,34 @@
19772   */
19773  
19774  #include <stdio.h>
19775 +#include <stdlib.h>
19776  #include <unistd.h>
19777  #include <time.h>
19778  #include <sys/time.h>
19779  #include <signal.h>
19780  #include <errno.h>
19781 -#include "linux/module.h"
19782 +#include <string.h>
19783  #include "user_util.h"
19784  #include "kern_util.h"
19785  #include "user.h"
19786  #include "process.h"
19787  #include "signal_user.h"
19788  #include "time_user.h"
19789 +#include "kern_constants.h"
19790 +
19791 +/* XXX This really needs to be declared and initialized in a kernel file since 
19792 + * it's in <linux/time.h>
19793 + */
19794 +extern struct timespec wall_to_monotonic;
19795  
19796  extern struct timeval xtime;
19797  
19798 +struct timeval local_offset = { 0, 0 };
19799 +
19800  void timer(void)
19801  {
19802         gettimeofday(&xtime, NULL);
19803 +       timeradd(&xtime, &local_offset, &xtime);
19804  }
19805  
19806  void set_interval(int timer_type)
19807 @@ -66,7 +76,7 @@
19808                        errno);
19809  }
19810  
19811 -void idle_timer(void)
19812 +void uml_idle_timer(void)
19813  {
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);
19818  }
19819  
19820 +static unsigned long long get_host_hz(void)
19821 +{
19822 +       char mhzline[16], *end;
19823 +       unsigned long long mhz;
19824 +       int ret, mult, rest, len;
19825 +
19826 +       ret = cpu_feature("cpu MHz", mhzline, 
19827 +                         sizeof(mhzline) / sizeof(mhzline[0]));
19828 +       if(!ret)
19829 +               panic ("Could not get host MHZ");
19830 +
19831 +       mhz = strtoul(mhzline, &end, 10);
19832 +
19833 +       /* This business is to parse a floating point number without using
19834 +        * floating types.
19835 +        */
19836 +
19837 +       rest = 0;
19838 +       mult = 0;
19839 +       if(*end == '.'){
19840 +               end++;
19841 +               len = strlen(end);
19842 +               if(len < 6)
19843 +                       mult = 6 - len;
19844 +               else if(len > 6)
19845 +                       end[6] = '\0';
19846 +               rest = strtoul(end, NULL, 10);
19847 +               while(mult-- > 0)
19848 +                       rest *= 10;
19849 +       }
19850 +
19851 +       return(1000000 * mhz + rest);
19852 +}
19853 +
19854 +unsigned long long host_hz = 0;
19855 +
19856 +extern int do_posix_clock_monotonic_gettime(struct timespec *tp);
19857 +
19858  void time_init(void)
19859  {
19860 +       struct timespec now;
19861
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);
19866 +
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;
19870  }
19871  
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);
19875  
19876  void do_gettimeofday(struct timeval *tv)
19877  {
19878 @@ -96,15 +152,13 @@
19879         clock_was_set();
19880  }
19881  
19882 -EXPORT_SYMBOL(do_gettimeofday);
19883 -
19884  int do_settimeofday(struct timespec *tv)
19885  {
19886         struct timeval now;
19887         unsigned long flags;
19888         struct timeval tv_in;
19889  
19890 -       if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
19891 +       if ((unsigned long) tv->tv_nsec >= UM_NSEC_PER_SEC)
19892                 return -EINVAL;
19893  
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);
19899 -}
19900  
19901 -EXPORT_SYMBOL(do_settimeofday);
19902 +       return(0);
19903 +}
19904  
19905  void idle_sleep(int secs)
19906  {
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
19911 @@ -1,6 +1,6 @@
19912  /*
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
19917   */
19918  
19919 @@ -18,16 +18,18 @@
19920  #include "umid.h"
19921  
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 },
19945  };
19946  
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';
19951                 total -= len;
19952 +               str += len;
19953                 reply.len = len + 1;
19954  
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
19960 @@ -0,0 +1,13 @@
19961 +#ifndef __UM_MODULE_I386_H
19962 +#define __UM_MODULE_I386_H
19963 +
19964 +/* UML is simple */
19965 +struct mod_arch_specific
19966 +{
19967 +};
19968 +
19969 +#define Elf_Shdr Elf32_Shdr
19970 +#define Elf_Sym Elf32_Sym
19971 +#define Elf_Ehdr Elf32_Ehdr
19972 +
19973 +#endif
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)
19980  {
19981         unsigned long ip;
19982 -       int err, pid;
19983 +       int pid;
19984  
19985         pid = debugger->pid;
19986 +
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);
19991 +
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);
19996 +
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, "
20002 -                            "errno = %d\n");
20003 +                            "errno = %d\n", errno);
20004         return(0);
20005  }
20006  
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
20011 @@ -1,3 +1,5 @@
20012 +#include <asm-generic/vmlinux.lds.h>
20013 +
20014    .fini      : { *(.fini)    } =0x9090
20015    _etext = .;
20016    PROVIDE (etext = .);
20017 @@ -13,18 +15,6 @@
20018  
20019    RODATA
20020  
20021 -  __start___ksymtab = .;       /* Kernel symbol table */
20022 -  __ksymtab : { *(__ksymtab) }
20023 -  __stop___ksymtab = .;
20024 -
20025 -  __start___gpl_ksymtab = .;   /* Kernel symbol table: GPL-only symbols */
20026 -  __gpl_ksymtab : { *(__gpl_ksymtab) }
20027 -  __stop___gpl_ksymtab = .;
20028 -
20029 -  __start___kallsyms = .;       /* All kernel symbols */
20030 -  __kallsyms : { *(__kallsyms) }
20031 -  __stop___kallsyms = .;
20032 -
20033    .unprotected : { *(.unprotected) }
20034    . = ALIGN(4096);
20035    PROVIDE (_unprotected_end = .);
20036 @@ -67,11 +57,17 @@
20037    }
20038    __initcall_end = .;
20039  
20040 +  __con_initcall_start = .;
20041 +  .con_initcall.init : { *(.con_initcall.init) }
20042 +  __con_initcall_end = .;
20043 +
20044    __uml_initcall_start = .;
20045    .uml.initcall.init : { *(.uml.initcall.init) }
20046    __uml_initcall_end = .;
20047    __init_end = .;
20048  
20049 +  SECURITY_INIT
20050 +
20051    __exitcall_begin = .;
20052    .exitcall : { *(.exitcall.exit) }
20053    __exitcall_end = .;
20054 @@ -80,7 +76,33 @@
20055    .uml.exitcall : { *(.uml.exitcall.exit) }
20056    __uml_exitcall_end = .;
20057  
20058 -  . = ALIGN(4096);
20059 +  . = ALIGN(4);
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) }
20068
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 = .;
20078 +
20079 +   . = ALIGN(4096);
20080    __initramfs_start = .;
20081    .init.ramfs : { *(.init.ramfs) }
20082    __initramfs_end = .;
20083 +
20084 +  /* Sections to be discarded */
20085 +  /DISCARD/ : {
20086 +       *(.exitcall.exit)
20087 +  }
20088
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
20093 @@ -1,149 +0,0 @@
20094 -/* 
20095 - * Copyright (C) 2002 Steve Schmidtke 
20096 - * Licensed under the GPL
20097 - */
20098 -
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"
20108 -#include "user.h"
20109 -#include "os.h"
20110 -
20111 -/* /dev/dsp file operations */
20112 -
20113 -ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer, 
20114 -                           size_t count, loff_t *ppos)
20115 -{
20116 -       ssize_t ret;
20117 -
20118 -#ifdef DEBUG
20119 -        printk("hostaudio: read_user called, count = %d\n", count);
20120 -#endif
20121 -
20122 -        ret = read(state->fd, buffer, count);
20123 -
20124 -        if(ret < 0) return(-errno);
20125 -        return(ret);
20126 -}
20127 -
20128 -ssize_t hostaudio_write_user(struct hostaudio_state *state, const char *buffer,
20129 -                            size_t count, loff_t *ppos)
20130 -{
20131 -       ssize_t ret;
20132 -
20133 -#ifdef DEBUG
20134 -        printk("hostaudio: write_user called, count = %d\n", count);
20135 -#endif
20136 -
20137 -        ret = write(state->fd, buffer, count);
20138 -
20139 -        if(ret < 0) return(-errno);
20140 -        return(ret);
20141 -}
20142 -
20143 -int hostaudio_ioctl_user(struct hostaudio_state *state, unsigned int cmd, 
20144 -                        unsigned long arg)
20145 -{
20146 -       int ret;
20147 -#ifdef DEBUG
20148 -        printk("hostaudio: ioctl_user called, cmd = %u\n", cmd);
20149 -#endif
20150 -
20151 -        ret = ioctl(state->fd, cmd, arg);
20152 -       
20153 -        if(ret < 0) return(-errno);
20154 -        return(ret);
20155 -}
20156 -
20157 -int hostaudio_open_user(struct hostaudio_state *state, int r, int w, char *dsp)
20158 -{
20159 -#ifdef DEBUG
20160 -        printk("hostaudio: open_user called\n");
20161 -#endif
20162 -
20163 -        state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
20164 -
20165 -        if(state->fd >= 0) return(0);
20166 -
20167 -        printk("hostaudio_open_user failed to open '%s', errno = %d\n",
20168 -              dsp, errno);
20169 -        
20170 -        return(-errno); 
20171 -}
20172 -
20173 -int hostaudio_release_user(struct hostaudio_state *state)
20174 -{
20175 -#ifdef DEBUG
20176 -        printk("hostaudio: release called\n");
20177 -#endif
20178 -        if(state->fd >= 0){
20179 -               close(state->fd);
20180 -               state->fd=-1;
20181 -        }
20182 -
20183 -        return(0);
20184 -}
20185 -
20186 -/* /dev/mixer file operations */
20187 -
20188 -int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state, 
20189 -                               unsigned int cmd, unsigned long arg)
20190 -{
20191 -       int ret;
20192 -#ifdef DEBUG
20193 -        printk("hostmixer: ioctl_user called cmd = %u\n",cmd);
20194 -#endif
20195 -
20196 -        ret = ioctl(state->fd, cmd, arg);
20197 -       if(ret < 0) 
20198 -               return(-errno);
20199 -       return(ret);
20200 -}
20201 -
20202 -int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, int w,
20203 -                              char *mixer)
20204 -{
20205 -#ifdef DEBUG
20206 -        printk("hostmixer: open_user called\n");
20207 -#endif
20208 -
20209 -        state->fd = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
20210 -
20211 -        if(state->fd >= 0) return(0);
20212 -
20213 -        printk("hostaudio_open_mixdev_user failed to open '%s', errno = %d\n",
20214 -              mixer, errno);
20215 -        
20216 -        return(-errno); 
20217 -}
20218 -
20219 -int hostmixer_release_mixdev_user(struct hostmixer_state *state)
20220 -{
20221 -#ifdef DEBUG
20222 -        printk("hostmixer: release_user called\n");
20223 -#endif
20224 -
20225 -        if(state->fd >= 0){
20226 -               close(state->fd);
20227 -               state->fd = -1;
20228 -        }
20229 -
20230 -        return 0;
20231 -}
20232 -
20233 -/*
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
20237 - * of the file.
20238 - * ---------------------------------------------------------------------------
20239 - * Local variables:
20240 - * c-file-style: "linux"
20241 - * End:
20242 - */
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 @@
20248         return(HZ);
20249  }
20250  
20251 +/*
20252 + * Scheduler clock - returns current time in nanosec units.
20253 + */
20254 +unsigned long long sched_clock(void)
20255 +{
20256 +       return (unsigned long long)jiffies_64 * (1000000000 / HZ);
20257 +}
20258 +
20259  /* Changed at early boot */
20260  int timer_irq_inited = 0;
20261  
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 
20264 - * write-enabled.
20265 - */
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 */
20271 +#endif
20272 +
20273 +extern unsigned long long host_hz;
20274  
20275  void timer_irq(union uml_pt_regs *regs)
20276  {
20277 -       int cpu = current->thread_info->cpu, ticks = missed_ticks[cpu];
20278 +       unsigned long long ticks = 0;
20279 +
20280 +       if(!timer_irq_inited){
20281 +               /* This is to ensure that ticks don't pile up when
20282 +                * the timer handler is suspended */
20283 +               first_tick = 0;
20284 +               return;
20285 +       }
20286  
20287 -        if(!timer_irq_inited) return;
20288 -       missed_ticks[cpu] = 0;
20289 -       while(ticks--) do_IRQ(TIMER_IRQ, regs);
20290 +       if(first_tick){
20291 +#ifdef CONFIG_UML_REAL_TIME_CLOCK
20292 +               unsigned long long tsc;
20293 +               /* We've had 1 tick */
20294 +               tsc = time_stamp();
20295 +
20296 +               delta += tsc - prev_tsc;
20297 +               prev_tsc = tsc;
20298 +
20299 +               ticks += (delta * HZ) / host_hz;
20300 +               delta -= (ticks * host_hz) / HZ;
20301 +#else
20302 +               ticks = 1;
20303 +#endif
20304 +       }
20305 +       else {
20306 +               prev_tsc = time_stamp();
20307 +               first_tick = 1;
20308 +       }
20309 +
20310 +       while(ticks > 0){
20311 +               do_IRQ(TIMER_IRQ, regs);
20312 +               ticks--;
20313 +       }
20314  }
20315  
20316  void boot_timer_handler(int sig)
20317 @@ -58,12 +96,15 @@
20318         do_timer(&regs);
20319  }
20320  
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)
20323  {
20324 +       unsigned long flags;
20325 +
20326         do_timer(regs);
20327 -       write_seqlock(&xtime_lock);
20328 +       write_seqlock_irqsave(&xtime_lock, flags);
20329         timer();
20330 -       write_sequnlock(&xtime_lock);
20331 +       write_sequnlock_irqrestore(&xtime_lock, flags);
20332 +       return(IRQ_HANDLED);
20333  }
20334  
20335  long um_time(int * tloc)
20336 @@ -81,12 +122,12 @@
20337  long um_stime(int * tptr)
20338  {
20339         int value;
20340 -       struct timeval new;
20341 +       struct timespec new;
20342  
20343         if (get_user(value, tptr))
20344                  return -EFAULT;
20345         new.tv_sec = value;
20346 -       new.tv_usec = 0;
20347 +       new.tv_nsec = 0;
20348         do_settimeofday(&new);
20349         return 0;
20350  }
20351 @@ -125,9 +166,11 @@
20352  void timer_handler(int sig, union uml_pt_regs *regs)
20353  {
20354  #ifdef CONFIG_SMP
20355 +       local_irq_disable();
20356         update_process_times(user_context(UPT_SP(regs)));
20357 +       local_irq_enable();
20358  #endif
20359 -       if(current->thread_info->cpu == 0)
20360 +       if(current_thread->cpu == 0)
20361                 timer_irq(regs);
20362  }
20363  
20364 @@ -136,6 +179,7 @@
20365  unsigned long time_lock(void)
20366  {
20367         unsigned long flags;
20368 +
20369         spin_lock_irqsave(&timer_spinlock, flags);
20370         return(flags);
20371  }
20372 @@ -150,8 +194,8 @@
20373         int err;
20374  
20375         CHOOSE_MODE(user_time_init_tt(), user_time_init_skas());
20376 -       if((err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", 
20377 -                             NULL)) != 0)
20378 +       err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL);
20379 +       if(err != 0)
20380                 printk(KERN_ERR "timer_init : request_irq failed - "
20381                        "errno = %d\n", -err);
20382         timer_irq_inited = 1;
20383 @@ -160,7 +204,6 @@
20384  
20385  __initcall(timer_init);
20386  
20387 -
20388  /*
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