summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-10-01 21:49:57 +0000
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-10-01 21:49:57 +0000
commita97fed52e57385fc749e6f6ef95be7ebdb81ba9b (patch)
treefb26f5a0ca1db4d31479e4ee47bc27be9a2b63bd
parent51996525c77e61a050562900a499798ded8981d0 (diff)
downloadqemu-a97fed52e57385fc749e6f6ef95be7ebdb81ba9b.tar.gz
qemu-a97fed52e57385fc749e6f6ef95be7ebdb81ba9b.tar.bz2
qemu-a97fed52e57385fc749e6f6ef95be7ebdb81ba9b.zip
Fix reproductible crash: call cpu_loop_exit from micro-op, not from helper.c
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3311 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--target-ppc/cpu.h4
-rw-r--r--target-ppc/helper.c18
-rw-r--r--target-ppc/op.c10
3 files changed, 16 insertions, 16 deletions
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index c4ae414413..396a5884b1 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -611,9 +611,9 @@ void do_store_sr (CPUPPCState *env, int srnum, target_ulong value);
target_ulong ppc_load_xer (CPUPPCState *env);
void ppc_store_xer (CPUPPCState *env, target_ulong value);
target_ulong do_load_msr (CPUPPCState *env);
-void do_store_msr (CPUPPCState *env, target_ulong value);
+int do_store_msr (CPUPPCState *env, target_ulong value);
#if defined(TARGET_PPC64)
-void ppc_store_msr_32 (CPUPPCState *env, uint32_t value);
+int ppc_store_msr_32 (CPUPPCState *env, uint32_t value);
#endif
void do_compute_hflags (CPUPPCState *env);
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 5b0fd09b9c..5fa5ee002a 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -1839,7 +1839,7 @@ target_ulong do_load_msr (CPUPPCState *env)
((target_ulong)msr_le << MSR_LE);
}
-void do_store_msr (CPUPPCState *env, target_ulong value)
+int do_store_msr (CPUPPCState *env, target_ulong value)
{
int enter_pm;
@@ -1921,21 +1921,15 @@ void do_store_msr (CPUPPCState *env, target_ulong value)
default:
break;
}
- if (enter_pm) {
- if (likely(!env->halted)) {
- /* power save: exit cpu loop */
- env->halted = 1;
- env->exception_index = EXCP_HLT;
- cpu_loop_exit();
- }
- }
+
+ return enter_pm;
}
#if defined(TARGET_PPC64)
-void ppc_store_msr_32 (CPUPPCState *env, uint32_t value)
+int ppc_store_msr_32 (CPUPPCState *env, uint32_t value)
{
- do_store_msr(env,
- (do_load_msr(env) & ~0xFFFFFFFFULL) | (value & 0xFFFFFFFF));
+ return do_store_msr(env, (do_load_msr(env) & ~0xFFFFFFFFULL) |
+ (value & 0xFFFFFFFF));
}
#endif
diff --git a/target-ppc/op.c b/target-ppc/op.c
index 822c267695..72fd483463 100644
--- a/target-ppc/op.c
+++ b/target-ppc/op.c
@@ -351,7 +351,10 @@ void OPPROTO op_load_msr (void)
void OPPROTO op_store_msr (void)
{
- do_store_msr(env, T0);
+ if (do_store_msr(env, T0)) {
+ env->halted = 1;
+ do_raise_exception(EXCP_HLT);
+ }
RETURN();
}
@@ -365,7 +368,10 @@ void OPPROTO op_update_riee (void)
#if defined (TARGET_PPC64)
void OPPROTO op_store_msr_32 (void)
{
- ppc_store_msr_32(env, T0);
+ if (ppc_store_msr_32(env, T0)) {
+ env->halted = 1;
+ do_raise_exception(EXCP_HLT);
+ }
RETURN();
}
#endif