Commit a97fed52e57385fc749e6f6ef95be7ebdb81ba9b
1 parent
51996525
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
Showing
3 changed files
with
16 additions
and
16 deletions
target-ppc/cpu.h
@@ -611,9 +611,9 @@ void do_store_sr (CPUPPCState *env, int srnum, target_ulong value); | @@ -611,9 +611,9 @@ void do_store_sr (CPUPPCState *env, int srnum, target_ulong value); | ||
611 | target_ulong ppc_load_xer (CPUPPCState *env); | 611 | target_ulong ppc_load_xer (CPUPPCState *env); |
612 | void ppc_store_xer (CPUPPCState *env, target_ulong value); | 612 | void ppc_store_xer (CPUPPCState *env, target_ulong value); |
613 | target_ulong do_load_msr (CPUPPCState *env); | 613 | target_ulong do_load_msr (CPUPPCState *env); |
614 | -void do_store_msr (CPUPPCState *env, target_ulong value); | 614 | +int do_store_msr (CPUPPCState *env, target_ulong value); |
615 | #if defined(TARGET_PPC64) | 615 | #if defined(TARGET_PPC64) |
616 | -void ppc_store_msr_32 (CPUPPCState *env, uint32_t value); | 616 | +int ppc_store_msr_32 (CPUPPCState *env, uint32_t value); |
617 | #endif | 617 | #endif |
618 | 618 | ||
619 | void do_compute_hflags (CPUPPCState *env); | 619 | void do_compute_hflags (CPUPPCState *env); |
target-ppc/helper.c
@@ -1839,7 +1839,7 @@ target_ulong do_load_msr (CPUPPCState *env) | @@ -1839,7 +1839,7 @@ target_ulong do_load_msr (CPUPPCState *env) | ||
1839 | ((target_ulong)msr_le << MSR_LE); | 1839 | ((target_ulong)msr_le << MSR_LE); |
1840 | } | 1840 | } |
1841 | 1841 | ||
1842 | -void do_store_msr (CPUPPCState *env, target_ulong value) | 1842 | +int do_store_msr (CPUPPCState *env, target_ulong value) |
1843 | { | 1843 | { |
1844 | int enter_pm; | 1844 | int enter_pm; |
1845 | 1845 | ||
@@ -1921,21 +1921,15 @@ void do_store_msr (CPUPPCState *env, target_ulong value) | @@ -1921,21 +1921,15 @@ void do_store_msr (CPUPPCState *env, target_ulong value) | ||
1921 | default: | 1921 | default: |
1922 | break; | 1922 | break; |
1923 | } | 1923 | } |
1924 | - if (enter_pm) { | ||
1925 | - if (likely(!env->halted)) { | ||
1926 | - /* power save: exit cpu loop */ | ||
1927 | - env->halted = 1; | ||
1928 | - env->exception_index = EXCP_HLT; | ||
1929 | - cpu_loop_exit(); | ||
1930 | - } | ||
1931 | - } | 1924 | + |
1925 | + return enter_pm; | ||
1932 | } | 1926 | } |
1933 | 1927 | ||
1934 | #if defined(TARGET_PPC64) | 1928 | #if defined(TARGET_PPC64) |
1935 | -void ppc_store_msr_32 (CPUPPCState *env, uint32_t value) | 1929 | +int ppc_store_msr_32 (CPUPPCState *env, uint32_t value) |
1936 | { | 1930 | { |
1937 | - do_store_msr(env, | ||
1938 | - (do_load_msr(env) & ~0xFFFFFFFFULL) | (value & 0xFFFFFFFF)); | 1931 | + return do_store_msr(env, (do_load_msr(env) & ~0xFFFFFFFFULL) | |
1932 | + (value & 0xFFFFFFFF)); | ||
1939 | } | 1933 | } |
1940 | #endif | 1934 | #endif |
1941 | 1935 |
target-ppc/op.c
@@ -351,7 +351,10 @@ void OPPROTO op_load_msr (void) | @@ -351,7 +351,10 @@ void OPPROTO op_load_msr (void) | ||
351 | 351 | ||
352 | void OPPROTO op_store_msr (void) | 352 | void OPPROTO op_store_msr (void) |
353 | { | 353 | { |
354 | - do_store_msr(env, T0); | 354 | + if (do_store_msr(env, T0)) { |
355 | + env->halted = 1; | ||
356 | + do_raise_exception(EXCP_HLT); | ||
357 | + } | ||
355 | RETURN(); | 358 | RETURN(); |
356 | } | 359 | } |
357 | 360 | ||
@@ -365,7 +368,10 @@ void OPPROTO op_update_riee (void) | @@ -365,7 +368,10 @@ void OPPROTO op_update_riee (void) | ||
365 | #if defined (TARGET_PPC64) | 368 | #if defined (TARGET_PPC64) |
366 | void OPPROTO op_store_msr_32 (void) | 369 | void OPPROTO op_store_msr_32 (void) |
367 | { | 370 | { |
368 | - ppc_store_msr_32(env, T0); | 371 | + if (ppc_store_msr_32(env, T0)) { |
372 | + env->halted = 1; | ||
373 | + do_raise_exception(EXCP_HLT); | ||
374 | + } | ||
369 | RETURN(); | 375 | RETURN(); |
370 | } | 376 | } |
371 | #endif | 377 | #endif |