All of lore.kernel.org
 help / color / mirror / Atom feed
From: yaroshchuk2000@gmail.com
To: qemu-devel@nongnu.org
Cc: qemu-trivial@nongnu.org, r.bolshakov@yadro.com,
	Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
Subject: [PATCH] target/i386/hvf: add vmware-cpuid-freq cpu feature
Date: Wed, 13 Jan 2021 23:52:21 +0300	[thread overview]
Message-ID: <20210113205221.32308-1-yaroshchuk2000@gmail.com> (raw)

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 | 92 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 91 insertions(+), 1 deletion(-)

diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index ed9356565c..0873e4969e 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,50 @@ 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)) {
+        /* fprintf(stderr, "%s: sysctl machdep.tsc.frequency errored\n", __func__); */
+        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)) {
+        /* fprintf(stderr, "%s: sysctl hw.busfrequency errored\n", __func__); */
+        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 +525,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 +651,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 */
+            *eax = 0x40000010;                     /* Max available cpuid leaf */
+            *ebx = signature[0];
+            *ecx = signature[1];
+            *edx = signature[2];
+            break;
+        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 +824,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-13 21:18 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-13 20:52 yaroshchuk2000 [this message]
2021-01-13 21:25 ` [PATCH] target/i386/hvf: add vmware-cpuid-freq cpu feature no-reply
2021-01-13 21:25   ` no-reply
2021-01-14 19:47 ` [PATCH v2] " yaroshchuk2000
2021-01-19 18:01   ` Roman Bolshakov
2021-01-19 18:14     ` Paolo Bonzini
2021-01-22 14:29     ` Vladislav Yaroshchuk
2021-01-22 14:29       ` Vladislav Yaroshchuk
2021-01-19 22:37   ` Cameron Esfahani
2021-01-19 22:37     ` dirty--- via
2021-01-22 14:51     ` Vladislav Yaroshchuk
2021-01-22 14:51       ` Vladislav Yaroshchuk
2021-01-22 15:05   ` [PATCH v3] " yaroshchuk2000
2021-01-22 15:05     ` yaroshchuk2000
2021-02-04  9:51     ` Roman Bolshakov
2021-02-04  9:51       ` Roman Bolshakov
2021-02-09 10:32     ` 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=20210113205221.32308-1-yaroshchuk2000@gmail.com \
    --to=yaroshchuk2000@gmail.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-trivial@nongnu.org \
    --cc=r.bolshakov@yadro.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.