diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-02-06 22:41:42 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-02-06 22:41:42 +0100 |
commit | bfbc5ab1970bbf9307e03a42e69b0d55eb92f2ef (patch) | |
tree | 8f71f8efd7cb541cbc26c0c4914b3de999d59c3d | |
parent | f029ea1694b4f0f8ec0cc848b936b0122bd17347 (diff) |
pc64: fix kmap()
kmapindex has to be per process, not per mach, as the process
can be switched to another processor while the mapping is
established.
to bootstrap the first process, we have to temporarily set up
so the kmap MMU's can be attached to the process. previously
we assumed that the first two pages for the initial process
where below 2GB and could be accessed with KADDR() directly.
with 16GB machine, all the 2GB above KZERO are dedicated to
the kernel so the user pages returned by newpage() need to
be mapped.
-rw-r--r-- | sys/src/9/pc64/dat.h | 2 | ||||
-rw-r--r-- | sys/src/9/pc64/main.c | 7 | ||||
-rw-r--r-- | sys/src/9/pc64/mmu.c | 8 |
3 files changed, 12 insertions, 5 deletions
diff --git a/sys/src/9/pc64/dat.h b/sys/src/9/pc64/dat.h index ca0f745c9..0882634c8 100644 --- a/sys/src/9/pc64/dat.h +++ b/sys/src/9/pc64/dat.h @@ -142,6 +142,7 @@ struct PMMU MMU* kmaphead; MMU* kmaptail; int kmapcount; + int kmapindex; int mmucount; }; @@ -182,7 +183,6 @@ struct Mach u64int mmumap[4]; /* bitmap of pml4 entries for zapping */ MMU* mmufree; /* freelist for MMU structures */ int mmucount; /* number of MMU structures in freelist */ - int kmapindex; /* next KMAP page index for use */ ulong ticks; /* of the clock since boot time */ Label sched; /* scheduler wakeup */ diff --git a/sys/src/9/pc64/main.c b/sys/src/9/pc64/main.c index 596aa0c48..9cec7f8f9 100644 --- a/sys/src/9/pc64/main.c +++ b/sys/src/9/pc64/main.c @@ -346,6 +346,9 @@ userinit(void) p->sched.pc = (uintptr)init0; p->sched.sp = (uintptr)p->kstack+KSTACK-(sizeof(Sargs)+BY2WD); + /* temporarily set up for kmap() */ + up = p; + /* * User Stack */ @@ -372,6 +375,10 @@ userinit(void) memmove(v, initcode, sizeof initcode); kunmap(v); + /* free kmap */ + mmurelease(p); + up = nil; + ready(p); } diff --git a/sys/src/9/pc64/mmu.c b/sys/src/9/pc64/mmu.c index 1c406ecc6..a475d53e9 100644 --- a/sys/src/9/pc64/mmu.c +++ b/sys/src/9/pc64/mmu.c @@ -415,7 +415,7 @@ mmurelease(Proc *proc) proc->mmucount += proc->kmapcount; proc->kmaphead = proc->kmaptail = nil; - proc->kmapcount = 0; + proc->kmapcount = proc->kmapindex = 0; } mmufree(proc); taskswitch((uintptr)m+MACHSIZE); @@ -469,13 +469,13 @@ kmap(Page *page) return (KMap*)KADDR(pa); x = splhi(); - va = KMAP + ((uintptr)m->kmapindex << PGSHIFT); + va = KMAP + ((uintptr)up->kmapindex << PGSHIFT); pte = mmuwalk(m->pml4, va, 0, 1); if(pte == 0 || *pte & PTEVALID) panic("kmap: pa=%#p va=%#p", pa, va); *pte = pa | PTEWRITE|PTEVALID; - m->kmapindex = (m->kmapindex + 1) % (1<<PTSHIFT); - if(m->kmapindex == 0) + up->kmapindex = (up->kmapindex + 1) % (1<<PTSHIFT); + if(up->kmapindex == 0) mmuflushtlb(); splx(x); return (KMap*)va; |