Merge branch 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm

Pull ARM updates from Russell King:
 "The main item in this pull request are the Spectre variant 1.1 fixes
  from Julien Thierry.

  A few other patches to improve various areas, and removal of some
  obsolete mcount bits and a redundant kbuild conditional"

* 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm:
  ARM: 8802/1: Call syscall_trace_exit even when system call skipped
  ARM: 8797/1: spectre-v1.1: harden __copy_to_user
  ARM: 8796/1: spectre-v1,v1.1: provide helpers for address sanitization
  ARM: 8795/1: spectre-v1.1: use put_user() for __put_user()
  ARM: 8794/1: uaccess: Prevent speculative use of the current addr_limit
  ARM: 8793/1: signal: replace __put_user_error with __put_user
  ARM: 8792/1: oabi-compat: copy oabi events using __copy_to_user()
  ARM: 8791/1: vfp: use __copy_to_user() when saving VFP state
  ARM: 8790/1: signal: always use __copy_to_user to save iwmmxt context
  ARM: 8789/1: signal: copy registers using __copy_to_user()
  ARM: 8801/1: makefile: use ARMv3M mode for RiscPC
  ARM: 8800/1: use choice for kernel unwinders
  ARM: 8798/1: remove unnecessary KBUILD_SRC ifeq conditional
  ARM: 8788/1: ftrace: remove old mcount support
  ARM: 8786/1: Debug kernel copy by printing
This commit is contained in:
Linus Torvalds
2018-10-23 19:32:10 +01:00
18 changed files with 202 additions and 224 deletions

View File

@@ -167,9 +167,6 @@ EXPORT_SYMBOL(_find_next_bit_be);
#endif
#ifdef CONFIG_FUNCTION_TRACER
#ifdef CONFIG_OLD_MCOUNT
EXPORT_SYMBOL(mcount);
#endif
EXPORT_SYMBOL(__gnu_mcount_nc);
#endif

View File

@@ -296,16 +296,15 @@ __sys_trace:
cmp scno, #-1 @ skip the syscall?
bne 2b
add sp, sp, #S_OFF @ restore stack
b ret_slow_syscall
__sys_trace_return:
str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
__sys_trace_return_nosave:
enable_irq_notrace
mov r0, sp
bl syscall_trace_exit
b ret_slow_syscall
__sys_trace_return_nosave:
enable_irq_notrace
__sys_trace_return:
str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
mov r0, sp
bl syscall_trace_exit
b ret_slow_syscall

View File

