diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-20 12:48:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-20 12:48:10 -0400 |
commit | 198190a188b9cefff22b51c0be5f0f70b6f9b618 (patch) | |
tree | 333216304026afaf12bd765f814014ceb6673e45 | |
parent | 31fd84b95eb211d5db460a1dda85e004800a7b52 (diff) | |
parent | aeed41a9371ee02257b608eb06a9058507a7d0f4 (diff) |
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/linux-aarch64
Pull arm64 fixes from Catalin Marinas:
"Main changes:
- AArch64 Linux compilation fixes following 3.7-rc1 changes
(MODULES_USE_ELF_RELA, update_vsyscall() prototype)
- Unnecessary register setting in start_thread() (thanks to Al Viro)
- ptrace fixes"
* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/linux-aarch64:
arm64: fix alignment padding in assembly code
arm64: ptrace: use HW_BREAKPOINT_EMPTY type for disabled breakpoints
arm64: ptrace: make structure padding explicit for debug registers
arm64: No need to set the x0-x2 registers in start_thread()
arm64: Ignore memory blocks below PHYS_OFFSET
arm64: Fix the update_vsyscall() prototype
arm64: Select MODULES_USE_ELF_RELA
arm64: Remove duplicate inclusion of mmu_context.h in smp.c
-rw-r--r-- | arch/arm64/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm64/include/asm/Kbuild | 1 | ||||
-rw-r--r-- | arch/arm64/include/asm/linkage.h | 7 | ||||
-rw-r--r-- | arch/arm64/include/asm/processor.h | 10 | ||||
-rw-r--r-- | arch/arm64/include/uapi/asm/ptrace.h | 3 | ||||
-rw-r--r-- | arch/arm64/kernel/ptrace.c | 73 | ||||
-rw-r--r-- | arch/arm64/kernel/setup.c | 12 | ||||
-rw-r--r-- | arch/arm64/kernel/smp.c | 1 | ||||
-rw-r--r-- | arch/arm64/kernel/vdso.c | 20 |
9 files changed, 83 insertions, 45 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 7ff68c946073..ef54a59a9e89 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig | |||
@@ -22,6 +22,7 @@ config ARM64 | |||
22 | select HAVE_PERF_EVENTS | 22 | select HAVE_PERF_EVENTS |
23 | select HAVE_SPARSE_IRQ | 23 | select HAVE_SPARSE_IRQ |
24 | select IRQ_DOMAIN | 24 | select IRQ_DOMAIN |
25 | select MODULES_USE_ELF_RELA | ||
25 | select NO_BOOTMEM | 26 | select NO_BOOTMEM |
26 | select OF | 27 | select OF |
27 | select OF_EARLY_FLATTREE | 28 | 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 | |||
18 | generic-y += irq_regs.h | 18 | generic-y += irq_regs.h |
19 | generic-y += kdebug.h | 19 | generic-y += kdebug.h |
20 | generic-y += kmap_types.h | 20 | generic-y += kmap_types.h |
21 | generic-y += linkage.h | ||
22 | generic-y += local.h | 21 | generic-y += local.h |
23 | generic-y += local64.h | 22 | generic-y += local64.h |
24 | generic-y += mman.h | 23 | generic-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 39a208a392f7..5d810044feda 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) | |||
92 | static inline void start_thread(struct pt_regs *regs, unsigned long pc, | 92 | static 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 |
106 | static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc, | 101 | static 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 | ||
80 | struct user_hwdebug_state { | 80 | struct 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 | ||
377 | static int hw_break_get(struct task_struct *target, | 382 | static 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 | ||
171 | void __init early_init_dt_add_memory_arch(u64 base, u64 size) | 171 | void __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 | */ |
225 | void update_vsyscall(struct timespec *ts, struct timespec *wtm, | 226 | void 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(); |