Commit ea1c18022edd0e2c45552d6fc2da6e15a3486b33
1 parent
516633dc
fixed self modifying code in case of asynchronous interrupt
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@924 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
8 additions
and
1 deletions
exec.c
| @@ -613,7 +613,7 @@ void tb_invalidate_phys_page_range(target_ulong start, target_ulong end, | @@ -613,7 +613,7 @@ void tb_invalidate_phys_page_range(target_ulong start, target_ulong end, | ||
| 613 | CPUState *env = cpu_single_env; | 613 | CPUState *env = cpu_single_env; |
| 614 | #endif | 614 | #endif |
| 615 | PageDesc *p; | 615 | PageDesc *p; |
| 616 | - TranslationBlock *tb, *tb_next, *current_tb; | 616 | + TranslationBlock *tb, *tb_next, *current_tb, *saved_tb; |
| 617 | target_ulong tb_start, tb_end; | 617 | target_ulong tb_start, tb_end; |
| 618 | target_ulong current_pc, current_cs_base; | 618 | target_ulong current_pc, current_cs_base; |
| 619 | 619 | ||
| @@ -681,7 +681,12 @@ void tb_invalidate_phys_page_range(target_ulong start, target_ulong end, | @@ -681,7 +681,12 @@ void tb_invalidate_phys_page_range(target_ulong start, target_ulong end, | ||
| 681 | #endif | 681 | #endif |
| 682 | } | 682 | } |
| 683 | #endif /* TARGET_HAS_PRECISE_SMC */ | 683 | #endif /* TARGET_HAS_PRECISE_SMC */ |
| 684 | + saved_tb = env->current_tb; | ||
| 685 | + env->current_tb = NULL; | ||
| 684 | tb_phys_invalidate(tb, -1); | 686 | tb_phys_invalidate(tb, -1); |
| 687 | + env->current_tb = saved_tb; | ||
| 688 | + if (env->interrupt_request && env->current_tb) | ||
| 689 | + cpu_interrupt(env, env->interrupt_request); | ||
| 685 | } | 690 | } |
| 686 | tb = tb_next; | 691 | tb = tb_next; |
| 687 | } | 692 | } |
| @@ -699,6 +704,7 @@ void tb_invalidate_phys_page_range(target_ulong start, target_ulong end, | @@ -699,6 +704,7 @@ void tb_invalidate_phys_page_range(target_ulong start, target_ulong end, | ||
| 699 | /* we generate a block containing just the instruction | 704 | /* we generate a block containing just the instruction |
| 700 | modifying the memory. It will ensure that it cannot modify | 705 | modifying the memory. It will ensure that it cannot modify |
| 701 | itself */ | 706 | itself */ |
| 707 | + env->current_tb = NULL; | ||
| 702 | tb_gen_code(env, current_pc, current_cs_base, current_flags, | 708 | tb_gen_code(env, current_pc, current_cs_base, current_flags, |
| 703 | CF_SINGLE_INSN); | 709 | CF_SINGLE_INSN); |
| 704 | cpu_resume_from_signal(env, NULL); | 710 | cpu_resume_from_signal(env, NULL); |
| @@ -795,6 +801,7 @@ static void tb_invalidate_phys_page(target_ulong addr, | @@ -795,6 +801,7 @@ static void tb_invalidate_phys_page(target_ulong addr, | ||
| 795 | /* we generate a block containing just the instruction | 801 | /* we generate a block containing just the instruction |
| 796 | modifying the memory. It will ensure that it cannot modify | 802 | modifying the memory. It will ensure that it cannot modify |
| 797 | itself */ | 803 | itself */ |
| 804 | + env->current_tb = NULL; | ||
| 798 | tb_gen_code(env, current_pc, current_cs_base, current_flags, | 805 | tb_gen_code(env, current_pc, current_cs_base, current_flags, |
| 799 | CF_SINGLE_INSN); | 806 | CF_SINGLE_INSN); |
| 800 | cpu_resume_from_signal(env, puc); | 807 | cpu_resume_from_signal(env, puc); |