Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86, mce: Clean up thermal init by introducing intel_thermal_supported() x86, mce: Thermal monitoring depends on APIC being enabled x86: Gart: fix breakage due to IOMMU initialization cleanup x86: Move swiotlb initialization before dma32_free_bootmem x86: Fix build warning in arch/x86/mm/mmio-mod.c x86: Remove usedac in feature-removal-schedule.txt x86: Fix duplicated UV BAU interrupt vector nvram: Fix write beyond end condition; prove to gcc copy is safe mm: Adjust do_pages_stat() so gcc can see copy_from_user() is safe x86: Limit the number of processor bootup messages x86: Remove enabling x2apic message for every CPU doc: Add documentation for bootloader_{type,version} x86, msr: Add support for non-contiguous cpumasks x86: Use find_e820() instead of hard coded trampoline address x86, AMD: Fix stale cpuid4_info shared_map data in shared_cpu_map cpumasks Trivial percpu-naming-introduced conflicts in arch/x86/kernel/cpu/intel_cacheinfo.c
This commit is contained in:
commit
75b08038ce
@ -291,13 +291,6 @@ Who: Michael Buesch <mb@bu3sch.de>
|
|||||||
|
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
What: usedac i386 kernel parameter
|
|
||||||
When: 2.6.27
|
|
||||||
Why: replaced by allowdac and no dac combination
|
|
||||||
Who: Glauber Costa <gcosta@redhat.com>
|
|
||||||
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
What: print_fn_descriptor_symbol()
|
What: print_fn_descriptor_symbol()
|
||||||
When: October 2009
|
When: October 2009
|
||||||
Why: The %pF vsprintf format provides the same functionality in a
|
Why: The %pF vsprintf format provides the same functionality in a
|
||||||
|
@ -19,6 +19,8 @@ Currently, these files might (depending on your configuration)
|
|||||||
show up in /proc/sys/kernel:
|
show up in /proc/sys/kernel:
|
||||||
- acpi_video_flags
|
- acpi_video_flags
|
||||||
- acct
|
- acct
|
||||||
|
- bootloader_type [ X86 only ]
|
||||||
|
- bootloader_version [ X86 only ]
|
||||||
- callhome [ S390 only ]
|
- callhome [ S390 only ]
|
||||||
- auto_msgmni
|
- auto_msgmni
|
||||||
- core_pattern
|
- core_pattern
|
||||||
@ -93,6 +95,35 @@ valid for 30 seconds.
|
|||||||
|
|
||||||
==============================================================
|
==============================================================
|
||||||
|
|
||||||
|
bootloader_type:
|
||||||
|
|
||||||
|
x86 bootloader identification
|
||||||
|
|
||||||
|
This gives the bootloader type number as indicated by the bootloader,
|
||||||
|
shifted left by 4, and OR'd with the low four bits of the bootloader
|
||||||
|
version. The reason for this encoding is that this used to match the
|
||||||
|
type_of_loader field in the kernel header; the encoding is kept for
|
||||||
|
backwards compatibility. That is, if the full bootloader type number
|
||||||
|
is 0x15 and the full version number is 0x234, this file will contain
|
||||||
|
the value 340 = 0x154.
|
||||||
|
|
||||||
|
See the type_of_loader and ext_loader_type fields in
|
||||||
|
Documentation/x86/boot.txt for additional information.
|
||||||
|
|
||||||
|
==============================================================
|
||||||
|
|
||||||
|
bootloader_version:
|
||||||
|
|
||||||
|
x86 bootloader version
|
||||||
|
|
||||||
|
The complete bootloader version number. In the example above, this
|
||||||
|
file will contain the value 564 = 0x234.
|
||||||
|
|
||||||
|
See the type_of_loader and ext_loader_ver fields in
|
||||||
|
Documentation/x86/boot.txt for additional information.
|
||||||
|
|
||||||
|
==============================================================
|
||||||
|
|
||||||
callhome:
|
callhome:
|
||||||
|
|
||||||
Controls the kernel's callhome behavior in case of a kernel panic.
|
Controls the kernel's callhome behavior in case of a kernel panic.
|
||||||
|
@ -113,7 +113,7 @@
|
|||||||
*/
|
*/
|
||||||
#define LOCAL_PENDING_VECTOR 0xec
|
#define LOCAL_PENDING_VECTOR 0xec
|
||||||
|
|
||||||
#define UV_BAU_MESSAGE 0xec
|
#define UV_BAU_MESSAGE 0xea
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Self IPI vector for machine checks
|
* Self IPI vector for machine checks
|
||||||
|
@ -244,6 +244,9 @@ do { \
|
|||||||
|
|
||||||
#define write_rdtscp_aux(val) wrmsr(0xc0000103, (val), 0)
|
#define write_rdtscp_aux(val) wrmsr(0xc0000103, (val), 0)
|
||||||
|
|
||||||
|
struct msr *msrs_alloc(void);
|
||||||
|
void msrs_free(struct msr *msrs);
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
|
int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
|
||||||
int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
|
int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
|
||||||
|
@ -16,7 +16,6 @@ extern unsigned long initial_code;
|
|||||||
extern unsigned long initial_gs;
|
extern unsigned long initial_gs;
|
||||||
|
|
||||||
#define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE)
|
#define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE)
|
||||||
#define TRAMPOLINE_BASE 0x6000
|
|
||||||
|
|
||||||
extern unsigned long setup_trampoline(void);
|
extern unsigned long setup_trampoline(void);
|
||||||
extern void __init reserve_trampoline_memory(void);
|
extern void __init reserve_trampoline_memory(void);
|
||||||
|
@ -280,7 +280,8 @@ void __init early_gart_iommu_check(void)
|
|||||||
* or BIOS forget to put that in reserved.
|
* or BIOS forget to put that in reserved.
|
||||||
* try to update e820 to make that region as reserved.
|
* try to update e820 to make that region as reserved.
|
||||||
*/
|
*/
|
||||||
int i, fix, slot;
|
u32 agp_aper_base = 0, agp_aper_order = 0;
|
||||||
|
int i, fix, slot, valid_agp = 0;
|
||||||
u32 ctl;
|
u32 ctl;
|
||||||
u32 aper_size = 0, aper_order = 0, last_aper_order = 0;
|
u32 aper_size = 0, aper_order = 0, last_aper_order = 0;
|
||||||
u64 aper_base = 0, last_aper_base = 0;
|
u64 aper_base = 0, last_aper_base = 0;
|
||||||
@ -290,6 +291,8 @@ void __init early_gart_iommu_check(void)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* This is mostly duplicate of iommu_hole_init */
|
/* This is mostly duplicate of iommu_hole_init */
|
||||||
|
agp_aper_base = search_agp_bridge(&agp_aper_order, &valid_agp);
|
||||||
|
|
||||||
fix = 0;
|
fix = 0;
|
||||||
for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
|
for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
|
||||||
int bus;
|
int bus;
|
||||||
@ -342,10 +345,10 @@ void __init early_gart_iommu_check(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fix)
|
if (valid_agp)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* different nodes have different setting, disable them all at first*/
|
/* disable them all at first */
|
||||||
for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
|
for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
|
||||||
int bus;
|
int bus;
|
||||||
int dev_base, dev_limit;
|
int dev_base, dev_limit;
|
||||||
@ -458,8 +461,6 @@ out:
|
|||||||
|
|
||||||
if (aper_alloc) {
|
if (aper_alloc) {
|
||||||
/* Got the aperture from the AGP bridge */
|
/* Got the aperture from the AGP bridge */
|
||||||
} else if (!valid_agp) {
|
|
||||||
/* Do nothing */
|
|
||||||
} else if ((!no_iommu && max_pfn > MAX_DMA32_PFN) ||
|
} else if ((!no_iommu && max_pfn > MAX_DMA32_PFN) ||
|
||||||
force_iommu ||
|
force_iommu ||
|
||||||
valid_agp ||
|
valid_agp ||
|
||||||
|
@ -1341,7 +1341,7 @@ void enable_x2apic(void)
|
|||||||
|
|
||||||
rdmsr(MSR_IA32_APICBASE, msr, msr2);
|
rdmsr(MSR_IA32_APICBASE, msr, msr2);
|
||||||
if (!(msr & X2APIC_ENABLE)) {
|
if (!(msr & X2APIC_ENABLE)) {
|
||||||
pr_info("Enabling x2apic\n");
|
printk_once(KERN_INFO "Enabling x2apic\n");
|
||||||
wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0);
|
wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,7 @@ void __cpuinit detect_extended_topology(struct cpuinfo_x86 *c)
|
|||||||
unsigned int eax, ebx, ecx, edx, sub_index;
|
unsigned int eax, ebx, ecx, edx, sub_index;
|
||||||
unsigned int ht_mask_width, core_plus_mask_width;
|
unsigned int ht_mask_width, core_plus_mask_width;
|
||||||
unsigned int core_select_mask, core_level_siblings;
|
unsigned int core_select_mask, core_level_siblings;
|
||||||
|
static bool printed;
|
||||||
|
|
||||||
if (c->cpuid_level < 0xb)
|
if (c->cpuid_level < 0xb)
|
||||||
return;
|
return;
|
||||||
@ -127,12 +128,14 @@ void __cpuinit detect_extended_topology(struct cpuinfo_x86 *c)
|
|||||||
|
|
||||||
c->x86_max_cores = (core_level_siblings / smp_num_siblings);
|
c->x86_max_cores = (core_level_siblings / smp_num_siblings);
|
||||||
|
|
||||||
|
if (!printed) {
|
||||||
printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
|
printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
|
||||||
c->phys_proc_id);
|
c->phys_proc_id);
|
||||||
if (c->x86_max_cores > 1)
|
if (c->x86_max_cores > 1)
|
||||||
printk(KERN_INFO "CPU: Processor Core ID: %d\n",
|
printk(KERN_INFO "CPU: Processor Core ID: %d\n",
|
||||||
c->cpu_core_id);
|
c->cpu_core_id);
|
||||||
|
printed = 1;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -375,8 +375,6 @@ static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
|
|||||||
node = nearby_node(apicid);
|
node = nearby_node(apicid);
|
||||||
}
|
}
|
||||||
numa_set_node(cpu, node);
|
numa_set_node(cpu, node);
|
||||||
|
|
||||||
printk(KERN_INFO "CPU %d/0x%x -> Node %d\n", cpu, apicid, node);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,6 +427,7 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c)
|
|||||||
#ifdef CONFIG_X86_HT
|
#ifdef CONFIG_X86_HT
|
||||||
u32 eax, ebx, ecx, edx;
|
u32 eax, ebx, ecx, edx;
|
||||||
int index_msb, core_bits;
|
int index_msb, core_bits;
|
||||||
|
static bool printed;
|
||||||
|
|
||||||
if (!cpu_has(c, X86_FEATURE_HT))
|
if (!cpu_has(c, X86_FEATURE_HT))
|
||||||
return;
|
return;
|
||||||
@ -442,7 +443,7 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c)
|
|||||||
smp_num_siblings = (ebx & 0xff0000) >> 16;
|
smp_num_siblings = (ebx & 0xff0000) >> 16;
|
||||||
|
|
||||||
if (smp_num_siblings == 1) {
|
if (smp_num_siblings == 1) {
|
||||||
printk(KERN_INFO "CPU: Hyper-Threading is disabled\n");
|
printk_once(KERN_INFO "CPU0: Hyper-Threading is disabled\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,11 +470,12 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c)
|
|||||||
((1 << core_bits) - 1);
|
((1 << core_bits) - 1);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if ((c->x86_max_cores * smp_num_siblings) > 1) {
|
if (!printed && (c->x86_max_cores * smp_num_siblings) > 1) {
|
||||||
printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
|
printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
|
||||||
c->phys_proc_id);
|
c->phys_proc_id);
|
||||||
printk(KERN_INFO "CPU: Processor Core ID: %d\n",
|
printk(KERN_INFO "CPU: Processor Core ID: %d\n",
|
||||||
c->cpu_core_id);
|
c->cpu_core_id);
|
||||||
|
printed = 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -1115,7 +1117,7 @@ void __cpuinit cpu_init(void)
|
|||||||
if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask))
|
if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask))
|
||||||
panic("CPU#%d already initialized!\n", cpu);
|
panic("CPU#%d already initialized!\n", cpu);
|
||||||
|
|
||||||
printk(KERN_INFO "Initializing CPU#%d\n", cpu);
|
pr_debug("Initializing CPU#%d\n", cpu);
|
||||||
|
|
||||||
clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
|
clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
|
||||||
|
|
||||||
|
@ -270,8 +270,6 @@ static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
|
|||||||
node = cpu_to_node(cpu);
|
node = cpu_to_node(cpu);
|
||||||
}
|
}
|
||||||
numa_set_node(cpu, node);
|
numa_set_node(cpu, node);
|
||||||
|
|
||||||
printk(KERN_INFO "CPU %d/0x%x -> Node %d\n", cpu, apicid, node);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,18 +507,19 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
|
|||||||
{
|
{
|
||||||
struct _cpuid4_info *this_leaf, *sibling_leaf;
|
struct _cpuid4_info *this_leaf, *sibling_leaf;
|
||||||
unsigned long num_threads_sharing;
|
unsigned long num_threads_sharing;
|
||||||
int index_msb, i;
|
int index_msb, i, sibling;
|
||||||
struct cpuinfo_x86 *c = &cpu_data(cpu);
|
struct cpuinfo_x86 *c = &cpu_data(cpu);
|
||||||
|
|
||||||
if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) {
|
if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) {
|
||||||
struct cpuinfo_x86 *d;
|
for_each_cpu(i, c->llc_shared_map) {
|
||||||
for_each_online_cpu(i) {
|
|
||||||
if (!per_cpu(ici_cpuid4_info, i))
|
if (!per_cpu(ici_cpuid4_info, i))
|
||||||
continue;
|
continue;
|
||||||
d = &cpu_data(i);
|
|
||||||
this_leaf = CPUID4_INFO_IDX(i, index);
|
this_leaf = CPUID4_INFO_IDX(i, index);
|
||||||
cpumask_copy(to_cpumask(this_leaf->shared_cpu_map),
|
for_each_cpu(sibling, c->llc_shared_map) {
|
||||||
d->llc_shared_map);
|
if (!cpu_online(sibling))
|
||||||
|
continue;
|
||||||
|
set_bit(sibling, this_leaf->shared_cpu_map);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -256,6 +256,16 @@ asmlinkage void smp_thermal_interrupt(struct pt_regs *regs)
|
|||||||
ack_APIC_irq();
|
ack_APIC_irq();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Thermal monitoring depends on APIC, ACPI and clock modulation */
|
||||||
|
static int intel_thermal_supported(struct cpuinfo_x86 *c)
|
||||||
|
{
|
||||||
|
if (!cpu_has_apic)
|
||||||
|
return 0;
|
||||||
|
if (!cpu_has(c, X86_FEATURE_ACPI) || !cpu_has(c, X86_FEATURE_ACC))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void __init mcheck_intel_therm_init(void)
|
void __init mcheck_intel_therm_init(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -263,8 +273,7 @@ void __init mcheck_intel_therm_init(void)
|
|||||||
* LVT value on BSP and use that value to restore APs' thermal LVT
|
* LVT value on BSP and use that value to restore APs' thermal LVT
|
||||||
* entry BIOS programmed later
|
* entry BIOS programmed later
|
||||||
*/
|
*/
|
||||||
if (cpu_has(&boot_cpu_data, X86_FEATURE_ACPI) &&
|
if (intel_thermal_supported(&boot_cpu_data))
|
||||||
cpu_has(&boot_cpu_data, X86_FEATURE_ACC))
|
|
||||||
lvtthmr_init = apic_read(APIC_LVTTHMR);
|
lvtthmr_init = apic_read(APIC_LVTTHMR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,8 +283,7 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
|
|||||||
int tm2 = 0;
|
int tm2 = 0;
|
||||||
u32 l, h;
|
u32 l, h;
|
||||||
|
|
||||||
/* Thermal monitoring depends on ACPI and clock modulation*/
|
if (!intel_thermal_supported(c))
|
||||||
if (!cpu_has(c, X86_FEATURE_ACPI) || !cpu_has(c, X86_FEATURE_ACC))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -339,8 +347,8 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
|
|||||||
l = apic_read(APIC_LVTTHMR);
|
l = apic_read(APIC_LVTTHMR);
|
||||||
apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
|
apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
|
||||||
|
|
||||||
printk(KERN_INFO "CPU%d: Thermal monitoring enabled (%s)\n",
|
printk_once(KERN_INFO "CPU0: Thermal monitoring enabled (%s)\n",
|
||||||
cpu, tm2 ? "TM2" : "TM1");
|
tm2 ? "TM2" : "TM1");
|
||||||
|
|
||||||
/* enable thermal throttle processing */
|
/* enable thermal throttle processing */
|
||||||
atomic_set(&therm_throt_en, 1);
|
atomic_set(&therm_throt_en, 1);
|
||||||
|
@ -732,7 +732,16 @@ struct early_res {
|
|||||||
char overlap_ok;
|
char overlap_ok;
|
||||||
};
|
};
|
||||||
static struct early_res early_res[MAX_EARLY_RES] __initdata = {
|
static struct early_res early_res[MAX_EARLY_RES] __initdata = {
|
||||||
{ 0, PAGE_SIZE, "BIOS data page" }, /* BIOS data page */
|
{ 0, PAGE_SIZE, "BIOS data page", 1 }, /* BIOS data page */
|
||||||
|
#ifdef CONFIG_X86_32
|
||||||
|
/*
|
||||||
|
* But first pinch a few for the stack/trampoline stuff
|
||||||
|
* FIXME: Don't need the extra page at 4K, but need to fix
|
||||||
|
* trampoline before removing it. (see the GDT stuff)
|
||||||
|
*/
|
||||||
|
{ PAGE_SIZE, PAGE_SIZE, "EX TRAMPOLINE", 1 },
|
||||||
|
#endif
|
||||||
|
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,8 +29,6 @@ static void __init i386_default_early_setup(void)
|
|||||||
|
|
||||||
void __init i386_start_kernel(void)
|
void __init i386_start_kernel(void)
|
||||||
{
|
{
|
||||||
reserve_trampoline_memory();
|
|
||||||
|
|
||||||
reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
|
reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
|
||||||
|
|
||||||
#ifdef CONFIG_BLK_DEV_INITRD
|
#ifdef CONFIG_BLK_DEV_INITRD
|
||||||
|
@ -98,8 +98,6 @@ void __init x86_64_start_reservations(char *real_mode_data)
|
|||||||
{
|
{
|
||||||
copy_bootdata(__va(real_mode_data));
|
copy_bootdata(__va(real_mode_data));
|
||||||
|
|
||||||
reserve_trampoline_memory();
|
|
||||||
|
|
||||||
reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
|
reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
|
||||||
|
|
||||||
#ifdef CONFIG_BLK_DEV_INITRD
|
#ifdef CONFIG_BLK_DEV_INITRD
|
||||||
|
@ -945,9 +945,6 @@ void __init early_reserve_e820_mpc_new(void)
|
|||||||
{
|
{
|
||||||
if (enable_update_mptable && alloc_mptable) {
|
if (enable_update_mptable && alloc_mptable) {
|
||||||
u64 startt = 0;
|
u64 startt = 0;
|
||||||
#ifdef CONFIG_X86_TRAMPOLINE
|
|
||||||
startt = TRAMPOLINE_BASE;
|
|
||||||
#endif
|
|
||||||
mpc_new_phys = early_reserve_e820(startt, mpc_new_length, 4);
|
mpc_new_phys = early_reserve_e820(startt, mpc_new_length, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,11 +120,14 @@ static void __init dma32_free_bootmem(void)
|
|||||||
|
|
||||||
void __init pci_iommu_alloc(void)
|
void __init pci_iommu_alloc(void)
|
||||||
{
|
{
|
||||||
|
int use_swiotlb;
|
||||||
|
|
||||||
|
use_swiotlb = pci_swiotlb_init();
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
/* free the range so iommu could get some range less than 4G */
|
/* free the range so iommu could get some range less than 4G */
|
||||||
dma32_free_bootmem();
|
dma32_free_bootmem();
|
||||||
#endif
|
#endif
|
||||||
if (pci_swiotlb_init())
|
if (use_swiotlb)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gart_iommu_hole_init();
|
gart_iommu_hole_init();
|
||||||
|
@ -710,7 +710,8 @@ static void gart_iommu_shutdown(void)
|
|||||||
struct pci_dev *dev;
|
struct pci_dev *dev;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (no_agp)
|
/* don't shutdown it if there is AGP installed */
|
||||||
|
if (!no_agp)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < num_k8_northbridges; i++) {
|
for (i = 0; i < num_k8_northbridges; i++) {
|
||||||
|
@ -73,6 +73,7 @@
|
|||||||
|
|
||||||
#include <asm/mtrr.h>
|
#include <asm/mtrr.h>
|
||||||
#include <asm/apic.h>
|
#include <asm/apic.h>
|
||||||
|
#include <asm/trampoline.h>
|
||||||
#include <asm/e820.h>
|
#include <asm/e820.h>
|
||||||
#include <asm/mpspec.h>
|
#include <asm/mpspec.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
@ -875,6 +876,13 @@ void __init setup_arch(char **cmdline_p)
|
|||||||
|
|
||||||
reserve_brk();
|
reserve_brk();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find and reserve possible boot-time SMP configuration:
|
||||||
|
*/
|
||||||
|
find_smp_config();
|
||||||
|
|
||||||
|
reserve_trampoline_memory();
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI_SLEEP
|
#ifdef CONFIG_ACPI_SLEEP
|
||||||
/*
|
/*
|
||||||
* Reserve low memory region for sleep support.
|
* Reserve low memory region for sleep support.
|
||||||
@ -921,11 +929,6 @@ void __init setup_arch(char **cmdline_p)
|
|||||||
|
|
||||||
early_acpi_boot_init();
|
early_acpi_boot_init();
|
||||||
|
|
||||||
/*
|
|
||||||
* Find and reserve possible boot-time SMP configuration:
|
|
||||||
*/
|
|
||||||
find_smp_config();
|
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI_NUMA
|
#ifdef CONFIG_ACPI_NUMA
|
||||||
/*
|
/*
|
||||||
* Parse SRAT to discover nodes.
|
* Parse SRAT to discover nodes.
|
||||||
|
@ -671,6 +671,26 @@ static void __cpuinit do_fork_idle(struct work_struct *work)
|
|||||||
complete(&c_idle->done);
|
complete(&c_idle->done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* reduce the number of lines printed when booting a large cpu count system */
|
||||||
|
static void __cpuinit announce_cpu(int cpu, int apicid)
|
||||||
|
{
|
||||||
|
static int current_node = -1;
|
||||||
|
int node = cpu_to_node(cpu);
|
||||||
|
|
||||||
|
if (system_state == SYSTEM_BOOTING) {
|
||||||
|
if (node != current_node) {
|
||||||
|
if (current_node > (-1))
|
||||||
|
pr_cont(" Ok.\n");
|
||||||
|
current_node = node;
|
||||||
|
pr_info("Booting Node %3d, Processors ", node);
|
||||||
|
}
|
||||||
|
pr_cont(" #%d%s", cpu, cpu == (nr_cpu_ids - 1) ? " Ok.\n" : "");
|
||||||
|
return;
|
||||||
|
} else
|
||||||
|
pr_info("Booting Node %d Processor %d APIC 0x%x\n",
|
||||||
|
node, cpu, apicid);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
|
* NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
|
||||||
* (ie clustered apic addressing mode), this is a LOGICAL apic ID.
|
* (ie clustered apic addressing mode), this is a LOGICAL apic ID.
|
||||||
@ -737,9 +757,8 @@ do_rest:
|
|||||||
/* start_ip had better be page-aligned! */
|
/* start_ip had better be page-aligned! */
|
||||||
start_ip = setup_trampoline();
|
start_ip = setup_trampoline();
|
||||||
|
|
||||||
/* So we see what's up */
|
/* So we see what's up */
|
||||||
printk(KERN_INFO "Booting processor %d APIC 0x%x ip 0x%lx\n",
|
announce_cpu(cpu, apicid);
|
||||||
cpu, apicid, start_ip);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This grunge runs the startup process for
|
* This grunge runs the startup process for
|
||||||
@ -788,21 +807,17 @@ do_rest:
|
|||||||
udelay(100);
|
udelay(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cpumask_test_cpu(cpu, cpu_callin_mask)) {
|
if (cpumask_test_cpu(cpu, cpu_callin_mask))
|
||||||
/* number CPUs logically, starting from 1 (BSP is 0) */
|
pr_debug("CPU%d: has booted.\n", cpu);
|
||||||
pr_debug("OK.\n");
|
else {
|
||||||
printk(KERN_INFO "CPU%d: ", cpu);
|
|
||||||
print_cpu_info(&cpu_data(cpu));
|
|
||||||
pr_debug("CPU has booted.\n");
|
|
||||||
} else {
|
|
||||||
boot_error = 1;
|
boot_error = 1;
|
||||||
if (*((volatile unsigned char *)trampoline_base)
|
if (*((volatile unsigned char *)trampoline_base)
|
||||||
== 0xA5)
|
== 0xA5)
|
||||||
/* trampoline started but...? */
|
/* trampoline started but...? */
|
||||||
printk(KERN_ERR "Stuck ??\n");
|
pr_err("CPU%d: Stuck ??\n", cpu);
|
||||||
else
|
else
|
||||||
/* trampoline code not run */
|
/* trampoline code not run */
|
||||||
printk(KERN_ERR "Not responding.\n");
|
pr_err("CPU%d: Not responding.\n", cpu);
|
||||||
if (apic->inquire_remote_apic)
|
if (apic->inquire_remote_apic)
|
||||||
apic->inquire_remote_apic(apicid);
|
apic->inquire_remote_apic(apicid);
|
||||||
}
|
}
|
||||||
@ -1293,14 +1308,16 @@ void native_cpu_die(unsigned int cpu)
|
|||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
/* They ack this in play_dead by setting CPU_DEAD */
|
/* They ack this in play_dead by setting CPU_DEAD */
|
||||||
if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
|
if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
|
||||||
printk(KERN_INFO "CPU %d is now offline\n", cpu);
|
if (system_state == SYSTEM_RUNNING)
|
||||||
|
pr_info("CPU %u is now offline\n", cpu);
|
||||||
|
|
||||||
if (1 == num_online_cpus())
|
if (1 == num_online_cpus())
|
||||||
alternatives_smp_switch(0);
|
alternatives_smp_switch(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
msleep(100);
|
msleep(100);
|
||||||
}
|
}
|
||||||
printk(KERN_ERR "CPU %u didn't die...\n", cpu);
|
pr_err("CPU %u didn't die...\n", cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
void play_dead_common(void)
|
void play_dead_common(void)
|
||||||
|
@ -12,21 +12,19 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ready for x86_64 and x86 */
|
/* ready for x86_64 and x86 */
|
||||||
unsigned char *__trampinitdata trampoline_base = __va(TRAMPOLINE_BASE);
|
unsigned char *__trampinitdata trampoline_base;
|
||||||
|
|
||||||
void __init reserve_trampoline_memory(void)
|
void __init reserve_trampoline_memory(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_X86_32
|
unsigned long mem;
|
||||||
/*
|
|
||||||
* But first pinch a few for the stack/trampoline stuff
|
|
||||||
* FIXME: Don't need the extra page at 4K, but need to fix
|
|
||||||
* trampoline before removing it. (see the GDT stuff)
|
|
||||||
*/
|
|
||||||
reserve_early(PAGE_SIZE, PAGE_SIZE + PAGE_SIZE, "EX TRAMPOLINE");
|
|
||||||
#endif
|
|
||||||
/* Has to be in very low memory so we can execute real-mode AP code. */
|
/* Has to be in very low memory so we can execute real-mode AP code. */
|
||||||
reserve_early(TRAMPOLINE_BASE, TRAMPOLINE_BASE + TRAMPOLINE_SIZE,
|
mem = find_e820_area(0, 1<<20, TRAMPOLINE_SIZE, PAGE_SIZE);
|
||||||
"TRAMPOLINE");
|
if (mem == -1L)
|
||||||
|
panic("Cannot allocate trampoline\n");
|
||||||
|
|
||||||
|
trampoline_base = __va(mem);
|
||||||
|
reserve_early(mem, mem + TRAMPOLINE_SIZE, "TRAMPOLINE");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -7,7 +7,6 @@ struct msr_info {
|
|||||||
u32 msr_no;
|
u32 msr_no;
|
||||||
struct msr reg;
|
struct msr reg;
|
||||||
struct msr *msrs;
|
struct msr *msrs;
|
||||||
int off;
|
|
||||||
int err;
|
int err;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -18,7 +17,7 @@ static void __rdmsr_on_cpu(void *info)
|
|||||||
int this_cpu = raw_smp_processor_id();
|
int this_cpu = raw_smp_processor_id();
|
||||||
|
|
||||||
if (rv->msrs)
|
if (rv->msrs)
|
||||||
reg = &rv->msrs[this_cpu - rv->off];
|
reg = per_cpu_ptr(rv->msrs, this_cpu);
|
||||||
else
|
else
|
||||||
reg = &rv->reg;
|
reg = &rv->reg;
|
||||||
|
|
||||||
@ -32,7 +31,7 @@ static void __wrmsr_on_cpu(void *info)
|
|||||||
int this_cpu = raw_smp_processor_id();
|
int this_cpu = raw_smp_processor_id();
|
||||||
|
|
||||||
if (rv->msrs)
|
if (rv->msrs)
|
||||||
reg = &rv->msrs[this_cpu - rv->off];
|
reg = per_cpu_ptr(rv->msrs, this_cpu);
|
||||||
else
|
else
|
||||||
reg = &rv->reg;
|
reg = &rv->reg;
|
||||||
|
|
||||||
@ -80,7 +79,6 @@ static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no,
|
|||||||
|
|
||||||
memset(&rv, 0, sizeof(rv));
|
memset(&rv, 0, sizeof(rv));
|
||||||
|
|
||||||
rv.off = cpumask_first(mask);
|
|
||||||
rv.msrs = msrs;
|
rv.msrs = msrs;
|
||||||
rv.msr_no = msr_no;
|
rv.msr_no = msr_no;
|
||||||
|
|
||||||
@ -120,6 +118,26 @@ void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(wrmsr_on_cpus);
|
EXPORT_SYMBOL(wrmsr_on_cpus);
|
||||||
|
|
||||||
|
struct msr *msrs_alloc(void)
|
||||||
|
{
|
||||||
|
struct msr *msrs = NULL;
|
||||||
|
|
||||||
|
msrs = alloc_percpu(struct msr);
|
||||||
|
if (!msrs) {
|
||||||
|
pr_warning("%s: error allocating msrs\n", __func__);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return msrs;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(msrs_alloc);
|
||||||
|
|
||||||
|
void msrs_free(struct msr *msrs)
|
||||||
|
{
|
||||||
|
free_percpu(msrs);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(msrs_free);
|
||||||
|
|
||||||
/* These "safe" variants are slower and should be used when the target MSR
|
/* These "safe" variants are slower and should be used when the target MSR
|
||||||
may not actually exist. */
|
may not actually exist. */
|
||||||
static void __rdmsr_safe_on_cpu(void *info)
|
static void __rdmsr_safe_on_cpu(void *info)
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
* Derived from the read-mod example from relay-examples by Tom Zanussi.
|
* Derived from the read-mod example from relay-examples by Tom Zanussi.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define pr_fmt(fmt) "mmiotrace: "
|
#define pr_fmt(fmt) "mmiotrace: " fmt
|
||||||
|
|
||||||
#define DEBUG 1
|
#define DEBUG 1
|
||||||
|
|
||||||
|
@ -264,10 +264,16 @@ static ssize_t nvram_write(struct file *file, const char __user *buf,
|
|||||||
unsigned char contents[NVRAM_BYTES];
|
unsigned char contents[NVRAM_BYTES];
|
||||||
unsigned i = *ppos;
|
unsigned i = *ppos;
|
||||||
unsigned char *tmp;
|
unsigned char *tmp;
|
||||||
int len;
|
|
||||||
|
|
||||||
len = (NVRAM_BYTES - i) < count ? (NVRAM_BYTES - i) : count;
|
if (i >= NVRAM_BYTES)
|
||||||
if (copy_from_user(contents, buf, len))
|
return 0; /* Past EOF */
|
||||||
|
|
||||||
|
if (count > NVRAM_BYTES - i)
|
||||||
|
count = NVRAM_BYTES - i;
|
||||||
|
if (count > NVRAM_BYTES)
|
||||||
|
return -EFAULT; /* Can't happen, but prove it to gcc */
|
||||||
|
|
||||||
|
if (copy_from_user(contents, buf, count))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
spin_lock_irq(&rtc_lock);
|
spin_lock_irq(&rtc_lock);
|
||||||
@ -275,7 +281,7 @@ static ssize_t nvram_write(struct file *file, const char __user *buf,
|
|||||||
if (!__nvram_check_checksum())
|
if (!__nvram_check_checksum())
|
||||||
goto checksum_err;
|
goto checksum_err;
|
||||||
|
|
||||||
for (tmp = contents; count-- > 0 && i < NVRAM_BYTES; ++i, ++tmp)
|
for (tmp = contents; count--; ++i, ++tmp)
|
||||||
__nvram_write_byte(*tmp, i);
|
__nvram_write_byte(*tmp, i);
|
||||||
|
|
||||||
__nvram_set_checksum();
|
__nvram_set_checksum();
|
||||||
|
@ -13,6 +13,8 @@ module_param(report_gart_errors, int, 0644);
|
|||||||
static int ecc_enable_override;
|
static int ecc_enable_override;
|
||||||
module_param(ecc_enable_override, int, 0644);
|
module_param(ecc_enable_override, int, 0644);
|
||||||
|
|
||||||
|
static struct msr *msrs;
|
||||||
|
|
||||||
/* Lookup table for all possible MC control instances */
|
/* Lookup table for all possible MC control instances */
|
||||||
struct amd64_pvt;
|
struct amd64_pvt;
|
||||||
static struct mem_ctl_info *mci_lookup[EDAC_MAX_NUMNODES];
|
static struct mem_ctl_info *mci_lookup[EDAC_MAX_NUMNODES];
|
||||||
@ -2495,8 +2497,7 @@ static void get_cpus_on_this_dct_cpumask(struct cpumask *mask, int nid)
|
|||||||
static bool amd64_nb_mce_bank_enabled_on_node(int nid)
|
static bool amd64_nb_mce_bank_enabled_on_node(int nid)
|
||||||
{
|
{
|
||||||
cpumask_var_t mask;
|
cpumask_var_t mask;
|
||||||
struct msr *msrs;
|
int cpu, nbe;
|
||||||
int cpu, nbe, idx = 0;
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) {
|
if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) {
|
||||||
@ -2507,32 +2508,22 @@ static bool amd64_nb_mce_bank_enabled_on_node(int nid)
|
|||||||
|
|
||||||
get_cpus_on_this_dct_cpumask(mask, nid);
|
get_cpus_on_this_dct_cpumask(mask, nid);
|
||||||
|
|
||||||
msrs = kzalloc(sizeof(struct msr) * cpumask_weight(mask), GFP_KERNEL);
|
|
||||||
if (!msrs) {
|
|
||||||
amd64_printk(KERN_WARNING, "%s: error allocating msrs\n",
|
|
||||||
__func__);
|
|
||||||
free_cpumask_var(mask);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
rdmsr_on_cpus(mask, MSR_IA32_MCG_CTL, msrs);
|
rdmsr_on_cpus(mask, MSR_IA32_MCG_CTL, msrs);
|
||||||
|
|
||||||
for_each_cpu(cpu, mask) {
|
for_each_cpu(cpu, mask) {
|
||||||
nbe = msrs[idx].l & K8_MSR_MCGCTL_NBE;
|
struct msr *reg = per_cpu_ptr(msrs, cpu);
|
||||||
|
nbe = reg->l & K8_MSR_MCGCTL_NBE;
|
||||||
|
|
||||||
debugf0("core: %u, MCG_CTL: 0x%llx, NB MSR is %s\n",
|
debugf0("core: %u, MCG_CTL: 0x%llx, NB MSR is %s\n",
|
||||||
cpu, msrs[idx].q,
|
cpu, reg->q,
|
||||||
(nbe ? "enabled" : "disabled"));
|
(nbe ? "enabled" : "disabled"));
|
||||||
|
|
||||||
if (!nbe)
|
if (!nbe)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
idx++;
|
|
||||||
}
|
}
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
kfree(msrs);
|
|
||||||
free_cpumask_var(mask);
|
free_cpumask_var(mask);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -2540,8 +2531,7 @@ out:
|
|||||||
static int amd64_toggle_ecc_err_reporting(struct amd64_pvt *pvt, bool on)
|
static int amd64_toggle_ecc_err_reporting(struct amd64_pvt *pvt, bool on)
|
||||||
{
|
{
|
||||||
cpumask_var_t cmask;
|
cpumask_var_t cmask;
|
||||||
struct msr *msrs = NULL;
|
int cpu;
|
||||||
int cpu, idx = 0;
|
|
||||||
|
|
||||||
if (!zalloc_cpumask_var(&cmask, GFP_KERNEL)) {
|
if (!zalloc_cpumask_var(&cmask, GFP_KERNEL)) {
|
||||||
amd64_printk(KERN_WARNING, "%s: error allocating mask\n",
|
amd64_printk(KERN_WARNING, "%s: error allocating mask\n",
|
||||||
@ -2551,34 +2541,27 @@ static int amd64_toggle_ecc_err_reporting(struct amd64_pvt *pvt, bool on)
|
|||||||
|
|
||||||
get_cpus_on_this_dct_cpumask(cmask, pvt->mc_node_id);
|
get_cpus_on_this_dct_cpumask(cmask, pvt->mc_node_id);
|
||||||
|
|
||||||
msrs = kzalloc(sizeof(struct msr) * cpumask_weight(cmask), GFP_KERNEL);
|
|
||||||
if (!msrs) {
|
|
||||||
amd64_printk(KERN_WARNING, "%s: error allocating msrs\n",
|
|
||||||
__func__);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
rdmsr_on_cpus(cmask, MSR_IA32_MCG_CTL, msrs);
|
rdmsr_on_cpus(cmask, MSR_IA32_MCG_CTL, msrs);
|
||||||
|
|
||||||
for_each_cpu(cpu, cmask) {
|
for_each_cpu(cpu, cmask) {
|
||||||
|
|
||||||
|
struct msr *reg = per_cpu_ptr(msrs, cpu);
|
||||||
|
|
||||||
if (on) {
|
if (on) {
|
||||||
if (msrs[idx].l & K8_MSR_MCGCTL_NBE)
|
if (reg->l & K8_MSR_MCGCTL_NBE)
|
||||||
pvt->flags.ecc_report = 1;
|
pvt->flags.ecc_report = 1;
|
||||||
|
|
||||||
msrs[idx].l |= K8_MSR_MCGCTL_NBE;
|
reg->l |= K8_MSR_MCGCTL_NBE;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Turn off ECC reporting only when it was off before
|
* Turn off ECC reporting only when it was off before
|
||||||
*/
|
*/
|
||||||
if (!pvt->flags.ecc_report)
|
if (!pvt->flags.ecc_report)
|
||||||
msrs[idx].l &= ~K8_MSR_MCGCTL_NBE;
|
reg->l &= ~K8_MSR_MCGCTL_NBE;
|
||||||
}
|
}
|
||||||
idx++;
|
|
||||||
}
|
}
|
||||||
wrmsr_on_cpus(cmask, MSR_IA32_MCG_CTL, msrs);
|
wrmsr_on_cpus(cmask, MSR_IA32_MCG_CTL, msrs);
|
||||||
|
|
||||||
kfree(msrs);
|
|
||||||
free_cpumask_var(cmask);
|
free_cpumask_var(cmask);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -3036,6 +3019,8 @@ static int __init amd64_edac_init(void)
|
|||||||
if (cache_k8_northbridges() < 0)
|
if (cache_k8_northbridges() < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
msrs = msrs_alloc();
|
||||||
|
|
||||||
err = pci_register_driver(&amd64_pci_driver);
|
err = pci_register_driver(&amd64_pci_driver);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
@ -3071,6 +3056,9 @@ static void __exit amd64_edac_exit(void)
|
|||||||
edac_pci_release_generic_ctl(amd64_ctl_pci);
|
edac_pci_release_generic_ctl(amd64_ctl_pci);
|
||||||
|
|
||||||
pci_unregister_driver(&amd64_pci_driver);
|
pci_unregister_driver(&amd64_pci_driver);
|
||||||
|
|
||||||
|
msrs_free(msrs);
|
||||||
|
msrs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(amd64_edac_init);
|
module_init(amd64_edac_init);
|
||||||
|
@ -1044,7 +1044,7 @@ static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages,
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
for (i = 0; i < nr_pages; i += chunk_nr) {
|
for (i = 0; i < nr_pages; i += chunk_nr) {
|
||||||
if (chunk_nr + i > nr_pages)
|
if (chunk_nr > nr_pages - i)
|
||||||
chunk_nr = nr_pages - i;
|
chunk_nr = nr_pages - i;
|
||||||
|
|
||||||
err = copy_from_user(chunk_pages, &pages[i],
|
err = copy_from_user(chunk_pages, &pages[i],
|
||||||
|
Loading…
Reference in New Issue
Block a user