Skip to content

Commit

Permalink
cpu: Turn cpu_handle_mmu_fault() into a CPUClass hook
Browse files Browse the repository at this point in the history
Note that while such functions may exist both for *-user and softmmu,
only *-user uses the CPUState hook, while softmmu reuses the prototype
for calling it directly.

Signed-off-by: Andreas Färber <[email protected]>
  • Loading branch information
afaerber committed Mar 13, 2014
1 parent 7372c2b commit 7510454
Show file tree
Hide file tree
Showing 61 changed files with 238 additions and 151 deletions.
3 changes: 3 additions & 0 deletions include/qom/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ struct TranslationBlock;
* @set_pc: Callback for setting the Program Counter register.
* @synchronize_from_tb: Callback for synchronizing state from a TCG
* #TranslationBlock.
* @handle_mmu_fault: Callback for handling an MMU fault.
* @get_phys_page_debug: Callback for obtaining a physical address.
* @gdb_read_register: Callback for letting GDB read a register.
* @gdb_write_register: Callback for letting GDB write a register.
Expand Down Expand Up @@ -117,6 +118,8 @@ typedef struct CPUClass {
Error **errp);
void (*set_pc)(CPUState *cpu, vaddr value);
void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb);
int (*handle_mmu_fault)(CPUState *cpu, vaddr address, int rw,
int mmu_index);
hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr);
int (*gdb_read_register)(CPUState *cpu, uint8_t *buf, int reg);
int (*gdb_write_register)(CPUState *cpu, uint8_t *buf, int reg);
Expand Down
4 changes: 3 additions & 1 deletion target-alpha/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,9 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
cc->set_pc = alpha_cpu_set_pc;
cc->gdb_read_register = alpha_cpu_gdb_read_register;
cc->gdb_write_register = alpha_cpu_gdb_write_register;
#ifndef CONFIG_USER_ONLY
#ifdef CONFIG_USER_ONLY
cc->handle_mmu_fault = alpha_cpu_handle_mmu_fault;
#else
cc->do_unassigned_access = alpha_cpu_unassigned_access;
cc->get_phys_page_debug = alpha_cpu_get_phys_page_debug;
dc->vmsd = &vmstate_alpha_cpu;
Expand Down
5 changes: 2 additions & 3 deletions target-alpha/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -446,9 +446,8 @@ int cpu_alpha_exec(CPUAlphaState *s);
is returned if the signal was handled by the virtual CPU. */
int cpu_alpha_signal_handler(int host_signum, void *pinfo,
void *puc);
int cpu_alpha_handle_mmu_fault (CPUAlphaState *env, uint64_t address, int rw,
int mmu_idx);
#define cpu_handle_mmu_fault cpu_alpha_handle_mmu_fault
int alpha_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
int mmu_idx);
void do_restore_state(CPUAlphaState *, uintptr_t retaddr);
void QEMU_NORETURN dynamic_excp(CPUAlphaState *, uintptr_t, int, int);
void QEMU_NORETURN arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t);
Expand Down
12 changes: 8 additions & 4 deletions target-alpha/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,13 @@ void helper_store_fpcr(CPUAlphaState *env, uint64_t val)
}

#if defined(CONFIG_USER_ONLY)
int cpu_alpha_handle_mmu_fault(CPUAlphaState *env, target_ulong address,
int alpha_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
int rw, int mmu_idx)
{
env->exception_index = EXCP_MMFAULT;
env->trap_arg0 = address;
AlphaCPU *cpu = ALPHA_CPU(cs);

cpu->env.exception_index = EXCP_MMFAULT;
cpu->env.trap_arg0 = address;
return 1;
}
#else
Expand Down Expand Up @@ -326,9 +328,11 @@ hwaddr alpha_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
return (fail >= 0 ? -1 : phys);
}

