linux/arch/arm64/kernel
Arun Chandran 5e05153144 arm64: convert part of soft_restart() to assembly
The current soft_restart() and setup_restart implementations incorrectly
assume that compiler will not spill/fill values to/from stack. However
this assumption seems to be wrong, revealed by the disassembly of the
currently existing code (v3.16) built with Linaro GCC 4.9-2014.05.

ffffffc000085224 <soft_restart>:
ffffffc000085224:  a9be7bfd  stp    x29, x30, [sp,#-32]!
ffffffc000085228:  910003fd  mov    x29, sp
ffffffc00008522c:  f9000fa0  str    x0, [x29,#24]
ffffffc000085230:  94003d21  bl     ffffffc0000946b4 <setup_mm_for_reboot>
ffffffc000085234:  94003b33  bl     ffffffc000093f00 <flush_cache_all>
ffffffc000085238:  94003dfa  bl     ffffffc000094a20 <cpu_cache_off>
ffffffc00008523c:  94003b31  bl     ffffffc000093f00 <flush_cache_all>
ffffffc000085240:  b0003321  adrp   x1, ffffffc0006ea000 <reset_devices>

ffffffc000085244:  f9400fa0  ldr    x0, [x29,#24] ----> spilled addr
ffffffc000085248:  f942fc22  ldr    x2, [x1,#1528] ----> global memstart_addr

ffffffc00008524c:  f0000061  adrp   x1, ffffffc000094000 <__inval_cache_range+0x40>
ffffffc000085250:  91290021  add    x1, x1, #0xa40
ffffffc000085254:  8b010041  add    x1, x2, x1
ffffffc000085258:  d2c00802  mov    x2, #0x4000000000           // #274877906944
ffffffc00008525c:  8b020021  add    x1, x1, x2
ffffffc000085260:  d63f0020  blr    x1
...

Here the compiler generates memory accesses after the cache is disabled,
loading stale values for the spilled value and global variable. As we cannot
control when the compiler will access memory we must rewrite the
functions in assembly to stash values we need in registers prior to
disabling the cache, avoiding the use of memory.

Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Arun Chandran <achandran@mvista.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
2014-09-08 14:39:18 +01:00
..
vdso arm64: vdso: fix build error when switching from LE to BE 2014-07-30 15:06:35 +01:00
.gitignore arm64: Build infrastructure 2012-09-17 13:42:21 +01:00
arm64ksyms.c arm64: Add ftrace support 2014-05-29 09:08:08 +01:00
asm-offsets.c arm64: KVM: implement lazy world switch for debug registers 2014-07-11 04:57:46 -07:00
cpu_ops.c arm64: kernel: enable PSCI cpu operations on UP systems 2014-07-18 15:23:25 +01:00
cpuinfo.c arm64: don't flag non-aliasing VIPT I-caches as aliasing 2014-09-08 14:39:18 +01:00
cputable.c arm64: add CPU_HOTPLUG infrastructure 2013-10-25 11:33:21 +01:00
debug-monitors.c KVM/ARM New features for 3.17 include: 2014-08-05 09:47:45 +02:00
efi-entry.S arm64: fix el2_setup check of CurrentEL 2014-07-04 16:16:52 +01:00
efi-stub.c arm64/efi: efistub: don't abort if base of DRAM is occupied 2014-09-08 14:39:18 +01:00
efi.c Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2014-08-24 16:17:41 -07:00
entry-fpsimd.S arm64: fpsimd: fix a typo in fpsimd_save_partial_state ENDPROC 2014-07-31 11:42:42 +01:00
entry-ftrace.S arm64, ftrace: Remove check of obsolete variable function_trace_stop 2014-07-18 13:58:10 -04:00
entry.S arm64: Add __NR_* definitions for compat syscalls 2014-07-10 11:02:40 +01:00
fpsimd.c arm64: fix bug for reloading FPSIMD state after cpu power off 2014-09-01 12:55:21 +01:00
ftrace.c arm64: ftrace: Add dynamic ftrace support 2014-05-29 09:08:33 +01:00
head.S arm64/efi: efistub: cover entire static mem footprint in PE/COFF .text 2014-09-08 14:39:18 +01:00
hw_breakpoint.c arm64: is_compat_task is defined both in asm/compat.h and linux/compat.h 2014-05-12 16:43:29 +01:00
hyp-stub.S irqchip: gic-v3: Initial support for GICv3 2014-07-08 22:11:47 +00:00
image.h arm64: Update the Image header 2014-07-10 12:36:40 +01:00
insn.c arm64: introduce aarch64_insn_gen_{nop|branch_imm}() helper functions 2014-01-08 15:21:29 +00:00
io.c arm64: Device specific operations 2012-09-17 13:42:04 +01:00
irq.c arm64: use cpu_online_mask when using forced irq_set_affinity 2014-05-12 16:25:07 +01:00
jump_label.c arm64, jump label: optimize jump label implementation 2014-01-08 15:23:53 +00:00
kgdb.c arm64: KGDB: Add step debugging support 2014-02-26 11:16:25 +00:00
kuser32.S arm64: Add __NR_* definitions for compat syscalls 2014-07-10 11:02:40 +01:00
Makefile Merge branch 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2014-08-04 17:13:50 -07:00
module.c arm64: move encode_insn_immediate() from module.c to insn.c 2014-01-08 15:21:29 +00:00
perf_event.c arm64: fix !CONFIG_COMPAT build failures 2014-04-06 23:25:04 +01:00
perf_regs.c arm64: perf: don't rely on layout of pt_regs when grabbing sp or pc 2014-08-28 20:01:50 +01:00
process.c arm64: convert part of soft_restart() to assembly 2014-09-08 14:39:18 +01:00
psci.c arm64: kernel: add __init marker to PSCI init functions 2014-07-18 15:23:45 +01:00
ptrace.c arm64: ptrace: fix compat reg getter/setter return values 2014-08-28 20:01:42 +01:00
return_address.c arm64: ftrace: Add CALLER_ADDRx macros 2014-05-29 09:08:33 +01:00
setup.c Revert "arm64: cpuinfo: print info for all CPUs" 2014-09-01 15:55:22 +01:00
signal32.c Merge branch 'signal-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/misc 2014-08-09 09:58:12 -07:00
signal.c arm64: Use sigsp() 2014-08-06 13:03:45 +02:00
sleep.S arm64: kernel: cpu_{suspend/resume} implementation 2013-12-16 17:17:31 +00:00
smp_spin_table.c arm64: spin-table: handle unmapped cpu-release-addrs 2014-09-08 14:39:18 +01:00
smp.c Nicolas Pitre added generic tracepoints for tracing IPIs and updated the 2014-08-09 17:33:44 -07:00
stacktrace.c arm64: Add 'notrace' attribute to unwind_frame() for ftrace 2014-05-29 09:04:31 +01:00
suspend.c arm64: kernel: add missing __init section marker to cpu_suspend_init 2014-07-18 15:23:59 +01:00
sys32.S arm64: compat: correct register concatenation for syscall wrappers 2013-10-25 15:59:36 +01:00
sys_compat.c arm64: Add __NR_* definitions for compat syscalls 2014-07-10 11:02:40 +01:00
sys.c arm64: switch to generic sigaltstack 2013-02-14 09:17:29 -05:00
time.c arm64: kernel: initialize broadcast hrtimer based clock event device 2014-05-30 17:48:13 +01:00
topology.c arm64: topology: add MPIDR-based detection 2014-07-09 12:22:40 +01:00
traps.c arm64: mm: Implement 4 levels of translation tables 2014-07-23 15:27:40 +01:00
vdso.c arm64,ia64,ppc,s390,sh,tile,um,x86,mm: remove default gate area 2014-08-08 15:57:27 -07:00
vmlinux.lds.S arm64: Enable TEXT_OFFSET fuzzing 2014-07-10 12:36:58 +01:00