Commit db620f46a8c8b168831812eabd7428a952964334

Authored by bellard
1 parent 3cd9acb4

reworked SVM interrupt handling logic - fixed vmrun EIP saved value - reworked c…

…r8 handling - added CPUState.hflags2

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4662 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-exec.c
@@ -368,11 +368,8 @@ int cpu_exec(CPUState *env1) @@ -368,11 +368,8 @@ int cpu_exec(CPUState *env1)
368 next_tb = 0; /* force lookup of first TB */ 368 next_tb = 0; /* force lookup of first TB */
369 for(;;) { 369 for(;;) {
370 interrupt_request = env->interrupt_request; 370 interrupt_request = env->interrupt_request;
371 - if (__builtin_expect(interrupt_request, 0)  
372 -#if defined(TARGET_I386)  
373 - && env->hflags & HF_GIF_MASK  
374 -#endif  
375 - && likely(!(env->singlestep_enabled & SSTEP_NOIRQ))) { 371 + if (__builtin_expect(interrupt_request, 0) &&
  372 + likely(!(env->singlestep_enabled & SSTEP_NOIRQ))) {
376 if (interrupt_request & CPU_INTERRUPT_DEBUG) { 373 if (interrupt_request & CPU_INTERRUPT_DEBUG) {
377 env->interrupt_request &= ~CPU_INTERRUPT_DEBUG; 374 env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
378 env->exception_index = EXCP_DEBUG; 375 env->exception_index = EXCP_DEBUG;
@@ -388,47 +385,51 @@ int cpu_exec(CPUState *env1) @@ -388,47 +385,51 @@ int cpu_exec(CPUState *env1)
388 } 385 }
389 #endif 386 #endif
390 #if defined(TARGET_I386) 387 #if defined(TARGET_I386)
391 - if ((interrupt_request & CPU_INTERRUPT_SMI) &&  
392 - !(env->hflags & HF_SMM_MASK)) {  
393 - svm_check_intercept(SVM_EXIT_SMI);  
394 - env->interrupt_request &= ~CPU_INTERRUPT_SMI;  
395 - do_smm_enter();  
396 - next_tb = 0;  
397 - } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&  
398 - !(env->hflags & HF_NMI_MASK)) {  
399 - env->interrupt_request &= ~CPU_INTERRUPT_NMI;  
400 - env->hflags |= HF_NMI_MASK;  
401 - do_interrupt(EXCP02_NMI, 0, 0, 0, 1);  
402 - next_tb = 0;  
403 - } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&  
404 - (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) &&  
405 - !(env->hflags & HF_INHIBIT_IRQ_MASK)) {  
406 - int intno;  
407 - svm_check_intercept(SVM_EXIT_INTR);  
408 - env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);  
409 - intno = cpu_get_pic_interrupt(env);  
410 - if (loglevel & CPU_LOG_TB_IN_ASM) {  
411 - fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);  
412 - }  
413 - do_interrupt(intno, 0, 0, 0, 1);  
414 - /* ensure that no TB jump will be modified as  
415 - the program flow was changed */  
416 - next_tb = 0; 388 + if (env->hflags2 & HF2_GIF_MASK) {
  389 + if ((interrupt_request & CPU_INTERRUPT_SMI) &&
  390 + !(env->hflags & HF_SMM_MASK)) {
  391 + svm_check_intercept(SVM_EXIT_SMI);
  392 + env->interrupt_request &= ~CPU_INTERRUPT_SMI;
  393 + do_smm_enter();
  394 + next_tb = 0;
  395 + } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
  396 + !(env->hflags2 & HF2_NMI_MASK)) {
  397 + env->interrupt_request &= ~CPU_INTERRUPT_NMI;
  398 + env->hflags2 |= HF2_NMI_MASK;
  399 + do_interrupt(EXCP02_NMI, 0, 0, 0, 1);
  400 + next_tb = 0;
  401 + } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
  402 + (((env->hflags2 & HF2_VINTR_MASK) &&
  403 + (env->hflags2 & HF2_HIF_MASK)) ||
  404 + (!(env->hflags2 & HF2_VINTR_MASK) &&
  405 + (env->eflags & IF_MASK &&
  406 + !(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
  407 + int intno;
  408 + svm_check_intercept(SVM_EXIT_INTR);
  409 + env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
  410 + intno = cpu_get_pic_interrupt(env);
  411 + if (loglevel & CPU_LOG_TB_IN_ASM) {
  412 + fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
  413 + }
  414 + do_interrupt(intno, 0, 0, 0, 1);
  415 + /* ensure that no TB jump will be modified as
  416 + the program flow was changed */
  417 + next_tb = 0;
417 #if !defined(CONFIG_USER_ONLY) 418 #if !defined(CONFIG_USER_ONLY)
418 - } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&  
419 - (env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) {  
420 - int intno;  
421 - /* FIXME: this should respect TPR */  
422 - env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;  
423 - svm_check_intercept(SVM_EXIT_VINTR);  
424 - intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));  
425 - if (loglevel & CPU_LOG_TB_IN_ASM)  
426 - fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno);  
427 - do_interrupt(intno, 0, 0, -1, 1);  
428 - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),  
429 - ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK);  
430 - next_tb = 0; 419 + } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
  420 + (env->eflags & IF_MASK) &&
  421 + !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
  422 + int intno;
  423 + /* FIXME: this should respect TPR */
  424 + svm_check_intercept(SVM_EXIT_VINTR);
  425 + env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
  426 + intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
  427 + if (loglevel & CPU_LOG_TB_IN_ASM)
  428 + fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno);
  429 + do_interrupt(intno, 0, 0, 0, 1);
  430 + next_tb = 0;
