mirror of https://github.com/xemu-project/xemu.git
Fix unassigned memory access handling
cea5f9a28f
exposed bugs in unassigned memory
access handling. Fix them by always passing CPUState to the handlers.
Reported-by: Hervé Poussineau <hpoussin@reactos.org>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
parent
21673cdecb
commit
b14ef7c9ab
|
@ -323,7 +323,7 @@ static inline tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong add
|
|||
pd = env1->tlb_table[mmu_idx][page_index].addr_code & ~TARGET_PAGE_MASK;
|
||||
if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
|
||||
#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SPARC)
|
||||
do_unassigned_access(addr, 0, 1, 0, 4);
|
||||
cpu_unassigned_access(env1, addr, 0, 1, 0, 4);
|
||||
#else
|
||||
cpu_abort(env1, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr);
|
||||
#endif
|
||||
|
|
12
exec.c
12
exec.c
|
@ -3238,7 +3238,7 @@ static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)
|
|||
printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
|
||||
#endif
|
||||
#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
|
||||
do_unassigned_access(addr, 0, 0, 0, 1);
|
||||
cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, 1);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -3249,7 +3249,7 @@ static uint32_t unassigned_mem_readw(void *opaque, target_phys_addr_t addr)
|
|||
printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
|
||||
#endif
|
||||
#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
|
||||
do_unassigned_access(addr, 0, 0, 0, 2);
|
||||
cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, 2);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -3260,7 +3260,7 @@ static uint32_t unassigned_mem_readl(void *opaque, target_phys_addr_t addr)
|
|||
printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
|
||||
#endif
|
||||
#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
|
||||
do_unassigned_access(addr, 0, 0, 0, 4);
|
||||
cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, 4);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -3271,7 +3271,7 @@ static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_
|
|||
printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
|
||||
#endif
|
||||
#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
|
||||
do_unassigned_access(addr, 1, 0, 0, 1);
|
||||
cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -3281,7 +3281,7 @@ static void unassigned_mem_writew(void *opaque, target_phys_addr_t addr, uint32_
|
|||
printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
|
||||
#endif
|
||||
#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
|
||||
do_unassigned_access(addr, 1, 0, 0, 2);
|
||||
cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, 2);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -3291,7 +3291,7 @@ static void unassigned_mem_writel(void *opaque, target_phys_addr_t addr, uint32_
|
|||
printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
|
||||
#endif
|
||||
#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
|
||||
do_unassigned_access(addr, 1, 0, 0, 4);
|
||||
cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, 4);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -434,8 +434,9 @@ uint64_t cpu_alpha_load_fpcr (CPUState *env);
|
|||
void cpu_alpha_store_fpcr (CPUState *env, uint64_t val);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
void swap_shadow_regs(CPUState *env);
|
||||
extern QEMU_NORETURN void do_unassigned_access(target_phys_addr_t addr,
|
||||
int, int, int, int);
|
||||
QEMU_NORETURN void cpu_unassigned_access(CPUState *env1,
|
||||
target_phys_addr_t addr, int is_write,
|
||||
int is_exec, int unused, int size);
|
||||
#endif
|
||||
|
||||
/* Bits in TB->FLAGS that control how translation is processed. */
|
||||
|
|
|
@ -1301,9 +1301,11 @@ static void QEMU_NORETURN do_unaligned_access(target_ulong addr, int is_write,
|
|||
helper_excp(EXCP_UNALIGN, 0);
|
||||
}
|
||||
|
||||
void QEMU_NORETURN do_unassigned_access(target_phys_addr_t addr, int is_write,
|
||||
int is_exec, int unused, int size)
|
||||
void QEMU_NORETURN cpu_unassigned_access(CPUState *env1,
|
||||
target_phys_addr_t addr, int is_write,
|
||||
int is_exec, int unused, int size)
|
||||
{
|
||||
env = env1;
|
||||
env->trap_arg0 = addr;
|
||||
env->trap_arg1 = is_write;
|
||||
dynamic_excp(EXCP_MCHK, 0);
|
||||
|
|
|
@ -347,8 +347,8 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
|
|||
}
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
|
||||
int is_asi, int size);
|
||||
void cpu_unassigned_access(CPUState *env1, target_phys_addr_t addr,
|
||||
int is_write, int is_exec, int is_asi, int size);
|
||||
#endif
|
||||
|
||||
static inline bool cpu_has_work(CPUState *env)
|
||||
|
|
|
@ -488,20 +488,14 @@ void helper_mmu_write(uint32_t rn, uint32_t v)
|
|||
mmu_write(env, rn, v);
|
||||
}
|
||||
|
||||
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
|
||||
int is_asi, int size)
|
||||
void cpu_unassigned_access(CPUState *env1, target_phys_addr_t addr,
|
||||
int is_write, int is_exec, int is_asi, int size)
|
||||
{
|
||||
CPUState *saved_env;
|
||||
|
||||
if (!cpu_single_env) {
|
||||
/* XXX: ??? */
|
||||
return;
|
||||
}
|
||||
|
||||
/* XXX: hack to restore env in all cases, even if not called from
|
||||
generated code */
|
||||
saved_env = env;
|
||||
env = cpu_single_env;
|
||||
env = env1;
|
||||
|
||||
qemu_log_mask(CPU_LOG_INT, "Unassigned " TARGET_FMT_plx " wr=%d exe=%d\n",
|
||||
addr, is_write, is_exec);
|
||||
if (!(env->sregs[SR_MSR] & MSR_EE)) {
|
||||
|
|
|
@ -493,8 +493,8 @@ void r4k_helper_tlbwr (void);
|
|||
void r4k_helper_tlbp (void);
|
||||
void r4k_helper_tlbr (void);
|
||||
|
||||
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
|
||||
int unused, int size);
|
||||
void cpu_unassigned_access(CPUState *env, target_phys_addr_t addr,
|
||||
int is_write, int is_exec, int unused, int size);
|
||||
#endif
|
||||
|
||||
void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf);
|
||||
|
|
|
@ -1980,9 +1980,11 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
|
|||
env = saved_env;
|
||||
}
|
||||
|
||||
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
|
||||
int unused, int size)
|
||||
void cpu_unassigned_access(CPUState *env1, target_phys_addr_t addr,
|
||||
int is_write, int is_exec, int unused, int size)
|
||||
{
|
||||
env = env1;
|
||||
|
||||
if (is_exec)
|
||||
helper_raise_exception(EXCP_IBE);
|
||||
else
|
||||
|
|
|
@ -510,8 +510,8 @@ static inline int tlb_compare_context(const SparcTLBEntry *tlb,
|
|||
|
||||
/* cpu-exec.c */
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
|
||||
int is_asi, int size);
|
||||
void cpu_unassigned_access(CPUState *env1, target_phys_addr_t addr,
|
||||
int is_write, int is_exec, int is_asi, int size);
|
||||
target_phys_addr_t cpu_get_phys_page_nofault(CPUState *env, target_ulong addr,
|
||||
int mmu_idx);
|
||||
|
||||
|
|
|
@ -79,9 +79,14 @@
|
|||
#define CACHE_CTRL_FD (1 << 22) /* Flush Data cache (Write only) */
|
||||
#define CACHE_CTRL_DS (1 << 23) /* Data cache snoop enable */
|
||||
|
||||
#if defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
static void do_unassigned_access(target_phys_addr_t addr, int is_write,
|
||||
int is_exec, int is_asi, int size);
|
||||
#else
|
||||
#ifdef TARGET_SPARC64
|
||||
static void do_unassigned_access(target_ulong addr, int is_write, int is_exec,
|
||||
int is_asi, int size);
|
||||
int is_asi, int size);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
|
||||
|
@ -4235,8 +4240,8 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
|
|||
|
||||
#ifndef TARGET_SPARC64
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
|
||||
int is_asi, int size)
|
||||
static void do_unassigned_access(target_phys_addr_t addr, int is_write,
|
||||
int is_exec, int is_asi, int size)
|
||||
{
|
||||
CPUState *saved_env;
|
||||
int fault_type;
|
||||
|
@ -4301,8 +4306,8 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
|
|||
static void do_unassigned_access(target_ulong addr, int is_write, int is_exec,
|
||||
int is_asi, int size)
|
||||
#else
|
||||
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
|
||||
int is_asi, int size)
|
||||
static void do_unassigned_access(target_phys_addr_t addr, int is_write,
|
||||
int is_exec, int is_asi, int size)
|
||||
#endif
|
||||
{
|
||||
CPUState *saved_env;
|
||||
|
@ -4351,3 +4356,12 @@ void helper_tick_set_limit(void *opaque, uint64_t limit)
|
|||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
void cpu_unassigned_access(CPUState *env1, target_phys_addr_t addr,
|
||||
int is_write, int is_exec, int is_asi, int size)
|
||||
{
|
||||
env = env1;
|
||||
do_unassigned_access(addr, is_write, is_exec, is_asi, size);
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue