2 Commits 64cfc1638f ... ff72efa5c7

Author SHA1 Message Date
  Agustina Arzille ff72efa5c7 Rename IPC page message and simplify VM bits 6 months ago
  Agustina Arzille 6bc394b648 Small style change 6 months ago
10 changed files with 94 additions and 131 deletions
  1. 1 1
      arch/x86/machine/pmu_intel.c
  2. 15 20
      kern/capability.c
  3. 3 3
      kern/capability.h
  4. 5 5
      kern/ipc.c
  5. 24 23
      kern/ipc.h
  6. 1 3
      kern/shell.c
  7. 3 6
      kern/unwind.c
  8. 17 16
      test/test_cap.c
  9. 25 54
      vm/map.c
  10. 0 0
      vm/map.h

+ 1 - 1
arch/x86/machine/pmu_intel.c

@@ -259,7 +259,7 @@ static struct perfmon_dev pmu_intel_dev __read_mostly;
 static void
 pmu_intel_percpu_init (void)
 {
-  const struct pmu_intel *pmu = pmu_intel_get();
+  const struct pmu_intel *pmu = pmu_intel_get ();
   uint64_t pmc_mask = (1ULL << pmu->nr_pmcs) - 1;
   cpu_set_msr64 (PMU_INTEL_MSR_GLOBAL_CTRL, 0x700000000 | pmc_mask);
 }

+ 15 - 20
kern/capability.c

@@ -383,16 +383,13 @@ cap_transfer_iters (struct task *task, struct cap_iters *r_it,
       data->caps_recv += nr_caps;
     }
 
-  if (ipc_page_iter_size (&r_it->page) && ipc_page_iter_size (&l_it->page))
+  if (ipc_vme_iter_size (&r_it->vme) && ipc_vme_iter_size (&l_it->vme))
     {
-      uint32_t *ptr = dir == IPC_COPY_TO ? &r_it->page.cur : &l_it->page.cur;
-      uint32_t prev = *ptr;
-      int nr_pages = ipc_page_iter_copy (task, &r_it->page, &l_it->page, dir);
+      int nr_vmes = ipc_vme_iter_copy (task, &r_it->vme, &l_it->vme, dir);
+      if (nr_vmes < 0)
+        return (nr_vmes);
 
-      if (nr_pages < 0)
-        return (nr_pages);
-
-      data->pages_recv += *ptr - prev;
+      data->vmes_recv += nr_vmes;
     }
 
   return (ret);
@@ -624,8 +621,8 @@ cap_ipc_msg_data_init (struct ipc_msg_data *data, uintptr_t tag)
   data->tag = tag;
   data->nbytes = 0;
   data->flags = 0;
-  data->pages_sent = data->caps_sent = 0;
-  data->pages_recv = data->caps_recv = 0;
+  data->vmes_sent = data->caps_sent = 0;
+  data->vmes_recv = data->caps_recv = 0;
 }
 
 static void
@@ -644,7 +641,7 @@ cap_iters_copy (struct cap_iters *dst, const struct cap_iters *src)
 
   copy_simple (dst, src, iov);
   copy_simple (dst, src, cap);
-  copy_simple (dst, src, page);
+  copy_simple (dst, src, vme);
 #undef copy_simple
 }
 
