diff options
author | Guenter Roeck <guenter.roeck@ericsson.com> | 2010-02-02 11:52:20 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2010-02-02 13:56:23 -0500 |
commit | 91dfc423cc8cfd399fb308a837102a7ab7fa067e (patch) | |
tree | 21c75672185153084a5ac8e38ca3938ca0cf4ac1 /arch | |
parent | ba284b1f199ef7121489010da6614561a679eab6 (diff) |
MIPS: 64-bit: Detect virtual memory size
Linux kernel 2.6.32 and later allocate address space from the top of the
kernel virtual memory address space.
This patch implements virtual memory size detection for 64 bit MIPS CPUs
to avoid resulting crashes.
Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
Cc: linux-mips@linux-mips.org
Patchwork: http://patchwork.linux-mips.org/patch/935/
Reviewed-by: David Daney <ddaney@caviumnetworks.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips/include/asm/cpu-features.h | 7 | ||||
-rw-r--r-- | arch/mips/include/asm/cpu-info.h | 3 | ||||
-rw-r--r-- | arch/mips/include/asm/pgtable-64.h | 4 | ||||
-rw-r--r-- | arch/mips/kernel/cpu-probe.c | 11 |
4 files changed, 24 insertions, 1 deletions
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index 1f4df647c38..272c5ef35bb 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h | |||
@@ -191,6 +191,9 @@ | |||
191 | # ifndef cpu_has_64bit_addresses | 191 | # ifndef cpu_has_64bit_addresses |
192 | # define cpu_has_64bit_addresses 0 | 192 | # define cpu_has_64bit_addresses 0 |
193 | # endif | 193 | # endif |
194 | # ifndef cpu_vmbits | ||
195 | # define cpu_vmbits 31 | ||
196 | # endif | ||
194 | #endif | 197 | #endif |
195 | 198 | ||
196 | #ifdef CONFIG_64BIT | 199 | #ifdef CONFIG_64BIT |
@@ -209,6 +212,10 @@ | |||
209 | # ifndef cpu_has_64bit_addresses | 212 | # ifndef cpu_has_64bit_addresses |
210 | # define cpu_has_64bit_addresses 1 | 213 | # define cpu_has_64bit_addresses 1 |
211 | # endif | 214 | # endif |
215 | # ifndef cpu_vmbits | ||
216 | # define cpu_vmbits cpu_data[0].vmbits | ||
217 | # define __NEED_VMBITS_PROBE | ||
218 | # endif | ||
212 | #endif | 219 | #endif |
213 | 220 | ||
214 | #if defined(CONFIG_CPU_MIPSR2_IRQ_VI) && !defined(cpu_has_vint) | 221 | #if defined(CONFIG_CPU_MIPSR2_IRQ_VI) && !defined(cpu_has_vint) |
diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h index 126044308de..b39def3f6e0 100644 --- a/arch/mips/include/asm/cpu-info.h +++ b/arch/mips/include/asm/cpu-info.h | |||
@@ -58,6 +58,9 @@ struct cpuinfo_mips { | |||
58 | struct cache_desc tcache; /* Tertiary/split secondary cache */ | 58 | struct cache_desc tcache; /* Tertiary/split secondary cache */ |
59 | int srsets; /* Shadow register sets */ | 59 | int srsets; /* Shadow register sets */ |
60 | int core; /* physical core number */ | 60 | int core; /* physical core number */ |
61 | #ifdef CONFIG_64BIT | ||
62 | int vmbits; /* Virtual memory size in bits */ | ||
63 | #endif | ||
61 | #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC) | 64 | #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC) |
62 | /* | 65 | /* |
63 | * In the MIPS MT "SMTC" model, each TC is considered | 66 | * In the MIPS MT "SMTC" model, each TC is considered |
diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h index 9cd50899395..8eda30b467d 100644 --- a/arch/mips/include/asm/pgtable-64.h +++ b/arch/mips/include/asm/pgtable-64.h | |||
@@ -110,7 +110,9 @@ | |||
110 | #define VMALLOC_START MAP_BASE | 110 | #define VMALLOC_START MAP_BASE |
111 | #define VMALLOC_END \ | 111 | #define VMALLOC_END \ |
112 | (VMALLOC_START + \ | 112 | (VMALLOC_START + \ |
113 | PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE - (1UL << 32)) | 113 | min(PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, \ |
114 | (1UL << cpu_vmbits)) - (1UL << 32)) | ||
115 | |||
114 | #if defined(CONFIG_MODULES) && defined(KBUILD_64BIT_SYM32) && \ | 116 | #if defined(CONFIG_MODULES) && defined(KBUILD_64BIT_SYM32) && \ |
115 | VMALLOC_START != CKSSEG | 117 | VMALLOC_START != CKSSEG |
116 | /* Load modules into 32bit-compatible segment. */ | 118 | /* Load modules into 32bit-compatible segment. */ |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 80e202eca05..9c187a64649 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -284,6 +284,15 @@ static inline int __cpu_has_fpu(void) | |||
284 | return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE); | 284 | return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE); |
285 | } | 285 | } |
286 | 286 | ||
287 | static inline void cpu_probe_vmbits(struct cpuinfo_mips *c) | ||
288 | { | ||
289 | #ifdef __NEED_VMBITS_PROBE | ||
290 | write_c0_entryhi(0x3ffffffffffff000ULL); | ||
291 | back_to_back_c0_hazard(); | ||
292 | c->vmbits = fls64(read_c0_entryhi() & 0x3ffffffffffff000ULL); | ||
293 | #endif | ||
294 | } | ||
295 | |||
287 | #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \ | 296 | #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \ |
288 | | MIPS_CPU_COUNTER) | 297 | | MIPS_CPU_COUNTER) |
289 | 298 | ||
@@ -969,6 +978,8 @@ __cpuinit void cpu_probe(void) | |||
969 | c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1; | 978 | c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1; |
970 | else | 979 | else |
971 | c->srsets = 1; | 980 | c->srsets = 1; |
981 | |||
982 | cpu_probe_vmbits(c); | ||
972 | } | 983 | } |
973 | 984 | ||
974 | __cpuinit void cpu_report(void) | 985 | __cpuinit void cpu_report(void) |