431 #endif 431 #endif
  432 + }
432 } 433 }
433 #elif defined(TARGET_PPC) 434 #elif defined(TARGET_PPC)
434 #if 0 435 #if 0
target-i386/cpu.h
@@ -145,11 +145,8 @@ @@ -145,11 +145,8 @@
145 #define HF_OSFXSR_SHIFT 16 /* CR4.OSFXSR */ 145 #define HF_OSFXSR_SHIFT 16 /* CR4.OSFXSR */
146 #define HF_VM_SHIFT 17 /* must be same as eflags */ 146 #define HF_VM_SHIFT 17 /* must be same as eflags */
147 #define HF_SMM_SHIFT 19 /* CPU in SMM mode */ 147 #define HF_SMM_SHIFT 19 /* CPU in SMM mode */
148 -#define HF_GIF_SHIFT 20 /* if set CPU takes interrupts */  
149 -#define HF_HIF_SHIFT 21 /* shadow copy of IF_MASK when in SVM */  
150 -#define HF_NMI_SHIFT 22 /* CPU serving NMI */  
151 -#define HF_SVME_SHIFT 23 /* SVME enabled (copy of EFER.SVME) */  
152 -#define HF_SVMI_SHIFT 24 /* SVM intercepts are active */ 148 +#define HF_SVME_SHIFT 20 /* SVME enabled (copy of EFER.SVME) */
  149 +#define HF_SVMI_SHIFT 21 /* SVM intercepts are active */
153 150
154 #define HF_CPL_MASK (3 << HF_CPL_SHIFT) 151 #define HF_CPL_MASK (3 << HF_CPL_SHIFT)
155 #define HF_SOFTMMU_MASK (1 << HF_SOFTMMU_SHIFT) 152 #define HF_SOFTMMU_MASK (1 << HF_SOFTMMU_SHIFT)
@@ -166,12 +163,21 @@ @@ -166,12 +163,21 @@
166 #define HF_CS64_MASK (1 << HF_CS64_SHIFT) 163 #define HF_CS64_MASK (1 << HF_CS64_SHIFT)
167 #define HF_OSFXSR_MASK (1 << HF_OSFXSR_SHIFT) 164 #define HF_OSFXSR_MASK (1 << HF_OSFXSR_SHIFT)
168 #define HF_SMM_MASK (1 << HF_SMM_SHIFT) 165 #define HF_SMM_MASK (1 << HF_SMM_SHIFT)
169 -#define HF_GIF_MASK (1 << HF_GIF_SHIFT)  
170 -#define HF_HIF_MASK (1 << HF_HIF_SHIFT)  
171 -#define HF_NMI_MASK (1 << HF_NMI_SHIFT)  
172 #define HF_SVME_MASK (1 << HF_SVME_SHIFT) 166 #define HF_SVME_MASK (1 << HF_SVME_SHIFT)
173 #define HF_SVMI_MASK (1 << HF_SVMI_SHIFT) 167 #define HF_SVMI_MASK (1 << HF_SVMI_SHIFT)
174 168
  169 +/* hflags2 */
  170 +
  171 +#define HF2_GIF_SHIFT 0 /* if set CPU takes interrupts */
  172 +#define HF2_HIF_SHIFT 1 /* value of IF_MASK when entering SVM */
  173 +#define HF2_NMI_SHIFT 2 /* CPU serving NMI */
  174 +#define HF2_VINTR_SHIFT 3 /* value of V_INTR_MASKING bit */
  175 +
  176 +#define HF2_GIF_MASK (1 << HF2_GIF_SHIFT)
  177 +#define HF2_HIF_MASK (1 << HF2_HIF_SHIFT)
  178 +#define HF2_NMI_MASK (1 << HF2_NMI_SHIFT)
  179 +#define HF2_VINTR_MASK (1 << HF2_VINTR_SHIFT)
  180 +
