summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2014-03-04 22:37:15 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2014-03-04 22:37:15 +0100
commit316d8ad76b13583848db2d93187a921c18ee275c (patch)
treed0f5c3b98606ab42bbb31f3b952ba30c607df294
parent06c8a5b3911239937e0c99634e25cfc7209df436 (diff)
pc64: fix segattach
the comment about Physseg.size being in pages is wrong, change type to uintptr and correct the comment. change the length parameter of segattach() and isoverlap() to uintptr as well. segments can grow over 4GB in pc64 now and globalsegattach() in devsegment calculates len argument of isoverlap() by s->top - s->bot. note that the syscall still takes 32bit ulong argument for the length! check for integer overflow in segattach(), make sure segment goes not beyond USTKTOP. change PTEMAPMEM constant to uvlong as it is used to calculate SEGMAXSIZE.
-rw-r--r--sys/src/9/bcm/main.c2
-rw-r--r--sys/src/9/pc64/mem.h2
-rw-r--r--sys/src/9/port/portdat.h2
-rw-r--r--sys/src/9/port/portfns.h4
-rw-r--r--sys/src/9/port/segment.c13
5 files changed, 11 insertions, 12 deletions
diff --git a/sys/src/9/bcm/main.c b/sys/src/9/bcm/main.c
index 3382bd397..2d74f083f 100644
--- a/sys/src/9/bcm/main.c
+++ b/sys/src/9/bcm/main.c
@@ -223,7 +223,7 @@ gpiomeminit(void)
seg.attr = SG_PHYSICAL;
seg.name = "gpio";
seg.pa = (VIRTIO+0x200000);
- seg.size = 1;
+ seg.size = BY2PG;
addphysseg(&seg);
}
diff --git a/sys/src/9/pc64/mem.h b/sys/src/9/pc64/mem.h
index d75e0f941..a641f8800 100644
--- a/sys/src/9/pc64/mem.h
+++ b/sys/src/9/pc64/mem.h
@@ -132,7 +132,7 @@
/*
* virtual MMU
*/
-#define PTEMAPMEM (1024*1024)
+#define PTEMAPMEM (1ull*MiB)
#define PTEPERTAB (PTEMAPMEM/BY2PG)
#define SEGMAPSIZE 65536
#define SSEGMAPSIZE 16
diff --git a/sys/src/9/port/portdat.h b/sys/src/9/port/portdat.h
index 062a6ac56..ee92c43c3 100644
--- a/sys/src/9/port/portdat.h
+++ b/sys/src/9/port/portdat.h
@@ -389,7 +389,7 @@ struct Physseg
ulong attr; /* Segment attributes */
char *name; /* Attach name */
uintptr pa; /* Physical address */
- ulong size; /* Maximum segment size in pages */
+ uintptr size; /* Maximum segment size in bytes */
Page *(*pgalloc)(Segment*, uintptr); /* Allocation if we need it */
void (*pgfree)(Page*);
};
diff --git a/sys/src/9/port/portfns.h b/sys/src/9/port/portfns.h
index 5200be1e9..233dcaf9a 100644
--- a/sys/src/9/port/portfns.h
+++ b/sys/src/9/port/portfns.h
@@ -137,7 +137,7 @@ int iprint(char*, ...);
void isdir(Chan*);
int iseve(void);
int islo(void);
-Segment* isoverlap(Proc*, uintptr, int);
+Segment* isoverlap(Proc*, uintptr, uintptr);
int ispages(void*);
int isphysseg(char*);
void ixsummary(void);
@@ -302,7 +302,7 @@ void scheddump(void);
void schedinit(void);
void (*screenputs)(char*, int);
long seconds(void);
-uintptr segattach(Proc*, ulong, char *, uintptr, ulong);
+uintptr segattach(Proc*, ulong, char *, uintptr, uintptr);
void segclock(uintptr);
void segpage(Segment*, Page*);
int setcolor(ulong, ulong, ulong, ulong);
diff --git a/sys/src/9/port/segment.c b/sys/src/9/port/segment.c
index c73698b9e..735c876b4 100644
--- a/sys/src/9/port/segment.c
+++ b/sys/src/9/port/segment.c
@@ -558,7 +558,7 @@ out:
}
Segment*
-isoverlap(Proc *p, uintptr va, int len)
+isoverlap(Proc *p, uintptr va, uintptr len)
{
int i;
Segment *ns;
@@ -621,7 +621,7 @@ isphysseg(char *name)
}
uintptr
-segattach(Proc *p, ulong attr, char *name, uintptr va, ulong len)
+segattach(Proc *p, ulong attr, char *name, uintptr va, uintptr len)
{
int sno;
Segment *s, *os;
@@ -671,13 +671,12 @@ segattach(Proc *p, ulong attr, char *name, uintptr va, ulong len)
error(Enovmem);
va -= len;
}
- va &= ~(BY2PG-1);
- } else {
- va &= ~(BY2PG-1);
- if(va == 0 || va >= USTKTOP)
- error(Ebadarg);
}
+ va &= ~(BY2PG-1);
+ if(va == 0 || (va+len) > USTKTOP || (va+len) < va)
+ error(Ebadarg);
+
if(isoverlap(p, va, len) != nil)
error(Esoverlap);