summaryrefslogtreecommitdiff
path: root/sys/src/9/port/page.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2015-03-10 18:16:08 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2015-03-10 18:16:08 +0100
commit4d211fdd4801bd6db06ae2c0a72b47de55f3194c (patch)
tree4fe0dd7a7a8a785f42812d4868168c5d7aba05ef /sys/src/9/port/page.c
parent5639d1e5fc46c5f236cff7168a5800367368a6ec (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.c24
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);