* [PATCH] target/i386/hvf: add vmware-cpuid-freq cpu feature
@ 2021-01-13 20:52 yaroshchuk2000
2021-01-13 21:25 ` no-reply
2021-01-14 19:47 ` [PATCH v2] " yaroshchuk2000
0 siblings, 2 replies; 11+ messages in thread
From: yaroshchuk2000 @ 2021-01-13 20:52 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-trivial, r.bolshakov, Vladislav Yaroshchuk
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
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] target/i386/hvf: add vmware-cpuid-freq cpu feature
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
1 sibling, 0 replies; 11+ messages in thread
From: no-reply @ 2021-01-13 21:25 UTC (permalink / raw)
To: yaroshchuk2000; +Cc: qemu-trivial, r.bolshakov, qemu-devel, yaroshchuk2000
Patchew URL: https://patchew.org/QEMU/20210113205221.32308-1-yaroshchuk2000@gmail.com/
Hi,
This series seems to have some coding style problems. See output below for
more information:
Type: series
Message-id: 20210113205221.32308-1-yaroshchuk2000@gmail.com
Subject: [PATCH] target/i386/hvf: add vmware-cpuid-freq cpu feature
=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
f4f6e29 target/i386/hvf: add vmware-cpuid-freq cpu feature
=== OUTPUT BEGIN ===
WARNING: line over 80 characters
#52: FILE: target/i386/hvf/hvf.c:471:
+ /* fprintf(stderr, "%s: sysctl machdep.tsc.frequency errored\n", __func__); */
ERROR: switch and case should be at the same indent
#124: FILE: target/i386/hvf/hvf.c:670:
+ switch (index) {
+ case 0x40000000:
[...]
+ case 0x40000010:
[...]
+ default:
WARNING: line over 80 characters
#127: FILE: target/i386/hvf/hvf.c:673:
+ *eax = 0x40000010; /* Max available cpuid leaf */
total: 1 errors, 2 warnings, 122 lines checked
Commit f4f6e29c5d8c (target/i386/hvf: add vmware-cpuid-freq cpu feature) has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===
Test command exited with code: 1
The full log is available at
http://patchew.org/logs/20210113205221.32308-1-yaroshchuk2000@gmail.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2] target/i386/hvf: add vmware-cpuid-freq cpu feature
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 ` yaroshchuk2000
2021-01-19 18:01 ` Roman Bolshakov
` (2 more replies)
1 sibling, 3 replies; 11+ messages in thread
From: yaroshchuk2000 @ 2021-01-14 19:47 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-trivial, r.bolshakov, Vladislav Yaroshchuk
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 */
+ *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 +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
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2] target/i386/hvf: add vmware-cpuid-freq cpu feature
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-19 22:37 ` dirty--- via
2021-01-22 15:05 ` [PATCH v3] " yaroshchuk2000
2 siblings, 2 replies; 11+ messages in thread
From: Roman Bolshakov @ 2021-01-19 18:01 UTC (permalink / raw)
To: yaroshchuk2000
Cc: Paolo Bonzini, Richard Henderson, qemu-devel, Cameron Esfahani,
Eduardo Habkost
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
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2] target/i386/hvf: add vmware-cpuid-freq cpu feature
2021-01-19 18:01 ` Roman Bolshakov
@ 2021-01-19 18:14 ` Paolo Bonzini
2021-01-22 14:29 ` Vladislav Yaroshchuk
1 sibling, 0 replies; 11+ messages in thread
From: Paolo Bonzini @ 2021-01-19 18:14 UTC (permalink / raw)
To: Roman Bolshakov, yaroshchuk2000
Cc: Richard Henderson, qemu-devel, Cameron Esfahani, Eduardo Habkost
On 19/01/21 19:01, Roman Bolshakov wrote:
>> + switch (index) {
>> + case 0x40000000:
>> + memcpy(signature, "TCGTCGTCGTCG", 12); /* QEMU Signature */
> Hi Vladislav,
>
> TCG belongs to TCG accel identification, for HVF it should be
> HVFHVFHVFHVF.
You can use the KVM identification just fine, as long as you comply with
the rest of the KVM CPUID specification.
Paolo
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2] target/i386/hvf: add vmware-cpuid-freq cpu feature
2021-01-14 19:47 ` [PATCH v2] " yaroshchuk2000
2021-01-19 18:01 ` Roman Bolshakov
@ 2021-01-19 22:37 ` dirty--- via
2021-01-22 14:51 ` Vladislav Yaroshchuk
2021-01-22 15:05 ` [PATCH v3] " yaroshchuk2000
2 siblings, 1 reply; 11+ messages in thread
From: dirty--- via @ 2021-01-19 22:37 UTC (permalink / raw)
To: yaroshchuk2000; +Cc: qemu-trivial, r.bolshakov, qemu-devel
> On Jan 14, 2021, at 11:47 AM, 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
> }
> }
>
We already have hvf/x86_cpuid.c. Can we put hvf_cpu_x86_cpuid() in there?
> +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 */
I agree with Roman, using "HVFHVFHVFHVF" is better.
> + *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 +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
>
>
Looks good.
Cameron Esfahani
dirty@apple.com
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2] target/i386/hvf: add vmware-cpuid-freq cpu feature
2021-01-19 18:01 ` Roman Bolshakov
2021-01-19 18:14 ` Paolo Bonzini
@ 2021-01-22 14:29 ` Vladislav Yaroshchuk
1 sibling, 0 replies; 11+ messages in thread
From: Vladislav Yaroshchuk @ 2021-01-22 14:29 UTC (permalink / raw)
To: Roman Bolshakov; +Cc: qemu-trivial, pbonzini, qemu-devel, dirty
[-- Attachment #1: Type: text/plain, Size: 6760 bytes --]
Hi Roman,
вт, 19 янв. 2021 г. в 21:01, Roman Bolshakov <r.bolshakov@yadro.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.
>
>
Ok, I understood the mistake. HVFHVFHVFHVF sounds more suitable, but
hypervisor signature is not a necessary thing for vmware-cpuid-freq
(especially unknown to anyone `HVFHVFHVFHVF`). Seems it can be dropped
by filling ebx=ecx=edx=0, as WHPX does. No reason to expose the HVF in
this case. If needed, it can be added as another feature.
> + 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.
>
>
I'll fix it in-place, resetting values in hvf_cpu_x86_cpuid()
Thank you for the review!
Sincerely,
Vladislav Yaroshchuk
> 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
> >
>
[-- Attachment #2: Type: text/html, Size: 9266 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2] target/i386/hvf: add vmware-cpuid-freq cpu feature
2021-01-19 22:37 ` dirty--- via
@ 2021-01-22 14:51 ` Vladislav Yaroshchuk
0 siblings, 0 replies; 11+ messages in thread
From: Vladislav Yaroshchuk @ 2021-01-22 14:51 UTC (permalink / raw)
To: Cameron Esfahani; +Cc: qemu-trivial, pbonzini, Roman Bolshakov, qemu-devel
[-- Attachment #1: Type: text/plain, Size: 5792 bytes --]
Hi Cameron,
ср, 20 янв. 2021 г. в 01:37, Cameron Esfahani <dirty@apple.com>:
>
>
> > On Jan 14, 2021, at 11:47 AM, 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
> > }
> > }
> >
>
> Seems that
> We already have hvf/x86_cpuid.c. Can we put hvf_cpu_x86_cpuid() in there?
>
> hvf/x86_cpuid.c is about host features, hvf_cpu_x86_cpuid() does not fit
it, as for me.
Also, KVM extends cpuid in target/i386/kvm/kvm.c. Same to WHPX:
target/i386/whpx/whpx-all.c.
I wanted to meet this rule: target/i386/hvf/hvf.c
Thank you!
Vladislav Yaroshchuk
> +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 */
>
> I agree with Roman, using "HVFHVFHVFHVF" is better.
>
> > + *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 +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
> >
> >
>
> Looks good.
>
> Cameron Esfahani
> dirty@apple.com
>
>
[-- Attachment #2: Type: text/html, Size: 8070 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v3] target/i386/hvf: add vmware-cpuid-freq cpu feature
2021-01-14 19:47 ` [PATCH v2] " yaroshchuk2000
2021-01-19 18:01 ` Roman Bolshakov
2021-01-19 22:37 ` dirty--- via
@ 2021-01-22 15:05 ` yaroshchuk2000
2021-02-04 9:51 ` Roman Bolshakov
2021-02-09 10:32 ` Roman Bolshakov
2 siblings, 2 replies; 11+ messages in thread
From: yaroshchuk2000 @ 2021-01-22 15:05 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-trivial, pbonzini, r.bolshakov, Vladislav Yaroshchuk, dirty
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>
---
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 ed9356565c..5a8914564b 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.23.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v3] target/i386/hvf: add vmware-cpuid-freq cpu feature
2021-01-22 15:05 ` [PATCH v3] " yaroshchuk2000
@ 2021-02-04 9:51 ` Roman Bolshakov
2021-02-09 10:32 ` Roman Bolshakov
1 sibling, 0 replies; 11+ messages in thread
From: Roman Bolshakov @ 2021-02-04 9:51 UTC (permalink / raw)
To: yaroshchuk2000; +Cc: qemu-trivial, pbonzini, qemu-devel, dirty
On Fri, Jan 22, 2021 at 06:05:18PM +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
>
> Leaf 0x40000000 not exposes HVF leaving hypervisor signature empty
>
> Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> ---
> target/i386/hvf/hvf.c | 96 ++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 95 insertions(+), 1 deletion(-)
>
I'd prefer to have generic expose-accel option for CPU and
vmware-cpuid-freq=on would depend on expose-accel=on.
Regardless of that,
Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>
Tested-by: Roman Bolshakov <r.bolshakov@yadro.com>
Thanks,
Roman
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3] target/i386/hvf: add vmware-cpuid-freq cpu feature
2021-01-22 15:05 ` [PATCH v3] " yaroshchuk2000
2021-02-04 9:51 ` Roman Bolshakov
@ 2021-02-09 10:32 ` Roman Bolshakov
1 sibling, 0 replies; 11+ messages in thread
From: Roman Bolshakov @ 2021-02-09 10:32 UTC (permalink / raw)
To: yaroshchuk2000; +Cc: qemu-trivial, pbonzini, qemu-devel, dirty
On Fri, Jan 22, 2021 at 06:05:18PM +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
>
> Leaf 0x40000000 not exposes HVF leaving hypervisor signature empty
>
> Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
> ---
> target/i386/hvf/hvf.c | 96 ++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 95 insertions(+), 1 deletion(-)
>
Queued, thanks!
-Roman
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2021-02-09 10:33 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
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
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.