From patchwork Fri Jan 20 12:20:27 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Tosatti X-Patchwork-Id: 9528197 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 7764960459 for ; Fri, 20 Jan 2017 12:28:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 67C2B28616 for ; Fri, 20 Jan 2017 12:28:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5A0D828639; Fri, 20 Jan 2017 12:28:12 +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.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable 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 E350928616 for ; Fri, 20 Jan 2017 12:28:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751976AbdATM1t (ORCPT ); Fri, 20 Jan 2017 07:27:49 -0500 Received: from mx1.redhat.com ([209.132.183.28]:36016 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751961AbdATM1p (ORCPT ); Fri, 20 Jan 2017 07:27:45 -0500 Received: from smtp.corp.redhat.com (int-mx16.intmail.prod.int.phx2.redhat.com [10.5.11.28]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0869485542; Fri, 20 Jan 2017 12:27:46 +0000 (UTC) Received: from amt.cnet (vpn1-4-171.gru2.redhat.com [10.97.4.171]) by smtp.corp.redhat.com (Postfix) with ESMTP id 679E01D85E0; Fri, 20 Jan 2017 12:27:42 +0000 (UTC) Received: from amt.cnet (localhost [127.0.0.1]) by amt.cnet (Postfix) with ESMTP id 80FE9100900; Fri, 20 Jan 2017 10:27:06 -0200 (BRST) Received: (from marcelo@localhost) by amt.cnet (8.14.7/8.14.7/Submit) id v0KCR6IQ020183; Fri, 20 Jan 2017 10:27:06 -0200 Message-Id: <20170120122503.579583520@redhat.com> User-Agent: quilt/0.60-1 Date: Fri, 20 Jan 2017 10:20:27 -0200 From: Marcelo Tosatti To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Paolo Bonzini , Radim Krcmar , Richard Cochran , Miroslav Lichvar , Marcelo Tosatti Subject: [patch 2/5] KVM: x86: add KVM_HC_CLOCK_OFFSET hypercall References: <20170120122025.665985919@redhat.com> Content-Disposition: inline; filename=kvm-hv-clock-offset X-Scanned-By: MIMEDefang 2.74 on 10.5.11.28 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Fri, 20 Jan 2017 12:27:46 +0000 (UTC) Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add a hypercall to retrieve the host realtime clock and the TSC value used to calculate that clock read. Used to implement clock synchronization between host and guest. Signed-off-by: Marcelo Tosatti --- Documentation/virtual/kvm/hypercalls.txt | 33 ++++++++++++++++++++++++ arch/x86/include/uapi/asm/kvm_para.h | 9 ++++++ arch/x86/kvm/x86.c | 41 +++++++++++++++++++++++++++++++ include/uapi/linux/kvm_para.h | 3 ++ 4 files changed, 86 insertions(+) v2: improve documentation (Radim) change hypercall name to KVM_HC_CLOCK_PAIRING (Radim) increase padding size -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Index: kvm-ptpdriver/arch/x86/include/uapi/asm/kvm_para.h =================================================================== --- kvm-ptpdriver.orig/arch/x86/include/uapi/asm/kvm_para.h 2017-01-13 16:43:11.947240575 -0200 +++ kvm-ptpdriver/arch/x86/include/uapi/asm/kvm_para.h 2017-01-13 16:43:25.038258187 -0200 @@ -50,6 +50,15 @@ __u32 pad[11]; }; +#define KVM_CLOCK_PAIRING_WALLCLOCK 0 +struct kvm_clock_offset { + __s64 sec; + __s64 nsec; + __u64 tsc; + __u32 flags; + __u32 pad[9]; +}; + #define KVM_STEAL_ALIGNMENT_BITS 5 #define KVM_STEAL_VALID_BITS ((-1ULL << (KVM_STEAL_ALIGNMENT_BITS + 1))) #define KVM_STEAL_RESERVED_MASK (((1 << KVM_STEAL_ALIGNMENT_BITS) - 1 ) << 1) Index: kvm-ptpdriver/Documentation/virtual/kvm/hypercalls.txt =================================================================== --- kvm-ptpdriver.orig/Documentation/virtual/kvm/hypercalls.txt 2017-01-13 16:43:11.947240575 -0200 +++ kvm-ptpdriver/Documentation/virtual/kvm/hypercalls.txt 2017-01-13 16:43:25.038258187 -0200 @@ -81,3 +81,36 @@ same guest can wakeup the sleeping vcpu by issuing KVM_HC_KICK_CPU hypercall, specifying APIC ID (a1) of the vcpu to be woken up. An additional argument (a0) is used in the hypercall for future use. + + +6. KVM_HC_CLOCK_PAIRING +------------------------ +Architecture: x86 +Status: active +Purpose: Hypercall used to synchronize host and guest clocks. +Usage: + +a0: guest physical address where host copies +"struct kvm_clock_offset" structure. + +a1: clock_type, ATM only KVM_CLOCK_PAIRING_WALLCLOCK (0) +is supported (hosts CLOCK_REALTIME clock). + + struct kvm_clock_offset { + __s64 sec; + __s64 nsec; + __u64 tsc; + __u32 flags; + __u32 pad[9]; + }; + + Where: + * sec: seconds from clock_type clock. + * nsec: nanoseconds from clock_type clock. + * tsc: TSC value used to calculate sec/nsec pair + (this hypercall only works when host uses TSC clocksource). + * flags: flags, unused (0) at the moment. + +Returns KVM_EOPNOTSUPP if the host does not use TSC clocksource, +or if clock type is different than KVM_CLOCK_PAIRING_WALLCLOCK. + Index: kvm-ptpdriver/arch/x86/kvm/x86.c =================================================================== --- kvm-ptpdriver.orig/arch/x86/kvm/x86.c 2017-01-13 16:43:20.898252596 -0200 +++ kvm-ptpdriver/arch/x86/kvm/x86.c 2017-01-13 16:43:25.041258191 -0200 @@ -6119,6 +6119,44 @@ } EXPORT_SYMBOL_GPL(kvm_emulate_halt); +static int kvm_pv_clock_pairing(struct kvm_vcpu *vcpu, gpa_t paddr, + unsigned long clock_type) +{ + struct kvm_clock_offset *clock_offset; + struct timespec ts; + cycle_t cycle; + int ret; + + if (clock_type != KVM_CLOCK_PAIRING_WALLCLOCK) + return -KVM_EOPNOTSUPP; + + if (pvclock_gtod_data.clock.vclock_mode != VCLOCK_TSC) + return -KVM_EOPNOTSUPP; + + clock_offset = kzalloc(sizeof(struct kvm_clock_offset), GFP_KERNEL); + if (clock_offset == NULL) + return -KVM_ENOMEM; + + if (kvm_get_walltime_and_clockread(&ts, &cycle) == false) { + kfree(clock_offset); + return -KVM_EOPNOTSUPP; + } + + clock_offset->sec = ts.tv_sec; + clock_offset->nsec = ts.tv_nsec; + clock_offset->tsc = kvm_read_l1_tsc(vcpu, cycle); + clock_offset->flags = 0; + + ret = 0; + if (kvm_write_guest(vcpu->kvm, paddr, clock_offset, + sizeof(struct kvm_clock_offset))) + ret = -KVM_EFAULT; + + kfree(clock_offset); + + return ret; +} + /* * kvm_pv_kick_cpu_op: Kick a vcpu. * @@ -6183,6 +6221,9 @@ kvm_pv_kick_cpu_op(vcpu->kvm, a0, a1); ret = 0; break; + case KVM_HC_CLOCK_PAIRING: + ret = kvm_pv_clock_pairing(vcpu, a0, a1); + break; default: ret = -KVM_ENOSYS; break; Index: kvm-ptpdriver/include/uapi/linux/kvm_para.h =================================================================== --- kvm-ptpdriver.orig/include/uapi/linux/kvm_para.h 2017-01-13 16:43:11.947240575 -0200 +++ kvm-ptpdriver/include/uapi/linux/kvm_para.h 2017-01-13 16:43:25.042258192 -0200 @@ -14,6 +14,8 @@ #define KVM_EFAULT EFAULT #define KVM_E2BIG E2BIG #define KVM_EPERM EPERM +#define KVM_EOPNOTSUPP EOPNOTSUPP +#define KVM_ENOMEM ENOMEM #define KVM_HC_VAPIC_POLL_IRQ 1 #define KVM_HC_MMU_OP 2 @@ -23,6 +25,7 @@ #define KVM_HC_MIPS_GET_CLOCK_FREQ 6 #define KVM_HC_MIPS_EXIT_VM 7 #define KVM_HC_MIPS_CONSOLE_OUTPUT 8 +#define KVM_HC_CLOCK_PAIRING 9 /* * hypercalls use architecture specific