* [PATCH 0/4] target/i386: V_IRQ masking and V_TPR fixes
@ 2021-08-20 14:15 Lara Lazier
2021-08-20 14:15 ` [PATCH 1/4] target/i386: Moved int_ctl into CPUX86State structure Lara Lazier
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Lara Lazier @ 2021-08-20 14:15 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, Lara Lazier
Patch 2 adds VGIF capability to mask virtual interrupts.
Patches 3 and 4 fix bugs related to vTPR, while patch 1 refactors
int_ctl into the state structure to simplify the fixes in the
following patches.
Lara Lazier (4):
target/i386: Moved int_ctl into CPUX86State structure
target/i386: Added VGIF V_IRQ masking capability
target/i386: Added ignore TPR check in ctl_has_irq
target/i386: Added changed priority check for VIRQ
slirp | 2 +-
target/i386/cpu.c | 9 ++--
target/i386/cpu.h | 18 ++++++++
target/i386/machine.c | 22 +++++++++-
target/i386/tcg/seg_helper.c | 2 +-
target/i386/tcg/sysemu/misc_helper.c | 11 ++++-
target/i386/tcg/sysemu/svm_helper.c | 62 +++++++++++-----------------
7 files changed, 79 insertions(+), 47 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/4] target/i386: Moved int_ctl into CPUX86State structure
2021-08-20 14:15 [PATCH 0/4] target/i386: V_IRQ masking and V_TPR fixes Lara Lazier
@ 2021-08-20 14:15 ` Lara Lazier
2021-08-20 14:15 ` [PATCH 2/4] target/i386: Added VGIF V_IRQ masking capability Lara Lazier
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Lara Lazier @ 2021-08-20 14:15 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, Lara Lazier
Moved int_ctl into the CPUX86State structure to remove some
unnecessary stores and loads.
Signed-off-by: Lara Lazier <laramglazier@gmail.com>
---
slirp | 2 +-
target/i386/cpu.c | 2 +-
target/i386/cpu.h | 1 +
target/i386/machine.c | 22 ++++++++++++-
target/i386/tcg/seg_helper.c | 2 +-
target/i386/tcg/sysemu/misc_helper.c | 4 +--
target/i386/tcg/sysemu/svm_helper.c | 48 +++++++++-------------------
7 files changed, 42 insertions(+), 39 deletions(-)
diff --git a/slirp b/slirp
index a88d9ace23..8f43a99191 160000
--- a/slirp
+++ b/slirp
@@ -1 +1 @@
-Subproject commit a88d9ace234a24ce1c17189642ef9104799425e0
+Subproject commit 8f43a99191afb47ca3f3c6972f6306209f367ece
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index ada7b49d8e..5dcdab3b80 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -5647,7 +5647,7 @@ static void x86_cpu_reset(DeviceState *dev)
env->old_exception = -1;
/* init to reset state */
-
+ env->int_ctl = 0;
env->hflags2 |= HF2_GIF_MASK;
env->hflags &= ~HF_GUEST_MASK;
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index c9c7350c76..e27a1aab99 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1577,6 +1577,7 @@ typedef struct CPUX86State {
uint64_t nested_cr3;
uint32_t nested_pg_mode;
uint8_t v_tpr;
+ uint32_t int_ctl;
/* KVM states, automatically cleared on reset */
uint8_t nmi_injected;
diff --git a/target/i386/machine.c b/target/i386/machine.c
index f6f094f1c9..013ca6837f 100644
--- a/target/i386/machine.c
+++ b/target/i386/machine.c
@@ -203,7 +203,7 @@ static int cpu_pre_save(void *opaque)
X86CPU *cpu = opaque;
CPUX86State *env = &cpu->env;
int i;
-
+ env->v_tpr = env->int_ctl & V_TPR_MASK;
/* FPU */
env->fpus_vmstate = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
env->fptag_vmstate = 0;
@@ -1356,6 +1356,25 @@ static const VMStateDescription vmstate_svm_npt = {
}
};
+static bool svm_guest_needed(void *opaque)
+{
+ X86CPU *cpu = opaque;
+ CPUX86State *env = &cpu->env;
+
+ return !env->int_ctl;
+}
+
+static const VMStateDescription vmstate_svm_guest = {
+ .name = "cpu/svn_guest",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = svm_guest_needed,
+ .fields = (VMStateField[]){
+ VMSTATE_UINT32(env.int_ctl, X86CPU),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
#ifndef TARGET_X86_64
static bool intel_efer32_needed(void *opaque)
{
@@ -1524,6 +1543,7 @@ const VMStateDescription vmstate_x86_cpu = {
&vmstate_msr_intel_pt,
&vmstate_msr_virt_ssbd,
&vmstate_svm_npt,
+ &vmstate_svm_guest,
#ifndef TARGET_X86_64
&vmstate_efer32,
#endif
diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c
index 3ed20ca31d..cef68b610a 100644
--- a/target/i386/tcg/seg_helper.c
+++ b/target/i386/tcg/seg_helper.c
@@ -1166,7 +1166,6 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
break;
#if !defined(CONFIG_USER_ONLY)
case CPU_INTERRUPT_VIRQ:
- /* FIXME: this should respect TPR */
cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR, 0, 0);
intno = x86_ldl_phys(cs, env->vm_vmcb
+ offsetof(struct vmcb, control.int_vector));
@@ -1174,6 +1173,7 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
"Servicing virtual hardware INT=0x%02x\n", intno);
do_interrupt_x86_hardirq(env, intno, 1);
cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
+ env->int_ctl &= ~V_IRQ_MASK;
break;
#endif
}
diff --git a/target/i386/tcg/sysemu/misc_helper.c b/target/i386/tcg/sysemu/misc_helper.c
index e7a2ebde81..91b0fc916b 100644
--- a/target/i386/tcg/sysemu/misc_helper.c
+++ b/target/i386/tcg/sysemu/misc_helper.c
@@ -73,7 +73,7 @@ target_ulong helper_read_crN(CPUX86State *env, int reg)
if (!(env->hflags2 & HF2_VINTR_MASK)) {
val = cpu_get_apic_tpr(env_archcpu(env)->apic_state);
} else {
- val = env->v_tpr;
+ val = env->int_ctl & V_TPR_MASK;
}
break;
}
@@ -121,7 +121,7 @@ void helper_write_crN(CPUX86State *env, int reg, target_ulong t0)
cpu_set_apic_tpr(env_archcpu(env)->apic_state, t0);
qemu_mutex_unlock_iothread();
}
- env->v_tpr = t0 & 0x0f;
+ env->int_ctl = (env->int_ctl & ~V_TPR_MASK) | (t0 & V_TPR_MASK);
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 989af1b7f2..9ef2454779 100644
--- a/target/i386/tcg/sysemu/svm_helper.c
+++ b/target/i386/tcg/sysemu/svm_helper.c
@@ -76,14 +76,14 @@ static inline void svm_load_seg_cache(CPUX86State *env, hwaddr addr,
sc->base, sc->limit, sc->flags);
}
-static inline bool ctl_has_irq(uint32_t int_ctl)
+static inline bool ctl_has_irq(CPUX86State *env)
{
uint32_t int_prio;
uint32_t tpr;
- int_prio = (int_ctl & V_INTR_PRIO_MASK) >> V_INTR_PRIO_SHIFT;
- tpr = int_ctl & V_TPR_MASK;
- return (int_ctl & V_IRQ_MASK) && (int_prio >= tpr);
+ int_prio = (env->int_ctl & V_INTR_PRIO_MASK) >> V_INTR_PRIO_SHIFT;
+ tpr = env->int_ctl & V_TPR_MASK;
+ return (env->int_ctl & V_IRQ_MASK) && (int_prio >= tpr);
}
static inline bool is_efer_invalid_state (CPUX86State *env)
@@ -121,13 +121,11 @@ static inline bool is_efer_invalid_state (CPUX86State *env)
return false;
}
-static inline bool virtual_gif_enabled(CPUX86State *env, uint32_t *int_ctl)
+static inline bool virtual_gif_enabled(CPUX86State *env)
{
if (likely(env->hflags & HF_GUEST_MASK)) {
- *int_ctl = x86_ldl_phys(env_cpu(env),
- env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
return (env->features[FEAT_SVM] & CPUID_SVM_VGIF)
- && (*int_ctl & V_GIF_ENABLED_MASK);
+ && (env->int_ctl & V_GIF_ENABLED_MASK);
}
return false;
}
@@ -139,7 +137,6 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
target_ulong addr;
uint64_t nested_ctl;
uint32_t event_inj;
- uint32_t int_ctl;
uint32_t asid;
uint64_t new_cr0;
uint64_t new_cr3;
@@ -292,11 +289,10 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
cpu_x86_update_cr3(env, new_cr3);
env->cr[2] = x86_ldq_phys(cs,
env->vm_vmcb + offsetof(struct vmcb, save.cr2));
- int_ctl = x86_ldl_phys(cs,
+ env->int_ctl = x86_ldl_phys(cs,
env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
env->hflags2 &= ~(HF2_HIF_MASK | HF2_VINTR_MASK);
- if (int_ctl & V_INTR_MASKING_MASK) {
- env->v_tpr = int_ctl & V_TPR_MASK;
+ if (env->int_ctl & V_INTR_MASKING_MASK) {
env->hflags2 |= HF2_VINTR_MASK;
if (env->eflags & IF_MASK) {
env->hflags2 |= HF2_HIF_MASK;
@@ -362,7 +358,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
env->hflags2 |= HF2_GIF_MASK;
- if (ctl_has_irq(int_ctl)) {
+ if (ctl_has_irq(env)) {
CPUState *cs = env_cpu(env);
cs->interrupt_request |= CPU_INTERRUPT_VIRQ;
}
@@ -521,11 +517,8 @@ void helper_stgi(CPUX86State *env)
{
cpu_svm_check_intercept_param(env, SVM_EXIT_STGI, 0, GETPC());
- CPUState *cs = env_cpu(env);
- uint32_t int_ctl;
- if (virtual_gif_enabled(env, &int_ctl)) {
- x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
- int_ctl | V_GIF_MASK);
+ if (virtual_gif_enabled(env)) {
+ env->int_ctl |= V_GIF_MASK;
} else {
env->hflags2 |= HF2_GIF_MASK;
}
@@ -535,11 +528,8 @@ void helper_clgi(CPUX86State *env)
{
cpu_svm_check_intercept_param(env, SVM_EXIT_CLGI, 0, GETPC());
- CPUState *cs = env_cpu(env);
- uint32_t int_ctl;
- if (virtual_gif_enabled(env, &int_ctl)) {
- x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
- int_ctl & ~V_GIF_MASK);
+ if (virtual_gif_enabled(env)) {
+ env->int_ctl &= ~V_GIF_MASK;
} else {
env->hflags2 &= ~HF2_GIF_MASK;
}
@@ -687,7 +677,6 @@ void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1,
void do_vmexit(CPUX86State *env)
{
CPUState *cs = env_cpu(env);
- uint32_t int_ctl;
if (env->hflags & HF_INHIBIT_IRQ_MASK) {
x86_stl_phys(cs,
@@ -730,16 +719,8 @@ void do_vmexit(CPUX86State *env)
env->vm_vmcb + offsetof(struct vmcb, save.cr3), env->cr[3]);
x86_stq_phys(cs,
env->vm_vmcb + offsetof(struct vmcb, save.cr4), env->cr[4]);
-
- int_ctl = x86_ldl_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
- int_ctl &= ~(V_TPR_MASK | V_IRQ_MASK);
- int_ctl |= env->v_tpr & V_TPR_MASK;
- if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
- int_ctl |= V_IRQ_MASK;
- }
x86_stl_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), int_ctl);
+ env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), env->int_ctl);
x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.rflags),
cpu_compute_eflags(env));
@@ -762,6 +743,7 @@ void do_vmexit(CPUX86State *env)
env->intercept = 0;
env->intercept_exceptions = 0;
cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
+ env->int_ctl = 0;
env->tsc_offset = 0;
env->gdt.base = x86_ldq_phys(cs, env->vm_hsave + offsetof(struct vmcb,
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/4] target/i386: Added VGIF V_IRQ masking capability
2021-08-20 14:15 [PATCH 0/4] target/i386: V_IRQ masking and V_TPR fixes Lara Lazier
2021-08-20 14:15 ` [PATCH 1/4] target/i386: Moved int_ctl into CPUX86State structure Lara Lazier
@ 2021-08-20 14:15 ` Lara Lazier
2021-08-20 14:15 ` [PATCH 3/4] target/i386: Added ignore TPR check in ctl_has_irq Lara Lazier
2021-08-20 14:15 ` [PATCH 4/4] target/i386: Added changed priority check for VIRQ Lara Lazier
3 siblings, 0 replies; 6+ messages in thread
From: Lara Lazier @ 2021-08-20 14:15 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, Lara Lazier
VGIF provides masking capability for when virtual interrupts
are taken. (APM2)
Signed-off-by: Lara Lazier <laramglazier@gmail.com>
---
target/i386/cpu.c | 7 +++++--
target/i386/cpu.h | 2 ++
target/i386/tcg/sysemu/svm_helper.c | 12 ++++++++++++
3 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 5dcdab3b80..b2094175d9 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -5649,6 +5649,7 @@ static void x86_cpu_reset(DeviceState *dev)
/* init to reset state */
env->int_ctl = 0;
env->hflags2 |= HF2_GIF_MASK;
+ env->hflags2 |= HF2_VGIF_MASK;
env->hflags &= ~HF_GUEST_MASK;
cpu_x86_update_cr0(env, 0x60000010);
@@ -6532,10 +6533,12 @@ int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request)
!(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
return CPU_INTERRUPT_HARD;
#if !defined(CONFIG_USER_ONLY)
- } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
+ } else if (env->hflags2 & HF2_VGIF_MASK) {
+ if((interrupt_request & CPU_INTERRUPT_VIRQ) &&
(env->eflags & IF_MASK) &&
!(env->hflags & HF_INHIBIT_IRQ_MASK)) {
- return CPU_INTERRUPT_VIRQ;
+ return CPU_INTERRUPT_VIRQ;
+ }
#endif
}
}
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index e27a1aab99..d26df6de6b 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -203,6 +203,7 @@ typedef enum X86Seg {
#define HF2_MPX_PR_SHIFT 5 /* BNDCFGx.BNDPRESERVE */
#define HF2_NPT_SHIFT 6 /* Nested Paging enabled */
#define HF2_IGNNE_SHIFT 7 /* Ignore CR0.NE=0 */
+#define HF2_VGIF_SHIFT 8 /* Can take VIRQ*/
#define HF2_GIF_MASK (1 << HF2_GIF_SHIFT)
#define HF2_HIF_MASK (1 << HF2_HIF_SHIFT)
@@ -212,6 +213,7 @@ typedef enum X86Seg {
#define HF2_MPX_PR_MASK (1 << HF2_MPX_PR_SHIFT)
#define HF2_NPT_MASK (1 << HF2_NPT_SHIFT)
#define HF2_IGNNE_MASK (1 << HF2_IGNNE_SHIFT)
+#define HF2_VGIF_MASK (1 << HF2_VGIF_SHIFT)
#define CR0_PE_SHIFT 0
#define CR0_MP_SHIFT 1
diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c
index 9ef2454779..2c44bdb243 100644
--- a/target/i386/tcg/sysemu/svm_helper.c
+++ b/target/i386/tcg/sysemu/svm_helper.c
@@ -130,6 +130,11 @@ static inline bool virtual_gif_enabled(CPUX86State *env)
return false;
}
+static inline bool virtual_gif_set(CPUX86State *env)
+{
+ return !virtual_gif_enabled(env) || (env->int_ctl & V_GIF_MASK);
+}
+
void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
{
CPUState *cs = env_cpu(env);
@@ -363,6 +368,10 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
cs->interrupt_request |= CPU_INTERRUPT_VIRQ;
}
+ if (virtual_gif_set(env)) {
+ env->hflags2 |= HF2_VGIF_MASK;
+ }
+
/* maybe we need to inject an event */
event_inj = x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
control.event_inj));
@@ -519,6 +528,7 @@ void helper_stgi(CPUX86State *env)
if (virtual_gif_enabled(env)) {
env->int_ctl |= V_GIF_MASK;
+ env->hflags2 |= HF2_VGIF_MASK;
} else {
env->hflags2 |= HF2_GIF_MASK;
}
@@ -530,6 +540,7 @@ void helper_clgi(CPUX86State *env)
if (virtual_gif_enabled(env)) {
env->int_ctl &= ~V_GIF_MASK;
+ env->hflags2 &= ~HF2_VGIF_MASK;
} else {
env->hflags2 &= ~HF2_GIF_MASK;
}
@@ -811,6 +822,7 @@ void do_vmexit(CPUX86State *env)
env->vm_vmcb + offsetof(struct vmcb, control.event_inj), 0);
env->hflags2 &= ~HF2_GIF_MASK;
+ env->hflags2 &= ~HF2_VGIF_MASK;
/* FIXME: Resets the current ASID register to zero (host ASID). */
/* Clears the V_IRQ and V_INTR_MASKING bits inside the processor. */
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] target/i386: Added ignore TPR check in ctl_has_irq
2021-08-20 14:15 [PATCH 0/4] target/i386: V_IRQ masking and V_TPR fixes Lara Lazier
2021-08-20 14:15 ` [PATCH 1/4] target/i386: Moved int_ctl into CPUX86State structure Lara Lazier
2021-08-20 14:15 ` [PATCH 2/4] target/i386: Added VGIF V_IRQ masking capability Lara Lazier
@ 2021-08-20 14:15 ` Lara Lazier
2021-08-20 14:15 ` [PATCH 4/4] target/i386: Added changed priority check for VIRQ Lara Lazier
3 siblings, 0 replies; 6+ messages in thread
From: Lara Lazier @ 2021-08-20 14:15 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, Lara Lazier
The APM2 states that if V_IGN_TPR is nonzero, the current
virtual interrupt ignores the (virtual) TPR.
Signed-off-by: Lara Lazier <laramglazier@gmail.com>
---
target/i386/tcg/sysemu/svm_helper.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c
index 2c44bdb243..cbd3f086c4 100644
--- a/target/i386/tcg/sysemu/svm_helper.c
+++ b/target/i386/tcg/sysemu/svm_helper.c
@@ -83,6 +83,11 @@ static inline bool ctl_has_irq(CPUX86State *env)
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);
}
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/4] target/i386: Added changed priority check for VIRQ
2021-08-20 14:15 [PATCH 0/4] target/i386: V_IRQ masking and V_TPR fixes Lara Lazier
` (2 preceding siblings ...)
2021-08-20 14:15 ` [PATCH 3/4] target/i386: Added ignore TPR check in ctl_has_irq Lara Lazier
@ 2021-08-20 14:15 ` Lara Lazier
3 siblings, 0 replies; 6+ messages in thread
From: Lara Lazier @ 2021-08-20 14:15 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, Lara Lazier
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>
---
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 d26df6de6b..69e722253d 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2245,6 +2245,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 cbd3f086c4..312f10f1e4 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)) {
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] target/i386: Added ignore TPR check in ctl_has_irq
2021-08-18 7:08 [PATCH 0/4] target/i386: V_IRQ masking and V_TPR fixes Lara Lazier
@ 2021-08-18 7:08 ` Lara Lazier
0 siblings, 0 replies; 6+ messages in thread
From: Lara Lazier @ 2021-08-18 7:08 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, Lara Lazier
The APM2 states that if V_IGN_TPR is nonzero, the current
virtual interrupt ignores the (virtual) TPR.
Signed-off-by: Lara Lazier <laramglazier@gmail.com>
---
target/i386/tcg/sysemu/svm_helper.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c
index 2c44bdb243..cbd3f086c4 100644
--- a/target/i386/tcg/sysemu/svm_helper.c
+++ b/target/i386/tcg/sysemu/svm_helper.c
@@ -83,6 +83,11 @@ static inline bool ctl_has_irq(CPUX86State *env)
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);
}
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2021-08-20 14:25 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-20 14:15 [PATCH 0/4] target/i386: V_IRQ masking and V_TPR fixes Lara Lazier
2021-08-20 14:15 ` [PATCH 1/4] target/i386: Moved int_ctl into CPUX86State structure Lara Lazier
2021-08-20 14:15 ` [PATCH 2/4] target/i386: Added VGIF V_IRQ masking capability Lara Lazier
2021-08-20 14:15 ` [PATCH 3/4] target/i386: Added ignore TPR check in ctl_has_irq Lara Lazier
2021-08-20 14:15 ` [PATCH 4/4] target/i386: Added changed priority check for VIRQ Lara Lazier
-- strict thread matches above, loose matches on Subject: below --
2021-08-18 7:08 [PATCH 0/4] target/i386: V_IRQ masking and V_TPR fixes Lara Lazier
2021-08-18 7:08 ` [PATCH 3/4] target/i386: Added ignore TPR check in ctl_has_irq Lara Lazier
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.