linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP
@ 2010-09-01 23:49 Tony Lindgren
  0 siblings, 0 replies; 14+ messages in thread
From: Tony Lindgren @ 2010-09-01 23:49 UTC (permalink / raw)
  To: linux-arm-kernel

Fix v7wbi_tlb_flags for SMP on UP. Note that we must enable MULTI_TLB
to avoid undefined reference to cpu_tlb error.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/include/asm/tlbflush.h |   14 +++++++++++++-
 1 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h
index 1fd0db9..55e1dd9 100644
--- a/arch/arm/include/asm/tlbflush.h
+++ b/arch/arm/include/asm/tlbflush.h
@@ -189,20 +189,32 @@
 # define v6wbi_always_flags	(-1UL)
 #endif
 
+#define v7wbi_tlb_flags_common (TLB_WB | TLB_DCLEAN)
 #define v7wbi_tlb_flags_smp (TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \
 			 TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID)
 #define v7wbi_tlb_flags_up (TLB_WB | TLB_DCLEAN | TLB_BTB | \
 			 TLB_V6_U_FULL | TLB_V6_U_PAGE | TLB_V6_U_ASID)
 
 #ifdef CONFIG_SMP
+#ifdef CONFIG_SMP_ON_UP
+#define v7wbi_tlb_flags	(v7wbi_tlb_flags_smp | v7wbi_tlb_flags_up)
+#else
 #define v7wbi_tlb_flags	v7wbi_tlb_flags_smp
+#endif
 #else
 #define v7wbi_tlb_flags	v7wbi_tlb_flags_up
 #endif
 
 #ifdef CONFIG_CPU_TLB_V7
 # define v7wbi_possible_flags	v7wbi_tlb_flags
