LKML Archive mirror
 help / color / mirror / Atom feed
* [PATCH] x86: detect running on a HyperV system
@ 2010-05-06 19:08 Greg KH
  2010-05-06 19:13 ` H. Peter Anvin
  2010-05-08  1:57 ` [tip:x86/cpu] x86: Detect running on a Microsoft " tip-bot for Ky Srinivasan
  0 siblings, 2 replies; 8+ messages in thread
From: Greg KH @ 2010-05-06 19:08 UTC (permalink / raw
  To: asdf, Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86
  Cc: linux-kernel, Vadim Rozenfeld, Avi Kivity, Gleb Natapov,
	Peter Zijlstra, Haiyang Zhang, Hank Janssen

From: Ky Srinivasan <ksrinivasan@novell.com>

This patch integrates HyperV detection within the framework currently
used by VmWare. With this patch, we can avoid having to replicate the
HyperV detection code in each of the Microsoft HyperV drivers.

Reworked and tweaked by Greg K-H to build properly.

Signed-off-by: K. Y. Srinivasan <ksrinivasan@novell.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Vadim Rozenfeld <vrozenfe@redhat.com>
Cc: Avi Kivity <avi@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: "K.Prasad" <prasad@linux.vnet.ibm.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Alan Cox <alan@linux.intel.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Hank Janssen <hjanssen@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---

KY, I fixed up the patch so it would build properly (the old one did not
anymore)  I also renamed the .c and .h file to "mshyperv.h".  I really
don't care about the name, but it shouldn't be "hyperv.h" as that is
already used by the kernel.  Hank, KY, any preference for the name?

x86-maintainers, we need this patch in the tree to get a -staging driver
to work properly.  If you don't object, can I take it through the
staging tree?  Or do you want to take it in -tip?

 arch/x86/include/asm/hyperv.h    |    6 +++
 arch/x86/include/asm/mshyperv.h  |    7 ++++
 arch/x86/include/asm/processor.h |    3 +
 arch/x86/kernel/cpu/Makefile     |    2 -
 arch/x86/kernel/cpu/hypervisor.c |   10 ++++-
 arch/x86/kernel/cpu/mshyperv.c   |   67 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 91 insertions(+), 4 deletions(-)

--- a/arch/x86/include/asm/hyperv.h
+++ b/arch/x86/include/asm/hyperv.h
@@ -14,6 +14,9 @@
 #define HYPERV_CPUID_ENLIGHTMENT_INFO		0x40000004
 #define HYPERV_CPUID_IMPLEMENT_LIMITS		0x40000005
 
+#define HYPERV_HYPERVISOR_PRESENT_BIT		0x80000000
+#define HYPERV_CPUID_MIN			0x40000005
+
 /*
  * Feature identification. EAX indicates which features are available
  * to the partition based upon the current partition privileges.
@@ -129,6 +132,9 @@
 /* MSR used to provide vcpu index */
 #define HV_X64_MSR_VP_INDEX			0x40000002
 
+/* MSR used to read the per-partition time reference counter */
+#define HV_X64_MSR_TIME_REF_COUNT		0x40000020
+
 /* Define the virtual APIC registers */
 #define HV_X64_MSR_EOI				0x40000070
 #define HV_X64_MSR_ICR				0x40000071
--- /dev/null
+++ b/arch/x86/include/asm/mshyperv.h
@@ -0,0 +1,7 @@
+#ifndef ASM_X86__MSHYPER_H
+#define ASM_X86__MSHYPER_H
+
+int ms_hyperv_platform(void);
+void __cpuinit ms_hyperv_set_feature_bits(struct cpuinfo_x86 *c);
+
+#endif
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -114,6 +114,8 @@ struct cpuinfo_x86 {
 	u16			cpu_index;
 #endif
 	unsigned int		x86_hyper_vendor;
+	/* The layout of this field is hypervisor specific */
+	unsigned int		x86_hyper_features;
 } __attribute__((__aligned__(SMP_CACHE_BYTES)));
 
 #define X86_VENDOR_INTEL	0
@@ -129,6 +131,7 @@ struct cpuinfo_x86 {
 
 #define X86_HYPER_VENDOR_NONE  0
 #define X86_HYPER_VENDOR_VMWARE 1
+#define X86_HYPER_VENDOR_MSFT	2
 
 /*
  * capabilities of CPUs
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -14,7 +14,7 @@ CFLAGS_common.o		:= $(nostackp)
 
 obj-y			:= intel_cacheinfo.o addon_cpuid_features.o
 obj-y			+= proc.o capflags.o powerflags.o common.o
-obj-y			+= vmware.o hypervisor.o sched.o
+obj-y			+= vmware.o hypervisor.o sched.o mshyperv.o
 
 obj-$(CONFIG_X86_32)	+= bugs.o cmpxchg.o
 obj-$(CONFIG_X86_64)	+= bugs_64.o
--- a/arch/x86/kernel/cpu/hypervisor.c
+++ b/arch/x86/kernel/cpu/hypervisor.c
@@ -23,6 +23,7 @@
 
 #include <asm/processor.h>
 #include <asm/vmware.h>
+#include <asm/mshyperv.h>
 #include <asm/hypervisor.h>
 
 static inline void __cpuinit
@@ -30,6 +31,8 @@ detect_hypervisor_vendor(struct cpuinfo_
 {
 	if (vmware_platform())
 		c->x86_hyper_vendor = X86_HYPER_VENDOR_VMWARE;
+	else if (ms_hyperv_platform())
+		c->x86_hyper_vendor = X86_HYPER_VENDOR_MSFT;
 	else
 		c->x86_hyper_vendor = X86_HYPER_VENDOR_NONE;
 }
@@ -37,10 +40,11 @@ detect_hypervisor_vendor(struct cpuinfo_
 static inline void __cpuinit
 hypervisor_set_feature_bits(struct cpuinfo_x86 *c)
 {
-	if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE) {
+	if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE)
 		vmware_set_feature_bits(c);
-		return;
-	}
+	else if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_MSFT)
+		ms_hyperv_set_feature_bits(c);
+	return;
 }
 
 void __cpuinit init_hypervisor(struct cpuinfo_x86 *c)
--- /dev/null
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -0,0 +1,67 @@
+/*
+ * HyperV  Detection code.
+ *
+ * Copyright (C) 2010, Novell, Inc.
+ * Author : K. Y. Srinivasan <ksrinivasan@novell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <linux/types.h>
+#include <asm/processor.h>
+#include <asm/hyperv.h>
+#include <asm/mshyperv.h>
+
+
+int ms_hyperv_platform(void)
+{
+	u32 eax, ebx, ecx, edx;
+	char hyp_signature[13];
+
+	cpuid(1, &eax, &ebx, &ecx, &edx);
+	if (!(ecx & HYPERV_HYPERVISOR_PRESENT_BIT))
+		return 0;
+
+	cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS, &eax, &ebx, &ecx, &edx);
+	*(u32 *)(hyp_signature + 0) = ebx;
+	*(u32 *)(hyp_signature + 4) = ecx;
+	*(u32 *)(hyp_signature + 8) = edx;
+
+	if ((eax < HYPERV_CPUID_MIN) || (memcmp("Microsoft Hv", hyp_signature, 12)))
+		return 0;
+	return 1;
+}
+
+void __cpuinit ms_hyperv_set_feature_bits(struct cpuinfo_x86 *c)
+{
+	u32 eax, ebx, ecx, edx;
+
+	c->x86_hyper_features = 0;
+	/*
+	 * Extract the features, recommendations etc.
+	 * The first 9 bits will be used to track hypervisor features.
+	 * The next 6 bits will be used to track the hypervisor
+	 * recommendations.
+	 */
+	cpuid(HYPERV_CPUID_FEATURES, &eax, &ebx, &ecx, &edx);
+	c->x86_hyper_features |= (eax & 0x1ff);
+
+	cpuid(HYPERV_CPUID_ENLIGHTMENT_INFO, &eax, &ebx, &ecx, &edx);
+	c->x86_hyper_features |= ((eax & 0x3f) << 9);
+	printk(KERN_INFO "Detected HyperV with features: %x\n",
+		c->x86_hyper_features);
+}

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] x86: detect running on a HyperV system
  2010-05-06 19:08 [PATCH] x86: detect running on a HyperV system Greg KH
