Skip to content

Commit

Permalink
change softmmu model
Browse files Browse the repository at this point in the history
  • Loading branch information
lacraig2 committed Mar 23, 2022
1 parent 4f504b1 commit fcd9ff7
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 45 deletions.
3 changes: 2 additions & 1 deletion include/exec/cpu_ldst.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@

/* The memory helpers for tcg-generated code need tcg_target_long etc. */
#include "tcg.h"

#define PANDA_DO_CBS_DATA_ACCESS
#ifdef MMU_MODE0_SUFFIX
#define CPU_MMU_INDEX 0
#define MEMSUFFIX MMU_MODE0_SUFFIX
Expand Down Expand Up @@ -359,6 +359,7 @@
#include "exec/cpu_ldst_template.h"
#undef CPU_MMU_INDEX
#undef MEMSUFFIX
#undef PANDA_DO_CBS_DATA_ACCESS

#define CPU_MMU_INDEX (cpu_mmu_index(env, true))
#define MEMSUFFIX _code
Expand Down
48 changes: 48 additions & 0 deletions include/exec/cpu_ldst_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,21 @@
#define SRETSUFFIX glue(s, SUFFIX)
#endif

#ifndef CONFIG_SOFTMMU_EXTERN_VAR_ONCE
#define CONFIG_SOFTMMU_EXTERN_VAR_ONCE
extern bool panda_use_memcb;
#endif

#ifndef MEM_CBS_REFERENCED
#define MEM_CBS_REFERENCED
#define target_ptr_t target_ulong
extern void panda_callbacks_mem_before_read(CPUState *env, target_ptr_t pc, target_ptr_t addr, size_t data_size, void *ram_ptr);
extern void panda_callbacks_mem_after_read(CPUState *env, target_ptr_t pc, target_ptr_t addr, size_t data_size, uint64_t result, void *ram_ptr);
extern void panda_callbacks_mem_before_write(CPUState *env, target_ptr_t pc, target_ptr_t addr, size_t data_size, uint64_t val, void *ram_ptr);
extern void panda_callbacks_mem_after_write(CPUState *env, target_ptr_t pc, target_ptr_t addr, size_t data_size, uint64_t val, void *ram_ptr);
#endif


/* generic load/store macros */

static inline RES_TYPE
Expand Down Expand Up @@ -103,7 +118,18 @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
oi, retaddr);
} else {
uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
#if defined(PANDA_DO_CBS_DATA_ACCESS)
if (likely(!panda_use_memcb)){
res = glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr);
}else{
CPUState *cpu = ENV_GET_CPU(env);
panda_callbacks_mem_before_read(cpu, cpu->panda_guest_pc, addr, DATA_SIZE, (void *)hostaddr);
res = glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr);
panda_callbacks_mem_after_read(cpu, cpu->panda_guest_pc, addr, DATA_SIZE, (uint64_t)res, (void *)hostaddr);
}
#else
res = glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr);
#endif
}
return res;
}
Expand Down Expand Up @@ -141,7 +167,18 @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
MMUSUFFIX)(env, addr, oi, retaddr);
} else {
uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
#if defined(PANDA_DO_CBS_DATA_ACCESS)
if (likely(!panda_use_memcb)){
res = glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr);
}else{
CPUState *cpu = ENV_GET_CPU(env);
panda_callbacks_mem_before_read(cpu, cpu->panda_guest_pc, addr, DATA_SIZE, (void *)hostaddr);
res = glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr);
panda_callbacks_mem_after_read(cpu, cpu->panda_guest_pc, addr, DATA_SIZE, (uint64_t)res, (void *)hostaddr);
}
#else
res = glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr);
#endif
}
return res;
}
Expand Down Expand Up @@ -183,7 +220,18 @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
retaddr);
} else {
uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
#if defined(PANDA_DO_CBS_DATA_ACCESS)
if (likely(!panda_use_memcb)){
glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v);
}else{
CPUState *cpu = ENV_GET_CPU(env);
panda_callbacks_mem_before_write(cpu, cpu->panda_guest_pc, addr, DATA_SIZE, (uint64_t)v, (void *)hostaddr);
glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v);
panda_callbacks_mem_after_write(cpu, cpu->panda_guest_pc, addr, DATA_SIZE, (uint64_t)v, (void *)hostaddr);
}
#else
glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v);
#endif
}
}

Expand Down
4 changes: 4 additions & 0 deletions panda/include/panda/callbacks/cb-support.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,15 @@ exit 0
// If this file is included from a file that doesn't define TranslationBlock (e.g., memory.c), we still need to be valid
typedef struct {} TranslationBlock;
#endif

#ifndef MEM_CBS_REFERENCED
#define MEM_CBS_REFERENCED
/* shared helpers for virtual/physical memory callbacks */
void panda_callbacks_mem_before_read(CPUState *env, target_ptr_t pc, target_ptr_t addr, size_t data_size, void *ram_ptr);
void panda_callbacks_mem_after_read(CPUState *env, target_ptr_t pc, target_ptr_t addr, size_t data_size, uint64_t result, void *ram_ptr);
void panda_callbacks_mem_before_write(CPUState *env, target_ptr_t pc, target_ptr_t addr, size_t data_size, uint64_t val, void *ram_ptr);
void panda_callbacks_mem_after_write(CPUState *env, target_ptr_t pc, target_ptr_t addr, size_t data_size, uint64_t val, void *ram_ptr);
#endif

/* invoked from cpu-exec.c */
void panda_callbacks_before_find_fast(void);
Expand Down
3 changes: 3 additions & 0 deletions panda/include/panda/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@ void panda_unload_plugin_idx(int idx);
void panda_unload_plugins(void);

extern bool panda_update_pc;
#ifndef CONFIG_SOFTMMU_EXTERN_VAR_ONCE
#define CONFIG_SOFTMMU_EXTERN_VAR_ONCE
extern bool panda_use_memcb;
#endif
extern panda_cb_list *panda_cbs[PANDA_CB_LAST];
extern bool panda_plugins_to_unload[MAX_PANDA_PLUGINS];
extern bool panda_plugin_to_unload;
Expand Down
99 changes: 79 additions & 20 deletions softmmu_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
#error unsupported data size
#endif

#ifndef CONFIG_SOFTMMU_EXTERN_VAR_ONCE
#define CONFIG_SOFTMMU_EXTERN_VAR_ONCE
extern bool panda_use_memcb;
#endif

/* For the benefit of TCG generated code, we want to avoid the complication
of ABI-specific return type promotion and always return a value extended
Expand Down Expand Up @@ -105,7 +109,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
}
#endif

WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
static inline WORD_TYPE glue(helper_le_ld_name,_internal)(CPUArchState *env, target_ulong addr,
TCGMemOpIdx oi, uintptr_t retaddr)
{
unsigned mmu_idx = get_mmuidx(oi);
Expand Down Expand Up @@ -153,8 +157,8 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
do_unaligned_access:
addr1 = addr & ~(DATA_SIZE - 1);
addr2 = addr1 + DATA_SIZE;
res1 = helper_le_ld_name(env, addr1, oi, retaddr);
res2 = helper_le_ld_name(env, addr2, oi, retaddr);
res1 = glue(helper_le_ld_name,_internal)(env, addr1, oi, retaddr);
res2 = glue(helper_le_ld_name,_internal)(env, addr2, oi, retaddr);
shift = (addr & (DATA_SIZE - 1)) * 8;

/* Little-endian combine. */
Expand All @@ -173,7 +177,8 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
}

#if DATA_SIZE > 1
WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,

static inline WORD_TYPE glue(helper_be_ld_name,_internal)(CPUArchState *env, target_ulong addr,
TCGMemOpIdx oi, uintptr_t retaddr)
{
unsigned mmu_idx = get_mmuidx(oi);
Expand Down Expand Up @@ -221,8 +226,8 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
do_unaligned_access:
addr1 = addr & ~(DATA_SIZE - 1);
addr2 = addr1 + DATA_SIZE;
res1 = helper_be_ld_name(env, addr1, oi, retaddr);
res2 = helper_be_ld_name(env, addr2, oi, retaddr);
res1 = glue(helper_be_ld_name,_internal)(env, addr1, oi, retaddr);
res2 = glue(helper_be_ld_name,_internal)(env, addr2, oi, retaddr);
shift = (addr & (DATA_SIZE - 1)) * 8;

/* Big-endian combine. */
Expand Down Expand Up @@ -266,7 +271,7 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
return io_writex(env, iotlbentry, val, addr, retaddr, DATA_SIZE);
}

void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
static inline void glue(helper_le_st_name,_internal)(CPUArchState *env, target_ulong addr, DATA_TYPE val,
TCGMemOpIdx oi, uintptr_t retaddr)
{
unsigned mmu_idx = get_mmuidx(oi);
Expand Down Expand Up @@ -327,7 +332,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
for (i = 0; i < DATA_SIZE; ++i) {
/* Little-endian extract. */
uint8_t val8 = val >> (i * 8);
glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8,
glue(glue(helper_ret_stb, MMUSUFFIX),_internal)(env, addr + i, val8,
oi, retaddr);
}
return;
Expand All @@ -342,7 +347,8 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
}

