diff options
author | Thomas Schwinge <thomas@codesourcery.com> | 2012-12-20 22:20:05 +0100 |
---|---|---|
committer | Thomas Schwinge <thomas@codesourcery.com> | 2012-12-20 22:20:05 +0100 |
commit | fc4d1650f3e35a1cff0111ae3808c61d44346f1f (patch) | |
tree | 6be97c865d896e3e49411ede9870410e0c4f6479 | |
parent | c77f17cfb827c17de7f1d5318cbbbeea03286715 (diff) |
glibc/mmap: Extend.
-rw-r--r-- | glibc/mmap.mdwn | 402 | ||||
-rw-r--r-- | hurd/interface/io_map.mdwn | 11 | ||||
-rw-r--r-- | hurd/porting/guidelines.mdwn | 1 | ||||
-rw-r--r-- | microkernel/mach/external_pager_mechanism.mdwn | 14 | ||||
-rw-r--r-- | microkernel/mach/interface/vm_map.mdwn | 16 | ||||
-rw-r--r-- | open_issues/git_nfs_mmap.mdwn | 4 | ||||
-rw-r--r-- | open_issues/glibc.mdwn | 20 | ||||
-rw-r--r-- | open_issues/glibc/mremap.mdwn | 2 | ||||
-rw-r--r-- | user/kam.mdwn | 8 |
9 files changed, 391 insertions, 87 deletions
diff --git a/glibc/mmap.mdwn b/glibc/mmap.mdwn index 09b0b65d..cddd0584 100644 --- a/glibc/mmap.mdwn +++ b/glibc/mmap.mdwn @@ -8,91 +8,379 @@ Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled [[GNU Free Documentation License|/fdl]]."]]"""]] -There are two implementations of `mmap` for GNU Hurd: -`sysdeps/mach/hurd/mmap.c` (main implementation) and -`sysdeps/mach/hurd/dl-sysdep.c` (*Minimal mmap implementation sufficient for -initial loading of shared libraries.*). +The `mmap` call is generally supported on GNU Hurd, as indicated by +`_POSIX_MAPPED_FILES` (`sysconf (_SC_MAPPED_FILES)`). - * `MAP_COPY` - What exactly is that? `elf/dl-load.c` has some explanation. - <http://lkml.indiana.edu/hypermail/linux/kernel/0110.1/1506.html> +# Flags - It is only handled in `dl-sysdep.c`, when `flags & (MAP_COPY|MAP_PRIVATE)` - is used for `vm_map`'s `copy` parameter, and `mmap.c` uses `! (flags & - MAP_SHARED)` instead, which seems inconsistent? +*Flags contain mapping type, sharing type and options.* + * *Mapping type (must choose one and only one of these).* -# `io_map` Failure + * `MAP_FILE` (*Mapped from a file or device.*) -This is the [[libnetfs: `io_map`|open_issues/libnetfs_io_map]] issue. + * `MAP_ANON`/`MAP_ANONYMOUS` (*Allocated from anonymous virtual memory.*) -[[!tag open_issue_glibc]] + Even though it is not defined to zero (it is for the Linux kernel; why not + for us?), `MAP_FILE` is the default and can be omitted. -Review of `mmap` usage in generic bits of glibc, based on -a1bcbd4035ac2483dc10da150d4db46f3e1744f8 (2012-03-11), listing these cases -where failure (due to `io_map` failing; that is, invocations where a `fd` is -passed) is not properly handled. + * *Sharing types (must choose one and only one of these).* -`catgets/open_catalog.c`, `iconv/gconv_cache.c`, `intl/loadmsgcat.c`, -`locale/loadlocale.c` have fallback code for the `MAP_FAILED` case. + * `MAP_SHARED` (*Share changes.*) -[[tschwinge]]'s current plan is to make the following cases do the same (if -that is possible); probably by introducing a generic `mmap_or_read` function, -that first tries `mmap` (and that will succeed on Linux-based systems and also -on Hurd-based, if it's backed by [[hurd/libdiskfs]]), and if that fails tries -`mmap` on anonymous memory and then fills it by `read`ing the required data. -This is also what the [[hurd/exec]] server is doing (and is the reason that the -`./true` invocation on [[libnetfs: `io_map`|open_issues/libnetfs_io_map]] -works, to my understanding): see `exec.c:prepare`, if `io_map` fails, -`e->filemap == MACH_PORT_NULL`; then `exec.c:map` (as invoked from -`exec.c:load_section`, `exec.c:check_elf`, `exec.c:do_exec`, or -`hashexec.c:check_hashbang`) will use `io_read` instead. + * `MAP_PRIVATE` (*Changes private; copy pages on write.*) -Doing so potentially means reading in a lot of unused data -- but we probably -can't do any better? + * `MAP_COPY` (*Virtual copy of region at mapping time.*) -In parallel (or even alternatively?), it should be researched how Linux (or any -other kernel) implements `mmap` on NFS and similar file systems, and then -implement the same in [[hurd/libnetfs]] and/or [[hurd/translator/nfs]], etc. + For us, `MAP_PRIVATE` is the default (is defined to zero), for the Linux + kernel, one of `MAP_SHARED` or `MAP_PRIVATE` has to be specified + explicitly. + + The Linux kernel does not support `MAP_COPY`, and as per the comment in + `elf/dl-load.c`, `MAP_PRIVATE | MAP_DENYWRITE` is Linux' replacement for + `MAP_COPY`. However, `MAP_DENYWRITE` is defunct (`mmap` manpage). + + In contrast to `MAP_COPY`, for `MAP_PRIVATE` *it is unspecified whether + changes made to the file after the `mmap` call are visible in the mapped + region* (`mmap` manpage). + + `MAP_COPY`: + + What exactly is that? `elf/dl-load.c` has some explanation. + <http://lkml.indiana.edu/hypermail/linux/kernel/0110.1/1506.html> + + It is only handled in `dl-sysdep.c`, when `flags & + (MAP_COPY|MAP_PRIVATE)` is used for + [[`vm_map`|microkernel/mach/interface/vm_map]]'s `copy` parameter, and + `mmap.c` uses `! (flags & MAP_SHARED)` instead, which seems + inconsistent? + + Usage in glibc: + + * `catgets/open_catalog.c:__open_catalog`, + `locale/loadlocale.c:_nl_load_locale`: *Linux seems to lack read-only + copy-on-write.* + + * `MAP_TYPE` (*Mask for type field.*/*Mask for type of mapping.*) + + [[!tag open_issue_glibc]]In `bits/mman.h` this is described and defined to + be a mask for the *mapping* type, in the `bits/mman.h` files corresponding + to Linux kernel it is described an defined to be a mask for the *sharing* + type. + + * *Other flags.* + + * `MAP_FIXED` (*Map address must be exactly as requested.*) + + If the memory region is already in use, an unmap is attempted before + (re-)mapping it. + + [[!tag open_issue_glibc]]The following text should be improved: + + `[glibc]/llio.texi` says: + + @var{address} gives a preferred starting address for the mapping. + @code{NULL} expresses no preference. Any previous mapping at that + address is automatically removed. [...] + + The comments in `misc/sys/mman.h`, `misc/mmap.c`, `misc/mmap64.c`, + `ports/sysdeps/unix/sysv/linux/hppa/mmap.c`, and + `sysdeps/mach/hurd/mmap.c` have a better wording: + + A successful `mmap' call + deallocates any previous mapping for the affected region. + + This is correct insofar that for `MAP_FIXED` indeed it is first + unmapped if already in use, and for the regular cases, an address will + be chosen that has no previous mapping. + + * `MAP_NOEXTEND` (*For `MAP_FILE`, don't change file size.*) + + Referenced in `[hurd]/TODO` as unimplemented. + + * `MAP_HASSEMPHORE` (*Region may contain semaphores.*) + + * `MAP_INHERIT` (*Region is retained after exec.*) + + * Linux-specific flags + + * `MAP_GROWSDOWN` (*Stack-like segment.*), `MAP_GROWSUP` (*Register + stack-like segment.*) + + See `mmap` manpage. + + * `MAP_DENYWRITE` (*`ETXTBSY`*) + + As per the comment in `elf/dl-load.c`, `MAP_PRIVATE | MAP_DENYWRITE` is + Linux' replacement for `MAP_COPY`. However, `MAP_DENYWRITE` is defunct + (`mmap` manpage). + + * `MAP_EXECUTABLE` (*Mark it as an executable.*) + + * `MAP_LOCKED` (*Lock the mapping.*) + + ... à la `mlock`. Not implemented for us, but probably + could[[open_issue_glibc]]. + + * `MAP_NORESERVE` (*Don't check for reservations.*) + + See `mmap` manpage. + + From [[hurd/porting/guidelines]]: *Not POSIX, but we could implement + it.* + + * `MAP_POPULATE` (*Populate (prefault) pagetables.*) + + From the `mmap` manpage: + + Populate (prefault) page tables for a mapping. For a file mapping, + this causes read-ahead on the file. Later accesses to the mapping + will not be blocked by page faults. MAP_POPULATE is only supported + for private mappings since Linux 2.6.23. + + Unknown Linux kernel version, `mm/mmap.c`: + + if (vm_flags & VM_LOCKED) { + if (!mlock_vma_pages_range(vma, addr, addr + len)) + mm->locked_vm += (len >> PAGE_SHIFT); + } else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK)) + make_pages_present(addr, addr + len); + return addr; + + Is only advisory, so can worked around with `#define MAP_POPULATE 0`, + 8069478040336a7de3461be275432493cc7e4c91. + + * `MAP_NONBLOCK` (*Do not block on IO.*) + + From the `mmap` manpage: + + Only meaningful in conjunction with MAP_POPULATE. Don't perform + read-ahead: only create page tables entries for pages that are + already present in RAM. Since Linux 2.6.23, this flag causes + MAP_POPULATE to do nothing. One day the combination of + MAP_POPULATE and MAP_NONBLOCK may be reimplemented. + + * `MAP_STACK` (*Allocation is for a stack.*) -Here, also probably the whole mapping region [has to be -read](http://lists.gnu.org/archive/html/bug-hurd/2001-10/msg00306.html) at -`mmap` time. + See `mmap` manpage. -List of files without fallback code for the *`MAP_FAILED` due to `io_map` -failed* case: + * `MAP_HUGETLB` (*Create huge page mapping.*) - * `elf/cache.c` + See `mmap` manpage. - * `elf/dl-load.c` + * `MAP_32BIT` (*Only give out 32-bit addresses.*) - * `elf/dl-misc.c` + See `mmap` manpage. - * `elf/dl-profile.c` - * `elf/readlib.c` +# Implementation - * `elf/sprof.c` +Essentially, `mmap` is implemented by means of +[[`io_map`|hurd/interface/io_map]] (not for `MAP_ANON`) followed by +[[`vm_map`|microkernel/mach/interface/vm_map]]. - * `locale/loadarchive.c` +There are two implementations: `sysdeps/mach/hurd/mmap.c` (main implementation) +and `sysdeps/mach/hurd/dl-sysdep.c` (*Minimal mmap implementation sufficient +for initial loading of shared libraries.*). - * `locale/programs/locale.c` - * `locale/programs/locarchive.c` +## `mmap ("/dev/zero")` - * `nscd/connections.c` +[[!tag open_issue_glibc open_issue_hurd]]Do we implement that (equivalently to +`MAP_ANON`)? - * `nscd/nscd_helper.c` - * `nss/makedb.c` +## Mapping Size - * `nss/nss_db/db-open.c` +From the `mmap` manpage: - * Omitted: + A file is mapped in multiples of the page size. For a file that is not a + multiple of the page size, the remaining memory is zeroed when mapped, and + writes to that region are not written out to the file. The effect of + changing the size of the underlying file of a mapping on the pages that + correspond to added or removed regions of the file is unspecified. - * `nptl/` +[[!tag open_issue_glibc]]Do we implement that? - * `sysdeps/unix/sparc/` - * `sysdepts/unix/sysv/linux/` +## Use of a Mapped Region + +From the `mmap` manpage: + + Use of a mapped region can result in these signals: + + SIGSEGV Attempted write into a region mapped as read-only. + + SIGBUS Attempted access to a portion of the buffer that does not + correspond to the file (for example, beyond the end of the file, + including the case where another process has truncated the file). + +[[!tag open_issue_glibc]]Do we implement that? + + +# Usage in glibc itself + +Review of `mmap` usage in generic bits of glibc (omitted: `nptl/`, +`sysdeps/unix/sparc/`, `sysdepts/unix/sysv/linux/`), based on +a1bcbd4035ac2483dc10da150d4db46f3e1744f8 (2012-03-11). `MAP_FILE` is the +interesting case; `MAP_ANON` is generally fine. Some of the `mmap` usages in +glibc have fallback code for the `MAP_FAILED` case, some do not. + + catgets/open_catalog.c: (struct catalog_obj *) __mmap (NULL, st.st_size, PROT_READ, + catgets/open_catalog.c- MAP_FILE|MAP_COPY, fd, 0); + +Has fallback for `MAP_FAILED`. + + elf/cache.c: = mmap (NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + elf/cache.c: = mmap (NULL, aux_cache_size, PROT_READ, MAP_PRIVATE, fd, 0); + +No fallback for `MAP_FAILED`. + + elf/dl-load.c: l->l_map_start = (ElfW(Addr)) __mmap ((void *) mappref, maplength, + elf/dl-load.c- c->prot, + elf/dl-load.c- MAP_COPY|MAP_FILE, + elf/dl-load.c- fd, c->mapoff); + elf/dl-load.c: && (__mmap ((void *) (l->l_addr + c->mapstart), + elf/dl-load.c- c->mapend - c->mapstart, c->prot, + elf/dl-load.c- MAP_FIXED|MAP_COPY|MAP_FILE, + elf/dl-load.c- fd, c->mapoff) + +No fallback for `MAP_FAILED`. + + elf/dl-misc.c: result = __mmap (NULL, *sizep, prot, + elf/dl-misc.c-#ifdef MAP_COPY + elf/dl-misc.c- MAP_COPY + elf/dl-misc.c-#else + elf/dl-misc.c- MAP_PRIVATE + elf/dl-misc.c-#endif + elf/dl-misc.c-#ifdef MAP_FILE + elf/dl-misc.c- | MAP_FILE + elf/dl-misc.c-#endif + elf/dl-misc.c- , fd, 0); + +No fallback for `MAP_FAILED`. + + elf/dl-profile.c: addr = (struct gmon_hdr *) __mmap (NULL, expected_size, PROT_READ|PROT_WRITE, + elf/dl-profile.c- MAP_SHARED|MAP_FILE, fd, 0); + +No fallback for `MAP_FAILED`. + + elf/readlib.c: file_contents = mmap (0, statbuf.st_size, PROT_READ, MAP_SHARED, + elf/readlib.c- fileno (file), 0); + +No fallback for `MAP_FAILED`. + + elf/sprof.c: result->symbol_map = mmap (NULL, max_offset - min_offset, + elf/sprof.c- PROT_READ, MAP_SHARED|MAP_FILE, symfd, + elf/sprof.c- min_offset); + elf/sprof.c: addr = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED|MAP_FILE, fd, 0); + +No fallback for `MAP_FAILED`. + + iconv/gconv_cache.c: gconv_cache = __mmap (NULL, cache_size, PROT_READ, MAP_SHARED, fd, 0); + iconv/iconv_charmap.c: && ((addr = mmap (NULL, st.st_size, PROT_READ, MAP_PRIVATE, + iconv/iconv_charmap.c- fd, 0)) != MAP_FAILED)) + iconv/iconv_prog.c: && ((addr = mmap (NULL, st.st_size, PROT_READ, MAP_PRIVATE, + iconv/iconv_prog.c- fd, 0)) != MAP_FAILED)) + +Have fallback for `MAP_FAILED`. + + intl/loadmsgcat.c: data = (struct mo_file_header *) mmap (NULL, size, PROT_READ, + intl/loadmsgcat.c- MAP_PRIVATE, fd, 0); + +Has fallback for `MAP_FAILED`. + + libio/fileops.c: p = __mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, + libio/fileops.c- fp->_fileno, 0); + libio/fileops.c: p = __mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fp->_fileno, 0); + +Has fallback for `MAP_FAILED`. + + locale/loadarchive.c: result = __mmap64 (NULL, mapsize, PROT_READ, MAP_FILE|MAP_COPY, fd, 0); + locale/loadarchive.c: result = __mmap64 (NULL, mapsize, PROT_READ, MAP_FILE|MAP_COPY, + locale/loadarchive.c- fd, 0); + locale/loadarchive.c: addr = __mmap64 (NULL, to - from, PROT_READ, MAP_FILE|MAP_COPY, + locale/loadarchive.c- fd, from); + +Some have fallback for `MAP_FAILED`. + + locale/programs/locale.c: void *mapped = mmap64 (NULL, st.st_size, PROT_READ, + locale/programs/locale.c- MAP_SHARED, fd, 0); + locale/programs/locale.c: && ((mapped = mmap64 (NULL, st.st_size, PROT_READ, + locale/programs/locale.c- MAP_SHARED, fd, 0)) + locale/programs/locale.c: addr = mmap64 (NULL, len, PROT_READ, MAP_SHARED, fd, 0); + locale/programs/locarchive.c: void *p = mmap64 (NULL, RESERVE_MMAP_SIZE, PROT_NONE, MAP_SHARED, fd, 0); + locale/programs/locarchive.c: p = mmap64 (p, total, PROT_READ | PROT_WRITE, MAP_SHARED | xflags, fd, 0); + locale/programs/locarchive.c: void *p = mmap64 (ah->addr + start, st.st_size - start, + locale/programs/locarchive.c- PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, + locale/programs/locarchive.c- ah->fd, start); + locale/programs/locarchive.c: ah->addr = mmap64 (ah->addr, st.st_size, PROT_READ | PROT_WRITE, + locale/programs/locarchive.c- MAP_SHARED | MAP_FIXED, ah->fd, 0); + locale/programs/locarchive.c: ah->addr = mmap64 (NULL, st.st_size, PROT_READ | PROT_WRITE, + locale/programs/locarchive.c- MAP_SHARED, ah->fd, 0); + locale/programs/locarchive.c: p = mmap64 (p, total, PROT_READ | PROT_WRITE, MAP_SHARED | xflags, fd, 0); + locale/programs/locarchive.c: ah->addr = mmap64 (p, st.st_size, PROT_READ | (readonly ? 0 : PROT_WRITE), + locale/programs/locarchive.c- MAP_SHARED | xflags, fd, 0); + locale/programs/locarchive.c: data[cnt].addr = mmap64 (NULL, st.st_size, PROT_READ, MAP_SHARED, + locale/programs/locarchive.c- fd, 0); + +No fallback for `MAP_FAILED`. + + nscd/connections.c: else if ((mem = mmap (NULL, dbs[cnt].max_db_size, + nscd/connections.c- PROT_READ | PROT_WRITE, + nscd/connections.c- MAP_SHARED, fd, 0)) + nscd/connections.c: || (mem = mmap (NULL, dbs[cnt].max_db_size, + nscd/connections.c- PROT_READ | PROT_WRITE, + nscd/connections.c- MAP_SHARED, fd, 0)) == MAP_FAILED) + nscd/nscd_helper.c: void *mapping = __mmap (NULL, mapsize, PROT_READ, MAP_SHARED, mapfd, 0); + +No fallback for `MAP_FAILED`. + + nss/makedb.c: const struct nss_db_header *header = mmap (NULL, st.st_size, PROT_READ, + nss/makedb.c- MAP_PRIVATE|MAP_POPULATE, fd, 0); + nss/nss_db/db-open.c: mapping->header = mmap (NULL, header.allocate, PROT_READ, + nss/nss_db/db-open.c- MAP_PRIVATE, fd, 0); + +No fallback for `MAP_FAILED`. + + posix/tst-mmap.c: ptr = mmap (NULL, 1000, PROT_READ, MAP_SHARED, fd, ps); + posix/tst-mmap.c: ptr = mmap64 (NULL, 1000, PROT_READ, MAP_SHARED, fd, ps); + rt/tst-mqueue3.c: void *mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + rt/tst-mqueue5.c: void *mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + rt/tst-shm.c: mem = mmap (NULL, 4000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + stdio-common/tst-fmemopen.c: if ((mmap_data = (char *) mmap (NULL, fs.st_size, PROT_READ, + stdio-common/tst-fmemopen.c- MAP_SHARED, fd, 0)) == MAP_FAILED) + +No fallback for `MAP_FAILED`. + + +## `io_map` Failure + +This is the [[libnetfs: `io_map`|open_issues/libnetfs_io_map]] issue. + +[[!tag open_issue_glibc open_issue_hurd]] +[[tschwinge]]'s current plan is to make the following cases do the same (if +that is possible); probably by introducing a generic `mmap_or_read` function, +that first tries `mmap` (and that will succeed on Linux-based systems and also +on Hurd-based, if it's backed by [[hurd/libdiskfs]]), and if that fails tries +`mmap` on anonymous memory and then fills it by `read`ing the required data. +This is also what the [[hurd/exec]] server is doing (and is the reason that the +`./true` invocation on [[libnetfs: `io_map`|open_issues/libnetfs_io_map]] +works, to my understanding): see `exec.c:prepare`, if `io_map` fails, +`e->filemap == MACH_PORT_NULL`; then `exec.c:map` (as invoked from +`exec.c:load_section`, `exec.c:check_elf`, `exec.c:do_exec`, or +`hashexec.c:check_hashbang`) will use `io_read` instead. + +Doing so potentially means reading in a lot of unused data -- but we probably +can't do any better? + +In parallel (or even alternatively?), it should be researched how Linux (or any +other kernel) implements `mmap` on NFS and similar file systems, and then +implement the same in [[hurd/libnetfs]] and/or [[hurd/translator/nfs]], etc. + +Here, also probably the whole mapping region [[!message-id desc="has to be +read" "871yjkl50c.fsf@becket.becket.net"]] ([bug-hurd list +archive](http://lists.gnu.org/archive/html/bug-hurd/2001-10/msg00306.html)) at +`mmap` time. Then, only `MAP_PRIVATE` (or rather: `MAP_COPY`) is possible, but +not `MAP_SHARED`. diff --git a/hurd/interface/io_map.mdwn b/hurd/interface/io_map.mdwn new file mode 100644 index 00000000..11a59a51 --- /dev/null +++ b/hurd/interface/io_map.mdwn @@ -0,0 +1,11 @@ +[[!meta copyright="Copyright © 2012 Free Software Foundation, Inc."]] + +[[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable +id="license" text="Permission is granted to copy, distribute and/or modify this +document under the terms of the GNU Free Documentation License, Version 1.2 or +any later version published by the Free Software Foundation; with no Invariant +Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license +is included in the section entitled [[GNU Free Documentation +License|/fdl]]."]]"""]] + +Used in [[glibc]] for implementing [[glibc/mmap]]. diff --git a/hurd/porting/guidelines.mdwn b/hurd/porting/guidelines.mdwn index 2618cd90..aabf0345 100644 --- a/hurd/porting/guidelines.mdwn +++ b/hurd/porting/guidelines.mdwn @@ -275,6 +275,7 @@ Oh, we should probably provide it. ## <a name="MAP_NORESERVE"> `MAP_NORESERVE` </a> Not POSIX, but we could implement it. +See [[glibc/mmap]]. ## <a name="O_DIRECT"> `O_DIRECT` </a> diff --git a/microkernel/mach/external_pager_mechanism.mdwn b/microkernel/mach/external_pager_mechanism.mdwn index 05a6cc56..54492b71 100644 --- a/microkernel/mach/external_pager_mechanism.mdwn +++ b/microkernel/mach/external_pager_mechanism.mdwn @@ -1,4 +1,4 @@ -[[!meta copyright="Copyright © 2002, 2007, 2008, 2010, 2011 Free Software +[[!meta copyright="Copyright © 2002, 2007, 2008, 2010, 2011, 2012 Free Software Foundation, Inc."]] [[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable @@ -23,8 +23,8 @@ latter. In Mach, a [[task]]'s [[virtual_address_space]] consists of references to [[memory_object]]s. -To associate a memory object with a portion of a task's -address space, `vm_map` is invoked on a capability designating +To associate a memory object with a portion of a task's address space, +[[`vm_map`|interface/vm_map]] is invoked on a capability designating the task and passing a reference to the memory object and the offset at which to install it. (The first time a task maps an object, Mach sends an initialization message @@ -69,8 +69,8 @@ it to the port set that it is listening on and returns a capability (a port send right) to the client. (C) The client attempts to map the object into its address space using -the `vm_map` RPC. It passes a reference to the port that the server gave -it to the vm server (typically Mach). +the [[`vm_map`|interface/vm_map]] RPC. It passes a reference to the port that +the server gave it to the vm server (typically Mach). (D) Since Mach has never seen the object before, it queues a `memory_object_init` on the given port along with a send right (the @@ -84,8 +84,8 @@ structures to manage the mapping and then invokes the `memory_object_ready` method on the control object. (F) The kernel sees that the manager is ready, sets up the appropriate -mappings in the client's address space and then replies to the `vm_map` RPC indicating -success. +mappings in the client's address space and then replies to the +[[`vm_map`|interface/vm_map]] RPC indicating success. There is nothing stopping others from playing *the kernel*. This is not a security problem: clients must [[trust]] the server from whom they diff --git a/microkernel/mach/interface/vm_map.mdwn b/microkernel/mach/interface/vm_map.mdwn new file mode 100644 index 00000000..7232209b --- /dev/null +++ b/microkernel/mach/interface/vm_map.mdwn @@ -0,0 +1,16 @@ +[[!meta copyright="Copyright © 2012 Free Software Foundation, Inc."]] + +[[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable +id="license" text="Permission is granted to copy, distribute and/or modify this +document under the terms of the GNU Free Documentation License, Version 1.2 or +any later version published by the Free Software Foundation; with no Invariant +Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license +is included in the section entitled [[GNU Free Documentation +License|/fdl]]."]]"""]] + +Used in [[glibc]] for implementing [[glibc/mmap]], brk and sbrk, and *attempt +to map page zero redzoned* (`[glibc]/hurd/hurdstartup.c:_hurd_startup`). + +[[!tag open_issue_glibc open_issue_gnumach]]It has an awkward mention in +`[glibc]/sysdeps/mach/hurd/dl-sysdep.c:fmh`: *XXX loser kludge for vm\_map +kernel bug*. diff --git a/open_issues/git_nfs_mmap.mdwn b/open_issues/git_nfs_mmap.mdwn index 21067022..e6726dfa 100644 --- a/open_issues/git_nfs_mmap.mdwn +++ b/open_issues/git_nfs_mmap.mdwn @@ -50,4 +50,6 @@ fails, and it isn't prepared to cope with that: This is the [[libnetfs: `io_map`|open_issues/libnetfs_io_map]] issue. There is a `NO_MMAP` conditional in Git's source code, but it is a compile-time -conditional. +conditional. The fallback code in `compat/mmap.c:git_mmap` only supports +`MAP_PRIVATE`, and simply `pread`s in the requested portion of a file. This +could be made a runtime fallback, too. diff --git a/open_issues/glibc.mdwn b/open_issues/glibc.mdwn index 9212c402..a9c12e5c 100644 --- a/open_issues/glibc.mdwn +++ b/open_issues/glibc.mdwn @@ -189,7 +189,8 @@ Last reviewed up to the [[Git mirror's d3bd58cf0a027016544949ffd27300ac5fb01bb8 `RLIMIT_RTTIME`, `SEEK_DATA` (`unistd.h`), `SEEK_HOLE` (`unistd.h`) `clock_adjtime`, `fallocate`, `fallocate64`, `name_to_handle_at`, `open_by_handle_at`, `process_vm_readv`, `process_vm_writev`, `sendmmsg`, - `setns`, `sync_file_range` + `setns`, `sync_file_range`, [[`mremap`|mremap]] and [[several + `MAP_*`|glibc/mmap]] * `chflags` @@ -269,8 +270,6 @@ Last reviewed up to the [[Git mirror's d3bd58cf0a027016544949ffd27300ac5fb01bb8 initialization <tschwinge> OK, that at least matches my understanding. - * [[`mremap`|mremap]] - * `syncfs` We should be easily able to implement that one. @@ -286,21 +285,6 @@ Last reviewed up to the [[Git mirror's d3bd58cf0a027016544949ffd27300ac5fb01bb8 Do we support `AT_FDCWD` et al.? (80b4e5f3ef231702b24d44c33e8dceb70abb3a06.) - * `MAP_POPULATE` (`mmap`, `sys/mman.h`) -- *Populate (prefault) - pagetables.* - - Some Linux kernel version, `mm/mmap.c`: - - if (vm_flags & VM_LOCKED) { - if (!mlock_vma_pages_range(vma, addr, addr + len)) - mm->locked_vm += (len >> PAGE_SHIFT); - } else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK)) - make_pages_present(addr, addr + len); - return addr; - - Is only advisory, so can worked around with `#define MAP_POPULATE 0`, - 8069478040336a7de3461be275432493cc7e4c91. - * `t/opendirat`: `opendirat` (`scandirat`, `scandirat64`) Need changes equivalent to c55fbd1ea768f9fdef34a01377702c0d72cbc213 + diff --git a/open_issues/glibc/mremap.mdwn b/open_issues/glibc/mremap.mdwn index 874c7ae0..c17506d7 100644 --- a/open_issues/glibc/mremap.mdwn +++ b/open_issues/glibc/mremap.mdwn @@ -15,6 +15,8 @@ The Hurd does not currently support the `mremap` function. For the `MREMAP_MAYMOVE` case it is easy to work around; see `[binutils]/gold/mremap.c`, for example. +Also see the discussion of [[glibc/mmap]]. + [[!toc]] diff --git a/user/kam.mdwn b/user/kam.mdwn index 8ee68866..c16908c3 100644 --- a/user/kam.mdwn +++ b/user/kam.mdwn @@ -1,12 +1,12 @@ -[[!meta copyright="Copyright © 2008 Free Software Foundation, Inc."]] +[[!meta copyright="Copyright © 2008, 2012 Free Software Foundation, Inc."]] [[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable id="license" text="Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license -is included in the section entitled -[[GNU Free Documentation License|/fdl]]."]]"""]] +is included in the section entitled [[GNU Free Documentation +License|/fdl]]."]]"""]] [[!meta title="Karim Allah Ahmed"]] @@ -67,7 +67,7 @@ Stage 1: * (./) port OSF Mach's clustered pagein during 'page faults' ( [src]/vm/vm_fault.c ) * (./) port "cluster_size" attribute of memory objects from OSF Mach. -* (./) port "behavior" attribute of vm_map entries from OSF Mach. +* (./) port "behavior" attribute of [[`vm_map`|microkernel/mach/interface/vm_map]] entries from OSF Mach. ####29th of May - 2nd of June: |