int cpu_alpha_handle_mmu_fault(CPUAlphaState *env, target_ulong addr, int rw,
int alpha_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, int rw,
int mmu_idx)
{
AlphaCPU *cpu = ALPHA_CPU(cs);
CPUAlphaState *env = &cpu->env;
target_ulong phys;
int prot, fail;

Expand Down
3 changes: 2 additions & 1 deletion target-alpha/mem_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,10 @@ void alpha_cpu_unassigned_access(CPUState *cs, hwaddr addr,
void tlb_fill(CPUAlphaState *env, target_ulong addr, int is_write,
int mmu_idx, uintptr_t retaddr)
{
AlphaCPU *cpu = alpha_env_get_cpu(env);
int ret;

ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx);
ret = alpha_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
if (unlikely(ret != 0)) {
if (retaddr) {
cpu_restore_state(env, retaddr);
Expand Down
4 changes: 3 additions & 1 deletion target-arm/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1013,7 +1013,9 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
cc->set_pc = arm_cpu_set_pc;
cc->gdb_read_register = arm_cpu_gdb_read_register;
cc->gdb_write_register = arm_cpu_gdb_write_register;
#ifndef CONFIG_USER_ONLY
#ifdef CONFIG_USER_ONLY
cc->handle_mmu_fault = arm_cpu_handle_mmu_fault;
#else
cc->get_phys_page_debug = arm_cpu_get_phys_page_debug;
cc->vmsd = &vmstate_arm_cpu;
#endif
Expand Down
5 changes: 2 additions & 3 deletions target-arm/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,9 +339,8 @@ 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 cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
int mmu_idx);
#define cpu_handle_mmu_fault cpu_arm_handle_mmu_fault
int arm_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
int mmu_idx);

/* SCTLR bit meanings. Several bits have been reused in newer
* versions of the architecture; in that case we define constants
Expand Down
13 changes: 9 additions & 4 deletions target-arm/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -2655,9 +2655,12 @@ void arm_cpu_do_interrupt(CPUState *cs)
env->exception_index = -1;
}

int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
int mmu_idx)
int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
int mmu_idx)
{
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;

if (rw == 2) {
env->exception_index = EXCP_PREFETCH_ABORT;
env->cp15.c6_insn = address;
Expand Down Expand Up @@ -3623,9 +3626,11 @@ static inline int get_phys_addr(CPUARMState *env, uint32_t address,
}
}

int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address,
int access_type, int mmu_idx)
int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
int access_type, int mmu_idx)
{
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;
hwaddr phys_addr;
target_ulong page_size;
int prot;
Expand Down
3 changes: 2 additions & 1 deletion target-arm/op_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,10 @@ uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def,
void tlb_fill(CPUARMState *env, target_ulong addr, int is_write, int mmu_idx,
uintptr_t retaddr)
{
ARMCPU *cpu = arm_env_get_cpu(env);
int ret;

ret = cpu_arm_handle_mmu_fault(env, addr, is_write, mmu_idx);
ret = arm_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
if (unlikely(ret)) {
if (retaddr) {
/* now we have a real cpu fault */
Expand Down
4 changes: 3 additions & 1 deletion target-cris/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,9 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
cc->set_pc = cris_cpu_set_pc;
cc->gdb_read_register = cris_cpu_gdb_read_register;
cc->gdb_write_register = cris_cpu_gdb_write_register;
#ifndef CONFIG_USER_ONLY
#ifdef CONFIG_USER_ONLY
cc->handle_mmu_fault = cris_cpu_handle_mmu_fault;
#else
cc->get_phys_page_debug = cris_cpu_get_phys_page_debug;
#endif

Expand Down
3 changes: 1 addition & 2 deletions target-cris/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,8 @@ static inline int cpu_mmu_index (CPUCRISState *env)
return !!(env->pregs[PR_CCS] & U_FLAG);
}

int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw,
int cris_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
int mmu_idx);
#define cpu_handle_mmu_fault cpu_cris_handle_mmu_fault

/* Support function regs. */
#define SFR_RW_GC_CFG 0][0
Expand Down
24 changes: 13 additions & 11 deletions target-cris/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ void crisv10_cpu_do_interrupt(CPUState *cs)
cris_cpu_do_interrupt(cs);
}

int cpu_cris_handle_mmu_fault(CPUCRISState * env, target_ulong address, int rw,
int cris_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
int mmu_idx)
{
CRISCPU *cpu = cris_env_get_cpu(env);
CRISCPU *cpu = CRIS_CPU(cs);

env->exception_index = 0xaa;
env->pregs[PR_EDA] = address;
cpu_dump_state(CPU(cpu), stderr, fprintf, 0);
cpu->env.exception_index = 0xaa;
cpu->env.pregs[PR_EDA] = address;
cpu_dump_state(cs, stderr, fprintf, 0);
return 1;
}

