diff options
| author | Ingo Molnar <mingo@elte.hu> | 2010-09-24 03:12:05 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-09-24 03:12:05 -0400 |
| commit | a5a2bad55de89a0adf7d6f783cb87ab7eb1a894f (patch) | |
| tree | 452cb8addc26f5c79fdd4e2fea92c78dc17fc8e8 /arch/x86 | |
| parent | d0303d71c2fb9bcb90a8d48e6462c78c86f70ce6 (diff) | |
| parent | 46eb3b64dddd20f44e76b08676fa642dd374bf1d (diff) | |
Merge branch 'tip/perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace into perf/core
Diffstat (limited to 'arch/x86')
| -rw-r--r-- | arch/x86/Kconfig | 1 | ||||
| -rw-r--r-- | arch/x86/include/asm/alternative.h | 11 | ||||
| -rw-r--r-- | arch/x86/include/asm/jump_label.h | 37 | ||||
| -rw-r--r-- | arch/x86/kernel/Makefile | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/alternative.c | 68 | ||||
| -rw-r--r-- | arch/x86/kernel/ftrace.c | 63 | ||||
| -rw-r--r-- | arch/x86/kernel/jump_label.c | 50 | ||||
| -rw-r--r-- | arch/x86/kernel/kprobes.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/module.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/setup.c | 6 |
10 files changed, 178 insertions, 66 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index cea0cd9a316f..b431a0824a93 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -59,6 +59,7 @@ config X86 | |||
| 59 | select ANON_INODES | 59 | select ANON_INODES |
| 60 | select HAVE_ARCH_KMEMCHECK | 60 | select HAVE_ARCH_KMEMCHECK |
| 61 | select HAVE_USER_RETURN_NOTIFIER | 61 | select HAVE_USER_RETURN_NOTIFIER |
| 62 | select HAVE_ARCH_JUMP_LABEL | ||
| 62 | 63 | ||
| 63 | config INSTRUCTION_DECODER | 64 | config INSTRUCTION_DECODER |
| 64 | def_bool (KPROBES || PERF_EVENTS) | 65 | def_bool (KPROBES || PERF_EVENTS) |
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index bc6abb7bc7ee..76561d20ea2f 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
| 5 | #include <linux/stddef.h> | 5 | #include <linux/stddef.h> |
| 6 | #include <linux/stringify.h> | 6 | #include <linux/stringify.h> |
| 7 | #include <linux/jump_label.h> | ||
| 7 | #include <asm/asm.h> | 8 | #include <asm/asm.h> |
| 8 | 9 | ||
| 9 | /* | 10 | /* |
| @@ -160,6 +161,8 @@ static inline void apply_paravirt(struct paravirt_patch_site *start, | |||
| 160 | #define __parainstructions_end NULL | 161 | #define __parainstructions_end NULL |
| 161 | #endif | 162 | #endif |
| 162 | 163 | ||
| 164 | extern void *text_poke_early(void *addr, const void *opcode, size_t len); | ||
| 165 | |||
| 163 | /* | 166 | /* |
| 164 | * Clear and restore the kernel write-protection flag on the local CPU. | 167 | * Clear and restore the kernel write-protection flag on the local CPU. |
| 165 | * Allows the kernel to edit read-only pages. | 168 | * Allows the kernel to edit read-only pages. |
| @@ -180,4 +183,12 @@ static inline void apply_paravirt(struct paravirt_patch_site *start, | |||
| 180 | extern void *text_poke(void *addr, const void *opcode, size_t len); | 183 | extern void *text_poke(void *addr, const void *opcode, size_t len); |
| 181 | extern void *text_poke_smp(void *addr, const void *opcode, size_t len); | 184 | extern void *text_poke_smp(void *addr, const void *opcode, size_t len); |
| 182 | 185 | ||
| 186 | #if defined(CONFIG_DYNAMIC_FTRACE) || defined(HAVE_JUMP_LABEL) | ||
| 187 | #define IDEAL_NOP_SIZE_5 5 | ||
| 188 | extern unsigned char ideal_nop5[IDEAL_NOP_SIZE_5]; | ||
| 189 | extern void arch_init_ideal_nop5(void); | ||
| 190 | #else | ||
| 191 | static inline void arch_init_ideal_nop5(void) {} | ||
| 192 | #endif | ||
| 193 | |||
| 183 | #endif /* _ASM_X86_ALTERNATIVE_H */ | 194 | #endif /* _ASM_X86_ALTERNATIVE_H */ |
diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h new file mode 100644 index 000000000000..f52d42e80585 --- /dev/null +++ b/arch/x86/include/asm/jump_label.h | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | #ifndef _ASM_X86_JUMP_LABEL_H | ||
| 2 | #define _ASM_X86_JUMP_LABEL_H | ||
| 3 | |||
| 4 | #ifdef __KERNEL__ | ||
| 5 | |||
| 6 | #include <linux/types.h> | ||
| 7 | #include <asm/nops.h> | ||
| 8 | |||
| 9 | #define JUMP_LABEL_NOP_SIZE 5 | ||
| 10 | |||
| 11 | # define JUMP_LABEL_INITIAL_NOP ".byte 0xe9 \n\t .long 0\n\t" | ||
| 12 | |||
| 13 | # define JUMP_LABEL(key, label) \ | ||
| 14 | do { \ | ||
| 15 | asm goto("1:" \ | ||
| 16 | JUMP_LABEL_INITIAL_NOP \ | ||
| 17 | ".pushsection __jump_table, \"a\" \n\t"\ | ||
| 18 | _ASM_PTR "1b, %l[" #label "], %c0 \n\t" \ | ||
| 19 | ".popsection \n\t" \ | ||
| 20 | : : "i" (key) : : label); \ | ||
| 21 | } while (0) | ||
| 22 | |||
| 23 | #endif /* __KERNEL__ */ | ||
| 24 | |||
| 25 | #ifdef CONFIG_X86_64 | ||
| 26 | typedef u64 jump_label_t; | ||
| 27 | #else | ||
| 28 | typedef u32 jump_label_t; | ||
| 29 | #endif | ||
| 30 | |||
| 31 | struct jump_entry { | ||
| 32 | jump_label_t code; | ||
| 33 | jump_label_t target; | ||
| 34 | jump_label_t key; | ||
| 35 | }; | ||
| 36 | |||
| 37 | #endif | ||
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 0925676266bd..24fa1718ddb9 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
| @@ -32,7 +32,7 @@ GCOV_PROFILE_paravirt.o := n | |||
| 32 | obj-y := process_$(BITS).o signal.o entry_$(BITS).o | 32 | obj-y := process_$(BITS).o signal.o entry_$(BITS).o |
| 33 | obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o | 33 | obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o |
| 34 | obj-y += time.o ioport.o ldt.o dumpstack.o | 34 | obj-y += time.o ioport.o ldt.o dumpstack.o |
| 35 | obj-y += setup.o x86_init.o i8259.o irqinit.o | 35 | obj-y += setup.o x86_init.o i8259.o irqinit.o jump_label.o |
| 36 | obj-$(CONFIG_X86_VISWS) += visws_quirks.o | 36 | obj-$(CONFIG_X86_VISWS) += visws_quirks.o |
| 37 | obj-$(CONFIG_X86_32) += probe_roms_32.o | 37 | obj-$(CONFIG_X86_32) += probe_roms_32.o |
| 38 | obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o | 38 | obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o |
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index f65ab8b014c4..cb0e6d385f6d 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c | |||
| @@ -195,7 +195,7 @@ static void __init_or_module add_nops(void *insns, unsigned int len) | |||
| 195 | 195 | ||
| 196 | extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; | 196 | extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; |
| 197 | extern s32 __smp_locks[], __smp_locks_end[]; | 197 | extern s32 __smp_locks[], __smp_locks_end[]; |
| 198 | static void *text_poke_early(void *addr, const void *opcode, size_t len); | 198 | void *text_poke_early(void *addr, const void *opcode, size_t len); |
| 199 | 199 | ||
| 200 | /* Replace instructions with better alternatives for this CPU type. | 200 | /* Replace instructions with better alternatives for this CPU type. |
| 201 | This runs before SMP is initialized to avoid SMP problems with | 201 | This runs before SMP is initialized to avoid SMP problems with |
| @@ -522,7 +522,7 @@ void __init alternative_instructions(void) | |||
| 522 | * instructions. And on the local CPU you need to be protected again NMI or MCE | 522 | * instructions. And on the local CPU you need to be protected again NMI or MCE |
| 523 | * handlers seeing an inconsistent instruction while you patch. | 523 | * handlers seeing an inconsistent instruction while you patch. |
| 524 | */ | 524 | */ |
| 525 | static void *__init_or_module text_poke_early(void *addr, const void *opcode, | 525 | void *__init_or_module text_poke_early(void *addr, const void *opcode, |
| 526 | size_t len) | 526 | size_t len) |
| 527 | { | 527 | { |
| 528 | unsigned long flags; | 528 | unsigned long flags; |
| @@ -641,3 +641,67 @@ void *__kprobes text_poke_smp(void *addr, const void *opcode, size_t len) | |||
| 641 | return addr; | 641 | return addr; |
| 642 | } | 642 | } |
| 643 | 643 | ||
| 644 | #if defined(CONFIG_DYNAMIC_FTRACE) || defined(HAVE_JUMP_LABEL) | ||
| 645 | |||
| 646 | unsigned char ideal_nop5[IDEAL_NOP_SIZE_5]; | ||
| 647 | |||
| 648 | void __init arch_init_ideal_nop5(void) | ||
| 649 | { | ||
| 650 | extern const unsigned char ftrace_test_p6nop[]; | ||
| 651 | extern const unsigned char ftrace_test_nop5[]; | ||
| 652 | extern const unsigned char ftrace_test_jmp[]; | ||
| 653 | int faulted = 0; | ||
| 654 | |||
| 655 | /* | ||
| 656 | * There is no good nop for all x86 archs. | ||
| 657 | * We will default to using the P6_NOP5, but first we | ||
| 658 | * will test to make sure that the nop will actually | ||
| 659 | * work on this CPU. If it faults, we will then | ||
| 660 | * go to a lesser efficient 5 byte nop. If that fails | ||
| 661 | * we then just use a jmp as our nop. This isn't the most | ||
| 662 | * efficient nop, but we can not use a multi part nop | ||
| 663 | * since we would then risk being preempted in the middle | ||
| 664 | * of that nop, and if we enabled tracing then, it might | ||
| 665 | * cause a system crash. | ||
| 666 | * | ||
| 667 | * TODO: check the cpuid to determine the best nop. | ||
| 668 | */ | ||
| 669 | asm volatile ( | ||
| 670 | "ftrace_test_jmp:" | ||
| 671 | "jmp ftrace_test_p6nop\n" | ||
| 672 | "nop\n" | ||
| 673 | "nop\n" | ||
| 674 | "nop\n" /* 2 byte jmp + 3 bytes */ | ||
| 675 | "ftrace_test_p6nop:" | ||
| 676 | P6_NOP5 | ||
| 677 | "jmp 1f\n" | ||
| 678 | "ftrace_test_nop5:" | ||
| 679 | ".byte 0x66,0x66,0x66,0x66,0x90\n" | ||
| 680 | "1:" | ||
| 681 | ".section .fixup, \"ax\"\n" | ||
| 682 | "2: movl $1, %0\n" | ||
| 683 | " jmp ftrace_test_nop5\n" | ||
| 684 | "3: movl $2, %0\n" | ||
| 685 | " jmp 1b\n" | ||
| 686 | ".previous\n" | ||
| 687 | _ASM_EXTABLE(ftrace_test_p6nop, 2b) | ||
| 688 | _ASM_EXTABLE(ftrace_test_nop5, 3b) | ||
| 689 | : "=r"(faulted) : "0" (faulted)); | ||
| 690 | |||
| 691 | switch (faulted) { | ||
| 692 | case 0: | ||
| 693 | pr_info("converting mcount calls to 0f 1f 44 00 00\n"); | ||
| 694 | memcpy(ideal_nop5, ftrace_test_p6nop, IDEAL_NOP_SIZE_5); | ||
| 695 | break; | ||
| 696 | case 1: | ||
| 697 | pr_info("converting mcount calls to 66 66 66 66 90\n"); | ||
| 698 | memcpy(ideal_nop5, ftrace_test_nop5, IDEAL_NOP_SIZE_5); | ||
| 699 | break; | ||
| 700 | case 2: | ||
| 701 | pr_info("converting mcount calls to jmp . + 5\n"); | ||
| 702 | memcpy(ideal_nop5, ftrace_test_jmp, IDEAL_NOP_SIZE_5); | ||
| 703 | break; | ||
| 704 | } | ||
| 705 | |||
| 706 | } | ||
| 707 | #endif | ||
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index cd37469b54ee..3afb33f14d2d 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c | |||
| @@ -257,14 +257,9 @@ do_ftrace_mod_code(unsigned long ip, void *new_code) | |||
| 257 | return mod_code_status; | 257 | return mod_code_status; |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | |||
| 261 | |||
| 262 | |||
| 263 | static unsigned char ftrace_nop[MCOUNT_INSN_SIZE]; | ||
| 264 | |||
| 265 | static unsigned char *ftrace_nop_replace(void) | 260 | static unsigned char *ftrace_nop_replace(void) |
| 266 | { | 261 | { |
| 267 | return ftrace_nop; | 262 | return ideal_nop5; |
| 268 | } | 263 | } |
| 269 | 264 | ||
| 270 | static int | 265 | static int |
| @@ -338,62 +333,6 @@ int ftrace_update_ftrace_func(ftrace_func_t func) | |||
| 338 | 333 | ||
| 339 | int __init ftrace_dyn_arch_init(void *data) | 334 | int __init ftrace_dyn_arch_init(void *data) |
| 340 | { | 335 | { |
| 341 | extern const unsigned char ftrace_test_p6nop[]; | ||
| 342 | extern const unsigned char ftrace_test_nop5[]; | ||
| 343 | extern const unsigned char ftrace_test_jmp[]; | ||
| 344 | int faulted = 0; | ||
| 345 | |||
| 346 | /* | ||
| 347 | * There is no good nop for all x86 archs. | ||
| 348 | * We will default to using the P6_NOP5, but first we | ||
| 349 | * will test to make sure that the nop will actually | ||
| 350 | * work on this CPU. If it faults, we will then | ||
| 351 | * go to a lesser efficient 5 byte nop. If that fails | ||
| 352 | * we then just use a jmp as our nop. This isn't the most | ||
| 353 | * efficient nop, but we can not use a multi part nop | ||
| 354 | * since we would then risk being preempted in the middle | ||
| 355 | * of that nop, and if we enabled tracing then, it might | ||
| 356 | * cause a system crash. | ||
| 357 | * | ||
| 358 | * TODO: check the cpuid to determine the best nop. | ||
| 359 | */ | ||
| 360 | asm volatile ( | ||
| 361 | "ftrace_test_jmp:" | ||
| 362 | "jmp ftrace_test_p6nop\n" | ||
| 363 | "nop\n" | ||
| 364 | "nop\n" | ||
| 365 | "nop\n" /* 2 byte jmp + 3 bytes */ | ||
| 366 | "ftrace_test_p6nop:" | ||
| 367 | P6_NOP5 | ||
| 368 | "jmp 1f\n" | ||
| 369 | "ftrace_test_nop5:" | ||
| 370 | ".byte 0x66,0x66,0x66,0x66,0x90\n" | ||
| 371 | "1:" | ||
| 372 | ".section .fixup, \"ax\"\n" | ||
| 373 | "2: movl $1, %0\n" | ||
| 374 | " jmp ftrace_test_nop5\n" | ||
| 375 | "3: movl $2, %0\n" | ||
| 376 | " jmp 1b\n" | ||
| 377 | ".previous\n" | ||
| 378 | _ASM_EXTABLE(ftrace_test_p6nop, 2b) | ||
| 379 | _ASM_EXTABLE(ftrace_test_nop5, 3b) | ||
| 380 | : "=r"(faulted) : "0" (faulted)); | ||
| 381 | |||
| 382 | switch (faulted) { | ||
| 383 | case 0: | ||
| 384 | pr_info("converting mcount calls to 0f 1f 44 00 00\n"); | ||
| 385 | memcpy(ftrace_nop, ftrace_test_p6nop, MCOUNT_INSN_SIZE); | ||
| 386 | break; | ||
| 387 | case 1: | ||
| 388 | pr_info("converting mcount calls to 66 66 66 66 90\n"); | ||
| 389 | memcpy(ftrace_nop, ftrace_test_nop5, MCOUNT_INSN_SIZE); | ||
| 390 | break; | ||
| 391 | case 2: | ||
| 392 | pr_info("converting mcount calls to jmp . + 5\n"); | ||
| 393 | memcpy(ftrace_nop, ftrace_test_jmp, MCOUNT_INSN_SIZE); | ||
| 394 | break; | ||
| 395 | } | ||
| 396 | |||
| 397 | /* The return code is retured via data */ | 336 | /* The return code is retured via data */ |
| 398 | *(unsigned long *)data = 0; | 337 | *(unsigned long *)data = 0; |
| 399 | 338 | ||
diff --git a/arch/x86/kernel/jump_label.c b/arch/x86/kernel/jump_label.c new file mode 100644 index 000000000000..961b6b30ba90 --- /dev/null +++ b/arch/x86/kernel/jump_label.c | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | /* | ||
| 2 | * jump label x86 support | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009 Jason Baron <jbaron@redhat.com> | ||
| 5 | * | ||
| 6 | */ | ||
| 7 | #include <linux/jump_label.h> | ||
| 8 | #include <linux/memory.h> | ||
| 9 | #include <linux/uaccess.h> | ||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/list.h> | ||
| 12 | #include <linux/jhash.h> | ||
| 13 | #include <linux/cpu.h> | ||
| 14 | #include <asm/kprobes.h> | ||
| 15 | #include <asm/alternative.h> | ||
| 16 | |||
| 17 | #ifdef HAVE_JUMP_LABEL | ||
| 18 | |||
| 19 | union jump_code_union { | ||
| 20 | char code[JUMP_LABEL_NOP_SIZE]; | ||
| 21 | struct { | ||
| 22 | char jump; | ||
| 23 | int offset; | ||
| 24 | } __attribute__((packed)); | ||
| 25 | }; | ||
| 26 | |||
| 27 | void arch_jump_label_transform(struct jump_entry *entry, | ||
| 28 | enum jump_label_type type) | ||
| 29 | { | ||
| 30 | union jump_code_union code; | ||
| 31 | |||
| 32 | if (type == JUMP_LABEL_ENABLE) { | ||
| 33 | code.jump = 0xe9; | ||
| 34 | code.offset = entry->target - | ||
| 35 | (entry->code + JUMP_LABEL_NOP_SIZE); | ||
| 36 | } else | ||
| 37 | memcpy(&code, ideal_nop5, JUMP_LABEL_NOP_SIZE); | ||
| 38 | get_online_cpus(); | ||
| 39 | mutex_lock(&text_mutex); | ||
| 40 | text_poke_smp((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE); | ||
| 41 | mutex_unlock(&text_mutex); | ||
| 42 | put_online_cpus(); | ||
| 43 | } | ||
| 44 | |||
| 45 | void arch_jump_label_text_poke_early(jump_label_t addr) | ||
| 46 | { | ||
| 47 | text_poke_early((void *)addr, ideal_nop5, JUMP_LABEL_NOP_SIZE); | ||
| 48 | } | ||
| 49 | |||
| 50 | #endif | ||
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index e05952af5d26..1cbd54c0df99 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c | |||
| @@ -1218,7 +1218,8 @@ static int __kprobes copy_optimized_instructions(u8 *dest, u8 *src) | |||
| 1218 | } | 1218 | } |
| 1219 | /* Check whether the address range is reserved */ | 1219 | /* Check whether the address range is reserved */ |
| 1220 | if (ftrace_text_reserved(src, src + len - 1) || | 1220 | if (ftrace_text_reserved(src, src + len - 1) || |
| 1221 | alternatives_text_reserved(src, src + len - 1)) | 1221 | alternatives_text_reserved(src, src + len - 1) || |
| 1222 | jump_label_text_reserved(src, src + len - 1)) | ||
| 1222 | return -EBUSY; | 1223 | return -EBUSY; |
| 1223 | 1224 | ||
| 1224 | return len; | 1225 | return len; |
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index e0bc186d7501..5399f58de7ed 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c | |||
| @@ -239,6 +239,9 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
| 239 | apply_paravirt(pseg, pseg + para->sh_size); | 239 | apply_paravirt(pseg, pseg + para->sh_size); |
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | /* make jump label nops */ | ||
| 243 | jump_label_apply_nops(me); | ||
| 244 | |||
| 242 | return module_bug_finalize(hdr, sechdrs, me); | 245 | return module_bug_finalize(hdr, sechdrs, me); |
| 243 | } | 246 | } |
| 244 | 247 | ||
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index c3a4fbb2b996..00e167870f71 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
| @@ -112,6 +112,7 @@ | |||
| 112 | #include <asm/numa_64.h> | 112 | #include <asm/numa_64.h> |
| 113 | #endif | 113 | #endif |
| 114 | #include <asm/mce.h> | 114 | #include <asm/mce.h> |
| 115 | #include <asm/alternative.h> | ||
| 115 | 116 | ||
| 116 | /* | 117 | /* |
| 117 | * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries. | 118 | * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries. |
| @@ -726,6 +727,7 @@ void __init setup_arch(char **cmdline_p) | |||
| 726 | { | 727 | { |
| 727 | int acpi = 0; | 728 | int acpi = 0; |
| 728 | int k8 = 0; | 729 | int k8 = 0; |
| 730 | unsigned long flags; | ||
| 729 | 731 | ||
| 730 | #ifdef CONFIG_X86_32 | 732 | #ifdef CONFIG_X86_32 |
| 731 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); | 733 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); |
| @@ -1071,6 +1073,10 @@ void __init setup_arch(char **cmdline_p) | |||
| 1071 | x86_init.oem.banner(); | 1073 | x86_init.oem.banner(); |
| 1072 | 1074 | ||
| 1073 | mcheck_init(); | 1075 | mcheck_init(); |
| 1076 | |||
| 1077 | local_irq_save(flags); | ||
| 1078 | arch_init_ideal_nop5(); | ||
| 1079 | local_irq_restore(flags); | ||
| 1074 | } | 1080 | } |
| 1075 | 1081 | ||
| 1076 | #ifdef CONFIG_X86_32 | 1082 | #ifdef CONFIG_X86_32 |
