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.
This commit is contained in:
cinap_lenrek 2014-03-04 22:37:15 +01:00
parent 06c8a5b391
commit 316d8ad76b
5 changed files with 11 additions and 12 deletions

View file

@ -223,7 +223,7 @@ gpiomeminit(void)
seg.attr = SG_PHYSICAL; seg.attr = SG_PHYSICAL;
seg.name = "gpio"; seg.name = "gpio";
seg.pa = (VIRTIO+0x200000); seg.pa = (VIRTIO+0x200000);
seg.size = 1; seg.size = BY2PG;
addphysseg(&seg); addphysseg(&seg);
} }

View file

@ -132,7 +132,7 @@
/* /*
* virtual MMU * virtual MMU
*/ */
#define PTEMAPMEM (1024*1024) #define PTEMAPMEM (1ull*MiB)
#define PTEPERTAB (PTEMAPMEM/BY2PG) #define PTEPERTAB (PTEMAPMEM/BY2PG)
#define SEGMAPSIZE 65536 #define SEGMAPSIZE 65536
#define SSEGMAPSIZE 16 #define SSEGMAPSIZE 16

View file

@ -389,7 +389,7 @@ struct Physseg
ulong attr; /* Segment attributes */ ulong attr; /* Segment attributes */
char *name; /* Attach name */ char *name; /* Attach name */
uintptr pa; /* Physical address */ 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 */ Page *(*pgalloc)(Segment*, uintptr); /* Allocation if we need it */
void (*pgfree)(Page*); void (*pgfree)(Page*);
}; };

View file

@ -137,7 +137,7 @@ int iprint(char*, ...);
void isdir(Chan*); void isdir(Chan*);
int iseve(void); int iseve(void);
int islo(void); int islo(void);
Segment* isoverlap(Proc*, uintptr, int); Segment* isoverlap(Proc*, uintptr, uintptr);
int ispages(void*); int ispages(void*);
int isphysseg(char*); int isphysseg(char*);
void ixsummary(void); void ixsummary(void);
@ -302,7 +302,7 @@ void scheddump(void);
void schedinit(void); void schedinit(void);
void (*screenputs)(char*, int); void (*screenputs)(char*, int);
long seconds(void); long seconds(void);
uintptr segattach(Proc*, ulong, char *, uintptr, ulong); uintptr segattach(Proc*, ulong, char *, uintptr, uintptr);
void segclock(uintptr); void segclock(uintptr);
void segpage(Segment*, Page*); void segpage(Segment*, Page*);
int setcolor(ulong, ulong, ulong, ulong); int setcolor(ulong, ulong, ulong, ulong);

View file

@ -558,7 +558,7 @@ out:
} }
Segment* Segment*
isoverlap(Proc *p, uintptr va, int len) isoverlap(Proc *p, uintptr va, uintptr len)
{ {
int i; int i;
Segment *ns; Segment *ns;
@ -621,7 +621,7 @@ isphysseg(char *name)
} }
uintptr 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; int sno;
Segment *s, *os; Segment *s, *os;
@ -671,13 +671,12 @@ segattach(Proc *p, ulong attr, char *name, uintptr va, ulong len)
error(Enovmem); error(Enovmem);
va -= len; 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) if(isoverlap(p, va, len) != nil)
error(Esoverlap); error(Esoverlap);