@@ -706,9 +703,9 @@ cap_sender_impl (struct cap_flow *flow, uintptr_t tag, struct cap_iters *in,
   user_copy_to ((void *)port->ctx[2], &port->mdata, sizeof (port->mdata));
 
   // After the copy, switch the counters.
-  port->mdata.pages_sent = port->mdata.pages_recv;
+  port->mdata.vmes_sent = port->mdata.vmes_recv;
   port->mdata.caps_sent = port->mdata.caps_recv;
-  port->mdata.pages_recv = port->mdata.caps_recv = 0;
+  port->mdata.vmes_recv = port->mdata.caps_recv = 0;
 
   // Jump to new PC and SP.
   ssize_t ret = cpu_port_swap (port->ctx, cur_port, (void *)flow->entry);
@@ -775,9 +772,7 @@ cap_push_pull_msg (struct cap_iters *l_it, struct ipc_msg_data *mdata,
 ssize_t
 cap_pull_iters (struct cap_iters *it, struct ipc_msg_data *mdata)
 {
-  struct thread *self = thread_self ();
-  struct cap_port_entry *port = self->cur_port;
-
+  struct cap_port_entry *port = thread_self()->cur_port;
   if (! port)
     return (-EINVAL);
 
@@ -788,7 +783,7 @@ cap_pull_iters (struct cap_iters *it, struct ipc_msg_data *mdata)
   if (ret < 0)
     return (ret);
 
-  port->mdata.pages_sent += tmp.pages_recv;
+  port->mdata.vmes_sent += tmp.vmes_recv;
   port->mdata.caps_sent += tmp.caps_recv;
 
   if (mdata && user_copy_to (mdata, &tmp, sizeof (tmp)) != 0)
@@ -814,14 +809,14 @@ cap_push_iters (struct cap_iters *it, struct ipc_msg_data *mdata)
     return (ret);
 
   port->mdata.nbytes += ret;
-  port->mdata.pages_recv += out_data.pages_recv;
+  port->mdata.vmes_recv += out_data.vmes_recv;
   port->mdata.caps_recv += out_data.caps_recv;
 
   if (mdata)
     {
-      out_data.pages_sent = out_data.pages_recv;
+      out_data.vmes_sent = out_data.vmes_recv;
       out_data.caps_sent = out_data.caps_recv;
-      out_data.pages_recv = out_data.caps_recv = 0;
+      out_data.vmes_recv = out_data.caps_recv = 0;
       if (user_copy_to (mdata, &out_data, sizeof (*mdata)) != 0)
         ret = -EFAULT;
     }

+ 3 - 3
kern/capability.h

@@ -153,7 +153,7 @@ struct cap_iters
 {
   struct ipc_iov_iter iov;
   struct ipc_cap_iter cap;
-  struct ipc_page_iter page;
+  struct ipc_vme_iter vme;
 };
 
 struct bulletin;
@@ -281,7 +281,7 @@ void cap_notify_dead (struct bulletin *bulletin);
     {   \
       iov_init (&(it)->iov, (void *)(buf), size);   \
       ipc_cap_iter_init (&(it)->cap, 0, 0);   \
-      ipc_page_iter_init (&(it)->page, 0, 0);   \
+      ipc_vme_iter_init (&(it)->vme, 0, 0);   \
     }   \
   while (0)
 
@@ -296,7 +296,7 @@ void cap_notify_dead (struct bulletin *bulletin);
     {   \
       ipc_iov_iter_init (&(it)->iov, (msg)->iovs, (msg)->iov_cnt);   \
       ipc_cap_iter_init (&(it)->cap, (msg)->caps, (msg)->cap_cnt);   \
-      ipc_page_iter_init (&(it)->page, (msg)->pages, (msg)->page_cnt);   \
+      ipc_vme_iter_init (&(it)->vme, (msg)->vmes, (msg)->vme_cnt);   \
     }   \
   while (0)
 

+ 5 - 5
kern/ipc.c

@@ -441,11 +441,11 @@ ipc_cap_iter_copy (struct task *r_task, struct ipc_cap_iter *r_it,
 }
 
 int
-ipc_page_iter_copy (struct task *r_task, struct ipc_page_iter *r_it,
-                    struct ipc_page_iter *l_it, int direction)
+ipc_vme_iter_copy (struct task *r_task, struct ipc_vme_iter *r_it,
+                   struct ipc_vme_iter *l_it, int direction)
 {
-#define ipc_page_copy_impl(task, r_it, l_it, dir)   \
+#define ipc_vme_copy_impl(task, r_it, l_it, dir)   \
   vm_map_iter_copy ((task)->map, (r_it), (l_it), (dir))
-  IPC_ITER_LOOP (page, ipc_page_copy_impl);
-#undef ipc_page_copy_impl
+  IPC_ITER_LOOP (vme, ipc_vme_copy_impl);
+#undef ipc_vme_copy_impl
 }

+ 24 - 23
kern/ipc.h

@@ -26,11 +26,12 @@
 
 #include <kern/types.h>
 
-struct ipc_msg_page
+struct ipc_msg_vme
 {
   uintptr_t addr;
   size_t size;
   int prot;
+  int max_prot;
 };
 
 struct ipc_msg_cap
@@ -58,9 +59,9 @@ struct ipc_cap_iter
   uint32_t end;
 };
 
-struct ipc_page_iter
+struct ipc_vme_iter
 {
-  struct ipc_msg_page *begin;
+  struct ipc_msg_vme *begin;
   uint32_t cur;
   uint32_t end;
 };
@@ -70,8 +71,8 @@ struct ipc_msg
   size_t size;
   struct iovec *iovs;
   uint32_t iov_cnt;
-  struct ipc_msg_page *pages;
-  uint32_t page_cnt;
+  struct ipc_msg_vme *vmes;
+  uint32_t vme_cnt;
   struct ipc_msg_cap *caps;
   uint32_t cap_cnt;
 };
@@ -87,8 +88,8 @@ struct ipc_msg_data
   uint32_t flags;
   uintptr_t tag;
   ssize_t nbytes;
-  uint32_t pages_sent;
-  uint32_t pages_recv;
+  uint32_t vmes_sent;
+  uint32_t vmes_recv;
   uint32_t caps_sent;
   uint32_t caps_recv;
 };
