diff --git a/qemu/aarch64.h b/qemu/aarch64.h index ab991a7f..70f44343 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -23,6 +23,7 @@ #define address_space_stq_le address_space_stq_le_aarch64 #define address_space_stq_be address_space_stq_be_aarch64 #define arm_release arm_release_aarch64 +#define arm_tlb_fill arm_tlb_fill_aarch64 #define aarch64_sync_32_to_64 aarch64_sync_32_to_64_aarch64 #define aarch64_sync_64_to_32 aarch64_sync_64_to_32_aarch64 #define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_aarch64 @@ -123,7 +124,6 @@ #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_aarch64 #define arm_cpu_finalizefn arm_cpu_finalizefn_aarch64 #define arm_cpu_get_phys_page_debug arm_cpu_get_phys_page_debug_aarch64 -#define arm_cpu_handle_mmu_fault arm_cpu_handle_mmu_fault_aarch64 #define arm_cpu_initfn arm_cpu_initfn_aarch64 #define arm_cpu_list arm_cpu_list_aarch64 #define cpu_loop_exit cpu_loop_exit_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 37e2278d..a3c33497 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -23,6 +23,7 @@ #define address_space_stq_le address_space_stq_le_aarch64eb #define address_space_stq_be address_space_stq_be_aarch64eb #define arm_release arm_release_aarch64eb +#define arm_tlb_fill arm_tlb_fill_aarch64eb #define aarch64_sync_32_to_64 aarch64_sync_32_to_64_aarch64eb #define aarch64_sync_64_to_32 aarch64_sync_64_to_32_aarch64eb #define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_aarch64eb @@ -123,7 +124,6 @@ #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_aarch64eb #define arm_cpu_finalizefn arm_cpu_finalizefn_aarch64eb #define arm_cpu_get_phys_page_debug arm_cpu_get_phys_page_debug_aarch64eb -#define arm_cpu_handle_mmu_fault arm_cpu_handle_mmu_fault_aarch64eb #define arm_cpu_initfn arm_cpu_initfn_aarch64eb #define arm_cpu_list arm_cpu_list_aarch64eb #define cpu_loop_exit cpu_loop_exit_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index ae1edac2..21653c2d 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -23,6 +23,7 @@ #define address_space_stq_le address_space_stq_le_arm #define address_space_stq_be address_space_stq_be_arm #define arm_release arm_release_arm +#define arm_tlb_fill arm_tlb_fill_arm #define aarch64_sync_32_to_64 aarch64_sync_32_to_64_arm #define aarch64_sync_64_to_32 aarch64_sync_64_to_32_arm #define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_arm @@ -123,7 +124,6 @@ #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_arm #define arm_cpu_finalizefn arm_cpu_finalizefn_arm #define arm_cpu_get_phys_page_debug arm_cpu_get_phys_page_debug_arm -#define arm_cpu_handle_mmu_fault arm_cpu_handle_mmu_fault_arm #define arm_cpu_initfn arm_cpu_initfn_arm #define arm_cpu_list arm_cpu_list_arm #define cpu_loop_exit cpu_loop_exit_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 86a132e2..84f57e99 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -23,6 +23,7 @@ #define address_space_stq_le address_space_stq_le_armeb #define address_space_stq_be address_space_stq_be_armeb #define arm_release arm_release_armeb +#define arm_tlb_fill arm_tlb_fill_armeb #define aarch64_sync_32_to_64 aarch64_sync_32_to_64_armeb #define aarch64_sync_64_to_32 aarch64_sync_64_to_32_armeb #define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_armeb @@ -123,7 +124,6 @@ #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_armeb #define arm_cpu_finalizefn arm_cpu_finalizefn_armeb #define arm_cpu_get_phys_page_debug arm_cpu_get_phys_page_debug_armeb -#define arm_cpu_handle_mmu_fault arm_cpu_handle_mmu_fault_armeb #define arm_cpu_initfn arm_cpu_initfn_armeb #define arm_cpu_list arm_cpu_list_armeb #define cpu_loop_exit cpu_loop_exit_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index a1935776..5de624a8 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -29,6 +29,7 @@ symbols = ( 'address_space_stq_le', 'address_space_stq_be', 'arm_release', + 'arm_tlb_fill', 'aarch64_sync_32_to_64', 'aarch64_sync_64_to_32', 'aarch64_tb_set_jmp_target', @@ -129,7 +130,6 @@ symbols = ( 'arm_cpu_exec_interrupt', 'arm_cpu_finalizefn', 'arm_cpu_get_phys_page_debug', - 'arm_cpu_handle_mmu_fault', 'arm_cpu_initfn', 'arm_cpu_list', 'cpu_loop_exit', diff --git a/qemu/m68k.h b/qemu/m68k.h index cc2a34ab..4d4c0249 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -23,6 +23,7 @@ #define address_space_stq_le address_space_stq_le_m68k #define address_space_stq_be address_space_stq_be_m68k #define arm_release arm_release_m68k +#define arm_tlb_fill arm_tlb_fill_m68k #define aarch64_sync_32_to_64 aarch64_sync_32_to_64_m68k #define aarch64_sync_64_to_32 aarch64_sync_64_to_32_m68k #define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_m68k @@ -123,7 +124,6 @@ #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_m68k #define arm_cpu_finalizefn arm_cpu_finalizefn_m68k #define arm_cpu_get_phys_page_debug arm_cpu_get_phys_page_debug_m68k -#define arm_cpu_handle_mmu_fault arm_cpu_handle_mmu_fault_m68k #define arm_cpu_initfn arm_cpu_initfn_m68k #define arm_cpu_list arm_cpu_list_m68k #define cpu_loop_exit cpu_loop_exit_m68k diff --git a/qemu/mips.h b/qemu/mips.h index fd4865ba..0cf1fb5b 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -23,6 +23,7 @@ #define address_space_stq_le address_space_stq_le_mips #define address_space_stq_be address_space_stq_be_mips #define arm_release arm_release_mips +#define arm_tlb_fill arm_tlb_fill_mips #define aarch64_sync_32_to_64 aarch64_sync_32_to_64_mips #define aarch64_sync_64_to_32 aarch64_sync_64_to_32_mips #define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_mips @@ -123,7 +124,6 @@ #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_mips #define arm_cpu_finalizefn arm_cpu_finalizefn_mips #define arm_cpu_get_phys_page_debug arm_cpu_get_phys_page_debug_mips -#define arm_cpu_handle_mmu_fault arm_cpu_handle_mmu_fault_mips #define arm_cpu_initfn arm_cpu_initfn_mips #define arm_cpu_list arm_cpu_list_mips #define cpu_loop_exit cpu_loop_exit_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index eb173257..7dc81fca 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -23,6 +23,7 @@ #define address_space_stq_le address_space_stq_le_mips64 #define address_space_stq_be address_space_stq_be_mips64 #define arm_release arm_release_mips64 +#define arm_tlb_fill arm_tlb_fill_mips64 #define aarch64_sync_32_to_64 aarch64_sync_32_to_64_mips64 #define aarch64_sync_64_to_32 aarch64_sync_64_to_32_mips64 #define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_mips64 @@ -123,7 +124,6 @@ #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_mips64 #define arm_cpu_finalizefn arm_cpu_finalizefn_mips64 #define arm_cpu_get_phys_page_debug arm_cpu_get_phys_page_debug_mips64 -#define arm_cpu_handle_mmu_fault arm_cpu_handle_mmu_fault_mips64 #define arm_cpu_initfn arm_cpu_initfn_mips64 #define arm_cpu_list arm_cpu_list_mips64 #define cpu_loop_exit cpu_loop_exit_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 9f76b40d..0b681ec2 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -23,6 +23,7 @@ #define address_space_stq_le address_space_stq_le_mips64el #define address_space_stq_be address_space_stq_be_mips64el #define arm_release arm_release_mips64el +#define arm_tlb_fill arm_tlb_fill_mips64el #define aarch64_sync_32_to_64 aarch64_sync_32_to_64_mips64el #define aarch64_sync_64_to_32 aarch64_sync_64_to_32_mips64el #define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_mips64el @@ -123,7 +124,6 @@ #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_mips64el #define arm_cpu_finalizefn arm_cpu_finalizefn_mips64el #define arm_cpu_get_phys_page_debug arm_cpu_get_phys_page_debug_mips64el -#define arm_cpu_handle_mmu_fault arm_cpu_handle_mmu_fault_mips64el #define arm_cpu_initfn arm_cpu_initfn_mips64el #define arm_cpu_list arm_cpu_list_mips64el #define cpu_loop_exit cpu_loop_exit_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 1a61eb3e..81a03b42 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -23,6 +23,7 @@ #define address_space_stq_le address_space_stq_le_mipsel #define address_space_stq_be address_space_stq_be_mipsel #define arm_release arm_release_mipsel +#define arm_tlb_fill arm_tlb_fill_mipsel #define aarch64_sync_32_to_64 aarch64_sync_32_to_64_mipsel #define aarch64_sync_64_to_32 aarch64_sync_64_to_32_mipsel #define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_mipsel @@ -123,7 +124,6 @@ #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_mipsel #define arm_cpu_finalizefn arm_cpu_finalizefn_mipsel #define arm_cpu_get_phys_page_debug arm_cpu_get_phys_page_debug_mipsel -#define arm_cpu_handle_mmu_fault arm_cpu_handle_mmu_fault_mipsel #define arm_cpu_initfn arm_cpu_initfn_mipsel #define arm_cpu_list arm_cpu_list_mipsel #define cpu_loop_exit cpu_loop_exit_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 48b92946..fd73d67b 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -23,6 +23,7 @@ #define address_space_stq_le address_space_stq_le_powerpc #define address_space_stq_be address_space_stq_be_powerpc #define arm_release arm_release_powerpc +#define arm_tlb_fill arm_tlb_fill_powerpc #define aarch64_sync_32_to_64 aarch64_sync_32_to_64_powerpc #define aarch64_sync_64_to_32 aarch64_sync_64_to_32_powerpc #define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_powerpc @@ -123,7 +124,6 @@ #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_powerpc #define arm_cpu_finalizefn arm_cpu_finalizefn_powerpc #define arm_cpu_get_phys_page_debug arm_cpu_get_phys_page_debug_powerpc -#define arm_cpu_handle_mmu_fault arm_cpu_handle_mmu_fault_powerpc #define arm_cpu_initfn arm_cpu_initfn_powerpc #define arm_cpu_list arm_cpu_list_powerpc #define cpu_loop_exit cpu_loop_exit_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index 43859ace..b1688cfc 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -23,6 +23,7 @@ #define address_space_stq_le address_space_stq_le_sparc #define address_space_stq_be address_space_stq_be_sparc #define arm_release arm_release_sparc +#define arm_tlb_fill arm_tlb_fill_sparc #define aarch64_sync_32_to_64 aarch64_sync_32_to_64_sparc #define aarch64_sync_64_to_32 aarch64_sync_64_to_32_sparc #define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_sparc @@ -123,7 +124,6 @@ #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_sparc #define arm_cpu_finalizefn arm_cpu_finalizefn_sparc #define arm_cpu_get_phys_page_debug arm_cpu_get_phys_page_debug_sparc -#define arm_cpu_handle_mmu_fault arm_cpu_handle_mmu_fault_sparc #define arm_cpu_initfn arm_cpu_initfn_sparc #define arm_cpu_list arm_cpu_list_sparc #define cpu_loop_exit cpu_loop_exit_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index a5656802..f728cccb 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -23,6 +23,7 @@ #define address_space_stq_le address_space_stq_le_sparc64 #define address_space_stq_be address_space_stq_be_sparc64 #define arm_release arm_release_sparc64 +#define arm_tlb_fill arm_tlb_fill_sparc64 #define aarch64_sync_32_to_64 aarch64_sync_32_to_64_sparc64 #define aarch64_sync_64_to_32 aarch64_sync_64_to_32_sparc64 #define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_sparc64 @@ -123,7 +124,6 @@ #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_sparc64 #define arm_cpu_finalizefn arm_cpu_finalizefn_sparc64 #define arm_cpu_get_phys_page_debug arm_cpu_get_phys_page_debug_sparc64 -#define arm_cpu_handle_mmu_fault arm_cpu_handle_mmu_fault_sparc64 #define arm_cpu_initfn arm_cpu_initfn_sparc64 #define arm_cpu_list arm_cpu_list_sparc64 #define cpu_loop_exit cpu_loop_exit_sparc64 diff --git a/qemu/target-arm/cpu.c b/qemu/target-arm/cpu.c index 4e2f96fb..34968da3 100644 --- a/qemu/target-arm/cpu.c +++ b/qemu/target-arm/cpu.c @@ -1118,6 +1118,23 @@ static const ARMCPUInfo arm_cpus[] = { { NULL } }; +#ifdef CONFIG_USER_ONLY +static int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, + int mmu_idx) +{ + ARMCPU *cpu = ARM_CPU(NULL, cs); + CPUARMState *env = &cpu->env; + + env->exception.vaddress = address; + if (rw == 2) { + cs->exception_index = EXCP_PREFETCH_ABORT; + } else { + cs->exception_index = EXCP_DATA_ABORT; + } + return 1; +} +#endif + static void arm_cpu_class_init(struct uc_struct *uc, ObjectClass *oc, void *data) { ARMCPUClass *acc = ARM_CPU_CLASS(uc, oc); diff --git a/qemu/target-arm/cpu.h b/qemu/target-arm/cpu.h index f3d14b5c..14b480b1 100644 --- a/qemu/target-arm/cpu.h +++ b/qemu/target-arm/cpu.h @@ -512,8 +512,6 @@ static inline bool is_a64(CPUARMState *env) is returned if the signal was handled by the virtual CPU. */ int cpu_arm_signal_handler(int host_signum, void *pinfo, void *puc); -int arm_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, - int mmu_idx); /** * pmccntr_sync diff --git a/qemu/target-arm/helper.c b/qemu/target-arm/helper.c index c0197b64..393c7b66 100644 --- a/qemu/target-arm/helper.c +++ b/qemu/target-arm/helper.c @@ -3522,21 +3522,6 @@ uint32_t HELPER(rbit)(uint32_t x) #if defined(CONFIG_USER_ONLY) -int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, - int mmu_idx) -{ - ARMCPU *cpu = ARM_CPU(NULL, cs); - CPUARMState *env = &cpu->env; - - env->exception.vaddress = address; - if (rw == 2) { - cs->exception_index = EXCP_PREFETCH_ABORT; - } else { - cs->exception_index = EXCP_DATA_ABORT; - } - return 1; -} - /* These should probably raise undefined insn exceptions. */ void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val) { @@ -5308,16 +5293,18 @@ static inline int get_phys_addr(CPUARMState *env, target_ulong address, } } -int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, - int access_type, int mmu_idx) +/* Walk the page table and (if the mapping exists) add the page + * to the TLB. Return 0 on success, or an ARM DFSR/IFSR fault + * register format value on failure. + */ +int arm_tlb_fill(CPUState *cs, vaddr address, + int access_type, int mmu_idx) { CPUARMState *env = cs->env_ptr; hwaddr phys_addr; target_ulong page_size; int prot; int ret; - uint32_t syn; - bool same_el = (arm_current_el(env) != 0); MemTxAttrs attrs = {0}; ret = get_phys_addr(env, address, access_type, mmu_idx, &phys_addr, @@ -5332,27 +5319,7 @@ int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, return 0; } - /* AArch64 syndrome does not have an LPAE bit */ - syn = ret & ~(1 << 9); - - /* For insn and data aborts we assume there is no instruction syndrome - * information; this is always true for exceptions reported to EL1. - */ - if (access_type == 2) { - syn = syn_insn_abort(same_el, 0, 0, syn); - cs->exception_index = EXCP_PREFETCH_ABORT; - } else { - syn = syn_data_abort(same_el, 0, 0, 0, access_type == 1, syn); - if (access_type == 1 && arm_feature(env, ARM_FEATURE_V6)) { - ret |= (1 << 11); - } - cs->exception_index = EXCP_DATA_ABORT; - } - - env->exception.syndrome = syn; - env->exception.vaddress = address; - env->exception.fsr = ret; - return 1; + return ret; } hwaddr arm_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) diff --git a/qemu/target-arm/internals.h b/qemu/target-arm/internals.h index 57239452..243e3e36 100644 --- a/qemu/target-arm/internals.h +++ b/qemu/target-arm/internals.h @@ -389,4 +389,7 @@ bool arm_is_psci_call(ARMCPU *cpu, int excp_type); void arm_handle_psci_call(ARMCPU *cpu); #endif +/* Do a page table walk and add page to TLB if possible */ +int arm_tlb_fill(CPUState *cpu, vaddr address, int rw, int mmu_idx); + #endif diff --git a/qemu/target-arm/op_helper.c b/qemu/target-arm/op_helper.c index e614f3ba..2bb1de70 100644 --- a/qemu/target-arm/op_helper.c +++ b/qemu/target-arm/op_helper.c @@ -80,16 +80,39 @@ void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx, { int ret; - ret = arm_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx); + ret = arm_tlb_fill(cs, addr, is_write, mmu_idx); if (unlikely(ret)) { ARMCPU *cpu = ARM_CPU(cs->uc, cs); CPUARMState *env = &cpu->env; + uint32_t syn, exc; + bool same_el = (arm_current_el(env) != 0); if (retaddr) { /* now we have a real cpu fault */ cpu_restore_state(cs, retaddr); } - raise_exception(env, cs->exception_index); + + /* AArch64 syndrome does not have an LPAE bit */ + syn = ret & ~(1 << 9); + + /* For insn and data aborts we assume there is no instruction syndrome + * information; this is always true for exceptions reported to EL1. + */ + if (is_write == 2) { + syn = syn_insn_abort(same_el, 0, 0, syn); + exc = EXCP_PREFETCH_ABORT; + } else { + syn = syn_data_abort(same_el, 0, 0, 0, is_write == 1, syn); + if (is_write == 1 && arm_feature(env, ARM_FEATURE_V6)) { + ret |= (1 << 11); + } + exc = EXCP_DATA_ABORT; + } + + env->exception.syndrome = syn; + env->exception.vaddress = addr; + env->exception.fsr = ret; + raise_exception(env, exc); } } #endif diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 6cd85c13..708daeb1 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -23,6 +23,7 @@ #define address_space_stq_le address_space_stq_le_x86_64 #define address_space_stq_be address_space_stq_be_x86_64 #define arm_release arm_release_x86_64 +#define arm_tlb_fill arm_tlb_fill_x86_64 #define aarch64_sync_32_to_64 aarch64_sync_32_to_64_x86_64 #define aarch64_sync_64_to_32 aarch64_sync_64_to_32_x86_64 #define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_x86_64 @@ -123,7 +124,6 @@ #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_x86_64 #define arm_cpu_finalizefn arm_cpu_finalizefn_x86_64 #define arm_cpu_get_phys_page_debug arm_cpu_get_phys_page_debug_x86_64 -#define arm_cpu_handle_mmu_fault arm_cpu_handle_mmu_fault_x86_64 #define arm_cpu_initfn arm_cpu_initfn_x86_64 #define arm_cpu_list arm_cpu_list_x86_64 #define cpu_loop_exit cpu_loop_exit_x86_64