175 #define CR0_PE_MASK (1 << 0) 181 #define CR0_PE_MASK (1 << 0)
176 #define CR0_MP_MASK (1 << 1) 182 #define CR0_MP_MASK (1 << 1)
177 #define CR0_EM_MASK (1 << 2) 183 #define CR0_EM_MASK (1 << 2)
@@ -488,7 +494,9 @@ typedef struct CPUX86State { @@ -488,7 +494,9 @@ typedef struct CPUX86State {
488 target_ulong cc_dst; 494 target_ulong cc_dst;
489 uint32_t cc_op; 495 uint32_t cc_op;
490 int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */ 496 int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */
491 - uint32_t hflags; /* hidden flags, see HF_xxx constants */ 497 + uint32_t hflags; /* TB flags, see HF_xxx constants. These flags
  498 + are known at translation time. */
  499 + uint32_t hflags2; /* various other flags, see HF2_xxx constants. */
492 500
493 /* segments */ 501 /* segments */
494 SegmentCache segs[6]; /* selector values */ 502 SegmentCache segs[6]; /* selector values */
@@ -497,7 +505,7 @@ typedef struct CPUX86State { @@ -497,7 +505,7 @@ typedef struct CPUX86State {
497 SegmentCache gdt; /* only base and limit are used */ 505 SegmentCache gdt; /* only base and limit are used */
498 SegmentCache idt; /* only base and limit are used */ 506 SegmentCache idt; /* only base and limit are used */
499 507
500 - target_ulong cr[9]; /* NOTE: cr1, cr5-7 are unused */ 508 + target_ulong cr[5]; /* NOTE: cr1 is unused */
501 uint64_t a20_mask; 509 uint64_t a20_mask;
502 510
503 /* FPU state */ 511 /* FPU state */
@@ -541,6 +549,7 @@ typedef struct CPUX86State { @@ -541,6 +549,7 @@ typedef struct CPUX86State {
541 uint16_t intercept_dr_read; 549 uint16_t intercept_dr_read;
542 uint16_t intercept_dr_write; 550 uint16_t intercept_dr_write;
543 uint32_t intercept_exceptions; 551 uint32_t intercept_exceptions;
  552 + uint8_t v_tpr;
544 553
545 #ifdef TARGET_X86_64 554 #ifdef TARGET_X86_64
546 target_ulong lstar; 555 target_ulong lstar;
target-i386/helper.c
@@ -374,7 +374,7 @@ void cpu_reset(CPUX86State *env) @@ -374,7 +374,7 @@ void cpu_reset(CPUX86State *env)
374 #ifdef CONFIG_SOFTMMU 374 #ifdef CONFIG_SOFTMMU
375 env->hflags |= HF_SOFTMMU_MASK; 375 env->hflags |= HF_SOFTMMU_MASK;
376 #endif 376 #endif
377 - env->hflags |= HF_GIF_MASK; 377 + env->hflags2 |= HF2_GIF_MASK;
378 378
379 cpu_x86_update_cr0(env, 0x60000010); 379 cpu_x86_update_cr0(env, 0x60000010);
380 env->a20_mask = ~0x0; 380 env->a20_mask = ~0x0;
target-i386/helper.h
@@ -47,9 +47,6 @@ DEF_HELPER(target_ulong, helper_read_crN, (int reg)) @@ -47,9 +47,6 @@ DEF_HELPER(target_ulong, helper_read_crN, (int reg))
47 DEF_HELPER(void, helper_write_crN, (int reg, target_ulong t0)) 47 DEF_HELPER(void, helper_write_crN, (int reg, target_ulong t0))
48 DEF_HELPER(void, helper_lmsw, (target_ulong t0)) 48 DEF_HELPER(void, helper_lmsw, (target_ulong t0))
49 DEF_HELPER(void, helper_clts, (void)) 49 DEF_HELPER(void, helper_clts, (void))
50 -#if !defined(CONFIG_USER_ONLY)  
51 -DEF_HELPER(target_ulong, helper_movtl_T0_cr8, (void))  
52 -#endif  
53 DEF_HELPER(void, helper_movl_drN_T0, (int reg, target_ulong t0)) 50 DEF_HELPER(void, helper_movl_drN_T0, (int reg, target_ulong t0))
54 DEF_HELPER(void, helper_invlpg, (target_ulong addr)) 51 DEF_HELPER(void, helper_invlpg, (target_ulong addr))
55 52
@@ -102,7 +99,7 @@ DEF_HELPER(void, helper_svm_check_intercept_param, (uint32_t type, uint64_t para @@ -102,7 +99,7 @@ DEF_HELPER(void, helper_svm_check_intercept_param, (uint32_t type, uint64_t para
102 DEF_HELPER(void, helper_vmexit, (uint32_t exit_code, uint64_t exit_info_1)) 99 DEF_HELPER(void, helper_vmexit, (uint32_t exit_code, uint64_t exit_info_1))
103 DEF_HELPER(void, helper_svm_check_io, (uint32_t port, uint32_t param, 100 DEF_HELPER(void, helper_svm_check_io, (uint32_t port, uint32_t param,
104 uint32_t next_eip_addend)) 101 uint32_t next_eip_addend))
105 -DEF_HELPER(void, helper_vmrun, (int aflag)) 102 +DEF_HELPER(void, helper_vmrun, (int aflag, int next_eip_addend))
106 DEF_HELPER(void, helper_vmmcall, (void)) 103 DEF_HELPER(void, helper_vmmcall, (void))
107 DEF_HELPER(void, helper_vmload, (int aflag)) 104 DEF_HELPER(void, helper_vmload, (int aflag))
108 DEF_HELPER(void, helper_vmsave, (int aflag)) 105 DEF_HELPER(void, helper_vmsave, (int aflag))
target-i386/op_helper.c
@@ -2591,7 +2591,7 @@ void helper_iret_real(int shift) @@ -2591,7 +2591,7 @@ void helper_iret_real(int shift)
2591 if (shift == 0) 2591 if (shift == 0)
2592 eflags_mask &= 0xffff; 2592 eflags_mask &= 0xffff;
2593 load_eflags(new_eflags, eflags_mask); 2593 load_eflags(new_eflags, eflags_mask);
2594 - env->hflags &= ~HF_NMI_MASK; 2594 + env->hflags2 &= ~HF2_NMI_MASK;
2595 } 2595 }
2596 2596
2597 static inline void validate_seg(int seg_reg, int cpl) 2597 static inline void validate_seg(int seg_reg, int cpl)
@@ -2843,7 +2843,7 @@ void helper_iret_protected(int shift, int next_eip) @@ -2843,7 +2843,7 @@ void helper_iret_protected(int shift, int next_eip)
2843 } else { 2843 } else {
2844 helper_ret_protected(shift, 1, 0); 2844 helper_ret_protected(shift, 1, 0);
2845 } 2845 }
2846 - env->hflags &= ~HF_NMI_MASK; 2846 + env->hflags2 &= ~HF2_NMI_MASK;
2847 #ifdef USE_KQEMU 2847 #ifdef USE_KQEMU
2848 if (kqemu_is_ok(env)) { 2848 if (kqemu_is_ok(env)) {
2849 CC_OP = CC_OP_EFLAGS; 2849 CC_OP = CC_OP_EFLAGS;
@@ -2934,7 +2934,11 @@ target_ulong helper_read_crN(int reg) @@ -2934,7 +2934,11 @@ target_ulong helper_read_crN(int reg)
2934 val = env->cr[reg]; 2934 val = env->cr[reg];
2935 break; 2935 break;
2936 case 8: 2936 case 8:
2937 - val = cpu_get_apic_tpr(env); 2937 + if (!(env->hflags2 & HF2_VINTR_MASK)) {
  2938 + val = cpu_get_apic_tpr(env);
  2939 + } else {
  2940 + val = env->v_tpr;
  2941 + }
2938 break; 2942 break;
2939 } 2943 }
2940 return val; 2944 return val;
@@ -2954,8 +2958,10 @@ void helper_write_crN(int reg, target_ulong t0) @@ -2954,8 +2958,10 @@ void helper_write_crN(int reg, target_ulong t0)
2954 cpu_x86_update_cr4(env, t0); 2958 cpu_x86_update_cr4(env, t0);
2955 break; 2959 break;
2956 case 8: 2960 case 8:
2957 - cpu_set_apic_tpr(env, t0);  
2958 - env->cr[8] = t0; 2961 + if (!(env->hflags2 & HF2_VINTR_MASK)) {
  2962 + cpu_set_apic_tpr(env, t0);
  2963 + }
  2964 + env->v_tpr = t0 & 0x0f;
2959 break; 2965 break;
2960 default: 2966 default:
2961 env->cr[reg] = t0; 2967 env->cr[reg] = t0;
@@ -2978,13 +2984,6 @@ void helper_clts(void) @@ -2978,13 +2984,6 @@ void helper_clts(void)
2978 env->hflags &= ~HF_TS_MASK; 2984 env->hflags &= ~HF_TS_MASK;
2979 } 2985 }
2980 2986
2981 -#if !defined(CONFIG_USER_ONLY)  
2982 -target_ulong helper_movtl_T0_cr8(void)  
2983 -{  
2984 - return cpu_get_apic_tpr(env);  
2985 -}  
2986 -#endif  
2987 -  
2988 /* XXX: do more */ 2987 /* XXX: do more */
2989 void helper_movl_drN_T0(int reg, target_ulong t0) 2988 void helper_movl_drN_T0(int reg, target_ulong t0)
2990 { 2989 {
@@ -4721,7 +4720,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr) @@ -4721,7 +4720,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
4721 4720
4722 #if defined(CONFIG_USER_ONLY) 4721 #if defined(CONFIG_USER_ONLY)
4723 4722
4724 -void helper_vmrun(int aflag) 4723 +void helper_vmrun(int aflag, int next_eip_addend)
4725 { 4724 {
4726 } 4725 }
4727 void helper_vmmcall(void) 4726 void helper_vmmcall(void)
@@ -4791,7 +4790,7 @@ static inline void svm_load_seg_cache(target_phys_addr_t addr, @@ -4791,7 +4790,7 @@ static inline void svm_load_seg_cache(target_phys_addr_t addr,
4791 sc->base, sc->limit, sc->flags); 4790 sc->base, sc->limit, sc->flags);
4792 } 4791 }
4793 4792
4794 -void helper_vmrun(int aflag) 4793 +void helper_vmrun(int aflag, int next_eip_addend)
4795 { 4794 {
4796 target_ulong addr; 4795 target_ulong addr;
4797 uint32_t event_inj; 4796 uint32_t event_inj;
@@ -4820,7 +4819,6 @@ void helper_vmrun(int aflag) @@ -4820,7 +4819,6 @@ void helper_vmrun(int aflag)
4820 stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr2), env->cr[2]); 4819 stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr2), env->cr[2]);
4821 stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr3), env->cr[3]); 4820 stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr3), env->cr[3]);
4822 stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr4), env->cr[4]); 4821 stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr4), env->cr[4]);
4823 - stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr8), env->cr[8]);  
4824 stq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr6), env->dr[6]); 4822 stq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr6), env->dr[6]);
4825 stq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr7), env->dr[7]); 4823 stq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr7), env->dr[7]);
4826 4824
@@ -4836,7 +4834,8 @@ void helper_vmrun(int aflag) @@ -4836,7 +4834,8 @@ void helper_vmrun(int aflag)
4836 svm_save_seg(env->vm_hsave + offsetof(struct vmcb, save.ds), 4834 svm_save_seg(env->vm_hsave + offsetof(struct vmcb, save.ds),
4837 &env->segs[R_DS]); 4835 &env->segs[R_DS]);
4838 4836
4839 - stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip), EIP); 4837 + stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip),
  4838 + EIP + next_eip_addend);
