@samitouri / QOSamiQemu / commits / 77f90aef5b

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