Selaa lähdekoodia

[LibOS] Implement mincore() system call

Isaku Yamahata 5 vuotta sitten
vanhempi
commit
086b997792

+ 1 - 0
LibOS/shim/include/shim_table.h

@@ -359,6 +359,7 @@ int shim_do_sched_yield (void);
 void * shim_do_mremap (void * addr, size_t old_len, size_t new_len,
                        int flags, void * new_addr);
 int shim_do_msync (void * start, size_t len, int flags);
+int shim_do_mincore (void * start, size_t len, unsigned char * vec);
 int shim_do_dup (int fd);
 int shim_do_dup2 (int oldfd, int newfd);
 int shim_do_pause (void);

+ 3 - 2
LibOS/shim/src/shim_syscalls.c

@@ -231,8 +231,9 @@ SHIM_SYSCALL_PASSTHROUGH (mremap, 5, void *, void *, addr, size_t, old_len,
 
 SHIM_SYSCALL_PASSTHROUGH (msync, 3, int, void *, start, size_t, len, int, flags)
 
-SHIM_SYSCALL_PASSTHROUGH (mincore, 3, int, void *, start, size_t, len,
-                          unsigned char *, vec)
+/* mincore: sys/shim_mmap.c */
+DEFINE_SHIM_SYSCALL (mincore, 3, shim_do_mincore, int, void *, start,
+                     size_t, len, unsigned char *, vec)
 
 SHIM_SYSCALL_PASSTHROUGH (madvise, 3, int, void *, start, size_t, len,
                           int, behavior)

+ 48 - 0
LibOS/shim/src/sys/shim_mmap.c

@@ -23,6 +23,8 @@
  * Implementation of system call "mmap", "munmap" and "mprotect".
  */
 
+#include <stdatomic.h>
+
 #include <shim_internal.h>
 #include <shim_table.h>
 #include <shim_handle.h>
@@ -201,3 +203,49 @@ int shim_do_munmap (void * addr, size_t length)
 
     return 0;
 }
+
+/* This emulation of mincore() always tells that pages are _NOT_ in RAM
+ * pessimistically due to lack of a good way to know it.
+ * Possibly it may cause performance(or other) issue due to this lying.
+ */
+int shim_do_mincore(void *addr, size_t len, unsigned char * vec)
+{
+    if (!ALIGNED(addr))
+        return -EINVAL;
+
+    if (test_user_memory(addr, len, false))
+        return -ENOMEM;
+
+    unsigned long pages = ALIGN_UP(len) / allocsize;
+    if (test_user_memory(vec, pages, true))
+        return -EFAULT;
+
+    for (unsigned long i = 0; i < pages; i++) {
+        struct shim_vma_val vma;
+        if (lookup_overlap_vma(addr + i * allocsize, 1, &vma) < 0)
+            return -ENOMEM;
+        /*
+         * lookup_overlap_vma() calls __dump_vma() which adds a reference to
+         * file, remove the reference to file immediately since we don't use
+         * it anyway
+         */
+        if (vma.file)
+            put_handle(vma.file);
+        if (vma.flags & VMA_UNMAPPED)
+            return -ENOMEM;
+    }
+
+    static atomic_bool warned = false;
+    if (!warned) {
+        warned = true;
+        warn("mincore emulation always tells pages are _NOT_ in RAM. "
+             "This may cause issues.\n");
+    }
+
+    /* There is no good way to know if the page is in RAM.
+     * Conservatively tell that it's not in RAM. */
+    for (unsigned long i = 0; i < pages; i++)
+        vec[i] = 0;
+
+    return 0;
+}

+ 4 - 0
LibOS/shim/test/apps/ltp/PASSED

@@ -358,6 +358,10 @@ mkdirat01,2
 mkdirat01,3
 mkdirat01,4
 mkdirat01,5
+mincore01,1
+mincore01,2
+mincore01,3
+mincore01,4
 mlock03,1
 mmap001,1
 mmap001,2