4840 stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp), ESP); 4839 stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp), ESP);
4841 stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax), EAX); 4840 stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax), EAX);
4842 4841
@@ -4866,17 +4865,16 @@ void helper_vmrun(int aflag) @@ -4866,17 +4865,16 @@ void helper_vmrun(int aflag)
4866 cpu_x86_update_cr3(env, ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr3))); 4865 cpu_x86_update_cr3(env, ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr3)));
4867 env->cr[2] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr2)); 4866 env->cr[2] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr2));
4868 int_ctl = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)); 4867 int_ctl = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
  4868 + env->hflags2 &= ~(HF2_HIF_MASK | HF2_VINTR_MASK);
4869 if (int_ctl & V_INTR_MASKING_MASK) { 4869 if (int_ctl & V_INTR_MASKING_MASK) {
4870 - env->cr[8] = int_ctl & V_TPR_MASK;  
4871 - cpu_set_apic_tpr(env, env->cr[8]); 4870 + env->v_tpr = int_ctl & V_TPR_MASK;
  4871 + env->hflags2 |= HF2_VINTR_MASK;
4872 if (env->eflags & IF_MASK) 4872 if (env->eflags & IF_MASK)
4873 - env->hflags |= HF_HIF_MASK; 4873 + env->hflags2 |= HF2_HIF_MASK;
4874 } 4874 }
4875 4875
4876 -#ifdef TARGET_X86_64  
4877 cpu_load_efer(env, 4876 cpu_load_efer(env,
4878 ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.efer))); 4877 ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.efer)));
4879 -#endif  
4880 env->eflags = 0; 4878 env->eflags = 0;
4881 load_eflags(ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rflags)), 4879 load_eflags(ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rflags)),
4882 ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); 4880 ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
@@ -4912,6 +4910,10 @@ void helper_vmrun(int aflag) @@ -4912,6 +4910,10 @@ void helper_vmrun(int aflag)
4912 4910
4913 helper_stgi(); 4911 helper_stgi();
4914 4912
  4913 + if (int_ctl & V_IRQ_MASK) {
  4914 + env->interrupt_request |= CPU_INTERRUPT_VIRQ;
  4915 + }
  4916 +
