* [patch 0/2] ARM: Disable outer cache before kexec call
@ 2010-07-01 16:05 Thomas Gleixner
2010-07-01 16:05 ` [patch 1/2] arm: Disable outer (L2) cache in kexec Thomas Gleixner
` (2 more replies)
0 siblings, 3 replies; 32+ messages in thread
From: Thomas Gleixner @ 2010-07-01 16:05 UTC (permalink / raw)
To: linux-arm-kernel
The following patch series addresses the problem, that the kexec code
does not disable the outer cache before disabling the inner cache and
jumping into the new kernel. This results in random crashes of the new
kernel.
Thanks,
tglx
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 1/2] arm: Disable outer (L2) cache in kexec
2010-07-01 16:05 [patch 0/2] ARM: Disable outer cache before kexec call Thomas Gleixner
@ 2010-07-01 16:05 ` Thomas Gleixner
2010-07-01 16:05 ` [patch 2/2] arm: Implement l2x0 cache disable function Thomas Gleixner
2010-07-01 16:14 ` [patch 0/2] ARM: Disable outer cache before kexec call Catalin Marinas
2 siblings, 0 replies; 32+ messages in thread
From: Thomas Gleixner @ 2010-07-01 16:05 UTC (permalink / raw)
To: linux-arm-kernel
An embedded and charset-unspecified text was scrubbed...
Name: arm-outer-cache-disable-for-kexec.patch
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20100701/1c9ff78e/attachment.ksh>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 2/2] arm: Implement l2x0 cache disable function
2010-07-01 16:05 [patch 0/2] ARM: Disable outer cache before kexec call Thomas Gleixner
2010-07-01 16:05 ` [patch 1/2] arm: Disable outer (L2) cache in kexec Thomas Gleixner
@ 2010-07-01 16:05 ` Thomas Gleixner
[not found] ` <AANLkTillHUsJF8brOtHh8tl9Us493GsWfpjhXXsFExY7@mail.gmail.com>
2010-07-02 11:47 ` Catalin Marinas
2010-07-01 16:14 ` [patch 0/2] ARM: Disable outer cache before kexec call Catalin Marinas
2 siblings, 2 replies; 32+ messages in thread
From: Thomas Gleixner @ 2010-07-01 16:05 UTC (permalink / raw)
To: linux-arm-kernel
An embedded and charset-unspecified text was scrubbed...
Name: arm-l2x0-cache-disable.patch
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20100701/d3d156ab/attachment.ksh>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 0/2] ARM: Disable outer cache before kexec call
2010-07-01 16:05 [patch 0/2] ARM: Disable outer cache before kexec call Thomas Gleixner
2010-07-01 16:05 ` [patch 1/2] arm: Disable outer (L2) cache in kexec Thomas Gleixner
2010-07-01 16:05 ` [patch 2/2] arm: Implement l2x0 cache disable function Thomas Gleixner
@ 2010-07-01 16:14 ` Catalin Marinas
2010-07-01 16:28 ` Thomas Gleixner
2 siblings, 1 reply; 32+ messages in thread
From: Catalin Marinas @ 2010-07-01 16:14 UTC (permalink / raw)
To: linux-arm-kernel
Hi Thomas,
On Thu, 2010-07-01 at 17:05 +0100, Thomas Gleixner wrote:
> The following patch series addresses the problem, that the kexec code
> does not disable the outer cache before disabling the inner cache and
> jumping into the new kernel. This results in random crashes of the new
> kernel.
We may need other ways to work around this problem. There are platforms
like OMAP3 (I think) where the L2 cache cannot be disabled as Linux is
running in non-secure (normal) mode.
Cannot some extra cache flushing work around this problem?
--
Catalin
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 0/2] ARM: Disable outer cache before kexec call
2010-07-01 16:14 ` [patch 0/2] ARM: Disable outer cache before kexec call Catalin Marinas
@ 2010-07-01 16:28 ` Thomas Gleixner
2010-07-01 16:35 ` Catalin Marinas
2010-07-01 16:38 ` Shilimkar, Santosh
0 siblings, 2 replies; 32+ messages in thread
From: Thomas Gleixner @ 2010-07-01 16:28 UTC (permalink / raw)
To: linux-arm-kernel
Catalin,
On Thu, 1 Jul 2010, Catalin Marinas wrote:
>
> On Thu, 2010-07-01 at 17:05 +0100, Thomas Gleixner wrote:
> > The following patch series addresses the problem, that the kexec code
> > does not disable the outer cache before disabling the inner cache and
> > jumping into the new kernel. This results in random crashes of the new
> > kernel.
>
> We may need other ways to work around this problem. There are platforms
> like OMAP3 (I think) where the L2 cache cannot be disabled as Linux is
> running in non-secure (normal) mode.
But it can disable the inner caches? That's weird.
> Cannot some extra cache flushing work around this problem?
We tried to keep the L2 on and just doing the l2x0_inv_all() call and
it hangs.
Thanks,
tglx
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 0/2] ARM: Disable outer cache before kexec call
2010-07-01 16:28 ` Thomas Gleixner
@ 2010-07-01 16:35 ` Catalin Marinas
2010-07-01 16:52 ` Thomas Gleixner
2010-07-01 16:38 ` Shilimkar, Santosh
1 sibling, 1 reply; 32+ messages in thread
From: Catalin Marinas @ 2010-07-01 16:35 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, 2010-07-01 at 17:28 +0100, Thomas Gleixner wrote:
> On Thu, 1 Jul 2010, Catalin Marinas wrote:
> > On Thu, 2010-07-01 at 17:05 +0100, Thomas Gleixner wrote:
> > > The following patch series addresses the problem, that the kexec code
> > > does not disable the outer cache before disabling the inner cache and
> > > jumping into the new kernel. This results in random crashes of the new
> > > kernel.
> >
> > We may need other ways to work around this problem. There are platforms
> > like OMAP3 (I think) where the L2 cache cannot be disabled as Linux is
> > running in non-secure (normal) mode.
>
> But it can disable the inner caches? That's weird.
That's because the CP15 SCTLR register is a banked one, so independent
configuration for secure and normal worlds.
The outer cache controller doesn't have banked registers and I'm not
even sure it has a notion of secure or non-secure cache line.
> > Cannot some extra cache flushing work around this problem?
>
> We tried to keep the L2 on and just doing the l2x0_inv_all() call and
> it hangs.
You would probably need an l2x0_flush_all() function which does clean
+invalidate. If you only do invalidate you may just remove valid cache
lines that have reached the RAM.
We only use the l2x0_inv_all() prior to enabling the L2 cache.
--
Catalin
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 0/2] ARM: Disable outer cache before kexec call
2010-07-01 16:28 ` Thomas Gleixner
2010-07-01 16:35 ` Catalin Marinas
@ 2010-07-01 16:38 ` Shilimkar, Santosh
2010-07-01 16:41 ` Catalin Marinas
2010-07-01 17:06 ` Russell King - ARM Linux
1 sibling, 2 replies; 32+ messages in thread
From: Shilimkar, Santosh @ 2010-07-01 16:38 UTC (permalink / raw)
To: linux-arm-kernel
> -----Original Message-----
> From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-arm-
> kernel-bounces at lists.infradead.org] On Behalf Of Thomas Gleixner
> Sent: Thursday, July 01, 2010 9:59 PM
> To: Catalin Marinas
> Cc: LAK
> Subject: Re: [patch 0/2] ARM: Disable outer cache before kexec call
>
> Catalin,
>
> On Thu, 1 Jul 2010, Catalin Marinas wrote:
> >
> > On Thu, 2010-07-01 at 17:05 +0100, Thomas Gleixner wrote:
> > > The following patch series addresses the problem, that the kexec code
> > > does not disable the outer cache before disabling the inner cache and
> > > jumping into the new kernel. This results in random crashes of the new
> > > kernel.
> >
> > We may need other ways to work around this problem. There are platforms
> > like OMAP3 (I think) where the L2 cache cannot be disabled as Linux is
> > running in non-secure (normal) mode.
>
> But it can disable the inner caches? That's weird.
>
If the C bit is disabled then it is as good as L1 and L2 are disabled.
> > Cannot some extra cache flushing work around this problem?
>
> We tried to keep the L2 on and just doing the l2x0_inv_all() call and
> it hangs.
>
Regards,
Santosh
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 0/2] ARM: Disable outer cache before kexec call
2010-07-01 16:38 ` Shilimkar, Santosh
@ 2010-07-01 16:41 ` Catalin Marinas
2010-07-01 16:44 ` Shilimkar, Santosh
2010-07-01 17:06 ` Russell King - ARM Linux
1 sibling, 1 reply; 32+ messages in thread
From: Catalin Marinas @ 2010-07-01 16:41 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, 2010-07-01 at 17:38 +0100, Shilimkar, Santosh wrote:
> > -----Original Message-----
> > From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-arm-
> > kernel-bounces at lists.infradead.org] On Behalf Of Thomas Gleixner
> > Sent: Thursday, July 01, 2010 9:59 PM
> > To: Catalin Marinas
> > Cc: LAK
> > Subject: Re: [patch 0/2] ARM: Disable outer cache before kexec call
> >
> > Catalin,
> >
> > On Thu, 1 Jul 2010, Catalin Marinas wrote:
> > >
> > > On Thu, 2010-07-01 at 17:05 +0100, Thomas Gleixner wrote:
> > > > The following patch series addresses the problem, that the kexec code
> > > > does not disable the outer cache before disabling the inner cache and
> > > > jumping into the new kernel. This results in random crashes of the new
> > > > kernel.
> > >
> > > We may need other ways to work around this problem. There are platforms
> > > like OMAP3 (I think) where the L2 cache cannot be disabled as Linux is
> > > running in non-secure (normal) mode.
> >
> > But it can disable the inner caches? That's weird.
>
> If the C bit is disabled then it is as good as L1 and L2 are disabled.
You may want to disable the I bit in SCTLR as well. With MMU disabled I
think the D side acts as strongly ordered (uncached) but you can still
get cached fetches in the I-cache (needs some TRM checking though). If
that's the case, the L2 cache could see I-cache L1 fetches as cacheable
accesses since L2 is a unified cache.
--
Catalin
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 0/2] ARM: Disable outer cache before kexec call
2010-07-01 16:41 ` Catalin Marinas
@ 2010-07-01 16:44 ` Shilimkar, Santosh
0 siblings, 0 replies; 32+ messages in thread
From: Shilimkar, Santosh @ 2010-07-01 16:44 UTC (permalink / raw)
To: linux-arm-kernel
> -----Original Message-----
> From: Catalin Marinas [mailto:catalin.marinas at arm.com]
> Sent: Thursday, July 01, 2010 10:11 PM
> To: Shilimkar, Santosh
> Cc: Thomas Gleixner; LAK
> Subject: RE: [patch 0/2] ARM: Disable outer cache before kexec call
>
> On Thu, 2010-07-01 at 17:38 +0100, Shilimkar, Santosh wrote:
> > > -----Original Message-----
> > > From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-arm-
> > > kernel-bounces at lists.infradead.org] On Behalf Of Thomas Gleixner
> > > Sent: Thursday, July 01, 2010 9:59 PM
> > > To: Catalin Marinas
> > > Cc: LAK
> > > Subject: Re: [patch 0/2] ARM: Disable outer cache before kexec call
> > >
> > > Catalin,
> > >
> > > On Thu, 1 Jul 2010, Catalin Marinas wrote:
> > > >
> > > > On Thu, 2010-07-01 at 17:05 +0100, Thomas Gleixner wrote:
> > > > > The following patch series addresses the problem, that the kexec
> code
> > > > > does not disable the outer cache before disabling the inner cache
> and
> > > > > jumping into the new kernel. This results in random crashes of the
> new
> > > > > kernel.
> > > >
> > > > We may need other ways to work around this problem. There are
> platforms
> > > > like OMAP3 (I think) where the L2 cache cannot be disabled as Linux
> is
> > > > running in non-secure (normal) mode.
> > >
> > > But it can disable the inner caches? That's weird.
> >
> > If the C bit is disabled then it is as good as L1 and L2 are disabled.
>
> You may want to disable the I bit in SCTLR as well. With MMU disabled I
> think the D side acts as strongly ordered (uncached) but you can still
> get cached fetches in the I-cache (needs some TRM checking though). If
> that's the case, the L2 cache could see I-cache L1 fetches as cacheable
> accesses since L2 is a unified cache.
>
You are right.
Regards,
Santosh
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 0/2] ARM: Disable outer cache before kexec call
2010-07-01 16:35 ` Catalin Marinas
@ 2010-07-01 16:52 ` Thomas Gleixner
2010-07-01 17:14 ` Catalin Marinas
2010-07-02 10:58 ` Tony Lindgren
0 siblings, 2 replies; 32+ messages in thread
From: Thomas Gleixner @ 2010-07-01 16:52 UTC (permalink / raw)
To: linux-arm-kernel
Catalin,
On Thu, 1 Jul 2010, Catalin Marinas wrote:
> On Thu, 2010-07-01 at 17:28 +0100, Thomas Gleixner wrote:
> > On Thu, 1 Jul 2010, Catalin Marinas wrote:
> > > On Thu, 2010-07-01 at 17:05 +0100, Thomas Gleixner wrote:
> > > > The following patch series addresses the problem, that the kexec code
> > > > does not disable the outer cache before disabling the inner cache and
> > > > jumping into the new kernel. This results in random crashes of the new
> > > > kernel.
> > >
> > > We may need other ways to work around this problem. There are platforms
> > > like OMAP3 (I think) where the L2 cache cannot be disabled as Linux is
> > > running in non-secure (normal) mode.
> >
> > But it can disable the inner caches? That's weird.
>
> That's because the CP15 SCTLR register is a banked one, so independent
> configuration for secure and normal worlds.
>
> The outer cache controller doesn't have banked registers and I'm not
> even sure it has a notion of secure or non-secure cache line.
Brilliant design.
> > > Cannot some extra cache flushing work around this problem?
> >
> > We tried to keep the L2 on and just doing the l2x0_inv_all() call and
> > it hangs.
>
> You would probably need an l2x0_flush_all() function which does clean
> +invalidate. If you only do invalidate you may just remove valid cache
> lines that have reached the RAM.
Tried that, no fun.
Thanks,
tglx
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 0/2] ARM: Disable outer cache before kexec call
2010-07-01 16:38 ` Shilimkar, Santosh
2010-07-01 16:41 ` Catalin Marinas
@ 2010-07-01 17:06 ` Russell King - ARM Linux
2010-07-01 17:21 ` Russell King - ARM Linux
1 sibling, 1 reply; 32+ messages in thread
From: Russell King - ARM Linux @ 2010-07-01 17:06 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Jul 01, 2010 at 10:08:37PM +0530, Shilimkar, Santosh wrote:
> > -----Original Message-----
> > From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-arm-
> > kernel-bounces at lists.infradead.org] On Behalf Of Thomas Gleixner
> > To: Catalin Marinas
> > Cc: LAK
> >
> > Catalin,
> >
> > But it can disable the inner caches? That's weird.
> >
> If the C bit is disabled then it is as good as L1 and L2 are disabled.
However, if L2 contains valid cache lines which haven't been written
back, the result of disabling the C bit effectively is instantaneous
memory corruption.
We know that some L2 caches aren't searched if the C bit in the MMU
tables is disabled, and for those caches I'd imagine the same thing
happens when you clear the C bit in the SCTLR when turning off the
MMU. What we currently do for L1 is:
- disable interrupts
- clean all caches (optionally invalidating)
- turn off I & C bits
- invalidate all caches
The 'clean' is there to push dirty data out of the caches back into
memory. We then turn off the I & C bits, ensuring that no new cache
lines are read in. At this point, some caches are no longer searched.
We then invalidate all caches to ensure that when _something_ later
re-enables the caches, that they don't see our stale data.
As L2 needs this same handling, what I propose is, for both
machine_restart() and machine_kexec():
1. we move the IRQ (and FIQ) disable out of each CPUs proc_fin()
2. call flush_cache_all() immediately after IRQs are disabled
(removing any cache flushing from proc_fin() implementations.)
3. call outer_flush_all() (new function) after that
4. call proc_fin() to disable the C & I bits.
5. call flush_cache_all() again to invalidate the inner caches
6. call outer_flush_all() again to invalidate the outer caches
7. whatever's next after the existing cpu_proc_fin()...
The only potential problem I see with this is that (5) and (6) may end
up writing back some dirty data associated with the stack, and one of
these functions may overwrite its return address - thereby causing us
to loop back to (2) or (3). I don't think that's a problem as the next
time around this 'loop' we won't be creating new dirty cache lines, and
we should get to step 7.
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 0/2] ARM: Disable outer cache before kexec call
2010-07-01 16:52 ` Thomas Gleixner
@ 2010-07-01 17:14 ` Catalin Marinas
2010-07-02 10:58 ` Tony Lindgren
1 sibling, 0 replies; 32+ messages in thread
From: Catalin Marinas @ 2010-07-01 17:14 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, 2010-07-01 at 17:52 +0100, Thomas Gleixner wrote:
> On Thu, 1 Jul 2010, Catalin Marinas wrote:
>
> > On Thu, 2010-07-01 at 17:28 +0100, Thomas Gleixner wrote:
> > > On Thu, 1 Jul 2010, Catalin Marinas wrote:
> > > > On Thu, 2010-07-01 at 17:05 +0100, Thomas Gleixner wrote:
> > > > > The following patch series addresses the problem, that the kexec code
> > > > > does not disable the outer cache before disabling the inner cache and
> > > > > jumping into the new kernel. This results in random crashes of the new
> > > > > kernel.
> > > >
> > > > We may need other ways to work around this problem. There are platforms
> > > > like OMAP3 (I think) where the L2 cache cannot be disabled as Linux is
> > > > running in non-secure (normal) mode.
> > >
> > > But it can disable the inner caches? That's weird.
> >
> > That's because the CP15 SCTLR register is a banked one, so independent
> > configuration for secure and normal worlds.
> >
> > The outer cache controller doesn't have banked registers and I'm not
> > even sure it has a notion of secure or non-secure cache line.
>
> Brilliant design.
The L2 cache is in many time some device outside the CPU. But in this
case I think it's more of a secure software issue - it could simply mark
all the secure page tables as outer non-cacheable and just let the
normal world handle the L2 cache as it likes.
> > > > Cannot some extra cache flushing work around this problem?
> > >
> > > We tried to keep the L2 on and just doing the l2x0_inv_all() call and
> > > it hangs.
> >
> > You would probably need an l2x0_flush_all() function which does clean
> > +invalidate. If you only do invalidate you may just remove valid cache
> > lines that have reached the RAM.
>
> Tried that, no fun.
Possibly some ordering issues. Please see Russell's reply on the cache
flushing steps (I haven't tried them though).
--
Catalin
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 0/2] ARM: Disable outer cache before kexec call
2010-07-01 17:06 ` Russell King - ARM Linux
@ 2010-07-01 17:21 ` Russell King - ARM Linux
2010-07-01 17:34 ` Catalin Marinas
2010-07-01 20:08 ` Thomas Gleixner
0 siblings, 2 replies; 32+ messages in thread
From: Russell King - ARM Linux @ 2010-07-01 17:21 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Jul 01, 2010 at 06:06:53PM +0100, Russell King - ARM Linux wrote:
> On Thu, Jul 01, 2010 at 10:08:37PM +0530, Shilimkar, Santosh wrote:
> > > -----Original Message-----
> > > From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-arm-
> > > kernel-bounces at lists.infradead.org] On Behalf Of Thomas Gleixner
> > > To: Catalin Marinas
> > > Cc: LAK
> > >
> > > Catalin,
> > >
> > > But it can disable the inner caches? That's weird.
> > >
> > If the C bit is disabled then it is as good as L1 and L2 are disabled.
>
> However, if L2 contains valid cache lines which haven't been written
> back, the result of disabling the C bit effectively is instantaneous
> memory corruption.
>
> We know that some L2 caches aren't searched if the C bit in the MMU
> tables is disabled, and for those caches I'd imagine the same thing
> happens when you clear the C bit in the SCTLR when turning off the
> MMU. What we currently do for L1 is:
>
> - disable interrupts
> - clean all caches (optionally invalidating)
> - turn off I & C bits
> - invalidate all caches
>
> The 'clean' is there to push dirty data out of the caches back into
> memory. We then turn off the I & C bits, ensuring that no new cache
> lines are read in. At this point, some caches are no longer searched.
>
> We then invalidate all caches to ensure that when _something_ later
> re-enables the caches, that they don't see our stale data.
>
> As L2 needs this same handling, what I propose is, for both
> machine_restart() and machine_kexec():
>
> 1. we move the IRQ (and FIQ) disable out of each CPUs proc_fin()
> 2. call flush_cache_all() immediately after IRQs are disabled
> (removing any cache flushing from proc_fin() implementations.)
> 3. call outer_flush_all() (new function) after that
> 4. call proc_fin() to disable the C & I bits.
> 5. call flush_cache_all() again to invalidate the inner caches
> 6. call outer_flush_all() again to invalidate the outer caches
> 7. whatever's next after the existing cpu_proc_fin()...
>
> The only potential problem I see with this is that (5) and (6) may end
> up writing back some dirty data associated with the stack, and one of
> these functions may overwrite its return address - thereby causing us
> to loop back to (2) or (3). I don't think that's a problem as the next
> time around this 'loop' we won't be creating new dirty cache lines, and
> we should get to step 7.
Right, something like this. I've not made an effort to fix the L2 bits,
but I have marked the places where attention is required. The interesting
bit is the first two files.
The next question this provokes is whether we need a dsb() between steps 3
and 4, and maybe again between 4 and 5, and possibly after 6 ?
arch/arm/kernel/machine_kexec.c | 8 +++++++-
arch/arm/kernel/process.c | 20 ++++++++++++++++----
arch/arm/mm/proc-arm1020.S | 6 +-----
arch/arm/mm/proc-arm1020e.S | 6 +-----
arch/arm/mm/proc-arm1022.S | 6 +-----
arch/arm/mm/proc-arm1026.S | 6 +-----
arch/arm/mm/proc-arm6_7.S | 2 --
arch/arm/mm/proc-arm720.S | 6 +-----
arch/arm/mm/proc-arm740.S | 6 +-----
arch/arm/mm/proc-arm7tdmi.S | 2 --
arch/arm/mm/proc-arm920.S | 10 +---------
arch/arm/mm/proc-arm922.S | 10 +---------
arch/arm/mm/proc-arm925.S | 6 +-----
arch/arm/mm/proc-arm926.S | 6 +-----
arch/arm/mm/proc-arm940.S | 6 +-----
arch/arm/mm/proc-arm946.S | 6 +-----
arch/arm/mm/proc-arm9tdmi.S | 2 --
arch/arm/mm/proc-fa526.S | 6 +-----
arch/arm/mm/proc-feroceon.S | 8 ++------
arch/arm/mm/proc-mohawk.S | 6 +-----
arch/arm/mm/proc-sa110.S | 8 ++------
arch/arm/mm/proc-sa1100.S | 6 +-----
arch/arm/mm/proc-v6.S | 5 +----
arch/arm/mm/proc-v7.S | 5 +----
arch/arm/mm/proc-xsc3.S | 6 +-----
arch/arm/mm/proc-xscale.S | 6 +-----
26 files changed, 46 insertions(+), 124 deletions(-)
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 598ca61..53f5dc4 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -74,7 +74,13 @@ void machine_kexec(struct kimage *image)
(unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
printk(KERN_INFO "Bye!\n");
- cpu_proc_fin();
+ local_irq_disable();
+ local_fiq_disable();
setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/
+ flush_cache_all();
+ /* XXX: L2 cache flush */
+ cpu_proc_fin();
+ flush_cache_all();
+ /* XXX: L2 cache flush */
cpu_reset(reboot_code_buffer_phys);
}
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index acf5e6f..3736887 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -84,10 +84,9 @@ __setup("hlt", hlt_setup);
void arm_machine_restart(char mode, const char *cmd)
{
- /*
- * Clean and disable cache, and turn off interrupts
- */
- cpu_proc_fin();
+ /* Disable interrupts first */
+ local_irq_disable();
+ local_fiq_disable();
/*
* Tell the mm system that we are going to reboot -
@@ -96,6 +95,19 @@ void arm_machine_restart(char mode, const char *cmd)
*/
setup_mm_for_reboot(mode);
+ /* Clean and invalidate caches */
+ flush_cache_all();
+
+ /* XXX: L2 cache flush */
+
+ /* Turn off caching */
+ cpu_proc_fin();
+
+ /* Push out any further dirty data, and ensure cache is empty */
+ flush_cache_all();
+
+ /* XXX: L2 cache flush */
+
/*
* Now call the architecture specific reboot code.
*/
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index 72507c6..203a4e9 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -79,15 +79,11 @@ ENTRY(cpu_arm1020_proc_init)
* cpu_arm1020_proc_fin()
*/
ENTRY(cpu_arm1020_proc_fin)
- stmfd sp!, {lr}
- mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, ip
- bl arm1020_flush_kern_cache_all
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- ldmfd sp!, {pc}
+ mov pc, lr
/*
* cpu_arm1020_reset(loc)
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index d278298..1a511e7 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -79,15 +79,11 @@ ENTRY(cpu_arm1020e_proc_init)
* cpu_arm1020e_proc_fin()
*/
ENTRY(cpu_arm1020e_proc_fin)
- stmfd sp!, {lr}
- mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, ip
- bl arm1020e_flush_kern_cache_all
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- ldmfd sp!, {pc}
+ mov pc, lr
/*
* cpu_arm1020e_reset(loc)
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index ce13e4a..1ffa4eb 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -68,15 +68,11 @@ ENTRY(cpu_arm1022_proc_init)
* cpu_arm1022_proc_fin()
*/
ENTRY(cpu_arm1022_proc_fin)
- stmfd sp!, {lr}
- mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, ip
- bl arm1022_flush_kern_cache_all
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- ldmfd sp!, {pc}
+ mov pc, lr
/*
* cpu_arm1022_reset(loc)
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index 636672a..5697c34 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -68,15 +68,11 @@ ENTRY(cpu_arm1026_proc_init)
* cpu_arm1026_proc_fin()
*/
ENTRY(cpu_arm1026_proc_fin)
- stmfd sp!, {lr}
- mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, ip
- bl arm1026_flush_kern_cache_all
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- ldmfd sp!, {pc}
+ mov pc, lr
/*
* cpu_arm1026_reset(loc)
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index 795dc61..64e0b32 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -184,8 +184,6 @@ ENTRY(cpu_arm7_proc_init)
ENTRY(cpu_arm6_proc_fin)
ENTRY(cpu_arm7_proc_fin)
- mov r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, r0
mov r0, #0x31 @ ....S..DP...M
mcr p15, 0, r0, c1, c0, 0 @ disable caches
mov pc, lr
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index 0b62de2..9d96824 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -54,15 +54,11 @@ ENTRY(cpu_arm720_proc_init)
mov pc, lr
ENTRY(cpu_arm720_proc_fin)
- stmfd sp!, {lr}
- mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, ip
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- mcr p15, 0, r1, c7, c7, 0 @ invalidate cache
- ldmfd sp!, {pc}
+ mov pc, lr
/*
* Function: arm720_proc_do_idle(void)
diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S
index 01860cd..6c1a9ab 100644
--- a/arch/arm/mm/proc-arm740.S
+++ b/arch/arm/mm/proc-arm740.S
@@ -36,15 +36,11 @@ ENTRY(cpu_arm740_switch_mm)
* cpu_arm740_proc_fin()
*/
ENTRY(cpu_arm740_proc_fin)
- stmfd sp!, {lr}
- mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, ip
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x3f000000 @ bank/f/lock/s
bic r0, r0, #0x0000000c @ w-buffer/cache
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- mcr p15, 0, r0, c7, c0, 0 @ invalidate cache
- ldmfd sp!, {pc}
+ mov pc, lr
/*
* cpu_arm740_reset(loc)
diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S
index 1201b98..6a850db 100644
--- a/arch/arm/mm/proc-arm7tdmi.S
+++ b/arch/arm/mm/proc-arm7tdmi.S
@@ -36,8 +36,6 @@ ENTRY(cpu_arm7tdmi_switch_mm)
* cpu_arm7tdmi_proc_fin()
*/
ENTRY(cpu_arm7tdmi_proc_fin)
- mov r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, r0
mov pc, lr
/*
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 8be8199..86f80aa 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -69,19 +69,11 @@ ENTRY(cpu_arm920_proc_init)
* cpu_arm920_proc_fin()
*/
ENTRY(cpu_arm920_proc_fin)
- stmfd sp!, {lr}
- mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, ip
-#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- bl arm920_flush_kern_cache_all
-#else
- bl v4wt_flush_kern_cache_all
-#endif
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- ldmfd sp!, {pc}
+ mov pc, lr
/*
* cpu_arm920_reset(loc)
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index c0ff8e4..f76ce9b 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -71,19 +71,11 @@ ENTRY(cpu_arm922_proc_init)
* cpu_arm922_proc_fin()
*/
ENTRY(cpu_arm922_proc_fin)
- stmfd sp!, {lr}
- mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, ip
-#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- bl arm922_flush_kern_cache_all
-#else
- bl v4wt_flush_kern_cache_all
-#endif
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- ldmfd sp!, {pc}
+ mov pc, lr
/*
* cpu_arm922_reset(loc)
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index 3c6cffe..657bd3f 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -92,15 +92,11 @@ ENTRY(cpu_arm925_proc_init)
* cpu_arm925_proc_fin()
*/
ENTRY(cpu_arm925_proc_fin)
- stmfd sp!, {lr}
- mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, ip
- bl arm925_flush_kern_cache_all
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- ldmfd sp!, {pc}
+ mov pc, lr
/*
* cpu_arm925_reset(loc)
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 75b707c..73f1f3c 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -61,15 +61,11 @@ ENTRY(cpu_arm926_proc_init)
* cpu_arm926_proc_fin()
*/
ENTRY(cpu_arm926_proc_fin)
- stmfd sp!, {lr}
- mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, ip
- bl arm926_flush_kern_cache_all
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- ldmfd sp!, {pc}
+ mov pc, lr
/*
* cpu_arm926_reset(loc)
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
index 1af1657..fffb061 100644
--- a/arch/arm/mm/proc-arm940.S
+++ b/arch/arm/mm/proc-arm940.S
@@ -37,15 +37,11 @@ ENTRY(cpu_arm940_switch_mm)
* cpu_arm940_proc_fin()
*/
ENTRY(cpu_arm940_proc_fin)
- stmfd sp!, {lr}
- mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, ip
- bl arm940_flush_kern_cache_all
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x00001000 @ i-cache
bic r0, r0, #0x00000004 @ d-cache
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- ldmfd sp!, {pc}
+ mov pc, lr
/*
* cpu_arm940_reset(loc)
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
index 1664b6a..249a605 100644
--- a/arch/arm/mm/proc-arm946.S
+++ b/arch/arm/mm/proc-arm946.S
@@ -44,15 +44,11 @@ ENTRY(cpu_arm946_switch_mm)
* cpu_arm946_proc_fin()
*/
ENTRY(cpu_arm946_proc_fin)
- stmfd sp!, {lr}
- mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, ip
- bl arm946_flush_kern_cache_all
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x00001000 @ i-cache
bic r0, r0, #0x00000004 @ d-cache
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- ldmfd sp!, {pc}
+ mov pc, lr
/*
* cpu_arm946_reset(loc)
diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S
index 28545c2..db47566 100644
--- a/arch/arm/mm/proc-arm9tdmi.S
+++ b/arch/arm/mm/proc-arm9tdmi.S
@@ -36,8 +36,6 @@ ENTRY(cpu_arm9tdmi_switch_mm)
* cpu_arm9tdmi_proc_fin()
*/
ENTRY(cpu_arm9tdmi_proc_fin)
- mov r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, r0
mov pc, lr
/*
diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S
index 08f5ac2..7803fdf 100644
--- a/arch/arm/mm/proc-fa526.S
+++ b/arch/arm/mm/proc-fa526.S
@@ -39,17 +39,13 @@ ENTRY(cpu_fa526_proc_init)
* cpu_fa526_proc_fin()
*/
ENTRY(cpu_fa526_proc_fin)
- stmfd sp!, {lr}
- mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, ip
- bl fa_flush_kern_cache_all
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
nop
nop
- ldmfd sp!, {pc}
+ mov pc, lr
/*
* cpu_fa526_reset(loc)
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index 53e6323..f8eff28 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -75,13 +75,9 @@ ENTRY(cpu_feroceon_proc_init)
* cpu_feroceon_proc_fin()
*/
ENTRY(cpu_feroceon_proc_fin)
- stmfd sp!, {lr}
- mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, ip
- bl feroceon_flush_kern_cache_all
-
#if defined(CONFIG_CACHE_FEROCEON_L2) && \
!defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
+ XXX: move me to L2 cache support
mov r0, #0
mcr p15, 1, r0, c15, c9, 0 @ clean L2
mcr p15, 0, r0, c7, c10, 4 @ drain WB
@@ -91,7 +87,7 @@ ENTRY(cpu_feroceon_proc_fin)
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- ldmfd sp!, {pc}
+ mov pc, lr
/*
* cpu_feroceon_reset(loc)
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index caa3115..5f6892f 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -51,15 +51,11 @@ ENTRY(cpu_mohawk_proc_init)
* cpu_mohawk_proc_fin()
*/
ENTRY(cpu_mohawk_proc_fin)
- stmfd sp!, {lr}
- mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, ip
- bl mohawk_flush_kern_cache_all
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1800 @ ...iz...........
bic r0, r0, #0x0006 @ .............ca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- ldmfd sp!, {pc}
+ mov pc, lr
/*
* cpu_mohawk_reset(loc)
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 7b706b3..a201eb0 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -44,17 +44,13 @@ ENTRY(cpu_sa110_proc_init)
* cpu_sa110_proc_fin()
*/
ENTRY(cpu_sa110_proc_fin)
- stmfd sp!, {lr}
- mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, ip
- bl v4wb_flush_kern_cache_all @ clean caches
-1: mov r0, #0
+ mov r0, #0
mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- ldmfd sp!, {pc}
+ mov pc, lr
/*
* cpu_sa110_reset(loc)
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 5c47760..7ddc480 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -55,16 +55,12 @@ ENTRY(cpu_sa1100_proc_init)
* - Clean and turn off caches.
*/
ENTRY(cpu_sa1100_proc_fin)
- stmfd sp!, {lr}
- mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, ip
- bl v4wb_flush_kern_cache_all
mcr p15, 0, ip, c15, c2, 2 @ Disable clock switching
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- ldmfd sp!, {pc}
+ mov pc, lr
/*
* cpu_sa1100_reset(loc)
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 7a5337e..e55ffd7 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -42,14 +42,11 @@ ENTRY(cpu_v6_proc_init)
mov pc, lr
ENTRY(cpu_v6_proc_fin)
- stmfd sp!, {lr}
- cpsid if @ disable interrupts
- bl v6_flush_kern_cache_all
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x0006 @ .............ca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- ldmfd sp!, {pc}
+ mov pc, lr
/*
* cpu_v6_reset(loc)
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 7aaf88a..b0f8873 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -45,14 +45,11 @@ ENTRY(cpu_v7_proc_init)
ENDPROC(cpu_v7_proc_init)
ENTRY(cpu_v7_proc_fin)
- stmfd sp!, {lr}
- cpsid if @ disable interrupts
- bl v7_flush_kern_cache_all
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x0006 @ .............ca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- ldmfd sp!, {pc}
+ mov pc, lr
ENDPROC(cpu_v7_proc_fin)
/*
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index e5797f1..361a51e 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -90,15 +90,11 @@ ENTRY(cpu_xsc3_proc_init)
* cpu_xsc3_proc_fin()
*/
ENTRY(cpu_xsc3_proc_fin)
- str lr, [sp, #-4]!
- mov r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
- msr cpsr_c, r0
- bl xsc3_flush_kern_cache_all @ clean caches
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1800 @ ...IZ...........
bic r0, r0, #0x0006 @ .............CA.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- ldr pc, [sp], #4
+ mov pc, lr
/*
* cpu_xsc3_reset(loc)
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 63037e2..1407597 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -124,15 +124,11 @@ ENTRY(cpu_xscale_proc_init)
* cpu_xscale_proc_fin()
*/
ENTRY(cpu_xscale_proc_fin)
- str lr, [sp, #-4]!
- mov r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
- msr cpsr_c, r0
- bl xscale_flush_kern_cache_all @ clean caches
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1800 @ ...IZ...........
bic r0, r0, #0x0006 @ .............CA.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- ldr pc, [sp], #4
+ mov pc, lr
/*
* cpu_xscale_reset(loc)
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [patch 0/2] ARM: Disable outer cache before kexec call
2010-07-01 17:21 ` Russell King - ARM Linux
@ 2010-07-01 17:34 ` Catalin Marinas
2010-07-01 17:48 ` Russell King - ARM Linux
2010-07-01 20:08 ` Thomas Gleixner
1 sibling, 1 reply; 32+ messages in thread
From: Catalin Marinas @ 2010-07-01 17:34 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, 2010-07-01 at 18:21 +0100, Russell King - ARM Linux wrote:
> On Thu, Jul 01, 2010 at 06:06:53PM +0100, Russell King - ARM Linux wrote:
> > On Thu, Jul 01, 2010 at 10:08:37PM +0530, Shilimkar, Santosh wrote:
> > > > -----Original Message-----
> > > > From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-arm-
> > > > kernel-bounces at lists.infradead.org] On Behalf Of Thomas Gleixner
> > > > To: Catalin Marinas
> > > > Cc: LAK
> > > >
> > > > Catalin,
> > > >
> > > > But it can disable the inner caches? That's weird.
> > > >
> > > If the C bit is disabled then it is as good as L1 and L2 are disabled.
> >
> > However, if L2 contains valid cache lines which haven't been written
> > back, the result of disabling the C bit effectively is instantaneous
> > memory corruption.
> >
> > We know that some L2 caches aren't searched if the C bit in the MMU
> > tables is disabled, and for those caches I'd imagine the same thing
> > happens when you clear the C bit in the SCTLR when turning off the
> > MMU. What we currently do for L1 is:
> >
> > - disable interrupts
> > - clean all caches (optionally invalidating)
> > - turn off I & C bits
> > - invalidate all caches
> >
> > The 'clean' is there to push dirty data out of the caches back into
> > memory. We then turn off the I & C bits, ensuring that no new cache
> > lines are read in. At this point, some caches are no longer searched.
> >
> > We then invalidate all caches to ensure that when _something_ later
> > re-enables the caches, that they don't see our stale data.
> >
> > As L2 needs this same handling, what I propose is, for both
> > machine_restart() and machine_kexec():
> >
> > 1. we move the IRQ (and FIQ) disable out of each CPUs proc_fin()
> > 2. call flush_cache_all() immediately after IRQs are disabled
> > (removing any cache flushing from proc_fin() implementations.)
> > 3. call outer_flush_all() (new function) after that
> > 4. call proc_fin() to disable the C & I bits.
> > 5. call flush_cache_all() again to invalidate the inner caches
> > 6. call outer_flush_all() again to invalidate the outer caches
> > 7. whatever's next after the existing cpu_proc_fin()...
> >
> > The only potential problem I see with this is that (5) and (6) may end
> > up writing back some dirty data associated with the stack, and one of
> > these functions may overwrite its return address - thereby causing us
> > to loop back to (2) or (3). I don't think that's a problem as the next
> > time around this 'loop' we won't be creating new dirty cache lines, and
> > we should get to step 7.
>
> Right, something like this. I've not made an effort to fix the L2 bits,
> but I have marked the places where attention is required. The interesting
> bit is the first two files.
>
> The next question this provokes is whether we need a dsb() between steps 3
> and 4, and maybe again between 4 and 5, and possibly after 6 ?
We don't need a dsb() after 3 and 6. The outer_flush_all() function
would need to do a cache_sync (which polls a register) since that's a
background operation on the L2 cache. DSB doesn't have any effect on the
L2 cache.
As for between 4 and 5, we may need an ISB as well (not sure about DSB).
It's worth checking the recommended MMU disabling sequences in the ARM
ARM (if any).
--
Catalin
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 0/2] ARM: Disable outer cache before kexec call
2010-07-01 17:34 ` Catalin Marinas
@ 2010-07-01 17:48 ` Russell King - ARM Linux
0 siblings, 0 replies; 32+ messages in thread
From: Russell King - ARM Linux @ 2010-07-01 17:48 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Jul 01, 2010 at 06:34:55PM +0100, Catalin Marinas wrote:
> On Thu, 2010-07-01 at 18:21 +0100, Russell King - ARM Linux wrote:
> > On Thu, Jul 01, 2010 at 06:06:53PM +0100, Russell King - ARM Linux wrote:
> > > 1. we move the IRQ (and FIQ) disable out of each CPUs proc_fin()
> > > 2. call flush_cache_all() immediately after IRQs are disabled
> > > (removing any cache flushing from proc_fin() implementations.)
> > > 3. call outer_flush_all() (new function) after that
> > > 4. call proc_fin() to disable the C & I bits.
> > > 5. call flush_cache_all() again to invalidate the inner caches
> > > 6. call outer_flush_all() again to invalidate the outer caches
> > > 7. whatever's next after the existing cpu_proc_fin()...
> > >
> > > The only potential problem I see with this is that (5) and (6) may end
> > > up writing back some dirty data associated with the stack, and one of
> > > these functions may overwrite its return address - thereby causing us
> > > to loop back to (2) or (3). I don't think that's a problem as the next
> > > time around this 'loop' we won't be creating new dirty cache lines, and
> > > we should get to step 7.
> >
> > Right, something like this. I've not made an effort to fix the L2 bits,
> > but I have marked the places where attention is required. The interesting
> > bit is the first two files.
> >
> > The next question this provokes is whether we need a dsb() between steps 3
> > and 4, and maybe again between 4 and 5, and possibly after 6 ?
>
> We don't need a dsb() after 3 and 6. The outer_flush_all() function
> would need to do a cache_sync (which polls a register) since that's a
> background operation on the L2 cache. DSB doesn't have any effect on the
> L2 cache.
Well, that leaves a question about Feroceon:
#if defined(CONFIG_CACHE_FEROCEON_L2) && \
!defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
mov r0, #0
mcr p15, 1, r0, c15, c9, 0 @ clean L2
mcr p15, 0, r0, c7, c10, 4 @ drain WB
#endif
The question is where to move that (effective) DSB to - I guess it can
move to arch/arm/mm/cache-feroceon-l2.c.
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 0/2] ARM: Disable outer cache before kexec call
2010-07-01 17:21 ` Russell King - ARM Linux
2010-07-01 17:34 ` Catalin Marinas
@ 2010-07-01 20:08 ` Thomas Gleixner
1 sibling, 0 replies; 32+ messages in thread
From: Thomas Gleixner @ 2010-07-01 20:08 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, 1 Jul 2010, Russell King - ARM Linux wrote:
> On Thu, Jul 01, 2010 at 06:06:53PM +0100, Russell King - ARM Linux wrote:
> > On Thu, Jul 01, 2010 at 10:08:37PM +0530, Shilimkar, Santosh wrote:
>
> Right, something like this. I've not made an effort to fix the L2 bits,
> but I have marked the places where attention is required. The interesting
> bit is the first two files.
I filled in the L2 bits for l2x0 in the following way:
Index: linux-2.6/arch/arm/mm/cache-l2x0.c
===================================================================
--- linux-2.6.orig/arch/arm/mm/cache-l2x0.c
+++ linux-2.6/arch/arm/mm/cache-l2x0.c
@@ -103,6 +103,18 @@ static void l2x0_cache_sync(void)
spin_unlock_irqrestore(&l2x0_lock, flags);
}
+static inline void l2x0_flush_all(void)
+{
+ unsigned long flags;
+
+ /* invalidate all ways */
+ spin_lock_irqsave(&l2x0_lock, flags);
+ writel(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY);
+ cache_wait(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask);
+ cache_sync();
+ spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
static inline void l2x0_inv_all(void)
{
unsigned long flags;
@@ -262,6 +274,7 @@ void __init l2x0_init(void __iomem *base
outer_cache.clean_range = l2x0_clean_range;
outer_cache.flush_range = l2x0_flush_range;
outer_cache.sync = l2x0_cache_sync;
+ outer_cache.flush_all = l2x0_cache_disable;
printk(KERN_INFO "%s cache controller enabled\n", type);
printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
Now I added outer_flush_all() calls to the places Russell pointed out.
Unfortunately that works just 5 times in a row, then the box stops
dead _after_ the decompressor jumps into the kernel. With current
mainline we fail in the decompressor itself. I guess we need the same
magic in the decompressor as well.
Adding the L2 disable function on top of these patches works like a
charm.
Seriously I think that keeping L2 enabled has enough unknown side
effects which might be dealt with by some random cache flushes, but
that's not a real solution to the underlying problem.
As a matter of sanity I think we should add the L2 disable
functionality. It's logical and it _DOES_ work. Further it solves a
real world problem as kexec is broken on any L2 enabled system AFAICT.
The sillyness of OMAP3 can be dealt with by those who invented that
insanity w/o imposing their wreckage on everyone.
Thanks,
tglx
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 0/2] ARM: Disable outer cache before kexec call
2010-07-01 16:52 ` Thomas Gleixner
2010-07-01 17:14 ` Catalin Marinas
@ 2010-07-02 10:58 ` Tony Lindgren
1 sibling, 0 replies; 32+ messages in thread
From: Tony Lindgren @ 2010-07-02 10:58 UTC (permalink / raw)
To: linux-arm-kernel
* Thomas Gleixner <tglx@linutronix.de> [100701 19:54]:
> Catalin,
>
> On Thu, 1 Jul 2010, Catalin Marinas wrote:
>
> > On Thu, 2010-07-01 at 17:28 +0100, Thomas Gleixner wrote:
> > > On Thu, 1 Jul 2010, Catalin Marinas wrote:
> > > > On Thu, 2010-07-01 at 17:05 +0100, Thomas Gleixner wrote:
> > > > > The following patch series addresses the problem, that the kexec code
> > > > > does not disable the outer cache before disabling the inner cache and
> > > > > jumping into the new kernel. This results in random crashes of the new
> > > > > kernel.
> > > >
> > > > We may need other ways to work around this problem. There are platforms
> > > > like OMAP3 (I think) where the L2 cache cannot be disabled as Linux is
> > > > running in non-secure (normal) mode.
> > >
> > > But it can disable the inner caches? That's weird.
> >
> > That's because the CP15 SCTLR register is a banked one, so independent
> > configuration for secure and normal worlds.
> >
> > The outer cache controller doesn't have banked registers and I'm not
> > even sure it has a notion of secure or non-secure cache line.
>
> Brilliant design.
FYI, on secure omaps disabling/enabling/configuring of L2 cache must
be done via SMI that runs some function in the secure software (PPA)..
The code is there in arch/arm/mach-omap2/sleep34xx.S, just search
for SMI or PPA.
Trying to set things via the ARM aux ctrl register will hang the system,
so we need to figure out some way to select the L2 enable/disable based
on if we're running in secure mode or not.
Regards,
Tony
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 2/2] arm: Implement l2x0 cache disable function
[not found] ` <AANLkTillHUsJF8brOtHh8tl9Us493GsWfpjhXXsFExY7@mail.gmail.com>
@ 2010-07-02 11:23 ` srinidhi
0 siblings, 0 replies; 32+ messages in thread
From: srinidhi @ 2010-07-02 11:23 UTC (permalink / raw)
To: linux-arm-kernel
> ---------- Forwarded message ----------
> From: Thomas Gleixner <tglx@linutronix.de>
> Date: Thu, Jul 1, 2010 at 9:35 PM
> Subject: [patch 2/2] arm: Implement l2x0 cache disable function
> To: LAK <linux-arm-kernel@lists.infradead.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
>
>
> This function is called from kexec code before the inner caches are
> disabled to prevent random crashes in the new kernel.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Index: linux-2.6/arch/arm/mm/cache-l2x0.c
> ===================================================================
> --- linux-2.6.orig/arch/arm/mm/cache-l2x0.c
> +++ linux-2.6/arch/arm/mm/cache-l2x0.c
> @@ -206,6 +206,12 @@ static void l2x0_flush_range(unsigned lo
> spin_unlock_irqrestore(&l2x0_lock, flags);
> }
>
> +static void l2x0_cache_disable(void)
> +{
> + l2x0_inv_all();
> + writel(0, l2x0_base + L2X0_CTRL);
> +}
I think it's a problem for PL310 controller where the access to
L2X0_CTRL is secure, accessing this in non-secure mode will fault.
Srinidhi
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 2/2] arm: Implement l2x0 cache disable function
2010-07-01 16:05 ` [patch 2/2] arm: Implement l2x0 cache disable function Thomas Gleixner
[not found] ` <AANLkTillHUsJF8brOtHh8tl9Us493GsWfpjhXXsFExY7@mail.gmail.com>
@ 2010-07-02 11:47 ` Catalin Marinas
2010-07-02 15:29 ` Thomas Gleixner
1 sibling, 1 reply; 32+ messages in thread
From: Catalin Marinas @ 2010-07-02 11:47 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, 2010-07-01 at 17:05 +0100, Thomas Gleixner wrote:
> This function is called from kexec code before the inner caches are
> disabled to prevent random crashes in the new kernel.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Index: linux-2.6/arch/arm/mm/cache-l2x0.c
> ===================================================================
> --- linux-2.6.orig/arch/arm/mm/cache-l2x0.c
> +++ linux-2.6/arch/arm/mm/cache-l2x0.c
> @@ -206,6 +206,12 @@ static void l2x0_flush_range(unsigned lo
> spin_unlock_irqrestore(&l2x0_lock, flags);
> }
>
> +static void l2x0_cache_disable(void)
> +{
> + l2x0_inv_all();
> + writel(0, l2x0_base + L2X0_CTRL);
> +}
Even if we go this route, we need an l2x0_flush_all() rather than
invalidate here as the latter removes dirty cache lines without evicting
them first.
--
Catalin
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 2/2] arm: Implement l2x0 cache disable function
2010-07-02 11:47 ` Catalin Marinas
@ 2010-07-02 15:29 ` Thomas Gleixner
2010-07-02 16:10 ` Catalin Marinas
2010-07-02 16:48 ` Shilimkar, Santosh
0 siblings, 2 replies; 32+ messages in thread
From: Thomas Gleixner @ 2010-07-02 15:29 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, 2 Jul 2010, Catalin Marinas wrote:
> On Thu, 2010-07-01 at 17:05 +0100, Thomas Gleixner wrote:
> > This function is called from kexec code before the inner caches are
> > disabled to prevent random crashes in the new kernel.
> >
> > Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> > Index: linux-2.6/arch/arm/mm/cache-l2x0.c
> > ===================================================================
> > --- linux-2.6.orig/arch/arm/mm/cache-l2x0.c
> > +++ linux-2.6/arch/arm/mm/cache-l2x0.c
> > @@ -206,6 +206,12 @@ static void l2x0_flush_range(unsigned lo
> > spin_unlock_irqrestore(&l2x0_lock, flags);
> > }
> >
> > +static void l2x0_cache_disable(void)
> > +{
> > + l2x0_inv_all();
> > + writel(0, l2x0_base + L2X0_CTRL);
> > +}
>
> Even if we go this route, we need an l2x0_flush_all() rather than
> invalidate here as the latter removes dirty cache lines without evicting
> them first.
True, but that's an implementation detail. What's more important is to
make a decision how to solve the problem as kexec is completely
unusable for all L2 systems right now.
I think the correct way to deal with this is disabling L2 and let the
OMAP3 folks deal with it. As Tony said there is some SMI magic to do
that, so we can do the following:
In l2x0_init()
if (!l2_enabled()) {
if (non_secure()) {
omap_smi_magic_l2_enable();
outer_cache.disable = omap_smi_magic_l2_disable;
} else {
sane_l2_enable();
outer_cache.disable = sane_l2_disable;
}
}
Russells patch has its own merits nevertheless as a cleanup and
simplification, but that's a separate issue.
Thoughts ?
tglx
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 2/2] arm: Implement l2x0 cache disable function
2010-07-02 15:29 ` Thomas Gleixner
@ 2010-07-02 16:10 ` Catalin Marinas
2010-07-02 16:39 ` Thomas Gleixner
2010-07-02 17:21 ` Russell King - ARM Linux
2010-07-02 16:48 ` Shilimkar, Santosh
1 sibling, 2 replies; 32+ messages in thread
From: Catalin Marinas @ 2010-07-02 16:10 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, 2010-07-02 at 16:29 +0100, Thomas Gleixner wrote:
> On Fri, 2 Jul 2010, Catalin Marinas wrote:
>
> > On Thu, 2010-07-01 at 17:05 +0100, Thomas Gleixner wrote:
> > > This function is called from kexec code before the inner caches are
> > > disabled to prevent random crashes in the new kernel.
> > >
> > > Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> > > Index: linux-2.6/arch/arm/mm/cache-l2x0.c
> > > ===================================================================
> > > --- linux-2.6.orig/arch/arm/mm/cache-l2x0.c
> > > +++ linux-2.6/arch/arm/mm/cache-l2x0.c
> > > @@ -206,6 +206,12 @@ static void l2x0_flush_range(unsigned lo
> > > spin_unlock_irqrestore(&l2x0_lock, flags);
> > > }
> > >
> > > +static void l2x0_cache_disable(void)
> > > +{
> > > + l2x0_inv_all();
> > > + writel(0, l2x0_base + L2X0_CTRL);
> > > +}
> >
> > Even if we go this route, we need an l2x0_flush_all() rather than
> > invalidate here as the latter removes dirty cache lines without evicting
> > them first.
>
> True, but that's an implementation detail. What's more important is to
> make a decision how to solve the problem as kexec is completely
> unusable for all L2 systems right now.
My view is that we should try to find why cache flushing doesn't work
but unfortunately I don't have any spare time to look into this (would
need to use tools like ICE debugging/tracing).
> I think the correct way to deal with this is disabling L2 and let the
> OMAP3 folks deal with it. As Tony said there is some SMI magic to do
> that, so we can do the following:
>
> In l2x0_init()
>
> if (!l2_enabled()) {
> if (non_secure()) {
> omap_smi_magic_l2_enable();
> outer_cache.disable = omap_smi_magic_l2_disable;
> } else {
> sane_l2_enable();
> outer_cache.disable = sane_l2_disable;
> }
> }
The non_secure() bit is the key. AFAIK there isn't an easy way to check
whether you are running in secure or non-secure mode (I think there is
some CP14 debug register telling this but those registers aren't
mandatory in a CPU implementation).
--
Catalin
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 2/2] arm: Implement l2x0 cache disable function
2010-07-02 16:10 ` Catalin Marinas
@ 2010-07-02 16:39 ` Thomas Gleixner
2010-07-02 16:51 ` Shilimkar, Santosh
2010-07-02 16:54 ` Catalin Marinas
2010-07-02 17:21 ` Russell King - ARM Linux
1 sibling, 2 replies; 32+ messages in thread
From: Thomas Gleixner @ 2010-07-02 16:39 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, 2 Jul 2010, Catalin Marinas wrote:
> On Fri, 2010-07-02 at 16:29 +0100, Thomas Gleixner wrote:
> > On Fri, 2 Jul 2010, Catalin Marinas wrote:
> >
> > > On Thu, 2010-07-01 at 17:05 +0100, Thomas Gleixner wrote:
> > > > This function is called from kexec code before the inner caches are
> > > > disabled to prevent random crashes in the new kernel.
> > > >
> > > > Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> > > > Index: linux-2.6/arch/arm/mm/cache-l2x0.c
> > > > ===================================================================
> > > > --- linux-2.6.orig/arch/arm/mm/cache-l2x0.c
> > > > +++ linux-2.6/arch/arm/mm/cache-l2x0.c
> > > > @@ -206,6 +206,12 @@ static void l2x0_flush_range(unsigned lo
> > > > spin_unlock_irqrestore(&l2x0_lock, flags);
> > > > }
> > > >
> > > > +static void l2x0_cache_disable(void)
> > > > +{
> > > > + l2x0_inv_all();
> > > > + writel(0, l2x0_base + L2X0_CTRL);
> > > > +}
> > >
> > > Even if we go this route, we need an l2x0_flush_all() rather than
> > > invalidate here as the latter removes dirty cache lines without evicting
> > > them first.
> >
> > True, but that's an implementation detail. What's more important is to
> > make a decision how to solve the problem as kexec is completely
> > unusable for all L2 systems right now.
>
> My view is that we should try to find why cache flushing doesn't work
> but unfortunately I don't have any spare time to look into this (would
> need to use tools like ICE debugging/tracing).
Simply because you need to flush the cache in the decompressor of the
new kernel before jumping into it and I doubt that Russell will be
happy about adding an utter L2 mess to the decompressor.
> > I think the correct way to deal with this is disabling L2 and let the
> > OMAP3 folks deal with it. As Tony said there is some SMI magic to do
> > that, so we can do the following:
> >
> > In l2x0_init()
> >
> > if (!l2_enabled()) {
> > if (non_secure()) {
> > omap_smi_magic_l2_enable();
> > outer_cache.disable = omap_smi_magic_l2_disable;
> > } else {
> > sane_l2_enable();
> > outer_cache.disable = sane_l2_disable;
> > }
> > }
>
> The non_secure() bit is the key. AFAIK there isn't an easy way to check
> whether you are running in secure or non-secure mode (I think there is
> some CP14 debug register telling this but those registers aren't
> mandatory in a CPU implementation).
And how does the kernel decide whether it needs to use that SMI code
in sleep34xx.S or not ?
Thanks,
tglx
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 2/2] arm: Implement l2x0 cache disable function
2010-07-02 15:29 ` Thomas Gleixner
2010-07-02 16:10 ` Catalin Marinas
@ 2010-07-02 16:48 ` Shilimkar, Santosh
1 sibling, 0 replies; 32+ messages in thread
From: Shilimkar, Santosh @ 2010-07-02 16:48 UTC (permalink / raw)
To: linux-arm-kernel
> -----Original Message-----
> From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-arm-
> kernel-bounces at lists.infradead.org] On Behalf Of Thomas Gleixner
> Sent: Friday, July 02, 2010 9:00 PM
> To: Catalin Marinas
> Cc: Tony Lindgren; LAK
> Subject: Re: [patch 2/2] arm: Implement l2x0 cache disable function
>
> On Fri, 2 Jul 2010, Catalin Marinas wrote:
>
> > On Thu, 2010-07-01 at 17:05 +0100, Thomas Gleixner wrote:
> > > This function is called from kexec code before the inner caches are
> > > disabled to prevent random crashes in the new kernel.
> > >
> > > Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> > > Index: linux-2.6/arch/arm/mm/cache-l2x0.c
> > > ===================================================================
> > > --- linux-2.6.orig/arch/arm/mm/cache-l2x0.c
> > > +++ linux-2.6/arch/arm/mm/cache-l2x0.c
> > > @@ -206,6 +206,12 @@ static void l2x0_flush_range(unsigned lo
> > > spin_unlock_irqrestore(&l2x0_lock, flags);
> > > }
> > >
> > > +static void l2x0_cache_disable(void)
> > > +{
> > > + l2x0_inv_all();
> > > + writel(0, l2x0_base + L2X0_CTRL);
> > > +}
> >
> > Even if we go this route, we need an l2x0_flush_all() rather than
> > invalidate here as the latter removes dirty cache lines without evicting
> > them first.
>
> True, but that's an implementation detail. What's more important is to
> make a decision how to solve the problem as kexec is completely
> unusable for all L2 systems right now.
>
> I think the correct way to deal with this is disabling L2 and let the
> OMAP3 folks deal with it. As Tony said there is some SMI magic to do
> that, so we can do the following:
>
Just to be clear OMAP3 don't have external(outer) L2 so the below point is actually applicable to OMAP4.
If " omap_smi_magic_l2_enable" such a generic "secure_l2x_enable" hook which
can be populated by the archs should take care of OMAP problem
> In l2x0_init()
>
> if (!l2_enabled()) {
> if (non_secure()) {
> omap_smi_magic_l2_enable();
> outer_cache.disable = omap_smi_magic_l2_disable;
> } else {
> sane_l2_enable();
> outer_cache.disable = sane_l2_disable;
> }
> }
>
> Russells patch has its own merits nevertheless as a cleanup and
> simplification, but that's a separate issue.
>
> Thoughts ?
>
> tglx
>
> _______________________________________________
> 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] 32+ messages in thread
* [patch 2/2] arm: Implement l2x0 cache disable function
2010-07-02 16:39 ` Thomas Gleixner
@ 2010-07-02 16:51 ` Shilimkar, Santosh
2010-07-02 16:54 ` Catalin Marinas
1 sibling, 0 replies; 32+ messages in thread
From: Shilimkar, Santosh @ 2010-07-02 16:51 UTC (permalink / raw)
To: linux-arm-kernel
> -----Original Message-----
> From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-arm-
> kernel-bounces at lists.infradead.org] On Behalf Of Thomas Gleixner
> Sent: Friday, July 02, 2010 10:10 PM
> To: Catalin Marinas
> Cc: Tony Lindgren; LAK
> Subject: Re: [patch 2/2] arm: Implement l2x0 cache disable function
>
> On Fri, 2 Jul 2010, Catalin Marinas wrote:
>
> > On Fri, 2010-07-02 at 16:29 +0100, Thomas Gleixner wrote:
> > > On Fri, 2 Jul 2010, Catalin Marinas wrote:
> > >
> > > > On Thu, 2010-07-01 at 17:05 +0100, Thomas Gleixner wrote:
> > > > > This function is called from kexec code before the inner caches
> are
> > > > > disabled to prevent random crashes in the new kernel.
> > > > >
> > > > > Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> > > > > Index: linux-2.6/arch/arm/mm/cache-l2x0.c
> > > > >
> ===================================================================
> > > > > --- linux-2.6.orig/arch/arm/mm/cache-l2x0.c
> > > > > +++ linux-2.6/arch/arm/mm/cache-l2x0.c
> > > > > @@ -206,6 +206,12 @@ static void l2x0_flush_range(unsigned lo
> > > > > spin_unlock_irqrestore(&l2x0_lock, flags);
> > > > > }
> > > > >
> > > > > +static void l2x0_cache_disable(void)
> > > > > +{
> > > > > + l2x0_inv_all();
> > > > > + writel(0, l2x0_base + L2X0_CTRL);
> > > > > +}
> > > >
> > > > Even if we go this route, we need an l2x0_flush_all() rather than
> > > > invalidate here as the latter removes dirty cache lines without
> evicting
> > > > them first.
> > >
> > > True, but that's an implementation detail. What's more important is to
> > > make a decision how to solve the problem as kexec is completely
> > > unusable for all L2 systems right now.
> >
> > My view is that we should try to find why cache flushing doesn't work
> > but unfortunately I don't have any spare time to look into this (would
> > need to use tools like ICE debugging/tracing).
>
> Simply because you need to flush the cache in the decompressor of the
> new kernel before jumping into it and I doubt that Russell will be
> happy about adding an utter L2 mess to the decompressor.
>
> > > I think the correct way to deal with this is disabling L2 and let the
> > > OMAP3 folks deal with it. As Tony said there is some SMI magic to do
> > > that, so we can do the following:
> > >
> > > In l2x0_init()
> > >
> > > if (!l2_enabled()) {
> > > if (non_secure()) {
> > > omap_smi_magic_l2_enable();
> > > outer_cache.disable = omap_smi_magic_l2_disable;
> > > } else {
> > > sane_l2_enable();
> > > outer_cache.disable = sane_l2_disable;
> > > }
> > > }
> >
> > The non_secure() bit is the key. AFAIK there isn't an easy way to check
> > whether you are running in secure or non-secure mode (I think there is
> > some CP14 debug register telling this but those registers aren't
> > mandatory in a CPU implementation).
>
> And how does the kernel decide whether it needs to use that SMI code
> in sleep34xx.S or not ?
>
It's OMAP3 specific code and SMI is the only way to enable or disable L2.
Regards,
Santosh
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 2/2] arm: Implement l2x0 cache disable function
2010-07-02 16:39 ` Thomas Gleixner
2010-07-02 16:51 ` Shilimkar, Santosh
@ 2010-07-02 16:54 ` Catalin Marinas
2010-07-02 17:23 ` Russell King - ARM Linux
2010-07-03 7:01 ` Shilimkar, Santosh
1 sibling, 2 replies; 32+ messages in thread
From: Catalin Marinas @ 2010-07-02 16:54 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, 2010-07-02 at 17:39 +0100, Thomas Gleixner wrote:
> On Fri, 2 Jul 2010, Catalin Marinas wrote:
>
> > On Fri, 2010-07-02 at 16:29 +0100, Thomas Gleixner wrote:
> > > On Fri, 2 Jul 2010, Catalin Marinas wrote:
> > >
> > > > On Thu, 2010-07-01 at 17:05 +0100, Thomas Gleixner wrote:
> > > > > This function is called from kexec code before the inner caches are
> > > > > disabled to prevent random crashes in the new kernel.
> > > > >
> > > > > Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> > > > > Index: linux-2.6/arch/arm/mm/cache-l2x0.c
> > > > > ===================================================================
> > > > > --- linux-2.6.orig/arch/arm/mm/cache-l2x0.c
> > > > > +++ linux-2.6/arch/arm/mm/cache-l2x0.c
> > > > > @@ -206,6 +206,12 @@ static void l2x0_flush_range(unsigned lo
> > > > > spin_unlock_irqrestore(&l2x0_lock, flags);
> > > > > }
> > > > >
> > > > > +static void l2x0_cache_disable(void)
> > > > > +{
> > > > > + l2x0_inv_all();
> > > > > + writel(0, l2x0_base + L2X0_CTRL);
> > > > > +}
> > > >
> > > > Even if we go this route, we need an l2x0_flush_all() rather than
> > > > invalidate here as the latter removes dirty cache lines without evicting
> > > > them first.
> > >
> > > True, but that's an implementation detail. What's more important is to
> > > make a decision how to solve the problem as kexec is completely
> > > unusable for all L2 systems right now.
> >
> > My view is that we should try to find why cache flushing doesn't work
> > but unfortunately I don't have any spare time to look into this (would
> > need to use tools like ICE debugging/tracing).
>
> Simply because you need to flush the cache in the decompressor of the
> new kernel before jumping into it and I doubt that Russell will be
> happy about adding an utter L2 mess to the decompressor.
The decompressor can create mappings as inner cacheable outer
non-cacheable and it would not pollute the L2 cache.
I wonder how the OMAP guys deal with an already enabled L2 cache during
decompressing.
> > > I think the correct way to deal with this is disabling L2 and let the
> > > OMAP3 folks deal with it. As Tony said there is some SMI magic to do
> > > that, so we can do the following:
> > >
> > > In l2x0_init()
> > >
> > > if (!l2_enabled()) {
> > > if (non_secure()) {
> > > omap_smi_magic_l2_enable();
> > > outer_cache.disable = omap_smi_magic_l2_disable;
> > > } else {
> > > sane_l2_enable();
> > > outer_cache.disable = sane_l2_disable;
> > > }
> > > }
> >
> > The non_secure() bit is the key. AFAIK there isn't an easy way to check
> > whether you are running in secure or non-secure mode (I think there is
> > some CP14 debug register telling this but those registers aren't
> > mandatory in a CPU implementation).
>
> And how does the kernel decide whether it needs to use that SMI code
> in sleep34xx.S or not ?
I think that's done at configuration time. But ideally we shouldn't have
different configurations for secure and non-secure modes.
--
Catalin
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 2/2] arm: Implement l2x0 cache disable function
2010-07-02 16:10 ` Catalin Marinas
2010-07-02 16:39 ` Thomas Gleixner
@ 2010-07-02 17:21 ` Russell King - ARM Linux
1 sibling, 0 replies; 32+ messages in thread
From: Russell King - ARM Linux @ 2010-07-02 17:21 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Jul 02, 2010 at 05:10:10PM +0100, Catalin Marinas wrote:
> On Fri, 2010-07-02 at 16:29 +0100, Thomas Gleixner wrote:
> > True, but that's an implementation detail. What's more important is to
> > make a decision how to solve the problem as kexec is completely
> > unusable for all L2 systems right now.
>
> My view is that we should try to find why cache flushing doesn't work
> but unfortunately I don't have any spare time to look into this (would
> need to use tools like ICE debugging/tracing).
It's quite simple. If you leave the L2 cache enabled, then the
decompressor needs to have L2 cache support in it, since it re-enables
the cache. We really don't want to go down that route.
Moreover, boot loaders will not expect L2 cache to be enabled when we
re-enter them for soft-reboot via their reset vector.
So, I agree with Thomas - we have to preserve the already stated
requirements in the kernel booting document(s) which stipulate that
caches must be disabled when the kernel is called.
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 2/2] arm: Implement l2x0 cache disable function
2010-07-02 16:54 ` Catalin Marinas
@ 2010-07-02 17:23 ` Russell King - ARM Linux
2010-07-03 7:01 ` Shilimkar, Santosh
1 sibling, 0 replies; 32+ messages in thread
From: Russell King - ARM Linux @ 2010-07-02 17:23 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Jul 02, 2010 at 05:54:40PM +0100, Catalin Marinas wrote:
> On Fri, 2010-07-02 at 17:39 +0100, Thomas Gleixner wrote:
> > Simply because you need to flush the cache in the decompressor of the
> > new kernel before jumping into it and I doubt that Russell will be
> > happy about adding an utter L2 mess to the decompressor.
>
> The decompressor can create mappings as inner cacheable outer
> non-cacheable and it would not pollute the L2 cache.
Doesn't solve the problem of boot loaders. Doesn't solve the problem
that there may be dirty cache lines left in the L2 cache which could
be searched.
There's too many "implementation" possibilities to bite us. The only
safe thing to do is to disable the L2 cache.
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 2/2] arm: Implement l2x0 cache disable function
2010-07-02 16:54 ` Catalin Marinas
2010-07-02 17:23 ` Russell King - ARM Linux
@ 2010-07-03 7:01 ` Shilimkar, Santosh
2010-07-04 14:07 ` Catalin Marinas
2010-07-04 19:09 ` Russell King - ARM Linux
1 sibling, 2 replies; 32+ messages in thread
From: Shilimkar, Santosh @ 2010-07-03 7:01 UTC (permalink / raw)
To: linux-arm-kernel
> -----Original Message-----
> From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-arm-
> kernel-bounces at lists.infradead.org] On Behalf Of Catalin Marinas
> Sent: Friday, July 02, 2010 10:25 PM
> To: Thomas Gleixner
> Cc: Tony Lindgren; LAK
> Subject: Re: [patch 2/2] arm: Implement l2x0 cache disable function
>
> On Fri, 2010-07-02 at 17:39 +0100, Thomas Gleixner wrote:
> > On Fri, 2 Jul 2010, Catalin Marinas wrote:
> >
> > > On Fri, 2010-07-02 at 16:29 +0100, Thomas Gleixner wrote:
> > > > On Fri, 2 Jul 2010, Catalin Marinas wrote:
> > > >
> > > > > On Thu, 2010-07-01 at 17:05 +0100, Thomas Gleixner wrote:
> > > > > > This function is called from kexec code before the inner caches
> are
> > > > > > disabled to prevent random crashes in the new kernel.
> > > > > >
> > > > > > Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> > > > > > Index: linux-2.6/arch/arm/mm/cache-l2x0.c
> > > > > >
> ===================================================================
> > > > > > --- linux-2.6.orig/arch/arm/mm/cache-l2x0.c
> > > > > > +++ linux-2.6/arch/arm/mm/cache-l2x0.c
> > > > > > @@ -206,6 +206,12 @@ static void l2x0_flush_range(unsigned lo
> > > > > > spin_unlock_irqrestore(&l2x0_lock, flags);
> > > > > > }
> > > > > >
> > > > > > +static void l2x0_cache_disable(void)
> > > > > > +{
> > > > > > + l2x0_inv_all();
> > > > > > + writel(0, l2x0_base + L2X0_CTRL);
> > > > > > +}
> > > > >
> > > > > Even if we go this route, we need an l2x0_flush_all() rather than
> > > > > invalidate here as the latter removes dirty cache lines without
> evicting
> > > > > them first.
> > > >
> > > > True, but that's an implementation detail. What's more important is
> to
> > > > make a decision how to solve the problem as kexec is completely
> > > > unusable for all L2 systems right now.
> > >
> > > My view is that we should try to find why cache flushing doesn't work
> > > but unfortunately I don't have any spare time to look into this (would
> > > need to use tools like ICE debugging/tracing).
> >
> > Simply because you need to flush the cache in the decompressor of the
> > new kernel before jumping into it and I doubt that Russell will be
> > happy about adding an utter L2 mess to the decompressor.
>
> The decompressor can create mappings as inner cacheable outer
> non-cacheable and it would not pollute the L2 cache.
>
> I wonder how the OMAP guys deal with an already enabled L2 cache during
> decompressing.
$L2 isn't enabled during the decompression. It's done " __v7_setup" on OMAP3
and just before " l2x0_init" on OMAP4
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 2/2] arm: Implement l2x0 cache disable function
2010-07-03 7:01 ` Shilimkar, Santosh
@ 2010-07-04 14:07 ` Catalin Marinas
2010-07-04 15:31 ` Shilimkar, Santosh
2010-07-04 19:09 ` Russell King - ARM Linux
1 sibling, 1 reply; 32+ messages in thread
From: Catalin Marinas @ 2010-07-04 14:07 UTC (permalink / raw)
To: linux-arm-kernel
On Sat, 2010-07-03 at 08:01 +0100, Shilimkar, Santosh wrote:
> > From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-arm-
> > kernel-bounces at lists.infradead.org] On Behalf Of Catalin Marinas
> > On Fri, 2010-07-02 at 17:39 +0100, Thomas Gleixner wrote:
> > > On Fri, 2 Jul 2010, Catalin Marinas wrote:
> > > > My view is that we should try to find why cache flushing doesn't work
> > > > but unfortunately I don't have any spare time to look into this (would
> > > > need to use tools like ICE debugging/tracing).
> > >
> > > Simply because you need to flush the cache in the decompressor of the
> > > new kernel before jumping into it and I doubt that Russell will be
> > > happy about adding an utter L2 mess to the decompressor.
> >
> > The decompressor can create mappings as inner cacheable outer
> > non-cacheable and it would not pollute the L2 cache.
> >
> > I wonder how the OMAP guys deal with an already enabled L2 cache during
> > decompressing.
>
> $L2 isn't enabled during the decompression. It's done " __v7_setup" on OMAP3
> and just before " l2x0_init" on OMAP4
Another approach would have been to mark the page tables as outer
non-cacheable in the decompressor.
Anyway, if you already handle L2 cache initialisation during __v7_setup
(and we could go back to a thread where I asked for per-platform CPU
initialisation support), you could handle L2 cache disabling as well.
As per Thomas' patches, the outer_cache_fns structure has a .disable()
function and this can be overridden by the OMAP code after l2x0_init().
The only additional comment I have to Thomas' second patch is that the
l2x0_cache_disable() implementation has to flush (clean+inv) the L2
cache (rather than just invalidate) and then disable by writing the L2
control register. The L2 flushing function doesn't need to be exported
via outer_cache_fns since it's only the disabling that would handle it.
--
Catalin
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 2/2] arm: Implement l2x0 cache disable function
2010-07-04 14:07 ` Catalin Marinas
@ 2010-07-04 15:31 ` Shilimkar, Santosh
0 siblings, 0 replies; 32+ messages in thread
From: Shilimkar, Santosh @ 2010-07-04 15:31 UTC (permalink / raw)
To: linux-arm-kernel
> -----Original Message-----
> From: Catalin Marinas [mailto:catalin.marinas at arm.com]
> Sent: Sunday, July 04, 2010 7:37 PM
> To: Shilimkar, Santosh
> Cc: Thomas Gleixner; Tony Lindgren; LAK
> Subject: RE: [patch 2/2] arm: Implement l2x0 cache disable function
>
> On Sat, 2010-07-03 at 08:01 +0100, Shilimkar, Santosh wrote:
> > > From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-arm-
> > > kernel-bounces at lists.infradead.org] On Behalf Of Catalin Marinas
> > > On Fri, 2010-07-02 at 17:39 +0100, Thomas Gleixner wrote:
> > > > On Fri, 2 Jul 2010, Catalin Marinas wrote:
> > > > > My view is that we should try to find why cache flushing doesn't
> work
> > > > > but unfortunately I don't have any spare time to look into this
> (would
> > > > > need to use tools like ICE debugging/tracing).
> > > >
> > > > Simply because you need to flush the cache in the decompressor of
> the
> > > > new kernel before jumping into it and I doubt that Russell will be
> > > > happy about adding an utter L2 mess to the decompressor.
> > >
> > > The decompressor can create mappings as inner cacheable outer
> > > non-cacheable and it would not pollute the L2 cache.
> > >
> > > I wonder how the OMAP guys deal with an already enabled L2 cache
> during
> > > decompressing.
> >
> > $L2 isn't enabled during the decompression. It's done " __v7_setup" on
> OMAP3
> > and just before " l2x0_init" on OMAP4
>
> Another approach would have been to mark the page tables as outer
> non-cacheable in the decompressor.
>
> Anyway, if you already handle L2 cache initialisation during __v7_setup
> (and we could go back to a thread where I asked for per-platform CPU
> initialisation support), you could handle L2 cache disabling as well.
>
Such a hook would be really nice. We have been discussing this for some
time.
> As per Thomas' patches, the outer_cache_fns structure has a .disable()
> function and this can be overridden by the OMAP code after l2x0_init().
>
Yes. That's good idea.
> The only additional comment I have to Thomas' second patch is that the
> l2x0_cache_disable() implementation has to flush (clean+inv) the L2
> cache (rather than just invalidate) and then disable by writing the L2
> control register. The L2 flushing function doesn't need to be exported
> via outer_cache_fns since it's only the disabling that would handle it.
>
Exporting a l2x0_flush_all would be good as well if it's not a problem.
Regards,
Santosh
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 2/2] arm: Implement l2x0 cache disable function
2010-07-03 7:01 ` Shilimkar, Santosh
2010-07-04 14:07 ` Catalin Marinas
@ 2010-07-04 19:09 ` Russell King - ARM Linux
2010-07-05 9:12 ` Catalin Marinas
1 sibling, 1 reply; 32+ messages in thread
From: Russell King - ARM Linux @ 2010-07-04 19:09 UTC (permalink / raw)
To: linux-arm-kernel
On Sat, Jul 03, 2010 at 12:31:53PM +0530, Shilimkar, Santosh wrote:
> > -----Original Message-----
> > From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-arm-
> > kernel-bounces at lists.infradead.org] On Behalf Of Catalin Marinas
> > Sent: Friday, July 02, 2010 10:25 PM
> > To: Thomas Gleixner
> > Cc: Tony Lindgren; LAK
> > Subject: Re: [patch 2/2] arm: Implement l2x0 cache disable function
> >
> > On Fri, 2010-07-02 at 17:39 +0100, Thomas Gleixner wrote:
> > > Simply because you need to flush the cache in the decompressor of the
> > > new kernel before jumping into it and I doubt that Russell will be
> > > happy about adding an utter L2 mess to the decompressor.
> >
> > The decompressor can create mappings as inner cacheable outer
> > non-cacheable and it would not pollute the L2 cache.
> >
> > I wonder how the OMAP guys deal with an already enabled L2 cache during
> > decompressing.
>
> $L2 isn't enabled during the decompression. It's done " __v7_setup" on OMAP3
> and just before " l2x0_init" on OMAP4
Not on the initial kernel, but on subsequent kernels booted via kexec,
because of this issue, L2 will be enabled.
So when the decompressor comes to set up its own page tables - it uses
the non-XP format - it ends up with tables setup with C=B=1, which
is interpreted as fully cacheable. As the L2 unit is still enabled,
this causes the region to be cacheable at L2 as well as L1 - which
is not what the decompressor expects.
The result is that cache lines get loaded into L2, and marked dirty.
When the decompressor then turns off the cache in order to call the
kernel, things go awol because the dirty lines in L2 haven't been
flushed out.
I think it's overkill to add L2 support to the decompressor - and I
also think it's overkill to teach the decompressor about the XP format
tables, especially as the booting documents clearly state that caches
shall be disabled before calling the kernel. Also, we really can't
insist that this is the case for boot loaders, and then do something
different when we call the next kernel.
Also consider the case where the kernel you're booting into doesn't
have L2 support enabled - maybe you disabled L2 support because it's
causing problems. If you boot with L2 already enabled, then this
kernel is going to struggle because it can't handle the enabled L2.
As I've already said, the boot loader case won't expect to be called
via its reset vector with L2 enabled either - and could well go wrong
if this is done.
So, all the ways you look at it, having L2 enabled when you're exiting
the kernel to call some other piece of code (such as boot loader or
decompressor) is asking for trouble.
Let's ensure that we bring L2 to a clean and disabled state prior to
invoking a boot loader or subsequent kernel - even if that means we
have to make SMC calls to achieve that.
^ permalink raw reply [flat|nested] 32+ messages in thread
* [patch 2/2] arm: Implement l2x0 cache disable function
2010-07-04 19:09 ` Russell King - ARM Linux
@ 2010-07-05 9:12 ` Catalin Marinas
0 siblings, 0 replies; 32+ messages in thread
From: Catalin Marinas @ 2010-07-05 9:12 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, 2010-07-04 at 20:09 +0100, Russell King - ARM Linux wrote:
> On Sat, Jul 03, 2010 at 12:31:53PM +0530, Shilimkar, Santosh wrote:
> > > -----Original Message-----
> > > From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-arm-
> > > kernel-bounces at lists.infradead.org] On Behalf Of Catalin Marinas
> > > Sent: Friday, July 02, 2010 10:25 PM
> > > To: Thomas Gleixner
> > > Cc: Tony Lindgren; LAK
> > > Subject: Re: [patch 2/2] arm: Implement l2x0 cache disable function
> > >
> > > On Fri, 2010-07-02 at 17:39 +0100, Thomas Gleixner wrote:
> > > > Simply because you need to flush the cache in the decompressor of the
> > > > new kernel before jumping into it and I doubt that Russell will be
> > > > happy about adding an utter L2 mess to the decompressor.
> > >
> > > The decompressor can create mappings as inner cacheable outer
> > > non-cacheable and it would not pollute the L2 cache.
> > >
> > > I wonder how the OMAP guys deal with an already enabled L2 cache during
> > > decompressing.
> >
> > $L2 isn't enabled during the decompression. It's done " __v7_setup" on OMAP3
> > and just before " l2x0_init" on OMAP4
[...]
> I think it's overkill to add L2 support to the decompressor - and I
> also think it's overkill to teach the decompressor about the XP format
> tables,
Even if we did this, the secure software needs to be aware of OS
rebooting since it may have a non-secure cacheable mapping which is
speculatively fetched (and I was also told that the L2 treats the secure
access bit as an address one - so you get separate cache lines for
secure and non-secure).
> Also consider the case where the kernel you're booting into doesn't
> have L2 support enabled - maybe you disabled L2 support because it's
> causing problems. If you boot with L2 already enabled, then this
> kernel is going to struggle because it can't handle the enabled L2.
You could have an outer non-cacheable cache policy and set the page
table bits accordingly. But I agree with you, it's not worth the extra
effort.
> Let's ensure that we bring L2 to a clean and disabled state prior to
> invoking a boot loader or subsequent kernel - even if that means we
> have to make SMC calls to achieve that.
So Thomas' original patches are pretty much OK, with the exception of
using clean+invalidate instead of just invalidate during disabling.
An additional question - do we need to flush the L2 cache again after it
was disabled, just in case we got some speculative loads?
--
Catalin
^ permalink raw reply [flat|nested] 32+ messages in thread
end of thread, other threads:[~2010-07-05 9:12 UTC | newest]
Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-01 16:05 [patch 0/2] ARM: Disable outer cache before kexec call Thomas Gleixner
2010-07-01 16:05 ` [patch 1/2] arm: Disable outer (L2) cache in kexec Thomas Gleixner
2010-07-01 16:05 ` [patch 2/2] arm: Implement l2x0 cache disable function Thomas Gleixner
[not found] ` <AANLkTillHUsJF8brOtHh8tl9Us493GsWfpjhXXsFExY7@mail.gmail.com>
2010-07-02 11:23 ` srinidhi
2010-07-02 11:47 ` Catalin Marinas
2010-07-02 15:29 ` Thomas Gleixner
2010-07-02 16:10 ` Catalin Marinas
2010-07-02 16:39 ` Thomas Gleixner
2010-07-02 16:51 ` Shilimkar, Santosh
2010-07-02 16:54 ` Catalin Marinas
2010-07-02 17:23 ` Russell King - ARM Linux
2010-07-03 7:01 ` Shilimkar, Santosh
2010-07-04 14:07 ` Catalin Marinas
2010-07-04 15:31 ` Shilimkar, Santosh
2010-07-04 19:09 ` Russell King - ARM Linux
2010-07-05 9:12 ` Catalin Marinas
2010-07-02 17:21 ` Russell King - ARM Linux
2010-07-02 16:48 ` Shilimkar, Santosh
2010-07-01 16:14 ` [patch 0/2] ARM: Disable outer cache before kexec call Catalin Marinas
2010-07-01 16:28 ` Thomas Gleixner
2010-07-01 16:35 ` Catalin Marinas
2010-07-01 16:52 ` Thomas Gleixner
2010-07-01 17:14 ` Catalin Marinas
2010-07-02 10:58 ` Tony Lindgren
2010-07-01 16:38 ` Shilimkar, Santosh
2010-07-01 16:41 ` Catalin Marinas
2010-07-01 16:44 ` Shilimkar, Santosh
2010-07-01 17:06 ` Russell King - ARM Linux
2010-07-01 17:21 ` Russell King - ARM Linux
2010-07-01 17:34 ` Catalin Marinas
2010-07-01 17:48 ` Russell King - ARM Linux
2010-07-01 20:08 ` Thomas Gleixner
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).