Skip to content

Commit e3126a5

Browse files
Lara Lazierbonzini
authored andcommitted
target/i386: Moved int_ctl into CPUX86State structure
Moved int_ctl into the CPUX86State structure. It removes some unnecessary stores and loads, and prepares for tracking the vIRQ state even when it is masked due to vGIF. Signed-off-by: Lara Lazier <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 900eeca commit e3126a5

File tree

6 files changed

+41
-38
lines changed

6 files changed

+41
-38
lines changed

target/i386/cpu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5655,7 +5655,7 @@ static void x86_cpu_reset(DeviceState *dev)
56555655
env->old_exception = -1;
56565656

56575657
/* init to reset state */
5658-
5658+
env->int_ctl = 0;
56595659
env->hflags2 |= HF2_GIF_MASK;
56605660
env->hflags &= ~HF_GUEST_MASK;
56615661

target/i386/cpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,6 +1578,7 @@ typedef struct CPUX86State {
15781578
uint64_t nested_cr3;
15791579
uint32_t nested_pg_mode;
15801580
uint8_t v_tpr;
1581+
uint32_t int_ctl;
15811582

15821583
/* KVM states, automatically cleared on reset */
15831584
uint8_t nmi_injected;

target/i386/machine.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ static int cpu_pre_save(void *opaque)
203203
X86CPU *cpu = opaque;
204204
CPUX86State *env = &cpu->env;
205205
int i;
206-
206+
env->v_tpr = env->int_ctl & V_TPR_MASK;
207207
/* FPU */
208208
env->fpus_vmstate = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
209209
env->fptag_vmstate = 0;
@@ -1356,6 +1356,25 @@ static const VMStateDescription vmstate_svm_npt = {
13561356
}
13571357
};
13581358

1359+
static bool svm_guest_needed(void *opaque)
1360+
{
1361+
X86CPU *cpu = opaque;
1362+
CPUX86State *env = &cpu->env;
1363+
1364+
return tcg_enabled() && env->int_ctl;
1365+
}
1366+
1367+
static const VMStateDescription vmstate_svm_guest = {
1368+
.name = "cpu/svm_guest",
1369+
.version_id = 1,
1370+
.minimum_version_id = 1,
1371+
.needed = svm_guest_needed,
1372+
.fields = (VMStateField[]){
1373+
VMSTATE_UINT32(env.int_ctl, X86CPU),
1374+
VMSTATE_END_OF_LIST()
1375+
}
1376+
};
1377+
13591378
#ifndef TARGET_X86_64
13601379
static bool intel_efer32_needed(void *opaque)
13611380
{
@@ -1524,6 +1543,7 @@ const VMStateDescription vmstate_x86_cpu = {
15241543
&vmstate_msr_intel_pt,
15251544
&vmstate_msr_virt_ssbd,
15261545
&vmstate_svm_npt,
1546+
&vmstate_svm_guest,
15271547
#ifndef TARGET_X86_64
15281548
&vmstate_efer32,
15291549
#endif

target/i386/tcg/seg_helper.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1166,14 +1166,14 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
11661166
break;
11671167
#if !defined(CONFIG_USER_ONLY)
11681168
case CPU_INTERRUPT_VIRQ:
1169-
/* FIXME: this should respect TPR */
11701169
cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR, 0, 0);
11711170
intno = x86_ldl_phys(cs, env->vm_vmcb
11721171
+ offsetof(struct vmcb, control.int_vector));
11731172
qemu_log_mask(CPU_LOG_TB_IN_ASM,
11741173
"Servicing virtual hardware INT=0x%02x\n", intno);
11751174
do_interrupt_x86_hardirq(env, intno, 1);
11761175
cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
1176+
env->int_ctl &= ~V_IRQ_MASK;
11771177
break;
11781178
#endif
11791179
}

target/i386/tcg/sysemu/misc_helper.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ target_ulong helper_read_crN(CPUX86State *env, int reg)
7373
if (!(env->hflags2 & HF2_VINTR_MASK)) {
7474
val = cpu_get_apic_tpr(env_archcpu(env)->apic_state);
7575
} else {
76-
val = env->v_tpr;
76+
val = env->int_ctl & V_TPR_MASK;
7777
}
7878
break;
7979
}
@@ -121,7 +121,7 @@ void helper_write_crN(CPUX86State *env, int reg, target_ulong t0)
121121
cpu_set_apic_tpr(env_archcpu(env)->apic_state, t0);
122122
qemu_mutex_unlock_iothread();
123123
}
124-
env->v_tpr = t0 & 0x0f;
124+
env->int_ctl = (env->int_ctl & ~V_TPR_MASK) | (t0 & V_TPR_MASK);
125125
break;
126126
default:
127127
env->cr[reg] = t0;

target/i386/tcg/sysemu/svm_helper.c

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,14 @@ static inline void svm_load_seg_cache(CPUX86State *env, hwaddr addr,
7676
sc->base, sc->limit, sc->flags);
7777
}
7878

79-
static inline bool ctl_has_irq(uint32_t int_ctl)
79+
static inline bool ctl_has_irq(CPUX86State *env)
8080
{
8181
uint32_t int_prio;
8282
uint32_t tpr;
8383

84-
int_prio = (int_ctl & V_INTR_PRIO_MASK) >> V_INTR_PRIO_SHIFT;
85-
tpr = int_ctl & V_TPR_MASK;
86-
return (int_ctl & V_IRQ_MASK) && (int_prio >= tpr);
84+
int_prio = (env->int_ctl & V_INTR_PRIO_MASK) >> V_INTR_PRIO_SHIFT;
85+
tpr = env->int_ctl & V_TPR_MASK;
86+
return (env->int_ctl & V_IRQ_MASK) && (int_prio >= tpr);
8787
}
8888

