target/i386/whpx/whpx-all.c | 2 -- 1 file changed, 2 deletions(-)
whpx_get_registers_for_vmexit only refreshes GPRs, RIP and RFLAGS.
x86_update_hflags() depends on state not refreshed here, while the code
using the fast runtime state does not depend on the hflags it recomputes.
Signed-off-by: Boden Randin <bodenrandin1@gmail.com>
---
Notes:
I opted to remove x86_update_hflags() in this patch instead of changing whpx_get_registers_for_vmexit to refresh the registers it requires because I couldn't find any code that depends on hflags after it calls the whpx_get_registers fast path.
Please let me know if I missed something or if maintaining the x86_update_hflags call would be preferable. This is my first open-source contribution, so please also let me know if I made any mistakes in the submission process.
target/i386/whpx/whpx-all.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index 113f79afb9..79a5256b20 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -744,8 +744,6 @@ static void whpx_get_registers_for_vmexit(CPUState *cpu, WHPXStateLevel level)
rflags_to_lflags(env);
assert(idx == RTL_NUMBER_OF(whpx_register_names_for_vmexit));
-
- x86_update_hflags(env);
}
static void whpx_get_legacy_fp_registers(CPUState *cpu, WHPXStateLevel level)
--
2.53.0.windows.1
> On 20. Sep 2026, at 04:03, Boden Randin <bodenrandin1@gmail.com> wrote:
>
> whpx_get_registers_for_vmexit only refreshes GPRs, RIP and RFLAGS.
>
> x86_update_hflags() depends on state not refreshed here, while the code
> using the fast runtime state does not depend on the hflags it recomputes.
>
> Signed-off-by: Boden Randin <bodenrandin1@gmail.com>
> ---
>
> Notes:
> I opted to remove x86_update_hflags() in this patch instead of changing whpx_get_registers_for_vmexit to refresh the registers it requires because I couldn't find any code that depends on hflags after it calls the whpx_get_registers fast path.
>
> Please let me know if I missed something or if maintaining the x86_update_hflags call would be preferable. This is my first open-source contribution, so please also let me know if I made any mistakes in the submission process.
>
> target/i386/whpx/whpx-all.c | 2 --
> 1 file changed, 2 deletions(-)
>
> diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
> index 113f79afb9..79a5256b20 100644
> --- a/target/i386/whpx/whpx-all.c
> +++ b/target/i386/whpx/whpx-all.c
> @@ -744,8 +744,6 @@ static void whpx_get_registers_for_vmexit(CPUState *cpu, WHPXStateLevel level)
> rflags_to_lflags(env);
>
> assert(idx == RTL_NUMBER_OF(whpx_register_names_for_vmexit));
> -
> - x86_update_hflags(env);
> }
Hi,
target/i386/emulate indeed doesn’t use hflags and we do a partial
register sync instead of a full one.
The purpose of not syncing all the registers needed to compute hflags
is to avoid some of them which aren’t covered by the shared register page -
thus affecting performance of MMIO accesses.
For reference these are the registers that are safe to fetch without
tanking performance as they’re part of the shared register page between the
VMM and the hypervisor as of recent Windows releases (Win11 era):
pub gp_registers: [u64; 16],
pub rip: u64,
pub rflags: u64,
pub reserved: u64,
pub xmm: [u128; 6],
pub segment: [u128; 6],
// Misc. control registers (cannot be set via this interface).
pub cr0: u64,
pub cr3: u64,
pub cr4: u64,
pub cr8: u64,
pub efer: u64,
pub dr7: u64,
pub pending_interruption: HvX64PendingInterruptionRegister,
pub interrupt_state: HvX64InterruptStateRegister,
pub instruction_emulation_hints: HvInstructionEmulatorHintsRegister,
WHP documentation doesn’t highlight this (but it is documented for
using Linux as dom0/L1VH). Fetching anything not in that list will
instantly go to the slow path of a hypercall and result in a major
MMIO performance hit.
That said, now that we’re properly rebuilding the segments from the
Hyper-V provided state instead of using TR/LDTR, it should be safe
to sync all the state required for hflagsat least for Windows 11.
For Windows 10, we’re still half as fast on some workloads than
the prior winhvemulate path so I wouldn’t be so sure...
Reviewed-by: Mohamed Mediouni <mohamed@unpredictable.fr>
>
> static void whpx_get_legacy_fp_registers(CPUState *cpu, WHPXStateLevel level)
> --
> 2.53.0.windows.1
>
© 2016 - 2026 Red Hat, Inc.