Merge branches 'x86/apic', 'x86/cleanups', 'x86/cpufeature', 'x86/crashdump', 'x86/debug', 'x86/defconfig', 'x86/detect-hyper', 'x86/doc', 'x86/dumpstack', 'x86/early-printk', 'x86/fpu', 'x86/idle', 'x86/io', 'x86/memory-corruption-check', 'x86/microcode', 'x86/mm', 'x86/mtrr', 'x86/nmi-watchdog', 'x86/pat2', 'x86/pci-ioapic-boot-irq-quirks', 'x86/ptrace', 'x86/quirks', 'x86/reboot', 'x86/setup-memory', 'x86/signal', 'x86/sparse-fixes', 'x86/time', 'x86/uv' and 'x86/xen' into x86/core
This commit is contained in:
parent
3d44cc3e01
1ccedb7cdb
34945ede31
d437797406
c415b3dce3
beeb4195cb
f269b07e86
4e42ebd57b
e1286f2c68
878719e831
fd28a5b58d
adf77bac05
8f2466f45f
93093d099e
bb5574608a
f34a10bd9f
b6fd6f2673
30604bb410
5b9a0e14eb
67bac792cd
7a9787e1eb
f4166c54bf
69b88afa8d
8daa19051e
3e1e9002aa
8403295e0f
4db646b1af
205516c12d
c8182f0016
ecbf29cdb3
commit
fa623d1b02
@ -98,6 +98,7 @@
|
||||
|
||||
#include <mach_apic.h>
|
||||
#include <asm/paravirt.h>
|
||||
#include <asm/hypervisor.h>
|
||||
|
||||
#include <asm/percpu.h>
|
||||
#include <asm/topology.h>
|
||||
@ -448,6 +449,7 @@ static void __init reserve_early_setup_data(void)
|
||||
* @size: Size of the crashkernel memory to reserve.
|
||||
* Returns the base address on success, and -1ULL on failure.
|
||||
*/
|
||||
static
|
||||
unsigned long long __init find_and_reserve_crashkernel(unsigned long long size)
|
||||
{
|
||||
const unsigned long long alignment = 16<<20; /* 16M */
|
||||
@ -583,161 +585,24 @@ static int __init setup_elfcorehdr(char *arg)
|
||||
early_param("elfcorehdr", setup_elfcorehdr);
|
||||
#endif
|
||||
|
||||
static struct x86_quirks default_x86_quirks __initdata;
|
||||
static int __init default_update_genapic(void)
|
||||
{
|
||||
#ifdef CONFIG_X86_SMP
|
||||
# if defined(CONFIG_X86_GENERICARCH) || defined(CONFIG_X86_64)
|
||||
genapic->wakeup_cpu = wakeup_secondary_cpu_via_init;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct x86_quirks default_x86_quirks __initdata = {
|
||||
.update_genapic = default_update_genapic,
|
||||
};
|
||||
|
||||
struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
|
||||
|
||||
/*
|
||||
* Some BIOSes seem to corrupt the low 64k of memory during events
|
||||
* like suspend/resume and unplugging an HDMI cable. Reserve all
|
||||
* remaining free memory in that area and fill it with a distinct
|
||||
* pattern.
|
||||
*/
|
||||
#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
|
||||
#define MAX_SCAN_AREAS 8
|
||||
|
||||
static int __read_mostly memory_corruption_check = -1;
|
||||
|
||||
static unsigned __read_mostly corruption_check_size = 64*1024;
|
||||
static unsigned __read_mostly corruption_check_period = 60; /* seconds */
|
||||
|
||||
static struct e820entry scan_areas[MAX_SCAN_AREAS];
|
||||
static int num_scan_areas;
|
||||
|
||||
|
||||
static int set_corruption_check(char *arg)
|
||||
{
|
||||
char *end;
|
||||
|
||||
memory_corruption_check = simple_strtol(arg, &end, 10);
|
||||
|
||||
return (*end == 0) ? 0 : -EINVAL;
|
||||
}
|
||||
early_param("memory_corruption_check", set_corruption_check);
|
||||
|
||||
static int set_corruption_check_period(char *arg)
|
||||
{
|
||||
char *end;
|
||||
|
||||
corruption_check_period = simple_strtoul(arg, &end, 10);
|
||||
|
||||
return (*end == 0) ? 0 : -EINVAL;
|
||||
}
|
||||
early_param("memory_corruption_check_period", set_corruption_check_period);
|
||||
|
||||
static int set_corruption_check_size(char *arg)
|
||||
{
|
||||
char *end;
|
||||
unsigned size;
|
||||
|
||||
size = memparse(arg, &end);
|
||||
|
||||
if (*end == '\0')
|
||||
corruption_check_size = size;
|
||||
|
||||
return (size == corruption_check_size) ? 0 : -EINVAL;
|
||||
}
|
||||
early_param("memory_corruption_check_size", set_corruption_check_size);
|
||||
|
||||
|
||||
static void __init setup_bios_corruption_check(void)
|
||||
{
|
||||
u64 addr = PAGE_SIZE; /* assume first page is reserved anyway */
|
||||
|
||||
if (memory_corruption_check == -1) {
|
||||
memory_corruption_check =
|
||||
#ifdef CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK
|
||||
1
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
if (corruption_check_size == 0)
|
||||
memory_corruption_check = 0;
|
||||
|
||||
if (!memory_corruption_check)
|
||||
return;
|
||||
|
||||
corruption_check_size = round_up(corruption_check_size, PAGE_SIZE);
|
||||
|
||||
while(addr < corruption_check_size && num_scan_areas < MAX_SCAN_AREAS) {
|
||||
u64 size;
|
||||
addr = find_e820_area_size(addr, &size, PAGE_SIZE);
|
||||
|
||||
if (addr == 0)
|
||||
break;
|
||||
|
||||
if ((addr + size) > corruption_check_size)
|
||||
size = corruption_check_size - addr;
|
||||
|
||||
if (size == 0)
|
||||
break;
|
||||
|
||||
e820_update_range(addr, size, E820_RAM, E820_RESERVED);
|
||||
scan_areas[num_scan_areas].addr = addr;
|
||||
scan_areas[num_scan_areas].size = size;
|
||||
num_scan_areas++;
|
||||
|
||||
/* Assume we've already mapped this early memory */
|
||||
memset(__va(addr), 0, size);
|
||||
|
||||
addr += size;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "Scanning %d areas for low memory corruption\n",
|
||||
num_scan_areas);
|
||||
update_e820();
|
||||
}
|
||||
|
||||
static struct timer_list periodic_check_timer;
|
||||
|
||||
void check_for_bios_corruption(void)
|
||||
{
|
||||
int i;
|
||||
int corruption = 0;
|
||||
|
||||
if (!memory_corruption_check)
|
||||
return;
|
||||
|
||||
for(i = 0; i < num_scan_areas; i++) {
|
||||
unsigned long *addr = __va(scan_areas[i].addr);
|
||||
unsigned long size = scan_areas[i].size;
|
||||
|
||||
for(; size; addr++, size -= sizeof(unsigned long)) {
|
||||
if (!*addr)
|
||||
continue;
|
||||
printk(KERN_ERR "Corrupted low memory at %p (%lx phys) = %08lx\n",
|
||||
addr, __pa(addr), *addr);
|
||||
corruption = 1;
|
||||
*addr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
WARN(corruption, KERN_ERR "Memory corruption detected in low memory\n");
|
||||
}
|
||||
|
||||
static void periodic_check_for_corruption(unsigned long data)
|
||||
{
|
||||
check_for_bios_corruption();
|
||||
mod_timer(&periodic_check_timer, round_jiffies(jiffies + corruption_check_period*HZ));
|
||||
}
|
||||
|
||||
void start_periodic_check_for_corruption(void)
|
||||
{
|
||||
if (!memory_corruption_check || corruption_check_period == 0)
|
||||
return;
|
||||
|
||||
printk(KERN_INFO "Scanning for low memory corruption every %d seconds\n",
|
||||
corruption_check_period);
|
||||
|
||||
init_timer(&periodic_check_timer);
|
||||
periodic_check_timer.function = &periodic_check_for_corruption;
|
||||
periodic_check_for_corruption(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_RESERVE_LOW_64K
|
||||
static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
|
||||
{
|
||||
printk(KERN_NOTICE
|
||||
@ -749,6 +614,7 @@ static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* List of systems that have known low memory corruption BIOS problems */
|
||||
static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
|
||||
@ -907,6 +773,12 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
dmi_check_system(bad_bios_dmi_table);
|
||||
|
||||
/*
|
||||
* VMware detection requires dmi to be available, so this
|
||||
* needs to be done after dmi_scan_machine, for the BP.
|
||||
*/
|
||||
init_hypervisor(&boot_cpu_data);
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
probe_roms();
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user