Added "retrieve" operation for revoke.
authorMark Nevill <nevillm@ethz.ch>
Tue, 12 Jun 2012 12:18:46 +0000 (14:18 +0200)
committerSimon Gerber <simon.gerber@inf.ethz.ch>
Thu, 18 Jul 2013 12:58:35 +0000 (14:58 +0200)
if/intermon.if
usr/monitor/Hakefile
usr/monitor/capops/capsend.c
usr/monitor/capops/init.c
usr/monitor/capops/internal.h
usr/monitor/capops/move.c
usr/monitor/capops/retrieve.c [new file with mode: 0644]
usr/monitor/include/capops.h
usr/monitor/include/capsend.h

index 3689079..d0eb2fe 100644 (file)
@@ -153,6 +153,8 @@ interface intermon "The Interface between monitors" {
 
     message capops_move_request(caprep cap, uint8 relations, capop_st st);
     message capops_move_result(errval status, capop_st st);
+    message capops_retrieve_request(caprep cap, capop_st st);
+    message capops_retrieve_result(errval status, uint8 relations, capop_st st);
 
     message capops_delete_remote(caprep cap, capop_st st);
     message capops_delete_remote_result(errval status, capop_st st);
index 30571ea..c7b31d2 100644 (file)
@@ -32,8 +32,9 @@
                      "rcap_db_common.c", "resource_ctrl.c", "timing.c",
                      "send_cap.c", rcap_db, "capops/capsend.c",
                      "capops/capqueue.c", "capops/caplock.c", "capops/copy.c",
-                     "capops/move.c", "capops/delete.c", "capops/revoke.c",
-                     "capops/retype.c", "capops/init.c", "capops/magic.c" ]
+                     "capops/move.c", "capops/retrieve.c", "capops/delete.c",
+                     "capops/revoke.c", "capops/retype.c", "capops/init.c",
+                     "capops/magic.c" ]
 
      arch_srcs "x86_32"  = [ "arch/x86/boot.c", "arch/x86/inter.c", "arch/x86/monitor_server.c", "arch/x86/notify_ipi.c" ]
      arch_srcs "x86_64"  = [ "arch/x86/boot.c", "arch/x86/inter.c", "arch/x86/monitor_server.c", "arch/x86/notify_ipi.c" ]
index 8a0920a..349a5e5 100644 (file)
@@ -486,11 +486,12 @@ update_owner_broadcast_send_cont(struct intermon_binding *b, intermon_caprep_t *
 }
 
 errval_t
-capsend_update_owner(struct capref capref, struct event_closure completion_continuation)
+capsend_update_owner(struct domcapref capref, struct event_closure completion_continuation)
 {
     errval_t err;
     struct capability cap;
-    err = monitor_cap_identify(capref, &cap);
+    err = monitor_domains_cap_identify(capref.croot, capref.cptr, capref.bits,
+                                       &cap);
     if (err_is_fail(err)) {
         return err;
     }
index 16b7e0f..c16362e 100644 (file)
@@ -9,6 +9,8 @@ errval_t capops_intermon_init(struct intermon_binding *b)
     b->rx_vtbl.capops_recv_copy_result        = recv_copy_result__rx;
     b->rx_vtbl.capops_move_request            = move_request__rx_handler;
     b->rx_vtbl.capops_move_result             = move_result__rx_handler;
+    b->rx_vtbl.capops_retrieve_request        = retrieve_request__rx;
+    b->rx_vtbl.capops_retrieve_result         = retrieve_result__rx;
     b->rx_vtbl.capops_delete_remote           = delete_remote__rx;
     b->rx_vtbl.capops_delete_remote_result    = delete_remote_result__rx;
     b->rx_vtbl.capops_request_revoke          = request_revoke__rx_handler;
index e91cad5..9eeb7c2 100644 (file)
 #ifndef CAPOPS_INTERNAL_H
 #define CAPOPS_INTERNAL_H
 
+#include <errors/errno.h>
+#include <barrelfish/waitset.h>
+#include <capops.h>
+
 typedef void (*gen_result_cont_fn)(errval_t, void*);
 struct result_closure {
     gen_result_cont_fn handler;
@@ -81,6 +85,12 @@ void move_request__rx_handler(struct intermon_binding *b,
                               genvaddr_t st);
 void move_result__rx_handler(struct intermon_binding *b, errval_t status,
                              genvaddr_t st);
+void retrieve_request__rx(struct intermon_binding *b,
+                          intermon_caprep_t caprep,
+                          genvaddr_t st);
+void retrieve_result__rx(struct intermon_binding *b,
+                         errval_t status, uint8_t relations,
+                         genvaddr_t st);
 void retype_request__rx(struct intermon_binding *b, intermon_caprep_t srcrep,
                         int desttype, uint32_t destbits, genvaddr_t st);
 void retype_response__rx(struct intermon_binding *b, errval_t status,
index 3c2d347..6ea434d 100644 (file)
@@ -193,7 +193,7 @@ move_request__rx_handler(struct intermon_binding *b, intermon_caprep_t caprep, u
         goto reset_owner;
     }
 
-    err = capsend_update_owner(*capref, MKCONT(free_owner_recv_cap, capref));
+    err = capsend_update_owner(domcapref, MKCONT(free_owner_recv_cap, capref));
     if (err_is_fail(err)) {
         goto reset_owner;
     }
diff --git a/usr/monitor/capops/retrieve.c b/usr/monitor/capops/retrieve.c
new file mode 100644 (file)
index 0000000..1952e32
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2012 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <barrelfish/barrelfish.h>
+#include <if/intermon_defs.h>
+#include "monitor.h"
+#include "capops.h"
+#include "capsend.h"
+#include "magic.h"
+#include "caplock.h"
+#include "internal.h"
+#include "dom_invocations.h"
+#include "monitor_invocations.h"
+
+struct retrieve_rpc_st {
+    struct intermon_msg_queue_elem iqn;
+    struct domcapref cap;
+    struct capability rawcap;
+    move_result_handler_t result_handler;
+    void *st;
+    coreid_t prev_owner;
+};
+
+struct retrieve_response_st {
+    struct intermon_msg_queue_elem iqn;
+    errval_t status;
+    uint8_t relations;
+    genvaddr_t st;
+    coreid_t from;
+};
+
+static void retrieve_owner__enq(struct retrieve_rpc_st *st);
+static void retrieve_owner__send(struct intermon_binding *b,
+                                 struct intermon_msg_queue_elem *e);
+static void retrieve_result__enq(errval_t status,
+                                 struct retrieve_response_st *st);
+static void retrieve_result__send(struct intermon_binding *b,
+                                  struct intermon_msg_queue_elem *e);
+static void retrieve_ownership_update__fin(void *st);
+
+void
+capops_retrieve(struct domcapref cap,
+                move_result_handler_t result_handler,
+                void *st)
+{
+    errval_t err;
+
+    distcap_state_t state;
+    err = dom_cnode_get_state(cap, &state);
+    GOTO_IF_ERR(err, report_error);
+    if (distcap_state_is_busy(state)) {
+        err = MON_ERR_REMOTE_CAP_RETRY;
+    }
+    if (distcap_state_is_foreign(state)) {
+        err = MON_ERR_CAP_FOREIGN;
+    }
+    GOTO_IF_ERR(err, report_error);
+
+    err = monitor_lock_cap(cap.croot, cap.cptr, cap.bits);
+    GOTO_IF_ERR(err, report_error);
+
+    struct retrieve_rpc_st *rst = NULL;
+    err = calloce(1, sizeof(*rst), &rst);
+    GOTO_IF_ERR(err, unlock_cap);
+
+    rst->cap = cap;
+    rst->result_handler = result_handler;
+    rst->st = st;
+
+    err = monitor_get_cap_owner(cap.croot, cap.cptr, cap.bits, &rst->prev_owner);
+    GOTO_IF_ERR(err, free_st);
+
+    if (rst->prev_owner == my_core_id) {
+        err = SYS_ERR_OK;
+        goto free_st;
+    }
+
+    retrieve_owner__enq(rst);
+
+    return;
+
+free_st:
+    free(rst);
+
+unlock_cap:
+    caplock_unlock(cap);
+
+report_error:
+    result_handler(err, st);
+}
+
+static void
+retrieve_ownership__rx(errval_t status, struct retrieve_rpc_st *st)
+{
+    caplock_unlock(st->cap);
+    st->result_handler(status, st->st);
+    free(st);
+}
+
+static void
+retrieve_owner__enq(struct retrieve_rpc_st *st)
+{
+    errval_t err;
+
+    st->iqn.cont = retrieve_owner__send;
+    err = capsend_owner(st->cap, (struct msg_queue_elem*)st);
+    if (err_is_fail(err)) {
+        retrieve_ownership__rx(err, st);
+    }
+}
+
+static void
+retrieve_owner__send(struct intermon_binding *b,
+                     struct intermon_msg_queue_elem *e)
+{
+    errval_t err;
+    struct retrieve_rpc_st *st = (struct retrieve_rpc_st*)e;
+    intermon_caprep_t caprep;
+
+    err = monitor_set_cap_owner(st->cap.croot, st->cap.cptr, st->cap.bits,
+                                my_core_id);
+    GOTO_IF_ERR(err, report_error);
+
+    capability_to_caprep(&st->rawcap, &caprep);
+    err = intermon_capops_retrieve_request__tx(b, NOP_CONT, caprep, (genvaddr_t)st);
+    GOTO_IF_ERR(err, report_error);
+
+    return;
+
+report_error:
+    retrieve_ownership__rx(err, st);
+}
+
+void
+retrieve_request__rx(struct intermon_binding *b,
+                     intermon_caprep_t caprep,
+                     genvaddr_t st)
+{
+    errval_t err, err2;
+    struct intermon_state *inter_st = (struct intermon_state*)b->st;
+
+    struct retrieve_response_st *rst;
+    err = calloce(1, sizeof(*rst), &rst);
+    PANIC_IF_ERR(err, "allocating retrieve respones state");
+    rst->st = st;
+    rst->from = inter_st->core_id;
+
+    struct capability rawcap;
+    caprep_to_capability(&caprep, &rawcap);
+
+    struct capref cap;
+    err = slot_alloc(&cap);
+    GOTO_IF_ERR(err, respond_err);
+
+    err = monitor_copy_if_exists(&rawcap, cap);
+    GOTO_IF_ERR(err, free_slot);
+
+    distcap_state_t state;
+    err = dom_cnode_get_state(get_cap_domref(cap), &state);
+    GOTO_IF_ERR(err, delete_cap);
+
+    if (distcap_state_is_busy(state)) {
+        err = MON_ERR_REMOTE_CAP_RETRY;
+        goto delete_cap;
+    }
+    if (distcap_state_is_foreign(state)) {
+        err = MON_ERR_CAP_FOREIGN;
+        goto delete_cap;
+    }
+
+    uint8_t relations, remote_relations;
+    err = monitor_cap_has_relations(cap, 0xFF, &relations);
+    GOTO_IF_ERR(err, delete_cap);
+
+    err = monitor_remote_relations(cap, 0, 0, &remote_relations);
+    GOTO_IF_ERR(err, delete_cap);
+
+    rst->relations = relations | remote_relations | RRELS_COPY_BIT;
+
+    err = monitor_set_cap_owner(cap_root, get_cap_addr(cap),
+                                get_cap_valid_bits(cap),
+                                rst->from);
+
+delete_cap:
+    err2 = cap_delete(cap);
+    DEBUG_IF_ERR(err2, "while deleting temp cap for retrieve");
+
+free_slot:
+    err2 = slot_free(cap);
+    DEBUG_IF_ERR(err2, "freeing temp cap slot for retrieve");
+
+respond_err:
+    retrieve_result__enq(err, rst);
+}
+
+static void
+retrieve_result__enq(errval_t status, struct retrieve_response_st *st)
+{
+    errval_t err;
+    st->status = status;
+    st->iqn.cont = retrieve_result__send;
+
+    err = capsend_target(st->from, (struct msg_queue_elem*)st);
+    PANIC_IF_ERR(err, "enqueing retrieve result");
+}
+
+static void
+retrieve_result__send(struct intermon_binding *b,
+                      struct intermon_msg_queue_elem *e)
+{
+    errval_t err;
+    struct retrieve_response_st *st = (struct retrieve_response_st*)e;
+
+    err = intermon_capops_retrieve_result__tx(b, NOP_CONT, st->status,
+                                              st->relations, st->st);
+    PANIC_IF_ERR(err, "sending retrieve result");
+    free(st);
+}
+
+void
+retrieve_result__rx(struct intermon_binding *b, errval_t status,
+                    uint8_t relations, genvaddr_t st)
+{
+    errval_t err;
+    struct retrieve_rpc_st *rst = (struct retrieve_rpc_st*)st;
+
+    if (err_is_fail(status)) {
+        err = status;
+        goto report_error;
+    }
+
+    err = monitor_domcap_remote_relations(rst->cap.croot, rst->cap.cptr,
+                                          rst->cap.bits, relations, 0xFF,
+                                          NULL);
+    PANIC_IF_ERR(err, "setting rrels for retrieved cap");
+
+    struct event_closure updated_cont
+        = MKCONT(retrieve_ownership_update__fin, rst);
+    err = capsend_update_owner(rst->cap, updated_cont);
+    PANIC_IF_ERR(err, "updating retrieve ownership");
+
+report_error:
+    retrieve_ownership__rx(err, rst);
+}
+
+static void
+retrieve_ownership_update__fin(void *st)
+{
+    struct retrieve_rpc_st *rst = (struct retrieve_rpc_st*)st;
+
+    retrieve_ownership__rx(SYS_ERR_OK, rst);
+}
index 033f430..8e7c566 100644 (file)
@@ -23,6 +23,9 @@ typedef void (*move_result_handler_t)(errval_t, void*);
 errval_t capops_move(struct domcapref cap, coreid_t dest,
                      move_result_handler_t result_handler, void *st);
 
+void capops_retrieve(struct domcapref cap,
+                     move_result_handler_t result_handler, void *st);
+
 typedef void (*delete_result_handler_t)(errval_t, void*);
 void capops_delete(struct domcapref cap,
                    delete_result_handler_t result_handler, void *st);
index d492b52..73041c4 100644 (file)
@@ -36,7 +36,7 @@ errval_t capsend_target(coreid_t dest, struct msg_queue_elem *queue_elem);
 
 errval_t capsend_owner(struct domcapref capref, struct msg_queue_elem *queue_elem);
 
-errval_t capsend_update_owner(struct capref capref, struct event_closure continuation);
+errval_t capsend_update_owner(struct domcapref capref, struct event_closure continuation);
 
 errval_t capsend_copies(struct capability *cap, capsend_send_fn send_fn, struct capsend_mc_st *mc_st);