Skip to content

Commit

Permalink
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/arm64/linux

Pull arm64 fixes from Will Deacon:
 "Most of these are CC'd for stable, but there are a few fixing issues
  introduced during the recent merge window too.

  There's also a fix for the xgene PMU driver, but it seemed daft to
  send as a separate pull request, so I've included it here with the
  rest of the fixes.

   - Fix ACPI boot due to recent broken NUMA changes
   - Fix remote enabling of CPU features requiring PSTATE bit manipulation
   - Add address range check when emulating user cache maintenance
   - Fix LL/SC loops that allow compiler to introduce memory accesses
   - Fix recently added write_sysreg_s macro
   - Ensure MDCR_EL2 is initialised on qemu targets without a PMU
   - Avoid kaslr breakage due to MODVERSIONs and DYNAMIC_FTRACE
   - Correctly drive recent ld when building relocatable Image
   - Remove junk IS_ERR check from xgene PMU driver added during merge window
   - pr_cont fixes after core changes in the merge window"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
  arm64: remove pr_cont abuse from mem_init
  arm64: fix show_regs fallout from KERN_CONT changes
  arm64: kernel: force ET_DYN ELF type for CONFIG_RELOCATABLE=y
  arm64: suspend: Reconfigure PSTATE after resume from idle
  arm64: mm: Set PSTATE.PAN from the cpu_enable_pan() call
  arm64: cpufeature: Schedule enable() calls instead of calling them via IPI
  arm64: Cortex-A53 errata workaround: check for kernel addresses
  arm64: percpu: rewrite ll/sc loops in assembly
  arm64: swp emulation: bound LL/SC retries before rescheduling
  arm64: sysreg: Fix use of XZR in write_sysreg_s
  arm64: kaslr: keep modules close to the kernel when DYNAMIC_FTRACE=y
  arm64: kernel: Init MDCR_EL2 even in the absence of a PMU
  perf: xgene: Remove bogus IS_ERR() check
  arm64: kernel: numa: fix ACPI boot cpu numa node mapping
  arm64: kaslr: fix breakage with CONFIG_MODVERSIONS=y
  • Loading branch information
torvalds committed Oct 20, 2016
2 parents bdcff41 + f7881bd commit f4814e6
Show file tree
Hide file tree
Showing 20 changed files with 184 additions and 121 deletions.
2 changes: 1 addition & 1 deletion arch/arm64/Kconfig
Expand Up @@ -915,7 +915,7 @@ config RANDOMIZE_BASE

config RANDOMIZE_MODULE_REGION_FULL
bool "Randomize the module region independently from the core kernel"
depends on RANDOMIZE_BASE
depends on RANDOMIZE_BASE && !DYNAMIC_FTRACE
default y
help
Randomizes the location of the module region without considering the
Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/Makefile
Expand Up @@ -15,7 +15,7 @@ CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET)
GZFLAGS :=-9

ifneq ($(CONFIG_RELOCATABLE),)
LDFLAGS_vmlinux += -pie -Bsymbolic
LDFLAGS_vmlinux += -pie -shared -Bsymbolic
endif