@ 2010-05-06 19:13 ` H. Peter Anvin
  2010-05-06 19:18   ` Greg KH
  2010-05-08  1:57 ` [tip:x86/cpu] x86: Detect running on a Microsoft " tip-bot for Ky Srinivasan
  1 sibling, 1 reply; 8+ messages in thread
From: H. Peter Anvin @ 2010-05-06 19:13 UTC (permalink / raw
  To: Greg KH
  Cc: asdf, Thomas Gleixner, Ingo Molnar, x86, linux-kernel,
	Vadim Rozenfeld, Avi Kivity, Gleb Natapov, Peter Zijlstra,
	Haiyang Zhang, Hank Janssen

On 05/06/2010 12:08 PM, Greg KH wrote:
> 
> x86-maintainers, we need this patch in the tree to get a -staging driver
> to work properly.  If you don't object, can I take it through the
> staging tree?  Or do you want to take it in -tip?
> 

I'd prefer to take it in -tip, partly because I would like to rework a
few things -- including preexisting braindamage like c->x86_hyper_vendor
(since when was hypervisor vendor a per-cpu property!?)

I'll try to get to it today, if not feel free to bug me.

	-hpa

-- 
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel.  I don't speak on their behalf.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] x86: detect running on a HyperV system
  2010-05-06 19:13 ` H. Peter Anvin
