SVM VINTR fix
PATCH 1/1 SVM VINTR fix
Hi,
in the recently introduced svm patch I misread the documentation and so a bug came to get included in there. This patch should fix the virtual interrupt handling completely and thus makes gfxboot work in the virtualized machine.
Please apply this.
Thanks,
Alex
cpu-exec.c +4 -3
@@ -408,7 +408,7 @@ int cpu_exec(CPUState *env1) !(env->hflags & HF_INHIBIT_IRQ_MASK)) {int intno;svm_check_intercept (SVM_EXIT_INTR ); - env->interrupt_request &= ~CPU_INTERRUPT_HARD ; + env->interrupt_request &= ~(CPU_INTERRUPT_HARD |CPU_INTERRUPT_VIRQ ); intno =cpu_get_pic_interrupt (env);if (loglevel &CPU_LOG_TB_IN_ASM ) {fprintf (logfile,"Servicing hardware INT=0x%02x\n" , intno);
@@ -427,12 +427,13 @@ int cpu_exec(CPUState *env1)int intno;/* FIXME: this should respect TPR */ env->interrupt_request &= ~CPU_INTERRUPT_VIRQ ; - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), - ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK); +svm_check_intercept (SVM_EXIT_VINTR ); intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));if (loglevel &CPU_LOG_TB_IN_ASM )fprintf (logfile,"Servicing virtual hardware INT=0x%02x\n" , intno);do_interrupt (intno,0 ,0 ,-1 ,1 ); + stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), + ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK);#if defined(__sparc__) && !defined(HOST_SOLARIS ) tmp_T0 =0 ;#else
target-i386/helper.c +9 -1
@@ -4120,8 +4122,9 @@ void helper_vmrun(target_ulong addr)if (loglevel &CPU_LOG_TB_IN_ASM )fprintf (logfile," %#x %#x\n" , env->exception_index, env->error_code); } -if (int_ctl &V_IRQ_MASK ) +if ((int_ctl &V_IRQ_MASK ) || (env->intercept &INTERCEPT_VINTR )) { env->interrupt_request |=CPU_INTERRUPT_VIRQ ; + }cpu_loop_exit (); }
@@ -4283,6 +4291,13 @@ void vmexit(uint64_t exit_code, uint64_t ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2)), EIP); +if (env->hflags &HF_INHIBIT_IRQ_MASK ) { + stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_state), SVM_INTERRUPT_SHADOW_MASK); + env->hflags &= ~HF_INHIBIT_IRQ_MASK ; + }else { + stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_state), 0); + } +/* Save the VM state in the vmcb */ SVM_SAVE_SEG (env->vm_vmcb, segs[R_ES ], es);SVM_SAVE_SEG (env->vm_vmcb, segs[R_CS ], cs);
target-i386/translate.c +0 -2
@@ -5551,8 +5551,6 @@ static target_ulong disas_insn(DisasContgen_op_set_inhibit_irq ();/* give a chance to handle pending irqs */ gen_jmp_im (s->pc - s->cs_base); -if (gen_svm_check_intercept (s, pc_start,SVM_EXIT_VINTR )) -break ;gen_eob (s); }else {gen_exception (s,EXCP0D_GPF , pc_start - s->cs_base);