From patchwork Thu Apr 21 13:29:35 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Stabellini X-Patchwork-Id: 8900761 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 48C6F9F457 for ; Thu, 21 Apr 2016 13:32:11 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6B75E202DD for ; Thu, 21 Apr 2016 13:32:10 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 752372026F for ; Thu, 21 Apr 2016 13:32:09 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1atEg9-0002cU-Bp; Thu, 21 Apr 2016 13:29:57 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1atEg7-0002cK-TT for xen-devel@lists.xenproject.org; Thu, 21 Apr 2016 13:29:56 +0000 Received: from [85.158.139.211] by server-15.bemta-5.messagelabs.com id 4A/0B-04147-3D5D8175; Thu, 21 Apr 2016 13:29:55 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprLIsWRWlGSWpSXmKPExsVybKJsh+6lqxL hBh2PDSy+b5nM5MDocfjDFZYAxijWzLyk/IoE1owJq56zFryVqJjR+52tgfGfcBcjF4eQwFRG idlvXjF3MXICOZ1MEo/fyoPYLALaEqduvGUHsdkEDCX+PtnE1sXIwSEBZC/5zAESFhFQkri3a jITiM0s4CGx9eQJNhBbWMBe4lPjdLBWXgFviWOd7WBxUQFdiUP//rBBxAUlTs58wgLRqyWxfP o2MFtCIENiXs8cVgjbS2LRjUtQtprE1XObmCcw8s9C0j4LSfsCRqZVjBrFqUVlqUW6hoZ6SUW Z6RkluYmZObqGBqZ6uanFxYnpqTmJScV6yfm5mxiBwcYABDsYV7Y7H2KU5GBSEuWN3CMRLsSX lJ9SmZFYnBFfVJqTWnyIUYaDQ0mCt/oKUE6wKDU9tSItMwcY9jBpCQ4eJRHetSBp3uKCxNziz HSI1ClGRSlx3q0gCQGQREZpHlwbLNYuMcpKCfMyAh0ixFOQWpSbWYIq/4pRnINRSZh3PsgUns y8Erjpr4AWMwEt5r8rCrK4JBEhJdXA2LLj2ev5V3WmXV7YPkk93uam86uUMiuhqR7y2x6vXzZ l268H/Zucrz2X+f8jUn/WIvF0oQQekbNMrg37XZRb7tQ1RDHdaZu0T+vjq7cm6ozZnffNPzt7 Gs/0rdv+VPDIdP2dRsdvHcsoXT77aFEg8yHDlXfiXubuFXvD0cxXVJQkuWvGk3cpKkosxRmJh lrMRcWJAA7HCY2wAgAA X-Env-Sender: sstabellini@kernel.org X-Msg-Ref: server-5.tower-206.messagelabs.com!1461245393!35777841!1 X-Originating-IP: [198.145.29.136] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 8.28; banners=-,-,- X-VirusChecked: Checked Received: (qmail 45336 invoked from network); 21 Apr 2016 13:29:54 -0000 Received: from mail.kernel.org (HELO mail.kernel.org) (198.145.29.136) by server-5.tower-206.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 21 Apr 2016 13:29:54 -0000 Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D3C472026F; Thu, 21 Apr 2016 13:29:51 +0000 (UTC) Received: from [10.0.0.5] (107.238.189.80.dyn.plus.net [80.189.238.107]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 3F4E42025A; Thu, 21 Apr 2016 13:29:50 +0000 (UTC) Date: Thu, 21 Apr 2016 14:29:35 +0100 (BST) From: Stefano Stabellini X-X-Sender: sstabellini@sstabellini-ThinkPad-X260 To: xen-devel@lists.xenproject.org Message-ID: User-Agent: Alpine 2.10 (DEB 1266 2009-07-14) MIME-Version: 1.0 X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Cc: andrew.cooper3@citrix.com, sstabellini@kernel.org, jbeulich@suse.com Subject: [Xen-devel] [PATCH] xen/time: fix system_time for vtsc=1 PV guests X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP For vtsc=1 PV guests, rdtsc is trapped and calculated from get_s_time() using gtime_to_gtsc. Similarly the tsc_timestamp, part of struct vcpu_time_info, is calculated from stime_local_stamp using gtime_to_gtsc. However gtime_to_gtsc can return 0, if time < vtsc_offset, which can actually happen when gtime_to_gtsc is called passing stime_local_stamp (the caller function is __update_vcpu_system_time). In that case the pvclock protocol doesn't work properly and the guest is unable to calculate the system time correctly. As a consequence when the guest tries to set a timer event (for example calling the VCPUOP_set_singleshot_timer hypercall), the event will be in the past causing Linux to hang. The purpose of the pvclock protocol is to allow the guest to calculate the system_time in nanosec correctly. The guest calculates as follow: from_vtsc_scale(rdtsc - vcpu_time_info.tsc_timestamp) + vcpu_time_info.system_time Given that with vtsc=1: rdtsc = to_vtsc_scale(NOW() - vtsc_offset) vcpu_time_info.tsc_timestamp = to_vtsc_scale(vcpu_time_info.system_time - vtsc_offset) The expression evaluates to NOW(), which is what we want. However when stime_local_stamp < vtsc_offset, vcpu_time_info.tsc_timestamp is actually 0, because it cannot be negative (the field is uint64_t). As a consequence the calculated overall system_time is not correct. This patch fixes the issue by passing vtsc_offset as system_time when vcpu_time_info.tsc_timestamp is 0: rdtsc = to_vtsc_scale(NOW() - vtsc_offset) vcpu_time_info.tsc_timestamp = 0 vcpu_time_info.system_time = vtsc_offset The pvclock expression evaluates to NOW(), which is what we want. Signed-off-by: Stefano Stabellini diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index 687e39b..27b0e5c 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -784,7 +784,7 @@ static void __update_vcpu_system_time(struct vcpu *v, int force) struct cpu_time *t; struct vcpu_time_info *u, _u = {}; struct domain *d = v->domain; - s_time_t tsc_stamp; + s_time_t stime_stamp, tsc_stamp = 0; if ( v->vcpu_info == NULL ) return; @@ -792,6 +792,7 @@ static void __update_vcpu_system_time(struct vcpu *v, int force) t = &this_cpu(cpu_time); u = &vcpu_info(v, time); + stime_stamp = t->stime_local_stamp; if ( d->arch.vtsc ) { s_time_t stime = t->stime_local_stamp; @@ -807,7 +808,11 @@ static void __update_vcpu_system_time(struct vcpu *v, int force) tsc_stamp = -gtime_to_gtsc(d, -stime); } else + { tsc_stamp = gtime_to_gtsc(d, stime); + if (!tsc_stamp) + stime_stamp = d->arch.vtsc_offset; + } _u.tsc_to_system_mul = d->arch.vtsc_to_ns.mul_frac; _u.tsc_shift = d->arch.vtsc_to_ns.shift; @@ -829,7 +834,7 @@ static void __update_vcpu_system_time(struct vcpu *v, int force) } _u.tsc_timestamp = tsc_stamp; - _u.system_time = t->stime_local_stamp; + _u.system_time = stime_stamp; if ( is_hvm_domain(d) ) _u.tsc_timestamp += v->arch.hvm_vcpu.cache_tsc_offset;