T284: Change flounder to use provided slots when in RPC and call lmp_chan_alloc_recv_...
authorSimon Gerber <simon.gerber@inf.ethz.ch>
Wed, 24 Aug 2016 08:10:38 +0000 (10:10 +0200)
committerSimon Gerber <simon.gerber@inf.ethz.ch>
Wed, 21 Sep 2016 09:48:21 +0000 (11:48 +0200)
Signed-off-by: Simon Gerber <simon.gerber@inf.ethz.ch>

19 files changed:
errors/errno.fugu
kernel/dispatch.c
lib/acpi_client/acpi_client.c
lib/barrelfish/inthandler.c
lib/barrelfish/ram_alloc.c
lib/octopus/client/capability_storage.c
lib/vfs/cache.c
tools/flounder/LMP.hs
tools/flounder/RPCClient.hs
usr/acpi/arch/armv8/acpi_main.c
usr/acpi/arch/x86/acpi_main.c
usr/drivers/cpuboot/main.c
usr/drivers/cpuboot/x86boot.c
usr/kaluga/device_caps.c
usr/pci/pci.c
usr/pci/pcie.c
usr/pci/pcimain.c
usr/ramfsd/main.c
usr/spawnd/service.c

index ee699a0..8637627 100755 (executable)
@@ -573,6 +573,7 @@ errors spawn SPAWN_ERR_ {
     failure ELF_MAP         "Failure in spawn_elf_map",
 
     failure SET_CAPS         "Failure in set_special_caps",
+    failure MONEP_SLOT_ALLOC "Failure allocating a slot for monitor EP",
     failure MONITOR_CLIENT         "Failure in monitor_client_setup",
     failure FREE             "Failure in spawn_free",
 
index cd2c412..ebbc65f 100644 (file)
@@ -286,6 +286,7 @@ static errval_t lmp_transfer_cap(struct capability *ep, struct dcb *send,
 
     /* Is destination empty */
     if (recv_cte->cap.type != ObjType_Null) {
+        printk(LOG_NOTE, "%s: dest slot occupied\n", __FUNCTION__);
         return SYS_ERR_LMP_CAPTRANSFER_DST_SLOT_OCCUPIED;
     }
 
index e0d76c1..6ea5c63 100644 (file)
@@ -71,6 +71,10 @@ errval_t acpi_get_vbe_bios_cap(struct capref *retcap, size_t *retsize)
     assert(retcap != NULL);
     assert(retsize != NULL);
     uint32_t s;
+    err = slot_alloc(retcap);
+    if (err_is_fail(err)) {
+        return err;
+    }
     err = rpc_client->vtbl.get_vbe_bios_cap(rpc_client, &msgerr, retcap, &s);
     *retsize = s;
     return err_is_fail(err) ? err : msgerr;
index ffc36bd..6391533 100644 (file)
@@ -41,6 +41,10 @@ errval_t alloc_dest_irq_cap(struct capref *retcap)
     errval_t err, msgerr;
 
     struct monitor_blocking_rpc_client *r = get_monitor_blocking_rpc_client();
+    err = slot_alloc(retcap);
+    if (err_is_fail(err)) {
+        return err;
+    }
     err = r->vtbl.get_irq_dest_cap(r, retcap, &msgerr);
     if (err_is_fail(err)){
         return err;
index 107c57e..a21ddb4 100644 (file)
@@ -39,22 +39,21 @@ static errval_t ram_alloc_remote(struct capref *ret, uint8_t size_bits,
         // the default value
         ram_set_affinity(0, 0);
         do {
-                struct capref cap;
-                err = slot_alloc(&cap);
+                err = slot_alloc(ret);
                 if (err_is_fail(err)) {
                     err = err_push(err, LIB_ERR_SLOT_ALLOC);
                     break;
                 }
-                err = slot_free(cap);
-                if (err_is_fail(err)) {
-                    err = err_push(err, LIB_ERR_SLOT_FREE);
-                    break;
-                }
         } while (0);
         ram_set_affinity(minbase, maxlimit);
         if (err_is_fail(err)) {
             return err;
         }
+    } else {
+        err = slot_alloc(ret);
+        if (err_is_fail(err)) {
+            return err;
+        }
     }
 
     assert(ret != NULL);
index f496505..d35b79d 100644 (file)
  */
 errval_t oct_get_capability(const char *key, struct capref *retcap)
 {
-    errval_t reterr;
+    errval_t err, reterr;
     struct octopus_thc_client_binding_t *cl = oct_get_thc_client();
 
-    errval_t err = cl->call_seq.get_cap(cl, key, retcap, &reterr);
+    err = slot_alloc(retcap);
+    if (err_is_fail(err)) {
+        return err;
+    }
+    err = cl->call_seq.get_cap(cl, key, retcap, &reterr);
     if(err_is_fail(err)) {
         return err;
     }
index b002617..cc28563 100644 (file)
@@ -858,6 +858,10 @@ static errval_t buffer_cache_connect(const char *bcache_name)
     }
 
     // Receive bulk transport cap from bcached
+    err = slot_alloc(&client->cache_memory);
+    if(err_is_fail(err)) {
+        USER_PANIC_ERR(err, "slot_alloc for new_client");
+    }
     err = client->rpc.vtbl.new_client(&client->rpc, &client->cache_memory);
     if(err_is_fail(err)) {
         USER_PANIC_ERR(err, "new_client");
index 7a39646..bd36996 100644 (file)
@@ -672,7 +672,7 @@ rx_handler arch ifn typedefs msgdefs msgs =
         C.SBlank,
 
         C.SComment "allocate a new receive slot if needed",
-        C.If (C.Unary C.Not $ C.Call "capref_is_null" [C.Variable "cap"])
+        C.If (need_slot_alloc "cap")
             [C.Ex $ C.Assignment errvar $
                 C.Call "lmp_chan_alloc_recv_slot" [chanaddr],
              C.If (C.Call "err_is_fail" [errvar])
@@ -721,6 +721,11 @@ rx_handler arch ifn typedefs msgdefs msgs =
         rx_msgfrag_field = C.DerefField bindvar "rx_msg_fragment"
         binding_incoming_token = C.DerefField bindvar "incoming_token"
 
+        capref_is_null c = C.Call "capref_is_null" [C.Variable c]
+        in_rpc = (C.Call "thread_get_rpc_in_progress" [])
+        need_slot_alloc c = C.Binary C.And (C.Unary C.Not (capref_is_null c))
+                                           (C.Unary C.Not in_rpc)
+
         call_cases = [C.Case (C.Variable $ msg_enum_elem_name ifn mn) (call_msgnum_case msgdef msg)
                             | (msgdef, msg@(LMPMsgSpec mn _)) <- zip msgdefs msgs]
 
@@ -762,7 +767,19 @@ rx_handler arch ifn typedefs msgdefs msgs =
             C.StmtList $ concat [store_arg_frags arch ifn mn msgwords word 0 afl
                                  | (afl, word) <- zip wl [0..]],
             case cap of
-                Just (CapFieldTransfer _ af) -> C.Ex $ C.Assignment (argfield_expr RX mn af) (C.Variable "cap")
+                Just (CapFieldTransfer _ af) -> C.StmtList [
+                      C.SComment "Updating recv slot: alloc if provided capref null, set otherwise",
+                      C.If (C.Binary C.And in_rpc 
+                        (C.Unary C.Not (C.Call "capref_is_null" [(argfield_expr RX mn af)])))
+                      [
+                          C.Ex $ C.Call "lmp_chan_set_recv_slot"
+                                    [chanaddr, (argfield_expr RX mn af)]
+                      ] [
+                          C.Ex $ C.Call "lmp_chan_rpc_without_allocated_slot" []
+                      ],
+                      C.SComment "Store received cap in provided capref",
+                      C.Ex $ C.Assignment (argfield_expr RX mn af) (C.Variable "cap")
+                     ]
                 Nothing -> C.StmtList [],
             C.SBlank,
 
index 6020498..7330430 100644 (file)
@@ -154,6 +154,9 @@ rpc_fn ifn typedefs msg@(RPC n args _) =
         C.Ex $ C.Call "assert" [C.Binary C.Equals async_err_var (C.Variable "SYS_ERR_OK")],
         C.Ex $ C.Call "thread_set_rpc_in_progress" [C.Variable "true"],
         C.SBlank,
+        C.SComment "set provided caprefs on underlying binding",
+        binding_save_rx_slots,
+        C.SBlank,
         C.SComment "call send function",
         C.Ex $ C.Assignment binding_error (C.Variable "SYS_ERR_OK"),
         C.Ex $ C.Call "thread_set_outgoing_token" [C.Call "thread_set_token" [message_chanstate]],
@@ -190,6 +193,12 @@ rpc_fn ifn typedefs msg@(RPC n args _) =
         mkargs (Arg _ (StringArray an _)) = [an]
         mkargs (Arg _ (DynamicArray an al _)) = [an, al]
         (txargs, rxargs) = partition_rpc_args args
+        is_cap_arg (Arg (Builtin t) _) = t == Cap || t == GiveAwayCap
+        is_cap_arg (Arg _ _) = False
+        rx_cap_args = filter is_cap_arg rxargs
+        binding_save_rx_slot (Arg tr (Name an)) = C.Ex $
+            C.Assignment (rpc_rx_union_elem n an) (C.DerefPtr $ C.Variable an)
+        binding_save_rx_slots = C.StmtList [ binding_save_rx_slot c | c <- rx_cap_args ]
         token_name = "token"
         outgoing_token = bindvar `C.DerefField` "outgoing_token"
         receiving_chanstate = C.CallInd (bindvar `C.DerefField` "get_receiving_chanstate") [bindvar]
index 29bf355..f52e3e5 100644 (file)
@@ -50,6 +50,10 @@ static errval_t init_allocators(void)
     size_t bootinfo_size;
     struct bootinfo *bootinfo;
 
+    err = slot_alloc(&bootinfo_frame);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "slot_alloc for monitor->get_bootinfo");
+    }
     msgerr = cl->vtbl.get_bootinfo(cl, &err, &bootinfo_frame, &bootinfo_size);
     if (err_is_fail(msgerr) || err_is_fail(err)) {
         USER_PANIC_ERR(err_is_fail(msgerr) ? msgerr : err, "failed in get_bootinfo");
@@ -88,6 +92,10 @@ static errval_t init_allocators(void)
 
     errval_t error_code;
     struct capref requested_caps;
+    err = slot_alloc(&requested_caps);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "slot_alloc for monitor->get_phyaddr_cap");
+    }
     err = cl->vtbl.get_phyaddr_cap(cl, &requested_caps, &error_code);
     assert(err_is_ok(err) && err_is_ok(error_code));
     physical_caps = requested_caps;
index b956a43..0f652e0 100644 (file)
@@ -91,6 +91,10 @@ static errval_t init_allocators(void)
     size_t bootinfo_size;
     struct bootinfo *bootinfo;
 
+    err = slot_alloc(&bootinfo_frame);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "slot_alloc for monitor->get_bootinfo");
+    }
     msgerr = cl->vtbl.get_bootinfo(cl, &err, &bootinfo_frame, &bootinfo_size);
     if (err_is_fail(msgerr) || err_is_fail(err)) {
         USER_PANIC_ERR(err_is_fail(msgerr) ? msgerr : err, "failed in get_bootinfo");
@@ -125,6 +129,10 @@ static errval_t init_allocators(void)
     // Request I/O Cap
     struct capref requested_caps;
     errval_t error_code;
+    err = slot_alloc(&requested_caps);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "slot_alloc for monitor->get_io_cap");
+    }
     err = cl->vtbl.get_io_cap(cl, &requested_caps, &error_code);
     assert(err_is_ok(err) && err_is_ok(error_code));
     // Copy into correct slot
