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.c80
1 files changed, 60 insertions, 20 deletions
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index c239b378097..27ae9128885 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -586,22 +586,71 @@ struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
586 */ 586 */
587#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION 587#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
588#define MAX_SCAN_AREAS 8 588#define MAX_SCAN_AREAS 8
589
590static int __read_mostly memory_corruption_check = 0;
591static unsigned __read_mostly corruption_check_size = 64*1024;
592static unsigned __read_mostly corruption_check_period = 60; /* seconds */
593
589static struct e820entry scan_areas[MAX_SCAN_AREAS]; 594static struct e820entry scan_areas[MAX_SCAN_AREAS];
590static int num_scan_areas; 595static int num_scan_areas;
591 596
597
598static int set_corruption_check(char *arg)
599{
600 char *end;
601
602 memory_corruption_check = simple_strtol(arg, &end, 10);
603
604 return (*end == 0) ? 0 : -EINVAL;
605}
606early_param("memory_corruption_check", set_corruption_check);
607
608static int set_corruption_check_period(char *arg)
609{
610 char *end;
611
612 corruption_check_period = simple_strtoul(arg, &end, 10);
613
614 return (*end == 0) ? 0 : -EINVAL;
615}
616early_param("memory_corruption_check_period", set_corruption_check_period);
617
618static int set_corruption_check_size(char *arg)
619{
620 char *end;
621 unsigned size;
622
623 size = memparse(arg, &end);
624
625 if (*end == '\0')
626 corruption_check_size = size;
627
628 return (size == corruption_check_size) ? 0 : -EINVAL;
629}
630early_param("memory_corruption_check_size", set_corruption_check_size);
631
632
592static void __init setup_bios_corruption_check(void) 633static void __init setup_bios_corruption_check(void)
593{ 634{
594 u64 addr = PAGE_SIZE; /* assume first page is reserved anyway */ 635 u64 addr = PAGE_SIZE; /* assume first page is reserved anyway */
595 636
596 while(addr < 0x10000 && num_scan_areas < MAX_SCAN_AREAS) { 637 if (corruption_check_size == 0)
638 memory_corruption_check = 0;
639
640 if (!memory_corruption_check)
641 return;
642
643 corruption_check_size = round_up(corruption_check_size, PAGE_SIZE);
644
645 while(addr < corruption_check_size && num_scan_areas < MAX_SCAN_AREAS) {
597 u64 size; 646 u64 size;
598 addr = find_e820_area_size(addr, &size, PAGE_SIZE); 647 addr = find_e820_area_size(addr, &size, PAGE_SIZE);
599 648
600 if (addr == 0) 649 if (addr == 0)
601 break; 650 break;
602 651
603 if ((addr + size) > 0x10000) 652 if ((addr + size) > corruption_check_size)
604 size = 0x10000 - addr; 653 size = corruption_check_size - addr;
605 654
606 if (size == 0) 655 if (size == 0)
607 break; 656 break;
@@ -617,12 +666,11 @@ static void __init setup_bios_corruption_check(void)
617 addr += size; 666 addr += size;
618 } 667 }
619 668
620 printk(KERN_INFO "scanning %d areas for BIOS corruption\n", 669 printk(KERN_INFO "Scanning %d areas for low memory corruption\n",
621 num_scan_areas); 670 num_scan_areas);
622 update_e820(); 671 update_e820();
623} 672}
624 673
625static int __read_mostly bios_corruption_check = 1;
626static struct timer_list periodic_check_timer; 674static struct timer_list periodic_check_timer;
627 675
628void check_for_bios_corruption(void) 676void check_for_bios_corruption(void)
@@ -630,7 +678,7 @@ void check_for_bios_corruption(void)
630 int i; 678 int i;
631 int corruption = 0; 679 int corruption = 0;
632 680
633 if (!bios_corruption_check) 681 if (!memory_corruption_check)
634 return; 682 return;
635 683
636 for(i = 0; i < num_scan_areas; i++) { 684 for(i = 0; i < num_scan_areas; i++) {
@@ -647,35 +695,27 @@ void check_for_bios_corruption(void)
647 } 695 }
648 } 696 }
649 697
650 if (corruption) 698 WARN(corruption, KERN_ERR "Memory corruption detected in low memory\n");
651 dump_stack();
652} 699}
653 700
654static void periodic_check_for_corruption(unsigned long data) 701static void periodic_check_for_corruption(unsigned long data)
655{ 702{
656 check_for_bios_corruption(); 703 check_for_bios_corruption();
657 mod_timer(&periodic_check_timer, jiffies + 60*HZ); 704 mod_timer(&periodic_check_timer, jiffies + corruption_check_period*HZ);
658} 705}
659 706
660void start_periodic_check_for_corruption(void) 707void start_periodic_check_for_corruption(void)
661{ 708{
662 if (!bios_corruption_check) 709 if (!memory_corruption_check || corruption_check_period == 0)
663 return; 710 return;
664 711
712 printk(KERN_INFO "Scanning for low memory corruption every %d seconds\n",
713 corruption_check_period);
714
665 init_timer(&periodic_check_timer); 715 init_timer(&periodic_check_timer);
666 periodic_check_timer.function = &periodic_check_for_corruption; 716 periodic_check_timer.function = &periodic_check_for_corruption;
667 periodic_check_for_corruption(0); 717 periodic_check_for_corruption(0);
668} 718}
669
670static int set_bios_corruption_check(char *arg)
671{
672 char *end;
673
674 bios_corruption_check = simple_strtol(arg, &end, 10);
675
676 return (*end == 0) ? 0 : -EINVAL;
677}
678early_param("bios_corruption_check", set_bios_corruption_check);
679#endif 719#endif
680 720
681/* 721/*