Commit 5ad0ec0b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 fixes from Will Deacon:

 - Fix panic() when it occurs during secondary CPU startup

 - Fix "kpti=off" when KASLR is enabled

 - Fix howler in compat syscall table for vDSO clock_getres() fallback

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
  arm64: compat: Fix syscall number of compat_clock_getres
  arm64: kpti: Fix "kpti=off" when KASLR is enabled
  arm64: smp: fix crash_smp_send_stop() behaviour
  arm64: smp: fix smp_send_stop() behaviour
parents f014d2b8 3568b889
...@@ -29,11 +29,9 @@ typedef struct { ...@@ -29,11 +29,9 @@ typedef struct {
*/ */
#define ASID(mm) ((mm)->context.id.counter & 0xffff) #define ASID(mm) ((mm)->context.id.counter & 0xffff)
extern bool arm64_use_ng_mappings;
static inline bool arm64_kernel_unmapped_at_el0(void) static inline bool arm64_kernel_unmapped_at_el0(void)
{ {
return arm64_use_ng_mappings; return cpus_have_const_cap(ARM64_UNMAP_KERNEL_AT_EL0);
} }
typedef void (*bp_hardening_cb_t)(void); typedef void (*bp_hardening_cb_t)(void);
......
...@@ -23,11 +23,13 @@ ...@@ -23,11 +23,13 @@
#include <asm/pgtable-types.h> #include <asm/pgtable-types.h>
extern bool arm64_use_ng_mappings;
#define _PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED) #define _PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
#define _PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S) #define _PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
#define PTE_MAYBE_NG (arm64_kernel_unmapped_at_el0() ? PTE_NG : 0) #define PTE_MAYBE_NG (arm64_use_ng_mappings ? PTE_NG : 0)
#define PMD_MAYBE_NG (arm64_kernel_unmapped_at_el0() ? PMD_SECT_NG : 0) #define PMD_MAYBE_NG (arm64_use_ng_mappings ? PMD_SECT_NG : 0)
#define PROT_DEFAULT (_PROT_DEFAULT | PTE_MAYBE_NG) #define PROT_DEFAULT (_PROT_DEFAULT | PTE_MAYBE_NG)
#define PROT_SECT_DEFAULT (_PROT_SECT_DEFAULT | PMD_MAYBE_NG) #define PROT_SECT_DEFAULT (_PROT_SECT_DEFAULT | PMD_MAYBE_NG)
......
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
#define __NR_compat_gettimeofday 78 #define __NR_compat_gettimeofday 78
#define __NR_compat_sigreturn 119 #define __NR_compat_sigreturn 119
#define __NR_compat_rt_sigreturn 173 #define __NR_compat_rt_sigreturn 173
#define __NR_compat_clock_getres 247
#define __NR_compat_clock_gettime 263 #define __NR_compat_clock_gettime 263
#define __NR_compat_clock_getres 264
#define __NR_compat_clock_gettime64 403 #define __NR_compat_clock_gettime64 403
#define __NR_compat_clock_getres_time64 406 #define __NR_compat_clock_getres_time64 406
......
...@@ -958,11 +958,22 @@ void tick_broadcast(const struct cpumask *mask) ...@@ -958,11 +958,22 @@ void tick_broadcast(const struct cpumask *mask)
} }
#endif #endif
/*
* The number of CPUs online, not counting this CPU (which may not be
* fully online and so not counted in num_online_cpus()).
*/
static inline unsigned int num_other_online_cpus(void)
{
unsigned int this_cpu_online = cpu_online(smp_processor_id());
return num_online_cpus() - this_cpu_online;
}
void smp_send_stop(void) void smp_send_stop(void)
{ {
unsigned long timeout; unsigned long timeout;
if (num_online_cpus() > 1) { if (num_other_online_cpus()) {
cpumask_t mask; cpumask_t mask;
cpumask_copy(&mask, cpu_online_mask); cpumask_copy(&mask, cpu_online_mask);
...@@ -975,10 +986,10 @@ void smp_send_stop(void) ...@@ -975,10 +986,10 @@ void smp_send_stop(void)
/* Wait up to one second for other CPUs to stop */ /* Wait up to one second for other CPUs to stop */
timeout = USEC_PER_SEC; timeout = USEC_PER_SEC;
while (num_online_cpus() > 1 && timeout--) while (num_other_online_cpus() && timeout--)
udelay(1); udelay(1);
if (num_online_cpus() > 1) if (num_other_online_cpus())
pr_warn("SMP: failed to stop secondary CPUs %*pbl\n", pr_warn("SMP: failed to stop secondary CPUs %*pbl\n",
cpumask_pr_args(cpu_online_mask)); cpumask_pr_args(cpu_online_mask));
...@@ -1001,7 +1012,11 @@ void crash_smp_send_stop(void) ...@@ -1001,7 +1012,11 @@ void crash_smp_send_stop(void)
cpus_stopped = 1; cpus_stopped = 1;
if (num_online_cpus() == 1) { /*
* If this cpu is the only one alive at this point in time, online or
* not, there are no stop messages to be sent around, so just back out.
*/
if (num_other_online_cpus() == 0) {
sdei_mask_local_cpu(); sdei_mask_local_cpu();
return; return;
} }
...@@ -1009,7 +1024,7 @@ void crash_smp_send_stop(void) ...@@ -1009,7 +1024,7 @@ void crash_smp_send_stop(void)
cpumask_copy(&mask, cpu_online_mask); cpumask_copy(&mask, cpu_online_mask);
cpumask_clear_cpu(smp_processor_id(), &mask); cpumask_clear_cpu(smp_processor_id(), &mask);
atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); atomic_set(&waiting_for_crash_ipi, num_other_online_cpus());
pr_crit("SMP: stopping secondary CPUs\n"); pr_crit("SMP: stopping secondary CPUs\n");
smp_cross_call(&mask, IPI_CPU_CRASH_STOP); smp_cross_call(&mask, IPI_CPU_CRASH_STOP);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment