Merge branch 'x86-alternatives-for-linus' of git://git.kernel.org/pub/scm/linux/kerne...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 6 Aug 2010 23:24:17 +0000 (16:24 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 6 Aug 2010 23:24:17 +0000 (16:24 -0700)
* 'x86-alternatives-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86, alternatives: BUG on encountering an invalid CPU feature number
  x86, alternatives: Fix one more open-coded 8-bit alternative number
  x86, alternatives: Use 16-bit numbers for cpufeature index

arch/x86/include/asm/alternative.h
arch/x86/include/asm/cpufeature.h
arch/x86/kernel/alternative.c
arch/x86/kernel/entry_32.S
arch/x86/lib/clear_page_64.S
arch/x86/lib/copy_page_64.S
arch/x86/lib/copy_user_64.S
arch/x86/lib/memcpy_64.S
arch/x86/lib/memset_64.S

index 03b6bb5394a02d7211f79a00d0b87e2f74e5cbc7..bc6abb7bc7ee3084aa8b5d87ae19244715469990 100644 (file)
 struct alt_instr {
        u8 *instr;              /* original instruction */
        u8 *replacement;
-       u cpuid;              /* cpuid bit set for replacement */
+       u16 cpuid;              /* cpuid bit set for replacement */
        u8  instrlen;           /* length of original instruction */
        u8  replacementlen;     /* length of new instruction, <= instrlen */
-       u8  pad1;
 #ifdef CONFIG_X86_64
        u32 pad2;
 #endif
@@ -86,9 +85,11 @@ static inline int alternatives_text_reserved(void *start, void *end)
       _ASM_ALIGN "\n"                                                  \
       _ASM_PTR "661b\n"                                /* label           */   \
       _ASM_PTR "663f\n"                                /* new instruction */   \
-      "         .byte " __stringify(feature) "\n"      /* feature bit     */   \
+      "         .word " __stringify(feature) "\n"      /* feature bit     */   \
       "         .byte 662b-661b\n"                     /* sourcelen       */   \
       "         .byte 664f-663f\n"                     /* replacementlen  */   \
+      ".previous\n"                                                    \
+      ".section .discard,\"aw\",@progbits\n"                           \
       "         .byte 0xff + (664f-663f) - (662b-661b)\n" /* rlen <= slen */   \
       ".previous\n"                                                    \
       ".section .altinstr_replacement, \"ax\"\n"                       \
index 0b205b8a4308f6317d2ae2f00eb2ee2bb7dd2ec1..781a50b29a4917545e71c3e74bdcbbda7faa383d 100644 (file)
@@ -302,7 +302,7 @@ extern const char * const x86_power_flags[32];
  * patch the target code for additional performance.
  *
  */
-static __always_inline __pure bool __static_cpu_has(u8 bit)
+static __always_inline __pure bool __static_cpu_has(u16 bit)
 {
 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
                asm goto("1: jmp %l[t_no]\n"
@@ -311,11 +311,11 @@ static __always_inline __pure bool __static_cpu_has(u8 bit)
                         _ASM_ALIGN "\n"
                         _ASM_PTR "1b\n"
                         _ASM_PTR "0\n"         /* no replacement */
-                        " .byte %P0\n"         /* feature bit */
+                        " .word %P0\n"         /* feature bit */
                         " .byte 2b - 1b\n"     /* source len */
                         " .byte 0\n"           /* replacement len */
-                        " .byte 0xff + 0 - (2b-1b)\n"  /* padding */
                         ".previous\n"
+                        /* skipping size check since replacement size = 0 */
                         : : "i" (bit) : : t_no);
                return true;
        t_no:
@@ -329,10 +329,12 @@ static __always_inline __pure bool __static_cpu_has(u8 bit)
                             _ASM_ALIGN "\n"
                             _ASM_PTR "1b\n"
                             _ASM_PTR "3f\n"
-                            " .byte %P1\n"             /* feature bit */
+                            " .word %P1\n"             /* feature bit */
                             " .byte 2b - 1b\n"         /* source len */
                             " .byte 4f - 3f\n"         /* replacement len */
-                            " .byte 0xff + (4f-3f) - (2b-1b)\n" /* padding */
+                            ".previous\n"
+                            ".section .discard,\"aw\",@progbits\n"
+                            " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */
                             ".previous\n"
                             ".section .altinstr_replacement,\"ax\"\n"
                             "3: movb $1,%0\n"
@@ -348,7 +350,7 @@ static __always_inline __pure bool __static_cpu_has(u8 bit)
 (                                                              \
        __builtin_constant_p(boot_cpu_has(bit)) ?               \
                boot_cpu_has(bit) :                             \
-       (__builtin_constant_p(bit) && !((bit) & ~0xff)) ?       \
+       __builtin_constant_p(bit) ?                             \
                __static_cpu_has(bit) :                         \
                boot_cpu_has(bit)                               \
 )
index 70237732a6c7c5f62f941d5df0594f7386ca6a10..f65ab8b014c4f42421d77200243c39c7fd252165 100644 (file)
@@ -214,6 +214,7 @@ void __init_or_module apply_alternatives(struct alt_instr *start,
                u8 *instr = a->instr;
                BUG_ON(a->replacementlen > a->instrlen);
                BUG_ON(a->instrlen > sizeof(insnbuf));
+               BUG_ON(a->cpuid >= NCAPINTS*32);
                if (!boot_cpu_has(a->cpuid))
                        continue;
 #ifdef CONFIG_X86_64
index 258e93fa26304d08fddcc5f9b75f5ff0757eafba..227d00920d2f8eaa1d90340ced0261ffe0a8f859 100644 (file)
@@ -913,7 +913,7 @@ ENTRY(simd_coprocessor_error)
        .balign 4
        .long 661b
        .long 663f
-       .byte X86_FEATURE_XMM
+       .word X86_FEATURE_XMM
        .byte 662b-661b
        .byte 664f-663f
 .previous
index ebeafcce04a9bd595b645af6941429fe8fc26c62..aa4326bfb24a1dc6dbe2b131dd7c7c19bb58d58d 100644 (file)
@@ -52,7 +52,7 @@ ENDPROC(clear_page)
        .align 8
        .quad clear_page
        .quad 1b
-       .byte X86_FEATURE_REP_GOOD
+       .word X86_FEATURE_REP_GOOD
        .byte .Lclear_page_end - clear_page
        .byte 2b - 1b
        .previous
index 727a5d46d2fc0cfb6888053a698841fb6e9732f9..6fec2d1cebe111a5d9a5be1528e2370743088dcc 100644 (file)
@@ -113,7 +113,7 @@ ENDPROC(copy_page)
        .align 8
        .quad copy_page
        .quad 1b
-       .byte X86_FEATURE_REP_GOOD
+       .word X86_FEATURE_REP_GOOD
        .byte .Lcopy_page_end - copy_page
        .byte 2b - 1b
        .previous
index 71100c98e337026e39afbb059c520f95edb9a01e..a460158b5ac5b76b8d5086b7d1d5a058aa4feef4 100644 (file)
@@ -29,7 +29,7 @@
        .align 8
        .quad  0b
        .quad  2b
-       .byte  \feature                 /* when feature is set */
+       .word  \feature                 /* when feature is set */
        .byte  5
        .byte  5
        .previous
index f82e884928af6643854f64df5899c42ab6fee9b2..bcbcd1e0f7d57fe4b3972adc24785dc6837386f6 100644 (file)
@@ -131,7 +131,7 @@ ENDPROC(__memcpy)
        .align 8
        .quad memcpy
        .quad .Lmemcpy_c
-       .byte X86_FEATURE_REP_GOOD
+       .word X86_FEATURE_REP_GOOD
 
        /*
         * Replace only beginning, memcpy is used to apply alternatives,
index e88d3b81644a8736bcba56acaef56328c39e77ff..09d3442696522e19aea8adb9efdbfd051d8d57aa 100644 (file)
@@ -121,7 +121,7 @@ ENDPROC(__memset)
        .align 8
        .quad memset
        .quad .Lmemset_c
-       .byte X86_FEATURE_REP_GOOD
+       .word X86_FEATURE_REP_GOOD
        .byte .Lfinal - memset
        .byte .Lmemset_e - .Lmemset_c
        .previous