aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig5
-rw-r--r--arch/arm/include/asm/memory.h21
-rw-r--r--arch/arm/include/asm/module.h4
-rw-r--r--arch/arm/kernel/head.S15
4 files changed, 39 insertions, 6 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4147f76e7988..b357c29e7dfc 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -195,7 +195,6 @@ config ARM_PATCH_PHYS_VIRT
195 bool "Patch physical to virtual translations at runtime (EXPERIMENTAL)" 195 bool "Patch physical to virtual translations at runtime (EXPERIMENTAL)"
196 depends on EXPERIMENTAL 196 depends on EXPERIMENTAL
197 depends on !XIP_KERNEL && !THUMB2_KERNEL && MMU 197 depends on !XIP_KERNEL && !THUMB2_KERNEL && MMU
198 depends on !ARCH_MSM
199 depends on !ARCH_REALVIEW || !SPARSEMEM 198 depends on !ARCH_REALVIEW || !SPARSEMEM
200 help 199 help
201 Patch phys-to-virt translation functions at runtime according to 200 Patch phys-to-virt translation functions at runtime according to
@@ -204,6 +203,10 @@ config ARM_PATCH_PHYS_VIRT
204 This can only be used with non-XIP, non-Thumb2, MMU kernels where 203 This can only be used with non-XIP, non-Thumb2, MMU kernels where
205 the base of physical memory is at a 16MB boundary. 204 the base of physical memory is at a 16MB boundary.
206 205
206config ARM_PATCH_PHYS_VIRT_16BIT
207 def_bool y
208 depends on ARM_PATCH_PHYS_VIRT && ARCH_MSM
209
207source "init/Kconfig" 210source "init/Kconfig"
208 211
209source "kernel/Kconfig.freezer" 212source "kernel/Kconfig.freezer"
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 7197879e1cb7..2398b3fc0268 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -154,29 +154,42 @@
154#ifndef __virt_to_phys 154#ifndef __virt_to_phys
155#ifdef CONFIG_ARM_PATCH_PHYS_VIRT 155#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
156 156
157/*
158 * Constants used to force the right instruction encodings and shifts
159 * so that all we need to do is modify the 8-bit constant field.
160 */
161#define __PV_BITS_31_24 0x81000000
162#define __PV_BITS_23_16 0x00810000
163
157extern unsigned long __pv_phys_offset; 164extern unsigned long __pv_phys_offset;
158#define PHYS_OFFSET __pv_phys_offset 165#define PHYS_OFFSET __pv_phys_offset
159 166
160#define __pv_stub(from,to,instr) \ 167#define __pv_stub(from,to,instr,type) \
161 __asm__("@ __pv_stub\n" \ 168 __asm__("@ __pv_stub\n" \
162 "1: " instr " %0, %1, %2\n" \ 169 "1: " instr " %0, %1, %2\n" \
163 " .pushsection .pv_table,\"a\"\n" \ 170 " .pushsection .pv_table,\"a\"\n" \
164 " .long 1b\n" \ 171 " .long 1b\n" \
165 " .popsection\n" \ 172 " .popsection\n" \
166 : "=r" (to) \ 173 : "=r" (to) \
167 : "r" (from), "I" (0x81000000)) 174 : "r" (from), "I" (type))
168 175
169static inline unsigned long __virt_to_phys(unsigned long x) 176static inline unsigned long __virt_to_phys(unsigned long x)
170{ 177{
171 unsigned long t; 178 unsigned long t;
172 __pv_stub(x, t, "add"); 179 __pv_stub(x, t, "add", __PV_BITS_31_24);
180#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
181 __pv_stub(t, t, "add", __PV_BITS_23_16);
182#endif
173 return t; 183 return t;
174} 184}
175 185
176static inline unsigned long __phys_to_virt(unsigned long x) 186static inline unsigned long __phys_to_virt(unsigned long x)
177{ 187{
178 unsigned long t; 188 unsigned long t;
179 __pv_stub(x, t, "sub"); 189 __pv_stub(x, t, "sub", __PV_BITS_31_24);
190#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
191 __pv_stub(t, t, "sub", __PV_BITS_23_16);
192#endif
180 return t; 193 return t;
181} 194}
182#else 195#else
diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h
index d072c21332ee..a2b775b81cfa 100644
--- a/arch/arm/include/asm/module.h
+++ b/arch/arm/include/asm/module.h
@@ -31,7 +31,11 @@ struct mod_arch_specific {
31 31
32/* Add __virt_to_phys patching state as well */ 32/* Add __virt_to_phys patching state as well */
33#ifdef CONFIG_ARM_PATCH_PHYS_VIRT 33#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
34#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
35#define MODULE_ARCH_VERMAGIC_P2V "p2v16 "
36#else
34#define MODULE_ARCH_VERMAGIC_P2V "p2v8 " 37#define MODULE_ARCH_VERMAGIC_P2V "p2v8 "
38#endif
35#else 39#else
36#define MODULE_ARCH_VERMAGIC_P2V "" 40#define MODULE_ARCH_VERMAGIC_P2V ""
37#endif 41#endif
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 1db8ead2e331..a94dd99d54c3 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -456,8 +456,13 @@ __fixup_pv_table:
456 add r4, r4, r3 @ adjust table start address 456 add r4, r4, r3 @ adjust table start address
457 add r5, r5, r3 @ adjust table end address 457 add r5, r5, r3 @ adjust table end address
458 str r8, [r7, r3]! @ save computed PHYS_OFFSET to __pv_phys_offset 458 str r8, [r7, r3]! @ save computed PHYS_OFFSET to __pv_phys_offset
459#ifndef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
459 mov r6, r3, lsr #24 @ constant for add/sub instructions 460 mov r6, r3, lsr #24 @ constant for add/sub instructions
460 teq r3, r6, lsl #24 @ must be 16MiB aligned 461 teq r3, r6, lsl #24 @ must be 16MiB aligned
462#else
463 mov r6, r3, lsr #16 @ constant for add/sub instructions
464 teq r3, r6, lsl #16 @ must be 64kiB aligned
465#endif
461 bne __error 466 bne __error
462 str r6, [r7, #4] @ save to __pv_offset 467 str r6, [r7, #4] @ save to __pv_offset
463 b __fixup_a_pv_table 468 b __fixup_a_pv_table
@@ -471,10 +476,18 @@ ENDPROC(__fixup_pv_table)
471 476
472 .text 477 .text
473__fixup_a_pv_table: 478__fixup_a_pv_table:
479#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
480 and r0, r6, #255 @ offset bits 23-16
481 mov r6, r6, lsr #8 @ offset bits 31-24
482#else
483 mov r0, #0 @ just in case...
484#endif
474 b 3f 485 b 3f
4752: ldr ip, [r7, r3] 4862: ldr ip, [r7, r3]
476 bic ip, ip, #0x000000ff 487 bic ip, ip, #0x000000ff
477 orr ip, ip, r6 488 tst ip, #0x400 @ rotate shift tells us LS or MS byte
489 orrne ip, ip, r6 @ mask in offset bits 31-24
490 orreq ip, ip, r0 @ mask in offset bits 23-16
478 str ip, [r7, r3] 491 str ip, [r7, r3]
4793: cmp r4, r5 4923: cmp r4, r5
480 ldrcc r7, [r4], #4 @ use branch for delay slot 493 ldrcc r7, [r4], #4 @ use branch for delay slot