@@ -102,7 +103,7 @@ struct task;
 /*
  * IPC iterator functions.
  *
- * These come in 3 flavors: iovec, capabilities and pages. The former works
+ * These come in 3 flavors: iovec, capabilities and VMEs. The former works
  * by simply copying data; the other 2 by transfering objects across tasks.
  */
 
@@ -121,15 +122,15 @@ ipc_cap_iter_size (const struct ipc_cap_iter *it)
 }
 
 static inline void
-ipc_page_iter_init (struct ipc_page_iter *it,
-                    struct ipc_msg_page *msg, uint32_t nr_msgs)
+ipc_vme_iter_init (struct ipc_vme_iter *it,
+                   struct ipc_msg_vme *msg, uint32_t nr_msgs)
 {
   it->begin = msg;
   it->cur = 0, it->end = nr_msgs;
 }
 
 static inline int
-ipc_page_iter_size (const struct ipc_page_iter *it)
+ipc_vme_iter_size (const struct ipc_vme_iter *it)
 {
   return ((int)(it->end - it->cur));
 }
@@ -171,9 +172,9 @@ ssize_t ipc_iov_iter_copy (struct task *r_task, struct ipc_iov_iter *r_it,
 int ipc_cap_iter_copy (struct task *r_task, struct ipc_cap_iter *r_it,
                        struct ipc_cap_iter *l_it, int direction);
 
-// Transfer pages in iterators between a local and a remote task.
-int ipc_page_iter_copy (struct task *r_task, struct ipc_page_iter *r_it,
-                        struct ipc_page_iter *l_it, int direction);
+// Transfer VMEs in iterators between a local and a remote task.
+int ipc_vme_iter_copy (struct task *r_task, struct ipc_vme_iter *r_it,
+                       struct ipc_vme_iter *l_it, int direction);
 
 // Copy bytes in iovecs between a local and a remote task.
 static inline ssize_t
@@ -186,16 +187,16 @@ ipc_bcopyv (struct task *r_task, struct iovec *r_iov, uint32_t r_niov,
   return (ipc_iov_iter_copy (r_task, &r_it, &l_it, direction));
 }
 
-// Transfer pages between a remote and a local task.
+// Transfer VMEs between a remote and a local task.
 static inline int
-ipc_copy_pages (struct task *r_task, struct ipc_msg_page *r_pages,
-                uint32_t r_npages, struct ipc_msg_page *l_pages,
-                uint32_t l_npages, int direction)
-{
-  struct ipc_page_iter r_it, l_it;
-  ipc_page_iter_init (&r_it, r_pages, r_npages);
-  ipc_page_iter_init (&l_it, l_pages, l_npages);
-  return (ipc_page_iter_copy (r_task, &r_it, &l_it, direction));
+ipc_copy_vmes (struct task *r_task, struct ipc_msg_vme *r_vmes,
+               uint32_t r_nvmes, struct ipc_msg_vme *l_vmes,
+               uint32_t l_nvmes, int direction)
+{
+  struct ipc_vme_iter r_it, l_it;
+  ipc_vme_iter_init (&r_it, r_vmes, r_nvmes);
+  ipc_vme_iter_init (&l_it, l_vmes, l_nvmes);
+  return (ipc_vme_iter_copy (r_task, &r_it, &l_it, direction));
 }
 
 // Transfer capabilities between a remote and a local task.

+ 1 - 3
kern/shell.c

@@ -1055,8 +1055,7 @@ shell_start (uintptr_t value __unused, void *arg __unused)
   thread_attr_init (&attr, THREAD_KERNEL_PREFIX "shell");
   thread_attr_set_detached (&attr);
 
-  struct thread *thread;
-  int error = thread_create (&thread, &attr, shell_main_run, &shell_main);
+  int error = thread_create (NULL, &attr, shell_main_run, &shell_main);
   error_check (error, "thread_create");
 }
 
@@ -1067,7 +1066,6 @@ shell_setup (void)
   shell_init (&shell_main, &shell_main_cmd_set, console_stream);
   bulletin_subscribe (log_get_bulletin (), &shell_log_bulletin_sub,
                       shell_start, NULL);
-
   return (0);
 }
 

