diff options
Diffstat (limited to 'arch/arm64/kernel')
-rw-r--r-- | arch/arm64/kernel/entry.S | 1 | ||||
-rw-r--r-- | arch/arm64/kernel/ptrace.c | 79 | ||||
-rw-r--r-- | arch/arm64/kernel/setup.c | 12 | ||||
-rw-r--r-- | arch/arm64/kernel/signal32.c | 22 | ||||
-rw-r--r-- | arch/arm64/kernel/smp.c | 1 | ||||
-rw-r--r-- | arch/arm64/kernel/sys.c | 4 | ||||
-rw-r--r-- | arch/arm64/kernel/sys32.S | 126 | ||||
-rw-r--r-- | arch/arm64/kernel/sys_compat.c | 10 | ||||
-rw-r--r-- | arch/arm64/kernel/vdso.c | 20 |
9 files changed, 94 insertions, 181 deletions
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 6538928ff1a..a6f3f7da688 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -26,6 +26,7 @@ #include <asm/errno.h> #include <asm/thread_info.h> #include <asm/unistd.h> +#include <asm/unistd32.h> /* * Bad Abort numbers diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index ac3550ecc7b..6e1e77f1831 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, struct arch_hw_breakpoint_ctrl ctrl, struct perf_event_attr *attr) { - int err, len, type; + int err, len, type, disabled = !ctrl.enabled; - err = arch_bp_generic_fields(ctrl, &len, &type); - if (err) - return err; - - switch (note_type) { - case NT_ARM_HW_BREAK: - if ((type & HW_BREAKPOINT_X) != type) - return -EINVAL; - break; - case NT_ARM_HW_WATCH: - if ((type & HW_BREAKPOINT_RW) != type) + if (disabled) { + len = 0; + type = HW_BREAKPOINT_EMPTY; + } else { + err = arch_bp_generic_fields(ctrl, &len, &type); + if (err) + return err; + + switch (note_type) { + case NT_ARM_HW_BREAK: + if ((type & HW_BREAKPOINT_X) != type) + return -EINVAL; + break; + case NT_ARM_HW_WATCH: + if ((type & HW_BREAKPOINT_RW) != type) + return -EINVAL; + break; + default: return -EINVAL; - break; - default: - return -EINVAL; + } } attr->bp_len = len; attr->bp_type = type; - attr->disabled = !ctrl.enabled; + attr->disabled = disabled; return 0; } @@ -372,7 +377,7 @@ static int ptrace_hbp_set_addr(unsigned int note_type, #define PTRACE_HBP_ADDR_SZ sizeof(u64) #define PTRACE_HBP_CTRL_SZ sizeof(u32) -#define PTRACE_HBP_REG_OFF sizeof(u32) +#define PTRACE_HBP_PAD_SZ sizeof(u32) static int hw_break_get(struct task_struct *target, const struct user_regset *regset, @@ -380,7 +385,7 @@ static int hw_break_get(struct task_struct *target, void *kbuf, void __user *ubuf) { unsigned int note_type = regset->core_note_type; - int ret, idx = 0, offset = PTRACE_HBP_REG_OFF, limit; + int ret, idx = 0, offset, limit; u32 info, ctrl; u64 addr; @@ -389,11 +394,20 @@ static int hw_break_get(struct task_struct *target, if (ret) return ret; - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &info, 0, 4); + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &info, 0, + sizeof(info)); + if (ret) + return ret; + + /* Pad */ + offset = offsetof(struct user_hwdebug_state, pad); + ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, offset, + offset + PTRACE_HBP_PAD_SZ); if (ret) return ret; /* (address, ctrl) registers */ + offset = offsetof(struct user_hwdebug_state, dbg_regs); limit = regset->n * regset->size; while (count && offset < limit) { ret = ptrace_hbp_get_addr(note_type, target, idx, &addr); @@ -413,6 +427,13 @@ static int hw_break_get(struct task_struct *target, if (ret) return ret; offset += PTRACE_HBP_CTRL_SZ; + + ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, + offset, + offset + PTRACE_HBP_PAD_SZ); + if (ret) + return ret; + offset += PTRACE_HBP_PAD_SZ; idx++; } @@ -425,12 +446,13 @@ static int hw_break_set(struct task_struct *target, const void *kbuf, const void __user *ubuf) { unsigned int note_type = regset->core_note_type; - int ret, idx = 0, offset = PTRACE_HBP_REG_OFF, limit; + int ret, idx = 0, offset, limit; u32 ctrl; u64 addr; - /* Resource info */ - ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, 4); + /* Resource info and pad */ + offset = offsetof(struct user_hwdebug_state, dbg_regs); + ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, offset); if (ret) return ret; @@ -454,6 +476,13 @@ static int hw_break_set(struct task_struct *target, if (ret) return ret; offset += PTRACE_HBP_CTRL_SZ; + + ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, + offset, + offset + PTRACE_HBP_PAD_SZ); + if (ret) + return ret; + offset += PTRACE_HBP_PAD_SZ; idx++; } @@ -823,11 +852,11 @@ static int compat_ptrace_read_user(struct task_struct *tsk, compat_ulong_t off, if (off & 3) return -EIO; - if (off == PT_TEXT_ADDR) + if (off == COMPAT_PT_TEXT_ADDR) tmp = tsk->mm->start_code; - else if (off == PT_DATA_ADDR) + else if (off == COMPAT_PT_DATA_ADDR) tmp = tsk->mm->start_data; - else if (off == PT_TEXT_END_ADDR) + else if (off == COMPAT_PT_TEXT_END_ADDR) tmp = tsk->mm->end_code; else if (off < sizeof(compat_elf_gregset_t)) return copy_regset_to_user(tsk, &user_aarch32_view, diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 48ffb9fb3fe..7665a9bfdb1 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) void __init early_init_dt_add_memory_arch(u64 base, u64 size) { + base &= PAGE_MASK; size &= PAGE_MASK; + if (base + size < PHYS_OFFSET) { + pr_warning("Ignoring memory block 0x%llx - 0x%llx\n", + base, base + size); + return; + } + if (base < PHYS_OFFSET) { + pr_warning("Ignoring memory range 0x%llx - 0x%llx\n", + base, PHYS_OFFSET); + size -= PHYS_OFFSET - base; + base = PHYS_OFFSET; + } memblock_add(base, size); } diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c index 0790a87a434..4654824747a 100644 --- a/arch/arm64/kernel/signal32.c +++ b/arch/arm64/kernel/signal32.c @@ -18,8 +18,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#define __SYSCALL_COMPAT - #include <linux/compat.h> #include <linux/signal.h> #include <linux/syscalls.h> @@ -28,7 +26,7 @@ #include <asm/fpsimd.h> #include <asm/signal32.h> #include <asm/uaccess.h> -#include <asm/unistd.h> +#include <asm/unistd32.h> struct compat_sigaction { compat_uptr_t sa_handler; @@ -126,19 +124,19 @@ struct compat_rt_sigframe { * For ARM syscalls, the syscall number has to be loaded into r7. * We do not support an OABI userspace. */ -#define MOV_R7_NR_SIGRETURN (0xe3a07000 | __NR_sigreturn) -#define SVC_SYS_SIGRETURN (0xef000000 | __NR_sigreturn) -#define MOV_R7_NR_RT_SIGRETURN (0xe3a07000 | __NR_rt_sigreturn) -#define SVC_SYS_RT_SIGRETURN (0xef000000 | __NR_rt_sigreturn) +#define MOV_R7_NR_SIGRETURN (0xe3a07000 | __NR_compat_sigreturn) +#define SVC_SYS_SIGRETURN (0xef000000 | __NR_compat_sigreturn) +#define MOV_R7_NR_RT_SIGRETURN (0xe3a07000 | __NR_compat_rt_sigreturn) +#define SVC_SYS_RT_SIGRETURN (0xef000000 | __NR_compat_rt_sigreturn) /* * For Thumb syscalls, we also pass the syscall number via r7. We therefore * need two 16-bit instructions. */ -#define SVC_THUMB_SIGRETURN (((0xdf00 | __NR_sigreturn) << 16) | \ - 0x2700 | __NR_sigreturn) -#define SVC_THUMB_RT_SIGRETURN (((0xdf00 | __NR_rt_sigreturn) << 16) | \ - 0x2700 | __NR_rt_sigreturn) +#define SVC_THUMB_SIGRETURN (((0xdf00 | __NR_compat_sigreturn) << 16) | \ + 0x2700 | __NR_compat_sigreturn) +#define SVC_THUMB_RT_SIGRETURN (((0xdf00 | __NR_compat_rt_sigreturn) << 16) | \ + 0x2700 | __NR_compat_rt_sigreturn) const compat_ulong_t aarch32_sigret_code[6] = { /* @@ -819,5 +817,5 @@ asmlinkage int compat_sys_rt_sigqueueinfo(int pid, int sig, void compat_setup_restart_syscall(struct pt_regs *regs) { - regs->regs[7] = __NR_restart_syscall; + regs->regs[7] = __NR_compat_restart_syscall; } diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index b711525be21..226b6bf6e9c 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -46,7 +46,6 @@ #include <asm/sections.h> #include <asm/tlbflush.h> #include <asm/ptrace.h> -#include <asm/mmu_context.h> /* * as from 2.5, kernels no longer have an init_tasks structure diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c index 905fcfb0ddd..b120df37de3 100644 --- a/arch/arm64/kernel/sys.c +++ b/arch/arm64/kernel/sys.c @@ -50,13 +50,13 @@ asmlinkage long sys_execve(const char __user *filenamei, struct pt_regs *regs) { long error; - char * filename; + struct filename *filename; filename = getname(filenamei); error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; - error = do_execve(filename, argv, envp, regs); + error = do_execve(filename->name, argv, envp, regs); putname(filename); out: return error; diff --git a/arch/arm64/kernel/sys32.S b/arch/arm64/kernel/sys32.S index 5e4dc93cc31..54c4aec47a0 100644 --- a/arch/arm64/kernel/sys32.S +++ b/arch/arm64/kernel/sys32.S @@ -147,136 +147,12 @@ compat_sys_fanotify_mark_wrapper: b sys_fanotify_mark ENDPROC(compat_sys_fanotify_mark_wrapper) -/* - * Use the compat system call wrappers. - */ -#define sys_fork compat_sys_fork_wrapper -#define sys_open compat_sys_open -#define sys_execve compat_sys_execve_wrapper -#define sys_lseek compat_sys_lseek_wrapper -#define sys_mount compat_sys_mount -#define sys_ptrace compat_sys_ptrace -#define sys_times compat_sys_times -#define sys_ioctl compat_sys_ioctl -#define sys_fcntl compat_sys_fcntl -#define sys_ustat compat_sys_ustat -#define sys_sigaction compat_sys_sigaction -#define sys_sigsuspend compat_sys_sigsuspend -#define sys_sigpending compat_sys_sigpending -#define sys_setrlimit compat_sys_setrlimit -#define sys_getrusage compat_sys_getrusage -#define sys_gettimeofday compat_sys_gettimeofday -#define sys_settimeofday compat_sys_settimeofday -#define sys_statfs compat_sys_statfs -#define sys_fstatfs compat_sys_fstatfs -#define sys_setitimer compat_sys_setitimer -#define sys_getitimer compat_sys_getitimer -#define sys_newstat compat_sys_newstat -#define sys_newlstat compat_sys_newlstat -#define sys_newfstat compat_sys_newfstat -#define sys_wait4 compat_sys_wait4 -#define sys_sysinfo compat_sys_sysinfo -#define sys_sigreturn compat_sys_sigreturn_wrapper -#define sys_clone compat_sys_clone_wrapper -#define sys_adjtimex compat_sys_adjtimex -#define sys_sigprocmask compat_sys_sigprocmask -#define sys_getdents compat_sys_getdents -#define sys_select compat_sys_select -#define sys_readv compat_sys_readv -#define sys_writev compat_sys_writev -#define sys_sysctl compat_sys_sysctl -#define sys_sched_rr_get_interval compat_sys_sched_rr_get_interval -#define sys_nanosleep compat_sys_nanosleep -#define sys_rt_sigreturn compat_sys_rt_sigreturn_wrapper -#define sys_rt_sigaction compat_sys_rt_sigaction -#define sys_rt_sigprocmask compat_sys_rt_sigprocmask -#define sys_rt_sigpending compat_sys_rt_sigpending -#define sys_rt_sigtimedwait compat_sys_rt_sigtimedwait -#define sys_rt_sigqueueinfo compat_sys_rt_sigqueueinfo -#define sys_rt_sigsuspend compat_sys_rt_sigsuspend -#define sys_pread64 compat_sys_pread64_wrapper -#define sys_pwrite64 compat_sys_pwrite64_wrapper -#define sys_sigaltstack compat_sys_sigaltstack_wrapper -#define sys_sendfile compat_sys_sendfile -#define sys_vfork compat_sys_vfork_wrapper -#define sys_getrlimit compat_sys_getrlimit -#define sys_mmap2 sys_mmap_pgoff -#define sys_truncate64 compat_sys_truncate64_wrapper -#define sys_ftruncate64 compat_sys_ftruncate64_wrapper -#define sys_getdents64 compat_sys_getdents64 -#define sys_fcntl64 compat_sys_fcntl64 -#define sys_readahead compat_sys_readahead_wrapper -#define sys_futex compat_sys_futex -#define sys_sched_setaffinity compat_sys_sched_setaffinity -#define sys_sched_getaffinity compat_sys_sched_getaffinity -#define sys_io_setup compat_sys_io_setup -#define sys_io_getevents compat_sys_io_getevents -#define sys_io_submit compat_sys_io_submit -#define sys_lookup_dcookie compat_sys_lookup_dcookie -#define sys_timer_create compat_sys_timer_create -#define sys_timer_settime compat_sys_timer_settime -#define sys_timer_gettime compat_sys_timer_gettime -#define sys_clock_settime compat_sys_clock_settime -#define sys_clock_gettime compat_sys_clock_gettime -#define sys_clock_getres compat_sys_clock_getres -#define sys_clock_nanosleep compat_sys_clock_nanosleep -#define sys_statfs64 compat_sys_statfs64_wrapper -#define sys_fstatfs64 compat_sys_fstatfs64_wrapper -#define sys_utimes compat_sys_utimes -#define sys_fadvise64_64 compat_sys_fadvise64_64_wrapper -#define sys_mq_open compat_sys_mq_open -#define sys_mq_timedsend compat_sys_mq_timedsend -#define sys_mq_timedreceive compat_sys_mq_timedreceive -#define sys_mq_notify compat_sys_mq_notify -#define sys_mq_getsetattr compat_sys_mq_getsetattr -#define sys_waitid compat_sys_waitid -#define sys_recv compat_sys_recv -#define sys_recvfrom compat_sys_recvfrom -#define sys_setsockopt compat_sys_setsockopt -#define sys_getsockopt compat_sys_getsockopt -#define sys_sendmsg compat_sys_sendmsg -#define sys_recvmsg compat_sys_recvmsg -#define sys_semctl compat_sys_semctl -#define sys_msgsnd compat_sys_msgsnd -#define sys_msgrcv compat_sys_msgrcv -#define sys_msgctl compat_sys_msgctl -#define sys_shmat compat_sys_shmat -#define sys_shmctl compat_sys_shmctl -#define sys_keyctl compat_sys_keyctl -#define sys_semtimedop compat_sys_semtimedop -#define sys_mbind compat_sys_mbind -#define sys_get_mempolicy compat_sys_get_mempolicy -#define sys_set_mempolicy compat_sys_set_mempolicy -#define sys_openat compat_sys_openat -#define sys_futimesat compat_sys_futimesat -#define sys_pselect6 compat_sys_pselect6 -#define sys_ppoll compat_sys_ppoll -#define sys_set_robust_list compat_sys_set_robust_list -#define sys_get_robust_list compat_sys_get_robust_list -#define sys_sync_file_range2 compat_sys_sync_file_range2_wrapper -#define sys_vmsplice compat_sys_vmsplice -#define sys_move_pages compat_sys_move_pages -#define sys_epoll_pwait compat_sys_epoll_pwait -#define sys_kexec_load compat_sys_kexec_load -#define sys_utimensat compat_sys_utimensat -#define sys_signalfd compat_sys_signalfd -#define sys_fallocate compat_sys_fallocate_wrapper -#define sys_timerfd_settime compat_sys_timerfd_settime -#define sys_timerfd_gettime compat_sys_timerfd_gettime -#define sys_signalfd4 compat_sys_signalfd4 -#define sys_preadv compat_sys_preadv -#define sys_pwritev compat_sys_pwritev -#define sys_rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo -#define sys_recvmmsg compat_sys_recvmmsg -#define sys_fanotify_mark compat_sys_fanotify_mark_wrapper - #undef __SYSCALL #define __SYSCALL(x, y) .quad y // x -#define __SYSCALL_COMPAT /* * The system calls table must be 4KB aligned. */ .align 12 ENTRY(compat_sys_call_table) -#include <asm/unistd.h> +#include <asm/unistd32.h> diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c index 93f10e27dc7..906e3bd270b 100644 --- a/arch/arm64/kernel/sys_compat.c +++ b/arch/arm64/kernel/sys_compat.c @@ -18,8 +18,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#define __SYSCALL_COMPAT - #include <linux/compat.h> #include <linux/personality.h> #include <linux/sched.h> @@ -28,7 +26,7 @@ #include <linux/uaccess.h> #include <asm/cacheflush.h> -#include <asm/unistd.h> +#include <asm/unistd32.h> asmlinkage int compat_sys_fork(struct pt_regs *regs) { @@ -56,14 +54,14 @@ asmlinkage int compat_sys_execve(const char __user *filenamei, struct pt_regs *regs) { int error; - char * filename; + struct filename *filename; filename = getname(filenamei); error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; - error = compat_do_execve(filename, compat_ptr(argv), compat_ptr(envp), - regs); + error = compat_do_execve(filename->name, compat_ptr(argv), + compat_ptr(envp), regs); putname(filename); out: return error; diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 17948fc7d66..ba457943a16 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -28,6 +28,7 @@ #include <linux/sched.h> #include <linux/signal.h> #include <linux/slab.h> +#include <linux/timekeeper_internal.h> #include <linux/vmalloc.h> #include <asm/cacheflush.h> @@ -222,11 +223,10 @@ struct vm_area_struct *get_gate_vma(struct mm_struct *mm) /* * Update the vDSO data page to keep in sync with kernel timekeeping. */ -void update_vsyscall(struct timespec *ts, struct timespec *wtm, - struct clocksource *clock, u32 mult) +void update_vsyscall(struct timekeeper *tk) { struct timespec xtime_coarse; - u32 use_syscall = strcmp(clock->name, "arch_sys_counter"); + u32 use_syscall = strcmp(tk->clock->name, "arch_sys_counter"); ++vdso_data->tb_seq_count; smp_wmb(); @@ -237,13 +237,13 @@ void update_vsyscall(struct timespec *ts, struct timespec *wtm, vdso_data->xtime_coarse_nsec = xtime_coarse.tv_nsec; if (!use_syscall) { - vdso_data->cs_cycle_last = clock->cycle_last; - vdso_data->xtime_clock_sec = ts->tv_sec; - vdso_data->xtime_clock_nsec = ts->tv_nsec; - vdso_data->cs_mult = mult; - vdso_data->cs_shift = clock->shift; - vdso_data->wtm_clock_sec = wtm->tv_sec; - vdso_data->wtm_clock_nsec = wtm->tv_nsec; + vdso_data->cs_cycle_last = tk->clock->cycle_last; + vdso_data->xtime_clock_sec = tk->xtime_sec; + vdso_data->xtime_clock_nsec = tk->xtime_nsec >> tk->shift; + vdso_data->cs_mult = tk->mult; + vdso_data->cs_shift = tk->shift; + vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec; + vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec; } smp_wmb(); |