[RFC PATCH v3] ARM: Introduce patching of phys_to_virt and vice versa
Russell King - ARM Linux
linux at arm.linux.org.uk
Mon Nov 8 06:49:48 EST 2010
On Sat, Nov 06, 2010 at 02:40:46AM +0800, Eric Miao wrote:
> +__fixup_phys_virt:
> + /*
> + * r0 - PHYS_OFFSET
> + * r6 - bits to set in phys_to_virt stub instructions
> + * r7 - bits to set in virt_to_phys stub instructions
> + */
> + ldr r0, =PHYS_OFFSET
> + cmp r0, #PAGE_OFFSET
> + subhi r1, r0, #PAGE_OFFSET
> + rsbls r1, r0, #PAGE_OFFSET
> + lsr r1, r1, #24
> + orr r1, r1, #0x400
> + orrhi r6, r1, #PATCH_INSTR_SUB
> + orrhi r7, r1, #PATCH_INSTR_ADD
> + orrls r6, r1, #PATCH_INSTR_ADD
> + orrls r7, r1, #PATCH_INSTR_SUB
> +
> + /* r0 - instruction to patch
> + * r1 - address offset
> + * r2 - index into __patch_table
> + * r3 - __patch_table_end
> + */
> + adr r0, 1f
> + ldmia r0, {r1, r2, r3}
> + sub r1, r0, r1
Also note that r1 here is (PHYS_OFFSET - PAGE_OFFSET) - r0 was the physical
address of '1f', and the loaded value of r1 is the virtual address of '1f'.
So, I think the above code can be replaced by:
adr r0, 1f
ldmia r0, {r1-r3}
sub r1, r0, r1
mov r4, r1, lsr #24
orr r4, r4, #0x0400
orr r6, r4, #PATCH_INSTR_SUB
orr r7, r4, #PATCH_INSTR_ADD
teq r1, r4, lsl #24
bne error
noting that:
add rd, rn, #PAGE_OFFSET - PHYS_OFFSET
sub rd, rn, #PHYS_OFFSET - PAGE_OFFSET
are equivalent.
We can do better than this - just make sure that all virt_to_phys() are an
add instruction, and all phys_to_virt() are a sub struction. Then we only
need to fixup the constant. IOW, virt_to_phys() is:
add rd, rn, #PHYS_OFFSET - PAGE_OFFSET
and phys_to_virt() is:
sub rd, rn, #PHYS_OFFSET - PAGE_OFFSET
More information about the linux-arm-kernel
mailing list