Commit 526216880d5c4cb2507bdb22d6a5d33016f38104

Authored by ths
1 parent 40d0591e

SVM VINTR fix, by Alexander Graf.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3248 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-exec.c
@@ -409,7 +409,7 @@ int cpu_exec(CPUState *env1) @@ -409,7 +409,7 @@ int cpu_exec(CPUState *env1)
409 !(env->hflags & HF_INHIBIT_IRQ_MASK)) { 409 !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
410 int intno; 410 int intno;
411 svm_check_intercept(SVM_EXIT_INTR); 411 svm_check_intercept(SVM_EXIT_INTR);
412 - env->interrupt_request &= ~CPU_INTERRUPT_HARD; 412 + env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
413 intno = cpu_get_pic_interrupt(env); 413 intno = cpu_get_pic_interrupt(env);
414 if (loglevel & CPU_LOG_TB_IN_ASM) { 414 if (loglevel & CPU_LOG_TB_IN_ASM) {
415 fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno); 415 fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
@@ -428,12 +428,13 @@ int cpu_exec(CPUState *env1) @@ -428,12 +428,13 @@ int cpu_exec(CPUState *env1)
428 int intno; 428 int intno;
429 /* FIXME: this should respect TPR */ 429 /* FIXME: this should respect TPR */
430 env->interrupt_request &= ~CPU_INTERRUPT_VIRQ; 430 env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
431 - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),  
432 - ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK); 431 + svm_check_intercept(SVM_EXIT_VINTR);
433 intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector)); 432 intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
434 if (loglevel & CPU_LOG_TB_IN_ASM) 433 if (loglevel & CPU_LOG_TB_IN_ASM)
435 fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno); 434 fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno);
436 do_interrupt(intno, 0, 0, -1, 1); 435 do_interrupt(intno, 0, 0, -1, 1);
  436 + stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
  437 + ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK);
437 #if defined(__sparc__) && !defined(HOST_SOLARIS) 438 #if defined(__sparc__) && !defined(HOST_SOLARIS)
438 tmp_T0 = 0; 439 tmp_T0 = 0;
439 #else 440 #else
target-i386/helper.c
@@ -4120,8 +4120,9 @@ void helper_vmrun(target_ulong addr) @@ -4120,8 +4120,9 @@ void helper_vmrun(target_ulong addr)
4120 if (loglevel & CPU_LOG_TB_IN_ASM) 4120 if (loglevel & CPU_LOG_TB_IN_ASM)
4121 fprintf(logfile, " %#x %#x\n", env->exception_index, env->error_code); 4121 fprintf(logfile, " %#x %#x\n", env->exception_index, env->error_code);
4122 } 4122 }
4123 - if (int_ctl & V_IRQ_MASK) 4123 + if ((int_ctl & V_IRQ_MASK) || (env->intercept & INTERCEPT_VINTR)) {
4124 env->interrupt_request |= CPU_INTERRUPT_VIRQ; 4124 env->interrupt_request |= CPU_INTERRUPT_VIRQ;
  4125 + }
4125 4126
4126 cpu_loop_exit(); 4127 cpu_loop_exit();
4127 } 4128 }
@@ -4283,6 +4284,13 @@ void vmexit(uint64_t exit_code, uint64_t exit_info_1) @@ -4283,6 +4284,13 @@ void vmexit(uint64_t exit_code, uint64_t exit_info_1)
4283 ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2)), 4284 ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2)),
4284 EIP); 4285 EIP);
4285 4286
  4287 + if(env->hflags & HF_INHIBIT_IRQ_MASK) {
  4288 + stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_state), SVM_INTERRUPT_SHADOW_MASK);
  4289 + env->hflags &= ~HF_INHIBIT_IRQ_MASK;
  4290 + } else {
  4291 + stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_state), 0);
  4292 + }
  4293 +
4286 /* Save the VM state in the vmcb */ 4294 /* Save the VM state in the vmcb */
4287 SVM_SAVE_SEG(env->vm_vmcb, segs[R_ES], es); 4295 SVM_SAVE_SEG(env->vm_vmcb, segs[R_ES], es);
4288 SVM_SAVE_SEG(env->vm_vmcb, segs[R_CS], cs); 4296 SVM_SAVE_SEG(env->vm_vmcb, segs[R_CS], cs);
target-i386/translate.c
@@ -5551,8 +5551,6 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -5551,8 +5551,6 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5551 gen_op_set_inhibit_irq(); 5551 gen_op_set_inhibit_irq();
5552 /* give a chance to handle pending irqs */ 5552 /* give a chance to handle pending irqs */
5553 gen_jmp_im(s->pc - s->cs_base); 5553 gen_jmp_im(s->pc - s->cs_base);
5554 - if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VINTR))  
5555 - break;  
5556 gen_eob(s); 5554 gen_eob(s);
5557 } else { 5555 } else {
5558 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 5556 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);