[PATCH v4 27/65] accel/hvf: Implement get_vcpu_stats()

Philippe Mathieu-Daudé posted 65 patches 4 months, 2 weeks ago
Maintainers: Richard Henderson <richard.henderson@linaro.org>, Paolo Bonzini <pbonzini@redhat.com>, Cameron Esfahani <dirty@apple.com>, Roman Bolshakov <rbolshakov@ddn.com>, Phil Dennis-Jordan <phil@philjordan.eu>, Mads Ynddal <mads@ynddal.dk>, Fabiano Rosas <farosas@suse.de>, Laurent Vivier <lvivier@redhat.com>, Stefano Stabellini <sstabellini@kernel.org>, Anthony PERARD <anthony@xenproject.org>, Paul Durrant <paul@xen.org>, "Edgar E. Iglesias" <edgar.iglesias@gmail.com>, Warner Losh <imp@bsdimp.com>, Kyle Evans <kevans@freebsd.org>, "Alex Bennée" <alex.bennee@linaro.org>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, "Dr. David Alan Gilbert" <dave@treblig.org>, Eduardo Habkost <eduardo@habkost.net>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, Yanan Wang <wangyanan55@huawei.com>, Zhao Liu <zhao1.liu@intel.com>, Reinoud Zandijk <reinoud@netbsd.org>, Sunil Muthuswamy <sunilmut@microsoft.com>, Eric Blake <eblake@redhat.com>, Markus Armbruster <armbru@redhat.com>, Michael Roth <michael.roth@amd.com>, Peter Xu <peterx@redhat.com>, David Hildenbrand <david@redhat.com>, Peter Maydell <peter.maydell@linaro.org>, Alexander Graf <agraf@csgraf.de>
There is a newer version of this series
[PATCH v4 27/65] accel/hvf: Implement get_vcpu_stats()
Posted by Philippe Mathieu-Daudé 4 months, 2 weeks ago
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 accel/hvf/hvf-accel-ops.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
index e7f40888c26..c07ebf8a652 100644
--- a/accel/hvf/hvf-accel-ops.c
+++ b/accel/hvf/hvf-accel-ops.c
@@ -358,6 +358,12 @@ static inline int hvf_gdbstub_sstep_flags(AccelState *as)
     return SSTEP_ENABLE | SSTEP_NOIRQ;
 }
 
+static void do_hvf_get_vcpu_exec_time(CPUState *cpu, run_on_cpu_data arg)
+{
+    int r = hv_vcpu_get_exec_time(cpu->accel->fd, arg.host_ptr);
+    assert_hvf_ok(r);
+}
+
 static void hvf_accel_class_init(ObjectClass *oc, const void *data)
 {
     AccelClass *ac = ACCEL_CLASS(oc);
@@ -583,6 +589,16 @@ static void hvf_remove_all_breakpoints(CPUState *cpu)
     }
 }
 
+static void hvf_get_vcpu_stats(CPUState *cpu, GString *buf)
+{
+    uint64_t time_us; /* units of mach_absolute_time() */
+
+    run_on_cpu(cpu, do_hvf_get_vcpu_exec_time, RUN_ON_CPU_HOST_PTR(&time_us));
+
+    g_string_append_printf(buf, "HVF cumulative execution time: %llu.%.3llus\n",
+                                time_us / 1000000, (time_us % 1000000) / 1000);
+}
+
 static void hvf_accel_ops_class_init(ObjectClass *oc, const void *data)
 {
     AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
@@ -601,7 +617,10 @@ static void hvf_accel_ops_class_init(ObjectClass *oc, const void *data)
     ops->remove_breakpoint = hvf_remove_breakpoint;
     ops->remove_all_breakpoints = hvf_remove_all_breakpoints;
     ops->update_guest_debug = hvf_update_guest_debug;
+
+    ops->get_vcpu_stats = hvf_get_vcpu_stats;
 };
