[PATCH v8 00/13] whpx: i386: bug fixes, feature probing and CPUID

Mohamed Mediouni posted 13 patches 4 days, 2 hours ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260407141809.16862-1-mohamed@unpredictable.fr
Maintainers: Pedro Barbuda <pbarbuda@microsoft.com>, Mohamed Mediouni <mohamed@unpredictable.fr>, Peter Maydell <peter.maydell@linaro.org>, Paolo Bonzini <pbonzini@redhat.com>, Zhao Liu <zhao1.liu@intel.com>, Roman Bolshakov <rbolshakov@ddn.com>, Phil Dennis-Jordan <phil@philjordan.eu>, Wei Liu <wei.liu@kernel.org>
There is a newer version of this series
accel/whpx/whpx-common.c       |   2 +
include/system/whpx-common.h   |   1 +
include/system/whpx-internal.h |  10 +
target/arm/whpx/whpx-all.c     |   1 +
target/i386/cpu.c              |  25 ++
target/i386/emulate/x86_emu.c  |   4 +-
target/i386/whpx/whpx-all.c    | 580 +++++++++++++++++++++++++++------
target/i386/whpx/whpx-i386.h   |   4 +
8 files changed, 530 insertions(+), 97 deletions(-)
create mode 100644 target/i386/whpx/whpx-i386.h
[PATCH v8 00/13] whpx: i386: bug fixes, feature probing and CPUID
Posted by Mohamed Mediouni 4 days, 2 hours ago
This is a supplemental update that includes
"whpx: i386: x2apic emulation for kernel-irqchip=off, feature probing"
v4 unmodified.

This might be too big for QEMU 11.0 at this point though...

"whpx: i386: disable TbFlushHypercalls for emulated LAPIC" is a
bugfix, and "target/i386: emulate: include name of unhandled instruction"
is a debugging aid.

"whpx: i386: x2apic emulation" makes things slightly better for Windows
10 users. But I strongly recommend *not* relying on it when possible and
using kernel-irqchip=on instead. On Windows 10 however that's more murky
because PIC interrupt injection is broken (interrupts don't wake the vCPU
from HLT) in that case.

"whpx: i386: wire up feature probing" is yet another commit adding a code path
not used on Windows 10. It'll tell the user today which CPU features they set
are incompatible with the hardware but it does not sync that to the CPUID view
that the guest has.

And then another commit to enable x2apic emulation by default even for
kernel-irqchip=off + re-introducing provided by QEMU enlightenments in a more
functional form to signal that the x2apic can be used. I'm not aware of the
actual vmware freq leaf being used though.

"whpx: x2apic emulation for kernel-irqchip=off follow-up" is rolled into this series.

"whpx: i386: reintroduce enlightenments for Windows 10" is a bugfix to make
x2APIC work as intended on Windows 10 without emulating an IOMMU.
*And* a massive improvement for Windows 10 hosts in performance for Linux guests
due to using the right clocksource instead of HPET.

And dependent on this series so included, CPUID intercepts finally...
However that's only supported starting from Windows 11/Server 2022.

Also ended up switching over Windows 10 to kernel-irqchip=off
by default due to PIC interrupt injection being broken.

Old performance (or lack thereof...) numbers:

On a Ryzen 7 8700GE with a Windows 10 VM running with KVM in nested virt, with
kernel-irqchip=off for the virt Alpine Linux x86_64 ISO (3.23.3) with -smp cores=2,
boot times as reported through dmesg:

- QEMU 10.2: 83 seconds
- QEMU 10.2 with a single core: 18.1 seconds
- as of v6 of this series, x2apic forced off: 29 seconds
- as of v6 this series, out of the box: 18 seconds
- v6 with kernel-irqchip=on and EDK2: 16.5 seconds
- v6 with kernel-irqchip=off and EDK2: 9.5 seconds
- v6, and with 1 core instead of two: 12.6 seconds

In v7, the Windows 10 numbers are pretty much at parity with Windows 11 now.

And with this series on a Windows 11 VM on the same hardware:
- kernel-irqchip=on: 6.5 seconds
- kernel-irqchip=on, x2apic forced off: 7.6 seconds
- kernel-irqchip=off: 8.3 seconds
- hyperv=off,kernel-irqchip=off: 7.6 seconds... which is faster,
so the absence of enlightenment support on Windows 10 doesn't explain things...

With kernel-irqchip=on on Windows 10, when booting with SeaBIOS, it gets stuck in
syslinux due to PIC interrupt injection being broken there. That can be counted
as an infinite boot time (?).

