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
8 depends on DEBUG_KERNEL && (H8300 || M68KNOMMU || V850)
9 - depends (USERMODE && MCONSOLE)
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
20 unsigned long beg = start;
21 + struct mm_struct * mm = vma->vm_mm;
23 - dir = pgd_offset(current->mm, start);
24 + dir = pgd_offset(mm, start);
25 flush_cache_range(vma, beg, end);
28 - spin_lock(¤t->mm->page_table_lock);
29 + spin_lock(&mm->page_table_lock);
31 change_pmd_range(dir, start, end - start, newprot);
32 start = (start + PGDIR_SIZE) & PGDIR_MASK;
34 } while (start && (start < end));
35 flush_tlb_range(vma, beg, end);
36 - spin_unlock(¤t->mm->page_table_lock);
37 + spin_unlock(&mm->page_table_lock);
46 -sys_mprotect(unsigned long start, size_t len, unsigned long prot)
48 +do_mprotect(struct mm_struct *mm, unsigned long start, size_t len,
51 unsigned long vm_flags, nstart, end, tmp;
52 struct vm_area_struct *vma, *prev;
55 vm_flags = calc_vm_prot_bits(prot);
57 - down_write(¤t->mm->mmap_sem);
58 + down_write(&mm->mmap_sem);
60 - vma = find_vma_prev(current->mm, start, &prev);
61 + vma = find_vma_prev(mm, start, &prev);
69 - up_write(¤t->mm->mmap_sem);
70 + up_write(&mm->mmap_sem);
74 +asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
76 + return(do_mprotect(current->mm, start, len, prot));
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
83 * The caller must hold down_write(current->mm->mmap_sem).
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)
94 - struct mm_struct * mm = current->mm;
95 struct vm_area_struct * vma, * prev;
97 unsigned int vm_flags;
102 -EXPORT_SYMBOL(do_mmap_pgoff);
103 +EXPORT_SYMBOL(__do_mmap_pgoff);
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
113 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
114 + * Licensed under the GPL
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"
126 +static struct file_operations proc_mm_fops;
128 +struct mm_struct *proc_mm_get_mm(int fd)
130 + struct mm_struct *ret = ERR_PTR(-EBADF);
137 + ret = ERR_PTR(-EINVAL);
138 + if(file->f_op != &proc_mm_fops)
141 + ret = file->private_data;
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);
153 +static ssize_t write_proc_mm(struct file *file, const char *buffer,
154 + size_t count, loff_t *ppos)
156 + struct mm_struct *mm = file->private_data;
157 + struct proc_mm_op req;
160 + if(count > sizeof(req))
163 + n = copy_from_user(&req, buffer, count);
170 + struct mm_mmap *map = &req.u.mmap;
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
177 + if (! (map->flags & MAP_FIXED))
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)
188 + struct mm_munmap *unmap = &req.u.munmap;
190 + down_write(&mm->mmap_sem);
191 + ret = do_munmap(mm, unmap->addr, unmap->len);
192 + up_write(&mm->mmap_sem);
198 + case MM_MPROTECT: {
199 + struct mm_mprotect *protect = &req.u.mprotect;
201 + ret = do_mprotect(mm, protect->addr, protect->len,
208 + case MM_COPY_SEGMENTS: {
209 + struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
212 + ret = PTR_ERR(from);
216 + ret = copy_context(mm, from);
229 +static int open_proc_mm(struct inode *inode, struct file *file)
231 + struct mm_struct *mm = mm_alloc();
238 + init_new_empty_context(mm);
239 + arch_pick_mmap_layout(mm);
241 + spin_lock(&mmlist_lock);
242 + list_add(&mm->mmlist, ¤t->mm->mmlist);
243 + spin_unlock(&mmlist_lock);
245 + file->private_data = mm;
253 +static int release_proc_mm(struct inode *inode, struct file *file)
255 + struct mm_struct *mm = file->private_data;
261 +static struct file_operations proc_mm_fops = {
262 + .open = open_proc_mm,
263 + .release = release_proc_mm,
264 + .write = write_proc_mm,
267 +static int make_proc_mm(void)
269 + struct proc_dir_entry *ent;
271 + ent = create_proc_entry("mm", 0222, &proc_root);
273 + printk("make_proc_mm : Failed to register /proc/mm\n");
276 + ent->proc_fops = &proc_mm_fops;
281 +__initcall(make_proc_mm);
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
288 + * ---------------------------------------------------------------------------
290 + * c-file-style: "linux"
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
298 obj-$(CONFIG_SHMEM) += shmem.o
299 obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
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
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.*/
315 +void mconsole_proc(struct mc_request *req)
321 + int first_chunk = 1;
322 + char *ptr = req->request.data;
324 + ptr += strlen("proc");
325 + while(isspace(*ptr)) ptr++;
326 + snprintf(path, sizeof(path), "/proc/%s", ptr);
328 + fd = sys_open(path, 0, 0);
330 + mconsole_reply(req, "Failed to open file", 1, 0);
331 + printk("open %s: %d\n",path,fd);
335 + buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
337 + mconsole_reply(req, "Failed to allocate buffer", 1, 0);
342 + len = sys_read(fd, buf, PAGE_SIZE-1);
344 + mconsole_reply(req, "Read of file failed", 1, 0);
347 + /*Begin the file content on his own line.*/
349 + mconsole_reply(req, "\n", 0, 1);
352 + if (len == PAGE_SIZE-1) {
354 + mconsole_reply(req, buf, 0, 1);
357 + mconsole_reply(req, buf, 0, 0);
372 void mconsole_proc(struct mc_request *req)
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
380 lp->tl.data = (unsigned long) &lp->user;
381 netif_start_queue(dev);
383 - spin_lock(&opened_lock);
384 - list_add(&lp->list, &opened);
385 - spin_unlock(&opened_lock);
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.
391 free_irq(dev->irq, dev);
392 if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
394 - spin_lock(&opened_lock);
395 - list_del(&lp->list);
396 - spin_unlock(&opened_lock);
398 spin_unlock(&lp->lock);
402 if (device->have_mac)
403 set_ether_mac(dev, device->mac);
405 + spin_lock(&opened_lock);
406 + list_add(&lp->list, &opened);
407 + spin_unlock(&opened_lock);
413 static void close_devices(void)
415 struct list_head *ele;
416 - struct uml_net_private *lp;
417 + struct uml_net_private *lp;
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);
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]);
434 - CATCH_EINTR(err = waitpid(pid, NULL, 0));
436 + CATCH_EINTR(err = waitpid(pid, NULL, 0));
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
445 CATCH_EINTR(waitpid(pid, NULL, 0));
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.
453 void os_kill_ptraced_process(int pid, int reap_child)
455 + kill(pid, SIGKILL);
456 ptrace(PTRACE_KILL, pid);
457 + ptrace(PTRACE_CONT, pid);
459 CATCH_EINTR(waitpid(pid, NULL, 0));
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
467 + * arch/um/kernel/elf_aux.c
469 + * Scan the Elf auxiliary vector provided by the host to extract
470 + * information about vsyscall-page, etc.
472 + * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
473 + * Author: Bodo Stroesser (bodo.stroesser@fujitsu-siemens.com)
478 +#include "elf_user.h"
480 +#if ELF_CLASS == ELFCLASS32
481 +typedef Elf32_auxv_t elf_auxv_t;
483 +typedef Elf64_auxv_t elf_auxv_t;
486 +char * elf_aux_platform;
489 +unsigned long vsyscall_ehdr;
490 +unsigned long vsyscall_end;
492 +unsigned long __kernel_vsyscall;
495 +__init void scan_elf_aux( char **envp)
497 + long page_size = 0;
500 + while ( *envp++ != NULL) ;
502 + for ( auxv = (elf_auxv_t *)envp; auxv->a_type != AT_NULL; auxv++) {
503 + switch ( auxv->a_type ) {
505 + __kernel_vsyscall = auxv->a_un.a_val;
507 + case AT_SYSINFO_EHDR:
508 + vsyscall_ehdr = auxv->a_un.a_val;
511 + elf_aux_hwcap = auxv->a_un.a_val;
514 + elf_aux_platform = auxv->a_un.a_val;
517 + page_size = auxv->a_un.a_val;
521 + if ( ! __kernel_vsyscall || ! vsyscall_ehdr ||
522 + ! elf_aux_hwcap || ! elf_aux_platform ||
523 + ! page_size || (vsyscall_ehdr % page_size) ) {
524 + __kernel_vsyscall = 0;
527 + elf_aux_platform = "i586";
530 + vsyscall_end = vsyscall_ehdr + page_size;
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
539 EXPORT_SYMBOL(strstr);
541 +EXPORT_SYMBOL(vsyscall_ehdr);
542 +EXPORT_SYMBOL(vsyscall_end);
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
552 # Licensed under the GPL
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/
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))
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
569 + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
570 + * Licensed under the GPL
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"
585 +#ifdef CONFIG_MODE_SKAS
589 +static int copy_sc_from_user_skas(struct pt_regs *regs,
590 + struct sigcontext *from)
592 + struct sigcontext sc;
593 + unsigned long fpregs[HOST_FP_SIZE];
596 + err = copy_from_user(&sc, from, sizeof(sc));
597 + err |= copy_from_user(fpregs, sc.fpstate, sizeof(fpregs));
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;
621 + err = ptrace_setfpregs(userspace_pid[0], fpregs);
623 + printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, "
624 + "errno = %d\n", err);
631 +int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
632 + struct pt_regs *regs, unsigned long fault_addr,
635 + struct sigcontext sc;
636 + unsigned long fpregs[HOST_FP_SIZE];
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;
660 + err = ptrace_getfpregs(userspace_pid[0], fpregs);
662 + printk("copy_sc_to_user_skas - PTRACE_GETFPREGS failed, "
663 + "errno = %d\n", err);
666 + to_fp = (to_fp ? to_fp : (struct _fpstate *) (to + 1));
667 + sc.fpstate = to_fp;
672 + return(copy_to_user(to, &sc, sizeof(sc)) ||
673 + copy_to_user(to_fp, fpregs, sizeof(fpregs)));
677 +#ifdef CONFIG_MODE_TT
678 +int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from,
681 + struct _fpstate *to_fp, *from_fp;
682 + unsigned long sigs;
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;
691 + err |= copy_from_user(&to->fpstate, &to_fp,
692 + sizeof(to->fpstate));
693 + err |= copy_from_user(to_fp, from_fp, fpsize);
698 +int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp,
699 + struct sigcontext *from, int fpsize)
701 + struct _fpstate *to_fp, *from_fp;
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);
716 +static int copy_sc_from_user(struct pt_regs *to, void *from)
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));
726 +static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp,
727 + struct pt_regs *from)
729 + return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
731 + copy_sc_to_user_skas(to, fp, from,
732 + current->thread.cr2,
733 + current->thread.err)));
736 +static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp,
737 + sigset_t *set, unsigned long sp)
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, ¤t->thread.regs);
745 + err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
753 + struct sigcontext sc;
754 + struct _fpstate fpstate;
755 + unsigned long extramask[_NSIG_WORDS-1];
763 + struct siginfo *pinfo;
765 + struct siginfo info;
766 + struct ucontext uc;
767 + struct _fpstate fpstate;
771 +int setup_signal_stack_sc(unsigned long stack_top, int sig,
772 + struct k_sigaction *ka, struct pt_regs *regs,
775 + struct sigframe __user *frame;
780 + frame = (struct sigframe *) stack_top - 1;
781 + if(verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
784 + restorer = (void *) frame->retcode;
785 + if(ka->sa.sa_flags & SA_RESTORER)
786 + restorer = ka->sa.sa_restorer;
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));
797 + * This is popl %eax ; movl $,%eax ; int $0x80
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.
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));
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;
816 + if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
817 + ptrace_notify(SIGTRAP);
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)
825 + struct rt_sigframe __user *frame;
830 + frame = (struct rt_sigframe *) stack_top - 1;
831 + if(verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
834 + restorer = (void *) frame->retcode;
835 + if(ka->sa.sa_flags & SA_RESTORER)
836 + restorer = ka->sa.sa_restorer;
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,
847 + * This is movl $,%eax ; int $0x80
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.
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));
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;
866 + if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
867 + ptrace_notify(SIGTRAP);
871 +long sys_sigreturn(struct pt_regs regs)
873 + unsigned long __user sp = PT_REGS_SP(¤t->thread.regs);
874 + struct sigframe __user *frame = (struct sigframe *)(sp - 8);
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);
881 + if(copy_from_user(&set.sig[0], oldmask, sizeof(&set.sig[0])) ||
882 + copy_from_user(&set.sig[1], extramask, sig_size))
885 + sigdelsetmask(&set, ~_BLOCKABLE);
887 + spin_lock_irq(¤t->sighand->siglock);
888 + current->blocked = set;
889 + recalc_sigpending();
890 + spin_unlock_irq(¤t->sighand->siglock);
892 + if(copy_sc_from_user(¤t->thread.regs, sc))
895 + PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; /* Avoid ERESTART handling */
896 + return(PT_REGS_SYSCALL_RET(¤t->thread.regs));
899 + force_sig(SIGSEGV, current);
903 +long sys_rt_sigreturn(struct pt_regs regs)
905 + unsigned long __user sp = PT_REGS_SP(¤t->thread.regs);
906 + struct rt_sigframe __user *frame = (struct rt_sigframe *) (sp - 4);
908 + struct ucontext __user *uc = &frame->uc;
909 + int sig_size = _NSIG_WORDS * sizeof(unsigned long);
911 + if(copy_from_user(&set, &uc->uc_sigmask, sig_size))
914 + sigdelsetmask(&set, ~_BLOCKABLE);
916 + spin_lock_irq(¤t->sighand->siglock);
917 + current->blocked = set;
918 + recalc_sigpending();
919 + spin_unlock_irq(¤t->sighand->siglock);
921 + if(copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext))
924 + PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; /* Avoid ERESTART handling */
925 + return(PT_REGS_SYSCALL_RET(¤t->thread.regs));
928 + force_sig(SIGSEGV, current);
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
937 + * ---------------------------------------------------------------------------
939 + * c-file-style: "linux"
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
948 int ptrace_getregs(long pid, unsigned long *regs_out)
950 - return(ptrace(PTRACE_GETREGS, pid, 0, regs_out));
951 + if(ptrace(PTRACE_GETREGS, pid, 0, regs_out) < 0)
956 int ptrace_setregs(long pid, unsigned long *regs)
958 - return(ptrace(PTRACE_SETREGS, pid, 0, regs));
959 + if(ptrace(PTRACE_SETREGS, pid, 0, regs) < 0)
964 int ptrace_getfpregs(long pid, unsigned long *regs)
966 - return(ptrace(PTRACE_GETFPREGS, pid, 0, regs));
967 + if(ptrace(PTRACE_GETFPREGS, pid, 0, regs) < 0)
972 +int ptrace_setfpregs(long pid, unsigned long *regs)
974 + if(ptrace(PTRACE_SETFPREGS, pid, 0, regs) < 0)
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
986 show_trace((unsigned long *) ®s);
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
993 + * ---------------------------------------------------------------------------
995 + * c-file-style: "linux"
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
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
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
1014 #include <asm/sigcontext.h>
1015 #include "sysdep/ptrace.h"
1016 #include "kern_util.h"
1017 -#include "frame_user.h"
1019 -int sc_size(void *data)
1021 - struct arch_frame_data *arch = data;
1023 - return(sizeof(struct sigcontext) + arch->fpstate_size);
1026 void sc_to_sc(void *to_ptr, void *from_ptr)
1028 struct sigcontext *to = to_ptr, *from = from_ptr;
1029 - int size = sizeof(*to) + signal_frame_sc.common.arch.fpstate_size;
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);
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
1045 extern int uml_exitcode;
1047 +extern void scan_elf_aux( char **envp);
1049 int main(int argc, char **argv, char **envp)
1053 set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
1054 set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
1056 + scan_elf_aux( envp);
1059 ret = linux_main(argc, argv);
1061 @@ -155,18 +159,20 @@
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.
1070 - unblock_signals();
1071 + /* stop timers and set SIG*ALRM to be ignored */
1073 + /* disable SIGIO for the fds and set SIGIO to be ignored */
1074 err = deactivate_all_fds();
1076 printf("deactivate_all_fds failed, errno = %d\n",
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.
1083 + unblock_signals();
1085 execvp(new_argv[0], new_argv);
1086 perror("Failed to exec kernel");
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
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>
1101 printk("Checking that ptrace can change system call numbers...");
1102 pid = start_ptraced_child(&stack);
1104 + if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
1105 + panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno);
1108 if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
1109 panic("check_ptrace : ptrace failed, errno = %d",
1111 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
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);
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
1130 + os_close_file(fd);
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
1139 void timer_handler(int sig, union uml_pt_regs *regs)
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));
1145 if(current_thread->cpu == 0)
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
1155 -/* XXX The alloc_stack here breaks if this is called in the tracing thread */
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)
1162 struct helper_data data;
1163 unsigned long stack, sp;
1164 - int pid, fds[2], err, n;
1165 + int pid, fds[2], ret, n;
1167 if((stack_out != NULL) && (*stack_out != 0))
1173 - err = os_pipe(fds, 1, 0);
1175 - printk("run_helper : pipe failed, err = %d\n", -err);
1176 + ret = os_pipe(fds, 1, 0);
1178 + printk("run_helper : pipe failed, ret = %d\n", -ret);
1182 - err = os_set_exec_close(fds[1], 1);
1184 - printk("run_helper : setting FD_CLOEXEC failed, err = %d\n",
1186 + ret = os_set_exec_close(fds[1], 1);
1188 + printk("run_helper : setting FD_CLOEXEC failed, ret = %d\n",
1194 pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
1196 printk("run_helper : clone failed, errno = %d\n", errno);
1202 os_close_file(fds[1]);
1203 - n = os_read_file(fds[0], &err, sizeof(err));
1206 + /*Read the errno value from the child.*/
1207 + n = os_read_file(fds[0], &ret, sizeof(ret));
1209 - printk("run_helper : read on pipe failed, err = %d\n", -n);
1212 + printk("run_helper : read on pipe failed, ret = %d\n", -n);
1214 + os_kill_process(pid, 1);
1217 CATCH_EINTR(n = waitpid(pid, NULL, 0));
1224 - if(stack_out == NULL) free_stack(stack, 0);
1225 - else *stack_out = stack;
1229 - os_kill_process(pid, 1);
1232 + os_close_file(fds[1]);
1233 os_close_file(fds[0]);
1234 - os_close_file(fds[1]);
1236 - free_stack(stack, 0);
1238 + if(stack_out == NULL)
1239 + free_stack(stack, 0);
1240 + else *stack_out = stack;
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
1253 + /* If there is a signal already queued, after unblocking ignore it */
1254 + set_handler(SIGIO, SIG_IGN, 0, -1);
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 @@
1264 #endif /* CONFIG_HIGHMEM */
1266 +static void __init fixaddr_user_init( void)
1268 + long size = FIXADDR_USER_END - FIXADDR_USER_START;
1272 + unsigned long paddr, vaddr = FIXADDR_USER_START;
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);
1290 void paging_init(void)
1292 unsigned long zones_size[MAX_NR_ZONES], vaddr;
1294 vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
1295 fixrange_init(vaddr, FIXADDR_TOP, swapper_pg_dir);
1297 + fixaddr_user_init();
1299 #ifdef CONFIG_HIGHMEM
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
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>
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)
1318 - int err, syscall_nr, status;
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);
1329 + UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->skas.regs); /* Mark this as a syscall */
1330 if (!local_using_sysemu)
1332 err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
1334 "errno = %d\n", errno);
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);
1343 @@ -131,6 +128,10 @@
1344 panic("start_userspace : expected SIGSTOP, got status = %d",
1347 + if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, (void *)PTRACE_O_TRACESYSGOOD) < 0)
1348 + panic("start_userspace : PTRACE_SETOPTIONS failed, errno=%d\n",
1351 if(munmap(stack, PAGE_SIZE) < 0)
1352 panic("start_userspace : munmap failed, errno = %d\n", errno);
1354 @@ -160,15 +161,19 @@
1356 regs->skas.is_user = 1;
1357 save_registers(regs);
1358 + UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
1360 if(WIFSTOPPED(status)){
1361 switch(WSTOPSIG(status)){
1366 + case (SIGTRAP|SYSCALL_TRAP):
1367 handle_trap(pid, regs, local_using_sysemu);
1370 + relay_signal(SIGTRAP, regs);
1375 @@ -222,9 +227,10 @@
1377 if(sigsetjmp(fork_buf, 1) == 0)
1378 new_thread_proc(stack, handler);
1379 - set_signals(flags);
1383 + set_signals(flags);
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
1393 -# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
1394 -# Licensed under the GPL
1397 -obj-y = sigcontext.o
1399 -USER_OBJS = sigcontext.o
1400 -USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
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
1410 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
1411 - * Licensed under the GPL
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"
1422 -#include "sigcontext.h"
1425 -int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, void *from_ptr)
1427 - struct sigcontext sc, *from = from_ptr;
1428 - unsigned long fpregs[FP_FRAME_SIZE];
1431 - err = copy_from_user_proc(&sc, from, sizeof(sc));
1432 - err |= copy_from_user_proc(fpregs, sc.fpstate, sizeof(fpregs));
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;
1456 - err = ptrace(PTRACE_SETFPREGS, pid, 0, fpregs);
1458 - printk("copy_sc_to_user - PTRACE_SETFPREGS failed, "
1459 - "errno = %d\n", errno);
1466 -int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp,
1467 - union uml_pt_regs *regs, unsigned long fault_addr,
1470 - struct sigcontext sc, *to = to_ptr;
1471 - struct _fpstate *to_fp;
1472 - unsigned long fpregs[FP_FRAME_SIZE];
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;
1496 - err = ptrace(PTRACE_GETFPREGS, pid, 0, fpregs);
1498 - printk("copy_sc_to_user - PTRACE_GETFPREGS failed, "
1499 - "errno = %d\n", errno);
1502 - to_fp = (struct _fpstate *)
1503 - (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
1504 - sc.fpstate = to_fp;
1509 - return(copy_to_user_proc(to, &sc, sizeof(sc)) ||
1510 - copy_to_user_proc(to_fp, fpregs, sizeof(fpregs)));
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
1518 - * ---------------------------------------------------------------------------
1519 - * Local variables:
1520 - * c-file-style: "linux"
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
1529 #include "user_util.h"
1534 #include "proc_mm.h"
1536 int start_uml_skas(void)
1539 - capture_signal_stack();
1541 init_new_thread_signals(1);
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
1548 int save_errno = errno;
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
1556 + if(sig == SIGSEGV)
1557 + change_sig(SIGSEGV, 1);
1559 r = &TASK_REGS(get_current())->skas;
1560 save_user = r->is_user;
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
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
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 \
1584 + syscall_kern.o syscall_user.o time.o tlb.o trap_user.o uaccess.o
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
1593 * c-file-style: "linux"
1597 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
1598 + * Licensed under the GPL
1601 +#ifndef __SKAS_MMU_H
1602 +#define __SKAS_MMU_H
1604 +struct mmu_context_skas {
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
1615 + * ---------------------------------------------------------------------------
1616 + * Local variables:
1617 + * c-file-style: "linux"
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
1625 extern int have_fpx_regs;
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);
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
1641 + * ---------------------------------------------------------------------------
1642 + * Local variables:
1643 + * c-file-style: "linux"
1647 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
1648 + * Licensed under the GPL
1651 +#ifndef __MODE_SKAS_H__
1652 +#define __MODE_SKAS_H__
1654 +#include <sysdep/ptrace.h>
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;
1661 +extern void user_time_init_skas(void);
1662 extern int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs,
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
1670 #define __SKAS_UACCESS_H
1672 #include "asm/errno.h"
1673 +#include "asm/fixmap.h"
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))))
1684 +static inline int verify_area_skas(int type, const void * addr,
1685 + unsigned long size)
1687 + return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
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);
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
1704 + * ---------------------------------------------------------------------------
1705 + * Local variables:
1706 + * c-file-style: "linux"
1710 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
1711 + * Licensed under the GPL
1714 +#ifndef __SKAS_UACCESS_H
1715 +#define __SKAS_UACCESS_H
1717 +#include "asm/errno.h"
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
1726 syscall_trace(regs, 1);
1727 record_syscall_end(index, result);
1730 -int do_syscall(void *task, int pid, int local_using_sysemu)
1732 - unsigned long proc_regs[FRAME_SIZE];
1733 - union uml_pt_regs *regs;
1736 - if(ptrace_getregs(pid, proc_regs) < 0)
1737 - tracer_panic("Couldn't read registers");
1738 - syscall = PT_SYSCALL_NR(proc_regs);
1740 - regs = TASK_REGS(task);
1741 - UPT_SYSCALL_NR(regs) = syscall;
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");
1751 - if(local_using_sysemu)
1754 - if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
1756 - tracer_panic("do_syscall : Nullifying syscall failed, "
1757 - "errno = %d", errno);
1761 + void do_sigtrap(void *task)
1763 + UPT_SYSCALL_NR(TASK_REGS(task)) = -1;
1766 + void do_syscall(void *task, int pid, int local_using_sysemu)
1768 + unsigned long proc_regs[FRAME_SIZE];
1770 + if(ptrace_getregs(pid, proc_regs) < 0)
1771 + tracer_panic("Couldn't read registers");
1773 + UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs);
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");
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);
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
1794 -# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
1795 -# Licensed under the GPL
1798 -obj-y = sigcontext.o
1800 -USER_OBJS = sigcontext.o
1801 -USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
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
1811 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
1812 - * Licensed under the GPL
1815 -#include <stdlib.h>
1816 -#include <asm/sigcontext.h>
1817 -#include "kern_util.h"
1818 -#include "sysdep/frame.h"
1820 -int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data)
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;
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);
1841 -int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, void *data)
1843 - struct arch_frame_data *arch = data;
1844 - struct sigcontext *to = to_ptr, *from = from_ptr;
1845 - struct _fpstate *to_fp, *from_fp;
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);
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
1865 - * ---------------------------------------------------------------------------
1866 - * Local variables:
1867 - * c-file-style: "linux"
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
1876 #include <sys/wait.h>
1877 #include <sys/ptrace.h>
1878 +#include <linux/ptrace.h>
1880 #include "user_util.h"
1881 #include "kern_util.h"
1883 tracer_panic("do_exec failed to get registers - errno = %d",
1886 - kill(old_pid, SIGKILL);
1887 + os_kill_ptraced_process(old_pid, 0);
1889 + if (ptrace(PTRACE_OLDSETOPTIONS, new_pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
1890 + tracer_panic("do_exec: PTRACE_SETOPTIONS failed, errno = %d", errno);
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
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>
1907 #include "mem_user.h"
1908 #include "process.h"
1909 #include "kern_util.h"
1911 #include "chan_user.h"
1912 #include "ptrace_user.h"
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");
1924 * any more, the trace of those will land here. So, we need to just
1925 * PTRACE_SYSCALL it.
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",
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;
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);
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);
1951 if((ptrace(PTRACE_CONT, pid, 0, 0) < 0)){
1952 printf("Failed to continue idle thread, errno = %d\n", errno);
1954 @@ -265,7 +270,25 @@
1956 else if(WIFSIGNALED(status)){
1957 sig = WTERMSIG(status);
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
1975 + ptrace(PTRACE_KILL, pid, 0, 0);
1976 + ptrace(PTRACE_CONT, pid, 0, 0);
1978 printf("Child %d exited with signal %d\n", pid,
1982 task = cpu_tasks[proc_id].task;
1983 tracing = is_tracing(task);
1984 old_tracing = tracing;
1986 + if ( tracing ) /* Assume: no syscall, when coming from user */
1988 local_using_sysemu = get_using_sysemu();
1989 pt_syscall_parm = local_using_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL;
1991 @@ -306,6 +330,15 @@
1993 op = do_proc_op(task, proc_id);
1996 + * This is called when entering user mode; after
1997 + * this, we start intercepting syscalls.
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);
2005 arch_leave_kernel(task, pid);
2007 @@ -314,7 +347,13 @@
2011 - ptrace(PTRACE_KILL, pid, 0, 0);
2012 + os_kill_ptraced_process(pid, 0);
2013 + /* Now let's reap remaining zombies */
2016 + waitpid(-1, &status,
2018 + } while (errno != ECHILD);
2019 return(op == OP_REBOOT);
2021 printf("Detaching pid %d\n", pid);
2022 @@ -328,14 +367,26 @@
2024 pid = cpu_tasks[proc_id].pid;
2026 + case (SIGTRAP|SYSCALL_TRAP):
2027 + if(!tracing && (debugger_pid != -1)){
2028 + child_signal(pid, W_STOPCODE(SIGTRAP));
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);
2041 if(!tracing && (debugger_pid != -1)){
2042 child_signal(pid, status);
2046 - if(do_syscall(task, pid, local_using_sysemu))
2050 if(tracing) sig = 0;
2055 + local_using_sysemu = get_using_sysemu();
2056 + pt_syscall_parm = local_using_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL;
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
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
2072 obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/
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
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);
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
2096 + * ---------------------------------------------------------------------------
2097 + * Local variables:
2098 + * c-file-style: "linux"
2102 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
2103 + * Licensed under the GPL
2106 +#ifndef __MODE_TT_H__
2107 +#define __MODE_TT_H__
2109 +#include "sysdep/ptrace.h"
2111 +enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
2113 +extern int tracing_pid;
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,
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
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);
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
2139 #include "asm/uaccess.h"
2140 #include "kern_util.h"
2141 #include "ptrace_user.h"
2142 +#include "signal_user.h"
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));
2152 + ptrace_notify(SIGTRAP | (tracesysgood ? SYSCALL_TRAP : 0));
2153 + if ( entryexit ) /* force do_signal() --> is_syscall() */
2154 + set_thread_flag(TIF_SIGPENDING);
2156 /* force do_signal() --> is_syscall() */
2157 set_thread_flag(TIF_SIGPENDING);
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
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
2173 . = ALIGN(4096); /* Init code and data */
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
2180 .ipi_pipe = { -1, -1 }
2183 -/* Placeholder to make UML link until the vsyscall stuff is actually
2186 -void *__kernel_vsyscall;
2188 unsigned long thread_saved_pc(struct task_struct *task)
2190 return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
2191 @@ -326,6 +321,11 @@
2195 + /* Need to check this early because mmapping happens before the
2196 + * kernel is running.
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
2208 (setitimer(ITIMER_REAL, &disable, NULL) < 0))
2209 printk("disnable_timer - setitimer failed, errno = %d\n",
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);
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
2223 EXPORT_SYMBOL(disable_hlt);
2225 -extern int signal_frame_size;
2227 void *um_kmalloc(int size)
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
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"
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(¤t->thread.regs)));
2250 -extern int userspace_pid[];
2252 -static int copy_sc_from_user(struct pt_regs *to, void *from,
2253 - struct arch_frame_data *arch)
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));
2263 -long sys_sigreturn(struct pt_regs regs)
2265 - void __user *sc = sp_to_sc(PT_REGS_SP(¤t->thread.regs));
2266 - void __user *mask = sp_to_mask(PT_REGS_SP(¤t->thread.regs));
2267 - int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
2269 - spin_lock_irq(¤t->sighand->siglock);
2270 - copy_from_user(¤t->blocked.sig[0], sc_sigmask(sc),
2271 - sizeof(current->blocked.sig[0]));
2272 - copy_from_user(¤t->blocked.sig[1], mask, sig_size);
2273 - sigdelsetmask(¤t->blocked, ~_BLOCKABLE);
2274 - recalc_sigpending();
2275 - spin_unlock_irq(¤t->sighand->siglock);
2276 - copy_sc_from_user(¤t->thread.regs, sc,
2277 - &signal_frame_sc.common.arch);
2278 - return(PT_REGS_SYSCALL_RET(¤t->thread.regs));
2281 -long sys_rt_sigreturn(struct pt_regs regs)
2283 - unsigned long sp = PT_REGS_SP(¤t->thread.regs);
2284 - struct ucontext __user *uc = sp_to_uc(sp);
2285 - int sig_size = _NSIG_WORDS * sizeof(unsigned long);
2287 - spin_lock_irq(¤t->sighand->siglock);
2288 - copy_from_user(¤t->blocked, &uc->uc_sigmask, sig_size);
2289 - sigdelsetmask(¤t->blocked, ~_BLOCKABLE);
2290 - recalc_sigpending();
2291 - spin_unlock_irq(¤t->sighand->siglock);
2292 - copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext,
2293 - &signal_frame_si.common.arch);
2294 - return(PT_REGS_SYSCALL_RET(¤t->thread.regs));
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
2308 + /*This must contain the right address - not quite the default ELF one.*/
2309 + PROVIDE (__executable_start = START);
2310 . = START + SIZEOF_HEADERS;
2312 + /* Used in arch/um/kernel/mem.c. Any memory between START and __binary_start
2320 .remap : { arch/um/kernel/tt/unmap_fin.o (.text) }
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 */
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
2337 EXPORT_SYMBOL(mode_tt);
2338 EXPORT_SYMBOL(handle_page_fault);
2339 EXPORT_SYMBOL(find_iomem);
2340 +EXPORT_SYMBOL(end_iomem);
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
2349 * disable profiling; it's safe because the profiling code does not interact
2350 * with the kernel code at all.*/
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.*/
2356 static void change_signals(int type)
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
2366 munmap(addr, UM_KERN_PAGE_SIZE);
2368 + os_close_file(fd);
2371 static int have_devanon = 0;
2372 @@ -261,6 +263,39 @@
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.
2383 +int logging_fd = -1;
2385 +int logging_line = 0;
2386 +char logging_buf[512];
2388 +void log(char *fmt, ...)
2391 + struct timeval tv;
2392 + struct openflags flags;
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);
2399 + gettimeofday(&tv, NULL);
2400 + sprintf(logging_buf, "%d\t %u.%u ", logging_line++, tv.tv_sec,
2402 + va_start(ap, fmt);
2403 + vsprintf(&logging_buf[strlen(logging_buf)], fmt, ap);
2405 + write(logging_fd, logging_buf, strlen(logging_buf));
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
2417 extra-y := vmlinux.lds
2418 clean-files := vmlinux.lds.S
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 @@
2431 It is safe to say 'Y' here.
2434 + bool "Magic SysRq key"
2435 + depends on MCONSOLE
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.
2443 + This is the feature normally accomplished by pressing a key
2444 + while holding SysRq (Alt+PrintScreen).
2446 + On UML, this is accomplished by sending a "sysrq" command with
2447 + mconsole, followed by the letter for the requested command.
2449 + The keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
2450 + unless you really know what this hack does.
2453 bool "2G/2G host address space split"
2455 @@ -153,28 +172,28 @@
2456 So, if you do not know what to do here, say 'N'.
2459 - bool "Symmetric multi-processing support (EXPERIMENTAL)"
2461 - depends on MODE_TT && EXPERIMENTAL
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)"
2467 + depends on MODE_TT && EXPERIMENTAL
2469 + This option enables UML SMP support.
2470 + It is NOT related to having a real SMP box. Not directly, at least.
2472 + UML implements virtual SMP by allowing as many processes to run
2473 + simultaneously on the host as there are virtual processors configured.
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.
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.
2486 - UML implements virtual SMP by allowing as many processes to run
2487 - simultaneously on the host as there are virtual processors configured.
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.
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.
2500 - If you don't know what to do, say N.
2501 + If you don't know what to do, say N.
2504 int "Maximum number of CPUs (2-32)"
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
2520 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
2521 - * Licensed under the GPL
2527 -#include "sysdep/frame.h"
2529 -struct frame_common {
2536 - struct arch_frame_data arch;
2540 - struct frame_common common;
2544 -extern struct sc_frame signal_frame_sc;
2546 -extern struct sc_frame signal_frame_sc_sr;
2549 - struct frame_common common;
2556 -extern struct si_frame signal_frame_si;
2558 -extern void capture_signal_stack(void);
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
2567 - * ---------------------------------------------------------------------------
2568 - * Local variables:
2569 - * c-file-style: "linux"
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
2578 + * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
2579 + * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
2580 + * Licensed under the GPL
2583 +#ifndef __ELF_USER_H__
2584 +#define __ELF_USER_H__
2586 +/* For compilation on a host that doesn't support AT_SYSINFO (Linux 2.4) */
2589 +#define AT_SYSINFO 32
2591 +#ifndef AT_SYSINFO_EHDR
2592 +#define AT_SYSINFO_EHDR 33
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
2601 extern int set_signals(int enable);
2602 extern int get_signals(void);
2604 +#define SYSCALL_TRAP 0x80
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
2614 #ifndef __SKAS_PTRACE_H
2615 #define __SKAS_PTRACE_H
2617 +#ifndef PTRACE_FAULTINFO
2618 struct ptrace_faultinfo {
2622 #define PTRACE_SIGPENDING 53
2623 #define PTRACE_LDT 54
2624 #define PTRACE_SWITCH_MM 55
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
2634 #ifndef __FRAME_KERN_H_
2635 #define __FRAME_KERN_H_
2638 -#include "sysdep/frame_kern.h"
2639 +#define _S(nr) (1<<((nr)-1))
2640 +#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
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
2649 int get_using_sysemu(void);
2650 extern int sysemu_supported;
2653 +/* syscall emulation path in ptrace */
2655 +#ifndef PTRACE_SYSEMU
2656 +#define PTRACE_SYSEMU 31
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.
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.
2675 +#ifndef PTRACE_OLDSETOPTIONS
2676 +#define PTRACE_OLDSETOPTIONS PTRACE_SETOPTIONS
2679 +void set_using_sysemu(int value);
2680 +int get_using_sysemu(void);
2681 +extern int sysemu_supported;
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
2690 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
2691 - * Licensed under the GPL
2694 -#ifndef __FRAME_I386_H
2695 -#define __FRAME_I386_H
2697 -struct arch_frame_data_raw {
2698 - unsigned long fp_start;
2702 -struct arch_frame_data {
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
2713 - * ---------------------------------------------------------------------------
2714 - * Local variables:
2715 - * c-file-style: "linux"
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
2724 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
2725 - * Licensed under the GPL
2728 -#ifndef __FRAME_KERN_I386_H
2729 -#define __FRAME_KERN_I386_H
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
2736 -static inline void *sp_to_sc(unsigned long sp)
2738 - return((void *) sp);
2741 -static inline void *sp_to_uc(unsigned long sp)
2745 - uc = sp + signal_frame_si.uc_index -
2746 - signal_frame_si.common.sp_index - 4;
2747 - return((void *) uc);
2750 -static inline void *sp_to_rt_sc(unsigned long sp)
2754 - sc = sp - signal_frame_si.common.sp_index +
2755 - signal_frame_si.common.len - 4;
2756 - return((void *) sc);
2759 -static inline void *sp_to_mask(unsigned long sp)
2761 - unsigned long mask;
2763 - mask = sp - signal_frame_sc.common.sp_index +
2764 - signal_frame_sc.common.len - 8;
2765 - return((void *) mask);
2768 -extern int sc_size(void *data);
2770 -static inline void *sp_to_rt_mask(unsigned long sp)
2772 - unsigned long mask;
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);
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
2787 - * ---------------------------------------------------------------------------
2788 - * Local variables:
2789 - * c-file-style: "linux"
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
2798 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
2799 - * Licensed under the GPL
2802 -#ifndef __FRAME_USER_I386_H
2803 -#define __FRAME_USER_I386_H
2805 -#include <asm/page.h>
2806 -#include "sysdep/frame.h"
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.
2823 -static inline void setup_arch_frame_raw(struct arch_frame_data_raw *data,
2824 - void *end, unsigned long srp)
2826 - unsigned long sr = *((unsigned long *) srp);
2828 - data->fp_start = (unsigned long) end;
2829 - if((sr & PAGE_MASK) == ((unsigned long) end & PAGE_MASK))
2831 - else data->sr = 0;
2834 -static inline void setup_arch_frame(struct arch_frame_data_raw *in,
2835 - struct arch_frame_data *out)
2837 - unsigned long fpstate_start = in->fp_start;
2840 - fpstate_start &= ~PAGE_MASK;
2841 - out->fpstate_size = PAGE_SIZE - fpstate_start;
2844 - out->fpstate_size = in->sr - fpstate_start;
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).
2855 -#define frame_restorer() \
2857 - unsigned long *fp; \
2859 - fp = __builtin_frame_address(0); \
2860 - ((unsigned long) (fp + 1)); \
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
2868 -#define frame_sp() \
2870 - unsigned long *fp; \
2872 - fp = __builtin_frame_address(0); \
2873 - ((unsigned long) (fp + 1)); \
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
2883 - * ---------------------------------------------------------------------------
2884 - * Local variables:
2885 - * c-file-style: "linux"
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
2894 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
2895 - * Licensed under the GPL
2898 -#ifndef __FRAME_USER_H_
2899 -#define __FRAME_USER_H_
2901 -#include "sysdep/frame_user.h"
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
2911 - * ---------------------------------------------------------------------------
2912 - * Local variables:
2913 - * c-file-style: "linux"
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
2921 #include <linux/user.h>
2922 #include <linux/security.h>
2923 #include <linux/audit.h>
2924 +#include <linux/proc_mm.h>
2926 #include <asm/uaccess.h>
2927 #include <asm/pgtable.h>
2928 @@ -406,15 +407,27 @@
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. */
2936 if ((unsigned long) data > _NSIG)
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().
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);
2950 if (request == PTRACE_SYSCALL) {
2951 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
2955 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
2957 child->exit_code = data;
2960 if ((unsigned long) data > _NSIG)
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);
2971 +#ifdef CONFIG_PROC_MM
2972 + case PTRACE_FAULTINFO: {
2973 + struct ptrace_faultinfo fault;
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,
2985 + case PTRACE_SIGPENDING:
2986 + ret = copy_to_user((unsigned long *) data,
2987 + &child->pending.signal,
2988 + sizeof(child->pending.signal));
2991 + case PTRACE_LDT: {
2992 + struct ptrace_ldt ldt;
2994 + if(copy_from_user(&ldt, (unsigned long *) data,
2999 + ret = __modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
3003 + case PTRACE_SWITCH_MM: {
3004 + struct mm_struct *old = child->mm;
3005 + struct mm_struct *new = proc_mm_get_mm(data);
3008 + ret = PTR_ERR(new);
3012 + atomic_inc(&new->mm_users);
3015 + child->active_mm = new;
3016 + task_unlock(child);
3024 ret = ptrace_request(child, request, addr, data);
3027 * - triggered by current->work.syscall_trace
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)
3033 + int is_sysemu, is_systrace, is_singlestep;
3034 if (unlikely(current->audit_context)) {
3036 audit_syscall_entry(current, regs->orig_eax,
3037 @@ -567,16 +635,27 @@
3039 audit_syscall_exit(current, regs->eax);
3042 - if (!test_thread_flag(TIF_SYSCALL_TRACE) &&
3043 - !test_thread_flag(TIF_SINGLESTEP))
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);
3049 + if (!is_systrace && !is_singlestep && !is_sysemu)
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.
3056 + if (is_sysemu && (is_systrace || is_singlestep)) {
3057 + clear_thread_flag(TIF_SYSCALL_EMU);
3060 if (!(current->ptrace & PT_PTRACED))
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));
3070 * this isn't the same as continuing with a signal, but it will do
3072 send_sig(current->exit_code, current, 1);
3073 current->exit_code = 0;
3075 + /* != 0 if nullifying the syscall, 0 if running it normally */
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
3083 #include <asm/system.h>
3084 #include <asm/ldt.h>
3085 #include <asm/desc.h>
3086 +#include <asm/mmu_context.h>
3088 #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
3089 static void flush_ldt(void *null)
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)
3100 + mm_context_t * pc = &mm->context;
3102 if (mincount <= pc->size)
3109 + if (¤t->active_mm->context == 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);
3118 + if (¤t->active_mm->context == pc)
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)
3130 - int err = alloc_ldt(new, old->size, 0);
3131 + int err = alloc_ldt(new, old->context.size, 0);
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);
3140 * we do not have to muck with descriptors here, that is
3141 * done in switch_mm() as needed.
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)
3146 - struct mm_struct * old_mm;
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);
3161 +int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
3163 + init_new_empty_context(mm);
3164 + return copy_context(mm, current->mm);
3168 * No need to lock the MM as we are the last user
3170 @@ -121,11 +127,11 @@
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)
3180 - struct mm_struct * mm = current->mm;
3182 if (!mm->context.size)
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)
3191 - struct mm_struct * mm = current->mm;
3192 __u32 entry_1, entry_2, *lp;
3194 struct user_desc ldt_info;
3197 down(&mm->context.sem);
3198 if (ldt_info.entry_number >= mm->context.size) {
3199 - error = alloc_ldt(¤t->mm->context, ldt_info.entry_number+1, 1);
3200 + error = alloc_ldt(mm, ldt_info.entry_number+1, 1);
3204 @@ -233,23 +238,29 @@
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)
3216 - ret = read_ldt(ptr, bytecount);
3217 + ret = read_ldt(mm, ptr, bytecount);
3220 - ret = write_ldt(ptr, bytecount, 1);
3221 + ret = write_ldt(mm, ptr, bytecount, 1);
3224 ret = read_default_ldt(ptr, bytecount);
3227 - ret = write_ldt(ptr, bytecount, 0);
3228 + ret = write_ldt(mm, ptr, bytecount, 0);
3234 +asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
3236 + return __modify_ldt(current->mm, func, ptr, bytecount);
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
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)
3255 - down_write(¤t->mm->mmap_sem);
3256 - error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
3257 - up_write(¤t->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);
3265 unsigned long prot, unsigned long flags,
3266 unsigned long fd, unsigned long pgoff)
3268 - return do_mmap2(addr, len, prot, flags, fd, pgoff);
3269 + return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
3274 if (a.offset & ~PAGE_MASK)
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);
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
3288 GET_THREAD_INFO(%ebp)
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
3296 pushl %eax # save orig_eax
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
3309 call do_syscall_trace
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
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
3325 + bool "/proc/mm support"
3328 # Common NUMA Features
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
3336 #define HOSTFS_ATTR_CTIME 64
3337 #define HOSTFS_ATTR_ATIME_SET 128
3338 #define HOSTFS_ATTR_MTIME_SET 256
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
3344 +/* If you are very careful, you'll notice that these two are missing:
3346 + * #define ATTR_KILL_SUID 2048
3347 + * #define ATTR_KILL_SGID 4096
3349 + * and this is because they were added in 2.5 development in this patch:
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
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
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
3363 struct hostfs_iattr {
3364 unsigned int ia_valid;
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
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 @@
3382 + err = inode_change_ok(dentry->d_inode, attr);
3387 attr->ia_valid &= ~ATTR_SIZE;
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
3396 clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE);
3397 +#ifdef TIF_SYSCALL_EMU
3398 + clear_tsk_thread_flag(p, TIF_SYSCALL_EMU);
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
3408 #define PTRACE_DETACH 0x11
3410 #define PTRACE_SYSCALL 24
3411 +#define PTRACE_SYSEMU 31
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
3420 extern struct shrinker *set_shrinker(int, shrinker_t);
3421 extern void remove_shrinker(struct shrinker *shrinker);
3423 +extern long do_mprotect(struct mm_struct *mm, unsigned long start,
3424 + size_t len, unsigned long prot);
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 @@
3431 extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
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);
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
3453 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3454 + * Licensed under the GPL
3457 +#ifndef __PROC_MM_H
3458 +#define __PROC_MM_H
3460 +#include "linux/sched.h"
3463 +#define MM_MUNMAP 55
3464 +#define MM_MPROTECT 56
3465 +#define MM_COPY_SEGMENTS 57
3468 + unsigned long addr;
3469 + unsigned long len;
3470 + unsigned long prot;
3471 + unsigned long flags;
3473 + unsigned long offset;
3477 + unsigned long addr;
3478 + unsigned long len;
3481 +struct mm_mprotect {
3482 + unsigned long addr;
3483 + unsigned long len;
3484 + unsigned int prot;
3487 +struct proc_mm_op {
3490 + struct mm_mmap mmap;
3491 + struct mm_munmap munmap;
3492 + struct mm_mprotect mprotect;
3493 + int copy_segments;
3497 +extern struct mm_struct *proc_mm_get_mm(int fd);
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
3506 #include "asm/archparam.h"
3508 -#define ELF_HWCAP (0)
3509 +extern long elf_aux_hwcap;
3510 +#define ELF_HWCAP (elf_aux_hwcap)
3512 #define SET_PERSONALITY(ex, ibcs2) do ; while(0)
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
3522 -#define ELF_PLATFORM "i586"
3523 +extern char * elf_aux_platform;
3524 +#define ELF_PLATFORM (elf_aux_platform)
3526 #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
3529 pr_reg[16] = PT_REGS_SS(regs); \
3532 -#if 0 /* Turn this back on when UML has VSYSCALL working */
3533 -#define VSYSCALL_BASE (__fix_to_virt(FIX_VSYSCALL))
3535 -#define VSYSCALL_BASE 0
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;
3545 +#define VSYSCALL_BASE vsyscall_ehdr
3546 +#define VSYSCALL_END vsyscall_end
3549 * Architecture-neutral AT_ values in 0-17, leave some room
3552 #define ARCH_DLINFO \
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); \
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.
3568 -#define ELF_CORE_EXTRA_PHDRS (VSYSCALL_EHDR->e_phnum)
3571 -#undef ELF_CORE_EXTRA_PHDRS
3572 +#define ELF_CORE_EXTRA_PHDRS \
3573 + (vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0 )
3576 #define ELF_CORE_WRITE_EXTRA_PHDRS \
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); \
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)); \
3600 #define ELF_CORE_WRITE_EXTRA_DATA \
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); \
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); \
3622 -#undef ELF_CORE_WRITE_EXTRA_PHDRS
3623 -#undef ELF_CORE_WRITE_EXTRA_DATA
3626 #define R_386_NONE 0
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
3634 #include <linux/config.h>
3635 #include <asm/kmap_types.h>
3636 +#include <asm/archparam.h>
3639 * Here we define all the compile-time 'special' virtual
3641 FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
3642 FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
3645 __end_of_fixed_addresses
3649 * This is the range that is readable by user mode, and things
3650 * acting like user mode such as get_user_pages.
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
3657 extern void __this_fixmap_does_not_exist(void);
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
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 */
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)
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 */
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
3695 +/*For SKAS3 support.*/
3696 +#ifndef _LINUX_PTRACE_STRUCT_DEF
3697 +#define _LINUX_PTRACE_STRUCT_DEF
3699 +#define PTRACE_FAULTINFO 52
3700 +#define PTRACE_SIGPENDING 53
3701 +#define PTRACE_LDT 54
3702 +#define PTRACE_SWITCH_MM 55
3704 +struct ptrace_faultinfo {
3706 + unsigned long addr;
3709 +struct ptrace_ldt {
3712 + unsigned long bytecount;
3715 +#endif /*ifndef _LINUX_PTRACE_STRUCT_DEF*/
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
3723 #include <asm/atomic.h>
3724 #include <asm/pgalloc.h>
3725 #include <asm/tlbflush.h>
3726 +#include <asm/semaphore.h>
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.
3734 int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
3735 void destroy_context(struct mm_struct *mm);
3737 +/* LDT initialization for a clean environment - needed for SKAS.*/
3738 +static inline void init_new_empty_context(struct mm_struct *mm)
3740 + init_MUTEX(&mm->context.sem);
3741 + mm->context.size = 0;
3744 +/* LDT copy for SKAS - for the above problem.*/
3745 +int copy_context(struct mm_struct *mm, struct mm_struct *old_mm);
3747 static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
3751 int cpu = smp_processor_id();
3754 + prev = per_cpu(cpu_tlbstate, cpu).active_mm;
3757 if (likely(prev != next)) {
3758 /* stop flush ipis for the previous mm */
3759 cpu_clear(cpu, prev->cpu_vm_mask);
3763 per_cpu(cpu_tlbstate, cpu).state = TLBSTATE_OK;
3764 - BUG_ON(per_cpu(cpu_tlbstate, cpu).active_mm != next);
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
3776 +extern int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
3777 + unsigned long bytecount);
3779 #endif /* !__ASSEMBLY__ */