2012-11-28 19:51:00

by H. Peter Anvin

[permalink] [raw]
Subject: [PATCH 0/8] RFC: Remove 386 support

From: "H. Peter Anvin" <[email protected]>

According to kernel bugzilla 44931:

https://bugzilla.kernel.org/show_bug.cgi?id=44931

... the Linux kernel hasn't actually been compiling for 386 for three
releases now. I have verified that it doesn't, because the 386
fallback code for not having cmpxchg doesn't actually build.

Given that, I thought I'd refresh my patchset for completely removing
386 support and am inviting comments.

The code savings aren't huge, just under 400 lines of code, but this
is all code that very few if any people still care about.

Note that I have no inclination to remove support for 486. 486 and
clones are widely used in embedded applications and there is enough
traffic about them that I am quite sure people do still care about
some versions of those.

Comments appreciated.

arch/x86/Kconfig | 11 ++----
arch/x86/Kconfig.cpu | 73 +++++++++++----------------------------
arch/x86/Makefile_32.cpu | 1 -
arch/x86/include/asm/atomic.h | 16 ---------
arch/x86/include/asm/cmpxchg_32.h | 55 -----------------------------
arch/x86/include/asm/cpufeature.h | 6 ----
arch/x86/include/asm/futex.h | 12 -------
arch/x86/include/asm/local.h | 18 +---------
arch/x86/include/asm/module.h | 2 --
arch/x86/include/asm/percpu.h | 3 --
arch/x86/include/asm/processor.h | 29 ++++++++++------
arch/x86/include/asm/swab.h | 29 ++--------------
arch/x86/include/asm/tlbflush.h | 3 --
arch/x86/include/asm/uaccess.h | 42 ----------------------
arch/x86/kernel/cpu/amd.c | 3 --
arch/x86/kernel/cpu/bugs.c | 41 ++--------------------
arch/x86/kernel/cpu/intel.c | 4 ---
arch/x86/lib/Makefile | 1 -
arch/x86/lib/cmpxchg.c | 54 -----------------------------
arch/x86/lib/usercopy_32.c | 57 ------------------------------
arch/x86/mm/init_32.c | 5 +--
arch/x86/mm/tlb.c | 8 ++---
arch/x86/um/Kconfig | 2 +-
arch/x86/xen/Kconfig | 2 +-
24 files changed, 52 insertions(+), 425 deletions(-)


2012-11-28 19:51:00

by H. Peter Anvin

[permalink] [raw]
Subject: [PATCH 4/8] x86, 386 removal: Remove CONFIG_BSWAP

From: "H. Peter Anvin" <[email protected]>

All 486+ CPUs support BSWAP, so remove the fallback 386 support
code.

Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/Kconfig.cpu | 4 ----
arch/x86/include/asm/futex.h | 12 ------------
arch/x86/include/asm/swab.h | 29 ++---------------------------
arch/x86/kernel/cpu/bugs.c | 13 ++-----------
4 files changed, 4 insertions(+), 54 deletions(-)

diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 52955ee..8e5867c 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -332,10 +332,6 @@ config X86_INVLPG
def_bool y
depends on X86_32

-config X86_BSWAP
- def_bool y
- depends on X86_32
-
config X86_POPAD_OK
def_bool y
depends on X86_32
diff --git a/arch/x86/include/asm/futex.h b/arch/x86/include/asm/futex.h
index f373046..be27ba1 100644
--- a/arch/x86/include/asm/futex.h
+++ b/arch/x86/include/asm/futex.h
@@ -55,12 +55,6 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
return -EFAULT;

-#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_BSWAP)
- /* Real i386 machines can only support FUTEX_OP_SET */
- if (op != FUTEX_OP_SET && boot_cpu_data.x86 == 3)
- return -ENOSYS;
-#endif
-
pagefault_disable();

switch (op) {
@@ -118,12 +112,6 @@ static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
{
int ret = 0;

-#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_BSWAP)
- /* Real i386 machines have no cmpxchg instruction */
- if (boot_cpu_data.x86 == 3)
- return -ENOSYS;
-#endif
-
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
return -EFAULT;

diff --git a/arch/x86/include/asm/swab.h b/arch/x86/include/asm/swab.h
index 557cd9f..7f235c7 100644
--- a/arch/x86/include/asm/swab.h
+++ b/arch/x86/include/asm/swab.h
@@ -6,22 +6,7 @@

static inline __attribute_const__ __u32 __arch_swab32(__u32 val)
{
-#ifdef __i386__
-# ifdef CONFIG_X86_BSWAP
- asm("bswap %0" : "=r" (val) : "0" (val));
-# else
- asm("xchgb %b0,%h0\n\t" /* swap lower bytes */
- "rorl $16,%0\n\t" /* swap words */
- "xchgb %b0,%h0" /* swap higher bytes */
- : "=q" (val)
- : "0" (val));
-# endif
-
-#else /* __i386__ */
- asm("bswapl %0"
- : "=r" (val)
- : "0" (val));
-#endif
+ asm("bswapl %0" : "=r" (val) : "0" (val));
return val;
}
#define __arch_swab32 __arch_swab32
@@ -37,22 +22,12 @@ static inline __attribute_const__ __u64 __arch_swab64(__u64 val)
__u64 u;
} v;
v.u = val;
-# ifdef CONFIG_X86_BSWAP
asm("bswapl %0 ; bswapl %1 ; xchgl %0,%1"
: "=r" (v.s.a), "=r" (v.s.b)
: "0" (v.s.a), "1" (v.s.b));
-# else
- v.s.a = __arch_swab32(v.s.a);
- v.s.b = __arch_swab32(v.s.b);
- asm("xchgl %0,%1"
- : "=r" (v.s.a), "=r" (v.s.b)
- : "0" (v.s.a), "1" (v.s.b));
-# endif
return v.u;
#else /* __i386__ */
- asm("bswapq %0"
- : "=r" (val)
- : "0" (val));
+ asm("bswapq %0" : "=r" (val) : "0" (val));
return val;
#endif
}
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index d0e910d..0cd07cc 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -136,24 +136,15 @@ static void __init check_popad(void)
/*
* Check whether we are able to run this kernel safely on SMP.
*
- * - In order to run on a i386, we need to be compiled for i386
- * (for due to lack of "invlpg" and working WP on a i386)
+ * - i386 is no longer supported.
* - In order to run on anything without a TSC, we need to be
* compiled for a i486.
*/

static void __init check_config(void)
{
-/*
- * We'd better not be a i386 if we're configured to use some
- * i486+ only features! (WP works in supervisor mode and the
- * new "invlpg" and "bswap" instructions)
- */
-#if defined(CONFIG_X86_WP_WORKS_OK) || defined(CONFIG_X86_INVLPG) || \
- defined(CONFIG_X86_BSWAP)
- if (boot_cpu_data.x86 == 3)
+ if (boot_cpu_data.x86 < 4)
panic("Kernel requires i486+ for 'invlpg' and other features");
-#endif
}


--
1.7.11.7

2012-11-28 19:50:59

by H. Peter Anvin

[permalink] [raw]
Subject: [PATCH 7/8] x86, 386 removal: Remove CONFIG_X86_POPAD_OK

From: "H. Peter Anvin" <[email protected]>

The check_popad() routine tested for a 386-specific bug, and never
actually did anything useful with it anyway other than print a
message.

Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/Kconfig.cpu | 4 ----
arch/x86/kernel/cpu/bugs.c | 28 ----------------------------
2 files changed, 32 deletions(-)

diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 159ee9c..423db71 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -325,10 +325,6 @@ config X86_INVD_BUG
def_bool y
depends on M486

-config X86_POPAD_OK
- def_bool y
- depends on X86_32
-
config X86_ALIGNMENT_16
def_bool y
depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 0cd07cc..92dfec9 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -107,33 +107,6 @@ static void __init check_hlt(void)
}