checkpatch false positives:

ERROR: spaces required around that '*' (ctx:WxV)
+         UINT32 Ecx, WHV_CPUID_OUTPUT *CpuidOutput))

Not a multiplication but a pointer reference.

ERROR: space prohibited after that '&' (ctx:ExW)
+                    & CPUID_7_0_EDX_CET_IBT) {
                     ^

ERROR: space prohibited after that '&' (ctx:ExW)
+                    & CPUID_7_0_ECX_CET_SHSTK) {
                     ^

Because it's multiline.

Changes in v8:

- Interrupt priority changes are back.
- Some CPUID fixes
- disable enlightenments and LAPIC for isapc

Changes in v7:

- Exposing VMware hypervisor identification when not
using Hyper-V enlightenments and when the VMware frequency
CPUID leaf isn't explictly disabled.

- Remove the interrupt priority logic as it has issues with
PIC interrupts. Can be reintroduced later.

- -cpu max passing through CPUID info from Hyper-V
- fill xsave info

- OSXSAVE CPUID leaf reporting fix.

Changes in v6:

- kernel-irqchip=off fix: re-registering the interrupt window
when the existing one has too low of a TPR value.

Folded into "whpx: i386: kernel-irqchip=off fixes".

- I/O port access fast path cleanup commit added at the end

The path relied on a side effect of whpx_get_reg instead of
something cleaner.

- Use the CR8 register provided by the hypervisor only when
kernel-irqchip=off. Rely on the APIC state synchronisation
otherwise.

This fixes some register sync errors that surfaced when setting
the TPR values properly.

Changes in v5/v1 with rename:

- kernel-irqchip=off fixes, notably making 64-bit Windows bootable
- switching over Windows 10 to kernel-irqchip=off by default

Changes in v4:

- Ugh for a revision sent quickly, unbreaking the arm64 build...
- and making checkpatch happier to some extent

Changes in v3:

- Fixing CPUID intercepts so that QEMU CPU models work fine now, instead
of the partial intercept that was present in QEMU 10.2
- cleanups

Changes in v2:

- GCC warned when a variable name was re-used within a different (but overlapping)
scope in the same function. It also warned with a -Werror=maybe-uninitialized for
the MSR write case. Address those
- make the in-KVM enlightenments path available on Windows 11 too when -M hyperv=off.

Mohamed Mediouni (13):
  target/i386: emulate: include name of unhandled instruction
  whpx: i386: x2apic emulation
  whpx: i386: wire up feature probing
  whpx: i386: disable TbFlushHypercalls for emulated LAPIC
  whpx: i386: enable x2apic by default for user-mode LAPIC
  whpx: i386: reintroduce enlightenments for Windows 10
  whpx: i386: introduce proper cpuid support
  whpx: i386: kernel-irqchip=off fixes
  whpx: i386: use WHvX64RegisterCr8 only when kernel-irqchip=off
  whpx: i386: disable kernel-irqchip on Windows 10 when PIC enabled
  whpx: i386: IO port fast path cleanup
  whpx: i386: disable enlightenments and LAPIC for isapc
  whpx: i386: interrupt priority support

 accel/whpx/whpx-common.c       |   2 +
 include/system/whpx-common.h   |   1 +
 include/system/whpx-internal.h |  10 +
 target/arm/whpx/whpx-all.c     |   1 +
 target/i386/cpu.c              |  25 ++
 target/i386/emulate/x86_emu.c  |   4 +-
 target/i386/whpx/whpx-all.c    | 580 +++++++++++++++++++++++++++------
 target/i386/whpx/whpx-i386.h   |   4 +
 8 files changed, 530 insertions(+), 97 deletions(-)
 create mode 100644 target/i386/whpx/whpx-i386.h

-- 
2.50.1 (Apple Git-155)
Re: [PATCH v8 00/13] whpx: i386: bug fixes, feature probing and CPUID
Posted by Mohamed Mediouni 4 days, 2 hours ago

> On 7. Apr 2026, at 16:17, Mohamed Mediouni <mohamed@unpredictable.fr> wrote:
> 
> This is a supplemental update that includes
> "whpx: i386: x2apic emulation for kernel-irqchip=off, feature probing"
> v4 unmodified.
> 
> This might be too big for QEMU 11.0 at this point though…
> 

Hi,

For those shipping prebuilt QEMU on Windows binaries, you probably
want to cherry-pick this series especially for Windows 10 users.

This is primarily due to the advertising as VMware enlightenment
which allows Linux to grab the TSC/APIC timer frequencies duo.

Secondarily is kernel-irqchip=off fixes so that modern Windows
boots in that configuration and making it have x2APIC support.

And then switching Windows 10 to kernel-irqchip=off except if
the machine has the PIC disabled as we can’t properly emulate
it with the Hyper-V APIC.

On Windows 11, the feature addition provided here is -cpu <model>
working.


> Old performance (or lack thereof...) numbers:
> 
> On a Ryzen 7 8700GE with a Windows 10 VM running with KVM in nested virt, with
> kernel-irqchip=off for the virt Alpine Linux x86_64 ISO (3.23.3) with -smp cores=2,
> boot times as reported through dmesg:
> 
> - QEMU 10.2: 83 seconds
> - QEMU 10.2 with a single core: 18.1 seconds
> - as of v6 of this series, x2apic forced off: 29 seconds
> - as of v6 this series, out of the box: 18 seconds
> - v6 with kernel-irqchip=on and EDK2: 16.5 seconds
> - v6 with kernel-irqchip=off and EDK2: 9.5 seconds
> - v6, and with 1 core instead of two: 12.6 seconds
> 
> In v7, the Windows 10 numbers are pretty much at parity with Windows 11 now.
> 
> And with this series on a Windows 11 VM on the same hardware:
> - kernel-irqchip=on: 6.5 seconds
> - kernel-irqchip=on, x2apic forced off: 7.6 seconds
> - kernel-irqchip=off: 8.3 seconds
> - hyperv=off,kernel-irqchip=off: 7.6 seconds... which is faster,
> so the absence of enlightenment support on Windows 10 doesn't explain things...
> 
> With kernel-irqchip=on on Windows 10, when booting with SeaBIOS, it gets stuck in
> syslinux due to PIC interrupt injection being broken there. That can be counted
> as an infinite boot time (?).
> 
> checkpatch false positives:
> 
> ERROR: spaces required around that '*' (ctx:WxV)
> +         UINT32 Ecx, WHV_CPUID_OUTPUT *CpuidOutput))
> 
> Not a multiplication but a pointer reference.
> 
> ERROR: space prohibited after that '&' (ctx:ExW)
> +                    & CPUID_7_0_EDX_CET_IBT) {
>                     ^
> 
> ERROR: space prohibited after that '&' (ctx:ExW)
> +                    & CPUID_7_0_ECX_CET_SHSTK) {
>                     ^
> 
> Because it's multiline.
> 
> Changes in v8:
> 
> - Interrupt priority changes are back.
> - Some CPUID fixes
> - disable enlightenments and LAPIC for isapc
> 
> Changes in v7:
> 
> - Exposing VMware hypervisor identification when not
> using Hyper-V enlightenments and when the VMware frequency
> CPUID leaf isn't explictly disabled.
> 
> - Remove the interrupt priority logic as it has issues with
> PIC interrupts. Can be reintroduced later.
> 
> - -cpu max passing through CPUID info from Hyper-V
> - fill xsave info
> 
> - OSXSAVE CPUID leaf reporting fix.
> 
> Changes in v6:
> 
> - kernel-irqchip=off fix: re-registering the interrupt window
> when the existing one has too low of a TPR value.
> 
> Folded into "whpx: i386: kernel-irqchip=off fixes".
> 
> - I/O port access fast path cleanup commit added at the end
> 
> The path relied on a side effect of whpx_get_reg instead of
> something cleaner.
> 
> - Use the CR8 register provided by the hypervisor only when
> kernel-irqchip=off. Rely on the APIC state synchronisation
> otherwise.
> 
> This fixes some register sync errors that surfaced when setting
> the TPR values properly.
> 
> Changes in v5/v1 with rename:
> 
> - kernel-irqchip=off fixes, notably making 64-bit Windows bootable
> - switching over Windows 10 to kernel-irqchip=off by default
> 
> Changes in v4:
> 
> - Ugh for a revision sent quickly, unbreaking the arm64 build...
> - and making checkpatch happier to some extent
> 
> Changes in v3:
> 
> - Fixing CPUID intercepts so that QEMU CPU models work fine now, instead
> of the partial intercept that was present in QEMU 10.2
> - cleanups
> 
> Changes in v2:
> 
> - GCC warned when a variable name was re-used within a different (but overlapping)
> scope in the same function. It also warned with a -Werror=maybe-uninitialized for
> the MSR write case. Address those
> - make the in-KVM enlightenments path available on Windows 11 too when -M hyperv=off.
> 
> Mohamed Mediouni (13):
>  target/i386: emulate: include name of unhandled instruction
>  whpx: i386: x2apic emulation
>  whpx: i386: wire up feature probing
>  whpx: i386: disable TbFlushHypercalls for emulated LAPIC
>  whpx: i386: enable x2apic by default for user-mode LAPIC
>  whpx: i386: reintroduce enlightenments for Windows 10
>  whpx: i386: introduce proper cpuid support
>  whpx: i386: kernel-irqchip=off fixes
>  whpx: i386: use WHvX64RegisterCr8 only when kernel-irqchip=off
>  whpx: i386: disable kernel-irqchip on Windows 10 when PIC enabled
>  whpx: i386: IO port fast path cleanup
>  whpx: i386: disable enlightenments and LAPIC for isapc
>  whpx: i386: interrupt priority support
> 
> accel/whpx/whpx-common.c       |   2 +
> include/system/whpx-common.h   |   1 +
> include/system/whpx-internal.h |  10 +
> target/arm/whpx/whpx-all.c     |   1 +
> target/i386/cpu.c              |  25 ++
> target/i386/emulate/x86_emu.c  |   4 +-
> target/i386/whpx/whpx-all.c    | 580 +++++++++++++++++++++++++++------
> target/i386/whpx/whpx-i386.h   |   4 +
> 8 files changed, 530 insertions(+), 97 deletions(-)
> create mode 100644 target/i386/whpx/whpx-i386.h
> 
> -- 
> 2.50.1 (Apple Git-155)
> 
Re: [PATCH v8 00/13] whpx: i386: bug fixes, feature probing and CPUID
Posted by Mohamed Mediouni 4 days, 2 hours ago

> On 7. Apr 2026, at 16:39, Mohamed Mediouni <mohamed@unpredictable.fr> wrote:
> 
> 
> 
>> On 7. Apr 2026, at 16:17, Mohamed Mediouni <mohamed@unpredictable.fr> wrote:
>> 
>> This is a supplemental update that includes
>> "whpx: i386: x2apic emulation for kernel-irqchip=off, feature probing"
>> v4 unmodified.
>> 
>> This might be too big for QEMU 11.0 at this point though…
>> 
> 
> Hi,
> 
> For those shipping prebuilt QEMU on Windows binaries, you probably
> want to cherry-pick this series especially for Windows 10 users.

Apart from the "Implement APIC IRR interrupt priorities” commit
which I’m still struggling a bit with.

That one still has at least one bug...
> 
> This is primarily due to the advertising as VMware enlightenment
> which allows Linux to grab the TSC/APIC timer frequencies duo.
> 
> Secondarily is kernel-irqchip=off fixes so that modern Windows
> boots in that configuration and making it have x2APIC support.
> 
> And then switching Windows 10 to kernel-irqchip=off except if
> the machine has the PIC disabled as we can’t properly emulate
> it with the Hyper-V APIC.
> 
> On Windows 11, the feature addition provided here is -cpu <model>
> working.
> 
> 
>> Old performance (or lack thereof...) numbers:
>> 
>> On a Ryzen 7 8700GE with a Windows 10 VM running with KVM in nested virt, with
>> kernel-irqchip=off for the virt Alpine Linux x86_64 ISO (3.23.3) with -smp cores=2,
>> boot times as reported through dmesg:
>> 
>> - QEMU 10.2: 83 seconds
>> - QEMU 10.2 with a single core: 18.1 seconds
>> - as of v6 of this series, x2apic forced off: 29 seconds
>> - as of v6 this series, out of the box: 18 seconds
>> - v6 with kernel-irqchip=on and EDK2: 16.5 seconds
>> - v6 with kernel-irqchip=off and EDK2: 9.5 seconds
>> - v6, and with 1 core instead of two: 12.6 seconds
>> 
>> In v7, the Windows 10 numbers are pretty much at parity with Windows 11 now.
>> 
>> And with this series on a Windows 11 VM on the same hardware:
>> - kernel-irqchip=on: 6.5 seconds
>> - kernel-irqchip=on, x2apic forced off: 7.6 seconds
>> - kernel-irqchip=off: 8.3 seconds
>> - hyperv=off,kernel-irqchip=off: 7.6 seconds... which is faster,
>> so the absence of enlightenment support on Windows 10 doesn't explain things...
>> 
>> With kernel-irqchip=on on Windows 10, when booting with SeaBIOS, it gets stuck in
>> syslinux due to PIC interrupt injection being broken there. That can be counted
>> as an infinite boot time (?).
>> 
>> checkpatch false positives:
>> 
>> ERROR: spaces required around that '*' (ctx:WxV)
>> +         UINT32 Ecx, WHV_CPUID_OUTPUT *CpuidOutput))
>> 
>> Not a multiplication but a pointer reference.
>> 
>> ERROR: space prohibited after that '&' (ctx:ExW)
>> +                    & CPUID_7_0_EDX_CET_IBT) {
>>                    ^
>> 
>> ERROR: space prohibited after that '&' (ctx:ExW)
>> +                    & CPUID_7_0_ECX_CET_SHSTK) {
>>                    ^
>> 
>> Because it's multiline.
>> 
>> Changes in v8:
>> 
>> - Interrupt priority changes are back.
>> - Some CPUID fixes
>> - disable enlightenments and LAPIC for isapc
>> 
>> Changes in v7:
>> 
>> - Exposing VMware hypervisor identification when not
>> using Hyper-V enlightenments and when the VMware frequency
>> CPUID leaf isn't explictly disabled.
>> 
>> - Remove the interrupt priority logic as it has issues with
>> PIC interrupts. Can be reintroduced later.
>> 
>> - -cpu max passing through CPUID info from Hyper-V
>> - fill xsave info
>> 
>> - OSXSAVE CPUID leaf reporting fix.
>> 
>> Changes in v6:
>> 
>> - kernel-irqchip=off fix: re-registering the interrupt window
>> when the existing one has too low of a TPR value.
>> 
>> Folded into "whpx: i386: kernel-irqchip=off fixes".
>> 
>> - I/O port access fast path cleanup commit added at the end
>> 
>> The path relied on a side effect of whpx_get_reg instead of
>> something cleaner.
>> 
>> - Use the CR8 register provided by the hypervisor only when
>> kernel-irqchip=off. Rely on the APIC state synchronisation
>> otherwise.
>> 
>> This fixes some register sync errors that surfaced when setting
>> the TPR values properly.
>> 
>> Changes in v5/v1 with rename:
>> 
>> - kernel-irqchip=off fixes, notably making 64-bit Windows bootable
>> - switching over Windows 10 to kernel-irqchip=off by default
>> 
>> Changes in v4:
>> 
>> - Ugh for a revision sent quickly, unbreaking the arm64 build...
>> - and making checkpatch happier to some extent
>> 
>> Changes in v3:
>> 
>> - Fixing CPUID intercepts so that QEMU CPU models work fine now, instead
>> of the partial intercept that was present in QEMU 10.2
>> - cleanups
>> 
>> Changes in v2:
>> 
>> - GCC warned when a variable name was re-used within a different (but overlapping)
>> scope in the same function. It also warned with a -Werror=maybe-uninitialized for
>> the MSR write case. Address those
>> - make the in-KVM enlightenments path available on Windows 11 too when -M hyperv=off.
>> 
>> Mohamed Mediouni (13):
>> target/i386: emulate: include name of unhandled instruction
>> whpx: i386: x2apic emulation
>> whpx: i386: wire up feature probing
>> whpx: i386: disable TbFlushHypercalls for emulated LAPIC
>> whpx: i386: enable x2apic by default for user-mode LAPIC
>> whpx: i386: reintroduce enlightenments for Windows 10
>> whpx: i386: introduce proper cpuid support
>> whpx: i386: kernel-irqchip=off fixes
>> whpx: i386: use WHvX64RegisterCr8 only when kernel-irqchip=off
>> whpx: i386: disable kernel-irqchip on Windows 10 when PIC enabled
>> whpx: i386: IO port fast path cleanup
>> whpx: i386: disable enlightenments and LAPIC for isapc
>> whpx: i386: interrupt priority support
>> 
>> accel/whpx/whpx-common.c       |   2 +
>> include/system/whpx-common.h   |   1 +
>> include/system/whpx-internal.h |  10 +
>> target/arm/whpx/whpx-all.c     |   1 +
>> target/i386/cpu.c              |  25 ++
>> target/i386/emulate/x86_emu.c  |   4 +-
>> target/i386/whpx/whpx-all.c    | 580 +++++++++++++++++++++++++++------
>> target/i386/whpx/whpx-i386.h   |   4 +
>> 8 files changed, 530 insertions(+), 97 deletions(-)
>> create mode 100644 target/i386/whpx/whpx-i386.h
>> 
>> -- 
>> 2.50.1 (Apple Git-155)
>> 
>