#if DATA_SIZE > 1
void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
static inline void glue(helper_be_st_name, _internal)(CPUArchState *env, target_ulong addr,
DATA_TYPE val,
TCGMemOpIdx oi, uintptr_t retaddr)
{
unsigned mmu_idx = get_mmuidx(oi);
Expand Down Expand Up @@ -403,7 +409,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
for (i = 0; i < DATA_SIZE; ++i) {
/* Big-endian extract. */
uint8_t val8 = val >> (((DATA_SIZE - 1) * 8) - (i * 8));
glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8,
glue(glue(helper_ret_stb, MMUSUFFIX),_internal)(env, addr + i, val8,
oi, retaddr);
}
return;
Expand All @@ -414,9 +420,12 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
}
#endif /* DATA_SIZE > 1 */

WORD_TYPE glue(helper_le_ld_name, _panda)(CPUArchState *env, target_ulong addr,
WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
TCGMemOpIdx oi, uintptr_t retaddr)
{
if (likely(!panda_use_memcb)){
return glue(helper_le_ld_name, _internal)(env, addr, oi, retaddr);
}
unsigned mmu_idx = get_mmuidx(oi);
int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_read;
Expand All @@ -437,15 +446,25 @@ WORD_TYPE glue(helper_le_ld_name, _panda)(CPUArchState *env, target_ulong addr,
}

panda_callbacks_mem_before_read(cpu, panda_current_pc(cpu), addr, DATA_SIZE, (void *)haddr);
WORD_TYPE ret = helper_le_ld_name(env, addr, oi, retaddr);
WORD_TYPE ret = glue(helper_le_ld_name, _internal)(env, addr, oi, retaddr);
panda_callbacks_mem_after_read(cpu, panda_current_pc(cpu), addr, DATA_SIZE, (uint64_t)ret, (void *)haddr);
return ret;
}

void glue(helper_le_st_name, _panda)(CPUArchState *env, target_ulong addr,
WORD_TYPE glue(helper_le_ld_name, _panda)(CPUArchState *env, target_ulong addr,
TCGMemOpIdx oi, uintptr_t retaddr)
{
return helper_le_ld_name(env, addr, oi, retaddr);
}

void helper_le_st_name(CPUArchState *env, target_ulong addr,
DATA_TYPE val, TCGMemOpIdx oi,
uintptr_t retaddr)
{
if (likely(!panda_use_memcb)){
glue(helper_le_st_name,_internal)(env, addr, val, oi, retaddr);
return;
}
unsigned mmu_idx = get_mmuidx(oi);
int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
Expand All @@ -466,14 +485,23 @@ void glue(helper_le_st_name, _panda)(CPUArchState *env, target_ulong addr,
}

panda_callbacks_mem_before_write(cpu, panda_current_pc(cpu), addr, DATA_SIZE, (uint64_t)val, (void *)haddr);
helper_le_st_name(env, addr, val, oi, retaddr);
glue(helper_le_st_name, _internal)(env, addr, val, oi, retaddr);
panda_callbacks_mem_after_write(cpu, panda_current_pc(cpu), addr, DATA_SIZE, (uint64_t)val, (void *)haddr);
}

void glue(helper_le_st_name, _panda)(CPUArchState *env, target_ulong addr,
DATA_TYPE val, TCGMemOpIdx oi,
uintptr_t retaddr){
return helper_le_st_name(env, addr, val, oi, retaddr);
}

#if DATA_SIZE > 1
WORD_TYPE glue(helper_be_ld_name, _panda)(CPUArchState *env, target_ulong addr,
WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
TCGMemOpIdx oi, uintptr_t retaddr)
{
if (likely(!panda_use_memcb)){
return glue(helper_be_ld_name,_internal)(env, addr, oi, retaddr);
}
unsigned mmu_idx = get_mmuidx(oi);
int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_read;
Expand All @@ -494,15 +522,24 @@ WORD_TYPE glue(helper_be_ld_name, _panda)(CPUArchState *env, target_ulong addr,
}

panda_callbacks_mem_before_read(cpu, panda_current_pc(cpu), addr, DATA_SIZE, (void *)haddr);
WORD_TYPE ret = helper_be_ld_name(env, addr, oi, retaddr);
WORD_TYPE ret = glue(helper_be_ld_name, _internal)(env, addr, oi, retaddr);
panda_callbacks_mem_after_read(cpu, panda_current_pc(cpu), addr, DATA_SIZE, (uint64_t)ret, (void *)haddr);
return ret;
}

void glue(helper_be_st_name, _panda)(CPUArchState *env, target_ulong addr,
DATA_TYPE val, TCGMemOpIdx oi,
uintptr_t retaddr)
WORD_TYPE glue(helper_be_ld_name, _panda)(CPUArchState *env, target_ulong addr,
TCGMemOpIdx oi, uintptr_t retaddr)
{
return helper_be_ld_name(env, addr, oi, retaddr);
}

void helper_be_st_name(CPUArchState *env, target_ulong addr,
DATA_TYPE val, TCGMemOpIdx oi,
uintptr_t retaddr){
if (likely(!panda_use_memcb)){
glue(helper_be_st_name,_internal)(env, addr, val, oi, retaddr);
return;
}
unsigned mmu_idx = get_mmuidx(oi);
int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
Expand All @@ -523,11 +560,33 @@ void glue(helper_be_st_name, _panda)(CPUArchState *env, target_ulong addr,
}

panda_callbacks_mem_before_write(cpu, panda_current_pc(cpu), addr, DATA_SIZE, (uint64_t)val, (void *)haddr);
helper_be_st_name(env, addr, val, oi, retaddr);
glue(helper_be_st_name, _internal)(env, addr, val, oi, retaddr);
panda_callbacks_mem_after_write(cpu, panda_current_pc(cpu), addr, DATA_SIZE, (uint64_t)val, (void *)haddr);
}

void glue(helper_be_st_name, _panda)(CPUArchState *env, target_ulong addr,
DATA_TYPE val, TCGMemOpIdx oi,
uintptr_t retaddr){
return helper_be_st_name(env, addr, val, oi, retaddr);
}

#endif /* DATA_SIZE > 1 */
#else
WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
TCGMemOpIdx oi, uintptr_t retaddr)
{
return glue(helper_le_ld_name,_internal)(env, addr, oi, retaddr);
}

