From cafb45b2562baa57cb58bef0636c073705954cc4 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 12 May 2015 06:43:04 +0200 Subject: MIPS: SMP: Fix build error. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CC arch/mips/kernel/smp.o arch/mips/kernel/smp.c: In function ‘start_secondary’: arch/mips/kernel/smp.c:149:2: error: passing argument 2 of ‘cpumask_set_cpu’ discards ‘volatile’ qualifier from pointer target type [-Werror] cpumask_set_cpu(cpu, &cpu_callin_map); ^ In file included from ./arch/mips/include/asm/processor.h:14:0, from ./arch/mips/include/asm/thread_info.h:15, from include/linux/thread_info.h:54, from include/asm-generic/preempt.h:4, from arch/mips/include/generated/asm/preempt.h:1, from include/linux/preempt.h:18, from include/linux/interrupt.h:8, from arch/mips/kernel/smp.c:24: include/linux/cpumask.h:272:91: note: expected ‘struct cpumask *’ but argument is of type ‘volatile struct cpumask_t *’ static inline void cpumask_set_cpu(unsigned int cpu, struct cpumask *dstp) ^ arch/mips/kernel/smp.c: In function ‘smp_prepare_boot_cpu’: arch/mips/kernel/smp.c:211:2: error: passing argument 2 of ‘cpumask_set_cpu’ discards ‘volatile’ qualifier from pointer target type [-Werror] cpumask_set_cpu(0, &cpu_callin_map); ^ In file included from ./arch/mips/include/asm/processor.h:14:0, from ./arch/mips/include/asm/thread_info.h:15, from include/linux/thread_info.h:54, from include/asm-generic/preempt.h:4, from arch/mips/include/generated/asm/preempt.h:1, from include/linux/preempt.h:18, from include/linux/interrupt.h:8, from arch/mips/kernel/smp.c:24: include/linux/cpumask.h:272:91: note: expected ‘struct cpumask *’ but argument is of type ‘volatile struct cpumask_t *’ static inline void cpumask_set_cpu(unsigned int cpu, struct cpumask *dstp) ^ arch/mips/kernel/smp.c: In function ‘__cpu_up’: arch/mips/kernel/smp.c:221:10: error: passing argument 2 of ‘cpumask_test_cpu’ discards ‘volatile’ qualifier from pointer target type [-Werror] while (!cpumask_test_cpu(cpu, &cpu_callin_map)) ^ In file included from ./arch/mips/include/asm/processor.h:14:0, from ./arch/mips/include/asm/thread_info.h:15, from include/linux/thread_info.h:54, from include/asm-generic/preempt.h:4, from arch/mips/include/generated/asm/preempt.h:1, from include/linux/preempt.h:18, from include/linux/interrupt.h:8, from arch/mips/kernel/smp.c:24: include/linux/cpumask.h:294:90: note: expected ‘const struct cpumask *’ but argument is of type ‘volatile struct cpumask_t *’ static inline int cpumask_test_cpu(int cpu, const struct cpumask *cpumask) ^ cc1: all warnings being treated as errors make[2]: *** [arch/mips/kernel/smp.o] Error 1 make[1]: *** [arch/mips/kernel] Error 2 make: *** [arch/mips] Error 2 Signed-off-by: Ralf Baechle --- arch/mips/include/asm/smp.h | 2 +- arch/mips/kernel/smp.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h index bb02fac9b4fa..2b25d1ba1ea0 100644 --- a/arch/mips/include/asm/smp.h +++ b/arch/mips/include/asm/smp.h @@ -45,7 +45,7 @@ extern int __cpu_logical_map[NR_CPUS]; #define SMP_DUMP 0x8 #define SMP_ASK_C0COUNT 0x10 -extern volatile cpumask_t cpu_callin_map; +extern cpumask_t cpu_callin_map; /* Mask of CPUs which are currently definitely operating coherently */ extern cpumask_t cpu_coherent_mask; diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 193ace7955fb..faa46ebd9dda 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -43,7 +43,7 @@ #include #include -volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */ +cpumask_t cpu_callin_map; /* Bitmask of started secondaries */ int __cpu_number_map[NR_CPUS]; /* Map physical to logical */ EXPORT_SYMBOL(__cpu_number_map); @@ -218,8 +218,10 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle) /* * Trust is futile. We should really have timeouts ... */ - while (!cpumask_test_cpu(cpu, &cpu_callin_map)) + while (!cpumask_test_cpu(cpu, &cpu_callin_map)) { udelay(100); + schedule(); + } synchronise_count_master(cpu); return 0; -- cgit v1.2.3 From 620b155034570f577470cf5309f741bac6a6e32b Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 6 May 2015 11:52:32 +0100 Subject: MIPS: fix FP mode selection in lieu of .MIPS.abiflags data Commit 46490b572544 ("MIPS: kernel: elf: Improve the overall ABI and FPU mode checks") reworked the ELF FP ABI mode selection logic, but when CONFIG_MIPS_O32_FP64_SUPPORT is enabled it breaks the use of binaries which have no PT_MIPS_ABIFLAGS program header & associated .MIPS.abiflags section. A default mode is selected based upon whether the ELF contains MIPS32 or MIPS64 code, but that selection is made in arch_elf_pt_proc. arch_elf_pt_proc only executes when a PT_MIPS_ABIFLAGS program header is found. If one is not found then arch_elf_pt_proc is never called, and no default overall_fp_mode value is selected. When arch_check_elf is called, both abi0 & abi1 are MIPS_ABI_FP_UNKNOWN which leads to both prog_req & interp_req being set to none_req. none_req matches none of the conditions for mode selection at the end of arch_check_elf, so overall_fp_mode is left untouched. Finally once mips_set_personality_fp is called the BUG() in the default case is then hit & the kernel likely panics. Fix this by moving the selection of a default overall mode to the start of arch_check_elf, which runs once per ELF executed regardless of whether it has a PT_MIPS_ABIFLAGS program header. Signed-off-by: Paul Burton Cc: Markos Chandras Cc: Matthew Fortune Cc: Ralf Baechle Cc: linux-mips@linux-mips.org Cc: stable@vger.kernel.org # v4.0+ Patchwork: http://patchwork.linux-mips.org/patch/9978/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/elf.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c index be4899f3c393..4a4d9e067c89 100644 --- a/arch/mips/kernel/elf.c +++ b/arch/mips/kernel/elf.c @@ -76,14 +76,6 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf, /* Lets see if this is an O32 ELF */ if (ehdr32->e_ident[EI_CLASS] == ELFCLASS32) { - /* FR = 1 for N32 */ - if (ehdr32->e_flags & EF_MIPS_ABI2) - state->overall_fp_mode = FP_FR1; - else - /* Set a good default FPU mode for O32 */ - state->overall_fp_mode = cpu_has_mips_r6 ? - FP_FRE : FP_FR0; - if (ehdr32->e_flags & EF_MIPS_FP64) { /* * Set MIPS_ABI_FP_OLD_64 for EF_MIPS_FP64. We will override it @@ -104,9 +96,6 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf, (char *)&abiflags, sizeof(abiflags)); } else { - /* FR=1 is really the only option for 64-bit */ - state->overall_fp_mode = FP_FR1; - if (phdr64->p_type != PT_MIPS_ABIFLAGS) return 0; if (phdr64->p_filesz < sizeof(abiflags)) @@ -137,6 +126,7 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, struct elf32_hdr *ehdr = _ehdr; struct mode_req prog_req, interp_req; int fp_abi, interp_fp_abi, abi0, abi1, max_abi; + bool is_mips64; if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT)) return 0; @@ -152,10 +142,22 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, abi0 = abi1 = fp_abi; } - /* ABI limits. O32 = FP_64A, N32/N64 = FP_SOFT */ - max_abi = ((ehdr->e_ident[EI_CLASS] == ELFCLASS32) && - (!(ehdr->e_flags & EF_MIPS_ABI2))) ? - MIPS_ABI_FP_64A : MIPS_ABI_FP_SOFT; + is_mips64 = (ehdr->e_ident[EI_CLASS] == ELFCLASS64) || + (ehdr->e_flags & EF_MIPS_ABI2); + + if (is_mips64) { + /* MIPS64 code always uses FR=1, thus the default is easy */ + state->overall_fp_mode = FP_FR1; + + /* Disallow access to the various FPXX & FP64 ABIs */ + max_abi = MIPS_ABI_FP_SOFT; + } else { + /* Default to a mode capable of running code expecting FR=0 */ + state->overall_fp_mode = cpu_has_mips_r6 ? FP_FRE : FP_FR0; + + /* Allow all ABIs we know about */ + max_abi = MIPS_ABI_FP_64A; + } if ((abi0 > max_abi && abi0 != MIPS_ABI_FP_UNKNOWN) || (abi1 > max_abi && abi1 != MIPS_ABI_FP_UNKNOWN)) -- cgit v1.2.3