From 7760bb069f11fb4259c76c05c69a0d254b5d8a10 Mon Sep 17 00:00:00 2001 From: Lara Lazier Date: Fri, 13 Aug 2021 11:45:52 +0200 Subject: [PATCH] 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 Signed-off-by: Paolo Bonzini --- target/i386/cpu.h | 15 +++++++++++++++ target/i386/tcg/sysemu/misc_helper.c | 7 +++++++ 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 24e8ec5273..6b09b8b62f 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 91b0fc916b..9ccaa054c4 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 a35b79548a..7bbd3a18c9 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)) {