Commit b5fc09ae52e3d19e01126715c998eb6587795b56
1 parent
c75a823c
Fix crash due to invalid env->current_tb (Adam Lackorzynski, Paul Brook, me)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4317 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
44 additions
and
24 deletions
cpu-exec.c
| @@ -36,6 +36,7 @@ | @@ -36,6 +36,7 @@ | ||
| 36 | #endif | 36 | #endif |
| 37 | 37 | ||
| 38 | int tb_invalidated_flag; | 38 | int tb_invalidated_flag; |
| 39 | +static unsigned long next_tb; | ||
| 39 | 40 | ||
| 40 | //#define DEBUG_EXEC | 41 | //#define DEBUG_EXEC |
| 41 | //#define DEBUG_SIGNAL | 42 | //#define DEBUG_SIGNAL |
| @@ -273,14 +274,12 @@ static inline TranslationBlock *tb_find_fast(void) | @@ -273,14 +274,12 @@ static inline TranslationBlock *tb_find_fast(void) | ||
| 273 | /* as some TB could have been invalidated because | 274 | /* as some TB could have been invalidated because |
| 274 | of memory exceptions while generating the code, we | 275 | of memory exceptions while generating the code, we |
| 275 | must recompute the hash index here */ | 276 | must recompute the hash index here */ |
| 276 | - T0 = 0; | 277 | + next_tb = 0; |
| 277 | } | 278 | } |
| 278 | } | 279 | } |
| 279 | return tb; | 280 | return tb; |
| 280 | } | 281 | } |
| 281 | 282 | ||
| 282 | -#define BREAK_CHAIN T0 = 0 | ||
| 283 | - | ||
| 284 | /* main execution loop */ | 283 | /* main execution loop */ |
| 285 | 284 | ||
| 286 | int cpu_exec(CPUState *env1) | 285 | int cpu_exec(CPUState *env1) |
| @@ -293,7 +292,7 @@ int cpu_exec(CPUState *env1) | @@ -293,7 +292,7 @@ int cpu_exec(CPUState *env1) | ||
| 293 | #endif | 292 | #endif |
| 294 | #endif | 293 | #endif |
| 295 | int ret, interrupt_request; | 294 | int ret, interrupt_request; |
| 296 | - long (*gen_func)(void); | 295 | + unsigned long (*gen_func)(void); |
| 297 | TranslationBlock *tb; | 296 | TranslationBlock *tb; |
| 298 | uint8_t *tc_ptr; | 297 | uint8_t *tc_ptr; |
| 299 | 298 | ||
| @@ -414,7 +413,7 @@ int cpu_exec(CPUState *env1) | @@ -414,7 +413,7 @@ int cpu_exec(CPUState *env1) | ||
| 414 | } | 413 | } |
| 415 | #endif | 414 | #endif |
| 416 | 415 | ||
| 417 | - T0 = 0; /* force lookup of first TB */ | 416 | + next_tb = 0; /* force lookup of first TB */ |
| 418 | for(;;) { | 417 | for(;;) { |
| 419 | SAVE_GLOBALS(); | 418 | SAVE_GLOBALS(); |
| 420 | interrupt_request = env->interrupt_request; | 419 | interrupt_request = env->interrupt_request; |
| @@ -443,13 +442,13 @@ int cpu_exec(CPUState *env1) | @@ -443,13 +442,13 @@ int cpu_exec(CPUState *env1) | ||
| 443 | svm_check_intercept(SVM_EXIT_SMI); | 442 | svm_check_intercept(SVM_EXIT_SMI); |
| 444 | env->interrupt_request &= ~CPU_INTERRUPT_SMI; | 443 | env->interrupt_request &= ~CPU_INTERRUPT_SMI; |
| 445 | do_smm_enter(); | 444 | do_smm_enter(); |
| 446 | - BREAK_CHAIN; | 445 | + next_tb = 0; |
| 447 | } else if ((interrupt_request & CPU_INTERRUPT_NMI) && | 446 | } else if ((interrupt_request & CPU_INTERRUPT_NMI) && |
| 448 | !(env->hflags & HF_NMI_MASK)) { | 447 | !(env->hflags & HF_NMI_MASK)) { |
| 449 | env->interrupt_request &= ~CPU_INTERRUPT_NMI; | 448 | env->interrupt_request &= ~CPU_INTERRUPT_NMI; |
| 450 | env->hflags |= HF_NMI_MASK; | 449 | env->hflags |= HF_NMI_MASK; |
| 451 | do_interrupt(EXCP02_NMI, 0, 0, 0, 1); | 450 | do_interrupt(EXCP02_NMI, 0, 0, 0, 1); |
| 452 | - BREAK_CHAIN; | 451 | + next_tb = 0; |
| 453 | } else if ((interrupt_request & CPU_INTERRUPT_HARD) && | 452 | } else if ((interrupt_request & CPU_INTERRUPT_HARD) && |
| 454 | (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) && | 453 | (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) && |
| 455 | !(env->hflags & HF_INHIBIT_IRQ_MASK)) { | 454 | !(env->hflags & HF_INHIBIT_IRQ_MASK)) { |
| @@ -463,7 +462,7 @@ int cpu_exec(CPUState *env1) | @@ -463,7 +462,7 @@ int cpu_exec(CPUState *env1) | ||
| 463 | do_interrupt(intno, 0, 0, 0, 1); | 462 | do_interrupt(intno, 0, 0, 0, 1); |
| 464 | /* ensure that no TB jump will be modified as | 463 | /* ensure that no TB jump will be modified as |
| 465 | the program flow was changed */ | 464 | the program flow was changed */ |
| 466 | - BREAK_CHAIN; | 465 | + next_tb = 0; |
| 467 | #if !defined(CONFIG_USER_ONLY) | 466 | #if !defined(CONFIG_USER_ONLY) |
| 468 | } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) && | 467 | } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) && |
| 469 | (env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) { | 468 | (env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) { |
| @@ -477,7 +476,7 @@ int cpu_exec(CPUState *env1) | @@ -477,7 +476,7 @@ int cpu_exec(CPUState *env1) | ||
| 477 | do_interrupt(intno, 0, 0, -1, 1); | 476 | do_interrupt(intno, 0, 0, -1, 1); |
| 478 | stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), | 477 | stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), |
| 479 | ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK); | 478 | ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK); |
| 480 | - BREAK_CHAIN; | 479 | + next_tb = 0; |
| 481 | #endif | 480 | #endif |
| 482 | } | 481 | } |
| 483 | #elif defined(TARGET_PPC) | 482 | #elif defined(TARGET_PPC) |
| @@ -490,7 +489,7 @@ int cpu_exec(CPUState *env1) | @@ -490,7 +489,7 @@ int cpu_exec(CPUState *env1) | ||
| 490 | ppc_hw_interrupt(env); | 489 | ppc_hw_interrupt(env); |
| 491 | if (env->pending_interrupts == 0) | 490 | if (env->pending_interrupts == 0) |
| 492 | env->interrupt_request &= ~CPU_INTERRUPT_HARD; | 491 | env->interrupt_request &= ~CPU_INTERRUPT_HARD; |
| 493 | - BREAK_CHAIN; | 492 | + next_tb = 0; |
| 494 | } | 493 | } |
| 495 | #elif defined(TARGET_MIPS) | 494 | #elif defined(TARGET_MIPS) |
| 496 | if ((interrupt_request & CPU_INTERRUPT_HARD) && | 495 | if ((interrupt_request & CPU_INTERRUPT_HARD) && |
| @@ -503,7 +502,7 @@ int cpu_exec(CPUState *env1) | @@ -503,7 +502,7 @@ int cpu_exec(CPUState *env1) | ||
| 503 | env->exception_index = EXCP_EXT_INTERRUPT; | 502 | env->exception_index = EXCP_EXT_INTERRUPT; |
| 504 | env->error_code = 0; | 503 | env->error_code = 0; |
| 505 | do_interrupt(env); | 504 | do_interrupt(env); |
| 506 | - BREAK_CHAIN; | 505 | + next_tb = 0; |
| 507 | } | 506 | } |
| 508 | #elif defined(TARGET_SPARC) | 507 | #elif defined(TARGET_SPARC) |
| 509 | if ((interrupt_request & CPU_INTERRUPT_HARD) && | 508 | if ((interrupt_request & CPU_INTERRUPT_HARD) && |
| @@ -520,7 +519,7 @@ int cpu_exec(CPUState *env1) | @@ -520,7 +519,7 @@ int cpu_exec(CPUState *env1) | ||
| 520 | #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) | 519 | #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) |
| 521 | cpu_check_irqs(env); | 520 | cpu_check_irqs(env); |
| 522 | #endif | 521 | #endif |
| 523 | - BREAK_CHAIN; | 522 | + next_tb = 0; |
| 524 | } | 523 | } |
| 525 | } else if (interrupt_request & CPU_INTERRUPT_TIMER) { | 524 | } else if (interrupt_request & CPU_INTERRUPT_TIMER) { |
| 526 | //do_interrupt(0, 0, 0, 0, 0); | 525 | //do_interrupt(0, 0, 0, 0, 0); |
| @@ -531,7 +530,7 @@ int cpu_exec(CPUState *env1) | @@ -531,7 +530,7 @@ int cpu_exec(CPUState *env1) | ||
| 531 | && !(env->uncached_cpsr & CPSR_F)) { | 530 | && !(env->uncached_cpsr & CPSR_F)) { |
| 532 | env->exception_index = EXCP_FIQ; | 531 | env->exception_index = EXCP_FIQ; |
| 533 | do_interrupt(env); | 532 | do_interrupt(env); |
| 534 | - BREAK_CHAIN; | 533 | + next_tb = 0; |
| 535 | } | 534 | } |
| 536 | /* ARMv7-M interrupt return works by loading a magic value | 535 | /* ARMv7-M interrupt return works by loading a magic value |
| 537 | into the PC. On real hardware the load causes the | 536 | into the PC. On real hardware the load causes the |
| @@ -547,22 +546,22 @@ int cpu_exec(CPUState *env1) | @@ -547,22 +546,22 @@ int cpu_exec(CPUState *env1) | ||
| 547 | || !(env->uncached_cpsr & CPSR_I))) { | 546 | || !(env->uncached_cpsr & CPSR_I))) { |
| 548 | env->exception_index = EXCP_IRQ; | 547 | env->exception_index = EXCP_IRQ; |
| 549 | do_interrupt(env); | 548 | do_interrupt(env); |
| 550 | - BREAK_CHAIN; | 549 | + next_tb = 0; |
| 551 | } | 550 | } |
| 552 | #elif defined(TARGET_SH4) | 551 | #elif defined(TARGET_SH4) |
| 553 | if (interrupt_request & CPU_INTERRUPT_HARD) { | 552 | if (interrupt_request & CPU_INTERRUPT_HARD) { |
| 554 | do_interrupt(env); | 553 | do_interrupt(env); |
| 555 | - BREAK_CHAIN; | 554 | + next_tb = 0; |
| 556 | } | 555 | } |
| 557 | #elif defined(TARGET_ALPHA) | 556 | #elif defined(TARGET_ALPHA) |
| 558 | if (interrupt_request & CPU_INTERRUPT_HARD) { | 557 | if (interrupt_request & CPU_INTERRUPT_HARD) { |
| 559 | do_interrupt(env); | 558 | do_interrupt(env); |
| 560 | - BREAK_CHAIN; | 559 | + next_tb = 0; |
| 561 | } | 560 | } |
| 562 | #elif defined(TARGET_CRIS) | 561 | #elif defined(TARGET_CRIS) |
| 563 | if (interrupt_request & CPU_INTERRUPT_HARD) { | 562 | if (interrupt_request & CPU_INTERRUPT_HARD) { |
| 564 | do_interrupt(env); | 563 | do_interrupt(env); |
| 565 | - BREAK_CHAIN; | 564 | + next_tb = 0; |
| 566 | } | 565 | } |
| 567 | #elif defined(TARGET_M68K) | 566 | #elif defined(TARGET_M68K) |
| 568 | if (interrupt_request & CPU_INTERRUPT_HARD | 567 | if (interrupt_request & CPU_INTERRUPT_HARD |
| @@ -575,7 +574,7 @@ int cpu_exec(CPUState *env1) | @@ -575,7 +574,7 @@ int cpu_exec(CPUState *env1) | ||
| 575 | first signalled. */ | 574 | first signalled. */ |
| 576 | env->exception_index = env->pending_vector; | 575 | env->exception_index = env->pending_vector; |
| 577 | do_interrupt(1); | 576 | do_interrupt(1); |
| 578 | - BREAK_CHAIN; | 577 | + next_tb = 0; |
| 579 | } | 578 | } |
| 580 | #endif | 579 | #endif |
| 581 | /* Don't use the cached interupt_request value, | 580 | /* Don't use the cached interupt_request value, |
| @@ -584,7 +583,7 @@ int cpu_exec(CPUState *env1) | @@ -584,7 +583,7 @@ int cpu_exec(CPUState *env1) | ||
| 584 | env->interrupt_request &= ~CPU_INTERRUPT_EXITTB; | 583 | env->interrupt_request &= ~CPU_INTERRUPT_EXITTB; |
| 585 | /* ensure that no TB jump will be modified as | 584 | /* ensure that no TB jump will be modified as |
| 586 | the program flow was changed */ | 585 | the program flow was changed */ |
| 587 | - BREAK_CHAIN; | 586 | + next_tb = 0; |
| 588 | } | 587 | } |
| 589 | if (interrupt_request & CPU_INTERRUPT_EXIT) { | 588 | if (interrupt_request & CPU_INTERRUPT_EXIT) { |
| 590 | env->interrupt_request &= ~CPU_INTERRUPT_EXIT; | 589 | env->interrupt_request &= ~CPU_INTERRUPT_EXIT; |
| @@ -640,13 +639,13 @@ int cpu_exec(CPUState *env1) | @@ -640,13 +639,13 @@ int cpu_exec(CPUState *env1) | ||
| 640 | spans two pages, we cannot safely do a direct | 639 | spans two pages, we cannot safely do a direct |
| 641 | jump. */ | 640 | jump. */ |
| 642 | { | 641 | { |
| 643 | - if (T0 != 0 && | 642 | + if (next_tb != 0 && |
| 644 | #if USE_KQEMU | 643 | #if USE_KQEMU |
| 645 | (env->kqemu_enabled != 2) && | 644 | (env->kqemu_enabled != 2) && |
| 646 | #endif | 645 | #endif |
| 647 | tb->page_addr[1] == -1) { | 646 | tb->page_addr[1] == -1) { |
| 648 | spin_lock(&tb_lock); | 647 | spin_lock(&tb_lock); |
| 649 | - tb_add_jump((TranslationBlock *)(long)(T0 & ~3), T0 & 3, tb); | 648 | + tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb); |
| 650 | spin_unlock(&tb_lock); | 649 | spin_unlock(&tb_lock); |
| 651 | } | 650 | } |
| 652 | } | 651 | } |
| @@ -667,7 +666,7 @@ int cpu_exec(CPUState *env1) | @@ -667,7 +666,7 @@ int cpu_exec(CPUState *env1) | ||
| 667 | asm volatile ("ble 0(%%sr4,%1)\n" | 666 | asm volatile ("ble 0(%%sr4,%1)\n" |
| 668 | "copy %%r31,%%r18\n" | 667 | "copy %%r31,%%r18\n" |
| 669 | "copy %%r28,%0\n" | 668 | "copy %%r28,%0\n" |
| 670 | - : "=r" (T0) | 669 | + : "=r" (next_tb) |
| 671 | : "r" (gen_func) | 670 | : "r" (gen_func) |
| 672 | : "r1", "r2", "r3", "r4", "r5", "r6", "r7", | 671 | : "r1", "r2", "r3", "r4", "r5", "r6", "r7", |
| 673 | "r8", "r9", "r10", "r11", "r12", "r13", | 672 | "r8", "r9", "r10", "r11", "r12", "r13", |
| @@ -690,8 +689,29 @@ int cpu_exec(CPUState *env1) | @@ -690,8 +689,29 @@ int cpu_exec(CPUState *env1) | ||
| 690 | fp.ip = tc_ptr; | 689 | fp.ip = tc_ptr; |
| 691 | fp.gp = code_gen_buffer + 2 * (1 << 20); | 690 | fp.gp = code_gen_buffer + 2 * (1 << 20); |
| 692 | (*(void (*)(void)) &fp)(); | 691 | (*(void (*)(void)) &fp)(); |
| 692 | +#elif defined(__i386) | ||
| 693 | + asm volatile ("sub $12, %%esp\n\t" | ||
| 694 | + "push %%ebp\n\t" | ||
| 695 | + "call *%1\n\t" | ||
| 696 | + "pop %%ebp\n\t" | ||
| 697 | + "add $12, %%esp\n\t" | ||
| 698 | + : "=a" (next_tb) | ||
| 699 | + : "a" (gen_func) | ||
| 700 | + : "ebx", "ecx", "edx", "esi", "edi", "cc", | ||
| 701 | + "memory"); | ||
| 702 | +#elif defined(__x86_64__) | ||
| 703 | + asm volatile ("sub $8, %%rsp\n\t" | ||
| 704 | + "push %%rbp\n\t" | ||
| 705 | + "call *%1\n\t" | ||
| 706 | + "pop %%rbp\n\t" | ||
| 707 | + "add $8, %%rsp\n\t" | ||
| 708 | + : "=a" (next_tb) | ||
| 709 | + : "a" (gen_func) | ||
| 710 | + : "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9", | ||
| 711 | + "r10", "r11", "r12", "r13", "r14", "r15", "cc", | ||
| 712 | + "memory"); | ||
| 693 | #else | 713 | #else |
| 694 | - T0 = gen_func(); | 714 | + next_tb = gen_func(); |
| 695 | #endif | 715 | #endif |
| 696 | env->current_tb = NULL; | 716 | env->current_tb = NULL; |
| 697 | /* reset soft MMU for next block (it can currently | 717 | /* reset soft MMU for next block (it can currently |
| @@ -700,7 +720,7 @@ int cpu_exec(CPUState *env1) | @@ -700,7 +720,7 @@ int cpu_exec(CPUState *env1) | ||
| 700 | if (env->hflags & HF_SOFTMMU_MASK) { | 720 | if (env->hflags & HF_SOFTMMU_MASK) { |
| 701 | env->hflags &= ~HF_SOFTMMU_MASK; | 721 | env->hflags &= ~HF_SOFTMMU_MASK; |
| 702 | /* do not allow linking to another block */ | 722 | /* do not allow linking to another block */ |
| 703 | - T0 = 0; | 723 | + next_tb = 0; |
| 704 | } | 724 | } |
| 705 | #endif | 725 | #endif |
| 706 | #if defined(USE_KQEMU) | 726 | #if defined(USE_KQEMU) |