diff options
| -rw-r--r-- | console.c | 5 | ||||
| -rw-r--r-- | defs.h | 6 | ||||
| -rw-r--r-- | exec.c | 16 | ||||
| -rw-r--r-- | fs.c | 11 | ||||
| -rw-r--r-- | ide.c | 3 | ||||
| -rw-r--r-- | lapic.c | 25 | ||||
| -rw-r--r-- | main.c | 9 | ||||
| -rw-r--r-- | mmu.h | 9 | ||||
| -rw-r--r-- | pipe.c | 4 | ||||
| -rw-r--r-- | proc.c | 133 | ||||
| -rw-r--r-- | proc.h | 16 | ||||
| -rw-r--r-- | sleeplock.c | 2 | ||||
| -rw-r--r-- | spinlock.c | 14 | ||||
| -rw-r--r-- | syscall.c | 28 | ||||
| -rw-r--r-- | sysfile.c | 18 | ||||
| -rw-r--r-- | sysproc.c | 6 | ||||
| -rw-r--r-- | trap.c | 24 | ||||
| -rw-r--r-- | trapasm.S | 3 | ||||
| -rw-r--r-- | vm.c | 21 | 
19 files changed, 181 insertions, 172 deletions
| @@ -111,7 +111,8 @@ panic(char *s)    cli();    cons.locking = 0; -  cprintf("cpu with apicid %d: panic: ", cpu->apicid); +  // use lapiccpunum so that we can call panic from mycpu() +  cprintf("lapicid %d: panic: ", lapicid());    cprintf(s);    cprintf("\n");    getcallerpcs(&s, pcs); @@ -242,7 +243,7 @@ consoleread(struct inode *ip, char *dst, int n)    acquire(&cons.lock);    while(n > 0){      while(input.r == input.w){ -      if(proc->killed){ +      if(myproc()->killed){          release(&cons.lock);          ilock(ip);          return -1; @@ -74,7 +74,7 @@ void            kbdintr(void);  // lapic.c  void            cmostime(struct rtcdate *r); -int             cpunum(void); +int             lapicid(void);  extern volatile uint*    lapic;  void            lapiceoi(void);  void            lapicinit(void); @@ -103,14 +103,18 @@ int             pipewrite(struct pipe*, char*, int);  //PAGEBREAK: 16  // proc.c +int             cpuid(void);  void            exit(void);  int             fork(void);  int             growproc(int);  int             kill(int); +struct cpu*     mycpu(void); +struct proc*    myproc();  void            pinit(void);  void            procdump(void);  void            scheduler(void) __attribute__((noreturn));  void            sched(void); +void            setproc(struct proc*);  void            sleep(void*, struct spinlock*);  void            userinit(void);  int             wait(void); @@ -17,11 +17,13 @@ exec(char *path, char **argv)    struct inode *ip;    struct proghdr ph;    pde_t *pgdir, *oldpgdir; +  struct proc *curproc = myproc();    begin_op();    if((ip = namei(path)) == 0){      end_op(); +    cprintf("exec: fail\n");      return -1;    }    ilock(ip); @@ -89,15 +91,15 @@ exec(char *path, char **argv)    for(last=s=path; *s; s++)      if(*s == '/')        last = s+1; -  safestrcpy(proc->name, last, sizeof(proc->name)); +  safestrcpy(curproc->name, last, sizeof(curproc->name));    // Commit to the user image. -  oldpgdir = proc->pgdir; -  proc->pgdir = pgdir; -  proc->sz = sz; -  proc->tf->eip = elf.entry;  // main -  proc->tf->esp = sp; -  switchuvm(proc); +  oldpgdir = curproc->pgdir; +  curproc->pgdir = pgdir; +  curproc->sz = sz; +  curproc->tf->eip = elf.entry;  // main +  curproc->tf->esp = sp; +  switchuvm(curproc);    freevm(oldpgdir);    return 0; @@ -169,7 +169,7 @@ iinit(int dev)    for(i = 0; i < NINODE; i++) {      initsleeplock(&icache.inode[i].lock, "inode");    } -   +    readsb(dev, &sb);    cprintf("sb: size %d nblocks %d ninodes %d nlog %d logstart %d\   inodestart %d bmap start %d\n", sb.size, sb.nblocks, @@ -451,13 +451,6 @@ readi(struct inode *ip, char *dst, uint off, uint n)    for(tot=0; tot<n; tot+=m, off+=m, dst+=m){      bp = bread(ip->dev, bmap(ip, off/BSIZE));      m = min(n - tot, BSIZE - off%BSIZE); -    /* -    cprintf("data off %d:\n", off); -    for (int j = 0; j < min(m, 10); j++) { -      cprintf("%x ", bp->data[off%BSIZE+j]); -    } -    cprintf("\n"); -    */      memmove(dst, bp->data + off%BSIZE, m);      brelse(bp);    } @@ -617,7 +610,7 @@ namex(char *path, int nameiparent, char *name)    if(*path == '/')      ip = iget(ROOTDEV, ROOTINO);    else -    ip = idup(proc->cwd); +    ip = idup(myproc()->cwd);    while((path = skipelem(path, name)) != 0){      ilock(ip); @@ -108,9 +108,9 @@ ideintr(void)    // First queued buffer is the active request.    acquire(&idelock); +    if((b = idequeue) == 0){      release(&idelock); -    // cprintf("spurious IDE interrupt\n");      return;    }    idequeue = b->qnext; @@ -164,5 +164,6 @@ iderw(struct buf *b)      sleep(b, &idelock);    } +    release(&idelock);  } @@ -9,7 +9,6 @@  #include "traps.h"  #include "mmu.h"  #include "x86.h" -#include "proc.h"  // ncpu  // Local APIC registers, divided by 4 for use as uint[] indices.  #define ID      (0x0020/4)   // ID @@ -99,31 +98,11 @@ lapicinit(void)  }  int -cpunum(void) +lapicid(void)  { -  int apicid, i; -   -  // Cannot call cpu when interrupts are enabled: -  // result not guaranteed to last long enough to be used! -  // Would prefer to panic but even printing is chancy here: -  // almost everything, including cprintf and panic, calls cpu, -  // often indirectly through acquire and release. -  if(readeflags()&FL_IF){ -    static int n; -    if(n++ == 0) -      cprintf("cpu called from %x with interrupts enabled\n", -        __builtin_return_address(0)); -  } -    if (!lapic)      return 0; - -  apicid = lapic[ID] >> 24; -  for (i = 0; i < ncpu; ++i) { -    if (cpus[i].apicid == apicid) -      return i; -  } -  panic("unknown apicid\n"); +  return lapic[ID] >> 24;  }  // Acknowledge interrupt. @@ -22,7 +22,6 @@ main(void)    mpinit();        // detect other processors    lapicinit();     // interrupt controller    seginit();       // segment descriptors -  cprintf("\ncpu%d: starting xv6\n\n", cpunum());    picinit();       // another interrupt controller    ioapicinit();    // another interrupt controller    consoleinit();   // console hardware @@ -31,7 +30,7 @@ main(void)    tvinit();        // trap vectors    binit();         // buffer cache    fileinit();      // file table -  ideinit();       // disk +  ideinit();       // disk     if(!ismp)      timerinit();   // uniprocessor timer    startothers();   // start other processors @@ -54,9 +53,9 @@ mpenter(void)  static void  mpmain(void)  { -  cprintf("cpu%d: starting\n", cpunum()); +  cprintf("cpu%d: starting %d\n", cpuid(), cpuid());    idtinit();       // load idt register -  xchg(&cpu->started, 1); // tell startothers() we're up +  xchg(&(mycpu()->started), 1); // tell startothers() we're up    scheduler();     // start running processes  } @@ -78,7 +77,7 @@ startothers(void)    memmove(code, _binary_entryother_start, (uint)_binary_entryother_size);    for(c = cpus; c < cpus+ncpu; c++){ -    if(c == cpus+cpunum())  // We've started already. +    if(c == mycpu())  // We've started already.        continue;      // Tell entryother.S what stack to use, where to enter, and what @@ -42,13 +42,12 @@  // various segment selectors.  #define SEG_KCODE 1  // kernel code  #define SEG_KDATA 2  // kernel data+stack -#define SEG_KCPU  3  // kernel per-cpu data -#define SEG_UCODE 4  // user code -#define SEG_UDATA 5  // user data+stack -#define SEG_TSS   6  // this process's task state +#define SEG_UCODE 3  // user code +#define SEG_UDATA 4  // user data+stack +#define SEG_TSS   5  // this process's task state  // cpu->gdt[NSEGS] holds the above segments. -#define NSEGS     7 +#define NSEGS     6  //PAGEBREAK!  #ifndef __ASSEMBLER__ @@ -83,7 +83,7 @@ pipewrite(struct pipe *p, char *addr, int n)    acquire(&p->lock);    for(i = 0; i < n; i++){      while(p->nwrite == p->nread + PIPESIZE){  //DOC: pipewrite-full -      if(p->readopen == 0 || proc->killed){ +      if(p->readopen == 0 || myproc()->killed){          release(&p->lock);          return -1;        } @@ -104,7 +104,7 @@ piperead(struct pipe *p, char *addr, int n)    acquire(&p->lock);    while(p->nread == p->nwrite && p->writeopen){  //DOC: pipe-empty -    if(proc->killed){ +    if(myproc()->killed){        release(&p->lock);        return -1;      } @@ -26,6 +26,45 @@ pinit(void)    initlock(&ptable.lock, "ptable");  } +// Must be called with interrupts disabled +int +cpuid() { +  return mycpu()-cpus; +} + +// Must be called with interrupts disabled to avoid the caller being rescheduled +// between reading lapicid and running through the loop. +struct cpu* +mycpu(void) +{ +  int apicid, i; +   +  if(readeflags()&FL_IF) +    panic("mycpu called with interrupts enabled\n"); +   +  apicid = lapicid(); +  // APIC IDs are not guaranteed to be contiguous. Maybe we should have +  // a reverse map, or reserve a register to store &cpus[i]. +  for (i = 0; i < ncpu; ++i) { +    if (cpus[i].apicid == apicid) +      return &cpus[i]; +  } +  panic("unknown apicid\n"); +} + +// Disable interrupts so that we are not rescheduled +// while reading proc from the cpu structure +struct proc* +myproc(void) { +  struct cpu *c; +  struct proc *p; +  pushcli(); +  c = mycpu(); +  p = c->proc; +  popcli(); +  return p; +} +  //PAGEBREAK: 32  // Look in the process table for an UNUSED proc.  // If found, change state to EMBRYO and initialize @@ -120,17 +159,18 @@ int  growproc(int n)  {    uint sz; +  struct proc *curproc = myproc(); -  sz = proc->sz; +  sz = curproc->sz;    if(n > 0){ -    if((sz = allocuvm(proc->pgdir, sz, sz + n)) == 0) +    if((sz = allocuvm(curproc->pgdir, sz, sz + n)) == 0)        return -1;    } else if(n < 0){ -    if((sz = deallocuvm(proc->pgdir, sz, sz + n)) == 0) +    if((sz = deallocuvm(curproc->pgdir, sz, sz + n)) == 0)        return -1;    } -  proc->sz = sz; -  switchuvm(proc); +  curproc->sz = sz; +  switchuvm(curproc);    return 0;  } @@ -142,32 +182,33 @@ fork(void)  {    int i, pid;    struct proc *np; +  struct proc *curproc = myproc();    // Allocate process.    if((np = allocproc()) == 0){      return -1;    } -  // Copy process state from p. -  if((np->pgdir = copyuvm(proc->pgdir, proc->sz)) == 0){ +  // Copy process state from proc. +  if((np->pgdir = copyuvm(curproc->pgdir, curproc->sz)) == 0){      kfree(np->kstack);      np->kstack = 0;      np->state = UNUSED;      return -1;    } -  np->sz = proc->sz; -  np->parent = proc; -  *np->tf = *proc->tf; +  np->sz = curproc->sz; +  np->parent = curproc; +  *np->tf = *curproc->tf;    // Clear %eax so that fork returns 0 in the child.    np->tf->eax = 0;    for(i = 0; i < NOFILE; i++) -    if(proc->ofile[i]) -      np->ofile[i] = filedup(proc->ofile[i]); -  np->cwd = idup(proc->cwd); +    if(curproc->ofile[i]) +      np->ofile[i] = filedup(curproc->ofile[i]); +  np->cwd = idup(curproc->cwd); -  safestrcpy(np->name, proc->name, sizeof(proc->name)); +  safestrcpy(np->name, curproc->name, sizeof(curproc->name));    pid = np->pid; @@ -186,33 +227,34 @@ fork(void)  void  exit(void)  { +  struct proc *curproc = myproc();    struct proc *p;    int fd; -  if(proc == initproc) +  if(curproc == initproc)      panic("init exiting");    // Close all open files.    for(fd = 0; fd < NOFILE; fd++){ -    if(proc->ofile[fd]){ -      fileclose(proc->ofile[fd]); -      proc->ofile[fd] = 0; +    if(curproc->ofile[fd]){ +      fileclose(curproc->ofile[fd]); +      curproc->ofile[fd] = 0;      }    }    begin_op(); -  iput(proc->cwd); +  iput(curproc->cwd);    end_op(); -  proc->cwd = 0; +  curproc->cwd = 0;    acquire(&ptable.lock);    // Parent might be sleeping in wait(). -  wakeup1(proc->parent); +  wakeup1(curproc->parent);    // Pass abandoned children to init.    for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ -    if(p->parent == proc){ +    if(p->parent == curproc){        p->parent = initproc;        if(p->state == ZOMBIE)          wakeup1(initproc); @@ -220,7 +262,7 @@ exit(void)    }    // Jump into the scheduler, never to return. -  proc->state = ZOMBIE; +  curproc->state = ZOMBIE;    sched();    panic("zombie exit");  } @@ -232,13 +274,14 @@ wait(void)  {    struct proc *p;    int havekids, pid; - +  struct proc *curproc = myproc(); +      acquire(&ptable.lock);    for(;;){      // Scan through table looking for exited children.      havekids = 0;      for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ -      if(p->parent != proc) +      if(p->parent != curproc)          continue;        havekids = 1;        if(p->state == ZOMBIE){ @@ -258,13 +301,13 @@ wait(void)      }      // No point waiting if we don't have any children. -    if(!havekids || proc->killed){ +    if(!havekids || curproc->killed){        release(&ptable.lock);        return -1;      }      // Wait for children to exit.  (See wakeup1 call in proc_exit.) -    sleep(proc, &ptable.lock);  //DOC: wait-sleep +    sleep(curproc, &ptable.lock);  //DOC: wait-sleep    }  } @@ -280,7 +323,9 @@ void  scheduler(void)  {    struct proc *p; - +  struct cpu *c = mycpu(); +  c->proc = 0; +      for(;;){      // Enable interrupts on this processor.      sti(); @@ -294,15 +339,16 @@ scheduler(void)        // Switch to chosen process.  It is the process's job        // to release ptable.lock and then reacquire it        // before jumping back to us. -      proc = p; +      c->proc = p;        switchuvm(p);        p->state = RUNNING; -      swtch(&cpu->scheduler, p->context); + +      swtch(&(c->scheduler), p->context);        switchkvm();        // Process is done running for now.        // It should have changed its p->state before coming back. -      proc = 0; +      c->proc = 0;      }      release(&ptable.lock); @@ -320,18 +366,19 @@ void  sched(void)  {    int intena; +  struct proc *p = myproc();    if(!holding(&ptable.lock))      panic("sched ptable.lock"); -  if(cpu->ncli != 1) +  if(mycpu()->ncli != 1)      panic("sched locks"); -  if(proc->state == RUNNING) +  if(p->state == RUNNING)      panic("sched running");    if(readeflags()&FL_IF)      panic("sched interruptible"); -  intena = cpu->intena; -  swtch(&proc->context, cpu->scheduler); -  cpu->intena = intena; +  intena = mycpu()->intena; +  swtch(&p->context, mycpu()->scheduler); +  mycpu()->intena = intena;  }  // Give up the CPU for one scheduling round. @@ -339,7 +386,7 @@ void  yield(void)  {    acquire(&ptable.lock);  //DOC: yieldlock -  proc->state = RUNNABLE; +  myproc()->state = RUNNABLE;    sched();    release(&ptable.lock);  } @@ -370,7 +417,9 @@ forkret(void)  void  sleep(void *chan, struct spinlock *lk)  { -  if(proc == 0) +  struct proc *p = myproc(); +   +  if(p == 0)      panic("sleep");    if(lk == 0) @@ -386,14 +435,14 @@ sleep(void *chan, struct spinlock *lk)      acquire(&ptable.lock);  //DOC: sleeplock1      release(lk);    } -    // Go to sleep. -  proc->chan = chan; -  proc->state = SLEEPING; +  p->chan = chan; +  p->state = SLEEPING; +    sched();    // Tidy up. -  proc->chan = 0; +  p->chan = 0;    // Reacquire original lock.    if(lk != &ptable.lock){  //DOC: sleeplock2 @@ -7,26 +7,12 @@ struct cpu {    volatile uint started;       // Has the CPU started?    int ncli;                    // Depth of pushcli nesting.    int intena;                  // Were interrupts enabled before pushcli? - -  // Cpu-local storage variables; see below -  struct cpu *cpu; -  struct proc *proc;           // The currently-running process. +  struct proc *proc;           // The process running on this cpu or null  };  extern struct cpu cpus[NCPU];  extern int ncpu; -// Per-CPU variables, holding pointers to the -// current cpu and to the current process. -// The asm suffix tells gcc to use "%gs:0" to refer to cpu -// and "%gs:4" to refer to proc.  seginit sets up the -// %gs segment register so that %gs refers to the memory -// holding those two variables in the local cpu's struct cpu. -// This is similar to how thread-local variables are implemented -// in thread libraries such as Linux pthreads. -extern struct cpu *cpu asm("%gs:0");       // &cpus[cpunum()] -extern struct proc *proc asm("%gs:4");     // cpus[cpunum()].proc -  //PAGEBREAK: 17  // Saved registers for kernel context switches.  // Don't need to save all the segment registers (%cs, etc), diff --git a/sleeplock.c b/sleeplock.c index 2ded78d..d0e4d91 100644 --- a/sleeplock.c +++ b/sleeplock.c @@ -27,7 +27,7 @@ acquiresleep(struct sleeplock *lk)      sleep(lk, &lk->lk);    }    lk->locked = 1; -  lk->pid = proc->pid; +  lk->pid = myproc()->pid;    release(&lk->lk);  } @@ -38,7 +38,7 @@ acquire(struct spinlock *lk)    __sync_synchronize();    // Record info about lock acquisition for debugging. -  lk->cpu = cpu; +  lk->cpu = mycpu();    getcallerpcs(&lk, lk->pcs);  } @@ -89,7 +89,7 @@ getcallerpcs(void *v, uint pcs[])  int  holding(struct spinlock *lock)  { -  return lock->locked && lock->cpu == cpu; +  return lock->locked && lock->cpu == mycpu();  } @@ -104,9 +104,9 @@ pushcli(void)    eflags = readeflags();    cli(); -  if(cpu->ncli == 0) -    cpu->intena = eflags & FL_IF; -  cpu->ncli += 1; +  if(mycpu()->ncli == 0) +    mycpu()->intena = eflags & FL_IF; +  mycpu()->ncli += 1;  }  void @@ -114,9 +114,9 @@ popcli(void)  {    if(readeflags()&FL_IF)      panic("popcli - interruptible"); -  if(--cpu->ncli < 0) +  if(--mycpu()->ncli < 0)      panic("popcli"); -  if(cpu->ncli == 0 && cpu->intena) +  if(mycpu()->ncli == 0 && mycpu()->intena)      sti();  } @@ -17,7 +17,9 @@  int  fetchint(uint addr, int *ip)  { -  if(addr >= proc->sz || addr+4 > proc->sz) +  struct proc *curproc = myproc(); + +  if(addr >= curproc->sz || addr+4 > curproc->sz)      return -1;    *ip = *(int*)(addr);    return 0; @@ -30,14 +32,16 @@ int  fetchstr(uint addr, char **pp)  {    char *s, *ep; +  struct proc *curproc = myproc(); -  if(addr >= proc->sz) +  if(addr >= curproc->sz)      return -1;    *pp = (char*)addr; -  ep = (char*)proc->sz; -  for(s = *pp; s < ep; s++) +  ep = (char*)curproc->sz; +  for(s = *pp; s < ep; s++){      if(*s == 0)        return s - *pp; +  }    return -1;  } @@ -45,7 +49,7 @@ fetchstr(uint addr, char **pp)  int  argint(int n, int *ip)  { -  return fetchint(proc->tf->esp + 4 + 4*n, ip); +  return fetchint((myproc()->tf->esp) + 4 + 4*n, ip);  }  // Fetch the nth word-sized system call argument as a pointer @@ -55,10 +59,11 @@ int  argptr(int n, char **pp, int size)  {    int i; - +  struct proc *curproc = myproc(); +     if(argint(n, &i) < 0)      return -1; -  if(size < 0 || (uint)i >= proc->sz || (uint)i+size > proc->sz) +  if(size < 0 || (uint)i >= curproc->sz || (uint)i+size > curproc->sz)      return -1;    *pp = (char*)i;    return 0; @@ -127,13 +132,14 @@ void  syscall(void)  {    int num; +  struct proc *curproc = myproc(); -  num = proc->tf->eax; +  num = curproc->tf->eax;    if(num > 0 && num < NELEM(syscalls) && syscalls[num]) { -    proc->tf->eax = syscalls[num](); +    curproc->tf->eax = syscalls[num]();    } else {      cprintf("%d %s: unknown sys call %d\n", -            proc->pid, proc->name, num); -    proc->tf->eax = -1; +            curproc->pid, curproc->name, num); +    curproc->tf->eax = -1;    }  } @@ -26,7 +26,7 @@ argfd(int n, int *pfd, struct file **pf)    if(argint(n, &fd) < 0)      return -1; -  if(fd < 0 || fd >= NOFILE || (f=proc->ofile[fd]) == 0) +  if(fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0)      return -1;    if(pfd)      *pfd = fd; @@ -41,10 +41,11 @@ static int  fdalloc(struct file *f)  {    int fd; +  struct proc *curproc = myproc();    for(fd = 0; fd < NOFILE; fd++){ -    if(proc->ofile[fd] == 0){ -      proc->ofile[fd] = f; +    if(curproc->ofile[fd] == 0){ +      curproc->ofile[fd] = f;        return fd;      }    } @@ -97,7 +98,7 @@ sys_close(void)    if(argfd(0, &fd, &f) < 0)      return -1; -  proc->ofile[fd] = 0; +  myproc()->ofile[fd] = 0;    fileclose(f);    return 0;  } @@ -373,7 +374,8 @@ sys_chdir(void)  {    char *path;    struct inode *ip; - +  struct proc *curproc = myproc(); +      begin_op();    if(argstr(0, &path) < 0 || (ip = namei(path)) == 0){      end_op(); @@ -386,9 +388,9 @@ sys_chdir(void)      return -1;    }    iunlock(ip); -  iput(proc->cwd); +  iput(curproc->cwd);    end_op(); -  proc->cwd = ip; +  curproc->cwd = ip;    return 0;  } @@ -432,7 +434,7 @@ sys_pipe(void)    fd0 = -1;    if((fd0 = fdalloc(rf)) < 0 || (fd1 = fdalloc(wf)) < 0){      if(fd0 >= 0) -      proc->ofile[fd0] = 0; +      myproc()->ofile[fd0] = 0;      fileclose(rf);      fileclose(wf);      return -1; @@ -39,7 +39,7 @@ sys_kill(void)  int  sys_getpid(void)  { -  return proc->pid; +  return myproc()->pid;  }  int @@ -50,7 +50,7 @@ sys_sbrk(void)    if(argint(0, &n) < 0)      return -1; -  addr = proc->sz; +  addr = myproc()->sz;    if(growproc(n) < 0)      return -1;    return addr; @@ -67,7 +67,7 @@ sys_sleep(void)    acquire(&tickslock);    ticks0 = ticks;    while(ticks - ticks0 < n){ -    if(proc->killed){ +    if(myproc()->killed){        release(&tickslock);        return -1;      } @@ -37,18 +37,18 @@ void  trap(struct trapframe *tf)  {    if(tf->trapno == T_SYSCALL){ -    if(proc->killed) +    if(myproc()->killed)        exit(); -    proc->tf = tf; +    myproc()->tf = tf;      syscall(); -    if(proc->killed) +    if(myproc()->killed)        exit();      return;    }    switch(tf->trapno){    case T_IRQ0 + IRQ_TIMER: -    if(cpunum() == 0){ +    if(cpuid() == 0){        acquire(&tickslock);        ticks++;        wakeup(&ticks); @@ -74,38 +74,38 @@ trap(struct trapframe *tf)    case T_IRQ0 + 7:    case T_IRQ0 + IRQ_SPURIOUS:      cprintf("cpu%d: spurious interrupt at %x:%x\n", -            cpunum(), tf->cs, tf->eip); +            cpuid(), tf->cs, tf->eip);      lapiceoi();      break;    //PAGEBREAK: 13    default: -    if(proc == 0 || (tf->cs&3) == 0){ +    if(myproc() == 0 || (tf->cs&3) == 0){        // In kernel, it must be our mistake.        cprintf("unexpected trap %d from cpu %d eip %x (cr2=0x%x)\n", -              tf->trapno, cpunum(), tf->eip, rcr2()); +              tf->trapno, cpuid(), tf->eip, rcr2());        panic("trap");      }      // In user space, assume process misbehaved.      cprintf("pid %d %s: trap %d err %d on cpu %d "              "eip 0x%x addr 0x%x--kill proc\n", -            proc->pid, proc->name, tf->trapno, tf->err, cpunum(), tf->eip, +            myproc()->pid, myproc()->name, tf->trapno, tf->err, cpuid(), tf->eip,              rcr2()); -    proc->killed = 1; +    myproc()->killed = 1;    }    // Force process exit if it has been killed and is in user space.    // (If it is still executing in the kernel, let it keep running    // until it gets to the regular system call return.) -  if(proc && proc->killed && (tf->cs&3) == DPL_USER) +  if(myproc() && myproc()->killed && (tf->cs&3) == DPL_USER)      exit();    // Force process to give up CPU on clock tick.    // If interrupts were on while locks held, would need to check nlock. -  if(proc && proc->state == RUNNING && tf->trapno == T_IRQ0+IRQ_TIMER) +  if(myproc() && myproc()->state == RUNNING && tf->trapno == T_IRQ0+IRQ_TIMER)      yield();    // Check if the process has been killed since we yielded -  if(proc && proc->killed && (tf->cs&3) == DPL_USER) +  if(myproc() && myproc()->killed && (tf->cs&3) == DPL_USER)      exit();  } @@ -14,9 +14,6 @@ alltraps:    movw $(SEG_KDATA<<3), %ax    movw %ax, %ds    movw %ax, %es -  movw $(SEG_KCPU<<3), %ax -  movw %ax, %fs -  movw %ax, %gs    # Call trap(tf), where tf=%esp    pushl %esp @@ -21,21 +21,12 @@ seginit(void)    // Cannot share a CODE descriptor for both kernel and user    // because it would have to have DPL_USR, but the CPU forbids    // an interrupt from CPL=0 to DPL=3. -  c = &cpus[cpunum()]; +  c = &cpus[cpuid()];    c->gdt[SEG_KCODE] = SEG(STA_X|STA_R, 0, 0xffffffff, 0);    c->gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0);    c->gdt[SEG_UCODE] = SEG(STA_X|STA_R, 0, 0xffffffff, DPL_USER);    c->gdt[SEG_UDATA] = SEG(STA_W, 0, 0xffffffff, DPL_USER); - -  // Map cpu and proc -- these are private per cpu. -  c->gdt[SEG_KCPU] = SEG(STA_W, &c->cpu, 8, 0); -    lgdt(c->gdt, sizeof(c->gdt)); -  loadgs(SEG_KCPU << 3); - -  // Initialize cpu-local storage. -  cpu = c; -  proc = 0;  }  // Return the address of the PTE in page table pgdir @@ -173,13 +164,13 @@ switchuvm(struct proc *p)      panic("switchuvm: no pgdir");    pushcli(); -  cpu->gdt[SEG_TSS] = SEG16(STS_T32A, &cpu->ts, sizeof(cpu->ts)-1, 0); -  cpu->gdt[SEG_TSS].s = 0; -  cpu->ts.ss0 = SEG_KDATA << 3; -  cpu->ts.esp0 = (uint)p->kstack + KSTACKSIZE; +  mycpu()->gdt[SEG_TSS] = SEG16(STS_T32A, &mycpu()->ts, sizeof(mycpu()->ts)-1, 0); +  mycpu()->gdt[SEG_TSS].s = 0; +  mycpu()->ts.ss0 = SEG_KDATA << 3; +  mycpu()->ts.esp0 = (uint)p->kstack + KSTACKSIZE;    // setting IOPL=0 in eflags *and* iomb beyond the tss segment limit    // forbids I/O instructions (e.g., inb and outb) from user space -  cpu->ts.iomb = (ushort) 0xFFFF; +  mycpu()->ts.iomb = (ushort) 0xFFFF;    ltr(SEG_TSS << 3);    lcr3(V2P(p->pgdir));  // switch to process's address space    popcli(); | 
