Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 Jun 1999 15:22:01 -0500
From:      Alan Cox <alc@cs.rice.edu>
To:        Jason Evans <jasone@canonware.com>
Cc:        stable@freebsd.org
Subject:   Re: Kernel panic with mmap() and VM_STACK (fix)
Message-ID:  <19990615152201.B5893@cs.rice.edu>

next in thread | raw e-mail | index | archive | help

--9amGYk9869ThD9tj
Content-Type: text/plain; charset=us-ascii

Please try the attached patch.

Alan

--9amGYk9869ThD9tj
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="stable.patch"

Index: kern/kern_exec.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_exec.c,v
retrieving revision 1.93.2.1
diff -c -r1.93.2.1 kern_exec.c
*** kern_exec.c	1999/04/14 04:55:23	1.93.2.1
--- kern_exec.c	1999/06/15 08:30:54
***************
*** 429,435 ****
  	int error;
  	struct vmspace *vmspace = imgp->proc->p_vmspace;
  #ifdef VM_STACK
! 	caddr_t	stack_addr = (caddr_t) (USRSTACK - MAXSSIZ);
  #else
  	caddr_t	stack_addr = (caddr_t) (USRSTACK - SGROWSIZ);
  #endif
--- 429,435 ----
  	int error;
  	struct vmspace *vmspace = imgp->proc->p_vmspace;
  #ifdef VM_STACK
! 	vm_offset_t stack_addr = USRSTACK - MAXSSIZ;
  #else
  	caddr_t	stack_addr = (caddr_t) (USRSTACK - SGROWSIZ);
  #endif
***************
*** 455,462 ****
  
  	/* Allocate a new stack */
  #ifdef VM_STACK
! 	error = vm_map_stack (&vmspace->vm_map, (vm_offset_t)stack_addr,
! 			      (vm_size_t)MAXSSIZ, VM_PROT_ALL, VM_PROT_ALL, 0);
  	if (error)
  		return (error);
  
--- 455,465 ----
  
  	/* Allocate a new stack */
  #ifdef VM_STACK
! 	error = vm_map_find(&vmspace->vm_map,
! 			    NULL, 0,
! 			    &stack_addr, MAXSSIZ, FALSE,
! 			    VM_PROT_ALL, VM_PROT_ALL,
! 			    VM_MAP_STACK);
  	if (error)
  		return (error);
  
Index: vm/vm_map.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_map.c,v
retrieving revision 1.139.2.7
diff -c -r1.139.2.7 vm_map.c
*** vm_map.c	1999/06/13 04:06:41	1.139.2.7
--- vm_map.c	1999/06/15 07:50:40
***************
*** 437,442 ****
--- 437,443 ----
  	vm_map_entry_t prev_entry;
  	vm_map_entry_t temp_entry;
  	vm_object_t prev_object;
+ 	vm_offset_t avail_ssize;
  	u_char protoeflags;
  
  	if ((object != NULL) && (cow & MAP_NOFAULT)) {
***************
*** 469,475 ****
--- 470,487 ----
  	    (prev_entry->next->start < end))
  		return (KERN_NO_SPACE);
  
+ 	avail_ssize = 0;
+ 
  	protoeflags = 0;
+ 	if (cow & VM_MAP_STACK) {
+ 		vm_offset_t base;
+ 
+ 		if ((base = end - SGROWSIZ) > start) {
+ 			avail_ssize = base - start;
+ 			start = base;
+ 		}
+ 		protoeflags |= MAP_ENTRY_STACK;
+ 	}
  	if (cow & MAP_COPY_NEEDED)
  		protoeflags |= MAP_ENTRY_NEEDS_COPY;
  
***************
*** 539,549 ****
  	new_entry = vm_map_entry_create(map);
  	new_entry->start = start;
  	new_entry->end = end;
  
  	new_entry->eflags = protoeflags;
  	new_entry->object.vm_object = object;
  	new_entry->offset = offset;