/*
- * Most 386 processors have a bug where a POPAD can lock the
- * machine even from user space.
- */
-
-static void __init check_popad(void)
-{
-#ifndef CONFIG_X86_POPAD_OK
- int res, inp = (int) &res;
-
- pr_info("Checking for popad bug... ");
- __asm__ __volatile__(
- "movl $12345678,%%eax; movl $0,%%edi; pusha; popa; movl (%%edx,%%edi),%%ecx "
- : "=&a" (res)
- : "d" (inp)
- : "ecx", "edi");
- /*
- * If this fails, it means that any user program may lock the
- * CPU hard. Too bad.
- */
- if (res != 12345678)
- pr_cont("Buggy\n");
- else
- pr_cont("OK\n");
-#endif
-}
-
-/*
* Check whether we are able to run this kernel safely on SMP.
*
* - i386 is no longer supported.
@@ -157,7 +130,6 @@ void __init check_bugs(void)
#endif
check_config();
check_hlt();
- check_popad();
init_utsname()->machine[1] =
'0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86);
alternative_instructions();
--
1.7.11.7

2012-11-28 19:50:58

by H. Peter Anvin

[permalink] [raw]
Subject: [PATCH 2/8] x86, 386 removal: Remove CONFIG_CMPXCHG

From: "H. Peter Anvin" <[email protected]>

All 486+ CPUs support CMPXCHG, so remove the fallback 386 support
code.

Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/Kconfig.cpu | 3 ---
arch/x86/include/asm/cmpxchg_32.h | 55 ---------------------------------------
arch/x86/include/asm/percpu.h | 3 ---
arch/x86/lib/Makefile | 1 -
arch/x86/lib/cmpxchg.c | 54 --------------------------------------
arch/x86/xen/Kconfig | 2 +-
6 files changed, 1 insertion(+), 117 deletions(-)
delete mode 100644 arch/x86/lib/cmpxchg.c

diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 36a07eb..1290a69 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -297,9 +297,6 @@ config X86_INTERNODE_CACHE_SHIFT
default "12" if X86_VSMP
default X86_L1_CACHE_SHIFT

-config X86_CMPXCHG
- def_bool y
-
config X86_L1_CACHE_SHIFT
int
default "7" if MPENTIUM4 || MPSC
diff --git a/arch/x86/include/asm/cmpxchg_32.h b/arch/x86/include/asm/cmpxchg_32.h
index 53f4b21..f8bf2ee 100644
--- a/arch/x86/include/asm/cmpxchg_32.h
+++ b/arch/x86/include/asm/cmpxchg_32.h
@@ -34,9 +34,7 @@ static inline void set_64bit(volatile u64 *ptr, u64 value)
: "memory");
}

-#ifdef CONFIG_X86_CMPXCHG
#define __HAVE_ARCH_CMPXCHG 1
-#endif

#ifdef CONFIG_X86_CMPXCHG64
#define cmpxchg64(ptr, o, n) \
@@ -73,59 +71,6 @@ static inline u64 __cmpxchg64_local(volatile u64 *ptr, u64 old, u64 new)
return prev;
}

-#ifndef CONFIG_X86_CMPXCHG
-/*
- * Building a kernel capable running on 80386. It may be necessary to
- * simulate the cmpxchg on the 80386 CPU. For that purpose we define
- * a function for each of the sizes we support.
- */
-
-extern unsigned long cmpxchg_386_u8(volatile void *, u8, u8);
-extern unsigned long cmpxchg_386_u16(volatile void *, u16, u16);
-extern unsigned long cmpxchg_386_u32(volatile void *, u32, u32);
-
-static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old,
- unsigned long new, int size)
-{
- switch (size) {
- case 1:
- return cmpxchg_386_u8(ptr, old, new);
- case 2:
- return cmpxchg_386_u16(ptr, old, new);
- case 4:
- return cmpxchg_386_u32(ptr, old, new);
- }
- return old;
-}
-
-#define cmpxchg(ptr, o, n) \
-({ \
- __typeof__(*(ptr)) __ret; \
- if (likely(boot_cpu_data.x86 > 3)) \
- __ret = (__typeof__(*(ptr)))__cmpxchg((ptr), \
- (unsigned long)(o), (unsigned long)(n), \
- sizeof(*(ptr))); \
- else \
- __ret = (__typeof__(*(ptr)))cmpxchg_386((ptr), \
- (unsigned long)(o), (unsigned long)(n), \
- sizeof(*(ptr))); \
- __ret; \
-})
-#define cmpxchg_local(ptr, o, n) \
-({ \
- __typeof__(*(ptr)) __ret; \
- if (likely(boot_cpu_data.x86 > 3)) \
- __ret = (__typeof__(*(ptr)))__cmpxchg_local((ptr), \
- (unsigned long)(o), (unsigned long)(n), \
- sizeof(*(ptr))); \
- else \
- __ret = (__typeof__(*(ptr)))cmpxchg_386((ptr), \
- (unsigned long)(o), (unsigned long)(n), \
- sizeof(*(ptr))); \
- __ret; \
-})
-#endif
-
#ifndef CONFIG_X86_CMPXCHG64
/*
* Building a kernel capable running on 80386 and 80486. It may be necessary
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index 1104afa..0da5200 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -406,7 +406,6 @@ do { \
#define this_cpu_xchg_2(pcp, nval) percpu_xchg_op(pcp, nval)
#define this_cpu_xchg_4(pcp, nval) percpu_xchg_op(pcp, nval)

-#ifndef CONFIG_M386
#define __this_cpu_add_return_1(pcp, val) percpu_add_return_op(pcp, val)
#define __this_cpu_add_return_2(pcp, val) percpu_add_return_op(pcp, val)
#define __this_cpu_add_return_4(pcp, val) percpu_add_return_op(pcp, val)
@@ -421,8 +420,6 @@ do { \
#define this_cpu_cmpxchg_2(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
#define this_cpu_cmpxchg_4(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)

-#endif /* !CONFIG_M386 */
-
#ifdef CONFIG_X86_CMPXCHG64
#define percpu_cmpxchg8b_double(pcp1, pcp2, o1, o2, n1, n2) \
({ \
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index b00f678..96b2c66 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -32,7 +32,6 @@ ifeq ($(CONFIG_X86_32),y)
lib-y += checksum_32.o
lib-y += strstr_32.o
lib-y += string_32.o
- lib-y += cmpxchg.o
ifneq ($(CONFIG_X86_CMPXCHG64),y)
lib-y += cmpxchg8b_emu.o atomic64_386_32.o
endif
diff --git a/arch/x86/lib/cmpxchg.c b/arch/x86/lib/cmpxchg.c
deleted file mode 100644
index 5d619f6..0000000
--- a/arch/x86/lib/cmpxchg.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * cmpxchg*() fallbacks for CPU not supporting these instructions
- */
-
-#include <linux/kernel.h>
-#include <linux/smp.h>
-#include <linux/module.h>
-
-#ifndef CONFIG_X86_CMPXCHG
-unsigned long cmpxchg_386_u8(volatile void *ptr, u8 old, u8 new)
-{
- u8 prev;
- unsigned long flags;
-
- /* Poor man's cmpxchg for 386. Unsuitable for SMP */
- local_irq_save(flags);
- prev = *(u8 *)ptr;
- if (prev == old)
- *(u8 *)ptr = new;
- local_irq_restore(flags);
- return prev;
-}
-EXPORT_SYMBOL(cmpxchg_386_u8);
-
-unsigned long cmpxchg_386_u16(volatile void *ptr, u16 old, u16 new)
-{
- u16 prev;
- unsigned long flags;
-
- /* Poor man's cmpxchg for 386. Unsuitable for SMP */
- local_irq_save(flags);
- prev = *(u16 *)ptr;
- if (prev == old)
- *(u16 *)ptr = new;
- local_irq_restore(flags);
- return prev;
-}
-EXPORT_SYMBOL(cmpxchg_386_u16);
-
-unsigned long cmpxchg_386_u32(volatile void *ptr, u32 old, u32 new)
-{
- u32 prev;
- unsigned long flags;
-
- /* Poor man's cmpxchg for 386. Unsuitable for SMP */
- local_irq_save(flags);
- prev = *(u32 *)ptr;
- if (prev == old)
- *(u32 *)ptr = new;
- local_irq_restore(flags);
- return prev;
-}
-EXPORT_SYMBOL(cmpxchg_386_u32);
-#endif
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index fdce49c..9a6775c 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -7,7 +7,7 @@ config XEN
select PARAVIRT
select PARAVIRT_CLOCK
depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS)
- depends on X86_CMPXCHG && X86_TSC
+ depends on X86_TSC
help
This is the Linux Xen port. Enabling this will allow the
kernel to boot in a paravirtualized environment under the
--
1.7.11.7

2012-11-28 19:51:48

by H. Peter Anvin

[permalink] [raw]
Subject: [PATCH 3/8] x86, 386 removal: Remove CONFIG_XADD

From: "H. Peter Anvin" <[email protected]>

All 486+ CPUs support CMPXCHG, so remove the fallback 386 support
code.

Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/Kconfig | 5 -----
arch/x86/Kconfig.cpu | 3 ---
arch/x86/include/asm/atomic.h | 16 ----------------
arch/x86/include/asm/local.h | 18 +-----------------
arch/x86/um/Kconfig | 2 +-
5 files changed, 2 insertions(+), 42 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index a1a6627..631b298 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -171,13 +171,8 @@ config ARCH_MAY_HAVE_PC_FDC
def_bool y
depends on ISA_DMA_API

-config RWSEM_GENERIC_SPINLOCK
- def_bool y
- depends on !X86_XADD
-
config RWSEM_XCHGADD_ALGORITHM
def_bool y
- depends on X86_XADD

config GENERIC_CALIBRATE_DELAY
def_bool y
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 1290a69..52955ee 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -304,9 +304,6 @@ config X86_L1_CACHE_SHIFT
default "4" if MELAN || M486 || MGEODEGX1
default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX

-config X86_XADD
- def_bool y
-
config X86_PPRO_FENCE
bool "PentiumPro memory ordering errata workaround"
depends on M686 || M586MMX || M586TSC || M586 || M486 || MGEODEGX1
diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h
index b6c3b82..722aa3b 100644
--- a/arch/x86/include/asm/atomic.h
+++ b/arch/x86/include/asm/atomic.h
@@ -172,23 +172,7 @@ static inline int atomic_add_negative(int i, atomic_t *v)
*/
static inline int atomic_add_return(int i, atomic_t *v)
{
-#ifdef CONFIG_M386
- int __i;
- unsigned long flags;
- if (unlikely(boot_cpu_data.x86 <= 3))
- goto no_xadd;
-#endif
- /* Modern 486+ processor */
return i + xadd(&v->counter, i);
-
-#ifdef CONFIG_M386
-no_xadd: /* Legacy 386 processor */
- raw_local_irq_save(flags);
- __i = atomic_read(v);
- atomic_set(v, i + __i);
- raw_local_irq_restore(flags);
- return i + __i;
-#endif
}

/**
diff --git a/arch/x86/include/asm/local.h b/arch/x86/include/asm/local.h
index c8bed0d..2d89e39 100644
--- a/arch/x86/include/asm/local.h
+++ b/arch/x86/include/asm/local.h
@@ -124,27 +124,11 @@ static inline int local_add_negative(long i, local_t *l)
*/
static inline long local_add_return(long i, local_t *l)
{
- long __i;
-#ifdef CONFIG_M386
- unsigned long flags;
- if (unlikely(boot_cpu_data.x86 <= 3))
- goto no_xadd;
-#endif
- /* Modern 486+ processor */
- __i = i;
+ long __i = i;
asm volatile(_ASM_XADD "%0, %1;"
: "+r" (i), "+m" (l->a.counter)
: : "memory");
return i + __i;
-
-#ifdef CONFIG_M386
-no_xadd: /* Legacy 386 processor */
- local_irq_save(flags);
- __i = local_read(l);
- local_set(l, i + __i);
- local_irq_restore(flags);
- return i + __i;
-#endif
}

static inline long local_sub_return(long i, local_t *l)
diff --git a/arch/x86/um/Kconfig b/arch/x86/um/Kconfig
index 0761175..b0c30da 100644
--- a/arch/x86/um/Kconfig
+++ b/arch/x86/um/Kconfig
@@ -31,7 +31,7 @@ config X86_64
select MODULES_USE_ELF_RELA

config RWSEM_XCHGADD_ALGORITHM
- def_bool X86_XADD && 64BIT
+ def_bool 64BIT

config RWSEM_GENERIC_SPINLOCK
def_bool !RWSEM_XCHGADD_ALGORITHM
--
1.7.11.7

2012-11-28 19:51:46

by H. Peter Anvin

[permalink] [raw]
Subject: [PATCH 8/8] x86, cleanups: Simplify sync_core() in the case of no CPUID

From: "H. Peter Anvin" <[email protected]>

Simplify the implementation of sync_core() for the case where we may
not have the CPUID instruction available.

Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/include/asm/processor.h | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 9a4ee46..b381df7 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -673,17 +673,24 @@ static inline void sync_core(void)
int tmp;

#ifdef CONFIG_M486
- if (boot_cpu_data.x86 < 5)
- /* There is no speculative execution.
- * jmp is a barrier to prefetching. */
- asm volatile("jmp 1f\n1:\n" ::: "memory");
- else
+ /*
+ * Do a CPUID if available, otherwise do a jump. The jump
+ * can conveniently enough be the jump around CPUID.
+ */
+ asm volatile("cmpl %2,%1\n\t"
+ "jl 1f\n\t"
+ "cpuid\n"
+ "1:"
+ : "=a" (tmp)
+ : "rm" (boot_cpu_data.cpuid_level), "ri" (0), "0" (1)
+ : "ebx", "ecx", "edx", "memory");
+#else
+ /* cpuid is a barrier to speculative execution.
+ * Prefetched instructions are automatically
+ * invalidated when modified. */
+ asm volatile("cpuid" : "=a" (tmp) : "0" (1)
+ : "ebx", "ecx", "edx", "memory");
#endif
- /* cpuid is a barrier to speculative execution.
- * Prefetched instructions are automatically
- * invalidated when modified. */
- asm volatile("cpuid" : "=a" (tmp) : "0" (1)
- : "ebx", "ecx", "edx", "memory");
}

