2005-04-16 15:20:36 -07:00
|
|
|
/*
|
2008-08-02 10:55:55 +01:00
|
|
|
* arch/arm/include/asm/processor.h
|
2005-04-16 15:20:36 -07:00
|
|
|
*
|
|
|
|
* Copyright (C) 1995-1999 Russell King
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
|
|
* published by the Free Software Foundation.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __ASM_ARM_PROCESSOR_H
|
|
|
|
#define __ASM_ARM_PROCESSOR_H
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Default implementation of macro that returns current
|
|
|
|
* instruction pointer ("program counter").
|
|
|
|
*/
|
|
|
|
#define current_text_addr() ({ __label__ _l; _l: &&_l;})
|
|
|
|
|
|
|
|
#ifdef __KERNEL__
|
|
|
|
|
2010-09-03 10:42:55 +01:00
|
|
|
#include <asm/hw_breakpoint.h>
|
2005-04-16 15:20:36 -07:00
|
|
|
#include <asm/ptrace.h>
|
|
|
|
#include <asm/types.h>
|
2013-07-02 12:10:42 +01:00
|
|
|
#include <asm/unified.h>
|
2005-04-16 15:20:36 -07:00
|
|
|
|
2008-02-08 04:19:26 -08:00
|
|
|
#ifdef __KERNEL__
|
2008-12-05 03:25:47 +01:00
|
|
|
#define STACK_TOP ((current->personality & ADDR_LIMIT_32BIT) ? \
|
2008-02-08 04:19:26 -08:00
|
|
|
TASK_SIZE : TASK_SIZE_26)
|
|
|
|
#define STACK_TOP_MAX TASK_SIZE
|
|
|
|
#endif
|
|
|
|
|
2005-04-16 15:20:36 -07:00
|
|
|
struct debug_info {
|
2010-09-03 10:42:55 +01:00
|
|
|
#ifdef CONFIG_HAVE_HW_BREAKPOINT
|
|
|
|
struct perf_event *hbp[ARM_MAX_HBP_SLOTS];
|
|
|
|
#endif
|
2005-04-16 15:20:36 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
struct thread_struct {
|
|
|
|
/* fault info */
|
|
|
|
unsigned long address;
|
|
|
|
unsigned long trap_no;
|
|
|
|
unsigned long error_code;
|
|
|
|
/* debugging */
|
|
|
|
struct debug_info debug;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define INIT_THREAD { }
|
|
|
|
|
2006-01-13 21:04:17 +00:00
|
|
|
#ifdef CONFIG_MMU
|
|
|
|
#define nommu_start_thread(regs) do { } while (0)
|
|
|
|
#else
|
|
|
|
#define nommu_start_thread(regs) regs->ARM_r10 = current->mm->start_data
|
|
|
|
#endif
|
|
|
|
|
2005-04-16 15:20:36 -07:00
|
|
|
#define start_thread(regs,pc,sp) \
|
|
|
|
({ \
|
2008-10-27 11:24:09 +00:00
|
|
|
memset(regs->uregs, 0, sizeof(regs->uregs)); \
|
2005-04-16 15:20:36 -07:00
|
|
|
if (current->personality & ADDR_LIMIT_32BIT) \
|
|
|
|
regs->ARM_cpsr = USR_MODE; \
|
|
|
|
else \
|
|
|
|
regs->ARM_cpsr = USR26_MODE; \
|
|
|
|
if (elf_hwcap & HWCAP_THUMB && pc & 1) \
|
|
|
|
regs->ARM_cpsr |= PSR_T_BIT; \
|
2009-05-30 14:00:18 +01:00
|
|
|
regs->ARM_cpsr |= PSR_ENDSTATE; \
|
2005-04-16 15:20:36 -07:00
|
|
|
regs->ARM_pc = pc & ~1; /* pc */ \
|
|
|
|
regs->ARM_sp = sp; /* sp */ \
|
2006-01-13 21:04:17 +00:00
|
|
|
nommu_start_thread(regs); \
|
2005-04-16 15:20:36 -07:00
|
|
|
})
|
|
|
|
|
|
|
|
/* Forward declaration, a strange C thing */
|
|
|
|
struct task_struct;
|
|
|
|
|
|
|
|
/* Free all resources held by a thread. */
|
|
|
|
extern void release_thread(struct task_struct *);
|
|
|
|
|
|
|
|
unsigned long get_wchan(struct task_struct *p);
|
|
|
|
|
2011-03-04 12:38:54 +01:00
|
|
|
#if __LINUX_ARM_ARCH__ == 6 || defined(CONFIG_ARM_ERRATA_754327)
|
ARM: avoid Cortex-A9 livelock on tight dmb loops
[ Upstream commit 5388a5b82199facacd3d7ac0d05aca6e8f902fed ]
machine_crash_nonpanic_core() does this:
while (1)
cpu_relax();
because the kernel has crashed, and we have no known safe way to deal
with the CPU. So, we place the CPU into an infinite loop which we
expect it to never exit - at least not until the system as a whole is
reset by some method.
In the absence of erratum 754327, this code assembles to:
b .
In other words, an infinite loop. When erratum 754327 is enabled,
this becomes:
1: dmb
b 1b
It has been observed that on some systems (eg, OMAP4) where, if a
crash is triggered, the system tries to kexec into the panic kernel,
but fails after taking the secondary CPU down - placing it into one
of these loops. This causes the system to livelock, and the most
noticable effect is the system stops after issuing:
Loading crashdump kernel...
to the system console.
The tested as working solution I came up with was to add wfe() to
these infinite loops thusly:
while (1) {
cpu_relax();
wfe();
}
which, without 754327 builds to:
1: wfe
b 1b
or with 754327 is enabled:
1: dmb
wfe
b 1b
Adding "wfe" does two things depending on the environment we're running
under:
- where we're running on bare metal, and the processor implements
"wfe", it stops us spinning endlessly in a loop where we're never
going to do any useful work.
- if we're running in a VM, it allows the CPU to be given back to the
hypervisor and rescheduled for other purposes (maybe a different VM)
rather than wasting CPU cycles inside a crashed VM.
However, in light of erratum 794072, Will Deacon wanted to see 10 nops
as well - which is reasonable to cover the case where we have erratum
754327 enabled _and_ we have a processor that doesn't implement the
wfe hint.
So, we now end up with:
1: wfe
b 1b
when erratum 754327 is disabled, or:
1: dmb
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
wfe
b 1b
when erratum 754327 is enabled. We also get the dmb + 10 nop
sequence elsewhere in the kernel, in terminating loops.
This is reasonable - it means we get the workaround for erratum
794072 when erratum 754327 is enabled, but still relinquish the dead
processor - either by placing it in a lower power mode when wfe is
implemented as such or by returning it to the hypervisior, or in the
case where wfe is a no-op, we use the workaround specified in erratum
794072 to avoid the problem.
These as two entirely orthogonal problems - the 10 nops addresses
erratum 794072, and the wfe is an optimisation that makes the system
more efficient when crashed either in terms of power consumption or
by allowing the host/other VMs to make use of the CPU.
I don't see any reason not to use kexec() inside a VM - it has the
potential to provide automated recovery from a failure of the VMs
kernel with the opportunity for saving a crashdump of the failure.
A panic() with a reboot timeout won't do that, and reading the
libvirt documentation, setting on_reboot to "preserve" won't either
(the documentation states "The preserve action for an on_reboot event
is treated as a destroy".) Surely it has to be a good thing to
avoiding having CPUs spinning inside a VM that is doing no useful
work.
Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2018-04-10 11:35:36 +01:00
|
|
|
#define cpu_relax() \
|
|
|
|
do { \
|
|
|
|
smp_mb(); \
|
|
|
|
__asm__ __volatile__("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"); \
|
|
|
|
} while (0)
|
2010-06-21 15:29:03 +01:00
|
|
|
#else
|
2005-04-16 15:20:36 -07:00
|
|
|
#define cpu_relax() barrier()
|
2010-06-21 15:29:03 +01:00
|
|
|
#endif
|
2005-04-16 15:20:36 -07:00
|
|
|
|
arch, locking: Ciao arch_mutex_cpu_relax()
The arch_mutex_cpu_relax() function, introduced by 34b133f, is
hacky and ugly. It was added a few years ago to address the fact
that common cpu_relax() calls include yielding on s390, and thus
impact the optimistic spinning functionality of mutexes. Nowadays
we use this function well beyond mutexes: rwsem, qrwlock, mcs and
lockref. Since the macro that defines the call is in the mutex header,
any users must include mutex.h and the naming is misleading as well.
This patch (i) renames the call to cpu_relax_lowlatency ("relax, but
only if you can do it with very low latency") and (ii) defines it in
each arch's asm/processor.h local header, just like for regular cpu_relax
functions. On all archs, except s390, cpu_relax_lowlatency is simply cpu_relax,
and thus we can take it out of mutex.h. While this can seem redundant,
I believe it is a good choice as it allows us to move out arch specific
logic from generic locking primitives and enables future(?) archs to
transparently define it, similarly to System Z.
Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Anton Blanchard <anton@samba.org>
Cc: Aurelien Jacquiot <a-jacquiot@ti.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Bharat Bhushan <r65777@freescale.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Chen Liqin <liqin.linux@gmail.com>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Chris Zankel <chris@zankel.net>
Cc: David Howells <dhowells@redhat.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
Cc: Dominik Dingel <dingel@linux.vnet.ibm.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Guan Xuetao <gxt@mprc.pku.edu.cn>
Cc: Haavard Skinnemoen <hskinnemoen@gmail.com>
Cc: Hans-Christian Egtvedt <egtvedt@samfundet.no>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Helge Deller <deller@gmx.de>
Cc: Hirokazu Takata <takata@linux-m32r.org>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: James E.J. Bottomley <jejb@parisc-linux.org>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Joe Perches <joe@perches.com>
Cc: Jonas Bonn <jonas@southpole.se>
Cc: Joseph Myers <joseph@codesourcery.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Koichi Yasutake <yasutake.koichi@jp.panasonic.com>
Cc: Lennox Wu <lennox.wu@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mark Salter <msalter@redhat.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: Michael Neuling <mikey@neuling.org>
Cc: Michal Simek <monstr@monstr.eu>
Cc: Mikael Starvik <starvik@axis.com>
Cc: Nicolas Pitre <nico@linaro.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Qais Yousef <qais.yousef@imgtec.com>
Cc: Qiaowei Ren <qiaowei.ren@intel.com>
Cc: Rafael Wysocki <rafael.j.wysocki@intel.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Richard Kuo <rkuo@codeaurora.org>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Steven Miao <realmz6@gmail.com>
Cc: Steven Rostedt <srostedt@redhat.com>
Cc: Stratos Karafotis <stratosk@semaphore.gr>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Vasily Kulikov <segoon@openwall.com>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: Vineet Gupta <Vineet.Gupta1@synopsys.com>
Cc: Waiman Long <Waiman.Long@hp.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Wolfram Sang <wsa@the-dreams.de>
Cc: adi-buildroot-devel@lists.sourceforge.net
Cc: linux390@de.ibm.com
Cc: linux-alpha@vger.kernel.org
Cc: linux-am33-list@redhat.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-c6x-dev@linux-c6x.org
Cc: linux-cris-kernel@axis.com
Cc: linux-hexagon@vger.kernel.org
Cc: linux-ia64@vger.kernel.org
Cc: linux@lists.openrisc.net
Cc: linux-m32r-ja@ml.linux-m32r.org
Cc: linux-m32r@ml.linux-m32r.org
Cc: linux-m68k@lists.linux-m68k.org
Cc: linux-metag@vger.kernel.org
Cc: linux-mips@linux-mips.org
Cc: linux-parisc@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-s390@vger.kernel.org
Cc: linux-sh@vger.kernel.org
Cc: linux-xtensa@linux-xtensa.org
Cc: sparclinux@vger.kernel.org
Link: http://lkml.kernel.org/r/1404079773.2619.4.camel@buesod1.americas.hpqcorp.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2014-06-29 15:09:33 -07:00
|
|
|
#define cpu_relax_lowlatency() cpu_relax()
|
|
|
|
|
2006-01-12 01:05:57 -08:00
|
|
|
#define task_pt_regs(p) \
|
2006-01-12 01:05:58 -08:00
|
|
|
((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
|
2006-01-12 01:05:57 -08:00
|
|
|
|
|
|
|
#define KSTK_EIP(tsk) task_pt_regs(tsk)->ARM_pc
|
|
|
|
#define KSTK_ESP(tsk) task_pt_regs(tsk)->ARM_sp
|
2005-04-16 15:20:36 -07:00
|
|
|
|
2013-07-02 12:10:42 +01:00
|
|
|
#ifdef CONFIG_SMP
|
|
|
|
#define __ALT_SMP_ASM(smp, up) \
|
|
|
|
"9998: " smp "\n" \
|
|
|
|
" .pushsection \".alt.smp.init\", \"a\"\n" \
|
|
|
|
" .long 9998b\n" \
|
|
|
|
" " up "\n" \
|
|
|
|
" .popsection\n"
|
|
|
|
#else
|
|
|
|
#define __ALT_SMP_ASM(smp, up) up
|
|
|
|
#endif
|
|
|
|
|
2005-04-16 15:20:36 -07:00
|
|
|
/*
|
|
|
|
* Prefetching support - only ARMv5.
|
|
|
|
*/
|
|
|
|
#if __LINUX_ARM_ARCH__ >= 5
|
|
|
|
|
|
|
|
#define ARCH_HAS_PREFETCH
|
2006-12-13 18:39:26 +01:00
|
|
|
static inline void prefetch(const void *ptr)
|
|
|
|
{
|
|
|
|
__asm__ __volatile__(
|
2008-08-12 22:10:59 +01:00
|
|
|
"pld\t%a0"
|
2013-06-26 16:47:35 +01:00
|
|
|
:: "p" (ptr));
|
2006-12-13 18:39:26 +01:00
|
|
|
}
|
2005-04-16 15:20:36 -07:00
|
|
|
|
2013-06-26 17:03:40 +01:00
|
|
|
#if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
|
2005-04-16 15:20:36 -07:00
|
|
|
#define ARCH_HAS_PREFETCHW
|
2013-06-26 17:03:40 +01:00
|
|
|
static inline void prefetchw(const void *ptr)
|
|
|
|
{
|
|
|
|
__asm__ __volatile__(
|
|
|
|
".arch_extension mp\n"
|
|
|
|
__ALT_SMP_ASM(
|
|
|
|
WASM(pldw) "\t%a0",
|
|
|
|
WASM(pld) "\t%a0"
|
|
|
|
)
|
|
|
|
:: "p" (ptr));
|
|
|
|
}
|
|
|
|
#endif
|
2005-04-16 15:20:36 -07:00
|
|
|
#endif
|
|
|
|
|
2011-11-22 04:01:07 +01:00
|
|
|
#define HAVE_ARCH_PICK_MMAP_LAYOUT
|
|
|
|
|
2005-04-16 15:20:36 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif /* __ASM_ARM_PROCESSOR_H */
|