ifeq ($(CONFIG_ARM64_ERRATUM_843419),y)
Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/include/asm/cpufeature.h
Expand Up @@ -94,7 +94,7 @@ struct arm64_cpu_capabilities {
u16 capability;
int def_scope; /* default scope */
bool (*matches)(const struct arm64_cpu_capabilities *caps, int scope);
void (*enable)(void *); /* Called on all active CPUs */
int (*enable)(void *); /* Called on all active CPUs */
union {
struct { /* To be used for erratum handling only */
u32 midr_model;
Expand Down
3 changes: 3 additions & 0 deletions arch/arm64/include/asm/exec.h
Expand Up @@ -18,6 +18,9 @@
#ifndef __ASM_EXEC_H
#define __ASM_EXEC_H

#include <linux/sched.h>

extern unsigned long arch_align_stack(unsigned long sp);
void uao_thread_switch(struct task_struct *next);

#endif /* __ASM_EXEC_H */
5 changes: 5 additions & 0 deletions arch/arm64/include/asm/module.h
Expand Up @@ -17,6 +17,7 @@
#define __ASM_MODULE_H

#include <asm-generic/module.h>
#include <asm/memory.h>

#define MODULE_ARCH_VERMAGIC "aarch64"

Expand All @@ -32,6 +33,10 @@ u64 module_emit_plt_entry(struct module *mod, const Elf64_Rela *rela,
Elf64_Sym *sym);

#ifdef CONFIG_RANDOMIZE_BASE
#ifdef CONFIG_MODVERSIONS
#define ARCH_RELOCATES_KCRCTAB
#define reloc_start (kimage_vaddr - KIMAGE_VADDR)
#endif
extern u64 module_alloc_base;
#else
#define module_alloc_base ((u64)_etext - MODULES_VSIZE)
Expand Down
120 changes: 56 additions & 64 deletions arch/arm64/include/asm/percpu.h
Expand Up @@ -44,48 +44,44 @@ static inline unsigned long __percpu_##op(void *ptr, \
\
switch (size) { \
case 1: \
do { \
asm ("//__per_cpu_" #op "_1\n" \
"ldxrb %w[ret], %[ptr]\n" \
asm ("//__per_cpu_" #op "_1\n" \
"1: ldxrb %w[ret], %[ptr]\n" \
#asm_op " %w[ret], %w[ret], %w[val]\n" \
"stxrb %w[loop], %w[ret], %[ptr]\n" \
: [loop] "=&r" (loop), [ret] "=&r" (ret), \
[ptr] "+Q"(*(u8 *)ptr) \
: [val] "Ir" (val)); \
} while (loop); \
" stxrb %w[loop], %w[ret], %[ptr]\n" \
" cbnz %w[loop], 1b" \
: [loop] "=&r" (loop), [ret] "=&r" (ret), \
[ptr] "+Q"(*(u8 *)ptr) \
: [val] "Ir" (val)); \
break; \
case 2: \
do { \
asm ("//__per_cpu_" #op "_2\n" \
"ldxrh %w[ret], %[ptr]\n" \
asm ("//__per_cpu_" #op "_2\n" \
"1: ldxrh %w[ret], %[ptr]\n" \
#asm_op " %w[ret], %w[ret], %w[val]\n" \
"stxrh %w[loop], %w[ret], %[ptr]\n" \
: [loop] "=&r" (loop), [ret] "=&r" (ret), \
[ptr] "+Q"(*(u16 *)ptr) \
: [val] "Ir" (val)); \
} while (loop); \
" stxrh %w[loop], %w[ret], %[ptr]\n" \
" cbnz %w[loop], 1b" \
: [loop] "=&r" (loop), [ret] "=&r" (ret), \
[ptr] "+Q"(*(u16 *)ptr) \
: [val] "Ir" (val)); \
break; \
case 4: \
do { \
asm ("//__per_cpu_" #op "_4\n" \
"ldxr %w[ret], %[ptr]\n" \
asm ("//__per_cpu_" #op "_4\n" \
"1: ldxr %w[ret], %[ptr]\n" \
#asm_op " %w[ret], %w[ret], %w[val]\n" \
"stxr %w[loop], %w[ret], %[ptr]\n" \
: [loop] "=&r" (loop), [ret] "=&r" (ret), \
[ptr] "+Q"(*(u32 *)ptr) \
: [val] "Ir" (val)); \
} while (loop); \
" stxr %w[loop], %w[ret], %[ptr]\n" \
" cbnz %w[loop], 1b" \
: [loop] "=&r" (loop), [ret] "=&r" (ret), \
[ptr] "+Q"(*(u32 *)ptr) \
: [val] "Ir" (val)); \
break; \
case 8: \
do { \
asm ("//__per_cpu_" #op "_8\n" \
"ldxr %[ret], %[ptr]\n" \
asm ("//__per_cpu_" #op "_8\n" \
"1: ldxr %[ret], %[ptr]\n" \
#asm_op " %[ret], %[ret], %[val]\n" \
"stxr %w[loop], %[ret], %[ptr]\n" \
: [loop] "=&r" (loop), [ret] "=&r" (ret), \
[ptr] "+Q"(*(u64 *)ptr) \
: [val] "Ir" (val)); \
} while (loop); \
" stxr %w[loop], %[ret], %[ptr]\n" \
" cbnz %w[loop], 1b" \
: [loop] "=&r" (loop), [ret] "=&r" (ret), \
[ptr] "+Q"(*(u64 *)ptr) \
: [val] "Ir" (val)); \
break; \
default: \
BUILD_BUG(); \
Expand Down Expand Up @@ -150,44 +146,40 @@ static inline unsigned long __percpu_xchg(void *ptr, unsigned long val,

switch (size) {
case 1:
do {
asm ("//__percpu_xchg_1\n"
"ldxrb %w[ret], %[ptr]\n"
"stxrb %w[loop], %w[val], %[ptr]\n"
: [loop] "=&r"(loop), [ret] "=&r"(ret),
[ptr] "+Q"(*(u8 *)ptr)
: [val] "r" (val));
} while (loop);
asm ("//__percpu_xchg_1\n"
"1: ldxrb %w[ret], %[ptr]\n"
" stxrb %w[loop], %w[val], %[ptr]\n"
" cbnz %w[loop], 1b"
: [loop] "=&r"(loop), [ret] "=&r"(ret),
[ptr] "+Q"(*(u8 *)ptr)
: [val] "r" (val));
break;
case 2:
do {
asm ("//__percpu_xchg_2\n"
"ldxrh %w[ret], %[ptr]\n"
"stxrh %w[loop], %w[val], %[ptr]\n"
: [loop] "=&r"(loop), [ret] "=&r"(ret),
[ptr] "+Q"(*(u16 *)ptr)
: [val] "r" (val));
} while (loop);
asm ("//__percpu_xchg_2\n"
"1: ldxrh %w[ret], %[ptr]\n"
" stxrh %w[loop], %w[val], %[ptr]\n"
" cbnz %w[loop], 1b"
: [loop] "=&r"(loop), [ret] "=&r"(ret),
[ptr] "+Q"(*(u16 *)ptr)
: [val] "r" (val));
break;
case 4:
do {
asm ("//__percpu_xchg_4\n"
"ldxr %w[ret], %[ptr]\n"
"stxr %w[loop], %w[val], %[ptr]\n"
: [loop] "=&r"(loop), [ret] "=&r"(ret),
[ptr] "+Q"(*(u32 *)ptr)
: [val] "r" (val));
} while (loop);
asm ("//__percpu_xchg_4\n"
"1: ldxr %w[ret], %[ptr]\n"
" stxr %w[loop], %w[val], %[ptr]\n"
" cbnz %w[loop], 1b"
: [loop] "=&r"(loop), [ret] "=&r"(ret),
[ptr] "+Q"(*(u32 *)ptr)
: [val] "r" (val));
break;
case 8:
do {
asm ("//__percpu_xchg_8\n"
"ldxr %[ret], %[ptr]\n"
"stxr %w[loop], %[val], %[ptr]\n"
: [loop] "=&r"(loop), [ret] "=&r"(ret),
[ptr] "+Q"(*(u64 *)ptr)
: [val] "r" (val));
} while (loop);
asm ("//__percpu_xchg_8\n"
"1: ldxr %[ret], %[ptr]\n"
" stxr %w[loop], %[val], %[ptr]\n"
" cbnz %w[loop], 1b"
: [loop] "=&r"(loop), [ret] "=&r"(ret),
[ptr] "+Q"(*(u64 *)ptr)
: [val] "r" (val));
break;
default:
BUILD_BUG();
Expand Down
6 changes: 3 additions & 3 deletions arch/arm64/include/asm/processor.h
Expand Up @@ -188,8 +188,8 @@ static inline void spin_lock_prefetch(const void *ptr)

#endif

void cpu_enable_pan(void *__unused);
void cpu_enable_uao(void *__unused);
void cpu_enable_cache_maint_trap(void *__unused);
int cpu_enable_pan(void *__unused);
int cpu_enable_uao(void *__unused);
int cpu_enable_cache_maint_trap(void *__unused);

#endif /* __ASM_PROCESSOR_H */
2 changes: 1 addition & 1 deletion arch/arm64/include/asm/sysreg.h
Expand Up @@ -286,7 +286,7 @@ asm(

#define write_sysreg_s(v, r) do { \
u64 __val = (u64)v; \
asm volatile("msr_s " __stringify(r) ", %0" : : "rZ" (__val)); \
asm volatile("msr_s " __stringify(r) ", %x0" : : "rZ" (__val)); \
} while (0)

static inline void config_sctlr_el1(u32 clear, u32 set)
Expand Down
8 changes: 8 additions & 0 deletions arch/arm64/include/asm/uaccess.h
Expand Up @@ -21,6 +21,7 @@
/*
* User space memory access functions
*/
#include <linux/bitops.h>
#include <linux/kasan-checks.h>
#include <linux/string.h>
#include <linux/thread_info.h>
Expand Down Expand Up @@ -102,6 +103,13 @@ static inline void set_fs(mm_segment_t fs)
flag; \
})

/*
* When dealing with data aborts or instruction traps we may end up with
* a tagged userland pointer. Clear the tag to get a sane pointer to pass
* on to access_ok(), for instance.
*/
#define untagged_addr(addr) sign_extend64(addr, 55)

#define access_ok(type, addr, size) __range_ok(addr, size)
#define user_addr_max get_fs

Expand Down
36 changes: 22 additions & 14 deletions arch/arm64/kernel/armv8_deprecated.c
Expand Up @@ -280,35 +280,43 @@ static void __init register_insn_emulation_sysctl(struct ctl_table *table)
/*
* Error-checking SWP macros implemented using ldxr{b}/stxr{b}
*/
#define __user_swpX_asm(data, addr, res, temp, B) \

/* Arbitrary constant to ensure forward-progress of the LL/SC loop */
#define __SWP_LL_SC_LOOPS 4

#define __user_swpX_asm(data, addr, res, temp, temp2, B) \
__asm__ __volatile__( \
" mov %w3, %w7\n" \
ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_HAS_PAN, \
CONFIG_ARM64_PAN) \
"0: ldxr"B" %w2, [%3]\n" \
"1: stxr"B" %w0, %w1, [%3]\n" \
"0: ldxr"B" %w2, [%4]\n" \
"1: stxr"B" %w0, %w1, [%4]\n" \
" cbz %w0, 2f\n" \
" mov %w0, %w4\n" \
" sub %w3, %w3, #1\n" \
" cbnz %w3, 0b\n" \
" mov %w0, %w5\n" \
" b 3f\n" \
"2:\n" \
" mov %w1, %w2\n" \
"3:\n" \
" .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
"4: mov %w0, %w5\n" \
"4: mov %w0, %w6\n" \
" b 3b\n" \
" .popsection" \
_ASM_EXTABLE(0b, 4b) \
_ASM_EXTABLE(1b, 4b) \
ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, \
CONFIG_ARM64_PAN) \
: "=&r" (res), "+r" (data), "=&r" (temp) \
: "r" (addr), "i" (-EAGAIN), "i" (-EFAULT) \
: "=&r" (res), "+r" (data), "=&r" (temp), "=&r" (temp2) \
: "r" (addr), "i" (-EAGAIN), "i" (-EFAULT), \
"i" (__SWP_LL_SC_LOOPS) \
: "memory")

#define __user_swp_asm(data, addr, res, temp) \
__user_swpX_asm(data, addr, res, temp, "")
#define __user_swpb_asm(data, addr, res, temp) \
__user_swpX_asm(data, addr, res, temp, "b")
#define __user_swp_asm(data, addr, res, temp, temp2) \
__user_swpX_asm(data, addr, res, temp, temp2, "")
#define __user_swpb_asm(data, addr, res, temp, temp2) \
__user_swpX_asm(data, addr, res, temp, temp2, "b")

/*
* Bit 22 of the instruction encoding distinguishes between
Expand All @@ -328,12 +336,12 @@ static int emulate_swpX(unsigned int address, unsigned int *data,
}

while (1) {
unsigned long temp;
unsigned long temp, temp2;

if (type == TYPE_SWPB)
__user_swpb_asm(*data, address, res, temp);
__user_swpb_asm(*data, address, res, temp, temp2);
else
__user_swp_asm(*data, address, res, temp);
__user_swp_asm(*data, address, res, temp, temp2);

if (likely(res != -EAGAIN) || signal_pending(current))
break;
Expand Down
3 changes: 2 additions & 1 deletion arch/arm64/kernel/cpu_errata.c
Expand Up @@ -39,10 +39,11 @@ has_mismatched_cache_line_size(const struct arm64_cpu_capabilities *entry,
(arm64_ftr_reg_ctrel0.sys_val & arm64_ftr_reg_ctrel0.strict_mask);
}

static void cpu_enable_trap_ctr_access(void *__unused)
static int cpu_enable_trap_ctr_access(void *__unused)
{
/* Clear SCTLR_EL1.UCT */
config_sctlr_el1(SCTLR_EL1_UCT, 0);
return 0;
}

#define MIDR_RANGE(model, min, max) \
Expand Down
10 changes: 9 additions & 1 deletion arch/arm64/kernel/cpufeature.c
Expand Up @@ -19,7 +19,9 @@
#define pr_fmt(fmt) "CPU features: " fmt

#include <linux/bsearch.h>
#include <linux/cpumask.h>
#include <linux/sort.h>
#include <linux/stop_machine.h>
#include <linux/types.h>
#include <asm/cpu.h>
#include <asm/cpufeature.h>
Expand Down Expand Up @@ -941,7 +943,13 @@ void __init enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps)
{
for (; caps->matches; caps++)
if (caps->enable && cpus_have_cap(caps->capability))
on_each_cpu(caps->enable, NULL, true);
/*
* Use stop_machine() as it schedules the work allowing
* us to modify PSTATE, instead of on_each_cpu() which
* uses an IPI, giving us a PSTATE that disappears when
* we return.
*/
stop_machine(caps->enable, NULL, cpu_online_mask);
}

/*
Expand Down
3 changes: 2 additions & 1 deletion arch/arm64/kernel/head.S
Expand Up @@ -586,8 +586,9 @@ CPU_LE( movk x0, #0x30d0, lsl #16 ) // Clear EE and E0E on LE systems
b.lt 4f // Skip if no PMU present
mrs x0, pmcr_el0 // Disable debug access traps
ubfx x0, x0, #11, #5 // to EL2 and allow access to
msr mdcr_el2, x0 // all PMU counters from EL1
4:
csel x0, xzr, x0, lt // all PMU counters from EL1
msr mdcr_el2, x0 // (if they exist)

/* Stage-2 translation */
msr vttbr_el2, xzr
Expand Down

0 comments on commit f4814e6

Please sign in to comment.