aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64')
-rw-r--r--arch/arm64/Kconfig4
-rw-r--r--arch/arm64/include/asm/Kbuild1
-rw-r--r--arch/arm64/include/asm/elf.h5
-rw-r--r--arch/arm64/include/asm/fpsimd.h5
-rw-r--r--arch/arm64/include/asm/io.h10
-rw-r--r--arch/arm64/include/asm/linkage.h7
-rw-r--r--arch/arm64/include/asm/pgtable-hwdef.h6
-rw-r--r--arch/arm64/include/asm/pgtable.h40
-rw-r--r--arch/arm64/include/asm/processor.h17
-rw-r--r--arch/arm64/include/asm/syscalls.h14
-rw-r--r--arch/arm64/include/asm/unistd.h2
-rw-r--r--arch/arm64/include/asm/unistd32.h8
-rw-r--r--arch/arm64/include/uapi/asm/ptrace.h3
-rw-r--r--arch/arm64/kernel/entry.S17
-rw-r--r--arch/arm64/kernel/perf_event.c10
-rw-r--r--arch/arm64/kernel/process.c101
-rw-r--r--arch/arm64/kernel/ptrace.c73
-rw-r--r--arch/arm64/kernel/setup.c12
-rw-r--r--arch/arm64/kernel/smp.c4
-rw-r--r--arch/arm64/kernel/sys.c76
-rw-r--r--arch/arm64/kernel/sys32.S19
-rw-r--r--arch/arm64/kernel/sys_compat.c38
-rw-r--r--arch/arm64/kernel/vdso.c20
-rw-r--r--arch/arm64/mm/init.c2
24 files changed, 178 insertions, 316 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 7ff68c946073..20b688c81956 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1,11 +1,14 @@
1config ARM64 1config ARM64
2 def_bool y 2 def_bool y
3 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE 3 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
4 select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
4 select GENERIC_CLOCKEVENTS 5 select GENERIC_CLOCKEVENTS
5 select GENERIC_HARDIRQS_NO_DEPRECATED 6 select GENERIC_HARDIRQS_NO_DEPRECATED
6 select GENERIC_IOMAP 7 select GENERIC_IOMAP
7 select GENERIC_IRQ_PROBE 8 select GENERIC_IRQ_PROBE
8 select GENERIC_IRQ_SHOW 9 select GENERIC_IRQ_SHOW
10 select GENERIC_KERNEL_EXECVE
11 select GENERIC_KERNEL_THREAD
9 select GENERIC_SMP_IDLE_THREAD 12 select GENERIC_SMP_IDLE_THREAD
10 select GENERIC_TIME_VSYSCALL 13 select GENERIC_TIME_VSYSCALL
11 select HARDIRQS_SW_RESEND 14 select HARDIRQS_SW_RESEND
@@ -22,6 +25,7 @@ config ARM64
22 select HAVE_PERF_EVENTS 25 select HAVE_PERF_EVENTS
23 select HAVE_SPARSE_IRQ 26 select HAVE_SPARSE_IRQ
24 select IRQ_DOMAIN 27 select IRQ_DOMAIN
28 select MODULES_USE_ELF_RELA
25 select NO_BOOTMEM 29 select NO_BOOTMEM
26 select OF 30 select OF
27 select OF_EARLY_FLATTREE 31 select OF_EARLY_FLATTREE
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index fe77e51a7847..a581a2205938 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -18,7 +18,6 @@ generic-y += ipcbuf.h
18generic-y += irq_regs.h 18generic-y += irq_regs.h
19generic-y += kdebug.h 19generic-y += kdebug.h
20generic-y += kmap_types.h 20generic-y += kmap_types.h
21generic-y += linkage.h
22generic-y += local.h 21generic-y += local.h
23generic-y += local64.h 22generic-y += local64.h
24generic-y += mman.h 23generic-y += mman.h
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index cf284649dfcb..07fea290d7c1 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -25,12 +25,10 @@
25#include <asm/user.h> 25#include <asm/user.h>
26 26
27typedef unsigned long elf_greg_t; 27typedef unsigned long elf_greg_t;
28typedef unsigned long elf_freg_t[3];
29 28
30#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t)) 29#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
31typedef elf_greg_t elf_gregset_t[ELF_NGREG]; 30typedef elf_greg_t elf_gregset_t[ELF_NGREG];
32 31typedef struct user_fpsimd_state elf_fpregset_t;
33typedef struct user_fp elf_fpregset_t;
34 32
35#define EM_AARCH64 183 33#define EM_AARCH64 183
36 34
@@ -87,7 +85,6 @@ typedef struct user_fp elf_fpregset_t;
87#define R_AARCH64_MOVW_PREL_G2_NC 292 85#define R_AARCH64_MOVW_PREL_G2_NC 292
88#define R_AARCH64_MOVW_PREL_G3 293 86#define R_AARCH64_MOVW_PREL_G3 293
89 87
90
91/* 88/*
92 * These are used to set parameters in the core dumps. 89 * These are used to set parameters in the core dumps.
93 */ 90 */
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index b42fab9f62a9..c43b4ac13008 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -25,9 +25,8 @@
25 * - FPSR and FPCR 25 * - FPSR and FPCR
26 * - 32 128-bit data registers 26 * - 32 128-bit data registers
27 * 27 *
28 * Note that user_fp forms a prefix of this structure, which is relied 28 * Note that user_fpsimd forms a prefix of this structure, which is
29 * upon in the ptrace FP/SIMD accessors. struct user_fpsimd_state must 29 * relied upon in the ptrace FP/SIMD accessors.
30 * form a prefix of struct fpsimd_state.
31 */ 30 */
32struct fpsimd_state { 31struct fpsimd_state {
33 union { 32 union {
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 74a2a7d304a9..d2f05a608274 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -114,7 +114,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
114 * I/O port access primitives. 114 * I/O port access primitives.
115 */ 115 */
116#define IO_SPACE_LIMIT 0xffff 116#define IO_SPACE_LIMIT 0xffff
117#define PCI_IOBASE ((void __iomem *)0xffffffbbfffe0000UL) 117#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_2M))
118 118
119static inline u8 inb(unsigned long addr) 119static inline u8 inb(unsigned long addr)
120{ 120{
@@ -222,12 +222,12 @@ extern void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot
222extern void __iounmap(volatile void __iomem *addr); 222extern void __iounmap(volatile void __iomem *addr);
223 223
224#define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_DIRTY) 224#define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_DIRTY)
225#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_XN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) 225#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
226#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC)) 226#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC))
227 227
228#define ioremap(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE) 228#define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
229#define ioremap_nocache(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE) 229#define ioremap_nocache(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
230#define ioremap_wc(addr, size) __ioremap((addr), (size), PROT_NORMAL_NC) 230#define ioremap_wc(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
231#define iounmap __iounmap 231#define iounmap __iounmap
232 232
233#define ARCH_HAS_IOREMAP_WC 233#define ARCH_HAS_IOREMAP_WC
diff --git a/arch/arm64/include/asm/linkage.h b/arch/arm64/include/asm/linkage.h
new file mode 100644
index 000000000000..636c1bced7d4
--- /dev/null
+++ b/arch/arm64/include/asm/linkage.h
@@ -0,0 +1,7 @@
1#ifndef __ASM_LINKAGE_H
2#define __ASM_LINKAGE_H
3
4#define __ALIGN .align 4
5#define __ALIGN_STR ".align 4"
6
7#endif
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index 0f3b4581d925..75fd13d289b9 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -38,7 +38,8 @@
38#define PMD_SECT_S (_AT(pmdval_t, 3) << 8) 38#define PMD_SECT_S (_AT(pmdval_t, 3) << 8)
39#define PMD_SECT_AF (_AT(pmdval_t, 1) << 10) 39#define PMD_SECT_AF (_AT(pmdval_t, 1) << 10)
40#define PMD_SECT_NG (_AT(pmdval_t, 1) << 11) 40#define PMD_SECT_NG (_AT(pmdval_t, 1) << 11)
41#define PMD_SECT_XN (_AT(pmdval_t, 1) << 54) 41#define PMD_SECT_PXN (_AT(pmdval_t, 1) << 53)
42#define PMD_SECT_UXN (_AT(pmdval_t, 1) << 54)
42 43
43/* 44/*
44 * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). 45 * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
@@ -57,7 +58,8 @@
57#define PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ 58#define PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */
58#define PTE_AF (_AT(pteval_t, 1) << 10) /* Access Flag */ 59#define PTE_AF (_AT(pteval_t, 1) << 10) /* Access Flag */
59#define PTE_NG (_AT(pteval_t, 1) << 11) /* nG */ 60#define PTE_NG (_AT(pteval_t, 1) << 11) /* nG */
60#define PTE_XN (_AT(pteval_t, 1) << 54) /* XN */ 61#define PTE_PXN (_AT(pteval_t, 1) << 53) /* Privileged XN */
62#define PTE_UXN (_AT(pteval_t, 1) << 54) /* User XN */
61 63
62/* 64/*
63 * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). 65 * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 8960239be722..14aba2db6776 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -62,23 +62,23 @@ extern pgprot_t pgprot_default;
62 62
63#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b)) 63#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b))
64 64
65#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_XN | PTE_RDONLY) 65#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
66#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN) 66#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
67#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG) 67#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN)
68#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) 68#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
69#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY) 69#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
70#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) 70#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
71#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY) 71#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
72#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_XN | PTE_DIRTY) 72#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY)
73#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_DIRTY) 73#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY)
74 74
75#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_XN | PTE_RDONLY) 75#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
76#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN) 76#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
77#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG) 77#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
78#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) 78#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
79#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY) 79#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
80#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) 80#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
81#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY) 81#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
82 82
83#endif /* __ASSEMBLY__ */ 83#endif /* __ASSEMBLY__ */
84 84
@@ -130,10 +130,10 @@ extern struct page *empty_zero_page;
130#define pte_young(pte) (pte_val(pte) & PTE_AF) 130#define pte_young(pte) (pte_val(pte) & PTE_AF)
131#define pte_special(pte) (pte_val(pte) & PTE_SPECIAL) 131#define pte_special(pte) (pte_val(pte) & PTE_SPECIAL)
132#define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY)) 132#define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY))
133#define pte_exec(pte) (!(pte_val(pte) & PTE_XN)) 133#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN))
134 134
135#define pte_present_exec_user(pte) \ 135#define pte_present_exec_user(pte) \
136 ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_XN)) == \ 136 ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == \
137 (PTE_VALID | PTE_USER)) 137 (PTE_VALID | PTE_USER))
138 138
139#define PTE_BIT_FUNC(fn,op) \ 139#define PTE_BIT_FUNC(fn,op) \
@@ -262,7 +262,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
262 262
263static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 263static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
264{ 264{
265 const pteval_t mask = PTE_USER | PTE_XN | PTE_RDONLY; 265 const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY;
266 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); 266 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
267 return pte; 267 return pte;
268} 268}
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 39a208a392f7..ab239b2c456f 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -43,6 +43,8 @@
43#else 43#else
44#define STACK_TOP STACK_TOP_MAX 44#define STACK_TOP STACK_TOP_MAX
45#endif /* CONFIG_COMPAT */ 45#endif /* CONFIG_COMPAT */
46
47#define ARCH_LOW_ADDRESS_LIMIT PHYS_MASK
46#endif /* __KERNEL__ */ 48#endif /* __KERNEL__ */
47 49
48struct debug_info { 50struct debug_info {
@@ -92,30 +94,20 @@ static inline void start_thread_common(struct pt_regs *regs, unsigned long pc)
92static inline void start_thread(struct pt_regs *regs, unsigned long pc, 94static inline void start_thread(struct pt_regs *regs, unsigned long pc,
93 unsigned long sp) 95 unsigned long sp)
94{ 96{
95 unsigned long *stack = (unsigned long *)sp;
96
97 start_thread_common(regs, pc); 97 start_thread_common(regs, pc);
98 regs->pstate = PSR_MODE_EL0t; 98 regs->pstate = PSR_MODE_EL0t;
99 regs->sp = sp; 99 regs->sp = sp;
100 regs->regs[2] = stack[2]; /* x2 (envp) */
101 regs->regs[1] = stack[1]; /* x1 (argv) */
102 regs->regs[0] = stack[0]; /* x0 (argc) */
103} 100}
104 101
105#ifdef CONFIG_COMPAT 102#ifdef CONFIG_COMPAT
106static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc, 103static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc,
107 unsigned long sp) 104 unsigned long sp)
108{ 105{
109 unsigned int *stack = (unsigned int *)sp;
110
111 start_thread_common(regs, pc); 106 start_thread_common(regs, pc);
112 regs->pstate = COMPAT_PSR_MODE_USR; 107 regs->pstate = COMPAT_PSR_MODE_USR;
113 if (pc & 1) 108 if (pc & 1)
114 regs->pstate |= COMPAT_PSR_T_BIT; 109 regs->pstate |= COMPAT_PSR_T_BIT;
115 regs->compat_sp = sp; 110 regs->compat_sp = sp;
116 regs->regs[2] = stack[2]; /* x2 (envp) */
117 regs->regs[1] = stack[1]; /* x1 (argv) */
118 regs->regs[0] = stack[0]; /* x0 (argc) */
119} 111}
120#endif 112#endif
121 113
@@ -136,11 +128,6 @@ unsigned long get_wchan(struct task_struct *p);
136extern struct task_struct *cpu_switch_to(struct task_struct *prev, 128extern struct task_struct *cpu_switch_to(struct task_struct *prev,
137 struct task_struct *next); 129 struct task_struct *next);
138 130
139/*
140 * Create a new kernel thread
141 */
142extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
143
144#define task_pt_regs(p) \ 131#define task_pt_regs(p) \
145 ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) 132 ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
146 133
diff --git a/arch/arm64/include/asm/syscalls.h b/arch/arm64/include/asm/syscalls.h
index 09ff33572aab..a1b00cd6f786 100644
--- a/arch/arm64/include/asm/syscalls.h
+++ b/arch/arm64/include/asm/syscalls.h
@@ -23,18 +23,16 @@
23/* 23/*
24 * System call wrappers implemented in kernel/entry.S. 24 * System call wrappers implemented in kernel/entry.S.
25 */ 25 */
26asmlinkage long sys_execve_wrapper(const char __user *filename,
27 const char __user *const __user *argv,
28 const char __user *const __user *envp);
29asmlinkage long sys_clone_wrapper(unsigned long clone_flags,
30 unsigned long newsp,
31 void __user *parent_tid,
32 unsigned long tls_val,
33 void __user *child_tid);
34asmlinkage long sys_rt_sigreturn_wrapper(void); 26asmlinkage long sys_rt_sigreturn_wrapper(void);
35asmlinkage long sys_sigaltstack_wrapper(const stack_t __user *uss, 27asmlinkage long sys_sigaltstack_wrapper(const stack_t __user *uss,
36 stack_t __user *uoss); 28 stack_t __user *uoss);
37 29
30/*
31 * AArch64 sys_clone implementation has a different prototype than the generic
32 * one (additional TLS value argument).
33 */
34#define sys_clone sys_clone
35
38#include <asm-generic/syscalls.h> 36#include <asm-generic/syscalls.h>
39 37
40#endif /* __ASM_SYSCALLS_H */ 38#endif /* __ASM_SYSCALLS_H */
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 63f853f8b718..43064a8bd99e 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -14,7 +14,6 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16#ifdef CONFIG_COMPAT 16#ifdef CONFIG_COMPAT
17#define __ARCH_WANT_COMPAT_IPC_PARSE_VERSION
18#define __ARCH_WANT_COMPAT_STAT64 17#define __ARCH_WANT_COMPAT_STAT64
19#define __ARCH_WANT_SYS_GETHOSTNAME 18#define __ARCH_WANT_SYS_GETHOSTNAME
20#define __ARCH_WANT_SYS_PAUSE 19#define __ARCH_WANT_SYS_PAUSE
@@ -26,4 +25,5 @@
26#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND 25#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
27#define __ARCH_WANT_COMPAT_SYS_SENDFILE 26#define __ARCH_WANT_COMPAT_SYS_SENDFILE
28#endif 27#endif
28#define __ARCH_WANT_SYS_EXECVE
29#include <uapi/asm/unistd.h> 29#include <uapi/asm/unistd.h>
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index 6d909faebf28..d9850cf9870d 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -23,7 +23,7 @@
23 23
24__SYSCALL(0, sys_restart_syscall) 24__SYSCALL(0, sys_restart_syscall)
25__SYSCALL(1, sys_exit) 25__SYSCALL(1, sys_exit)
26__SYSCALL(2, compat_sys_fork_wrapper) 26__SYSCALL(2, compat_sys_fork)
27__SYSCALL(3, sys_read) 27__SYSCALL(3, sys_read)
28__SYSCALL(4, sys_write) 28__SYSCALL(4, sys_write)
29__SYSCALL(5, compat_sys_open) 29__SYSCALL(5, compat_sys_open)
@@ -32,7 +32,7 @@ __SYSCALL(7, sys_ni_syscall) /* 7 was sys_waitpid */
32__SYSCALL(8, sys_creat) 32__SYSCALL(8, sys_creat)
33__SYSCALL(9, sys_link) 33__SYSCALL(9, sys_link)
34__SYSCALL(10, sys_unlink) 34__SYSCALL(10, sys_unlink)
35__SYSCALL(11, compat_sys_execve_wrapper) 35__SYSCALL(11, compat_sys_execve)
36__SYSCALL(12, sys_chdir) 36__SYSCALL(12, sys_chdir)
37__SYSCALL(13, sys_ni_syscall) /* 13 was sys_time */ 37__SYSCALL(13, sys_ni_syscall) /* 13 was sys_time */
38__SYSCALL(14, sys_mknod) 38__SYSCALL(14, sys_mknod)
@@ -141,7 +141,7 @@ __SYSCALL(116, compat_sys_sysinfo)
141__SYSCALL(117, sys_ni_syscall) /* 117 was sys_ipc */ 141__SYSCALL(117, sys_ni_syscall) /* 117 was sys_ipc */
142__SYSCALL(118, sys_fsync) 142__SYSCALL(118, sys_fsync)
143__SYSCALL(119, compat_sys_sigreturn_wrapper) 143__SYSCALL(119, compat_sys_sigreturn_wrapper)
144__SYSCALL(120, compat_sys_clone_wrapper) 144__SYSCALL(120, sys_clone)
145__SYSCALL(121, sys_setdomainname) 145__SYSCALL(121, sys_setdomainname)
146__SYSCALL(122, sys_newuname) 146__SYSCALL(122, sys_newuname)
147__SYSCALL(123, sys_ni_syscall) /* 123 was sys_modify_ldt */ 147__SYSCALL(123, sys_ni_syscall) /* 123 was sys_modify_ldt */
@@ -211,7 +211,7 @@ __SYSCALL(186, compat_sys_sigaltstack_wrapper)
211__SYSCALL(187, compat_sys_sendfile) 211__SYSCALL(187, compat_sys_sendfile)
212__SYSCALL(188, sys_ni_syscall) /* 188 reserved */ 212__SYSCALL(188, sys_ni_syscall) /* 188 reserved */
213__SYSCALL(189, sys_ni_syscall) /* 189 reserved */ 213__SYSCALL(189, sys_ni_syscall) /* 189 reserved */
214__SYSCALL(190, compat_sys_vfork_wrapper) 214__SYSCALL(190, compat_sys_vfork)
215__SYSCALL(191, compat_sys_getrlimit) /* SuS compliant getrlimit */ 215__SYSCALL(191, compat_sys_getrlimit) /* SuS compliant getrlimit */
216__SYSCALL(192, sys_mmap_pgoff) 216__SYSCALL(192, sys_mmap_pgoff)
217__SYSCALL(193, compat_sys_truncate64_wrapper) 217__SYSCALL(193, compat_sys_truncate64_wrapper)
diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h
index 9b131b4efa0b..6913643bbe54 100644
--- a/arch/arm64/include/uapi/asm/ptrace.h
+++ b/arch/arm64/include/uapi/asm/ptrace.h
@@ -79,13 +79,14 @@ struct user_fpsimd_state {
79 79
80struct user_hwdebug_state { 80struct user_hwdebug_state {
81 __u32 dbg_info; 81 __u32 dbg_info;
82 __u32 pad;
82 struct { 83 struct {
83 __u64 addr; 84 __u64 addr;
84 __u32 ctrl; 85 __u32 ctrl;
86 __u32 pad;
85 } dbg_regs[16]; 87 } dbg_regs[16];
86}; 88};
87 89
88
89#endif /* __ASSEMBLY__ */ 90#endif /* __ASSEMBLY__ */
90 91
91#endif /* _UAPI__ASM_PTRACE_H */ 92#endif /* _UAPI__ASM_PTRACE_H */
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index a6f3f7da6880..cbfa4d28100e 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -594,7 +594,7 @@ work_resched:
594/* 594/*
595 * "slow" syscall return path. 595 * "slow" syscall return path.
596 */ 596 */
597ENTRY(ret_to_user) 597ret_to_user:
598 disable_irq // disable interrupts 598 disable_irq // disable interrupts
599 ldr x1, [tsk, #TI_FLAGS] 599 ldr x1, [tsk, #TI_FLAGS]
600 and x2, x1, #_TIF_WORK_MASK 600 and x2, x1, #_TIF_WORK_MASK
@@ -611,7 +611,10 @@ ENDPROC(ret_to_user)
611 */ 611 */
612ENTRY(ret_from_fork) 612ENTRY(ret_from_fork)
613 bl schedule_tail 613 bl schedule_tail
614 get_thread_info tsk 614 cbz x19, 1f // not a kernel thread
615 mov x0, x20
616 blr x19
6171: get_thread_info tsk
615 b ret_to_user 618 b ret_to_user
616ENDPROC(ret_from_fork) 619ENDPROC(ret_from_fork)
617 620
@@ -673,16 +676,6 @@ __sys_trace_return:
673/* 676/*
674 * Special system call wrappers. 677 * Special system call wrappers.
675 */ 678 */
676ENTRY(sys_execve_wrapper)
677 mov x3, sp
678 b sys_execve
679ENDPROC(sys_execve_wrapper)
680
681ENTRY(sys_clone_wrapper)
682 mov x5, sp
683 b sys_clone
684ENDPROC(sys_clone_wrapper)
685
686ENTRY(sys_rt_sigreturn_wrapper) 679ENTRY(sys_rt_sigreturn_wrapper)
687 mov x0, sp 680 mov x0, sp
688 b sys_rt_sigreturn 681 b sys_rt_sigreturn
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index ecbf2d81ec5c..c76c7241125b 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -613,17 +613,11 @@ enum armv8_pmuv3_perf_types {
613 ARMV8_PMUV3_PERFCTR_BUS_ACCESS = 0x19, 613 ARMV8_PMUV3_PERFCTR_BUS_ACCESS = 0x19,
614 ARMV8_PMUV3_PERFCTR_MEM_ERROR = 0x1A, 614 ARMV8_PMUV3_PERFCTR_MEM_ERROR = 0x1A,
615 ARMV8_PMUV3_PERFCTR_BUS_CYCLES = 0x1D, 615 ARMV8_PMUV3_PERFCTR_BUS_CYCLES = 0x1D,
616
617 /*
618 * This isn't an architected event.
619 * We detect this event number and use the cycle counter instead.
620 */
621 ARMV8_PMUV3_PERFCTR_CPU_CYCLES = 0xFF,
622}; 616};
623 617
624/* PMUv3 HW events mapping. */ 618/* PMUv3 HW events mapping. */
625static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = { 619static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = {
626 [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES, 620 [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES,
627 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED, 621 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED,
628 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS, 622 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS,
629 [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL, 623 [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL,
@@ -1106,7 +1100,7 @@ static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc,
1106 unsigned long evtype = event->config_base & ARMV8_EVTYPE_EVENT; 1100 unsigned long evtype = event->config_base & ARMV8_EVTYPE_EVENT;
1107 1101
1108 /* Always place a cycle counter into the cycle counter. */ 1102 /* Always place a cycle counter into the cycle counter. */
1109 if (evtype == ARMV8_PMUV3_PERFCTR_CPU_CYCLES) { 1103 if (evtype == ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES) {
1110 if (test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask)) 1104 if (test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask))
1111 return -EAGAIN; 1105 return -EAGAIN;
1112 1106
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index f22965ea1cfc..8a5f3341861e 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -240,27 +240,41 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
240 struct pt_regs *childregs = task_pt_regs(p); 240 struct pt_regs *childregs = task_pt_regs(p);
241 unsigned long tls = p->thread.tp_value; 241 unsigned long tls = p->thread.tp_value;
242 242
243 *childregs = *regs; 243 memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context));
244 childregs->regs[0] = 0;
245 244
246 if (is_compat_thread(task_thread_info(p))) 245 if (likely(regs)) {
247 childregs->compat_sp = stack_start; 246 *childregs = *regs;
248 else { 247 childregs->regs[0] = 0;
248 if (is_compat_thread(task_thread_info(p))) {
249 if (stack_start)
250 childregs->compat_sp = stack_start;
251 } else {
252 /*
253 * Read the current TLS pointer from tpidr_el0 as it may be
254 * out-of-sync with the saved value.
255 */
256 asm("mrs %0, tpidr_el0" : "=r" (tls));
257 if (stack_start) {
258 /* 16-byte aligned stack mandatory on AArch64 */
259 if (stack_start & 15)
260 return -EINVAL;
261 childregs->sp = stack_start;
262 }
263 }
249 /* 264 /*
250 * Read the current TLS pointer from tpidr_el0 as it may be 265 * If a TLS pointer was passed to clone (4th argument), use it
251 * out-of-sync with the saved value. 266 * for the new thread.
252 */ 267 */
253 asm("mrs %0, tpidr_el0" : "=r" (tls)); 268 if (clone_flags & CLONE_SETTLS)
254 childregs->sp = stack_start; 269 tls = regs->regs[3];
270 } else {
271 memset(childregs, 0, sizeof(struct pt_regs));
272 childregs->pstate = PSR_MODE_EL1h;
273 p->thread.cpu_context.x19 = stack_start;
274 p->thread.cpu_context.x20 = stk_sz;
255 } 275 }
256
257 memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context));
258 p->thread.cpu_context.sp = (unsigned long)childregs;
259 p->thread.cpu_context.pc = (unsigned long)ret_from_fork; 276 p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
260 277 p->thread.cpu_context.sp = (unsigned long)childregs;
261 /* If a TLS pointer was passed to clone, use that for the new thread. */
262 if (clone_flags & CLONE_SETTLS)
263 tls = regs->regs[3];
264 p->thread.tp_value = tls; 278 p->thread.tp_value = tls;
265 279
266 ptrace_hw_copy_thread(p); 280 ptrace_hw_copy_thread(p);
@@ -309,61 +323,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
309 return last; 323 return last;
310} 324}
311 325
312/*
313 * Fill in the task's elfregs structure for a core dump.
314 */
315int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs)
316{
317 elf_core_copy_regs(elfregs, task_pt_regs(t));
318 return 1;
319}
320
321/*
322 * fill in the fpe structure for a core dump...
323 */
324int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
325{
326 return 0;
327}
328EXPORT_SYMBOL(dump_fpu);
329
330/*
331 * Shuffle the argument into the correct register before calling the
332 * thread function. x1 is the thread argument, x2 is the pointer to
333 * the thread function, and x3 points to the exit function.
334 */
335extern void kernel_thread_helper(void);
336asm( ".section .text\n"
337" .align\n"
338" .type kernel_thread_helper, #function\n"
339"kernel_thread_helper:\n"
340" mov x0, x1\n"
341" mov x30, x3\n"
342" br x2\n"
343" .size kernel_thread_helper, . - kernel_thread_helper\n"
344" .previous");
345
346#define kernel_thread_exit do_exit
347
348/*
349 * Create a kernel thread.
350 */
351pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
352{
353 struct pt_regs regs;
354
355 memset(&regs, 0, sizeof(regs));
356
357 regs.regs[1] = (unsigned long)arg;
358 regs.regs[2] = (unsigned long)fn;
359 regs.regs[3] = (unsigned long)kernel_thread_exit;
360 regs.pc = (unsigned long)kernel_thread_helper;
361 regs.pstate = PSR_MODE_EL1h;
362
363 return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
364}
365EXPORT_SYMBOL(kernel_thread);
366
367unsigned long get_wchan(struct task_struct *p) 326unsigned long get_wchan(struct task_struct *p)
368{ 327{
369 struct stackframe frame; 328 struct stackframe frame;
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 2ea3968367c2..6e1e77f1831c 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -234,28 +234,33 @@ static int ptrace_hbp_fill_attr_ctrl(unsigned int note_type,
234 struct arch_hw_breakpoint_ctrl ctrl, 234 struct arch_hw_breakpoint_ctrl ctrl,
235 struct perf_event_attr *attr) 235 struct perf_event_attr *attr)
236{ 236{
237 int err, len, type; 237 int err, len, type, disabled = !ctrl.enabled;
238 238
239 err = arch_bp_generic_fields(ctrl, &len, &type); 239 if (disabled) {
240 if (err) 240 len = 0;
241 return err; 241 type = HW_BREAKPOINT_EMPTY;
242 242 } else {
243 switch (note_type) { 243 err = arch_bp_generic_fields(ctrl, &len, &type);
244 case NT_ARM_HW_BREAK: 244 if (err)
245 if ((type & HW_BREAKPOINT_X) != type) 245 return err;
246 return -EINVAL; 246
247 break; 247 switch (note_type) {
248 case NT_ARM_HW_WATCH: 248 case NT_ARM_HW_BREAK:
249 if ((type & HW_BREAKPOINT_RW) != type) 249 if ((type & HW_BREAKPOINT_X) != type)
250 return -EINVAL;
251 break;
252 case NT_ARM_HW_WATCH:
253 if ((type & HW_BREAKPOINT_RW) != type)
254 return -EINVAL;
255 break;
256 default:
250 return -EINVAL; 257 return -EINVAL;
251 break; 258 }
252 default:
253 return -EINVAL;
254 } 259 }
255 260
256 attr->bp_len = len; 261 attr->bp_len = len;
257 attr->bp_type = type; 262 attr->bp_type = type;
258 attr->disabled = !ctrl.enabled; 263 attr->disabled = disabled;
259 264
260 return 0; 265 return 0;
261} 266}
@@ -372,7 +377,7 @@ static int ptrace_hbp_set_addr(unsigned int note_type,
372 377
373#define PTRACE_HBP_ADDR_SZ sizeof(u64) 378#define PTRACE_HBP_ADDR_SZ sizeof(u64)
374#define PTRACE_HBP_CTRL_SZ sizeof(u32) 379#define PTRACE_HBP_CTRL_SZ sizeof(u32)
375#define PTRACE_HBP_REG_OFF sizeof(u32) 380#define PTRACE_HBP_PAD_SZ sizeof(u32)
376 381
377static int hw_break_get(struct task_struct *target, 382static int hw_break_get(struct task_struct *target,
378 const struct user_regset *regset, 383 const struct user_regset *regset,
@@ -380,7 +385,7 @@ static int hw_break_get(struct task_struct *target,
380 void *kbuf, void __user *ubuf) 385 void *kbuf, void __user *ubuf)
381{ 386{
382 unsigned int note_type = regset->core_note_type; 387 unsigned int note_type = regset->core_note_type;
383 int ret, idx = 0, offset = PTRACE_HBP_REG_OFF, limit; 388 int ret, idx = 0, offset, limit;
384 u32 info, ctrl; 389 u32 info, ctrl;
385 u64 addr; 390 u64 addr;
386 391
@@ -389,11 +394,20 @@ static int hw_break_get(struct task_struct *target,
389 if (ret) 394 if (ret)
390 return ret; 395 return ret;
391 396
392 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &info, 0, 4); 397 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &info, 0,
398 sizeof(info));
399 if (ret)
400 return ret;
401
402 /* Pad */
403 offset = offsetof(struct user_hwdebug_state, pad);
404 ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, offset,
405 offset + PTRACE_HBP_PAD_SZ);
393 if (ret) 406 if (ret)
394 return ret; 407 return ret;
395 408
396 /* (address, ctrl) registers */ 409 /* (address, ctrl) registers */
410 offset = offsetof(struct user_hwdebug_state, dbg_regs);
397 limit = regset->n * regset->size; 411 limit = regset->n * regset->size;
398 while (count && offset < limit) { 412 while (count && offset < limit) {
399 ret = ptrace_hbp_get_addr(note_type, target, idx, &addr); 413 ret = ptrace_hbp_get_addr(note_type, target, idx, &addr);
@@ -413,6 +427,13 @@ static int hw_break_get(struct task_struct *target,
413 if (ret) 427 if (ret)
414 return ret; 428 return ret;
415 offset += PTRACE_HBP_CTRL_SZ; 429 offset += PTRACE_HBP_CTRL_SZ;
430
431 ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
432 offset,
433 offset + PTRACE_HBP_PAD_SZ);
434 if (ret)
435 return ret;
436 offset += PTRACE_HBP_PAD_SZ;
416 idx++; 437 idx++;
417 } 438 }
418 439
@@ -425,12 +446,13 @@ static int hw_break_set(struct task_struct *target,
425 const void *kbuf, const void __user *ubuf) 446 const void *kbuf, const void __user *ubuf)
426{ 447{
427 unsigned int note_type = regset->core_note_type; 448 unsigned int note_type = regset->core_note_type;
428 int ret, idx = 0, offset = PTRACE_HBP_REG_OFF, limit; 449 int ret, idx = 0, offset, limit;
429 u32 ctrl; 450 u32 ctrl;
430 u64 addr; 451 u64 addr;
431 452
432 /* Resource info */ 453 /* Resource info and pad */
433 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, 4); 454 offset = offsetof(struct user_hwdebug_state, dbg_regs);
455 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, offset);
434 if (ret) 456 if (ret)
435 return ret; 457 return ret;
436 458
@@ -454,6 +476,13 @@ static int hw_break_set(struct task_struct *target,
454 if (ret) 476 if (ret)
455 return ret; 477 return ret;
456 offset += PTRACE_HBP_CTRL_SZ; 478 offset += PTRACE_HBP_CTRL_SZ;
479
480 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
481 offset,
482 offset + PTRACE_HBP_PAD_SZ);
483 if (ret)
484 return ret;
485 offset += PTRACE_HBP_PAD_SZ;
457 idx++; 486 idx++;
458 } 487 }
459 488
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 48ffb9fb3fe3..7665a9bfdb1e 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -170,7 +170,19 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
170 170
171void __init early_init_dt_add_memory_arch(u64 base, u64 size) 171void __init early_init_dt_add_memory_arch(u64 base, u64 size)
172{ 172{
173 base &= PAGE_MASK;
173 size &= PAGE_MASK; 174 size &= PAGE_MASK;
175 if (base + size < PHYS_OFFSET) {
176 pr_warning("Ignoring memory block 0x%llx - 0x%llx\n",
177 base, base + size);
178 return;
179 }
180 if (base < PHYS_OFFSET) {
181 pr_warning("Ignoring memory range 0x%llx - 0x%llx\n",
182 base, PHYS_OFFSET);
183 size -= PHYS_OFFSET - base;
184 base = PHYS_OFFSET;
185 }
174 memblock_add(base, size); 186 memblock_add(base, size);
175} 187}
176 188
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index b711525be21f..538300f2273d 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -46,7 +46,6 @@
46#include <asm/sections.h> 46#include <asm/sections.h>
47#include <asm/tlbflush.h> 47#include <asm/tlbflush.h>
48#include <asm/ptrace.h> 48#include <asm/ptrace.h>
49#include <asm/mmu_context.h>
50 49
51/* 50/*
52 * as from 2.5, kernels no longer have an init_tasks structure 51 * as from 2.5, kernels no longer have an init_tasks structure
@@ -212,8 +211,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
212 * before we continue. 211 * before we continue.
213 */ 212 */
214 set_cpu_online(cpu, true); 213 set_cpu_online(cpu, true);
215 while (!cpu_active(cpu)) 214 complete(&cpu_running);
216 cpu_relax();
217 215
218 /* 216 /*
219 * OK, it's off to the idle thread for us 217 * OK, it's off to the idle thread for us
diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c
index b120df37de35..4364df85050e 100644
--- a/arch/arm64/kernel/sys.c
+++ b/arch/arm64/kernel/sys.c
@@ -31,79 +31,11 @@
31 */ 31 */
32asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, 32asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp,
33 int __user *parent_tidptr, unsigned long tls_val, 33 int __user *parent_tidptr, unsigned long tls_val,
34 int __user *child_tidptr, struct pt_regs *regs) 34 int __user *child_tidptr)
35{ 35{
36 if (!newsp) 36 return do_fork(clone_flags, newsp, current_pt_regs(), 0,
37 newsp = regs->sp; 37 parent_tidptr, child_tidptr);
38 /* 16-byte aligned stack mandatory on AArch64 */
39 if (newsp & 15)
40 return -EINVAL;
41 return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
42}
43
44/*
45 * sys_execve() executes a new program.
46 */
47asmlinkage long sys_execve(const char __user *filenamei,
48 const char __user *const __user *argv,
49 const char __user *const __user *envp,
50 struct pt_regs *regs)
51{
52 long error;
53 struct filename *filename;
54
55 filename = getname(filenamei);
56 error = PTR_ERR(filename);
57 if (IS_ERR(filename))
58 goto out;
59 error = do_execve(filename->name, argv, envp, regs);
60 putname(filename);
61out:
62 return error;
63}
64
65int kernel_execve(const char *filename,
66 const char *const argv[],
67 const char *const envp[])
68{
69 struct pt_regs regs;
70 int ret;
71
72 memset(&regs, 0, sizeof(struct pt_regs));
73 ret = do_execve(filename,
74 (const char __user *const __user *)argv,
75 (const char __user *const __user *)envp, &regs);
76 if (ret < 0)
77 goto out;
78
79 /*
80 * Save argc to the register structure for userspace.
81 */
82 regs.regs[0] = ret;
83
84 /*
85 * We were successful. We won't be returning to our caller, but
86 * instead to user space by manipulating the kernel stack.
87 */
88 asm( "add x0, %0, %1\n\t"
89 "mov x1, %2\n\t"
90 "mov x2, %3\n\t"
91 "bl memmove\n\t" /* copy regs to top of stack */
92 "mov x27, #0\n\t" /* not a syscall */
93 "mov x28, %0\n\t" /* thread structure */
94 "mov sp, x0\n\t" /* reposition stack pointer */
95 "b ret_to_user"
96 :
97 : "r" (current_thread_info()),
98 "Ir" (THREAD_START_SP - sizeof(regs)),
99 "r" (&regs),
100 "Ir" (sizeof(regs))
101 : "x0", "x1", "x2", "x27", "x28", "x30", "memory");
102
103 out:
104 return ret;
105} 38}
106EXPORT_SYMBOL(kernel_execve);
107 39
108asmlinkage long sys_mmap(unsigned long addr, unsigned long len, 40asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
109 unsigned long prot, unsigned long flags, 41 unsigned long prot, unsigned long flags,
@@ -118,8 +50,6 @@ asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
118/* 50/*
119 * Wrappers to pass the pt_regs argument. 51 * Wrappers to pass the pt_regs argument.
120 */ 52 */
121#define sys_execve sys_execve_wrapper
122#define sys_clone sys_clone_wrapper
123#define sys_rt_sigreturn sys_rt_sigreturn_wrapper 53#define sys_rt_sigreturn sys_rt_sigreturn_wrapper
124#define sys_sigaltstack sys_sigaltstack_wrapper 54#define sys_sigaltstack sys_sigaltstack_wrapper
125 55
diff --git a/arch/arm64/kernel/sys32.S b/arch/arm64/kernel/sys32.S
index 54c4aec47a08..7ef59e9245ef 100644
--- a/arch/arm64/kernel/sys32.S
+++ b/arch/arm64/kernel/sys32.S
@@ -26,25 +26,6 @@
26/* 26/*
27 * System call wrappers for the AArch32 compatibility layer. 27 * System call wrappers for the AArch32 compatibility layer.
28 */ 28 */
29compat_sys_fork_wrapper:
30 mov x0, sp
31 b compat_sys_fork
32ENDPROC(compat_sys_fork_wrapper)
33
34compat_sys_vfork_wrapper:
35 mov x0, sp
36 b compat_sys_vfork
37ENDPROC(compat_sys_vfork_wrapper)
38
39compat_sys_execve_wrapper:
40 mov x3, sp
41 b compat_sys_execve
42ENDPROC(compat_sys_execve_wrapper)
43
44compat_sys_clone_wrapper:
45 mov x5, sp
46 b compat_sys_clone
47ENDPROC(compat_sys_clone_wrapper)
48 29
49compat_sys_sigreturn_wrapper: 30compat_sys_sigreturn_wrapper:
50 mov x0, sp 31 mov x0, sp
diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c
index 906e3bd270b0..6fabc1912da0 100644
--- a/arch/arm64/kernel/sys_compat.c
+++ b/arch/arm64/kernel/sys_compat.c
@@ -28,43 +28,15 @@
28#include <asm/cacheflush.h> 28#include <asm/cacheflush.h>
29#include <asm/unistd32.h> 29#include <asm/unistd32.h>
30 30
31asmlinkage int compat_sys_fork(struct pt_regs *regs) 31asmlinkage int compat_sys_fork(void)
32{ 32{
33 return do_fork(SIGCHLD, regs->compat_sp, regs, 0, NULL, NULL); 33 return do_fork(SIGCHLD, 0, current_pt_regs(), 0, NULL, NULL);
34} 34}
35 35
36asmlinkage int compat_sys_clone(unsigned long clone_flags, unsigned long newsp, 36asmlinkage int compat_sys_vfork(void)
37 int __user *parent_tidptr, int tls_val,
38 int __user *child_tidptr, struct pt_regs *regs)
39{ 37{
40 if (!newsp) 38 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0,
41 newsp = regs->compat_sp; 39 current_pt_regs(), 0, NULL, NULL);
42
43 return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
44}
45
46asmlinkage int compat_sys_vfork(struct pt_regs *regs)
47{
48 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->compat_sp,
49 regs, 0, NULL, NULL);
50}
51
52asmlinkage int compat_sys_execve(const char __user *filenamei,
53 compat_uptr_t argv, compat_uptr_t envp,
54 struct pt_regs *regs)
55{
56 int error;
57 struct filename *filename;
58
59 filename = getname(filenamei);
60 error = PTR_ERR(filename);
61 if (IS_ERR(filename))
62 goto out;
63 error = compat_do_execve(filename->name, compat_ptr(argv),
64 compat_ptr(envp), regs);
65 putname(filename);
66out:
67 return error;
68} 40}
69 41
70asmlinkage int compat_sys_sched_rr_get_interval(compat_pid_t pid, 42asmlinkage int compat_sys_sched_rr_get_interval(compat_pid_t pid,
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 17948fc7d663..ba457943a16b 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -28,6 +28,7 @@
28#include <linux/sched.h> 28#include <linux/sched.h>
29#include <linux/signal.h> 29#include <linux/signal.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/timekeeper_internal.h>
31#include <linux/vmalloc.h> 32#include <linux/vmalloc.h>
32 33
33#include <asm/cacheflush.h> 34#include <asm/cacheflush.h>
@@ -222,11 +223,10 @@ struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
222/* 223/*
223 * Update the vDSO data page to keep in sync with kernel timekeeping. 224 * Update the vDSO data page to keep in sync with kernel timekeeping.
224 */ 225 */
225void update_vsyscall(struct timespec *ts, struct timespec *wtm, 226void update_vsyscall(struct timekeeper *tk)
226 struct clocksource *clock, u32 mult)
227{ 227{
228 struct timespec xtime_coarse; 228 struct timespec xtime_coarse;
229 u32 use_syscall = strcmp(clock->name, "arch_sys_counter"); 229 u32 use_syscall = strcmp(tk->clock->name, "arch_sys_counter");
230 230
231 ++vdso_data->tb_seq_count; 231 ++vdso_data->tb_seq_count;
232 smp_wmb(); 232 smp_wmb();
@@ -237,13 +237,13 @@ void update_vsyscall(struct timespec *ts, struct timespec *wtm,
237 vdso_data->xtime_coarse_nsec = xtime_coarse.tv_nsec; 237 vdso_data->xtime_coarse_nsec = xtime_coarse.tv_nsec;
238 238
239 if (!use_syscall) { 239 if (!use_syscall) {
240 vdso_data->cs_cycle_last = clock->cycle_last; 240 vdso_data->cs_cycle_last = tk->clock->cycle_last;
241 vdso_data->xtime_clock_sec = ts->tv_sec; 241 vdso_data->xtime_clock_sec = tk->xtime_sec;
242 vdso_data->xtime_clock_nsec = ts->tv_nsec; 242 vdso_data->xtime_clock_nsec = tk->xtime_nsec >> tk->shift;
243 vdso_data->cs_mult = mult; 243 vdso_data->cs_mult = tk->mult;
244 vdso_data->cs_shift = clock->shift; 244 vdso_data->cs_shift = tk->shift;
245 vdso_data->wtm_clock_sec = wtm->tv_sec; 245 vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec;
246 vdso_data->wtm_clock_nsec = wtm->tv_nsec; 246 vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec;
247 } 247 }
248 248
249 smp_wmb(); 249 smp_wmb();
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index efbf7df05d3f..4cd28931dba9 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -80,7 +80,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
80#ifdef CONFIG_ZONE_DMA32 80#ifdef CONFIG_ZONE_DMA32
81 /* 4GB maximum for 32-bit only capable devices */ 81 /* 4GB maximum for 32-bit only capable devices */
82 max_dma32 = min(max, MAX_DMA32_PFN); 82 max_dma32 = min(max, MAX_DMA32_PFN);
83 zone_size[ZONE_DMA32] = max_dma32 - min; 83 zone_size[ZONE_DMA32] = max(min, max_dma32) - min;
84#endif 84#endif
85 zone_size[ZONE_NORMAL] = max - max_dma32; 85 zone_size[ZONE_NORMAL] = max - max_dma32;
86 86