Skip to content

Commit a7af558

Browse files
sanpar-qcomeyck
authored andcommitted
core_complex: fix uint64_t overflow issue
1 parent dcedbcc commit a7af558

1 file changed

Lines changed: 28 additions & 7 deletions

File tree

src/sysc/core_complex.cpp

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,23 @@ using namespace sc_core;
8888
namespace {
8989
iss::debugger::encoder_decoder encdec;
9090
std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
91+
92+
inline bool is_within_dmi_range(uint64_t start, unsigned length, uint64_t inclusive_end) {
93+
if(length == 0) {
94+
return true;
95+
}
96+
if(start > inclusive_end) {
97+
return false;
98+
}
99+
return static_cast<uint64_t>(length - 1) <= (inclusive_end - start);
100+
}
101+
102+
inline bool is_invalidate_end_covered(uint64_t end, uint64_t inclusive_end) {
103+
if(end <= inclusive_end) {
104+
return true;
105+
}
106+
return inclusive_end != std::numeric_limits<uint64_t>::max() && end == (inclusive_end + 1);
107+
}
91108
} // namespace
92109

93110
template <unsigned int BUSWIDTH, typename QK>
@@ -191,20 +208,22 @@ template <unsigned int BUSWIDTH, typename QK> void core_complex<BUSWIDTH, QK>::i
191208
core_complex_if::exec_on_sysc = util::delegate<void(std::function<void(void)>&)>::from<this_class, &this_class::exec_on_sysc<QK>>(this);
192209
ibus.register_invalidate_direct_mem_ptr([this](uint64_t start, uint64_t end) -> void {
193210
auto lut_entry = fetch_lut.getEntry(start);
194-
if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && end <= lut_entry.get_end_address() + 1) {
211+
if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && is_invalidate_end_covered(end, lut_entry.get_end_address())) {
195212
fetch_lut.removeEntry(lut_entry);
196213
}
197214
});
198215
dbus.register_invalidate_direct_mem_ptr([this](uint64_t start, uint64_t end) -> void {
199216
for(auto& read_lut : dmi_read_luts) {
200217
auto lut_entry = read_lut.getEntry(start);
201-
if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && end <= lut_entry.get_end_address() + 1) {
218+
if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE &&
219+
is_invalidate_end_covered(end, lut_entry.get_end_address())) {
202220
read_lut.removeEntry(lut_entry);
203221
}
204222
}
205223
for(auto& write_lut : dmi_write_luts) {
206224
auto lut_entry = write_lut.getEntry(start);
207-
if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && end <= lut_entry.get_end_address() + 1) {
225+
if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE &&
226+
is_invalidate_end_covered(end, lut_entry.get_end_address())) {
208227
write_lut.removeEntry(lut_entry);
209228
}
210229
}
@@ -396,7 +415,8 @@ bool core_complex<BUSWIDTH, QK>::read_mem(const addr_t& addr, unsigned length, u
396415
bool is_fetch = addr.space == std::numeric_limits<decltype(addr.space)>::max() ? true : false;
397416
auto& dmi_lut = is_fetch ? fetch_lut : get_read_lut(addr.space);
398417
auto lut_entry = dmi_lut.getEntry(addr.val);
399-
if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && (addr.val + length) <= (lut_entry.get_end_address() + 1)) {
418+
if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE &&
419+
is_within_dmi_range(addr.val, length, lut_entry.get_end_address())) {
400420
auto offset = addr.val - lut_entry.get_start_address();
401421
std::copy(lut_entry.get_dmi_ptr() + offset, lut_entry.get_dmi_ptr() + offset + length, data);
402422
if(is_fetch)
@@ -450,7 +470,7 @@ bool core_complex<BUSWIDTH, QK>::read_mem(const addr_t& addr, unsigned length, u
450470
gp.set_address(addr.val);
451471
tlm_dmi_ext dmi_data;
452472
if(exec_get_direct_mem_ptr(gp, dmi_data)) {
453-
if(dmi_data.is_read_allowed() && (addr.val + length - 1) <= dmi_data.get_end_address())
473+
if(dmi_data.is_read_allowed() && is_within_dmi_range(addr.val, length, dmi_data.get_end_address()))
454474
dmi_lut.addEntry(dmi_data, dmi_data.get_start_address(), dmi_data.get_end_address() - dmi_data.get_start_address() + 1);
455475
}
456476
}
@@ -461,7 +481,8 @@ bool core_complex<BUSWIDTH, QK>::read_mem(const addr_t& addr, unsigned length, u
461481
template <unsigned int BUSWIDTH, typename QK>
462482
bool core_complex<BUSWIDTH, QK>::write_mem(const addr_t& addr, unsigned length, const uint8_t* const data) {
463483
auto lut_entry = get_write_lut(addr.space).getEntry(addr.val);
464-
if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && (addr.val + length) <= (lut_entry.get_end_address() + 1)) {
484+
if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE &&
485+
is_within_dmi_range(addr.val, length, lut_entry.get_end_address())) {
465486
auto offset = addr.val - lut_entry.get_start_address();
466487
std::copy(data, data + length, lut_entry.get_dmi_ptr() + offset);
467488
dbus_inc += lut_entry.get_write_latency() / curr_clk;
@@ -508,7 +529,7 @@ bool core_complex<BUSWIDTH, QK>::write_mem(const addr_t& addr, unsigned length,
508529
gp.set_address(addr.val);
509530
tlm_dmi_ext dmi_data;
510531
if(exec_get_direct_mem_ptr(gp, dmi_data)) {
511-
if(dmi_data.is_write_allowed() && (addr.val + length - 1) <= dmi_data.get_end_address())
532+
if(dmi_data.is_write_allowed() && is_within_dmi_range(addr.val, length, dmi_data.get_end_address()))
512533
get_write_lut(addr.space)
513534
.addEntry(dmi_data, dmi_data.get_start_address(), dmi_data.get_end_address() - dmi_data.get_start_address() + 1);
514535
}

0 commit comments

Comments
 (0)