static inline void __monitor(const void *eax, unsigned long ecx,
--
1.7.11.7

2012-11-28 19:52:35

by H. Peter Anvin

[permalink] [raw]
Subject: [PATCH 6/8] x86, 386 removal: Remove CONFIG_X86_WP_WORKS_OK

From: "H. Peter Anvin" <[email protected]>

All 486+ CPUs support WP in supervisor mode, so remove the fallback
386 support code.

Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/Kconfig.cpu | 3 ---
arch/x86/include/asm/uaccess.h | 42 -------------------------------
arch/x86/lib/usercopy_32.c | 57 ------------------------------------------
arch/x86/mm/init_32.c | 5 +---
4 files changed, 1 insertion(+), 106 deletions(-)

diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index d3bdc18..159ee9c 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -325,9 +325,6 @@ config X86_INVD_BUG
def_bool y
depends on M486

-config X86_WP_WORKS_OK
- def_bool y
-
config X86_POPAD_OK
def_bool y
depends on X86_32
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index 7ccf8d1..1709801 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -237,8 +237,6 @@ extern void __put_user_2(void);
extern void __put_user_4(void);
extern void __put_user_8(void);

-#ifdef CONFIG_X86_WP_WORKS_OK
-
/**
* put_user: - Write a simple value into user space.
* @x: Value to copy to user space.
@@ -326,29 +324,6 @@ do { \
} \
} while (0)

-#else
-
-#define __put_user_size(x, ptr, size, retval, errret) \
-do { \
- __typeof__(*(ptr))__pus_tmp = x; \
- retval = 0; \
- \
- if (unlikely(__copy_to_user_ll(ptr, &__pus_tmp, size) != 0)) \
- retval = errret; \
-} while (0)
-
-#define put_user(x, ptr) \
-({ \
- int __ret_pu; \
- __typeof__(*(ptr))__pus_tmp = x; \
- __ret_pu = 0; \
- if (unlikely(__copy_to_user_ll(ptr, &__pus_tmp, \
- sizeof(*(ptr))) != 0)) \
- __ret_pu = -EFAULT; \
- __ret_pu; \
-})
-#endif
-
#ifdef CONFIG_X86_32
#define __get_user_asm_u64(x, ptr, retval, errret) (x) = __get_user_bad()
#define __get_user_asm_ex_u64(x, ptr) (x) = __get_user_bad()
@@ -543,29 +518,12 @@ struct __large_struct { unsigned long buf[100]; };
(x) = (__force __typeof__(*(ptr)))__gue_val; \
} while (0)

-#ifdef CONFIG_X86_WP_WORKS_OK
-
#define put_user_try uaccess_try
#define put_user_catch(err) uaccess_catch(err)

#define put_user_ex(x, ptr) \
__put_user_size_ex((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))

-#else /* !CONFIG_X86_WP_WORKS_OK */
-
-#define put_user_try do { \
- int __uaccess_err = 0;
-
-#define put_user_catch(err) \
- (err) |= __uaccess_err; \
-} while (0)
-
-#define put_user_ex(x, ptr) do { \
- __uaccess_err |= __put_user(x, ptr); \
-} while (0)
-
-#endif /* CONFIG_X86_WP_WORKS_OK */
-
extern unsigned long
copy_from_user_nmi(void *to, const void __user *from, unsigned long n);
extern __must_check long
diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c
index 98f6d6b6..f0312d7 100644
--- a/arch/x86/lib/usercopy_32.c
+++ b/arch/x86/lib/usercopy_32.c
@@ -570,63 +570,6 @@ do { \
unsigned long __copy_to_user_ll(void __user *to, const void *from,
unsigned long n)
{
-#ifndef CONFIG_X86_WP_WORKS_OK
- if (unlikely(boot_cpu_data.wp_works_ok == 0) &&
- ((unsigned long)to) < TASK_SIZE) {
- /*
- * When we are in an atomic section (see
- * mm/filemap.c:file_read_actor), return the full
- * length to take the slow path.
- */
- if (in_atomic())
- return n;
-
- /*
- * CPU does not honor the WP bit when writing
- * from supervisory mode, and due to preemption or SMP,
- * the page tables can change at any time.
- * Do it manually. Manfred <[email protected]>
- */
- while (n) {
- unsigned long offset = ((unsigned long)to)%PAGE_SIZE;
- unsigned long len = PAGE_SIZE - offset;
- int retval;
- struct page *pg;
- void *maddr;
-
- if (len > n)
- len = n;
-
-survive:
- down_read(&current->mm->mmap_sem);
- retval = get_user_pages(current, current->mm,
- (unsigned long)to, 1, 1, 0, &pg, NULL);
-
- if (retval == -ENOMEM && is_global_init(current)) {
- up_read(&current->mm->mmap_sem);
- congestion_wait(BLK_RW_ASYNC, HZ/50);
- goto survive;
- }
-
- if (retval != 1) {
- up_read(&current->mm->mmap_sem);
- break;
- }
-
- maddr = kmap_atomic(pg);
- memcpy(maddr + offset, from, len);
- kunmap_atomic(maddr);
- set_page_dirty_lock(pg);
- put_page(pg);
- up_read(&current->mm->mmap_sem);
-
- from += len;
- to += len;
- n -= len;
- }
- return n;
- }
-#endif
stac();
if (movsl_is_ok(to, from, n))
__copy_user(to, from, n);
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 11a5800..745d66b 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -715,10 +715,7 @@ static void __init test_wp_bit(void)

if (!boot_cpu_data.wp_works_ok) {
printk(KERN_CONT "No.\n");
-#ifdef CONFIG_X86_WP_WORKS_OK
- panic(
- "This kernel doesn't support CPU's with broken WP. Recompile it for a 386!");
-#endif
+ panic("Linux doesn't support CPUs with broken WP.");
} else {
printk(KERN_CONT "Ok.\n");
}
--
1.7.11.7

2012-11-28 19:52:54

by H. Peter Anvin

[permalink] [raw]
Subject: [PATCH 5/8] x86, 386 removal: Remove CONFIG_INVLPG

From: "H. Peter Anvin" <[email protected]>

All 486+ CPUs support INVLPG, so remove the fallback 386 support
code.

Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/Kconfig.cpu | 4 ----
arch/x86/include/asm/cpufeature.h | 6 ------
arch/x86/include/asm/tlbflush.h | 3 ---
arch/x86/kernel/cpu/amd.c | 3 ---
arch/x86/kernel/cpu/intel.c | 4 ----
arch/x86/mm/tlb.c | 8 +++-----
6 files changed, 3 insertions(+), 25 deletions(-)

diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 8e5867c..d3bdc18 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -328,10 +328,6 @@ config X86_INVD_BUG
config X86_WP_WORKS_OK
def_bool y

-config X86_INVLPG
- def_bool y
- depends on X86_32
-
config X86_POPAD_OK
def_bool y
depends on X86_32
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 8c297aa..ff8dd62 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -312,12 +312,6 @@ extern const char * const x86_power_flags[32];
#define cpu_has_cx16 boot_cpu_has(X86_FEATURE_CX16)
#define cpu_has_eager_fpu boot_cpu_has(X86_FEATURE_EAGER_FPU)

-#if defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_64)
-# define cpu_has_invlpg 1
-#else
-# define cpu_has_invlpg (boot_cpu_data.x86 > 3)
-#endif
-
#ifdef CONFIG_X86_64

#undef cpu_has_vme
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 74a4433..0fee48e 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -56,10 +56,7 @@ static inline void __flush_tlb_all(void)

static inline void __flush_tlb_one(unsigned long addr)
{
- if (cpu_has_invlpg)
__flush_tlb_single(addr);
- else
- __flush_tlb();
}

#define TLB_FLUSH_ALL -1UL
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 1b7d165..a025d8c 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -753,9 +753,6 @@ static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c,

static void __cpuinit cpu_set_tlb_flushall_shift(struct cpuinfo_x86 *c)
{
- if (!cpu_has_invlpg)
- return;
-
tlb_flushall_shift = 5;

if (c->x86 <= 0x11)
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 198e019..fcaabd0 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -612,10 +612,6 @@ static void __cpuinit intel_tlb_lookup(const unsigned char desc)

static void __cpuinit intel_tlb_flushall_shift_set(struct cpuinfo_x86 *c)
{
- if (!cpu_has_invlpg) {
- tlb_flushall_shift = -1;
- return;
- }
switch ((c->x86 << 8) + c->x86_model) {
case 0x60f: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
case 0x616: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 60f926c..13a6b29 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -104,7 +104,7 @@ static void flush_tlb_func(void *info)
return;

if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK) {
- if (f->flush_end == TLB_FLUSH_ALL || !cpu_has_invlpg)
+ if (f->flush_end == TLB_FLUSH_ALL)
local_flush_tlb();
else if (!f->flush_end)
__flush_tlb_single(f->flush_start);
@@ -337,10 +337,8 @@ static const struct file_operations fops_tlbflush = {

static int __cpuinit create_tlb_flushall_shift(void)
{
- if (cpu_has_invlpg) {
- debugfs_create_file("tlb_flushall_shift", S_IRUSR | S_IWUSR,
- arch_debugfs_dir, NULL, &fops_tlbflush);
- }
+ debugfs_create_file("tlb_flushall_shift", S_IRUSR | S_IWUSR,
+ arch_debugfs_dir, NULL, &fops_tlbflush);
return 0;
}
late_initcall(create_tlb_flushall_shift);
--
1.7.11.7

2012-11-28 19:52:52

by H. Peter Anvin

[permalink] [raw]
Subject: [PATCH 1/8] x86, 386 removal: Remove CONFIG_M386 from Kconfig

From: "H. Peter Anvin" <[email protected]>

Remove the CONFIG_M386 symbol from Kconfig so that it cannot be
selected.

Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/Kconfig | 6 ++---
arch/x86/Kconfig.cpu | 58 ++++++++++++++++------------------------
arch/x86/Makefile_32.cpu | 1 -
arch/x86/include/asm/module.h | 2 --
arch/x86/include/asm/processor.h | 2 +-
5 files changed, 27 insertions(+), 42 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 46c3bff..a1a6627 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -69,8 +69,8 @@ config X86
select HAVE_PERF_USER_STACK_DUMP
select HAVE_DEBUG_KMEMLEAK
select ANON_INODES
- select HAVE_ALIGNED_STRUCT_PAGE if SLUB && !M386
- select HAVE_CMPXCHG_LOCAL if !M386
+ select HAVE_ALIGNED_STRUCT_PAGE if SLUB
+ select HAVE_CMPXCHG_LOCAL
select HAVE_CMPXCHG_DOUBLE
select HAVE_ARCH_KMEMCHECK
select HAVE_USER_RETURN_NOTIFIER
@@ -1100,7 +1100,7 @@ config HIGHMEM4G

config HIGHMEM64G
bool "64GB"
- depends on !M386 && !M486
+ depends on !M486
select X86_PAE
---help---
Select this if you have a 32-bit processor and more than 4
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index f3b86d0..36a07eb 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -4,23 +4,24 @@ choice
default M686 if X86_32
default GENERIC_CPU if X86_64

-config M386
- bool "386"
- depends on X86_32 && !UML
+config M486
+ bool "486"
+ depends on X86_32
---help---
- This is the processor type of your CPU. This information is used for
- optimizing purposes. In order to compile a kernel that can run on
- all x86 CPU types (albeit not optimally fast), you can specify
- "386" here.
+ This is the processor type of your CPU. This information is
+ used for optimizing purposes. In order to compile a kernel
+ that can run on all supported x86 CPU types (albeit not
+ optimally fast), you can specify "486" here.
+
+ Note that the 386 is no longer supported, this includes
+ AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI 486DLC/DLC2,
+ and UMC 486SX-S.

The kernel will not necessarily run on earlier architectures than
the one you have chosen, e.g. a Pentium optimized kernel will run on
a PPro, but not necessarily on a i486.

Here are the settings recommended for greatest speed:
- - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI
- 486DLC/DLC2, and UMC 486SX-S. Only "386" kernels will run on a 386
- class machine.
- "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or
SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
- "586" for generic Pentium CPUs lacking the TSC
@@ -43,16 +44,7 @@ config M386
- "VIA C3-2" for VIA C3-2 "Nehemiah" (model 9 and above).
- "VIA C7" for VIA C7.

- If you don't know what to do, choose "386".
-
-config M486
- bool "486"
- depends on X86_32
- ---help---
- Select this for a 486 series processor, either Intel or one of the
- compatible processors from AMD, Cyrix, IBM, or Intel. Includes DX,
- DX2, and DX4 variants; also SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or
- U5S.
+ If you don't know what to do, choose "486".

config M586
bool "586/K5/5x86/6x86/6x86MX"
@@ -307,22 +299,20 @@ config X86_INTERNODE_CACHE_SHIFT

config X86_CMPXCHG
def_bool y
- depends on X86_64 || (X86_32 && !M386)

config X86_L1_CACHE_SHIFT
int
default "7" if MPENTIUM4 || MPSC
default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU
- default "4" if MELAN || M486 || M386 || MGEODEGX1
+ default "4" if MELAN || M486 || MGEODEGX1
default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX

config X86_XADD
def_bool y
- depends on !M386

config X86_PPRO_FENCE
bool "PentiumPro memory ordering errata workaround"
- depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1
+ depends on M686 || M586MMX || M586TSC || M586 || M486 || MGEODEGX1
---help---
Old PentiumPro multiprocessor systems had errata that could cause
memory operations to violate the x86 ordering standard in rare cases.
@@ -335,27 +325,26 @@ config X86_PPRO_FENCE

config X86_F00F_BUG
def_bool y
- depends on M586MMX || M586TSC || M586 || M486 || M386
+ depends on M586MMX || M586TSC || M586 || M486

config X86_INVD_BUG
def_bool y
- depends on M486 || M386
+ depends on M486

config X86_WP_WORKS_OK
def_bool y
- depends on !M386

config X86_INVLPG
def_bool y
- depends on X86_32 && !M386
+ depends on X86_32

config X86_BSWAP
def_bool y
- depends on X86_32 && !M386
+ depends on X86_32

config X86_POPAD_OK
def_bool y
- depends on X86_32 && !M386
+ depends on X86_32

config X86_ALIGNMENT_16
def_bool y
@@ -412,12 +401,11 @@ config X86_MINIMUM_CPU_FAMILY
default "64" if X86_64
default "6" if X86_32 && X86_P6_NOP
default "5" if X86_32 && X86_CMPXCHG64
- default "4" if X86_32 && (X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK)
- default "3"
+ default "4"

config X86_DEBUGCTLMSR
def_bool y
- depends on !(MK6 || MWINCHIPC6 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 || M486 || M386) && !UML
+ depends on !(MK6 || MWINCHIPC6 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 || M486) && !UML

menuconfig PROCESSOR_SELECT
bool "Supported processor vendors" if EXPERT
@@ -441,7 +429,7 @@ config CPU_SUP_INTEL
config CPU_SUP_CYRIX_32
default y
bool "Support Cyrix processors" if PROCESSOR_SELECT
- depends on M386 || M486 || M586 || M586TSC || M586MMX || (EXPERT && !64BIT)
+ depends on M486 || M586 || M586TSC || M586MMX || (EXPERT && !64BIT)
---help---
This enables detection, tunings and quirks for Cyrix processors

@@ -495,7 +483,7 @@ config CPU_SUP_TRANSMETA_32
config CPU_SUP_UMC_32
default y
bool "Support UMC processors" if PROCESSOR_SELECT
- depends on M386 || M486 || (EXPERT && !64BIT)
+ depends on M486 || (EXPERT && !64BIT)
---help---
This enables detection, tunings and quirks for UMC processors

diff --git a/arch/x86/Makefile_32.cpu b/arch/x86/Makefile_32.cpu
index 86cee7b..6647ed4 100644
--- a/arch/x86/Makefile_32.cpu
+++ b/arch/x86/Makefile_32.cpu
@@ -10,7 +10,6 @@ tune = $(call cc-option,-mcpu=$(1),$(2))
endif

align := $(cc-option-align)
-cflags-$(CONFIG_M386) += -march=i386
cflags-$(CONFIG_M486) += -march=i486
cflags-$(CONFIG_M586) += -march=i586
cflags-$(CONFIG_M586TSC) += -march=i586
diff --git a/arch/x86/include/asm/module.h b/arch/x86/include/asm/module.h
index 9eae775..e3b7819 100644
--- a/arch/x86/include/asm/module.h
+++ b/arch/x86/include/asm/module.h
@@ -5,8 +5,6 @@

#ifdef CONFIG_X86_64
/* X86_64 does not define MODULE_PROC_FAMILY */
-#elif defined CONFIG_M386
-#define MODULE_PROC_FAMILY "386 "
#elif defined CONFIG_M486
#define MODULE_PROC_FAMILY "486 "
#elif defined CONFIG_M586
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index ad1fc85..9a4ee46 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -672,7 +672,7 @@ static inline void sync_core(void)
{
int tmp;

-#if defined(CONFIG_M386) || defined(CONFIG_M486)
+#ifdef CONFIG_M486
if (boot_cpu_data.x86 < 5)
/* There is no speculative execution.
* jmp is a barrier to prefetching. */
--
1.7.11.7

2012-11-28 20:30:33

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH 3/8] x86, 386 removal: Remove CONFIG_XADD

On Wed, Nov 28, 2012 at 11:50:25AM -0800, H. Peter Anvin wrote:
> From: "H. Peter Anvin" <[email protected]>
>
> All 486+ CPUs support CMPXCHG, so remove the fallback 386 support
> code.

This commit message should say something about XADD and not about
CMPXCHG, right?

--
Regards/Gruss,
Boris.

2012-11-28 20:42:04

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH 8/8] x86, cleanups: Simplify sync_core() in the case of no CPUID

On Wed, Nov 28, 2012 at 11:50:30AM -0800, H. Peter Anvin wrote:
> From: "H. Peter Anvin" <[email protected]>
>
> Simplify the implementation of sync_core() for the case where we may
> not have the CPUID instruction available.
>
> Signed-off-by: H. Peter Anvin <[email protected]>
> ---
> arch/x86/include/asm/processor.h | 27 +++++++++++++++++----------
> 1 file changed, 17 insertions(+), 10 deletions(-)
>
> diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
> index 9a4ee46..b381df7 100644
> --- a/arch/x86/include/asm/processor.h
> +++ b/arch/x86/include/asm/processor.h
> @@ -673,17 +673,24 @@ static inline void sync_core(void)
> int tmp;
>
> #ifdef CONFIG_M486
> - if (boot_cpu_data.x86 < 5)
> - /* There is no speculative execution.
> - * jmp is a barrier to prefetching. */
> - asm volatile("jmp 1f\n1:\n" ::: "memory");
> - else
> + /*
> + * Do a CPUID if available, otherwise do a jump. The jump
> + * can conveniently enough be the jump around CPUID.
> + */
> + asm volatile("cmpl %2,%1\n\t"
> + "jl 1f\n\t"
> + "cpuid\n"
> + "1:"
> + : "=a" (tmp)
> + : "rm" (boot_cpu_data.cpuid_level), "ri" (0), "0" (1)
> + : "ebx", "ecx", "edx", "memory");
> +#else
> + /* cpuid is a barrier to speculative execution.
> + * Prefetched instructions are automatically
> + * invalidated when modified. */

While at it, you could correct this comment to adhere to kernel coding
style:

/*
* cpuid is a barrier...
* ...
*/

> + asm volatile("cpuid" : "=a" (tmp) : "0" (1)
> + : "ebx", "ecx", "edx", "memory");

... and then write this in its shorter form:

tmp = cpuid_eax(1);

to have it a bit easier on the eyes.

Thanks.

--
Regards/Gruss,
Boris.

2012-11-28 20:47:06

by Alan

[permalink] [raw]
Subject: Re: [PATCH 6/8] x86, 386 removal: Remove CONFIG_X86_WP_WORKS_OK

On Wed, 28 Nov 2012 11:50:28 -0800
"H. Peter Anvin" <[email protected]> wrote:

> From: "H. Peter Anvin" <[email protected]>
>
> All 486+ CPUs support WP in supervisor mode, so remove the fallback
> 386 support code.

This breaks the Nx586 support. Do we care: I doubt it 8)

2012-11-28 23:11:46

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 6/8] x86, 386 removal: Remove CONFIG_X86_WP_WORKS_OK

Yes, the Nx586 was supported as a 386. Again, doubt anyone cares at this point.

Alan Cox <[email protected]> wrote:

>On Wed, 28 Nov 2012 11:50:28 -0800
>"H. Peter Anvin" <[email protected]> wrote:
>
>> From: "H. Peter Anvin" <[email protected]>
>>
>> All 486+ CPUs support WP in supervisor mode, so remove the fallback
>> 386 support code.
>
>This breaks the Nx586 support. Do we care: I doubt it 8)

--
Sent from my mobile phone. Please excuse brevity and lack of formatting.

2012-11-29 00:15:25

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 8/8] x86, cleanups: Simplify sync_core() in the case of no CPUID

On 11/28/2012 12:41 PM, Borislav Petkov wrote:
>
> While at it, you could correct this comment to adhere to kernel coding
> style:
>
> /*
> * cpuid is a barrier...
> * ...
> */
>
>> + asm volatile("cpuid" : "=a" (tmp) : "0" (1)
>> + : "ebx", "ecx", "edx", "memory");
>
> ... and then write this in its shorter form:
>
> tmp = cpuid_eax(1);
>
> to have it a bit easier on the eyes.
>

Wrong barrier semantics.

-hpa

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

2012-11-29 09:13:24

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH 8/8] x86, cleanups: Simplify sync_core() in the case of no CPUID

On Wed, Nov 28, 2012 at 04:14:43PM -0800, H. Peter Anvin wrote:
> Wrong barrier semantics.

Let me try to understand what you mean by that :)

Now, your version's asm output looks like this:

----
.loc 2 95 0
movl $139, %esi #, tmp140
xorl %eax, %eax # tmp141
movl %esi, %ecx # tmp140,
movl %eax, %edx # tmp141,
#APP
# 95 "/home/boris/kernel/linux-2.6/arch/x86/include/asm/msr.h" 1
wrmsr
# 0 "" 2
#NO_APP
.loc 3 694 0
movb $1, %al #,
#APP
# 694 "/home/boris/kernel/linux-2.6/arch/x86/include/asm/processor.h" 1
cpuid
# 0 "" 2
.LVL15:
#NO_APP
----

This is the sync_core() call from early_init_intel(). Now look like 139
remains in %ecx after the WRMSR and CPUID actually gets called with
RAX=1 and RCX=139 (btw, 139 is MSR_IA32_UCODE_REV). Even if this works
I'd say, we don't want to have any stray values in RCX when doing CPUID,
no?

Now here's the version with the change I proposed:

----
.loc 2 95 0
xorl %esi, %esi # tmp144
movl $139, %edi #, tmp143
movl %edi, %ecx # tmp143,
movl %esi, %eax # tmp144,
movl %esi, %edx # tmp144,
#APP
# 95 "/home/boris/kernel/linux-2.6/arch/x86/include/asm/msr.h" 1
wrmsr
# 0 "" 2
.LVL15:
#NO_APP
.loc 3 199 0
movb $1, %al #,
movl %esi, %ecx # tmp144, ecx
#APP
# 199 "/home/boris/kernel/linux-2.6/arch/x86/include/asm/processor.h" 1
cpuid
# 0 "" 2
.LVL16:
#NO_APP
----

RCX gets correctly cleaned to 0 and *then* we call CPUID.

And the asm output is the same except that RCX gets correctly cleaned up
before calling CPUID.

So what am I missing?

Thanks.

--
Regards/Gruss,
Boris.

2012-11-29 21:06:22

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 8/8] x86, cleanups: Simplify sync_core() in the case of no CPUID

On 11/29/2012 01:13 AM, Borislav Petkov wrote:
>
> RCX gets correctly cleaned to 0 and *then* we call CPUID.
>
> And the asm output is the same except that RCX gets correctly cleaned up
> before calling CPUID.
>
> So what am I missing?
>

It doesn't matter in that context, as the surrounding MSR references
have barriers, but what I'm refering to is the "memory" barrier.

The value of ECX doesn't matter when EAX=1.

-hpa

2012-11-29 21:19:03

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH 8/8] x86, cleanups: Simplify sync_core() in the case of no CPUID

On Thu, Nov 29, 2012 at 01:06:20PM -0800, H. Peter Anvin wrote:
> It doesn't matter in that context, as the surrounding MSR references
> have barriers, but what I'm refering to is the "memory" barrier.

Ok, but the only difference between the two versions is this line:

movl %esi, %ecx # tmp144, ecx

coming from the cpuid_eax() function. So the memory barrier is the same
and in the right place in both cases.

> The value of ECX doesn't matter when EAX=1.

Ok.

--
Regards/Gruss,
Boris.

2012-11-29 21:20:20

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 8/8] x86, cleanups: Simplify sync_core() in the case of no CPUID

On 11/29/2012 01:18 PM, Borislav Petkov wrote:
> On Thu, Nov 29, 2012 at 01:06:20PM -0800, H. Peter Anvin wrote:
>> It doesn't matter in that context, as the surrounding MSR references
>> have barriers, but what I'm refering to is the "memory" barrier.
>
> Ok, but the only difference between the two versions is this line:
>
> movl %esi, %ecx # tmp144, ecx
>
> coming from the cpuid_eax() function. So the memory barrier is the same
> and in the right place in both cases.
>

In the case of that one call site, yes, because the MSR references
include the barrier. Other sites, current or future, may not have the
same property.

-hpa

2012-11-29 21:24:28

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 8/8] x86, cleanups: Simplify sync_core() in the case of no CPUID

On 11/28/2012 12:41 PM, Borislav Petkov wrote:
>
> While at it, you could correct this comment to adhere to kernel coding
> style:
>
> /*
> * cpuid is a barrier...
> * ...
> */
>
>> + asm volatile("cpuid" : "=a" (tmp) : "0" (1)
>> + : "ebx", "ecx", "edx", "memory");
>
> ... and then write this in its shorter form:
>
> tmp = cpuid_eax(1);
>
> to have it a bit easier on the eyes.
>

Thinking about it some more, there is another reason to not do this,
which is that we don't want this particular CPUID to be paravirtualized;
we're after the synchronizing side effect, not the CPUID return value
itself.

So let's leave it as a primitive; it gets too confusing otherwise.

-hpa

2012-11-29 21:31:57

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH 8/8] x86, cleanups: Simplify sync_core() in the case of no CPUID

On Thu, Nov 29, 2012 at 01:20:00PM -0800, H. Peter Anvin wrote:
> On 11/29/2012 01:18 PM, Borislav Petkov wrote:
> > On Thu, Nov 29, 2012 at 01:06:20PM -0800, H. Peter Anvin wrote:
> >> It doesn't matter in that context, as the surrounding MSR references
> >> have barriers, but what I'm refering to is the "memory" barrier.
> >
> > Ok, but the only difference between the two versions is this line:
> >
> > movl %esi, %ecx # tmp144, ecx
> >
> > coming from the cpuid_eax() function. So the memory barrier is the same
> > and in the right place in both cases.
> >
>
> In the case of that one call site, yes, because the MSR references
> include the barrier. Other sites, current or future, may not have the
> same property.

Sorry, but I think we're misunderstanding each other in some way, so let
me restart. Here's the version I'm suggesting:

