Skip to content

Commit

Permalink
redo addr dump interface to make it possible for ECPT
Browse files Browse the repository at this point in the history
  • Loading branch information
siyuanchai1999 committed Jan 30, 2024
1 parent 09beb36 commit 3dd075f
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 68 deletions.
12 changes: 4 additions & 8 deletions accel/tcg/cputlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1287,13 +1287,10 @@ static inline ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
}

static unsigned long tlb_fill_pgtables(CPUState *cpu, target_ulong addr, int size,
int mmu_idx, unsigned long *cr3, unsigned long *pud,
unsigned long *pmd, unsigned long *pte,
unsigned int *page_size, unsigned long *entry) {
int mmu_idx, void * trans_info) {
CPUClass *cc = CPU_GET_CLASS(cpu);
return cc->tcg_ops->tlb_fill_pgtables(cpu, addr, size, mmu_idx, cr3, pud, pmd, pte, page_size, entry);
return cc->tcg_ops->tlb_fill_pgtables(cpu, addr, size, mmu_idx, trans_info);
}

/*
* Note: tlb_fill() can trigger a resize of the TLB. This means that all of the
* caller's prior references to the TLB table (e.g. CPUTLBEntry pointers) must
Expand Down Expand Up @@ -1498,13 +1495,12 @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
* Returns guest virtual address, or ~0 on failure.
*/
unsigned long translate_guest_virtual(CPUArchState *env, target_ulong addr,
unsigned long *cr3, unsigned long *pud, unsigned long *pmd,
unsigned long *pte, unsigned int *size, unsigned long *entry)
void *trans_info)
{
uintptr_t mmu_idx = cpu_mmu_index(env, true); //the second param is unused on x86

/* guest physical. */
return tlb_fill_pgtables(env_cpu(env), addr, 0, mmu_idx, cr3, pud, pmd, pte, size, entry);
return tlb_fill_pgtables(env_cpu(env), addr, 0, mmu_idx, trans_info);
}


Expand Down
4 changes: 2 additions & 2 deletions include/exec/exec-all.h
Original file line number Diff line number Diff line change
Expand Up @@ -708,9 +708,9 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr);
*/
tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr,
void **hostp);

unsigned long translate_guest_virtual(CPUArchState *env, target_ulong addr,
unsigned long *cr3, unsigned long *pud, unsigned long *pmd,
unsigned long *pte, unsigned int *size, unsigned long *entry);
void *trans_info);

void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length);
void tlb_set_dirty(CPUState *cpu, target_ulong vaddr);
Expand Down
16 changes: 16 additions & 0 deletions include/exec/memop.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,20 @@ static inline bool memop_big_endian(MemOp op)
return (op & MO_BSWAP) == MO_BE;
}


#ifndef PAGE_TABLE_LEAVES
#define PAGE_TABLE_LEAVES 4
#endif
typedef struct MemRecord
{
uint8_t header;
uint8_t access_rw;
uint16_t access_cpu;
uint32_t access_sz;
uint64_t vaddr;
uint64_t paddr;
uint64_t pte;
uint64_t leaves[PAGE_TABLE_LEAVES];
} MemRecord;

#endif
5 changes: 2 additions & 3 deletions include/hw/core/tcg-cpu-ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,9 @@ struct TCGCPUOps {
* not return. For user-only mode, always raise an exception
* and do not return.
*/

unsigned long (*tlb_fill_pgtables)(CPUState *cpu, vaddr addr, int size,
int mmu_idx, unsigned long *cr3, unsigned long *pud,
unsigned long *pmd, unsigned long *pte,
unsigned int *page_size, unsigned long *entry);
int mmu_idx, void *trans_info);
bool (*tlb_fill)(CPUState *cpu, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr);
Expand Down
6 changes: 2 additions & 4 deletions include/qemu/qemu-plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -484,10 +484,8 @@ const char *qemu_plugin_hwaddr_device_name(const struct qemu_plugin_hwaddr *h);
* Get page walk information on each level
*/

unsigned long qemu_plugin_pa_by_va(const unsigned long vaddr, unsigned long *cr3,
unsigned long *pud, unsigned long *pmd,
unsigned long *pte, unsigned int *size, unsigned long *entry);

unsigned long qemu_plugin_pa_by_va(const unsigned long vaddr, void * trans_info);

unsigned long qemu_plugin_read_cr3(void);
void qemu_plugin_vm_shutdown(void);

Expand Down
7 changes: 2 additions & 5 deletions plugins/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,14 +327,11 @@ uint64_t qemu_plugin_hwaddr_phys_addr(const struct qemu_plugin_hwaddr *haddr)
return 0;
}

unsigned long qemu_plugin_pa_by_va(const unsigned long vaddr, unsigned long *cr3,
unsigned long *pud, unsigned long *pmd,
unsigned long *pte, unsigned int *size, unsigned long *entry)
unsigned long qemu_plugin_pa_by_va(const unsigned long vaddr, void * trans_info)
{
CPUState *cpu = current_cpu;
return translate_guest_virtual(cpu->env_ptr, vaddr, cr3, pud, pmd, pte, size, entry);
return translate_guest_virtual(cpu->env_ptr, vaddr, trans_info);
}

unsigned long qemu_plugin_read_cr3(void)
{
CPUState *cpu = current_cpu;
Expand Down
4 changes: 1 addition & 3 deletions target/i386/tcg/helper-tcg.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@ bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);


unsigned long x86_tlb_fill_pgtables(CPUState *cs, vaddr addr, int size,
int mmu_idx, unsigned long *cr3, unsigned long *pud,
unsigned long *pmd, unsigned long *pte,
unsigned int *page_size, unsigned long *entry);
int mmu_idx, void * trans_info);

/* helper.c */
bool x86_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
Expand Down
12 changes: 6 additions & 6 deletions target/i386/tcg/sysemu/excp_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1445,14 +1445,14 @@ static int handle_mmu_fault(CPUState *cs, vaddr addr, int size,
}

unsigned long x86_tlb_fill_pgtables(CPUState *cs, vaddr addr, int size,
int mmu_idx, unsigned long *cr3, unsigned long *pud,
unsigned long *pmd, unsigned long *pte,
unsigned int *page_size, unsigned long *entry) {
int mmu_idx, void * trans_info) {

X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;
int pg_mode;
hwaddr paddr;

MemRecord * rec = (MemRecord *) trans_info;
unsigned int page_size = 0;
if (!(env->cr[0] & CR0_PG_MASK)) {
paddr = addr;
if (!(env->hflags & HF_LMA_MASK)) {
Expand All @@ -1462,8 +1462,8 @@ unsigned long x86_tlb_fill_pgtables(CPUState *cs, vaddr addr, int size,
} else {
pg_mode = get_pg_mode(env);
paddr = mmu_translate_pgtables(cs, addr, get_hphys, env->cr[3],
mmu_idx, pg_mode,
cr3, pud, pmd, pte, page_size, entry);
mmu_idx, pg_mode,
&rec->leaves[0], &rec->leaves[1], &rec->leaves[2], &rec->leaves[3], &page_size, &rec->pte);
}

return paddr;
Expand Down
44 changes: 7 additions & 37 deletions tests/plugin/execlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
#ifndef MAX_CPU_COUNT
#define MAX_CPU_COUNT 64
#endif

// Maximum number of instruction recorded
#ifndef MAX_INS_COUNT
#define MAX_INS_COUNT (3000000000UL) // 3 billion
Expand All @@ -45,11 +45,6 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
#define FRONTEND_FETCH_SIZE (16UL)
#endif

// Number of translation accesses in a single walk
#ifndef PAGE_TABLE_LEAVES
#define PAGE_TABLE_LEAVES 4
#endif

// Name of the log file
#ifndef DEFAULT_BIN_RECORD_FILE_NAME
#define DEFAULT_BIN_RECORD_FILE_NAME "walk_log.bin"
Expand Down Expand Up @@ -111,18 +106,6 @@ typedef struct FileHandle
FILE* fp;
} FileHandle;

typedef struct MemRecord
{
uint8_t header;
uint8_t access_rw;
uint16_t access_cpu;
uint32_t access_sz;
uint64_t vaddr;
uint64_t paddr;
uint64_t pte;
uint64_t leaves[PAGE_TABLE_LEAVES];
} MemRecord;

typedef struct InsRecord
{
uint8_t header;
Expand Down Expand Up @@ -291,7 +274,6 @@ static void vcpu_mem(unsigned int cpu_index, qemu_plugin_meminfo_t info,
uint64_t vaddr, void *udata)
{
MemRecord rec;
uint32_t discard;

if (!should_do_logging()) {
return;
Expand All @@ -302,14 +284,8 @@ static void vcpu_mem(unsigned int cpu_index, qemu_plugin_meminfo_t info,
rec.access_cpu = cpu_index % MAX_CPU_COUNT; /* dummy field for now. introduced because of different QEMU version @jiyuan */
rec.access_sz = 1 << qemu_plugin_mem_size_shift(info);
rec.vaddr = vaddr;
rec.paddr = qemu_plugin_pa_by_va(vaddr,
&rec.leaves[0],
&rec.leaves[1],
&rec.leaves[2],
&rec.leaves[3],
&discard,
&rec.pte
);
rec.paddr = qemu_plugin_pa_by_va(vaddr,
(void *)&rec);
// printf("Radix Translate: vaddr=%lx PTE0=%lx PTE1=%lx PTE2=%lx "
// "PTE3=%lx paddr=%lx access_rw=%d access_cpu=%d access_sz=%d\n",
// rec.vaddr, rec.leaves[0], rec.leaves[1], rec.leaves[2], rec.leaves[3],
Expand Down Expand Up @@ -404,16 +380,10 @@ static void vcpu_insn_fetch(unsigned int cpu_index, void *udata)
rec.access_cpu = cpu;
rec.access_sz = FRONTEND_FETCH_SIZE;
rec.vaddr = ins_line;
rec.paddr = qemu_plugin_pa_by_va(ins_line,
&rec.leaves[0],
&rec.leaves[1],
&rec.leaves[2],
&rec.leaves[3],
&cpu, // cpu is no longer used, so just reuse it here
&rec.pte
);

write_ins_fetch(&rec);
rec.paddr = qemu_plugin_pa_by_va(ins_line,
(void *)&rec);

write_ins_fetch(&rec);

if (BIN_RECORD_INCL_DECD)
vcpu_insn_exec(cpu_index, udata);
Expand Down

0 comments on commit 3dd075f

Please sign in to comment.