From owner-freebsd-stable Tue Jun 15 13:22:18 1999 Delivered-To: freebsd-stable@freebsd.org Received: from cs.rice.edu (cs.rice.edu [128.42.1.30]) by hub.freebsd.org (Postfix) with ESMTP id 196C315429 for ; Tue, 15 Jun 1999 13:22:13 -0700 (PDT) (envelope-from alc@cs.rice.edu) Received: (from alc@localhost) by cs.rice.edu (8.9.0/8.9.0) id PAA06945; Tue, 15 Jun 1999 15:22:01 -0500 (CDT) Date: Tue, 15 Jun 1999 15:22:01 -0500 From: Alan Cox To: Jason Evans Cc: stable@freebsd.org Subject: Re: Kernel panic with mmap() and VM_STACK (fix) Message-ID: <19990615152201.B5893@cs.rice.edu> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary=9amGYk9869ThD9tj X-Mailer: Mutt 0.95.5us Sender: owner-freebsd-stable@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --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