@@ -139,6 +147,10 @@ static errval_t init_allocators(void)
 
     // Here we get a cnode cap, so we need to put it somewhere in the root cnode
     // As we already have a reserved slot for a phyaddr caps cnode, we put it there
+    err = slot_alloc(&requested_caps);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "slot_alloc for monitor->get_phyaddr_cap");
+    }
     err = cl->vtbl.get_phyaddr_cap(cl, &requested_caps, &error_code);
     assert(err_is_ok(err) && err_is_ok(error_code));
     physical_caps = requested_caps;
index 85a7f1b..79e4119 100644 (file)
@@ -54,8 +54,13 @@ static void setup_monitor_messaging(void)
 
 static void load_ipi_cap(void)
 {
+    errval_t err;
     struct monitor_blocking_rpc_client *mc = get_monitor_blocking_rpc_client();
-    errval_t err = mc->vtbl.get_ipi_cap(mc, &ipi_cap);
+    err = slot_alloc(&ipi_cap);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "slot_alloc for monitor->get_ipi_cap failed");
+    }
+    err = mc->vtbl.get_ipi_cap(mc, &ipi_cap);
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "get_ipi_cap failed.");
     }
index 11d7730..bb94d6e 100644 (file)
@@ -192,9 +192,13 @@ int start_aps_x86_64_start(uint8_t core_id, genvaddr_t entry)
 
 #else
     struct acpi_rpc_client* acl = get_acpi_rpc_client();
