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