diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-20 18:40:44 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-20 18:40:44 -0500 |
commit | 82b51734b4f228c76b6064b6e899d9d3d4c17c1a (patch) | |
tree | 0f8735944ab146713dba402261b4c7cc5629d02f /arch/arm64/include | |
parent | 15c81026204da897a05424c79263aea861a782cc (diff) | |
parent | 883c057367014d20a14b5054e4eb0d81ce3bea5c (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/Kbuild | 1 | ||||
-rw-r--r-- | arch/arm64/include/asm/cmpxchg.h | 28 | ||||
-rw-r--r-- | arch/arm64/include/asm/cpu_ops.h | 6 | ||||
-rw-r--r-- | arch/arm64/include/asm/cputype.h | 28 | ||||
-rw-r--r-- | arch/arm64/include/asm/debug-monitors.h | 21 | ||||
-rw-r--r-- | arch/arm64/include/asm/dma-contiguous.h | 29 | ||||
-rw-r--r-- | arch/arm64/include/asm/futex.h | 1 | ||||
-rw-r--r-- | arch/arm64/include/asm/hardirq.h | 2 | ||||
-rw-r--r-- | arch/arm64/include/asm/insn.h | 108 | ||||
-rw-r--r-- | arch/arm64/include/asm/jump_label.h | 52 | ||||
-rw-r--r-- | arch/arm64/include/asm/memory.h | 3 | ||||
-rw-r--r-- | arch/arm64/include/asm/percpu.h | 41 | ||||
-rw-r--r-- | arch/arm64/include/asm/proc-fns.h | 3 | ||||
-rw-r--r-- | arch/arm64/include/asm/smp_plat.h | 13 | ||||
-rw-r--r-- | arch/arm64/include/asm/suspend.h | 27 | ||||
-rw-r--r-- | arch/arm64/include/asm/uaccess.h | 25 | ||||
-rw-r--r-- | arch/arm64/include/asm/word-at-a-time.h | 94 | ||||
-rw-r--r-- | arch/arm64/include/uapi/asm/hwcap.h | 6 |
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 | |||
26 | generic-y += msgbuf.h | 26 | generic-y += msgbuf.h |
27 | generic-y += mutex.h | 27 | generic-y += mutex.h |
28 | generic-y += pci.h | 28 | generic-y += pci.h |
29 | generic-y += percpu.h | ||
30 | generic-y += poll.h | 29 | generic-y += poll.h |
31 | generic-y += posix_types.h | 30 | generic-y += posix_types.h |
32 | generic-y += resource.h | 31 | generic-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 | */ |
43 | struct cpu_operations { | 46 | struct 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 | ||
55 | extern const struct cpu_operations *cpu_ops[NR_CPUS]; | 61 | extern 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 | */ |
55 | static inline u32 __attribute_const__ read_cpuid_id(void) | 55 | static 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 | ||
60 | static inline u64 __attribute_const__ read_cpuid_mpidr(void) | 60 | static 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 | ||
65 | static inline unsigned int __attribute_const__ read_cpuid_implementor(void) | 65 | static 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 | ||
75 | static inline u32 __attribute_const__ read_cpuid_cachetype(void) | 75 | static 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 | |||
68 | struct step_hook { | ||
69 | struct list_head node; | ||
70 | int (*fn)(struct pt_regs *regs, unsigned int esr); | ||
71 | }; | ||
72 | |||
73 | void register_step_hook(struct step_hook *hook); | ||
74 | void unregister_step_hook(struct step_hook *hook); | ||
75 | |||
76 | struct 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 | |||
83 | void register_break_hook(struct break_hook *hook); | ||
84 | void unregister_break_hook(struct break_hook *hook); | ||
85 | |||
65 | u8 debug_monitors_arch(void); | 86 | u8 debug_monitors_arch(void); |
66 | 87 | ||
67 | void enable_debug_monitors(enum debug_el el); | 88 | void 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 | |||
23 | static inline void | ||
24 | dma_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 | ||
25 | typedef struct { | 25 | typedef 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 | */ | ||
39 | enum 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 | |||
49 | enum 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 | |||
58 | enum 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 | |||
69 | enum aarch64_insn_branch_type { | ||
70 | AARCH64_INSN_BRANCH_NOLINK, | ||
71 | AARCH64_INSN_BRANCH_LINK, | ||
72 | }; | ||
73 | |||
74 | #define __AARCH64_INSN_FUNCS(abbr, mask, val) \ | ||
75 | static __always_inline bool aarch64_insn_is_##abbr(u32 code) \ | ||
76 | { return (code & (mask)) == (val); } \ | ||
77 | static __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 | |||
90 | bool aarch64_insn_is_nop(u32 insn); | ||
91 | |||
92 | int aarch64_insn_read(void *addr, u32 *insnp); | ||
93 | int aarch64_insn_write(void *addr, u32 insn); | ||
94 | enum aarch64_insn_encoding_class aarch64_get_insn_class(u32 insn); | ||
95 | u32 aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, | ||
96 | u32 insn, u64 imm); | ||
97 | u32 aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr, | ||
98 | enum aarch64_insn_branch_type type); | ||
99 | u32 aarch64_insn_gen_hint(enum aarch64_insn_hint_op op); | ||
100 | u32 aarch64_insn_gen_nop(void); | ||
101 | |||
102 | bool aarch64_insn_hotpatch_safe(u32 old_insn, u32 new_insn); | ||
103 | |||
104 | int aarch64_insn_patch_text_nosync(void *addr, u32 insn); | ||
105 | int aarch64_insn_patch_text_sync(void *addrs[], u32 insns[], int cnt); | ||
106 | int 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 | |||
28 | static __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; | ||
38 | l_yes: | ||
39 | return true; | ||
40 | } | ||
41 | |||
42 | #endif /* __KERNEL__ */ | ||
43 | |||
44 | typedef u64 jump_label_t; | ||
45 | |||
46 | struct 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 | |||
19 | static inline void set_my_cpu_offset(unsigned long off) | ||
20 | { | ||
21 | asm volatile("msr tpidr_el1, %0" :: "r" (off) : "memory"); | ||
22 | } | ||
23 | |||
24 | static 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 | ||
28 | struct mm_struct; | 28 | struct mm_struct; |
29 | struct cpu_suspend_ctx; | ||
29 | 30 | ||
30 | extern void cpu_cache_off(void); | 31 | extern void cpu_cache_off(void); |
31 | extern void cpu_do_idle(void); | 32 | extern void cpu_do_idle(void); |
32 | extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm); | 33 | extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm); |
33 | extern void cpu_reset(unsigned long addr) __attribute__((noreturn)); | 34 | extern void cpu_reset(unsigned long addr) __attribute__((noreturn)); |
35 | extern void cpu_do_suspend(struct cpu_suspend_ctx *ptr); | ||
36 | extern 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 | ||
24 | struct mpidr_hash { | ||
25 | u64 mask; | ||
26 | u32 shift_aff[4]; | ||
27 | u32 bits; | ||
28 | }; | ||
29 | |||
30 | extern struct mpidr_hash mpidr_hash; | ||
31 | |||
32 | static 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 | */ | ||
10 | struct 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 | |||
19 | struct sleep_save_sp { | ||
20 | phys_addr_t *save_ptr_stash; | ||
21 | phys_addr_t save_ptr_stash_phys; | ||
22 | }; | ||
23 | |||
24 | extern void cpu_resume(void); | ||
25 | extern 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 | |||
240 | extern unsigned long __must_check __copy_in_user(void __user *to, const void __user *from, unsigned long n); | 241 | extern unsigned long __must_check __copy_in_user(void __user *to, const void __user *from, unsigned long n); |
241 | extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n); | 242 | extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n); |
242 | 243 | ||
243 | extern unsigned long __must_check __strncpy_from_user(char *to, const char __user *from, unsigned long count); | ||
244 | extern unsigned long __must_check __strnlen_user(const char __user *s, long n); | ||
245 | |||
246 | static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n) | 244 | static 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 | ||
279 | static inline long __must_check strncpy_from_user(char *dst, const char __user *src, long count) | 277 | extern 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 | ||
289 | static inline long __must_check strnlen_user(const char __user *s, long n) | 279 | extern __must_check long strlen_user(const char __user *str); |
290 | { | 280 | extern __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 | |||
23 | struct 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 | |||
29 | static 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 | |||
39 | static inline unsigned long create_zero_mask(unsigned long bits) | ||
40 | { | ||
41 | bits = (bits - 1) & ~bits; | ||
42 | return bits >> 7; | ||
43 | } | ||
44 | |||
45 | static 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 | */ | ||
63 | static 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 */ |