Extract a through-monitor-only cap_identify call from debug_cap_identify.
authorRazvan Damachi <razvan.damachi@gmail.com>
Mon, 26 Jun 2017 11:58:56 +0000 (13:58 +0200)
committerSimon Gerber <simon.gerber@inf.ethz.ch>
Thu, 31 Aug 2017 14:35:08 +0000 (16:35 +0200)
The function debug_cap_identify in debug.c used to try to identify the given
capref by first invoking the kernel, then performing an RPC with the monitor,
if the kernel invocation failed. The kernel invocation was there for domains
that hold the cap_kernel, which is necessary for the invocation to succeed.
Therefore, having the invocation there for domains which do not hold cap_kernel
is redundant, incurring unnecessary extra work.

A monitor_cap_identify_remote function is now part of monitor_client.c, through
which callers can identify caprefs through the monitor directly. The old
debug_cap_identify function in debug.c now resorts to this new function if the
kernel invocation fails.

Moreover, userspace apps such as the process manager or spawnd need to identify
caps involved in their RPCs (e.g. domain caps), however they do not hold the
cap_kernel reference. They can thus now use the new function to query the
monitor directly, without attempting to drop in the local kernel first.

Signed-off-by: Razvan Damachi <razvan.damachi@gmail.com>

include/barrelfish/monitor_client.h
lib/barrelfish/debug.c
lib/barrelfish/domain.c
lib/barrelfish/monitor_client.c

index e03d7f1..c30e66f 100644 (file)
@@ -49,6 +49,8 @@ errval_t monitor_cap_set_remote(struct capref cap, bool remote);
 
 errval_t monitor_debug_print_cababilities(void);
 
+errval_t monitor_cap_identify_remote(struct capref cap, struct capability *ret);
+
 __END_DECLS
 
 #endif // BARRELFISH_MONITOR_CLIENT_H
index 3c42017..382194f 100644 (file)
@@ -17,9 +17,9 @@
 #include <barrelfish/barrelfish.h>
 #include <barrelfish/caddr.h>
 #include <barrelfish/debug.h>
+#include <barrelfish/monitor_client.h>
 #include <barrelfish/sys_debug.h>
 #include <barrelfish/dispatch.h>
-#include <if/monitor_blocking_defs.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
@@ -68,41 +68,19 @@ invoke_kernel_identify_cap(capaddr_t cap, int level, struct capability *out)
 
 errval_t debug_cap_identify(struct capref cap, struct capability *ret)
 {
-    errval_t err, msgerr;
-
     if (get_cap_addr(cap) == 0) {
         return SYS_ERR_CAP_NOT_FOUND;
     }
 
     uint8_t level = get_cap_level(cap);
     capaddr_t caddr = get_cap_addr(cap);
-    err = invoke_kernel_identify_cap(caddr, level, ret);
+    errval_t err = invoke_kernel_identify_cap(caddr, level, ret);
     if (err_is_ok(err)) {
         // we have kernel cap, return result;
         return SYS_ERR_OK;
     }
 
-    // Direct invocation failed, try via monitor
-    union {
-        monitor_blocking_caprep_t caprep;
-        struct capability capability;
-    } u;
-
-    struct monitor_blocking_binding *r = get_monitor_blocking_binding();
-    if (!r) {
-        return LIB_ERR_MONITOR_RPC_NULL;
-    }
-    err = r->rpc_tx_vtbl.cap_identify(r, cap, &msgerr, &u.caprep);
-    if (err_is_fail(err)){
-        return err;
-    } else if (err_is_fail(msgerr)) {
-        return msgerr;
-    }
-
-    assert(ret != NULL);
-    *ret = u.capability;
-
-    return msgerr;
+    return monitor_cap_identify_remote(cap, ret);
 }
 
 /**
index 4e90933..7d7c690 100644 (file)
@@ -23,6 +23,7 @@
 #include <barrelfish/barrelfish.h>
 #include <barrelfish/curdispatcher_arch.h>
 #include <barrelfish/dispatcher_arch.h>
+#include <barrelfish/monitor_client.h>
 #include <barrelfish/waitset_chan.h>
 #include <barrelfish_kpi/domain_params.h>
 #include <arch/registers.h>
@@ -1432,7 +1433,7 @@ errval_t domain_cap_hash(struct capref domain_cap, uint64_t *ret_hash)
     assert(ret_hash != NULL);
 
     struct capability ret_cap;
-    errval_t err = debug_cap_identify(domain_cap, &ret_cap);
+    errval_t err = monitor_cap_identify_remote(domain_cap, &ret_cap);
     if (err_is_fail(err)) {
         return err_push(err, PROC_MGMT_ERR_DOMAIN_CAP_HASH);
     }
index eb68424..dc9d15e 100644 (file)
@@ -410,3 +410,32 @@ errval_t monitor_debug_print_cababilities(void)
 
     return err;
 }
+
+/**
+ * \brief Ask the monitor to remotely identify the given cap.
+ */
+errval_t monitor_cap_identify_remote(struct capref cap, struct capability *ret)
+{
+    errval_t err, msgerr;
+
+    union {
+        monitor_blocking_caprep_t caprep;
+        struct capability capability;
+    } u;
+
+    struct monitor_blocking_binding *r = get_monitor_blocking_binding();
+    if (!r) {
+        return LIB_ERR_MONITOR_RPC_NULL;
+    }
+    err = r->rpc_tx_vtbl.cap_identify(r, cap, &msgerr, &u.caprep);
+    if (err_is_fail(err)){
+        return err;
+    } else if (err_is_fail(msgerr)) {
+        return msgerr;
+    }
+
+    assert(ret != NULL);
+    *ret = u.capability;
+
+    return msgerr;
+}
\ No newline at end of file