ARM: P2V: introduce phys_to_virt/virt_to_phys runtime patching
Subsystems (4)
RFC 4/5 ARM: P2V: introduce phys_to_virt/virt_to_phys runtime patching
A warning for OMAP.
Your use of the __virt_to_phys() in assembly code for the debug stuff will break with this patch... please ensure that it is resolved by the next merge window.
----- Forwarded message from Russell King - ARM Linux <[email protected]> -----
Date: Tue, 04 Jan 2011 20:23:18 +0000
From: Russell King - ARM Linux <[email protected]>
To: Nicolas Pitre <[email protected]>
Cc: [email protected]
Subject: [RFC 4/5] ARM: P2V: introduce phys_to_virt/virt_to_phys runtime
patching
This idea came from Nicolas, Eric Miao produced an initial version, which was then rewritten into this.
Patch the physical to virtual translations at runtime. As we modify the code, this makes it incompatible with XIP kernels, but on allows is to achieve this with minimal loss of performance.
As many translations are of the form:
physical = virtual + (PHYS_OFFSET - PAGE_OFFSET) virtual = physical - (PHYS_OFFSET - PAGE_OFFSET)
we generate an 'add' instruction for __virt_to_phys(), and a 'sub' instruction for __phys_to_virt(). We calculate at run time (PHYS_OFFSET
- PAGE_OFFSET) by comparing the address prior to MMU initialization with where it should be once the MMU has been initialized, and place this constant into the above add/sub instructions.
Once we have (PHYS_OFFSET - PAGE_OFFSET), we can calcuate the real PHYS_OFFSET as PAGE_OFFSET is a build-time constant, and save this for the C-mode PHYS_OFFSET variable definition to use.
At present, we are unable to support Realview with Sparsemem enabled as this uses a complex mapping function, and MSM as this requires a constant which will not fit in our math instruction.
--- arch/arm/Kconfig | 14 +++++++++ arch/arm/include/asm/memory.h | 55 ++++++++++++++++++++++++++++-------- arch/arm/kernel/head.S | 63 +++++++++++++++++++++++++++++++++++++++++ arch/arm/kernel/module.c | 23 ++++++++++++++- arch/arm/kernel/setup.c | 2 +- arch/arm/kernel/vmlinux.lds.S | 4 ++ 6 files changed, 147 insertions(+), 14 deletions(-)
arch/arm/Kconfig +14 -0
@@ -196,6 +196,19 @@ config VECTORS_BASE help The base address of exception vectors. +config ARM_PATCH_PHYS_VIRT + bool "Patch physical to virtual translations at runtime (EXPERIMENTAL)" + depends on EXPERIMENTAL + depends on !XIP_KERNEL && !THUMB2_KERNEL && MMU + depends on !ARCH_MSM + depends on !ARCH_REALVIEW || !SPARSEMEM + help + Patch phys-to-virt translation functions at runtime according to + the position of the kernel in system memory. + + This can only be used with non-XIP, non-Thumb2, MMU kernels where + the base of physical memory is at a 16MB boundary. + source "init/Kconfig" source "kernel/Kconfig.freezer"
@@ -608,6 +621,7 @@ config ARCH_PXA select TICK_ONESHOT select PLAT_PXA select SPARSE_IRQ + select ARM_PATCH_PHYS_VIRT help Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
arch/arm/include/asm/memory.h +43 -12
73 lines not on this page · raw message
arch/arm/kernel/head.S +63 -0
73 lines not on this page · raw message
arch/arm/kernel/module.c +22 -1
@@ -276,12 +276,28 @@ struct mod_unwind_map {const Elf_Shdr *txt_sec; }; +static const Elf_Shdr *find_mod_section (const Elf32_Ehdr *hdr, +const Elf_Shdr *sechdrs,const char *name) +{ +const Elf_Shdr *s, *se; +const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; + +for (s = sechdrs, se = sechdrs + hdr->e_shnum; s < se; s++) +if (strcmp (name, secstrs + s->sh_name) ==0 ) +return s; + +return NULL ; +} + +extern void fixup_pv_table (const void *,unsigned long ); +int module_finalize (const Elf32_Ehdr *hdr,const Elf_Shdr *sechdrs,struct module *mod) { +const Elf_Shdr *s =NULL ;#ifdef CONFIG_ARM_UNWIND const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; -const Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum; +const Elf_Shdr *sechdrs_end = sechdrs + hdr->e_shnum;struct mod_unwind_map maps[ARM_SEC_MAX ];int i;
@@ -323,6 +339,11 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, maps[i].txt_sec->sh_addr, maps[i].txt_sec->sh_size);#endif +#ifdef CONFIG_ARM_PATCH_PHYS_VIRT + s =find_mod_section (hdr, sechdrs,".pv_table" ); +if (s) +fixup_pv_table ((void *)s->sh_addr, s->sh_size); +#endif return 0 ; }
arch/arm/kernel/setup.c +1 -1
@@ -804,7 +804,7 @@ void __init setup_arch(char **cmdline_p)struct machine_desc *mdesc;char *from = default_command_line; - tags->mem.start =PHYS_OFFSET ; + init_tags.mem.start =PHYS_OFFSET ;unwind_init ();
arch/arm/kernel/vmlinux.lds.S +4 -0
@@ -57,6 +57,10 @@ SECTIONS __smpalt_end = .; #endif + __pv_table_begin = .; + *(.pv_table) + __pv_table_end = .; + INIT_SETUP(16) INIT_CALLS
Signature · 1 line
1.6.2.5
Tony Lindgren
maintainerQuoted 5 lines · Russell King - ARM Linux
A warning for OMAP.
Your use of the
__virt_to_phys()in assembly code for the debug stuff will break with this patch... please ensure that it is resolved by the next merge window.
Sure thanks. I'm aware of this series, will take care of it.
Tony
Tony Lindgren
maintainerPATCH 1/1 omap: Fix DEBUG_LL code for p2v changes (Re: Fwd: [RFC 4/5] ARM: P2V: introduce phys_to_virt/virt_to_phys runtime patching)
Quoted 8 lines · Tony Lindgren
Quoted 5 lines · Russell King - ARM Linux
A warning for OMAP.
Your use of the
__virt_to_phys()in assembly code for the debug stuff will break with this patch... please ensure that it is resolved by the next merge window.Sure thanks. I'm aware of this series, will take care of it.
Here's a minimal fix for your p2v branch. Will send more DEBUG_LL related patches in a separate series.
Regards,
Tony
From: Tony Lindgren <[email protected]>
Date: Thu, 3 Feb 2011 15:17:44 -0800
Subject: [PATCH] omap: Fix DEBUG_LL code for p2v changes
These are needed for CONFIG_ARM_PATCH_PHYS_VIRT to work.
arch/arm/mach-omap1/include/mach/debug-macro.S +6 -3
@@ -17,6 +17,9 @@ #include <plat/serial.h> +#define omap_uart_v2p(x) ((x) - PAGE_OFFSET + PLAT_PHYS_OFFSET) +#define omap_uart_p2v(x) ((x) - PLAT_PHYS_OFFSET + PAGE_OFFSET) + .pushsection .data omap_uart_phys: .word 0x0 omap_uart_virt: .word 0x0
@@ -33,7 +36,7 @@ omap_uart_virt: .word 0x0 /* Use omap_uart_phys/virt if already configured */ 9: mrc p15, 0, \rp, c1, c0 tst \rp, #1 @ MMU enabled? - ldreq \rp, =__virt_to_phys(omap_uart_phys) @ MMU not enabled + ldreq \rp, =omap_uart_v2p(omap_uart_phys) @ MMU disabled ldrne \rp, =omap_uart_phys @ MMU enabled add \rv, \rp, #4 @ omap_uart_virt ldr \rp, [\rp, #0]
@@ -46,7 +49,7 @@ omap_uart_virt: .word 0x0 mrc p15, 0, \rp, c1, c0 tst \rp, #1 @ MMU enabled? ldreq \rp, =OMAP_UART_INFO @ MMU not enabled - ldrne \rp, =__phys_to_virt(OMAP_UART_INFO) @ MMU enabled + ldrne \rp, =omap_uart_p2v(OMAP_UART_INFO) @ MMU enabled ldr \rp, [\rp, #0] /* Select the UART to use based on the UART1 scratchpad value */
@@ -73,7 +76,7 @@ omap_uart_virt: .word 0x0 98: add \rp, \rp, #0xff000000 @ phys base mrc p15, 0, \rv, c1, c0 tst \rv, #1 @ MMU enabled? - ldreq \rv, =__virt_to_phys(omap_uart_phys) @ MMU not enabled + ldreq \rv, =omap_uart_v2p(omap_uart_phys) @ MMU disabled ldrne \rv, =omap_uart_phys @ MMU enabled str \rp, [\rv, #0] sub \rp, \rp, #0xff000000 @ phys base
arch/arm/mach-omap2/include/mach/debug-macro.S +8 -5
@@ -19,6 +19,9 @@ #define UART_OFFSET(addr) ((addr) & 0x00ffffff) +#define omap_uart_v2p(x) ((x) - PAGE_OFFSET + PLAT_PHYS_OFFSET) +#define omap_uart_p2v(x) ((x) - PLAT_PHYS_OFFSET + PAGE_OFFSET) + .pushsection .data omap_uart_phys: .word 0 omap_uart_virt: .word 0
@@ -36,7 +39,7 @@ omap_uart_lsr: .word 0 /* Use omap_uart_phys/virt if already configured */ 10: mrc p15, 0, \rp, c1, c0 tst \rp, #1 @ MMU enabled? - ldreq \rp, =__virt_to_phys(omap_uart_phys) @ MMU not enabled + ldreq \rp, =omap_uart_v2p(omap_uart_phys) @ MMU disabled ldrne \rp, =omap_uart_phys @ MMU enabled add \rv, \rp, #4 @ omap_uart_virt ldr \rp, [\rp, #0]
@@ -49,7 +52,7 @@ omap_uart_lsr: .word 0 mrc p15, 0, \rp, c1, c0 tst \rp, #1 @ MMU enabled? ldreq \rp, =OMAP_UART_INFO @ MMU not enabled - ldrne \rp, =__phys_to_virt(OMAP_UART_INFO) @ MMU enabled + ldrne \rp, =omap_uart_p2v(OMAP_UART_INFO) @ MMU enabled ldr \rp, [\rp, #0] /* Select the UART to use based on the UART1 scratchpad value */
@@ -94,7 +97,7 @@ omap_uart_lsr: .word 0 95: ldr \rp, =ZOOM_UART_BASE mrc p15, 0, \rv, c1, c0 tst \rv, #1 @ MMU enabled? - ldreq \rv, =__virt_to_phys(omap_uart_phys) @ MMU not enabled + ldreq \rv, =omap_uart_v2p(omap_uart_phys) @ MMU disabled ldrne \rv, =omap_uart_phys @ MMU enabled str \rp, [\rv, #0] ldr \rp, =ZOOM_UART_VIRT
@@ -109,7 +112,7 @@ omap_uart_lsr: .word 0 98: add \rp, \rp, #0x48000000 @ phys base mrc p15, 0, \rv, c1, c0 tst \rv, #1 @ MMU enabled? - ldreq \rv, =__virt_to_phys(omap_uart_phys) @ MMU not enabled + ldreq \rv, =omap_uart_v2p(omap_uart_phys) @ MMU disabled ldrne \rv, =omap_uart_phys @ MMU enabled str \rp, [\rv, #0] sub \rp, \rp, #0x48000000 @ phys base
@@ -131,7 +134,7 @@ omap_uart_lsr: .word 0 .macro busyuart,rd,rx 1001: mrc p15, 0, \rd, c1, c0 tst \rd, #1 @ MMU enabled? - ldreq \rd, =__virt_to_phys(omap_uart_lsr) @ MMU not enabled + ldreq \rd, =omap_uart_v2p(omap_uart_lsr) @ MMU disabled ldrne \rd, =omap_uart_lsr @ MMU enabled ldr \rd, [\rd, #0] ldrb \rd, [\rx, \rd]
Re: [PATCH] omap: Fix DEBUG_LL code for p2v changes (Re: Fwd: [RFC 4/5] ARM: P2V: introduce phys_to_virt/virt_to_phys runtime patching)
Quoted 4 lines · Tony Lindgren
Quoted 3 lines · Tony Lindgren
Quoted 2 lines · Russell King - ARM Linux
A warning for OMAP.
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
Your use of the
__virt_to_phys()in assembly code for the debug stuff will break with this patch... please ensure that it is resolved by the next merge window.Sure thanks. I'm aware of this series, will take care of it.
Here's a minimal fix for your p2v branch. Will send more
DEBUG_LLrelated patches in a separate series.
Could you please provide some acks/tested bys for the p2v stuff?
Thanks.
Tony Lindgren
maintainerRe: [PATCH] omap: Fix DEBUG_LL code for p2v changes (Re: Fwd: [RFC 4/5] ARM: P2V: introduce phys_to_virt/virt_to_phys runtime patching)
Quoted 9 lines · Russell King - ARM Linux
Quoted 8 lines · Tony Lindgren
Quoted 7 lines · Tony Lindgren
Quoted 5 lines · Russell King - ARM Linux
A warning for OMAP.
Your use of the
__virt_to_phys()in assembly code for the debug stuff will break with this patch... please ensure that it is resolved by the next merge window.
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
Sure thanks. I'm aware of this series, will take care of it.
Here's a minimal fix for your p2v branch. Will send more
DEBUG_LLrelated patches in a separate series.Could you please provide some acks/tested bys for the p2v stuff?
Sorry was out of town for the weekend, will reply with acks.
Tony