From patchwork Wed Dec 18 14:42:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Liu X-Patchwork-Id: 11300897 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 470176C1 for ; Wed, 18 Dec 2019 14:44:02 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 22D3821582 for ; Wed, 18 Dec 2019 14:44:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="eRw0xfct" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 22D3821582 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=xen.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ihaXi-0004c1-J1; Wed, 18 Dec 2019 14:43:14 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ihaXg-0004b8-Qi for xen-devel@lists.xenproject.org; Wed, 18 Dec 2019 14:43:12 +0000 X-Inumbo-ID: a555c682-21a4-11ea-a1e1-bc764e2007e4 Received: from mail-wr1-x441.google.com (unknown [2a00:1450:4864:20::441]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id a555c682-21a4-11ea-a1e1-bc764e2007e4; Wed, 18 Dec 2019 14:42:42 +0000 (UTC) Received: by mail-wr1-x441.google.com with SMTP id j42so2535911wrj.12 for ; Wed, 18 Dec 2019 06:42:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xgvjPlMwm29xJ6uZnTs5QusdsP0ROEFMExYoGH+1sMI=; b=eRw0xfctu0OTvIglKIo39rP7/4FZy6NVsz1FDtzB/lgtjIXCP1aEffr+5yFOs+HitZ cdq5/OhZ2buV2E69qSQ0fxSsNhibp/3W/oju5pZxp2XFI0XQCMGm/ZpEBPHA4jg2DuJo VKNiiN37IFQvbwNg5XYU87k7CbsYOX6Hbwham+0PEZtXV0n8YVqgCWd1XU8p6gET9ANm yLuRudGuepKvv3VtLIPg6atowxDE9zERFvOtZphX+X9HbZWaa8fWDV9tOE8PfvHrMcEu Ojqja6hF3OQjF3mdzgHKdrub7V64jrSg3GV6s7AgMCJO0i3MyjM5nw1LnaFyLA104lO3 aqPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=xgvjPlMwm29xJ6uZnTs5QusdsP0ROEFMExYoGH+1sMI=; b=ulquhfyzZLL35XgwvFay3BhNzrwaC3XFY8bc6Q98fqDdQBSUmIdCkcmJXGfR1yYmWG +GEZplp/smPP4chg5wQSPwUhvs3pPpTUTRXbf6pYwwdYGrJdZ/huSzS/VIxSSTiwNtgt YiQE5Fq7UNOrBaeKEbmePbbJUWAJSeaXiLV9ERc3LhOJnpa694zJSxAO0oKY2N6Zp51U q1t2UiB9A4HZ0GvUf6PmX4KAxEUhzLcR7oE0MkiaRn14uwgkWdfTqeJ80WFLJ7r0yIDQ SJSp8cBWA+p591ZyDh9Bwiyl5e8E2GinOb3d/JEWP+yGqwdK7iWIey5S8HXFO4JbdILu X4BA== X-Gm-Message-State: APjAAAUMy8L5CXCG98kEqTjhjl0yEQcmbeZz02EZj7lh9eD2Izcaa8xK tzR7uLaxV+3duMYY21w7I0Pk+NT8 X-Google-Smtp-Source: APXvYqyJbwfAymplFqMpaeqZPw149s7ETAp8hGHW+jXe4j29khHnTo6iluuWBtSlMpx157KOforL+A== X-Received: by 2002:a5d:5283:: with SMTP id c3mr3457407wrv.148.1576680161546; Wed, 18 Dec 2019 06:42:41 -0800 (PST) Received: from debian.mshome.net (38.163.200.146.dyn.plus.net. [146.200.163.38]) by smtp.gmail.com with ESMTPSA id p17sm2724894wmk.30.2019.12.18.06.42.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Dec 2019 06:42:41 -0800 (PST) From: Wei Liu X-Google-Original-From: Wei Liu To: Xen Development List Date: Wed, 18 Dec 2019 14:42:33 +0000 Message-Id: <20191218144233.15372-7-liuwe@microsoft.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191218144233.15372-1-liuwe@microsoft.com> References: <20191218144233.15372-1-liuwe@microsoft.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH v2 6/6] x86: implement Hyper-V clock source X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Wei Liu , Wei Liu , Andrew Cooper , Paul Durrant , Michael Kelley , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Implement a clock source using Hyper-V's reference TSC page. Signed-off-by: Wei Liu Reviewed-by: Jan Beulich --- v2: 1. Address Jan's comments. Relevant spec: https://github.com/MicrosoftDocs/Virtualization-Documentation/raw/live/tlfs/Hypervisor%20Top%20Level%20Functional%20Specification%20v5.0C.pdf Section 12.6. --- xen/arch/x86/time.c | 101 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index 216169a025..8b96b2e9a5 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -644,6 +645,103 @@ static struct platform_timesource __initdata plt_xen_timer = }; #endif +#ifdef CONFIG_HYPERV_GUEST +/************************************************************ + * HYPER-V REFERENCE TSC + */ + +static struct ms_hyperv_tsc_page *hyperv_tsc; +static struct page_info *hyperv_tsc_page; + +static int64_t __init init_hyperv_timer(struct platform_timesource *pts) +{ + paddr_t maddr; + uint64_t tsc_msr, freq; + + if ( !(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE) ) + return 0; + + hyperv_tsc_page = alloc_domheap_page(NULL, 0); + if ( !hyperv_tsc_page ) + return 0; + + hyperv_tsc = __map_domain_page_global(hyperv_tsc_page); + if ( !hyperv_tsc ) + { + free_domheap_page(hyperv_tsc_page); + hyperv_tsc_page = NULL; + return 0; + } + + maddr = page_to_maddr(hyperv_tsc_page); + + /* + * Per Hyper-V TLFS: + * 1. Read existing MSR value + * 2. Preserve bits [11:1] + * 3. Set bits [63:12] to be guest physical address of tsc page + * 4. Set enabled bit (0) + * 5. Write back new MSR value + */ + rdmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr); + tsc_msr &= 0xffeULL; + tsc_msr |= maddr | 1 /* enabled */; + wrmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr); + + /* Get TSC frequency from Hyper-V */ + rdmsrl(HV_X64_MSR_TSC_FREQUENCY, freq); + pts->frequency = freq; + + return freq; +} + +static inline uint64_t read_hyperv_timer(void) +{ + uint64_t scale, offset, ret, tsc; + uint32_t seq; + const struct ms_hyperv_tsc_page *tsc_page = hyperv_tsc; + + do { + seq = tsc_page->tsc_sequence; + + /* Seq 0 is special. It means the TSC enlightenment is not + * available at the moment. The reference time can only be + * obtained from the Reference Counter MSR. + */ + if ( seq == 0 ) + { + rdmsrl(HV_X64_MSR_TIME_REF_COUNT, ret); + return ret; + } + + /* rdtsc_ordered already contains a load fence */ + tsc = rdtsc_ordered(); + scale = tsc_page->tsc_scale; + offset = tsc_page->tsc_offset; + + smp_rmb(); + + } while (tsc_page->tsc_sequence != seq); + + /* ret = ((tsc * scale) >> 64) + offset; */ + asm ( "mul %[scale]; add %[offset], %[ret]" + : "+a" (tsc), [ret] "=d" (ret) + : [scale] "rm" (scale), [offset] "rm" (offset) ); + + return ret; +} + +static struct platform_timesource __initdata plt_hyperv_timer = +{ + .id = "hyperv", + .name = "HYPER-V REFERENCE TSC", + .read_counter = read_hyperv_timer, + .init = init_hyperv_timer, + /* See TSC time source for why counter_bits is set to 63 */ + .counter_bits = 63, +}; +#endif + /************************************************************ * GENERIC PLATFORM TIMER INFRASTRUCTURE */ @@ -793,6 +891,9 @@ static u64 __init init_platform_timer(void) static struct platform_timesource * __initdata plt_timers[] = { #ifdef CONFIG_XEN_GUEST &plt_xen_timer, +#endif +#ifdef CONFIG_HYPERV_GUEST + &plt_hyperv_timer, #endif &plt_hpet, &plt_pmtimer, &plt_pit };