Changes in 4.9.225 igb: use igb_adapter->io_addr instead of e1000_hw->hw_addr padata: Remove unused but set variables padata: get_next is never NULL padata: ensure the reorder timer callback runs on the correct CPU padata: ensure padata_do_serial() runs on the correct CPU evm: Check also if *tfm is an error pointer in init_desc() ima: Fix return value of ima_write_policy() fix multiplication overflow in copy_fdtable() iommu/amd: Fix over-read of ACPI UID from IVRS table i2c: mux: demux-pinctrl: Fix an error handling path in 'i2c_demux_pinctrl_probe()' gcc-common.h: Update for GCC 10 HID: multitouch: add eGalaxTouch P80H84 support configfs: fix config_item refcnt leak in configfs_rmdir() component: Silence bind error on -EPROBE_DEFER gtp: set NLM_F_MULTI flag in gtp_genl_dump_pdp() ceph: fix double unlock in handle_cap_export() USB: core: Fix misleading driver bug report platform/x86: asus-nb-wmi: Do not load on Asus T100TA and T200TA ARM: futex: Address build warning i2c: dev: Fix the race between the release of i2c_dev and cdev padata: set cpu_index of unused CPUs to -1 padata: Replace delayed timer with immediate workqueue in padata_reorder padata: initialize pd->cpu with effective cpumask padata: purge get_cpu and reorder_via_wq from padata_do_serial arm64: fix the flush_icache_range arguments in machine_kexec watchdog: Fix the race between the release of watchdog_core_data and cdev net: l2tp: export debug flags to UAPI net: l2tp: deprecate PPPOL2TP_MSG_* in favour of L2TP_MSG_* net: l2tp: ppp: change PPPOL2TP_MSG_* => L2TP_MSG_* New kernel function to get IP overhead on a socket. L2TP:Adjust intf MTU, add underlay L3, L2 hdrs. l2tp: remove useless duplicate session detection in l2tp_netlink l2tp: remove l2tp_session_find() l2tp: define parameters of l2tp_session_get*() as "const" l2tp: define parameters of l2tp_tunnel_find*() as "const" l2tp: initialise session's refcount before making it reachable l2tp: hold tunnel while looking up sessions in l2tp_netlink l2tp: hold tunnel while processing genl delete command l2tp: hold tunnel while handling genl tunnel updates l2tp: hold tunnel while handling genl TUNNEL_GET commands l2tp: hold tunnel used while creating sessions with netlink l2tp: prevent creation of sessions on terminated tunnels l2tp: pass tunnel pointer to ->session_create() l2tp: fix l2tp_eth module loading l2tp: don't register sessions in l2tp_session_create() l2tp: initialise l2tp_eth sessions before registering them l2tp: protect sock pointer of struct pppol2tp_session with RCU l2tp: initialise PPP sessions before registering them ALSA: pcm: fix incorrect hw_base increase dmaengine: tegra210-adma: Fix an error handling path in 'tegra_adma_probe()' l2tp: device MTU setup, tunnel socket needs a lock x86/uaccess, ubsan: Fix UBSAN vs. SMAP ubsan: build ubsan.c more conservatively platform/x86: alienware-wmi: fix kfree on potentially uninitialized pointer libnvdimm/btt: Remove unnecessary code in btt_freelist_init cxgb4: free mac_hlist properly cxgb4/cxgb4vf: Fix mac_hlist initialization and free Revert "gfs2: Don't demote a glock until its revokes are written" staging: iio: ad2s1210: Fix SPI reading staging: greybus: Fix uninitialized scalar variable iio: dac: vf610: Fix an error handling path in 'vf610_dac_probe()' mei: release me_cl object reference rapidio: fix an error in get_user_pages_fast() error handling iio: sca3000: Remove an erroneous 'get_device()' Linux 4.9.225 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I5183590d1e0ef7ea6623cf70c753ea169d0fd8a1
178 lines
4.2 KiB
C
178 lines
4.2 KiB
C
#ifndef _ASM_ARM_FUTEX_H
|
|
#define _ASM_ARM_FUTEX_H
|
|
|
|
#ifdef __KERNEL__
|
|
|
|
#include <linux/futex.h>
|
|
#include <linux/uaccess.h>
|
|
#include <asm/errno.h>
|
|
|
|
#define __futex_atomic_ex_table(err_reg) \
|
|
"3:\n" \
|
|
" .pushsection __ex_table,\"a\"\n" \
|
|
" .align 3\n" \
|
|
" .long 1b, 4f, 2b, 4f\n" \
|
|
" .popsection\n" \
|
|
" .pushsection .text.fixup,\"ax\"\n" \
|
|
" .align 2\n" \
|
|
"4: mov %0, " err_reg "\n" \
|
|
" b 3b\n" \
|
|
" .popsection"
|
|
|
|
#ifdef CONFIG_SMP
|
|
|
|
#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \
|
|
({ \
|
|
unsigned int __ua_flags; \
|
|
smp_mb(); \
|
|
prefetchw(uaddr); \
|
|
__ua_flags = uaccess_save_and_enable(); \
|
|
__asm__ __volatile__( \
|
|
"1: ldrex %1, [%3]\n" \
|
|
" " insn "\n" \
|
|
"2: strex %2, %0, [%3]\n" \
|
|
" teq %2, #0\n" \
|
|
" bne 1b\n" \
|
|
" mov %0, #0\n" \
|
|
__futex_atomic_ex_table("%5") \
|
|
: "=&r" (ret), "=&r" (oldval), "=&r" (tmp) \
|
|
: "r" (uaddr), "r" (oparg), "Ir" (-EFAULT) \
|
|
: "cc", "memory"); \
|
|
uaccess_restore(__ua_flags); \
|
|
})
|
|
|
|
static inline int
|
|
futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
|
|
u32 oldval, u32 newval)
|
|
{
|
|
unsigned int __ua_flags;
|
|
int ret;
|
|
u32 val;
|
|
|
|
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
|
|
return -EFAULT;
|
|
|
|
smp_mb();
|
|
/* Prefetching cannot fault */
|
|
prefetchw(uaddr);
|
|
__ua_flags = uaccess_save_and_enable();
|
|
__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
|
|
"1: ldrex %1, [%4]\n"
|
|
" teq %1, %2\n"
|
|
" ite eq @ explicit IT needed for the 2b label\n"
|
|
"2: strexeq %0, %3, [%4]\n"
|
|
" movne %0, #0\n"
|
|
" teq %0, #0\n"
|
|
" bne 1b\n"
|
|
__futex_atomic_ex_table("%5")
|
|
: "=&r" (ret), "=&r" (val)
|
|
: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
|
|
: "cc", "memory");
|
|
uaccess_restore(__ua_flags);
|
|
smp_mb();
|
|
|
|
*uval = val;
|
|
return ret;
|
|
}
|
|
|
|
#else /* !SMP, we can work around lack of atomic ops by disabling preemption */
|
|
|
|
#include <linux/preempt.h>
|
|
#include <asm/domain.h>
|
|
|
|
#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \
|
|
({ \
|
|
unsigned int __ua_flags = uaccess_save_and_enable(); \
|
|
__asm__ __volatile__( \
|
|
"1: " TUSER(ldr) " %1, [%3]\n" \
|
|
" " insn "\n" \
|
|
"2: " TUSER(str) " %0, [%3]\n" \
|
|
" mov %0, #0\n" \
|
|
__futex_atomic_ex_table("%5") \
|
|
: "=&r" (ret), "=&r" (oldval), "=&r" (tmp) \
|
|
: "r" (uaddr), "r" (oparg), "Ir" (-EFAULT) \
|
|
: "cc", "memory"); \
|
|
uaccess_restore(__ua_flags); \
|
|
})
|
|
|
|
static inline int
|
|
futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
|
|
u32 oldval, u32 newval)
|
|
{
|
|
unsigned int __ua_flags;
|
|
int ret = 0;
|
|
u32 val;
|
|
|
|
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
|
|
return -EFAULT;
|
|
|
|
preempt_disable();
|
|
__ua_flags = uaccess_save_and_enable();
|
|
__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
|
|
"1: " TUSER(ldr) " %1, [%4]\n"
|
|
" teq %1, %2\n"
|
|
" it eq @ explicit IT needed for the 2b label\n"
|
|
"2: " TUSER(streq) " %3, [%4]\n"
|
|
__futex_atomic_ex_table("%5")
|
|
: "+r" (ret), "=&r" (val)
|
|
: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
|
|
: "cc", "memory");
|
|
uaccess_restore(__ua_flags);
|
|
|
|
*uval = val;
|
|
preempt_enable();
|
|
|
|
return ret;
|
|
}
|
|
|
|
#endif /* !SMP */
|
|
|
|
static inline int
|
|
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
|
|
{
|
|
int oldval = 0, ret, tmp;
|
|
|
|
#ifndef CONFIG_SMP
|
|
preempt_disable();
|
|
#endif
|
|
pagefault_disable();
|
|
|
|
switch (op) {
|
|
case FUTEX_OP_SET:
|
|
__futex_atomic_op("mov %0, %4", ret, oldval, tmp, uaddr, oparg);
|
|
break;
|
|
case FUTEX_OP_ADD:
|
|
__futex_atomic_op("add %0, %1, %4", ret, oldval, tmp, uaddr, oparg);
|
|
break;
|
|
case FUTEX_OP_OR:
|
|
__futex_atomic_op("orr %0, %1, %4", ret, oldval, tmp, uaddr, oparg);
|
|
break;
|
|
case FUTEX_OP_ANDN:
|
|
__futex_atomic_op("and %0, %1, %4", ret, oldval, tmp, uaddr, ~oparg);
|
|
break;
|
|
case FUTEX_OP_XOR:
|
|
__futex_atomic_op("eor %0, %1, %4", ret, oldval, tmp, uaddr, oparg);
|
|
break;
|
|
default:
|
|
ret = -ENOSYS;
|
|
}
|
|
|
|
pagefault_enable();
|
|
#ifndef CONFIG_SMP
|
|
preempt_enable();
|
|
#endif
|
|
|
|
/*
|
|
* Store unconditionally. If ret != 0 the extra store is the least
|
|
* of the worries but GCC cannot figure out that __futex_atomic_op()
|
|
* is either setting ret to -EFAULT or storing the old value in
|
|
* oldval which results in a uninitialized warning at the call site.
|
|
*/
|
|
*oval = oldval;
|
|
|
|
return ret;
|
|
}
|
|
|
|
#endif /* __KERNEL__ */
|
|
#endif /* _ASM_ARM_FUTEX_H */
|