Expand All @@ -73,23 +73,25 @@ static void cris_shift_ccs(CPUCRISState *env)
env->pregs[PR_CCS] = ccs;
}

int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw,
int cris_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
int mmu_idx)
{
D(CPUState *cpu = CPU(cris_env_get_cpu(env)));
CRISCPU *cpu = CRIS_CPU(cs);
CPUCRISState *env = &cpu->env;
struct cris_mmu_result res;
int prot, miss;
int r = -1;
target_ulong phy;

D(printf("%s addr=%x pc=%x rw=%x\n", __func__, address, env->pc, rw));
D(printf("%s addr=%" VADDR_PRIx " pc=%x rw=%x\n",
__func__, address, env->pc, rw));
miss = cris_mmu_translate(&res, env, address & TARGET_PAGE_MASK,
rw, mmu_idx, 0);
if (miss) {
if (env->exception_index == EXCP_BUSFAULT) {
cpu_abort(env,
"CRIS: Illegal recursive bus fault."
"addr=%x rw=%d\n",
"addr=%" VADDR_PRIx " rw=%d\n",
address, rw);
}

Expand All @@ -109,8 +111,8 @@ int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw,
r = 0;
}
if (r > 0) {
D_LOG("%s returns %d irqreq=%x addr=%x phy=%x vec=%x pc=%x\n",
__func__, r, cpu->interrupt_request, address, res.phy,
D_LOG("%s returns %d irqreq=%x addr=%" VADDR_PRIx " phy=%x vec=%x"
" pc=%x\n", __func__, r, cs->interrupt_request, address, res.phy,
res.bf_vec, env->pc);
}
return r;
Expand Down
3 changes: 2 additions & 1 deletion target-cris/op_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,12 @@
void tlb_fill(CPUCRISState *env, target_ulong addr, int is_write, int mmu_idx,
uintptr_t retaddr)
{
CRISCPU *cpu = cris_env_get_cpu(env);
int ret;

D_LOG("%s pc=%x tpc=%x ra=%p\n", __func__,
env->pc, env->pregs[PR_EDA], (void *)retaddr);
ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx);
ret = cris_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
if (unlikely(ret)) {
if (retaddr) {
/* now we have a real cpu fault */
Expand Down
4 changes: 3 additions & 1 deletion target-i386/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -2810,7 +2810,9 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
cc->gdb_write_register = x86_cpu_gdb_write_register;
cc->get_arch_id = x86_cpu_get_arch_id;
cc->get_paging_enabled = x86_cpu_get_paging_enabled;
#ifndef CONFIG_USER_ONLY
#ifdef CONFIG_USER_ONLY
cc->handle_mmu_fault = x86_cpu_handle_mmu_fault;
#else
cc->get_memory_mapping = x86_cpu_get_memory_mapping;
cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;
cc->write_elf64_note = x86_cpu_write_elf64_note;
Expand Down
3 changes: 1 addition & 2 deletions target-i386/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -1067,9 +1067,8 @@ void host_cpuid(uint32_t function, uint32_t count,
uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);

/* helper.c */
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
int x86_cpu_handle_mmu_fault(CPUState *cpu, vaddr addr,
int is_write, int mmu_idx);
#define cpu_handle_mmu_fault cpu_x86_handle_mmu_fault
void x86_cpu_set_a20(X86CPU *cpu, int a20_state);

static inline bool hw_local_breakpoint_enabled(unsigned long dr7, int index)
Expand Down
20 changes: 12 additions & 8 deletions target-i386/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -485,9 +485,12 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)

#if defined(CONFIG_USER_ONLY)

int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
int is_write, int mmu_idx)
{
X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;

/* user mode only emulation */
is_write &= 1;
env->cr[2] = addr;
Expand All @@ -508,14 +511,15 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
# endif

/* return value:
-1 = cannot handle fault
0 = nothing more to do
1 = generate PF fault
*/
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
* -1 = cannot handle fault
* 0 = nothing more to do
* 1 = generate PF fault
*/
int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
int is_write1, int mmu_idx)
{
CPUState *cs = CPU(x86_env_get_cpu(env));
X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;
uint64_t ptep, pte;
target_ulong pde_addr, pte_addr;
int error_code, is_dirty, prot, page_size, is_write, is_user;
Expand All @@ -525,7 +529,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,

is_user = mmu_idx == MMU_USER_IDX;
#if defined(DEBUG_MMU)
printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
printf("MMU fault: addr=%" VADDR_PRIx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
addr, is_write1, is_user, env->eip);
#endif
is_write = is_write1 & 1;
Expand Down
3 changes: 2 additions & 1 deletion target-i386/mem_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,10 @@ void helper_boundl(CPUX86State *env, target_ulong a0, int v)
void tlb_fill(CPUX86State *env, target_ulong addr, int is_write, int mmu_idx,
uintptr_t retaddr)
{
X86CPU *cpu = x86_env_get_cpu(env);
int ret;

ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx);
ret = x86_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
if (ret) {
if (retaddr) {
/* now we have a real cpu fault */
Expand Down
4 changes: 3 additions & 1 deletion target-lm32/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,9 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
cc->set_pc = lm32_cpu_set_pc;
cc->gdb_read_register = lm32_cpu_gdb_read_register;
cc->gdb_write_register = lm32_cpu_gdb_write_register;
#ifndef CONFIG_USER_ONLY
#ifdef CONFIG_USER_ONLY
cc->handle_mmu_fault = lm32_cpu_handle_mmu_fault;
#else
cc->get_phys_page_debug = lm32_cpu_get_phys_page_debug;
cc->vmsd = &vmstate_lm32_cpu;
#endif
Expand Down
3 changes: 1 addition & 2 deletions target-lm32/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,8 @@ static inline CPULM32State *cpu_init(const char *cpu_model)
#define cpu_gen_code cpu_lm32_gen_code
#define cpu_signal_handler cpu_lm32_signal_handler

int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw,
int lm32_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
int mmu_idx);
#define cpu_handle_mmu_fault cpu_lm32_handle_mmu_fault

#include "exec/cpu-all.h"

Expand Down
4 changes: 3 additions & 1 deletion target-lm32/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
#include "cpu.h"
#include "qemu/host-utils.h"

int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw,
int lm32_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
int mmu_idx)
{
LM32CPU *cpu = LM32_CPU(cs);
CPULM32State *env = &cpu->env;
int prot;

address &= TARGET_PAGE_MASK;
Expand Down
3 changes: 2 additions & 1 deletion target-lm32/op_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,10 @@ uint32_t HELPER(rcsr_jrx)(CPULM32State *env)
void tlb_fill(CPULM32State *env, target_ulong addr, int is_write, int mmu_idx,
uintptr_t retaddr)
{
LM32CPU *cpu = lm32_env_get_cpu(env);
int ret;

ret = cpu_lm32_handle_mmu_fault(env, addr, is_write, mmu_idx);
ret = lm32_cpu_handle_mmu_fault(CPU(cpu), addr, is_write, mmu_idx);
if (unlikely(ret)) {
if (retaddr) {
/* now we have a real cpu fault */
Expand Down
4 changes: 3 additions & 1 deletion target-m68k/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,9 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
cc->set_pc = m68k_cpu_set_pc;
cc->gdb_read_register = m68k_cpu_gdb_read_register;
cc->gdb_write_register = m68k_cpu_gdb_write_register;
#ifndef CONFIG_USER_ONLY
#ifdef CONFIG_USER_ONLY
cc->handle_mmu_fault = m68k_cpu_handle_mmu_fault;
#else
cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug;
#endif
dc->vmsd = &vmstate_m68k_cpu;
Expand Down
3 changes: 1 addition & 2 deletions target-m68k/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,8 @@ static inline int cpu_mmu_index (CPUM68KState *env)
return (env->sr & SR_S) == 0 ? 1 : 0;
}

int cpu_m68k_handle_mmu_fault(CPUM68KState *env, target_ulong address, int rw,
int m68k_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
int mmu_idx);
#define cpu_handle_mmu_fault cpu_m68k_handle_mmu_fault

#include "exec/cpu-all.h"

Expand Down
Loading

0 comments on commit 7510454

Please sign in to comment.