whpx: i386: kernel-irqchip=off fixes
This was really... quite broken. After fixing this, Windows boots with kernel-irqchip=off. Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr> Link: https://lore.kernel.org/r/20260422214225.2242-9-mohamed@unpredictable.fr Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Mohamed Mediouni committed
Apr 22, 2026 at 23:41 UTC
77f90aef5b32c84090c322c1e238b46be9905cac
2 files changed
+7
-37
include/system/whpx-common.h
+1
@@ -4,6 +4,7 @@
4
5
struct AccelCPUState {
6
bool window_registered;
7
+ int window_priority;
8
bool interruptable;
9
bool ready_for_pic_interrupt;
10
uint64_t tpr;
target/i386/whpx/whpx-all.c
+6
-37
@@ -22,6 +22,8 @@
22
#include "qemu/main-loop.h"
23
#include "hw/core/boards.h"
24
#include "hw/intc/ioapic.h"
25
+#include "hw/intc/i8259.h"
26
+#include "hw/i386/x86.h"
27
#include "hw/i386/apic_internal.h"
28
#include "qemu/error-report.h"
29
#include "qapi/error.h"
@@ -390,28 +392,6 @@ static int whpx_set_tsc(CPUState *cpu)
392
return 0;
393
}
394
393
-/*
394
- * The CR8 register in the CPU is mapped to the TPR register of the APIC,
395
- * however, they use a slightly different encoding. Specifically:
396
- *
397
- * APIC.TPR[bits 7:4] = CR8[bits 3:0]
398
- *
399
- * This mechanism is described in section 10.8.6.1 of Volume 3 of Intel 64
400
- * and IA-32 Architectures Software Developer's Manual.
401
- *
402
- * The functions below translate the value of CR8 to TPR and vice versa.
403
- */
404
-
405
-static uint64_t whpx_apic_tpr_to_cr8(uint64_t tpr)
406
-{
407
- return tpr >> 4;
408
-}
409
-
410
-static uint64_t whpx_cr8_to_apic_tpr(uint64_t cr8)
411
-{
412
- return cr8 << 4;
413
-}
414
-
395
void whpx_set_registers(CPUState *cpu, WHPXStateLevel level)
396
{
397
struct whpx_state *whpx = &whpx_global;
@@ -440,7 +420,7 @@ void whpx_set_registers(CPUState *cpu, WHPXStateLevel level)
420
v86 = (env->eflags & VM_MASK);
421
r86 = !(env->cr[0] & CR0_PE_MASK);
422
443
- vcpu->tpr = whpx_apic_tpr_to_cr8(cpu_get_apic_tpr(x86_cpu->apic_state));
423
+ vcpu->tpr = cpu_get_apic_tpr(x86_cpu->apic_state);
424
vcpu->apic_base = cpu_get_apic_base(x86_cpu->apic_state);
425
426
idx = 0;
@@ -711,17 +691,6 @@ void whpx_get_registers(CPUState *cpu, WHPXStateLevel level)
691
hr);
692
}
693
714
- if (whpx_irqchip_in_kernel()) {
715
- /*
716
- * Fetch the TPR value from the emulated APIC. It may get overwritten
717
- * below with the value from CR8 returned by
718
- * WHvGetVirtualProcessorRegisters().
719
- */
720
- whpx_apic_get(x86_cpu->apic_state);
721
- vcpu->tpr = whpx_apic_tpr_to_cr8(
722
- cpu_get_apic_tpr(x86_cpu->apic_state));
723
- }
724
-
694
idx = 0;
695
696
/* Indexes for first 16 registers match between HV and QEMU definitions */
@@ -770,7 +739,7 @@ void whpx_get_registers(CPUState *cpu, WHPXStateLevel level)
739
tpr = vcxt.values[idx++].Reg64;
740
if (tpr != vcpu->tpr) {
741
vcpu->tpr = tpr;
773
- cpu_set_apic_tpr(x86_cpu->apic_state, whpx_cr8_to_apic_tpr(tpr));
742
+ cpu_set_apic_tpr(x86_cpu->apic_state, tpr);
743
}
744
745
/* 8 Debug Registers - Skipped */
@@ -1775,7 +1744,7 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
1744
}
1745
1746
/* Sync the TPR to the CR8 if was modified during the intercept */
1778
- tpr = whpx_apic_tpr_to_cr8(cpu_get_apic_tpr(x86_cpu->apic_state));
1747
+ tpr = cpu_get_apic_tpr(x86_cpu->apic_state);
1748
if (tpr != vcpu->tpr) {
1749
vcpu->tpr = tpr;
1750
reg_values[reg_count].Reg64 = tpr;
@@ -1822,7 +1791,7 @@ static void whpx_vcpu_post_run(CPUState *cpu)
1791
if (vcpu->tpr != tpr) {
1792
vcpu->tpr = tpr;
1793
bql_lock();
1825
- cpu_set_apic_tpr(x86_cpu->apic_state, whpx_cr8_to_apic_tpr(vcpu->tpr));
1794
+ cpu_set_apic_tpr(x86_cpu->apic_state, vcpu->tpr);
1795
bql_unlock();
1796
}
1797