@ 2010-05-06 19:18   ` Greg KH
  2010-05-06 21:23     ` H. Peter Anvin
  2010-05-07  1:49     ` H. Peter Anvin
  0 siblings, 2 replies; 8+ messages in thread
From: Greg KH @ 2010-05-06 19:18 UTC (permalink / raw
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, x86, linux-kernel, Vadim Rozenfeld,
	Avi Kivity, Gleb Natapov, Peter Zijlstra, Haiyang Zhang,
	Hank Janssen

On Thu, May 06, 2010 at 12:13:17PM -0700, H. Peter Anvin wrote:
> On 05/06/2010 12:08 PM, Greg KH wrote:
> > 
> > x86-maintainers, we need this patch in the tree to get a -staging driver
> > to work properly.  If you don't object, can I take it through the
> > staging tree?  Or do you want to take it in -tip?
> > 
> 
> I'd prefer to take it in -tip, partly because I would like to rework a
> few things -- including preexisting braindamage like c->x86_hyper_vendor
> (since when was hypervisor vendor a per-cpu property!?)

Heh, good point, but where should it live?

And I have no objection to taking it in -tip, thanks for doing so.

> I'll try to get to it today, if not feel free to bug me.

Will do :)

thanks again,

greg k-h

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] x86: detect running on a HyperV system
  2010-05-06 19:18   ` Greg KH
@ 2010-05-06 21:23     ` H. Peter Anvin
  2010-05-07  1:49     ` H. Peter Anvin
  1 sibling, 0 replies; 8+ messages in thread
From: H. Peter Anvin @ 2010-05-06 21:23 UTC (permalink / raw
  To: Greg KH
  Cc: Thomas Gleixner, Ingo Molnar, x86, linux-kernel, Vadim Rozenfeld,
	Avi Kivity, Gleb Natapov, Peter Zijlstra, Haiyang Zhang,
	Hank Janssen

On 05/06/2010 12:18 PM, Greg KH wrote:
>>
>> I'd prefer to take it in -tip, partly because I would like to rework a
>> few things -- including preexisting braindamage like c->x86_hyper_vendor
>> (since when was hypervisor vendor a per-cpu property!?)
> 
> Heh, good point, but where should it live?
> 

Probably just make it a global variable, or somesuch.

	-hpa

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] x86: detect running on a HyperV system
  2010-05-06 19:18   ` Greg KH
  2010-05-06 21:23     ` H. Peter Anvin
@ 2010-05-07  1:49     ` H. Peter Anvin
  2010-05-07 15:46       ` Greg KH
  1 sibling, 1 reply; 8+ messages in thread