+
 static const TypeInfo hvf_accel_ops_type = {
     .name = ACCEL_OPS_NAME("hvf"),
 
-- 
2.49.0


Re: [PATCH v4 27/65] accel/hvf: Implement get_vcpu_stats()
Posted by Mads Ynddal 4 months, 2 weeks ago
> On 2 Jul 2025, at 20.52, Philippe Mathieu-Daudé <philmd@linaro.org> wrote:
> 
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> accel/hvf/hvf-accel-ops.c | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
> 
> diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
> index e7f40888c26..c07ebf8a652 100644
> --- a/accel/hvf/hvf-accel-ops.c
> +++ b/accel/hvf/hvf-accel-ops.c
> @@ -358,6 +358,12 @@ static inline int hvf_gdbstub_sstep_flags(AccelState *as)
>     return SSTEP_ENABLE | SSTEP_NOIRQ;
> }
> 
> +static void do_hvf_get_vcpu_exec_time(CPUState *cpu, run_on_cpu_data arg)
> +{
> +    int r = hv_vcpu_get_exec_time(cpu->accel->fd, arg.host_ptr);
> +    assert_hvf_ok(r);
> +}
> +
> static void hvf_accel_class_init(ObjectClass *oc, const void *data)
> {
>     AccelClass *ac = ACCEL_CLASS(oc);
> @@ -583,6 +589,16 @@ static void hvf_remove_all_breakpoints(CPUState *cpu)
>     }
> }
> 
> +static void hvf_get_vcpu_stats(CPUState *cpu, GString *buf)
> +{
> +    uint64_t time_us; /* units of mach_absolute_time() */
> +
> +    run_on_cpu(cpu, do_hvf_get_vcpu_exec_time, RUN_ON_CPU_HOST_PTR(&time_us));
> +
> +    g_string_append_printf(buf, "HVF cumulative execution time: %llu.%.3llus\n",
> +                                time_us / 1000000, (time_us % 1000000) / 1000);
> +}
> +
> static void hvf_accel_ops_class_init(ObjectClass *oc, const void *data)
> {
>     AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
> @@ -601,7 +617,10 @@ static void hvf_accel_ops_class_init(ObjectClass *oc, const void *data)
>     ops->remove_breakpoint = hvf_remove_breakpoint;
>     ops->remove_all_breakpoints = hvf_remove_all_breakpoints;
>     ops->update_guest_debug = hvf_update_guest_debug;
> +
> +    ops->get_vcpu_stats = hvf_get_vcpu_stats;
> };
> +
> static const TypeInfo hvf_accel_ops_type = {
>     .name = ACCEL_OPS_NAME("hvf"),
> 
> -- 
> 2.49.0
> 

This doesn't return the right time for me (M3 Pro). If you tested on Intel, it might have a different time scale for mach units?

This is what I needed to change to make it work. Tested with 'yes > /dev/null' in the guest and 'info accel' in monitor.


diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
index cf623a1ea4..5b3bcd553d 100644
--- a/accel/hvf/hvf-accel-ops.c
+++ b/accel/hvf/hvf-accel-ops.c
@@ -59,6 +59,7 @@
 #include "system/hvf.h"
 #include "system/hvf_int.h"
 #include "hw/core/cpu.h"
+#include <mach/mach_time.h>

 HVFState *hvf_state;

@@ -340,12 +341,16 @@ static void hvf_remove_all_breakpoints(CPUState *cpu)

 static void hvf_get_vcpu_stats(CPUState *cpu, GString *buf)
 {
-    uint64_t time_us; /* units of mach_absolute_time() */
+    uint64_t time_mach; /* units of mach_absolute_time() */

-    run_on_cpu(cpu, do_hvf_get_vcpu_exec_time, RUN_ON_CPU_HOST_PTR(&time_us));
+    run_on_cpu(cpu, do_hvf_get_vcpu_exec_time, RUN_ON_CPU_HOST_PTR(&time_mach));
+
+    mach_timebase_info_data_t timebase;
+    mach_timebase_info(&timebase);
+    uint64_t time_ns = time_mach * timebase.numer / timebase.denom;

     g_string_append_printf(buf, "HVF cumulative execution time: %llu.%.3llus\n",
-                                time_us / 1000000, (time_us % 1000000) / 1000);
+                                time_ns / 1000000000, (time_ns % 1000000000) / 1000000);
 }

 static void hvf_accel_ops_class_init(ObjectClass *oc, const void *data)
