* [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 0/4] Hacks to allow booting ARM SMP kernel on UP ARMv7 @ 2010-08-17 14:12 Tony Lindgren 2010-08-17 15:40 ` Russell King - ARM Linux 0 siblings, 1 reply; 14+ messages in thread From: Tony Lindgren @ 2010-08-17 14:12 UTC (permalink / raw) To: linux-arm-kernel * Russell King - ARM Linux <linux@arm.linux.org.uk> [100817 16:44]: > On Tue, Aug 17, 2010 at 01:53:12PM +0300, Tony Lindgren wrote: > > Here are some experimental patches to allow booting ARMv7 SMP > > kernel on UP to some extent. Posting these early in case it is > > of any help as I know at least Bryan Wu is working on similar > > issues. > > I think these are compeltely the wrong direction. First thing to realise > is that XIP in the "SMP and UP in one kernel" is not really practical - > I'm not sure that many people who want that kind of flexibility also want > XIP too. > > So let's forget about the kernel text being read-only. OK, at least for me. > The second thing to realise is that most of the SMP dependencies are in > assembly - and we can make lists of instructions and their modified > versions that would be necessary to boot a SMP kernel on UP. OK cool. > So something like this will do (though note that not everywhere has been > fixed up - such as the page table flags - or this patch tested yet.) Great, will give it a try hopefully tomorrow. Sounds like that's the way to deal with fixing up things when booting up older UP ARMv6 without the 32v6 support :) > If we don't want the SMP-on-UP support for SMP kernels (it's not actually > all that big - around 512 bytes) then we can discard the .smpalt.init > section and the __fixup_smp code. OK Regards, Tony ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 0/4] Hacks to allow booting ARM SMP kernel on UP ARMv7 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 0 siblings, 1 reply; 14+ messages in thread From: Russell King - ARM Linux @ 2010-08-17 15:40 UTC (permalink / raw) To: linux-arm-kernel On Tue, Aug 17, 2010 at 05:12:11PM +0300, Tony Lindgren wrote: > Great, will give it a try hopefully tomorrow. Sounds like that's the way > to deal with fixing up things when booting up older UP ARMv6 without the > 32v6 support :) What I've also been debating about is adding another word to the smpalt structure, that being a set of flags which denote the situation where the alternative should be used. That means we can use it to do individual word replacements for SMP vs UP, ARMv6 vs ARMv6k etc. ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 0/4] Hacks to allow booting ARM SMP kernel on UP ARMv7 2010-08-17 15:40 ` Russell King - ARM Linux @ 2010-08-19 7:38 ` Tony Lindgren 2010-08-19 9:38 ` Bryan Wu 0 siblings, 1 reply; 14+ messages in thread From: Tony Lindgren @ 2010-08-19 7:38 UTC (permalink / raw) To: linux-arm-kernel * Russell King - ARM Linux <linux@arm.linux.org.uk> [100817 18:33]: > On Tue, Aug 17, 2010 at 05:12:11PM +0300, Tony Lindgren wrote: > > Great, will give it a try hopefully tomorrow. Sounds like that's the way > > to deal with fixing up things when booting up older UP ARMv6 without the > > 32v6 support :) > > What I've also been debating about is adding another word to the > smpalt structure, that being a set of flags which denote the situation > where the alternative should be used. > > That means we can use it to do individual word replacements for SMP vs > UP, ARMv6 vs ARMv6k etc. Sounds good to me. Maybe it should then be called cpualt instead of smpalt? Tried booting your patch and needed the following fix for Cortex-A8 UP. Now it boots to the following error: Machine configuration botched (nr -1073741824), unable to continue. Does some struct size need to be changed or something? Regards, Tony -------------- next part -------------- A non-text attachment was scrubbed... Name: smp-on-up-fix.patch Type: text/x-diff Size: 667 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20100819/088d7ba9/attachment.bin> ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 0/4] Hacks to allow booting ARM SMP kernel on UP ARMv7 2010-08-19 7:38 ` Tony Lindgren @ 2010-08-19 9:38 ` Bryan Wu 2010-08-19 9:57 ` Tony Lindgren 0 siblings, 1 reply; 14+ messages in thread From: Bryan Wu @ 2010-08-19 9:38 UTC (permalink / raw) To: linux-arm-kernel On 08/19/2010 03:38 PM, Tony Lindgren wrote: > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100817 18:33]: >> On Tue, Aug 17, 2010 at 05:12:11PM +0300, Tony Lindgren wrote: >>> Great, will give it a try hopefully tomorrow. Sounds like that's the way >>> to deal with fixing up things when booting up older UP ARMv6 without the >>> 32v6 support :) >> >> What I've also been debating about is adding another word to the >> smpalt structure, that being a set of flags which denote the situation >> where the alternative should be used. >> >> That means we can use it to do individual word replacements for SMP vs >> UP, ARMv6 vs ARMv6k etc. > > Sounds good to me. Maybe it should then be called cpualt instead of smpalt? > > Tried booting your patch and needed the following fix for Cortex-A8 UP. > > Now it boots to the following error: > > Machine configuration botched (nr -1073741824), unable to continue. > > Does some struct size need to be changed or something? > I also tested these 2 patches on my beagle board based on -for-next branch for linux-omap tree. I don't have debug hardware to find the kernel boot failure. It looks like it stops at very early stage. Do you know where is the message (nr -1073741824) coming from? Thanks, -- Bryan Wu <bryan.wu@canonical.com> Kernel Developer +86.138-1617-6545 Mobile Ubuntu Kernel Team | Hardware Enablement Team Canonical Ltd. www.canonical.com Ubuntu - Linux for human beings | www.ubuntu.com ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 0/4] Hacks to allow booting ARM SMP kernel on UP ARMv7 2010-08-19 9:38 ` Bryan Wu @ 2010-08-19 9:57 ` Tony Lindgren 2010-08-19 10:20 ` Russell King - ARM Linux 0 siblings, 1 reply; 14+ messages in thread From: Tony Lindgren @ 2010-08-19 9:57 UTC (permalink / raw) To: linux-arm-kernel * Bryan Wu <bryan.wu@canonical.com> [100819 12:31]: > On 08/19/2010 03:38 PM, Tony Lindgren wrote: > > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100817 18:33]: > >> On Tue, Aug 17, 2010 at 05:12:11PM +0300, Tony Lindgren wrote: > >>> Great, will give it a try hopefully tomorrow. Sounds like that's the way > >>> to deal with fixing up things when booting up older UP ARMv6 without the > >>> 32v6 support :) > >> > >> What I've also been debating about is adding another word to the > >> smpalt structure, that being a set of flags which denote the situation > >> where the alternative should be used. > >> > >> That means we can use it to do individual word replacements for SMP vs > >> UP, ARMv6 vs ARMv6k etc. > > > > Sounds good to me. Maybe it should then be called cpualt instead of smpalt? > > > > Tried booting your patch and needed the following fix for Cortex-A8 UP. > > > > Now it boots to the following error: > > > > Machine configuration botched (nr -1073741824), unable to continue. > > > > Does some struct size need to be changed or something? > > > > I also tested these 2 patches on my beagle board based on -for-next branch for > linux-omap tree. I don't have debug hardware to find the kernel boot failure. It > looks like it stops at very early stage. > > Do you know where is the message (nr -1073741824) coming from? Looks like something is not quite right with smp_on_up part of __fixup_smp, returning early before smp_on_up does not produce that. Regards, Tony ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 0/4] Hacks to allow booting ARM SMP kernel on UP ARMv7 2010-08-19 9:57 ` Tony Lindgren @ 2010-08-19 10:20 ` Russell King - ARM Linux 2010-08-20 12:06 ` Tony Lindgren 0 siblings, 1 reply; 14+ messages in thread From: Russell King - ARM Linux @ 2010-08-19 10:20 UTC (permalink / raw) To: linux-arm-kernel On Thu, Aug 19, 2010 at 12:57:06PM +0300, Tony Lindgren wrote: > Looks like something is not quite right with smp_on_up part of __fixup_smp, > returning early before smp_on_up does not produce that. It's probably overwriting some register it shouldn't be. I might be able to look at this sometime during the coming week... assuming that the weather is as bad as they forecast and I have 'net connectivity. ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 0/4] Hacks to allow booting ARM SMP kernel on UP ARMv7 2010-08-19 10:20 ` Russell King - ARM Linux @ 2010-08-20 12:06 ` Tony Lindgren 2010-08-30 22:55 ` Tony Lindgren 0 siblings, 1 reply; 14+ messages in thread From: Tony Lindgren @ 2010-08-20 12:06 UTC (permalink / raw) To: linux-arm-kernel * Russell King - ARM Linux <linux@arm.linux.org.uk> [100819 13:13]: > On Thu, Aug 19, 2010 at 12:57:06PM +0300, Tony Lindgren wrote: > > Looks like something is not quite right with smp_on_up part of __fixup_smp, > > returning early before smp_on_up does not produce that. > > It's probably overwriting some register it shouldn't be. I might be > able to look at this sometime during the coming week... assuming that > the weather is as bad as they forecast and I have 'net connectivity. OK, I'll be offline too probably until late next week. Tony ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 0/4] Hacks to allow booting ARM SMP kernel on UP ARMv7 2010-08-20 12:06 ` Tony Lindgren @ 2010-08-30 22:55 ` Tony Lindgren 2010-09-02 13:36 ` Russell King - ARM Linux 0 siblings, 1 reply; 14+ messages in thread From: Tony Lindgren @ 2010-08-30 22:55 UTC (permalink / raw) To: linux-arm-kernel * Tony Lindgren <tony@atomide.com> [100820 04:59]: > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100819 13:13]: > > On Thu, Aug 19, 2010 at 12:57:06PM +0300, Tony Lindgren wrote: > > > Looks like something is not quite right with smp_on_up part of __fixup_smp, > > > returning early before smp_on_up does not produce that. > > > > It's probably overwriting some register it shouldn't be. I might be > > able to look at this sometime during the coming week... assuming that > > the weather is as bad as they forecast and I have 'net connectivity. This seems to fix it. Tony -------------- next part -------------- A non-text attachment was scrubbed... Name: fix-smp-on-up.patch Type: text/x-diff Size: 788 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20100830/c3899324/attachment.bin> ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 0/4] Hacks to allow booting ARM SMP kernel on UP ARMv7 2010-08-30 22:55 ` Tony Lindgren @ 2010-09-02 13:36 ` Russell King - ARM Linux 2010-09-02 16:16 ` Tony Lindgren 0 siblings, 1 reply; 14+ messages in thread From: Russell King - ARM Linux @ 2010-09-02 13:36 UTC (permalink / raw) To: linux-arm-kernel On Mon, Aug 30, 2010 at 03:55:27PM -0700, Tony Lindgren wrote: > * Tony Lindgren <tony@atomide.com> [100820 04:59]: > > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100819 13:13]: > > > On Thu, Aug 19, 2010 at 12:57:06PM +0300, Tony Lindgren wrote: > > > > Looks like something is not quite right with smp_on_up part of __fixup_smp, > > > > returning early before smp_on_up does not produce that. > > > > > > It's probably overwriting some register it shouldn't be. I might be > > > able to look at this sometime during the coming week... assuming that > > > the weather is as bad as they forecast and I have 'net connectivity. > > This seems to fix it. Thanks, merged that into my original patch - so here it is again with everything updated. diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9295110..725a463 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' tknow 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/smp_midr.h b/arch/arm/include/asm/smp_midr.h index e69de29..4538ba4 100644 --- a/arch/arm/include/asm/smp_midr.h +++ b/arch/arm/include/asm/smp_midr.h @@ -0,0 +1,17 @@ +#ifndef ASMARM_SMP_MIDR_H +#define ASMARM_SMP_MIDR_H + +#define hard_smp_processor_id() \ + ({ \ + unsigned int cpunum; \ + __asm__("\n" \ + "1: mrc p15, 0, %0, c0, c0, 5\n" \ + " .pushsection \".smpalt.init\", \"a\"\n" \ + " .word 1b\n" \ + " mov %0, #0\n" \ + " .popsection" \ + : "=r" (cpunum)); \ + cpunum &= 0x0F; \ + }) + +#endif diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h index 33b546a..1fd0db9 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,12 +189,15 @@ # 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) + +#ifdef CONFIG_SMP +#define v7wbi_tlb_flags v7wbi_tlb_flags_smp +#else +#define v7wbi_tlb_flags v7wbi_tlb_flags_up #endif #ifdef CONFIG_CPU_TLB_V7 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..cf76484 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 6a3ff65..ed96907 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 0/4] Hacks to allow booting ARM SMP kernel on UP ARMv7 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 0 siblings, 1 reply; 14+ messages in thread From: Tony Lindgren @ 2010-09-02 16:16 UTC (permalink / raw) To: linux-arm-kernel * Russell King - ARM Linux <linux@arm.linux.org.uk> [100902 06:29]: > On Mon, Aug 30, 2010 at 03:55:27PM -0700, Tony Lindgren wrote: > > * Tony Lindgren <tony@atomide.com> [100820 04:59]: > > > * Russell King - ARM Linux <linux@arm.linux.org.uk> [100819 13:13]: > > > > On Thu, Aug 19, 2010 at 12:57:06PM +0300, Tony Lindgren wrote: > > > > > Looks like something is not quite right with smp_on_up part of __fixup_smp, > > > > > returning early before smp_on_up does not produce that. > > > > > > > > It's probably overwriting some register it shouldn't be. I might be > > > > able to look at this sometime during the coming week... assuming that > > > > the weather is as bad as they forecast and I have 'net connectivity. > > > > This seems to fix it. > > Thanks, merged that into my original patch - so here it is again with > everything updated. Your patch sure makes things simpler! The problem still is the V6 vs V7 SMP code though. Will post my six patches that apply on top of your patch as a reply to this mail. With those, everything seems to work, at least after testing on omap3630 (Cortex-A8 UP) and omap4430 (Cortex-A9 SMP). Will, maybe see if there are some parts in your patchset that should be used instead? I noticed pretty much all the earlier hacks are no longer needed :) Regards, 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: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).