-# define v7wbi_always_flags	v7wbi_tlb_flags
+# ifdef CONFIG_SMP_ON_UP
+#  define v7wbi_always_flags	v7wbi_tlb_flags_common
+#  ifndef MULTI_TLB
+#   define MULTI_TLB 1
+#  endif
+# else
+#  define v7wbi_always_flags	v7wbi_tlb_flags
+# endif
 # ifdef _TLB
 #  define MULTI_TLB 1
 # else
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP
  2010-09-02 16:16                 ` Tony Lindgren
@ 2010-09-02 16:20                   ` Tony Lindgren
  2010-09-02 16:25                     ` Russell King - ARM Linux
  0 siblings, 1 reply; 14+ messages in thread
From: Tony Lindgren @ 2010-09-02 16:20 UTC (permalink / raw)
  To: linux-arm-kernel



^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP
  2010-09-02 16:20                   ` [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP Tony Lindgren
@ 2010-09-02 16:25                     ` Russell King - ARM Linux
  2010-09-02 16:34                       ` Tony Lindgren
  0 siblings, 1 reply; 14+ messages in thread
From: Russell King - ARM Linux @ 2010-09-02 16:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 02, 2010 at 09:20:40AM -0700, Tony Lindgren wrote:
> >From 253e91b76e104dbdf05c5c3eaf9cbf426972c938 Mon Sep 17 00:00:00 2001
> From: Tony Lindgren <tony@atomide.com>
> Date: Wed, 1 Sep 2010 16:49:13 -0700
> Subject: [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP
> 
> Fix v7wbi_tlb_flags for SMP on UP. Note that we must enable MULTI_TLB
> to avoid undefined reference to cpu_tlb error.

This isn't required, as it is already covered by my patch.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP
  2010-09-02 16:25                     ` Russell King - ARM Linux
@ 2010-09-02 16:34                       ` Tony Lindgren
  2010-09-02 23:47                         ` Tony Lindgren
  0 siblings, 1 reply; 14+ messages in thread
From: Tony Lindgren @ 2010-09-02 16:34 UTC (permalink / raw)
  To: linux-arm-kernel

* Russell King - ARM Linux <linux@arm.linux.org.uk> [100902 09:18]:
> On Thu, Sep 02, 2010 at 09:20:40AM -0700, Tony Lindgren wrote:
> > >From 253e91b76e104dbdf05c5c3eaf9cbf426972c938 Mon Sep 17 00:00:00 2001
> > From: Tony Lindgren <tony@atomide.com>
> > Date: Wed, 1 Sep 2010 16:49:13 -0700
> > Subject: [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP
> > 
> > Fix v7wbi_tlb_flags for SMP on UP. Note that we must enable MULTI_TLB
> > to avoid undefined reference to cpu_tlb error.
> 
> This isn't required, as it is already covered by my patch.

Yup, seems to be working without this patch.

Tony

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP
  2010-09-02 16:34                       ` Tony Lindgren
@ 2010-09-02 23:47                         ` Tony Lindgren
  2010-09-03  9:07                           ` Russell King - ARM Linux
  0 siblings, 1 reply; 14+ messages in thread
From: Tony Lindgren @ 2010-09-02 23:47 UTC (permalink / raw)
  To: linux-arm-kernel

* Tony Lindgren <tony@atomide.com> [100902 09:29]:
> * Russell King - ARM Linux <linux@arm.linux.org.uk> [100902 09:18]:
> > On Thu, Sep 02, 2010 at 09:20:40AM -0700, Tony Lindgren wrote:
> > > >From 253e91b76e104dbdf05c5c3eaf9cbf426972c938 Mon Sep 17 00:00:00 2001
> > > From: Tony Lindgren <tony@atomide.com>
> > > Date: Wed, 1 Sep 2010 16:49:13 -0700
> > > Subject: [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP
> > > 
> > > Fix v7wbi_tlb_flags for SMP on UP. Note that we must enable MULTI_TLB
> > > to avoid undefined reference to cpu_tlb error.
> > 
> > This isn't required, as it is already covered by my patch.
> 
> Yup, seems to be working without this patch.

Correction, only boots on SMP hardawre. On UP hardware I still
need the following patch.

Left out forcing MULTI_TLB as looks like your patch already
does that.

Also noticed I'm now getting unhandled fault on SMP system
which I was not getting earlier. Will try to track it down.

Tony
-------------- next part --------------
A non-text attachment was scrubbed...
Name: tlbflush-fix-smp-on-up-flags.patch
Type: text/x-diff
Size: 1386 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20100902/0370d3cb/attachment.bin>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP
  2010-09-02 23:47                         ` Tony Lindgren
@ 2010-09-03  9:07                           ` Russell King - ARM Linux
  2010-09-03  9:10                             ` Russell King - ARM Linux
  0 siblings, 1 reply; 14+ messages in thread
From: Russell King - ARM Linux @ 2010-09-03  9:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 02, 2010 at 04:47:46PM -0700, Tony Lindgren wrote:
> Correction, only boots on SMP hardawre. On UP hardware I still
> need the following patch.

This should fix that properly.

 arch/arm/Kconfig                          |   12 ++++++++
 arch/arm/include/asm/assembler.h          |   20 ++++++++++++-
 arch/arm/include/asm/tlbflush.h           |   24 +++++++++++-----
 arch/arm/kernel/entry-armv.S              |    7 +---
 arch/arm/kernel/head.S                    |   34 +++++++++++++++++++++++
 arch/arm/kernel/vmlinux.lds.S             |   11 +++++++
 arch/arm/mach-realview/include/mach/smp.h |   10 +------
 arch/arm/mach-s5pv310/include/mach/smp.h  |    9 +-----
 arch/arm/mach-tegra/include/mach/smp.h    |   10 +------
 arch/arm/mach-ux500/include/mach/smp.h    |    9 +-----
 arch/arm/mach-vexpress/include/mach/smp.h |    9 +-----
 arch/arm/mm/cache-v7.S                    |   14 +++-------
 arch/arm/mm/proc-v6.S                     |   43 +++++++++++++++++++----------
 arch/arm/mm/proc-v7.S                     |   31 +++++++++++++--------
 arch/arm/mm/tlb-v7.S                      |   33 ++++++++--------------
 arch/arm/plat-omap/include/plat/smp.h     |   12 +-------
 16 files changed, 163 insertions(+), 125 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ab2536c..4575e4a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1166,6 +1166,18 @@ config SMP
 
 	  If you don't know what to do here, say N.
 
+config SMP_ON_UP
+	bool "Allow booting SMP kernel on uniprocessor systems (EXPERIMENTAL)"
+	depends on SMP && !XIP
+	default y
+	help
+	  SMP kernels contain instructions which fail on non-SMP processors.
+	  Enabling this option allows the kernel to modify itself to make
+	  these instructions safe.  Disabling it allows about 1K of space
+	  savings.
+
+	  If you don't know what to do here, say Y.
+
 config HAVE_ARM_SCU
 	bool
 	depends on SMP
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 6e8f05c..55974d2 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -154,16 +154,32 @@
 	.long	9999b,9001f;			\
 	.popsection
 
+#ifdef CONFIG_SMP
+#define SMP(instr...)						\
+9998:	instr
+#define UP(instr...)						\
+	.pushsection ".smpalt.init", "a"			;\
+	.word	9998b						;\
+	instr							;\
+	.popsection
+#else
+#define SMP(instr...)
+#define UP(instr...) instr
+#endif
+
 /*
  * SMP data memory barrier
  */
 	.macro	smp_dmb
 #ifdef CONFIG_SMP
 #if __LINUX_ARM_ARCH__ >= 7
-	dmb
+	SMP(dmb)
 #elif __LINUX_ARM_ARCH__ == 6
-	mcr	p15, 0, r0, c7, c10, 5	@ dmb
+	SMP(mcr	p15, 0, r0, c7, c10, 5)	@ dmb
+#else
+#error Incompatible SMP platform
 #endif
+	UP(nop)
 #endif
 	.endm
 
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h
index 33b546a..c344c34 100644
--- a/arch/arm/include/asm/tlbflush.h
+++ b/arch/arm/include/asm/tlbflush.h
@@ -70,6 +70,10 @@
 #undef _TLB
 #undef MULTI_TLB
 
+#ifdef CONFIG_SMP_ON_UP
+#define MULTI_TLB 1
+#endif
+
 #define v3_tlb_flags	(TLB_V3_FULL | TLB_V3_PAGE)
 
 #ifdef CONFIG_CPU_TLB_V3
@@ -185,17 +189,23 @@
 # define v6wbi_always_flags	(-1UL)
 #endif
 
-#ifdef CONFIG_SMP
-#define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \
+#define v7wbi_tlb_flags_smp	(TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \
 			 TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID)
-#else
-#define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \
+#define v7wbi_tlb_flags_up	(TLB_WB | TLB_DCLEAN | TLB_BTB | \
 			 TLB_V6_U_FULL | TLB_V6_U_PAGE | TLB_V6_U_ASID)
-#endif
 
 #ifdef CONFIG_CPU_TLB_V7
-# define v7wbi_possible_flags	v7wbi_tlb_flags
-# define v7wbi_always_flags	v7wbi_tlb_flags
+
+# ifdef CONFIG_SMP
+#  define v7wbi_possible_flags	v7wbi_tlb_flags_smp
+#  define v7wbi_always_flags	v7wbi_tlb_flags_smp
+# elif defined(CONFIG_SMP_ON_UP)
+#  define v7wbi_possible_flags	(v7wbi_tlb_flags_smp | v7wbi_tlb_flags_up)
+#  define v7wbi_always_flags	(v7wbi_tlb_flags_smp & v7wbi_tlb_flags_up)
+# else
+#  define v7wbi_possible_flags	v7wbi_tlb_flags_up
+#  define v7wbi_always_flags	v7wbi_tlb_flags_up
+# endif
 # ifdef _TLB
 #  define MULTI_TLB 1
 # else
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index bb8e93a..bb2ef60 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -965,11 +965,8 @@ kuser_cmpxchg_fixup:
 	beq	1b
 	rsbs	r0, r3, #0
 	/* beware -- each __kuser slot must be 8 instructions max */
-#ifdef CONFIG_SMP
-	b	__kuser_memory_barrier
-#else
-	usr_ret	lr
-#endif
+	SMP(b	__kuser_memory_barrier)
+	UP(usr_ret	lr)
 
 #endif
 
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index eb62bf9..0b4a626 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -86,6 +86,9 @@ ENTRY(stext)
 	movs	r8, r5				@ invalid machine (r5=0)?
 	beq	__error_a			@ yes, error 'a'
 	bl	__vet_atags
+#ifdef CONFIG_SMP_ON_UP
+	bl	__fixup_smp
+#endif
 	bl	__create_page_tables
 
 	/*
@@ -333,4 +336,35 @@ __create_page_tables:
 ENDPROC(__create_page_tables)
 	.ltorg
 
+#ifdef CONFIG_SMP_ON_UP
+__fixup_smp:
+	and	r0, r9, #0xff000000
+	teq	r0, #0x41000000		@ ARM CPU?
+	bne	smp_on_up		@ no, assume UP
+	and	r0, r9, #0x00070000
+	teq	r0, #0x00070000		@ ARMv6/v7?
+	bne	smp_on_up		@ no, assume UP
+	mrc	p15, 0, r0, c0, c0, 5	@ read MIDR
+	movs	r0, r0, lsr #30
+	teqne	r0, #3			@ check top two bits 00 or 11
+	movne	pc, lr
+
+smp_on_up:
+	adr	r0, 1f
+	ldmia	r0, {r3, r6, r7}
+	sub	r3, r0, r3
+	add	r6, r6, r3
+	add	r7, r7, r3
+2:	cmp	r6, r7
+	ldmia	r6!, {r0, r4}
+	movhs	pc, lr
+	str	r4, [r0, r3]
+	b	2b
+ENDPROC(__fixup_smp)
+
+1:	.word	.
+	.word	__smpalt_begin
+	.word	__smpalt_end
+#endif
+
 #include "head-common.S"
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index b16c079..53cb57e 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -40,6 +40,11 @@ SECTIONS
 		__tagtable_begin = .;
 			*(.taglist.init)
 		__tagtable_end = .;
+#ifdef CONFIG_SMP_ON_UP
+		__smpalt_begin = .;
+			*(.smpalt.init)
+		__smpalt_end = .;
+#endif
 
 		INIT_SETUP(16)
 
@@ -237,6 +242,12 @@ SECTIONS
 
 	/* Default discards */
 	DISCARDS
+
+#ifndef CONFIG_SMP_ON_UP
+	/DISCARD/ {
+		*(.smpalt.init)
+	}
+#endif
 }
 
 /*
diff --git a/arch/arm/mach-realview/include/mach/smp.h b/arch/arm/mach-realview/include/mach/smp.h
index dd53892..833ee85 100644
--- a/arch/arm/mach-realview/include/mach/smp.h
+++ b/arch/arm/mach-realview/include/mach/smp.h
@@ -1,16 +1,8 @@
 #ifndef ASMARM_ARCH_SMP_H
 #define ASMARM_ARCH_SMP_H
 
-
 #include <asm/hardware/gic.h>
-
-#define hard_smp_processor_id()			\
-	({						\
-		unsigned int cpunum;			\
-		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
-			: "=r" (cpunum));		\
-		cpunum &= 0x0F;				\
-	})
+#include <asm/smp_midr.h>
 
 /*
  * We use IRQ1 as the IPI
diff --git a/arch/arm/mach-s5pv310/include/mach/smp.h b/arch/arm/mach-s5pv310/include/mach/smp.h
index 990f3ba..1b8b637 100644
--- a/arch/arm/mach-s5pv310/include/mach/smp.h
+++ b/arch/arm/mach-s5pv310/include/mach/smp.h
@@ -7,17 +7,10 @@
 #define ASM_ARCH_SMP_H __FILE__
 
 #include <asm/hardware/gic.h>
+#include <asm/smp_midr.h>
 
 extern void __iomem *gic_cpu_base_addr;
 
-#define hard_smp_processor_id()			\
-	({						\
-		unsigned int cpunum;			\
-		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
-			: "=r" (cpunum));		\
-		cpunum &= 0x03;				\
-	})
-
 /*
  * We use IRQ1 as the IPI
  */
diff --git a/arch/arm/mach-tegra/include/mach/smp.h b/arch/arm/mach-tegra/include/mach/smp.h
index 8b42dab..d5c4030 100644
--- a/arch/arm/mach-tegra/include/mach/smp.h
+++ b/arch/arm/mach-tegra/include/mach/smp.h
@@ -1,16 +1,8 @@
 #ifndef ASMARM_ARCH_SMP_H
 #define ASMARM_ARCH_SMP_H
 
-
 #include <asm/hardware/gic.h>
-
-#define hard_smp_processor_id()			\
-	({						\
-		unsigned int cpunum;			\
-		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
-			: "=r" (cpunum));		\
-		cpunum &= 0x0F;				\
-	})
+#include <asm/smp_midr.h>
 
 /*
  * We use IRQ1 as the IPI
diff --git a/arch/arm/mach-ux500/include/mach/smp.h b/arch/arm/mach-ux500/include/mach/smp.h
index b59f7bc..87a9cf3 100644
--- a/arch/arm/mach-ux500/include/mach/smp.h
+++ b/arch/arm/mach-ux500/include/mach/smp.h
@@ -10,18 +10,11 @@
 #define ASMARM_ARCH_SMP_H
 
 #include <asm/hardware/gic.h>
+#include <asm/smp_midr.h>
 
 /* This is required to wakeup the secondary core */
 extern void u8500_secondary_startup(void);
 
-#define hard_smp_processor_id()				\
-	({						\
-		unsigned int cpunum;			\
-		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
-			: "=r" (cpunum));		\
-		cpunum &= 0x0F;				\
-	})
-
 /*
  * We use IRQ1 as the IPI
  */
diff --git a/arch/arm/mach-vexpress/include/mach/smp.h b/arch/arm/mach-vexpress/include/mach/smp.h
index 72a9621..e02bc7d 100644
--- a/arch/arm/mach-vexpress/include/mach/smp.h
+++ b/arch/arm/mach-vexpress/include/mach/smp.h
@@ -2,14 +2,7 @@
 #define __MACH_SMP_H
 
 #include <asm/hardware/gic.h>
-
-#define hard_smp_processor_id()				\
-	({						\
-		unsigned int cpunum;			\
-		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
-			: "=r" (cpunum));		\
-		cpunum &= 0x0F;				\
-	})
+#include <asm/smp_midr.h>
 
 /*
  * We use IRQ1 as the IPI
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 37c8157..2aa59d5 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -91,11 +91,8 @@ ENTRY(v7_flush_kern_cache_all)
  THUMB(	stmfd	sp!, {r4-r7, r9-r11, lr}	)
 	bl	v7_flush_dcache_all
 	mov	r0, #0
-#ifdef CONFIG_SMP
-	mcr	p15, 0, r0, c7, c1, 0		@ invalidate I-cache inner shareable
-#else
-	mcr	p15, 0, r0, c7, c5, 0		@ I+BTB cache invalidate
-#endif
+	SMP(mcr	p15, 0, r0, c7, c1, 0)		@ invalidate I-cache inner shareable
+	UP(mcr	p15, 0, r0, c7, c5, 0)		@ I+BTB cache invalidate
  ARM(	ldmfd	sp!, {r4-r5, r7, r9-r11, lr}	)
  THUMB(	ldmfd	sp!, {r4-r7, r9-r11, lr}	)
 	mov	pc, lr
@@ -171,11 +168,8 @@ ENTRY(v7_coherent_user_range)
 	cmp	r0, r1
 	blo	1b
 	mov	r0, #0
-#ifdef CONFIG_SMP
-	mcr	p15, 0, r0, c7, c1, 6		@ invalidate BTB Inner Shareable
-#else
-	mcr	p15, 0, r0, c7, c5, 6		@ invalidate BTB
-#endif
+	SMP(mcr	p15, 0, r0, c7, c1, 6)		@ invalidate BTB Inner Shareable
+	UP(mcr	p15, 0, r0, c7, c5, 6)		@ invalidate BTB
 	dsb
 	isb
 	mov	pc, lr
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 22aac85..00692b0 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -30,13 +30,10 @@
 #define TTB_RGN_WT	(2 << 3)
 #define TTB_RGN_WB	(3 << 3)
 
-#ifndef CONFIG_SMP
-#define TTB_FLAGS	TTB_RGN_WBWA
-#define PMD_FLAGS	PMD_SECT_WB
-#else
-#define TTB_FLAGS	TTB_RGN_WBWA|TTB_S
-#define PMD_FLAGS	PMD_SECT_WBWA|PMD_SECT_S
-#endif
+#define TTB_FLAGS_UP	TTB_RGN_WBWA
+#define PMD_FLAGS_UP	PMD_SECT_WB
+#define TTB_FLAGS_SMP	TTB_RGN_WBWA|TTB_S
+#define PMD_FLAGS_SMP	PMD_SECT_WBWA|PMD_SECT_S
 
 ENTRY(cpu_v6_proc_init)
 	mov	pc, lr
@@ -97,7 +94,8 @@ ENTRY(cpu_v6_switch_mm)
 #ifdef CONFIG_MMU
 	mov	r2, #0
 	ldr	r1, [r1, #MM_CONTEXT_ID]	@ get mm->context.id
-	orr	r0, r0, #TTB_FLAGS
+	SMP(orr	r0, r0, #TTB_FLAGS_SMP)
+	UP(orr	r0, r0, #TTB_FLAGS_UP)
 	mcr	p15, 0, r2, c7, c5, 6		@ flush BTAC/BTB
 	mcr	p15, 0, r2, c7, c10, 4		@ drain write buffer
 	mcr	p15, 0, r0, c2, c0, 0		@ set TTB 0
@@ -156,9 +154,11 @@ cpu_pj4_name:
  */
 __v6_setup:
 #ifdef CONFIG_SMP
-	mrc	p15, 0, r0, c1, c0, 1		@ Enable SMP/nAMP mode
+	SMP(mrc	p15, 0, r0, c1, c0, 1)		@ Enable SMP/nAMP mode
+	UP(nop)
 	orr	r0, r0, #0x20
-	mcr	p15, 0, r0, c1, c0, 1
+	SMP(mcr	p15, 0, r0, c1, c0, 1)
+	UP(nop)
 #endif
 
 	mov	r0, #0
@@ -169,7 +169,8 @@ __v6_setup:
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r0, c8, c7, 0		@ invalidate I + D TLBs
 	mcr	p15, 0, r0, c2, c0, 2		@ TTB control register
-	orr	r4, r4, #TTB_FLAGS
+	SMP(orr	r4, r4, #TTB_FLAGS_SMP)
+	UP(orr	r4, r4, #TTB_FLAGS_UP)
 	mcr	p15, 0, r4, c2, c0, 1		@ load TTB1
 #endif /* CONFIG_MMU */
 	adr	r5, v6_crval
@@ -225,10 +226,16 @@ cpu_elf_name:
 __v6_proc_info:
 	.long	0x0007b000
 	.long	0x0007f000
-	.long   PMD_TYPE_SECT | \
+	SMP(.long \
+		PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ | \
+		PMD_FLAGS_SMP)
+	UP(.long \
+		PMD_TYPE_SECT | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ | \
-		PMD_FLAGS
+		PMD_FLAGS_UP)
 	.long   PMD_TYPE_SECT | \
 		PMD_SECT_XN | \
 		PMD_SECT_AP_WRITE | \
@@ -249,10 +256,16 @@ __v6_proc_info:
 __pj4_v6_proc_info:
 	.long	0x560f5810
 	.long	0xff0ffff0
-	.long   PMD_TYPE_SECT | \
+	SMP(.long \
+		PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ | \
+		PMD_FLAGS_SMP)
+	UP(.long \
+		PMD_TYPE_SECT | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ | \
-		PMD_FLAGS
+		PMD_FLAGS_UP)
 	.long   PMD_TYPE_SECT | \
 		PMD_SECT_XN | \
 		PMD_SECT_AP_WRITE | \
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 6a8506d..07fc660 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -30,15 +30,13 @@
 #define TTB_IRGN_WT	((1 << 0) | (0 << 6))
 #define TTB_IRGN_WB	((1 << 0) | (1 << 6))
 
-#ifndef CONFIG_SMP
 /* PTWs cacheable, inner WB not shareable, outer WB not shareable */
-#define TTB_FLAGS	TTB_IRGN_WB|TTB_RGN_OC_WB
-#define PMD_FLAGS	PMD_SECT_WB
-#else
+#define TTB_FLAGS_UP	TTB_IRGN_WB|TTB_RGN_OC_WB
+#define PMD_FLAGS_UP	PMD_SECT_WB
+
 /* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */
-#define TTB_FLAGS	TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA
-#define PMD_FLAGS	PMD_SECT_WBWA|PMD_SECT_S
-#endif
+#define TTB_FLAGS_SMP	TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA
+#define PMD_FLAGS_SMP	PMD_SECT_WBWA|PMD_SECT_S
 
 ENTRY(cpu_v7_proc_init)
 	mov	pc, lr
@@ -105,7 +103,8 @@ ENTRY(cpu_v7_switch_mm)
 #ifdef CONFIG_MMU
 	mov	r2, #0
 	ldr	r1, [r1, #MM_CONTEXT_ID]	@ get mm->context.id
-	orr	r0, r0, #TTB_FLAGS
+	SMP(orr	r0, r0, #TTB_FLAGS_SMP)
+	UP(orr	r0, r0, #TTB_FLAGS_UP)
 #ifdef CONFIG_ARM_ERRATA_430973
 	mcr	p15, 0, r2, c7, c5, 6		@ flush BTAC/BTB
 #endif
@@ -188,7 +187,8 @@ cpu_v7_name:
  */
 __v7_setup:
 #ifdef CONFIG_SMP
-	mrc	p15, 0, r0, c1, c0, 1
+	SMP(mrc	p15, 0, r0, c1, c0, 1)
+	UP(mov	r0, #(1 << 6))			@ fake it for UP
 	tst	r0, #(1 << 6)			@ SMP/nAMP mode enabled?
 	orreq	r0, r0, #(1 << 6) | (1 << 0)	@ Enable SMP/nAMP mode and
 	mcreq	p15, 0, r0, c1, c0, 1		@ TLB ops broadcasting
@@ -235,7 +235,8 @@ __v7_setup:
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r10, c8, c7, 0		@ invalidate I + D TLBs
 	mcr	p15, 0, r10, c2, c0, 2		@ TTB control register
-	orr	r4, r4, #TTB_FLAGS
+	SMP(orr	r4, r4, #TTB_FLAGS_SMP)
+	UP(orr	r4, r4, #TTB_FLAGS_UP)
 	mcr	p15, 0, r4, c2, c0, 1		@ load TTB1
 	mov	r10, #0x1f			@ domains 0, 1 = manager
 	mcr	p15, 0, r10, c3, c0, 0		@ load domain access register
@@ -330,10 +331,16 @@ cpu_elf_name:
 __v7_proc_info:
 	.long	0x000f0000		@ Required ID value
 	.long	0x000f0000		@ Mask for ID
-	.long   PMD_TYPE_SECT | \
+	SMP(.long \
+		PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ | \
+		PMD_FLAGS_SMP)
+	UP(.long \
+		PMD_TYPE_SECT | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ | \
-		PMD_FLAGS
+		PMD_FLAGS_UP)
 	.long   PMD_TYPE_SECT | \
 		PMD_SECT_XN | \
 		PMD_SECT_AP_WRITE | \
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S
index f3f288a..26247c9 100644
--- a/arch/arm/mm/tlb-v7.S
+++ b/arch/arm/mm/tlb-v7.S
@@ -13,6 +13,7 @@
  */
 #include <linux/init.h>
 #include <linux/linkage.h>
+#include <asm/assembler.h>
 #include <asm/asm-offsets.h>
 #include <asm/page.h>
 #include <asm/tlbflush.h>
@@ -41,20 +42,15 @@ ENTRY(v7wbi_flush_user_tlb_range)
 	orr	r0, r3, r0, lsl #PAGE_SHIFT	@ Create initial MVA
 	mov	r1, r1, lsl #PAGE_SHIFT
 1:
-#ifdef CONFIG_SMP
-	mcr	p15, 0, r0, c8, c3, 1		@ TLB invalidate U MVA (shareable) 
-#else
-	mcr	p15, 0, r0, c8, c7, 1		@ TLB invalidate U MVA
-#endif
+	SMP(mcr	p15, 0, r0, c8, c3, 1)		@ TLB invalidate U MVA (shareable) 
+	UP(mcr	p15, 0, r0, c8, c7, 1)		@ TLB invalidate U MVA
+
 	add	r0, r0, #PAGE_SZ
 	cmp	r0, r1
 	blo	1b
 	mov	ip, #0
-#ifdef CONFIG_SMP
-	mcr	p15, 0, ip, c7, c1, 6		@ flush BTAC/BTB Inner Shareable
-#else
-	mcr	p15, 0, ip, c7, c5, 6		@ flush BTAC/BTB
-#endif
+	SMP(mcr	p15, 0, ip, c7, c1, 6)		@ flush BTAC/BTB Inner Shareable
+	UP(mcr	p15, 0, ip, c7, c5, 6)		@ flush BTAC/BTB
 	dsb
 	mov	pc, lr
 ENDPROC(v7wbi_flush_user_tlb_range)
@@ -74,20 +70,14 @@ ENTRY(v7wbi_flush_kern_tlb_range)
 	mov	r0, r0, lsl #PAGE_SHIFT
 	mov	r1, r1, lsl #PAGE_SHIFT
 1:
-#ifdef CONFIG_SMP
-	mcr	p15, 0, r0, c8, c3, 1		@ TLB invalidate U MVA (shareable)
-#else
-	mcr	p15, 0, r0, c8, c7, 1		@ TLB invalidate U MVA
-#endif
+	SMP(mcr	p15, 0, r0, c8, c3, 1)		@ TLB invalidate U MVA (shareable)
+	UP(mcr	p15, 0, r0, c8, c7, 1)		@ TLB invalidate U MVA
 	add	r0, r0, #PAGE_SZ
 	cmp	r0, r1
 	blo	1b
 	mov	r2, #0
-#ifdef CONFIG_SMP
-	mcr	p15, 0, r2, c7, c1, 6		@ flush BTAC/BTB Inner Shareable
-#else
-	mcr	p15, 0, r2, c7, c5, 6		@ flush BTAC/BTB
-#endif
+	SMP(mcr	p15, 0, r2, c7, c1, 6)		@ flush BTAC/BTB Inner Shareable
+	UP(mcr	p15, 0, r2, c7, c5, 6)		@ flush BTAC/BTB
 	dsb
 	isb
 	mov	pc, lr
@@ -99,5 +89,6 @@ ENDPROC(v7wbi_flush_kern_tlb_range)
 ENTRY(v7wbi_tlb_fns)
 	.long	v7wbi_flush_user_tlb_range
 	.long	v7wbi_flush_kern_tlb_range
-	.long	v7wbi_tlb_flags
+	SMP(.long	v7wbi_tlb_flags_smp)
+	UP(.long	v7wbi_tlb_flags_up)
 	.size	v7wbi_tlb_fns, . - v7wbi_tlb_fns
diff --git a/arch/arm/plat-omap/include/plat/smp.h b/arch/arm/plat-omap/include/plat/smp.h
index 5177a9c..99d7e6b 100644
--- a/arch/arm/plat-omap/include/plat/smp.h
+++ b/arch/arm/plat-omap/include/plat/smp.h
@@ -18,6 +18,7 @@
 #define OMAP_ARCH_SMP_H
 
 #include <asm/hardware/gic.h>
+#include <asm/smp_midr.h>
 
 /* Needed for secondary core boot */
 extern void omap_secondary_startup(void);
@@ -33,15 +34,4 @@ static inline void smp_cross_call(const struct cpumask *mask)
 	gic_raise_softirq(mask, 1);
 }
 
-/*
- * Read MPIDR: Multiprocessor affinity register
- */
-#define hard_smp_processor_id()			\
-	({						\
-		unsigned int cpunum;			\
-		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
-			: "=r" (cpunum));		\
-		cpunum &= 0x0F;				\
-	})
-
 #endif

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP
  2010-09-03  9:07                           ` Russell King - ARM Linux
@ 2010-09-03  9:10                             ` Russell King - ARM Linux
  2010-09-03 17:04                               ` Tony Lindgren
  2010-09-06 11:46                               ` Catalin Marinas
  0 siblings, 2 replies; 14+ messages in thread
From: Russell King - ARM Linux @ 2010-09-03  9:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Sep 03, 2010 at 10:07:34AM +0100, Russell King - ARM Linux wrote:
> On Thu, Sep 02, 2010 at 04:47:46PM -0700, Tony Lindgren wrote:
> > Correction, only boots on SMP hardawre. On UP hardware I still
> > need the following patch.
> 
> This should fix that properly.

Correction - the order of the config tests was wrong.

 arch/arm/Kconfig                          |   12 ++++++++
 arch/arm/include/asm/assembler.h          |   20 ++++++++++++-
 arch/arm/include/asm/tlbflush.h           |   24 +++++++++++-----
 arch/arm/kernel/entry-armv.S              |    7 +---
 arch/arm/kernel/head.S                    |   34 +++++++++++++++++++++++
 arch/arm/kernel/vmlinux.lds.S             |   11 +++++++
 arch/arm/mach-realview/include/mach/smp.h |   10 +------
 arch/arm/mach-s5pv310/include/mach/smp.h  |    9 +-----
 arch/arm/mach-tegra/include/mach/smp.h    |   10 +------
 arch/arm/mach-ux500/include/mach/smp.h    |    9 +-----
 arch/arm/mach-vexpress/include/mach/smp.h |    9 +-----
 arch/arm/mm/cache-v7.S                    |   14 +++-------
 arch/arm/mm/proc-v6.S                     |   43 +++++++++++++++++++----------
 arch/arm/mm/proc-v7.S                     |   31 +++++++++++++--------
 arch/arm/mm/tlb-v7.S                      |   33 ++++++++--------------
 arch/arm/plat-omap/include/plat/smp.h     |   12 +-------
 16 files changed, 163 insertions(+), 125 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ab2536c..4575e4a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1166,6 +1166,18 @@ config SMP
 
 	  If you don't know what to do here, say N.
 
+config SMP_ON_UP
+	bool "Allow booting SMP kernel on uniprocessor systems (EXPERIMENTAL)"
+	depends on SMP && !XIP
+	default y
+	help
+	  SMP kernels contain instructions which fail on non-SMP processors.
+	  Enabling this option allows the kernel to modify itself to make
+	  these instructions safe.  Disabling it allows about 1K of space
+	  savings.
+
+	  If you don't know what to do here, say Y.
+
 config HAVE_ARM_SCU
 	bool
 	depends on SMP
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 6e8f05c..55974d2 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -154,16 +154,32 @@
 	.long	9999b,9001f;			\
 	.popsection
 
+#ifdef CONFIG_SMP
+#define SMP(instr...)						\
+9998:	instr
+#define UP(instr...)						\
+	.pushsection ".smpalt.init", "a"			;\
+	.word	9998b						;\
+	instr							;\
+	.popsection
+#else
+#define SMP(instr...)
+#define UP(instr...) instr
+#endif
+
 /*
  * SMP data memory barrier
  */
 	.macro	smp_dmb
 #ifdef CONFIG_SMP
 #if __LINUX_ARM_ARCH__ >= 7
-	dmb
+	SMP(dmb)
 #elif __LINUX_ARM_ARCH__ == 6
-	mcr	p15, 0, r0, c7, c10, 5	@ dmb
+	SMP(mcr	p15, 0, r0, c7, c10, 5)	@ dmb
+#else
+#error Incompatible SMP platform
 #endif
+	UP(nop)
 #endif
 	.endm
 
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h
index 33b546a..cf2f018 100644
--- a/arch/arm/include/asm/tlbflush.h
+++ b/arch/arm/include/asm/tlbflush.h
@@ -70,6 +70,10 @@
 #undef _TLB
 #undef MULTI_TLB
 
+#ifdef CONFIG_SMP_ON_UP
+#define MULTI_TLB 1
+#endif
+
 #define v3_tlb_flags	(TLB_V3_FULL | TLB_V3_PAGE)
 
 #ifdef CONFIG_CPU_TLB_V3
@@ -185,17 +189,23 @@
 # define v6wbi_always_flags	(-1UL)
 #endif
 
-#ifdef CONFIG_SMP
-#define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \
+#define v7wbi_tlb_flags_smp	(TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \
 			 TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID)
-#else
-#define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \
+#define v7wbi_tlb_flags_up	(TLB_WB | TLB_DCLEAN | TLB_BTB | \
 			 TLB_V6_U_FULL | TLB_V6_U_PAGE | TLB_V6_U_ASID)
-#endif
 
 #ifdef CONFIG_CPU_TLB_V7
-# define v7wbi_possible_flags	v7wbi_tlb_flags
-# define v7wbi_always_flags	v7wbi_tlb_flags
+
+# ifdef CONFIG_SMP_ON_UP
+#  define v7wbi_possible_flags	(v7wbi_tlb_flags_smp | v7wbi_tlb_flags_up)
+#  define v7wbi_always_flags	(v7wbi_tlb_flags_smp & v7wbi_tlb_flags_up)
+# elif defined(CONFIG_SMP)
+#  define v7wbi_possible_flags	v7wbi_tlb_flags_smp
+#  define v7wbi_always_flags	v7wbi_tlb_flags_smp
+# else
+#  define v7wbi_possible_flags	v7wbi_tlb_flags_up
+#  define v7wbi_always_flags	v7wbi_tlb_flags_up
+# endif
 # ifdef _TLB
 #  define MULTI_TLB 1
 # else
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index bb8e93a..bb2ef60 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -965,11 +965,8 @@ kuser_cmpxchg_fixup:
 	beq	1b
 	rsbs	r0, r3, #0
 	/* beware -- each __kuser slot must be 8 instructions max */
-#ifdef CONFIG_SMP
-	b	__kuser_memory_barrier
-#else
-	usr_ret	lr
-#endif
+	SMP(b	__kuser_memory_barrier)
+	UP(usr_ret	lr)
 
 #endif
 
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index eb62bf9..0b4a626 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -86,6 +86,9 @@ ENTRY(stext)
 	movs	r8, r5				@ invalid machine (r5=0)?
 	beq	__error_a			@ yes, error 'a'
 	bl	__vet_atags
+#ifdef CONFIG_SMP_ON_UP
+	bl	__fixup_smp
+#endif
 	bl	__create_page_tables
 
 	/*
@@ -333,4 +336,35 @@ __create_page_tables:
 ENDPROC(__create_page_tables)
 	.ltorg
 
+#ifdef CONFIG_SMP_ON_UP
+__fixup_smp:
+	and	r0, r9, #0xff000000
+	teq	r0, #0x41000000		@ ARM CPU?
+	bne	smp_on_up		@ no, assume UP
+	and	r0, r9, #0x00070000
+	teq	r0, #0x00070000		@ ARMv6/v7?
+	bne	smp_on_up		@ no, assume UP
+	mrc	p15, 0, r0, c0, c0, 5	@ read MIDR
+	movs	r0, r0, lsr #30
+	teqne	r0, #3			@ check top two bits 00 or 11
+	movne	pc, lr
+
+smp_on_up:
+	adr	r0, 1f
+	ldmia	r0, {r3, r6, r7}
+	sub	r3, r0, r3
+	add	r6, r6, r3
+	add	r7, r7, r3
+2:	cmp	r6, r7
+	ldmia	r6!, {r0, r4}
+	movhs	pc, lr
+	str	r4, [r0, r3]
+	b	2b
+ENDPROC(__fixup_smp)
+
+1:	.word	.
+	.word	__smpalt_begin
+	.word	__smpalt_end
+#endif
+
 #include "head-common.S"
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index b16c079..53cb57e 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -40,6 +40,11 @@ SECTIONS
 		__tagtable_begin = .;
 			*(.taglist.init)
 		__tagtable_end = .;
+#ifdef CONFIG_SMP_ON_UP
+		__smpalt_begin = .;
+			*(.smpalt.init)
+		__smpalt_end = .;
+#endif
 
 		INIT_SETUP(16)
 
@@ -237,6 +242,12 @@ SECTIONS
 
 	/* Default discards */
 	DISCARDS
+
+#ifndef CONFIG_SMP_ON_UP
+	/DISCARD/ {
+		*(.smpalt.init)
+	}
+#endif
 }
 
 /*
diff --git a/arch/arm/mach-realview/include/mach/smp.h b/arch/arm/mach-realview/include/mach/smp.h
index dd53892..833ee85 100644
--- a/arch/arm/mach-realview/include/mach/smp.h
+++ b/arch/arm/mach-realview/include/mach/smp.h
@@ -1,16 +1,8 @@
 #ifndef ASMARM_ARCH_SMP_H
 #define ASMARM_ARCH_SMP_H
 
-
 #include <asm/hardware/gic.h>
-
-#define hard_smp_processor_id()			\
-	({						\
-		unsigned int cpunum;			\
-		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
-			: "=r" (cpunum));		\
-		cpunum &= 0x0F;				\
-	})
+#include <asm/smp_midr.h>
 
 /*
  * We use IRQ1 as the IPI
diff --git a/arch/arm/mach-s5pv310/include/mach/smp.h b/arch/arm/mach-s5pv310/include/mach/smp.h
index 990f3ba..1b8b637 100644
--- a/arch/arm/mach-s5pv310/include/mach/smp.h
+++ b/arch/arm/mach-s5pv310/include/mach/smp.h
@@ -7,17 +7,10 @@
 #define ASM_ARCH_SMP_H __FILE__
 
 #include <asm/hardware/gic.h>
+#include <asm/smp_midr.h>
 
 extern void __iomem *gic_cpu_base_addr;
 
-#define hard_smp_processor_id()			\
-	({						\
-		unsigned int cpunum;			\
-		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
-			: "=r" (cpunum));		\
-		cpunum &= 0x03;				\
-	})
-
 /*
  * We use IRQ1 as the IPI
  */
diff --git a/arch/arm/mach-tegra/include/mach/smp.h b/arch/arm/mach-tegra/include/mach/smp.h
index 8b42dab..d5c4030 100644
--- a/arch/arm/mach-tegra/include/mach/smp.h
+++ b/arch/arm/mach-tegra/include/mach/smp.h
@@ -1,16 +1,8 @@
 #ifndef ASMARM_ARCH_SMP_H
 #define ASMARM_ARCH_SMP_H
 
-
 #include <asm/hardware/gic.h>
-
-#define hard_smp_processor_id()			\
-	({						\
-		unsigned int cpunum;			\
-		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
-			: "=r" (cpunum));		\
-		cpunum &= 0x0F;				\
-	})
+#include <asm/smp_midr.h>
 
 /*
  * We use IRQ1 as the IPI
diff --git a/arch/arm/mach-ux500/include/mach/smp.h b/arch/arm/mach-ux500/include/mach/smp.h
index b59f7bc..87a9cf3 100644
--- a/arch/arm/mach-ux500/include/mach/smp.h
+++ b/arch/arm/mach-ux500/include/mach/smp.h
@@ -10,18 +10,11 @@
 #define ASMARM_ARCH_SMP_H
 
 #include <asm/hardware/gic.h>
+#include <asm/smp_midr.h>
 
 /* This is required to wakeup the secondary core */
 extern void u8500_secondary_startup(void);
 
-#define hard_smp_processor_id()				\
-	({						\
-		unsigned int cpunum;			\
-		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
-			: "=r" (cpunum));		\
-		cpunum &= 0x0F;				\
-	})
-
 /*
  * We use IRQ1 as the IPI
  */
diff --git a/arch/arm/mach-vexpress/include/mach/smp.h b/arch/arm/mach-vexpress/include/mach/smp.h
index 72a9621..e02bc7d 100644
--- a/arch/arm/mach-vexpress/include/mach/smp.h
+++ b/arch/arm/mach-vexpress/include/mach/smp.h
@@ -2,14 +2,7 @@
 #define __MACH_SMP_H
 
 #include <asm/hardware/gic.h>
-
-#define hard_smp_processor_id()				\
-	({						\
-		unsigned int cpunum;			\
-		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
-			: "=r" (cpunum));		\
-		cpunum &= 0x0F;				\
-	})
+#include <asm/smp_midr.h>
 
 /*
  * We use IRQ1 as the IPI
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 37c8157..2aa59d5 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -91,11 +91,8 @@ ENTRY(v7_flush_kern_cache_all)
  THUMB(	stmfd	sp!, {r4-r7, r9-r11, lr}	)
 	bl	v7_flush_dcache_all
 	mov	r0, #0
-#ifdef CONFIG_SMP
-	mcr	p15, 0, r0, c7, c1, 0		@ invalidate I-cache inner shareable
-#else
-	mcr	p15, 0, r0, c7, c5, 0		@ I+BTB cache invalidate
-#endif
+	SMP(mcr	p15, 0, r0, c7, c1, 0)		@ invalidate I-cache inner shareable
+	UP(mcr	p15, 0, r0, c7, c5, 0)		@ I+BTB cache invalidate
  ARM(	ldmfd	sp!, {r4-r5, r7, r9-r11, lr}	)
  THUMB(	ldmfd	sp!, {r4-r7, r9-r11, lr}	)
 	mov	pc, lr
@@ -171,11 +168,8 @@ ENTRY(v7_coherent_user_range)
 	cmp	r0, r1
 	blo	1b
 	mov	r0, #0
-#ifdef CONFIG_SMP
-	mcr	p15, 0, r0, c7, c1, 6		@ invalidate BTB Inner Shareable
-#else
-	mcr	p15, 0, r0, c7, c5, 6		@ invalidate BTB
-#endif
+	SMP(mcr	p15, 0, r0, c7, c1, 6)		@ invalidate BTB Inner Shareable
+	UP(mcr	p15, 0, r0, c7, c5, 6)		@ invalidate BTB
 	dsb
 	isb
 	mov	pc, lr
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 22aac85..00692b0 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -30,13 +30,10 @@
 #define TTB_RGN_WT	(2 << 3)
 #define TTB_RGN_WB	(3 << 3)
 
-#ifndef CONFIG_SMP
-#define TTB_FLAGS	TTB_RGN_WBWA
-#define PMD_FLAGS	PMD_SECT_WB
-#else
-#define TTB_FLAGS	TTB_RGN_WBWA|TTB_S
-#define PMD_FLAGS	PMD_SECT_WBWA|PMD_SECT_S
-#endif
+#define TTB_FLAGS_UP	TTB_RGN_WBWA
+#define PMD_FLAGS_UP	PMD_SECT_WB
+#define TTB_FLAGS_SMP	TTB_RGN_WBWA|TTB_S
+#define PMD_FLAGS_SMP	PMD_SECT_WBWA|PMD_SECT_S
 
 ENTRY(cpu_v6_proc_init)
 	mov	pc, lr
@@ -97,7 +94,8 @@ ENTRY(cpu_v6_switch_mm)
 #ifdef CONFIG_MMU
 	mov	r2, #0
 	ldr	r1, [r1, #MM_CONTEXT_ID]	@ get mm->context.id
-	orr	r0, r0, #TTB_FLAGS
+	SMP(orr	r0, r0, #TTB_FLAGS_SMP)
+	UP(orr	r0, r0, #TTB_FLAGS_UP)
 	mcr	p15, 0, r2, c7, c5, 6		@ flush BTAC/BTB
 	mcr	p15, 0, r2, c7, c10, 4		@ drain write buffer
 	mcr	p15, 0, r0, c2, c0, 0		@ set TTB 0
@@ -156,9 +154,11 @@ cpu_pj4_name:
  */
 __v6_setup:
 #ifdef CONFIG_SMP
-	mrc	p15, 0, r0, c1, c0, 1		@ Enable SMP/nAMP mode
+	SMP(mrc	p15, 0, r0, c1, c0, 1)		@ Enable SMP/nAMP mode
+	UP(nop)
 	orr	r0, r0, #0x20
-	mcr	p15, 0, r0, c1, c0, 1
+	SMP(mcr	p15, 0, r0, c1, c0, 1)
+	UP(nop)
 #endif
 
 	mov	r0, #0
@@ -169,7 +169,8 @@ __v6_setup:
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r0, c8, c7, 0		@ invalidate I + D TLBs
 	mcr	p15, 0, r0, c2, c0, 2		@ TTB control register
-	orr	r4, r4, #TTB_FLAGS
+	SMP(orr	r4, r4, #TTB_FLAGS_SMP)
+	UP(orr	r4, r4, #TTB_FLAGS_UP)
 	mcr	p15, 0, r4, c2, c0, 1		@ load TTB1
 #endif /* CONFIG_MMU */
 	adr	r5, v6_crval
@@ -225,10 +226,16 @@ cpu_elf_name:
 __v6_proc_info:
 	.long	0x0007b000
 	.long	0x0007f000
-	.long   PMD_TYPE_SECT | \
+	SMP(.long \
+		PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ | \
+		PMD_FLAGS_SMP)
+	UP(.long \
+		PMD_TYPE_SECT | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ | \
-		PMD_FLAGS
+		PMD_FLAGS_UP)
 	.long   PMD_TYPE_SECT | \
 		PMD_SECT_XN | \
 		PMD_SECT_AP_WRITE | \
@@ -249,10 +256,16 @@ __v6_proc_info:
 __pj4_v6_proc_info:
 	.long	0x560f5810
 	.long	0xff0ffff0
-	.long   PMD_TYPE_SECT | \
+	SMP(.long \
+		PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ | \
+		PMD_FLAGS_SMP)
+	UP(.long \
+		PMD_TYPE_SECT | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ | \
-		PMD_FLAGS
+		PMD_FLAGS_UP)
 	.long   PMD_TYPE_SECT | \
 		PMD_SECT_XN | \
 		PMD_SECT_AP_WRITE | \
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 6a8506d..07fc660 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -30,15 +30,13 @@
 #define TTB_IRGN_WT	((1 << 0) | (0 << 6))
 #define TTB_IRGN_WB	((1 << 0) | (1 << 6))
 
-#ifndef CONFIG_SMP
 /* PTWs cacheable, inner WB not shareable, outer WB not shareable */
-#define TTB_FLAGS	TTB_IRGN_WB|TTB_RGN_OC_WB
-#define PMD_FLAGS	PMD_SECT_WB
-#else
+#define TTB_FLAGS_UP	TTB_IRGN_WB|TTB_RGN_OC_WB
+#define PMD_FLAGS_UP	PMD_SECT_WB
+
 /* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */
-#define TTB_FLAGS	TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA
-#define PMD_FLAGS	PMD_SECT_WBWA|PMD_SECT_S
-#endif
+#define TTB_FLAGS_SMP	TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA
+#define PMD_FLAGS_SMP	PMD_SECT_WBWA|PMD_SECT_S
 
 ENTRY(cpu_v7_proc_init)
 	mov	pc, lr
@@ -105,7 +103,8 @@ ENTRY(cpu_v7_switch_mm)
 #ifdef CONFIG_MMU
 	mov	r2, #0
 	ldr	r1, [r1, #MM_CONTEXT_ID]	@ get mm->context.id
-	orr	r0, r0, #TTB_FLAGS
+	SMP(orr	r0, r0, #TTB_FLAGS_SMP)
+	UP(orr	r0, r0, #TTB_FLAGS_UP)
 #ifdef CONFIG_ARM_ERRATA_430973
 	mcr	p15, 0, r2, c7, c5, 6		@ flush BTAC/BTB
 #endif
@@ -188,7 +187,8 @@ cpu_v7_name:
  */
 __v7_setup:
 #ifdef CONFIG_SMP
-	mrc	p15, 0, r0, c1, c0, 1
+	SMP(mrc	p15, 0, r0, c1, c0, 1)
+	UP(mov	r0, #(1 << 6))			@ fake it for UP
 	tst	r0, #(1 << 6)			@ SMP/nAMP mode enabled?
 	orreq	r0, r0, #(1 << 6) | (1 << 0)	@ Enable SMP/nAMP mode and
 	mcreq	p15, 0, r0, c1, c0, 1		@ TLB ops broadcasting
@@ -235,7 +235,8 @@ __v7_setup:
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r10, c8, c7, 0		@ invalidate I + D TLBs
 	mcr	p15, 0, r10, c2, c0, 2		@ TTB control register
-	orr	r4, r4, #TTB_FLAGS
+	SMP(orr	r4, r4, #TTB_FLAGS_SMP)
+	UP(orr	r4, r4, #TTB_FLAGS_UP)
 	mcr	p15, 0, r4, c2, c0, 1		@ load TTB1
 	mov	r10, #0x1f			@ domains 0, 1 = manager
 	mcr	p15, 0, r10, c3, c0, 0		@ load domain access register
@@ -330,10 +331,16 @@ cpu_elf_name:
 __v7_proc_info:
 	.long	0x000f0000		@ Required ID value
 	.long	0x000f0000		@ Mask for ID
-	.long   PMD_TYPE_SECT | \
+	SMP(.long \
+		PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ | \
+		PMD_FLAGS_SMP)
+	UP(.long \
+		PMD_TYPE_SECT | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ | \
-		PMD_FLAGS
+		PMD_FLAGS_UP)
 	.long   PMD_TYPE_SECT | \
 		PMD_SECT_XN | \
 		PMD_SECT_AP_WRITE | \
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S
index f3f288a..26247c9 100644
--- a/arch/arm/mm/tlb-v7.S
+++ b/arch/arm/mm/tlb-v7.S
@@ -13,6 +13,7 @@
  */
 #include <linux/init.h>
 #include <linux/linkage.h>
+#include <asm/assembler.h>
 #include <asm/asm-offsets.h>
 #include <asm/page.h>
 #include <asm/tlbflush.h>
@@ -41,20 +42,15 @@ ENTRY(v7wbi_flush_user_tlb_range)
 	orr	r0, r3, r0, lsl #PAGE_SHIFT	@ Create initial MVA
 	mov	r1, r1, lsl #PAGE_SHIFT
 1:
-#ifdef CONFIG_SMP
-	mcr	p15, 0, r0, c8, c3, 1		@ TLB invalidate U MVA (shareable) 
-#else
-	mcr	p15, 0, r0, c8, c7, 1		@ TLB invalidate U MVA
-#endif
+	SMP(mcr	p15, 0, r0, c8, c3, 1)		@ TLB invalidate U MVA (shareable) 
+	UP(mcr	p15, 0, r0, c8, c7, 1)		@ TLB invalidate U MVA
+
 	add	r0, r0, #PAGE_SZ
 	cmp	r0, r1
 	blo	1b
 	mov	ip, #0
-#ifdef CONFIG_SMP
-	mcr	p15, 0, ip, c7, c1, 6		@ flush BTAC/BTB Inner Shareable
-#else
-	mcr	p15, 0, ip, c7, c5, 6		@ flush BTAC/BTB
-#endif
+	SMP(mcr	p15, 0, ip, c7, c1, 6)		@ flush BTAC/BTB Inner Shareable
+	UP(mcr	p15, 0, ip, c7, c5, 6)		@ flush BTAC/BTB
 	dsb
 	mov	pc, lr
 ENDPROC(v7wbi_flush_user_tlb_range)
@@ -74,20 +70,14 @@ ENTRY(v7wbi_flush_kern_tlb_range)
 	mov	r0, r0, lsl #PAGE_SHIFT
 	mov	r1, r1, lsl #PAGE_SHIFT
 1:
-#ifdef CONFIG_SMP
-	mcr	p15, 0, r0, c8, c3, 1		@ TLB invalidate U MVA (shareable)
-#else
-	mcr	p15, 0, r0, c8, c7, 1		@ TLB invalidate U MVA
-#endif
+	SMP(mcr	p15, 0, r0, c8, c3, 1)		@ TLB invalidate U MVA (shareable)
+	UP(mcr	p15, 0, r0, c8, c7, 1)		@ TLB invalidate U MVA
 	add	r0, r0, #PAGE_SZ
 	cmp	r0, r1
 	blo	1b
 	mov	r2, #0
-#ifdef CONFIG_SMP
-	mcr	p15, 0, r2, c7, c1, 6		@ flush BTAC/BTB Inner Shareable
-#else
-	mcr	p15, 0, r2, c7, c5, 6		@ flush BTAC/BTB
-#endif
+	SMP(mcr	p15, 0, r2, c7, c1, 6)		@ flush BTAC/BTB Inner Shareable
+	UP(mcr	p15, 0, r2, c7, c5, 6)		@ flush BTAC/BTB
 	dsb
 	isb
 	mov	pc, lr
@@ -99,5 +89,6 @@ ENDPROC(v7wbi_flush_kern_tlb_range)
 ENTRY(v7wbi_tlb_fns)
 	.long	v7wbi_flush_user_tlb_range
 	.long	v7wbi_flush_kern_tlb_range
-	.long	v7wbi_tlb_flags
+	SMP(.long	v7wbi_tlb_flags_smp)
+	UP(.long	v7wbi_tlb_flags_up)
 	.size	v7wbi_tlb_fns, . - v7wbi_tlb_fns
diff --git a/arch/arm/plat-omap/include/plat/smp.h b/arch/arm/plat-omap/include/plat/smp.h
index 5177a9c..99d7e6b 100644
--- a/arch/arm/plat-omap/include/plat/smp.h
+++ b/arch/arm/plat-omap/include/plat/smp.h
@@ -18,6 +18,7 @@
 #define OMAP_ARCH_SMP_H
 
 #include <asm/hardware/gic.h>
+#include <asm/smp_midr.h>
 
 /* Needed for secondary core boot */
 extern void omap_secondary_startup(void);
@@ -33,15 +34,4 @@ static inline void smp_cross_call(const struct cpumask *mask)
 	gic_raise_softirq(mask, 1);
 }
 
-/*
- * Read MPIDR: Multiprocessor affinity register
- */
-#define hard_smp_processor_id()			\
-	({						\
-		unsigned int cpunum;			\
-		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
-			: "=r" (cpunum));		\
-		cpunum &= 0x0F;				\
-	})
-
 #endif

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP
  2010-09-03  9:10                             ` Russell King - ARM Linux
@ 2010-09-03 17:04                               ` Tony Lindgren
  2010-09-03 19:36                                 ` Russell King - ARM Linux
  2010-09-06 11:46                               ` Catalin Marinas
  1 sibling, 1 reply; 14+ messages in thread
From: Tony Lindgren @ 2010-09-03 17:04 UTC (permalink / raw)
  To: linux-arm-kernel

* Russell King - ARM Linux <linux@arm.linux.org.uk> [100903 02:02]:
> On Fri, Sep 03, 2010 at 10:07:34AM +0100, Russell King - ARM Linux wrote:
> > On Thu, Sep 02, 2010 at 04:47:46PM -0700, Tony Lindgren wrote:
> > > Correction, only boots on SMP hardawre. On UP hardware I still
> > > need the following patch.
> > 
> > This should fix that properly.
> 
> Correction - the order of the config tests was wrong.

OK that works now.

Looks like your new patch is missing smp_midr.h BTW.

Tony

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP
  2010-09-03 17:04                               ` Tony Lindgren
@ 2010-09-03 19:36                                 ` Russell King - ARM Linux
  0 siblings, 0 replies; 14+ messages in thread
From: Russell King - ARM Linux @ 2010-09-03 19:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Sep 03, 2010 at 10:04:03AM -0700, Tony Lindgren wrote:
> * Russell King - ARM Linux <linux@arm.linux.org.uk> [100903 02:02]:
> > On Fri, Sep 03, 2010 at 10:07:34AM +0100, Russell King - ARM Linux wrote:
> > > On Thu, Sep 02, 2010 at 04:47:46PM -0700, Tony Lindgren wrote:
> > > > Correction, only boots on SMP hardawre. On UP hardware I still
> > > > need the following patch.
> > > 
> > > This should fix that properly.
> > 
> > Correction - the order of the config tests was wrong.
> 
> OK that works now.
> 
> Looks like your new patch is missing smp_midr.h BTW.

Damn git.  Hate it when keeping patches external to git, even in git diff
form.  Luckily the file is just sitting around in my tree rather than
having been deleted entirely...

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP
  2010-09-03  9:10                             ` Russell King - ARM Linux
  2010-09-03 17:04                               ` Tony Lindgren
@ 2010-09-06 11:46                               ` Catalin Marinas
  2010-09-06 15:34                                 ` Russell King - ARM Linux
  1 sibling, 1 reply; 14+ messages in thread
From: Catalin Marinas @ 2010-09-06 11:46 UTC (permalink / raw)
  To: linux-arm-kernel

Russell,

I can see you posted another version while writing this e-mail. But I
think most comments still apply. 

On Fri, 2010-09-03 at 10:10 +0100, Russell King - ARM Linux wrote:
> diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
> index 6e8f05c..55974d2 100644
> --- a/arch/arm/include/asm/assembler.h
> +++ b/arch/arm/include/asm/assembler.h
> @@ -154,16 +154,32 @@
>         .long   9999b,9001f;                    \
>         .popsection
> 
> +#ifdef CONFIG_SMP
> +#define SMP(instr...)                                          \
> +9998:  instr
> +#define UP(instr...)                                           \
> +       .pushsection ".smpalt.init", "a"                        ;\
> +       .word   9998b                                           ;\
> +       instr                                                   ;\
> +       .popsection
> +#else
> +#define SMP(instr...)
> +#define UP(instr...) instr
> +#endif

Would this work with Thumb-2 kernel builds? Maybe you can add a W(instr)
in the SMP/UP macros to make sure that the instruction is always 32-bit
wide.

> diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
> index bb8e93a..bb2ef60 100644
> --- a/arch/arm/kernel/entry-armv.S
> +++ b/arch/arm/kernel/entry-armv.S
> @@ -965,11 +965,8 @@ kuser_cmpxchg_fixup:
>         beq     1b
>         rsbs    r0, r3, #0
>         /* beware -- each __kuser slot must be 8 instructions max */
> -#ifdef CONFIG_SMP
> -       b       __kuser_memory_barrier
> -#else
> -       usr_ret lr
> -#endif
> +       SMP(b   __kuser_memory_barrier)
> +       UP(usr_ret      lr)

Ah, the automatic W() I mentioned above wouldn't work for macros.

> @@ -333,4 +336,35 @@ __create_page_tables:
>  ENDPROC(__create_page_tables)
>         .ltorg
> 
> +#ifdef CONFIG_SMP_ON_UP
> +__fixup_smp:
> +       and     r0, r9, #0xff000000
> +       teq     r0, #0x41000000         @ ARM CPU?
> +       bne     smp_on_up               @ no, assume UP

That's a bit restricting but I'm not sure we have a better way. If we
have the new CPUID format (MIDR[19:16] = 0xf), we can check MMFR0[31:28]
for 1 which means "implemented with hardware coherency support".

> +       and     r0, r9, #0x00070000
> +       teq     r0, #0x00070000         @ ARMv6/v7?
> +       bne     smp_on_up               @ no, assume UP
> +       mrc     p15, 0, r0, c0, c0, 5   @ read MIDR

Typo in comment - MPIDR.

I think this applies to the smp_midr.h file. Should we call it
smp_mpidr.h or just mpidr.h?

> +       movs    r0, r0, lsr #30
> +       teqne   r0, #3                  @ check top two bits 00 or 11
> +       movne   pc, lr
> +
> +smp_on_up:
> +       adr     r0, 1f
> +       ldmia   r0, {r3, r6, r7}
> +       sub     r3, r0, r3
> +       add     r6, r6, r3
> +       add     r7, r7, r3
> +2:     cmp     r6, r7
> +       ldmia   r6!, {r0, r4}
> +       movhs   pc, lr
> +       str     r4, [r0, r3]
> +       b       2b
> +ENDPROC(__fixup_smp)
> +
> +1:     .word   .
> +       .word   __smpalt_begin
> +       .word   __smpalt_end

I think a '.align 2' would be useful as Thumb-2 code may break the
alignment of 1f.

-- 
Catalin

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP
  2010-09-06 11:46                               ` Catalin Marinas
@ 2010-09-06 15:34                                 ` Russell King - ARM Linux
  2010-09-06 15:53                                   ` Catalin Marinas
  0 siblings, 1 reply; 14+ messages in thread
From: Russell King - ARM Linux @ 2010-09-06 15:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 06, 2010 at 12:46:34PM +0100, Catalin Marinas wrote:
> Russell,
> 
> I can see you posted another version while writing this e-mail. But I
> think most comments still apply. 
> 
> On Fri, 2010-09-03 at 10:10 +0100, Russell King - ARM Linux wrote:
> > diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
> > index 6e8f05c..55974d2 100644
> > --- a/arch/arm/include/asm/assembler.h
> > +++ b/arch/arm/include/asm/assembler.h
> > @@ -154,16 +154,32 @@
> >         .long   9999b,9001f;                    \
> >         .popsection
> > 
> > +#ifdef CONFIG_SMP
> > +#define SMP(instr...)                                          \
> > +9998:  instr
> > +#define UP(instr...)                                           \
> > +       .pushsection ".smpalt.init", "a"                        ;\
> > +       .word   9998b                                           ;\
> > +       instr                                                   ;\
> > +       .popsection
> > +#else
> > +#define SMP(instr...)
> > +#define UP(instr...) instr
> > +#endif
> 
> Would this work with Thumb-2 kernel builds? Maybe you can add a W(instr)
> in the SMP/UP macros to make sure that the instruction is always 32-bit
> wide.

Probably not, and it's not obvious how to make it work for T2 kernel
builds.  For the time being, I'm going to make this available only for
native ARM builds.  We can think about how to make this work for T2
sometime later.

> > diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
> > index bb8e93a..bb2ef60 100644
> > --- a/arch/arm/kernel/entry-armv.S
> > +++ b/arch/arm/kernel/entry-armv.S
> > @@ -965,11 +965,8 @@ kuser_cmpxchg_fixup:
> >         beq     1b
> >         rsbs    r0, r3, #0
> >         /* beware -- each __kuser slot must be 8 instructions max */
> > -#ifdef CONFIG_SMP
> > -       b       __kuser_memory_barrier
> > -#else
> > -       usr_ret lr
> > -#endif
> > +       SMP(b   __kuser_memory_barrier)
> > +       UP(usr_ret      lr)
> 
> Ah, the automatic W() I mentioned above wouldn't work for macros.

Indeed, that's only half of the problem.  On T2, some of these may be
16-bit values, others may be 32-bit values, and this mechanism has no
way to know the size of the areas.

> > @@ -333,4 +336,35 @@ __create_page_tables:
> >  ENDPROC(__create_page_tables)
> >         .ltorg
> > 
> > +#ifdef CONFIG_SMP_ON_UP
> > +__fixup_smp:
> > +       and     r0, r9, #0xff000000
> > +       teq     r0, #0x41000000         @ ARM CPU?
> > +       bne     smp_on_up               @ no, assume UP
> 
> That's a bit restricting but I'm not sure we have a better way. If we
> have the new CPUID format (MIDR[19:16] = 0xf), we can check MMFR0[31:28]
> for 1 which means "implemented with hardware coherency support".
> 
> > +       and     r0, r9, #0x00070000
> > +       teq     r0, #0x00070000         @ ARMv6/v7?
> > +       bne     smp_on_up               @ no, assume UP
> > +       mrc     p15, 0, r0, c0, c0, 5   @ read MIDR
> 
> Typo in comment - MPIDR.

Fixed.

> I think this applies to the smp_midr.h file. Should we call it
> smp_mpidr.h or just mpidr.h?

Already fixed.

> I think a '.align 2' would be useful as Thumb-2 code may break the
> alignment of 1f.

Maybe, but if we restrict this to only ARM builds for the time being,
there isn't a problem.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP
  2010-09-06 15:34                                 ` Russell King - ARM Linux
@ 2010-09-06 15:53                                   ` Catalin Marinas
  2010-09-06 16:36                                     ` Russell King - ARM Linux
  0 siblings, 1 reply; 14+ messages in thread
From: Catalin Marinas @ 2010-09-06 15:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2010-09-06 at 16:34 +0100, Russell King - ARM Linux wrote:
> On Mon, Sep 06, 2010 at 12:46:34PM +0100, Catalin Marinas wrote:
> > Would this work with Thumb-2 kernel builds? Maybe you can add a W(instr)
> > in the SMP/UP macros to make sure that the instruction is always 32-bit
> > wide.
> 
> Probably not, and it's not obvious how to make it work for T2 kernel
> builds.  For the time being, I'm going to make this available only for
> native ARM builds.  We can think about how to make this work for T2
> sometime later.
[...]
> Indeed, that's only half of the problem.  On T2, some of these may be
> 16-bit values, others may be 32-bit values, and this mechanism has no
> way to know the size of the areas.

We can add the W() macro and they are guaranteed to be 32-bit wide or
get a compilation error. Something like using "UP(W(nop))", though it's
doesn't look as nice.

The usr_ret macro is always compiled to ARM mode anyway.

It may be easier to do it in this patch patch rather than at a later
time trying to grep for SMP/UP macros.

-- 
Catalin

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP
  2010-09-06 15:53                                   ` Catalin Marinas
@ 2010-09-06 16:36                                     ` Russell King - ARM Linux
  2010-09-06 17:11                                       ` Catalin Marinas
  0 siblings, 1 reply; 14+ messages in thread
From: Russell King - ARM Linux @ 2010-09-06 16:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 06, 2010 at 04:53:47PM +0100, Catalin Marinas wrote:
> On Mon, 2010-09-06 at 16:34 +0100, Russell King - ARM Linux wrote:
> > On Mon, Sep 06, 2010 at 12:46:34PM +0100, Catalin Marinas wrote:
> > > Would this work with Thumb-2 kernel builds? Maybe you can add a W(instr)
> > > in the SMP/UP macros to make sure that the instruction is always 32-bit
> > > wide.
> > 
> > Probably not, and it's not obvious how to make it work for T2 kernel
> > builds.  For the time being, I'm going to make this available only for
> > native ARM builds.  We can think about how to make this work for T2
> > sometime later.
> [...]
> > Indeed, that's only half of the problem.  On T2, some of these may be
> > 16-bit values, others may be 32-bit values, and this mechanism has no
> > way to know the size of the areas.
> 
> We can add the W() macro and they are guaranteed to be 32-bit wide or
> get a compilation error. Something like using "UP(W(nop))", though it's
> doesn't look as nice.
> 
> The usr_ret macro is always compiled to ARM mode anyway.

That's not the only place - here's another:

+       ALT_SMP(test_for_ipi r0, r6, r5, lr)
+       ALT_UP_B(9997f)

test_for_ipi may be thumb code, which could be 16-bit aligned.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP
  2010-09-06 16:36                                     ` Russell King - ARM Linux
@ 2010-09-06 17:11                                       ` Catalin Marinas
  0 siblings, 0 replies; 14+ messages in thread
From: Catalin Marinas @ 2010-09-06 17:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2010-09-06 at 17:36 +0100, Russell King - ARM Linux wrote:
> On Mon, Sep 06, 2010 at 04:53:47PM +0100, Catalin Marinas wrote:
> > On Mon, 2010-09-06 at 16:34 +0100, Russell King - ARM Linux wrote:
> > > On Mon, Sep 06, 2010 at 12:46:34PM +0100, Catalin Marinas wrote:
> > > > Would this work with Thumb-2 kernel builds? Maybe you can add a W(instr)
> > > > in the SMP/UP macros to make sure that the instruction is always 32-bit
> > > > wide.
> > >
> > > Probably not, and it's not obvious how to make it work for T2 kernel
> > > builds.  For the time being, I'm going to make this available only for
> > > native ARM builds.  We can think about how to make this work for T2
> > > sometime later.
> > [...]
> > > Indeed, that's only half of the problem.  On T2, some of these may be
> > > 16-bit values, others may be 32-bit values, and this mechanism has no
> > > way to know the size of the areas.
> >
> > We can add the W() macro and they are guaranteed to be 32-bit wide or
> > get a compilation error. Something like using "UP(W(nop))", though it's
> > doesn't look as nice.
> >
> > The usr_ret macro is always compiled to ARM mode anyway.
> 
> That's not the only place - here's another:
> 
> +       ALT_SMP(test_for_ipi r0, r6, r5, lr)
> +       ALT_UP_B(9997f)
> 
> test_for_ipi may be thumb code, which could be 16-bit aligned.

The branch can be 16-bit aligned as well but we would have to change the
fixup loop for Thumb-2 to load/store 2 half-words and avoid an alignment
fault.

Anyway, I agree that for now we should get the ARM builds working and we
can change the Thumb-2 afterwards, as time allows. It doesn't look like
something fundamental would prevent this.

-- 
Catalin

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2010-09-06 17:11 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-09-01 23:49 [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP Tony Lindgren
  -- strict thread matches above, loose matches on Subject: below --
2010-08-17 14:12 [PATCH 0/4] Hacks to allow booting ARM SMP kernel on UP ARMv7 Tony Lindgren
2010-08-17 15:40 ` Russell King - ARM Linux
2010-08-19  7:38   ` Tony Lindgren
2010-08-19  9:38     ` Bryan Wu
2010-08-19  9:57       ` Tony Lindgren
2010-08-19 10:20         ` Russell King - ARM Linux
2010-08-20 12:06           ` Tony Lindgren
2010-08-30 22:55             ` Tony Lindgren
2010-09-02 13:36               ` Russell King - ARM Linux
2010-09-02 16:16                 ` Tony Lindgren
2010-09-02 16:20                   ` [PATCH 3/6] ARM: Fix v7wbi_tlb_flags for SMP on UP Tony Lindgren
2010-09-02 16:25                     ` Russell King - ARM Linux
2010-09-02 16:34                       ` Tony Lindgren
2010-09-02 23:47                         ` Tony Lindgren
2010-09-03  9:07                           ` Russell King - ARM Linux
2010-09-03  9:10                             ` Russell King - ARM Linux
2010-09-03 17:04                               ` Tony Lindgren
2010-09-03 19:36                                 ` Russell King - ARM Linux
2010-09-06 11:46                               ` Catalin Marinas
2010-09-06 15:34                                 ` Russell King - ARM Linux
2010-09-06 15:53                                   ` Catalin Marinas
2010-09-06 16:36                                     ` Russell King - ARM Linux
2010-09-06 17:11                                       ` Catalin Marinas

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).