arm and patch phys offset
Russell King - ARM Linux
linux at arm.linux.org.uk
Mon Dec 12 16:57:36 EST 2011
On Mon, Dec 12, 2011 at 04:38:07PM -0500, Nicolas Pitre wrote:
> You could try instrumenting the patching code, although it is a bit
> tricky because of the non-standard register life rules in that file.
> But something like this should tell you if the expected amount of fixups
> were applied:
>
> diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
> index 08c82fd844..7f43d1fe01 100644
> --- a/arch/arm/kernel/head.S
> +++ b/arch/arm/kernel/head.S
> @@ -530,14 +530,23 @@ __fixup_a_pv_table:
> bcc 1b
> bx lr
> #else
> + mov r0, #0
> b 2f
> 1: ldr ip, [r7, r3]
> bic ip, ip, #0x000000ff
> orr ip, ip, r6 @ mask in offset bits 31-24
> str ip, [r7, r3]
> + add r0, r0, #1
> 2: cmp r4, r5
> ldrcc r7, [r4], #4 @ use branch for delay slot
> bcc 1b
If you look at this code, there is _no_ way it can fixup only some entries
in the table and not others - unless the CPU starts executing something
which isn't this code.
It quite simply loads the address of each entry in the table, incrementing
the pointer by a word size. It then _unconditionally_ loads, modifies
and stores the instruction at the location in question.
The termination condition is when r4 >= r5, which will prevent the loading
of the next pointer _and_ prevent the looping, thus terminating the fixup
altogether.
So, something else is going on. If I had to guess, I'd suspect the kernel
is being called with caches enabled - which violates the expectations of
the kernel set down many years ago.
More information about the linux-arm-kernel
mailing list