From patchwork Fri Jan 20 14:11:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Dennis-Jordan X-Patchwork-Id: 9528555 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BB2E660434 for ; Fri, 20 Jan 2017 14:12:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AC4CC28684 for ; Fri, 20 Jan 2017 14:12:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A10A028687; Fri, 20 Jan 2017 14:12:17 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 040DE28684 for ; Fri, 20 Jan 2017 14:12:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752294AbdATOMN (ORCPT ); Fri, 20 Jan 2017 09:12:13 -0500 Received: from mail-wm0-f65.google.com ([74.125.82.65]:32982 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752106AbdATOML (ORCPT ); Fri, 20 Jan 2017 09:12:11 -0500 Received: by mail-wm0-f65.google.com with SMTP id r144so7034708wme.0 for ; Fri, 20 Jan 2017 06:12:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=philjordan-eu.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=eBR913wYdFG1lSf451xQMHHOVii+97OyBmd1OF8zQqs=; b=OHTfF8Tp7vE8FRJOYCYEyJMS8dyjLKw6KGrRz/MFbtoXNeoXfI9ySjZySinuTRw6WA 3ZrQxhc7bJVzgkVXB+AyShUpqz8j8k3wVsxCH9vJFl0M4PcD8vc8DzWEK/Qws8lXRU6b hceRtcOOtKlzeHNGC0RPgF4EC0vMJ8vUYXms7IvE1EDH5F/hQ6PUsmdnF+gfi4BcXYEA vhSBhkFwwO8EZS59ZRvC2bBgfqFxRfXxAaEcSS2YnMV0BdX7Wu6CL/F6krKCmewbeFOS ckUCTyavgXs+scbjin0Pxe5+9Z/I3dOtRlC5bh9iJfZIrrZpXaispiRzZ1cpJI9epDkZ QsLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=eBR913wYdFG1lSf451xQMHHOVii+97OyBmd1OF8zQqs=; b=jFxN82sQmx7h6FoUlO/2uBvqaTeozAIjisafEJuWI/M2Y1y+r7tLJkZ/t9LpzcB5xT WEulCigqhs+JRMAymL8oDw6ZO2tF+24fnRQs3Xgytg4CPz82TGa5YXJwrRYsFh2Jo1CI RAdKqLejD4ZeQ2n/1yel92yxp74bmwPy8A38GDwS6dmmZIwrItkzjVlYOZmqoFMO5SPB pTRI5S216pkjJ0cGSdOm+GzbXtqtJHW+Qzjzh50lMMnb0KooS6OxEAa2ie4+HEgLkS7z mEYKAgd23lB3AiAV3C8EqAdIIKzIWaWpNevGkr/XUJ+VY/rM0OcJYBqcKi8TSoVPpnEr 3hmg== X-Gm-Message-State: AIkVDXKMhZFumllOQaCFK2A4Wt3QZGTlAWNABSb9oOyW1qrzaEePI3GotppPB5n134YLpw== X-Received: by 10.28.189.134 with SMTP id n128mr3332958wmf.77.1484921524881; Fri, 20 Jan 2017 06:12:04 -0800 (PST) Received: from Phils-MacBook-Pro-57025.local.eu (37-186-10-86.ip.as39912.net. [37.186.10.86]) by smtp.gmail.com with ESMTPSA id 191sm6339827wmo.21.2017.01.20.06.12.03 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 20 Jan 2017 06:12:04 -0800 (PST) From: Phil Dennis-Jordan To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Richard Henderson , Eduardo Habkost , Marcelo Tosatti , "Michael S. Tsirkin" , kvm@vger.kernel.org, Phil Dennis-Jordan Subject: [PATCH v2 1/3] x86-KVM: Supply TSC and APIC clock rates to guest like VMWare Date: Fri, 20 Jan 2017 15:11:34 +0100 Message-Id: <1484921496-11257-2-git-send-email-phil@philjordan.eu> X-Mailer: git-send-email 2.3.2 (Apple Git-55) In-Reply-To: <1484921496-11257-1-git-send-email-phil@philjordan.eu> References: <1484921496-11257-1-git-send-email-phil@philjordan.eu> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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 10a9cd8..6854e76 100644 --- a/target/i386/kvm.c +++ b/target/i386/kvm.c @@ -973,12 +973,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; @@ -998,6 +992,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)); }