diff options
Diffstat (limited to 'target-i386')
-rw-r--r-- | target-i386/cpu.h | 4 | ||||
-rw-r--r-- | target-i386/kvm.c | 4 | ||||
-rw-r--r-- | target-i386/translate.c | 14 |
3 files changed, 17 insertions, 5 deletions
diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 0ea47b5ed..a1acf48ce 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -477,6 +477,7 @@ for syscall instruction */ /* i386-specific interrupt pending bits. */ +#define CPU_INTERRUPT_POLL CPU_INTERRUPT_TGT_EXT_1 #define CPU_INTERRUPT_SMI CPU_INTERRUPT_TGT_EXT_2 #define CPU_INTERRUPT_NMI CPU_INTERRUPT_TGT_EXT_3 #define CPU_INTERRUPT_MCE CPU_INTERRUPT_TGT_EXT_4 @@ -1030,7 +1031,8 @@ static inline void cpu_clone_regs(CPUX86State *env, target_ulong newsp) static inline bool cpu_has_work(CPUX86State *env) { - return ((env->interrupt_request & CPU_INTERRUPT_HARD) && + return ((env->interrupt_request & (CPU_INTERRUPT_HARD | + CPU_INTERRUPT_POLL)) && (env->eflags & IF_MASK)) || (env->interrupt_request & (CPU_INTERRUPT_NMI | CPU_INTERRUPT_INIT | diff --git a/target-i386/kvm.c b/target-i386/kvm.c index e74a9e464..d8bbe4ff6 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -1725,6 +1725,10 @@ int kvm_arch_process_async_events(CPUX86State *env) return 0; } + if (env->interrupt_request & CPU_INTERRUPT_POLL) { + env->interrupt_request &= ~CPU_INTERRUPT_POLL; + apic_poll_irq(env->apic_state); + } if (((env->interrupt_request & CPU_INTERRUPT_HARD) && (env->eflags & IF_MASK)) || (env->interrupt_request & CPU_INTERRUPT_NMI)) { diff --git a/target-i386/translate.c b/target-i386/translate.c index c1ede1a75..c792e7ace 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -7409,8 +7409,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { modrm = ldub_code(s->pc++); - if ((modrm & 0xc0) != 0xc0) - goto illegal_op; + /* Ignore the mod bits (assume (modrm&0xc0)==0xc0). + * AMD documentation (24594.pdf) and testing of + * intel 386 and 486 processors all show that the mod bits + * are assumed to be 1's, regardless of actual values. + */ rm = (modrm & 7) | REX_B(s); reg = ((modrm >> 3) & 7) | rex_r; if (CODE64(s)) @@ -7451,8 +7454,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { modrm = ldub_code(s->pc++); - if ((modrm & 0xc0) != 0xc0) - goto illegal_op; + /* Ignore the mod bits (assume (modrm&0xc0)==0xc0). + * AMD documentation (24594.pdf) and testing of + * intel 386 and 486 processors all show that the mod bits + * are assumed to be 1's, regardless of actual values. + */ rm = (modrm & 7) | REX_B(s); reg = ((modrm >> 3) & 7) | rex_r; if (CODE64(s)) |