Annotation of linux/kernel/fork.c, revision 1.1.1.10

1.1       root        1: /*
1.1.1.2   root        2:  *  linux/kernel/fork.c
                      3:  *
1.1.1.10! root        4:  *  Copyright (C) 1991, 1992  Linus Torvalds
1.1.1.2   root        5:  */
                      6: 
                      7: /*
1.1       root        8:  *  'fork.c' contains the help-routines for the 'fork' system call
                      9:  * (see also system_call.s), and some misc functions ('verify_area').
                     10:  * Fork is rather simple, once you get the hang of it, but the memory
                     11:  * management can be a bitch. See 'mm/mm.c': 'copy_page_tables()'
                     12:  */
                     13: 
1.1.1.10! root       14: #include <linux/errno.h>
1.1       root       15: #include <linux/sched.h>
                     16: #include <linux/kernel.h>
1.1.1.9   root       17: #include <linux/mm.h>
1.1.1.10! root       18: #include <linux/stddef.h>
        !            19: 
1.1       root       20: #include <asm/segment.h>
                     21: #include <asm/system.h>
                     22: 
1.1.1.10! root       23: #define MAX_TASKS_PER_USER ((NR_TASKS/4)*3)
        !            24: 
1.1       root       25: long last_pid=0;
                     26: 
                     27: void verify_area(void * addr,int size)
                     28: {
                     29:        unsigned long start;
                     30: 
                     31:        start = (unsigned long) addr;
                     32:        size += start & 0xfff;
                     33:        start &= 0xfffff000;
                     34:        start += get_base(current->ldt[2]);
                     35:        while (size>0) {
                     36:                size -= 4096;
                     37:                write_verify(start);
                     38:                start += 4096;
                     39:        }
                     40: }
                     41: 
                     42: int copy_mem(int nr,struct task_struct * p)
                     43: {
                     44:        unsigned long old_data_base,new_data_base,data_limit;
                     45:        unsigned long old_code_base,new_code_base,code_limit;
                     46: 
1.1.1.10! root       47:        code_limit = get_limit(0x0f);
        !            48:        data_limit = get_limit(0x17);
1.1       root       49:        old_code_base = get_base(current->ldt[1]);
                     50:        old_data_base = get_base(current->ldt[2]);
1.1.1.5   root       51:        if (old_data_base != old_code_base) {
                     52:                printk("ldt[0]: %08x %08x\n",current->ldt[0].a,current->ldt[0].b);
                     53:                printk("ldt[1]: %08x %08x\n",current->ldt[1].a,current->ldt[1].b);
                     54:                printk("ldt[2]: %08x %08x\n",current->ldt[2].a,current->ldt[2].b);
1.1       root       55:                panic("We don't support separate I&D");
1.1.1.5   root       56:        }
1.1       root       57:        if (data_limit < code_limit)
                     58:                panic("Bad data_limit");
1.1.1.4   root       59:        new_data_base = new_code_base = nr * TASK_SIZE;
1.1.1.3   root       60:        p->start_code = new_code_base;
1.1       root       61:        set_base(p->ldt[1],new_code_base);
                     62:        set_base(p->ldt[2],new_data_base);
                     63:        if (copy_page_tables(old_data_base,new_data_base,data_limit)) {
                     64:                free_page_tables(new_data_base,data_limit);
                     65:                return -ENOMEM;
                     66:        }
                     67:        return 0;
                     68: }
                     69: 
1.1.1.5   root       70: static int find_empty_process(void)
                     71: {
1.1.1.10! root       72:        int i, task_nr;
        !            73:        int this_user_tasks = 0;
1.1.1.5   root       74: 
1.1.1.10! root       75: repeat:
        !            76:        if ((++last_pid) & 0xffff0000)
        !            77:                last_pid=1;
        !            78:        for(i=0 ; i < NR_TASKS ; i++) {
        !            79:                if (!task[i])
        !            80:                        continue;
        !            81:                if (task[i]->uid == current->uid)
        !            82:                        this_user_tasks++;
        !            83:                if (task[i]->pid == last_pid || task[i]->pgrp == last_pid)
        !            84:                        goto repeat;
        !            85:        }
        !            86:        if (this_user_tasks > MAX_TASKS_PER_USER && !suser())
        !            87:                return -EAGAIN;
        !            88: /* Only the super-user can fill the last available slot */
        !            89:        task_nr = 0;
1.1.1.5   root       90:        for(i=1 ; i<NR_TASKS ; i++)
                     91:                if (!task[i])
1.1.1.10! root       92:                        if (task_nr)
        !            93:                                return task_nr;
        !            94:                        else
        !            95:                                task_nr = i;
        !            96:        if (task_nr && suser())
        !            97:                return task_nr;
1.1.1.5   root       98:        return -EAGAIN;
                     99: }
                    100: 
1.1       root      101: /*
                    102:  *  Ok, this is the main fork-routine. It copies the system process
                    103:  * information (task[nr]) and sets up the necessary registers. It
                    104:  * also copies the data segment in it's entirety.
                    105:  */
