From: Alok Kataria <akataria@vmware.com>
To: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>, Ingo Molnar <mingo@elte.hu>,
the arch/x86 maintainers <x86@kernel.org>,
LKML <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] x86,apic: V2 Add apic calibration hook.
Date: Mon, 20 Sep 2010 16:59:56 -0700 [thread overview]
Message-ID: <1285027196.9954.45.camel@ank32.eng.vmware.com> (raw)
In-Reply-To: <1285025650.9954.43.camel@ank32.eng.vmware.com>
On Mon, 2010-09-20 at 16:34 -0700, Alok Kataria wrote:
> Below is the preparatory change, will followup with the 2nd patch which
> introduces the actual hook.
Below is the 2nd patch.
--
Add apic timer calibration hook.
From: Alok N Kataria <akataria@vmware.com>
Add a new function ptr calibrate_apic_clock to x86_init_timers structure.
On native this does the usual apic calibration. On VMware's platform we
override it with a routine which gets that information from the hypervisor.
Signed-off-by: Alok N Kataria <akataria@vmware.com>
Index: linux-x86-tree.git/arch/x86/include/asm/apic.h
===================================================================
--- linux-x86-tree.git.orig/arch/x86/include/asm/apic.h 2010-09-20 16:05:58.000000000 -0700
+++ linux-x86-tree.git/arch/x86/include/asm/apic.h 2010-09-20 16:36:42.000000000 -0700
@@ -17,6 +17,10 @@
#define ARCH_APICTIMER_STOPS_ON_C3 1
+/* Clock divisor */
+#define APIC_DIVISOR 16
+#define LAPIC_CAL_LOOPS (HZ/10)
+
/*
* Debugging macros
*/
@@ -238,6 +242,8 @@ extern void setup_boot_APIC_clock(void);
extern void setup_secondary_APIC_clock(void);
extern int APIC_init_uniprocessor(void);
extern void enable_NMI_through_LVT0(void);
+extern int native_calibrate_apic_clock(void);
+extern int initialize_lapic_timer(long delta, unsigned int calibration_result);
/*
* On 32bit this is mach-xxx local
Index: linux-x86-tree.git/arch/x86/include/asm/x86_init.h
===================================================================
--- linux-x86-tree.git.orig/arch/x86/include/asm/x86_init.h 2010-09-20 16:06:11.000000000 -0700
+++ linux-x86-tree.git/arch/x86/include/asm/x86_init.h 2010-09-20 16:54:08.000000000 -0700
@@ -83,11 +83,13 @@ struct x86_init_paging {
* boot cpu
* @tsc_pre_init: platform function called before TSC init
* @timer_init: initialize the platform timer (default PIT/HPET)
+ * @calibrate_apic_clock: calibrate APIC clock freq (ticks per HZ)
*/
struct x86_init_timers {
void (*setup_percpu_clockev)(void);
void (*tsc_pre_init)(void);
void (*timer_init)(void);
+ int (*calibrate_apic_clock)(void);
};
/**
Index: linux-x86-tree.git/arch/x86/kernel/cpu/vmware.c
===================================================================
--- linux-x86-tree.git.orig/arch/x86/kernel/cpu/vmware.c 2010-09-20 16:05:30.000000000 -0700
+++ linux-x86-tree.git/arch/x86/kernel/cpu/vmware.c 2010-09-20 16:40:35.000000000 -0700
@@ -26,6 +26,7 @@
#include <asm/div64.h>
#include <asm/x86_init.h>
#include <asm/hypervisor.h>
+#include <asm/apic.h>
#define CPUID_VMWARE_INFO_LEAF 0x40000000
#define VMWARE_HYPERVISOR_MAGIC 0x564D5868
@@ -72,17 +73,40 @@ static unsigned long vmware_get_tsc_khz(
return tsc_hz;
}
+static int __init vmware_calibrate_apic_clock(void)
+{
+ unsigned int calibration_result;
+ uint32_t eax, ebx, ecx, edx;
+ int err;
+ long delta;
+ unsigned long flags;
+
+ VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
+ BUG_ON(!ecx);
+ calibration_result = ecx / HZ;
+
+ printk(KERN_INFO "APIC bus freq read from hypervisor\n");
+
+ delta = (calibration_result * LAPIC_CAL_LOOPS) / APIC_DIVISOR;
+ local_irq_save(flags);
+ err = initialize_lapic_timer(delta, calibration_result);
+ local_irq_restore(flags);
+
+ return err;
+}
+
static void __init vmware_platform_setup(void)
{
uint32_t eax, ebx, ecx, edx;
VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
- if (ebx != UINT_MAX)
+ if (ebx != UINT_MAX) {
x86_platform.calibrate_tsc = vmware_get_tsc_khz;
- else
+ x86_init.timers.calibrate_apic_clock = vmware_calibrate_apic_clock;
+ } else
printk(KERN_WARNING
- "Failed to get TSC freq from the hypervisor\n");
+ "Failed to setup VMware hypervisor platform\n");
}
/*
Index: linux-x86-tree.git/arch/x86/kernel/x86_init.c
===================================================================
--- linux-x86-tree.git.orig/arch/x86/kernel/x86_init.c 2010-09-20 16:05:07.000000000 -0700
+++ linux-x86-tree.git/arch/x86/kernel/x86_init.c 2010-09-20 16:41:21.000000000 -0700
@@ -68,6 +68,7 @@ struct x86_init_ops x86_init __initdata
.setup_percpu_clockev = setup_boot_APIC_clock,
.tsc_pre_init = x86_init_noop,
.timer_init = hpet_time_init,
+ .calibrate_apic_clock = native_calibrate_apic_clock
},
.iommu = {
Index: linux-x86-tree.git/arch/x86/kernel/apic/apic.c
===================================================================
--- linux-x86-tree.git.orig/arch/x86/kernel/apic/apic.c 2010-09-20 16:10:13.000000000 -0700
+++ linux-x86-tree.git/arch/x86/kernel/apic/apic.c 2010-09-20 16:42:12.000000000 -0700
@@ -326,13 +326,6 @@ int lapic_get_maxlvt(void)
}
/*
- * Local APIC timer
- */
-
-/* Clock divisor */
-#define APIC_DIVISOR 16
-
-/*
* This function sets up the local APIC timer, with a timeout of
* 'clocks' APIC bus clock. During calibration we actually call
* this function twice on the boot CPU, once with a bogus timeout
@@ -500,8 +493,6 @@ static void __cpuinit setup_APIC_timer(v
* back to normal later in the boot process).
*/
-#define LAPIC_CAL_LOOPS (HZ/10)
-
static __initdata int lapic_cal_loops = -1;
static __initdata long lapic_cal_t1, lapic_cal_t2;
static __initdata unsigned long long lapic_cal_tsc1, lapic_cal_tsc2;
prev parent reply other threads:[~2010-09-20 23:59 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-09-20 21:17 [PATCH] x86,apic: V2 Add apic calibration hook Alok Kataria
2010-09-20 22:11 ` Thomas Gleixner
2010-09-20 23:34 ` Alok Kataria
2010-09-20 23:59 ` Alok Kataria [this message]
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=1285027196.9954.45.camel@ank32.eng.vmware.com \
--to=akataria@vmware.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=tglx@linutronix.de \
--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.