From: David Long <dave.long@linaro.org>
To: stable@vger.kernel.org,
Russell King - ARM Linux <linux@armlinux.org.uk>,
Florian Fainelli <f.fainelli@gmail.com>,
Julien Thierry <julien.thierry@arm.com>,
Tony Lindgren <tony@atomide.com>,
Marc Zyngier <marc.zyngier@arm.com>,
Mark Rutland <mark.rutland@arm.com>
Cc: Greg KH <gregkh@linuxfoundation.org>, Mark Brown <broonie@kernel.org>
Subject: [PATCH 4.14 15/17] ARM: spectre-v2: per-CPU vtables to work around big.Little systems
Date: Thu, 10 Jan 2019 12:51:48 -0500 [thread overview]
Message-ID: <20190110175150.5239-16-dave.long@linaro.org> (raw)
In-Reply-To: <20190110175150.5239-1-dave.long@linaro.org>
From: Russell King <rmk+kernel@armlinux.org.uk>
Commit 383fb3ee8024d596f488d2dbaf45e572897acbdb upstream.
In big.Little systems, some CPUs require the Spectre workarounds in
paths such as the context switch, but other CPUs do not. In order
to handle these differences, we need per-CPU vtables.
We are unable to use the kernel's per-CPU variables to support this
as per-CPU is not initialised at times when we need access to the
vtables, so we have to use an array indexed by logical CPU number.
We use an array-of-pointers to avoid having function pointers in
the kernel's read/write .data section.
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: David A. Long <dave.long@linaro.org>
---
arch/arm/include/asm/proc-fns.h | 23 +++++++++++++++++++++++
arch/arm/kernel/setup.c | 5 +++++
arch/arm/kernel/smp.c | 31 +++++++++++++++++++++++++++++++
arch/arm/mm/proc-v7-bugs.c | 17 ++---------------
4 files changed, 61 insertions(+), 15 deletions(-)
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index c259cc49c641..e1b6f280ab08 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -104,12 +104,35 @@ extern void cpu_do_resume(void *);
#else
extern struct processor processor;
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+#include <linux/smp.h>
+/*
+ * This can't be a per-cpu variable because we need to access it before
+ * per-cpu has been initialised. We have a couple of functions that are
+ * called in a pre-emptible context, and so can't use smp_processor_id()
+ * there, hence PROC_TABLE(). We insist in init_proc_vtable() that the
+ * function pointers for these are identical across all CPUs.
+ */
+extern struct processor *cpu_vtable[];
+#define PROC_VTABLE(f) cpu_vtable[smp_processor_id()]->f
+#define PROC_TABLE(f) cpu_vtable[0]->f
+static inline void init_proc_vtable(const struct processor *p)
+{
+ unsigned int cpu = smp_processor_id();
+ *cpu_vtable[cpu] = *p;
+ WARN_ON_ONCE(cpu_vtable[cpu]->dcache_clean_area !=
+ cpu_vtable[0]->dcache_clean_area);
+ WARN_ON_ONCE(cpu_vtable[cpu]->set_pte_ext !=
+ cpu_vtable[0]->set_pte_ext);
+}
+#else
#define PROC_VTABLE(f) processor.f
#define PROC_TABLE(f) processor.f
static inline void init_proc_vtable(const struct processor *p)
{
processor = *p;
}
+#endif
#define cpu_proc_init PROC_VTABLE(_proc_init)
#define cpu_check_bugs PROC_VTABLE(check_bugs)
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index c1588e31aa83..a6d27284105a 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -115,6 +115,11 @@ EXPORT_SYMBOL(elf_hwcap2);
#ifdef MULTI_CPU
struct processor processor __ro_after_init;
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+struct processor *cpu_vtable[NR_CPUS] = {
+ [0] = &processor,
+};
+#endif
#endif
#ifdef MULTI_TLB
struct cpu_tlb_fns cpu_tlb __ro_after_init;
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index e61af0600133..f6b1c9d2e178 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -42,6 +42,7 @@
#include <asm/mmu_context.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
+#include <asm/procinfo.h>
#include <asm/processor.h>
#include <asm/sections.h>
#include <asm/tlbflush.h>
@@ -102,6 +103,30 @@ static unsigned long get_arch_pgd(pgd_t *pgd)
#endif
}
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+static int secondary_biglittle_prepare(unsigned int cpu)
+{
+ if (!cpu_vtable[cpu])
+ cpu_vtable[cpu] = kzalloc(sizeof(*cpu_vtable[cpu]), GFP_KERNEL);
+
+ return cpu_vtable[cpu] ? 0 : -ENOMEM;
+}
+
+static void secondary_biglittle_init(void)
+{
+ init_proc_vtable(lookup_processor(read_cpuid_id())->proc);
+}
+#else
+static int secondary_biglittle_prepare(unsigned int cpu)
+{
+ return 0;
+}
+
+static void secondary_biglittle_init(void)
+{
+}
+#endif
+
int __cpu_up(unsigned int cpu, struct task_struct *idle)
{
int ret;
@@ -109,6 +134,10 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
if (!smp_ops.smp_boot_secondary)
return -ENOSYS;
+ ret = secondary_biglittle_prepare(cpu);
+ if (ret)
+ return ret;
+
/*
* We need to tell the secondary core where to find
* its stack and the page tables.
@@ -360,6 +389,8 @@ asmlinkage void secondary_start_kernel(void)
struct mm_struct *mm = &init_mm;
unsigned int cpu;
+ secondary_biglittle_init();
+
/*
* The identity mapping is uncached (strongly ordered), so
* switch away from it before attempting any exclusive accesses.
diff --git a/arch/arm/mm/proc-v7-bugs.c b/arch/arm/mm/proc-v7-bugs.c
index 5544b82a2e7a..9a07916af8dd 100644
--- a/arch/arm/mm/proc-v7-bugs.c
+++ b/arch/arm/mm/proc-v7-bugs.c
@@ -52,8 +52,6 @@ static void cpu_v7_spectre_init(void)
case ARM_CPU_PART_CORTEX_A17:
case ARM_CPU_PART_CORTEX_A73:
case ARM_CPU_PART_CORTEX_A75:
- if (processor.switch_mm != cpu_v7_bpiall_switch_mm)
- goto bl_error;
per_cpu(harden_branch_predictor_fn, cpu) =
harden_branch_predictor_bpiall;
spectre_v2_method = "BPIALL";
@@ -61,8 +59,6 @@ static void cpu_v7_spectre_init(void)
case ARM_CPU_PART_CORTEX_A15:
case ARM_CPU_PART_BRAHMA_B15:
- if (processor.switch_mm != cpu_v7_iciallu_switch_mm)
- goto bl_error;
per_cpu(harden_branch_predictor_fn, cpu) =
harden_branch_predictor_iciallu;
spectre_v2_method = "ICIALLU";
@@ -88,11 +84,9 @@ static void cpu_v7_spectre_init(void)
ARM_SMCCC_ARCH_WORKAROUND_1, &res);
if ((int)res.a0 != 0)
break;
- if (processor.switch_mm != cpu_v7_hvc_switch_mm && cpu)
- goto bl_error;
per_cpu(harden_branch_predictor_fn, cpu) =
call_hvc_arch_workaround_1;
- processor.switch_mm = cpu_v7_hvc_switch_mm;
+ cpu_do_switch_mm = cpu_v7_hvc_switch_mm;
spectre_v2_method = "hypervisor";
break;
@@ -101,11 +95,9 @@ static void cpu_v7_spectre_init(void)
ARM_SMCCC_ARCH_WORKAROUND_1, &res);
if ((int)res.a0 != 0)
break;
- if (processor.switch_mm != cpu_v7_smc_switch_mm && cpu)
- goto bl_error;
per_cpu(harden_branch_predictor_fn, cpu) =
call_smc_arch_workaround_1;
- processor.switch_mm = cpu_v7_smc_switch_mm;
+ cpu_do_switch_mm = cpu_v7_smc_switch_mm;
spectre_v2_method = "firmware";
break;
@@ -119,11 +111,6 @@ static void cpu_v7_spectre_init(void)
if (spectre_v2_method)
pr_info("CPU%u: Spectre v2: using %s workaround\n",
smp_processor_id(), spectre_v2_method);
- return;
-
-bl_error:
- pr_err("CPU%u: Spectre v2: incorrect context switching function, system vulnerable\n",
- cpu);
}
#else
static void cpu_v7_spectre_init(void)
--
2.17.1
next prev parent reply other threads:[~2019-01-10 17:52 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-01-10 17:51 [PATCH 4.14 00/17] V4.14 backport of more 32-bit arm spectre patches David Long
2019-01-10 17:51 ` [PATCH 4.14 01/17] ARM: 8789/1: signal: copy registers using __copy_to_user() David Long
2019-01-10 17:51 ` [PATCH 4.14 02/17] ARM: 8790/1: signal: always use __copy_to_user to save iwmmxt context David Long
2019-01-10 17:51 ` [PATCH 4.14 03/17] ARM: 8791/1: vfp: use __copy_to_user() when saving VFP state David Long
2019-01-10 17:51 ` [PATCH 4.14 04/17] ARM: 8792/1: oabi-compat: copy oabi events using __copy_to_user() David Long
2019-01-10 17:51 ` [PATCH 4.14 05/17] ARM: 8793/1: signal: replace __put_user_error with __put_user David Long
2019-01-10 17:51 ` [PATCH 4.14 06/17] ARM: 8794/1: uaccess: Prevent speculative use of the current addr_limit David Long
2019-01-10 17:51 ` [PATCH 4.14 07/17] ARM: 8795/1: spectre-v1.1: use put_user() for __put_user() David Long
2019-01-10 17:51 ` [PATCH 4.14 08/17] ARM: 8796/1: spectre-v1,v1.1: provide helpers for address sanitization David Long
2019-01-10 17:51 ` [PATCH 4.14 09/17] ARM: 8797/1: spectre-v1.1: harden __copy_to_user David Long
2019-01-10 17:51 ` [PATCH 4.14 10/17] ARM: 8810/1: vfp: Fix wrong assignement to ufp_exc David Long
2019-01-10 17:51 ` [PATCH 4.14 11/17] ARM: make lookup_processor_type() non-__init David Long
2019-01-10 17:51 ` [PATCH 4.14 12/17] ARM: split out processor lookup David Long
2019-01-10 17:51 ` [PATCH 4.14 13/17] ARM: clean up per-processor check_bugs method call David Long
2019-01-10 17:51 ` [PATCH 4.14 14/17] ARM: add PROC_VTABLE and PROC_TABLE macros David Long
2019-01-10 17:51 ` David Long [this message]
2019-01-10 17:51 ` [PATCH 4.14 16/17] ARM: ensure that processor vtables is not lost after boot David Long
2019-01-10 17:51 ` [PATCH 4.14 17/17] ARM: fix the cockup in the previous patch David Long
2019-01-15 15:45 ` [PATCH 4.14 00/17] V4.14 backport of more 32-bit arm spectre patches Greg KH
2019-01-15 16:07 ` David Long
2019-01-15 16:30 ` Greg KH
2019-01-15 16:39 ` David Long
2019-01-15 17:06 ` Russell King - ARM Linux admin
2019-01-15 17:19 ` Greg KH
2019-01-16 19:27 ` David Long
2019-01-16 19:33 ` Greg KH
2019-01-16 19:40 ` David Long
2019-01-16 19:48 ` Greg KH
2019-01-16 19:49 ` Russell King - ARM Linux admin
2019-01-18 16:07 ` Greg KH
2019-01-18 20:24 ` David Long
2019-01-19 8:08 ` Greg KH
2019-01-19 9:56 ` Russell King - ARM Linux admin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190110175150.5239-16-dave.long@linaro.org \
--to=dave.long@linaro.org \
--cc=broonie@kernel.org \
--cc=f.fainelli@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=julien.thierry@arm.com \
--cc=linux@armlinux.org.uk \
--cc=marc.zyngier@arm.com \
--cc=mark.rutland@arm.com \
--cc=stable@vger.kernel.org \
--cc=tony@atomide.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).