Commit fbf9eeb34dfd9f9eb805410d90ffbb9ca2c0fbd1

Authored by bellard
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;