git: 9front

Download patch

ref: 8772e0d0d2271a3ace04a7051ac5ea9aeb57634b
parent: 63932f106b84ebcfdd4f8f5fc75080a45e7383a8
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Tue Mar 4 17:37:15 EST 2014

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.

--- a/sys/src/9/bcm/main.c
+++ b/sys/src/9/bcm/main.c
@@ -223,7 +223,7 @@
 	seg.attr = SG_PHYSICAL;
 	seg.name = "gpio";
 	seg.pa = (VIRTIO+0x200000);
-	seg.size = 1;
+	seg.size = BY2PG;
 	addphysseg(&seg);
 }
 
--- 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
--- a/sys/src/9/port/portdat.h
+++ b/sys/src/9/port/portdat.h
@@ -389,7 +389,7 @@
 	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*);
 };
--- a/sys/src/9/port/portfns.h
+++ b/sys/src/9/port/portfns.h
@@ -137,7 +137,7 @@
 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		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);
--- a/sys/src/9/port/segment.c
+++ b/sys/src/9/port/segment.c
@@ -558,7 +558,7 @@
 }
 
 Segment*
-isoverlap(Proc *p, uintptr va, int len)
+isoverlap(Proc *p, uintptr va, uintptr len)
 {
 	int i;
 	Segment *ns;
@@ -621,7 +621,7 @@
 }
 
 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,12 +671,11 @@
 				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);
--