diff options
Diffstat (limited to 'arch/arm64/kernel')
| -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 |
4 files changed, 73 insertions, 33 deletions
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(); |
