aboutsummaryrefslogtreecommitdiff
path: root/target-sparc
diff options
context:
space:
mode:
authorBlue Swirl <blauwirbel@gmail.com>2011-08-01 21:26:03 +0000
committerBlue Swirl <blauwirbel@gmail.com>2011-08-01 21:26:03 +0000
commit67494323f2c782fe3e65c60529fe9dfa613fc500 (patch)
tree1e99ed4562eb475214f3923f8e5263acb04bf4ef /target-sparc
parent927d721777e73339f73719f36eaf400ab641366c (diff)
Sparc: fix non-faulting unassigned memory accesses
Commit b14ef7c9ab41ea824c3ccadb070ad95567cca84e 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: Bob Breuer <breuerr@mc.net> Tested-by: Bob Breuer <breuerr@mc.net> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'target-sparc')
-rw-r--r--target-sparc/op_helper.c25
1 files changed, 8 insertions, 17 deletions
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index c1c4d4b07e..5aeca2b06d 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -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,
int is_exec, int is_asi, int size)
{
- CPUState *saved_env;
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
if (is_asi)
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,
if (env->mmuregs[0] & MMU_NF) {
tlb_flush(env, 1);
}
-
- env = saved_env;
}
#endif
#else
@@ -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)
#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
printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
"\n", addr, env->pc);
@@ -4335,8 +4321,6 @@ static void do_unassigned_access(target_phys_addr_t addr, int is_write,
raise_exception(TT_CODE_ACCESS);
else
raise_exception(TT_DATA_ACCESS);
-
- env = saved_env;
}
#endif
@@ -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,
int is_write, int is_exec, int is_asi, int size)
{
+ CPUState *saved_env;
+
+ saved_env = env;
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