From e98c731550569f5dd5c0d12eebe3aaea20481361 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 16 May 2019 17:23:42 -0400 Subject: [PATCH] target/riscv: Convert to CPUClass::tlb_fill Note that env->pc is removed from the qemu_log as that value is garbage. The PC isn't recovered until cpu_restore_state, called from cpu_loop_exit_restore, called from riscv_raise_exception. Backports commit 8a4ca3c10a96be6ed7f023b685b688c4d409bbcb from qemu --- qemu/header_gen.py | 2 +- qemu/riscv32.h | 2 +- qemu/riscv64.h | 2 +- qemu/target/riscv/cpu.c | 5 ++-- qemu/target/riscv/cpu.h | 5 ++-- qemu/target/riscv/cpu_helper.c | 46 ++++++++++++++++------------------ 6 files changed, 29 insertions(+), 33 deletions(-) diff --git a/qemu/header_gen.py b/qemu/header_gen.py index a2e48ebb..a0585551 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -5527,12 +5527,12 @@ riscv_symbols = ( 'riscv_cpu_exec_interrupt', 'riscv_cpu_get_fflags', 'riscv_cpu_get_phys_page_debug', - 'riscv_cpu_handle_mmu_fault', 'riscv_cpu_list', 'riscv_cpu_mmu_index', 'riscv_cpu_register_types', 'riscv_cpu_set_fflags', 'riscv_cpu_set_mode', + 'riscv_cpu_tlb_fill', 'riscv_cpu_update_mip', 'riscv_csrrw', 'riscv_csrrw_debug', diff --git a/qemu/riscv32.h b/qemu/riscv32.h index c36ae194..993149b0 100644 --- a/qemu/riscv32.h +++ b/qemu/riscv32.h @@ -3444,12 +3444,12 @@ #define riscv_cpu_exec_interrupt riscv_cpu_exec_interrupt_riscv32 #define riscv_cpu_get_fflags riscv_cpu_get_fflags_riscv32 #define riscv_cpu_get_phys_page_debug riscv_cpu_get_phys_page_debug_riscv32 -#define riscv_cpu_handle_mmu_fault riscv_cpu_handle_mmu_fault_riscv32 #define riscv_cpu_list riscv_cpu_list_riscv32 #define riscv_cpu_mmu_index riscv_cpu_mmu_index_riscv32 #define riscv_cpu_register_types riscv_cpu_register_types_riscv32 #define riscv_cpu_set_fflags riscv_cpu_set_fflags_riscv32 #define riscv_cpu_set_mode riscv_cpu_set_mode_riscv32 +#define riscv_cpu_tlb_fill riscv_cpu_tlb_fill_riscv32 #define riscv_cpu_update_mip riscv_cpu_update_mip_riscv32 #define riscv_csrrw riscv_csrrw_riscv32 #define riscv_csrrw_debug riscv_csrrw_debug_riscv32 diff --git a/qemu/riscv64.h b/qemu/riscv64.h index ddaff0b5..98fc1eeb 100644 --- a/qemu/riscv64.h +++ b/qemu/riscv64.h @@ -3444,12 +3444,12 @@ #define riscv_cpu_exec_interrupt riscv_cpu_exec_interrupt_riscv64 #define riscv_cpu_get_fflags riscv_cpu_get_fflags_riscv64 #define riscv_cpu_get_phys_page_debug riscv_cpu_get_phys_page_debug_riscv64 -#define riscv_cpu_handle_mmu_fault riscv_cpu_handle_mmu_fault_riscv64 #define riscv_cpu_list riscv_cpu_list_riscv64 #define riscv_cpu_mmu_index riscv_cpu_mmu_index_riscv64 #define riscv_cpu_register_types riscv_cpu_register_types_riscv64 #define riscv_cpu_set_fflags riscv_cpu_set_fflags_riscv64 #define riscv_cpu_set_mode riscv_cpu_set_mode_riscv64 +#define riscv_cpu_tlb_fill riscv_cpu_tlb_fill_riscv64 #define riscv_cpu_update_mip riscv_cpu_update_mip_riscv64 #define riscv_csrrw riscv_csrrw_riscv64 #define riscv_csrrw_debug riscv_csrrw_debug_riscv64 diff --git a/qemu/target/riscv/cpu.c b/qemu/target/riscv/cpu.c index 88afcb3f..20301193 100644 --- a/qemu/target/riscv/cpu.c +++ b/qemu/target/riscv/cpu.c @@ -344,14 +344,13 @@ static void riscv_cpu_class_init(struct uc_struct *uc, ObjectClass *oc, void *da //cc->gdb_num_core_regs = 65; //cc->gdb_stop_before_watchpoint = true; //cc->disas_set_info = riscv_cpu_disas_set_info; -#ifdef CONFIG_USER_ONLY - cc->handle_mmu_fault = riscv_cpu_handle_mmu_fault; -#else +#ifndef CONFIG_USER_ONLY cc->do_unaligned_access = riscv_cpu_do_unaligned_access; cc->get_phys_page_debug = riscv_cpu_get_phys_page_debug; #endif #ifdef CONFIG_TCG cc->tcg_initialize = riscv_translate_init; + cc->tlb_fill = riscv_cpu_tlb_fill; #endif /* For now, mark unmigratable: */ //cc->vmsd = &vmstate_riscv_cpu; diff --git a/qemu/target/riscv/cpu.h b/qemu/target/riscv/cpu.h index e5122665..4d0ed9e1 100644 --- a/qemu/target/riscv/cpu.h +++ b/qemu/target/riscv/cpu.h @@ -266,8 +266,9 @@ hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr); -int riscv_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, - int rw, int mmu_idx); +bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, + MMUAccessType access_type, int mmu_idx, + bool probe, uintptr_t retaddr); char *riscv_isa_string(RISCVCPU *cpu); void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf); diff --git a/qemu/target/riscv/cpu_helper.c b/qemu/target/riscv/cpu_helper.c index a63f7eca..7d1bb1ce 100644 --- a/qemu/target/riscv/cpu_helper.c +++ b/qemu/target/riscv/cpu_helper.c @@ -380,53 +380,49 @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr, riscv_raise_exception(env, cs->exception_index, retaddr); } -/* called by qemu's softmmu to fill the qemu tlb */ void tlb_fill(CPUState *cs, target_ulong addr, int size, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr) { - int ret; - ret = riscv_cpu_handle_mmu_fault(cs, addr, size, access_type, mmu_idx); - if (ret == TRANSLATE_FAIL) { - RISCVCPU *cpu = RISCV_CPU(cs->uc, cs); - CPURISCVState *env = &cpu->env; - riscv_raise_exception(env, cs->exception_index, retaddr); - } + riscv_cpu_tlb_fill(cs, addr, size, access_type, mmu_idx, false, retaddr); } - #endif -int riscv_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, - int rw, int mmu_idx) +bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, + MMUAccessType access_type, int mmu_idx, + bool probe, uintptr_t retaddr) { +#ifndef CONFIG_USER_ONLY RISCVCPU *cpu = RISCV_CPU(cs->uc, cs); CPURISCVState *env = &cpu->env; -#if !defined(CONFIG_USER_ONLY) hwaddr pa = 0; int prot; -#endif int ret = TRANSLATE_FAIL; - qemu_log_mask(CPU_LOG_MMU, - "%s pc " TARGET_FMT_lx " ad %" VADDR_PRIx " rw %d mmu_idx \ - %d\n", __func__, env->pc, address, rw, mmu_idx); + qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n", + __func__, address, access_type, mmu_idx); + + ret = get_physical_address(env, &pa, &prot, address, access_type, mmu_idx); -#if !defined(CONFIG_USER_ONLY) - ret = get_physical_address(env, &pa, &prot, address, rw, mmu_idx); qemu_log_mask(CPU_LOG_MMU, - "%s address=%" VADDR_PRIx " ret %d physical " TARGET_FMT_plx - " prot %d\n", __func__, address, ret, pa, prot); + "%s address=%" VADDR_PRIx " ret %d physical " TARGET_FMT_plx + " prot %d\n", __func__, address, ret, pa, prot); + if (riscv_feature(env, RISCV_FEATURE_PMP) && - !pmp_hart_has_privs(env, pa, TARGET_PAGE_SIZE, 1 << rw)) { + !pmp_hart_has_privs(env, pa, TARGET_PAGE_SIZE, 1 << access_type)) { ret = TRANSLATE_FAIL; } if (ret == TRANSLATE_SUCCESS) { tlb_set_page(cs, address & TARGET_PAGE_MASK, pa & TARGET_PAGE_MASK, prot, mmu_idx, TARGET_PAGE_SIZE); - } else if (ret == TRANSLATE_FAIL) { - raise_mmu_exception(env, address, rw); + return true; + } else if (probe) { + return false; + } else { + raise_mmu_exception(env, address, access_type); + riscv_raise_exception(env, cs->exception_index, retaddr); } #else - switch (rw) { + switch (access_type) { case MMU_INST_FETCH: cs->exception_index = RISCV_EXCP_INST_PAGE_FAULT; break; @@ -437,8 +433,8 @@ int riscv_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, cs->exception_index = RISCV_EXCP_STORE_PAGE_FAULT; break; } + cpu_loop_exit_restore(cs, retaddr); #endif - return ret; } /*