4915 /* maybe we need to inject an event */ 4917 /* maybe we need to inject an event */
4916 event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj)); 4918 event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj));
4917 if (event_inj & SVM_EVTINJ_VALID) { 4919 if (event_inj & SVM_EVTINJ_VALID) {
@@ -4931,14 +4933,17 @@ void helper_vmrun(int aflag) @@ -4931,14 +4933,17 @@ void helper_vmrun(int aflag)
4931 env->exception_next_eip = -1; 4933 env->exception_next_eip = -1;
4932 if (loglevel & CPU_LOG_TB_IN_ASM) 4934 if (loglevel & CPU_LOG_TB_IN_ASM)
4933 fprintf(logfile, "INTR"); 4935 fprintf(logfile, "INTR");
  4936 + /* XXX: is it always correct ? */
  4937 + do_interrupt(vector, 0, 0, 0, 1);
4934 break; 4938 break;
4935 case SVM_EVTINJ_TYPE_NMI: 4939 case SVM_EVTINJ_TYPE_NMI:
4936 - env->exception_index = vector; 4940 + env->exception_index = EXCP02_NMI;
4937 env->error_code = event_inj_err; 4941 env->error_code = event_inj_err;
4938 env->exception_is_int = 0; 4942 env->exception_is_int = 0;
4939 env->exception_next_eip = EIP; 4943 env->exception_next_eip = EIP;
4940 if (loglevel & CPU_LOG_TB_IN_ASM) 4944 if (loglevel & CPU_LOG_TB_IN_ASM)
4941 fprintf(logfile, "NMI"); 4945 fprintf(logfile, "NMI");
  4946 + cpu_loop_exit();
4942 break; 4947 break;
4943 case SVM_EVTINJ_TYPE_EXEPT: 4948 case SVM_EVTINJ_TYPE_EXEPT:
4944 env->exception_index = vector; 4949 env->exception_index = vector;
@@ -4947,6 +4952,7 @@ void helper_vmrun(int aflag) @@ -4947,6 +4952,7 @@ void helper_vmrun(int aflag)
4947 env->exception_next_eip = -1; 4952 env->exception_next_eip = -1;
4948 if (loglevel & CPU_LOG_TB_IN_ASM) 4953 if (loglevel & CPU_LOG_TB_IN_ASM)
4949 fprintf(logfile, "EXEPT"); 4954 fprintf(logfile, "EXEPT");
  4955 + cpu_loop_exit();
4950 break; 4956 break;
4951 case SVM_EVTINJ_TYPE_SOFT: 4957 case SVM_EVTINJ_TYPE_SOFT:
4952 env->exception_index = vector; 4958 env->exception_index = vector;
@@ -4955,17 +4961,12 @@ void helper_vmrun(int aflag) @@ -4955,17 +4961,12 @@ void helper_vmrun(int aflag)
4955 env->exception_next_eip = EIP; 4961 env->exception_next_eip = EIP;
4956 if (loglevel & CPU_LOG_TB_IN_ASM) 4962 if (loglevel & CPU_LOG_TB_IN_ASM)
4957 fprintf(logfile, "SOFT"); 4963 fprintf(logfile, "SOFT");
  4964 + cpu_loop_exit();
4958 break; 4965 break;
4959 } 4966 }
4960 if (loglevel & CPU_LOG_TB_IN_ASM) 4967 if (loglevel & CPU_LOG_TB_IN_ASM)
4961 fprintf(logfile, " %#x %#x\n", env->exception_index, env->error_code); 4968 fprintf(logfile, " %#x %#x\n", env->exception_index, env->error_code);
4962 } 4969 }
4963 - if ((int_ctl & V_IRQ_MASK) ||  
4964 - (env->intercept & (1ULL << (SVM_EXIT_INTR - SVM_EXIT_INTR)))) {  
4965 - env->interrupt_request |= CPU_INTERRUPT_VIRQ;  
4966 - }  
4967 -  
4968 - cpu_loop_exit();  
4969 } 4970 }
4970 4971
4971 void helper_vmmcall(void) 4972 void helper_vmmcall(void)
@@ -5049,13 +5050,13 @@ void helper_vmsave(int aflag) @@ -5049,13 +5050,13 @@ void helper_vmsave(int aflag)
5049 void helper_stgi(void) 5050 void helper_stgi(void)
5050 { 5051 {
5051 helper_svm_check_intercept_param(SVM_EXIT_STGI, 0); 5052 helper_svm_check_intercept_param(SVM_EXIT_STGI, 0);
5052 - env->hflags |= HF_GIF_MASK; 5053 + env->hflags2 |= HF2_GIF_MASK;
5053 } 5054 }
5054 5055
5055 void helper_clgi(void) 5056 void helper_clgi(void)
5056 { 5057 {
5057 helper_svm_check_intercept_param(SVM_EXIT_CLGI, 0); 5058 helper_svm_check_intercept_param(SVM_EXIT_CLGI, 0);
5058 - env->hflags &= ~HF_GIF_MASK; 5059 + env->hflags2 &= ~HF2_GIF_MASK;
5059 } 5060 }
5060 5061
5061 void helper_skinit(void) 5062 void helper_skinit(void)
@@ -5204,11 +5205,12 @@ void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1) @@ -5204,11 +5205,12 @@ void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
5204 stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr3), env->cr[3]); 5205 stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr3), env->cr[3]);
5205 stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr4), env->cr[4]); 5206 stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr4), env->cr[4]);
5206 5207
5207 - if ((int_ctl = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl))) & V_INTR_MASKING_MASK) {  
5208 - int_ctl &= ~V_TPR_MASK;  
5209 - int_ctl |= env->cr[8] & V_TPR_MASK;  
5210 - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), int_ctl);  
5211 - } 5208 + int_ctl = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
  5209 + int_ctl &= ~(V_TPR_MASK | V_IRQ_MASK);
  5210 + int_ctl |= env->v_tpr & V_TPR_MASK;
  5211 + if (env->interrupt_request & CPU_INTERRUPT_VIRQ)
  5212 + int_ctl |= V_IRQ_MASK;
  5213 + stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), int_ctl);
