* [PATCH] arm: proc-v7: pc phy addresses before disable MMU
@ 2011-09-24 8:02 Per Forlin
2011-09-24 8:06 ` Russell King - ARM Linux
2011-09-24 8:13 ` Mika Westerberg
0 siblings, 2 replies; 12+ messages in thread
From: Per Forlin @ 2011-09-24 8:02 UTC (permalink / raw)
To: linux-arm-kernel
PC runs virtual addresses when calling cpu_v7_reset(). The MMU
is switched off and "mov pc, r0" sets pc back to
virtual addresses even though the MMU is switched off.
This will result in a crash if the pipeline delay after
MMU disable is one instruction. To prevent this set PC
to physical addresses before disabling the MMU.
Signed-off-by: Per Fransson <per.xx.fransson@stericsson.com>
Signed-off-by: Per Forlin <per.forlin@stericsson.com>
---
arch/arm/mm/proc-v7.S | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 9049c07..f26e831 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -64,6 +64,7 @@ ENDPROC(cpu_v7_proc_fin)
*/
.align 5
ENTRY(cpu_v7_reset)
+ sub pc, pc, #PAGE_OFFSET+4 @ go to physical addresses
mrc p15, 0, r1, c1, c0, 0 @ ctrl register
bic r1, r1, #0x1 @ ...............m
THUMB( bic r1, r1, #1 << 30 ) @ SCTLR.TE (Thumb exceptions)
--
1.6.3.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH] arm: proc-v7: pc phy addresses before disable MMU
2011-09-24 8:02 [PATCH] arm: proc-v7: pc phy addresses before disable MMU Per Forlin
@ 2011-09-24 8:06 ` Russell King - ARM Linux
2011-09-24 8:13 ` Mika Westerberg
1 sibling, 0 replies; 12+ messages in thread
From: Russell King - ARM Linux @ 2011-09-24 8:06 UTC (permalink / raw)
To: linux-arm-kernel
On Sat, Sep 24, 2011 at 10:02:50AM +0200, Per Forlin wrote:
> PC runs virtual addresses when calling cpu_v7_reset(). The MMU
> is switched off and "mov pc, r0" sets pc back to
> virtual addresses even though the MMU is switched off.
> This will result in a crash if the pipeline delay after
> MMU disable is one instruction. To prevent this set PC
> to physical addresses before disabling the MMU.
This is broken - it assumes physical memory starts at zero. That's
not the case for many platforms.
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] arm: proc-v7: pc phy addresses before disable MMU
2011-09-24 8:02 [PATCH] arm: proc-v7: pc phy addresses before disable MMU Per Forlin
2011-09-24 8:06 ` Russell King - ARM Linux
@ 2011-09-24 8:13 ` Mika Westerberg
2011-09-24 9:32 ` Per Förlin
1 sibling, 1 reply; 12+ messages in thread
From: Mika Westerberg @ 2011-09-24 8:13 UTC (permalink / raw)
To: linux-arm-kernel
On Sat, Sep 24, 2011 at 10:02:50AM +0200, Per Forlin wrote:
> PC runs virtual addresses when calling cpu_v7_reset(). The MMU
> is switched off and "mov pc, r0" sets pc back to
> virtual addresses even though the MMU is switched off.
> This will result in a crash if the pipeline delay after
> MMU disable is one instruction. To prevent this set PC
> to physical addresses before disabling the MMU.
>
> Signed-off-by: Per Fransson <per.xx.fransson@stericsson.com>
> Signed-off-by: Per Forlin <per.forlin@stericsson.com>
> ---
> arch/arm/mm/proc-v7.S | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
> index 9049c07..f26e831 100644
> --- a/arch/arm/mm/proc-v7.S
> +++ b/arch/arm/mm/proc-v7.S
> @@ -64,6 +64,7 @@ ENDPROC(cpu_v7_proc_fin)
> */
> .align 5
> ENTRY(cpu_v7_reset)
> + sub pc, pc, #PAGE_OFFSET+4 @ go to physical addresses
This only works on machines where PHYS_OFFSET is zero.
IIRC, there is a P<->V offset calculated at boot time. Maybe you could use
that instead here?
> mrc p15, 0, r1, c1, c0, 0 @ ctrl register
> bic r1, r1, #0x1 @ ...............m
> THUMB( bic r1, r1, #1 << 30 ) @ SCTLR.TE (Thumb exceptions)
> --
> 1.6.3.3
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] arm: proc-v7: pc phy addresses before disable MMU
2011-09-24 8:13 ` Mika Westerberg
@ 2011-09-24 9:32 ` Per Förlin
2011-09-24 11:00 ` Will Deacon
2011-10-03 14:32 ` Dave Martin
0 siblings, 2 replies; 12+ messages in thread
From: Per Förlin @ 2011-09-24 9:32 UTC (permalink / raw)
To: linux-arm-kernel
On 09/24/2011 10:13 AM, Mika Westerberg wrote:
> On Sat, Sep 24, 2011 at 10:02:50AM +0200, Per Forlin wrote:
>> PC runs virtual addresses when calling cpu_v7_reset(). The MMU
>> is switched off and "mov pc, r0" sets pc back to
>> virtual addresses even though the MMU is switched off.
>> This will result in a crash if the pipeline delay after
>> MMU disable is one instruction. To prevent this set PC
>> to physical addresses before disabling the MMU.
>>
>> Signed-off-by: Per Fransson <per.xx.fransson@stericsson.com>
>> Signed-off-by: Per Forlin <per.forlin@stericsson.com>
>> ---
>> arch/arm/mm/proc-v7.S | 1 +
>> 1 files changed, 1 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
>> index 9049c07..f26e831 100644
>> --- a/arch/arm/mm/proc-v7.S
>> +++ b/arch/arm/mm/proc-v7.S
>> @@ -64,6 +64,7 @@ ENDPROC(cpu_v7_proc_fin)
>> */
>> .align 5
>> ENTRY(cpu_v7_reset)
>> + sub pc, pc, #PAGE_OFFSET+4 @ go to physical addresses
>
> This only works on machines where PHYS_OFFSET is zero.
>
You are right! Russell was very quick to point out the same thing.
> IIRC, there is a P<->V offset calculated at boot time. Maybe you could use
> that instead here?
>
I am trying to figure out how I can get the value of PHYS_OFFSET in assembler code (proc-v7.S).
I guess I could use the value calculated in arch/arm/kernel.head.S but wouldn't that make
this patch dependent on CONFIG_ARM_PATCH_PHYS_VIRT?
Regards,
Per
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] arm: proc-v7: pc phy addresses before disable MMU
2011-09-24 9:32 ` Per Förlin
@ 2011-09-24 11:00 ` Will Deacon
2011-09-24 12:55 ` Per Förlin
2011-10-03 14:32 ` Dave Martin
1 sibling, 1 reply; 12+ messages in thread
From: Will Deacon @ 2011-09-24 11:00 UTC (permalink / raw)
To: linux-arm-kernel
On Sat, Sep 24, 2011 at 10:32:48AM +0100, Per F?rlin wrote:
> I am trying to figure out how I can get the value of PHYS_OFFSET in assembler code (proc-v7.S).
> I guess I could use the value calculated in arch/arm/kernel.head.S but wouldn't that make
> this patch dependent on CONFIG_ARM_PATCH_PHYS_VIRT?
Wouldn't we just be better off passing a physical address to cpu_v7_reset
instead?
Will
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] arm: proc-v7: pc phy addresses before disable MMU
2011-09-24 11:00 ` Will Deacon
@ 2011-09-24 12:55 ` Per Förlin
2011-09-24 13:02 ` Russell King - ARM Linux
0 siblings, 1 reply; 12+ messages in thread
From: Per Förlin @ 2011-09-24 12:55 UTC (permalink / raw)
To: linux-arm-kernel
On 09/24/2011 01:00 PM, Will Deacon wrote:
> On Sat, Sep 24, 2011 at 10:32:48AM +0100, Per F?rlin wrote:
>> I am trying to figure out how I can get the value of PHYS_OFFSET in assembler code (proc-v7.S).
>> I guess I could use the value calculated in arch/arm/kernel.head.S but wouldn't that make
>> this patch dependent on CONFIG_ARM_PATCH_PHYS_VIRT?
>
> Wouldn't we just be better off passing a physical address to cpu_v7_reset
> instead?
>
Good point! I'm fine with that.
/Per
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] arm: proc-v7: pc phy addresses before disable MMU
2011-09-24 12:55 ` Per Förlin
@ 2011-09-24 13:02 ` Russell King - ARM Linux
2011-09-30 5:37 ` Per Förlin
0 siblings, 1 reply; 12+ messages in thread
From: Russell King - ARM Linux @ 2011-09-24 13:02 UTC (permalink / raw)
To: linux-arm-kernel
On Sat, Sep 24, 2011 at 02:55:42PM +0200, Per F?rlin wrote:
> On 09/24/2011 01:00 PM, Will Deacon wrote:
> > On Sat, Sep 24, 2011 at 10:32:48AM +0100, Per F?rlin wrote:
> >> I am trying to figure out how I can get the value of PHYS_OFFSET in assembler code (proc-v7.S).
> >> I guess I could use the value calculated in arch/arm/kernel.head.S but wouldn't that make
> >> this patch dependent on CONFIG_ARM_PATCH_PHYS_VIRT?
> >
> > Wouldn't we just be better off passing a physical address to cpu_v7_reset
> > instead?
> >
> Good point! I'm fine with that.
Alternatively, call it using the phys address.
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] arm: proc-v7: pc phy addresses before disable MMU
2011-09-24 13:02 ` Russell King - ARM Linux
@ 2011-09-30 5:37 ` Per Förlin
2011-09-30 8:34 ` Will Deacon
0 siblings, 1 reply; 12+ messages in thread
From: Per Förlin @ 2011-09-30 5:37 UTC (permalink / raw)
To: linux-arm-kernel
On 09/24/2011 03:02 PM, Russell King - ARM Linux wrote:
> On Sat, Sep 24, 2011 at 02:55:42PM +0200, Per F?rlin wrote:
>> On 09/24/2011 01:00 PM, Will Deacon wrote:
>>> On Sat, Sep 24, 2011 at 10:32:48AM +0100, Per F?rlin wrote:
>>>> I am trying to figure out how I can get the value of PHYS_OFFSET in assembler code (proc-v7.S).
>>>> I guess I could use the value calculated in arch/arm/kernel.head.S but wouldn't that make
>>>> this patch dependent on CONFIG_ARM_PATCH_PHYS_VIRT?
>>>
>>> Wouldn't we just be better off passing a physical address to cpu_v7_reset
>>> instead?
>>>
>> Good point! I'm fine with that.
>
> Alternatively, call it using the phys address.
I changed the code to use a label instead of the ARM specific instruction offset +4. A few more lines but the intention is that it should work with both ARM and THUMB. I'm in favour of Russell's idea of setting pc to physical before calling cpu_reset().
/* Go to physical addresses to be ready for MMU disable */
asm("ADR r1, pc_phy_here \n\t"
"sub r1, %0 \n\t"
"mov pc, r1 \n\t"
"pc_phy_here: \n\t"
: :"r" (PAGE_OFFSET - PHYS_OFFSET) : "r1", "cc");
Where is the best place for this code?
Should this be run for all ARM cpu_reset()?
I haven't found a nice way to add to cpu_reset() yet. This is what I have so far.
1. Redirect cpu_reset to c-function __cpu_reset_phy() that sets the pc to phy and then calls __cpu_reset() (the original one)
1.1 May add ifdefs in __cpu_reset_phy() to only do the virt to phy transition for some explicit ARM versions before calling __cpu_reset()
2. Rename cpu_v7_reset() to __cpu_v7_reset(). Only redirect cpu_v7_reset() to the c-function that goes to phy and then calls __cpu_v7_reset().
3. Add a new in parameter "phys_offset" to cpu_reset(). Modify only those CPU_reset() that needs this parameter. Redirect cpu_reset(x,y) to CPU_reset(x) or CPU_reset(x,y) based on ARM version.
Regards,
Per
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH] arm: proc-v7: pc phy addresses before disable MMU
2011-09-30 5:37 ` Per Förlin
@ 2011-09-30 8:34 ` Will Deacon
2011-09-30 9:34 ` Per Förlin
0 siblings, 1 reply; 12+ messages in thread
From: Will Deacon @ 2011-09-30 8:34 UTC (permalink / raw)
To: linux-arm-kernel
Hi Per,
On Fri, Sep 30, 2011 at 06:37:41AM +0100, Per F?rlin wrote:
> On 09/24/2011 03:02 PM, Russell King - ARM Linux wrote:
> > On Sat, Sep 24, 2011 at 02:55:42PM +0200, Per F?rlin wrote:
> >> On 09/24/2011 01:00 PM, Will Deacon wrote:
> >>> On Sat, Sep 24, 2011 at 10:32:48AM +0100, Per F?rlin wrote:
> >>>> I am trying to figure out how I can get the value of PHYS_OFFSET in assembler code (proc-v7.S).
> >>>> I guess I could use the value calculated in arch/arm/kernel.head.S but wouldn't that make
> >>>> this patch dependent on CONFIG_ARM_PATCH_PHYS_VIRT?
> >>>
> >>> Wouldn't we just be better off passing a physical address to cpu_v7_reset
> >>> instead?
> >>>
> >> Good point! I'm fine with that.
> >
> > Alternatively, call it using the phys address.
> I changed the code to use a label instead of the ARM specific instruction offset +4. A few more lines but the intention is that it should work with both ARM and THUMB. I'm in favour of Russell's idea of setting pc to physical before calling cpu_reset().
> /* Go to physical addresses to be ready for MMU disable */
> asm("ADR r1, pc_phy_here \n\t"
> "sub r1, %0 \n\t"
> "mov pc, r1 \n\t"
> "pc_phy_here: \n\t"
> : :"r" (PAGE_OFFSET - PHYS_OFFSET) : "r1", "cc");
I'm not sure why all of this is necessary. Take a look at my kexec patches
here:
http://www.linux-arm.org/git?p=linux-2.6-wd.git;a=shortlog;h=refs/heads/kexec-mmu-off
The interesting bit is __arm_machine_reset in kernel/process.c
Will
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH] arm: proc-v7: pc phy addresses before disable MMU
2011-09-30 8:34 ` Will Deacon
@ 2011-09-30 9:34 ` Per Förlin
2011-09-30 9:38 ` Will Deacon
0 siblings, 1 reply; 12+ messages in thread
From: Per Förlin @ 2011-09-30 9:34 UTC (permalink / raw)
To: linux-arm-kernel
On 09/30/2011 10:34 AM, Will Deacon wrote:
> Hi Per,
>
> On Fri, Sep 30, 2011 at 06:37:41AM +0100, Per F?rlin wrote:
>> On 09/24/2011 03:02 PM, Russell King - ARM Linux wrote:
>>> On Sat, Sep 24, 2011 at 02:55:42PM +0200, Per F?rlin wrote:
>>>> On 09/24/2011 01:00 PM, Will Deacon wrote:
>>>>> On Sat, Sep 24, 2011 at 10:32:48AM +0100, Per F?rlin wrote:
>>>>>> I am trying to figure out how I can get the value of PHYS_OFFSET in assembler code (proc-v7.S).
>>>>>> I guess I could use the value calculated in arch/arm/kernel.head.S but wouldn't that make
>>>>>> this patch dependent on CONFIG_ARM_PATCH_PHYS_VIRT?
>>>>>
>>>>> Wouldn't we just be better off passing a physical address to cpu_v7_reset
>>>>> instead?
>>>>>
>>>> Good point! I'm fine with that.
>>>
>>> Alternatively, call it using the phys address.
>> I changed the code to use a label instead of the ARM specific instruction offset +4. A few more lines but the intention is that it should work with both ARM and THUMB. I'm in favour of Russell's idea of setting pc to physical before calling cpu_reset().
>> /* Go to physical addresses to be ready for MMU disable */
>> asm("ADR r1, pc_phy_here \n\t"
>> "sub r1, %0 \n\t"
>> "mov pc, r1 \n\t"
>> "pc_phy_here: \n\t"
>> : :"r" (PAGE_OFFSET - PHYS_OFFSET) : "r1", "cc");
>
> I'm not sure why all of this is necessary. Take a look at my kexec patches
> here:
>
> http://www.linux-arm.org/git?p=linux-2.6-wd.git;a=shortlog;h=refs/heads/kexec-mmu-off
>
> The interesting bit is __arm_machine_reset in kernel/process.c
>
/* Switch to the identity mapping. */
phys_reset = (phys_reset_t)virt_to_phys(cpu_reset);
phys_reset(reset_args->reset_code_phys);
Yes this is definitely how it should be done. My mind was stuck in the assembler code.
If I get this right the bug I run into is already fixed by your kexec patches. I could simply use your patches?
Thanks,
Per
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH] arm: proc-v7: pc phy addresses before disable MMU
2011-09-30 9:34 ` Per Förlin
@ 2011-09-30 9:38 ` Will Deacon
0 siblings, 0 replies; 12+ messages in thread
From: Will Deacon @ 2011-09-30 9:38 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Sep 30, 2011 at 10:34:06AM +0100, Per F?rlin wrote:
> On 09/30/2011 10:34 AM, Will Deacon wrote:
> > I'm not sure why all of this is necessary. Take a look at my kexec patches
> > here:
> >
> > http://www.linux-arm.org/git?p=linux-2.6-wd.git;a=shortlog;h=refs/heads/kexec-mmu-off
> >
> > The interesting bit is __arm_machine_reset in kernel/process.c
> >
> /* Switch to the identity mapping. */
> phys_reset = (phys_reset_t)virt_to_phys(cpu_reset);
> phys_reset(reset_args->reset_code_phys);
> Yes this is definitely how it should be done. My mind was stuck in the assembler code.
Easy mistake to make!
> If I get this right the bug I run into is already fixed by your kexec patches. I could simply use your patches?
Sure, I reworked them the other day so I'll post them to the list again
soon. There are still some open problems to solve but the reset code is
more-or-less there.
Will
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] arm: proc-v7: pc phy addresses before disable MMU
2011-09-24 9:32 ` Per Förlin
2011-09-24 11:00 ` Will Deacon
@ 2011-10-03 14:32 ` Dave Martin
1 sibling, 0 replies; 12+ messages in thread
From: Dave Martin @ 2011-10-03 14:32 UTC (permalink / raw)
To: linux-arm-kernel
On Sat, Sep 24, 2011 at 11:32:48AM +0200, Per F?rlin wrote:
> On 09/24/2011 10:13 AM, Mika Westerberg wrote:
> > On Sat, Sep 24, 2011 at 10:02:50AM +0200, Per Forlin wrote:
> >> PC runs virtual addresses when calling cpu_v7_reset(). The MMU
> >> is switched off and "mov pc, r0" sets pc back to
> >> virtual addresses even though the MMU is switched off.
> >> This will result in a crash if the pipeline delay after
> >> MMU disable is one instruction. To prevent this set PC
> >> to physical addresses before disabling the MMU.
> >>
> >> Signed-off-by: Per Fransson <per.xx.fransson@stericsson.com>
> >> Signed-off-by: Per Forlin <per.forlin@stericsson.com>
> >> ---
> >> arch/arm/mm/proc-v7.S | 1 +
> >> 1 files changed, 1 insertions(+), 0 deletions(-)
> >>
> >> diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
> >> index 9049c07..f26e831 100644
> >> --- a/arch/arm/mm/proc-v7.S
> >> +++ b/arch/arm/mm/proc-v7.S
> >> @@ -64,6 +64,7 @@ ENDPROC(cpu_v7_proc_fin)
> >> */
> >> .align 5
> >> ENTRY(cpu_v7_reset)
> >> + sub pc, pc, #PAGE_OFFSET+4 @ go to physical addresses
> >
> > This only works on machines where PHYS_OFFSET is zero.
> >
> You are right! Russell was very quick to point out the same thing.
For reference, I'll also point out that except for "mov pc,<Rm>",
almost no instruction involving an explicit reference to the pc will
safely do what you want in Thumb-2 kernels, due to the variable instruction
size.
Cheers
---Dave
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2011-10-03 14:32 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-09-24 8:02 [PATCH] arm: proc-v7: pc phy addresses before disable MMU Per Forlin
2011-09-24 8:06 ` Russell King - ARM Linux
2011-09-24 8:13 ` Mika Westerberg
2011-09-24 9:32 ` Per Förlin
2011-09-24 11:00 ` Will Deacon
2011-09-24 12:55 ` Per Förlin
2011-09-24 13:02 ` Russell King - ARM Linux
2011-09-30 5:37 ` Per Förlin
2011-09-30 8:34 ` Will Deacon
2011-09-30 9:34 ` Per Förlin
2011-09-30 9:38 ` Will Deacon
2011-10-03 14:32 ` Dave Martin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).