diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2010-09-13 11:03:21 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-11-04 11:44:31 -0400 |
commit | 247055aa21ffef1c49dd64710d5e94c2aee19b58 (patch) | |
tree | e9e026b96597d080de4c16bb88c17b0495c61904 /arch/arm/include/asm/assembler.h | |
parent | ff8b16d7e15a8ba2a6086645614a483e048e3fbf (diff) |
ARM: 6384/1: Remove the domain switching on ARMv6k/v7 CPUs
This patch removes the domain switching functionality via the set_fs and
__switch_to functions on cores that have a TLS register.
Currently, the ioremap and vmalloc areas share the same level 1 page
tables and therefore have the same domain (DOMAIN_KERNEL). When the
kernel domain is modified from Client to Manager (via the __set_fs or in
the __switch_to function), the XN (eXecute Never) bit is overridden and
newer CPUs can speculatively prefetch the ioremap'ed memory.
Linux performs the kernel domain switching to allow user-specific
functions (copy_to/from_user, get/put_user etc.) to access kernel
memory. In order for these functions to work with the kernel domain set
to Client, the patch modifies the LDRT/STRT and related instructions to
the LDR/STR ones.
The user pages access rights are also modified for kernel read-only
access rather than read/write so that the copy-on-write mechanism still
works. CPU_USE_DOMAINS gets disabled only if the hardware has a TLS register
(CPU_32v6K is defined) since writing the TLS value to the high vectors page
isn't possible.
The user addresses passed to the kernel are checked by the access_ok()
function so that they do not point to the kernel space.
Tested-by: Anton Vorontsov <cbouatmailru@gmail.com>
Cc: Tony Lindgren <tony@atomide.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/include/asm/assembler.h')
-rw-r--r-- | arch/arm/include/asm/assembler.h | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 062b58c029ab..4e84d09c9c1b 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #endif | 18 | #endif |
19 | 19 | ||
20 | #include <asm/ptrace.h> | 20 | #include <asm/ptrace.h> |
21 | #include <asm/domain.h> | ||
21 | 22 | ||
22 | /* | 23 | /* |
23 | * Endian independent macros for shifting bytes within registers. | 24 | * Endian independent macros for shifting bytes within registers. |
@@ -206,12 +207,12 @@ | |||
206 | */ | 207 | */ |
207 | #ifdef CONFIG_THUMB2_KERNEL | 208 | #ifdef CONFIG_THUMB2_KERNEL |
208 | 209 | ||
209 | .macro usraccoff, instr, reg, ptr, inc, off, cond, abort | 210 | .macro usraccoff, instr, reg, ptr, inc, off, cond, abort, t=T() |
210 | 9999: | 211 | 9999: |
211 | .if \inc == 1 | 212 | .if \inc == 1 |
212 | \instr\cond\()bt \reg, [\ptr, #\off] | 213 | \instr\cond\()b\()\t\().w \reg, [\ptr, #\off] |
213 | .elseif \inc == 4 | 214 | .elseif \inc == 4 |
214 | \instr\cond\()t \reg, [\ptr, #\off] | 215 | \instr\cond\()\t\().w \reg, [\ptr, #\off] |
215 | .else | 216 | .else |
216 | .error "Unsupported inc macro argument" | 217 | .error "Unsupported inc macro argument" |
217 | .endif | 218 | .endif |
@@ -246,13 +247,13 @@ | |||
246 | 247 | ||
247 | #else /* !CONFIG_THUMB2_KERNEL */ | 248 | #else /* !CONFIG_THUMB2_KERNEL */ |
248 | 249 | ||
249 | .macro usracc, instr, reg, ptr, inc, cond, rept, abort | 250 | .macro usracc, instr, reg, ptr, inc, cond, rept, abort, t=T() |
250 | .rept \rept | 251 | .rept \rept |
251 | 9999: | 252 | 9999: |
252 | .if \inc == 1 | 253 | .if \inc == 1 |
253 | \instr\cond\()bt \reg, [\ptr], #\inc | 254 | \instr\cond\()b\()\t \reg, [\ptr], #\inc |
254 | .elseif \inc == 4 | 255 | .elseif \inc == 4 |
255 | \instr\cond\()t \reg, [\ptr], #\inc | 256 | \instr\cond\()\t \reg, [\ptr], #\inc |
256 | .else | 257 | .else |
257 | .error "Unsupported inc macro argument" | 258 | .error "Unsupported inc macro argument" |
258 | .endif | 259 | .endif |