From: H. Peter Anvin @ 2010-05-07  1:49 UTC (permalink / raw
  To: Greg KH
  Cc: Thomas Gleixner, Ingo Molnar, x86, linux-kernel, Vadim Rozenfeld,
	Avi Kivity, Gleb Natapov, Peter Zijlstra, Haiyang Zhang,
	Hank Janssen

On 05/06/2010 12:18 PM, Greg KH wrote:
> On Thu, May 06, 2010 at 12:13:17PM -0700, H. Peter Anvin wrote:
>> On 05/06/2010 12:08 PM, Greg KH wrote:
>>>
>>> x86-maintainers, we need this patch in the tree to get a -staging driver
>>> to work properly.  If you don't object, can I take it through the
>>> staging tree?  Or do you want to take it in -tip?
>>>
>>
>> I'd prefer to take it in -tip, partly because I would like to rework a
>> few things -- including preexisting braindamage like c->x86_hyper_vendor
>> (since when was hypervisor vendor a per-cpu property!?)
> 
> Heh, good point, but where should it live?
> 
> And I have no objection to taking it in -tip, thanks for doing so.
> 
>> I'll try to get to it today, if not feel free to bug me.
> 
> Will do :)
> 
> thanks again,
> 

Okay... we write something called x86_hyper_features, but it isn't
actually used for anything.  I'm assuming based on what I can see in
<asm/hyperv.h> that it is almost certainly not anything CPU-based.  I
really don't like a random field that can be stuffed with information
from random locations, and it doesn't look like it's even a flag field
in any meaningful way.  Worse, the field is just used to mix bits from
two different CPUID levels at what appears to be a completely arbitrary
boundary:

        /*
         * Extract the features, recommendations etc.
         * The first 9 bits will be used to track hypervisor features.
         * The next 6 bits will be used to track the hypervisor
         * recommendations.
         */
        cpuid(HYPERV_CPUID_FEATURES, &eax, &ebx, &ecx, &edx);
        c->x86_hyper_features |= (eax & 0x1ff);

        cpuid(HYPERV_CPUID_ENLIGHTMENT_INFO, &eax, &ebx, &ecx, &edx);
        c->x86_hyper_features |= ((eax & 0x3f) << 9);

Why 9?  Why 6?  The only thing that I can think of that justifies those
particular numbers is what the *current* version of Hyper-V does.

