All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Kiszka <jan.kiszka@domain.hid>
To: xenomai-core <xenomai@xenomai.org>
Cc: Rodrigo Rosenfeld Rosas <lbocseg@domain.hid>
Subject: [Xenomai-core] [PATCH] provide rtdm_mmap_to_user / rtdm_munmap
Date: Fri, 10 Feb 2006 01:09:58 +0100	[thread overview]
Message-ID: <43EBD9D6.5090404@domain.hid> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 578 bytes --]

Hi all,

this is a first attempt to add the requested mmap functionality to the
RTDM driver API. Anyone interested in this feature is invited to test my
patch (Rodrigo... ;) ). Comments on the implementation are welcome as well.

Philippe, I need xnarch_remap_page_range for this and added a #define
XENO_HEAP_MODULE hack to rtdm/drvlib.c therefore. What would you suggest
as a cleaner approach? Make this function available unconditionally or
introduce something like XENO_RTDM_MODULE? Moreover, isn't this
implementation also interesting for nucleus/heap.c?

Jan

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: rtdm_mmap.patch --]
[-- Type: text/x-patch; name="rtdm_mmap.patch", Size: 4956 bytes --]

Index: include/rtdm/rtdm_driver.h
===================================================================
--- include/rtdm/rtdm_driver.h	(Revision 551)
+++ include/rtdm/rtdm_driver.h	(Arbeitskopie)
@@ -995,6 +995,10 @@
     xnfree(ptr);
 }
 
