Make debug_my_cspace work with new CSpace layout
authorLukas Humbel <lukas.humbel@inf.ethz.ch>
Tue, 1 Nov 2016 17:13:58 +0000 (18:13 +0100)
committerLukas Humbel <lukas.humbel@inf.ethz.ch>
Tue, 1 Nov 2016 17:44:34 +0000 (18:44 +0100)
Signed-off-by: Lukas Humbel <lukas.humbel@inf.ethz.ch>

include/barrelfish/invocations.h
include/barrelfish_kpi/capabilities.h
kernel/arch/armv7/syscall.c
kernel/arch/armv8/syscall.c
kernel/arch/x86_64/syscall.c
kernel/include/syscall.h
kernel/syscall.c
lib/barrelfish/debug.c

index b35b320..3186204 100644 (file)
@@ -156,6 +156,27 @@ static inline errval_t invoke_cnode_get_state(struct capref root, capaddr_t cap,
     return sysret.error;
 }
 
+
+/**
+ * \brief Get the size of a L1 CNode in bytes.
+ *
+ * \param root Size of this L1 CNode will be returned
+ * \param ret  Result will be stored here in bytes.
+ *
+ * \return Error code
+ */
+static inline errval_t invoke_cnode_get_size(struct capref root, size_t * ret)
+{
+    struct sysret sys_ret =  cap_invoke1(root, CNodeCmd_GetSize);
+    if(err_is_ok(sys_ret.error)){
+        *ret = sys_ret.value;
+    } else {
+        *ret = 0;
+    }
+
+    return sys_ret.error;
+}
+
 static inline errval_t invoke_cnode_resize(struct capref root, capaddr_t new_cptr,
                                            capaddr_t retcn_ptr, cslot_t retslot)
 {
index 5a5e43e..9d2490e 100644 (file)
@@ -361,6 +361,7 @@ enum cnode_cmd {
     CNodeCmd_Revoke,    ///< Revoke capability
     CNodeCmd_Create,    ///< Create capability
     CNodeCmd_GetState,  ///< Get distcap state for capability
+    CNodeCmd_GetSize,   ///< Get Size of CNode, only applicable for L1 Cnode
     CNodeCmd_Resize,    ///< Resize CNode, only applicable for L1 Cnode
 };
 
index d380b8d..416d771 100644 (file)
@@ -308,6 +308,19 @@ handle_get_state(
 }
 
 static struct sysret
+handle_get_size(
+    struct capability* root,
+    arch_registers_state_t* context,
+    int argc
+    )
+{
+    assert(2 == argc);
+    return sys_get_size_l1cnode(root);
+}
+
+
+
+static struct sysret
 handle_resize(
     struct capability* root,
     arch_registers_state_t* context,
@@ -960,6 +973,7 @@ static invocation_t invocations[ObjType_Num][CAP_MAX_CMD] = {
         [CNodeCmd_Revoke]   = handle_revoke,
         [CNodeCmd_Create]   = handle_create,
         [CNodeCmd_GetState] = handle_get_state,
+        [CNodeCmd_GetSize]  = handle_get_size,
         [CNodeCmd_Resize]   = handle_resize,
     },
     [ObjType_L2CNode] = {
index 0e1ecc2..2b41a94 100644 (file)
@@ -307,6 +307,17 @@ handle_get_state(
 }
 
 static struct sysret
+handle_get_size(
+    struct capability* root,
+    arch_registers_state_t* context,
+    int argc
+    )
+{
+    assert(2 == argc);
+    return sys_get_size_l1cnode(root);
+}
+
+static struct sysret
 handle_resize(
     struct capability* root,
     arch_registers_state_t* context,
@@ -870,6 +881,7 @@ static invocation_t invocations[ObjType_Num][CAP_MAX_CMD] = {
         [CNodeCmd_Delete] = handle_delete,
         [CNodeCmd_Revoke] = handle_revoke,
         [CNodeCmd_GetState] = handle_get_state,
+        [CNodeCmd_GetSize] = handle_get_size,
         [CNodeCmd_Resize] = handle_resize,
     },
     [ObjType_L2CNode] = {
index 7bca085..699aead 100644 (file)
@@ -222,6 +222,12 @@ static struct sysret handle_get_state(struct capability *root,
     return sys_get_state(root, cptr, level);
 }
 
+static struct sysret handle_get_size(struct capability *root,
+                                      int cmd, uintptr_t *args)
+{
+    return sys_get_size_l1cnode(root);
+}
+
 static struct sysret handle_resize(struct capability *root,
                                    int cmd, uintptr_t *args)
 {
@@ -1167,6 +1173,7 @@ static invocation_handler_t invocations[ObjType_Num][CAP_MAX_CMD] = {
         [CNodeCmd_Delete] = handle_delete,
         [CNodeCmd_Revoke] = handle_revoke,
         [CNodeCmd_GetState] = handle_get_state,
+        [CNodeCmd_GetSize] = handle_get_size,
         [CNodeCmd_Resize] = handle_resize,
     },
     [ObjType_L2CNode] = {
index d82f647..2a86b2b 100644 (file)
@@ -54,6 +54,7 @@ sys_copy_or_mint(struct capability *root, capaddr_t dest_cspace_cptr,
 struct sysret sys_delete(struct capability *root, capaddr_t cptr, uint8_t level);
 struct sysret sys_revoke(struct capability *root, capaddr_t cptr, uint8_t level);
 struct sysret sys_get_state(struct capability *root, capaddr_t cptr, uint8_t level);
+struct sysret sys_get_size_l1cnode(struct capability *root);
 struct sysret sys_resize_l1cnode(struct capability *root, capaddr_t newroot_cptr,
                                  capaddr_t retcn_cptr, cslot_t retslot);
 struct sysret
index 9094540..d7212f6 100644 (file)
@@ -518,6 +518,15 @@ struct sysret sys_get_state(struct capability *root, capaddr_t cptr, uint8_t lev
     return (struct sysret) { .error = SYS_ERR_OK, .value = state };
 }
 
+struct sysret sys_get_size_l1cnode(struct capability *root)
+{
+    assert(root->type == ObjType_L1CNode);
+
+    return (struct sysret) { .error = SYS_ERR_OK,
+        .value = root->u.l1cnode.allocated_bytes};
+}
+
+
 struct sysret sys_resize_l1cnode(struct capability *root, capaddr_t newroot_cptr,
                                  capaddr_t retcn_cptr, cslot_t retslot)
 {
index 837000d..d48c09f 100644 (file)
@@ -410,36 +410,22 @@ int debug_print_cap_at_capref(char *buf, size_t len, struct capref cap)
 }
 
 /**
- * \brief Walk the cspace printing all non-null capabilities
- *
- * \param cnode         cnode to walk
- * \param level         depth in the cspace
- *
- * \bug assumes guards are always zero
+ * \brief Walk and debug print a L2 CNode
  */
-static void walk_cspace(struct cnoderef cnode, uint8_t level)
-{
-    USER_PANIC("walk_cspace NYI for 2-level cspace layout\n");
-#if 0
-    struct capability cap;
+static void walk_cspace_l2(struct capref l2cnode){
     errval_t err;
+    struct capability cap;
+    struct cnoderef cnode = build_cnoderef(l2cnode, 1);
+    
+    debug_printf("  Printing L2 CNode at L1 slot=%d\n", l2cnode.slot);
 
-    struct capref pos = {
-        .cnode = cnode, .slot = 0
-    };
-
-    // If too many bits resolved, return
-    if (pos.cnode.address_bits + pos.cnode.guard_size + pos.cnode.size_bits
-        > CPTR_BITS) {
-        return;
-    }
+    for(int i=0; i<L2_CNODE_SLOTS; i++){
+        struct capref pos = {
+            .cnode = cnode, .slot = i 
+        };
 
-    // Walk through all the slots in the CNode
-    for (pos.slot = 0; pos.slot < (((capaddr_t)1) << cnode.size_bits); pos.slot++) {
         // Get cap data
         err = debug_cap_identify(pos, &cap);
-
-        // If cap type was Null, kernel returns error
         if (err_no(err) == SYS_ERR_IDENTIFY_LOOKUP ||
             err_no(err) == SYS_ERR_CAP_NOT_FOUND ||
             err_no(err) == SYS_ERR_LMP_CAPTRANSFER_SRC_LOOKUP) {
@@ -452,51 +438,63 @@ static void walk_cspace(struct cnoderef cnode, uint8_t level)
         char buf[256];
         size_t prpos = 0;
 
-        // Print the stats for the child slot
-        for(int i = 0; i < level; i++) {
-            prpos += snprintf(&buf[prpos], sizeof(buf) - prpos, "  ");
-            assert(prpos < sizeof(buf));
-        }
-        prpos += snprintf(&buf[prpos], sizeof(buf) - prpos,
-                          "slot %" PRIuCADDR " caddr 0x%" PRIxCADDR " (%u bits) is a ",
-                          pos.slot, get_cap_addr(pos), get_cap_valid_bits(pos));
+        prpos += snprintf(buf, sizeof(buf),
+                          "slot %" PRIuCADDR " caddr 0x%" PRIxCADDR " is a ",
+                          pos.slot, get_cap_addr(pos));
         assert(prpos < sizeof(buf));
         prpos += debug_print_cap(&buf[prpos], sizeof(buf) - prpos, &cap);
         assert(prpos < sizeof(buf));
-        debug_printf("%s\n", buf);
-
-        // If CNode type, descend into it
-        if (cap.type == ObjType_CNode) {
-            struct cnoderef childcn = {
-                .address = get_cap_addr(pos),
-                .address_bits = get_cap_valid_bits(pos),
-                .size_bits = cap.u.cnode.bits,
-                .guard_size = cap.u.cnode.guard_size,
-            };
-            walk_cspace(childcn, level + 1);
-        }
+        debug_printf("    %s\n", buf);
     }
-#endif
 }
 
 /**
  * \brief Dump an arbitrary cspace, given the root
+ * 
+ * \bug Works correct only for own cspace. (to fix this cap_identify must 
+ * be made to work with all caps)
+ * 
  */
 void debug_cspace(struct capref root)
 {
-    struct capability cap;
+    struct capability root_cap;
+    struct capability l2_cap;
 
     /* find out size of root cnode */
-    errval_t err = debug_cap_identify(root, &cap);
+    errval_t err = debug_cap_identify(root, &root_cap);
+    assert(err_is_ok(err));
+    assert(root_cap.type == ObjType_L1CNode);
+
+    size_t c1size = 0;
+    err = invoke_cnode_get_size(root, &c1size);
     assert(err_is_ok(err));
 
-    struct cnoderef cnode = build_cnoderef(root, 0);
-    walk_cspace(cnode, 0);
+    int l1slots = c1size/sizeof(struct capability);
+    debug_printf("Printing L1 CNode (slots=%u)\n", l1slots);
+    for(int slot=0; slot < l1slots; slot++){
+
+        struct cnoderef cnode = build_cnoderef(root, 0);
+        struct capref pos = {
+            .cnode = cnode, .slot = slot
+        };
+        err = debug_cap_identify(pos, &l2_cap);
+
+        // If cap type was Null, kernel returns error
+        if (err_no(err) == SYS_ERR_IDENTIFY_LOOKUP ||
+            err_no(err) == SYS_ERR_CAP_NOT_FOUND ||
+            err_no(err) == SYS_ERR_LMP_CAPTRANSFER_SRC_LOOKUP) {
+            continue;
+        } else if (err_is_fail(err)) {
+            DEBUG_ERR(err, "debug_cap_identify failed");
+            return;
+        }
+        walk_cspace_l2(pos);
+    }
 }
 
 void debug_my_cspace(void)
 {
-    walk_cspace(cnode_root, 0);
+    debug_cspace(cap_root);
 }
 
 int debug_print_capref(char *buf, size_t len, struct capref cap)