It would be better to just have a global variable where these two levels
are separately stuffed away instead of arbitrarily commingled (again,
I'm assuming none of the bits are actually per CPU.)

What does this driver of yours do with them?

	-hpa

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] x86: detect running on a HyperV system
  2010-05-07  1:49     ` H. Peter Anvin
@ 2010-05-07 15:46       ` Greg KH
  2010-05-07 16:20         ` Hank Janssen
  0 siblings, 1 reply; 8+ messages in thread
From: Greg KH @ 2010-05-07 15:46 UTC (permalink / raw
  To: H. Peter Anvin, K. Y. Srinivasan
  Cc: Thomas Gleixner, Ingo Molnar, x86, linux-kernel, Vadim Rozenfeld,
	Avi Kivity, Gleb Natapov, Peter Zijlstra, Haiyang Zhang,
	Hank Janssen

[KY added to the To:, sorry for not including him earlier, he wrote this
code]

On Thu, May 06, 2010 at 06:49:31PM -0700, H. Peter Anvin wrote:
> On 05/06/2010 12:18 PM, Greg KH wrote:
> > On Thu, May 06, 2010 at 12:13:17PM -0700, H. Peter Anvin wrote:
> >> On 05/06/2010 12:08 PM, Greg KH wrote:
> >>>
> >>> x86-maintainers, we need this patch in the tree to get a -staging driver
> >>> to work properly.  If you don't object, can I take it through the
> >>> staging tree?  Or do you want to take it in -tip?
> >>>
> >>
> >> I'd prefer to take it in -tip, partly because I would like to rework a
> >> few things -- including preexisting braindamage like c->x86_hyper_vendor
> >> (since when was hypervisor vendor a per-cpu property!?)
> > 
> > Heh, good point, but where should it live?
> > 
> > And I have no objection to taking it in -tip, thanks for doing so.
> > 
> >> I'll try to get to it today, if not feel free to bug me.
> > 
> > Will do :)
> > 
> > thanks again,
> > 
> 
> Okay... we write something called x86_hyper_features, but it isn't
> actually used for anything.  I'm assuming based on what I can see in
> <asm/hyperv.h> that it is almost certainly not anything CPU-based.  I
> really don't like a random field that can be stuffed with information
> from random locations, and it doesn't look like it's even a flag field
> in any meaningful way.  Worse, the field is just used to mix bits from
> two different CPUID levels at what appears to be a completely arbitrary
> boundary:
> 
>         /*
>          * Extract the features, recommendations etc.
>          * The first 9 bits will be used to track hypervisor features.
>          * The next 6 bits will be used to track the hypervisor
>          * recommendations.
>          */
>         cpuid(HYPERV_CPUID_FEATURES, &eax, &ebx, &ecx, &edx);
>         c->x86_hyper_features |= (eax & 0x1ff);
> 
>         cpuid(HYPERV_CPUID_ENLIGHTMENT_INFO, &eax, &ebx, &ecx, &edx);
>         c->x86_hyper_features |= ((eax & 0x3f) << 9);
> 
> Why 9?  Why 6?  The only thing that I can think of that justifies those
> particular numbers is what the *current* version of Hyper-V does.

I think that is what Hyper-V is saying it will always do.  Hank?  Any
help here?

> It would be better to just have a global variable where these two levels
> are separately stuffed away instead of arbitrarily commingled (again,
> I'm assuming none of the bits are actually per CPU.)

Sure, that would be fine, that's all we really need.

> What does this driver of yours do with them?

It just tests to see if the functionality is present.  I've included the
driver below to show this.

thanks,

greg k-h

--------
From: K. Y. Srinivasan <ksrinivasan@novell.com>
Subject: Staging: A clocksource for Linux guests hosted on HyperV.

This patch is a clocksource implementation suitable for guests hosted on
HyperV.  Time keeping in Linux guests hosted on HyperV is unstable. This
clocksource driver fixes the problem.

Signed-off-by: K. Y. Srinivasan <ksrinivasan@novell.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 drivers/staging/hv/Makefile        |    2 
 drivers/staging/hv/hv_timesource.c |   94 +++++++++++++++++++++++++++++++++++++
 2 files changed, 95 insertions(+), 1 deletion(-)

--- a/drivers/staging/hv/Makefile
+++ b/drivers/staging/hv/Makefile
@@ -1,4 +1,4 @@
-obj-$(CONFIG_HYPERV)		+= hv_vmbus.o
+obj-$(CONFIG_HYPERV)		+= hv_vmbus.o hv_timesource.o
 obj-$(CONFIG_HYPERV_STORAGE)	+= hv_storvsc.o
 obj-$(CONFIG_HYPERV_BLOCK)	+= hv_blkvsc.o
 obj-$(CONFIG_HYPERV_NET)	+= hv_netvsc.o
--- /dev/null
+++ b/drivers/staging/hv/hv_timesource.c
@@ -0,0 +1,94 @@
+/*
+ * A clocksource for Linux running on HyperV.
+ *
+ * Copyright (C) 2010, Novell, Inc.
+ * Author : K. Y. Srinivasan <ksrinivasan@novell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+#include <linux/init.h>
+#include <linux/clocksource.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/dmi.h>
+#include <asm/hyperv.h>
+
+#define HV_CLOCK_SHIFT	22
+
+static cycle_t read_hv_clock(struct clocksource *arg)
+{
+	cycle_t current_tick;
+	/*
+	 * Read the partition counter to get the current tick count. This count
+	 * is set to 0 when the partition is created and is incremented in
+	 * 100 nanosecond units.
+	 */
+	rdmsrl(HV_X64_MSR_TIME_REF_COUNT, current_tick);
+	return current_tick;
+}
+
+static struct clocksource hyperv_cs = {
+	.name           = "hyperv_clocksource",
+	.rating         = 400, /* use this when running on Hyperv*/
+	.read           = read_hv_clock,
+	.mask           = CLOCKSOURCE_MASK(64),
+	/*
+	 * The time ref counter in HyperV is in 100ns units.
+	 * The definition of mult is:
+	 * mult/2^shift = ns/cyc = 100
+	 * mult = (100 << shift)
+	 */
+	.mult           = (100 << HV_CLOCK_SHIFT),
+	.shift          = HV_CLOCK_SHIFT,
+};
+
+static const struct dmi_system_id __initconst
+hv_timesource_dmi_table[] __maybe_unused  = {
+	{
+		.ident = "Hyper-V",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
+			DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"),
+		},
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(dmi, hv_timesource_dmi_table);
+
+static const struct pci_device_id __initconst
+hv_timesource_pci_table[] __maybe_unused = {
+	{ PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */
+	{ 0 }
+};
+MODULE_DEVICE_TABLE(pci, hv_timesource_pci_table);
+
+
+static int __init init_hv_clocksource(void)
+{
+	if ((boot_cpu_data.x86_hyper_vendor != X86_HYPER_VENDOR_MSFT) ||
+		!(boot_cpu_data.x86_hyper_features &
+		HV_X64_MSR_TIME_REF_COUNT_AVAILABLE))
+		return -ENODEV;
+	printk(KERN_INFO "Registering HyperV clock source\n");
+	return clocksource_register(&hyperv_cs);
+}
+
+module_init(init_hv_clocksource);
+MODULE_DESCRIPTION("HyperV based clocksource");
+MODULE_AUTHOR("K. Y. Srinivasan <ksrinivasan@novell.com>");
+MODULE_LICENSE("GPL");

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH] x86: detect running on a HyperV system
  2010-05-07 15:46       ` Greg KH