static inline void sync_core(void)
{
int tmp;

#ifdef CONFIG_M486
/*
* Do a CPUID if available, otherwise do a jump. The jump
* can conveniently enough be the jump around CPUID.
*/
asm volatile("cmpl %2,%1\n\t"
"jl 1f\n\t"
"cpuid\n"
"1:"
: "=a" (tmp)
: "rm" (boot_cpu_data.cpuid_level), "ri" (0), "0" (1)
: "ebx", "ecx", "edx", "memory");
#else
/*
* CPUID is a barrier to speculative execution. Prefetched instructions
* are automatically invalidated when modified.
*/
tmp = cpuid_eax(1);

/*
asm volatile("cpuid" : "=a" (tmp) : "0" (1)
: "ebx", "ecx", "edx", "memory");
*/
#endif
}

with the last asm volatile("cpuid"...) commented out. The only
non-trivial difference between the two is the zeroing out of %ecx when
looking at the resulting asm.

Now, cpuid_eax is actually native_cpuid() which has the memory barrier
character by having an "asm volatile" in there too and it too clobbers
memory.

Are you saying that there's a semantic difference between the naked
"asm volatile" and the compiler inlining a couple of inline functions
resulting in the same "asm volatile" memory barrier for it?

Hmm, strange.

--
Regards/Gruss,
Boris.

2012-11-29 21:34:06

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH 8/8] x86, cleanups: Simplify sync_core() in the case of no CPUID

On Thu, Nov 29, 2012 at 01:24:26PM -0800, H. Peter Anvin wrote:
> Thinking about it some more, there is another reason to not do
> this, which is that we don't want this particular CPUID to be
> paravirtualized; we're after the synchronizing side effect, not the
> CPUID return value itself.

Ok, you're right, this can be a PVOP call.

> So let's leave it as a primitive; it gets too confusing otherwise.

Ok.

Thanks.

--
Regards/Gruss,
Boris.

2012-11-30 17:02:16

by Linus Torvalds

[permalink] [raw]
Subject: Re: [PATCH 8/8] x86, cleanups: Simplify sync_core() in the case of no CPUID

On Thu, Nov 29, 2012 at 1:24 PM, H. Peter Anvin <[email protected]> wrote:
>
> Thinking about it some more, there is another reason to not do this,
> which is that we don't want this particular CPUID to be paravirtualized;
> we're after the synchronizing side effect, not the CPUID return value
> itself.
>
> So let's leave it as a primitive; it gets too confusing otherwise.

Hmm. The virtualization issue brings up another point: do we *really*
want to use cpuid for serialization at all?

Exactly because under _real_ virtualization (as opposed to para-virt),
it can cause unnecessary exits in a virtualized environment, no?

So I'm wondering if there is any better synchronizing instruction..

I guess sync_core() isn't used *that* much, so maybe we don't care,
but I thought I'd ask...

Linus

2012-11-30 17:28:09

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH 8/8] x86, cleanups: Simplify sync_core() in the case of no CPUID

On Fri, Nov 30, 2012 at 09:01:50AM -0800, Linus Torvalds wrote:
> Hmm. The virtualization issue brings up another point: do we *really*
> want to use cpuid for serialization at all?
>
> Exactly because under _real_ virtualization (as opposed to para-virt),
> it can cause unnecessary exits in a virtualized environment, no?

Well, in that case the function performs as advertized although it is a
very expensive serialization for virt. And virt guys hate exits.

> So I'm wondering if there is any better synchronizing instruction..
>
> I guess sync_core() isn't used *that* much, so maybe we don't care,
> but I thought I'd ask...

Well, we use it in alternatives, MCE, intel_early_init, Intel
ucode, ftrace, and SGI's GRU thing.

>From all of the above, the alternatives case is kinda relevant for virt
where we do text_poke_early in a loop for every alternative section
so this could pile up to a bunch of vmexits depending on the emulated
hardware. Might be worth a replacement if it is noticeable in guests.

Hmm...

--
Regards/Gruss,
Boris.

2012-11-30 18:03:33

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 8/8] x86, cleanups: Simplify sync_core() in the case of no CPUID

On 11/30/2012 09:01 AM, Linus Torvalds wrote:
> On Thu, Nov 29, 2012 at 1:24 PM, H. Peter Anvin <[email protected]> wrote:
>>
>> Thinking about it some more, there is another reason to not do this,
>> which is that we don't want this particular CPUID to be paravirtualized;
>> we're after the synchronizing side effect, not the CPUID return value
>> itself.
>>
>> So let's leave it as a primitive; it gets too confusing otherwise.
>
> Hmm. The virtualization issue brings up another point: do we *really*
> want to use cpuid for serialization at all?
>

Well, the grand total of serializing instructions are:

INVD, INVEPT, INVLPG, INVVPID, LGDT, LIDT, LLDT, LTR, MOV to CR, MOV to
DR, WBINVD, WRMSR, CPUID, IRET, RSM.

It doesn't really leave a lot of wiggle room, and in the microcode case,
the use of CPUID level 1 is actually mandated (presumably to get a
uniform sequence for validation purposes.)

> From all of the above, the alternatives case is kinda relevant for virt
> where we do text_poke_early in a loop for every alternative section
> so this could pile up to a bunch of vmexits depending on the emulated
> hardware. Might be worth a replacement if it is noticeable in guests.

This is still boot time, and I really doubt it is measurable in the long
run. Yes, exists suck, but at least CPUID is generally a quick exit,
since all the relevant state is in registers.

-hpa

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

2012-11-30 18:10:42

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH 8/8] x86, cleanups: Simplify sync_core() in the case of no CPUID

On Fri, Nov 30, 2012 at 10:03:03AM -0800, H. Peter Anvin wrote:
> Well, the grand total of serializing instructions are:
>
> INVD, INVEPT, INVLPG, INVVPID, LGDT, LIDT, LLDT, LTR, MOV to CR, MOV
> to DR, WBINVD, WRMSR, CPUID, IRET, RSM.

What about MFENCE with JMP 1f to kill prefetches? Probably too
expensive. Oh and MFENCE is an SSE2 insn so maybe not supported by 486
or something later ...

> >From all of the above, the alternatives case is kinda relevant for virt
> >where we do text_poke_early in a loop for every alternative section
> >so this could pile up to a bunch of vmexits depending on the emulated
> >hardware. Might be worth a replacement if it is noticeable in guests.
>
> This is still boot time, and I really doubt it is measurable in the
> long run. Yes, exists suck, but at least CPUID is generally a quick
> exit, since all the relevant state is in registers.

Agreed.

--
Regards/Gruss,
Boris.

2012-11-30 18:40:57

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 8/8] x86, cleanups: Simplify sync_core() in the case of no CPUID

On 11/30/2012 10:10 AM, Borislav Petkov wrote:
> On Fri, Nov 30, 2012 at 10:03:03AM -0800, H. Peter Anvin wrote:
>> Well, the grand total of serializing instructions are:
>>
>> INVD, INVEPT, INVLPG, INVVPID, LGDT, LIDT, LLDT, LTR, MOV to CR, MOV
>> to DR, WBINVD, WRMSR, CPUID, IRET, RSM.
>
> What about MFENCE with JMP 1f to kill prefetches? Probably too
> expensive. Oh and MFENCE is an SSE2 insn so maybe not supported by 486
> or something later ...

It's not serializing in the strict sense.

-hpa

2012-12-01 00:34:52

by H. Peter Anvin

[permalink] [raw]
Subject: [tip:x86/nuke386] x86, 386 removal: Remove CONFIG_M386 from Kconfig

Commit-ID: eb068e781020cf491333c773fb41820b57bfada4
Gitweb: http://git.kernel.org/tip/eb068e781020cf491333c773fb41820b57bfada4
Author: H. Peter Anvin <[email protected]>
AuthorDate: Wed, 28 Nov 2012 11:50:23 -0800
Committer: H. Peter Anvin <[email protected]>
CommitDate: Thu, 29 Nov 2012 13:23:01 -0800

x86, 386 removal: Remove CONFIG_M386 from Kconfig

Remove the CONFIG_M386 symbol from Kconfig so that it cannot be
selected.

Signed-off-by: H. Peter Anvin <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
---
arch/x86/Kconfig | 6 ++---
arch/x86/Kconfig.cpu | 58 ++++++++++++++++------------------------
arch/x86/Makefile_32.cpu | 1 -
arch/x86/include/asm/module.h | 2 --
arch/x86/include/asm/processor.h | 2 +-
5 files changed, 27 insertions(+), 42 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 46c3bff..a1a6627 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -69,8 +69,8 @@ config X86
select HAVE_PERF_USER_STACK_DUMP
select HAVE_DEBUG_KMEMLEAK
select ANON_INODES
- select HAVE_ALIGNED_STRUCT_PAGE if SLUB && !M386
- select HAVE_CMPXCHG_LOCAL if !M386
+ select HAVE_ALIGNED_STRUCT_PAGE if SLUB
+ select HAVE_CMPXCHG_LOCAL
select HAVE_CMPXCHG_DOUBLE
select HAVE_ARCH_KMEMCHECK
select HAVE_USER_RETURN_NOTIFIER
@@ -1100,7 +1100,7 @@ config HIGHMEM4G

config HIGHMEM64G
bool "64GB"
- depends on !M386 && !M486
+ depends on !M486
select X86_PAE
---help---
Select this if you have a 32-bit processor and more than 4
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index f3b86d0..36a07eb 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -4,23 +4,24 @@ choice
default M686 if X86_32
default GENERIC_CPU if X86_64

-config M386
- bool "386"
- depends on X86_32 && !UML
+config M486
+ bool "486"
+ depends on X86_32
---help---
- This is the processor type of your CPU. This information is used for
- optimizing purposes. In order to compile a kernel that can run on
- all x86 CPU types (albeit not optimally fast), you can specify
- "386" here.
+ This is the processor type of your CPU. This information is
+ used for optimizing purposes. In order to compile a kernel
+ that can run on all supported x86 CPU types (albeit not
+ optimally fast), you can specify "486" here.
+
+ Note that the 386 is no longer supported, this includes
+ AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI 486DLC/DLC2,
+ and UMC 486SX-S.

The kernel will not necessarily run on earlier architectures than
the one you have chosen, e.g. a Pentium optimized kernel will run on
a PPro, but not necessarily on a i486.

Here are the settings recommended for greatest speed:
- - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI
- 486DLC/DLC2, and UMC 486SX-S. Only "386" kernels will run on a 386
- class machine.
- "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or
SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
- "586" for generic Pentium CPUs lacking the TSC
@@ -43,16 +44,7 @@ config M386
- "VIA C3-2" for VIA C3-2 "Nehemiah" (model 9 and above).
- "VIA C7" for VIA C7.

- If you don't know what to do, choose "386".
-
-config M486
- bool "486"
- depends on X86_32
- ---help---
- Select this for a 486 series processor, either Intel or one of the
- compatible processors from AMD, Cyrix, IBM, or Intel. Includes DX,
- DX2, and DX4 variants; also SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or
- U5S.
+ If you don't know what to do, choose "486".

config M586
bool "586/K5/5x86/6x86/6x86MX"
@@ -307,22 +299,20 @@ config X86_INTERNODE_CACHE_SHIFT

config X86_CMPXCHG
def_bool y
- depends on X86_64 || (X86_32 && !M386)

config X86_L1_CACHE_SHIFT
int
default "7" if MPENTIUM4 || MPSC
default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU
- default "4" if MELAN || M486 || M386 || MGEODEGX1
+ default "4" if MELAN || M486 || MGEODEGX1
default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX

config X86_XADD
def_bool y
- depends on !M386

config X86_PPRO_FENCE
bool "PentiumPro memory ordering errata workaround"
- depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1
+ depends on M686 || M586MMX || M586TSC || M586 || M486 || MGEODEGX1
---help---
Old PentiumPro multiprocessor systems had errata that could cause
memory operations to violate the x86 ordering standard in rare cases.
@@ -335,27 +325,26 @@ config X86_PPRO_FENCE

config X86_F00F_BUG
def_bool y
- depends on M586MMX || M586TSC || M586 || M486 || M386
+ depends on M586MMX || M586TSC || M586 || M486

config X86_INVD_BUG
def_bool y
- depends on M486 || M386
+ depends on M486

config X86_WP_WORKS_OK
def_bool y
- depends on !M386

config X86_INVLPG
def_bool y
- depends on X86_32 && !M386
+ depends on X86_32

config X86_BSWAP
def_bool y
- depends on X86_32 && !M386
+ depends on X86_32

