aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <guenter.roeck@ericsson.com>2010-02-02 11:52:20 -0500
committerRalf Baechle <ralf@linux-mips.org>2010-02-02 13:56:23 -0500
commit91dfc423cc8cfd399fb308a837102a7ab7fa067e (patch)
tree21c75672185153084a5ac8e38ca3938ca0cf4ac1
parentba284b1f199ef7121489010da6614561a679eab6 (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>
-rw-r--r--arch/mips/include/asm/cpu-features.h7
-rw-r--r--arch/mips/include/asm/cpu-info.h3
-rw-r--r--arch/mips/include/asm/pgtable-64.h4
-rw-r--r--arch/mips/kernel/cpu-probe.c11
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 1f4df647c384..272c5ef35bbb 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 126044308dec..b39def3f6e03 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 9cd508993956..8eda30b467da 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 80e202eca056..9c187a64649b 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
287static 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)