Skip to contentSkip to conversation

ARM: socfpga: put back v7_invalidate_l1 in socfpga_secondary_startup

PATCH New dinguyen at opensource.altera.com 4 participants 13 messages Jul 8, 2015 – Jul 16, 2015

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ARM: socfpga: put back v7_invalidate_l1 in socfpga_secondary_startup

From: Dinh Nguyen <[email protected]>

The commit "02b4e2756e01 ARM: v7 setup function should invalidate L1 cache" caused the SoCFPGA to not boot reliably. About 20% of the time or roughly (1 in 5), booting the platform would cause this kernel panic:

CPU1: thread -1, cpu 1, socket 0, mpidr 80000001

Internal error: Oops - undefined instruction: 0 [#1] SMP ARM
Modules linked in:
CPU: 1 PID: 0 Comm: swapper/1 Not tainted
4.1.0-rc8-next-20150617-00002-gdd1f624 #1
Hardware name: Altera SOCFPGA
task: eecaeac0 ti: eecce000 task.ti: eecce000
PC is at vfp_notifier+0x58/0x12c
LR is at notifier_call_chain+0x44/0x84
pc : [<c000a6bc>]    lr : [<c003d134>]    psr: 80000193

sp : eeccff48 ip : c06563c8 fp : eeccffd4
r10: eecaef80 r9 : ef1f1300 r8 : 00000002
r7 : eecd0000 r6 : c0656bc0 r5 : 00000000 r4 : eecd0000 r3 : c000a664 r2 : eecd0000 r1 : 00000002 r0 : c06563c8
Flags: Nzcv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel
Control: 10c5387d Table: 0000404a DAC: 00000015
Process swapper/1 (pid: 0, stack limit = 0xeecce218)

Stack: (0xeeccff48 to 0xeecd0000)

ff40: c000a664 ffffffff 00000000 c003d134 eecd0018 eecaeac0
ff60: c06648e0 0b52d2f9 c048cfa8 c003d18c 00000000 f0002100 00000001 c003d1ac
ff80: 00000000 eecaeac0 c064f300 c001369c c064b304 c0013140 00000000 ef1ed328
ffa0: eeccffe8 c001e760 c0486ec4 2eba2000 c06957c0 c06524dc 00000015 c06957c0
ffc0: c048c778 c064b304 c06957c0 00000000 eeccffdc c0486ec4 eeccffe4 c0487138
ffe0: 00000001 c00544e8 c0009494 c0697bc0 00000000 000094ac 7ef5bffd 3f39b3f8 [<c000a6bc>] (vfp_notifier) from [<c003d134>] (notifier_call_chain+0x44/0x84) [<c003d134>] (notifier_call_chain) from [<c003d18c>] (__atomic_notifier_call_chain+0x18/0x20)
[<c003d18c>] (__atomic_notifier_call_chain) from [<c003d1ac>] (atomic_notifier_call_chain+0x18/0x20)
[<c003d1ac>] (atomic_notifier_call_chain) from [<c001369c>] (__switch_to+0x34/0x58)

Code: e3a03002 e5843208 e3a00000 e8bd8038 (eef85a10)
---[ end trace 9eaea9661b3b550a ]---
Kernel panic - not syncing: Attempted to kill the idle task!
SMP: failed to stop secondary CPUs
---[ end Kernel panic - not syncing: Attempted to kill the idle task!

So this patch puts back the call to v7_invalidate_l1 in the secondary_startup path, and the platform is now able to boot up reliably.

---
 arch/arm/mach-socfpga/core.h    |    1 +
 arch/arm/mach-socfpga/headsmp.S |    5 +++++
 arch/arm/mach-socfpga/platsmp.c |    2 +-
 3 files changed, 7 insertions(+), 1 deletion(-)
arch/arm/mach-socfpga/core.h +1 -0
index 7259c37..30d7988 100644
@@ -33,6 +33,7 @@
 
 #define RSTMGR_MPUMODRST_CPU1		0x2     /* CPU1 Reset */
 
+extern void socfpga_secondary_startup(void);
 extern void socfpga_init_clocks(void);
 extern void socfpga_sysmgr_init(void);
 
arch/arm/mach-socfpga/headsmp.S +5 -0
index 5d94b7a..a521413 100644
@@ -33,3 +33,8 @@ ARM_BE8(rev	r4, r4)
 1:	.long	.
 	.long	socfpga_cpu1start_addr
 ENTRY(secondary_trampoline_end)
+
+ENTRY(socfpga_secondary_startup)
+	bl      v7_invalidate_l1
+	b       secondary_startup
+ENDPROC(socfpga_secondary_startup)
arch/arm/mach-socfpga/platsmp.c +1 -1
index c6f1df8..7ed6127 100644
@@ -40,7 +40,7 @@ static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle)
 
 		memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size);
 