+ 3 - 6
kern/unwind.c

@@ -279,12 +279,9 @@ unw_read_encptr (uint8_t enc, const unsigned char **ptr,
         return (-EINVAL);
     }
 
-  if (enc & DW_EH_PE_indirect)
-    {
-      p = (const unsigned char *)(uintptr_t)ret;
-      if (unw_read_safe ((uintptr_t)p, &ret) != 0)
-        return (-EFAULT);
-    }
+  if ((enc & DW_EH_PE_indirect) &&
+      unw_read_safe (ret, &ret) != 0)
+    return (-EFAULT);
 
   *ptr = p;
   *out = ret;

+ 17 - 16
test/test_cap.c

@@ -50,7 +50,7 @@ struct test_cap_vars
   char buf[16];
   uint32_t bufsize;
   struct iovec iov;
-  struct ipc_msg_page mpage;
+  struct ipc_msg_vme mvme;
   struct ipc_msg_cap mcap;
   struct cap_thread_info info;
 };
@@ -78,7 +78,7 @@ static void
 test_cap_entry (struct ipc_msg *msg, struct ipc_msg_data *mdata)
 {
   assert (mdata->nbytes > 0);
-  assert (mdata->pages_recv == 1);
+  assert (mdata->vmes_recv == 1);
   assert (mdata->caps_recv == 1);
   assert (mdata->tag == TEST_CAP_CHANNEL_TAG);
   assert (mdata->task_id == task_id (thread_self()->task));
@@ -91,11 +91,11 @@ test_cap_entry (struct ipc_msg *msg, struct ipc_msg_data *mdata)
   assert (memcmp (vars->buf, "hello", 5) == 0);
 
   struct vm_map_entry entry;
-  int error = vm_map_lookup (vm_map_self (), vars->mpage.addr, &entry);
+  int error = vm_map_lookup (vm_map_self (), vars->mvme.addr, &entry);
 
   assert (! error);
   assert (VM_MAP_PROT (entry.flags) == VM_PROT_READ);
-  assert (*(char *)vars->mpage.addr == 'x');
+  assert (*(char *)vars->mvme.addr == 'x');
 
   vm_map_entry_put (&entry);
 
@@ -117,8 +117,8 @@ test_cap_entry (struct ipc_msg *msg, struct ipc_msg_data *mdata)
   assert (mp->nbytes == nb);
 
   memset (mem, 'z', 100);
-  vars->mpage.addr = (uintptr_t)mem;
-  vars->mpage.size = PAGE_SIZE;
+  vars->mvme.addr = (uintptr_t)mem;
+  vars->mvme.size = PAGE_SIZE;
   vars->mcap.cap = test_cap_alloc_task (task_self ());
   vars->iov = IOVEC (memset (vars->buf, '?', sizeof (vars->buf)), 8);
 
@@ -170,15 +170,15 @@ test_cap_receiver (void *arg)
     assert (vars->mdata.thread_id = thread_id (thread_self ()));
   }
 