@@ -15,23 +15,8 @@
* start of every function. In mcount, apart from the function's address (in
* lr), we need to get hold of the function's caller's address.
*
* Older GCCs (pre-4.4) inserted a call to a routine called mcount like this:
*
* bl mcount
*
* These versions have the limitation that in order for the mcount routine to
* be able to determine the function's caller's address, an APCS-style frame
* pointer (which is set up with something like the code below) is required.
*
* mov ip, sp
* push {fp, ip, lr, pc}
* sub fp, ip, #4
*
* With EABI, these frame pointers are not available unless -mapcs-frame is
* specified, and if building as Thumb-2, not even then.
*
* Newer GCCs (4.4+) solve this problem by introducing a new version of mcount,
* with call sites like:
* Newer GCCs (4.4+) solve this problem by using a version of mcount with call
* sites like:
*
* push {lr}
* bl __gnu_mcount_nc
@@ -46,17 +31,10 @@
* allows it to be clobbered in subroutines and doesn't use it to hold
* parameters.)
*
* When using dynamic ftrace, we patch out the mcount call by a "mov r0, r0"
* for the mcount case, and a "pop {lr}" for the __gnu_mcount_nc case (see
* arch/arm/kernel/ftrace.c).
* When using dynamic ftrace, we patch out the mcount call by a "pop {lr}"
* instead of the __gnu_mcount_nc call (see arch/arm/kernel/ftrace.c).
*/
#ifndef CONFIG_OLD_MCOUNT
#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
#error Ftrace requires CONFIG_FRAME_POINTER=y with GCC older than 4.4.0.
#endif
#endif
.macro mcount_adjust_addr rd, rn
bic \rd, \rn, #1 @ clear the Thumb bit if present
sub \rd, \rd, #MCOUNT_INSN_SIZE
@@ -209,51 +187,6 @@ ftrace_graph_call\suffix:
mcount_exit
.endm
#ifdef CONFIG_OLD_MCOUNT
/*
* mcount
*/
.macro mcount_enter
stmdb sp!, {r0-r3, lr}
.endm
.macro mcount_get_lr reg
ldr \reg, [fp, #-4]
.endm
.macro mcount_exit
ldr lr, [fp, #-4]
ldmia sp!, {r0-r3, pc}
.endm
ENTRY(mcount)
#ifdef CONFIG_DYNAMIC_FTRACE
stmdb sp!, {lr}
ldr lr, [fp, #-4]
ldmia sp!, {pc}
#else
__mcount _old
#endif
ENDPROC(mcount)
#ifdef CONFIG_DYNAMIC_FTRACE
ENTRY(ftrace_caller_old)
__ftrace_caller _old
ENDPROC(ftrace_caller_old)
#endif
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
ENTRY(ftrace_graph_caller_old)
__ftrace_graph_caller
ENDPROC(ftrace_graph_caller_old)
#endif
.purgem mcount_enter
.purgem mcount_get_lr
.purgem mcount_exit
#endif
/*
* __gnu_mcount_nc
*/

View File

@@ -47,30 +47,6 @@ void arch_ftrace_update_code(int command)
stop_machine(__ftrace_modify_code, &command, NULL);
}
#ifdef CONFIG_OLD_MCOUNT
#define OLD_MCOUNT_ADDR ((unsigned long) mcount)
#define OLD_FTRACE_ADDR ((unsigned long) ftrace_caller_old)
#define OLD_NOP 0xe1a00000 /* mov r0, r0 */
static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec)
{
return rec->arch.old_mcount ? OLD_NOP : NOP;
}
static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr)
{
if (!rec->arch.old_mcount)
return addr;
if (addr == MCOUNT_ADDR)
addr = OLD_MCOUNT_ADDR;
else if (addr == FTRACE_ADDR)
addr = OLD_FTRACE_ADDR;
return addr;
}
#else
static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec)
{
return NOP;
@@ -80,7 +56,6 @@ static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr)
{
return addr;
}
#endif
int ftrace_arch_code_modify_prepare(void)
{
@@ -150,15 +125,6 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
}
#endif
#ifdef CONFIG_OLD_MCOUNT
if (!ret) {
pc = (unsigned long)&ftrace_call_old;
new = ftrace_call_replace(pc, (unsigned long)func);
ret = ftrace_modify_code(pc, 0, new, false);
}
#endif
return ret;
}
@@ -203,16 +169,6 @@ int ftrace_make_nop(struct module *mod,
new = ftrace_nop_replace(rec);
ret = ftrace_modify_code(ip, old, new, true);
#ifdef CONFIG_OLD_MCOUNT
if (ret == -EINVAL && addr == MCOUNT_ADDR) {
rec->arch.old_mcount = true;
old = ftrace_call_replace(ip, adjust_address(rec, addr));
new = ftrace_nop_replace(rec);
ret = ftrace_modify_code(ip, old, new, true);
}
#endif
return ret;
}
@@ -290,13 +246,6 @@ static int ftrace_modify_graph_caller(bool enable)
#endif
#ifdef CONFIG_OLD_MCOUNT
if (!ret)
ret = __ftrace_modify_caller(&ftrace_graph_call_old,
ftrace_graph_caller_old,
enable);
#endif
return ret;
}

View File