-		writel(virt_to_phys(secondary_startup),
+		writel(virt_to_phys(socfpga_secondary_startup),
 		       sys_manager_base_addr + (socfpga_cpu1start_addr & 0x000000ff));
 
 		flush_cache_all();
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH 1/1 ARM: socfpga: put back v7_invalidate_l1 in socfpga_secondary_startup

Quoted 43 lines · dinguyen at opensource.altera.com

From: Dinh Nguyen <[email protected]>

The commit "02b4e2756e01 ARM: v7 setup function should invalidate L1 cache" caused the SoCFPGA to not boot reliably. About 20% of the time or roughly (1 in 5), booting the platform would cause this kernel panic:

CPU1: thread -1, cpu 1, socket 0, mpidr 80000001

Internal error: Oops - undefined instruction: 0 [#1] SMP ARM
Modules linked in:
CPU: 1 PID: 0 Comm: swapper/1 Not tainted
4.1.0-rc8-next-20150617-00002-gdd1f624 #1
Hardware name: Altera SOCFPGA
task: eecaeac0 ti: eecce000 task.ti: eecce000
PC is at vfp_notifier+0x58/0x12c
LR is at notifier_call_chain+0x44/0x84
pc : [<c000a6bc>]    lr : [<c003d134>]    psr: 80000193

sp : eeccff48 ip : c06563c8 fp : eeccffd4
r10: eecaef80 r9 : ef1f1300 r8 : 00000002
r7 : eecd0000 r6 : c0656bc0 r5 : 00000000 r4 : eecd0000 r3 : c000a664 r2 : eecd0000 r1 : 00000002 r0 : c06563c8
Flags: Nzcv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel
Control: 10c5387d Table: 0000404a DAC: 00000015
Process swapper/1 (pid: 0, stack limit = 0xeecce218)

Stack: (0xeeccff48 to 0xeecd0000)

ff40: c000a664 ffffffff 00000000 c003d134 eecd0018 eecaeac0
ff60: c06648e0 0b52d2f9 c048cfa8 c003d18c 00000000 f0002100 00000001 c003d1ac
ff80: 00000000 eecaeac0 c064f300 c001369c c064b304 c0013140 00000000 ef1ed328
ffa0: eeccffe8 c001e760 c0486ec4 2eba2000 c06957c0 c06524dc 00000015 c06957c0
ffc0: c048c778 c064b304 c06957c0 00000000 eeccffdc c0486ec4 eeccffe4 c0487138
ffe0: 00000001 c00544e8 c0009494 c0697bc0 00000000 000094ac 7ef5bffd 3f39b3f8 [<c000a6bc>] (vfp_notifier) from [<c003d134>] (notifier_call_chain+0x44/0x84) [<c003d134>] (notifier_call_chain) from [<c003d18c>] (__atomic_notifier_call_chain+0x18/0x20)
[<c003d18c>] (__atomic_notifier_call_chain) from [<c003d1ac>] (atomic_notifier_call_chain+0x18/0x20)
[<c003d1ac>] (atomic_notifier_call_chain) from [<c001369c>] (__switch_to+0x34/0x58)

Code: e3a03002 e5843208 e3a00000 e8bd8038 (eef85a10)
---[ end trace 9eaea9661b3b550a ]---
Kernel panic - not syncing: Attempted to kill the idle task!
SMP: failed to stop secondary CPUs
---[ end Kernel panic - not syncing: Attempted to kill the idle task!
Quoted 4 lines

So this patch puts back the call to v7_invalidate_l1 in the secondary_startup path, and the platform is now able to boot up reliably.

Can you print the value of CPACR in the oops and reproduce please? I suspect, somehow, the CPACR is not allowing CPU1 access to the VFP, but this is not controlled by data as such (it can only go wrong if the hotplug notifier call chain misses calling into the VFP code.)

We ought to understand what the cause of this is before reverting this part of the patch. Not having a SoCFPGA board means that I can't do any investigation of this myself.

Signature · 2 lines
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.
#2 lore raw

PATCH 1/1 ARM: socfpga: put back v7_invalidate_l1 in socfpga_secondary_startup

Quoted 47 lines · Russell King - ARM Linux
Quoted 46 lines · dinguyen at opensource.altera.com

From: Dinh Nguyen <[email protected]>

The commit "02b4e2756e01 ARM: v7 setup function should invalidate L1 cache" caused the SoCFPGA to not boot reliably. About 20% of the time or roughly (1 in 5), booting the platform would cause this kernel panic:

CPU1: thread -1, cpu 1, socket 0, mpidr 80000001

Internal error: Oops - undefined instruction: 0 [#1] SMP ARM
Modules linked in:
CPU: 1 PID: 0 Comm: swapper/1 Not tainted
4.1.0-rc8-next-20150617-00002-gdd1f624 #1
Hardware name: Altera SOCFPGA
task: eecaeac0 ti: eecce000 task.ti: eecce000
PC is at vfp_notifier+0x58/0x12c
LR is at notifier_call_chain+0x44/0x84
pc : [<c000a6bc>]    lr : [<c003d134>]    psr: 80000193

sp : eeccff48 ip : c06563c8 fp : eeccffd4
r10: eecaef80 r9 : ef1f1300 r8 : 00000002
r7 : eecd0000 r6 : c0656bc0 r5 : 00000000 r4 : eecd0000 r3 : c000a664 r2 : eecd0000 r1 : 00000002 r0 : c06563c8
Flags: Nzcv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel
Control: 10c5387d Table: 0000404a DAC: 00000015
Process swapper/1 (pid: 0, stack limit = 0xeecce218)

Stack: (0xeeccff48 to 0xeecd0000)

ff40: c000a664 ffffffff 00000000 c003d134 eecd0018 eecaeac0
ff60: c06648e0 0b52d2f9 c048cfa8 c003d18c 00000000 f0002100 00000001 c003d1ac
ff80: 00000000 eecaeac0 c064f300 c001369c c064b304 c0013140 00000000 ef1ed328
ffa0: eeccffe8 c001e760 c0486ec4 2eba2000 c06957c0 c06524dc 00000015 c06957c0
ffc0: c048c778 c064b304 c06957c0 00000000 eeccffdc c0486ec4 eeccffe4 c0487138
ffe0: 00000001 c00544e8 c0009494 c0697bc0 00000000 000094ac 7ef5bffd 3f39b3f8 [<c000a6bc>] (vfp_notifier) from [<c003d134>] (notifier_call_chain+0x44/0x84) [<c003d134>] (notifier_call_chain) from [<c003d18c>] (__atomic_notifier_call_chain+0x18/0x20)
[<c003d18c>] (__atomic_notifier_call_chain) from [<c003d1ac>] (atomic_notifier_call_chain+0x18/0x20)
[<c003d1ac>] (atomic_notifier_call_chain) from [<c001369c>] (__switch_to+0x34/0x58)

Code: e3a03002 e5843208 e3a00000 e8bd8038 (eef85a10)
---[ end trace 9eaea9661b3b550a ]---
Kernel panic - not syncing: Attempted to kill the idle task!
SMP: failed to stop secondary CPUs
---[ end Kernel panic - not syncing: Attempted to kill the idle task!

So this patch puts back the call to v7_invalidate_l1 in the secondary_startup path, and the platform is now able to boot up reliably.

Quoted 7 lines
Quoted 1 line

Can you print the value of CPACR in the oops and reproduce please? I suspect, somehow, the CPACR is not allowing CPU1 access to the VFP, but this is not controlled by data as such (it can only go wrong if the hotplug notifier call chain misses calling into the VFP code.)

The value of CPACR is 0x00F00000. So cp11 and cp10 are privileged and user mode access.

Dinh

#3 lore raw

PATCH 1/1 ARM: socfpga: put back v7_invalidate_l1 in socfpga_secondary_startup

Quoted 2 lines · Dinh Nguyen

The value of CPACR is 0x00F00000. So cp11 and cp10 are privileged and user mode access.

Hmm.

I think what you've found is a(nother) latent bug in the CPU bring up code.

For SMP CPUs, the sequence we're following during early initialisation is:

1. Enable SMP coherency.
2. Invalidate the caches.

If the cache contains rubbish, enabling SMP coherency before invalidating the cache is plainly an absurd thing to do.

Can you try the patch below - not tested in any way, so you may need to tweak it, but it should allow us to prove that point.

arch/arm/mm/proc-v7.S +7 -2
index 0716bbe19872..db5137fc297d 100644
@@ -275,6 +275,10 @@ __v7_b15mp_setup:
 __v7_ca17mp_setup:
 	mov	r10, #0
 1:
+	adr	r12, __v7_setup_stack		@ the local stack
+	stmia	r12, {r0-r5, r7, r9-r11, lr}
+	bl      v7_invalidate_l1
+	ldmia	r12, {r0-r5, r7, r9-r11, lr}
 #ifdef CONFIG_SMP
 	ALT_SMP(mrc	p15, 0, r0, c1, c0, 1)
 	ALT_UP(mov	r0, #(1 << 6))		@ fake it for UP
@@ -283,7 +287,7 @@ __v7_ca17mp_setup:
 	orreq	r0, r0, r10			@ Enable CPU-specific SMP bits
 	mcreq	p15, 0, r0, c1, c0, 1
 #endif
-	b	__v7_setup
+	b	__v7_setup_cont
 
 /*
  * Errata:
@@ -417,6 +421,7 @@ __v7_setup:
 	bl      v7_invalidate_l1
 	ldmia	r12, {r0-r5, r7, r9, r11, lr}
 
+__v7_setup_cont:
 	and	r0, r9, #0xff000000		@ ARM?
 	teq	r0, #0x41000000
 	bne	__errata_finish
@@ -480,7 +485,7 @@ ENDPROC(__v7_setup)
 
 	.align	2
 __v7_setup_stack:
-	.space	4 * 11				@ 11 registers
+	.space	4 * 12				@ 12 registers
 
 	__INITDATA
 
Signature · 2 lines
FTTC broadband for 0.8mile line: [email protected] down 400kbps up
according to speedtest.net.
#4 lore raw

PATCH 1/1 ARM: socfpga: put back v7_invalidate_l1 in socfpga_secondary_startup

Quoted 54 lines · Russell King - ARM Linux
Quoted 2 lines · Dinh Nguyen

The value of CPACR is 0x00F00000. So cp11 and cp10 are privileged and user mode access.

Hmm.

I think what you've found is a(nother) latent bug in the CPU bring up code.

For SMP CPUs, the sequence we're following during early initialisation is:

1. Enable SMP coherency.
2. Invalidate the caches.

If the cache contains rubbish, enabling SMP coherency before invalidating the cache is plainly an absurd thing to do.

Can you try the patch below - not tested in any way, so you may need to tweak it, but it should allow us to prove that point.

arch/arm/mm/proc-v7.S +6 -1
index 0716bbe19872..db5137fc297d 100644
@@ -275,6 +275,10 @@ __v7_b15mp_setup:
 __v7_ca17mp_setup:
 	mov	r10, #0
 1:
+	adr	r12, __v7_setup_stack		@ the local stack
+	stmia	r12, {r0-r5, r7, r9-r11, lr}
+	bl      v7_invalidate_l1
+	ldmia	r12, {r0-r5, r7, r9-r11, lr}
 #ifdef CONFIG_SMP
 	ALT_SMP(mrc	p15, 0, r0, c1, c0, 1)
 	ALT_UP(mov	r0, #(1 << 6))		@ fake it for UP
@@ -283,7 +287,7 @@ __v7_ca17mp_setup:
 	orreq	r0, r0, r10			@ Enable CPU-specific SMP bits
 	mcreq	p15, 0, r0, c1, c0, 1
 #endif
-	b	__v7_setup
+	b	__v7_setup_cont
 
 /*
  * Errata:
@@ -417,6 +421,7 @@ __v7_setup:
 	bl      v7_invalidate_l1
 	ldmia	r12, {r0-r5, r7, r9, r11, lr}
 
+__v7_setup_cont:
 	and	r0, r9, #0xff000000		@ ARM?
 	teq	r0, #0x41000000
 	bne	__errata_finish

arch/arm/mm/proc-v7.S ENDPROC(__v7_setup) · line 491

Quoted 8 lines
arch/arm/mm/proc-v7.S +1 -1
@@ -480,7 +485,7 @@ ENDPROC(__v7_setup)
 
 	.align	2
 __v7_setup_stack:
-	.space	4 * 11				@ 11 registers
+	.space	4 * 12				@ 12 registers
 
 	__INITDATA
 

This patch seems to have fixed the issue. The SoCFPGA platform is now booting/rebooting reliably. Also, the patch was applicable as-is.

Also, I went back and studied up on the CPACR register. I misquoted the value in my previous response, I was looking at CPACR on CPU0. For CPU1, when the error happens, the value of CPACR is 0x0, so CP10 and CP11 were set to "Access denied".

Dinh

#5 lore raw

PATCH 1/1 ARM: socfpga: put back v7_invalidate_l1 in socfpga_secondary_startup

In reply to Russell King - ARM Linux

Dear Russell,

Quoted 25 lines · On Wed, 8 Jul 2015 22:07:34 +0100 Russell King - ARM Linux…
Quoted 2 lines · Dinh Nguyen

The value of CPACR is 0x00F00000. So cp11 and cp10 are privileged and user mode access.

Hmm.

I think what you've found is a(nother) latent bug in the CPU bring up code.

For SMP CPUs, the sequence we're following during early initialisation is:

1. Enable SMP coherency.
2. Invalidate the caches.

If the cache contains rubbish, enabling SMP coherency before invalidating the cache is plainly an absurd thing to do.

Can you try the patch below - not tested in any way, so you may need to tweak it, but it should allow us to prove that point.

arch/arm/mm/proc-v7.S +0 -0
index 0716bbe19872..db5137fc297d 100644

arch/arm/mm/proc-v7.S __v7_b15mp_setup: · line 281

Quoted 7 lines
arch/arm/mm/proc-v7.S +4 -0
@@ -275,6 +275,10 @@ __v7_b15mp_setup:
 __v7_ca17mp_setup:
 	mov	r10, #0
 1:
+	adr	r12, __v7_setup_stack		@ the local stack
+	stmia	r12, {r0-r5, r7, r9-r11, lr}
+	bl      v7_invalidate_l1
+	ldmia	r12, {r0-r5, r7, r9-r11, lr}

Some CPUs such as CA7 need enable SMP before any cache maintenance.

CA7 TRM says something about SMP bit:
"You must ensure this bit is set to 1 before the caches and MMU are enabled, or any cache and TLB maintenance operations are performed."

So it seems we need to use different path for different CPUs.

Also CA7 would invalidate L1 automatically once reset, can we remove the invalidate op in CA7 case?

I'm not sure I understand the code correctly, criticism is welcome.

Thanks,
Jisheng

Quoted 29 lines
arch/arm/mm/proc-v7.S +3 -2
 #ifdef CONFIG_SMP
 	ALT_SMP(mrc	p15, 0, r0, c1, c0, 1)
 	ALT_UP(mov	r0, #(1 << 6))		@ fake it for UP
@@ -283,7 +287,7 @@ __v7_ca17mp_setup:
 	orreq	r0, r0, r10			@ Enable CPU-specific SMP bits
 	mcreq	p15, 0, r0, c1, c0, 1
 #endif
-	b	__v7_setup
+	b	__v7_setup_cont
 
 /*
  * Errata:
@@ -417,6 +421,7 @@ __v7_setup:
 	bl      v7_invalidate_l1
 	ldmia	r12, {r0-r5, r7, r9, r11, lr}
 
+__v7_setup_cont:
 	and	r0, r9, #0xff000000		@ ARM?
 	teq	r0, #0x41000000
 	bne	__errata_finish
@@ -480,7 +485,7 @@ ENDPROC(__v7_setup)
 
 	.align	2
 __v7_setup_stack:
-	.space	4 * 11				@ 11 registers
+	.space	4 * 12				@ 12 registers
 
 	__INITDATA
 
#6 lore raw

PATCH 1/1 ARM: socfpga: put back v7_invalidate_l1 in socfpga_secondary_startup

Quoted 40 lines · Jisheng Zhang

Dear Russell,

Quoted 25 lines · On Wed, 8 Jul 2015 22:07:34 +0100 Russell King - ARM Linux…
Quoted 2 lines · Dinh Nguyen

The value of CPACR is 0x00F00000. So cp11 and cp10 are privileged and user mode access.

Hmm.

I think what you've found is a(nother) latent bug in the CPU bring up code.

For SMP CPUs, the sequence we're following during early initialisation is:

1. Enable SMP coherency.
2. Invalidate the caches.

If the cache contains rubbish, enabling SMP coherency before invalidating the cache is plainly an absurd thing to do.

Can you try the patch below - not tested in any way, so you may need to tweak it, but it should allow us to prove that point.

arch/arm/mm/proc-v7.S +0 -0
index 0716bbe19872..db5137fc297d 100644

arch/arm/mm/proc-v7.S __v7_b15mp_setup: · line 281

Quoted 7 lines
arch/arm/mm/proc-v7.S +4 -0
@@ -275,6 +275,10 @@ __v7_b15mp_setup:
 __v7_ca17mp_setup:
 	mov	r10, #0
 1:
+	adr	r12, __v7_setup_stack		@ the local stack
+	stmia	r12, {r0-r5, r7, r9-r11, lr}
+	bl      v7_invalidate_l1
+	ldmia	r12, {r0-r5, r7, r9-r11, lr}

Some CPUs such as CA7 need enable SMP before any cache maintenance.

Quoted 3 lines

CA7 TRM says something about SMP bit:
"You must ensure this bit is set to 1 before the caches and MMU are enabled, or any cache and TLB maintenance operations are performed."

Frankly, that's wrong for two reasons. Think about it for a moment...

If the cache contains crap - in other words, it contains random uninitialised data in the cache lines at random locations, some of which are marked valid and some of which are marked dirty - then enabling the SMP bit puts the caches into coherent mode, and they join the coherent cluster.

That means those cache lines containing crap become visible to other CPUs in the cluster, and can be migrated to other CPUs, and the crap data in them becomes visible to other CPUs. This leads to state corruption on other CPUs in the cluster.

Moreover, the cache invalidation of the local L1 cache is broadcast to other CPUs in the cluster, and _their_ caches are also invalidated, again, leading to state corruption on already running CPUs. We don't want the invalidation of the incoming CPU to be broadcast to the other CPUs.

This is all round a very bad thing.

Quoted 2 lines

Also CA7 would invalidate L1 automatically once reset, can we remove the invalidate op in CA7 case?

No, because we enter this path from multiple different situations, eg, after the decompressor has run, after the boot loader has run which may have enabled caches and not properly invalidated them prior to calling the kernel.

Signature · 2 lines
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.
#7 lore raw

PATCH 1/1 ARM: socfpga: put back v7_invalidate_l1 in socfpga_secondary_startup

Dear Russell,

Quoted 66 lines · On Thu, 9 Jul 2015 08:57:17 +0100 Russell King - ARM Linux…
Quoted 40 lines · Jisheng Zhang

Dear Russell,

Quoted 25 lines · On Wed, 8 Jul 2015 22:07:34 +0100 Russell King - ARM Linux…
Quoted 2 lines · Dinh Nguyen

The value of CPACR is 0x00F00000. So cp11 and cp10 are privileged and user mode access.

Hmm.

I think what you've found is a(nother) latent bug in the CPU bring up code.

For SMP CPUs, the sequence we're following during early initialisation is:

1. Enable SMP coherency.
2. Invalidate the caches.

If the cache contains rubbish, enabling SMP coherency before invalidating the cache is plainly an absurd thing to do.

Can you try the patch below - not tested in any way, so you may need to tweak it, but it should allow us to prove that point.

arch/arm/mm/proc-v7.S +0 -0
index 0716bbe19872..db5137fc297d 100644

arch/arm/mm/proc-v7.S __v7_b15mp_setup: · line 281

Quoted 7 lines
arch/arm/mm/proc-v7.S +4 -0
@@ -275,6 +275,10 @@ __v7_b15mp_setup:
 __v7_ca17mp_setup:
 	mov	r10, #0
 1:
+	adr	r12, __v7_setup_stack		@ the local stack
+	stmia	r12, {r0-r5, r7, r9-r11, lr}
+	bl      v7_invalidate_l1
+	ldmia	r12, {r0-r5, r7, r9-r11, lr}

Some CPUs such as CA7 need enable SMP before any cache maintenance.

Quoted 3 lines

CA7 TRM says something about SMP bit:
"You must ensure this bit is set to 1 before the caches and MMU are enabled, or any cache and TLB maintenance operations are performed."

Frankly, that's wrong for two reasons. Think about it for a moment...

If the cache contains crap - in other words, it contains random uninitialised data in the cache lines at random locations, some of which are marked valid and some of which are marked dirty - then enabling the SMP bit puts the caches into coherent mode, and they join the coherent cluster.

That means those cache lines containing crap become visible to other CPUs in the cluster, and can be migrated to other CPUs, and the crap data in them becomes visible to other CPUs. This leads to state corruption on other CPUs in the cluster.

Moreover, the cache invalidation of the local L1 cache is broadcast to other CPUs in the cluster, and _their_ caches are also invalidated, again, leading to state corruption on already running CPUs. We don't want the invalidation of the incoming CPU to be broadcast to the other CPUs.

This is all round a very bad thing.

Quoted 8 lines
Quoted 2 lines

Also CA7 would invalidate L1 automatically once reset, can we remove the invalidate op in CA7 case?

No, because we enter this path from multiple different situations, eg, after the decompressor has run, after the boot loader has run which may have enabled caches and not properly invalidated them prior to calling the kernel.

Got it. Thanks very much for your detailed explanation!

#8 lore raw

PATCH 1/1 ARM: socfpga: put back v7_invalidate_l1 in socfpga_secondary_startup

Hi Russell,

Quoted 74 lines · Jisheng Zhang

Dear Russell,

Quoted 69 lines · On Thu, 9 Jul 2015 08:57:17 +0100 Russell King - ARM Linux…
Quoted 40 lines · Jisheng Zhang

Dear Russell,

Quoted 25 lines · On Wed, 8 Jul 2015 22:07:34 +0100 Russell King - ARM Linux…
Quoted 2 lines · Dinh Nguyen

The value of CPACR is 0x00F00000. So cp11 and cp10 are privileged and user mode access.

Hmm.

I think what you've found is a(nother) latent bug in the CPU bring up code.

For SMP CPUs, the sequence we're following during early initialisation is:

1. Enable SMP coherency.
2. Invalidate the caches.

If the cache contains rubbish, enabling SMP coherency before invalidating the cache is plainly an absurd thing to do.

Can you try the patch below - not tested in any way, so you may need to tweak it, but it should allow us to prove that point.

arch/arm/mm/proc-v7.S +0 -0
index 0716bbe19872..db5137fc297d 100644

arch/arm/mm/proc-v7.S __v7_b15mp_setup: · line 281

Quoted 7 lines
arch/arm/mm/proc-v7.S +4 -0
@@ -275,6 +275,10 @@ __v7_b15mp_setup:
 __v7_ca17mp_setup:
 	mov	r10, #0
 1:
+	adr	r12, __v7_setup_stack		@ the local stack
+	stmia	r12, {r0-r5, r7, r9-r11, lr}
+	bl      v7_invalidate_l1
+	ldmia	r12, {r0-r5, r7, r9-r11, lr}

Some CPUs such as CA7 need enable SMP before any cache maintenance.

Quoted 3 lines

CA7 TRM says something about SMP bit:
"You must ensure this bit is set to 1 before the caches and MMU are enabled, or any cache and TLB maintenance operations are performed."

Frankly, that's wrong for two reasons. Think about it for a moment...

If the cache contains crap - in other words, it contains random uninitialised data in the cache lines at random locations, some of which are marked valid and some of which are marked dirty - then enabling the SMP bit puts the caches into coherent mode, and they join the coherent cluster.

That means those cache lines containing crap become visible to other CPUs in the cluster, and can be migrated to other CPUs, and the crap data in them becomes visible to other CPUs. This leads to state corruption on other CPUs in the cluster.

Moreover, the cache invalidation of the local L1 cache is broadcast to other CPUs in the cluster, and _their_ caches are also invalidated, again, leading to state corruption on already running CPUs. We don't want the invalidation of the incoming CPU to be broadcast to the other CPUs.

This is all round a very bad thing.

Quoted 2 lines

Also CA7 would invalidate L1 automatically once reset, can we remove the invalidate op in CA7 case?

Quoted 8 lines
Quoted 5 lines

No, because we enter this path from multiple different situations, eg, after the decompressor has run, after the boot loader has run which may have enabled caches and not properly invalidated them prior to calling the kernel.

Got it. Thanks very much for your detailed explanation!

Just wondering if you are still planning to send this patch and if you need me to do anything to help?

Thanks,
Dinh

#9 lore raw

PATCH 1/1 ARM: socfpga: put back v7_invalidate_l1 in socfpga_secondary_startup

Quoted 4 lines · Dinh Nguyen

Hi Russell,

Just wondering if you are still planning to send this patch and if you need me to do anything to help?

Giving a tested-by tag would help. Thanks. :)

Signature · 2 lines
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.
#10 lore raw

PATCH 1/1 ARM: socfpga: put back v7_invalidate_l1 in socfpga_secondary_startup

Quoted 8 lines · Russell King - ARM Linux
Quoted 4 lines · Dinh Nguyen

Hi Russell,

Just wondering if you are still planning to send this patch and if you need me to do anything to help?

Giving a tested-by tag would help. Thanks. :)

Okay, I've given my Tested-by in a follow-up response that has the patch still in the email.

Thanks,
Dinh

#11 lore raw

PATCH 1/1 ARM: socfpga: put back v7_invalidate_l1 in socfpga_secondary_startup

In reply to Russell King - ARM Linux
Quoted 54 lines · Russell King - ARM Linux
Quoted 2 lines · Dinh Nguyen

The value of CPACR is 0x00F00000. So cp11 and cp10 are privileged and user mode access.

Hmm.

I think what you've found is a(nother) latent bug in the CPU bring up code.

For SMP CPUs, the sequence we're following during early initialisation is:

1. Enable SMP coherency.
2. Invalidate the caches.

If the cache contains rubbish, enabling SMP coherency before invalidating the cache is plainly an absurd thing to do.

Can you try the patch below - not tested in any way, so you may need to tweak it, but it should allow us to prove that point.

arch/arm/mm/proc-v7.S +6 -1
index 0716bbe19872..db5137fc297d 100644
@@ -275,6 +275,10 @@ __v7_b15mp_setup:
 __v7_ca17mp_setup:
 	mov	r10, #0
 1:
+	adr	r12, __v7_setup_stack		@ the local stack
+	stmia	r12, {r0-r5, r7, r9-r11, lr}
+	bl      v7_invalidate_l1
+	ldmia	r12, {r0-r5, r7, r9-r11, lr}
 #ifdef CONFIG_SMP
 	ALT_SMP(mrc	p15, 0, r0, c1, c0, 1)
 	ALT_UP(mov	r0, #(1 << 6))		@ fake it for UP
@@ -283,7 +287,7 @@ __v7_ca17mp_setup:
 	orreq	r0, r0, r10			@ Enable CPU-specific SMP bits
 	mcreq	p15, 0, r0, c1, c0, 1
 #endif
-	b	__v7_setup
+	b	__v7_setup_cont
 
 /*
  * Errata:
@@ -417,6 +421,7 @@ __v7_setup:
 	bl      v7_invalidate_l1
 	ldmia	r12, {r0-r5, r7, r9, r11, lr}
 
+__v7_setup_cont:
 	and	r0, r9, #0xff000000		@ ARM?
 	teq	r0, #0x41000000
 	bne	__errata_finish

arch/arm/mm/proc-v7.S ENDPROC(__v7_setup) · line 491

Quoted 8 lines
arch/arm/mm/proc-v7.S +1 -1
@@ -480,7 +485,7 @@ ENDPROC(__v7_setup)
 
 	.align	2
 __v7_setup_stack:
-	.space	4 * 11				@ 11 registers
+	.space	4 * 12				@ 12 registers
 
 	__INITDATA
 

For this patch, please feel free to add:

Thanks,
Dinh

#12 lore raw

PATCH 1/1 ARM: socfpga: put back v7_invalidate_l1 in socfpga_secondary_startup

Hi, Russell!

Quoted 60 lines · Dinh Nguyen
Quoted 59 lines · Russell King - ARM Linux
Quoted 2 lines · Dinh Nguyen

The value of CPACR is 0x00F00000. So cp11 and cp10 are privileged and user mode access.

Hmm.

I think what you've found is a(nother) latent bug in the CPU bring up code.

For SMP CPUs, the sequence we're following during early initialisation is:

1. Enable SMP coherency.
2. Invalidate the caches.

If the cache contains rubbish, enabling SMP coherency before invalidating the cache is plainly an absurd thing to do.

Can you try the patch below - not tested in any way, so you may need to tweak it, but it should allow us to prove that point.

arch/arm/mm/proc-v7.S +7 -2
index 0716bbe19872..db5137fc297d 100644
@@ -275,6 +275,10 @@ __v7_b15mp_setup:
 __v7_ca17mp_setup:
 	mov	r10, #0
 1:
+	adr	r12, __v7_setup_stack		@ the local stack
+	stmia	r12, {r0-r5, r7, r9-r11, lr}
+	bl      v7_invalidate_l1
+	ldmia	r12, {r0-r5, r7, r9-r11, lr}
 #ifdef CONFIG_SMP
 	ALT_SMP(mrc	p15, 0, r0, c1, c0, 1)
 	ALT_UP(mov	r0, #(1 << 6))		@ fake it for UP
@@ -283,7 +287,7 @@ __v7_ca17mp_setup:
 	orreq	r0, r0, r10			@ Enable CPU-specific SMP bits
 	mcreq	p15, 0, r0, c1, c0, 1
 #endif
-	b	__v7_setup
+	b	__v7_setup_cont
 
 /*
  * Errata:
@@ -417,6 +421,7 @@ __v7_setup:
 	bl      v7_invalidate_l1
 	ldmia	r12, {r0-r5, r7, r9, r11, lr}
 
+__v7_setup_cont:
 	and	r0, r9, #0xff000000		@ ARM?
 	teq	r0, #0x41000000
 	bne	__errata_finish
@@ -480,7 +485,7 @@ ENDPROC(__v7_setup)
 
 	.align	2
 __v7_setup_stack:
-	.space	4 * 11				@ 11 registers
+	.space	4 * 12				@ 12 registers
 
Quoted 8 lines

arch/arm/mm/proc-v7.S ENDPROC(__v7_setup) · line 491

Quoted 3 lines
arch/arm/mm/proc-v7.S +0 -0
 	__INITDATA
 

For this patch, please feel free to add:

I just ran into the same problem as Dinh. This patch fixed it for me, too. Without it, 4.2-rc2 (at least) is pretty broken for me :-(
So, you may also add

When you send a proper patch.

Thanks,
Steffen Trumtrar

Signature · 4 lines
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |