Make kernel create IPI cap which is passed to monitor.
authorSimon Gerber <simon.gerber@inf.ethz.ch>
Fri, 21 Nov 2014 14:05:09 +0000 (15:05 +0100)
committerSimon Gerber <simon.gerber@inf.ethz.ch>
Fri, 21 Nov 2014 14:34:15 +0000 (15:34 +0100)
This replaces the create_cap invocation in the monitor that creates an IPI cap
when someone requests a copy of it.

errors/errno.fugu
include/barrelfish/caddr.h
include/barrelfish_kpi/init.h
kernel/startup.c
lib/barrelfish/capabilities.c
usr/init/spawn.c
usr/monitor/monitor_rpc_server.c

index e23488e..a95ebab 100755 (executable)
@@ -649,6 +649,7 @@ errors init INIT_ERR_ {
     failure COPY_SUPERCN_CAP    "Failed to copy superCN cap to mem_serv",
     failure MAP_BOOTINFO        "Failed to map bootinfo to child",
     failure COPY_KERNEL_CAP     "Failed to copy kernel cap to monitor",
+    failure COPY_IPI            "Failed to copy IPI cap to monitor",
     failure COPY_PERF_MON       "Failed to copy performance monitoring cap to monitor",
     failure COPY_MODULECN_CAP   "Failed to copy module CNode cap to monitor",
     failure COPY_PACN_CAP       "Failed to copy phys addr CNode cap to monitor",
index 86db376..c0cd091 100644 (file)
@@ -62,7 +62,8 @@ extern struct cnoderef cnode_root, cnode_task, cnode_base,
 
 /* well-known capabilities */
 extern struct capref cap_root, cap_monitorep, cap_irq, cap_io, cap_dispatcher,
-  cap_selfep, cap_kernel, cap_initep, cap_perfmon, cap_dispframe, cap_sessionid;
+                     cap_selfep, cap_kernel, cap_initep, cap_perfmon, cap_dispframe,
+                     cap_sessionid, cap_ipi;
 
 /**
  * \brief Returns the number of valid bits in the CSpace address of a cap
index 20c7281..2928270 100644 (file)
 #define TASKCN_SLOT_PERF_MON    14  ///< cap for performance monitoring
 #define TASKCN_SLOT_DISPFRAME2  15  ///< Copy of dispatcher frame cap (mapped into spawn vspace)
 #define TASKCN_SLOT_ARGSPAGE2   16  ///< Copy of environment cap (mapped into spawn vspace)
-#define TASKCN_SLOT_SYSMEM     17  ///< First free slot in taskcn for user
+#define TASKCN_SLOT_SYSMEM      17  ///< ???
 #define TASKCN_SLOT_COREBOOT    18  ///< Copy of realmode section used to bootstrap a core
-#define TASKCN_SLOTS_USER       19  ///< First free slot in taskcn for user
+#define TASKCN_SLOT_IPI         19  ///< Copy of IPI cap
+#define TASKCN_SLOTS_USER       20  ///< First free slot in taskcn for user
 
 /// Address bits resolved for the standard CNodes (taskcn, supercn, base_page_cn)
 #define DEFAULT_CN_ADDR_BITS    (CPTR_BITS - DEFAULT_CNODE_BITS)
index 613b92a..f815812 100644 (file)
@@ -301,6 +301,12 @@ struct dcb *spawn_module(struct spawn_state *st,
                           caps_locate_slot(CNODE(st->taskcn), TASKCN_SLOT_IRQ));
     assert(err_is_ok(err));
 
+    // Create capability for IPI sending
+    struct cte *ipicap_cte = caps_locate_slot(CNODE(st->taskcn),
+                                              TASKCN_SLOT_IPI);
+    err = caps_create_new(ObjType_IPI, 0, 0, 0, ipicap_cte);
+    assert(err_is_ok(err));
+
     /* Initialize dispatcher */
     dispatcher_handle_t init_handle
         = local_phys_to_mem(init_dispframe_cte->cap.u.frame.base);
index 8c7af10..8ead3fc 100644 (file)
@@ -126,6 +126,12 @@ struct capref cap_kernel = {
     .slot  = TASKCN_SLOT_KERNELCAP
 };
 
+/// Capability for IPI sending (only in monitor)
+struct capref cap_ipi = {
+    .cnode = TASK_CNODE_INIT,
+    .slot  = TASKCN_SLOT_IPI
+};
+
 /// PerfMon CNode
 struct capref cap_perfmon = {
     .cnode = TASK_CNODE_INIT,
index 4eede3e..a74dd7c 100644 (file)
@@ -63,6 +63,16 @@ errval_t initialize_monitor(struct spawninfo *si)
         return err_push(err, INIT_ERR_COPY_PERF_MON);
     }
 
+    /* Give monitor the IPI capability */
+    dest.cnode = si->taskcn;
+    dest.slot = TASKCN_SLOT_IPI;
+    src.cnode = cnode_task;
+    src.slot = TASKCN_SLOT_IPI;
+    err = cap_copy(dest, src);
+    if (err_is_fail(err)) {
+        return err_push(err, INIT_ERR_COPY_IPI);
+    }
+
     /* Give monitor modulecn */
     dest.cnode = si->rootcn;
     dest.slot  = ROOTCN_SLOT_MODULECN;
index 66b9143..9fd677e 100644 (file)
@@ -693,28 +693,7 @@ static void get_ipi_cap(struct monitor_blocking_binding *b)
     // who requests it. There is currently no way to determine
     // if the client is a valid recipient
 
-    // get slot for ipi cap
-    struct capref ipi;
-    err = slot_alloc(&ipi);
-    if (err_is_fail(err)) {
-        DEBUG_ERR(err, "slot alloc for ipi");
-    }
-
-    // TODO: do this in a slightly saner way!
-    // fabricate an IPI cap
-    struct capability cap;
-    memset(&cap, 0, sizeof(cap));
-    cap.type = ObjType_IPI;
-    cap.rights = CAPRIGHTS_ALLRIGHTS;
-
-    // put it in the slot
-    capaddr_t caddr = get_cnode_addr(ipi);
-    uint8_t vbits = get_cnode_valid_bits(ipi);
-    size_t  slot  = ipi.slot;
-    err = invoke_monitor_create_cap((uint64_t*)&cap, caddr, vbits, slot);
-    assert(err_is_ok(err));
-
-    err = b->tx_vtbl.get_ipi_cap_response(b, NOP_CONT, ipi);
+    err = b->tx_vtbl.get_ipi_cap_response(b, NOP_CONT, cap_ipi);
     assert(err_is_ok(err));
 }