72 lines
3.5 KiB
Diff
72 lines
3.5 KiB
Diff
Index: qemu/cpu-exec.c
|
|
===================================================================
|
|
--- qemu.orig/cpu-exec.c
|
|
+++ qemu/cpu-exec.c
|
|
@@ -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
|
|
Index: qemu/target-i386/helper.c
|
|
===================================================================
|
|
--- qemu.orig/target-i386/helper.c
|
|
+++ qemu/target-i386/helper.c
|
|
@@ -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);
|
|
Index: qemu/target-i386/translate.c
|
|
===================================================================
|
|
--- qemu.orig/target-i386/translate.c
|
|
+++ qemu/target-i386/translate.c
|
|
@@ -5551,8 +5551,6 @@ static target_ulong disas_insn(DisasCont
|
|
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);
|