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

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.11! root       59:        new_data_base = old_data_base;
        !            60:        new_code_base = old_code_base;
1.1.1.3   root       61:        p->start_code = new_code_base;
1.1       root       62:        set_base(p->ldt[1],new_code_base);
                     63:        set_base(p->ldt[2],new_data_base);
1.1.1.11! root       64:        return copy_page_tables(p);
1.1       root       65: }
                     66: 
1.1.1.5   root       67: static int find_empty_process(void)
                     68: {
1.1.1.10  root       69:        int i, task_nr;
                     70:        int this_user_tasks = 0;
1.1.1.5   root       71: 
1.1.1.10  root       72: repeat:
                     73:        if ((++last_pid) & 0xffff0000)
                     74:                last_pid=1;
                     75:        for(i=0 ; i < NR_TASKS ; i++) {
                     76:                if (!task[i])
                     77:                        continue;
                     78:                if (task[i]->uid == current->uid)
                     79:                        this_user_tasks++;
                     80:                if (task[i]->pid == last_pid || task[i]->pgrp == last_pid)
                     81:                        goto repeat;
                     82:        }
                     83:        if (this_user_tasks > MAX_TASKS_PER_USER && !suser())
                     84:                return -EAGAIN;
                     85: /* Only the super-user can fill the last available slot */
                     86:        task_nr = 0;
1.1.1.5   root       87:        for(i=1 ; i<NR_TASKS ; i++)
                     88:                if (!task[i])
1.1.1.10  root       89:                        if (task_nr)
                     90:                                return task_nr;
                     91:                        else
                     92:                                task_nr = i;
                     93:        if (task_nr && suser())
                     94:                return task_nr;
1.1.1.5   root       95:        return -EAGAIN;
                     96: }
                     97: 
1.1       root       98: /*
                     99:  *  Ok, this is the main fork-routine. It copies the system process
                    100:  * information (task[nr]) and sets up the necessary registers. It
                    101:  * also copies the data segment in it's entirety.
                    102:  */
1.1.1.5   root      103: int sys_fork(long ebx,long ecx,long edx,
                    104:                long esi, long edi, long ebp, long eax, long ds,
                    105:                long es, long fs, long gs, long orig_eax,
1.1       root      106:                long eip,long cs,long eflags,long esp,long ss)
                    107: {
                    108:        struct task_struct *p;
1.1.1.5   root      109:        int i,nr;
1.1       root      110:        struct file *f;
                    111: 
1.1.1.10  root      112:        p = (struct task_struct *) get_free_page(GFP_KERNEL);
1.1       root      113:        if (!p)
                    114:                return -EAGAIN;
1.1.1.5   root      115:        nr = find_empty_process();
                    116:        if (nr < 0) {
                    117:                free_page((unsigned long) p);
                    118:                return nr;
                    119:        }
1.1.1.3   root      120:        task[nr] = p;
1.1       root      121:        *p = *current;  /* NOTE! this doesn't copy the supervisor stack */
1.1.1.10  root      122:        p->wait.task = p;
                    123:        p->wait.next = NULL;
1.1.1.3   root      124:        p->state = TASK_UNINTERRUPTIBLE;
1.1.1.8   root      125:        p->flags &= ~PF_PTRACED;
1.1       root      126:        p->pid = last_pid;
1.1.1.10  root      127:        if (p->pid > 1)
                    128:                p->swappable = 1;
1.1.1.8   root      129:        p->p_pptr = p->p_opptr = current;
1.1.1.7   root      130:        p->p_cptr = NULL;
1.1.1.8   root      131:        SET_LINKS(p);
1.1       root      132:        p->counter = p->priority;
                    133:        p->signal = 0;
1.1.1.8   root      134:        p->it_real_value = p->it_virt_value = p->it_prof_value = 0;
                    135:        p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0;
1.1       root      136:        p->leader = 0;          /* process leadership doesn't inherit */
                    137:        p->utime = p->stime = 0;
                    138:        p->cutime = p->cstime = 0;
1.1.1.6   root      139:        p->min_flt = p->maj_flt = 0;
                    140:        p->cmin_flt = p->cmaj_flt = 0;
1.1       root      141:        p->start_time = jiffies;
                    142:        p->tss.back_link = 0;
                    143:        p->tss.esp0 = PAGE_SIZE + (long) p;
                    144:        p->tss.ss0 = 0x10;
                    145:        p->tss.eip = eip;
1.1.1.10  root      146:        p->tss.eflags = eflags & 0xffffcfff;    /* iopl is always 0 for a new process */
1.1       root      147:        p->tss.eax = 0;
                    148:        p->tss.ecx = ecx;
                    149:        p->tss.edx = edx;
                    150:        p->tss.ebx = ebx;
                    151:        p->tss.esp = esp;
                    152:        p->tss.ebp = ebp;
                    153:        p->tss.esi = esi;
                    154:        p->tss.edi = edi;
                    155:        p->tss.es = es & 0xffff;
                    156:        p->tss.cs = cs & 0xffff;
                    157:        p->tss.ss = ss & 0xffff;
                    158:        p->tss.ds = ds & 0xffff;
                    159:        p->tss.fs = fs & 0xffff;
                    160:        p->tss.gs = gs & 0xffff;
                    161:        p->tss.ldt = _LDT(nr);
1.1.1.7   root      162:        p->tss.trace_bitmap = offsetof(struct tss_struct,io_bitmap) << 16;
                    163:        for (i = 0; i<IO_BITMAP_SIZE ; i++)
                    164:                p->tss.io_bitmap[i] = ~0;
1.1       root      165:        if (last_task_used_math == current)
1.1.1.4   root      166:                __asm__("clts ; fnsave %0 ; frstor %0"::"m" (p->tss.i387));
1.1       root      167:        if (copy_mem(nr,p)) {
1.1.1.3   root      168:                task[nr] = NULL;
1.1.1.8   root      169:                REMOVE_LINKS(p);
1.1       root      170:                free_page((long) p);
                    171:                return -EAGAIN;
                    172:        }
                    173:        for (i=0; i<NR_OPEN;i++)
                    174:                if (f=p->filp[i])
                    175:                        f->f_count++;
                    176:        if (current->pwd)
                    177:                current->pwd->i_count++;
                    178:        if (current->root)
                    179:                current->root->i_count++;
1.1.1.3   root      180:        if (current->executable)
                    181:                current->executable->i_count++;
1.1.1.7   root      182:        for (i=0; i < current->numlibraries ; i++)
                    183:                if (current->libraries[i].library)
                    184:                        current->libraries[i].library->i_count++;
1.1       root      185:        set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY,&(p->tss));
                    186:        set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,&(p->ldt));
1.1.1.3   root      187:        p->state = TASK_RUNNING;        /* do this last, just in case */
1.1.1.5   root      188:        return p->pid;
1.1       root      189: }

unix.superglobalmegacorp.com

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