config X86_POPAD_OK
def_bool y
- depends on X86_32 && !M386
+ depends on X86_32

config X86_ALIGNMENT_16
def_bool y
@@ -412,12 +401,11 @@ config X86_MINIMUM_CPU_FAMILY
default "64" if X86_64
default "6" if X86_32 && X86_P6_NOP
default "5" if X86_32 && X86_CMPXCHG64
- default "4" if X86_32 && (X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK)
- default "3"
+ default "4"

config X86_DEBUGCTLMSR
def_bool y
- depends on !(MK6 || MWINCHIPC6 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 || M486 || M386) && !UML
+ depends on !(MK6 || MWINCHIPC6 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 || M486) && !UML

menuconfig PROCESSOR_SELECT
bool "Supported processor vendors" if EXPERT
@@ -441,7 +429,7 @@ config CPU_SUP_INTEL
config CPU_SUP_CYRIX_32
default y
bool "Support Cyrix processors" if PROCESSOR_SELECT
- depends on M386 || M486 || M586 || M586TSC || M586MMX || (EXPERT && !64BIT)
+ depends on M486 || M586 || M586TSC || M586MMX || (EXPERT && !64BIT)
---help---
This enables detection, tunings and quirks for Cyrix processors

@@ -495,7 +483,7 @@ config CPU_SUP_TRANSMETA_32
config CPU_SUP_UMC_32
default y
bool "Support UMC processors" if PROCESSOR_SELECT
- depends on M386 || M486 || (EXPERT && !64BIT)
+ depends on M486 || (EXPERT && !64BIT)
---help---
This enables detection, tunings and quirks for UMC processors

diff --git a/arch/x86/Makefile_32.cpu b/arch/x86/Makefile_32.cpu
index 86cee7b..6647ed4 100644
--- a/arch/x86/Makefile_32.cpu
+++ b/arch/x86/Makefile_32.cpu
@@ -10,7 +10,6 @@ tune = $(call cc-option,-mcpu=$(1),$(2))
endif

align := $(cc-option-align)
-cflags-$(CONFIG_M386) += -march=i386
cflags-$(CONFIG_M486) += -march=i486
cflags-$(CONFIG_M586) += -march=i586
cflags-$(CONFIG_M586TSC) += -march=i586
diff --git a/arch/x86/include/asm/module.h b/arch/x86/include/asm/module.h
index 9eae775..e3b7819 100644
--- a/arch/x86/include/asm/module.h
+++ b/arch/x86/include/asm/module.h
@@ -5,8 +5,6 @@

#ifdef CONFIG_X86_64
/* X86_64 does not define MODULE_PROC_FAMILY */
-#elif defined CONFIG_M386
-#define MODULE_PROC_FAMILY "386 "
#elif defined CONFIG_M486
#define MODULE_PROC_FAMILY "486 "
#elif defined CONFIG_M586
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index ad1fc85..9a4ee46 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -672,7 +672,7 @@ static inline void sync_core(void)
{
int tmp;

-#if defined(CONFIG_M386) || defined(CONFIG_M486)
+#ifdef CONFIG_M486
if (boot_cpu_data.x86 < 5)
/* There is no speculative execution.
* jmp is a barrier to prefetching. */

2012-12-01 00:36:05

by H. Peter Anvin

[permalink] [raw]
Subject: [tip:x86/nuke386] x86, 386 removal: Remove CONFIG_CMPXCHG

Commit-ID: d55c5a93db2d5fa95f233ab153f594365d95b777
Gitweb: http://git.kernel.org/tip/d55c5a93db2d5fa95f233ab153f594365d95b777
Author: H. Peter Anvin <[email protected]>
AuthorDate: Wed, 28 Nov 2012 11:50:24 -0800
Committer: H. Peter Anvin <[email protected]>
CommitDate: Thu, 29 Nov 2012 13:23:01 -0800

x86, 386 removal: Remove CONFIG_CMPXCHG

All 486+ CPUs support CMPXCHG, so remove the fallback 386 support
code.

Signed-off-by: H. Peter Anvin <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
---
arch/x86/Kconfig.cpu | 3 ---
arch/x86/include/asm/cmpxchg_32.h | 55 ---------------------------------------
arch/x86/include/asm/percpu.h | 3 ---
arch/x86/lib/Makefile | 1 -
arch/x86/lib/cmpxchg.c | 54 --------------------------------------
arch/x86/xen/Kconfig | 2 +-
6 files changed, 1 insertion(+), 117 deletions(-)

diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 36a07eb..1290a69 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -297,9 +297,6 @@ config X86_INTERNODE_CACHE_SHIFT
default "12" if X86_VSMP
default X86_L1_CACHE_SHIFT

-config X86_CMPXCHG
- def_bool y
-
config X86_L1_CACHE_SHIFT
int
default "7" if MPENTIUM4 || MPSC
diff --git a/arch/x86/include/asm/cmpxchg_32.h b/arch/x86/include/asm/cmpxchg_32.h
index 53f4b21..f8bf2ee 100644
--- a/arch/x86/include/asm/cmpxchg_32.h
+++ b/arch/x86/include/asm/cmpxchg_32.h
@@ -34,9 +34,7 @@ static inline void set_64bit(volatile u64 *ptr, u64 value)
: "memory");
}

-#ifdef CONFIG_X86_CMPXCHG
#define __HAVE_ARCH_CMPXCHG 1
-#endif

#ifdef CONFIG_X86_CMPXCHG64
#define cmpxchg64(ptr, o, n) \
@@ -73,59 +71,6 @@ static inline u64 __cmpxchg64_local(volatile u64 *ptr, u64 old, u64 new)
return prev;
}