+    err = slot_alloc(&bootcap);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "slot_alloc for mm_realloc_range_proxy");
+    }
     errval_t error_code;
     err = acl->vtbl.mm_realloc_range_proxy(acl, 16, 0x0,
-                                                    &bootcap, &error_code);
+                                           &bootcap, &error_code);
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "mm_alloc_range_proxy failed.");
     }
@@ -307,8 +311,13 @@ int start_aps_x86_32_start(uint8_t core_id, genvaddr_t entry)
 
     struct capref bootcap;
     struct acpi_rpc_client* acl = get_acpi_rpc_client();
-    errval_t error_code;
-    errval_t err = acl->vtbl.mm_realloc_range_proxy(acl, 16, 0x0,
+    errval_t err, error_code;
+
+    err = slot_alloc(&bootcap);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "slot_alloc for mm_alloc_range_proxy");
+    }
+    err = acl->vtbl.mm_realloc_range_proxy(acl, 16, 0x0,
                                                     &bootcap, &error_code);
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "mm_alloc_range_proxy failed.");
index cfa1909..d1dcc43 100644 (file)
@@ -85,6 +85,8 @@ errval_t init_cap_manager(void)
     assert(cl != NULL);
 
     struct capref requested_cap;
+    err = slot_alloc(&requested_cap);
+    assert(err_is_ok(err));
     err = cl->vtbl.get_io_cap(cl, &requested_cap, &error_code);
     assert(err_is_ok(err) && err_is_ok(error_code));
 
