[PATCH v3 14/14] whpx: i386: saving/restoring less state for WHPX_LEVEL_FAST_RUNTIME_STATE

Mohamed Mediouni posted 14 patches 1 month, 3 weeks ago
Maintainers: Pedro Barbuda <pbarbuda@microsoft.com>, Mohamed Mediouni <mohamed@unpredictable.fr>, Paolo Bonzini <pbonzini@redhat.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, "Daniel P. Berrangé" <berrange@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Peter Maydell <peter.maydell@linaro.org>, Zhao Liu <zhao1.liu@intel.com>, Cameron Esfahani <dirty@apple.com>, Roman Bolshakov <rbolshakov@ddn.com>, Phil Dennis-Jordan <phil@philjordan.eu>, Wei Liu <wei.liu@kernel.org>, Magnus Kulke <magnus.kulke@linux.microsoft.com>
There is a newer version of this series
[PATCH v3 14/14] whpx: i386: saving/restoring less state for WHPX_LEVEL_FAST_RUNTIME_STATE
Posted by Mohamed Mediouni 1 month, 3 weeks ago
Optimise vmexits by save/restoring less state in those cases instead of the full state.

Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
---
 target/i386/whpx/whpx-all.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index 7bbe63e794..9d1febce52 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -420,6 +420,13 @@ void whpx_set_registers(CPUState *cpu, WHPXStateLevel level)
         vcxt.values[idx].Segment = whpx_seg_q2h(&env->segs[i], v86, r86);
     }
 
+    /*
+     * This is a hot path called on every MMIO access.
+     */
+    if (level <= WHPX_LEVEL_FAST_RUNTIME_STATE) {
+        goto skip_to_set_registers;
+    }
+
     assert(idx == WHvX64RegisterLdtr);
     vcxt.values[idx++].Segment = whpx_seg_q2h(&env->ldt, 0, 0);
 
@@ -529,10 +536,11 @@ void whpx_set_registers(CPUState *cpu, WHPXStateLevel level)
 
     assert(idx == RTL_NUMBER_OF(whpx_register_names));
 
+    skip_to_set_registers:
     hr = whp_dispatch.WHvSetVirtualProcessorRegisters(
         whpx->partition, cpu->cpu_index,
         whpx_register_names,
-        RTL_NUMBER_OF(whpx_register_names),
+        idx,
         &vcxt.values[0]);
 
     if (FAILED(hr)) {
@@ -612,7 +620,7 @@ void whpx_get_registers(CPUState *cpu, WHPXStateLevel level)
                      hr);
     }
 
-    if (whpx_irqchip_in_kernel()) {
+    if (level > WHPX_LEVEL_FAST_RUNTIME_STATE && whpx_irqchip_in_kernel()) {
         /*
          * Fetch the TPR value from the emulated APIC. It may get overwritten
          * below with the value from CR8 returned by
@@ -668,7 +676,7 @@ void whpx_get_registers(CPUState *cpu, WHPXStateLevel level)
     env->cr[4] = vcxt.values[idx++].Reg64;
     assert(whpx_register_names[idx] == WHvX64RegisterCr8);
     tpr = vcxt.values[idx++].Reg64;
-    if (tpr != vcpu->tpr) {
+    if (level > WHPX_LEVEL_FAST_RUNTIME_STATE && tpr != vcpu->tpr) {
         vcpu->tpr = tpr;
         cpu_set_apic_tpr(x86_cpu->apic_state, whpx_cr8_to_apic_tpr(tpr));
     }
@@ -754,7 +762,7 @@ void whpx_get_registers(CPUState *cpu, WHPXStateLevel level)
 
     assert(idx == RTL_NUMBER_OF(whpx_register_names));
 
-    if (whpx_irqchip_in_kernel()) {
+    if (level > WHPX_LEVEL_FAST_RUNTIME_STATE && whpx_irqchip_in_kernel()) {
         whpx_apic_get(x86_cpu->apic_state);
     }
 
-- 
2.50.1 (Apple Git-155)
Re: [PATCH v3 14/14] whpx: i386: saving/restoring less state for WHPX_LEVEL_FAST_RUNTIME_STATE
Posted by Bernhard Beschow 1 month, 3 weeks ago

Am 15. Februar 2026 05:22:25 UTC schrieb Mohamed Mediouni <mohamed@unpredictable.fr>:
>Optimise vmexits by save/restoring less state in those cases instead of the full state.
>
>Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
>---
> target/i386/whpx/whpx-all.c | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
>
>diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
>index 7bbe63e794..9d1febce52 100644
>--- a/target/i386/whpx/whpx-all.c
>+++ b/target/i386/whpx/whpx-all.c
>@@ -420,6 +420,13 @@ void whpx_set_registers(CPUState *cpu, WHPXStateLevel level)
>         vcxt.values[idx].Segment = whpx_seg_q2h(&env->segs[i], v86, r86);
>     }
> 
>+    /*
>+     * This is a hot path called on every MMIO access.
>+     */
>+    if (level <= WHPX_LEVEL_FAST_RUNTIME_STATE) {
>+        goto skip_to_set_registers;
>+    }

Looks like we can get rid of the goto by extending the scope of the if statement to the skip_to_set_registers label.

With this fixed:

Reviewed-by: Bernhard Beschow <shentey@gmail.com>

>+
>     assert(idx == WHvX64RegisterLdtr);
>     vcxt.values[idx++].Segment = whpx_seg_q2h(&env->ldt, 0, 0);
> 
>@@ -529,10 +536,11 @@ void whpx_set_registers(CPUState *cpu, WHPXStateLevel level)
> 
>     assert(idx == RTL_NUMBER_OF(whpx_register_names));
> 
>+    skip_to_set_registers:
>     hr = whp_dispatch.WHvSetVirtualProcessorRegisters(
>         whpx->partition, cpu->cpu_index,
>         whpx_register_names,
>-        RTL_NUMBER_OF(whpx_register_names),
>+        idx,
>         &vcxt.values[0]);
> 
>     if (FAILED(hr)) {
>@@ -612,7 +620,7 @@ void whpx_get_registers(CPUState *cpu, WHPXStateLevel level)
>                      hr);
>     }
> 
>-    if (whpx_irqchip_in_kernel()) {
>+    if (level > WHPX_LEVEL_FAST_RUNTIME_STATE && whpx_irqchip_in_kernel()) {
>         /*
>          * Fetch the TPR value from the emulated APIC. It may get overwritten
>          * below with the value from CR8 returned by
>@@ -668,7 +676,7 @@ void whpx_get_registers(CPUState *cpu, WHPXStateLevel level)
>     env->cr[4] = vcxt.values[idx++].Reg64;
>     assert(whpx_register_names[idx] == WHvX64RegisterCr8);
>     tpr = vcxt.values[idx++].Reg64;
>-    if (tpr != vcpu->tpr) {
>+    if (level > WHPX_LEVEL_FAST_RUNTIME_STATE && tpr != vcpu->tpr) {
>         vcpu->tpr = tpr;
>         cpu_set_apic_tpr(x86_cpu->apic_state, whpx_cr8_to_apic_tpr(tpr));
>     }
>@@ -754,7 +762,7 @@ void whpx_get_registers(CPUState *cpu, WHPXStateLevel level)
> 
>     assert(idx == RTL_NUMBER_OF(whpx_register_names));
> 
>-    if (whpx_irqchip_in_kernel()) {
>+    if (level > WHPX_LEVEL_FAST_RUNTIME_STATE && whpx_irqchip_in_kernel()) {
>         whpx_apic_get(x86_cpu->apic_state);
>     }
>