Module: xenomai-forge Branch: next Commit: 927778a3ea60e6f54f0e93117c562f18f11b966a URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=927778a3ea60e6f54f0e93117c562f18f11b966a
Author: Philippe Gerum <[email protected]> Date: Thu Aug 7 14:45:51 2014 +0200 lib/cobalt: export mmap() interface --- include/cobalt/sys/Makefile.am | 1 + include/cobalt/sys/Makefile.in | 1 + include/cobalt/sys/mman.h | 37 +++++++++++++++++++++++++++++++++++++ lib/cobalt/arch/arm/features.c | 4 ++-- lib/cobalt/arch/nios2/features.c | 4 ++-- lib/cobalt/arch/sh/features.c | 4 ++-- lib/cobalt/cobalt.wrappers | 2 ++ lib/cobalt/rtdm.c | 29 +++++++++++++++++++++++++++++ lib/cobalt/sem_heap.c | 34 ++++++++++++++++++---------------- lib/cobalt/wrappers.c | 8 ++++++++ lib/copperplate/heapobj-pshared.c | 6 +++--- 11 files changed, 105 insertions(+), 25 deletions(-) diff --git a/include/cobalt/sys/Makefile.am b/include/cobalt/sys/Makefile.am index 12e4205..099cc27 100644 --- a/include/cobalt/sys/Makefile.am +++ b/include/cobalt/sys/Makefile.am @@ -3,6 +3,7 @@ includesubdir = $(includedir)/cobalt/sys includesub_HEADERS = \ cobalt.h \ ioctl.h \ + mman.h \ select.h \ socket.h \ time.h \ diff --git a/include/cobalt/sys/Makefile.in b/include/cobalt/sys/Makefile.in index c669683..f874cb3 100644 --- a/include/cobalt/sys/Makefile.in +++ b/include/cobalt/sys/Makefile.in @@ -333,6 +333,7 @@ includesubdir = $(includedir)/cobalt/sys includesub_HEADERS = \ cobalt.h \ ioctl.h \ + mman.h \ select.h \ socket.h \ time.h \ diff --git a/include/cobalt/sys/mman.h b/include/cobalt/sys/mman.h new file mode 100644 index 0000000..f1cd704 --- /dev/null +++ b/include/cobalt/sys/mman.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2014 Philippe Gerum <[email protected]>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#pragma GCC system_header +#include_next <sys/mman.h> + +#ifndef _COBALT_SYS_MMAN_H +#define _COBALT_SYS_MMAN_H + +#include <cobalt/wrappers.h> + +#ifdef __cplusplus +extern "C" { +#endif + +COBALT_DECL(void *, mmap(void *addr, size_t length, int prot, int flags, + int fd, off_t offset)); + +#ifdef __cplusplus +} +#endif + +#endif /* !_COBALT_SYS_MMAN_H */ diff --git a/lib/cobalt/arch/arm/features.c b/lib/cobalt/arch/arm/features.c index 7717eb4..53d2b74 100644 --- a/lib/cobalt/arch/arm/features.c +++ b/lib/cobalt/arch/arm/features.c @@ -70,8 +70,8 @@ void cobalt_check_features(struct xnfeatinfo *finfo) phys_addr = (unsigned long)__xn_tscinfo.kinfo.counter; - addr = mmap(NULL, page_size, PROT_READ, MAP_SHARED, - fd, phys_addr & ~(page_size - 1)); + addr = __STD(mmap(NULL, page_size, PROT_READ, MAP_SHARED, + fd, phys_addr & ~(page_size - 1))); if (addr == MAP_FAILED) { report_error("mmap(/dev/mem): %s", strerror(errno)); exit(EXIT_FAILURE); diff --git a/lib/cobalt/arch/nios2/features.c b/lib/cobalt/arch/nios2/features.c index dd5838d..d1a397b 100644 --- a/lib/cobalt/arch/nios2/features.c +++ b/lib/cobalt/arch/nios2/features.c @@ -45,8 +45,8 @@ void cobalt_check_features(struct xnfeatinfo *finfo) } pagesz = sysconf(_SC_PAGESIZE); - p = mmap(NULL, pagesz, PROT_READ | PROT_WRITE, MAP_SHARED, - fd, pa & ~(pagesz - 1)); + p = __STD(mmap(NULL, pagesz, PROT_READ | PROT_WRITE, MAP_SHARED, + fd, pa & ~(pagesz - 1))); if (p == MAP_FAILED) { report_error("mmap(/dev/mem): %s", strerror(errno)); exit(EXIT_FAILURE); diff --git a/lib/cobalt/arch/sh/features.c b/lib/cobalt/arch/sh/features.c index 38983f0..e9be6e7 100644 --- a/lib/cobalt/arch/sh/features.c +++ b/lib/cobalt/arch/sh/features.c @@ -46,8 +46,8 @@ static volatile void *map_kmem(unsigned long pa, unsigned int pagesz) exit(EXIT_FAILURE); } - p = mmap(NULL, pagesz, PROT_READ | PROT_WRITE, MAP_SHARED, - fd, pa & ~(pagesz - 1)); + p = __STD(mmap(NULL, pagesz, PROT_READ | PROT_WRITE, MAP_SHARED, + fd, pa & ~(pagesz - 1))); if (p == MAP_FAILED) { report_error("mmap(/dev/mem): %s", strerror(errno)); exit(EXIT_FAILURE); diff --git a/lib/cobalt/cobalt.wrappers b/lib/cobalt/cobalt.wrappers index d426e05..a4884ba 100644 --- a/lib/cobalt/cobalt.wrappers +++ b/lib/cobalt/cobalt.wrappers @@ -103,3 +103,5 @@ --wrap sigqueue --wrap kill --wrap sleep +--wrap mmap +--wrap munmap diff --git a/lib/cobalt/rtdm.c b/lib/cobalt/rtdm.c index 48a4d9c..bc5ae6c 100644 --- a/lib/cobalt/rtdm.c +++ b/lib/cobalt/rtdm.c @@ -24,6 +24,7 @@ #include <fcntl.h> #include <unistd.h> #include <sys/socket.h> +#include <sys/mman.h> #include <rtdm/rtdm.h> #include <cobalt/uapi/rtdm/syscall.h> #include <cobalt/uapi/syscall.h> @@ -403,3 +404,31 @@ COBALT_IMPL(int, shutdown, (int fd, int how)) return __STD(shutdown(fd, how)); } + +COBALT_IMPL(void *, mmap, (void *addr, size_t length, int prot, int flags, + int fd, off_t offset)) +{ + struct _rtdm_mmap_request rma; + int ret; + + if (fd < 0) /* We don't do anonymous mappings. */ + goto regular; + + /* RTDM ignores the address hint, and rejects MAP_FIXED. */ + rma.length = length; + rma.offset = offset; + rma.prot = prot; + rma.flags = flags; + + ret = XENOMAI_SKINCALL3(__rtdm_muxid, sc_rtdm_mmap, fd, &rma, &addr); + if (ret != -EBADF && ret != -ENOSYS) { + ret = set_errno(ret); + if (ret) + return MAP_FAILED; + + return addr; + } + +regular: + return __STD(mmap(addr, length, prot, flags, fd, offset)); +} diff --git a/lib/cobalt/sem_heap.c b/lib/cobalt/sem_heap.c index 1146417..1a007f8 100644 --- a/lib/cobalt/sem_heap.c +++ b/lib/cobalt/sem_heap.c @@ -61,8 +61,8 @@ void *cobalt_map_heap(struct xnheap_desc *hd) return MAP_FAILED; } - addr = mmap(NULL, hd->size, PROT_READ|PROT_WRITE, - MAP_SHARED, fd, hd->area); + addr = __STD(mmap(NULL, hd->size, PROT_READ|PROT_WRITE, + MAP_SHARED, fd, hd->area)); close(fd); @@ -88,24 +88,26 @@ static void *map_sem_heap(unsigned int shared) static void unmap_on_fork(void) { + void *addr; + /* - Remapping the private heap must be done after the process has been - bound again, in order for it to have a new private heap, - Otherwise the global heap would be used instead, which - leads to unwanted effects. - - On machines without an MMU, there is no such thing as fork. - - As a protection against access to the heaps by the fastsync - code, we set up an inaccessible mapping where the heap was, so - that access to these addresses will cause a segmentation - fault. - */ - void *addr = mmap((void *)cobalt_sem_heap[PRIVATE], + * Remapping the private heap must be done after the process + * has re-attached to the Cobalt core, in order to reinstate a + * proper private heap, Otherwise the global heap would be + * used instead, leading to unwanted effects. + * + * On machines without an MMU, there is no such thing as fork. + * + * We replace former mappings with an invalid one, to detect + * any spuriously late access from the fastsync code. + */ + addr = __STD(mmap((void *)cobalt_sem_heap[PRIVATE], private_hdesc.size, PROT_NONE, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0)); + if (addr != (void *)cobalt_sem_heap[PRIVATE]) munmap((void *)cobalt_sem_heap[PRIVATE], private_hdesc.size); + cobalt_sem_heap[PRIVATE] = 0UL; init_private_heap = PTHREAD_ONCE_INIT; } diff --git a/lib/cobalt/wrappers.c b/lib/cobalt/wrappers.c index 6fbdab4..64dc003 100644 --- a/lib/cobalt/wrappers.c +++ b/lib/cobalt/wrappers.c @@ -28,6 +28,7 @@ #include <sys/select.h> #include <sys/socket.h> #include <sys/time.h> +#include <sys/mman.h> #include <stdio.h> #include <stdarg.h> #include <stdlib.h> @@ -279,6 +280,13 @@ int __real_select (int __nfds, fd_set *__restrict __readfds, } __weak +void *__real_mmap(void *addr, size_t length, int prot, int flags, + int fd, off_t offset) +{ + return mmap(addr, length, prot, flags, fd, offset); +} + +__weak int __real_vfprintf(FILE *stream, const char *fmt, va_list args) { return vfprintf(stream, fmt, args); diff --git a/lib/copperplate/heapobj-pshared.c b/lib/copperplate/heapobj-pshared.c index f7cc3b0..9e50047 100644 --- a/lib/copperplate/heapobj-pshared.c +++ b/lib/copperplate/heapobj-pshared.c @@ -643,7 +643,7 @@ static int create_main_heap(void) goto errno_fail; if (sbuf.st_size > 0) { - m_heap = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + m_heap = __STD(mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)); if (m_heap == MAP_FAILED) goto errno_fail; if (m_heap->cpid && kill(m_heap->cpid, 0) == 0) { @@ -668,7 +668,7 @@ static int create_main_heap(void) if (ret) goto unlink_fail; - m_heap = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + m_heap = __STD(mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)); if (m_heap == MAP_FAILED) goto unlink_fail; @@ -736,7 +736,7 @@ static int bind_main_heap(const char *session) goto fail; } - m_heap = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + m_heap = __STD(mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)); if (m_heap == MAP_FAILED) goto errno_fail; _______________________________________________ Xenomai-git mailing list [email protected] http://www.xenomai.org/mailman/listinfo/xenomai-git
