aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64')
-rw-r--r--arch/arm64/Kconfig1
-rw-r--r--arch/arm64/include/asm/Kbuild1
-rw-r--r--arch/arm64/include/asm/linkage.h7
-rw-r--r--arch/arm64/include/asm/processor.h10
-rw-r--r--arch/arm64/include/uapi/asm/ptrace.h3
-rw-r--r--arch/arm64/kernel/ptrace.c73
-rw-r--r--arch/arm64/kernel/setup.c12
-rw-r--r--arch/arm64/kernel/smp.c1
-rw-r--r--arch/arm64/kernel/vdso.c20
9 files changed, 83 insertions, 45 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 75b212d5db9d..138fc9cfd783 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -24,6 +24,7 @@ config ARM64
24 select HAVE_PERF_EVENTS 24 select HAVE_PERF_EVENTS
25 select HAVE_SPARSE_IRQ 25 select HAVE_SPARSE_IRQ
26 select IRQ_DOMAIN 26 select IRQ_DOMAIN
27 select MODULES_USE_ELF_RELA
27 select NO_BOOTMEM 28 select NO_BOOTMEM
28 select OF 29 select OF
29 select OF_EARLY_FLATTREE 30 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/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/processor.h b/arch/arm64/include/asm/processor.h
index d6331acaf64e..42471d07d972 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -92,30 +92,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, 92static inline void start_thread(struct pt_regs *regs, unsigned long pc,
93 unsigned long sp) 93 unsigned long sp)
94{ 94{
95 unsigned long *stack = (unsigned long *)sp;
96
97 start_thread_common(regs, pc); 95 start_thread_common(regs, pc);
98 regs->pstate = PSR_MODE_EL0t; 96 regs->pstate = PSR_MODE_EL0t;
99 regs->sp = sp; 97 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} 98}
104 99
105#ifdef CONFIG_COMPAT 100#ifdef CONFIG_COMPAT
106static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc, 101static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc,
107 unsigned long sp) 102 unsigned long sp)
108{ 103{
109 unsigned int *stack = (unsigned int *)sp;
110
111 start_thread_common(regs, pc); 104 start_thread_common(regs, pc);
112 regs->pstate = COMPAT_PSR_MODE_USR; 105 regs->pstate = COMPAT_PSR_MODE_USR;
113 if (pc & 1) 106 if (pc & 1)
114 regs->pstate |= COMPAT_PSR_T_BIT; 107 regs->pstate |= COMPAT_PSR_T_BIT;
115 regs->compat_sp = sp; 108 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} 109}
120#endif 110#endif
121 111
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/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..226b6bf6e9c2 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
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();