diff options
author | Fenghua Yu <fenghua.yu@intel.com> | 2013-03-19 11:04:44 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2013-03-19 22:51:08 -0400 |
commit | c83a9d5e425d4678b05ca058fec6254f18601474 (patch) | |
tree | 9fcab0ae6fa17816496cd7e1a16f0708dee3f660 /arch/x86/kernel | |
parent | 66db3feb486c01349f767b98ebb10b0c3d2d021b (diff) |
x86-32, microcode_intel_early: Fix crash with CONFIG_DEBUG_VIRTUAL
In 32-bit, __pa_symbol() in CONFIG_DEBUG_VIRTUAL accesses kernel data
(e.g. max_low_pfn) that not only hasn't been setup yet in such early
boot phase, but since we are in linear mode, cannot even be detected
as uninitialized.
Thus, use __pa_nodebug() rather than __pa_symbol() to get a global
symbol's physical address.
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Link: http://lkml.kernel.org/r/1363705484-27645-1-git-send-email-fenghua.yu@intel.com
Reported-and-tested-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/microcode_intel_early.c | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/arch/x86/kernel/microcode_intel_early.c b/arch/x86/kernel/microcode_intel_early.c index 7890bc838952..5992ee8086b7 100644 --- a/arch/x86/kernel/microcode_intel_early.c +++ b/arch/x86/kernel/microcode_intel_early.c | |||
@@ -90,13 +90,13 @@ microcode_phys(struct microcode_intel **mc_saved_tmp, | |||
90 | struct microcode_intel ***mc_saved; | 90 | struct microcode_intel ***mc_saved; |
91 | 91 | ||
92 | mc_saved = (struct microcode_intel ***) | 92 | mc_saved = (struct microcode_intel ***) |
93 | __pa_symbol(&mc_saved_data->mc_saved); | 93 | __pa_nodebug(&mc_saved_data->mc_saved); |
94 | for (i = 0; i < mc_saved_data->mc_saved_count; i++) { | 94 | for (i = 0; i < mc_saved_data->mc_saved_count; i++) { |
95 | struct microcode_intel *p; | 95 | struct microcode_intel *p; |
96 | 96 | ||
97 | p = *(struct microcode_intel **) | 97 | p = *(struct microcode_intel **) |
98 | __pa(mc_saved_data->mc_saved + i); | 98 | __pa_nodebug(mc_saved_data->mc_saved + i); |
99 | mc_saved_tmp[i] = (struct microcode_intel *)__pa(p); | 99 | mc_saved_tmp[i] = (struct microcode_intel *)__pa_nodebug(p); |
100 | } | 100 | } |
101 | } | 101 | } |
102 | #endif | 102 | #endif |
@@ -562,7 +562,7 @@ scan_microcode(unsigned long start, unsigned long end, | |||
562 | struct cpio_data cd; | 562 | struct cpio_data cd; |
563 | long offset = 0; | 563 | long offset = 0; |
564 | #ifdef CONFIG_X86_32 | 564 | #ifdef CONFIG_X86_32 |
565 | char *p = (char *)__pa_symbol(ucode_name); | 565 | char *p = (char *)__pa_nodebug(ucode_name); |
566 | #else | 566 | #else |
567 | char *p = ucode_name; | 567 | char *p = ucode_name; |
568 | #endif | 568 | #endif |
@@ -630,8 +630,8 @@ static void __cpuinit print_ucode(struct ucode_cpu_info *uci) | |||
630 | if (mc_intel == NULL) | 630 | if (mc_intel == NULL) |
631 | return; | 631 | return; |
632 | 632 | ||
633 | delay_ucode_info_p = (int *)__pa_symbol(&delay_ucode_info); | 633 | delay_ucode_info_p = (int *)__pa_nodebug(&delay_ucode_info); |
634 | current_mc_date_p = (int *)__pa_symbol(¤t_mc_date); | 634 | current_mc_date_p = (int *)__pa_nodebug(¤t_mc_date); |
635 | 635 | ||
636 | *delay_ucode_info_p = 1; | 636 | *delay_ucode_info_p = 1; |
637 | *current_mc_date_p = mc_intel->hdr.date; | 637 | *current_mc_date_p = mc_intel->hdr.date; |
@@ -741,15 +741,15 @@ load_ucode_intel_bsp(void) | |||
741 | #ifdef CONFIG_X86_32 | 741 | #ifdef CONFIG_X86_32 |
742 | struct boot_params *boot_params_p; | 742 | struct boot_params *boot_params_p; |
743 | 743 | ||
744 | boot_params_p = (struct boot_params *)__pa_symbol(&boot_params); | 744 | boot_params_p = (struct boot_params *)__pa_nodebug(&boot_params); |
745 | ramdisk_image = boot_params_p->hdr.ramdisk_image; | 745 | ramdisk_image = boot_params_p->hdr.ramdisk_image; |
746 | ramdisk_size = boot_params_p->hdr.ramdisk_size; | 746 | ramdisk_size = boot_params_p->hdr.ramdisk_size; |
747 | initrd_start_early = ramdisk_image; | 747 | initrd_start_early = ramdisk_image; |
748 | initrd_end_early = initrd_start_early + ramdisk_size; | 748 | initrd_end_early = initrd_start_early + ramdisk_size; |
749 | 749 | ||
750 | _load_ucode_intel_bsp( | 750 | _load_ucode_intel_bsp( |
751 | (struct mc_saved_data *)__pa_symbol(&mc_saved_data), | 751 | (struct mc_saved_data *)__pa_nodebug(&mc_saved_data), |
752 | (unsigned long *)__pa_symbol(&mc_saved_in_initrd), | 752 | (unsigned long *)__pa_nodebug(&mc_saved_in_initrd), |
753 | initrd_start_early, initrd_end_early, &uci); | 753 | initrd_start_early, initrd_end_early, &uci); |
754 | #else | 754 | #else |
755 | ramdisk_image = boot_params.hdr.ramdisk_image; | 755 | ramdisk_image = boot_params.hdr.ramdisk_image; |
@@ -772,10 +772,10 @@ void __cpuinit load_ucode_intel_ap(void) | |||
772 | unsigned long *initrd_start_p; | 772 | unsigned long *initrd_start_p; |
773 | 773 | ||
774 | mc_saved_in_initrd_p = | 774 | mc_saved_in_initrd_p = |
775 | (unsigned long *)__pa_symbol(mc_saved_in_initrd); | 775 | (unsigned long *)__pa_nodebug(mc_saved_in_initrd); |
776 | mc_saved_data_p = (struct mc_saved_data *)__pa_symbol(&mc_saved_data); | 776 | mc_saved_data_p = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data); |
777 | initrd_start_p = (unsigned long *)__pa_symbol(&initrd_start); | 777 | initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start); |
778 | initrd_start_addr = (unsigned long)__pa_symbol(*initrd_start_p); | 778 | initrd_start_addr = (unsigned long)__pa_nodebug(*initrd_start_p); |
779 | #else | 779 | #else |
780 | mc_saved_data_p = &mc_saved_data; | 780 | mc_saved_data_p = &mc_saved_data; |
781 | mc_saved_in_initrd_p = mc_saved_in_initrd; | 781 | mc_saved_in_initrd_p = mc_saved_in_initrd; |