From 5ce98e5d685993cf6a75460e7f258c574b18f656 Mon Sep 17 00:00:00 2001 From: Mingle Chen Date: Fri, 9 Sep 2022 15:34:21 +0100 Subject: [PATCH 1/5] Add tracing for total instruction count --- trace_extra/memory_interceptor.cc | 2 ++ trace_extra/memory_interceptor.hh | 1 + trace_extra/trace_perfetto.cc | 21 ++++++++++++++++++--- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/trace_extra/memory_interceptor.cc b/trace_extra/memory_interceptor.cc index f948d87d13..cbf3ffd1c6 100644 --- a/trace_extra/memory_interceptor.cc +++ b/trace_extra/memory_interceptor.cc @@ -38,6 +38,7 @@ DynamorioTraceInterceptor::ThreadLocalState::ThreadLocalState( } io::filtering_ostream DynamorioTraceInterceptor::mem_logfile; +uint64_t DynamorioTraceInterceptor::instr_count = 0; void DynamorioTraceInterceptor::OnTracePacket(InterceptorContext context) { @@ -57,6 +58,7 @@ void DynamorioTraceInterceptor::OnTracePacket(InterceptorContext context) perfetto::protos::pbzero::Opcode::Decoder opcode( instr.opcode_obj()); if (opcode.has_size()) { + ++instr_count; trace_entry_t entry; entry.type = TRACE_TYPE_INSTR; entry.addr = reinterpret_cast(instr.pc()); diff --git a/trace_extra/memory_interceptor.hh b/trace_extra/memory_interceptor.hh index b2f985d8e9..e9a8011bc9 100644 --- a/trace_extra/memory_interceptor.hh +++ b/trace_extra/memory_interceptor.hh @@ -46,6 +46,7 @@ class DynamorioTraceInterceptor public: static io::filtering_ostream mem_logfile; + static uint64_t instr_count; ~DynamorioTraceInterceptor() override = default; struct ThreadLocalState diff --git a/trace_extra/trace_perfetto.cc b/trace_extra/trace_perfetto.cc index 3caf0fcab4..297dd4cdc9 100644 --- a/trace_extra/trace_perfetto.cc +++ b/trace_extra/trace_perfetto.cc @@ -71,7 +71,10 @@ std::unique_ptr session; fs::path logfile("qemu_trace.pb"); /* perfetto interceptor trace file */ -string mem_logfile_name = "mem_access.trace.gz"; +string mem_logfile = "mem_trace.gz"; + +/* instrcution count file */ +string instr_count_file; /* enable perfetto interceptor */ bool enable_interceptor = false; @@ -134,9 +137,15 @@ bool perfetto_start_tracing(void) perfetto::TrackEvent::Register(); if (enable_interceptor) { + // hardcode instr_path for now + fs::path mem_logfile_path(mem_logfile); + instr_count_file = + mem_logfile_path.parent_path().parent_path().string() + + "/instr_count.txt"; + DynamorioTraceInterceptor::mem_logfile.push(io::gzip_compressor()); DynamorioTraceInterceptor::mem_logfile.push( - io::file_descriptor_sink(mem_logfile_name)); + io::file_descriptor_sink(mem_logfile)); // drcachesim needs a header in the file, so we create it here trace_entry_t header{ .type = TRACE_TYPE_HEADER, @@ -229,6 +238,12 @@ void perfetto_tracing_stop(void) DynamorioTraceInterceptor::mem_logfile.write((char *)&footer, sizeof(footer)); io::close(DynamorioTraceInterceptor::mem_logfile); + + // store the number of instructions executed + ofstream outfile; + outfile.open(instr_count_file); + outfile << DynamorioTraceInterceptor::instr_count << std::endl; + outfile.close(); } } @@ -513,7 +528,7 @@ qemu_log_instr_perfetto_conf_categories(const char *category_str) extern "C" void qemu_log_instr_perfetto_interceptor_logfile(const char *name) { - mem_logfile_name = name; + mem_logfile = name; } extern "C" void qemu_log_instr_perfetto_enable_interceptor() From f75ca6603ce38f2e1a606e151eb5a8bc19ac2e2e Mon Sep 17 00:00:00 2001 From: Mingle Chen Date: Wed, 5 Apr 2023 15:09:34 +0100 Subject: [PATCH 2/5] Implement experimental riscv instructions --- target/riscv/helper.h | 2 ++ target/riscv/insn32-cheri.decode | 6 ++-- target/riscv/insn_trans/trans_cheri.c.inc | 40 +++++++++++++++++++++++ target/riscv/op_helper_cheri.c | 8 +++++ 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 09c54114a8..48fb4ce99e 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -77,6 +77,8 @@ DEF_HELPER_3(lr_c_cap, void, env, i32, i32) DEF_HELPER_3(sc_c_modedep, tl, env, i32, i32) DEF_HELPER_3(sc_c_ddc, tl, env, i32, i32) DEF_HELPER_3(sc_c_cap, tl, env, i32, i32) +/* experimental instruction helpers*/ +DEF_HELPER_2(ctestdereferenceable, tl, env, i32) #endif #ifdef CONFIG_TCG_LOG_INSTR diff --git a/target/riscv/insn32-cheri.decode b/target/riscv/insn32-cheri.decode index 79bbc61aa6..d7cb3bacca 100644 --- a/target/riscv/insn32-cheri.decode +++ b/target/riscv/insn32-cheri.decode @@ -57,6 +57,8 @@ ccopytype 0011110 ..... ..... 000 ..... 1011011 @r ccseal 0011111 ..... ..... 000 ..... 1011011 @r ctestsubset 0100000 ..... ..... 000 ..... 1011011 @r cseqx 0100001 ..... ..... 000 ..... 1011011 @r +candaddr 0100010 ..... ..... 000 ..... 1011011 @r + # 1111011 unused # 1111100 Used for Stores (see below) # 1111101 Used for Loads (see below) @@ -85,9 +87,9 @@ cgetaddr 1111111 01111 ..... 000 ..... 1011011 @r2 # fpclear 1111111 10000 ..... 000 ..... 1011011 @r2 csealentry 1111111 10001 ..... 000 ..... 1011011 @r2 cloadtags 1111111 10010 ..... 000 ..... 1011011 @r2 +ctestdereferenceable 1111111 10011 ..... 000 ..... 1011011 @r2 jalr_pcc 1111111 10100 ..... 000 ..... 1011011 @r2 - - +candpermuserdata 1111111 10101 ..... 000 ..... 1011011 @r2 # There is an existing @sfence_vma format with rs1+rs2 fields, but let's define a new name @r_2source ....... ..... ..... ... ..... ....... %rs2 %rs1 diff --git a/target/riscv/insn_trans/trans_cheri.c.inc b/target/riscv/insn_trans/trans_cheri.c.inc index dae1d785f2..1d50ab6c39 100644 --- a/target/riscv/insn_trans/trans_cheri.c.inc +++ b/target/riscv/insn_trans/trans_cheri.c.inc @@ -166,6 +166,9 @@ TRANSLATE_INT_CAP(cgetsealed) TRANSLATE_INT_CAP(cloadtags) +// experimental ctestdereferenceable +TRANSLATE_INT_CAP(ctestdereferenceable) + // Two operand (int int) static inline bool trans_crrl(DisasContext *ctx, arg_crrl *a) { @@ -181,6 +184,40 @@ TRANSLATE_CAP_CAP(ccleartag) TRANSLATE_CAP_CAP(cmove) TRANSLATE_CAP_CAP(csealentry) +// experimental candpermuserdata + +/* User-defined permission bits. */ +#define CAP_PERM_SW0 (1 << 15) /* 0x00008000 */ +#define CAP_PERM_SW1 (1 << 16) /* 0x00010000 */ +#define CAP_PERM_SW2 (1 << 17) /* 0x00020000 */ +#define CAP_PERM_SW3 (1 << 18) /* 0x00040000 */ +#define CAP_PERM_SW_VMEM CAP_PERM_SW1 + +#define CAP_PERMS_SWALL \ + (CAP_PERM_SW0 | CAP_PERM_SW1 | CAP_PERM_SW2 | CAP_PERM_SW3) + +#define CAP_PERMS_USERSPACE \ + (CAP_PERM_GLOBAL | CAP_PERM_LOAD | CAP_PERM_LOAD_CAP | CAP_PERM_CINVOKE | \ + (CAP_PERMS_SWALL & ~CAP_PERM_SW_VMEM)) + +#define CAP_PERMS_USERSPACE_DATA \ + (CAP_PERMS_USERSPACE | CAP_PERM_STORE | CAP_PERM_STORE_CAP | \ + CAP_PERM_STORE_LOCAL) + +static inline bool trans_candpermuserdata(DisasContext *ctx, + arg_candpermuserdata *a) +{ + TCGv_i32 source_regnum = tcg_const_i32(a->rs1); + TCGv_i32 dest_regnum = tcg_const_i32(a->rd); + TCGv gpr = tcg_temp_new(); + gen_set_gpr(gpr, CAP_PERMS_USERSPACE_DATA & ~CAP_PERM_SW_VMEM); + gen_helper_candperm(cpu_env, dest_regnum, source_regnum, gpr); + tcg_temp_free(gpr); + tcg_temp_free_i32(dest_regnum); + tcg_temp_free_i32(source_regnum); + return true; +} + // Three operand (cap cap cap) TRANSLATE_CAP_CAP_CAP(cbuildcap) TRANSLATE_CAP_CAP_CAP(ccopytype) @@ -215,6 +252,9 @@ TRANSLATE_CAP_CAP_INT(csetboundsexact) TRANSLATE_CAP_CAP_INT(csetflags) TRANSLATE_CAP_CAP_INT(csetoffset) +// Add experimental CAndAddr instruction +TRANSLATE_CAP_CAP_INT(candaddr) + // Three operand (int cap cap) TRANSLATE_INT_CAP_CAP(csub) TRANSLATE_INT_CAP_CAP(ctestsubset) diff --git a/target/riscv/op_helper_cheri.c b/target/riscv/op_helper_cheri.c index 8588b5415e..4398fdba3a 100644 --- a/target/riscv/op_helper_cheri.c +++ b/target/riscv/op_helper_cheri.c @@ -453,3 +453,11 @@ target_ulong HELPER(sc_c_cap)(CPUArchState *env, uint32_t addr_reg, uint32_t val { return sc_c_impl(env, addr_reg, val_reg, /*offset=*/0, GETPC()); } + +/* Helpers for experimental instructions. */ +target_ulong HELPER(ctestdereferenceable)(CPUArchState *env, uint32_t addr_reg) +{ + const cap_register_t *cbp = get_readonly_capreg(env, addr_reg); + + return cbp->cr_tag && cap_is_unsealed(cbp) && cap_cursor_in_bounds(cbp); +} From ff676a6c212f3d3cb6ffb239adda812598fea8e9 Mon Sep 17 00:00:00 2001 From: Mingle Chen Date: Wed, 5 Apr 2023 16:47:06 +0100 Subject: [PATCH 3/5] Remove obsolete definition of debug_counter_names --- trace_extra/guest_context_tracker.cc | 8 -------- trace_extra/guest_context_tracker.hh | 10 ---------- 2 files changed, 18 deletions(-) diff --git a/trace_extra/guest_context_tracker.cc b/trace_extra/guest_context_tracker.cc index 24ee0386af..c628ff9863 100644 --- a/trace_extra/guest_context_tracker.cc +++ b/trace_extra/guest_context_tracker.cc @@ -51,14 +51,6 @@ std::unordered_map, tuple_hasher> track_state_map; -/* - * Constant mapping of QEMUDebugCounter IDs to counter track names - */ -const std::array debug_counter_names{ - "tb_icount", - "tb_icount_tracing", -}; - /* Helper to generate unique IDs for dynamic tracks */ unsigned long gen_track_uuid() { diff --git a/trace_extra/guest_context_tracker.hh b/trace_extra/guest_context_tracker.hh index 357d36c741..0815aee78c 100644 --- a/trace_extra/guest_context_tracker.hh +++ b/trace_extra/guest_context_tracker.hh @@ -61,9 +61,6 @@ unsigned long gen_track_uuid(); perfetto::protos::pbzero::QEMULogEntryModeSwitch qemu_cpu_mode_to_trace(qemu_log_instr_cpu_mode_t mode); -extern const std::array - debug_counter_names; - /* * Custom track representing a QEMU guest context. */ @@ -216,13 +213,6 @@ struct qemu_fallback_state : public qemu_tracker_state { perfetto::TrackEvent::EraseTrackDescriptor(track); } - perfetto::CounterTrack - get_debug_counter_track(QEMUDebugCounter counter_index) - { - return perfetto::CounterTrack( - debug_counter_names[counter_index].c_str(), track); - } - perfetto::Track *get_track() { return &track; From 4e8fb0e40344a649f9e6ef425cdc9e3c8c863d56 Mon Sep 17 00:00:00 2001 From: Mingle Chen Date: Wed, 12 Apr 2023 16:52:57 +0100 Subject: [PATCH 4/5] Fix canduserperm translation in qemu --- target/riscv/insn_trans/trans_cheri.c.inc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/target/riscv/insn_trans/trans_cheri.c.inc b/target/riscv/insn_trans/trans_cheri.c.inc index 1d50ab6c39..85fc14a1fd 100644 --- a/target/riscv/insn_trans/trans_cheri.c.inc +++ b/target/riscv/insn_trans/trans_cheri.c.inc @@ -209,12 +209,11 @@ static inline bool trans_candpermuserdata(DisasContext *ctx, { TCGv_i32 source_regnum = tcg_const_i32(a->rs1); TCGv_i32 dest_regnum = tcg_const_i32(a->rd); - TCGv gpr = tcg_temp_new(); - gen_set_gpr(gpr, CAP_PERMS_USERSPACE_DATA & ~CAP_PERM_SW_VMEM); - gen_helper_candperm(cpu_env, dest_regnum, source_regnum, gpr); - tcg_temp_free(gpr); + TCGv perms = tcg_const_tl(CAP_PERMS_USERSPACE_DATA & ~CAP_PERM_SW_VMEM); + gen_helper_candperm(cpu_env, dest_regnum, source_regnum, perms); tcg_temp_free_i32(dest_regnum); tcg_temp_free_i32(source_regnum); + tcg_temp_free(perms); return true; } From eebfe7af0b86e0bd12a36191798f8c29faea9be8 Mon Sep 17 00:00:00 2001 From: Mingle Chen Date: Sat, 22 Apr 2023 16:09:51 +0100 Subject: [PATCH 5/5] Change ctestdereferenceable implementation to avoid issue with zero length cap --- target/riscv/op_helper_cheri.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/riscv/op_helper_cheri.c b/target/riscv/op_helper_cheri.c index 4398fdba3a..fb7bd3c86b 100644 --- a/target/riscv/op_helper_cheri.c +++ b/target/riscv/op_helper_cheri.c @@ -459,5 +459,5 @@ target_ulong HELPER(ctestdereferenceable)(CPUArchState *env, uint32_t addr_reg) { const cap_register_t *cbp = get_readonly_capreg(env, addr_reg); - return cbp->cr_tag && cap_is_unsealed(cbp) && cap_cursor_in_bounds(cbp); + return cbp->cr_tag && cap_is_unsealed(cbp) && cap_get_offset(cbp) == 0; }