aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/setup.c')
-rw-r--r--arch/x86/kernel/setup.c168
1 files changed, 20 insertions, 148 deletions
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index bdec76e55594..a31223828597 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -98,6 +98,7 @@
98 98
99#include <mach_apic.h> 99#include <mach_apic.h>
100#include <asm/paravirt.h> 100#include <asm/paravirt.h>
101#include <asm/hypervisor.h>
101 102
102#include <asm/percpu.h> 103#include <asm/percpu.h>
103#include <asm/topology.h> 104#include <asm/topology.h>
@@ -448,6 +449,7 @@ static void __init reserve_early_setup_data(void)
448 * @size: Size of the crashkernel memory to reserve. 449 * @size: Size of the crashkernel memory to reserve.
449 * Returns the base address on success, and -1ULL on failure. 450 * Returns the base address on success, and -1ULL on failure.
450 */ 451 */
452static
451unsigned long long __init find_and_reserve_crashkernel(unsigned long long size) 453unsigned long long __init find_and_reserve_crashkernel(unsigned long long size)
452{ 454{
453 const unsigned long long alignment = 16<<20; /* 16M */ 455 const unsigned long long alignment = 16<<20; /* 16M */
@@ -583,161 +585,24 @@ static int __init setup_elfcorehdr(char *arg)
583early_param("elfcorehdr", setup_elfcorehdr); 585early_param("elfcorehdr", setup_elfcorehdr);
584#endif 586#endif
585 587
586static struct x86_quirks default_x86_quirks __initdata; 588static int __init default_update_genapic(void)
587
588struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
589
590/*
591 * Some BIOSes seem to corrupt the low 64k of memory during events
592 * like suspend/resume and unplugging an HDMI cable. Reserve all
593 * remaining free memory in that area and fill it with a distinct
594 * pattern.
595 */
596#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
597#define MAX_SCAN_AREAS 8
598
599static int __read_mostly memory_corruption_check = -1;
600
601static unsigned __read_mostly corruption_check_size = 64*1024;
602static unsigned __read_mostly corruption_check_period = 60; /* seconds */
603
604static struct e820entry scan_areas[MAX_SCAN_AREAS];
605static int num_scan_areas;
606
607
608static int set_corruption_check(char *arg)
609{
610 char *end;
611
612 memory_corruption_check = simple_strtol(arg, &end, 10);
613
614 return (*end == 0) ? 0 : -EINVAL;
615}
616early_param("memory_corruption_check", set_corruption_check);
617
618static int set_corruption_check_period(char *arg)
619{
620 char *end;
621
622 corruption_check_period = simple_strtoul(arg, &end, 10);
623
624 return (*end == 0) ? 0 : -EINVAL;
625}
626early_param("memory_corruption_check_period", set_corruption_check_period);
627
628static int set_corruption_check_size(char *arg)
629{ 589{
630 char *end; 590#ifdef CONFIG_X86_SMP
631 unsigned size; 591# if defined(CONFIG_X86_GENERICARCH) || defined(CONFIG_X86_64)
632 592 genapic->wakeup_cpu = wakeup_secondary_cpu_via_init;
633 size = memparse(arg, &end); 593# endif
634
635 if (*end == '\0')
636 corruption_check_size = size;
637
638 return (size == corruption_check_size) ? 0 : -EINVAL;
639}
640early_param("memory_corruption_check_size", set_corruption_check_size);
641
642
643static void __init setup_bios_corruption_check(void)
644{
645 u64 addr = PAGE_SIZE; /* assume first page is reserved anyway */
646
647 if (memory_corruption_check == -1) {
648 memory_corruption_check =
649#ifdef CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK
650 1
651#else
652 0
653#endif 594#endif
654 ;
655 }
656
657 if (corruption_check_size == 0)
658 memory_corruption_check = 0;
659
660 if (!memory_corruption_check)
661 return;
662
663 corruption_check_size = round_up(corruption_check_size, PAGE_SIZE);
664 595
665 while(addr < corruption_check_size && num_scan_areas < MAX_SCAN_AREAS) { 596 return 0;
666 u64 size;
667 addr = find_e820_area_size(addr, &size, PAGE_SIZE);
668
669 if (addr == 0)
670 break;
671
672 if ((addr + size) > corruption_check_size)
673 size = corruption_check_size - addr;
674
675 if (size == 0)
676 break;
677
678 e820_update_range(addr, size, E820_RAM, E820_RESERVED);
679 scan_areas[num_scan_areas].addr = addr;
680 scan_areas[num_scan_areas].size = size;
681 num_scan_areas++;
682
683 /* Assume we've already mapped this early memory */
684 memset(__va(addr), 0, size);
685
686 addr += size;
687 }
688
689 printk(KERN_INFO "Scanning %d areas for low memory corruption\n",
690 num_scan_areas);
691 update_e820();
692}
693
694static struct timer_list periodic_check_timer;
695
696void check_for_bios_corruption(void)
697{
698 int i;
699 int corruption = 0;
700
701 if (!memory_corruption_check)
702 return;
703
704 for(i = 0; i < num_scan_areas; i++) {
705 unsigned long *addr = __va(scan_areas[i].addr);
706 unsigned long size = scan_areas[i].size;
707
708 for(; size; addr++, size -= sizeof(unsigned long)) {
709 if (!*addr)
710 continue;
711 printk(KERN_ERR "Corrupted low memory at %p (%lx phys) = %08lx\n",
712 addr, __pa(addr), *addr);
713 corruption = 1;
714 *addr = 0;
715 }
716 }
717
718 WARN(corruption, KERN_ERR "Memory corruption detected in low memory\n");
719}
720
721static void periodic_check_for_corruption(unsigned long data)
722{
723 check_for_bios_corruption();
724 mod_timer(&periodic_check_timer, round_jiffies(jiffies + corruption_check_period*HZ));
725} 597}
726 598
727void start_periodic_check_for_corruption(void) 599static struct x86_quirks default_x86_quirks __initdata = {
728{ 600 .update_genapic = default_update_genapic,
729 if (!memory_corruption_check || corruption_check_period == 0) 601};
730 return;
731
732 printk(KERN_INFO "Scanning for low memory corruption every %d seconds\n",
733 corruption_check_period);
734 602
735 init_timer(&periodic_check_timer); 603struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
736 periodic_check_timer.function = &periodic_check_for_corruption;
737 periodic_check_for_corruption(0);
738}
739#endif
740 604
605#ifdef CONFIG_X86_RESERVE_LOW_64K
741static int __init dmi_low_memory_corruption(const struct dmi_system_id *d) 606static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
742{ 607{
743 printk(KERN_NOTICE 608 printk(KERN_NOTICE
@@ -749,6 +614,7 @@ static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
749 614
750 return 0; 615 return 0;
751} 616}
617#endif
752 618
753/* List of systems that have known low memory corruption BIOS problems */ 619/* List of systems that have known low memory corruption BIOS problems */
754static struct dmi_system_id __initdata bad_bios_dmi_table[] = { 620static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
@@ -907,6 +773,12 @@ void __init setup_arch(char **cmdline_p)
907 773
908 dmi_check_system(bad_bios_dmi_table); 774 dmi_check_system(bad_bios_dmi_table);
909 775
776 /*
777 * VMware detection requires dmi to be available, so this
778 * needs to be done after dmi_scan_machine, for the BP.
779 */
780 init_hypervisor(&boot_cpu_data);
781
910#ifdef CONFIG_X86_32 782#ifdef CONFIG_X86_32
911 probe_roms(); 783 probe_roms();
912#endif 784#endif