summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/9/port/portfns.h2
-rw-r--r--sys/src/9/port/segment.c16
-rw-r--r--sys/src/9/port/sysproc.c12
3 files changed, 18 insertions, 12 deletions
diff --git a/sys/src/9/port/portfns.h b/sys/src/9/port/portfns.h
index d1e26d7e0..a93ddd2ab 100644
--- a/sys/src/9/port/portfns.h
+++ b/sys/src/9/port/portfns.h
@@ -167,7 +167,7 @@ void* mallocalign(ulong, ulong, long, ulong);
void mallocsummary(void);
Block* mem2bl(uchar*, int);
ulong mcountseg(Segment*);
-void mfreeseg(Segment*, uintptr, int);
+void mfreeseg(Segment*, uintptr, ulong);
void microdelay(int);
uvlong mk64fract(uvlong, uvlong);
void mkqid(Qid*, vlong, ulong, int);
diff --git a/sys/src/9/port/segment.c b/sys/src/9/port/segment.c
index c64a4efbf..295c8551f 100644
--- a/sys/src/9/port/segment.c
+++ b/sys/src/9/port/segment.c
@@ -479,12 +479,15 @@ mcountseg(Segment *s)
* called with s locked
*/
void
-mfreeseg(Segment *s, uintptr start, int pages)
+mfreeseg(Segment *s, uintptr start, ulong pages)
{
int i, j, size;
uintptr soff;
Page *pg;
+ if(pages == 0)
+ return;
+
if((s->type&SG_TYPE) == SG_PHYSICAL)
return;
@@ -500,12 +503,12 @@ mfreeseg(Segment *s, uintptr start, int pages)
j = (soff&(PTEMAPMEM-1))/BY2PG;
size = s->mapsize;
- for(i = soff/PTEMAPMEM; i < size; i++) {
- if(pages <= 0)
- return;
+ for(i = soff/PTEMAPMEM; i < size; i++, j = 0) {
if(s->map[i] == nil) {
- pages -= PTEPERTAB-j;
- j = 0;
+ j = PTEPERTAB - j;
+ if(j >= pages)
+ return;
+ pages -= j;
continue;
}
while(j < PTEPERTAB) {
@@ -518,7 +521,6 @@ mfreeseg(Segment *s, uintptr start, int pages)
return;
j++;
}
- j = 0;
}
}
diff --git a/sys/src/9/port/sysproc.c b/sys/src/9/port/sysproc.c
index b787a3d6a..4b26d0970 100644
--- a/sys/src/9/port/sysproc.c
+++ b/sys/src/9/port/sysproc.c
@@ -823,19 +823,23 @@ syssegfree(va_list list)
uintptr from, to;
from = va_arg(list, uintptr);
+ to = va_arg(list, ulong);
+ to += from;
+ if(to < from)
+ error(Ebadarg);
s = seg(up, from, 1);
if(s == nil)
error(Ebadarg);
- to = va_arg(list, ulong);
- to += from;
to &= ~(BY2PG-1);
from = PGROUND(from);
-
+ if(from >= to) {
+ qunlock(s);
+ return 0;
+ }
if(to > s->top) {
qunlock(s);
error(Ebadarg);
}
-
mfreeseg(s, from, (to - from) / BY2PG);
qunlock(s);
flushmmu();