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>
---
target/i386/whpx/whpx-all.c | 37 ++++++++++++++++++++++---------------
1 file changed, 22 insertions(+), 15 deletions(-)
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index 97284b954b..a3e91ca533 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -93,7 +93,6 @@ static const WHV_REGISTER_NAME whpx_register_names[] = {
WHvX64RegisterCr2,
WHvX64RegisterCr3,
WHvX64RegisterCr4,
- WHvX64RegisterCr8,
/* X64 Debug Registers */
/*
@@ -457,8 +456,11 @@ void whpx_set_registers(CPUState *cpu, WHPXStateLevel level)
vcxt.values[idx++].Reg64 = env->cr[3];
assert(whpx_register_names[idx] == WHvX64RegisterCr4);
vcxt.values[idx++].Reg64 = env->cr[4];
- assert(whpx_register_names[idx] == WHvX64RegisterCr8);
- vcxt.values[idx++].Reg64 = vcpu->tpr;
+ /* For kernel-irqchip=on, TPR is managed as part of APIC state */
+ if (!whpx_irqchip_in_kernel()) {
+ WHV_REGISTER_VALUE cr8 = {.Reg64 = vcpu->tpr};
+ whpx_set_reg(cpu, WHvX64RegisterCr8, cr8);
+ }
/* 8 Debug Registers - Skipped */
@@ -714,11 +716,14 @@ void whpx_get_registers(CPUState *cpu, WHPXStateLevel level)
env->cr[3] = vcxt.values[idx++].Reg64;
assert(whpx_register_names[idx] == WHvX64RegisterCr4);
env->cr[4] = vcxt.values[idx++].Reg64;
- assert(whpx_register_names[idx] == WHvX64RegisterCr8);
- tpr = vcxt.values[idx++].Reg64;
- if (tpr != vcpu->tpr) {
- vcpu->tpr = tpr;
- cpu_set_apic_tpr(x86_cpu->apic_state, tpr);
+
+ /* For kernel-irqchip=on, TPR is managed as part of APIC state */
+ if (!whpx_irqchip_in_kernel()) {
+ tpr = vcpu->exit_ctx.VpContext.Cr8;
+ if (tpr != vcpu->tpr) {
+ vcpu->tpr = tpr;
+ cpu_set_apic_tpr(x86_cpu->apic_state, tpr);
+ }
}
/* 8 Debug Registers - Skipped */
@@ -1660,7 +1665,7 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
/* Sync the TPR to the CR8 if was modified during the intercept */
tpr = cpu_get_apic_tpr(x86_cpu->apic_state);
- if (tpr != vcpu->tpr) {
+ if (!whpx_irqchip_in_kernel() && tpr != vcpu->tpr) {
vcpu->tpr = tpr;
reg_values[reg_count].Reg64 = tpr;
qatomic_set(&cpu->exit_request, true);
@@ -1707,12 +1712,14 @@ static void whpx_vcpu_post_run(CPUState *cpu)
env->eflags = vcpu->exit_ctx.VpContext.Rflags;
- uint64_t tpr = vcpu->exit_ctx.VpContext.Cr8;
- if (vcpu->tpr != tpr) {
- vcpu->tpr = tpr;
- bql_lock();
- cpu_set_apic_tpr(x86_cpu->apic_state, vcpu->tpr);
- bql_unlock();
+ if (!whpx_irqchip_in_kernel()) {
+ uint64_t tpr = vcpu->exit_ctx.VpContext.Cr8;
+ if (vcpu->tpr != tpr) {
+ vcpu->tpr = tpr;
+ bql_lock();
+ cpu_set_apic_tpr(x86_cpu->apic_state, vcpu->tpr);
+ bql_unlock();
+ }
}
vcpu->interruption_pending =
--
2.50.1 (Apple Git-155)