[PATCH v2 10/10] whpx: x86: optimise MMIO vmexit by only restoring needed registers

Mohamed Mediouni posted 10 patches 1 month, 4 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 v2 10/10] whpx: x86: optimise MMIO vmexit by only restoring needed registers
Posted by Mohamed Mediouni 1 month, 4 weeks ago
Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
---
 include/system/whpx-accel-ops.h |  8 +++++---
 target/i386/whpx/whpx-all.c     | 12 ++++++++++--
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/include/system/whpx-accel-ops.h b/include/system/whpx-accel-ops.h
index ed9d4c49f4..469a3a4350 100644
--- a/include/system/whpx-accel-ops.h
+++ b/include/system/whpx-accel-ops.h
@@ -22,11 +22,13 @@ void whpx_cpu_synchronize_post_reset(CPUState *cpu);
 void whpx_cpu_synchronize_post_init(CPUState *cpu);
 void whpx_cpu_synchronize_pre_loadvm(CPUState *cpu);
 
+/* subset of runtime state for faster returns from vmexit */
+#define WHPX_SET_FAST_RUNTIME_STATE   1
 /* state subset only touched by the VCPU itself during runtime */
-#define WHPX_SET_RUNTIME_STATE   1
+#define WHPX_SET_RUNTIME_STATE   2
 /* state subset modified during VCPU reset */
-#define WHPX_SET_RESET_STATE     2
+#define WHPX_SET_RESET_STATE     3
 /* full state set, modified during initialization or on vmload */
-#define WHPX_SET_FULL_STATE      3
+#define WHPX_SET_FULL_STATE      4
 
 #endif /* TARGET_I386_WHPX_ACCEL_OPS_H */
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index 0e8fb0e72e..61251a2835 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, int 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_SET_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, int 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)) {
@@ -771,7 +779,7 @@ static int emulate_instruction(CPUState *cpu, const uint8_t *insn_bytes, size_t
     whpx_get_registers(cpu);
     decode_instruction_stream(env, &decode, &stream);
     exec_instruction(env, &decode);
-    whpx_set_registers(cpu, WHPX_SET_RUNTIME_STATE);
+    whpx_set_registers(cpu, WHPX_SET_FAST_RUNTIME_STATE);
 
     return 0;
 }
-- 
2.50.1 (Apple Git-155)
Re: [PATCH v2 10/10] whpx: x86: optimise MMIO vmexit by only restoring needed registers
Posted by Philippe Mathieu-Daudé 1 month, 3 weeks ago
On 13/2/26 04:45, Mohamed Mediouni wrote:
> Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
> ---
>   include/system/whpx-accel-ops.h |  8 +++++---
>   target/i386/whpx/whpx-all.c     | 12 ++++++++++--
>   2 files changed, 15 insertions(+), 5 deletions(-)
> 
> diff --git a/include/system/whpx-accel-ops.h b/include/system/whpx-accel-ops.h
> index ed9d4c49f4..469a3a4350 100644
> --- a/include/system/whpx-accel-ops.h
> +++ b/include/system/whpx-accel-ops.h
> @@ -22,11 +22,13 @@ void whpx_cpu_synchronize_post_reset(CPUState *cpu);
>   void whpx_cpu_synchronize_post_init(CPUState *cpu);
>   void whpx_cpu_synchronize_pre_loadvm(CPUState *cpu);
>   
> +/* subset of runtime state for faster returns from vmexit */
> +#define WHPX_SET_FAST_RUNTIME_STATE   1
>   /* state subset only touched by the VCPU itself during runtime */
> -#define WHPX_SET_RUNTIME_STATE   1
> +#define WHPX_SET_RUNTIME_STATE   2
>   /* state subset modified during VCPU reset */
> -#define WHPX_SET_RESET_STATE     2
> +#define WHPX_SET_RESET_STATE     3
>   /* full state set, modified during initialization or on vmload */
> -#define WHPX_SET_FULL_STATE      3
> +#define WHPX_SET_FULL_STATE      4

Could we make this an enum used by whpx_set_registers() @level argument?

Otherwise,
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>