Received: by 10.223.164.202 with SMTP id h10csp1563499wrb; Wed, 15 Nov 2017 23:51:55 -0800 (PST) X-Google-Smtp-Source: AGs4zMaxb+uUpEMAKCXfhSrnjNg/Pbo+JOY6tXPnAOhaPe8ecV67VKfR+DKJB5ExnG4LMUn9/Ewm X-Received: by 10.101.66.70 with SMTP id d6mr798981pgq.395.1510818715694; Wed, 15 Nov 2017 23:51:55 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510818715; cv=none; d=google.com; s=arc-20160816; b=p5qkJ//5Fflyi+l9qiCqq4o///SfAnGpZiKHJ4BBL0O6TjjfqUukIlJpQIv3iiI0z0 ElIMmcSC43Zau94DazbhLPNTEML64k2qEmHRbzz90jBomEM2OBBhfMXJTHRNc/1TAzDd A3WjnPGMtYNjSj1a3PokfY+QKowDOi8rQjlhSRtH/PknPK8enrXYaGQnynncORMx2hHz HTbktvxQAol+z538kP+5EULeq2dDcAdOhAiMBgig8e09xVT6e4aeBO+ULtdr4keiXcIk rf5yMzZGcUU31fJNA5JCnfyCP9qd4yEYcHNs09GzlNdKMkpOKw4duz4s9XQI4bEYZp8V UYyA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=G9IZwYhUYdZLMVCrTQ4NAHNIKVig7gBOllH37S8viZw=; b=xSueb74zNYzyrcQ8pObEaqNFyNV9GNb1niFsH94KpNw6nKi813C0TptDJJm2OHVQ29 urIoFF/o+X8ExTfUvYtRj+LF1neSdJV5Dpbem8SvPzDrRBJSBrcv2hfuN9OIPZbtrxNg MxGSmnCMx2/slmZnBRpX48HpcZwj/rKI3hVns89V0VBO5BBj0gziBc7FM708k0/D7WnG X/PsbIYepWug2s0raUfGXOyxcBI0c2fsdl+J/v56n/SBuUhc1qqcc1fpX0QxZqZbU0R1 Zfsyv7vbCHgkh/WYuVV2nuE5XvWn4VvhaaImgr7S4AaaIHLrlvd3aiqqALIlgHt4+lr0 mZiA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m37si449066plg.275.2017.11.15.23.51.42; Wed, 15 Nov 2017 23:51:55 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933515AbdKPHsc (ORCPT + 91 others); Thu, 16 Nov 2017 02:48:32 -0500 Received: from goliath.siemens.de ([192.35.17.28]:60479 "EHLO goliath.siemens.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759400AbdKPHrx (ORCPT ); Thu, 16 Nov 2017 02:47:53 -0500 Received: from mail1.siemens.de (mail1.siemens.de [139.23.33.14]) by goliath.siemens.de (8.15.2/8.15.2) with ESMTPS id vAG7Qtmc008237 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 16 Nov 2017 08:26:55 +0100 Received: from md1f2u6c.ww002.siemens.net ([167.87.32.158]) by mail1.siemens.de (8.15.2/8.15.2) with ESMTP id vAG7QrlU029336; Thu, 16 Nov 2017 08:26:55 +0100 From: Jan Kiszka To: Thomas Gleixner , Ingo Molnar , "H . Peter Anvin" Cc: x86@kernel.org, Linux Kernel Mailing List , jailhouse-dev@googlegroups.com Subject: [PATCH 05/10] x86: jailhouse: Set up timekeeping Date: Thu, 16 Nov 2017 08:26:47 +0100 Message-Id: <62f3fde8db44e5aedf934b5a753d448979f50082.1510817211.git.jan.kiszka@siemens.com> X-Mailer: git-send-email 2.12.3 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jan Kiszka Calibrate the TSC and, where necessary, the APIC timer against the TMTIMER. We need our own implementation as neither the PIC nor the HPET are available, and the standard calibration routines try to make use of them. Signed-off-by: Jan Kiszka --- arch/x86/include/asm/tsc.h | 3 ++ arch/x86/kernel/jailhouse.c | 82 +++++++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/tsc.c | 14 ++++---- 3 files changed, 92 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h index cf5d53c3f9ea..be92e0c8ac17 100644 --- a/arch/x86/include/asm/tsc.h +++ b/arch/x86/include/asm/tsc.h @@ -71,4 +71,7 @@ extern void tsc_restore_sched_clock_state(void); unsigned long cpu_khz_from_msr(void); +u64 tsc_read_refs(u64 *ref, int hpet); +unsigned long tsc_calc_pmtimer_ref(u64 deltatsc, u64 pm1, u64 pm2); + #endif /* _ASM_X86_TSC_H */ diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index f7e99f7a8873..8e5b2f0c8a34 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -50,6 +50,83 @@ static uint32_t __init jailhouse_detect(void) return jailhouse_cpuid_base(); } +#define MAX_RETRIES 5 +#define SMI_TRESHOLD 50000 + +static unsigned long apic_timer_access(u64 *pmt, bool setup) +{ + unsigned long ret = 0; + unsigned int n; + u64 t1, t2; + + for (n = 0; n < MAX_RETRIES; n++) { + t1 = get_cycles(); + *pmt = acpi_pm_read_early(); + if (setup) + apic_write(APIC_TMICT, 0xffffffff); + else + ret = apic_read(APIC_TMCCT); + t2 = get_cycles(); + + if ((t2 - t1) < SMI_TRESHOLD * 2) + return ret; + } + + panic("Jailhouse: SMI disturbed APIC timer calibration"); +} + +static void jailhouse_timer_init(void) +{ + u64 divided_apic_freq; + unsigned long tmr; + u64 start, end; + + if (boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) + return; + + apic_write(APIC_LVTT, APIC_LVT_MASKED); + apic_write(APIC_TDCR, APIC_TDR_DIV_16); + + apic_timer_access(&start, true); + while ((acpi_pm_read_early() - start) < 100000) + cpu_relax(); + tmr = apic_timer_access(&end, false); + + divided_apic_freq = + tsc_calc_pmtimer_ref((0xffffffffU - tmr) * 1000000, start, end); + + lapic_timer_frequency = divided_apic_freq * 16; + apic_write(APIC_TMICT, 0); +} + +static unsigned long jailhouse_calibrate_cpu(void) +{ + u64 tsc1, tsc2, pm1, pm2; + unsigned long flags; + + local_irq_save(flags); + + tsc1 = tsc_read_refs(&pm1, 0); + while ((get_cycles() - tsc1) < 50000000) + cpu_relax(); + tsc2 = tsc_read_refs(&pm2, 0); + + local_irq_restore(flags); + + /* Check, whether the sampling succeeded (SMI?) */ + if (tsc1 == ULLONG_MAX || tsc2 == ULLONG_MAX) { + pr_err("Jailhouse: TSC calibration against PMTIMER failed\n"); + return 0; + } + + return tsc_calc_pmtimer_ref((tsc2 - tsc1) * 1000000, pm1, pm2); +} + +static unsigned long jailhouse_calibrate_tsc(void) +{ + return 0; +} + static unsigned int x2apic_get_apic_id(unsigned long id) { return id; @@ -61,6 +138,11 @@ static void __init jailhouse_init_platform(void) struct jailhouse_setup_data *data; unsigned int cpu; + x86_init.timers.timer_init = jailhouse_timer_init; + + x86_platform.calibrate_cpu = jailhouse_calibrate_cpu; + x86_platform.calibrate_tsc = jailhouse_calibrate_tsc; + data = early_memremap(pa_data, sizeof(*data)); if (data->header.type != SETUP_JAILHOUSE || diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 8ea117f8142e..a61000cc4f21 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -286,7 +286,7 @@ __setup("tsc=", tsc_setup); /* * Read TSC and the reference counters. Take care of SMI disturbance */ -static u64 tsc_read_refs(u64 *p, int hpet) +u64 tsc_read_refs(u64 *p, int hpet) { u64 t1, t2; int i; @@ -307,7 +307,7 @@ static u64 tsc_read_refs(u64 *p, int hpet) /* * Calculate the TSC frequency from HPET reference */ -static unsigned long calc_hpet_ref(u64 deltatsc, u64 hpet1, u64 hpet2) +static unsigned long tsc_calc_hpet_ref(u64 deltatsc, u64 hpet1, u64 hpet2) { u64 tmp; @@ -324,7 +324,7 @@ static unsigned long calc_hpet_ref(u64 deltatsc, u64 hpet1, u64 hpet2) /* * Calculate the TSC frequency from PMTimer reference */ -static unsigned long calc_pmtimer_ref(u64 deltatsc, u64 pm1, u64 pm2) +unsigned long tsc_calc_pmtimer_ref(u64 deltatsc, u64 pm1, u64 pm2) { u64 tmp; @@ -728,9 +728,9 @@ unsigned long native_calibrate_cpu(void) tsc2 = (tsc2 - tsc1) * 1000000LL; if (hpet) - tsc2 = calc_hpet_ref(tsc2, ref1, ref2); + tsc2 = tsc_calc_hpet_ref(tsc2, ref1, ref2); else - tsc2 = calc_pmtimer_ref(tsc2, ref1, ref2); + tsc2 = tsc_calc_pmtimer_ref(tsc2, ref1, ref2); tsc_ref_min = min(tsc_ref_min, (unsigned long) tsc2); @@ -1200,9 +1200,9 @@ static void tsc_refine_calibration_work(struct work_struct *work) delta = tsc_stop - tsc_start; delta *= 1000000LL; if (hpet) - freq = calc_hpet_ref(delta, ref_start, ref_stop); + freq = tsc_calc_hpet_ref(delta, ref_start, ref_stop); else - freq = calc_pmtimer_ref(delta, ref_start, ref_stop); + freq = tsc_calc_pmtimer_ref(delta, ref_start, ref_stop); /* Make sure we're within 1% */ if (abs(tsc_khz - freq) > tsc_khz/100) -- 2.12.3 From 1584897069097293453@xxx Thu Nov 23 22:20:28 +0000 2017 X-GM-THRID: 1584897069097293453 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread