shithub: riscv

Download patch

ref: 316d8ad76b13583848db2d93187a921c18ee275c
parent: 06c8a5b3911239937e0c99634e25cfc7209df436
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);