Skip to content

Commit

Permalink
feat: add memory range introspection
Browse files Browse the repository at this point in the history
  • Loading branch information
diegonehab committed Oct 24, 2023
1 parent cc52626 commit c1f0190
Show file tree
Hide file tree
Showing 28 changed files with 472 additions and 224 deletions.
12 changes: 12 additions & 0 deletions src/clua-i-virtual-machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,17 @@ static int machine_obj_index_reset_uarch_state(lua_State *L) {
return 0;
}

/// \brief This is the machine:get_memory_ranges() method implementation.
/// \param L Lua state.
static int machine_obj_index_get_memory_ranges(lua_State *L) {
auto &m = clua_check<clua_managed_cm_ptr<cm_machine>>(L, 1);
auto &managed_mrds = clua_push_to(L, clua_managed_cm_ptr<cm_memory_range_descr_array>(nullptr));
TRY_EXECUTE(cm_get_memory_ranges(m.get(), &managed_mrds.get(), err_msg));
clua_push_cm_memory_range_descr_array(L, managed_mrds.get());
managed_mrds.reset();
return 1;
}

/// \brief This is the machine:run_uarch() method implementation.
/// \param L Lua state.
static int machine_obj_index_run_uarch(lua_State *L) {
Expand Down Expand Up @@ -646,6 +657,7 @@ static const auto machine_obj_index = cartesi::clua_make_luaL_Reg_array({
{"read_uarch_halt_flag", machine_obj_index_read_uarch_halt_flag},
{"set_uarch_halt_flag", machine_obj_index_set_uarch_halt_flag},
{"reset_uarch_state", machine_obj_index_reset_uarch_state},
{"get_memory_ranges", machine_obj_index_get_memory_ranges},
});

/// \brief This is the machine __close metamethod implementation.
Expand Down
18 changes: 18 additions & 0 deletions src/clua-machine-util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ void cm_delete(cm_memory_range_config *ptr) {
cm_delete_memory_range_config(ptr);
}

/// \brief Deleter for C api memory range description array
template <>
void cm_delete(cm_memory_range_descr_array *ptr) {
cm_delete_memory_range_descr_array(ptr);
}

static char *copy_lua_str(lua_State *L, int idx) {
const char *lua_str = lua_tostring(L, idx);
auto size = strlen(lua_str) + 1;
Expand Down Expand Up @@ -693,6 +699,18 @@ void clua_push_cm_proof(lua_State *L, const cm_merkle_tree_proof *proof) {
lua_setfield(L, -2, "target_hash"); // proof
}

void clua_push_cm_memory_range_descr_array(lua_State *L, const cm_memory_range_descr_array *mrds) {
lua_newtable(L); // array
for (size_t i = 0; i < mrds->count; ++i) {
const auto &mrd = mrds->entry[i];
lua_newtable(L); // array config
clua_setintegerfield(L, mrd.start, "start", -1); // array config
clua_setintegerfield(L, mrd.length, "length", -1); // array config
clua_setstringfield(L, mrd.description, "description", -1); // array config
lua_rawseti(L, -2, i + 1); // array
}
}

cm_access_log_type clua_check_cm_log_type(lua_State *L, int tabidx) {
luaL_checktype(L, tabidx, LUA_TTABLE);
return cm_access_log_type{opt_boolean_field(L, tabidx, "proofs"), opt_boolean_field(L, tabidx, "annotations")};
Expand Down
9 changes: 9 additions & 0 deletions src/clua-machine-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ void cm_delete(cm_memory_range_config *p);
template <>
void cm_delete(const cm_semantic_version *p);

/// \brief Deleter for C api memory range description array
template <>
void cm_delete(cm_memory_range_descr_array *p);

// clua_managed_cm_ptr is a smart pointer,
// however we don't use all its functionally, therefore we exclude it from code coverage.
// LCOV_EXCL_START
Expand Down Expand Up @@ -175,6 +179,11 @@ void clua_push_cm_hash(lua_State *L, const cm_hash *hash);
/// \param c Machine configuration to be pushed
void clua_push_cm_machine_config(lua_State *L, const cm_machine_config *c);

/// \brief Pushes a C api cm_memory_range_descr_array to the Lua stack
/// \param L Lua state
/// \param mrds Memory range description array to be pushed
void clua_push_cm_memory_range_descr_array(lua_State *L, const cm_memory_range_descr_array *mrds);

#if 0
/// \brief Pushes a cm_machine_runtime_config to the Lua stack
/// \param L Lua state
Expand Down
1 change: 1 addition & 0 deletions src/clua-machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ int clua_machine_init(lua_State *L, int ctxidx) {
clua_createnewtype<clua_managed_cm_ptr<char>>(L, ctxidx);
clua_createnewtype<clua_managed_cm_ptr<unsigned char>>(L, ctxidx);
clua_createnewtype<clua_managed_cm_ptr<cm_memory_range_config>>(L, ctxidx);
clua_createnewtype<clua_managed_cm_ptr<cm_memory_range_descr_array>>(L, ctxidx);
if (!clua_typeexists<machine_class>(L, ctxidx)) {
clua_createtype<machine_class>(L, "cartesi machine class", ctxidx);
clua_setmethods<machine_class>(L, machine_class_index.data(), 0, ctxidx);
Expand Down
12 changes: 12 additions & 0 deletions src/grpc-virtual-machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -952,4 +952,16 @@ uarch_interpreter_break_reason grpc_virtual_machine::do_run_uarch(uint64_t uarch
return uarch_interpreter_break_reason::reached_target_cycle;
}

machine_memory_range_descrs grpc_virtual_machine::do_get_memory_ranges(void) const {
machine_memory_range_descrs mrds;
const Void request;
GetMemoryRangesResponse response;
ClientContext context;
check_status(m_stub->get_stub()->GetMemoryRanges(&context, request, &response));
for (const auto &proto_m: response.memory_range()) {
mrds.push_back(get_proto_memory_range_descr(proto_m));
}
return mrds;
}

} // namespace cartesi
1 change: 1 addition & 0 deletions src/grpc-virtual-machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ class grpc_virtual_machine : public i_virtual_machine {
void do_reset_uarch_state() override;
bool do_read_uarch_halt_flag(void) const override;
uarch_interpreter_break_reason do_run_uarch(uint64_t uarch_cycle_end) override;
machine_memory_range_descrs do_get_memory_ranges(void) const override;

grpc_machine_stub_ptr m_stub;
};
Expand Down
6 changes: 6 additions & 0 deletions src/i-virtual-machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,11 @@ class i_virtual_machine {
return do_run_uarch(uarch_cycle_end);
}

/// \brief Returns a list of descriptions for all PMA entries registered in the machine, sorted by start
virtual machine_memory_range_descrs get_memory_ranges(void) const {
return do_get_memory_ranges();
}

private:
virtual interpreter_break_reason do_run(uint64_t mcycle_end) = 0;
virtual void do_store(const std::string &dir) = 0;
Expand Down Expand Up @@ -760,6 +765,7 @@ class i_virtual_machine {
virtual void do_reset_uarch_state() = 0;
virtual uint64_t do_read_uarch_ram_length(void) const = 0;
virtual uarch_interpreter_break_reason do_run_uarch(uint64_t uarch_cycle_end) = 0;
virtual machine_memory_range_descrs do_get_memory_ranges(void) const = 0;
};

} // namespace cartesi
Expand Down
41 changes: 41 additions & 0 deletions src/json-util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,37 @@ template void ju_get_opt_field<uint64_t>(const nlohmann::json &j, const uint64_t
template void ju_get_opt_field<std::string>(const nlohmann::json &j, const std::string &key, machine_config &value,
const std::string &path);

template <typename K>
void ju_get_opt_field(const nlohmann::json &j, const K &key, machine_memory_range_descr &value,
const std::string &path) {
if (!contains(j, key)) {
return;
}
const auto &jconfig = j[key];
const auto new_path = path + to_string(key) + "/";
ju_get_opt_field(jconfig, "length"s, value.length, new_path);
ju_get_opt_field(jconfig, "start"s, value.start, new_path);
ju_get_opt_field(jconfig, "description"s, value.description, new_path);
}

template void ju_get_opt_field<uint64_t>(const nlohmann::json &j, const uint64_t &key,
machine_memory_range_descr &value, const std::string &path);

template void ju_get_opt_field<std::string>(const nlohmann::json &j, const std::string &key,
machine_memory_range_descr &value, const std::string &path);

template <typename K>
void ju_get_opt_field(const nlohmann::json &j, const K &key, machine_memory_range_descrs &value,
const std::string &path) {
ju_get_opt_vector_like_field(j, key, value, path);
}

template void ju_get_opt_field<uint64_t>(const nlohmann::json &j, const uint64_t &key,
machine_memory_range_descrs &value, const std::string &path);

template void ju_get_opt_field<std::string>(const nlohmann::json &j, const std::string &key,
machine_memory_range_descrs &value, const std::string &path);

void to_json(nlohmann::json &j, const machine::csr &csr) {
j = csr_to_name(csr);
}
Expand Down Expand Up @@ -1224,4 +1255,14 @@ void to_json(nlohmann::json &j, const machine_runtime_config &runtime) {
};
}

void to_json(nlohmann::json &j, const machine_memory_range_descr &mrd) {
j = nlohmann::json{{"length", mrd.length}, {"start", mrd.start}, {"description", mrd.description}};
}

void to_json(nlohmann::json &j, const machine_memory_range_descrs &mrds) {
j = nlohmann::json::array();
std::transform(mrds.cbegin(), mrds.cend(), std::back_inserter(j),
[](const auto &a) -> nlohmann::json { return a; });
}

} // namespace cartesi
29 changes: 29 additions & 0 deletions src/json-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,26 @@ template <typename K>
void ju_get_opt_field(const nlohmann::json &j, const K &key, machine_config &value,
const std::string &path = "params/");

/// \brief Attempts to load a machine_memory_range_descr object from a field in a JSON object
/// \tparam K Key type (explicit extern declarations for uint64_t and std::string are provided)
/// \param j JSON object to load from
/// \param key Key to load value from
/// \param value Object to store value
/// \param path Path to j
template <typename K>
void ju_get_opt_field(const nlohmann::json &j, const K &key, machine_memory_range_descr &value,
const std::string &path = "params/");

/// \brief Attempts to load a machine_memory_range_descrs object from a field in a JSON object
/// \tparam K Key type (explicit extern declarations for uint64_t and std::string are provided)
/// \param j JSON object to load from
/// \param key Key to load value from
/// \param value Object to store value
/// \param path Path to j
template <typename K>
void ju_get_opt_field(const nlohmann::json &j, const K &key, machine_memory_range_descrs &value,
const std::string &path = "params/");

/// \brief Attempts to load an array from a field in a JSON object
/// \tparam K Key type (explicit extern declarations for uint64_t and std::string are provided)
/// \param j JSON object to load from
Expand Down Expand Up @@ -554,6 +574,7 @@ void to_json(nlohmann::json &j, const concurrency_runtime_config &config);
void to_json(nlohmann::json &j, const htif_runtime_config &config);
void to_json(nlohmann::json &j, const machine_runtime_config &runtime);
void to_json(nlohmann::json &j, const machine::csr &csr);
void to_json(nlohmann::json &j, const machine_memory_range_descrs &mrds);

// Extern template declarations
extern template void ju_get_opt_field(const nlohmann::json &j, const std::string &key, std::string &value,
Expand Down Expand Up @@ -692,6 +713,14 @@ extern template void ju_get_opt_field(const nlohmann::json &j, const uint64_t &k
const std::string &base = "params/");
extern template void ju_get_opt_field(const nlohmann::json &j, const std::string &key, machine_config &value,
const std::string &base = "params/");
extern template void ju_get_opt_field(const nlohmann::json &j, const uint64_t &key,
machine_memory_range_descr &value, const std::string &base = "params/");
extern template void ju_get_opt_field(const nlohmann::json &j, const std::string &key,
machine_memory_range_descr &value, const std::string &base = "params/");
extern template void ju_get_opt_field(const nlohmann::json &j, const uint64_t &key,
machine_memory_range_descrs &value, const std::string &base = "params/");
extern template void ju_get_opt_field(const nlohmann::json &j, const std::string &key,
machine_memory_range_descrs &value, const std::string &base = "params/");

} // namespace cartesi

Expand Down
38 changes: 38 additions & 0 deletions src/jsonrpc-discover.json
Original file line number Diff line number Diff line change
Expand Up @@ -1026,6 +1026,19 @@
"type": "boolean"
}
}
},

