qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] SVM VINTR fix


From: Alexander Graf
Subject: [Qemu-devel] [PATCH] SVM VINTR fix
Date: Tue, 25 Sep 2007 17:04:22 +0200
User-agent: Thunderbird 2.0.0.4 (X11/20070613)

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
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);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]