Skip to content

Commit bc43237

Browse files
committed
feat: add maximum uarch cycle to prevent overflow in collect APIs
1 parent 03a8a23 commit bc43237

15 files changed

+157
-151
lines changed

src/clua-cartesi.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ CM_API int luaopen_cartesi(lua_State *L) {
213213
clua_setintegerfield(L, CM_VERSION_PATCH, "VERSION_PATCH", -1);
214214
clua_setintegerfield(L, CM_HASH_SIZE, "HASH_SIZE", -1);
215215
clua_setintegerfield(L, CM_MCYCLE_MAX, "MCYCLE_MAX", -1);
216+
clua_setintegerfield(L, CM_UARCH_CYCLE_MAX, "UARCH_CYCLE_MAX", -1);
216217
clua_setintegerfield(L, CM_TREE_LOG2_WORD_SIZE, "TREE_LOG2_WORD_SIZE", -1);
217218
clua_setintegerfield(L, CM_TREE_LOG2_PAGE_SIZE, "TREE_LOG2_PAGE_SIZE", -1);
218219
clua_setintegerfield(L, CM_TREE_LOG2_ROOT_SIZE, "TREE_LOG2_ROOT_SIZE", -1);
@@ -224,6 +225,7 @@ CM_API int luaopen_cartesi(lua_State *L) {
224225
clua_setintegerfield(L, CM_BREAK_REASON_REACHED_TARGET_MCYCLE, "BREAK_REASON_REACHED_TARGET_MCYCLE", -1);
225226
clua_setintegerfield(L, CM_UARCH_BREAK_REASON_REACHED_TARGET_CYCLE, "UARCH_BREAK_REASON_REACHED_TARGET_CYCLE", -1);
226227
clua_setintegerfield(L, CM_UARCH_BREAK_REASON_UARCH_HALTED, "UARCH_BREAK_REASON_UARCH_HALTED", -1);
228+
clua_setintegerfield(L, CM_UARCH_BREAK_REASON_CYCLE_OVERFLOW, "UARCH_BREAK_REASON_CYCLE_OVERFLOW", -1);
227229
clua_setintegerfield(L, CM_ACCESS_LOG_TYPE_ANNOTATIONS, "ACCESS_LOG_TYPE_ANNOTATIONS", -1);
228230
clua_setintegerfield(L, CM_ACCESS_LOG_TYPE_LARGE_DATA, "ACCESS_LOG_TYPE_LARGE_DATA", -1);
229231
clua_setintegerfield(L, CM_CMIO_YIELD_COMMAND_AUTOMATIC, "CMIO_YIELD_COMMAND_AUTOMATIC", -1);

src/json-util.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,8 @@ static std::string uarch_interpreter_break_reason_to_name(uarch_interpreter_brea
570570
return "uarch_halted";
571571
case R::reached_target_cycle:
572572
return "reached_target_cycle";
573+
case R::cycle_overflow:
574+
return "cycle_overflow";
573575
}
574576
throw std::domain_error{"invalid uarch interpreter break reason"};
575577
}
@@ -607,13 +609,14 @@ static interpreter_break_reason interpreter_break_reason_from_name(const std::st
607609

608610
static uarch_interpreter_break_reason uarch_interpreter_break_reason_from_name(const std::string &name) {
609611
using uibr = uarch_interpreter_break_reason;
610-
if (name == "reached_target_cycle") {
611-
return uibr::reached_target_cycle;
612+
const static std::unordered_map<std::string, uibr> g_uibr_name = {
613+
{"reached_target_cycle", uibr::reached_target_cycle}, {"uarch_halted", uibr::uarch_halted},
614+
{"cycle_overflow", uibr::cycle_overflow}};
615+
auto got = g_uibr_name.find(name);
616+
if (got == g_uibr_name.end()) {
617+
throw std::domain_error{"invalid uarch interpreter break reason"};
612618
}
613-
if (name == "uarch_halted") {
614-
return uibr::uarch_halted;
615-
}
616-
throw std::domain_error{"invalid uarch interpreter break reason"};
619+
return got->second;
617620
}
618621

619622
static hash_function_type hash_function_from_name(const std::string &name) {

src/jsonrpc-discover.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1975,7 +1975,7 @@
19751975
},
19761976
"UarchInterpreterBreakReason": {
19771977
"title": "UarchInterpreterBreakReason",
1978-
"enum": ["reached_target_cycle", "uarch_halted"]
1978+
"enum": ["reached_target_cycle", "uarch_halted", "cycle_overflow"]
19791979
},
19801980
"Base64String": {
19811981
"title": "Base64String",

src/machine-c-api.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ extern "C" {
3737
#endif
3838

3939
#define CM_MCYCLE_MAX UINT64_MAX
40+
#define CM_UARCH_CYCLE_MAX UINT64_C(1048576)
4041

4142
// -----------------------------------------------------------------------------
4243
// API enums and structures
@@ -101,6 +102,7 @@ typedef enum cm_break_reason {
101102
typedef enum cm_uarch_break_reason {
102103
CM_UARCH_BREAK_REASON_REACHED_TARGET_CYCLE,
103104
CM_UARCH_BREAK_REASON_UARCH_HALTED,
105+
CM_UARCH_BREAK_REASON_CYCLE_OVERFLOW,
104106
CM_UARCH_BREAK_REASON_FAILED,
105107
} cm_uarch_break_reason;
106108

src/machine.cpp

Lines changed: 93 additions & 96 deletions
Large diffs are not rendered by default.

src/uarch-constants.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "address-range-constants.h"
2323
#include "address-range-defines.h"
24+
#include "machine-c-api.h"
2425
#include "uarch-defines.h"
2526

2627
namespace cartesi {
@@ -40,7 +41,9 @@ enum uarch_state_constants : uint64_t {
4041
UARCH_STATE_ALIGN_MASK = (UINT64_C(1) << UARCH_STATE_LOG2_SIZE) - 1, ///< Mask for uarch state alignment
4142
UARCH_STATE_MASK = ~UARCH_STATE_ALIGN_MASK, ///< Mask for uarch state address space
4243
UARCH_STATE_CHILD_ALIGN_MASK =
43-
(UINT64_C(1) << UARCH_STATE_CHILD_LOG2_SIZE) - 1 ///< Mask for uarch state child alignment
44+
(UINT64_C(1) << UARCH_STATE_CHILD_LOG2_SIZE) - 1, ///< Mask for uarch state child alignment
45+
UARCH_LOG2_MAX_CYCLE = EXPAND_UINT64_C(UARCH_LOG2_MAX_CYCLE_DEF),
46+
UARCH_MAX_CYCLE = (UINT64_C(1) << UARCH_LOG2_MAX_CYCLE),
4447
};
4548

4649
static_assert((UARCH_STATE_START_ADDRESS & UARCH_STATE_ALIGN_MASK) == 0,
@@ -61,6 +64,7 @@ static_assert(UARCH_SHADOW_START_ADDRESS < UARCH_RAM_START_ADDRESS,
6164
"UARCH_SHADOW_START_ADDRESS must be smaller than UARCH_RAN_START_ADDRESS");
6265
static_assert((UARCH_SHADOW_LENGTH & (AR_PAGE_SIZE - 1)) == 0, "UARCH_SHADOW_LENGTH must be multiple of AR_PAGE_SIZE");
6366
static_assert((UARCH_RAM_LENGTH & (AR_PAGE_SIZE - 1)) == 0, "UARCH_RAM_LENGTH must be multiple of AR_PAGE_SIZE");
67+
static_assert(UARCH_MAX_CYCLE == CM_UARCH_CYCLE_MAX, "CM_UARCH_CYCLE_MAX must be equal to UARCH_MAX_CYCLE");
6468

6569
/// \brief ecall function codes
6670
enum uarch_ecall_functions : uint64_t {

src/uarch-defines.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
/// \brief Log2 size of the entire uarch memory range: shadow and ram
2626
#define UARCH_STATE_LOG2_SIZE_DEF 22
2727

28+
/// \brief Log2 of the expected maximum uarch cycle
29+
#define UARCH_LOG2_MAX_CYCLE_DEF 20
30+
2831
// microarchitecture ecall function codes
2932
#define UARCH_ECALL_FN_HALT_DEF 1 // halt uarch
3033
#define UARCH_ECALL_FN_PUTCHAR_DEF 2 // putchar

src/uarch-interpret.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,8 @@ uarch_interpreter_break_reason uarch_interpret(const STATE_ACCESS a, uint64_t cy
3838
break;
3939
case UArchStepStatus::UArchHalted:
4040
return uarch_interpreter_break_reason::uarch_halted;
41-
// LCOV_EXCL_START
4241
case UArchStepStatus::CycleOverflow:
43-
// Prior condition ensures that this case is unreachable. but linter may complain about missing it
44-
return uarch_interpreter_break_reason::reached_target_cycle;
45-
// LCOV_EXCL_STOP
42+
return uarch_interpreter_break_reason::cycle_overflow;
4643
}
4744
}
4845
return uarch_interpreter_break_reason::reached_target_cycle;

src/uarch-interpret.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
namespace cartesi {
2323

24-
enum class uarch_interpreter_break_reason : int { reached_target_cycle, uarch_halted };
24+
enum class uarch_interpreter_break_reason : int { reached_target_cycle, uarch_halted, cycle_overflow };
2525

2626
// Run the microarchitecture interpreter until cycle hits a target or a fixed point is reached
2727
template <typename STATE_ACCESS>

src/uarch-step.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1098,7 +1098,7 @@ UArchStepStatus uarch_step(const UarchState a) {
10981098
// This must be the first read in order to match the first log access in machine::verify_step_uarch
10991099
uint64 cycle = readCycle(a);
11001100
// do not advance if cycle will overflow
1101-
if (cycle == UINT64_MAX) {
1101+
if (cycle >= UARCH_MAX_CYCLE) {
11021102
return UArchStepStatus::CycleOverflow;
11031103
}
11041104
// do not advance if machine is halted

0 commit comments

Comments
 (0)