5212 5214
5213 stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rflags), compute_eflags()); 5215 stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rflags), compute_eflags());
5214 stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip), env->eip); 5216 stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip), env->eip);
@@ -5219,7 +5221,7 @@ void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1) @@ -5219,7 +5221,7 @@ void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
5219 stb_phys(env->vm_vmcb + offsetof(struct vmcb, save.cpl), env->hflags & HF_CPL_MASK); 5221 stb_phys(env->vm_vmcb + offsetof(struct vmcb, save.cpl), env->hflags & HF_CPL_MASK);
5220 5222
5221 /* Reload the host state from vm_hsave */ 5223 /* Reload the host state from vm_hsave */
5222 - env->hflags &= ~HF_HIF_MASK; 5224 + env->hflags2 &= ~(HF2_HIF_MASK | HF2_VINTR_MASK);
5223 env->hflags &= ~HF_SVMI_MASK; 5225 env->hflags &= ~HF_SVMI_MASK;
5224 env->intercept = 0; 5226 env->intercept = 0;
5225 env->intercept_exceptions = 0; 5227 env->intercept_exceptions = 0;
@@ -5234,17 +5236,10 @@ void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1) @@ -5234,17 +5236,10 @@ void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
5234 cpu_x86_update_cr0(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr0)) | CR0_PE_MASK); 5236 cpu_x86_update_cr0(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr0)) | CR0_PE_MASK);
5235 cpu_x86_update_cr4(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr4))); 5237 cpu_x86_update_cr4(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr4)));
5236 cpu_x86_update_cr3(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr3))); 5238 cpu_x86_update_cr3(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr3)));
5237 - if (int_ctl & V_INTR_MASKING_MASK) {  
5238 - env->cr[8] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr8));  
5239 - cpu_set_apic_tpr(env, env->cr[8]);  
5240 - }  
5241 /* we need to set the efer after the crs so the hidden flags get 5239 /* we need to set the efer after the crs so the hidden flags get
5242 set properly */ 5240 set properly */
5243 -#ifdef TARGET_X86_64  
5244 cpu_load_efer(env, 5241 cpu_load_efer(env,
5245 ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.efer))); 5242 ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.efer)));
5246 -#endif  
5247 -  
5248 env->eflags = 0; 5243 env->eflags = 0;
5249 load_eflags(ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rflags)), 5244 load_eflags(ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rflags)),
5250 ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); 5245 ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
target-i386/svm.h
@@ -205,9 +205,7 @@ struct __attribute__ ((__packed__)) vmcb_save_area { @@ -205,9 +205,7 @@ struct __attribute__ ((__packed__)) vmcb_save_area {
205 uint64_t sysenter_esp; 205 uint64_t sysenter_esp;
206 uint64_t sysenter_eip; 206 uint64_t sysenter_eip;
207 uint64_t cr2; 207 uint64_t cr2;
208 - /* qemu: cr8 added to reuse this as hsave */  
209 - uint64_t cr8;  
210 - uint8_t reserved_6[32 - 8]; /* originally 32 */ 208 + uint8_t reserved_6[32];
211 uint64_t g_pat; 209 uint64_t g_pat;
212 uint64_t dbgctl; 210 uint64_t dbgctl;
213 uint64_t br_from; 211 uint64_t br_from;
target-i386/translate.c
@@ -6569,10 +6569,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -6569,10 +6569,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
6569 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 6569 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6570 break; 6570 break;
6571 } else { 6571 } else {
6572 - tcg_gen_helper_0_1(helper_vmrun,  
6573 - tcg_const_i32(s->aflag));  
6574 - s->cc_op = CC_OP_EFLAGS;  
6575 - gen_eob(s); 6572 + tcg_gen_helper_0_2(helper_vmrun,
  6573 + tcg_const_i32(s->aflag),
  6574 + tcg_const_i32(s->pc - pc_start));
  6575 + tcg_gen_exit_tb(0);
  6576 + s->is_jmp = 3;
6576 } 6577 }
6577 break; 6578 break;
6578 case 1: /* VMMCALL */ 6579 case 1: /* VMMCALL */