Skip to contentSkip to conversation

3.4.107-rc1 review

PATCH In review [email protected] 10 participants 192 messages Apr 9, 2015 – May 4, 2015 Page 1 of 2

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

cover 3.4.107-rc1 review

From: Zefan Li <[email protected]>

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

Responses should be made by Thu Apr 9 16:25:15 CST 2015. Anything received after that time might be too late.

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

thanks,

Zefan Li

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

Aaro Koskinen (1):
MIPS: Loongson: Make platform serial setup always built-in.

Adam Lee (1):
Bluetooth: ath3k: workaround the compatibility issue with xHCI
controller

Al Viro (2):
move d_rcu from overlapping d_child to overlapping d_alias deal with deadlock in d_walk()

Alan Stern (1):
usb-storage/SCSI: Add broken_fua blacklist flag

Alex Deucher (1):
drm/radeon: check the right ring in radeon_evict_flags()

Alex Williamson (1):
driver core: Fix unbalanced device reference in drivers_probe

Amit Virdi (1):
usb: dwc3: gadget: Stop TRB preparation after limit is reached

Anantha Krishnan (2):
Bluetooth: Add support for Acer [13D3:3432]
Bluetooth: Add support for Acer [0489:e078]

Andreas Müller (1):
mac80211: fix multicast LED blinking and counter

Andy Lutomirski (4):
x86_64, switch_to(): Load TLS descriptors before switching DS and ES x86/tls: Disallow unusual TLS segments
x86/tls: Don't validate lm in set_thread_area() after all x86_64, vdso: Fix the vdso address randomization algorithm

Andy Shevchenko (5):
sata_dwc_460ex: fix resource leak on error path
spi: dw-mid: fix FIFO size
Bluetooth: sort the list of IDs in the source code
Bluetooth: append new supported device to the list [0b05:17d0]
spi: dw: revisit FIFO size detection again

Ani Sinha (1):
net:socket: set msg_namelen to 0 if msg_name is passed as NULL in
msghdr struct from userland.

Arseny Solokha (1):
OHCI: add a quirk for ULi M5237 blocking on reset

Ashay Jaiswal (1):
regulator: core: fix race condition in regulator_put()

Axel Lin (1):
spi: dw: Fix detecting FIFO depth

Bo Shen (1):
ASoC: atmel_ssc_dai: fix start event for I2S mode

Bob Paauwe (1):
drm/i915: Only fence tiled region of object.

Borislav Petkov (1):
x86, cpu, amd: Add workaround for family 16h, erratum 793

Catalin Marinas (1):
net: compat: Update get_compat_msghdr() to match
copy_msghdr_from_user() behaviour

Christian Borntraeger (1):
KVM: s390: flush CPU on load control

Clemens Ladisch (1):
ALSA: seq-dummy: remove deadlock-causing events on close

Cristina Ciocan (1):
iio: Fix IIO_EVENT_CODE_EXTRACT_DIR bit mask

Dan Carpenter (1):
HID: roccat: potential out of bounds in pyra_sysfs_write_settings()

Dan Williams (1):
libata: allow sata_sil24 to opt-out of tag ordered submission

Daniel Borkmann (5):
x86, um: actually mark system call tables readonly
net: sctp: fix slab corruption from use after free on INIT collisions
net: sctp: fix panic on duplicate ASCONF chunks
net: sctp: fix skb_over_panic when receiving malformed ASCONF chunks
net: sctp: fix NULL pointer dereference in af->from_addr_param on
malformed packet

Daniel Vetter (1):
drm/i915: Unlock panel even when LVDS is disabled

Dave Kleikamp (1):
jfs: fix readdir regression

David Daney (1):
MIPS: Fix C0_Pagegrain[IEC] support.

David Jeffery (1):
libata: prevent HSM state change race between ISR and PIO

David Peterson (1):
USB: cp210x: add IDs for CEL USB sticks and MeshWorks devices

Devin Ryles (1):
AHCI: Add DeviceIDs for Sunrise Point-LP SATA controller

Dmitry Eremin-Solenikov (2):
ARM: 8216/1: xscale: correct auxiliary register in suspend/resume
mfd: tc6393xb: Fail ohci suspend if full state restore is required

Dmitry Nezhevenko (1):
usb-storage/SCSI: blacklist FUA on JMicron 152d:2566 USB-SATA
controller

Dmitry Torokhov (2):
sata_fsl: fix error handling of irq_of_parse_and_map
Input: I8042 - add Acer Aspire 7738 to the nomux list

Dmitry Tunin (1):
Bluetooth: ath3k: Add support of MCI 13d3:3408 bt device

Dominique Leuenberger (1):
hp_accel: Add support for HP ZBook 15

Eric Nelson (1):
ASoC: sgtl5000: add delay before first I2C access

Felix Fietkau (4):
ath9k_hw: fix hardware queue allocation
ath9k: fix BE/BK queue order
ath5k: fix hardware queue index assignment
MIPS: IRQ: Fix disable_irq on CPU IRQs

Fernando Soto (1):
Drivers: hv: vmbus: incorrect device name is printed when child device
is unregistered

Filipe Manana (1):
Btrfs: fix fs corruption on transaction abort if device supports
discard

Greg Kroah-Hartman (3):
Input: xpad - use proper endpoint type
USB: cdc-acm: check for valid interfaces
sysfs.h: add ATTRIBUTE_GROUPS() macro

Grygorii Strashko (1):
i2c: davinci: generate STP always when NACK is received

Guenter Roeck (1):
driver core: Introduce device_create_groups

Hannes Frederic Sowa (1):
ipv6: replacing a rt6_info needs to purge possible propagated
rt6_infos too

Hannes Reinecke (1):
scsi: correct return values for .eh_abort_handler implementations

Hans de Goede (1):
usb-quirks: Add reset-resume quirk for MS Wireless Laser Mouse 6000

Hector Marco-Gisbert (1):
x86, mm/ASLR: Fix stack randomization on 64-bit systems

Hemmo Nieminen (1):
MIPS: Fix kernel lockup or crash after CPU offline/online

Hugh Dickins (1):
mm: fix swapoff hang after page migration and fork

Ian Abbott (1):
staging: comedi: cb_pcidas64: fix incorrect AI range code handling

James P Michels III (1):
usb-core bInterval quirk

Jan Kara (8):
writeback: Move I_DIRTY_PAGES handling
ncpfs: return proper error from NCP_IOC_SETROOT ioctl
isofs: Fix infinite looping over CE entries
isofs: Fix unchecked printing of ER records
udf: Verify i_size when loading inode
udf: Verify symlink size before loading it
udf: Check path length when reading symlink
udf: Check component length before reading it

Janne Heikkinen (1):
Bluetooth: Add USB device 04ca:3010 as Atheros AR3012

Jason Lee Cragg (1):
ALSA: usb-audio: Add mic volume fix quirk for Logitech Webcam C210

Jens Axboe (1):
genhd: check for int overflow in disk_expand_part_tbl()

Jerry Hoemann (1):
fsnotify: next_i is freed during fsnotify_unmount_inodes.

Jiang Liu (1):
iommu/vt-d: Fix an off-by-one bug in __domain_mapping()

Jiri Jaburek (1):
ALSA: usb-audio: extend KEF X300A FU 10 tweak to Arcam rPAC

Johan Hovold (10):
USB: keyspan: fix tty line-status reporting
USB: keyspan: fix overrun-error reporting
USB: ssu100: fix overrun-error reporting
USB: console: fix potential use after free
gpio: fix memory and reference leaks in gpiochip_add error path
gpio: sysfs: fix gpio-chip device-attribute leak
gpio: sysfs: fix gpio device-attribute leak
gpio: sysfs: fix gpio attribute-creation race
gpio: sysfs: fix memory leak in gpiod_export_link
gpio: sysfs: fix memory leak in gpiod_sysfs_set_active_low

Johannes Berg (1):
nl80211: fix per-station group key get/del and memory leak

Johannes Weiner (1):
mm: protect set_page_dirty() from ongoing truncation

John Stultz (1):
ntp: Fixup adjtimex freq validation on 32-bit systems

Julian Anastasov (1):
ipvs: rerouting to local clients is not needed anymore

Junxiao Bi (1):
ocfs2: fix journal commit deadlock

K. Y. Srinivasan (1):
x86, hyperv: Mark the Hyper-V clocksource as being continuous

Kazuya Mizuguchi (1):
usb: renesas_usbhs: gadget: fix NULL pointer dereference in
ep_disable()

Kirill A. Shutemov (1):
pagemap: do not leak physical addresses to non-privileged userspace

Konstantin Khlebnikov (2):
mm: prevent endless growth of anon_vma hierarchy
mm: fix corner case in anon_vma endless growing prevention

Lars Ellenberg (1):
drbd: merge_bvec_fn: properly remap bvm->bi_bdev

Lars-Peter Clausen (1):
ASoC: sigmadsp: Refuse to load firmware files with a non-supported
version

Laurent Dufour (2):
powerpc/pseries: Fix endiannes issue in RTAS call from xmon powerpc/xmon: Fix another endiannes issue in RTAS call from xmon

Leon Yu (1):
mm: fix anon_vma->degree underflow in anon_vma endless growing
prevention

Levente Kurusa (1):
ahci: disable NCQ on Samsung pci-e SSDs on macbooks

Linus Torvalds (4):
mm: propagate error from stack expansion even for guard page
mm: Don't count the stack guard page towards RLIMIT_STACK
vm: add VM_FAULT_SIGSEGV handling support
vm: make stack guard page errors return VM_FAULT_SIGSEGV rather than
SIGBUS

Long Li (1):
storvsc: ring buffer failures may result in I/O freeze

Lu Baolu (1):
usb: xhci: rework root port wake bits if controller isn't allowed to
wakeup

Macpaul Lin (1):
USB: Add OTG PET device to TPL

Marcel Holtmann (3):
Bluetooth: Add support for Intel bootloader devices
Bluetooth: Ignore isochronous endpoints for Intel USB bootloader
Bluetooth: Add support for Broadcom device of Asus Z97-DELUXE
motherboard

Martin Schwidefsky (1):
s390/3215: fix tty output containing tabs

Mathias Nyman (2):
USB: xhci: don't start a halted endpoint before its new dequeue is set
USB: xhci: Reset a halted endpoint immediately when we encounter a
stall.

Maurizio Lombardi (1):
bnx2fc: do not add shared skbs to the fcoe_rx_list

Michael Halcrow (1):
eCryptfs: Remove buggy and unnecessary write in file name decode
routine

Michael Karcher (1):
scripts/recordmcount.pl: There is no -m32 gcc option on Super-H
anymore

Michael S. Tsirkin (1):
virtio_pci: document why we defer kfree

Myron Stowe (1):
PCI: Restore detection of read-only BARs

Nicholas Bellinger (1):
iscsi-target: Fail connection on short sendmsg writes

Nicolas Dichtel (1):
caif: remove wrong dev_net_set() call

Oliver Hartkopp (1):
can: dev: fix crtlmode_supported check

Oliver Neukum (1):
cdc-acm: memory leak in error case

Petr Mladek (1):
drm/radeon: kernel panic in drm_calc_vbltimestamp_from_scanoutpos with

    3.18.0-rc6

Preston Fick (2):
USB: serial: cp210x: add IDs for CEL MeshConnect USB Stick
USB: cp210x: fix ID for production CEL MeshConnect USB Stick

Rabin Vincent (1):
crypto: af_alg - fix backlog handling

Richard Weinberger (1):
UBI: Fix invalid vfree()

Robert Baldyga (1):
serial: samsung: wait for transfer completion before clock disable

Ryan Mallon (1):
gpiolib: Refactor gpio_export

Ryusuke Konishi (2):
nilfs2: fix deadlock of segment constructor over I_SYNC flag
nilfs2: fix deadlock of segment constructor during recovery

Saran Maruti Ramanara (1):
net: sctp: fix passing wrong parameter header to param_type2af in
sctp_process_param

Sasha Levin (4):
virtio_pci: defer kfree until release callback
time: settimeofday: Validate the values of tv from user
time: adjtimex: Validate the ADJ_FREQUENCY values
KEYS: close race between key lookup and freeing

Srihari Vijayaraghavan (1):
Input: i8042 - reset keyboard to fix Elantech touchpad detection

Stephane Grosjean (2):
can: peak_usb: fix memset() usage
can: peak_usb: fix cleanup sequence order in case of error during init

Steven Rostedt (Red Hat) (1):
ftrace/jprobes/x86: Fix conflict between jprobes and function graph
tracing

[email protected] (1):
megaraid_sas: corrected return of wait_event from abort frame path

Takashi Iwai (5):
ALSA: hda - Limit 40bit DMA for AMD HDMI controllers
ALSA: usb-audio: Don't resubmit pending URBs at MIDI error recovery
KEYS: Fix stale key registration at error path
ALSA: hda - Fix wrong gpio_dir & gpio_mask hint setups for IDT/STAC
codecs
ALSA: ak411x: Fix stall in work callback

Tejun Heo (3):
ahci: disable MSI instead of NCQ on Samsung pci-e SSDs on macbooks
ahci: disable MSI on SAMSUNG 0xa800 SSD
writeback: fix a subtle race condition in I_DIRTY clearing

Thomas Gleixner (1):
genirq: Prevent proc race against freeing of irq descriptors

Thomas Hellstrom (2):
drm/vmwgfx: Don't use memory accounting for kernel-side fence objects drm/vmwgfx: Fix fence event code

Thor Thayer (1):
spi: dw: Fix dynamic speed change.

Tim Chen (1):
sched/rt: Reduce rq lock contention by eliminating locking of
non-feasible target

Tim Niemeyer (1):
Bluetooth: Fix invalid length check in l2cap_information_rsp()

Tomi Valkeinen (1):
video/logo: prevent use of logos after they have been freed

Toshiaki Makita (1):
net: Fix stacked vlan offload features computation

Trond Myklebust (2):
SUNRPC: Fix locking around callback channel reply receive
nfsd: Fix slot wake up race in the nfsv4.1 callback code

Troy Clark (1):
usb: serial: ftdi_sio: add PIDs for Matrix Orbital products

Tyler Hicks (1):
eCryptfs: Force RO mount when encrypted view is enabled

Vincent Zwanenburg (1):
Add a new PID/VID 0227/0930 for AR3012.

Wanlong Gao (1):
virtio: use dev_to_virtio wrapper in virtio

Zidan Wang (1):
ASoC: wm8960: Fix capture sample rate from 11250 to 11025

karl beldan (1):
lib/checksum.c: fix carry in csum_tcpudp_nofold

 Documentation/kernel-parameters.txt          |   1 +
 arch/alpha/mm/fault.c                        |   2 +
 arch/arm/mm/proc-xscale.S                    |   4 +-
 arch/avr32/mm/fault.c                        |   2 +
 arch/cris/mm/fault.c                         |   2 +
 arch/frv/mm/fault.c                          |   2 +
 arch/ia64/mm/fault.c                         |   2 +
 arch/m32r/mm/fault.c                         |   2 +
 arch/m68k/mm/fault.c                         |   2 +
 arch/microblaze/mm/fault.c                   |   2 +
 arch/mips/kernel/irq_cpu.c                   |   4 +
 arch/mips/kernel/smp.c                       |   2 +-
 arch/mips/loongson/common/Makefile           |   3 +-
 arch/mips/mm/fault.c                         |   2 +
 arch/mips/mm/tlb-r4k.c                       |   2 +
 arch/mn10300/mm/fault.c                      |   2 +
 arch/openrisc/mm/fault.c                     |   2 +
 arch/parisc/mm/fault.c                       |   2 +
 arch/powerpc/mm/fault.c                      |   6 +-
 arch/powerpc/platforms/cell/spu_fault.c      |   2 +-
 arch/powerpc/platforms/cell/spufs/inode.c    |   4 +-
 arch/powerpc/xmon/xmon.c                     |   7 +-
 arch/s390/kvm/intercept.c                    |   2 +
 arch/s390/mm/fault.c                         |   7 +
 arch/score/mm/fault.c                        |   2 +
 arch/sh/mm/fault_32.c                        |   2 +
 arch/sh/mm/tlbflush_64.c                     |   2 +
 arch/sparc/mm/fault_32.c                     |   2 +
 arch/sparc/mm/fault_64.c                     |   2 +
 arch/tile/mm/fault.c                         |   2 +
 arch/um/kernel/trap.c                        |   2 +
 arch/x86/include/asm/ldt.h                   |   7 +
 arch/x86/include/asm/msr-index.h             |   1 +
 arch/x86/kernel/cpu/amd.c                    |  10 ++
 arch/x86/kernel/cpu/mshyperv.c               |   1 +
 arch/x86/kernel/kprobes.c                    |  20 ++-
 arch/x86/kernel/process_64.c                 | 101 +++++++++++----
 arch/x86/kernel/tls.c                        |  16 +++
 arch/x86/mm/fault.c                          |   2 +
 arch/x86/mm/mmap.c                           |   6 +-
 arch/x86/um/sys_call_table_32.c              |   2 +-
 arch/x86/um/sys_call_table_64.c              |   2 +-
 arch/x86/vdso/vma.c                          |  36 ++++--
 arch/xtensa/mm/fault.c                       |   2 +
 block/genhd.c                                |  11 +-
 crypto/af_alg.c                              |   3 +
 drivers/ata/ahci.c                           |  26 ++++
 drivers/ata/libata-core.c                    |   5 +-
 drivers/ata/libata-sff.c                     |  12 ++
 drivers/ata/sata_dwc_460ex.c                 |  26 ++--
 drivers/ata/sata_fsl.c                       |   2 +-
 drivers/ata/sata_sil24.c                     |   2 +-
 drivers/base/bus.c                           |   8 +-
 drivers/base/core.c                          | 111 ++++++++++++----
 drivers/block/drbd/drbd_req.c                |   1 +
 drivers/bluetooth/ath3k.c                    |  84 +++++++-----
 drivers/bluetooth/btusb.c                    |  63 +++++----
 drivers/gpio/gpiolib.c                       | 145 ++++++++++++---------
 drivers/gpu/drm/i915/i915_gem.c              |  14 ++
 drivers/gpu/drm/i915/intel_lvds.c            |  24 ++--
 drivers/gpu/drm/radeon/radeon_kms.c          |   2 +
 drivers/gpu/drm/radeon/radeon_ttm.c          |   2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c        |  38 ++----
 drivers/hid/hid-roccat-pyra.c                |   7 +
 drivers/hv/vmbus_drv.c                       |   8 +-
 drivers/i2c/busses/i2c-davinci.c             |   8 +-
 drivers/input/joystick/xpad.c                |  16 ++-
 drivers/input/serio/i8042-x86ia64io.h        |  39 ++++++
 drivers/input/serio/i8042.c                  |  14 ++
 drivers/iommu/intel-iommu.c                  |   8 +-
 drivers/mfd/tc6393xb.c                       |  13 +-
 drivers/mtd/ubi/upd.c                        |  10 +-
 drivers/net/can/dev.c                        |   8 +-
 drivers/net/can/usb/peak_usb/pcan_usb_core.c |  17 ++-
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c  |   3 +-
 drivers/net/wireless/ath/ath5k/qcu.c         |   8 +-
 drivers/net/wireless/ath/ath9k/hw.h          |   4 +-
 drivers/net/wireless/ath/ath9k/mac.c         |   9 +-
 drivers/pci/probe.c                          |   3 +
 drivers/platform/x86/hp_accel.c              |   1 +
 drivers/regulator/core.c                     |   2 +
 drivers/s390/char/con3215.c                  |  20 ++-
 drivers/scsi/NCR5380.c                       |  12 +-
 drivers/scsi/aha1740.c                       |   2 +-
 drivers/scsi/atari_NCR5380.c                 |   2 +-
 drivers/scsi/bnx2fc/bnx2fc_fcoe.c            |   7 +
 drivers/scsi/megaraid.c                      |   8 +-
 drivers/scsi/megaraid/megaraid_sas_base.c    |   2 +-
 drivers/scsi/sd.c                            |   5 +-
 drivers/scsi/storvsc_drv.c                   |   7 +-
 drivers/scsi/sun3_NCR5380.c                  |  10 +-
 drivers/spi/spi-dw-mid.c                     |   1 -
 drivers/spi/spi-dw.c                         |  10 +-
 drivers/staging/comedi/drivers/cb_pcidas64.c | 123 +++++++++++-------
 drivers/staging/iio/events.h                 |   2 +-
 drivers/target/iscsi/iscsi_target_util.c     |  26 ++--
 drivers/tty/serial/samsung.c                 |   4 +
 drivers/usb/class/cdc-acm.c                  |  10 +-
 drivers/usb/core/config.c                    |  11 ++
 drivers/usb/core/inode.c                     |   6 +-
 drivers/usb/core/otg_whitelist.h             |   5 +
 drivers/usb/core/quirks.c                    |  11 ++
 drivers/usb/dwc3/gadget.c                    |   3 +
 drivers/usb/host/pci-quirks.c                |  18 ++-
 drivers/usb/host/xhci-pci.c                  |   2 +-
 drivers/usb/host/xhci-ring.c                 |  43 ++-----
 drivers/usb/host/xhci.c                      | 102 ++++++++-------
 drivers/usb/host/xhci.h                      |   2 +-
 drivers/usb/renesas_usbhs/mod_gadget.c       |   3 +
 drivers/usb/serial/console.c                 |  15 ++-
 drivers/usb/serial/cp210x.c                  |   3 +
 drivers/usb/serial/ftdi_sio.c                |  33 +++++
 drivers/usb/serial/ftdi_sio_ids.h            |  39 +++++-
 drivers/usb/serial/keyspan.c                 |  97 ++++++++------
 drivers/usb/serial/ssu100.c                  |  11 +-
 drivers/usb/storage/scsiglue.c               |   4 +
 drivers/usb/storage/unusual_devs.h           |  14 ++
 drivers/video/logo/logo.c                    |  17 ++-
 drivers/virtio/virtio.c                      |  19 ++-
 drivers/virtio/virtio_pci.c                  |  13 +-
 fs/9p/vfs_inode_dotl.c                       |   2 +-
 fs/affs/amigaffs.c                           |   2 +-
 fs/autofs4/expire.c                          |  10 +-
 fs/autofs4/root.c                            |   2 +-
 fs/binfmt_elf.c                              |   5 +-
 fs/btrfs/disk-io.c                           |   6 -
 fs/btrfs/extent-tree.c                       |  10 +-
 fs/ceph/dir.c                                |   8 +-
 fs/ceph/inode.c                              |   6 +-
 fs/cifs/inode.c                              |   2 +-
 fs/coda/cache.c                              |   2 +-
 fs/dcache.c                                  | 183 +++++++++++++++------------
 fs/debugfs/inode.c                           |   6 +-
 fs/ecryptfs/crypto.c                         |   1 -
 fs/ecryptfs/file.c                           |  12 --
 fs/ecryptfs/main.c                           |  16 ++-
 fs/exportfs/expfs.c                          |   2 +-
 fs/ext4/fsync.c                              |   2 +-
 fs/fs-writeback.c                            |  28 +++-
 fs/isofs/rock.c                              |   9 ++
 fs/jfs/jfs_dtree.c                           |   4 +-
 fs/libfs.c                                   |  12 +-
 fs/ncpfs/dir.c                               |   2 +-
 fs/ncpfs/ioctl.c                             |   1 -
 fs/ncpfs/ncplib_kernel.h                     |   4 +-
 fs/nfs/getroot.c                             |   2 +-
 fs/nfsd/nfs4callback.c                       |   8 +-
 fs/nilfs2/nilfs.h                            |   2 -
 fs/nilfs2/segment.c                          |  45 ++++++-
 fs/nilfs2/segment.h                          |   5 +
 fs/notify/fsnotify.c                         |   4 +-
 fs/notify/inode_mark.c                       |  17 ++-
 fs/ocfs2/aops.c                              |  16 ++-
 fs/ocfs2/dcache.c                            |   2 +-
 fs/proc/stat.c                               |   2 +-
 fs/proc/task_mmu.c                           |  10 ++
 fs/udf/dir.c                                 |   3 +-
 fs/udf/inode.c                               |  14 ++
 fs/udf/namei.c                               |   3 +-
 fs/udf/symlink.c                             |  57 +++++++--
 fs/udf/udfdecl.h                             |   3 +-
 fs/udf/unicode.c                             |  28 ++--
 include/linux/dcache.h                       |   8 +-
 include/linux/device.h                       |   5 +
 include/linux/kernel_stat.h                  |   5 +
 include/linux/libata.h                       |   1 +
 include/linux/mm.h                           |   7 +-
 include/linux/rmap.h                         |  10 ++
 include/linux/sysfs.h                        |   9 ++
 include/linux/time.h                         |  13 ++
 include/linux/usb/quirks.h                   |  11 ++
 include/linux/usb_usual.h                    |   4 +-
 include/linux/virtio.h                       |   6 +-
 include/linux/writeback.h                    |   1 -
 include/net/sctp/sctp.h                      |   5 +
 include/net/sctp/sm.h                        |   6 +-
 include/scsi/scsi_device.h                   |   1 +
 include/sound/ak4113.h                       |   2 +-
 include/sound/ak4114.h                       |   2 +-
 kernel/cgroup.c                              |   4 +-
 kernel/irq/internals.h                       |   8 ++
 kernel/irq/irqdesc.c                         |  52 ++++++++
 kernel/irq/proc.c                            |  22 +++-
 kernel/sched/rt.c                            |  17 ++-
 kernel/time.c                                |   4 +
 kernel/time/ntp.c                            |  11 ++
 lib/checksum.c                               |  12 +-
 mm/ksm.c                                     |   2 +-
 mm/memory.c                                  |  63 +++++----
 mm/mmap.c                                    |  14 +-
 mm/page-writeback.c                          |  43 ++-----
 mm/rmap.c                                    |  49 ++++++-
 net/bluetooth/l2cap_core.c                   |   4 +-
 net/caif/chnl_net.c                          |   1 -
 net/compat.c                                 |   7 +
 net/core/dev.c                               |   8 ++
 net/ipv6/ip6_fib.c                           |  45 ++++---
 net/mac80211/rx.c                            |  11 +-
 net/netfilter/ipvs/ip_vs_core.c              |  32 +++--
 net/sctp/associola.c                         |   3 +-
 net/sctp/sm_make_chunk.c                     | 104 ++++++++-------
 net/sctp/sm_statefuns.c                      |  18 +--
 net/socket.c                                 |   3 +
 net/sunrpc/svcsock.c                         |  27 ++--
 net/wireless/nl80211.c                       |   9 +-
 scripts/recordmcount.pl                      |   1 -
 security/keys/encrypted-keys/encrypted.c     |   5 +-
 security/keys/gc.c                           |   4 +-
 security/selinux/selinuxfs.c                 |   6 +-
 sound/core/seq/seq_dummy.c                   |  31 -----
 sound/i2c/other/ak4113.c                     |  17 ++-
 sound/i2c/other/ak4114.c                     |  18 ++-
 sound/pci/hda/hda_intel.c                    |  14 +-
 sound/pci/hda/patch_sigmatel.c               |   4 +-
 sound/soc/atmel/atmel_ssc_dai.c              |  18 +--
 sound/soc/codecs/sgtl5000.c                  |   3 +
 sound/soc/codecs/sigmadsp.c                  |   7 +
 sound/soc/codecs/wm8960.c                    |   2 +-
 sound/usb/midi.c                             |   2 +
 sound/usb/mixer.c                            |   1 +
 sound/usb/mixer_maps.c                       |  15 ++-
 221 files changed, 2085 insertions(+), 1057 deletions(-)
Signature · 1 line
1.9.1
#1 lore raw

PATCH 1/176 spi: dw: Fix dynamic speed change.

From: Thor Thayer <[email protected]>

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

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

commit 0a8727e69778683495058852f783eeda141a754e upstream.

An IOCTL call that calls spi_setup() and then dw_spi_setup() will overwrite the persisted last transfer speed. On each transfer, the SPI speed is compared to the last transfer speed to determine if the clock divider registers need to be updated (did the speed change?). This bug was observed with the spidev driver using spi-config to update the max transfer speed.

This fix: Don't overwrite the persisted last transaction clock speed when updating the SPI parameters in dw_spi_setup(). On the next transaction, the new speed won't match the persisted last speed and the hardware registers will be updated.
On initialization, the persisted last transaction clock speed will be 0 but will be updated after the first SPI transaction.

Move zeroed clock divider check into clock change test because chip->clk_div is zero on startup and would cause a divide-by-zero error. The calculation was wrong as well (can't support odd #).

---
 drivers/spi/spi-dw.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
drivers/spi/spi-dw.c +1 -5
index d1a495f..ff06b42 100644
@@ -394,9 +394,6 @@ static void pump_transfers(unsigned long data)
 	chip = dws->cur_chip;
 	spi = message->spi;
 
-	if (unlikely(!chip->clk_div))
-		chip->clk_div = dws->max_freq / chip->speed_hz;
-
 	if (message->state == ERROR_STATE) {
 		message->status = -EIO;
 		goto early_exit;
@@ -438,7 +435,7 @@ static void pump_transfers(unsigned long data)
 	if (transfer->speed_hz) {
 		speed = chip->speed_hz;
 
-		if (transfer->speed_hz != speed) {
+		if ((transfer->speed_hz != speed) || (!chip->clk_div)) {
 			speed = transfer->speed_hz;
 			if (speed > dws->max_freq) {
 				printk(KERN_ERR "MRST SPI0: unsupported"
@@ -677,7 +674,6 @@ static int dw_spi_setup(struct spi_device *spi)
 		dev_err(&spi->dev, "No max speed HZ parameter\n");
 		return -EINVAL;
 	}
-	chip->speed_hz = spi->max_speed_hz;
 
 	chip->tmode = 0; /* Tx & Rx */
 	/* Default SPI mode is SCPOL = 0, SCPH = 0 */
Signature · 1 line
1.9.1
#2 lore raw

PATCH 2/176 USB: serial: cp210x: add IDs for CEL MeshConnect USB Stick

In reply to [email protected]

From: Preston Fick <[email protected]>

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

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

commit ffcfe30ebd8dd703d0fc4324ffe56ea21f5479f4 upstream.

---
 drivers/usb/serial/cp210x.c | 1 +
 1 file changed, 1 insertion(+)
drivers/usb/serial/cp210x.c +1 -0
index 19074db..f4edbe5 100644
@@ -126,6 +126,7 @@ static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */
 	{ USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */
 	{ USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */
+	{ USB_DEVICE(0x10C4, 0x8875) }, /* CEL MeshConnect USB Stick */
 	{ USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */
 	{ USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */
 	{ USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */
Signature · 1 line
1.9.1
#3 lore raw

PATCH 3/176 iio: Fix IIO_EVENT_CODE_EXTRACT_DIR bit mask

In reply to [email protected]

From: Cristina Ciocan <[email protected]>

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

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

commit ccf54555da9a5e91e454b909ca6a5303c7d6b910 upstream.

The direction field is set on 7 bits, thus we need to AND it with 0111 111 mask in order to retrieve it, that is 0x7F, not 0xCF as it is now.

Fixes ade7ef7ba (staging:iio: Differential channel handling)
---
 drivers/staging/iio/events.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/iio/events.h +1 -1
index c25f0e3..a6f999c 100644
@@ -90,7 +90,7 @@ enum iio_event_direction {
 
 #define IIO_EVENT_CODE_EXTRACT_TYPE(mask) ((mask >> 56) & 0xFF)
 
-#define IIO_EVENT_CODE_EXTRACT_DIR(mask) ((mask >> 48) & 0xCF)
+#define IIO_EVENT_CODE_EXTRACT_DIR(mask) ((mask >> 48) & 0x7F)
 
 #define IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(mask) ((mask >> 32) & 0xFF)
 
Signature · 1 line
1.9.1
#4 lore raw

PATCH 4/176 usb: serial: ftdi_sio: add PIDs for Matrix Orbital products

In reply to [email protected]

From: Troy Clark <[email protected]>

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

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

commit 204ec6e07ea7aff863df0f7c53301f9cbbfbb9d3 upstream.

Add PIDs for new Matrix Orbital GTT series products.

[johan: shorten commit message ]
---
 drivers/usb/serial/ftdi_sio.c     | 33 +++++++++++++++++++++++++++++++++
 drivers/usb/serial/ftdi_sio_ids.h | 39 +++++++++++++++++++++++++++++++++++----
 2 files changed, 68 insertions(+), 4 deletions(-)
drivers/usb/serial/ftdi_sio.c +33 -0
index a89433b..4bfcfa7 100644
@@ -494,6 +494,39 @@ static struct usb_device_id id_table_combined [] = {
 	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FD_PID) },
 	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FE_PID) },
 	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FF_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_4701_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9300_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9301_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9302_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9303_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9304_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9305_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9306_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9307_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9308_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9309_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930A_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930B_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930C_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930D_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930E_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930F_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9310_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9311_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9312_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9313_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9314_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9315_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9316_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9317_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9318_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9319_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931A_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931B_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931C_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931D_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931E_PID) },
+	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931F_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) },
drivers/usb/serial/ftdi_sio_ids.h +35 -4
index 64ee791..ecb4dee 100644
@@ -920,8 +920,8 @@
 #define BAYER_CONTOUR_CABLE_PID        0x6001
 
 /*
- * The following are the values for the Matrix Orbital FTDI Range
- * Anything in this range will use an FT232RL.
+ * Matrix Orbital Intelligent USB displays.
+ * http://www.matrixorbital.com
  */
 #define MTXORB_VID			0x1B3D
 #define MTXORB_FTDI_RANGE_0100_PID	0x0100
@@ -1180,8 +1180,39 @@
 #define MTXORB_FTDI_RANGE_01FD_PID	0x01FD
 #define MTXORB_FTDI_RANGE_01FE_PID	0x01FE
 #define MTXORB_FTDI_RANGE_01FF_PID	0x01FF
-
-
+#define MTXORB_FTDI_RANGE_4701_PID	0x4701
+#define MTXORB_FTDI_RANGE_9300_PID	0x9300
+#define MTXORB_FTDI_RANGE_9301_PID	0x9301
+#define MTXORB_FTDI_RANGE_9302_PID	0x9302
+#define MTXORB_FTDI_RANGE_9303_PID	0x9303
+#define MTXORB_FTDI_RANGE_9304_PID	0x9304
+#define MTXORB_FTDI_RANGE_9305_PID	0x9305
+#define MTXORB_FTDI_RANGE_9306_PID	0x9306
+#define MTXORB_FTDI_RANGE_9307_PID	0x9307
+#define MTXORB_FTDI_RANGE_9308_PID	0x9308
+#define MTXORB_FTDI_RANGE_9309_PID	0x9309
+#define MTXORB_FTDI_RANGE_930A_PID	0x930A
+#define MTXORB_FTDI_RANGE_930B_PID	0x930B
+#define MTXORB_FTDI_RANGE_930C_PID	0x930C
+#define MTXORB_FTDI_RANGE_930D_PID	0x930D
+#define MTXORB_FTDI_RANGE_930E_PID	0x930E
+#define MTXORB_FTDI_RANGE_930F_PID	0x930F
+#define MTXORB_FTDI_RANGE_9310_PID	0x9310
+#define MTXORB_FTDI_RANGE_9311_PID	0x9311
+#define MTXORB_FTDI_RANGE_9312_PID	0x9312
+#define MTXORB_FTDI_RANGE_9313_PID	0x9313
+#define MTXORB_FTDI_RANGE_9314_PID	0x9314
+#define MTXORB_FTDI_RANGE_9315_PID	0x9315
+#define MTXORB_FTDI_RANGE_9316_PID	0x9316
+#define MTXORB_FTDI_RANGE_9317_PID	0x9317
+#define MTXORB_FTDI_RANGE_9318_PID	0x9318
+#define MTXORB_FTDI_RANGE_9319_PID	0x9319
+#define MTXORB_FTDI_RANGE_931A_PID	0x931A
+#define MTXORB_FTDI_RANGE_931B_PID	0x931B
+#define MTXORB_FTDI_RANGE_931C_PID	0x931C
+#define MTXORB_FTDI_RANGE_931D_PID	0x931D
+#define MTXORB_FTDI_RANGE_931E_PID	0x931E
+#define MTXORB_FTDI_RANGE_931F_PID	0x931F
 
 /*
  * The Mobility Lab (TML)
Signature · 1 line
1.9.1
#5 lore raw

PATCH 5/176 USB: keyspan: fix tty line-status reporting

In reply to [email protected]

From: Johan Hovold <[email protected]>

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

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

commit 5d1678a33c731b56e245e888fdae5e88efce0997 upstream.

Fix handling of TTY error flags, which are not bitmasks and must specifically not be ORed together as this prevents the line discipline from recognising them.

Also insert null characters when reporting overrun errors as these are not associated with the received character.

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")

[lizf: Backported to 3.4:
- s/&port->port/tty/
- adjust context
- adjust indentation]

---
 drivers/usb/serial/keyspan.c | 78 ++++++++++++++++++++++++++++----------------
 1 file changed, 50 insertions(+), 28 deletions(-)
drivers/usb/serial/keyspan.c +50 -28
index 66d806e..5704ced 100644
@@ -333,14 +333,19 @@ static void	usa26_indat_callback(struct urb *urb)
 			/* some bytes had errors, every byte has status */
 			dbg("%s - RX error!!!!", __func__);
 			for (i = 0; i + 1 < urb->actual_length; i += 2) {
-				int stat = data[i], flag = 0;
-				if (stat & RXERROR_OVERRUN)
-					flag |= TTY_OVERRUN;
-				if (stat & RXERROR_FRAMING)
-					flag |= TTY_FRAME;
-				if (stat & RXERROR_PARITY)
-					flag |= TTY_PARITY;
+				int stat = data[i];
+				int flag = TTY_NORMAL;
+
+				if (stat & RXERROR_OVERRUN) {
+					tty_insert_flip_char(tty, 0,
+								TTY_OVERRUN);
+				}
 				/* XXX should handle break (0x10) */
+				if (stat & RXERROR_PARITY)
+					flag = TTY_PARITY;
+				else if (stat & RXERROR_FRAMING)
+					flag = TTY_FRAME;
+
 				tty_insert_flip_char(tty, data[i+1], flag);
 			}
 		}
@@ -712,14 +717,19 @@ static void	usa49_indat_callback(struct urb *urb)
 		} else {
 			/* some bytes had errors, every byte has status */
 			for (i = 0; i + 1 < urb->actual_length; i += 2) {
-				int stat = data[i], flag = 0;
-				if (stat & RXERROR_OVERRUN)
-					flag |= TTY_OVERRUN;
-				if (stat & RXERROR_FRAMING)
-					flag |= TTY_FRAME;
-				if (stat & RXERROR_PARITY)
-					flag |= TTY_PARITY;
+				int stat = data[i];
+				int flag = TTY_NORMAL;
+
+				if (stat & RXERROR_OVERRUN) {
+					tty_insert_flip_char(tty, 0,
+								TTY_OVERRUN);
+				}
 				/* XXX should handle break (0x10) */
+				if (stat & RXERROR_PARITY)
+					flag = TTY_PARITY;
+				else if (stat & RXERROR_FRAMING)
+					flag = TTY_FRAME;
+
 				tty_insert_flip_char(tty, data[i+1], flag);
 			}
 		}
@@ -779,14 +789,19 @@ static void usa49wg_indat_callback(struct urb *urb)
 				 * some bytes had errors, every byte has status
 				 */
 				for (x = 0; x + 1 < len; x += 2) {
-					int stat = data[i], flag = 0;
-					if (stat & RXERROR_OVERRUN)
-						flag |= TTY_OVERRUN;
-					if (stat & RXERROR_FRAMING)
-						flag |= TTY_FRAME;
-					if (stat & RXERROR_PARITY)
-						flag |= TTY_PARITY;
+					int stat = data[i];
+					int flag = TTY_NORMAL;
+
+					if (stat & RXERROR_OVERRUN) {
+						tty_insert_flip_char(tty, 0,
+								TTY_OVERRUN);
+					}
 					/* XXX should handle break (0x10) */
+					if (stat & RXERROR_PARITY)
+						flag = TTY_PARITY;
+					else if (stat & RXERROR_FRAMING)
+						flag = TTY_FRAME;
+
 					tty_insert_flip_char(tty,
 							data[i+1], flag);
 					i += 2;
@@ -855,14 +870,21 @@ static void usa90_indat_callback(struct urb *urb)
 			/* some bytes had errors, every byte has status */
 				dbg("%s - RX error!!!!", __func__);
 				for (i = 0; i + 1 < urb->actual_length; i += 2) {
-					int stat = data[i], flag = 0;
-					if (stat & RXERROR_OVERRUN)
-						flag |= TTY_OVERRUN;
-					if (stat & RXERROR_FRAMING)
-						flag |= TTY_FRAME;
-					if (stat & RXERROR_PARITY)
-						flag |= TTY_PARITY;
+					int stat = data[i];
+					int flag = TTY_NORMAL;
+
+					if (stat & RXERROR_OVERRUN) {
+						tty_insert_flip_char(
+								tty, 0,
+								TTY_OVERRUN);
+					}
+
 					/* XXX should handle break (0x10) */
+					if (stat & RXERROR_PARITY)
+						flag = TTY_PARITY;
+					else if (stat & RXERROR_FRAMING)
+						flag = TTY_FRAME;
+
 					tty_insert_flip_char(tty, data[i+1],
 									flag);
 				}
Signature · 1 line
1.9.1
#6 lore raw

PATCH 6/176 USB: keyspan: fix overrun-error reporting

In reply to [email protected]

From: Johan Hovold <[email protected]>

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

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

commit 855515a6d3731242d85850a206f2ec084c917338 upstream.

Fix reporting of overrun errors, which are not associated with a character. Instead insert a null character and report only once.

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")

[lizf: Backported to 3.4:
- s/&port->port/tty
- adjust context
- adjust indentation]

---
 drivers/usb/serial/keyspan.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)
drivers/usb/serial/keyspan.c +9 -10
index 5704ced..0879ac7 100644
@@ -323,12 +323,11 @@ static void	usa26_indat_callback(struct urb *urb)
 		if ((data[0] & 0x80) == 0) {
 			/* no errors on individual bytes, only
 			   possible overrun err */
-			if (data[0] & RXERROR_OVERRUN)
-				err = TTY_OVERRUN;
-			else
-				err = 0;
+			if (data[0] & RXERROR_OVERRUN) {
+				tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+			}
 			for (i = 1; i < urb->actual_length ; ++i)
-				tty_insert_flip_char(tty, data[i], err);
+				tty_insert_flip_char(tty, data[i], TTY_NORMAL);
 		} else {
 			/* some bytes had errors, every byte has status */
 			dbg("%s - RX error!!!!", __func__);
@@ -859,13 +858,13 @@ static void usa90_indat_callback(struct urb *urb)
 			if ((data[0] & 0x80) == 0) {
 				/* no errors on individual bytes, only
 				   possible overrun err*/
-				if (data[0] & RXERROR_OVERRUN)
-					err = TTY_OVERRUN;
-				else
-					err = 0;
+				if (data[0] & RXERROR_OVERRUN) {
+					tty_insert_flip_char(tty, 0,
+								TTY_OVERRUN);
+				}
 				for (i = 1; i < urb->actual_length ; ++i)
 					tty_insert_flip_char(tty, data[i],
-									err);
+								TTY_NORMAL);
 			}  else {
 			/* some bytes had errors, every byte has status */
 				dbg("%s - RX error!!!!", __func__);
Signature · 1 line
1.9.1
#7 lore raw

PATCH 7/176 USB: ssu100: fix overrun-error reporting

In reply to [email protected]

From: Johan Hovold <[email protected]>

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

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

commit 75bcbf29c284dd0154c3e895a0bd1ef0e796160e upstream.

Fix reporting of overrun errors, which should only be reported once using the inserted null character.

Fixes 6b8f1ca5581b ("USB: ssu100: set tty_flags in ssu100_process_packet")

[lizf: Backported to 3.4:
- adjust context
- lookup tty using tty_port_tty_get()]

---
 drivers/usb/serial/ssu100.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)
drivers/usb/serial/ssu100.c +4 -7
index d19fa6a..f425507 100644
@@ -598,10 +598,10 @@ static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr,
 			if (*tty_flag == TTY_NORMAL)
 				*tty_flag = TTY_FRAME;
 		}
-		if (lsr & UART_LSR_OE){
+		if (lsr & UART_LSR_OE) {
 			priv->icount.overrun++;
-			if (*tty_flag == TTY_NORMAL)
-				*tty_flag = TTY_OVERRUN;
+			tty_insert_flip_char(tty_port_tty_get(&port->port),
+					0, TTY_OVERRUN);
 		}
 	}
 
@@ -622,11 +622,8 @@ static int ssu100_process_packet(struct urb *urb,
 	if ((len >= 4) &&
 	    (packet[0] == 0x1b) && (packet[1] == 0x1b) &&
 	    ((packet[2] == 0x00) || (packet[2] == 0x01))) {
-		if (packet[2] == 0x00) {
+		if (packet[2] == 0x00)
 			ssu100_update_lsr(port, packet[3], &flag);
-			if (flag == TTY_OVERRUN)
-				tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-		}
 		if (packet[2] == 0x01)
 			ssu100_update_msr(port, packet[3]);
 
Signature · 1 line
1.9.1
#8 lore raw

PATCH 8/176 SUNRPC: Fix locking around callback channel reply receive

In reply to [email protected]

From: Trond Myklebust <[email protected]>

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

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

commit 093a1468b6edb0e568be7311b8d2228d205702db upstream.

Both xprt_lookup_rqst() and xprt_complete_rqst() require that you take the transport lock in order to avoid races with xprt_transmit().

[lizf: Backported to 3.4: adjust context]
---
 net/sunrpc/svcsock.c | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)
net/sunrpc/svcsock.c +16 -11
index 4c23cfc..a0769e1 100644
@@ -1055,17 +1055,12 @@ static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp)
 	xid = *p++;
 	calldir = *p;
 
-	if (bc_xprt)
-		req = xprt_lookup_rqst(bc_xprt, xid);
-
-	if (!req) {
-		printk(KERN_NOTICE
-			"%s: Got unrecognized reply: "
-			"calldir 0x%x xpt_bc_xprt %p xid %08x\n",
-			__func__, ntohl(calldir),
-			bc_xprt, xid);
+	if (!bc_xprt)
 		return -EAGAIN;
-	}
+	spin_lock_bh(&bc_xprt->transport_lock);
+	req = xprt_lookup_rqst(bc_xprt, xid);
+	if (!req)
+		goto unlock_notfound;
 
 	memcpy(&req->rq_private_buf, &req->rq_rcv_buf, sizeof(struct xdr_buf));
 	/*
@@ -1076,11 +1071,21 @@ static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp)
 	dst = &req->rq_private_buf.head[0];
 	src = &rqstp->rq_arg.head[0];
 	if (dst->iov_len < src->iov_len)
-		return -EAGAIN; /* whatever; just giving up. */
+		goto unlock_eagain; /* whatever; just giving up. */
 	memcpy(dst->iov_base, src->iov_base, src->iov_len);
 	xprt_complete_rqst(req->rq_task, svsk->sk_reclen);
 	rqstp->rq_arg.len = 0;
+	spin_unlock_bh(&bc_xprt->transport_lock);
 	return 0;
+unlock_notfound:
+	printk(KERN_NOTICE
+		"%s: Got unrecognized reply: "
+		"calldir 0x%x xpt_bc_xprt %p xid %08x\n",
+		__func__, ntohl(calldir),
+		bc_xprt, ntohl(xid));
+unlock_eagain:
+	spin_unlock_bh(&bc_xprt->transport_lock);
+	return -EAGAIN;
 }
 
 static int copy_pages_to_kvecs(struct kvec *vec, struct page **pages, int len)
Signature · 1 line
1.9.1
#9 lore raw

PATCH 9/176 nfsd: Fix slot wake up race in the nfsv4.1 callback code

In reply to [email protected]

From: Trond Myklebust <[email protected]>

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

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

commit c6c15e1ed303ffc47e696ea1c9a9df1761c1f603 upstream.

The currect code for nfsd41_cb_get_slot() and nfsd4_cb_done() has no locking in order to guarantee atomicity, and so allows for races of the form.

Task 1 Task 2
====== ======

if (test_and_set_bit(0) != 0) {
                                        clear_bit(0)
                                        rpc_wake_up_next(queue)
        rpc_sleep_on(queue)
        return false;
}

This patch breaks the race condition by adding a retest of the bit after the call to rpc_sleep_on().

---
 fs/nfsd/nfs4callback.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
fs/nfsd/nfs4callback.c +6 -2
index c8e9f63..ebf3f59 100644
@@ -784,8 +784,12 @@ static bool nfsd41_cb_get_slot(struct nfs4_client *clp, struct rpc_task *task)
 {
 	if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) {
 		rpc_sleep_on(&clp->cl_cb_waitq, task, NULL);
-		dprintk("%s slot is busy\n", __func__);
-		return false;
+		/* Race breaker */
+		if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) {
+			dprintk("%s slot is busy\n", __func__);
+			return false;
+		}
+		rpc_wake_up_queued_task(&clp->cl_cb_waitq, task);
 	}
 	return true;
 }
Signature · 1 line
1.9.1
#10 lore raw

PATCH 10/176 bnx2fc: do not add shared skbs to the fcoe_rx_list

In reply to [email protected]

From: Maurizio Lombardi <[email protected]>

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

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

commit 01a4cc4d0cd6a836c7b923760e8eb1cbb6a47258 upstream.

In some cases, the fcoe_rx_list may contains multiple instances of the same skb (the so called "shared skbs").

the bnx2fc_l2_rcv thread is a loop that extracts a skb from the list, modifies (and destroys) its content and then proceed to the next one. The problem is that if the skb is shared, the remaining instances will be corrupted.

The solution is to use skb_share_check() before adding the skb to the fcoe_rx_list.

[ 6286.808725] ------------[ cut here ]------------
[ 6286.808729] WARNING: at include/scsi/fc_frame.h:173 bnx2fc_l2_rcv_thread+0x425/0x450 [bnx2fc]()
[ 6286.808748] Modules linked in: bnx2x(-) mdio dm_service_time bnx2fc cnic uio fcoe libfcoe 8021q garp stp mrp libfc llc scsi_transport_fc scsi_tgt sg iTCO_wdt iTCO_vendor_support coretemp kvm_intel kvm crct10dif_pclmul crc32_pclmul crc32c_intel e1000e ghash_clmulni_intel aesni_intel lrw gf128mul glue_helper ablk_helper ptp cryptd hpilo serio_raw hpwdt lpc_ich pps_core ipmi_si pcspkr mfd_core ipmi_msghandler shpchp pcc_cpufreq mperf nfsd auth_rpcgss nfs_acl lockd sunrpc dm_multipath xfs libcrc32c ata_generic pata_acpi sd_mod crc_t10dif crct10dif_common mgag200 syscopyarea sysfillrect sysimgblt i2c_algo_bit ata_piix drm_kms_helper ttm drm libata i2c_core hpsa dm_mirror dm_region_hash dm_log dm_mod [last unloaded: mdio]
[ 6286.808750] CPU: 3 PID: 1304 Comm: bnx2fc_l2_threa Not tainted 3.10.0-121.el7.x86_64 #1
[ 6286.808750] Hardware name: HP ProLiant DL120 G7, BIOS J01 07/01/2013
[ 6286.808752]  0000000000000000 000000000b36e715 ffff8800deba1e00 ffffffff815ec0ba
[ 6286.808753]  ffff8800deba1e38 ffffffff8105dee1 ffffffffa05618c0 ffff8801e4c81888
[ 6286.808754]  ffffe8ffff663868 ffff8801f402b180 ffff8801f56bc000 ffff8800deba1e48
[ 6286.808754] Call Trace:
[ 6286.808759]  [<ffffffff815ec0ba>] dump_stack+0x19/0x1b
[ 6286.808762]  [<ffffffff8105dee1>] warn_slowpath_common+0x61/0x80
[ 6286.808763]  [<ffffffff8105e00a>] warn_slowpath_null+0x1a/0x20
[ 6286.808765]  [<ffffffffa054f415>] bnx2fc_l2_rcv_thread+0x425/0x450 [bnx2fc]
[ 6286.808767]  [<ffffffffa054eff0>] ? bnx2fc_disable+0x90/0x90 [bnx2fc]
[ 6286.808769]  [<ffffffff81085aef>] kthread+0xcf/0xe0
[ 6286.808770]  [<ffffffff81085a20>] ? kthread_create_on_node+0x140/0x140
[ 6286.808772]  [<ffffffff815fc76c>] ret_from_fork+0x7c/0xb0
[ 6286.808773]  [<ffffffff81085a20>] ? kthread_create_on_node+0x140/0x140
[ 6286.808774] ---[ end trace c6cdb939184ccb4e ]---
---
 drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 7 +++++++
 1 file changed, 7 insertions(+)
drivers/scsi/bnx2fc/bnx2fc_fcoe.c +7 -0
index c1c6a92..cabfbf3 100644
@@ -406,6 +406,7 @@ static int bnx2fc_rcv(struct sk_buff *skb, struct net_device *dev,
 	struct fc_frame_header *fh;
 	struct fcoe_rcv_info *fr;
 	struct fcoe_percpu_s *bg;
+	struct sk_buff *tmp_skb;
 	unsigned short oxid;
 
 	interface = container_of(ptype, struct bnx2fc_interface,
@@ -417,6 +418,12 @@ static int bnx2fc_rcv(struct sk_buff *skb, struct net_device *dev,
 		goto err;
 	}
 
+	tmp_skb = skb_share_check(skb, GFP_ATOMIC);
+	if (!tmp_skb)
+		goto err;
+
+	skb = tmp_skb;
+
 	if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) {
 		printk(KERN_ERR PFX "bnx2fc_rcv: Wrong FC type frame\n");
 		goto err;
Signature · 1 line
1.9.1
#11 lore raw

PATCH 11/176 ARM: 8216/1: xscale: correct auxiliary register in suspend/resume

In reply to [email protected]

From: Dmitry Eremin-Solenikov <[email protected]>

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

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

commit ef59a20ba375aeb97b3150a118318884743452a8 upstream.

According to the manuals I have, XScale auxiliary register should be reached with opc_2 = 1 instead of crn = 1. cpu_xscale_proc_init correctly uses c1, c0, 1 arguments, but cpu_xscale_do_suspend and cpu_xscale_do_resume use c1, c1, 0. Correct suspend/resume functions to also use c1, c0, 1.

The issue was primarily noticed thanks to qemu reporing "unsupported instruction" on the pxa suspend path. Confirmed in PXA210/250 and PXA255 XScale Core manuals and in PXA270 and PXA320 Developers Guides.

Harware tested by me on tosa (pxa255). Robert confirmed on pxa270 board.

---
 arch/arm/mm/proc-xscale.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/mm/proc-xscale.S +2 -2
index 9882153..98646d0 100644
@@ -531,7 +531,7 @@ ENTRY(cpu_xscale_do_suspend)
 	mrc	p15, 0, r5, c15, c1, 0	@ CP access reg
 	mrc	p15, 0, r6, c13, c0, 0	@ PID
 	mrc	p15, 0, r7, c3, c0, 0	@ domain ID
-	mrc	p15, 0, r8, c1, c1, 0	@ auxiliary control reg
+	mrc	p15, 0, r8, c1, c0, 1	@ auxiliary control reg
 	mrc	p15, 0, r9, c1, c0, 0	@ control reg
 	bic	r4, r4, #2		@ clear frequency change bit
 	stmia	r0, {r4 - r9}		@ store cp regs
@@ -548,7 +548,7 @@ ENTRY(cpu_xscale_do_resume)
 	mcr	p15, 0, r6, c13, c0, 0	@ PID
 	mcr	p15, 0, r7, c3, c0, 0	@ domain ID
 	mcr	p15, 0, r1, c2, c0, 0	@ translation table base addr
-	mcr	p15, 0, r8, c1, c1, 0	@ auxiliary control reg
+	mcr	p15, 0, r8, c1, c0, 1	@ auxiliary control reg
 	mov	r0, r9			@ control register
 	b	cpu_resume_mmu
 ENDPROC(cpu_xscale_do_resume)
Signature · 1 line
1.9.1
#12 lore raw

PATCH 12/176 USB: xhci: don't start a halted endpoint before its new dequeue is set

In reply to [email protected]

From: Mathias Nyman <[email protected]>

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

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

commit c3492dbfa1050debf23a5b5cd2bc7514c5b37896 upstream.

A halted endpoint ring must first be reset, then move the ring dequeue pointer past the problematic TRB. If we start the ring too early after reset, but before moving the dequeue pointer we will end up executing the same problematic TRB again.

As we always issue a set transfer dequeue command after a reset endpoint command we can skip starting endpoint rings at reset endpoint command completion.

Without this fix we end up trying to handle the same faulty TD for contol endpoints. causing timeout, and failing testusb ctrl_out write tests.

Fixes e9df17e (USB: xhci: Correct assumptions about number of rings per endpoint.)
---
 drivers/usb/host/xhci-ring.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/usb/host/xhci-ring.c +1 -2
index 95e8648..0346e41 100644
@@ -1178,9 +1178,8 @@ static void handle_reset_ep_completion(struct xhci_hcd *xhci,
 				false);
 		xhci_ring_cmd_db(xhci);
 	} else {
-		/* Clear our internal halted state and restart the ring(s) */
+		/* Clear our internal halted state */
 		xhci->devs[slot_id]->eps[ep_index].ep_state &= ~EP_HALTED;
-		ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
 	}
 }
 
Signature · 1 line
1.9.1
#13 lore raw

PATCH 13/176 USB: xhci: Reset a halted endpoint immediately when we encounter a stall.

In reply to [email protected]

From: Mathias Nyman <[email protected]>

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

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

commit 8e71a322fdb127814bcba423a512914ca5bc6cf5 upstream.

If a device is halted and reuturns a STALL, then the halted endpoint needs to be cleared both on the host and device side. The host side halt is cleared by issueing a xhci reset endpoint command. The device side is cleared with a ClearFeature(ENDPOINT_HALT) request, which should be issued by the device driver if a URB reruen -EPIPE.

Previously we cleared the host side halt after the device side was cleared. To make sure the host side halt is cleared in time we want to issue the reset endpoint command immedialtely when a STALL status is encountered.

Otherwise we end up not following the specs and not returning -EPIPE several times in a row when trying to transfer data to a halted endpoint.

Fixes bcef3fd (USB: xhci: Handle errors that cause endpoint halts.)
[lizf: Backported to 3.4: adjust context]
---
 drivers/usb/host/xhci-ring.c | 40 +++++++----------------------
 drivers/usb/host/xhci.c      | 60 +++++++++++---------------------------------
 2 files changed, 24 insertions(+), 76 deletions(-)
drivers/usb/host/xhci-ring.c +9 -31
index 0346e41..950edeb 100644
@@ -1915,23 +1915,12 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td,
 		ep->stopped_trb = event_trb;
 		return 0;
 	} else {
-		if (trb_comp_code == COMP_STALL) {
-			/* The transfer is completed from the driver's
-			 * perspective, but we need to issue a set dequeue
-			 * command for this stalled endpoint to move the dequeue
-			 * pointer past the TD.  We can't do that here because
-			 * the halt condition must be cleared first.  Let the
-			 * USB class driver clear the stall later.
-			 */
-			ep->stopped_td = td;
-			ep->stopped_trb = event_trb;
-			ep->stopped_stream = ep_ring->stream_id;
-		} else if (xhci_requires_manual_halt_cleanup(xhci,
-					ep_ctx, trb_comp_code)) {
-			/* Other types of errors halt the endpoint, but the
-			 * class driver doesn't call usb_reset_endpoint() unless
-			 * the error is -EPIPE.  Clear the halted status in the
-			 * xHCI hardware manually.
+		if (trb_comp_code == COMP_STALL ||
+		    xhci_requires_manual_halt_cleanup(xhci, ep_ctx,
+						      trb_comp_code)) {
+			/* Issue a reset endpoint command to clear the host side			 * halt, followed by a set dequeue command to move the
+			 * dequeue pointer past the TD.
+			 * The class driver clears the device side halt later.
 			 */
 			xhci_cleanup_halted_endpoint(xhci,
 					slot_id, ep_index, ep_ring->stream_id,
@@ -2051,9 +2040,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
 		else
 			td->urb->actual_length = 0;
 
-		xhci_cleanup_halted_endpoint(xhci,
-			slot_id, ep_index, 0, td, event_trb);
-		return finish_td(xhci, td, event_trb, event, ep, status, true);
+		return finish_td(xhci, td, event_trb, event, ep, status, false);
 	}
 	/*
 	 * Did we transfer any data, despite the errors that might have
@@ -2605,17 +2592,8 @@ cleanup:
 		if (ret) {
 			urb = td->urb;
 			urb_priv = urb->hcpriv;
-			/* Leave the TD around for the reset endpoint function
-			 * to use(but only if it's not a control endpoint,
-			 * since we already queued the Set TR dequeue pointer
-			 * command for stalled control endpoints).
-			 */
-			if (usb_endpoint_xfer_control(&urb->ep->desc) ||
-				(trb_comp_code != COMP_STALL &&
-					trb_comp_code != COMP_BABBLE))
-				xhci_urb_free_priv(xhci, urb_priv);
-			else
-				kfree(urb_priv);
+
+			xhci_urb_free_priv(xhci, urb_priv);
 
 			usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb);
 			if ((urb->actual_length != urb->transfer_buffer_length &&
drivers/usb/host/xhci.c +15 -45

76 lines not on this page · raw message

Signature · 1 line
1.9.1
#14 lore raw

PATCH 14/176 usb: xhci: rework root port wake bits if controller isn't allowed to wakeup

In reply to [email protected]

From: Lu Baolu <[email protected]>

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

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

commit a1377e5397ab321e21b793ec8cd2b6f12bd3c718 upstream.

When system is being suspended, if host device is not allowed to do wakeup, xhci_suspend() needs to clear all root port wake on bits. Otherwise, some platforms may generate spurious wakeup, even if PCI PME# is disabled.

The initial commit ff8cbf250b44 ("xhci: clear root port wake on bits"), which also got into stable, turned out to not work correctly and had to be reverted, and is now rewritten.

[lizf: Backported to 3.4:
- adjust context
- drop changes to xhci_plat_suspend()]

---
 drivers/usb/host/xhci-pci.c |  2 +-
 drivers/usb/host/xhci.c     | 42 +++++++++++++++++++++++++++++++++++++++++-
 drivers/usb/host/xhci.h     |  2 +-
 3 files changed, 43 insertions(+), 3 deletions(-)
drivers/usb/host/xhci-pci.c +1 -1
index c8835d5..c9e39d4 100644
@@ -238,7 +238,7 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
 			xhci->shared_hcd->state != HC_STATE_SUSPENDED)
 		return -EINVAL;
 
-	retval = xhci_suspend(xhci);
+	retval = xhci_suspend(xhci, do_wakeup);
 
 	return retval;
 }
drivers/usb/host/xhci.c +41 -1

66 lines not on this page · raw message

drivers/usb/host/xhci.h +1 -1
index 2b7fe0b..6c809350 100644
@@ -1729,7 +1729,7 @@ void xhci_shutdown(struct usb_hcd *hcd);
 int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks);
 
 #ifdef	CONFIG_PM
-int xhci_suspend(struct xhci_hcd *xhci);
+int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup);
 int xhci_resume(struct xhci_hcd *xhci, bool hibernated);
 #else
 #define	xhci_suspend	NULL
Signature · 1 line
1.9.1
#15 lore raw

PATCH 15/176 ALSA: hda - Limit 40bit DMA for AMD HDMI controllers

In reply to [email protected]

From: Takashi Iwai <[email protected]>

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

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

commit 413cbf469a19e7662ba5025695bf5a573927105a upstream.

AMD/ATI HDMI controller chip models, we already have a filter to lower to 32bit DMA, but the rest are supposed to be working with 64bit although the hardware doesn't really work with 63bit but only with 40 or 48bit DMA. In this patch, we take 40bit DMA for safety for the AMD/ATI controllers as the graphics drivers does.

[lizf: Backported to 3.4:
- adjust context
- s/AZX_GCAP_640K/ICH6_GCAP_64OK]

---
 sound/pci/hda/hda_intel.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)
sound/pci/hda/hda_intel.c +11 -3
index 33e538f..f461737 100644
@@ -2685,6 +2685,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
 	struct azx *chip;
 	int i, err;
 	unsigned short gcap;
+	unsigned int dma_bits = 64;
 	static struct snd_device_ops ops = {
 		.dev_free = azx_dev_free,
 	};
@@ -2780,9 +2781,14 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
 	gcap = azx_readw(chip, GCAP);
 	snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap);
 
+	/* AMD devices support 40 or 48bit DMA, take the safe one */
+	if (chip->pci->vendor == PCI_VENDOR_ID_AMD)
+		dma_bits = 40;
+
 	/* disable SB600 64bit support for safety */
 	if (chip->pci->vendor == PCI_VENDOR_ID_ATI) {
 		struct pci_dev *p_smbus;
+		dma_bits = 40;
 		p_smbus = pci_get_device(PCI_VENDOR_ID_ATI,
 					 PCI_DEVICE_ID_ATI_SBX00_SMBUS,
 					 NULL);
@@ -2812,9 +2818,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
 	}
 
 	/* allow 64bit DMA address if supported by H/W */
-	if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
-		pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
-	else {
+	if (!(gcap & ICH6_GCAP_64OK))
+		dma_bits = 32;
+	if (!pci_set_dma_mask(pci, DMA_BIT_MASK(dma_bits))) {
+		pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(dma_bits));
+	} else {
 		pci_set_dma_mask(pci, DMA_BIT_MASK(32));
 		pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32));
 	}
Signature · 1 line
1.9.1
#16 lore raw

PATCH 16/176 MIPS: Loongson: Make platform serial setup always built-in.

In reply to [email protected]

From: Aaro Koskinen <[email protected]>

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

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

commit 26927f76499849e095714452b8a4e09350f6a3b9 upstream.

If SERIAL_8250 is compiled as a module, the platform specific setup for Loongson will be a module too, and it will not work very well. At least on Loongson 3 it will trigger a build failure, since loongson_sysconf is not exported to modules.

Fix by making the platform specific serial code always built-in.

Patchwork: https://patchwork.linux-mips.org/patch/8533/

---
 arch/mips/loongson/common/Makefile | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/mips/loongson/common/Makefile +2 -1
index e526488..ce415f7 100644
@@ -10,7 +10,8 @@ obj-$(CONFIG_GENERIC_GPIO) += gpio.o
 # Serial port support
 #
 obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
-obj-$(CONFIG_SERIAL_8250) += serial.o
+loongson-serial-$(CONFIG_SERIAL_8250) := serial.o
+obj-y += $(loongson-serial-m) $(loongson-serial-y)
 obj-$(CONFIG_LOONGSON_UART_BASE) += uart_base.o
 obj-$(CONFIG_LOONGSON_MC146818) += rtc.o
 
Signature · 1 line
1.9.1
#17 lore raw

PATCH 17/176 usb-quirks: Add reset-resume quirk for MS Wireless Laser Mouse 6000

In reply to [email protected]

From: Hans de Goede <[email protected]>

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

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

commit 263e80b43559a6103e178a9176938ce171b23872 upstream.

This wireless mouse receiver needs a reset-resume quirk to properly come out of reset.

---
 drivers/usb/core/quirks.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/usb/core/quirks.c +3 -0
index 980a9d8..ada0df9 100644
@@ -43,6 +43,9 @@ static const struct usb_device_id usb_quirk_list[] = {
 	/* Creative SB Audigy 2 NX */
 	{ USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
 
+	/* Microsoft Wireless Laser Mouse 6000 Receiver */
+	{ USB_DEVICE(0x045e, 0x00e1), .driver_info = USB_QUIRK_RESET_RESUME },
+
 	/* Microsoft LifeCam-VX700 v2.0 */
 	{ USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME },
 
Signature · 1 line
1.9.1
#18 lore raw

PATCH 18/176 Input: xpad - use proper endpoint type

In reply to [email protected]

From: Greg Kroah-Hartman <[email protected]>

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

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

commit a1f9a4072655843fc03186acbad65990cc05dd2d upstream.

The xpad wireless endpoint is not a bulk endpoint on my devices, but rather an interrupt one, so the USB core complains when it is submitted. I'm guessing that the author really did mean that this should be an interrupt urb, but as there are a zillion different xpad devices out there, let's cover out bases and handle both bulk and interrupt endpoints just as easily.

---
 drivers/input/joystick/xpad.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)
drivers/input/joystick/xpad.c +13 -3
index 42f7b25..b4e8db8 100644
@@ -979,9 +979,19 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
 		}
 
 		ep_irq_in = &intf->cur_altsetting->endpoint[1].desc;
-		usb_fill_bulk_urb(xpad->bulk_out, udev,
-				usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress),
-				xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad);
+		if (usb_endpoint_is_bulk_out(ep_irq_in)) {
+			usb_fill_bulk_urb(xpad->bulk_out, udev,
+					  usb_sndbulkpipe(udev,
+							  ep_irq_in->bEndpointAddress),
+					  xpad->bdata, XPAD_PKT_LEN,
+					  xpad_bulk_out, xpad);
+		} else {
+			usb_fill_int_urb(xpad->bulk_out, udev,
+					 usb_sndintpipe(udev,
+							ep_irq_in->bEndpointAddress),
+					 xpad->bdata, XPAD_PKT_LEN,
+					 xpad_bulk_out, xpad, 0);
+		}
 
 		/*
 		 * Submit the int URB immediately rather than waiting for open
Signature · 1 line
1.9.1
#19 lore raw

PATCH 19/176 powerpc/pseries: Fix endiannes issue in RTAS call from xmon

In reply to [email protected]

From: Laurent Dufour <[email protected]>

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

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

commit 3b8a3c01096925a824ed3272601082289d9c23a5 upstream.

On pseries system (LPAR) xmon failed to enter when running in LE mode, system is hunging. Inititating xmon will lead to such an output on the console:

SysRq : Entering xmon
cpu 0x15: Vector: 0 at [c0000003f39ffb10]

    pc: c00000000007ed7c: sysrq_handle_xmon+0x5c/0x70
    lr: c00000000007ed7c: sysrq_handle_xmon+0x5c/0x70
    sp: c0000003f39ffc70
   msr: 8000000000009033
  current = 0xc0000003fafa7180
  paca    = 0xc000000007d75e80	 softe: 0	 irq_happened: 0x01
    pid   = 14617, comm = bash
Bad kernel stack pointer fafb4b0 at eca7cc4
cpu 0x15: Vector: 300 (Data Access) at [c000000007f07d40]
    pc: 000000000eca7cc4
    lr: 000000000eca7c44
    sp: fafb4b0
   msr: 8000000000001000
   dar: 10000000
 dsisr: 42000000
  current = 0xc0000003fafa7180
  paca    = 0xc000000007d75e80	 softe: 0	 irq_happened: 0x01
    pid   = 14617, comm = bash

cpu 0x15: Exception 300 (Data Access) in xmon, returning to main loop
xmon: WARNING: bad recursive fault on cpu 0x15

The root cause is that xmon is calling RTAS to turn off the surveillance when entering xmon, and RTAS is requiring big endian parameters.

This patch is byte swapping the RTAS arguments when running in LE mode.

---
 arch/powerpc/xmon/xmon.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
arch/powerpc/xmon/xmon.c +3 -3
index eab3492..3c3fc92 100644
@@ -285,10 +285,10 @@ static inline void disable_surveillance(void)
 	args.token = rtas_token("set-indicator");
 	if (args.token == RTAS_UNKNOWN_SERVICE)
 		return;
-	args.nargs = 3;
-	args.nret = 1;
+	args.nargs = cpu_to_be32(3);
+	args.nret = cpu_to_be32(1);
 	args.rets = &args.args[3];
-	args.args[0] = SURVEILLANCE_TOKEN;
+	args.args[0] = cpu_to_be32(SURVEILLANCE_TOKEN);
 	args.args[1] = 0;
 	args.args[2] = 0;
 	enter_rtas(__pa(&args));
Signature · 1 line
1.9.1
#20 lore raw

PATCH 20/176 drm/i915: Unlock panel even when LVDS is disabled

In reply to [email protected]

From: Daniel Vetter <[email protected]>

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

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

commit b0616c5306b342ceca07044dbc4f917d95c4f825 upstream.

Otherwise we'll have backtraces in assert_panel_unlocked because the BIOS locks the register. In the reporter's case this regression was introduced in

commit c31407a3672aaebb4acddf90944a114fa5c8af7b

Author: Chris Wilson <[email protected]>
Date:   Thu Oct 18 21:07:01 2012 +0100

drm/i915: Add no-lvds quirk for Supermicro X7SPA-H

Cc Alexey Orishko <[email protected]>
Cc Chris Wilson <[email protected]>
Cc Francois Tigeot <[email protected]>
[lizf: Backported to 3.4: adjust context]
---
 drivers/gpu/drm/i915/intel_lvds.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)
drivers/gpu/drm/i915/intel_lvds.c +11 -13
index 77190cc..3febe29 100644
@@ -932,6 +932,17 @@ bool intel_lvds_init(struct drm_device *dev)
 	int pipe;
 	u8 pin;
 
+	/*
+	 * Unlock registers and just leave them unlocked. Do this before
+	 * checking quirk lists to avoid bogus WARNINGs.
+	 */
+	if (HAS_PCH_SPLIT(dev)) {
+		I915_WRITE(PCH_PP_CONTROL,
+			   I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS);
+	} else {
+		I915_WRITE(PP_CONTROL,
+			   I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS);
+	}
 	if (!intel_lvds_supported(dev))
 		return false;
 
@@ -1109,19 +1120,6 @@ out:
 		pwm = I915_READ(BLC_PWM_PCH_CTL1);
 		pwm |= PWM_PCH_ENABLE;
 		I915_WRITE(BLC_PWM_PCH_CTL1, pwm);
-		/*
-		 * Unlock registers and just
-		 * leave them unlocked
-		 */
-		I915_WRITE(PCH_PP_CONTROL,
-			   I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS);
-	} else {
-		/*
-		 * Unlock registers and just
-		 * leave them unlocked
-		 */
-		I915_WRITE(PP_CONTROL,
-			   I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS);
 	}
 	dev_priv->lid_notifier.notifier_call = intel_lid_notify;
 	if (acpi_lid_notifier_register(&dev_priv->lid_notifier)) {
Signature · 1 line
1.9.1
#21 lore raw

PATCH 21/176 AHCI: Add DeviceIDs for Sunrise Point-LP SATA controller

In reply to [email protected]

From: Devin Ryles <[email protected]>

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

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

commit 249cd0a187ed4ef1d0af7f74362cc2791ec5581b upstream.

This patch adds DeviceIDs for Sunrise Point-LP.

---
 drivers/ata/ahci.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/ata/ahci.c +3 -0
index ca9a287..63e2f67 100644
@@ -313,6 +313,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
 	{ PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */
 	{ PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */
 	{ PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */
+	{ PCI_VDEVICE(INTEL, 0x9d03), board_ahci }, /* Sunrise Point-LP AHCI */
+	{ PCI_VDEVICE(INTEL, 0x9d05), board_ahci }, /* Sunrise Point-LP RAID */
+	{ PCI_VDEVICE(INTEL, 0x9d07), board_ahci }, /* Sunrise Point-LP RAID */
 	{ PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */
 	{ PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H RAID */
 	{ PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */
Signature · 1 line
1.9.1
#22 lore raw

PATCH 22/176 sata_fsl: fix error handling of irq_of_parse_and_map

In reply to [email protected]

From: Dmitry Torokhov <[email protected]>

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

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

commit aad0b624129709c94c2e19e583b6053520353fa8 upstream.

irq_of_parse_and_map() returns 0 on error (the result is unsigned int), so testing for negative result never works.

---
 drivers/ata/sata_fsl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ata/sata_fsl.c +1 -1
index d6577b9..3d3b59a 100644
@@ -1426,7 +1426,7 @@ static int sata_fsl_probe(struct platform_device *ofdev)
 	host_priv->csr_base = csr_base;
 
 	irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
-	if (irq < 0) {
+	if (!irq) {
 		dev_err(&ofdev->dev, "invalid irq from platform\n");
 		goto error_exit_with_cleanup;
 	}
Signature · 1 line
1.9.1
#23 lore raw

PATCH 23/176 drm/radeon: kernel panic in drm_calc_vbltimestamp_from_scanoutpos with 3.18.0-rc6

In reply to [email protected]

From: Petr Mladek <[email protected]>

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

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

commit f5475cc43c899e33098d4db44b7c5e710f16589d upstream.

I was unable too boot 3.18.0-rc6 because of the following kernel panic in drm_calc_vbltimestamp_from_scanoutpos():

    [drm] Initialized drm 1.1.0 20060810
    [drm] radeon kernel modesetting enabled.
    [drm] initializing kernel modesetting (RV100 0x1002:0x515E 0x15D9:0x8080).
    [drm] register mmio base: 0xC8400000
    [drm] register mmio size: 65536
    radeon 0000:0b:01.0: VRAM: 128M 0x00000000D0000000 - 0x00000000D7FFFFFF (16M used)
    radeon 0000:0b:01.0: GTT: 512M 0x00000000B0000000 - 0x00000000CFFFFFFF
    [drm] Detected VRAM RAM=128M, BAR=128M
    [drm] RAM width 16bits DDR
    [TTM] Zone  kernel: Available graphics memory: 3829346 kiB
    [TTM] Zone   dma32: Available graphics memory: 2097152 kiB
    [TTM] Initializing pool allocator
    [TTM] Initializing DMA pool allocator
    [drm] radeon: 16M of VRAM memory ready
    [drm] radeon: 512M of GTT memory ready.
    [drm] GART: num cpu pages 131072, num gpu pages 131072
    [drm] PCI GART of 512M enabled (table at 0x0000000037880000).
    radeon 0000:0b:01.0: WB disabled
    radeon 0000:0b:01.0: fence driver on ring 0 use gpu addr 0x00000000b0000000 and cpu addr 0xffff8800bbbfa000
    [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
    [drm] Driver supports precise vblank timestamp query.
    [drm] radeon: irq initialized.
    [drm] Loading R100 Microcode
    radeon 0000:0b:01.0: Direct firmware load for radeon/R100_cp.bin failed with error -2
    radeon_cp: Failed to load firmware "radeon/R100_cp.bin"
    [drm:r100_cp_init] *ERROR* Failed to load firmware!
    radeon 0000:0b:01.0: failed initializing CP (-2).
    radeon 0000:0b:01.0: Disabling GPU acceleration
    [drm] radeon: cp finalized
    BUG: unable to handle kernel NULL pointer dereference at 000000000000025c
    IP: [<ffffffff8150423b>] drm_calc_vbltimestamp_from_scanoutpos+0x4b/0x320
    PGD 0
    Oops: 0000 [#1] SMP
    Modules linked in:
    CPU: 1 PID: 1 Comm: swapper/0 Not tainted 3.18.0-rc6-4-default #2649
    Hardware name: Supermicro X7DB8/X7DB8, BIOS 6.00 07/26/2006
    task: ffff880234da2010 ti: ffff880234da4000 task.ti: ffff880234da4000
    RIP: 0010:[<ffffffff8150423b>]  [<ffffffff8150423b>] drm_calc_vbltimestamp_from_scanoutpos+0x4b/0x320
    RSP: 0000:ffff880234da7918  EFLAGS: 00010086
    RAX: ffffffff81557890 RBX: 0000000000000000 RCX: ffff880234da7a48
    RDX: ffff880234da79f4 RSI: 0000000000000000 RDI: ffff880232e15000
    RBP: ffff880234da79b8 R08: 0000000000000000 R09: 0000000000000000
    R10: 000000000000000a R11: 0000000000000001 R12: ffff880232dda1c0
    R13: ffff880232e1518c R14: 0000000000000292 R15: ffff880232e15000
    FS:  0000000000000000(0000) GS:ffff88023fc40000(0000) knlGS:0000000000000000
    CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
    CR2: 000000000000025c CR3: 0000000002014000 CR4: 00000000000007e0
    Stack:
     ffff880234da79d8 0000000000000286 ffff880232dcbc00 0000000000002480
     ffff880234da7958 0000000000000296 ffff880234da7998 ffffffff8151b51d
     ffff880234da7a48 0000000032dcbeb0 ffff880232dcbc00 ffff880232dcbc58
    Call Trace:
     [<ffffffff8151b51d>] ? drm_vma_offset_remove+0x1d/0x110
     [<ffffffff8152dc98>] radeon_get_vblank_timestamp_kms+0x38/0x60
     [<ffffffff8152076a>] ? ttm_bo_release_list+0xba/0x180
     [<ffffffff81503751>] drm_get_last_vbltimestamp+0x41/0x70
     [<ffffffff81503933>] vblank_disable_and_save+0x73/0x1d0
     [<ffffffff81106b2f>] ? try_to_del_timer_sync+0x4f/0x70
     [<ffffffff81505245>] drm_vblank_cleanup+0x65/0xa0
     [<ffffffff815604fa>] radeon_irq_kms_fini+0x1a/0x70
     [<ffffffff8156c07e>] r100_init+0x26e/0x410
     [<ffffffff8152ae3e>] radeon_device_init+0x7ae/0xb50
     [<ffffffff8152d57f>] radeon_driver_load_kms+0x8f/0x210
     [<ffffffff81506965>] drm_dev_register+0xb5/0x110
     [<ffffffff8150998f>] drm_get_pci_dev+0x8f/0x200
     [<ffffffff815291cd>] radeon_pci_probe+0xad/0xe0
     [<ffffffff8141a365>] local_pci_probe+0x45/0xa0
     [<ffffffff8141b741>] pci_device_probe+0xd1/0x130
     [<ffffffff81633dad>] driver_probe_device+0x12d/0x3e0
     [<ffffffff8163413b>] __driver_attach+0x9b/0xa0
     [<ffffffff816340a0>] ? __device_attach+0x40/0x40
     [<ffffffff81631cd3>] bus_for_each_dev+0x63/0xa0
     [<ffffffff8163378e>] driver_attach+0x1e/0x20
     [<ffffffff81633390>] bus_add_driver+0x180/0x240
     [<ffffffff81634914>] driver_register+0x64/0xf0
     [<ffffffff81419cac>] __pci_register_driver+0x4c/0x50
     [<ffffffff81509bf5>] drm_pci_init+0xf5/0x120
     [<ffffffff821dc871>] ? ttm_init+0x6a/0x6a
     [<ffffffff821dc908>] radeon_init+0x97/0xb5
     [<ffffffff810002fc>] do_one_initcall+0xbc/0x1f0
     [<ffffffff810e3278>] ? __wake_up+0x48/0x60
     [<ffffffff8218e256>] kernel_init_freeable+0x18a/0x215
     [<ffffffff8218d983>] ? initcall_blacklist+0xc0/0xc0
     [<ffffffff818a78f0>] ? rest_init+0x80/0x80
     [<ffffffff818a78fe>] kernel_init+0xe/0xf0
     [<ffffffff818c0c3c>] ret_from_fork+0x7c/0xb0
     [<ffffffff818a78f0>] ? rest_init+0x80/0x80
    Code: 45 ac 0f 88 a8 01 00 00 3b b7 d0 01 00 00 49 89 ff 0f 83 99 01 00 00 48 8b 47 20 48 8b 80 88 00 00 00 48 85 c0 0f 84 cd 01 00 00 <41> 8b b1 5c 02 00 00 41 8b 89 58 02 00 00 89 75 98 41 8b b1 60
    RIP  [<ffffffff8150423b>] drm_calc_vbltimestamp_from_scanoutpos+0x4b/0x320
     RSP <ffff880234da7918>
    CR2: 000000000000025c
    ---[ end trace ad2c0aadf48e2032 ]---
    Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009

It has helped me to add a NULL pointer check that was suggested at
http://lists.freedesktop.org/archives/dri-devel/2014-October/070663.html

I am not familiar with the code. But the change looks sane and we need something fast at this stage of 3.18 development.

---
 drivers/gpu/drm/radeon/radeon_kms.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/gpu/drm/radeon/radeon_kms.c +2 -0
index 9b46238..b731686 100644
@@ -428,6 +428,8 @@ int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc,
 
 	/* Get associated drm_crtc: */
 	drmcrtc = &rdev->mode_info.crtcs[crtc]->base;
+	if (!drmcrtc)
+		return -EINVAL;
 
 	/* Helper routine in DRM core does all the work: */
 	return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error,
Signature · 1 line
1.9.1
#24 lore raw

PATCH 24/176 mm: fix swapoff hang after page migration and fork

In reply to [email protected]

From: Hugh Dickins <[email protected]>

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

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

commit 2022b4d18a491a578218ce7a4eca8666db895a73 upstream.

I've been seeing swapoff hangs in recent testing: it's cycling around trying unsuccessfully to find an mm for some remaining pages of swap.

I have been exercising swap and page migration more heavily recently, and now notice a long-standing error in copy_one_pte(): it's trying to add dst_mm to swapoff's mmlist when it finds a swap entry, but is doing so even when it's a migration entry or an hwpoison entry.

Which wouldn't matter much, except it adds dst_mm next to src_mm, assuming src_mm is already on the mmlist: which may not be so. Then if pages are later swapped out from dst_mm, swapoff won't be able to find where to replace them.

There's already a !non_swap_entry() test for stats: move that up before the swap_duplicate() and the addition to mmlist.

---
 mm/memory.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)
mm/memory.c +13 -13
index c34e60a..60ead07 100644
@@ -847,20 +847,20 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
 		if (!pte_file(pte)) {
 			swp_entry_t entry = pte_to_swp_entry(pte);
 
-			if (swap_duplicate(entry) < 0)
-				return entry.val;
-
-			/* make sure dst_mm is on swapoff's mmlist. */
-			if (unlikely(list_empty(&dst_mm->mmlist))) {
-				spin_lock(&mmlist_lock);
-				if (list_empty(&dst_mm->mmlist))
-					list_add(&dst_mm->mmlist,
-						 &src_mm->mmlist);
-				spin_unlock(&mmlist_lock);
-			}
-			if (likely(!non_swap_entry(entry)))
+			if (likely(!non_swap_entry(entry))) {
+				if (swap_duplicate(entry) < 0)
+					return entry.val;
+
+				/* make sure dst_mm is on swapoff's mmlist. */
+				if (unlikely(list_empty(&dst_mm->mmlist))) {
+					spin_lock(&mmlist_lock);
+					if (list_empty(&dst_mm->mmlist))
+						list_add(&dst_mm->mmlist,
+							 &src_mm->mmlist);
+					spin_unlock(&mmlist_lock);
+				}
 				rss[MM_SWAPENTS]++;
-			else if (is_migration_entry(entry)) {
+			} else if (is_migration_entry(entry)) {
 				page = migration_entry_to_page(entry);
 
 				if (PageAnon(page))
Signature · 1 line
1.9.1
#25 lore raw

PATCH 25/176 ahci: disable NCQ on Samsung pci-e SSDs on macbooks

In reply to [email protected]

From: Levente Kurusa <[email protected]>

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

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

commit 67809f85d31eac600f6b28defa5386c9d2a13b1d upstream.

Samsung's pci-e SSDs with device ID 0x1600 which are found on some macbooks time out on NCQ commands. Blacklist NCQ on the device so that the affected machines can at least boot.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=60731

[lizf: Backported to 3.4: adjust context]
---
 drivers/ata/ahci.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
drivers/ata/ahci.c +14 -0
index 63e2f67..a3d2d37 100644
@@ -61,6 +61,7 @@ enum board_ids {
 	/* board IDs by feature in alphabetical order */
 	board_ahci,
 	board_ahci_ign_iferr,
+	board_ahci_noncq,
 	board_ahci_nosntf,
 	board_ahci_yes_fbs,
 
@@ -121,6 +122,13 @@ static const struct ata_port_info ahci_port_info[] = {
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &ahci_ops,
 	},
+	[board_ahci_noncq] = {
+		AHCI_HFLAGS	(AHCI_HFLAG_NO_NCQ),
+		.flags		= AHCI_FLAG_COMMON,
+		.pio_mask	= ATA_PIO4,
+		.udma_mask	= ATA_UDMA6,
+		.port_ops	= &ahci_ops,
+	},
 	[board_ahci_nosntf] =
 	{
 		AHCI_HFLAGS	(AHCI_HFLAG_NO_SNTF),
@@ -472,6 +480,12 @@ static const struct pci_device_id ahci_pci_tbl[] = {
 	{ PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci },	/* ASM1061 */
 	{ PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci },	/* ASM1062 */
 
+	/*
+	 * Samsung SSDs found on some macbooks.  NCQ times out.
+	 * https://bugzilla.kernel.org/show_bug.cgi?id=60731
+	 */
+	{ PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_noncq },
+
 	/* Enmotus */
 	{ PCI_DEVICE(0x1c44, 0x8000), board_ahci },
 
Signature · 1 line
1.9.1
#26 lore raw

PATCH 26/176 ahci: disable MSI instead of NCQ on Samsung pci-e SSDs on macbooks

In reply to [email protected]

From: Tejun Heo <[email protected]>

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

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

commit 66a7cbc303f4d28f201529b06061944d51ab530c upstream.

Samsung pci-e SSDs on macbooks failed miserably on NCQ commands, so 67809f85d31e ("ahci: disable NCQ on Samsung pci-e SSDs on macbooks") disabled NCQ on them. It turns out that NCQ is fine as long as MSI is not used, so let's turn off MSI and leave NCQ on.

Fixes 67809f85d31e ("ahci: disable NCQ on Samsung pci-e SSDs on macbooks")
---
 drivers/ata/ahci.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)
drivers/ata/ahci.c +11 -3
index a3d2d37..4aa63bf 100644
@@ -61,6 +61,7 @@ enum board_ids {
 	/* board IDs by feature in alphabetical order */
 	board_ahci,
 	board_ahci_ign_iferr,
+	board_ahci_nomsi,
 	board_ahci_noncq,
 	board_ahci_nosntf,
 	board_ahci_yes_fbs,
@@ -122,6 +123,13 @@ static const struct ata_port_info ahci_port_info[] = {
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &ahci_ops,
 	},
+	[board_ahci_nomsi] = {
+		AHCI_HFLAGS	(AHCI_HFLAG_NO_MSI),
+		.flags		= AHCI_FLAG_COMMON,
+		.pio_mask	= ATA_PIO4,
+		.udma_mask	= ATA_UDMA6,
+		.port_ops	= &ahci_ops,
+	},
 	[board_ahci_noncq] = {
 		AHCI_HFLAGS	(AHCI_HFLAG_NO_NCQ),
 		.flags		= AHCI_FLAG_COMMON,
@@ -481,10 +489,10 @@ static const struct pci_device_id ahci_pci_tbl[] = {
 	{ PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci },	/* ASM1062 */
 
 	/*
-	 * Samsung SSDs found on some macbooks.  NCQ times out.
-	 * https://bugzilla.kernel.org/show_bug.cgi?id=60731
+	 * Samsung SSDs found on some macbooks.  NCQ times out if MSI is
+	 * enabled.  https://bugzilla.kernel.org/show_bug.cgi?id=60731
 	 */
-	{ PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_noncq },
+	{ PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_nomsi },
 
 	/* Enmotus */
 	{ PCI_DEVICE(0x1c44, 0x8000), board_ahci },
Signature · 1 line
1.9.1
#27 lore raw

PATCH 27/176 ahci: disable MSI on SAMSUNG 0xa800 SSD

In reply to [email protected]

From: Tejun Heo <[email protected]>

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

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

commit 2b21ef0aae65f22f5ba86b13c4588f6f0c2dbefb upstream.

Just like 0x1600 which got blacklisted by 66a7cbc303f4 ("ahci: disable MSI instead of NCQ on Samsung pci-e SSDs on macbooks"), 0xa800 chokes on NCQ commands if MSI is enabled. Disable MSI.

---
 drivers/ata/ahci.c | 1 +
 1 file changed, 1 insertion(+)
drivers/ata/ahci.c +1 -0
index 4aa63bf..6fc61eb 100644
@@ -493,6 +493,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
 	 * enabled.  https://bugzilla.kernel.org/show_bug.cgi?id=60731
 	 */
 	{ PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_nomsi },
+	{ PCI_VDEVICE(SAMSUNG, 0xa800), board_ahci_nomsi },
 
 	/* Enmotus */
 	{ PCI_DEVICE(0x1c44, 0x8000), board_ahci },
Signature · 1 line
1.9.1
#28 lore raw

PATCH 28/176 i2c: davinci: generate STP always when NACK is received

In reply to [email protected]

From: Grygorii Strashko <[email protected]>

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

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

commit 9ea359f7314132cbcb5a502d2d8ef095be1f45e4 upstream.

According to I2C specification the NACK should be handled as follows:
"When SDA remains HIGH during this ninth clock pulse, this is defined as the Not Acknowledge signal. The master can then generate either a STOP condition to abort the transfer, or a repeated START condition to start a new transfer." [I2C spec Rev. 6, 3.1.6: http://www.nxp.com/documents/user_manual/UM10204.pdf]

Currently the Davinci i2c driver interrupts the transfer on receipt of a NACK but fails to send a STOP in some situations and so makes the bus stuck until next I2C IP reset (idle/enable).

For example, the issue will happen during SMBus read transfer which consists from two i2c messages write command/address and read data:

S Slave Address Wr A Command Code A Sr Slave Address Rd A D1..Dn A P <--- write -----------------------> <--- read --------------------->

The I2C client device will send NACK if it can't recognize "Command Code" and it's expected from I2C master to generate STP in this case. But now, Davinci i2C driver will just exit with -EREMOTEIO and STP will not be generated.

Hence, fix it by generating Stop condition (STP) always when NACK is received.

This patch fixes Davinci I2C in the same way it was done for OMAP I2C commit cda2109a26eb ("i2c: omap: query STP always when NACK is received").

---
 drivers/i2c/busses/i2c-davinci.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)
drivers/i2c/busses/i2c-davinci.c +3 -5
index 79b4bcb..1837fe6 100644
@@ -416,11 +416,9 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
 	if (dev->cmd_err & DAVINCI_I2C_STR_NACK) {
 		if (msg->flags & I2C_M_IGNORE_NAK)
 			return msg->len;
-		if (stop) {
-			w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
-			w |= DAVINCI_I2C_MDR_STP;
-			davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
-		}
+		w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
+		w |= DAVINCI_I2C_MDR_STP;
+		davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
 		return -EREMOTEIO;
 	}
 	return -EIO;
Signature · 1 line
1.9.1
#29 lore raw

PATCH 29/176 eCryptfs: Force RO mount when encrypted view is enabled

In reply to [email protected]

From: Tyler Hicks <[email protected]>

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

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

commit 332b122d39c9cbff8b799007a825d94b2e7c12f2 upstream.

The ecryptfs_encrypted_view mount option greatly changes the functionality of an eCryptfs mount. Instead of encrypting and decrypting lower files, it provides a unified view of the encrypted files in the lower filesystem. The presence of the ecryptfs_encrypted_view mount option is intended to force a read-only mount and modifying files is not supported when the feature is in use. See the following commit for more information:

e77a56d [PATCH] eCryptfs: Encrypted passthrough

This patch forces the mount to be read-only when the ecryptfs_encrypted_view mount option is specified by setting the MS_RDONLY flag on the superblock. Additionally, this patch removes some broken logic in ecryptfs_open() that attempted to prevent modifications of files when the encrypted view feature was in use. The check in ecryptfs_open() was not sufficient to prevent file modifications using system calls that do not operate on a file descriptor.

[lizf: Backported to 3.4: adjust context]
---
 fs/ecryptfs/file.c | 12 ------------
 fs/ecryptfs/main.c | 16 +++++++++++++---
 2 files changed, 13 insertions(+), 15 deletions(-)
fs/ecryptfs/file.c +0 -12
index d45ba45..f04aa33 100644
@@ -195,24 +195,12 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
 {
 	int rc = 0;
 	struct ecryptfs_crypt_stat *crypt_stat = NULL;
-	struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
 	struct dentry *ecryptfs_dentry = file->f_path.dentry;
 	/* Private value of ecryptfs_dentry allocated in
 	 * ecryptfs_lookup() */
 	struct dentry *lower_dentry;
 	struct ecryptfs_file_info *file_info;
 
-	mount_crypt_stat = &ecryptfs_superblock_to_private(
-		ecryptfs_dentry->d_sb)->mount_crypt_stat;
-	if ((mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED)
-	    && ((file->f_flags & O_WRONLY) || (file->f_flags & O_RDWR)
-		|| (file->f_flags & O_CREAT) || (file->f_flags & O_TRUNC)
-		|| (file->f_flags & O_APPEND))) {
-		printk(KERN_WARNING "Mount has encrypted view enabled; "
-		       "files may only be read\n");
-		rc = -EPERM;
-		goto out;
-	}
 	/* Released in ecryptfs_release or end of function if failure */
 	file_info = kmem_cache_zalloc(ecryptfs_file_info_cache, GFP_KERNEL);
 	ecryptfs_set_file_private(file, file_info);
fs/ecryptfs/main.c +13 -3
index 240832e..93b7bec 100644
@@ -494,6 +494,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
 {
 	struct super_block *s;
 	struct ecryptfs_sb_info *sbi;
+	struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
 	struct ecryptfs_dentry_info *root_info;
 	const char *err = "Getting sb failed";
 	struct inode *inode;
@@ -512,6 +513,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
 		err = "Error parsing options";
 		goto out;
 	}
+	mount_crypt_stat = &sbi->mount_crypt_stat;
 
 	s = sget(fs_type, NULL, set_anon_super, NULL);
 	if (IS_ERR(s)) {
@@ -557,11 +559,19 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
 
 	/**
 	 * Set the POSIX ACL flag based on whether they're enabled in the lower
-	 * mount. Force a read-only eCryptfs mount if the lower mount is ro.
-	 * Allow a ro eCryptfs mount even when the lower mount is rw.
+	 * mount.
 	 */
 	s->s_flags = flags & ~MS_POSIXACL;
-	s->s_flags |= path.dentry->d_sb->s_flags & (MS_RDONLY | MS_POSIXACL);
+	s->s_flags |= path.dentry->d_sb->s_flags & MS_POSIXACL;
+
+	/**
+	 * Force a read-only eCryptfs mount when:
+	 *   1) The lower mount is ro
+	 *   2) The ecryptfs_encrypted_view mount option is specified
+	 */
+	if (path.dentry->d_sb->s_flags & MS_RDONLY ||
+	    mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED)
+		s->s_flags |= MS_RDONLY;
 
 	s->s_maxbytes = path.dentry->d_sb->s_maxbytes;
 	s->s_blocksize = path.dentry->d_sb->s_blocksize;
Signature · 1 line
1.9.1
#30 lore raw

PATCH 30/176 writeback: Move I_DIRTY_PAGES handling

In reply to [email protected]

From: Jan Kara <[email protected]>

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

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

commit 6290be1c1dc6589eeda213aa40946b27fa4faac8 upstream.

Instead of clearing I_DIRTY_PAGES and resetting it when we didn't succeed in writing them all, just clear the bit only when we succeeded writing all the pages. We also move the clearing of the bit close to other i_state handling to separate it from writeback list handling. This is desirable because list handling will differ for flusher thread and other writeback_single_inode() callers in future. No filesystem plays any tricks with I_DIRTY_PAGES (like checking it in ->writepages or ->write_inode implementation) so this movement is safe.

---
 fs/fs-writeback.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
fs/fs-writeback.c +3 -2
index b35bd64..ea0e821 100644
@@ -402,7 +402,6 @@ writeback_single_inode(struct inode *inode, struct bdi_writeback *wb,
 
 	/* Set I_SYNC, reset I_DIRTY_PAGES */
 	inode->i_state |= I_SYNC;
-	inode->i_state &= ~I_DIRTY_PAGES;
 	spin_unlock(&inode->i_lock);
 	spin_unlock(&wb->list_lock);
 
@@ -425,6 +424,9 @@ writeback_single_inode(struct inode *inode, struct bdi_writeback *wb,
 	 * write_inode()
 	 */
 	spin_lock(&inode->i_lock);
+	/* Clear I_DIRTY_PAGES if we've written out all dirty pages */
+	if (!mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
+		inode->i_state &= ~I_DIRTY_PAGES;
 	dirty = inode->i_state & I_DIRTY;
 	inode->i_state &= ~(I_DIRTY_SYNC | I_DIRTY_DATASYNC);
 	spin_unlock(&inode->i_lock);
@@ -453,7 +455,6 @@ writeback_single_inode(struct inode *inode, struct bdi_writeback *wb,
 			 * We didn't write back all the pages.  nfs_writepages()
 			 * sometimes bales out without doing anything.
 			 */
-			inode->i_state |= I_DIRTY_PAGES;
 			if (wbc->nr_to_write <= 0) {
 				/*
 				 * slice used up: queue for next turn
Signature · 1 line
1.9.1
#31 lore raw

PATCH 31/176 writeback: fix a subtle race condition in I_DIRTY clearing

In reply to [email protected]

From: Tejun Heo <[email protected]>

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

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

commit 9c6ac78eb3521c5937b2dd8a7d1b300f41092f45 upstream.

After invoking ->dirty_inode(), __mark_inode_dirty() does smp_mb() and tests inode->i_state locklessly to see whether it already has all the necessary I_DIRTY bits set. The comment above the barrier doesn't contain any useful information - memory barriers can't ensure "changes are seen by all cpus" by itself.

And it sure enough was broken. Please consider the following scenario.

CPU 0 CPU 1
-------------------------------------------------------------------------------

					enters __writeback_single_inode()
					grabs inode->i_lock
					tests PAGECACHE_TAG_DIRTY which is clear

enters __set_page_dirty()
grabs mapping->tree_lock
sets PAGECACHE_TAG_DIRTY
releases mapping->tree_lock
leaves __set_page_dirty()

enters __mark_inode_dirty()
smp_mb()
sees I_DIRTY_PAGES set
leaves __mark_inode_dirty()

					clears I_DIRTY_PAGES
					releases inode->i_lock

Now @inode has dirty pages w/ I_DIRTY_PAGES clear. This doesn't seem to lead to an immediately critical problem because requeue_inode() later checks PAGECACHE_TAG_DIRTY instead of I_DIRTY_PAGES when deciding whether the inode needs to be requeued for IO and there are enough unintentional memory barriers inbetween, so while the inode ends up with inconsistent I_DIRTY_PAGES flag, it doesn't fall off the IO list.

The lack of explicit barrier may also theoretically affect the other I_DIRTY bits which deal with metadata dirtiness. There is no guarantee that a strong enough barrier exists between I_DIRTY_[DATA]SYNC clearing and write_inode() writing out the dirtied inode. Filesystem inode writeout path likely has enough stuff which can behave as full barrier but it's theoretically possible that the writeout may not see all the updates from ->dirty_inode().

Fix it by adding an explicit smp_mb() after I_DIRTY clearing. Note that I_DIRTY_PAGES needs a special treatment as it always needs to be cleared to be interlocked with the lockless test on __mark_inode_dirty() side. It's cleared unconditionally and reinstated after smp_mb() if the mapping still has dirty pages.

Also add comments explaining how and why the barriers are paired.

Lightly tested.

---
 fs/fs-writeback.c | 29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)
fs/fs-writeback.c +22 -7
index ea0e821..f845834 100644
@@ -424,12 +424,28 @@ writeback_single_inode(struct inode *inode, struct bdi_writeback *wb,
 	 * write_inode()
 	 */
 	spin_lock(&inode->i_lock);
-	/* Clear I_DIRTY_PAGES if we've written out all dirty pages */
-	if (!mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
-		inode->i_state &= ~I_DIRTY_PAGES;
+
 	dirty = inode->i_state & I_DIRTY;
-	inode->i_state &= ~(I_DIRTY_SYNC | I_DIRTY_DATASYNC);
+	inode->i_state &= ~I_DIRTY;
+
+	/*
+	 * Paired with smp_mb() in __mark_inode_dirty().  This allows
+	 * __mark_inode_dirty() to test i_state without grabbing i_lock -
+	 * either they see the I_DIRTY bits cleared or we see the dirtied
+	 * inode.
+	 *
+	 * I_DIRTY_PAGES is always cleared together above even if @mapping
+	 * still has dirty pages.  The flag is reinstated after smp_mb() if
+	 * necessary.  This guarantees that either __mark_inode_dirty()
+	 * sees clear I_DIRTY_PAGES or we see PAGECACHE_TAG_DIRTY.
+	 */
+	smp_mb();
+
+	if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
+		inode->i_state |= I_DIRTY_PAGES;
+
 	spin_unlock(&inode->i_lock);
+
 	/* Don't write the inode if only I_DIRTY_PAGES was set */
 	if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) {
 		int err = write_inode(inode, wbc);
@@ -1075,12 +1091,11 @@ void __mark_inode_dirty(struct inode *inode, int flags)
 	}
 
 	/*
-	 * make sure that changes are seen by all cpus before we test i_state
-	 * -- mikulas
+	 * Paired with smp_mb() in __writeback_single_inode() for the
+	 * following lockless i_state test.  See there for details.
 	 */
 	smp_mb();
 
-	/* avoid the locking if we can */
 	if ((inode->i_state & flags) == flags)
 		return;
 
Signature · 1 line
1.9.1
#32 lore raw

PATCH 32/176 usb: renesas_usbhs: gadget: fix NULL pointer dereference in ep_disable()

In reply to [email protected]

From: Kazuya Mizuguchi <[email protected]>

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

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

commit 11432050f070810ba139d0226344eef120c3a559 upstream.

This patch fixes an issue that the NULL pointer dereference happens when we uses g_audio driver. Since the g_audio driver will call usb_ep_disable() in afunc_set_alt() before it calls usb_ep_enable(), the uep->pipe of renesas usbhs driver will be NULL. So, this patch adds a condition to avoid the oops.

Fixes 2f98382dc (usb: renesas_usbhs: Add Renesas USBHS Gadget)
---
 drivers/usb/renesas_usbhs/mod_gadget.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/usb/renesas_usbhs/mod_gadget.c +3 -0
index 00bd2a5..056dc6e 100644
@@ -672,6 +672,9 @@ static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge)
 	struct device *dev = usbhsg_gpriv_to_dev(gpriv);
 	unsigned long flags;
 
+	if (!pipe)
+		return -EINVAL;
+
 	usbhsg_pipe_disable(uep);
 
 	dev_dbg(dev, "set halt %d (pipe %d)\n",
Signature · 1 line
1.9.1
#33 lore raw

PATCH 33/176 KVM: s390: flush CPU on load control

In reply to [email protected]

From: Christian Borntraeger <[email protected]>

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

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

commit 2dca485f8740208604543c3960be31a5dd3ea603 upstream.

some control register changes will flush some aspects of the CPU, e.g. POP explicitely mentions that for CR9-CR11 "TLBs may be cleared". Instead of trying to be clever and only flush on specific CRs, let play safe and flush on all lctl(g) as future machines might define new bits in CRs. Load control intercept should not happen that often.

[lizf: Backported to 3.4:
- adjust filename
- adjust context]

---
 arch/s390/kvm/intercept.c | 2 ++
 1 file changed, 2 insertions(+)
arch/s390/kvm/intercept.c +2 -0
index 3614565..f10fef6 100644
@@ -58,6 +58,7 @@ static int handle_lctlg(struct kvm_vcpu *vcpu)
 			break;
 		reg = (reg + 1) % 16;
 	} while (1);
+	kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
 	return 0;
 }
 
@@ -97,6 +98,7 @@ static int handle_lctl(struct kvm_vcpu *vcpu)
 			break;
 		reg = (reg + 1) % 16;
 	} while (1);
+	kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
 	return 0;
 }
 
Signature · 1 line
1.9.1
#34 lore raw

Re: [PATCH 3.4 033/176] KVM: s390: flush CPU on load control

Am 09.04.2015 um 10:44 schrieb [email protected]:

Quoted 8 lines

From: Christian Borntraeger <[email protected]>

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

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

commit 2dca485f8740208604543c3960be31a5dd3ea603 upstream.

Hmmm, I just realized that this patch only makes a difference with

commit d3d692c82e4ed79ae7c85f8825ccfdb7d11819da ("KVM: s390: implement KVM_REQ_TLB_FLUSH and make use of it")

It should not hurt to have this patch as far as I can tell, but it makes no difference. This is also true for other stable versions < 3.18 - sorry for noticing it that late.

commit d3d692c82e4ed79ae7c85f8825ccfdb7d11819da on the other hand is not that easy to backport into Linux versions < 3.16.

So maybe just drop this patch?

Christian

Quoted 38 lines

some control register changes will flush some aspects of the CPU, e.g. POP explicitely mentions that for CR9-CR11 "TLBs may be cleared". Instead of trying to be clever and only flush on specific CRs, let play safe and flush on all lctl(g) as future machines might define new bits in CRs. Load control intercept should not happen that often.

[lizf: Backported to 3.4:
- adjust filename
- adjust context]

---
 arch/s390/kvm/intercept.c | 2 ++
 1 file changed, 2 insertions(+)
arch/s390/kvm/intercept.c +2 -0
index 3614565..f10fef6 100644
@@ -58,6 +58,7 @@ static int handle_lctlg(struct kvm_vcpu *vcpu)
 			break;
 		reg = (reg + 1) % 16;
 	} while (1);
+	kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
 	return 0;
 }
 
@@ -97,6 +98,7 @@ static int handle_lctl(struct kvm_vcpu *vcpu)
 			break;
 		reg = (reg + 1) % 16;
 	} while (1);
+	kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
 	return 0;
 }
 
#35 lore raw

Re: [PATCH 3.4 033/176] KVM: s390: flush CPU on load control

Quoted 14 lines · Christian Borntraeger

Am 09.04.2015 um 10:44 schrieb [email protected]:

Quoted 8 lines

From: Christian Borntraeger <[email protected]>

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

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

commit 2dca485f8740208604543c3960be31a5dd3ea603 upstream.

Hmmm, I just realized that this patch only makes a difference with

commit d3d692c82e4ed79ae7c85f8825ccfdb7d11819da ("KVM: s390: implement KVM_REQ_TLB_FLUSH and make use of it")

Quoted 9 lines

It should not hurt to have this patch as far as I can tell, but it makes no difference. This is also true for other stable versions < 3.18 - sorry for noticing it that late.

commit d3d692c82e4ed79ae7c85f8825ccfdb7d11819da on the other hand is not that easy to backport into Linux versions < 3.16.

So maybe just drop this patch?

I'll drop this one. Thanks for your review!

#36 lore raw

Re: [PATCH 3.4 033/176] KVM: s390: flush CPU on load control

In reply to Christian Borntraeger
Quoted 14 lines · Christian Borntraeger

Am 09.04.2015 um 10:44 schrieb [email protected]:

Quoted 8 lines

From: Christian Borntraeger <[email protected]>

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

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

commit 2dca485f8740208604543c3960be31a5dd3ea603 upstream.

Hmmm, I just realized that this patch only makes a difference with

commit d3d692c82e4ed79ae7c85f8825ccfdb7d11819da ("KVM: s390: implement KVM_REQ_TLB_FLUSH and make use of it")

Quoted 8 lines

It should not hurt to have this patch as far as I can tell, but it makes no difference. This is also true for other stable versions < 3.18 - sorry for noticing it that late.

commit d3d692c82e4ed79ae7c85f8825ccfdb7d11819da on the other hand is not that easy to backport into Linux versions < 3.16.

So maybe just drop this patch?

I also mistakenly applied this to 3.2 and will revert it in the next update.

Ben.

Signature · 2 lines
Ben Hutchings
Once a job is fouled up, anything done to improve it makes it worse.
#37 lore raw

PATCH 34/176 UBI: Fix invalid vfree()

In reply to [email protected]

From: Richard Weinberger <[email protected]>

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

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

commit f38aed975c0c3645bbdfc5ebe35726e64caaf588 upstream.

The logic of vfree()'ing vol->upd_buf is tied to vol->updating. In ubi_start_update() vol->updating is set long before vmalloc()'ing vol->upd_buf. If we encounter a write failure in ubi_start_update() before vmalloc() the UBI device release function will try to vfree() vol->upd_buf because vol->updating is set.
Fix this by allocating vol->upd_buf directly after setting vol->updating.

Fixes:

[   31.559338] UBI warning: vol_cdev_release: update of volume 2 not finished, volume is damaged
[   31.559340] ------------[ cut here ]------------
[   31.559343] WARNING: CPU: 1 PID: 2747 at mm/vmalloc.c:1446 __vunmap+0xe3/0x110()
[   31.559344] Trying to vfree() nonexistent vm area (ffffc90001f2b000)
[   31.559345] Modules linked in:
[   31.565620]  0000000000000bba ffff88002a0cbdb0 ffffffff818f0497 ffff88003b9ba148
[   31.566347]  ffff88002a0cbde0 ffffffff8156f515 ffff88003b9ba148 0000000000000bba
[   31.567073]  0000000000000000 0000000000000000 ffff88002a0cbe88 ffffffff8156c10a
[   31.567793] Call Trace:
[   31.568034]  [<ffffffff818f0497>] dump_stack+0x4e/0x7a
[   31.568510]  [<ffffffff8156f515>] ubi_io_write_vid_hdr+0x155/0x160
[   31.569084]  [<ffffffff8156c10a>] ubi_eba_write_leb+0x23a/0x870
[   31.569628]  [<ffffffff81569b36>] vol_cdev_write+0x226/0x380
[   31.570155]  [<ffffffff81179265>] vfs_write+0xb5/0x1f0
[   31.570627]  [<ffffffff81179f8a>] SyS_pwrite64+0x6a/0xa0
[   31.571123]  [<ffffffff818fde12>] system_call_fastpath+0x16/0x1b
---
 drivers/mtd/ubi/upd.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/mtd/ubi/upd.c +6 -4
index 425bf5a..068a246 100644
@@ -135,6 +135,10 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol,
 	ubi_assert(!vol->updating && !vol->changing_leb);
 	vol->updating = 1;
 
+	vol->upd_buf = vmalloc(ubi->leb_size);
+	if (!vol->upd_buf)
+		return -ENOMEM;
+
 	err = set_update_marker(ubi, vol);
 	if (err)
 		return err;
@@ -154,14 +158,12 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol,
 		err = clear_update_marker(ubi, vol, 0);
 		if (err)
 			return err;
+
+		vfree(vol->upd_buf);
 		vol->updating = 0;
 		return 0;
 	}
 
-	vol->upd_buf = vmalloc(ubi->leb_size);
-	if (!vol->upd_buf)
-		return -ENOMEM;
-
 	vol->upd_ebs = div_u64(bytes + vol->usable_leb_size - 1,
 			       vol->usable_leb_size);
 	vol->upd_bytes = bytes;
Signature · 1 line
1.9.1
#38 lore raw

PATCH 35/176 driver core: Fix unbalanced device reference in drivers_probe

In reply to [email protected]

From: Alex Williamson <[email protected]>

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

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

commit bb34cb6bbd287b57e955bc5cfd42fcde6aaca279 upstream.

bus_find_device_by_name() acquires a device reference which is never released. This results in an object leak, which on older kernels results in failure to release all resources of PCI devices. libvirt uses drivers_probe to re-attach devices to the host after assignment and is therefore a common trigger for this leak.

Example:

# cd /sys/bus/pci/
# dmesg -C
# echo 1 > devices/0000\:01\:00.0/sriov_numvfs
# echo 0 > devices/0000\:01\:00.0/sriov_numvfs
# dmesg | grep 01:10
 pci 0000:01:10.0: [8086:10ca] type 00 class 0x020000
 kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_add_internal: parent: '0000:00:01.0', set: 'devices'
 kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_uevent_env
 kobject: '0000:01:10.0' (ffff8801d79cd0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0'
 kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_uevent_env
 kobject: '0000:01:10.0' (ffff8801d79cd0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0'
 kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_uevent_env
 kobject: '0000:01:10.0' (ffff8801d79cd0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0'
 kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_cleanup, parent           (null)
 kobject: '0000:01:10.0' (ffff8801d79cd0a8): calling ktype release
 kobject: '0000:01:10.0': free name

[kobject freed as expected]

# dmesg -C
# echo 1 > devices/0000\:01\:00.0/sriov_numvfs
# echo 0000:01:10.0 > drivers_probe
# echo 0 > devices/0000\:01\:00.0/sriov_numvfs
# dmesg | grep 01:10
 pci 0000:01:10.0: [8086:10ca] type 00 class 0x020000
 kobject: '0000:01:10.0' (ffff8801d79ce0a8): kobject_add_internal: parent: '0000:00:01.0', set: 'devices'
 kobject: '0000:01:10.0' (ffff8801d79ce0a8): kobject_uevent_env
 kobject: '0000:01:10.0' (ffff8801d79ce0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0'
 kobject: '0000:01:10.0' (ffff8801d79ce0a8): kobject_uevent_env
 kobject: '0000:01:10.0' (ffff8801d79ce0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0'
 kobject: '0000:01:10.0' (ffff8801d79ce0a8): kobject_uevent_env
 kobject: '0000:01:10.0' (ffff8801d79ce0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0'

[no free]

---
 drivers/base/bus.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/base/bus.c +5 -3
index b850cec..0f682f7 100644
@@ -245,13 +245,15 @@ static ssize_t store_drivers_probe(struct bus_type *bus,
 				   const char *buf, size_t count)
 {
 	struct device *dev;
+	int err = -EINVAL;
 
 	dev = bus_find_device_by_name(bus, NULL, buf);
 	if (!dev)
 		return -ENODEV;
-	if (bus_rescan_devices_helper(dev, NULL) != 0)
-		return -EINVAL;
-	return count;
+	if (bus_rescan_devices_helper(dev, NULL) == 0)
+		err = count;
+	put_device(dev);
+	return err;
 }
 #endif
 
Signature · 1 line
1.9.1
#39 lore raw

PATCH 36/176 drbd: merge_bvec_fn: properly remap bvm->bi_bdev

In reply to [email protected]

From: Lars Ellenberg <[email protected]>

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

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

commit 3b9d35d744bb5139f9fed57f38c019bb8c7d351c upstream.

This was not noticed for many years. Affects operation if md raid is used a backing device for DRBD.

[lizf: Backported to 3.4: s/device/mdev]
---
 drivers/block/drbd/drbd_req.c | 1 +
 1 file changed, 1 insertion(+)
drivers/block/drbd/drbd_req.c +1 -0
index be984e0..43da226 100644
@@ -1184,6 +1184,7 @@ int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct
 		struct request_queue * const b =
 			mdev->ldev->backing_bdev->bd_disk->queue;
 		if (b->merge_bvec_fn) {
+			bvm->bi_bdev = mdev->ldev->backing_bdev;
 			backing_limit = b->merge_bvec_fn(b, bvm, bvec);
 			limit = min(limit, backing_limit);
 		}
Signature · 1 line
1.9.1
#40 lore raw

PATCH 37/176 PCI: Restore detection of read-only BARs

In reply to [email protected]

From: Myron Stowe <[email protected]>

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

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

commit 36e8164882ca6d3c41cb91e6f09a3ed236841f80 upstream.

Commit 6ac665c63dca ("PCI: rewrite PCI BAR reading code") masked off low-order bits from 'l', but not from 'sz'. Both are passed to pci_size(), which compares 'base == maxbase' to check for read-only BARs. The masking of 'l' means that comparison will never be 'true', so the check for read-only BARs no longer works.

Resolve this by also masking off the low-order bits of 'sz' before passing it into pci_size() as 'maxbase'. With this change, pci_size() will once again catch the problems that have been encountered to date:

- AGP aperture BAR of AMD-7xx host bridges: if the AGP window is

    disabled, this BAR is read-only and read as 0x00000008 [1]

- BARs 0-4 of ALi IDE controllers can be non-zero and read-only [1]

- Intel Sandy Bridge - Thermal Management Controller [8086:0103];

    BAR 0 returning 0xfed98004 [2]
  - Intel Xeon E5 v3/Core i7 Power Control Unit [8086:2fc0];
    Bar 0 returning 0x00001a [3]
---
 drivers/pci/probe.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/pci/probe.c +3 -0
index 63e0199..d62ad0b 100644
@@ -254,14 +254,17 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 		res->flags |= IORESOURCE_SIZEALIGN;
 		if (res->flags & IORESOURCE_IO) {
 			l &= PCI_BASE_ADDRESS_IO_MASK;
+			sz &= PCI_BASE_ADDRESS_IO_MASK;
 			mask = PCI_BASE_ADDRESS_IO_MASK & (u32) IO_SPACE_LIMIT;
 		} else {
 			l &= PCI_BASE_ADDRESS_MEM_MASK;
+			sz &= PCI_BASE_ADDRESS_MEM_MASK;
 			mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
 		}
 	} else {
 		res->flags |= (l & IORESOURCE_ROM_ENABLE);
 		l &= PCI_ROM_ADDRESS_MASK;
+		sz &= PCI_ROM_ADDRESS_MASK;
 		mask = (u32)PCI_ROM_ADDRESS_MASK;
 	}
 
Signature · 1 line
1.9.1
#41 lore raw

Re: [PATCH 3.4 037/176] PCI: Restore detection of read-only BARs

Quoted 3 lines · On Thu, 2015-04-09 at 16:44 +0800, [email protected] wrote:

From: Myron Stowe <[email protected]>

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

No objections, but I think you want 06cf35f903aa ("PCI: Handle read-only BARs on AMD CS553x devices") at the same time.

Quoted 62 lines

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

commit 36e8164882ca6d3c41cb91e6f09a3ed236841f80 upstream.

Commit 6ac665c63dca ("PCI: rewrite PCI BAR reading code") masked off low-order bits from 'l', but not from 'sz'. Both are passed to pci_size(), which compares 'base == maxbase' to check for read-only BARs. The masking of 'l' means that comparison will never be 'true', so the check for read-only BARs no longer works.

Resolve this by also masking off the low-order bits of 'sz' before passing it into pci_size() as 'maxbase'. With this change, pci_size() will once again catch the problems that have been encountered to date:

- AGP aperture BAR of AMD-7xx host bridges: if the AGP window is

    disabled, this BAR is read-only and read as 0x00000008 [1]

- BARs 0-4 of ALi IDE controllers can be non-zero and read-only [1]

- Intel Sandy Bridge - Thermal Management Controller [8086:0103];

    BAR 0 returning 0xfed98004 [2]
  - Intel Xeon E5 v3/Core i7 Power Control Unit [8086:2fc0];
    Bar 0 returning 0x00001a [3]
---
 drivers/pci/probe.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/pci/probe.c +3 -0
index 63e0199..d62ad0b 100644
@@ -254,14 +254,17 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 		res->flags |= IORESOURCE_SIZEALIGN;
 		if (res->flags & IORESOURCE_IO) {
 			l &= PCI_BASE_ADDRESS_IO_MASK;
+			sz &= PCI_BASE_ADDRESS_IO_MASK;
 			mask = PCI_BASE_ADDRESS_IO_MASK & (u32) IO_SPACE_LIMIT;
 		} else {
 			l &= PCI_BASE_ADDRESS_MEM_MASK;
+			sz &= PCI_BASE_ADDRESS_MEM_MASK;
 			mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
 		}
 	} else {
 		res->flags |= (l & IORESOURCE_ROM_ENABLE);
 		l &= PCI_ROM_ADDRESS_MASK;
+		sz &= PCI_ROM_ADDRESS_MASK;
 		mask = (u32)PCI_ROM_ADDRESS_MASK;
 	}
 
#42 lore raw

Re: [PATCH 3.4 037/176] PCI: Restore detection of read-only BARs

Quoted 7 lines · Myron Stowe
Quoted 3 lines · On Thu, 2015-04-09 at 16:44 +0800, [email protected] wrote:

From: Myron Stowe <[email protected]>

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

No objections, but I think you want 06cf35f903aa ("PCI: Handle read-only BARs on AMD CS553x devices") at the same time.

I'll queue it up. Thanks for your review!

#43 lore raw

PATCH 38/176 scsi: correct return values for .eh_abort_handler implementations

In reply to [email protected]

From: Hannes Reinecke <[email protected]>

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

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

commit b6c92b7e0af575e2b8b05bdf33633cf9e1661cbf upstream.

The .eh_abort_handler needs to return SUCCESS, FAILED, or FAST_IO_FAIL. So fixup all callers to adhere to this requirement.

[lizf: Backported to 3.4: drop changes to esas2r_main.c]
---
 drivers/scsi/NCR5380.c       | 12 ++++++------
 drivers/scsi/aha1740.c       |  2 +-
 drivers/scsi/atari_NCR5380.c |  2 +-
 drivers/scsi/megaraid.c      |  8 ++++----
 drivers/scsi/sun3_NCR5380.c  | 10 +++++-----
 5 files changed, 17 insertions(+), 17 deletions(-)
drivers/scsi/NCR5380.c +6 -6
index 165e4dd86..a57f85a 100644
@@ -2662,14 +2662,14 @@ static void NCR5380_dma_complete(NCR5380_instance * instance) {
  *
  * Purpose : abort a command
  *
- * Inputs : cmd - the Scsi_Cmnd to abort, code - code to set the 
- *      host byte of the result field to, if zero DID_ABORTED is 
+ * Inputs : cmd - the Scsi_Cmnd to abort, code - code to set the
+ *      host byte of the result field to, if zero DID_ABORTED is
  *      used.
  *
- * Returns : 0 - success, -1 on failure.
+ * Returns : SUCCESS - success, FAILED on failure.
  *
- *	XXX - there is no way to abort the command that is currently 
- *	connected, you have to wait for it to complete.  If this is 
+ *	XXX - there is no way to abort the command that is currently
+ *	connected, you have to wait for it to complete.  If this is
  *	a problem, we could implement longjmp() / setjmp(), setjmp()
  *	called where the loop started in NCR5380_main().
  *
@@ -2719,7 +2719,7 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) {
  * aborted flag and get back into our main loop.
  */
 
-		return 0;
+		return SUCCESS;
 	}
 #endif
 
drivers/scsi/aha1740.c +1 -1
index a3e6ed3..d0fa3e7 100644
@@ -550,7 +550,7 @@ static int aha1740_eh_abort_handler (Scsi_Cmnd *dummy)
  * quiet as possible...
  */
 
-	return 0;
+	return SUCCESS;
 }
 
 static struct scsi_host_template aha1740_template = {
drivers/scsi/atari_NCR5380.c +1 -1
index 2db79b4..589c2a3 100644
@@ -2638,7 +2638,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
  *	host byte of the result field to, if zero DID_ABORTED is
  *	used.
  *
- * Returns : 0 - success, -1 on failure.
+ * Returns : SUCCESS - success, FAILED on failure.
  *
  * XXX - there is no way to abort the command that is currently
  *	 connected, you have to wait for it to complete.  If this is
drivers/scsi/megaraid.c +4 -4
index 4d39a9f..152fe62 100644
@@ -1967,7 +1967,7 @@ megaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor)
 	     cmd->device->id, cmd->device->lun);
 
 	if(list_empty(&adapter->pending_list))
-		return FALSE;
+		return FAILED;
 
 	list_for_each_safe(pos, next, &adapter->pending_list) {
 
@@ -1990,7 +1990,7 @@ megaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor)
 					(aor==SCB_ABORT) ? "ABORTING":"RESET",
 					scb->idx);
 
-				return FALSE;
+				return FAILED;
 			}
 			else {
 
@@ -2015,12 +2015,12 @@ megaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor)
 				list_add_tail(SCSI_LIST(cmd),
 						&adapter->completed_list);
 
-				return TRUE;
+				return SUCCESS;
 			}
 		}
 	}
 
-	return FALSE;
+	return FAILED;
 }
 
 static inline int
drivers/scsi/sun3_NCR5380.c +5 -5
index 7e12a2e..9aaf084 100644
@@ -2624,15 +2624,15 @@ static void NCR5380_reselect (struct Scsi_Host *instance)
  * Purpose : abort a command
  *
  * Inputs : cmd - the struct scsi_cmnd to abort, code - code to set the
- * 	host byte of the result field to, if zero DID_ABORTED is 
+ *	host byte of the result field to, if zero DID_ABORTED is
  *	used.
  *
- * Returns : 0 - success, -1 on failure.
+ * Returns : SUCCESS - success, FAILED on failure.
  *
- * XXX - there is no way to abort the command that is currently 
- * 	 connected, you have to wait for it to complete.  If this is 
+ * XXX - there is no way to abort the command that is currently
+ *	 connected, you have to wait for it to complete.  If this is
  *	 a problem, we could implement longjmp() / setjmp(), setjmp()
- * 	 called where the loop started in NCR5380_main().
+ *	 called where the loop started in NCR5380_main().
  */
 
 static int NCR5380_abort(struct scsi_cmnd *cmd)
Signature · 1 line
1.9.1
#44 lore raw

PATCH 39/176 genhd: check for int overflow in disk_expand_part_tbl()

In reply to [email protected]

From: Jens Axboe <[email protected]>

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

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

commit 5fabcb4c33fe11c7e3afdf805fde26c1a54d0953 upstream.

We can get here from blkdev_ioctl() -> blkpg_ioctl() -> add_partition() with a user passed in partno value. If we pass in 0x7fffffff, the new target in disk_expand_part_tbl() overflows the 'int' and we access beyond the end of ptbl->part[] and even write to it when we do the rcu_assign_pointer() to assign the new partition.

---
 block/genhd.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
block/genhd.c +9 -2
index 60f7e6c..7a2a8dc 100644
@@ -1069,9 +1069,16 @@ int disk_expand_part_tbl(struct gendisk *disk, int partno)
 	struct disk_part_tbl *old_ptbl = disk->part_tbl;
 	struct disk_part_tbl *new_ptbl;
 	int len = old_ptbl ? old_ptbl->len : 0;
-	int target = partno + 1;
+	int i, target;
 	size_t size;
-	int i;
+
+	/*
+	 * check for int overflow, since we can get here from blkpg_ioctl()
+	 * with a user passed 'partno'.
+	 */
+	target = partno + 1;
+	if (target < 0)
+		return -EINVAL;
 
 	/* disk_max_parts() is zero during initialization, ignore if so */
 	if (disk_max_parts(disk) && target > disk_max_parts(disk))
Signature · 1 line
1.9.1
#45 lore raw

PATCH 40/176 ASoC: sigmadsp: Refuse to load firmware files with a non-supported version

In reply to [email protected]

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

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

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

commit 50c0f21b42dd4cd02b51f82274f66912d9a7fa32 upstream.

Make sure to check the version field of the firmware header to make sure to not accidentally try to parse a firmware file with a different layout. Trying to do so can result in loading invalid firmware code to the device.

---
 sound/soc/codecs/sigmadsp.c | 7 +++++++
 1 file changed, 7 insertions(+)
sound/soc/codecs/sigmadsp.c +7 -0
index 4068f24..bb3878c 100644
@@ -176,6 +176,13 @@ static int _process_sigma_firmware(struct device *dev,
 		goto done;
 	}
 
+	if (ssfw_head->version != 1) {
+		dev_err(dev,
+			"Failed to load firmware: Invalid version %d. Supported firmware versions: 1\n",
+			ssfw_head->version);
+		goto done;
+	}
+
 	crc = crc32(0, fw->data + sizeof(*ssfw_head),
 			fw->size - sizeof(*ssfw_head));
 	pr_debug("%s: crc=%x\n", __func__, crc);
Signature · 1 line
1.9.1
#46 lore raw

PATCH 41/176 megaraid_sas: corrected return of wait_event from abort frame path

In reply to [email protected]

From: "[email protected]" <[email protected]>

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

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

commit 170c238701ec38b1829321b17c70671c101bac55 upstream.

Corrected wait_event() call which was waiting for wrong completion status (0xFF).

---
 drivers/scsi/megaraid/megaraid_sas_base.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/megaraid/megaraid_sas_base.c +1 -1
index 6188700..bacd344 100644
@@ -919,7 +919,7 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
 	abort_fr->abort_mfi_phys_addr_hi = 0;
 
 	cmd->sync_cmd = 1;
-	cmd->cmd_status = 0xFF;
+	cmd->cmd_status = ENODATA;
 
 	instance->instancet->issue_dcmd(instance, cmd);
 
Signature · 1 line
1.9.1
#47 lore raw

PATCH 42/176 cdc-acm: memory leak in error case

In reply to [email protected]

From: Oliver Neukum <[email protected]>

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

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

commit d908f8478a8d18e66c80a12adb27764920c1f1ca upstream.

If probe() fails not only the attributes need to be removed but also the memory freed.

---
 drivers/usb/class/cdc-acm.c | 1 +
 1 file changed, 1 insertion(+)
drivers/usb/class/cdc-acm.c +1 -0
index 8f4a628..cd8550a 100644
@@ -1429,6 +1429,7 @@ static void acm_disconnect(struct usb_interface *intf)
 				&dev_attr_wCountryCodes);
 		device_remove_file(&acm->control->dev,
 				&dev_attr_iCountryCodeRelDate);
+		kfree(acm->country_codes);
 	}
 	device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities);
 	usb_set_intfdata(acm->control, NULL);
Signature · 1 line
1.9.1
#48 lore raw

PATCH 43/176 USB: cdc-acm: check for valid interfaces

In reply to [email protected]

From: Greg Kroah-Hartman <[email protected]>

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

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

commit 403dff4e2c94f275e24fd85f40b2732ffec268a1 upstream.

We need to check that we have both a valid data and control inteface for both types of headers (union and not union.)

References: https://bugzilla.kernel.org/show_bug.cgi?id=83551

---
 drivers/usb/class/cdc-acm.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/usb/class/cdc-acm.c +5 -4
index cd8550a..0532577 100644
@@ -1108,10 +1108,11 @@ next_desc:
 	} else {
 		control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0);
 		data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0));
-		if (!control_interface || !data_interface) {
-			dev_dbg(&intf->dev, "no interfaces\n");
-			return -ENODEV;
-		}
+	}
+
+	if (!control_interface || !data_interface) {
+		dev_dbg(&intf->dev, "no interfaces\n");
+		return -ENODEV;
 	}
 
 	if (data_interface_num != call_interface_num)
Signature · 1 line
1.9.1
#49 lore raw

PATCH 44/176 mfd: tc6393xb: Fail ohci suspend if full state restore is required

In reply to [email protected]

From: Dmitry Eremin-Solenikov <[email protected]>

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

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

commit 1a5fb99de4850cba710d91becfa2c65653048589 upstream.

Some boards with TC6393XB chip require full state restore during system resume thanks to chip's VCC being cut off during suspend (Sharp SL-6000 tosa is one of them). Failing to do so would result in ohci Oops on resume due to internal memory contentes being changed. Fail ohci suspend on tc6393xb is full state restore is required.

Recommended workaround is to unbind tmio-ohci driver before suspend and rebind it after resume.

---
 drivers/mfd/tc6393xb.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/mfd/tc6393xb.c +12 -1
index 9612264..b69d91b 100644
@@ -263,6 +263,17 @@ static int tc6393xb_ohci_disable(struct platform_device *dev)
 	return 0;
 }
 
+static int tc6393xb_ohci_suspend(struct platform_device *dev)
+{
+	struct tc6393xb_platform_data *tcpd = dev_get_platdata(dev->dev.parent);
+
+	/* We can't properly store/restore OHCI state, so fail here */
+	if (tcpd->resume_restore)
+		return -EBUSY;
+
+	return tc6393xb_ohci_disable(dev);
+}
+
 static int tc6393xb_fb_enable(struct platform_device *dev)
 {
 	struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
@@ -403,7 +414,7 @@ static struct mfd_cell __devinitdata tc6393xb_cells[] = {
 		.num_resources = ARRAY_SIZE(tc6393xb_ohci_resources),
 		.resources = tc6393xb_ohci_resources,
 		.enable = tc6393xb_ohci_enable,
-		.suspend = tc6393xb_ohci_disable,
+		.suspend = tc6393xb_ohci_suspend,
 		.resume = tc6393xb_ohci_enable,
 		.disable = tc6393xb_ohci_disable,
 	},
Signature · 1 line
1.9.1
#50 lore raw

PATCH 45/176 serial: samsung: wait for transfer completion before clock disable

In reply to [email protected]

From: Robert Baldyga <[email protected]>

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

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

commit 1ff383a4c3eda8893ec61b02831826e1b1f46b41 upstream.

This patch adds waiting until transmit buffer and shifter will be empty before clock disabling.

Without this fix it's possible to have clock disabled while data was not transmited yet, which causes unproper state of TX line and problems in following data transfers.

[lizf: Backported to 3.4: adjust context]
---
 drivers/tty/serial/samsung.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/tty/serial/samsung.c +4 -0
index d8b0aee..1b7d2c0 100644
@@ -524,11 +524,15 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
 			      unsigned int old)
 {
 	struct s3c24xx_uart_port *ourport = to_ourport(port);
+	int timeout = 10000;
 
 	ourport->pm_level = level;
 
 	switch (level) {
 	case 3:
+		while (--timeout && !s3c24xx_serial_txempty_nofifo(port))
+			udelay(100);
+
 		if (!IS_ERR(ourport->baudclk) && ourport->baudclk != NULL)
 			clk_disable(ourport->baudclk);
 
Signature · 1 line
1.9.1
#51 lore raw

PATCH 46/176 eCryptfs: Remove buggy and unnecessary write in file name decode routine

In reply to [email protected]

From: Michael Halcrow <[email protected]>

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

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

commit 942080643bce061c3dd9d5718d3b745dcb39a8bc upstream.

Dmitry Chernenkov used KASAN to discover that eCryptfs writes past the end of the allocated buffer during encrypted filename decoding. This fix corrects the issue by getting rid of the unnecessary 0 write when the current bit offset is 2.

---
 fs/ecryptfs/crypto.c | 1 -
 1 file changed, 1 deletion(-)
fs/ecryptfs/crypto.c +0 -1
index ea99312..3d06338 100644
@@ -2044,7 +2044,6 @@ ecryptfs_decode_from_filename(unsigned char *dst, size_t *dst_size,
 			break;
 		case 2:
 			dst[dst_byte_offset++] |= (src_byte);
-			dst[dst_byte_offset] = 0;
 			current_bit_offset = 0;
 			break;
 		}
Signature · 1 line
1.9.1
#52 lore raw

PATCH 47/176 ath9k_hw: fix hardware queue allocation

In reply to [email protected]

From: Felix Fietkau <[email protected]>

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

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

commit ad8fdccf9c197a89e2d2fa78c453283dcc2c343f upstream.

The driver passes the desired hardware queue index for a WMM data queue in qinfo->tqi_subtype. This was ignored in ath9k_hw_setuptxqueue, which instead relied on the order in which the function is called.

---
 drivers/net/wireless/ath/ath9k/mac.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)
drivers/net/wireless/ath/ath9k/mac.c +1 -8
index f7bd253..2d628f9 100644
@@ -303,14 +303,7 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
 		q = ATH9K_NUM_TX_QUEUES - 3;
 		break;
 	case ATH9K_TX_QUEUE_DATA:
-		for (q = 0; q < ATH9K_NUM_TX_QUEUES; q++)
-			if (ah->txq[q].tqi_type ==
-			    ATH9K_TX_QUEUE_INACTIVE)
-				break;
-		if (q == ATH9K_NUM_TX_QUEUES) {
-			ath_err(common, "No available TX queue\n");
-			return -1;
-		}
+		q = qinfo->tqi_subtype;
 		break;
 	default:
 		ath_err(common, "Invalid TX queue type: %u\n", type);
Signature · 1 line
1.9.1
#53 lore raw

PATCH 48/176 ath9k: fix BE/BK queue order

In reply to [email protected]

From: Felix Fietkau <[email protected]>

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

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

commit 78063d81d353e10cbdd279c490593113b8fdae1c upstream.

Hardware queues are ordered by priority. Use queue index 0 for BK, which has lower priority than BE.

---
 drivers/net/wireless/ath/ath9k/hw.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath9k/hw.h +2 -2
index f49be96..d4f09b4 100644
@@ -181,8 +181,8 @@
 #define PAPRD_IDEAL_AGC2_PWR_RANGE	0xe0
 
 enum ath_hw_txq_subtype {
-	ATH_TXQ_AC_BE = 0,
-	ATH_TXQ_AC_BK = 1,
+	ATH_TXQ_AC_BK = 0,
+	ATH_TXQ_AC_BE = 1,
 	ATH_TXQ_AC_VI = 2,
 	ATH_TXQ_AC_VO = 3,
 };
Signature · 1 line
1.9.1
#54 lore raw

PATCH 49/176 ath5k: fix hardware queue index assignment

In reply to [email protected]

From: Felix Fietkau <[email protected]>

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

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

commit 9e4982f6a51a2442f1bb588fee42521b44b4531c upstream.

Like with ath9k, ath5k queues also need to be ordered by priority. queue_info->tqi_subtype already contains the correct index, so use it instead of relying on the order of ath5k_hw_setup_tx_queue calls.

---
 drivers/net/wireless/ath/ath5k/qcu.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)
drivers/net/wireless/ath/ath5k/qcu.c +1 -7
index 30b50f9..19ba204 100644
@@ -223,13 +223,7 @@ ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
 	} else {
 		switch (queue_type) {
 		case AR5K_TX_QUEUE_DATA:
-			for (queue = AR5K_TX_QUEUE_ID_DATA_MIN;
-				ah->ah_txq[queue].tqi_type !=
-				AR5K_TX_QUEUE_INACTIVE; queue++) {
-
-				if (queue > AR5K_TX_QUEUE_ID_DATA_MAX)
-					return -EINVAL;
-			}
+			queue = queue_info->tqi_subtype;
 			break;
 		case AR5K_TX_QUEUE_UAPSD:
 			queue = AR5K_TX_QUEUE_ID_UAPSD;
Signature · 1 line
1.9.1
#55 lore raw

PATCH 50/176 iommu/vt-d: Fix an off-by-one bug in __domain_mapping()

In reply to [email protected]

From: Jiang Liu <[email protected]>

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

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

commit cc4f14aa170d895c9a43bdb56f62070c8a6da908 upstream.

There's an off-by-one bug in function __domain_mapping(), which may trigger the BUG_ON(nr_pages < lvl_pages) when

	(nr_pages + 1) & superpage_mask == 0

The issue was introduced by commit 9051aa0268dc "intel-iommu: Combine domain_pfn_mapping() and domain_sg_mapping()", which sets sg_res to "nr_pages + 1" to avoid some of the 'sg_res==0' code paths.

It's safe to remove extra "+1" because sg_res is only used to calculate page size now.

Reported-And-Tested-by Sudeep Dutt <[email protected]>
[lizf: Backported to 3.4: adjust context]
---
 drivers/iommu/intel-iommu.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)
drivers/iommu/intel-iommu.c +3 -5
index dd255c5..28af276 100644
@@ -1792,7 +1792,7 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
 	struct dma_pte *first_pte = NULL, *pte = NULL;
 	phys_addr_t uninitialized_var(pteval);
 	int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
-	unsigned long sg_res;
+	unsigned long sg_res = 0;
 	unsigned int largepage_lvl = 0;
 	unsigned long lvl_pages = 0;
 
@@ -1803,10 +1803,8 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
 
 	prot &= DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP;
 
-	if (sg)
-		sg_res = 0;
-	else {
-		sg_res = nr_pages + 1;
+	if (!sg) {
+		sg_res = nr_pages;
 		pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot;
 	}
 
Signature · 1 line
1.9.1
#56 lore raw

PATCH 51/176 drm/vmwgfx: Don't use memory accounting for kernel-side fence objects

In reply to [email protected]

From: Thomas Hellstrom <[email protected]>

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

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

commit 1f563a6a46544602183e7493b6ef69769d3d76d9 upstream.

Kernel side fence objects are used when unbinding resources and may thus be created as part of a memory reclaim operation. This might trigger recursive memory reclaims and result in the kernel running out of stack space.

So a simple way out is to avoid accounting of these fence objects. In principle this is OK since while user-space can trigger the creation of such objects, it can't really hold on to them. However, their lifetime is quite long, so some form of accounting should perhaps be implemented in the future.

Fixes kernel crashes when running, for example viewperf11 ensight-04 test 3 with low system memory settings.

[lizf: Backported to 3.4: adjust context]
---
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 21 ++-------------------
 1 file changed, 2 insertions(+), 19 deletions(-)
drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +2 -19
index 7e07433..051ca79 100644
@@ -485,14 +485,7 @@ void vmw_fence_obj_flush(struct vmw_fence_obj *fence)
 
 static void vmw_fence_destroy(struct vmw_fence_obj *fence)
 {
-	struct vmw_fence_manager *fman = fence->fman;
-
 	kfree(fence);
-	/*
-	 * Free kernel space accounting.
-	 */
-	ttm_mem_global_free(vmw_mem_glob(fman->dev_priv),
-			    fman->fence_size);
 }
 
 int vmw_fence_create(struct vmw_fence_manager *fman,
@@ -500,20 +493,12 @@ int vmw_fence_create(struct vmw_fence_manager *fman,
 		     uint32_t mask,
 		     struct vmw_fence_obj **p_fence)
 {
-	struct ttm_mem_global *mem_glob = vmw_mem_glob(fman->dev_priv);
 	struct vmw_fence_obj *fence;
 	int ret;
 
-	ret = ttm_mem_global_alloc(mem_glob, fman->fence_size,
-				   false, false);
-	if (unlikely(ret != 0))
-		return ret;
-
 	fence = kzalloc(sizeof(*fence), GFP_KERNEL);
-	if (unlikely(fence == NULL)) {
-		ret = -ENOMEM;
-		goto out_no_object;
-	}
+	if (unlikely(fence == NULL))
+		return -ENOMEM;
 
 	ret = vmw_fence_obj_init(fman, fence, seqno, mask,
 				 vmw_fence_destroy);
@@ -525,8 +510,6 @@ int vmw_fence_create(struct vmw_fence_manager *fman,
 
 out_err_init:
 	kfree(fence);
-out_no_object:
-	ttm_mem_global_free(mem_glob, fman->fence_size);
 	return ret;
 }
 
Signature · 1 line
1.9.1
#57 lore raw

PATCH 52/176 drm/vmwgfx: Fix fence event code

In reply to [email protected]

From: Thomas Hellstrom <[email protected]>

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

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

commit 89669e7a7f96be3ee8d9a22a071d7c0d3b4428fc upstream.

The commit "vmwgfx: Rework fence event action" introduced a number of bugs that are fixed with this commit:

a) A forgotten return stateemnt.
b) An if statement with identical branches.

---
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)
drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +6 -11
index 051ca79..992b46b 100644
@@ -1032,6 +1032,8 @@ int vmw_event_fence_action_create(struct drm_file *file_priv,
 	if (ret != 0)
 		goto out_no_queue;
 
+	return 0;
+
 out_no_queue:
 	event->base.destroy(&event->base);
 out_no_event:
@@ -1106,17 +1108,10 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data,
 
 	BUG_ON(fence == NULL);
 
-	if (arg->flags & DRM_VMW_FE_FLAG_REQ_TIME)
-		ret = vmw_event_fence_action_create(file_priv, fence,
-						    arg->flags,
-						    arg->user_data,
-						    true);
-	else
-		ret = vmw_event_fence_action_create(file_priv, fence,
-						    arg->flags,
-						    arg->user_data,
-						    true);
-
+	ret = vmw_event_fence_action_create(file_priv, fence,
+					    arg->flags,
+					    arg->user_data,
+					    true);
 	if (unlikely(ret != 0)) {
 		if (ret != -ERESTARTSYS)
 			DRM_ERROR("Failed to attach event to fence.\n");
Signature · 1 line
1.9.1
#58 lore raw

PATCH 53/176 hp_accel: Add support for HP ZBook 15

In reply to [email protected]

From: Dominique Leuenberger <[email protected]>

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

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

commit 6583659e0f92e38079a8dd081e0a1181a0f37747 upstream.

HP ZBook 15 laptop needs a non-standard mapping (x_inverted).

---
 drivers/platform/x86/hp_accel.c | 1 +
 1 file changed, 1 insertion(+)
drivers/platform/x86/hp_accel.c +1 -0
index 0076fea..be6b648 100644
@@ -237,6 +237,7 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
 	AXIS_DMI_MATCH("HPB64xx", "HP ProBook 64", xy_swap),
 	AXIS_DMI_MATCH("HPB64xx", "HP EliteBook 84", xy_swap),
 	AXIS_DMI_MATCH("HPB65xx", "HP ProBook 65", x_inverted),
+	AXIS_DMI_MATCH("HPZBook15", "HP ZBook 15", x_inverted),
 	{ NULL, }
 /* Laptop models without axis info (yet):
  * "NC6910" "HP Compaq 6910"
Signature · 1 line
1.9.1
#59 lore raw

PATCH 54/176 drm/radeon: check the right ring in radeon_evict_flags()

In reply to [email protected]

From: Alex Deucher <[email protected]>

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

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

commit 5e5c21cac1001089007260c48b0c89ebaace0e71 upstream.

Check the that ring we are using for copies is functional rather than the GFX ring. On newer asics we use the DMA ring for bo moves.

---
 drivers/gpu/drm/radeon/radeon_ttm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/radeon/radeon_ttm.c +1 -1
index 49b55ed..15042d0 100644
@@ -188,7 +188,7 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo,
 	rbo = container_of(bo, struct radeon_bo, tbo);
 	switch (bo->mem.mem_type) {
 	case TTM_PL_VRAM:
-		if (rbo->rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready == false)
+		if (rbo->rdev->ring[radeon_copy_ring_index(rbo->rdev)].ready == false)
 			radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU);
 		else
 			radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT);
Signature · 1 line
1.9.1
#60 lore raw

PATCH 55/176 can: peak_usb: fix memset() usage

In reply to [email protected]

From: Stephane Grosjean <[email protected]>

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

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

commit dc50ddcd4c58a5a0226038307d6ef884bec9f8c2 upstream.

This patchs fixes a misplaced call to memset() that fills the request buffer with 0. The problem was with sending PCAN_USBPRO_REQ_FCT requests, the content set by the caller was thus lost.

With this patch, the memory area is zeroed only when requesting info from the device.

---
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/can/usb/peak_usb/pcan_usb_pro.c +1 -2
index c95913a..5fe28be 100644
@@ -333,8 +333,6 @@ static int pcan_usb_pro_send_req(struct peak_usb_device *dev, int req_id,
 	if (!(dev->state & PCAN_USB_STATE_CONNECTED))
 		return 0;
 
-	memset(req_addr, '\0', req_size);
-
 	req_type = USB_TYPE_VENDOR | USB_RECIP_OTHER;
 
 	switch (req_id) {
@@ -345,6 +343,7 @@ static int pcan_usb_pro_send_req(struct peak_usb_device *dev, int req_id,
 	default:
 		p = usb_rcvctrlpipe(dev->udev, 0);
 		req_type |= USB_DIR_IN;
+		memset(req_addr, '\0', req_size);
 		break;
 	}
 
Signature · 1 line
1.9.1
#61 lore raw

PATCH 56/176 can: peak_usb: fix cleanup sequence order in case of error during init

In reply to [email protected]

From: Stephane Grosjean <[email protected]>

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

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

commit af35d0f1cce7a990286e2b94c260a2c2d2a0e4b0 upstream.

This patch sets the correct reverse sequence order to the instructions set to run, when any failure occurs during the initialization steps. It also adds the missing unregistration call of the can device if the failure appears after having been registered.

---
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)
drivers/net/can/usb/peak_usb/pcan_usb_core.c +10 -7
index d2f91f7..925c7e1 100644
@@ -737,7 +737,7 @@ static int peak_usb_create_dev(struct peak_usb_adapter *peak_usb_adapter,
 		dev_err(&intf->dev, "%s: couldn't alloc cmd buffer\n",
 			PCAN_USB_DRIVER_NAME);
 		err = -ENOMEM;
-		goto lbl_set_intf_data;
+		goto lbl_free_candev;
 	}
 
 	dev->udev = usb_dev;
@@ -776,7 +776,7 @@ static int peak_usb_create_dev(struct peak_usb_adapter *peak_usb_adapter,
 	err = register_candev(netdev);
 	if (err) {
 		dev_err(&intf->dev, "couldn't register CAN device: %d\n", err);
-		goto lbl_free_cmd_buf;
+		goto lbl_restore_intf_data;
 	}
 
 	if (dev->prev_siblings)
@@ -789,14 +789,14 @@ static int peak_usb_create_dev(struct peak_usb_adapter *peak_usb_adapter,
 	if (dev->adapter->dev_init) {
 		err = dev->adapter->dev_init(dev);
 		if (err)
-			goto lbl_free_cmd_buf;
+			goto lbl_unregister_candev;
 	}
 
 	/* set bus off */
 	if (dev->adapter->dev_set_bus) {
 		err = dev->adapter->dev_set_bus(dev, 0);
 		if (err)
-			goto lbl_free_cmd_buf;
+			goto lbl_unregister_candev;
 	}
 
 	/* get device number early */
@@ -808,11 +808,14 @@ static int peak_usb_create_dev(struct peak_usb_adapter *peak_usb_adapter,
 
 	return 0;
 
-lbl_free_cmd_buf:
-	kfree(dev->cmd_buf);
+lbl_unregister_candev:
+	unregister_candev(netdev);
 
-lbl_set_intf_data:
+lbl_restore_intf_data:
 	usb_set_intfdata(intf, dev->prev_siblings);
+	kfree(dev->cmd_buf);
+
+lbl_free_candev:
 	free_candev(netdev);
 
 	return err;
Signature · 1 line
1.9.1
#62 lore raw

PATCH 57/176 ALSA: usb-audio: Don't resubmit pending URBs at MIDI error recovery

In reply to [email protected]

From: Takashi Iwai <[email protected]>

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

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

commit 66139a48cee1530c91f37c145384b4ee7043f0b7 upstream.

In snd_usbmidi_error_timer(), the driver tries to resubmit MIDI input URBs to reactivate the MIDI stream, but this causes the error when some of URBs are still pending like:

 WARNING: CPU: 0 PID: 0 at ../drivers/usb/core/urb.c:339 usb_submit_urb+0x5f/0x70()
 URB ef705c40 submitted while active
 CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.16.6-2-desktop #1
 Hardware name: FOXCONN TPS01/TPS01, BIOS 080015  03/23/2010
  c0984bfa f4009ed4 c078deaf f4009ee4 c024c884 c09a135c f4009f00 00000000
  c0984bfa 00000153 c061ac4f c061ac4f 00000009 00000001 ef705c40 e854d1c0
  f4009eec c024c8d3 00000009 f4009ee4 c09a135c f4009f00 f4009f04 c061ac4f
 Call Trace:
  [<c0205df6>] try_stack_unwind+0x156/0x170
  [<c020482a>] dump_trace+0x5a/0x1b0
  [<c0205e56>] show_trace_log_lvl+0x46/0x50
  [<c02049d1>] show_stack_log_lvl+0x51/0xe0
  [<c0205eb7>] show_stack+0x27/0x50
  [<c078deaf>] dump_stack+0x45/0x65
  [<c024c884>] warn_slowpath_common+0x84/0xa0
  [<c024c8d3>] warn_slowpath_fmt+0x33/0x40
  [<c061ac4f>] usb_submit_urb+0x5f/0x70
  [<f7974104>] snd_usbmidi_submit_urb+0x14/0x60 [snd_usbmidi_lib]
  [<f797483a>] snd_usbmidi_error_timer+0x6a/0xa0 [snd_usbmidi_lib]
  [<c02570c0>] call_timer_fn+0x30/0x130
  [<c0257442>] run_timer_softirq+0x1c2/0x260
  [<c0251493>] __do_softirq+0xc3/0x270
  [<c0204732>] do_softirq_own_stack+0x22/0x30
  [<c025186d>] irq_exit+0x8d/0xa0
  [<c0795228>] smp_apic_timer_interrupt+0x38/0x50
  [<c0794a3c>] apic_timer_interrupt+0x34/0x3c
  [<c0673d9e>] cpuidle_enter_state+0x3e/0xd0
  [<c028bb8d>] cpu_idle_loop+0x29d/0x3e0
  [<c028bd23>] cpu_startup_entry+0x53/0x60
  [<c0bfac1e>] start_kernel+0x415/0x41a

For avoiding these errors, check the pending URBs and skip resubmitting such ones.

---
 sound/usb/midi.c | 2 ++
 1 file changed, 2 insertions(+)
sound/usb/midi.c +2 -0
index e5fee18..de86e74 100644
@@ -364,6 +364,8 @@ static void snd_usbmidi_error_timer(unsigned long data)
 		if (in && in->error_resubmit) {
 			in->error_resubmit = 0;
 			for (j = 0; j < INPUT_URBS; ++j) {
+				if (atomic_read(&in->urbs[j]->use_count))
+					continue;
 				in->urbs[j]->dev = umidi->dev;
 				snd_usbmidi_submit_urb(in->urbs[j], GFP_ATOMIC);
 			}
Signature · 1 line
1.9.1
#63 lore raw

PATCH 58/176 KEYS: Fix stale key registration at error path

In reply to [email protected]

From: Takashi Iwai <[email protected]>

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

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

commit b26bdde5bb27f3f900e25a95e33a0c476c8c2c48 upstream.

When loading encrypted-keys module, if the last check of aes_get_sizes() in init_encrypted() fails, the driver just returns an error without unregistering its key type. This results in the stale entry in the list. In addition to memory leaks, this leads to a kernel crash when registering a new key type later.

This patch fixes the problem by swapping the calls of aes_get_sizes() and register_key_type(), and releasing resources properly at the error paths.

Bugzilla: https://bugzilla.opensuse.org/show_bug.cgi?id=908163

---
 security/keys/encrypted-keys/encrypted.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
security/keys/encrypted-keys/encrypted.c +4 -1
index 2d1bb8a..a02f923 100644
@@ -1016,10 +1016,13 @@ static int __init init_encrypted(void)
 	ret = encrypted_shash_alloc();
 	if (ret < 0)
 		return ret;
+	ret = aes_get_sizes();
+	if (ret < 0)
+		goto out;
 	ret = register_key_type(&key_type_encrypted);
 	if (ret < 0)
 		goto out;
-	return aes_get_sizes();
+	return 0;
 out:
 	encrypted_shash_release();
 	return ret;
Signature · 1 line
1.9.1
#64 lore raw

PATCH 59/176 Btrfs: fix fs corruption on transaction abort if device supports discard

In reply to [email protected]

From: Filipe Manana <[email protected]>

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

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

commit 678886bdc6378c1cbd5072da2c5a3035000214e3 upstream.

When we abort a transaction we iterate over all the ranges marked as dirty in fs_info->freed_extents[0] and fs_info->freed_extents[1], clear them from those trees, add them back (unpin) to the free space caches and, if the fs was mounted with "-o discard", perform a discard on those regions. Also, after adding the regions to the free space caches, a fitrim ioctl call can see those ranges in a block group's free space cache and perform a discard on the ranges, so the same issue can happen without "-o discard" as well.

This causes corruption, affecting one or multiple btree nodes (in the worst case leaving the fs unmountable) because some of those ranges (the ones in the fs_info->pinned_extents tree) correspond to btree nodes/leafs that are referred by the last committed super block - breaking the rule that anything that was committed by a transaction is untouched until the next transaction commits successfully.

I ran into this while running in a loop (for several hours) the fstest that I recently submitted:

[PATCH] fstests: add btrfs test to stress chunk allocation/removal and fstrim

The corruption always happened when a transaction aborted and then fsck complained like this:

_check_btrfs_filesystem: filesystem on /dev/sdc is inconsistent *** fsck.btrfs output ***
Check tree block failed, want=94945280, have=0
Check tree block failed, want=94945280, have=0
Check tree block failed, want=94945280, have=0
Check tree block failed, want=94945280, have=0
Check tree block failed, want=94945280, have=0
read block failed check_tree_block
Couldn't open file system

In this case 94945280 corresponded to the root of a tree. Using frace what I observed was the following sequence of steps happened:

1) transaction N started, fs_info->pinned_extents pointed to

      fs_info->freed_extents[0];

2) node/eb 94945280 is created;

3) eb is persisted to disk;

4) transaction N commit starts, fs_info->pinned_extents now points to

      fs_info->freed_extents[1], and transaction N completes;

5) transaction N + 1 starts;

6) eb is COWed, and btrfs_free_tree_block() called for this eb;

7) eb range (94945280 to 94945280 + 16Kb) is added to

      fs_info->pinned_extents (fs_info->freed_extents[1]);

8) Something goes wrong in transaction N + 1, like hitting ENOSPC

      for example, and the transaction is aborted, turning the fs into
      readonly mode. The stack trace I got for example:

      [112065.253935]  [<ffffffff8140c7b6>] dump_stack+0x4d/0x66
      [112065.254271]  [<ffffffff81042984>] warn_slowpath_common+0x7f/0x98
      [112065.254567]  [<ffffffffa0325990>] ? __btrfs_abort_transaction+0x50/0x10b [btrfs]
      [112065.261674]  [<ffffffff810429e5>] warn_slowpath_fmt+0x48/0x50
      [112065.261922]  [<ffffffffa032949e>] ? btrfs_free_path+0x26/0x29 [btrfs]
      [112065.262211]  [<ffffffffa0325990>] __btrfs_abort_transaction+0x50/0x10b [btrfs]
      [112065.262545]  [<ffffffffa036b1d6>] btrfs_remove_chunk+0x537/0x58b [btrfs]
      [112065.262771]  [<ffffffffa033840f>] btrfs_delete_unused_bgs+0x1de/0x21b [btrfs]
      [112065.263105]  [<ffffffffa0343106>] cleaner_kthread+0x100/0x12f [btrfs]
      (...)
      [112065.264493] ---[ end trace dd7903a975a31a08 ]---
      [112065.264673] BTRFS: error (device sdc) in btrfs_remove_chunk:2625: errno=-28 No space left
      [112065.264997] BTRFS info (device sdc): forced readonly

9) The clear kthread sees that the BTRFS_FS_STATE_ERROR bit is set in

      fs_info->fs_state and calls btrfs_cleanup_transaction(), which in
      turn calls btrfs_destroy_pinned_extent();

10) Then btrfs_destroy_pinned_extent() iterates over all the ranges marked as dirty in fs_info->freed_extents[], and for each one it calls discard, if the fs was mounted with "-o discard", and adds the range to the free space cache of the respective block group;

11) btrfs_trim_block_group(), invoked from the fitrim ioctl code path,

       sees the free space entries and performs a discard;

12) After an umount and mount (or fsck), our eb's location on disk was full of zeroes, and it should have been untouched, because it was marked as dirty in the fs_info->pinned_extents tree, and therefore used by the trees that the last committed superblock points to.

Fix this by not performing a discard and not adding the ranges to the free space caches - it's useless from this point since the fs is now in readonly mode and we won't write free space caches to disk anymore (otherwise we would leak space) nor any new superblock. By not adding the ranges to the free space caches, it prevents other code paths from allocating that space and write to it as well, therefore being safer and simpler.

This isn't a new problem, as it's been present since 2011 (git commit acce952b0263825da32cf10489413dec78053347).

---
 fs/btrfs/disk-io.c     |  6 ------
 fs/btrfs/extent-tree.c | 10 ++++++----
 2 files changed, 6 insertions(+), 10 deletions(-)
fs/btrfs/disk-io.c +0 -6
index a7ffc88..7c23cd9 100644
@@ -3556,12 +3556,6 @@ static int btrfs_destroy_pinned_extent(struct btrfs_root *root,
 		if (ret)
 			break;
 
-		/* opt_discard */
-		if (btrfs_test_opt(root, DISCARD))
-			ret = btrfs_error_discard_extent(root, start,
-							 end + 1 - start,
-							 NULL);
-
 		clear_extent_dirty(unpin, start, end, GFP_NOFS);
 		btrfs_error_unpin_extent_range(root, start, end);
 		cond_resched();
fs/btrfs/extent-tree.c +6 -4
index 224ce21..cf6e7f4 100644
@@ -4892,7 +4892,8 @@ void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans,
 	update_global_block_rsv(fs_info);
 }
 
-static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end)
+static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end,
+			      const bool return_free_space)
 {
 	struct btrfs_fs_info *fs_info = root->fs_info;
 	struct btrfs_block_group_cache *cache = NULL;
@@ -4912,7 +4913,8 @@ static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end)
 
 		if (start < cache->last_byte_to_unpin) {
 			len = min(len, cache->last_byte_to_unpin - start);
-			btrfs_add_free_space(cache, start, len);
+			if (return_free_space)
+				btrfs_add_free_space(cache, start, len);
 		}
 
 		start += len;
@@ -4960,7 +4962,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
 						   end + 1 - start, NULL);
 
 		clear_extent_dirty(unpin, start, end, GFP_NOFS);
-		unpin_extent_range(root, start, end);
+		unpin_extent_range(root, start, end, true);
 		cond_resched();
 	}
 
@@ -8008,7 +8010,7 @@ out:
 
 int btrfs_error_unpin_extent_range(struct btrfs_root *root, u64 start, u64 end)
 {
-	return unpin_extent_range(root, start, end);
+	return unpin_extent_range(root, start, end, false);
 }
 
 int btrfs_error_discard_extent(struct btrfs_root *root, u64 bytenr,
Signature · 1 line
1.9.1
#65 lore raw

PATCH 60/176 ncpfs: return proper error from NCP_IOC_SETROOT ioctl

In reply to [email protected]

From: Jan Kara <[email protected]>

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

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

commit a682e9c28cac152e6e54c39efcf046e0c8cfcf63 upstream.

If some error happens in NCP_IOC_SETROOT ioctl, the appropriate error return value is then (in most cases) just overwritten before we return. This can result in reporting success to userspace although error happened.

This bug was introduced by commit 2e54eb96e2c8 ("BKL: Remove BKL from ncpfs"). Propagate the errors correctly.

Coverity id: 1226925.

Fixes 2e54eb96e2c80 ("BKL: Remove BKL from ncpfs")
Cc Petr Vandrovec <[email protected]>
---
 fs/ncpfs/ioctl.c | 1 -
 1 file changed, 1 deletion(-)
fs/ncpfs/ioctl.c +0 -1
index 6958adf..0a76def 100644
@@ -445,7 +445,6 @@ static long __ncp_ioctl(struct inode *inode, unsigned int cmd, unsigned long arg
 						result = -EIO;
 					}
 				}
-				result = 0;
 			}
 			mutex_unlock(&server->root_setup_lock);
 
Signature · 1 line
1.9.1
#66 lore raw

PATCH 61/176 x86_64, switch_to(): Load TLS descriptors before switching DS and ES

In reply to [email protected]

From: Andy Lutomirski <[email protected]>

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

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

commit f647d7c155f069c1a068030255c300663516420e upstream.

Otherwise, if buggy user code points DS or ES into the TLS array, they would be corrupted after a context switch.

This also significantly improves the comments and documents some gotchas in the code.

Before this patch, the both tests below failed. With this patch, the es test passes, although the gsbase test still fails.

----- begin es test -----

/*
* Copyright (c) 2014 Andy Lutomirski
* GPL v2
*/

static unsigned short GDT3(int idx)

{
	return (idx << 3) | 3;
}

static int create_tls(int idx, unsigned int base)

{
	struct user_desc desc = {
		.entry_number    = idx,
		.base_addr       = base,
		.limit           = 0xfffff,
		.seg_32bit       = 1,
		.contents        = 0, /* Data, grow-up */
		.read_exec_only  = 0,
		.limit_in_pages  = 1,
		.seg_not_present = 0,
		.useable         = 0,
	};

	if (syscall(SYS_set_thread_area, &desc) != 0)
		err(1, "set_thread_area");

	return desc.entry_number;
}

int main()

{
	int idx = create_tls(-1, 0);
	printf("Allocated GDT index %d\n", idx);

	unsigned short orig_es;
	asm volatile ("mov %%es,%0" : "=rm" (orig_es));

	int errors = 0;
	int total = 1000;
	for (int i = 0; i < total; i++) {
		asm volatile ("mov %0,%%es" : : "rm" (GDT3(idx)));
		usleep(100);

		unsigned short es;
		asm volatile ("mov %%es,%0" : "=rm" (es));
		asm volatile ("mov %0,%%es" : : "rm" (orig_es));
		if (es != GDT3(idx)) {
			if (errors == 0)
				printf("[FAIL]\tES changed from 0x%hx to 0x%hx\n",
				       GDT3(idx), es);
			errors++;
		}
	}

	if (errors) {
		printf("[FAIL]\tES was corrupted %d/%d times\n", errors, total);
		return 1;
	} else {
		printf("[OK]\tES was preserved\n");
		return 0;
	}
}

----- end es test -----

----- begin gsbase test -----

/*
* gsbase.c, a gsbase test
* Copyright (c) 2014 Andy Lutomirski
* GPL v2
*/

static unsigned char *testptr, *testptr2;

static unsigned char read_gs_testvals(void)

{
	unsigned char ret;
	asm volatile ("movb %%gs:%1, %0" : "=r" (ret) : "m" (*testptr));
	return ret;
}

int main()

{
	int errors = 0;

	testptr = mmap((void *)0x200000000UL, 1, PROT_READ | PROT_WRITE,
		       MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
	if (testptr == MAP_FAILED)
		err(1, "mmap");

	testptr2 = mmap((void *)0x300000000UL, 1, PROT_READ | PROT_WRITE,
		       MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
	if (testptr2 == MAP_FAILED)
		err(1, "mmap");

	*testptr = 0;
	*testptr2 = 1;

	if (syscall(SYS_arch_prctl, ARCH_SET_GS,
		    (unsigned long)testptr2 - (unsigned long)testptr) != 0)
		err(1, "ARCH_SET_GS");

	usleep(100);

	if (read_gs_testvals() == 1) {
		printf("[OK]\tARCH_SET_GS worked\n");
	} else {
		printf("[FAIL]\tARCH_SET_GS failed\n");
		errors++;
	}

	asm volatile ("mov %0,%%gs" : : "r" (0));

	if (read_gs_testvals() == 0) {
		printf("[OK]\tWriting 0 to gs worked\n");
	} else {
		printf("[FAIL]\tWriting 0 to gs failed\n");
		errors++;
	}

	usleep(100);

	if (read_gs_testvals() == 0) {
		printf("[OK]\tgsbase is still zero\n");
	} else {
		printf("[FAIL]\tgsbase was corrupted\n");
		errors++;
	}

	return errors == 0 ? 0 : 1;
}

----- end gsbase test -----

---
 arch/x86/kernel/process_64.c | 101 +++++++++++++++++++++++++++++++------------
 1 file changed, 73 insertions(+), 28 deletions(-)
arch/x86/kernel/process_64.c +73 -28
index 43d8b48..bb390e1 100644
@@ -286,24 +286,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 
 	fpu = switch_fpu_prepare(prev_p, next_p, cpu);
 
-	/*
-	 * Reload esp0, LDT and the page table pointer:
-	 */
+	/* Reload esp0 and ss1. */
 	load_sp0(tss, next);
 
-	/*
-	 * Switch DS and ES.
-	 * This won't pick up thread selector changes, but I guess that is ok.
-	 */
-	savesegment(es, prev->es);
-	if (unlikely(next->es | prev->es))
-		loadsegment(es, next->es);
-
-	savesegment(ds, prev->ds);
-	if (unlikely(next->ds | prev->ds))
-		loadsegment(ds, next->ds);
-
-
 	/* We must save %fs and %gs before load_TLS() because
 	 * %fs and %gs may be cleared by load_TLS().
 	 *
@@ -312,41 +297,101 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 	savesegment(fs, fsindex);
 	savesegment(gs, gsindex);
 
+	/*
+	 * Load TLS before restoring any segments so that segment loads
+	 * reference the correct GDT entries.
+	 */
 	load_TLS(next, cpu);
 
 	/*
-	 * Leave lazy mode, flushing any hypercalls made here.
-	 * This must be done before restoring TLS segments so
-	 * the GDT and LDT are properly updated, and must be
-	 * done before math_state_restore, so the TS bit is up
-	 * to date.
+	 * Leave lazy mode, flushing any hypercalls made here.  This
+	 * must be done after loading TLS entries in the GDT but before
+	 * loading segments that might reference them, and and it must
+	 * be done before math_state_restore, so the TS bit is up to
+	 * date.
 	 */
 	arch_end_context_switch(next_p);
 
+	/* Switch DS and ES.
+	 *
+	 * Reading them only returns the selectors, but writing them (if
+	 * nonzero) loads the full descriptor from the GDT or LDT.  The
+	 * LDT for next is loaded in switch_mm, and the GDT is loaded
+	 * above.
+	 *
+	 * We therefore need to write new values to the segment
+	 * registers on every context switch unless both the new and old
+	 * values are zero.
+	 *
+	 * Note that we don't need to do anything for CS and SS, as
+	 * those are saved and restored as part of pt_regs.
+	 */
+	savesegment(es, prev->es);
+	if (unlikely(next->es | prev->es))
+		loadsegment(es, next->es);
+
+	savesegment(ds, prev->ds);
+	if (unlikely(next->ds | prev->ds))
+		loadsegment(ds, next->ds);
+
 	/*
 	 * Switch FS and GS.
 	 *
-	 * Segment register != 0 always requires a reload.  Also
-	 * reload when it has changed.  When prev process used 64bit
-	 * base always reload to avoid an information leak.
+	 * These are even more complicated than FS and GS: they have
+	 * 64-bit bases are that controlled by arch_prctl.  Those bases
+	 * only differ from the values in the GDT or LDT if the selector
+	 * is 0.
+	 *
+	 * Loading the segment register resets the hidden base part of
+	 * the register to 0 or the value from the GDT / LDT.  If the
+	 * next base address zero, writing 0 to the segment register is
+	 * much faster than using wrmsr to explicitly zero the base.
+	 *
+	 * The thread_struct.fs and thread_struct.gs values are 0
+	 * if the fs and gs bases respectively are not overridden
+	 * from the values implied by fsindex and gsindex.  They
+	 * are nonzero, and store the nonzero base addresses, if
+	 * the bases are overridden.
+	 *
+	 * (fs != 0 && fsindex != 0) || (gs != 0 && gsindex != 0) should
+	 * be impossible.
+	 *
+	 * Therefore we need to reload the segment registers if either
+	 * the old or new selector is nonzero, and we need to override
+	 * the base address if next thread expects it to be overridden.
+	 *
+	 * This code is unnecessarily slow in the case where the old and
+	 * new indexes are zero and the new base is nonzero -- it will
+	 * unnecessarily write 0 to the selector before writing the new
+	 * base address.
+	 *
+	 * Note: This all depends on arch_prctl being the only way that
+	 * user code can override the segment base.  Once wrfsbase and
+	 * wrgsbase are enabled, most of this code will need to change.
 	 */
 	if (unlikely(fsindex | next->fsindex | prev->fs)) {
 		loadsegment(fs, next->fsindex);
+
 		/*
-		 * Check if the user used a selector != 0; if yes
-		 *  clear 64bit base, since overloaded base is always
-		 *  mapped to the Null selector
+		 * If user code wrote a nonzero value to FS, then it also
+		 * cleared the overridden base address.
+		 *
+		 * XXX: if user code wrote 0 to FS and cleared the base
+		 * address itself, we won't notice and we'll incorrectly
+		 * restore the prior base address next time we reschdule
+		 * the process.
 		 */
 		if (fsindex)
 			prev->fs = 0;
 	}
-	/* when next process has a 64bit base use it */
 	if (next->fs)
 		wrmsrl(MSR_FS_BASE, next->fs);
 	prev->fsindex = fsindex;
 
 	if (unlikely(gsindex | next->gsindex | prev->gs)) {
 		load_gs_index(next->gsindex);
+
+		/* This works (and fails) the same way as fsindex above. */
 		if (gsindex)
 			prev->gs = 0;
 	}
Signature · 1 line
1.9.1
#67 lore raw

PATCH 62/176 genirq: Prevent proc race against freeing of irq descriptors

In reply to [email protected]

From: Thomas Gleixner <[email protected]>

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

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

commit c291ee622165cb2c8d4e7af63fffd499354a23be upstream.

Since the rework of the sparse interrupt code to actually free the unused interrupt descriptors there exists a race between the /proc interfaces to the irq subsystem and the code which frees the interrupt descriptor.

CPU0 CPU1

				show_interrupts()
				  desc = irq_to_desc(X);
free_desc(desc)
  remove_from_radix_tree();
  kfree(desc);
				  raw_spinlock_irq(&desc->lock);

/proc/interrupts is the only interface which can actively corrupt kernel memory via the lock access. /proc/stat can only read from freed memory. Extremly hard to trigger, but possible.

The interfaces in /proc/irq/N/ are not affected by this because the removal of the proc file is serialized in procfs against concurrent readers/writers. The removal happens before the descriptor is freed.

For architectures which have CONFIG_SPARSE_IRQ=n this is a non issue as the descriptor is never freed. It's merely cleared out with the irq descriptor lock held. So any concurrent proc access will either see the old correct value or the cleared out ones.

Protect the lookup and access to the irq descriptor in show_interrupts() with the sparse_irq_lock.

Provide kstat_irqs_usr() which is protecting the lookup and access with sparse_irq_lock and switch /proc/stat to use it.

Document the existing kstat_irqs interfaces so it's clear that the caller needs to take care about protection. The users of these interfaces are either not affected due to SPARSE_IRQ=n or already protected against removal.

Fixes 1f5a5b87f78f "genirq: Implement a sane sparse_irq allocator"

[lizf: Backported to 3.4:
- define kstat_irqs() for CONFIG_GENERIC_HARDIRQS
- add ifdef/endif CONFIG_SPARSE_IRQ]

---
 fs/proc/stat.c              |  2 +-
 include/linux/kernel_stat.h |  5 +++++
 kernel/irq/internals.h      |  8 +++++++
 kernel/irq/irqdesc.c        | 52 +++++++++++++++++++++++++++++++++++++++++++++
 kernel/irq/proc.c           | 22 ++++++++++++++++++-
 5 files changed, 87 insertions(+), 2 deletions(-)
fs/proc/stat.c +1 -1
index e296572..f65c5da 100644
@@ -159,7 +159,7 @@ static int show_stat(struct seq_file *p, void *v)
 
 	/* sum again ? it could be updated? */
 	for_each_irq_nr(j)
-		seq_put_decimal_ull(p, ' ', kstat_irqs(j));
+		seq_put_decimal_ull(p, ' ', kstat_irqs_usr(j));
 
 	seq_printf(p,
 		"\nctxt %llu\n"
include/linux/kernel_stat.h +5 -0
index 2fbd905..8e62498 100644
@@ -104,8 +104,13 @@ static inline unsigned int kstat_irqs(unsigned int irq)
 
 	return sum;
 }
+static inline unsigned int kstat_irqs_usr(unsigned int irq)
+{
+	return kstat_irqs(irq);
+}
 #else
 extern unsigned int kstat_irqs(unsigned int irq);
+extern unsigned int kstat_irqs_usr(unsigned int irq);
 #endif
 
 /*
kernel/irq/internals.h +8 -0
index 8e5c56b..5a41440 100644
@@ -74,6 +74,14 @@ extern void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu);
 extern void mask_irq(struct irq_desc *desc);
 extern void unmask_irq(struct irq_desc *desc);
 
+#ifdef CONFIG_SPARSE_IRQ
+extern void irq_lock_sparse(void);
+extern void irq_unlock_sparse(void);
+#else
+static inline void irq_lock_sparse(void) { }
+static inline void irq_unlock_sparse(void) { }
+#endif
+
 extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr);
 
 irqreturn_t handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action);
kernel/irq/irqdesc.c +52 -0

79 lines not on this page · raw message

kernel/irq/proc.c +21 -1
index 4bd4faa..fb655f5f 100644
@@ -15,6 +15,23 @@
 
 #include "internals.h"
 
+/*
+ * Access rules:
+ *
+ * procfs protects read/write of /proc/irq/N/ files against a
+ * concurrent free of the interrupt descriptor. remove_proc_entry()
+ * immediately prevents new read/writes to happen and waits for
+ * already running read/write functions to complete.
+ *
+ * We remove the proc entries first and then delete the interrupt
+ * descriptor from the radix tree and free it. So it is guaranteed
+ * that irq_to_desc(N) is valid as long as the read/writes are
+ * permitted by procfs.
+ *
+ * The read from /proc/interrupts is a different problem because there
+ * is no protection. So the lookup and the access to irqdesc
+ * information must be protected by sparse_irq_lock.
+ */
 static struct proc_dir_entry *root_irq_dir;
 
 #ifdef CONFIG_SMP
@@ -441,9 +458,10 @@ int show_interrupts(struct seq_file *p, void *v)
 		seq_putc(p, '\n');
 	}
 
+	irq_lock_sparse();
 	desc = irq_to_desc(i);
 	if (!desc)
-		return 0;
+		goto outsparse;
 
 	raw_spin_lock_irqsave(&desc->lock, flags);
 	for_each_online_cpu(j)
@@ -481,6 +499,8 @@ int show_interrupts(struct seq_file *p, void *v)
 	seq_putc(p, '\n');
 out:
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
+outsparse:
+	irq_unlock_sparse();
 	return 0;
 }
 #endif
Signature · 1 line
1.9.1
#68 lore raw

PATCH 63/176 x86/tls: Disallow unusual TLS segments

In reply to [email protected]

From: Andy Lutomirski <[email protected]>

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

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

commit 0e58af4e1d2166e9e33375a0f121e4867010d4f8 upstream.

Users have no business installing custom code segments into the GDT, and segments that are not present but are otherwise valid are a historical source of interesting attacks.

For completeness, block attempts to set the L bit. (Prior to this patch, the L bit would have been silently dropped.)

This is an ABI break. I've checked glibc, musl, and Wine, and none of them look like they'll have any trouble.

Note to stable maintainers: this is a hardening patch that fixes no known bugs. Given the possibility of ABI issues, this probably shouldn't be backported quickly.

---
 arch/x86/kernel/tls.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
arch/x86/kernel/tls.c +22 -0
index 9d25a6e..23a0b54 100644
@@ -60,6 +60,28 @@ static bool tls_desc_okay(const struct user_desc *info)
 	if (!info->seg_32bit)
 		return false;
 
+	/* Only allow data segments in the TLS array. */
+	if (info->contents > 1)
+		return false;
+
+	/*
+	 * Non-present segments with DPL 3 present an interesting attack
+	 * surface.  The kernel should handle such segments correctly,
+	 * but TLS is very difficult to protect in a sandbox, so prevent
+	 * such segments from being created.
+	 *
+	 * If userspace needs to remove a TLS entry, it can still delete
+	 * it outright.
+	 */
+	if (info->seg_not_present)
+		return false;
+
+#ifdef CONFIG_X86_64
+	/* The L bit makes no sense for data. */
+	if (info->lm)
+		return false;
+#endif
+
 	return true;
 }
 
Signature · 1 line
1.9.1
#69 lore raw

PATCH 64/176 x86/tls: Don't validate lm in set_thread_area() after all

In reply to [email protected]

From: Andy Lutomirski <[email protected]>

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

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

commit 3fb2f4237bb452eb4e98f6a5dbd5a445b4fed9d0 upstream.

It turns out that there's a lurking ABI issue. GCC, when compiling this in a 32-bit program:

struct user_desc desc = {
	.entry_number    = idx,
	.base_addr       = base,
	.limit           = 0xfffff,
	.seg_32bit       = 1,
	.contents        = 0, /* Data, grow-up */
	.read_exec_only  = 0,
	.limit_in_pages  = 1,
	.seg_not_present = 0,
	.useable         = 0,
};

will leave .lm uninitialized. This means that anything in the kernel that reads user_desc.lm for 32-bit tasks is unreliable.

Revert the .lm check in set_thread_area(). The value never did anything in the first place.

Fixes 0e58af4e1d21 ("x86/tls: Disallow unusual TLS segments")
Cc Linus Torvalds <[email protected]>
[lizf: Backported to 3.4: adjust filename]
---
 arch/x86/include/asm/ldt.h | 7 +++++++
 arch/x86/kernel/tls.c      | 6 ------
 2 files changed, 7 insertions(+), 6 deletions(-)
arch/x86/include/asm/ldt.h +7 -0
index 46727eb..6e1aaf7 100644
@@ -28,6 +28,13 @@ struct user_desc {
 	unsigned int  seg_not_present:1;
 	unsigned int  useable:1;
 #ifdef __x86_64__
+	/*
+	 * Because this bit is not present in 32-bit user code, user
+	 * programs can pass uninitialized values here.  Therefore, in
+	 * any context in which a user_desc comes from a 32-bit program,
+	 * the kernel must act as though lm == 0, regardless of the
+	 * actual value.
+	 */
 	unsigned int  lm:1;
 #endif
 };
arch/x86/kernel/tls.c +0 -6
index 23a0b54..fe2e363 100644
@@ -76,12 +76,6 @@ static bool tls_desc_okay(const struct user_desc *info)
 	if (info->seg_not_present)
 		return false;
 
-#ifdef CONFIG_X86_64
-	/* The L bit makes no sense for data. */
-	if (info->lm)
-		return false;
-#endif
-
 	return true;
 }
 
Signature · 1 line
1.9.1
#70 lore raw

PATCH 65/176 storvsc: ring buffer failures may result in I/O freeze

In reply to [email protected]

From: Long Li <[email protected]>

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

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

commit e86fb5e8ab95f10ec5f2e9430119d5d35020c951 upstream.

When ring buffer returns an error indicating retry, storvsc may not return a proper error code to SCSI when bounce buffer is not used. This has introduced I/O freeze on RAID running atop storvsc devices. This patch fixes it by always returning a proper error code.

---
 drivers/scsi/storvsc_drv.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/scsi/storvsc_drv.c +3 -4
index 446c023..a0df0fb 100644
@@ -1359,13 +1359,12 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
 	if (ret == -EAGAIN) {
 		/* no more space */
 
-		if (cmd_request->bounce_sgl_count) {
+		if (cmd_request->bounce_sgl_count)
 			destroy_bounce_buffer(cmd_request->bounce_sgl,
 					cmd_request->bounce_sgl_count);
 
-			ret = SCSI_MLQUEUE_DEVICE_BUSY;
-			goto queue_error;
-		}
+		ret = SCSI_MLQUEUE_DEVICE_BUSY;
+		goto queue_error;
 	}
 
 	return 0;
Signature · 1 line
1.9.1
#71 lore raw

PATCH 66/176 isofs: Fix infinite looping over CE entries

In reply to [email protected]

From: Jan Kara <[email protected]>

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

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

commit f54e18f1b831c92f6512d2eedb224cd63d607d3d upstream.

Rock Ridge extensions define so called Continuation Entries (CE) which define where is further space with Rock Ridge data. Corrupted isofs image can contain arbitrarily long chain of these, including a one containing loop and thus causing kernel to end in an infinite loop when traversing these entries.

Limit the traversal to 32 entries which should be more than enough space to store all the Rock Ridge data.

---
 fs/isofs/rock.c | 6 ++++++
 1 file changed, 6 insertions(+)
fs/isofs/rock.c +6 -0
index ee62cc0..26859de 100644
@@ -30,6 +30,7 @@ struct rock_state {
 	int cont_size;
 	int cont_extent;
 	int cont_offset;
+	int cont_loops;
 	struct inode *inode;
 };
 
@@ -73,6 +74,9 @@ static void init_rock_state(struct rock_state *rs, struct inode *inode)
 	rs->inode = inode;
 }
 
+/* Maximum number of Rock Ridge continuation entries */
+#define RR_MAX_CE_ENTRIES 32
+
 /*
  * Returns 0 if the caller should continue scanning, 1 if the scan must end
  * and -ve on error.
@@ -105,6 +109,8 @@ static int rock_continue(struct rock_state *rs)
 			goto out;
 		}
 		ret = -EIO;
+		if (++rs->cont_loops >= RR_MAX_CE_ENTRIES)
+			goto out;
 		bh = sb_bread(rs->inode->i_sb, rs->cont_extent);
 		if (bh) {
 			memcpy(rs->buffer, bh->b_data + rs->cont_offset,
Signature · 1 line
1.9.1
#72 lore raw

PATCH 67/176 iscsi-target: Fail connection on short sendmsg writes

In reply to [email protected]

From: Nicholas Bellinger <[email protected]>

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

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

commit 6bf6ca7515c1df06f5c03737537f5e0eb191e29e upstream.

This patch changes iscsit_do_tx_data() to fail on short writes when kernel_sendmsg() returns a value different than requested transfer length, returning -EPIPE and thus causing a connection reset to occur.

This avoids a potential bug in the original code where a short write would result in kernel_sendmsg() being called again with the original iovec base + length.

In practice this has not been an issue because iscsit_do_tx_data() is only used for transferring 48 byte headers + 4 byte digests, along with seldom used control payloads from NOPIN + TEXT_RSP + REJECT with less than 32k of data.

So following Al's audit of iovec consumers, go ahead and fail the connection on short writes for now, and remove the bogus logic ahead of his proper upstream fix.

---
 drivers/target/iscsi/iscsi_target_util.c | 26 +++++++++++---------------
 1 file changed, 11 insertions(+), 15 deletions(-)
drivers/target/iscsi/iscsi_target_util.c +11 -15
index 4c05ed6..8d57ab3 100644
@@ -1480,15 +1480,15 @@ static int iscsit_do_tx_data(
 	struct iscsi_conn *conn,
 	struct iscsi_data_count *count)
 {
-	int data = count->data_length, total_tx = 0, tx_loop = 0, iov_len;
+	int ret, iov_len;
 	struct kvec *iov_p;
 	struct msghdr msg;
 
 	if (!conn || !conn->sock || !conn->conn_ops)
 		return -1;
 
-	if (data <= 0) {
-		pr_err("Data length is: %d\n", data);
+	if (count->data_length <= 0) {
+		pr_err("Data length is: %d\n", count->data_length);
 		return -1;
 	}
 
@@ -1497,20 +1497,16 @@ static int iscsit_do_tx_data(
 	iov_p = count->iov;
 	iov_len = count->iov_count;
 
-	while (total_tx < data) {
-		tx_loop = kernel_sendmsg(conn->sock, &msg, iov_p, iov_len,
-					(data - total_tx));
-		if (tx_loop <= 0) {
-			pr_debug("tx_loop: %d total_tx %d\n",
-				tx_loop, total_tx);
-			return tx_loop;
-		}
-		total_tx += tx_loop;
-		pr_debug("tx_loop: %d, total_tx: %d, data: %d\n",
-					tx_loop, total_tx, data);
+	ret = kernel_sendmsg(conn->sock, &msg, iov_p, iov_len,
+			     count->data_length);
+	if (ret != count->data_length) {
+		pr_err("Unexpected ret: %d send data %d\n",
+		       ret, count->data_length);
+		return -EPIPE;
 	}
+	pr_debug("ret: %d, sent data: %d\n", ret, count->data_length);
 
-	return total_tx;
+	return ret;
 }
 
 int rx_data(
Signature · 1 line
1.9.1
#73 lore raw

PATCH 68/176 ALSA: usb-audio: extend KEF X300A FU 10 tweak to Arcam rPAC

In reply to [email protected]

From: Jiri Jaburek <[email protected]>

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

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

commit d70a1b9893f820fdbcdffac408c909c50f2e6b43 upstream.

The Arcam rPAC seems to have the same problem - whenever anything (alsamixer, udevd, 3.9+ kernel from 60af3d037eb8c, ..) attempts to access mixer / control interface of the card, the firmware "locks up" the entire device, resulting in
SNDRV_PCM_IOCTL_HW_PARAMS failed (-5): Input/output error
from alsa-lib.

Other operating systems can somehow read the mixer (there seems to be playback volume/mute), but any manipulation is ignored by the device (which has hardware volume controls).

---
 sound/usb/mixer_maps.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)
sound/usb/mixer_maps.c +12 -3
index 0e4e909..1e0798f 100644
@@ -304,8 +304,11 @@ static struct usbmix_name_map hercules_usb51_map[] = {
 	{ 0 }				/* terminator */
 };
 
-static const struct usbmix_name_map kef_x300a_map[] = {
-	{ 10, NULL }, /* firmware locks up (?) when we try to access this FU */
+/* some (all?) SCMS USB3318 devices are affected by a firmware lock up
+ * when anything attempts to access FU 10 (control)
+ */
+static const struct usbmix_name_map scms_usb3318_map[] = {
+	{ 10, NULL },
 	{ 0 }
 };
 
@@ -377,8 +380,14 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = {
 		.ignore_ctl_error = 1,
 	},
 	{
+		/* KEF X300A */
 		.id = USB_ID(0x27ac, 0x1000),
-		.map = kef_x300a_map,
+		.map = scms_usb3318_map,
+	},
+	{
+		/* Arcam rPAC */
+		.id = USB_ID(0x25c4, 0x0003),
+		.map = scms_usb3318_map,
 	},
 	{ 0 } /* terminator */
 };
Signature · 1 line
1.9.1
#74 lore raw

PATCH 69/176 ocfs2: fix journal commit deadlock

In reply to [email protected]

From: Junxiao Bi <[email protected]>

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

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

commit 136f49b9171074872f2a14ad0ab10486d1ba13ca upstream.

For buffer write, page lock will be got in write_begin and released in write_end, in ocfs2_write_end_nolock(), before it unlock the page in ocfs2_free_write_ctxt(), it calls ocfs2_run_deallocs(), this will ask for the read lock of journal->j_trans_barrier. Holding page lock and ask for journal->j_trans_barrier breaks the locking order.

This will cause a deadlock with journal commit threads, ocfs2cmt will get write lock of journal->j_trans_barrier first, then it wakes up kjournald2 to do the commit work, at last it waits until done. To commit journal, kjournald2 needs flushing data first, it needs get the cache page lock.

Since some ocfs2 cluster locks are holding by write process, this deadlock may hung the whole cluster.

unlock pages before ocfs2_run_deallocs() can fix the locking order, also put unlock before ocfs2_commit_trans() to make page lock is unlocked before j_trans_barrier to preserve unlocking order.

---
 fs/ocfs2/aops.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)
fs/ocfs2/aops.c +14 -2
index 340bd02..e9829ca 100644
@@ -917,7 +917,7 @@ void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages)
 	}
 }
 
-static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc)
+static void ocfs2_unlock_pages(struct ocfs2_write_ctxt *wc)
 {
 	int i;
 
@@ -938,7 +938,11 @@ static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc)
 		page_cache_release(wc->w_target_page);
 	}
 	ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages);
+}
 
+static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc)
+{
+	ocfs2_unlock_pages(wc);
 	brelse(wc->w_di_bh);
 	kfree(wc);
 }
@@ -2059,11 +2063,19 @@ out_write_size:
 	di->i_mtime_nsec = di->i_ctime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec);
 	ocfs2_journal_dirty(handle, wc->w_di_bh);
 
+	/* unlock pages before dealloc since it needs acquiring j_trans_barrier
+	 * lock, or it will cause a deadlock since journal commit threads holds
+	 * this lock and will ask for the page lock when flushing the data.
+	 * put it here to preserve the unlock order.
+	 */
+	ocfs2_unlock_pages(wc);
+
 	ocfs2_commit_trans(osb, handle);
 
 	ocfs2_run_deallocs(osb, &wc->w_dealloc);
 
-	ocfs2_free_write_ctxt(wc);
+	brelse(wc->w_di_bh);
+	kfree(wc);
 
 	return copied;
 }
Signature · 1 line
1.9.1
#75 lore raw

PATCH 70/176 isofs: Fix unchecked printing of ER records

In reply to [email protected]

From: Jan Kara <[email protected]>

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

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

commit 4e2024624e678f0ebb916e6192bd23c1f9fdf696 upstream.

We didn't check length of rock ridge ER records before printing them. Thus corrupted isofs image can cause us to access and print some memory behind the buffer with obvious consequences.

---
 fs/isofs/rock.c | 3 +++
 1 file changed, 3 insertions(+)
fs/isofs/rock.c +3 -0
index 26859de..1780949 100644
@@ -362,6 +362,9 @@ repeat:
 			rs.cont_size = isonum_733(rr->u.CE.size);
 			break;
 		case SIG('E', 'R'):
+			/* Invalid length of ER tag id? */
+			if (rr->u.ER.len_id + offsetof(struct rock_ridge, u.ER.data) > rr->len)
+				goto out;
 			ISOFS_SB(inode->i_sb)->s_rock = 1;
 			printk(KERN_DEBUG "ISO 9660 Extensions: ");
 			{
Signature · 1 line
1.9.1
#76 lore raw

PATCH 71/176 udf: Verify i_size when loading inode

In reply to [email protected]

From: Jan Kara <[email protected]>

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

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

commit e159332b9af4b04d882dbcfe1bb0117f0a6d4b58 upstream.

Verify that inode size is sane when loading inode with data stored in ICB. Otherwise we may get confused later when working with the inode and inode size is too big.

[lizf: Backported to 3.4: just return on error, as there's no "out" label]
---
 fs/udf/inode.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
fs/udf/inode.c +14 -0
index aa70035..8053ee7 100644
@@ -1392,6 +1392,20 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
 							iinfo->i_lenEAttr;
 	}
 
+	/* Sanity checks for files in ICB so that we don't get confused later */
+	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
+		/*
+		 * For file in ICB data is stored in allocation descriptor
+		 * so sizes should match
+		 */
+		if (iinfo->i_lenAlloc != inode->i_size)
+			return;
+		/* File in ICB has to fit in there... */
+		if (inode->i_size > inode->i_sb->s_blocksize -
+					udf_file_entry_alloc_offset(inode))
+			return;
+	}
+
 	switch (fe->icbTag.fileType) {
 	case ICBTAG_FILE_TYPE_DIRECTORY:
 		inode->i_op = &udf_dir_inode_operations;
Signature · 1 line
1.9.1
#77 lore raw

PATCH 72/176 udf: Verify symlink size before loading it

In reply to [email protected]

From: Jan Kara <[email protected]>

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

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

commit a1d47b262952a45aae62bd49cfaf33dd76c11a2c upstream.

UDF specification allows arbitrarily large symlinks. However we support only symlinks at most one block large. Check the length of the symlink so that we don't access memory beyond end of the symlink block.

---
 fs/udf/symlink.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
fs/udf/symlink.c +13 -4
index d7c6dbe..d89f324 100644
@@ -80,11 +80,17 @@ static int udf_symlink_filler(struct file *file, struct page *page)
 	struct inode *inode = page->mapping->host;
 	struct buffer_head *bh = NULL;
 	unsigned char *symlink;
-	int err = -EIO;
+	int err;
 	unsigned char *p = kmap(page);
 	struct udf_inode_info *iinfo;
 	uint32_t pos;
 
+	/* We don't support symlinks longer than one block */
+	if (inode->i_size > inode->i_sb->s_blocksize) {
+		err = -ENAMETOOLONG;
+		goto out_unmap;
+	}
+
 	iinfo = UDF_I(inode);
 	pos = udf_block_map(inode, 0);
 
@@ -94,8 +100,10 @@ static int udf_symlink_filler(struct file *file, struct page *page)
 	} else {
 		bh = sb_bread(inode->i_sb, pos);
 
-		if (!bh)
-			goto out;
+		if (!bh) {
+			err = -EIO;
+			goto out_unlock_inode;
+		}
 
 		symlink = bh->b_data;
 	}
@@ -109,9 +117,10 @@ static int udf_symlink_filler(struct file *file, struct page *page)
 	unlock_page(page);
 	return 0;
 
-out:
+out_unlock_inode:
 	up_read(&iinfo->i_data_sem);
 	SetPageError(page);
+out_unmap:
 	kunmap(page);
 	unlock_page(page);
 	return err;
Signature · 1 line
1.9.1
#78 lore raw

PATCH 73/176 udf: Check path length when reading symlink

In reply to [email protected]

From: Jan Kara <[email protected]>

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

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

commit 0e5cc9a40ada6046e6bc3bdfcd0c0d7e4b706b14 upstream.

Symlink reading code does not check whether the resulting path fits into the page provided by the generic code. This isn't as easy as just checking the symlink size because of various encoding conversions we perform on path. So we have to check whether there is still enough space in the buffer on the fly.

[lizf: Backported to 3.4: udf_get_filename() is called in do_udf_readdir()]
---
 fs/udf/dir.c     |  3 ++-
 fs/udf/namei.c   |  3 ++-
 fs/udf/symlink.c | 31 ++++++++++++++++++++++++++-----
 fs/udf/udfdecl.h |  3 ++-
 fs/udf/unicode.c | 28 ++++++++++++++++------------
 5 files changed, 48 insertions(+), 20 deletions(-)
fs/udf/dir.c +2 -1
index eb8bfe2..56341af 100644
@@ -163,7 +163,8 @@ static int do_udf_readdir(struct inode *dir, struct file *filp,
 			struct kernel_lb_addr tloc = lelb_to_cpu(cfi.icb.extLocation);
 
 			iblock = udf_get_lb_pblock(dir->i_sb, &tloc, 0);
-			flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi);
+			flen = udf_get_filename(dir->i_sb, nameptr, lfi, fname,
+						UDF_NAME_LEN);
 			dt_type = DT_UNKNOWN;
 		}
 
fs/udf/namei.c +2 -1
index 78bff11..407c129 100644
@@ -233,7 +233,8 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
 		if (!lfi)
 			continue;
 
-		flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi);
+		flen = udf_get_filename(dir->i_sb, nameptr, lfi, fname,
+					UDF_NAME_LEN);
 		if (flen && udf_match(flen, fname, child->len, child->name))
 			goto out_ok;
 	}
fs/udf/symlink.c +26 -5
index d89f324..2d0c372 100644
@@ -30,13 +30,16 @@
 #include <linux/buffer_head.h>
 #include "udf_i.h"
 
-static void udf_pc_to_char(struct super_block *sb, unsigned char *from,
-			   int fromlen, unsigned char *to)
+static int udf_pc_to_char(struct super_block *sb, unsigned char *from,
+			  int fromlen, unsigned char *to, int tolen)
 {
 	struct pathComponent *pc;
 	int elen = 0;
+	int comp_len;
 	unsigned char *p = to;
 
+	/* Reserve one byte for terminating \0 */
+	tolen--;
 	while (elen < fromlen) {
 		pc = (struct pathComponent *)(from + elen);
 		switch (pc->componentType) {
@@ -49,22 +52,37 @@ static void udf_pc_to_char(struct super_block *sb, unsigned char *from,
 				break;
 			/* Fall through */
 		case 2:
+			if (tolen == 0)
+				return -ENAMETOOLONG;
 			p = to;
 			*p++ = '/';
+			tolen--;
 			break;
 		case 3:
+			if (tolen < 3)
+				return -ENAMETOOLONG;
 			memcpy(p, "../", 3);
 			p += 3;
+			tolen -= 3;
 			break;
 		case 4:
+			if (tolen < 2)
+				return -ENAMETOOLONG;
 			memcpy(p, "./", 2);
 			p += 2;
+			tolen -= 2;
 			/* that would be . - just ignore */
 			break;
 		case 5:
-			p += udf_get_filename(sb, pc->componentIdent, p,
-					      pc->lengthComponentIdent);
+			comp_len = udf_get_filename(sb, pc->componentIdent,
+						    pc->lengthComponentIdent,
+						    p, tolen);
+			p += comp_len;
+			tolen -= comp_len;
+			if (tolen == 0)
+				return -ENAMETOOLONG;
 			*p++ = '/';
+			tolen--;
 			break;
 		}
 		elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;
@@ -73,6 +91,7 @@ static void udf_pc_to_char(struct super_block *sb, unsigned char *from,
 		p[-1] = '\0';
 	else
 		p[0] = '\0';
+	return 0;
 }
 
 static int udf_symlink_filler(struct file *file, struct page *page)
@@ -108,8 +127,10 @@ static int udf_symlink_filler(struct file *file, struct page *page)
 		symlink = bh->b_data;
 	}
 
-	udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p);
+	err = udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p, PAGE_SIZE);
 	brelse(bh);
+	if (err)
+		goto out_unlock_inode;
 
 	up_read(&iinfo->i_data_sem);
 	SetPageUptodate(page);
fs/udf/udfdecl.h +2 -1
index ebe1031..375f648 100644
@@ -207,7 +207,8 @@ udf_get_lb_pblock(struct super_block *sb, struct kernel_lb_addr *loc,
 }
 
 /* unicode.c */
-extern int udf_get_filename(struct super_block *, uint8_t *, uint8_t *, int);
+extern int udf_get_filename(struct super_block *, uint8_t *, int, uint8_t *,
+			    int);
 extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *,
 			    int);
 extern int udf_build_ustr(struct ustr *, dstring *, int);
fs/udf/unicode.c +16 -12
index 44b815e..d29c06f 100644
@@ -28,7 +28,8 @@
 
 #include "udf_sb.h"
 
-static int udf_translate_to_linux(uint8_t *, uint8_t *, int, uint8_t *, int);
+static int udf_translate_to_linux(uint8_t *, int, uint8_t *, int, uint8_t *,
+				  int);
 
 static int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen)
 {
@@ -333,8 +334,8 @@ try_again:
 	return u_len + 1;
 }
 
-int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname,
-		     int flen)
+int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen,
+		     uint8_t *dname, int dlen)
 {
 	struct ustr *filename, *unifilename;
 	int len = 0;
@@ -347,7 +348,7 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname,
 	if (!unifilename)
 		goto out1;
 
-	if (udf_build_ustr_exact(unifilename, sname, flen))
+	if (udf_build_ustr_exact(unifilename, sname, slen))
 		goto out2;
 
 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) {
@@ -366,7 +367,8 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname,
 	} else
 		goto out2;
 
-	len = udf_translate_to_linux(dname, filename->u_name, filename->u_len,
+	len = udf_translate_to_linux(dname, dlen,
+				     filename->u_name, filename->u_len,
 				     unifilename->u_name, unifilename->u_len);
 out2:
 	kfree(unifilename);
@@ -403,10 +405,12 @@ int udf_put_filename(struct super_block *sb, const uint8_t *sname,
 #define EXT_MARK		'.'
 #define CRC_MARK		'#'
 #define EXT_SIZE 		5
+/* Number of chars we need to store generated CRC to make filename unique */
+#define CRC_LEN			5
 
-static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName,
-				  int udfLen, uint8_t *fidName,
-				  int fidNameLen)
+static int udf_translate_to_linux(uint8_t *newName, int newLen,
+				  uint8_t *udfName, int udfLen,
+				  uint8_t *fidName, int fidNameLen)
 {
 	int index, newIndex = 0, needsCRC = 0;
 	int extIndex = 0, newExtIndex = 0, hasExt = 0;
@@ -440,7 +444,7 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName,
 					newExtIndex = newIndex;
 				}
 			}
-			if (newIndex < 256)
+			if (newIndex < newLen)
 				newName[newIndex++] = curr;
 			else
 				needsCRC = 1;
@@ -468,13 +472,13 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName,
 				}
 				ext[localExtIndex++] = curr;
 			}
-			maxFilenameLen = 250 - localExtIndex;
+			maxFilenameLen = newLen - CRC_LEN - localExtIndex;
 			if (newIndex > maxFilenameLen)
 				newIndex = maxFilenameLen;
 			else
 				newIndex = newExtIndex;
-		} else if (newIndex > 250)
-			newIndex = 250;
+		} else if (newIndex > newLen - CRC_LEN)
+			newIndex = newLen - CRC_LEN;
 		newName[newIndex++] = CRC_MARK;
 		valueCRC = crc_itu_t(0, fidName, fidNameLen);
 		newName[newIndex++] = hexChar[(valueCRC & 0xf000) >> 12];
Signature · 1 line
1.9.1
#79 lore raw

PATCH 74/176 x86_64, vdso: Fix the vdso address randomization algorithm

In reply to [email protected]

From: Andy Lutomirski <[email protected]>

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

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

commit 394f56fe480140877304d342dec46d50dc823d46 upstream.

The theory behind vdso randomization is that it's mapped at a random offset above the top of the stack. To avoid wasting a page of memory for an extra page table, the vdso isn't supposed to extend past the lowest PMD into which it can fit. Other than that, the address should be a uniformly distributed address that meets all of the alignment requirements.

The current algorithm is buggy: the vdso has about a 50% probability of being at the very end of a PMD. The current algorithm also has a decent chance of failing outright due to incorrect handling of the case where the top of the stack is near the top of its PMD.

This fixes the implementation. The paxtest estimate of vdso "randomisation" improves from 11 bits to 18 bits. (Disclaimer: I don't know what the paxtest code is actually calculating.)

It's worth noting that this algorithm is inherently biased: the vdso is more likely to end up near the end of its PMD than near the beginning. Ideally we would either nix the PMD sharing requirement or jointly randomize the vdso and the stack to reduce the bias.

In the mean time, this is a considerable improvement with basically no risk of compatibility issues, since the allowed outputs of the algorithm are unchanged.

As an easy test, doing this:

for i in seq 10000
do grep -P vdso /proc/self/maps |cut -d- -f1
done |sort |uniq -d

used to produce lots of output (1445 lines on my most recent run). A tiny subset looks like this:

7fffdfffe000
7fffe01fe000
7fffe05fe000
7fffe07fe000
7fffe09fe000
7fffe0bfe000
7fffe0dfe000

Note the suspicious fe000 endings. With the fix, I get a much more palatable 76 repeated addresses.

[lizf: Backported to 3.4:
- adjust context
- adjust comment]

---
 arch/x86/vdso/vma.c | 36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)
arch/x86/vdso/vma.c +26 -10
index 00aaf04..47aa108 100644
@@ -117,23 +117,39 @@ subsys_initcall(init_vdso);
 
 struct linux_binprm;
 
-/* Put the vdso above the (randomized) stack with another randomized offset.
-   This way there is no hole in the middle of address space.
-   To save memory make sure it is still in the same PTE as the stack top.
-   This doesn't give that many random bits */
+/*
+ * Put the vdso above the (randomized) stack with another randomized
+ * offset.  This way there is no hole in the middle of address space.
+ * To save memory make sure it is still in the same PTE as the stack
+ * top.  This doesn't give that many random bits.
+ *
+ * Note that this algorithm is imperfect: the distribution of the vdso
+ * start address within a PMD is biased toward the end.
+ *
+ */
 static unsigned long vdso_addr(unsigned long start, unsigned len)
 {
 	unsigned long addr, end;
 	unsigned offset;
-	end = (start + PMD_SIZE - 1) & PMD_MASK;
+
+	/*
+	 * Round up the start address.  It can start out unaligned as a result
+	 * of stack start randomization.
+	 */
+	start = PAGE_ALIGN(start);
+
+	/* Round the lowest possible end address up to a PMD boundary. */
+	end = (start + len + PMD_SIZE - 1) & PMD_MASK;
 	if (end >= TASK_SIZE_MAX)
 		end = TASK_SIZE_MAX;
 	end -= len;
-	/* This loses some more bits than a modulo, but is cheaper */
-	offset = get_random_int() & (PTRS_PER_PTE - 1);
-	addr = start + (offset << PAGE_SHIFT);
-	if (addr >= end)
-		addr = end;
+
+	if (end > start) {
+		offset = get_random_int() % (((end - start) >> PAGE_SHIFT) + 1);
+		addr = start + (offset << PAGE_SHIFT);
+	} else {
+		addr = start;
+	}
 
 	/*
 	 * page-align it here so that get_unmapped_area doesn't
Signature · 1 line
1.9.1
#80 lore raw

PATCH 75/176 udf: Check component length before reading it

In reply to [email protected]

From: Jan Kara <[email protected]>

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

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

commit e237ec37ec154564f8690c5bd1795339955eeef9 upstream.

Check that length specified in a component of a symlink fits in the input buffer we are reading. Also properly ignore component length for component types that do not use it. Otherwise we read memory after end of buffer for corrupted udf image.

---
 fs/udf/symlink.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
fs/udf/symlink.c +7 -2
index 2d0c372..0422b7b 100644
@@ -42,14 +42,17 @@ static int udf_pc_to_char(struct super_block *sb, unsigned char *from,
 	tolen--;
 	while (elen < fromlen) {
 		pc = (struct pathComponent *)(from + elen);
+		elen += sizeof(struct pathComponent);
 		switch (pc->componentType) {
 		case 1:
 			/*
 			 * Symlink points to some place which should be agreed
  			 * upon between originator and receiver of the media. Ignore.
 			 */
-			if (pc->lengthComponentIdent > 0)
+			if (pc->lengthComponentIdent > 0) {
+				elen += pc->lengthComponentIdent;
 				break;
+			}
 			/* Fall through */
 		case 2:
 			if (tolen == 0)
@@ -74,6 +77,9 @@ static int udf_pc_to_char(struct super_block *sb, unsigned char *from,
 			/* that would be . - just ignore */
 			break;
 		case 5:
+			elen += pc->lengthComponentIdent;
+			if (elen > fromlen)
+				return -EIO;
 			comp_len = udf_get_filename(sb, pc->componentIdent,
 						    pc->lengthComponentIdent,
 						    p, tolen);
@@ -85,7 +91,6 @@ static int udf_pc_to_char(struct super_block *sb, unsigned char *from,
 			tolen--;
 			break;
 		}
-		elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;
 	}
 	if (p > to + 1)
 		p[-1] = '\0';
Signature · 1 line
1.9.1
#81 lore raw

PATCH 76/176 crypto: af_alg - fix backlog handling

In reply to [email protected]

From: Rabin Vincent <[email protected]>

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

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

commit 7e77bdebff5cb1e9876c561f69710b9ab8fa1f7e upstream.

If a request is backlogged, it's complete() handler will get called
twice: once with -EINPROGRESS, and once with the final error code.

af_alg's complete handler, unlike other users, does not handle the -EINPROGRESS but instead always completes the completion that recvmsg() is waiting on. This can lead to a return to user space while the request is still pending in the driver. If userspace closes the sockets before the requests are handled by the driver, this will lead to use-after-frees (and potential crashes) in the kernel due to the tfm having been freed.

The crashes can be easily reproduced (for example) by reducing the max queue length in cryptod.c and running the following (from
http://www.chronox.de/libkcapi.html) on AES-NI capable hardware:

 $ while true; do kcapi -x 1 -e -c '__ecb-aes-aesni' \
    -k 00000000000000000000000000000000 \
    -p 00000000000000000000000000000000 >/dev/null & done
---
 crypto/af_alg.c | 3 +++
 1 file changed, 3 insertions(+)
crypto/af_alg.c +3 -0
index bf948e1..6ef6e2a 100644
@@ -449,6 +449,9 @@ void af_alg_complete(struct crypto_async_request *req, int err)
 {
 	struct af_alg_completion *completion = req->data;
 
+	if (err == -EINPROGRESS)
+		return;
+
 	completion->err = err;
 	complete(&completion->completion);
 }
Signature · 1 line
1.9.1
#82 lore raw

PATCH 77/176 net: Fix stacked vlan offload features computation

In reply to [email protected]

From: Toshiaki Makita <[email protected]>

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

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

commit 796f2da81bead71ffc91ef70912cd8d1827bf756 upstream.

When vlan tags are stacked, it is very likely that the outer tag is stored in skb->vlan_tci and skb->protocol shows the inner tag's vlan_proto. Currently netif_skb_features() first looks at skb->protocol even if there is the outer tag in vlan_tci, thus it incorrectly retrieves the protocol encapsulated by the inner vlan instead of the inner vlan protocol. This allows GSO packets to be passed to HW and they end up being corrupted.

Fixes 58e998c6d239 ("offloading: Force software GSO for multiple vlan tags.")

[lizf: Backported to 3.4:
- remove ETH_P_8021AD
- pass protocol to harmonize_features()]

---
 net/core/dev.c | 8 ++++++++
 1 file changed, 8 insertions(+)
net/core/dev.c +8 -0
index 0770364..f783dd3 100644
@@ -2149,6 +2149,14 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
 	} else if (!vlan_tx_tag_present(skb)) {
 		return harmonize_features(skb, protocol, features);
 	}
+	if (!vlan_tx_tag_present(skb)) {
+		if (unlikely(protocol == htons(ETH_P_8021Q))) {
+			struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
+			protocol = veh->h_vlan_encapsulated_proto;
+		} else {
+			return harmonize_features(skb, protocol, features);
+		}
+        }
 
 	features &= (skb->dev->vlan_features | NETIF_F_HW_VLAN_TX);
 
Signature · 1 line
1.9.1
#83 lore raw

Re: [PATCH 3.4 077/176] net: Fix stacked vlan offload features computation

Quoted 34 lines · On 2015/04/09 17:45, [email protected] wrote:

From: Toshiaki Makita <[email protected]>

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

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

commit 796f2da81bead71ffc91ef70912cd8d1827bf756 upstream.

When vlan tags are stacked, it is very likely that the outer tag is stored in skb->vlan_tci and skb->protocol shows the inner tag's vlan_proto. Currently netif_skb_features() first looks at skb->protocol even if there is the outer tag in vlan_tci, thus it incorrectly retrieves the protocol encapsulated by the inner vlan instead of the inner vlan protocol. This allows GSO packets to be passed to HW and they end up being corrupted.

Fixes 58e998c6d239 ("offloading: Force software GSO for multiple vlan tags.")

[lizf: Backported to 3.4:
- remove ETH_P_8021AD
- pass protocol to harmonize_features()]

---
 net/core/dev.c | 8 ++++++++
 1 file changed, 8 insertions(+)
net/core/dev.c +0 -0
index 0770364..f783dd3 100644
@@ -2149,6 +2149,14 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
 	} else if (!vlan_tx_tag_present(skb)) {

net/core/dev.c netdev_features_t netif_skb_features(struct sk_buff *skb) · line 2159

Quoted 10 lines
net/core/dev.c +8 -0
 		return harmonize_features(skb, protocol, features);
 	}
+	if (!vlan_tx_tag_present(skb)) {
+		if (unlikely(protocol == htons(ETH_P_8021Q))) {
+			struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
+			protocol = veh->h_vlan_encapsulated_proto;
+		} else {
+			return harmonize_features(skb, protocol, features);
+		}
+        }

This does not look like a correct fix.
We need to replace the existing check rather than add a new check, like this:
https://lkml.org/lkml/2015/2/16/649

Thanks,
Toshiaki Makita

#84 lore raw

Re: [PATCH 3.4 077/176] net: Fix stacked vlan offload features computation

Quoted 13 lines
Quoted 13 lines
net/core/dev.c +5 -0
index 0770364..f783dd3 100644
@@ -2149,6 +2149,14 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
 	} else if (!vlan_tx_tag_present(skb)) {
 		return harmonize_features(skb, protocol, features);
 	}
+	if (!vlan_tx_tag_present(skb)) {
+		if (unlikely(protocol == htons(ETH_P_8021Q))) {
+			struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
+			protocol = veh->h_vlan_encapsulated_proto;
+		} else {
Quoted 8 lines

net/core/dev.c netdev_features_t netif_skb_features(struct sk_buff *skb) · line 2159

Quoted 3 lines
net/core/dev.c +3 -0
+			return harmonize_features(skb, protocol, features);
+		}
+        }

This does not look like a correct fix.
We need to replace the existing check rather than add a new check, like this:
https://lkml.org/lkml/2015/2/16/649

Will fix. Thanks for the review!

#85 lore raw

PATCH 78/176 video/logo: prevent use of logos after they have been freed

In reply to [email protected]

From: Tomi Valkeinen <[email protected]>

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

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

commit 92b004d1aa9f367c372511ca0330f58216b25703 upstream.

If the probe of an fb driver has been deferred due to missing dependencies, and the probe is later ran when a module is loaded, the fbdev framework will try to find a logo to use.

However, the logos are __initdata, and have already been freed. This causes sometimes page faults, if the logo memory is not mapped, sometimes other random crashes as the logo data is invalid, and sometimes nothing, if the fbdev decides to reject the logo (e.g. the random value depicting the logo's height is too big).

This patch adds a late_initcall function to mark the logos as freed. In reality the logos are freed later, and fbdev probe may be ran between this late_initcall and the freeing of the logos. In that case we will miss drawing the logo, even if it would be possible.

---
 drivers/video/logo/logo.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)
drivers/video/logo/logo.c +16 -1
index 080c35b..cc5dbb5 100644
@@ -25,6 +25,21 @@ static bool nologo;
 module_param(nologo, bool, 0);
 MODULE_PARM_DESC(nologo, "Disables startup logo");
 
+/*
+ * Logos are located in the initdata, and will be freed in kernel_init.
+ * Use late_init to mark the logos as freed to prevent any further use.
+ */
+
+static bool logos_freed;
+
+static int __init fb_logo_late_init(void)
+{
+	logos_freed = true;
+	return 0;
+}
+
+late_initcall(fb_logo_late_init);
+
 /* logo's are marked __initdata. Use __init_refok to tell
  * modpost that it is intended that this function uses data
  * marked __initdata.
@@ -33,7 +48,7 @@ const struct linux_logo * __init_refok fb_find_logo(int depth)
 {
 	const struct linux_logo *logo = NULL;
 
-	if (nologo)
+	if (nologo || logos_freed)
 		return NULL;
 
 	if (depth >= 1) {
Signature · 1 line
1.9.1
#86 lore raw

PATCH 79/176 USB: cp210x: fix ID for production CEL MeshConnect USB Stick

In reply to [email protected]

From: Preston Fick <[email protected]>

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

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

commit 90441b4dbe90ba0c38111ea89fa093a8c9627801 upstream.

Fixing typo for MeshConnect IDs. The original PID (0x8875) is not in production and is not needed. Instead it has been changed to the official production PID (0x8857).

---
 drivers/usb/serial/cp210x.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/serial/cp210x.c +1 -1
index f4edbe5..d0c07da 100644
@@ -126,7 +126,7 @@ static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */
 	{ USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */
 	{ USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */
-	{ USB_DEVICE(0x10C4, 0x8875) }, /* CEL MeshConnect USB Stick */
+	{ USB_DEVICE(0x10C4, 0x8857) }, /* CEL MeshConnect USB Stick */
 	{ USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */
 	{ USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */
 	{ USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */
Signature · 1 line
1.9.1
#87 lore raw

PATCH 80/176 x86, um: actually mark system call tables readonly

In reply to [email protected]

From: Daniel Borkmann <[email protected]>

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

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

commit b485342bd79af363c77ef1a421c4a0aef2de9812 upstream.

Commit a074335a370e ("x86, um: Mark system call tables readonly") was supposed to mark the sys_call_table in UML as RO by adding the const, but it doesn't have the desired effect as it's nevertheless being placed into the data section since __cacheline_aligned enforces sys_call_table being placed into .data..cacheline_aligned instead. We need to use the ____cacheline_aligned version instead to fix this issue.

Before:

$ nm -v arch/x86/um/sys_call_table_64.o | grep -1 "sys_call_table"
                 U sys_writev
0000000000000000 D sys_call_table
0000000000000000 D syscall_table_size

After:

$ nm -v arch/x86/um/sys_call_table_64.o | grep -1 "sys_call_table"
                 U sys_writev
0000000000000000 R sys_call_table
0000000000000000 D syscall_table_size
Fixes a074335a370e ("x86, um: Mark system call tables readonly")
Cc H. Peter Anvin <[email protected]>
Cc Andrew Morton <[email protected]>
---
 arch/x86/um/sys_call_table_32.c | 2 +-
 arch/x86/um/sys_call_table_64.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
arch/x86/um/sys_call_table_32.c +1 -1
index 68d1dc9..bd8b159 100644
@@ -43,7 +43,7 @@ typedef asmlinkage void (*sys_call_ptr_t)(void);
 
 extern asmlinkage void sys_ni_syscall(void);
 
-const sys_call_ptr_t sys_call_table[] __cacheline_aligned = {
+const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = {
 	/*
 	 * Smells like a compiler bug -- it doesn't work
 	 * when the & below is removed.
arch/x86/um/sys_call_table_64.c +1 -1
index 9924776..cbdab94 100644
@@ -48,7 +48,7 @@ typedef void (*sys_call_ptr_t)(void);
 
 extern void sys_ni_syscall(void);
 
-const sys_call_ptr_t sys_call_table[] __cacheline_aligned = {
+const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = {
 	/*
 	 * Smells like a compiler bug -- it doesn't work
 	 * when the & below is removed.
Signature · 1 line
1.9.1
#88 lore raw

PATCH 81/176 ALSA: hda - Fix wrong gpio_dir & gpio_mask hint setups for IDT/STAC codecs

In reply to [email protected]

From: Takashi Iwai <[email protected]>

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

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

commit c507de88f6a336bd7296c9ec0073b2d4af8b4f5e upstream.

stac_store_hints() does utterly wrong for masking the values for gpio_dir and gpio_data, likely due to copy&paste errors. Fortunately, this feature is used very rarely, so the impact must be really small.

---
 sound/pci/hda/patch_sigmatel.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
sound/pci/hda/patch_sigmatel.c +2 -2
index 137b67f..606f87a 100644
@@ -4246,9 +4246,9 @@ static void stac_store_hints(struct hda_codec *codec)
 			spec->gpio_mask;
 	}
 	if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir))
-		spec->gpio_mask &= spec->gpio_mask;
-	if (get_int_hint(codec, "gpio_data", &spec->gpio_data))
 		spec->gpio_dir &= spec->gpio_mask;
+	if (get_int_hint(codec, "gpio_data", &spec->gpio_data))
+		spec->gpio_data &= spec->gpio_mask;
 	if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask))
 		spec->eapd_mask &= spec->gpio_mask;
 	if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute))
Signature · 1 line
1.9.1
#89 lore raw

PATCH 82/176 virtio: use dev_to_virtio wrapper in virtio

In reply to [email protected]

From: Wanlong Gao <[email protected]>

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

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

commit 9bffdca8c64a72ac54c47a552734ab457bc720d4 upstream.

Use dev_to_virtio wrapper in virtio to make code clearly.

---
 drivers/virtio/virtio.c | 19 +++++++++----------
 include/linux/virtio.h  |  6 +++++-
 2 files changed, 14 insertions(+), 11 deletions(-)
drivers/virtio/virtio.c +9 -10
index 984c501..cc02a9b 100644
@@ -9,33 +9,32 @@ static unsigned int dev_index;
 static ssize_t device_show(struct device *_d,
 			   struct device_attribute *attr, char *buf)
 {
-	struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
+	struct virtio_device *dev = dev_to_virtio(_d);
 	return sprintf(buf, "0x%04x\n", dev->id.device);
 }
 static ssize_t vendor_show(struct device *_d,
 			   struct device_attribute *attr, char *buf)
 {
-	struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
+	struct virtio_device *dev = dev_to_virtio(_d);
 	return sprintf(buf, "0x%04x\n", dev->id.vendor);
 }
 static ssize_t status_show(struct device *_d,
 			   struct device_attribute *attr, char *buf)
 {
-	struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
+	struct virtio_device *dev = dev_to_virtio(_d);
 	return sprintf(buf, "0x%08x\n", dev->config->get_status(dev));
 }
 static ssize_t modalias_show(struct device *_d,
 			     struct device_attribute *attr, char *buf)
 {
-	struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
-
+	struct virtio_device *dev = dev_to_virtio(_d);
 	return sprintf(buf, "virtio:d%08Xv%08X\n",
 		       dev->id.device, dev->id.vendor);
 }
 static ssize_t features_show(struct device *_d,
 			     struct device_attribute *attr, char *buf)
 {
-	struct virtio_device *dev = container_of(_d, struct virtio_device, dev);
+	struct virtio_device *dev = dev_to_virtio(_d);
 	unsigned int i;
 	ssize_t len = 0;
 
@@ -70,7 +69,7 @@ static inline int virtio_id_match(const struct virtio_device *dev,
 static int virtio_dev_match(struct device *_dv, struct device_driver *_dr)
 {
 	unsigned int i;
-	struct virtio_device *dev = container_of(_dv,struct virtio_device,dev);
+	struct virtio_device *dev = dev_to_virtio(_dv);
 	const struct virtio_device_id *ids;
 
 	ids = container_of(_dr, struct virtio_driver, driver)->id_table;
@@ -82,7 +81,7 @@ static int virtio_dev_match(struct device *_dv, struct device_driver *_dr)
 
 static int virtio_uevent(struct device *_dv, struct kobj_uevent_env *env)
 {
-	struct virtio_device *dev = container_of(_dv,struct virtio_device,dev);
+	struct virtio_device *dev = dev_to_virtio(_dv);
 
 	return add_uevent_var(env, "MODALIAS=virtio:d%08Xv%08X",
 			      dev->id.device, dev->id.vendor);
@@ -110,7 +109,7 @@ EXPORT_SYMBOL_GPL(virtio_check_driver_offered_feature);
 static int virtio_dev_probe(struct device *_d)
 {
 	int err, i;
-	struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
+	struct virtio_device *dev = dev_to_virtio(_d);
 	struct virtio_driver *drv = container_of(dev->dev.driver,
 						 struct virtio_driver, driver);
 	u32 device_features;
@@ -148,7 +147,7 @@ static int virtio_dev_probe(struct device *_d)
 
 static int virtio_dev_remove(struct device *_d)
 {
-	struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
+	struct virtio_device *dev = dev_to_virtio(_d);
 	struct virtio_driver *drv = container_of(dev->dev.driver,
 						 struct virtio_driver, driver);
 
include/linux/virtio.h +5 -1
index 2b779bf..f73e2c7 100644
@@ -75,7 +75,11 @@ struct virtio_device {
 	void *priv;
 };
 
-#define dev_to_virtio(dev) container_of(dev, struct virtio_device, dev)
+static inline struct virtio_device *dev_to_virtio(struct device *_dev)
+{
+	return container_of(_dev, struct virtio_device, dev);
+}
+
 int register_virtio_device(struct virtio_device *dev);
 void unregister_virtio_device(struct virtio_device *dev);
 
Signature · 1 line
1.9.1
#90 lore raw

PATCH 83/176 virtio_pci: defer kfree until release callback

In reply to [email protected]

From: Sasha Levin <[email protected]>

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

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

commit 63bd62a08ca45a0c804c3c89777edc7f76a2d6da upstream.

A struct device which has just been unregistered can live on past the point at which a driver decides to drop it's initial reference to the kobject gained on allocation.

This implies that when releasing a virtio device, we can't free a struct virtio_device until the underlying struct device has been released, which might not happen immediately on device_unregister().

Unfortunately, this is exactly what virtio pci does:
it has an empty release callback, and frees memory immediately after unregistering the device.

This causes an easy to reproduce crash if CONFIG_DEBUG_KOBJECT_RELEASE it enabled.

To fix, free the memory only once we know the device is gone in the release callback.

[lizf: Backported to 3.4: adjust filename]
---
 drivers/virtio/virtio_pci.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)
drivers/virtio/virtio_pci.c +4 -6
index a41f264..c9c93e0 100644
@@ -624,11 +624,10 @@ static struct virtio_config_ops virtio_pci_config_ops = {
 
 static void virtio_pci_release_dev(struct device *_d)
 {
-	/*
-	 * No need for a release method as we allocate/free
-	 * all devices together with the pci devices.
-	 * Provide an empty one to avoid getting a warning from core.
-	 */
+	struct virtio_device *vdev = dev_to_virtio(_d);
+	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+
+	kfree(vp_dev);
 }
 
 /* the PCI probing function */
@@ -716,7 +715,6 @@ static void __devexit virtio_pci_remove(struct pci_dev *pci_dev)
 	pci_iounmap(pci_dev, vp_dev->ioaddr);
 	pci_release_regions(pci_dev);
 	pci_disable_device(pci_dev);
-	kfree(vp_dev);
 }
 
 #ifdef CONFIG_PM
Signature · 1 line
1.9.1
#91 lore raw

PATCH 84/176 virtio_pci: document why we defer kfree

In reply to [email protected]

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

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

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

commit a1eb03f546d651a8f39c7d0692b1f7f5b4e7e3cd upstream.

The reason we defer kfree until release function is because it's a general rule for kobjects: kfree of the reference counter itself is only legal in the release function.

Previous patch didn't make this clear, document this in code.

[lizf: Backported to 3.4: adjust filename]
---
 drivers/virtio/virtio_pci.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/virtio/virtio_pci.c +3 -0
index c9c93e0..cc56763 100644
@@ -627,6 +627,9 @@ static void virtio_pci_release_dev(struct device *_d)
 	struct virtio_device *vdev = dev_to_virtio(_d);
 	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
 
+	/* As struct device is a kobject, it's not safe to
+	 * free the memory (including the reference counter itself)
+	 * until it's release callback. */
 	kfree(vp_dev);
 }
 
Signature · 1 line
1.9.1
#92 lore raw

PATCH 85/176 USB: cp210x: add IDs for CEL USB sticks and MeshWorks devices

In reply to [email protected]

From: David Peterson <[email protected]>

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

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

commit 1ae78a4870989a354028cb17dabf819b595e70e3 upstream.

Added virtual com port VID/PID entries for CEL USB sticks and MeshWorks devices.

---
 drivers/usb/serial/cp210x.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/usb/serial/cp210x.c +3 -1
index d0c07da..8137937 100644
@@ -126,10 +126,12 @@ static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */
 	{ USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */
 	{ USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */
-	{ USB_DEVICE(0x10C4, 0x8857) }, /* CEL MeshConnect USB Stick */
+	{ USB_DEVICE(0x10C4, 0x8856) },	/* CEL EM357 ZigBee USB Stick - LR */
+	{ USB_DEVICE(0x10C4, 0x8857) },	/* CEL EM357 ZigBee USB Stick */
 	{ USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */
 	{ USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */
 	{ USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */
+	{ USB_DEVICE(0x10C4, 0x8977) },	/* CEL MeshWorks DevKit Device */
 	{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
 	{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
 	{ USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
Signature · 1 line
1.9.1
#93 lore raw

PATCH 86/176 mm: propagate error from stack expansion even for guard page

In reply to [email protected]

From: Linus Torvalds <[email protected]>

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

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

commit fee7e49d45149fba60156f5b59014f764d3e3728 upstream.

Jay Foad reports that the address sanitizer test (asan) sometimes gets confused by a stack pointer that ends up being outside the stack vma that is reported by /proc/maps.

This happens due to an interaction between RLIMIT_STACK and the guard
page: when we do the guard page check, we ignore the potential error from the stack expansion, which effectively results in a missing guard page, since the expected stack expansion won't have been done.

And since /proc/maps explicitly ignores the guard page (commit
d7824370e263: "mm: fix up some user-visible effects of the stack guard page"), the stack pointer ends up being outside the reported stack area.

This is the minimal patch: it just propagates the error. It also effectively makes the guard page part of the stack limit, which in turn measn that the actual real stack is one page less than the stack limit.

Let's see if anybody notices. We could teach acct_stack_growth() to allow an extra page for a grow-up/grow-down stack in the rlimit test, but I don't want to add more complexity if it isn't needed.

---
 include/linux/mm.h | 2 +-
 mm/memory.c        | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)
include/linux/mm.h +1 -1
index 656b4e9..dacfd4a 100644
@@ -1456,7 +1456,7 @@ extern int expand_downwards(struct vm_area_struct *vma,
 #if VM_GROWSUP
 extern int expand_upwards(struct vm_area_struct *vma, unsigned long address);
 #else
-  #define expand_upwards(vma, address) do { } while (0)
+  #define expand_upwards(vma, address) (0)
 #endif
 
 /* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
mm/memory.c +2 -2
index 60ead07..4d1acc4 100644
@@ -3137,7 +3137,7 @@ static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned lo
 		if (prev && prev->vm_end == address)
 			return prev->vm_flags & VM_GROWSDOWN ? 0 : -ENOMEM;
 
-		expand_downwards(vma, address - PAGE_SIZE);
+		return expand_downwards(vma, address - PAGE_SIZE);
 	}
 	if ((vma->vm_flags & VM_GROWSUP) && address + PAGE_SIZE == vma->vm_end) {
 		struct vm_area_struct *next = vma->vm_next;
@@ -3146,7 +3146,7 @@ static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned lo
 		if (next && next->vm_start == address + PAGE_SIZE)
 			return next->vm_flags & VM_GROWSUP ? 0 : -ENOMEM;
 
-		expand_upwards(vma, address + PAGE_SIZE);
+		return expand_upwards(vma, address + PAGE_SIZE);
 	}
 	return 0;
 }
Signature · 1 line
1.9.1
#94 lore raw

PATCH 87/176 sata_dwc_460ex: fix resource leak on error path

In reply to [email protected]

From: Andy Shevchenko <[email protected]>

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

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

commit 4aaa71873ddb9faf4b0c4826579e2f6d18ff9ab4 upstream.

DMA mapped IO should be unmapped on the error path in probe() and unconditionally on remove().

Fixes 62936009f35a ([libata] Add 460EX on-chip SATA driver, sata_dwc_460ex)
---
 drivers/ata/sata_dwc_460ex.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)
drivers/ata/sata_dwc_460ex.c +12 -14
index 69f7cde..9d6eb14 100644
@@ -791,7 +791,7 @@ static int dma_dwc_init(struct sata_dwc_device *hsdev, int irq)
 	if (err) {
 		dev_err(host_pvt.dwc_dev, "%s: dma_request_interrupts returns"
 			" %d\n", __func__, err);
-		goto error_out;
+		return err;
 	}
 
 	/* Enabe DMA */
@@ -802,11 +802,6 @@ static int dma_dwc_init(struct sata_dwc_device *hsdev, int irq)
 		sata_dma_regs);
 
 	return 0;
-
-error_out:
-	dma_dwc_exit(hsdev);
-
-	return err;
 }
 
 static int sata_dwc_scr_read(struct ata_link *link, unsigned int scr, u32 *val)
@@ -1634,7 +1629,7 @@ static int sata_dwc_probe(struct platform_device *ofdev)
 	char *ver = (char *)&versionr;
 	u8 *base = NULL;
 	int err = 0;
-	int irq, rc;
+	int irq;
 	struct ata_host *host;
 	struct ata_port_info pi = sata_dwc_port_info[0];
 	const struct ata_port_info *ppi[] = { &pi, NULL };
@@ -1688,7 +1683,7 @@ static int sata_dwc_probe(struct platform_device *ofdev)
 	if (irq == NO_IRQ) {
 		dev_err(&ofdev->dev, "no SATA DMA irq\n");
 		err = -ENODEV;
-		goto error_out;
+		goto error_iomap;
 	}
 
 	/* Get physical SATA DMA register base address */
@@ -1697,14 +1692,16 @@ static int sata_dwc_probe(struct platform_device *ofdev)
 		dev_err(&ofdev->dev, "ioremap failed for AHBDMA register"
 			" address\n");
 		err = -ENODEV;
-		goto error_out;
+		goto error_iomap;
 	}
 
 	/* Save dev for later use in dev_xxx() routines */
 	host_pvt.dwc_dev = &ofdev->dev;
 
 	/* Initialize AHB DMAC */
-	dma_dwc_init(hsdev, irq);
+	err = dma_dwc_init(hsdev, irq);
+	if (err)
+		goto error_dma_iomap;
 
 	/* Enable SATA Interrupts */
 	sata_dwc_enable_interrupts(hsdev);
@@ -1722,9 +1719,8 @@ static int sata_dwc_probe(struct platform_device *ofdev)
 	 * device discovery process, invoking our port_start() handler &
 	 * error_handler() to execute a dummy Softreset EH session
 	 */
-	rc = ata_host_activate(host, irq, sata_dwc_isr, 0, &sata_dwc_sht);
-
-	if (rc != 0)
+	err = ata_host_activate(host, irq, sata_dwc_isr, 0, &sata_dwc_sht);
+	if (err)
 		dev_err(&ofdev->dev, "failed to activate host");
 
 	dev_set_drvdata(&ofdev->dev, host);
@@ -1733,7 +1729,8 @@ static int sata_dwc_probe(struct platform_device *ofdev)
 error_out:
 	/* Free SATA DMA resources */
 	dma_dwc_exit(hsdev);
-
+error_dma_iomap:
+	iounmap((void __iomem *)host_pvt.sata_dma_regs);
 error_iomap:
 	iounmap(base);
 error_kmalloc:
@@ -1754,6 +1751,7 @@ static int sata_dwc_remove(struct platform_device *ofdev)
 	/* Free SATA DMA resources */
 	dma_dwc_exit(hsdev);
 
+	iounmap((void __iomem *)host_pvt.sata_dma_regs);
 	iounmap(hsdev->reg_base);
 	kfree(hsdev);
 	kfree(host);
Signature · 1 line
1.9.1
#95 lore raw

PATCH 88/176 time: settimeofday: Validate the values of tv from user

In reply to [email protected]

From: Sasha Levin <[email protected]>

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

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

commit 6ada1fc0e1c4775de0e043e1bd3ae9d065491aa5 upstream.

An unvalidated user input is multiplied by a constant, which can result in an undefined behaviour for large values. While this is validated later, we should avoid triggering undefined behaviour.

Cc Thomas Gleixner <[email protected]>
Cc Ingo Molnar <[email protected]>

[jstultz: include trivial milisecond->microsecond correction noticed by Andy]

[lizf: Backported to 3.4: adjust filename]
---
 include/linux/time.h | 13 +++++++++++++
 kernel/time.c        |  4 ++++
 2 files changed, 17 insertions(+)
include/linux/time.h +13 -0
index 03dce74..bf1bb61 100644
@@ -189,6 +189,19 @@ extern void getboottime(struct timespec *ts);
 extern void monotonic_to_bootbased(struct timespec *ts);
 extern void get_monotonic_boottime(struct timespec *ts);
 
+static inline bool timeval_valid(const struct timeval *tv)
+{
+	/* Dates before 1970 are bogus */
+	if (tv->tv_sec < 0)
+		return false;
+
+	/* Can't have more microseconds then a second */
+	if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC)
+		return false;
+
+	return true;
+}
+
 extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
 extern int timekeeping_valid_for_hres(void);
 extern u64 timekeeping_max_deferment(void);
kernel/time.c +4 -0
index a095290..0864d70 100644
@@ -186,6 +186,10 @@ SYSCALL_DEFINE2(settimeofday, struct timeval __user *, tv,
 	if (tv) {
 		if (copy_from_user(&user_tv, tv, sizeof(*tv)))
 			return -EFAULT;
+
+		if (!timeval_valid(&user_tv))
+			return -EINVAL;
+
 		new_ts.tv_sec = user_tv.tv_sec;
 		new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC;
 	}
Signature · 1 line
1.9.1
#96 lore raw

PATCH 89/176 time: adjtimex: Validate the ADJ_FREQUENCY values

In reply to [email protected]

From: Sasha Levin <[email protected]>

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

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

commit 5e5aeb4367b450a28f447f6d5ab57d8f2ab16a5f upstream.

Verify that the frequency value from userspace is valid and makes sense.

Unverified values can cause overflows later on.

Cc Thomas Gleixner <[email protected]>
Cc Ingo Molnar <[email protected]>
[jstultz: Fix up bug for negative values and drop redunent cap check]
[lizf: Backported to 3.4: adjust context]
---
 kernel/time/ntp.c | 7 +++++++
 1 file changed, 7 insertions(+)
kernel/time/ntp.c +7 -0
index 8b70710..7666b24 100644
@@ -660,6 +660,13 @@ int do_adjtimex(struct timex *txc)
 			return result;
 	}
 
+	if (txc->modes & ADJ_FREQUENCY) {
+		if (LONG_MIN / PPM_SCALE > txc->freq)
+			return -EINVAL;
+		if (LONG_MAX / PPM_SCALE < txc->freq)
+			return -EINVAL;
+	}
+
 	getnstimeofday(&ts);
 
 	spin_lock_irq(&ntp_lock);
Signature · 1 line
1.9.1
#97 lore raw

PATCH 90/176 Input: i8042 - reset keyboard to fix Elantech touchpad detection

In reply to [email protected]

From: Srihari Vijayaraghavan <[email protected]>

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

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

commit 148e9a711e034e06310a8c36b64957934ebe30f2 upstream.

On some laptops, keyboard needs to be reset in order to successfully detect touchpad (e.g., some Gigabyte laptop models with Elantech touchpads). Without resettin keyboard touchpad pretends to be completely dead.

Based on the original patch by Mateusz Jończyk this version has been expanded to include DMI based detection & application of the fix automatically on the affected models of laptops. This has been confirmed to fix problem by three users already on three different models of laptops.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=81331

Tested by: Zakariya Dehlawi <[email protected]>

---
 Documentation/kernel-parameters.txt   |  1 +
 drivers/input/serio/i8042-x86ia64io.h | 32 ++++++++++++++++++++++++++++++++
 drivers/input/serio/i8042.c           | 14 ++++++++++++++
 3 files changed, 47 insertions(+)
Documentation/kernel-parameters.txt +1 -0
index 63740da..c7523c4 100644
@@ -979,6 +979,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 	i8042.notimeout	[HW] Ignore timeout condition signalled by controller
 	i8042.reset	[HW] Reset the controller during init and cleanup
 	i8042.unlock	[HW] Unlock (ignore) the keylock
+	i8042.kbdreset  [HW] Reset device connected to KBD port
 
 	i810=		[HW,DRM]
 
drivers/input/serio/i8042-x86ia64io.h +32 -0
index ce715b1..f41d199 100644
@@ -721,6 +721,35 @@ static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = {
 	{ }
 };
 
+/*
+ * Some laptops need keyboard reset before probing for the trackpad to get
+ * it detected, initialised & finally work.
+ */
+static const struct dmi_system_id __initconst i8042_dmi_kbdreset_table[] = {
+	{
+		/* Gigabyte P35 v2 - Elantech touchpad */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "P35V2"),
+		},
+	},
+		{
+		/* Aorus branded Gigabyte X3 Plus - Elantech touchpad */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "X3"),
+		},
+	},
+	{
+		/* Gigabyte P34 - Elantech touchpad */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "P34"),
+		},
+	},
+	{ }
+};
+
 #endif /* CONFIG_X86 */
 
 #ifdef CONFIG_PNP
@@ -1001,6 +1030,9 @@ static int __init i8042_platform_init(void)
 	if (dmi_check_system(i8042_dmi_dritek_table))
 		i8042_dritek = true;
 
+	if (dmi_check_system(i8042_dmi_kbdreset_table))
+		i8042_kbdreset = true;
+
 	/*
 	 * A20 was already enabled during early kernel init. But some buggy
 	 * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to
drivers/input/serio/i8042.c +14 -0
index 8656441..178e75d 100644
@@ -67,6 +67,10 @@ static bool i8042_notimeout;
 module_param_named(notimeout, i8042_notimeout, bool, 0);
 MODULE_PARM_DESC(notimeout, "Ignore timeouts signalled by i8042");
 
+static bool i8042_kbdreset;
+module_param_named(kbdreset, i8042_kbdreset, bool, 0);
+MODULE_PARM_DESC(kbdreset, "Reset device connected to KBD port");
+
 #ifdef CONFIG_X86
 static bool i8042_dritek;
 module_param_named(dritek, i8042_dritek, bool, 0);
@@ -783,6 +787,16 @@ static int __init i8042_check_aux(void)
 		return -1;
 
 /*
+ * Reset keyboard (needed on some laptops to successfully detect
+ * touchpad, e.g., some Gigabyte laptop models with Elantech
+ * touchpads).
+ */
+	if (i8042_kbdreset) {
+		pr_warn("Attempting to reset device connected to KBD port\n");
+		i8042_kbd_write(NULL, (unsigned char) 0xff);
+	}
+
+/*
  * Test AUX IRQ delivery to make sure BIOS did not grab the IRQ and
  * used it for a PCI card or somethig else.
  */
Signature · 1 line
1.9.1
#98 lore raw

PATCH 91/176 Input: I8042 - add Acer Aspire 7738 to the nomux list

In reply to [email protected]

From: Dmitry Torokhov <[email protected]>

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

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

commit 9333caeaeae4f831054e0e127a6ed3948b604d3e upstream.

When KBC is in active multiplexing mode the touchpad on this laptop does not work.

---
 drivers/input/serio/i8042-x86ia64io.h | 7 +++++++
 1 file changed, 7 insertions(+)
drivers/input/serio/i8042-x86ia64io.h +7 -0
index f41d199..78227f3 100644
@@ -408,6 +408,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
 		},
 	},
 	{
+		/* Acer Aspire 7738 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7738"),
+		},
+	},
+	{
 		/* Gericom Bellagio */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Gericom"),
Signature · 1 line
1.9.1
#99 lore raw

PATCH 92/176 mac80211: fix multicast LED blinking and counter

In reply to [email protected]

From: Andreas Müller <[email protected]>

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

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

commit d025933e29872cb1fe19fc54d80e4dfa4ee5779c upstream.

As multicast-frames can't be fragmented, "dot11MulticastReceivedFrameCount" stopped being incremented after the use-after-free fix. Furthermore, the RX-LED will be triggered by every multicast frame (which wouldn't happen before) which wouldn't allow the LED to rest at all.

Fixes https://bugzilla.kernel.org/show_bug.cgi?id=89431 which also had the patch.

Fixes b8fff407a180 ("mac80211: fix use-after-free in defragmentation")
[rewrite commit message]
---
 net/mac80211/rx.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
net/mac80211/rx.c +6 -5
index 32929b0..24f2a41 100644
@@ -1486,14 +1486,14 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
 	sc = le16_to_cpu(hdr->seq_ctrl);
 	frag = sc & IEEE80211_SCTL_FRAG;
 
-	if (likely(!ieee80211_has_morefrags(fc) && frag == 0))
-		goto out;
-
 	if (is_multicast_ether_addr(hdr->addr1)) {
 		rx->local->dot11MulticastReceivedFrameCount++;
-		goto out;
+		goto out_no_led;
 	}
 
+	if (likely(!ieee80211_has_morefrags(fc) && frag == 0))
+		goto out;
+
 	I802_DEBUG_INC(rx->local->rx_handlers_fragments);
 
 	if (skb_linearize(rx->skb))
@@ -1584,9 +1584,10 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
 	status->rx_flags |= IEEE80211_RX_FRAGMENTED;
 
  out:
+	ieee80211_led_rx(rx->local);
+ out_no_led:
 	if (rx->sta)
 		rx->sta->rx_packets++;
-	ieee80211_led_rx(rx->local);
 	return RX_CONTINUE;
 }
 
Signature · 1 line
1.9.1
#100 lore raw

PATCH 93/176 mm: prevent endless growth of anon_vma hierarchy

In reply to [email protected]

From: Konstantin Khlebnikov <[email protected]>

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

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

commit 7a3ef208e662f4b63d43a23f61a64a129c525bbc upstream.

Constantly forking task causes unlimited grow of anon_vma chain. Each next child allocates new level of anon_vmas and links vma to all previous levels because pages might be inherited from any level.

This patch adds heuristic which decides to reuse existing anon_vma instead of forking new one. It adds counter anon_vma->degree which counts linked vmas and directly descending anon_vmas and reuses anon_vma if counter is lower than two. As a result each anon_vma has either vma or at least two descending anon_vmas. In such trees half of nodes are leafs with alive vmas, thus count of anon_vmas is no more than two times bigger than count of vmas.

This heuristic reuses anon_vmas as few as possible because each reuse adds false aliasing among vmas and rmap walker ought to scan more ptes when it searches where page is might be mapped.

Fixes 5beb49305251 ("mm: change anon_vma linking to fix multi-process server scalability issue")
[[email protected]: fix typo, per Rik]
[lizf: Backported to 3.4: adjust context]
---
 include/linux/rmap.h | 10 ++++++++++
 mm/rmap.c            | 42 +++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 51 insertions(+), 1 deletion(-)
include/linux/rmap.h +10 -0
index fd07c45..5a6cbf7 100644
@@ -37,6 +37,16 @@ struct anon_vma {
 	atomic_t refcount;
 
 	/*
+	 * Count of child anon_vmas and VMAs which points to this anon_vma.
+	 *
+	 * This counter is used for making decision about reusing anon_vma
+	 * instead of forking new one. See comments in function anon_vma_clone.
+	 */
+	unsigned degree;
+
+	struct anon_vma *parent;	/* Parent of this anon_vma */
+
+	/*
 	 * NOTE: the LSB of the head.next is set by
 	 * mm_take_all_locks() _after_ taking the above lock. So the
 	 * head must only be read/written after taking the above lock
mm/rmap.c +41 -1

108 lines not on this page · raw message

Signature · 1 line
1.9.1
#101 lore raw

PATCH 94/176 mm: protect set_page_dirty() from ongoing truncation

In reply to [email protected]

From: Johannes Weiner <[email protected]>

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

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

commit 2d6d7f98284648c5ed113fe22a132148950b140f upstream.

Tejun, while reviewing the code, spotted the following race condition between the dirtying and truncation of a page:

__set_page_dirty_nobuffers() __delete_from_page_cache()
if (TestSetPageDirty(page))

                                     page->mapping = NULL
				     if (PageDirty())
				       dec_zone_page_state(page, NR_FILE_DIRTY);
				       dec_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE);
    if (page->mapping)
      account_page_dirtied(page)
        __inc_zone_page_state(page, NR_FILE_DIRTY);
	__inc_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE);

which results in an imbalance of NR_FILE_DIRTY and BDI_RECLAIMABLE.

Dirtiers usually lock out truncation, either by holding the page lock directly, or in case of zap_pte_range(), by pinning the mapcount with the page table lock held. The notable exception to this rule, though, is do_wp_page(), for which this race exists. However, do_wp_page() already waits for a locked page to unlock before setting the dirty bit, in order to prevent a race where clear_page_dirty() misses the page bit in the presence of dirty ptes. Upgrade that wait to a fully locked set_page_dirty() to also cover the situation explained above.

Afterwards, the code in set_page_dirty() dealing with a truncation race is no longer needed. Remove it.

[lizf: Backported to 3.4:
- adjust context
- use VM_BUG_ON() instead of VM_BUG_ON_PAGE()]

---
 include/linux/writeback.h |  1 -
 mm/memory.c               | 27 +++++++++++++++++----------
 mm/page-writeback.c       | 43 ++++++++++++-------------------------------
 3 files changed, 29 insertions(+), 42 deletions(-)
include/linux/writeback.h +0 -1
index a2b84f5..dd8d491 100644
@@ -186,7 +186,6 @@ int write_cache_pages(struct address_space *mapping,
 		      struct writeback_control *wbc, writepage_t writepage,
 		      void *data);
 int do_writepages(struct address_space *mapping, struct writeback_control *wbc);
-void set_page_dirty_balance(struct page *page, int page_mkwrite);
 void writeback_set_ratelimit(void);
 void tag_pages_for_writeback(struct address_space *mapping,
 			     pgoff_t start, pgoff_t end);
mm/memory.c +17 -10
index 4d1acc4..c9c93e2 100644
@@ -2681,18 +2681,25 @@ reuse:
 		if (!dirty_page)
 			return ret;
 
-		/*
-		 * Yes, Virginia, this is actually required to prevent a race
-		 * with clear_page_dirty_for_io() from clearing the page dirty
-		 * bit after it clear all dirty ptes, but before a racing
-		 * do_wp_page installs a dirty pte.
-		 *
-		 * __do_fault is protected similarly.
-		 */
 		if (!page_mkwrite) {
-			wait_on_page_locked(dirty_page);
-			set_page_dirty_balance(dirty_page, page_mkwrite);
+			struct address_space *mapping;
+			int dirtied;
+
+			lock_page(dirty_page);
+			dirtied = set_page_dirty(dirty_page);
+			VM_BUG_ON(dirty_page);
+			mapping = dirty_page->mapping;
+			unlock_page(dirty_page);
+
+			if (dirtied && mapping) {
+				/*
+				 * Some device drivers do not set page.mapping
+				 * but still dirty their pages
+				 */
+				balance_dirty_pages_ratelimited(mapping);
+			}
 		}
+
 		put_page(dirty_page);
 		if (page_mkwrite) {
 			struct address_space *mapping = dirty_page->mapping;
mm/page-writeback.c +12 -31

72 lines not on this page · raw message

Signature · 1 line
1.9.1
#102 lore raw

PATCH 95/176 HID: roccat: potential out of bounds in pyra_sysfs_write_settings()

In reply to [email protected]

From: Dan Carpenter <[email protected]>

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

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

commit 606185b20caf4c57d7e41e5a5ea4aff460aef2ab upstream.

This is a static checker fix. We write some binary settings to the sysfs file. One of the settings is the "->startup_profile". There isn't any checking to make sure it fits into the pyra->profile_settings[] array in the profile_activated() function.

I added a check to pyra_sysfs_write_settings() in both places because I wasn't positive that the other callers were correct.

[lizf: Backported to 3.4: define the variable @settings]
---
 drivers/hid/hid-roccat-pyra.c | 7 +++++++
 1 file changed, 7 insertions(+)
drivers/hid/hid-roccat-pyra.c +7 -0
index df05c1b1..5346647 100644
@@ -35,6 +35,8 @@ static struct class *pyra_class;
 static void profile_activated(struct pyra_device *pyra,
 		unsigned int new_profile)
 {
+	if (new_profile >= ARRAY_SIZE(pyra->profile_settings))
+		return;
 	pyra->actual_profile = new_profile;
 	pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi;
 }
@@ -299,10 +301,15 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp,
 	int retval = 0;
 	int difference;
 	struct pyra_roccat_report roccat_report;
+	struct pyra_settings const *settings;
 
 	if (off != 0 || count != sizeof(struct pyra_settings))
 		return -EINVAL;
 
+	settings = (struct pyra_settings const *)buf;
+	if (settings->startup_profile >= ARRAY_SIZE(pyra->profile_settings))
+		return -EINVAL;
+
 	mutex_lock(&pyra->pyra_lock);
 	difference = memcmp(buf, &pyra->settings, sizeof(struct pyra_settings));
 	if (difference) {
Signature · 1 line
1.9.1
#103 lore raw

PATCH 96/176 OHCI: add a quirk for ULi M5237 blocking on reset

In reply to [email protected]

From: Arseny Solokha <[email protected]>

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

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

commit 56abcab833fafcfaeb2f5b25e0364c1dec45f53e upstream.

Commit 8dccddbc2368 ("OHCI: final fix for NVIDIA problems (I hope)") introduced into 3.1.9 broke boot on e.g. Freescale P2020DS development board. The code path that was previously specific to NVIDIA controllers had then become taken for all chips.

However, the M5237 installed on the board wedges solid when accessing its base+OHCI_FMINTERVAL register, making it impossible to boot any kernel newer than 3.1.8 on this particular and apparently other similar machines.

Don't readl() and writel() base+OHCI_FMINTERVAL on PCI ID 10b9:5237.

The patch is suitable for the -next tree as well as all maintained kernels up to 3.2 inclusive.

---
 drivers/usb/host/pci-quirks.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)
drivers/usb/host/pci-quirks.c +15 -3
index 90dcf54..1f230ed 100644
@@ -470,7 +470,8 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
 {
 	void __iomem *base;
 	u32 control;
-	u32 fminterval;
+	u32 fminterval = 0;
+	bool no_fminterval = false;
 	int cnt;
 
 	if (!mmio_resource_enabled(pdev, 0))
@@ -480,6 +481,13 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
 	if (base == NULL)
 		return;
 
+	/*
+	 * ULi M5237 OHCI controller locks the whole system when accessing
+	 * the OHCI_FMINTERVAL offset.
+	 */
+	if (pdev->vendor == PCI_VENDOR_ID_AL && pdev->device == 0x5237)
+		no_fminterval = true;
+
 	control = readl(base + OHCI_CONTROL);
 
 /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */
@@ -518,7 +526,9 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
 	}
 
 	/* software reset of the controller, preserving HcFmInterval */
-	fminterval = readl(base + OHCI_FMINTERVAL);
+	if (!no_fminterval)
+		fminterval = readl(base + OHCI_FMINTERVAL);
+
 	writel(OHCI_HCR, base + OHCI_CMDSTATUS);
 
 	/* reset requires max 10 us delay */
@@ -527,7 +537,9 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
 			break;
 		udelay(1);
 	}
-	writel(fminterval, base + OHCI_FMINTERVAL);
+
+	if (!no_fminterval)
+		writel(fminterval, base + OHCI_FMINTERVAL);
 
 	/* Now the controller is safely in SUSPEND and nothing can wake it up */
 	iounmap(base);
Signature · 1 line
1.9.1
#104 lore raw

PATCH 97/176 USB: console: fix potential use after free

In reply to [email protected]

From: Johan Hovold <[email protected]>

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

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

commit 32a4bf2e81ec378e5925d4e069e0677a6c86a6ad upstream.

Use tty kref to release the fake tty in usb_console_setup to avoid use after free if the underlying serial driver has acquired a reference.

Note that using the tty destructor release_one_tty requires some more state to be initialised.

Fixes 4a90f09b20f4 ("tty: usb-serial krefs")
[lizf: Backported to 3.4: adjust context]
---
 drivers/usb/serial/console.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/usb/serial/console.c +10 -5
index 1ee6b2a..ae0fa72 100644
@@ -47,6 +47,8 @@ static struct console usbcons;
  * ------------------------------------------------------------
  */
 
+static const struct tty_operations usb_console_fake_tty_ops = {
+};
 
 /*
  * The parsing of the command line works exactly like the
@@ -141,14 +143,17 @@ static int usb_console_setup(struct console *co, char *options)
 				goto reset_open_count;
 			}
 			kref_init(&tty->kref);
-			tty_port_tty_set(&port->port, tty);
 			tty->driver = usb_serial_tty_driver;
 			tty->index = co->index;
+			INIT_LIST_HEAD(&tty->tty_files);
+			kref_get(&tty->driver->kref);
+			tty->ops = &usb_console_fake_tty_ops
 			if (tty_init_termios(tty)) {
 				retval = -ENOMEM;
 				err("no more memory");
-				goto free_tty;
+				goto put_tty;
 			}
+			tty_port_tty_set(&port->port, tty);
 		}
 
 		/* only call the device specific open if this
@@ -170,7 +175,7 @@ static int usb_console_setup(struct console *co, char *options)
 			serial->type->set_termios(tty, port, &dummy);
 
 			tty_port_tty_set(&port->port, NULL);
-			kfree(tty);
+			tty_kref_put(tty);
 		}
 		set_bit(ASYNCB_INITIALIZED, &port->port.flags);
 	}
@@ -186,8 +191,8 @@ static int usb_console_setup(struct console *co, char *options)
 
  fail:
 	tty_port_tty_set(&port->port, NULL);
- free_tty:
-	kfree(tty);
+ put_tty:
+	tty_kref_put(tty);
  reset_open_count:
 	port->port.count = 0;
 	usb_autopm_put_interface(serial->interface);
Signature · 1 line
1.9.1
#105 lore raw

PATCH 98/176 mm: Don't count the stack guard page towards RLIMIT_STACK

In reply to [email protected]

From: Linus Torvalds <[email protected]>

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

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

commit 690eac53daff34169a4d74fc7bfbd388c4896abb upstream.

Commit fee7e49d4514 ("mm: propagate error from stack expansion even for guard page") made sure that we return the error properly for stack growth conditions. It also theorized that counting the guard page towards the stack limit might break something, but also said "Let's see if anybody notices".

Somebody did notice. Apparently android-x86 sets the stack limit very close to the limit indeed, and including the guard page in the rlimit check causes the android 'zygote' process problems.

So this adds the (fairly trivial) code to make the stack rlimit check be against the actual real stack size, rather than the size of the vma that includes the guard page.

---
 mm/mmap.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
mm/mmap.c +5 -2
index 94fdbe8..84dc5fc 100644
@@ -1727,14 +1727,17 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
 {
 	struct mm_struct *mm = vma->vm_mm;
 	struct rlimit *rlim = current->signal->rlim;
-	unsigned long new_start;
+	unsigned long new_start, actual_size;
 
 	/* address space limit tests */
 	if (!may_expand_vm(mm, grow))
 		return -ENOMEM;
 
 	/* Stack limit test */
-	if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur))
+	actual_size = size;
+	if (size && (vma->vm_flags & (VM_GROWSUP | VM_GROWSDOWN)))
+		actual_size -= PAGE_SIZE;
+	if (actual_size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur))
 		return -ENOMEM;
 
 	/* mlock limit tests */
Signature · 1 line
1.9.1
#106 lore raw

PATCH 99/176 mm: fix corner case in anon_vma endless growing prevention

In reply to [email protected]

From: Konstantin Khlebnikov <[email protected]>

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

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

commit b800c91a0517071156e772d4fb329ad33590da62 upstream.

Fix for BUG_ON(anon_vma->degree) splashes in unlink_anon_vmas() ("kernel BUG at mm/rmap.c:399!") caused by commit 7a3ef208e662 ("mm: prevent endless growth of anon_vma hierarchy")

Anon_vma_clone() is usually called for a copy of source vma in destination argument. If source vma has anon_vma it should be already in dst->anon_vma. NULL in dst->anon_vma is used as a sign that it's called from anon_vma_fork(). In this case anon_vma_clone() finds anon_vma for reusing.

Vma_adjust() calls it differently and this breaks anon_vma reusing
logic: anon_vma_clone() links vma to old anon_vma and updates degree counters but vma_adjust() overrides vma->anon_vma right after that. As a result final unlink_anon_vmas() decrements degree for wrong anon_vma.

This patch assigns ->anon_vma before calling anon_vma_clone().

[lizf: Backported to 3.4: define variable @error and return this instead
of returning -ENOMEM]

---
 mm/mmap.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
mm/mmap.c +7 -2
index 84dc5fc..f880ca1 100644
@@ -567,9 +567,14 @@ again:			remove_next = 1 + (end > next->vm_end);
 		 * shrinking vma had, to cover any anon pages imported.
 		 */
 		if (exporter && exporter->anon_vma && !importer->anon_vma) {
-			if (anon_vma_clone(importer, exporter))
-				return -ENOMEM;
+			int error;
+
 			importer->anon_vma = exporter->anon_vma;
+			error = anon_vma_clone(importer, exporter);
+			if (error) {
+				importer->anon_vma = NULL;
+				return error;
+			}
 		}
 	}
 
Signature · 1 line
1.9.1
#107 lore raw

PATCH 100/176 gpio: fix memory and reference leaks in gpiochip_add error path

In reply to [email protected]

From: Johan Hovold <[email protected]>

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

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

commit 5539b3c938d64a60cb1fc442ac3ce9263d52de0c upstream.

Memory allocated and references taken by of_gpiochip_add and acpi_gpiochip_add were never released on errors in gpiochip_add (e.g. failure to find free gpio range).

Fixes 391c970c0dd1 ("of/gpio: add default of_xlate function if device

has a node pointer")

Fixes 664e3e5ac64c ("gpio / ACPI: register to ACPI events

automatically")

[lizf: Backported to 3.4:
- move the call to of_gpiochip_add() into the above if condition.
- remove the call to acpi_gpiochip_remove()]

---
 drivers/gpio/gpiolib.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/gpio/gpiolib.c +5 -6
index 112c16e..663570c 100644
@@ -1081,19 +1081,18 @@ int gpiochip_add(struct gpio_chip *chip)
 				? (1 << FLAG_IS_OUT)
 				: 0;
 		}
-	}
 
-	of_gpiochip_add(chip);
+		of_gpiochip_add(chip);
+	}
 
 unlock:
 	spin_unlock_irqrestore(&gpio_lock, flags);
 
-	if (status)
-		goto fail;
-
 	status = gpiochip_export(chip);
-	if (status)
+	if (status) {
+		of_gpiochip_remove(chip);
 		goto fail;
+	}
 
 	pr_info("gpiochip_add: registered GPIOs %d to %d on device: %s\n",
 		chip->base, chip->base + chip->ngpio - 1,
Signature · 1 line
1.9.1
#108 lore raw

PATCH 101/176 usb: dwc3: gadget: Stop TRB preparation after limit is reached

In reply to [email protected]

From: Amit Virdi <[email protected]>

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

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

commit 39e60635a01520e8c8ed3946a28c2b98e6a46f79 upstream.

DWC3 gadget sets up a pool of 32 TRBs for each EP during initialization. This means, the max TRBs that can be submitted for an EP is fixed to 32. Since the request queue for an EP is a linked list, any number of requests can be queued to it by the gadget layer. However, the dwc3 driver must not submit TRBs more than the pool it has created for. This limit wasn't respected when SG was used resulting in submitting more than the max TRBs, eventually leading to non-transfer of the TRBs submitted over the max limit.

Root cause:
When SG is used, there are two loops iterating to prepare TRBs:
- Outer loop over the request_list
- Inner loop over the SG list
The code was missing break to get out of the outer loop.

Fixes eeb720fb21d6 (usb: dwc3: gadget: add support for SG lists)
---
 drivers/usb/dwc3/gadget.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/usb/dwc3/gadget.c +3 -0
index 1acb3a4..b7f8926 100644
@@ -851,6 +851,9 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)
 				if (last_one)
 					break;
 			}
+
+			if (last_one)
+				break;
 		} else {
 			dma = req->request.dma;
 			length = req->request.length;
Signature · 1 line
1.9.1
#109 lore raw

PATCH 102/176 ftrace/jprobes/x86: Fix conflict between jprobes and function graph tracing

In reply to [email protected]

From: "Steven Rostedt (Red Hat)" <[email protected]>

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

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

commit 237d28db036e411f22c03cfd5b0f6dc2aa9bf3bc upstream.

If the function graph tracer traces a jprobe callback, the system will crash. This can easily be demonstrated by compiling the jprobe sample module that is in the kernel tree, loading it and running the function graph tracer.

 # modprobe jprobe_example.ko
 # echo function_graph > /sys/kernel/debug/tracing/current_tracer
 # ls

The first two commands end up in a nice crash after the first fork. (do_fork has a jprobe attached to it, so "ls" just triggers that fork)

The problem is caused by the jprobe_return() that all jprobe callbacks must end with. The way jprobes works is that the function a jprobe is attached to has a breakpoint placed at the start of it (or it uses ftrace if fentry is supported). The breakpoint handler (or ftrace callback) will copy the stack frame and change the ip address to return to the jprobe handler instead of the function. The jprobe handler must end with jprobe_return() which swaps the stack and does an int3 (breakpoint). This breakpoint handler will then put back the saved stack frame, simulate the instruction at the beginning of the function it added a breakpoint to, and then continue on.

For function tracing to work, it hijakes the return address from the stack frame, and replaces it with a hook function that will trace the end of the call. This hook function will restore the return address of the function call.

If the function tracer traces the jprobe handler, the hook function for that handler will not be called, and its saved return address will be used for the next function. This will result in a kernel crash.

To solve this, pause function tracing before the jprobe handler is called and unpause it before it returns back to the function it probed.

Some other updates:

Used a variable "saved_sp" to hold kcb->jprobe_saved_sp. This makes the code look a bit cleaner and easier to understand (various tries to fix this bug required this change).

Note, if fentry is being used, jprobes will change the ip address before the function graph tracer runs and it will not be able to trace the function that the jprobe is probing.

[lizf: Backported to 3.4:
- adjust filename
- adjust context]

---
 arch/x86/kernel/kprobes.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)
arch/x86/kernel/kprobes.c +15 -5
index e213fc8..15d3c45 100644
@@ -1003,6 +1003,15 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 	regs->flags &= ~X86_EFLAGS_IF;
 	trace_hardirqs_off();
 	regs->ip = (unsigned long)(jp->entry);
+
+	/*
+	 * jprobes use jprobe_return() which skips the normal return
+	 * path of the function, and this messes up the accounting of the
+	 * function graph tracer to get messed up.
+	 *
+	 * Pause function graph tracing while performing the jprobe function.
+	 */
+	pause_graph_tracing();
 	return 1;
 }
 
@@ -1028,24 +1037,25 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 	u8 *addr = (u8 *) (regs->ip - 1);
 	struct jprobe *jp = container_of(p, struct jprobe, kp);
+	void *saved_sp = kcb->jprobe_saved_sp;
 
 	if ((addr > (u8 *) jprobe_return) &&
 	    (addr < (u8 *) jprobe_return_end)) {
-		if (stack_addr(regs) != kcb->jprobe_saved_sp) {
+		if (stack_addr(regs) != saved_sp) {
 			struct pt_regs *saved_regs = &kcb->jprobe_saved_regs;
 			printk(KERN_ERR
 			       "current sp %p does not match saved sp %p\n",
-			       stack_addr(regs), kcb->jprobe_saved_sp);
+			       stack_addr(regs), saved_sp);
 			printk(KERN_ERR "Saved registers for jprobe %p\n", jp);
 			show_registers(saved_regs);
 			printk(KERN_ERR "Current registers\n");
 			show_registers(regs);
 			BUG();
 		}
+		/* It's OK to start function graph tracing again */
+		unpause_graph_tracing();
 		*regs = kcb->jprobe_saved_regs;
-		memcpy((kprobe_opcode_t *)(kcb->jprobe_saved_sp),
-		       kcb->jprobes_stack,
-		       MIN_STACK_SIZE(kcb->jprobe_saved_sp));
+		memcpy(saved_sp, kcb->jprobes_stack, MIN_STACK_SIZE(saved_sp));
 		preempt_enable_no_resched();
 		return 1;
 	}
Signature · 1 line
1.9.1
#110 lore raw

PATCH 103/176 can: dev: fix crtlmode_supported check

In reply to [email protected]

From: Oliver Hartkopp <[email protected]>

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

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

commit 9b1087aa5e86448fe6ad40a58964e35f3ba423d5 upstream.

When changing flags in the CAN drivers ctrlmode the provided new content has to be checked whether the bits are allowed to be changed. The bits that are to be changed are given as a bitfield in cm->mask. Therefore checking against cm->flags is wrong as the content can hold any kind of values.

The iproute2 tool sets the bits in cm->mask and cm->flags depending on the detected command line options. To be robust against bogus user space applications additionally sanitize the provided flags with the provided mask.

Cc Wolfgang Grandegger <[email protected]>
[lizf: Backported to 3.4: adjust context]
---
 drivers/net/can/dev.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/can/dev.c +6 -2
index d4f7f95..88c39e4 100644
@@ -612,10 +612,14 @@ static int can_changelink(struct net_device *dev,
 		if (dev->flags & IFF_UP)
 			return -EBUSY;
 		cm = nla_data(data[IFLA_CAN_CTRLMODE]);
-		if (cm->flags & ~priv->ctrlmode_supported)
+
+		/* check whether changed bits are allowed to be modified */
+		if (cm->mask & ~priv->ctrlmode_supported)
 			return -EOPNOTSUPP;
+
+		/* clear bits to be modified and copy the flag values */
 		priv->ctrlmode &= ~cm->mask;
-		priv->ctrlmode |= cm->flags;
+		priv->ctrlmode |= (cm->flags & cm->mask);
 	}
 
 	if (data[IFLA_CAN_BITTIMING]) {
Signature · 1 line
1.9.1
#111 lore raw

PATCH 104/176 sysfs.h: add ATTRIBUTE_GROUPS() macro

In reply to [email protected]

From: Greg Kroah-Hartman <[email protected]>

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

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

commit f2f37f58b1b933b06d6d84e80a31a1b500fb0db2 upstream.

To make it easier for driver subsystems to work with attribute groups, create the ATTRIBUTE_GROUPS macro to remove some of the repetitive typing for the most common use for attribute groups.

---
 include/linux/sysfs.h | 9 +++++++++
 1 file changed, 9 insertions(+)
include/linux/sysfs.h +9 -0
index 0010009..caf2e56 100644
@@ -80,6 +80,15 @@ struct attribute_group {
 
 #define __ATTR_NULL { .attr = { .name = NULL } }
 
+#define ATTRIBUTE_GROUPS(name)					\
+static const struct attribute_group name##_group = {		\
+	.attrs = name##_attrs,					\
+};								\
+static const struct attribute_group *name##_groups[] = {	\
+	&name##_group,						\
+	NULL,							\
+}
+
 #define attr_name(_attr) (_attr).attr.name
 
 struct file;
Signature · 1 line
1.9.1
#112 lore raw

PATCH 105/176 driver core: Introduce device_create_groups

In reply to [email protected]

From: Guenter Roeck <[email protected]>

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

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

commit 39ef311204941ddd01ea2950d6220c8ccc710d15 upstream.

device_create_groups lets callers create devices as well as associated sysfs attributes with a single call. This avoids race conditions seen if sysfs attributes on new devices are created later.

[fixed up comment block placement and add checks for printk buffer formats - gregkh]

Cc Jean Delvare <[email protected]>
[lizf: Backported to 3.4: adjust context]
---
 drivers/base/core.c    | 111 ++++++++++++++++++++++++++++++++++++-------------
 include/linux/device.h |   5 +++
 2 files changed, 88 insertions(+), 28 deletions(-)
drivers/base/core.c +83 -28
index 32e86d6..aeaf0e1 100644
@@ -1494,34 +1494,11 @@ static void device_create_release(struct device *dev)
 	kfree(dev);
 }
 
-/**
- * device_create_vargs - creates a device and registers it with sysfs
- * @class: pointer to the struct class that this device should be registered to
- * @parent: pointer to the parent struct device of this new device, if any
- * @devt: the dev_t for the char device to be added
- * @drvdata: the data to be added to the device for callbacks
- * @fmt: string for the device's name
- * @args: va_list for the device's name
- *
- * This function can be used by char device classes.  A struct device
- * will be created in sysfs, registered to the specified class.
- *
- * A "dev" file will be created, showing the dev_t for the device, if
- * the dev_t is not 0,0.
- * If a pointer to a parent struct device is passed in, the newly created
- * struct device will be a child of that device in sysfs.
- * The pointer to the struct device will be returned from the call.
- * Any further sysfs files that might be required can be created using this
- * pointer.
- *
- * Returns &struct device pointer on success, or ERR_PTR() on error.
- *
- * Note: the struct class passed to this function must have previously
- * been created with a call to class_create().
- */
-struct device *device_create_vargs(struct class *class, struct device *parent,
-				   dev_t devt, void *drvdata, const char *fmt,
-				   va_list args)
+static struct device *
+device_create_groups_vargs(struct class *class, struct device *parent,
+			   dev_t devt, void *drvdata,
+			   const struct attribute_group **groups,
+			   const char *fmt, va_list args)
 {
 	struct device *dev = NULL;
 	int retval = -ENODEV;
@@ -1538,6 +1515,7 @@ struct device *device_create_vargs(struct class *class, struct device *parent,
 	dev->devt = devt;
 	dev->class = class;
 	dev->parent = parent;
+	dev->groups = groups;
 	dev->release = device_create_release;
 	dev_set_drvdata(dev, drvdata);
 
@@ -1555,6 +1533,39 @@ error:
 	put_device(dev);
 	return ERR_PTR(retval);
 }
+
+/**
+ * device_create_vargs - creates a device and registers it with sysfs
+ * @class: pointer to the struct class that this device should be registered to
+ * @parent: pointer to the parent struct device of this new device, if any
+ * @devt: the dev_t for the char device to be added
+ * @drvdata: the data to be added to the device for callbacks
+ * @fmt: string for the device's name
+ * @args: va_list for the device's name
+ *
+ * This function can be used by char device classes.  A struct device
+ * will be created in sysfs, registered to the specified class.
+ *
+ * A "dev" file will be created, showing the dev_t for the device, if
+ * the dev_t is not 0,0.
+ * If a pointer to a parent struct device is passed in, the newly created
+ * struct device will be a child of that device in sysfs.
+ * The pointer to the struct device will be returned from the call.
+ * Any further sysfs files that might be required can be created using this
+ * pointer.
+ *
+ * Returns &struct device pointer on success, or ERR_PTR() on error.
+ *
+ * Note: the struct class passed to this function must have previously
+ * been created with a call to class_create().
+ */
+struct device *device_create_vargs(struct class *class, struct device *parent,
+				   dev_t devt, void *drvdata, const char *fmt,
+				   va_list args)
+{
+	return device_create_groups_vargs(class, parent, devt, drvdata, NULL,
+					  fmt, args);
+}
 EXPORT_SYMBOL_GPL(device_create_vargs);
 
 /**
@@ -1594,6 +1605,50 @@ struct device *device_create(struct class *class, struct device *parent,
 }
 EXPORT_SYMBOL_GPL(device_create);
 
+/**
+ * device_create_with_groups - creates a device and registers it with sysfs
+ * @class: pointer to the struct class that this device should be registered to
+ * @parent: pointer to the parent struct device of this new device, if any
+ * @devt: the dev_t for the char device to be added
+ * @drvdata: the data to be added to the device for callbacks
+ * @groups: NULL-terminated list of attribute groups to be created
+ * @fmt: string for the device's name
+ *
+ * This function can be used by char device classes.  A struct device
+ * will be created in sysfs, registered to the specified class.
+ * Additional attributes specified in the groups parameter will also
+ * be created automatically.
+ *
+ * A "dev" file will be created, showing the dev_t for the device, if
+ * the dev_t is not 0,0.
+ * If a pointer to a parent struct device is passed in, the newly created
+ * struct device will be a child of that device in sysfs.
+ * The pointer to the struct device will be returned from the call.
+ * Any further sysfs files that might be required can be created using this
+ * pointer.
+ *
+ * Returns &struct device pointer on success, or ERR_PTR() on error.
+ *
+ * Note: the struct class passed to this function must have previously
+ * been created with a call to class_create().
+ */
+struct device *device_create_with_groups(struct class *class,
+					 struct device *parent, dev_t devt,
+					 void *drvdata,
+					 const struct attribute_group **groups,
+					 const char *fmt, ...)
+{
+	va_list vargs;
+	struct device *dev;
+
+	va_start(vargs, fmt);
+	dev = device_create_groups_vargs(class, parent, devt, drvdata, groups,
+					 fmt, vargs);
+	va_end(vargs);
+	return dev;
+}
+EXPORT_SYMBOL_GPL(device_create_with_groups);
+
 static int __match_devt(struct device *dev, void *data)
 {
 	dev_t *devt = data;
include/linux/device.h +5 -0
index 5ad17cc..e93fed9 100644
@@ -835,6 +835,11 @@ extern __printf(5, 6)
 struct device *device_create(struct class *cls, struct device *parent,
 			     dev_t devt, void *drvdata,
 			     const char *fmt, ...);
+extern __printf(6, 7)
+struct device *device_create_with_groups(struct class *cls,
+			     struct device *parent, dev_t devt, void *drvdata,
+			     const struct attribute_group **groups,
+			     const char *fmt, ...);
 extern void device_destroy(struct class *cls, dev_t devt);
 
 /*
Signature · 1 line
1.9.1
#113 lore raw

PATCH 106/176 gpio: sysfs: fix gpio-chip device-attribute leak

In reply to [email protected]

From: Johan Hovold <[email protected]>

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

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

commit 121b6a79955a3a3fd7bbb9b8cb88d5b9dad6283d upstream.

The gpio-chip device attributes were never destroyed when the device was removed.

Fix by using device_create_with_groups() to create the device attributes of the chip class device.

Note that this also fixes the attribute-creation race with userspace.

Fixes d8f388d8dc8d ("gpio: sysfs interface")
[lizf: Backported to 3.4: adjust filename]
---
 drivers/gpio/gpiolib.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)
drivers/gpio/gpiolib.c +8 -11
index 663570c..c6df762 100644
@@ -589,16 +589,13 @@ static ssize_t chip_ngpio_show(struct device *dev,
 }
 static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL);
 
-static const struct attribute *gpiochip_attrs[] = {
+static struct attribute *gpiochip_attrs[] = {
 	&dev_attr_base.attr,
 	&dev_attr_label.attr,
 	&dev_attr_ngpio.attr,
 	NULL,
 };
-
-static const struct attribute_group gpiochip_attr_group = {
-	.attrs = (struct attribute **) gpiochip_attrs,
-};
+ATTRIBUTE_GROUPS(gpiochip);
 
 /*
  * /sys/class/gpio/export ... write-only
@@ -924,13 +921,13 @@ static int gpiochip_export(struct gpio_chip *chip)
 
 	/* use chip->base for the ID; it's already known to be unique */
 	mutex_lock(&sysfs_lock);
-	dev = device_create(&gpio_class, chip->dev, MKDEV(0, 0), chip,
-				"gpiochip%d", chip->base);
-	if (!IS_ERR(dev)) {
-		status = sysfs_create_group(&dev->kobj,
-				&gpiochip_attr_group);
-	} else
+	dev = device_create_with_groups(&gpio_class, chip->dev, MKDEV(0, 0),
+					chip, gpiochip_groups,
+					"gpiochip%d", chip->base);
+	if (IS_ERR(dev))
 		status = PTR_ERR(dev);
+	else
+		status = 0;
 	chip->exported = (status == 0);
 	mutex_unlock(&sysfs_lock);
 
Signature · 1 line
1.9.1
#114 lore raw

PATCH 107/176 gpiolib: Refactor gpio_export

In reply to [email protected]

From: Ryan Mallon <[email protected]>

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

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

commit fc4e2514995d9cd7f3e1a67098ce65d72acf8ec7 upstream.

The gpio_export function uses nested if statements and the status variable to handle the failure cases. This makes the function logic difficult to follow. Refactor the code to abort immediately on failure using goto. This makes the code slightly longer, but significantly reduces the nesting and number of split lines and makes the code easier to read.

---
 drivers/gpio/gpiolib.c | 85 +++++++++++++++++++++++++++-----------------------
 1 file changed, 46 insertions(+), 39 deletions(-)
drivers/gpio/gpiolib.c +46 -39
index c6df762..c579f3d 100644
@@ -701,8 +701,9 @@ int gpio_export(unsigned gpio, bool direction_may_change)
 {
 	unsigned long		flags;
 	struct gpio_desc	*desc;
-	int			status = -EINVAL;
+	int			status;
 	const char		*ioname = NULL;
+	struct device		*dev;
 
 	/* can't export until sysfs is available ... */
 	if (!gpio_class.p) {
@@ -710,59 +711,65 @@ int gpio_export(unsigned gpio, bool direction_may_change)
 		return -ENOENT;
 	}
 
-	if (!gpio_is_valid(gpio))
-		goto done;
+	if (!gpio_is_valid(gpio)) {
+		pr_debug("%s: gpio %d is not valid\n", __func__, gpio);
+		return -EINVAL;
+	}
 
 	mutex_lock(&sysfs_lock);
 
 	spin_lock_irqsave(&gpio_lock, flags);
 	desc = &gpio_desc[gpio];
-	if (test_bit(FLAG_REQUESTED, &desc->flags)
-			&& !test_bit(FLAG_EXPORT, &desc->flags)) {
-		status = 0;
-		if (!desc->chip->direction_input
-				|| !desc->chip->direction_output)
-			direction_may_change = false;
+	if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
+	     test_bit(FLAG_EXPORT, &desc->flags)) {
+		spin_unlock_irqrestore(&gpio_lock, flags);
+		pr_debug("%s: gpio %d unavailable (requested=%d, exported=%d)\n",
+				__func__, gpio,
+				test_bit(FLAG_REQUESTED, &desc->flags),
+				test_bit(FLAG_EXPORT, &desc->flags));
+		return -EPERM;
 	}
+
+	if (!desc->chip->direction_input || !desc->chip->direction_output)
+		direction_may_change = false;
 	spin_unlock_irqrestore(&gpio_lock, flags);
 
 	if (desc->chip->names && desc->chip->names[gpio - desc->chip->base])
 		ioname = desc->chip->names[gpio - desc->chip->base];
 
-	if (status == 0) {
-		struct device	*dev;
-
-		dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
-				desc, ioname ? ioname : "gpio%u", gpio);
-		if (!IS_ERR(dev)) {
-			status = sysfs_create_group(&dev->kobj,
-						&gpio_attr_group);
-
-			if (!status && direction_may_change)
-				status = device_create_file(dev,
-						&dev_attr_direction);
-
-			if (!status && gpio_to_irq(gpio) >= 0
-					&& (direction_may_change
-						|| !test_bit(FLAG_IS_OUT,
-							&desc->flags)))
-				status = device_create_file(dev,
-						&dev_attr_edge);
-
-			if (status != 0)
-				device_unregister(dev);
-		} else
-			status = PTR_ERR(dev);
-		if (status == 0)
-			set_bit(FLAG_EXPORT, &desc->flags);
+	dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
+			    desc, ioname ? ioname : "gpio%u", gpio);
+	if (IS_ERR(dev)) {
+		status = PTR_ERR(dev);
+		goto fail_unlock;
 	}
 
-	mutex_unlock(&sysfs_lock);
-
-done:
+	status = sysfs_create_group(&dev->kobj, &gpio_attr_group);
 	if (status)
-		pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
+		goto fail_unregister_device;
+
+	if (direction_may_change) {
+		status = device_create_file(dev, &dev_attr_direction);
+		if (status)
+			goto fail_unregister_device;
+	}
 
+	if (gpio_to_irq(gpio) >= 0 && (direction_may_change ||
+				       !test_bit(FLAG_IS_OUT, &desc->flags))) {
+		status = device_create_file(dev, &dev_attr_edge);
+		if (status)
+			goto fail_unregister_device;
+	}
+
+	set_bit(FLAG_EXPORT, &desc->flags);
+	mutex_unlock(&sysfs_lock);
+	return 0;
+
+fail_unregister_device:
+	device_unregister(dev);
+fail_unlock:
+	mutex_unlock(&sysfs_lock);
+	pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
 	return status;
 }
 EXPORT_SYMBOL_GPL(gpio_export);
Signature · 1 line
1.9.1
#115 lore raw

PATCH 108/176 gpio: sysfs: fix gpio device-attribute leak

In reply to [email protected]

From: Johan Hovold <[email protected]>

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

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

commit 0915e6feb38de8d3601819992a5bd050201a56fa upstream.

The gpio device attributes were never destroyed when the gpio was unexported (or on export failures).

Use device_create_with_groups() to create the default device attributes of the gpio class device. Note that this also fixes the attribute-creation race with userspace for these attributes.

Remove contingent attributes in export error path and on unexport.

Fixes d8f388d8dc8d ("gpio: sysfs interface")

[lizf: Backported to 3.4:
- adjust filename
- adjust context]

---
 drivers/gpio/gpiolib.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)
drivers/gpio/gpiolib.c +12 -14
index c579f3d..4db6c55 100644
@@ -319,7 +319,7 @@ static ssize_t gpio_value_store(struct device *dev,
 	return status;
 }
 
-static const DEVICE_ATTR(value, 0644,
+static DEVICE_ATTR(value, 0644,
 		gpio_value_show, gpio_value_store);
 
 static irqreturn_t gpio_sysfs_irq(int irq, void *priv)
@@ -542,18 +542,15 @@ static ssize_t gpio_active_low_store(struct device *dev,
 	return status ? : size;
 }
 
-static const DEVICE_ATTR(active_low, 0644,
+static DEVICE_ATTR(active_low, 0644,
 		gpio_active_low_show, gpio_active_low_store);
 
-static const struct attribute *gpio_attrs[] = {
+static struct attribute *gpio_attrs[] = {
 	&dev_attr_value.attr,
 	&dev_attr_active_low.attr,
 	NULL,
 };
-
-static const struct attribute_group gpio_attr_group = {
-	.attrs = (struct attribute **) gpio_attrs,
-};
+ATTRIBUTE_GROUPS(gpio);
 
 /*
  * /sys/class/gpio/gpiochipN/
@@ -737,17 +734,14 @@ int gpio_export(unsigned gpio, bool direction_may_change)
 	if (desc->chip->names && desc->chip->names[gpio - desc->chip->base])
 		ioname = desc->chip->names[gpio - desc->chip->base];
 
-	dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
-			    desc, ioname ? ioname : "gpio%u", gpio);
+	dev = device_create_with_groups(&gpio_class, desc->chip->dev,
+					MKDEV(0, 0), desc, gpio_groups,
+					ioname ? ioname : "gpio%u", gpio);
 	if (IS_ERR(dev)) {
 		status = PTR_ERR(dev);
 		goto fail_unlock;
 	}
 
-	status = sysfs_create_group(&dev->kobj, &gpio_attr_group);
-	if (status)
-		goto fail_unregister_device;
-
 	if (direction_may_change) {
 		status = device_create_file(dev, &dev_attr_direction);
 		if (status)
@@ -758,13 +752,15 @@ int gpio_export(unsigned gpio, bool direction_may_change)
 				       !test_bit(FLAG_IS_OUT, &desc->flags))) {
 		status = device_create_file(dev, &dev_attr_edge);
 		if (status)
-			goto fail_unregister_device;
+			goto fail_remove_attr_direction;
 	}
 
 	set_bit(FLAG_EXPORT, &desc->flags);
 	mutex_unlock(&sysfs_lock);
 	return 0;
 
+fail_remove_attr_direction:
+	device_remove_file(dev, &dev_attr_direction);
 fail_unregister_device:
 	device_unregister(dev);
 fail_unlock:
@@ -904,6 +900,8 @@ void gpio_unexport(unsigned gpio)
 
 	mutex_unlock(&sysfs_lock);
 	if (dev) {
+		device_remove_file(dev, &dev_attr_edge);
+		device_remove_file(dev, &dev_attr_direction);
 		device_unregister(dev);
 		put_device(dev);
 	}
Signature · 1 line
1.9.1
#116 lore raw

PATCH 109/176 gpio: sysfs: fix gpio attribute-creation race

In reply to [email protected]

From: Johan Hovold <[email protected]>

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

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

commit ebbeba120ab2ec6ac5f3afc1425ec6ff0b77ad6f upstream.

Fix attribute-creation race with userspace by using the default group to create also the contingent gpio device attributes.

Fixes d8f388d8dc8d ("gpio: sysfs interface")

[lizf:
- adjust filename
- call gpio_to_irq() instead of gpiod_to_irq]

---
 drivers/gpio/gpiolib.c | 63 ++++++++++++++++++++++++++++++++------------------
 1 file changed, 41 insertions(+), 22 deletions(-)
drivers/gpio/gpiolib.c +41 -22
index 4db6c55..6c4443b 100644
@@ -60,6 +60,7 @@ struct gpio_desc {
 #define FLAG_ACTIVE_LOW	7	/* sysfs value has active low */
 #define FLAG_OPEN_DRAIN	8	/* Gpio is open drain type */
 #define FLAG_OPEN_SOURCE 9	/* Gpio is open source type */
+#define FLAG_SYSFS_DIR	10	/* show sysfs direction attribute */
 
 #define ID_SHIFT	16	/* add new flags before this one */
 
@@ -545,12 +546,45 @@ static ssize_t gpio_active_low_store(struct device *dev,
 static DEVICE_ATTR(active_low, 0644,
 		gpio_active_low_show, gpio_active_low_store);
 
+static umode_t gpio_is_visible(struct kobject *kobj, struct attribute *attr,
+			       int n)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct gpio_desc *desc = dev_get_drvdata(dev);
+	unsigned gpio = desc - gpio_desc;
+	umode_t mode = attr->mode;
+	bool show_direction = test_bit(FLAG_SYSFS_DIR, &desc->flags);
+
+	if (attr == &dev_attr_direction.attr) {
+		if (!show_direction)
+			mode = 0;
+	} else if (attr == &dev_attr_edge.attr) {
+		if (gpio_to_irq(gpio) < 0)
+			mode = 0;
+		if (!show_direction && test_bit(FLAG_IS_OUT, &desc->flags))
+			mode = 0;
+	}
+
+	return mode;
+}
+
 static struct attribute *gpio_attrs[] = {
+	&dev_attr_direction.attr,
+	&dev_attr_edge.attr,
 	&dev_attr_value.attr,
 	&dev_attr_active_low.attr,
 	NULL,
 };
-ATTRIBUTE_GROUPS(gpio);
+
+static const struct attribute_group gpio_group = {
+	.attrs = gpio_attrs,
+	.is_visible = gpio_is_visible,
+};
+
+static const struct attribute_group *gpio_groups[] = {
+	&gpio_group,
+	NULL
+};
 
 /*
  * /sys/class/gpio/gpiochipN/
@@ -727,8 +761,11 @@ int gpio_export(unsigned gpio, bool direction_may_change)
 		return -EPERM;
 	}
 
-	if (!desc->chip->direction_input || !desc->chip->direction_output)
-		direction_may_change = false;
+	if (desc->chip->direction_input && desc->chip->direction_output &&
+			direction_may_change) {
+		set_bit(FLAG_SYSFS_DIR, &desc->flags);
+	}
+
 	spin_unlock_irqrestore(&gpio_lock, flags);
 
 	if (desc->chip->names && desc->chip->names[gpio - desc->chip->base])
@@ -742,27 +779,10 @@ int gpio_export(unsigned gpio, bool direction_may_change)
 		goto fail_unlock;
 	}
 
-	if (direction_may_change) {
-		status = device_create_file(dev, &dev_attr_direction);
-		if (status)
-			goto fail_unregister_device;
-	}
-
-	if (gpio_to_irq(gpio) >= 0 && (direction_may_change ||
-				       !test_bit(FLAG_IS_OUT, &desc->flags))) {
-		status = device_create_file(dev, &dev_attr_edge);
-		if (status)
-			goto fail_remove_attr_direction;
-	}
-
 	set_bit(FLAG_EXPORT, &desc->flags);
 	mutex_unlock(&sysfs_lock);
 	return 0;
 
-fail_remove_attr_direction:
-	device_remove_file(dev, &dev_attr_direction);
-fail_unregister_device:
-	device_unregister(dev);
 fail_unlock:
 	mutex_unlock(&sysfs_lock);
 	pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
@@ -893,6 +913,7 @@ void gpio_unexport(unsigned gpio)
 		dev = class_find_device(&gpio_class, NULL, desc, match_export);
 		if (dev) {
 			gpio_setup_irq(desc, dev, 0);
+			clear_bit(FLAG_SYSFS_DIR, &desc->flags);
 			clear_bit(FLAG_EXPORT, &desc->flags);
 		} else
 			status = -ENODEV;
@@ -900,8 +921,6 @@ void gpio_unexport(unsigned gpio)
 
 	mutex_unlock(&sysfs_lock);
 	if (dev) {
-		device_remove_file(dev, &dev_attr_edge);
-		device_remove_file(dev, &dev_attr_direction);
 		device_unregister(dev);
 		put_device(dev);
 	}
Signature · 1 line
1.9.1
#117 lore raw

PATCH 110/176 ALSA: usb-audio: Add mic volume fix quirk for Logitech Webcam C210

In reply to [email protected]

From: Jason Lee Cragg <[email protected]>

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

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

commit 6455931186bff407493135e74c5f32efd30860e2 upstream.

---
 sound/usb/mixer.c | 1 +
 1 file changed, 1 insertion(+)
sound/usb/mixer.c +1 -0
index 2b67823..c419aa3 100644
@@ -834,6 +834,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
 	case USB_ID(0x046d, 0x0807): /* Logitech Webcam C500 */
 	case USB_ID(0x046d, 0x0808):
 	case USB_ID(0x046d, 0x0809):
+	case USB_ID(0x046d, 0x0819): /* Logitech Webcam C210 */
 	case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */
 	case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */
 	case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */
Signature · 1 line
1.9.1
#118 lore raw

PATCH 111/176 libata: allow sata_sil24 to opt-out of tag ordered submission

In reply to [email protected]

From: Dan Williams <[email protected]>

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

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

commit 72dd299d5039a336493993dcc63413cf31d0e662 upstream.

Ronny reports: https://bugzilla.kernel.org/show_bug.cgi?id=87101
"Since commit 8a4aeec8d "libata/ahci: accommodate tag ordered controllers" the access to the harddisk on the first SATA-port is failing on its first access. The access to the harddisk on the second port is working normal.

When reverting the above commit, access to both harddisks is working fine again."

Maintain tag ordered submission as the default, but allow sata_sil24 to continue with the old behavior.

---
 drivers/ata/libata-core.c | 5 ++++-
 drivers/ata/sata_sil24.c  | 2 +-
 include/linux/libata.h    | 1 +
 3 files changed, 6 insertions(+), 2 deletions(-)
drivers/ata/libata-core.c +4 -1
index 6b92236..adaf994 100644
@@ -4712,7 +4712,10 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
 		return NULL;
 
 	for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) {
-		tag = tag < max_queue ? tag : 0;
+		if (ap->flags & ATA_FLAG_LOWTAG)
+			tag = i;
+		else
+			tag = tag < max_queue ? tag : 0;
 
 		/* the last tag is reserved for internal command. */
 		if (tag == ATA_TAG_INTERNAL)
drivers/ata/sata_sil24.c +1 -1
index e7e610a..cb68aa3 100644
@@ -246,7 +246,7 @@ enum {
 	/* host flags */
 	SIL24_COMMON_FLAGS	= ATA_FLAG_SATA | ATA_FLAG_PIO_DMA |
 				  ATA_FLAG_NCQ | ATA_FLAG_ACPI_SATA |
-				  ATA_FLAG_AN | ATA_FLAG_PMP,
+				  ATA_FLAG_AN | ATA_FLAG_PMP | ATA_FLAG_LOWTAG,
 	SIL24_FLAG_PCIX_IRQ_WOC	= (1 << 24), /* IRQ loss errata on PCI-X */
 
 	IRQ_STAT_4PORTS		= 0xf,
include/linux/libata.h +1 -0
index dd16deb..764cd54 100644
@@ -207,6 +207,7 @@ enum {
 	ATA_FLAG_SW_ACTIVITY	= (1 << 22), /* driver supports sw activity
 					      * led */
 	ATA_FLAG_NO_DIPM	= (1 << 23), /* host not happy with DIPM */
+	ATA_FLAG_LOWTAG		= (1 << 24), /* host wants lowest available tag */
 
 	/* bits 24:31 of ap->flags are reserved for LLD specific flags */
 
Signature · 1 line
1.9.1
#119 lore raw

PATCH 112/176 scripts/recordmcount.pl: There is no -m32 gcc option on Super-H anymore

In reply to [email protected]

From: Michael Karcher <[email protected]>

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

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

commit 1caf6aaaa47471831d77c75f094d4e00ad1ec808 upstream.

Compiling SH with gcc-4.8 fails due to the -m32 option not being supported.

Quoted 1 line

From http://buildd.debian-ports.org/status/fetch.php?pkg=linux&arch=sh4&ver=3.16.7-ckt4-1&stamp=1421425783

CC init/main.o
gcc-4.8: error: unrecognized command line option '-m32'
ld: cannot find init/.tmp_mc_main.o: No such file or directory
objcopy: 'init/.tmp_mx_main.o': No such file
rm: cannot remove 'init/.tmp_mx_main.o': No such file or directory
rm: cannot remove 'init/.tmp_mc_main.o': No such file or directory

---
 scripts/recordmcount.pl | 1 -
 1 file changed, 1 deletion(-)
scripts/recordmcount.pl +0 -1
index 858966a..679218b 100755
@@ -262,7 +262,6 @@ if ($arch eq "x86_64") {
     # force flags for this arch
     $ld .= " -m shlelf_linux";
     $objcopy .= " -O elf32-sh-linux";
-    $cc .= " -m32";
 
 } elsif ($arch eq "powerpc") {
     $local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)";
Signature · 1 line
1.9.1
#120 lore raw

PATCH 113/176 libata: prevent HSM state change race between ISR and PIO

In reply to [email protected]

From: David Jeffery <[email protected]>

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

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

commit ce7514526742c0898b837d4395f515b79dfb5a12 upstream.

It is possible for ata_sff_flush_pio_task() to set ap->hsm_task_state to HSM_ST_IDLE in between the time __ata_sff_port_intr() checks for HSM_ST_IDLE and before it calls ata_sff_hsm_move() causing ata_sff_hsm_move() to BUG().

This problem is hard to reproduce making this patch hard to verify, but this fix will prevent the race.

I have not been able to reproduce the problem, but here is a crash dump from a 2.6.32 kernel.

On examining the ata port's state, its hsm_task_state field has a value of HSM_ST_IDLE:

crash> struct ata_port.hsm_task_state ffff881c1121c000
hsm_task_state = 0

Normally, this should not be possible as ata_sff_hsm_move() was called from ata_sff_host_intr(), which checks hsm_task_state and won't call ata_sff_hsm_move() if it has a HSM_ST_IDLE value.

PID: 11053 TASK: ffff8816e846cae0 CPU: 0 COMMAND: "sshd"
#0 [ffff88008ba03960] machine_kexec at ffffffff81038f3b #1 [ffff88008ba039c0] crash_kexec at ffffffff810c5d92 #2 [ffff88008ba03a90] oops_end at ffffffff8152b510 #3 [ffff88008ba03ac0] die at ffffffff81010e0b #4 [ffff88008ba03af0] do_trap at ffffffff8152ad74 #5 [ffff88008ba03b50] do_invalid_op at ffffffff8100cf95 #6 [ffff88008ba03bf0] invalid_op at ffffffff8100bf9b

    [exception RIP: ata_sff_hsm_move+317]
    RIP: ffffffff813a77ad  RSP: ffff88008ba03ca0  RFLAGS: 00010097
    RAX: 0000000000000000  RBX: ffff881c1121dc60  RCX: 0000000000000000
    RDX: ffff881c1121dd10  RSI: ffff881c1121dc60  RDI: ffff881c1121c000
    RBP: ffff88008ba03d00   R8: 0000000000000000   R9: 000000000000002e
    R10: 000000000001003f  R11: 000000000000009b  R12: ffff881c1121c000
    R13: 0000000000000000  R14: 0000000000000050  R15: ffff881c1121dd78
    ORIG_RAX: ffffffffffffffff  CS: 0010  SS: 0018
 #7 [ffff88008ba03d08] ata_sff_host_intr at ffffffff813a7fbd
 #8 [ffff88008ba03d38] ata_sff_interrupt at ffffffff813a821e
 #9 [ffff88008ba03d78] handle_IRQ_event at ffffffff810e6ec0
---
 drivers/ata/libata-sff.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/ata/libata-sff.c +12 -0
index 3723e5e..fad2734 100644
@@ -1333,7 +1333,19 @@ void ata_sff_flush_pio_task(struct ata_port *ap)
 	DPRINTK("ENTER\n");
 
 	cancel_delayed_work_sync(&ap->sff_pio_task);
+
+	/*
+	 * We wanna reset the HSM state to IDLE.  If we do so without
+	 * grabbing the port lock, critical sections protected by it which
+	 * expect the HSM state to stay stable may get surprised.  For
+	 * example, we may set IDLE in between the time
+	 * __ata_sff_port_intr() checks for HSM_ST_IDLE and before it calls
+	 * ata_sff_hsm_move() causing ata_sff_hsm_move() to BUG().
+	 */
+	spin_lock_irq(ap->lock);
 	ap->hsm_task_state = HSM_ST_IDLE;
+	spin_unlock_irq(ap->lock);
+
 	ap->sff_pio_task_link = NULL;
 
 	if (ata_msg_ctl(ap))
Signature · 1 line
1.9.1
#121 lore raw

PATCH 114/176 x86, hyperv: Mark the Hyper-V clocksource as being continuous

In reply to [email protected]

From: "K. Y. Srinivasan" <[email protected]>

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

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

commit 32c6590d126836a062b3140ed52d898507987017 upstream.

The Hyper-V clocksource is continuous; mark it accordingly.

---
 arch/x86/kernel/cpu/mshyperv.c | 1 +
 1 file changed, 1 insertion(+)
arch/x86/kernel/cpu/mshyperv.c +1 -0
index 646d192..c465584 100644
@@ -55,6 +55,7 @@ static struct clocksource hyperv_cs = {
 	.rating		= 400, /* use this when running on Hyperv*/
 	.read		= read_hv_clock,
 	.mask		= CLOCKSOURCE_MASK(64),
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
 static void __init ms_hyperv_init_platform(void)
Signature · 1 line
1.9.1
#122 lore raw

PATCH 115/176 spi: dw: Fix detecting FIFO depth

In reply to [email protected]

From: Axel Lin <[email protected]>

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

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

commit d297933cc7fcfbaaf2d37570baac73287bf0357d upstream.

Current code tries to find the highest valid fifo depth by checking the value it wrote to DW_SPI_TXFLTR. There are a few problems in current code:
1) There is an off-by-one in dws->fifo_len setting because it assumes the latest register write fails so the latest valid value should be fifo - 1.
2) We know the depth could be from 2 to 256 from HW spec, so it is not necessary to test fifo == 257. In the case fifo is 257, it means the latest valid setting is fifo = 256. So after the for loop iteration, we should check fifo == 2 case instead of fifo == 257 if detecting the FIFO depth fails.
This patch fixes above issues.

[lizf: Backported to 3.4: adjust context]
---
 drivers/spi/spi-dw.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/spi/spi-dw.c +2 -2
index ff06b42..71ef1e4 100644
@@ -780,13 +780,13 @@ static void spi_hw_init(struct dw_spi *dws)
 	 */
 	if (!dws->fifo_len) {
 		u32 fifo;
-		for (fifo = 2; fifo <= 257; fifo++) {
+		for (fifo = 2; fifo <= 256; fifo++) {
 			dw_writew(dws, DW_SPI_TXFLTR, fifo);
 			if (fifo != dw_readw(dws, DW_SPI_TXFLTR))
 				break;
 		}
 
-		dws->fifo_len = (fifo == 257) ? 0 : fifo;
+		dws->fifo_len = (fifo == 2) ? 0 : fifo - 1;
 		dw_writew(dws, DW_SPI_TXFLTR, 0);
 	}
 }
Signature · 1 line
1.9.1
#123 lore raw

Re: [PATCH 3.4 115/176] spi: dw: Fix detecting FIFO depth

2015-04-09 16:46 GMT+08:00 <[email protected]>:

Quoted 19 lines

From: Axel Lin <[email protected]>

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

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

commit d297933cc7fcfbaaf2d37570baac73287bf0357d upstream.

Current code tries to find the highest valid fifo depth by checking the value it wrote to DW_SPI_TXFLTR. There are a few problems in current code:
1) There is an off-by-one in dws->fifo_len setting because it assumes the latest register write fails so the latest valid value should be fifo - 1.
2) We know the depth could be from 2 to 256 from HW spec, so it is not necessary to test fifo == 257. In the case fifo is 257, it means the latest valid setting is fifo = 256. So after the for loop iteration, we should check fifo == 2 case instead of fifo == 257 if detecting the FIFO depth fails.
This patch fixes above issues.

Quoted 5 lines
[lizf: Backported to 3.4: adjust context]

Hi,
This patch needs below fix:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/spi/spi-dw.c?id=9d239d353c319f9ff884c287ce47feb7cdf60ddc

Thanks,
Axel

#124 lore raw

Re: [PATCH 3.4 115/176] spi: dw: Fix detecting FIFO depth

Quoted 26 lines · Axel Lin

2015-04-09 16:46 GMT+08:00 <[email protected]>:

Quoted 19 lines

From: Axel Lin <[email protected]>

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

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

commit d297933cc7fcfbaaf2d37570baac73287bf0357d upstream.

Current code tries to find the highest valid fifo depth by checking the value it wrote to DW_SPI_TXFLTR. There are a few problems in current code:
1) There is an off-by-one in dws->fifo_len setting because it assumes the latest register write fails so the latest valid value should be fifo - 1.
2) We know the depth could be from 2 to 256 from HW spec, so it is not necessary to test fifo == 257. In the case fifo is 257, it means the latest valid setting is fifo = 256. So after the for loop iteration, we should check fifo == 2 case instead of fifo == 257 if detecting the FIFO depth fails.
This patch fixes above issues.

Quoted 5 lines
[lizf: Backported to 3.4: adjust context]
Quoted 4 lines

Hi,
This patch needs below fix:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/spi/spi-dw.c?id=9d239d353c319f9ff884c287ce47feb7cdf60ddc

Already queued. :)

See "[PATCH 3.4 173/176] spi: dw: revisit FIFO size detection again"

Thanks for your review!

#125 lore raw

PATCH 116/176 spi: dw-mid: fix FIFO size

In reply to [email protected]

From: Andy Shevchenko <[email protected]>

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

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

commit 67bf9cda4b498b8cea4a40be67a470afe57d2e88 upstream.

The FIFO size is 40 accordingly to the specifications, but this means 0x40, i.e. 64 bytes. This patch fixes the typo and enables FIFO size autodetection for Intel MID devices.

Fixes 7063c0d942a1 (spi/dw_spi: add DMA support)
---
 drivers/spi/spi-dw-mid.c | 1 -
 1 file changed, 1 deletion(-)
drivers/spi/spi-dw-mid.c +0 -1
index efc494a..f15f624 100644
@@ -219,7 +219,6 @@ int dw_spi_mid_init(struct dw_spi *dws)
 	iounmap(clk_reg);
 
 	dws->num_cs = 16;
-	dws->fifo_len = 40;	/* FIFO has 40 words buffer */
 
 #ifdef CONFIG_SPI_DW_MID_DMA
 	dws->dma_priv = kzalloc(sizeof(struct mid_dma), GFP_KERNEL);
Signature · 1 line
1.9.1
#126 lore raw

PATCH 117/176 ASoC: wm8960: Fix capture sample rate from 11250 to 11025

In reply to [email protected]

From: Zidan Wang <[email protected]>

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

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

commit 22ee76daddb87f88d2336d1b4737ef27c4f307ac upstream.

wm8960 codec can't support sample rate 11250, it must be 11025.

---
 sound/soc/codecs/wm8960.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/codecs/wm8960.c +1 -1
index ddb0d90..a09d7eb 100644
@@ -496,7 +496,7 @@ static struct {
 	{ 22050, 2 },
 	{ 24000, 2 },
 	{ 16000, 3 },
-	{ 11250, 4 },
+	{ 11025, 4 },
 	{ 12000, 4 },
 	{  8000, 5 },
 };
Signature · 1 line
1.9.1
#127 lore raw

PATCH 118/176 regulator: core: fix race condition in regulator_put()

In reply to [email protected]

From: Ashay Jaiswal <[email protected]>

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

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

commit 83b0302d347a49f951e904184afe57ac3723476e upstream.

The regulator framework maintains a list of consumer regulators for a regulator device and protects it from concurrent access using the regulator device's mutex lock.

In the case of regulator_put() the consumer is removed and regulator device's parameters are updated without holding the regulator device's mutex. This would lead to a race condition between the regulator_put() and any function which traverses the consumer list or modifies regulator device's parameters.
Fix this race condition by holding the regulator device's mutex in case of regulator_put.

[lizf: Backported to 3.4:
- adjust context
- no need to change the comment]

---
 drivers/regulator/core.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/regulator/core.c +2 -0
index c18f0fd..0d71557 100644
@@ -1395,12 +1395,14 @@ void regulator_put(struct regulator *regulator)
 		device_remove_file(regulator->dev, &regulator->dev_attr);
 		kfree(regulator->dev_attr.attr.name);
 	}
+	mutex_lock(&rdev->mutex);
 	kfree(regulator->supply_name);
 	list_del(&regulator->list);
 	kfree(regulator);
 
 	rdev->open_count--;
 	rdev->exclusive = 0;
+	mutex_unlock(&rdev->mutex);
 
 	module_put(rdev->owner);
 	mutex_unlock(&regulator_list_mutex);
Signature · 1 line
1.9.1
#128 lore raw

PATCH 119/176 powerpc/xmon: Fix another endiannes issue in RTAS call from xmon

In reply to [email protected]

From: Laurent Dufour <[email protected]>

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

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

commit e6eb2eba494d6f99e69ca3c3748cd37a2544ab38 upstream.

The commit 3b8a3c010969 ("powerpc/pseries: Fix endiannes issue in RTAS call from xmon") was fixing an endianness issue in the call made from xmon to RTAS.

However, as Michael Ellerman noticed, this fix was not complete, the token value was not byte swapped. This lead to call an unexpected and most of the time unexisting RTAS function, which is silently ignored by RTAS.

This fix addresses this hole.

---
 arch/powerpc/xmon/xmon.c | 1 +
 1 file changed, 1 insertion(+)
arch/powerpc/xmon/xmon.c +1 -0
index 3c3fc92..7729c6c 100644
@@ -285,6 +285,7 @@ static inline void disable_surveillance(void)
 	args.token = rtas_token("set-indicator");
 	if (args.token == RTAS_UNKNOWN_SERVICE)
 		return;
+	args.token = cpu_to_be32(args.token);
 	args.nargs = cpu_to_be32(3);
 	args.nret = cpu_to_be32(1);
 	args.rets = &args.args[3];
Signature · 1 line
1.9.1
#129 lore raw

PATCH 120/176 nl80211: fix per-station group key get/del and memory leak

In reply to [email protected]

From: Johannes Berg <[email protected]>

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

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

commit 0fa7b39131576dd1baa6ca17fca53c65d7f62249 upstream.

In case userspace attempts to obtain key information for or delete a unicast key, this is currently erroneously rejected unless the driver sets the WIPHY_FLAG_IBSS_RSN flag. Apparently enough drivers do so it was never noticed.

Fix that, and while at it fix a potential memory leak: the error path in the get_key() function was placed after allocating a message but didn't free it - move it to a better place. Luckily admin permissions are needed to call this operation.

Fixes e31b82136d1ad ("cfg80211/mac80211: allow per-station GTKs")
[lizf: Backported to 3.4: adjust context]
---
 net/wireless/nl80211.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)
net/wireless/nl80211.c +4 -5
index 52646f9..63c1807 100644
@@ -1868,6 +1868,9 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
 	if (!rdev->ops->get_key)
 		return -EOPNOTSUPP;
 
+	if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
+		return -ENOENT;
+
 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 	if (!msg)
 		return -ENOMEM;
@@ -1885,10 +1888,6 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
 	if (mac_addr)
 		NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
 
-	if (pairwise && mac_addr &&
-	    !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
-		return -ENOENT;
-
 	err = rdev->ops->get_key(&rdev->wiphy, dev, key_idx, pairwise,
 				 mac_addr, &cookie, get_key_callback);
 
@@ -2060,7 +2059,7 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
 	wdev_lock(dev->ieee80211_ptr);
 	err = nl80211_key_allowed(dev->ieee80211_ptr);
 
-	if (key.type == NL80211_KEYTYPE_PAIRWISE && mac_addr &&
+	if (key.type == NL80211_KEYTYPE_GROUP && mac_addr &&
 	    !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
 		err = -ENOENT;
 
Signature · 1 line
1.9.1
#130 lore raw

PATCH 121/176 usb-storage/SCSI: Add broken_fua blacklist flag

In reply to [email protected]

From: Alan Stern <[email protected]>

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

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

commit b14bf2d0c0358140041d1c1805a674376964d0e0 upstream.

Some buggy JMicron USB-ATA bridges don't know how to translate the FUA bit in READs or WRITEs. This patch adds an entry in unusual_devs.h and a blacklist flag to tell the sd driver not to use FUA.

---
 drivers/scsi/sd.c                  | 5 ++++-
 drivers/usb/storage/scsiglue.c     | 4 ++++
 drivers/usb/storage/unusual_devs.h | 7 +++++++
 include/linux/usb_usual.h          | 4 +++-
 include/scsi/scsi_device.h         | 1 +
 5 files changed, 19 insertions(+), 2 deletions(-)
drivers/scsi/sd.c +4 -1
index 05973a4..7f6746a 100644
@@ -2238,7 +2238,10 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
 		}
 
 		sdkp->DPOFUA = (data.device_specific & 0x10) != 0;
-		if (sdkp->DPOFUA && !sdkp->device->use_10_for_rw) {
+		if (sdp->broken_fua) {
+			sd_printk(KERN_NOTICE, sdkp, "Disabling FUA\n");
+			sdkp->DPOFUA = 0;
+		} else if (sdkp->DPOFUA && !sdkp->device->use_10_for_rw) {
 			sd_printk(KERN_NOTICE, sdkp,
 				  "Uses READ/WRITE(6), disabling FUA\n");
 			sdkp->DPOFUA = 0;
drivers/usb/storage/scsiglue.c +4 -0
index 3a7fd6f..248a198 100644
@@ -242,6 +242,10 @@ static int slave_configure(struct scsi_device *sdev)
 					US_FL_SCM_MULT_TARG)) &&
 				us->protocol == USB_PR_BULK)
 			us->use_last_sector_hacks = 1;
+
+		/* A few buggy USB-ATA bridges don't understand FUA */
+		if (us->fflags & US_FL_BROKEN_FUA)
+			sdev->broken_fua = 1;
 	} else {
 
 		/* Non-disk-type devices don't need to blacklist any pages
drivers/usb/storage/unusual_devs.h +7 -0
index a280945..e404189 100644
@@ -1940,6 +1940,13 @@ UNUSUAL_DEV(  0x14cd, 0x6600, 0x0201, 0x0201,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
+/* Reported by Michael Büsch <[email protected]> */
+UNUSUAL_DEV(  0x152d, 0x0567, 0x0114, 0x0114,
+		"JMicron",
+		"USB to ATA/ATAPI Bridge",
+		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+		US_FL_BROKEN_FUA ),
+
 /* Reported by Alexandre Oliva <[email protected]>
  * JMicron responds to USN and several other SCSI ioctls with a
  * residue that causes subsequent I/O requests to fail.  */
include/linux/usb_usual.h +3 -1
index 17df360..f2000e9 100644
@@ -64,7 +64,9 @@
 	US_FLAG(NO_READ_CAPACITY_16,	0x00080000)		\
 		/* cannot handle READ_CAPACITY_16 */		\
 	US_FLAG(INITIAL_READ10,	0x00100000)			\
-		/* Initial READ(10) (and others) must be retried */
+		/* Initial READ(10) (and others) must be retried */	\
+	US_FLAG(BROKEN_FUA,	0x01000000)			\
+		/* Cannot handle FUA in WRITE or READ CDBs */	\
 
 #define US_FLAG(name, value)	US_FL_##name = value ,
 enum { US_DO_ALL_FLAGS };
include/scsi/scsi_device.h +1 -0
index ba96988..d2f5f44 100644
@@ -153,6 +153,7 @@ struct scsi_device {
 	unsigned no_read_capacity_16:1; /* Avoid READ_CAPACITY_16 cmds */
 	unsigned try_rc_10_first:1;	/* Try READ_CAPACACITY_10 first */
 	unsigned is_visible:1;	/* is the device visible in sysfs */
+	unsigned broken_fua:1;		/* Don't set FUA bit */
 
 	DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */
 	struct list_head event_list;	/* asserted events */
Signature · 1 line
1.9.1
#131 lore raw

PATCH 122/176 usb-storage/SCSI: blacklist FUA on JMicron 152d:2566 USB-SATA controller

In reply to [email protected]

From: Dmitry Nezhevenko <[email protected]>

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

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

commit bf5c4136fa5ce471bdbf4cf59a813e32755fd014 upstream.

It looks like FUA support is broken on JMicron 152d:2566 bridge:

[223159.885704] sd 7:0:0:0: [sdc] Write Protect is off
[223159.885706] sd 7:0:0:0: [sdc] Mode Sense: 47 00 10 08
[223159.885942] sd 7:0:0:0: [sdc] Write cache: enabled, read cache: enabled, supports DPO and FUA
[223283.691677] sd 7:0:0:0: [sdc]
[223283.691680] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[223283.691681] sd 7:0:0:0: [sdc]
[223283.691682] Sense Key : Illegal Request [current]
[223283.691684] sd 7:0:0:0: [sdc]
[223283.691685] Add. Sense: Invalid field in cdb
[223283.691686] sd 7:0:0:0: [sdc] CDB:
[223283.691687] Write(10): 2a 08 15 d0 83 0d 00 00 01 00
[223283.691690] blk_update_request: critical target error, dev sdc, sector 2927892584

This patch adds blacklist flag so that sd will not use FUA

---
 drivers/usb/storage/unusual_devs.h | 7 +++++++
 1 file changed, 7 insertions(+)
drivers/usb/storage/unusual_devs.h +7 -0
index e404189..25174be 100644
@@ -1956,6 +1956,13 @@ UNUSUAL_DEV(  0x152d, 0x2329, 0x0100, 0x0100,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE | US_FL_SANE_SENSE ),
 
+/* Reported by Dmitry Nezhevenko <[email protected]> */
+UNUSUAL_DEV(  0x152d, 0x2566, 0x0114, 0x0114,
+		"JMicron",
+		"USB to ATA/ATAPI Bridge",
+		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+		US_FL_BROKEN_FUA ),
+
 /* Entrega Technologies U1-SC25 (later Xircom PortGear PGSCSI)
  * and Mac USB Dock USB-SCSI */
 UNUSUAL_DEV(  0x1645, 0x0007, 0x0100, 0x0133,
Signature · 1 line
1.9.1
#132 lore raw

PATCH 123/176 usb-core bInterval quirk

In reply to [email protected]

From: James P Michels III <[email protected]>

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

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

commit cd83ce9e6195aa3ea15ab4db92892802c20df5d0 upstream.

This patch adds a usb quirk to support devices with interupt endpoints and bInterval values expressed as microframes. The quirk causes the parse endpoint function to modify the reported bInterval to a standards conforming value.

There is currently code in the endpoint parser that checks for bIntervals that are outside of the valid range (1-16 for USB 2+ high speed and super speed interupt endpoints). In this case, the code assumes the bInterval is being reported in 1ms frames. As well, the correction is only applied if the original bInterval value is out of the 1-16 range.

With this quirk applied to the device, the bInterval will be accurately adjusted from microframes to an exponent.

---
 drivers/usb/core/config.c  | 11 +++++++++++
 drivers/usb/core/quirks.c  |  4 ++++
 include/linux/usb/quirks.h | 11 +++++++++++
 3 files changed, 26 insertions(+)
drivers/usb/core/config.c +11 -0
index 6ed7e7c..cc1004a 100644
@@ -201,6 +201,17 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
 			if (n == 0)
 				n = 9;	/* 32 ms = 2^(9-1) uframes */
 			j = 16;
+
+			/*
+			 * Adjust bInterval for quirked devices.
+			 * This quirk fixes bIntervals reported in
+			 * linear microframes.
+			 */
+			if (to_usb_device(ddev)->quirks &
+				USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL) {
+				n = clamp(fls(d->bInterval), i, j);
+				i = j = n;
+			}
 			break;
 		default:		/* USB_SPEED_FULL or _LOW */
 			/* For low-speed, 10 ms is the official minimum.
drivers/usb/core/quirks.c +4 -0
index ada0df9..a60c5b7 100644
@@ -152,6 +152,10 @@ static const struct usb_device_id usb_quirk_list[] = {
 	/* SKYMEDI USB_DRIVE */
 	{ USB_DEVICE(0x1516, 0x8628), .driver_info = USB_QUIRK_RESET_RESUME },
 
+	/* Razer - Razer Blade Keyboard */
+	{ USB_DEVICE(0x1532, 0x0116), .driver_info =
+			USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
+
 	/* BUILDWIN Photo Frame */
 	{ USB_DEVICE(0x1908, 0x1315), .driver_info =
 			USB_QUIRK_HONOR_BNUMINTERFACES },
include/linux/usb/quirks.h +11 -0
index d0d2af0..0972470 100644
@@ -36,4 +36,15 @@
 /* device can't handle device_qualifier descriptor requests */
 #define USB_QUIRK_DEVICE_QUALIFIER	0x00000100
 
+/*
+ * For high speed and super speed interupt endpoints, the USB 2.0 and
+ * USB 3.0 spec require the interval in microframes
+ * (1 microframe = 125 microseconds) to be calculated as
+ * interval = 2 ^ (bInterval-1).
+ *
+ * Devices with this quirk report their bInterval as the result of this
+ * calculation instead of the exponent variable used in the calculation.
+ */
+#define USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL	0x00000080
+
 #endif /* __LINUX_USB_QUIRKS_H */
Signature · 1 line
1.9.1
#133 lore raw

PATCH 124/176 USB: Add OTG PET device to TPL

In reply to [email protected]

From: Macpaul Lin <[email protected]>

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

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

commit e5dff0e80463cc3fa236e898ef1491b40be70b19 upstream.

OTG device shall support this device for allowing compliance automated testing. The modification is derived from Pavankumar and Vijayavardhans' previous work.

Cc Pavankumar Kondeti <[email protected]>
Cc Vijayavardhan Vennapusa <[email protected]>
---
 drivers/usb/core/otg_whitelist.h | 5 +++++
 drivers/usb/core/quirks.c        | 4 ++++
 2 files changed, 9 insertions(+)
drivers/usb/core/otg_whitelist.h +5 -0
index e8cdce5..2753cec 100644
@@ -59,6 +59,11 @@ static int is_targeted(struct usb_device *dev)
 	     le16_to_cpu(dev->descriptor.idProduct) == 0xbadd))
 		return 0;
 
+	/* OTG PET device is always targeted (see OTG 2.0 ECN 6.4.2) */
+	if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a &&
+	     le16_to_cpu(dev->descriptor.idProduct) == 0x0200))
+		return 1;
+
 	/* NOTE: can't use usb_match_id() since interface caches
 	 * aren't set up yet. this is cut/paste from that code.
 	 */
drivers/usb/core/quirks.c +4 -0
index a60c5b7..9fac46d 100644
@@ -175,6 +175,10 @@ static const struct usb_device_id usb_interface_quirk_list[] = {
 	{ USB_DEVICE(0x0b05, 0x17e0), .driver_info =
 			USB_QUIRK_IGNORE_REMOTE_WAKEUP },
 
+	/* Protocol and OTG Electrical Test Device */
+	{ USB_DEVICE(0x1a0a, 0x0200), .driver_info =
+			USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
+
 	{ }  /* terminating entry must be last */
 };
 
Signature · 1 line
1.9.1
#134 lore raw

PATCH 125/176 drm/i915: Only fence tiled region of object.

In reply to [email protected]

From: Bob Paauwe <[email protected]>

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

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

commit af1a7301c7cf8912dca03065d448c4437c5c239f upstream.

When creating a fence for a tiled object, only fence the area that makes up the actual tiles. The object may be larger than the tiled area and if we allow those extra addresses to be fenced, they'll get converted to addresses beyond where the object is mapped. This opens up the possiblity of writes beyond the end of object.

To prevent this, we adjust the size of the fence to only encompass the area that makes up the actual tiles. The extra space is considered un-tiled and now behaves as if it was a linear object.

Testcase: igt/gem_tiled_fence_overflow

[lizf: Backported to 3.4:
- adjust context
- adjust indentation
- make the same change to both sandybridge_write_fence_reg() and i965_write_fence_reg()]

---
 drivers/gpu/drm/i915/i915_gem.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
drivers/gpu/drm/i915/i915_gem.c +14 -0
index 2ac4ded..b1f1d10 100644
@@ -2193,6 +2193,13 @@ static int sandybridge_write_fence_reg(struct drm_i915_gem_object *obj,
 	int regnum = obj->fence_reg;
 	uint64_t val;
 
+	/* Adjust fence size to match tiled area */
+	if (obj->tiling_mode != I915_TILING_NONE) {
+		uint32_t row_size = obj->stride *
+			(obj->tiling_mode == I915_TILING_Y ? 32 : 8);
+		size = (size / row_size) * row_size;
+	}
+
 	val = (uint64_t)((obj->gtt_offset + size - 4096) &
 			 0xfffff000) << 32;
 	val |= obj->gtt_offset & 0xfffff000;
@@ -2230,6 +2237,13 @@ static int i965_write_fence_reg(struct drm_i915_gem_object *obj,
 	int regnum = obj->fence_reg;
 	uint64_t val;
 
+	/* Adjust fence size to match tiled area */
+	if (obj->tiling_mode != I915_TILING_NONE) {
+		uint32_t row_size = obj->stride *
+			(obj->tiling_mode == I915_TILING_Y ? 32 : 8);
+		size = (size / row_size) * row_size;
+	}
+
 	val = (uint64_t)((obj->gtt_offset + size - 4096) &
 		    0xfffff000) << 32;
 	val |= obj->gtt_offset & 0xfffff000;
Signature · 1 line
1.9.1
#135 lore raw

PATCH 126/176 ALSA: seq-dummy: remove deadlock-causing events on close

In reply to [email protected]

From: Clemens Ladisch <[email protected]>

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

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

commit 0767e95bb96d7fdddcd590fb809e6975d93aebc5 upstream.

When the last subscriber to a "Through" port has been removed, the subscribed destination ports might still be active, so it would be wrong to send "all sounds off" and "reset controller" events to them. The proper place for such a shutdown would be the closing of the actual MIDI port (and close_substream() in rawmidi.c already can do this).

This also fixes a deadlock when dummy_unuse() tries to send events to its own port that is already locked because it is being freed.

---
 sound/core/seq/seq_dummy.c | 31 -------------------------------
 1 file changed, 31 deletions(-)
sound/core/seq/seq_dummy.c +0 -31
index dbc5507..f60d814 100644
@@ -82,36 +82,6 @@ struct snd_seq_dummy_port {
 static int my_client = -1;
 
 /*
- * unuse callback - send ALL_SOUNDS_OFF and RESET_CONTROLLERS events
- * to subscribers.
- * Note: this callback is called only after all subscribers are removed.
- */
-static int
-dummy_unuse(void *private_data, struct snd_seq_port_subscribe *info)
-{
-	struct snd_seq_dummy_port *p;
-	int i;
-	struct snd_seq_event ev;
-
-	p = private_data;
-	memset(&ev, 0, sizeof(ev));
-	if (p->duplex)
-		ev.source.port = p->connect;
-	else
-		ev.source.port = p->port;
-	ev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS;
-	ev.type = SNDRV_SEQ_EVENT_CONTROLLER;
-	for (i = 0; i < 16; i++) {
-		ev.data.control.channel = i;
-		ev.data.control.param = MIDI_CTL_ALL_SOUNDS_OFF;
-		snd_seq_kernel_client_dispatch(p->client, &ev, 0, 0);
-		ev.data.control.param = MIDI_CTL_RESET_CONTROLLERS;
-		snd_seq_kernel_client_dispatch(p->client, &ev, 0, 0);
-	}
-	return 0;
-}
-
-/*
  * event input callback - just redirect events to subscribers
  */
 static int
@@ -175,7 +145,6 @@ create_port(int idx, int type)
 		| SNDRV_SEQ_PORT_TYPE_PORT;
 	memset(&pcb, 0, sizeof(pcb));
 	pcb.owner = THIS_MODULE;
-	pcb.unuse = dummy_unuse;
 	pcb.event_input = dummy_input;
 	pcb.private_free = dummy_free;
 	pcb.private_data = rec;
Signature · 1 line
1.9.1
#136 lore raw

PATCH 127/176 net: sctp: fix slab corruption from use after free on INIT collisions

In reply to [email protected]

From: Daniel Borkmann <[email protected]>

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

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

commit 600ddd6825543962fb807884169e57b580dba208 upstream.

When hitting an INIT collision case during the 4WHS with AUTH enabled, as already described in detail in commit 1be9a950c646 ("net: sctp: inherit auth_capable on INIT collisions"), it can happen that we occasionally still remotely trigger the following panic on server side which seems to have been uncovered after the fix from commit 1be9a950c646 ...

[  533.876389] BUG: unable to handle kernel paging request at 00000000ffffffff
[  533.913657] IP: [<ffffffff811ac385>] __kmalloc+0x95/0x230
[  533.940559] PGD 5030f2067 PUD 0
[  533.957104] Oops: 0000 [#1] SMP
[  533.974283] Modules linked in: sctp mlx4_en [...]
[  534.939704] Call Trace:
[  534.951833]  [<ffffffff81294e30>] ? crypto_init_shash_ops+0x60/0xf0
[  534.984213]  [<ffffffff81294e30>] crypto_init_shash_ops+0x60/0xf0
[  535.015025]  [<ffffffff8128c8ed>] __crypto_alloc_tfm+0x6d/0x170
[  535.045661]  [<ffffffff8128d12c>] crypto_alloc_base+0x4c/0xb0
[  535.074593]  [<ffffffff8160bd42>] ? _raw_spin_lock_bh+0x12/0x50
[  535.105239]  [<ffffffffa0418c11>] sctp_inet_listen+0x161/0x1e0 [sctp]
[  535.138606]  [<ffffffff814e43bd>] SyS_listen+0x9d/0xb0
[  535.166848]  [<ffffffff816149a9>] system_call_fastpath+0x16/0x1b

... or depending on the the application, for example this one:

[ 1370.026490] BUG: unable to handle kernel paging request at 00000000ffffffff
[ 1370.026506] IP: [<ffffffff811ab455>] kmem_cache_alloc+0x75/0x1d0
[ 1370.054568] PGD 633c94067 PUD 0
[ 1370.070446] Oops: 0000 [#1] SMP
[ 1370.085010] Modules linked in: sctp kvm_amd kvm [...]
[ 1370.963431] Call Trace:
[ 1370.974632]  [<ffffffff8120f7cf>] ? SyS_epoll_ctl+0x53f/0x960
[ 1371.000863]  [<ffffffff8120f7cf>] SyS_epoll_ctl+0x53f/0x960
[ 1371.027154]  [<ffffffff812100d3>] ? anon_inode_getfile+0xd3/0x170
[ 1371.054679]  [<ffffffff811e3d67>] ? __alloc_fd+0xa7/0x130
[ 1371.080183]  [<ffffffff816149a9>] system_call_fastpath+0x16/0x1b

With slab debugging enabled, we can see that the poison has been overwritten:

[  669.826368] BUG kmalloc-128 (Tainted: G        W     ): Poison overwritten
[  669.826385] INFO: 0xffff880228b32e50-0xffff880228b32e50. First byte 0x6a instead of 0x6b
[  669.826414] INFO: Allocated in sctp_auth_create_key+0x23/0x50 [sctp] age=3 cpu=0 pid=18494
[  669.826424]  __slab_alloc+0x4bf/0x566
[  669.826433]  __kmalloc+0x280/0x310
[  669.826453]  sctp_auth_create_key+0x23/0x50 [sctp]
[  669.826471]  sctp_auth_asoc_create_secret+0xcb/0x1e0 [sctp]
[  669.826488]  sctp_auth_asoc_init_active_key+0x68/0xa0 [sctp]
[  669.826505]  sctp_do_sm+0x29d/0x17c0 [sctp] [...]
[  669.826629] INFO: Freed in kzfree+0x31/0x40 age=1 cpu=0 pid=18494
[  669.826635]  __slab_free+0x39/0x2a8
[  669.826643]  kfree+0x1d6/0x230
[  669.826650]  kzfree+0x31/0x40
[  669.826666]  sctp_auth_key_put+0x19/0x20 [sctp]
[  669.826681]  sctp_assoc_update+0x1ee/0x2d0 [sctp]
[  669.826695]  sctp_do_sm+0x674/0x17c0 [sctp]

Since this only triggers in some collision-cases with AUTH, the problem at heart is that sctp_auth_key_put() on asoc->asoc_shared_key is called twice when having refcnt 1, once directly in sctp_assoc_update() and yet again from within sctp_auth_asoc_init_active_key() via sctp_assoc_update() on the already kzfree'd memory, which is also consistent with the observation of the poison decrease from 0x6b to 0x6a (note: the overwrite is detected at a later point in time when poison is checked on new allocation).

Reference counting of auth keys revisited:

Shared keys for AUTH chunks are being stored in endpoints and associations in endpoint_shared_keys list. On endpoint creation, a null key is being added; on association creation, all endpoint shared keys are being cached and thus cloned over to the association. struct sctp_shared_key only holds a pointer to the actual key bytes, that is, struct sctp_auth_bytes which keeps track of users internally through refcounting. Naturally, on assoc or enpoint destruction, sctp_shared_key are being destroyed directly and the reference on sctp_auth_bytes dropped.

User space can add keys to either list via setsockopt(2) through struct sctp_authkey and by passing that to sctp_auth_set_key() which replaces or adds a new auth key. There, sctp_auth_create_key() creates a new sctp_auth_bytes with refcount 1 and in case of replacement drops the reference on the old sctp_auth_bytes. A key can be set active from user space through setsockopt() on the id via sctp_auth_set_active_key(), which iterates through either endpoint_shared_keys and in case of an assoc, invokes (one of various places) sctp_auth_asoc_init_active_key().

sctp_auth_asoc_init_active_key() computes the actual secret from local's and peer's random, hmac and shared key parameters and returns a new key directly as sctp_auth_bytes, that is asoc->asoc_shared_key, plus drops the reference if there was a previous one. The secret, which where we eventually double drop the ref comes from sctp_auth_asoc_set_secret() with intitial refcount of 1, which also stays unchanged eventually in sctp_assoc_update(). This key is later being used for crypto layer to set the key for the hash in crypto_hash_setkey() from sctp_auth_calculate_hmac().

To close the loop: asoc->asoc_shared_key is freshly allocated secret material and independant of the sctp_shared_key management keeping track of only shared keys in endpoints and assocs. Hence, also commit 4184b2a79a76 ("net: sctp: fix memory leak in auth key management") is independant of this bug here since it concerns a different layer (though same structures being used eventually). asoc->asoc_shared_key is reference dropped correctly on assoc destruction in sctp_association_free() and when active keys are being replaced in sctp_auth_asoc_init_active_key(), it always has a refcount of 1. Hence, it's freed prematurely in sctp_assoc_update(). Simple fix is to remove that sctp_auth_key_put() from there which fixes these panics.

Fixes 730fc3d05cd4 ("[SCTP]: Implete SCTP-AUTH parameter processing")
---
 net/sctp/associola.c | 1 -
 1 file changed, 1 deletion(-)
net/sctp/associola.c +0 -1
index da54d29..c37dbef 100644
@@ -1272,7 +1272,6 @@ void sctp_assoc_update(struct sctp_association *asoc,
 	asoc->peer.peer_hmacs = new->peer.peer_hmacs;
 	new->peer.peer_hmacs = NULL;
 
-	sctp_auth_key_put(asoc->asoc_shared_key);
 	sctp_auth_asoc_init_active_key(asoc, GFP_ATOMIC);
 }
 
Signature · 1 line
1.9.1
#137 lore raw

PATCH 128/176 ipv6: replacing a rt6_info needs to purge possible propagated rt6_infos too

In reply to [email protected]

From: Hannes Frederic Sowa <[email protected]>

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

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

commit 6e9e16e6143b725662e47026a1d0f270721cdd24 upstream.

Lubomir Rintel reported that during replacing a route the interface reference counter isn't correctly decremented.

To quote bug <https://bugzilla.kernel.org/show_bug.cgi?id=91941>:

| [root@rhel7-5 lkundrak]# sh -x lal
| + ip link add dev0 type dummy
| + ip link set dev0 up
| + ip link add dev1 type dummy
| + ip link set dev1 up
| + ip addr add 2001:db8:8086::2/64 dev dev0
| + ip route add 2001:db8:8086::/48 dev dev0 proto static metric 20
| + ip route add 2001:db8:8088::/48 dev dev1 proto static metric 10
| + ip route replace 2001:db8:8086::/48 dev dev1 proto static metric 20
| + ip link del dev0 type dummy
| Message from syslogd@rhel7-5 at Jan 23 10:54:41 ...
|  kernel:unregister_netdevice: waiting for dev0 to become free. Usage count = 2
|
| Message from syslogd@rhel7-5 at Jan 23 10:54:51 ...
|  kernel:unregister_netdevice: waiting for dev0 to become free. Usage count = 2

During replacement of a rt6_info we must walk all parent nodes and check if the to be replaced rt6_info got propagated. If so, replace it with an alive one.

Fixes 4a287eba2de3957 ("IPv6 routing, NLM_F_* flag support: REPLACE and EXCL flags support, warn about missing CREATE flag")
---
 net/ipv6/ip6_fib.c | 45 ++++++++++++++++++++++++++-------------------
 1 file changed, 26 insertions(+), 19 deletions(-)
net/ipv6/ip6_fib.c +26 -19
index 5bb77a6..2cfcfb7 100644
@@ -633,6 +633,29 @@ insert_above:
 	return ln;
 }
 
+static void fib6_purge_rt(struct rt6_info *rt, struct fib6_node *fn,
+			  struct net *net)
+{
+	if (atomic_read(&rt->rt6i_ref) != 1) {
+		/* This route is used as dummy address holder in some split
+		 * nodes. It is not leaked, but it still holds other resources,
+		 * which must be released in time. So, scan ascendant nodes
+		 * and replace dummy references to this route with references
+		 * to still alive ones.
+		 */
+		while (fn) {
+			if (!(fn->fn_flags & RTN_RTINFO) && fn->leaf == rt) {
+				fn->leaf = fib6_find_prefix(net, fn);
+				atomic_inc(&fn->leaf->rt6i_ref);
+				rt6_release(rt);
+			}
+			fn = fn->parent;
+		}
+		/* No more references are possible at this point. */
+		BUG_ON(atomic_read(&rt->rt6i_ref) != 1);
+	}
+}
+
 /*
  *	Insert routing information in a node.
  */
@@ -723,11 +746,12 @@ add:
 		rt->dst.rt6_next = iter->dst.rt6_next;
 		atomic_inc(&rt->rt6i_ref);
 		inet6_rt_notify(RTM_NEWROUTE, rt, info);
-		rt6_release(iter);
 		if (!(fn->fn_flags & RTN_RTINFO)) {
 			info->nl_net->ipv6.rt6_stats->fib_route_nodes++;
 			fn->fn_flags |= RTN_RTINFO;
 		}
+		fib6_purge_rt(iter, fn, info->nl_net);
+		rt6_release(iter);
 	}
 
 	return 0;
@@ -1229,24 +1253,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
 		fn = fib6_repair_tree(net, fn);
 	}
 
-	if (atomic_read(&rt->rt6i_ref) != 1) {
-		/* This route is used as dummy address holder in some split
-		 * nodes. It is not leaked, but it still holds other resources,
-		 * which must be released in time. So, scan ascendant nodes
-		 * and replace dummy references to this route with references
-		 * to still alive ones.
-		 */
-		while (fn) {
-			if (!(fn->fn_flags & RTN_RTINFO) && fn->leaf == rt) {
-				fn->leaf = fib6_find_prefix(net, fn);
-				atomic_inc(&fn->leaf->rt6i_ref);
-				rt6_release(rt);
-			}
-			fn = fn->parent;
-		}
-		/* No more references are possible at this point. */
-		BUG_ON(atomic_read(&rt->rt6i_ref) != 1);
-	}
+	fib6_purge_rt(rt, fn, net);
 
 	inet6_rt_notify(RTM_DELROUTE, rt, info);
 	rt6_release(rt);
Signature · 1 line
1.9.1
#138 lore raw

PATCH 129/176 vm: add VM_FAULT_SIGSEGV handling support

In reply to [email protected]

From: Linus Torvalds <[email protected]>

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

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

commit 33692f27597fcab536d7cbbcc8f52905133e4aa7 upstream.

The core VM already knows about VM_FAULT_SIGBUS, but cannot return a "you should SIGSEGV" error, because the SIGSEGV case was generally handled by the caller - usually the architecture fault handler.

That results in lots of duplication - all the architecture fault handlers end up doing very similar "look up vma, check permissions, do retries etc" - but it generally works. However, there are cases where the VM actually wants to SIGSEGV, and applications _expect_ SIGSEGV.

In particular, when accessing the stack guard page, libsigsegv expects a SIGSEGV. And it usually got one, because the stack growth is handled by that duplicated architecture fault handler.

However, when the generic VM layer started propagating the error return from the stack expansion in commit fee7e49d4514 ("mm: propagate error from stack expansion even for guard page"), that now exposed the existing VM_FAULT_SIGBUS result to user space. And user space really expected SIGSEGV, not SIGBUS.

To fix that case, we need to add a VM_FAULT_SIGSEGV, and teach all those duplicate architecture fault handlers about it. They all already have the code to handle SIGSEGV, so it's about just tying that new return value to the existing code, but it's all a bit annoying.

This is the mindless minimal patch to do this. A more extensive patch would be to try to gather up the mostly shared fault handling logic into one generic helper routine, and long-term we really should do that cleanup.

Just from this patch, you can generally see that most architectures just copied (directly or indirectly) the old x86 way of doing things, but in the meantime that original x86 model has been improved to hold the VM semaphore for shorter times etc and to handle VM_FAULT_RETRY and other "newer" things, so it would be a good idea to bring all those improvements to the generic case and teach other architectures about them too.

[bwh: Backported to 3.2:
- Adjust filenames, context
- Drop arc, metag, nios2 and lustre changes
- For sh, patch both 32-bit and 64-bit implementations to use goto bad_area
- For s390, pass int_code and trans_exc_code as arguments to do_no_context() and do_sigsegv()]

[lizf: Backported to 3.4: adjust context in arch/power/mm/fault.c]
---
 arch/alpha/mm/fault.c                   | 2 ++
 arch/avr32/mm/fault.c                   | 2 ++
 arch/cris/mm/fault.c                    | 2 ++
 arch/frv/mm/fault.c                     | 2 ++
 arch/ia64/mm/fault.c                    | 2 ++
 arch/m32r/mm/fault.c                    | 2 ++
 arch/m68k/mm/fault.c                    | 2 ++
 arch/microblaze/mm/fault.c              | 2 ++
 arch/mips/mm/fault.c                    | 2 ++
 arch/mn10300/mm/fault.c                 | 2 ++
 arch/openrisc/mm/fault.c                | 2 ++
 arch/parisc/mm/fault.c                  | 2 ++
 arch/powerpc/mm/fault.c                 | 6 +++++-
 arch/powerpc/platforms/cell/spu_fault.c | 2 +-
 arch/s390/mm/fault.c                    | 7 +++++++
 arch/score/mm/fault.c                   | 2 ++
 arch/sh/mm/fault_32.c                   | 2 ++
 arch/sh/mm/tlbflush_64.c                | 2 ++
 arch/sparc/mm/fault_32.c                | 2 ++
 arch/sparc/mm/fault_64.c                | 2 ++
 arch/tile/mm/fault.c                    | 2 ++
 arch/um/kernel/trap.c                   | 2 ++
 arch/x86/mm/fault.c                     | 2 ++
 arch/xtensa/mm/fault.c                  | 2 ++
 include/linux/mm.h                      | 5 +++--
 mm/ksm.c                                | 2 +-
 mm/memory.c                             | 4 ++--
 27 files changed, 61 insertions(+), 7 deletions(-)
arch/alpha/mm/fault.c +2 -0
index 5eecab1..f153733 100644
@@ -149,6 +149,8 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
+		else if (fault & VM_FAULT_SIGSEGV)
+			goto bad_area;
 		else if (fault & VM_FAULT_SIGBUS)
 			goto do_sigbus;
 		BUG();
arch/avr32/mm/fault.c +2 -0
index f7040a1..632b649 100644
@@ -136,6 +136,8 @@ good_area:
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
+		else if (fault & VM_FAULT_SIGSEGV)
+			goto bad_area;
 		else if (fault & VM_FAULT_SIGBUS)
 			goto do_sigbus;
 		BUG();
arch/cris/mm/fault.c +2 -0
index b4760d8..b07c00c 100644
@@ -167,6 +167,8 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
+		else if (fault & VM_FAULT_SIGSEGV)
+			goto bad_area;
 		else if (fault & VM_FAULT_SIGBUS)
 			goto do_sigbus;
 		BUG();
arch/frv/mm/fault.c +2 -0
index 331c1e2..8545496 100644
@@ -166,6 +166,8 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
+		else if (fault & VM_FAULT_SIGSEGV)
+			goto bad_area;
 		else if (fault & VM_FAULT_SIGBUS)
 			goto do_sigbus;
 		BUG();
arch/ia64/mm/fault.c +2 -0
index 02d29c2..3c820ea 100644
@@ -162,6 +162,8 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
 		 */
 		if (fault & VM_FAULT_OOM) {
 			goto out_of_memory;
+		} else if (fault & VM_FAULT_SIGSEGV) {
+			goto bad_area;
 		} else if (fault & VM_FAULT_SIGBUS) {
 			signal = SIGBUS;
 			goto bad_area;
arch/m32r/mm/fault.c +2 -0
index 3cdfa9c..06827fc 100644
@@ -198,6 +198,8 @@ good_area:
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
+		else if (fault & VM_FAULT_SIGSEGV)
+			goto bad_area;
 		else if (fault & VM_FAULT_SIGBUS)
 			goto do_sigbus;
 		BUG();
arch/m68k/mm/fault.c +2 -0
index 6b020a8..8646409 100644
@@ -146,6 +146,8 @@ good_area:
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
+		else if (fault & VM_FAULT_SIGSEGV)
+			goto map_err;
 		else if (fault & VM_FAULT_SIGBUS)
 			goto bus_err;
 		BUG();
arch/microblaze/mm/fault.c +2 -0
index c38a265..c7fe3da 100644
@@ -214,6 +214,8 @@ good_area:
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
+		else if (fault & VM_FAULT_SIGSEGV)
+			goto bad_area;
 		else if (fault & VM_FAULT_SIGBUS)
 			goto do_sigbus;
 		BUG();
arch/mips/mm/fault.c +2 -0
index c14f6df..5c9ba6a 100644
@@ -155,6 +155,8 @@ good_area:
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
+		else if (fault & VM_FAULT_SIGSEGV)
+			goto bad_area;
 		else if (fault & VM_FAULT_SIGBUS)
 			goto do_sigbus;
 		BUG();
arch/mn10300/mm/fault.c +2 -0
index 90f346f..eb411b3 100644
@@ -255,6 +255,8 @@ good_area:
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
+		else if (fault & VM_FAULT_SIGSEGV)
+			goto bad_area;
 		else if (fault & VM_FAULT_SIGBUS)
 			goto do_sigbus;
 		BUG();
arch/openrisc/mm/fault.c +2 -0
index a5dce82..162abfb 100644
@@ -163,6 +163,8 @@ good_area:
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
+		else if (fault & VM_FAULT_SIGSEGV)
+			goto bad_area;
 		else if (fault & VM_FAULT_SIGBUS)
 			goto do_sigbus;
 		BUG();
arch/parisc/mm/fault.c +2 -0
index 18162ce..a9b765a 100644
@@ -210,6 +210,8 @@ good_area:
 		 */
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
+		else if (fault & VM_FAULT_SIGSEGV)
+			goto bad_area;
 		else if (fault & VM_FAULT_SIGBUS)
 			goto bad_area;
 		BUG();
arch/powerpc/mm/fault.c +5 -1
index 08ffcf5..3d30a4a 100644
@@ -419,7 +419,11 @@ good_area:
 	 */
 	fault = handle_mm_fault(mm, vma, address, flags);
 	if (unlikely(fault & (VM_FAULT_RETRY|VM_FAULT_ERROR))) {
-		int rc = mm_fault_error(regs, address, fault);
+		int rc;
+
+		if (fault & VM_FAULT_SIGSEGV)
+			goto bad_area;
+		rc = mm_fault_error(regs, address, fault);
 		if (rc >= MM_FAULT_RETURN)
 			return rc;
 	}
arch/powerpc/platforms/cell/spu_fault.c +1 -1
index 641e727..62f3e4e 100644
@@ -75,7 +75,7 @@ int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea,
 		if (*flt & VM_FAULT_OOM) {
 			ret = -ENOMEM;
 			goto out_unlock;
-		} else if (*flt & VM_FAULT_SIGBUS) {
+		} else if (*flt & (VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV)) {
 			ret = -EFAULT;
 			goto out_unlock;
 		}
arch/s390/mm/fault.c +7 -0
index f2b11ee..f22603d 100644
@@ -237,6 +237,13 @@ static noinline void do_fault_error(struct pt_regs *regs, int fault)
 				do_no_context(regs);
 			else
 				pagefault_out_of_memory();
+		} else if (fault & VM_FAULT_SIGSEGV) {
+			/* Kernel mode? Handle exceptions or die */
+			if (!user_mode(regs))
+				do_no_context(regs, int_code, trans_exc_code);
+			else
+				do_sigsegv(regs, int_code, SEGV_MAPERR,
+					   trans_exc_code);
 		} else if (fault & VM_FAULT_SIGBUS) {
 			/* Kernel mode? Handle exceptions or die */
 			if (!(regs->psw.mask & PSW_MASK_PSTATE))
arch/score/mm/fault.c +2 -0
index 47b600e..b3744ca 100644
@@ -110,6 +110,8 @@ survive:
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
+		else if (fault & VM_FAULT_SIGSEGV)
+			goto bad_area;
 		else if (fault & VM_FAULT_SIGBUS)
 			goto do_sigbus;
 		BUG();
arch/sh/mm/fault_32.c +2 -0
index e99b104..a491963 100644
@@ -206,6 +206,8 @@ good_area:
 			goto out_of_memory;
 		else if (fault & VM_FAULT_SIGBUS)
 			goto do_sigbus;
+		else if (fault & VM_FAULT_SIGSEGV)
+			goto bad_area;
 		BUG();
 	}
 	if (fault & VM_FAULT_MAJOR) {
arch/sh/mm/tlbflush_64.c +2 -0
index 11c5a18..92f0df9 100644
@@ -194,6 +194,8 @@ good_area:
 			goto out_of_memory;
 		else if (fault & VM_FAULT_SIGBUS)
 			goto do_sigbus;
+		else if (fault & VM_FAULT_SIGSEGV)
+			goto bad_area;
 		BUG();
 	}
 
arch/sparc/mm/fault_32.c +2 -0
index df3155a..5c6238d 100644
@@ -300,6 +300,8 @@ good_area:
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
+		else if (fault & VM_FAULT_SIGSEGV)
+			goto bad_area;
 		else if (fault & VM_FAULT_SIGBUS)
 			goto do_sigbus;
 		BUG();
arch/sparc/mm/fault_64.c +2 -0
index 1387aca..0dc7b90 100644
@@ -443,6 +443,8 @@ good_area:
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
+		else if (fault & VM_FAULT_SIGSEGV)
+			goto bad_area;
 		else if (fault & VM_FAULT_SIGBUS)
 			goto do_sigbus;
 		BUG();
arch/tile/mm/fault.c +2 -0
index 22e58f5..a362926 100644
@@ -433,6 +433,8 @@ good_area:
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
+		else if (fault & VM_FAULT_SIGSEGV)
+			goto bad_area;
 		else if (fault & VM_FAULT_SIGBUS)
 			goto do_sigbus;
 		BUG();
arch/um/kernel/trap.c +2 -0
index dafc947..f79ffc9 100644
@@ -69,6 +69,8 @@ good_area:
 		if (unlikely(fault & VM_FAULT_ERROR)) {
 			if (fault & VM_FAULT_OOM) {
 				goto out_of_memory;
+			} else if (fault & VM_FAULT_SIGSEGV) {
+				goto out;
 			} else if (fault & VM_FAULT_SIGBUS) {
 				err = -EACCES;
 				goto out;
arch/x86/mm/fault.c +2 -0
index 4a0a2e8..b723f2e 100644
@@ -887,6 +887,8 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code,
 		if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON|
 			     VM_FAULT_HWPOISON_LARGE))
 			do_sigbus(regs, error_code, address, fault);
+		else if (fault & VM_FAULT_SIGSEGV)
+			bad_area_nosemaphore(regs, error_code, address);
 		else
 			BUG();
 	}
arch/xtensa/mm/fault.c +2 -0
index b17885a..b3877be 100644
@@ -108,6 +108,8 @@ good_area:
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
+		else if (fault & VM_FAULT_SIGSEGV)
+			goto bad_area;
 		else if (fault & VM_FAULT_SIGBUS)
 			goto do_sigbus;
 		BUG();
include/linux/mm.h +3 -2
index dacfd4a..ceebf63 100644
@@ -841,6 +841,7 @@ static inline int page_mapped(struct page *page)
 #define VM_FAULT_WRITE	0x0008	/* Special case for get_user_pages */
 #define VM_FAULT_HWPOISON 0x0010	/* Hit poisoned small page */
 #define VM_FAULT_HWPOISON_LARGE 0x0020  /* Hit poisoned large page. Index encoded in upper bits */
+#define VM_FAULT_SIGSEGV 0x0040
 
 #define VM_FAULT_NOPAGE	0x0100	/* ->fault installed the pte, not return page */
 #define VM_FAULT_LOCKED	0x0200	/* ->fault locked the returned page */
@@ -848,8 +849,8 @@ static inline int page_mapped(struct page *page)
 
 #define VM_FAULT_HWPOISON_LARGE_MASK 0xf000 /* encodes hpage index for large hwpoison */
 
-#define VM_FAULT_ERROR	(VM_FAULT_OOM | VM_FAULT_SIGBUS | VM_FAULT_HWPOISON | \
-			 VM_FAULT_HWPOISON_LARGE)
+#define VM_FAULT_ERROR	(VM_FAULT_OOM | VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV | \
+			 VM_FAULT_HWPOISON | VM_FAULT_HWPOISON_LARGE)
 
 /* Encode hstate index for a hwpoisoned large page */
 #define VM_FAULT_SET_HINDEX(x) ((x) << 12)
mm/ksm.c +1 -1
index 47c8853..77c7118 100644
@@ -342,7 +342,7 @@ static int break_ksm(struct vm_area_struct *vma, unsigned long addr)
 		else
 			ret = VM_FAULT_WRITE;
 		put_page(page);
-	} while (!(ret & (VM_FAULT_WRITE | VM_FAULT_SIGBUS | VM_FAULT_OOM)));
+	} while (!(ret & (VM_FAULT_WRITE | VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV | VM_FAULT_OOM)));
 	/*
 	 * We must loop because handle_mm_fault() may back out if there's
 	 * any difficulty e.g. if pte accessed bit gets updated concurrently.
mm/memory.c +2 -2
index c9c93e2..f573cec 100644
@@ -1787,7 +1787,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
 						else
 							return -EFAULT;
 					}
-					if (ret & VM_FAULT_SIGBUS)
+					if (ret & (VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV))
 						return i ? i : -EFAULT;
 					BUG();
 				}
@@ -1891,7 +1891,7 @@ int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm,
 			return -ENOMEM;
 		if (ret & (VM_FAULT_HWPOISON | VM_FAULT_HWPOISON_LARGE))
 			return -EHWPOISON;
-		if (ret & VM_FAULT_SIGBUS)
+		if (ret & (VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV))
 			return -EFAULT;
 		BUG();
 	}
Signature · 1 line
1.9.1
#139 lore raw

PATCH 130/176 vm: make stack guard page errors return VM_FAULT_SIGSEGV rather than SIGBUS

In reply to [email protected]

From: Linus Torvalds <[email protected]>

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

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

commit 9c145c56d0c8a0b62e48c8d71e055ad0fb2012ba upstream.

The stack guard page error case has long incorrectly caused a SIGBUS rather than a SIGSEGV, but nobody actually noticed until commit fee7e49d4514 ("mm: propagate error from stack expansion even for guard page") because that error case was never actually triggered in any normal situations.

Now that we actually report the error, people noticed the wrong signal that resulted. So far, only the test suite of libsigsegv seems to have actually cared, but there are real applications that use libsigsegv, so let's not wait for any of those to break.

---
 mm/memory.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
mm/memory.c +1 -1
index f573cec..45cd14f 100644
@@ -3175,7 +3175,7 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
 
 	/* Check if we need to add a guard page to the stack */
 	if (check_stack_guard_page(vma, address) < 0)
-		return VM_FAULT_SIGBUS;
+		return VM_FAULT_SIGSEGV;
 
 	/* Use the zero-page for reads */
 	if (!(flags & FAULT_FLAG_WRITE)) {
Signature · 1 line
1.9.1
#140 lore raw

PATCH 131/176 net: sctp: fix panic on duplicate ASCONF chunks

In reply to [email protected]

From: Daniel Borkmann <[email protected]>

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

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

commit b69040d8e39f20d5215a03502a8e8b4c6ab78395 upstream.

When receiving a e.g. semi-good formed connection scan in the form of ...

-------------- INIT[ASCONF; ASCONF_ACK] -------------> <----------- INIT-ACK[ASCONF; ASCONF_ACK] ------------ -------------------- COOKIE-ECHO --------------------> <-------------------- COOKIE-ACK --------------------- ---------------- ASCONF_a; ASCONF_b ----------------->

... where ASCONF_a equals ASCONF_b chunk (at least both serials need to be equal), we panic an SCTP server!

The problem is that good-formed ASCONF chunks that we reply with ASCONF_ACK chunks are cached per serial. Thus, when we receive a same ASCONF chunk twice (e.g. through a lost ASCONF_ACK), we do not need to process them again on the server side (that was the idea, also proposed in the RFC). Instead, we know it was cached and we just resend the cached chunk instead. So far, so good.

Where things get nasty is in SCTP's side effect interpreter, that is, sctp_cmd_interpreter():

While incoming ASCONF_a (chunk = event_arg) is being marked !end_of_packet and !singleton, and we have an association context, we do not flush the outqueue the first time after processing the ASCONF_ACK singleton chunk via SCTP_CMD_REPLY. Instead, we keep it queued up, although we set local_cork to 1. Commit 2e3216cd54b1 changed the precedence, so that as long as we get bundled, incoming chunks we try possible bundling on outgoing queue as well. Before this commit, we would just flush the output queue.

Now, while ASCONF_a's ASCONF_ACK sits in the corked outq, we continue to process the same ASCONF_b chunk from the packet. As we have cached the previous ASCONF_ACK, we find it, grab it and do another SCTP_CMD_REPLY command on it. So, effectively, we rip the chunk->list pointers and requeue the same ASCONF_ACK chunk another time. Since we process ASCONF_b, it's correctly marked with end_of_packet and we enforce an uncork, and thus flush, thus crashing the kernel.

Fix it by testing if the ASCONF_ACK is currently pending and if that is the case, do not requeue it. When flushing the output queue we may relink the chunk for preparing an outgoing packet, but eventually unlink it when it's copied into the skb right before transmission.

Joint work with Vlad Yasevich.

Fixes 2e3216cd54b1 ("sctp: Follow security requirement of responding with 1 packet")
---
 include/net/sctp/sctp.h | 5 +++++
 net/sctp/associola.c    | 2 ++
 2 files changed, 7 insertions(+)
include/net/sctp/sctp.h +5 -0
index a2ef814..43c8bbc 100644
@@ -524,6 +524,11 @@ static inline void sctp_assoc_pending_pmtu(struct sctp_association *asoc)
 	asoc->pmtu_pending = 0;
 }
 
+static inline bool sctp_chunk_pending(const struct sctp_chunk *chunk)
+{
+	return !list_empty(&chunk->list);
+}
+
 /* Walk through a list of TLV parameters.  Don't trust the
  * individual parameter lengths and instead depend on
  * the chunk length to indicate when to stop.  Make sure
net/sctp/associola.c +2 -0
index c37dbef..d014b05 100644
@@ -1637,6 +1637,8 @@ struct sctp_chunk *sctp_assoc_lookup_asconf_ack(
 	 * ack chunk whose serial number matches that of the request.
 	 */
 	list_for_each_entry(ack, &asoc->asconf_ack_list, transmitted_list) {
+		if (sctp_chunk_pending(ack))
+			continue;
 		if (ack->subh.addip_hdr->serial == serial) {
 			sctp_chunk_hold(ack);
 			return ack;
Signature · 1 line
1.9.1
#141 lore raw

PATCH 132/176 net: sctp: fix skb_over_panic when receiving malformed ASCONF chunks

In reply to [email protected]

From: Daniel Borkmann <[email protected]>

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

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

commit 9de7922bc709eee2f609cd01d98aaedc4cf5ea74 upstream.

Commit 6f4c618ddb0 ("SCTP : Add paramters validity check for ASCONF chunk") added basic verification of ASCONF chunks, however, it is still possible to remotely crash a server by sending a special crafted ASCONF chunk, even up to pre 2.6.12 kernels:

skb_over_panic: text:ffffffffa01ea1c3 len:31056 put:30768
head:ffff88011bd81800 data:ffff88011bd81800 tail:0x7950 end:0x440 dev:<NULL>

 ------------[ cut here ]------------
kernel BUG at net/core/skbuff.c:129!
[...]
Call Trace:
 <IRQ>
 [<ffffffff8144fb1c>] skb_put+0x5c/0x70
 [<ffffffffa01ea1c3>] sctp_addto_chunk+0x63/0xd0 [sctp]
 [<ffffffffa01eadaf>] sctp_process_asconf+0x1af/0x540 [sctp]
 [<ffffffff8152d025>] ? _read_unlock_bh+0x15/0x20
 [<ffffffffa01e0038>] sctp_sf_do_asconf+0x168/0x240 [sctp]
 [<ffffffffa01e3751>] sctp_do_sm+0x71/0x1210 [sctp]
 [<ffffffff8147645d>] ? fib_rules_lookup+0xad/0xf0
 [<ffffffffa01e6b22>] ? sctp_cmp_addr_exact+0x32/0x40 [sctp]
 [<ffffffffa01e8393>] sctp_assoc_bh_rcv+0xd3/0x180 [sctp]
 [<ffffffffa01ee986>] sctp_inq_push+0x56/0x80 [sctp]
 [<ffffffffa01fcc42>] sctp_rcv+0x982/0xa10 [sctp]
 [<ffffffffa01d5123>] ? ipt_local_in_hook+0x23/0x28 [iptable_filter]
 [<ffffffff8148bdc9>] ? nf_iterate+0x69/0xb0
 [<ffffffff81496d10>] ? ip_local_deliver_finish+0x0/0x2d0
 [<ffffffff8148bf86>] ? nf_hook_slow+0x76/0x120
 [<ffffffff81496d10>] ? ip_local_deliver_finish+0x0/0x2d0
 [<ffffffff81496ded>] ip_local_deliver_finish+0xdd/0x2d0
 [<ffffffff81497078>] ip_local_deliver+0x98/0xa0
 [<ffffffff8149653d>] ip_rcv_finish+0x12d/0x440
 [<ffffffff81496ac5>] ip_rcv+0x275/0x350
 [<ffffffff8145c88b>] __netif_receive_skb+0x4ab/0x750
 [<ffffffff81460588>] netif_receive_skb+0x58/0x60

This can be triggered e.g., through a simple scripted nmap connection scan injecting the chunk after the handshake, for example, ...

-------------- INIT[ASCONF; ASCONF_ACK] -------------> <----------- INIT-ACK[ASCONF; ASCONF_ACK] ------------ -------------------- COOKIE-ECHO --------------------> <-------------------- COOKIE-ACK --------------------- ------------------ ASCONF; UNKNOWN ------------------>

... where ASCONF chunk of length 280 contains 2 parameters ...

1) Add IP address parameter (param length: 16)
2) Add/del IP address parameter (param length: 255)

... followed by an UNKNOWN chunk of e.g. 4 bytes. Here, the Address Parameter in the ASCONF chunk is even missing, too. This is just an example and similarly-crafted ASCONF chunks could be used just as well.

The ASCONF chunk passes through sctp_verify_asconf() as all parameters passed sanity checks, and after walking, we ended up successfully at the chunk end boundary, and thus may invoke sctp_process_asconf(). Parameter walking is done with WORD_ROUND() to take padding into account.

In sctp_process_asconf()'s TLV processing, we may fail in sctp_process_asconf_param() e.g., due to removal of the IP address that is also the source address of the packet containing the ASCONF chunk, and thus we need to add all TLVs after the failure to our ASCONF response to remote via helper function sctp_add_asconf_response(), which basically invokes a sctp_addto_chunk() adding the error parameters to the given skb.

When walking to the next parameter this time, we proceed with ...

  length = ntohs(asconf_param->param_hdr.length);
  asconf_param = (void *)asconf_param + length;

... instead of the WORD_ROUND()'ed length, thus resulting here in an off-by-one that leads to reading the follow-up garbage parameter length of 12336, and thus throwing an skb_over_panic for the reply when trying to sctp_addto_chunk() next time, which implicitly calls the skb_put() with that length.

Fix it by using sctp_walk_params() [ which is also used in INIT parameter processing ] macro in the verification *and* in ASCONF processing: it will make sure we don't spill over, that we walk parameters WORD_ROUND()'ed. Moreover, we're being more defensive and guard against unknown parameter types and missized addresses.

Joint work with Vlad Yasevich.

Fixes b896b82be4ae ("[SCTP] ADDIP: Support for processing incoming ASCONF_ACK chunks.")
[lizf: Backported to 3.4: adjust context]
---
 include/net/sctp/sm.h    |  6 +--
 net/sctp/sm_make_chunk.c | 99 +++++++++++++++++++++++++++---------------------
 net/sctp/sm_statefuns.c  | 18 +--------
 3 files changed, 60 insertions(+), 63 deletions(-)
include/net/sctp/sm.h +3 -3
index 9148632..4d1be75 100644
@@ -251,9 +251,9 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *,
 					      int, __be16);
 struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
 					     union sctp_addr *addr);
-int sctp_verify_asconf(const struct sctp_association *asoc,
-		       struct sctp_paramhdr *param_hdr, void *chunk_end,
-		       struct sctp_paramhdr **errp);
+bool sctp_verify_asconf(const struct sctp_association *asoc,
+			struct sctp_chunk *chunk, bool addr_param_needed,
+			struct sctp_paramhdr **errp);
 struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
 				       struct sctp_chunk *asconf);
 int sctp_process_asconf_ack(struct sctp_association *asoc,
net/sctp/sm_make_chunk.c +55 -44

158 lines not on this page · raw message

net/sctp/sm_statefuns.c +2 -16
index 5ac33b6..a6a3006 100644
@@ -3516,9 +3516,7 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
 	struct sctp_chunk	*asconf_ack = NULL;
 	struct sctp_paramhdr	*err_param = NULL;
 	sctp_addiphdr_t		*hdr;
-	union sctp_addr_param	*addr_param;
 	__u32			serial;
-	int			length;
 
 	if (!sctp_vtag_verify(chunk, asoc)) {
 		sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
@@ -3543,17 +3541,8 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
 	hdr = (sctp_addiphdr_t *)chunk->skb->data;
 	serial = ntohl(hdr->serial);
 
-	addr_param = (union sctp_addr_param *)hdr->params;
-	length = ntohs(addr_param->p.length);
-	if (length < sizeof(sctp_paramhdr_t))
-		return sctp_sf_violation_paramlen(ep, asoc, type, arg,
-			   (void *)addr_param, commands);
-
 	/* Verify the ASCONF chunk before processing it. */
-	if (!sctp_verify_asconf(asoc,
-			    (sctp_paramhdr_t *)((void *)addr_param + length),
-			    (void *)chunk->chunk_end,
-			    &err_param))
+	if (!sctp_verify_asconf(asoc, chunk, true, &err_param))
 		return sctp_sf_violation_paramlen(ep, asoc, type, arg,
 						  (void *)err_param, commands);
 
@@ -3670,10 +3659,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
 	rcvd_serial = ntohl(addip_hdr->serial);
 
 	/* Verify the ASCONF-ACK chunk before processing it. */
-	if (!sctp_verify_asconf(asoc,
-	    (sctp_paramhdr_t *)addip_hdr->params,
-	    (void *)asconf_ack->chunk_end,
-	    &err_param))
+	if (!sctp_verify_asconf(asoc, asconf_ack, false, &err_param))
 		return sctp_sf_violation_paramlen(ep, asoc, type, arg,
 			   (void *)err_param, commands);
 
Signature · 1 line
1.9.1
#142 lore raw

PATCH 133/176 x86, mm/ASLR: Fix stack randomization on 64-bit systems

In reply to [email protected]

From: Hector Marco-Gisbert <[email protected]>

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

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

commit 4e7c22d447bb6d7e37bfe39ff658486ae78e8d77 upstream.

The issue is that the stack for processes is not properly randomized on 64 bit architectures due to an integer overflow.

The affected function is randomize_stack_top() in file "fs/binfmt_elf.c":

  static unsigned long randomize_stack_top(unsigned long stack_top)
  {
           unsigned int random_variable = 0;
           if ((current->flags & PF_RANDOMIZE) &&
                   !(current->personality & ADDR_NO_RANDOMIZE)) {
                   random_variable = get_random_int() & STACK_RND_MASK;
                   random_variable <<= PAGE_SHIFT;
           }
           return PAGE_ALIGN(stack_top) + random_variable;
           return PAGE_ALIGN(stack_top) - random_variable;

}

Note that, it declares the "random_variable" variable as "unsigned int". Since the result of the shifting operation between STACK_RND_MASK (which is 0x3fffff on x86_64, 22 bits) and PAGE_SHIFT (which is 12 on x86_64):

	  random_variable <<= PAGE_SHIFT;

then the two leftmost bits are dropped when storing the result in the "random_variable". This variable shall be at least 34 bits long to hold the (22+12) result.

These two dropped bits have an impact on the entropy of process stack. Concretely, the total stack entropy is reduced by four: from 2^28 to 2^30 (One fourth of expected entropy).

This patch restores back the entropy by correcting the types involved in the operations in the functions randomize_stack_top() and stack_maxrandom_size().

The successful fix can be tested with:

  $ for i in `seq 1 10`; do cat /proc/self/maps | grep stack; done
  7ffeda566000-7ffeda587000 rw-p 00000000 00:00 0                          [stack]
  7fff5a332000-7fff5a353000 rw-p 00000000 00:00 0                          [stack]
  7ffcdb7a1000-7ffcdb7c2000 rw-p 00000000 00:00 0                          [stack]
  7ffd5e2c4000-7ffd5e2e5000 rw-p 00000000 00:00 0                          [stack]
  ...

Once corrected, the leading bytes should be between 7ffc and 7fff, rather than always being 7fff.

[ Rebased, fixed 80 char bugs, cleaned up commit message, added test example and CVE ]
Cc Linus Torvalds <[email protected]>
Cc Andrew Morton <[email protected]>
Cc Al Viro <[email protected]>
Fixes CVE-2015-1593
---
 arch/x86/mm/mmap.c | 6 +++---
 fs/binfmt_elf.c    | 5 +++--
 2 files changed, 6 insertions(+), 5 deletions(-)
arch/x86/mm/mmap.c +3 -3
index 5c1ae28..75f9e5d 100644
@@ -35,12 +35,12 @@ struct __read_mostly va_alignment va_align = {
 	.flags = -1,
 };
 
-static unsigned int stack_maxrandom_size(void)
+static unsigned long stack_maxrandom_size(void)
 {
-	unsigned int max = 0;
+	unsigned long max = 0;
 	if ((current->flags & PF_RANDOMIZE) &&
 		!(current->personality & ADDR_NO_RANDOMIZE)) {
-		max = ((-1U) & STACK_RND_MASK) << PAGE_SHIFT;
+		max = ((-1UL) & STACK_RND_MASK) << PAGE_SHIFT;
 	}
 
 	return max;
fs/binfmt_elf.c +3 -2
index a009b9e..6dacccef 100644
@@ -539,11 +539,12 @@ out:
 
 static unsigned long randomize_stack_top(unsigned long stack_top)
 {
-	unsigned int random_variable = 0;
+	unsigned long random_variable = 0;
 
 	if ((current->flags & PF_RANDOMIZE) &&
 		!(current->personality & ADDR_NO_RANDOMIZE)) {
-		random_variable = get_random_int() & STACK_RND_MASK;
+		random_variable = (unsigned long) get_random_int();
+		random_variable &= STACK_RND_MASK;
 		random_variable <<= PAGE_SHIFT;
 	}
 #ifdef CONFIG_STACK_GROWSUP
Signature · 1 line
1.9.1
#143 lore raw

PATCH 134/176 KEYS: close race between key lookup and freeing

In reply to [email protected]

From: Sasha Levin <[email protected]>

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

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

commit a3a8784454692dd72e5d5d34dcdab17b4420e74c upstream.

When a key is being garbage collected, it's key->user would get put before the ->destroy() callback is called, where the key is removed from it's respective tracking structures.

This leaves a key hanging in a semi-invalid state which leaves a window open for a different task to try an access key->user. An example is find_keyring_by_name() which would dereference key->user for a key that is in the process of being garbage collected (where key->user was freed but ->destroy() wasn't called yet - so it's still present in the linked list).

This would cause either a panic, or corrupt memory.

Fixes CVE-2014-9529.

[lizf: Backported to 3.4: adjust indentation]
---
 security/keys/gc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
security/keys/gc.c +2 -2
index a42b455..87632bd 100644
@@ -188,12 +188,12 @@ static noinline void key_gc_unused_key(struct key *key)
 	if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
 		atomic_dec(&key->user->nikeys);
 
-	key_user_put(key->user);
-
 	/* now throw away the key memory */
 	if (key->type->destroy)
 		key->type->destroy(key);
 
+	key_user_put(key->user);
+
 	kfree(key->description);
 
 #ifdef KEY_DEBUGGING
Signature · 1 line
1.9.1
#144 lore raw

PATCH 135/176 move d_rcu from overlapping d_child to overlapping d_alias

In reply to [email protected]

From: Al Viro <[email protected]>

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

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

commit 946e51f2bf37f1656916eb75bd0742ba33983c28 upstream.

[bwh: Backported to 3.2:
- Apply name changes in all the different places we use d_alias and d_child
- Move the WARN_ON() in __d_free() to d_free() as we don't have dentry_free()]

[lizf: Backported to 3.4:
- adjust context
- need one more name change in debugfs]

---
 arch/powerpc/platforms/cell/spufs/inode.c |  4 +-
 drivers/usb/core/inode.c                  |  6 +--
 fs/9p/vfs_inode_dotl.c                    |  2 +-
 fs/affs/amigaffs.c                        |  2 +-
 fs/autofs4/expire.c                       | 10 ++--
 fs/autofs4/root.c                         |  2 +-
 fs/ceph/dir.c                             |  8 ++--
 fs/ceph/inode.c                           |  6 +--
 fs/cifs/inode.c                           |  2 +-
 fs/coda/cache.c                           |  2 +-
 fs/dcache.c                               | 80 +++++++++++++++----------------
 fs/debugfs/inode.c                        |  6 +--
 fs/exportfs/expfs.c                       |  2 +-
 fs/ext4/fsync.c                           |  2 +-
 fs/libfs.c                                | 12 ++---
 fs/ncpfs/dir.c                            |  2 +-
 fs/ncpfs/ncplib_kernel.h                  |  4 +-
 fs/nfs/getroot.c                          |  2 +-
 fs/notify/fsnotify.c                      |  4 +-
 fs/ocfs2/dcache.c                         |  2 +-
 include/linux/dcache.h                    |  8 ++--
 kernel/cgroup.c                           |  4 +-
 security/selinux/selinuxfs.c              |  6 +--
 23 files changed, 89 insertions(+), 89 deletions(-)
arch/powerpc/platforms/cell/spufs/inode.c +2 -2
index ad697f8..7c85576 100644
@@ -164,7 +164,7 @@ static void spufs_prune_dir(struct dentry *dir)
 	struct dentry *dentry, *tmp;
 
 	mutex_lock(&dir->d_inode->i_mutex);
-	list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) {
+	list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) {
 		spin_lock(&dentry->d_lock);
 		if (!(d_unhashed(dentry)) && dentry->d_inode) {
 			dget_dlock(dentry);
@@ -222,7 +222,7 @@ out:
 	 * - free child's inode if possible
 	 * - free child
 	 */
-	list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) {
+	list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) {
 		dput(dentry);
 	}
 
drivers/usb/core/inode.c +3 -3
index d2b9af5..b283a65 100644
@@ -211,7 +211,7 @@ static void update_bus(struct dentry *bus)
 
 	mutex_lock(&bus->d_inode->i_mutex);
 
-	list_for_each_entry(dev, &bus->d_subdirs, d_u.d_child)
+	list_for_each_entry(dev, &bus->d_subdirs, d_child)
 		if (dev->d_inode)
 			update_dev(dev);
 
@@ -228,7 +228,7 @@ static void update_sb(struct super_block *sb)
 
 	mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_PARENT);
 
-	list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) {
+	list_for_each_entry(bus, &root->d_subdirs, d_child) {
 		if (bus->d_inode) {
 			switch (S_IFMT & bus->d_inode->i_mode) {
 			case S_IFDIR:
@@ -342,7 +342,7 @@ static int usbfs_empty (struct dentry *dentry)
 
 	spin_lock(&dentry->d_lock);
 	list_for_each(list, &dentry->d_subdirs) {
-		struct dentry *de = list_entry(list, struct dentry, d_u.d_child);
+		struct dentry *de = list_entry(list, struct dentry, d_child);
 
 		spin_lock_nested(&de->d_lock, DENTRY_D_LOCK_NESTED);
 		if (usbfs_positive(de)) {
fs/9p/vfs_inode_dotl.c +1 -1
index a1e6c99..a86a78d 100644
@@ -81,7 +81,7 @@ static struct dentry *v9fs_dentry_from_dir_inode(struct inode *inode)
 	spin_lock(&inode->i_lock);
 	/* Directory should have only one entry. */
 	BUG_ON(S_ISDIR(inode->i_mode) && !list_is_singular(&inode->i_dentry));
-	dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias);
+	dentry = list_entry(inode->i_dentry.next, struct dentry, d_u.d_alias);
 	spin_unlock(&inode->i_lock);
 	return dentry;
 }
fs/affs/amigaffs.c +1 -1
index 52a6407..43a8f37 100644
@@ -132,7 +132,7 @@ affs_fix_dcache(struct dentry *dentry, u32 entry_ino)
 	head = &inode->i_dentry;
 	next = head->next;
 	while (next != head) {
-		dentry = list_entry(next, struct dentry, d_alias);
+		dentry = list_entry(next, struct dentry, d_u.d_alias);
 		if (entry_ino == (u32)(long)dentry->d_fsdata) {
 			dentry->d_fsdata = data;
 			break;
fs/autofs4/expire.c +5 -5
index b1cdb0a..54effed 100644
@@ -100,7 +100,7 @@ static struct dentry *get_next_positive_subdir(struct dentry *prev,
 	p = prev;
 	spin_lock(&p->d_lock);
 again:
-	next = p->d_u.d_child.next;
+	next = p->d_child.next;
 start:
 	if (next == &root->d_subdirs) {
 		spin_unlock(&p->d_lock);
@@ -109,7 +109,7 @@ start:
 		return NULL;
 	}
 
-	q = list_entry(next, struct dentry, d_u.d_child);
+	q = list_entry(next, struct dentry, d_child);
 
 	spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED);
 	/* Negative dentry - try next */
@@ -166,13 +166,13 @@ again:
 				goto relock;
 			}
 			spin_unlock(&p->d_lock);
-			next = p->d_u.d_child.next;
+			next = p->d_child.next;
 			p = parent;
 			if (next != &parent->d_subdirs)
 				break;
 		}
 	}
-	ret = list_entry(next, struct dentry, d_u.d_child);
+	ret = list_entry(next, struct dentry, d_child);
 
 	spin_lock_nested(&ret->d_lock, DENTRY_D_LOCK_NESTED);
 	/* Negative dentry - try next */
@@ -457,7 +457,7 @@ found:
 	spin_lock(&sbi->lookup_lock);
 	spin_lock(&expired->d_parent->d_lock);
 	spin_lock_nested(&expired->d_lock, DENTRY_D_LOCK_NESTED);
-	list_move(&expired->d_parent->d_subdirs, &expired->d_u.d_child);
+	list_move(&expired->d_parent->d_subdirs, &expired->d_child);
 	spin_unlock(&expired->d_lock);
 	spin_unlock(&expired->d_parent->d_lock);
 	spin_unlock(&sbi->lookup_lock);
fs/autofs4/root.c +1 -1
index 8c4292f..4117604 100644
@@ -651,7 +651,7 @@ static void autofs_clear_leaf_automount_flags(struct dentry *dentry)
 	/* only consider parents below dentrys in the root */
 	if (IS_ROOT(parent->d_parent))
 		return;
-	d_child = &dentry->d_u.d_child;
+	d_child = &dentry->d_child;
 	/* Set parent managed if it's becoming empty */
 	if (d_child->next == &parent->d_subdirs &&
 	    d_child->prev == &parent->d_subdirs)
fs/ceph/dir.c +4 -4
index 3e8094b..455b643 100644
@@ -104,7 +104,7 @@ static unsigned fpos_off(loff_t p)
 /*
  * When possible, we try to satisfy a readdir by peeking at the
  * dcache.  We make this work by carefully ordering dentries on
- * d_u.d_child when we initially get results back from the MDS, and
+ * d_child when we initially get results back from the MDS, and
  * falling back to a "normal" sync readdir if any dentries in the dir
  * are dropped.
  *
@@ -140,11 +140,11 @@ static int __dcache_readdir(struct file *filp,
 		p = parent->d_subdirs.prev;
 		dout(" initial p %p/%p\n", p->prev, p->next);
 	} else {
-		p = last->d_u.d_child.prev;
+		p = last->d_child.prev;
 	}
 
 more:
-	dentry = list_entry(p, struct dentry, d_u.d_child);
+	dentry = list_entry(p, struct dentry, d_child);
 	di = ceph_dentry(dentry);
 	while (1) {
 		dout(" p %p/%p %s d_subdirs %p/%p\n", p->prev, p->next,
@@ -166,7 +166,7 @@ more:
 		     !dentry->d_inode ? " null" : "");
 		spin_unlock(&dentry->d_lock);
 		p = p->prev;
-		dentry = list_entry(p, struct dentry, d_u.d_child);
+		dentry = list_entry(p, struct dentry, d_child);
 		di = ceph_dentry(dentry);
 	}
 
fs/ceph/inode.c +3 -3
index 81613bc..1ea7720 100644
@@ -869,9 +869,9 @@ static void ceph_set_dentry_offset(struct dentry *dn)
 
 	spin_lock(&dir->d_lock);
 	spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED);
-	list_move(&dn->d_u.d_child, &dir->d_subdirs);
+	list_move(&dn->d_child, &dir->d_subdirs);
 	dout("set_dentry_offset %p %lld (%p %p)\n", dn, di->offset,
-	     dn->d_u.d_child.prev, dn->d_u.d_child.next);
+	     dn->d_child.prev, dn->d_child.next);
 	spin_unlock(&dn->d_lock);
 	spin_unlock(&dir->d_lock);
 }
@@ -1262,7 +1262,7 @@ retry_lookup:
 			/* reorder parent's d_subdirs */
 			spin_lock(&parent->d_lock);
 			spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED);
-			list_move(&dn->d_u.d_child, &parent->d_subdirs);
+			list_move(&dn->d_child, &parent->d_subdirs);
 			spin_unlock(&dn->d_lock);
 			spin_unlock(&parent->d_lock);
 		}
fs/cifs/inode.c +1 -1
index 8d6ac6b..2c2acc0 100644
@@ -833,7 +833,7 @@ inode_has_hashed_dentries(struct inode *inode)
 	struct dentry *dentry;
 
 	spin_lock(&inode->i_lock);
-	list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
+	list_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
 		if (!d_unhashed(dentry) || IS_ROOT(dentry)) {
 			spin_unlock(&inode->i_lock);
 			return true;
fs/coda/cache.c +1 -1
index 6901578..4b2e5cb 100644
@@ -95,7 +95,7 @@ static void coda_flag_children(struct dentry *parent, int flag)
 	spin_lock(&parent->d_lock);
 	list_for_each(child, &parent->d_subdirs)
 	{
-		de = list_entry(child, struct dentry, d_u.d_child);
+		de = list_entry(child, struct dentry, d_child);
 		/* don't know what to do with negative dentries */
 		if ( ! de->d_inode ) 
 			continue;
fs/dcache.c +40 -40

280 lines not on this page · raw message

fs/debugfs/inode.c +3 -3
index 9dc6e76..47d64e9 100644
@@ -539,7 +539,7 @@ void debugfs_remove_recursive(struct dentry *dentry)
 	parent = dentry;
  down:
 	mutex_lock(&parent->d_inode->i_mutex);
-	list_for_each_entry_safe(child, next, &parent->d_subdirs, d_u.d_child) {
+	list_for_each_entry_safe(child, next, &parent->d_subdirs, d_child) {
 		if (!debugfs_positive(child))
 			continue;
 
@@ -560,8 +560,8 @@ void debugfs_remove_recursive(struct dentry *dentry)
 	mutex_lock(&parent->d_inode->i_mutex);
 
 	if (child != dentry) {
-		next = list_entry(child->d_u.d_child.next, struct dentry,
-					d_u.d_child);
+		next = list_entry(child->d_child.next, struct dentry,
+					d_child);
 		goto up;
 	}
 
fs/exportfs/expfs.c +1 -1
index b05acb7..3bbf5e7 100644
@@ -50,7 +50,7 @@ find_acceptable_alias(struct dentry *result,
 
 	inode = result->d_inode;
 	spin_lock(&inode->i_lock);
-	list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
+	list_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
 		dget(dentry);
 		spin_unlock(&inode->i_lock);
 		if (toput)
fs/ext4/fsync.c +1 -1
index a8d03a4..019c29c 100644
@@ -139,7 +139,7 @@ static int ext4_sync_parent(struct inode *inode)
 		spin_lock(&inode->i_lock);
 		if (!list_empty(&inode->i_dentry)) {
 			dentry = list_first_entry(&inode->i_dentry,
-						  struct dentry, d_alias);
+						  struct dentry, d_u.d_alias);
 			dget(dentry);
 		}
 		spin_unlock(&inode->i_lock);
fs/libfs.c +6 -6
index 18d08f5..65c126f 100644
@@ -104,18 +104,18 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
 
 			spin_lock(&dentry->d_lock);
 			/* d_lock not required for cursor */
-			list_del(&cursor->d_u.d_child);
+			list_del(&cursor->d_child);
 			p = dentry->d_subdirs.next;
 			while (n && p != &dentry->d_subdirs) {
 				struct dentry *next;
-				next = list_entry(p, struct dentry, d_u.d_child);
+				next = list_entry(p, struct dentry, d_child);
 				spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
 				if (simple_positive(next))
 					n--;
 				spin_unlock(&next->d_lock);
 				p = p->next;
 			}
-			list_add_tail(&cursor->d_u.d_child, p);
+			list_add_tail(&cursor->d_child, p);
 			spin_unlock(&dentry->d_lock);
 		}
 	}
@@ -139,7 +139,7 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
 {
 	struct dentry *dentry = filp->f_path.dentry;
 	struct dentry *cursor = filp->private_data;
-	struct list_head *p, *q = &cursor->d_u.d_child;
+	struct list_head *p, *q = &cursor->d_child;
 	ino_t ino;
 	int i = filp->f_pos;
 
@@ -165,7 +165,7 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
 
 			for (p=q->next; p != &dentry->d_subdirs; p=p->next) {
 				struct dentry *next;
-				next = list_entry(p, struct dentry, d_u.d_child);
+				next = list_entry(p, struct dentry, d_child);
 				spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
 				if (!simple_positive(next)) {
 					spin_unlock(&next->d_lock);
@@ -289,7 +289,7 @@ int simple_empty(struct dentry *dentry)
 	int ret = 0;
 
 	spin_lock(&dentry->d_lock);
-	list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child) {
+	list_for_each_entry(child, &dentry->d_subdirs, d_child) {
 		spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED);
 		if (simple_positive(child)) {
 			spin_unlock(&child->d_lock);
fs/ncpfs/dir.c +1 -1
index 9560fd7..ba792a0 100644
@@ -391,7 +391,7 @@ ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
 	spin_lock(&parent->d_lock);
 	next = parent->d_subdirs.next;
 	while (next != &parent->d_subdirs) {
-		dent = list_entry(next, struct dentry, d_u.d_child);
+		dent = list_entry(next, struct dentry, d_child);
 		if ((unsigned long)dent->d_fsdata == fpos) {
 			if (dent->d_inode)
 				dget(dent);
fs/ncpfs/ncplib_kernel.h +2 -2
index 32c0658..6d5e7c5 100644
@@ -194,7 +194,7 @@ ncp_renew_dentries(struct dentry *parent)
 	spin_lock(&parent->d_lock);
 	next = parent->d_subdirs.next;
 	while (next != &parent->d_subdirs) {
-		dentry = list_entry(next, struct dentry, d_u.d_child);
+		dentry = list_entry(next, struct dentry, d_child);
 
 		if (dentry->d_fsdata == NULL)
 			ncp_age_dentry(server, dentry);
@@ -216,7 +216,7 @@ ncp_invalidate_dircache_entries(struct dentry *parent)
 	spin_lock(&parent->d_lock);
 	next = parent->d_subdirs.next;
 	while (next != &parent->d_subdirs) {
-		dentry = list_entry(next, struct dentry, d_u.d_child);
+		dentry = list_entry(next, struct dentry, d_child);
 		dentry->d_fsdata = NULL;
 		ncp_age_dentry(server, dentry);
 		next = next->next;
fs/nfs/getroot.c +1 -1
index 4ca6f5c..b242f69 100644
@@ -62,7 +62,7 @@ static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *i
 		 */
 		spin_lock(&sb->s_root->d_inode->i_lock);
 		spin_lock(&sb->s_root->d_lock);
-		list_del_init(&sb->s_root->d_alias);
+		list_del_init(&sb->s_root->d_u.d_alias);
 		spin_unlock(&sb->s_root->d_lock);
 		spin_unlock(&sb->s_root->d_inode->i_lock);
 	}
fs/notify/fsnotify.c +2 -2
index ccb14d3..e5b6db6 100644
@@ -63,14 +63,14 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)
 	spin_lock(&inode->i_lock);
 	/* run all of the dentries associated with this inode.  Since this is a
 	 * directory, there damn well better only be one item on this list */
-	list_for_each_entry(alias, &inode->i_dentry, d_alias) {
+	list_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
 		struct dentry *child;
 
 		/* run all of the children of the original inode and fix their
 		 * d_flags to indicate parental interest (their parent is the
 		 * original inode) */
 		spin_lock(&alias->d_lock);
-		list_for_each_entry(child, &alias->d_subdirs, d_u.d_child) {
+		list_for_each_entry(child, &alias->d_subdirs, d_child) {
 			if (!child->d_inode)
 				continue;
 
fs/ocfs2/dcache.c +1 -1
index e5ba348..26977cc 100644
@@ -175,7 +175,7 @@ struct dentry *ocfs2_find_local_alias(struct inode *inode,
 
 	spin_lock(&inode->i_lock);
 	list_for_each(p, &inode->i_dentry) {
-		dentry = list_entry(p, struct dentry, d_alias);
+		dentry = list_entry(p, struct dentry, d_u.d_alias);
 
 		spin_lock(&dentry->d_lock);
 		if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) {
include/linux/dcache.h +4 -4
index 1332df0..31e55bf 100644
@@ -105,15 +105,15 @@ struct dentry {
 	void *d_fsdata;			/* fs-specific data */
 
 	struct list_head d_lru;		/* LRU list */
+	struct list_head d_child;	/* child of parent list */
+	struct list_head d_subdirs;	/* our children */
 	/*
-	 * d_child and d_rcu can share memory
+	 * d_alias and d_rcu can share memory
 	 */
 	union {
-		struct list_head d_child;	/* child of parent list */
+		struct list_head d_alias;	/* inode alias list */
 	 	struct rcu_head d_rcu;
 	} d_u;
-	struct list_head d_subdirs;	/* our children */
-	struct list_head d_alias;	/* inode alias list */
 };
 
 /*
kernel/cgroup.c +2 -2
index c776f89..34eda95 100644
@@ -898,7 +898,7 @@ static void cgroup_clear_directory(struct dentry *dentry)
 	spin_lock(&dentry->d_lock);
 	node = dentry->d_subdirs.next;
 	while (node != &dentry->d_subdirs) {
-		struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
+		struct dentry *d = list_entry(node, struct dentry, d_child);
 
 		spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
 		list_del_init(node);
@@ -932,7 +932,7 @@ static void cgroup_d_remove_dir(struct dentry *dentry)
 	parent = dentry->d_parent;
 	spin_lock(&parent->d_lock);
 	spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
-	list_del_init(&dentry->d_u.d_child);
+	list_del_init(&dentry->d_child);
 	spin_unlock(&dentry->d_lock);
 	spin_unlock(&parent->d_lock);
 	remove_dir(dentry);
security/selinux/selinuxfs.c +3 -3
index 3068d16..0a9891e 100644
@@ -1191,7 +1191,7 @@ static void sel_remove_entries(struct dentry *de)
 	spin_lock(&de->d_lock);
 	node = de->d_subdirs.next;
 	while (node != &de->d_subdirs) {
-		struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
+		struct dentry *d = list_entry(node, struct dentry, d_child);
 
 		spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
 		list_del_init(node);
@@ -1694,12 +1694,12 @@ static void sel_remove_classes(void)
 
 	list_for_each(class_node, &class_dir->d_subdirs) {
 		struct dentry *class_subdir = list_entry(class_node,
-					struct dentry, d_u.d_child);
+					struct dentry, d_child);
 		struct list_head *class_subdir_node;
 
 		list_for_each(class_subdir_node, &class_subdir->d_subdirs) {
 			struct dentry *d = list_entry(class_subdir_node,
-						struct dentry, d_u.d_child);
+						struct dentry, d_child);
 
 			if (d->d_inode)
 				if (d->d_inode->i_mode & S_IFDIR)
Signature · 1 line
1.9.1
#145 lore raw

PATCH 136/176 deal with deadlock in d_walk()

In reply to [email protected]

From: Al Viro <[email protected]>

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

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

commit ca5358ef75fc69fee5322a38a340f5739d997c10 upstream.

... by not hitting rename_retry for reasons other than rename having happened. In other words, do _not_ restart when finding that between unlocking the child and locking the parent the former got into __dentry_kill(). Skip the killed siblings instead...

[bwh: Backported to 3.2:
- As we only have try_to_ascend() and not d_walk(), apply this change to all callers of try_to_ascend()
- Adjust context to make __dentry_kill() apply to d_kill()]

[lizf: Backported to 3.4: fold the fix 2d5a2e6775fa in 3.2.y into this patch]
---
 fs/dcache.c | 105 +++++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 65 insertions(+), 40 deletions(-)
fs/dcache.c +65 -40
index 2ccc646..8038a78 100644
@@ -368,9 +368,9 @@ static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent)
 	__releases(parent->d_lock)
 	__releases(dentry->d_inode->i_lock)
 {
-	list_del(&dentry->d_child);
+	__list_del_entry(&dentry->d_child);
 	/*
-	 * Inform try_to_ascend() that we are no longer attached to the
+	 * Inform ascending readers that we are no longer attached to the
 	 * dentry tree
 	 */
 	dentry->d_flags |= DCACHE_DENTRY_KILLED;
@@ -1011,34 +1011,6 @@ void shrink_dcache_for_umount(struct super_block *sb)
 	}
 }
 
-/*
- * This tries to ascend one level of parenthood, but
- * we can race with renaming, so we need to re-check
- * the parenthood after dropping the lock and check
- * that the sequence number still matches.
- */
-static struct dentry *try_to_ascend(struct dentry *old, int locked, unsigned seq)
-{
-	struct dentry *new = old->d_parent;
-
-	rcu_read_lock();
-	spin_unlock(&old->d_lock);
-	spin_lock(&new->d_lock);
-
-	/*
-	 * might go back up the wrong parent if we have had a rename
-	 * or deletion
-	 */
-	if (new != old->d_parent ||
-		 (old->d_flags & DCACHE_DENTRY_KILLED) ||
-		 (!locked && read_seqretry(&rename_lock, seq))) {
-		spin_unlock(&new->d_lock);
-		new = NULL;
-	}
-	rcu_read_unlock();
-	return new;
-}
-
 
 /*
  * Search for at least 1 mount point in the dentry's subdirs.
@@ -1094,30 +1066,48 @@ resume:
 	/*
 	 * All done at this level ... ascend and resume the search.
 	 */
+	rcu_read_lock();
+ascend:
 	if (this_parent != parent) {
 		struct dentry *child = this_parent;
-		this_parent = try_to_ascend(this_parent, locked, seq);
-		if (!this_parent)
+		this_parent = child->d_parent;
+
+		spin_unlock(&child->d_lock);
+		spin_lock(&this_parent->d_lock);
+
+		/* might go back up the wrong parent if we have had a rename */
+		if (!locked && read_seqretry(&rename_lock, seq))
 			goto rename_retry;
 		next = child->d_child.next;
+		while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)) {
+			if (next == &this_parent->d_subdirs)
+				goto ascend;
+			child = list_entry(next, struct dentry, d_child);
+			next = next->next;
+		}
+		rcu_read_unlock();
 		goto resume;
 	}
-	spin_unlock(&this_parent->d_lock);
 	if (!locked && read_seqretry(&rename_lock, seq))
 		goto rename_retry;
+	spin_unlock(&this_parent->d_lock);
+	rcu_read_unlock();
 	if (locked)
 		write_sequnlock(&rename_lock);
 	return 0; /* No mount points found in tree */
 positive:
 	if (!locked && read_seqretry(&rename_lock, seq))
-		goto rename_retry;
+		goto rename_retry_unlocked;
 	if (locked)
 		write_sequnlock(&rename_lock);
 	return 1;
 
 rename_retry:
+	spin_unlock(&this_parent->d_lock);
+	rcu_read_unlock();
 	if (locked)
 		goto again;
+rename_retry_unlocked:
 	locked = 1;
 	write_seqlock(&rename_lock);
 	goto again;
@@ -1182,6 +1172,7 @@ resume:
 		 */
 		if (found && need_resched()) {
 			spin_unlock(&dentry->d_lock);
+			rcu_read_lock();
 			goto out;
 		}
 
@@ -1201,23 +1192,40 @@ resume:
 	/*
 	 * All done at this level ... ascend and resume the search.
 	 */
+	rcu_read_lock();
+ascend:
 	if (this_parent != parent) {
 		struct dentry *child = this_parent;
-		this_parent = try_to_ascend(this_parent, locked, seq);
-		if (!this_parent)
+		this_parent = child->d_parent;
+
+		spin_unlock(&child->d_lock);
+		spin_lock(&this_parent->d_lock);
+
+		/* might go back up the wrong parent if we have had a rename */
+		if (!locked && read_seqretry(&rename_lock, seq))
 			goto rename_retry;
 		next = child->d_child.next;
+		while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)) {
+			if (next == &this_parent->d_subdirs)
+				goto ascend;
+			child = list_entry(next, struct dentry, d_child);
+			next = next->next;
+		}
+		rcu_read_unlock();
 		goto resume;
 	}
 out:
-	spin_unlock(&this_parent->d_lock);
 	if (!locked && read_seqretry(&rename_lock, seq))
 		goto rename_retry;
+	spin_unlock(&this_parent->d_lock);
+	rcu_read_unlock();
 	if (locked)
 		write_sequnlock(&rename_lock);
 	return found;
 
 rename_retry:
+	spin_unlock(&this_parent->d_lock);
+	rcu_read_unlock();
 	if (found)
 		return found;
 	if (locked)
@@ -2955,26 +2963,43 @@ resume:
 		}
 		spin_unlock(&dentry->d_lock);
 	}
+	rcu_read_lock();
+ascend:
 	if (this_parent != root) {
 		struct dentry *child = this_parent;
 		if (!(this_parent->d_flags & DCACHE_GENOCIDE)) {
 			this_parent->d_flags |= DCACHE_GENOCIDE;
 			this_parent->d_count--;
 		}
-		this_parent = try_to_ascend(this_parent, locked, seq);
-		if (!this_parent)
+		this_parent = child->d_parent;
+
+		spin_unlock(&child->d_lock);
+		spin_lock(&this_parent->d_lock);
+
+		/* might go back up the wrong parent if we have had a rename */
+		if (!locked && read_seqretry(&rename_lock, seq))
 			goto rename_retry;
 		next = child->d_child.next;
+		while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)) {
+			if (next == &this_parent->d_subdirs)
+				goto ascend;
+			child = list_entry(next, struct dentry, d_child);
+			next = next->next;
+		}
+		rcu_read_unlock();
 		goto resume;
 	}
-	spin_unlock(&this_parent->d_lock);
 	if (!locked && read_seqretry(&rename_lock, seq))
 		goto rename_retry;
+	spin_unlock(&this_parent->d_lock);
+	rcu_read_unlock();
 	if (locked)
 		write_sequnlock(&rename_lock);
 	return;
 
 rename_retry:
+	spin_unlock(&this_parent->d_lock);
+	rcu_read_unlock();
 	if (locked)
 		goto again;
 	locked = 1;
Signature · 1 line
1.9.1
#146 lore raw

PATCH 137/176 MIPS: IRQ: Fix disable_irq on CPU IRQs

In reply to [email protected]

From: Felix Fietkau <[email protected]>

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

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

commit a3e6c1eff54878506b2dddcc202df9cc8180facb upstream.

If the irq_chip does not define .irq_disable, any call to disable_irq will defer disabling the IRQ until it fires while marked as disabled. This assumes that the handler function checks for this condition, which handle_percpu_irq does not. In this case, calling disable_irq leads to an IRQ storm, if the interrupt fires while disabled.

This optimization is only useful when disabling the IRQ is slow, which is not true for the MIPS CPU IRQ.

Disable this optimization by implementing .irq_disable and .irq_enable

Patchwork: https://patchwork.linux-mips.org/patch/8949/

---
 arch/mips/kernel/irq_cpu.c | 4 ++++
 1 file changed, 4 insertions(+)
arch/mips/kernel/irq_cpu.c +4 -0
index 972263b..0ed44be 100644
@@ -55,6 +55,8 @@ static struct irq_chip mips_cpu_irq_controller = {
 	.irq_mask_ack	= mask_mips_irq,
 	.irq_unmask	= unmask_mips_irq,
 	.irq_eoi	= unmask_mips_irq,
+	.irq_disable	= mask_mips_irq,
+	.irq_enable	= unmask_mips_irq,
 };
 
 /*
@@ -91,6 +93,8 @@ static struct irq_chip mips_mt_cpu_irq_controller = {
 	.irq_mask_ack	= mips_mt_cpu_irq_ack,
 	.irq_unmask	= unmask_mips_irq,
 	.irq_eoi	= unmask_mips_irq,
+	.irq_disable	= mask_mips_irq,
+	.irq_enable	= unmask_mips_irq,
 };
 
 void __init mips_cpu_irq_init(void)
Signature · 1 line
1.9.1
#147 lore raw

PATCH 138/176 ASoC: atmel_ssc_dai: fix start event for I2S mode

In reply to [email protected]

From: Bo Shen <[email protected]>

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

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

commit a43bd7e125143b875caae6d4f9938855b440faaf upstream.

According to the I2S specification information as following:
- WS = 0, channel 1 (left)
- WS = 1, channel 2 (right)
So, the start event should be TF/RF falling edge.

---
 sound/soc/atmel/atmel_ssc_dai.c | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)
sound/soc/atmel/atmel_ssc_dai.c +4 -14
index 354341e..8d7d29c 100644
@@ -341,7 +341,6 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
 	struct atmel_pcm_dma_params *dma_params;
 	int dir, channels, bits;
 	u32 tfmr, rfmr, tcmr, rcmr;
-	int start_event;
 	int ret;
 
 	/*
@@ -460,19 +459,10 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
 		 * The SSC transmit clock is obtained from the BCLK signal on
 		 * on the TK line, and the SSC receive clock is
 		 * generated from the transmit clock.
-		 *
-		 *  For single channel data, one sample is transferred
-		 * on the falling edge of the LRC clock.
-		 * For two channel data, one sample is
-		 * transferred on both edges of the LRC clock.
 		 */
-		start_event = ((channels == 1)
-				? SSC_START_FALLING_RF
-				: SSC_START_EDGE_RF);
-
 		rcmr =	  SSC_BF(RCMR_PERIOD, 0)
 			| SSC_BF(RCMR_STTDLY, START_DELAY)
-			| SSC_BF(RCMR_START, start_event)
+			| SSC_BF(RCMR_START, SSC_START_FALLING_RF)
 			| SSC_BF(RCMR_CKI, SSC_CKI_RISING)
 			| SSC_BF(RCMR_CKO, SSC_CKO_NONE)
 			| SSC_BF(RCMR_CKS, SSC_CKS_CLOCK);
@@ -480,14 +470,14 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
 		rfmr =	  SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
 			| SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
 			| SSC_BF(RFMR_FSLEN, 0)
-			| SSC_BF(RFMR_DATNB, 0)
+			| SSC_BF(RFMR_DATNB, (channels - 1))
 			| SSC_BIT(RFMR_MSBF)
 			| SSC_BF(RFMR_LOOP, 0)
 			| SSC_BF(RFMR_DATLEN, (bits - 1));
 
 		tcmr =	  SSC_BF(TCMR_PERIOD, 0)
 			| SSC_BF(TCMR_STTDLY, START_DELAY)
-			| SSC_BF(TCMR_START, start_event)
+			| SSC_BF(TCMR_START, SSC_START_FALLING_RF)
 			| SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
 			| SSC_BF(TCMR_CKO, SSC_CKO_NONE)
 			| SSC_BF(TCMR_CKS, SSC_CKS_PIN);
@@ -496,7 +486,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
 			| SSC_BF(TFMR_FSDEN, 0)
 			| SSC_BF(TFMR_FSOS, SSC_FSOS_NONE)
 			| SSC_BF(TFMR_FSLEN, 0)
-			| SSC_BF(TFMR_DATNB, 0)
+			| SSC_BF(TFMR_DATNB, (channels - 1))
 			| SSC_BIT(TFMR_MSBF)
 			| SSC_BF(TFMR_DATDEF, 0)
 			| SSC_BF(TFMR_DATLEN, (bits - 1));
Signature · 1 line
1.9.1
#148 lore raw

PATCH 139/176 ALSA: ak411x: Fix stall in work callback

In reply to [email protected]

From: Takashi Iwai <[email protected]>

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

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

commit 4161b4505f1690358ac0a9ee59845a7887336b21 upstream.

When ak4114 work calls its callback and the callback invokes ak4114_reinit(), it stalls due to flush_delayed_work(). For avoiding this, control the reentrance by introducing a refcount. Also flush_delayed_work() is replaced with cancel_delayed_work_sync().

The exactly same bug is present in ak4113.c and fixed as well.

[lizf: Backported to 3.4: snd_ak4113_reinit() and snd_ak4114_reinit() used flush_delayed_work_sync() instead of flush_delayed_work()]

---
 include/sound/ak4113.h   |  2 +-
 include/sound/ak4114.h   |  2 +-
 sound/i2c/other/ak4113.c | 17 ++++++++---------
 sound/i2c/other/ak4114.c | 18 ++++++++----------
 4 files changed, 18 insertions(+), 21 deletions(-)
include/sound/ak4113.h +1 -1
index 2609048..3a34f6e 100644
@@ -286,7 +286,7 @@ struct ak4113 {
 	ak4113_write_t *write;
 	ak4113_read_t *read;
 	void *private_data;
-	unsigned int init:1;
+	atomic_t wq_processing;
 	spinlock_t lock;
 	unsigned char regmap[AK4113_WRITABLE_REGS];
 	struct snd_kcontrol *kctls[AK4113_CONTROLS];
include/sound/ak4114.h +1 -1
index 3ce69fd..6944116 100644
@@ -168,7 +168,7 @@ struct ak4114 {
 	ak4114_write_t * write;
 	ak4114_read_t * read;
 	void * private_data;
-	unsigned int init: 1;
+	atomic_t wq_processing;
 	spinlock_t lock;
 	unsigned char regmap[7];
 	unsigned char txcsb[5];
sound/i2c/other/ak4113.c +8 -9
index dde5c9c..e1ab3ad 100644
@@ -56,8 +56,7 @@ static inline unsigned char reg_read(struct ak4113 *ak4113, unsigned char reg)
 
 static void snd_ak4113_free(struct ak4113 *chip)
 {
-	chip->init = 1;	/* don't schedule new work */
-	mb();
+	atomic_inc(&chip->wq_processing);	/* don't schedule new work */
 	cancel_delayed_work_sync(&chip->work);
 	kfree(chip);
 }
@@ -89,6 +88,7 @@ int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
 	chip->write = write;
 	chip->private_data = private_data;
 	INIT_DELAYED_WORK(&chip->work, ak4113_stats);
+	atomic_set(&chip->wq_processing, 0);
 
 	for (reg = 0; reg < AK4113_WRITABLE_REGS ; reg++)
 		chip->regmap[reg] = pgm[reg];
@@ -139,13 +139,11 @@ static void ak4113_init_regs(struct ak4113 *chip)
 
 void snd_ak4113_reinit(struct ak4113 *chip)
 {
-	chip->init = 1;
-	mb();
-	flush_delayed_work_sync(&chip->work);
+	if (atomic_inc_return(&chip->wq_processing) == 1)
+		cancel_delayed_work_sync(&chip->work);
 	ak4113_init_regs(chip);
 	/* bring up statistics / event queing */
-	chip->init = 0;
-	if (chip->kctls[0])
+	if (atomic_dec_and_test(&chip->wq_processing))
 		schedule_delayed_work(&chip->work, HZ / 10);
 }
 EXPORT_SYMBOL_GPL(snd_ak4113_reinit);
@@ -632,8 +630,9 @@ static void ak4113_stats(struct work_struct *work)
 {
 	struct ak4113 *chip = container_of(work, struct ak4113, work.work);
 
-	if (!chip->init)
+	if (atomic_inc_return(&chip->wq_processing) == 1)
 		snd_ak4113_check_rate_and_errors(chip, chip->check_flags);
 
-	schedule_delayed_work(&chip->work, HZ / 10);
+	if (atomic_dec_and_test(&chip->wq_processing))
+		schedule_delayed_work(&chip->work, HZ / 10);
 }
sound/i2c/other/ak4114.c +8 -10
index fdf3c1b..4c6b379 100644
@@ -66,8 +66,7 @@ static void reg_dump(struct ak4114 *ak4114)
 
 static void snd_ak4114_free(struct ak4114 *chip)
 {
-	chip->init = 1;	/* don't schedule new work */
-	mb();
+	atomic_inc(&chip->wq_processing);	/* don't schedule new work */
 	cancel_delayed_work_sync(&chip->work);
 	kfree(chip);
 }
@@ -100,6 +99,7 @@ int snd_ak4114_create(struct snd_card *card,
 	chip->write = write;
 	chip->private_data = private_data;
 	INIT_DELAYED_WORK(&chip->work, ak4114_stats);
+	atomic_set(&chip->wq_processing, 0);
 
 	for (reg = 0; reg < 7; reg++)
 		chip->regmap[reg] = pgm[reg];
@@ -152,13 +152,11 @@ static void ak4114_init_regs(struct ak4114 *chip)
 
 void snd_ak4114_reinit(struct ak4114 *chip)
 {
-	chip->init = 1;
-	mb();
-	flush_delayed_work_sync(&chip->work);
+	if (atomic_inc_return(&chip->wq_processing) == 1)
+		cancel_delayed_work_sync(&chip->work);
 	ak4114_init_regs(chip);
 	/* bring up statistics / event queing */
-	chip->init = 0;
-	if (chip->kctls[0])
+	if (atomic_dec_and_test(&chip->wq_processing))
 		schedule_delayed_work(&chip->work, HZ / 10);
 }
 
@@ -612,10 +610,10 @@ static void ak4114_stats(struct work_struct *work)
 {
 	struct ak4114 *chip = container_of(work, struct ak4114, work.work);
 
-	if (!chip->init)
+	if (atomic_inc_return(&chip->wq_processing) == 1)
 		snd_ak4114_check_rate_and_errors(chip, chip->check_flags);
-
-	schedule_delayed_work(&chip->work, HZ / 10);
+	if (atomic_dec_and_test(&chip->wq_processing))
+		schedule_delayed_work(&chip->work, HZ / 10);
 }
 
 EXPORT_SYMBOL(snd_ak4114_create);
Signature · 1 line
1.9.1
#149 lore raw

PATCH 140/176 lib/checksum.c: fix carry in csum_tcpudp_nofold

In reply to [email protected]

From: karl beldan <[email protected]>

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

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

commit 150ae0e94634714b23919f0c333fee28a5b199d5 upstream.

The carry from the 64->32bits folding was dropped, e.g with:
saddr=0xFFFFFFFF daddr=0xFF0000FF len=0xFFFF proto=0 sum=1, csum_tcpudp_nofold returned 0 instead of 1.

---
 lib/checksum.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
lib/checksum.c +10 -2
index 12dceb2..edbf473 100644
@@ -47,6 +47,15 @@ static inline unsigned short from32to16(unsigned int x)
 	return x;
 }
 
+static inline u32 from64to32(u64 x)
+{
+	/* add up 32-bit and 32-bit for 32+c bit */
+	x = (x & 0xffffffff) + (x >> 32);
+	/* add up carry.. */
+	x = (x & 0xffffffff) + (x >> 32);
+	return (u32)x;
+}
+
 static unsigned int do_csum(const unsigned char *buff, int len)
 {
 	int odd;
@@ -193,8 +202,7 @@ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
 #else
 	s += (proto + len) << 8;
 #endif
-	s += (s >> 32);
-	return (__force __wsum)s;
+	return (__force __wsum)from64to32(s);
 }
 EXPORT_SYMBOL(csum_tcpudp_nofold);
 #endif
Signature · 1 line
1.9.1
#150 lore raw

Re: [PATCH 3.4 140/176] lib/checksum.c: fix carry in csum_tcpudp_nofold

Quoted 9 lines · On Thu, Apr 09, 2015 at 04:46:28PM +0800, [email protected] wrote:

From: karl beldan <[email protected]>

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

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

commit 150ae0e94634714b23919f0c333fee28a5b199d5 upstream.

Hi Zefan,

The above patch introduced a build error for some archs, please consider applying 9ce357795ef208faa0d59894d9d119a7434e37f3 "lib/checksum.c: fix build for generic csum_tcpudp_nofold" as well.

Karl

maintainer
#151 lore raw

Re: [PATCH 3.4 140/176] lib/checksum.c: fix carry in csum_tcpudp_nofold

From: Karl Beldan <[email protected]>
Date: Thu, 9 Apr 2015 19:44:08 +0200

Quoted 8 lines · On Thu, Apr 09, 2015 at 04:46:28PM +0800, [email protected] wrote:
Quoted 7 lines

From: karl beldan <[email protected]>

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

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

Quoted 8 lines
Quoted 2 lines

commit 150ae0e94634714b23919f0c333fee28a5b199d5 upstream.

Hi Zefan,

The above patch introduced a build error for some archs, please consider applying 9ce357795ef208faa0d59894d9d119a7434e37f3 "lib/checksum.c: fix build for generic csum_tcpudp_nofold" as well.

+1