aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-07-20 11:33:22 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-07-20 11:33:22 -0700
commit2a0ea7df1ffb6bb46a8cf9b4d6f0bfca1e93a761 (patch)
treea43cc1e72a06e90cac3e1dd96eb6ec6c35d9db1e /arch/arc/kernel
parentMerge tag 'nds32-for-linus-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/greentime/linux (diff)
parentARCv2: [plat-hsdk]: Save accl reg pair by default (diff)
downloadlinux-dev-2a0ea7df1ffb6bb46a8cf9b4d6f0bfca1e93a761.tar.xz
linux-dev-2a0ea7df1ffb6bb46a8cf9b4d6f0bfca1e93a761.zip
Merge tag 'arc-4.18-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc
Pull ARC fixes from Vineet Gupta: "ARC is back after radio silence in 4.17: - Fix CONFIG_SWAP [Alexey] - Robustify cmpxchg emulation for systems w/o atomics [Alexey / PeterZ] - Allow mprotext(PROT_EXEC) for stack mappings [Vineet] - HSDK platform enable PCIe, APG GPIO [Gustavo] - miscll other fixes, config updates etc" * tag 'arc-4.18-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc: ARCv2: [plat-hsdk]: Save accl reg pair by default ARC: mm: allow mprotect to make stack mappings executable ARC: Fix CONFIG_SWAP ARC: [arcompact] entry.S: minor code movement ARC: configs: Remove CONFIG_INITRAMFS_SOURCE from defconfigs ARC: configs: remove no longer needed CONFIG_DEVPTS_MULTIPLE_INSTANCES ARC: Improve cmpxchg syscall implementation ARC: [plat-hsdk]: Configure APB GPIO controller on ARC HSDK platform ARC: [plat-hsdk] Add PCIe support ARC: Enable machine_desc->init_per_cpu for !CONFIG_SMP ARC: Explicitly add -mmedium-calls to CFLAGS
Diffstat (limited to 'arch/arc/kernel')
-rw-r--r--arch/arc/kernel/irq.c2
-rw-r--r--arch/arc/kernel/process.c47
2 files changed, 37 insertions, 12 deletions
diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c
index 538b36afe89e..62b185057c04 100644
--- a/arch/arc/kernel/irq.c
+++ b/arch/arc/kernel/irq.c
@@ -31,10 +31,10 @@ void __init init_IRQ(void)
/* a SMP H/w block could do IPI IRQ request here */
if (plat_smp_ops.init_per_cpu)
plat_smp_ops.init_per_cpu(smp_processor_id());
+#endif
if (machine_desc->init_per_cpu)
machine_desc->init_per_cpu(smp_processor_id());
-#endif
}
/*
diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c
index 5ac3b547453f..4674541eba3f 100644
--- a/arch/arc/kernel/process.c
+++ b/arch/arc/kernel/process.c
@@ -47,7 +47,8 @@ SYSCALL_DEFINE0(arc_gettls)
SYSCALL_DEFINE3(arc_usr_cmpxchg, int *, uaddr, int, expected, int, new)
{
struct pt_regs *regs = current_pt_regs();
- int uval = -EFAULT;
+ u32 uval;
+ int ret;
/*
* This is only for old cores lacking LLOCK/SCOND, which by defintion
@@ -60,23 +61,47 @@ SYSCALL_DEFINE3(arc_usr_cmpxchg, int *, uaddr, int, expected, int, new)
/* Z indicates to userspace if operation succeded */
regs->status32 &= ~STATUS_Z_MASK;
- if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
- return -EFAULT;
+ ret = access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr));
+ if (!ret)
+ goto fail;
+again:
preempt_disable();
- if (__get_user(uval, uaddr))
- goto done;
+ ret = __get_user(uval, uaddr);
+ if (ret)
+ goto fault;
- if (uval == expected) {
- if (!__put_user(new, uaddr))
- regs->status32 |= STATUS_Z_MASK;
- }
+ if (uval != expected)
+ goto out;
-done:
- preempt_enable();
+ ret = __put_user(new, uaddr);
+ if (ret)
+ goto fault;
+
+ regs->status32 |= STATUS_Z_MASK;
+out:
+ preempt_enable();
return uval;
+
+fault:
+ preempt_enable();
+
+ if (unlikely(ret != -EFAULT))
+ goto fail;
+
+ down_read(&current->mm->mmap_sem);
+ ret = fixup_user_fault(current, current->mm, (unsigned long) uaddr,
+ FAULT_FLAG_WRITE, NULL);
+ up_read(&current->mm->mmap_sem);
+
+ if (likely(!ret))
+ goto again;
+
+fail:
+ force_sig(SIGSEGV, current);
+ return ret;
}
#ifdef CONFIG_ISA_ARCV2