-#ifndef CONFIG_X86_CMPXCHG
-/*
- * Building a kernel capable running on 80386. It may be necessary to
- * simulate the cmpxchg on the 80386 CPU. For that purpose we define
- * a function for each of the sizes we support.
- */
-
-extern unsigned long cmpxchg_386_u8(volatile void *, u8, u8);
-extern unsigned long cmpxchg_386_u16(volatile void *, u16, u16);
-extern unsigned long cmpxchg_386_u32(volatile void *, u32, u32);
-
-static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old,
- unsigned long new, int size)
-{
- switch (size) {
- case 1:
- return cmpxchg_386_u8(ptr, old, new);
- case 2:
- return cmpxchg_386_u16(ptr, old, new);
- case 4:
- return cmpxchg_386_u32(ptr, old, new);
- }
- return old;
-}
-
-#define cmpxchg(ptr, o, n) \
-({ \
- __typeof__(*(ptr)) __ret; \
- if (likely(boot_cpu_data.x86 > 3)) \
- __ret = (__typeof__(*(ptr)))__cmpxchg((ptr), \
- (unsigned long)(o), (unsigned long)(n), \
- sizeof(*(ptr))); \
- else \
- __ret = (__typeof__(*(ptr)))cmpxchg_386((ptr), \
- (unsigned long)(o), (unsigned long)(n), \
- sizeof(*(ptr))); \
- __ret; \
-})
-#define cmpxchg_local(ptr, o, n) \
-({ \
- __typeof__(*(ptr)) __ret; \
- if (likely(boot_cpu_data.x86 > 3)) \
- __ret = (__typeof__(*(ptr)))__cmpxchg_local((ptr), \
- (unsigned long)(o), (unsigned long)(n), \
- sizeof(*(ptr))); \
- else \
- __ret = (__typeof__(*(ptr)))cmpxchg_386((ptr), \
- (unsigned long)(o), (unsigned long)(n), \
- sizeof(*(ptr))); \
- __ret; \
-})
-#endif
-
#ifndef CONFIG_X86_CMPXCHG64
/*
* Building a kernel capable running on 80386 and 80486. It may be necessary
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index 1104afa..0da5200 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -406,7 +406,6 @@ do { \
#define this_cpu_xchg_2(pcp, nval) percpu_xchg_op(pcp, nval)
#define this_cpu_xchg_4(pcp, nval) percpu_xchg_op(pcp, nval)

-#ifndef CONFIG_M386
#define __this_cpu_add_return_1(pcp, val) percpu_add_return_op(pcp, val)
#define __this_cpu_add_return_2(pcp, val) percpu_add_return_op(pcp, val)
#define __this_cpu_add_return_4(pcp, val) percpu_add_return_op(pcp, val)
@@ -421,8 +420,6 @@ do { \
#define this_cpu_cmpxchg_2(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
#define this_cpu_cmpxchg_4(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)

-#endif /* !CONFIG_M386 */
-
#ifdef CONFIG_X86_CMPXCHG64
#define percpu_cmpxchg8b_double(pcp1, pcp2, o1, o2, n1, n2) \
({ \
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index b00f678..96b2c66 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -32,7 +32,6 @@ ifeq ($(CONFIG_X86_32),y)
lib-y += checksum_32.o
lib-y += strstr_32.o
lib-y += string_32.o
- lib-y += cmpxchg.o
ifneq ($(CONFIG_X86_CMPXCHG64),y)
lib-y += cmpxchg8b_emu.o atomic64_386_32.o
endif
diff --git a/arch/x86/lib/cmpxchg.c b/arch/x86/lib/cmpxchg.c
deleted file mode 100644
index 5d619f6..0000000
--- a/arch/x86/lib/cmpxchg.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * cmpxchg*() fallbacks for CPU not supporting these instructions
- */
-
-#include <linux/kernel.h>
-#include <linux/smp.h>
-#include <linux/module.h>
-
-#ifndef CONFIG_X86_CMPXCHG
-unsigned long cmpxchg_386_u8(volatile void *ptr, u8 old, u8 new)
-{
- u8 prev;
- unsigned long flags;
-
- /* Poor man's cmpxchg for 386. Unsuitable for SMP */
- local_irq_save(flags);
- prev = *(u8 *)ptr;
- if (prev == old)
- *(u8 *)ptr = new;
- local_irq_restore(flags);
- return prev;
-}
-EXPORT_SYMBOL(cmpxchg_386_u8);
-
-unsigned long cmpxchg_386_u16(volatile void *ptr, u16 old, u16 new)
-{
- u16 prev;
- unsigned long flags;
-
- /* Poor man's cmpxchg for 386. Unsuitable for SMP */
- local_irq_save(flags);
- prev = *(u16 *)ptr;
- if (prev == old)
- *(u16 *)ptr = new;
- local_irq_restore(flags);
- return prev;
-}
-EXPORT_SYMBOL(cmpxchg_386_u16);
-
-unsigned long cmpxchg_386_u32(volatile void *ptr, u32 old, u32 new)
-{
- u32 prev;
- unsigned long flags;
-
- /* Poor man's cmpxchg for 386. Unsuitable for SMP */
- local_irq_save(flags);
- prev = *(u32 *)ptr;
- if (prev == old)
- *(u32 *)ptr = new;
- local_irq_restore(flags);
- return prev;
-}
-EXPORT_SYMBOL(cmpxchg_386_u32);
-#endif
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index fdce49c..9a6775c 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -7,7 +7,7 @@ config XEN
select PARAVIRT
select PARAVIRT_CLOCK
depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS)
- depends on X86_CMPXCHG && X86_TSC
+ depends on X86_TSC
help
This is the Linux Xen port. Enabling this will allow the
kernel to boot in a paravirtualized environment under the

2012-12-01 00:36:56

by H. Peter Anvin

[permalink] [raw]
Subject: [tip:x86/nuke386] x86, 386 removal: Remove CONFIG_XADD

Commit-ID: 7ac468b1300f35143a9b5b100e3970ca7ae1d9b8
Gitweb: http://git.kernel.org/tip/7ac468b1300f35143a9b5b100e3970ca7ae1d9b8
Author: H. Peter Anvin <[email protected]>
AuthorDate: Wed, 28 Nov 2012 11:50:25 -0800
Committer: H. Peter Anvin <[email protected]>
CommitDate: Thu, 29 Nov 2012 13:23:02 -0800

x86, 386 removal: Remove CONFIG_XADD

All 486+ CPUs support XADD, so remove the fallback 386 support
code.

Signed-off-by: H. Peter Anvin <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
---
arch/x86/Kconfig | 5 -----
arch/x86/Kconfig.cpu | 3 ---
arch/x86/include/asm/atomic.h | 16 ----------------
arch/x86/include/asm/local.h | 18 +-----------------
arch/x86/um/Kconfig | 2 +-
5 files changed, 2 insertions(+), 42 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index a1a6627..631b298 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -171,13 +171,8 @@ config ARCH_MAY_HAVE_PC_FDC
def_bool y
depends on ISA_DMA_API

-config RWSEM_GENERIC_SPINLOCK
- def_bool y
- depends on !X86_XADD
-
config RWSEM_XCHGADD_ALGORITHM
def_bool y
- depends on X86_XADD

config GENERIC_CALIBRATE_DELAY
def_bool y
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 1290a69..52955ee 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -304,9 +304,6 @@ config X86_L1_CACHE_SHIFT
default "4" if MELAN || M486 || MGEODEGX1
default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX

-config X86_XADD
- def_bool y
-
config X86_PPRO_FENCE
bool "PentiumPro memory ordering errata workaround"
depends on M686 || M586MMX || M586TSC || M586 || M486 || MGEODEGX1
diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h
index b6c3b82..722aa3b 100644
--- a/arch/x86/include/asm/atomic.h
+++ b/arch/x86/include/asm/atomic.h
@@ -172,23 +172,7 @@ static inline int atomic_add_negative(int i, atomic_t *v)
*/
static inline int atomic_add_return(int i, atomic_t *v)
{
-#ifdef CONFIG_M386
- int __i;
- unsigned long flags;
- if (unlikely(boot_cpu_data.x86 <= 3))
- goto no_xadd;
-#endif
- /* Modern 486+ processor */
return i + xadd(&v->counter, i);
-
-#ifdef CONFIG_M386
-no_xadd: /* Legacy 386 processor */
- raw_local_irq_save(flags);
- __i = atomic_read(v);
- atomic_set(v, i + __i);
- raw_local_irq_restore(flags);
- return i + __i;
-#endif
}

/**
diff --git a/arch/x86/include/asm/local.h b/arch/x86/include/asm/local.h
index c8bed0d..2d89e39 100644
--- a/arch/x86/include/asm/local.h
+++ b/arch/x86/include/asm/local.h
@@ -124,27 +124,11 @@ static inline int local_add_negative(long i, local_t *l)
*/
static inline long local_add_return(long i, local_t *l)
{
- long __i;
-#ifdef CONFIG_M386
- unsigned long flags;
- if (unlikely(boot_cpu_data.x86 <= 3))
- goto no_xadd;
-#endif
- /* Modern 486+ processor */
- __i = i;
+ long __i = i;
asm volatile(_ASM_XADD "%0, %1;"
: "+r" (i), "+m" (l->a.counter)
: : "memory");
return i + __i;
-
-#ifdef CONFIG_M386
-no_xadd: /* Legacy 386 processor */
- local_irq_save(flags);
- __i = local_read(l);
- local_set(l, i + __i);
- local_irq_restore(flags);
- return i + __i;
-#endif
}

static inline long local_sub_return(long i, local_t *l)
diff --git a/arch/x86/um/Kconfig b/arch/x86/um/Kconfig
index 0761175..b0c30da 100644
--- a/arch/x86/um/Kconfig
+++ b/arch/x86/um/Kconfig
@@ -31,7 +31,7 @@ config X86_64
select MODULES_USE_ELF_RELA

config RWSEM_XCHGADD_ALGORITHM
- def_bool X86_XADD && 64BIT
+ def_bool 64BIT

config RWSEM_GENERIC_SPINLOCK
def_bool !RWSEM_XCHGADD_ALGORITHM

2012-12-01 00:37:59

by H. Peter Anvin

[permalink] [raw]
Subject: [tip:x86/nuke386] x86, 386 removal: Remove CONFIG_BSWAP

Commit-ID: e5bb8ad862a97a0facc83f3b81731de919fec6ad
Gitweb: http://git.kernel.org/tip/e5bb8ad862a97a0facc83f3b81731de919fec6ad
Author: H. Peter Anvin <[email protected]>
AuthorDate: Wed, 28 Nov 2012 11:50:26 -0800
Committer: H. Peter Anvin <[email protected]>
CommitDate: Thu, 29 Nov 2012 13:23:02 -0800

x86, 386 removal: Remove CONFIG_BSWAP

All 486+ CPUs support BSWAP, so remove the fallback 386 support
code.

Signed-off-by: H. Peter Anvin <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
---
arch/x86/Kconfig.cpu | 4 ----
arch/x86/include/asm/futex.h | 12 ------------
arch/x86/include/asm/swab.h | 29 ++---------------------------
arch/x86/kernel/cpu/bugs.c | 13 ++-----------
4 files changed, 4 insertions(+), 54 deletions(-)

diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 52955ee..8e5867c 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -332,10 +332,6 @@ config X86_INVLPG
def_bool y
depends on X86_32

-config X86_BSWAP
- def_bool y
- depends on X86_32
-
config X86_POPAD_OK
def_bool y
depends on X86_32
diff --git a/arch/x86/include/asm/futex.h b/arch/x86/include/asm/futex.h
index f373046..be27ba1 100644
--- a/arch/x86/include/asm/futex.h
+++ b/arch/x86/include/asm/futex.h
@@ -55,12 +55,6 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
return -EFAULT;

-#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_BSWAP)
- /* Real i386 machines can only support FUTEX_OP_SET */
- if (op != FUTEX_OP_SET && boot_cpu_data.x86 == 3)
- return -ENOSYS;
-#endif
-
pagefault_disable();

switch (op) {
@@ -118,12 +112,6 @@ static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
{
int ret = 0;

-#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_BSWAP)
- /* Real i386 machines have no cmpxchg instruction */
- if (boot_cpu_data.x86 == 3)
- return -ENOSYS;
-#endif
-
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
return -EFAULT;

diff --git a/arch/x86/include/asm/swab.h b/arch/x86/include/asm/swab.h
index 557cd9f..7f235c7 100644
--- a/arch/x86/include/asm/swab.h
+++ b/arch/x86/include/asm/swab.h
@@ -6,22 +6,7 @@

static inline __attribute_const__ __u32 __arch_swab32(__u32 val)
{
-#ifdef __i386__
-# ifdef CONFIG_X86_BSWAP
- asm("bswap %0" : "=r" (val) : "0" (val));
-# else
- asm("xchgb %b0,%h0\n\t" /* swap lower bytes */
- "rorl $16,%0\n\t" /* swap words */
- "xchgb %b0,%h0" /* swap higher bytes */
- : "=q" (val)
- : "0" (val));
-# endif
-
-#else /* __i386__ */
- asm("bswapl %0"
- : "=r" (val)
- : "0" (val));
-#endif
+ asm("bswapl %0" : "=r" (val) : "0" (val));
return val;
}
#define __arch_swab32 __arch_swab32
@@ -37,22 +22,12 @@ static inline __attribute_const__ __u64 __arch_swab64(__u64 val)
__u64 u;
} v;
v.u = val;
-# ifdef CONFIG_X86_BSWAP
asm("bswapl %0 ; bswapl %1 ; xchgl %0,%1"
: "=r" (v.s.a), "=r" (v.s.b)
: "0" (v.s.a), "1" (v.s.b));
-# else
- v.s.a = __arch_swab32(v.s.a);
- v.s.b = __arch_swab32(v.s.b);
- asm("xchgl %0,%1"
- : "=r" (v.s.a), "=r" (v.s.b)
- : "0" (v.s.a), "1" (v.s.b));
-# endif
return v.u;
#else /* __i386__ */
- asm("bswapq %0"
- : "=r" (val)
- : "0" (val));
+ asm("bswapq %0" : "=r" (val) : "0" (val));
return val;
#endif
}
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index d0e910d..0cd07cc 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -136,24 +136,15 @@ static void __init check_popad(void)
/*
* Check whether we are able to run this kernel safely on SMP.
*
- * - In order to run on a i386, we need to be compiled for i386
- * (for due to lack of "invlpg" and working WP on a i386)
+ * - i386 is no longer supported.
* - In order to run on anything without a TSC, we need to be
* compiled for a i486.
*/

static void __init check_config(void)
{
-/*
- * We'd better not be a i386 if we're configured to use some
- * i486+ only features! (WP works in supervisor mode and the
- * new "invlpg" and "bswap" instructions)
- */
-#if defined(CONFIG_X86_WP_WORKS_OK) || defined(CONFIG_X86_INVLPG) || \
- defined(CONFIG_X86_BSWAP)
- if (boot_cpu_data.x86 == 3)
+ if (boot_cpu_data.x86 < 4)
panic("Kernel requires i486+ for 'invlpg' and other features");
-#endif
}

2012-12-01 00:39:03

by H. Peter Anvin

[permalink] [raw]
Subject: [tip:x86/nuke386] x86, 386 removal: Remove CONFIG_INVLPG

Commit-ID: 094ab1db7cb7833cd4c820acd868fc26acf3f08e
Gitweb: http://git.kernel.org/tip/094ab1db7cb7833cd4c820acd868fc26acf3f08e
Author: H. Peter Anvin <[email protected]>
AuthorDate: Wed, 28 Nov 2012 11:50:27 -0800
Committer: H. Peter Anvin <[email protected]>
CommitDate: Thu, 29 Nov 2012 13:23:02 -0800

x86, 386 removal: Remove CONFIG_INVLPG

All 486+ CPUs support INVLPG, so remove the fallback 386 support
code.

Signed-off-by: H. Peter Anvin <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
---
arch/x86/Kconfig.cpu | 4 ----
arch/x86/include/asm/cpufeature.h | 6 ------
arch/x86/include/asm/tlbflush.h | 3 ---
arch/x86/kernel/cpu/amd.c | 3 ---
arch/x86/kernel/cpu/intel.c | 4 ----
arch/x86/mm/tlb.c | 8 +++-----
6 files changed, 3 insertions(+), 25 deletions(-)

diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 8e5867c..d3bdc18 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -328,10 +328,6 @@ config X86_INVD_BUG
config X86_WP_WORKS_OK
def_bool y

-config X86_INVLPG
- def_bool y
- depends on X86_32
-
config X86_POPAD_OK
def_bool y
depends on X86_32
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 8c297aa..ff8dd62 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -312,12 +312,6 @@ extern const char * const x86_power_flags[32];
#define cpu_has_cx16 boot_cpu_has(X86_FEATURE_CX16)
#define cpu_has_eager_fpu boot_cpu_has(X86_FEATURE_EAGER_FPU)

-#if defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_64)
-# define cpu_has_invlpg 1
-#else
-# define cpu_has_invlpg (boot_cpu_data.x86 > 3)
-#endif
-
#ifdef CONFIG_X86_64

#undef cpu_has_vme
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 74a4433..0fee48e 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -56,10 +56,7 @@ static inline void __flush_tlb_all(void)

static inline void __flush_tlb_one(unsigned long addr)
{
- if (cpu_has_invlpg)
__flush_tlb_single(addr);
- else
- __flush_tlb();
}

#define TLB_FLUSH_ALL -1UL
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 1b7d165..a025d8c 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -753,9 +753,6 @@ static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c,

static void __cpuinit cpu_set_tlb_flushall_shift(struct cpuinfo_x86 *c)
{
- if (!cpu_has_invlpg)
- return;
-
tlb_flushall_shift = 5;

if (c->x86 <= 0x11)
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 198e019..fcaabd0 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -612,10 +612,6 @@ static void __cpuinit intel_tlb_lookup(const unsigned char desc)

static void __cpuinit intel_tlb_flushall_shift_set(struct cpuinfo_x86 *c)
{
- if (!cpu_has_invlpg) {
- tlb_flushall_shift = -1;
- return;
- }
switch ((c->x86 << 8) + c->x86_model) {
case 0x60f: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
case 0x616: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 60f926c..13a6b29 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -104,7 +104,7 @@ static void flush_tlb_func(void *info)
return;

if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK) {
- if (f->flush_end == TLB_FLUSH_ALL || !cpu_has_invlpg)
+ if (f->flush_end == TLB_FLUSH_ALL)
local_flush_tlb();
else if (!f->flush_end)
__flush_tlb_single(f->flush_start);
@@ -337,10 +337,8 @@ static const struct file_operations fops_tlbflush = {

static int __cpuinit create_tlb_flushall_shift(void)
{
- if (cpu_has_invlpg) {
- debugfs_create_file("tlb_flushall_shift", S_IRUSR | S_IWUSR,
- arch_debugfs_dir, NULL, &fops_tlbflush);
- }
+ debugfs_create_file("tlb_flushall_shift", S_IRUSR | S_IWUSR,
+ arch_debugfs_dir, NULL, &fops_tlbflush);
return 0;
}
late_initcall(create_tlb_flushall_shift);

2012-12-01 00:40:06

by H. Peter Anvin

[permalink] [raw]
Subject: [tip:x86/nuke386] x86, 386 removal: Remove CONFIG_X86_WP_WORKS_OK

Commit-ID: a5c2a893dbd4956a72fb261e8790d19f67b52c99
Gitweb: http://git.kernel.org/tip/a5c2a893dbd4956a72fb261e8790d19f67b52c99
Author: H. Peter Anvin <[email protected]>
AuthorDate: Wed, 28 Nov 2012 11:50:28 -0800
Committer: H. Peter Anvin <[email protected]>
CommitDate: Thu, 29 Nov 2012 13:23:03 -0800

x86, 386 removal: Remove CONFIG_X86_WP_WORKS_OK

All 486+ CPUs support WP in supervisor mode, so remove the fallback
386 support code.

Signed-off-by: H. Peter Anvin <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
---
arch/x86/Kconfig.cpu | 3 ---
arch/x86/include/asm/uaccess.h | 42 -------------------------------
arch/x86/lib/usercopy_32.c | 57 ------------------------------------------
arch/x86/mm/init_32.c | 5 +---
4 files changed, 1 insertion(+), 106 deletions(-)

diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index d3bdc18..159ee9c 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -325,9 +325,6 @@ config X86_INVD_BUG
def_bool y
depends on M486

-config X86_WP_WORKS_OK
- def_bool y
-
config X86_POPAD_OK
def_bool y
depends on X86_32
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index 7ccf8d1..1709801 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -237,8 +237,6 @@ extern void __put_user_2(void);
extern void __put_user_4(void);
extern void __put_user_8(void);

-#ifdef CONFIG_X86_WP_WORKS_OK
-
/**
* put_user: - Write a simple value into user space.
* @x: Value to copy to user space.
@@ -326,29 +324,6 @@ do { \
} \
} while (0)

-#else
-
-#define __put_user_size(x, ptr, size, retval, errret) \
-do { \
- __typeof__(*(ptr))__pus_tmp = x; \
- retval = 0; \
- \
- if (unlikely(__copy_to_user_ll(ptr, &__pus_tmp, size) != 0)) \
- retval = errret; \
-} while (0)
-
-#define put_user(x, ptr) \
-({ \
- int __ret_pu; \
- __typeof__(*(ptr))__pus_tmp = x; \
- __ret_pu = 0; \
- if (unlikely(__copy_to_user_ll(ptr, &__pus_tmp, \
- sizeof(*(ptr))) != 0)) \
- __ret_pu = -EFAULT; \
- __ret_pu; \
-})
-#endif
-
#ifdef CONFIG_X86_32
#define __get_user_asm_u64(x, ptr, retval, errret) (x) = __get_user_bad()
#define __get_user_asm_ex_u64(x, ptr) (x) = __get_user_bad()
@@ -543,29 +518,12 @@ struct __large_struct { unsigned long buf[100]; };
(x) = (__force __typeof__(*(ptr)))__gue_val; \
} while (0)

-#ifdef CONFIG_X86_WP_WORKS_OK
-
#define put_user_try uaccess_try
#define put_user_catch(err) uaccess_catch(err)

#define put_user_ex(x, ptr) \
__put_user_size_ex((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))

-#else /* !CONFIG_X86_WP_WORKS_OK */
-
-#define put_user_try do { \
- int __uaccess_err = 0;
-
-#define put_user_catch(err) \
- (err) |= __uaccess_err; \
-} while (0)
-
-#define put_user_ex(x, ptr) do { \
- __uaccess_err |= __put_user(x, ptr); \
-} while (0)
-
-#endif /* CONFIG_X86_WP_WORKS_OK */
-
extern unsigned long
copy_from_user_nmi(void *to, const void __user *from, unsigned long n);
extern __must_check long
diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c
index 98f6d6b6..f0312d7 100644
--- a/arch/x86/lib/usercopy_32.c
+++ b/arch/x86/lib/usercopy_32.c
@@ -570,63 +570,6 @@ do { \
unsigned long __copy_to_user_ll(void __user *to, const void *from,
unsigned long n)
{
-#ifndef CONFIG_X86_WP_WORKS_OK
- if (unlikely(boot_cpu_data.wp_works_ok == 0) &&
- ((unsigned long)to) < TASK_SIZE) {
- /*
- * When we are in an atomic section (see
- * mm/filemap.c:file_read_actor), return the full
- * length to take the slow path.
- */
- if (in_atomic())
- return n;
-
- /*
- * CPU does not honor the WP bit when writing
- * from supervisory mode, and due to preemption or SMP,
- * the page tables can change at any time.
- * Do it manually. Manfred <[email protected]>
- */
- while (n) {
- unsigned long offset = ((unsigned long)to)%PAGE_SIZE;
- unsigned long len = PAGE_SIZE - offset;
- int retval;
- struct page *pg;
- void *maddr;
-
- if (len > n)
- len = n;
-
-survive:
- down_read(&current->mm->mmap_sem);
- retval = get_user_pages(current, current->mm,
- (unsigned long)to, 1, 1, 0, &pg, NULL);
-
- if (retval == -ENOMEM && is_global_init(current)) {
- up_read(&current->mm->mmap_sem);
- congestion_wait(BLK_RW_ASYNC, HZ/50);
- goto survive;
- }
-
- if (retval != 1) {
- up_read(&current->mm->mmap_sem);
- break;
- }
-
- maddr = kmap_atomic(pg);
- memcpy(maddr + offset, from, len);
- kunmap_atomic(maddr);
- set_page_dirty_lock(pg);
- put_page(pg);
- up_read(&current->mm->mmap_sem);
-
- from += len;
- to += len;
- n -= len;
- }
- return n;
- }
-#endif
stac();
if (movsl_is_ok(to, from, n))
__copy_user(to, from, n);
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 11a5800..745d66b 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -715,10 +715,7 @@ static void __init test_wp_bit(void)

if (!boot_cpu_data.wp_works_ok) {
printk(KERN_CONT "No.\n");
-#ifdef CONFIG_X86_WP_WORKS_OK
- panic(
- "This kernel doesn't support CPU's with broken WP. Recompile it for a 386!");
-#endif
+ panic("Linux doesn't support CPUs with broken WP.");
} else {
printk(KERN_CONT "Ok.\n");
}

2012-12-01 00:41:08

by H. Peter Anvin

[permalink] [raw]
Subject: [tip:x86/nuke386] x86, 386 removal: Remove CONFIG_X86_POPAD_OK

Commit-ID: e3228cf4544355f73437a2b9c6916be9cbafc201
Gitweb: http://git.kernel.org/tip/e3228cf4544355f73437a2b9c6916be9cbafc201
Author: H. Peter Anvin <[email protected]>
AuthorDate: Wed, 28 Nov 2012 11:50:29 -0800
Committer: H. Peter Anvin <[email protected]>
CommitDate: Thu, 29 Nov 2012 13:23:03 -0800

x86, 386 removal: Remove CONFIG_X86_POPAD_OK

The check_popad() routine tested for a 386-specific bug, and never
actually did anything useful with it anyway other than print a
message.

Signed-off-by: H. Peter Anvin <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
---
arch/x86/Kconfig.cpu | 4 ----
arch/x86/kernel/cpu/bugs.c | 28 ----------------------------
2 files changed, 32 deletions(-)

diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 159ee9c..423db71 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -325,10 +325,6 @@ config X86_INVD_BUG
def_bool y
depends on M486

-config X86_POPAD_OK
- def_bool y
- depends on X86_32
-
config X86_ALIGNMENT_16
def_bool y
depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 0cd07cc..92dfec9 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -107,33 +107,6 @@ static void __init check_hlt(void)
}

/*
- * Most 386 processors have a bug where a POPAD can lock the
- * machine even from user space.
- */
-
-static void __init check_popad(void)
-{
-#ifndef CONFIG_X86_POPAD_OK
- int res, inp = (int) &res;
-
- pr_info("Checking for popad bug... ");
- __asm__ __volatile__(
- "movl $12345678,%%eax; movl $0,%%edi; pusha; popa; movl (%%edx,%%edi),%%ecx "
- : "=&a" (res)
- : "d" (inp)
- : "ecx", "edi");
- /*
- * If this fails, it means that any user program may lock the
- * CPU hard. Too bad.
- */
- if (res != 12345678)
- pr_cont("Buggy\n");
- else
- pr_cont("OK\n");
-#endif
-}
-
-/*
* Check whether we are able to run this kernel safely on SMP.
*
* - i386 is no longer supported.
@@ -157,7 +130,6 @@ void __init check_bugs(void)
#endif
check_config();
check_hlt();
- check_popad();
init_utsname()->machine[1] =
'0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86);
alternative_instructions();

2012-12-01 00:42:29

by H. Peter Anvin

[permalink] [raw]
Subject: [tip:x86/nuke386] x86, cleanups: Simplify sync_core() in the case of no CPUID

Commit-ID: 45c39fb0cc20d24da08d5bb159f57d191098104d
Gitweb: http://git.kernel.org/tip/45c39fb0cc20d24da08d5bb159f57d191098104d
Author: H. Peter Anvin <[email protected]>
AuthorDate: Wed, 28 Nov 2012 11:50:30 -0800
Committer: H. Peter Anvin <[email protected]>
CommitDate: Thu, 29 Nov 2012 13:25:39 -0800

x86, cleanups: Simplify sync_core() in the case of no CPUID

Simplify the implementation of sync_core() for the case where we may
not have the CPUID instruction available.

[ v2: stylistic cleanup of the #else clause per suggestion by Borislav
Petkov. ]

Signed-off-by: H. Peter Anvin <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Cc: Borislav Petkov <[email protected]>
---
arch/x86/include/asm/processor.h | 31 +++++++++++++++++++++----------
1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 9a4ee46..b0d3e73 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -673,17 +673,28 @@ static inline void sync_core(void)
int tmp;

#ifdef CONFIG_M486
- if (boot_cpu_data.x86 < 5)
- /* There is no speculative execution.
- * jmp is a barrier to prefetching. */
- asm volatile("jmp 1f\n1:\n" ::: "memory");
- else
+ /*
+ * Do a CPUID if available, otherwise do a jump. The jump
+ * can conveniently enough be the jump around CPUID.
+ */
+ asm volatile("cmpl %2,%1\n\t"
+ "jl 1f\n\t"
+ "cpuid\n"
+ "1:"
+ : "=a" (tmp)
+ : "rm" (boot_cpu_data.cpuid_level), "ri" (0), "0" (1)
+ : "ebx", "ecx", "edx", "memory");
+#else
+ /*
+ * CPUID is a barrier to speculative execution.
+ * Prefetched instructions are automatically
+ * invalidated when modified.
+ */
+ asm volatile("cpuid"
+ : "=a" (tmp)
+ : "0" (1)
+ : "ebx", "ecx", "edx", "memory");
#endif
- /* cpuid is a barrier to speculative execution.
- * Prefetched instructions are automatically
- * invalidated when modified. */
- asm volatile("cpuid" : "=a" (tmp) : "0" (1)
- : "ebx", "ecx", "edx", "memory");
}

static inline void __monitor(const void *eax, unsigned long ecx,

2012-12-01 00:43:23

by H. Peter Anvin

[permalink] [raw]
Subject: [tip:x86/nuke386] x86, 386 removal: Document Nx586 as a 386 and thus unsupported

Commit-ID: 11af32b69ef7ee64c7d8848cad71a6f3749d9e37
Gitweb: http://git.kernel.org/tip/11af32b69ef7ee64c7d8848cad71a6f3749d9e37
Author: H. Peter Anvin <[email protected]>
AuthorDate: Thu, 29 Nov 2012 13:28:39 -0800
Committer: H. Peter Anvin <[email protected]>
CommitDate: Thu, 29 Nov 2012 13:28:39 -0800

x86, 386 removal: Document Nx586 as a 386 and thus unsupported

Per Alan Cox, Nx586 did not support WP in supervisor mode, making it a
386 by Linux kernel standards. As such, it is too unsupported now.

Reported-by: Alan Cox <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/Kconfig.cpu | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 423db71..c026cca 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -15,7 +15,7 @@ config M486

Note that the 386 is no longer supported, this includes
AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI 486DLC/DLC2,
- and UMC 486SX-S.
+ UMC 486SX-S and the NexGen Nx586.

The kernel will not necessarily run on earlier architectures than
the one you have chosen, e.g. a Pentium optimized kernel will run on