2005-01-07 02:29:27 +00:00
|
|
|
/*-
|
1994-05-24 10:09:53 +00:00
|
|
|
* Copyright (c) 1988 University of Utah.
|
|
|
|
* Copyright (c) 1991, 1993
|
|
|
|
* The Regents of the University of California. All rights reserved.
|
|
|
|
*
|
|
|
|
* This code is derived from software contributed to Berkeley by
|
|
|
|
* the Systems Programming Group of the University of Utah Computer
|
|
|
|
* Science Department.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 4. Neither the name of the University nor the names of its contributors
|
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
* from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$
|
|
|
|
*
|
|
|
|
* @(#)vm_mmap.c 8.4 (Berkeley) 1/12/94
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Mapped file (mmap) interface to VM
|
|
|
|
*/
|
|
|
|
|
2003-06-11 23:50:51 +00:00
|
|
|
#include <sys/cdefs.h>
|
|
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
|
1997-12-16 17:40:42 +00:00
|
|
|
#include "opt_compat.h"
|
2006-03-26 12:20:54 +00:00
|
|
|
#include "opt_hwpmc_hooks.h"
|
2015-03-21 17:56:55 +00:00
|
|
|
#include "opt_vm.h"
|
1996-12-22 23:17:09 +00:00
|
|
|
|
1994-05-24 10:09:53 +00:00
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/systm.h>
|
2014-03-16 10:55:57 +00:00
|
|
|
#include <sys/capsicum.h>
|
2011-08-11 12:30:23 +00:00
|
|
|
#include <sys/kernel.h>
|
2001-05-01 08:13:21 +00:00
|
|
|
#include <sys/lock.h>
|
2001-05-19 01:28:09 +00:00
|
|
|
#include <sys/mutex.h>
|
1995-11-12 06:43:28 +00:00
|
|
|
#include <sys/sysproto.h>
|
1994-05-24 10:09:53 +00:00
|
|
|
#include <sys/filedesc.h>
|
2006-11-06 13:42:10 +00:00
|
|
|
#include <sys/priv.h>
|
1994-05-24 10:09:53 +00:00
|
|
|
#include <sys/proc.h>
|
2013-09-19 18:53:42 +00:00
|
|
|
#include <sys/procctl.h>
|
2011-04-05 20:23:59 +00:00
|
|
|
#include <sys/racct.h>
|
2002-06-26 00:29:28 +00:00
|
|
|
#include <sys/resource.h>
|
|
|
|
#include <sys/resourcevar.h>
|
2013-03-09 02:32:23 +00:00
|
|
|
#include <sys/rwlock.h>
|
2012-12-18 07:35:01 +00:00
|
|
|
#include <sys/sysctl.h>
|
1994-05-24 10:09:53 +00:00
|
|
|
#include <sys/vnode.h>
|
1997-03-23 03:37:54 +00:00
|
|
|
#include <sys/fcntl.h>
|
1994-05-24 10:09:53 +00:00
|
|
|
#include <sys/file.h>
|
|
|
|
#include <sys/mman.h>
|
2004-03-18 20:58:51 +00:00
|
|
|
#include <sys/mount.h>
|
1994-05-24 10:09:53 +00:00
|
|
|
#include <sys/conf.h>
|
1998-05-19 07:13:21 +00:00
|
|
|
#include <sys/stat.h>
|
2013-09-19 18:53:42 +00:00
|
|
|
#include <sys/syscallsubr.h>
|
2009-09-20 12:40:56 +00:00
|
|
|
#include <sys/sysent.h>
|
1995-12-07 12:48:31 +00:00
|
|
|
#include <sys/vmmeter.h>
|
1994-05-24 10:09:53 +00:00
|
|
|
|
2006-10-22 11:52:19 +00:00
|
|
|
#include <security/mac/mac_framework.h>
|
|
|
|
|
1994-05-24 10:09:53 +00:00
|
|
|
#include <vm/vm.h>
|
1995-12-07 12:48:31 +00:00
|
|
|
#include <vm/vm_param.h>
|
|
|
|
#include <vm/pmap.h>
|
|
|
|
#include <vm/vm_map.h>
|
|
|
|
#include <vm/vm_object.h>
|
1999-01-21 08:29:12 +00:00
|
|
|
#include <vm/vm_page.h>
|
1994-05-24 10:09:53 +00:00
|
|
|
#include <vm/vm_pager.h>
|
1995-03-16 18:17:34 +00:00
|
|
|
#include <vm/vm_pageout.h>
|
1995-12-07 12:48:31 +00:00
|
|
|
#include <vm/vm_extern.h>
|
1996-05-19 07:36:50 +00:00
|
|
|
#include <vm/vm_page.h>
|
2012-02-23 21:07:16 +00:00
|
|
|
#include <vm/vnode_pager.h>
|
1994-05-24 10:09:53 +00:00
|
|
|
|
2006-03-26 12:20:54 +00:00
|
|
|
#ifdef HWPMC_HOOKS
|
|
|
|
#include <sys/pmckern.h>
|
|
|
|
#endif
|
|
|
|
|
2012-12-18 07:35:01 +00:00
|
|
|
int old_mlock = 0;
|
2014-06-28 03:56:17 +00:00
|
|
|
SYSCTL_INT(_vm, OID_AUTO, old_mlock, CTLFLAG_RWTUN, &old_mlock, 0,
|
2012-12-18 07:35:01 +00:00
|
|
|
"Do not apply RLIMIT_MEMLOCK on mlockall");
|
|
|
|
|
2013-09-09 18:11:59 +00:00
|
|
|
#ifdef MAP_32BIT
|
|
|
|
#define MAP_32BIT_MAX_ADDR ((vm_offset_t)1 << 31)
|
1995-11-12 06:43:28 +00:00
|
|
|
#endif
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
|
2013-09-09 18:11:59 +00:00
|
|
|
#ifndef _SYS_SYSPROTO_H_
|
|
|
|
struct sbrk_args {
|
|
|
|
int incr;
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2001-08-31 01:26:30 +00:00
|
|
|
/*
|
|
|
|
* MPSAFE
|
|
|
|
*/
|
1994-05-24 10:09:53 +00:00
|
|
|
/* ARGSUSED */
|
|
|
|
int
|
2011-09-16 13:58:51 +00:00
|
|
|
sys_sbrk(td, uap)
|
2001-09-12 08:38:13 +00:00
|
|
|
struct thread *td;
|
1994-05-24 10:09:53 +00:00
|
|
|
struct sbrk_args *uap;
|
|
|
|
{
|
|
|
|
/* Not yet implemented */
|
|
|
|
return (EOPNOTSUPP);
|
|
|
|
}
|
|
|
|
|
1995-11-12 06:43:28 +00:00
|
|
|
#ifndef _SYS_SYSPROTO_H_
|
1994-05-24 10:09:53 +00:00
|
|
|
struct sstk_args {
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
int incr;
|
1994-05-24 10:09:53 +00:00
|
|
|
};
|
1995-11-12 06:43:28 +00:00
|
|
|
#endif
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
|
2001-08-31 01:26:30 +00:00
|
|
|
/*
|
|
|
|
* MPSAFE
|
|
|
|
*/
|
1994-05-24 10:09:53 +00:00
|
|
|
/* ARGSUSED */
|
|
|
|
int
|
2011-09-16 13:58:51 +00:00
|
|
|
sys_sstk(td, uap)
|
2001-09-12 08:38:13 +00:00
|
|
|
struct thread *td;
|
1994-05-24 10:09:53 +00:00
|
|
|
struct sstk_args *uap;
|
|
|
|
{
|
|
|
|
/* Not yet implemented */
|
|
|
|
return (EOPNOTSUPP);
|
|
|
|
}
|
|
|
|
|
2004-06-11 11:16:26 +00:00
|
|
|
#if defined(COMPAT_43)
|
1995-11-12 06:43:28 +00:00
|
|
|
#ifndef _SYS_SYSPROTO_H_
|
1994-05-24 10:09:53 +00:00
|
|
|
struct getpagesize_args {
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
int dummy;
|
1994-05-24 10:09:53 +00:00
|
|
|
};
|
1995-11-12 06:43:28 +00:00
|
|
|
#endif
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
|
1994-05-24 10:09:53 +00:00
|
|
|
int
|
2001-09-12 08:38:13 +00:00
|
|
|
ogetpagesize(td, uap)
|
|
|
|
struct thread *td;
|
1994-05-24 10:09:53 +00:00
|
|
|
struct getpagesize_args *uap;
|
|
|
|
{
|
2001-07-04 16:20:28 +00:00
|
|
|
/* MP SAFE */
|
2001-09-12 08:38:13 +00:00
|
|
|
td->td_retval[0] = PAGE_SIZE;
|
1994-05-24 10:09:53 +00:00
|
|
|
return (0);
|
|
|
|
}
|
2004-06-11 11:16:26 +00:00
|
|
|
#endif /* COMPAT_43 */
|
1994-05-24 10:09:53 +00:00
|
|
|
|
1997-08-30 18:50:06 +00:00
|
|
|
|
2003-12-08 02:45:45 +00:00
|
|
|
/*
|
1997-08-30 18:50:06 +00:00
|
|
|
* Memory Map (mmap) system call. Note that the file offset
|
|
|
|
* and address are allowed to be NOT page aligned, though if
|
|
|
|
* the MAP_FIXED flag it set, both must have the same remainder
|
|
|
|
* modulo the PAGE_SIZE (POSIX 1003.1b). If the address is not
|
|
|
|
* page-aligned, the actual mapping starts at trunc_page(addr)
|
|
|
|
* and the return value is adjusted up by the page offset.
|
1999-09-21 05:00:48 +00:00
|
|
|
*
|
|
|
|
* Generally speaking, only character devices which are themselves
|
|
|
|
* memory-based, such as a video framebuffer, can be mmap'd. Otherwise
|
|
|
|
* there would be no cache coherency between a descriptor and a VM mapping
|
|
|
|
* both to the same character device.
|
1997-08-30 18:50:06 +00:00
|
|
|
*/
|
1995-11-12 06:43:28 +00:00
|
|
|
#ifndef _SYS_SYSPROTO_H_
|
1994-05-24 10:09:53 +00:00
|
|
|
struct mmap_args {
|
1997-12-31 02:35:29 +00:00
|
|
|
void *addr;
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
size_t len;
|
|
|
|
int prot;
|
|
|
|
int flags;
|
|
|
|
int fd;
|
|
|
|
long pad;
|
|
|
|
off_t pos;
|
1994-05-24 10:09:53 +00:00
|
|
|
};
|
1995-11-12 06:43:28 +00:00
|
|
|
#endif
|
1994-05-24 10:09:53 +00:00
|
|
|
|
2001-08-31 01:26:30 +00:00
|
|
|
/*
|
|
|
|
* MPSAFE
|
|
|
|
*/
|
1994-05-24 10:09:53 +00:00
|
|
|
int
|
2011-09-16 13:58:51 +00:00
|
|
|
sys_mmap(td, uap)
|
2001-09-12 08:38:13 +00:00
|
|
|
struct thread *td;
|
2001-07-04 19:00:13 +00:00
|
|
|
struct mmap_args *uap;
|
1994-05-24 10:09:53 +00:00
|
|
|
{
|
2004-02-27 22:02:15 +00:00
|
|
|
struct file *fp;
|
1994-05-24 10:09:53 +00:00
|
|
|
vm_offset_t addr;
|
1996-03-02 17:14:09 +00:00
|
|
|
vm_size_t size, pageoff;
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
vm_prot_t cap_maxprot;
|
2014-09-15 17:20:13 +00:00
|
|
|
int align, error, flags, prot;
|
1997-08-30 18:50:06 +00:00
|
|
|
off_t pos;
|
2001-09-12 08:38:13 +00:00
|
|
|
struct vmspace *vms = td->td_proc->p_vmspace;
|
2011-08-11 12:30:23 +00:00
|
|
|
cap_rights_t rights;
|
1994-05-24 10:09:53 +00:00
|
|
|
|
1997-08-30 18:50:06 +00:00
|
|
|
addr = (vm_offset_t) uap->addr;
|
|
|
|
size = uap->len;
|
2014-09-15 17:20:13 +00:00
|
|
|
prot = uap->prot;
|
1994-05-24 10:09:53 +00:00
|
|
|
flags = uap->flags;
|
1997-08-30 18:50:06 +00:00
|
|
|
pos = uap->pos;
|
|
|
|
|
2002-01-13 11:58:06 +00:00
|
|
|
fp = NULL;
|
2009-09-27 14:49:51 +00:00
|
|
|
|
2014-10-18 12:28:51 +00:00
|
|
|
/*
|
|
|
|
* Ignore old flags that used to be defined but did not do anything.
|
|
|
|
*/
|
2014-12-05 15:24:42 +00:00
|
|
|
flags &= ~(MAP_RESERVED0020 | MAP_RESERVED0040);
|
2014-10-18 12:28:51 +00:00
|
|
|
|
2012-08-14 11:47:07 +00:00
|
|
|
/*
|
|
|
|
* Enforce the constraints.
|
|
|
|
* Mapping of length 0 is only allowed for old binaries.
|
|
|
|
* Anonymous mapping shall specify -1 as filedescriptor and
|
|
|
|
* zero position for new code. Be nice to ancient a.out
|
|
|
|
* binaries and correct pos for anonymous mapping, since old
|
|
|
|
* ld.so sometimes issues anonymous map requests with non-zero
|
|
|
|
* pos.
|
|
|
|
*/
|
|
|
|
if (!SV_CURPROC_FLAG(SV_AOUT)) {
|
|
|
|
if ((uap->len == 0 && curproc->p_osrel >= P_OSREL_MAP_ANON) ||
|
|
|
|
((flags & MAP_ANON) != 0 && (uap->fd != -1 || pos != 0)))
|
|
|
|
return (EINVAL);
|
|
|
|
} else {
|
|
|
|
if ((flags & MAP_ANON) != 0)
|
|
|
|
pos = 0;
|
|
|
|
}
|
1996-03-02 17:14:09 +00:00
|
|
|
|
1999-01-06 23:05:42 +00:00
|
|
|
if (flags & MAP_STACK) {
|
|
|
|
if ((uap->fd != -1) ||
|
|
|
|
((prot & (PROT_READ | PROT_WRITE)) != (PROT_READ | PROT_WRITE)))
|
|
|
|
return (EINVAL);
|
|
|
|
flags |= MAP_ANON;
|
|
|
|
pos = 0;
|
1999-01-26 02:49:52 +00:00
|
|
|
}
|
2014-10-18 12:28:51 +00:00
|
|
|
if ((flags & ~(MAP_SHARED | MAP_PRIVATE | MAP_FIXED | MAP_HASSEMAPHORE |
|
|
|
|
MAP_STACK | MAP_NOSYNC | MAP_ANON | MAP_EXCL | MAP_NOCORE |
|
|
|
|
MAP_PREFAULT_READ |
|
2014-09-15 17:20:13 +00:00
|
|
|
#ifdef MAP_32BIT
|
|
|
|
MAP_32BIT |
|
|
|
|
#endif
|
|
|
|
MAP_ALIGNMENT_MASK)) != 0)
|
|
|
|
return (EINVAL);
|
2014-06-19 05:00:39 +00:00
|
|
|
if ((flags & (MAP_EXCL | MAP_FIXED)) == MAP_EXCL)
|
|
|
|
return (EINVAL);
|
The vm_mmap_cdev() explicitely converts absence of both MAP_SHARED and
MAP_PRIVATE flags to MAP_SHARED. Apparently, some code in tree, in
particular, libgeom, relied on this behaviour, see r271721. For
regular file types, the absence of the flags is interpreted as
MAP_PRIVATE, and libc nlist used this (fixed in r271723).
Allow the implicit flags for legacy binaries. Bump __FreeBSD_version
to get the ABI note on new binaries to check for in mmap code.
Remove the test for presence of one of the MAP_ANON, MAP_SHARED or
MAP_PRIVATE flags before fget_mmap(). For MAP_ANON, we already verify
that passed fd == -1. For fd != -1, test after fget_mmap() (for newer
binaries) covers the case.
Reported by: bdrewery, pho
Reviewed by: jhb
Sponsored by: The FreeBSD Foundation
2014-09-17 21:04:50 +00:00
|
|
|
if ((flags & (MAP_SHARED | MAP_PRIVATE)) == (MAP_SHARED | MAP_PRIVATE))
|
2014-09-15 17:20:13 +00:00
|
|
|
return (EINVAL);
|
|
|
|
if (prot != PROT_NONE &&
|
|
|
|
(prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) != 0)
|
|
|
|
return (EINVAL);
|
1999-01-26 02:49:52 +00:00
|
|
|
|
1996-03-02 17:14:09 +00:00
|
|
|
/*
|
1997-08-30 18:50:06 +00:00
|
|
|
* Align the file position to a page boundary,
|
|
|
|
* and save its page offset component.
|
1996-03-02 17:14:09 +00:00
|
|
|
*/
|
1997-08-30 18:50:06 +00:00
|
|
|
pageoff = (pos & PAGE_MASK);
|
|
|
|
pos -= pageoff;
|
|
|
|
|
|
|
|
/* Adjust size for rounding (on both ends). */
|
|
|
|
size += pageoff; /* low end... */
|
|
|
|
size = (vm_size_t) round_page(size); /* hi end */
|
1996-03-02 17:14:09 +00:00
|
|
|
|
2013-08-16 21:13:55 +00:00
|
|
|
/* Ensure alignment is at least a page and fits in a pointer. */
|
|
|
|
align = flags & MAP_ALIGNMENT_MASK;
|
|
|
|
if (align != 0 && align != MAP_ALIGNED_SUPER &&
|
|
|
|
(align >> MAP_ALIGNMENT_SHIFT >= sizeof(void *) * NBBY ||
|
|
|
|
align >> MAP_ALIGNMENT_SHIFT < PAGE_SHIFT))
|
|
|
|
return (EINVAL);
|
|
|
|
|
1994-05-24 10:09:53 +00:00
|
|
|
/*
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
* Check for illegal addresses. Watch out for address wrap... Note
|
|
|
|
* that VM_*_ADDRESS are not constants due to casts (argh).
|
1994-05-24 10:09:53 +00:00
|
|
|
*/
|
|
|
|
if (flags & MAP_FIXED) {
|
1997-08-30 18:50:06 +00:00
|
|
|
/*
|
|
|
|
* The specified address must have the same remainder
|
|
|
|
* as the file offset taken modulo PAGE_SIZE, so it
|
|
|
|
* should be aligned after adjustment by pageoff.
|
|
|
|
*/
|
|
|
|
addr -= pageoff;
|
|
|
|
if (addr & PAGE_MASK)
|
|
|
|
return (EINVAL);
|
2009-09-27 14:49:51 +00:00
|
|
|
|
1997-08-30 18:50:06 +00:00
|
|
|
/* Address range must be all in user VM space. */
|
2002-09-21 22:07:17 +00:00
|
|
|
if (addr < vm_map_min(&vms->vm_map) ||
|
|
|
|
addr + size > vm_map_max(&vms->vm_map))
|
1994-05-24 10:09:53 +00:00
|
|
|
return (EINVAL);
|
1994-08-04 03:06:48 +00:00
|
|
|
if (addr + size < addr)
|
1994-05-24 10:09:53 +00:00
|
|
|
return (EINVAL);
|
2013-09-09 18:11:59 +00:00
|
|
|
#ifdef MAP_32BIT
|
|
|
|
if (flags & MAP_32BIT && addr + size > MAP_32BIT_MAX_ADDR)
|
|
|
|
return (EINVAL);
|
|
|
|
} else if (flags & MAP_32BIT) {
|
|
|
|
/*
|
|
|
|
* For MAP_32BIT, override the hint if it is too high and
|
|
|
|
* do not bother moving the mapping past the heap (since
|
|
|
|
* the heap is usually above 2GB).
|
|
|
|
*/
|
|
|
|
if (addr + size > MAP_32BIT_MAX_ADDR)
|
|
|
|
addr = 0;
|
|
|
|
#endif
|
2004-02-04 21:52:57 +00:00
|
|
|
} else {
|
2010-12-04 17:41:58 +00:00
|
|
|
/*
|
|
|
|
* XXX for non-fixed mappings where no hint is provided or
|
|
|
|
* the hint would fall in the potential heap space,
|
|
|
|
* place it after the end of the largest possible heap.
|
|
|
|
*
|
|
|
|
* There should really be a pmap call to determine a reasonable
|
|
|
|
* location.
|
|
|
|
*/
|
2004-02-04 21:52:57 +00:00
|
|
|
PROC_LOCK(td->td_proc);
|
|
|
|
if (addr == 0 ||
|
|
|
|
(addr >= round_page((vm_offset_t)vms->vm_taddr) &&
|
|
|
|
addr < round_page((vm_offset_t)vms->vm_daddr +
|
2015-06-10 10:48:12 +00:00
|
|
|
lim_max_proc(td->td_proc, RLIMIT_DATA))))
|
2004-02-04 21:52:57 +00:00
|
|
|
addr = round_page((vm_offset_t)vms->vm_daddr +
|
2015-06-10 10:48:12 +00:00
|
|
|
lim_max_proc(td->td_proc, RLIMIT_DATA));
|
2004-02-04 21:52:57 +00:00
|
|
|
PROC_UNLOCK(td->td_proc);
|
|
|
|
}
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
if (size == 0) {
|
|
|
|
/*
|
|
|
|
* Return success without mapping anything for old
|
|
|
|
* binaries that request a page-aligned mapping of
|
|
|
|
* length 0. For modern binaries, this function
|
|
|
|
* returns an error earlier.
|
|
|
|
*/
|
|
|
|
error = 0;
|
|
|
|
} else if (flags & MAP_ANON) {
|
2004-03-01 02:44:33 +00:00
|
|
|
/*
|
|
|
|
* Mapping blank space is trivial.
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
*
|
|
|
|
* This relies on VM_PROT_* matching PROT_*.
|
2004-03-01 02:44:33 +00:00
|
|
|
*/
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
error = vm_mmap_object(&vms->vm_map, &addr, size, prot,
|
|
|
|
VM_PROT_ALL, flags, NULL, pos, FALSE, td);
|
2004-03-01 02:44:33 +00:00
|
|
|
} else {
|
1994-05-24 10:09:53 +00:00
|
|
|
/*
|
2011-08-11 12:30:23 +00:00
|
|
|
* Mapping file, get fp for validation and don't let the
|
|
|
|
* descriptor disappear on us if we block. Check capability
|
|
|
|
* rights, but also return the maximum rights to be combined
|
|
|
|
* with maxprot later.
|
1994-05-24 10:09:53 +00:00
|
|
|
*/
|
Change the cap_rights_t type from uint64_t to a structure that we can extend
in the future in a backward compatible (API and ABI) way.
The cap_rights_t represents capability rights. We used to use one bit to
represent one right, but we are running out of spare bits. Currently the new
structure provides place for 114 rights (so 50 more than the previous
cap_rights_t), but it is possible to grow the structure to hold at least 285
rights, although we can make it even larger if 285 rights won't be enough.
The structure definition looks like this:
struct cap_rights {
uint64_t cr_rights[CAP_RIGHTS_VERSION + 2];
};
The initial CAP_RIGHTS_VERSION is 0.
The top two bits in the first element of the cr_rights[] array contain total
number of elements in the array - 2. This means if those two bits are equal to
0, we have 2 array elements.
The top two bits in all remaining array elements should be 0.
The next five bits in all array elements contain array index. Only one bit is
used and bit position in this five-bits range defines array index. This means
there can be at most five array elements in the future.
To define new right the CAPRIGHT() macro must be used. The macro takes two
arguments - an array index and a bit to set, eg.
#define CAP_PDKILL CAPRIGHT(1, 0x0000000000000800ULL)
We still support aliases that combine few rights, but the rights have to belong
to the same array element, eg:
#define CAP_LOOKUP CAPRIGHT(0, 0x0000000000000400ULL)
#define CAP_FCHMOD CAPRIGHT(0, 0x0000000000002000ULL)
#define CAP_FCHMODAT (CAP_FCHMOD | CAP_LOOKUP)
There is new API to manage the new cap_rights_t structure:
cap_rights_t *cap_rights_init(cap_rights_t *rights, ...);
void cap_rights_set(cap_rights_t *rights, ...);
void cap_rights_clear(cap_rights_t *rights, ...);
bool cap_rights_is_set(const cap_rights_t *rights, ...);
bool cap_rights_is_valid(const cap_rights_t *rights);
void cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src);
void cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src);
bool cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little);
Capability rights to the cap_rights_init(), cap_rights_set(),
cap_rights_clear() and cap_rights_is_set() functions are provided by
separating them with commas, eg:
cap_rights_t rights;
cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_FSTAT);
There is no need to terminate the list of rights, as those functions are
actually macros that take care of the termination, eg:
#define cap_rights_set(rights, ...) \
__cap_rights_set((rights), __VA_ARGS__, 0ULL)
void __cap_rights_set(cap_rights_t *rights, ...);
Thanks to using one bit as an array index we can assert in those functions that
there are no two rights belonging to different array elements provided
together. For example this is illegal and will be detected, because CAP_LOOKUP
belongs to element 0 and CAP_PDKILL to element 1:
cap_rights_init(&rights, CAP_LOOKUP | CAP_PDKILL);
Providing several rights that belongs to the same array's element this way is
correct, but is not advised. It should only be used for aliases definition.
This commit also breaks compatibility with some existing Capsicum system calls,
but I see no other way to do that. This should be fine as Capsicum is still
experimental and this change is not going to 9.x.
Sponsored by: The FreeBSD Foundation
2013-09-05 00:09:56 +00:00
|
|
|
cap_rights_init(&rights, CAP_MMAP);
|
2011-08-11 12:30:23 +00:00
|
|
|
if (prot & PROT_READ)
|
Change the cap_rights_t type from uint64_t to a structure that we can extend
in the future in a backward compatible (API and ABI) way.
The cap_rights_t represents capability rights. We used to use one bit to
represent one right, but we are running out of spare bits. Currently the new
structure provides place for 114 rights (so 50 more than the previous
cap_rights_t), but it is possible to grow the structure to hold at least 285
rights, although we can make it even larger if 285 rights won't be enough.
The structure definition looks like this:
struct cap_rights {
uint64_t cr_rights[CAP_RIGHTS_VERSION + 2];
};
The initial CAP_RIGHTS_VERSION is 0.
The top two bits in the first element of the cr_rights[] array contain total
number of elements in the array - 2. This means if those two bits are equal to
0, we have 2 array elements.
The top two bits in all remaining array elements should be 0.
The next five bits in all array elements contain array index. Only one bit is
used and bit position in this five-bits range defines array index. This means
there can be at most five array elements in the future.
To define new right the CAPRIGHT() macro must be used. The macro takes two
arguments - an array index and a bit to set, eg.
#define CAP_PDKILL CAPRIGHT(1, 0x0000000000000800ULL)
We still support aliases that combine few rights, but the rights have to belong
to the same array element, eg:
#define CAP_LOOKUP CAPRIGHT(0, 0x0000000000000400ULL)
#define CAP_FCHMOD CAPRIGHT(0, 0x0000000000002000ULL)
#define CAP_FCHMODAT (CAP_FCHMOD | CAP_LOOKUP)
There is new API to manage the new cap_rights_t structure:
cap_rights_t *cap_rights_init(cap_rights_t *rights, ...);
void cap_rights_set(cap_rights_t *rights, ...);
void cap_rights_clear(cap_rights_t *rights, ...);
bool cap_rights_is_set(const cap_rights_t *rights, ...);
bool cap_rights_is_valid(const cap_rights_t *rights);
void cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src);
void cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src);
bool cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little);
Capability rights to the cap_rights_init(), cap_rights_set(),
cap_rights_clear() and cap_rights_is_set() functions are provided by
separating them with commas, eg:
cap_rights_t rights;
cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_FSTAT);
There is no need to terminate the list of rights, as those functions are
actually macros that take care of the termination, eg:
#define cap_rights_set(rights, ...) \
__cap_rights_set((rights), __VA_ARGS__, 0ULL)
void __cap_rights_set(cap_rights_t *rights, ...);
Thanks to using one bit as an array index we can assert in those functions that
there are no two rights belonging to different array elements provided
together. For example this is illegal and will be detected, because CAP_LOOKUP
belongs to element 0 and CAP_PDKILL to element 1:
cap_rights_init(&rights, CAP_LOOKUP | CAP_PDKILL);
Providing several rights that belongs to the same array's element this way is
correct, but is not advised. It should only be used for aliases definition.
This commit also breaks compatibility with some existing Capsicum system calls,
but I see no other way to do that. This should be fine as Capsicum is still
experimental and this change is not going to 9.x.
Sponsored by: The FreeBSD Foundation
2013-09-05 00:09:56 +00:00
|
|
|
cap_rights_set(&rights, CAP_MMAP_R);
|
2011-08-11 12:30:23 +00:00
|
|
|
if ((flags & MAP_SHARED) != 0) {
|
|
|
|
if (prot & PROT_WRITE)
|
Change the cap_rights_t type from uint64_t to a structure that we can extend
in the future in a backward compatible (API and ABI) way.
The cap_rights_t represents capability rights. We used to use one bit to
represent one right, but we are running out of spare bits. Currently the new
structure provides place for 114 rights (so 50 more than the previous
cap_rights_t), but it is possible to grow the structure to hold at least 285
rights, although we can make it even larger if 285 rights won't be enough.
The structure definition looks like this:
struct cap_rights {
uint64_t cr_rights[CAP_RIGHTS_VERSION + 2];
};
The initial CAP_RIGHTS_VERSION is 0.
The top two bits in the first element of the cr_rights[] array contain total
number of elements in the array - 2. This means if those two bits are equal to
0, we have 2 array elements.
The top two bits in all remaining array elements should be 0.
The next five bits in all array elements contain array index. Only one bit is
used and bit position in this five-bits range defines array index. This means
there can be at most five array elements in the future.
To define new right the CAPRIGHT() macro must be used. The macro takes two
arguments - an array index and a bit to set, eg.
#define CAP_PDKILL CAPRIGHT(1, 0x0000000000000800ULL)
We still support aliases that combine few rights, but the rights have to belong
to the same array element, eg:
#define CAP_LOOKUP CAPRIGHT(0, 0x0000000000000400ULL)
#define CAP_FCHMOD CAPRIGHT(0, 0x0000000000002000ULL)
#define CAP_FCHMODAT (CAP_FCHMOD | CAP_LOOKUP)
There is new API to manage the new cap_rights_t structure:
cap_rights_t *cap_rights_init(cap_rights_t *rights, ...);
void cap_rights_set(cap_rights_t *rights, ...);
void cap_rights_clear(cap_rights_t *rights, ...);
bool cap_rights_is_set(const cap_rights_t *rights, ...);
bool cap_rights_is_valid(const cap_rights_t *rights);
void cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src);
void cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src);
bool cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little);
Capability rights to the cap_rights_init(), cap_rights_set(),
cap_rights_clear() and cap_rights_is_set() functions are provided by
separating them with commas, eg:
cap_rights_t rights;
cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_FSTAT);
There is no need to terminate the list of rights, as those functions are
actually macros that take care of the termination, eg:
#define cap_rights_set(rights, ...) \
__cap_rights_set((rights), __VA_ARGS__, 0ULL)
void __cap_rights_set(cap_rights_t *rights, ...);
Thanks to using one bit as an array index we can assert in those functions that
there are no two rights belonging to different array elements provided
together. For example this is illegal and will be detected, because CAP_LOOKUP
belongs to element 0 and CAP_PDKILL to element 1:
cap_rights_init(&rights, CAP_LOOKUP | CAP_PDKILL);
Providing several rights that belongs to the same array's element this way is
correct, but is not advised. It should only be used for aliases definition.
This commit also breaks compatibility with some existing Capsicum system calls,
but I see no other way to do that. This should be fine as Capsicum is still
experimental and this change is not going to 9.x.
Sponsored by: The FreeBSD Foundation
2013-09-05 00:09:56 +00:00
|
|
|
cap_rights_set(&rights, CAP_MMAP_W);
|
2011-08-11 12:30:23 +00:00
|
|
|
}
|
|
|
|
if (prot & PROT_EXEC)
|
Change the cap_rights_t type from uint64_t to a structure that we can extend
in the future in a backward compatible (API and ABI) way.
The cap_rights_t represents capability rights. We used to use one bit to
represent one right, but we are running out of spare bits. Currently the new
structure provides place for 114 rights (so 50 more than the previous
cap_rights_t), but it is possible to grow the structure to hold at least 285
rights, although we can make it even larger if 285 rights won't be enough.
The structure definition looks like this:
struct cap_rights {
uint64_t cr_rights[CAP_RIGHTS_VERSION + 2];
};
The initial CAP_RIGHTS_VERSION is 0.
The top two bits in the first element of the cr_rights[] array contain total
number of elements in the array - 2. This means if those two bits are equal to
0, we have 2 array elements.
The top two bits in all remaining array elements should be 0.
The next five bits in all array elements contain array index. Only one bit is
used and bit position in this five-bits range defines array index. This means
there can be at most five array elements in the future.
To define new right the CAPRIGHT() macro must be used. The macro takes two
arguments - an array index and a bit to set, eg.
#define CAP_PDKILL CAPRIGHT(1, 0x0000000000000800ULL)
We still support aliases that combine few rights, but the rights have to belong
to the same array element, eg:
#define CAP_LOOKUP CAPRIGHT(0, 0x0000000000000400ULL)
#define CAP_FCHMOD CAPRIGHT(0, 0x0000000000002000ULL)
#define CAP_FCHMODAT (CAP_FCHMOD | CAP_LOOKUP)
There is new API to manage the new cap_rights_t structure:
cap_rights_t *cap_rights_init(cap_rights_t *rights, ...);
void cap_rights_set(cap_rights_t *rights, ...);
void cap_rights_clear(cap_rights_t *rights, ...);
bool cap_rights_is_set(const cap_rights_t *rights, ...);
bool cap_rights_is_valid(const cap_rights_t *rights);
void cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src);
void cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src);
bool cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little);
Capability rights to the cap_rights_init(), cap_rights_set(),
cap_rights_clear() and cap_rights_is_set() functions are provided by
separating them with commas, eg:
cap_rights_t rights;
cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_FSTAT);
There is no need to terminate the list of rights, as those functions are
actually macros that take care of the termination, eg:
#define cap_rights_set(rights, ...) \
__cap_rights_set((rights), __VA_ARGS__, 0ULL)
void __cap_rights_set(cap_rights_t *rights, ...);
Thanks to using one bit as an array index we can assert in those functions that
there are no two rights belonging to different array elements provided
together. For example this is illegal and will be detected, because CAP_LOOKUP
belongs to element 0 and CAP_PDKILL to element 1:
cap_rights_init(&rights, CAP_LOOKUP | CAP_PDKILL);
Providing several rights that belongs to the same array's element this way is
correct, but is not advised. It should only be used for aliases definition.
This commit also breaks compatibility with some existing Capsicum system calls,
but I see no other way to do that. This should be fine as Capsicum is still
experimental and this change is not going to 9.x.
Sponsored by: The FreeBSD Foundation
2013-09-05 00:09:56 +00:00
|
|
|
cap_rights_set(&rights, CAP_MMAP_X);
|
|
|
|
error = fget_mmap(td, uap->fd, &rights, &cap_maxprot, &fp);
|
|
|
|
if (error != 0)
|
2002-01-13 11:58:06 +00:00
|
|
|
goto done;
|
The vm_mmap_cdev() explicitely converts absence of both MAP_SHARED and
MAP_PRIVATE flags to MAP_SHARED. Apparently, some code in tree, in
particular, libgeom, relied on this behaviour, see r271721. For
regular file types, the absence of the flags is interpreted as
MAP_PRIVATE, and libc nlist used this (fixed in r271723).
Allow the implicit flags for legacy binaries. Bump __FreeBSD_version
to get the ABI note on new binaries to check for in mmap code.
Remove the test for presence of one of the MAP_ANON, MAP_SHARED or
MAP_PRIVATE flags before fget_mmap(). For MAP_ANON, we already verify
that passed fd == -1. For fd != -1, test after fget_mmap() (for newer
binaries) covers the case.
Reported by: bdrewery, pho
Reviewed by: jhb
Sponsored by: The FreeBSD Foundation
2014-09-17 21:04:50 +00:00
|
|
|
if ((flags & (MAP_SHARED | MAP_PRIVATE)) == 0 &&
|
|
|
|
td->td_proc->p_osrel >= P_OSREL_MAP_FSTRICT) {
|
|
|
|
error = EINVAL;
|
|
|
|
goto done;
|
|
|
|
}
|
2014-09-15 17:20:13 +00:00
|
|
|
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
/* This relies on VM_PROT_* matching PROT_*. */
|
|
|
|
error = fo_mmap(fp, &vms->vm_map, &addr, size, prot,
|
|
|
|
cap_maxprot, flags, pos, td);
|
2006-03-26 12:20:54 +00:00
|
|
|
}
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
|
1994-05-24 10:09:53 +00:00
|
|
|
if (error == 0)
|
2001-09-12 08:38:13 +00:00
|
|
|
td->td_retval[0] = (register_t) (addr + pageoff);
|
2000-11-18 21:01:04 +00:00
|
|
|
done:
|
|
|
|
if (fp)
|
2001-09-12 08:38:13 +00:00
|
|
|
fdrop(fp, td);
|
2002-07-06 22:14:38 +00:00
|
|
|
|
1994-05-24 10:09:53 +00:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
The lseek(2), mmap(2), truncate(2), ftruncate(2), pread(2), and
pwrite(2) syscalls are wrapped to provide compatibility with pre-7.x
kernels which required padding before the off_t parameter. The
fcntl(2) contains compatibility code to handle kernels before the
struct flock was changed during the 8.x CURRENT development. The
shims were reasonable to allow easier revert to the older kernel at
that time.
Now, two or three major releases later, shims do not serve any
purpose. Such old kernels cannot handle current libc, so revert the
compatibility code.
Make padded syscalls support conditional under the COMPAT6 config
option. For COMPAT32, the syscalls were under COMPAT6 already.
Remove WITHOUT_SYSCALL_COMPAT build option, which only purpose was to
(partially) disable the removed shims.
Reviewed by: jhb, imp (previous versions)
Discussed with: peter
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
2015-04-18 21:50:13 +00:00
|
|
|
#if defined(COMPAT_FREEBSD6)
|
2007-07-04 22:57:21 +00:00
|
|
|
int
|
|
|
|
freebsd6_mmap(struct thread *td, struct freebsd6_mmap_args *uap)
|
|
|
|
{
|
|
|
|
struct mmap_args oargs;
|
|
|
|
|
|
|
|
oargs.addr = uap->addr;
|
|
|
|
oargs.len = uap->len;
|
|
|
|
oargs.prot = uap->prot;
|
|
|
|
oargs.flags = uap->flags;
|
|
|
|
oargs.fd = uap->fd;
|
|
|
|
oargs.pos = uap->pos;
|
2011-09-16 13:58:51 +00:00
|
|
|
return (sys_mmap(td, &oargs));
|
2007-07-04 22:57:21 +00:00
|
|
|
}
|
The lseek(2), mmap(2), truncate(2), ftruncate(2), pread(2), and
pwrite(2) syscalls are wrapped to provide compatibility with pre-7.x
kernels which required padding before the off_t parameter. The
fcntl(2) contains compatibility code to handle kernels before the
struct flock was changed during the 8.x CURRENT development. The
shims were reasonable to allow easier revert to the older kernel at
that time.
Now, two or three major releases later, shims do not serve any
purpose. Such old kernels cannot handle current libc, so revert the
compatibility code.
Make padded syscalls support conditional under the COMPAT6 config
option. For COMPAT32, the syscalls were under COMPAT6 already.
Remove WITHOUT_SYSCALL_COMPAT build option, which only purpose was to
(partially) disable the removed shims.
Reviewed by: jhb, imp (previous versions)
Discussed with: peter
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
2015-04-18 21:50:13 +00:00
|
|
|
#endif
|
2007-07-04 22:57:21 +00:00
|
|
|
|
1994-10-09 01:52:19 +00:00
|
|
|
#ifdef COMPAT_43
|
1995-11-12 06:43:28 +00:00
|
|
|
#ifndef _SYS_SYSPROTO_H_
|
1994-10-09 01:52:19 +00:00
|
|
|
struct ommap_args {
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
caddr_t addr;
|
|
|
|
int len;
|
|
|
|
int prot;
|
|
|
|
int flags;
|
|
|
|
int fd;
|
|
|
|
long pos;
|
1994-10-09 01:52:19 +00:00
|
|
|
};
|
1995-11-12 06:43:28 +00:00
|
|
|
#endif
|
1994-10-09 01:52:19 +00:00
|
|
|
int
|
2001-09-12 08:38:13 +00:00
|
|
|
ommap(td, uap)
|
|
|
|
struct thread *td;
|
2001-07-04 19:00:13 +00:00
|
|
|
struct ommap_args *uap;
|
1994-10-09 01:52:19 +00:00
|
|
|
{
|
|
|
|
struct mmap_args nargs;
|
|
|
|
static const char cvtbsdprot[8] = {
|
|
|
|
0,
|
|
|
|
PROT_EXEC,
|
|
|
|
PROT_WRITE,
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
PROT_EXEC | PROT_WRITE,
|
1994-10-09 01:52:19 +00:00
|
|
|
PROT_READ,
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
PROT_EXEC | PROT_READ,
|
|
|
|
PROT_WRITE | PROT_READ,
|
|
|
|
PROT_EXEC | PROT_WRITE | PROT_READ,
|
1994-10-09 01:52:19 +00:00
|
|
|
};
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
|
1994-10-09 01:52:19 +00:00
|
|
|
#define OMAP_ANON 0x0002
|
|
|
|
#define OMAP_COPY 0x0020
|
|
|
|
#define OMAP_SHARED 0x0010
|
|
|
|
#define OMAP_FIXED 0x0100
|
|
|
|
|
|
|
|
nargs.addr = uap->addr;
|
|
|
|
nargs.len = uap->len;
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
nargs.prot = cvtbsdprot[uap->prot & 0x7];
|
2012-08-14 12:11:48 +00:00
|
|
|
#ifdef COMPAT_FREEBSD32
|
2014-07-07 00:27:09 +00:00
|
|
|
#if defined(__amd64__)
|
2012-08-14 12:11:48 +00:00
|
|
|
if (i386_read_exec && SV_PROC_FLAG(td->td_proc, SV_ILP32) &&
|
|
|
|
nargs.prot != 0)
|
|
|
|
nargs.prot |= PROT_EXEC;
|
|
|
|
#endif
|
|
|
|
#endif
|
1994-10-09 01:52:19 +00:00
|
|
|
nargs.flags = 0;
|
|
|
|
if (uap->flags & OMAP_ANON)
|
|
|
|
nargs.flags |= MAP_ANON;
|
|
|
|
if (uap->flags & OMAP_COPY)
|
|
|
|
nargs.flags |= MAP_COPY;
|
|
|
|
if (uap->flags & OMAP_SHARED)
|
|
|
|
nargs.flags |= MAP_SHARED;
|
|
|
|
else
|
|
|
|
nargs.flags |= MAP_PRIVATE;
|
|
|
|
if (uap->flags & OMAP_FIXED)
|
|
|
|
nargs.flags |= MAP_FIXED;
|
|
|
|
nargs.fd = uap->fd;
|
|
|
|
nargs.pos = uap->pos;
|
2011-09-16 13:58:51 +00:00
|
|
|
return (sys_mmap(td, &nargs));
|
1994-10-09 01:52:19 +00:00
|
|
|
}
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
#endif /* COMPAT_43 */
|
1994-10-09 01:52:19 +00:00
|
|
|
|
|
|
|
|
1995-11-12 06:43:28 +00:00
|
|
|
#ifndef _SYS_SYSPROTO_H_
|
1994-05-24 10:09:53 +00:00
|
|
|
struct msync_args {
|
1997-12-31 02:35:29 +00:00
|
|
|
void *addr;
|
2007-10-18 22:47:39 +00:00
|
|
|
size_t len;
|
1995-03-25 16:55:46 +00:00
|
|
|
int flags;
|
1994-05-24 10:09:53 +00:00
|
|
|
};
|
1995-11-12 06:43:28 +00:00
|
|
|
#endif
|
2001-08-31 01:26:30 +00:00
|
|
|
/*
|
|
|
|
* MPSAFE
|
|
|
|
*/
|
1994-05-24 10:09:53 +00:00
|
|
|
int
|
2011-09-16 13:58:51 +00:00
|
|
|
sys_msync(td, uap)
|
2001-09-12 08:38:13 +00:00
|
|
|
struct thread *td;
|
1994-05-24 10:09:53 +00:00
|
|
|
struct msync_args *uap;
|
|
|
|
{
|
|
|
|
vm_offset_t addr;
|
1996-02-23 18:49:25 +00:00
|
|
|
vm_size_t size, pageoff;
|
1995-03-25 16:55:46 +00:00
|
|
|
int flags;
|
1994-05-24 10:09:53 +00:00
|
|
|
vm_map_t map;
|
|
|
|
int rv;
|
|
|
|
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
addr = (vm_offset_t) uap->addr;
|
1996-03-02 17:14:09 +00:00
|
|
|
size = uap->len;
|
1995-03-25 16:55:46 +00:00
|
|
|
flags = uap->flags;
|
|
|
|
|
1996-02-23 18:49:25 +00:00
|
|
|
pageoff = (addr & PAGE_MASK);
|
|
|
|
addr -= pageoff;
|
|
|
|
size += pageoff;
|
|
|
|
size = (vm_size_t) round_page(size);
|
1996-03-02 17:14:09 +00:00
|
|
|
if (addr + size < addr)
|
2002-03-10 21:52:48 +00:00
|
|
|
return (EINVAL);
|
1996-02-23 18:49:25 +00:00
|
|
|
|
|
|
|
if ((flags & (MS_ASYNC|MS_INVALIDATE)) == (MS_ASYNC|MS_INVALIDATE))
|
1995-03-25 17:36:00 +00:00
|
|
|
return (EINVAL);
|
|
|
|
|
2001-09-12 08:38:13 +00:00
|
|
|
map = &td->td_proc->p_vmspace->vm_map;
|
1996-03-02 17:14:09 +00:00
|
|
|
|
1994-05-24 10:09:53 +00:00
|
|
|
/*
|
|
|
|
* Clean the pages and interpret the return value.
|
|
|
|
*/
|
2003-11-09 05:25:35 +00:00
|
|
|
rv = vm_map_sync(map, addr, addr + size, (flags & MS_ASYNC) == 0,
|
1995-03-25 16:55:46 +00:00
|
|
|
(flags & MS_INVALIDATE) != 0);
|
1994-05-24 10:09:53 +00:00
|
|
|
switch (rv) {
|
|
|
|
case KERN_SUCCESS:
|
2002-03-10 21:52:48 +00:00
|
|
|
return (0);
|
1994-05-24 10:09:53 +00:00
|
|
|
case KERN_INVALID_ADDRESS:
|
2014-05-07 08:38:02 +00:00
|
|
|
return (ENOMEM);
|
2003-11-14 06:55:11 +00:00
|
|
|
case KERN_INVALID_ARGUMENT:
|
|
|
|
return (EBUSY);
|
2012-03-17 23:00:32 +00:00
|
|
|
case KERN_FAILURE:
|
|
|
|
return (EIO);
|
1994-05-24 10:09:53 +00:00
|
|
|
default:
|
|
|
|
return (EINVAL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1995-11-12 06:43:28 +00:00
|
|
|
#ifndef _SYS_SYSPROTO_H_
|
1994-05-24 10:09:53 +00:00
|
|
|
struct munmap_args {
|
1997-12-31 02:35:29 +00:00
|
|
|
void *addr;
|
1996-03-02 17:14:09 +00:00
|
|
|
size_t len;
|
1994-05-24 10:09:53 +00:00
|
|
|
};
|
1995-11-12 06:43:28 +00:00
|
|
|
#endif
|
2001-08-31 01:26:30 +00:00
|
|
|
/*
|
|
|
|
* MPSAFE
|
|
|
|
*/
|
1994-05-24 10:09:53 +00:00
|
|
|
int
|
2011-09-16 13:58:51 +00:00
|
|
|
sys_munmap(td, uap)
|
2001-09-12 08:38:13 +00:00
|
|
|
struct thread *td;
|
2001-07-04 19:00:13 +00:00
|
|
|
struct munmap_args *uap;
|
1994-05-24 10:09:53 +00:00
|
|
|
{
|
2006-03-26 12:20:54 +00:00
|
|
|
#ifdef HWPMC_HOOKS
|
|
|
|
struct pmckern_map_out pkm;
|
|
|
|
vm_map_entry_t entry;
|
|
|
|
#endif
|
1994-05-24 10:09:53 +00:00
|
|
|
vm_offset_t addr;
|
1996-02-23 18:49:25 +00:00
|
|
|
vm_size_t size, pageoff;
|
1994-05-24 10:09:53 +00:00
|
|
|
vm_map_t map;
|
|
|
|
|
|
|
|
addr = (vm_offset_t) uap->addr;
|
1996-03-02 17:14:09 +00:00
|
|
|
size = uap->len;
|
2003-11-10 01:37:40 +00:00
|
|
|
if (size == 0)
|
|
|
|
return (EINVAL);
|
1996-02-23 18:49:25 +00:00
|
|
|
|
|
|
|
pageoff = (addr & PAGE_MASK);
|
|
|
|
addr -= pageoff;
|
|
|
|
size += pageoff;
|
|
|
|
size = (vm_size_t) round_page(size);
|
1996-03-02 17:14:09 +00:00
|
|
|
if (addr + size < addr)
|
2002-03-10 21:52:48 +00:00
|
|
|
return (EINVAL);
|
1996-03-02 17:14:09 +00:00
|
|
|
|
1994-05-24 10:09:53 +00:00
|
|
|
/*
|
2002-09-21 22:07:17 +00:00
|
|
|
* Check for illegal addresses. Watch out for address wrap...
|
1994-05-24 10:09:53 +00:00
|
|
|
*/
|
2001-09-12 08:38:13 +00:00
|
|
|
map = &td->td_proc->p_vmspace->vm_map;
|
2002-09-21 22:07:17 +00:00
|
|
|
if (addr < vm_map_min(map) || addr + size > vm_map_max(map))
|
|
|
|
return (EINVAL);
|
2003-11-10 01:37:40 +00:00
|
|
|
vm_map_lock(map);
|
2006-03-26 12:20:54 +00:00
|
|
|
#ifdef HWPMC_HOOKS
|
|
|
|
/*
|
|
|
|
* Inform hwpmc if the address range being unmapped contains
|
|
|
|
* an executable region.
|
|
|
|
*/
|
2010-09-07 00:23:45 +00:00
|
|
|
pkm.pm_address = (uintptr_t) NULL;
|
2006-03-26 12:20:54 +00:00
|
|
|
if (vm_map_lookup_entry(map, addr, &entry)) {
|
|
|
|
for (;
|
|
|
|
entry != &map->header && entry->start < addr + size;
|
|
|
|
entry = entry->next) {
|
|
|
|
if (vm_map_check_protection(map, entry->start,
|
|
|
|
entry->end, VM_PROT_EXECUTE) == TRUE) {
|
|
|
|
pkm.pm_address = (uintptr_t) addr;
|
|
|
|
pkm.pm_size = (size_t) size;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2009-02-24 20:57:43 +00:00
|
|
|
vm_map_delete(map, addr, addr + size);
|
2010-09-07 00:23:45 +00:00
|
|
|
|
|
|
|
#ifdef HWPMC_HOOKS
|
|
|
|
/* downgrade the lock to prevent a LOR with the pmc-sx lock */
|
|
|
|
vm_map_lock_downgrade(map);
|
2010-09-07 02:51:11 +00:00
|
|
|
if (pkm.pm_address != (uintptr_t) NULL)
|
2010-09-07 00:23:45 +00:00
|
|
|
PMC_CALL_HOOK(td, PMC_FN_MUNMAP, (void *) &pkm);
|
|
|
|
vm_map_unlock_read(map);
|
|
|
|
#else
|
2003-11-10 01:37:40 +00:00
|
|
|
vm_map_unlock(map);
|
2010-09-07 00:23:45 +00:00
|
|
|
#endif
|
|
|
|
/* vm_map_delete returns nothing but KERN_SUCCESS anyway */
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
return (0);
|
1994-05-24 10:09:53 +00:00
|
|
|
}
|
|
|
|
|
1995-11-12 06:43:28 +00:00
|
|
|
#ifndef _SYS_SYSPROTO_H_
|
1994-05-24 10:09:53 +00:00
|
|
|
struct mprotect_args {
|
1997-12-31 02:35:29 +00:00
|
|
|
const void *addr;
|
1996-03-02 17:14:09 +00:00
|
|
|
size_t len;
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
int prot;
|
1994-05-24 10:09:53 +00:00
|
|
|
};
|
1995-11-12 06:43:28 +00:00
|
|
|
#endif
|
2001-08-31 01:26:30 +00:00
|
|
|
/*
|
|
|
|
* MPSAFE
|
|
|
|
*/
|
1994-05-24 10:09:53 +00:00
|
|
|
int
|
2011-09-16 13:58:51 +00:00
|
|
|
sys_mprotect(td, uap)
|
2001-09-12 08:38:13 +00:00
|
|
|
struct thread *td;
|
1994-05-24 10:09:53 +00:00
|
|
|
struct mprotect_args *uap;
|
|
|
|
{
|
|
|
|
vm_offset_t addr;
|
1996-02-23 18:49:25 +00:00
|
|
|
vm_size_t size, pageoff;
|
2001-07-04 19:00:13 +00:00
|
|
|
vm_prot_t prot;
|
1994-05-24 10:09:53 +00:00
|
|
|
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
addr = (vm_offset_t) uap->addr;
|
1996-03-02 17:14:09 +00:00
|
|
|
size = uap->len;
|
1994-05-24 10:09:53 +00:00
|
|
|
prot = uap->prot & VM_PROT_ALL;
|
|
|
|
|
1996-02-23 18:49:25 +00:00
|
|
|
pageoff = (addr & PAGE_MASK);
|
|
|
|
addr -= pageoff;
|
|
|
|
size += pageoff;
|
|
|
|
size = (vm_size_t) round_page(size);
|
1996-03-02 17:14:09 +00:00
|
|
|
if (addr + size < addr)
|
2002-03-10 21:52:48 +00:00
|
|
|
return (EINVAL);
|
1996-02-23 18:49:25 +00:00
|
|
|
|
2002-05-18 03:58:16 +00:00
|
|
|
switch (vm_map_protect(&td->td_proc->p_vmspace->vm_map, addr,
|
|
|
|
addr + size, prot, FALSE)) {
|
1994-05-24 10:09:53 +00:00
|
|
|
case KERN_SUCCESS:
|
|
|
|
return (0);
|
|
|
|
case KERN_PROTECTION_FAILURE:
|
|
|
|
return (EACCES);
|
Implement global and per-uid accounting of the anonymous memory. Add
rlimit RLIMIT_SWAP that limits the amount of swap that may be reserved
for the uid.
The accounting information (charge) is associated with either map entry,
or vm object backing the entry, assuming the object is the first one
in the shadow chain and entry does not require COW. Charge is moved
from entry to object on allocation of the object, e.g. during the mmap,
assuming the object is allocated, or on the first page fault on the
entry. It moves back to the entry on forks due to COW setup.
The per-entry granularity of accounting makes the charge process fair
for processes that change uid during lifetime, and decrements charge
for proper uid when region is unmapped.
The interface of vm_pager_allocate(9) is extended by adding struct ucred *,
that is used to charge appropriate uid when allocation if performed by
kernel, e.g. md(4).
Several syscalls, among them is fork(2), may now return ENOMEM when
global or per-uid limits are enforced.
In collaboration with: pho
Reviewed by: alc
Approved by: re (kensmith)
2009-06-23 20:45:22 +00:00
|
|
|
case KERN_RESOURCE_SHORTAGE:
|
|
|
|
return (ENOMEM);
|
1994-05-24 10:09:53 +00:00
|
|
|
}
|
|
|
|
return (EINVAL);
|
|
|
|
}
|
|
|
|
|
1996-02-23 18:49:25 +00:00
|
|
|
#ifndef _SYS_SYSPROTO_H_
|
|
|
|
struct minherit_args {
|
1997-12-31 02:35:29 +00:00
|
|
|
void *addr;
|
1996-03-02 17:14:09 +00:00
|
|
|
size_t len;
|
1996-02-23 18:49:25 +00:00
|
|
|
int inherit;
|
|
|
|
};
|
|
|
|
#endif
|
2001-08-31 01:26:30 +00:00
|
|
|
/*
|
|
|
|
* MPSAFE
|
|
|
|
*/
|
1996-02-23 18:49:25 +00:00
|
|
|
int
|
2011-09-16 13:58:51 +00:00
|
|
|
sys_minherit(td, uap)
|
2001-09-12 08:38:13 +00:00
|
|
|
struct thread *td;
|
1996-02-23 18:49:25 +00:00
|
|
|
struct minherit_args *uap;
|
|
|
|
{
|
|
|
|
vm_offset_t addr;
|
|
|
|
vm_size_t size, pageoff;
|
2001-07-04 19:00:13 +00:00
|
|
|
vm_inherit_t inherit;
|
1996-02-23 18:49:25 +00:00
|
|
|
|
|
|
|
addr = (vm_offset_t)uap->addr;
|
1996-03-02 17:14:09 +00:00
|
|
|
size = uap->len;
|
1996-02-23 18:49:25 +00:00
|
|
|
inherit = uap->inherit;
|
|
|
|
|
|
|
|
pageoff = (addr & PAGE_MASK);
|
|
|
|
addr -= pageoff;
|
|
|
|
size += pageoff;
|
|
|
|
size = (vm_size_t) round_page(size);
|
1996-03-02 17:14:09 +00:00
|
|
|
if (addr + size < addr)
|
2002-03-10 21:52:48 +00:00
|
|
|
return (EINVAL);
|
1996-02-23 18:49:25 +00:00
|
|
|
|
2002-05-18 18:59:00 +00:00
|
|
|
switch (vm_map_inherit(&td->td_proc->p_vmspace->vm_map, addr,
|
|
|
|
addr + size, inherit)) {
|
1996-02-23 18:49:25 +00:00
|
|
|
case KERN_SUCCESS:
|
|
|
|
return (0);
|
|
|
|
case KERN_PROTECTION_FAILURE:
|
|
|
|
return (EACCES);
|
|
|
|
}
|
|
|
|
return (EINVAL);
|
|
|
|
}
|
|
|
|
|
1995-11-12 06:43:28 +00:00
|
|
|
#ifndef _SYS_SYSPROTO_H_
|
1994-05-24 10:09:53 +00:00
|
|
|
struct madvise_args {
|
1997-12-31 02:35:29 +00:00
|
|
|
void *addr;
|
1996-03-02 17:14:09 +00:00
|
|
|
size_t len;
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
int behav;
|
1994-05-24 10:09:53 +00:00
|
|
|
};
|
1995-11-12 06:43:28 +00:00
|
|
|
#endif
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
|
2001-08-31 01:26:30 +00:00
|
|
|
/*
|
|
|
|
* MPSAFE
|
|
|
|
*/
|
1994-05-24 10:09:53 +00:00
|
|
|
int
|
2011-09-16 13:58:51 +00:00
|
|
|
sys_madvise(td, uap)
|
2001-09-12 08:38:13 +00:00
|
|
|
struct thread *td;
|
1994-05-24 10:09:53 +00:00
|
|
|
struct madvise_args *uap;
|
|
|
|
{
|
1996-05-31 00:38:04 +00:00
|
|
|
vm_offset_t start, end;
|
2002-09-21 22:07:17 +00:00
|
|
|
vm_map_t map;
|
2013-09-19 18:53:42 +00:00
|
|
|
int flags;
|
1999-09-21 05:00:48 +00:00
|
|
|
|
2003-03-31 21:09:57 +00:00
|
|
|
/*
|
|
|
|
* Check for our special case, advising the swap pager we are
|
|
|
|
* "immortal."
|
|
|
|
*/
|
|
|
|
if (uap->behav == MADV_PROTECT) {
|
2013-09-19 18:53:42 +00:00
|
|
|
flags = PPROT_SET;
|
|
|
|
return (kern_procctl(td, P_PID, td->td_proc->p_pid,
|
|
|
|
PROC_SPROTECT, &flags));
|
2003-03-31 21:09:57 +00:00
|
|
|
}
|
2013-09-19 18:53:42 +00:00
|
|
|
|
1999-09-21 05:00:48 +00:00
|
|
|
/*
|
|
|
|
* Check for illegal behavior
|
|
|
|
*/
|
2000-02-28 04:10:35 +00:00
|
|
|
if (uap->behav < 0 || uap->behav > MADV_CORE)
|
1999-09-21 05:00:48 +00:00
|
|
|
return (EINVAL);
|
1996-05-19 07:36:50 +00:00
|
|
|
/*
|
|
|
|
* Check for illegal addresses. Watch out for address wrap... Note
|
|
|
|
* that VM_*_ADDRESS are not constants due to casts (argh).
|
|
|
|
*/
|
2002-09-21 22:07:17 +00:00
|
|
|
map = &td->td_proc->p_vmspace->vm_map;
|
|
|
|
if ((vm_offset_t)uap->addr < vm_map_min(map) ||
|
|
|
|
(vm_offset_t)uap->addr + uap->len > vm_map_max(map))
|
1996-05-19 07:36:50 +00:00
|
|
|
return (EINVAL);
|
|
|
|
if (((vm_offset_t) uap->addr + uap->len) < (vm_offset_t) uap->addr)
|
|
|
|
return (EINVAL);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Since this routine is only advisory, we default to conservative
|
|
|
|
* behavior.
|
|
|
|
*/
|
1996-09-19 10:12:41 +00:00
|
|
|
start = trunc_page((vm_offset_t) uap->addr);
|
|
|
|
end = round_page((vm_offset_t) uap->addr + uap->len);
|
2003-12-08 02:45:45 +00:00
|
|
|
|
2002-09-21 22:07:17 +00:00
|
|
|
if (vm_map_madvise(map, start, end, uap->behav))
|
2002-05-18 07:48:06 +00:00
|
|
|
return (EINVAL);
|
|
|
|
return (0);
|
1994-05-24 10:09:53 +00:00
|
|
|
}
|
|
|
|
|
1995-11-12 06:43:28 +00:00
|
|
|
#ifndef _SYS_SYSPROTO_H_
|
1994-05-24 10:09:53 +00:00
|
|
|
struct mincore_args {
|
1997-12-31 02:35:29 +00:00
|
|
|
const void *addr;
|
1996-03-02 17:14:09 +00:00
|
|
|
size_t len;
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
char *vec;
|
1994-05-24 10:09:53 +00:00
|
|
|
};
|
1995-11-12 06:43:28 +00:00
|
|
|
#endif
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
|
2001-08-31 01:26:30 +00:00
|
|
|
/*
|
|
|
|
* MPSAFE
|
|
|
|
*/
|
1994-05-24 10:09:53 +00:00
|
|
|
int
|
2011-09-16 13:58:51 +00:00
|
|
|
sys_mincore(td, uap)
|
2001-09-12 08:38:13 +00:00
|
|
|
struct thread *td;
|
1994-05-24 10:09:53 +00:00
|
|
|
struct mincore_args *uap;
|
|
|
|
{
|
1996-05-19 07:36:50 +00:00
|
|
|
vm_offset_t addr, first_addr;
|
|
|
|
vm_offset_t end, cend;
|
|
|
|
pmap_t pmap;
|
|
|
|
vm_map_t map;
|
1995-10-21 17:42:28 +00:00
|
|
|
char *vec;
|
2001-08-31 01:26:30 +00:00
|
|
|
int error = 0;
|
1996-05-19 07:36:50 +00:00
|
|
|
int vecindex, lastvecindex;
|
2001-07-04 19:00:13 +00:00
|
|
|
vm_map_entry_t current;
|
1996-05-19 07:36:50 +00:00
|
|
|
vm_map_entry_t entry;
|
Roughly half of a typical pmap_mincore() implementation is machine-
independent code. Move this code into mincore(), and eliminate the
page queues lock from pmap_mincore().
Push down the page queues lock into pmap_clear_modify(),
pmap_clear_reference(), and pmap_is_modified(). Assert that these
functions are never passed an unmanaged page.
Eliminate an inaccurate comment from powerpc/powerpc/mmu_if.m:
Contrary to what the comment says, pmap_mincore() is not simply an
optimization. Without a complete pmap_mincore() implementation,
mincore() cannot return either MINCORE_MODIFIED or MINCORE_REFERENCED
because only the pmap can provide this information.
Eliminate the page queues lock from vfs_setdirty_locked_object(),
vm_pageout_clean(), vm_object_page_collect_flush(), and
vm_object_page_clean(). Generally speaking, these are all accesses
to the page's dirty field, which are synchronized by the containing
vm object's lock.
Reduce the scope of the page queues lock in vm_object_madvise() and
vm_page_dontneed().
Reviewed by: kib (an earlier version)
2010-05-24 14:26:57 +00:00
|
|
|
vm_object_t object;
|
|
|
|
vm_paddr_t locked_pa;
|
|
|
|
vm_page_t m;
|
|
|
|
vm_pindex_t pindex;
|
1996-05-19 07:36:50 +00:00
|
|
|
int mincoreinfo;
|
1999-03-02 22:55:02 +00:00
|
|
|
unsigned int timestamp;
|
Roughly half of a typical pmap_mincore() implementation is machine-
independent code. Move this code into mincore(), and eliminate the
page queues lock from pmap_mincore().
Push down the page queues lock into pmap_clear_modify(),
pmap_clear_reference(), and pmap_is_modified(). Assert that these
functions are never passed an unmanaged page.
Eliminate an inaccurate comment from powerpc/powerpc/mmu_if.m:
Contrary to what the comment says, pmap_mincore() is not simply an
optimization. Without a complete pmap_mincore() implementation,
mincore() cannot return either MINCORE_MODIFIED or MINCORE_REFERENCED
because only the pmap can provide this information.
Eliminate the page queues lock from vfs_setdirty_locked_object(),
vm_pageout_clean(), vm_object_page_collect_flush(), and
vm_object_page_clean(). Generally speaking, these are all accesses
to the page's dirty field, which are synchronized by the containing
vm object's lock.
Reduce the scope of the page queues lock in vm_object_madvise() and
vm_page_dontneed().
Reviewed by: kib (an earlier version)
2010-05-24 14:26:57 +00:00
|
|
|
boolean_t locked;
|
1994-05-24 10:09:53 +00:00
|
|
|
|
1996-05-19 07:36:50 +00:00
|
|
|
/*
|
|
|
|
* Make sure that the addresses presented are valid for user
|
|
|
|
* mode.
|
|
|
|
*/
|
|
|
|
first_addr = addr = trunc_page((vm_offset_t) uap->addr);
|
1996-03-02 17:14:09 +00:00
|
|
|
end = addr + (vm_size_t)round_page(uap->len);
|
2002-09-21 22:07:17 +00:00
|
|
|
map = &td->td_proc->p_vmspace->vm_map;
|
|
|
|
if (end > vm_map_max(map) || end < addr)
|
2006-06-21 12:59:05 +00:00
|
|
|
return (ENOMEM);
|
1995-10-21 17:42:28 +00:00
|
|
|
|
1996-05-19 07:36:50 +00:00
|
|
|
/*
|
|
|
|
* Address of byte vector
|
|
|
|
*/
|
1995-10-21 17:42:28 +00:00
|
|
|
vec = uap->vec;
|
1996-05-19 07:36:50 +00:00
|
|
|
|
2001-09-12 08:38:13 +00:00
|
|
|
pmap = vmspace_pmap(td->td_proc->p_vmspace);
|
1996-05-19 07:36:50 +00:00
|
|
|
|
1999-03-01 20:42:16 +00:00
|
|
|
vm_map_lock_read(map);
|
1999-03-02 22:55:02 +00:00
|
|
|
RestartScan:
|
|
|
|
timestamp = map->timestamp;
|
1996-05-19 07:36:50 +00:00
|
|
|
|
2006-06-21 12:59:05 +00:00
|
|
|
if (!vm_map_lookup_entry(map, addr, &entry)) {
|
|
|
|
vm_map_unlock_read(map);
|
|
|
|
return (ENOMEM);
|
|
|
|
}
|
1996-05-19 07:36:50 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Do this on a map entry basis so that if the pages are not
|
|
|
|
* in the current processes address space, we can easily look
|
|
|
|
* up the pages elsewhere.
|
|
|
|
*/
|
|
|
|
lastvecindex = -1;
|
2001-07-04 19:00:13 +00:00
|
|
|
for (current = entry;
|
|
|
|
(current != &map->header) && (current->start < end);
|
|
|
|
current = current->next) {
|
1996-05-19 07:36:50 +00:00
|
|
|
|
2006-06-21 12:59:05 +00:00
|
|
|
/*
|
|
|
|
* check for contiguity
|
|
|
|
*/
|
|
|
|
if (current->end < end &&
|
|
|
|
(entry->next == &map->header ||
|
|
|
|
current->next->start > current->end)) {
|
|
|
|
vm_map_unlock_read(map);
|
|
|
|
return (ENOMEM);
|
|
|
|
}
|
|
|
|
|
1996-05-19 07:36:50 +00:00
|
|
|
/*
|
|
|
|
* ignore submaps (for now) or null objects
|
|
|
|
*/
|
1999-02-07 21:48:23 +00:00
|
|
|
if ((current->eflags & MAP_ENTRY_IS_SUB_MAP) ||
|
1996-05-19 07:36:50 +00:00
|
|
|
current->object.vm_object == NULL)
|
|
|
|
continue;
|
2003-12-08 02:45:45 +00:00
|
|
|
|
1996-05-19 07:36:50 +00:00
|
|
|
/*
|
|
|
|
* limit this scan to the current map entry and the
|
|
|
|
* limits for the mincore call
|
|
|
|
*/
|
|
|
|
if (addr < current->start)
|
|
|
|
addr = current->start;
|
|
|
|
cend = current->end;
|
|
|
|
if (cend > end)
|
|
|
|
cend = end;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* scan this entry one page at a time
|
|
|
|
*/
|
2001-07-04 19:00:13 +00:00
|
|
|
while (addr < cend) {
|
1996-05-19 07:36:50 +00:00
|
|
|
/*
|
|
|
|
* Check pmap first, it is likely faster, also
|
|
|
|
* it can provide info as to whether we are the
|
|
|
|
* one referencing or modifying the page.
|
|
|
|
*/
|
Roughly half of a typical pmap_mincore() implementation is machine-
independent code. Move this code into mincore(), and eliminate the
page queues lock from pmap_mincore().
Push down the page queues lock into pmap_clear_modify(),
pmap_clear_reference(), and pmap_is_modified(). Assert that these
functions are never passed an unmanaged page.
Eliminate an inaccurate comment from powerpc/powerpc/mmu_if.m:
Contrary to what the comment says, pmap_mincore() is not simply an
optimization. Without a complete pmap_mincore() implementation,
mincore() cannot return either MINCORE_MODIFIED or MINCORE_REFERENCED
because only the pmap can provide this information.
Eliminate the page queues lock from vfs_setdirty_locked_object(),
vm_pageout_clean(), vm_object_page_collect_flush(), and
vm_object_page_clean(). Generally speaking, these are all accesses
to the page's dirty field, which are synchronized by the containing
vm object's lock.
Reduce the scope of the page queues lock in vm_object_madvise() and
vm_page_dontneed().
Reviewed by: kib (an earlier version)
2010-05-24 14:26:57 +00:00
|
|
|
object = NULL;
|
|
|
|
locked_pa = 0;
|
|
|
|
retry:
|
|
|
|
m = NULL;
|
|
|
|
mincoreinfo = pmap_mincore(pmap, addr, &locked_pa);
|
|
|
|
if (locked_pa != 0) {
|
1996-05-19 07:36:50 +00:00
|
|
|
/*
|
Roughly half of a typical pmap_mincore() implementation is machine-
independent code. Move this code into mincore(), and eliminate the
page queues lock from pmap_mincore().
Push down the page queues lock into pmap_clear_modify(),
pmap_clear_reference(), and pmap_is_modified(). Assert that these
functions are never passed an unmanaged page.
Eliminate an inaccurate comment from powerpc/powerpc/mmu_if.m:
Contrary to what the comment says, pmap_mincore() is not simply an
optimization. Without a complete pmap_mincore() implementation,
mincore() cannot return either MINCORE_MODIFIED or MINCORE_REFERENCED
because only the pmap can provide this information.
Eliminate the page queues lock from vfs_setdirty_locked_object(),
vm_pageout_clean(), vm_object_page_collect_flush(), and
vm_object_page_clean(). Generally speaking, these are all accesses
to the page's dirty field, which are synchronized by the containing
vm object's lock.
Reduce the scope of the page queues lock in vm_object_madvise() and
vm_page_dontneed().
Reviewed by: kib (an earlier version)
2010-05-24 14:26:57 +00:00
|
|
|
* The page is mapped by this process but not
|
|
|
|
* both accessed and modified. It is also
|
|
|
|
* managed. Acquire the object lock so that
|
|
|
|
* other mappings might be examined.
|
1996-05-19 07:36:50 +00:00
|
|
|
*/
|
Roughly half of a typical pmap_mincore() implementation is machine-
independent code. Move this code into mincore(), and eliminate the
page queues lock from pmap_mincore().
Push down the page queues lock into pmap_clear_modify(),
pmap_clear_reference(), and pmap_is_modified(). Assert that these
functions are never passed an unmanaged page.
Eliminate an inaccurate comment from powerpc/powerpc/mmu_if.m:
Contrary to what the comment says, pmap_mincore() is not simply an
optimization. Without a complete pmap_mincore() implementation,
mincore() cannot return either MINCORE_MODIFIED or MINCORE_REFERENCED
because only the pmap can provide this information.
Eliminate the page queues lock from vfs_setdirty_locked_object(),
vm_pageout_clean(), vm_object_page_collect_flush(), and
vm_object_page_clean(). Generally speaking, these are all accesses
to the page's dirty field, which are synchronized by the containing
vm object's lock.
Reduce the scope of the page queues lock in vm_object_madvise() and
vm_page_dontneed().
Reviewed by: kib (an earlier version)
2010-05-24 14:26:57 +00:00
|
|
|
m = PHYS_TO_VM_PAGE(locked_pa);
|
|
|
|
if (m->object != object) {
|
|
|
|
if (object != NULL)
|
2013-03-09 02:32:23 +00:00
|
|
|
VM_OBJECT_WUNLOCK(object);
|
Roughly half of a typical pmap_mincore() implementation is machine-
independent code. Move this code into mincore(), and eliminate the
page queues lock from pmap_mincore().
Push down the page queues lock into pmap_clear_modify(),
pmap_clear_reference(), and pmap_is_modified(). Assert that these
functions are never passed an unmanaged page.
Eliminate an inaccurate comment from powerpc/powerpc/mmu_if.m:
Contrary to what the comment says, pmap_mincore() is not simply an
optimization. Without a complete pmap_mincore() implementation,
mincore() cannot return either MINCORE_MODIFIED or MINCORE_REFERENCED
because only the pmap can provide this information.
Eliminate the page queues lock from vfs_setdirty_locked_object(),
vm_pageout_clean(), vm_object_page_collect_flush(), and
vm_object_page_clean(). Generally speaking, these are all accesses
to the page's dirty field, which are synchronized by the containing
vm object's lock.
Reduce the scope of the page queues lock in vm_object_madvise() and
vm_page_dontneed().
Reviewed by: kib (an earlier version)
2010-05-24 14:26:57 +00:00
|
|
|
object = m->object;
|
2013-03-09 02:32:23 +00:00
|
|
|
locked = VM_OBJECT_TRYWLOCK(object);
|
Roughly half of a typical pmap_mincore() implementation is machine-
independent code. Move this code into mincore(), and eliminate the
page queues lock from pmap_mincore().
Push down the page queues lock into pmap_clear_modify(),
pmap_clear_reference(), and pmap_is_modified(). Assert that these
functions are never passed an unmanaged page.
Eliminate an inaccurate comment from powerpc/powerpc/mmu_if.m:
Contrary to what the comment says, pmap_mincore() is not simply an
optimization. Without a complete pmap_mincore() implementation,
mincore() cannot return either MINCORE_MODIFIED or MINCORE_REFERENCED
because only the pmap can provide this information.
Eliminate the page queues lock from vfs_setdirty_locked_object(),
vm_pageout_clean(), vm_object_page_collect_flush(), and
vm_object_page_clean(). Generally speaking, these are all accesses
to the page's dirty field, which are synchronized by the containing
vm object's lock.
Reduce the scope of the page queues lock in vm_object_madvise() and
vm_page_dontneed().
Reviewed by: kib (an earlier version)
2010-05-24 14:26:57 +00:00
|
|
|
vm_page_unlock(m);
|
|
|
|
if (!locked) {
|
2013-03-09 02:32:23 +00:00
|
|
|
VM_OBJECT_WLOCK(object);
|
Roughly half of a typical pmap_mincore() implementation is machine-
independent code. Move this code into mincore(), and eliminate the
page queues lock from pmap_mincore().
Push down the page queues lock into pmap_clear_modify(),
pmap_clear_reference(), and pmap_is_modified(). Assert that these
functions are never passed an unmanaged page.
Eliminate an inaccurate comment from powerpc/powerpc/mmu_if.m:
Contrary to what the comment says, pmap_mincore() is not simply an
optimization. Without a complete pmap_mincore() implementation,
mincore() cannot return either MINCORE_MODIFIED or MINCORE_REFERENCED
because only the pmap can provide this information.
Eliminate the page queues lock from vfs_setdirty_locked_object(),
vm_pageout_clean(), vm_object_page_collect_flush(), and
vm_object_page_clean(). Generally speaking, these are all accesses
to the page's dirty field, which are synchronized by the containing
vm object's lock.
Reduce the scope of the page queues lock in vm_object_madvise() and
vm_page_dontneed().
Reviewed by: kib (an earlier version)
2010-05-24 14:26:57 +00:00
|
|
|
vm_page_lock(m);
|
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
vm_page_unlock(m);
|
|
|
|
KASSERT(m->valid == VM_PAGE_BITS_ALL,
|
|
|
|
("mincore: page %p is mapped but invalid",
|
|
|
|
m));
|
|
|
|
} else if (mincoreinfo == 0) {
|
1996-05-19 07:36:50 +00:00
|
|
|
/*
|
Roughly half of a typical pmap_mincore() implementation is machine-
independent code. Move this code into mincore(), and eliminate the
page queues lock from pmap_mincore().
Push down the page queues lock into pmap_clear_modify(),
pmap_clear_reference(), and pmap_is_modified(). Assert that these
functions are never passed an unmanaged page.
Eliminate an inaccurate comment from powerpc/powerpc/mmu_if.m:
Contrary to what the comment says, pmap_mincore() is not simply an
optimization. Without a complete pmap_mincore() implementation,
mincore() cannot return either MINCORE_MODIFIED or MINCORE_REFERENCED
because only the pmap can provide this information.
Eliminate the page queues lock from vfs_setdirty_locked_object(),
vm_pageout_clean(), vm_object_page_collect_flush(), and
vm_object_page_clean(). Generally speaking, these are all accesses
to the page's dirty field, which are synchronized by the containing
vm object's lock.
Reduce the scope of the page queues lock in vm_object_madvise() and
vm_page_dontneed().
Reviewed by: kib (an earlier version)
2010-05-24 14:26:57 +00:00
|
|
|
* The page is not mapped by this process. If
|
|
|
|
* the object implements managed pages, then
|
|
|
|
* determine if the page is resident so that
|
|
|
|
* the mappings might be examined.
|
1996-05-19 07:36:50 +00:00
|
|
|
*/
|
Roughly half of a typical pmap_mincore() implementation is machine-
independent code. Move this code into mincore(), and eliminate the
page queues lock from pmap_mincore().
Push down the page queues lock into pmap_clear_modify(),
pmap_clear_reference(), and pmap_is_modified(). Assert that these
functions are never passed an unmanaged page.
Eliminate an inaccurate comment from powerpc/powerpc/mmu_if.m:
Contrary to what the comment says, pmap_mincore() is not simply an
optimization. Without a complete pmap_mincore() implementation,
mincore() cannot return either MINCORE_MODIFIED or MINCORE_REFERENCED
because only the pmap can provide this information.
Eliminate the page queues lock from vfs_setdirty_locked_object(),
vm_pageout_clean(), vm_object_page_collect_flush(), and
vm_object_page_clean(). Generally speaking, these are all accesses
to the page's dirty field, which are synchronized by the containing
vm object's lock.
Reduce the scope of the page queues lock in vm_object_madvise() and
vm_page_dontneed().
Reviewed by: kib (an earlier version)
2010-05-24 14:26:57 +00:00
|
|
|
if (current->object.vm_object != object) {
|
|
|
|
if (object != NULL)
|
2013-03-09 02:32:23 +00:00
|
|
|
VM_OBJECT_WUNLOCK(object);
|
Roughly half of a typical pmap_mincore() implementation is machine-
independent code. Move this code into mincore(), and eliminate the
page queues lock from pmap_mincore().
Push down the page queues lock into pmap_clear_modify(),
pmap_clear_reference(), and pmap_is_modified(). Assert that these
functions are never passed an unmanaged page.
Eliminate an inaccurate comment from powerpc/powerpc/mmu_if.m:
Contrary to what the comment says, pmap_mincore() is not simply an
optimization. Without a complete pmap_mincore() implementation,
mincore() cannot return either MINCORE_MODIFIED or MINCORE_REFERENCED
because only the pmap can provide this information.
Eliminate the page queues lock from vfs_setdirty_locked_object(),
vm_pageout_clean(), vm_object_page_collect_flush(), and
vm_object_page_clean(). Generally speaking, these are all accesses
to the page's dirty field, which are synchronized by the containing
vm object's lock.
Reduce the scope of the page queues lock in vm_object_madvise() and
vm_page_dontneed().
Reviewed by: kib (an earlier version)
2010-05-24 14:26:57 +00:00
|
|
|
object = current->object.vm_object;
|
2013-03-09 02:32:23 +00:00
|
|
|
VM_OBJECT_WLOCK(object);
|
1996-05-19 07:36:50 +00:00
|
|
|
}
|
Roughly half of a typical pmap_mincore() implementation is machine-
independent code. Move this code into mincore(), and eliminate the
page queues lock from pmap_mincore().
Push down the page queues lock into pmap_clear_modify(),
pmap_clear_reference(), and pmap_is_modified(). Assert that these
functions are never passed an unmanaged page.
Eliminate an inaccurate comment from powerpc/powerpc/mmu_if.m:
Contrary to what the comment says, pmap_mincore() is not simply an
optimization. Without a complete pmap_mincore() implementation,
mincore() cannot return either MINCORE_MODIFIED or MINCORE_REFERENCED
because only the pmap can provide this information.
Eliminate the page queues lock from vfs_setdirty_locked_object(),
vm_pageout_clean(), vm_object_page_collect_flush(), and
vm_object_page_clean(). Generally speaking, these are all accesses
to the page's dirty field, which are synchronized by the containing
vm object's lock.
Reduce the scope of the page queues lock in vm_object_madvise() and
vm_page_dontneed().
Reviewed by: kib (an earlier version)
2010-05-24 14:26:57 +00:00
|
|
|
if (object->type == OBJT_DEFAULT ||
|
|
|
|
object->type == OBJT_SWAP ||
|
|
|
|
object->type == OBJT_VNODE) {
|
|
|
|
pindex = OFF_TO_IDX(current->offset +
|
|
|
|
(addr - current->start));
|
|
|
|
m = vm_page_lookup(object, pindex);
|
2012-04-08 18:25:12 +00:00
|
|
|
if (m == NULL &&
|
|
|
|
vm_page_is_cached(object, pindex))
|
|
|
|
mincoreinfo = MINCORE_INCORE;
|
Roughly half of a typical pmap_mincore() implementation is machine-
independent code. Move this code into mincore(), and eliminate the
page queues lock from pmap_mincore().
Push down the page queues lock into pmap_clear_modify(),
pmap_clear_reference(), and pmap_is_modified(). Assert that these
functions are never passed an unmanaged page.
Eliminate an inaccurate comment from powerpc/powerpc/mmu_if.m:
Contrary to what the comment says, pmap_mincore() is not simply an
optimization. Without a complete pmap_mincore() implementation,
mincore() cannot return either MINCORE_MODIFIED or MINCORE_REFERENCED
because only the pmap can provide this information.
Eliminate the page queues lock from vfs_setdirty_locked_object(),
vm_pageout_clean(), vm_object_page_collect_flush(), and
vm_object_page_clean(). Generally speaking, these are all accesses
to the page's dirty field, which are synchronized by the containing
vm object's lock.
Reduce the scope of the page queues lock in vm_object_madvise() and
vm_page_dontneed().
Reviewed by: kib (an earlier version)
2010-05-24 14:26:57 +00:00
|
|
|
if (m != NULL && m->valid == 0)
|
|
|
|
m = NULL;
|
|
|
|
if (m != NULL)
|
|
|
|
mincoreinfo = MINCORE_INCORE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (m != NULL) {
|
|
|
|
/* Examine other mappings to the page. */
|
|
|
|
if (m->dirty == 0 && pmap_is_modified(m))
|
|
|
|
vm_page_dirty(m);
|
|
|
|
if (m->dirty != 0)
|
|
|
|
mincoreinfo |= MINCORE_MODIFIED_OTHER;
|
2010-05-26 18:00:44 +00:00
|
|
|
/*
|
2011-09-06 10:30:11 +00:00
|
|
|
* The first test for PGA_REFERENCED is an
|
2010-05-26 18:00:44 +00:00
|
|
|
* optimization. The second test is
|
|
|
|
* required because a concurrent pmap
|
|
|
|
* operation could clear the last reference
|
2011-09-06 10:30:11 +00:00
|
|
|
* and set PGA_REFERENCED before the call to
|
2010-05-26 18:00:44 +00:00
|
|
|
* pmap_is_referenced().
|
|
|
|
*/
|
2011-09-06 10:30:11 +00:00
|
|
|
if ((m->aflags & PGA_REFERENCED) != 0 ||
|
2010-05-26 18:00:44 +00:00
|
|
|
pmap_is_referenced(m) ||
|
2011-09-06 10:30:11 +00:00
|
|
|
(m->aflags & PGA_REFERENCED) != 0)
|
Roughly half of a typical pmap_mincore() implementation is machine-
independent code. Move this code into mincore(), and eliminate the
page queues lock from pmap_mincore().
Push down the page queues lock into pmap_clear_modify(),
pmap_clear_reference(), and pmap_is_modified(). Assert that these
functions are never passed an unmanaged page.
Eliminate an inaccurate comment from powerpc/powerpc/mmu_if.m:
Contrary to what the comment says, pmap_mincore() is not simply an
optimization. Without a complete pmap_mincore() implementation,
mincore() cannot return either MINCORE_MODIFIED or MINCORE_REFERENCED
because only the pmap can provide this information.
Eliminate the page queues lock from vfs_setdirty_locked_object(),
vm_pageout_clean(), vm_object_page_collect_flush(), and
vm_object_page_clean(). Generally speaking, these are all accesses
to the page's dirty field, which are synchronized by the containing
vm object's lock.
Reduce the scope of the page queues lock in vm_object_madvise() and
vm_page_dontneed().
Reviewed by: kib (an earlier version)
2010-05-24 14:26:57 +00:00
|
|
|
mincoreinfo |= MINCORE_REFERENCED_OTHER;
|
1996-05-19 07:36:50 +00:00
|
|
|
}
|
Roughly half of a typical pmap_mincore() implementation is machine-
independent code. Move this code into mincore(), and eliminate the
page queues lock from pmap_mincore().
Push down the page queues lock into pmap_clear_modify(),
pmap_clear_reference(), and pmap_is_modified(). Assert that these
functions are never passed an unmanaged page.
Eliminate an inaccurate comment from powerpc/powerpc/mmu_if.m:
Contrary to what the comment says, pmap_mincore() is not simply an
optimization. Without a complete pmap_mincore() implementation,
mincore() cannot return either MINCORE_MODIFIED or MINCORE_REFERENCED
because only the pmap can provide this information.
Eliminate the page queues lock from vfs_setdirty_locked_object(),
vm_pageout_clean(), vm_object_page_collect_flush(), and
vm_object_page_clean(). Generally speaking, these are all accesses
to the page's dirty field, which are synchronized by the containing
vm object's lock.
Reduce the scope of the page queues lock in vm_object_madvise() and
vm_page_dontneed().
Reviewed by: kib (an earlier version)
2010-05-24 14:26:57 +00:00
|
|
|
if (object != NULL)
|
2013-03-09 02:32:23 +00:00
|
|
|
VM_OBJECT_WUNLOCK(object);
|
1996-05-19 07:36:50 +00:00
|
|
|
|
1999-03-02 22:55:02 +00:00
|
|
|
/*
|
|
|
|
* subyte may page fault. In case it needs to modify
|
|
|
|
* the map, we release the lock.
|
|
|
|
*/
|
|
|
|
vm_map_unlock_read(map);
|
|
|
|
|
1996-05-19 07:36:50 +00:00
|
|
|
/*
|
|
|
|
* calculate index into user supplied byte vector
|
|
|
|
*/
|
|
|
|
vecindex = OFF_TO_IDX(addr - first_addr);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If we have skipped map entries, we need to make sure that
|
|
|
|
* the byte vector is zeroed for those skipped entries.
|
|
|
|
*/
|
2001-07-04 19:00:13 +00:00
|
|
|
while ((lastvecindex + 1) < vecindex) {
|
2013-09-12 20:46:32 +00:00
|
|
|
++lastvecindex;
|
2002-03-10 21:52:48 +00:00
|
|
|
error = subyte(vec + lastvecindex, 0);
|
1996-05-19 07:36:50 +00:00
|
|
|
if (error) {
|
2001-08-31 01:26:30 +00:00
|
|
|
error = EFAULT;
|
|
|
|
goto done2;
|
1996-05-19 07:36:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Pass the page information to the user
|
|
|
|
*/
|
2002-03-10 21:52:48 +00:00
|
|
|
error = subyte(vec + vecindex, mincoreinfo);
|
1996-05-19 07:36:50 +00:00
|
|
|
if (error) {
|
2001-08-31 01:26:30 +00:00
|
|
|
error = EFAULT;
|
|
|
|
goto done2;
|
1996-05-19 07:36:50 +00:00
|
|
|
}
|
1999-03-02 22:55:02 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If the map has changed, due to the subyte, the previous
|
|
|
|
* output may be invalid.
|
|
|
|
*/
|
|
|
|
vm_map_lock_read(map);
|
|
|
|
if (timestamp != map->timestamp)
|
|
|
|
goto RestartScan;
|
|
|
|
|
1996-05-19 07:36:50 +00:00
|
|
|
lastvecindex = vecindex;
|
|
|
|
addr += PAGE_SIZE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-03-02 22:55:02 +00:00
|
|
|
/*
|
|
|
|
* subyte may page fault. In case it needs to modify
|
|
|
|
* the map, we release the lock.
|
|
|
|
*/
|
|
|
|
vm_map_unlock_read(map);
|
|
|
|
|
1996-05-19 07:36:50 +00:00
|
|
|
/*
|
|
|
|
* Zero the last entries in the byte vector.
|
|
|
|
*/
|
|
|
|
vecindex = OFF_TO_IDX(end - first_addr);
|
2001-07-04 19:00:13 +00:00
|
|
|
while ((lastvecindex + 1) < vecindex) {
|
2013-09-12 20:46:32 +00:00
|
|
|
++lastvecindex;
|
2002-03-10 21:52:48 +00:00
|
|
|
error = subyte(vec + lastvecindex, 0);
|
1996-05-19 07:36:50 +00:00
|
|
|
if (error) {
|
2001-08-31 01:26:30 +00:00
|
|
|
error = EFAULT;
|
|
|
|
goto done2;
|
1995-10-21 17:42:28 +00:00
|
|
|
}
|
|
|
|
}
|
2003-12-08 02:45:45 +00:00
|
|
|
|
1999-03-02 22:55:02 +00:00
|
|
|
/*
|
|
|
|
* If the map has changed, due to the subyte, the previous
|
|
|
|
* output may be invalid.
|
|
|
|
*/
|
|
|
|
vm_map_lock_read(map);
|
|
|
|
if (timestamp != map->timestamp)
|
|
|
|
goto RestartScan;
|
1999-03-01 20:42:16 +00:00
|
|
|
vm_map_unlock_read(map);
|
2001-08-31 01:26:30 +00:00
|
|
|
done2:
|
|
|
|
return (error);
|
1994-05-24 10:09:53 +00:00
|
|
|
}
|
|
|
|
|
1995-11-12 06:43:28 +00:00
|
|
|
#ifndef _SYS_SYSPROTO_H_
|
1994-05-24 10:09:53 +00:00
|
|
|
struct mlock_args {
|
1997-12-31 02:35:29 +00:00
|
|
|
const void *addr;
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
size_t len;
|
1994-05-24 10:09:53 +00:00
|
|
|
};
|
1995-11-12 06:43:28 +00:00
|
|
|
#endif
|
2001-08-31 01:26:30 +00:00
|
|
|
/*
|
|
|
|
* MPSAFE
|
|
|
|
*/
|
1994-05-24 10:09:53 +00:00
|
|
|
int
|
2011-09-16 13:58:51 +00:00
|
|
|
sys_mlock(td, uap)
|
2001-09-12 08:38:13 +00:00
|
|
|
struct thread *td;
|
1994-05-24 10:09:53 +00:00
|
|
|
struct mlock_args *uap;
|
|
|
|
{
|
2013-06-08 13:13:40 +00:00
|
|
|
|
|
|
|
return (vm_mlock(td->td_proc, td->td_ucred, uap->addr, uap->len));
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
vm_mlock(struct proc *proc, struct ucred *cred, const void *addr0, size_t len)
|
|
|
|
{
|
2004-03-15 09:11:23 +00:00
|
|
|
vm_offset_t addr, end, last, start;
|
|
|
|
vm_size_t npages, size;
|
2013-01-10 12:43:58 +00:00
|
|
|
vm_map_t map;
|
2011-04-05 20:23:59 +00:00
|
|
|
unsigned long nsize;
|
2004-03-15 09:11:23 +00:00
|
|
|
int error;
|
1994-05-24 10:09:53 +00:00
|
|
|
|
2013-06-08 13:13:40 +00:00
|
|
|
error = priv_check_cred(cred, PRIV_VM_MLOCK, 0);
|
2004-02-26 00:27:04 +00:00
|
|
|
if (error)
|
|
|
|
return (error);
|
2013-06-08 13:13:40 +00:00
|
|
|
addr = (vm_offset_t)addr0;
|
|
|
|
size = len;
|
2004-03-15 09:11:23 +00:00
|
|
|
last = addr + size;
|
2004-03-05 22:03:11 +00:00
|
|
|
start = trunc_page(addr);
|
2004-03-15 09:11:23 +00:00
|
|
|
end = round_page(last);
|
|
|
|
if (last < addr || end < addr)
|
1994-05-24 10:09:53 +00:00
|
|
|
return (EINVAL);
|
2004-03-05 22:03:11 +00:00
|
|
|
npages = atop(end - start);
|
|
|
|
if (npages > vm_page_max_wired)
|
|
|
|
return (ENOMEM);
|
2013-01-10 12:43:58 +00:00
|
|
|
map = &proc->p_vmspace->vm_map;
|
2004-02-26 00:27:04 +00:00
|
|
|
PROC_LOCK(proc);
|
2013-01-10 12:43:58 +00:00
|
|
|
nsize = ptoa(npages + pmap_wired_count(map->pmap));
|
2015-06-10 10:48:12 +00:00
|
|
|
if (nsize > lim_cur_proc(proc, RLIMIT_MEMLOCK)) {
|
2004-02-26 00:27:04 +00:00
|
|
|
PROC_UNLOCK(proc);
|
1997-06-15 23:35:32 +00:00
|
|
|
return (ENOMEM);
|
2004-02-04 21:52:57 +00:00
|
|
|
}
|
2004-02-26 00:27:04 +00:00
|
|
|
PROC_UNLOCK(proc);
|
2014-03-22 10:26:09 +00:00
|
|
|
if (npages + vm_cnt.v_wire_count > vm_page_max_wired)
|
2004-03-05 22:03:11 +00:00
|
|
|
return (EAGAIN);
|
2011-07-06 20:06:44 +00:00
|
|
|
#ifdef RACCT
|
2015-04-29 10:23:02 +00:00
|
|
|
if (racct_enable) {
|
|
|
|
PROC_LOCK(proc);
|
|
|
|
error = racct_set(proc, RACCT_MEMLOCK, nsize);
|
|
|
|
PROC_UNLOCK(proc);
|
|
|
|
if (error != 0)
|
|
|
|
return (ENOMEM);
|
|
|
|
}
|
2011-07-06 20:06:44 +00:00
|
|
|
#endif
|
2013-01-10 12:43:58 +00:00
|
|
|
error = vm_map_wire(map, start, end,
|
2004-03-15 06:43:51 +00:00
|
|
|
VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES);
|
2011-07-06 20:06:44 +00:00
|
|
|
#ifdef RACCT
|
2015-04-29 10:23:02 +00:00
|
|
|
if (racct_enable && error != KERN_SUCCESS) {
|
2011-04-05 20:23:59 +00:00
|
|
|
PROC_LOCK(proc);
|
|
|
|
racct_set(proc, RACCT_MEMLOCK,
|
2013-01-10 12:43:58 +00:00
|
|
|
ptoa(pmap_wired_count(map->pmap)));
|
2011-04-05 20:23:59 +00:00
|
|
|
PROC_UNLOCK(proc);
|
|
|
|
}
|
2011-07-06 20:06:44 +00:00
|
|
|
#endif
|
1994-05-24 10:09:53 +00:00
|
|
|
return (error == KERN_SUCCESS ? 0 : ENOMEM);
|
|
|
|
}
|
|
|
|
|
1997-06-15 23:35:32 +00:00
|
|
|
#ifndef _SYS_SYSPROTO_H_
|
|
|
|
struct mlockall_args {
|
|
|
|
int how;
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2001-08-31 01:26:30 +00:00
|
|
|
/*
|
|
|
|
* MPSAFE
|
|
|
|
*/
|
1997-06-15 23:35:32 +00:00
|
|
|
int
|
2011-09-16 13:58:51 +00:00
|
|
|
sys_mlockall(td, uap)
|
2001-09-12 08:38:13 +00:00
|
|
|
struct thread *td;
|
1997-06-15 23:35:32 +00:00
|
|
|
struct mlockall_args *uap;
|
|
|
|
{
|
2003-08-11 07:14:08 +00:00
|
|
|
vm_map_t map;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
map = &td->td_proc->p_vmspace->vm_map;
|
2012-12-18 07:35:01 +00:00
|
|
|
error = priv_check(td, PRIV_VM_MLOCK);
|
|
|
|
if (error)
|
|
|
|
return (error);
|
2003-08-11 07:14:08 +00:00
|
|
|
|
|
|
|
if ((uap->how == 0) || ((uap->how & ~(MCL_CURRENT|MCL_FUTURE)) != 0))
|
|
|
|
return (EINVAL);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If wiring all pages in the process would cause it to exceed
|
|
|
|
* a hard resource limit, return ENOMEM.
|
|
|
|
*/
|
2012-12-18 07:35:01 +00:00
|
|
|
if (!old_mlock && uap->how & MCL_CURRENT) {
|
|
|
|
PROC_LOCK(td->td_proc);
|
2015-06-10 10:48:12 +00:00
|
|
|
if (map->size > lim_cur(td, RLIMIT_MEMLOCK)) {
|
2012-12-18 07:35:01 +00:00
|
|
|
PROC_UNLOCK(td->td_proc);
|
|
|
|
return (ENOMEM);
|
|
|
|
}
|
2004-02-04 21:52:57 +00:00
|
|
|
PROC_UNLOCK(td->td_proc);
|
|
|
|
}
|
2011-07-06 20:06:44 +00:00
|
|
|
#ifdef RACCT
|
2015-04-29 10:23:02 +00:00
|
|
|
if (racct_enable) {
|
|
|
|
PROC_LOCK(td->td_proc);
|
|
|
|
error = racct_set(td->td_proc, RACCT_MEMLOCK, map->size);
|
|
|
|
PROC_UNLOCK(td->td_proc);
|
|
|
|
if (error != 0)
|
|
|
|
return (ENOMEM);
|
|
|
|
}
|
2011-07-06 20:06:44 +00:00
|
|
|
#endif
|
2003-08-11 07:14:08 +00:00
|
|
|
|
|
|
|
if (uap->how & MCL_FUTURE) {
|
|
|
|
vm_map_lock(map);
|
|
|
|
vm_map_modflags(map, MAP_WIREFUTURE, 0);
|
|
|
|
vm_map_unlock(map);
|
|
|
|
error = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uap->how & MCL_CURRENT) {
|
|
|
|
/*
|
|
|
|
* P1003.1-2001 mandates that all currently mapped pages
|
|
|
|
* will be memory resident and locked (wired) upon return
|
|
|
|
* from mlockall(). vm_map_wire() will wire pages, by
|
|
|
|
* calling vm_fault_wire() for each page in the region.
|
|
|
|
*/
|
|
|
|
error = vm_map_wire(map, vm_map_min(map), vm_map_max(map),
|
|
|
|
VM_MAP_WIRE_USER|VM_MAP_WIRE_HOLESOK);
|
|
|
|
error = (error == KERN_SUCCESS ? 0 : EAGAIN);
|
|
|
|
}
|
2011-07-06 20:06:44 +00:00
|
|
|
#ifdef RACCT
|
2015-04-29 10:23:02 +00:00
|
|
|
if (racct_enable && error != KERN_SUCCESS) {
|
2011-04-05 20:23:59 +00:00
|
|
|
PROC_LOCK(td->td_proc);
|
|
|
|
racct_set(td->td_proc, RACCT_MEMLOCK,
|
2013-01-10 12:43:58 +00:00
|
|
|
ptoa(pmap_wired_count(map->pmap)));
|
2011-04-05 20:23:59 +00:00
|
|
|
PROC_UNLOCK(td->td_proc);
|
|
|
|
}
|
2011-07-06 20:06:44 +00:00
|
|
|
#endif
|
2003-08-11 07:14:08 +00:00
|
|
|
|
|
|
|
return (error);
|
1997-06-15 23:35:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef _SYS_SYSPROTO_H_
|
2002-06-06 18:51:14 +00:00
|
|
|
struct munlockall_args {
|
2003-08-11 07:14:08 +00:00
|
|
|
register_t dummy;
|
1997-06-15 23:35:32 +00:00
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2001-08-31 01:26:30 +00:00
|
|
|
/*
|
|
|
|
* MPSAFE
|
|
|
|
*/
|
1997-06-15 23:35:32 +00:00
|
|
|
int
|
2011-09-16 13:58:51 +00:00
|
|
|
sys_munlockall(td, uap)
|
2001-09-12 08:38:13 +00:00
|
|
|
struct thread *td;
|
1997-06-15 23:35:32 +00:00
|
|
|
struct munlockall_args *uap;
|
|
|
|
{
|
2003-08-11 07:14:08 +00:00
|
|
|
vm_map_t map;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
map = &td->td_proc->p_vmspace->vm_map;
|
2006-11-06 13:42:10 +00:00
|
|
|
error = priv_check(td, PRIV_VM_MUNLOCK);
|
2003-08-11 07:14:08 +00:00
|
|
|
if (error)
|
|
|
|
return (error);
|
|
|
|
|
|
|
|
/* Clear the MAP_WIREFUTURE flag from this vm_map. */
|
|
|
|
vm_map_lock(map);
|
|
|
|
vm_map_modflags(map, 0, MAP_WIREFUTURE);
|
|
|
|
vm_map_unlock(map);
|
|
|
|
|
|
|
|
/* Forcibly unwire all pages. */
|
|
|
|
error = vm_map_unwire(map, vm_map_min(map), vm_map_max(map),
|
|
|
|
VM_MAP_WIRE_USER|VM_MAP_WIRE_HOLESOK);
|
2011-07-06 20:06:44 +00:00
|
|
|
#ifdef RACCT
|
2015-04-29 10:23:02 +00:00
|
|
|
if (racct_enable && error == KERN_SUCCESS) {
|
2011-04-05 20:23:59 +00:00
|
|
|
PROC_LOCK(td->td_proc);
|
|
|
|
racct_set(td->td_proc, RACCT_MEMLOCK, 0);
|
|
|
|
PROC_UNLOCK(td->td_proc);
|
|
|
|
}
|
2011-07-06 20:06:44 +00:00
|
|
|
#endif
|
2003-08-11 07:14:08 +00:00
|
|
|
|
|
|
|
return (error);
|
1997-06-15 23:35:32 +00:00
|
|
|
}
|
|
|
|
|
1995-11-12 06:43:28 +00:00
|
|
|
#ifndef _SYS_SYSPROTO_H_
|
1994-05-24 10:09:53 +00:00
|
|
|
struct munlock_args {
|
1997-12-31 02:35:29 +00:00
|
|
|
const void *addr;
|
These changes embody the support of the fully coherent merged VM buffer cache,
much higher filesystem I/O performance, and much better paging performance. It
represents the culmination of over 6 months of R&D.
The majority of the merged VM/cache work is by John Dyson.
The following highlights the most significant changes. Additionally, there are
(mostly minor) changes to the various filesystem modules (nfs, msdosfs, etc) to
support the new VM/buffer scheme.
vfs_bio.c:
Significant rewrite of most of vfs_bio to support the merged VM buffer cache
scheme. The scheme is almost fully compatible with the old filesystem
interface. Significant improvement in the number of opportunities for write
clustering.
vfs_cluster.c, vfs_subr.c
Upgrade and performance enhancements in vfs layer code to support merged
VM/buffer cache. Fixup of vfs_cluster to eliminate the bogus pagemove stuff.
vm_object.c:
Yet more improvements in the collapse code. Elimination of some windows that
can cause list corruption.
vm_pageout.c:
Fixed it, it really works better now. Somehow in 2.0, some "enhancements"
broke the code. This code has been reworked from the ground-up.
vm_fault.c, vm_page.c, pmap.c, vm_object.c
Support for small-block filesystems with merged VM/buffer cache scheme.
pmap.c vm_map.c
Dynamic kernel VM size, now we dont have to pre-allocate excessive numbers of
kernel PTs.
vm_glue.c
Much simpler and more effective swapping code. No more gratuitous swapping.
proc.h
Fixed the problem that the p_lock flag was not being cleared on a fork.
swap_pager.c, vnode_pager.c
Removal of old vfs_bio cruft to support the past pseudo-coherency. Now the
code doesn't need it anymore.
machdep.c
Changes to better support the parameter values for the merged VM/buffer cache
scheme.
machdep.c, kern_exec.c, vm_glue.c
Implemented a seperate submap for temporary exec string space and another one
to contain process upages. This eliminates all map fragmentation problems
that previously existed.
ffs_inode.c, ufs_inode.c, ufs_readwrite.c
Changes for merged VM/buffer cache. Add "bypass" support for sneaking in on
busy buffers.
Submitted by: John Dyson and David Greenman
1995-01-09 16:06:02 +00:00
|
|
|
size_t len;
|
1994-05-24 10:09:53 +00:00
|
|
|
};
|
1995-11-12 06:43:28 +00:00
|
|
|
#endif
|
2001-08-31 01:26:30 +00:00
|
|
|
/*
|
|
|
|
* MPSAFE
|
|
|
|
*/
|
1994-05-24 10:09:53 +00:00
|
|
|
int
|
2011-09-16 13:58:51 +00:00
|
|
|
sys_munlock(td, uap)
|
2001-09-12 08:38:13 +00:00
|
|
|
struct thread *td;
|
1994-05-24 10:09:53 +00:00
|
|
|
struct munlock_args *uap;
|
|
|
|
{
|
2004-03-15 09:11:23 +00:00
|
|
|
vm_offset_t addr, end, last, start;
|
2004-03-05 22:03:11 +00:00
|
|
|
vm_size_t size;
|
2013-07-22 22:16:47 +00:00
|
|
|
#ifdef RACCT
|
2013-07-22 21:47:14 +00:00
|
|
|
vm_map_t map;
|
2013-07-22 22:16:47 +00:00
|
|
|
#endif
|
1994-05-24 10:09:53 +00:00
|
|
|
int error;
|
|
|
|
|
2006-11-06 13:42:10 +00:00
|
|
|
error = priv_check(td, PRIV_VM_MUNLOCK);
|
2004-02-26 00:27:04 +00:00
|
|
|
if (error)
|
|
|
|
return (error);
|
2004-03-05 22:03:11 +00:00
|
|
|
addr = (vm_offset_t)uap->addr;
|
|
|
|
size = uap->len;
|
2004-03-15 09:11:23 +00:00
|
|
|
last = addr + size;
|
2004-03-05 22:03:11 +00:00
|
|
|
start = trunc_page(addr);
|
2004-03-15 09:11:23 +00:00
|
|
|
end = round_page(last);
|
|
|
|
if (last < addr || end < addr)
|
1994-05-24 10:09:53 +00:00
|
|
|
return (EINVAL);
|
2004-03-05 22:03:11 +00:00
|
|
|
error = vm_map_unwire(&td->td_proc->p_vmspace->vm_map, start, end,
|
2004-03-15 06:43:51 +00:00
|
|
|
VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES);
|
2011-07-06 20:06:44 +00:00
|
|
|
#ifdef RACCT
|
2015-04-29 10:23:02 +00:00
|
|
|
if (racct_enable && error == KERN_SUCCESS) {
|
2011-04-05 20:23:59 +00:00
|
|
|
PROC_LOCK(td->td_proc);
|
2013-07-22 21:47:14 +00:00
|
|
|
map = &td->td_proc->p_vmspace->vm_map;
|
|
|
|
racct_set(td->td_proc, RACCT_MEMLOCK,
|
|
|
|
ptoa(pmap_wired_count(map->pmap)));
|
2011-04-05 20:23:59 +00:00
|
|
|
PROC_UNLOCK(td->td_proc);
|
|
|
|
}
|
2011-07-06 20:06:44 +00:00
|
|
|
#endif
|
1994-05-24 10:09:53 +00:00
|
|
|
return (error == KERN_SUCCESS ? 0 : ENOMEM);
|
|
|
|
}
|
|
|
|
|
2004-02-27 22:02:15 +00:00
|
|
|
/*
|
|
|
|
* vm_mmap_vnode()
|
|
|
|
*
|
|
|
|
* Helper function for vm_mmap. Perform sanity check specific for mmap
|
|
|
|
* operations on vnodes.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
vm_mmap_vnode(struct thread *td, vm_size_t objsize,
|
|
|
|
vm_prot_t prot, vm_prot_t *maxprotp, int *flagsp,
|
2012-02-23 21:07:16 +00:00
|
|
|
struct vnode *vp, vm_ooffset_t *foffp, vm_object_t *objp,
|
|
|
|
boolean_t *writecounted)
|
2004-02-27 22:02:15 +00:00
|
|
|
{
|
|
|
|
struct vattr va;
|
|
|
|
vm_object_t obj;
|
2009-06-01 21:32:52 +00:00
|
|
|
vm_offset_t foff;
|
2008-08-28 15:23:18 +00:00
|
|
|
struct ucred *cred;
|
2012-10-22 17:50:54 +00:00
|
|
|
int error, flags, locktype;
|
2004-02-27 22:02:15 +00:00
|
|
|
|
2008-08-28 15:23:18 +00:00
|
|
|
cred = td->td_ucred;
|
2012-02-23 21:07:16 +00:00
|
|
|
if ((*maxprotp & VM_PROT_WRITE) && (*flagsp & MAP_SHARED))
|
|
|
|
locktype = LK_EXCLUSIVE;
|
|
|
|
else
|
|
|
|
locktype = LK_SHARED;
|
2012-10-22 17:50:54 +00:00
|
|
|
if ((error = vget(vp, locktype, td)) != 0)
|
2004-02-27 22:02:15 +00:00
|
|
|
return (error);
|
2009-06-01 21:32:52 +00:00
|
|
|
foff = *foffp;
|
2004-02-27 22:02:15 +00:00
|
|
|
flags = *flagsp;
|
2005-01-25 00:40:01 +00:00
|
|
|
obj = vp->v_object;
|
2004-02-27 22:02:15 +00:00
|
|
|
if (vp->v_type == VREG) {
|
|
|
|
/*
|
|
|
|
* Get the proper underlying object
|
|
|
|
*/
|
2005-01-25 00:40:01 +00:00
|
|
|
if (obj == NULL) {
|
2004-02-27 22:02:15 +00:00
|
|
|
error = EINVAL;
|
|
|
|
goto done;
|
|
|
|
}
|
2013-04-28 19:25:09 +00:00
|
|
|
if (obj->type == OBJT_VNODE && obj->handle != vp) {
|
2004-02-27 22:02:15 +00:00
|
|
|
vput(vp);
|
2012-02-23 21:07:16 +00:00
|
|
|
vp = (struct vnode *)obj->handle;
|
|
|
|
/*
|
|
|
|
* Bypass filesystems obey the mpsafety of the
|
2013-05-02 18:35:12 +00:00
|
|
|
* underlying fs. Tmpfs never bypasses.
|
2012-02-23 21:07:16 +00:00
|
|
|
*/
|
|
|
|
error = vget(vp, locktype, td);
|
2012-10-22 17:50:54 +00:00
|
|
|
if (error != 0)
|
2012-02-23 21:07:16 +00:00
|
|
|
return (error);
|
2012-02-24 10:41:58 +00:00
|
|
|
}
|
|
|
|
if (locktype == LK_EXCLUSIVE) {
|
|
|
|
*writecounted = TRUE;
|
|
|
|
vnode_pager_update_writecount(obj, 0, objsize);
|
2004-02-27 22:02:15 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
error = EINVAL;
|
|
|
|
goto done;
|
|
|
|
}
|
2008-08-28 15:23:18 +00:00
|
|
|
if ((error = VOP_GETATTR(vp, &va, cred)))
|
2004-02-27 22:02:15 +00:00
|
|
|
goto done;
|
2005-04-14 16:03:30 +00:00
|
|
|
#ifdef MAC
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
/* This relies on VM_PROT_* matching PROT_*. */
|
|
|
|
error = mac_vnode_check_mmap(cred, vp, (int)prot, flags);
|
2005-04-14 16:03:30 +00:00
|
|
|
if (error != 0)
|
|
|
|
goto done;
|
|
|
|
#endif
|
2004-02-27 22:02:15 +00:00
|
|
|
if ((flags & MAP_SHARED) != 0) {
|
|
|
|
if ((va.va_flags & (SF_SNAPSHOT|IMMUTABLE|APPEND)) != 0) {
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
if (prot & VM_PROT_WRITE) {
|
2004-02-27 22:02:15 +00:00
|
|
|
error = EPERM;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
*maxprotp &= ~VM_PROT_WRITE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* If it is a regular file without any references
|
|
|
|
* we do not need to sync it.
|
|
|
|
* Adjust object size to be the size of actual file.
|
|
|
|
*/
|
2009-06-01 21:32:52 +00:00
|
|
|
objsize = round_page(va.va_size);
|
|
|
|
if (va.va_nlink == 0)
|
|
|
|
flags |= MAP_NOSYNC;
|
2015-03-21 17:56:55 +00:00
|
|
|
if (obj->type == OBJT_VNODE) {
|
2013-04-28 19:25:09 +00:00
|
|
|
obj = vm_pager_allocate(OBJT_VNODE, vp, objsize, prot, foff,
|
|
|
|
cred);
|
2015-03-21 17:56:55 +00:00
|
|
|
if (obj == NULL) {
|
|
|
|
error = ENOMEM;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
} else {
|
2013-04-28 19:25:09 +00:00
|
|
|
KASSERT(obj->type == OBJT_DEFAULT || obj->type == OBJT_SWAP,
|
|
|
|
("wrong object type"));
|
2015-03-21 17:56:55 +00:00
|
|
|
VM_OBJECT_WLOCK(obj);
|
|
|
|
vm_object_reference_locked(obj);
|
|
|
|
#if VM_NRESERVLEVEL > 0
|
|
|
|
vm_object_color(obj, 0);
|
|
|
|
#endif
|
|
|
|
VM_OBJECT_WUNLOCK(obj);
|
2004-02-27 22:02:15 +00:00
|
|
|
}
|
|
|
|
*objp = obj;
|
|
|
|
*flagsp = flags;
|
2009-06-01 21:32:52 +00:00
|
|
|
|
2008-08-28 15:23:18 +00:00
|
|
|
vfs_mark_atime(vp, cred);
|
2005-10-04 14:58:58 +00:00
|
|
|
|
2004-02-27 22:02:15 +00:00
|
|
|
done:
|
2013-03-28 06:39:27 +00:00
|
|
|
if (error != 0 && *writecounted) {
|
|
|
|
*writecounted = FALSE;
|
|
|
|
vnode_pager_update_writecount(obj, objsize, 0);
|
|
|
|
}
|
2004-02-27 22:02:15 +00:00
|
|
|
vput(vp);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
2005-04-01 20:00:11 +00:00
|
|
|
/*
|
|
|
|
* vm_mmap_cdev()
|
|
|
|
*
|
|
|
|
* MPSAFE
|
|
|
|
*
|
|
|
|
* Helper function for vm_mmap. Perform sanity check specific for mmap
|
|
|
|
* operations on cdevs.
|
|
|
|
*/
|
|
|
|
int
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
vm_mmap_cdev(struct thread *td, vm_size_t objsize, vm_prot_t prot,
|
|
|
|
vm_prot_t *maxprotp, int *flagsp, struct cdev *cdev, struct cdevsw *dsw,
|
|
|
|
vm_ooffset_t *foff, vm_object_t *objp)
|
2005-04-01 20:00:11 +00:00
|
|
|
{
|
|
|
|
vm_object_t obj;
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
int error, flags;
|
2005-04-01 20:00:11 +00:00
|
|
|
|
|
|
|
flags = *flagsp;
|
|
|
|
|
2008-03-20 16:08:42 +00:00
|
|
|
if (dsw->d_flags & D_MMAP_ANON) {
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
*objp = NULL;
|
|
|
|
*foff = 0;
|
2005-04-01 20:00:11 +00:00
|
|
|
*maxprotp = VM_PROT_ALL;
|
|
|
|
*flagsp |= MAP_ANON;
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
/*
|
2009-06-01 21:32:52 +00:00
|
|
|
* cdevs do not provide private mappings of any kind.
|
2005-04-01 20:00:11 +00:00
|
|
|
*/
|
|
|
|
if ((*maxprotp & VM_PROT_WRITE) == 0 &&
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
(prot & VM_PROT_WRITE) != 0)
|
2005-04-01 20:00:11 +00:00
|
|
|
return (EACCES);
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
if (flags & (MAP_PRIVATE|MAP_COPY))
|
2005-04-01 20:00:11 +00:00
|
|
|
return (EINVAL);
|
|
|
|
/*
|
|
|
|
* Force device mappings to be shared.
|
|
|
|
*/
|
|
|
|
flags |= MAP_SHARED;
|
|
|
|
#ifdef MAC_XXX
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
error = mac_cdev_check_mmap(td->td_ucred, cdev, (int)prot);
|
|
|
|
if (error != 0)
|
2005-04-01 20:00:11 +00:00
|
|
|
return (error);
|
|
|
|
#endif
|
2009-06-01 21:32:52 +00:00
|
|
|
/*
|
|
|
|
* First, try d_mmap_single(). If that is not implemented
|
|
|
|
* (returns ENODEV), fall back to using the device pager.
|
|
|
|
* Note that d_mmap_single() must return a reference to the
|
|
|
|
* object (it needs to bump the reference count of the object
|
|
|
|
* it returns somehow).
|
|
|
|
*
|
|
|
|
* XXX assumes VM_PROT_* == PROT_*
|
|
|
|
*/
|
|
|
|
error = dsw->d_mmap_single(cdev, foff, objsize, objp, (int)prot);
|
|
|
|
if (error != ENODEV)
|
|
|
|
return (error);
|
Implement global and per-uid accounting of the anonymous memory. Add
rlimit RLIMIT_SWAP that limits the amount of swap that may be reserved
for the uid.
The accounting information (charge) is associated with either map entry,
or vm object backing the entry, assuming the object is the first one
in the shadow chain and entry does not require COW. Charge is moved
from entry to object on allocation of the object, e.g. during the mmap,
assuming the object is allocated, or on the first page fault on the
entry. It moves back to the entry on forks due to COW setup.
The per-entry granularity of accounting makes the charge process fair
for processes that change uid during lifetime, and decrements charge
for proper uid when region is unmapped.
The interface of vm_pager_allocate(9) is extended by adding struct ucred *,
that is used to charge appropriate uid when allocation if performed by
kernel, e.g. md(4).
Several syscalls, among them is fork(2), may now return ENOMEM when
global or per-uid limits are enforced.
In collaboration with: pho
Reviewed by: alc
Approved by: re (kensmith)
2009-06-23 20:45:22 +00:00
|
|
|
obj = vm_pager_allocate(OBJT_DEVICE, cdev, objsize, prot, *foff,
|
|
|
|
td->td_ucred);
|
2005-04-01 20:00:11 +00:00
|
|
|
if (obj == NULL)
|
|
|
|
return (EINVAL);
|
|
|
|
*objp = obj;
|
|
|
|
*flagsp = flags;
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
/*
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
* vm_mmap()
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
*
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
* Internal version of mmap used by exec, sys5 shared memory, and
|
|
|
|
* various device drivers. Handle is either a vnode pointer, a
|
|
|
|
* character device, or NULL for MAP_ANON.
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
*/
|
|
|
|
int
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
|
|
|
|
vm_prot_t maxprot, int flags,
|
|
|
|
objtype_t handle_type, void *handle,
|
|
|
|
vm_ooffset_t foff)
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
{
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
vm_object_t object;
|
|
|
|
struct thread *td = curthread;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
int error;
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
boolean_t writecounted;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
if (size == 0)
|
|
|
|
return (EINVAL);
|
|
|
|
|
|
|
|
size = round_page(size);
|
|
|
|
writecounted = FALSE;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Lookup/allocate object.
|
|
|
|
*/
|
|
|
|
switch (handle_type) {
|
|
|
|
case OBJT_DEVICE: {
|
|
|
|
struct cdevsw *dsw;
|
|
|
|
struct cdev *cdev;
|
|
|
|
int ref;
|
|
|
|
|
|
|
|
cdev = handle;
|
|
|
|
dsw = dev_refthread(cdev, &ref);
|
|
|
|
if (dsw == NULL)
|
|
|
|
return (ENXIO);
|
|
|
|
error = vm_mmap_cdev(td, size, prot, &maxprot, &flags, cdev,
|
|
|
|
dsw, &foff, &object);
|
|
|
|
dev_relthread(cdev, ref);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case OBJT_VNODE:
|
|
|
|
error = vm_mmap_vnode(td, size, prot, &maxprot, &flags,
|
|
|
|
handle, &foff, &object, &writecounted);
|
|
|
|
break;
|
|
|
|
case OBJT_DEFAULT:
|
|
|
|
if (handle == NULL) {
|
|
|
|
error = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* FALLTHROUGH */
|
|
|
|
default:
|
|
|
|
error = EINVAL;
|
|
|
|
break;
|
|
|
|
}
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
if (error)
|
|
|
|
return (error);
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
|
|
|
|
error = vm_mmap_object(map, addr, size, prot, maxprot, flags, object,
|
|
|
|
foff, writecounted, td);
|
|
|
|
if (error != 0 && object != NULL) {
|
|
|
|
/*
|
|
|
|
* If this mapping was accounted for in the vnode's
|
|
|
|
* writecount, then undo that now.
|
|
|
|
*/
|
|
|
|
if (writecounted)
|
|
|
|
vnode_pager_release_writecount(object, 0, size);
|
|
|
|
vm_object_deallocate(object);
|
|
|
|
}
|
|
|
|
return (error);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
}
|
|
|
|
|
1994-05-24 10:09:53 +00:00
|
|
|
/*
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
* Internal version of mmap that maps a specific VM object into an
|
|
|
|
* map. Called by mmap for MAP_ANON, vm_mmap, shm_mmap, and vn_mmap.
|
1994-05-24 10:09:53 +00:00
|
|
|
*/
|
|
|
|
int
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
vm_mmap_object(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
|
|
|
|
vm_prot_t maxprot, int flags, vm_object_t object, vm_ooffset_t foff,
|
|
|
|
boolean_t writecounted, struct thread *td)
|
1994-05-24 10:09:53 +00:00
|
|
|
{
|
|
|
|
boolean_t fitit;
|
2013-08-16 21:13:55 +00:00
|
|
|
int docow, error, findspace, rv;
|
1994-05-24 10:09:53 +00:00
|
|
|
|
2012-02-16 06:45:51 +00:00
|
|
|
if (map == &td->td_proc->p_vmspace->vm_map) {
|
|
|
|
PROC_LOCK(td->td_proc);
|
2015-06-10 10:48:12 +00:00
|
|
|
if (map->size + size > lim_cur_proc(td->td_proc, RLIMIT_VMEM)) {
|
2012-02-16 06:45:51 +00:00
|
|
|
PROC_UNLOCK(td->td_proc);
|
|
|
|
return (ENOMEM);
|
|
|
|
}
|
|
|
|
if (racct_set(td->td_proc, RACCT_VMEM, map->size + size)) {
|
|
|
|
PROC_UNLOCK(td->td_proc);
|
|
|
|
return (ENOMEM);
|
|
|
|
}
|
2012-12-18 07:35:01 +00:00
|
|
|
if (!old_mlock && map->flags & MAP_WIREFUTURE) {
|
2013-01-10 12:43:58 +00:00
|
|
|
if (ptoa(pmap_wired_count(map->pmap)) + size >
|
2015-06-10 10:48:12 +00:00
|
|
|
lim_cur_proc(td->td_proc, RLIMIT_MEMLOCK)) {
|
2012-12-18 07:35:01 +00:00
|
|
|
racct_set_force(td->td_proc, RACCT_VMEM,
|
|
|
|
map->size);
|
|
|
|
PROC_UNLOCK(td->td_proc);
|
|
|
|
return (ENOMEM);
|
|
|
|
}
|
|
|
|
error = racct_set(td->td_proc, RACCT_MEMLOCK,
|
2013-01-10 12:43:58 +00:00
|
|
|
ptoa(pmap_wired_count(map->pmap)) + size);
|
2012-12-18 07:35:01 +00:00
|
|
|
if (error != 0) {
|
|
|
|
racct_set_force(td->td_proc, RACCT_VMEM,
|
|
|
|
map->size);
|
|
|
|
PROC_UNLOCK(td->td_proc);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
}
|
2011-04-05 20:23:59 +00:00
|
|
|
PROC_UNLOCK(td->td_proc);
|
|
|
|
}
|
2002-06-26 00:29:28 +00:00
|
|
|
|
1995-03-21 10:15:52 +00:00
|
|
|
/*
|
|
|
|
* We currently can only deal with page aligned file offsets.
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
* The mmap() system call already enforces this by subtracting
|
|
|
|
* the page offset from the file offset, but checking here
|
|
|
|
* catches errors in device drivers (e.g. d_single_mmap()
|
|
|
|
* callbacks) and other internal mapping requests (such as in
|
|
|
|
* exec).
|
1995-03-21 10:15:52 +00:00
|
|
|
*/
|
|
|
|
if (foff & PAGE_MASK)
|
|
|
|
return (EINVAL);
|
|
|
|
|
1995-07-09 06:58:03 +00:00
|
|
|
if ((flags & MAP_FIXED) == 0) {
|
|
|
|
fitit = TRUE;
|
|
|
|
*addr = round_page(*addr);
|
|
|
|
} else {
|
|
|
|
if (*addr != trunc_page(*addr))
|
|
|
|
return (EINVAL);
|
|
|
|
fitit = FALSE;
|
|
|
|
}
|
2012-02-23 21:07:16 +00:00
|
|
|
|
2004-02-27 22:02:15 +00:00
|
|
|
if (flags & MAP_ANON) {
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
if (object != NULL || foff != 0)
|
|
|
|
return (EINVAL);
|
1999-06-05 18:21:53 +00:00
|
|
|
docow = 0;
|
2010-08-28 16:57:07 +00:00
|
|
|
} else if (flags & MAP_PREFAULT_READ)
|
|
|
|
docow = MAP_PREFAULT;
|
|
|
|
else
|
1999-06-05 18:21:53 +00:00
|
|
|
docow = MAP_PREFAULT_PARTIAL;
|
1994-05-24 10:09:53 +00:00
|
|
|
|
1999-12-12 03:19:33 +00:00
|
|
|
if ((flags & (MAP_ANON|MAP_SHARED)) == 0)
|
1999-06-05 18:21:53 +00:00
|
|
|
docow |= MAP_COPY_ON_WRITE;
|
1999-12-12 03:19:33 +00:00
|
|
|
if (flags & MAP_NOSYNC)
|
|
|
|
docow |= MAP_DISABLE_SYNCER;
|
2000-02-28 04:10:35 +00:00
|
|
|
if (flags & MAP_NOCORE)
|
|
|
|
docow |= MAP_DISABLE_COREDUMP;
|
2012-02-11 17:29:07 +00:00
|
|
|
/* Shared memory is also shared with children. */
|
|
|
|
if (flags & MAP_SHARED)
|
|
|
|
docow |= MAP_INHERIT_SHARE;
|
2012-02-23 21:07:16 +00:00
|
|
|
if (writecounted)
|
|
|
|
docow |= MAP_VN_WRITECOUNT;
|
2014-06-09 03:37:41 +00:00
|
|
|
if (flags & MAP_STACK) {
|
|
|
|
if (object != NULL)
|
|
|
|
return (EINVAL);
|
|
|
|
docow |= MAP_STACK_GROWS_DOWN;
|
|
|
|
}
|
2014-06-19 05:00:39 +00:00
|
|
|
if ((flags & MAP_EXCL) != 0)
|
|
|
|
docow |= MAP_CHECK_EXCL;
|
1996-03-12 02:27:20 +00:00
|
|
|
|
2014-06-09 03:37:41 +00:00
|
|
|
if (fitit) {
|
2013-08-16 21:13:55 +00:00
|
|
|
if ((flags & MAP_ALIGNMENT_MASK) == MAP_ALIGNED_SUPER)
|
|
|
|
findspace = VMFS_SUPER_SPACE;
|
|
|
|
else if ((flags & MAP_ALIGNMENT_MASK) != 0)
|
|
|
|
findspace = VMFS_ALIGNED_SPACE(flags >>
|
|
|
|
MAP_ALIGNMENT_SHIFT);
|
|
|
|
else
|
|
|
|
findspace = VMFS_OPTIMAL_SPACE;
|
2013-09-09 18:11:59 +00:00
|
|
|
rv = vm_map_find(map, object, foff, addr, size,
|
|
|
|
#ifdef MAP_32BIT
|
|
|
|
flags & MAP_32BIT ? MAP_32BIT_MAX_ADDR :
|
|
|
|
#endif
|
|
|
|
0, findspace, prot, maxprot, docow);
|
2014-06-09 03:37:41 +00:00
|
|
|
} else {
|
2008-04-28 05:30:23 +00:00
|
|
|
rv = vm_map_fixed(map, object, foff, *addr, size,
|
2014-06-09 03:37:41 +00:00
|
|
|
prot, maxprot, docow);
|
|
|
|
}
|
1996-07-30 03:08:57 +00:00
|
|
|
|
2012-02-25 21:06:39 +00:00
|
|
|
if (rv == KERN_SUCCESS) {
|
|
|
|
/*
|
|
|
|
* If the process has requested that all future mappings
|
|
|
|
* be wired, then heed this.
|
|
|
|
*/
|
2012-04-21 18:36:53 +00:00
|
|
|
if (map->flags & MAP_WIREFUTURE) {
|
2012-02-25 21:06:39 +00:00
|
|
|
vm_map_wire(map, *addr, *addr + size,
|
2012-04-21 18:36:53 +00:00
|
|
|
VM_MAP_WIRE_USER | ((flags & MAP_STACK) ?
|
|
|
|
VM_MAP_WIRE_HOLESOK : VM_MAP_WIRE_NOHOLES));
|
|
|
|
}
|
1994-05-24 10:09:53 +00:00
|
|
|
}
|
2011-07-10 20:49:13 +00:00
|
|
|
return (vm_mmap_to_errno(rv));
|
|
|
|
}
|
|
|
|
|
2012-02-25 21:06:39 +00:00
|
|
|
/*
|
|
|
|
* Translate a Mach VM return code to zero on success or the appropriate errno
|
|
|
|
* on failure.
|
|
|
|
*/
|
2011-07-10 20:49:13 +00:00
|
|
|
int
|
|
|
|
vm_mmap_to_errno(int rv)
|
|
|
|
{
|
|
|
|
|
1994-05-24 10:09:53 +00:00
|
|
|
switch (rv) {
|
|
|
|
case KERN_SUCCESS:
|
|
|
|
return (0);
|
|
|
|
case KERN_INVALID_ADDRESS:
|
|
|
|
case KERN_NO_SPACE:
|
|
|
|
return (ENOMEM);
|
|
|
|
case KERN_PROTECTION_FAILURE:
|
|
|
|
return (EACCES);
|
|
|
|
default:
|
|
|
|
return (EINVAL);
|
|
|
|
}
|
|
|
|
}
|