aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/setup.c
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2008-09-07 04:51:34 -0400
committerIngo Molnar <mingo@elte.hu>2008-09-07 11:40:01 -0400
commit9f077871ce7237e2387fc76542b3b4033cb05e49 (patch)
treee9a32b88c71a86b478b61fe50d0cb66b10bad10c /arch/x86/kernel/setup.c
parentbb577f980ef35e2b0d00aeed566724e5032aa5eb (diff)
x86: clean up memory corruption check and add more kernel parameters
The corruption check is enabled in Kconfig by default, but disabled at runtime. This patch adds several kernel parameters to control the corruption check's behaviour; these are documented in kernel-parameters.txt. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
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 c239b3780973..27ae91288855 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/*