summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrans Kaashoek <[email protected]>2017-01-31 17:47:16 -0500
committerFrans Kaashoek <[email protected]>2017-01-31 17:47:16 -0500
commitabf847a083888bbed4260ecacf849ea19f23e810 (patch)
tree4ae9b3487bbfe27f6382486bf877917dbb8bc030
parent59cdd6c63b89395d64ec9550181af5ed569b8466 (diff)
downloadxv6-labs-abf847a083888bbed4260ecacf849ea19f23e810.tar.gz
xv6-labs-abf847a083888bbed4260ecacf849ea19f23e810.tar.bz2
xv6-labs-abf847a083888bbed4260ecacf849ea19f23e810.zip
Start of an experiment to remove the use of gs for cpu local variables.
-rw-r--r--console.c4
-rw-r--r--defs.h4
-rw-r--r--exec.c15
-rw-r--r--fs.c4
-rw-r--r--ide.c3
-rw-r--r--lapic.c6
-rw-r--r--main.c9
-rw-r--r--pipe.c4
-rw-r--r--proc.c89
-rw-r--r--proc.h27
-rw-r--r--sleeplock.c2
-rw-r--r--spinlock.c14
-rw-r--r--syscall.c21
-rw-r--r--sysfile.c14
-rw-r--r--sysproc.c6
-rw-r--r--trap.c24
-rw-r--r--vm.c22
17 files changed, 145 insertions, 123 deletions
diff --git a/console.c b/console.c
index 4d678b0..f7e1e73 100644
--- a/console.c
+++ b/console.c
@@ -111,7 +111,7 @@ panic(char *s)
cli();
cons.locking = 0;
- cprintf("cpu with apicid %d: panic: ", cpu->apicid);
+ cprintf("cpu %d: panic: ", cpuid());
cprintf(s);
cprintf("\n");
getcallerpcs(&s, pcs);
@@ -242,7 +242,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;
diff --git a/defs.h b/defs.h
index 300c75c..67ea9f6 100644
--- a/defs.h
+++ b/defs.h
@@ -74,7 +74,7 @@ void kbdintr(void);
// lapic.c
void cmostime(struct rtcdate *r);
-int cpunum(void);
+int lapiccpunum(void);
extern volatile uint* lapic;
void lapiceoi(void);
void lapicinit(void);
@@ -103,6 +103,7 @@ int pipewrite(struct pipe*, char*, int);
//PAGEBREAK: 16
// proc.c
+int cpuid(void);
void exit(void);
int fork(void);
int growproc(int);
@@ -111,6 +112,7 @@ 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);
diff --git a/exec.c b/exec.c
index 4d7d97c..14d673f 100644
--- a/exec.c
+++ b/exec.c
@@ -22,6 +22,7 @@ exec(char *path, char **argv)
if((ip = namei(path)) == 0){
end_op();
+ cprintf("exec: fail\n");
return -1;
}
ilock(ip);
@@ -89,15 +90,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(myproc()->name, last, sizeof(myproc()->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 = myproc()->pgdir;
+ myproc()->pgdir = pgdir;
+ myproc()->sz = sz;
+ myproc()->tf->eip = elf.entry; // main
+ myproc()->tf->esp = sp;
+ switchuvm(myproc());
freevm(oldpgdir);
return 0;
diff --git a/fs.c b/fs.c
index be8c5c5..2f0cf3b 100644
--- a/fs.c
+++ b/fs.c
@@ -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,
@@ -615,7 +615,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);
diff --git a/ide.c b/ide.c
index b3112b9..881fe0d 100644
--- a/ide.c
+++ b/ide.c
@@ -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);
}
diff --git a/lapic.c b/lapic.c
index 7507f97..9039665 100644
--- a/lapic.c
+++ b/lapic.c
@@ -99,11 +99,11 @@ lapicinit(void)
}
int
-cpunum(void)
+lapiccpunum(void)
{
int apicid, i;
- // Cannot call cpu when interrupts are enabled:
+ // Cannot call cpunum 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,
@@ -111,7 +111,7 @@ cpunum(void)
if(readeflags()&FL_IF){
static int n;
if(n++ == 0)
- cprintf("cpu called from %x with interrupts enabled\n",
+ cprintf("cpunum called from %x with interrupts enabled\n",
__builtin_return_address(0));
}
diff --git a/main.c b/main.c
index 731e429..d7e59cf 100644
--- a/main.c
+++ b/main.c
@@ -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(), lapiccpunum());
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
diff --git a/pipe.c b/pipe.c
index a9f471e..e9abe7f 100644
--- a/pipe.c
+++ b/pipe.c
@@ -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;
}
diff --git a/proc.c b/proc.c
index 7d03ad7..bd62e4b 100644
--- a/proc.c
+++ b/proc.c
@@ -26,6 +26,16 @@ pinit(void)
initlock(&ptable.lock, "ptable");
}
+int
+cpuid() {
+ return mycpu()-cpus;
+}
+
+void
+setproc(struct proc* p) {
+ mycpu()->proc = p;
+}
+
//PAGEBREAK: 32
// Look in the process table for an UNUSED proc.
// If found, change state to EMBRYO and initialize
@@ -121,16 +131,16 @@ growproc(int n)
{
uint sz;
- sz = proc->sz;
+ sz = myproc()->sz;
if(n > 0){
- if((sz = allocuvm(proc->pgdir, sz, sz + n)) == 0)
+ if((sz = allocuvm(myproc()->pgdir, sz, sz + n)) == 0)
return -1;
} else if(n < 0){
- if((sz = deallocuvm(proc->pgdir, sz, sz + n)) == 0)
+ if((sz = deallocuvm(myproc()->pgdir, sz, sz + n)) == 0)
return -1;
}
- proc->sz = sz;
- switchuvm(proc);
+ myproc()->sz = sz;
+ switchuvm(myproc());
return 0;
}
@@ -148,26 +158,26 @@ fork(void)
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(myproc()->pgdir, myproc()->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 = myproc()->sz;
+ np->parent = myproc();
+ *np->tf = *myproc()->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(myproc()->ofile[i])
+ np->ofile[i] = filedup(myproc()->ofile[i]);
+ np->cwd = idup(myproc()->cwd);
- safestrcpy(np->name, proc->name, sizeof(proc->name));
+ safestrcpy(np->name, myproc()->name, sizeof(myproc()->name));
pid = np->pid;
@@ -189,30 +199,30 @@ exit(void)
struct proc *p;
int fd;
- if(proc == initproc)
+ if(myproc() == 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(myproc()->ofile[fd]){
+ fileclose(myproc()->ofile[fd]);
+ myproc()->ofile[fd] = 0;
}
}
begin_op();
- iput(proc->cwd);
+ iput(myproc()->cwd);
end_op();
- proc->cwd = 0;
+ myproc()->cwd = 0;
acquire(&ptable.lock);
// Parent might be sleeping in wait().
- wakeup1(proc->parent);
+ wakeup1(myproc()->parent);
// Pass abandoned children to init.
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
- if(p->parent == proc){
+ if(p->parent == myproc()){
p->parent = initproc;
if(p->state == ZOMBIE)
wakeup1(initproc);
@@ -220,7 +230,7 @@ exit(void)
}
// Jump into the scheduler, never to return.
- proc->state = ZOMBIE;
+ myproc()->state = ZOMBIE;
sched();
panic("zombie exit");
}
@@ -238,7 +248,7 @@ wait(void)
// 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 != myproc())
continue;
havekids = 1;
if(p->state == ZOMBIE){
@@ -258,13 +268,13 @@ wait(void)
}
// No point waiting if we don't have any children.
- if(!havekids || proc->killed){
+ if(!havekids || myproc()->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(myproc(), &ptable.lock); //DOC: wait-sleep
}
}
@@ -294,15 +304,15 @@ 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;
+ setproc(p);
switchuvm(p);
p->state = RUNNING;
- swtch(&cpu->scheduler, p->context);
+ swtch(&(mycpu()->scheduler), p->context);
switchkvm();
// Process is done running for now.
// It should have changed its p->state before coming back.
- proc = 0;
+ setproc(0);
}
release(&ptable.lock);
@@ -323,15 +333,15 @@ sched(void)
if(!holding(&ptable.lock))
panic("sched ptable.lock");
- if(cpu->ncli != 1)
+ if(mycpu()->ncli != 1)
panic("sched locks");
- if(proc->state == RUNNING)
+ if(myproc()->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(&myproc()->context, mycpu()->scheduler);
+ mycpu()->intena = intena;
}
// Give up the CPU for one scheduling round.
@@ -339,7 +349,7 @@ void
yield(void)
{
acquire(&ptable.lock); //DOC: yieldlock
- proc->state = RUNNABLE;
+ myproc()->state = RUNNABLE;
sched();
release(&ptable.lock);
}
@@ -370,7 +380,7 @@ forkret(void)
void
sleep(void *chan, struct spinlock *lk)
{
- if(proc == 0)
+ if(myproc() == 0)
panic("sleep");
if(lk == 0)
@@ -386,14 +396,13 @@ sleep(void *chan, struct spinlock *lk)
acquire(&ptable.lock); //DOC: sleeplock1
release(lk);
}
-
// Go to sleep.
- proc->chan = chan;
- proc->state = SLEEPING;
+ myproc()->chan = chan;
+ myproc()->state = SLEEPING;
sched();
// Tidy up.
- proc->chan = 0;
+ myproc()->chan = 0;
// Reacquire original lock.
if(lk != &ptable.lock){ //DOC: sleeplock2
diff --git a/proc.h b/proc.h
index 7352805..38a2d32 100644
--- a/proc.h
+++ b/proc.h
@@ -7,25 +7,36 @@ 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.
+ // Per-CPU variables, holding pointers to the current cpu and to the current
+ // process (see cpu() and proc() in proc.c)
+ struct cpu *cpu; // On cpu 0, cpu = &cpus[0]; on cpu 1, cpu=&cpus[1], etc.
+ struct proc *proc; // The currently-running process on this cpu
};
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
+
+static inline struct cpu*
+mycpu(void) {
+ struct cpu *cpu;
+ asm("movl %%gs:0, %0" : "=r"(cpu));
+ return cpu;
+}
+
+static inline struct proc*
+myproc(void) {
+ struct proc *proc;
+ asm("movl %%gs:4, %0" : "=r"(proc));
+ return proc;
+}
+
//PAGEBREAK: 17
// Saved registers for kernel context switches.
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);
}
diff --git a/spinlock.c b/spinlock.c
index 942d93d..9120bf2 100644
--- a/spinlock.c
+++ b/spinlock.c
@@ -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();
}
diff --git a/syscall.c b/syscall.c
index 9ae7536..2d6769e 100644
--- a/syscall.c
+++ b/syscall.c
@@ -17,7 +17,7 @@
int
fetchint(uint addr, int *ip)
{
- if(addr >= proc->sz || addr+4 > proc->sz)
+ if(addr >= myproc()->sz || addr+4 > myproc()->sz)
return -1;
*ip = *(int*)(addr);
return 0;
@@ -31,13 +31,14 @@ fetchstr(uint addr, char **pp)
{
char *s, *ep;
- if(addr >= proc->sz)
+ if(addr >= myproc()->sz)
return -1;
*pp = (char*)addr;
- ep = (char*)proc->sz;
- for(s = *pp; s < ep; s++)
+ ep = (char*)myproc()->sz;
+ for(s = *pp; s < ep; s++){
if(*s == 0)
return s - *pp;
+ }
return -1;
}
@@ -45,7 +46,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
@@ -58,7 +59,7 @@ argptr(int n, char **pp, int size)
if(argint(n, &i) < 0)
return -1;
- if(size < 0 || (uint)i >= proc->sz || (uint)i+size > proc->sz)
+ if(size < 0 || (uint)i >= myproc()->sz || (uint)i+size > myproc()->sz)
return -1;
*pp = (char*)i;
return 0;
@@ -128,12 +129,12 @@ syscall(void)
{
int num;
- num = proc->tf->eax;
+ num = myproc()->tf->eax;
if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {
- proc->tf->eax = syscalls[num]();
+ myproc()->tf->eax = syscalls[num]();
} else {
cprintf("%d %s: unknown sys call %d\n",
- proc->pid, proc->name, num);
- proc->tf->eax = -1;
+ myproc()->pid, myproc()->name, num);
+ myproc()->tf->eax = -1;
}
}
diff --git a/sysfile.c b/sysfile.c
index 98e8c43..fae6960 100644
--- a/sysfile.c
+++ b/sysfile.c
@@ -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;
@@ -43,8 +43,8 @@ fdalloc(struct file *f)
int fd;
for(fd = 0; fd < NOFILE; fd++){
- if(proc->ofile[fd] == 0){
- proc->ofile[fd] = f;
+ if(myproc()->ofile[fd] == 0){
+ myproc()->ofile[fd] = f;
return fd;
}
}
@@ -97,7 +97,7 @@ sys_close(void)
if(argfd(0, &fd, &f) < 0)
return -1;
- proc->ofile[fd] = 0;
+ myproc()->ofile[fd] = 0;
fileclose(f);
return 0;
}
@@ -386,9 +386,9 @@ sys_chdir(void)
return -1;
}
iunlock(ip);
- iput(proc->cwd);
+ iput(myproc()->cwd);
end_op();
- proc->cwd = ip;
+ myproc()->cwd = ip;
return 0;
}
@@ -432,7 +432,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;
diff --git a/sysproc.c b/sysproc.c
index 6b585e0..0686d29 100644
--- a/sysproc.c
+++ b/sysproc.c
@@ -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;
}
diff --git a/trap.c b/trap.c
index e6b3784..b5eba82 100644
--- a/trap.c
+++ b/trap.c
@@ -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();
}
diff --git a/vm.c b/vm.c
index 9db8b67..cb159ad 100644
--- a/vm.c
+++ b/vm.c
@@ -21,21 +21,19 @@ 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[lapiccpunum()];
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);
-
+ c->cpu = c;
// Map cpu and proc -- these are private per cpu.
- c->gdt[SEG_KCPU] = SEG(STA_W, &c->cpu, 8, 0);
-
+ c->gdt[SEG_KCPU] = SEG(STA_W, &c->cpu, 4, 0);
lgdt(c->gdt, sizeof(c->gdt));
loadgs(SEG_KCPU << 3);
-
// Initialize cpu-local storage.
- cpu = c;
- proc = 0;
+ // setcpu(c);
+ setproc(0);
}
// Return the address of the PTE in page table pgdir
@@ -171,13 +169,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();