* [git pull] x86 fixes (NOPL issue)
@ 2008-09-06 2:22 H. Peter Anvin
2008-09-06 3:01 ` Yinghai Lu
2008-09-08 15:02 ` David Sanders
0 siblings, 2 replies; 7+ messages in thread
From: H. Peter Anvin @ 2008-09-06 2:22 UTC (permalink / raw)
To: Linus Torvalds; +Cc: x86 maintainers, LKML
Hi Linus,
Please pull:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git x86-fixes-for-linus-2
H. Peter Anvin (4):
x86: boot: stub out unimplemented CPU feature words
x86: add NOPL as a synthetic CPU feature bit
x86: use X86_FEATURE_NOPL in alternatives
Merge branch 'x86/urgent' into x86-fixes-for-linus-2
This fixes the NOPL issue by detecting it explicitly. I don't have
access to Virtual PC, but this works on Virtual Server 2005 R2 which
has the same issue. These changes have been in -tip since August 18,
so they have had some reasonable degree of exposure already.
arch/x86/boot/cpucheck.c | 8 +++---
arch/x86/kernel/alternative.c | 36 ++++++++++++----------------------
arch/x86/kernel/cpu/common.c | 32 ++++++++++++++++++++++++++++++-
arch/x86/kernel/cpu/common_64.c | 36 +++++++++++++++++++++++++++++++++++
arch/x86/kernel/cpu/feature_names.c | 3 +-
include/asm-x86/cpufeature.h | 11 +++++----
include/asm-x86/required-features.h | 8 ++++++-
7 files changed, 99 insertions(+), 35 deletions(-)
diff --git a/arch/x86/boot/cpucheck.c b/arch/x86/boot/cpucheck.c
index 4b9ae7c..4d3ff03 100644
--- a/arch/x86/boot/cpucheck.c
+++ b/arch/x86/boot/cpucheck.c
@@ -38,12 +38,12 @@ static const u32 req_flags[NCAPINTS] =
{
REQUIRED_MASK0,
REQUIRED_MASK1,
- REQUIRED_MASK2,
- REQUIRED_MASK3,
+ 0, /* REQUIRED_MASK2 not implemented in this file */
+ 0, /* REQUIRED_MASK3 not implemented in this file */
REQUIRED_MASK4,
- REQUIRED_MASK5,
+ 0, /* REQUIRED_MASK5 not implemented in this file */
REQUIRED_MASK6,
- REQUIRED_MASK7,
+ 0, /* REQUIRED_MASK7 not implemented in this file */
};
#define A32(a, b, c, d) (((d) << 24)+((c) << 16)+((b) << 8)+(a))
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 2763cb3..65a0c1b 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -145,35 +145,25 @@ static const unsigned char *const p6_nops[ASM_NOP_MAX+1] = {
extern char __vsyscall_0;
const unsigned char *const *find_nop_table(void)
{
- return boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
- boot_cpu_data.x86 < 6 ? k8_nops : p6_nops;
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
+ boot_cpu_has(X86_FEATURE_NOPL))
+ return p6_nops;
+ else
+ return k8_nops;
}
#else /* CONFIG_X86_64 */
-static const struct nop {
- int cpuid;
- const unsigned char *const *noptable;
-} noptypes[] = {
- { X86_FEATURE_K8, k8_nops },
- { X86_FEATURE_K7, k7_nops },
- { X86_FEATURE_P4, p6_nops },
- { X86_FEATURE_P3, p6_nops },
- { -1, NULL }
-};
-
const unsigned char *const *find_nop_table(void)
{
- const unsigned char *const *noptable = intel_nops;
- int i;
-
- for (i = 0; noptypes[i].cpuid >= 0; i++) {
- if (boot_cpu_has(noptypes[i].cpuid)) {
- noptable = noptypes[i].noptable;
- break;
- }
- }
- return noptable;
+ if (boot_cpu_has(X86_FEATURE_K8))
+ return k8_nops;
+ else if (boot_cpu_has(X86_FEATURE_K7))
+ return k7_nops;
+ else if (boot_cpu_has(X86_FEATURE_NOPL))
+ return p6_nops;
+ else
+ return intel_nops;
}
#endif /* CONFIG_X86_64 */
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 80ab20d..0785b3c 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -13,6 +13,7 @@
#include <asm/mtrr.h>
#include <asm/mce.h>
#include <asm/pat.h>
+#include <asm/asm.h>
#ifdef CONFIG_X86_LOCAL_APIC
#include <asm/mpspec.h>
#include <asm/apic.h>
@@ -341,6 +342,35 @@ static void __init early_cpu_detect(void)
early_get_cap(c);
}
+/*
+ * The NOPL instruction is supposed to exist on all CPUs with
+ * family >= 6, unfortunately, that's not true in practice because
+ * of early VIA chips and (more importantly) broken virtualizers that
+ * are not easy to detect. Hence, probe for it based on first
+ * principles.
+ */
+static void __cpuinit detect_nopl(struct cpuinfo_x86 *c)
+{
+ const u32 nopl_signature = 0x888c53b1; /* Random number */
+ u32 has_nopl = nopl_signature;
+
+ clear_cpu_cap(c, X86_FEATURE_NOPL);
+ if (c->x86 >= 6) {
+ asm volatile("\n"
+ "1: .byte 0x0f,0x1f,0xc0\n" /* nopl %eax */
+ "2:\n"
+ " .section .fixup,\"ax\"\n"
+ "3: xor %0,%0\n"
+ " jmp 2b\n"
+ " .previous\n"
+ _ASM_EXTABLE(1b,3b)
+ : "+a" (has_nopl));
+
+ if (has_nopl == nopl_signature)
+ set_cpu_cap(c, X86_FEATURE_NOPL);
+ }
+}
+
static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
{
u32 tfms, xlvl;
@@ -395,8 +425,8 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
}
init_scattered_cpuid_features(c);
+ detect_nopl(c);
}
-
}
static void __cpuinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
diff --git a/arch/x86/kernel/cpu/common_64.c b/arch/x86/kernel/cpu/common_64.c
index dd6e3f1..c3afba5 100644
--- a/arch/x86/kernel/cpu/common_64.c
+++ b/arch/x86/kernel/cpu/common_64.c
@@ -18,6 +18,7 @@
#include <asm/mtrr.h>
#include <asm/mce.h>
#include <asm/pat.h>
+#include <asm/asm.h>
#include <asm/numa.h>
#ifdef CONFIG_X86_LOCAL_APIC
#include <asm/mpspec.h>
@@ -215,6 +216,39 @@ static void __init early_cpu_support_print(void)
}
}
+/*
+ * The NOPL instruction is supposed to exist on all CPUs with
+ * family >= 6, unfortunately, that's not true in practice because
+ * of early VIA chips and (more importantly) broken virtualizers that
+ * are not easy to detect. Hence, probe for it based on first
+ * principles.
+ *
+ * Note: no 64-bit chip is known to lack these, but put the code here
+ * for consistency with 32 bits, and to make it utterly trivial to
+ * diagnose the problem should it ever surface.
+ */
+static void __cpuinit detect_nopl(struct cpuinfo_x86 *c)
+{
+ const u32 nopl_signature = 0x888c53b1; /* Random number */
+ u32 has_nopl = nopl_signature;
+
+ clear_cpu_cap(c, X86_FEATURE_NOPL);
+ if (c->x86 >= 6) {
+ asm volatile("\n"
+ "1: .byte 0x0f,0x1f,0xc0\n" /* nopl %eax */
+ "2:\n"
+ " .section .fixup,\"ax\"\n"
+ "3: xor %0,%0\n"
+ " jmp 2b\n"
+ " .previous\n"
+ _ASM_EXTABLE(1b,3b)
+ : "+a" (has_nopl));
+
+ if (has_nopl == nopl_signature)
+ set_cpu_cap(c, X86_FEATURE_NOPL);
+ }
+}
+
static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c);
void __init early_cpu_init(void)
@@ -313,6 +347,8 @@ static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
c->x86_phys_bits = eax & 0xff;
}
+ detect_nopl(c);
+
if (c->x86_vendor != X86_VENDOR_UNKNOWN &&
cpu_devs[c->x86_vendor]->c_early_init)
cpu_devs[c->x86_vendor]->c_early_init(c);
diff --git a/arch/x86/kernel/cpu/feature_names.c b/arch/x86/kernel/cpu/feature_names.c
index e43ad4a..c901779 100644
--- a/arch/x86/kernel/cpu/feature_names.c
+++ b/arch/x86/kernel/cpu/feature_names.c
@@ -39,7 +39,8 @@ const char * const x86_cap_flags[NCAPINTS*32] = {
NULL, NULL, NULL, NULL,
"constant_tsc", "up", NULL, "arch_perfmon",
"pebs", "bts", NULL, NULL,
- "rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "rep_good", NULL, NULL, NULL,
+ "nopl", NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* Intel-defined (#2) */
diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h
index 762f6a6..9489283 100644
--- a/include/asm-x86/cpufeature.h
+++ b/include/asm-x86/cpufeature.h
@@ -72,14 +72,15 @@
#define X86_FEATURE_UP (3*32+ 9) /* smp kernel running on up */
#define X86_FEATURE_FXSAVE_LEAK (3*32+10) /* FXSAVE leaks FOP/FIP/FOP */
#define X86_FEATURE_ARCH_PERFMON (3*32+11) /* Intel Architectural PerfMon */
-#define X86_FEATURE_PEBS (3*32+12) /* Precise-Event Based Sampling */
-#define X86_FEATURE_BTS (3*32+13) /* Branch Trace Store */
-#define X86_FEATURE_SYSCALL32 (3*32+14) /* syscall in ia32 userspace */
-#define X86_FEATURE_SYSENTER32 (3*32+15) /* sysenter in ia32 userspace */
+#define X86_FEATURE_PEBS (3*32+12) /* Precise-Event Based Sampling */
+#define X86_FEATURE_BTS (3*32+13) /* Branch Trace Store */
+#define X86_FEATURE_SYSCALL32 (3*32+14) /* syscall in ia32 userspace */
+#define X86_FEATURE_SYSENTER32 (3*32+15) /* sysenter in ia32 userspace */
#define X86_FEATURE_REP_GOOD (3*32+16) /* rep microcode works well on this CPU */
#define X86_FEATURE_MFENCE_RDTSC (3*32+17) /* Mfence synchronizes RDTSC */
#define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */
-#define X86_FEATURE_11AP (3*32+19) /* Bad local APIC aka 11AP */
+#define X86_FEATURE_11AP (3*32+19) /* Bad local APIC aka 11AP */
+#define X86_FEATURE_NOPL (3*32+20) /* The NOPL (0F 1F) instructions */
/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
#define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */
diff --git a/include/asm-x86/required-features.h b/include/asm-x86/required-features.h
index adec887..5c2ff4b 100644
--- a/include/asm-x86/required-features.h
+++ b/include/asm-x86/required-features.h
@@ -41,6 +41,12 @@
# define NEED_3DNOW 0
#endif
+#if defined(CONFIG_X86_P6_NOP) || defined(CONFIG_X86_64)
+# define NEED_NOPL (1<<(X86_FEATURE_NOPL & 31))
+#else
+# define NEED_NOPL 0
+#endif
+
#ifdef CONFIG_X86_64
#define NEED_PSE 0
#define NEED_MSR (1<<(X86_FEATURE_MSR & 31))
@@ -67,7 +73,7 @@
#define REQUIRED_MASK1 (NEED_LM|NEED_3DNOW)
#define REQUIRED_MASK2 0
-#define REQUIRED_MASK3 0
+#define REQUIRED_MASK3 (NEED_NOPL)
#define REQUIRED_MASK4 0
#define REQUIRED_MASK5 0
#define REQUIRED_MASK6 0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [git pull] x86 fixes (NOPL issue)
2008-09-06 2:22 [git pull] x86 fixes (NOPL issue) H. Peter Anvin
@ 2008-09-06 3:01 ` Yinghai Lu
2008-09-08 15:02 ` David Sanders
1 sibling, 0 replies; 7+ messages in thread
From: Yinghai Lu @ 2008-09-06 3:01 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: Linus Torvalds, x86 maintainers, LKML
On Fri, Sep 5, 2008 at 7:22 PM, H. Peter Anvin <hpa@zytor.com> wrote:
> Hi Linus,
>
> Please pull:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git x86-fixes-for-linus-2
>
> H. Peter Anvin (4):
> x86: boot: stub out unimplemented CPU feature words
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
> index 80ab20d..0785b3c 100644
> --- a/arch/x86/kernel/cpu/common.c
> +++ b/arch/x86/kernel/cpu/common.c
> @@ -13,6 +13,7 @@
> #include <asm/mtrr.h>
> #include <asm/mce.h>
> #include <asm/pat.h>
> +#include <asm/asm.h>
> #ifdef CONFIG_X86_LOCAL_APIC
> #include <asm/mpspec.h>
> #include <asm/apic.h>
> @@ -341,6 +342,35 @@ static void __init early_cpu_detect(void)
> early_get_cap(c);
> }
>
> +/*
> + * The NOPL instruction is supposed to exist on all CPUs with
> + * family >= 6, unfortunately, that's not true in practice because
> + * of early VIA chips and (more importantly) broken virtualizers that
> + * are not easy to detect. Hence, probe for it based on first
> + * principles.
> + */
if so, should only test on VIA chips.
YH
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [git pull] x86 fixes (NOPL issue)
2008-09-06 2:22 [git pull] x86 fixes (NOPL issue) H. Peter Anvin
2008-09-06 3:01 ` Yinghai Lu
@ 2008-09-08 15:02 ` David Sanders
1 sibling, 0 replies; 7+ messages in thread
From: David Sanders @ 2008-09-08 15:02 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: linux-kernel, Linus Torvalds, x86 maintainers
On Friday 05 September 2008 22:22, H. Peter Anvin wrote:
> This fixes the NOPL issue by detecting it explicitly. I don't have
> access to Virtual PC, but this works on Virtual Server 2005 R2 which
> has the same issue. These changes have been in -tip since August 18,
> so they have had some reasonable degree of exposure already.
>
We it be possible to send these fixes back the stable trees 2.6.26.y and
2.6.25.y?
David
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [git pull] x86 fixes (NOPL issue)
2008-09-06 5:50 ` Yinghai Lu
@ 2008-09-06 5:53 ` H. Peter Anvin
0 siblings, 0 replies; 7+ messages in thread
From: H. Peter Anvin @ 2008-09-06 5:53 UTC (permalink / raw)
To: Yinghai Lu; +Cc: Robert Hancock, Linus Torvalds, x86 maintainers, LKML
Yinghai Lu wrote:
>
> oh, is the one that is going to fix booting with VirtualBox?
>
MS Virtual Server/Virtual PC. VirtualBox seems to be a different
problem, which seems to be related to not respecting interrupt
boundaries properly.
-hpa
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [git pull] x86 fixes (NOPL issue)
2008-09-06 4:07 ` H. Peter Anvin
@ 2008-09-06 5:50 ` Yinghai Lu
2008-09-06 5:53 ` H. Peter Anvin
0 siblings, 1 reply; 7+ messages in thread
From: Yinghai Lu @ 2008-09-06 5:50 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: Robert Hancock, Linus Torvalds, x86 maintainers, LKML
On Fri, Sep 5, 2008 at 9:07 PM, H. Peter Anvin <hpa@zytor.com> wrote:
> Robert Hancock wrote:
>>>
>>> if so, should only test on VIA chips.
>>
>> The virtual CPUs are more of a problem. They can't be distinguished from
>> the real CPU models they are emulating other than by actually testing.
>
> Right, hence the first-principles test. In theory we could just execute the
> test on ALL CPUs, but I have excluded family < 6 simply because there is a
> (very) remote possibility one of them might have used that opcode for
> something completely different.
oh, is the one that is going to fix booting with VirtualBox?
YH
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [git pull] x86 fixes (NOPL issue)
2008-09-06 4:03 ` Robert Hancock
@ 2008-09-06 4:07 ` H. Peter Anvin
2008-09-06 5:50 ` Yinghai Lu
0 siblings, 1 reply; 7+ messages in thread
From: H. Peter Anvin @ 2008-09-06 4:07 UTC (permalink / raw)
To: Robert Hancock; +Cc: Yinghai Lu, Linus Torvalds, x86 maintainers, LKML
Robert Hancock wrote:
>>
>> if so, should only test on VIA chips.
>
> The virtual CPUs are more of a problem. They can't be distinguished from
> the real CPU models they are emulating other than by actually testing.
Right, hence the first-principles test. In theory we could just execute
the test on ALL CPUs, but I have excluded family < 6 simply because
there is a (very) remote possibility one of them might have used that
opcode for something completely different.
-hpa
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [git pull] x86 fixes (NOPL issue)
[not found] ` <fa.uHa5kqSRJ8gj0H3r9BmGsTqRvFI@ifi.uio.no>
@ 2008-09-06 4:03 ` Robert Hancock
2008-09-06 4:07 ` H. Peter Anvin
0 siblings, 1 reply; 7+ messages in thread
From: Robert Hancock @ 2008-09-06 4:03 UTC (permalink / raw)
To: Yinghai Lu; +Cc: H. Peter Anvin, Linus Torvalds, x86 maintainers, LKML
Yinghai Lu wrote:
> On Fri, Sep 5, 2008 at 7:22 PM, H. Peter Anvin <hpa@zytor.com> wrote:
>> Hi Linus,
>>
>> Please pull:
>>
>> git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git x86-fixes-for-linus-2
>>
>> H. Peter Anvin (4):
>> x86: boot: stub out unimplemented CPU feature words
> diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
>> index 80ab20d..0785b3c 100644
>> --- a/arch/x86/kernel/cpu/common.c
>> +++ b/arch/x86/kernel/cpu/common.c
>> @@ -13,6 +13,7 @@
>> #include <asm/mtrr.h>
>> #include <asm/mce.h>
>> #include <asm/pat.h>
>> +#include <asm/asm.h>
>> #ifdef CONFIG_X86_LOCAL_APIC
>> #include <asm/mpspec.h>
>> #include <asm/apic.h>
>> @@ -341,6 +342,35 @@ static void __init early_cpu_detect(void)
>> early_get_cap(c);
>> }
>>
>> +/*
>> + * The NOPL instruction is supposed to exist on all CPUs with
>> + * family >= 6, unfortunately, that's not true in practice because
>> + * of early VIA chips and (more importantly) broken virtualizers that
>> + * are not easy to detect. Hence, probe for it based on first
>> + * principles.
>> + */
>
> if so, should only test on VIA chips.
The virtual CPUs are more of a problem. They can't be distinguished from
the real CPU models they are emulating other than by actually testing.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2008-09-08 15:03 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-09-06 2:22 [git pull] x86 fixes (NOPL issue) H. Peter Anvin
2008-09-06 3:01 ` Yinghai Lu
2008-09-08 15:02 ` David Sanders
[not found] <fa.HDZlnwhQIaOU7WkvenWvWDveLiI@ifi.uio.no>
[not found] ` <fa.uHa5kqSRJ8gj0H3r9BmGsTqRvFI@ifi.uio.no>
2008-09-06 4:03 ` Robert Hancock
2008-09-06 4:07 ` H. Peter Anvin
2008-09-06 5:50 ` Yinghai Lu
2008-09-06 5:53 ` H. Peter Anvin
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 NNTP newsgroup(s).