@ 2010-05-07 16:20         ` Hank Janssen
  0 siblings, 0 replies; 8+ messages in thread
From: Hank Janssen @ 2010-05-07 16:20 UTC (permalink / raw
  To: Greg KH, H. Peter Anvin, K. Y. Srinivasan
  Cc: Thomas Gleixner, Ingo Molnar, x86@kernel.org,
	linux-kernel@vger.kernel.org, Vadim Rozenfeld, Avi Kivity,
	Gleb Natapov, Peter Zijlstra, Haiyang Zhang



SNIP SNIP SNIP----------
> From: Greg KH [greg@kroah.com]    -    Friday, May 07, 2010 8:46 AM
>
>[KY added to the To:, sorry for not including him earlier, he wrote this
>code]

On Thu, May 06, 2010 at 06:49:31PM -0700, H. Peter Anvin wrote:
>> On 05/06/2010 12:18 PM, Greg KH wrote:
>> > On Thu, May 06, 2010 at 12:13:17PM -0700, H. Peter Anvin wrote:
>> >> On 05/06/2010 12:08 PM, Greg KH wrote:
>> Okay... we write something called x86_hyper_features, but it isn't
>> actually used for anything.  I'm assuming based on what I can see in
>> <asm/hyperv.h> that it is almost certainly not anything CPU-based.  I
>> really don't like a random field that can be stuffed with information
>> from random locations, and it doesn't look like it's even a flag field
>> in any meaningful way.  Worse, the field is just used to mix bits from
>> two different CPUID levels at what appears to be a completely arbitrary
>> boundary:
>>
>>         /*
>>          * Extract the features, recommendations etc.
>>          * The first 9 bits will be used to track hypervisor features.
>>          * The next 6 bits will be used to track the hypervisor
>>          * recommendations.
>>          */
>>         cpuid(HYPERV_CPUID_FEATURES, &eax, &ebx, &ecx, &edx);
>>         c->x86_hyper_features |= (eax & 0x1ff);
>>
>>         cpuid(HYPERV_CPUID_ENLIGHTMENT_INFO, &eax, &ebx, &ecx, &edx);
>>         c->x86_hyper_features |= ((eax & 0x3f) << 9);
>>
>> Why 9?  Why 6?  The only thing that I can think of that justifies those
>> particular numbers is what the *current* version of Hyper-V does.
>
>I think that is what Hyper-V is saying it will always do.  Hank?  Any
>help here?

That is correct. Hyper-V will always do this.

For functionality like a timesource, we need to get to hyper-v the way Ky did in his
code. There is no messaging for it like IDE/SCSI/Network and the like.

My understanding is that more information is going to be contained in these areas
once Windows 8 is more defined. I know Windows 8 will give us changes but we do
not know yet what they are. And I will not untill much later in the year. They are
designing some of the low level stuff there right now.

I know that some of the messaging protocols will change regarding networking.

Hank.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [tip:x86/cpu] x86: Detect running on a Microsoft HyperV system
  2010-05-06 19:08 [PATCH] x86: detect running on a HyperV system Greg KH
  2010-05-06 19:13 ` H. Peter Anvin