{
"name": "machine.get_memory_ranges",
"summary": "Returns a list with descriptions for all of the machine's memory ranges",
"params": [],
"result": {
"name": "ranges",
"description": "Array of memory range descriptions",
"schema": {
"$ref": "#/components/schemas/MemoryRangeDescriptionArray"
}
}
}
],

Expand Down Expand Up @@ -1668,7 +1681,32 @@
"type": "boolean"
}
}
},

"MemoryRangeDescription": {
"title": "MemoryRangeDescription",
"type": "object",
"properties": {
"start": {
"$ref": "#/components/schemas/UnsignedInteger"
},
"length": {
"$ref": "#/components/schemas/UnsignedInteger"
},
"description": {
"type": "string"
}
}
},

"MemoryRangeDescriptionArray": {
"title": "MemoryRangeDescriptionArray",
"type": "array",
"items": {
"$ref": "#/components/schemas/MemoryRangeDescription"
}
}

}
}
}
15 changes: 15 additions & 0 deletions src/jsonrpc-remote-machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1504,6 +1504,20 @@ static json jsonrpc_machine_dump_pmas_handler(const json &j, mg_connection *con,
return jsonrpc_response_ok(j);
}

/// \brief JSONRPC handler for the machine.get_memory_ranges method
/// \param j JSON request object
/// \param con Mongoose connection
/// \param h Handler data
/// \returns JSON response object
static json jsonrpc_machine_get_memory_ranges_handler(const json &j, mg_connection *con, http_handler_data *h) {
(void) con;
if (!h->machine) {
return jsonrpc_response_invalid_request(j, "no machine");
}
jsonrpc_check_no_params(j);
return jsonrpc_response_ok(j, h->machine->get_memory_ranges());
}

