提交 67494323 编写于 作者: B Blue Swirl

Sparc: fix non-faulting unassigned memory accesses

Commit b14ef7c9
introduced cpu_unassigned_access() function. On Sparc,
the function does not restore AREG0 used for global CPUState
on function exit, causing bugs with non-faulting unassigned
memory accesses. Alpha, Microblaze and MIPS are not affected.

Fix by restoring AREG0 on exit. Remove excess saving by
do_unassigned_access() functions.

Also ignore unassigned accesses outside of CPU context.
Reported-by: NBob Breuer <breuerr@mc.net>
Tested-by: NBob Breuer <breuerr@mc.net>
Signed-off-by: NBlue Swirl <blauwirbel@gmail.com>
上级 927d7217
...@@ -4252,13 +4252,8 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr) ...@@ -4252,13 +4252,8 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
static void do_unassigned_access(target_phys_addr_t addr, int is_write, static void do_unassigned_access(target_phys_addr_t addr, int is_write,
int is_exec, int is_asi, int size) int is_exec, int is_asi, int size)
{ {
CPUState *saved_env;
int fault_type; int fault_type;
/* XXX: hack to restore env in all cases, even if not called from
generated code */
saved_env = env;
env = cpu_single_env;
#ifdef DEBUG_UNASSIGNED #ifdef DEBUG_UNASSIGNED
if (is_asi) if (is_asi)
printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
...@@ -4306,8 +4301,6 @@ static void do_unassigned_access(target_phys_addr_t addr, int is_write, ...@@ -4306,8 +4301,6 @@ static void do_unassigned_access(target_phys_addr_t addr, int is_write,
if (env->mmuregs[0] & MMU_NF) { if (env->mmuregs[0] & MMU_NF) {
tlb_flush(env, 1); tlb_flush(env, 1);
} }
env = saved_env;
} }
#endif #endif
#else #else
...@@ -4319,13 +4312,6 @@ static void do_unassigned_access(target_phys_addr_t addr, int is_write, ...@@ -4319,13 +4312,6 @@ static void do_unassigned_access(target_phys_addr_t addr, int is_write,
int is_exec, int is_asi, int size) int is_exec, int is_asi, int size)
#endif #endif
{ {
CPUState *saved_env;
/* XXX: hack to restore env in all cases, even if not called from
generated code */
saved_env = env;
env = cpu_single_env;
#ifdef DEBUG_UNASSIGNED #ifdef DEBUG_UNASSIGNED
printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
"\n", addr, env->pc); "\n", addr, env->pc);
...@@ -4335,8 +4321,6 @@ static void do_unassigned_access(target_phys_addr_t addr, int is_write, ...@@ -4335,8 +4321,6 @@ static void do_unassigned_access(target_phys_addr_t addr, int is_write,
raise_exception(TT_CODE_ACCESS); raise_exception(TT_CODE_ACCESS);
else else
raise_exception(TT_DATA_ACCESS); raise_exception(TT_DATA_ACCESS);
env = saved_env;
} }
#endif #endif
...@@ -4370,7 +4354,14 @@ void helper_tick_set_limit(void *opaque, uint64_t limit) ...@@ -4370,7 +4354,14 @@ void helper_tick_set_limit(void *opaque, uint64_t limit)
void cpu_unassigned_access(CPUState *env1, target_phys_addr_t addr, void cpu_unassigned_access(CPUState *env1, target_phys_addr_t addr,
int is_write, int is_exec, int is_asi, int size) int is_write, int is_exec, int is_asi, int size)
{ {
CPUState *saved_env;
saved_env = env;
env = env1; env = env1;
do_unassigned_access(addr, is_write, is_exec, is_asi, size); /* Ignore unassigned accesses outside of CPU context */
if (env1) {
do_unassigned_access(addr, is_write, is_exec, is_asi, size);
}
env = saved_env;
} }
#endif #endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册