8989
static inline bool is_efer_invalid_state (CPUX86State *env)
@@ -121,13 +121,11 @@ static inline bool is_efer_invalid_state (CPUX86State *env)
121121
return false;
122122
}
123123

124-
static inline bool virtual_gif_enabled(CPUX86State *env, uint32_t *int_ctl)
124+
static inline bool virtual_gif_enabled(CPUX86State *env)
125125
{
126126
if (likely(env->hflags & HF_GUEST_MASK)) {
127-
*int_ctl = x86_ldl_phys(env_cpu(env),
128-
env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
129127
return (env->features[FEAT_SVM] & CPUID_SVM_VGIF)
130-
&& (*int_ctl & V_GIF_ENABLED_MASK);
128+
&& (env->int_ctl & V_GIF_ENABLED_MASK);
131129
}
132130
return false;
133131
}
@@ -139,7 +137,6 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
139137
target_ulong addr;
140138
uint64_t nested_ctl;
141139
uint32_t event_inj;
142-
uint32_t int_ctl;
143140
uint32_t asid;
144141
uint64_t new_cr0;
145142
uint64_t new_cr3;
@@ -292,11 +289,10 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
292289
cpu_x86_update_cr3(env, new_cr3);
293290
env->cr[2] = x86_ldq_phys(cs,
294291
env->vm_vmcb + offsetof(struct vmcb, save.cr2));
295-
int_ctl = x86_ldl_phys(cs,
292+
env->int_ctl = x86_ldl_phys(cs,
296293
env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
297294
env->hflags2 &= ~(HF2_HIF_MASK | HF2_VINTR_MASK);
298-
if (int_ctl & V_INTR_MASKING_MASK) {
299-
env->v_tpr = int_ctl & V_TPR_MASK;
295+
if (env->int_ctl & V_INTR_MASKING_MASK) {
300296
env->hflags2 |= HF2_VINTR_MASK;
301297
if (env->eflags & IF_MASK) {
302298
env->hflags2 |= HF2_HIF_MASK;
@@ -362,7 +358,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
362358

363359
env->hflags2 |= HF2_GIF_MASK;
364360

365-
if (ctl_has_irq(int_ctl)) {
361+
if (ctl_has_irq(env)) {
366362
CPUState *cs = env_cpu(env);
367363

368364
cs->interrupt_request |= CPU_INTERRUPT_VIRQ;
@@ -522,11 +518,8 @@ void helper_stgi(CPUX86State *env)
522518
{
523519
cpu_svm_check_intercept_param(env, SVM_EXIT_STGI, 0, GETPC());
524520

525-
CPUState *cs = env_cpu(env);
526-
uint32_t int_ctl;
527-
if (virtual_gif_enabled(env, &int_ctl)) {
528-
x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
529-
int_ctl | V_GIF_MASK);
521+
if (virtual_gif_enabled(env)) {
522+
env->int_ctl |= V_GIF_MASK;
530523
} else {
531524
env->hflags2 |= HF2_GIF_MASK;
532525
}
@@ -536,11 +529,8 @@ void helper_clgi(CPUX86State *env)
536529
{
537530
cpu_svm_check_intercept_param(env, SVM_EXIT_CLGI, 0, GETPC());
538531

539-
CPUState *cs = env_cpu(env);
540-
uint32_t int_ctl;
541-
if (virtual_gif_enabled(env, &int_ctl)) {
542-
x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
543-
int_ctl & ~V_GIF_MASK);
532+
if (virtual_gif_enabled(env)) {
533+
env->int_ctl &= ~V_GIF_MASK;
544534
} else {
545535
env->hflags2 &= ~HF2_GIF_MASK;
546536
}
@@ -688,7 +678,6 @@ void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1,
688678
void do_vmexit(CPUX86State *env)
689679
{
690680
CPUState *cs = env_cpu(env);
691-
uint32_t int_ctl;
692681

693682
if (env->hflags & HF_INHIBIT_IRQ_MASK) {
694683
x86_stl_phys(cs,
@@ -731,16 +720,8 @@ void do_vmexit(CPUX86State *env)
731720
env->vm_vmcb + offsetof(struct vmcb, save.cr3), env->cr[3]);
732721
x86_stq_phys(cs,
733722
env->vm_vmcb + offsetof(struct vmcb, save.cr4), env->cr[4]);
734-
735-
int_ctl = x86_ldl_phys(cs,
736-
env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
737-
int_ctl &= ~(V_TPR_MASK | V_IRQ_MASK);
738-
int_ctl |= env->v_tpr & V_TPR_MASK;
739-
if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
740-
int_ctl |= V_IRQ_MASK;
741-
}
742723
x86_stl_phys(cs,
743-
env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), int_ctl);
724+
env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), env->int_ctl);
744725

745726
x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.rflags),
746727
cpu_compute_eflags(env));
@@ -763,6 +744,7 @@ void do_vmexit(CPUX86State *env)
763744
env->intercept = 0;
764745
env->intercept_exceptions = 0;
765746
cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
747+
env->int_ctl = 0;
766748
env->tsc_offset = 0;
767749

768750
env->gdt.base = x86_ldq_phys(cs, env->vm_hsave + offsetof(struct vmcb,

0 commit comments

Comments
 (0)