Index: lib/libc/sys/minherit.2 =================================================================== --- lib/libc/sys/minherit.2 +++ lib/libc/sys/minherit.2 @@ -29,7 +29,7 @@ .\" .\" @(#)minherit.2 8.1 (Berkeley) 6/9/93 .\" -.Dd October 30, 2007 +.Dd July 23, 2014 .Dt MINHERIT 2 .Os .Sh NAME @@ -91,6 +91,11 @@ after the parent forks and there is no way to get the previous shared-backing-store mapping without unmapping and remapping the address space in the parent. +.It Dv INHERIT_ZERO +This option causes the address space in question to be mapped as new +anonymous pages, +which would be initialized to all zero bytes, +in the child process. .El .Sh RETURN VALUES .Rv -std minherit @@ -130,6 +135,13 @@ .Ox and then in .Fx 2.2 . +.Pp +The +.Dv INHERIT_ZERO +support first appeared in +.Ox 5.6 +and then in +.Fx 10.1 . .Sh BUGS Once you set inheritance to .Dv MAP_PRIVATE Index: sys/sys/mman.h =================================================================== --- sys/sys/mman.h +++ sys/sys/mman.h @@ -43,6 +43,7 @@ #define INHERIT_SHARE 0 #define INHERIT_COPY 1 #define INHERIT_NONE 2 +#define INHERIT_ZERO 3 #endif /* Index: sys/vm/vm.h =================================================================== --- sys/vm/vm.h +++ sys/vm/vm.h @@ -68,6 +68,7 @@ #define VM_INHERIT_SHARE ((vm_inherit_t) 0) #define VM_INHERIT_COPY ((vm_inherit_t) 1) #define VM_INHERIT_NONE ((vm_inherit_t) 2) +#define VM_INHERIT_ZERO ((vm_inherit_t) 3) #define VM_INHERIT_DEFAULT VM_INHERIT_COPY typedef u_char vm_prot_t; /* protection codes */ Index: sys/vm/vm_map.c =================================================================== --- sys/vm/vm_map.c +++ sys/vm/vm_map.c @@ -2228,6 +2228,7 @@ case VM_INHERIT_NONE: case VM_INHERIT_COPY: case VM_INHERIT_SHARE: + case VM_INHERIT_ZERO: break; default: return (KERN_INVALID_ARGUMENT); @@ -3343,6 +3344,31 @@ vm_map_copy_entry(old_map, new_map, old_entry, new_entry, fork_charge); break; + + case VM_INHERIT_ZERO: + /* + * Clone the entry and link into the map. + */ + new_entry = vm_map_entry_create(new_map); + *new_entry = *old_entry; + /* + * Copied entry is COW over the old object. + */ + new_entry->eflags &= ~(MAP_ENTRY_USER_WIRED | + MAP_ENTRY_IN_TRANSITION | MAP_ENTRY_VN_WRITECNT); + new_entry->wiring_thread = NULL; + new_entry->wired_count = 0; + new_entry->object.vm_object = NULL; + new_entry->cred = NULL; + vm_map_entry_link(new_map, new_map->header.prev, + new_entry); + vmspace_map_entry_forked(vm1, vm2, new_entry); + if (old_entry->cred != NULL) { + new_entry->cred = curthread->td_ucred; + crhold(new_entry->cred); + *fork_charge += (new_entry->end - new_entry->start); + } + break; } old_entry = old_entry->next; }