-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAlkm0zAACgkQONu9yGCS aT5QnxAAh9uZYFJtQ7wYngD7cQcDH1KVztqEYxCP5OtxzAZBrSNBufLdhKBbc1ZP C04Mo+FzzNiJtBwkmlOqYaEPYUSx/uwCEk9mNX85VtchIhKBrwWF7GxkeXCPs6e5 yP5TUXmxbbSp3qM4q2Z4XSW8eEPZ2l3zoy0fkjz2kS02e4RW0yQ34dvzw0BG2urr +9ocyVjDBoU3QNKyVw3fd1AltKesSZK0fa2vEO+TOTW6Bm3xD4egCJdOzu9saUwK hfSKXsJ0/pf1r1iyfz2foR/Hi3i4j6vRqnneyqozT7nxEJEuBQ3B5WhnsbDfzrXu +CY23KBkDkQ1RBngmtTQd3ABHEN1E2StpBImG5RUr+5giV6/e4rdz0/HWGMvCvAz iWqXdgZNdCnc96HPEWaDGUKxndCxsiaJOhgZwW2zm/0drVWRE+vjsOmFLyUp2Ky1 1vnKfwlvTFU4xjQ5H44AuuSHQsv+GNEtPPIHrbBv/wg90/2VuF0aYuNYjHSsc4Ca 3YM53S6/sjQqmsKixWboax8Kh2wRrEuFbqSFQV64JjFpGau61JQFMtRNl4+FFXzm Cm+26Fan4Wtyo5zB9xnBZbDwCOXqwTXQYUP2SejtObq+Uk2tXxF05emeta9pURF3 vdgv6N0cTPm4K3VZyBZvj8JitEr2OEaIxoUqE2BXkA1MPmbqOoI= =Z1no -----END PGP SIGNATURE----- Merge 4.4.70 into android-4.4 Changes in 4.4.70 usb: misc: legousbtower: Fix buffers on stack usb: misc: legousbtower: Fix memory leak USB: ene_usb6250: fix DMA to the stack watchdog: pcwd_usb: fix NULL-deref at probe char: lp: fix possible integer overflow in lp_setup() USB: core: replace %p with %pK ARM: tegra: paz00: Mark panel regulator as enabled on boot tpm_crb: check for bad response size infiniband: call ipv6 route lookup via the stub interface dm btree: fix for dm_btree_find_lowest_key() dm raid: select the Kconfig option CONFIG_MD_RAID0 dm bufio: avoid a possible ABBA deadlock dm bufio: check new buffer allocation watermark every 30 seconds dm cache metadata: fail operations if fail_io mode has been established dm bufio: make the parameter "retain_bytes" unsigned long dm thin metadata: call precommit before saving the roots dm space map disk: fix some book keeping in the disk space map md: update slab_cache before releasing new stripes when stripes resizing rtlwifi: rtl8821ae: setup 8812ae RFE according to device type mwifiex: pcie: fix cmd_buf use-after-free in remove/reset ima: accept previously set IMA_NEW_FILE KVM: x86: Fix load damaged SSEx MXCSR register KVM: X86: Fix read out-of-bounds vulnerability in kvm pio emulation regulator: tps65023: Fix inverted core enable logic. s390/kdump: Add final note s390/cputime: fix incorrect system time ath9k_htc: Add support of AirTies 1eda:2315 AR9271 device ath9k_htc: fix NULL-deref at probe drm/amdgpu: Avoid overflows/divide-by-zero in latency_watermark calculations. drm/amdgpu: Make display watermark calculations more accurate drm/nouveau/therm: remove ineffective workarounds for alarm bugs drm/nouveau/tmr: ack interrupt before processing alarms drm/nouveau/tmr: fix corruption of the pending list when rescheduling an alarm drm/nouveau/tmr: avoid processing completed alarms when adding a new one drm/nouveau/tmr: handle races with hw when updating the next alarm time cdc-acm: fix possible invalid access when processing notification proc: Fix unbalanced hard link numbers of: fix sparse warning in of_pci_range_parser_one iio: dac: ad7303: fix channel description pid_ns: Sleep in TASK_INTERRUPTIBLE in zap_pid_ns_processes pid_ns: Fix race between setns'ed fork() and zap_pid_ns_processes() USB: serial: ftdi_sio: fix setting latency for unprivileged users USB: serial: ftdi_sio: add Olimex ARM-USB-TINY(H) PIDs ext4 crypto: don't let data integrity writebacks fail with ENOMEM ext4 crypto: fix some error handling net: qmi_wwan: Add SIMCom 7230E fscrypt: fix context consistency check when key(s) unavailable f2fs: check entire encrypted bigname when finding a dentry fscrypt: avoid collisions when presenting long encrypted filenames sched/fair: Do not announce throttled next buddy in dequeue_task_fair() sched/fair: Initialize throttle_count for new task-groups lazily usb: host: xhci-plat: propagate return value of platform_get_irq() xhci: apply PME_STUCK_QUIRK and MISSING_CAS quirk for Denverton usb: host: xhci-mem: allocate zeroed Scratchpad Buffer net: irda: irda-usb: fix firmware name on big-endian hosts usbvision: fix NULL-deref at probe mceusb: fix NULL-deref at probe ttusb2: limit messages to buffer size usb: musb: tusb6010_omap: Do not reset the other direction's packet size USB: iowarrior: fix info ioctl on big-endian hosts usb: serial: option: add Telit ME910 support USB: serial: qcserial: add more Lenovo EM74xx device IDs USB: serial: mct_u232: fix big-endian baud-rate handling USB: serial: io_ti: fix div-by-zero in set_termios USB: hub: fix SS hub-descriptor handling USB: hub: fix non-SS hub-descriptor handling ipx: call ipxitf_put() in ioctl error path iio: proximity: as3935: fix as3935_write ceph: fix recursion between ceph_set_acl() and __ceph_setattr() gspca: konica: add missing endpoint sanity check s5p-mfc: Fix unbalanced call to clock management dib0700: fix NULL-deref at probe zr364xx: enforce minimum size when reading header dvb-frontends/cxd2841er: define symbol_rate_min/max in T/C fe-ops cx231xx-audio: fix init error path cx231xx-audio: fix NULL-deref at probe cx231xx-cards: fix NULL-deref at probe powerpc/book3s/mce: Move add_taint() later in virtual mode powerpc/pseries: Fix of_node_put() underflow during DLPAR remove powerpc/64e: Fix hang when debugging programs with relocated kernel ARM: dts: at91: sama5d3_xplained: fix ADC vref ARM: dts: at91: sama5d3_xplained: not all ADC channels are available arm64: xchg: hazard against entire exchange variable arm64: uaccess: ensure extension of access_ok() addr arm64: documentation: document tagged pointer stack constraints xc2028: Fix use-after-free bug properly mm/huge_memory.c: respect FOLL_FORCE/FOLL_COW for thp staging: rtl8192e: fix 2 byte alignment of register BSSIDR. staging: rtl8192e: rtl92e_get_eeprom_size Fix read size of EPROM_CMD. iommu/vt-d: Flush the IOTLB to get rid of the initial kdump mappings metag/uaccess: Fix access_ok() metag/uaccess: Check access_ok in strncpy_from_user uwb: fix device quirk on big-endian hosts genirq: Fix chained interrupt data ordering osf_wait4(): fix infoleak tracing/kprobes: Enforce kprobes teardown after testing PCI: Fix pci_mmap_fits() for HAVE_PCI_RESOURCE_TO_USER platforms PCI: Freeze PME scan before suspending devices drm/edid: Add 10 bpc quirk for LGD 764 panel in HP zBook 17 G2 nfsd: encoders mustn't use unitialized values in error cases drivers: char: mem: Check for address space wraparound with mmap() Linux 4.4.70 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
227 lines
6.7 KiB
C
227 lines
6.7 KiB
C
/*
|
|
* Based on arch/arm/include/asm/cmpxchg.h
|
|
*
|
|
* Copyright (C) 2012 ARM Ltd.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#ifndef __ASM_CMPXCHG_H
|
|
#define __ASM_CMPXCHG_H
|
|
|
|
#include <linux/bug.h>
|
|
|
|
#include <asm/atomic.h>
|
|
#include <asm/barrier.h>
|
|
#include <asm/lse.h>
|
|
|
|
/*
|
|
* We need separate acquire parameters for ll/sc and lse, since the full
|
|
* barrier case is generated as release+dmb for the former and
|
|
* acquire+release for the latter.
|
|
*/
|
|
#define __XCHG_CASE(w, sz, name, mb, nop_lse, acq, acq_lse, rel, cl) \
|
|
static inline unsigned long __xchg_case_##name(unsigned long x, \
|
|
volatile void *ptr) \
|
|
{ \
|
|
unsigned long ret, tmp; \
|
|
\
|
|
asm volatile(ARM64_LSE_ATOMIC_INSN( \
|
|
/* LL/SC */ \
|
|
" prfm pstl1strm, %2\n" \
|
|
"1: ld" #acq "xr" #sz "\t%" #w "0, %2\n" \
|
|
" st" #rel "xr" #sz "\t%w1, %" #w "3, %2\n" \
|
|
" cbnz %w1, 1b\n" \
|
|
" " #mb, \
|
|
/* LSE atomics */ \
|
|
" nop\n" \
|
|
" nop\n" \
|
|
" swp" #acq_lse #rel #sz "\t%" #w "3, %" #w "0, %2\n" \
|
|
" nop\n" \
|
|
" " #nop_lse) \
|
|
: "=&r" (ret), "=&r" (tmp), "+Q" (*(unsigned long *)ptr) \
|
|
: "r" (x) \
|
|
: cl); \
|
|
\
|
|
return ret; \
|
|
}
|
|
|
|
__XCHG_CASE(w, b, 1, , , , , , )
|
|
__XCHG_CASE(w, h, 2, , , , , , )
|
|
__XCHG_CASE(w, , 4, , , , , , )
|
|
__XCHG_CASE( , , 8, , , , , , )
|
|
__XCHG_CASE(w, b, acq_1, , , a, a, , "memory")
|
|
__XCHG_CASE(w, h, acq_2, , , a, a, , "memory")
|
|
__XCHG_CASE(w, , acq_4, , , a, a, , "memory")
|
|
__XCHG_CASE( , , acq_8, , , a, a, , "memory")
|
|
__XCHG_CASE(w, b, rel_1, , , , , l, "memory")
|
|
__XCHG_CASE(w, h, rel_2, , , , , l, "memory")
|
|
__XCHG_CASE(w, , rel_4, , , , , l, "memory")
|
|
__XCHG_CASE( , , rel_8, , , , , l, "memory")
|
|
__XCHG_CASE(w, b, mb_1, dmb ish, nop, , a, l, "memory")
|
|
__XCHG_CASE(w, h, mb_2, dmb ish, nop, , a, l, "memory")
|
|
__XCHG_CASE(w, , mb_4, dmb ish, nop, , a, l, "memory")
|
|
__XCHG_CASE( , , mb_8, dmb ish, nop, , a, l, "memory")
|
|
|
|
#undef __XCHG_CASE
|
|
|
|
#define __XCHG_GEN(sfx) \
|
|
static inline unsigned long __xchg##sfx(unsigned long x, \
|
|
volatile void *ptr, \
|
|
int size) \
|
|
{ \
|
|
switch (size) { \
|
|
case 1: \
|
|
return __xchg_case##sfx##_1(x, ptr); \
|
|
case 2: \
|
|
return __xchg_case##sfx##_2(x, ptr); \
|
|
case 4: \
|
|
return __xchg_case##sfx##_4(x, ptr); \
|
|
case 8: \
|
|
return __xchg_case##sfx##_8(x, ptr); \
|
|
default: \
|
|
BUILD_BUG(); \
|
|
} \
|
|
\
|
|
unreachable(); \
|
|
}
|
|
|
|
__XCHG_GEN()
|
|
__XCHG_GEN(_acq)
|
|
__XCHG_GEN(_rel)
|
|
__XCHG_GEN(_mb)
|
|
|
|
#undef __XCHG_GEN
|
|
|
|
#define __xchg_wrapper(sfx, ptr, x) \
|
|
({ \
|
|
__typeof__(*(ptr)) __ret; \
|
|
__ret = (__typeof__(*(ptr))) \
|
|
__xchg##sfx((unsigned long)(x), (ptr), sizeof(*(ptr))); \
|
|
__ret; \
|
|
})
|
|
|
|
/* xchg */
|
|
#define xchg_relaxed(...) __xchg_wrapper( , __VA_ARGS__)
|
|
#define xchg_acquire(...) __xchg_wrapper(_acq, __VA_ARGS__)
|
|
#define xchg_release(...) __xchg_wrapper(_rel, __VA_ARGS__)
|
|
#define xchg(...) __xchg_wrapper( _mb, __VA_ARGS__)
|
|
|
|
#define __CMPXCHG_GEN(sfx) \
|
|
static inline unsigned long __cmpxchg##sfx(volatile void *ptr, \
|
|
unsigned long old, \
|
|
unsigned long new, \
|
|
int size) \
|
|
{ \
|
|
switch (size) { \
|
|
case 1: \
|
|
return __cmpxchg_case##sfx##_1(ptr, (u8)old, new); \
|
|
case 2: \
|
|
return __cmpxchg_case##sfx##_2(ptr, (u16)old, new); \
|
|
case 4: \
|
|
return __cmpxchg_case##sfx##_4(ptr, old, new); \
|
|
case 8: \
|
|
return __cmpxchg_case##sfx##_8(ptr, old, new); \
|
|
default: \
|
|
BUILD_BUG(); \
|
|
} \
|
|
\
|
|
unreachable(); \
|
|
}
|
|
|
|
__CMPXCHG_GEN()
|
|
__CMPXCHG_GEN(_acq)
|
|
__CMPXCHG_GEN(_rel)
|
|
__CMPXCHG_GEN(_mb)
|
|
|
|
#undef __CMPXCHG_GEN
|
|
|
|
#define __cmpxchg_wrapper(sfx, ptr, o, n) \
|
|
({ \
|
|
__typeof__(*(ptr)) __ret; \
|
|
__ret = (__typeof__(*(ptr))) \
|
|
__cmpxchg##sfx((ptr), (unsigned long)(o), \
|
|
(unsigned long)(n), sizeof(*(ptr))); \
|
|
__ret; \
|
|
})
|
|
|
|
/* cmpxchg */
|
|
#define cmpxchg_relaxed(...) __cmpxchg_wrapper( , __VA_ARGS__)
|
|
#define cmpxchg_acquire(...) __cmpxchg_wrapper(_acq, __VA_ARGS__)
|
|
#define cmpxchg_release(...) __cmpxchg_wrapper(_rel, __VA_ARGS__)
|
|
#define cmpxchg(...) __cmpxchg_wrapper( _mb, __VA_ARGS__)
|
|
#define cmpxchg_local cmpxchg_relaxed
|
|
|
|
/* cmpxchg64 */
|
|
#define cmpxchg64_relaxed cmpxchg_relaxed
|
|
#define cmpxchg64_acquire cmpxchg_acquire
|
|
#define cmpxchg64_release cmpxchg_release
|
|
#define cmpxchg64 cmpxchg
|
|
#define cmpxchg64_local cmpxchg_local
|
|
|
|
/* cmpxchg_double */
|
|
#define system_has_cmpxchg_double() 1
|
|
|
|
#define __cmpxchg_double_check(ptr1, ptr2) \
|
|
({ \
|
|
if (sizeof(*(ptr1)) != 8) \
|
|
BUILD_BUG(); \
|
|
VM_BUG_ON((unsigned long *)(ptr2) - (unsigned long *)(ptr1) != 1); \
|
|
})
|
|
|
|
#define cmpxchg_double(ptr1, ptr2, o1, o2, n1, n2) \
|
|
({\
|
|
int __ret;\
|
|
__cmpxchg_double_check(ptr1, ptr2); \
|
|
__ret = !__cmpxchg_double_mb((unsigned long)(o1), (unsigned long)(o2), \
|
|
(unsigned long)(n1), (unsigned long)(n2), \
|
|
ptr1); \
|
|
__ret; \
|
|
})
|
|
|
|
#define cmpxchg_double_local(ptr1, ptr2, o1, o2, n1, n2) \
|
|
({\
|
|
int __ret;\
|
|
__cmpxchg_double_check(ptr1, ptr2); \
|
|
__ret = !__cmpxchg_double((unsigned long)(o1), (unsigned long)(o2), \
|
|
(unsigned long)(n1), (unsigned long)(n2), \
|
|
ptr1); \
|
|
__ret; \
|
|
})
|
|
|
|
/* this_cpu_cmpxchg */
|
|
#define _protect_cmpxchg_local(pcp, o, n) \
|
|
({ \
|
|
typeof(*raw_cpu_ptr(&(pcp))) __ret; \
|
|
preempt_disable(); \
|
|
__ret = cmpxchg_local(raw_cpu_ptr(&(pcp)), o, n); \
|
|
preempt_enable(); \
|
|
__ret; \
|
|
})
|
|
|
|
#define this_cpu_cmpxchg_1(ptr, o, n) _protect_cmpxchg_local(ptr, o, n)
|
|
#define this_cpu_cmpxchg_2(ptr, o, n) _protect_cmpxchg_local(ptr, o, n)
|
|
#define this_cpu_cmpxchg_4(ptr, o, n) _protect_cmpxchg_local(ptr, o, n)
|
|
#define this_cpu_cmpxchg_8(ptr, o, n) _protect_cmpxchg_local(ptr, o, n)
|
|
|
|
#define this_cpu_cmpxchg_double_8(ptr1, ptr2, o1, o2, n1, n2) \
|
|
({ \
|
|
int __ret; \
|
|
preempt_disable(); \
|
|
__ret = cmpxchg_double_local( raw_cpu_ptr(&(ptr1)), \
|
|
raw_cpu_ptr(&(ptr2)), \
|
|
o1, o2, n1, n2); \
|
|
preempt_enable(); \
|
|
__ret; \
|
|
})
|
|
|
|
#endif /* __ASM_CMPXCHG_H */
|