From patchwork Mon Jun 12 13:30:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhoujian (jay)" X-Patchwork-Id: 9781085 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 9F76460352 for ; Mon, 12 Jun 2017 13:32:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 893A228609 for ; Mon, 12 Jun 2017 13:32:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7E33328616; Mon, 12 Jun 2017 13:32:02 +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 lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D773728609 for ; Mon, 12 Jun 2017 13:32:01 +0000 (UTC) Received: from localhost ([::1]:38104 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dKPRo-0003aB-DW for patchwork-qemu-devel@patchwork.kernel.org; Mon, 12 Jun 2017 09:32:00 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34995) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dKPR5-0003Zd-Fv for qemu-devel@nongnu.org; Mon, 12 Jun 2017 09:31:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dKPR2-0002Nh-Ba for qemu-devel@nongnu.org; Mon, 12 Jun 2017 09:31:15 -0400 Received: from szxga03-in.huawei.com ([45.249.212.189]:3892) by eggs.gnu.org with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.71) (envelope-from ) id 1dKPR1-0002N6-Oa for qemu-devel@nongnu.org; Mon, 12 Jun 2017 09:31:12 -0400 Received: from 172.30.72.54 (EHLO DGGEML402-HUB.china.huawei.com) ([172.30.72.54]) by dggrg03-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id APG31752; Mon, 12 Jun 2017 21:31:07 +0800 (CST) Received: from localhost (10.177.19.14) by DGGEML402-HUB.china.huawei.com (10.3.17.38) with Microsoft SMTP Server id 14.3.301.0; Mon, 12 Jun 2017 21:30:56 +0800 From: Jay Zhou To: Date: Mon, 12 Jun 2017 21:30:51 +0800 Message-ID: <1497274251-26448-1-git-send-email-jianjay.zhou@huawei.com> X-Mailer: git-send-email 2.6.1.windows.1 MIME-Version: 1.0 X-Originating-IP: [10.177.19.14] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A0B0201.593E979C.018A, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: a6119bf8c6f0a720d56d64ce2cb7d3c9 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] [fuzzy] X-Received-From: 45.249.212.189 Subject: [Qemu-devel] [PATCH RFC] migration: kvmclock: save and load the PVCLOCK_TSC_UNSTABLE_BIT flag when migration X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: wangxinxin.wang@huawei.com, arei.gonglei@huawei.com, weidong.huang@huawei.com, kvm@vger.kernel.org, Jay Zhou Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Guest using kvmclock will be hanged when migrating from unstable tsc host to stable tsc host occasionally. Sometimes, the tsc timestamp saved at the source side will be backward when the guest stopped, and this value is transferred to the destination side. The guest at the destination side thought kvmclock is stable, so the protection mechanism against time going backwards is not used. When the first time vcpu0 enters the guest at the destination side to update the wall clock, the result of pvclock_clocksource_read will be backward occasionally, which results in the wall clock drift. Signed-off-by: Jay Zhou --- hw/i386/kvm/clock.c | 12 ++++++++++-- linux-headers/asm-x86/kvm.h | 2 ++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c index 13eca37..fcc4f62 100644 --- a/hw/i386/kvm/clock.c +++ b/hw/i386/kvm/clock.c @@ -29,6 +29,7 @@ #define TYPE_KVM_CLOCK "kvmclock" #define KVM_CLOCK(obj) OBJECT_CHECK(KVMClockState, (obj), TYPE_KVM_CLOCK) +#define PVCLOCK_TSC_STABLE_BIT (1 << 0) typedef struct KVMClockState { /*< private >*/ @@ -57,7 +58,7 @@ struct pvclock_vcpu_time_info { uint8_t pad[2]; } __attribute__((__packed__)); /* 32 bytes */ -static uint64_t kvmclock_current_nsec(KVMClockState *s) +static uint64_t kvmclock_current_nsec(KVMClockState *s, uint8_t *flags) { CPUState *cpu = first_cpu; CPUX86State *env = cpu->env_ptr; @@ -77,6 +78,7 @@ static uint64_t kvmclock_current_nsec(KVMClockState *s) cpu_physical_memory_read(kvmclock_struct_pa, &time, sizeof(time)); assert(time.tsc_timestamp <= migration_tsc); + *flags = time.flags; delta = migration_tsc - time.tsc_timestamp; if (time.tsc_shift < 0) { delta >>= -time.tsc_shift; @@ -153,16 +155,22 @@ static void kvmclock_vm_state_change(void *opaque, int running, if (running) { struct kvm_clock_data data = {}; + uint8_t flags_at_migration; /* * If the host where s->clock was read did not support reliable * KVM_GET_CLOCK, read kvmclock value from memory. */ if (!s->clock_is_reliable) { - uint64_t pvclock_via_mem = kvmclock_current_nsec(s); + uint64_t pvclock_via_mem = kvmclock_current_nsec(s, + &flags_at_migration); /* We can't rely on the saved clock value, just discard it */ if (pvclock_via_mem) { s->clock = pvclock_via_mem; + /* whether src kvmclock has PVCLOCK_TSC_STABLE_BIT flag */ + if (!(flags_at_migration & PVCLOCK_TSC_STABLE_BIT)) { + data.flags |= MIGRATION_PVCLOCK_TSC_UNSTABLE_BIT; + } } } diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h index c2824d0..9faed3e 100644 --- a/linux-headers/asm-x86/kvm.h +++ b/linux-headers/asm-x86/kvm.h @@ -360,4 +360,6 @@ struct kvm_sync_regs { #define KVM_X86_QUIRK_LINT0_REENABLED (1 << 0) #define KVM_X86_QUIRK_CD_NW_CLEARED (1 << 1) +#define MIGRATION_PVCLOCK_TSC_UNSTABLE_BIT (1 << 0) + #endif /* _ASM_X86_KVM_H */