All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: Roman Bolshakov <r.bolshakov@yadro.com>,
	Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
Subject: [PULL 16/19] target/i386/hvf: add vmware-cpuid-freq cpu feature
Date: Mon, 15 Feb 2021 14:16:23 +0100	[thread overview]
Message-ID: <20210215131626.65640-17-pbonzini@redhat.com> (raw)
In-Reply-To: <20210215131626.65640-1-pbonzini@redhat.com>

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

Leaf 0x40000000 not exposes HVF leaving hypervisor signature empty

Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
Message-Id: <20210122150518.3551-1-yaroshchuk2000@gmail.com>
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/hvf/hvf.c | 96 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 95 insertions(+), 1 deletion(-)

diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index 5b90dcdf88..10a06c3c79 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,48 @@ 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,
+     * leafs 0x40000001-0x4000000F are filled with zeros
+     * Provides vmware-cpuid-freq support to hvf
+     *
+     * Note: leaf 0x40000000 not exposes HVF,
+     * leaving hypervisor signature empty
+     */
+
+    if (index < 0x40000000 || index > 0x40000010 ||
+        !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:
+        *eax = 0x40000010;    /* Max available cpuid leaf */
+        *ebx = 0;             /* Leave signature empty */
+        *ecx = 0;
+        *edx = 0;
+        break;
+    case 0x40000010:
+        *eax = env->tsc_khz;
+        *ebx = env->apic_bus_freq / 1000; /* Hz to KHz */
+        *ecx = 0;
+        *edx = 0;
+        break;
+    default:
+        *eax = 0;
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0;
+        break;
+    }
+}
+
 int hvf_vcpu_exec(CPUState *cpu)
 {
     X86CPU *x86_cpu = X86_CPU(cpu);
@@ -734,7 +828,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.29.2




  parent reply	other threads:[~2021-02-15 13:40 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-15 13:16 [PULL 00/19] i386, qgraph patches for 2020-02-15 Paolo Bonzini
2021-02-15 13:16 ` [PULL 01/19] pc: add parser for OVMF reset block Paolo Bonzini
2021-02-15 13:16 ` [PULL 02/19] sev: update sev-inject-launch-secret to make gpa optional Paolo Bonzini
2021-05-20 21:36   ` Philippe Mathieu-Daudé
2021-05-20 22:19     ` James Bottomley
2021-05-21 11:34       ` Philippe Mathieu-Daudé
2021-02-15 13:16 ` [PULL 03/19] sev/i386: Add initial support for SEV-ES Paolo Bonzini
2021-02-15 13:16 ` [PULL 04/19] sev/i386: Require in-kernel irqchip support for SEV-ES guests Paolo Bonzini
2021-02-15 13:16 ` [PULL 05/19] sev/i386: Allow AP booting under SEV-ES Paolo Bonzini
2021-02-15 13:16 ` [PULL 06/19] sev/i386: Don't allow a system reset under an SEV-ES guest Paolo Bonzini
2021-02-15 13:16 ` [PULL 07/19] kvm/i386: Use a per-VM check for SMM capability Paolo Bonzini
2021-02-15 13:16 ` [PULL 08/19] sev/i386: Enable an SEV-ES guest based on SEV policy Paolo Bonzini
2021-02-15 13:16 ` [PULL 09/19] libqos/qgraph: add qos_node_create_driver_named() Paolo Bonzini
2021-02-15 14:06   ` Christian Schoenebeck
2021-02-18  9:10     ` Christian Schoenebeck
2021-02-18  9:14       ` Paolo Bonzini
2021-02-18  9:23         ` Christian Schoenebeck
2021-02-15 13:16 ` [PULL 10/19] libqos/qgraph_internal: add qos_printf() and qos_printf_literal() Paolo Bonzini
2021-02-15 13:16 ` [PULL 11/19] tests/qtest/qos-test: dump qos graph if verbose Paolo Bonzini
2021-02-15 13:16 ` [PULL 12/19] tests/qtest/qos-test: dump environment variables " Paolo Bonzini
2021-02-15 13:16 ` [PULL 13/19] tests/qtest/qos-test: dump QEMU command " Paolo Bonzini
2021-02-15 13:16 ` [PULL 14/19] util/cutils: Skip "." when looking for next directory component Paolo Bonzini
2021-02-15 13:16 ` [PULL 15/19] hvf: Guard xgetbv call Paolo Bonzini
2021-02-15 13:16 ` Paolo Bonzini [this message]
2021-02-15 13:16 ` [PULL 17/19] hvf: x86: Remove unused definitions Paolo Bonzini
2021-02-15 13:16 ` [PULL 18/19] target/i386/hvf: add rdmsr 35H MSR_CORE_THREAD_COUNT Paolo Bonzini
2021-02-15 13:16 ` [PULL 19/19] hvf: Fetch cr4 before evaluating CPUID(1) Paolo Bonzini
2021-02-15 13:29 ` [PULL 00/19] i386, qgraph patches for 2020-02-15 Thomas Huth
2021-02-15 13:30 ` Philippe Mathieu-Daudé
2021-02-15 13:43 ` no-reply
2021-02-15 21:13 ` Eric Blake
2021-02-16 14:13   ` Peter Maydell

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=20210215131626.65640-17-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=r.bolshakov@yadro.com \
    --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.