From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: x86 team <x86@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
Peter Zijlstra <peterz@infradead.org>,
Arjan van de Veen <arjan@infradead.org>,
Avi Kivity <avi@redhat.com>,
Jeremy Fitzhardinge <jeremy@goop.org>,
Rusty Russell <rusty@rustcorp.com.au>,
Alok N Kataria <akataria@vmware.com>,
Pan Jacob jun <jacob.jun.pan@intel.com>
Subject: [RFC patch 30/32] x86: Move tsc_calibration to platform
Date: Fri, 21 Aug 2009 21:32:12 -0000 [thread overview]
Message-ID: <20090821205603.267985525@linutronix.de> (raw)
In-Reply-To: 20090821205008.518392436@linutronix.de
[-- Attachment #1: x86-move-tsc-calibration-to-platform.patch --]
[-- Type: text/plain, Size: 12940 bytes --]
TSC calibration is modified by the vmware hypervisor and paravirt by
separate means. Moorestown wants to add its own calibration routine as
well. So make calibrate_tsc a proper platform function and override it
by paravirt or by the early setup of the vmware hypervisor.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/hypervisor.h | 2 +-
arch/x86/include/asm/paravirt.h | 2 --
arch/x86/include/asm/platform.h | 2 ++
arch/x86/include/asm/timer.h | 5 -----
arch/x86/include/asm/tsc.h | 3 ++-
arch/x86/include/asm/vmware.h | 2 +-
arch/x86/kernel/cpu/hypervisor.c | 14 +++++++-------
arch/x86/kernel/cpu/vmware.c | 35 +++++++++++++++++++----------------
arch/x86/kernel/kvmclock.c | 2 +-
arch/x86/kernel/paravirt.c | 1 -
arch/x86/kernel/platform_setup.c | 2 ++
arch/x86/kernel/setup.c | 2 +-
arch/x86/kernel/tsc.c | 10 ++--------
arch/x86/kernel/vmi_32.c | 2 +-
arch/x86/kernel/vmiclock_32.c | 2 +-
arch/x86/lguest/boot.c | 2 +-
arch/x86/xen/enlighten.c | 2 +-
17 files changed, 42 insertions(+), 48 deletions(-)
Index: linux-2.6/arch/x86/include/asm/hypervisor.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/hypervisor.h
+++ linux-2.6/arch/x86/include/asm/hypervisor.h
@@ -20,7 +20,7 @@
#ifndef ASM_X86__HYPERVISOR_H
#define ASM_X86__HYPERVISOR_H
-extern unsigned long get_hypervisor_tsc_freq(void);
extern void init_hypervisor(struct cpuinfo_x86 *c);
+extern void init_hypervisor_platform(void);
#endif
Index: linux-2.6/arch/x86/include/asm/paravirt.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/paravirt.h
+++ linux-2.6/arch/x86/include/asm/paravirt.h
@@ -103,7 +103,6 @@ struct pv_time_ops {
int (*set_wallclock)(unsigned long);
unsigned long long (*sched_clock)(void);
- unsigned long (*get_tsc_khz)(void);
};
struct pv_cpu_ops {
@@ -867,7 +866,6 @@ static inline unsigned long long paravir
{
return PVOP_CALL0(unsigned long long, pv_time_ops.sched_clock);
}
-#define calibrate_tsc() (pv_time_ops.get_tsc_khz())
static inline unsigned long long paravirt_read_pmc(int counter)
{
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -90,11 +90,13 @@ struct platform_setup_paging {
* boot cpu
* @tsc_pre_init: platform function called before TSC init
* @timer_init: initialize the platform timer (default PIT/HPET)
+ * @calibrate_tsc: calibrate TSC
*/
struct platform_setup_timers {
void (*setup_percpu_clockev)(void);
void (*tsc_pre_init)(void);
void (*timer_init)(void);
+ unsigned long (*calibrate_tsc)(void);
};
/**
Index: linux-2.6/arch/x86/include/asm/timer.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/timer.h
+++ linux-2.6/arch/x86/include/asm/timer.h
@@ -8,7 +8,6 @@
#define TICK_SIZE (tick_nsec / 1000)
unsigned long long native_sched_clock(void);
-unsigned long native_calibrate_tsc(void);
extern int recalibrate_cpu_khz(void);
#if defined(CONFIG_X86_32) && defined(CONFIG_X86_IO_APIC)
@@ -19,10 +18,6 @@ extern int timer_ack;
extern int no_timer_check;
-#ifndef CONFIG_PARAVIRT
-#define calibrate_tsc() native_calibrate_tsc()
-#endif
-
/* Accelerators for sched_clock()
* convert from cycles(64bits) => nanoseconds (64bits)
* basic equation:
Index: linux-2.6/arch/x86/include/asm/tsc.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/tsc.h
+++ linux-2.6/arch/x86/include/asm/tsc.h
@@ -48,7 +48,8 @@ static __always_inline cycles_t vget_cyc
extern void tsc_init(void);
extern void mark_tsc_unstable(char *reason);
extern int unsynchronized_tsc(void);
-int check_tsc_unstable(void);
+extern int check_tsc_unstable(void);
+extern unsigned long native_calibrate_tsc(void);
/*
* Boot-time check whether the TSCs are synchronized across
Index: linux-2.6/arch/x86/include/asm/vmware.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/vmware.h
+++ linux-2.6/arch/x86/include/asm/vmware.h
@@ -20,7 +20,7 @@
#ifndef ASM_X86__VMWARE_H
#define ASM_X86__VMWARE_H
-extern unsigned long vmware_get_tsc_khz(void);
+extern void vmware_platform_setup(void);
extern int vmware_platform(void);
extern void vmware_set_feature_bits(struct cpuinfo_x86 *c);
Index: linux-2.6/arch/x86/kernel/cpu/hypervisor.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/hypervisor.c
+++ linux-2.6/arch/x86/kernel/cpu/hypervisor.c
@@ -35,13 +35,6 @@ detect_hypervisor_vendor(struct cpuinfo_
}
}
-unsigned long get_hypervisor_tsc_freq(void)
-{
- if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE)
- return vmware_get_tsc_khz();
- return 0;
-}
-
static inline void __cpuinit
hypervisor_set_feature_bits(struct cpuinfo_x86 *c)
{
@@ -56,3 +49,10 @@ void __cpuinit init_hypervisor(struct cp
detect_hypervisor_vendor(c);
hypervisor_set_feature_bits(c);
}
+
+void __init init_hypervisor_platform(void)
+{
+ init_hypervisor(&boot_cpu_data);
+ if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE)
+ vmware_platform_setup();
+}
Index: linux-2.6/arch/x86/kernel/cpu/vmware.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/vmware.c
+++ linux-2.6/arch/x86/kernel/cpu/vmware.c
@@ -24,6 +24,7 @@
#include <linux/dmi.h>
#include <asm/div64.h>
#include <asm/vmware.h>
+#include <asm/platform.h>
#define CPUID_VMWARE_INFO_LEAF 0x40000000
#define VMWARE_HYPERVISOR_MAGIC 0x564D5868
@@ -47,19 +48,27 @@ static inline int __vmware_platform(void
return eax != (uint32_t)-1 && ebx == VMWARE_HYPERVISOR_MAGIC;
}
-static unsigned long __vmware_get_tsc_khz(void)
+static unsigned long vmware_get_tsc_khz(void)
{
- uint64_t tsc_hz;
- uint32_t eax, ebx, ecx, edx;
+ uint64_t tsc_hz;
+ uint32_t eax, ebx, ecx, edx;
+
+ VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
+
+ tsc_hz = eax | (((uint64_t)ebx) << 32);
+ do_div(tsc_hz, 1000);
+ BUG_ON(tsc_hz >> 32);
+ return tsc_hz;
+}
+
+void __init vmware_platform_setup(void)
+{
+ uint32_t eax, ebx, ecx, edx;
- VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
+ VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
- if (ebx == UINT_MAX)
- return 0;
- tsc_hz = eax | (((uint64_t)ebx) << 32);
- do_div(tsc_hz, 1000);
- BUG_ON(tsc_hz >> 32);
- return tsc_hz;
+ if (ebx != UINT_MAX)
+ platform_setup.timers.calibrate_tsc = vmware_get_tsc_khz;
}
/*
@@ -87,12 +96,6 @@ int vmware_platform(void)
return 0;
}
-unsigned long vmware_get_tsc_khz(void)
-{
- BUG_ON(!vmware_platform());
- return __vmware_get_tsc_khz();
-}
-
/*
* VMware hypervisor takes care of exporting a reliable TSC to the guest.
* Still, due to timing difference when running on virtual cpus, the TSC can
Index: linux-2.6/arch/x86/kernel/kvmclock.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/kvmclock.c
+++ linux-2.6/arch/x86/kernel/kvmclock.c
@@ -187,7 +187,7 @@ void __init kvmclock_init(void)
pv_time_ops.get_wallclock = kvm_get_wallclock;
pv_time_ops.set_wallclock = kvm_set_wallclock;
pv_time_ops.sched_clock = kvm_clock_read;
- pv_time_ops.get_tsc_khz = kvm_get_tsc_khz;
+ platform_setup.timers.calibrate_tsc = kvm_get_tsc_khz;
#ifdef CONFIG_X86_LOCAL_APIC
platform_cpuhotplug_setup.setup_percpu_clockev =
kvm_setup_secondary_clock;
Index: linux-2.6/arch/x86/kernel/paravirt.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/paravirt.c
+++ linux-2.6/arch/x86/kernel/paravirt.c
@@ -309,7 +309,6 @@ struct pv_time_ops pv_time_ops = {
.get_wallclock = native_get_wallclock,
.set_wallclock = native_set_wallclock,
.sched_clock = native_sched_clock,
- .get_tsc_khz = native_calibrate_tsc,
};
struct pv_irq_ops pv_irq_ops = {
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -12,6 +12,7 @@
#include <asm/e820.h>
#include <asm/time.h>
#include <asm/irq.h>
+#include <asm/tsc.h>
void __cpuinit platform_setup_noop(void) { }
void __init platform_setup_uint_noop(unsigned int unused) { }
@@ -59,6 +60,7 @@ struct __initdata platform_setup_ops pla
.setup_percpu_clockev = setup_boot_APIC_clock,
.tsc_pre_init = platform_setup_noop,
.timer_init = hpet_time_init,
+ .calibrate_tsc = native_calibrate_tsc,
},
.quirks = {
Index: linux-2.6/arch/x86/kernel/setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/setup.c
+++ linux-2.6/arch/x86/kernel/setup.c
@@ -818,7 +818,7 @@ void __init setup_arch(char **cmdline_p)
* VMware detection requires dmi to be available, so this
* needs to be done after dmi_scan_machine, for the BP.
*/
- init_hypervisor(&boot_cpu_data);
+ init_hypervisor_platform();
platform_setup.resources.probe_roms();
Index: linux-2.6/arch/x86/kernel/tsc.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/tsc.c
+++ linux-2.6/arch/x86/kernel/tsc.c
@@ -401,15 +401,9 @@ unsigned long native_calibrate_tsc(void)
{
u64 tsc1, tsc2, delta, ref1, ref2;
unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX;
- unsigned long flags, latch, ms, fast_calibrate, hv_tsc_khz;
+ unsigned long flags, latch, ms, fast_calibrate;
int hpet = is_hpet_enabled(), i, loopmin;
- hv_tsc_khz = get_hypervisor_tsc_freq();
- if (hv_tsc_khz) {
- printk(KERN_INFO "TSC: Frequency read from the hypervisor\n");
- return hv_tsc_khz;
- }
-
local_irq_save(flags);
fast_calibrate = quick_pit_calibrate();
local_irq_restore(flags);
@@ -917,7 +911,7 @@ void __init tsc_init(void)
if (!cpu_has_tsc)
return;
- tsc_khz = calibrate_tsc();
+ tsc_khz = platform_setup.timers.calibrate_tsc();
cpu_khz = tsc_khz;
if (!tsc_khz) {
Index: linux-2.6/arch/x86/kernel/vmi_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/vmi_32.c
+++ linux-2.6/arch/x86/kernel/vmi_32.c
@@ -826,7 +826,7 @@ static inline int __init activate_vmi(vo
vmi_time_ap_init;
#endif
pv_time_ops.sched_clock = vmi_sched_clock;
- pv_time_ops.get_tsc_khz = vmi_tsc_khz;
+ platform_setup.timers.calibrate_tsc = vmi_tsc_khz;
/* We have true wallclock functions; disable CMOS clock sync */
no_sync_cmos_clock = 1;
Index: linux-2.6/arch/x86/kernel/vmiclock_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/vmiclock_32.c
+++ linux-2.6/arch/x86/kernel/vmiclock_32.c
@@ -68,7 +68,7 @@ unsigned long long vmi_sched_clock(void)
return cycles_2_ns(vmi_timer_ops.get_cycle_counter(VMI_CYCLES_AVAILABLE));
}
-/* paravirt_ops.get_tsc_khz = vmi_tsc_khz */
+/* platform_setup.calibrate_tsc = vmi_tsc_khz */
unsigned long vmi_tsc_khz(void)
{
unsigned long long khz;
Index: linux-2.6/arch/x86/lguest/boot.c
===================================================================
--- linux-2.6.orig/arch/x86/lguest/boot.c
+++ linux-2.6/arch/x86/lguest/boot.c
@@ -1320,11 +1320,11 @@ __init void lguest_init(void)
/* Time operations */
pv_time_ops.get_wallclock = lguest_get_wallclock;
- pv_time_ops.get_tsc_khz = lguest_tsc_khz;
platform_setup.resources.memory_setup = lguest_memory_setup;
platform_setup.irqs.intr_init = lguest_init_IRQ;
platform_setup.timers.timer_init = lguest_time_init;
+ platform_setup.timers.calibrate_tsc = lguest_tsc_khz;
/*
* Now is a good time to look at the implementations of these functions
Index: linux-2.6/arch/x86/xen/enlighten.c
===================================================================
--- linux-2.6.orig/arch/x86/xen/enlighten.c
+++ linux-2.6/arch/x86/xen/enlighten.c
@@ -844,7 +844,6 @@ static const struct pv_init_ops xen_init
static const struct pv_time_ops xen_time_ops __initdata = {
.set_wallclock = xen_set_wallclock,
.get_wallclock = xen_get_wallclock,
- .get_tsc_khz = xen_tsc_khz,
.sched_clock = xen_sched_clock,
};
@@ -981,6 +980,7 @@ asmlinkage void __init xen_start_kernel(
platform_setup.oem.banner = xen_banner;
platform_setup.timers.timer_init = xen_time_init;
+ platform_setup.timers.calibrate_tsc = xen_tsc_khz;
/* Override the default per cpu clockevents setup functions */
platform_setup.timers.setup_percpu_clockev = platform_setup_noop;
next prev parent reply other threads:[~2009-08-21 21:34 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 01/32] x86: Add platform_setup infrastructure Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 02/32] x86: Add probe_roms to platform_setup Thomas Gleixner
2009-08-21 22:23 ` Jeremy Fitzhardinge
2009-08-21 22:36 ` Thomas Gleixner
2009-08-28 21:52 ` [RFC PATCH 0/7] x86/boot: Moorestown patch set based on platform_set abstraction Pan, Jacob jun
2009-08-29 16:59 ` Thomas Gleixner
2009-08-28 21:52 ` [RFC PATCH 2/7] x86: introduce a set of platform feature flags Pan, Jacob jun
2009-08-28 21:52 ` [RFC PATCH 3/7] x86: add moorestown specific platform setup code Pan, Jacob jun
2009-08-29 17:20 ` Thomas Gleixner
2009-08-28 21:53 ` [RFC PATCH 4/7] x86/apbt: Moorestown APB system timer driver Pan, Jacob jun
2009-08-28 21:53 ` [RFC PATCH 5/7] x86/apic: decouple legacy irq handling in ioapic Pan, Jacob jun
2009-08-28 21:53 ` [RFC PATCH 6/7] x86/apic: Early setup IOAPIC for APB timer Pan, Jacob jun
2009-08-28 21:53 ` [RFC PATCH 7/7] x86: add more platform_setup functions Pan, Jacob jun
2009-08-29 17:31 ` Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 03/32] x86: Add request_standard_resources to platform_setup Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 04/32] x86: Add reserve_ebda_region " Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 05/32] x86: Move memory_setup to platform Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 06/32] x86: Sanitize smp_record and move it to platform_setup Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 07/32] x86: Move ioapic_ids_setup " Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 08/32] x86: Move mpc_apic_id " Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 09/32] x86: Move smp_read_mpc_oem " Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 10/32] x86: Move mpc_oem_pci_bus " Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 11/32] x86: Move oem_bus_info " Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 12/32] x86: Move get/find_smp_config " Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 13/32] x86: Move pre_intr_init " Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 14/32] x86: Move irq_init " Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 15/32] x86: Move traps_init " Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 16/32] x86: Replace ARCH_SETUP by a proper platform function Thomas Gleixner
2009-08-21 22:30 ` Jeremy Fitzhardinge
2009-08-21 23:42 ` Thomas Gleixner
2009-08-28 21:52 ` [PATCH 1/7] x86/boot: adding hw subarch ID for Moorestown Pan, Jacob jun
2009-08-29 16:58 ` Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 17/32] x86: Move paravirt banner printout to platform Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 18/32] x86: Move paravirt pagetable_setup " Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 19/32] x86: Move xen_post_allocator_init into xen_pagetable_setup_done Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 20/32] x86: Move percpu clockevents setup to platform Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 21/32] x86: Add timer_init " Thomas Gleixner
2009-08-24 6:48 ` Andrey Panin
2009-08-21 21:31 ` [RFC patch 22/32] x86: Remove do_timer hook Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 23/32] x86: Prepare unification of time_32/64.c Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 24/32] x86: Simplify timer_ack magic in time_32.c Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 25/32] x86: Remove mca bus ifdef from timer interrupt Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 26/32] x86: Make timer setup and global variables the same in time_32/64.c Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 27/32] x86: Move calibrate_cpu to tsc.c Thomas Gleixner
2009-08-21 21:32 ` [RFC patch 28/32] x86: time_32/64.c unify profile_pc Thomas Gleixner
2009-08-21 21:32 ` [RFC patch 29/32] x86: Replace the now identical time_32/64.c by time.c Thomas Gleixner
2009-08-21 21:32 ` Thomas Gleixner [this message]
2009-08-21 21:32 ` [RFC patch 31/32] init: Move sched_clock_init after late_time_init Thomas Gleixner
2009-08-21 21:32 ` [RFC patch 32/32] x86: Move tsc_init to late_time_init Thomas Gleixner
2009-08-21 22:19 ` [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Jeremy Fitzhardinge
2009-08-22 10:57 ` Ingo Molnar
2009-08-23 9:15 ` Thomas Gleixner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090821205603.267985525@linutronix.de \
--to=tglx@linutronix.de \
--cc=akataria@vmware.com \
--cc=akpm@linux-foundation.org \
--cc=arjan@infradead.org \
--cc=avi@redhat.com \
--cc=jacob.jun.pan@intel.com \
--cc=jeremy@goop.org \
--cc=linux-kernel@vger.kernel.org \
--cc=peterz@infradead.org \
--cc=rusty@rustcorp.com.au \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.