[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 18/41] x86-KVM: Supply TSC and APIC clock rates to gu
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PULL 18/41] x86-KVM: Supply TSC and APIC clock rates to guest like VMWare |
Date: |
Fri, 27 Jan 2017 14:45:26 +0100 |
From: Phil Dennis-Jordan <address@hidden>
This fixes timekeeping of x86-64 Darwin/OS X/macOS guests when using KVM.
Darwin/OS X/macOS for x86-64 uses the TSC for timekeeping; it normally
calibrates this by querying various clock frequency scaling MSRs. Details
depend on the exact CPU model detected. The local APIC timer frequency is
extracted from (EFI) firmware.
This is problematic in the presence of virtualisation, as the MSRs in question
are typically not handled by the hypervisor. VMWare (Fusion) advertises TSC and
APIC frequency via a custom 0x40000010 CPUID leaf, in the eax and ebx registers
respectively. This is documented at https://lwn.net/Articles/301888/ among
other places.
Darwin/OS X/macOS looks for the generic 0x40000000 hypervisor leaf, and if this
indicates via eax that leaf 0x40000010 might be available, that is in turn
queried for the two frequencies.
This adds a CPU option "vmware-cpuid-freq" to enable the same behaviour when
running Qemu with KVM acceleration, if the KVM TSC frequency can be determined,
and it is stable. (invtsc or user-specified) The virtualised APIC bus cycle is
hardcoded to 1GHz in KVM, so ebx of the CPUID leaf is also hardcoded to this
value.
Signed-off-by: Phil Dennis-Jordan <address@hidden>
Message-Id: <address@hidden>
Signed-off-by: Paolo Bonzini <address@hidden>
---
target/i386/cpu.c | 1 +
target/i386/cpu.h | 4 ++++
target/i386/kvm.c | 36 ++++++++++++++++++++++++++++++------
3 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index aba11ae..dabad37 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -3677,6 +3677,7 @@ static Property x86_cpu_properties[] = {
DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true),
DEFINE_PROP_BOOL("lmce", X86CPU, enable_lmce, false),
DEFINE_PROP_BOOL("l3-cache", X86CPU, enable_l3_cache, true),
+ DEFINE_PROP_BOOL("vmware-cpuid-freq", X86CPU, vmware_cpuid_freq, false),
DEFINE_PROP_END_OF_LIST()
};
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 6c1902b..d51b892 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1213,6 +1213,10 @@ struct X86CPU {
bool host_features;
uint32_t apic_id;
+ /* Enables publishing of TSC increment and Local APIC bus frequencies to
+ * the guest OS in CPUID page 0x40000010, the same way that VMWare does. */
+ bool vmware_cpuid_freq;
+
/* if true the CPUID code directly forward host cache leaves to the guest
*/
bool cache_info_passthrough;
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index e6c4f75..00e9080 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -974,12 +974,6 @@ int kvm_arch_init_vcpu(CPUState *cs)
vmstate_x86_cpu.unmigratable = 1;
}
- cpuid_data.cpuid.padding = 0;
- r = kvm_vcpu_ioctl(cs, KVM_SET_CPUID2, &cpuid_data);
- if (r) {
- return r;
- }
-
r = kvm_arch_set_tsc_khz(cs);
if (r < 0) {
return r;
@@ -999,6 +993,36 @@ int kvm_arch_init_vcpu(CPUState *cs)
}
}
+ if (cpu->vmware_cpuid_freq
+ /* Guests depend on 0x40000000 to detect this feature, so only expose
+ * it if KVM exposes leaf 0x40000000. (Conflicts with Hyper-V) */
+ && cpu->expose_kvm
+ && kvm_base == KVM_CPUID_SIGNATURE
+ /* TSC clock must be stable and known for this feature. */
+ && ((env->features[FEAT_8000_0007_EDX] & CPUID_APM_INVTSC)
+ || env->user_tsc_khz != 0)
+ && env->tsc_khz != 0) {
+
+ c = &cpuid_data.entries[cpuid_i++];
+ c->function = KVM_CPUID_SIGNATURE | 0x10;
+ c->eax = env->tsc_khz;
+ /* LAPIC resolution of 1ns (freq: 1GHz) is hardcoded in KVM's
+ * APIC_BUS_CYCLE_NS */
+ c->ebx = 1000000;
+ c->ecx = c->edx = 0;
+
+ c = cpuid_find_entry(&cpuid_data.cpuid, kvm_base, 0);
+ c->eax = MAX(c->eax, KVM_CPUID_SIGNATURE | 0x10);
+ }
+
+ cpuid_data.cpuid.nent = cpuid_i;
+
+ cpuid_data.cpuid.padding = 0;
+ r = kvm_vcpu_ioctl(cs, KVM_SET_CPUID2, &cpuid_data);
+ if (r) {
+ return r;
+ }
+
if (has_xsave) {
env->kvm_xsave_buf = qemu_memalign(4096, sizeof(struct kvm_xsave));
}
--
1.8.3.1
- [Qemu-devel] [PULL 07/41] apic: save apic_delivered flag, (continued)
- [Qemu-devel] [PULL 07/41] apic: save apic_delivered flag, Paolo Bonzini, 2017/01/27
- [Qemu-devel] [PULL 08/41] memory: tune mtree_print_mr() to dump mr type, Paolo Bonzini, 2017/01/27
- [Qemu-devel] [PULL 12/41] hw/isa/lpc_ich9: negotiate SMI broadcast on pc-q35-2.9+ machine types, Paolo Bonzini, 2017/01/27
- [Qemu-devel] [PULL 11/41] hw/isa/lpc_ich9: add broadcast SMI feature, Paolo Bonzini, 2017/01/27
- [Qemu-devel] [PULL 13/41] block/iscsi: avoid data corruption with cache=writeback, Paolo Bonzini, 2017/01/27
- [Qemu-devel] [PULL 09/41] memory: hmp: add "-f" for "info mtree", Paolo Bonzini, 2017/01/27
- [Qemu-devel] [PULL 10/41] hw/isa/lpc_ich9: add SMI feature negotiation via fw_cfg, Paolo Bonzini, 2017/01/27
- [Qemu-devel] [PULL 14/41] Introduce DEVICE_CATEGORY_CPU for CPU devices, Paolo Bonzini, 2017/01/27
- [Qemu-devel] [PULL 15/41] hw/scsi: Fix debug message of cdb structure in scsi-generic, Paolo Bonzini, 2017/01/27
- [Qemu-devel] [PULL 17/41] block: get max_transfer limit for char (scsi-generic) devices, Paolo Bonzini, 2017/01/27
- [Qemu-devel] [PULL 18/41] x86-KVM: Supply TSC and APIC clock rates to guest like VMWare,
Paolo Bonzini <=
- [Qemu-devel] [PULL 16/41] block: Fix target variable of BLKSECTGET ioctl, Paolo Bonzini, 2017/01/27
- [Qemu-devel] [PULL 19/41] pc: Enable vmware-cpuid-freq CPU option for 2.9+ machine types, Paolo Bonzini, 2017/01/27
- [Qemu-devel] [PULL 23/41] char: add qemu_chr_fe_add_watch() Returns description, Paolo Bonzini, 2017/01/27
- [Qemu-devel] [PULL 20/41] block/iscsi: statically link qemu_iscsi_opts, Paolo Bonzini, 2017/01/27
- [Qemu-devel] [PULL 24/41] doc: fix spelling, Paolo Bonzini, 2017/01/27
- [Qemu-devel] [PULL 21/41] tests: fix linking test-char on win32, Paolo Bonzini, 2017/01/27
- [Qemu-devel] [PULL 26/41] char: use a static array for backends, Paolo Bonzini, 2017/01/27
- [Qemu-devel] [PULL 25/41] char: use a const CharDriver, Paolo Bonzini, 2017/01/27
- [Qemu-devel] [PULL 22/41] qemu-options: stdio is available on win32, Paolo Bonzini, 2017/01/27
- [Qemu-devel] [PULL 28/41] char: fold single-user functions in caller, Paolo Bonzini, 2017/01/27