Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / kernel_patches / patches / uml-2.6.10-fc3.patch
1 Index: linux-2.6.10/lib/Kconfig.debug
2 ===================================================================
3 --- linux-2.6.10.orig/lib/Kconfig.debug 2004-12-25 05:35:24.000000000 +0800
4 +++ linux-2.6.10/lib/Kconfig.debug      2005-04-06 23:44:30.189033160 +0800
5 @@ -23,7 +23,6 @@
6  config MAGIC_SYSRQ
7         bool "Magic SysRq key"
8         depends on DEBUG_KERNEL && (H8300 || M68KNOMMU || V850)
9 -       depends (USERMODE && MCONSOLE)
10         help
11           Enables console device to interpret special characters as
12           commands to dump state information.
13 Index: linux-2.6.10/mm/mprotect.c
14 ===================================================================
15 --- linux-2.6.10.orig/mm/mprotect.c     2004-12-25 05:35:50.000000000 +0800
16 +++ linux-2.6.10/mm/mprotect.c  2005-04-06 23:44:30.204030880 +0800
17 @@ -93,19 +93,20 @@
18  {
19         pgd_t *dir;
20         unsigned long beg = start;
21 +       struct mm_struct * mm = vma->vm_mm;
22  
23 -       dir = pgd_offset(current->mm, start);
24 +       dir = pgd_offset(mm, start);
25         flush_cache_range(vma, beg, end);
26         if (start >= end)
27                 BUG();
28 -       spin_lock(&current->mm->page_table_lock);
29 +       spin_lock(&mm->page_table_lock);
30         do {
31                 change_pmd_range(dir, start, end - start, newprot);
32                 start = (start + PGDIR_SIZE) & PGDIR_MASK;
33                 dir++;
34         } while (start && (start < end));
35         flush_tlb_range(vma, beg, end);
36 -       spin_unlock(&current->mm->page_table_lock);
37 +       spin_unlock(&mm->page_table_lock);
38         return;
39  }
40  
41 @@ -190,8 +191,9 @@
42         return error;
43  }
44  
45 -asmlinkage long
46 -sys_mprotect(unsigned long start, size_t len, unsigned long prot)
47 +long
48 +do_mprotect(struct mm_struct *mm, unsigned long start, size_t len,
49 +            unsigned long prot)
50  {
51         unsigned long vm_flags, nstart, end, tmp;
52         struct vm_area_struct *vma, *prev;
53 @@ -220,9 +222,9 @@
54  
55         vm_flags = calc_vm_prot_bits(prot);
56  
57 -       down_write(&current->mm->mmap_sem);
58 +       down_write(&mm->mmap_sem);
59  
60 -       vma = find_vma_prev(current->mm, start, &prev);
61 +       vma = find_vma_prev(mm, start, &prev);
62         error = -ENOMEM;
63         if (!vma)
64                 goto out;
65 @@ -288,6 +290,11 @@
66                 }
67         }
68  out:
69 -       up_write(&current->mm->mmap_sem);
70 +       up_write(&mm->mmap_sem);
71         return error;
72  }
73 +
74 +asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
75 +{
76 +        return(do_mprotect(current->mm, start, len, prot));
77 +}
78 Index: linux-2.6.10/mm/mmap.c
79 ===================================================================
80 --- linux-2.6.10.orig/mm/mmap.c 2005-04-06 23:38:33.000000000 +0800
81 +++ linux-2.6.10/mm/mmap.c      2005-04-06 23:44:30.193032552 +0800
82 @@ -759,11 +759,11 @@
83   * The caller must hold down_write(current->mm->mmap_sem).
84   */
85  
86 -unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
87 -                       unsigned long len, unsigned long prot,
88 -                       unsigned long flags, unsigned long pgoff)
89 +unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file * file,
90 +                           unsigned long addr, unsigned long len,
91 +                           unsigned long prot, unsigned long flags,
92 +                           unsigned long pgoff)
93  {
94 -       struct mm_struct * mm = current->mm;
95         struct vm_area_struct * vma, * prev;
96         struct inode *inode;
97         unsigned int vm_flags;
98 @@ -1037,7 +1037,7 @@
99         return error;
100  }
101  
102 -EXPORT_SYMBOL(do_mmap_pgoff);
103 +EXPORT_SYMBOL(__do_mmap_pgoff);
104  
105  /* Get an address range which is currently unmapped.
106   * For shmat() with addr=0.
107 Index: linux-2.6.10/mm/proc_mm.c
108 ===================================================================
109 --- linux-2.6.10.orig/mm/proc_mm.c      2005-04-07 06:37:43.373923992 +0800
110 +++ linux-2.6.10/mm/proc_mm.c   2005-04-06 23:44:30.204030880 +0800
111 @@ -0,0 +1,181 @@
112 +/*
113 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
114 + * Licensed under the GPL
115 + */
116 +
117 +#include "linux/mm.h"
118 +#include "linux/init.h"
119 +#include "linux/proc_fs.h"
120 +#include "linux/proc_mm.h"
121 +#include "linux/file.h"
122 +#include "linux/mman.h"
123 +#include "asm/uaccess.h"
124 +#include "asm/mmu_context.h"
125 +
126 +static struct file_operations proc_mm_fops;
127 +
128 +struct mm_struct *proc_mm_get_mm(int fd)
129 +{
130 +       struct mm_struct *ret = ERR_PTR(-EBADF);
131 +       struct file *file;
132 +
133 +       file = fget(fd);
134 +       if (!file)
135 +               goto out;
136 +
137 +       ret = ERR_PTR(-EINVAL);
138 +       if(file->f_op != &proc_mm_fops)
139 +               goto out_fput;
140 +
141 +       ret = file->private_data;
142 + out_fput:
143 +       fput(file);
144 + out:
145 +       return(ret);
146 +}
147 +
148 +extern long do_mmap2(struct mm_struct *mm, unsigned long addr,
149 +                    unsigned long len, unsigned long prot,
150 +                    unsigned long flags, unsigned long fd,
151 +                    unsigned long pgoff);
152 +
153 +static ssize_t write_proc_mm(struct file *file, const char *buffer,
154 +                            size_t count, loff_t *ppos)
155 +{
156 +       struct mm_struct *mm = file->private_data;
157 +       struct proc_mm_op req;
158 +       int n, ret;
159 +
160 +       if(count > sizeof(req))
161 +               return(-EINVAL);
162 +
163 +       n = copy_from_user(&req, buffer, count);
164 +       if(n != 0)
165 +               return(-EFAULT);
166 +
167 +       ret = count;
168 +       switch(req.op){
169 +       case MM_MMAP: {
170 +               struct mm_mmap *map = &req.u.mmap;
171 +
172 +               /* Nobody ever noticed it, but do_mmap_pgoff() calls
173 +                * get_unmapped_area() which checks current->mm, if
174 +                * MAP_FIXED is not set, so mmap() could replace
175 +                * an old mapping.
176 +                */
177 +               if (! (map->flags & MAP_FIXED))
178 +                       return(-EINVAL);
179 +
180 +               ret = do_mmap2(mm, map->addr, map->len, map->prot,
181 +                              map->flags, map->fd, map->offset >> PAGE_SHIFT);
182 +               if((ret & ~PAGE_MASK) == 0)
183 +                       ret = count;
184 +
185 +               break;
186 +       }
187 +       case MM_MUNMAP: {
188 +               struct mm_munmap *unmap = &req.u.munmap;
189 +
190 +               down_write(&mm->mmap_sem);
191 +               ret = do_munmap(mm, unmap->addr, unmap->len);
192 +               up_write(&mm->mmap_sem);
193 +
194 +               if(ret == 0)
195 +                       ret = count;
196 +               break;
197 +       }
198 +       case MM_MPROTECT: {
199 +               struct mm_mprotect *protect = &req.u.mprotect;
200 +
201 +               ret = do_mprotect(mm, protect->addr, protect->len,
202 +                                 protect->prot);
203 +               if(ret == 0)
204 +                       ret = count;
205 +               break;
206 +       }
207 +
208 +       case MM_COPY_SEGMENTS: {
209 +               struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
210 +
211 +               if(IS_ERR(from)){
212 +                       ret = PTR_ERR(from);
213 +                       break;
214 +               }
215 +
216 +               ret = copy_context(mm, from);
217 +               if(ret == 0)
218 +                       ret = count;
219 +               break;
220 +       }
221 +       default:
222 +               ret = -EINVAL;
223 +               break;
224 +       }
225 +
226 +       return(ret);
227 +}
228 +
229 +static int open_proc_mm(struct inode *inode, struct file *file)
230 +{
231 +       struct mm_struct *mm = mm_alloc();
232 +       int ret;
233 +
234 +       ret = -ENOMEM;
235 +       if(mm == NULL)
236 +               goto out_mem;
237 +
238 +       init_new_empty_context(mm);
239 +       arch_pick_mmap_layout(mm);
240 +
241 +       spin_lock(&mmlist_lock);
242 +       list_add(&mm->mmlist, &current->mm->mmlist);
243 +       spin_unlock(&mmlist_lock);
244 +
245 +       file->private_data = mm;
246 +
247 +       return(0);
248 +
249 + out_mem:
250 +       return(ret);
251 +}
252 +
253 +static int release_proc_mm(struct inode *inode, struct file *file)
254 +{
255 +       struct mm_struct *mm = file->private_data;
256 +
257 +       mmput(mm);
258 +       return(0);
259 +}
260 +
261 +static struct file_operations proc_mm_fops = {
262 +       .open           = open_proc_mm,
263 +       .release        = release_proc_mm,
264 +       .write          = write_proc_mm,
265 +};
266 +
267 +static int make_proc_mm(void)
268 +{
269 +       struct proc_dir_entry *ent;
270 +
271 +       ent = create_proc_entry("mm", 0222, &proc_root);
272 +       if(ent == NULL){
273 +               printk("make_proc_mm : Failed to register /proc/mm\n");
274 +               return(0);
275 +       }
276 +       ent->proc_fops = &proc_mm_fops;
277 +
278 +       return(0);
279 +}
280 +
281 +__initcall(make_proc_mm);
282 +
283 +/*
284 + * Overrides for Emacs so that we follow Linus's tabbing style.
285 + * Emacs will notice this stuff at the end of the file and automatically
286 + * adjust the settings for this buffer only.  This must remain at the end
287 + * of the file.
288 + * ---------------------------------------------------------------------------
289 + * Local variables:
290 + * c-file-style: "linux"
291 + * End:
292 + */
293 Index: linux-2.6.10/mm/Makefile
294 ===================================================================
295 --- linux-2.6.10.orig/mm/Makefile       2004-12-25 05:35:00.000000000 +0800
296 +++ linux-2.6.10/mm/Makefile    2005-04-06 23:44:30.205030728 +0800
297 @@ -18,3 +18,4 @@
298  obj-$(CONFIG_SHMEM) += shmem.o
299  obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
300  
301 +obj-$(CONFIG_PROC_MM)  += proc_mm.o
302 Index: linux-2.6.10/arch/um/drivers/mconsole_kern.c
303 ===================================================================
304 --- linux-2.6.10.orig/arch/um/drivers/mconsole_kern.c   2004-12-25 05:33:49.000000000 +0800
305 +++ linux-2.6.10/arch/um/drivers/mconsole_kern.c        2005-04-06 23:44:30.283018872 +0800
306 @@ -204,6 +204,68 @@
307  }
308  #endif
309  
310 +/* This is a more convoluted version of mconsole_proc, which has some stability
311 + * problems; however, we need it fixed, because it is expected that UML users
312 + * mount HPPFS instead of procfs on /proc. And we want mconsole_proc to still
313 + * show the real procfs content, not the ones from hppfs.*/
314 +#if 0
315 +void mconsole_proc(struct mc_request *req)
316 +{
317 +       char path[64];
318 +       char *buf;
319 +       int len;
320 +       int fd;
321 +       int first_chunk = 1;
322 +       char *ptr = req->request.data;
323 +
324 +       ptr += strlen("proc");
325 +       while(isspace(*ptr)) ptr++;
326 +       snprintf(path, sizeof(path), "/proc/%s", ptr);
327 +
328 +       fd = sys_open(path, 0, 0);
329 +       if (fd < 0) {
330 +               mconsole_reply(req, "Failed to open file", 1, 0);
331 +               printk("open %s: %d\n",path,fd);
332 +               goto out;
333 +       }
334 +
335 +       buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
336 +       if(buf == NULL){
337 +               mconsole_reply(req, "Failed to allocate buffer", 1, 0);
338 +               goto out_close;
339 +       }
340 +
341 +       for (;;) {
342 +               len = sys_read(fd, buf, PAGE_SIZE-1);
343 +               if (len < 0) {
344 +                       mconsole_reply(req, "Read of file failed", 1, 0);
345 +                       goto out_free;
346 +               }
347 +               /*Begin the file content on his own line.*/
348 +               if (first_chunk) {
349 +                       mconsole_reply(req, "\n", 0, 1);
350 +                       first_chunk = 0;
351 +               }
352 +               if (len == PAGE_SIZE-1) {
353 +                       buf[len] = '\0';
354 +                       mconsole_reply(req, buf, 0, 1);
355 +               } else {
356 +                       buf[len] = '\0';
357 +                       mconsole_reply(req, buf, 0, 0);
358 +                       break;
359 +               }
360 +       }
361 +       /*END*/
362 +
363 + out_free:
364 +       kfree(buf);
365 + out_close:
366 +       sys_close(fd);
367 + out:
368 +       /* nothing */;
369 +}
370 +#endif
371 +
372  void mconsole_proc(struct mc_request *req)
373  {
374         char path[64];
375 Index: linux-2.6.10/arch/um/drivers/net_kern.c
376 ===================================================================
377 --- linux-2.6.10.orig/arch/um/drivers/net_kern.c        2004-12-25 05:34:44.000000000 +0800
378 +++ linux-2.6.10/arch/um/drivers/net_kern.c     2005-04-06 23:44:30.282019024 +0800
379 @@ -126,10 +126,6 @@
380         lp->tl.data = (unsigned long) &lp->user;
381         netif_start_queue(dev);
382  
383 -       spin_lock(&opened_lock);
384 -       list_add(&lp->list, &opened);
385 -       spin_unlock(&opened_lock);
386 -
387         /* clear buffer - it can happen that the host side of the interface
388          * is full when we get here.  In this case, new data is never queued,
389          * SIGIOs never arrive, and the net never works.
390 @@ -152,9 +148,6 @@
391         free_irq(dev->irq, dev);
392         if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
393         lp->fd = -1;
394 -       spin_lock(&opened_lock);
395 -       list_del(&lp->list);
396 -       spin_unlock(&opened_lock);
397  
398         spin_unlock(&lp->lock);
399         return 0;
400 @@ -397,6 +390,11 @@
401  
402         if (device->have_mac)
403                 set_ether_mac(dev, device->mac);
404 +
405 +       spin_lock(&opened_lock);
406 +       list_add(&lp->list, &opened);
407 +       spin_unlock(&opened_lock);
408 +
409         return(0);
410  }
411  
412 @@ -705,7 +703,7 @@
413  static void close_devices(void)
414  {
415         struct list_head *ele;
416 -       struct uml_net_private *lp;     
417 +       struct uml_net_private *lp;
418  
419         list_for_each(ele, &opened){
420                 lp = list_entry(ele, struct uml_net_private, list);
421 Index: linux-2.6.10/arch/um/drivers/net_user.c
422 ===================================================================
423 --- linux-2.6.10.orig/arch/um/drivers/net_user.c        2004-12-25 05:34:26.000000000 +0800
424 +++ linux-2.6.10/arch/um/drivers/net_user.c     2005-04-06 23:44:30.284018720 +0800
425 @@ -173,10 +173,12 @@
426         pe_data.stdout = fds[1];
427         pid = run_helper(change_pre_exec, &pe_data, argv, NULL);
428  
429 -       os_close_file(fds[1]);
430         read_output(fds[0], output, output_len);
431 +       os_close_file(fds[0]);
432 +       os_close_file(fds[1]);
433  
434 -       CATCH_EINTR(err = waitpid(pid, NULL, 0));
435 +       if (pid > 0)
436 +               CATCH_EINTR(err = waitpid(pid, NULL, 0));
437         return(pid);
438  }
439  
440 Index: linux-2.6.10/arch/um/os-Linux/elf_aux.c
441 ===================================================================
442 --- linux-2.6.10.orig/arch/um/os-Linux/elf_aux.c        2005-04-07 06:37:43.373923992 +0800
443 +++ linux-2.6.10/arch/um/os-Linux/elf_aux.c     2005-04-06 23:44:30.280019328 +0800
444 @@ -0,0 +1,67 @@
445 +/*
446 + *  arch/um/kernel/elf_aux.c
447 + *
448 + *  Scan the Elf auxiliary vector provided by the host to extract
449 + *  information about vsyscall-page, etc.
450 + *
451 + *  Copyright (C) 2004 Fujitsu Siemens Computers GmbH
452 + *  Author: Bodo Stroesser (bodo.stroesser@fujitsu-siemens.com)
453 + */
454 +#include <elf.h>
455 +#include <stddef.h>
456 +#include "init.h"
457 +#include "elf_user.h"
458 +
459 +#if ELF_CLASS == ELFCLASS32
460 +typedef Elf32_auxv_t elf_auxv_t;
461 +#else
462 +typedef Elf64_auxv_t elf_auxv_t;
463 +#endif
464 +
465 +char * elf_aux_platform;
466 +long elf_aux_hwcap;
467 +
468 +unsigned long vsyscall_ehdr;
469 +unsigned long vsyscall_end;
470 +
471 +unsigned long __kernel_vsyscall;
472 +
473 +
474 +__init void scan_elf_aux( char **envp)
475 +{
476 +       long page_size = 0;
477 +       elf_auxv_t * auxv;
478 +
479 +       while ( *envp++ != NULL) ;
480 +
481 +       for ( auxv = (elf_auxv_t *)envp; auxv->a_type != AT_NULL; auxv++) {
482 +               switch ( auxv->a_type ) {
483 +                       case AT_SYSINFO:
484 +                               __kernel_vsyscall = auxv->a_un.a_val;
485 +                               break;
486 +                       case AT_SYSINFO_EHDR:
487 +                               vsyscall_ehdr = auxv->a_un.a_val;
488 +                               break;
489 +                       case AT_HWCAP:
490 +                               elf_aux_hwcap = auxv->a_un.a_val;
491 +                               break;
492 +                       case AT_PLATFORM:
493 +                               elf_aux_platform = auxv->a_un.a_ptr;
494 +                               break;
495 +                       case AT_PAGESZ:
496 +                               page_size = auxv->a_un.a_val;
497 +                               break;
498 +               }
499 +       }
500 +       if ( ! __kernel_vsyscall || ! vsyscall_ehdr ||
501 +            ! elf_aux_hwcap || ! elf_aux_platform ||
502 +            ! page_size || (vsyscall_ehdr % page_size) ) {
503 +               __kernel_vsyscall = 0;
504 +               vsyscall_ehdr = 0;
505 +               elf_aux_hwcap = 0;
506 +               elf_aux_platform = "i586";
507 +       }
508 +       else {
509 +               vsyscall_end = vsyscall_ehdr + page_size;
510 +       }
511 +}
512 Index: linux-2.6.10/arch/um/os-Linux/user_syms.c
513 ===================================================================
514 --- linux-2.6.10.orig/arch/um/os-Linux/user_syms.c      2004-12-25 05:35:23.000000000 +0800
515 +++ linux-2.6.10/arch/um/os-Linux/user_syms.c   2005-04-06 23:44:30.279019480 +0800
516 @@ -26,6 +26,9 @@
517  
518  EXPORT_SYMBOL(strstr);
519  
520 +EXPORT_SYMBOL(vsyscall_ehdr);
521 +EXPORT_SYMBOL(vsyscall_end);
522 +
523  /* Here, instead, I can provide a fake prototype. Yes, someone cares: genksyms.
524   * However, the modules will use the CRC defined *here*, no matter if it is
525   * good; so the versions of these symbols will always match
526 Index: linux-2.6.10/arch/um/os-Linux/Makefile
527 ===================================================================
528 --- linux-2.6.10.orig/arch/um/os-Linux/Makefile 2004-12-25 05:35:00.000000000 +0800
529 +++ linux-2.6.10/arch/um/os-Linux/Makefile      2005-04-06 23:44:30.281019176 +0800
530 @@ -3,9 +3,9 @@
531  # Licensed under the GPL
532  #
533  
534 -obj-y = file.o process.o time.o tty.o user_syms.o drivers/
535 +obj-y = elf_aux.o file.o process.o time.o tty.o user_syms.o drivers/
536  
537 -USER_OBJS := $(foreach file,file.o process.o time.o tty.o,$(obj)/$(file))
538 +USER_OBJS := $(foreach file,elf_aux.o file.o process.o time.o tty.o,$(obj)/$(file))
539  
540  $(USER_OBJS) : %.o: %.c
541         $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
542 Index: linux-2.6.10/arch/um/sys-i386/signal.c
543 ===================================================================
544 --- linux-2.6.10.orig/arch/um/sys-i386/signal.c 2005-04-07 06:37:43.373923992 +0800
545 +++ linux-2.6.10/arch/um/sys-i386/signal.c      2005-04-06 23:44:30.236026016 +0800
546 @@ -0,0 +1,374 @@
547 +/*
548 + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
549 + * Licensed under the GPL
550 + */
551 +
552 +#include "linux/signal.h"
553 +#include "linux/ptrace.h"
554 +#include "asm/current.h"
555 +#include "asm/ucontext.h"
556 +#include "asm/uaccess.h"
557 +#include "asm/unistd.h"
558 +#include "frame_kern.h"
559 +#include "signal_user.h"
560 +#include "ptrace_user.h"
561 +#include "sigcontext.h"
562 +#include "mode.h"
563 +
564 +#ifdef CONFIG_MODE_SKAS
565 +
566 +#include "skas.h"
567 +
568 +static int copy_sc_from_user_skas(struct pt_regs *regs,
569 +                                 struct sigcontext *from)
570 +{
571 +       struct sigcontext sc;
572 +       unsigned long fpregs[HOST_FP_SIZE];
573 +       int err;
574 +
575 +       err = copy_from_user(&sc, from, sizeof(sc));
576 +       err |= copy_from_user(fpregs, sc.fpstate, sizeof(fpregs));
577 +       if(err)
578 +               return(err);
579 +
580 +       REGS_GS(regs->regs.skas.regs) = sc.gs;
581 +       REGS_FS(regs->regs.skas.regs) = sc.fs;
582 +       REGS_ES(regs->regs.skas.regs) = sc.es;
583 +       REGS_DS(regs->regs.skas.regs) = sc.ds;
584 +       REGS_EDI(regs->regs.skas.regs) = sc.edi;
585 +       REGS_ESI(regs->regs.skas.regs) = sc.esi;
586 +       REGS_EBP(regs->regs.skas.regs) = sc.ebp;
587 +       REGS_SP(regs->regs.skas.regs) = sc.esp;
588 +       REGS_EBX(regs->regs.skas.regs) = sc.ebx;
589 +       REGS_EDX(regs->regs.skas.regs) = sc.edx;
590 +       REGS_ECX(regs->regs.skas.regs) = sc.ecx;
591 +       REGS_EAX(regs->regs.skas.regs) = sc.eax;
592 +       REGS_IP(regs->regs.skas.regs) = sc.eip;
593 +       REGS_CS(regs->regs.skas.regs) = sc.cs;
594 +       REGS_EFLAGS(regs->regs.skas.regs) = sc.eflags;
595 +       REGS_SS(regs->regs.skas.regs) = sc.ss;
596 +       regs->regs.skas.fault_addr = sc.cr2;
597 +       regs->regs.skas.fault_type = FAULT_WRITE(sc.err);
598 +       regs->regs.skas.trap_type = sc.trapno;
599 +
600 +       err = ptrace_setfpregs(userspace_pid[0], fpregs);
601 +       if(err < 0){
602 +               printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, "
603 +                      "errno = %d\n", err);
604 +               return(1);
605 +       }
606 +
607 +       return(0);
608 +}
609 +
610 +int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
611 +                        struct pt_regs *regs, unsigned long fault_addr,
612 +                        int fault_type)
613 +{
614 +       struct sigcontext sc;
615 +       unsigned long fpregs[HOST_FP_SIZE];
616 +       int err;
617 +
618 +       sc.gs = REGS_GS(regs->regs.skas.regs);
619 +       sc.fs = REGS_FS(regs->regs.skas.regs);
620 +       sc.es = REGS_ES(regs->regs.skas.regs);
621 +       sc.ds = REGS_DS(regs->regs.skas.regs);
622 +       sc.edi = REGS_EDI(regs->regs.skas.regs);
623 +       sc.esi = REGS_ESI(regs->regs.skas.regs);
624 +       sc.ebp = REGS_EBP(regs->regs.skas.regs);
625 +       sc.esp = REGS_SP(regs->regs.skas.regs);
626 +       sc.ebx = REGS_EBX(regs->regs.skas.regs);
627 +       sc.edx = REGS_EDX(regs->regs.skas.regs);
628 +       sc.ecx = REGS_ECX(regs->regs.skas.regs);
629 +       sc.eax = REGS_EAX(regs->regs.skas.regs);
630 +       sc.eip = REGS_IP(regs->regs.skas.regs);
631 +       sc.cs = REGS_CS(regs->regs.skas.regs);
632 +       sc.eflags = REGS_EFLAGS(regs->regs.skas.regs);
633 +       sc.esp_at_signal = regs->regs.skas.regs[UESP];
634 +       sc.ss = regs->regs.skas.regs[SS];
635 +       sc.cr2 = fault_addr;
636 +       sc.err = TO_SC_ERR(fault_type);
637 +       sc.trapno = regs->regs.skas.trap_type;
638 +
639 +       err = ptrace_getfpregs(userspace_pid[0], fpregs);
640 +       if(err < 0){
641 +               printk("copy_sc_to_user_skas - PTRACE_GETFPREGS failed, "
642 +                      "errno = %d\n", err);
643 +               return(1);
644 +       }
645 +       to_fp = (to_fp ? to_fp : (struct _fpstate *) (to + 1));
646 +       sc.fpstate = to_fp;
647 +
648 +       if(err)
649 +               return(err);
650 +
651 +       return(copy_to_user(to, &sc, sizeof(sc)) ||
652 +              copy_to_user(to_fp, fpregs, sizeof(fpregs)));
653 +}
654 +#endif
655 +
656 +#ifdef CONFIG_MODE_TT
657 +int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from,
658 +                        int fpsize)
659 +{
660 +       struct _fpstate *to_fp, *from_fp;
661 +       unsigned long sigs;
662 +       int err;
663 +
664 +       to_fp = to->fpstate;
665 +       from_fp = from->fpstate;
666 +       sigs = to->oldmask;
667 +       err = copy_from_user(to, from, sizeof(*to));
668 +       to->oldmask = sigs;
669 +       if(to_fp != NULL){
670 +               err |= copy_from_user(&to->fpstate, &to_fp,
671 +                                     sizeof(to->fpstate));
672 +               err |= copy_from_user(to_fp, from_fp, fpsize);
673 +       }
674 +       return(err);
675 +}
676 +
677 +int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp,
678 +                      struct sigcontext *from, int fpsize)
679 +{
680 +       struct _fpstate *to_fp, *from_fp;
681 +       int err;
682 +
683 +       to_fp = (fp ? fp : (struct _fpstate *) (to + 1));
684 +       from_fp = from->fpstate;
685 +       err = copy_to_user(to, from, sizeof(*to));
686 +       if(from_fp != NULL){
687 +               err |= copy_to_user(&to->fpstate, &to_fp,
688 +                                        sizeof(to->fpstate));
689 +               err |= copy_to_user(to_fp, from_fp, fpsize);
690 +       }
691 +       return(err);
692 +}
693 +#endif
694 +
695 +static int copy_sc_from_user(struct pt_regs *to, void *from)
696 +{
697 +       int ret;
698 +
699 +       ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from,
700 +                                              sizeof(struct _fpstate)),
701 +                         copy_sc_from_user_skas(to, from));
702 +       return(ret);
703 +}
704 +
705 +static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp,
706 +                          struct pt_regs *from)
707 +{
708 +       return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
709 +                                             sizeof(*fp)),
710 +                          copy_sc_to_user_skas(to, fp, from,
711 +                                               current->thread.cr2,
712 +                                               current->thread.err)));
713 +}
714 +
715 +static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp,
716 +                                sigset_t *set, unsigned long sp)
717 +{
718 +       int err = 0;
719 +
720 +       err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp);
721 +       err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
722 +       err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
723 +       err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs);
724 +       err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
725 +       return(err);
726 +}
727 +
728 +struct sigframe
729 +{
730 +       char *pretcode;
731 +       int sig;
732 +       struct sigcontext sc;
733 +       struct _fpstate fpstate;
734 +       unsigned long extramask[_NSIG_WORDS-1];
735 +       char retcode[8];
736 +};
737 +
738 +struct rt_sigframe
739 +{
740 +       char *pretcode;
741 +       int sig;
742 +       struct siginfo *pinfo;
743 +       void *puc;
744 +       struct siginfo info;
745 +       struct ucontext uc;
746 +       struct _fpstate fpstate;
747 +       char retcode[8];
748 +};
749 +
750 +int setup_signal_stack_sc(unsigned long stack_top, int sig,
751 +                         struct k_sigaction *ka, struct pt_regs *regs,
752 +                         sigset_t *mask)
753 +{
754 +       struct sigframe __user *frame;
755 +       void *restorer;
756 +       int err = 0;
757 +
758 +       stack_top &= -8UL;
759 +       frame = (struct sigframe *) stack_top - 1;
760 +       if(verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
761 +               return(1);
762 +
763 +       restorer = (void *) frame->retcode;
764 +       if(ka->sa.sa_flags & SA_RESTORER)
765 +               restorer = ka->sa.sa_restorer;
766 +
767 +       err |= __put_user(restorer, &frame->pretcode);
768 +       err |= __put_user(sig, &frame->sig);
769 +       err |= copy_sc_to_user(&frame->sc, NULL, regs);
770 +       err |= __put_user(mask->sig[0], &frame->sc.oldmask);
771 +       if (_NSIG_WORDS > 1)
772 +               err |= __copy_to_user(&frame->extramask, &mask->sig[1],
773 +                                     sizeof(frame->extramask));
774 +
775 +       /*
776 +        * This is popl %eax ; movl $,%eax ; int $0x80
777 +        *
778 +        * WE DO NOT USE IT ANY MORE! It's only left here for historical
779 +        * reasons and because gdb uses it as a signature to notice
780 +        * signal handler stack frames.
781 +        */
782 +       err |= __put_user(0xb858, (short __user *)(frame->retcode+0));
783 +       err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2));
784 +       err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
785 +
786 +       if(err)
787 +               return(err);
788 +
789 +       PT_REGS_SP(regs) = (unsigned long) frame;
790 +       PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
791 +       PT_REGS_EAX(regs) = (unsigned long) sig;
792 +       PT_REGS_EDX(regs) = (unsigned long) 0;
793 +       PT_REGS_ECX(regs) = (unsigned long) 0;
794 +
795 +       if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
796 +               ptrace_notify(SIGTRAP);
797 +       return(0);
798 +}
799 +
800 +int setup_signal_stack_si(unsigned long stack_top, int sig,
801 +                         struct k_sigaction *ka, struct pt_regs *regs,
802 +                         siginfo_t *info, sigset_t *mask)
803 +{
804 +       struct rt_sigframe __user *frame;
805 +       void *restorer;
806 +       int err = 0;
807 +
808 +       stack_top &= -8UL;
809 +       frame = (struct rt_sigframe *) stack_top - 1;
810 +       if(verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
811 +               return(1);
812 +
813 +       restorer = (void *) frame->retcode;
814 +       if(ka->sa.sa_flags & SA_RESTORER)
815 +               restorer = ka->sa.sa_restorer;
816 +
817 +       err |= __put_user(restorer, &frame->pretcode);
818 +       err |= __put_user(sig, &frame->sig);
819 +       err |= __put_user(&frame->info, &frame->pinfo);
820 +       err |= __put_user(&frame->uc, &frame->puc);
821 +       err |= copy_siginfo_to_user(&frame->info, info);
822 +       err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask,
823 +                                    PT_REGS_SP(regs));
824 +
825 +       /*
826 +        * This is movl $,%eax ; int $0x80
827 +        *
828 +        * WE DO NOT USE IT ANY MORE! It's only left here for historical
829 +        * reasons and because gdb uses it as a signature to notice
830 +        * signal handler stack frames.
831 +        */
832 +       err |= __put_user(0xb8, (char __user *)(frame->retcode+0));
833 +       err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1));
834 +       err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
835 +
836 +       if(err)
837 +               return(err);
838 +
839 +       PT_REGS_SP(regs) = (unsigned long) frame;
840 +       PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
841 +       PT_REGS_EAX(regs) = (unsigned long) sig;
842 +       PT_REGS_EDX(regs) = (unsigned long) &frame->info;
843 +       PT_REGS_ECX(regs) = (unsigned long) &frame->uc;
844 +
845 +       if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
846 +               ptrace_notify(SIGTRAP);
847 +       return(0);
848 +}
849 +
850 +long sys_sigreturn(struct pt_regs regs)
851 +{
852 +       unsigned long __user sp = PT_REGS_SP(&current->thread.regs);
853 +       struct sigframe __user *frame = (struct sigframe *)(sp - 8);
854 +       sigset_t set;
855 +       struct sigcontext __user *sc = &frame->sc;
856 +       unsigned long __user *oldmask = &sc->oldmask;
857 +       unsigned long __user *extramask = &frame->extramask;
858 +       int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
859 +
860 +       if(copy_from_user(&set.sig[0], oldmask, sizeof(&set.sig[0])) ||
861 +          copy_from_user(&set.sig[1], extramask, sig_size))
862 +               goto segfault;
863 +
864 +       sigdelsetmask(&set, ~_BLOCKABLE);
865 +
866 +       spin_lock_irq(&current->sighand->siglock);
867 +       current->blocked = set;
868 +       recalc_sigpending();
869 +       spin_unlock_irq(&current->sighand->siglock);
870 +
871 +       if(copy_sc_from_user(&current->thread.regs, sc))
872 +               goto segfault;
873 +
874 +       PT_REGS_SYSCALL_NR(&current->thread.regs) = -1; /* Avoid ERESTART handling */
875 +       return(PT_REGS_SYSCALL_RET(&current->thread.regs));
876 +
877 + segfault:
878 +       force_sig(SIGSEGV, current);
879 +       return 0;
880 +}
881 +
882 +long sys_rt_sigreturn(struct pt_regs regs)
883 +{
884 +       unsigned long __user sp = PT_REGS_SP(&current->thread.regs);
885 +       struct rt_sigframe __user *frame = (struct rt_sigframe *) (sp - 4);
886 +       sigset_t set;
887 +       struct ucontext __user *uc = &frame->uc;
888 +       int sig_size = _NSIG_WORDS * sizeof(unsigned long);
889 +
890 +       if(copy_from_user(&set, &uc->uc_sigmask, sig_size))
891 +               goto segfault;
892 +
893 +       sigdelsetmask(&set, ~_BLOCKABLE);
894 +
895 +       spin_lock_irq(&current->sighand->siglock);
896 +       current->blocked = set;
897 +       recalc_sigpending();
898 +       spin_unlock_irq(&current->sighand->siglock);
899 +
900 +       if(copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext))
901 +               goto segfault;
902 +
903 +       PT_REGS_SYSCALL_NR(&current->thread.regs) = -1; /* Avoid ERESTART handling */
904 +       return(PT_REGS_SYSCALL_RET(&current->thread.regs));
905 +
906 + segfault:
907 +       force_sig(SIGSEGV, current);
908 +       return 0;
909 +}
910 +
911 +/*
912 + * Overrides for Emacs so that we follow Linus's tabbing style.
913 + * Emacs will notice this stuff at the end of the file and automatically
914 + * adjust the settings for this buffer only.  This must remain at the end
915 + * of the file.
916 + * ---------------------------------------------------------------------------
917 + * Local variables:
918 + * c-file-style: "linux"
919 + * End:
920 + */
921 Index: linux-2.6.10/arch/um/sys-i386/ptrace_user.c
922 ===================================================================
923 --- linux-2.6.10.orig/arch/um/sys-i386/ptrace_user.c    2004-12-25 05:35:50.000000000 +0800
924 +++ linux-2.6.10/arch/um/sys-i386/ptrace_user.c 2005-04-06 23:44:30.233026472 +0800
925 @@ -17,17 +17,30 @@
926  
927  int ptrace_getregs(long pid, unsigned long *regs_out)
928  {
929 -       return(ptrace(PTRACE_GETREGS, pid, 0, regs_out));
930 +       if(ptrace(PTRACE_GETREGS, pid, 0, regs_out) < 0)
931 +               return(-errno);
932 +       return(0);
933  }
934  
935  int ptrace_setregs(long pid, unsigned long *regs)
936  {
937 -       return(ptrace(PTRACE_SETREGS, pid, 0, regs));
938 +       if(ptrace(PTRACE_SETREGS, pid, 0, regs) < 0)
939 +               return(-errno);
940 +       return(0);
941  }
942  
943  int ptrace_getfpregs(long pid, unsigned long *regs)
944  {
945 -       return(ptrace(PTRACE_GETFPREGS, pid, 0, regs));
946 +       if(ptrace(PTRACE_GETFPREGS, pid, 0, regs) < 0)
947 +               return(-errno);
948 +       return(0);
949 +}
950 +
951 +int ptrace_setfpregs(long pid, unsigned long *regs)
952 +{
953 +       if(ptrace(PTRACE_SETFPREGS, pid, 0, regs) < 0)
954 +               return(-errno);
955 +       return(0);
956  }
957  
958  static void write_debugregs(int pid, unsigned long *regs)
959 Index: linux-2.6.10/arch/um/sys-i386/sysrq.c
960 ===================================================================
961 --- linux-2.6.10.orig/arch/um/sys-i386/sysrq.c  2004-12-25 05:33:49.000000000 +0800
962 +++ linux-2.6.10/arch/um/sys-i386/sysrq.c       2005-04-06 23:44:30.234026320 +0800
963 @@ -33,3 +33,13 @@
964  
965          show_trace((unsigned long *) &regs);
966  }
967 +
968 +/* Overrides for Emacs so that we follow Linus's tabbing style.
969 + * Emacs will notice this stuff at the end of the file and automatically
970 + * adjust the settings for this buffer only.  This must remain at the end
971 + * of the file.
972 + * ---------------------------------------------------------------------------
973 + * Local variables:
974 + * c-file-style: "linux"
975 + * End:
976 + */
977 Index: linux-2.6.10/arch/um/sys-i386/Makefile
978 ===================================================================
979 --- linux-2.6.10.orig/arch/um/sys-i386/Makefile 2004-12-25 05:34:01.000000000 +0800
980 +++ linux-2.6.10/arch/um/sys-i386/Makefile      2005-04-06 23:44:30.236026016 +0800
981 @@ -1,5 +1,5 @@
982  obj-y = bitops.o bugs.o checksum.o fault.o ksyms.o ldt.o ptrace.o \
983 -       ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
984 +       ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o
985  
986  obj-$(CONFIG_HIGHMEM) += highmem.o
987  obj-$(CONFIG_MODULES) += module.o
988 Index: linux-2.6.10/arch/um/sys-i386/sigcontext.c
989 ===================================================================
990 --- linux-2.6.10.orig/arch/um/sys-i386/sigcontext.c     2004-12-25 05:33:49.000000000 +0800
991 +++ linux-2.6.10/arch/um/sys-i386/sigcontext.c  2005-04-06 23:44:30.233026472 +0800
992 @@ -9,22 +9,14 @@
993  #include <asm/sigcontext.h>
994  #include "sysdep/ptrace.h"
995  #include "kern_util.h"
996 -#include "frame_user.h"
997 -
998 -int sc_size(void *data)
999 -{
1000 -       struct arch_frame_data *arch = data;
1001 -
1002 -       return(sizeof(struct sigcontext) + arch->fpstate_size);
1003 -}
1004  
1005  void sc_to_sc(void *to_ptr, void *from_ptr)
1006  {
1007         struct sigcontext *to = to_ptr, *from = from_ptr;
1008 -       int size = sizeof(*to) + signal_frame_sc.common.arch.fpstate_size;
1009  
1010 -       memcpy(to, from, size);
1011 -       if(from->fpstate != NULL) to->fpstate = (struct _fpstate *) (to + 1);
1012 +       memcpy(to, from, sizeof(*to) + sizeof(struct _fpstate));
1013 +       if(from->fpstate != NULL)
1014 +               to->fpstate = (struct _fpstate *) (to + 1);
1015  }
1016  
1017  unsigned long *sc_sigmask(void *sc_ptr)
1018 Index: linux-2.6.10/arch/um/kernel/main.c
1019 ===================================================================
1020 --- linux-2.6.10.orig/arch/um/kernel/main.c     2004-12-25 05:35:24.000000000 +0800
1021 +++ linux-2.6.10/arch/um/kernel/main.c  2005-04-06 23:44:30.262022064 +0800
1022 @@ -81,6 +81,8 @@
1023  
1024  extern int uml_exitcode;
1025  
1026 +extern void scan_elf_aux( char **envp);
1027 +
1028  int main(int argc, char **argv, char **envp)
1029  {
1030         char **new_argv;
1031 @@ -147,6 +149,8 @@
1032         set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
1033         set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
1034  
1035 +       scan_elf_aux( envp);
1036 +
1037         do_uml_initcalls();
1038         ret = linux_main(argc, argv);
1039  
1040 @@ -155,18 +159,20 @@
1041                 int err;
1042  
1043                 printf("\n");
1044 -
1045 -               /* Let any pending signals fire, then disable them.  This
1046 -                * ensures that they won't be delivered after the exec, when
1047 -                * they are definitely not expected.
1048 -                */
1049 -               unblock_signals();
1050 +               /* stop timers and set SIG*ALRM to be ignored */
1051                 disable_timer();
1052 +               /* disable SIGIO for the fds and set SIGIO to be ignored */
1053                 err = deactivate_all_fds();
1054                 if(err)
1055                         printf("deactivate_all_fds failed, errno = %d\n",
1056                                -err);
1057  
1058 +               /* Let any pending signals fire now.  This ensures
1059 +                * that they won't be delivered after the exec, when
1060 +                * they are definitely not expected.
1061 +                */
1062 +               unblock_signals();
1063 +
1064                 execvp(new_argv[0], new_argv);
1065                 perror("Failed to exec kernel");
1066                 ret = 1;
1067 Index: linux-2.6.10/arch/um/kernel/process.c
1068 ===================================================================
1069 --- linux-2.6.10.orig/arch/um/kernel/process.c  2004-12-25 05:35:25.000000000 +0800
1070 +++ linux-2.6.10/arch/um/kernel/process.c       2005-04-06 23:44:30.240025408 +0800
1071 @@ -13,6 +13,7 @@
1072  #include <setjmp.h>
1073  #include <sys/time.h>
1074  #include <sys/ptrace.h>
1075 +#include <linux/ptrace.h>
1076  #include <sys/wait.h>
1077  #include <sys/mman.h>
1078  #include <asm/ptrace.h>
1079 @@ -285,6 +286,9 @@
1080         printk("Checking that ptrace can change system call numbers...");
1081         pid = start_ptraced_child(&stack);
1082  
1083 +       if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
1084 +               panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno);
1085 +
1086         while(1){
1087                 if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
1088                         panic("check_ptrace : ptrace failed, errno = %d", 
1089 @@ -292,8 +296,8 @@
1090                 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
1091                 if(n < 0)
1092                         panic("check_ptrace : wait failed, errno = %d", errno);
1093 -               if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
1094 -                       panic("check_ptrace : expected SIGTRAP, "
1095 +               if(!WIFSTOPPED(status) || (WSTOPSIG(status) != (SIGTRAP|SYSCALL_TRAP)))
1096 +                       panic("check_ptrace : expected (SIGTRAP|SYSCALL_TRAP), "
1097                               "got status = %d", status);
1098                 
1099                 syscall = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET,
1100 Index: linux-2.6.10/arch/um/kernel/initrd_user.c
1101 ===================================================================
1102 --- linux-2.6.10.orig/arch/um/kernel/initrd_user.c      2004-12-25 05:34:26.000000000 +0800
1103 +++ linux-2.6.10/arch/um/kernel/initrd_user.c   2005-04-06 23:44:30.252023584 +0800
1104 @@ -29,6 +29,8 @@
1105                        filename, -n);
1106                 return(-1);
1107         }
1108 +
1109 +       os_close_file(fd);
1110         return(0);
1111  }
1112  
1113 Index: linux-2.6.10/arch/um/kernel/time_kern.c
1114 ===================================================================
1115 --- linux-2.6.10.orig/arch/um/kernel/time_kern.c        2004-12-25 05:35:00.000000000 +0800
1116 +++ linux-2.6.10/arch/um/kernel/time_kern.c     2005-04-06 23:44:30.271020696 +0800
1117 @@ -170,7 +170,7 @@
1118  void timer_handler(int sig, union uml_pt_regs *regs)
1119  {
1120         local_irq_disable();
1121 -       update_process_times(user_context(UPT_SP(regs)));
1122 +       update_process_times(CHOOSE_MODE(user_context(UPT_SP(regs)), (regs)->skas.is_user));
1123         local_irq_enable();
1124         if(current_thread->cpu == 0)
1125                 timer_irq(regs);
1126 Index: linux-2.6.10/arch/um/kernel/helper.c
1127 ===================================================================
1128 --- linux-2.6.10.orig/arch/um/kernel/helper.c   2004-12-25 05:34:45.000000000 +0800
1129 +++ linux-2.6.10/arch/um/kernel/helper.c        2005-04-06 23:44:30.271020696 +0800
1130 @@ -49,14 +49,14 @@
1131         return(0);
1132  }
1133  
1134 -/* XXX The alloc_stack here breaks if this is called in the tracing thread */
1135 -
1136 +/* Returns either the pid of the child process we run or -E* on failure.
1137 + * XXX The alloc_stack here breaks if this is called in the tracing thread */
1138  int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
1139                unsigned long *stack_out)
1140  {
1141         struct helper_data data;
1142         unsigned long stack, sp;
1143 -       int pid, fds[2], err, n;
1144 +       int pid, fds[2], ret, n;
1145  
1146         if((stack_out != NULL) && (*stack_out != 0))
1147                 stack = *stack_out;
1148 @@ -64,16 +64,16 @@
1149         if(stack == 0)
1150                 return(-ENOMEM);
1151  
1152 -       err = os_pipe(fds, 1, 0);
1153 -       if(err < 0){
1154 -               printk("run_helper : pipe failed, err = %d\n", -err);
1155 +       ret = os_pipe(fds, 1, 0);
1156 +       if(ret < 0){
1157 +               printk("run_helper : pipe failed, ret = %d\n", -ret);
1158                 goto out_free;
1159         }
1160  
1161 -       err = os_set_exec_close(fds[1], 1);
1162 -       if(err < 0){
1163 -               printk("run_helper : setting FD_CLOEXEC failed, err = %d\n",
1164 -                      -err);
1165 +       ret = os_set_exec_close(fds[1], 1);
1166 +       if(ret < 0){
1167 +               printk("run_helper : setting FD_CLOEXEC failed, ret = %d\n",
1168 +                      -ret);
1169                 goto out_close;
1170         }
1171  
1172 @@ -85,34 +85,36 @@
1173         pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
1174         if(pid < 0){
1175                 printk("run_helper : clone failed, errno = %d\n", errno);
1176 -               err = -errno;
1177 +               ret = -errno;
1178                 goto out_close;
1179         }
1180  
1181         os_close_file(fds[1]);
1182 -       n = os_read_file(fds[0], &err, sizeof(err));
1183 +       fds[1] = -1;
1184 +
1185 +       /*Read the errno value from the child.*/
1186 +       n = os_read_file(fds[0], &ret, sizeof(ret));
1187         if(n < 0){
1188 -               printk("run_helper : read on pipe failed, err = %d\n", -n);
1189 -               err = n;
1190 -               goto out_kill;
1191 +               printk("run_helper : read on pipe failed, ret = %d\n", -n);
1192 +               ret = n;
1193 +               os_kill_process(pid, 1);
1194         }
1195         else if(n != 0){
1196                 CATCH_EINTR(n = waitpid(pid, NULL, 0));
1197 -               pid = -errno;
1198 +               ret = -errno;
1199 +       } else {
1200 +               ret = pid;
1201         }
1202  
1203 -       if(stack_out == NULL) free_stack(stack, 0);
1204 -        else *stack_out = stack;
1205 -       return(pid);
1206 -
1207 - out_kill:
1208 -       os_kill_process(pid, 1);
1209   out_close:
1210 +       if (fds[1] != -1)
1211 +               os_close_file(fds[1]);
1212         os_close_file(fds[0]);
1213 -       os_close_file(fds[1]);
1214   out_free:
1215 -       free_stack(stack, 0);
1216 -       return(err);
1217 +       if(stack_out == NULL)
1218 +               free_stack(stack, 0);
1219 +        else *stack_out = stack;
1220 +       return(ret);
1221  }
1222  
1223  int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, 
1224 Index: linux-2.6.10/arch/um/kernel/irq_user.c
1225 ===================================================================
1226 --- linux-2.6.10.orig/arch/um/kernel/irq_user.c 2004-12-25 05:34:32.000000000 +0800
1227 +++ linux-2.6.10/arch/um/kernel/irq_user.c      2005-04-06 23:44:30.263021912 +0800
1228 @@ -374,6 +374,8 @@
1229                 if(err)
1230                         return(err);
1231         }
1232 +       /* If there is a signal already queued, after unblocking ignore it */
1233 +       set_handler(SIGIO, SIG_IGN, 0, -1);
1234  
1235         return(0);
1236  }
1237 Index: linux-2.6.10/arch/um/kernel/mem.c
1238 ===================================================================
1239 --- linux-2.6.10.orig/arch/um/kernel/mem.c      2004-12-25 05:34:32.000000000 +0800
1240 +++ linux-2.6.10/arch/um/kernel/mem.c   2005-04-06 23:44:30.279019480 +0800
1241 @@ -175,6 +175,30 @@
1242  }
1243  #endif /* CONFIG_HIGHMEM */
1244  
1245 +static void __init fixaddr_user_init( void)
1246 +{
1247 +       long size = FIXADDR_USER_END - FIXADDR_USER_START;
1248 +       pgd_t *pgd;
1249 +       pmd_t *pmd;
1250 +       pte_t *pte;
1251 +       unsigned long paddr, vaddr = FIXADDR_USER_START;
1252 +
1253 +       if (  ! size )
1254 +               return;
1255 +
1256 +       fixrange_init( FIXADDR_USER_START, FIXADDR_USER_END, swapper_pg_dir);
1257 +       paddr = (unsigned long)alloc_bootmem_low_pages( size);
1258 +       memcpy( (void *)paddr, (void *)FIXADDR_USER_START, size);
1259 +       paddr = __pa(paddr);
1260 +       for ( ; size > 0; size-=PAGE_SIZE, vaddr+=PAGE_SIZE, paddr+=PAGE_SIZE) {
1261 +               pgd = swapper_pg_dir + pgd_index(vaddr);
1262 +               pmd = pmd_offset(pgd, vaddr);
1263 +               pte = pte_offset_kernel(pmd, vaddr);
1264 +               /*pte_set_val( (*pte), paddr, PAGE_READONLY);*/
1265 +               pte_val(*pte) = paddr | pgprot_val(PAGE_READONLY);
1266 +       }
1267 +}
1268 +
1269  void paging_init(void)
1270  {
1271         unsigned long zones_size[MAX_NR_ZONES], vaddr;
1272 @@ -195,6 +219,8 @@
1273         vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
1274         fixrange_init(vaddr, FIXADDR_TOP, swapper_pg_dir);
1275  
1276 +       fixaddr_user_init();
1277 +
1278  #ifdef CONFIG_HIGHMEM
1279         init_highmem();
1280  #endif
1281 Index: linux-2.6.10/arch/um/kernel/skas/process.c
1282 ===================================================================
1283 --- linux-2.6.10.orig/arch/um/kernel/skas/process.c     2004-12-25 05:35:39.000000000 +0800
1284 +++ linux-2.6.10/arch/um/kernel/skas/process.c  2005-04-06 23:44:30.268021152 +0800
1285 @@ -11,6 +11,7 @@
1286  #include <sched.h>
1287  #include <sys/wait.h>
1288  #include <sys/ptrace.h>
1289 +#include <linux/ptrace.h>
1290  #include <sys/mman.h>
1291  #include <sys/user.h>
1292  #include <asm/unistd.h>
1293 @@ -60,15 +61,10 @@
1294  /*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/
1295  static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu)
1296  {
1297 -       int err, syscall_nr, status;
1298 -
1299 -       syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
1300 -       UPT_SYSCALL_NR(regs) = syscall_nr;
1301 -       if(syscall_nr < 0){
1302 -               relay_signal(SIGTRAP, regs);
1303 -               return;
1304 -       }
1305  
1306 +       int err, status;
1307 +  
1308 +       UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->skas.regs); /* Mark this as a syscall */
1309         if (!local_using_sysemu)
1310         {
1311                 err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
1312 @@ -82,7 +78,8 @@
1313                               "errno = %d\n", errno);
1314  
1315                 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
1316 -               if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
1317 +               if((err < 0) || !WIFSTOPPED(status) ||
1318 +                               (WSTOPSIG(status) != (SIGTRAP|SYSCALL_TRAP)))
1319                         panic("handle_trap - failed to wait at end of syscall, "
1320                               "errno = %d, status = %d\n", errno, status);
1321         }
1322 @@ -131,6 +128,10 @@
1323                 panic("start_userspace : expected SIGSTOP, got status = %d",
1324                       status);
1325  
1326 +       if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, (void *)PTRACE_O_TRACESYSGOOD) < 0)
1327 +               panic("start_userspace : PTRACE_SETOPTIONS failed, errno=%d\n",
1328 +                     errno);
1329 +
1330         if(munmap(stack, PAGE_SIZE) < 0)
1331                 panic("start_userspace : munmap failed, errno = %d\n", errno);
1332  
1333 @@ -160,15 +161,19 @@
1334  
1335                 regs->skas.is_user = 1;
1336                 save_registers(regs);
1337 +               UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
1338  
1339                 if(WIFSTOPPED(status)){
1340                         switch(WSTOPSIG(status)){
1341                         case SIGSEGV:
1342                                 handle_segv(pid);
1343                                 break;
1344 -                       case SIGTRAP:
1345 +                       case (SIGTRAP|SYSCALL_TRAP):
1346                                 handle_trap(pid, regs, local_using_sysemu);
1347                                 break;
1348 +                       case SIGTRAP:
1349 +                               relay_signal(SIGTRAP, regs);
1350 +                               break;
1351                         case SIGIO:
1352                         case SIGVTALRM:
1353                         case SIGILL:
1354 @@ -222,9 +227,10 @@
1355         block_signals();
1356         if(sigsetjmp(fork_buf, 1) == 0)
1357                 new_thread_proc(stack, handler);
1358 -       set_signals(flags);
1359  
1360         remove_sigstack();
1361 +
1362 +       set_signals(flags);
1363  }
1364  
1365  void thread_wait(void *sw, void *fb)
1366 Index: linux-2.6.10/arch/um/kernel/skas/sys-i386/Makefile
1367 ===================================================================
1368 --- linux-2.6.10.orig/arch/um/kernel/skas/sys-i386/Makefile     2004-12-25 05:35:27.000000000 +0800
1369 +++ linux-2.6.10/arch/um/kernel/skas/sys-i386/Makefile  2005-04-07 06:37:43.373923992 +0800
1370 @@ -1,12 +0,0 @@
1371 -# 
1372 -# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
1373 -# Licensed under the GPL
1374 -#
1375 -
1376 -obj-y = sigcontext.o
1377 -
1378 -USER_OBJS = sigcontext.o
1379 -USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
1380 -
1381 -$(USER_OBJS) : %.o: %.c
1382 -       $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
1383 Index: linux-2.6.10/arch/um/kernel/skas/sys-i386/sigcontext.c
1384 ===================================================================
1385 --- linux-2.6.10.orig/arch/um/kernel/skas/sys-i386/sigcontext.c 2004-12-25 05:33:51.000000000 +0800
1386 +++ linux-2.6.10/arch/um/kernel/skas/sys-i386/sigcontext.c      2005-04-07 06:37:43.373923992 +0800
1387 @@ -1,114 +0,0 @@
1388 -/* 
1389 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
1390 - * Licensed under the GPL
1391 - */
1392 -
1393 -#include <errno.h>
1394 -#include <asm/sigcontext.h>
1395 -#include <sys/ptrace.h>
1396 -#include <linux/ptrace.h>
1397 -#include "sysdep/ptrace.h"
1398 -#include "sysdep/ptrace_user.h"
1399 -#include "kern_util.h"
1400 -#include "user.h"
1401 -#include "sigcontext.h"
1402 -#include "mode.h"
1403 -
1404 -int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, void *from_ptr)
1405 -{
1406 -       struct sigcontext sc, *from = from_ptr;
1407 -       unsigned long fpregs[FP_FRAME_SIZE];
1408 -       int err;
1409 -
1410 -       err = copy_from_user_proc(&sc, from, sizeof(sc));
1411 -       err |= copy_from_user_proc(fpregs, sc.fpstate, sizeof(fpregs));
1412 -       if(err)
1413 -               return(err);
1414 -
1415 -       regs->skas.regs[GS] = sc.gs;
1416 -       regs->skas.regs[FS] = sc.fs;
1417 -       regs->skas.regs[ES] = sc.es;
1418 -       regs->skas.regs[DS] = sc.ds;
1419 -       regs->skas.regs[EDI] = sc.edi;
1420 -       regs->skas.regs[ESI] = sc.esi;
1421 -       regs->skas.regs[EBP] = sc.ebp;
1422 -       regs->skas.regs[UESP] = sc.esp;
1423 -       regs->skas.regs[EBX] = sc.ebx;
1424 -       regs->skas.regs[EDX] = sc.edx;
1425 -       regs->skas.regs[ECX] = sc.ecx;
1426 -       regs->skas.regs[EAX] = sc.eax;
1427 -       regs->skas.regs[EIP] = sc.eip;
1428 -       regs->skas.regs[CS] = sc.cs;
1429 -       regs->skas.regs[EFL] = sc.eflags;
1430 -       regs->skas.regs[SS] = sc.ss;
1431 -       regs->skas.fault_addr = sc.cr2;
1432 -       regs->skas.fault_type = FAULT_WRITE(sc.err);
1433 -       regs->skas.trap_type = sc.trapno;
1434 -
1435 -       err = ptrace(PTRACE_SETFPREGS, pid, 0, fpregs);
1436 -       if(err < 0){
1437 -               printk("copy_sc_to_user - PTRACE_SETFPREGS failed, "
1438 -                      "errno = %d\n", errno);
1439 -               return(1);
1440 -       }
1441 -
1442 -       return(0);
1443 -}
1444 -
1445 -int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp,
1446 -                        union uml_pt_regs *regs, unsigned long fault_addr,
1447 -                        int fault_type)
1448 -{
1449 -       struct sigcontext sc, *to = to_ptr;
1450 -       struct _fpstate *to_fp;
1451 -       unsigned long fpregs[FP_FRAME_SIZE];
1452 -       int err;
1453 -
1454 -       sc.gs = regs->skas.regs[GS];
1455 -       sc.fs = regs->skas.regs[FS];
1456 -       sc.es = regs->skas.regs[ES];
1457 -       sc.ds = regs->skas.regs[DS];
1458 -       sc.edi = regs->skas.regs[EDI];
1459 -       sc.esi = regs->skas.regs[ESI];
1460 -       sc.ebp = regs->skas.regs[EBP];
1461 -       sc.esp = regs->skas.regs[UESP];
1462 -       sc.ebx = regs->skas.regs[EBX];
1463 -       sc.edx = regs->skas.regs[EDX];
1464 -       sc.ecx = regs->skas.regs[ECX];
1465 -       sc.eax = regs->skas.regs[EAX];
1466 -       sc.eip = regs->skas.regs[EIP];
1467 -       sc.cs = regs->skas.regs[CS];
1468 -       sc.eflags = regs->skas.regs[EFL];
1469 -       sc.esp_at_signal = regs->skas.regs[UESP];
1470 -       sc.ss = regs->skas.regs[SS];
1471 -       sc.cr2 = fault_addr;
1472 -       sc.err = TO_SC_ERR(fault_type);
1473 -       sc.trapno = regs->skas.trap_type;
1474 -
1475 -       err = ptrace(PTRACE_GETFPREGS, pid, 0, fpregs);
1476 -       if(err < 0){
1477 -               printk("copy_sc_to_user - PTRACE_GETFPREGS failed, "
1478 -                      "errno = %d\n", errno);
1479 -               return(1);
1480 -       }
1481 -       to_fp = (struct _fpstate *) 
1482 -               (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
1483 -       sc.fpstate = to_fp;
1484 -
1485 -       if(err)
1486 -               return(err);
1487 -
1488 -       return(copy_to_user_proc(to, &sc, sizeof(sc)) ||
1489 -              copy_to_user_proc(to_fp, fpregs, sizeof(fpregs)));
1490 -}
1491 -
1492 -/*
1493 - * Overrides for Emacs so that we follow Linus's tabbing style.
1494 - * Emacs will notice this stuff at the end of the file and automatically
1495 - * adjust the settings for this buffer only.  This must remain at the end
1496 - * of the file.
1497 - * ---------------------------------------------------------------------------
1498 - * Local variables:
1499 - * c-file-style: "linux"
1500 - * End:
1501 - */
1502 Index: linux-2.6.10/arch/um/kernel/skas/process_kern.c
1503 ===================================================================
1504 --- linux-2.6.10.orig/arch/um/kernel/skas/process_kern.c        2004-12-25 05:35:50.000000000 +0800
1505 +++ linux-2.6.10/arch/um/kernel/skas/process_kern.c     2005-04-06 23:44:30.268021152 +0800
1506 @@ -19,7 +19,6 @@
1507  #include "os.h"
1508  #include "user_util.h"
1509  #include "tlb.h"
1510 -#include "frame.h"
1511  #include "kern.h"
1512  #include "mode.h"
1513  #include "proc_mm.h"
1514 @@ -183,7 +182,6 @@
1515  int start_uml_skas(void)
1516  {
1517         start_userspace(0);
1518 -       capture_signal_stack();
1519  
1520         init_new_thread_signals(1);
1521         uml_idle_timer();
1522 Index: linux-2.6.10/arch/um/kernel/skas/trap_user.c
1523 ===================================================================
1524 --- linux-2.6.10.orig/arch/um/kernel/skas/trap_user.c   2004-12-25 05:34:32.000000000 +0800
1525 +++ linux-2.6.10/arch/um/kernel/skas/trap_user.c        2005-04-06 23:44:30.269021000 +0800
1526 @@ -21,6 +21,14 @@
1527         int save_errno = errno;
1528         int save_user;
1529  
1530 +       /* This is done because to allow SIGSEGV to be delivered inside a SEGV
1531 +        * handler.  This can happen in copy_user, and if SEGV is disabled,
1532 +        * the process will die.
1533 +        * XXX Figure out why this is better than SA_NODEFER
1534 +        */
1535 +       if(sig == SIGSEGV)
1536 +               change_sig(SIGSEGV, 1);
1537 +
1538         r = &TASK_REGS(get_current())->skas;
1539         save_user = r->is_user;
1540         r->is_user = 0;
1541 Index: linux-2.6.10/arch/um/kernel/skas/syscall_kern.c
1542 ===================================================================
1543 --- linux-2.6.10.orig/arch/um/kernel/skas/syscall_kern.c        2004-12-25 05:35:00.000000000 +0800
1544 +++ linux-2.6.10/arch/um/kernel/skas/syscall_kern.c     2005-04-06 23:44:30.269021000 +0800
1545 @@ -6,6 +6,7 @@
1546  #include "linux/sys.h"
1547  #include "linux/ptrace.h"
1548  #include "asm/errno.h"
1549 +#include "linux/ptrace.h"
1550  #include "asm/unistd.h"
1551  #include "asm/ptrace.h"
1552  #include "asm/current.h"
1553 Index: linux-2.6.10/arch/um/kernel/skas/Makefile
1554 ===================================================================
1555 --- linux-2.6.10.orig/arch/um/kernel/skas/Makefile      2004-12-25 05:34:30.000000000 +0800
1556 +++ linux-2.6.10/arch/um/kernel/skas/Makefile   2005-04-06 23:44:30.270020848 +0800
1557 @@ -4,8 +4,7 @@
1558  #
1559  
1560  obj-y := exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \
1561 -       syscall_kern.o syscall_user.o time.o tlb.o trap_user.o uaccess.o \
1562 -       sys-$(SUBARCH)/
1563 +       syscall_kern.o syscall_user.o time.o tlb.o trap_user.o uaccess.o
1564  
1565  subdir-y := util
1566  
1567 Index: linux-2.6.10/arch/um/kernel/skas/include/mmu-skas.h
1568 ===================================================================
1569 --- linux-2.6.10.orig/arch/um/kernel/skas/include/mmu-skas.h    2004-12-25 05:35:24.000000000 +0800
1570 +++ linux-2.6.10/arch/um/kernel/skas/include/mmu-skas.h 2005-04-06 23:44:30.265021608 +0800
1571 @@ -22,3 +22,27 @@
1572   * c-file-style: "linux"
1573   * End:
1574   */
1575 +/*
1576 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
1577 + * Licensed under the GPL
1578 + */
1579 +
1580 +#ifndef __SKAS_MMU_H
1581 +#define __SKAS_MMU_H
1582 +
1583 +struct mmu_context_skas {
1584 +       int mm_fd;
1585 +};
1586 +
1587 +#endif
1588 +
1589 +/*
1590 + * Overrides for Emacs so that we follow Linus's tabbing style.
1591 + * Emacs will notice this stuff at the end of the file and automatically
1592 + * adjust the settings for this buffer only.  This must remain at the end
1593 + * of the file.
1594 + * ---------------------------------------------------------------------------
1595 + * Local variables:
1596 + * c-file-style: "linux"
1597 + * End:
1598 + */
1599 Index: linux-2.6.10/arch/um/kernel/skas/include/mode-skas.h
1600 ===================================================================
1601 --- linux-2.6.10.orig/arch/um/kernel/skas/include/mode-skas.h   2004-12-25 05:34:58.000000000 +0800
1602 +++ linux-2.6.10/arch/um/kernel/skas/include/mode-skas.h        2005-04-06 23:44:30.265021608 +0800
1603 @@ -14,6 +14,40 @@
1604  extern int have_fpx_regs;
1605  
1606  extern void user_time_init_skas(void);
1607 +extern void sig_handler_common_skas(int sig, void *sc_ptr);
1608 +extern void halt_skas(void);
1609 +extern void reboot_skas(void);
1610 +extern void kill_off_processes_skas(void);
1611 +extern int is_skas_winch(int pid, int fd, void *data);
1612 +
1613 +#endif
1614 +
1615 +/*
1616 + * Overrides for Emacs so that we follow Linus's tabbing style.
1617 + * Emacs will notice this stuff at the end of the file and automatically
1618 + * adjust the settings for this buffer only.  This must remain at the end
1619 + * of the file.
1620 + * ---------------------------------------------------------------------------
1621 + * Local variables:
1622 + * c-file-style: "linux"
1623 + * End:
1624 + */
1625 +/*
1626 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
1627 + * Licensed under the GPL
1628 + */
1629 +
1630 +#ifndef __MODE_SKAS_H__
1631 +#define __MODE_SKAS_H__
1632 +
1633 +#include <sysdep/ptrace.h>
1634 +
1635 +extern unsigned long exec_regs[];
1636 +extern unsigned long exec_fp_regs[];
1637 +extern unsigned long exec_fpx_regs[];
1638 +extern int have_fpx_regs;
1639 +
1640 +extern void user_time_init_skas(void);
1641  extern int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs,
1642                                   void *from_ptr);
1643  extern int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp,
1644 Index: linux-2.6.10/arch/um/kernel/skas/include/uaccess-skas.h
1645 ===================================================================
1646 --- linux-2.6.10.orig/arch/um/kernel/skas/include/uaccess-skas.h        2004-12-25 05:34:32.000000000 +0800
1647 +++ linux-2.6.10/arch/um/kernel/skas/include/uaccess-skas.h     2005-04-06 23:44:30.264021760 +0800
1648 @@ -7,6 +7,51 @@
1649  #define __SKAS_UACCESS_H
1650  
1651  #include "asm/errno.h"
1652 +#include "asm/fixmap.h"
1653 +
1654 +#define access_ok_skas(type, addr, size) \
1655 +       ((segment_eq(get_fs(), KERNEL_DS)) || \
1656 +        (((unsigned long) (addr) < TASK_SIZE) && \
1657 +         ((unsigned long) (addr) + (size) <= TASK_SIZE)) || \
1658 +        ((type == VERIFY_READ ) && \
1659 +         ((unsigned long) (addr) >= FIXADDR_USER_START) && \
1660 +         ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
1661 +         ((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
1662 +
1663 +static inline int verify_area_skas(int type, const void * addr,
1664 +                                  unsigned long size)
1665 +{
1666 +       return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
1667 +}
1668 +
1669 +extern int copy_from_user_skas(void *to, const void *from, int n);
1670 +extern int copy_to_user_skas(void *to, const void *from, int n);
1671 +extern int strncpy_from_user_skas(char *dst, const char *src, int count);
1672 +extern int __clear_user_skas(void *mem, int len);
1673 +extern int clear_user_skas(void *mem, int len);
1674 +extern int strnlen_user_skas(const void *str, int len);
1675 +
1676 +#endif
1677 +
1678 +/*
1679 + * Overrides for Emacs so that we follow Linus's tabbing style.
1680 + * Emacs will notice this stuff at the end of the file and automatically
1681 + * adjust the settings for this buffer only.  This must remain at the end
1682 + * of the file.
1683 + * ---------------------------------------------------------------------------
1684 + * Local variables:
1685 + * c-file-style: "linux"
1686 + * End:
1687 + */
1688 +/*
1689 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
1690 + * Licensed under the GPL
1691 + */
1692 +
1693 +#ifndef __SKAS_UACCESS_H
1694 +#define __SKAS_UACCESS_H
1695 +
1696 +#include "asm/errno.h"
1697  
1698  #define access_ok_skas(type, addr, size) \
1699         ((segment_eq(get_fs(), KERNEL_DS)) || \
1700 Index: linux-2.6.10/arch/um/kernel/tt/syscall_user.c
1701 ===================================================================
1702 --- linux-2.6.10.orig/arch/um/kernel/tt/syscall_user.c  2004-12-25 05:35:01.000000000 +0800
1703 +++ linux-2.6.10/arch/um/kernel/tt/syscall_user.c       2005-04-06 23:44:30.275020088 +0800
1704 @@ -42,37 +42,31 @@
1705         syscall_trace(regs, 1);
1706         record_syscall_end(index, result);
1707  }
1708 -
1709 -int do_syscall(void *task, int pid, int local_using_sysemu)
1710 -{
1711 -       unsigned long proc_regs[FRAME_SIZE];
1712 -       union uml_pt_regs *regs;
1713 -       int syscall;
1714 -
1715 -       if(ptrace_getregs(pid, proc_regs) < 0)
1716 -               tracer_panic("Couldn't read registers");
1717 -       syscall = PT_SYSCALL_NR(proc_regs);
1718 -
1719 -       regs = TASK_REGS(task);
1720 -       UPT_SYSCALL_NR(regs) = syscall;
1721 -
1722 -       if(syscall < 0)
1723 -               return(0);
1724 -
1725 -       if((syscall != __NR_sigreturn) &&
1726 -          ((unsigned long *) PT_IP(proc_regs) >= &_stext) && 
1727 -          ((unsigned long *) PT_IP(proc_regs) <= &_etext))
1728 -               tracer_panic("I'm tracing myself and I can't get out");
1729 -
1730 -       if(local_using_sysemu)
1731 -               return(1);
1732 -
1733 -       if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, 
1734 -                 __NR_getpid) < 0)
1735 -               tracer_panic("do_syscall : Nullifying syscall failed, "
1736 -                            "errno = %d", errno);
1737 -       return(1);
1738 -}
1739 +  
1740 + void do_sigtrap(void *task)
1741 + {
1742 +       UPT_SYSCALL_NR(TASK_REGS(task)) = -1;
1743 + }
1744
1745 + void do_syscall(void *task, int pid, int local_using_sysemu)
1746 +  {
1747 +       unsigned long proc_regs[FRAME_SIZE];
1748 +  
1749 +       if(ptrace_getregs(pid, proc_regs) < 0)
1750 +               tracer_panic("Couldn't read registers");
1751 +  
1752 +       UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs);
1753 +  
1754 +       if(((unsigned long *) PT_IP(proc_regs) >= &_stext) &&
1755 +          ((unsigned long *) PT_IP(proc_regs) <= &_etext))
1756 +               tracer_panic("I'm tracing myself and I can't get out");
1757 +  
1758 +       /* syscall number -1 in sysemu skips syscall restarting in host */
1759 +       if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, 
1760 +                 local_using_sysemu ? -1 : __NR_getpid) < 0)
1761 +               tracer_panic("do_syscall : Nullifying syscall failed, "
1762 +                            "errno = %d", errno);
1763 +  }
1764  
1765  /*
1766   * Overrides for Emacs so that we follow Linus's tabbing style.
1767 Index: linux-2.6.10/arch/um/kernel/tt/sys-i386/Makefile
1768 ===================================================================
1769 --- linux-2.6.10.orig/arch/um/kernel/tt/sys-i386/Makefile       2004-12-25 05:34:32.000000000 +0800
1770 +++ linux-2.6.10/arch/um/kernel/tt/sys-i386/Makefile    2005-04-07 06:37:43.373923992 +0800
1771 @@ -1,12 +0,0 @@
1772 -# 
1773 -# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
1774 -# Licensed under the GPL
1775 -#
1776 -
1777 -obj-y = sigcontext.o
1778 -
1779 -USER_OBJS = sigcontext.o
1780 -USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
1781 -
1782 -$(USER_OBJS) : %.o: %.c
1783 -       $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
1784 Index: linux-2.6.10/arch/um/kernel/tt/sys-i386/sigcontext.c
1785 ===================================================================
1786 --- linux-2.6.10.orig/arch/um/kernel/tt/sys-i386/sigcontext.c   2004-12-25 05:35:39.000000000 +0800
1787 +++ linux-2.6.10/arch/um/kernel/tt/sys-i386/sigcontext.c        2005-04-07 06:37:43.373923992 +0800
1788 @@ -1,60 +0,0 @@
1789 -/* 
1790 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
1791 - * Licensed under the GPL
1792 - */
1793 -
1794 -#include <stdlib.h>
1795 -#include <asm/sigcontext.h>
1796 -#include "kern_util.h"
1797 -#include "sysdep/frame.h"
1798 -
1799 -int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data)
1800 -{
1801 -       struct arch_frame_data *arch = data;
1802 -       struct sigcontext *to = to_ptr, *from = from_ptr;
1803 -       struct _fpstate *to_fp, *from_fp;
1804 -       unsigned long sigs;
1805 -       int err;
1806 -
1807 -       to_fp = to->fpstate;
1808 -       from_fp = from->fpstate;
1809 -       sigs = to->oldmask;
1810 -       err = copy_from_user_proc(to, from, sizeof(*to));
1811 -       to->oldmask = sigs;
1812 -       if(to_fp != NULL){
1813 -               err |= copy_from_user_proc(&to->fpstate, &to_fp,
1814 -                                          sizeof(to->fpstate));
1815 -               err |= copy_from_user_proc(to_fp, from_fp, arch->fpstate_size);
1816 -       }
1817 -       return(err);
1818 -}
1819 -
1820 -int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, void *data)
1821 -{
1822 -       struct arch_frame_data *arch = data;
1823 -       struct sigcontext *to = to_ptr, *from = from_ptr;
1824 -       struct _fpstate *to_fp, *from_fp;
1825 -       int err;
1826 -
1827 -       to_fp = (struct _fpstate *) 
1828 -               (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
1829 -       from_fp = from->fpstate;
1830 -       err = copy_to_user_proc(to, from, sizeof(*to));
1831 -       if(from_fp != NULL){
1832 -               err |= copy_to_user_proc(&to->fpstate, &to_fp,
1833 -                                        sizeof(to->fpstate));
1834 -               err |= copy_to_user_proc(to_fp, from_fp, arch->fpstate_size);
1835 -       }
1836 -       return(err);
1837 -}
1838 -
1839 -/*
1840 - * Overrides for Emacs so that we follow Linus's tabbing style.
1841 - * Emacs will notice this stuff at the end of the file and automatically
1842 - * adjust the settings for this buffer only.  This must remain at the end
1843 - * of the file.
1844 - * ---------------------------------------------------------------------------
1845 - * Local variables:
1846 - * c-file-style: "linux"
1847 - * End:
1848 - */
1849 Index: linux-2.6.10/arch/um/kernel/tt/exec_user.c
1850 ===================================================================
1851 --- linux-2.6.10.orig/arch/um/kernel/tt/exec_user.c     2004-12-25 05:35:24.000000000 +0800
1852 +++ linux-2.6.10/arch/um/kernel/tt/exec_user.c  2005-04-06 23:44:30.273020392 +0800
1853 @@ -10,6 +10,7 @@
1854  #include <errno.h>
1855  #include <sys/wait.h>
1856  #include <sys/ptrace.h>
1857 +#include <linux/ptrace.h>
1858  #include <signal.h>
1859  #include "user_util.h"
1860  #include "kern_util.h"
1861 @@ -35,7 +36,10 @@
1862                 tracer_panic("do_exec failed to get registers - errno = %d",
1863                              errno);
1864  
1865 -       kill(old_pid, SIGKILL);
1866 +       os_kill_ptraced_process(old_pid, 0);
1867 +
1868 +       if (ptrace(PTRACE_OLDSETOPTIONS, new_pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
1869 +               tracer_panic("do_exec: PTRACE_SETOPTIONS failed, errno = %d", errno);
1870  
1871         if(ptrace_setregs(new_pid, regs) < 0)
1872                 tracer_panic("do_exec failed to start new proc - errno = %d",
1873 Index: linux-2.6.10/arch/um/kernel/tt/tracer.c
1874 ===================================================================
1875 --- linux-2.6.10.orig/arch/um/kernel/tt/tracer.c        2004-12-25 05:33:49.000000000 +0800
1876 +++ linux-2.6.10/arch/um/kernel/tt/tracer.c     2005-04-06 23:44:30.276019936 +0800
1877 @@ -13,6 +13,7 @@
1878  #include <string.h>
1879  #include <sys/mman.h>
1880  #include <sys/ptrace.h>
1881 +#include <linux/ptrace.h>
1882  #include <sys/time.h>
1883  #include <sys/wait.h>
1884  #include "user.h"
1885 @@ -25,7 +26,6 @@
1886  #include "mem_user.h"
1887  #include "process.h"
1888  #include "kern_util.h"
1889 -#include "frame.h"
1890  #include "chan_user.h"
1891  #include "ptrace_user.h"
1892  #include "mode.h"
1893 @@ -72,6 +72,8 @@
1894            (ptrace(PTRACE_CONT, pid, 0, 0) < 0))
1895                 tracer_panic("OP_FORK failed to attach pid");
1896         wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
1897 +       if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
1898 +               tracer_panic("OP_FORK: PTRACE_SETOPTIONS failed, errno = %d", errno);
1899         if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
1900                 tracer_panic("OP_FORK failed to continue process");
1901  }
1902 @@ -141,7 +143,7 @@
1903          * any more, the trace of those will land here.  So, we need to just 
1904          * PTRACE_SYSCALL it.
1905          */
1906 -       case SIGTRAP:
1907 +       case (SIGTRAP|SYSCALL_TRAP):
1908                 if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
1909                         tracer_panic("sleeping_process_signal : Failed to "
1910                                      "PTRACE_SYSCALL pid %d, errno = %d\n",
1911 @@ -184,9 +186,8 @@
1912         unsigned long eip = 0;
1913         int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0;
1914         int last_index, proc_id = 0, n, err, old_tracing = 0, strace = 0;
1915 -       int pt_syscall_parm, local_using_sysemu;
1916 +       int pt_syscall_parm, local_using_sysemu = 0;
1917  
1918 -       capture_signal_stack();
1919         signal(SIGPIPE, SIG_IGN);
1920         setup_tracer_winch();
1921         tracing_pid = os_getpid();
1922 @@ -198,6 +199,10 @@
1923                 printf("waitpid on idle thread failed, errno = %d\n", errno);
1924                 exit(1);
1925         }
1926 +       if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) {
1927 +               printf("Failed to PTRACE_SETOPTIONS for idle thread, errno = %d\n", errno);
1928 +               exit(1);
1929 +       }
1930         if((ptrace(PTRACE_CONT, pid, 0, 0) < 0)){
1931                 printf("Failed to continue idle thread, errno = %d\n", errno);
1932                 exit(1);
1933 @@ -297,7 +302,8 @@
1934                         task = cpu_tasks[proc_id].task;
1935                         tracing = is_tracing(task);
1936                         old_tracing = tracing;
1937 -
1938 +                       if ( tracing ) /* Assume: no syscall, when coming from user */
1939 +                               do_sigtrap(task);
1940                         local_using_sysemu = get_using_sysemu();
1941                         pt_syscall_parm = local_using_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL;
1942  
1943 @@ -306,6 +312,15 @@
1944                                 sig = 0;
1945                                 op = do_proc_op(task, proc_id);
1946                                 switch(op){
1947 +                               /*
1948 +                                * This is called when entering user mode; after
1949 +                                * this, we start intercepting syscalls.
1950 +                                *
1951 +                                * In fact, a process is started in kernel mode,
1952 +                                * so with is_tracing() == 0 (and that is reset
1953 +                                * when executing syscalls, since UML kernel has
1954 +                                * the right to do syscalls);
1955 +                                */
1956                                 case OP_TRACE_ON:
1957                                         arch_leave_kernel(task, pid);
1958                                         tracing = 1;
1959 @@ -314,7 +329,13 @@
1960                                 case OP_HALT:
1961                                         unmap_physmem();
1962                                         kmalloc_ok = 0;
1963 -                                       ptrace(PTRACE_KILL, pid, 0, 0);
1964 +                                       os_kill_ptraced_process(pid, 0);
1965 +                                       /* Now let's reap remaining zombies */
1966 +                                       errno = 0;
1967 +                                       do {
1968 +                                               waitpid(-1, &status,
1969 +                                                       WUNTRACED);
1970 +                                       } while (errno != ECHILD);
1971                                         return(op == OP_REBOOT);
1972                                 case OP_NONE:
1973                                         printf("Detaching pid %d\n", pid);
1974 @@ -328,14 +349,26 @@
1975                                  */
1976                                 pid = cpu_tasks[proc_id].pid;
1977                                 break;
1978 +                       case (SIGTRAP|SYSCALL_TRAP):
1979 +                               if(!tracing && (debugger_pid != -1)){
1980 +                                       child_signal(pid, W_STOPCODE(SIGTRAP));
1981 +                                       continue;
1982 +                               }
1983 +                               tracing = 0;
1984 +                               /* local_using_sysemu has been already set
1985 +                                * below, since if we are here, is_tracing() on
1986 +                                * the traced task was 1, i.e. the process had
1987 +                                * already run through one iteration of the
1988 +                                * loop which executed a OP_TRACE_ON request.*/
1989 +                               do_syscall(task, pid, local_using_sysemu);
1990 +                               sig = SIGUSR2;
1991 +                               break;
1992                         case SIGTRAP:
1993                                 if(!tracing && (debugger_pid != -1)){
1994                                         child_signal(pid, status);
1995                                         continue;
1996                                 }
1997                                 tracing = 0;
1998 -                               if(do_syscall(task, pid, local_using_sysemu))
1999 -                                       sig = SIGUSR2;
2000                                 break;
2001                         case SIGPROF:
2002                                 if(tracing) sig = 0;
2003 @@ -371,6 +404,9 @@
2004                                 continue;
2005                         }
2006  
2007 +                       local_using_sysemu = get_using_sysemu();
2008 +                       pt_syscall_parm = local_using_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL;
2009
2010                         if(tracing){
2011                                 if(singlestepping(task))
2012                                         cont_type = PTRACE_SINGLESTEP;
2013 Index: linux-2.6.10/arch/um/kernel/tt/Makefile
2014 ===================================================================
2015 --- linux-2.6.10.orig/arch/um/kernel/tt/Makefile        2004-12-25 05:34:57.000000000 +0800
2016 +++ linux-2.6.10/arch/um/kernel/tt/Makefile     2005-04-06 23:44:30.277019784 +0800
2017 @@ -8,7 +8,7 @@
2018  
2019  obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
2020         syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \
2021 -       uaccess.o uaccess_user.o sys-$(SUBARCH)/
2022 +       uaccess.o uaccess_user.o 
2023  
2024  obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/
2025  
2026 Index: linux-2.6.10/arch/um/kernel/tt/include/mode-tt.h
2027 ===================================================================
2028 --- linux-2.6.10.orig/arch/um/kernel/tt/include/mode-tt.h       2004-12-25 05:35:01.000000000 +0800
2029 +++ linux-2.6.10/arch/um/kernel/tt/include/mode-tt.h    2005-04-06 23:44:30.272020544 +0800
2030 @@ -14,6 +14,41 @@
2031  
2032  extern int tracer(int (*init_proc)(void *), void *sp);
2033  extern void user_time_init_tt(void);
2034 +extern void sig_handler_common_tt(int sig, void *sc);
2035 +extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
2036 +extern void reboot_tt(void);
2037 +extern void halt_tt(void);
2038 +extern int is_tracer_winch(int pid, int fd, void *data);
2039 +extern void kill_off_processes_tt(void);
2040 +
2041 +#endif
2042 +
2043 +/*
2044 + * Overrides for Emacs so that we follow Linus's tabbing style.
2045 + * Emacs will notice this stuff at the end of the file and automatically
2046 + * adjust the settings for this buffer only.  This must remain at the end
2047 + * of the file.
2048 + * ---------------------------------------------------------------------------
2049 + * Local variables:
2050 + * c-file-style: "linux"
2051 + * End:
2052 + */
2053 +/*
2054 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
2055 + * Licensed under the GPL
2056 + */
2057 +
2058 +#ifndef __MODE_TT_H__
2059 +#define __MODE_TT_H__
2060 +
2061 +#include "sysdep/ptrace.h"
2062 +
2063 +enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
2064 +
2065 +extern int tracing_pid;
2066 +
2067 +extern int tracer(int (*init_proc)(void *), void *sp);
2068 +extern void user_time_init_tt(void);
2069  extern int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data);
2070  extern int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr,
2071                               void *data);
2072 Index: linux-2.6.10/arch/um/kernel/tt/include/tt.h
2073 ===================================================================
2074 --- linux-2.6.10.orig/arch/um/kernel/tt/include/tt.h    2004-12-25 05:34:58.000000000 +0800
2075 +++ linux-2.6.10/arch/um/kernel/tt/include/tt.h 2005-04-06 23:44:30.273020392 +0800
2076 @@ -26,7 +26,8 @@
2077  extern int is_tracing(void *task);
2078  extern void syscall_handler(int sig, union uml_pt_regs *regs);
2079  extern void exit_kernel(int pid, void *task);
2080 -extern int do_syscall(void *task, int pid, int local_using_sysemu);
2081 +extern void do_syscall(void *task, int pid, int local_using_sysemu);
2082 +extern void do_sigtrap(void *task);
2083  extern int is_valid_pid(int pid);
2084  extern void remap_data(void *segment_start, void *segment_end, int w);
2085  
2086 Index: linux-2.6.10/arch/um/kernel/ptrace.c
2087 ===================================================================
2088 --- linux-2.6.10.orig/arch/um/kernel/ptrace.c   2004-12-25 05:35:50.000000000 +0800
2089 +++ linux-2.6.10/arch/um/kernel/ptrace.c        2005-04-06 23:44:30.254023280 +0800
2090 @@ -16,6 +16,7 @@
2091  #include "asm/uaccess.h"
2092  #include "kern_util.h"
2093  #include "ptrace_user.h"
2094 +#include "signal_user.h"
2095  
2096  /*
2097   * Called by kernel/ptrace.c when detaching..
2098 @@ -328,8 +329,10 @@
2099         /* the 0x80 provides a way for the tracing parent to distinguish
2100            between a syscall stop and SIGTRAP delivery */
2101         tracesysgood = (current->ptrace & PT_TRACESYSGOOD) && !is_singlestep;
2102 -       ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0));
2103 -
2104 +       ptrace_notify(SIGTRAP | (tracesysgood ? SYSCALL_TRAP : 0));
2105 +       if ( entryexit ) /* force do_signal() --> is_syscall() */
2106 +               set_thread_flag(TIF_SIGPENDING);
2107
2108         /* force do_signal() --> is_syscall() */
2109         set_thread_flag(TIF_SIGPENDING);
2110  
2111 Index: linux-2.6.10/arch/um/kernel/dyn.lds.S
2112 ===================================================================
2113 --- linux-2.6.10.orig/arch/um/kernel/dyn.lds.S  2004-12-25 05:34:48.000000000 +0800
2114 +++ linux-2.6.10/arch/um/kernel/dyn.lds.S       2005-04-06 23:44:30.253023432 +0800
2115 @@ -7,8 +7,11 @@
2116  
2117  SECTIONS
2118  {
2119 +  PROVIDE (__executable_start = START);
2120    . = START + SIZEOF_HEADERS;
2121    .interp         : { *(.interp) }
2122 +  /* Used in arch/um/kernel/mem.c. Any memory between START and __binary_start
2123 +   * is remapped.*/
2124    __binary_start = .;
2125    . = ALIGN(4096);             /* Init code and data */
2126    _stext = .;
2127 Index: linux-2.6.10/arch/um/kernel/um_arch.c
2128 ===================================================================
2129 --- linux-2.6.10.orig/arch/um/kernel/um_arch.c  2004-12-25 05:35:24.000000000 +0800
2130 +++ linux-2.6.10/arch/um/kernel/um_arch.c       2005-04-06 23:44:30.239025560 +0800
2131 @@ -44,11 +44,6 @@
2132         .ipi_pipe               = { -1, -1 }
2133  };
2134  
2135 -/* Placeholder to make UML link until the vsyscall stuff is actually
2136 - * implemented
2137 - */
2138 -void *__kernel_vsyscall;
2139 -
2140  unsigned long thread_saved_pc(struct task_struct *task)
2141  {
2142         return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
2143 @@ -326,6 +321,11 @@
2144          */
2145         check_tmpexec();
2146  
2147 +       /* Need to check this early because mmapping happens before the
2148 +        * kernel is running.
2149 +        */
2150 +       check_tmpexec();
2151 +
2152         brk_start = (unsigned long) sbrk(0);
2153         CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start);
2154         /* Increase physical memory size for exec-shield users
2155 Index: linux-2.6.10/arch/um/kernel/time.c
2156 ===================================================================
2157 --- linux-2.6.10.orig/arch/um/kernel/time.c     2004-12-25 05:34:26.000000000 +0800
2158 +++ linux-2.6.10/arch/um/kernel/time.c  2005-04-06 23:44:30.237025864 +0800
2159 @@ -60,6 +60,9 @@
2160            (setitimer(ITIMER_REAL, &disable, NULL) < 0))
2161                 printk("disnable_timer - setitimer failed, errno = %d\n",
2162                        errno);
2163 +       /* If there are signals already queued, after unblocking ignore them */
2164 +       set_handler(SIGALRM, SIG_IGN, 0, -1);
2165 +       set_handler(SIGVTALRM, SIG_IGN, 0, -1);
2166  }
2167  
2168  void switch_timers(int to_real)
2169 Index: linux-2.6.10/arch/um/kernel/process_kern.c
2170 ===================================================================
2171 --- linux-2.6.10.orig/arch/um/kernel/process_kern.c     2004-12-25 05:34:57.000000000 +0800
2172 +++ linux-2.6.10/arch/um/kernel/process_kern.c  2005-04-06 23:44:30.240025408 +0800
2173 @@ -291,8 +291,6 @@
2174  
2175  EXPORT_SYMBOL(disable_hlt);
2176  
2177 -extern int signal_frame_size;
2178 -
2179  void *um_kmalloc(int size)
2180  {
2181         return(kmalloc(size, GFP_KERNEL));
2182 Index: linux-2.6.10/arch/um/kernel/trap_user.c
2183 ===================================================================
2184 --- linux-2.6.10.orig/arch/um/kernel/trap_user.c        2004-12-25 05:34:44.000000000 +0800
2185 +++ linux-2.6.10/arch/um/kernel/trap_user.c     2005-04-06 23:44:30.277019784 +0800
2186 @@ -18,7 +18,6 @@
2187  #include "sigcontext.h"
2188  #include "sysdep/sigcontext.h"
2189  #include "irq_user.h"
2190 -#include "frame_user.h"
2191  #include "signal_user.h"
2192  #include "time_user.h"
2193  #include "task.h"
2194 Index: linux-2.6.10/arch/um/kernel/signal_kern.c
2195 ===================================================================
2196 --- linux-2.6.10.orig/arch/um/kernel/signal_kern.c      2004-12-25 05:34:58.000000000 +0800
2197 +++ linux-2.6.10/arch/um/kernel/signal_kern.c   2005-04-06 23:44:30.264021760 +0800
2198 @@ -230,53 +230,6 @@
2199         return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
2200  }
2201  
2202 -extern int userspace_pid[];
2203 -
2204 -static int copy_sc_from_user(struct pt_regs *to, void *from, 
2205 -                            struct arch_frame_data *arch)
2206 -{
2207 -       int ret;
2208 -
2209 -       ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, arch),
2210 -                         copy_sc_from_user_skas(userspace_pid[0],
2211 -                                                &to->regs, from));
2212 -       return(ret);
2213 -}
2214 -
2215 -long sys_sigreturn(struct pt_regs regs)
2216 -{
2217 -       void __user *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
2218 -       void __user *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
2219 -       int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
2220 -
2221 -       spin_lock_irq(&current->sighand->siglock);
2222 -       copy_from_user(&current->blocked.sig[0], sc_sigmask(sc), 
2223 -                      sizeof(current->blocked.sig[0]));
2224 -       copy_from_user(&current->blocked.sig[1], mask, sig_size);
2225 -       sigdelsetmask(&current->blocked, ~_BLOCKABLE);
2226 -       recalc_sigpending();
2227 -       spin_unlock_irq(&current->sighand->siglock);
2228 -       copy_sc_from_user(&current->thread.regs, sc, 
2229 -                         &signal_frame_sc.common.arch);
2230 -       return(PT_REGS_SYSCALL_RET(&current->thread.regs));
2231 -}
2232 -
2233 -long sys_rt_sigreturn(struct pt_regs regs)
2234 -{
2235 -       unsigned long sp = PT_REGS_SP(&current->thread.regs);
2236 -       struct ucontext __user *uc = sp_to_uc(sp);
2237 -       int sig_size = _NSIG_WORDS * sizeof(unsigned long);
2238 -
2239 -       spin_lock_irq(&current->sighand->siglock);
2240 -       copy_from_user(&current->blocked, &uc->uc_sigmask, sig_size);
2241 -       sigdelsetmask(&current->blocked, ~_BLOCKABLE);
2242 -       recalc_sigpending();
2243 -       spin_unlock_irq(&current->sighand->siglock);
2244 -       copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext,
2245 -                         &signal_frame_si.common.arch);
2246 -       return(PT_REGS_SYSCALL_RET(&current->thread.regs));
2247 -}
2248 -
2249  /*
2250   * Overrides for Emacs so that we follow Linus's tabbing style.
2251   * Emacs will notice this stuff at the end of the file and automatically
2252 Index: linux-2.6.10/arch/um/kernel/uml.lds.S
2253 ===================================================================
2254 --- linux-2.6.10.orig/arch/um/kernel/uml.lds.S  2004-12-25 05:34:44.000000000 +0800
2255 +++ linux-2.6.10/arch/um/kernel/uml.lds.S       2005-04-06 23:44:30.254023280 +0800
2256 @@ -7,8 +7,12 @@
2257  
2258  SECTIONS
2259  {
2260 +  /*This must contain the right address - not quite the default ELF one.*/
2261 +  PROVIDE (__executable_start = START);
2262    . = START + SIZEOF_HEADERS;
2263  
2264 +  /* Used in arch/um/kernel/mem.c. Any memory between START and __binary_start
2265 +   * is remapped.*/
2266    __binary_start = .;
2267  #ifdef MODE_TT
2268    .thread_private : {
2269 @@ -20,9 +24,13 @@
2270    }
2271    . = ALIGN(4096);
2272    .remap : { arch/um/kernel/tt/unmap_fin.o (.text) }
2273 -#endif
2274  
2275 +  /*If you put this after #endif, STATIC build without TT mode
2276 +  gives a segfaulting binary. And after all, a hole just after
2277 +  binary_start is not very polite to glibc.*/
2278    . = ALIGN(4096);             /* Init code and data */
2279 +#endif
2280 +
2281    _stext = .;
2282    __init_begin = .;
2283    .init.text : {
2284 Index: linux-2.6.10/arch/um/kernel/ksyms.c
2285 ===================================================================
2286 --- linux-2.6.10.orig/arch/um/kernel/ksyms.c    2004-12-25 05:33:50.000000000 +0800
2287 +++ linux-2.6.10/arch/um/kernel/ksyms.c 2005-04-06 23:44:30.238025712 +0800
2288 @@ -48,6 +48,7 @@
2289  EXPORT_SYMBOL(mode_tt);
2290  EXPORT_SYMBOL(handle_page_fault);
2291  EXPORT_SYMBOL(find_iomem);
2292 +EXPORT_SYMBOL(end_iomem);
2293  
2294  #ifdef CONFIG_MODE_TT
2295  EXPORT_SYMBOL(strncpy_from_user_tt);
2296 Index: linux-2.6.10/arch/um/kernel/signal_user.c
2297 ===================================================================
2298 --- linux-2.6.10.orig/arch/um/kernel/signal_user.c      2004-12-25 05:35:23.000000000 +0800
2299 +++ linux-2.6.10/arch/um/kernel/signal_user.c   2005-04-06 23:44:30.252023584 +0800
2300 @@ -61,6 +61,10 @@
2301   * disable profiling; it's safe because the profiling code does not interact
2302   * with the kernel code at all.*/
2303  
2304 +/* Both here and in set/get_signal we don't touch SIGPROF, because we must not
2305 + * disable profiling; it's safe because the profiling code does not interact
2306 + * with the kernel code at all.*/
2307 +
2308  static void change_signals(int type)
2309  {
2310         sigset_t mask;
2311 Index: linux-2.6.10/arch/um/kernel/mem_user.c
2312 ===================================================================
2313 --- linux-2.6.10.orig/arch/um/kernel/mem_user.c 2004-12-25 05:34:57.000000000 +0800
2314 +++ linux-2.6.10/arch/um/kernel/mem_user.c      2005-04-06 23:44:30.237025864 +0800
2315 @@ -101,6 +101,8 @@
2316         }
2317         printf("OK\n");
2318         munmap(addr, UM_KERN_PAGE_SIZE);
2319 +
2320 +       os_close_file(fd);
2321  }
2322  
2323  static int have_devanon = 0;
2324 @@ -261,6 +263,39 @@
2325  }
2326  #endif
2327  
2328 +#if 0
2329 +/* Debugging facility for dumping stuff out to the host, avoiding the timing
2330 + * problems that come with printf and breakpoints.
2331 + * Enable in case of emergency.
2332 + */
2333 +
2334 +int logging = 1;
2335 +int logging_fd = -1;
2336 +
2337 +int logging_line = 0;
2338 +char logging_buf[512];
2339 +
2340 +void log(char *fmt, ...)
2341 +{
2342 +        va_list ap;
2343 +        struct timeval tv;
2344 +        struct openflags flags;
2345 +
2346 +        if(logging == 0) return;
2347 +        if(logging_fd < 0){
2348 +                flags = of_create(of_trunc(of_rdwr(OPENFLAGS())));
2349 +                logging_fd = os_open_file("log", flags, 0644);
2350 +        }
2351 +        gettimeofday(&tv, NULL);
2352 +        sprintf(logging_buf, "%d\t %u.%u  ", logging_line++, tv.tv_sec,
2353 +                tv.tv_usec);
2354 +        va_start(ap, fmt);
2355 +        vsprintf(&logging_buf[strlen(logging_buf)], fmt, ap);
2356 +        va_end(ap);
2357 +        write(logging_fd, logging_buf, strlen(logging_buf));
2358 +}
2359 +#endif
2360 +
2361  /*
2362   * Overrides for Emacs so that we follow Linus's tabbing style.
2363   * Emacs will notice this stuff at the end of the file and automatically
2364 Index: linux-2.6.10/arch/um/kernel/Makefile
2365 ===================================================================
2366 --- linux-2.6.10.orig/arch/um/kernel/Makefile   2004-12-25 05:35:01.000000000 +0800
2367 +++ linux-2.6.10/arch/um/kernel/Makefile        2005-04-06 23:44:30.278019632 +0800
2368 @@ -6,7 +6,7 @@
2369  extra-y := vmlinux.lds
2370  clean-files := vmlinux.lds.S
2371  
2372 -obj-y = checksum.o config.o exec_kern.o exitcode.o frame_kern.o frame.o \
2373 +obj-y = checksum.o config.o exec_kern.o exitcode.o \
2374         helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \
2375         physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \
2376         sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \
2377 Index: linux-2.6.10/arch/um/Kconfig
2378 ===================================================================
2379 --- linux-2.6.10.orig/arch/um/Kconfig   2004-12-25 05:34:45.000000000 +0800
2380 +++ linux-2.6.10/arch/um/Kconfig        2005-04-06 23:44:30.285018568 +0800
2381 @@ -139,6 +139,25 @@
2382  
2383          It is safe to say 'Y' here.
2384  
2385 +config MAGIC_SYSRQ
2386 +        bool "Magic SysRq key"
2387 +        depends on MCONSOLE
2388 +        ---help---
2389 +        If you say Y here, you will have some control over the system even
2390 +        if the system crashes for example during kernel debugging (e.g., you
2391 +        will be able to flush the buffer cache to disk, reboot the system
2392 +        immediately or dump some status information). A key for each of the
2393 +        possible requests is provided.
2394 +
2395 +        This is the feature normally accomplished by pressing a key
2396 +        while holding SysRq (Alt+PrintScreen).
2397 +
2398 +        On UML, this is accomplished by sending a "sysrq" command with
2399 +        mconsole, followed by the letter for the requested command.
2400 +
2401 +        The keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
2402 +        unless you really know what this hack does.
2403 +
2404  config HOST_2G_2G
2405         bool "2G/2G host address space split"
2406         default n
2407 @@ -153,28 +172,28 @@
2408         So, if you do not know what to do here, say 'N'.
2409  
2410  config SMP
2411 -       bool "Symmetric multi-processing support (EXPERIMENTAL)"
2412 -       default n
2413 -       depends on MODE_TT && EXPERIMENTAL
2414 -       help
2415 -       This option enables UML SMP support.
2416 -       It is NOT related to having a real SMP box. Not directly, at least.
2417 +        bool "Symmetric multi-processing support (EXPERIMENTAL)"
2418 +        default n
2419 +        depends on MODE_TT && EXPERIMENTAL
2420 +        help
2421 +        This option enables UML SMP support.
2422 +        It is NOT related to having a real SMP box. Not directly, at least.
2423 +
2424 +        UML implements virtual SMP by allowing as many processes to run
2425 +        simultaneously on the host as there are virtual processors configured.
2426 +
2427 +        Obviously, if the host is a uniprocessor, those processes will
2428 +        timeshare, but, inside UML, will appear to be running simultaneously.
2429 +        If the host is a multiprocessor, then UML processes may run
2430 +        simultaneously, depending on the host scheduler.
2431 +
2432 +        This, however, is supported only in TT mode. So, if you use the SKAS
2433 +        patch on your host, switching to TT mode and enabling SMP usually gives
2434 +        you worse performances.
2435 +        Also, since the support for SMP has been under-developed, there could
2436 +        be some bugs being exposed by enabling SMP.
2437  
2438 -       UML implements virtual SMP by allowing as many processes to run
2439 -       simultaneously on the host as there are virtual processors configured.
2440 -
2441 -       Obviously, if the host is a uniprocessor, those processes will
2442 -       timeshare, but, inside UML, will appear to be running simultaneously.
2443 -       If the host is a multiprocessor, then UML processes may run
2444 -       simultaneously, depending on the host scheduler.
2445 -
2446 -       This, however, is supported only in TT mode. So, if you use the SKAS
2447 -       patch on your host, switching to TT mode and enabling SMP usually gives
2448 -       you worse performances.
2449 -       Also, since the support for SMP has been under-developed, there could
2450 -       be some bugs being exposed by enabling SMP.
2451 -
2452 -       If you don't know what to do, say N.
2453 +        If you don't know what to do, say N.
2454  
2455  config NR_CPUS
2456         int "Maximum number of CPUs (2-32)"
2457 @@ -282,4 +301,8 @@
2458         bool
2459         default n
2460  
2461 +config INPUT
2462 +       bool
2463 +       default n
2464 +
2465  source "arch/um/Kconfig.debug"
2466 Index: linux-2.6.10/arch/um/include/frame.h
2467 ===================================================================
2468 --- linux-2.6.10.orig/arch/um/include/frame.h   2004-12-25 05:34:31.000000000 +0800
2469 +++ linux-2.6.10/arch/um/include/frame.h        2005-04-07 06:37:43.373923992 +0800
2470 @@ -1,53 +0,0 @@
2471 -/* 
2472 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
2473 - * Licensed under the GPL
2474 - */
2475 -
2476 -#ifndef __FRAME_H_
2477 -#define __FRAME_H_
2478 -
2479 -#include "sysdep/frame.h"
2480 -
2481 -struct frame_common {
2482 -       void *data;
2483 -       int len;
2484 -       int sig_index;
2485 -       int sr_index;
2486 -       int sr_relative;
2487 -       int sp_index;
2488 -       struct arch_frame_data arch;
2489 -};
2490 -
2491 -struct sc_frame {
2492 -       struct frame_common common;
2493 -       int sc_index;
2494 -};
2495 -
2496 -extern struct sc_frame signal_frame_sc;
2497 -
2498 -extern struct sc_frame signal_frame_sc_sr;
2499 -
2500 -struct si_frame {
2501 -       struct frame_common common;
2502 -       int sip_index;
2503 -       int si_index;
2504 -       int ucp_index;
2505 -       int uc_index;
2506 -};
2507 -
2508 -extern struct si_frame signal_frame_si;
2509 -
2510 -extern void capture_signal_stack(void);
2511 -
2512 -#endif
2513 -
2514 -/*
2515 - * Overrides for Emacs so that we follow Linus's tabbing style.
2516 - * Emacs will notice this stuff at the end of the file and automatically
2517 - * adjust the settings for this buffer only.  This must remain at the end
2518 - * of the file.
2519 - * ---------------------------------------------------------------------------
2520 - * Local variables:
2521 - * c-file-style: "linux"
2522 - * End:
2523 - */
2524 Index: linux-2.6.10/arch/um/include/elf_user.h
2525 ===================================================================
2526 --- linux-2.6.10.orig/arch/um/include/elf_user.h        2005-04-07 06:37:43.373923992 +0800
2527 +++ linux-2.6.10/arch/um/include/elf_user.h     2005-04-06 23:44:30.231026776 +0800
2528 @@ -0,0 +1,19 @@
2529 +/*
2530 + * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
2531 + * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
2532 + * Licensed under the GPL
2533 + */
2534 +
2535 +#ifndef __ELF_USER_H__
2536 +#define __ELF_USER_H__
2537 +
2538 +/* For compilation on a host that doesn't support AT_SYSINFO (Linux 2.4)  */
2539 +
2540 +#ifndef AT_SYSINFO
2541 +#define AT_SYSINFO 32
2542 +#endif
2543 +#ifndef AT_SYSINFO_EHDR
2544 +#define AT_SYSINFO_EHDR 33
2545 +#endif
2546 +
2547 +#endif
2548 Index: linux-2.6.10/arch/um/include/signal_user.h
2549 ===================================================================
2550 --- linux-2.6.10.orig/arch/um/include/signal_user.h     2004-12-25 05:33:49.000000000 +0800
2551 +++ linux-2.6.10/arch/um/include/signal_user.h  2005-04-06 23:44:30.232026624 +0800
2552 @@ -14,6 +14,8 @@
2553  extern int set_signals(int enable);
2554  extern int get_signals(void);
2555  
2556 +#define SYSCALL_TRAP 0x80
2557 +
2558  #endif
2559  
2560  /*
2561 Index: linux-2.6.10/arch/um/include/skas_ptrace.h
2562 ===================================================================
2563 --- linux-2.6.10.orig/arch/um/include/skas_ptrace.h     2004-12-25 05:35:27.000000000 +0800
2564 +++ linux-2.6.10/arch/um/include/skas_ptrace.h  2005-04-06 23:44:30.232026624 +0800
2565 @@ -6,6 +6,7 @@
2566  #ifndef __SKAS_PTRACE_H
2567  #define __SKAS_PTRACE_H
2568  
2569 +#ifndef PTRACE_FAULTINFO
2570  struct ptrace_faultinfo {
2571         int is_write;
2572         unsigned long addr;
2573 @@ -21,6 +22,7 @@
2574  #define PTRACE_SIGPENDING 53
2575  #define PTRACE_LDT 54
2576  #define PTRACE_SWITCH_MM 55
2577 +#endif
2578  
2579  #endif
2580  
2581 Index: linux-2.6.10/arch/um/include/frame_kern.h
2582 ===================================================================
2583 --- linux-2.6.10.orig/arch/um/include/frame_kern.h      2004-12-25 05:34:57.000000000 +0800
2584 +++ linux-2.6.10/arch/um/include/frame_kern.h   2005-04-06 23:44:30.228027232 +0800
2585 @@ -6,8 +6,8 @@
2586  #ifndef __FRAME_KERN_H_
2587  #define __FRAME_KERN_H_
2588  
2589 -#include "frame.h"
2590 -#include "sysdep/frame_kern.h"
2591 +#define _S(nr) (1<<((nr)-1))
2592 +#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
2593  
2594  extern int setup_signal_stack_sc(unsigned long stack_top, int sig, 
2595                                  struct k_sigaction *ka,
2596 Index: linux-2.6.10/arch/um/include/ptrace_user.h
2597 ===================================================================
2598 --- linux-2.6.10.orig/arch/um/include/ptrace_user.h     2004-12-25 05:33:51.000000000 +0800
2599 +++ linux-2.6.10/arch/um/include/ptrace_user.h  2005-04-06 23:44:30.229027080 +0800
2600 @@ -26,4 +26,35 @@
2601  int get_using_sysemu(void);
2602  extern int sysemu_supported;
2603  
2604 +
2605 +/* syscall emulation path in ptrace */
2606 +
2607 +#ifndef PTRACE_SYSEMU
2608 +#define PTRACE_SYSEMU 31
2609 +#endif
2610 +
2611 +/* On architectures, that started to support PTRACE_O_TRACESYSGOOD
2612 + * in linux 2.4, there are two different definitions of
2613 + * PTRACE_SETOPTIONS: linux 2.4 uses 21 while linux 2.6 uses 0x4200.
2614 + * For binary compatibility, 2.6 also supports the old "21", named
2615 + * PTRACE_OLDSETOPTION. On these architectures, UML always must use
2616 + * "21", to ensure the kernel runs on 2.4 and 2.6 host without
2617 + * recompilation. So, we use PTRACE_OLDSETOPTIONS in UML.
2618 + * We also want to be able to build the kernel on 2.4, which doesn't
2619 + * have PTRACE_OLDSETOPTIONS. So, if it is missing, we declare
2620 + * PTRACE_OLDSETOPTIONS to to be the same as PTRACE_SETOPTIONS.
2621 + *
2622 + * On architectures, that start to support PTRACE_O_TRACESYSGOOD on
2623 + * linux 2.6, PTRACE_OLDSETOPTIONS never is defined, and also isn't
2624 + * supported by the host kernel. In that case, our trick lets us use
2625 + * the new 0x4200 with the name PTRACE_OLDSETOPTIONS.
2626 + */
2627 +#ifndef PTRACE_OLDSETOPTIONS
2628 +#define PTRACE_OLDSETOPTIONS PTRACE_SETOPTIONS
2629 +#endif
2630 +
2631 +void set_using_sysemu(int value);
2632 +int get_using_sysemu(void);
2633 +extern int sysemu_supported;
2634 +
2635  #endif
2636 Index: linux-2.6.10/arch/um/include/sysdep-i386/frame.h
2637 ===================================================================
2638 --- linux-2.6.10.orig/arch/um/include/sysdep-i386/frame.h       2004-12-25 05:35:01.000000000 +0800
2639 +++ linux-2.6.10/arch/um/include/sysdep-i386/frame.h    2005-04-07 06:37:43.373923992 +0800
2640 @@ -1,29 +0,0 @@
2641 -/* 
2642 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
2643 - * Licensed under the GPL
2644 - */
2645 -
2646 -#ifndef __FRAME_I386_H
2647 -#define __FRAME_I386_H
2648 -
2649 -struct arch_frame_data_raw {
2650 -       unsigned long fp_start;
2651 -       unsigned long sr;
2652 -};
2653 -
2654 -struct arch_frame_data {
2655 -       int fpstate_size;
2656 -};
2657 -
2658 -#endif
2659 -
2660 -/*
2661 - * Overrides for Emacs so that we follow Linus's tabbing style.
2662 - * Emacs will notice this stuff at the end of the file and automatically
2663 - * adjust the settings for this buffer only.  This must remain at the end
2664 - * of the file.
2665 - * ---------------------------------------------------------------------------
2666 - * Local variables:
2667 - * c-file-style: "linux"
2668 - * End:
2669 - */
2670 Index: linux-2.6.10/arch/um/include/sysdep-i386/frame_kern.h
2671 ===================================================================
2672 --- linux-2.6.10.orig/arch/um/include/sysdep-i386/frame_kern.h  2004-12-25 05:34:26.000000000 +0800
2673 +++ linux-2.6.10/arch/um/include/sysdep-i386/frame_kern.h       2005-04-07 06:37:43.373923992 +0800
2674 @@ -1,69 +0,0 @@
2675 -/* 
2676 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
2677 - * Licensed under the GPL
2678 - */
2679 -
2680 -#ifndef __FRAME_KERN_I386_H
2681 -#define __FRAME_KERN_I386_H
2682 -
2683 -/* This is called from sys_sigreturn.  It takes the sp at the point of the
2684 - * sigreturn system call and returns the address of the sigcontext struct
2685 - * on the stack.
2686 - */
2687 -
2688 -static inline void *sp_to_sc(unsigned long sp)
2689 -{
2690 -       return((void *) sp);
2691 -}
2692 -
2693 -static inline void *sp_to_uc(unsigned long sp)
2694 -{
2695 -       unsigned long uc;
2696 -
2697 -       uc = sp + signal_frame_si.uc_index - 
2698 -               signal_frame_si.common.sp_index - 4;
2699 -       return((void *) uc);
2700 -}
2701 -
2702 -static inline void *sp_to_rt_sc(unsigned long sp)
2703 -{
2704 -       unsigned long sc;
2705 -
2706 -       sc = sp - signal_frame_si.common.sp_index + 
2707 -               signal_frame_si.common.len - 4;
2708 -       return((void *) sc);
2709 -}
2710 -
2711 -static inline void *sp_to_mask(unsigned long sp)
2712 -{
2713 -       unsigned long mask;
2714 -
2715 -       mask = sp - signal_frame_sc.common.sp_index + 
2716 -               signal_frame_sc.common.len - 8;
2717 -       return((void *) mask);
2718 -}
2719 -
2720 -extern int sc_size(void *data);
2721 -
2722 -static inline void *sp_to_rt_mask(unsigned long sp)
2723 -{
2724 -       unsigned long mask;
2725 -
2726 -       mask = sp - signal_frame_si.common.sp_index + 
2727 -               signal_frame_si.common.len + 
2728 -               sc_size(&signal_frame_si.common.arch) - 4;
2729 -       return((void *) mask);
2730 -}
2731 -
2732 -#endif
2733 -
2734 -/*
2735 - * Overrides for Emacs so that we follow Linus's tabbing style.
2736 - * Emacs will notice this stuff at the end of the file and automatically
2737 - * adjust the settings for this buffer only.  This must remain at the end
2738 - * of the file.
2739 - * ---------------------------------------------------------------------------
2740 - * Local variables:
2741 - * c-file-style: "linux"
2742 - * End:
2743 - */
2744 Index: linux-2.6.10/arch/um/include/sysdep-i386/frame_user.h
2745 ===================================================================
2746 --- linux-2.6.10.orig/arch/um/include/sysdep-i386/frame_user.h  2004-12-25 05:35:28.000000000 +0800
2747 +++ linux-2.6.10/arch/um/include/sysdep-i386/frame_user.h       2005-04-07 06:37:43.373923992 +0800
2748 @@ -1,91 +0,0 @@
2749 -/* 
2750 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
2751 - * Licensed under the GPL
2752 - */
2753 -
2754 -#ifndef __FRAME_USER_I386_H
2755 -#define __FRAME_USER_I386_H
2756 -
2757 -#include <asm/page.h>
2758 -#include "sysdep/frame.h"
2759 -
2760 -/* This stuff is to calculate the size of the fp state struct at runtime
2761 - * because it has changed between 2.2 and 2.4 and it would be good for a
2762 - * UML compiled on one to work on the other.
2763 - * So, setup_arch_frame_raw fills in the arch struct with the raw data, which
2764 - * just contains the address of the end of the sigcontext.  This is invoked
2765 - * from the signal handler.
2766 - * setup_arch_frame uses that data to figure out what 
2767 - * arch_frame_data.fpstate_size should be.  It really has no idea, since it's
2768 - * not allowed to do sizeof(struct fpstate) but it's safe to consider that it's
2769 - * everything from the end of the sigcontext up to the top of the stack.  So,
2770 - * it masks off the page number to get the offset within the page and subtracts
2771 - * that from the page size, and that's how big the fpstate struct will be
2772 - * considered to be.
2773 - */
2774 -
2775 -static inline void setup_arch_frame_raw(struct arch_frame_data_raw *data,
2776 -                                       void *end, unsigned long srp)
2777 -{
2778 -       unsigned long sr = *((unsigned long *) srp);
2779 -
2780 -       data->fp_start = (unsigned long) end;
2781 -       if((sr & PAGE_MASK) == ((unsigned long) end & PAGE_MASK))
2782 -               data->sr = sr;
2783 -       else data->sr = 0;
2784 -}
2785 -
2786 -static inline void setup_arch_frame(struct arch_frame_data_raw *in, 
2787 -                                   struct arch_frame_data *out)
2788 -{
2789 -       unsigned long fpstate_start = in->fp_start;
2790 -
2791 -       if(in->sr == 0){
2792 -               fpstate_start &= ~PAGE_MASK;
2793 -               out->fpstate_size = PAGE_SIZE - fpstate_start;
2794 -       }
2795 -       else {
2796 -               out->fpstate_size = in->sr - fpstate_start;
2797 -       }
2798 -}
2799 -
2800 -/* This figures out where on the stack the SA_RESTORER function address
2801 - * is stored.  For i386, it's the signal handler return address, so it's
2802 - * located next to the frame pointer.
2803 - * This is inlined, so __builtin_frame_address(0) is correct.  Otherwise,
2804 - * it would have to be __builtin_frame_address(1).
2805 - */
2806 -
2807 -#define frame_restorer() \
2808 -({ \
2809 -       unsigned long *fp; \
2810 -\
2811 -       fp = __builtin_frame_address(0); \
2812 -       ((unsigned long) (fp + 1)); \
2813 -})
2814 -
2815 -/* Similarly, this returns the value of sp when the handler was first
2816 - * entered.  This is used to calculate the proper sp when delivering
2817 - * signals.
2818 - */
2819 -
2820 -#define frame_sp() \
2821 -({ \
2822 -       unsigned long *fp; \
2823 -\
2824 -       fp = __builtin_frame_address(0); \
2825 -       ((unsigned long) (fp + 1)); \
2826 -})
2827 -
2828 -#endif
2829 -
2830 -/*
2831 - * Overrides for Emacs so that we follow Linus's tabbing style.
2832 - * Emacs will notice this stuff at the end of the file and automatically
2833 - * adjust the settings for this buffer only.  This must remain at the end
2834 - * of the file.
2835 - * ---------------------------------------------------------------------------
2836 - * Local variables:
2837 - * c-file-style: "linux"
2838 - * End:
2839 - */
2840 Index: linux-2.6.10/arch/um/include/frame_user.h
2841 ===================================================================
2842 --- linux-2.6.10.orig/arch/um/include/frame_user.h      2004-12-25 05:33:50.000000000 +0800
2843 +++ linux-2.6.10/arch/um/include/frame_user.h   2005-04-07 06:37:43.373923992 +0800
2844 @@ -1,23 +0,0 @@
2845 -/* 
2846 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
2847 - * Licensed under the GPL
2848 - */
2849 -
2850 -#ifndef __FRAME_USER_H_
2851 -#define __FRAME_USER_H_
2852 -
2853 -#include "sysdep/frame_user.h"
2854 -#include "frame.h"
2855 -
2856 -#endif
2857 -
2858 -/*
2859 - * Overrides for Emacs so that we follow Linus's tabbing style.
2860 - * Emacs will notice this stuff at the end of the file and automatically
2861 - * adjust the settings for this buffer only.  This must remain at the end
2862 - * of the file.
2863 - * ---------------------------------------------------------------------------
2864 - * Local variables:
2865 - * c-file-style: "linux"
2866 - * End:
2867 - */
2868 Index: linux-2.6.10/arch/i386/kernel/ptrace.c
2869 ===================================================================
2870 --- linux-2.6.10.orig/arch/i386/kernel/ptrace.c 2004-12-25 05:34:29.000000000 +0800
2871 +++ linux-2.6.10/arch/i386/kernel/ptrace.c      2005-04-06 23:44:30.208030272 +0800
2872 @@ -15,6 +15,7 @@
2873  #include <linux/user.h>
2874  #include <linux/security.h>
2875  #include <linux/audit.h>
2876 +#include <linux/proc_mm.h>
2877  
2878  #include <asm/uaccess.h>
2879  #include <asm/pgtable.h>
2880 @@ -406,15 +407,27 @@
2881                   }
2882                   break;
2883  
2884 +       case PTRACE_SYSEMU: /* continue and stop at next syscall, which will not be executed */
2885         case PTRACE_SYSCALL:    /* continue and stop at next (return from) syscall */
2886         case PTRACE_CONT:       /* restart after signal. */
2887                 ret = -EIO;
2888                 if ((unsigned long) data > _NSIG)
2889                         break;
2890 +               /* If we came here with PTRACE_SYSEMU and now continue with
2891 +                * PTRACE_SYSCALL, entry.S used to intercept the syscall return.
2892 +                * But it shouldn't!
2893 +                * So we don't clear TIF_SYSCALL_EMU, which is always unused in
2894 +                * this special case, to remember, we came from SYSEMU. That
2895 +                * flag will be cleared by do_syscall_trace().
2896 +                */
2897 +               if (request == PTRACE_SYSEMU) {
2898 +                       set_tsk_thread_flag(child, TIF_SYSCALL_EMU);
2899 +               } else if (request == PTRACE_CONT) {
2900 +                       clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
2901 +               }
2902                 if (request == PTRACE_SYSCALL) {
2903                         set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
2904 -               }
2905 -               else {
2906 +               } else {
2907                         clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
2908                 }
2909                 child->exit_code = data;
2910 @@ -443,6 +456,8 @@
2911                 ret = -EIO;
2912                 if ((unsigned long) data > _NSIG)
2913                         break;
2914 +               /*See do_syscall_trace to know why we don't clear
2915 +                * TIF_SYSCALL_EMU.*/
2916                 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
2917                 set_singlestep(child);
2918                 child->exit_code = data;
2919 @@ -542,6 +557,58 @@
2920                                         (struct user_desc __user *) data);
2921                 break;
2922  
2923 +#ifdef CONFIG_PROC_MM
2924 +       case PTRACE_FAULTINFO: {
2925 +               struct ptrace_faultinfo fault;
2926 +
2927 +               fault = ((struct ptrace_faultinfo)
2928 +                       { .is_write     = child->thread.error_code,
2929 +                         .addr         = child->thread.cr2 });
2930 +               ret = copy_to_user((unsigned long *) data, &fault,
2931 +                                  sizeof(fault));
2932 +               if(ret)
2933 +                       break;
2934 +               break;
2935 +       }
2936 +
2937 +       case PTRACE_SIGPENDING:
2938 +               ret = copy_to_user((unsigned long *) data,
2939 +                                  &child->pending.signal,
2940 +                                  sizeof(child->pending.signal));
2941 +               break;
2942 +
2943 +       case PTRACE_LDT: {
2944 +               struct ptrace_ldt ldt;
2945 +
2946 +               if(copy_from_user(&ldt, (unsigned long *) data,
2947 +                                 sizeof(ldt))){
2948 +                       ret = -EIO;
2949 +                       break;
2950 +               }
2951 +               ret = __modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
2952 +               break;
2953 +       }
2954 +
2955 +       case PTRACE_SWITCH_MM: {
2956 +               struct mm_struct *old = child->mm;
2957 +               struct mm_struct *new = proc_mm_get_mm(data);
2958 +
2959 +               if(IS_ERR(new)){
2960 +                       ret = PTR_ERR(new);
2961 +                       break;
2962 +               }
2963 +
2964 +               atomic_inc(&new->mm_users);
2965 +               task_lock(child);
2966 +               child->mm = new;
2967 +               child->active_mm = new;
2968 +               task_unlock(child);
2969 +               mmput(old);
2970 +               ret = 0;
2971 +               break;
2972 +       }
2973 +#endif
2974 +
2975         default:
2976                 ret = ptrace_request(child, request, addr, data);
2977                 break;
2978 @@ -557,8 +624,9 @@
2979   * - triggered by current->work.syscall_trace
2980   */
2981  __attribute__((regparm(3)))
2982 -void do_syscall_trace(struct pt_regs *regs, int entryexit)
2983 +int do_syscall_trace(struct pt_regs *regs, int entryexit)
2984  {
2985 +       int is_sysemu, is_systrace, is_singlestep;
2986         if (unlikely(current->audit_context)) {
2987                 if (!entryexit)
2988                         audit_syscall_entry(current, regs->orig_eax,
2989 @@ -567,16 +635,27 @@
2990                 else
2991                         audit_syscall_exit(current, regs->eax);
2992         }
2993 -
2994 -       if (!test_thread_flag(TIF_SYSCALL_TRACE) &&
2995 -           !test_thread_flag(TIF_SINGLESTEP))
2996 -               return;
2997 +       is_sysemu = test_thread_flag(TIF_SYSCALL_EMU);
2998 +       is_systrace = test_thread_flag(TIF_SYSCALL_TRACE);
2999 +       is_singlestep = test_thread_flag(TIF_SINGLESTEP);
3000 +
3001 +       if (!is_systrace && !is_singlestep && !is_sysemu)
3002 +               return 0;
3003 +       /* We can detect the case of coming from PTRACE_SYSEMU and now running
3004 +        * with PTRACE_SYSCALL or PTRACE_SINGLESTEP, by TIF_SYSCALL_EMU being
3005 +        * set additionally.
3006 +        * If so let's reset the flag and return without action.
3007 +        */
3008 +       if (is_sysemu && (is_systrace || is_singlestep)) {
3009 +               clear_thread_flag(TIF_SYSCALL_EMU);
3010 +               return 0;
3011 +       }
3012         if (!(current->ptrace & PT_PTRACED))
3013 -               return;
3014 +               return 0;
3015         /* the 0x80 provides a way for the tracing parent to distinguish
3016            between a syscall stop and SIGTRAP delivery */
3017         ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) &&
3018 -                                !test_thread_flag(TIF_SINGLESTEP) ? 0x80 : 0));
3019 +                                !is_singlestep ? 0x80 : 0));
3020  
3021         /*
3022          * this isn't the same as continuing with a signal, but it will do
3023 @@ -587,4 +666,6 @@
3024                 send_sig(current->exit_code, current, 1);
3025                 current->exit_code = 0;
3026         }
3027 +       /* != 0 if nullifying the syscall, 0 if running it normally */
3028 +       return is_sysemu;
3029  }
3030 Index: linux-2.6.10/arch/i386/kernel/ldt.c
3031 ===================================================================
3032 --- linux-2.6.10.orig/arch/i386/kernel/ldt.c    2004-12-25 05:35:23.000000000 +0800
3033 +++ linux-2.6.10/arch/i386/kernel/ldt.c 2005-04-06 23:44:30.220028448 +0800
3034 @@ -18,6 +18,7 @@
3035  #include <asm/system.h>
3036  #include <asm/ldt.h>
3037  #include <asm/desc.h>
3038 +#include <asm/mmu_context.h>
3039  
3040  #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
3041  static void flush_ldt(void *null)
3042 @@ -27,11 +28,12 @@
3043  }
3044  #endif
3045  
3046 -static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
3047 +static int alloc_ldt(struct mm_struct *mm, int mincount, int reload)
3048  {
3049         void *oldldt;
3050         void *newldt;
3051         int oldsize;
3052 +       mm_context_t * pc = &mm->context;
3053  
3054         if (mincount <= pc->size)
3055                 return 0;
3056 @@ -58,13 +60,15 @@
3057  #ifdef CONFIG_SMP
3058                 cpumask_t mask;
3059                 preempt_disable();
3060 -               load_LDT(pc);
3061 +               if (&current->active_mm->context == pc)
3062 +                       load_LDT(pc);
3063                 mask = cpumask_of_cpu(smp_processor_id());
3064 -               if (!cpus_equal(current->mm->cpu_vm_mask, mask))
3065 +               if (!cpus_equal(mm->cpu_vm_mask, mask))
3066                         smp_call_function(flush_ldt, NULL, 1, 1);
3067                 preempt_enable();
3068  #else
3069 -               load_LDT(pc);
3070 +               if (&current->active_mm->context == pc)
3071 +                       load_LDT(pc);
3072  #endif
3073         }
3074         if (oldsize) {
3075 @@ -76,12 +80,12 @@
3076         return 0;
3077  }
3078  
3079 -static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
3080 +static inline int copy_ldt(struct mm_struct *new, struct mm_struct *old)
3081  {
3082 -       int err = alloc_ldt(new, old->size, 0);
3083 +       int err = alloc_ldt(new, old->context.size, 0);
3084         if (err < 0)
3085                 return err;
3086 -       memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
3087 +       memcpy(new->context.ldt, old->context.ldt, old->context.size*LDT_ENTRY_SIZE);
3088         return 0;
3089  }
3090  
3091 @@ -89,22 +93,24 @@
3092   * we do not have to muck with descriptors here, that is
3093   * done in switch_mm() as needed.
3094   */
3095 -int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
3096 +int copy_context(struct mm_struct *mm, struct mm_struct *old_mm)
3097  {
3098 -       struct mm_struct * old_mm;
3099         int retval = 0;
3100  
3101 -       init_MUTEX(&mm->context.sem);
3102 -       mm->context.size = 0;
3103 -       old_mm = current->mm;
3104         if (old_mm && old_mm->context.size > 0) {
3105                 down(&old_mm->context.sem);
3106 -               retval = copy_ldt(&mm->context, &old_mm->context);
3107 +               retval = copy_ldt(mm, old_mm);
3108                 up(&old_mm->context.sem);
3109         }
3110         return retval;
3111  }
3112  
3113 +int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
3114 +{
3115 +       init_new_empty_context(mm);
3116 +       return copy_context(mm, current->mm);
3117 +}
3118 +
3119  /*
3120   * No need to lock the MM as we are the last user
3121   */
3122 @@ -121,11 +127,11 @@
3123         }
3124  }
3125  
3126 -static int read_ldt(void __user * ptr, unsigned long bytecount)
3127 +static int read_ldt(struct mm_struct * mm, void __user * ptr,
3128 +                   unsigned long bytecount)
3129  {
3130         int err;
3131         unsigned long size;
3132 -       struct mm_struct * mm = current->mm;
3133  
3134         if (!mm->context.size)
3135                 return 0;
3136 @@ -174,9 +180,8 @@
3137         return err;
3138  }
3139  
3140 -static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
3141 +static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
3142  {
3143 -       struct mm_struct * mm = current->mm;
3144         __u32 entry_1, entry_2, *lp;
3145         int error;
3146         struct user_desc ldt_info;
3147 @@ -200,7 +205,7 @@
3148  
3149         down(&mm->context.sem);
3150         if (ldt_info.entry_number >= mm->context.size) {
3151 -               error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
3152 +               error = alloc_ldt(mm, ldt_info.entry_number+1, 1);
3153                 if (error < 0)
3154                         goto out_unlock;
3155         }
3156 @@ -233,23 +238,29 @@
3157         return error;
3158  }
3159  
3160 -asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
3161 +int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
3162 +              unsigned long bytecount)
3163  {
3164         int ret = -ENOSYS;
3165  
3166         switch (func) {
3167         case 0:
3168 -               ret = read_ldt(ptr, bytecount);
3169 +               ret = read_ldt(mm, ptr, bytecount);
3170                 break;
3171         case 1:
3172 -               ret = write_ldt(ptr, bytecount, 1);
3173 +               ret = write_ldt(mm, ptr, bytecount, 1);
3174                 break;
3175         case 2:
3176                 ret = read_default_ldt(ptr, bytecount);
3177                 break;
3178         case 0x11:
3179 -               ret = write_ldt(ptr, bytecount, 0);
3180 +               ret = write_ldt(mm, ptr, bytecount, 0);
3181                 break;
3182         }
3183         return ret;
3184  }
3185 +
3186 +asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
3187 +{
3188 +       return __modify_ldt(current->mm, func, ptr, bytecount);
3189 +}
3190 Index: linux-2.6.10/arch/i386/kernel/sys_i386.c
3191 ===================================================================
3192 --- linux-2.6.10.orig/arch/i386/kernel/sys_i386.c       2004-12-25 05:35:39.000000000 +0800
3193 +++ linux-2.6.10/arch/i386/kernel/sys_i386.c    2005-04-06 23:44:30.220028448 +0800
3194 @@ -41,7 +41,7 @@
3195  }
3196  
3197  /* common code for old and new mmaps */
3198 -static inline long do_mmap2(
3199 +long do_mmap2(struct mm_struct *mm,
3200         unsigned long addr, unsigned long len,
3201         unsigned long prot, unsigned long flags,
3202         unsigned long fd, unsigned long pgoff)
3203 @@ -56,9 +56,9 @@
3204                         goto out;
3205         }
3206  
3207 -       down_write(&current->mm->mmap_sem);
3208 -       error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
3209 -       up_write(&current->mm->mmap_sem);
3210 +       down_write(&mm->mmap_sem);
3211 +       error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
3212 +       up_write(&mm->mmap_sem);
3213  
3214         if (file)
3215                 fput(file);
3216 @@ -70,7 +70,7 @@
3217         unsigned long prot, unsigned long flags,
3218         unsigned long fd, unsigned long pgoff)
3219  {
3220 -       return do_mmap2(addr, len, prot, flags, fd, pgoff);
3221 +       return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
3222  }
3223  
3224  /*
3225 @@ -101,7 +101,7 @@
3226         if (a.offset & ~PAGE_MASK)
3227                 goto out;
3228  
3229 -       err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
3230 +       err = do_mmap2(current->mm, a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
3231  out:
3232         return err;
3233  }
3234 Index: linux-2.6.10/arch/i386/kernel/entry.S
3235 ===================================================================
3236 --- linux-2.6.10.orig/arch/i386/kernel/entry.S  2005-04-06 23:38:35.000000000 +0800
3237 +++ linux-2.6.10/arch/i386/kernel/entry.S       2005-04-06 23:44:30.206030576 +0800
3238 @@ -222,7 +222,7 @@
3239         SAVE_ALL
3240         GET_THREAD_INFO(%ebp)
3241  
3242 -       testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
3243 +       testb $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
3244         jnz syscall_trace_entry
3245         cmpl $(nr_syscalls), %eax
3246         jae syscall_badsys
3247 @@ -245,8 +245,8 @@
3248         pushl %eax                      # save orig_eax
3249         SAVE_ALL
3250         GET_THREAD_INFO(%ebp)
3251 -                                       # system call tracing in operation
3252 -       testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
3253 +                                       # system call tracing in operation / emulation
3254 +       testb $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
3255         jnz syscall_trace_entry
3256         cmpl $(nr_syscalls), %eax
3257         jae syscall_badsys
3258 @@ -307,6 +307,9 @@
3259         movl %esp, %eax
3260         xorl %edx,%edx
3261         call do_syscall_trace
3262 +       cmpl $0, %eax
3263 +       jne syscall_exit                # ret != 0 -> running under PTRACE_SYSEMU,
3264 +                                       # so must skip actual syscall
3265         movl ORIG_EAX(%esp), %eax
3266         cmpl $(nr_syscalls), %eax
3267         jnae syscall_call
3268 Index: linux-2.6.10/arch/i386/Kconfig
3269 ===================================================================
3270 --- linux-2.6.10.orig/arch/i386/Kconfig 2005-04-06 23:38:33.000000000 +0800
3271 +++ linux-2.6.10/arch/i386/Kconfig      2005-04-06 23:44:30.222028144 +0800
3272 @@ -738,6 +738,10 @@
3273         depends on HIGHMEM64G
3274         default y
3275  
3276 +config PROC_MM
3277 +       bool "/proc/mm support"
3278 +       default y
3279 +
3280  # Common NUMA Features
3281  config NUMA
3282         bool "Numa Memory Allocation and Scheduler Support"
3283 Index: linux-2.6.10/fs/hostfs/hostfs.h
3284 ===================================================================
3285 --- linux-2.6.10.orig/fs/hostfs/hostfs.h        2004-12-25 05:35:24.000000000 +0800
3286 +++ linux-2.6.10/fs/hostfs/hostfs.h     2005-04-06 23:44:30.286018416 +0800
3287 @@ -16,9 +16,30 @@
3288  #define HOSTFS_ATTR_CTIME      64
3289  #define HOSTFS_ATTR_ATIME_SET  128
3290  #define HOSTFS_ATTR_MTIME_SET  256
3291 +
3292 +/* These two are unused by hostfs. */
3293  #define HOSTFS_ATTR_FORCE      512     /* Not a change, but a change it */
3294  #define HOSTFS_ATTR_ATTR_FLAG  1024
3295  
3296 +/* If you are very careful, you'll notice that these two are missing:
3297 + *
3298 + * #define ATTR_KILL_SUID      2048
3299 + * #define ATTR_KILL_SGID      4096
3300 + *
3301 + * and this is because they were added in 2.5 development in this patch:
3302 + *
3303 + * http://linux.bkbits.net:8080/linux-2.5/
3304 + * cset@3caf4a12k4XgDzK7wyK-TGpSZ9u2Ww?nav=index.html
3305 + * |src/.|src/include|src/include/linux|related/include/linux/fs.h
3306 + *
3307 + * Actually, they are not needed by most ->setattr() methods - they are set by
3308 + * callers of notify_change() to notify that the setuid/setgid bits must be
3309 + * dropped.
3310 + * notify_change() will delete those flags, make sure attr->ia_valid & ATTR_MODE
3311 + * is on, and remove the appropriate bits from attr->ia_mode (attr is a
3312 + * "struct iattr *"). -BlaisorBlade
3313 + */
3314 +
3315  struct hostfs_iattr {
3316         unsigned int    ia_valid;
3317         mode_t          ia_mode;
3318 Index: linux-2.6.10/fs/hostfs/hostfs_kern.c
3319 ===================================================================
3320 --- linux-2.6.10.orig/fs/hostfs/hostfs_kern.c   2004-12-25 05:34:01.000000000 +0800
3321 +++ linux-2.6.10/fs/hostfs/hostfs_kern.c        2005-04-06 23:44:30.287018264 +0800
3322 @@ -393,6 +393,7 @@
3323  static struct file_operations hostfs_file_fops = {
3324         .llseek         = generic_file_llseek,
3325         .read           = generic_file_read,
3326 +       .sendfile       = generic_file_sendfile,
3327         .write          = generic_file_write,
3328         .mmap           = generic_file_mmap,
3329         .open           = hostfs_file_open,
3330 @@ -818,6 +819,10 @@
3331         char *name;
3332         int err;
3333  
3334 +       err = inode_change_ok(dentry->d_inode, attr);
3335 +       if (err)
3336 +               return err;
3337 +
3338         if(append)
3339                 attr->ia_valid &= ~ATTR_SIZE;
3340  
3341 Index: linux-2.6.10/kernel/fork.c
3342 ===================================================================
3343 --- linux-2.6.10.orig/kernel/fork.c     2005-04-06 23:38:35.000000000 +0800
3344 +++ linux-2.6.10/kernel/fork.c  2005-04-06 23:44:30.191032856 +0800
3345 @@ -927,6 +927,9 @@
3346          * of CLONE_PTRACE.
3347          */
3348         clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE);
3349 +#ifdef TIF_SYSCALL_EMU
3350 +       clear_tsk_thread_flag(p, TIF_SYSCALL_EMU);
3351 +#endif
3352  
3353         /* Our parent execution domain becomes current domain
3354            These must match for thread signalling to apply */
3355 Index: linux-2.6.10/include/linux/ptrace.h
3356 ===================================================================
3357 --- linux-2.6.10.orig/include/linux/ptrace.h    2005-04-06 23:38:33.000000000 +0800
3358 +++ linux-2.6.10/include/linux/ptrace.h 2005-04-06 23:44:30.187033464 +0800
3359 @@ -20,6 +20,7 @@
3360  #define PTRACE_DETACH          0x11
3361  
3362  #define PTRACE_SYSCALL           24
3363 +#define PTRACE_SYSEMU            31
3364  
3365  /* 0x4200-0x4300 are reserved for architecture-independent additions.  */
3366  #define PTRACE_SETOPTIONS      0x4200
3367 Index: linux-2.6.10/include/linux/mm.h
3368 ===================================================================
3369 --- linux-2.6.10.orig/include/linux/mm.h        2005-04-06 23:38:33.000000000 +0800
3370 +++ linux-2.6.10/include/linux/mm.h     2005-04-06 23:44:30.188033312 +0800
3371 @@ -625,6 +625,9 @@
3372  extern struct shrinker *set_shrinker(int, shrinker_t);
3373  extern void remove_shrinker(struct shrinker *shrinker);
3374  
3375 +extern long do_mprotect(struct mm_struct *mm, unsigned long start,
3376 +                       size_t len, unsigned long prot);
3377 +
3378  /*
3379   * On a two-level page table, this ends up being trivial. Thus the
3380   * inlining and the symmetry break with pte_alloc_map() that does all
3381 @@ -684,9 +687,15 @@
3382  
3383  extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
3384  
3385 -extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
3386 +extern unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file *file,
3387 +                                  unsigned long addr, unsigned long len,
3388 +                                  unsigned long prot, unsigned long flag,
3389 +                                  unsigned long pgoff);
3390 +static inline unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
3391         unsigned long len, unsigned long prot,
3392 -       unsigned long flag, unsigned long pgoff);
3393 +       unsigned long flag, unsigned long pgoff) {
3394 +       return __do_mmap_pgoff(current->mm, file, addr, len, prot, flag, pgoff);
3395 +}
3396  
3397  static inline unsigned long do_mmap(struct file *file, unsigned long addr,
3398         unsigned long len, unsigned long prot,
3399 Index: linux-2.6.10/include/linux/proc_mm.h
3400 ===================================================================
3401 --- linux-2.6.10.orig/include/linux/proc_mm.h   2005-04-07 06:37:43.373923992 +0800
3402 +++ linux-2.6.10/include/linux/proc_mm.h        2005-04-06 23:44:30.189033160 +0800
3403 @@ -0,0 +1,48 @@
3404 +/*
3405 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3406 + * Licensed under the GPL
3407 + */
3408 +
3409 +#ifndef __PROC_MM_H
3410 +#define __PROC_MM_H
3411 +
3412 +#include "linux/sched.h"
3413 +
3414 +#define MM_MMAP 54
3415 +#define MM_MUNMAP 55
3416 +#define MM_MPROTECT 56
3417 +#define MM_COPY_SEGMENTS 57
3418 +
3419 +struct mm_mmap {
3420 +       unsigned long addr;
3421 +       unsigned long len;
3422 +       unsigned long prot;
3423 +       unsigned long flags;
3424 +       unsigned long fd;
3425 +       unsigned long offset;
3426 +};
3427 +
3428 +struct mm_munmap {
3429 +       unsigned long addr;
3430 +       unsigned long len;
3431 +};
3432 +
3433 +struct mm_mprotect {
3434 +       unsigned long addr;
3435 +       unsigned long len;
3436 +        unsigned int prot;
3437 +};
3438 +
3439 +struct proc_mm_op {
3440 +       int op;
3441 +       union {
3442 +               struct mm_mmap mmap;
3443 +               struct mm_munmap munmap;
3444 +               struct mm_mprotect mprotect;
3445 +               int copy_segments;
3446 +       } u;
3447 +};
3448 +
3449 +extern struct mm_struct *proc_mm_get_mm(int fd);
3450 +
3451 +#endif
3452 Index: linux-2.6.10/include/asm-um/elf.h
3453 ===================================================================
3454 --- linux-2.6.10.orig/include/asm-um/elf.h      2004-12-25 05:35:01.000000000 +0800
3455 +++ linux-2.6.10/include/asm-um/elf.h   2005-04-06 23:44:30.183034072 +0800
3456 @@ -3,7 +3,8 @@
3457  
3458  #include "asm/archparam.h"
3459  
3460 -#define ELF_HWCAP (0)
3461 +extern long elf_aux_hwcap;
3462 +#define ELF_HWCAP (elf_aux_hwcap)
3463  
3464  #define SET_PERSONALITY(ex, ibcs2) do ; while(0)
3465  
3466 Index: linux-2.6.10/include/asm-um/archparam-i386.h
3467 ===================================================================
3468 --- linux-2.6.10.orig/include/asm-um/archparam-i386.h   2004-12-25 05:35:24.000000000 +0800
3469 +++ linux-2.6.10/include/asm-um/archparam-i386.h        2005-04-06 23:44:30.183034072 +0800
3470 @@ -10,7 +10,8 @@
3471  
3472  #include "user.h"
3473  
3474 -#define ELF_PLATFORM "i586"
3475 +extern char * elf_aux_platform;
3476 +#define ELF_PLATFORM (elf_aux_platform)
3477  
3478  #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
3479  
3480 @@ -56,15 +57,13 @@
3481         pr_reg[16] = PT_REGS_SS(regs);          \
3482  } while(0);
3483  
3484 -#if 0 /* Turn this back on when UML has VSYSCALL working */
3485 -#define VSYSCALL_BASE  (__fix_to_virt(FIX_VSYSCALL))
3486 -#else
3487 -#define VSYSCALL_BASE  0
3488 -#endif
3489  
3490 -#define VSYSCALL_EHDR  ((const struct elfhdr *) VSYSCALL_BASE)
3491 -#define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
3492 -extern void *__kernel_vsyscall;
3493 +extern unsigned long vsyscall_ehdr;
3494 +extern unsigned long vsyscall_end;
3495 +extern unsigned long __kernel_vsyscall;
3496 +
3497 +#define VSYSCALL_BASE vsyscall_ehdr
3498 +#define VSYSCALL_END vsyscall_end
3499  
3500  /*
3501   * Architecture-neutral AT_ values in 0-17, leave some room
3502 @@ -75,8 +74,10 @@
3503  
3504  #define ARCH_DLINFO                                            \
3505  do {                                                           \
3506 -               NEW_AUX_ENT(AT_SYSINFO, VSYSCALL_ENTRY);        \
3507 -               NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE);    \
3508 +       if ( vsyscall_ehdr ) {                                  \
3509 +               NEW_AUX_ENT(AT_SYSINFO, __kernel_vsyscall);     \
3510 +               NEW_AUX_ENT(AT_SYSINFO_EHDR, vsyscall_ehdr);    \
3511 +       }                                                       \
3512  } while (0)
3513  
3514  /*
3515 @@ -87,22 +88,18 @@
3516   * Dumping its extra ELF program headers includes all the other information
3517   * a debugger needs to easily find how the vsyscall DSO was being used.
3518   */
3519 -#if 0
3520 -#define ELF_CORE_EXTRA_PHDRS           (VSYSCALL_EHDR->e_phnum)
3521 -#endif
3522 -
3523 -#undef ELF_CORE_EXTRA_PHDRS
3524 +#define ELF_CORE_EXTRA_PHDRS                                                 \
3525 +       (vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0 )
3526  
3527 -#if 0
3528  #define ELF_CORE_WRITE_EXTRA_PHDRS                                           \
3529 -do {                                                                         \
3530 -       const struct elf_phdr *const vsyscall_phdrs =                         \
3531 -               (const struct elf_phdr *) (VSYSCALL_BASE                      \
3532 -                                          + VSYSCALL_EHDR->e_phoff);         \
3533 +if ( vsyscall_ehdr ) {                                                       \
3534 +       const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr;    \
3535 +       const struct elf_phdr *const phdrp =                                  \
3536 +               (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);   \
3537         int i;                                                                \
3538         Elf32_Off ofs = 0;                                                    \
3539 -       for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {                        \
3540 -               struct elf_phdr phdr = vsyscall_phdrs[i];                     \
3541 +       for (i = 0; i < ehdrp->e_phnum; ++i) {                                \
3542 +               struct elf_phdr phdr = phdrp[i];                              \
3543                 if (phdr.p_type == PT_LOAD) {                                 \
3544                         ofs = phdr.p_offset = offset;                         \
3545                         offset += phdr.p_filesz;                              \
3546 @@ -112,23 +109,19 @@
3547                 phdr.p_paddr = 0; /* match other core phdrs */                \
3548                 DUMP_WRITE(&phdr, sizeof(phdr));                              \
3549         }                                                                     \
3550 -} while (0)
3551 +}
3552  #define ELF_CORE_WRITE_EXTRA_DATA                                            \
3553 -do {                                                                         \
3554 -       const struct elf_phdr *const vsyscall_phdrs =                         \
3555 -               (const struct elf_phdr *) (VSYSCALL_BASE                      \
3556 -                                          + VSYSCALL_EHDR->e_phoff);         \
3557 +if ( vsyscall_ehdr ) {                                                       \
3558 +       const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr;    \
3559 +       const struct elf_phdr *const phdrp =                                  \
3560 +               (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);   \
3561         int i;                                                                \
3562 -       for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {                        \
3563 -               if (vsyscall_phdrs[i].p_type == PT_LOAD)                      \
3564 -                       DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr,        \
3565 -                                  vsyscall_phdrs[i].p_filesz);               \
3566 +       for (i = 0; i < ehdrp->e_phnum; ++i) {                                \
3567 +               if (phdrp[i].p_type == PT_LOAD)                               \
3568 +                       DUMP_WRITE((void *) phdrp[i].p_vaddr,                 \
3569 +                                  phdrp[i].p_filesz);                        \
3570         }                                                                     \
3571 -} while (0)
3572 -#endif
3573 -
3574 -#undef ELF_CORE_WRITE_EXTRA_PHDRS
3575 -#undef ELF_CORE_WRITE_EXTRA_DATA
3576 +}
3577  
3578  #define R_386_NONE     0
3579  #define R_386_32       1
3580 Index: linux-2.6.10/include/asm-um/fixmap.h
3581 ===================================================================
3582 --- linux-2.6.10.orig/include/asm-um/fixmap.h   2004-12-25 05:35:28.000000000 +0800
3583 +++ linux-2.6.10/include/asm-um/fixmap.h        2005-04-06 23:44:30.184033920 +0800
3584 @@ -3,6 +3,7 @@
3585  
3586  #include <linux/config.h>
3587  #include <asm/kmap_types.h>
3588 +#include <asm/archparam.h>
3589  
3590  /*
3591   * Here we define all the compile-time 'special' virtual
3592 @@ -34,7 +35,6 @@
3593         FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
3594         FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
3595  #endif
3596 -       FIX_VSYSCALL,
3597         __end_of_fixed_addresses
3598  };
3599  
3600 @@ -68,8 +68,8 @@
3601   * This is the range that is readable by user mode, and things
3602   * acting like user mode such as get_user_pages.
3603   */
3604 -#define FIXADDR_USER_START     (__fix_to_virt(FIX_VSYSCALL))
3605 -#define FIXADDR_USER_END       (FIXADDR_USER_START + PAGE_SIZE)
3606 +#define FIXADDR_USER_START     VSYSCALL_BASE
3607 +#define FIXADDR_USER_END       VSYSCALL_END
3608  
3609  extern void __this_fixmap_does_not_exist(void);
3610  
3611 Index: linux-2.6.10/include/asm-i386/thread_info.h
3612 ===================================================================
3613 --- linux-2.6.10.orig/include/asm-i386/thread_info.h    2004-12-25 05:34:00.000000000 +0800
3614 +++ linux-2.6.10/include/asm-i386/thread_info.h 2005-04-06 23:44:30.185033768 +0800
3615 @@ -139,6 +139,7 @@
3616  #define TIF_NEED_RESCHED       3       /* rescheduling necessary */
3617  #define TIF_SINGLESTEP         4       /* restore singlestep on return to user mode */
3618  #define TIF_IRET               5       /* return with iret */
3619 +#define TIF_SYSCALL_EMU                6       /* syscall emulation active */
3620  #define TIF_SYSCALL_AUDIT      7       /* syscall auditing active */
3621  #define TIF_POLLING_NRFLAG     16      /* true if poll_idle() is polling TIF_NEED_RESCHED */
3622  
3623 @@ -148,12 +149,14 @@
3624  #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
3625  #define _TIF_SINGLESTEP                (1<<TIF_SINGLESTEP)
3626  #define _TIF_IRET              (1<<TIF_IRET)
3627 +#define _TIF_SYSCALL_EMU       (1<<TIF_SYSCALL_EMU)
3628  #define _TIF_SYSCALL_AUDIT     (1<<TIF_SYSCALL_AUDIT)
3629  #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
3630  
3631  /* work to do on interrupt/exception return */
3632  #define _TIF_WORK_MASK \
3633 -  (0x0000FFFF & ~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP))
3634 +  (0x0000FFFF & ~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP|\
3635 +                 _TIF_SYSCALL_EMU))
3636  #define _TIF_ALLWORK_MASK      0x0000FFFF      /* work to do on any return to u-space */
3637  
3638  /*
3639 Index: linux-2.6.10/include/asm-i386/ptrace.h
3640 ===================================================================
3641 --- linux-2.6.10.orig/include/asm-i386/ptrace.h 2004-12-25 05:33:51.000000000 +0800
3642 +++ linux-2.6.10/include/asm-i386/ptrace.h      2005-04-06 23:44:30.186033616 +0800
3643 @@ -64,4 +64,26 @@
3644  #endif
3645  #endif
3646  
3647 +/*For SKAS3 support.*/
3648 +#ifndef _LINUX_PTRACE_STRUCT_DEF
3649 +#define _LINUX_PTRACE_STRUCT_DEF
3650 +
3651 +#define PTRACE_FAULTINFO         52
3652 +#define PTRACE_SIGPENDING        53
3653 +#define PTRACE_LDT               54
3654 +#define PTRACE_SWITCH_MM         55
3655 +
3656 +struct ptrace_faultinfo {
3657 +       int is_write;
3658 +       unsigned long addr;
3659 +};
3660 +
3661 +struct ptrace_ldt {
3662 +       int func;
3663 +       void *ptr;
3664 +       unsigned long bytecount;
3665 +};
3666 +
3667 +#endif /*ifndef _LINUX_PTRACE_STRUCT_DEF*/
3668 +
3669  #endif
3670 Index: linux-2.6.10/include/asm-i386/mmu_context.h
3671 ===================================================================
3672 --- linux-2.6.10.orig/include/asm-i386/mmu_context.h    2004-12-25 05:33:48.000000000 +0800
3673 +++ linux-2.6.10/include/asm-i386/mmu_context.h 2005-04-06 23:44:30.185033768 +0800
3674 @@ -6,13 +6,25 @@
3675  #include <asm/atomic.h>
3676  #include <asm/pgalloc.h>
3677  #include <asm/tlbflush.h>
3678 +#include <asm/semaphore.h>
3679  
3680  /*
3681 - * Used for LDT copy/destruction.
3682 + * Used for LDT initialization/destruction. You cannot copy an LDT with
3683 + * init_new_context, since it thinks you are passing it a new LDT and won't
3684 + * deallocate its old content.
3685   */
3686  int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
3687  void destroy_context(struct mm_struct *mm);
3688  
3689 +/* LDT initialization for a clean environment - needed for SKAS.*/
3690 +static inline void init_new_empty_context(struct mm_struct *mm)
3691 +{
3692 +       init_MUTEX(&mm->context.sem);
3693 +       mm->context.size = 0;
3694 +}
3695 +
3696 +/* LDT copy for SKAS - for the above problem.*/
3697 +int copy_context(struct mm_struct *mm, struct mm_struct *old_mm);
3698  
3699  static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
3700  {
3701 @@ -29,6 +41,10 @@
3702  {
3703         int cpu = smp_processor_id();
3704  
3705 +#ifdef CONFIG_SMP
3706 +       prev = per_cpu(cpu_tlbstate, cpu).active_mm;
3707 +#endif
3708 +
3709         if (likely(prev != next)) {
3710                 /* stop flush ipis for the previous mm */
3711                 cpu_clear(cpu, prev->cpu_vm_mask);
3712 @@ -50,7 +66,6 @@
3713  #ifdef CONFIG_SMP
3714         else {
3715                 per_cpu(cpu_tlbstate, cpu).state = TLBSTATE_OK;
3716 -               BUG_ON(per_cpu(cpu_tlbstate, cpu).active_mm != next);
3717  
3718                 if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
3719                         /* We were in lazy tlb mode and leave_mm disabled 
3720 Index: linux-2.6.10/include/asm-i386/desc.h
3721 ===================================================================
3722 --- linux-2.6.10.orig/include/asm-i386/desc.h   2004-12-25 05:33:48.000000000 +0800
3723 +++ linux-2.6.10/include/asm-i386/desc.h        2005-04-06 23:44:30.186033616 +0800
3724 @@ -126,6 +126,9 @@
3725         put_cpu();
3726  }
3727  
3728 +extern int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
3729 +                     unsigned long bytecount);
3730 +
3731  #endif /* !__ASSEMBLY__ */
3732  
3733  #endif