From dfbdcda280eb762bae2184145cc0702932d41798 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Sat, 18 Sep 2021 10:44:34 +0200 Subject: gcc-plugins: arm-ssp: Prepare for THREAD_INFO_IN_TASK support We will be enabling THREAD_INFO_IN_TASK support for ARM, which means that we can no longer load the stack canary value by masking the stack pointer and taking the copy that lives in thread_info. Instead, we will be able to load it from the task_struct directly, by using the TPIDRURO register which will hold the current task pointer when THREAD_INFO_IN_TASK is in effect. This is much more straight-forward, and allows us to declutter this code a bit while at it. Note that this means that ARMv6 (non-v6K) SMP systems can no longer use this feature, but those are quite rare to begin with, so this is a reasonable trade off. Reviewed-by: Kees Cook Signed-off-by: Ard Biesheuvel Reviewed-by: Linus Walleij Tested-by: Amit Daniel Kachhap --- arch/arm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index fc196421b2ce..ff3e64ae959e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1600,7 +1600,7 @@ config XEN config STACKPROTECTOR_PER_TASK bool "Use a unique stack canary value for each task" - depends on GCC_PLUGINS && STACKPROTECTOR && SMP && !XIP_DEFLATED_DATA + depends on GCC_PLUGINS && STACKPROTECTOR && THREAD_INFO_IN_TASK && !XIP_DEFLATED_DATA select GCC_PLUGIN_ARM_SSP_PER_TASK default y help -- cgit v1.2.3 From 50596b7559bf226bb35ad55855ee979453ec06a1 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Sat, 18 Sep 2021 10:44:37 +0200 Subject: ARM: smp: Store current pointer in TPIDRURO register if available Now that the user space TLS register is assigned on every return to user space, we can use it to keep the 'current' pointer while running in the kernel. This removes the need to access it via thread_info, which is located at the base of the stack, but will be moved out of there in a subsequent patch. Use the __builtin_thread_pointer() helper when available - this will help GCC understand that reloading the value within the same function is not necessary, even when using the per-task stack protector (which also generates accesses via the TLS register). For example, the generated code below loads TPIDRURO only once, and uses it to access both the stack canary and the preempt_count fields. : e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} ee1d 4f70 mrc 15, 0, r4, cr13, cr0, {3} 4606 mov r6, r0 b094 sub sp, #80 ; 0x50 f8d4 34e8 ldr.w r3, [r4, #1256] ; 0x4e8 <- stack canary 9313 str r3, [sp, #76] ; 0x4c f8d4 8004 ldr.w r8, [r4, #4] <- preempt count Co-developed-by: Keith Packard Signed-off-by: Keith Packard Signed-off-by: Ard Biesheuvel Reviewed-by: Linus Walleij Tested-by: Amit Daniel Kachhap --- arch/arm/Kconfig | 5 ++++ arch/arm/Makefile | 4 +++ arch/arm/include/asm/assembler.h | 24 ++++++++++++++++++ arch/arm/include/asm/current.h | 50 ++++++++++++++++++++++++++++++++++++++ arch/arm/include/asm/switch_to.h | 2 ++ arch/arm/include/asm/thread_info.h | 2 ++ arch/arm/kernel/entry-armv.S | 5 ++++ arch/arm/kernel/entry-common.S | 1 + arch/arm/kernel/head-common.S | 5 ++++ arch/arm/kernel/process.c | 4 +++ arch/arm/kernel/smp.c | 2 ++ arch/arm/mm/proc-macros.S | 3 +-- 12 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 arch/arm/include/asm/current.h (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ff3e64ae959e..cd195e6f4ea6 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1157,6 +1157,11 @@ config SMP_ON_UP If you don't know what to do here, say Y. + +config CURRENT_POINTER_IN_TPIDRURO + def_bool y + depends on SMP && CPU_32v6K && !CPU_V6 + config ARM_CPU_TOPOLOGY bool "Support cpu topology definition" depends on SMP && CPU_V7 diff --git a/arch/arm/Makefile b/arch/arm/Makefile index b46e673a0ebe..1c540157e283 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -113,6 +113,10 @@ ifeq ($(CONFIG_CC_IS_CLANG),y) CFLAGS_ABI += -meabi gnu endif +ifeq ($(CONFIG_CURRENT_POINTER_IN_TPIDRURO),y) +CFLAGS_ABI += -mtp=cp15 +endif + # Accept old syntax despite ".syntax unified" AFLAGS_NOWARN :=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W) diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index e2b1fd558bf3..c1551dee28be 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -199,6 +199,30 @@ .endm .endr + .macro get_current, rd +#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO + mrc p15, 0, \rd, c13, c0, 3 @ get TPIDRURO register +#else + get_thread_info \rd + ldr \rd, [\rd, #TI_TASK] +#endif + .endm + + .macro set_current, rn +#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO + mcr p15, 0, \rn, c13, c0, 3 @ set TPIDRURO register +#endif + .endm + + .macro reload_current, t1:req, t2:req +#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO + adr_l \t1, __entry_task @ get __entry_task base address + mrc p15, 0, \t2, c13, c0, 4 @ get per-CPU offset + ldr \t1, [\t1, \t2] @ load variable + mcr p15, 0, \t1, c13, c0, 3 @ store in TPIDRURO +#endif + .endm + /* * Get current thread_info. */ diff --git a/arch/arm/include/asm/current.h b/arch/arm/include/asm/current.h new file mode 100644 index 000000000000..1d472fa7697b --- /dev/null +++ b/arch/arm/include/asm/current.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021 Keith Packard + * Copyright (c) 2021 Google, LLC + */ + +#ifndef _ASM_ARM_CURRENT_H +#define _ASM_ARM_CURRENT_H + +#ifndef __ASSEMBLY__ + +struct task_struct; + +static inline void set_current(struct task_struct *cur) +{ + if (!IS_ENABLED(CONFIG_CURRENT_POINTER_IN_TPIDRURO)) + return; + + /* Set TPIDRURO */ + asm("mcr p15, 0, %0, c13, c0, 3" :: "r"(cur) : "memory"); +} + +#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO + +static inline struct task_struct *get_current(void) +{ + struct task_struct *cur; + +#if __has_builtin(__builtin_thread_pointer) + /* + * Use the __builtin helper when available - this results in better + * code, especially when using GCC in combination with the per-task + * stack protector, as the compiler will recognize that it needs to + * load the TLS register only once in every function. + */ + cur = __builtin_thread_pointer(); +#else + asm("mrc p15, 0, %0, c13, c0, 3" : "=r"(cur)); +#endif + return cur; +} + +#define current get_current() +#else +#include +#endif /* CONFIG_CURRENT_POINTER_IN_TPIDRURO */ + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_ARM_CURRENT_H */ diff --git a/arch/arm/include/asm/switch_to.h b/arch/arm/include/asm/switch_to.h index 007d8fea7157..61e4a3c4ca6e 100644 --- a/arch/arm/include/asm/switch_to.h +++ b/arch/arm/include/asm/switch_to.h @@ -26,6 +26,8 @@ extern struct task_struct *__switch_to(struct task_struct *, struct thread_info #define switch_to(prev,next,last) \ do { \ __complete_pending_tlbi(); \ + if (IS_ENABLED(CONFIG_CURRENT_POINTER_IN_TPIDRURO)) \ + __this_cpu_write(__entry_task, next); \ last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \ } while (0) diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index f0cacc733231..76b6fbd5540c 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h @@ -29,6 +29,8 @@ struct task_struct; +DECLARE_PER_CPU(struct task_struct *, __entry_task); + #include struct cpu_context_save { diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 241b73d64df7..7263a45abf3d 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -384,6 +384,8 @@ ENDPROC(__fiq_abt) ATRAP( teq r8, r7) ATRAP( mcrne p15, 0, r8, c1, c0, 0) + reload_current r7, r8 + @ @ Clear FP to mark the first stack frame @ @@ -762,6 +764,8 @@ ENTRY(__switch_to) add r7, r7, #TSK_STACK_CANARY & ~IMM12_MASK .endif ldr r7, [r7, #TSK_STACK_CANARY & IMM12_MASK] +#elif defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) + ldr r7, [r2, #TI_TASK] #endif #ifdef CONFIG_CPU_USE_DOMAINS mcr p15, 0, r6, c3, c0, 0 @ Set domain register @@ -776,6 +780,7 @@ ENTRY(__switch_to) #endif THUMB( mov ip, r4 ) mov r0, r5 + set_current r7 ARM( ldmia r4, {r4 - sl, fp, sp, pc} ) @ Load all regs saved previously THUMB( ldmia ip!, {r4 - sl, fp} ) @ Load all regs saved previously THUMB( ldr sp, [ip], #4 ) diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index d9c99db50243..ac86c34682bb 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -170,6 +170,7 @@ ENTRY(vector_swi) str saved_psr, [sp, #S_PSR] @ Save CPSR str r0, [sp, #S_OLD_R0] @ Save OLD_R0 #endif + reload_current r10, ip zero_fp alignment_trap r10, ip, __cr_alignment asm_trace_hardirqs_on save=0 diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index 29b2eda136bb..da18e0a17dc2 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S @@ -105,6 +105,11 @@ __mmap_switched: mov r1, #0 bl __memset @ clear .bss +#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO + adr_l r0, init_task @ get swapper task_struct + set_current r0 +#endif + ldmia r4, {r0, r1, r2, r3} str r9, [r0] @ Save processor ID str r7, [r1] @ Save machine type diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index cd73c216b272..30428d756515 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -36,6 +36,10 @@ #include "signal.h" +#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO +DEFINE_PER_CPU(struct task_struct *, __entry_task); +#endif + #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK) #include unsigned long __stack_chk_guard __read_mostly; diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 8979d548ec17..97ee6b1567e9 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -409,6 +409,8 @@ asmlinkage void secondary_start_kernel(struct task_struct *task) struct mm_struct *mm = &init_mm; unsigned int cpu; + set_current(task); + secondary_biglittle_init(); /* diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index e2c743aa2eb2..d48ba99d739c 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S @@ -30,8 +30,7 @@ * act_mm - get current->active_mm */ .macro act_mm, rd - get_thread_info \rd - ldr \rd, [\rd, #TI_TASK] + get_current \rd .if (TSK_ACTIVE_MM > IMM12_MASK) add \rd, \rd, #TSK_ACTIVE_MM & ~IMM12_MASK .endif -- cgit v1.2.3 From 18ed1c01a7dd3d7c780b06a49124da237a4c1790 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Sat, 18 Sep 2021 10:44:38 +0200 Subject: ARM: smp: Enable THREAD_INFO_IN_TASK Now that we no longer rely on thread_info living at the base of the task stack to be able to access the 'current' pointer, we can wire up the generic support for moving thread_info into the task struct itself. Note that this requires us to update the cpu field in thread_info explicitly, now that the core code no longer does so. Ideally, we would switch the percpu code to access the cpu field in task_struct instead, but this unleashes #include circular dependency hell. Co-developed-by: Keith Packard Signed-off-by: Keith Packard Signed-off-by: Ard Biesheuvel Reviewed-by: Linus Walleij Tested-by: Amit Daniel Kachhap --- arch/arm/Kconfig | 1 + arch/arm/include/asm/assembler.h | 5 +++++ arch/arm/include/asm/switch_to.h | 14 ++++++++++++++ arch/arm/include/asm/thread_info.h | 10 +++++++++- arch/arm/kernel/asm-offsets.c | 2 ++ arch/arm/kernel/entry-armv.S | 2 +- arch/arm/kernel/smp.c | 3 +++ 7 files changed, 35 insertions(+), 2 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index cd195e6f4ea6..4f61c9789e7f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -125,6 +125,7 @@ config ARM select PERF_USE_VMALLOC select RTC_LIB select SYS_SUPPORTS_APM_EMULATION + select THREAD_INFO_IN_TASK if CURRENT_POINTER_IN_TPIDRURO select TRACE_IRQFLAGS_SUPPORT if !CPU_V7M # Above selects are sorted alphabetically; please add new ones # according to that. Thanks. diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index c1551dee28be..7d23d4bb2168 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -227,10 +227,15 @@ * Get current thread_info. */ .macro get_thread_info, rd +#ifdef CONFIG_THREAD_INFO_IN_TASK + /* thread_info is the first member of struct task_struct */ + get_current \rd +#else ARM( mov \rd, sp, lsr #THREAD_SIZE_ORDER + PAGE_SHIFT ) THUMB( mov \rd, sp ) THUMB( lsr \rd, \rd, #THREAD_SIZE_ORDER + PAGE_SHIFT ) mov \rd, \rd, lsl #THREAD_SIZE_ORDER + PAGE_SHIFT +#endif .endm /* diff --git a/arch/arm/include/asm/switch_to.h b/arch/arm/include/asm/switch_to.h index 61e4a3c4ca6e..b55c7b2755e4 100644 --- a/arch/arm/include/asm/switch_to.h +++ b/arch/arm/include/asm/switch_to.h @@ -23,9 +23,23 @@ */ extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *); +static inline void set_ti_cpu(struct task_struct *p) +{ +#ifdef CONFIG_THREAD_INFO_IN_TASK + /* + * The core code no longer maintains the thread_info::cpu field once + * CONFIG_THREAD_INFO_IN_TASK is in effect, but we rely on it for + * raw_smp_processor_id(), which cannot access struct task_struct* + * directly for reasons of circular #inclusion hell. + */ + task_thread_info(p)->cpu = task_cpu(p); +#endif +} + #define switch_to(prev,next,last) \ do { \ __complete_pending_tlbi(); \ + set_ti_cpu(next); \ if (IS_ENABLED(CONFIG_CURRENT_POINTER_IN_TPIDRURO)) \ __this_cpu_write(__entry_task, next); \ last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \ diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index 76b6fbd5540c..787511396f3f 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h @@ -54,7 +54,9 @@ struct cpu_context_save { struct thread_info { unsigned long flags; /* low level flags */ int preempt_count; /* 0 => preemptable, <0 => bug */ +#ifndef CONFIG_THREAD_INFO_IN_TASK struct task_struct *task; /* main task structure */ +#endif __u32 cpu; /* cpu */ __u32 cpu_domain; /* cpu domain */ struct cpu_context_save cpu_context; /* cpu context */ @@ -70,11 +72,16 @@ struct thread_info { #define INIT_THREAD_INFO(tsk) \ { \ - .task = &tsk, \ + INIT_THREAD_INFO_TASK(tsk) \ .flags = 0, \ .preempt_count = INIT_PREEMPT_COUNT, \ } +#ifdef CONFIG_THREAD_INFO_IN_TASK +#define INIT_THREAD_INFO_TASK(tsk) +#else +#define INIT_THREAD_INFO_TASK(tsk) .task = &(tsk), + /* * how to get the thread information struct from C */ @@ -85,6 +92,7 @@ static inline struct thread_info *current_thread_info(void) return (struct thread_info *) (current_stack_pointer & ~(THREAD_SIZE - 1)); } +#endif #define thread_saved_pc(tsk) \ ((unsigned long)(task_thread_info(tsk)->cpu_context.pc)) diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index 9c864ee76107..645845e4982a 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -43,7 +43,9 @@ int main(void) BLANK(); DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); +#ifndef CONFIG_THREAD_INFO_IN_TASK DEFINE(TI_TASK, offsetof(struct thread_info, task)); +#endif DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); DEFINE(TI_CPU_DOMAIN, offsetof(struct thread_info, cpu_domain)); DEFINE(TI_CPU_SAVE, offsetof(struct thread_info, cpu_context)); diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 7263a45abf3d..a54b5044d406 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -765,7 +765,7 @@ ENTRY(__switch_to) .endif ldr r7, [r7, #TSK_STACK_CANARY & IMM12_MASK] #elif defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) - ldr r7, [r2, #TI_TASK] + mov r7, r2 @ Preserve 'next' #endif #ifdef CONFIG_CPU_USE_DOMAINS mcr p15, 0, r6, c3, c0, 0 @ Set domain register diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 97ee6b1567e9..cde5b6d8bac5 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -154,6 +154,9 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) secondary_data.swapper_pg_dir = get_arch_pgd(swapper_pg_dir); #endif secondary_data.task = idle; + if (IS_ENABLED(CONFIG_THREAD_INFO_IN_TASK)) + task_thread_info(idle)->cpu = cpu; + sync_cache_w(&secondary_data); /* -- cgit v1.2.3 From c6e77bb61a557dcf6f7440497634a5dc7ada0b3f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 18 Oct 2021 15:30:39 +0100 Subject: ARM: 9143/1: add CONFIG_PHYS_OFFSET default values For platforms that are not yet converted to ARCH_MULTIPLATFORM, we can disable CONFIG_ARM_PATCH_PHYS_VIRT, which in turn requires setting a correct address here. As we actualy know what all the values are supposed to be based on the old mach/memory.h header file contents (from git history), we can just add them here. This also solves a problem in Kconfig where 'make randconfig' fails to continue if no number is selected for a 'hex' option. Users can still override the number at configuration time, e.g. when the memory visible to the kernel starts at a nonstandard address on some machine, but it should no longer be required now. I originally posted this back in 2016, but the problem still persists. The patch has gotten much simpler though, as almost all platforms rely on ARM_PATCH_PHYS_VIRT now. Link: https://lore.kernel.org/linux-arm-kernel/1455804123-2526139-5-git-send-email-arnd@arndb.de/ Acked-by: Nicolas Pitre Reviewed-by: Linus Walleij Signed-off-by: Arnd Bergmann Signed-off-by: Russell King (Oracle) --- arch/arm/Kconfig | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index fc196421b2ce..680920f78fcb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -264,10 +264,12 @@ config PHYS_OFFSET hex "Physical address of main memory" if MMU depends on !ARM_PATCH_PHYS_VIRT default DRAM_BASE if !MMU - default 0x00000000 if ARCH_FOOTBRIDGE + default 0x00000000 if ARCH_FOOTBRIDGE || ARCH_IXP4XX default 0x10000000 if ARCH_OMAP1 || ARCH_RPC - default 0x20000000 if ARCH_S5PV210 - default 0xc0000000 if ARCH_SA1100 + default 0x30000000 if ARCH_S3C24XX + default 0xa0000000 if ARCH_IOP32X || ARCH_PXA + default 0xc0000000 if ARCH_EP93XX || ARCH_SA1100 + default 0 help Please provide the physical address corresponding to the location of main memory in your system. -- cgit v1.2.3 From ecb108e3e3f7c692082b7c6fce41779c3835854a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 18 Oct 2021 15:30:41 +0100 Subject: ARM: 9144/1: forbid ftrace with clang and thumb2_kernel clang fails to build kernels with THUMB2 and FUNCTION_TRACER enabled when there is any inline asm statement containing the frame pointer register r7: arch/arm/mach-exynos/mcpm-exynos.c:154:2: error: inline asm clobber list contains reserved registers: R7 [-Werror,-Winline-asm] arch/arm/probes/kprobes/actions-thumb.c:449:3: error: inline asm clobber list contains reserved registers: R7 [-Werror,-Winline-asm] Apparently gcc should also have warned about this, and the configuration is actually invalid, though there is some disagreement on the bug trackers about this. Link: https://bugs.llvm.org/show_bug.cgi?id=45826 Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94986 Reviewed-by: Nick Desaulniers Signed-off-by: Arnd Bergmann Signed-off-by: Russell King (Oracle) --- arch/arm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 680920f78fcb..5fdb4a11cda3 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -91,7 +91,7 @@ config ARM select HAVE_FAST_GUP if ARM_LPAE select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL select HAVE_FUNCTION_GRAPH_TRACER if !THUMB2_KERNEL && !CC_IS_CLANG - select HAVE_FUNCTION_TRACER if !XIP_KERNEL + select HAVE_FUNCTION_TRACER if !XIP_KERNEL && !(THUMB2_KERNEL && CC_IS_CLANG) select HAVE_GCC_PLUGINS select HAVE_HW_BREAKPOINT if PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7) select HAVE_IRQ_TIME_ACCOUNTING -- cgit v1.2.3 From 2abd6e34fcf3bd9f9ffafcaa47cdc3ed443f9add Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 18 Oct 2021 15:30:02 +0100 Subject: ARM: 9146/1: RiscPC needs older gcc version Attempting to build mach-rpc with gcc-9 or higher, or with any version of clang results in a build failure, like: arm-linux-gnueabi-gcc-11.1.0: error: unrecognized -march target: armv3m arm-linux-gnueabi-gcc-11.1.0: note: valid arguments are: armv4 armv4t armv5t armv5te armv5tej armv6 armv6j armv6k armv6z armv6kz armv6zk armv6t2 armv6-m armv6s-m armv7 armv7-a armv7ve armv7-r armv7-m armv7e-m armv8-a armv8.1-a armv8.2-a armv8.3-a armv8.4-a armv8.5-a armv8.6-a armv8-m.base armv8-m.main armv8-r armv8.1-m.main iwmmxt iwmmxt2; did you mean 'armv4'? Building with gcc-5 also fails in at least one of these ways: /tmp/cczZoCcv.s:68: Error: selected processor does not support `bx lr' in ARM mode drivers/tty/vt/vt_ioctl.c:958:1: internal compiler error: Segmentation fault Handle this in Kconfig so we don't run into this with randconfig builds, allowing only gcc-6 through gcc-8. Signed-off-by: Arnd Bergmann Signed-off-by: Russell King (Oracle) --- arch/arm/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5fdb4a11cda3..ec317bc8cb99 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -434,6 +434,7 @@ config ARCH_PXA config ARCH_RPC bool "RiscPC" depends on MMU + depends on !CC_IS_CLANG && GCC_VERSION < 90100 && GCC_VERSION >= 60000 select ARCH_ACORN select ARCH_MAY_HAVE_PC_FDC select ARCH_SPARSEMEM_ENABLE -- cgit v1.2.3