- 	new_entry->avail_ssize = 0;
  
  	if (map->is_main_map) {
  		new_entry->inheritance = VM_INHERIT_DEFAULT;
--- 551,561 ----
  	new_entry = vm_map_entry_create(map);
  	new_entry->start = start;
  	new_entry->end = end;
+ 	new_entry->avail_ssize = avail_ssize;
  
  	new_entry->eflags = protoeflags;
  	new_entry->object.vm_object = object;
  	new_entry->offset = offset;
  
  	if (map->is_main_map) {
  		new_entry->inheritance = VM_INHERIT_DEFAULT;
***************
*** 567,637 ****
  
  	default_pager_convert_to_swapq(object);
  	return (KERN_SUCCESS);
- }
- 
- int
- vm_map_stack (vm_map_t map, vm_offset_t addrbos, vm_size_t max_ssize,
- 	      vm_prot_t prot, vm_prot_t max, int cow)
- {
- 	vm_map_entry_t prev_entry;
- 	vm_map_entry_t new_stack_entry;
- 	vm_size_t      init_ssize;
- 	int            rv;
- 
- 	if (VM_MIN_ADDRESS > 0 && addrbos < VM_MIN_ADDRESS)
- 		return (KERN_NO_SPACE);
- 
- 	if (max_ssize < SGROWSIZ)
- 		init_ssize = max_ssize;
- 	else
- 		init_ssize = SGROWSIZ;
- 
- 	vm_map_lock(map);
- 
- 	/* If addr is already mapped, no go */
- 	if (vm_map_lookup_entry(map, addrbos, &prev_entry)) {
- 		vm_map_unlock(map);
- 		return (KERN_NO_SPACE);
- 	}
- 
- 	/* If we can't accomodate max_ssize in the current mapping,
- 	 * no go.  However, we need to be aware that subsequent user
- 	 * mappings might map into the space we have reserved for
- 	 * stack, and currently this space is not protected.  
- 	 * 
- 	 * Hopefully we will at least detect this condition 
- 	 * when we try to grow the stack.
- 	 */
- 	if ((prev_entry->next != &map->header) &&
- 	    (prev_entry->next->start < addrbos + max_ssize)) {
- 		vm_map_unlock(map);
- 		return (KERN_NO_SPACE);
- 	}
- 
- 	/* We initially map a stack of only init_ssize.  We will
- 	 * grow as needed later.  Since this is to be a grow 
- 	 * down stack, we map at the top of the range.
- 	 *
- 	 * Note: we would normally expect prot and max to be
- 	 * VM_PROT_ALL, and cow to be 0.  Possibly we should
- 	 * eliminate these as input parameters, and just
- 	 * pass these values here in the insert call.
- 	 */
- 	rv = vm_map_insert(map, NULL, 0, addrbos + max_ssize - init_ssize,
- 	                   addrbos + max_ssize, prot, max, cow);
- 
- 	/* Now set the avail_ssize amount */
- 	if (rv == KERN_SUCCESS){
- 		new_stack_entry = prev_entry->next;
- 		if (new_stack_entry->end   != addrbos + max_ssize ||
- 		    new_stack_entry->start != addrbos + max_ssize - init_ssize)
- 			panic ("Bad entry start/end for new stack entry");
- 		else 
- 			new_stack_entry->avail_ssize = max_ssize - init_ssize;
- 	}
- 
- 	vm_map_unlock(map);
- 	return (rv);
  }
  
  /* Attempts to grow a vm stack entry.  Returns KERN_SUCCESS if the
--- 579,584 ----
Index: vm/vm_map.h
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_map.h,v
retrieving revision 1.33.2.2
diff -c -r1.33.2.2 vm_map.h
*** vm_map.h	1999/03/11 05:56:49	1.33.2.2
--- vm_map.h	1999/06/15 07:39:56
***************
*** 119,124 ****
--- 119,125 ----
  #define MAP_ENTRY_NEEDS_COPY		0x8
  #define MAP_ENTRY_NOFAULT		0x10
  #define MAP_ENTRY_USER_WIRED		0x20
+ #define MAP_ENTRY_STACK			0x40
  
  /*
   *	Maps are doubly-linked lists of map entries, kept sorted
***************
*** 296,301 ****
--- 297,303 ----
  #define MAP_COPY_NEEDED 0x1
  #define MAP_COPY_ON_WRITE 0x2
  #define MAP_NOFAULT 0x4
+ #define VM_MAP_STACK		0x20
  
  /*
   * vm_fault option flags
***************
*** 340,346 ****
  void vm_init2 __P((void));
  int vm_uiomove __P((vm_map_t, vm_object_t, off_t, int, vm_offset_t, int *));
  void vm_freeze_copyopts __P((vm_object_t, vm_pindex_t, vm_pindex_t));
- int vm_map_stack __P((vm_map_t, vm_offset_t, vm_size_t, vm_prot_t, vm_prot_t, int));
  int vm_map_growstack __P((struct proc *p, vm_offset_t addr));
  
  #endif
--- 342,347 ----
Index: vm/vm_mmap.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_mmap.c,v
retrieving revision 1.86.2.2
diff -c -r1.86.2.2 vm_mmap.c
*** vm_mmap.c	1999/05/10 17:09:25	1.86.2.2
--- vm_mmap.c	1999/06/15 07:44:24
***************
*** 1017,1022 ****
--- 1017,1026 ----
  	if ((flags & (MAP_ANON|MAP_SHARED)) == 0) {
  		docow = MAP_COPY_ON_WRITE | MAP_COPY_NEEDED;
  	}
+ #ifdef VM_STACK
+ 	if (flags & MAP_STACK)
+ 		docow |= VM_MAP_STACK;
+ #endif
  
  #if defined(VM_PROT_READ_IS_EXEC)
  	if (prot & VM_PROT_READ)
***************
*** 1030,1041 ****
  		*addr = pmap_addr_hint(object, *addr, size);
  	}
  
- #ifdef VM_STACK
- 	if (flags & MAP_STACK)
- 		rv = vm_map_stack (map, *addr, size, prot,
- 				   maxprot, docow);
- 	else
- #endif
  	rv = vm_map_find(map, object, foff, addr, size, fitit,
  			prot, maxprot, docow);
  
--- 1034,1039 ----

--9amGYk9869ThD9tj--


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19990615152201.B5893>