-  vars->mpage = (struct ipc_msg_page) { .addr = PAGE_SIZE * 10 };
+  vars->mvme = (struct ipc_msg_vme) { .addr = PAGE_SIZE * 10 };
   vars->iov = IOVEC (&vars->bufsize, sizeof (vars->bufsize));
   vars->msg = (struct ipc_msg)
     {
       .size = sizeof (struct ipc_msg),
       .iovs = &vars->iov,
       .iov_cnt = 1,
-      .pages = &vars->mpage,
-      .page_cnt = 1,
+      .vmes = &vars->mvme,
+      .vme_cnt = 1,
       .caps = &vars->mcap,
       .cap_cnt = 1,
     };
@@ -207,7 +207,7 @@ test_cap_sender (void *arg)
 
   struct
     {
-      struct ipc_msg_page mpage;
+      struct ipc_msg_vme mvme;
       char buf[6];
       uint32_t bufsize;
       struct iovec iovecs[2];
@@ -216,10 +216,11 @@ test_cap_sender (void *arg)
       struct ipc_msg_cap mcap;
     } *vars = (void *)((char *)mem + PAGE_SIZE);
 
-  vars->mpage = (struct ipc_msg_page)
+  vars->mvme = (struct ipc_msg_vme)
     {
       .addr = (uintptr_t)memset (mem, 'x', PAGE_SIZE),
       .prot = VM_PROT_READ,
+      .max_prot = VM_PROT_READ,
       .size = PAGE_SIZE
     };
 
@@ -239,8 +240,8 @@ test_cap_sender (void *arg)
       .size = sizeof (struct ipc_msg),
       .iovs = vars->iovecs,
       .iov_cnt = 2,
-      .pages = &vars->mpage,
-      .page_cnt = 1,
+      .vmes = &vars->mvme,
+      .vme_cnt = 1,
       .caps = &vars->mcap,
       .cap_cnt = 1,
     };
@@ -250,9 +251,9 @@ test_cap_sender (void *arg)
   assert (nb > 0);
   assert (vars->bufsize == 'Z');
   assert (memcmp (vars->buf, "?????", 5) == 0);
-  assert (*(char *)vars->mpage.addr == 'z');
-  assert (vars->mdata.pages_sent == 1);
-  assert (vars->mdata.pages_recv == 1);
+  assert (*(char *)vars->mvme.addr == 'z');
+  assert (vars->mdata.vmes_sent == 1);
+  assert (vars->mdata.vmes_recv == 1);
   assert (vars->mdata.caps_sent == 1);
   assert (vars->mdata.caps_recv == 1);
 

+ 25 - 54
vm/map.c

@@ -661,57 +661,29 @@ vm_map_protect_entry (struct vm_map *map, struct vm_map_entry *entry,
   else if (VM_MAP_PROT (entry->flags) == prot)
     return (0);   // Nothing to do.
 
-  struct list entries;
-  list_init (&entries);
-
-  if (start == entry->start)
+  int nr_entries = (start != entry->start) + (end != entry->end);
+  if (nr_entries != 0)
     {
-      if (end == entry->end)
-        {
-          VM_MAP_SET_PROT (&entry->flags, prot);
-          /*
-           * The protection of the full entry changed. See if we can merge
-           * some entries.
-           *
-           * This is done by looking to the entry before, since protection
-           * changes are applied while iterating forward.
-           */
-           if (&entry->list_node != list_first (&map->entry_list))
-             vm_map_try_merge_entries (map, list_prev_entry (entry, list_node),
-                                       entry, dead);
-        }
-      else
-        {
-          int error = vm_map_entry_alloc (&entries, 1);
-          if (error)
-            return (error);
+      struct list entries;
+      list_init (&entries);
 
-          vm_map_clip_end (map, entry, end, &entries);
-          VM_MAP_SET_PROT (&entry->flags, prot);
-        }
-    }
-  else if (end == entry->end)
-    {
-      int error = vm_map_entry_alloc (&entries, 1);
+      int error = vm_map_entry_alloc (&entries, nr_entries);
       if (error)
         return (error);
 
       vm_map_clip_start (map, entry, start, &entries);
+      vm_map_clip_end (map, entry, end, &entries);
       VM_MAP_SET_PROT (&entry->flags, prot);
+      assert (list_empty (&entries));
     }
   else
     {
-      int error = vm_map_entry_alloc (&entries, 2);
-      if (error)
-        return (error);
-
-      vm_map_clip_start (map, entry, start, &entries);
-      vm_map_clip_end (map, entry, end, &entries);
       VM_MAP_SET_PROT (&entry->flags, prot);
+      if (&entry->list_node != list_first (&map->entry_list))
+        vm_map_try_merge_entries (map, list_prev_entry (entry, list_node),
+                                  entry, dead);
     }
 
-  assert (list_empty (&entries));
-
   if (prot == VM_PROT_NONE)
     pmap_remove_range (map->pmap, start, end, VM_MAP_PROT_PFLAGS);
   else
@@ -1236,7 +1208,7 @@ vm_map_fork (struct vm_map **mapp, struct vm_map *src)
 }
 
 static void