Re: [PATCH v4 27/65] accel/hvf: Implement get_vcpu_stats()
Posted by Philippe Mathieu-Daudé 4 months, 1 week ago
On 4/7/25 14:05, Mads Ynddal wrote:
> 
>> On 2 Jul 2025, at 20.52, Philippe Mathieu-Daudé <philmd@linaro.org> wrote:
>>
>> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>> accel/hvf/hvf-accel-ops.c | 19 +++++++++++++++++++
>> 1 file changed, 19 insertions(+)
>>
>> diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
>> index e7f40888c26..c07ebf8a652 100644
>> --- a/accel/hvf/hvf-accel-ops.c
>> +++ b/accel/hvf/hvf-accel-ops.c
>> @@ -358,6 +358,12 @@ static inline int hvf_gdbstub_sstep_flags(AccelState *as)
>>      return SSTEP_ENABLE | SSTEP_NOIRQ;
>> }
>>
>> +static void do_hvf_get_vcpu_exec_time(CPUState *cpu, run_on_cpu_data arg)
>> +{
>> +    int r = hv_vcpu_get_exec_time(cpu->accel->fd, arg.host_ptr);
>> +    assert_hvf_ok(r);
>> +}
>> +
>> static void hvf_accel_class_init(ObjectClass *oc, const void *data)
>> {
>>      AccelClass *ac = ACCEL_CLASS(oc);
>> @@ -583,6 +589,16 @@ static void hvf_remove_all_breakpoints(CPUState *cpu)
>>      }
>> }
>>
>> +static void hvf_get_vcpu_stats(CPUState *cpu, GString *buf)
>> +{
>> +    uint64_t time_us; /* units of mach_absolute_time() */
>> +
>> +    run_on_cpu(cpu, do_hvf_get_vcpu_exec_time, RUN_ON_CPU_HOST_PTR(&time_us));
>> +
>> +    g_string_append_printf(buf, "HVF cumulative execution time: %llu.%.3llus\n",
>> +                                time_us / 1000000, (time_us % 1000000) / 1000);
>> +}
>> +
>> static void hvf_accel_ops_class_init(ObjectClass *oc, const void *data)
>> {
>>      AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
>> @@ -601,7 +617,10 @@ static void hvf_accel_ops_class_init(ObjectClass *oc, const void *data)
>>      ops->remove_breakpoint = hvf_remove_breakpoint;
>>      ops->remove_all_breakpoints = hvf_remove_all_breakpoints;
>>      ops->update_guest_debug = hvf_update_guest_debug;
>> +
>> +    ops->get_vcpu_stats = hvf_get_vcpu_stats;
>> };
>> +
>> static const TypeInfo hvf_accel_ops_type = {
>>      .name = ACCEL_OPS_NAME("hvf"),
>>
>> -- 
>> 2.49.0
>>
> 
> This doesn't return the right time for me (M3 Pro). If you tested on Intel, it might have a different time scale for mach units?
> 
> This is what I needed to change to make it work. Tested with 'yes > /dev/null' in the guest and 'info accel' in monitor.
> 
> 
> diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
> index cf623a1ea4..5b3bcd553d 100644
> --- a/accel/hvf/hvf-accel-ops.c
> +++ b/accel/hvf/hvf-accel-ops.c
> @@ -59,6 +59,7 @@
>   #include "system/hvf.h"
>   #include "system/hvf_int.h"
>   #include "hw/core/cpu.h"
> +#include <mach/mach_time.h>
> 
>   HVFState *hvf_state;
> 
> @@ -340,12 +341,16 @@ static void hvf_remove_all_breakpoints(CPUState *cpu)
> 
>   static void hvf_get_vcpu_stats(CPUState *cpu, GString *buf)
>   {
> -    uint64_t time_us; /* units of mach_absolute_time() */
> +    uint64_t time_mach; /* units of mach_absolute_time() */
> 
> -    run_on_cpu(cpu, do_hvf_get_vcpu_exec_time, RUN_ON_CPU_HOST_PTR(&time_us));
> +    run_on_cpu(cpu, do_hvf_get_vcpu_exec_time, RUN_ON_CPU_HOST_PTR(&time_mach));
> +
> +    mach_timebase_info_data_t timebase;
> +    mach_timebase_info(&timebase);
> +    uint64_t time_ns = time_mach * timebase.numer / timebase.denom;

Great, thank you! That works for me :)

> 
>       g_string_append_printf(buf, "HVF cumulative execution time: %llu.%.3llus\n",
> -                                time_us / 1000000, (time_us % 1000000) / 1000);
> +                                time_ns / 1000000000, (time_ns % 1000000000) / 1000000);
>   }
> 
>   static void hvf_accel_ops_class_init(ObjectClass *oc, const void *data)
> 
>