Subject: Re: found anoncvs problem . . .
To: None <chuck@maria.wustl.edu>
From: Niklas Hallqvist <niklas@appli.se>
List: port-m68k
Date: 12/03/1995 11:10:18
[ port-m68kers, this is a reply to a message on misc@openbsd.org.
  I've tried to keep enough context to make it understandable.  -NH ]

>>>>> "Chuck" == Chuck Cranor <chuck@maria.wustl.edu> writes:

Chuck>     the only thing that could cause that sequence is trying to
Chuck> allocate memory in a full map with kmem_alloc_wait (the process
Chuck> goes to sleep waiting for free space).  the map in question is
Chuck> pt_map, as defined in pmap.c.  the pt_map is used by pmap to
Chuck> reserve vm space for user page tables.  if you look at the
Chuck> mvme68k pmap.c (which is based on the hp300 pmap) you will note
Chuck> the following bit of code in pmap_init():

Chuck> /* NOTE: M68K_PTMAXSIZE = 0x70000000, M68K_MAX_PTSIZE = 0x400000 */
Chuck> /* maxproc = maxusers_from_config*16 + 20 */
Chuck> 	s = min(M68K_PTMAXSIZE, maxproc*M68K_MAX_PTSIZE);
Chuck> 	addr2 = addr + s;
Chuck> 	rv = vm_map_find(kernel_map, NULL, 0, &addr, s, TRUE);
Chuck> 	if (rv != KERN_SUCCESS)
Chuck> 		panic("pmap_init: cannot allocate space for PT map");
Chuck> 	pmap_reference(vm_map_pmap(kernel_map));
Chuck> 	pt_map = vm_map_create(vm_map_pmap(kernel_map), addr, addr2, TRUE);

Chuck>     what that code does is reserve space in the kernel address
Chuck> space for the user page tables.  the size of the space reserved
Chuck> depends on "maxusers" as specified in config.

Chuck>     here is the problem: i had set maxusers to "64" ... that
Chuck> means that maxproc is 64*16 + 20, or 1044.  "s" gets the size
Chuck> of the space reserved.

Chuck> 	s = min(M68K_PTMAXSIZE, maxproc*M68K_MAX_PTSIZE);
Chuck>  s = min(0x70000000, 1044*0x400000);
Chuck>  s = min(0x70000000, 0x105000000);
Chuck>  s = 0x70000000;

Chuck>      but wait!  0x105000000 overflows the 32 bit interger and
Chuck> gets silently truncated to 0x5000000.  Since each process has
Chuck> one pmap and each pmap needs 0x400000 (M68K_MAX_PTSIZE) we are
Chuck> only reserving enough room for 0x5000000/0x400000 processes
Chuck> (that is 20 processes!).  oops.

Chuck>     i think there should be something somehere to detect this
Chuck> overflow so that others don't get bit by it (i'm not a big fan
Chuck> of silent failure).  i will try and generate a patch to detect
Chuck> this problem.  in the mean time reducing maxusers to 26 solves
Chuck> the problem.  this may effect m68k ports that use pmaps based
Chuck> on the hp300 pmap.

My proposal is to rearrange the assignment to look like:

	s = M68K_PTMAXSIZE / M68K_MAX_PTSIZE < maxproc ?
	    M68K_PTMAXSIZE : maxproc * M68K_MAX_PTSIZE ;

That way all possibilities of overflow goes awy, unless
M68K_MAX_PTSIZE is zero, of course.  But that case can easily be
discarded, as that would mean the port was broken anyway...

I've checked this in the amiga tree (i.e. the OpenBSD one).

Niklas