@ 2010-05-08  1:57 ` tip-bot for Ky Srinivasan
  1 sibling, 0 replies; 8+ messages in thread
From: tip-bot for Ky Srinivasan @ 2010-05-08  1:57 UTC (permalink / raw
  To: linux-tip-commits
  Cc: eranian, mingo, a.p.zijlstra, hjanssen, fweisbec, gregkh, tglx,
	adobriyan, hpa, linux-kernel, paulus, alan, gleb, ksrinivasan,
	haiyangz, vrozenfe, avi, prasad

Commit-ID:  a2a47c6c3d1a7c01da4464b3b7be93b924f874c1
Gitweb:     http://git.kernel.org/tip/a2a47c6c3d1a7c01da4464b3b7be93b924f874c1
Author:     Ky Srinivasan <ksrinivasan@novell.com>
AuthorDate: Thu, 6 May 2010 12:08:41 -0700
Committer:  H. Peter Anvin <hpa@zytor.com>
CommitDate: Thu, 6 May 2010 18:24:15 -0700

x86: Detect running on a Microsoft HyperV system

This patch integrates HyperV detection within the framework currently
used by VmWare. With this patch, we can avoid having to replicate the
HyperV detection code in each of the Microsoft HyperV drivers.

Reworked and tweaked by Greg K-H to build properly.

Signed-off-by: K. Y. Srinivasan <ksrinivasan@novell.com>
LKML-Reference: <20100506190841.GA1605@kroah.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Vadim Rozenfeld <vrozenfe@redhat.com>
Cc: Avi Kivity <avi@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: "K.Prasad" <prasad@linux.vnet.ibm.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Alan Cox <alan@linux.intel.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Hank Janssen <hjanssen@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86/include/asm/hyperv.h    |    6 +++
 arch/x86/include/asm/mshyperv.h  |    7 ++++
 arch/x86/include/asm/processor.h |    3 ++
 arch/x86/kernel/cpu/Makefile     |    2 +-
 arch/x86/kernel/cpu/hypervisor.c |   10 ++++--
 arch/x86/kernel/cpu/mshyperv.c   |   67 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 91 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/hyperv.h b/arch/x86/include/asm/hyperv.h
index e153a2b..4604047 100644
--- a/arch/x86/include/asm/hyperv.h
+++ b/arch/x86/include/asm/hyperv.h
@@ -14,6 +14,9 @@
 #define HYPERV_CPUID_ENLIGHTMENT_INFO		0x40000004
 #define HYPERV_CPUID_IMPLEMENT_LIMITS		0x40000005
 
+#define HYPERV_HYPERVISOR_PRESENT_BIT		0x80000000
+#define HYPERV_CPUID_MIN			0x40000005
+
 /*
  * Feature identification. EAX indicates which features are available
  * to the partition based upon the current partition privileges.
@@ -129,6 +132,9 @@
 /* MSR used to provide vcpu index */
 #define HV_X64_MSR_VP_INDEX			0x40000002
 
+/* MSR used to read the per-partition time reference counter */
+#define HV_X64_MSR_TIME_REF_COUNT		0x40000020
+
 /* Define the virtual APIC registers */
 #define HV_X64_MSR_EOI				0x40000070
 #define HV_X64_MSR_ICR				0x40000071
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
new file mode 100644
index 0000000..6cd8101
--- /dev/null
+++ b/arch/x86/include/asm/mshyperv.h
@@ -0,0 +1,7 @@
+#ifndef ASM_X86__MSHYPER_H
+#define ASM_X86__MSHYPER_H
+
+int ms_hyperv_platform(void);
+void __cpuinit ms_hyperv_set_feature_bits(struct cpuinfo_x86 *c);
+
+#endif
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index b753ea5..597c041 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -114,6 +114,8 @@ struct cpuinfo_x86 {
 	u16			cpu_index;
 #endif
 	unsigned int		x86_hyper_vendor;
+	/* The layout of this field is hypervisor specific */
+	unsigned int		x86_hyper_features;
 } __attribute__((__aligned__(SMP_CACHE_BYTES)));
 
 #define X86_VENDOR_INTEL	0
@@ -129,6 +131,7 @@ struct cpuinfo_x86 {
 
 #define X86_HYPER_VENDOR_NONE  0
 #define X86_HYPER_VENDOR_VMWARE 1
+#define X86_HYPER_VENDOR_MSFT	2
 
 /*
  * capabilities of CPUs
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index c202b62..3a785da 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -14,7 +14,7 @@ CFLAGS_common.o		:= $(nostackp)
 
 obj-y			:= intel_cacheinfo.o addon_cpuid_features.o
 obj-y			+= proc.o capflags.o powerflags.o common.o
-obj-y			+= vmware.o hypervisor.o sched.o
+obj-y			+= vmware.o hypervisor.o sched.o mshyperv.o
 
 obj-$(CONFIG_X86_32)	+= bugs.o cmpxchg.o
 obj-$(CONFIG_X86_64)	+= bugs_64.o
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c
index 08be922..de3f4e0 100644
--- a/arch/x86/kernel/cpu/hypervisor.c
+++ b/arch/x86/kernel/cpu/hypervisor.c
@@ -23,6 +23,7 @@
 
 #include <asm/processor.h>
 #include <asm/vmware.h>
+#include <asm/mshyperv.h>
 #include <asm/hypervisor.h>
 
 static inline void __cpuinit
@@ -30,6 +31,8 @@ detect_hypervisor_vendor(struct cpuinfo_x86 *c)
 {
 	if (vmware_platform())
 		c->x86_hyper_vendor = X86_HYPER_VENDOR_VMWARE;
+	else if (ms_hyperv_platform())
+		c->x86_hyper_vendor = X86_HYPER_VENDOR_MSFT;
 	else
 		c->x86_hyper_vendor = X86_HYPER_VENDOR_NONE;
 }
@@ -37,10 +40,11 @@ detect_hypervisor_vendor(struct cpuinfo_x86 *c)
 static inline void __cpuinit
 hypervisor_set_feature_bits(struct cpuinfo_x86 *c)
 {
-	if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE) {
+	if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE)
 		vmware_set_feature_bits(c);
-		return;
-	}
+	else if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_MSFT)
+		ms_hyperv_set_feature_bits(c);
+	return;
 }
 
 void __cpuinit init_hypervisor(struct cpuinfo_x86 *c)
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
new file mode 100644
index 0000000..2443b61
--- /dev/null
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -0,0 +1,67 @@
+/*
+ * HyperV  Detection code.
+ *
+ * Copyright (C) 2010, Novell, Inc.
+ * Author : K. Y. Srinivasan <ksrinivasan@novell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <linux/types.h>
+#include <asm/processor.h>
+#include <asm/hyperv.h>
+#include <asm/mshyperv.h>
+
+
+int ms_hyperv_platform(void)
+{
+	u32 eax, ebx, ecx, edx;
+	char hyp_signature[13];
+
+	cpuid(1, &eax, &ebx, &ecx, &edx);
+	if (!(ecx & HYPERV_HYPERVISOR_PRESENT_BIT))
+		return 0;
+
+	cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS, &eax, &ebx, &ecx, &edx);
+	*(u32 *)(hyp_signature + 0) = ebx;
+	*(u32 *)(hyp_signature + 4) = ecx;
+	*(u32 *)(hyp_signature + 8) = edx;
+
+	if ((eax < HYPERV_CPUID_MIN) || (memcmp("Microsoft Hv", hyp_signature, 12)))
+		return 0;
+	return 1;
+}
+
+void __cpuinit ms_hyperv_set_feature_bits(struct cpuinfo_x86 *c)
+{
+	u32 eax, ebx, ecx, edx;
+
+	c->x86_hyper_features = 0;
+	/*
+	 * Extract the features, recommendations etc.
+	 * The first 9 bits will be used to track hypervisor features.
+	 * The next 6 bits will be used to track the hypervisor
+	 * recommendations.
+	 */
+	cpuid(HYPERV_CPUID_FEATURES, &eax, &ebx, &ecx, &edx);
+	c->x86_hyper_features |= (eax & 0x1ff);
+
+	cpuid(HYPERV_CPUID_ENLIGHTMENT_INFO, &eax, &ebx, &ecx, &edx);
+	c->x86_hyper_features |= ((eax & 0x3f) << 9);
+	printk(KERN_INFO "Detected HyperV with features: %x\n",
+		c->x86_hyper_features);
+}

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2010-05-08  1:59 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-06 19:08 [PATCH] x86: detect running on a HyperV system Greg KH
2010-05-06 19:13 ` H. Peter Anvin
2010-05-06 19:18   ` Greg KH
2010-05-06 21:23     ` H. Peter Anvin
2010-05-07  1:49     ` H. Peter Anvin
2010-05-07 15:46       ` Greg KH
2010-05-07 16:20         ` Hank Janssen
2010-05-08  1:57 ` [tip:x86/cpu] x86: Detect running on a Microsoft " tip-bot for Ky Srinivasan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).