@@ -77,8 +77,6 @@ static int preserve_iwmmxt_context(struct iwmmxt_sigframe __user *frame)
kframe->magic = IWMMXT_MAGIC;
kframe->size = IWMMXT_STORAGE_SIZE;
iwmmxt_task_copy(current_thread_info(), &kframe->storage);
err = __copy_to_user(frame, kframe, sizeof(*frame));
} else {
/*
* For bug-compatibility with older kernels, some space
@@ -86,10 +84,14 @@ static int preserve_iwmmxt_context(struct iwmmxt_sigframe __user *frame)
* Set the magic and size appropriately so that properly
* written userspace can skip it reliably:
*/
__put_user_error(DUMMY_MAGIC, &frame->magic, err);
__put_user_error(IWMMXT_STORAGE_SIZE, &frame->size, err);
*kframe = (struct iwmmxt_sigframe) {
.magic = DUMMY_MAGIC,
.size = IWMMXT_STORAGE_SIZE,
};
}
err = __copy_to_user(frame, kframe, sizeof(*kframe));
return err;
}
@@ -135,17 +137,18 @@ static int restore_iwmmxt_context(char __user **auxp)
static int preserve_vfp_context(struct vfp_sigframe __user *frame)
{
const unsigned long magic = VFP_MAGIC;
const unsigned long size = VFP_STORAGE_SIZE;
struct vfp_sigframe kframe;
int err = 0;
__put_user_error(magic, &frame->magic, err);
__put_user_error(size, &frame->size, err);
memset(&kframe, 0, sizeof(kframe));
kframe.magic = VFP_MAGIC;
kframe.size = VFP_STORAGE_SIZE;
err = vfp_preserve_user_clear_hwstate(&kframe.ufp, &kframe.ufp_exc);
if (err)
return -EFAULT;
return err;
return vfp_preserve_user_clear_hwstate(&frame->ufp, &frame->ufp_exc);
return __copy_to_user(frame, &kframe, sizeof(kframe));
}
static int restore_vfp_context(char __user **auxp)
@@ -288,30 +291,35 @@ static int
setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
{
struct aux_sigframe __user *aux;
struct sigcontext context;
int err = 0;
__put_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err);
__put_user_error(regs->ARM_r1, &sf->uc.uc_mcontext.arm_r1, err);
__put_user_error(regs->ARM_r2, &sf->uc.uc_mcontext.arm_r2, err);
__put_user_error(regs->ARM_r3, &sf->uc.uc_mcontext.arm_r3, err);
__put_user_error(regs->ARM_r4, &sf->uc.uc_mcontext.arm_r4, err);
__put_user_error(regs->ARM_r5, &sf->uc.uc_mcontext.arm_r5, err);
__put_user_error(regs->ARM_r6, &sf->uc.uc_mcontext.arm_r6, err);
__put_user_error(regs->ARM_r7, &sf->uc.uc_mcontext.arm_r7, err);
__put_user_error(regs->ARM_r8, &sf->uc.uc_mcontext.arm_r8, err);
__put_user_error(regs->ARM_r9, &sf->uc.uc_mcontext.arm_r9, err);
__put_user_error(regs->ARM_r10, &sf->uc.uc_mcontext.arm_r10, err);
__put_user_error(regs->ARM_fp, &sf->uc.uc_mcontext.arm_fp, err);
__put_user_error(regs->ARM_ip, &sf->uc.uc_mcontext.arm_ip, err);
__put_user_error(regs->ARM_sp, &sf->uc.uc_mcontext.arm_sp, err);
__put_user_error(regs->ARM_lr, &sf->uc.uc_mcontext.arm_lr, err);
__put_user_error(regs->ARM_pc, &sf->uc.uc_mcontext.arm_pc, err);
__put_user_error(regs->ARM_cpsr, &sf->uc.uc_mcontext.arm_cpsr, err);
context = (struct sigcontext) {
.arm_r0 = regs->ARM_r0,
.arm_r1 = regs->ARM_r1,
.arm_r2 = regs->ARM_r2,
.arm_r3 = regs->ARM_r3,
.arm_r4 = regs->ARM_r4,
.arm_r5 = regs->ARM_r5,
.arm_r6 = regs->ARM_r6,
.arm_r7 = regs->ARM_r7,
.arm_r8 = regs->ARM_r8,
.arm_r9 = regs->ARM_r9,
.arm_r10 = regs->ARM_r10,
.arm_fp = regs->ARM_fp,
.arm_ip = regs->ARM_ip,
.arm_sp = regs->ARM_sp,
.arm_lr = regs->ARM_lr,
.arm_pc = regs->ARM_pc,
.arm_cpsr = regs->ARM_cpsr,
__put_user_error(current->thread.trap_no, &sf->uc.uc_mcontext.trap_no, err);
__put_user_error(current->thread.error_code, &sf->uc.uc_mcontext.error_code, err);
__put_user_error(current->thread.address, &sf->uc.uc_mcontext.fault_address, err);
__put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err);
.trap_no = current->thread.trap_no,
.error_code = current->thread.error_code,
.fault_address = current->thread.address,
.oldmask = set->sig[0],
};
err |= __copy_to_user(&sf->uc.uc_mcontext, &context, sizeof(context));
err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
@@ -328,7 +336,7 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
if (err == 0)
err |= preserve_vfp_context(&aux->vfp);
#endif
__put_user_error(0, &aux->end_magic, err);
err |= __put_user(0, &aux->end_magic);
return err;
}
@@ -491,7 +499,7 @@ setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
/*
* Set uc.uc_flags to a value which sc.trap_no would never have.
*/
__put_user_error(0x5ac3c35a, &frame->uc.uc_flags, err);
err = __put_user(0x5ac3c35a, &frame->uc.uc_flags);
err |= setup_sigframe(frame, regs, set);
if (err == 0)
@@ -511,8 +519,8 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
err |= copy_siginfo_to_user(&frame->info, &ksig->info);
__put_user_error(0, &frame->sig.uc.uc_flags, err);
__put_user_error(NULL, &frame->sig.uc.uc_link, err);
err |= __put_user(0, &frame->sig.uc.uc_flags);
err |= __put_user(NULL, &frame->sig.uc.uc_link);
err |= __save_altstack(&frame->sig.uc.uc_stack, regs->ARM_sp);
err |= setup_sigframe(&frame->sig, regs, set);

View File

@@ -277,6 +277,7 @@ asmlinkage long sys_oabi_epoll_wait(int epfd,
int maxevents, int timeout)
{
struct epoll_event *kbuf;
struct oabi_epoll_event e;
mm_segment_t fs;
long ret, err, i;
@@ -295,8 +296,11 @@ asmlinkage long sys_oabi_epoll_wait(int epfd,
set_fs(fs);
err = 0;
for (i = 0; i < ret; i++) {
__put_user_error(kbuf[i].events, &events->events, err);
__put_user_error(kbuf[i].data, &events->data, err);
e.events = kbuf[i].events;
e.data = kbuf[i].data;
err = __copy_to_user(events, &e, sizeof(e));
if (err)
break;
events++;
}
kfree(kbuf);