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