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
[-- Attachment #1 --]
Please try the attached patch.
Alan
[-- Attachment #2 --]
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 ----
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19990615152201.B5893>
