aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm/cache.c
diff options
context:
space:
mode:
authorDavid Daney <ddaney@caviumnetworks.com>2010-02-10 18:12:47 -0500
committerRalf Baechle <ralf@linux-mips.org>2010-02-27 06:53:26 -0500
commit6dd9344cfc41bcc60a01cdc828cb278be7a10e01 (patch)
tree9c62d563eba8f3acfd1c826a63e6999261b06f5a /arch/mips/mm/cache.c
parent32546f38fab839eee6f62b3f06c2774eade4188a (diff)
MIPS: Implement Read Inhibit/eXecute Inhibit
The SmartMIPS ASE specifies how Read Inhibit (RI) and eXecute Inhibit (XI) bits in the page tables work. The upper two bits of EntryLo{0,1} are RI and XI when the feature is enabled in the PageGrain register. SmartMIPS only covers 32-bit systems. Cavium Octeon+ extends this to 64-bit systems by continuing to place the RI and XI bits in the top of EntryLo even when EntryLo is 64-bits wide. Because we need to carry the RI and XI bits in the PTE, the layout of the PTE is changed. There is a two instruction overhead in the TLB refill hot path to get the EntryLo bits into the proper position. Also the TLB load exception has to probe the TLB to check if RI or XI caused the exception. Also of note is that the layout of the PTE bits is done at compile and runtime rather than statically. In the 32-bit case this allows for the same number of PFN bits as before the patch as the _PAGE_HUGE is not supported in 32-bit kernels (we have _PAGE_NO_EXEC and _PAGE_NO_READ instead of _PAGE_READ and _PAGE_HUGE). The patch is tested on Cavium Octeon+, but should also work on 32-bit systems with the Smart-MIPS ASE. Signed-off-by: David Daney <ddaney@caviumnetworks.com> To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/952/ Patchwork: http://patchwork.linux-mips.org/patch/956/ Patchwork: http://patchwork.linux-mips.org/patch/962/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mm/cache.c')
-rw-r--r--arch/mips/mm/cache.c53
1 files changed, 37 insertions, 16 deletions
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index e716cafc346d..be8627bc5b02 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -137,22 +137,43 @@ EXPORT_SYMBOL_GPL(_page_cachable_default);
137 137
138static inline void setup_protection_map(void) 138static inline void setup_protection_map(void)
139{ 139{
140 protection_map[0] = PAGE_NONE; 140 if (kernel_uses_smartmips_rixi) {
141 protection_map[1] = PAGE_READONLY; 141 protection_map[0] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
142 protection_map[2] = PAGE_COPY; 142 protection_map[1] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
143 protection_map[3] = PAGE_COPY; 143 protection_map[2] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
144 protection_map[4] = PAGE_READONLY; 144 protection_map[3] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
145 protection_map[5] = PAGE_READONLY; 145 protection_map[4] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_READ);
146 protection_map[6] = PAGE_COPY; 146 protection_map[5] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
147 protection_map[7] = PAGE_COPY; 147 protection_map[6] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_READ);
148 protection_map[8] = PAGE_NONE; 148 protection_map[7] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
149 protection_map[9] = PAGE_READONLY; 149
150 protection_map[10] = PAGE_SHARED; 150 protection_map[8] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
151 protection_map[11] = PAGE_SHARED; 151 protection_map[9] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
152 protection_map[12] = PAGE_READONLY; 152 protection_map[10] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | _PAGE_NO_READ);
153 protection_map[13] = PAGE_READONLY; 153 protection_map[11] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
154 protection_map[14] = PAGE_SHARED; 154 protection_map[12] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_READ);
155 protection_map[15] = PAGE_SHARED; 155 protection_map[13] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
156 protection_map[14] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE | _PAGE_NO_READ);
157 protection_map[15] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE);
158
159 } else {
160 protection_map[0] = PAGE_NONE;
161 protection_map[1] = PAGE_READONLY;
162 protection_map[2] = PAGE_COPY;
163 protection_map[3] = PAGE_COPY;
164 protection_map[4] = PAGE_READONLY;
165 protection_map[5] = PAGE_READONLY;
166 protection_map[6] = PAGE_COPY;
167 protection_map[7] = PAGE_COPY;
168 protection_map[8] = PAGE_NONE;
169 protection_map[9] = PAGE_READONLY;
170 protection_map[10] = PAGE_SHARED;
171 protection_map[11] = PAGE_SHARED;
172 protection_map[12] = PAGE_READONLY;
173 protection_map[13] = PAGE_READONLY;
174 protection_map[14] = PAGE_SHARED;
175 protection_map[15] = PAGE_SHARED;
176 }
156} 177}
157 178
158void __cpuinit cpu_cache_init(void) 179void __cpuinit cpu_cache_init(void)