Module: xenomai-forge
Branch: next
Commit: 927778a3ea60e6f54f0e93117c562f18f11b966a
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=927778a3ea60e6f54f0e93117c562f18f11b966a

Author: Philippe Gerum <r...@xenomai.org>
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 <r...@xenomai.org>.
+ *
+ * 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
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to