Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 4449

kernel-2.6.18-194.11.1.el5.src.rpm

From: Geoff Gustafson <grgustaf@redhat.com>
Date: Thu, 27 Mar 2008 16:36:27 -0400
Subject: [xen] HV ignoring extended cpu model field
Message-id: 20080327203627.GB19434@samurai.boston.redhat.com
O-Subject: [RHEL5.2 PATCH] xen hv ignoring extended cpu model field (bz 439254)
Bugzilla: 439254

In trying to test my recent oprofile patch w/ the Xen HV, I was surprised to
see that the code didn't have an effect. It turned out that this model 23 cpu
was getting reported as 7 in the HV (I'd recently noticed this on 4.7, too.)
This is because only the bottom four bits, not the new extended model field,
is being used.

So it's getting treated like a Pentium III for some purposes, like determining
available performance registers for oprofile.

The early_cpu_detect() function in the same file actually had this fix
already, but the generic_identify() did not. You can see in arch/i386 under the
normal kernel that both functions have the fix (so bare metal is fine).

I have just confirmed that with this patch, plus the oprofile xen one I've
recently posted, we start seeing what we expected... we get all the Core 2
events available to oprofile, not just the Pentium III ones. So that's the one
concrete thing I've seen so far. Intel also pointed out that this means
CONSTANT_TSC will not be detected, and will affect cpufreq and clock stuff.

Please carefully consider this issue, ye gurus, and ACK if appropriate.

- Geoff

Acked-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Rik van Riel <riel@redhat.com>
Acked-by: Chris Lalancette <clalance@redhat.com>

diff --git a/arch/x86/cpu/common.c b/arch/x86/cpu/common.c
index 956bd19..bbda900 100644
--- a/arch/x86/cpu/common.c
+++ b/arch/x86/cpu/common.c
@@ -250,10 +250,10 @@ void __devinit generic_identify(struct cpuinfo_x86 * c)
 			c->x86_capability[4] = excap;
 			c->x86 = (tfms >> 8) & 15;
 			c->x86_model = (tfms >> 4) & 15;
-			if (c->x86 == 0xf) {
+			if (c->x86 == 0xf)
 				c->x86 += (tfms >> 20) & 0xff;
+			if (c->x86 >= 0x6)
 				c->x86_model += ((tfms >> 16) & 0xF) << 4;
-			} 
 			c->x86_mask = tfms & 15;
 		} else {
 			/* Have CPUID level 0 only - unheard of */