2014-07-08 19:47:42

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 000/125] 3.2.61-rc1 review

This is the start of the stable review cycle for the 3.2.61 release.
There are 125 patches in this series, which will be posted as responses
to this one. If anyone has any issues with these being applied, please
let me know.

Responses should be made by Thu Jul 10 19:01:49 UTC 2014.
Anything received after that time might be too late.

A combined patch relative to 3.2.60 will be posted as an additional
response to this. A shortlog and diffstat can be found below.

Ben.

-------------

Alan Stern (2):
USB: Avoid runtime suspend loops for HCDs that can't handle suspend/resume
[8ef42ddd9a53b73e6fc3934278710c27f80f324f]
USB: EHCI: avoid BIOS handover on the HASEE E200
[b0a50e92bda3c4aeb8017d4e6c6e92146ebd5c9b]

Alex Deucher (3):
drm/radeon/atom: fix dithering on certain panels
[642528355c694f5ed68f6bff9ff520326a249f99]
drm/radeon: fix typo in radeon_connector_is_dp12_capable()
[af5d36539dfe043f1cf0f8b7334d6bb12cd14e75]
drm/radeon: only apply hdmi bpc pll flags when encoder mode is hdmi
[7d5ab3009a8ca777174f6f469277b3922d56fd4b]

Alex Smith (1):
recordmcount/MIPS: Fix possible incorrect mcount_loc table entries in modules
[91ad11d7cc6f4472ebf177a6252fbf0fd100d798]

Alexej Starschenko (1):
USB: serial: option: add support for Novatel E371 PCIe card
[8a61ba3a47ac39f660702aa66a172185dd605a86]

Andreas Schrägle (1):
ahci: add PCI ID for Marvell 88SE91A0 SATA Controller
[754a292fe6b08196cb135c03b404444e17de520a]

Andrey Ryabinin (2):
ARM: 8051/1: put_user: fix possible data corruption in put_user
[537094b64b229bf3ad146042f83e74cf6abe59df]
mm: rmap: fix use-after-free in __put_anon_vma
[624483f3ea82598ab0f62f1bdb9177f531ab1892]

Andy Lutomirski (2):
auditsc: audit_krule mask accesses need bounds checking
[a3c54931199565930d6d84f4c3456f6440aefd41]
x86_32, entry: Do syscall exit work on badsys (CVE-2014-4508)
[554086d85e71f30abe46fc014fea31929a7c6a8a]

Arik Nemtsov (1):
mac80211: don't check netdev state for debugfs read/write
[923eaf367206e01f22c97aee22300e332d071916]

Bart Van Assche (3):
IB/srp: Fix a sporadic crash triggered by cable pulling
[024ca90151f5e4296d30f72c13ff9a075e23c9ec]
IB/umad: Fix error handling
[8ec0a0e6b58218bdc1db91dd70ebfcd6ad8dd6cd]
[SCSI] Stop accepting SCSI requests before removing a device
[b485462aca7df4e32bcf7efb6f84a69e8b640243]

Ben Collins (1):
[SCSI] megaraid: Use resource_size_t for PCI resources, not long
[11f8a7b31f2140b0dc164bb484281235ffbe51d3]

Benjamin Herrenschmidt (1):
powerpc/serial: Use saner flags when creating legacy ports
[c4cad90f9e9dcb85afc5e75a02ae3522ed077296]

Benjamin Tissoires (1):
Input: synaptics - fix resolution for manually provided min/max
[d49cb7aeebb974713f9f7ab2991352d3050b095b]

Benny Halevy (1):
nfsd4: use recall_lock for delegation hashing
[931ee56c67573eb4e51c8a4e78598d965b8b059e]

Boris BREZILLON (1):
rtc: rtc-at91rm9200: fix infinite wait for ACKUPD irq
[2fe121e1f5aa3bf31b418a9790db6c400e922291]

Chris Mason (1):
Btrfs: fix double free in find_lock_delalloc_range
[7d78874273463a784759916fc3e0b4e2eb141c70]

Chris Wilson (1):
drm/i915: Only copy back the modified fields to userspace from execbuffer
[9aab8bff7aa3bee567213ad3c1fdfb217bb980a2]

Christian Borntraeger (1):
s390/lowcore: reserve 96 bytes for IRB in lowcore
[993072ee67aa179c48c85eb19869804e68887d86]

Christian König (1):
drm/radeon: stop poisoning the GART TLB
[0986c1a55ca64b44ee126a2f719a6e9f28cbe0ed]

Christoph Hellwig (1):
nfsd: getattr for FATTR4_WORD0_FILES_AVAIL needs the statfs buffer
[12337901d654415d9f764b5f5ba50052e9700f37]

Dan Carpenter (1):
RDMA/cxgb4: Fix four byte info leak in c4iw_create_cq()
[e24a72a3302a638d4c6e77f0b40c45cc61c3f089]

Daniel Vetter (1):
drm/i915: s/DRM_ERROR/DRM_DEBUG in i915_gem_execbuffer.c
[ff240199b6a3b0bec5ae9b6d26403dad38e8cb19]

David Henningsson (1):
ALSA: hda - Add quirk for external mic on Lifebook U904
[2041d56464a067461d7cc21734a0f024587ed2ff]

David Woodhouse (1):
iommu/vt-d: Fix missing IOTLB flush in intel_iommu_unmap()
[ea8ea460c9ace60bbb5ac6e5521d637d5c15293d]

Dennis Dalessandro (1):
IB/ipath: Translate legacy diagpkt into newer extended diagpkt
[7e6d3e5c70f13874fb06e6b67696ed90ce79bd48]

Emil Goode (1):
ARM: imx: fix error handling in ipu device registration
[d1d70e5dc2cfa9047bb935c41ba808ebb8135696]

Eric Dumazet (1):
net: fix inet_getid() and ipv6_select_ident() bugs
[39c36094d78c39e038c1e499b2364e13bce36f54]

Felipe Balbi (1):
bluetooth: hci_ldisc: fix deadlock condition
[da64c27d3c93ee9f89956b9de86c4127eb244494]

Gabor Juhos (1):
watchdog: ath79_wdt: avoid spurious restarts on AR934x
[23afeb613ec0e10aecfae7838a14d485db62ac52]

Geert Uytterhoeven (1):
Documentation: Update stable address in Chinese and Japanese translations
[98b0f811aade1b7c6e7806c86aa0befd5919d65f]

George McCollister (1):
USB: ftdi_sio: add NovaTech OrionLXm product ID
[d0839d757e6294921c31b1c4ca4f1dcc5df63bcd]

Greg Kroah-Hartman (1):
lzo: properly check for overruns
[206a81c18401c0cde6e579164f752c4b147324ce]

Guenter Roeck (1):
powerpc: Fix 64 bit builds with binutils 2.24
[7998eb3dc700aaf499f93f50b3d77da834ef9e1d]

Hans de Goede (4):
Input: elantech - deal with clickpads reporting right button events
[cd9e83e2754465856097f31c7ab933ce74c473f8]
Input: elantech - don't set bit 1 of reg_10 when the no_hw_res quirk is set
[fb4f8f568a9def02240ef9bf7aabd246dc63a081]
Input: synaptics - T540p - unify with other LEN0034 models
[6d396ede224dc596d92d7cab433713536e68916c]
Input: synaptics - add min/max quirk for the ThinkPad W540
[0b5fe736fe923f1f5e05413878d5990e92ffbdf5]

Huang Rui (1):
usb: usbtest: fix unlink write error with pattern 1
[e4d58f5dcb7d7be45df8def31881ebfae99c75da]

Hugh Dickins (2):
mm: fix crashes from mbind() merging vmas
[d05f0cdcbe6388723f1900c549b4850360545201]
mm: fix sleeping function warning from __put_anon_vma
[7f39dda9d86fb4f4f17af0de170decf125726f8c]

Hujianyang (2):
UBIFS: Remove incorrect assertion in shrink_tnc()
[72abc8f4b4e8574318189886de627a2bfe6cd0da]
UBIFS: fix an mmap and fsync race condition
[691a7c6f28ac90cccd0dbcf81348ea90b211bdd0]

J. Bruce Fields (1):
nfsd4: fix FREE_STATEID lockowner leak
[48385408b45523d9a432c66292d47ef43efcbb94]

James Bottomley (3):
[SCSI] Fix spurious request sense in error handling
[d555a2abf3481f81303d835046a5ec2c4fb3ca8e]
[SCSI] dual scan thread bug fix
[f2495e228fce9f9cec84367547813cbb0d6db15a]
[SCSI] fix our current target reap infrastructure
[e63ed0d7a98014fdfc2cfeb3f6dada313dcabb59]

Jan Kara (1):
ext4: fix zeroing of page during writeback
[eeece469dedadf3918bad50ad80f4616a0064e90]

Jeff Mahoney (1):
reiserfs: call truncate_setsize under tailpack mutex
[22e7478ddbcb670e33fab72d0bbe7c394c3a2c84]

Johan Hedberg (2):
Bluetooth: Fix SSP acceptor just-works confirmation without MITM
[ba15a58b179ed76a7e887177f2b06de12c58ec8f]
Bluetooth: Fix check for connection encryption
[e694788d73efe139b24f78b036deb97fe57fa8cb]

Johan Hovold (14):
USB: cdc-acm: fix broken runtime suspend
[140cb81ac8c625942a1d695875932c615767a526]
USB: cdc-acm: fix potential urb leak and PM imbalance in write
[183a45087d126d126e8dd1d9b2602fc129dff9ad]
USB: cdc-acm: fix runtime PM for control messages
[bae3f4c53585e9a170da9436e0f06919874bda9a]
USB: cdc-acm: fix write and resume race
[e144ed28bed10684f9aaec6325ed974d53f76110]
USB: cdc-acm: fix write and suspend race
[5a345c20c17d87099224a4be12e69e5bd7023dca]
USB: io_ti: fix firmware download on big-endian machines (part 2)
[c03890ff5e24a4bf59059f2d179f427559b7330a]
USB: option: fix runtime PM handling
[acf47d4f9c39b1cba467aa9442fc2efe0b1da741]
USB: sierra: fix AA deadlock in open error path
[353fe198602e8b4d1c7bdcceb8e60955087201b1]
USB: sierra: fix remote wakeup
[80cc0fcbdaeaf10d04ba27779a2d7ceb73d2717a]
USB: sierra: fix urb and memory leak in resume error path
[7fdd26a01eb7b6cb6855ff8f69ef4a720720dfcb]
USB: sierra: fix urb and memory leak on disconnect
[014333f77c0b71123d6ef7d31a9724e0699c9548]
USB: usb_wwan: fix potential blocked I/O after resume
[fb7ad4f93d9f0f7d49beda32f5e7becb94b29a4d]
USB: usb_wwan: fix urb leak at shutdown
[79eed03e77d481b55d85d1cfe5a1636a0d3897fd]
USB: usb_wwan: fix write and suspend race
[170fad9e22df0063eba0701adb966786d7a4ec5a]

Johannes Weiner (1):
mm: vmscan: clear kswapd's special reclaim powers before exiting
[71abdc15adf8c702a1dd535f8e30df50758848d2]

Jérôme Carretero (1):
ahci: Add Device ID for HighPoint RocketRaid 642L
[d251836508fb26cd1a22b41381739835ee23728d]

Kailang Yang (1):
ALSA: hda/realtek - Add support of ALC891 codec
[b6c5fbad16aa5026f508093a8d651c25e1cb6179]

Kees Cook (1):
HID: core: fix validation of report id 0
[1b15d2e5b8077670b1e6a33250a0d9577efff4a5]

Krzysztof Hałasa (1):
mac80211: fix IBSS join by initializing last_scan_completed
[c7d37a66e345df2fdf1aa7b2c9a6d3d53846ca5b]

Lai Jiangshan (1):
idr: fix overflow bug during maximum ID calculation at maximum height
[3afb69cb5572b3c8c898c00880803cf1a49852c4]

Lars-Peter Clausen (5):
ALSA: control: Don't access controls outside of protected regions
[fd9f26e4eca5d08a27d12c0933fceef76ed9663d]
ALSA: control: Fix replacing user controls
[82262a46627bebb0febcc26664746c25cef08563]
ALSA: control: Handle numid overflow
[ac902c112d90a89e59916f751c2745f4dbdbb4bd]
ALSA: control: Make sure that id->index does not overflow
[883a1d49f0d77d30012f114b2e19fc141beb3e8e]
ALSA: control: Protect user controls against concurrent access
[07f4d9d74a04aa7c72c5dae0ef97565f28f17b92]

Liu Hua (1):
ARM: 8012/1: kdump: Avoid overflow when converting pfn to physaddr
[8fad87bca7ac9737e413ba5f1656f1114a8c314d]

Lv Zheng (1):
ACPI: Fix conflict between customized DSDT and DSDT local copy
[73577d1df8e1f31f6b1a5eebcdbc334eb0330e47]

Marco Stornelli (1):
reiserfs: drop vmtruncate
[cfac4b47c664e207740880d6492938761c53d74b]

Markos Chandras (2):
MIPS: MSC: Prevent out-of-bounds writes to MIPS SC ioremap'd region
[ab6c15bc6620ebe220970cc040b29bcb2757f373]
MIPS: asm: thread_info: Add _TIF_SECCOMP flag
[137f7df8cead00688524c82360930845396b8a21]

Markus F.X.J. Oberhumer (2):
lib/lzo: Rename lzo1x_decompress.c to lzo1x_decompress_safe.c
[b6bec26cea948148a9420e7a0ac337f925de49e7]
lib/lzo: Update LZO compression to current upstream version
[8b975bd3f9089f8ee5d7bbfd798537b992bbc7e7]

Mathias Nyman (1):
xhci: delete endpoints from bandwidth list before freeing whole device
[5dc2808c4729bf080487e61b80ee04e0fdb12a37]

Matthew Dempsky (1):
ptrace: fix fork event messages across pid namespaces
[4e52365f279564cef0ddd41db5237f0471381093]

Maurizio Lombardi (1):
ext4: fix wrong assert in ext4_mb_normalize_request()
[b5b60778558cafad17bbcbf63e0310bd3c68eb17]

Michael Neuling (1):
powerpc: Don't setup CPUs with bad status
[59a53afe70fd530040bdc69581f03d880157f15a]

Michael S. Tsirkin (3):
skbuff: add an api to orphan frags
[a353e0ce0fd42d8859260666d1e9b10f2abd4698]
skbuff: export skb_copy_ubufs
[dcc0fb782b3a6e2abfeaaeb45dd88ed09596be0f]
skbuff: skb_segment: orphan frags before copying
[1fd819ecb90cc9b822cd84d3056ddba315d3340f]

Michal Schmidt (1):
netlink: rate-limit leftover bytes warning and print process name
[bfc5184b69cf9eeb286137640351c650c27f118a]

Mike Marciniszyn (1):
IB/qib: Fix port in pkey change event
[911eccd284d13d78c92ec4f1f1092c03457d732a]

Mikulas Patocka (1):
matroxfb: perform a dummy read of M_STATUS
[972754cfaee94d6e25acf94a497bc0a864d91b7e]

Mimi Zohar (1):
evm: prohibit userspace writing 'security.evm' HMAC value
[2fb1c9a4f2dbc2f0bd2431c7fa64d0b5483864e4]

Minchan Kim (1):
mm: revert 0def08e3 ("mm/mempolicy.c: check return code of check_range")
[082708072a4250f5c4dbc62065e7af93f5e45646]

Naoya Horiguchi (1):
hugetlb: fix copy_hugetlb_page_range() to handle migration/hwpoisoned entry
[4a705fef986231a3e7a6b1a6d3c37025f021f49f]

NeilBrown (1):
md: always set MD_RECOVERY_INTR when aborting a reshape or other "resync".
[3991b31ea072b070081ca3bfa860a077eda67de5]

Nicholas Bellinger (3):
iscsi-target: Reject mutual authentication with reflected CHAP_C
[1d2b60a5545942b1376cb48c1d55843d71e3a08f]
target: Explicitly clear ramdisk_mcp backend pages
[4442dc8a92b8f9ad8ee9e7f8438f4c04c03a22dc]
target: Fix left-over se_lun->lun_sep pointer OOPs
[83ff42fcce070801a3aa1cd6a3269d7426271a8d]

Oleg Nesterov (1):
tracing: Fix syscall_*regfunc() vs copy_process() race
[4af4206be2bd1933cae20c2b6fb2058dbc887f7c]

Peter Zijlstra (1):
perf: Fix race in removing an event
[46ce0fe97a6be7532ce6126bb26ce89fed81528c]

Rafał Miłecki (1):
b43: fix frequency reported on G-PHY with /new/ firmware
[2fc68eb122c7ea6cd5be1fe7d6650c0beb2f4f40]

Ralf Baechle (1):
MIPS: Cleanup flags in syscall flags handlers.
[e7f3b48af7be9f8007a224663a5b91340626fed5]

Stanislaw Gruszka (1):
rt2x00: disable TKIP on USB
[8edcb0ba0d56f5914eef11eda6db8bfe74eb9ca8]

Tejun Heo (1):
ptrace,x86: force IRET path after a ptrace_stop()
[b9cd18de4db3c9ffa7e17b0dc0ca99ed5aa4d43a]

Thomas Gleixner (5):
genirq: Sanitize spurious interrupt detection of threaded irqs
[1e77d0a1ed7417d2a5a52a7b8d32aea1833faa6c]
rtmutex: Detect changes in the pi lock chain
[82084984383babe728e6e3c9a8e5c46278091315]
rtmutex: Fix deadlock detector for real
[397335f004f41e5fcf7a795e94eb3ab83411a17c]
rtmutex: Handle deadlock detection smarter
[3d5c9340d1949733eb37616abd15db36aef9a57c]
rtmutex: Plug slow unlock race
[27e35715df54cbc4f2d044f681802ae30479e7fb]

Tom Gundersen (1):
net: tunnels - enable module autoloading
[f98f89a0104454f35a62d681683c844f6dbf4043]

Wei Yang (2):
mlx4_core: Stash PCI ID driver_data in mlx4_priv structure
[839f12434c7618d326b9d1ece5eca643e5e48d0a]
net/mlx4_core: Preserve pci_dev_data after __mlx4_remove_one()
[befdf8978accecac2e0739e6b5075afc62db37fe]

Will Deacon (1):
mm: highmem: don't treat PKMAP_ADDR(LAST_PKMAP) as a highmem address
[498c2280212327858e521e9d21345d4cc2637f54]

Xiao Jin (2):
USB: usb_wwan: fix race between write and resume
[d9e93c08d8d985e5ef89436ebc9f4aad7e31559f]
USB: usb_wwan: fix urb leak in write error path
[db0904737947d509844e171c9863ecc5b4534005]

Xufeng Zhang (1):
sctp: Fix sk_ack_backlog wrap-around problem
[d3217b15a19a4779c39b212358a5c71d725822ee]

Yann Droneaud (1):
RDMA/cxgb4: Add missing padding at end of struct c4iw_create_cq_resp
[b6f04d3d21458818073a2f5af5339f958864bf71]

Zhaowei Yuan (1):
drm: fix NULL pointer access by wrong ioctl
[1539fb9bd405ee32282ea0a38404f9e008ac5b7a]

Documentation/ja_JP/HOWTO | 2 +-
Documentation/ja_JP/stable_kernel_rules.txt | 6 +-
Documentation/zh_CN/HOWTO | 2 +-
Documentation/zh_CN/stable_kernel_rules.txt | 2 +-
Makefile | 4 +-
arch/arm/include/asm/uaccess.h | 3 +-
arch/arm/kernel/crash_dump.c | 2 +-
arch/arm/plat-mxc/devices/platform-ipu-core.c | 2 +-
arch/mips/include/asm/thread_info.h | 2 +
arch/mips/kernel/irq-msc01.c | 2 +-
arch/mips/kernel/scall32-o32.S | 2 +-
arch/mips/kernel/scall64-64.S | 2 +-
arch/mips/kernel/scall64-n32.S | 2 +-
arch/mips/kernel/scall64-o32.S | 2 +-
arch/powerpc/Makefile | 4 +-
arch/powerpc/include/asm/ppc_asm.h | 7 +-
arch/powerpc/kernel/legacy_serial.c | 15 +-
arch/powerpc/kernel/setup-common.c | 2 +-
arch/s390/include/asm/lowcore.h | 11 +-
arch/x86/include/asm/ptrace.h | 16 ++
arch/x86/kernel/entry_32.S | 10 +-
drivers/acpi/bus.c | 7 +
drivers/ata/ahci.c | 4 +
drivers/bluetooth/hci_ldisc.c | 25 +-
drivers/bluetooth/hci_uart.h | 2 +
drivers/gpu/drm/drm_drv.c | 3 +-
drivers/gpu/drm/i915/i915_gem_execbuffer.c | 102 ++++----
drivers/gpu/drm/radeon/atombios_crtc.c | 48 ++--
drivers/gpu/drm/radeon/atombios_encoders.c | 5 +-
drivers/gpu/drm/radeon/radeon_connectors.c | 2 +-
drivers/gpu/drm/radeon/rs600.c | 7 +-
drivers/hid/hid-core.c | 12 +-
drivers/infiniband/core/user_mad.c | 49 ++--
drivers/infiniband/hw/cxgb4/cq.c | 3 +-
drivers/infiniband/hw/cxgb4/user.h | 1 +
drivers/infiniband/hw/ipath/ipath_diag.c | 4 +
drivers/infiniband/hw/qib/qib_mad.c | 2 +-
drivers/infiniband/ulp/srp/ib_srp.c | 6 +
drivers/input/mouse/elantech.c | 27 ++-
drivers/input/mouse/synaptics.c | 26 +-
drivers/iommu/intel-iommu.c | 18 +-
drivers/md/md.c | 4 +-
drivers/net/ethernet/mellanox/mlx4/main.c | 120 +++++----
drivers/net/ethernet/mellanox/mlx4/mlx4.h | 3 +
drivers/net/wireless/b43/xmit.c | 10 +-
drivers/net/wireless/rt2x00/rt2x00mac.c | 2 +
drivers/rtc/rtc-at91rm9200.c | 16 +-
drivers/scsi/megaraid/megaraid_sas.h | 1 -
drivers/scsi/megaraid/megaraid_sas_base.c | 5 +-
drivers/scsi/scsi_error.c | 9 +
drivers/scsi/scsi_lib.c | 7 +-
drivers/scsi/scsi_scan.c | 112 +++++----
drivers/scsi/scsi_sysfs.c | 31 ++-
drivers/target/iscsi/iscsi_target_auth.c | 10 +
drivers/target/target_core_device.c | 1 +
drivers/target/target_core_rd.c | 2 +-
drivers/usb/class/cdc-acm.c | 96 +++++---
drivers/usb/class/cdc-acm.h | 2 +-
drivers/usb/core/driver.c | 9 +-
drivers/usb/core/hub.c | 16 +-
drivers/usb/host/pci-quirks.c | 19 +-
drivers/usb/host/xhci-mem.c | 20 +-
drivers/usb/misc/usbtest.c | 10 +
drivers/usb/serial/ftdi_sio.c | 2 +
drivers/usb/serial/ftdi_sio_ids.h | 5 +
drivers/usb/serial/io_ti.c | 2 +-
drivers/usb/serial/io_usbvend.h | 2 +-
drivers/usb/serial/option.c | 14 +-
drivers/usb/serial/sierra.c | 48 +++-
drivers/usb/serial/usb_wwan.c | 85 ++++---
drivers/video/matrox/matroxfb_base.h | 2 +-
drivers/watchdog/ath79_wdt.c | 10 +
fs/btrfs/extent_io.c | 1 +
fs/ext4/mballoc.c | 2 +-
fs/ext4/page-io.c | 24 +-
fs/nfsd/nfs4state.c | 22 +-
fs/nfsd/nfs4xdr.c | 4 +-
fs/reiserfs/file.c | 3 +-
fs/reiserfs/inode.c | 21 +-
fs/ubifs/file.c | 3 +-
fs/ubifs/shrinker.c | 1 -
include/linux/irqdesc.h | 4 +
include/linux/lzo.h | 15 +-
include/linux/ptrace.h | 35 +++
include/linux/reiserfs_fs.h | 1 +
include/linux/skbuff.h | 16 ++
include/net/inetpeer.h | 9 +-
include/scsi/scsi_device.h | 3 +-
include/sound/core.h | 2 +
include/trace/syscall.h | 15 ++
kernel/auditsc.c | 25 +-
kernel/events/core.c | 45 ++--
kernel/fork.c | 12 +-
kernel/irq/manage.c | 4 +-
kernel/irq/spurious.c | 106 +++++++-
kernel/rtmutex-debug.h | 5 +
kernel/rtmutex.c | 268 ++++++++++++++++++---
kernel/rtmutex.h | 5 +
lib/decompress_unlzo.c | 2 +-
lib/idr.c | 8 +-
lib/lzo/Makefile | 2 +-
lib/lzo/lzo1x_compress.c | 335 +++++++++++++++-----------
lib/lzo/lzo1x_decompress.c | 255 --------------------
lib/lzo/lzodefs.h | 38 ++-
lib/nlattr.c | 5 +-
mm/highmem.c | 2 +-
mm/hugetlb.c | 71 +++---
mm/mempolicy.c | 57 +++--
mm/rmap.c | 11 +-
mm/vmscan.c | 3 +
net/bluetooth/hci_conn.c | 2 +-
net/bluetooth/hci_event.c | 7 +-
net/core/skbuff.c | 5 +-
net/ipv4/ipip.c | 1 +
net/ipv6/ip6_output.c | 11 +-
net/ipv6/ip6_tunnel.c | 1 +
net/ipv6/sit.c | 1 +
net/mac80211/debugfs_netdev.c | 6 +-
net/mac80211/ibss.c | 1 +
net/sctp/associola.c | 2 +-
scripts/recordmcount.h | 4 +-
security/integrity/evm/evm_main.c | 12 +-
sound/core/control.c | 78 +++---
sound/core/init.c | 1 +
sound/pci/hda/patch_realtek.c | 10 +
125 files changed, 1696 insertions(+), 1014 deletions(-)

--
Ben Hutchings
Any smoothly functioning technology is indistinguishable from a rigged demo.


2014-07-08 19:08:47

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 005/125] Input: synaptics - add min/max quirk for the ThinkPad W540

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Hans de Goede <[email protected]>

commit 0b5fe736fe923f1f5e05413878d5990e92ffbdf5 upstream.

https://bugzilla.redhat.com/show_bug.cgi?id=1096436

Tested-and-reported-by: [email protected]
Signed-off-by: Hans de Goede <[email protected]>
Signed-off-by: Dmitry Torokhov <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/input/mouse/synaptics.c | 8 ++++++++
1 file changed, 8 insertions(+)

--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -1442,6 +1442,14 @@ static const struct dmi_system_id min_ma
.driver_data = (int []){1024, 5112, 2024, 4832},
},
{
+ /* Lenovo ThinkPad W540 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W540"),
+ },
+ .driver_data = (int []){1024, 5112, 2024, 4832},
+ },
+ {
/* Lenovo Yoga S1 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),

2014-07-08 19:08:45

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 012/125] matroxfb: perform a dummy read of M_STATUS

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Mikulas Patocka <[email protected]>

commit 972754cfaee94d6e25acf94a497bc0a864d91b7e upstream.

I had occasional screen corruption with the matrox framebuffer driver and
I found out that the reason for the corruption is that the hardware
blitter accesses the videoram while it is being written to.

The matrox driver has a macro WaitTillIdle() that should wait until the
blitter is idle, but it sometimes doesn't work. I added a dummy read
mga_inl(M_STATUS) to WaitTillIdle() to fix the problem. The dummy read
will flush the write buffer in the PCI chipset, and the next read of
M_STATUS will return the hardware status.

Since applying this patch, I had no screen corruption at all.

Signed-off-by: Mikulas Patocka <[email protected]>
Signed-off-by: Tomi Valkeinen <[email protected]>
[bwh: Backported to 3.2: adjust filename]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/video/fbdev/matrox/matroxfb_base.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/video/matrox/matroxfb_base.h
+++ b/drivers/video/matrox/matroxfb_base.h
@@ -698,7 +698,7 @@ void matroxfb_unregister_driver(struct m

#define mga_fifo(n) do {} while ((mga_inl(M_FIFOSTATUS) & 0xFF) < (n))

-#define WaitTillIdle() do {} while (mga_inl(M_STATUS) & 0x10000)
+#define WaitTillIdle() do { mga_inl(M_STATUS); do {} while (mga_inl(M_STATUS) & 0x10000); } while (0)

/* code speedup */
#ifdef CONFIG_FB_MATROX_MILLENIUM

2014-07-08 19:09:18

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 041/125] USB: serial: option: add support for Novatel E371 PCIe card

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Alexej Starschenko <[email protected]>

commit 8a61ba3a47ac39f660702aa66a172185dd605a86 upstream.

Adds product ID for the Novatel E371 PCI Express Mini Card.

$ lsusb
Bus 001 Device 024: ID 1410:9011 Novatel Wireless

$ usb-devices
T: Bus=01 Lev=01 Prnt=01 Port=03 Cnt=01 Dev#= 24 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=1410 ProdID=9011 Rev=00.03
S: Manufacturer=Novatel Wireless, Inc.
S: Product=Novatel Wireless HSPA
S: SerialNumber=012773002115811
C: #Ifs= 6 Cfg#= 1 Atr=e0 MxPwr=500mA
I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I: If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I: If#= 6 Alt= 0 #EPs= 1 Cls=02(commc) Sub=06 Prot=00 Driver=cdc_ether
I: If#= 7 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether

Tested with kernel 3.2.0.

Signed-off-by: Alexej Starschenko <[email protected]>
Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/option.c | 2 ++
1 file changed, 2 insertions(+)

--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -161,6 +161,7 @@ static void option_instat_callback(struc
#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000
#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001
#define NOVATELWIRELESS_PRODUCT_E362 0x9010
+#define NOVATELWIRELESS_PRODUCT_E371 0x9011
#define NOVATELWIRELESS_PRODUCT_G2 0xA010
#define NOVATELWIRELESS_PRODUCT_MC551 0xB001

@@ -1025,6 +1026,7 @@ static const struct usb_device_id option
/* Novatel Ovation MC551 a.k.a. Verizon USB551L */
{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E371, 0xff, 0xff, 0xff) },

{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },

2014-07-08 19:09:16

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 042/125] usb: usbtest: fix unlink write error with pattern 1

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Huang Rui <[email protected]>

commit e4d58f5dcb7d7be45df8def31881ebfae99c75da upstream.

TEST 12 and TEST 24 unlinks the URB write request for N times. When
host and gadget both initialize pattern 1 (mod 63) data series to
transfer, the gadget side will complain the wrong data which is not
expected. Because in host side, usbtest doesn't fill the data buffer
as mod 63 and this patch fixed it.

[20285.488974] dwc3 dwc3.0.auto: ep1out-bulk: Transfer Not Ready
[20285.489181] dwc3 dwc3.0.auto: ep1out-bulk: reason Transfer Not Active
[20285.489423] dwc3 dwc3.0.auto: ep1out-bulk: req ffff8800aa6cb480 dma aeb50800 length 512 last
[20285.489727] dwc3 dwc3.0.auto: ep1out-bulk: cmd 'Start Transfer' params 00000000 a9eaf000 00000000
[20285.490055] dwc3 dwc3.0.auto: Command Complete --> 0
[20285.490281] dwc3 dwc3.0.auto: ep1out-bulk: Transfer Not Ready
[20285.490492] dwc3 dwc3.0.auto: ep1out-bulk: reason Transfer Active
[20285.490713] dwc3 dwc3.0.auto: ep1out-bulk: endpoint busy
[20285.490909] dwc3 dwc3.0.auto: ep1out-bulk: Transfer Complete
[20285.491117] dwc3 dwc3.0.auto: request ffff8800aa6cb480 from ep1out-bulk completed 512/512 ===> 0
[20285.491431] zero gadget: bad OUT byte, buf[1] = 0
[20285.491605] dwc3 dwc3.0.auto: ep1out-bulk: cmd 'Set Stall' params 00000000 00000000 00000000
[20285.491915] dwc3 dwc3.0.auto: Command Complete --> 0
[20285.492099] dwc3 dwc3.0.auto: queing request ffff8800aa6cb480 to ep1out-bulk length 512
[20285.492387] dwc3 dwc3.0.auto: ep1out-bulk: Transfer Not Ready
[20285.492595] dwc3 dwc3.0.auto: ep1out-bulk: reason Transfer Not Active
[20285.492830] dwc3 dwc3.0.auto: ep1out-bulk: req ffff8800aa6cb480 dma aeb51000 length 512 last
[20285.493135] dwc3 dwc3.0.auto: ep1out-bulk: cmd 'Start Transfer' params 00000000 a9eaf000 00000000
[20285.493465] dwc3 dwc3.0.auto: Command Complete --> 0

Signed-off-by: Huang Rui <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/misc/usbtest.c | 10 ++++++++++
1 file changed, 10 insertions(+)

--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -1132,6 +1132,11 @@ static int unlink1(struct usbtest_dev *d
urb->context = &completion;
urb->complete = unlink1_callback;

+ if (usb_pipeout(urb->pipe)) {
+ simple_fill_buf(urb);
+ urb->transfer_flags |= URB_ZERO_PACKET;
+ }
+
/* keep the endpoint busy. there are lots of hc/hcd-internal
* states, and testing should get to all of them over time.
*
@@ -1262,6 +1267,11 @@ static int unlink_queued(struct usbtest_
unlink_queued_callback, &ctx);
ctx.urbs[i]->transfer_dma = buf_dma;
ctx.urbs[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
+
+ if (usb_pipeout(ctx.urbs[i]->pipe)) {
+ simple_fill_buf(ctx.urbs[i]);
+ ctx.urbs[i]->transfer_flags |= URB_ZERO_PACKET;
+ }
}

/* Submit all the URBs and then unlink URBs num - 4 and num - 2. */

2014-07-08 19:09:14

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 062/125] iscsi-target: Reject mutual authentication with reflected CHAP_C

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Nicholas Bellinger <[email protected]>

commit 1d2b60a5545942b1376cb48c1d55843d71e3a08f upstream.

This patch adds an explicit check in chap_server_compute_md5() to ensure
the CHAP_C value received from the initiator during mutual authentication
does not match the original CHAP_C provided by the target.

This is in line with RFC-3720, section 8.2.1:

Originators MUST NOT reuse the CHAP challenge sent by the Responder
for the other direction of a bidirectional authentication.
Responders MUST check for this condition and close the iSCSI TCP
connection if it occurs.

Reported-by: Tejas Vaykole <[email protected]>
Signed-off-by: Nicholas Bellinger <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/target/iscsi/iscsi_target_auth.c | 10 ++++++++++
1 file changed, 10 insertions(+)

--- a/drivers/target/iscsi/iscsi_target_auth.c
+++ b/drivers/target/iscsi/iscsi_target_auth.c
@@ -337,6 +337,16 @@ static int chap_server_compute_md5(
goto out;
}
/*
+ * During mutual authentication, the CHAP_C generated by the
+ * initiator must not match the original CHAP_C generated by
+ * the target.
+ */
+ if (!memcmp(challenge_binhex, chap->challenge, CHAP_CHALLENGE_LENGTH)) {
+ pr_err("initiator CHAP_C matches target CHAP_C, failing"
+ " login attempt\n");
+ goto out;
+ }
+ /*
* Generate CHAP_N and CHAP_R for mutual authentication.
*/
tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);

2014-07-08 19:11:22

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 053/125] UBIFS: Remove incorrect assertion in shrink_tnc()

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: hujianyang <[email protected]>

commit 72abc8f4b4e8574318189886de627a2bfe6cd0da upstream.

I hit the same assert failed as Dolev Raviv reported in Kernel v3.10
shows like this:

[ 9641.164028] UBIFS assert failed in shrink_tnc at 131 (pid 13297)
[ 9641.234078] CPU: 1 PID: 13297 Comm: mmap.test Tainted: G O 3.10.40 #1
[ 9641.234116] [<c0011a6c>] (unwind_backtrace+0x0/0x12c) from [<c000d0b0>] (show_stack+0x20/0x24)
[ 9641.234137] [<c000d0b0>] (show_stack+0x20/0x24) from [<c0311134>] (dump_stack+0x20/0x28)
[ 9641.234188] [<c0311134>] (dump_stack+0x20/0x28) from [<bf22425c>] (shrink_tnc_trees+0x25c/0x350 [ubifs])
[ 9641.234265] [<bf22425c>] (shrink_tnc_trees+0x25c/0x350 [ubifs]) from [<bf2245ac>] (ubifs_shrinker+0x25c/0x310 [ubifs])
[ 9641.234307] [<bf2245ac>] (ubifs_shrinker+0x25c/0x310 [ubifs]) from [<c00cdad8>] (shrink_slab+0x1d4/0x2f8)
[ 9641.234327] [<c00cdad8>] (shrink_slab+0x1d4/0x2f8) from [<c00d03d0>] (do_try_to_free_pages+0x300/0x544)
[ 9641.234344] [<c00d03d0>] (do_try_to_free_pages+0x300/0x544) from [<c00d0a44>] (try_to_free_pages+0x2d0/0x398)
[ 9641.234363] [<c00d0a44>] (try_to_free_pages+0x2d0/0x398) from [<c00c6a60>] (__alloc_pages_nodemask+0x494/0x7e8)
[ 9641.234382] [<c00c6a60>] (__alloc_pages_nodemask+0x494/0x7e8) from [<c00f62d8>] (new_slab+0x78/0x238)
[ 9641.234400] [<c00f62d8>] (new_slab+0x78/0x238) from [<c031081c>] (__slab_alloc.constprop.42+0x1a4/0x50c)
[ 9641.234419] [<c031081c>] (__slab_alloc.constprop.42+0x1a4/0x50c) from [<c00f80e8>] (kmem_cache_alloc_trace+0x54/0x188)
[ 9641.234459] [<c00f80e8>] (kmem_cache_alloc_trace+0x54/0x188) from [<bf227908>] (do_readpage+0x168/0x468 [ubifs])
[ 9641.234553] [<bf227908>] (do_readpage+0x168/0x468 [ubifs]) from [<bf2296a0>] (ubifs_readpage+0x424/0x464 [ubifs])
[ 9641.234606] [<bf2296a0>] (ubifs_readpage+0x424/0x464 [ubifs]) from [<c00c17c0>] (filemap_fault+0x304/0x418)
[ 9641.234638] [<c00c17c0>] (filemap_fault+0x304/0x418) from [<c00de694>] (__do_fault+0xd4/0x530)
[ 9641.234665] [<c00de694>] (__do_fault+0xd4/0x530) from [<c00e10c0>] (handle_pte_fault+0x480/0xf54)
[ 9641.234690] [<c00e10c0>] (handle_pte_fault+0x480/0xf54) from [<c00e2bf8>] (handle_mm_fault+0x140/0x184)
[ 9641.234716] [<c00e2bf8>] (handle_mm_fault+0x140/0x184) from [<c0316688>] (do_page_fault+0x150/0x3ac)
[ 9641.234737] [<c0316688>] (do_page_fault+0x150/0x3ac) from [<c000842c>] (do_DataAbort+0x3c/0xa0)
[ 9641.234759] [<c000842c>] (do_DataAbort+0x3c/0xa0) from [<c0314e38>] (__dabt_usr+0x38/0x40)

After analyzing the code, I found a condition that may cause this failed
in correct operations. Thus, I think this assertion is wrong and should be
removed.

Suppose there are two clean znodes and one dirty znode in TNC. So the
per-filesystem atomic_t @clean_zn_cnt is (2). If commit start, dirty_znode
is set to COW_ZNODE in get_znodes_to_commit() in case of potentially ops
on this znode. We clear COW bit and DIRTY bit in write_index() without
@tnc_mutex locked. We don't increase @clean_zn_cnt in this place. As the
comments in write_index() shows, if another process hold @tnc_mutex and
dirty this znode after we clean it, @clean_zn_cnt would be decreased to (1).
We will increase @clean_zn_cnt to (2) with @tnc_mutex locked in
free_obsolete_znodes() to keep it right.

If shrink_tnc() performs between decrease and increase, it will release
other 2 clean znodes it holds and found @clean_zn_cnt is less than zero
(1 - 2 = -1), then hit the assertion. Because free_obsolete_znodes() will
soon correct @clean_zn_cnt and no harm to fs in this case, I think this
assertion could be removed.

2 clean zondes and 1 dirty znode, @clean_zn_cnt == 2

Thread A (commit) Thread B (write or others) Thread C (shrinker)
->write_index
->clear_bit(DIRTY_NODE)
->clear_bit(COW_ZNODE)

@clean_zn_cnt == 2
->mutex_locked(&tnc_mutex)
->dirty_cow_znode
->!ubifs_zn_cow(znode)
->!test_and_set_bit(DIRTY_NODE)
->atomic_dec(&clean_zn_cnt)
->mutex_unlocked(&tnc_mutex)

@clean_zn_cnt == 1
->mutex_locked(&tnc_mutex)
->shrink_tnc
->destroy_tnc_subtree
->atomic_sub(&clean_zn_cnt, 2)
->ubifs_assert <- hit
->mutex_unlocked(&tnc_mutex)

@clean_zn_cnt == -1
->mutex_lock(&tnc_mutex)
->free_obsolete_znodes
->atomic_inc(&clean_zn_cnt)
->mutux_unlock(&tnc_mutex)

@clean_zn_cnt == 0 (correct after shrink)

Signed-off-by: hujianyang <[email protected]>
Signed-off-by: Artem Bityutskiy <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/ubifs/shrinker.c | 1 -
1 file changed, 1 deletion(-)

--- a/fs/ubifs/shrinker.c
+++ b/fs/ubifs/shrinker.c
@@ -128,7 +128,6 @@ static int shrink_tnc(struct ubifs_info
freed = ubifs_destroy_tnc_subtree(znode);
atomic_long_sub(freed, &ubifs_clean_zn_cnt);
atomic_long_sub(freed, &c->clean_zn_cnt);
- ubifs_assert(atomic_long_read(&c->clean_zn_cnt) >= 0);
total_freed += freed;
znode = zprev;
}

2014-07-08 19:11:21

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 048/125] xhci: delete endpoints from bandwidth list before freeing whole device

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Mathias Nyman <[email protected]>

commit 5dc2808c4729bf080487e61b80ee04e0fdb12a37 upstream.

Lists of endpoints are stored for bandwidth calculation for roothub ports.
Make sure we remove all endpoints from the list before the whole device,
containing its endpoints list_head stuctures, is freed.

This used to be done in the wrong order in xhci_mem_cleanup(),
and triggered an oops in resume from S4 (hibernate).

Tested-by: Ville Syrjälä <[email protected]>
Signed-off-by: Mathias Nyman <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/host/xhci-mem.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)

--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1722,6 +1722,16 @@ void xhci_mem_cleanup(struct xhci_hcd *x
kfree(cur_cd);
}

+ num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
+ for (i = 0; i < num_ports; i++) {
+ struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table;
+ for (j = 0; j < XHCI_MAX_INTERVAL; j++) {
+ struct list_head *ep = &bwt->interval_bw[j].endpoints;
+ while (!list_empty(ep))
+ list_del_init(ep->next);
+ }
+ }
+
for (i = 1; i < MAX_HC_SLOTS; ++i)
xhci_free_virt_device(xhci, i);

@@ -1762,16 +1772,6 @@ void xhci_mem_cleanup(struct xhci_hcd *x
if (!xhci->rh_bw)
goto no_bw;

- num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
- for (i = 0; i < num_ports; i++) {
- struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table;
- for (j = 0; j < XHCI_MAX_INTERVAL; j++) {
- struct list_head *ep = &bwt->interval_bw[j].endpoints;
- while (!list_empty(ep))
- list_del_init(ep->next);
- }
- }
-
for (i = 0; i < num_ports; i++) {
struct xhci_tt_bw_info *tt, *n;
list_for_each_entry_safe(tt, n, &xhci->rh_bw[i].tts, tt_list) {

2014-07-08 19:11:18

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 052/125] nfsd: getattr for FATTR4_WORD0_FILES_AVAIL needs the statfs buffer

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Christoph Hellwig <[email protected]>

commit 12337901d654415d9f764b5f5ba50052e9700f37 upstream.

Note nobody's ever noticed because the typical client probably never
requests FILES_AVAIL without also requesting something else on the list.

Signed-off-by: Christoph Hellwig <[email protected]>
Signed-off-by: J. Bruce Fields <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/nfsd/nfs4xdr.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2035,8 +2035,8 @@ nfsd4_encode_fattr(struct svc_fh *fhp, s
err = vfs_getattr(exp->ex_path.mnt, dentry, &stat);
if (err)
goto out_nfserr;
- if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL |
- FATTR4_WORD0_MAXNAME)) ||
+ if ((bmval0 & (FATTR4_WORD0_FILES_AVAIL | FATTR4_WORD0_FILES_FREE |
+ FATTR4_WORD0_FILES_TOTAL | FATTR4_WORD0_MAXNAME)) ||
(bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE |
FATTR4_WORD1_SPACE_TOTAL))) {
err = vfs_statfs(&path, &statfs);

2014-07-08 19:11:17

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 060/125] powerpc/serial: Use saner flags when creating legacy ports

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Benjamin Herrenschmidt <[email protected]>

commit c4cad90f9e9dcb85afc5e75a02ae3522ed077296 upstream.

We had a mix & match of flags used when creating legacy ports
depending on where we found them in the device-tree. Among others
we were missing UPF_SKIP_TEST for some kind of ISA ports which is
a problem as quite a few UARTs out there don't support the loopback
test (such as a lot of BMCs).

Let's pick the set of flags used by the SoC code and generalize it
which means autoconf, no loopback test, irq maybe shared and fixed
port.

Sending to stable as the lack of UPF_SKIP_TEST is breaking
serial on some machines so I want this back into distros

Signed-off-by: Benjamin Herrenschmidt <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/powerpc/kernel/legacy_serial.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)

--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -48,6 +48,9 @@ static struct __initdata of_device_id le
static unsigned int legacy_serial_count;
static int legacy_serial_console = -1;

+static const upf_t legacy_port_flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_SHARE_IRQ | UPF_FIXED_PORT;
+
static unsigned int tsi_serial_in(struct uart_port *p, int offset)
{
unsigned int tmp;
@@ -153,8 +156,6 @@ static int __init add_legacy_soc_port(st
{
u64 addr;
const u32 *addrp;
- upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ
- | UPF_FIXED_PORT;
struct device_node *tsi = of_get_parent(np);

/* We only support ports that have a clock frequency properly
@@ -185,9 +186,11 @@ static int __init add_legacy_soc_port(st
* IO port value. It will be fixed up later along with the irq
*/
if (tsi && !strcmp(tsi->type, "tsi-bridge"))
- return add_legacy_port(np, -1, UPIO_TSI, addr, addr, NO_IRQ, flags, 0);
+ return add_legacy_port(np, -1, UPIO_TSI, addr, addr,
+ NO_IRQ, legacy_port_flags, 0);
else
- return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0);
+ return add_legacy_port(np, -1, UPIO_MEM, addr, addr,
+ NO_IRQ, legacy_port_flags, 0);
}

static int __init add_legacy_isa_port(struct device_node *np,
@@ -228,7 +231,7 @@ static int __init add_legacy_isa_port(st

/* Add port, irq will be dealt with later */
return add_legacy_port(np, index, UPIO_PORT, be32_to_cpu(reg[1]), taddr,
- NO_IRQ, UPF_BOOT_AUTOCONF, 0);
+ NO_IRQ, legacy_port_flags, 0);

}

@@ -301,7 +304,7 @@ static int __init add_legacy_pci_port(st
* IO port value. It will be fixed up later along with the irq
*/
return add_legacy_port(np, index, iotype, base, addr, NO_IRQ,
- UPF_BOOT_AUTOCONF, np != pci_dev);
+ legacy_port_flags, np != pci_dev);
}
#endif

2014-07-08 19:11:13

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 003/125] genirq: Sanitize spurious interrupt detection of threaded irqs

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Thomas Gleixner <[email protected]>

commit 1e77d0a1ed7417d2a5a52a7b8d32aea1833faa6c upstream.

Till reported that the spurious interrupt detection of threaded
interrupts is broken in two ways:

- note_interrupt() is called for each action thread of a shared
interrupt line. That's wrong as we are only interested whether none
of the device drivers felt responsible for the interrupt, but by
calling multiple times for a single interrupt line we account
IRQ_NONE even if one of the drivers felt responsible.

- note_interrupt() when called from the thread handler is not
serialized. That leaves the members of irq_desc which are used for
the spurious detection unprotected.

To solve this we need to defer the spurious detection of a threaded
interrupt to the next hardware interrupt context where we have
implicit serialization.

If note_interrupt is called with action_ret == IRQ_WAKE_THREAD, we
check whether the previous interrupt requested a deferred check. If
not, we request a deferred check for the next hardware interrupt and
return.

If set, we check whether one of the interrupt threads signaled
success. Depending on this information we feed the result into the
spurious detector.

If one primary handler of a shared interrupt returns IRQ_HANDLED we
disable the deferred check of irq threads on the same line, as we have
found at least one device driver who cared.

Reported-by: Till Straumann <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Tested-by: Austin Schuh <[email protected]>
Cc: Oliver Hartkopp <[email protected]>
Cc: Wolfgang Grandegger <[email protected]>
Cc: Pavel Pisa <[email protected]>
Cc: Marc Kleine-Budde <[email protected]>
Cc: [email protected]
Link: http://lkml.kernel.org/r/alpine.LFD.2.02.1303071450130.22263@ionos
[bwh: Backported to 3.2: adjust context, indentation]
Signed-off-by: Ben Hutchings <[email protected]>
---
include/linux/irqdesc.h | 4 ++
kernel/irq/manage.c | 4 +-
kernel/irq/spurious.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 108 insertions(+), 6 deletions(-)

--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -27,6 +27,8 @@ struct module;
* @irq_count: stats field to detect stalled irqs
* @last_unhandled: aging timer for unhandled count
* @irqs_unhandled: stats field for spurious unhandled interrupts
+ * @threads_handled: stats field for deferred spurious detection of threaded handlers
+ * @threads_handled_last: comparator field for deferred spurious detection of theraded handlers
* @lock: locking for SMP
* @affinity_hint: hint to user space for preferred irq affinity
* @affinity_notify: context for notification of affinity changes
@@ -53,6 +55,8 @@ struct irq_desc {
unsigned int irq_count; /* For detecting broken IRQs */
unsigned long last_unhandled; /* Aging timer for unhandled count */
unsigned int irqs_unhandled;
+ atomic_t threads_handled;
+ int threads_handled_last;
raw_spinlock_t lock;
struct cpumask *percpu_enabled;
#ifdef CONFIG_SMP
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -813,8 +813,8 @@ static int irq_thread(void *data)

raw_spin_unlock_irq(&desc->lock);
action_ret = handler_fn(desc, action);
- if (!noirqdebug)
- note_interrupt(action->irq, desc, action_ret);
+ if (action_ret == IRQ_HANDLED)
+ atomic_inc(&desc->threads_handled);
}

wake = atomic_dec_and_test(&desc->threads_active);
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -265,21 +265,119 @@ try_misrouted_irq(unsigned int irq, stru
return action && (action->flags & IRQF_IRQPOLL);
}

+#define SPURIOUS_DEFERRED 0x80000000
+
void note_interrupt(unsigned int irq, struct irq_desc *desc,
irqreturn_t action_ret)
{
if (desc->istate & IRQS_POLL_INPROGRESS)
return;

- /* we get here again via the threaded handler */
- if (action_ret == IRQ_WAKE_THREAD)
- return;
-
if (bad_action_ret(action_ret)) {
report_bad_irq(irq, desc, action_ret);
return;
}

+ /*
+ * We cannot call note_interrupt from the threaded handler
+ * because we need to look at the compound of all handlers
+ * (primary and threaded). Aside of that in the threaded
+ * shared case we have no serialization against an incoming
+ * hardware interrupt while we are dealing with a threaded
+ * result.
+ *
+ * So in case a thread is woken, we just note the fact and
+ * defer the analysis to the next hardware interrupt.
+ *
+ * The threaded handlers store whether they sucessfully
+ * handled an interrupt and we check whether that number
+ * changed versus the last invocation.
+ *
+ * We could handle all interrupts with the delayed by one
+ * mechanism, but for the non forced threaded case we'd just
+ * add pointless overhead to the straight hardirq interrupts
+ * for the sake of a few lines less code.
+ */
+ if (action_ret & IRQ_WAKE_THREAD) {
+ /*
+ * There is a thread woken. Check whether one of the
+ * shared primary handlers returned IRQ_HANDLED. If
+ * not we defer the spurious detection to the next
+ * interrupt.
+ */
+ if (action_ret == IRQ_WAKE_THREAD) {
+ int handled;
+ /*
+ * We use bit 31 of thread_handled_last to
+ * denote the deferred spurious detection
+ * active. No locking necessary as
+ * thread_handled_last is only accessed here
+ * and we have the guarantee that hard
+ * interrupts are not reentrant.
+ */
+ if (!(desc->threads_handled_last & SPURIOUS_DEFERRED)) {
+ desc->threads_handled_last |= SPURIOUS_DEFERRED;
+ return;
+ }
+ /*
+ * Check whether one of the threaded handlers
+ * returned IRQ_HANDLED since the last
+ * interrupt happened.
+ *
+ * For simplicity we just set bit 31, as it is
+ * set in threads_handled_last as well. So we
+ * avoid extra masking. And we really do not
+ * care about the high bits of the handled
+ * count. We just care about the count being
+ * different than the one we saw before.
+ */
+ handled = atomic_read(&desc->threads_handled);
+ handled |= SPURIOUS_DEFERRED;
+ if (handled != desc->threads_handled_last) {
+ action_ret = IRQ_HANDLED;
+ /*
+ * Note: We keep the SPURIOUS_DEFERRED
+ * bit set. We are handling the
+ * previous invocation right now.
+ * Keep it for the current one, so the
+ * next hardware interrupt will
+ * account for it.
+ */
+ desc->threads_handled_last = handled;
+ } else {
+ /*
+ * None of the threaded handlers felt
+ * responsible for the last interrupt
+ *
+ * We keep the SPURIOUS_DEFERRED bit
+ * set in threads_handled_last as we
+ * need to account for the current
+ * interrupt as well.
+ */
+ action_ret = IRQ_NONE;
+ }
+ } else {
+ /*
+ * One of the primary handlers returned
+ * IRQ_HANDLED. So we don't care about the
+ * threaded handlers on the same line. Clear
+ * the deferred detection bit.
+ *
+ * In theory we could/should check whether the
+ * deferred bit is set and take the result of
+ * the previous run into account here as
+ * well. But it's really not worth the
+ * trouble. If every other interrupt is
+ * handled we never trigger the spurious
+ * detector. And if this is just the one out
+ * of 100k unhandled ones which is handled
+ * then we merily delay the spurious detection
+ * by one hard interrupt. Not a real problem.
+ */
+ desc->threads_handled_last &= ~SPURIOUS_DEFERRED;
+ }
+ }
+
if (unlikely(action_ret == IRQ_NONE)) {
/*
* If we are seeing only the odd spurious IRQ caused by

2014-07-08 19:11:08

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 034/125] USB: cdc-acm: fix write and suspend race

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 5a345c20c17d87099224a4be12e69e5bd7023dca upstream.

Fix race between write() and suspend() which could lead to writes being
dropped (or I/O while suspended) if the device is runtime suspended
while a write request is being processed.

Specifically, suspend() releases the write_lock after determining the
device is idle but before incrementing the susp_count, thus leaving a
window where a concurrent write() can submit an urb.

Fixes: 11ea859d64b6 ("USB: additional power savings for cdc-acm devices
that support remote wakeup")

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/class/cdc-acm.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)

--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1338,18 +1338,15 @@ static int acm_suspend(struct usb_interf
struct acm *acm = usb_get_intfdata(intf);
int cnt;

+ spin_lock_irq(&acm->read_lock);
+ spin_lock(&acm->write_lock);
if (PMSG_IS_AUTO(message)) {
- int b;
-
- spin_lock_irq(&acm->write_lock);
- b = acm->transmitting;
- spin_unlock_irq(&acm->write_lock);
- if (b)
+ if (acm->transmitting) {
+ spin_unlock(&acm->write_lock);
+ spin_unlock_irq(&acm->read_lock);
return -EBUSY;
+ }
}
-
- spin_lock_irq(&acm->read_lock);
- spin_lock(&acm->write_lock);
cnt = acm->susp_count++;
spin_unlock(&acm->write_lock);
spin_unlock_irq(&acm->read_lock);

2014-07-08 19:13:16

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 056/125] drm/radeon: only apply hdmi bpc pll flags when encoder mode is hdmi

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Alex Deucher <[email protected]>

commit 7d5ab3009a8ca777174f6f469277b3922d56fd4b upstream.

May fix display issues with non-HDMI displays.

Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/radeon/atombios_crtc.c | 48 ++++++++++++++++++----------------
1 file changed, 26 insertions(+), 22 deletions(-)

--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -830,14 +830,16 @@ static void atombios_crtc_program_pll(st
args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */
if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_REF_DIV_SRC;
- switch (bpc) {
- case 8:
- default:
- args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_24BPP;
- break;
- case 10:
- args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP;
- break;
+ if (encoder_mode == ATOM_ENCODER_MODE_HDMI) {
+ switch (bpc) {
+ case 8:
+ default:
+ args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_24BPP;
+ break;
+ case 10:
+ args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP;
+ break;
+ }
}
args.v5.ucTransmitterID = encoder_id;
args.v5.ucEncoderMode = encoder_mode;
@@ -852,20 +854,22 @@ static void atombios_crtc_program_pll(st
args.v6.ucMiscInfo = 0; /* HDMI depth, etc. */
if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
- switch (bpc) {
- case 8:
- default:
- args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_24BPP;
- break;
- case 10:
- args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP;
- break;
- case 12:
- args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP;
- break;
- case 16:
- args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP;
- break;
+ if (encoder_mode == ATOM_ENCODER_MODE_HDMI) {
+ switch (bpc) {
+ case 8:
+ default:
+ args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_24BPP;
+ break;
+ case 10:
+ args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP;
+ break;
+ case 12:
+ args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP;
+ break;
+ case 16:
+ args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP;
+ break;
+ }
}
args.v6.ucTransmitterID = encoder_id;
args.v6.ucEncoderMode = encoder_mode;

2014-07-08 19:08:43

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 124/125] skbuff: export skb_copy_ubufs

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: "Michael S. Tsirkin" <[email protected]>

commit dcc0fb782b3a6e2abfeaaeb45dd88ed09596be0f upstream.

Export skb_copy_ubufs so that modules can orphan frags.

Signed-off-by: Michael S. Tsirkin <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/core/skbuff.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -655,7 +655,7 @@ int skb_copy_ubufs(struct sk_buff *skb,
skb_shinfo(skb)->tx_flags &= ~SKBTX_DEV_ZEROCOPY;
return 0;
}
-
+EXPORT_SYMBOL_GPL(skb_copy_ubufs);

/**
* skb_clone - duplicate an sk_buff

2014-07-08 19:13:43

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 055/125] drm/radeon/atom: fix dithering on certain panels

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Alex Deucher <[email protected]>

commit 642528355c694f5ed68f6bff9ff520326a249f99 upstream.

We need to specify the encoder mode as LVDS for eDP
when using the Crtc_Source atom table in order to properly
set up the FMT hardware.

bug:
https://bugs.freedesktop.org/show_bug.cgi?id=73911

Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/radeon/atombios_encoders.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -1626,8 +1626,11 @@ atombios_set_encoder_crtc_source(struct
args.v2.ucEncodeMode = ATOM_ENCODER_MODE_CRT;
else
args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder);
- } else
+ } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+ args.v2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;
+ } else {
args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder);
+ }
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:

2014-07-08 19:13:44

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 054/125] drm/radeon: fix typo in radeon_connector_is_dp12_capable()

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Alex Deucher <[email protected]>

commit af5d36539dfe043f1cf0f8b7334d6bb12cd14e75 upstream.

We were checking the ext clock rather than the display clock.

Noticed by ArtForz on IRC.

Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/radeon/radeon_connectors.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1246,7 +1246,7 @@ bool radeon_connector_is_dp12_capable(st
struct radeon_device *rdev = dev->dev_private;

if (ASIC_IS_DCE5(rdev) &&
- (rdev->clock.dp_extclk >= 53900) &&
+ (rdev->clock.default_dispclk >= 53900) &&
radeon_connector_encoder_is_hbr2(connector)) {
return true;
}

2014-07-08 19:13:41

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 027/125] USB: sierra: fix remote wakeup

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 80cc0fcbdaeaf10d04ba27779a2d7ceb73d2717a upstream.

Make sure that needs_remote_wake up is always set when there are open
ports.

Currently close() would unconditionally set needs_remote_wakeup to 0
even though there might still be open ports. This could lead to blocked
input and possibly dropped data on devices that do not support remote
wakeup (and which must therefore not be runtime suspended while open).

Add an open_ports counter (protected by the susp_lock) and only clear
needs_remote_wakeup when the last port is closed.

Fixes: e6929a9020ac ("USB: support for autosuspend in sierra while
online")

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[bwh: Backported to 3.2: adjust indentation]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/sierra.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)

--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -59,6 +59,7 @@ struct sierra_intf_private {
spinlock_t susp_lock;
unsigned int suspended:1;
int in_flight;
+ unsigned int open_ports;
};

static int sierra_set_power_state(struct usb_device *udev, __u16 swiState)
@@ -814,7 +815,6 @@ static void sierra_close(struct usb_seri
if (serial->dev) {
mutex_lock(&serial->disc_mutex);
if (!serial->disconnected) {
- serial->interface->needs_remote_wakeup = 0;
/* odd error handling due to pm counters */
if (!usb_autopm_get_interface(serial->interface))
sierra_send_setup(port);
@@ -825,6 +825,8 @@ static void sierra_close(struct usb_seri
mutex_unlock(&serial->disc_mutex);
spin_lock_irq(&intfdata->susp_lock);
portdata->opened = 0;
+ if (--intfdata->open_ports == 0)
+ serial->interface->needs_remote_wakeup = 0;
spin_unlock_irq(&intfdata->susp_lock);

for (;;) {
@@ -885,9 +887,10 @@ static int sierra_open(struct tty_struct

sierra_send_setup(port);

- serial->interface->needs_remote_wakeup = 1;
spin_lock_irq(&intfdata->susp_lock);
portdata->opened = 1;
+ if (++intfdata->open_ports == 1)
+ serial->interface->needs_remote_wakeup = 1;
spin_unlock_irq(&intfdata->susp_lock);
usb_autopm_put_interface(serial->interface);

2014-07-08 19:13:39

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 066/125] idr: fix overflow bug during maximum ID calculation at maximum height

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Lai Jiangshan <[email protected]>

commit 3afb69cb5572b3c8c898c00880803cf1a49852c4 upstream.

idr_replace() open-codes the logic to calculate the maximum valid ID
given the height of the idr tree; unfortunately, the open-coded logic
doesn't account for the fact that the top layer may have unused slots
and over-shifts the limit to zero when the tree is at its maximum
height.

The following test code shows it fails to replace the value for
id=((1<<27)+42):

static void test5(void)
{
int id;
DEFINE_IDR(test_idr);
#define TEST5_START ((1<<27)+42) /* use the highest layer */

printk(KERN_INFO "Start test5\n");
id = idr_alloc(&test_idr, (void *)1, TEST5_START, 0, GFP_KERNEL);
BUG_ON(id != TEST5_START);
TEST_BUG_ON(idr_replace(&test_idr, (void *)2, TEST5_START) != (void *)1);
idr_destroy(&test_idr);
printk(KERN_INFO "End of test5\n");
}

Fix the bug by using idr_max() which correctly takes into account the
maximum allowed shift.

sub_alloc() shares the same problem and may incorrectly fail with
-EAGAIN; however, this bug doesn't affect correct operation because
idr_get_empty_slot(), which already uses idr_max(), retries with the
increased @id in such cases.

[[email protected]: Updated patch description.]
Signed-off-by: Lai Jiangshan <[email protected]>
Acked-by: Tejun Heo <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
lib/idr.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)

--- a/lib/idr.c
+++ b/lib/idr.c
@@ -167,7 +167,7 @@ static int sub_alloc(struct idr *idp, in
id = (id | ((1 << (IDR_BITS * l)) - 1)) + 1;

/* if already at the top layer, we need to grow */
- if (id >= 1 << (idp->layers * IDR_BITS)) {
+ if (id > idr_max(idp->layers)) {
*starting_id = id;
return IDR_NEED_TO_GROW;
}
@@ -672,14 +672,12 @@ void *idr_replace(struct idr *idp, void
if (!p)
return ERR_PTR(-EINVAL);

- n = (p->layer+1) * IDR_BITS;
-
id &= MAX_ID_MASK;

- if (id >= (1 << n))
+ if (id > idr_max(p->layer + 1))
return ERR_PTR(-EINVAL);

- n -= IDR_BITS;
+ n = p->layer * IDR_BITS;
while ((n > 0) && p) {
p = p->ary[(id >> n) & IDR_MASK];
n -= IDR_BITS;

2014-07-08 19:14:55

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 025/125] USB: sierra: fix urb and memory leak in resume error path

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 7fdd26a01eb7b6cb6855ff8f69ef4a720720dfcb upstream.

Neither the transfer buffer or the urb itself were released in the
resume error path for delayed writes. Also on errors, the remainder of
the queue was not even processed, which leads to further urb and buffer
leaks.

The same error path also failed to balance the outstanding-urb counter,
something which results in degraded throughput or completely blocked
writes.

Fix this by releasing urb and buffer and balancing counters on errors,
and by always processing the whole queue even when submission of one urb
fails.

Fixes: e6929a9020ac ("USB: support for autosuspend in sierra while
online")

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/sierra.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -1065,8 +1065,12 @@ static int sierra_resume(struct usb_seri
if (err < 0) {
intfdata->in_flight--;
usb_unanchor_urb(urb);
- usb_scuttle_anchored_urbs(&portdata->delayed);
- break;
+ kfree(urb->transfer_buffer);
+ usb_free_urb(urb);
+ spin_lock(&portdata->lock);
+ portdata->outstanding_urbs--;
+ spin_unlock(&portdata->lock);
+ continue;
}
}

2014-07-08 19:15:24

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 029/125] USB: usb_wwan: fix urb leak in write error path

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: xiao jin <[email protected]>

commit db0904737947d509844e171c9863ecc5b4534005 upstream.

When enable usb serial for modem data, sometimes the tty is blocked
in tty_wait_until_sent because portdata->out_busy always is set and
have no chance to be cleared.

We find a bug in write error path. usb_wwan_write set portdata->out_busy
firstly, then try autopm async with error. No out urb submit and no
usb_wwan_outdat_callback to this write, portdata->out_busy can't be
cleared.

This patch clear portdata->out_busy if usb_wwan_write try autopm async
with error.

Fixes: 383cedc3bb43 ("USB: serial: full autosuspend support for the
option driver")

Signed-off-by: xiao jin <[email protected]>
Signed-off-by: Zhang, Qi1 <[email protected]>
Reviewed-by: David Cohen <[email protected]>
Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/usb_wwan.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -236,8 +236,10 @@ int usb_wwan_write(struct tty_struct *tt
usb_pipeendpoint(this_urb->pipe), i);

err = usb_autopm_get_interface_async(port->serial->interface);
- if (err < 0)
+ if (err < 0) {
+ clear_bit(i, &portdata->out_busy);
break;
+ }

/* send the data */
memcpy(this_urb->transfer_buffer, buf, todo);

2014-07-08 19:15:31

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 072/125] drm/radeon: stop poisoning the GART TLB

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Christian König <[email protected]>

commit 0986c1a55ca64b44ee126a2f719a6e9f28cbe0ed upstream.

When we set the valid bit on invalid GART entries they are
loaded into the TLB when an adjacent entry is loaded. This
poisons the TLB with invalid entries which are sometimes
not correctly removed on TLB flush.

For stable inclusion the patch probably needs to be modified a bit.

Signed-off-by: Christian König <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
[bwh: Backported to 3.2: R600_PTE_GART is not defined and we list all the
flags indvidually]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -529,8 +529,11 @@ int rs600_gart_set_page(struct radeon_de
return -EINVAL;
}
addr = addr & 0xFFFFFFFFFFFFF000ULL;
- addr |= R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED;
- addr |= R600_PTE_READABLE | R600_PTE_WRITEABLE;
+ if (addr == rdev->dummy_page.addr)
+ addr |= R600_PTE_SYSTEM | R600_PTE_SNOOPED;
+ else
+ addr |= (R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED |
+ R600_PTE_READABLE | R600_PTE_WRITEABLE);
writeq(addr, ptr + (i * 8));
return 0;
}

2014-07-08 19:15:29

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 033/125] USB: usb_wwan: fix potential blocked I/O after resume

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit fb7ad4f93d9f0f7d49beda32f5e7becb94b29a4d upstream.

Keep trying to submit urbs rather than bail out on first read-urb
submission error, which would also prevent I/O for any further ports
from being resumed.

Instead keep an error count, for all types of failed submissions, and
let USB core know that something went wrong.

Also make sure to always clear the suspended flag. Currently a failed
read-urb submission would prevent cached writes as well as any
subsequent writes from being submitted until next suspend-resume cycle,
something which may not even necessarily happen.

Note that USB core currently only logs an error if an interface resume
failed.

Fixes: 383cedc3bb43 ("USB: serial: full autosuspend support for the
option driver")

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/usb_wwan.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)

--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -688,12 +688,12 @@ int usb_wwan_suspend(struct usb_serial *
}
EXPORT_SYMBOL(usb_wwan_suspend);

-static void play_delayed(struct usb_serial_port *port)
+static int play_delayed(struct usb_serial_port *port)
{
struct usb_wwan_intf_private *data;
struct usb_wwan_port_private *portdata;
struct urb *urb;
- int err;
+ int err = 0;

portdata = usb_get_serial_port_data(port);
data = port->serial->private;
@@ -710,6 +710,8 @@ static void play_delayed(struct usb_seri
break;
}
}
+
+ return err;
}

int usb_wwan_resume(struct usb_serial *serial)
@@ -719,7 +721,8 @@ int usb_wwan_resume(struct usb_serial *s
struct usb_wwan_intf_private *intfdata = serial->private;
struct usb_wwan_port_private *portdata;
struct urb *urb;
- int err = 0;
+ int err;
+ int err_count = 0;

dbg("%s entered", __func__);
/* get the interrupt URBs resubmitted unconditionally */
@@ -734,7 +737,7 @@ int usb_wwan_resume(struct usb_serial *s
if (err < 0) {
err("%s: Error %d for interrupt URB of port%d",
__func__, err, i);
- goto err_out;
+ err_count++;
}
}

@@ -748,22 +751,27 @@ int usb_wwan_resume(struct usb_serial *s
if (!portdata->opened)
continue;

+ err = play_delayed(port);
+ if (err)
+ err_count++;
+
for (j = 0; j < N_IN_URB; j++) {
urb = portdata->in_urbs[j];
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
err("%s: Error %d for bulk URB %d",
__func__, err, i);
- spin_unlock_irq(&intfdata->susp_lock);
- goto err_out;
+ err_count++;
}
}
- play_delayed(port);
}
intfdata->suspended = 0;
spin_unlock_irq(&intfdata->susp_lock);
-err_out:
- return err;
+
+ if (err_count)
+ return -EIO;
+
+ return 0;
}
EXPORT_SYMBOL(usb_wwan_resume);
#endif

2014-07-08 19:15:21

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 031/125] USB: usb_wwan: fix write and suspend race

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 170fad9e22df0063eba0701adb966786d7a4ec5a upstream.

Fix race between write() and suspend() which could lead to writes being
dropped (or I/O while suspended) if the device is runtime suspended
while a write request is being processed.

Specifically, suspend() releases the susp_lock after determining the
device is idle but before setting the suspended flag, thus leaving a
window where a concurrent write() can submit an urb.

Fixes: 383cedc3bb43 ("USB: serial: full autosuspend support for the
option driver")

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/usb_wwan.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)

--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -647,22 +647,19 @@ EXPORT_SYMBOL(usb_wwan_release);
int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message)
{
struct usb_wwan_intf_private *intfdata = serial->private;
- int b;

dbg("%s entered", __func__);

+ spin_lock_irq(&intfdata->susp_lock);
if (PMSG_IS_AUTO(message)) {
- spin_lock_irq(&intfdata->susp_lock);
- b = intfdata->in_flight;
- spin_unlock_irq(&intfdata->susp_lock);
-
- if (b)
+ if (intfdata->in_flight) {
+ spin_unlock_irq(&intfdata->susp_lock);
return -EBUSY;
+ }
}
-
- spin_lock_irq(&intfdata->susp_lock);
intfdata->suspended = 1;
spin_unlock_irq(&intfdata->susp_lock);
+
stop_read_write_urbs(serial);

return 0;

2014-07-08 19:15:19

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 069/125] Input: synaptics - fix resolution for manually provided min/max

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Benjamin Tissoires <[email protected]>

commit d49cb7aeebb974713f9f7ab2991352d3050b095b upstream.

commit 421e08c41fda fixed the reported min/max for the X and Y axis,
but unfortunately, it broke the resolution of those same axis.

On the t540p, the resolution is the same regarding X and Y. It is not
a problem for xf86-input-synaptics because this driver is only interested
in the ratio between X and Y.
Unfortunately, xf86-input-cmt uses directly the resolution, and having a
null resolution leads to some divide by 0 errors, which are translated by
-infinity in the resulting coordinates.

Reported-by: Peter Hutterer <[email protected]>
Signed-off-by: Benjamin Tissoires <[email protected]>
Signed-off-by: Dmitry Torokhov <[email protected]>
[bwh: Backported to 3.2: I didn't apply the PNP ID changes, so the
code being moved looks different]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/input/mouse/synaptics.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)

--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -245,14 +245,6 @@ static int synaptics_resolution(struct p
struct synaptics_data *priv = psmouse->private;
unsigned char resp[3];

- if (quirk_min_max) {
- priv->x_min = quirk_min_max[0];
- priv->x_max = quirk_min_max[1];
- priv->y_min = quirk_min_max[2];
- priv->y_max = quirk_min_max[3];
- return 0;
- }
-
if (SYN_ID_MAJOR(priv->identity) < 4)
return 0;

@@ -263,6 +255,14 @@ static int synaptics_resolution(struct p
}
}

+ if (quirk_min_max) {
+ priv->x_min = quirk_min_max[0];
+ priv->x_max = quirk_min_max[1];
+ priv->y_min = quirk_min_max[2];
+ priv->y_max = quirk_min_max[3];
+ return 0;
+ }
+
if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 &&
SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) {
if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MAX_COORDS, resp)) {

2014-07-08 19:17:12

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 032/125] USB: usb_wwan: fix urb leak at shutdown

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 79eed03e77d481b55d85d1cfe5a1636a0d3897fd upstream.

The delayed-write queue was never emptied at shutdown (close), something
which could lead to leaked urbs if the port is closed before being
runtime resumed due to a write.

When this happens the output buffer would not drain on close
(closing_wait timeout), and after consecutive opens, writes could be
corrupted with previously buffered data, transfered with reduced
throughput or completely blocked.

Note that unbusy_queued_urb() was simply moved out of CONFIG_PM.

Fixes: 383cedc3bb43 ("USB: serial: full autosuspend support for the
option driver")

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[bwh: Backported to 3.2: adjust indentation]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/usb_wwan.c | 34 ++++++++++++++++++++++------------
1 file changed, 22 insertions(+), 12 deletions(-)

--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -434,12 +434,26 @@ int usb_wwan_open(struct tty_struct *tty
}
EXPORT_SYMBOL(usb_wwan_open);

+static void unbusy_queued_urb(struct urb *urb,
+ struct usb_wwan_port_private *portdata)
+{
+ int i;
+
+ for (i = 0; i < N_OUT_URB; i++) {
+ if (urb == portdata->out_urbs[i]) {
+ clear_bit(i, &portdata->out_busy);
+ break;
+ }
+ }
+}
+
void usb_wwan_close(struct usb_serial_port *port)
{
int i;
struct usb_serial *serial = port->serial;
struct usb_wwan_port_private *portdata;
struct usb_wwan_intf_private *intfdata = port->serial->private;
+ struct urb *urb;

dbg("%s", __func__);
portdata = usb_get_serial_port_data(port);
@@ -450,6 +464,14 @@ void usb_wwan_close(struct usb_serial_po
portdata->opened = 0;
spin_unlock_irq(&intfdata->susp_lock);

+ for (;;) {
+ urb = usb_get_from_anchor(&portdata->delayed);
+ if (!urb)
+ break;
+ unbusy_queued_urb(urb, portdata);
+ usb_autopm_put_interface_async(serial->interface);
+ }
+
for (i = 0; i < N_IN_URB; i++)
usb_kill_urb(portdata->in_urbs[i]);
for (i = 0; i < N_OUT_URB; i++)
@@ -666,18 +688,6 @@ int usb_wwan_suspend(struct usb_serial *
}
EXPORT_SYMBOL(usb_wwan_suspend);

-static void unbusy_queued_urb(struct urb *urb, struct usb_wwan_port_private *portdata)
-{
- int i;
-
- for (i = 0; i < N_OUT_URB; i++) {
- if (urb == portdata->out_urbs[i]) {
- clear_bit(i, &portdata->out_busy);
- break;
- }
- }
-}
-
static void play_delayed(struct usb_serial_port *port)
{
struct usb_wwan_intf_private *data;

2014-07-08 19:17:19

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 040/125] USB: ftdi_sio: add NovaTech OrionLXm product ID

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: George McCollister <[email protected]>

commit d0839d757e6294921c31b1c4ca4f1dcc5df63bcd upstream.

The NovaTech OrionLXm uses an onboard FTDI serial converter for JTAG and
console access.

Here is the lsusb output:
Bus 004 Device 123: ID 0403:7c90 Future Technology Devices
International, Ltd

Signed-off-by: George McCollister <[email protected]>
Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/ftdi_sio.c | 2 ++
drivers/usb/serial/ftdi_sio_ids.h | 5 +++++
2 files changed, 7 insertions(+)

--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -591,6 +591,8 @@ static struct usb_device_id id_table_com
{ USB_DEVICE(FTDI_VID, FTDI_TAVIR_STK500_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_TIAO_UMPA_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ { USB_DEVICE(FTDI_VID, FTDI_NT_ORIONLXM_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
/*
* ELV devices:
*/
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -538,6 +538,11 @@
*/
#define FTDI_TIAO_UMPA_PID 0x8a98 /* TIAO/DIYGADGET USB Multi-Protocol Adapter */

+/*
+ * NovaTech product ids (FTDI_VID)
+ */
+#define FTDI_NT_ORIONLXM_PID 0x7c90 /* OrionLXm Substation Automation Platform */
+

/********************************/
/** third-party VID/PID combos **/

2014-07-08 19:17:17

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 045/125] s390/lowcore: reserve 96 bytes for IRB in lowcore

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Christian Borntraeger <[email protected]>

commit 993072ee67aa179c48c85eb19869804e68887d86 upstream.

The IRB might be 96 bytes if the extended-I/O-measurement facility is
used. This feature is currently not used by Linux, but struct irb
already has the emw defined. So let's make the irb in lowcore match the
size of the internal data structure to be future proof.
We also have to add a pad, to correctly align the paste.

The bigger irb field also circumvents a bug in some QEMU versions that
always write the emw field on test subchannel and therefore destroy the
paste definitions of this CPU. Running under these QEMU version broke
some timing functions in the VDSO and all users of these functions,
e.g. some JREs.

Signed-off-by: Christian Borntraeger <[email protected]>
Signed-off-by: Martin Schwidefsky <[email protected]>
Cc: Heiko Carstens <[email protected]>
Cc: Sebastian Ott <[email protected]>
Cc: Cornelia Huck <[email protected]>
[bwh: Backported to 3.2: offsets of the affected fields in the 64-bit version
of struct _lowcore are 128 bytes smaller]
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/s390/include/asm/lowcore.h | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)

--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -140,9 +140,9 @@ struct _lowcore {
__u8 pad_0x02e8[0x0300-0x02e8]; /* 0x02e8 */

/* Interrupt response block */
- __u8 irb[64]; /* 0x0300 */
+ __u8 irb[96]; /* 0x0300 */

- __u8 pad_0x0340[0x0e00-0x0340]; /* 0x0340 */
+ __u8 pad_0x0360[0x0e00-0x0360]; /* 0x0360 */

/*
* 0xe00 contains the address of the IPL Parameter Information
@@ -274,12 +274,13 @@ struct _lowcore {
__u64 cmf_hpp; /* 0x0378 */

/* Interrupt response block. */
- __u8 irb[64]; /* 0x0380 */
+ __u8 irb[96]; /* 0x0380 */
+ __u8 pad_0x03e0[0x0400-0x03e0]; /* 0x03e0 */

/* Per cpu primary space access list */
- __u32 paste[16]; /* 0x03c0 */
+ __u32 paste[16]; /* 0x0400 */

- __u8 pad_0x0400[0x0e00-0x0400]; /* 0x0400 */
+ __u8 pad_0x0440[0x0e00-0x0440]; /* 0x0440 */

/*
* 0xe00 contains the address of the IPL Parameter Information

2014-07-08 19:17:13

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 035/125] USB: cdc-acm: fix write and resume race

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit e144ed28bed10684f9aaec6325ed974d53f76110 upstream.

Fix race between write() and resume() due to improper locking that could
lead to writes being reordered.

Resume must be done atomically and susp_count be protected by the
write_lock in order to prevent racing with write(). This could otherwise
lead to writes being reordered if write() grabs the write_lock after
susp_count is decremented, but before the delayed urb is submitted.

Fixes: 11ea859d64b6 ("USB: additional power savings for cdc-acm devices
that support remote wakeup")

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[bwh: Backported to 3.2:
- Adjust context
- Move mutex_lock(acm->mutex) above acquisition of spinlocks]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/class/cdc-acm.c | 23 +++++++++--------------
1 file changed, 9 insertions(+), 14 deletions(-)

--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1371,28 +1371,21 @@ static int acm_resume(struct usb_interfa
struct acm *acm = usb_get_intfdata(intf);
struct acm_wb *wb;
int rv = 0;
- int cnt;

+ mutex_lock(&acm->mutex);
spin_lock_irq(&acm->read_lock);
- acm->susp_count -= 1;
- cnt = acm->susp_count;
- spin_unlock_irq(&acm->read_lock);
+ spin_lock(&acm->write_lock);

- if (cnt)
- return 0;
+ if (--acm->susp_count)
+ goto out;

- mutex_lock(&acm->mutex);
if (acm->port.count) {
- rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO);
+ rv = usb_submit_urb(acm->ctrlurb, GFP_ATOMIC);

- spin_lock_irq(&acm->write_lock);
if (acm->delayed_wb) {
wb = acm->delayed_wb;
acm->delayed_wb = NULL;
- spin_unlock_irq(&acm->write_lock);
acm_start_wb(acm, wb);
- } else {
- spin_unlock_irq(&acm->write_lock);
}

/*
@@ -1400,13 +1393,15 @@ static int acm_resume(struct usb_interfa
* do the write path at all cost
*/
if (rv < 0)
- goto err_out;
+ goto out;

- rv = acm_submit_read_urbs(acm, GFP_NOIO);
+ rv = acm_submit_read_urbs(acm, GFP_ATOMIC);
}
-
-err_out:
+out:
+ spin_unlock(&acm->write_lock);
+ spin_unlock_irq(&acm->read_lock);
mutex_unlock(&acm->mutex);
+
return rv;
}

2014-07-08 19:17:10

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 028/125] USB: option: fix runtime PM handling

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit acf47d4f9c39b1cba467aa9442fc2efe0b1da741 upstream.

Fix potential I/O while runtime suspended due to missing PM operations
in send_setup.

Fixes: 383cedc3bb43 ("USB: serial: full autosuspend support for the
option driver")

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -1955,6 +1955,7 @@ static int option_send_setup(struct usb_
struct usb_wwan_port_private *portdata;
int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
int val = 0;
+ int res;
dbg("%s", __func__);

if (is_blacklisted(ifNum, OPTION_BLACKLIST_SENDSETUP,
@@ -1970,9 +1971,16 @@ static int option_send_setup(struct usb_
if (portdata->rts_state)
val |= 0x02;

- return usb_control_msg(serial->dev,
- usb_rcvctrlpipe(serial->dev, 0),
+ res = usb_autopm_get_interface(serial->interface);
+ if (res)
+ return res;
+
+ res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
0x22, 0x21, val, ifNum, NULL, 0, USB_CTRL_SET_TIMEOUT);
+
+ usb_autopm_put_interface(serial->interface);
+
+ return res;
}

MODULE_AUTHOR(DRIVER_AUTHOR);

2014-07-08 19:17:08

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 026/125] USB: sierra: fix urb and memory leak on disconnect

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 014333f77c0b71123d6ef7d31a9724e0699c9548 upstream.

The delayed-write queue was never emptied on disconnect, something which
would lead to leaked urbs and transfer buffers if the device is
disconnected before being runtime resumed due to a write.

Fixes: e6929a9020ac ("USB: support for autosuspend in sierra while
online")

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[bwh: Backported to 3.2: adjust context, indentation]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/sierra.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -802,6 +802,7 @@ static void sierra_close(struct usb_seri
struct usb_serial *serial = port->serial;
struct sierra_port_private *portdata;
struct sierra_intf_private *intfdata = port->serial->private;
+ struct urb *urb;


dev_dbg(&port->dev, "%s\n", __func__);
@@ -826,6 +827,17 @@ static void sierra_close(struct usb_seri
portdata->opened = 0;
spin_unlock_irq(&intfdata->susp_lock);

+ for (;;) {
+ urb = usb_get_from_anchor(&portdata->delayed);
+ if (!urb)
+ break;
+ kfree(urb->transfer_buffer);
+ usb_free_urb(urb);
+ usb_autopm_put_interface_async(serial->interface);
+ spin_lock(&portdata->lock);
+ portdata->outstanding_urbs--;
+ spin_unlock(&portdata->lock);
+ }

/* Stop reading urbs */
sierra_stop_rx_urbs(port);

2014-07-08 19:17:05

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 036/125] USB: cdc-acm: fix broken runtime suspend

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 140cb81ac8c625942a1d695875932c615767a526 upstream.

The current ACM runtime-suspend implementation is broken in several
ways:

Firstly, it buffers only the first write request being made while
suspended -- any further writes are silently dropped.

Secondly, writes being dropped also leak write urbs, which are never
reclaimed (until the device is unbound).

Thirdly, even the single buffered write is not cleared at shutdown
(which may happen before the device is resumed), something which can
lead to another urb leak as well as a PM usage-counter leak.

Fix this by implementing a delayed-write queue using urb anchors and
making sure to discard the queue properly at shutdown.

Fixes: 11ea859d64b6 ("USB: additional power savings for cdc-acm devices
that support remote wakeup")

Reported-by: Xiao Jin <[email protected]>
Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/class/cdc-acm.c | 32 ++++++++++++++++++++++----------
drivers/usb/class/cdc-acm.h | 2 +-
2 files changed, 23 insertions(+), 11 deletions(-)

--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -183,12 +183,9 @@ static int acm_write_start(struct acm *a
acm->susp_count);
usb_autopm_get_interface_async(acm->control);
if (acm->susp_count) {
- if (!acm->delayed_wb)
- acm->delayed_wb = wb;
- else
- usb_autopm_put_interface_async(acm->control);
+ usb_anchor_urb(wb->urb, &acm->delayed);
spin_unlock_irqrestore(&acm->write_lock, flags);
- return 0; /* A white lie */
+ return 0;
}
usb_mark_last_busy(acm->dev);

@@ -545,11 +542,23 @@ static void acm_tty_unregister(struct ac

static void acm_port_down(struct acm *acm)
{
+ struct urb *urb;
+ struct acm_wb *wb;
int i;

if (acm->dev) {
usb_autopm_get_interface(acm->control);
acm_set_control(acm, acm->ctrlout = 0);
+
+ for (;;) {
+ urb = usb_get_from_anchor(&acm->delayed);
+ if (!urb)
+ break;
+ wb = urb->context;
+ wb->use = 0;
+ usb_autopm_put_interface_async(acm->control);
+ }
+
usb_kill_urb(acm->ctrlurb);
for (i = 0; i < ACM_NW; i++)
usb_kill_urb(acm->wb[i].urb);
@@ -1112,6 +1121,7 @@ made_compressed_probe:
acm->bInterval = epread->bInterval;
tty_port_init(&acm->port);
acm->port.ops = &acm_port_ops;
+ init_usb_anchor(&acm->delayed);

buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
if (!buf) {
@@ -1369,7 +1379,7 @@ static int acm_suspend(struct usb_interf
static int acm_resume(struct usb_interface *intf)
{
struct acm *acm = usb_get_intfdata(intf);
- struct acm_wb *wb;
+ struct urb *urb;
int rv = 0;

mutex_lock(&acm->mutex);
@@ -1382,10 +1392,12 @@ static int acm_resume(struct usb_interfa
if (acm->port.count) {
rv = usb_submit_urb(acm->ctrlurb, GFP_ATOMIC);

- if (acm->delayed_wb) {
- wb = acm->delayed_wb;
- acm->delayed_wb = NULL;
- acm_start_wb(acm, wb);
+ for (;;) {
+ urb = usb_get_from_anchor(&acm->delayed);
+ if (!urb)
+ break;
+
+ acm_start_wb(acm, urb->context);
}

/*
--- a/drivers/usb/class/cdc-acm.h
+++ b/drivers/usb/class/cdc-acm.h
@@ -116,7 +116,7 @@ struct acm {
unsigned int throttled:1; /* actually throttled */
unsigned int throttle_req:1; /* throttle requested */
u8 bInterval;
- struct acm_wb *delayed_wb; /* write queued for a device about to be woken */
+ struct usb_anchor delayed; /* writes queued for a device about to be woken */
};

#define CDC_DATA_INTERFACE_TYPE 0x0a

2014-07-08 19:19:21

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 044/125] md: always set MD_RECOVERY_INTR when aborting a reshape or other "resync".

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: NeilBrown <[email protected]>

commit 3991b31ea072b070081ca3bfa860a077eda67de5 upstream.

If mddev->ro is set, md_to_sync will (correctly) abort.
However in that case MD_RECOVERY_INTR isn't set.

If a RESHAPE had been requested, then ->finish_reshape() will be
called and it will think the reshape was successful even though
nothing happened.

Normally a resync will not be requested if ->ro is set, but if an
array is stopped while a reshape is on-going, then when the array is
started, the reshape will be restarted. If the array is also set
read-only at this point, the reshape will instantly appear to success,
resulting in data corruption.

Consequently, this patch is suitable for any -stable kernel.

Signed-off-by: NeilBrown <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/md/md.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -7035,8 +7035,10 @@ void md_do_sync(struct mddev *mddev)
/* just incase thread restarts... */
if (test_bit(MD_RECOVERY_DONE, &mddev->recovery))
return;
- if (mddev->ro) /* never try to sync a read-only array */
+ if (mddev->ro) {/* never try to sync a read-only array */
+ set_bit(MD_RECOVERY_INTR, &mddev->recovery);
return;
+ }

if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))

2014-07-08 19:19:29

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 074/125] watchdog: ath79_wdt: avoid spurious restarts on AR934x

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Gabor Juhos <[email protected]>

commit 23afeb613ec0e10aecfae7838a14d485db62ac52 upstream.

On some AR934x based systems, where the frequency of
the AHB bus is relatively high, the built-in watchdog
causes a spurious restart when it gets enabled.

The possible cause of these restarts is that the timeout
value written into the TIMER register does not reaches
the hardware in time.

Add an explicit delay into the ath79_wdt_enable function
to avoid the spurious restarts.

Signed-off-by: Gabor Juhos <[email protected]>
Reviewed-by: Guenter Roeck <[email protected]>
Signed-off-by: Wim Van Sebroeck <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/watchdog/ath79_wdt.c | 10 ++++++++++
1 file changed, 10 insertions(+)

--- a/drivers/watchdog/ath79_wdt.c
+++ b/drivers/watchdog/ath79_wdt.c
@@ -18,6 +18,7 @@
*/

#include <linux/bitops.h>
+#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/init.h>
@@ -73,6 +74,15 @@ static inline void ath79_wdt_keepalive(v
static inline void ath79_wdt_enable(void)
{
ath79_wdt_keepalive();
+
+ /*
+ * Updating the TIMER register requires a few microseconds
+ * on the AR934x SoCs at least. Use a small delay to ensure
+ * that the TIMER register is updated within the hardware
+ * before enabling the watchdog.
+ */
+ udelay(2);
+
ath79_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_FCR);
}

2014-07-08 19:19:27

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 043/125] powerpc: Fix 64 bit builds with binutils 2.24

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Guenter Roeck <[email protected]>

commit 7998eb3dc700aaf499f93f50b3d77da834ef9e1d upstream.

With binutils 2.24, various 64 bit builds fail with relocation errors
such as

arch/powerpc/kernel/built-in.o: In function `exc_debug_crit_book3e':
(.text+0x165ee): relocation truncated to fit: R_PPC64_ADDR16_HI
against symbol `interrupt_base_book3e' defined in .text section
in arch/powerpc/kernel/built-in.o
arch/powerpc/kernel/built-in.o: In function `exc_debug_crit_book3e':
(.text+0x16602): relocation truncated to fit: R_PPC64_ADDR16_HI
against symbol `interrupt_end_book3e' defined in .text section
in arch/powerpc/kernel/built-in.o

The assembler maintainer says:

I changed the ABI, something that had to be done but unfortunately
happens to break the booke kernel code. When building up a 64-bit
value with lis, ori, shl, oris, ori or similar sequences, you now
should use @high and @higha in place of @h and @ha. @h and @ha
(and their associated relocs R_PPC64_ADDR16_HI and R_PPC64_ADDR16_HA)
now report overflow if the value is out of 32-bit signed range.
ie. @h and @ha assume you're building a 32-bit value. This is needed
to report out-of-range -mcmodel=medium toc pointer offsets in @toc@h
and @toc@ha expressions, and for consistency I did the same for all
other @h and @ha relocs.

Replacing @h with @high in one strategic location fixes the relocation
errors. This has to be done conditionally since the assembler either
supports @h or @high but not both.

Signed-off-by: Guenter Roeck <[email protected]>
Signed-off-by: Benjamin Herrenschmidt <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/powerpc/Makefile | 4 +++-
arch/powerpc/include/asm/ppc_asm.h | 7 ++++++-
2 files changed, 9 insertions(+), 2 deletions(-)

--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -69,7 +69,9 @@ LDFLAGS_vmlinux := $(LDFLAGS_vmlinux-yy)

CFLAGS-$(CONFIG_PPC64) := -mminimal-toc -mtraceback=no -mcall-aixdesc
CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 -mmultiple
-KBUILD_CPPFLAGS += -Iarch/$(ARCH)
+asinstr := $(call as-instr,lis 9$(comma)foo@high,-DHAVE_AS_ATHIGH=1)
+
+KBUILD_CPPFLAGS += -Iarch/$(ARCH) $(asinstr)
KBUILD_AFLAGS += -Iarch/$(ARCH)
KBUILD_CFLAGS += -msoft-float -pipe -Iarch/$(ARCH) $(CFLAGS-y)
CPP = $(CC) -E $(KBUILD_CFLAGS)
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -292,11 +292,16 @@ n:
* ld rY,ADDROFF(name)(rX)
*/
#ifdef __powerpc64__
+#ifdef HAVE_AS_ATHIGH
+#define __AS_ATHIGH high
+#else
+#define __AS_ATHIGH h
+#endif
#define LOAD_REG_IMMEDIATE(reg,expr) \
lis (reg),(expr)@highest; \
ori (reg),(reg),(expr)@higher; \
rldicr (reg),(reg),32,31; \
- oris (reg),(reg),(expr)@h; \
+ oris reg,reg,(expr)@__AS_ATHIGH; \
ori (reg),(reg),(expr)@l;

#define LOAD_REG_ADDR(reg,name) \

2014-07-08 19:19:24

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 058/125] nfsd4: use recall_lock for delegation hashing

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Benny Halevy <[email protected]>

commit 931ee56c67573eb4e51c8a4e78598d965b8b059e upstream.

This fixes a bug in the handling of the fi_delegations list.

nfs4_setlease does not hold the recall_lock when adding to it. The
client_mutex is held, which prevents against concurrent list changes,
but nfsd_break_deleg_cb does not hold while walking it. New delegations
could theoretically creep onto the list while we're walking it there.

Signed-off-by: Benny Halevy <[email protected]>
Signed-off-by: Jeff Layton <[email protected]>
Signed-off-by: J. Bruce Fields <[email protected]>
[bwh: Backported to 3.2:
- Adjust context
- Also remove a list_del_init() in nfs4_setlease() which would now be
before the corresponding list_add()
- Drop change to nfsd_find_all_delegations(), which doesn't exist]
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/nfsd/nfs4state.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)

--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -337,13 +337,22 @@ static void unhash_stid(struct nfs4_stid
idr_remove(stateids, s->sc_stateid.si_opaque.so_id);
}

+static void
+hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp)
+{
+ lockdep_assert_held(&recall_lock);
+
+ list_add(&dp->dl_perfile, &fp->fi_delegations);
+ list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations);
+}
+
/* Called under the state lock. */
static void
unhash_delegation(struct nfs4_delegation *dp)
{
unhash_stid(&dp->dl_stid);
- list_del_init(&dp->dl_perclnt);
spin_lock(&recall_lock);
+ list_del_init(&dp->dl_perclnt);
list_del_init(&dp->dl_perfile);
list_del_init(&dp->dl_recall_lru);
spin_unlock(&recall_lock);
@@ -2810,10 +2819,8 @@ static int nfs4_setlease(struct nfs4_del
if (!fl)
return -ENOMEM;
fl->fl_file = find_readable_file(fp);
- list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations);
status = vfs_setlease(fl->fl_file, fl->fl_type, &fl);
if (status) {
- list_del_init(&dp->dl_perclnt);
locks_free_lock(fl);
return -ENOMEM;
}
@@ -2821,7 +2828,9 @@ static int nfs4_setlease(struct nfs4_del
fp->fi_deleg_file = fl->fl_file;
get_file(fp->fi_deleg_file);
atomic_set(&fp->fi_delegees, 1);
- list_add(&dp->dl_perfile, &fp->fi_delegations);
+ spin_lock(&recall_lock);
+ hash_delegation_locked(dp, fp);
+ spin_unlock(&recall_lock);
return 0;
}

@@ -2837,9 +2846,8 @@ static int nfs4_set_delegation(struct nf
return -EAGAIN;
}
atomic_inc(&fp->fi_delegees);
- list_add(&dp->dl_perfile, &fp->fi_delegations);
+ hash_delegation_locked(dp, fp);
spin_unlock(&recall_lock);
- list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations);
return 0;
}

2014-07-08 19:19:22

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 061/125] ALSA: hda/realtek - Add support of ALC891 codec

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Kailang Yang <[email protected]>

commit b6c5fbad16aa5026f508093a8d651c25e1cb6179 upstream.

New codec support for ALC891.

Signed-off-by: Kailang Yang <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
sound/pci/hda/patch_realtek.c | 1 +
1 file changed, 1 insertion(+)

--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -6056,6 +6056,7 @@ static const struct hda_codec_preset snd
{ .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
{ .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 },
{ .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
+ { .id = 0x10ec0867, .name = "ALC891", .patch = patch_alc882 },
{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },

2014-07-08 19:19:19

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 049/125] IB/umad: Fix error handling

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Bart Van Assche <[email protected]>

commit 8ec0a0e6b58218bdc1db91dd70ebfcd6ad8dd6cd upstream.

Avoid leaking a kref count in ib_umad_open() if port->ib_dev == NULL
or if nonseekable_open() fails.

Avoid leaking a kref count, that sm_sem is kept down and also that the
IB_PORT_SM capability mask is not cleared in ib_umad_sm_open() if
nonseekable_open() fails.

Since container_of() never returns NULL, remove the code that tests
whether container_of() returns NULL.

Moving the kref_get() call from the start of ib_umad_*open() to the
end is safe since it is the responsibility of the caller of these
functions to ensure that the cdev pointer remains valid until at least
when these functions return.

Signed-off-by: Bart Van Assche <[email protected]>

[[email protected]: rework a bit to reduce the amount of code changed]

Signed-off-by: Yann Droneaud <[email protected]>

[ nonseekable_open() can't actually fail, but.... - Roland ]

Signed-off-by: Roland Dreier <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/infiniband/core/user_mad.c | 49 +++++++++++++++++++++-----------------
1 file changed, 27 insertions(+), 22 deletions(-)

--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -780,27 +780,19 @@ static int ib_umad_open(struct inode *in
{
struct ib_umad_port *port;
struct ib_umad_file *file;
- int ret;
+ int ret = -ENXIO;

port = container_of(inode->i_cdev, struct ib_umad_port, cdev);
- if (port)
- kref_get(&port->umad_dev->ref);
- else
- return -ENXIO;

mutex_lock(&port->file_mutex);

- if (!port->ib_dev) {
- ret = -ENXIO;
+ if (!port->ib_dev)
goto out;
- }

+ ret = -ENOMEM;
file = kzalloc(sizeof *file, GFP_KERNEL);
- if (!file) {
- kref_put(&port->umad_dev->ref, ib_umad_release_dev);
- ret = -ENOMEM;
+ if (!file)
goto out;
- }

mutex_init(&file->mutex);
spin_lock_init(&file->send_lock);
@@ -814,6 +806,13 @@ static int ib_umad_open(struct inode *in
list_add_tail(&file->port_list, &port->file_list);

ret = nonseekable_open(inode, filp);
+ if (ret) {
+ list_del(&file->port_list);
+ kfree(file);
+ goto out;
+ }
+
+ kref_get(&port->umad_dev->ref);

out:
mutex_unlock(&port->file_mutex);
@@ -880,10 +879,6 @@ static int ib_umad_sm_open(struct inode
int ret;

port = container_of(inode->i_cdev, struct ib_umad_port, sm_cdev);
- if (port)
- kref_get(&port->umad_dev->ref);
- else
- return -ENXIO;

if (filp->f_flags & O_NONBLOCK) {
if (down_trylock(&port->sm_sem)) {
@@ -898,17 +893,27 @@ static int ib_umad_sm_open(struct inode
}

ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props);
- if (ret) {
- up(&port->sm_sem);
- goto fail;
- }
+ if (ret)
+ goto err_up_sem;

filp->private_data = port;

- return nonseekable_open(inode, filp);
+ ret = nonseekable_open(inode, filp);
+ if (ret)
+ goto err_clr_sm_cap;
+
+ kref_get(&port->umad_dev->ref);
+
+ return 0;
+
+err_clr_sm_cap:
+ swap(props.set_port_cap_mask, props.clr_port_cap_mask);
+ ib_modify_port(port->ib_dev, port->port_num, 0, &props);
+
+err_up_sem:
+ up(&port->sm_sem);

fail:
- kref_put(&port->umad_dev->ref, ib_umad_release_dev);
return ret;
}

2014-07-08 19:19:18

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 038/125] USB: cdc-acm: fix potential urb leak and PM imbalance in write

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 183a45087d126d126e8dd1d9b2602fc129dff9ad upstream.

Make sure to check return value of autopm get in write() in order to
avoid urb leak and PM counter imbalance on errors.

Fixes: 11ea859d64b6 ("USB: additional power savings for cdc-acm devices
that support remote wakeup")

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[bwh: Backported to 3.2:
- Adjust context
- Error/status variable is called rc, not stat]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/class/cdc-acm.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -191,7 +191,13 @@ static int acm_write_start(struct acm *a

dev_vdbg(&acm->data->dev, "%s - susp_count %d\n", __func__,
acm->susp_count);
- usb_autopm_get_interface_async(acm->control);
+ rc = usb_autopm_get_interface_async(acm->control);
+ if (rc) {
+ wb->use = 0;
+ spin_unlock_irqrestore(&acm->write_lock, flags);
+ return rc;
+ }
+
if (acm->susp_count) {
usb_anchor_urb(wb->urb, &acm->delayed);
spin_unlock_irqrestore(&acm->write_lock, flags);

2014-07-08 19:19:16

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 046/125] mac80211: don't check netdev state for debugfs read/write

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Arik Nemtsov <[email protected]>

commit 923eaf367206e01f22c97aee22300e332d071916 upstream.

Doing so will lead to an oops for a p2p-dev interface, since it has
no netdev.

Signed-off-by: Arik Nemtsov <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/mac80211/debugfs_netdev.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -33,8 +33,7 @@ static ssize_t ieee80211_if_read(
ssize_t ret = -EINVAL;

read_lock(&dev_base_lock);
- if (sdata->dev->reg_state == NETREG_REGISTERED)
- ret = (*format)(sdata, buf, sizeof(buf));
+ ret = (*format)(sdata, buf, sizeof(buf));
read_unlock(&dev_base_lock);

if (ret >= 0)
@@ -62,8 +61,7 @@ static ssize_t ieee80211_if_write(

ret = -ENODEV;
rtnl_lock();
- if (sdata->dev->reg_state == NETREG_REGISTERED)
- ret = (*write)(sdata, buf, count);
+ ret = (*write)(sdata, buf, count);
rtnl_unlock();

freebuf:

2014-07-08 19:21:36

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 071/125] Btrfs: fix double free in find_lock_delalloc_range

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Chris Mason <[email protected]>

commit 7d78874273463a784759916fc3e0b4e2eb141c70 upstream.

We need to NULL the cached_state after freeing it, otherwise
we might free it again if find_delalloc_range doesn't find anything.

Signed-off-by: Chris Mason <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/btrfs/extent_io.c | 1 +
1 file changed, 1 insertion(+)

--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -1523,6 +1523,7 @@ again:
* shortening the size of the delalloc range we're searching
*/
free_extent_state(cached_state);
+ cached_state = NULL;
if (!loops) {
unsigned long offset = (*start) & (PAGE_CACHE_SIZE - 1);
max_bytes = PAGE_CACHE_SIZE - offset;

2014-07-08 19:21:39

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 070/125] nfsd4: fix FREE_STATEID lockowner leak

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: "J. Bruce Fields" <[email protected]>

commit 48385408b45523d9a432c66292d47ef43efcbb94 upstream.

27b11428b7de ("nfsd4: remove lockowner when removing lock stateid")
introduced a memory leak.

Reported-by: Jeff Layton <[email protected]>
Signed-off-by: J. Bruce Fields <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/nfsd/nfs4state.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -3393,7 +3393,7 @@ nfsd4_free_lock_stateid(struct nfs4_ol_s
* correspondance, and we have to delete the lockowner when we
* delete the lock stateid:
*/
- unhash_lockowner(lo);
+ release_lockowner(lo);
return nfs_ok;
}

2014-07-08 19:21:37

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 063/125] mm: vmscan: clear kswapd's special reclaim powers before exiting

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Johannes Weiner <[email protected]>

commit 71abdc15adf8c702a1dd535f8e30df50758848d2 upstream.

When kswapd exits, it can end up taking locks that were previously held
by allocating tasks while they waited for reclaim. Lockdep currently
warns about this:

On Wed, May 28, 2014 at 06:06:34PM +0800, Gu Zheng wrote:
> inconsistent {RECLAIM_FS-ON-W} -> {IN-RECLAIM_FS-R} usage.
> kswapd2/1151 [HC0[0]:SC0[0]:HE1:SE1] takes:
> (&sig->group_rwsem){+++++?}, at: exit_signals+0x24/0x130
> {RECLAIM_FS-ON-W} state was registered at:
> mark_held_locks+0xb9/0x140
> lockdep_trace_alloc+0x7a/0xe0
> kmem_cache_alloc_trace+0x37/0x240
> flex_array_alloc+0x99/0x1a0
> cgroup_attach_task+0x63/0x430
> attach_task_by_pid+0x210/0x280
> cgroup_procs_write+0x16/0x20
> cgroup_file_write+0x120/0x2c0
> vfs_write+0xc0/0x1f0
> SyS_write+0x4c/0xa0
> tracesys+0xdd/0xe2
> irq event stamp: 49
> hardirqs last enabled at (49): _raw_spin_unlock_irqrestore+0x36/0x70
> hardirqs last disabled at (48): _raw_spin_lock_irqsave+0x2b/0xa0
> softirqs last enabled at (0): copy_process.part.24+0x627/0x15f0
> softirqs last disabled at (0): (null)
>
> other info that might help us debug this:
> Possible unsafe locking scenario:
>
> CPU0
> ----
> lock(&sig->group_rwsem);
> <Interrupt>
> lock(&sig->group_rwsem);
>
> *** DEADLOCK ***
>
> no locks held by kswapd2/1151.
>
> stack backtrace:
> CPU: 30 PID: 1151 Comm: kswapd2 Not tainted 3.10.39+ #4
> Call Trace:
> dump_stack+0x19/0x1b
> print_usage_bug+0x1f7/0x208
> mark_lock+0x21d/0x2a0
> __lock_acquire+0x52a/0xb60
> lock_acquire+0xa2/0x140
> down_read+0x51/0xa0
> exit_signals+0x24/0x130
> do_exit+0xb5/0xa50
> kthread+0xdb/0x100
> ret_from_fork+0x7c/0xb0

This is because the kswapd thread is still marked as a reclaimer at the
time of exit. But because it is exiting, nobody is actually waiting on
it to make reclaim progress anymore, and it's nothing but a regular
thread at this point. Be tidy and strip it of all its powers
(PF_MEMALLOC, PF_SWAPWRITE, PF_KSWAPD, and the lockdep reclaim state)
before returning from the thread function.

Signed-off-by: Johannes Weiner <[email protected]>
Reported-by: Gu Zheng <[email protected]>
Cc: Yasuaki Ishimatsu <[email protected]>
Cc: Tang Chen <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
mm/vmscan.c | 3 +++
1 file changed, 3 insertions(+)

--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3016,7 +3016,10 @@ static int kswapd(void *p)
}
}

+ tsk->flags &= ~(PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD);
current->reclaim_state = NULL;
+ lockdep_clear_current_reclaim_state();
+
return 0;
}

2014-07-08 19:21:34

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 057/125] ahci: Add Device ID for HighPoint RocketRaid 642L

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Jérôme Carretero <[email protected]>

commit d251836508fb26cd1a22b41381739835ee23728d upstream.

This device normally comes with a proprietary driver, using a web GUI
to configure RAID:
http://www.highpoint-tech.com/USA_new/series_rr600-download.htm
But thankfully it also works out of the box with the AHCI driver,
being just a Marvell 88SE9235.

Devices 640L, 644L, 644LS should also be supported but not tested here.

Signed-off-by: Jérôme Carretero <[email protected]>
Signed-off-by: Tejun Heo <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/ata/ahci.c | 2 ++
1 file changed, 2 insertions(+)

--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -458,6 +458,8 @@ static const struct pci_device_id ahci_p
.driver_data = board_ahci_yes_fbs },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9230),
.driver_data = board_ahci_yes_fbs },
+ { PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0642),
+ .driver_data = board_ahci_yes_fbs },

/* Promise */
{ PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */

2014-07-08 19:23:02

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 068/125] Input: elantech - don't set bit 1 of reg_10 when the no_hw_res quirk is set

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Hans de Goede <[email protected]>

commit fb4f8f568a9def02240ef9bf7aabd246dc63a081 upstream.

The touchpad on the GIGABYTE U2442 not only stops communicating when we try
to set bit 3 (enable real hardware resolution) of reg_10, but on some BIOS
versions also when we set bit 1 (enable two finger mode auto correct).

I've asked the original reporter of:
https://bugzilla.kernel.org/show_bug.cgi?id=61151

To check that not setting bit 1 does not lead to any adverse effects on his
model / BIOS revision, and it does not, so this commit fixes the touchpad
not working on these versions by simply never setting bit 1 for laptop
models with the no_hw_res quirk.

Reported-and-tested-by: James Lademann <[email protected]>
Tested-by: Philipp Wolfer <[email protected]>
Signed-off-by: Hans de Goede <[email protected]>
Signed-off-by: Dmitry Torokhov <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/input/mouse/elantech.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -801,7 +801,7 @@ static int elantech_set_absolute_mode(st
if (etd->set_hw_resolution)
etd->reg_10 = 0x0b;
else
- etd->reg_10 = 0x03;
+ etd->reg_10 = 0x01;

if (elantech_write_reg(psmouse, 0x10, etd->reg_10))
rc = -1;
@@ -1225,7 +1225,8 @@ static int elantech_reconnect(struct psm
}

/*
- * Some hw_version 3 models go into error state when we try to set bit 3 of r10
+ * Some hw_version 3 models go into error state when we try to set
+ * bit 3 and/or bit 1 of r10.
*/
static const struct dmi_system_id no_hw_res_dmi_table[] = {
#if defined(CONFIG_DMI) && defined(CONFIG_X86)

2014-07-08 19:23:00

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 059/125] mm: fix sleeping function warning from __put_anon_vma

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Hugh Dickins <[email protected]>

commit 7f39dda9d86fb4f4f17af0de170decf125726f8c upstream.

Trinity reports BUG:

sleeping function called from invalid context at kernel/locking/rwsem.c:47
in_atomic(): 0, irqs_disabled(): 0, pid: 5787, name: trinity-c27

__might_sleep < down_write < __put_anon_vma < page_get_anon_vma <
migrate_pages < compact_zone < compact_zone_order < try_to_compact_pages ..

Right, since conversion to mutex then rwsem, we should not put_anon_vma()
from inside an rcu_read_lock()ed section: fix the two places that did so.
And add might_sleep() to anon_vma_free(), as suggested by Peter Zijlstra.

Fixes: 88c22088bf23 ("mm: optimize page_lock_anon_vma() fast-path")
Reported-by: Dave Jones <[email protected]>
Signed-off-by: Hugh Dickins <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
mm/rmap.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -103,6 +103,7 @@ static inline void anon_vma_free(struct
* LOCK should suffice since the actual taking of the lock must
* happen _before_ what follows.
*/
+ might_sleep();
if (mutex_is_locked(&anon_vma->root->mutex)) {
anon_vma_lock(anon_vma);
anon_vma_unlock(anon_vma);
@@ -434,8 +435,9 @@ struct anon_vma *page_get_anon_vma(struc
* above cannot corrupt).
*/
if (!page_mapped(page)) {
+ rcu_read_unlock();
put_anon_vma(anon_vma);
- anon_vma = NULL;
+ return NULL;
}
out:
rcu_read_unlock();
@@ -485,9 +487,9 @@ struct anon_vma *page_lock_anon_vma(stru
}

if (!page_mapped(page)) {
+ rcu_read_unlock();
put_anon_vma(anon_vma);
- anon_vma = NULL;
- goto out;
+ return NULL;
}

/* we pinned the anon_vma, its safe to sleep */

2014-07-08 19:22:59

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 067/125] Input: elantech - deal with clickpads reporting right button events

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Hans de Goede <[email protected]>

commit cd9e83e2754465856097f31c7ab933ce74c473f8 upstream.

At least the Dell Vostro 5470 elantech *clickpad* reports right button
clicks when clicked in the right bottom area:

https://bugzilla.redhat.com/show_bug.cgi?id=1103528

This is different from how (elantech) clickpads normally operate, normally
no matter where the user clicks on the pad the pad always reports a left
button event, since there is only 1 hardware button beneath the path.

It looks like Dell has put 2 buttons under the pad, one under each bottom
corner, causing this.

Since this however still clearly is a real clickpad hardware-wise, we still
want to report it as such to userspace, so that things like finger movement
in the bottom area can be properly ignored as it should be on clickpads.

So deal with this weirdness by simply mapping a right click to a left click
on elantech clickpads. As an added advantage this is something which we can
simply do on all elantech clickpads, so no need to add special quirks for
this weird model.

Reported-and-tested-by: Elder Marco <[email protected]>
Signed-off-by: Hans de Goede <[email protected]>
Signed-off-by: Dmitry Torokhov <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/input/mouse/elantech.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)

--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -455,8 +455,15 @@ static void elantech_report_absolute_v3(
input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
- input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
- input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
+
+ /* For clickpads map both buttons to BTN_LEFT */
+ if (etd->fw_version & 0x001000) {
+ input_report_key(dev, BTN_LEFT, packet[0] & 0x03);
+ } else {
+ input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
+ input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
+ }
+
input_report_abs(dev, ABS_PRESSURE, pres);
input_report_abs(dev, ABS_TOOL_WIDTH, width);

@@ -466,10 +473,17 @@ static void elantech_report_absolute_v3(
static void elantech_input_sync_v4(struct psmouse *psmouse)
{
struct input_dev *dev = psmouse->dev;
+ struct elantech_data *etd = psmouse->private;
unsigned char *packet = psmouse->packet;

- input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
- input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
+ /* For clickpads map both buttons to BTN_LEFT */
+ if (etd->fw_version & 0x001000) {
+ input_report_key(dev, BTN_LEFT, packet[0] & 0x03);
+ } else {
+ input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
+ input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
+ }
+
input_mt_report_pointer_emulation(dev, true);
input_sync(dev);
}

2014-07-08 19:22:57

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 065/125] ptrace: fix fork event messages across pid namespaces

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Matthew Dempsky <[email protected]>

commit 4e52365f279564cef0ddd41db5237f0471381093 upstream.

When tracing a process in another pid namespace, it's important for fork
event messages to contain the child's pid as seen from the tracer's pid
namespace, not the parent's. Otherwise, the tracer won't be able to
correlate the fork event with later SIGTRAP signals it receives from the
child.

We still risk a race condition if a ptracer from a different pid
namespace attaches after we compute the pid_t value. However, sending a
bogus fork event message in this unlikely scenario is still a vast
improvement over the status quo where we always send bogus fork event
messages to debuggers in a different pid namespace than the forking
process.

Signed-off-by: Matthew Dempsky <[email protected]>
Acked-by: Oleg Nesterov <[email protected]>
Cc: Kees Cook <[email protected]>
Cc: Julien Tinnes <[email protected]>
Cc: Roland McGrath <[email protected]>
Cc: Jan Kratochvil <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
include/linux/ptrace.h | 32 ++++++++++++++++++++++++++++++++
kernel/fork.c | 10 +++++++---
2 files changed, 39 insertions(+), 3 deletions(-)

--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -112,6 +112,7 @@

#include <linux/compiler.h> /* For unlikely. */
#include <linux/sched.h> /* For struct task_struct. */
+#include <linux/pid_namespace.h> /* For task_active_pid_ns. */


extern long arch_ptrace(struct task_struct *child, long request,
@@ -204,6 +205,37 @@ static inline void ptrace_event(int even
}

/**
+ * ptrace_event_pid - possibly stop for a ptrace event notification
+ * @event: %PTRACE_EVENT_* value to report
+ * @pid: process identifier for %PTRACE_GETEVENTMSG to return
+ *
+ * Check whether @event is enabled and, if so, report @event and @pid
+ * to the ptrace parent. @pid is reported as the pid_t seen from the
+ * the ptrace parent's pid namespace.
+ *
+ * Called without locks.
+ */
+static inline void ptrace_event_pid(int event, struct pid *pid)
+{
+ /*
+ * FIXME: There's a potential race if a ptracer in a different pid
+ * namespace than parent attaches between computing message below and
+ * when we acquire tasklist_lock in ptrace_stop(). If this happens,
+ * the ptracer will get a bogus pid from PTRACE_GETEVENTMSG.
+ */
+ unsigned long message = 0;
+ struct pid_namespace *ns;
+
+ rcu_read_lock();
+ ns = task_active_pid_ns(rcu_dereference(current->parent));
+ if (ns)
+ message = pid_nr_ns(pid, ns);
+ rcu_read_unlock();
+
+ ptrace_event(event, message);
+}
+
+/**
* ptrace_init_task - initialize ptrace state for a new child
* @child: new child task
* @ptrace: true if child should be ptrace'd by parent's tracer
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1513,10 +1513,12 @@ long do_fork(unsigned long clone_flags,
*/
if (!IS_ERR(p)) {
struct completion vfork;
+ struct pid *pid;

trace_sched_process_fork(current, p);

- nr = task_pid_vnr(p);
+ pid = get_task_pid(p, PIDTYPE_PID);
+ nr = pid_vnr(pid);

if (clone_flags & CLONE_PARENT_SETTID)
put_user(nr, parent_tidptr);
@@ -1540,14 +1542,16 @@ long do_fork(unsigned long clone_flags,

/* forking complete and child started to run, tell ptracer */
if (unlikely(trace))
- ptrace_event(trace, nr);
+ ptrace_event_pid(trace, pid);

if (clone_flags & CLONE_VFORK) {
freezer_do_not_count();
wait_for_completion(&vfork);
freezer_count();
- ptrace_event(PTRACE_EVENT_VFORK_DONE, nr);
+ ptrace_event_pid(PTRACE_EVENT_VFORK_DONE, pid);
}
+
+ put_pid(pid);
} else {
nr = PTR_ERR(p);
}

2014-07-08 19:22:55

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 107/125] perf: Fix race in removing an event

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Peter Zijlstra <[email protected]>

commit 46ce0fe97a6be7532ce6126bb26ce89fed81528c upstream.

When removing a (sibling) event we do:

raw_spin_lock_irq(&ctx->lock);
perf_group_detach(event);
raw_spin_unlock_irq(&ctx->lock);

<hole>

perf_remove_from_context(event);
raw_spin_lock_irq(&ctx->lock);
...
raw_spin_unlock_irq(&ctx->lock);

Now, assuming the event is a sibling, it will be 'unreachable' for
things like ctx_sched_out() because that iterates the
groups->siblings, and we just unhooked the sibling.

So, if during <hole> we get ctx_sched_out(), it will miss the event
and not call event_sched_out() on it, leaving it programmed on the
PMU.

The subsequent perf_remove_from_context() call will find the ctx is
inactive and only call list_del_event() to remove the event from all
other lists.

Hereafter we can proceed to free the event; while still programmed!

Close this hole by moving perf_group_detach() inside the same
ctx->lock region(s) perf_remove_from_context() has.

The condition on inherited events only in __perf_event_exit_task() is
likely complete crap because non-inherited events are part of groups
too and we're tearing down just the same. But leave that for another
patch.

Most-likely-Fixes: e03a9a55b4e ("perf: Change close() semantics for group events")
Reported-by: Vince Weaver <[email protected]>
Tested-by: Vince Weaver <[email protected]>
Much-staring-at-traces-by: Vince Weaver <[email protected]>
Much-staring-at-traces-by: Thomas Gleixner <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Linus Torvalds <[email protected]>
Signed-off-by: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
[bwh: Backported to 3.2: drop change in perf_pmu_migrate_context()]
Signed-off-by: Ben Hutchings <[email protected]>
---
kernel/events/core.c | 47 ++++++++++++++++++++++++++---------------------
1 file changed, 26 insertions(+), 21 deletions(-)

--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -1180,6 +1180,11 @@ group_sched_out(struct perf_event *group
cpuctx->exclusive = 0;
}

+struct remove_event {
+ struct perf_event *event;
+ bool detach_group;
+};
+
/*
* Cross CPU call to remove a performance event
*
@@ -1188,12 +1193,15 @@ group_sched_out(struct perf_event *group
*/
static int __perf_remove_from_context(void *info)
{
- struct perf_event *event = info;
+ struct remove_event *re = info;
+ struct perf_event *event = re->event;
struct perf_event_context *ctx = event->ctx;
struct perf_cpu_context *cpuctx = __get_cpu_context(ctx);

raw_spin_lock(&ctx->lock);
event_sched_out(event, cpuctx, ctx);
+ if (re->detach_group)
+ perf_group_detach(event);
list_del_event(event, ctx);
if (!ctx->nr_events && cpuctx->task_ctx == ctx) {
ctx->is_active = 0;
@@ -1218,10 +1226,14 @@ static int __perf_remove_from_context(vo
* When called from perf_event_exit_task, it's OK because the
* context has been detached from its task.
*/
-static void perf_remove_from_context(struct perf_event *event)
+static void perf_remove_from_context(struct perf_event *event, bool detach_group)
{
struct perf_event_context *ctx = event->ctx;
struct task_struct *task = ctx->task;
+ struct remove_event re = {
+ .event = event,
+ .detach_group = detach_group,
+ };

lockdep_assert_held(&ctx->mutex);

@@ -1230,12 +1242,12 @@ static void perf_remove_from_context(str
* Per cpu events are removed via an smp call and
* the removal is always successful.
*/
- cpu_function_call(event->cpu, __perf_remove_from_context, event);
+ cpu_function_call(event->cpu, __perf_remove_from_context, &re);
return;
}

retry:
- if (!task_function_call(task, __perf_remove_from_context, event))
+ if (!task_function_call(task, __perf_remove_from_context, &re))
return;

raw_spin_lock_irq(&ctx->lock);
@@ -1252,6 +1264,8 @@ retry:
* Since the task isn't running, its safe to remove the event, us
* holding the ctx->lock ensures the task won't get scheduled in.
*/
+ if (detach_group)
+ perf_group_detach(event);
list_del_event(event, ctx);
raw_spin_unlock_irq(&ctx->lock);
}
@@ -3046,10 +3060,7 @@ int perf_event_release_kernel(struct per
* to trigger the AB-BA case.
*/
mutex_lock_nested(&ctx->mutex, SINGLE_DEPTH_NESTING);
- raw_spin_lock_irq(&ctx->lock);
- perf_group_detach(event);
- raw_spin_unlock_irq(&ctx->lock);
- perf_remove_from_context(event);
+ perf_remove_from_context(event, true);
mutex_unlock(&ctx->mutex);

free_event(event);
@@ -6459,7 +6470,7 @@ SYSCALL_DEFINE5(perf_event_open,
struct perf_event_context *gctx = group_leader->ctx;

mutex_lock(&gctx->mutex);
- perf_remove_from_context(group_leader);
+ perf_remove_from_context(group_leader, false);

/*
* Removing from the context ends up with disabled
@@ -6469,7 +6480,7 @@ SYSCALL_DEFINE5(perf_event_open,
perf_event__state_init(group_leader);
list_for_each_entry(sibling, &group_leader->sibling_list,
group_entry) {
- perf_remove_from_context(sibling);
+ perf_remove_from_context(sibling, false);
perf_event__state_init(sibling);
put_ctx(gctx);
}
@@ -6622,13 +6633,7 @@ __perf_event_exit_task(struct perf_event
struct perf_event_context *child_ctx,
struct task_struct *child)
{
- if (child_event->parent) {
- raw_spin_lock_irq(&child_ctx->lock);
- perf_group_detach(child_event);
- raw_spin_unlock_irq(&child_ctx->lock);
- }
-
- perf_remove_from_context(child_event);
+ perf_remove_from_context(child_event, !!child_event->parent);

/*
* It can happen that the parent exits first, and has events
@@ -7113,14 +7118,14 @@ static void perf_pmu_rotate_stop(struct

static void __perf_event_exit_context(void *__info)
{
+ struct remove_event re = { .detach_group = false };
struct perf_event_context *ctx = __info;
- struct perf_event *event;

perf_pmu_rotate_stop(ctx->pmu);

rcu_read_lock();
- list_for_each_entry_rcu(event, &ctx->event_list, event_entry)
- __perf_remove_from_context(event);
+ list_for_each_entry_rcu(re.event, &ctx->event_list, event_entry)
+ __perf_remove_from_context(&re);
rcu_read_unlock();
}

2014-07-08 19:24:27

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 004/125] UBIFS: fix an mmap and fsync race condition

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: hujianyang <[email protected]>

commit 691a7c6f28ac90cccd0dbcf81348ea90b211bdd0 upstream.

There is a race condition in UBIFS:

Thread A (mmap) Thread B (fsync)

->__do_fault ->write_cache_pages
-> ubifs_vm_page_mkwrite
-> budget_space
-> lock_page
-> release/convert_page_budget
-> SetPagePrivate
-> TestSetPageDirty
-> unlock_page
-> lock_page
-> TestClearPageDirty
-> ubifs_writepage
-> do_writepage
-> release_budget
-> ClearPagePrivate
-> unlock_page
-> !(ret & VM_FAULT_LOCKED)
-> lock_page
-> set_page_dirty
-> ubifs_set_page_dirty
-> TestSetPageDirty (set page dirty without budgeting)
-> unlock_page

This leads to situation where we have a diry page but no budget allocated for
this page, so further write-back may fail with -ENOSPC.

In this fix we return from page_mkwrite without performing unlock_page. We
return VM_FAULT_LOCKED instead. After doing this, the race above will not
happen.

Signed-off-by: hujianyang <[email protected]>
Tested-by: Laurence Withers <[email protected]>
Signed-off-by: Artem Bityutskiy <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/ubifs/file.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1522,8 +1522,7 @@ static int ubifs_vm_page_mkwrite(struct
ubifs_release_dirty_inode_budget(c, ui);
}

- unlock_page(page);
- return 0;
+ return VM_FAULT_LOCKED;

out_unlock:
unlock_page(page);

2014-07-08 19:24:33

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 119/125] iommu/vt-d: Fix missing IOTLB flush in intel_iommu_unmap()

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: David Woodhouse <[email protected]>

Part of commit ea8ea460c9ace60bbb5ac6e5521d637d5c15293d upstream.

This missing IOTLB flush was added as a minor, inconsequential bug-fix
in commit ea8ea460c ("iommu/vt-d: Clean up and fix page table clear/free
behaviour") in 3.15. It wasn't originally intended for -stable but a
couple of users have reported issues which turn out to be fixed by
adding the missing flush.

Signed-off-by: David Woodhouse <[email protected]>
[bwh: Backported to 3.2:
- Adjust context
- Use &dmar_domain->iommu_bmp, as it is a single word not an array]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/iommu/intel-iommu.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)

--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -4070,7 +4070,7 @@ static int intel_iommu_unmap(struct iomm
{
struct dmar_domain *dmar_domain = domain->priv;
size_t size = PAGE_SIZE << gfp_order;
- int order;
+ int order, iommu_id;

order = dma_pte_clear_range(dmar_domain, iova >> VTD_PAGE_SHIFT,
(iova + size - 1) >> VTD_PAGE_SHIFT);
@@ -4078,6 +4078,22 @@ static int intel_iommu_unmap(struct iomm
if (dmar_domain->max_addr == iova + size)
dmar_domain->max_addr = iova;

+ for_each_set_bit(iommu_id, &dmar_domain->iommu_bmp, g_num_of_iommus) {
+ struct intel_iommu *iommu = g_iommus[iommu_id];
+ int num, ndomains;
+
+ /*
+ * find bit position of dmar_domain
+ */
+ ndomains = cap_ndoms(iommu->cap);
+ for_each_set_bit(num, iommu->domain_ids, ndomains) {
+ if (iommu->domains[num] == dmar_domain)
+ iommu_flush_iotlb_psi(iommu, num,
+ iova >> VTD_PAGE_SHIFT,
+ 1 << order, 0);
+ }
+ }
+
return order;
}

2014-07-08 19:24:30

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 084/125] ALSA: control: Fix replacing user controls

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Lars-Peter Clausen <[email protected]>

commit 82262a46627bebb0febcc26664746c25cef08563 upstream.

There are two issues with the current implementation for replacing user
controls. The first is that the code does not check if the control is actually a
user control and neither does it check if the control is owned by the process
that tries to remove it. That allows userspace applications to remove arbitrary
controls, which can cause a user after free if a for example a driver does not
expect a control to be removed from under its feed.

The second issue is that on one hand when a control is replaced the
user_ctl_count limit is not checked and on the other hand the user_ctl_count is
increased (even though the number of user controls does not change). This allows
userspace, once the user_ctl_count limit as been reached, to repeatedly replace
a control until user_ctl_count overflows. Once that happens new controls can be
added effectively bypassing the user_ctl_count limit.

Both issues can be fixed by instead of open-coding the removal of the control
that is to be replaced to use snd_ctl_remove_user_ctl(). This function does
proper permission checks as well as decrements user_ctl_count after the control
has been removed.

Note that by using snd_ctl_remove_user_ctl() the check which returns -EBUSY at
beginning of the function if the control already exists is removed. This is not
a problem though since the check is quite useless, because the lock that is
protecting the control list is released between the check and before adding the
new control to the list, which means that it is possible that a different
control with the same settings is added to the list after the check. Luckily
there is another check that is done while holding the lock in snd_ctl_add(), so
we'll rely on that to make sure that the same control is not added twice.

Signed-off-by: Lars-Peter Clausen <[email protected]>
Acked-by: Jaroslav Kysela <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
sound/core/control.c | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)

--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1151,8 +1151,6 @@ static int snd_ctl_elem_add(struct snd_c
struct user_element *ue;
int idx, err;

- if (!replace && card->user_ctl_count >= MAX_USER_CONTROLS)
- return -ENOMEM;
if (info->count < 1)
return -EINVAL;
access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
@@ -1161,21 +1159,16 @@ static int snd_ctl_elem_add(struct snd_c
SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE));
info->id.numid = 0;
memset(&kctl, 0, sizeof(kctl));
- down_write(&card->controls_rwsem);
- _kctl = snd_ctl_find_id(card, &info->id);
- err = 0;
- if (_kctl) {
- if (replace)
- err = snd_ctl_remove(card, _kctl);
- else
- err = -EBUSY;
- } else {
- if (replace)
- err = -ENOENT;
+
+ if (replace) {
+ err = snd_ctl_remove_user_ctl(file, &info->id);
+ if (err)
+ return err;
}
- up_write(&card->controls_rwsem);
- if (err < 0)
- return err;
+
+ if (card->user_ctl_count >= MAX_USER_CONTROLS)
+ return -ENOMEM;
+
memcpy(&kctl.id, &info->id, sizeof(info->id));
kctl.count = info->owner ? info->owner : 1;
access |= SNDRV_CTL_ELEM_ACCESS_USER;

2014-07-08 19:24:29

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 125/125] skbuff: skb_segment: orphan frags before copying

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: "Michael S. Tsirkin" <[email protected]>

commit 1fd819ecb90cc9b822cd84d3056ddba315d3340f upstream.

skb_segment copies frags around, so we need
to copy them carefully to avoid accessing
user memory after reporting completion to userspace
through a callback.

skb_segment doesn't normally happen on datapath:
TSO needs to be disabled - so disabling zero copy
in this case does not look like a big deal.

Signed-off-by: Michael S. Tsirkin <[email protected]>
Acked-by: Herbert Xu <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
[bwh: Backported to 3.2. As skb_segment() only supports page-frags *or* a
frag list, there is no need for the additional frag_skb pointer or the
preparatory renaming.]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2698,6 +2698,9 @@ struct sk_buff *skb_segment(struct sk_bu
skb_put(nskb, hsize), hsize);

while (pos < offset + len && i < nfrags) {
+ if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC)))
+ goto err;
+
*frag = skb_shinfo(skb)->frags[i];
__skb_frag_ref(frag);
size = skb_frag_size(frag);

2014-07-08 19:24:25

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 073/125] auditsc: audit_krule mask accesses need bounds checking

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Andy Lutomirski <[email protected]>

commit a3c54931199565930d6d84f4c3456f6440aefd41 upstream.

Fixes an easy DoS and possible information disclosure.

This does nothing about the broken state of x32 auditing.

eparis: If the admin has enabled auditd and has specifically loaded
audit rules. This bug has been around since before git. Wow...

Signed-off-by: Andy Lutomirski <[email protected]>
Signed-off-by: Eric Paris <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
[bwh: Backported to 3.2: audit_filter_inode_name() is not a separate
function but part of audit_filter_inodes()]
Signed-off-by: Ben Hutchings <[email protected]>
---
kernel/auditsc.c | 27 ++++++++++++++++++---------
1 file changed, 18 insertions(+), 9 deletions(-)

--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -688,6 +688,22 @@ static enum audit_state audit_filter_tas
return AUDIT_BUILD_CONTEXT;
}

+static int audit_in_mask(const struct audit_krule *rule, unsigned long val)
+{
+ int word, bit;
+
+ if (val > 0xffffffff)
+ return false;
+
+ word = AUDIT_WORD(val);
+ if (word >= AUDIT_BITMASK_SIZE)
+ return false;
+
+ bit = AUDIT_BIT(val);
+
+ return rule->mask[word] & bit;
+}
+
/* At syscall entry and exit time, this filter is called if the
* audit_state is not low enough that auditing cannot take place, but is
* also not high enough that we already know we have to write an audit
@@ -705,11 +721,8 @@ static enum audit_state audit_filter_sys

rcu_read_lock();
if (!list_empty(list)) {
- int word = AUDIT_WORD(ctx->major);
- int bit = AUDIT_BIT(ctx->major);
-
list_for_each_entry_rcu(e, list, list) {
- if ((e->rule.mask[word] & bit) == bit &&
+ if (audit_in_mask(&e->rule, ctx->major) &&
audit_filter_rules(tsk, &e->rule, ctx, NULL,
&state, false)) {
rcu_read_unlock();
@@ -738,8 +751,6 @@ void audit_filter_inodes(struct task_str

rcu_read_lock();
for (i = 0; i < ctx->name_count; i++) {
- int word = AUDIT_WORD(ctx->major);
- int bit = AUDIT_BIT(ctx->major);
struct audit_names *n = &ctx->names[i];
int h = audit_hash_ino((u32)n->ino);
struct list_head *list = &audit_inode_hash[h];
@@ -748,7 +759,7 @@ void audit_filter_inodes(struct task_str
continue;

list_for_each_entry_rcu(e, list, list) {
- if ((e->rule.mask[word] & bit) == bit &&
+ if (audit_in_mask(&e->rule, ctx->major) &&
audit_filter_rules(tsk, &e->rule, ctx, n,
&state, false)) {
rcu_read_unlock();

2014-07-08 19:24:24

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 080/125] rtmutex: Detect changes in the pi lock chain

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Thomas Gleixner <[email protected]>

commit 82084984383babe728e6e3c9a8e5c46278091315 upstream.

When we walk the lock chain, we drop all locks after each step. So the
lock chain can change under us before we reacquire the locks. That's
harmless in principle as we just follow the wrong lock path. But it
can lead to a false positive in the dead lock detection logic:

T0 holds L0
T0 blocks on L1 held by T1
T1 blocks on L2 held by T2
T2 blocks on L3 held by T3
T4 blocks on L4 held by T4

Now we walk the chain

lock T1 -> lock L2 -> adjust L2 -> unlock T1 ->
lock T2 -> adjust T2 -> drop locks

T2 times out and blocks on L0

Now we continue:

lock T2 -> lock L0 -> deadlock detected, but it's not a deadlock at all.

Brad tried to work around that in the deadlock detection logic itself,
but the more I looked at it the less I liked it, because it's crystal
ball magic after the fact.

We actually can detect a chain change very simple:

lock T1 -> lock L2 -> adjust L2 -> unlock T1 -> lock T2 -> adjust T2 ->

next_lock = T2->pi_blocked_on->lock;

drop locks

T2 times out and blocks on L0

Now we continue:

lock T2 ->

if (next_lock != T2->pi_blocked_on->lock)
return;

So if we detect that T2 is now blocked on a different lock we stop the
chain walk. That's also correct in the following scenario:

lock T1 -> lock L2 -> adjust L2 -> unlock T1 -> lock T2 -> adjust T2 ->

next_lock = T2->pi_blocked_on->lock;

drop locks

T3 times out and drops L3
T2 acquires L3 and blocks on L4 now

Now we continue:

lock T2 ->

if (next_lock != T2->pi_blocked_on->lock)
return;

We don't have to follow up the chain at that point, because T2
propagated our priority up to T4 already.

[ Folded a cleanup patch from peterz ]

Signed-off-by: Thomas Gleixner <[email protected]>
Reported-by: Brad Mouring <[email protected]>
Cc: Steven Rostedt <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
[bwh: Backported to 3.2: adjust filename, context]
Signed-off-by: Ben Hutchings <[email protected]>
---
kernel/rtmutex.c | 95 ++++++++++++++++++++++++++++++++++++------------
1 file changed, 71 insertions(+), 24 deletions(-)

--- a/kernel/rtmutex.c
+++ b/kernel/rtmutex.c
@@ -141,14 +141,36 @@ static void rt_mutex_adjust_prio(struct
*/
int max_lock_depth = 1024;

+static inline struct rt_mutex *task_blocked_on_lock(struct task_struct *p)
+{
+ return p->pi_blocked_on ? p->pi_blocked_on->lock : NULL;
+}
+
/*
* Adjust the priority chain. Also used for deadlock detection.
* Decreases task's usage by one - may thus free the task.
+ *
+ * @task: the task owning the mutex (owner) for which a chain walk is
+ * probably needed
+ * @deadlock_detect: do we have to carry out deadlock detection?
+ * @orig_lock: the mutex (can be NULL if we are walking the chain to recheck
+ * things for a task that has just got its priority adjusted, and
+ * is waiting on a mutex)
+ * @next_lock: the mutex on which the owner of @orig_lock was blocked before
+ * we dropped its pi_lock. Is never dereferenced, only used for
+ * comparison to detect lock chain changes.
+ * @orig_waiter: rt_mutex_waiter struct for the task that has just donated
+ * its priority to the mutex owner (can be NULL in the case
+ * depicted above or if the top waiter is gone away and we are
+ * actually deboosting the owner)
+ * @top_task: the current top waiter
+ *
* Returns 0 or -EDEADLK.
*/
static int rt_mutex_adjust_prio_chain(struct task_struct *task,
int deadlock_detect,
struct rt_mutex *orig_lock,
+ struct rt_mutex *next_lock,
struct rt_mutex_waiter *orig_waiter,
struct task_struct *top_task)
{
@@ -207,6 +229,18 @@ static int rt_mutex_adjust_prio_chain(st
goto out_unlock_pi;

/*
+ * We dropped all locks after taking a refcount on @task, so
+ * the task might have moved on in the lock chain or even left
+ * the chain completely and blocks now on an unrelated lock or
+ * on @orig_lock.
+ *
+ * We stored the lock on which @task was blocked in @next_lock,
+ * so we can detect the chain change.
+ */
+ if (next_lock != waiter->lock)
+ goto out_unlock_pi;
+
+ /*
* Drop out, when the task has no waiters. Note,
* top_waiter can be NULL, when we are in the deboosting
* mode!
@@ -292,11 +326,26 @@ static int rt_mutex_adjust_prio_chain(st
__rt_mutex_adjust_prio(task);
}

+ /*
+ * Check whether the task which owns the current lock is pi
+ * blocked itself. If yes we store a pointer to the lock for
+ * the lock chain change detection above. After we dropped
+ * task->pi_lock next_lock cannot be dereferenced anymore.
+ */
+ next_lock = task_blocked_on_lock(task);
+
raw_spin_unlock_irqrestore(&task->pi_lock, flags);

top_waiter = rt_mutex_top_waiter(lock);
raw_spin_unlock(&lock->wait_lock);

+ /*
+ * We reached the end of the lock chain. Stop right here. No
+ * point to go back just to figure that out.
+ */
+ if (!next_lock)
+ goto out_put_task;
+
if (!detect_deadlock && waiter != top_waiter)
goto out_put_task;

@@ -407,8 +456,9 @@ static int task_blocks_on_rt_mutex(struc
{
struct task_struct *owner = rt_mutex_owner(lock);
struct rt_mutex_waiter *top_waiter = waiter;
- unsigned long flags;
+ struct rt_mutex *next_lock;
int chain_walk = 0, res;
+ unsigned long flags;

/*
* Early deadlock detection. We really don't want the task to
@@ -441,20 +491,28 @@ static int task_blocks_on_rt_mutex(struc
if (!owner)
return 0;

+ raw_spin_lock_irqsave(&owner->pi_lock, flags);
if (waiter == rt_mutex_top_waiter(lock)) {
- raw_spin_lock_irqsave(&owner->pi_lock, flags);
plist_del(&top_waiter->pi_list_entry, &owner->pi_waiters);
plist_add(&waiter->pi_list_entry, &owner->pi_waiters);

__rt_mutex_adjust_prio(owner);
if (owner->pi_blocked_on)
chain_walk = 1;
- raw_spin_unlock_irqrestore(&owner->pi_lock, flags);
- }
- else if (debug_rt_mutex_detect_deadlock(waiter, detect_deadlock))
+ } else if (debug_rt_mutex_detect_deadlock(waiter, detect_deadlock)) {
chain_walk = 1;
+ }

- if (!chain_walk)
+ /* Store the lock on which owner is blocked or NULL */
+ next_lock = task_blocked_on_lock(owner);
+
+ raw_spin_unlock_irqrestore(&owner->pi_lock, flags);
+ /*
+ * Even if full deadlock detection is on, if the owner is not
+ * blocked itself, we can avoid finding this out in the chain
+ * walk.
+ */
+ if (!chain_walk || !next_lock)
return 0;

/*
@@ -466,8 +524,8 @@ static int task_blocks_on_rt_mutex(struc

raw_spin_unlock(&lock->wait_lock);

- res = rt_mutex_adjust_prio_chain(owner, detect_deadlock, lock, waiter,
- task);
+ res = rt_mutex_adjust_prio_chain(owner, detect_deadlock, lock,
+ next_lock, waiter, task);

raw_spin_lock(&lock->wait_lock);

@@ -516,8 +574,8 @@ static void remove_waiter(struct rt_mute
{
int first = (waiter == rt_mutex_top_waiter(lock));
struct task_struct *owner = rt_mutex_owner(lock);
+ struct rt_mutex *next_lock = NULL;
unsigned long flags;
- int chain_walk = 0;

raw_spin_lock_irqsave(&current->pi_lock, flags);
plist_del(&waiter->list_entry, &lock->wait_list);
@@ -541,15 +599,15 @@ static void remove_waiter(struct rt_mute
}
__rt_mutex_adjust_prio(owner);

- if (owner->pi_blocked_on)
- chain_walk = 1;
+ /* Store the lock on which owner is blocked or NULL */
+ next_lock = task_blocked_on_lock(owner);

raw_spin_unlock_irqrestore(&owner->pi_lock, flags);
}

WARN_ON(!plist_node_empty(&waiter->pi_list_entry));

- if (!chain_walk)
+ if (!next_lock)
return;

/* gets dropped in rt_mutex_adjust_prio_chain()! */
@@ -557,7 +615,7 @@ static void remove_waiter(struct rt_mute

raw_spin_unlock(&lock->wait_lock);

- rt_mutex_adjust_prio_chain(owner, 0, lock, NULL, current);
+ rt_mutex_adjust_prio_chain(owner, 0, lock, next_lock, NULL, current);

raw_spin_lock(&lock->wait_lock);
}
@@ -570,6 +628,7 @@ static void remove_waiter(struct rt_mute
void rt_mutex_adjust_pi(struct task_struct *task)
{
struct rt_mutex_waiter *waiter;
+ struct rt_mutex *next_lock;
unsigned long flags;

raw_spin_lock_irqsave(&task->pi_lock, flags);
@@ -579,12 +638,13 @@ void rt_mutex_adjust_pi(struct task_stru
raw_spin_unlock_irqrestore(&task->pi_lock, flags);
return;
}
-
+ next_lock = waiter->lock;
raw_spin_unlock_irqrestore(&task->pi_lock, flags);

/* gets dropped in rt_mutex_adjust_prio_chain()! */
get_task_struct(task);
- rt_mutex_adjust_prio_chain(task, 0, NULL, NULL, task);
+
+ rt_mutex_adjust_prio_chain(task, 0, NULL, next_lock, NULL, task);
}

/**

2014-07-08 19:24:22

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 077/125] ALSA: hda - Add quirk for external mic on Lifebook U904

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: David Henningsson <[email protected]>

commit 2041d56464a067461d7cc21734a0f024587ed2ff upstream.

According to the bug reporter (Данило Шеган), the external mic
starts to work and has proper jack detection if only pin 0x19
is marked properly as an external headset mic.

AlsaInfo at https://bugs.launchpad.net/ubuntu/+source/pulseaudio/+bug/1328587/+attachment/4128991/+files/AlsaInfo.txt

BugLink: https://bugs.launchpad.net/bugs/1328587
Signed-off-by: David Henningsson <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
[bwh: Backported to 3.2:
- s/struct hda_pintbl/struct alc_pincfg/
- s/HDA_FIXUP_PINS/ALC_FIXUP_PINS/
Signed-off-by: Ben Hutchings <[email protected]>
---
sound/pci/hda/patch_realtek.c | 9 +++++++++
1 file changed, 9 insertions(+)

--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4920,6 +4920,7 @@ enum {
ALC269_FIXUP_STEREO_DMIC,
ALC269_FIXUP_QUANTA_MUTE,
ALC269_FIXUP_LIFEBOOK,
+ ALC269_FIXUP_LIFEBOOK_EXTMIC,
ALC269_FIXUP_AMIC,
ALC269_FIXUP_DMIC,
ALC269VB_FIXUP_AMIC,
@@ -5008,6 +5009,13 @@ static const struct alc_fixup alc269_fix
.chained = true,
.chain_id = ALC269_FIXUP_QUANTA_MUTE
},
+ [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
+ .type = ALC_FIXUP_PINS,
+ .v.pins = (const struct alc_pincfg[]) {
+ { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
+ { }
+ },
+ },
[ALC269_FIXUP_AMIC] = {
.type = ALC_FIXUP_PINS,
.v.pins = (const struct alc_pincfg[]) {
@@ -5079,6 +5087,7 @@ static const struct snd_pci_quirk alc269
SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
+ SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),

2014-07-08 19:24:21

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 090/125] rt2x00: disable TKIP on USB

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Stanislaw Gruszka <[email protected]>

commit 8edcb0ba0d56f5914eef11eda6db8bfe74eb9ca8 upstream.

On USB we can not get atomically TKIP key. We have to disable support
for TKIP acceleration on USB hardware to avoid bug as showed bellow.

[ 860.827243] BUG: scheduling while atomic: hostapd/3397/0x00000002
<snip>
[ 860.827280] Call Trace:
[ 860.827282] [<ffffffff81682ea6>] dump_stack+0x4d/0x66
[ 860.827284] [<ffffffff8167eb9b>] __schedule_bug+0x47/0x55
[ 860.827285] [<ffffffff81685bb3>] __schedule+0x733/0x7b0
[ 860.827287] [<ffffffff81685c59>] schedule+0x29/0x70
[ 860.827289] [<ffffffff81684f8a>] schedule_timeout+0x15a/0x2b0
[ 860.827291] [<ffffffff8105ac50>] ? ftrace_raw_event_tick_stop+0xc0/0xc0
[ 860.827294] [<ffffffff810c13c2>] ? __module_text_address+0x12/0x70
[ 860.827296] [<ffffffff81686823>] wait_for_completion_timeout+0xb3/0x140
[ 860.827298] [<ffffffff81080fc0>] ? wake_up_state+0x20/0x20
[ 860.827301] [<ffffffff814d5b3d>] usb_start_wait_urb+0x7d/0x150
[ 860.827303] [<ffffffff814d5cd5>] usb_control_msg+0xc5/0x110
[ 860.827305] [<ffffffffa02fb0c6>] rt2x00usb_vendor_request+0xc6/0x160 [rt2x00usb]
[ 860.827307] [<ffffffffa02fb215>] rt2x00usb_vendor_req_buff_lock+0x75/0x150 [rt2x00usb]
[ 860.827309] [<ffffffffa02fb393>] rt2x00usb_vendor_request_buff+0xa3/0xe0 [rt2x00usb]
[ 860.827311] [<ffffffffa023d1a3>] rt2x00usb_register_multiread+0x33/0x40 [rt2800usb]
[ 860.827314] [<ffffffffa05805f9>] rt2800_get_tkip_seq+0x39/0x50 [rt2800lib]
[ 860.827321] [<ffffffffa0480f88>] ieee80211_get_key+0x218/0x2a0 [mac80211]
[ 860.827322] [<ffffffff815cc68c>] ? __nlmsg_put+0x6c/0x80
[ 860.827329] [<ffffffffa051b02e>] nl80211_get_key+0x22e/0x360 [cfg80211]

Reported-and-tested-by: Peter Wu <[email protected]>
Reported-and-tested-by: Pontus Fuchs <[email protected]>
Signed-off-by: Stanislaw Gruszka <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/wireless/rt2x00/rt2x00mac.c | 2 ++
1 file changed, 2 insertions(+)

--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -517,6 +517,8 @@ int rt2x00mac_set_key(struct ieee80211_h
crypto.cipher = rt2x00crypto_key_to_cipher(key);
if (crypto.cipher == CIPHER_NONE)
return -EOPNOTSUPP;
+ if (crypto.cipher == CIPHER_TKIP && rt2x00_is_usb(rt2x00dev))
+ return -EOPNOTSUPP;

crypto.cmd = cmd;

2014-07-08 19:24:18

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 083/125] ALSA: control: Protect user controls against concurrent access

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Lars-Peter Clausen <[email protected]>

commit 07f4d9d74a04aa7c72c5dae0ef97565f28f17b92 upstream.

The user-control put and get handlers as well as the tlv do not protect against
concurrent access from multiple threads. Since the state of the control is not
updated atomically it is possible that either two write operations or a write
and a read operation race against each other. Both can lead to arbitrary memory
disclosure. This patch introduces a new lock that protects user-controls from
concurrent access. Since applications typically access controls sequentially
than in parallel a single lock per card should be fine.

Signed-off-by: Lars-Peter Clausen <[email protected]>
Acked-by: Jaroslav Kysela <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
include/sound/core.h | 2 ++
sound/core/control.c | 31 +++++++++++++++++++++++++------
sound/core/init.c | 1 +
3 files changed, 28 insertions(+), 6 deletions(-)

--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -120,6 +120,8 @@ struct snd_card {
int user_ctl_count; /* count of all user controls */
struct list_head controls; /* all controls for this card */
struct list_head ctl_files; /* active control files */
+ struct mutex user_ctl_lock; /* protects user controls against
+ concurrent access */

struct snd_info_entry *proc_root; /* root for soundcard specific files */
struct snd_info_entry *proc_id; /* the card id */
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -988,6 +988,7 @@ static int snd_ctl_elem_unlock(struct sn

struct user_element {
struct snd_ctl_elem_info info;
+ struct snd_card *card;
void *elem_data; /* element data */
unsigned long elem_data_size; /* size of element data in bytes */
void *tlv_data; /* TLV data */
@@ -1031,7 +1032,9 @@ static int snd_ctl_elem_user_get(struct
{
struct user_element *ue = kcontrol->private_data;

+ mutex_lock(&ue->card->user_ctl_lock);
memcpy(&ucontrol->value, ue->elem_data, ue->elem_data_size);
+ mutex_unlock(&ue->card->user_ctl_lock);
return 0;
}

@@ -1040,10 +1043,12 @@ static int snd_ctl_elem_user_put(struct
{
int change;
struct user_element *ue = kcontrol->private_data;
-
+
+ mutex_lock(&ue->card->user_ctl_lock);
change = memcmp(&ucontrol->value, ue->elem_data, ue->elem_data_size) != 0;
if (change)
memcpy(ue->elem_data, &ucontrol->value, ue->elem_data_size);
+ mutex_unlock(&ue->card->user_ctl_lock);
return change;
}

@@ -1063,19 +1068,32 @@ static int snd_ctl_elem_user_tlv(struct
new_data = memdup_user(tlv, size);
if (IS_ERR(new_data))
return PTR_ERR(new_data);
+ mutex_lock(&ue->card->user_ctl_lock);
change = ue->tlv_data_size != size;
if (!change)
change = memcmp(ue->tlv_data, new_data, size);
kfree(ue->tlv_data);
ue->tlv_data = new_data;
ue->tlv_data_size = size;
+ mutex_unlock(&ue->card->user_ctl_lock);
} else {
- if (! ue->tlv_data_size || ! ue->tlv_data)
- return -ENXIO;
- if (size < ue->tlv_data_size)
- return -ENOSPC;
+ int ret = 0;
+
+ mutex_lock(&ue->card->user_ctl_lock);
+ if (!ue->tlv_data_size || !ue->tlv_data) {
+ ret = -ENXIO;
+ goto err_unlock;
+ }
+ if (size < ue->tlv_data_size) {
+ ret = -ENOSPC;
+ goto err_unlock;
+ }
if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size))
- return -EFAULT;
+ ret = -EFAULT;
+err_unlock:
+ mutex_unlock(&ue->card->user_ctl_lock);
+ if (ret)
+ return ret;
}
return change;
}
@@ -1207,6 +1225,7 @@ static int snd_ctl_elem_add(struct snd_c
ue = kzalloc(sizeof(struct user_element) + private_size, GFP_KERNEL);
if (ue == NULL)
return -ENOMEM;
+ ue->card = card;
ue->info = *info;
ue->info.access = 0;
ue->elem_data = (char *)ue + sizeof(*ue);
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -207,6 +207,7 @@ int snd_card_create(int idx, const char
INIT_LIST_HEAD(&card->devices);
init_rwsem(&card->controls_rwsem);
rwlock_init(&card->ctl_files_rwlock);
+ mutex_init(&card->user_ctl_lock);
INIT_LIST_HEAD(&card->controls);
INIT_LIST_HEAD(&card->ctl_files);
spin_lock_init(&card->files_lock);

2014-07-08 19:24:16

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 082/125] USB: EHCI: avoid BIOS handover on the HASEE E200

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Alan Stern <[email protected]>

commit b0a50e92bda3c4aeb8017d4e6c6e92146ebd5c9b upstream.

Leandro Liptak reports that his HASEE E200 computer hangs when we ask
the BIOS to hand over control of the EHCI host controller. This
definitely sounds like a bug in the BIOS, but at the moment there is
no way to fix it.

This patch works around the problem by avoiding the handoff whenever
the motherboard and BIOS version match those of Leandro's computer.

Signed-off-by: Alan Stern <[email protected]>
Reported-by: Leandro Liptak <[email protected]>
Tested-by: Leandro Liptak <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/host/pci-quirks.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)

--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -555,6 +555,14 @@ static const struct dmi_system_id __devi
DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"),
},
},
+ {
+ /* HASEE E200 */
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "HASEE"),
+ DMI_MATCH(DMI_BOARD_NAME, "E210"),
+ DMI_MATCH(DMI_BIOS_VERSION, "6.00"),
+ },
+ },
{ }
};

@@ -564,9 +572,14 @@ static void __devinit ehci_bios_handoff(
{
int try_handoff = 1, tried_handoff = 0;

- /* The Pegatron Lucid tablet sporadically waits for 98 seconds trying
- * the handoff on its unused controller. Skip it. */
- if (pdev->vendor == 0x8086 && pdev->device == 0x283a) {
+ /*
+ * The Pegatron Lucid tablet sporadically waits for 98 seconds trying
+ * the handoff on its unused controller. Skip it.
+ *
+ * The HASEE E200 hangs when the semaphore is set (bugzilla #77021).
+ */
+ if (pdev->vendor == 0x8086 && (pdev->device == 0x283a ||
+ pdev->device == 0x27cc)) {
if (dmi_check_system(ehci_dmi_nohandoff_table))
try_handoff = 0;
}

2014-07-08 19:27:44

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 078/125] mm: rmap: fix use-after-free in __put_anon_vma

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Andrey Ryabinin <[email protected]>

commit 624483f3ea82598ab0f62f1bdb9177f531ab1892 upstream.

While working address sanitizer for kernel I've discovered
use-after-free bug in __put_anon_vma.

For the last anon_vma, anon_vma->root freed before child anon_vma.
Later in anon_vma_free(anon_vma) we are referencing to already freed
anon_vma->root to check rwsem.

This fixes it by freeing the child anon_vma before freeing
anon_vma->root.

Signed-off-by: Andrey Ryabinin <[email protected]>
Acked-by: Peter Zijlstra <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
mm/rmap.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1671,10 +1671,9 @@ void __put_anon_vma(struct anon_vma *ano
{
struct anon_vma *root = anon_vma->root;

+ anon_vma_free(anon_vma);
if (root != anon_vma && atomic_dec_and_test(&root->refcount))
anon_vma_free(root);
-
- anon_vma_free(anon_vma);
}

#ifdef CONFIG_MIGRATION

2014-07-08 19:27:43

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 104/125] [SCSI] Stop accepting SCSI requests before removing a device

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Bart Van Assche <[email protected]>

commit b485462aca7df4e32bcf7efb6f84a69e8b640243 upstream.

Avoid that the code for requeueing SCSI requests triggers a
crash by making sure that that code isn't scheduled anymore
after a device has been removed.

Also, source code inspection of __scsi_remove_device() revealed
a race condition in this function: no new SCSI requests must be
accepted for a SCSI device after device removal started.

Signed-off-by: Bart Van Assche <[email protected]>
Reviewed-by: Mike Christie <[email protected]>
Acked-by: Tejun Heo <[email protected]>
Signed-off-by: James Bottomley <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/scsi/scsi_lib.c | 7 ++++---
drivers/scsi/scsi_sysfs.c | 11 +++++++++--
2 files changed, 13 insertions(+), 5 deletions(-)

--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -155,13 +155,14 @@ static int __scsi_queue_insert(struct sc

/*
* Requeue this command. It will go before all other commands
- * that are already in the queue.
+ * that are already in the queue. Schedule requeue work under
+ * lock such that the kblockd_schedule_work() call happens
+ * before blk_cleanup_queue() finishes.
*/
spin_lock_irqsave(q->queue_lock, flags);
blk_requeue_request(q, cmd->request);
- spin_unlock_irqrestore(q->queue_lock, flags);
-
kblockd_schedule_work(q, &device->requeue_work);
+ spin_unlock_irqrestore(q->queue_lock, flags);

return 0;
}
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -963,13 +963,20 @@ void __scsi_remove_device(struct scsi_de
device_del(dev);
} else
put_device(&sdev->sdev_dev);
+
+ /*
+ * Stop accepting new requests and wait until all queuecommand() and
+ * scsi_run_queue() invocations have finished before tearing down the
+ * device.
+ */
scsi_device_set_state(sdev, SDEV_DEL);
+ blk_cleanup_queue(sdev->request_queue);
+ cancel_work_sync(&sdev->requeue_work);
+
if (sdev->host->hostt->slave_destroy)
sdev->host->hostt->slave_destroy(sdev);
transport_destroy_device(dev);

- /* Freeing the queue signals to block that we're done */
- blk_cleanup_queue(sdev->request_queue);
put_device(dev);
}

2014-07-08 19:27:41

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 079/125] rtmutex: Handle deadlock detection smarter

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Thomas Gleixner <[email protected]>

commit 3d5c9340d1949733eb37616abd15db36aef9a57c upstream.

Even in the case when deadlock detection is not requested by the
caller, we can detect deadlocks. Right now the code stops the lock
chain walk and keeps the waiter enqueued, even on itself. Silly not to
yell when such a scenario is detected and to keep the waiter enqueued.

Return -EDEADLK unconditionally and handle it at the call sites.

The futex calls return -EDEADLK. The non futex ones dequeue the
waiter, throw a warning and put the task into a schedule loop.

Tagged for stable as it makes the code more robust.

Signed-off-by: Thomas Gleixner <[email protected]>
Cc: Steven Rostedt <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Brad Mouring <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
[bwh: Backported to 3.2: adjust filenames]
Signed-off-by: Ben Hutchings <[email protected]>
---
kernel/rtmutex-debug.h | 5 +++++
kernel/rtmutex.c | 33 ++++++++++++++++++++++++++++-----
kernel/rtmutex.h | 5 +++++
3 files changed, 38 insertions(+), 5 deletions(-)

--- a/kernel/rtmutex-debug.h
+++ b/kernel/rtmutex-debug.h
@@ -31,3 +31,8 @@ static inline int debug_rt_mutex_detect_
{
return (waiter != NULL);
}
+
+static inline void rt_mutex_print_deadlock(struct rt_mutex_waiter *w)
+{
+ debug_rt_mutex_print_deadlock(w);
+}
--- a/kernel/rtmutex.c
+++ b/kernel/rtmutex.c
@@ -182,7 +182,7 @@ static int rt_mutex_adjust_prio_chain(st
}
put_task_struct(task);

- return deadlock_detect ? -EDEADLK : 0;
+ return -EDEADLK;
}
retry:
/*
@@ -245,7 +245,7 @@ static int rt_mutex_adjust_prio_chain(st
if (lock == orig_lock || rt_mutex_owner(lock) == top_task) {
debug_rt_mutex_deadlock(deadlock_detect, orig_waiter, lock);
raw_spin_unlock(&lock->wait_lock);
- ret = deadlock_detect ? -EDEADLK : 0;
+ ret = -EDEADLK;
goto out_unlock_pi;
}

@@ -419,7 +419,7 @@ static int task_blocks_on_rt_mutex(struc
* which is wrong, as the other waiter is not in a deadlock
* situation.
*/
- if (detect_deadlock && owner == task)
+ if (owner == task)
return -EDEADLK;

raw_spin_lock_irqsave(&task->pi_lock, flags);
@@ -644,6 +644,26 @@ __rt_mutex_slowlock(struct rt_mutex *loc
return ret;
}

+static void rt_mutex_handle_deadlock(int res, int detect_deadlock,
+ struct rt_mutex_waiter *w)
+{
+ /*
+ * If the result is not -EDEADLOCK or the caller requested
+ * deadlock detection, nothing to do here.
+ */
+ if (res != -EDEADLOCK || detect_deadlock)
+ return;
+
+ /*
+ * Yell lowdly and stop the task right here.
+ */
+ rt_mutex_print_deadlock(w);
+ while (1) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule();
+ }
+}
+
/*
* Slow path lock function:
*/
@@ -681,8 +701,10 @@ rt_mutex_slowlock(struct rt_mutex *lock,

set_current_state(TASK_RUNNING);

- if (unlikely(ret))
+ if (unlikely(ret)) {
remove_waiter(lock, &waiter);
+ rt_mutex_handle_deadlock(ret, detect_deadlock, &waiter);
+ }

/*
* try_to_take_rt_mutex() sets the waiter bit
@@ -990,7 +1012,8 @@ int rt_mutex_start_proxy_lock(struct rt_
return 1;
}

- ret = task_blocks_on_rt_mutex(lock, waiter, task, detect_deadlock);
+ /* We enforce deadlock detection for futexes */
+ ret = task_blocks_on_rt_mutex(lock, waiter, task, 1);

if (ret && !rt_mutex_owner(lock)) {
/*
--- a/kernel/rtmutex.h
+++ b/kernel/rtmutex.h
@@ -24,3 +24,8 @@
#define debug_rt_mutex_print_deadlock(w) do { } while (0)
#define debug_rt_mutex_detect_deadlock(w,d) (d)
#define debug_rt_mutex_reset_waiter(w) do { } while (0)
+
+static inline void rt_mutex_print_deadlock(struct rt_mutex_waiter *w)
+{
+ WARN(1, "rtmutex deadlock detected\n");
+}

2014-07-08 19:28:30

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 098/125] mm: revert 0def08e3 ("mm/mempolicy.c: check return code of check_range")

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Minchan Kim <[email protected]>

commit 082708072a4250f5c4dbc62065e7af93f5e45646 upstream.

Revert commit 0def08e3acc2 because check_range can't fail in
migrate_to_node with considering current usecases.

Quote from Johannes

: I think it makes sense to revert. Not because of the semantics, but I
: just don't see how check_range() could even fail for this callsite:
:
: 1. we pass mm->mmap->vm_start in there, so we should not fail due to
: find_vma()
:
: 2. we pass MPOL_MF_DISCONTIG_OK, so the discontig checks do not apply
: and so can not fail
:
: 3. we pass MPOL_MF_MOVE | MPOL_MF_MOVE_ALL, the page table loops will
: continue until addr == end, so we never fail with -EIO

And I added a new VM_BUG_ON for checking migrate_to_node's future usecase
which might pass to MPOL_MF_STRICT.

Suggested-by: Johannes Weiner <[email protected]>
Signed-off-by: Minchan Kim <[email protected]>
Acked-by: KOSAKI Motohiro <[email protected]>
Cc: Mel Gorman <[email protected]>
Cc: Christoph Lameter <[email protected]>
Cc: David Rientjes <[email protected]>
Cc: Vasiliy Kulikov <[email protected]>
Acked-by: Johannes Weiner <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
mm/mempolicy.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)

--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -945,15 +945,18 @@ static int migrate_to_node(struct mm_str
nodemask_t nmask;
LIST_HEAD(pagelist);
int err = 0;
- struct vm_area_struct *vma;

nodes_clear(nmask);
node_set(source, nmask);

- vma = check_range(mm, mm->mmap->vm_start, mm->task_size, &nmask,
+ /*
+ * This does not "check" the range but isolates all pages that
+ * need migration. Between passing in the full user address
+ * space range and MPOL_MF_DISCONTIG_OK, this call can not fail.
+ */
+ VM_BUG_ON(!(flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)));
+ check_range(mm, mm->mmap->vm_start, mm->task_size, &nmask,
flags | MPOL_MF_DISCONTIG_OK, &pagelist);
- if (IS_ERR(vma))
- return PTR_ERR(vma);

if (!list_empty(&pagelist)) {
err = migrate_pages(&pagelist, new_node_page, dest,

2014-07-08 19:28:29

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 076/125] evm: prohibit userspace writing 'security.evm' HMAC value

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Mimi Zohar <[email protected]>

commit 2fb1c9a4f2dbc2f0bd2431c7fa64d0b5483864e4 upstream.

Calculating the 'security.evm' HMAC value requires access to the
EVM encrypted key. Only the kernel should have access to it. This
patch prevents userspace tools(eg. setfattr, cp --preserve=xattr)
from setting/modifying the 'security.evm' HMAC value directly.

Signed-off-by: Mimi Zohar <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
security/integrity/evm/evm_main.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)

--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -207,12 +207,20 @@ static int evm_protect_xattr(struct dent
* @xattr_value: pointer to the new extended attribute value
* @xattr_value_len: pointer to the new extended attribute value length
*
- * Updating 'security.evm' requires CAP_SYS_ADMIN privileges and that
- * the current value is valid.
+ * Before allowing the 'security.evm' protected xattr to be updated,
+ * verify the existing value is valid. As only the kernel should have
+ * access to the EVM encrypted key needed to calculate the HMAC, prevent
+ * userspace from writing HMAC value. Writing 'security.evm' requires
+ * requires CAP_SYS_ADMIN privileges.
*/
int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name,
const void *xattr_value, size_t xattr_value_len)
{
+ const struct evm_ima_xattr_data *xattr_data = xattr_value;
+
+ if ((strcmp(xattr_name, XATTR_NAME_EVM) == 0)
+ && (xattr_data->type == EVM_XATTR_HMAC))
+ return -EPERM;
return evm_protect_xattr(dentry, xattr_name, xattr_value,
xattr_value_len);
}

2014-07-08 19:29:52

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 081/125] rtmutex: Plug slow unlock race

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Thomas Gleixner <[email protected]>

commit 27e35715df54cbc4f2d044f681802ae30479e7fb upstream.

When the rtmutex fast path is enabled the slow unlock function can
create the following situation:

spin_lock(foo->m->wait_lock);
foo->m->owner = NULL;
rt_mutex_lock(foo->m); <-- fast path
free = atomic_dec_and_test(foo->refcnt);
rt_mutex_unlock(foo->m); <-- fast path
if (free)
kfree(foo);

spin_unlock(foo->m->wait_lock); <--- Use after free.

Plug the race by changing the slow unlock to the following scheme:

while (!rt_mutex_has_waiters(m)) {
/* Clear the waiters bit in m->owner */
clear_rt_mutex_waiters(m);
owner = rt_mutex_owner(m);
spin_unlock(m->wait_lock);
if (cmpxchg(m->owner, owner, 0) == owner)
return;
spin_lock(m->wait_lock);
}

So in case of a new waiter incoming while the owner tries the slow
path unlock we have two situations:

unlock(wait_lock);
lock(wait_lock);
cmpxchg(p, owner, 0) == owner
mark_rt_mutex_waiters(lock);
acquire(lock);

Or:

unlock(wait_lock);
lock(wait_lock);
mark_rt_mutex_waiters(lock);
cmpxchg(p, owner, 0) != owner
enqueue_waiter();
unlock(wait_lock);
lock(wait_lock);
wakeup_next waiter();
unlock(wait_lock);
lock(wait_lock);
acquire(lock);

If the fast path is disabled, then the simple

m->owner = NULL;
unlock(m->wait_lock);

is sufficient as all access to m->owner is serialized via
m->wait_lock;

Also document and clarify the wakeup_next_waiter function as suggested
by Oleg Nesterov.

Reported-by: Steven Rostedt <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Reviewed-by: Steven Rostedt <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
[bwh: Backported to 3.2: adjust filename]
Signed-off-by: Ben Hutchings <[email protected]>
---
kernel/rtmutex.c | 115 ++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 109 insertions(+), 6 deletions(-)

--- a/kernel/rtmutex.c
+++ b/kernel/rtmutex.c
@@ -81,6 +81,47 @@ static inline void mark_rt_mutex_waiters
owner = *p;
} while (cmpxchg(p, owner, owner | RT_MUTEX_HAS_WAITERS) != owner);
}
+
+/*
+ * Safe fastpath aware unlock:
+ * 1) Clear the waiters bit
+ * 2) Drop lock->wait_lock
+ * 3) Try to unlock the lock with cmpxchg
+ */
+static inline bool unlock_rt_mutex_safe(struct rt_mutex *lock)
+ __releases(lock->wait_lock)
+{
+ struct task_struct *owner = rt_mutex_owner(lock);
+
+ clear_rt_mutex_waiters(lock);
+ raw_spin_unlock(&lock->wait_lock);
+ /*
+ * If a new waiter comes in between the unlock and the cmpxchg
+ * we have two situations:
+ *
+ * unlock(wait_lock);
+ * lock(wait_lock);
+ * cmpxchg(p, owner, 0) == owner
+ * mark_rt_mutex_waiters(lock);
+ * acquire(lock);
+ * or:
+ *
+ * unlock(wait_lock);
+ * lock(wait_lock);
+ * mark_rt_mutex_waiters(lock);
+ *
+ * cmpxchg(p, owner, 0) != owner
+ * enqueue_waiter();
+ * unlock(wait_lock);
+ * lock(wait_lock);
+ * wake waiter();
+ * unlock(wait_lock);
+ * lock(wait_lock);
+ * acquire(lock);
+ */
+ return rt_mutex_cmpxchg(lock, owner, NULL);
+}
+
#else
# define rt_mutex_cmpxchg(l,c,n) (0)
static inline void mark_rt_mutex_waiters(struct rt_mutex *lock)
@@ -88,6 +129,17 @@ static inline void mark_rt_mutex_waiters
lock->owner = (struct task_struct *)
((unsigned long)lock->owner | RT_MUTEX_HAS_WAITERS);
}
+
+/*
+ * Simple slow path only version: lock->owner is protected by lock->wait_lock.
+ */
+static inline bool unlock_rt_mutex_safe(struct rt_mutex *lock)
+ __releases(lock->wait_lock)
+{
+ lock->owner = NULL;
+ raw_spin_unlock(&lock->wait_lock);
+ return true;
+}
#endif

/*
@@ -535,7 +587,8 @@ static int task_blocks_on_rt_mutex(struc
/*
* Wake up the next waiter on the lock.
*
- * Remove the top waiter from the current tasks waiter list and wake it up.
+ * Remove the top waiter from the current tasks pi waiter list and
+ * wake it up.
*
* Called with lock->wait_lock held.
*/
@@ -556,10 +609,23 @@ static void wakeup_next_waiter(struct rt
*/
plist_del(&waiter->pi_list_entry, &current->pi_waiters);

- rt_mutex_set_owner(lock, NULL);
+ /*
+ * As we are waking up the top waiter, and the waiter stays
+ * queued on the lock until it gets the lock, this lock
+ * obviously has waiters. Just set the bit here and this has
+ * the added benefit of forcing all new tasks into the
+ * slow path making sure no task of lower priority than
+ * the top waiter can steal this lock.
+ */
+ lock->owner = (void *) RT_MUTEX_HAS_WAITERS;

raw_spin_unlock_irqrestore(&current->pi_lock, flags);

+ /*
+ * It's safe to dereference waiter as it cannot go away as
+ * long as we hold lock->wait_lock. The waiter task needs to
+ * acquire it in order to dequeue the waiter.
+ */
wake_up_process(waiter->task);
}

@@ -820,12 +886,49 @@ rt_mutex_slowunlock(struct rt_mutex *loc

rt_mutex_deadlock_account_unlock(current);

- if (!rt_mutex_has_waiters(lock)) {
- lock->owner = NULL;
- raw_spin_unlock(&lock->wait_lock);
- return;
+ /*
+ * We must be careful here if the fast path is enabled. If we
+ * have no waiters queued we cannot set owner to NULL here
+ * because of:
+ *
+ * foo->lock->owner = NULL;
+ * rtmutex_lock(foo->lock); <- fast path
+ * free = atomic_dec_and_test(foo->refcnt);
+ * rtmutex_unlock(foo->lock); <- fast path
+ * if (free)
+ * kfree(foo);
+ * raw_spin_unlock(foo->lock->wait_lock);
+ *
+ * So for the fastpath enabled kernel:
+ *
+ * Nothing can set the waiters bit as long as we hold
+ * lock->wait_lock. So we do the following sequence:
+ *
+ * owner = rt_mutex_owner(lock);
+ * clear_rt_mutex_waiters(lock);
+ * raw_spin_unlock(&lock->wait_lock);
+ * if (cmpxchg(&lock->owner, owner, 0) == owner)
+ * return;
+ * goto retry;
+ *
+ * The fastpath disabled variant is simple as all access to
+ * lock->owner is serialized by lock->wait_lock:
+ *
+ * lock->owner = NULL;
+ * raw_spin_unlock(&lock->wait_lock);
+ */
+ while (!rt_mutex_has_waiters(lock)) {
+ /* Drops lock->wait_lock ! */
+ if (unlock_rt_mutex_safe(lock) == true)
+ return;
+ /* Relock the rtmutex and try again */
+ raw_spin_lock(&lock->wait_lock);
}

+ /*
+ * The wakeup next waiter path does not suffer from the above
+ * race. See the comments there.
+ */
wakeup_next_waiter(lock);

raw_spin_unlock(&lock->wait_lock);

2014-07-08 19:30:03

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 085/125] ALSA: control: Don't access controls outside of protected regions

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Lars-Peter Clausen <[email protected]>

commit fd9f26e4eca5d08a27d12c0933fceef76ed9663d upstream.

A control that is visible on the card->controls list can be freed at any time.
This means we must not access any of its memory while not holding the
controls_rw_lock. Otherwise we risk a use after free access.

Signed-off-by: Lars-Peter Clausen <[email protected]>
Acked-by: Jaroslav Kysela <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
sound/core/control.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)

--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -329,6 +329,7 @@ int snd_ctl_add(struct snd_card *card, s
{
struct snd_ctl_elem_id id;
unsigned int idx;
+ unsigned int count;
int err = -EINVAL;

if (! kcontrol)
@@ -357,8 +358,9 @@ int snd_ctl_add(struct snd_card *card, s
card->controls_count += kcontrol->count;
kcontrol->id.numid = card->last_numid + 1;
card->last_numid += kcontrol->count;
+ count = kcontrol->count;
up_write(&card->controls_rwsem);
- for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
+ for (idx = 0; idx < count; idx++, id.index++, id.numid++)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
return 0;

@@ -387,6 +389,7 @@ int snd_ctl_replace(struct snd_card *car
bool add_on_replace)
{
struct snd_ctl_elem_id id;
+ unsigned int count;
unsigned int idx;
struct snd_kcontrol *old;
int ret;
@@ -422,8 +425,9 @@ add:
card->controls_count += kcontrol->count;
kcontrol->id.numid = card->last_numid + 1;
card->last_numid += kcontrol->count;
+ count = kcontrol->count;
up_write(&card->controls_rwsem);
- for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
+ for (idx = 0; idx < count; idx++, id.index++, id.numid++)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
return 0;

@@ -894,9 +898,9 @@ static int snd_ctl_elem_write(struct snd
result = kctl->put(kctl, control);
}
if (result > 0) {
+ struct snd_ctl_elem_id id = control->id;
up_read(&card->controls_rwsem);
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
- &control->id);
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &id);
return 0;
}
}
@@ -1330,8 +1334,9 @@ static int snd_ctl_tlv_ioctl(struct snd_
}
err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv);
if (err > 0) {
+ struct snd_ctl_elem_id id = kctl->id;
up_read(&card->controls_rwsem);
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id);
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &id);
return 0;
}
} else {

2014-07-08 19:29:59

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 086/125] ALSA: control: Handle numid overflow

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Lars-Peter Clausen <[email protected]>

commit ac902c112d90a89e59916f751c2745f4dbdbb4bd upstream.

Each control gets automatically assigned its numids when the control is created.
The allocation is done by incrementing the numid by the amount of allocated
numids per allocation. This means that excessive creation and destruction of
controls (e.g. via SNDRV_CTL_IOCTL_ELEM_ADD/REMOVE) can cause the id to
eventually overflow. Currently when this happens for the control that caused the
overflow kctl->id.numid + kctl->count will also over flow causing it to be
smaller than kctl->id.numid. Most of the code assumes that this is something
that can not happen, so we need to make sure that it won't happen

Signed-off-by: Lars-Peter Clausen <[email protected]>
Acked-by: Jaroslav Kysela <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
sound/core/control.c | 4 ++++
1 file changed, 4 insertions(+)

--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -288,6 +288,10 @@ static bool snd_ctl_remove_numid_conflic
{
struct snd_kcontrol *kctl;

+ /* Make sure that the ids assigned to the control do not wrap around */
+ if (card->last_numid >= UINT_MAX - count)
+ card->last_numid = 0;
+
list_for_each_entry(kctl, &card->controls, list) {
if (kctl->id.numid < card->last_numid + 1 + count &&
kctl->id.numid + kctl->count > card->last_numid + 1) {

2014-07-08 19:29:58

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 091/125] b43: fix frequency reported on G-PHY with /new/ firmware

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Rafał Miłecki <[email protected]>

commit 2fc68eb122c7ea6cd5be1fe7d6650c0beb2f4f40 upstream.

Support for firmware rev 508+ was added years ago, but we never noticed
it reports channel in a different way for G-PHY devices. Instead of
offset from 2400 MHz it simply passes channel id (AKA hw_value).

So far it was (most probably) affecting monitor mode users only, but
the following recent commit made it noticeable for quite everybody:

commit 3afc2167f60a327a2c1e1e2600ef209a3c2b75b7
Author: Emmanuel Grumbach <[email protected]>
Date: Tue Mar 4 16:50:13 2014 +0200

cfg80211/mac80211: ignore signal if the frame was heard on wrong channel

Reported-by: Aaro Koskinen <[email protected]>
Signed-off-by: Rafał Miłecki <[email protected]>
Tested-by: Aaro Koskinen <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/wireless/b43/xmit.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)

--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -808,9 +808,13 @@ void b43_rx(struct b43_wldev *dev, struc
break;
case B43_PHYTYPE_G:
status.band = IEEE80211_BAND_2GHZ;
- /* chanid is the radio channel cookie value as used
- * to tune the radio. */
- status.freq = chanid + 2400;
+ /* Somewhere between 478.104 and 508.1084 firmware for G-PHY
+ * has been modified to be compatible with N-PHY and others.
+ */
+ if (dev->fw.rev >= 508)
+ status.freq = ieee80211_channel_to_frequency(chanid, status.band);
+ else
+ status.freq = chanid + 2400;
break;
case B43_PHYTYPE_N:
case B43_PHYTYPE_LP:

2014-07-08 19:29:56

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 087/125] ALSA: control: Make sure that id->index does not overflow

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Lars-Peter Clausen <[email protected]>

commit 883a1d49f0d77d30012f114b2e19fc141beb3e8e upstream.

The ALSA control code expects that the range of assigned indices to a control is
continuous and does not overflow. Currently there are no checks to enforce this.
If a control with a overflowing index range is created that control becomes
effectively inaccessible and unremovable since snd_ctl_find_id() will not be
able to find it. This patch adds a check that makes sure that controls with a
overflowing index range can not be created.

Signed-off-by: Lars-Peter Clausen <[email protected]>
Acked-by: Jaroslav Kysela <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
sound/core/control.c | 3 +++
1 file changed, 3 insertions(+)

--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -341,6 +341,9 @@ int snd_ctl_add(struct snd_card *card, s
if (snd_BUG_ON(!card || !kcontrol->info))
goto error;
id = kcontrol->id;
+ if (id.index > UINT_MAX - kcontrol->count)
+ goto error;
+
down_write(&card->controls_rwsem);
if (snd_ctl_find_id(card, &id)) {
up_write(&card->controls_rwsem);

2014-07-08 19:29:54

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 113/125] sctp: Fix sk_ack_backlog wrap-around problem

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Xufeng Zhang <[email protected]>

[ Upstream commit d3217b15a19a4779c39b212358a5c71d725822ee ]

Consider the scenario:
For a TCP-style socket, while processing the COOKIE_ECHO chunk in
sctp_sf_do_5_1D_ce(), after it has passed a series of sanity check,
a new association would be created in sctp_unpack_cookie(), but afterwards,
some processing maybe failed, and sctp_association_free() will be called to
free the previously allocated association, in sctp_association_free(),
sk_ack_backlog value is decremented for this socket, since the initial
value for sk_ack_backlog is 0, after the decrement, it will be 65535,
a wrap-around problem happens, and if we want to establish new associations
afterward in the same socket, ABORT would be triggered since sctp deem the
accept queue as full.
Fix this issue by only decrementing sk_ack_backlog for associations in
the endpoint's list.

Fix-suggested-by: Neil Horman <[email protected]>
Signed-off-by: Xufeng Zhang <[email protected]>
Acked-by: Daniel Borkmann <[email protected]>
Acked-by: Vlad Yasevich <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/sctp/associola.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -389,7 +389,7 @@ void sctp_association_free(struct sctp_a
/* Only real associations count against the endpoint, so
* don't bother for if this is a temporary association.
*/
- if (!asoc->temp) {
+ if (!list_empty(&asoc->asocs)) {
list_del(&asoc->asocs);

/* Decrement the backlog value for a TCP-style listening

2014-07-08 19:29:53

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 089/125] Bluetooth: Fix SSP acceptor just-works confirmation without MITM

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hedberg <[email protected]>

commit ba15a58b179ed76a7e887177f2b06de12c58ec8f upstream.

=46romthe Bluetooth Core Specification 4.1 page 1958:

"if both devices have set the Authentication_Requirements parameter to
one of the MITM Protection Not Required options, authentication stage 1
shall function as if both devices set their IO capabilities to
DisplayOnly (e.g., Numeric comparison with automatic confirmation on
both devices)"

So far our implementation has done user confirmation for all just-works
cases regardless of the MITM requirements, however following the
specification to the word means that we should not be doing confirmation
when neither side has the MITM flag set.

Signed-off-by: Johan Hedberg <[email protected]>
Tested-by: Szymon Janc <[email protected]>
Signed-off-by: Marcel Holtmann <[email protected]>
[bwh: Backported to 3.2: s/conn->flags/conn->pend/]
Signed-off-by: Ben Hutchings <[email protected]>
---
net/bluetooth/hci_event.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)

--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2690,8 +2690,11 @@ static inline void hci_user_confirm_requ

/* If we're not the initiators request authorization to
* proceed from user space (mgmt_user_confirm with
- * confirm_hint set to 1). */
- if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
+ * confirm_hint set to 1). The exception is if neither
+ * side had MITM in which case we do auto-accept.
+ */
+ if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) &&
+ (loc_mitm || rem_mitm)) {
BT_DBG("Confirming auto-accept as acceptor");
confirm_hint = 1;
goto confirm;

2014-07-08 19:29:50

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 099/125] mm: fix crashes from mbind() merging vmas

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Hugh Dickins <[email protected]>

commit d05f0cdcbe6388723f1900c549b4850360545201 upstream.

In v2.6.34 commit 9d8cebd4bcd7 ("mm: fix mbind vma merge problem")
introduced vma merging to mbind(), but it should have also changed the
convention of passing start vma from queue_pages_range() (formerly
check_range()) to new_vma_page(): vma merging may have already freed
that structure, resulting in BUG at mm/mempolicy.c:1738 and probably
worse crashes.

Fixes: 9d8cebd4bcd7 ("mm: fix mbind vma merge problem")
Reported-by: Naoya Horiguchi <[email protected]>
Tested-by: Naoya Horiguchi <[email protected]>
Signed-off-by: Hugh Dickins <[email protected]>
Acked-by: Christoph Lameter <[email protected]>
Cc: KOSAKI Motohiro <[email protected]>
Cc: Minchan Kim <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
[bwh: Backported to 3.2:
- Adjust context
- Keep the same arguments to migrate_pages() except for private=start]
Signed-off-by: Ben Hutchings <[email protected]>
---
mm/mempolicy.c | 46 ++++++++++++++++++++--------------------------
1 file changed, 20 insertions(+), 26 deletions(-)

--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -566,24 +566,23 @@ static inline int check_pgd_range(struct
* If pagelist != NULL then isolate pages from the LRU and
* put them on the pagelist.
*/
-static struct vm_area_struct *
+static int
check_range(struct mm_struct *mm, unsigned long start, unsigned long end,
const nodemask_t *nodes, unsigned long flags, void *private)
{
- int err;
- struct vm_area_struct *first, *vma, *prev;
-
+ int err = 0;
+ struct vm_area_struct *vma, *prev;

- first = find_vma(mm, start);
- if (!first)
- return ERR_PTR(-EFAULT);
+ vma = find_vma(mm, start);
+ if (!vma)
+ return -EFAULT;
prev = NULL;
- for (vma = first; vma && vma->vm_start < end; vma = vma->vm_next) {
+ for (; vma && vma->vm_start < end; vma = vma->vm_next) {
if (!(flags & MPOL_MF_DISCONTIG_OK)) {
if (!vma->vm_next && vma->vm_end < end)
- return ERR_PTR(-EFAULT);
+ return -EFAULT;
if (prev && prev->vm_end < vma->vm_start)
- return ERR_PTR(-EFAULT);
+ return -EFAULT;
}
if (!is_vm_hugetlb_page(vma) &&
((flags & MPOL_MF_STRICT) ||
@@ -597,14 +596,12 @@ check_range(struct mm_struct *mm, unsign
start = vma->vm_start;
err = check_pgd_range(vma, start, endvma, nodes,
flags, private);
- if (err) {
- first = ERR_PTR(err);
+ if (err)
break;
- }
}
prev = vma;
}
- return first;
+ return err;
}

/*
@@ -1060,16 +1057,17 @@ out:

/*
* Allocate a new page for page migration based on vma policy.
- * Start assuming that page is mapped by vma pointed to by @private.
+ * Start by assuming the page is mapped by the same vma as contains @start.
* Search forward from there, if not. N.B., this assumes that the
* list of pages handed to migrate_pages()--which is how we get here--
* is in virtual address order.
*/
-static struct page *new_vma_page(struct page *page, unsigned long private, int **x)
+static struct page *new_page(struct page *page, unsigned long start, int **x)
{
- struct vm_area_struct *vma = (struct vm_area_struct *)private;
+ struct vm_area_struct *vma;
unsigned long uninitialized_var(address);

+ vma = find_vma(current->mm, start);
while (vma) {
address = page_address_in_vma(page, vma);
if (address != -EFAULT)
@@ -1095,7 +1093,7 @@ int do_migrate_pages(struct mm_struct *m
return -ENOSYS;
}

-static struct page *new_vma_page(struct page *page, unsigned long private, int **x)
+static struct page *new_page(struct page *page, unsigned long start, int **x)
{
return NULL;
}
@@ -1105,7 +1103,6 @@ static long do_mbind(unsigned long start
unsigned short mode, unsigned short mode_flags,
nodemask_t *nmask, unsigned long flags)
{
- struct vm_area_struct *vma;
struct mm_struct *mm = current->mm;
struct mempolicy *new;
unsigned long end;
@@ -1169,19 +1166,16 @@ static long do_mbind(unsigned long start
if (err)
goto mpol_out;

- vma = check_range(mm, start, end, nmask,
+ err = check_range(mm, start, end, nmask,
flags | MPOL_MF_INVERT, &pagelist);
-
- err = PTR_ERR(vma);
- if (!IS_ERR(vma)) {
+ if (!err) {
int nr_failed = 0;

err = mbind_range(mm, start, end, new);

if (!list_empty(&pagelist)) {
- nr_failed = migrate_pages(&pagelist, new_vma_page,
- (unsigned long)vma,
- false, true);
+ nr_failed = migrate_pages(&pagelist, new_page,
+ start, false, true);
if (nr_failed)
putback_lru_pages(&pagelist);
}

2014-07-08 19:29:48

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 008/125] IB/srp: Fix a sporadic crash triggered by cable pulling

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Bart Van Assche <[email protected]>

commit 024ca90151f5e4296d30f72c13ff9a075e23c9ec upstream.

Avoid that the loops that iterate over the request ring can encounter
a pointer to a SCSI command in req->scmnd that is no longer associated
with that request. If the function srp_unmap_data() is invoked twice
for a SCSI command that is not in flight then that would cause
ib_fmr_pool_unmap() to be invoked with an invalid pointer as argument,
resulting in a kernel oops.

Reported-by: Sagi Grimberg <[email protected]>
Reference: http://thread.gmane.org/gmane.linux.drivers.rdma/19068/focus=19069
Signed-off-by: Bart Van Assche <[email protected]>
Reviewed-by: Sagi Grimberg <[email protected]>
Signed-off-by: Roland Dreier <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/infiniband/ulp/srp/ib_srp.c | 6 ++++++
1 file changed, 6 insertions(+)

--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -1353,6 +1353,12 @@ err_unmap:
err_iu:
srp_put_tx_iu(target, iu, SRP_IU_CMD);

+ /*
+ * Avoid that the loops that iterate over the request ring can
+ * encounter a dangling SCSI command pointer.
+ */
+ req->scmnd = NULL;
+
spin_lock_irqsave(&target->lock, flags);
list_add(&req->list, &target->free_reqs);

2014-07-08 19:33:45

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 093/125] lib/lzo: Rename lzo1x_decompress.c to lzo1x_decompress_safe.c

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: "Markus F.X.J. Oberhumer" <[email protected]>

commit b6bec26cea948148a9420e7a0ac337f925de49e7 upstream.

Rename the source file to match the function name and thereby
also make room for a possible future even slightly faster
"non-safe" decompressor version.

Signed-off-by: Markus F.X.J. Oberhumer <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
lib/decompress_unlzo.c | 2 +-
lib/lzo/Makefile | 2 +-
lib/lzo/lzo1x_decompress.c | 255 ----------------------------------------
lib/lzo/lzo1x_decompress_safe.c | 255 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 257 insertions(+), 257 deletions(-)
delete mode 100644 lib/lzo/lzo1x_decompress.c
create mode 100644 lib/lzo/lzo1x_decompress_safe.c

--- a/lib/decompress_unlzo.c
+++ b/lib/decompress_unlzo.c
@@ -31,7 +31,7 @@
*/

#ifdef STATIC
-#include "lzo/lzo1x_decompress.c"
+#include "lzo/lzo1x_decompress_safe.c"
#else
#include <linux/decompress/unlzo.h>
#endif
--- a/lib/lzo/Makefile
+++ b/lib/lzo/Makefile
@@ -1,5 +1,5 @@
lzo_compress-objs := lzo1x_compress.o
-lzo_decompress-objs := lzo1x_decompress.o
+lzo_decompress-objs := lzo1x_decompress_safe.o

obj-$(CONFIG_LZO_COMPRESS) += lzo_compress.o
obj-$(CONFIG_LZO_DECOMPRESS) += lzo_decompress.o
--- a/lib/lzo/lzo1x_decompress.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * LZO1X Decompressor from MiniLZO
- *
- * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <[email protected]>
- *
- * The full LZO package can be found at:
- * http://www.oberhumer.com/opensource/lzo/
- *
- * Changed for kernel use by:
- * Nitin Gupta <[email protected]>
- * Richard Purdie <[email protected]>
- */
-
-#ifndef STATIC
-#include <linux/module.h>
-#include <linux/kernel.h>
-#endif
-
-#include <asm/unaligned.h>
-#include <linux/lzo.h>
-#include "lzodefs.h"
-
-#define HAVE_IP(x, ip_end, ip) ((size_t)(ip_end - ip) < (x))
-#define HAVE_OP(x, op_end, op) ((size_t)(op_end - op) < (x))
-#define HAVE_LB(m_pos, out, op) (m_pos < out || m_pos >= op)
-
-#define COPY4(dst, src) \
- put_unaligned(get_unaligned((const u32 *)(src)), (u32 *)(dst))
-
-int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
- unsigned char *out, size_t *out_len)
-{
- const unsigned char * const ip_end = in + in_len;
- unsigned char * const op_end = out + *out_len;
- const unsigned char *ip = in, *m_pos;
- unsigned char *op = out;
- size_t t;
-
- *out_len = 0;
-
- if (*ip > 17) {
- t = *ip++ - 17;
- if (t < 4)
- goto match_next;
- if (HAVE_OP(t, op_end, op))
- goto output_overrun;
- if (HAVE_IP(t + 1, ip_end, ip))
- goto input_overrun;
- do {
- *op++ = *ip++;
- } while (--t > 0);
- goto first_literal_run;
- }
-
- while ((ip < ip_end)) {
- t = *ip++;
- if (t >= 16)
- goto match;
- if (t == 0) {
- if (HAVE_IP(1, ip_end, ip))
- goto input_overrun;
- while (*ip == 0) {
- t += 255;
- ip++;
- if (HAVE_IP(1, ip_end, ip))
- goto input_overrun;
- }
- t += 15 + *ip++;
- }
- if (HAVE_OP(t + 3, op_end, op))
- goto output_overrun;
- if (HAVE_IP(t + 4, ip_end, ip))
- goto input_overrun;
-
- COPY4(op, ip);
- op += 4;
- ip += 4;
- if (--t > 0) {
- if (t >= 4) {
- do {
- COPY4(op, ip);
- op += 4;
- ip += 4;
- t -= 4;
- } while (t >= 4);
- if (t > 0) {
- do {
- *op++ = *ip++;
- } while (--t > 0);
- }
- } else {
- do {
- *op++ = *ip++;
- } while (--t > 0);
- }
- }
-
-first_literal_run:
- t = *ip++;
- if (t >= 16)
- goto match;
- m_pos = op - (1 + M2_MAX_OFFSET);
- m_pos -= t >> 2;
- m_pos -= *ip++ << 2;
-
- if (HAVE_LB(m_pos, out, op))
- goto lookbehind_overrun;
-
- if (HAVE_OP(3, op_end, op))
- goto output_overrun;
- *op++ = *m_pos++;
- *op++ = *m_pos++;
- *op++ = *m_pos;
-
- goto match_done;
-
- do {
-match:
- if (t >= 64) {
- m_pos = op - 1;
- m_pos -= (t >> 2) & 7;
- m_pos -= *ip++ << 3;
- t = (t >> 5) - 1;
- if (HAVE_LB(m_pos, out, op))
- goto lookbehind_overrun;
- if (HAVE_OP(t + 3 - 1, op_end, op))
- goto output_overrun;
- goto copy_match;
- } else if (t >= 32) {
- t &= 31;
- if (t == 0) {
- if (HAVE_IP(1, ip_end, ip))
- goto input_overrun;
- while (*ip == 0) {
- t += 255;
- ip++;
- if (HAVE_IP(1, ip_end, ip))
- goto input_overrun;
- }
- t += 31 + *ip++;
- }
- m_pos = op - 1;
- m_pos -= get_unaligned_le16(ip) >> 2;
- ip += 2;
- } else if (t >= 16) {
- m_pos = op;
- m_pos -= (t & 8) << 11;
-
- t &= 7;
- if (t == 0) {
- if (HAVE_IP(1, ip_end, ip))
- goto input_overrun;
- while (*ip == 0) {
- t += 255;
- ip++;
- if (HAVE_IP(1, ip_end, ip))
- goto input_overrun;
- }
- t += 7 + *ip++;
- }
- m_pos -= get_unaligned_le16(ip) >> 2;
- ip += 2;
- if (m_pos == op)
- goto eof_found;
- m_pos -= 0x4000;
- } else {
- m_pos = op - 1;
- m_pos -= t >> 2;
- m_pos -= *ip++ << 2;
-
- if (HAVE_LB(m_pos, out, op))
- goto lookbehind_overrun;
- if (HAVE_OP(2, op_end, op))
- goto output_overrun;
-
- *op++ = *m_pos++;
- *op++ = *m_pos;
- goto match_done;
- }
-
- if (HAVE_LB(m_pos, out, op))
- goto lookbehind_overrun;
- if (HAVE_OP(t + 3 - 1, op_end, op))
- goto output_overrun;
-
- if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) {
- COPY4(op, m_pos);
- op += 4;
- m_pos += 4;
- t -= 4 - (3 - 1);
- do {
- COPY4(op, m_pos);
- op += 4;
- m_pos += 4;
- t -= 4;
- } while (t >= 4);
- if (t > 0)
- do {
- *op++ = *m_pos++;
- } while (--t > 0);
- } else {
-copy_match:
- *op++ = *m_pos++;
- *op++ = *m_pos++;
- do {
- *op++ = *m_pos++;
- } while (--t > 0);
- }
-match_done:
- t = ip[-2] & 3;
- if (t == 0)
- break;
-match_next:
- if (HAVE_OP(t, op_end, op))
- goto output_overrun;
- if (HAVE_IP(t + 1, ip_end, ip))
- goto input_overrun;
-
- *op++ = *ip++;
- if (t > 1) {
- *op++ = *ip++;
- if (t > 2)
- *op++ = *ip++;
- }
-
- t = *ip++;
- } while (ip < ip_end);
- }
-
- *out_len = op - out;
- return LZO_E_EOF_NOT_FOUND;
-
-eof_found:
- *out_len = op - out;
- return (ip == ip_end ? LZO_E_OK :
- (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
-input_overrun:
- *out_len = op - out;
- return LZO_E_INPUT_OVERRUN;
-
-output_overrun:
- *out_len = op - out;
- return LZO_E_OUTPUT_OVERRUN;
-
-lookbehind_overrun:
- *out_len = op - out;
- return LZO_E_LOOKBEHIND_OVERRUN;
-}
-#ifndef STATIC
-EXPORT_SYMBOL_GPL(lzo1x_decompress_safe);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("LZO1X Decompressor");
-
-#endif
--- /dev/null
+++ b/lib/lzo/lzo1x_decompress_safe.c
@@ -0,0 +1,255 @@
+/*
+ * LZO1X Decompressor from MiniLZO
+ *
+ * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <[email protected]>
+ *
+ * The full LZO package can be found at:
+ * http://www.oberhumer.com/opensource/lzo/
+ *
+ * Changed for kernel use by:
+ * Nitin Gupta <[email protected]>
+ * Richard Purdie <[email protected]>
+ */
+
+#ifndef STATIC
+#include <linux/module.h>
+#include <linux/kernel.h>
+#endif
+
+#include <asm/unaligned.h>
+#include <linux/lzo.h>
+#include "lzodefs.h"
+
+#define HAVE_IP(x, ip_end, ip) ((size_t)(ip_end - ip) < (x))
+#define HAVE_OP(x, op_end, op) ((size_t)(op_end - op) < (x))
+#define HAVE_LB(m_pos, out, op) (m_pos < out || m_pos >= op)
+
+#define COPY4(dst, src) \
+ put_unaligned(get_unaligned((const u32 *)(src)), (u32 *)(dst))
+
+int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
+ unsigned char *out, size_t *out_len)
+{
+ const unsigned char * const ip_end = in + in_len;
+ unsigned char * const op_end = out + *out_len;
+ const unsigned char *ip = in, *m_pos;
+ unsigned char *op = out;
+ size_t t;
+
+ *out_len = 0;
+
+ if (*ip > 17) {
+ t = *ip++ - 17;
+ if (t < 4)
+ goto match_next;
+ if (HAVE_OP(t, op_end, op))
+ goto output_overrun;
+ if (HAVE_IP(t + 1, ip_end, ip))
+ goto input_overrun;
+ do {
+ *op++ = *ip++;
+ } while (--t > 0);
+ goto first_literal_run;
+ }
+
+ while ((ip < ip_end)) {
+ t = *ip++;
+ if (t >= 16)
+ goto match;
+ if (t == 0) {
+ if (HAVE_IP(1, ip_end, ip))
+ goto input_overrun;
+ while (*ip == 0) {
+ t += 255;
+ ip++;
+ if (HAVE_IP(1, ip_end, ip))
+ goto input_overrun;
+ }
+ t += 15 + *ip++;
+ }
+ if (HAVE_OP(t + 3, op_end, op))
+ goto output_overrun;
+ if (HAVE_IP(t + 4, ip_end, ip))
+ goto input_overrun;
+
+ COPY4(op, ip);
+ op += 4;
+ ip += 4;
+ if (--t > 0) {
+ if (t >= 4) {
+ do {
+ COPY4(op, ip);
+ op += 4;
+ ip += 4;
+ t -= 4;
+ } while (t >= 4);
+ if (t > 0) {
+ do {
+ *op++ = *ip++;
+ } while (--t > 0);
+ }
+ } else {
+ do {
+ *op++ = *ip++;
+ } while (--t > 0);
+ }
+ }
+
+first_literal_run:
+ t = *ip++;
+ if (t >= 16)
+ goto match;
+ m_pos = op - (1 + M2_MAX_OFFSET);
+ m_pos -= t >> 2;
+ m_pos -= *ip++ << 2;
+
+ if (HAVE_LB(m_pos, out, op))
+ goto lookbehind_overrun;
+
+ if (HAVE_OP(3, op_end, op))
+ goto output_overrun;
+ *op++ = *m_pos++;
+ *op++ = *m_pos++;
+ *op++ = *m_pos;
+
+ goto match_done;
+
+ do {
+match:
+ if (t >= 64) {
+ m_pos = op - 1;
+ m_pos -= (t >> 2) & 7;
+ m_pos -= *ip++ << 3;
+ t = (t >> 5) - 1;
+ if (HAVE_LB(m_pos, out, op))
+ goto lookbehind_overrun;
+ if (HAVE_OP(t + 3 - 1, op_end, op))
+ goto output_overrun;
+ goto copy_match;
+ } else if (t >= 32) {
+ t &= 31;
+ if (t == 0) {
+ if (HAVE_IP(1, ip_end, ip))
+ goto input_overrun;
+ while (*ip == 0) {
+ t += 255;
+ ip++;
+ if (HAVE_IP(1, ip_end, ip))
+ goto input_overrun;
+ }
+ t += 31 + *ip++;
+ }
+ m_pos = op - 1;
+ m_pos -= get_unaligned_le16(ip) >> 2;
+ ip += 2;
+ } else if (t >= 16) {
+ m_pos = op;
+ m_pos -= (t & 8) << 11;
+
+ t &= 7;
+ if (t == 0) {
+ if (HAVE_IP(1, ip_end, ip))
+ goto input_overrun;
+ while (*ip == 0) {
+ t += 255;
+ ip++;
+ if (HAVE_IP(1, ip_end, ip))
+ goto input_overrun;
+ }
+ t += 7 + *ip++;
+ }
+ m_pos -= get_unaligned_le16(ip) >> 2;
+ ip += 2;
+ if (m_pos == op)
+ goto eof_found;
+ m_pos -= 0x4000;
+ } else {
+ m_pos = op - 1;
+ m_pos -= t >> 2;
+ m_pos -= *ip++ << 2;
+
+ if (HAVE_LB(m_pos, out, op))
+ goto lookbehind_overrun;
+ if (HAVE_OP(2, op_end, op))
+ goto output_overrun;
+
+ *op++ = *m_pos++;
+ *op++ = *m_pos;
+ goto match_done;
+ }
+
+ if (HAVE_LB(m_pos, out, op))
+ goto lookbehind_overrun;
+ if (HAVE_OP(t + 3 - 1, op_end, op))
+ goto output_overrun;
+
+ if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) {
+ COPY4(op, m_pos);
+ op += 4;
+ m_pos += 4;
+ t -= 4 - (3 - 1);
+ do {
+ COPY4(op, m_pos);
+ op += 4;
+ m_pos += 4;
+ t -= 4;
+ } while (t >= 4);
+ if (t > 0)
+ do {
+ *op++ = *m_pos++;
+ } while (--t > 0);
+ } else {
+copy_match:
+ *op++ = *m_pos++;
+ *op++ = *m_pos++;
+ do {
+ *op++ = *m_pos++;
+ } while (--t > 0);
+ }
+match_done:
+ t = ip[-2] & 3;
+ if (t == 0)
+ break;
+match_next:
+ if (HAVE_OP(t, op_end, op))
+ goto output_overrun;
+ if (HAVE_IP(t + 1, ip_end, ip))
+ goto input_overrun;
+
+ *op++ = *ip++;
+ if (t > 1) {
+ *op++ = *ip++;
+ if (t > 2)
+ *op++ = *ip++;
+ }
+
+ t = *ip++;
+ } while (ip < ip_end);
+ }
+
+ *out_len = op - out;
+ return LZO_E_EOF_NOT_FOUND;
+
+eof_found:
+ *out_len = op - out;
+ return (ip == ip_end ? LZO_E_OK :
+ (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
+input_overrun:
+ *out_len = op - out;
+ return LZO_E_INPUT_OVERRUN;
+
+output_overrun:
+ *out_len = op - out;
+ return LZO_E_OUTPUT_OVERRUN;
+
+lookbehind_overrun:
+ *out_len = op - out;
+ return LZO_E_LOOKBEHIND_OVERRUN;
+}
+#ifndef STATIC
+EXPORT_SYMBOL_GPL(lzo1x_decompress_safe);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("LZO1X Decompressor");
+
+#endif

2014-07-08 19:33:44

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 094/125] lib/lzo: Update LZO compression to current upstream version

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: "Markus F.X.J. Oberhumer" <[email protected]>

commit 8b975bd3f9089f8ee5d7bbfd798537b992bbc7e7 upstream.

This commit updates the kernel LZO code to the current upsteam version
which features a significant speed improvement - benchmarking the Calgary
and Silesia test corpora typically shows a doubled performance in
both compression and decompression on modern i386/x86_64/powerpc machines.

Signed-off-by: Markus F.X.J. Oberhumer <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
include/linux/lzo.h | 15 +-
lib/lzo/lzo1x_compress.c | 335 ++++++++++++++++++++++----------------
lib/lzo/lzo1x_decompress_safe.c | 350 +++++++++++++++++++---------------------
lib/lzo/lzodefs.h | 38 +++--
4 files changed, 395 insertions(+), 343 deletions(-)

--- a/include/linux/lzo.h
+++ b/include/linux/lzo.h
@@ -4,28 +4,28 @@
* LZO Public Kernel Interface
* A mini subset of the LZO real-time data compression library
*
- * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <[email protected]>
+ * Copyright (C) 1996-2012 Markus F.X.J. Oberhumer <[email protected]>
*
* The full LZO package can be found at:
* http://www.oberhumer.com/opensource/lzo/
*
- * Changed for kernel use by:
+ * Changed for Linux kernel use by:
* Nitin Gupta <[email protected]>
* Richard Purdie <[email protected]>
*/

-#define LZO1X_MEM_COMPRESS (16384 * sizeof(unsigned char *))
-#define LZO1X_1_MEM_COMPRESS LZO1X_MEM_COMPRESS
+#define LZO1X_1_MEM_COMPRESS (8192 * sizeof(unsigned short))
+#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS

#define lzo1x_worst_compress(x) ((x) + ((x) / 16) + 64 + 3)

-/* This requires 'workmem' of size LZO1X_1_MEM_COMPRESS */
+/* This requires 'wrkmem' of size LZO1X_1_MEM_COMPRESS */
int lzo1x_1_compress(const unsigned char *src, size_t src_len,
- unsigned char *dst, size_t *dst_len, void *wrkmem);
+ unsigned char *dst, size_t *dst_len, void *wrkmem);

/* safe decompression with overrun testing */
int lzo1x_decompress_safe(const unsigned char *src, size_t src_len,
- unsigned char *dst, size_t *dst_len);
+ unsigned char *dst, size_t *dst_len);

/*
* Return values (< 0 = Error)
@@ -40,5 +40,6 @@ int lzo1x_decompress_safe(const unsigned
#define LZO_E_EOF_NOT_FOUND (-7)
#define LZO_E_INPUT_NOT_CONSUMED (-8)
#define LZO_E_NOT_YET_IMPLEMENTED (-9)
+#define LZO_E_INVALID_ARGUMENT (-10)

#endif
--- a/lib/lzo/lzo1x_compress.c
+++ b/lib/lzo/lzo1x_compress.c
@@ -1,194 +1,243 @@
/*
- * LZO1X Compressor from MiniLZO
+ * LZO1X Compressor from LZO
*
- * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <[email protected]>
+ * Copyright (C) 1996-2012 Markus F.X.J. Oberhumer <[email protected]>
*
* The full LZO package can be found at:
* http://www.oberhumer.com/opensource/lzo/
*
- * Changed for kernel use by:
+ * Changed for Linux kernel use by:
* Nitin Gupta <[email protected]>
* Richard Purdie <[email protected]>
*/

#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/lzo.h>
#include <asm/unaligned.h>
+#include <linux/lzo.h>
#include "lzodefs.h"

static noinline size_t
-_lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
- unsigned char *out, size_t *out_len, void *wrkmem)
+lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
+ unsigned char *out, size_t *out_len,
+ size_t ti, void *wrkmem)
{
+ const unsigned char *ip;
+ unsigned char *op;
const unsigned char * const in_end = in + in_len;
- const unsigned char * const ip_end = in + in_len - M2_MAX_LEN - 5;
- const unsigned char ** const dict = wrkmem;
- const unsigned char *ip = in, *ii = ip;
- const unsigned char *end, *m, *m_pos;
- size_t m_off, m_len, dindex;
- unsigned char *op = out;
+ const unsigned char * const ip_end = in + in_len - 20;
+ const unsigned char *ii;
+ lzo_dict_t * const dict = (lzo_dict_t *) wrkmem;

- ip += 4;
+ op = out;
+ ip = in;
+ ii = ip;
+ ip += ti < 4 ? 4 - ti : 0;

for (;;) {
- dindex = ((size_t)(0x21 * DX3(ip, 5, 5, 6)) >> 5) & D_MASK;
- m_pos = dict[dindex];
-
- if (m_pos < in)
- goto literal;
-
- if (ip == m_pos || ((size_t)(ip - m_pos) > M4_MAX_OFFSET))
- goto literal;
-
- m_off = ip - m_pos;
- if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
- goto try_match;
-
- dindex = (dindex & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f);
- m_pos = dict[dindex];
-
- if (m_pos < in)
- goto literal;
-
- if (ip == m_pos || ((size_t)(ip - m_pos) > M4_MAX_OFFSET))
- goto literal;
-
- m_off = ip - m_pos;
- if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
- goto try_match;
-
- goto literal;
-
-try_match:
- if (get_unaligned((const unsigned short *)m_pos)
- == get_unaligned((const unsigned short *)ip)) {
- if (likely(m_pos[2] == ip[2]))
- goto match;
- }
-
+ const unsigned char *m_pos;
+ size_t t, m_len, m_off;
+ u32 dv;
literal:
- dict[dindex] = ip;
- ++ip;
+ ip += 1 + ((ip - ii) >> 5);
+next:
if (unlikely(ip >= ip_end))
break;
- continue;
-
-match:
- dict[dindex] = ip;
- if (ip != ii) {
- size_t t = ip - ii;
+ dv = get_unaligned_le32(ip);
+ t = ((dv * 0x1824429d) >> (32 - D_BITS)) & D_MASK;
+ m_pos = in + dict[t];
+ dict[t] = (lzo_dict_t) (ip - in);
+ if (unlikely(dv != get_unaligned_le32(m_pos)))
+ goto literal;

+ ii -= ti;
+ ti = 0;
+ t = ip - ii;
+ if (t != 0) {
if (t <= 3) {
op[-2] |= t;
- } else if (t <= 18) {
+ COPY4(op, ii);
+ op += t;
+ } else if (t <= 16) {
*op++ = (t - 3);
+ COPY8(op, ii);
+ COPY8(op + 8, ii + 8);
+ op += t;
} else {
- size_t tt = t - 18;
-
- *op++ = 0;
- while (tt > 255) {
- tt -= 255;
+ if (t <= 18) {
+ *op++ = (t - 3);
+ } else {
+ size_t tt = t - 18;
*op++ = 0;
+ while (unlikely(tt > 255)) {
+ tt -= 255;
+ *op++ = 0;
+ }
+ *op++ = tt;
}
- *op++ = tt;
+ do {
+ COPY8(op, ii);
+ COPY8(op + 8, ii + 8);
+ op += 16;
+ ii += 16;
+ t -= 16;
+ } while (t >= 16);
+ if (t > 0) do {
+ *op++ = *ii++;
+ } while (--t > 0);
}
+ }
+
+ m_len = 4;
+ {
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && defined(LZO_USE_CTZ64)
+ u64 v;
+ v = get_unaligned((const u64 *) (ip + m_len)) ^
+ get_unaligned((const u64 *) (m_pos + m_len));
+ if (unlikely(v == 0)) {
+ do {
+ m_len += 8;
+ v = get_unaligned((const u64 *) (ip + m_len)) ^
+ get_unaligned((const u64 *) (m_pos + m_len));
+ if (unlikely(ip + m_len >= ip_end))
+ goto m_len_done;
+ } while (v == 0);
+ }
+# if defined(__LITTLE_ENDIAN)
+ m_len += (unsigned) __builtin_ctzll(v) / 8;
+# elif defined(__BIG_ENDIAN)
+ m_len += (unsigned) __builtin_clzll(v) / 8;
+# else
+# error "missing endian definition"
+# endif
+#elif defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && defined(LZO_USE_CTZ32)
+ u32 v;
+ v = get_unaligned((const u32 *) (ip + m_len)) ^
+ get_unaligned((const u32 *) (m_pos + m_len));
+ if (unlikely(v == 0)) {
do {
- *op++ = *ii++;
- } while (--t > 0);
+ m_len += 4;
+ v = get_unaligned((const u32 *) (ip + m_len)) ^
+ get_unaligned((const u32 *) (m_pos + m_len));
+ if (v != 0)
+ break;
+ m_len += 4;
+ v = get_unaligned((const u32 *) (ip + m_len)) ^
+ get_unaligned((const u32 *) (m_pos + m_len));
+ if (unlikely(ip + m_len >= ip_end))
+ goto m_len_done;
+ } while (v == 0);
}
+# if defined(__LITTLE_ENDIAN)
+ m_len += (unsigned) __builtin_ctz(v) / 8;
+# elif defined(__BIG_ENDIAN)
+ m_len += (unsigned) __builtin_clz(v) / 8;
+# else
+# error "missing endian definition"
+# endif
+#else
+ if (unlikely(ip[m_len] == m_pos[m_len])) {
+ do {
+ m_len += 1;
+ if (ip[m_len] != m_pos[m_len])
+ break;
+ m_len += 1;
+ if (ip[m_len] != m_pos[m_len])
+ break;
+ m_len += 1;
+ if (ip[m_len] != m_pos[m_len])
+ break;
+ m_len += 1;
+ if (ip[m_len] != m_pos[m_len])
+ break;
+ m_len += 1;
+ if (ip[m_len] != m_pos[m_len])
+ break;
+ m_len += 1;
+ if (ip[m_len] != m_pos[m_len])
+ break;
+ m_len += 1;
+ if (ip[m_len] != m_pos[m_len])
+ break;
+ m_len += 1;
+ if (unlikely(ip + m_len >= ip_end))
+ goto m_len_done;
+ } while (ip[m_len] == m_pos[m_len]);
+ }
+#endif
+ }
+m_len_done:

- ip += 3;
- if (m_pos[3] != *ip++ || m_pos[4] != *ip++
- || m_pos[5] != *ip++ || m_pos[6] != *ip++
- || m_pos[7] != *ip++ || m_pos[8] != *ip++) {
- --ip;
- m_len = ip - ii;
-
- if (m_off <= M2_MAX_OFFSET) {
- m_off -= 1;
- *op++ = (((m_len - 1) << 5)
- | ((m_off & 7) << 2));
- *op++ = (m_off >> 3);
- } else if (m_off <= M3_MAX_OFFSET) {
- m_off -= 1;
+ m_off = ip - m_pos;
+ ip += m_len;
+ ii = ip;
+ if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) {
+ m_off -= 1;
+ *op++ = (((m_len - 1) << 5) | ((m_off & 7) << 2));
+ *op++ = (m_off >> 3);
+ } else if (m_off <= M3_MAX_OFFSET) {
+ m_off -= 1;
+ if (m_len <= M3_MAX_LEN)
*op++ = (M3_MARKER | (m_len - 2));
- goto m3_m4_offset;
- } else {
- m_off -= 0x4000;
-
- *op++ = (M4_MARKER | ((m_off & 0x4000) >> 11)
- | (m_len - 2));
- goto m3_m4_offset;
+ else {
+ m_len -= M3_MAX_LEN;
+ *op++ = M3_MARKER | 0;
+ while (unlikely(m_len > 255)) {
+ m_len -= 255;
+ *op++ = 0;
+ }
+ *op++ = (m_len);
}
+ *op++ = (m_off << 2);
+ *op++ = (m_off >> 6);
} else {
- end = in_end;
- m = m_pos + M2_MAX_LEN + 1;
-
- while (ip < end && *m == *ip) {
- m++;
- ip++;
- }
- m_len = ip - ii;
-
- if (m_off <= M3_MAX_OFFSET) {
- m_off -= 1;
- if (m_len <= 33) {
- *op++ = (M3_MARKER | (m_len - 2));
- } else {
- m_len -= 33;
- *op++ = M3_MARKER | 0;
- goto m3_m4_len;
- }
- } else {
- m_off -= 0x4000;
- if (m_len <= M4_MAX_LEN) {
- *op++ = (M4_MARKER
- | ((m_off & 0x4000) >> 11)
+ m_off -= 0x4000;
+ if (m_len <= M4_MAX_LEN)
+ *op++ = (M4_MARKER | ((m_off >> 11) & 8)
| (m_len - 2));
- } else {
- m_len -= M4_MAX_LEN;
- *op++ = (M4_MARKER
- | ((m_off & 0x4000) >> 11));
-m3_m4_len:
- while (m_len > 255) {
- m_len -= 255;
- *op++ = 0;
- }
-
- *op++ = (m_len);
+ else {
+ m_len -= M4_MAX_LEN;
+ *op++ = (M4_MARKER | ((m_off >> 11) & 8));
+ while (unlikely(m_len > 255)) {
+ m_len -= 255;
+ *op++ = 0;
}
+ *op++ = (m_len);
}
-m3_m4_offset:
- *op++ = ((m_off & 63) << 2);
+ *op++ = (m_off << 2);
*op++ = (m_off >> 6);
}
-
- ii = ip;
- if (unlikely(ip >= ip_end))
- break;
+ goto next;
}
-
*out_len = op - out;
- return in_end - ii;
+ return in_end - (ii - ti);
}

-int lzo1x_1_compress(const unsigned char *in, size_t in_len, unsigned char *out,
- size_t *out_len, void *wrkmem)
+int lzo1x_1_compress(const unsigned char *in, size_t in_len,
+ unsigned char *out, size_t *out_len,
+ void *wrkmem)
{
- const unsigned char *ii;
+ const unsigned char *ip = in;
unsigned char *op = out;
- size_t t;
+ size_t l = in_len;
+ size_t t = 0;

- if (unlikely(in_len <= M2_MAX_LEN + 5)) {
- t = in_len;
- } else {
- t = _lzo1x_1_do_compress(in, in_len, op, out_len, wrkmem);
+ while (l > 20) {
+ size_t ll = l <= (M4_MAX_OFFSET + 1) ? l : (M4_MAX_OFFSET + 1);
+ uintptr_t ll_end = (uintptr_t) ip + ll;
+ if ((ll_end + ((t + ll) >> 5)) <= ll_end)
+ break;
+ BUILD_BUG_ON(D_SIZE * sizeof(lzo_dict_t) > LZO1X_1_MEM_COMPRESS);
+ memset(wrkmem, 0, D_SIZE * sizeof(lzo_dict_t));
+ t = lzo1x_1_do_compress(ip, ll, op, out_len, t, wrkmem);
+ ip += ll;
op += *out_len;
+ l -= ll;
}
+ t += l;

if (t > 0) {
- ii = in + in_len - t;
+ const unsigned char *ii = in + in_len - t;

if (op == out && t <= 238) {
*op++ = (17 + t);
@@ -198,16 +247,21 @@ int lzo1x_1_compress(const unsigned char
*op++ = (t - 3);
} else {
size_t tt = t - 18;
-
*op++ = 0;
while (tt > 255) {
tt -= 255;
*op++ = 0;
}
-
*op++ = tt;
}
- do {
+ if (t >= 16) do {
+ COPY8(op, ii);
+ COPY8(op + 8, ii + 8);
+ op += 16;
+ ii += 16;
+ t -= 16;
+ } while (t >= 16);
+ if (t > 0) do {
*op++ = *ii++;
} while (--t > 0);
}
@@ -223,4 +277,3 @@ EXPORT_SYMBOL_GPL(lzo1x_1_compress);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("LZO1X-1 Compressor");
-
--- a/lib/lzo/lzo1x_decompress_safe.c
+++ b/lib/lzo/lzo1x_decompress_safe.c
@@ -1,12 +1,12 @@
/*
- * LZO1X Decompressor from MiniLZO
+ * LZO1X Decompressor from LZO
*
- * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <[email protected]>
+ * Copyright (C) 1996-2012 Markus F.X.J. Oberhumer <[email protected]>
*
* The full LZO package can be found at:
* http://www.oberhumer.com/opensource/lzo/
*
- * Changed for kernel use by:
+ * Changed for Linux kernel use by:
* Nitin Gupta <[email protected]>
* Richard Purdie <[email protected]>
*/
@@ -15,225 +15,207 @@
#include <linux/module.h>
#include <linux/kernel.h>
#endif
-
#include <asm/unaligned.h>
#include <linux/lzo.h>
#include "lzodefs.h"

-#define HAVE_IP(x, ip_end, ip) ((size_t)(ip_end - ip) < (x))
-#define HAVE_OP(x, op_end, op) ((size_t)(op_end - op) < (x))
-#define HAVE_LB(m_pos, out, op) (m_pos < out || m_pos >= op)
-
-#define COPY4(dst, src) \
- put_unaligned(get_unaligned((const u32 *)(src)), (u32 *)(dst))
+#define HAVE_IP(x) ((size_t)(ip_end - ip) >= (size_t)(x))
+#define HAVE_OP(x) ((size_t)(op_end - op) >= (size_t)(x))
+#define NEED_IP(x) if (!HAVE_IP(x)) goto input_overrun
+#define NEED_OP(x) if (!HAVE_OP(x)) goto output_overrun
+#define TEST_LB(m_pos) if ((m_pos) < out) goto lookbehind_overrun

int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
- unsigned char *out, size_t *out_len)
+ unsigned char *out, size_t *out_len)
{
+ unsigned char *op;
+ const unsigned char *ip;
+ size_t t, next;
+ size_t state = 0;
+ const unsigned char *m_pos;
const unsigned char * const ip_end = in + in_len;
unsigned char * const op_end = out + *out_len;
- const unsigned char *ip = in, *m_pos;
- unsigned char *op = out;
- size_t t;

- *out_len = 0;
+ op = out;
+ ip = in;

+ if (unlikely(in_len < 3))
+ goto input_overrun;
if (*ip > 17) {
t = *ip++ - 17;
- if (t < 4)
+ if (t < 4) {
+ next = t;
goto match_next;
- if (HAVE_OP(t, op_end, op))
- goto output_overrun;
- if (HAVE_IP(t + 1, ip_end, ip))
- goto input_overrun;
- do {
- *op++ = *ip++;
- } while (--t > 0);
- goto first_literal_run;
- }
-
- while ((ip < ip_end)) {
- t = *ip++;
- if (t >= 16)
- goto match;
- if (t == 0) {
- if (HAVE_IP(1, ip_end, ip))
- goto input_overrun;
- while (*ip == 0) {
- t += 255;
- ip++;
- if (HAVE_IP(1, ip_end, ip))
- goto input_overrun;
- }
- t += 15 + *ip++;
- }
- if (HAVE_OP(t + 3, op_end, op))
- goto output_overrun;
- if (HAVE_IP(t + 4, ip_end, ip))
- goto input_overrun;
-
- COPY4(op, ip);
- op += 4;
- ip += 4;
- if (--t > 0) {
- if (t >= 4) {
- do {
- COPY4(op, ip);
- op += 4;
- ip += 4;
- t -= 4;
- } while (t >= 4);
- if (t > 0) {
- do {
- *op++ = *ip++;
- } while (--t > 0);
- }
- } else {
- do {
- *op++ = *ip++;
- } while (--t > 0);
- }
}
+ goto copy_literal_run;
+ }

-first_literal_run:
+ for (;;) {
t = *ip++;
- if (t >= 16)
- goto match;
- m_pos = op - (1 + M2_MAX_OFFSET);
- m_pos -= t >> 2;
- m_pos -= *ip++ << 2;
-
- if (HAVE_LB(m_pos, out, op))
- goto lookbehind_overrun;
-
- if (HAVE_OP(3, op_end, op))
- goto output_overrun;
- *op++ = *m_pos++;
- *op++ = *m_pos++;
- *op++ = *m_pos;
-
- goto match_done;
-
- do {
-match:
- if (t >= 64) {
- m_pos = op - 1;
- m_pos -= (t >> 2) & 7;
- m_pos -= *ip++ << 3;
- t = (t >> 5) - 1;
- if (HAVE_LB(m_pos, out, op))
- goto lookbehind_overrun;
- if (HAVE_OP(t + 3 - 1, op_end, op))
- goto output_overrun;
- goto copy_match;
- } else if (t >= 32) {
- t &= 31;
- if (t == 0) {
- if (HAVE_IP(1, ip_end, ip))
- goto input_overrun;
- while (*ip == 0) {
+ if (t < 16) {
+ if (likely(state == 0)) {
+ if (unlikely(t == 0)) {
+ while (unlikely(*ip == 0)) {
t += 255;
ip++;
- if (HAVE_IP(1, ip_end, ip))
- goto input_overrun;
+ NEED_IP(1);
}
- t += 31 + *ip++;
+ t += 15 + *ip++;
}
- m_pos = op - 1;
- m_pos -= get_unaligned_le16(ip) >> 2;
- ip += 2;
- } else if (t >= 16) {
- m_pos = op;
- m_pos -= (t & 8) << 11;
-
- t &= 7;
- if (t == 0) {
- if (HAVE_IP(1, ip_end, ip))
- goto input_overrun;
- while (*ip == 0) {
- t += 255;
- ip++;
- if (HAVE_IP(1, ip_end, ip))
- goto input_overrun;
- }
- t += 7 + *ip++;
+ t += 3;
+copy_literal_run:
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+ if (likely(HAVE_IP(t + 15) && HAVE_OP(t + 15))) {
+ const unsigned char *ie = ip + t;
+ unsigned char *oe = op + t;
+ do {
+ COPY8(op, ip);
+ op += 8;
+ ip += 8;
+ COPY8(op, ip);
+ op += 8;
+ ip += 8;
+ } while (ip < ie);
+ ip = ie;
+ op = oe;
+ } else
+#endif
+ {
+ NEED_OP(t);
+ NEED_IP(t + 3);
+ do {
+ *op++ = *ip++;
+ } while (--t > 0);
}
- m_pos -= get_unaligned_le16(ip) >> 2;
- ip += 2;
- if (m_pos == op)
- goto eof_found;
- m_pos -= 0x4000;
- } else {
+ state = 4;
+ continue;
+ } else if (state != 4) {
+ next = t & 3;
m_pos = op - 1;
m_pos -= t >> 2;
m_pos -= *ip++ << 2;
-
- if (HAVE_LB(m_pos, out, op))
- goto lookbehind_overrun;
- if (HAVE_OP(2, op_end, op))
- goto output_overrun;
-
- *op++ = *m_pos++;
- *op++ = *m_pos;
- goto match_done;
+ TEST_LB(m_pos);
+ NEED_OP(2);
+ op[0] = m_pos[0];
+ op[1] = m_pos[1];
+ op += 2;
+ goto match_next;
+ } else {
+ next = t & 3;
+ m_pos = op - (1 + M2_MAX_OFFSET);
+ m_pos -= t >> 2;
+ m_pos -= *ip++ << 2;
+ t = 3;
}
-
- if (HAVE_LB(m_pos, out, op))
- goto lookbehind_overrun;
- if (HAVE_OP(t + 3 - 1, op_end, op))
- goto output_overrun;
-
- if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) {
- COPY4(op, m_pos);
- op += 4;
- m_pos += 4;
- t -= 4 - (3 - 1);
+ } else if (t >= 64) {
+ next = t & 3;
+ m_pos = op - 1;
+ m_pos -= (t >> 2) & 7;
+ m_pos -= *ip++ << 3;
+ t = (t >> 5) - 1 + (3 - 1);
+ } else if (t >= 32) {
+ t = (t & 31) + (3 - 1);
+ if (unlikely(t == 2)) {
+ while (unlikely(*ip == 0)) {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 31 + *ip++;
+ NEED_IP(2);
+ }
+ m_pos = op - 1;
+ next = get_unaligned_le16(ip);
+ ip += 2;
+ m_pos -= next >> 2;
+ next &= 3;
+ } else {
+ m_pos = op;
+ m_pos -= (t & 8) << 11;
+ t = (t & 7) + (3 - 1);
+ if (unlikely(t == 2)) {
+ while (unlikely(*ip == 0)) {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 7 + *ip++;
+ NEED_IP(2);
+ }
+ next = get_unaligned_le16(ip);
+ ip += 2;
+ m_pos -= next >> 2;
+ next &= 3;
+ if (m_pos == op)
+ goto eof_found;
+ m_pos -= 0x4000;
+ }
+ TEST_LB(m_pos);
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+ if (op - m_pos >= 8) {
+ unsigned char *oe = op + t;
+ if (likely(HAVE_OP(t + 15))) {
do {
- COPY4(op, m_pos);
- op += 4;
- m_pos += 4;
- t -= 4;
- } while (t >= 4);
- if (t > 0)
- do {
- *op++ = *m_pos++;
- } while (--t > 0);
+ COPY8(op, m_pos);
+ op += 8;
+ m_pos += 8;
+ COPY8(op, m_pos);
+ op += 8;
+ m_pos += 8;
+ } while (op < oe);
+ op = oe;
+ if (HAVE_IP(6)) {
+ state = next;
+ COPY4(op, ip);
+ op += next;
+ ip += next;
+ continue;
+ }
} else {
-copy_match:
- *op++ = *m_pos++;
- *op++ = *m_pos++;
+ NEED_OP(t);
do {
*op++ = *m_pos++;
- } while (--t > 0);
+ } while (op < oe);
}
-match_done:
- t = ip[-2] & 3;
- if (t == 0)
- break;
+ } else
+#endif
+ {
+ unsigned char *oe = op + t;
+ NEED_OP(t);
+ op[0] = m_pos[0];
+ op[1] = m_pos[1];
+ op += 2;
+ m_pos += 2;
+ do {
+ *op++ = *m_pos++;
+ } while (op < oe);
+ }
match_next:
- if (HAVE_OP(t, op_end, op))
- goto output_overrun;
- if (HAVE_IP(t + 1, ip_end, ip))
- goto input_overrun;
-
- *op++ = *ip++;
- if (t > 1) {
+ state = next;
+ t = next;
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+ if (likely(HAVE_IP(6) && HAVE_OP(4))) {
+ COPY4(op, ip);
+ op += t;
+ ip += t;
+ } else
+#endif
+ {
+ NEED_IP(t + 3);
+ NEED_OP(t);
+ while (t > 0) {
*op++ = *ip++;
- if (t > 2)
- *op++ = *ip++;
+ t--;
}
-
- t = *ip++;
- } while (ip < ip_end);
+ }
}

- *out_len = op - out;
- return LZO_E_EOF_NOT_FOUND;
-
eof_found:
*out_len = op - out;
- return (ip == ip_end ? LZO_E_OK :
- (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
+ return (t != 3 ? LZO_E_ERROR :
+ ip == ip_end ? LZO_E_OK :
+ ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN);
+
input_overrun:
*out_len = op - out;
return LZO_E_INPUT_OVERRUN;
--- a/lib/lzo/lzodefs.h
+++ b/lib/lzo/lzodefs.h
@@ -1,19 +1,37 @@
/*
* lzodefs.h -- architecture, OS and compiler specific defines
*
- * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <[email protected]>
+ * Copyright (C) 1996-2012 Markus F.X.J. Oberhumer <[email protected]>
*
* The full LZO package can be found at:
* http://www.oberhumer.com/opensource/lzo/
*
- * Changed for kernel use by:
+ * Changed for Linux kernel use by:
* Nitin Gupta <[email protected]>
* Richard Purdie <[email protected]>
*/

-#define LZO_VERSION 0x2020
-#define LZO_VERSION_STRING "2.02"
-#define LZO_VERSION_DATE "Oct 17 2005"
+
+#define COPY4(dst, src) \
+ put_unaligned(get_unaligned((const u32 *)(src)), (u32 *)(dst))
+#if defined(__x86_64__)
+#define COPY8(dst, src) \
+ put_unaligned(get_unaligned((const u64 *)(src)), (u64 *)(dst))
+#else
+#define COPY8(dst, src) \
+ COPY4(dst, src); COPY4((dst) + 4, (src) + 4)
+#endif
+
+#if defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN)
+#error "conflicting endian definitions"
+#elif defined(__x86_64__)
+#define LZO_USE_CTZ64 1
+#define LZO_USE_CTZ32 1
+#elif defined(__i386__) || defined(__powerpc__)
+#define LZO_USE_CTZ32 1
+#elif defined(__arm__) && (__LINUX_ARM_ARCH__ >= 5)
+#define LZO_USE_CTZ32 1
+#endif

#define M1_MAX_OFFSET 0x0400
#define M2_MAX_OFFSET 0x0800
@@ -34,10 +52,8 @@
#define M3_MARKER 32
#define M4_MARKER 16

-#define D_BITS 14
-#define D_MASK ((1u << D_BITS) - 1)
+#define lzo_dict_t unsigned short
+#define D_BITS 13
+#define D_SIZE (1u << D_BITS)
+#define D_MASK (D_SIZE - 1)
#define D_HIGH ((D_MASK >> 1) + 1)
-
-#define DX2(p, s1, s2) (((((size_t)((p)[2]) << (s2)) ^ (p)[1]) \
- << (s1)) ^ (p)[0])
-#define DX3(p, s1, s2, s3) ((DX2((p)+1, s2, s3) << (s1)) ^ (p)[0])

2014-07-08 19:34:11

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 022/125] IB/qib: Fix port in pkey change event

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Mike Marciniszyn <[email protected]>

commit 911eccd284d13d78c92ec4f1f1092c03457d732a upstream.

The code used a literal 1 in dispatching an IB_EVENT_PKEY_CHANGE.

As of the dual port qib QDR card, this is not necessarily correct.

Change to use the port as specified in the call.

Reported-by: Alex Estrin <[email protected]>
Reviewed-by: Dennis Dalessandro <[email protected]>
Signed-off-by: Mike Marciniszyn <[email protected]>
Signed-off-by: Roland Dreier <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/infiniband/hw/qib/qib_mad.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/infiniband/hw/qib/qib_mad.c
+++ b/drivers/infiniband/hw/qib/qib_mad.c
@@ -1007,7 +1007,7 @@ static int set_pkeys(struct qib_devdata

event.event = IB_EVENT_PKEY_CHANGE;
event.device = &dd->verbs_dev.ibdev;
- event.element.port_num = 1;
+ event.element.port_num = port;
ib_dispatch_event(&event);
}
return 0;

2014-07-08 19:34:26

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 039/125] USB: io_ti: fix firmware download on big-endian machines (part 2)

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit c03890ff5e24a4bf59059f2d179f427559b7330a upstream.

A recent patch that purported to fix firmware download on big-endian
machines failed to add the corresponding sparse annotation to the
i2c-header. This was reported by the kbuild test robot.

Adding the appropriate annotation revealed another endianess bug related
to the i2c-header Size-field in a code path that is exercised when the
firmware is actually being downloaded (and not just verified and left
untouched unless older than the firmware at hand).

This patch adds the required sparse annotation to the i2c-header and
makes sure that the Size-field is sent in little-endian byte order
during firmware download also on big-endian machines.

Note that this patch is only compile-tested, but that there is no
functional change for little-endian systems.

Reported-by: kbuild test robot <[email protected]>
Cc: Ludovic Drolez <[email protected]>
Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/io_ti.c | 2 +-
drivers/usb/serial/io_usbvend.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -923,7 +923,7 @@ static int build_i2c_fw_hdr(__u8 *header
firmware_rec = (struct ti_i2c_firmware_rec*)i2c_header->Data;

i2c_header->Type = I2C_DESC_TYPE_FIRMWARE_BLANK;
- i2c_header->Size = (__u16)buffer_size;
+ i2c_header->Size = cpu_to_le16(buffer_size);
i2c_header->CheckSum = cs;
firmware_rec->Ver_Major = OperationalMajorVersion;
firmware_rec->Ver_Minor = OperationalMinorVersion;
--- a/drivers/usb/serial/io_usbvend.h
+++ b/drivers/usb/serial/io_usbvend.h
@@ -594,7 +594,7 @@ struct edge_boot_descriptor {

struct ti_i2c_desc {
__u8 Type; // Type of descriptor
- __u16 Size; // Size of data only not including header
+ __le16 Size; // Size of data only not including header
__u8 CheckSum; // Checksum (8 bit sum of data only)
__u8 Data[0]; // Data starts here
} __attribute__((packed));

2014-07-08 19:34:19

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 021/125] ext4: fix wrong assert in ext4_mb_normalize_request()

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Maurizio Lombardi <[email protected]>

commit b5b60778558cafad17bbcbf63e0310bd3c68eb17 upstream.

The variable "size" is expressed as number of blocks and not as
number of clusters, this could trigger a kernel panic when using
ext4 with the size of a cluster different from the size of a block.

Signed-off-by: Maurizio Lombardi <[email protected]>
Signed-off-by: Theodore Ts'o <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/ext4/mballoc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -3067,7 +3067,7 @@ ext4_mb_normalize_request(struct ext4_al
}
BUG_ON(start + size <= ac->ac_o_ex.fe_logical &&
start > ac->ac_o_ex.fe_logical);
- BUG_ON(size <= 0 || size > EXT4_CLUSTERS_PER_GROUP(ac->ac_sb));
+ BUG_ON(size <= 0 || size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb));

/* now prepare goal request */

2014-07-08 19:34:34

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 030/125] USB: usb_wwan: fix race between write and resume

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: xiao jin <[email protected]>

commit d9e93c08d8d985e5ef89436ebc9f4aad7e31559f upstream.

We find a race between write and resume. usb_wwan_resume run play_delayed()
and spin_unlock, but intfdata->suspended still is not set to zero.
At this time usb_wwan_write is called and anchor the urb to delay
list. Then resume keep running but the delayed urb have no chance
to be commit until next resume. If the time of next resume is far
away, tty will be blocked in tty_wait_until_sent during time. The
race also can lead to writes being reordered.

This patch put play_Delayed and intfdata->suspended together in the
spinlock, it's to avoid the write race during resume.

Fixes: 383cedc3bb43 ("USB: serial: full autosuspend support for the
option driver")

Signed-off-by: xiao jin <[email protected]>
Signed-off-by: Zhang, Qi1 <[email protected]>
Reviewed-by: David Cohen <[email protected]>
Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[bwh: Backported to 3.2: there's no need to check for portdata == NULL]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/usb_wwan.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)

--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -731,17 +731,15 @@ int usb_wwan_resume(struct usb_serial *s
}
}

+ spin_lock_irq(&intfdata->susp_lock);
for (i = 0; i < serial->num_ports; i++) {
/* walk all ports */
port = serial->port[i];
portdata = usb_get_serial_port_data(port);

/* skip closed ports */
- spin_lock_irq(&intfdata->susp_lock);
- if (!portdata->opened) {
- spin_unlock_irq(&intfdata->susp_lock);
+ if (!portdata->opened)
continue;
- }

for (j = 0; j < N_IN_URB; j++) {
urb = portdata->in_urbs[j];
@@ -754,9 +752,7 @@ int usb_wwan_resume(struct usb_serial *s
}
}
play_delayed(port);
- spin_unlock_irq(&intfdata->susp_lock);
}
- spin_lock_irq(&intfdata->susp_lock);
intfdata->suspended = 0;
spin_unlock_irq(&intfdata->susp_lock);
err_out:

2014-07-08 19:34:30

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 051/125] RDMA/cxgb4: Add missing padding at end of struct c4iw_create_cq_resp

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Yann Droneaud <[email protected]>

commit b6f04d3d21458818073a2f5af5339f958864bf71 upstream.

The i386 ABI disagrees with most other ABIs regarding alignment of
data types larger than 4 bytes: on most ABIs a padding must be added
at end of the structures, while it is not required on i386.

So for most ABI struct c4iw_create_cq_resp gets implicitly padded
to be aligned on a 8 bytes multiple, while for i386, such padding
is not added.

The tool pahole can be used to find such implicit padding:

$ pahole --anon_include \
--nested_anon_include \
--recursive \
--class_name c4iw_create_cq_resp \
drivers/infiniband/hw/cxgb4/iw_cxgb4.o

Then, structure layout can be compared between i386 and x86_64:

# +++ obj-i386/drivers/infiniband/hw/cxgb4/iw_cxgb4.o.pahole.txt 2014-03-28 11:43:05.547432195 +0100
# --- obj-x86_64/drivers/infiniband/hw/cxgb4/iw_cxgb4.o.pahole.txt 2014-03-28 10:55:10.990133017 +0100
@@ -14,9 +13,8 @@ struct c4iw_create_cq_resp {
__u32 size; /* 28 4 */
__u32 qid_mask; /* 32 4 */

- /* size: 36, cachelines: 1, members: 6 */
- /* last cacheline: 36 bytes */
+ /* size: 40, cachelines: 1, members: 6 */
+ /* padding: 4 */
+ /* last cacheline: 40 bytes */
};

This ABI disagreement will make an x86_64 kernel try to write past the
buffer provided by an i386 binary.

When boundary check will be implemented, the x86_64 kernel will refuse
to write past the i386 userspace provided buffer and the uverbs will
fail.

If the structure is on a page boundary and the next page is not
mapped, ib_copy_to_udata() will fail and the uverb will fail.

This patch adds an explicit padding at end of structure
c4iw_create_cq_resp, and, like 92b0ca7cb149 ("IB/mlx5: Fix stack info
leak in mlx5_ib_alloc_ucontext()"), makes function c4iw_create_cq()
not writting this padding field to userspace. This way, x86_64 kernel
will be able to write struct c4iw_create_cq_resp as expected by
unpatched and patched i386 libcxgb4.

Link: http://marc.info/[email protected]
Fixes: cfdda9d764362 ("RDMA/cxgb4: Add driver for Chelsio T4 RNIC")
Fixes: e24a72a3302a6 ("RDMA/cxgb4: Fix four byte info leak in c4iw_create_cq()")
Cc: Dan Carpenter <[email protected]>
Signed-off-by: Yann Droneaud <[email protected]>
Acked-by: Steve Wise <[email protected]>
Signed-off-by: Roland Dreier <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/infiniband/hw/cxgb4/cq.c | 4 ++--
drivers/infiniband/hw/cxgb4/user.h | 1 +
2 files changed, 3 insertions(+), 2 deletions(-)

--- a/drivers/infiniband/hw/cxgb4/cq.c
+++ b/drivers/infiniband/hw/cxgb4/cq.c
@@ -833,7 +833,6 @@ struct ib_cq *c4iw_create_cq(struct ib_d
if (!mm2)
goto err4;

- memset(&uresp, 0, sizeof(uresp));
uresp.qid_mask = rhp->rdev.cqmask;
uresp.cqid = chp->cq.cqid;
uresp.size = chp->cq.size;
@@ -844,7 +843,8 @@ struct ib_cq *c4iw_create_cq(struct ib_d
uresp.gts_key = ucontext->key;
ucontext->key += PAGE_SIZE;
spin_unlock(&ucontext->mmap_lock);
- ret = ib_copy_to_udata(udata, &uresp, sizeof uresp);
+ ret = ib_copy_to_udata(udata, &uresp,
+ sizeof(uresp) - sizeof(uresp.reserved));
if (ret)
goto err5;

--- a/drivers/infiniband/hw/cxgb4/user.h
+++ b/drivers/infiniband/hw/cxgb4/user.h
@@ -48,6 +48,7 @@ struct c4iw_create_cq_resp {
__u32 cqid;
__u32 size;
__u32 qid_mask;
+ __u32 reserved; /* explicit padding (optional for i386) */
};


2014-07-08 19:34:51

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 024/125] USB: sierra: fix AA deadlock in open error path

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 353fe198602e8b4d1c7bdcceb8e60955087201b1 upstream.

Fix AA deadlock in open error path that would call close() and try to
grab the already held disc_mutex.

Fixes: b9a44bc19f48 ("sierra: driver urb handling improvements")

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/sierra.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)

--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -868,14 +868,9 @@ static int sierra_open(struct tty_struct
usb_sndbulkpipe(serial->dev, endpoint) | USB_DIR_IN);

err = sierra_submit_rx_urbs(port, GFP_KERNEL);
- if (err) {
- /* get rid of everything as in close */
- sierra_close(port);
- /* restore balance for autopm */
- if (!serial->disconnected)
- usb_autopm_put_interface(serial->interface);
- return err;
- }
+ if (err)
+ goto err_submit;
+
sierra_send_setup(port);

serial->interface->needs_remote_wakeup = 1;
@@ -885,6 +880,16 @@ static int sierra_open(struct tty_struct
usb_autopm_put_interface(serial->interface);

return 0;
+
+err_submit:
+ sierra_stop_rx_urbs(port);
+
+ for (i = 0; i < portdata->num_in_urbs; i++) {
+ sierra_release_urb(portdata->in_urbs[i]);
+ portdata->in_urbs[i] = NULL;
+ }
+
+ return err;
}


2014-07-08 19:35:15

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 047/125] rtmutex: Fix deadlock detector for real

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Thomas Gleixner <[email protected]>

commit 397335f004f41e5fcf7a795e94eb3ab83411a17c upstream.

The current deadlock detection logic does not work reliably due to the
following early exit path:

/*
* Drop out, when the task has no waiters. Note,
* top_waiter can be NULL, when we are in the deboosting
* mode!
*/
if (top_waiter && (!task_has_pi_waiters(task) ||
top_waiter != task_top_pi_waiter(task)))
goto out_unlock_pi;

So this not only exits when the task has no waiters, it also exits
unconditionally when the current waiter is not the top priority waiter
of the task.

So in a nested locking scenario, it might abort the lock chain walk
and therefor miss a potential deadlock.

Simple fix: Continue the chain walk, when deadlock detection is
enabled.

We also avoid the whole enqueue, if we detect the deadlock right away
(A-A). It's an optimization, but also prevents that another waiter who
comes in after the detection and before the task has undone the damage
observes the situation and detects the deadlock and returns
-EDEADLOCK, which is wrong as the other task is not in a deadlock
situation.

Signed-off-by: Thomas Gleixner <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Reviewed-by: Steven Rostedt <[email protected]>
Cc: Lai Jiangshan <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
[bwh: Backported to 3.2: adjust filename]
Signed-off-by: Ben Hutchings <[email protected]>
---
kernel/rtmutex.c | 32 ++++++++++++++++++++++++++++----
1 file changed, 28 insertions(+), 4 deletions(-)

--- a/kernel/rtmutex.c
+++ b/kernel/rtmutex.c
@@ -211,9 +211,16 @@ static int rt_mutex_adjust_prio_chain(st
* top_waiter can be NULL, when we are in the deboosting
* mode!
*/
- if (top_waiter && (!task_has_pi_waiters(task) ||
- top_waiter != task_top_pi_waiter(task)))
- goto out_unlock_pi;
+ if (top_waiter) {
+ if (!task_has_pi_waiters(task))
+ goto out_unlock_pi;
+ /*
+ * If deadlock detection is off, we stop here if we
+ * are not the top pi waiter of the task.
+ */
+ if (!detect_deadlock && top_waiter != task_top_pi_waiter(task))
+ goto out_unlock_pi;
+ }

/*
* When deadlock detection is off then we check, if further
@@ -229,7 +236,12 @@ static int rt_mutex_adjust_prio_chain(st
goto retry;
}

- /* Deadlock detection */
+ /*
+ * Deadlock detection. If the lock is the same as the original
+ * lock which caused us to walk the lock chain or if the
+ * current lock is owned by the task which initiated the chain
+ * walk, we detected a deadlock.
+ */
if (lock == orig_lock || rt_mutex_owner(lock) == top_task) {
debug_rt_mutex_deadlock(deadlock_detect, orig_waiter, lock);
raw_spin_unlock(&lock->wait_lock);
@@ -398,6 +410,18 @@ static int task_blocks_on_rt_mutex(struc
unsigned long flags;
int chain_walk = 0, res;

+ /*
+ * Early deadlock detection. We really don't want the task to
+ * enqueue on itself just to untangle the mess later. It's not
+ * only an optimization. We drop the locks, so another waiter
+ * can come in before the chain walk detects the deadlock. So
+ * the other will detect the deadlock and return -EDEADLOCK,
+ * which is wrong, as the other waiter is not in a deadlock
+ * situation.
+ */
+ if (detect_deadlock && owner == task)
+ return -EDEADLK;
+
raw_spin_lock_irqsave(&task->pi_lock, flags);
__rt_mutex_adjust_prio(task);
waiter->task = task;

2014-07-08 19:36:04

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 037/125] USB: cdc-acm: fix runtime PM for control messages

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit bae3f4c53585e9a170da9436e0f06919874bda9a upstream.

Fix runtime PM handling of control messages by adding the required PM
counter operations.

Fixes: 11ea859d64b6 ("USB: additional power savings for cdc-acm devices
that support remote wakeup")

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/class/cdc-acm.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -72,13 +72,23 @@ static const struct tty_port_operations
static int acm_ctrl_msg(struct acm *acm, int request, int value,
void *buf, int len)
{
- int retval = usb_control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0),
+ int retval;
+
+ retval = usb_autopm_get_interface(acm->control);
+ if (retval)
+ return retval;
+
+ retval = usb_control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0),
request, USB_RT_ACM, value,
acm->control->altsetting[0].desc.bInterfaceNumber,
buf, len, 5000);
+
dev_dbg(&acm->control->dev,
"%s - rq 0x%02x, val %#x, len %#x, result %d\n",
__func__, request, value, len, retval);
+
+ usb_autopm_put_interface(acm->control);
+
return retval < 0 ? retval : 0;
}

2014-07-08 19:36:35

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 075/125] powerpc: Don't setup CPUs with bad status

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Michael Neuling <[email protected]>

commit 59a53afe70fd530040bdc69581f03d880157f15a upstream.

OPAL will mark a CPU that is guarded as "bad" in the status property of the CPU
node.

Unfortunatley Linux doesn't check this property and will put the bad CPU in the
present map. This has caused hangs on booting when we try to unsplit the core.

This patch checks the CPU is avaliable via this status property before putting
it in the present map.

Signed-off-by: Michael Neuling <[email protected]>
Tested-by: Anton Blanchard <[email protected]>
Signed-off-by: Benjamin Herrenschmidt <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/powerpc/kernel/setup-common.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -449,7 +449,7 @@ void __init smp_setup_cpu_maps(void)
for (j = 0; j < nthreads && cpu < nr_cpu_ids; j++) {
DBG(" thread %d -> cpu %d (hard id %d)\n",
j, cpu, intserv[j]);
- set_cpu_present(cpu, true);
+ set_cpu_present(cpu, of_device_is_available(dn));
set_hard_smp_processor_id(cpu, intserv[j]);
set_cpu_possible(cpu, true);
cpu++;

2014-07-08 19:34:23

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 019/125] ahci: add PCI ID for Marvell 88SE91A0 SATA Controller

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Andreas Schrägle <[email protected]>

commit 754a292fe6b08196cb135c03b404444e17de520a upstream.

Add support for Marvell Technology Group Ltd. 88SE91A0 SATA 6Gb/s
Controller by adding its PCI ID.

Signed-off-by: Andreas Schrägle <[email protected]>
Signed-off-by: Tejun Heo <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/ata/ahci.c | 2 ++
1 file changed, 2 insertions(+)

--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -452,6 +452,8 @@ static const struct pci_device_id ahci_p
.driver_data = board_ahci_yes_fbs }, /* 88se9172 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9192),
.driver_data = board_ahci_yes_fbs }, /* 88se9172 on some Gigabyte */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a0),
+ .driver_data = board_ahci_yes_fbs },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a3),
.driver_data = board_ahci_yes_fbs },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9230),

2014-07-08 19:36:56

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 023/125] IB/ipath: Translate legacy diagpkt into newer extended diagpkt

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Dennis Dalessandro <[email protected]>

commit 7e6d3e5c70f13874fb06e6b67696ed90ce79bd48 upstream.

This patch addresses an issue where the legacy diagpacket is sent in
from the user, but the driver operates on only the extended
diagpkt. This patch specifically initializes the extended diagpkt
based on the legacy packet.

Reported-by: Rickard Strandqvist <[email protected]>
Reviewed-by: Mike Marciniszyn <[email protected]>
Signed-off-by: Dennis Dalessandro <[email protected]>
Signed-off-by: Roland Dreier <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/infiniband/hw/ipath/ipath_diag.c | 4 ++++
1 file changed, 4 insertions(+)

--- a/drivers/infiniband/hw/ipath/ipath_diag.c
+++ b/drivers/infiniband/hw/ipath/ipath_diag.c
@@ -346,6 +346,10 @@ static ssize_t ipath_diagpkt_write(struc
ret = -EFAULT;
goto bail;
}
+ dp.len = odp.len;
+ dp.unit = odp.unit;
+ dp.data = odp.data;
+ dp.pbc_wd = 0;
} else {
ret = -EINVAL;
goto bail;

2014-07-08 19:37:29

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 050/125] RDMA/cxgb4: Fix four byte info leak in c4iw_create_cq()

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Dan Carpenter <[email protected]>

commit e24a72a3302a638d4c6e77f0b40c45cc61c3f089 upstream.

There is a four byte hole at the end of the "uresp" struct after the
->qid_mask member.

Signed-off-by: Dan Carpenter <[email protected]>
Signed-off-by: Roland Dreier <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/infiniband/hw/cxgb4/cq.c | 1 +
1 file changed, 1 insertion(+)

--- a/drivers/infiniband/hw/cxgb4/cq.c
+++ b/drivers/infiniband/hw/cxgb4/cq.c
@@ -833,6 +833,7 @@ struct ib_cq *c4iw_create_cq(struct ib_d
if (!mm2)
goto err4;

+ memset(&uresp, 0, sizeof(uresp));
uresp.qid_mask = rhp->rdev.cqmask;
uresp.cqid = chp->cq.cqid;
uresp.size = chp->cq.size;

2014-07-08 19:37:54

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 020/125] ext4: fix zeroing of page during writeback

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Jan Kara <[email protected]>

commit eeece469dedadf3918bad50ad80f4616a0064e90 upstream.

Tail of a page straddling inode size must be zeroed when being written
out due to POSIX requirement that modifications of mmaped page beyond
inode size must not be written to the file. ext4_bio_write_page() did
this only for blocks fully beyond inode size but didn't properly zero
blocks partially beyond inode size. Fix this.

The problem has been uncovered by mmap_11-4 test in openposix test suite
(part of LTP).

Reported-by: Xiaoguang Wang <[email protected]>
Fixes: 5a0dc7365c240
Fixes: bd2d0210cf22f
Signed-off-by: Jan Kara <[email protected]>
Signed-off-by: Theodore Ts'o <[email protected]>
[bwh: Backported to 3.2:
- Adjust context
- block_end was used instead of block_start + blocksize]
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/ext4/page-io.c | 24 +++++++++++-------------
1 file changed, 11 insertions(+), 13 deletions(-)

--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -386,24 +386,24 @@ int ext4_bio_write_page(struct ext4_io_s
set_page_writeback(page);
ClearPageError(page);

+ /*
+ * Comments copied from block_write_full_page_endio:
+ *
+ * The page straddles i_size. It must be zeroed out on each and every
+ * writepage invocation because it may be mmapped. "A file is mapped
+ * in multiples of the page size. For a file that is not a multiple of
+ * the page size, the remaining memory is zeroed when mapped, and
+ * writes to that region are not written out to the file."
+ */
+ if (len < PAGE_CACHE_SIZE)
+ zero_user_segment(page, len, PAGE_CACHE_SIZE);
+
for (bh = head = page_buffers(page), block_start = 0;
bh != head || !block_start;
block_start = block_end, bh = bh->b_this_page) {

block_end = block_start + blocksize;
if (block_start >= len) {
- /*
- * Comments copied from block_write_full_page_endio:
- *
- * The page straddles i_size. It must be zeroed out on
- * each and every writepage invocation because it may
- * be mmapped. "A file is mapped in multiples of the
- * page size. For a file that is not a multiple of
- * the page size, the remaining memory is zeroed when
- * mapped, and writes to that region are not written
- * out to the file."
- */
- zero_user_segment(page, block_start, block_end);
clear_buffer_dirty(bh);
set_buffer_uptodate(bh);
continue;

2014-07-08 19:34:15

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 018/125] drm/i915: Only copy back the modified fields to userspace from execbuffer

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Chris Wilson <[email protected]>

commit 9aab8bff7aa3bee567213ad3c1fdfb217bb980a2 upstream.

We only want to modifiy a single field in the userspace view of the
execbuffer command buffer, so explicitly change that rather than copy
everything back again.

This serves two purposes:

1. The single fields are much cheaper to copy (constant size so the
copy uses special case code) and much smaller than the whole array.

2. We modify the array for internal use that need to be masked from
the user.

Note: We need this backported since without it the next bugfix will
blow up when userspace recycles batchbuffers and relocations.

Signed-off-by: Chris Wilson <[email protected]>
Cc: Daniel Vetter <[email protected]>
Signed-off-by: Daniel Vetter <[email protected]>
[bwh: Backported to 3.2: to_user_ptr() is open-coded]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/i915/i915_gem_execbuffer.c | 54 ++++++++++++++++++------------
1 file changed, 32 insertions(+), 22 deletions(-)

--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -679,9 +679,9 @@ i915_gem_execbuffer_relocate_slow(struct
* relocations were valid.
*/
for (j = 0; j < exec[i].relocation_count; j++) {
- if (copy_to_user(&user_relocs[j].presumed_offset,
- &invalid_offset,
- sizeof(invalid_offset))) {
+ if (__copy_to_user(&user_relocs[j].presumed_offset,
+ &invalid_offset,
+ sizeof(invalid_offset))) {
ret = -EFAULT;
mutex_lock(&dev->struct_mutex);
goto err;
@@ -1325,19 +1325,21 @@ i915_gem_execbuffer(struct drm_device *d

ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list);
if (!ret) {
+ struct drm_i915_gem_exec_object __user *user_exec_list =
+ (void __user *)(uintptr_t)args->buffers_ptr;
+
/* Copy the new buffer offsets back to the user's exec list. */
- for (i = 0; i < args->buffer_count; i++)
- exec_list[i].offset = exec2_list[i].offset;
- /* ... and back out to userspace */
- ret = copy_to_user((struct drm_i915_relocation_entry __user *)
- (uintptr_t) args->buffers_ptr,
- exec_list,
- sizeof(*exec_list) * args->buffer_count);
- if (ret) {
- ret = -EFAULT;
- DRM_DEBUG("failed to copy %d exec entries "
- "back to user (%d)\n",
- args->buffer_count, ret);
+ for (i = 0; i < args->buffer_count; i++) {
+ ret = __copy_to_user(&user_exec_list[i].offset,
+ &exec2_list[i].offset,
+ sizeof(user_exec_list[i].offset));
+ if (ret) {
+ ret = -EFAULT;
+ DRM_DEBUG("failed to copy %d exec entries "
+ "back to user (%d)\n",
+ args->buffer_count, ret);
+ break;
+ }
}
}

@@ -1384,15 +1386,21 @@ i915_gem_execbuffer2(struct drm_device *
ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list);
if (!ret) {
/* Copy the new buffer offsets back to the user's exec list. */
- ret = copy_to_user((struct drm_i915_relocation_entry __user *)
- (uintptr_t) args->buffers_ptr,
- exec2_list,
- sizeof(*exec2_list) * args->buffer_count);
- if (ret) {
- ret = -EFAULT;
- DRM_DEBUG("failed to copy %d exec entries "
- "back to user (%d)\n",
- args->buffer_count, ret);
+ struct drm_i915_gem_exec_object2 __user *user_exec_list =
+ (void __user *)(uintptr_t)args->buffers_ptr;
+ int i;
+
+ for (i = 0; i < args->buffer_count; i++) {
+ ret = __copy_to_user(&user_exec_list[i].offset,
+ &exec2_list[i].offset,
+ sizeof(user_exec_list[i].offset));
+ if (ret) {
+ ret = -EFAULT;
+ DRM_DEBUG("failed to copy %d exec entries "
+ "back to user\n",
+ args->buffer_count);
+ break;
+ }
}
}

2014-07-08 19:38:27

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 017/125] drm/i915: s/DRM_ERROR/DRM_DEBUG in i915_gem_execbuffer.c

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Daniel Vetter <[email protected]>

commit ff240199b6a3b0bec5ae9b6d26403dad38e8cb19 upstream.

These are all user-trigerable, so tune down their loudness a notch.
For some of these we have i-g-t tests (because they prevent
newly-discovered bugs), without this patches running the test suite
leaves behind a dirty dmesg.

Reviewed-by: Chris Wilson <[email protected]>
Signed-Off-by: Daniel Vetter <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/i915/i915_gem_execbuffer.c | 50 +++++++++++++++---------------
1 file changed, 25 insertions(+), 25 deletions(-)

--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -287,14 +287,14 @@ i915_gem_execbuffer_relocate_entry(struc
* exec_object list, so it should have a GTT space bound by now.
*/
if (unlikely(target_offset == 0)) {
- DRM_ERROR("No GTT space found for object %d\n",
+ DRM_DEBUG("No GTT space found for object %d\n",
reloc->target_handle);
return ret;
}

/* Validate that the target is in a valid r/w GPU domain */
if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) {
- DRM_ERROR("reloc with multiple write domains: "
+ DRM_DEBUG("reloc with multiple write domains: "
"obj %p target %d offset %d "
"read %08x write %08x",
obj, reloc->target_handle,
@@ -304,7 +304,7 @@ i915_gem_execbuffer_relocate_entry(struc
return ret;
}
if (unlikely((reloc->write_domain | reloc->read_domains) & I915_GEM_DOMAIN_CPU)) {
- DRM_ERROR("reloc with read/write CPU domains: "
+ DRM_DEBUG("reloc with read/write CPU domains: "
"obj %p target %d offset %d "
"read %08x write %08x",
obj, reloc->target_handle,
@@ -315,7 +315,7 @@ i915_gem_execbuffer_relocate_entry(struc
}
if (unlikely(reloc->write_domain && target_obj->pending_write_domain &&
reloc->write_domain != target_obj->pending_write_domain)) {
- DRM_ERROR("Write domain conflict: "
+ DRM_DEBUG("Write domain conflict: "
"obj %p target %d offset %d "
"new %08x old %08x\n",
obj, reloc->target_handle,
@@ -336,7 +336,7 @@ i915_gem_execbuffer_relocate_entry(struc

/* Check that the relocation address is valid... */
if (unlikely(reloc->offset > obj->base.size - 4)) {
- DRM_ERROR("Relocation beyond object bounds: "
+ DRM_DEBUG("Relocation beyond object bounds: "
"obj %p target %d offset %d size %d.\n",
obj, reloc->target_handle,
(int) reloc->offset,
@@ -344,7 +344,7 @@ i915_gem_execbuffer_relocate_entry(struc
return ret;
}
if (unlikely(reloc->offset & 3)) {
- DRM_ERROR("Relocation not 4-byte aligned: "
+ DRM_DEBUG("Relocation not 4-byte aligned: "
"obj %p target %d offset %d.\n",
obj, reloc->target_handle,
(int) reloc->offset);
@@ -704,7 +704,7 @@ i915_gem_execbuffer_relocate_slow(struct
obj = to_intel_bo(drm_gem_object_lookup(dev, file,
exec[i].handle));
if (&obj->base == NULL) {
- DRM_ERROR("Invalid object handle %d at index %d\n",
+ DRM_DEBUG("Invalid object handle %d at index %d\n",
exec[i].handle, i);
ret = -ENOENT;
goto err;
@@ -1015,7 +1015,7 @@ i915_gem_do_execbuffer(struct drm_device
int ret, mode, i;

if (!i915_gem_check_execbuffer(args)) {
- DRM_ERROR("execbuf with invalid offset/length\n");
+ DRM_DEBUG("execbuf with invalid offset/length\n");
return -EINVAL;
}

@@ -1030,20 +1030,20 @@ i915_gem_do_execbuffer(struct drm_device
break;
case I915_EXEC_BSD:
if (!HAS_BSD(dev)) {
- DRM_ERROR("execbuf with invalid ring (BSD)\n");
+ DRM_DEBUG("execbuf with invalid ring (BSD)\n");
return -EINVAL;
}
ring = &dev_priv->ring[VCS];
break;
case I915_EXEC_BLT:
if (!HAS_BLT(dev)) {
- DRM_ERROR("execbuf with invalid ring (BLT)\n");
+ DRM_DEBUG("execbuf with invalid ring (BLT)\n");
return -EINVAL;
}
ring = &dev_priv->ring[BCS];
break;
default:
- DRM_ERROR("execbuf with unknown ring: %d\n",
+ DRM_DEBUG("execbuf with unknown ring: %d\n",
(int)(args->flags & I915_EXEC_RING_MASK));
return -EINVAL;
}
@@ -1069,18 +1069,18 @@ i915_gem_do_execbuffer(struct drm_device
}
break;
default:
- DRM_ERROR("execbuf with unknown constants: %d\n", mode);
+ DRM_DEBUG("execbuf with unknown constants: %d\n", mode);
return -EINVAL;
}

if (args->buffer_count < 1) {
- DRM_ERROR("execbuf with %d buffers\n", args->buffer_count);
+ DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count);
return -EINVAL;
}

if (args->num_cliprects != 0) {
if (ring != &dev_priv->ring[RCS]) {
- DRM_ERROR("clip rectangles are only valid with the render ring\n");
+ DRM_DEBUG("clip rectangles are only valid with the render ring\n");
return -EINVAL;
}

@@ -1130,7 +1130,7 @@ i915_gem_do_execbuffer(struct drm_device
obj = to_intel_bo(drm_gem_object_lookup(dev, file,
exec[i].handle));
if (&obj->base == NULL) {
- DRM_ERROR("Invalid object handle %d at index %d\n",
+ DRM_DEBUG("Invalid object handle %d at index %d\n",
exec[i].handle, i);
/* prevent error path from reading uninitialized data */
ret = -ENOENT;
@@ -1138,7 +1138,7 @@ i915_gem_do_execbuffer(struct drm_device
}

if (!list_empty(&obj->exec_list)) {
- DRM_ERROR("Object %p [handle %d, index %d] appears more than once in object list\n",
+ DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n",
obj, exec[i].handle, i);
ret = -EINVAL;
goto err;
@@ -1176,7 +1176,7 @@ i915_gem_do_execbuffer(struct drm_device

/* Set the pending read domains for the batch buffer to COMMAND */
if (batch_obj->base.pending_write_domain) {
- DRM_ERROR("Attempting to use self-modifying batch buffer\n");
+ DRM_DEBUG("Attempting to use self-modifying batch buffer\n");
ret = -EINVAL;
goto err;
}
@@ -1275,7 +1275,7 @@ i915_gem_execbuffer(struct drm_device *d
int ret, i;

if (args->buffer_count < 1) {
- DRM_ERROR("execbuf with %d buffers\n", args->buffer_count);
+ DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count);
return -EINVAL;
}

@@ -1283,7 +1283,7 @@ i915_gem_execbuffer(struct drm_device *d
exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count);
exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count);
if (exec_list == NULL || exec2_list == NULL) {
- DRM_ERROR("Failed to allocate exec list for %d buffers\n",
+ DRM_DEBUG("Failed to allocate exec list for %d buffers\n",
args->buffer_count);
drm_free_large(exec_list);
drm_free_large(exec2_list);
@@ -1294,7 +1294,7 @@ i915_gem_execbuffer(struct drm_device *d
(uintptr_t) args->buffers_ptr,
sizeof(*exec_list) * args->buffer_count);
if (ret != 0) {
- DRM_ERROR("copy %d exec entries failed %d\n",
+ DRM_DEBUG("copy %d exec entries failed %d\n",
args->buffer_count, ret);
drm_free_large(exec_list);
drm_free_large(exec2_list);
@@ -1335,7 +1335,7 @@ i915_gem_execbuffer(struct drm_device *d
sizeof(*exec_list) * args->buffer_count);
if (ret) {
ret = -EFAULT;
- DRM_ERROR("failed to copy %d exec entries "
+ DRM_DEBUG("failed to copy %d exec entries "
"back to user (%d)\n",
args->buffer_count, ret);
}
@@ -1356,7 +1356,7 @@ i915_gem_execbuffer2(struct drm_device *

if (args->buffer_count < 1 ||
args->buffer_count > UINT_MAX / sizeof(*exec2_list)) {
- DRM_ERROR("execbuf2 with %d buffers\n", args->buffer_count);
+ DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count);
return -EINVAL;
}

@@ -1366,7 +1366,7 @@ i915_gem_execbuffer2(struct drm_device *
exec2_list = drm_malloc_ab(sizeof(*exec2_list),
args->buffer_count);
if (exec2_list == NULL) {
- DRM_ERROR("Failed to allocate exec list for %d buffers\n",
+ DRM_DEBUG("Failed to allocate exec list for %d buffers\n",
args->buffer_count);
return -ENOMEM;
}
@@ -1375,7 +1375,7 @@ i915_gem_execbuffer2(struct drm_device *
(uintptr_t) args->buffers_ptr,
sizeof(*exec2_list) * args->buffer_count);
if (ret != 0) {
- DRM_ERROR("copy %d exec entries failed %d\n",
+ DRM_DEBUG("copy %d exec entries failed %d\n",
args->buffer_count, ret);
drm_free_large(exec2_list);
return -EFAULT;
@@ -1390,7 +1390,7 @@ i915_gem_execbuffer2(struct drm_device *
sizeof(*exec2_list) * args->buffer_count);
if (ret) {
ret = -EFAULT;
- DRM_ERROR("failed to copy %d exec entries "
+ DRM_DEBUG("failed to copy %d exec entries "
"back to user (%d)\n",
args->buffer_count, ret);
}

2014-07-08 19:38:47

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 064/125] rtc: rtc-at91rm9200: fix infinite wait for ACKUPD irq

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Boris BREZILLON <[email protected]>

commit 2fe121e1f5aa3bf31b418a9790db6c400e922291 upstream.

The rtc user must wait at least 1 sec between each time/calandar update
(see atmel's datasheet chapter "Updating Time/Calendar").

Use the 1Hz interrupt to update the at91_rtc_upd_rdy flag and wait for
the at91_rtc_wait_upd_rdy event if the rtc is not ready.

This patch fixes a deadlock in an uninterruptible wait when the RTC is
updated more than once every second. AFAICT the bug is here from the
beginning, but I think we should at least backport this fix to 3.10 and
the following longterm and stable releases.

Signed-off-by: Boris BREZILLON <[email protected]>
Reported-by: Bryan Evenson <[email protected]>
Tested-by: Bryan Evenson <[email protected]>
Cc: Andrew Victor <[email protected]>
Cc: Nicolas Ferre <[email protected]>
Cc: Jean-Christophe Plagniol-Villard <[email protected]>
Cc: Alessandro Zummo <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
[bwh: Backported to 3.2:
- Adjust context
- at91_rtc_write() is called at91_sys_write()
- Use at91_sys_write() directly instead of the missing
at91_rtc_write_ier() and at91_rtc_write_idr()]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/rtc/rtc-at91rm9200.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)

--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -36,6 +36,7 @@
#define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */

static DECLARE_COMPLETION(at91_rtc_updated);
+static DECLARE_COMPLETION(at91_rtc_upd_rdy);
static unsigned int at91_alarm_year = AT91_RTC_EPOCH;

/*
@@ -97,6 +98,8 @@ static int at91_rtc_settime(struct devic
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);

+ wait_for_completion(&at91_rtc_upd_rdy);
+
/* Stop Time/Calendar from counting */
cr = at91_sys_read(AT91_RTC_CR);
at91_sys_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM);
@@ -119,7 +122,9 @@ static int at91_rtc_settime(struct devic

/* Restart Time/Calendar */
cr = at91_sys_read(AT91_RTC_CR);
+ at91_sys_write(AT91_RTC_SCCR, AT91_RTC_SECEV);
at91_sys_write(AT91_RTC_CR, cr & ~(AT91_RTC_UPDCAL | AT91_RTC_UPDTIM));
+ at91_sys_write(AT91_RTC_IER, AT91_RTC_SECEV);

return 0;
}
@@ -226,8 +231,10 @@ static irqreturn_t at91_rtc_interrupt(in
if (rtsr) { /* this interrupt is shared! Is it ours? */
if (rtsr & AT91_RTC_ALARM)
events |= (RTC_AF | RTC_IRQF);
- if (rtsr & AT91_RTC_SECEV)
- events |= (RTC_UF | RTC_IRQF);
+ if (rtsr & AT91_RTC_SECEV) {
+ complete(&at91_rtc_upd_rdy);
+ at91_sys_write(AT91_RTC_IDR, AT91_RTC_SECEV);
+ }
if (rtsr & AT91_RTC_ACKUPD)
complete(&at91_rtc_updated);

@@ -291,6 +298,11 @@ static int __init at91_rtc_probe(struct
}
platform_set_drvdata(pdev, rtc);

+ /* enable SECEV interrupt in order to initialize at91_rtc_upd_rdy
+ * completion.
+ */
+ at91_sys_write(AT91_RTC_IER, AT91_RTC_SECEV);
+
printk(KERN_INFO "AT91 Real Time Clock driver.\n");
return 0;
}

2014-07-08 19:33:42

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 092/125] tracing: Fix syscall_*regfunc() vs copy_process() race

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Oleg Nesterov <[email protected]>

commit 4af4206be2bd1933cae20c2b6fb2058dbc887f7c upstream.

syscall_regfunc() and syscall_unregfunc() should set/clear
TIF_SYSCALL_TRACEPOINT system-wide, but do_each_thread() can race
with copy_process() and miss the new child which was not added to
the process/thread lists yet.

Change copy_process() to update the child's TIF_SYSCALL_TRACEPOINT
under tasklist.

Link: http://lkml.kernel.org/p/[email protected]

Fixes: a871bd33a6c0 "tracing: Add syscall tracepoints"
Acked-by: Frederic Weisbecker <[email protected]>
Acked-by: Paul E. McKenney <[email protected]>
Signed-off-by: Oleg Nesterov <[email protected]>
Signed-off-by: Steven Rostedt <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
include/trace/syscall.h | 15 +++++++++++++++
kernel/fork.c | 2 ++
2 files changed, 17 insertions(+)

--- a/include/trace/syscall.h
+++ b/include/trace/syscall.h
@@ -4,6 +4,7 @@
#include <linux/tracepoint.h>
#include <linux/unistd.h>
#include <linux/ftrace_event.h>
+#include <linux/thread_info.h>

#include <asm/ptrace.h>

@@ -54,4 +55,18 @@ int perf_sysexit_enable(struct ftrace_ev
void perf_sysexit_disable(struct ftrace_event_call *call);
#endif

+#if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_HAVE_SYSCALL_TRACEPOINTS)
+static inline void syscall_tracepoint_update(struct task_struct *p)
+{
+ if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
+ set_tsk_thread_flag(p, TIF_SYSCALL_TRACEPOINT);
+ else
+ clear_tsk_thread_flag(p, TIF_SYSCALL_TRACEPOINT);
+}
+#else
+static inline void syscall_tracepoint_update(struct task_struct *p)
+{
+}
+#endif
+
#endif /* _TRACE_SYSCALL_H */
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1370,7 +1370,9 @@ static struct task_struct *copy_process(

total_forks++;
spin_unlock(&current->sighand->siglock);
+ syscall_tracepoint_update(p);
write_unlock_irq(&tasklist_lock);
+
proc_fork_connector(p);
cgroup_post_fork(p);
if (clone_flags & CLONE_THREAD)

2014-07-08 19:39:38

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 109/125] MIPS: asm: thread_info: Add _TIF_SECCOMP flag

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Markos Chandras <[email protected]>

commit 137f7df8cead00688524c82360930845396b8a21 upstream.

Add _TIF_SECCOMP flag to _TIF_WORK_SYSCALL_ENTRY to indicate
that the system call needs to be checked against a seccomp filter.

Signed-off-by: Markos Chandras <[email protected]>
Reviewed-by: Paul Burton <[email protected]>
Reviewed-by: James Hogan <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/6405/
Signed-off-by: Ralf Baechle <[email protected]>
[bwh: Backported to 3.2: various other flags are not included in
_TIF_WORK_SYSCALL_ENTRY]
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/mips/include/asm/thread_info.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -149,7 +149,7 @@ register struct thread_info *__current_t
#define _TIF_FPUBOUND (1<<TIF_FPUBOUND)
#define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH)

-#define _TIF_WORK_SYSCALL_ENTRY (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT)
+#define _TIF_WORK_SYSCALL_ENTRY (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP)

/* work to do in syscall_trace_leave() */
#define _TIF_WORK_SYSCALL_EXIT (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT)

2014-07-08 19:39:36

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 118/125] [SCSI] megaraid: Use resource_size_t for PCI resources, not long

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Ben Collins <[email protected]>

commit 11f8a7b31f2140b0dc164bb484281235ffbe51d3 upstream.

The assumption that sizeof(long) >= sizeof(resource_size_t) can lead to
truncation of the PCI resource address, meaning this driver didn't work
on 32-bit systems with 64-bit PCI adressing ranges.

Signed-off-by: Ben Collins <[email protected]>
Acked-by: Sumit Saxena <[email protected]>
Signed-off-by: James Bottomley <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/scsi/megaraid/megaraid_sas.h | 1 -
drivers/scsi/megaraid/megaraid_sas_base.c | 5 +++--
2 files changed, 3 insertions(+), 3 deletions(-)

--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1295,7 +1295,6 @@ struct megasas_instance {
u32 *reply_queue;
dma_addr_t reply_queue_h;

- unsigned long base_addr;
struct megasas_register_set __iomem *reg_set;

struct megasas_pd_list pd_list[MEGASAS_MAX_PD];
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -3499,6 +3499,7 @@ static int megasas_init_fw(struct megasa
u32 max_sectors_1;
u32 max_sectors_2;
u32 tmp_sectors, msix_enable;
+ resource_size_t base_addr;
struct megasas_register_set __iomem *reg_set;
struct megasas_ctrl_info *ctrl_info;
unsigned long bar_list;
@@ -3507,14 +3508,14 @@ static int megasas_init_fw(struct megasa
/* Find first memory bar */
bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
instance->bar = find_first_bit(&bar_list, sizeof(unsigned long));
- instance->base_addr = pci_resource_start(instance->pdev, instance->bar);
if (pci_request_selected_regions(instance->pdev, instance->bar,
"megasas: LSI")) {
printk(KERN_DEBUG "megasas: IO memory region busy!\n");
return -EBUSY;
}

- instance->reg_set = ioremap_nocache(instance->base_addr, 8192);
+ base_addr = pci_resource_start(instance->pdev, instance->bar);
+ instance->reg_set = ioremap_nocache(base_addr, 8192);

if (!instance->reg_set) {
printk(KERN_DEBUG "megasas: Failed to map IO mem\n");

2014-07-08 19:39:35

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 095/125] lzo: properly check for overruns

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Greg Kroah-Hartman <[email protected]>

commit 206a81c18401c0cde6e579164f752c4b147324ce upstream.

The lzo decompressor can, if given some really crazy data, possibly
overrun some variable types. Modify the checking logic to properly
detect overruns before they happen.

Reported-by: "Don A. Bailey" <[email protected]>
Tested-by: "Don A. Bailey" <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
lib/lzo/lzo1x_decompress_safe.c | 62 +++++++++++++++++++++++++++--------------
1 file changed, 41 insertions(+), 21 deletions(-)

--- a/lib/lzo/lzo1x_decompress_safe.c
+++ b/lib/lzo/lzo1x_decompress_safe.c
@@ -19,11 +19,31 @@
#include <linux/lzo.h>
#include "lzodefs.h"

-#define HAVE_IP(x) ((size_t)(ip_end - ip) >= (size_t)(x))
-#define HAVE_OP(x) ((size_t)(op_end - op) >= (size_t)(x))
-#define NEED_IP(x) if (!HAVE_IP(x)) goto input_overrun
-#define NEED_OP(x) if (!HAVE_OP(x)) goto output_overrun
-#define TEST_LB(m_pos) if ((m_pos) < out) goto lookbehind_overrun
+#define HAVE_IP(t, x) \
+ (((size_t)(ip_end - ip) >= (size_t)(t + x)) && \
+ (((t + x) >= t) && ((t + x) >= x)))
+
+#define HAVE_OP(t, x) \
+ (((size_t)(op_end - op) >= (size_t)(t + x)) && \
+ (((t + x) >= t) && ((t + x) >= x)))
+
+#define NEED_IP(t, x) \
+ do { \
+ if (!HAVE_IP(t, x)) \
+ goto input_overrun; \
+ } while (0)
+
+#define NEED_OP(t, x) \
+ do { \
+ if (!HAVE_OP(t, x)) \
+ goto output_overrun; \
+ } while (0)
+
+#define TEST_LB(m_pos) \
+ do { \
+ if ((m_pos) < out) \
+ goto lookbehind_overrun; \
+ } while (0)

int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
unsigned char *out, size_t *out_len)
@@ -58,14 +78,14 @@ int lzo1x_decompress_safe(const unsigned
while (unlikely(*ip == 0)) {
t += 255;
ip++;
- NEED_IP(1);
+ NEED_IP(1, 0);
}
t += 15 + *ip++;
}
t += 3;
copy_literal_run:
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
- if (likely(HAVE_IP(t + 15) && HAVE_OP(t + 15))) {
+ if (likely(HAVE_IP(t, 15) && HAVE_OP(t, 15))) {
const unsigned char *ie = ip + t;
unsigned char *oe = op + t;
do {
@@ -81,8 +101,8 @@ copy_literal_run:
} else
#endif
{
- NEED_OP(t);
- NEED_IP(t + 3);
+ NEED_OP(t, 0);
+ NEED_IP(t, 3);
do {
*op++ = *ip++;
} while (--t > 0);
@@ -95,7 +115,7 @@ copy_literal_run:
m_pos -= t >> 2;
m_pos -= *ip++ << 2;
TEST_LB(m_pos);
- NEED_OP(2);
+ NEED_OP(2, 0);
op[0] = m_pos[0];
op[1] = m_pos[1];
op += 2;
@@ -119,10 +139,10 @@ copy_literal_run:
while (unlikely(*ip == 0)) {
t += 255;
ip++;
- NEED_IP(1);
+ NEED_IP(1, 0);
}
t += 31 + *ip++;
- NEED_IP(2);
+ NEED_IP(2, 0);
}
m_pos = op - 1;
next = get_unaligned_le16(ip);
@@ -137,10 +157,10 @@ copy_literal_run:
while (unlikely(*ip == 0)) {
t += 255;
ip++;
- NEED_IP(1);
+ NEED_IP(1, 0);
}
t += 7 + *ip++;
- NEED_IP(2);
+ NEED_IP(2, 0);
}
next = get_unaligned_le16(ip);
ip += 2;
@@ -154,7 +174,7 @@ copy_literal_run:
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
if (op - m_pos >= 8) {
unsigned char *oe = op + t;
- if (likely(HAVE_OP(t + 15))) {
+ if (likely(HAVE_OP(t, 15))) {
do {
COPY8(op, m_pos);
op += 8;
@@ -164,7 +184,7 @@ copy_literal_run:
m_pos += 8;
} while (op < oe);
op = oe;
- if (HAVE_IP(6)) {
+ if (HAVE_IP(6, 0)) {
state = next;
COPY4(op, ip);
op += next;
@@ -172,7 +192,7 @@ copy_literal_run:
continue;
}
} else {
- NEED_OP(t);
+ NEED_OP(t, 0);
do {
*op++ = *m_pos++;
} while (op < oe);
@@ -181,7 +201,7 @@ copy_literal_run:
#endif
{
unsigned char *oe = op + t;
- NEED_OP(t);
+ NEED_OP(t, 0);
op[0] = m_pos[0];
op[1] = m_pos[1];
op += 2;
@@ -194,15 +214,15 @@ match_next:
state = next;
t = next;
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
- if (likely(HAVE_IP(6) && HAVE_OP(4))) {
+ if (likely(HAVE_IP(6, 0) && HAVE_OP(4, 0))) {
COPY4(op, ip);
op += t;
ip += t;
} else
#endif
{
- NEED_IP(t + 3);
- NEED_OP(t);
+ NEED_IP(t, 3);
+ NEED_OP(t, 0);
while (t > 0) {
*op++ = *ip++;
t--;

2014-07-08 19:39:34

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 088/125] Bluetooth: Fix check for connection encryption

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hedberg <[email protected]>

commit e694788d73efe139b24f78b036deb97fe57fa8cb upstream.

The conn->link_key variable tracks the type of link key in use. It is
set whenever we respond to a link key request as well as when we get a
link key notification event.

These two events do not however always guarantee that encryption is
enabled: getting a link key request and responding to it may only mean
that the remote side has requested authentication but not encryption. On
the other hand, the encrypt change event is a certain guarantee that
encryption is enabled. The real encryption state is already tracked in
the conn->link_mode variable through the HCI_LM_ENCRYPT bit.

This patch fixes a check for encryption in the hci_conn_auth function to
use the proper conn->link_mode value and thereby eliminates the chance
of a false positive result.

Signed-off-by: Johan Hedberg <[email protected]>
Signed-off-by: Marcel Holtmann <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
net/bluetooth/hci_conn.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -617,7 +617,7 @@ static int hci_conn_auth(struct hci_conn
/* If we're already encrypted set the REAUTH_PEND flag,
* otherwise set the ENCRYPT_PEND.
*/
- if (conn->key_type != 0xff)
+ if (conn->link_mode & HCI_LM_ENCRYPT)
set_bit(HCI_CONN_REAUTH_PEND, &conn->pend);
else
set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);

2014-07-08 19:39:32

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 011/125] ARM: imx: fix error handling in ipu device registration

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Emil Goode <[email protected]>

commit d1d70e5dc2cfa9047bb935c41ba808ebb8135696 upstream.

If we fail to allocate struct platform_device pdev we
dereference it after the goto label err.

This bug was found using coccinelle.

Fixes: afa77ef (ARM: mx3: dynamically allocate "ipu-core" devices)
Signed-off-by: Emil Goode <[email protected]>
Acked-by: Uwe Kleine-König <[email protected]>
Signed-off-by: Shawn Guo <[email protected]>
Signed-off-by: Olof Johansson <[email protected]>
[bwh: Backported to 3.2: adjust filename]
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/arm/plat-mxc/devices/platform-ipu-core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/plat-mxc/devices/platform-ipu-core.c b/arch/arm/plat-mxc/devices/platform-ipu-core.c
index fc4dd7c..6bd7c3f 100644
--- a/arch/arm/plat-mxc/devices/platform-ipu-core.c
+++ b/arch/arm/plat-mxc/devices/platform-ipu-core.c
@@ -77,7 +77,7 @@ struct platform_device *__init imx_alloc_mx3_camera(

pdev = platform_device_alloc("mx3-camera", 0);
if (!pdev)
- goto err;
+ return ERR_PTR(-ENOMEM);

pdev->dev.dma_mask = kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
if (!pdev->dev.dma_mask)

2014-07-08 19:39:31

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 120/125] ARM: 8012/1: kdump: Avoid overflow when converting pfn to physaddr

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Liu Hua <[email protected]>

commit 8fad87bca7ac9737e413ba5f1656f1114a8c314d upstream.

When we configure CONFIG_ARM_LPAE=y, pfn << PAGE_SHIFT will
overflow if pfn >= 0x100000 in copy_oldmem_page.
So use __pfn_to_phys for converting.

Signed-off-by: Liu Hua <[email protected]>
Signed-off-by: Russell King <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/arm/kernel/crash_dump.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/arch/arm/kernel/crash_dump.c
+++ b/arch/arm/kernel/crash_dump.c
@@ -39,7 +39,7 @@ ssize_t copy_oldmem_page(unsigned long p
if (!csize)
return 0;

- vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
+ vaddr = ioremap(__pfn_to_phys(pfn), PAGE_SIZE);
if (!vaddr)
return -ENOMEM;

2014-07-08 19:39:28

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 097/125] hugetlb: fix copy_hugetlb_page_range() to handle migration/hwpoisoned entry

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Naoya Horiguchi <[email protected]>

commit 4a705fef986231a3e7a6b1a6d3c37025f021f49f upstream.

There's a race between fork() and hugepage migration, as a result we try
to "dereference" a swap entry as a normal pte, causing kernel panic.
The cause of the problem is that copy_hugetlb_page_range() can't handle
"swap entry" family (migration entry and hwpoisoned entry) so let's fix
it.

[[email protected]: coding-style fixes]
Signed-off-by: Naoya Horiguchi <[email protected]>
Acked-by: Hugh Dickins <[email protected]>
Cc: Christoph Lameter <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
mm/hugetlb.c | 71 ++++++++++++++++++++++++++++++++++++------------------------
1 file changed, 43 insertions(+), 28 deletions(-)

--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2272,6 +2272,31 @@ static void set_huge_ptep_writable(struc
update_mmu_cache(vma, address, ptep);
}

+static int is_hugetlb_entry_migration(pte_t pte)
+{
+ swp_entry_t swp;
+
+ if (huge_pte_none(pte) || pte_present(pte))
+ return 0;
+ swp = pte_to_swp_entry(pte);
+ if (non_swap_entry(swp) && is_migration_entry(swp))
+ return 1;
+ else
+ return 0;
+}
+
+static int is_hugetlb_entry_hwpoisoned(pte_t pte)
+{
+ swp_entry_t swp;
+
+ if (huge_pte_none(pte) || pte_present(pte))
+ return 0;
+ swp = pte_to_swp_entry(pte);
+ if (non_swap_entry(swp) && is_hwpoison_entry(swp))
+ return 1;
+ else
+ return 0;
+}

int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
struct vm_area_struct *vma)
@@ -2299,10 +2324,26 @@ int copy_hugetlb_page_range(struct mm_st

spin_lock(&dst->page_table_lock);
spin_lock_nested(&src->page_table_lock, SINGLE_DEPTH_NESTING);
- if (!huge_pte_none(huge_ptep_get(src_pte))) {
+ entry = huge_ptep_get(src_pte);
+ if (huge_pte_none(entry)) { /* skip none entry */
+ ;
+ } else if (unlikely(is_hugetlb_entry_migration(entry) ||
+ is_hugetlb_entry_hwpoisoned(entry))) {
+ swp_entry_t swp_entry = pte_to_swp_entry(entry);
+
+ if (is_write_migration_entry(swp_entry) && cow) {
+ /*
+ * COW mappings require pages in both
+ * parent and child to be set to read.
+ */
+ make_migration_entry_read(&swp_entry);
+ entry = swp_entry_to_pte(swp_entry);
+ set_huge_pte_at(src, addr, src_pte, entry);
+ }
+ set_huge_pte_at(dst, addr, dst_pte, entry);
+ } else {
if (cow)
huge_ptep_set_wrprotect(src, addr, src_pte);
- entry = huge_ptep_get(src_pte);
ptepage = pte_page(entry);
get_page(ptepage);
page_dup_rmap(ptepage);
@@ -2317,32 +2358,6 @@ nomem:
return -ENOMEM;
}

-static int is_hugetlb_entry_migration(pte_t pte)
-{
- swp_entry_t swp;
-
- if (huge_pte_none(pte) || pte_present(pte))
- return 0;
- swp = pte_to_swp_entry(pte);
- if (non_swap_entry(swp) && is_migration_entry(swp))
- return 1;
- else
- return 0;
-}
-
-static int is_hugetlb_entry_hwpoisoned(pte_t pte)
-{
- swp_entry_t swp;
-
- if (huge_pte_none(pte) || pte_present(pte))
- return 0;
- swp = pte_to_swp_entry(pte);
- if (non_swap_entry(swp) && is_hwpoison_entry(swp))
- return 1;
- else
- return 0;
-}
-
void __unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end, struct page *ref_page)
{

2014-07-08 19:41:32

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 101/125] recordmcount/MIPS: Fix possible incorrect mcount_loc table entries in modules

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Alex Smith <[email protected]>

commit 91ad11d7cc6f4472ebf177a6252fbf0fd100d798 upstream.

On MIPS calls to _mcount in modules generate 2 instructions to load
the _mcount address (and therefore 2 relocations). The mcount_loc
table should only reference the first of these, so the second is
filtered out by checking the relocation offset and ignoring ones that
immediately follow the previous one seen.

However if a module has an _mcount call at offset 0, the second
relocation would not be filtered out due to old_r_offset == 0
being taken to mean that the current relocation is the first one
seen, and both would end up in the mcount_loc table.

This results in ftrace_make_nop() patching both (adjacent)
instructions to branches over the _mcount call sequence like so:

0xffffffffc08a8000: 04 00 00 10 b 0xffffffffc08a8014
0xffffffffc08a8004: 04 00 00 10 b 0xffffffffc08a8018
0xffffffffc08a8008: 2d 08 e0 03 move at,ra
...

The second branch is in the delay slot of the first, which is
defined to be unpredictable - on the platform on which this bug was
encountered, it triggers a reserved instruction exception.

Fix by initializing old_r_offset to ~0 and using that instead of 0
to determine whether the current relocation is the first seen.

Signed-off-by: Alex Smith <[email protected]>
Cc: [email protected]
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/7098/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
scripts/recordmcount.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--- a/scripts/recordmcount.h
+++ b/scripts/recordmcount.h
@@ -163,11 +163,11 @@ static int mcount_adjust = 0;

static int MIPS_is_fake_mcount(Elf_Rel const *rp)
{
- static Elf_Addr old_r_offset;
+ static Elf_Addr old_r_offset = ~(Elf_Addr)0;
Elf_Addr current_r_offset = _w(rp->r_offset);
int is_fake;

- is_fake = old_r_offset &&
+ is_fake = (old_r_offset != ~(Elf_Addr)0) &&
(current_r_offset - old_r_offset == MIPS_FAKEMCOUNT_OFFSET);
old_r_offset = current_r_offset;

2014-07-08 19:41:30

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 102/125] MIPS: MSC: Prevent out-of-bounds writes to MIPS SC ioremap'd region

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Markos Chandras <[email protected]>

commit ab6c15bc6620ebe220970cc040b29bcb2757f373 upstream.

Previously, the lower limit for the MIPS SC initialization loop was
set incorrectly allowing one extra loop leading to writes
beyond the MSC ioremap'd space. More precisely, the value of the 'imp'
in the last loop increased beyond the msc_irqmap_t boundaries and
as a result of which, the 'n' variable was loaded with an incorrect
value. This value was used later on to calculate the offset in the
MSC01_IC_SUP which led to random crashes like the following one:

CPU 0 Unable to handle kernel paging request at virtual address e75c0200,
epc == 8058dba4, ra == 8058db90
[...]
Call Trace:
[<8058dba4>] init_msc_irqs+0x104/0x154
[<8058b5bc>] arch_init_irq+0xd8/0x154
[<805897b0>] start_kernel+0x220/0x36c

Kernel panic - not syncing: Attempted to kill the idle task!

This patch fixes the problem

Signed-off-by: Markos Chandras <[email protected]>
Reviewed-by: James Hogan <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/7118/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/mips/kernel/irq-msc01.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/arch/mips/kernel/irq-msc01.c
+++ b/arch/mips/kernel/irq-msc01.c
@@ -131,7 +131,7 @@ void __init init_msc_irqs(unsigned long

board_bind_eic_interrupt = &msc_bind_eic_interrupt;

- for (; nirq >= 0; nirq--, imp++) {
+ for (; nirq > 0; nirq--, imp++) {
int n = imp->im_irq;

switch (imp->im_type) {

2014-07-08 19:41:29

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 114/125] mlx4_core: Stash PCI ID driver_data in mlx4_priv structure

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Wei Yang <[email protected]>

[ No upstream commit, this is a cherry picked backport enabler. ]

That way we can check flags later on, when we've finished with the
pci_device_id structure.

This is a backport.

Signed-off-by: Roland Dreier <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/ethernet/mellanox/mlx4/main.c | 12 +++++++++---
drivers/net/ethernet/mellanox/mlx4/mlx4.h | 2 ++
2 files changed, 11 insertions(+), 3 deletions(-)

--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -1220,7 +1220,7 @@ static void mlx4_clear_steering(struct m
kfree(priv->steer);
}

-static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
+static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)
{
struct mlx4_priv *priv;
struct mlx4_dev *dev;
@@ -1362,6 +1362,7 @@ static int __mlx4_init_one(struct pci_de
mlx4_sense_init(dev);
mlx4_start_sense(dev);

+ priv->pci_dev_data = pci_dev_data;
pci_set_drvdata(pdev, dev);

return 0;
@@ -1414,7 +1415,7 @@ static int __devinit mlx4_init_one(struc
{
printk_once(KERN_INFO "%s", mlx4_version);

- return __mlx4_init_one(pdev, id);
+ return __mlx4_init_one(pdev, id->driver_data);
}

static void mlx4_remove_one(struct pci_dev *pdev)
@@ -1463,8 +1464,13 @@ static void mlx4_remove_one(struct pci_d

int mlx4_restart_one(struct pci_dev *pdev)
{
+ struct mlx4_dev *dev = pci_get_drvdata(pdev);
+ struct mlx4_priv *priv = mlx4_priv(dev);
+ int pci_dev_data;
+
+ pci_dev_data = priv->pci_dev_data;
mlx4_remove_one(pdev);
- return __mlx4_init_one(pdev, NULL);
+ return __mlx4_init_one(pdev, pci_dev_data);
}

static DEFINE_PCI_DEVICE_TABLE(mlx4_pci_table) = {
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -328,6 +328,8 @@ struct mlx4_priv {
struct list_head ctx_list;
spinlock_t ctx_lock;

+ int pci_dev_data;
+
struct list_head pgdir_list;
struct mutex pgdir_mutex;

2014-07-08 19:42:20

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 002/125] bluetooth: hci_ldisc: fix deadlock condition

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Felipe Balbi <[email protected]>

commit da64c27d3c93ee9f89956b9de86c4127eb244494 upstream.

LDISCs shouldn't call tty->ops->write() from within
->write_wakeup().

->write_wakeup() is called with port lock taken and
IRQs disabled, tty->ops->write() will try to acquire
the same port lock and we will deadlock.

Acked-by: Marcel Holtmann <[email protected]>
Reviewed-by: Peter Hurley <[email protected]>
Reported-by: Huang Shijie <[email protected]>
Signed-off-by: Felipe Balbi <[email protected]>
Tested-by: Andreas Bießmann <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[bwh: Backported to 3.2: adjust context, indentation]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/bluetooth/hci_ldisc.c | 24 +++++++++++++++++++-----
drivers/bluetooth/hci_uart.h | 1 +
2 files changed, 20 insertions(+), 5 deletions(-)

--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -120,10 +120,6 @@ static inline struct sk_buff *hci_uart_d

int hci_uart_tx_wakeup(struct hci_uart *hu)
{
- struct tty_struct *tty = hu->tty;
- struct hci_dev *hdev = hu->hdev;
- struct sk_buff *skb;
-
if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) {
set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
return 0;
@@ -131,6 +127,22 @@ int hci_uart_tx_wakeup(struct hci_uart *

BT_DBG("");

+ schedule_work(&hu->write_work);
+
+ return 0;
+}
+
+static void hci_uart_write_work(struct work_struct *work)
+{
+ struct hci_uart *hu = container_of(work, struct hci_uart, write_work);
+ struct tty_struct *tty = hu->tty;
+ struct hci_dev *hdev = hu->hdev;
+ struct sk_buff *skb;
+
+ /* REVISIT: should we cope with bad skbs or ->write() returning
+ * and error value ?
+ */
+
restart:
clear_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);

@@ -155,7 +167,6 @@ restart:
goto restart;

clear_bit(HCI_UART_SENDING, &hu->tx_state);
- return 0;
}

/* ------- Interface to HCI layer ------ */
@@ -274,6 +285,8 @@ static int hci_uart_tty_open(struct tty_
hu->tty = tty;
tty->receive_room = 65536;

+ INIT_WORK(&hu->write_work, hci_uart_write_work);
+
spin_lock_init(&hu->rx_lock);

/* Flush any pending characters in the driver and line discipline. */
@@ -308,6 +321,8 @@ static void hci_uart_tty_close(struct tt
if (hdev)
hci_uart_close(hdev);

+ cancel_work_sync(&hu->write_work);
+
if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
if (hdev) {
hci_unregister_dev(hdev);
--- a/drivers/bluetooth/hci_uart.h
+++ b/drivers/bluetooth/hci_uart.h
@@ -64,6 +64,8 @@ struct hci_uart {
unsigned long flags;
unsigned long hdev_flags;

+ struct work_struct write_work;
+
struct hci_uart_proto *proto;
void *priv;

2014-07-08 19:42:26

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 007/125] HID: core: fix validation of report id 0

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Kees Cook <[email protected]>

commit 1b15d2e5b8077670b1e6a33250a0d9577efff4a5 upstream.

Some drivers use the first HID report in the list instead of using an
index. In these cases, validation uses ID 0, which was supposed to mean
"first known report". This fixes the problem, which was causing at least
the lgff family of devices to stop working since hid_validate_values
was being called with ID 0, but the devices used single numbered IDs
for their reports:

0x05, 0x01, /* Usage Page (Desktop), */
0x09, 0x05, /* Usage (Gamepad), */
0xA1, 0x01, /* Collection (Application), */
0xA1, 0x02, /* Collection (Logical), */
0x85, 0x01, /* Report ID (1), */
...

Reported-by: Simon Wood <[email protected]>
Signed-off-by: Kees Cook <[email protected]>
Reviewed-by: Benjamin Tissoires <[email protected]>
Signed-off-by: Jiri Kosina <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/hid/hid-core.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -754,7 +754,17 @@ struct hid_report *hid_validate_values(s
* ->numbered being checked, which may not always be the case when
* drivers go to access report values.
*/
- report = hid->report_enum[type].report_id_hash[id];
+ if (id == 0) {
+ /*
+ * Validating on id 0 means we should examine the first
+ * report in the list.
+ */
+ report = list_entry(
+ hid->report_enum[type].report_list.next,
+ struct hid_report, list);
+ } else {
+ report = hid->report_enum[type].report_id_hash[id];
+ }
if (!report) {
hid_err(hid, "missing %s %u\n", hid_report_names[type], id);
return NULL;

2014-07-08 19:42:22

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 096/125] x86_32, entry: Do syscall exit work on badsys (CVE-2014-4508)

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Andy Lutomirski <[email protected]>

commit 554086d85e71f30abe46fc014fea31929a7c6a8a upstream.

The bad syscall nr paths are their own incomprehensible route
through the entry control flow. Rearrange them to work just like
syscalls that return -ENOSYS.

This fixes an OOPS in the audit code when fast-path auditing is
enabled and sysenter gets a bad syscall nr (CVE-2014-4508).

This has probably been broken since Linux 2.6.27:
af0575bba0 i386 syscall audit fast-path

Cc: Roland McGrath <[email protected]>
Reported-by: Toralf Förster <[email protected]>
Signed-off-by: Andy Lutomirski <[email protected]>
Link: http://lkml.kernel.org/r/e09c499eade6fc321266dd6b54da7beb28d6991c.1403558229.git.luto@amacapital.net
Signed-off-by: H. Peter Anvin <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/x86/kernel/entry_32.S | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)

--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -427,9 +427,10 @@ sysenter_past_esp:
jnz sysenter_audit
sysenter_do_call:
cmpl $(nr_syscalls), %eax
- jae syscall_badsys
+ jae sysenter_badsys
call *sys_call_table(,%eax,4)
movl %eax,PT_EAX(%esp)
+sysenter_after_call:
LOCKDEP_SYS_EXIT
DISABLE_INTERRUPTS(CLBR_ANY)
TRACE_IRQS_OFF
@@ -681,7 +682,12 @@ END(syscall_fault)

syscall_badsys:
movl $-ENOSYS,PT_EAX(%esp)
- jmp resume_userspace
+ jmp syscall_exit
+END(syscall_badsys)
+
+sysenter_badsys:
+ movl $-ENOSYS,PT_EAX(%esp)
+ jmp sysenter_after_call
END(syscall_badsys)
CFI_ENDPROC
/*

2014-07-08 19:42:18

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 103/125] target: Fix left-over se_lun->lun_sep pointer OOPs

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Nicholas Bellinger <[email protected]>

commit 83ff42fcce070801a3aa1cd6a3269d7426271a8d upstream.

This patch fixes a left-over se_lun->lun_sep pointer OOPs when one
of the /sys/kernel/config/target/$FABRIC/$WWPN/$TPGT/lun/$LUN/alua*
attributes is accessed after the $DEVICE symlink has been removed.

To address this bug, go ahead and clear se_lun->lun_sep memory in
core_dev_unexport(), so that the existing checks for show/store
ALUA attributes in target_core_fabric_configfs.c work as expected.

Reported-by: Sebastian Herbszt <[email protected]>
Tested-by: Sebastian Herbszt <[email protected]>
Signed-off-by: Nicholas Bellinger <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/target/target_core_device.c | 1 +
1 file changed, 1 insertion(+)

--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -646,6 +646,7 @@ void core_dev_unexport(
spin_unlock(&dev->se_port_lock);

se_dev_stop(dev);
+ lun->lun_sep = NULL;
lun->lun_se_dev = NULL;
}

2014-07-08 19:42:16

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 115/125] net/mlx4_core: Preserve pci_dev_data after __mlx4_remove_one()

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Wei Yang <[email protected]>

[ Upstream commit befdf8978accecac2e0739e6b5075afc62db37fe ]

This patch wrap up a helper function __mlx4_remove_one() which does the tear
down function but preserve the drv_data. Functions like
mlx4_pci_err_detected() and mlx4_restart_one() will call this one with out
releasing drvdata.

Signed-off-by: Wei Yang <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/ethernet/mellanox/mlx4/main.c | 110 +++++++++++++++++-------------
drivers/net/ethernet/mellanox/mlx4/mlx4.h | 1 +
2 files changed, 65 insertions(+), 46 deletions(-)

--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -1283,15 +1283,8 @@ static int __mlx4_init_one(struct pci_de
/* Allow large DMA segments, up to the firmware limit of 1 GB */
dma_set_max_seg_size(&pdev->dev, 1024 * 1024 * 1024);

- priv = kzalloc(sizeof *priv, GFP_KERNEL);
- if (!priv) {
- dev_err(&pdev->dev, "Device struct alloc failed, "
- "aborting.\n");
- err = -ENOMEM;
- goto err_release_regions;
- }
-
- dev = &priv->dev;
+ dev = pci_get_drvdata(pdev);
+ priv = mlx4_priv(dev);
dev->pdev = pdev;
INIT_LIST_HEAD(&priv->ctx_list);
spin_lock_init(&priv->ctx_lock);
@@ -1362,8 +1355,7 @@ static int __mlx4_init_one(struct pci_de
mlx4_sense_init(dev);
mlx4_start_sense(dev);

- priv->pci_dev_data = pci_dev_data;
- pci_set_drvdata(pdev, dev);
+ priv->removed = 0;

return 0;

@@ -1413,53 +1405,79 @@ err_disable_pdev:
static int __devinit mlx4_init_one(struct pci_dev *pdev,
const struct pci_device_id *id)
{
+ struct mlx4_priv *priv;
+ struct mlx4_dev *dev;
+
printk_once(KERN_INFO "%s", mlx4_version);

+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ dev = &priv->dev;
+ pci_set_drvdata(pdev, dev);
+ priv->pci_dev_data = id->driver_data;
+
return __mlx4_init_one(pdev, id->driver_data);
}

-static void mlx4_remove_one(struct pci_dev *pdev)
+static void __mlx4_remove_one(struct pci_dev *pdev)
{
struct mlx4_dev *dev = pci_get_drvdata(pdev);
struct mlx4_priv *priv = mlx4_priv(dev);
+ int pci_dev_data;
int p;

- if (dev) {
- mlx4_stop_sense(dev);
- mlx4_unregister_device(dev);
-
- for (p = 1; p <= dev->caps.num_ports; p++) {
- mlx4_cleanup_port_info(&priv->port[p]);
- mlx4_CLOSE_PORT(dev, p);
- }
-
- mlx4_cleanup_counters_table(dev);
- mlx4_cleanup_mcg_table(dev);
- mlx4_cleanup_qp_table(dev);
- mlx4_cleanup_srq_table(dev);
- mlx4_cleanup_cq_table(dev);
- mlx4_cmd_use_polling(dev);
- mlx4_cleanup_eq_table(dev);
- mlx4_cleanup_mr_table(dev);
- mlx4_cleanup_xrcd_table(dev);
- mlx4_cleanup_pd_table(dev);
-
- iounmap(priv->kar);
- mlx4_uar_free(dev, &priv->driver_uar);
- mlx4_cleanup_uar_table(dev);
- mlx4_clear_steering(dev);
- mlx4_free_eq_table(dev);
- mlx4_close_hca(dev);
- mlx4_cmd_cleanup(dev);
-
- if (dev->flags & MLX4_FLAG_MSI_X)
- pci_disable_msix(pdev);
-
- kfree(priv);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
+ if (priv->removed)
+ return;
+
+ pci_dev_data = priv->pci_dev_data;
+
+ mlx4_stop_sense(dev);
+ mlx4_unregister_device(dev);
+
+ for (p = 1; p <= dev->caps.num_ports; p++) {
+ mlx4_cleanup_port_info(&priv->port[p]);
+ mlx4_CLOSE_PORT(dev, p);
}
+
+ mlx4_cleanup_counters_table(dev);
+ mlx4_cleanup_mcg_table(dev);
+ mlx4_cleanup_qp_table(dev);
+ mlx4_cleanup_srq_table(dev);
+ mlx4_cleanup_cq_table(dev);
+ mlx4_cmd_use_polling(dev);
+ mlx4_cleanup_eq_table(dev);
+ mlx4_cleanup_mr_table(dev);
+ mlx4_cleanup_xrcd_table(dev);
+ mlx4_cleanup_pd_table(dev);
+
+ iounmap(priv->kar);
+ mlx4_uar_free(dev, &priv->driver_uar);
+ mlx4_cleanup_uar_table(dev);
+ mlx4_clear_steering(dev);
+ mlx4_free_eq_table(dev);
+ mlx4_close_hca(dev);
+ mlx4_cmd_cleanup(dev);
+
+ if (dev->flags & MLX4_FLAG_MSI_X)
+ pci_disable_msix(pdev);
+
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ memset(priv, 0, sizeof(*priv));
+ priv->pci_dev_data = pci_dev_data;
+ priv->removed = 1;
+}
+
+static void mlx4_remove_one(struct pci_dev *pdev)
+{
+ struct mlx4_dev *dev = pci_get_drvdata(pdev);
+ struct mlx4_priv *priv = mlx4_priv(dev);
+
+ __mlx4_remove_one(pdev);
+ kfree(priv);
+ pci_set_drvdata(pdev, NULL);
}

int mlx4_restart_one(struct pci_dev *pdev)
@@ -1469,7 +1487,7 @@ int mlx4_restart_one(struct pci_dev *pde
int pci_dev_data;

pci_dev_data = priv->pci_dev_data;
- mlx4_remove_one(pdev);
+ __mlx4_remove_one(pdev);
return __mlx4_init_one(pdev, pci_dev_data);
}

--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -329,6 +329,7 @@ struct mlx4_priv {
spinlock_t ctx_lock;

int pci_dev_data;
+ int removed;

struct list_head pgdir_list;
struct mutex pgdir_mutex;

2014-07-08 19:42:14

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 014/125] ARM: 8051/1: put_user: fix possible data corruption in put_user

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Andrey Ryabinin <[email protected]>

commit 537094b64b229bf3ad146042f83e74cf6abe59df upstream.

According to arm procedure call standart r2 register is call-cloberred.
So after the result of x expression was put into r2 any following
function call in p may overwrite r2. To fix this, the result of p
expression must be saved to the temporary variable before the
assigment x expression to __r2.

Signed-off-by: Andrey Ryabinin <[email protected]>
Reviewed-by: Nicolas Pitre <[email protected]>
Signed-off-by: Russell King <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/arm/include/asm/uaccess.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -158,8 +158,9 @@ extern int __put_user_8(void *, unsigned
#define put_user(x,p) \
({ \
unsigned long __limit = current_thread_info()->addr_limit - 1; \
+ const typeof(*(p)) __user *__tmp_p = (p); \
register const typeof(*(p)) __r2 asm("r2") = (x); \
- register const typeof(*(p)) __user *__p asm("r0") = (p);\
+ register const typeof(*(p)) __user *__p asm("r0") = __tmp_p; \
register unsigned long __l asm("r1") = __limit; \
register int __e asm("r0"); \
switch (sizeof(*(__p))) { \

2014-07-08 19:44:36

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 106/125] [SCSI] dual scan thread bug fix

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: James Bottomley <[email protected]>

commit f2495e228fce9f9cec84367547813cbb0d6db15a upstream.

In the highly unusual case where two threads are running concurrently through
the scanning code scanning the same target, we run into the situation where
one may allocate the target while the other is still using it. In this case,
because the reap checks for STARGET_CREATED and kills the target without
reference counting, the second thread will do the wrong thing on reap.

Fix this by reference counting even creates and doing the STARGET_CREATED
check in the final put.

Tested-by: Sarah Sharp <[email protected]>
Signed-off-by: James Bottomley <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/scsi/scsi_scan.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)

--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -332,6 +332,7 @@ static void scsi_target_destroy(struct s
struct Scsi_Host *shost = dev_to_shost(dev->parent);
unsigned long flags;

+ starget->state = STARGET_DEL;
transport_destroy_device(dev);
spin_lock_irqsave(shost->host_lock, flags);
if (shost->hostt->target_destroy)
@@ -396,9 +397,15 @@ static void scsi_target_reap_ref_release
struct scsi_target *starget
= container_of(kref, struct scsi_target, reap_ref);

- transport_remove_device(&starget->dev);
- device_del(&starget->dev);
- starget->state = STARGET_DEL;
+ /*
+ * if we get here and the target is still in the CREATED state that
+ * means it was allocated but never made visible (because a scan
+ * turned up no LUNs), so don't call device_del() on it.
+ */
+ if (starget->state != STARGET_CREATED) {
+ transport_remove_device(&starget->dev);
+ device_del(&starget->dev);
+ }
scsi_target_destroy(starget);
}

@@ -518,11 +525,13 @@ static struct scsi_target *scsi_alloc_ta
*/
void scsi_target_reap(struct scsi_target *starget)
{
+ /*
+ * serious problem if this triggers: STARGET_DEL is only set in the if
+ * the reap_ref drops to zero, so we're trying to do another final put
+ * on an already released kref
+ */
BUG_ON(starget->state == STARGET_DEL);
- if (starget->state == STARGET_CREATED)
- scsi_target_destroy(starget);
- else
- scsi_target_reap_ref_put(starget);
+ scsi_target_reap_ref_put(starget);
}

/**

2014-07-08 19:44:35

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 122/125] ptrace,x86: force IRET path after a ptrace_stop()

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Tejun Heo <[email protected]>

commit b9cd18de4db3c9ffa7e17b0dc0ca99ed5aa4d43a upstream.

The 'sysret' fastpath does not correctly restore even all regular
registers, much less any segment registers or reflags values. That is
very much part of why it's faster than 'iret'.

Normally that isn't a problem, because the normal ptrace() interface
catches the process using the signal handler infrastructure, which
always returns with an iret.

However, some paths can get caught using ptrace_event() instead of the
signal path, and for those we need to make sure that we aren't going to
return to user space using 'sysret'. Otherwise the modifications that
may have been done to the register set by the tracer wouldn't
necessarily take effect.

Fix it by forcing IRET path by setting TIF_NOTIFY_RESUME from
arch_ptrace_stop_needed() which is invoked from ptrace_stop().

Signed-off-by: Tejun Heo <[email protected]>
Reported-by: Andy Lutomirski <[email protected]>
Acked-by: Oleg Nesterov <[email protected]>
Suggested-by: Linus Torvalds <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/x86/include/asm/ptrace.h | 16 ++++++++++++++++
include/linux/ptrace.h | 3 +++
2 files changed, 19 insertions(+)

--- a/arch/x86/include/asm/ptrace.h
+++ b/arch/x86/include/asm/ptrace.h
@@ -287,6 +287,22 @@ static inline unsigned long regs_get_ker

#define ARCH_HAS_USER_SINGLE_STEP_INFO

+/*
+ * When hitting ptrace_stop(), we cannot return using SYSRET because
+ * that does not restore the full CPU state, only a minimal set. The
+ * ptracer can change arbitrary register values, which is usually okay
+ * because the usual ptrace stops run off the signal delivery path which
+ * forces IRET; however, ptrace_event() stops happen in arbitrary places
+ * in the kernel and don't force IRET path.
+ *
+ * So force IRET path after a ptrace stop.
+ */
+#define arch_ptrace_stop_needed(code, info) \
+({ \
+ set_thread_flag(TIF_NOTIFY_RESUME); \
+ false; \
+})
+
struct user_desc;
extern int do_get_thread_area(struct task_struct *p, int idx,
struct user_desc __user *info);
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -403,6 +403,9 @@ static inline void user_single_step_sigi
* calling arch_ptrace_stop() when it would be superfluous. For example,
* if the thread has not been back to user mode since the last stop, the
* thread state might indicate that nothing needs to be done.
+ *
+ * This is guaranteed to be invoked once before a task stops for ptrace and
+ * may include arch-specific operations necessary prior to a ptrace stop.
*/
#define arch_ptrace_stop_needed(code, info) (0)
#endif

2014-07-08 19:44:34

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 006/125] ACPI: Fix conflict between customized DSDT and DSDT local copy

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Lv Zheng <[email protected]>

commit 73577d1df8e1f31f6b1a5eebcdbc334eb0330e47 upstream.

This patch fixes the following issue:
If DSDT is customized, no local DSDT copy is needed.

References: https://bugzilla.kernel.org/show_bug.cgi?id=69711
Signed-off-by: Enrico Etxe Arte <[email protected]>
Signed-off-by: Lv Zheng <[email protected]>
[rjw: Subject]
Signed-off-by: Rafael J. Wysocki <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/acpi/bus.c | 7 +++++++
1 file changed, 7 insertions(+)

--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -57,6 +57,12 @@ EXPORT_SYMBOL(acpi_root_dir);


#ifdef CONFIG_X86
+#ifdef CONFIG_ACPI_CUSTOM_DSDT
+static inline int set_copy_dsdt(const struct dmi_system_id *id)
+{
+ return 0;
+}
+#else
static int set_copy_dsdt(const struct dmi_system_id *id)
{
printk(KERN_NOTICE "%s detected - "
@@ -64,6 +70,7 @@ static int set_copy_dsdt(const struct dm
acpi_gbl_copy_dsdt_locally = 1;
return 0;
}
+#endif

static struct dmi_system_id dsdt_dmi_table[] __initdata = {
/*

2014-07-08 19:44:32

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 111/125] net: tunnels - enable module autoloading

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Tom Gundersen <[email protected]>

[ Upstream commit f98f89a0104454f35a62d681683c844f6dbf4043 ]

Enable the module alias hookup to allow tunnel modules to be autoloaded on demand.

This is in line with how most other netdev kinds work, and will allow userspace
to create tunnels without having CAP_SYS_MODULE.

Signed-off-by: Tom Gundersen <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/ipv4/ipip.c | 1 +
net/ipv6/ip6_tunnel.c | 1 +
net/ipv6/sit.c | 1 +
3 files changed, 3 insertions(+)

--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -909,4 +909,5 @@ static void __exit ipip_fini(void)
module_init(ipip_init);
module_exit(ipip_fini);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_RTNL_LINK("ipip");
MODULE_ALIAS_NETDEV("tunl0");
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -57,6 +57,7 @@
MODULE_AUTHOR("Ville Nuorvala");
MODULE_DESCRIPTION("IPv6 tunneling device");
MODULE_LICENSE("GPL");
+MODULE_ALIAS_RTNL_LINK("ip6tnl");
MODULE_ALIAS_NETDEV("ip6tnl0");

#ifdef IP6_TNL_DEBUG
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -1293,4 +1293,5 @@ static int __init sit_init(void)
module_init(sit_init);
module_exit(sit_cleanup);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_RTNL_LINK("sit");
MODULE_ALIAS_NETDEV("sit0");

2014-07-08 19:44:30

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 016/125] mac80211: fix IBSS join by initializing last_scan_completed

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Krzysztof Hałasa <[email protected]>

commit c7d37a66e345df2fdf1aa7b2c9a6d3d53846ca5b upstream.

Without this fix, freshly rebooted Linux creates a new IBSS
instead of joining an existing one. Only when jiffies counter
overflows after 5 minutes the IBSS can be successfully joined.

Signed-off-by: Krzysztof Hałasa <[email protected]>
[edit commit message slightly]
Signed-off-by: Johannes Berg <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
net/mac80211/ibss.c | 1 +
1 file changed, 1 insertion(+)

--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -914,6 +914,7 @@ int ieee80211_ibss_join(struct ieee80211

sdata->u.ibss.privacy = params->privacy;
sdata->u.ibss.basic_rates = params->basic_rates;
+ sdata->u.ibss.last_scan_completed = jiffies;
memcpy(sdata->vif.bss_conf.mcast_rate, params->mcast_rate,
sizeof(params->mcast_rate));

2014-07-08 19:44:28

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 116/125] target: Explicitly clear ramdisk_mcp backend pages

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Nicholas Bellinger <[email protected]>

Part of commit 4442dc8a92b8f9ad8ee9e7f8438f4c04c03a22dc upstream.

This patch changes rd_allocate_sgl_table() to explicitly clear
ramdisk_mcp backend memory pages by passing __GFP_ZERO into
alloc_pages().

This addresses a potential security issue where reading from a
ramdisk_mcp could return sensitive information, and follows what
>= v3.15 does to explicitly clear ramdisk_mcp memory at backend
device initialization time.

Reported-by: Jorge Daniel Sequeira Matias <[email protected]>
Cc: Jorge Daniel Sequeira Matias <[email protected]>
Signed-off-by: Nicholas Bellinger <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/target/target_core_rd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/target/target_core_rd.c
+++ b/drivers/target/target_core_rd.c
@@ -179,7 +179,7 @@ static int rd_build_device_space(struct
- 1;

for (j = 0; j < sg_per_table; j++) {
- pg = alloc_pages(GFP_KERNEL, 0);
+ pg = alloc_pages(GFP_KERNEL | __GFP_ZERO, 0);
if (!pg) {
pr_err("Unable to allocate scatterlist"
" pages for struct rd_dev_sg_table\n");

2014-07-08 19:44:26

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 105/125] [SCSI] fix our current target reap infrastructure

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: James Bottomley <[email protected]>

commit e63ed0d7a98014fdfc2cfeb3f6dada313dcabb59 upstream.

This patch eliminates the reap_ref and replaces it with a proper kref.
On last put of this kref, the target is removed from visibility in
sysfs. The final call to scsi_target_reap() for the device is done from
__scsi_remove_device() and only if the device was made visible. This
ensures that the target disappears as soon as the last device is gone
rather than waiting until final release of the device (which is often
too long).

Reviewed-by: Alan Stern <[email protected]>
Tested-by: Sarah Sharp <[email protected]>
Signed-off-by: James Bottomley <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/scsi/scsi_scan.c | 99 ++++++++++++++++++++++++++++------------------
drivers/scsi/scsi_sysfs.c | 20 +++++++---
include/scsi/scsi_device.h | 3 +-
3 files changed, 75 insertions(+), 47 deletions(-)

--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -383,6 +383,31 @@ static struct scsi_target *__scsi_find_t
}

/**
+ * scsi_target_reap_ref_release - remove target from visibility
+ * @kref: the reap_ref in the target being released
+ *
+ * Called on last put of reap_ref, which is the indication that no device
+ * under this target is visible anymore, so render the target invisible in
+ * sysfs. Note: we have to be in user context here because the target reaps
+ * should be done in places where the scsi device visibility is being removed.
+ */
+static void scsi_target_reap_ref_release(struct kref *kref)
+{
+ struct scsi_target *starget
+ = container_of(kref, struct scsi_target, reap_ref);
+
+ transport_remove_device(&starget->dev);
+ device_del(&starget->dev);
+ starget->state = STARGET_DEL;
+ scsi_target_destroy(starget);
+}
+
+static void scsi_target_reap_ref_put(struct scsi_target *starget)
+{
+ kref_put(&starget->reap_ref, scsi_target_reap_ref_release);
+}
+
+/**
* scsi_alloc_target - allocate a new or find an existing target
* @parent: parent of the target (need not be a scsi host)
* @channel: target channel number (zero if no channels)
@@ -404,7 +429,7 @@ static struct scsi_target *scsi_alloc_ta
+ shost->transportt->target_size;
struct scsi_target *starget;
struct scsi_target *found_target;
- int error;
+ int error, ref_got;

starget = kzalloc(size, GFP_KERNEL);
if (!starget) {
@@ -413,7 +438,7 @@ static struct scsi_target *scsi_alloc_ta
}
dev = &starget->dev;
device_initialize(dev);
- starget->reap_ref = 1;
+ kref_init(&starget->reap_ref);
dev->parent = get_device(parent);
dev_set_name(dev, "target%d:%d:%d", shost->host_no, channel, id);
dev->bus = &scsi_bus_type;
@@ -453,29 +478,36 @@ static struct scsi_target *scsi_alloc_ta
return starget;

found:
- found_target->reap_ref++;
+ /*
+ * release routine already fired if kref is zero, so if we can still
+ * take the reference, the target must be alive. If we can't, it must
+ * be dying and we need to wait for a new target
+ */
+ ref_got = kref_get_unless_zero(&found_target->reap_ref);
+
spin_unlock_irqrestore(shost->host_lock, flags);
- if (found_target->state != STARGET_DEL) {
+ if (ref_got) {
put_device(dev);
return found_target;
}
- /* Unfortunately, we found a dying target; need to
- * wait until it's dead before we can get a new one */
+ /*
+ * Unfortunately, we found a dying target; need to wait until it's
+ * dead before we can get a new one. There is an anomaly here. We
+ * *should* call scsi_target_reap() to balance the kref_get() of the
+ * reap_ref above. However, since the target being released, it's
+ * already invisible and the reap_ref is irrelevant. If we call
+ * scsi_target_reap() we might spuriously do another device_del() on
+ * an already invisible target.
+ */
put_device(&found_target->dev);
- flush_scheduled_work();
+ /*
+ * length of time is irrelevant here, we just want to yield the CPU
+ * for a tick to avoid busy waiting for the target to die.
+ */
+ msleep(1);
goto retry;
}

-static void scsi_target_reap_usercontext(struct work_struct *work)
-{
- struct scsi_target *starget =
- container_of(work, struct scsi_target, ew.work);
-
- transport_remove_device(&starget->dev);
- device_del(&starget->dev);
- scsi_target_destroy(starget);
-}
-
/**
* scsi_target_reap - check to see if target is in use and destroy if not
* @starget: target to be checked
@@ -486,28 +518,11 @@ static void scsi_target_reap_usercontext
*/
void scsi_target_reap(struct scsi_target *starget)
{
- struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
- unsigned long flags;
- enum scsi_target_state state;
- int empty = 0;
-
- spin_lock_irqsave(shost->host_lock, flags);
- state = starget->state;
- if (--starget->reap_ref == 0 && list_empty(&starget->devices)) {
- empty = 1;
- starget->state = STARGET_DEL;
- }
- spin_unlock_irqrestore(shost->host_lock, flags);
-
- if (!empty)
- return;
-
- BUG_ON(state == STARGET_DEL);
- if (state == STARGET_CREATED)
+ BUG_ON(starget->state == STARGET_DEL);
+ if (starget->state == STARGET_CREATED)
scsi_target_destroy(starget);
else
- execute_in_process_context(scsi_target_reap_usercontext,
- &starget->ew);
+ scsi_target_reap_ref_put(starget);
}

/**
@@ -1532,6 +1547,10 @@ struct scsi_device *__scsi_add_device(st
}
mutex_unlock(&shost->scan_mutex);
scsi_autopm_put_target(starget);
+ /*
+ * paired with scsi_alloc_target(). Target will be destroyed unless
+ * scsi_probe_and_add_lun made an underlying device visible
+ */
scsi_target_reap(starget);
put_device(&starget->dev);

@@ -1612,8 +1631,10 @@ static void __scsi_scan_target(struct de

out_reap:
scsi_autopm_put_target(starget);
- /* now determine if the target has any children at all
- * and if not, nuke it */
+ /*
+ * paired with scsi_alloc_target(): determine if the target has
+ * any children at all and if not, nuke it
+ */
scsi_target_reap(starget);

put_device(&starget->dev);
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -331,17 +331,14 @@ static void scsi_device_dev_release_user
{
struct scsi_device *sdev;
struct device *parent;
- struct scsi_target *starget;
struct list_head *this, *tmp;
unsigned long flags;

sdev = container_of(work, struct scsi_device, ew.work);

parent = sdev->sdev_gendev.parent;
- starget = to_scsi_target(parent);

spin_lock_irqsave(sdev->host->host_lock, flags);
- starget->reap_ref++;
list_del(&sdev->siblings);
list_del(&sdev->same_target_siblings);
list_del(&sdev->starved_entry);
@@ -361,8 +358,6 @@ static void scsi_device_dev_release_user
/* NULL queue means the device can't be used */
sdev->request_queue = NULL;

- scsi_target_reap(scsi_target(sdev));
-
kfree(sdev->inquiry);
kfree(sdev);

@@ -977,6 +972,13 @@ void __scsi_remove_device(struct scsi_de
sdev->host->hostt->slave_destroy(sdev);
transport_destroy_device(dev);

+ /*
+ * Paired with the kref_get() in scsi_sysfs_initialize(). We have
+ * remoed sysfs visibility from the device, so make the target
+ * invisible if this was the last device underneath it.
+ */
+ scsi_target_reap(scsi_target(sdev));
+
put_device(dev);
}

@@ -1039,7 +1041,7 @@ void scsi_remove_target(struct device *d
continue;
if (starget->dev.parent == dev || &starget->dev == dev) {
/* assuming new targets arrive at the end */
- starget->reap_ref++;
+ kref_get(&starget->reap_ref);
spin_unlock_irqrestore(shost->host_lock, flags);
if (last)
scsi_target_reap(last);
@@ -1123,6 +1125,12 @@ void scsi_sysfs_device_initialize(struct
list_add_tail(&sdev->same_target_siblings, &starget->devices);
list_add_tail(&sdev->siblings, &shost->__devices);
spin_unlock_irqrestore(shost->host_lock, flags);
+ /*
+ * device can now only be removed via __scsi_remove_device() so hold
+ * the target. Target will be held in CREATED state until something
+ * beneath it becomes visible (in which case it moves to RUNNING)
+ */
+ kref_get(&starget->reap_ref);
}

int scsi_is_sdev_device(const struct device *dev)
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -239,7 +239,7 @@ struct scsi_target {
struct list_head siblings;
struct list_head devices;
struct device dev;
- unsigned int reap_ref; /* protected by the host lock */
+ struct kref reap_ref; /* last put renders target invisible */
unsigned int channel;
unsigned int id; /* target id ... replace
* scsi_device.id eventually */
@@ -261,7 +261,6 @@ struct scsi_target {
#define SCSI_DEFAULT_TARGET_BLOCKED 3

char scsi_level;
- struct execute_work ew;
enum scsi_target_state state;
void *hostdata; /* available to low-level driver */
unsigned long starget_data[0]; /* for the transport */

2014-07-08 19:44:24

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 108/125] MIPS: Cleanup flags in syscall flags handlers.

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Ralf Baechle <[email protected]>

commit e7f3b48af7be9f8007a224663a5b91340626fed5 upstream.

This will simplify further modifications.

Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/mips/include/asm/thread_info.h | 2 ++
arch/mips/kernel/scall32-o32.S | 2 +-
arch/mips/kernel/scall64-64.S | 2 +-
arch/mips/kernel/scall64-n32.S | 2 +-
arch/mips/kernel/scall64-o32.S | 2 +-
5 files changed, 6 insertions(+), 4 deletions(-)

--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -149,6 +149,8 @@ register struct thread_info *__current_t
#define _TIF_FPUBOUND (1<<TIF_FPUBOUND)
#define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH)

+#define _TIF_WORK_SYSCALL_ENTRY (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT)
+
/* work to do in syscall_trace_leave() */
#define _TIF_WORK_SYSCALL_EXIT (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT)

--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -52,7 +52,7 @@ NESTED(handle_sys, PT_SIZE, sp)

stack_done:
lw t0, TI_FLAGS($28) # syscall tracing enabled?
- li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+ li t1, _TIF_WORK_SYSCALL_ENTRY
and t0, t1
bnez t0, syscall_trace_entry # -> yes

--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -54,7 +54,7 @@ NESTED(handle_sys64, PT_SIZE, sp)

sd a3, PT_R26(sp) # save a3 for syscall restarting

- li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+ li t1, _TIF_WORK_SYSCALL_ENTRY
LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
and t0, t1, t0
bnez t0, syscall_trace_entry
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -53,7 +53,7 @@ NESTED(handle_sysn32, PT_SIZE, sp)

sd a3, PT_R26(sp) # save a3 for syscall restarting

- li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+ li t1, _TIF_WORK_SYSCALL_ENTRY
LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
and t0, t1, t0
bnez t0, n32_syscall_trace_entry
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -81,7 +81,7 @@ NESTED(handle_sys, PT_SIZE, sp)
PTR 4b, bad_stack
.previous

- li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+ li t1, _TIF_WORK_SYSCALL_ENTRY
LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
and t0, t1, t0
bnez t0, trace_a_syscall

2014-07-08 19:44:23

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 100/125] drm: fix NULL pointer access by wrong ioctl

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Zhaowei Yuan <[email protected]>

commit 1539fb9bd405ee32282ea0a38404f9e008ac5b7a upstream.

If user uses wrong ioctl command with _IOC_NONE and argument size
greater than 0, it can cause NULL pointer access from memset of line
463. If _IOC_NONE, don't memset to 0 for kdata.

Signed-off-by: Zhaowei Yuan <[email protected]>
Reviewed-by: David Herrmann <[email protected]>
Signed-off-by: Dave Airlie <[email protected]>
[bwh: Backported to 3.2: adjust indentation]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/drm_drv.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -456,8 +456,9 @@ long drm_ioctl(struct file *filp,
retcode = -EFAULT;
goto err_i1;
}
- } else
+ } else if (cmd & IOC_OUT) {
memset(kdata, 0, usize);
+ }

if (ioctl->flags & DRM_UNLOCKED)
retcode = func(dev, kdata, file_priv);

2014-07-08 19:46:57

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 110/125] netlink: rate-limit leftover bytes warning and print process name

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Michal Schmidt <[email protected]>

[ Upstream commit bfc5184b69cf9eeb286137640351c650c27f118a ]

Any process is able to send netlink messages with leftover bytes.
Make the warning rate-limited to prevent too much log spam.

The warning is supposed to help find userspace bugs, so print the
triggering command name to implicate the buggy program.

[v2: Use pr_warn_ratelimited instead of printk_ratelimited.]

Signed-off-by: Michal Schmidt <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
lib/nlattr.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

--- a/lib/nlattr.c
+++ b/lib/nlattr.c
@@ -12,6 +12,7 @@
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/string.h>
+#include <linux/ratelimit.h>
#include <linux/types.h>
#include <net/netlink.h>

@@ -197,8 +198,8 @@ int nla_parse(struct nlattr **tb, int ma
}

if (unlikely(rem > 0))
- printk(KERN_WARNING "netlink: %d bytes leftover after parsing "
- "attributes.\n", rem);
+ pr_warn_ratelimited("netlink: %d bytes leftover after parsing attributes in process `%s'.\n",
+ rem, current->comm);

err = 0;
errout:

2014-07-08 19:46:55

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 112/125] net: fix inet_getid() and ipv6_select_ident() bugs

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <[email protected]>

[ Upstream commit 39c36094d78c39e038c1e499b2364e13bce36f54 ]

I noticed we were sending wrong IPv4 ID in TCP flows when MTU discovery
is disabled.
Note how GSO/TSO packets do not have monotonically incrementing ID.

06:37:41.575531 IP (id 14227, proto: TCP (6), length: 4396)
06:37:41.575534 IP (id 14272, proto: TCP (6), length: 65212)
06:37:41.575544 IP (id 14312, proto: TCP (6), length: 57972)
06:37:41.575678 IP (id 14317, proto: TCP (6), length: 7292)
06:37:41.575683 IP (id 14361, proto: TCP (6), length: 63764)

It appears I introduced this bug in linux-3.1.

inet_getid() must return the old value of peer->ip_id_count,
not the new one.

Lets revert this part, and remove the prevention of
a null identification field in IPv6 Fragment Extension Header,
which is dubious and not even done properly.

Fixes: 87c48fa3b463 ("ipv6: make fragment identifications less predictable")
Signed-off-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
include/net/inetpeer.h | 9 +--------
net/ipv6/ip6_output.c | 11 +++--------
2 files changed, 4 insertions(+), 16 deletions(-)

--- a/include/net/inetpeer.h
+++ b/include/net/inetpeer.h
@@ -115,16 +115,9 @@ static inline void inet_peer_refcheck(co
/* can be called with or without local BH being disabled */
static inline int inet_getid(struct inet_peer *p, int more)
{
- int old, new;
more++;
inet_peer_refcheck(p);
- do {
- old = atomic_read(&p->ip_id_count);
- new = old + more;
- if (!new)
- new = 1;
- } while (atomic_cmpxchg(&p->ip_id_count, old, new) != old);
- return new;
+ return atomic_add_return(more, &p->ip_id_count) - more;
}

#endif /* _NET_INETPEER_H */
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -612,7 +612,7 @@ int ip6_find_1stfragopt(struct sk_buff *
void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt)
{
static atomic_t ipv6_fragmentation_id;
- int old, new;
+ int ident;

if (rt && !(rt->dst.flags & DST_NOPEER)) {
struct inet_peer *peer;
@@ -625,13 +625,8 @@ void ipv6_select_ident(struct frag_hdr *
return;
}
}
- do {
- old = atomic_read(&ipv6_fragmentation_id);
- new = old + 1;
- if (!new)
- new = 1;
- } while (atomic_cmpxchg(&ipv6_fragmentation_id, old, new) != old);
- fhdr->identification = htonl(new);
+ ident = atomic_inc_return(&ipv6_fragmentation_id);
+ fhdr->identification = htonl(ident);
}

int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))

2014-07-08 19:46:54

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 117/125] [SCSI] Fix spurious request sense in error handling

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: James Bottomley <[email protected]>

commit d555a2abf3481f81303d835046a5ec2c4fb3ca8e upstream.

We unconditionally execute scsi_eh_get_sense() to make sure all failed
commands that should have sense attached, do. However, the routine forgets
that some commands, because of the way they fail, will not have any sense code
... we should not bother them with a REQUEST_SENSE command. Fix this by
testing to see if we actually got a CHECK_CONDITION return and skip asking for
sense if we don't.

Tested-by: Alan Stern <[email protected]>
Signed-off-by: James Bottomley <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/scsi/scsi_error.c | 9 +++++++++
1 file changed, 9 insertions(+)

--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -902,6 +902,15 @@ int scsi_eh_get_sense(struct list_head *
SCSI_SENSE_VALID(scmd))
continue;

+ if (status_byte(scmd->result) != CHECK_CONDITION)
+ /*
+ * don't request sense if there's no check condition
+ * status because the error we're processing isn't one
+ * that has a sense code (and some devices get
+ * confused by sense requests out of the blue)
+ */
+ continue;
+
SCSI_LOG_ERROR_RECOVERY(2, scmd_printk(KERN_INFO, scmd,
"%s: requesting sense\n",
current->comm));

2014-07-08 19:47:44

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 121/125] Documentation: Update stable address in Chinese and Japanese translations

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Geert Uytterhoeven <[email protected]>

commit 98b0f811aade1b7c6e7806c86aa0befd5919d65f upstream.

The English and Korean translations were updated, the Chinese and Japanese
weren't.

Signed-off-by: Geert Uytterhoeven <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
Documentation/ja_JP/HOWTO | 2 +-
Documentation/ja_JP/stable_kernel_rules.txt | 6 +++---
Documentation/zh_CN/HOWTO | 2 +-
Documentation/zh_CN/stable_kernel_rules.txt | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)

--- a/Documentation/ja_JP/HOWTO
+++ b/Documentation/ja_JP/HOWTO
@@ -315,7 +315,7 @@
もし、2.6.x.y カーネルが存在しない場合には、番号が一番大きい 2.6.x が
最新の安定版カーネルです。

-2.6.x.y は "stable" チーム <[email protected]> でメンテされており、必
+2.6.x.y は "stable" チーム <[email protected]> でメンテされており、必
要に応じてリリースされます。通常のリリース期間は 2週間毎ですが、差し迫っ
た問題がなければもう少し長くなることもあります。セキュリティ関連の問題
の場合はこれに対してだいたいの場合、すぐにリリースがされます。
--- a/Documentation/ja_JP/stable_kernel_rules.txt
+++ b/Documentation/ja_JP/stable_kernel_rules.txt
@@ -50,16 +50,16 @@

-stable ツリーにパッチを送付する手続き-

- - 上記の規則に従っているかを確認した後に、[email protected] にパッチ
+ - 上記の規則に従っているかを確認した後に、[email protected] にパッチ
を送る。
- 送信者はパッチがキューに受け付けられた際には ACK を、却下された場合
には NAK を受け取る。この反応は開発者たちのスケジュールによって、数
日かかる場合がある。
- もし受け取られたら、パッチは他の開発者たちと関連するサブシステムの
メンテナーによるレビューのために -stable キューに追加される。
- - パッチに [email protected] のアドレスが付加されているときには、それ
+ - パッチに [email protected] のアドレスが付加されているときには、それ
が Linus のツリーに入る時に自動的に stable チームに email される。
- - セキュリティパッチはこのエイリアス ([email protected]) に送られるべ
+ - セキュリティパッチはこのエイリアス ([email protected]) に送られるべ
きではなく、代わりに [email protected] のアドレスに送られる。

レビューサイクル-
--- a/Documentation/zh_CN/HOWTO
+++ b/Documentation/zh_CN/HOWTO
@@ -237,7 +237,7 @@
如果没有2.6.x.y版本内核存在,那么最新的2.6.x版本内核就相当于是当前的稳定
版内核。

-2.6.x.y版本由“稳定版”小组(邮件地址<[email protected]>)维护,一般隔周发
+2.6.x.y版本由“稳定版”小组(邮件地址<[email protected]>)维护,一般隔周发
布新版本。

内核源码中的Documentation/stable_kernel_rules.txt文件具体描述了可被稳定
--- a/Documentation/zh_CN/stable_kernel_rules.txt
+++ b/Documentation/zh_CN/stable_kernel_rules.txt
@@ -42,7 +42,7 @@

向稳定版代码树提交补丁的过程:

- - 在确认了补丁符合以上的规则后,将补丁发送到[email protected]
+ - 在确认了补丁符合以上的规则后,将补丁发送到[email protected]
- 如果补丁被接受到队列里,发送者会收到一个ACK回复,如果没有被接受,收
到的是NAK回复。回复需要几天的时间,这取决于开发者的时间安排。
- 被接受的补丁会被加到稳定版本队列里,等待其他开发者的审查。

2014-07-08 19:47:45

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 010/125] reiserfs: call truncate_setsize under tailpack mutex

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Jeff Mahoney <[email protected]>

commit 22e7478ddbcb670e33fab72d0bbe7c394c3a2c84 upstream.

Prior to commit 0e4f6a791b1e (Fix reiserfs_file_release()), reiserfs
truncates serialized on i_mutex. They mostly still do, with the exception
of reiserfs_file_release. That blocks out other writers via the tailpack
mutex and the inode openers counter adjusted in reiserfs_file_open.

However, NFS will call reiserfs_setattr without having called ->open, so
we end up with a race when nfs is calling ->setattr while another
process is releasing the file. Ultimately, it triggers the
BUG_ON(inode->i_size != new_file_size) check in maybe_indirect_to_direct.

The solution is to pull the lock into reiserfs_setattr to encompass the
truncate_setsize call as well.

Signed-off-by: Jeff Mahoney <[email protected]>
Signed-off-by: Jan Kara <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/reiserfs/inode.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -3211,8 +3211,14 @@ int reiserfs_setattr(struct dentry *dent
attr->ia_size != i_size_read(inode)) {
error = inode_newsize_ok(inode, attr->ia_size);
if (!error) {
+ /*
+ * Could race against reiserfs_file_release
+ * if called from NFS, so take tailpack mutex.
+ */
+ mutex_lock(&REISERFS_I(inode)->tailpack);
truncate_setsize(inode, attr->ia_size);
- reiserfs_vfs_truncate_file(inode);
+ reiserfs_truncate_file(inode, 1);
+ mutex_unlock(&REISERFS_I(inode)->tailpack);
}
}

2014-07-08 19:48:36

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 009/125] reiserfs: drop vmtruncate

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Marco Stornelli <[email protected]>

commit cfac4b47c664e207740880d6492938761c53d74b upstream.

Removed vmtruncate

Signed-off-by: Marco Stornelli <[email protected]>
Reviewed-by: Jan Kara <[email protected]>
Signed-off-by: Al Viro <[email protected]>
[bwh: Backported to 3.2: adjust filename]
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/reiserfs/file.c | 3 +--
fs/reiserfs/inode.c | 15 +++++++++++----
include/linux/reiserfs_fs.h | 1 +
3 files changed, 13 insertions(+), 6 deletions(-)

--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -126,7 +126,7 @@ static int reiserfs_file_open(struct ino
return err;
}

-static void reiserfs_vfs_truncate_file(struct inode *inode)
+void reiserfs_vfs_truncate_file(struct inode *inode)
{
mutex_lock(&(REISERFS_I(inode)->tailpack));
reiserfs_truncate_file(inode, 1);
@@ -312,7 +312,6 @@ const struct file_operations reiserfs_fi
};

const struct inode_operations reiserfs_file_inode_operations = {
- .truncate = reiserfs_vfs_truncate_file,
.setattr = reiserfs_setattr,
.setxattr = reiserfs_setxattr,
.getxattr = reiserfs_getxattr,
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -3091,8 +3091,10 @@ static ssize_t reiserfs_direct_IO(int rw
loff_t isize = i_size_read(inode);
loff_t end = offset + iov_length(iov, nr_segs);

- if (end > isize)
- vmtruncate(inode, isize);
+ if ((end > isize) && inode_newsize_ok(inode, isize) == 0) {
+ truncate_setsize(inode, isize);
+ reiserfs_vfs_truncate_file(inode);
+ }
}

return ret;
@@ -3206,8 +3208,13 @@ int reiserfs_setattr(struct dentry *dent
*/
reiserfs_write_unlock_once(inode->i_sb, depth);
if ((attr->ia_valid & ATTR_SIZE) &&
- attr->ia_size != i_size_read(inode))
- error = vmtruncate(inode, attr->ia_size);
+ attr->ia_size != i_size_read(inode)) {
+ error = inode_newsize_ok(inode, attr->ia_size);
+ if (!error) {
+ truncate_setsize(inode, attr->ia_size);
+ reiserfs_vfs_truncate_file(inode);
+ }
+ }

if (!error) {
setattr_copy(inode, attr);
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -1882,6 +1882,7 @@ struct reiserfs_transaction_handle *reis
*,
int count);
int reiserfs_end_persistent_transaction(struct reiserfs_transaction_handle *);
+void reiserfs_vfs_truncate_file(struct inode *inode);
int reiserfs_commit_page(struct inode *inode, struct page *page,
unsigned from, unsigned to);
int reiserfs_flush_old_commits(struct super_block *);

2014-07-08 19:48:35

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 013/125] USB: Avoid runtime suspend loops for HCDs that can't handle suspend/resume

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Alan Stern <[email protected]>

commit 8ef42ddd9a53b73e6fc3934278710c27f80f324f upstream.

Not all host controller drivers have bus-suspend and bus-resume
methods. When one doesn't, it will cause problems if runtime PM is
enabled in the kernel. The PM core will attempt to suspend the
controller's root hub, the suspend will fail because there is no
bus-suspend routine, and a -EBUSY error code will be returned to the
PM core. This will cause the suspend attempt to be repeated shortly
thereafter, in a never-ending loop.

Part of the problem is that the original error code -ENOENT gets
changed to -EBUSY in usb_runtime_suspend(), on the grounds that the PM
core will interpret -ENOENT as meaning that the root hub has gotten
into a runtime-PM error state. While this change is appropriate for
real USB devices, it's not such a good idea for a root hub. In fact,
considering the root hub to be in a runtime-PM error state would not
be far from the truth. Therefore this patch updates
usb_runtime_suspend() so that it adjusts error codes only for
non-root-hub devices.

Furthermore, the patch attempts to prevent the problem from occurring
in the first place by not enabling runtime PM by default for root hubs
whose host controller driver doesn't have bus_suspend and bus_resume
methods.

Signed-off-by: Alan Stern <[email protected]>
Reported-by: Will Deacon <[email protected]>
Tested-by: Will Deacon <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[bwh: Backported to 3.2: runtime PM is also not supported for USB 3.0
non-root hubs]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1686,10 +1686,13 @@ int usb_runtime_suspend(struct device *d
if (status == -EAGAIN || status == -EBUSY)
usb_mark_last_busy(udev);

- /* The PM core reacts badly unless the return code is 0,
- * -EAGAIN, or -EBUSY, so always return -EBUSY on an error.
+ /*
+ * The PM core reacts badly unless the return code is 0,
+ * -EAGAIN, or -EBUSY, so always return -EBUSY on an error
+ * (except for root hubs, because they don't suspend through
+ * an upstream port like other USB devices).
*/
- if (status != 0)
+ if (status != 0 && udev->parent)
return -EBUSY;
return status;
}
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1370,14 +1370,24 @@ static int hub_probe(struct usb_interfac
desc = intf->cur_altsetting;
hdev = interface_to_usbdev(intf);

- /* Hubs have proper suspend/resume support. USB 3.0 device suspend is
+ /*
+ * Hubs have proper suspend/resume support, except for root hubs
+ * where the controller driver doesn't have bus_suspend and
+ * bus_resume methods. Also, USB 3.0 device suspend is
* different from USB 2.0/1.1 device suspend, and unfortunately we
* don't support it yet. So leave autosuspend disabled for USB 3.0
* external hubs for now. Enable autosuspend for USB 3.0 roothubs,
* since that isn't a "real" hub.
*/
- if (!hub_is_superspeed(hdev) || !hdev->parent)
- usb_enable_autosuspend(hdev);
+ if (hdev->parent) { /* normal device */
+ if (!hub_is_superspeed(hdev))
+ usb_enable_autosuspend(hdev);
+ } else { /* root hub */
+ const struct hc_driver *drv = bus_to_hcd(hdev->bus)->driver;
+
+ if (drv->bus_suspend && drv->bus_resume)
+ usb_enable_autosuspend(hdev);
+ }

if (hdev->level == MAX_TOPO_LEVEL) {
dev_err(&intf->dev,

2014-07-08 19:48:34

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 123/125] skbuff: add an api to orphan frags

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: "Michael S. Tsirkin" <[email protected]>

commit a353e0ce0fd42d8859260666d1e9b10f2abd4698 upstream.

Many places do
if ((skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY))
skb_copy_ubufs(skb, gfp_mask);
to copy and invoke frag destructors if necessary.
Add an inline helper for this.

Signed-off-by: Michael S. Tsirkin <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
include/linux/skbuff.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)

--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1633,6 +1633,22 @@ static inline void skb_orphan(struct sk_
}

/**
+ * skb_orphan_frags - orphan the frags contained in a buffer
+ * @skb: buffer to orphan frags from
+ * @gfp_mask: allocation mask for replacement pages
+ *
+ * For each frag in the SKB which needs a destructor (i.e. has an
+ * owner) create a copy of that frag and release the original
+ * page by calling the destructor.
+ */
+static inline int skb_orphan_frags(struct sk_buff *skb, gfp_t gfp_mask)
+{
+ if (likely(!(skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY)))
+ return 0;
+ return skb_copy_ubufs(skb, gfp_mask);
+}
+
+/**
* __skb_queue_purge - empty a list
* @list: list to empty
*

2014-07-08 19:48:32

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 015/125] Input: synaptics - T540p - unify with other LEN0034 models

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Hans de Goede <[email protected]>

commit 6d396ede224dc596d92d7cab433713536e68916c upstream.

The T540p has a touchpad with pnp-id LEN0034, all the models with this
pnp-id have the same min/max values, except the T540p where the values are
slightly off. Fix them to be identical.

This is a preparation patch for simplifying the quirk table.

Signed-off-by: Hans de Goede <[email protected]>
Signed-off-by: Dmitry Torokhov <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/input/mouse/synaptics.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -1431,7 +1431,7 @@ static const struct dmi_system_id min_ma
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T540"),
},
- .driver_data = (int []){1024, 5056, 2058, 4832},
+ .driver_data = (int []){1024, 5112, 2024, 4832},
},
{
/* Lenovo ThinkPad L540 */

2014-07-08 19:49:35

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.2 001/125] mm: highmem: don't treat PKMAP_ADDR(LAST_PKMAP) as a highmem address

3.2.61-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Will Deacon <[email protected]>

commit 498c2280212327858e521e9d21345d4cc2637f54 upstream.

kmap_to_page returns the corresponding struct page for a virtual address
of an arbitrary mapping. This works by checking whether the address
falls in the pkmap region and using the pkmap page tables instead of the
linear mapping if appropriate.

Unfortunately, the bounds checking means that PKMAP_ADDR(LAST_PKMAP) is
incorrectly treated as a highmem address and we can end up walking off
the end of pkmap_page_table and subsequently passing junk to pte_page.

This patch fixes the bound check to stay within the pkmap tables.

Signed-off-by: Will Deacon <[email protected]>
Cc: Mel Gorman <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
mm/highmem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/highmem.c b/mm/highmem.c
index d517cd1..2da13a5 100644
--- a/mm/highmem.c
+++ b/mm/highmem.c
@@ -98,7 +98,7 @@ struct page *kmap_to_page(void *vaddr)
{
unsigned long addr = (unsigned long)vaddr;

- if (addr >= PKMAP_ADDR(0) && addr <= PKMAP_ADDR(LAST_PKMAP)) {
+ if (addr >= PKMAP_ADDR(0) && addr < PKMAP_ADDR(LAST_PKMAP)) {
int i = (addr - PKMAP_ADDR(0)) >> PAGE_SHIFT;
return pte_page(pkmap_page_table[i]);
}

2014-07-08 20:13:01

by Guenter Roeck

[permalink] [raw]
Subject: Re: [PATCH 3.2 000/125] 3.2.61-rc1 review

On 07/08/2014 12:01 PM, Ben Hutchings wrote:
> This is the start of the stable review cycle for the 3.2.61 release.
> There are 125 patches in this series, which will be posted as responses
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Thu Jul 10 19:01:49 UTC 2014.
> Anything received after that time might be too late.
>

Ben,

I am seeing a large number of build failures.

lib/nlattr.c: In function 'nla_parse':
lib/nlattr.c:201:3: error: dereferencing pointer to incomplete type
make[1]: *** [lib/nlattr.o] Error 1
make[1]: *** Waiting for unfinished jobs....

i386:defconfig is affected, so you should be able to test with it.
Build for x86_64 passes.

Guenter

2014-07-08 20:47:33

by Hugh Dickins

[permalink] [raw]
Subject: Re: [PATCH 3.2 099/125] mm: fix crashes from mbind() merging vmas

On Tue, 8 Jul 2014, Ben Hutchings wrote:

> 3.2.61-rc1 review patch. If anyone has any objections, please let me know.
>
> ------------------
>
> From: Hugh Dickins <[email protected]>
>
> commit d05f0cdcbe6388723f1900c549b4850360545201 upstream.
>
> In v2.6.34 commit 9d8cebd4bcd7 ("mm: fix mbind vma merge problem")
> introduced vma merging to mbind(), but it should have also changed the
> convention of passing start vma from queue_pages_range() (formerly
> check_range()) to new_vma_page(): vma merging may have already freed
> that structure, resulting in BUG at mm/mempolicy.c:1738 and probably
> worse crashes.
>
> Fixes: 9d8cebd4bcd7 ("mm: fix mbind vma merge problem")
> Reported-by: Naoya Horiguchi <[email protected]>
> Tested-by: Naoya Horiguchi <[email protected]>
> Signed-off-by: Hugh Dickins <[email protected]>
> Acked-by: Christoph Lameter <[email protected]>
> Cc: KOSAKI Motohiro <[email protected]>
> Cc: Minchan Kim <[email protected]>
> Signed-off-by: Andrew Morton <[email protected]>
> Signed-off-by: Linus Torvalds <[email protected]>
> [bwh: Backported to 3.2:
> - Adjust context
> - Keep the same arguments to migrate_pages() except for private=start]
> Signed-off-by: Ben Hutchings <[email protected]>
> ---
> mm/mempolicy.c | 46 ++++++++++++++++++++--------------------------
> 1 file changed, 20 insertions(+), 26 deletions(-)
>
> --- a/mm/mempolicy.c
> +++ b/mm/mempolicy.c
> @@ -566,24 +566,23 @@ static inline int check_pgd_range(struct
> * If pagelist != NULL then isolate pages from the LRU and
> * put them on the pagelist.
> */
> -static struct vm_area_struct *
> +static int
> check_range(struct mm_struct *mm, unsigned long start, unsigned long end,
> const nodemask_t *nodes, unsigned long flags, void *private)
> {
> - int err;
> - struct vm_area_struct *first, *vma, *prev;
> -
> + int err = 0;
> + struct vm_area_struct *vma, *prev;
>
> - first = find_vma(mm, start);
> - if (!first)
> - return ERR_PTR(-EFAULT);
> + vma = find_vma(mm, start);
> + if (!vma)
> + return -EFAULT;
> prev = NULL;
> - for (vma = first; vma && vma->vm_start < end; vma = vma->vm_next) {
> + for (; vma && vma->vm_start < end; vma = vma->vm_next) {
> if (!(flags & MPOL_MF_DISCONTIG_OK)) {
> if (!vma->vm_next && vma->vm_end < end)
> - return ERR_PTR(-EFAULT);
> + return -EFAULT;
> if (prev && prev->vm_end < vma->vm_start)
> - return ERR_PTR(-EFAULT);
> + return -EFAULT;
> }
> if (!is_vm_hugetlb_page(vma) &&
> ((flags & MPOL_MF_STRICT) ||
> @@ -597,14 +596,12 @@ check_range(struct mm_struct *mm, unsign
> start = vma->vm_start;
> err = check_pgd_range(vma, start, endvma, nodes,
> flags, private);
> - if (err) {
> - first = ERR_PTR(err);
> + if (err)
> break;
> - }
> }
> prev = vma;
> }
> - return first;
> + return err;
> }
>
> /*
> @@ -1060,16 +1057,17 @@ out:
>
> /*
> * Allocate a new page for page migration based on vma policy.
> - * Start assuming that page is mapped by vma pointed to by @private.
> + * Start by assuming the page is mapped by the same vma as contains @start.
> * Search forward from there, if not. N.B., this assumes that the
> * list of pages handed to migrate_pages()--which is how we get here--
> * is in virtual address order.
> */
> -static struct page *new_vma_page(struct page *page, unsigned long private, int **x)
> +static struct page *new_page(struct page *page, unsigned long start, int **x)
> {
> - struct vm_area_struct *vma = (struct vm_area_struct *)private;
> + struct vm_area_struct *vma;
> unsigned long uninitialized_var(address);
>
> + vma = find_vma(current->mm, start);
> while (vma) {
> address = page_address_in_vma(page, vma);
> if (address != -EFAULT)
> @@ -1095,7 +1093,7 @@ int do_migrate_pages(struct mm_struct *m
> return -ENOSYS;
> }
>
> -static struct page *new_vma_page(struct page *page, unsigned long private, int **x)
> +static struct page *new_page(struct page *page, unsigned long start, int **x)
> {
> return NULL;
> }
> @@ -1105,7 +1103,6 @@ static long do_mbind(unsigned long start
> unsigned short mode, unsigned short mode_flags,
> nodemask_t *nmask, unsigned long flags)
> {
> - struct vm_area_struct *vma;
> struct mm_struct *mm = current->mm;
> struct mempolicy *new;
> unsigned long end;
> @@ -1169,19 +1166,16 @@ static long do_mbind(unsigned long start
> if (err)
> goto mpol_out;
>
> - vma = check_range(mm, start, end, nmask,
> + err = check_range(mm, start, end, nmask,
> flags | MPOL_MF_INVERT, &pagelist);
> -
> - err = PTR_ERR(vma);
> - if (!IS_ERR(vma)) {
> + if (!err) {
> int nr_failed = 0;
>
> err = mbind_range(mm, start, end, new);
>
> if (!list_empty(&pagelist)) {
> - nr_failed = migrate_pages(&pagelist, new_vma_page,
> - (unsigned long)vma,
> - false, true);
> + nr_failed = migrate_pages(&pagelist, new_page,
> + start, false, true);
> if (nr_failed)
> putback_lru_pages(&pagelist);
> }

I don't think that's correct, I can't see a change to the
"vma = check_range(" in migrate_to_node() which 3.2 and 3.4 trees have.
Does it build (without warning) with CONFIG_NUMA and CONFIG_MIGRATION?
I expect this version I sent yesterday for 3.4.98 will be good for 3.2:

------------------ version for 3.4.98 ------------------

>From d05f0cdcbe6388723f1900c549b4850360545201 Mon Sep 17 00:00:00 2001
From: Hugh Dickins <[email protected]>
Date: Mon, 23 Jun 2014 13:22:07 -0700
Subject: [PATCH] mm: fix crashes from mbind() merging vmas

In v2.6.34 commit 9d8cebd4bcd7 ("mm: fix mbind vma merge problem")
introduced vma merging to mbind(), but it should have also changed the
convention of passing start vma from queue_pages_range() (formerly
check_range()) to new_vma_page(): vma merging may have already freed
that structure, resulting in BUG at mm/mempolicy.c:1738 and probably
worse crashes.

Fixes: 9d8cebd4bcd7 ("mm: fix mbind vma merge problem")
Reported-by: Naoya Horiguchi <[email protected]>
Tested-by: Naoya Horiguchi <[email protected]>
Signed-off-by: Hugh Dickins <[email protected]>
Acked-by: Christoph Lameter <[email protected]>
Cc: KOSAKI Motohiro <[email protected]>
Cc: Minchan Kim <[email protected]>
Cc: <[email protected]> [2.6.34+]
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>

--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -566,24 +566,24 @@ static inline int check_pgd_range(struct
* If pagelist != NULL then isolate pages from the LRU and
* put them on the pagelist.
*/
-static struct vm_area_struct *
+static int
check_range(struct mm_struct *mm, unsigned long start, unsigned long end,
const nodemask_t *nodes, unsigned long flags, void *private)
{
- int err;
- struct vm_area_struct *first, *vma, *prev;
+ int err = 0;
+ struct vm_area_struct *vma, *prev;


- first = find_vma(mm, start);
- if (!first)
- return ERR_PTR(-EFAULT);
+ vma = find_vma(mm, start);
+ if (!vma)
+ return -EFAULT;
prev = NULL;
- for (vma = first; vma && vma->vm_start < end; vma = vma->vm_next) {
+ for (; vma && vma->vm_start < end; vma = vma->vm_next) {
if (!(flags & MPOL_MF_DISCONTIG_OK)) {
if (!vma->vm_next && vma->vm_end < end)
- return ERR_PTR(-EFAULT);
+ return -EFAULT;
if (prev && prev->vm_end < vma->vm_start)
- return ERR_PTR(-EFAULT);
+ return -EFAULT;
}
if (!is_vm_hugetlb_page(vma) &&
((flags & MPOL_MF_STRICT) ||
@@ -597,14 +597,12 @@ check_range(struct mm_struct *mm, unsign
start = vma->vm_start;
err = check_pgd_range(vma, start, endvma, nodes,
flags, private);
- if (err) {
- first = ERR_PTR(err);
+ if (err)
break;
- }
}
prev = vma;
}
- return first;
+ return err;
}

/*
@@ -945,16 +943,15 @@ static int migrate_to_node(struct mm_str
{
nodemask_t nmask;
LIST_HEAD(pagelist);
- int err = 0;
- struct vm_area_struct *vma;
+ int err;

nodes_clear(nmask);
node_set(source, nmask);

- vma = check_range(mm, mm->mmap->vm_start, mm->task_size, &nmask,
+ err = check_range(mm, mm->mmap->vm_start, mm->task_size, &nmask,
flags | MPOL_MF_DISCONTIG_OK, &pagelist);
- if (IS_ERR(vma))
- return PTR_ERR(vma);
+ if (err)
+ return err;

if (!list_empty(&pagelist)) {
err = migrate_pages(&pagelist, new_node_page, dest,
@@ -1058,16 +1055,17 @@ out:

/*
* Allocate a new page for page migration based on vma policy.
- * Start assuming that page is mapped by vma pointed to by @private.
+ * Start by assuming the page is mapped by the same vma as contains @start.
* Search forward from there, if not. N.B., this assumes that the
* list of pages handed to migrate_pages()--which is how we get here--
* is in virtual address order.
*/
-static struct page *new_vma_page(struct page *page, unsigned long private, int **x)
+static struct page *new_page(struct page *page, unsigned long start, int **x)
{
- struct vm_area_struct *vma = (struct vm_area_struct *)private;
+ struct vm_area_struct *vma;
unsigned long uninitialized_var(address);

+ vma = find_vma(current->mm, start);
while (vma) {
address = page_address_in_vma(page, vma);
if (address != -EFAULT)
@@ -1093,7 +1091,7 @@ int do_migrate_pages(struct mm_struct *m
return -ENOSYS;
}

-static struct page *new_vma_page(struct page *page, unsigned long private, int **x)
+static struct page *new_page(struct page *page, unsigned long start, int **x)
{
return NULL;
}
@@ -1103,7 +1101,6 @@ static long do_mbind(unsigned long start
unsigned short mode, unsigned short mode_flags,
nodemask_t *nmask, unsigned long flags)
{
- struct vm_area_struct *vma;
struct mm_struct *mm = current->mm;
struct mempolicy *new;
unsigned long end;
@@ -1167,19 +1164,17 @@ static long do_mbind(unsigned long start
if (err)
goto mpol_out;

- vma = check_range(mm, start, end, nmask,
+ err = check_range(mm, start, end, nmask,
flags | MPOL_MF_INVERT, &pagelist);

- err = PTR_ERR(vma);
- if (!IS_ERR(vma)) {
+ if (!err) {
int nr_failed = 0;

err = mbind_range(mm, start, end, new);

if (!list_empty(&pagelist)) {
- nr_failed = migrate_pages(&pagelist, new_vma_page,
- (unsigned long)vma,
- false, true);
+ nr_failed = migrate_pages(&pagelist, new_page,
+ start, false, true);
if (nr_failed)
putback_lru_pages(&pagelist);
}

2014-07-08 21:28:12

by Hugh Dickins

[permalink] [raw]
Subject: Re: [PATCH 3.2 099/125] mm: fix crashes from mbind() merging vmas

On Tue, 8 Jul 2014, Hugh Dickins wrote:
> On Tue, 8 Jul 2014, Ben Hutchings wrote:
>
> > 3.2.61-rc1 review patch. If anyone has any objections, please let me know.
> >
> > ------------------
> >
> > From: Hugh Dickins <[email protected]>
> >
> > commit d05f0cdcbe6388723f1900c549b4850360545201 upstream.
>
> I don't think that's correct, I can't see a change to the
> "vma = check_range(" in migrate_to_node() which 3.2 and 3.4 trees have.
> Does it build (without warning) with CONFIG_NUMA and CONFIG_MIGRATION?
> I expect this version I sent yesterday for 3.4.98 will be good for 3.2:

Hah, I now see that 098/125 in your series removes precisely the "vma = "
I was calling attention to. So all should be okay and you can ignore me.

Hugh

2014-07-09 01:27:41

by Guenter Roeck

[permalink] [raw]
Subject: Re: [PATCH 3.2 000/125] 3.2.61-rc1 review

On 07/08/2014 12:01 PM, Ben Hutchings wrote:
> This is the start of the stable review cycle for the 3.2.61 release.
> There are 125 patches in this series, which will be posted as responses
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Thu Jul 10 19:01:49 UTC 2014.
> Anything received after that time might be too late.
>

Build results:
total: 109 pass: 71 fail: 38
Failed builds:
alpha:allmodconfig
arm:defconfig
arm:imx_v4_v5_defconfig
arm:mxs_defconfig
arm:dove_defconfig
arm:kirkwood_defconfig
arm:omap2plus_defconfig
arm:tegra_defconfig
arm:u8500_defconfig
arm:at91sam9rl_defconfig
arm:pxa910_defconfig
arm:mackerel_defconfig
arm:ixp4xx_defconfig
arm:vexpress_defconfig
arm:msm_defconfig
arm:at91rm9200_defconfig
arm:at91sam9263_defconfig
arm:at91sam9g45_defconfig
arm:assabet_defconfig
i386:defconfig
i386:allyesconfig
i386:allmodconfig
m32r:defconfig
microblaze:mmu_defconfig
microblaze:nommu_defconfig
mips:defconfig
mips:allmodconfig
mips:bcm47xx_defconfig
mips:bcm63xx_defconfig
mips:ar7_defconfig
mips:fuloong2e_defconfig
mips:malta_defconfig
score:defconfig
sparc64:allmodconfig
um:defconfig
unicore32:defconfig
xtensa:defconfig
xtensa:allmodconfig

Qemu images fail to build for mips, mips64, and x86.

Build error seems to be always the same.

lib/nlattr.c: In function 'nla_parse':
lib/nlattr.c:201:3: error: dereferencing pointer to incomplete type
make[1]: *** [lib/nlattr.o] Error 1

Culprit is bfc5184b69 (netlink: rate-limit leftover bytes warning
and print process name). In 3.2, it is necessary to include <linux/sched.h>
explicitly to get the definition of 'struct task_struct'.

Details are available at http://server.roeck-us.net:8010/builders.

Guenter

2014-07-09 01:54:16

by Ben Hutchings

[permalink] [raw]
Subject: Re: [PATCH 3.2 099/125] mm: fix crashes from mbind() merging vmas

On Tue, 2014-07-08 at 14:26 -0700, Hugh Dickins wrote:
> On Tue, 8 Jul 2014, Hugh Dickins wrote:
> > On Tue, 8 Jul 2014, Ben Hutchings wrote:
> >
> > > 3.2.61-rc1 review patch. If anyone has any objections, please let me know.
> > >
> > > ------------------
> > >
> > > From: Hugh Dickins <[email protected]>
> > >
> > > commit d05f0cdcbe6388723f1900c549b4850360545201 upstream.
> >
> > I don't think that's correct, I can't see a change to the
> > "vma = check_range(" in migrate_to_node() which 3.2 and 3.4 trees have.
> > Does it build (without warning) with CONFIG_NUMA and CONFIG_MIGRATION?
> > I expect this version I sent yesterday for 3.4.98 will be good for 3.2:
>
> Hah, I now see that 098/125 in your series

Which, for anyone who missed it, was commit 082708072a42, 'mm: revert
0def08e3 ("mm/mempolicy.c: check return code of check_range")'.

> removes precisely the "vma = "
> I was calling attention to. So all should be okay and you can ignore me.

Right - of course I'm assuming that the reasoning given for that revert
is valid for 3.2.

Ben.

--
Ben Hutchings
All the simple programs have been written, and all the good names taken.


Attachments:
signature.asc (811.00 B)
This is a digitally signed message part

2014-07-09 02:01:32

by Ben Hutchings

[permalink] [raw]
Subject: Re: [PATCH 3.2 000/125] 3.2.61-rc1 review

On Tue, 2014-07-08 at 18:27 -0700, Guenter Roeck wrote:
[...]
> Qemu images fail to build for mips, mips64, and x86.
>
> Build error seems to be always the same.
>
> lib/nlattr.c: In function 'nla_parse':
> lib/nlattr.c:201:3: error: dereferencing pointer to incomplete type
> make[1]: *** [lib/nlattr.o] Error 1
>
> Culprit is bfc5184b69 (netlink: rate-limit leftover bytes warning
> and print process name). In 3.2, it is necessary to include <linux/sched.h>
> explicitly to get the definition of 'struct task_struct'.

Thanks - I saw this same regression occurred with 3.4.y, but somehow I
missed what the solution was, and it didn't affect my x86_64 build.
It's odd that the compiler doesn't report the name of the incomplete
type - seems like that would have saved us some time.

Ben.

> Details are available at http://server.roeck-us.net:8010/builders.
>
> Guenter
>

--
Ben Hutchings
All the simple programs have been written, and all the good names taken.


Attachments:
signature.asc (811.00 B)
This is a digitally signed message part

2014-07-09 02:40:42

by Ben Hutchings

[permalink] [raw]
Subject: Re: [PATCH 3.2 000/125] 3.2.61-rc1 review

This is the combined patch for 3.2.61-rc1 relative to 3.2.60.

An additional fix is needed for some architectures:

diff -u b/lib/nlattr.c b/lib/nlattr.c
--- b/lib/nlattr.c
+++ b/lib/nlattr.c
@@ -13,6 +13,7 @@
#include <linux/skbuff.h>
#include <linux/string.h>
#include <linux/ratelimit.h>
+#include <linux/sched.h>
#include <linux/types.h>
#include <net/netlink.h>

--- END ---

Ben.

--
Ben Hutchings
All the simple programs have been written, and all the good names taken.


Attachments:
linux-3.2.61-rc1.patch (187.61 kB)
signature.asc (811.00 B)
This is a digitally signed message part
Download all attachments

2014-07-09 03:13:53

by Guenter Roeck

[permalink] [raw]
Subject: Re: [PATCH 3.2 000/125] 3.2.61-rc1 review

On 07/08/2014 12:01 PM, Ben Hutchings wrote:
> This is the start of the stable review cycle for the 3.2.61 release.
> There are 125 patches in this series, which will be posted as responses
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Thu Jul 10 19:01:49 UTC 2014.
> Anything received after that time might be too late.
>

Looks better now, with the additional fix.

Build results:
total: 109 pass: 100 fail: 9
Failed builds:
alpha:allmodconfig
microblaze:mmu_defconfig
microblaze:nommu_defconfig
mips:allmodconfig
score:defconfig
sparc64:allmodconfig
unicore32:defconfig
xtensa:defconfig
xtensa:allmodconfig

Qemu tests all passed.

Results are as expected.

Details are available at http://server.roeck-us.net:8010/builders.

Guenter

2014-07-09 05:59:44

by Hugh Dickins

[permalink] [raw]
Subject: Re: [PATCH 3.2 099/125] mm: fix crashes from mbind() merging vmas

On Wed, 9 Jul 2014, Ben Hutchings wrote:
> On Tue, 2014-07-08 at 14:26 -0700, Hugh Dickins wrote:
> > On Tue, 8 Jul 2014, Hugh Dickins wrote:
> > > On Tue, 8 Jul 2014, Ben Hutchings wrote:
> > >
> > > > 3.2.61-rc1 review patch. If anyone has any objections, please let me know.
> > > >
> > > > ------------------
> > > >
> > > > From: Hugh Dickins <[email protected]>
> > > >
> > > > commit d05f0cdcbe6388723f1900c549b4850360545201 upstream.
> > >
> > > I don't think that's correct, I can't see a change to the
> > > "vma = check_range(" in migrate_to_node() which 3.2 and 3.4 trees have.
> > > Does it build (without warning) with CONFIG_NUMA and CONFIG_MIGRATION?
> > > I expect this version I sent yesterday for 3.4.98 will be good for 3.2:
> >
> > Hah, I now see that 098/125 in your series
>
> Which, for anyone who missed it, was commit 082708072a42, 'mm: revert
> 0def08e3 ("mm/mempolicy.c: check return code of check_range")'.
>
> > removes precisely the "vma = "
> > I was calling attention to. So all should be okay and you can ignore me.
>
> Right - of course I'm assuming that the reasoning given for that revert
> is valid for 3.2.

It should be fine: both reverter 082708072a42 and revertee 0def08e3
were cleanups of little importance, it just happens that the revert
made your backport of mine slightly easier, hence you included it.

The revert does add a VM_BUG_ON, at first a worry for -stable,
but in fact it looks safe to me.

(I wish I had done a much simpler patch for mine, but too late for that!)

Hugh

2014-07-09 11:53:52

by Satoru Takeuchi

[permalink] [raw]
Subject: Re: [PATCH 3.2 000/125] 3.2.61-rc1 review

At Tue, 08 Jul 2014 18:27:37 -0700,
Guenter Roeck wrote:
>
> On 07/08/2014 12:01 PM, Ben Hutchings wrote:
> > This is the start of the stable review cycle for the 3.2.61 release.
> > There are 125 patches in this series, which will be posted as responses
> > to this one. If anyone has any issues with these being applied, please
> > let me know.
> >
> > Responses should be made by Thu Jul 10 19:01:49 UTC 2014.
> > Anything received after that time might be too late.
> >
>
> Build results:
> total: 109 pass: 71 fail: 38
> Failed builds:
> alpha:allmodconfig
> arm:defconfig
> arm:imx_v4_v5_defconfig
> arm:mxs_defconfig
> arm:dove_defconfig
> arm:kirkwood_defconfig
> arm:omap2plus_defconfig
> arm:tegra_defconfig
> arm:u8500_defconfig
> arm:at91sam9rl_defconfig
> arm:pxa910_defconfig
> arm:mackerel_defconfig
> arm:ixp4xx_defconfig
> arm:vexpress_defconfig
> arm:msm_defconfig
> arm:at91rm9200_defconfig
> arm:at91sam9263_defconfig
> arm:at91sam9g45_defconfig
> arm:assabet_defconfig
> i386:defconfig
> i386:allyesconfig
> i386:allmodconfig
> m32r:defconfig
> microblaze:mmu_defconfig
> microblaze:nommu_defconfig
> mips:defconfig
> mips:allmodconfig
> mips:bcm47xx_defconfig
> mips:bcm63xx_defconfig
> mips:ar7_defconfig
> mips:fuloong2e_defconfig
> mips:malta_defconfig
> score:defconfig
> sparc64:allmodconfig
> um:defconfig
> unicore32:defconfig
> xtensa:defconfig
> xtensa:allmodconfig
>
> Qemu images fail to build for mips, mips64, and x86.
>
> Build error seems to be always the same.
>
> lib/nlattr.c: In function 'nla_parse':
> lib/nlattr.c:201:3: error: dereferencing pointer to incomplete type
> make[1]: *** [lib/nlattr.o] Error 1
>
> Culprit is bfc5184b69 (netlink: rate-limit leftover bytes warning
> and print process name). In 3.2, it is necessary to include <linux/sched.h>
> explicitly to get the definition of 'struct task_struct'.
>
> Details are available at http://server.roeck-us.net:8010/builders.
>
> Guenter
>

This kernel passed my test. I didn't hit the problem which
Guenter reported since I only test x86_64 arch.

- Test Cases:
- Build this kernel.
- Boot this kernel.
- Build the latest mainline kernel with this kernel.

- Test Tool:
https://github.com/satoru-takeuchi/test-linux-stable

- Test Result (kernel .config, ktest config and test log):
http://satoru-takeuchi.org/test-linux-stable/results/<version>-<test datetime>.tar.xz

- Build Environment:
- OS: Debian Jessy x86_64
- CPU: Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz x 4
- memory: 8GB

- Test Target Environment:
- Debian Jessy x86_64 (KVM guest on the Build Environment)
- # of vCPU: 2
- memory: 2GB

Thanks,
Satoru

2014-07-09 21:30:50

by Ben Hutchings

[permalink] [raw]
Subject: Re: [PATCH 3.2 000/125] 3.2.61-rc1 review

On Wed, 2014-07-09 at 20:53 +0900, Satoru Takeuchi wrote:
[...]
> This kernel passed my test. I didn't hit the problem which
> Guenter reported since I only test x86_64 arch.
[...]

Thanks for testing!

Ben.

--
Ben Hutchings
All the simple programs have been written, and all the good names taken.


Attachments:
signature.asc (811.00 B)
This is a digitally signed message part