changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: pc64: fix segattach

changeset 3415: 4477c30eec57
parent 3414: cfe71dcc4dd4
child 3416: f4cacb086d2f
author: cinap_lenrek@felloff.net
date: Tue, 04 Mar 2014 22:37:15 +0100
files: sys/src/9/bcm/main.c sys/src/9/pc64/mem.h sys/src/9/port/portdat.h sys/src/9/port/portfns.h sys/src/9/port/segment.c
description: 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.
     1.1--- a/sys/src/9/bcm/main.c
     1.2+++ b/sys/src/9/bcm/main.c
     1.3@@ -223,7 +223,7 @@ gpiomeminit(void)
     1.4 	seg.attr = SG_PHYSICAL;
     1.5 	seg.name = "gpio";
     1.6 	seg.pa = (VIRTIO+0x200000);
     1.7-	seg.size = 1;
     1.8+	seg.size = BY2PG;
     1.9 	addphysseg(&seg);
    1.10 }
    1.11 
     2.1--- a/sys/src/9/pc64/mem.h
     2.2+++ b/sys/src/9/pc64/mem.h
     2.3@@ -132,7 +132,7 @@
     2.4 /*
     2.5  *  virtual MMU
     2.6  */
     2.7-#define	PTEMAPMEM	(1024*1024)	
     2.8+#define	PTEMAPMEM	(1ull*MiB)	
     2.9 #define	PTEPERTAB	(PTEMAPMEM/BY2PG)
    2.10 #define	SEGMAPSIZE	65536
    2.11 #define	SSEGMAPSIZE	16
     3.1--- a/sys/src/9/port/portdat.h
     3.2+++ b/sys/src/9/port/portdat.h
     3.3@@ -389,7 +389,7 @@ struct Physseg
     3.4 	ulong	attr;			/* Segment attributes */
     3.5 	char	*name;			/* Attach name */
     3.6 	uintptr	pa;			/* Physical address */
     3.7-	ulong	size;			/* Maximum segment size in pages */
     3.8+	uintptr	size;			/* Maximum segment size in bytes */
     3.9 	Page	*(*pgalloc)(Segment*, uintptr);	/* Allocation if we need it */
    3.10 	void	(*pgfree)(Page*);
    3.11 };
     4.1--- a/sys/src/9/port/portfns.h
     4.2+++ b/sys/src/9/port/portfns.h
     4.3@@ -137,7 +137,7 @@ int		iprint(char*, ...);
     4.4 void		isdir(Chan*);
     4.5 int		iseve(void);
     4.6 int		islo(void);
     4.7-Segment*	isoverlap(Proc*, uintptr, int);
     4.8+Segment*	isoverlap(Proc*, uintptr, uintptr);
     4.9 int		ispages(void*);
    4.10 int		isphysseg(char*);
    4.11 void		ixsummary(void);
    4.12@@ -302,7 +302,7 @@ void		scheddump(void);
    4.13 void		schedinit(void);
    4.14 void		(*screenputs)(char*, int);
    4.15 long		seconds(void);
    4.16-uintptr		segattach(Proc*, ulong, char *, uintptr, ulong);
    4.17+uintptr		segattach(Proc*, ulong, char *, uintptr, uintptr);
    4.18 void		segclock(uintptr);
    4.19 void		segpage(Segment*, Page*);
    4.20 int		setcolor(ulong, ulong, ulong, ulong);
     5.1--- a/sys/src/9/port/segment.c
     5.2+++ b/sys/src/9/port/segment.c
     5.3@@ -558,7 +558,7 @@ out:
     5.4 }
     5.5 
     5.6 Segment*
     5.7-isoverlap(Proc *p, uintptr va, int len)
     5.8+isoverlap(Proc *p, uintptr va, uintptr len)
     5.9 {
    5.10 	int i;
    5.11 	Segment *ns;
    5.12@@ -621,7 +621,7 @@ isphysseg(char *name)
    5.13 }
    5.14 
    5.15 uintptr
    5.16-segattach(Proc *p, ulong attr, char *name, uintptr va, ulong len)
    5.17+segattach(Proc *p, ulong attr, char *name, uintptr va, uintptr len)
    5.18 {
    5.19 	int sno;
    5.20 	Segment *s, *os;
    5.21@@ -671,13 +671,12 @@ segattach(Proc *p, ulong attr, char *nam
    5.22 				error(Enovmem);
    5.23 			va -= len;
    5.24 		}
    5.25-		va &= ~(BY2PG-1);
    5.26-	} else {
    5.27-		va &= ~(BY2PG-1);
    5.28-		if(va == 0 || va >= USTKTOP)
    5.29-			error(Ebadarg);
    5.30 	}
    5.31 
    5.32+	va &= ~(BY2PG-1);
    5.33+	if(va == 0 || (va+len) > USTKTOP || (va+len) < va)
    5.34+		error(Ebadarg);
    5.35+
    5.36 	if(isoverlap(p, va, len) != nil)
    5.37 		error(Esoverlap);
    5.38