Commit fbf9eeb34dfd9f9eb805410d90ffbb9ca2c0fbd1
1 parent
046d6672
added cpu_resume_from_signal() - irq fix
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@755 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
52 additions
and
20 deletions
cpu-exec.c
| @@ -21,6 +21,20 @@ | @@ -21,6 +21,20 @@ | ||
| 21 | #include "exec.h" | 21 | #include "exec.h" |
| 22 | #include "disas.h" | 22 | #include "disas.h" |
| 23 | 23 | ||
| 24 | +#if !defined(CONFIG_SOFTMMU) | ||
| 25 | +#undef EAX | ||
| 26 | +#undef ECX | ||
| 27 | +#undef EDX | ||
| 28 | +#undef EBX | ||
| 29 | +#undef ESP | ||
| 30 | +#undef EBP | ||
| 31 | +#undef ESI | ||
| 32 | +#undef EDI | ||
| 33 | +#undef EIP | ||
| 34 | +#include <signal.h> | ||
| 35 | +#include <sys/ucontext.h> | ||
| 36 | +#endif | ||
| 37 | + | ||
| 24 | int tb_invalidated_flag; | 38 | int tb_invalidated_flag; |
| 25 | 39 | ||
| 26 | //#define DEBUG_EXEC | 40 | //#define DEBUG_EXEC |
| @@ -34,6 +48,28 @@ void cpu_loop_exit(void) | @@ -34,6 +48,28 @@ void cpu_loop_exit(void) | ||
| 34 | } | 48 | } |
| 35 | #endif | 49 | #endif |
| 36 | 50 | ||
| 51 | +/* exit the current TB from a signal handler. The host registers are | ||
| 52 | + restored in a state compatible with the CPU emulator | ||
| 53 | + */ | ||
| 54 | +void cpu_resume_from_signal(CPUState *env1, void *puc) | ||
| 55 | +{ | ||
| 56 | +#if !defined(CONFIG_SOFTMMU) | ||
| 57 | + struct ucontext *uc = puc; | ||
| 58 | +#endif | ||
| 59 | + | ||
| 60 | + env = env1; | ||
| 61 | + | ||
| 62 | + /* XXX: restore cpu registers saved in host registers */ | ||
| 63 | + | ||
| 64 | +#if !defined(CONFIG_SOFTMMU) | ||
| 65 | + if (puc) { | ||
| 66 | + /* XXX: use siglongjmp ? */ | ||
| 67 | + sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL); | ||
| 68 | + } | ||
| 69 | +#endif | ||
| 70 | + longjmp(env->jmp_env, 1); | ||
| 71 | +} | ||
| 72 | + | ||
| 37 | /* main execution loop */ | 73 | /* main execution loop */ |
| 38 | 74 | ||
| 39 | int cpu_exec(CPUState *env1) | 75 | int cpu_exec(CPUState *env1) |
| @@ -190,12 +226,12 @@ int cpu_exec(CPUState *env1) | @@ -190,12 +226,12 @@ int cpu_exec(CPUState *env1) | ||
| 190 | (env->eflags & IF_MASK) && | 226 | (env->eflags & IF_MASK) && |
| 191 | !(env->hflags & HF_INHIBIT_IRQ_MASK)) { | 227 | !(env->hflags & HF_INHIBIT_IRQ_MASK)) { |
| 192 | int intno; | 228 | int intno; |
| 229 | + env->interrupt_request &= ~CPU_INTERRUPT_HARD; | ||
| 193 | intno = cpu_get_pic_interrupt(env); | 230 | intno = cpu_get_pic_interrupt(env); |
| 194 | if (loglevel & CPU_LOG_TB_IN_ASM) { | 231 | if (loglevel & CPU_LOG_TB_IN_ASM) { |
| 195 | fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno); | 232 | fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno); |
| 196 | } | 233 | } |
| 197 | do_interrupt(intno, 0, 0, 0, 1); | 234 | do_interrupt(intno, 0, 0, 0, 1); |
| 198 | - env->interrupt_request &= ~CPU_INTERRUPT_HARD; | ||
| 199 | /* ensure that no TB jump will be modified as | 235 | /* ensure that no TB jump will be modified as |
| 200 | the program flow was changed */ | 236 | the program flow was changed */ |
| 201 | #ifdef __sparc__ | 237 | #ifdef __sparc__ |
| @@ -548,6 +584,15 @@ int cpu_exec(CPUState *env1) | @@ -548,6 +584,15 @@ int cpu_exec(CPUState *env1) | ||
| 548 | return ret; | 584 | return ret; |
| 549 | } | 585 | } |
| 550 | 586 | ||
| 587 | +/* must only be called from the generated code as an exception can be | ||
| 588 | + generated */ | ||
| 589 | +void tb_invalidate_page_range(target_ulong start, target_ulong end) | ||
| 590 | +{ | ||
| 591 | + target_ulong phys_addr; | ||
| 592 | + phys_addr = get_phys_addr_code(env, start); | ||
| 593 | + tb_invalidate_phys_page_range(phys_addr, phys_addr + end - start, 0); | ||
| 594 | +} | ||
| 595 | + | ||
| 551 | #if defined(TARGET_I386) && defined(CONFIG_USER_ONLY) | 596 | #if defined(TARGET_I386) && defined(CONFIG_USER_ONLY) |
| 552 | 597 | ||
| 553 | void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector) | 598 | void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector) |
| @@ -594,18 +639,6 @@ void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32) | @@ -594,18 +639,6 @@ void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32) | ||
| 594 | 639 | ||
| 595 | #if !defined(CONFIG_SOFTMMU) | 640 | #if !defined(CONFIG_SOFTMMU) |
| 596 | 641 | ||
| 597 | -#undef EAX | ||
| 598 | -#undef ECX | ||
| 599 | -#undef EDX | ||
| 600 | -#undef EBX | ||
| 601 | -#undef ESP | ||
| 602 | -#undef EBP | ||
| 603 | -#undef ESI | ||
| 604 | -#undef EDI | ||
| 605 | -#undef EIP | ||
| 606 | -#include <signal.h> | ||
| 607 | -#include <sys/ucontext.h> | ||
| 608 | - | ||
| 609 | #if defined(TARGET_I386) | 642 | #if defined(TARGET_I386) |
| 610 | 643 | ||
| 611 | /* 'pc' is the host PC at which the exception was raised. 'address' is | 644 | /* 'pc' is the host PC at which the exception was raised. 'address' is |
| @@ -626,9 +659,10 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, | @@ -626,9 +659,10 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, | ||
| 626 | pc, address, is_write, *(unsigned long *)old_set); | 659 | pc, address, is_write, *(unsigned long *)old_set); |
| 627 | #endif | 660 | #endif |
| 628 | /* XXX: locking issue */ | 661 | /* XXX: locking issue */ |
| 629 | - if (is_write && page_unprotect(address)) { | 662 | + if (is_write && page_unprotect(address, pc, puc)) { |
| 630 | return 1; | 663 | return 1; |
| 631 | } | 664 | } |
| 665 | + | ||
| 632 | /* see if it is an MMU fault */ | 666 | /* see if it is an MMU fault */ |
| 633 | ret = cpu_x86_handle_mmu_fault(env, address, is_write, | 667 | ret = cpu_x86_handle_mmu_fault(env, address, is_write, |
| 634 | ((env->hflags & HF_CPL_MASK) == 3), 0); | 668 | ((env->hflags & HF_CPL_MASK) == 3), 0); |
| @@ -655,8 +689,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, | @@ -655,8 +689,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, | ||
| 655 | } else { | 689 | } else { |
| 656 | /* activate soft MMU for this block */ | 690 | /* activate soft MMU for this block */ |
| 657 | env->hflags |= HF_SOFTMMU_MASK; | 691 | env->hflags |= HF_SOFTMMU_MASK; |
| 658 | - sigprocmask(SIG_SETMASK, old_set, NULL); | ||
| 659 | - cpu_loop_exit(); | 692 | + cpu_resume_from_signal(env, puc); |
| 660 | } | 693 | } |
| 661 | /* never comes here */ | 694 | /* never comes here */ |
| 662 | return 1; | 695 | return 1; |
| @@ -676,7 +709,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, | @@ -676,7 +709,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, | ||
| 676 | void *puc) | 709 | void *puc) |
| 677 | { | 710 | { |
| 678 | /* XXX: locking issue */ | 711 | /* XXX: locking issue */ |
| 679 | - if (is_write && page_unprotect(address)) { | 712 | + if (is_write && page_unprotect(address, pc, puc)) { |
| 680 | return 1; | 713 | return 1; |
| 681 | } | 714 | } |
| 682 | return 0; | 715 | return 0; |
| @@ -698,7 +731,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, | @@ -698,7 +731,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, | ||
| 698 | pc, address, is_write, *(unsigned long *)old_set); | 731 | pc, address, is_write, *(unsigned long *)old_set); |
| 699 | #endif | 732 | #endif |
| 700 | /* XXX: locking issue */ | 733 | /* XXX: locking issue */ |
| 701 | - if (is_write && page_unprotect(address)) { | 734 | + if (is_write && page_unprotect(address, pc, puc)) { |
| 702 | return 1; | 735 | return 1; |
| 703 | } | 736 | } |
| 704 | 737 | ||
| @@ -727,8 +760,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, | @@ -727,8 +760,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, | ||
| 727 | do_queue_exception_err(env->exception_index, env->error_code); | 760 | do_queue_exception_err(env->exception_index, env->error_code); |
| 728 | } else { | 761 | } else { |
| 729 | /* activate soft MMU for this block */ | 762 | /* activate soft MMU for this block */ |
| 730 | - sigprocmask(SIG_SETMASK, old_set, NULL); | ||
| 731 | - cpu_loop_exit(); | 763 | + cpu_resume_from_signal(env, puc); |
| 732 | } | 764 | } |
| 733 | /* never comes here */ | 765 | /* never comes here */ |
| 734 | return 1; | 766 | return 1; |