-vm_map_iter_cleanup (struct vm_map *map, struct ipc_page_iter *it, uint32_t ix)
+vm_map_iter_cleanup (struct vm_map *map, struct ipc_vme_iter *it, uint32_t ix)
 {
   for (; it->cur != ix; --it->cur)
     {
@@ -1264,11 +1236,11 @@ vm_map_iter_fini (struct sxlock **lockp)
 }
 
 int
-vm_map_iter_copy (struct vm_map *r_map, struct ipc_page_iter *r_it,
-                  struct ipc_page_iter *l_it, int direction)
+vm_map_iter_copy (struct vm_map *r_map, struct ipc_vme_iter *r_it,
+                  struct ipc_vme_iter *l_it, int direction)
 {
   struct vm_map *in_map, *out_map;
-  struct ipc_page_iter *in_it, *out_it;
+  struct ipc_vme_iter *in_it, *out_it;
 
   if (direction == IPC_COPY_FROM)
     {
@@ -1282,8 +1254,8 @@ vm_map_iter_copy (struct vm_map *r_map, struct ipc_page_iter *r_it,
     }
 
   uint32_t prev = out_it->cur;
-  int i = 0, nmax = (int)MIN (ipc_page_iter_size (in_it),
-                              ipc_page_iter_size (out_it));
+  int i = 0, nmax = (int)MIN (ipc_vme_iter_size (in_it),
+                              ipc_vme_iter_size (out_it));
   struct sxlock *lock CLEANUP (vm_map_iter_fini) = &in_map->lock;
 
   SXLOCK_EXGUARD (&out_map->lock);
@@ -1301,37 +1273,36 @@ vm_map_iter_copy (struct vm_map *r_map, struct ipc_page_iter *r_it,
         {
           _Auto entry = vm_map_lookup_nearest (in_map, page.addr);
           _Auto outp = &out_it->begin[out_it->cur];
-          uint64_t offset;
 
 #define ERR(code)   \
   return ((vm_map_iter_cleanup (out_map, out_it, prev)), (code))
 
           if (! entry)
             ERR (-ESRCH);
-          else if ((VM_MAP_MAXPROT (entry->flags) & page.prot) != page.prot)
+          else if ((VM_MAP_MAXPROT (entry->flags) & page.max_prot) !=
+                   page.max_prot || (page.max_prot & page.prot) != page.prot)
             ERR (-EACCES);
-          else if (entry->flags & VM_MAP_ANON)
-            offset = entry->offset + (page.addr - entry->start);
-          else
-            offset = entry->offset;
 
           size_t size = MIN (end - page.addr, page.size);
           if (! size)
             ERR (-EINVAL);
 
-          int flags = entry->flags & ~VM_MAP_ANON;
-          VM_MAP_SET_PROT (&flags, page.prot);
-          int error = vm_map_enter_locked (out_map, &outp->addr, size,
+          uint64_t offset = entry->offset + (page.addr - entry->start);
+          int flags = VM_MAP_FLAGS (page.max_prot, page.prot,
+                                    VM_MAP_INHERIT (entry->flags),
+                                    VM_MAP_ADVICE (entry->flags), 0),
+              error = vm_map_enter_locked (out_map, &outp->addr, size,
                                            0, flags, entry->object, offset);
           if (error)
             ERR (-error);
 
           outp->prot = page.prot;
+          outp->max_prot = page.max_prot;
           outp->size = size;
           page.addr += size;
           ++out_it->cur;
         }
-      while (page.addr < end && ipc_page_iter_size (out_it));
+      while (page.addr < end && ipc_vme_iter_size (out_it));
 
       ++in_it->cur;
     }

+ 0 - 0
vm/map.h


Some files were not shown because too many files changed in this diff