x86, alternatives: Use 16-bit numbers for cpufeature index
authorH. Peter Anvin <hpa@linux.intel.com>
Thu, 10 Jun 2010 00:10:43 +0000 (00:10 +0000)
committerH. Peter Anvin <hpa@zytor.com>
Wed, 7 Jul 2010 17:36:28 +0000 (10:36 -0700)
We already have cpufeature indicies above 255, so use a 16-bit number
for the alternatives index.  This consumes a padding field and so
doesn't add any size, but it means that abusing the padding field to
create assembly errors on overflow no longer works.  We can retain the
test simply by redirecting it to the .discard section, however.

[ v3: updated to include open-coded locations ]

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
LKML-Reference: <tip-f88731e3068f9d1392ba71cc9f50f035d26a0d4f@git.kernel.org>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
arch/x86/include/asm/alternative.h
arch/x86/include/asm/cpufeature.h
arch/x86/kernel/entry_32.S
arch/x86/lib/clear_page_64.S
arch/x86/lib/copy_page_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 468145914389942273f2d68c5b9d57b48bf84a8e..e8b88967de35ad8bdc5c9ef8f1d8aead2f7ef3f8 100644 (file)
@@ -291,7 +291,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"
@@ -300,11 +300,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:
@@ -318,10 +318,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"
@@ -337,7 +339,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 cd49141cf153fb124dc46a6497dbc863a3c81ad9..7862cf510ea94ae8b0340bca4de9b7961eae5088 100644 (file)
@@ -914,7 +914,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 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