diff options
author | ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-09-23 15:28:04 +0000 |
---|---|---|
committer | ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-09-23 15:28:04 +0000 |
commit | 0573fbfc3f1c616071c59caef22975d1280b1c5d (patch) | |
tree | 169a727a4c733c7b72e624eaee84a0f1aaa971ba /cpu-exec.c | |
parent | bbbb2f0af96dbf6706c90209ebb16dc5b87d32e1 (diff) |
SVM Support, by Alexander Graf.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3210 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'cpu-exec.c')
-rw-r--r-- | cpu-exec.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/cpu-exec.c b/cpu-exec.c index 3395059662..58737b3a40 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -163,6 +163,7 @@ static inline TranslationBlock *tb_find_fast(void) #if defined(TARGET_I386) flags = env->hflags; flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK)); + flags |= env->intercept; cs_base = env->segs[R_CS].base; pc = cs_base + env->eip; #elif defined(TARGET_ARM) @@ -372,7 +373,11 @@ int cpu_exec(CPUState *env1) tmp_T0 = T0; #endif interrupt_request = env->interrupt_request; - if (__builtin_expect(interrupt_request, 0)) { + if (__builtin_expect(interrupt_request, 0) +#if defined(TARGET_I386) + && env->hflags & HF_GIF_MASK +#endif + ) { if (interrupt_request & CPU_INTERRUPT_DEBUG) { env->interrupt_request &= ~CPU_INTERRUPT_DEBUG; env->exception_index = EXCP_DEBUG; @@ -390,6 +395,7 @@ int cpu_exec(CPUState *env1) #if defined(TARGET_I386) if ((interrupt_request & CPU_INTERRUPT_SMI) && !(env->hflags & HF_SMM_MASK)) { + svm_check_intercept(SVM_EXIT_SMI); env->interrupt_request &= ~CPU_INTERRUPT_SMI; do_smm_enter(); #if defined(__sparc__) && !defined(HOST_SOLARIS) @@ -398,9 +404,10 @@ int cpu_exec(CPUState *env1) T0 = 0; #endif } else if ((interrupt_request & CPU_INTERRUPT_HARD) && - (env->eflags & IF_MASK) && + (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) { int intno; + svm_check_intercept(SVM_EXIT_INTR); env->interrupt_request &= ~CPU_INTERRUPT_HARD; intno = cpu_get_pic_interrupt(env); if (loglevel & CPU_LOG_TB_IN_ASM) { @@ -414,6 +421,24 @@ int cpu_exec(CPUState *env1) #else T0 = 0; #endif +#if !defined(CONFIG_USER_ONLY) + } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) && + (env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) { + 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); + 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); +#if defined(__sparc__) && !defined(HOST_SOLARIS) + tmp_T0 = 0; +#else + T0 = 0; +#endif +#endif } #elif defined(TARGET_PPC) #if 0 |