diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-03-10 18:16:08 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-03-10 18:16:08 +0100 |
commit | 4d211fdd4801bd6db06ae2c0a72b47de55f3194c (patch) | |
tree | 4fe0dd7a7a8a785f42812d4868168c5d7aba05ef /sys/src/9/port/page.c | |
parent | 5639d1e5fc46c5f236cff7168a5800367368a6ec (diff) |
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.
Diffstat (limited to 'sys/src/9/port/page.c')
-rw-r--r-- | sys/src/9/port/page.c | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/sys/src/9/port/page.c b/sys/src/9/port/page.c index 0061ed658..4945b3436 100644 --- a/sys/src/9/port/page.c +++ b/sys/src/9/port/page.c @@ -148,7 +148,6 @@ newpage(int clear, Segment **s, uintptr va) KMap *k; int color; - color = getpgcolor(va); lock(&palloc); for(;;) { if(palloc.freecount > swapalloc.highwater) @@ -188,6 +187,7 @@ newpage(int clear, Segment **s, uintptr va) } /* First try for our colour */ + color = getpgcolor(va); l = &palloc.head; for(p = *l; p != nil; p = p->next){ if(p->color == color) @@ -384,24 +384,24 @@ ptealloc(void) void freepte(Segment *s, Pte *p) { - Page **pg; + Page **pg, **pe; + + pg = p->first; + pe = p->last; switch(s->type&SG_TYPE) { case SG_PHYSICAL: - for(pg = p->first; pg <= p->last; pg++) { - if(*pg != nil) { - if(decref(*pg) == 0) - free(*pg); - *pg = nil; - } + while(pg <= pe){ + if(*pg != nil && decref(*pg) == 0) + free(*pg); + pg++; } break; default: - for(pg = p->first; pg <= p->last; pg++) { - if(*pg != nil) { + while(pg <= pe){ + if(*pg != nil) putpage(*pg); - *pg = nil; - } + pg++; } } free(p); |