1.1.1.5   root      106: int sys_fork(long ebx,long ecx,long edx,
                    107:                long esi, long edi, long ebp, long eax, long ds,
                    108:                long es, long fs, long gs, long orig_eax,
1.1       root      109:                long eip,long cs,long eflags,long esp,long ss)
                    110: {
                    111:        struct task_struct *p;
1.1.1.5   root      112:        int i,nr;
1.1       root      113:        struct file *f;
                    114: 
1.1.1.10! root      115:        p = (struct task_struct *) get_free_page(GFP_KERNEL);
1.1       root      116:        if (!p)
                    117:                return -EAGAIN;
1.1.1.5   root      118:        nr = find_empty_process();
                    119:        if (nr < 0) {
                    120:                free_page((unsigned long) p);
                    121:                return nr;
                    122:        }
1.1.1.3   root      123:        task[nr] = p;
1.1       root      124:        *p = *current;  /* NOTE! this doesn't copy the supervisor stack */
1.1.1.10! root      125:        p->wait.task = p;
        !           126:        p->wait.next = NULL;
1.1.1.3   root      127:        p->state = TASK_UNINTERRUPTIBLE;
1.1.1.8   root      128:        p->flags &= ~PF_PTRACED;
1.1       root      129:        p->pid = last_pid;
1.1.1.10! root      130:        if (p->pid > 1)
        !           131:                p->swappable = 1;
1.1.1.8   root      132:        p->p_pptr = p->p_opptr = current;
1.1.1.7   root      133:        p->p_cptr = NULL;
1.1.1.8   root      134:        SET_LINKS(p);
1.1       root      135:        p->counter = p->priority;
                    136:        p->signal = 0;
1.1.1.8   root      137:        p->it_real_value = p->it_virt_value = p->it_prof_value = 0;
                    138:        p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0;
1.1       root      139:        p->leader = 0;          /* process leadership doesn't inherit */
                    140:        p->utime = p->stime = 0;
                    141:        p->cutime = p->cstime = 0;
1.1.1.6   root      142:        p->min_flt = p->maj_flt = 0;
                    143:        p->cmin_flt = p->cmaj_flt = 0;
1.1       root      144:        p->start_time = jiffies;
                    145:        p->tss.back_link = 0;
                    146:        p->tss.esp0 = PAGE_SIZE + (long) p;
                    147:        p->tss.ss0 = 0x10;
                    148:        p->tss.eip = eip;
1.1.1.10! root      149:        p->tss.eflags = eflags & 0xffffcfff;    /* iopl is always 0 for a new process */
1.1       root      150:        p->tss.eax = 0;
                    151:        p->tss.ecx = ecx;
                    152:        p->tss.edx = edx;
                    153:        p->tss.ebx = ebx;
                    154:        p->tss.esp = esp;
                    155:        p->tss.ebp = ebp;
                    156:        p->tss.esi = esi;
                    157:        p->tss.edi = edi;
                    158:        p->tss.es = es & 0xffff;
                    159:        p->tss.cs = cs & 0xffff;
                    160:        p->tss.ss = ss & 0xffff;
                    161:        p->tss.ds = ds & 0xffff;
                    162:        p->tss.fs = fs & 0xffff;
                    163:        p->tss.gs = gs & 0xffff;
                    164:        p->tss.ldt = _LDT(nr);
1.1.1.7   root      165:        p->tss.trace_bitmap = offsetof(struct tss_struct,io_bitmap) << 16;
                    166:        for (i = 0; i<IO_BITMAP_SIZE ; i++)
                    167:                p->tss.io_bitmap[i] = ~0;
1.1       root      168:        if (last_task_used_math == current)
1.1.1.4   root      169:                __asm__("clts ; fnsave %0 ; frstor %0"::"m" (p->tss.i387));
1.1       root      170:        if (copy_mem(nr,p)) {
1.1.1.3   root      171:                task[nr] = NULL;
1.1.1.8   root      172:                REMOVE_LINKS(p);
1.1       root      173:                free_page((long) p);
                    174:                return -EAGAIN;
                    175:        }
                    176:        for (i=0; i<NR_OPEN;i++)
                    177:                if (f=p->filp[i])
                    178:                        f->f_count++;
                    179:        if (current->pwd)
                    180:                current->pwd->i_count++;
                    181:        if (current->root)
                    182:                current->root->i_count++;
1.1.1.3   root      183:        if (current->executable)
                    184:                current->executable->i_count++;
1.1.1.7   root      185:        for (i=0; i < current->numlibraries ; i++)
                    186:                if (current->libraries[i].library)
                    187:                        current->libraries[i].library->i_count++;
1.1       root      188:        set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY,&(p->tss));
                    189:        set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,&(p->ldt));
1.1.1.3   root      190:        p->state = TASK_RUNNING;        /* do this last, just in case */
1.1.1.5   root      191:        return p->pid;
1.1       root      192: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.