Received: from milmhbs1.lsil.com (147.145.21.209) by coscas01.lsi.com
 (172.21.36.60) with Microsoft SMTP Server id 8.1.393.1; Mon, 1 Feb 2010
 17:19:41 -0700
Received: from mail2.lsil.com (mail2.lsil.com [147.145.40.22])	by
 milmhbs1.lsil.com (8.12.11/8.12.11) with ESMTP id o120JfWe028119	for
 <andy.sharp@lsi.com>; Mon, 1 Feb 2010 16:19:41 -0800
Received: from psmtp.com (na3sys009amx182.postini.com [74.125.149.163])	by
 mail2.lsil.com (8.12.11/8.12.11) with SMTP id o120Euqw000833	for
 <andy.sharp@lsi.com>; Mon, 1 Feb 2010 16:14:56 -0800 (PST)
Received: from source ([78.24.191.182]) by na3sys009amx182.postini.com
 ([74.125.148.14]) with SMTP;	Mon, 01 Feb 2010 18:19:40 CST
Received: from localhost.localdomain ([127.0.0.1]:42924 "EHLO
        eddie.linux-mips.org" rhost-flags-OK-OK-OK-FAIL)        by
 eddie.linux-mips.org with ESMTP id S1492509Ab0BBATc (ORCPT
        <rfc822;andy.sharp@lsi.com>); Tue, 2 Feb 2010 01:19:32 +0100
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 02 Feb 2010 01:19:14
 +0100 (CET)
Received: from mgate.redback.com ([155.53.3.41]:18405 "EHLO mgate.redback.com"
        rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP        id
 S1492422Ab0BBATK (ORCPT <rfc822;linux-mips@linux-mips.org>);        Tue, 2
 Feb 2010 01:19:10 +0100
Received: from prattle.redback.com ([155.53.12.9])  by mgate.redback.com with
 ESMTP; 01 Feb 2010 16:19:07 -0800
Received: from localhost (localhost [127.0.0.1])        by prattle.redback.com
 (Postfix) with ESMTP id 2A670E3A68A;        Mon,  1 Feb 2010 16:19:07 -0800
 (PST)
Received: from prattle.redback.com ([127.0.0.1]) by localhost (prattle
 [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 06350-09; Mon,  1 Feb
 2010 16:19:07 -0800 (PST)
Received: from localhost (rbos-pc-13.lab.redback.com [10.12.11.133])        by
 prattle.redback.com (Postfix) with ESMTP id 18DF5E3A687;        Mon,  1 Feb
 2010 16:19:05 -0800 (PST)
From: Guenter Roeck <guenter.roeck@ericsson.com>
To: "linux-mips@linux-mips.org" <linux-mips@linux-mips.org>
CC: Guenter Roeck <guenter.roeck@ericsson.com>
Sender: "linux-mips-bounce@linux-mips.org" <linux-mips-bounce@linux-mips.org>
Date: Mon, 1 Feb 2010 17:02:59 -0700
Subject: [PATCH v4] Virtual memory size detection for 64 bit MIPS CPUs
Thread-Topic: [PATCH v4] Virtual memory size detection for 64 bit MIPS CPUs
Thread-Index: AcqjnWpLZFYUU2N6Roy3lL2Eabd+0A==
Message-ID: <1265068979-12052-1-git-send-email-guenter.roeck@ericsson.com>
Accept-Language: en-US
Content-Language: en-US
X-MS-Exchange-Organization-AuthAs: Anonymous
X-MS-Exchange-Organization-AuthSource: coscas01.lsi.com
X-MS-Has-Attach:
X-Auto-Response-Suppress: All
X-MS-TNEF-Correlator:
x-scanned-by: MIMEDefang 2.39
errors-to: linux-mips-bounce@linux-mips.org
x-pstn-levels: (S:76.44355/99.90000 CV:99.9000 FC:95.5390 LC:95.5390
 R:95.9108 P:95.9108 M:97.0282 C:98.6951 )
x-pstn-settings: 3 (1.0000:1.0000) s cv gt3 gt2 gt1 r p m c 
x-pstn-addresses: from <guenter.roeck@ericsson.com> [22/1] 
x-pstn-neptune: 0/0/0.00/0
x-ironport-av: E=Sophos;i="4.49,386,1262592000";    d="scan'208";a="7753395"
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0

Linux kernel 2.6.32 and later allocates memory from the top of virtual memo=
ry
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>
---
 arch/mips/include/asm/cpu-features.h |    3 +++
 arch/mips/include/asm/cpu-info.h     |    1 +
 arch/mips/include/asm/pgtable-64.h   |    4 +++-
 arch/mips/kernel/cpu-probe.c         |   12 ++++++++++++
 4 files changed, 19 insertions(+), 1 deletions(-)

diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/c=
pu-features.h
index 1f4df64..284eb55 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -209,6 +209,9 @@
 # ifndef cpu_has_64bit_addresses
 # define cpu_has_64bit_addresses	1
 # endif
+# ifndef cpu_vmbits
+# define cpu_vmbits cpu_data[0].vmbits
+# endif
 #endif
=20
 #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-i=
nfo.h
index 1260443..3c694bc 100644
--- a/arch/mips/include/asm/cpu-info.h
+++ b/arch/mips/include/asm/cpu-info.h
@@ -58,6 +58,7 @@ struct cpuinfo_mips {
 	struct cache_desc	tcache;	/* Tertiary/split secondary cache */
 	int			srsets;	/* Shadow register sets */
 	int			core;	/* physical core number */
+	int			vmbits;	/* Virtual memory size in bits */
 #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
 	/*
 	 * 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/pgt=
able-64.h
index 9cd5089..259ec58 100644
--- a/arch/mips/include/asm/pgtable-64.h
+++ b/arch/mips/include/asm/pgtable-64.h
@@ -110,7 +110,9 @@
 #define VMALLOC_START		MAP_BASE
 #define VMALLOC_END	\
 	(VMALLOC_START + \
-	 PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE - (1UL << 32))
+	 min(PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, \
+	     (1UL<<cpu_vmbits)) - (1UL << 32))
+
 #if defined(CONFIG_MODULES) && defined(KBUILD_64BIT_SYM32) && \
 	VMALLOC_START !=3D CKSSEG
 /* Load modules into 32bit-compatible segment. */
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 7a51866..ac9aca1 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -282,6 +282,16 @@ static inline int __cpu_has_fpu(void)
 	return ((cpu_get_fpu_id() & 0xff00) !=3D FPIR_IMP_NONE);
 }
=20
+static inline void cpu_set_vmbits(struct cpuinfo_mips *c)
+{
+	if (cpu_has_64bits) {
+		write_c0_entryhi(0xfffffffffffff000ULL);
+		back_to_back_c0_hazard();
+		c->vmbits =3D fls64(read_c0_entryhi() & 0x3ffffffffffff000ULL);
+	} else
+		c->vmbits =3D 32;
+}
+
 #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \
 		| MIPS_CPU_COUNTER)
=20
@@ -967,6 +977,8 @@ __cpuinit void cpu_probe(void)
 		c->srsets =3D ((read_c0_srsctl() >> 26) & 0x0f) + 1;
 	else
 		c->srsets =3D 1;
+
+	cpu_set_vmbits(c);
 }
=20
 __cpuinit void cpu_report(void)
--=20
1.6.0.4