/// \brief Sends a JSONRPC response through the Mongoose connection
/// \param con Mongoose connection
/// \param j JSON response object
Expand Down Expand Up @@ -1580,6 +1594,7 @@ static json jsonrpc_dispatch_method(const json &j, mg_connection *con, http_hand
{"machine.verify_merkle_tree", jsonrpc_machine_verify_merkle_tree_handler},
{"machine.verify_dirty_page_maps", jsonrpc_machine_verify_dirty_page_maps_handler},
{"machine.dump_pmas", jsonrpc_machine_dump_pmas_handler},
{"machine.get_memory_ranges", jsonrpc_machine_get_memory_ranges_handler},
};
auto method = j["method"].get<std::string>();
SLOG(debug) << h->server_address << " handling \"" << method << "\" method";
Expand Down
6 changes: 6 additions & 0 deletions src/jsonrpc-virtual-machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,12 @@ uarch_interpreter_break_reason jsonrpc_virtual_machine::do_run_uarch(uint64_t ua
return result;
}

machine_memory_range_descrs jsonrpc_virtual_machine::do_get_memory_ranges(void) const {
machine_memory_range_descrs result;
jsonrpc_request(m_mgr->get_mgr(), m_mgr->get_remote_address(), "machine.get_memory_ranges", std::tie(), result);
return result;
}

