diff options
author | Lara Lazier <laramglazier@gmail.com> | 2021-08-13 11:45:52 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2021-09-13 13:56:26 +0200 |
commit | 7760bb069f11fb4259c76c05c69a0d254b5d8a10 (patch) | |
tree | c5232bcd6897af055c29b4815b00d00f210e61a1 /target | |
parent | 66a0201ba7a3143689014eb711a5942babca2585 (diff) | |
download | qemu-7760bb069f11fb4259c76c05c69a0d254b5d8a10.zip qemu-7760bb069f11fb4259c76c05c69a0d254b5d8a10.tar.gz qemu-7760bb069f11fb4259c76c05c69a0d254b5d8a10.tar.bz2 |
target/i386: Added changed priority check for VIRQ
Writes to cr8 affect v_tpr. This could set or unset an interrupt
request as the priority might have changed.
Signed-off-by: Lara Lazier <laramglazier@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'target')
-rw-r--r-- | target/i386/cpu.h | 15 | ||||
-rw-r--r-- | target/i386/tcg/sysemu/misc_helper.c | 7 | ||||
-rw-r--r-- | target/i386/tcg/sysemu/svm_helper.c | 15 |
3 files changed, 22 insertions, 15 deletions
diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 24e8ec5..6b09b8b 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -2246,6 +2246,21 @@ static inline uint64_t cr4_reserved_bits(CPUX86State *env) return reserved_bits; } +static inline bool ctl_has_irq(CPUX86State *env) +{ + uint32_t int_prio; + uint32_t tpr; + + int_prio = (env->int_ctl & V_INTR_PRIO_MASK) >> V_INTR_PRIO_SHIFT; + tpr = env->int_ctl & V_TPR_MASK; + + if (env->int_ctl & V_IGN_TPR_MASK) { + return (env->int_ctl & V_IRQ_MASK); + } + + return (env->int_ctl & V_IRQ_MASK) && (int_prio >= tpr); +} + #if defined(TARGET_X86_64) && \ defined(CONFIG_USER_ONLY) && \ defined(CONFIG_LINUX) diff --git a/target/i386/tcg/sysemu/misc_helper.c b/target/i386/tcg/sysemu/misc_helper.c index 91b0fc9..9ccaa05 100644 --- a/target/i386/tcg/sysemu/misc_helper.c +++ b/target/i386/tcg/sysemu/misc_helper.c @@ -122,6 +122,13 @@ void helper_write_crN(CPUX86State *env, int reg, target_ulong t0) qemu_mutex_unlock_iothread(); } env->int_ctl = (env->int_ctl & ~V_TPR_MASK) | (t0 & V_TPR_MASK); + + CPUState *cs = env_cpu(env); + if (ctl_has_irq(env)) { + cpu_interrupt(cs, CPU_INTERRUPT_VIRQ); + } else { + cpu_reset_interrupt(cs, CPU_INTERRUPT_VIRQ); + } break; default: env->cr[reg] = t0; diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c index a35b795..7bbd3a1 100644 --- a/target/i386/tcg/sysemu/svm_helper.c +++ b/target/i386/tcg/sysemu/svm_helper.c @@ -76,21 +76,6 @@ static inline void svm_load_seg_cache(CPUX86State *env, hwaddr addr, sc->base, sc->limit, sc->flags); } -static inline bool ctl_has_irq(CPUX86State *env) -{ - uint32_t int_prio; - uint32_t tpr; - - int_prio = (env->int_ctl & V_INTR_PRIO_MASK) >> V_INTR_PRIO_SHIFT; - tpr = env->int_ctl & V_TPR_MASK; - - if (env->int_ctl & V_IGN_TPR_MASK) { - return env->int_ctl & V_IRQ_MASK; - } - - return (env->int_ctl & V_IRQ_MASK) && (int_prio >= tpr); -} - static inline bool is_efer_invalid_state (CPUX86State *env) { if (!(env->efer & MSR_EFER_SVME)) { |