+int rtdm_mmap_to_user(rtdm_user_info_t *user_info, void *src_addr, size_t len,
+                      int prot, void **pptr);
+int rtdm_munmap(rtdm_user_info_t *user_info, void *ptr, size_t len);
+
 static inline int rtdm_read_user_ok(rtdm_user_info_t *user_info,
                                     const void __user *ptr, size_t size)
 {
Index: ksrc/skins/rtdm/drvlib.c
===================================================================
--- ksrc/skins/rtdm/drvlib.c	(Revision 551)
+++ ksrc/skins/rtdm/drvlib.c	(Arbeitskopie)
@@ -31,7 +31,9 @@
 
 
 #include <linux/delay.h>
+#include <linux/mman.h>
 
+#define XENO_HEAP_MODULE
 #include <rtdm/rtdm_driver.h>
 
 
@@ -1286,7 +1288,7 @@
  * Rescheduling: never.
  */
 int rtdm_irq_disable(rtdm_irq_t *irq_handle);
-/** @} */
+/** @} Interrupt Management Services */
 
 
 /*!
@@ -1358,16 +1360,127 @@
  * environments.
  */
 void rtdm_nrtsig_pend(rtdm_nrtsig_t *nrt_sig);
-/** @} */
+/** @} Non-Real-Time Signalling Services */
 
+#endif /* DOXYGEN_CPP */
 
+
 /*!
  * @ingroup driverapi
  * @defgroup util Utility Services
  * @{
  */
 
+static int rtdm_mmap_buffer(struct file *filp, struct vm_area_struct *vma)
+{
+    return xnarch_remap_page_range(vma, vma->vm_start,
+                                   virt_to_phys(filp->private_data),
+                                   vma->vm_end - vma->vm_start, PAGE_SHARED);
+}
+
+static struct file_operations rtdm_mmap_fops = {
+    .mmap = rtdm_mmap_buffer,
+};
+
 /**
+ * Map a kernel memory range into the address space of the user.
+ *
+ * @param[in] user_info User information pointer as passed to the invoked
+ * device operation handler
+ * @param[in] src_addr Kernel address to be mapped
+ * @param[in] len Length of the memory range
+ * @param[in] prot Protection flags for the user's memory range, typically
+ * either PROT_READ or PROT_READ|PROT_WRITE
+ * @param[in,out] pptr Address of a pointer containing the desired user
+ * address or NULL on entry and the finally assigned address on return
+ *
+ * @return 0 on success, otherwise:
+ *
+ * - -EXXX is returned if .
+ *
+ * @note An RTDM driver is expected to invoke rtdm_munmap on every mapped
+ * memory range either when the user requests it explicitly or when the
+ * related device is closed.
+ *
+ * Environments:
+ *
+ * This service can be called from:
+ *
+ * - Kernel module initialization/cleanup code
+ * - User-space task (non-RT)
+ *
+ * Rescheduling: possible.
+ */
+int rtdm_mmap_to_user(rtdm_user_info_t *user_info, void *src_addr, size_t len,
+                      int prot, void **pptr)
+{
+    struct file             *filp;
+    struct file_operations  *old_fops;
+    void                    *old_priv_data;
+    void                    *user_ptr;
+
+    filp = filp_open("/dev/zero", O_RDWR, 0);
+    if (IS_ERR(filp))
+        return PTR_ERR(filp);
+
+    old_fops = filp->f_op;
+    filp->f_op = &rtdm_mmap_fops;
+
+    old_priv_data = filp->private_data;
+    filp->private_data = src_addr;
+
+    down_write(&user_info->mm->mmap_sem);
+    user_ptr = (void *)do_mmap(filp, (unsigned long)*pptr, len, prot,
+                               MAP_SHARED, 0);
+    up_write(&user_info->mm->mmap_sem);
+
+    filp->f_op = old_fops;
+    filp->private_data = old_priv_data;
+
+    filp_close(filp, user_info->files);
+
+    if (IS_ERR(user_ptr))
+        return PTR_ERR(user_ptr);
+
+    *pptr = user_ptr;
+    return 0;
+}
+
+/**
+ * Unmap a user memory range.
+ *
+ * @param[in] user_info User information pointer as passed to
+ * rtdm_mmap_to_user() when requesting to map the memory range
+ * @param[in] ptr User address or the memory range
+ * @param[in] len Length of the memory range
+ *
+ * @return 0 on success, otherwise:
+ *
+ * - -EXXX is returned if .
+ *
+ * Environments:
+ *
+ * This service can be called from:
+ *
+ * - Kernel module initialization/cleanup code
+ * - User-space task (non-RT)
+ *
+ * Rescheduling: possible.
+ */
+int rtdm_munmap(rtdm_user_info_t *user_info, void *ptr, size_t len)
+{
+    int err;
+
+    down_write(&user_info->mm->mmap_sem);
+    err = do_munmap(user_info->mm, (unsigned long)ptr, len);
+    up_write(&user_info->mm->mmap_sem);
+
+    return err;
+}
+
+#ifdef DOXYGEN_CPP /* Only used for doxygen doc generation */
+
+/**
  * Real-time safe message printing on kernel console
  *
  * @param[in] format Format string (conforming standard @c printf())
@@ -1583,6 +1696,6 @@
  */
 int rtdm_in_rt_context(void);
 
-/** @} */
+#endif /* DOXYGEN_CPP */
 
-#endif /* DOXYGEN_CPP */
+/** @} Utility Services */

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 252 bytes --]

             reply	other threads:[~2006-02-10  0:09 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-02-10  0:09 Jan Kiszka [this message]
2006-02-10  0:37 ` [Xenomai-core] [PATCH] provide rtdm_mmap_to_user / rtdm_munmap Jan Kiszka
2006-02-10 20:58   ` Rodrigo Rosenfeld Rosas
2006-02-10 21:28     ` Rodrigo Rosenfeld Rosas
2006-02-11  0:35       ` Jan Kiszka
2006-02-11 13:11         ` Rodrigo Rosenfeld Rosas
2006-02-11 13:29           ` Jan Kiszka
2006-02-11 19:44             ` Rodrigo Rosenfeld Rosas
2006-02-12 22:45               ` Jan Kiszka
2006-02-13  3:22                 ` Rodrigo Rosenfeld Rosas
2006-02-14  0:39                   ` Jan Kiszka
2006-02-14  2:04                     ` Rodrigo Rosenfeld Rosas
2006-02-14  7:55                       ` Jan Kiszka
  -- strict thread matches above, loose matches on Subject: below --
2006-02-14 13:14 Rodrigo Rosenfeld Rosas
2006-02-14 19:13 ` Philippe Gerum
2006-02-15  0:30 ` Jan Kiszka
2006-02-15 14:53   ` Rodrigo Rosenfeld Rosas
2006-02-16 17:14     ` Rodrigo Rosenfeld Rosas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=43EBD9D6.5090404@domain.hid \
    --to=jan.kiszka@domain.hid \
    --cc=lbocseg@domain.hid \
    --cc=xenomai@xenomai.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.