All of lore.kernel.org
 help / color / mirror / Atom feed
From: Roman Bolshakov <r.bolshakov@yadro.com>
To: <yaroshchuk2000@gmail.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	Richard Henderson <richard.henderson@linaro.org>,
	qemu-devel@nongnu.org, Cameron Esfahani <dirty@apple.com>,
	Eduardo Habkost <ehabkost@redhat.com>
Subject: Re: [PATCH v2] target/i386/hvf: add vmware-cpuid-freq cpu feature
Date: Tue, 19 Jan 2021 21:01:28 +0300	[thread overview]
Message-ID: <YAceePtQwCy8Gmwx@SPB-NB-133.local> (raw)
In-Reply-To: <20210114194703.134333-1-yaroshchuk2000@gmail.com>

On Thu, Jan 14, 2021 at 10:47:03PM +0300, yaroshchuk2000@gmail.com wrote:
> From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> 
> For `-accel hvf` cpu_x86_cpuid() is wrapped with hvf_cpu_x86_cpuid() to
> add paravirtualization cpuid leaf 0x40000010
> https://lkml.org/lkml/2008/10/1/246
> 
> Leaf 0x40000010, Timing Information:
> EAX: (Virtual) TSC frequency in kHz.
> EBX: (Virtual) Bus (local apic timer) frequency in kHz.
> ECX, EDX: RESERVED (Per above, reserved fields are set to zero).
> 
> On macOS TSC and APIC Bus frequencies can be readed by sysctl call with
> names `machdep.tsc.frequency` and `hw.busfrequency`
> 
> This options is required for Darwin-XNU guest to be synchronized with
> host
> 
> Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> ---
>  target/i386/hvf/hvf.c | 90 ++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 89 insertions(+), 1 deletion(-)
> 
> diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
> index ed9356565c..a5daafe202 100644
> --- a/target/i386/hvf/hvf.c
> +++ b/target/i386/hvf/hvf.c
> @@ -65,6 +65,7 @@
>  
>  #include <Hypervisor/hv.h>
>  #include <Hypervisor/hv_vmx.h>
> +#include <sys/sysctl.h>
>  
>  #include "exec/address-spaces.h"
>  #include "hw/i386/apic_internal.h"
> @@ -456,6 +457,48 @@ static void dummy_signal(int sig)
>  {
>  }
>  
> +static void init_tsc_freq(CPUX86State *env)
> +{
> +    size_t length;
> +    uint64_t tsc_freq;
> +
> +    if (env->tsc_khz != 0) {
> +        return;
> +    }
> +
> +    length = sizeof(uint64_t);
> +    if (sysctlbyname("machdep.tsc.frequency", &tsc_freq, &length, NULL, 0)) {
> +        return;
> +    }
> +    env->tsc_khz = tsc_freq / 1000;  /* Hz to KHz */
> +}
> +
> +static void init_apic_bus_freq(CPUX86State *env)
> +{
> +    size_t length;
> +    uint64_t bus_freq;
> +
> +    if (env->apic_bus_freq != 0) {
> +        return;
> +    }
> +
> +    length = sizeof(uint64_t);
> +    if (sysctlbyname("hw.busfrequency", &bus_freq, &length, NULL, 0)) {
> +        return;
> +    }
> +    env->apic_bus_freq = bus_freq;
> +}
> +
> +static inline bool tsc_is_known(CPUX86State *env)
> +{
> +    return env->tsc_khz != 0;
> +}
> +
> +static inline bool apic_bus_freq_is_known(CPUX86State *env)
> +{
> +    return env->apic_bus_freq != 0;
> +}
> +
>  int hvf_init_vcpu(CPUState *cpu)
>  {
>  
> @@ -480,6 +523,15 @@ int hvf_init_vcpu(CPUState *cpu)
>      hvf_state->hvf_caps = g_new0(struct hvf_vcpu_caps, 1);
>      env->hvf_mmio_buf = g_new(char, 4096);
>  
> +    if (x86cpu->vmware_cpuid_freq) {
> +        init_tsc_freq(env);
> +        init_apic_bus_freq(env);
> +
> +        if (!tsc_is_known(env) || !apic_bus_freq_is_known(env)) {
> +            error_report("vmware-cpuid-freq: feature couldn't be enabled");
> +        }
> +    }
> +
>      r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf_fd, HV_VCPU_DEFAULT);
>      cpu->vcpu_dirty = 1;
>      assert_hvf_ok(r);
> @@ -597,6 +649,42 @@ static void hvf_store_events(CPUState *cpu, uint32_t ins_len, uint64_t idtvec_in
>      }
>  }
>  
> +static void hvf_cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
> +                              uint32_t *eax, uint32_t *ebx,
> +                              uint32_t *ecx, uint32_t *edx)
> +{
> +    /*
> +     * A wrapper extends cpu_x86_cpuid with 0x40000000 and 0x40000010 leafs
> +     * Provides vmware-cpuid-freq support to hvf
> +     */
> +
> +    uint32_t signature[3];
> +
> +    if (!tsc_is_known(env) || !apic_bus_freq_is_known(env)) {
> +        cpu_x86_cpuid(env, index, count, eax, ebx, ecx, edx);
> +        return;
> +    }
> +
> +    switch (index) {
> +    case 0x40000000:
> +        memcpy(signature, "TCGTCGTCGTCG", 12); /* QEMU Signature */

Hi Vladislav,

TCG belongs to TCG accel identification, for HVF it should be
HVFHVFHVFHVF.

> +        *eax = 0x40000010;                     /* Max available cpuid leaf */
> +        *ebx = signature[0];
> +        *ecx = signature[1];
> +        *edx = signature[2];

TCG and KVM don't report their identity unless kvm or tcg-cpuid
properties are set. I wonder if we need to guard it likewise?

But as of now QEMU is not consistent in that regard. Two parameters are
needed for KVM - kvm=on,vmware-cpuid-freq=on. vmware-cpuid-freq is
sufficient for WHPX but WHPX doesn't expose itself (ebx=ecx=edx=0). TCG
doesn't seem to support vmware-cpuid-freq but reports it's name only if
tcg-cpuid property is set.

> +        break;

CPUID for not implemented hypervisor-specific leafs from 0x40000001 up
to 0x4000000f should be all zeroes but cpu_x86_cpuid() only returns zero
values for 0x40000001. Likely, you need to reset return values for the
leafs here or in cpu_x86_cpuid(). In the latter case you'll also fix a
similar bug in WHPX accel.

Otherwise, looks good.

Thanks,
Roman

> +    case 0x40000010:
> +        *eax = env->tsc_khz;
> +        *ebx = env->apic_bus_freq / 1000; /* Hz to KHz */
> +        *ecx = 0;
> +        *edx = 0;
> +        break;
> +    default:
> +        cpu_x86_cpuid(env, index, count, eax, ebx, ecx, edx);
> +        break;
> +    }
> +}
> +
>  int hvf_vcpu_exec(CPUState *cpu)
>  {
>      X86CPU *x86_cpu = X86_CPU(cpu);
> @@ -734,7 +822,7 @@ int hvf_vcpu_exec(CPUState *cpu)
>              uint32_t rcx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RCX);
>              uint32_t rdx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RDX);
>  
> -            cpu_x86_cpuid(env, rax, rcx, &rax, &rbx, &rcx, &rdx);
> +            hvf_cpu_x86_cpuid(env, rax, rcx, &rax, &rbx, &rcx, &rdx);
>  
>              wreg(cpu->hvf_fd, HV_X86_RAX, rax);
>              wreg(cpu->hvf_fd, HV_X86_RBX, rbx);
> -- 
> 2.28.0
> 


  reply	other threads:[~2021-01-19 18:44 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-13 20:52 [PATCH] target/i386/hvf: add vmware-cpuid-freq cpu feature yaroshchuk2000
2021-01-13 21:25 ` no-reply
2021-01-14 19:47 ` [PATCH v2] " yaroshchuk2000
2021-01-19 18:01   ` Roman Bolshakov [this message]
2021-01-19 18:14     ` Paolo Bonzini
2021-01-22 14:29     ` Vladislav Yaroshchuk
2021-01-19 22:37   ` dirty--- via
2021-01-22 14:51     ` Vladislav Yaroshchuk
2021-01-22 15:05   ` [PATCH v3] " yaroshchuk2000
2021-02-04  9:51     ` Roman Bolshakov
2021-02-09 10:32     ` Roman Bolshakov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YAceePtQwCy8Gmwx@SPB-NB-133.local \
    --to=r.bolshakov@yadro.com \
    --cc=dirty@apple.com \
    --cc=ehabkost@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=yaroshchuk2000@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.