Cheri Qemu

References:

  • Translate
  • References: reference More CCall References: target/mips/translate.c // target/mips/translate.c mips_tr_translate_insn() --> gen_branch() // is_slot decode_opc() --> gen_compute_compact_branch() --> gen_branch() // bcond_compute == 0 --> gen_helper_copy_cap_btarget_to_pcc(cpu_env) // MIPS_HFLAG_BRCCALL/MIPS_HFLAG_BRC --> CHERI_HELPER_IMPL(copy_cap_btarget_to_pcc(CPUArchState *env)) More Syscall References: target/mips/translate.c mips_tr_translate_insn() --> decode_opc() // !(ctx->hflags & MIPS_HFLAG_M16) --> decode_opc_special() --> generate_exception_end(ctx, EXCP_SYSCALL) generate_exception_end() -> generate_exception_err() // target/mips/translate.c // generate_exception_end(ctx, EXCP_SYSCALL) --> generate_exception_err(ctx, excp, 0) static inline void generate_exception_err(DisasContext *ctx, MipsExcp excp, int err) { TCGv_i32 texcp = tcg_const_i32(excp); TCGv_i32 terr = tcg_const_i32(err); save_cpu_state(ctx, 1); gen_helper_raise_exception_err(cpu_env, texcp, terr); tcg_temp_free_i32(terr); tcg_temp_free_i32(texcp); ctx->base.

  • Addr Trans
  • Reference reference All memory translation requests finally invokes a callback func env->tlb->map_address Example code: // target/mips/helper.c static int get_seg_physical_address(CPUMIPSState *env, hwaddr *physical, int *prot, target_ulong real_address, int rw, int access_type, int mmu_idx, unsigned int am, bool eu, target_ulong segmask, hwaddr physical_base) { int ret; int mapped = is_seg_am_mapped(am, eu, mmu_idx); if (mapped < 0) { /* is_seg_am_mapped can report TLBRET_BADADDR */ return mapped; } else if (mapped) { /* The segment is TLB mapped */ ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type); } else { /* The segment is unmapped */ *physical = physical_base | (real_address & segmask); *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; ret = TLBRET_MATCH; } return ret; } env->tlb->map_address is assigned in translate_init.

  • Instruction Fetch and PCC checks
  • References: QEMU source ~4.2.93 QEMU Detailed Study Translator Internals QEMU start to instruction fetch Some call paths for instruction fetch and decoding: // cpu_exec callers cpu_loop // linux-user/mips/cpu_loop.c => cpu_exec qemu_tcg_init_vcpu // thread creation using fn pointer, cpus.c => qemu_tcg_rr_cpu_thread_fn => tcg_cpu_exec => cpu_exec qemu_tcg_init_vcpu // thread creation using fn pointer, cpus.c => qemu_tcg_cpu_thread_fn => tcg_cpu_exec => cpu_exec // cpu_exec ---> translator_loop cpu_exec => tb_find => if (not found): tb_gen_code // accel/tcg/translate-all.

  • Guest RAM
  • Q&A How can we convert a virt addr in QEMU to a (faked) physical addr? Reference 1 2 Memory Regions Entire physical memory is modelled as an acyclic graph of MemoryRegion objects 1. Sinks(leaves) are RAM and MIMO regions. While other nodes represents buses, memory controllers, and memory regions that have been rerouted. In addition to MemoryRegsion objects, the memory API provides AddressSpace objects for every root and possibly for intermediate MemoryRegsions too.

  • Memtrace
  • Reference 1 Simple Q&A What kind of operations the guest_mem_before_exec trace? trace the virtual address when the CPU access the memory Load cap: no mem trace when TLB hit(probe_read). A bug? probably no. A TLB hit means the table entry already loaded into TLB. Loading this entry can only be counted once as a memory access. guest_mem_before_exec Event format def The def of trace event: # tcg/tcg-op. reference ↩

  • Tag Mem
  • References: github/qemu, 202005. tagbit{set|get} tag_bit_set will create a new tag block if the indexed block does not exist. tag_bit_get will return zero tags if the inidexed tag block does not exist. This is how the tag (efficiently) stored: it exists only after the tag has been set/initialized. Otherwise, it is assumed to be always zero tags and will not have a tag block to store their values.

  • Cheriops
  • ALL CHERI/MIPS Instructinos are declared as emulating functions in target/mips/helper.h, with macro DEF_HELPER_*. Implemented in target/mips/op_helper_cheri.c, using macro CHERI_HELPER_IMPL. For example, cseal instruction is declared as DEF_HELPER_4(cseal, void, env, i32, i32, i32), and implemented as void CHERI_HELPER_IMPL(cseal)(CPUMIPSState *env, uint32_t cd, uint32_t cs, uint32_t ct). capability runtime check instructions PCC check DEF_HELPER_2(ccheck_pc, void, env, i64) CHERI_HELPER_IMPL(ccheck_pc)(CPUMIPSState *env, uint64_t next_pc) DDC check will always be checked on ld/st without explicit instructions. see check_cap.

  • Basics
  • TCG Frontend Ops1 implements supported operations for the targe CPU (what QEMU executes; not where QEMU executes). [tcg/tcg.h]() contains frontend helpers. // file // tcg/tcg.h ALL CHERI/MIPS Instructinos are defined as emulating functions in target/mips/helper.h // file // target/mips/helper.h // QEMU-CHERI extension: DEF_HELPER_1(mfc0_rtc64, i64, env) DEF_HELPER_2(mtc0_rtc64, void, env, i64) // BERI extension: DEF_HELPER_1(mfc0_coreid, tl, env) DEF_HELPER_2(cheri_debug_message, void, env, i64) #if defined(TARGET_CHERI) DEF_HELPER_2(mtc2_dumpcstate, void, env, tl) DEF_HELPER_1(ccheck_btarget, void, env) DEF_HELPER_2(ccheck_pc, void, env, i64) DEF_HELPER_3(ccheck_store, tl, env, tl, i32) DEF_HELPER_3(ccheck_store_right, tl, env, tl, i32) DEF_HELPER_3(ccheck_load, tl, env, tl, i32) DEF_HELPER_3(ccheck_load_right, tl, env, tl, i32) DEF_HELPER_5(cinvalidate_tag, void, env, tl, i32, i32, tl) DEF_HELPER_5(cinvalidate_tag_left_right, void, env, tl, i32, i32, tl) DEF_HELPER_5(cinvalidate_tag32, void, env, tl, i32, i32, i32) DEF_HELPER_4(candperm, void, env, i32, i32, tl) DEF_HELPER_3(cbez, tl, env, i32, i32) DEF_HELPER_3(cbnz, tl, env, i32, i32) DEF_HELPER_3(cbts, tl, env, i32, i32) DEF_HELPER_3(cbtu, tl, env, i32, i32) DEF_HELPER_3(ccall, void, env, i32, i32) DEF_HELPER_3(ccall_notrap, tl, env, i32, i32) DEF_HELPER_3(ccheckperm, void, env, i32, tl) DEF_HELPER_3(cchecktype, void, env, i32, i32) DEF_HELPER_2(cclearreg, void, env, i32) DEF_HELPER_3(ccleartag, void, env, i32, i32) DEF_HELPER_4(cfromptr, void, env, i32, i32, tl) DEF_HELPER_2(cgetaddr, tl, env, i32) DEF_HELPER_2(cgetbase, tl, env, i32) DEF_HELPER_1(cgetcause, tl, env) DEF_HELPER_2(cgetlen, tl, env, i32) DEF_HELPER_2(cgetoffset, tl, env, i32) DEF_HELPER_2(cgetpcc, void, env, i32) DEF_HELPER_3(cgetpccsetoffset, void, env, i32, tl) DEF_HELPER_2(cgetperm, tl, env, i32) DEF_HELPER_2(cgetsealed, tl, env, i32) DEF_HELPER_2(cgettag, tl, env, i32) DEF_HELPER_2(cgettype, tl, env, i32) DEF_HELPER_4(cincbase, void, env, i32, i32, tl) DEF_HELPER_4(cincoffset, void, env, i32, i32, tl) DEF_HELPER_3(cjalr, tl, env, i32, i32) DEF_HELPER_2(cjr, tl, env, i32) DEF_HELPER_1(creturn, void, env) DEF_HELPER_4(cseal, void, env, i32, i32, i32) DEF_HELPER_4(ccseal, void, env, i32, i32, i32) DEF_HELPER_4(csetbounds, void, env, i32, i32, tl) DEF_HELPER_4(csetboundsexact, void, env, i32, i32, tl) DEF_HELPER_2(crap, tl, env, tl) DEF_HELPER_2(cram, tl, env, tl) DEF_HELPER_3(csub, tl, env, i32, i32) DEF_HELPER_2(csetcause, void, env, tl) DEF_HELPER_4(csetlen, void, env, i32, i32, tl) DEF_HELPER_4(csetoffset, void, env, i32, i32, tl) DEF_HELPER_3(ctoptr, tl, env, i32, i32) DEF_HELPER_4(cunseal, void, env, i32, i32, i32) DEF_HELPER_4(cmovz, void, env, i32, i32, tl) DEF_HELPER_4(cmovn, void, env, i32, i32, tl) DEF_HELPER_4(cbuildcap, void, env, i32, i32, i32) DEF_HELPER_4(ccopytype, void, env, i32, i32, i32) DEF_HELPER_3(creadhwr, void, env, i32, i32) DEF_HELPER_3(cwritehwr, void, env, i32, i32) DEF_HELPER_3(csealentry, void, env, i32, i32) DEF_HELPER_3(cloadtags, tl, env, i32, i64) DEF_HELPER_3(ceq, tl, env, i32, i32) DEF_HELPER_3(cne, tl, env, i32, i32) DEF_HELPER_3(clt, tl, env, i32, i32) DEF_HELPER_3(cle, tl, env, i32, i32) DEF_HELPER_3(cltu, tl, env, i32, i32) DEF_HELPER_3(cleu, tl, env, i32, i32) DEF_HELPER_3(cexeq, tl, env, i32, i32) DEF_HELPER_3(cnexeq, tl, env, i32, i32) DEF_HELPER_4(csetaddr, void, env, i32, i32, tl) DEF_HELPER_3(cgetandaddr, tl, env, i32, tl) DEF_HELPER_4(candaddr, void, env, i32, i32, tl) DEF_HELPER_3(ctestsubset, tl, env, i32, i32) DEF_HELPER_5(cload, tl, env, i32, tl, i32, i32) DEF_HELPER_5(cstore, tl, env, i32, tl, i32, i32) DEF_HELPER_3(cloadlinked, tl, env, i32, i32) DEF_HELPER_3(cstorecond, tl, env, i32, i32) DEF_HELPER_3(cscc_without_tcg, tl, env, i32, i32) DEF_HELPER_5(csc_without_tcg, void, env, i32, i32, tl, i32) DEF_HELPER_5(clc_without_tcg, void, env, i32, i32, tl, i32) DEF_HELPER_3(cllc_without_tcg, void, env, i32, i32) #endif #if defined(TARGET_CHERI) /* cannot access EPC directly since it is the offset of EPCC */ DEF_HELPER_1(mfc0_epc, tl, env) DEF_HELPER_2(mtc0_epc, void, env, tl) DEF_HELPER_1(mfc0_error_epc, tl, env) DEF_HELPER_2(mtc0_error_epc, void, env, tl) #endif #if defined(TARGET_CHERI) DEF_HELPER_2(rdhwr_statcounters_icount, tl, env, i32) DEF_HELPER_1(rdhwr_statcounters_reset, tl, env) DEF_HELPER_1(rdhwr_statcounters_itlb_miss, tl, env) DEF_HELPER_1(rdhwr_statcounters_dtlb_miss, tl, env) DEF_HELPER_2(rdhwr_statcounters_memory, tl, env, i32) DEF_HELPER_2(rdhwr_statcounters_ignored, tl, env, i32) #endif New instruction TCG frontend.

  • Build
  • Isaac: Just a quick FYI, since I just noticed this problem: Apparently, cheribuild hardcodes the git branch to use when building qemu, regardless of the –qemu/git-revision setting. A manual clone is needed to override. (I was wondering why my change to how $DDC was handled wasn’t reflected in the simulator. It turns out that I was building CTSRD’s branch, not my branch.)

Created Sep 19, 2019 // Last Updated May 18, 2021

If you could revise
the fundmental principles of
computer system design
to improve security...

... what would you change?