#if DATA_SIZE > 1

WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
TCGMemOpIdx oi, uintptr_t retaddr)
{
return glue(helper_be_ld_name,_internal)(env, addr, oi, retaddr);
}

#endif
#endif /* !defined(SOFTMMU_CODE_ACCESS) */

#undef READ_ACCESS_TYPE
Expand Down
27 changes: 3 additions & 24 deletions tcg/i386/tcg-target.inc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1220,7 +1220,7 @@ extern bool panda_use_memcb;
* int mmu_idx, uintptr_t ra)
*/

static void * const qemu_ld_helpers_normal[16] = {
static void * const qemu_ld_helpers[16] = {
[MO_UB] = helper_ret_ldub_mmu,
[MO_LEUW] = helper_le_lduw_mmu,
[MO_LEUL] = helper_le_ldul_mmu,
Expand All @@ -1229,23 +1229,13 @@ static void * const qemu_ld_helpers_normal[16] = {
[MO_BEUL] = helper_be_ldul_mmu,
[MO_BEQ] = helper_be_ldq_mmu,
};
static void * const qemu_ld_helpers_panda[16] = {
[MO_UB] = helper_ret_ldub_mmu_panda,
[MO_LEUW] = helper_le_lduw_mmu_panda,
[MO_LEUL] = helper_le_ldul_mmu_panda,
[MO_LEQ] = helper_le_ldq_mmu_panda,
[MO_BEUW] = helper_be_lduw_mmu_panda,
[MO_BEUL] = helper_be_ldul_mmu_panda,
[MO_BEQ] = helper_be_ldq_mmu_panda,
};
#define qemu_ld_helpers \
(panda_use_memcb ? qemu_ld_helpers_panda : qemu_ld_helpers_normal)


/* helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr,
* uintxx_t val, int mmu_idx, uintptr_t ra)
*/

static void * const qemu_st_helpers_normal[16] = {
static void * const qemu_st_helpers[16] = {
[MO_UB] = helper_ret_stb_mmu,
[MO_LEUW] = helper_le_stw_mmu,
[MO_LEUL] = helper_le_stl_mmu,
Expand All @@ -1254,17 +1244,6 @@ static void * const qemu_st_helpers_normal[16] = {
[MO_BEUL] = helper_be_stl_mmu,
[MO_BEQ] = helper_be_stq_mmu,
};
static void * const qemu_st_helpers_panda[16] = {
[MO_UB] = helper_ret_stb_mmu_panda,
[MO_LEUW] = helper_le_stw_mmu_panda,
[MO_LEUL] = helper_le_stl_mmu_panda,
[MO_LEQ] = helper_le_stq_mmu_panda,
[MO_BEUW] = helper_be_stw_mmu_panda,
[MO_BEUL] = helper_be_stl_mmu_panda,
[MO_BEQ] = helper_be_stq_mmu_panda,
};
#define qemu_st_helpers \
(panda_use_memcb ? qemu_st_helpers_panda : qemu_st_helpers_normal)

/* Perform the TLB load and compare.
Expand Down

0 comments on commit fcd9ff7

Please sign in to comment.