diff options
author | ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-09-27 01:52:00 +0000 |
---|---|---|
committer | ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-09-27 01:52:00 +0000 |
commit | 526216880d5c4cb2507bdb22d6a5d33016f38104 (patch) | |
tree | cecf0b1407ea31e6a0814714d1e0faf432113b16 | |
parent | 40d0591e2c4922f545ebf1c9a3bd89e73e8428b4 (diff) | |
download | qemu-526216880d5c4cb2507bdb22d6a5d33016f38104.tar.gz qemu-526216880d5c4cb2507bdb22d6a5d33016f38104.tar.bz2 qemu-526216880d5c4cb2507bdb22d6a5d33016f38104.zip |
SVM VINTR fix, by Alexander Graf.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3248 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r-- | cpu-exec.c | 7 | ||||
-rw-r--r-- | target-i386/helper.c | 10 | ||||
-rw-r--r-- | target-i386/translate.c | 2 |
3 files changed, 13 insertions, 6 deletions
diff --git a/cpu-exec.c b/cpu-exec.c index 8d91520408..55758faef2 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -409,7 +409,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); @@ -428,12 +428,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 diff --git a/target-i386/helper.c b/target-i386/helper.c index 40dc41f3a7..91fd6a96c7 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -4120,8 +4120,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 +4284,13 @@ void vmexit(uint64_t exit_code, uint64_t exit_info_1) 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); diff --git a/target-i386/translate.c b/target-i386/translate.c index d62d563bd9..cd9541265a 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -5551,8 +5551,6 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_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); |