whpx: i386: use WHvX64RegisterCr8 only when kernel-irqchip=off
When kernel-irqchip=on, manage TPR as part of the APIC state instead entirely. This fixes some failure to set state errors. Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr> Link: https://lore.kernel.org/r/20260422214225.2242-10-mohamed@unpredictable.fr Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Mohamed Mediouni committed
Apr 22, 2026 at 23:41 UTC
4fdbad6c4981e8c7ff1b9780f6d392227f249cb3
1 file changed
+22
-15
target/i386/whpx/whpx-all.c
+22
-15
@@ -95,7 +95,6 @@ static const WHV_REGISTER_NAME whpx_register_names[] = {
95
WHvX64RegisterCr2,
96
WHvX64RegisterCr3,
97
WHvX64RegisterCr4,
98
- WHvX64RegisterCr8,
98
99
/* X64 Debug Registers */
100
/*
@@ -478,8 +477,11 @@ void whpx_set_registers(CPUState *cpu, WHPXStateLevel level)
477
vcxt.values[idx++].Reg64 = env->cr[3];
478
assert(whpx_register_names[idx] == WHvX64RegisterCr4);
479
vcxt.values[idx++].Reg64 = env->cr[4];
481
- assert(whpx_register_names[idx] == WHvX64RegisterCr8);
482
- vcxt.values[idx++].Reg64 = vcpu->tpr;
480
+ /* For kernel-irqchip=on, TPR is managed as part of APIC state */
481
+ if (!whpx_irqchip_in_kernel()) {
482
+ WHV_REGISTER_VALUE cr8 = {.Reg64 = vcpu->tpr};
483
+ whpx_set_reg(cpu, WHvX64RegisterCr8, cr8);
484
+ }
485
486
/* 8 Debug Registers - Skipped */
487
@@ -735,11 +737,14 @@ void whpx_get_registers(CPUState *cpu, WHPXStateLevel level)
737
env->cr[3] = vcxt.values[idx++].Reg64;
738
assert(whpx_register_names[idx] == WHvX64RegisterCr4);
739
env->cr[4] = vcxt.values[idx++].Reg64;
738
- assert(whpx_register_names[idx] == WHvX64RegisterCr8);
739
- tpr = vcxt.values[idx++].Reg64;
740
- if (tpr != vcpu->tpr) {
741
- vcpu->tpr = tpr;
742
- cpu_set_apic_tpr(x86_cpu->apic_state, tpr);
740
+
741
+ /* For kernel-irqchip=on, TPR is managed as part of APIC state */
742
+ if (!whpx_irqchip_in_kernel()) {
743
+ tpr = vcpu->exit_ctx.VpContext.Cr8;
744
+ if (tpr != vcpu->tpr) {
745
+ vcpu->tpr = tpr;
746
+ cpu_set_apic_tpr(x86_cpu->apic_state, tpr);
747
+ }
748
}
749
750
/* 8 Debug Registers - Skipped */
@@ -1745,7 +1750,7 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
1750
1751
/* Sync the TPR to the CR8 if was modified during the intercept */
1752
tpr = cpu_get_apic_tpr(x86_cpu->apic_state);
1748
- if (tpr != vcpu->tpr) {
1753
+ if (!whpx_irqchip_in_kernel() && tpr != vcpu->tpr) {
1754
vcpu->tpr = tpr;
1755
reg_values[reg_count].Reg64 = tpr;
1756
qatomic_set(&cpu->exit_request, true);
@@ -1787,12 +1792,14 @@ static void whpx_vcpu_post_run(CPUState *cpu)
1792
1793
env->eflags = vcpu->exit_ctx.VpContext.Rflags;
1794
1790
- uint64_t tpr = vcpu->exit_ctx.VpContext.Cr8;
1791
- if (vcpu->tpr != tpr) {
1792
- vcpu->tpr = tpr;
1793
- bql_lock();
1794
- cpu_set_apic_tpr(x86_cpu->apic_state, vcpu->tpr);
1795
- bql_unlock();
1795
+ if (!whpx_irqchip_in_kernel()) {
1796
+ uint64_t tpr = vcpu->exit_ctx.VpContext.Cr8;
1797
+ if (vcpu->tpr != tpr) {
1798
+ vcpu->tpr = tpr;
1799
+ bql_lock();
1800
+ cpu_set_apic_tpr(x86_cpu->apic_state, vcpu->tpr);
1801
+ bql_unlock();
1802
+ }
1803
}
1804
1805
vcpu->interruption_pending =