aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-20 18:40:44 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-20 18:40:44 -0500
commit82b51734b4f228c76b6064b6e899d9d3d4c17c1a (patch)
tree0f8735944ab146713dba402261b4c7cc5629d02f /arch/arm64/include
parent15c81026204da897a05424c79263aea861a782cc (diff)
parent883c057367014d20a14b5054e4eb0d81ce3bea5c (diff)
Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull ARM64 updates from Catalin Marinas: - CPU suspend support on top of PSCI (firmware Power State Coordination Interface) - jump label support - CMA can now be enabled on arm64 - HWCAP bits for crypto and CRC32 extensions - optimised percpu using tpidr_el1 register - code cleanup * tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (42 commits) arm64: fix typo in entry.S arm64: kernel: restore HW breakpoint registers in cpu_suspend jump_label: use defined macros instead of hard-coding for better readability arm64, jump label: optimize jump label implementation arm64, jump label: detect %c support for ARM64 arm64: introduce aarch64_insn_gen_{nop|branch_imm}() helper functions arm64: move encode_insn_immediate() from module.c to insn.c arm64: introduce interfaces to hotpatch kernel and module code arm64: introduce basic aarch64 instruction decoding helpers arm64: dts: Reduce size of virtio block device for foundation model arm64: Remove unused __data_loc variable arm64: Enable CMA arm64: Warn on NULL device structure for dma APIs arm64: Add hwcaps for crypto and CRC32 extensions. arm64: drop redundant macros from read_cpuid() arm64: Remove outdated comment arm64: cmpxchg: update macros to prevent warnings arm64: support single-step and breakpoint handler hooks ARM64: fix framepointer check in unwind_frame ARM64: check stack pointer in get_wchan ...
Diffstat (limited to 'arch/arm64/include')
-rw-r--r--arch/arm64/include/asm/Kbuild1
-rw-r--r--arch/arm64/include/asm/cmpxchg.h28
-rw-r--r--arch/arm64/include/asm/cpu_ops.h6
-rw-r--r--arch/arm64/include/asm/cputype.h28
-rw-r--r--arch/arm64/include/asm/debug-monitors.h21
-rw-r--r--arch/arm64/include/asm/dma-contiguous.h29
-rw-r--r--arch/arm64/include/asm/futex.h1
-rw-r--r--arch/arm64/include/asm/hardirq.h2
-rw-r--r--arch/arm64/include/asm/insn.h108
-rw-r--r--arch/arm64/include/asm/jump_label.h52
-rw-r--r--arch/arm64/include/asm/memory.h3
-rw-r--r--arch/arm64/include/asm/percpu.h41
-rw-r--r--arch/arm64/include/asm/proc-fns.h3
-rw-r--r--arch/arm64/include/asm/smp_plat.h13
-rw-r--r--arch/arm64/include/asm/suspend.h27
-rw-r--r--arch/arm64/include/asm/uaccess.h25
-rw-r--r--arch/arm64/include/asm/word-at-a-time.h94
-rw-r--r--arch/arm64/include/uapi/asm/hwcap.h6
18 files changed, 437 insertions, 51 deletions
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index 519f89f5b6a3..d0ff25de67ca 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -26,7 +26,6 @@ generic-y += mman.h
26generic-y += msgbuf.h 26generic-y += msgbuf.h
27generic-y += mutex.h 27generic-y += mutex.h
28generic-y += pci.h 28generic-y += pci.h
29generic-y += percpu.h
30generic-y += poll.h 29generic-y += poll.h
31generic-y += posix_types.h 30generic-y += posix_types.h
32generic-y += resource.h 31generic-y += resource.h
diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h
index 3914c0dcd09c..56166d7f4a25 100644
--- a/arch/arm64/include/asm/cmpxchg.h
+++ b/arch/arm64/include/asm/cmpxchg.h
@@ -158,17 +158,23 @@ static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old,
158 return ret; 158 return ret;
159} 159}
160 160
161#define cmpxchg(ptr,o,n) \ 161#define cmpxchg(ptr, o, n) \
162 ((__typeof__(*(ptr)))__cmpxchg_mb((ptr), \ 162({ \
163 (unsigned long)(o), \ 163 __typeof__(*(ptr)) __ret; \
164 (unsigned long)(n), \ 164 __ret = (__typeof__(*(ptr))) \
165 sizeof(*(ptr)))) 165 __cmpxchg_mb((ptr), (unsigned long)(o), (unsigned long)(n), \
166 166 sizeof(*(ptr))); \
167#define cmpxchg_local(ptr,o,n) \ 167 __ret; \
168 ((__typeof__(*(ptr)))__cmpxchg((ptr), \ 168})
169 (unsigned long)(o), \ 169
170 (unsigned long)(n), \ 170#define cmpxchg_local(ptr, o, n) \
171 sizeof(*(ptr)))) 171({ \
172 __typeof__(*(ptr)) __ret; \
173 __ret = (__typeof__(*(ptr))) \
174 __cmpxchg((ptr), (unsigned long)(o), \
175 (unsigned long)(n), sizeof(*(ptr))); \
176 __ret; \
177})
172 178
173#define cmpxchg64(ptr,o,n) cmpxchg((ptr),(o),(n)) 179#define cmpxchg64(ptr,o,n) cmpxchg((ptr),(o),(n))
174#define cmpxchg64_local(ptr,o,n) cmpxchg_local((ptr),(o),(n)) 180#define cmpxchg64_local(ptr,o,n) cmpxchg_local((ptr),(o),(n))
diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h
index c4cdb5e5b73d..152413076503 100644
--- a/arch/arm64/include/asm/cpu_ops.h
+++ b/arch/arm64/include/asm/cpu_ops.h
@@ -39,6 +39,9 @@ struct device_node;
39 * from the cpu to be killed. 39 * from the cpu to be killed.
40 * @cpu_die: Makes a cpu leave the kernel. Must not fail. Called from the 40 * @cpu_die: Makes a cpu leave the kernel. Must not fail. Called from the
41 * cpu being killed. 41 * cpu being killed.
42 * @cpu_suspend: Suspends a cpu and saves the required context. May fail owing
43 * to wrong parameters or error conditions. Called from the
44 * CPU being suspended. Must be called with IRQs disabled.
42 */ 45 */
43struct cpu_operations { 46struct cpu_operations {
44 const char *name; 47 const char *name;
@@ -50,6 +53,9 @@ struct cpu_operations {
50 int (*cpu_disable)(unsigned int cpu); 53 int (*cpu_disable)(unsigned int cpu);
51 void (*cpu_die)(unsigned int cpu); 54 void (*cpu_die)(unsigned int cpu);
52#endif 55#endif
56#ifdef CONFIG_ARM64_CPU_SUSPEND
57 int (*cpu_suspend)(unsigned long);
58#endif
53}; 59};
54 60
55extern const struct cpu_operations *cpu_ops[NR_CPUS]; 61extern const struct cpu_operations *cpu_ops[NR_CPUS];
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 5fe138e0b828..c404fb0df3a6 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -16,23 +16,23 @@
16#ifndef __ASM_CPUTYPE_H 16#ifndef __ASM_CPUTYPE_H
17#define __ASM_CPUTYPE_H 17#define __ASM_CPUTYPE_H
18 18
19#define ID_MIDR_EL1 "midr_el1"
20#define ID_MPIDR_EL1 "mpidr_el1"
21#define ID_CTR_EL0 "ctr_el0"
22
23#define ID_AA64PFR0_EL1 "id_aa64pfr0_el1"
24#define ID_AA64DFR0_EL1 "id_aa64dfr0_el1"
25#define ID_AA64AFR0_EL1 "id_aa64afr0_el1"
26#define ID_AA64ISAR0_EL1 "id_aa64isar0_el1"
27#define ID_AA64MMFR0_EL1 "id_aa64mmfr0_el1"
28
29#define INVALID_HWID ULONG_MAX 19#define INVALID_HWID ULONG_MAX
30 20
31#define MPIDR_HWID_BITMASK 0xff00ffffff 21#define MPIDR_HWID_BITMASK 0xff00ffffff
32 22
23#define MPIDR_LEVEL_BITS_SHIFT 3
24#define MPIDR_LEVEL_BITS (1 << MPIDR_LEVEL_BITS_SHIFT)
25#define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
26
27#define MPIDR_LEVEL_SHIFT(level) \
28 (((1 << level) >> 1) << MPIDR_LEVEL_BITS_SHIFT)
29
30#define MPIDR_AFFINITY_LEVEL(mpidr, level) \
31 ((mpidr >> MPIDR_LEVEL_SHIFT(level)) & MPIDR_LEVEL_MASK)
32
33#define read_cpuid(reg) ({ \ 33#define read_cpuid(reg) ({ \
34 u64 __val; \ 34 u64 __val; \
35 asm("mrs %0, " reg : "=r" (__val)); \ 35 asm("mrs %0, " #reg : "=r" (__val)); \
36 __val; \ 36 __val; \
37}) 37})
38 38
@@ -54,12 +54,12 @@
54 */ 54 */
55static inline u32 __attribute_const__ read_cpuid_id(void) 55static inline u32 __attribute_const__ read_cpuid_id(void)
56{ 56{
57 return read_cpuid(ID_MIDR_EL1); 57 return read_cpuid(MIDR_EL1);
58} 58}
59 59
60static inline u64 __attribute_const__ read_cpuid_mpidr(void) 60static inline u64 __attribute_const__ read_cpuid_mpidr(void)
61{ 61{
62 return read_cpuid(ID_MPIDR_EL1); 62 return read_cpuid(MPIDR_EL1);
63} 63}
64 64
65static inline unsigned int __attribute_const__ read_cpuid_implementor(void) 65static inline unsigned int __attribute_const__ read_cpuid_implementor(void)
@@ -74,7 +74,7 @@ static inline unsigned int __attribute_const__ read_cpuid_part_number(void)
74 74
75static inline u32 __attribute_const__ read_cpuid_cachetype(void) 75static inline u32 __attribute_const__ read_cpuid_cachetype(void)
76{ 76{
77 return read_cpuid(ID_CTR_EL0); 77 return read_cpuid(CTR_EL0);
78} 78}
79 79
80#endif /* __ASSEMBLY__ */ 80#endif /* __ASSEMBLY__ */
diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h
index a2232d07be9d..62314791570c 100644
--- a/arch/arm64/include/asm/debug-monitors.h
+++ b/arch/arm64/include/asm/debug-monitors.h
@@ -62,6 +62,27 @@ struct task_struct;
62 62
63#define DBG_ARCH_ID_RESERVED 0 /* In case of ptrace ABI updates. */ 63#define DBG_ARCH_ID_RESERVED 0 /* In case of ptrace ABI updates. */
64 64
65#define DBG_HOOK_HANDLED 0
66#define DBG_HOOK_ERROR 1
67
68struct step_hook {
69 struct list_head node;
70 int (*fn)(struct pt_regs *regs, unsigned int esr);
71};
72
73void register_step_hook(struct step_hook *hook);
74void unregister_step_hook(struct step_hook *hook);
75
76struct break_hook {
77 struct list_head node;
78 u32 esr_val;
79 u32 esr_mask;
80 int (*fn)(struct pt_regs *regs, unsigned int esr);
81};
82
83void register_break_hook(struct break_hook *hook);
84void unregister_break_hook(struct break_hook *hook);
85
65u8 debug_monitors_arch(void); 86u8 debug_monitors_arch(void);
66 87
67void enable_debug_monitors(enum debug_el el); 88void enable_debug_monitors(enum debug_el el);
diff --git a/arch/arm64/include/asm/dma-contiguous.h b/arch/arm64/include/asm/dma-contiguous.h
new file mode 100644
index 000000000000..d6aacb61ff4a
--- /dev/null
+++ b/arch/arm64/include/asm/dma-contiguous.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#ifndef _ASM_DMA_CONTIGUOUS_H
15#define _ASM_DMA_CONTIGUOUS_H
16
17#ifdef __KERNEL__
18#ifdef CONFIG_DMA_CMA
19
20#include <linux/types.h>
21#include <asm-generic/dma-contiguous.h>
22
23static inline void
24dma_contiguous_early_fixup(phys_addr_t base, unsigned long size) { }
25
26#endif
27#endif
28
29#endif
diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h
index c582fa316366..78cc3aba5d69 100644
--- a/arch/arm64/include/asm/futex.h
+++ b/arch/arm64/include/asm/futex.h
@@ -30,6 +30,7 @@
30" cbnz %w3, 1b\n" \ 30" cbnz %w3, 1b\n" \
31"3:\n" \ 31"3:\n" \
32" .pushsection .fixup,\"ax\"\n" \ 32" .pushsection .fixup,\"ax\"\n" \
33" .align 2\n" \
33"4: mov %w0, %w5\n" \ 34"4: mov %w0, %w5\n" \
34" b 3b\n" \ 35" b 3b\n" \
35" .popsection\n" \ 36" .popsection\n" \
diff --git a/arch/arm64/include/asm/hardirq.h b/arch/arm64/include/asm/hardirq.h
index 990c051e7829..ae4801d77514 100644
--- a/arch/arm64/include/asm/hardirq.h
+++ b/arch/arm64/include/asm/hardirq.h
@@ -20,7 +20,7 @@
20#include <linux/threads.h> 20#include <linux/threads.h>
21#include <asm/irq.h> 21#include <asm/irq.h>
22 22
23#define NR_IPI 4 23#define NR_IPI 5
24 24
25typedef struct { 25typedef struct {
26 unsigned int __softirq_pending; 26 unsigned int __softirq_pending;
diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
new file mode 100644
index 000000000000..c44ad39ed310
--- /dev/null
+++ b/arch/arm64/include/asm/insn.h
@@ -0,0 +1,108 @@
1/*
2 * Copyright (C) 2013 Huawei Ltd.
3 * Author: Jiang Liu <liuj97@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17#ifndef __ASM_INSN_H
18#define __ASM_INSN_H
19#include <linux/types.h>
20
21/* A64 instructions are always 32 bits. */
22#define AARCH64_INSN_SIZE 4
23
24/*
25 * ARM Architecture Reference Manual for ARMv8 Profile-A, Issue A.a
26 * Section C3.1 "A64 instruction index by encoding":
27 * AArch64 main encoding table
28 * Bit position
29 * 28 27 26 25 Encoding Group
30 * 0 0 - - Unallocated
31 * 1 0 0 - Data processing, immediate
32 * 1 0 1 - Branch, exception generation and system instructions
33 * - 1 - 0 Loads and stores
34 * - 1 0 1 Data processing - register
35 * 0 1 1 1 Data processing - SIMD and floating point
36 * 1 1 1 1 Data processing - SIMD and floating point
37 * "-" means "don't care"
38 */
39enum aarch64_insn_encoding_class {
40 AARCH64_INSN_CLS_UNKNOWN, /* UNALLOCATED */
41 AARCH64_INSN_CLS_DP_IMM, /* Data processing - immediate */
42 AARCH64_INSN_CLS_DP_REG, /* Data processing - register */
43 AARCH64_INSN_CLS_DP_FPSIMD, /* Data processing - SIMD and FP */
44 AARCH64_INSN_CLS_LDST, /* Loads and stores */
45 AARCH64_INSN_CLS_BR_SYS, /* Branch, exception generation and
46 * system instructions */
47};
48
49enum aarch64_insn_hint_op {
50 AARCH64_INSN_HINT_NOP = 0x0 << 5,
51 AARCH64_INSN_HINT_YIELD = 0x1 << 5,
52 AARCH64_INSN_HINT_WFE = 0x2 << 5,
53 AARCH64_INSN_HINT_WFI = 0x3 << 5,
54 AARCH64_INSN_HINT_SEV = 0x4 << 5,
55 AARCH64_INSN_HINT_SEVL = 0x5 << 5,
56};
57
58enum aarch64_insn_imm_type {
59 AARCH64_INSN_IMM_ADR,
60 AARCH64_INSN_IMM_26,
61 AARCH64_INSN_IMM_19,
62 AARCH64_INSN_IMM_16,
63 AARCH64_INSN_IMM_14,
64 AARCH64_INSN_IMM_12,
65 AARCH64_INSN_IMM_9,
66 AARCH64_INSN_IMM_MAX
67};
68
69enum aarch64_insn_branch_type {
70 AARCH64_INSN_BRANCH_NOLINK,
71 AARCH64_INSN_BRANCH_LINK,
72};
73
74#define __AARCH64_INSN_FUNCS(abbr, mask, val) \
75static __always_inline bool aarch64_insn_is_##abbr(u32 code) \
76{ return (code & (mask)) == (val); } \
77static __always_inline u32 aarch64_insn_get_##abbr##_value(void) \
78{ return (val); }
79
80__AARCH64_INSN_FUNCS(b, 0xFC000000, 0x14000000)
81__AARCH64_INSN_FUNCS(bl, 0xFC000000, 0x94000000)
82__AARCH64_INSN_FUNCS(svc, 0xFFE0001F, 0xD4000001)
83__AARCH64_INSN_FUNCS(hvc, 0xFFE0001F, 0xD4000002)
84__AARCH64_INSN_FUNCS(smc, 0xFFE0001F, 0xD4000003)
85__AARCH64_INSN_FUNCS(brk, 0xFFE0001F, 0xD4200000)
86__AARCH64_INSN_FUNCS(hint, 0xFFFFF01F, 0xD503201F)
87
88#undef __AARCH64_INSN_FUNCS
89
90bool aarch64_insn_is_nop(u32 insn);
91
92int aarch64_insn_read(void *addr, u32 *insnp);
93int aarch64_insn_write(void *addr, u32 insn);
94enum aarch64_insn_encoding_class aarch64_get_insn_class(u32 insn);
95u32 aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
96 u32 insn, u64 imm);
97u32 aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr,
98 enum aarch64_insn_branch_type type);
99u32 aarch64_insn_gen_hint(enum aarch64_insn_hint_op op);
100u32 aarch64_insn_gen_nop(void);
101
102bool aarch64_insn_hotpatch_safe(u32 old_insn, u32 new_insn);
103
104int aarch64_insn_patch_text_nosync(void *addr, u32 insn);
105int aarch64_insn_patch_text_sync(void *addrs[], u32 insns[], int cnt);
106int aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt);
107
108#endif /* __ASM_INSN_H */
diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
new file mode 100644
index 000000000000..076a1c714049
--- /dev/null
+++ b/arch/arm64/include/asm/jump_label.h
@@ -0,0 +1,52 @@
1/*
2 * Copyright (C) 2013 Huawei Ltd.
3 * Author: Jiang Liu <liuj97@gmail.com>
4 *
5 * Based on arch/arm/include/asm/jump_label.h
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef __ASM_JUMP_LABEL_H
20#define __ASM_JUMP_LABEL_H
21#include <linux/types.h>
22#include <asm/insn.h>
23
24#ifdef __KERNEL__
25
26#define JUMP_LABEL_NOP_SIZE AARCH64_INSN_SIZE
27
28static __always_inline bool arch_static_branch(struct static_key *key)
29{
30 asm goto("1: nop\n\t"
31 ".pushsection __jump_table, \"aw\"\n\t"
32 ".align 3\n\t"
33 ".quad 1b, %l[l_yes], %c0\n\t"
34 ".popsection\n\t"
35 : : "i"(key) : : l_yes);
36
37 return false;
38l_yes:
39 return true;
40}
41
42#endif /* __KERNEL__ */
43
44typedef u64 jump_label_t;
45
46struct jump_entry {
47 jump_label_t code;
48 jump_label_t target;
49 jump_label_t key;
50};
51
52#endif /* __ASM_JUMP_LABEL_H */
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 37762175896f..9dc5dc39fded 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -146,8 +146,7 @@ static inline void *phys_to_virt(phys_addr_t x)
146#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET 146#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET
147 147
148#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) 148#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
149#define virt_addr_valid(kaddr) (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \ 149#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
150 ((void *)(kaddr) < (void *)high_memory))
151 150
152#endif 151#endif
153 152
diff --git a/arch/arm64/include/asm/percpu.h b/arch/arm64/include/asm/percpu.h
new file mode 100644
index 000000000000..13fb0b3efc5f
--- /dev/null
+++ b/arch/arm64/include/asm/percpu.h
@@ -0,0 +1,41 @@
1/*
2 * Copyright (C) 2013 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_PERCPU_H
17#define __ASM_PERCPU_H
18
19static inline void set_my_cpu_offset(unsigned long off)
20{
21 asm volatile("msr tpidr_el1, %0" :: "r" (off) : "memory");
22}
23
24static inline unsigned long __my_cpu_offset(void)
25{
26 unsigned long off;
27 register unsigned long *sp asm ("sp");
28
29 /*
30 * We want to allow caching the value, so avoid using volatile and
31 * instead use a fake stack read to hazard against barrier().
32 */
33 asm("mrs %0, tpidr_el1" : "=r" (off) : "Q" (*sp));
34
35 return off;
36}
37#define __my_cpu_offset __my_cpu_offset()
38
39#include <asm-generic/percpu.h>
40
41#endif /* __ASM_PERCPU_H */
diff --git a/arch/arm64/include/asm/proc-fns.h b/arch/arm64/include/asm/proc-fns.h
index 7cdf466fd0c5..0c657bb54597 100644
--- a/arch/arm64/include/asm/proc-fns.h
+++ b/arch/arm64/include/asm/proc-fns.h
@@ -26,11 +26,14 @@
26#include <asm/page.h> 26#include <asm/page.h>
27 27
28struct mm_struct; 28struct mm_struct;
29struct cpu_suspend_ctx;
29 30
30extern void cpu_cache_off(void); 31extern void cpu_cache_off(void);
31extern void cpu_do_idle(void); 32extern void cpu_do_idle(void);
32extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm); 33extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
33extern void cpu_reset(unsigned long addr) __attribute__((noreturn)); 34extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
35extern void cpu_do_suspend(struct cpu_suspend_ctx *ptr);
36extern u64 cpu_do_resume(phys_addr_t ptr, u64 idmap_ttbr);
34 37
35#include <asm/memory.h> 38#include <asm/memory.h>
36 39
diff --git a/arch/arm64/include/asm/smp_plat.h b/arch/arm64/include/asm/smp_plat.h
index ed43a0d2b1b2..59e282311b58 100644
--- a/arch/arm64/include/asm/smp_plat.h
+++ b/arch/arm64/include/asm/smp_plat.h
@@ -21,6 +21,19 @@
21 21
22#include <asm/types.h> 22#include <asm/types.h>
23 23
24struct mpidr_hash {
25 u64 mask;
26 u32 shift_aff[4];
27 u32 bits;
28};
29
30extern struct mpidr_hash mpidr_hash;
31
32static inline u32 mpidr_hash_size(void)
33{
34 return 1 << mpidr_hash.bits;
35}
36
24/* 37/*
25 * Logical CPU mapping. 38 * Logical CPU mapping.
26 */ 39 */
diff --git a/arch/arm64/include/asm/suspend.h b/arch/arm64/include/asm/suspend.h
new file mode 100644
index 000000000000..e9c149c042e0
--- /dev/null
+++ b/arch/arm64/include/asm/suspend.h
@@ -0,0 +1,27 @@
1#ifndef __ASM_SUSPEND_H
2#define __ASM_SUSPEND_H
3
4#define NR_CTX_REGS 11
5
6/*
7 * struct cpu_suspend_ctx must be 16-byte aligned since it is allocated on
8 * the stack, which must be 16-byte aligned on v8
9 */
10struct cpu_suspend_ctx {
11 /*
12 * This struct must be kept in sync with
13 * cpu_do_{suspend/resume} in mm/proc.S
14 */
15 u64 ctx_regs[NR_CTX_REGS];
16 u64 sp;
17} __aligned(16);
18
19struct sleep_save_sp {
20 phys_addr_t *save_ptr_stash;
21 phys_addr_t save_ptr_stash_phys;
22};
23
24extern void cpu_resume(void);
25extern int cpu_suspend(unsigned long);
26
27#endif
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
index 7ecc2b23882e..6c0f684aca81 100644
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -100,6 +100,7 @@ static inline void set_fs(mm_segment_t fs)
100}) 100})
101 101
102#define access_ok(type, addr, size) __range_ok(addr, size) 102#define access_ok(type, addr, size) __range_ok(addr, size)
103#define user_addr_max get_fs
103 104
104/* 105/*
105 * The "__xxx" versions of the user access functions do not verify the address 106 * The "__xxx" versions of the user access functions do not verify the address
@@ -240,9 +241,6 @@ extern unsigned long __must_check __copy_to_user(void __user *to, const void *fr
240extern unsigned long __must_check __copy_in_user(void __user *to, const void __user *from, unsigned long n); 241extern unsigned long __must_check __copy_in_user(void __user *to, const void __user *from, unsigned long n);
241extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n); 242extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n);
242 243
243extern unsigned long __must_check __strncpy_from_user(char *to, const char __user *from, unsigned long count);
244extern unsigned long __must_check __strnlen_user(const char __user *s, long n);
245
246static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n) 244static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
247{ 245{
248 if (access_ok(VERIFY_READ, from, n)) 246 if (access_ok(VERIFY_READ, from, n))
@@ -276,24 +274,9 @@ static inline unsigned long __must_check clear_user(void __user *to, unsigned lo
276 return n; 274 return n;
277} 275}
278 276
279static inline long __must_check strncpy_from_user(char *dst, const char __user *src, long count) 277extern long strncpy_from_user(char *dest, const char __user *src, long count);
280{
281 long res = -EFAULT;
282 if (access_ok(VERIFY_READ, src, 1))
283 res = __strncpy_from_user(dst, src, count);
284 return res;
285}
286
287#define strlen_user(s) strnlen_user(s, ~0UL >> 1)
288 278
289static inline long __must_check strnlen_user(const char __user *s, long n) 279extern __must_check long strlen_user(const char __user *str);
290{ 280extern __must_check long strnlen_user(const char __user *str, long n);
291 unsigned long res = 0;
292
293 if (__addr_ok(s))
294 res = __strnlen_user(s, n);
295
296 return res;
297}
298 281
299#endif /* __ASM_UACCESS_H */ 282#endif /* __ASM_UACCESS_H */
diff --git a/arch/arm64/include/asm/word-at-a-time.h b/arch/arm64/include/asm/word-at-a-time.h
new file mode 100644
index 000000000000..aab5bf09e9d9
--- /dev/null
+++ b/arch/arm64/include/asm/word-at-a-time.h
@@ -0,0 +1,94 @@
1/*
2 * Copyright (C) 2013 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_WORD_AT_A_TIME_H
17#define __ASM_WORD_AT_A_TIME_H
18
19#ifndef __AARCH64EB__
20
21#include <linux/kernel.h>
22
23struct word_at_a_time {
24 const unsigned long one_bits, high_bits;
25};
26
27#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) }
28
29static inline unsigned long has_zero(unsigned long a, unsigned long *bits,
30 const struct word_at_a_time *c)
31{
32 unsigned long mask = ((a - c->one_bits) & ~a) & c->high_bits;
33 *bits = mask;
34 return mask;
35}
36
37#define prep_zero_mask(a, bits, c) (bits)
38
39static inline unsigned long create_zero_mask(unsigned long bits)
40{
41 bits = (bits - 1) & ~bits;
42 return bits >> 7;
43}
44
45static inline unsigned long find_zero(unsigned long mask)
46{
47 return fls64(mask) >> 3;
48}
49
50#define zero_bytemask(mask) (mask)
51
52#else /* __AARCH64EB__ */
53#include <asm-generic/word-at-a-time.h>
54#endif
55
56/*
57 * Load an unaligned word from kernel space.
58 *
59 * In the (very unlikely) case of the word being a page-crosser
60 * and the next page not being mapped, take the exception and
61 * return zeroes in the non-existing part.
62 */
63static inline unsigned long load_unaligned_zeropad(const void *addr)
64{
65 unsigned long ret, offset;
66
67 /* Load word from unaligned pointer addr */
68 asm(
69 "1: ldr %0, %3\n"
70 "2:\n"
71 " .pushsection .fixup,\"ax\"\n"
72 " .align 2\n"
73 "3: and %1, %2, #0x7\n"
74 " bic %2, %2, #0x7\n"
75 " ldr %0, [%2]\n"
76 " lsl %1, %1, #0x3\n"
77#ifndef __AARCH64EB__
78 " lsr %0, %0, %1\n"
79#else
80 " lsl %0, %0, %1\n"
81#endif
82 " b 2b\n"
83 " .popsection\n"
84 " .pushsection __ex_table,\"a\"\n"
85 " .align 3\n"
86 " .quad 1b, 3b\n"
87 " .popsection"
88 : "=&r" (ret), "=&r" (offset)
89 : "r" (addr), "Q" (*(unsigned long *)addr));
90
91 return ret;
92}
93
94#endif /* __ASM_WORD_AT_A_TIME_H */
diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h
index 9b12476e9c85..73cf0f54d57c 100644
--- a/arch/arm64/include/uapi/asm/hwcap.h
+++ b/arch/arm64/include/uapi/asm/hwcap.h
@@ -22,6 +22,10 @@
22#define HWCAP_FP (1 << 0) 22#define HWCAP_FP (1 << 0)
23#define HWCAP_ASIMD (1 << 1) 23#define HWCAP_ASIMD (1 << 1)
24#define HWCAP_EVTSTRM (1 << 2) 24#define HWCAP_EVTSTRM (1 << 2)
25 25#define HWCAP_AES (1 << 3)
26#define HWCAP_PMULL (1 << 4)
27#define HWCAP_SHA1 (1 << 5)
28#define HWCAP_SHA2 (1 << 6)
29#define HWCAP_CRC32 (1 << 7)
26 30
27#endif /* _UAPI__ASM_HWCAP_H */ 31#endif /* _UAPI__ASM_HWCAP_H */