index 016d7a1..6eebca9 100644 (file)
@@ -182,6 +182,8 @@ static errval_t alloc_device_bar(uint8_t idx,
         /*err = mm_alloc_range(&pci_mm_physaddr, bits, base + i * framesize,
          base + (i + 1) * framesize, &c->phys_cap[i], NULL);*/
         errval_t error_code;
+        err = slot_alloc(&c->phys_cap[i]);
+        assert(err_is_ok(err));
         err = acl->vtbl.mm_alloc_range_proxy(acl, bits, base + i * framesize,
                                              base + (i + 1) * framesize,
                                              &c->phys_cap[i], &error_code);
index da3b6b6..737dad0 100644 (file)
@@ -43,6 +43,10 @@ errval_t pcie_setup_confspace(void) {
         struct capref pcie_cap;
         struct acpi_rpc_client* acl = get_acpi_rpc_client();
         errval_t error_code;
+        err = slot_alloc(&pcie_cap);
+        if (err_is_fail(err)) {
+            return err;
+        }
         err = acl->vtbl.mm_alloc_range_proxy(acl, region_bits, address,
                 address + (1UL << region_bits), &pcie_cap, &error_code);
         if (err_is_fail(err)) {
index 38338db..ce7909f 100644 (file)
@@ -42,6 +42,8 @@ static errval_t init_io_ports(void)
     // Request I/O Cap
     struct capref requested_caps;
     errval_t error_code;
+    err = slot_alloc(&requested_caps);
+    assert(err_is_ok(err));
     err = cl->vtbl.get_io_cap(cl, &requested_caps, &error_code);
     assert(err_is_ok(err) && err_is_ok(error_code));
 
index e308dd4..a60061b 100644 (file)
@@ -442,6 +442,10 @@ static errval_t map_bootinfo(struct bootinfo **bootinfo)
     struct capref bootinfo_frame;
     size_t bootinfo_size;
 
+    err = slot_alloc(&bootinfo_frame);
+    if (err_is_fail(err)) {
+        return err;
+    }
     msgerr = cl->vtbl.get_bootinfo(cl, &err, &bootinfo_frame, &bootinfo_size);
     if (err_is_fail(msgerr)) {
         err = msgerr;
index 39bddce..132091c 100644 (file)
@@ -103,6 +103,10 @@ static errval_t spawn(char *path, char *const argv[], char *argbuf,
     /* request connection from monitor */
     struct monitor_blocking_rpc_client *mrpc = get_monitor_blocking_rpc_client();
     struct capref monep;
+    err = slot_alloc(&monep);
+    if (err_is_fail(err)) {
+        return err_push(err, SPAWN_ERR_MONEP_SLOT_ALLOC);
+    }
     err = mrpc->vtbl.alloc_monitor_ep(mrpc, &msgerr, &monep);
     if (err_is_fail(err)) {
         return err_push(err, SPAWN_ERR_MONITOR_CLIENT);