2011-03-30 12:46:40 +00:00
|
|
|
#include "u.h"
|
|
|
|
#include "../port/lib.h"
|
|
|
|
#include "mem.h"
|
|
|
|
#include "dat.h"
|
|
|
|
#include "fns.h"
|
|
|
|
#include "../port/error.h"
|
|
|
|
|
2014-06-22 13:12:45 +00:00
|
|
|
Palloc palloc;
|
2011-03-30 12:46:40 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
pageinit(void)
|
|
|
|
{
|
|
|
|
int color, i, j;
|
|
|
|
Page *p;
|
|
|
|
Pallocmem *pm;
|
2014-04-15 19:34:41 +00:00
|
|
|
vlong m, v, u;
|
2011-03-30 12:46:40 +00:00
|
|
|
|
2014-06-01 01:13:58 +00:00
|
|
|
if(palloc.pages == nil){
|
|
|
|
ulong np;
|
|
|
|
|
|
|
|
np = 0;
|
|
|
|
for(i=0; i<nelem(palloc.mem); i++){
|
|
|
|
pm = &palloc.mem[i];
|
|
|
|
np += pm->npage;
|
|
|
|
}
|
|
|
|
palloc.pages = xalloc(np*sizeof(Page));
|
|
|
|
if(palloc.pages == nil)
|
|
|
|
panic("pageinit");
|
2011-03-30 12:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
color = 0;
|
2014-06-22 13:12:45 +00:00
|
|
|
palloc.head = nil;
|
|
|
|
p = palloc.pages;
|
2011-03-30 12:46:40 +00:00
|
|
|
for(i=0; i<nelem(palloc.mem); i++){
|
|
|
|
pm = &palloc.mem[i];
|
|
|
|
for(j=0; j<pm->npage; j++){
|
2014-06-01 01:13:58 +00:00
|
|
|
memset(p, 0, sizeof *p);
|
2011-03-30 12:46:40 +00:00
|
|
|
p->pa = pm->base+j*BY2PG;
|
2015-06-18 10:15:33 +00:00
|
|
|
if(cankaddr(p->pa) && (KADDR(p->pa) == nil || KADDR(p->pa) == (void*)-BY2PG))
|
|
|
|
continue;
|
2011-03-30 12:46:40 +00:00
|
|
|
p->color = color;
|
|
|
|
color = (color+1)%NCOLOR;
|
2014-06-22 13:12:45 +00:00
|
|
|
pagechainhead(p);
|
2011-03-30 12:46:40 +00:00
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
palloc.user = p - palloc.pages;
|
2014-04-15 19:34:41 +00:00
|
|
|
u = palloc.user*BY2PG;
|
|
|
|
v = u + conf.nswap*BY2PG;
|
2011-03-30 12:46:40 +00:00
|
|
|
|
|
|
|
/* Paging numbers */
|
|
|
|
swapalloc.highwater = (palloc.user*5)/100;
|
|
|
|
swapalloc.headroom = swapalloc.highwater + (swapalloc.highwater/4);
|
|
|
|
|
|
|
|
m = 0;
|
|
|
|
for(i=0; i<nelem(conf.mem); i++)
|
|
|
|
if(conf.mem[i].npage)
|
|
|
|
m += conf.mem[i].npage*BY2PG;
|
2014-04-15 19:34:41 +00:00
|
|
|
m += PGROUND(end - (char*)KTZERO);
|
|
|
|
|
|
|
|
print("%lldM memory: ", (m+1024*1024-1)/(1024*1024));
|
|
|
|
print("%lldM kernel data, ", (m-u+1024*1024-1)/(1024*1024));
|
|
|
|
print("%lldM user, ", u/(1024*1024));
|
|
|
|
print("%lldM swap\n", v/(1024*1024));
|
2011-03-30 12:46:40 +00:00
|
|
|
}
|
|
|
|
|
2014-02-24 21:42:22 +00:00
|
|
|
void
|
2014-06-22 13:12:45 +00:00
|
|
|
pagechainhead(Page *p)
|
2011-03-30 12:46:40 +00:00
|
|
|
{
|
2014-06-22 13:12:45 +00:00
|
|
|
p->next = palloc.head;
|
|
|
|
palloc.head = p;
|
|
|
|
palloc.freecount++;
|
2011-03-30 12:46:40 +00:00
|
|
|
}
|
|
|
|
|
2015-06-15 15:40:47 +00:00
|
|
|
void
|
|
|
|
pagechaindone(void)
|
|
|
|
{
|
|
|
|
if(palloc.pwait[0].p != nil && wakeup(&palloc.pwait[0]) != nil)
|
|
|
|
return;
|
|
|
|
if(palloc.pwait[1].p != nil)
|
|
|
|
wakeup(&palloc.pwait[1]);
|
|
|
|
}
|
|
|
|
|
2019-05-01 08:07:39 +00:00
|
|
|
void
|
2015-07-08 22:01:50 +00:00
|
|
|
freepages(Page *head, Page *tail, ulong np)
|
2011-03-30 12:46:40 +00:00
|
|
|
{
|
2019-05-01 08:07:39 +00:00
|
|
|
assert(palloc.Lock.p == up);
|
2014-06-22 13:12:45 +00:00
|
|
|
tail->next = palloc.head;
|
|
|
|
palloc.head = head;
|
2015-07-08 22:01:50 +00:00
|
|
|
palloc.freecount += np;
|
2015-06-15 15:40:47 +00:00
|
|
|
pagechaindone();
|
2011-03-30 12:46:40 +00:00
|
|
|
}
|
|
|
|
|
2015-07-08 22:01:50 +00:00
|
|
|
ulong
|
|
|
|
pagereclaim(Image *i, ulong pages)
|
2011-03-30 12:46:40 +00:00
|
|
|
{
|
2015-02-07 02:01:59 +00:00
|
|
|
Page **h, **l, **x, *p;
|
2014-06-22 13:12:45 +00:00
|
|
|
Page *fh, *ft;
|
2015-07-08 22:01:50 +00:00
|
|
|
ulong np;
|
|
|
|
|
|
|
|
if(pages == 0)
|
|
|
|
return 0;
|
2014-06-22 13:12:45 +00:00
|
|
|
|
|
|
|
lock(i);
|
|
|
|
if(i->pgref == 0){
|
|
|
|
unlock(i);
|
|
|
|
return 0;
|
2011-03-30 12:46:40 +00:00
|
|
|
}
|
2014-06-22 13:12:45 +00:00
|
|
|
incref(i);
|
|
|
|
|
2015-07-08 22:01:50 +00:00
|
|
|
np = 0;
|
2014-06-22 13:12:45 +00:00
|
|
|
fh = ft = nil;
|
|
|
|
for(h = i->pghash; h < &i->pghash[PGHSIZE]; h++){
|
2015-02-07 02:01:59 +00:00
|
|
|
l = h;
|
|
|
|
x = nil;
|
|
|
|
for(p = *l; p != nil; p = p->next){
|
2014-06-22 13:12:45 +00:00
|
|
|
if(p->ref == 0)
|
2015-02-07 02:01:59 +00:00
|
|
|
x = l;
|
2014-06-22 13:12:45 +00:00
|
|
|
l = &p->next;
|
|
|
|
}
|
2015-02-07 02:01:59 +00:00
|
|
|
if(x == nil)
|
2014-06-22 13:12:45 +00:00
|
|
|
continue;
|
|
|
|
|
2015-02-07 02:01:59 +00:00
|
|
|
p = *x;
|
|
|
|
*x = p->next;
|
2014-06-22 13:12:45 +00:00
|
|
|
p->next = nil;
|
|
|
|
p->image = nil;
|
|
|
|
p->daddr = ~0;
|
|
|
|
i->pgref--;
|
|
|
|
decref(i);
|
|
|
|
|
|
|
|
if(fh == nil)
|
|
|
|
fh = p;
|
|
|
|
else
|
|
|
|
ft->next = p;
|
|
|
|
ft = p;
|
2015-07-08 22:01:50 +00:00
|
|
|
if(++np >= pages)
|
2014-06-22 13:12:45 +00:00
|
|
|
break;
|
2011-03-30 12:46:40 +00:00
|
|
|
}
|
2014-06-22 13:12:45 +00:00
|
|
|
unlock(i);
|
|
|
|
putimage(i);
|
|
|
|
|
2019-05-01 08:07:39 +00:00
|
|
|
if(np > 0){
|
|
|
|
lock(&palloc);
|
2015-07-08 22:01:50 +00:00
|
|
|
freepages(fh, ft, np);
|
2019-05-01 08:07:39 +00:00
|
|
|
unlock(&palloc);
|
|
|
|
}
|
2014-06-22 13:12:45 +00:00
|
|
|
|
2015-07-08 22:01:50 +00:00
|
|
|
return np;
|
2014-06-22 13:12:45 +00:00
|
|
|
}
|
|
|
|
|
2015-06-15 14:05:00 +00:00
|
|
|
static int
|
2014-06-22 13:12:45 +00:00
|
|
|
ispages(void*)
|
|
|
|
{
|
2015-06-15 14:05:00 +00:00
|
|
|
return palloc.freecount > swapalloc.highwater || up->noswap && palloc.freecount > 0;
|
2011-03-30 12:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Page*
|
2014-01-19 23:47:55 +00:00
|
|
|
newpage(int clear, Segment **s, uintptr va)
|
2011-03-30 12:46:40 +00:00
|
|
|
{
|
2014-06-22 13:12:45 +00:00
|
|
|
Page *p, **l;
|
2011-03-30 12:46:40 +00:00
|
|
|
KMap *k;
|
2015-02-07 01:52:23 +00:00
|
|
|
int color;
|
2011-03-30 12:46:40 +00:00
|
|
|
|
2014-06-22 13:12:45 +00:00
|
|
|
lock(&palloc);
|
2015-06-15 14:05:00 +00:00
|
|
|
while(!ispages(nil)){
|
2011-03-30 12:46:40 +00:00
|
|
|
unlock(&palloc);
|
2014-06-22 13:12:45 +00:00
|
|
|
if(s != nil)
|
|
|
|
qunlock(*s);
|
2011-03-30 12:46:40 +00:00
|
|
|
|
2011-08-24 12:43:15 +00:00
|
|
|
if(!waserror()){
|
2015-06-15 14:05:00 +00:00
|
|
|
Rendezq *q;
|
2011-03-30 12:46:40 +00:00
|
|
|
|
2015-06-15 14:05:00 +00:00
|
|
|
q = &palloc.pwait[!up->noswap];
|
|
|
|
eqlock(q);
|
2011-08-24 12:43:15 +00:00
|
|
|
if(!waserror()){
|
|
|
|
kickpager();
|
2015-06-15 14:05:00 +00:00
|
|
|
sleep(q, ispages, nil);
|
2011-08-24 12:43:15 +00:00
|
|
|
poperror();
|
|
|
|
}
|
2015-06-15 14:05:00 +00:00
|
|
|
qunlock(q);
|
2011-08-24 12:43:15 +00:00
|
|
|
poperror();
|
|
|
|
}
|
2011-03-30 12:46:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If called from fault and we lost the segment from
|
|
|
|
* underneath don't waste time allocating and freeing
|
|
|
|
* a page. Fault will call newpage again when it has
|
|
|
|
* reacquired the segment locks
|
|
|
|
*/
|
2014-06-22 13:12:45 +00:00
|
|
|
if(s != nil){
|
|
|
|
*s = nil;
|
|
|
|
return nil;
|
2011-08-24 12:43:15 +00:00
|
|
|
}
|
2011-03-30 12:46:40 +00:00
|
|
|
lock(&palloc);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* First try for our colour */
|
kernel: fix integer overflow in syssegflush(), segment code cleanup
mcountseg(), mfreeseg():
use Pte.first/last pointers when possible and avoid constructs
like s->map[i]->pages[j].
freepte():
do not zero entries in freepte(), the segment is going away and
here is no point in zeroing page pointers. hoist common code at
the top avoiding duplication.
segpage(), fixfault():
avoid load after store for Pte** pointer.
fixfault():
return -1 in default case to avoid the "used but not set" warning
for mmuphys and get rid of the useless initialization.
syssegflush():
due to len being unsigned, the pe = PGROUND(pe) can make "chunk"
bigger than len causing a overflow. rewrite the function and deal
with page alignment and errors at the beginning.
syssegflush(), segpage(), fixfault(), putseg(), relocateseg(),
mcountseg(), mfreeseg():
keep naming consistent.
2015-03-10 17:16:08 +00:00
|
|
|
color = getpgcolor(va);
|
2014-06-22 13:12:45 +00:00
|
|
|
l = &palloc.head;
|
|
|
|
for(p = *l; p != nil; p = p->next){
|
2011-03-30 12:46:40 +00:00
|
|
|
if(p->color == color)
|
|
|
|
break;
|
2014-06-22 13:12:45 +00:00
|
|
|
l = &p->next;
|
|
|
|
}
|
2011-03-30 12:46:40 +00:00
|
|
|
|
2014-06-22 13:12:45 +00:00
|
|
|
if(p == nil) {
|
|
|
|
l = &palloc.head;
|
|
|
|
p = *l;
|
2011-03-30 12:46:40 +00:00
|
|
|
}
|
|
|
|
|
2014-06-22 13:12:45 +00:00
|
|
|
*l = p->next;
|
|
|
|
p->next = nil;
|
|
|
|
palloc.freecount--;
|
|
|
|
unlock(&palloc);
|
2011-03-30 12:46:40 +00:00
|
|
|
|
2014-06-22 13:12:45 +00:00
|
|
|
p->ref = 1;
|
2011-03-30 12:46:40 +00:00
|
|
|
p->va = va;
|
|
|
|
p->modref = 0;
|
2015-02-07 01:52:23 +00:00
|
|
|
p->txtflush = 0;
|
2011-03-30 12:46:40 +00:00
|
|
|
|
|
|
|
if(clear) {
|
|
|
|
k = kmap(p);
|
|
|
|
memset((void*)VA(k), 0, BY2PG);
|
|
|
|
kunmap(k);
|
|
|
|
}
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
putpage(Page *p)
|
|
|
|
{
|
|
|
|
if(onswap(p)) {
|
|
|
|
putswap(p);
|
|
|
|
return;
|
|
|
|
}
|
2014-06-22 13:12:45 +00:00
|
|
|
if(p->image != nil) {
|
|
|
|
decref(p);
|
2011-03-30 12:46:40 +00:00
|
|
|
return;
|
|
|
|
}
|
2019-05-01 08:07:39 +00:00
|
|
|
if(decref(p) == 0){
|
|
|
|
lock(&palloc);
|
2014-06-22 13:12:45 +00:00
|
|
|
freepages(p, p, 1);
|
2019-05-01 08:07:39 +00:00
|
|
|
unlock(&palloc);
|
|
|
|
}
|
2011-03-30 12:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
copypage(Page *f, Page *t)
|
|
|
|
{
|
|
|
|
KMap *ks, *kd;
|
|
|
|
|
|
|
|
ks = kmap(f);
|
|
|
|
kd = kmap(t);
|
|
|
|
memmove((void*)VA(kd), (void*)VA(ks), BY2PG);
|
|
|
|
kunmap(ks);
|
|
|
|
kunmap(kd);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-06-22 13:12:45 +00:00
|
|
|
cachepage(Page *p, Image *i)
|
|
|
|
{
|
|
|
|
Page **h;
|
|
|
|
|
|
|
|
lock(i);
|
|
|
|
p->image = i;
|
|
|
|
h = &PGHASH(i, p->daddr);
|
|
|
|
p->next = *h;
|
|
|
|
*h = p;
|
|
|
|
incref(i);
|
|
|
|
i->pgref++;
|
|
|
|
unlock(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
uncachepage(Page *p)
|
2011-03-30 12:46:40 +00:00
|
|
|
{
|
2014-06-22 13:12:45 +00:00
|
|
|
Page **l, *x;
|
2013-11-08 21:31:26 +00:00
|
|
|
Image *i;
|
2011-03-30 12:46:40 +00:00
|
|
|
|
2013-11-08 21:31:26 +00:00
|
|
|
i = p->image;
|
2014-06-22 13:12:45 +00:00
|
|
|
if(i == nil)
|
2011-03-30 12:46:40 +00:00
|
|
|
return;
|
|
|
|
|
2014-06-22 13:12:45 +00:00
|
|
|
lock(i);
|
|
|
|
if(p->image != i){
|
|
|
|
unlock(i);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
l = &PGHASH(i, p->daddr);
|
|
|
|
for(x = *l; x != nil; x = x->next) {
|
|
|
|
if(x == p){
|
|
|
|
*l = p->next;
|
|
|
|
p->next = nil;
|
|
|
|
p->image = nil;
|
|
|
|
p->daddr = ~0;
|
|
|
|
i->pgref--;
|
|
|
|
unlock(i);
|
|
|
|
putimage(i);
|
|
|
|
return;
|
2011-03-30 12:46:40 +00:00
|
|
|
}
|
2014-06-22 13:12:45 +00:00
|
|
|
l = &x->next;
|
2011-03-30 12:46:40 +00:00
|
|
|
}
|
2013-11-08 21:31:26 +00:00
|
|
|
unlock(i);
|
2011-03-30 12:46:40 +00:00
|
|
|
}
|
|
|
|
|
2014-06-22 13:12:45 +00:00
|
|
|
Page*
|
|
|
|
lookpage(Image *i, uintptr daddr)
|
2011-03-30 12:46:40 +00:00
|
|
|
{
|
2015-02-07 02:01:59 +00:00
|
|
|
Page *p, **h, **l;
|
2011-03-30 12:46:40 +00:00
|
|
|
|
2013-11-08 21:31:26 +00:00
|
|
|
lock(i);
|
2015-02-07 02:01:59 +00:00
|
|
|
l = h = &PGHASH(i, daddr);
|
|
|
|
for(p = *l; p != nil; p = p->next){
|
|
|
|
if(p->daddr == daddr){
|
|
|
|
*l = p->next;
|
|
|
|
p->next = *h;
|
|
|
|
*h = p;
|
2014-06-22 13:12:45 +00:00
|
|
|
incref(p);
|
|
|
|
unlock(i);
|
|
|
|
return p;
|
|
|
|
}
|
2015-02-07 02:01:59 +00:00
|
|
|
l = &p->next;
|
2014-06-22 13:12:45 +00:00
|
|
|
}
|
2013-11-08 21:31:26 +00:00
|
|
|
unlock(i);
|
|
|
|
|
2014-06-22 13:12:45 +00:00
|
|
|
return nil;
|
2011-03-30 12:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-01-19 23:47:55 +00:00
|
|
|
cachedel(Image *i, uintptr daddr)
|
2011-03-30 12:46:40 +00:00
|
|
|
{
|
2014-06-22 13:12:45 +00:00
|
|
|
Page *p;
|
2012-10-16 12:12:21 +00:00
|
|
|
|
2014-06-22 13:12:45 +00:00
|
|
|
while((p = lookpage(i, daddr)) != nil){
|
|
|
|
uncachepage(p);
|
|
|
|
putpage(p);
|
2011-03-30 12:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Pte*
|
|
|
|
ptecpy(Pte *old)
|
|
|
|
{
|
|
|
|
Pte *new;
|
|
|
|
Page **src, **dst;
|
|
|
|
|
|
|
|
new = ptealloc();
|
|
|
|
dst = &new->pages[old->first-old->pages];
|
|
|
|
new->first = dst;
|
|
|
|
for(src = old->first; src <= old->last; src++, dst++)
|
2014-06-22 13:12:45 +00:00
|
|
|
if(*src != nil) {
|
2011-03-30 12:46:40 +00:00
|
|
|
if(onswap(*src))
|
|
|
|
dupswap(*src);
|
2014-06-22 13:12:45 +00:00
|
|
|
else
|
|
|
|
incref(*src);
|
2011-03-30 12:46:40 +00:00
|
|
|
new->last = dst;
|
|
|
|
*dst = *src;
|
|
|
|
}
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
Pte*
|
|
|
|
ptealloc(void)
|
|
|
|
{
|
|
|
|
Pte *new;
|
|
|
|
|
|
|
|
new = smalloc(sizeof(Pte));
|
|
|
|
new->first = &new->pages[PTEPERTAB];
|
|
|
|
new->last = new->pages;
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
freepte(Segment *s, Pte *p)
|
|
|
|
{
|
kernel: fix integer overflow in syssegflush(), segment code cleanup
mcountseg(), mfreeseg():
use Pte.first/last pointers when possible and avoid constructs
like s->map[i]->pages[j].
freepte():
do not zero entries in freepte(), the segment is going away and
here is no point in zeroing page pointers. hoist common code at
the top avoiding duplication.
segpage(), fixfault():
avoid load after store for Pte** pointer.
fixfault():
return -1 in default case to avoid the "used but not set" warning
for mmuphys and get rid of the useless initialization.
syssegflush():
due to len being unsigned, the pe = PGROUND(pe) can make "chunk"
bigger than len causing a overflow. rewrite the function and deal
with page alignment and errors at the beginning.
syssegflush(), segpage(), fixfault(), putseg(), relocateseg(),
mcountseg(), mfreeseg():
keep naming consistent.
2015-03-10 17:16:08 +00:00
|
|
|
Page **pg, **pe;
|
|
|
|
|
|
|
|
pg = p->first;
|
|
|
|
pe = p->last;
|
2011-03-30 12:46:40 +00:00
|
|
|
|
|
|
|
switch(s->type&SG_TYPE) {
|
|
|
|
case SG_PHYSICAL:
|
kernel: fix integer overflow in syssegflush(), segment code cleanup
mcountseg(), mfreeseg():
use Pte.first/last pointers when possible and avoid constructs
like s->map[i]->pages[j].
freepte():
do not zero entries in freepte(), the segment is going away and
here is no point in zeroing page pointers. hoist common code at
the top avoiding duplication.
segpage(), fixfault():
avoid load after store for Pte** pointer.
fixfault():
return -1 in default case to avoid the "used but not set" warning
for mmuphys and get rid of the useless initialization.
syssegflush():
due to len being unsigned, the pe = PGROUND(pe) can make "chunk"
bigger than len causing a overflow. rewrite the function and deal
with page alignment and errors at the beginning.
syssegflush(), segpage(), fixfault(), putseg(), relocateseg(),
mcountseg(), mfreeseg():
keep naming consistent.
2015-03-10 17:16:08 +00:00
|
|
|
while(pg <= pe){
|
|
|
|
if(*pg != nil && decref(*pg) == 0)
|
|
|
|
free(*pg);
|
|
|
|
pg++;
|
2011-03-30 12:46:40 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
kernel: fix integer overflow in syssegflush(), segment code cleanup
mcountseg(), mfreeseg():
use Pte.first/last pointers when possible and avoid constructs
like s->map[i]->pages[j].
freepte():
do not zero entries in freepte(), the segment is going away and
here is no point in zeroing page pointers. hoist common code at
the top avoiding duplication.
segpage(), fixfault():
avoid load after store for Pte** pointer.
fixfault():
return -1 in default case to avoid the "used but not set" warning
for mmuphys and get rid of the useless initialization.
syssegflush():
due to len being unsigned, the pe = PGROUND(pe) can make "chunk"
bigger than len causing a overflow. rewrite the function and deal
with page alignment and errors at the beginning.
syssegflush(), segpage(), fixfault(), putseg(), relocateseg(),
mcountseg(), mfreeseg():
keep naming consistent.
2015-03-10 17:16:08 +00:00
|
|
|
while(pg <= pe){
|
|
|
|
if(*pg != nil)
|
2011-03-30 12:46:40 +00:00
|
|
|
putpage(*pg);
|
kernel: fix integer overflow in syssegflush(), segment code cleanup
mcountseg(), mfreeseg():
use Pte.first/last pointers when possible and avoid constructs
like s->map[i]->pages[j].
freepte():
do not zero entries in freepte(), the segment is going away and
here is no point in zeroing page pointers. hoist common code at
the top avoiding duplication.
segpage(), fixfault():
avoid load after store for Pte** pointer.
fixfault():
return -1 in default case to avoid the "used but not set" warning
for mmuphys and get rid of the useless initialization.
syssegflush():
due to len being unsigned, the pe = PGROUND(pe) can make "chunk"
bigger than len causing a overflow. rewrite the function and deal
with page alignment and errors at the beginning.
syssegflush(), segpage(), fixfault(), putseg(), relocateseg(),
mcountseg(), mfreeseg():
keep naming consistent.
2015-03-10 17:16:08 +00:00
|
|
|
pg++;
|
2015-03-03 12:08:29 +00:00
|
|
|
}
|
2011-03-30 12:46:40 +00:00
|
|
|
}
|
|
|
|
free(p);
|
|
|
|
}
|