diff options
author | Tony Luck <tony.luck@intel.com> | 2008-08-12 13:34:20 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2008-08-12 13:34:20 -0400 |
commit | 10617bbe84628eb18ab5f723d3ba35005adde143 (patch) | |
tree | 2d1dada5b7d8dd8cd060f54a597aaa34ccc8edb6 /arch/ia64/kernel/setup.c | |
parent | 45fc3c4d9b7ab12798af43a73aea53eeecd16acf (diff) |
[IA64] Ensure cpu0 can access per-cpu variables in early boot code
ia64 handles per-cpu variables a litle differently from other architectures
in that it maps the physical memory allocated for each cpu at a constant
virtual address (0xffffffffffff0000). This mapping is not enabled until
the architecture specific cpu_init() function is run, which causes problems
since some generic code is run before this point. In particular when
CONFIG_PRINTK_TIME is enabled, the boot cpu will trap on the access to
per-cpu memory at the first printk() call so the boot will fail without
the kernel printing anything to the console.
Fix this by allocating percpu memory for cpu0 in the kernel data section
and doing all initialization to enable percpu access in head.S before
calling any generic code.
Other cpus must take care not to access per-cpu variables too early, but
their code path from start_secondary() to cpu_init() is all in arch/ia64
Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/kernel/setup.c')
-rw-r--r-- | arch/ia64/kernel/setup.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 593279f33e96..c27d5b2c182b 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c | |||
@@ -927,17 +927,19 @@ cpu_init (void) | |||
927 | if (smp_processor_id() == 0) { | 927 | if (smp_processor_id() == 0) { |
928 | cpu_set(0, per_cpu(cpu_sibling_map, 0)); | 928 | cpu_set(0, per_cpu(cpu_sibling_map, 0)); |
929 | cpu_set(0, cpu_core_map[0]); | 929 | cpu_set(0, cpu_core_map[0]); |
930 | } else { | ||
931 | /* | ||
932 | * Set ar.k3 so that assembly code in MCA handler can compute | ||
933 | * physical addresses of per cpu variables with a simple: | ||
934 | * phys = ar.k3 + &per_cpu_var | ||
935 | * and the alt-dtlb-miss handler can set per-cpu mapping into | ||
936 | * the TLB when needed. head.S already did this for cpu0. | ||
937 | */ | ||
938 | ia64_set_kr(IA64_KR_PER_CPU_DATA, | ||
939 | ia64_tpa(cpu_data) - (long) __per_cpu_start); | ||
930 | } | 940 | } |
931 | #endif | 941 | #endif |
932 | 942 | ||
933 | /* | ||
934 | * We set ar.k3 so that assembly code in MCA handler can compute | ||
935 | * physical addresses of per cpu variables with a simple: | ||
936 | * phys = ar.k3 + &per_cpu_var | ||
937 | */ | ||
938 | ia64_set_kr(IA64_KR_PER_CPU_DATA, | ||
939 | ia64_tpa(cpu_data) - (long) __per_cpu_start); | ||
940 | |||
941 | get_max_cacheline_size(); | 943 | get_max_cacheline_size(); |
942 | 944 | ||
943 | /* | 945 | /* |