#pragma GCC diagnostic pop

} // namespace cartesi
1 change: 1 addition & 0 deletions src/jsonrpc-virtual-machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ class jsonrpc_virtual_machine final : public i_virtual_machine {
void do_write_uarch_cycle(uint64_t val) override;
uint64_t do_read_uarch_ram_length(void) const override;
uarch_interpreter_break_reason do_run_uarch(uint64_t uarch_cycle_end) override;
machine_memory_range_descrs do_get_memory_ranges(void) const override;

jsonrpc_mg_mgr_ptr m_mgr;
};
Expand Down
43 changes: 43 additions & 0 deletions src/machine-c-api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,27 @@ cartesi::access_log convert_from_c(const cm_access_log *c_acc_log) {
return new_cpp_acc_log;
}

// --------------------------------------------
// Memory range description conversion functions
// --------------------------------------------
cm_memory_range_descr convert_to_c(const cartesi::machine_memory_range_descr &cpp_mrd) {
cm_memory_range_descr new_mrd{};
new_mrd.start = cpp_mrd.start;
new_mrd.length = cpp_mrd.length;
new_mrd.description = convert_to_c(cpp_mrd.description);
return new_mrd;
}

cm_memory_range_descr_array *convert_to_c(const cartesi::machine_memory_range_descrs &cpp_mrds) {
auto *new_mrda = new cm_memory_range_descr_array{};
new_mrda->count = cpp_mrds.size();
new_mrda->entry = new cm_memory_range_descr[new_mrda->count];
for (size_t i = 0; i < new_mrda->count; ++i) {
new_mrda->entry[i] = convert_to_c(cpp_mrds[i]);
}
return new_mrda;
}

// -----------------------------------------------------
// Public API functions for generation of default configs
// -----------------------------------------------------
Expand Down Expand Up @@ -1349,3 +1370,25 @@ int cm_rollback(cm_machine *m, char **err_msg) try {
} catch (...) {
return cm_result_failure(err_msg);
}

CM_API int cm_get_memory_ranges(cm_machine *m, cm_memory_range_descr_array **mrds, char **err_msg) try {
if (mrds == nullptr) {
throw std::invalid_argument("invalid memory range output");
}
auto *cpp_machine = convert_from_c(m);
*mrds = convert_to_c(cpp_machine->get_memory_ranges());
return cm_result_success(err_msg);
} catch (...) {
return cm_result_failure(err_msg);
}

CM_API void cm_delete_memory_range_descr_array(cm_memory_range_descr_array *mrds) {
if (mrds == nullptr) {
return;
}
for (size_t i = 0; i < mrds->count; ++i) {
delete[] mrds->entry[i].description;
}
delete[] mrds->entry;
delete mrds;
}
Loading

0 comments on commit c1f0190

Please sign in to comment.