* [PATCH] x86: make 64bit identify_cpu use cpu_dev
@ 2008-06-18 9:15 Yinghai Lu
2008-06-18 14:17 ` Ingo Molnar
2008-06-19 22:30 ` [PATCH] x86: make 64bit identify_cpu use cpu_dev v2 Yinghai Lu
0 siblings, 2 replies; 26+ messages in thread
From: Yinghai Lu @ 2008-06-18 9:15 UTC (permalink / raw)
To: Ingo Molnar, H. Peter Anvin, Thomas Gleixner, Dave Jones
Cc: linux-kernel@vger.kernel.org
may need to move some functions to common.c later
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Index: linux-2.6/arch/x86/kernel/cpu/amd_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/amd_64.c
+++ linux-2.6/arch/x86/kernel/cpu/amd_64.c
@@ -7,8 +7,7 @@
#include <mach_apic.h>
-extern int __cpuinit get_model_name(struct cpuinfo_x86 *c);
-extern void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c);
+#include "cpu.h"
int force_mwait __cpuinitdata;
@@ -109,7 +108,7 @@ static void __cpuinit early_init_amd_mc(
#endif
}
-void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
+static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
{
early_init_amd_mc(c);
@@ -118,7 +117,7 @@ void __cpuinit early_init_amd(struct cpu
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
}
-void __cpuinit init_amd(struct cpuinfo_x86 *c)
+static void __cpuinit init_amd(struct cpuinfo_x86 *c)
{
unsigned level;
@@ -200,3 +199,13 @@ void __cpuinit init_amd(struct cpuinfo_x
set_memory_4k((unsigned long)__va(tseg), 1);
}
}
+
+static struct cpu_dev amd_cpu_dev __cpuinitdata = {
+ .c_vendor = "AMD",
+ .c_ident = { "AuthenticAMD" },
+ .c_early_init = early_init_amd,
+ .c_init = init_amd,
+};
+
+cpu_vendor_dev_register(X86_VENDOR_AMD, &amd_cpu_dev);
+
Index: linux-2.6/arch/x86/kernel/cpu/centaur_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/centaur_64.c
+++ linux-2.6/arch/x86/kernel/cpu/centaur_64.c
@@ -4,13 +4,15 @@
#include <asm/cpufeature.h>
#include <asm/processor.h>
-void __cpuinit early_init_centaur(struct cpuinfo_x86 *c)
+#include "cpu.h"
+
+static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c)
{
if (c->x86 == 0x6 && c->x86_model >= 0xf)
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
}
-void __cpuinit init_centaur(struct cpuinfo_x86 *c)
+static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
{
/* Cache sizes */
unsigned n;
@@ -29,3 +31,13 @@ void __cpuinit init_centaur(struct cpuin
}
set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
}
+
+static struct cpu_dev centaur_cpu_dev __cpuinitdata = {
+ .c_vendor = "Centaur",
+ .c_ident = { "CentaurHauls" },
+ .c_early_init = early_init_centaur,
+ .c_init = init_centaur,
+};
+
+cpu_vendor_dev_register(X86_VENDOR_CENTAUR, ¢aur_cpu_dev);
+
Index: linux-2.6/arch/x86/kernel/cpu/cpu.h
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/cpu.h
+++ linux-2.6/arch/x86/kernel/cpu/cpu.h
@@ -1,4 +1,6 @@
-#ifdef CONFIG_X86_32
+#ifndef ARCH_X86_CPU_H
+
+#define ARCH_X86_CPU_H
struct cpu_model_info {
int vendor;
@@ -38,4 +40,4 @@ extern struct cpu_vendor_dev __x86cpuven
extern int get_model_name(struct cpuinfo_x86 *c);
extern void display_cacheinfo(struct cpuinfo_x86 *c);
-#endif /* CONFIG_X86_32 */
+#endif
Index: linux-2.6/arch/x86/kernel/cpu/intel_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/intel_64.c
+++ linux-2.6/arch/x86/kernel/cpu/intel_64.c
@@ -5,7 +5,9 @@
#include <asm/topology.h>
#include <asm/numa_64.h>
-void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
+#include "cpu.h"
+
+static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
{
if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
(c->x86 == 0x6 && c->x86_model >= 0x0e))
@@ -48,7 +50,7 @@ static void __cpuinit srat_detect_node(v
#endif
}
-void __cpuinit init_intel(struct cpuinfo_x86 *c)
+static void __cpuinit init_intel(struct cpuinfo_x86 *c)
{
/* Cache sizes */
unsigned n;
@@ -90,3 +92,12 @@ void __cpuinit init_intel(struct cpuinfo
srat_detect_node();
}
+
+static struct cpu_dev intel_cpu_dev __cpuinitdata = {
+ .c_vendor = "Intel",
+ .c_ident = { "GenuineIntel" },
+ .c_early_init = early_init_intel,
+ .c_init = init_intel,
+};
+cpu_vendor_dev_register(X86_VENDOR_INTEL, &intel_cpu_dev);
+
Index: linux-2.6/arch/x86/kernel/setup_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/setup_64.c
+++ linux-2.6/arch/x86/kernel/setup_64.c
@@ -81,6 +81,8 @@
#define ARCH_SETUP
#endif
+#include "cpu/cpu.h"
+
/* We need valid kernel segments for data and code in long mode too
* IRET will check the segment types kkeil 2000/10/28
* Also sysret mandates a special GDT layout
@@ -180,6 +182,7 @@ static struct resource bss_resource = {
.flags = IORESOURCE_RAM,
};
+static void __init early_cpu_init(void);
static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c);
#ifdef CONFIG_PROC_VMCORE
@@ -341,6 +344,7 @@ void __init setup_arch(char **cmdline_p)
bss_resource.start = virt_to_phys(&__bss_start);
bss_resource.end = virt_to_phys(&__bss_stop)-1;
+ early_cpu_init();
early_identify_cpu(&boot_cpu_data);
strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
@@ -527,6 +531,19 @@ void __init setup_arch(char **cmdline_p)
check_enable_amd_mmconf_dmi();
}
+struct cpu_dev *cpu_devs[X86_VENDOR_NUM] = {};
+
+static void __cpuinit default_init(struct cpuinfo_x86 *c)
+{
+ display_cacheinfo(c);
+}
+
+static struct cpu_dev __cpuinitdata default_cpu = {
+ .c_init = default_init,
+ .c_vendor = "Unknown",
+};
+static struct cpu_dev *this_cpu __cpuinitdata = &default_cpu;
+
int __cpuinit get_model_name(struct cpuinfo_x86 *c)
{
unsigned int *v;
@@ -628,24 +645,37 @@ out:
static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c)
{
char *v = c->x86_vendor_id;
+ int i;
+ static int printed;
- if (!strcmp(v, "AuthenticAMD"))
- c->x86_vendor = X86_VENDOR_AMD;
- else if (!strcmp(v, "GenuineIntel"))
- c->x86_vendor = X86_VENDOR_INTEL;
- else if (!strcmp(v, "CentaurHauls"))
- c->x86_vendor = X86_VENDOR_CENTAUR;
- else
- c->x86_vendor = X86_VENDOR_UNKNOWN;
+ for (i = 0; i < X86_VENDOR_NUM; i++) {
+ if (cpu_devs[i]) {
+ if (!strcmp(v, cpu_devs[i]->c_ident[0]) ||
+ (cpu_devs[i]->c_ident[1] &&
+ !strcmp(v, cpu_devs[i]->c_ident[1]))) {
+ c->x86_vendor = i;
+ this_cpu = cpu_devs[i];
+ return;
+ }
+ }
+ }
+ if (!printed) {
+ printed++;
+ printk(KERN_ERR "CPU: Vendor unknown, using generic init.\n");
+ printk(KERN_ERR "CPU: Your system may be unstable.\n");
+ }
+ c->x86_vendor = X86_VENDOR_UNKNOWN;
}
-// FIXME: Needs to use cpu_vendor_dev_register
-extern void __cpuinit early_init_amd(struct cpuinfo_x86 *c);
-extern void __cpuinit init_amd(struct cpuinfo_x86 *c);
-extern void __cpuinit early_init_intel(struct cpuinfo_x86 *c);
-extern void __cpuinit init_intel(struct cpuinfo_x86 *c);
-extern void __cpuinit early_init_centaur(struct cpuinfo_x86 *c);
-extern void __cpuinit init_centaur(struct cpuinfo_x86 *c);
+static void __init early_cpu_init(void)
+{
+ struct cpu_vendor_dev *cvdev;
+
+ for (cvdev = __x86cpuvendor_start ;
+ cvdev < __x86cpuvendor_end ;
+ cvdev++)
+ cpu_devs[cvdev->vendor] = cvdev->cpu_dev;
+}
/* Do some early cpuid on the boot CPU to get some parameter that are
needed before check_bugs. Everything advanced is in identify_cpu
@@ -725,17 +755,9 @@ static void __cpuinit early_identify_cpu
if (c->extended_cpuid_level >= 0x80000007)
c->x86_power = cpuid_edx(0x80000007);
- switch (c->x86_vendor) {
- case X86_VENDOR_AMD:
- early_init_amd(c);
- break;
- case X86_VENDOR_INTEL:
- early_init_intel(c);
- break;
- case X86_VENDOR_CENTAUR:
- early_init_centaur(c);
- break;
- }
+ if (c->x86_vendor != X86_VENDOR_UNKNOWN &&
+ cpu_devs[c->x86_vendor]->c_early_init)
+ cpu_devs[c->x86_vendor]->c_early_init(c);
validate_pat_support(c);
}
@@ -763,24 +785,8 @@ void __cpuinit identify_cpu(struct cpuin
* At the end of this section, c->x86_capability better
* indicate the features this CPU genuinely supports!
*/
- switch (c->x86_vendor) {
- case X86_VENDOR_AMD:
- init_amd(c);
- break;
-
- case X86_VENDOR_INTEL:
- init_intel(c);
- break;
-
- case X86_VENDOR_CENTAUR:
- init_centaur(c);
- break;
-
- case X86_VENDOR_UNKNOWN:
- default:
- display_cacheinfo(c);
- break;
- }
+ if (this_cpu->c_init)
+ this_cpu->c_init(c);
detect_ht(c);
^ permalink raw reply [flat|nested] 26+ messages in thread* Re: [PATCH] x86: make 64bit identify_cpu use cpu_dev 2008-06-18 9:15 [PATCH] x86: make 64bit identify_cpu use cpu_dev Yinghai Lu @ 2008-06-18 14:17 ` Ingo Molnar 2008-06-19 9:03 ` Ingo Molnar 2008-06-19 22:30 ` [PATCH] x86: make 64bit identify_cpu use cpu_dev v2 Yinghai Lu 1 sibling, 1 reply; 26+ messages in thread From: Ingo Molnar @ 2008-06-18 14:17 UTC (permalink / raw) To: Yinghai Lu Cc: H. Peter Anvin, Thomas Gleixner, Dave Jones, linux-kernel@vger.kernel.org * Yinghai Lu <yhlu.kernel@gmail.com> wrote: > may need to move some functions to common.c later > > Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> applied to tip/x86/cpu, thanks Yinghai. Ingo ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] x86: make 64bit identify_cpu use cpu_dev 2008-06-18 14:17 ` Ingo Molnar @ 2008-06-19 9:03 ` Ingo Molnar 2008-06-19 20:00 ` Yinghai Lu 0 siblings, 1 reply; 26+ messages in thread From: Ingo Molnar @ 2008-06-19 9:03 UTC (permalink / raw) To: Yinghai Lu Cc: H. Peter Anvin, Thomas Gleixner, Dave Jones, linux-kernel@vger.kernel.org * Ingo Molnar <mingo@elte.hu> wrote: > * Yinghai Lu <yhlu.kernel@gmail.com> wrote: > > > may need to move some functions to common.c later > > > > Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> > > applied to tip/x86/cpu, thanks Yinghai. -tip testing found a boot failure on 64-bit, the bootup just hangs early during bootup. I bisected it down to this patch and reverting the patch solves the lockup. Here is the config that triggers it: http://redhat.com/~mingo/misc/config-Thu_Jun_19_10_11_15_CEST_2008.bad Ingo ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] x86: make 64bit identify_cpu use cpu_dev 2008-06-19 9:03 ` Ingo Molnar @ 2008-06-19 20:00 ` Yinghai Lu 0 siblings, 0 replies; 26+ messages in thread From: Yinghai Lu @ 2008-06-19 20:00 UTC (permalink / raw) To: Ingo Molnar Cc: H. Peter Anvin, Thomas Gleixner, Dave Jones, linux-kernel@vger.kernel.org On Thu, Jun 19, 2008 at 2:03 AM, Ingo Molnar <mingo@elte.hu> wrote: > > * Ingo Molnar <mingo@elte.hu> wrote: > >> * Yinghai Lu <yhlu.kernel@gmail.com> wrote: >> >> > may need to move some functions to common.c later >> > >> > Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> >> >> applied to tip/x86/cpu, thanks Yinghai. > > -tip testing found a boot failure on 64-bit, the bootup just hangs early > during bootup. I bisected it down to this patch and reverting the patch > solves the lockup. > > Here is the config that triggers it: > > http://redhat.com/~mingo/misc/config-Thu_Jun_19_10_11_15_CEST_2008.bad can not duplicate that here. can you send me the boot log on your system? YH ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH] x86: make 64bit identify_cpu use cpu_dev v2 2008-06-18 9:15 [PATCH] x86: make 64bit identify_cpu use cpu_dev Yinghai Lu 2008-06-18 14:17 ` Ingo Molnar @ 2008-06-19 22:30 ` Yinghai Lu 2008-06-20 6:29 ` Ingo Molnar ` (2 more replies) 1 sibling, 3 replies; 26+ messages in thread From: Yinghai Lu @ 2008-06-19 22:30 UTC (permalink / raw) To: Ingo Molnar, H. Peter Anvin, Thomas Gleixner, Dave Jones Cc: linux-kernel@vger.kernel.org v2: fix early_panic on some conf reason : struct cpu_vendor_dev size is 16, need to make table to be 16 byte alignment also print out the cpu supported... Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- arch/x86/kernel/cpu/amd_64.c | 17 ++++- arch/x86/kernel/cpu/centaur_64.c | 16 ++++- arch/x86/kernel/cpu/cpu.h | 6 +- arch/x86/kernel/cpu/intel_64.c | 15 ++++- arch/x86/kernel/setup_64.c | 114 +++++++++++++++++++++++---------------- arch/x86/kernel/vmlinux_64.lds.S | 1 6 files changed, 115 insertions(+), 54 deletions(-) Index: linux-2.6/arch/x86/kernel/cpu/amd_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/cpu/amd_64.c +++ linux-2.6/arch/x86/kernel/cpu/amd_64.c @@ -7,8 +7,7 @@ #include <mach_apic.h> -extern int __cpuinit get_model_name(struct cpuinfo_x86 *c); -extern void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c); +#include "cpu.h" int force_mwait __cpuinitdata; @@ -109,7 +108,7 @@ static void __cpuinit early_init_amd_mc( #endif } -void __cpuinit early_init_amd(struct cpuinfo_x86 *c) +static void __cpuinit early_init_amd(struct cpuinfo_x86 *c) { early_init_amd_mc(c); @@ -118,7 +117,7 @@ void __cpuinit early_init_amd(struct cpu set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); } -void __cpuinit init_amd(struct cpuinfo_x86 *c) +static void __cpuinit init_amd(struct cpuinfo_x86 *c) { unsigned level; @@ -200,3 +199,13 @@ void __cpuinit init_amd(struct cpuinfo_x set_memory_4k((unsigned long)__va(tseg), 1); } } + +static struct cpu_dev amd_cpu_dev __cpuinitdata = { + .c_vendor = "AMD", + .c_ident = { "AuthenticAMD" }, + .c_early_init = early_init_amd, + .c_init = init_amd, +}; + +cpu_vendor_dev_register(X86_VENDOR_AMD, &amd_cpu_dev); + Index: linux-2.6/arch/x86/kernel/cpu/centaur_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/cpu/centaur_64.c +++ linux-2.6/arch/x86/kernel/cpu/centaur_64.c @@ -4,13 +4,15 @@ #include <asm/cpufeature.h> #include <asm/processor.h> -void __cpuinit early_init_centaur(struct cpuinfo_x86 *c) +#include "cpu.h" + +static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c) { if (c->x86 == 0x6 && c->x86_model >= 0xf) set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); } -void __cpuinit init_centaur(struct cpuinfo_x86 *c) +static void __cpuinit init_centaur(struct cpuinfo_x86 *c) { /* Cache sizes */ unsigned n; @@ -29,3 +31,13 @@ void __cpuinit init_centaur(struct cpuin } set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); } + +static struct cpu_dev centaur_cpu_dev __cpuinitdata = { + .c_vendor = "Centaur", + .c_ident = { "CentaurHauls" }, + .c_early_init = early_init_centaur, + .c_init = init_centaur, +}; + +cpu_vendor_dev_register(X86_VENDOR_CENTAUR, ¢aur_cpu_dev); + Index: linux-2.6/arch/x86/kernel/cpu/cpu.h =================================================================== --- linux-2.6.orig/arch/x86/kernel/cpu/cpu.h +++ linux-2.6/arch/x86/kernel/cpu/cpu.h @@ -1,4 +1,6 @@ -#ifdef CONFIG_X86_32 +#ifndef ARCH_X86_CPU_H + +#define ARCH_X86_CPU_H struct cpu_model_info { int vendor; @@ -38,4 +40,4 @@ extern struct cpu_vendor_dev __x86cpuven extern int get_model_name(struct cpuinfo_x86 *c); extern void display_cacheinfo(struct cpuinfo_x86 *c); -#endif /* CONFIG_X86_32 */ +#endif Index: linux-2.6/arch/x86/kernel/cpu/intel_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/cpu/intel_64.c +++ linux-2.6/arch/x86/kernel/cpu/intel_64.c @@ -5,7 +5,9 @@ #include <asm/topology.h> #include <asm/numa_64.h> -void __cpuinit early_init_intel(struct cpuinfo_x86 *c) +#include "cpu.h" + +static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) { if ((c->x86 == 0xf && c->x86_model >= 0x03) || (c->x86 == 0x6 && c->x86_model >= 0x0e)) @@ -48,7 +50,7 @@ static void __cpuinit srat_detect_node(v #endif } -void __cpuinit init_intel(struct cpuinfo_x86 *c) +static void __cpuinit init_intel(struct cpuinfo_x86 *c) { /* Cache sizes */ unsigned n; @@ -90,3 +92,12 @@ void __cpuinit init_intel(struct cpuinfo srat_detect_node(); } + +static struct cpu_dev intel_cpu_dev __cpuinitdata = { + .c_vendor = "Intel", + .c_ident = { "GenuineIntel" }, + .c_early_init = early_init_intel, + .c_init = init_intel, +}; +cpu_vendor_dev_register(X86_VENDOR_INTEL, &intel_cpu_dev); + Index: linux-2.6/arch/x86/kernel/setup_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup_64.c +++ linux-2.6/arch/x86/kernel/setup_64.c @@ -81,6 +81,8 @@ #define ARCH_SETUP #endif +#include "cpu/cpu.h" + /* We need valid kernel segments for data and code in long mode too * IRET will check the segment types kkeil 2000/10/28 * Also sysret mandates a special GDT layout @@ -180,6 +182,7 @@ static struct resource bss_resource = { .flags = IORESOURCE_RAM, }; +static void __init early_cpu_init(void); static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c); #ifdef CONFIG_PROC_VMCORE @@ -341,6 +344,7 @@ void __init setup_arch(char **cmdline_p) bss_resource.start = virt_to_phys(&__bss_start); bss_resource.end = virt_to_phys(&__bss_stop)-1; + early_cpu_init(); early_identify_cpu(&boot_cpu_data); strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); @@ -527,6 +531,19 @@ void __init setup_arch(char **cmdline_p) check_enable_amd_mmconf_dmi(); } +struct cpu_dev *cpu_devs[X86_VENDOR_NUM] = {}; + +static void __cpuinit default_init(struct cpuinfo_x86 *c) +{ + display_cacheinfo(c); +} + +static struct cpu_dev __cpuinitdata default_cpu = { + .c_init = default_init, + .c_vendor = "Unknown", +}; +static struct cpu_dev *this_cpu __cpuinitdata = &default_cpu; + int __cpuinit get_model_name(struct cpuinfo_x86 *c) { unsigned int *v; @@ -628,24 +645,57 @@ out: static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c) { char *v = c->x86_vendor_id; + int i; + static int printed; - if (!strcmp(v, "AuthenticAMD")) - c->x86_vendor = X86_VENDOR_AMD; - else if (!strcmp(v, "GenuineIntel")) - c->x86_vendor = X86_VENDOR_INTEL; - else if (!strcmp(v, "CentaurHauls")) - c->x86_vendor = X86_VENDOR_CENTAUR; - else - c->x86_vendor = X86_VENDOR_UNKNOWN; + for (i = 0; i < X86_VENDOR_NUM; i++) { + if (cpu_devs[i]) { + if (!strcmp(v, cpu_devs[i]->c_ident[0]) || + (cpu_devs[i]->c_ident[1] && + !strcmp(v, cpu_devs[i]->c_ident[1]))) { + c->x86_vendor = i; + this_cpu = cpu_devs[i]; + return; + } + } + } + if (!printed) { + printed++; + printk(KERN_ERR "CPU: Vendor unknown, using generic init.\n"); + printk(KERN_ERR "CPU: Your system may be unstable.\n"); + } + c->x86_vendor = X86_VENDOR_UNKNOWN; } -// FIXME: Needs to use cpu_vendor_dev_register -extern void __cpuinit early_init_amd(struct cpuinfo_x86 *c); -extern void __cpuinit init_amd(struct cpuinfo_x86 *c); -extern void __cpuinit early_init_intel(struct cpuinfo_x86 *c); -extern void __cpuinit init_intel(struct cpuinfo_x86 *c); -extern void __cpuinit early_init_centaur(struct cpuinfo_x86 *c); -extern void __cpuinit init_centaur(struct cpuinfo_x86 *c); +static void __init early_cpu_support_print(void) +{ + int i,j; + struct cpu_dev *cpu_devx; + + printk("KERNEL supported cpus:\n"); + for (i = 0; i < X86_VENDOR_NUM; i++) { + cpu_devx = cpu_devs[i]; + if (!cpu_devx) + continue; + for (j = 0; j < 2; j++) { + if (!cpu_devx->c_ident[j]) + continue; + printk(" %s %s\n", cpu_devx->c_vendor, + cpu_devx->c_ident[j]); + } + } +} + +static void __init early_cpu_init(void) +{ + struct cpu_vendor_dev *cvdev; + + for (cvdev = __x86cpuvendor_start ; + cvdev < __x86cpuvendor_end ; + cvdev++) + cpu_devs[cvdev->vendor] = cvdev->cpu_dev; + early_cpu_support_print(); +} /* Do some early cpuid on the boot CPU to get some parameter that are needed before check_bugs. Everything advanced is in identify_cpu @@ -725,17 +775,9 @@ static void __cpuinit early_identify_cpu if (c->extended_cpuid_level >= 0x80000007) c->x86_power = cpuid_edx(0x80000007); - switch (c->x86_vendor) { - case X86_VENDOR_AMD: - early_init_amd(c); - break; - case X86_VENDOR_INTEL: - early_init_intel(c); - break; - case X86_VENDOR_CENTAUR: - early_init_centaur(c); - break; - } + if (c->x86_vendor != X86_VENDOR_UNKNOWN && + cpu_devs[c->x86_vendor]->c_early_init) + cpu_devs[c->x86_vendor]->c_early_init(c); validate_pat_support(c); } @@ -763,24 +805,8 @@ void __cpuinit identify_cpu(struct cpuin * At the end of this section, c->x86_capability better * indicate the features this CPU genuinely supports! */ - switch (c->x86_vendor) { - case X86_VENDOR_AMD: - init_amd(c); - break; - - case X86_VENDOR_INTEL: - init_intel(c); - break; - - case X86_VENDOR_CENTAUR: - init_centaur(c); - break; - - case X86_VENDOR_UNKNOWN: - default: - display_cacheinfo(c); - break; - } + if (this_cpu->c_init) + this_cpu->c_init(c); detect_ht(c); Index: linux-2.6/arch/x86/kernel/vmlinux_64.lds.S =================================================================== --- linux-2.6.orig/arch/x86/kernel/vmlinux_64.lds.S +++ linux-2.6/arch/x86/kernel/vmlinux_64.lds.S @@ -168,6 +168,7 @@ SECTIONS *(.con_initcall.init) } __con_initcall_end = .; + . = ALIGN(16); __x86cpuvendor_start = .; .x86cpuvendor.init : AT(ADDR(.x86cpuvendor.init) - LOAD_OFFSET) { *(.x86cpuvendor.init) ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] x86: make 64bit identify_cpu use cpu_dev v2 2008-06-19 22:30 ` [PATCH] x86: make 64bit identify_cpu use cpu_dev v2 Yinghai Lu @ 2008-06-20 6:29 ` Ingo Molnar 2008-06-20 7:08 ` Yinghai Lu [not found] ` <200806210323.01590.yhlu.kernel@gmail.com> 2008-06-21 10:24 ` [PATCH] x86: seperate funcs from setup_64 to cpu common_64.c Yinghai Lu 2 siblings, 1 reply; 26+ messages in thread From: Ingo Molnar @ 2008-06-20 6:29 UTC (permalink / raw) To: Yinghai Lu Cc: H. Peter Anvin, Thomas Gleixner, Dave Jones, linux-kernel@vger.kernel.org, Thomas Petazzoni * Yinghai Lu <yhlu.kernel@gmail.com> wrote: > v2: fix early_panic on some conf > reason : struct cpu_vendor_dev size is 16, need to make table to be 16 > byte alignment > also print out the cpu supported... applied to tip/x86/cpu, thanks Yinghai. > --- linux-2.6.orig/arch/x86/kernel/vmlinux_64.lds.S > +++ linux-2.6/arch/x86/kernel/vmlinux_64.lds.S > @@ -168,6 +168,7 @@ SECTIONS > *(.con_initcall.init) > } > __con_initcall_end = .; > + . = ALIGN(16); > __x86cpuvendor_start = .; > .x86cpuvendor.init : AT(ADDR(.x86cpuvendor.init) - LOAD_OFFSET) { > *(.x86cpuvendor.init) ah, nice one! we broke that via v2.6.25-37-g03ae576 "x86: use ELF section to list CPU vendor specific code" - should we backport your fix to mainline right now? I'm wondering why it only triggered now - did alignment change in this section due to your changes and thus this dormant bug became triggerable? Ingo ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] x86: make 64bit identify_cpu use cpu_dev v2 2008-06-20 6:29 ` Ingo Molnar @ 2008-06-20 7:08 ` Yinghai Lu 0 siblings, 0 replies; 26+ messages in thread From: Yinghai Lu @ 2008-06-20 7:08 UTC (permalink / raw) To: Ingo Molnar Cc: H. Peter Anvin, Thomas Gleixner, Dave Jones, linux-kernel@vger.kernel.org, Thomas Petazzoni On Thu, Jun 19, 2008 at 11:29 PM, Ingo Molnar <mingo@elte.hu> wrote: > > * Yinghai Lu <yhlu.kernel@gmail.com> wrote: > >> v2: fix early_panic on some conf >> reason : struct cpu_vendor_dev size is 16, need to make table to be 16 >> byte alignment >> also print out the cpu supported... > > applied to tip/x86/cpu, thanks Yinghai. > >> --- linux-2.6.orig/arch/x86/kernel/vmlinux_64.lds.S >> +++ linux-2.6/arch/x86/kernel/vmlinux_64.lds.S >> @@ -168,6 +168,7 @@ SECTIONS >> *(.con_initcall.init) >> } >> __con_initcall_end = .; >> + . = ALIGN(16); >> __x86cpuvendor_start = .; >> .x86cpuvendor.init : AT(ADDR(.x86cpuvendor.init) - LOAD_OFFSET) { >> *(.x86cpuvendor.init) > > ah, nice one! > > we broke that via v2.6.25-37-g03ae576 "x86: use ELF section to list CPU > vendor specific code" - should we backport your fix to mainline right > now? I'm wondering why it only triggered now - did alignment change in > this section due to your changes and thus this dormant bug became > triggerable? don't need, that section is not used before this patch. we my add some building check to verify those kind info to avoid same kind bug. YH ^ permalink raw reply [flat|nested] 26+ messages in thread
[parent not found: <200806210323.01590.yhlu.kernel@gmail.com>]
* [PATCH] x86: change identify_cpu to static [not found] ` <200806210323.01590.yhlu.kernel@gmail.com> @ 2008-06-21 10:24 ` Yinghai Lu 0 siblings, 0 replies; 26+ messages in thread From: Yinghai Lu @ 2008-06-21 10:24 UTC (permalink / raw) To: Ingo Molnar, H. Peter Anvin, Thomas Gleixner; +Cc: linux-kernel@vger.kernel.org [PATCH] x86: change identify_cpu to static Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kernel/cpu/common_64.c | 2 +- include/asm-x86/processor.h | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) Index: linux-2.6/arch/x86/kernel/cpu/common_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/cpu/common_64.c +++ linux-2.6/arch/x86/kernel/cpu/common_64.c @@ -312,7 +312,7 @@ static void __cpuinit early_identify_cpu /* * This does the hard work of actually picking apart the CPU stuff... */ -void __cpuinit identify_cpu(struct cpuinfo_x86 *c) +static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) { int i; Index: linux-2.6/arch/x86/kernel/cpu/common.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/cpu/common.c +++ linux-2.6/arch/x86/kernel/cpu/common.c @@ -427,7 +427,7 @@ __setup("serialnumber", x86_serial_nr_se /* * This does the hard work of actually picking apart the CPU stuff... */ -void __cpuinit identify_cpu(struct cpuinfo_x86 *c) +static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) { int i; Index: linux-2.6/include/asm-x86/processor.h =================================================================== --- linux-2.6.orig/include/asm-x86/processor.h +++ linux-2.6/include/asm-x86/processor.h @@ -155,7 +155,6 @@ static inline int hlt_works(int cpu) extern void cpu_detect(struct cpuinfo_x86 *c); extern void early_cpu_init(void); -extern void identify_cpu(struct cpuinfo_x86 *); extern void identify_boot_cpu(void); extern void identify_secondary_cpu(struct cpuinfo_x86 *); extern void print_cpu_info(struct cpuinfo_x86 *); ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH] x86: seperate funcs from setup_64 to cpu common_64.c 2008-06-19 22:30 ` [PATCH] x86: make 64bit identify_cpu use cpu_dev v2 Yinghai Lu 2008-06-20 6:29 ` Ingo Molnar [not found] ` <200806210323.01590.yhlu.kernel@gmail.com> @ 2008-06-21 10:24 ` Yinghai Lu 2008-06-21 23:25 ` [PATCH] x86: merge setup64.c into common_64.c Yinghai Lu 2008-06-22 2:16 ` [PATCH] x86: remove two duplicated func in setup_32.c Yinghai Lu 2 siblings, 2 replies; 26+ messages in thread From: Yinghai Lu @ 2008-06-21 10:24 UTC (permalink / raw) To: Ingo Molnar, H. Peter Anvin, Thomas Gleixner; +Cc: linux-kernel@vger.kernel.org Signed-off-by: Yinghai Lu <yhlu.kernel@mail.com> --- arch/x86/kernel/cpu/Makefile | 2 arch/x86/kernel/cpu/common_64.c | 406 ++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/setup_64.c | 393 -------------------------------------- include/asm-x86/processor.h | 1 4 files changed, 409 insertions(+), 393 deletions(-) Index: linux-2.6/arch/x86/kernel/setup_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup_64.c +++ linux-2.6/arch/x86/kernel/setup_64.c @@ -41,7 +41,6 @@ #include <linux/dmi.h> #include <linux/dma-mapping.h> #include <linux/ctype.h> -#include <linux/sort.h> #include <linux/uaccess.h> #include <linux/init_ohci1394_dma.h> #include <linux/kvm_para.h> @@ -52,7 +51,6 @@ #include <asm/vsyscall.h> #include <asm/io.h> #include <asm/smp.h> -#include <asm/msr.h> #include <asm/desc.h> #include <video/edid.h> #include <asm/e820.h> @@ -67,11 +65,6 @@ #include <asm/sections.h> #include <asm/dmi.h> #include <asm/cacheflush.h> -#include <asm/mce.h> -#include <asm/ds.h> -#include <asm/topology.h> -#include <asm/trampoline.h> -#include <asm/pat.h> #include <mach_apic.h> #ifdef CONFIG_PARAVIRT @@ -80,24 +73,6 @@ #define ARCH_SETUP #endif -#include "cpu/cpu.h" - -/* We need valid kernel segments for data and code in long mode too - * IRET will check the segment types kkeil 2000/10/28 - * Also sysret mandates a special GDT layout - */ -/* The TLS descriptors are currently at a different place compared to i386. - Hopefully nobody expects them at a fixed place (Wine?) */ -DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = { - [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } }, - [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } }, - [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } }, - [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } }, - [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } }, - [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } }, -} }; -EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); - /* * Machine setup.. */ @@ -105,8 +80,6 @@ EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); struct cpuinfo_x86 boot_cpu_data __read_mostly; EXPORT_SYMBOL(boot_cpu_data); -__u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata; - unsigned long mmu_cr4_features; /* Boot loader ID as an integer, for the benefit of proc_dointvec */ @@ -181,9 +154,6 @@ static struct resource bss_resource = { .flags = IORESOURCE_RAM, }; -static void __init early_cpu_init(void); -static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c); - #ifdef CONFIG_PROC_VMCORE /* elfcorehdr= specifies the location of elf core header * stored by the crashed kernel. This option will be passed @@ -243,17 +213,6 @@ static inline void copy_edd(void) } #endif -/* Current gdt points %fs at the "master" per-cpu area: after this, - * * it's on the real one. */ -void switch_to_new_gdt(void) -{ - struct desc_ptr gdt_descr; - - gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id()); - gdt_descr.size = GDT_SIZE - 1; - load_gdt(&gdt_descr); -} - /* * setup_arch - architecture-specific boot-time initializations * @@ -304,7 +263,6 @@ void __init setup_arch(char **cmdline_p) bss_resource.end = virt_to_phys(&__bss_stop)-1; early_cpu_init(); - early_identify_cpu(&boot_cpu_data); strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; @@ -488,353 +446,3 @@ void __init setup_arch(char **cmdline_p) #endif } -struct cpu_dev *cpu_devs[X86_VENDOR_NUM] = {}; - -static void __cpuinit default_init(struct cpuinfo_x86 *c) -{ - display_cacheinfo(c); -} - -static struct cpu_dev __cpuinitdata default_cpu = { - .c_init = default_init, - .c_vendor = "Unknown", -}; -static struct cpu_dev *this_cpu __cpuinitdata = &default_cpu; - -int __cpuinit get_model_name(struct cpuinfo_x86 *c) -{ - unsigned int *v; - - if (c->extended_cpuid_level < 0x80000004) - return 0; - - v = (unsigned int *) c->x86_model_id; - cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]); - cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]); - cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]); - c->x86_model_id[48] = 0; - return 1; -} - - -void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) -{ - unsigned int n, dummy, eax, ebx, ecx, edx; - - n = c->extended_cpuid_level; - - if (n >= 0x80000005) { - cpuid(0x80000005, &dummy, &ebx, &ecx, &edx); - printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), " - "D cache %dK (%d bytes/line)\n", - edx>>24, edx&0xFF, ecx>>24, ecx&0xFF); - c->x86_cache_size = (ecx>>24) + (edx>>24); - /* On K8 L1 TLB is inclusive, so don't count it */ - c->x86_tlbsize = 0; - } - - if (n >= 0x80000006) { - cpuid(0x80000006, &dummy, &ebx, &ecx, &edx); - ecx = cpuid_ecx(0x80000006); - c->x86_cache_size = ecx >> 16; - c->x86_tlbsize += ((ebx >> 16) & 0xfff) + (ebx & 0xfff); - - printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n", - c->x86_cache_size, ecx & 0xFF); - } - if (n >= 0x80000008) { - cpuid(0x80000008, &eax, &dummy, &dummy, &dummy); - c->x86_virt_bits = (eax >> 8) & 0xff; - c->x86_phys_bits = eax & 0xff; - } -} - -void __cpuinit detect_ht(struct cpuinfo_x86 *c) -{ -#ifdef CONFIG_SMP - u32 eax, ebx, ecx, edx; - int index_msb, core_bits; - - cpuid(1, &eax, &ebx, &ecx, &edx); - - - if (!cpu_has(c, X86_FEATURE_HT)) - return; - if (cpu_has(c, X86_FEATURE_CMP_LEGACY)) - goto out; - - smp_num_siblings = (ebx & 0xff0000) >> 16; - - if (smp_num_siblings == 1) { - printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); - } else if (smp_num_siblings > 1) { - - if (smp_num_siblings > NR_CPUS) { - printk(KERN_WARNING "CPU: Unsupported number of " - "siblings %d", smp_num_siblings); - smp_num_siblings = 1; - return; - } - - index_msb = get_count_order(smp_num_siblings); - c->phys_proc_id = phys_pkg_id(index_msb); - - smp_num_siblings = smp_num_siblings / c->x86_max_cores; - - index_msb = get_count_order(smp_num_siblings); - - core_bits = get_count_order(c->x86_max_cores); - - c->cpu_core_id = phys_pkg_id(index_msb) & - ((1 << core_bits) - 1); - } -out: - if ((c->x86_max_cores * smp_num_siblings) > 1) { - printk(KERN_INFO "CPU: Physical Processor ID: %d\n", - c->phys_proc_id); - printk(KERN_INFO "CPU: Processor Core ID: %d\n", - c->cpu_core_id); - } - -#endif -} - -static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c) -{ - char *v = c->x86_vendor_id; - int i; - static int printed; - - for (i = 0; i < X86_VENDOR_NUM; i++) { - if (cpu_devs[i]) { - if (!strcmp(v, cpu_devs[i]->c_ident[0]) || - (cpu_devs[i]->c_ident[1] && - !strcmp(v, cpu_devs[i]->c_ident[1]))) { - c->x86_vendor = i; - this_cpu = cpu_devs[i]; - return; - } - } - } - if (!printed) { - printed++; - printk(KERN_ERR "CPU: Vendor unknown, using generic init.\n"); - printk(KERN_ERR "CPU: Your system may be unstable.\n"); - } - c->x86_vendor = X86_VENDOR_UNKNOWN; -} - -static void __init early_cpu_support_print(void) -{ - int i,j; - struct cpu_dev *cpu_devx; - - printk("KERNEL supported cpus:\n"); - for (i = 0; i < X86_VENDOR_NUM; i++) { - cpu_devx = cpu_devs[i]; - if (!cpu_devx) - continue; - for (j = 0; j < 2; j++) { - if (!cpu_devx->c_ident[j]) - continue; - printk(" %s %s\n", cpu_devx->c_vendor, - cpu_devx->c_ident[j]); - } - } -} - -static void __init early_cpu_init(void) -{ - struct cpu_vendor_dev *cvdev; - - for (cvdev = __x86cpuvendor_start ; - cvdev < __x86cpuvendor_end ; - cvdev++) - cpu_devs[cvdev->vendor] = cvdev->cpu_dev; - early_cpu_support_print(); -} - -/* Do some early cpuid on the boot CPU to get some parameter that are - needed before check_bugs. Everything advanced is in identify_cpu - below. */ -static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c) -{ - u32 tfms, xlvl; - - c->loops_per_jiffy = loops_per_jiffy; - c->x86_cache_size = -1; - c->x86_vendor = X86_VENDOR_UNKNOWN; - c->x86_model = c->x86_mask = 0; /* So far unknown... */ - c->x86_vendor_id[0] = '\0'; /* Unset */ - c->x86_model_id[0] = '\0'; /* Unset */ - c->x86_clflush_size = 64; - c->x86_cache_alignment = c->x86_clflush_size; - c->x86_max_cores = 1; - c->x86_coreid_bits = 0; - c->extended_cpuid_level = 0; - memset(&c->x86_capability, 0, sizeof c->x86_capability); - - /* Get vendor name */ - cpuid(0x00000000, (unsigned int *)&c->cpuid_level, - (unsigned int *)&c->x86_vendor_id[0], - (unsigned int *)&c->x86_vendor_id[8], - (unsigned int *)&c->x86_vendor_id[4]); - - get_cpu_vendor(c); - - /* Initialize the standard set of capabilities */ - /* Note that the vendor-specific code below might override */ - - /* Intel-defined flags: level 0x00000001 */ - if (c->cpuid_level >= 0x00000001) { - __u32 misc; - cpuid(0x00000001, &tfms, &misc, &c->x86_capability[4], - &c->x86_capability[0]); - c->x86 = (tfms >> 8) & 0xf; - c->x86_model = (tfms >> 4) & 0xf; - c->x86_mask = tfms & 0xf; - if (c->x86 == 0xf) - c->x86 += (tfms >> 20) & 0xff; - if (c->x86 >= 0x6) - c->x86_model += ((tfms >> 16) & 0xF) << 4; - if (test_cpu_cap(c, X86_FEATURE_CLFLSH)) - c->x86_clflush_size = ((misc >> 8) & 0xff) * 8; - } else { - /* Have CPUID level 0 only - unheard of */ - c->x86 = 4; - } - - c->initial_apicid = (cpuid_ebx(1) >> 24) & 0xff; -#ifdef CONFIG_SMP - c->phys_proc_id = c->initial_apicid; -#endif - /* AMD-defined flags: level 0x80000001 */ - xlvl = cpuid_eax(0x80000000); - c->extended_cpuid_level = xlvl; - if ((xlvl & 0xffff0000) == 0x80000000) { - if (xlvl >= 0x80000001) { - c->x86_capability[1] = cpuid_edx(0x80000001); - c->x86_capability[6] = cpuid_ecx(0x80000001); - } - if (xlvl >= 0x80000004) - get_model_name(c); /* Default name */ - } - - /* Transmeta-defined flags: level 0x80860001 */ - xlvl = cpuid_eax(0x80860000); - if ((xlvl & 0xffff0000) == 0x80860000) { - /* Don't set x86_cpuid_level here for now to not confuse. */ - if (xlvl >= 0x80860001) - c->x86_capability[2] = cpuid_edx(0x80860001); - } - - c->extended_cpuid_level = cpuid_eax(0x80000000); - if (c->extended_cpuid_level >= 0x80000007) - c->x86_power = cpuid_edx(0x80000007); - - if (c->x86_vendor != X86_VENDOR_UNKNOWN && - cpu_devs[c->x86_vendor]->c_early_init) - cpu_devs[c->x86_vendor]->c_early_init(c); - - validate_pat_support(c); - - /* early_param could clear that, but recall get it set again */ - if (disable_apic) - clear_cpu_cap(c, X86_FEATURE_APIC); -} - -/* - * This does the hard work of actually picking apart the CPU stuff... - */ -void __cpuinit identify_cpu(struct cpuinfo_x86 *c) -{ - int i; - - early_identify_cpu(c); - - init_scattered_cpuid_features(c); - - c->apicid = phys_pkg_id(0); - - /* - * Vendor-specific initialization. In this section we - * canonicalize the feature flags, meaning if there are - * features a certain CPU supports which CPUID doesn't - * tell us, CPUID claiming incorrect flags, or other bugs, - * we handle them here. - * - * At the end of this section, c->x86_capability better - * indicate the features this CPU genuinely supports! - */ - if (this_cpu->c_init) - this_cpu->c_init(c); - - detect_ht(c); - - /* - * On SMP, boot_cpu_data holds the common feature set between - * all CPUs; so make sure that we indicate which features are - * common between the CPUs. The first time this routine gets - * executed, c == &boot_cpu_data. - */ - if (c != &boot_cpu_data) { - /* AND the already accumulated flags with these */ - for (i = 0; i < NCAPINTS; i++) - boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; - } - - /* Clear all flags overriden by options */ - for (i = 0; i < NCAPINTS; i++) - c->x86_capability[i] &= ~cleared_cpu_caps[i]; - -#ifdef CONFIG_X86_MCE - mcheck_init(c); -#endif - select_idle_routine(c); - -#ifdef CONFIG_NUMA - numa_add_cpu(smp_processor_id()); -#endif - -} - -void __cpuinit identify_boot_cpu(void) -{ - identify_cpu(&boot_cpu_data); -} - -void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) -{ - BUG_ON(c == &boot_cpu_data); - identify_cpu(c); - mtrr_ap_init(); -} - -static __init int setup_noclflush(char *arg) -{ - setup_clear_cpu_cap(X86_FEATURE_CLFLSH); - return 1; -} -__setup("noclflush", setup_noclflush); - -void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) -{ - if (c->x86_model_id[0]) - printk(KERN_CONT "%s", c->x86_model_id); - - if (c->x86_mask || c->cpuid_level >= 0) - printk(KERN_CONT " stepping %02x\n", c->x86_mask); - else - printk(KERN_CONT "\n"); -} - -static __init int setup_disablecpuid(char *arg) -{ - int bit; - if (get_option(&arg, &bit) && bit < NCAPINTS*32) - setup_clear_cpu_cap(bit); - else - return 0; - return 1; -} -__setup("clearcpuid=", setup_disablecpuid); Index: linux-2.6/arch/x86/kernel/cpu/common_64.c =================================================================== --- /dev/null +++ linux-2.6/arch/x86/kernel/cpu/common_64.c @@ -0,0 +1,406 @@ +#include <linux/init.h> +#include <linux/string.h> +#include <linux/delay.h> +#include <linux/smp.h> +#include <linux/module.h> +#include <linux/percpu.h> +#include <linux/bootmem.h> +#include <asm/processor.h> +#include <asm/i387.h> +#include <asm/msr.h> +#include <asm/io.h> +#include <asm/mmu_context.h> +#include <asm/mtrr.h> +#include <asm/mce.h> +#include <asm/pat.h> +#include <asm/numa.h> +#ifdef CONFIG_X86_LOCAL_APIC +#include <asm/mpspec.h> +#include <asm/apic.h> +#include <mach_apic.h> +#endif + +#include "cpu.h" + +/* We need valid kernel segments for data and code in long mode too + * IRET will check the segment types kkeil 2000/10/28 + * Also sysret mandates a special GDT layout + */ +/* The TLS descriptors are currently at a different place compared to i386. + Hopefully nobody expects them at a fixed place (Wine?) */ +DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = { + [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } }, + [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } }, + [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } }, + [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } }, + [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } }, + [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } }, +} }; +EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); + +__u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata; + +/* Current gdt points %fs at the "master" per-cpu area: after this, + * * it's on the real one. */ +void switch_to_new_gdt(void) +{ + struct desc_ptr gdt_descr; + + gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id()); + gdt_descr.size = GDT_SIZE - 1; + load_gdt(&gdt_descr); +} + +struct cpu_dev *cpu_devs[X86_VENDOR_NUM] = {}; + +static void __cpuinit default_init(struct cpuinfo_x86 *c) +{ + display_cacheinfo(c); +} + +static struct cpu_dev __cpuinitdata default_cpu = { + .c_init = default_init, + .c_vendor = "Unknown", +}; +static struct cpu_dev *this_cpu __cpuinitdata = &default_cpu; + +int __cpuinit get_model_name(struct cpuinfo_x86 *c) +{ + unsigned int *v; + + if (c->extended_cpuid_level < 0x80000004) + return 0; + + v = (unsigned int *) c->x86_model_id; + cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]); + cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]); + cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]); + c->x86_model_id[48] = 0; + return 1; +} + + +void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) +{ + unsigned int n, dummy, eax, ebx, ecx, edx; + + n = c->extended_cpuid_level; + + if (n >= 0x80000005) { + cpuid(0x80000005, &dummy, &ebx, &ecx, &edx); + printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), " + "D cache %dK (%d bytes/line)\n", + edx>>24, edx&0xFF, ecx>>24, ecx&0xFF); + c->x86_cache_size = (ecx>>24) + (edx>>24); + /* On K8 L1 TLB is inclusive, so don't count it */ + c->x86_tlbsize = 0; + } + + if (n >= 0x80000006) { + cpuid(0x80000006, &dummy, &ebx, &ecx, &edx); + ecx = cpuid_ecx(0x80000006); + c->x86_cache_size = ecx >> 16; + c->x86_tlbsize += ((ebx >> 16) & 0xfff) + (ebx & 0xfff); + + printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n", + c->x86_cache_size, ecx & 0xFF); + } + if (n >= 0x80000008) { + cpuid(0x80000008, &eax, &dummy, &dummy, &dummy); + c->x86_virt_bits = (eax >> 8) & 0xff; + c->x86_phys_bits = eax & 0xff; + } +} + +void __cpuinit detect_ht(struct cpuinfo_x86 *c) +{ +#ifdef CONFIG_SMP + u32 eax, ebx, ecx, edx; + int index_msb, core_bits; + + cpuid(1, &eax, &ebx, &ecx, &edx); + + + if (!cpu_has(c, X86_FEATURE_HT)) + return; + if (cpu_has(c, X86_FEATURE_CMP_LEGACY)) + goto out; + + smp_num_siblings = (ebx & 0xff0000) >> 16; + + if (smp_num_siblings == 1) { + printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); + } else if (smp_num_siblings > 1) { + + if (smp_num_siblings > NR_CPUS) { + printk(KERN_WARNING "CPU: Unsupported number of " + "siblings %d", smp_num_siblings); + smp_num_siblings = 1; + return; + } + + index_msb = get_count_order(smp_num_siblings); + c->phys_proc_id = phys_pkg_id(index_msb); + + smp_num_siblings = smp_num_siblings / c->x86_max_cores; + + index_msb = get_count_order(smp_num_siblings); + + core_bits = get_count_order(c->x86_max_cores); + + c->cpu_core_id = phys_pkg_id(index_msb) & + ((1 << core_bits) - 1); + } +out: + if ((c->x86_max_cores * smp_num_siblings) > 1) { + printk(KERN_INFO "CPU: Physical Processor ID: %d\n", + c->phys_proc_id); + printk(KERN_INFO "CPU: Processor Core ID: %d\n", + c->cpu_core_id); + } + +#endif +} + +static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c) +{ + char *v = c->x86_vendor_id; + int i; + static int printed; + + for (i = 0; i < X86_VENDOR_NUM; i++) { + if (cpu_devs[i]) { + if (!strcmp(v, cpu_devs[i]->c_ident[0]) || + (cpu_devs[i]->c_ident[1] && + !strcmp(v, cpu_devs[i]->c_ident[1]))) { + c->x86_vendor = i; + this_cpu = cpu_devs[i]; + return; + } + } + } + if (!printed) { + printed++; + printk(KERN_ERR "CPU: Vendor unknown, using generic init.\n"); + printk(KERN_ERR "CPU: Your system may be unstable.\n"); + } + c->x86_vendor = X86_VENDOR_UNKNOWN; +} + +static void __init early_cpu_support_print(void) +{ + int i,j; + struct cpu_dev *cpu_devx; + + printk("KERNEL supported cpus:\n"); + for (i = 0; i < X86_VENDOR_NUM; i++) { + cpu_devx = cpu_devs[i]; + if (!cpu_devx) + continue; + for (j = 0; j < 2; j++) { + if (!cpu_devx->c_ident[j]) + continue; + printk(" %s %s\n", cpu_devx->c_vendor, + cpu_devx->c_ident[j]); + } + } +} + +static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c); + +void __init early_cpu_init(void) +{ + struct cpu_vendor_dev *cvdev; + + for (cvdev = __x86cpuvendor_start ; + cvdev < __x86cpuvendor_end ; + cvdev++) + cpu_devs[cvdev->vendor] = cvdev->cpu_dev; + early_cpu_support_print(); + early_identify_cpu(&boot_cpu_data); +} + +/* Do some early cpuid on the boot CPU to get some parameter that are + needed before check_bugs. Everything advanced is in identify_cpu + below. */ +static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c) +{ + u32 tfms, xlvl; + + c->loops_per_jiffy = loops_per_jiffy; + c->x86_cache_size = -1; + c->x86_vendor = X86_VENDOR_UNKNOWN; + c->x86_model = c->x86_mask = 0; /* So far unknown... */ + c->x86_vendor_id[0] = '\0'; /* Unset */ + c->x86_model_id[0] = '\0'; /* Unset */ + c->x86_clflush_size = 64; + c->x86_cache_alignment = c->x86_clflush_size; + c->x86_max_cores = 1; + c->x86_coreid_bits = 0; + c->extended_cpuid_level = 0; + memset(&c->x86_capability, 0, sizeof c->x86_capability); + + /* Get vendor name */ + cpuid(0x00000000, (unsigned int *)&c->cpuid_level, + (unsigned int *)&c->x86_vendor_id[0], + (unsigned int *)&c->x86_vendor_id[8], + (unsigned int *)&c->x86_vendor_id[4]); + + get_cpu_vendor(c); + + /* Initialize the standard set of capabilities */ + /* Note that the vendor-specific code below might override */ + + /* Intel-defined flags: level 0x00000001 */ + if (c->cpuid_level >= 0x00000001) { + __u32 misc; + cpuid(0x00000001, &tfms, &misc, &c->x86_capability[4], + &c->x86_capability[0]); + c->x86 = (tfms >> 8) & 0xf; + c->x86_model = (tfms >> 4) & 0xf; + c->x86_mask = tfms & 0xf; + if (c->x86 == 0xf) + c->x86 += (tfms >> 20) & 0xff; + if (c->x86 >= 0x6) + c->x86_model += ((tfms >> 16) & 0xF) << 4; + if (test_cpu_cap(c, X86_FEATURE_CLFLSH)) + c->x86_clflush_size = ((misc >> 8) & 0xff) * 8; + } else { + /* Have CPUID level 0 only - unheard of */ + c->x86 = 4; + } + + c->initial_apicid = (cpuid_ebx(1) >> 24) & 0xff; +#ifdef CONFIG_SMP + c->phys_proc_id = c->initial_apicid; +#endif + /* AMD-defined flags: level 0x80000001 */ + xlvl = cpuid_eax(0x80000000); + c->extended_cpuid_level = xlvl; + if ((xlvl & 0xffff0000) == 0x80000000) { + if (xlvl >= 0x80000001) { + c->x86_capability[1] = cpuid_edx(0x80000001); + c->x86_capability[6] = cpuid_ecx(0x80000001); + } + if (xlvl >= 0x80000004) + get_model_name(c); /* Default name */ + } + + /* Transmeta-defined flags: level 0x80860001 */ + xlvl = cpuid_eax(0x80860000); + if ((xlvl & 0xffff0000) == 0x80860000) { + /* Don't set x86_cpuid_level here for now to not confuse. */ + if (xlvl >= 0x80860001) + c->x86_capability[2] = cpuid_edx(0x80860001); + } + + c->extended_cpuid_level = cpuid_eax(0x80000000); + if (c->extended_cpuid_level >= 0x80000007) + c->x86_power = cpuid_edx(0x80000007); + + if (c->x86_vendor != X86_VENDOR_UNKNOWN && + cpu_devs[c->x86_vendor]->c_early_init) + cpu_devs[c->x86_vendor]->c_early_init(c); + + validate_pat_support(c); + + /* early_param could clear that, but recall get it set again */ + if (disable_apic) + clear_cpu_cap(c, X86_FEATURE_APIC); +} + +/* + * This does the hard work of actually picking apart the CPU stuff... + */ +void __cpuinit identify_cpu(struct cpuinfo_x86 *c) +{ + int i; + + early_identify_cpu(c); + + init_scattered_cpuid_features(c); + + c->apicid = phys_pkg_id(0); + + /* + * Vendor-specific initialization. In this section we + * canonicalize the feature flags, meaning if there are + * features a certain CPU supports which CPUID doesn't + * tell us, CPUID claiming incorrect flags, or other bugs, + * we handle them here. + * + * At the end of this section, c->x86_capability better + * indicate the features this CPU genuinely supports! + */ + if (this_cpu->c_init) + this_cpu->c_init(c); + + detect_ht(c); + + /* + * On SMP, boot_cpu_data holds the common feature set between + * all CPUs; so make sure that we indicate which features are + * common between the CPUs. The first time this routine gets + * executed, c == &boot_cpu_data. + */ + if (c != &boot_cpu_data) { + /* AND the already accumulated flags with these */ + for (i = 0; i < NCAPINTS; i++) + boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; + } + + /* Clear all flags overriden by options */ + for (i = 0; i < NCAPINTS; i++) + c->x86_capability[i] &= ~cleared_cpu_caps[i]; + +#ifdef CONFIG_X86_MCE + mcheck_init(c); +#endif + select_idle_routine(c); + +#ifdef CONFIG_NUMA + numa_add_cpu(smp_processor_id()); +#endif + +} + +void __cpuinit identify_boot_cpu(void) +{ + identify_cpu(&boot_cpu_data); +} + +void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) +{ + BUG_ON(c == &boot_cpu_data); + identify_cpu(c); + mtrr_ap_init(); +} + +static __init int setup_noclflush(char *arg) +{ + setup_clear_cpu_cap(X86_FEATURE_CLFLSH); + return 1; +} +__setup("noclflush", setup_noclflush); + +void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) +{ + if (c->x86_model_id[0]) + printk(KERN_CONT "%s", c->x86_model_id); + + if (c->x86_mask || c->cpuid_level >= 0) + printk(KERN_CONT " stepping %02x\n", c->x86_mask); + else + printk(KERN_CONT "\n"); +} + +static __init int setup_disablecpuid(char *arg) +{ + int bit; + if (get_option(&arg, &bit) && bit < NCAPINTS*32) + setup_clear_cpu_cap(bit); + else + return 0; + return 1; +} +__setup("clearcpuid=", setup_disablecpuid); Index: linux-2.6/arch/x86/kernel/cpu/Makefile =================================================================== --- linux-2.6.orig/arch/x86/kernel/cpu/Makefile +++ linux-2.6/arch/x86/kernel/cpu/Makefile @@ -6,7 +6,7 @@ obj-y := intel_cacheinfo.o addon_cpuid obj-y += proc.o feature_names.o obj-$(CONFIG_X86_32) += common.o bugs.o -obj-$(CONFIG_X86_64) += bugs_64.o +obj-$(CONFIG_X86_64) += common_64.o bugs_64.o obj-$(CONFIG_X86_32) += amd.o obj-$(CONFIG_X86_64) += amd_64.o obj-$(CONFIG_X86_32) += cyrix.o Index: linux-2.6/include/asm-x86/processor.h =================================================================== --- linux-2.6.orig/include/asm-x86/processor.h +++ linux-2.6/include/asm-x86/processor.h @@ -154,6 +154,7 @@ static inline int hlt_works(int cpu) extern void cpu_detect(struct cpuinfo_x86 *c); +extern void early_cpu_init(void); extern void identify_cpu(struct cpuinfo_x86 *); extern void identify_boot_cpu(void); extern void identify_secondary_cpu(struct cpuinfo_x86 *); ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH] x86: merge setup64.c into common_64.c 2008-06-21 10:24 ` [PATCH] x86: seperate funcs from setup_64 to cpu common_64.c Yinghai Lu @ 2008-06-21 23:25 ` Yinghai Lu 2008-06-22 2:16 ` [PATCH] x86: remove two duplicated func in setup_32.c Yinghai Lu 1 sibling, 0 replies; 26+ messages in thread From: Yinghai Lu @ 2008-06-21 23:25 UTC (permalink / raw) To: Ingo Molnar, H. Peter Anvin, Thomas Gleixner; +Cc: linux-kernel@vger.kernel.org Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- arch/x86/kernel/Makefile | 2 arch/x86/kernel/cpu/common_64.c | 277 ++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/setup64.c | 287 ---------------------------------------- 3 files changed, 277 insertions(+), 289 deletions(-) Index: linux-2.6/arch/x86/kernel/setup64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup64.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * X86-64 specific CPU setup. - * Copyright (C) 1995 Linus Torvalds - * Copyright 2001, 2002, 2003 SuSE Labs / Andi Kleen. - * See setup.c for older changelog. - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/string.h> -#include <linux/bootmem.h> -#include <linux/bitops.h> -#include <linux/module.h> -#include <linux/kgdb.h> -#include <linux/topology.h> -#include <asm/pda.h> -#include <asm/pgtable.h> -#include <asm/processor.h> -#include <asm/desc.h> -#include <asm/atomic.h> -#include <asm/mmu_context.h> -#include <asm/smp.h> -#include <asm/i387.h> -#include <asm/percpu.h> -#include <asm/proto.h> -#include <asm/sections.h> -#include <asm/setup.h> -#include <asm/genapic.h> - -#ifndef CONFIG_DEBUG_BOOT_PARAMS -struct boot_params __initdata boot_params; -#else -struct boot_params boot_params; -#endif - -cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; - -struct x8664_pda **_cpu_pda __read_mostly; -EXPORT_SYMBOL(_cpu_pda); - -struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; - -char boot_cpu_stack[IRQSTACKSIZE] __page_aligned_bss; - -unsigned long __supported_pte_mask __read_mostly = ~0UL; -EXPORT_SYMBOL_GPL(__supported_pte_mask); - -static int do_not_nx __cpuinitdata = 0; - -/* noexec=on|off -Control non executable mappings for 64bit processes. - -on Enable(default) -off Disable -*/ -static int __init nonx_setup(char *str) -{ - if (!str) - return -EINVAL; - if (!strncmp(str, "on", 2)) { - __supported_pte_mask |= _PAGE_NX; - do_not_nx = 0; - } else if (!strncmp(str, "off", 3)) { - do_not_nx = 1; - __supported_pte_mask &= ~_PAGE_NX; - } - return 0; -} -early_param("noexec", nonx_setup); - -int force_personality32 = 0; - -/* noexec32=on|off -Control non executable heap for 32bit processes. -To control the stack too use noexec=off - -on PROT_READ does not imply PROT_EXEC for 32bit processes (default) -off PROT_READ implies PROT_EXEC -*/ -static int __init nonx32_setup(char *str) -{ - if (!strcmp(str, "on")) - force_personality32 &= ~READ_IMPLIES_EXEC; - else if (!strcmp(str, "off")) - force_personality32 |= READ_IMPLIES_EXEC; - return 1; -} -__setup("noexec32=", nonx32_setup); - -void pda_init(int cpu) -{ - struct x8664_pda *pda = cpu_pda(cpu); - - /* Setup up data that may be needed in __get_free_pages early */ - asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0)); - /* Memory clobbers used to order PDA accessed */ - mb(); - wrmsrl(MSR_GS_BASE, pda); - mb(); - - pda->cpunumber = cpu; - pda->irqcount = -1; - pda->kernelstack = - (unsigned long)stack_thread_info() - PDA_STACKOFFSET + THREAD_SIZE; - pda->active_mm = &init_mm; - pda->mmu_state = 0; - - if (cpu == 0) { - /* others are initialized in smpboot.c */ - pda->pcurrent = &init_task; - pda->irqstackptr = boot_cpu_stack; - } else { - pda->irqstackptr = (char *) - __get_free_pages(GFP_ATOMIC, IRQSTACK_ORDER); - if (!pda->irqstackptr) - panic("cannot allocate irqstack for cpu %d", cpu); - - if (pda->nodenumber == 0 && cpu_to_node(cpu) != NUMA_NO_NODE) - pda->nodenumber = cpu_to_node(cpu); - } - - pda->irqstackptr += IRQSTACKSIZE-64; -} - -char boot_exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ] -__attribute__((section(".bss.page_aligned"))); - -extern asmlinkage void ignore_sysret(void); - -/* May not be marked __init: used by software suspend */ -void syscall_init(void) -{ - /* - * LSTAR and STAR live in a bit strange symbiosis. - * They both write to the same internal register. STAR allows to set CS/DS - * but only a 32bit target. LSTAR sets the 64bit rip. - */ - wrmsrl(MSR_STAR, ((u64)__USER32_CS)<<48 | ((u64)__KERNEL_CS)<<32); - wrmsrl(MSR_LSTAR, system_call); - wrmsrl(MSR_CSTAR, ignore_sysret); - -#ifdef CONFIG_IA32_EMULATION - syscall32_cpu_init (); -#endif - - /* Flags to clear on syscall */ - wrmsrl(MSR_SYSCALL_MASK, - X86_EFLAGS_TF|X86_EFLAGS_DF|X86_EFLAGS_IF|X86_EFLAGS_IOPL); -} - -void __cpuinit check_efer(void) -{ - unsigned long efer; - - rdmsrl(MSR_EFER, efer); - if (!(efer & EFER_NX) || do_not_nx) { - __supported_pte_mask &= ~_PAGE_NX; - } -} - -unsigned long kernel_eflags; - -/* - * Copies of the original ist values from the tss are only accessed during - * debugging, no special alignment required. - */ -DEFINE_PER_CPU(struct orig_ist, orig_ist); - -/* - * cpu_init() initializes state that is per-CPU. Some data is already - * initialized (naturally) in the bootstrap process, such as the GDT - * and IDT. We reload them nevertheless, this function acts as a - * 'CPU state barrier', nothing should get across. - * A lot of state is already set up in PDA init. - */ -void __cpuinit cpu_init (void) -{ - int cpu = stack_smp_processor_id(); - struct tss_struct *t = &per_cpu(init_tss, cpu); - struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu); - unsigned long v; - char *estacks = NULL; - struct task_struct *me; - int i; - - /* CPU 0 is initialised in head64.c */ - if (cpu != 0) { - pda_init(cpu); - } else - estacks = boot_exception_stacks; - - me = current; - - if (cpu_test_and_set(cpu, cpu_initialized)) - panic("CPU#%d already initialized!\n", cpu); - - printk("Initializing CPU#%d\n", cpu); - - clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); - - /* - * Initialize the per-CPU GDT with the boot GDT, - * and set up the GDT descriptor: - */ - - switch_to_new_gdt(); - load_idt((const struct desc_ptr *)&idt_descr); - - memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8); - syscall_init(); - - wrmsrl(MSR_FS_BASE, 0); - wrmsrl(MSR_KERNEL_GS_BASE, 0); - barrier(); - - check_efer(); - - /* - * set up and load the per-CPU TSS - */ - for (v = 0; v < N_EXCEPTION_STACKS; v++) { - static const unsigned int order[N_EXCEPTION_STACKS] = { - [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER, - [DEBUG_STACK - 1] = DEBUG_STACK_ORDER - }; - if (cpu) { - estacks = (char *)__get_free_pages(GFP_ATOMIC, order[v]); - if (!estacks) - panic("Cannot allocate exception stack %ld %d\n", - v, cpu); - } - estacks += PAGE_SIZE << order[v]; - orig_ist->ist[v] = t->x86_tss.ist[v] = (unsigned long)estacks; - } - - t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap); - /* - * <= is required because the CPU will access up to - * 8 bits beyond the end of the IO permission bitmap. - */ - for (i = 0; i <= IO_BITMAP_LONGS; i++) - t->io_bitmap[i] = ~0UL; - - atomic_inc(&init_mm.mm_count); - me->active_mm = &init_mm; - if (me->mm) - BUG(); - enter_lazy_tlb(&init_mm, me); - - load_sp0(t, ¤t->thread); - set_tss_desc(cpu, t); - load_TR_desc(); - load_LDT(&init_mm.context); - -#ifdef CONFIG_KGDB - /* - * If the kgdb is connected no debug regs should be altered. This - * is only applicable when KGDB and a KGDB I/O module are built - * into the kernel and you are using early debugging with - * kgdbwait. KGDB will control the kernel HW breakpoint registers. - */ - if (kgdb_connected && arch_kgdb_ops.correct_hw_break) - arch_kgdb_ops.correct_hw_break(); - else { -#endif - /* - * Clear all 6 debug registers: - */ - - set_debugreg(0UL, 0); - set_debugreg(0UL, 1); - set_debugreg(0UL, 2); - set_debugreg(0UL, 3); - set_debugreg(0UL, 6); - set_debugreg(0UL, 7); -#ifdef CONFIG_KGDB - /* If the kgdb is connected no debug regs should be altered. */ - } -#endif - - fpu_init(); - - raw_local_save_flags(kernel_eflags); - - if (is_uv_system()) - uv_cpu_init(); -} Index: linux-2.6/arch/x86/kernel/Makefile =================================================================== --- linux-2.6.orig/arch/x86/kernel/Makefile +++ linux-2.6/arch/x86/kernel/Makefile @@ -30,7 +30,7 @@ obj-y += setup_$(BITS).o i8259.o irqin obj-$(CONFIG_X86_32) += probe_roms_32.o obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o -obj-$(CONFIG_X86_64) += syscall_64.o vsyscall_64.o setup64.o +obj-$(CONFIG_X86_64) += syscall_64.o vsyscall_64.o obj-y += bootflag.o e820.o obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o obj-y += alternative.o i8253.o pci-nommu.o Index: linux-2.6/arch/x86/kernel/cpu/common_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/cpu/common_64.c +++ linux-2.6/arch/x86/kernel/cpu/common_64.c @@ -1,10 +1,17 @@ #include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/string.h> +#include <linux/bootmem.h> +#include <linux/bitops.h> +#include <linux/module.h> +#include <linux/kgdb.h> +#include <linux/topology.h> #include <linux/string.h> #include <linux/delay.h> #include <linux/smp.h> #include <linux/module.h> #include <linux/percpu.h> -#include <linux/bootmem.h> #include <asm/processor.h> #include <asm/i387.h> #include <asm/msr.h> @@ -19,6 +26,15 @@ #include <asm/apic.h> #include <mach_apic.h> #endif +#include <asm/pda.h> +#include <asm/pgtable.h> +#include <asm/processor.h> +#include <asm/desc.h> +#include <asm/atomic.h> +#include <asm/proto.h> +#include <asm/sections.h> +#include <asm/setup.h> +#include <asm/genapic.h> #include "cpu.h" @@ -404,3 +420,262 @@ static __init int setup_disablecpuid(cha return 1; } __setup("clearcpuid=", setup_disablecpuid); + +#ifndef CONFIG_DEBUG_BOOT_PARAMS +struct boot_params __initdata boot_params; +#else +struct boot_params boot_params; +#endif + +cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; + +struct x8664_pda **_cpu_pda __read_mostly; +EXPORT_SYMBOL(_cpu_pda); + +struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; + +char boot_cpu_stack[IRQSTACKSIZE] __page_aligned_bss; + +unsigned long __supported_pte_mask __read_mostly = ~0UL; +EXPORT_SYMBOL_GPL(__supported_pte_mask); + +static int do_not_nx __cpuinitdata; + +/* noexec=on|off +Control non executable mappings for 64bit processes. + +on Enable(default) +off Disable +*/ +static int __init nonx_setup(char *str) +{ + if (!str) + return -EINVAL; + if (!strncmp(str, "on", 2)) { + __supported_pte_mask |= _PAGE_NX; + do_not_nx = 0; + } else if (!strncmp(str, "off", 3)) { + do_not_nx = 1; + __supported_pte_mask &= ~_PAGE_NX; + } + return 0; +} +early_param("noexec", nonx_setup); + +int force_personality32; + +/* noexec32=on|off +Control non executable heap for 32bit processes. +To control the stack too use noexec=off + +on PROT_READ does not imply PROT_EXEC for 32bit processes (default) +off PROT_READ implies PROT_EXEC +*/ +static int __init nonx32_setup(char *str) +{ + if (!strcmp(str, "on")) + force_personality32 &= ~READ_IMPLIES_EXEC; + else if (!strcmp(str, "off")) + force_personality32 |= READ_IMPLIES_EXEC; + return 1; +} +__setup("noexec32=", nonx32_setup); + +void pda_init(int cpu) +{ + struct x8664_pda *pda = cpu_pda(cpu); + + /* Setup up data that may be needed in __get_free_pages early */ + asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0)); + /* Memory clobbers used to order PDA accessed */ + mb(); + wrmsrl(MSR_GS_BASE, pda); + mb(); + + pda->cpunumber = cpu; + pda->irqcount = -1; + pda->kernelstack = (unsigned long)stack_thread_info() - + PDA_STACKOFFSET + THREAD_SIZE; + pda->active_mm = &init_mm; + pda->mmu_state = 0; + + if (cpu == 0) { + /* others are initialized in smpboot.c */ + pda->pcurrent = &init_task; + pda->irqstackptr = boot_cpu_stack; + } else { + pda->irqstackptr = (char *) + __get_free_pages(GFP_ATOMIC, IRQSTACK_ORDER); + if (!pda->irqstackptr) + panic("cannot allocate irqstack for cpu %d", cpu); + + if (pda->nodenumber == 0 && cpu_to_node(cpu) != NUMA_NO_NODE) + pda->nodenumber = cpu_to_node(cpu); + } + + pda->irqstackptr += IRQSTACKSIZE-64; +} + +char boot_exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + + DEBUG_STKSZ] +__attribute__((section(".bss.page_aligned"))); + +extern asmlinkage void ignore_sysret(void); + +/* May not be marked __init: used by software suspend */ +void syscall_init(void) +{ + /* + * LSTAR and STAR live in a bit strange symbiosis. + * They both write to the same internal register. STAR allows to + * set CS/DS but only a 32bit target. LSTAR sets the 64bit rip. + */ + wrmsrl(MSR_STAR, ((u64)__USER32_CS)<<48 | ((u64)__KERNEL_CS)<<32); + wrmsrl(MSR_LSTAR, system_call); + wrmsrl(MSR_CSTAR, ignore_sysret); + +#ifdef CONFIG_IA32_EMULATION + syscall32_cpu_init(); +#endif + + /* Flags to clear on syscall */ + wrmsrl(MSR_SYSCALL_MASK, + X86_EFLAGS_TF|X86_EFLAGS_DF|X86_EFLAGS_IF|X86_EFLAGS_IOPL); +} + +void __cpuinit check_efer(void) +{ + unsigned long efer; + + rdmsrl(MSR_EFER, efer); + if (!(efer & EFER_NX) || do_not_nx) + __supported_pte_mask &= ~_PAGE_NX; +} + +unsigned long kernel_eflags; + +/* + * Copies of the original ist values from the tss are only accessed during + * debugging, no special alignment required. + */ +DEFINE_PER_CPU(struct orig_ist, orig_ist); + +/* + * cpu_init() initializes state that is per-CPU. Some data is already + * initialized (naturally) in the bootstrap process, such as the GDT + * and IDT. We reload them nevertheless, this function acts as a + * 'CPU state barrier', nothing should get across. + * A lot of state is already set up in PDA init. + */ +void __cpuinit cpu_init(void) +{ + int cpu = stack_smp_processor_id(); + struct tss_struct *t = &per_cpu(init_tss, cpu); + struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu); + unsigned long v; + char *estacks = NULL; + struct task_struct *me; + int i; + + /* CPU 0 is initialised in head64.c */ + if (cpu != 0) + pda_init(cpu); + else + estacks = boot_exception_stacks; + + me = current; + + if (cpu_test_and_set(cpu, cpu_initialized)) + panic("CPU#%d already initialized!\n", cpu); + + printk(KERN_INFO "Initializing CPU#%d\n", cpu); + + clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); + + /* + * Initialize the per-CPU GDT with the boot GDT, + * and set up the GDT descriptor: + */ + + switch_to_new_gdt(); + load_idt((const struct desc_ptr *)&idt_descr); + + memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8); + syscall_init(); + + wrmsrl(MSR_FS_BASE, 0); + wrmsrl(MSR_KERNEL_GS_BASE, 0); + barrier(); + + check_efer(); + + /* + * set up and load the per-CPU TSS + */ + for (v = 0; v < N_EXCEPTION_STACKS; v++) { + static const unsigned int order[N_EXCEPTION_STACKS] = { + [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER, + [DEBUG_STACK - 1] = DEBUG_STACK_ORDER + }; + if (cpu) { + estacks = (char *)__get_free_pages(GFP_ATOMIC, order[v]); + if (!estacks) + panic("Cannot allocate exception stack %ld %d\n", + v, cpu); + } + estacks += PAGE_SIZE << order[v]; + orig_ist->ist[v] = t->x86_tss.ist[v] = (unsigned long)estacks; + } + + t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap); + /* + * <= is required because the CPU will access up to + * 8 bits beyond the end of the IO permission bitmap. + */ + for (i = 0; i <= IO_BITMAP_LONGS; i++) + t->io_bitmap[i] = ~0UL; + + atomic_inc(&init_mm.mm_count); + me->active_mm = &init_mm; + if (me->mm) + BUG(); + enter_lazy_tlb(&init_mm, me); + + load_sp0(t, ¤t->thread); + set_tss_desc(cpu, t); + load_TR_desc(); + load_LDT(&init_mm.context); + +#ifdef CONFIG_KGDB + /* + * If the kgdb is connected no debug regs should be altered. This + * is only applicable when KGDB and a KGDB I/O module are built + * into the kernel and you are using early debugging with + * kgdbwait. KGDB will control the kernel HW breakpoint registers. + */ + if (kgdb_connected && arch_kgdb_ops.correct_hw_break) + arch_kgdb_ops.correct_hw_break(); + else { +#endif + /* + * Clear all 6 debug registers: + */ + + set_debugreg(0UL, 0); + set_debugreg(0UL, 1); + set_debugreg(0UL, 2); + set_debugreg(0UL, 3); + set_debugreg(0UL, 6); + set_debugreg(0UL, 7); +#ifdef CONFIG_KGDB + /* If the kgdb is connected no debug regs should be altered. */ + } +#endif + + fpu_init(); + + raw_local_save_flags(kernel_eflags); + + if (is_uv_system()) + uv_cpu_init(); +} ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH] x86: remove two duplicated func in setup_32.c 2008-06-21 10:24 ` [PATCH] x86: seperate funcs from setup_64 to cpu common_64.c Yinghai Lu 2008-06-21 23:25 ` [PATCH] x86: merge setup64.c into common_64.c Yinghai Lu @ 2008-06-22 2:16 ` Yinghai Lu 2008-06-22 3:22 ` [PATCH] x86: move reserve_standard_io_resource to setup.c Yinghai Lu 1 sibling, 1 reply; 26+ messages in thread From: Yinghai Lu @ 2008-06-22 2:16 UTC (permalink / raw) To: Ingo Molnar, H. Peter Anvin, Thomas Gleixner; +Cc: linux-kernel@vger.kernel.org early_cpu_init is declcared in processor.h memory_setup is defined in e820.c Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- a/arch/x86/kernel/setup_32.c 2008-06-21 17:17:02.000000000 -0700 +++ b/arch/x86/kernel/setup_32.c 2008-06-21 17:17:51.000000000 -0700 @@ -207,7 +207,6 @@ struct ist_info ist_info; EXPORT_SYMBOL(ist_info); #endif -extern void early_cpu_init(void); extern int root_mountflags; unsigned long saved_video_mode; @@ -607,12 +606,6 @@ static void set_mca_bus(int x) static void set_mca_bus(int x) { } #endif -/* Overridden in paravirt.c if CONFIG_PARAVIRT */ -char * __init __attribute__((weak)) memory_setup(void) -{ - return machine_specific_memory_setup(); -} - /* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH] x86: move reserve_standard_io_resource to setup.c 2008-06-22 2:16 ` [PATCH] x86: remove two duplicated func in setup_32.c Yinghai Lu @ 2008-06-22 3:22 ` Yinghai Lu 2008-06-22 4:02 ` [PATCH] x86: move elfcorehdr parsing " Yinghai Lu 0 siblings, 1 reply; 26+ messages in thread From: Yinghai Lu @ 2008-06-22 3:22 UTC (permalink / raw) To: Ingo Molnar, H. Peter Anvin, Thomas Gleixner; +Cc: linux-kernel@vger.kernel.org Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- arch/x86/kernel/setup.c | 33 ++++++++++++++++++++++++++ arch/x86/kernel/setup_32.c | 57 --------------------------------------------- arch/x86/kernel/setup_64.c | 29 ---------------------- include/asm-x86/setup.h | 2 + 4 files changed, 37 insertions(+), 84 deletions(-) Index: linux-2.6/arch/x86/kernel/setup_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup_64.c +++ linux-2.6/arch/x86/kernel/setup_64.c @@ -110,29 +110,6 @@ extern int root_mountflags; static char __initdata command_line[COMMAND_LINE_SIZE]; -static struct resource standard_io_resources[] = { - { .name = "dma1", .start = 0x00, .end = 0x1f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO }, - { .name = "pic1", .start = 0x20, .end = 0x21, - .flags = IORESOURCE_BUSY | IORESOURCE_IO }, - { .name = "timer0", .start = 0x40, .end = 0x43, - .flags = IORESOURCE_BUSY | IORESOURCE_IO }, - { .name = "timer1", .start = 0x50, .end = 0x53, - .flags = IORESOURCE_BUSY | IORESOURCE_IO }, - { .name = "keyboard", .start = 0x60, .end = 0x60, - .flags = IORESOURCE_BUSY | IORESOURCE_IO }, - { .name = "keyboard", .start = 0x64, .end = 0x64, - .flags = IORESOURCE_BUSY | IORESOURCE_IO }, - { .name = "dma page reg", .start = 0x80, .end = 0x8f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO }, - { .name = "pic2", .start = 0xa0, .end = 0xa1, - .flags = IORESOURCE_BUSY | IORESOURCE_IO }, - { .name = "dma2", .start = 0xc0, .end = 0xdf, - .flags = IORESOURCE_BUSY | IORESOURCE_IO }, - { .name = "fpu", .start = 0xf0, .end = 0xff, - .flags = IORESOURCE_BUSY | IORESOURCE_IO } -}; - #define IORESOURCE_RAM (IORESOURCE_BUSY | IORESOURCE_MEM) static struct resource data_resource = { @@ -220,8 +197,6 @@ static inline void copy_edd(void) */ void __init setup_arch(char **cmdline_p) { - unsigned i; - printk(KERN_INFO "Command line: %s\n", boot_command_line); ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev); @@ -430,9 +405,7 @@ void __init setup_arch(char **cmdline_p) e820_reserve_resources(); e820_mark_nosave_regions(end_pfn); - /* request I/O space for devices used on all i[345]86 PCs */ - for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) - request_resource(&ioport_resource, &standard_io_resources[i]); + reserve_standard_io_resources(); e820_setup_gap(); Index: linux-2.6/arch/x86/kernel/setup_32.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup_32.c +++ linux-2.6/arch/x86/kernel/setup_32.c @@ -109,58 +109,6 @@ static struct resource video_ram_resourc .flags = IORESOURCE_BUSY | IORESOURCE_MEM }; -static struct resource standard_io_resources[] = { { - .name = "dma1", - .start = 0x0000, - .end = 0x001f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "pic1", - .start = 0x0020, - .end = 0x0021, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "timer0", - .start = 0x0040, - .end = 0x0043, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "timer1", - .start = 0x0050, - .end = 0x0053, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "keyboard", - .start = 0x0060, - .end = 0x0060, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "keyboard", - .start = 0x0064, - .end = 0x0064, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "dma page reg", - .start = 0x0080, - .end = 0x008f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "pic2", - .start = 0x00a0, - .end = 0x00a1, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "dma2", - .start = 0x00c0, - .end = 0x00df, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "fpu", - .start = 0x00f0, - .end = 0x00ff, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -} }; - /* cpu data as detected by the assembly code in head.S */ struct cpuinfo_x86 new_cpu_data __cpuinitdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; /* common cpu data for all cpus */ @@ -615,7 +563,6 @@ static void set_mca_bus(int x) { } */ void __init setup_arch(char **cmdline_p) { - int i; unsigned long max_low_pfn; memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); @@ -830,9 +777,7 @@ void __init setup_arch(char **cmdline_p) e820_mark_nosave_regions(max_low_pfn); request_resource(&iomem_resource, &video_ram_resource); - /* request I/O space for devices used on all i[345]86 PCs */ - for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) - request_resource(&ioport_resource, &standard_io_resources[i]); + reserve_standard_io_resources(); e820_setup_gap(); Index: linux-2.6/arch/x86/kernel/setup.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup.c +++ linux-2.6/arch/x86/kernel/setup.c @@ -467,3 +467,36 @@ void __init reserve_crashkernel(void) void __init reserve_crashkernel(void) {} #endif + +static struct resource standard_io_resources[] = { + { .name = "dma1", .start = 0x00, .end = 0x1f, + .flags = IORESOURCE_BUSY | IORESOURCE_IO }, + { .name = "pic1", .start = 0x20, .end = 0x21, + .flags = IORESOURCE_BUSY | IORESOURCE_IO }, + { .name = "timer0", .start = 0x40, .end = 0x43, + .flags = IORESOURCE_BUSY | IORESOURCE_IO }, + { .name = "timer1", .start = 0x50, .end = 0x53, + .flags = IORESOURCE_BUSY | IORESOURCE_IO }, + { .name = "keyboard", .start = 0x60, .end = 0x60, + .flags = IORESOURCE_BUSY | IORESOURCE_IO }, + { .name = "keyboard", .start = 0x64, .end = 0x64, + .flags = IORESOURCE_BUSY | IORESOURCE_IO }, + { .name = "dma page reg", .start = 0x80, .end = 0x8f, + .flags = IORESOURCE_BUSY | IORESOURCE_IO }, + { .name = "pic2", .start = 0xa0, .end = 0xa1, + .flags = IORESOURCE_BUSY | IORESOURCE_IO }, + { .name = "dma2", .start = 0xc0, .end = 0xdf, + .flags = IORESOURCE_BUSY | IORESOURCE_IO }, + { .name = "fpu", .start = 0xf0, .end = 0xff, + .flags = IORESOURCE_BUSY | IORESOURCE_IO } +}; + +void __init reserve_standard_io_resources(void) +{ + int i; + + /* request I/O space for devices used on all i[345]86 PCs */ + for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) + request_resource(&ioport_resource, &standard_io_resources[i]); + +} Index: linux-2.6/include/asm-x86/setup.h =================================================================== --- linux-2.6.orig/include/asm-x86/setup.h +++ linux-2.6/include/asm-x86/setup.h @@ -38,6 +38,8 @@ void reserve_crashkernel(void); #ifndef __ASSEMBLY__ #include <asm/bootparam.h> +void reserve_standard_io_resources(void); + #ifndef _SETUP /* ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH] x86: move elfcorehdr parsing to setup.c 2008-06-22 3:22 ` [PATCH] x86: move reserve_standard_io_resource to setup.c Yinghai Lu @ 2008-06-22 4:02 ` Yinghai Lu 2008-06-22 9:44 ` [PATCH] x86: introduce initmem_init for 64 bit Yinghai Lu 0 siblings, 1 reply; 26+ messages in thread From: Yinghai Lu @ 2008-06-22 4:02 UTC (permalink / raw) To: Ingo Molnar, H. Peter Anvin, Thomas Gleixner; +Cc: linux-kernel@vger.kernel.org Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- arch/x86/kernel/setup.c | 19 +++++++++++++++++++ arch/x86/kernel/setup_32.c | 16 ---------------- arch/x86/kernel/setup_64.c | 17 ----------------- 3 files changed, 19 insertions(+), 33 deletions(-) Index: linux-2.6/arch/x86/kernel/setup_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup_64.c +++ linux-2.6/arch/x86/kernel/setup_64.c @@ -26,7 +26,6 @@ #include <asm/processor.h> #include <linux/console.h> #include <linux/seq_file.h> -#include <linux/crash_dump.h> #include <linux/root_dev.h> #include <linux/pci.h> #include <asm/pci-direct.h> @@ -131,22 +130,6 @@ static struct resource bss_resource = { .flags = IORESOURCE_RAM, }; -#ifdef CONFIG_PROC_VMCORE -/* elfcorehdr= specifies the location of elf core header - * stored by the crashed kernel. This option will be passed - * by kexec loader to the capture kernel. - */ -static int __init setup_elfcorehdr(char *arg) -{ - char *end; - if (!arg) - return -EINVAL; - elfcorehdr_addr = memparse(arg, &end); - return end > arg ? 0 : -EINVAL; -} -early_param("elfcorehdr", setup_elfcorehdr); -#endif - #ifndef CONFIG_NUMA static void __init contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn) Index: linux-2.6/arch/x86/kernel/setup_32.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup_32.c +++ linux-2.6/arch/x86/kernel/setup_32.c @@ -42,7 +42,6 @@ #include <linux/iscsi_ibft.h> #include <linux/nodemask.h> #include <linux/kexec.h> -#include <linux/crash_dump.h> #include <linux/dmi.h> #include <linux/pfn.h> #include <linux/pci.h> @@ -195,21 +194,6 @@ static inline void copy_edd(void) } #endif -#ifdef CONFIG_PROC_VMCORE -/* elfcorehdr= specifies the location of elf core header - * stored by the crashed kernel. - */ -static int __init parse_elfcorehdr(char *arg) -{ - if (!arg) - return -EINVAL; - - elfcorehdr_addr = memparse(arg, &arg); - return 0; -} -early_param("elfcorehdr", parse_elfcorehdr); -#endif /* CONFIG_PROC_VMCORE */ - /* * highmem=size forces highmem to be exactly 'size' bytes. * This works even on boxes that have no highmem otherwise. Index: linux-2.6/arch/x86/kernel/setup.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup.c +++ linux-2.6/arch/x86/kernel/setup.c @@ -4,6 +4,7 @@ #include <linux/bootmem.h> #include <linux/percpu.h> #include <linux/kexec.h> +#include <linux/crash_dump.h> #include <asm/smp.h> #include <asm/percpu.h> #include <asm/sections.h> @@ -500,3 +501,21 @@ void __init reserve_standard_io_resource request_resource(&ioport_resource, &standard_io_resources[i]); } + +#ifdef CONFIG_PROC_VMCORE +/* elfcorehdr= specifies the location of elf core header + * stored by the crashed kernel. This option will be passed + * by kexec loader to the capture kernel. + */ +static int __init setup_elfcorehdr(char *arg) +{ + char *end; + if (!arg) + return -EINVAL; + elfcorehdr_addr = memparse(arg, &end); + return end > arg ? 0 : -EINVAL; +} +early_param("elfcorehdr", setup_elfcorehdr); +#endif + + ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH] x86: introduce initmem_init for 64 bit 2008-06-22 4:02 ` [PATCH] x86: move elfcorehdr parsing " Yinghai Lu @ 2008-06-22 9:44 ` Yinghai Lu 2008-06-22 9:45 ` [PATCH] x86: introduce initmem_init for 32 bit Yinghai Lu 0 siblings, 1 reply; 26+ messages in thread From: Yinghai Lu @ 2008-06-22 9:44 UTC (permalink / raw) To: Ingo Molnar, H. Peter Anvin, Thomas Gleixner; +Cc: linux-kernel@vger.kernel.org Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- arch/x86/kernel/setup_64.c | 25 +------------------------ arch/x86/mm/init_64.c | 16 ++++++++++++++++ arch/x86/mm/numa_64.c | 2 +- include/asm-x86/numa_64.h | 1 - include/asm-x86/page_64.h | 1 + 5 files changed, 19 insertions(+), 26 deletions(-) Index: linux-2.6/arch/x86/kernel/setup_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup_64.c +++ linux-2.6/arch/x86/kernel/setup_64.c @@ -130,25 +130,6 @@ static struct resource bss_resource = { .flags = IORESOURCE_RAM, }; -#ifndef CONFIG_NUMA -static void __init -contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn) -{ - unsigned long bootmap_size, bootmap; - - bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT; - bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size, - PAGE_SIZE); - if (bootmap == -1L) - panic("Cannot find bootmem map of size %ld\n", bootmap_size); - bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn); - e820_register_active_regions(0, start_pfn, end_pfn); - free_bootmem_with_active_regions(0, end_pfn); - early_res_to_bootmem(0, end_pfn<<PAGE_SHIFT); - reserve_bootmem(bootmap, bootmap_size, BOOTMEM_DEFAULT); -} -#endif - #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) struct edd edd; #ifdef CONFIG_EDD_MODULE @@ -309,11 +290,7 @@ void __init setup_arch(char **cmdline_p) acpi_numa_init(); #endif -#ifdef CONFIG_NUMA - numa_initmem_init(0, end_pfn); -#else - contig_initmem_init(0, end_pfn); -#endif + initmem_init(0, end_pfn); dma32_reserve_bootmem(); Index: linux-2.6/arch/x86/mm/init_64.c =================================================================== --- linux-2.6.orig/arch/x86/mm/init_64.c +++ linux-2.6/arch/x86/mm/init_64.c @@ -624,6 +624,22 @@ unsigned long __init_refok init_memory_m } #ifndef CONFIG_NUMA +void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn) +{ + unsigned long bootmap_size, bootmap; + + bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT; + bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size, + PAGE_SIZE); + if (bootmap == -1L) + panic("Cannot find bootmem map of size %ld\n", bootmap_size); + bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn); + e820_register_active_regions(0, start_pfn, end_pfn); + free_bootmem_with_active_regions(0, end_pfn); + early_res_to_bootmem(0, end_pfn<<PAGE_SHIFT); + reserve_bootmem(bootmap, bootmap_size, BOOTMEM_DEFAULT); +} + void __init paging_init(void) { unsigned long max_zone_pfns[MAX_NR_ZONES]; Index: linux-2.6/arch/x86/mm/numa_64.c =================================================================== --- linux-2.6.orig/arch/x86/mm/numa_64.c +++ linux-2.6/arch/x86/mm/numa_64.c @@ -514,7 +514,7 @@ out: } #endif /* CONFIG_NUMA_EMU */ -void __init numa_initmem_init(unsigned long start_pfn, unsigned long last_pfn) +void __init initmem_init(unsigned long start_pfn, unsigned long last_pfn) { int i; Index: linux-2.6/include/asm-x86/numa_64.h =================================================================== --- linux-2.6.orig/include/asm-x86/numa_64.h +++ linux-2.6/include/asm-x86/numa_64.h @@ -22,7 +22,6 @@ extern int hotadd_percent; extern s16 apicid_to_node[MAX_LOCAL_APIC]; -extern void numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn); extern unsigned long numa_free_all_bootmem(void); extern void setup_node_bootmem(int nodeid, unsigned long start, unsigned long end); Index: linux-2.6/include/asm-x86/page_64.h =================================================================== --- linux-2.6.orig/include/asm-x86/page_64.h +++ linux-2.6/include/asm-x86/page_64.h @@ -83,6 +83,7 @@ typedef struct { pteval_t pte; } pte_t; extern unsigned long init_memory_mapping(unsigned long start, unsigned long end); +extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn); #endif /* !__ASSEMBLY__ */ #ifdef CONFIG_FLATMEM ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH] x86: introduce initmem_init for 32 bit 2008-06-22 9:44 ` [PATCH] x86: introduce initmem_init for 64 bit Yinghai Lu @ 2008-06-22 9:45 ` Yinghai Lu 2008-06-22 9:46 ` [PATCH] x86: introduce reserve_initrd Yinghai Lu 0 siblings, 1 reply; 26+ messages in thread From: Yinghai Lu @ 2008-06-22 9:45 UTC (permalink / raw) To: Ingo Molnar, H. Peter Anvin, Thomas Gleixner; +Cc: linux-kernel@vger.kernel.org Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- arch/x86/kernel/setup_32.c | 94 --------------------------------------------- arch/x86/mm/discontig_32.c | 4 - arch/x86/mm/init_32.c | 90 +++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/page_32.h | 5 ++ 4 files changed, 99 insertions(+), 94 deletions(-) Index: linux-2.6/arch/x86/kernel/setup_32.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup_32.c +++ linux-2.6/arch/x86/kernel/setup_32.c @@ -301,71 +301,11 @@ unsigned long __init find_max_low_pfn(vo return max_low_pfn; } -#ifndef CONFIG_NEED_MULTIPLE_NODES -static void __init setup_bootmem_allocator(void); -static unsigned long __init setup_memory(void) -{ - /* - * partially used pages are not usable - thus - * we are rounding upwards: - */ - min_low_pfn = PFN_UP(init_pg_tables_end); - - max_low_pfn = find_max_low_pfn(); - -#ifdef CONFIG_HIGHMEM - highstart_pfn = highend_pfn = max_pfn; - if (max_pfn > max_low_pfn) { - highstart_pfn = max_low_pfn; - } - memory_present(0, 0, highend_pfn); - printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", - pages_to_mb(highend_pfn - highstart_pfn)); - num_physpages = highend_pfn; - high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1; -#else - memory_present(0, 0, max_low_pfn); - num_physpages = max_low_pfn; - high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1; -#endif -#ifdef CONFIG_FLATMEM - max_mapnr = num_physpages; -#endif - printk(KERN_NOTICE "%ldMB LOWMEM available.\n", - pages_to_mb(max_low_pfn)); - - setup_bootmem_allocator(); - - return max_low_pfn; -} - -static void __init zone_sizes_init(void) -{ - unsigned long max_zone_pfns[MAX_NR_ZONES]; - memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); - max_zone_pfns[ZONE_DMA] = - virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; - max_zone_pfns[ZONE_NORMAL] = max_low_pfn; - remove_all_active_ranges(); -#ifdef CONFIG_HIGHMEM - max_zone_pfns[ZONE_HIGHMEM] = highend_pfn; - e820_register_active_regions(0, 0, highend_pfn); -#else - e820_register_active_regions(0, 0, max_low_pfn); -#endif - - free_area_init_nodes(max_zone_pfns); -} -#else -extern unsigned long __init setup_memory(void); -extern void zone_sizes_init(void); -#endif /* !CONFIG_NEED_MULTIPLE_NODES */ - #ifdef CONFIG_BLK_DEV_INITRD static bool do_relocate_initrd = false; -static void __init reserve_initrd(void) +void __init reserve_initrd(void) { u64 ramdisk_image = boot_params.hdr.ramdisk_image; u64 ramdisk_size = boot_params.hdr.ramdisk_size; @@ -481,36 +421,6 @@ static void __init relocate_initrd(void) #endif /* CONFIG_BLK_DEV_INITRD */ -void __init setup_bootmem_allocator(void) -{ - int i; - unsigned long bootmap_size, bootmap; - /* - * Initialize the boot-time allocator (with low memory only): - */ - bootmap_size = bootmem_bootmap_pages(max_low_pfn)<<PAGE_SHIFT; - bootmap = find_e820_area(min_low_pfn<<PAGE_SHIFT, - max_pfn_mapped<<PAGE_SHIFT, bootmap_size, - PAGE_SIZE); - if (bootmap == -1L) - panic("Cannot find bootmem map of size %ld\n", bootmap_size); - reserve_early(bootmap, bootmap + bootmap_size, "BOOTMAP"); -#ifdef CONFIG_BLK_DEV_INITRD - reserve_initrd(); -#endif - bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, max_low_pfn); - printk(KERN_INFO " mapped low ram: 0 - %08lx\n", - max_pfn_mapped<<PAGE_SHIFT); - printk(KERN_INFO " low ram: %08lx - %08lx\n", - min_low_pfn<<PAGE_SHIFT, max_low_pfn<<PAGE_SHIFT); - printk(KERN_INFO " bootmap %08lx - %08lx\n", - bootmap, bootmap + bootmap_size); - for_each_online_node(i) - free_bootmem_with_active_regions(i, max_low_pfn); - early_res_to_bootmem(0, max_low_pfn<<PAGE_SHIFT); - -} - /* * The node 0 pgdat is initialized before all of these because * it's needed for bootmem. node>0 pgdats have their virtual @@ -672,7 +582,7 @@ void __init setup_arch(char **cmdline_p) acpi_numa_init(); #endif - max_low_pfn = setup_memory(); + max_low_pfn = initmem_init(0, max_pfn); #ifdef CONFIG_ACPI_SLEEP /* Index: linux-2.6/arch/x86/mm/discontig_32.c =================================================================== --- linux-2.6.orig/arch/x86/mm/discontig_32.c +++ linux-2.6/arch/x86/mm/discontig_32.c @@ -309,8 +309,8 @@ static void init_remap_allocator(int nid (ulong) node_remap_end_vaddr[nid]); } -extern void setup_bootmem_allocator(void); -unsigned long __init setup_memory(void) +unsigned long __init initmem_init(unsigned long start_pfn, + unsigned long end_pfn) { int nid; unsigned long system_start_pfn, system_max_low_pfn; Index: linux-2.6/arch/x86/mm/init_32.c =================================================================== --- linux-2.6.orig/arch/x86/mm/init_32.c +++ linux-2.6/arch/x86/mm/init_32.c @@ -540,6 +540,96 @@ static void __init set_nx(void) } #endif +#ifndef CONFIG_NEED_MULTIPLE_NODES +extern unsigned long find_max_low_pfn(void); +unsigned long __init initmem_init(unsigned long start_pfn, + unsigned long end_pfn) +{ + /* + * partially used pages are not usable - thus + * we are rounding upwards: + */ + min_low_pfn = PFN_UP(init_pg_tables_end); + + max_low_pfn = find_max_low_pfn(); + +#ifdef CONFIG_HIGHMEM + highstart_pfn = highend_pfn = max_pfn; + if (max_pfn > max_low_pfn) + highstart_pfn = max_low_pfn; + memory_present(0, 0, highend_pfn); + printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", + pages_to_mb(highend_pfn - highstart_pfn)); + num_physpages = highend_pfn; + high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1; +#else + memory_present(0, 0, max_low_pfn); + num_physpages = max_low_pfn; + high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1; +#endif +#ifdef CONFIG_FLATMEM + max_mapnr = num_physpages; +#endif + printk(KERN_NOTICE "%ldMB LOWMEM available.\n", + pages_to_mb(max_low_pfn)); + + setup_bootmem_allocator(); + + return max_low_pfn; +} + +void __init zone_sizes_init(void) +{ + unsigned long max_zone_pfns[MAX_NR_ZONES]; + memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); + max_zone_pfns[ZONE_DMA] = + virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; + max_zone_pfns[ZONE_NORMAL] = max_low_pfn; + remove_all_active_ranges(); +#ifdef CONFIG_HIGHMEM + max_zone_pfns[ZONE_HIGHMEM] = highend_pfn; + e820_register_active_regions(0, 0, highend_pfn); +#else + e820_register_active_regions(0, 0, max_low_pfn); +#endif + + free_area_init_nodes(max_zone_pfns); +} +#endif /* !CONFIG_NEED_MULTIPLE_NODES */ + +extern void reserve_initrd(void); + +void __init setup_bootmem_allocator(void) +{ + int i; + unsigned long bootmap_size, bootmap; + /* + * Initialize the boot-time allocator (with low memory only): + */ + bootmap_size = bootmem_bootmap_pages(max_low_pfn)<<PAGE_SHIFT; + bootmap = find_e820_area(min_low_pfn<<PAGE_SHIFT, + max_pfn_mapped<<PAGE_SHIFT, bootmap_size, + PAGE_SIZE); + if (bootmap == -1L) + panic("Cannot find bootmem map of size %ld\n", bootmap_size); + reserve_early(bootmap, bootmap + bootmap_size, "BOOTMAP"); +#ifdef CONFIG_BLK_DEV_INITRD + reserve_initrd(); +#endif + bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, max_low_pfn); + printk(KERN_INFO " mapped low ram: 0 - %08lx\n", + max_pfn_mapped<<PAGE_SHIFT); + printk(KERN_INFO " low ram: %08lx - %08lx\n", + min_low_pfn<<PAGE_SHIFT, max_low_pfn<<PAGE_SHIFT); + printk(KERN_INFO " bootmap %08lx - %08lx\n", + bootmap, bootmap + bootmap_size); + for_each_online_node(i) + free_bootmem_with_active_regions(i, max_low_pfn); + early_res_to_bootmem(0, max_low_pfn<<PAGE_SHIFT); + +} + + /* * paging_init() sets up the page tables - note that the first 8MB are * already mapped by head.S. Index: linux-2.6/include/asm-x86/page_32.h =================================================================== --- linux-2.6.orig/include/asm-x86/page_32.h +++ linux-2.6/include/asm-x86/page_32.h @@ -97,6 +97,11 @@ extern int sysctl_legacy_va_layout; #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE) #define MAXMEM (-__PAGE_OFFSET - __VMALLOC_RESERVE) +extern unsigned long initmem_init(unsigned long, unsigned long); +extern void zone_sizes_init(void); +extern void setup_bootmem_allocator(void); + + #ifdef CONFIG_X86_USE_3DNOW #include <asm/mmx.h> ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH] x86: introduce reserve_initrd 2008-06-22 9:45 ` [PATCH] x86: introduce initmem_init for 32 bit Yinghai Lu @ 2008-06-22 9:46 ` Yinghai Lu 2008-06-23 0:37 ` [PATCH] x86: move boot_params declaring to setup.c Yinghai Lu ` (5 more replies) 0 siblings, 6 replies; 26+ messages in thread From: Yinghai Lu @ 2008-06-22 9:46 UTC (permalink / raw) To: Ingo Molnar, H. Peter Anvin, Thomas Gleixner; +Cc: linux-kernel@vger.kernel.org Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- arch/x86/kernel/setup_32.c | 16 ++++++++----- arch/x86/kernel/setup_64.c | 53 ++++++++++++++++++++++++--------------------- arch/x86/mm/init_32.c | 6 +---- include/asm-x86/setup.h | 2 + 4 files changed, 43 insertions(+), 34 deletions(-) Index: linux-2.6/arch/x86/kernel/setup_32.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup_32.c +++ linux-2.6/arch/x86/kernel/setup_32.c @@ -337,7 +337,7 @@ void __init reserve_initrd(void) * in i386_start_kernel */ initrd_start = ramdisk_image + PAGE_OFFSET; - initrd_end = initrd_start+ramdisk_size; + initrd_end = initrd_start + ramdisk_size; return; } @@ -364,7 +364,7 @@ void __init reserve_initrd(void) #define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT) -static void __init relocate_initrd(void) +static void __init post_reserve_initrd(void) { u64 ramdisk_image = boot_params.hdr.ramdisk_image; u64 ramdisk_size = boot_params.hdr.ramdisk_size; @@ -418,7 +418,13 @@ static void __init relocate_initrd(void) /* need to free that, otherwise init highmem will reserve it again */ free_early(ramdisk_image, ramdisk_image+ramdisk_size); } - +#else +void __init reserve_initrd(void) +{ +} +static void __init post_reserve_initrd(void) +{ +} #endif /* CONFIG_BLK_DEV_INITRD */ /* @@ -638,9 +644,7 @@ void __init setup_arch(char **cmdline_p) * NOTE: at this point the bootmem allocator is fully available. */ -#ifdef CONFIG_BLK_DEV_INITRD - relocate_initrd(); -#endif + post_reserve_initrd(); remapped_pgdat_init(); sparse_init(); Index: linux-2.6/arch/x86/kernel/setup_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup_64.c +++ linux-2.6/arch/x86/kernel/setup_64.c @@ -154,6 +154,33 @@ static inline void copy_edd(void) } #endif +void __init reserve_initrd(void) +{ +#ifdef CONFIG_BLK_DEV_INITRD + if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { + unsigned long ramdisk_image = boot_params.hdr.ramdisk_image; + unsigned long ramdisk_size = boot_params.hdr.ramdisk_size; + unsigned long ramdisk_end = ramdisk_image + ramdisk_size; + unsigned long end_of_mem = end_pfn << PAGE_SHIFT; + + if (ramdisk_end <= end_of_mem) { + /* + * don't need to reserve again, already reserved early + * in x86_64_start_kernel, and early_res_to_bootmem + * will convert that to reserved in bootmem + */ + initrd_start = ramdisk_image + PAGE_OFFSET; + initrd_end = initrd_start+ramdisk_size; + } else { + free_early(ramdisk_image, ramdisk_end); + printk(KERN_ERR "initrd extends beyond end of memory " + "(0x%08lx > 0x%08lx)\ndisabling initrd\n", + ramdisk_end, end_of_mem); + initrd_start = 0; + } + } +#endif +} /* * setup_arch - architecture-specific boot-time initializations * @@ -251,6 +278,8 @@ void __init setup_arch(char **cmdline_p) end_pfn = e820_end_of_ram(); } + reserve_initrd(); + num_physpages = end_pfn; check_efer(); @@ -307,30 +336,6 @@ void __init setup_arch(char **cmdline_p) */ find_smp_config(); #endif -#ifdef CONFIG_BLK_DEV_INITRD - if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { - unsigned long ramdisk_image = boot_params.hdr.ramdisk_image; - unsigned long ramdisk_size = boot_params.hdr.ramdisk_size; - unsigned long ramdisk_end = ramdisk_image + ramdisk_size; - unsigned long end_of_mem = end_pfn << PAGE_SHIFT; - - if (ramdisk_end <= end_of_mem) { - /* - * don't need to reserve again, already reserved early - * in x86_64_start_kernel, and early_res_to_bootmem - * convert that to reserved in bootmem - */ - initrd_start = ramdisk_image + PAGE_OFFSET; - initrd_end = initrd_start+ramdisk_size; - } else { - free_bootmem(ramdisk_image, ramdisk_size); - printk(KERN_ERR "initrd extends beyond end of memory " - "(0x%08lx > 0x%08lx)\ndisabling initrd\n", - ramdisk_end, end_of_mem); - initrd_start = 0; - } - } -#endif reserve_crashkernel(); reserve_ibft_region(); Index: linux-2.6/arch/x86/mm/init_32.c =================================================================== --- linux-2.6.orig/arch/x86/mm/init_32.c +++ linux-2.6/arch/x86/mm/init_32.c @@ -597,8 +597,6 @@ void __init zone_sizes_init(void) } #endif /* !CONFIG_NEED_MULTIPLE_NODES */ -extern void reserve_initrd(void); - void __init setup_bootmem_allocator(void) { int i; @@ -613,9 +611,9 @@ void __init setup_bootmem_allocator(void if (bootmap == -1L) panic("Cannot find bootmem map of size %ld\n", bootmap_size); reserve_early(bootmap, bootmap + bootmap_size, "BOOTMAP"); -#ifdef CONFIG_BLK_DEV_INITRD + reserve_initrd(); -#endif + bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, max_low_pfn); printk(KERN_INFO " mapped low ram: 0 - %08lx\n", max_pfn_mapped<<PAGE_SHIFT); Index: linux-2.6/include/asm-x86/setup.h =================================================================== --- linux-2.6.orig/include/asm-x86/setup.h +++ linux-2.6/include/asm-x86/setup.h @@ -39,6 +39,8 @@ void reserve_crashkernel(void); #include <asm/bootparam.h> void reserve_standard_io_resources(void); +void reserve_initrd(void); + #ifndef _SETUP ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH] x86: move boot_params declaring to setup.c 2008-06-22 9:46 ` [PATCH] x86: introduce reserve_initrd Yinghai Lu @ 2008-06-23 0:37 ` Yinghai Lu 2008-06-23 0:40 ` [PATCH] x86: move reservetop and vmalloc parsing to pgtable_32.c Yinghai Lu ` (4 subsequent siblings) 5 siblings, 0 replies; 26+ messages in thread From: Yinghai Lu @ 2008-06-23 0:37 UTC (permalink / raw) To: Ingo Molnar, H. Peter Anvin, Thomas Gleixner; +Cc: linux-kernel@vger.kernel.org Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- arch/x86/kernel/cpu/common_64.c | 6 ------ arch/x86/kernel/setup.c | 6 ++++++ arch/x86/kernel/setup_32.c | 6 ------ 3 files changed, 6 insertions(+), 12 deletions(-) Index: linux-2.6/arch/x86/kernel/cpu/common_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/cpu/common_64.c +++ linux-2.6/arch/x86/kernel/cpu/common_64.c @@ -421,12 +421,6 @@ static __init int setup_disablecpuid(cha } __setup("clearcpuid=", setup_disablecpuid); -#ifndef CONFIG_DEBUG_BOOT_PARAMS -struct boot_params __initdata boot_params; -#else -struct boot_params boot_params; -#endif - cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; struct x8664_pda **_cpu_pda __read_mostly; Index: linux-2.6/arch/x86/kernel/setup.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup.c +++ linux-2.6/arch/x86/kernel/setup.c @@ -15,6 +15,12 @@ #include <asm/apicdef.h> #include <asm/highmem.h> +#ifndef CONFIG_DEBUG_BOOT_PARAMS +struct boot_params __initdata boot_params; +#else +struct boot_params boot_params; +#endif + #ifdef CONFIG_X86_LOCAL_APIC unsigned int num_processors; unsigned disabled_cpus __cpuinitdata; Index: linux-2.6/arch/x86/kernel/setup_32.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup_32.c +++ linux-2.6/arch/x86/kernel/setup_32.c @@ -161,12 +161,6 @@ unsigned long saved_video_mode; static char __initdata command_line[COMMAND_LINE_SIZE]; -#ifndef CONFIG_DEBUG_BOOT_PARAMS -struct boot_params __initdata boot_params; -#else -struct boot_params boot_params; -#endif - #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) struct edd edd; #ifdef CONFIG_EDD_MODULE ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH] x86: move reservetop and vmalloc parsing to pgtable_32.c 2008-06-22 9:46 ` [PATCH] x86: introduce reserve_initrd Yinghai Lu 2008-06-23 0:37 ` [PATCH] x86: move boot_params declaring to setup.c Yinghai Lu @ 2008-06-23 0:40 ` Yinghai Lu 2008-06-23 0:40 ` [PATCH] x86: introduce reserve_initrd Yinghai Lu ` (3 subsequent siblings) 5 siblings, 0 replies; 26+ messages in thread From: Yinghai Lu @ 2008-06-23 0:40 UTC (permalink / raw) To: Ingo Molnar, H. Peter Anvin, Thomas Gleixner; +Cc: linux-kernel@vger.kernel.org also change reserve_top_address to __init attibute Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- arch/x86/kernel/setup_32.c | 33 --------------------------------- arch/x86/mm/pgtable_32.c | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 34 deletions(-) Index: linux-2.6/arch/x86/kernel/setup_32.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup_32.c +++ linux-2.6/arch/x86/kernel/setup_32.c @@ -185,39 +185,6 @@ static inline void copy_edd(void) } #endif -/* - * vmalloc=size forces the vmalloc area to be exactly 'size' - * bytes. This can be used to increase (or decrease) the - * vmalloc area - the default is 128m. - */ -static int __init parse_vmalloc(char *arg) -{ - if (!arg) - return -EINVAL; - - __VMALLOC_RESERVE = memparse(arg, &arg); - return 0; -} -early_param("vmalloc", parse_vmalloc); - -/* - * reservetop=size reserves a hole at the top of the kernel address space which - * a hypervisor can load into later. Needed for dynamically loaded hypervisors, - * so relocating the fixmap can be done before paging initialization. - */ -static int __init parse_reservetop(char *arg) -{ - unsigned long address; - - if (!arg) - return -EINVAL; - - address = memparse(arg, &arg); - reserve_top_address(address); - return 0; -} -early_param("reservetop", parse_reservetop); - #ifdef CONFIG_BLK_DEV_INITRD static bool do_relocate_initrd = false; Index: linux-2.6/arch/x86/mm/pgtable_32.c =================================================================== --- linux-2.6.orig/arch/x86/mm/pgtable_32.c +++ linux-2.6/arch/x86/mm/pgtable_32.c @@ -152,7 +152,7 @@ EXPORT_SYMBOL(__FIXADDR_TOP); * Can be used to relocate the fixmap area and poke a hole in the top * of kernel address space to make room for a hypervisor. */ -void reserve_top_address(unsigned long reserve) +void __init reserve_top_address(unsigned long reserve) { BUG_ON(fixmaps_set > 0); printk(KERN_INFO "Reserving virtual address space above 0x%08x\n", @@ -160,3 +160,36 @@ void reserve_top_address(unsigned long r __FIXADDR_TOP = -reserve - PAGE_SIZE; __VMALLOC_RESERVE += reserve; } + +/* + * vmalloc=size forces the vmalloc area to be exactly 'size' + * bytes. This can be used to increase (or decrease) the + * vmalloc area - the default is 128m. + */ +static int __init parse_vmalloc(char *arg) +{ + if (!arg) + return -EINVAL; + + __VMALLOC_RESERVE = memparse(arg, &arg); + return 0; +} +early_param("vmalloc", parse_vmalloc); + +/* + * reservetop=size reserves a hole at the top of the kernel address space which + * a hypervisor can load into later. Needed for dynamically loaded hypervisors, + * so relocating the fixmap can be done before paging initialization. + */ +static int __init parse_reservetop(char *arg) +{ + unsigned long address; + + if (!arg) + return -EINVAL; + + address = memparse(arg, &arg); + reserve_top_address(address); + return 0; +} +early_param("reservetop", parse_reservetop); ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH] x86: introduce reserve_initrd 2008-06-22 9:46 ` [PATCH] x86: introduce reserve_initrd Yinghai Lu 2008-06-23 0:37 ` [PATCH] x86: move boot_params declaring to setup.c Yinghai Lu 2008-06-23 0:40 ` [PATCH] x86: move reservetop and vmalloc parsing to pgtable_32.c Yinghai Lu @ 2008-06-23 0:40 ` Yinghai Lu 2008-06-23 10:04 ` [PATCH] x86: move reservetop and vmalloc parsing to pgtable_32.c Yinghai Lu ` (2 subsequent siblings) 5 siblings, 0 replies; 26+ messages in thread From: Yinghai Lu @ 2008-06-23 0:40 UTC (permalink / raw) To: Ingo Molnar, H. Peter Anvin, Thomas Gleixner; +Cc: linux-kernel@vger.kernel.org Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- arch/x86/kernel/setup_32.c | 16 ++++++++----- arch/x86/kernel/setup_64.c | 53 ++++++++++++++++++++++++--------------------- arch/x86/mm/init_32.c | 6 +---- include/asm-x86/setup.h | 2 + 4 files changed, 43 insertions(+), 34 deletions(-) Index: linux-2.6/arch/x86/kernel/setup_32.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup_32.c +++ linux-2.6/arch/x86/kernel/setup_32.c @@ -337,7 +337,7 @@ void __init reserve_initrd(void) * in i386_start_kernel */ initrd_start = ramdisk_image + PAGE_OFFSET; - initrd_end = initrd_start+ramdisk_size; + initrd_end = initrd_start + ramdisk_size; return; } @@ -364,7 +364,7 @@ void __init reserve_initrd(void) #define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT) -static void __init relocate_initrd(void) +static void __init post_reserve_initrd(void) { u64 ramdisk_image = boot_params.hdr.ramdisk_image; u64 ramdisk_size = boot_params.hdr.ramdisk_size; @@ -418,7 +418,13 @@ static void __init relocate_initrd(void) /* need to free that, otherwise init highmem will reserve it again */ free_early(ramdisk_image, ramdisk_image+ramdisk_size); } - +#else +void __init reserve_initrd(void) +{ +} +static void __init post_reserve_initrd(void) +{ +} #endif /* CONFIG_BLK_DEV_INITRD */ /* @@ -638,9 +644,7 @@ void __init setup_arch(char **cmdline_p) * NOTE: at this point the bootmem allocator is fully available. */ -#ifdef CONFIG_BLK_DEV_INITRD - relocate_initrd(); -#endif + post_reserve_initrd(); remapped_pgdat_init(); sparse_init(); Index: linux-2.6/arch/x86/kernel/setup_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup_64.c +++ linux-2.6/arch/x86/kernel/setup_64.c @@ -154,6 +154,33 @@ static inline void copy_edd(void) } #endif +void __init reserve_initrd(void) +{ +#ifdef CONFIG_BLK_DEV_INITRD + if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { + unsigned long ramdisk_image = boot_params.hdr.ramdisk_image; + unsigned long ramdisk_size = boot_params.hdr.ramdisk_size; + unsigned long ramdisk_end = ramdisk_image + ramdisk_size; + unsigned long end_of_mem = end_pfn << PAGE_SHIFT; + + if (ramdisk_end <= end_of_mem) { + /* + * don't need to reserve again, already reserved early + * in x86_64_start_kernel, and early_res_to_bootmem + * will convert that to reserved in bootmem + */ + initrd_start = ramdisk_image + PAGE_OFFSET; + initrd_end = initrd_start+ramdisk_size; + } else { + free_early(ramdisk_image, ramdisk_end); + printk(KERN_ERR "initrd extends beyond end of memory " + "(0x%08lx > 0x%08lx)\ndisabling initrd\n", + ramdisk_end, end_of_mem); + initrd_start = 0; + } + } +#endif +} /* * setup_arch - architecture-specific boot-time initializations * @@ -251,6 +278,8 @@ void __init setup_arch(char **cmdline_p) end_pfn = e820_end_of_ram(); } + reserve_initrd(); + num_physpages = end_pfn; check_efer(); @@ -307,30 +336,6 @@ void __init setup_arch(char **cmdline_p) */ find_smp_config(); #endif -#ifdef CONFIG_BLK_DEV_INITRD - if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { - unsigned long ramdisk_image = boot_params.hdr.ramdisk_image; - unsigned long ramdisk_size = boot_params.hdr.ramdisk_size; - unsigned long ramdisk_end = ramdisk_image + ramdisk_size; - unsigned long end_of_mem = end_pfn << PAGE_SHIFT; - - if (ramdisk_end <= end_of_mem) { - /* - * don't need to reserve again, already reserved early - * in x86_64_start_kernel, and early_res_to_bootmem - * convert that to reserved in bootmem - */ - initrd_start = ramdisk_image + PAGE_OFFSET; - initrd_end = initrd_start+ramdisk_size; - } else { - free_bootmem(ramdisk_image, ramdisk_size); - printk(KERN_ERR "initrd extends beyond end of memory " - "(0x%08lx > 0x%08lx)\ndisabling initrd\n", - ramdisk_end, end_of_mem); - initrd_start = 0; - } - } -#endif reserve_crashkernel(); reserve_ibft_region(); Index: linux-2.6/arch/x86/mm/init_32.c =================================================================== --- linux-2.6.orig/arch/x86/mm/init_32.c +++ linux-2.6/arch/x86/mm/init_32.c @@ -597,8 +597,6 @@ void __init zone_sizes_init(void) } #endif /* !CONFIG_NEED_MULTIPLE_NODES */ -extern void reserve_initrd(void); - void __init setup_bootmem_allocator(void) { int i; @@ -613,9 +611,9 @@ void __init setup_bootmem_allocator(void if (bootmap == -1L) panic("Cannot find bootmem map of size %ld\n", bootmap_size); reserve_early(bootmap, bootmap + bootmap_size, "BOOTMAP"); -#ifdef CONFIG_BLK_DEV_INITRD + reserve_initrd(); -#endif + bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, max_low_pfn); printk(KERN_INFO " mapped low ram: 0 - %08lx\n", max_pfn_mapped<<PAGE_SHIFT); Index: linux-2.6/include/asm-x86/setup.h =================================================================== --- linux-2.6.orig/include/asm-x86/setup.h +++ linux-2.6/include/asm-x86/setup.h @@ -39,6 +39,8 @@ void reserve_crashkernel(void); #include <asm/bootparam.h> void reserve_standard_io_resources(void); +void reserve_initrd(void); + #ifndef _SETUP ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH] x86: move reservetop and vmalloc parsing to pgtable_32.c 2008-06-22 9:46 ` [PATCH] x86: introduce reserve_initrd Yinghai Lu ` (2 preceding siblings ...) 2008-06-23 0:40 ` [PATCH] x86: introduce reserve_initrd Yinghai Lu @ 2008-06-23 10:04 ` Yinghai Lu 2008-06-23 10:05 ` [PATCH] x86: cleanup using max_low_pfn for 32 bit Yinghai Lu 2008-06-23 10:06 ` [PATCH] x86: cleanup min_low_pfn Yinghai Lu 5 siblings, 0 replies; 26+ messages in thread From: Yinghai Lu @ 2008-06-23 10:04 UTC (permalink / raw) To: Ingo Molnar, H. Peter Anvin, Thomas Gleixner; +Cc: linux-kernel@vger.kernel.org also change reserve_top_address to __init attibute Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- arch/x86/kernel/setup_32.c | 33 --------------------------------- arch/x86/mm/pgtable_32.c | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 34 deletions(-) Index: linux-2.6/arch/x86/kernel/setup_32.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup_32.c +++ linux-2.6/arch/x86/kernel/setup_32.c @@ -185,39 +185,6 @@ static inline void copy_edd(void) } #endif -/* - * vmalloc=size forces the vmalloc area to be exactly 'size' - * bytes. This can be used to increase (or decrease) the - * vmalloc area - the default is 128m. - */ -static int __init parse_vmalloc(char *arg) -{ - if (!arg) - return -EINVAL; - - __VMALLOC_RESERVE = memparse(arg, &arg); - return 0; -} -early_param("vmalloc", parse_vmalloc); - -/* - * reservetop=size reserves a hole at the top of the kernel address space which - * a hypervisor can load into later. Needed for dynamically loaded hypervisors, - * so relocating the fixmap can be done before paging initialization. - */ -static int __init parse_reservetop(char *arg) -{ - unsigned long address; - - if (!arg) - return -EINVAL; - - address = memparse(arg, &arg); - reserve_top_address(address); - return 0; -} -early_param("reservetop", parse_reservetop); - #ifdef CONFIG_BLK_DEV_INITRD static bool do_relocate_initrd = false; Index: linux-2.6/arch/x86/mm/pgtable_32.c =================================================================== --- linux-2.6.orig/arch/x86/mm/pgtable_32.c +++ linux-2.6/arch/x86/mm/pgtable_32.c @@ -152,7 +152,7 @@ EXPORT_SYMBOL(__FIXADDR_TOP); * Can be used to relocate the fixmap area and poke a hole in the top * of kernel address space to make room for a hypervisor. */ -void reserve_top_address(unsigned long reserve) +void __init reserve_top_address(unsigned long reserve) { BUG_ON(fixmaps_set > 0); printk(KERN_INFO "Reserving virtual address space above 0x%08x\n", @@ -160,3 +160,36 @@ void reserve_top_address(unsigned long r __FIXADDR_TOP = -reserve - PAGE_SIZE; __VMALLOC_RESERVE += reserve; } + +/* + * vmalloc=size forces the vmalloc area to be exactly 'size' + * bytes. This can be used to increase (or decrease) the + * vmalloc area - the default is 128m. + */ +static int __init parse_vmalloc(char *arg) +{ + if (!arg) + return -EINVAL; + + __VMALLOC_RESERVE = memparse(arg, &arg); + return 0; +} +early_param("vmalloc", parse_vmalloc); + +/* + * reservetop=size reserves a hole at the top of the kernel address space which + * a hypervisor can load into later. Needed for dynamically loaded hypervisors, + * so relocating the fixmap can be done before paging initialization. + */ +static int __init parse_reservetop(char *arg) +{ + unsigned long address; + + if (!arg) + return -EINVAL; + + address = memparse(arg, &arg); + reserve_top_address(address); + return 0; +} +early_param("reservetop", parse_reservetop); ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH] x86: cleanup using max_low_pfn for 32 bit 2008-06-22 9:46 ` [PATCH] x86: introduce reserve_initrd Yinghai Lu ` (3 preceding siblings ...) 2008-06-23 10:04 ` [PATCH] x86: move reservetop and vmalloc parsing to pgtable_32.c Yinghai Lu @ 2008-06-23 10:05 ` Yinghai Lu 2008-06-23 19:56 ` Ingo Molnar 2008-06-23 10:06 ` [PATCH] x86: cleanup min_low_pfn Yinghai Lu 5 siblings, 1 reply; 26+ messages in thread From: Yinghai Lu @ 2008-06-23 10:05 UTC (permalink / raw) To: Ingo Molnar, H. Peter Anvin, Thomas Gleixner; +Cc: linux-kernel@vger.kernel.org for max_low_pfn is not changed after it is set. so we can move that early and out of initmem_init. could call find_low_pfn_range just after max_pfn is set. also could move reserve_initrd out of setup_bootmem_allocator so 32bit is more like 64bit. Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- arch/x86/kernel/setup_32.c | 16 ++++++++++------ arch/x86/kernel/setup_64.c | 2 +- arch/x86/mm/discontig_32.c | 22 +++++++--------------- arch/x86/mm/init_32.c | 25 +++++++++---------------- include/asm-x86/page_32.h | 3 ++- include/asm-x86/setup.h | 2 -- 6 files changed, 29 insertions(+), 41 deletions(-) Index: linux-2.6/arch/x86/kernel/setup_32.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup_32.c +++ linux-2.6/arch/x86/kernel/setup_32.c @@ -189,13 +189,14 @@ static inline void copy_edd(void) static bool do_relocate_initrd = false; -void __init reserve_initrd(void) +static void __init reserve_initrd(void) { u64 ramdisk_image = boot_params.hdr.ramdisk_image; u64 ramdisk_size = boot_params.hdr.ramdisk_size; u64 ramdisk_end = ramdisk_image + ramdisk_size; u64 end_of_lowmem = max_low_pfn << PAGE_SHIFT; u64 ramdisk_here; + u64 ramdisk_target; if (!boot_params.hdr.type_of_loader || !ramdisk_image || !ramdisk_size) @@ -203,7 +204,7 @@ void __init reserve_initrd(void) initrd_start = 0; - if (ramdisk_size >= end_of_lowmem/2) { + if (ramdisk_size >= (end_of_lowmem>>1)) { free_early(ramdisk_image, ramdisk_end); printk(KERN_ERR "initrd too large to handle, " "disabling initrd\n"); @@ -226,7 +227,8 @@ void __init reserve_initrd(void) } /* We need to move the initrd down into lowmem */ - ramdisk_here = find_e820_area(min_low_pfn<<PAGE_SHIFT, + ramdisk_target = max_pfn_mapped<<PAGE_SHIFT; + ramdisk_here = find_e820_area(min(ramdisk_target, end_of_lowmem>>1), end_of_lowmem, ramdisk_size, PAGE_SIZE); @@ -347,8 +349,6 @@ static void set_mca_bus(int x) { } */ void __init setup_arch(char **cmdline_p) { - unsigned long max_low_pfn; - memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); pre_setup_arch_hook(); early_cpu_init(); @@ -456,6 +456,10 @@ void __init setup_arch(char **cmdline_p) max_pfn = e820_end_of_ram(); } + find_low_pfn_range(); + + reserve_initrd(); + dmi_scan_machine(); io_delay_init(); @@ -472,7 +476,7 @@ void __init setup_arch(char **cmdline_p) acpi_numa_init(); #endif - max_low_pfn = initmem_init(0, max_pfn); + initmem_init(0, max_pfn); #ifdef CONFIG_ACPI_SLEEP /* Index: linux-2.6/arch/x86/kernel/setup_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup_64.c +++ linux-2.6/arch/x86/kernel/setup_64.c @@ -154,7 +154,7 @@ static inline void copy_edd(void) } #endif -void __init reserve_initrd(void) +static void __init reserve_initrd(void) { #ifdef CONFIG_BLK_DEV_INITRD if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { Index: linux-2.6/arch/x86/mm/discontig_32.c =================================================================== --- linux-2.6.orig/arch/x86/mm/discontig_32.c +++ linux-2.6/arch/x86/mm/discontig_32.c @@ -309,11 +309,10 @@ static void init_remap_allocator(int nid (ulong) node_remap_end_vaddr[nid]); } -unsigned long __init initmem_init(unsigned long start_pfn, +void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn) { int nid; - unsigned long system_start_pfn, system_max_low_pfn; long kva_target_pfn; /* @@ -324,17 +323,11 @@ unsigned long __init initmem_init(unsign * and ZONE_HIGHMEM. */ - /* call find_max_low_pfn at first, it could update max_pfn */ - system_max_low_pfn = max_low_pfn = find_max_low_pfn(); - remove_all_active_ranges(); get_memcfg_numa(); kva_pages = round_up(calculate_numa_remap_pages(), PTRS_PER_PTE); - /* partially used pages are not usable - thus round upwards */ - system_start_pfn = min_low_pfn = PFN_UP(init_pg_tables_end); - kva_target_pfn = round_down(max_low_pfn - kva_pages, PTRS_PER_PTE); do { kva_start_pfn = find_e820_area(kva_target_pfn<<PAGE_SHIFT, @@ -357,19 +350,19 @@ unsigned long __init initmem_init(unsign "KVA PG"); #ifdef CONFIG_HIGHMEM highstart_pfn = highend_pfn = max_pfn; - if (max_pfn > system_max_low_pfn) - highstart_pfn = system_max_low_pfn; + if (max_pfn > max_low_pfn) + highstart_pfn = max_low_pfn; printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", pages_to_mb(highend_pfn - highstart_pfn)); num_physpages = highend_pfn; high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1; #else - num_physpages = system_max_low_pfn; - high_memory = (void *) __va(system_max_low_pfn * PAGE_SIZE - 1) + 1; + num_physpages = max_low_pfn; + high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1; #endif printk(KERN_NOTICE "%ldMB LOWMEM available.\n", - pages_to_mb(system_max_low_pfn)); - printk("min_low_pfn = %ld, max_low_pfn = %ld, highstart_pfn = %ld\n", + pages_to_mb(max_low_pfn)); + printk("min_low_pfn = %ld, max_low_pfn = %ld, highstart_pfn = %ld\n", min_low_pfn, max_low_pfn, highstart_pfn); printk("Low memory ends at vaddr %08lx\n", @@ -387,7 +380,6 @@ unsigned long __init initmem_init(unsign memset(NODE_DATA(0), 0, sizeof(struct pglist_data)); NODE_DATA(0)->bdata = &node0_bdata; setup_bootmem_allocator(); - return max_low_pfn; } void __init zone_sizes_init(void) Index: linux-2.6/arch/x86/mm/init_32.c =================================================================== --- linux-2.6.orig/arch/x86/mm/init_32.c +++ linux-2.6/arch/x86/mm/init_32.c @@ -561,9 +561,15 @@ early_param("highmem", parse_highmem); /* * Determine low and high memory ranges: */ -unsigned long __init find_max_low_pfn(void) +void __init find_low_pfn_range(void) { - unsigned long max_low_pfn; + /* it could update max_pfn */ + + /* + * partially used pages are not usable - thus + * we are rounding upwards: + */ + min_low_pfn = PFN_UP(init_pg_tables_end); max_low_pfn = max_pfn; if (max_low_pfn > MAXMEM_PFN) { @@ -625,21 +631,12 @@ unsigned long __init find_max_low_pfn(vo " kernel!\n"); #endif } - return max_low_pfn; } #ifndef CONFIG_NEED_MULTIPLE_NODES -unsigned long __init initmem_init(unsigned long start_pfn, +void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn) { - /* - * partially used pages are not usable - thus - * we are rounding upwards: - */ - min_low_pfn = PFN_UP(init_pg_tables_end); - - max_low_pfn = find_max_low_pfn(); - #ifdef CONFIG_HIGHMEM highstart_pfn = highend_pfn = max_pfn; if (max_pfn > max_low_pfn) @@ -661,8 +658,6 @@ unsigned long __init initmem_init(unsign pages_to_mb(max_low_pfn)); setup_bootmem_allocator(); - - return max_low_pfn; } void __init zone_sizes_init(void) @@ -699,8 +694,6 @@ void __init setup_bootmem_allocator(void panic("Cannot find bootmem map of size %ld\n", bootmap_size); reserve_early(bootmap, bootmap + bootmap_size, "BOOTMAP"); - reserve_initrd(); - bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, max_low_pfn); printk(KERN_INFO " mapped low ram: 0 - %08lx\n", max_pfn_mapped<<PAGE_SHIFT); Index: linux-2.6/include/asm-x86/page_32.h =================================================================== --- linux-2.6.orig/include/asm-x86/page_32.h +++ linux-2.6/include/asm-x86/page_32.h @@ -97,7 +97,8 @@ extern int sysctl_legacy_va_layout; #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE) #define MAXMEM (-__PAGE_OFFSET - __VMALLOC_RESERVE) -extern unsigned long initmem_init(unsigned long, unsigned long); +extern void find_low_pfn_range(void); +extern void initmem_init(unsigned long, unsigned long); extern void zone_sizes_init(void); extern void setup_bootmem_allocator(void); Index: linux-2.6/include/asm-x86/setup.h =================================================================== --- linux-2.6.orig/include/asm-x86/setup.h +++ linux-2.6/include/asm-x86/setup.h @@ -39,8 +39,6 @@ void reserve_crashkernel(void); #include <asm/bootparam.h> void reserve_standard_io_resources(void); -void reserve_initrd(void); - #ifndef _SETUP ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] x86: cleanup using max_low_pfn for 32 bit 2008-06-23 10:05 ` [PATCH] x86: cleanup using max_low_pfn for 32 bit Yinghai Lu @ 2008-06-23 19:56 ` Ingo Molnar 2008-06-23 19:57 ` H. Peter Anvin 2008-06-23 20:22 ` Ingo Molnar 0 siblings, 2 replies; 26+ messages in thread From: Ingo Molnar @ 2008-06-23 19:56 UTC (permalink / raw) To: Yinghai Lu; +Cc: H. Peter Anvin, Thomas Gleixner, linux-kernel@vger.kernel.org * Yinghai Lu <yhlu.kernel@gmail.com> wrote: > for max_low_pfn is not changed after it is set. so we can move that > early and out of initmem_init. > > could call find_low_pfn_range just after max_pfn is set. > > also could move reserve_initrd out of setup_bootmem_allocator > > so 32bit is more like 64bit. applied, thanks Yinghai. i've picked up the following patches from you into a new tip/x86/setup-memory topic: Yinghai Lu (19): x86: check command line when CONFIG_X86_MPPARSE is not set, v2 x86: clean up init_amd() x86: remove some acpi ifdefs in setup_32/64 x86: seperate funcs from setup_64 to cpu common_64.c x86: change identify_cpu to static x86: add e820_remove_range x86: seperate probe_roms into another file x86: merge setup64.c into common_64.c x86: remove two duplicated funcs in setup_32.c x86: move reserve_standard_io_resource to setup.c x86: move elfcorehdr parsing to setup.c x86: introduce initmem_init for 64 bit x86: introduce initmem_init for 32 bit x86: introduce reserve_initrd x86: move boot_params declaring to setup.c x86: move find_max_low_pfn to init_32.c x86: move reservetop and vmalloc parsing to pgtable_32.c x86: clean up using max_low_pfn on 32-bit x86: clean up min_low_pfn very nice stuff - and it's working pretty well in my testing so far! Ingo ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] x86: cleanup using max_low_pfn for 32 bit 2008-06-23 19:56 ` Ingo Molnar @ 2008-06-23 19:57 ` H. Peter Anvin 2008-06-23 20:22 ` Ingo Molnar 1 sibling, 0 replies; 26+ messages in thread From: H. Peter Anvin @ 2008-06-23 19:57 UTC (permalink / raw) To: Ingo Molnar; +Cc: Yinghai Lu, Thomas Gleixner, linux-kernel@vger.kernel.org Ingo Molnar wrote: > > very nice stuff - and it's working pretty well in my testing so far! > Very nice stuff indeed! -hpa ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] x86: cleanup using max_low_pfn for 32 bit 2008-06-23 19:56 ` Ingo Molnar 2008-06-23 19:57 ` H. Peter Anvin @ 2008-06-23 20:22 ` Ingo Molnar 2008-06-23 20:27 ` Yinghai Lu 1 sibling, 1 reply; 26+ messages in thread From: Ingo Molnar @ 2008-06-23 20:22 UTC (permalink / raw) To: Yinghai Lu; +Cc: H. Peter Anvin, Thomas Gleixner, linux-kernel@vger.kernel.org > x86: clean up using max_low_pfn on 32-bit this one needed the small fix below. Ingo -----------> commit 749cffb6c81f6637bbd054a4db246196eaa69ccc Author: Ingo Molnar <mingo@elte.hu> Date: Mon Jun 23 22:19:22 2008 +0200 x86: build fix fix: arch/x86/kernel/setup_32.c:409: error: 'enable_local_apic' undeclared (first use in this function) arch/x86/kernel/setup_32.c:409: error: (Each undeclared identifier is reported only once arch/x86/kernel/setup_32.c:409: error: for each function it appears in.) Signed-off-by: Ingo Molnar <mingo@elte.hu> diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index b42f570..1e67037 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -406,7 +406,9 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); if (acpi_mps_check()){ +#ifdef CONFIG_X86_LOCAL_APIC enable_local_apic = -1; +#endif clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC); } ^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH] x86: cleanup using max_low_pfn for 32 bit 2008-06-23 20:22 ` Ingo Molnar @ 2008-06-23 20:27 ` Yinghai Lu 0 siblings, 0 replies; 26+ messages in thread From: Yinghai Lu @ 2008-06-23 20:27 UTC (permalink / raw) To: Ingo Molnar; +Cc: H. Peter Anvin, Thomas Gleixner, linux-kernel@vger.kernel.org On Mon, Jun 23, 2008 at 1:22 PM, Ingo Molnar <mingo@elte.hu> wrote: > >> x86: clean up using max_low_pfn on 32-bit > > this one needed the small fix below. > > Ingo > > -----------> > commit 749cffb6c81f6637bbd054a4db246196eaa69ccc > Author: Ingo Molnar <mingo@elte.hu> > Date: Mon Jun 23 22:19:22 2008 +0200 > > x86: build fix > > fix: > > arch/x86/kernel/setup_32.c:409: error: 'enable_local_apic' undeclared (first use in this function) > arch/x86/kernel/setup_32.c:409: error: (Each undeclared identifier is reported only once > arch/x86/kernel/setup_32.c:409: error: for each function it appears in.) > > Signed-off-by: Ingo Molnar <mingo@elte.hu> > > diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c > index b42f570..1e67037 100644 > --- a/arch/x86/kernel/setup_32.c > +++ b/arch/x86/kernel/setup_32.c > @@ -406,7 +406,9 @@ void __init setup_arch(char **cmdline_p) > parse_early_param(); > > if (acpi_mps_check()){ > +#ifdef CONFIG_X86_LOCAL_APIC > enable_local_apic = -1; > +#endif > clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC); > } need to merge enable_local_apic (32bit) and disable_apic (64 bit). YH ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH] x86: cleanup min_low_pfn 2008-06-22 9:46 ` [PATCH] x86: introduce reserve_initrd Yinghai Lu ` (4 preceding siblings ...) 2008-06-23 10:05 ` [PATCH] x86: cleanup using max_low_pfn for 32 bit Yinghai Lu @ 2008-06-23 10:06 ` Yinghai Lu 5 siblings, 0 replies; 26+ messages in thread From: Yinghai Lu @ 2008-06-23 10:06 UTC (permalink / raw) To: Ingo Molnar, H. Peter Anvin, Thomas Gleixner; +Cc: linux-kernel@vger.kernel.org for 32bit we already had early_res support, so don't need to track min_low_pfn. keep it to 0 always. also use init_bootmem_node instead of init_bootmem, so don't touch min_low_pfn. Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> --- arch/x86/mm/init_32.c | 10 ++++------ arch/x86/mm/init_64.c | 4 +++- 2 files changed, 7 insertions(+), 7 deletions(-) Index: linux-2.6/arch/x86/mm/init_32.c =================================================================== --- linux-2.6.orig/arch/x86/mm/init_32.c +++ linux-2.6/arch/x86/mm/init_32.c @@ -565,11 +565,7 @@ void __init find_low_pfn_range(void) { /* it could update max_pfn */ - /* - * partially used pages are not usable - thus - * we are rounding upwards: - */ - min_low_pfn = PFN_UP(init_pg_tables_end); + /* max_low_pfn is 0, we already have early_res support */ max_low_pfn = max_pfn; if (max_low_pfn > MAXMEM_PFN) { @@ -694,7 +690,9 @@ void __init setup_bootmem_allocator(void panic("Cannot find bootmem map of size %ld\n", bootmap_size); reserve_early(bootmap, bootmap + bootmap_size, "BOOTMAP"); - bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, max_low_pfn); + /* don't touch min_low_pfn */ + bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap >> PAGE_SHIFT, + min_low_pfn, max_low_pfn); printk(KERN_INFO " mapped low ram: 0 - %08lx\n", max_pfn_mapped<<PAGE_SHIFT); printk(KERN_INFO " low ram: %08lx - %08lx\n", Index: linux-2.6/arch/x86/mm/init_64.c =================================================================== --- linux-2.6.orig/arch/x86/mm/init_64.c +++ linux-2.6/arch/x86/mm/init_64.c @@ -633,7 +633,9 @@ void __init initmem_init(unsigned long s PAGE_SIZE); if (bootmap == -1L) panic("Cannot find bootmem map of size %ld\n", bootmap_size); - bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn); + /* don't touch min_low_pfn */ + bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap >> PAGE_SHIFT, + 0, end_pfn); e820_register_active_regions(0, start_pfn, end_pfn); free_bootmem_with_active_regions(0, end_pfn); early_res_to_bootmem(0, end_pfn<<PAGE_SHIFT); ^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2008-06-23 20:28 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-18 9:15 [PATCH] x86: make 64bit identify_cpu use cpu_dev Yinghai Lu
2008-06-18 14:17 ` Ingo Molnar
2008-06-19 9:03 ` Ingo Molnar
2008-06-19 20:00 ` Yinghai Lu
2008-06-19 22:30 ` [PATCH] x86: make 64bit identify_cpu use cpu_dev v2 Yinghai Lu
2008-06-20 6:29 ` Ingo Molnar
2008-06-20 7:08 ` Yinghai Lu
[not found] ` <200806210323.01590.yhlu.kernel@gmail.com>
2008-06-21 10:24 ` [PATCH] x86: change identify_cpu to static Yinghai Lu
2008-06-21 10:24 ` [PATCH] x86: seperate funcs from setup_64 to cpu common_64.c Yinghai Lu
2008-06-21 23:25 ` [PATCH] x86: merge setup64.c into common_64.c Yinghai Lu
2008-06-22 2:16 ` [PATCH] x86: remove two duplicated func in setup_32.c Yinghai Lu
2008-06-22 3:22 ` [PATCH] x86: move reserve_standard_io_resource to setup.c Yinghai Lu
2008-06-22 4:02 ` [PATCH] x86: move elfcorehdr parsing " Yinghai Lu
2008-06-22 9:44 ` [PATCH] x86: introduce initmem_init for 64 bit Yinghai Lu
2008-06-22 9:45 ` [PATCH] x86: introduce initmem_init for 32 bit Yinghai Lu
2008-06-22 9:46 ` [PATCH] x86: introduce reserve_initrd Yinghai Lu
2008-06-23 0:37 ` [PATCH] x86: move boot_params declaring to setup.c Yinghai Lu
2008-06-23 0:40 ` [PATCH] x86: move reservetop and vmalloc parsing to pgtable_32.c Yinghai Lu
2008-06-23 0:40 ` [PATCH] x86: introduce reserve_initrd Yinghai Lu
2008-06-23 10:04 ` [PATCH] x86: move reservetop and vmalloc parsing to pgtable_32.c Yinghai Lu
2008-06-23 10:05 ` [PATCH] x86: cleanup using max_low_pfn for 32 bit Yinghai Lu
2008-06-23 19:56 ` Ingo Molnar
2008-06-23 19:57 ` H. Peter Anvin
2008-06-23 20:22 ` Ingo Molnar
2008-06-23 20:27 ` Yinghai Lu
2008-06-23 10:06 ` [PATCH] x86: cleanup min_low_pfn Yinghai Lu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox