Skip to contentSkip to conversation

3.12.40-stable review

PATCH In review Jiri Slaby 2 participants 157 messages Apr 7, 2015 – May 4, 2015

Subsystems (2)
lore
Share & tools
lore

Jiri Slaby

author
#0 lore raw

cover 3.12.40-stable review

This is the start of the stable review cycle for the 3.12.40 release. There are 155 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 14:50:04 CEST 2015. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

	http://kernel.org/pub/linux/kernel/people/jirislaby/stable-review/patch-3.12.40-rc1.xz

and the diffstat can be found below.

thanks,
js

===============

Al Viro (2):
caif: fix MSG_OOB test in caif_seqpkt_recvmsg()
rxrpc: bogus MSG_PEEK test in rxrpc_recvmsg()

Alex Deucher (7):
drm/radeon: do a posting read in evergreen_set_irq drm/radeon: do a posting read in r100_set_irq drm/radeon: do a posting read in r600_set_irq drm/radeon: do a posting read in cik_set_irq drm/radeon: do a posting read in si_set_irq drm/radeon: do a posting read in rs600_set_irq drm/radeon: fix interlaced modes on DCE8

Alex Smith (1):
MIPS: asm/reg.h: Make 32- and 64-bit definitions available at the same
time

Alexander Sverdlin (1):
spi: pl022: Fix race in giveback() leading to driver lock-up

Alexandre Belloni (1):
ARM: at91: pm: fix at91rm9200 standby

Alexey Kodanev (1):
net: sysctl_net_core: check SNDBUF and RCVBUF for min length

Andreas Larsson (1):
sparc32: destroy_context() and switch_mm() needs to disable
interrupts.

Andy Lutomirski (1):
module: Clean up ro/nx after early module load failures

Andy Shevchenko (1):
dmaengine: dw: append MODULE_ALIAS for platform driver

Anton Blanchard (1):
powerpc/perf: Fix ABIv2 kernel backtraces

Anton Kolesov (1):
ARC: Update order of registers in KGDB to match GDB 7.5

Arnd Bergmann (1):
rds: avoid potential stack overflow

Bart Van Assche (2):
target: Fix reference leak in target_get_sess_cmd() error path
tcm_qla2xxx: Fix incorrect use of __transport_register_session

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

Ben Dooks (1):
ARM: Correct BUG() assembly to ensure it is endian-agnostic

Ben Hutchings (1):
dns_resolver: Null-terminate the right string

Bob Copeland (1):
mac80211: drop unencrypted frames in mesh fwding

Bob Moore (1):
ACPICA: Update to GPIO region handler interface.

Brian King (1):
bnx2x: Force fundamental reset for EEH recovery

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

Chen Gang (2):
ARM: 7866/1: include: asm: use 'long long' instead of 'u64' within
atomic.h
ARM: 7867/1: include: asm: use 'int' instead of 'unsigned long' for
'oldval' in atomic_cmpxchg().

Chris Mason (1):
Btrfs: don't delay inode ref updates during log replay

Christian König (1):
drm/radeon: drop setting UPLL to sleep mode

Dan Carpenter (1):
tcm_fc: missing curly braces in ft_invl_hw_context()

Daniel Mack (1):
ALSA: snd-usb: add quirks for Roland UA-22

Darrick J. Wong (1):
dm io: deal with wandering queue limits when handling REQ_DISCARD and
REQ_WRITE_SAME

Dave Chiluk (1):
stable_kernel_rules: Add pointer to netdev-FAQ for network patches

Dave Hansen (3):
mm: thp: give transparent hugepage code a separate copy_page ipc/shm.c: fix overly aggressive shmdt() when calls span multiple
segments
shmdt: use i_size_read() instead of ->i_size

David Ahern (3):
sparc: perf: Remove redundant perf_pmu_{en|dis}able calls
sparc: perf: Make counting mode actually work
sparc: Touch NMI watchdog when walking cpus and calling printk

David Jeffery (1):
Don't leak a key reference if request_key() tries to use a revoked
keyring

David S. Miller (2):
sparc64: Fix several bugs in memmove().
crypto: sha - Handle unaligned input data in generic sha256 and

    sha512.

Doug Anderson (1):
regulator: core: Fix enable GPIO reference counting

Eli Cohen (1):
IB/core: Avoid leakage from kernel to user space

Eric Dumazet (3):
inet_diag: fix possible overflow in inet_diag_dump_one_icsk()
tcp: make connect() mem charging friendly
net: fix sparse warning in sk_dst_set()

Eric Nelson (1):
ASoC: sgtl5000: remove useless register write clearing
CHRGPUMP_POWERUP

Gao feng (1):
ipv6: reallocate addrconf router for ipv6 address when lo device up

Harald Freudenberger (1):
crypto: s390 - fix aes,des ctr mode concurrency finding.

Helge Deller (1):
parisc: add serial ports of C8000/1GHz machine to hardware database

James Bottomley (1):
libsas: Fix Kernel Crash in smp_execute_task

Jan Beulich (1):
xen-pciback: limit guest control of command register

Jan Kiszka (1):
intel_idle: Add CPU model 54 (Atom N2000 series)

Jason Low (1):
cpuset: Fix cpuset sched_relax_domain_level

Javier Martinez Canillas (1):
regulator: Only enable disabled regulators on resume

JeHyeon Yeon (1):
LZ4 : fix the data abort issue

Jiri Slaby (2):
mm, hugetlb: define page_hstate for !HUGETLB_PAGE x86/vdso: Fix the build on GCC5

Joerg Roedel (2):
iommu/core: Check for the right function pointer in iommu_map() x86/irq: Check for valid irq descriptor in
check_irq_vectors_for_cpu_disable()

Johan Hovold (1):
USB: zte_ev: fix removed PIDs

Johannes Berg (1):
nl80211: ignore HT/VHT capabilities without QoS/WMM

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

Jonathan Cameron (1):
iio:adc:max1363 incorrect resolutions for max11604, max11605, max11610

    and max11611.

Josh Hunt (1):
tcp: fix tcp fin memory accounting

Jouni Malinen (1):
cfg80211: Fix 160 MHz channels with 80+80 and 160 MHz drivers

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

Lan Tianyu (1):
ACPI: Run fixed event device notifications in process context

Lars-Peter Clausen (1):
regmap: regcache-rbtree: Fix present bitmap resize

Laura Abbott (1):
ARM: 7931/1: Correct virt_addr_valid

Lee Duncan (1):
target: Allow Write Exclusive non-reservation holders to READ

Liu Hua (1):
hung_task: check the value of "sysctl_hung_task_timeout_sec"

Malcolm Priestley (1):
vt6655: RFbSetPower fix missing rate RATE_12M

Manfred Spraul (1):
ipc/sem.c: fully initialize sem_array before making it visible

Michael Ellerman (1):
powerpc/smp: Wait until secondaries are active & online

Michael S. Tsirkin (2):
virtio_console: init work unconditionally
virtio_console: avoid config access from irq

Michael Wang (1):
power, sched: stop updating inside arch_update_cpu_topology() when
nothing to be update

Michal Kazior (1):
mac80211: disable u-APSD queues by default

Miklos Szeredi (2):
fuse: set stolen page uptodate
fuse: notify: don't move pages

Mikulas Patocka (1):
dm: hold suspend_lock while suspending device during device deletion

Naoya Horiguchi (2):
mm/hugetlb: fix getting refcount 0 page in hugetlb_fault() include/linux/hugetlb.h: make isolate_huge_page() an inline

NeilBrown (1):
md/bitmap: always wait for writes on unplug.

Nicholas Bellinger (6):
target: Fix virtual LUN=0 target_configure_device failure OOPs
iscsi-target: Avoid early conn_logout_comp for iser connections target/pscsi: Fix NULL pointer dereference in get_device_type
target: Fix R_HOLDER bit usage for AllRegistrants
target: Avoid dropping AllRegistrants reservation during unregister
target: Allow AllRegistrants to re-RESERVE existing reservation

Oleg Nesterov (2):
x86/fpu: Avoid math_state_restore() without used_math() in

    __restore_xstate_sig()

x86/fpu: Drop_fpu() should not assume that tsk equals current

Oliver Hartkopp (1):
can: add missing initialisations in CAN related skbuffs

Ondrej Zary (1):
Revert "net: cx82310_eth: use common match macro"

Peter Hurley (1):
console: Fix console name size mismatch

Peter Zijlstra (1):
perf: Fix irq_work 'tail' recursion

Quentin Casasnovas (1):
x86/microcode/intel: Guard against stack overflow in the loader

Rabin Vincent (1):
crypto: testmgr - don't use interruptible wait in tests

Rob Gardner (1):
sparc: semtimedop() unreachable due to comparison error

Roger Pau Monne (2):
xen-blkfront: revoke foreign access for grants not mapped by the
backend
xen-blkfront: restore the non-persistent data path

Roland Dreier (1):
iscsi-target: Fix wrong buffer / buffer overrun in
iscsi_change_param_value()

Romeo Cane (1):
powerpc: Fix sys_call_table declaration to enable syscall tracing

Russell King (1):
Change email address for 8250_pci

Rusty Russell (1):
module: set nx before marking module MODULE_STATE_COMING.

Ryusuke Konishi (1):
nilfs2: fix deadlock of segment constructor during recovery

Santosh Shilimkar (1):
ARM: OMAP4: Fix the boot regression with CPU_IDLE enabled

Scott Wood (1):
powerpc/mpc85xx: Add ranges to etsec2 nodes

Sergei Antonov (1):
hfsplus: fix B-tree corruption after insertion at position 0

Stephan Mueller (1):
crypto: aesni - fix memory usage in GCM decryption

Steven Barth (1):
ipv6: fix backtracking for throw routes

Steven Capper (2):
ARM: 8108/1: mm: Introduce {pte,pmd}_isset and {pte,pmd}_isclear
ARM: 8109/1: mm: Modify pte_write and pmd_write logic for LPAE

Takashi Iwai (18):
ALSA: hda - Fix regression of HD-audio controller fallback modes
ALSA: control: Add sanity checks for user ctl id name string
ALSA: hda - Fix built-in mic on Compaq Presario CQ60
ALSA: hda - Don't access stereo amps for mono channel widgets
ALSA: hda - Set single_adc_amp flag for CS420x codecs
ALSA: hda - Add workaround for MacBook Air 5,2 built-in mic
ALSA: hda - Treat stereo-to-mono mix properly
ASoC: pcm1681: Fix wrong value references for boolean kctl
ASoC: cs4271: Fix wrong value references for boolean kctl
ASoC: wm8960: Fix wrong value references for boolean kctl
ASoC: tas5086: Fix wrong value references for boolean kctl
ASoC: wm8731: Fix wrong value references for boolean kctl
ASoC: wm2000: Fix wrong value references for boolean kctl
ASoC: wm8903: Fix wrong value references for boolean kctl
ASoC: wm8904: Fix wrong value references for boolean kctl
ASoC: ak4641: Fix wrong value references for boolean kctl
ASoC: adav80x: Fix wrong value references for boolean kctl
ASoC: wm8955: Fix wrong value references for boolean kctl

Tejun Heo (1):
workqueue: fix hang involving racing cancel[_delayed]_work_sync()'s
for PREEMPT_NONE

Thomas Fitzsimmons (1):
net: mvneta: Fix big endian issue in mvneta_txq_desc_csum()

Thomas Hellstrom (1):
drm/vmwgfx: Reorder device takedown somewhat

Tommi Rantala (1):
drm/radeon: fix DRM_IOCTL_RADEON_CS oops

Tony Lindgren (1):
ARM: OMAP2+: hwmod: Rearm wake-up interrupts for DT when MUSB is idled

Trond Myklebust (1):
NFS: Add attribute update barriers to nfs_setattr_update_inode()

Vincent Stehlé (1):
topology: Fix compilation warning when not in SMP

Vineet Gupta (2):
ARC: [nsimosci] Allow "headless" models to boot
ARC: [nsimosci] move peripherals to match model to FPGA

Wei Yang (2):
net/mlx4_core: pass pci_device_id.driver_data to __mlx4_init_one
during reset
net/mlx4_core: Preserve pci_dev_data after __mlx4_remove_one()

Zoltan Kiss (1):
core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle
errors

[email protected] (1):
tpm/ibmvtpm: Additional LE support for tpm_ibmvtpm_send

[email protected] (1):
HID: add ALWAYS_POLL quirk for a Logitech 0xc007

willy tarreau (5):
net: mvneta: increase the 64-bit rx/tx stats out of the hot path
net: mvneta: use per_cpu stats to fix an SMP lock up
net: mvneta: do not schedule in mvneta_tx_timeout
net: mvneta: add missing bit descriptions for interrupt masks and
causes
net: mvneta: replace Tx timer with a real interrupt

 Documentation/stable_kernel_rules.txt            |   3 +
 arch/arc/boot/dts/nsimosci.dts                   |  18 +-
 arch/arc/include/asm/kgdb.h                      |  32 +--
 arch/arm/include/asm/atomic.h                    |  52 ++---
 arch/arm/include/asm/bug.h                       |  10 +-
 arch/arm/include/asm/memory.h                    |   3 +-
 arch/arm/include/asm/pgtable-3level-hwdef.h      |   3 +-
 arch/arm/include/asm/pgtable-3level.h            |  49 +++--
 arch/arm/include/asm/pgtable.h                   |  14 +-
 arch/arm/kernel/traps.c                          |   8 +-
 arch/arm/mach-at91/pm.h                          |   2 +-
 arch/arm/mach-omap2/cpuidle44xx.c                |  25 ++-
 arch/arm/mach-omap2/omap_hwmod.c                 |   4 +
 arch/arm/mm/proc-v7-3level.S                     |   9 +-
 arch/mips/include/asm/reg.h                      | 260 +++++++++++++++--------
 arch/mips/kernel/binfmt_elfo32.c                 |  32 ++-
 arch/parisc/kernel/hardware.c                    |   3 +-
 arch/powerpc/boot/dts/fsl/pq3-etsec2-0.dtsi      |   1 +
 arch/powerpc/boot/dts/fsl/pq3-etsec2-1.dtsi      |   1 +
 arch/powerpc/boot/dts/fsl/pq3-etsec2-2.dtsi      |   1 +
 arch/powerpc/include/asm/ptrace.h                |   7 +
 arch/powerpc/include/asm/syscall.h               |   2 +-
 arch/powerpc/kernel/smp.c                        |   4 +-
 arch/powerpc/mm/numa.c                           |  15 ++
 arch/powerpc/perf/callchain.c                    |   2 +-
 arch/s390/crypto/aes_s390.c                      |   3 +
 arch/s390/crypto/des_s390.c                      |   3 +
 arch/sparc/kernel/perf_event.c                   |  15 +-
 arch/sparc/kernel/process_64.c                   |   4 +
 arch/sparc/kernel/sys_sparc_64.c                 |   2 +-
 arch/sparc/lib/memmove.S                         |  35 ++-
 arch/sparc/mm/srmmu.c                            |  11 +-
 arch/x86/crypto/aesni-intel_glue.c               |   4 +-
 arch/x86/include/asm/fpu-internal.h              |   2 +-
 arch/x86/kernel/irq.c                            |   3 +
 arch/x86/kernel/microcode_intel_early.c          |   2 +-
 arch/x86/kernel/xsave.c                          |   7 +-
 arch/x86/vdso/vdso32/sigreturn.S                 |   1 +
 crypto/sha256_generic.c                          |   3 +-
 crypto/sha512_generic.c                          |   3 +-
 crypto/tcrypt.c                                  |  10 +-
 crypto/testmgr.c                                 |  48 ++---
 drivers/acpi/acpica/aclocal.h                    |   1 +
 drivers/acpi/acpica/acobject.h                   |   1 +
 drivers/acpi/acpica/dsfield.c                    |   2 +
 drivers/acpi/acpica/evregion.c                   |  47 ++--
 drivers/acpi/acpica/exfield.c                    |  67 ++++++
 drivers/acpi/acpica/exprep.c                     |   2 +
 drivers/acpi/scan.c                              |  15 +-
 drivers/base/regmap/regcache-rbtree.c            |   2 +-
 drivers/base/topology.c                          |   3 +-
 drivers/block/xen-blkfront.c                     | 148 ++++++++++---
 drivers/char/tpm/tpm_ibmvtpm.c                   |  10 +-
 drivers/char/tpm/tpm_ibmvtpm.h                   |   6 +-
 drivers/char/virtio_console.c                    |  19 +-
 drivers/dma/dw/platform.c                        |   5 +-
 drivers/gpu/drm/radeon/atombios_crtc.c           |   3 +
 drivers/gpu/drm/radeon/cik.c                     |   3 +
 drivers/gpu/drm/radeon/evergreen.c               |   3 +
 drivers/gpu/drm/radeon/r100.c                    |   4 +
 drivers/gpu/drm/radeon/r600.c                    |   3 +
 drivers/gpu/drm/radeon/radeon_cs.c               |   4 +-
 drivers/gpu/drm/radeon/rs600.c                   |   4 +
 drivers/gpu/drm/radeon/si.c                      |   9 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c              |  47 ++--
 drivers/hid/hid-ids.h                            |   1 +
 drivers/hid/usbhid/hid-quirks.c                  |   1 +
 drivers/idle/intel_idle.c                        |   1 +
 drivers/iio/adc/max1363.c                        |  16 +-
 drivers/infiniband/core/uverbs_main.c            |   1 +
 drivers/iommu/iommu.c                            |   2 +-
 drivers/md/bitmap.c                              |  16 +-
 drivers/md/dm-io.c                               |  15 +-
 drivers/md/dm.c                                  |   6 +
 drivers/net/can/dev.c                            |   8 +
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c |   4 +
 drivers/net/ethernet/marvell/mvneta.c            | 209 +++++++++---------
 drivers/net/ethernet/mellanox/mlx4/main.c        | 168 ++++++++-------
 drivers/net/ethernet/mellanox/mlx4/mlx4.h        |   1 +
 drivers/net/usb/cx82310_eth.c                    |  11 +-
 drivers/regulator/core.c                         |  34 +--
 drivers/scsi/libsas/sas_discover.c               |   6 +-
 drivers/scsi/megaraid/megaraid_sas.h             |   1 -
 drivers/scsi/megaraid/megaraid_sas_base.c        |   5 +-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c               |   2 +-
 drivers/spi/spi-pl022.c                          |   2 +-
 drivers/staging/vt6655/rf.c                      |   1 +
 drivers/target/iscsi/iscsi_target.c              |  14 +-
 drivers/target/iscsi/iscsi_target_login.c        |  50 +++--
 drivers/target/target_core_device.c              |   4 +-
 drivers/target/target_core_pr.c                  | 130 +++++++++---
 drivers/target/target_core_pscsi.c               |   2 +-
 drivers/target/target_core_transport.c           |   4 +
 drivers/target/tcm_fc/tfc_io.c                   |   3 +-
 drivers/tty/serial/8250/8250_pci.c               |   2 +-
 drivers/usb/serial/zte_ev.c                      |   8 +
 drivers/xen/xen-pciback/conf_space.c             |   2 +-
 drivers/xen/xen-pciback/conf_space.h             |   2 +
 drivers/xen/xen-pciback/conf_space_header.c      |  61 ++++--
 fs/btrfs/delayed-inode.c                         |   8 +
 fs/fuse/dev.c                                    |   7 +-
 fs/hfsplus/brec.c                                |  20 +-
 fs/nfs/inode.c                                   |  17 +-
 fs/nfs/nfs3proc.c                                |   2 +-
 fs/nfs/nfs4proc.c                                |   6 +-
 fs/nfs/proc.c                                    |   2 +-
 fs/nilfs2/segment.c                              |   7 +-
 fs/proc/task_mmu.c                               |   3 +
 include/linux/hugetlb.h                          |  10 +-
 include/linux/nfs_fs.h                           |   2 +-
 include/linux/workqueue.h                        |   3 +-
 include/net/sock.h                               |   2 +-
 ipc/sem.c                                        |  15 +-
 ipc/shm.c                                        |  21 +-
 kernel/cpuset.c                                  |   3 -
 kernel/events/core.c                             |  10 +
 kernel/module.c                                  |  37 ++--
 kernel/printk/console_cmdline.h                  |   2 +-
 kernel/printk/printk.c                           |   1 +
 kernel/sysctl.c                                  |   6 +
 kernel/time/ntp.c                                |  10 +-
 kernel/workqueue.c                               |  56 ++++-
 lib/lz4/lz4_decompress.c                         |   3 +
 mm/hugetlb.c                                     |  85 ++++----
 mm/migrate.c                                     |  48 +++++
 net/caif/caif_socket.c                           |   2 +-
 net/can/af_can.c                                 |   3 +
 net/compat.c                                     |   7 +
 net/core/sysctl_net_core.c                       |  10 +-
 net/dns_resolver/dns_query.c                     |   2 +-
 net/ipv4/inet_diag.c                             |  18 +-
 net/ipv4/tcp_output.c                            |  68 +++---
 net/ipv6/addrconf.c                              |  14 +-
 net/ipv6/fib6_rules.c                            |   1 +
 net/mac80211/ieee80211_i.h                       |  23 +-
 net/mac80211/rx.c                                |   3 +
 net/netfilter/nfnetlink_queue_core.c             |  29 ++-
 net/rds/iw_rdma.c                                |  40 ++--
 net/rxrpc/ar-recvmsg.c                           |   2 +-
 net/wireless/chan.c                              |   9 +-
 net/wireless/nl80211.c                           |  10 +
 security/keys/request_key.c                      |   1 +
 sound/core/control.c                             |   4 +
 sound/pci/hda/hda_generic.c                      |  47 +++-
 sound/pci/hda/hda_intel.c                        |   2 +-
 sound/pci/hda/hda_proc.c                         |  38 +++-
 sound/pci/hda/patch_cirrus.c                     |   2 +
 sound/pci/hda/patch_conexant.c                   |  11 +
 sound/soc/codecs/adav80x.c                       |   4 +-
 sound/soc/codecs/ak4641.c                        |   4 +-
 sound/soc/codecs/cs4271.c                        |   4 +-
 sound/soc/codecs/pcm1681.c                       |   4 +-
 sound/soc/codecs/sgtl5000.c                      |   8 +-
 sound/soc/codecs/tas5086.c                       |   4 +-
 sound/soc/codecs/wm2000.c                        |   8 +-
 sound/soc/codecs/wm8731.c                        |   4 +-
 sound/soc/codecs/wm8903.c                        |   4 +-
 sound/soc/codecs/wm8904.c                        |   4 +-
 sound/soc/codecs/wm8955.c                        |   4 +-
 sound/soc/codecs/wm8960.c                        |   4 +-
 sound/usb/quirks-table.h                         |  30 +++
 161 files changed, 1837 insertions(+), 898 deletions(-)
Signature · 1 line
2.3.4
author
#1 lore raw

PATCH 1/155 mm/hugetlb: fix getting refcount 0 page in hugetlb_fault()

From: Naoya Horiguchi <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 0f792cf949a0be506c2aa8bfac0605746b146dda upstream.

When running the test which causes the race as shown in the previous patch, we can hit the BUG "get_page() on refcount 0 page" in hugetlb_fault().

This race happens when pte turns into migration entry just after the first check of is_hugetlb_entry_migration() in hugetlb_fault() passed with false. To fix this, we need to check pte_present() again after huge_ptep_get().

This patch also reorders taking ptl and doing pte_page(), because pte_page() should be done in ptl. Due to this reordering, we need use trylock_page() in page != pagecache_page case to respect locking order.

Fixes 66aebce747ea ("hugetlb: fix race condition in hugetlb_fault()")
Cc Hugh Dickins <[email protected]>
Cc James Hogan <[email protected]>
Cc David Rientjes <[email protected]>
Cc Mel Gorman <[email protected]>
Cc Johannes Weiner <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Rik van Riel <[email protected]>
Cc Andrea Arcangeli <[email protected]>
Cc Luiz Capitulino <[email protected]>
Cc Nishanth Aravamudan <[email protected]>
Cc Lee Schermerhorn <[email protected]>
Cc Steve Capper <[email protected]>
Cc <[email protected]> [3.2+]
---
 mm/hugetlb.c | 51 ++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 36 insertions(+), 15 deletions(-)
mm/hugetlb.c +36 -15
index ed00a70fb052..1b040cb0ac5b 100644
@@ -2960,6 +2960,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 	struct page *pagecache_page = NULL;
 	static DEFINE_MUTEX(hugetlb_instantiation_mutex);
 	struct hstate *h = hstate_vma(vma);
+	int need_wait_lock = 0;
 
 	address &= huge_page_mask(h);
 
@@ -2993,6 +2994,16 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 	ret = 0;
 
 	/*
+	 * entry could be a migration/hwpoison entry at this point, so this
+	 * check prevents the kernel from going below assuming that we have
+	 * a active hugepage in pagecache. This goto expects the 2nd page fault,
+	 * and is_hugetlb_entry_(migration|hwpoisoned) check will properly
+	 * handle it.
+	 */
+	if (!pte_present(entry))
+		goto out_mutex;
+
+	/*
 	 * If we are going to COW the mapping later, we examine the pending
 	 * reservations for this page now. This will ensure that any
 	 * allocations necessary to record that reservation occur outside the
@@ -3011,29 +3022,31 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 								vma, address);
 	}
 
+	spin_lock(&mm->page_table_lock);
+
+	/* Check for a racing update before calling hugetlb_cow */
+	if (unlikely(!pte_same(entry, huge_ptep_get(ptep))))
+		goto out_page_table_lock;
+
 	/*
 	 * hugetlb_cow() requires page locks of pte_page(entry) and
 	 * pagecache_page, so here we need take the former one
 	 * when page != pagecache_page or !pagecache_page.
-	 * Note that locking order is always pagecache_page -> page,
-	 * so no worry about deadlock.
 	 */
 	page = pte_page(entry);
-	get_page(page);
 	if (page != pagecache_page)
-		lock_page(page);
-
-	spin_lock(&mm->page_table_lock);
-	/* Check for a racing update before calling hugetlb_cow */
-	if (unlikely(!pte_same(entry, huge_ptep_get(ptep))))
-		goto out_page_table_lock;
+		if (!trylock_page(page)) {
+			need_wait_lock = 1;
+			goto out_page_table_lock;
+		}
 
+	get_page(page);
 
 	if (flags & FAULT_FLAG_WRITE) {
 		if (!huge_pte_write(entry)) {
 			ret = hugetlb_cow(mm, vma, address, ptep, entry,
 							pagecache_page);
-			goto out_page_table_lock;
+			goto out_put_page;
 		}
 		entry = huge_pte_mkdirty(entry);
 	}
@@ -3041,7 +3054,10 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 	if (huge_ptep_set_access_flags(vma, address, ptep, entry,
 						flags & FAULT_FLAG_WRITE))
 		update_mmu_cache(vma, address, ptep);
-
+out_put_page:
+	if (page != pagecache_page)
+		unlock_page(page);
+	put_page(page);
 out_page_table_lock:
 	spin_unlock(&mm->page_table_lock);
 
@@ -3049,12 +3065,17 @@ out_page_table_lock:
 		unlock_page(pagecache_page);
 		put_page(pagecache_page);
 	}
-	if (page != pagecache_page)
-		unlock_page(page);
-	put_page(page);
-
 out_mutex:
 	mutex_unlock(&hugetlb_instantiation_mutex);
+	/*
+	 * Generally it's safe to hold refcount during waiting page lock. But
+	 * here we just wait to defer the next page fault to avoid busy loop and
+	 * the page is not used after unlocked before returning from the current
+	 * page fault. So we are safe from accessing freed page, even if we wait
+	 * here without taking refcount.
+	 */
+	if (need_wait_lock)
+		wait_on_page_locked(page);
 
 	return ret;
 }
Signature · 1 line
2.3.4
author
#2 lore raw

PATCH 2/155 ALSA: hda - Fix regression of HD-audio controller fallback modes

From: Takashi Iwai <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit a1f3f1ca66bd12c339b17a0c2ef93a093f90a277 upstream.

The commit [63e51fd708f5: ALSA: hda - Don't take unresponsive D3 transition too serious] introduced a conditional fallback behavior to the HD-audio controller depending on the flag set. However, it introduced a silly bug, too, that the flag was evaluated in a reverse way. This resulted in a regression of HD-audio controller driver where it can't go to the fallback mode at communication errors.

Unfortunately (or fortunately?) this didn't come up until recently because the affected code path is an error handling that happens only on an unstable hardware chip. Most of recent chips work stably, thus they didn't hit this problem. Now, we've got a regression report with a VIA chip, and this seems indeed requiring the fallback to the polling mode, and finally the bug was revealed.

The fix is a oneliner to remove the wrong logical NOT in the check. (Lesson learned - be careful about double negation.)

The bug should be backported to stable, but the patch won't be applicable to 3.13 or earlier because of the code splits. The stable fix patches for earlier kernels will be posted later manually.

[... and this is the manual patch -- tiwai]

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

Fixes 63e51fd708f5 ('ALSA: hda - Don't take unresponsive D3 transition too serious')
Cc <[email protected]> # v3.11-3.13
---
 sound/pci/hda/hda_intel.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/pci/hda/hda_intel.c +1 -1
index 86e63b665777..3e57cfcf08e2 100644
@@ -1007,7 +1007,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus,
 		}
 	}
 
-	if (!bus->no_response_fallback)
+	if (bus->no_response_fallback)
 		return -1;
 
 	if (!chip->polling_mode && chip->poll_count < 2) {
Signature · 1 line
2.3.4
author
#3 lore raw

PATCH 3/155 net: sysctl_net_core: check SNDBUF and RCVBUF for min length

In reply to Jiri Slaby

From: Alexey Kodanev <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

[ Upstream commit b1cb59cf2efe7971d3d72a7b963d09a512d994c9 ]

sysctl has sysctl.net.core.rmem_*/wmem_* parameters which can be set to incorrect values. Given that 'struct sk_buff' allocates from rcvbuf, incorrectly set buffer length could result to memory allocation failures. For example, set them as follows:

    # sysctl net.core.rmem_default=64
      net.core.wmem_default = 64
    # sysctl net.core.wmem_default=64
      net.core.wmem_default = 64
    # ping localhost -s 1024 -i 0 > /dev/null

This could result to the following failure:

skbuff: skb_over_panic: text:ffffffff81628db4 len:-32 put:-32 head:ffff88003a1cc200 data:ffff88003a1cc200 tail:0xffffffe0 end:0xc0 dev:<NULL> kernel BUG at net/core/skbuff.c:102!
invalid opcode: 0000 [#1] SMP
...
task: ffff88003b7f5550 ti: ffff88003ae88000 task.ti: ffff88003ae88000

RIP: 0010:[<ffffffff8155fbd1>]  [<ffffffff8155fbd1>] skb_put+0xa1/0xb0
RSP: 0018:ffff88003ae8bc68  EFLAGS: 00010296
RAX: 000000000000008d RBX: 00000000ffffffe0 RCX: 0000000000000000
RDX: ffff88003fdcf598 RSI: ffff88003fdcd9c8 RDI: ffff88003fdcd9c8
RBP: ffff88003ae8bc88 R08: 0000000000000001 R09: 0000000000000000
R10: 0000000000000001 R11: 00000000000002b2 R12: 0000000000000000
R13: 0000000000000000 R14: ffff88003d3f7300 R15: ffff88000012a900
FS:  00007fa0e2b4a840(0000) GS:ffff88003fc00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000d0f7e0 CR3: 000000003b8fb000 CR4: 00000000000006f0
Stack:
 ffff88003a1cc200 00000000ffffffe0 00000000000000c0 ffffffff818cab1d
 ffff88003ae8bd68 ffffffff81628db4 ffff88003ae8bd48 ffff88003b7f5550
 ffff880031a09408 ffff88003b7f5550 ffff88000012aa48 ffff88000012ab00
Call Trace:
 [<ffffffff81628db4>] unix_stream_sendmsg+0x2c4/0x470
 [<ffffffff81556f56>] sock_write_iter+0x146/0x160
 [<ffffffff811d9612>] new_sync_write+0x92/0xd0
 [<ffffffff811d9cd6>] vfs_write+0xd6/0x180
 [<ffffffff811da499>] SyS_write+0x59/0xd0
 [<ffffffff81651532>] system_call_fastpath+0x12/0x17
Code: 00 00 48 89 44 24 10 8b 87 c8 00 00 00 48 89 44 24 08 48 8b 87 d8 00
      00 00 48 c7 c7 30 db 91 81 48 89 04 24 31 c0 e8 4f a8 0e 00 <0f> 0b
      eb fe 66 66 2e 0f 1f 84 00 00 00 00 00 55 48 89 e5 48 83
RIP  [<ffffffff8155fbd1>] skb_put+0xa1/0xb0
RSP <ffff88003ae8bc68>
Kernel panic - not syncing: Fatal exception

Moreover, the possible minimum is 1, so we can get another kernel panic:
...

BUG: unable to handle kernel paging request at ffff88013caee5c0
IP: [<ffffffff815604cf>] __alloc_skb+0x12f/0x1f0

...

---
 net/core/sysctl_net_core.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
net/core/sysctl_net_core.c +6 -4
index cca444190907..f3413ae3d973 100644
@@ -25,6 +25,8 @@
 static int zero = 0;
 static int one = 1;
 static int ushort_max = USHRT_MAX;
+static int min_sndbuf = SOCK_MIN_SNDBUF;
+static int min_rcvbuf = SOCK_MIN_RCVBUF;
 
 #ifdef CONFIG_RPS
 static int rps_sock_flow_sysctl(struct ctl_table *table, int write,
@@ -222,7 +224,7 @@ static struct ctl_table net_core_table[] = {
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &one,
+		.extra1		= &min_sndbuf,
 	},
 	{
 		.procname	= "rmem_max",
@@ -230,7 +232,7 @@ static struct ctl_table net_core_table[] = {
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &one,
+		.extra1		= &min_rcvbuf,
 	},
 	{
 		.procname	= "wmem_default",
@@ -238,7 +240,7 @@ static struct ctl_table net_core_table[] = {
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &one,
+		.extra1		= &min_sndbuf,
 	},
 	{
 		.procname	= "rmem_default",
@@ -246,7 +248,7 @@ static struct ctl_table net_core_table[] = {
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &one,
+		.extra1		= &min_rcvbuf,
 	},
 	{
 		.procname	= "dev_weight",
Signature · 1 line
2.3.4
author
#4 lore raw

PATCH 4/155 rds: avoid potential stack overflow

In reply to Jiri Slaby

From: Arnd Bergmann <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

[ Upstream commit f862e07cf95d5b62a5fc5e981dd7d0dbaf33a501 ]

The rds_iw_update_cm_id function stores a large 'struct rds_sock' object on the stack in order to pass a pair of addresses. This happens to just fit withint the 1024 byte stack size warning limit on x86, but just exceed that limit on ARM, which gives us this warning:

net/rds/iw_rdma.c:200:1: warning: the frame size of 1056 bytes is larger than 1024 bytes [-Wframe-larger-than=]

As the use of this large variable is basically bogus, we can rearrange the code to not do that. Instead of passing an rds socket into rds_iw_get_device, we now just pass the two addresses that we have available in rds_iw_update_cm_id, and we change rds_iw_get_mr accordingly, to create two address structures on the stack there.

---
 net/rds/iw_rdma.c | 40 ++++++++++++++++++++++------------------
 1 file changed, 22 insertions(+), 18 deletions(-)
net/rds/iw_rdma.c +22 -18
index a817705ce2d0..dba8d0864f18 100644
@@ -88,7 +88,9 @@ static unsigned int rds_iw_unmap_fastreg_list(struct rds_iw_mr_pool *pool,
 			int *unpinned);
 static void rds_iw_destroy_fastreg(struct rds_iw_mr_pool *pool, struct rds_iw_mr *ibmr);
 
-static int rds_iw_get_device(struct rds_sock *rs, struct rds_iw_device **rds_iwdev, struct rdma_cm_id **cm_id)
+static int rds_iw_get_device(struct sockaddr_in *src, struct sockaddr_in *dst,
+			     struct rds_iw_device **rds_iwdev,
+			     struct rdma_cm_id **cm_id)
 {
 	struct rds_iw_device *iwdev;
 	struct rds_iw_cm_id *i_cm_id;
@@ -112,15 +114,15 @@ static int rds_iw_get_device(struct rds_sock *rs, struct rds_iw_device **rds_iwd
 				src_addr->sin_port,
 				dst_addr->sin_addr.s_addr,
 				dst_addr->sin_port,
-				rs->rs_bound_addr,
-				rs->rs_bound_port,
-				rs->rs_conn_addr,
-				rs->rs_conn_port);
+				src->sin_addr.s_addr,
+				src->sin_port,
+				dst->sin_addr.s_addr,
+				dst->sin_port);
 #ifdef WORKING_TUPLE_DETECTION
-			if (src_addr->sin_addr.s_addr == rs->rs_bound_addr &&
-			    src_addr->sin_port == rs->rs_bound_port &&
-			    dst_addr->sin_addr.s_addr == rs->rs_conn_addr &&
-			    dst_addr->sin_port == rs->rs_conn_port) {
+			if (src_addr->sin_addr.s_addr == src->sin_addr.s_addr &&
+			    src_addr->sin_port == src->sin_port &&
+			    dst_addr->sin_addr.s_addr == dst->sin_addr.s_addr &&
+			    dst_addr->sin_port == dst->sin_port) {
 #else
 			/* FIXME - needs to compare the local and remote
 			 * ipaddr/port tuple, but the ipaddr is the only
@@ -128,7 +130,7 @@ static int rds_iw_get_device(struct rds_sock *rs, struct rds_iw_device **rds_iwd
 			 * zero'ed.  It doesn't appear to be properly populated
 			 * during connection setup...
 			 */
-			if (src_addr->sin_addr.s_addr == rs->rs_bound_addr) {
+			if (src_addr->sin_addr.s_addr == src->sin_addr.s_addr) {
 #endif
 				spin_unlock_irq(&iwdev->spinlock);
 				*rds_iwdev = iwdev;
@@ -180,19 +182,13 @@ int rds_iw_update_cm_id(struct rds_iw_device *rds_iwdev, struct rdma_cm_id *cm_i
 {
 	struct sockaddr_in *src_addr, *dst_addr;
 	struct rds_iw_device *rds_iwdev_old;
-	struct rds_sock rs;
 	struct rdma_cm_id *pcm_id;
 	int rc;
 
 	src_addr = (struct sockaddr_in *)&cm_id->route.addr.src_addr;
 	dst_addr = (struct sockaddr_in *)&cm_id->route.addr.dst_addr;
 
-	rs.rs_bound_addr = src_addr->sin_addr.s_addr;
-	rs.rs_bound_port = src_addr->sin_port;
-	rs.rs_conn_addr = dst_addr->sin_addr.s_addr;
-	rs.rs_conn_port = dst_addr->sin_port;
-
-	rc = rds_iw_get_device(&rs, &rds_iwdev_old, &pcm_id);
+	rc = rds_iw_get_device(src_addr, dst_addr, &rds_iwdev_old, &pcm_id);
 	if (rc)
 		rds_iw_remove_cm_id(rds_iwdev, cm_id);
 
@@ -598,9 +594,17 @@ void *rds_iw_get_mr(struct scatterlist *sg, unsigned long nents,
 	struct rds_iw_device *rds_iwdev;
 	struct rds_iw_mr *ibmr = NULL;
 	struct rdma_cm_id *cm_id;
+	struct sockaddr_in src = {
+		.sin_addr.s_addr = rs->rs_bound_addr,
+		.sin_port = rs->rs_bound_port,
+	};
+	struct sockaddr_in dst = {
+		.sin_addr.s_addr = rs->rs_conn_addr,
+		.sin_port = rs->rs_conn_port,
+	};
 	int ret;
 
-	ret = rds_iw_get_device(rs, &rds_iwdev, &cm_id);
+	ret = rds_iw_get_device(&src, &dst, &rds_iwdev, &cm_id);
 	if (ret || !cm_id) {
 		ret = -ENODEV;
 		goto out;
Signature · 1 line
2.3.4
author
#5 lore raw

PATCH 5/155 inet_diag: fix possible overflow in inet_diag_dump_one_icsk()

In reply to Jiri Slaby

From: Eric Dumazet <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

[ Upstream commit c8e2c80d7ec00d020320f905822bf49c5ad85250 ]

inet_diag_dump_one_icsk() allocates too small skb.

Add inet_sk_attr_size() helper right before inet_sk_diag_fill() so that it can be updated if/when new attributes are added.

iproute2/ss currently does not use this dump_one() interface, this might explain nobody noticed this problem yet.

---
 net/ipv4/inet_diag.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)
net/ipv4/inet_diag.c +15 -3
index 45dbdab915e2..14a1ed611b05 100644
@@ -71,6 +71,20 @@ static inline void inet_diag_unlock_handler(
 	mutex_unlock(&inet_diag_table_mutex);
 }
 
+static size_t inet_sk_attr_size(void)
+{
+	return	  nla_total_size(sizeof(struct tcp_info))
+		+ nla_total_size(1) /* INET_DIAG_SHUTDOWN */
+		+ nla_total_size(1) /* INET_DIAG_TOS */
+		+ nla_total_size(1) /* INET_DIAG_TCLASS */
+		+ nla_total_size(sizeof(struct inet_diag_meminfo))
+		+ nla_total_size(sizeof(struct inet_diag_msg))
+		+ nla_total_size(SK_MEMINFO_VARS * sizeof(u32))
+		+ nla_total_size(TCP_CA_NAME_MAX)
+		+ nla_total_size(sizeof(struct tcpvegas_info))
+		+ 64;
+}
+
 int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
 			      struct sk_buff *skb, struct inet_diag_req_v2 *req,
 			      struct user_namespace *user_ns,		      	
@@ -326,9 +340,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s
 	if (err)
 		goto out;
 
-	rep = nlmsg_new(sizeof(struct inet_diag_msg) +
-			sizeof(struct inet_diag_meminfo) +
-			sizeof(struct tcp_info) + 64, GFP_KERNEL);
+	rep = nlmsg_new(inet_sk_attr_size(), GFP_KERNEL);
 	if (!rep) {
 		err = -ENOMEM;
 		goto out;
Signature · 1 line
2.3.4
author
#6 lore raw

PATCH 6/155 caif: fix MSG_OOB test in caif_seqpkt_recvmsg()

In reply to Jiri Slaby

From: Al Viro <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

[ Upstream commit 3eeff778e00c956875c70b145c52638c313dfb23 ]

It should be checking flags, not msg->msg_flags. It's ->sendmsg() instances that need to look for that in ->msg_flags, ->recvmsg() ones (including the other ->recvmsg() instance in that file, as well as unix_dgram_recvmsg() this one claims to be imitating) check in flags. Braino had been introduced in commit dcda13 ("caif: Bugfix - use MSG_TRUNC in receive") back in 2010, so it goes quite a while back.

---
 net/caif/caif_socket.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/caif/caif_socket.c +1 -1
index d6be3edb7a43..526bf56f4d31 100644
@@ -283,7 +283,7 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock,
 	int copylen;
 
 	ret = -EOPNOTSUPP;
-	if (m->msg_flags&MSG_OOB)
+	if (flags & MSG_OOB)
 		goto read_error;
 
 	skb = skb_recv_datagram(sk, flags, 0 , &ret);
Signature · 1 line
2.3.4
author
#7 lore raw

PATCH 7/155 rxrpc: bogus MSG_PEEK test in rxrpc_recvmsg()

In reply to Jiri Slaby

From: Al Viro <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

[ Upstream commit 7d985ed1dca5c90535d67ce92ef6ca520302340a ]

[I would really like an ACK on that one from dhowells; it appears to be quite straightforward, but...]

MSG_PEEK isn't passed to ->recvmsg() via msg->msg_flags; as the matter of fact, neither the kernel users of rxrpc, nor the syscalls ever set that bit in there. It gets passed via flags; in fact, another such check in the same function is done correctly - as flags & MSG_PEEK.

It had been that way (effectively disabled) for 8 years, though, so the patch needs beating up - that case had never been tested. If it is correct, it's -stable fodder.

---
 net/rxrpc/ar-recvmsg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/rxrpc/ar-recvmsg.c +1 -1
index 898492a8d61b..5cc2da5d295d 100644
@@ -87,7 +87,7 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,
 		if (!skb) {
 			/* nothing remains on the queue */
 			if (copied &&
-			    (msg->msg_flags & MSG_PEEK || timeo == 0))
+			    (flags & MSG_PEEK || timeo == 0))
 				goto out;
 
 			/* wait for a message to turn up */
Signature · 1 line
2.3.4
author
#8 lore raw

PATCH 8/155 Revert "net: cx82310_eth: use common match macro"

In reply to Jiri Slaby

From: Ondrej Zary <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

[ Upstream commit 8d006e0105978619fb472e150c88b0d49337fe2b ]

This reverts commit 11ad714b98f6d9ca0067568442afe3e70eb94845 because it breaks cx82310_eth.

The custom USB_DEVICE_CLASS macro matches
bDeviceClass, bDeviceSubClass and bDeviceProtocol
but the common USB_DEVICE_AND_INTERFACE_INFO matches bInterfaceClass, bInterfaceSubClass and bInterfaceProtocol instead, which are not specified.

---
 drivers/net/usb/cx82310_eth.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/net/usb/cx82310_eth.c +10 -1
index 1e207f086b75..49ab45e17fe8 100644
@@ -302,9 +302,18 @@ static const struct driver_info	cx82310_info = {
 	.tx_fixup	= cx82310_tx_fixup,
 };
 
+#define USB_DEVICE_CLASS(vend, prod, cl, sc, pr) \
+	.match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
+		       USB_DEVICE_ID_MATCH_DEV_INFO, \
+	.idVendor = (vend), \
+	.idProduct = (prod), \
+	.bDeviceClass = (cl), \
+	.bDeviceSubClass = (sc), \
+	.bDeviceProtocol = (pr)
+
 static const struct usb_device_id products[] = {
 	{
-		USB_DEVICE_AND_INTERFACE_INFO(0x0572, 0xcb01, 0xff, 0, 0),
+		USB_DEVICE_CLASS(0x0572, 0xcb01, 0xff, 0, 0),
 		.driver_info = (unsigned long) &cx82310_info
 	},
 	{ },
Signature · 1 line
2.3.4
author
#9 lore raw

PATCH 9/155 ipv6: fix backtracking for throw routes

In reply to Jiri Slaby

From: Steven Barth <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

[ Upstream commit 73ba57bfae4a1914f6a6dac71e3168dd900e00af ]

for throw routes to trigger evaluation of other policy rules EAGAIN needs to be propagated up to fib_rules_lookup similar to how its done for IPv4

A simple testcase for verification is:

ip -6 rule add lookup 33333 priority 33333
ip -6 route add throw 2001:db8::1
ip -6 route add 2001:db8::1 via fe80::1 dev wlan0 table 33333 ip route get 2001:db8::1

---
 net/ipv6/fib6_rules.c | 1 +
 1 file changed, 1 insertion(+)
net/ipv6/fib6_rules.c +1 -0
index 3fd0a578329e..ab82a47d0bdf 100644
@@ -104,6 +104,7 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
 				goto again;
 			flp6->saddr = saddr;
 		}
+		err = rt->dst.error;
 		goto out;
 	}
 again:
Signature · 1 line
2.3.4
author
#10 lore raw

PATCH 10/155 tcp: fix tcp fin memory accounting

In reply to Jiri Slaby

From: Josh Hunt <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

[ Upstream commit d22e1537181188e5dc8cbc51451832625035bdc2 ]

tcp_send_fin() does not account for the memory it allocates properly, so sk_forward_alloc can be negative in cases where we've sent a FIN:

ss example output (ss -amn | grep -B1 f4294):
tcp FIN-WAIT-1 0 1 192.168.0.1:45520 192.0.2.1:8080

	skmem:(r0,rb87380,t0,tb87380,f4294966016,w1280,o0,bl0)
---
 net/ipv4/tcp_output.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
net/ipv4/tcp_output.c +1 -5
index b4435ae4c485..c3cfdad25629 100644
@@ -2603,15 +2603,11 @@ void tcp_send_fin(struct sock *sk)
 	} else {
 		/* Socket is locked, keep trying until memory is available. */
 		for (;;) {
-			skb = alloc_skb_fclone(MAX_TCP_HEADER,
-					       sk->sk_allocation);
+			skb = sk_stream_alloc_skb(sk, 0, sk->sk_allocation);
 			if (skb)
 				break;
 			yield();
 		}
-
-		/* Reserve space for headers and prepare control bits. */
-		skb_reserve(skb, MAX_TCP_HEADER);
 		/* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */
 		tcp_init_nondata_skb(skb, tp->write_seq,
 				     TCPHDR_ACK | TCPHDR_FIN);
Signature · 1 line
2.3.4
author
#11 lore raw

PATCH 11/155 net: compat: Update get_compat_msghdr() to match copy_msghdr_from_user() behaviour

In reply to Jiri Slaby

From: Catalin Marinas <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

[ Upstream commit 91edd096e224941131f896b86838b1e59553696a ]

Commit db31c55a6fb2 (net: clamp ->msg_namelen instead of returning an error) introduced the clamping of msg_namelen when the unsigned value was larger than sizeof(struct sockaddr_storage). This caused a msg_namelen of -1 to be valid. The native code was subsequently fixed by commit dbb490b96584 (net: socket: error on a negative msg_namelen).

In addition, the native code sets msg_namelen to 0 when msg_name is NULL. This was done in commit (6a2a2b3ae075 net:socket: set msg_namelen to 0 if msg_name is passed as NULL in msghdr struct from userland) and subsequently updated by 08adb7dabd48 (fold verify_iovec() into copy_msghdr_from_user()).

This patch brings the get_compat_msghdr() in line with copy_msghdr_from_user().

Fixes db31c55a6fb2 (net: clamp ->msg_namelen instead of returning an error)
Cc David S. Miller <[email protected]>
Cc Dan Carpenter <[email protected]>
---
 net/compat.c | 7 +++++++
 1 file changed, 7 insertions(+)
net/compat.c +7 -0
index 275af79c131b..d12529050b29 100644
@@ -71,6 +71,13 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg)
 	    __get_user(kmsg->msg_controllen, &umsg->msg_controllen) ||
 	    __get_user(kmsg->msg_flags, &umsg->msg_flags))
 		return -EFAULT;
+
+	if (!tmp1)
+		kmsg->msg_namelen = 0;
+
+	if (kmsg->msg_namelen < 0)
+		return -EINVAL;
+
 	if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
 		kmsg->msg_namelen = sizeof(struct sockaddr_storage);
 	kmsg->msg_name = compat_ptr(tmp1);
Signature · 1 line
2.3.4
author
#12 lore raw

PATCH 12/155 tcp: make connect() mem charging friendly

In reply to Jiri Slaby

From: Eric Dumazet <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

[ Upstream commit 355a901e6cf1b2b763ec85caa2a9f04fbcc4ab4a ]

While working on sk_forward_alloc problems reported by Denys Fedoryshchenko, we found that tcp connect() (and fastopen) do not call sk_wmem_schedule() for SYN packet (and/or SYN/DATA packet), so sk_forward_alloc is negative while connect is in progress.

We can fix this by calling regular sk_stream_alloc_skb() both for the SYN packet (in tcp_connect()) and the syn_data packet in tcp_send_syn_data()

Then, tcp_send_syn_data() can avoid copying syn_data as we simply can manipulate syn_data->cb[] to remove SYN flag (and increment seq)

Instead of open coding memcpy_fromiovecend(), simply use this helper.

This leaves in socket write queue clean fast clone skbs.

This was tested against our fastopen packetdrill tests.

---
 net/ipv4/tcp_output.c | 62 ++++++++++++++++++++++-----------------------------
 1 file changed, 27 insertions(+), 35 deletions(-)
net/ipv4/tcp_output.c +27 -35
index c3cfdad25629..e07ccba040be 100644
@@ -2881,9 +2881,9 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct tcp_fastopen_request *fo = tp->fastopen_req;
-	int syn_loss = 0, space, i, err = 0, iovlen = fo->data->msg_iovlen;
-	struct sk_buff *syn_data = NULL, *data;
+	int syn_loss = 0, space, err = 0;
 	unsigned long last_syn_loss = 0;
+	struct sk_buff *syn_data;
 
 	tp->rx_opt.mss_clamp = tp->advmss;  /* If MSS is not cached */
 	tcp_fastopen_cache_get(sk, &tp->rx_opt.mss_clamp, &fo->cookie,
@@ -2914,42 +2914,38 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
 	/* limit to order-0 allocations */
 	space = min_t(size_t, space, SKB_MAX_HEAD(MAX_TCP_HEADER));
 
-	syn_data = skb_copy_expand(syn, MAX_TCP_HEADER, space,
-				   sk->sk_allocation);
-	if (syn_data == NULL)
+	syn_data = sk_stream_alloc_skb(sk, space, sk->sk_allocation);
+	if (!syn_data)
 		goto fallback;
+	syn_data->ip_summed = CHECKSUM_PARTIAL;
+	memcpy(syn_data->cb, syn->cb, sizeof(syn->cb));
+	if (unlikely(memcpy_fromiovecend(skb_put(syn_data, space),
+					 fo->data->msg_iov, 0, space))) {
+		kfree_skb(syn_data);
+		goto fallback;
+	}
 
-	for (i = 0; i < iovlen && syn_data->len < space; ++i) {
-		struct iovec *iov = &fo->data->msg_iov[i];
-		unsigned char __user *from = iov->iov_base;
-		int len = iov->iov_len;
+	/* No more data pending in inet_wait_for_connect() */
+	if (space == fo->size)
+		fo->data = NULL;
+	fo->copied = space;
 
-		if (syn_data->len + len > space)
-			len = space - syn_data->len;
-		else if (i + 1 == iovlen)
-			/* No more data pending in inet_wait_for_connect() */
-			fo->data = NULL;
+	tcp_connect_queue_skb(sk, syn_data);
 
-		if (skb_add_data(syn_data, from, len))
-			goto fallback;
-	}
-
-	/* Queue a data-only packet after the regular SYN for retransmission */
-	data = pskb_copy(syn_data, sk->sk_allocation);
-	if (data == NULL)
-		goto fallback;
-	TCP_SKB_CB(data)->seq++;
-	TCP_SKB_CB(data)->tcp_flags &= ~TCPHDR_SYN;
-	TCP_SKB_CB(data)->tcp_flags = (TCPHDR_ACK|TCPHDR_PSH);
-	tcp_connect_queue_skb(sk, data);
-	fo->copied = data->len;
+	err = tcp_transmit_skb(sk, syn_data, 1, sk->sk_allocation);
 
-	if (tcp_transmit_skb(sk, syn_data, 0, sk->sk_allocation) == 0) {
+	/* Now full SYN+DATA was cloned and sent (or not),
+	 * remove the SYN from the original skb (syn_data)
+	 * we keep in write queue in case of a retransmit, as we
+	 * also have the SYN packet (with no data) in the same queue.
+	 */
+	TCP_SKB_CB(syn_data)->seq++;
+	TCP_SKB_CB(syn_data)->tcp_flags = TCPHDR_ACK | TCPHDR_PSH;
+	if (!err) {
 		tp->syn_data = (fo->copied > 0);
 		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPFASTOPENACTIVE);
 		goto done;
 	}
-	syn_data = NULL;
 
 fallback:
 	/* Send a regular SYN with Fast Open cookie request option */
@@ -2958,7 +2954,6 @@ fallback:
 	err = tcp_transmit_skb(sk, syn, 1, sk->sk_allocation);
 	if (err)
 		tp->syn_fastopen = 0;
-	kfree_skb(syn_data);
 done:
 	fo->cookie.len = -1;  /* Exclude Fast Open option for SYN retries */
 	return err;
@@ -2978,13 +2973,10 @@ int tcp_connect(struct sock *sk)
 		return 0;
 	}
 
-	buff = alloc_skb_fclone(MAX_TCP_HEADER + 15, sk->sk_allocation);
-	if (unlikely(buff == NULL))
+	buff = sk_stream_alloc_skb(sk, 0, sk->sk_allocation);
+	if (unlikely(!buff))
 		return -ENOBUFS;
 
-	/* Reserve space for headers. */
-	skb_reserve(buff, MAX_TCP_HEADER);
-
 	tcp_init_nondata_skb(buff, tp->write_seq++, TCPHDR_SYN);
 	tp->retrans_stamp = TCP_SKB_CB(buff)->when = tcp_time_stamp;
 	tcp_connect_queue_skb(sk, buff);
Signature · 1 line
2.3.4
author
#13 lore raw

PATCH 13/155 sparc32: destroy_context() and switch_mm() needs to disable interrupts.

In reply to Jiri Slaby

From: Andreas Larsson <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

[ Upstream commit 66d0f7ec9f1038452178b1993fc07fd96d30fd38 ]

Load balancing can be triggered in the critical sections protected by srmmu_context_spinlock in destroy_context() and switch_mm() and can hang the cpu waiting for the rq lock of another cpu that in turn has called switch_mm hangning on srmmu_context_spinlock leading to deadlock.

So, disable interrupt while taking srmmu_context_spinlock in destroy_context() and switch_mm() so we don't deadlock.

See also commit 77b838fa1ef0 ("[SPARC64]: destroy_context() needs to disable interrupts.")

---
 arch/sparc/mm/srmmu.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
arch/sparc/mm/srmmu.c +7 -4
index 5d721df48a72..1e0e7d2837da 100644
@@ -455,10 +455,12 @@ static void __init sparc_context_init(int numctx)
 void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm,
 	       struct task_struct *tsk)
 {
+	unsigned long flags;
+
 	if (mm->context == NO_CONTEXT) {
-		spin_lock(&srmmu_context_spinlock);
+		spin_lock_irqsave(&srmmu_context_spinlock, flags);
 		alloc_context(old_mm, mm);
-		spin_unlock(&srmmu_context_spinlock);
+		spin_unlock_irqrestore(&srmmu_context_spinlock, flags);
 		srmmu_ctxd_set(&srmmu_context_table[mm->context], mm->pgd);
 	}
 
@@ -983,14 +985,15 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
 
 void destroy_context(struct mm_struct *mm)
 {
+	unsigned long flags;
 
 	if (mm->context != NO_CONTEXT) {
 		flush_cache_mm(mm);
 		srmmu_ctxd_set(&srmmu_context_table[mm->context], srmmu_swapper_pg_dir);
 		flush_tlb_mm(mm);
-		spin_lock(&srmmu_context_spinlock);
+		spin_lock_irqsave(&srmmu_context_spinlock, flags);
 		free_context(mm->context);
-		spin_unlock(&srmmu_context_spinlock);
+		spin_unlock_irqrestore(&srmmu_context_spinlock, flags);
 		mm->context = NO_CONTEXT;
 	}
 }
Signature · 1 line
2.3.4
author
#14 lore raw

PATCH 14/155 sparc: semtimedop() unreachable due to comparison error

In reply to Jiri Slaby

From: Rob Gardner <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

[ Upstream commit 53eb2516972b8c4628651dfcb926cb9ef8b2864a ]

A bug was reported that the semtimedop() system call was always failing eith ENOSYS.

Since SEMCTL is defined as 3, and SEMTIMEDOP is defined as 4, the comparison "call <= SEMCTL" will always prevent SEMTIMEDOP from getting through to the semaphore ops switch statement.

This is corrected by changing the comparison to "call <= SEMTIMEDOP".

Orabug: 20633375

---
 arch/sparc/kernel/sys_sparc_64.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/sparc/kernel/sys_sparc_64.c +1 -1
index d05eb9c1d846..d188c591f2d6 100644
@@ -331,7 +331,7 @@ SYSCALL_DEFINE6(sparc_ipc, unsigned int, call, int, first, unsigned long, second
 	long err;
 
 	/* No need for backward compatibility. We can start fresh... */
-	if (call <= SEMCTL) {
+	if (call <= SEMTIMEDOP) {
 		switch (call) {
 		case SEMOP:
 			err = sys_semtimedop(first, ptr,
Signature · 1 line
2.3.4
author
#15 lore raw

PATCH 15/155 sparc: perf: Remove redundant perf_pmu_{en|dis}able calls

In reply to Jiri Slaby

From: David Ahern <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

[ Upstream commit 5b0d4b5514bbcce69b516d0742f2cfc84ebd6db3 ]

perf_pmu_disable is called by core perf code before pmu->del and the enable function is called by core perf code afterwards. No need to call again within sparc_pmu_del.

Ditto for pmu->add and sparc_pmu_add.

---
 arch/sparc/kernel/perf_event.c | 4 ----
 1 file changed, 4 deletions(-)
arch/sparc/kernel/perf_event.c +0 -4
index 617b9fe33771..102199579d67 100644
@@ -1101,7 +1101,6 @@ static void sparc_pmu_del(struct perf_event *event, int _flags)
 	int i;
 
 	local_irq_save(flags);
-	perf_pmu_disable(event->pmu);
 
 	for (i = 0; i < cpuc->n_events; i++) {
 		if (event == cpuc->event[i]) {
@@ -1127,7 +1126,6 @@ static void sparc_pmu_del(struct perf_event *event, int _flags)
 		}
 	}
 
-	perf_pmu_enable(event->pmu);
 	local_irq_restore(flags);
 }
 
@@ -1361,7 +1359,6 @@ static int sparc_pmu_add(struct perf_event *event, int ef_flags)
 	unsigned long flags;
 
 	local_irq_save(flags);
-	perf_pmu_disable(event->pmu);
 
 	n0 = cpuc->n_events;
 	if (n0 >= sparc_pmu->max_hw_events)
@@ -1394,7 +1391,6 @@ nocheck:
 
 	ret = 0;
 out:
-	perf_pmu_enable(event->pmu);
 	local_irq_restore(flags);
 	return ret;
 }
Signature · 1 line
2.3.4
author
#16 lore raw

PATCH 16/155 sparc: perf: Make counting mode actually work

In reply to Jiri Slaby

From: David Ahern <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

[ Upstream commit d51291cb8f32bfae6b331e1838651f3ddefa73a5 ]

Currently perf-stat (aka, counting mode) does not work:

$ perf stat ls
...
 Performance counter stats for 'ls':
          1.585665      task-clock (msec)         #    0.580 CPUs utilized
                24      context-switches          #    0.015 M/sec
                 0      cpu-migrations            #    0.000 K/sec
                86      page-faults               #    0.054 M/sec
   <not supported>      cycles
   <not supported>      stalled-cycles-frontend
   <not supported>      stalled-cycles-backend
   <not supported>      instructions
   <not supported>      branches
   <not supported>      branch-misses
       0.002735100 seconds time elapsed

The reason is that state is never reset (stays with PERF_HES_UPTODATE set). Add a call to sparc_pmu_enable_event during the added_event handling. Clean up the encoding since pmu_start calls sparc_pmu_enable_event which does the same. Passing PERF_EF_RELOAD to sparc_pmu_start means the call to sparc_perf_event_set_period can be removed as well.

With this patch:

$ perf stat ls
...
 Performance counter stats for 'ls':
          1.552890      task-clock (msec)         #    0.552 CPUs utilized
                24      context-switches          #    0.015 M/sec
                 0      cpu-migrations            #    0.000 K/sec
                86      page-faults               #    0.055 M/sec
         5,748,997      cycles                    #    3.702 GHz
   <not supported>      stalled-cycles-frontend:HG
   <not supported>      stalled-cycles-backend:HG
         1,684,362      instructions:HG           #    0.29  insns per cycle
           295,133      branches:HG               #  190.054 M/sec
            28,007      branch-misses:HG          #    9.49% of all branches
       0.002815665 seconds time elapsed
---
 arch/sparc/kernel/perf_event.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)
arch/sparc/kernel/perf_event.c +3 -8
index 102199579d67..3ccb6777a7e1 100644
@@ -960,6 +960,8 @@ out:
 	cpuc->pcr[0] |= cpuc->event[0]->hw.config_base;
 }
 
+static void sparc_pmu_start(struct perf_event *event, int flags);
+
 /* On this PMU each PIC has it's own PCR control register.  */
 static void calculate_multiple_pcrs(struct cpu_hw_events *cpuc)
 {
@@ -972,20 +974,13 @@ static void calculate_multiple_pcrs(struct cpu_hw_events *cpuc)
 		struct perf_event *cp = cpuc->event[i];
 		struct hw_perf_event *hwc = &cp->hw;
 		int idx = hwc->idx;
-		u64 enc;
 
 		if (cpuc->current_idx[i] != PIC_NO_INDEX)
 			continue;
 
-		sparc_perf_event_set_period(cp, hwc, idx);
 		cpuc->current_idx[i] = idx;
 
-		enc = perf_event_get_enc(cpuc->events[i]);
-		cpuc->pcr[idx] &= ~mask_for_index(idx);
-		if (hwc->state & PERF_HES_STOPPED)
-			cpuc->pcr[idx] |= nop_for_index(idx);
-		else
-			cpuc->pcr[idx] |= event_encoding(enc, idx);
+		sparc_pmu_start(cp, PERF_EF_RELOAD);
 	}
 out:
 	for (i = 0; i < cpuc->n_events; i++) {
Signature · 1 line
2.3.4
author
#17 lore raw

PATCH 17/155 sparc: Touch NMI watchdog when walking cpus and calling printk

In reply to Jiri Slaby

From: David Ahern <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

[ Upstream commit 31aaa98c248da766ece922bbbe8cc78cfd0bc920 ]

With the increase in number of CPUs calls to functions that dump output to console (e.g., arch_trigger_all_cpu_backtrace) can take a long time to complete. If IRQs are disabled eventually the NMI watchdog kicks in and creates more havoc. Avoid by telling the NMI watchdog everything is ok.

---
 arch/sparc/kernel/process_64.c | 4 ++++
 1 file changed, 4 insertions(+)
arch/sparc/kernel/process_64.c +4 -0
index fa49b80d8ab6..6616c775c4dd 100644
@@ -280,6 +280,8 @@ void arch_trigger_all_cpu_backtrace(void)
 			printk("             TPC[%lx] O7[%lx] I7[%lx] RPC[%lx]\n",
 			       gp->tpc, gp->o7, gp->i7, gp->rpc);
 		}
+
+		touch_nmi_watchdog();
 	}
 
 	memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot));
@@ -355,6 +357,8 @@ static void pmu_snapshot_all_cpus(void)
 		       (cpu == this_cpu ? '*' : ' '), cpu,
 		       pp->pcr[0], pp->pcr[1], pp->pcr[2], pp->pcr[3],
 		       pp->pic[0], pp->pic[1], pp->pic[2], pp->pic[3]);
+
+		touch_nmi_watchdog();
 	}
 
 	memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot));
Signature · 1 line
2.3.4
author
#18 lore raw

PATCH 18/155 sparc64: Fix several bugs in memmove().

In reply to Jiri Slaby

From: "David S. Miller" <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

[ Upstream commit 2077cef4d5c29cf886192ec32066f783d6a80db8 ]

Firstly, handle zero length calls properly. Believe it or not there are a few of these happening during early boot.

Next, we can't just drop to a memcpy() call in the forward copy case where dst <= src. The reason is that the cache initializing stores used in the Niagara memcpy() implementations can end up clearing out cache lines before we've sourced their original contents completely.

For example, considering NG4memcpy, the main unrolled loop begins like this:

     load   src + 0x00
     load   src + 0x08
     load   src + 0x10
     load   src + 0x18
     load   src + 0x20
     store  dst + 0x00

Assume dst is 64 byte aligned and let's say that dst is src - 8 for this memcpy() call. That store at the end there is the one to the first line in the cache line, thus clearing the whole line, which thus clobbers "src + 0x28" before it even gets loaded.

To avoid this, just fall through to a simple copy only mildly optimized for the case where src and dst are 8 byte aligned and the length is a multiple of 8 as well. We could get fancy and call GENmemcpy() but this is good enough for how this thing is actually used.

---
 arch/sparc/lib/memmove.S | 35 ++++++++++++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 3 deletions(-)
arch/sparc/lib/memmove.S +32 -3
index b7f6334e159f..857ad4f8905f 100644
@@ -8,9 +8,11 @@
 
 	.text
 ENTRY(memmove) /* o0=dst o1=src o2=len */
-	mov		%o0, %g1
+	brz,pn		%o2, 99f
+	 mov		%o0, %g1
+
 	cmp		%o0, %o1
-	bleu,pt		%xcc, memcpy
+	bleu,pt		%xcc, 2f
 	 add		%o1, %o2, %g7
 	cmp		%g7, %o0
 	bleu,pt		%xcc, memcpy
@@ -24,7 +26,34 @@ ENTRY(memmove) /* o0=dst o1=src o2=len */
 	stb		%g7, [%o0]
 	bne,pt		%icc, 1b
 	 sub		%o0, 1, %o0
-
+99:
 	retl
 	 mov		%g1, %o0
+
+	/* We can't just call memcpy for these memmove cases.  On some
+	 * chips the memcpy uses cache initializing stores and when dst
+	 * and src are close enough, those can clobber the source data
+	 * before we've loaded it in.
+	 */
+2:	or		%o0, %o1, %g7
+	or		%o2, %g7, %g7
+	andcc		%g7, 0x7, %g0
+	bne,pn		%xcc, 4f
+	 nop
+
+3:	ldx		[%o1], %g7
+	add		%o1, 8, %o1
+	subcc		%o2, 8, %o2
+	add		%o0, 8, %o0
+	bne,pt		%icc, 3b
+	 stx		%g7, [%o0 - 0x8]
+	ba,a,pt		%xcc, 99b
+
+4:	ldub		[%o1], %g7
+	add		%o1, 1, %o1
+	subcc		%o2, 1, %o2
+	add		%o0, 1, %o0
+	bne,pt		%icc, 4b
+	 stb		%g7, [%o0 - 0x1]
+	ba,a,pt		%xcc, 99b
 ENDPROC(memmove)
Signature · 1 line
2.3.4
author
#19 lore raw

PATCH 19/155 HID: add ALWAYS_POLL quirk for a Logitech 0xc007

In reply to Jiri Slaby

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

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit a415457733b5fa40bc996bf1f4df471cd98d3608 upstream.

This device disconnects every 60s without X

---
 drivers/hid/hid-ids.h           | 1 +
 drivers/hid/usbhid/hid-quirks.c | 1 +
 2 files changed, 2 insertions(+)
drivers/hid/hid-ids.h +1 -0
index 946b8cbfaa9f..56a4ed6e679b 100644
@@ -555,6 +555,7 @@
 
 #define USB_VENDOR_ID_LOGITECH		0x046d
 #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e
+#define USB_DEVICE_ID_LOGITECH_C077	0xc007
 #define USB_DEVICE_ID_LOGITECH_RECEIVER	0xc101
 #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST  0xc110
 #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f
drivers/hid/usbhid/hid-quirks.c +1 -0
index 25484ee3c51e..89b7eb4f9d3a 100644
@@ -78,6 +78,7 @@ static const struct hid_blacklist {
 	{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, HID_QUIRK_ALWAYS_POLL },
 	{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP, HID_QUIRK_NO_INIT_REPORTS },
Signature · 1 line
2.3.4
author
#20 lore raw

PATCH 20/155 powerpc/mpc85xx: Add ranges to etsec2 nodes

In reply to Jiri Slaby

From: Scott Wood <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit bb344ca5b90df62b1a3b7a35c6a9d00b306a170d upstream.

Commit 746c9e9f92dd "of/base: Fix PowerPC address parsing hack" limited the applicability of the workaround whereby a missing ranges is treated as an empty ranges. This workaround was hiding a bug in the etsec2 device tree nodes, which have children with reg, but did not have ranges.

---
 arch/powerpc/boot/dts/fsl/pq3-etsec2-0.dtsi | 1 +
 arch/powerpc/boot/dts/fsl/pq3-etsec2-1.dtsi | 1 +
 arch/powerpc/boot/dts/fsl/pq3-etsec2-2.dtsi | 1 +
 3 files changed, 3 insertions(+)
arch/powerpc/boot/dts/fsl/pq3-etsec2-0.dtsi +1 -0
index 1382fec9e8c5..7fcb1ac0f232 100644
@@ -50,6 +50,7 @@ ethernet@b0000 {
 	fsl,num_tx_queues = <0x8>;
 	fsl,magic-packet;
 	local-mac-address = [ 00 00 00 00 00 00 ];
+	ranges;
 
 	queue-group@b0000 {
 		#address-cells = <1>;
arch/powerpc/boot/dts/fsl/pq3-etsec2-1.dtsi +1 -0
index 221cd2ea5b31..9f25427c1527 100644
@@ -50,6 +50,7 @@ ethernet@b1000 {
 	fsl,num_tx_queues = <0x8>;
 	fsl,magic-packet;
 	local-mac-address = [ 00 00 00 00 00 00 ];
+	ranges;
 
 	queue-group@b1000 {
 		#address-cells = <1>;
arch/powerpc/boot/dts/fsl/pq3-etsec2-2.dtsi +1 -0
index 61456c317609..cd7c318ab131 100644
@@ -49,6 +49,7 @@ ethernet@b2000 {
 	fsl,num_tx_queues = <0x8>;
 	fsl,magic-packet;
 	local-mac-address = [ 00 00 00 00 00 00 ];
+	ranges;
 
 	queue-group@b2000 {
 		#address-cells = <1>;
Signature · 1 line
2.3.4
author
#21 lore raw

PATCH 21/155 include/linux/hugetlb.h: make isolate_huge_page() an inline

In reply to Jiri Slaby

From: Naoya Horiguchi <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit f40386a4e976acb2bd3e0f9ead11e8e769acbe98 upstream.

With CONFIG_HUGETLBFS=n:

mm/migrate.c: In function `do_move_page_to_node_array':
include/linux/hugetlb.h:140:33: warning: statement with no effect [-Wunused-value]

   #define isolate_huge_page(p, l) false
                                   ^
  mm/migrate.c:1170:4: note: in expansion of macro `isolate_huge_page'
      isolate_huge_page(page, &pagelist);
---
 include/linux/hugetlb.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
include/linux/hugetlb.h +4 -1
index e492c34439c3..7e8e0001f241 100644
@@ -143,7 +143,10 @@ static inline int dequeue_hwpoisoned_huge_page(struct page *page)
 	return 0;
 }
 
-#define isolate_huge_page(p, l) false
+static inline bool isolate_huge_page(struct page *page, struct list_head *list)
+{
+	return false;
+}
 #define putback_active_hugepage(p)	do {} while (0)
 #define is_hugepage_active(x)	false
 static inline void copy_huge_page(struct page *dst, struct page *src)
Signature · 1 line
2.3.4
author
#22 lore raw

PATCH 22/155 mm, hugetlb: define page_hstate for !HUGETLB_PAGE

In reply to Jiri Slaby

3.12-stable review patch. If anyone has any objections, please let me know.

===============

This is a single hunk introduced later in the upstream commit cb900f41215447433cbc456d1c4294e858a84d7c (mm, hugetlb: convert hugetlbfs to use split pmd lock). We need page_hstate even for !HUGETLB_PAGE case for the next patch (mm: thp: give transparent hugepage code a separate copy_page).

---
 include/linux/hugetlb.h | 1 +
 1 file changed, 1 insertion(+)
include/linux/hugetlb.h +1 -0
index 7e8e0001f241..2a943a396d20 100644
@@ -418,6 +418,7 @@ struct hstate {};
 #define hstate_sizelog(s) NULL
 #define hstate_vma(v) NULL
 #define hstate_inode(i) NULL
+#define page_hstate(page) NULL
 #define huge_page_size(h) PAGE_SIZE
 #define huge_page_mask(h) PAGE_MASK
 #define vma_kernel_pagesize(v) PAGE_SIZE
Signature · 1 line
2.3.4
author
#23 lore raw

PATCH 23/155 mm: thp: give transparent hugepage code a separate copy_page

In reply to Jiri Slaby

From: Dave Hansen <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 30b0a105d9f7141e4cbf72ae5511832457d89788 upstream.

Right now, the migration code in migrate_page_copy() uses copy_huge_page() for hugetlbfs and thp pages:

       if (PageHuge(page) || PageTransHuge(page))
                copy_huge_page(newpage, page);

So, yay for code reuse. But:

  void copy_huge_page(struct page *dst, struct page *src)
  {
        struct hstate *h = page_hstate(src);

and a non-hugetlbfs page has no page_hstate(). This works 99% of the time because page_hstate() determines the hstate from the page order alone. Since the page order of a THP page matches the default hugetlbfs page order, it works.

But, if you change the default huge page size on the boot command-line (say default_hugepagesz=1G), then we might not even *have* a 2MB hstate so page_hstate() returns null and copy_huge_page() oopses pretty fast since copy_huge_page() dereferences the hstate:

  void copy_huge_page(struct page *dst, struct page *src)
  {
        struct hstate *h = page_hstate(src);
        if (unlikely(pages_per_huge_page(h) > MAX_ORDER_NR_PAGES)) {
  ...

Mel noticed that the migration code is really the only user of these functions. This moves all the copy code over to migrate.c and makes copy_huge_page() work for THP by checking for it explicitly.

I believe the bug was introduced in commit b32967ff101a ("mm: numa: Add THP migration for the NUMA working set scanning fault case")

[[email protected]: fix coding-style and comment text, per Naoya Horiguchi]
Cc Hillf Danton <[email protected]>
Cc Andrea Arcangeli <[email protected]>
---
 include/linux/hugetlb.h |  4 ----
 mm/hugetlb.c            | 34 ----------------------------------
 mm/migrate.c            | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 48 insertions(+), 38 deletions(-)
include/linux/hugetlb.h +0 -4
index 2a943a396d20..1eaf61dde2c3 100644
@@ -70,7 +70,6 @@ int dequeue_hwpoisoned_huge_page(struct page *page);
 bool isolate_huge_page(struct page *page, struct list_head *list);
 void putback_active_hugepage(struct page *page);
 bool is_hugepage_active(struct page *page);
-void copy_huge_page(struct page *dst, struct page *src);
 
 #ifdef CONFIG_ARCH_WANT_HUGE_PMD_SHARE
 pte_t *huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud);
@@ -149,9 +148,6 @@ static inline bool isolate_huge_page(struct page *page, struct list_head *list)
 }
 #define putback_active_hugepage(p)	do {} while (0)
 #define is_hugepage_active(x)	false
-static inline void copy_huge_page(struct page *dst, struct page *src)
-{
-}
 
 static inline unsigned long hugetlb_change_protection(struct vm_area_struct *vma,
 		unsigned long address, unsigned long end, pgprot_t newprot)
mm/hugetlb.c +0 -34
index 1b040cb0ac5b..b43467a88243 100644
@@ -476,40 +476,6 @@ static int vma_has_reserves(struct vm_area_struct *vma, long chg)
 	return 0;
 }
 
-static void copy_gigantic_page(struct page *dst, struct page *src)
-{
-	int i;
-	struct hstate *h = page_hstate(src);
-	struct page *dst_base = dst;
-	struct page *src_base = src;
-
-	for (i = 0; i < pages_per_huge_page(h); ) {
-		cond_resched();
-		copy_highpage(dst, src);
-
-		i++;
-		dst = mem_map_next(dst, dst_base, i);
-		src = mem_map_next(src, src_base, i);
-	}
-}
-
-void copy_huge_page(struct page *dst, struct page *src)
-{
-	int i;
-	struct hstate *h = page_hstate(src);
-
-	if (unlikely(pages_per_huge_page(h) > MAX_ORDER_NR_PAGES)) {
-		copy_gigantic_page(dst, src);
-		return;
-	}
-
-	might_sleep();
-	for (i = 0; i < pages_per_huge_page(h); i++) {
-		cond_resched();
-		copy_highpage(dst + i, src + i);
-	}
-}
-
 static void enqueue_huge_page(struct hstate *h, struct page *page)
 {
 	int nid = page_to_nid(page);
mm/migrate.c +48 -0

54 lines not on this page · raw message

Signature · 1 line
2.3.4
author
#24 lore raw

PATCH 24/155 IB/core: Avoid leakage from kernel to user space

In reply to Jiri Slaby

From: Eli Cohen <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 377b513485fd885dea1083a9a5430df65b35e048 upstream.

Clear the reserved field of struct ib_uverbs_async_event_desc which is copied to user space.

---
 drivers/infiniband/core/uverbs_main.c | 1 +
 1 file changed, 1 insertion(+)
drivers/infiniband/core/uverbs_main.c +1 -0
index 2df31f68ea09..849c9dc7d1f6 100644
@@ -473,6 +473,7 @@ static void ib_uverbs_async_handler(struct ib_uverbs_file *file,
 
 	entry->desc.async.element    = element;
 	entry->desc.async.event_type = event;
+	entry->desc.async.reserved   = 0;
 	entry->counter               = counter;
 
 	list_add_tail(&entry->list, &file->async_file->event_list);
Signature · 1 line
2.3.4
author
#25 lore raw

PATCH 25/155 drm/radeon: fix DRM_IOCTL_RADEON_CS oops

In reply to Jiri Slaby

From: Tommi Rantala <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit a28b2a47edcd0cb7c051b445f71a426000394606 upstream.

Passing zeroed drm_radeon_cs struct to DRM_IOCTL_RADEON_CS produces the following oops.

Fix by always calling INIT_LIST_HEAD() to avoid the crash in list_sort().

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

#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <drm/radeon_drm.h>

static const struct drm_radeon_cs cs;

int main(int argc, char **argv)

 {
         return ioctl(open(argv[1], O_RDWR), DRM_IOCTL_RADEON_CS, &cs);

}

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

[ttrantal@test2 ~]$ ./main /dev/dri/card0

[   46.904650] BUG: unable to handle kernel NULL pointer dereference at           (null)
[   46.905022] IP: [<ffffffff814d6df2>] list_sort+0x42/0x240
[   46.905022] PGD 68f29067 PUD 688b5067 PMD 0
[   46.905022] Oops: 0002 [#1] SMP
[   46.905022] CPU: 0 PID: 2413 Comm: main Not tainted 4.0.0-rc1+ #58
[   46.905022] Hardware name: Hewlett-Packard HP Compaq dc5750 Small Form Factor/0A64h, BIOS 786E3 v02.10 01/25/2007
[   46.905022] task: ffff880058e2bcc0 ti: ffff880058e64000 task.ti: ffff880058e64000
[   46.905022] RIP: 0010:[<ffffffff814d6df2>]  [<ffffffff814d6df2>] list_sort+0x42/0x240
[   46.905022] RSP: 0018:ffff880058e67998  EFLAGS: 00010246
[   46.905022] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
[   46.905022] RDX: ffffffff81644410 RSI: ffff880058e67b40 RDI: ffff880058e67a58
[   46.905022] RBP: ffff880058e67a88 R08: 0000000000000000 R09: 0000000000000000
[   46.905022] R10: ffff880058e2bcc0 R11: ffffffff828e6ca0 R12: ffffffff81644410
[   46.905022] R13: ffff8800694b8018 R14: 0000000000000000 R15: ffff880058e679b0
[   46.905022] FS:  00007fdc65a65700(0000) GS:ffff88006d600000(0000) knlGS:0000000000000000
[   46.905022] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   46.905022] CR2: 0000000000000000 CR3: 0000000058dd9000 CR4: 00000000000006f0
[   46.905022] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   46.905022] DR3: 0000000000000000 DR6: 00000000ffff4ff0 DR7: 0000000000000400
[   46.905022] Stack:
[   46.905022]  ffff880058e67b40 ffff880058e2bcc0 ffff880058e67a78 0000000000000000
[   46.905022]  0000000000000000 0000000000000000 0000000000000000 0000000000000000
[   46.905022]  0000000000000000 0000000000000000 0000000000000000 0000000000000000
[   46.905022] Call Trace:
[   46.905022]  [<ffffffff81644a65>] radeon_cs_parser_fini+0x195/0x220
[   46.905022]  [<ffffffff81645069>] radeon_cs_ioctl+0xa9/0x960
[   46.905022]  [<ffffffff815e1f7c>] drm_ioctl+0x19c/0x640
[   46.905022]  [<ffffffff810f8fdd>] ? trace_hardirqs_on_caller+0xfd/0x1c0
[   46.905022]  [<ffffffff810f90ad>] ? trace_hardirqs_on+0xd/0x10
[   46.905022]  [<ffffffff8160c066>] radeon_drm_ioctl+0x46/0x80
[   46.905022]  [<ffffffff81211868>] do_vfs_ioctl+0x318/0x570
[   46.905022]  [<ffffffff81462ef6>] ? selinux_file_ioctl+0x56/0x110
[   46.905022]  [<ffffffff81211b41>] SyS_ioctl+0x81/0xa0
[   46.905022]  [<ffffffff81dc6312>] system_call_fastpath+0x12/0x17
[   46.905022] Code: 48 89 b5 10 ff ff ff 0f 84 03 01 00 00 4c 8d bd 28 ff ff
ff 31 c0 48 89 fb b9 15 00 00 00 49 89 d4 4c 89 ff f3 48 ab 48 8b 46 08 <48> c7
00 00 00 00 00 48 8b 0e 48 85 c9 0f 84 7d 00 00 00 c7 85
[   46.905022] RIP  [<ffffffff814d6df2>] list_sort+0x42/0x240
[   46.905022]  RSP <ffff880058e67998>
[   46.905022] CR2: 0000000000000000
[   47.149253] ---[ end trace 09576b4e8b2c20b8 ]---
---
 drivers/gpu/drm/radeon/radeon_cs.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/radeon/radeon_cs.c +3 -1
index ed9a997c99a3..f4af10089409 100644
@@ -178,11 +178,13 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
 	u32 ring = RADEON_CS_RING_GFX;
 	s32 priority = 0;
 
+	INIT_LIST_HEAD(&p->validated);
+
 	if (!cs->num_chunks) {
 		return 0;
 	}
+
 	/* get chunks */
-	INIT_LIST_HEAD(&p->validated);
 	p->idx = 0;
 	p->ib.sa_bo = NULL;
 	p->ib.semaphore = NULL;
Signature · 1 line
2.3.4
author
#26 lore raw

PATCH 26/155 drm/radeon: do a posting read in evergreen_set_irq

In reply to Jiri Slaby

From: Alex Deucher <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit c320bb5f6dc0cb88a811cbaf839303e0a3916a92 upstream.

To make sure the writes go through the pci bridge.

bug:
https://bugzilla.kernel.org/show_bug.cgi?id=90741

---
 drivers/gpu/drm/radeon/evergreen.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/gpu/drm/radeon/evergreen.c +3 -0
index 20b00a0f42b4..063b72fbfe1e 100644
@@ -4497,6 +4497,9 @@ int evergreen_irq_set(struct radeon_device *rdev)
 	WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, afmt5);
 	WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, afmt6);
 
+	/* posting read */
+	RREG32(SRBM_STATUS);
+
 	return 0;
 }
 
Signature · 1 line
2.3.4
author
#27 lore raw

PATCH 27/155 drm/radeon: do a posting read in r100_set_irq

In reply to Jiri Slaby

From: Alex Deucher <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit f957063fee6392bb9365370db6db74dc0b2dce0a upstream.

To make sure the writes go through the pci bridge.

bug:
https://bugzilla.kernel.org/show_bug.cgi?id=90741

---
 drivers/gpu/drm/radeon/r100.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/gpu/drm/radeon/r100.c +4 -0
index f98dcbeb9a72..91bcb794d59e 100644
@@ -742,6 +742,10 @@ int r100_irq_set(struct radeon_device *rdev)
 		tmp |= RADEON_FP2_DETECT_MASK;
 	}
 	WREG32(RADEON_GEN_INT_CNTL, tmp);
+
+	/* read back to post the write */
+	RREG32(RADEON_GEN_INT_CNTL);
+
 	return 0;
 }
 
Signature · 1 line
2.3.4
author
#28 lore raw

PATCH 28/155 drm/radeon: do a posting read in r600_set_irq

In reply to Jiri Slaby

From: Alex Deucher <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 9d1393f23d5656cdd5f368efd60694d4aeed81d3 upstream.

To make sure the writes go through the pci bridge.

bug:
https://bugzilla.kernel.org/show_bug.cgi?id=90741

---
 drivers/gpu/drm/radeon/r600.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/gpu/drm/radeon/r600.c +3 -0
index 88eb936fbc2f..2c0a0d7c2492 100644
@@ -3509,6 +3509,9 @@ int r600_irq_set(struct radeon_device *rdev)
 		WREG32(RV770_CG_THERMAL_INT, thermal_int);
 	}
 
+	/* posting read */
+	RREG32(R_000E50_SRBM_STATUS);
+
 	return 0;
 }
 
Signature · 1 line
2.3.4
author
#29 lore raw

PATCH 29/155 drm/radeon: do a posting read in cik_set_irq

In reply to Jiri Slaby

From: Alex Deucher <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit cffefd9bb31cd35ab745d3b49005d10616d25bdc upstream.

To make sure the writes go through the pci bridge.

bug:
https://bugzilla.kernel.org/show_bug.cgi?id=90741

---
 drivers/gpu/drm/radeon/cik.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/gpu/drm/radeon/cik.c +3 -0
index 6e2e4a859047..bb4c6573a525 100644
@@ -6352,6 +6352,9 @@ int cik_irq_set(struct radeon_device *rdev)
 	WREG32(DC_HPD5_INT_CONTROL, hpd5);
 	WREG32(DC_HPD6_INT_CONTROL, hpd6);
 
+	/* posting read */
+	RREG32(SRBM_STATUS);
+
 	return 0;
 }
 
Signature · 1 line
2.3.4
author
#30 lore raw

PATCH 30/155 drm/radeon: do a posting read in si_set_irq

In reply to Jiri Slaby

From: Alex Deucher <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 0586915ec10d0ae60de5cd3381ad25a704760402 upstream.

To make sure the writes go through the pci bridge.

bug:
https://bugzilla.kernel.org/show_bug.cgi?id=90741

---
 drivers/gpu/drm/radeon/si.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/gpu/drm/radeon/si.c +3 -0
index 50482e763d80..6301b3638bb4 100644
@@ -5901,6 +5901,9 @@ int si_irq_set(struct radeon_device *rdev)
 
 	WREG32(CG_THERMAL_INT, thermal_int);
 
+	/* posting read */
+	RREG32(SRBM_STATUS);
+
 	return 0;
 }
 
Signature · 1 line
2.3.4
author
#31 lore raw

PATCH 31/155 drm/radeon: do a posting read in rs600_set_irq

In reply to Jiri Slaby

From: Alex Deucher <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 54acf107e4e66d1f4a697e08a7f60dba9fcf07c3 upstream.

To make sure the writes go through the pci bridge.

bug:
https://bugzilla.kernel.org/show_bug.cgi?id=90741

---
 drivers/gpu/drm/radeon/rs600.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/gpu/drm/radeon/rs600.c +4 -0
index bbe84591f159..dcb119571f11 100644
@@ -636,6 +636,10 @@ int rs600_irq_set(struct radeon_device *rdev)
 	WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2);
 	if (ASIC_IS_DCE2(rdev))
 		WREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL, hdmi0);
+
+	/* posting read */
+	RREG32(R_000040_GEN_INT_CNTL);
+
 	return 0;
 }
 
Signature · 1 line
2.3.4
author
#32 lore raw

PATCH 32/155 drm/radeon: fix interlaced modes on DCE8

In reply to Jiri Slaby

From: Alex Deucher <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 77ae5f4b48a0445426c9c1ef7c0f28b717e35d55 upstream.

Need to double the viewport height.

---
 drivers/gpu/drm/radeon/atombios_crtc.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/gpu/drm/radeon/atombios_crtc.c +3 -0
index ba8742ab85ee..65344d65ff91 100644
@@ -1278,6 +1278,9 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
 	       (x << 16) | y);
 	viewport_w = crtc->mode.hdisplay;
 	viewport_h = (crtc->mode.vdisplay + 1) & ~1;
+	if ((rdev->family >= CHIP_BONAIRE) &&
+	    (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE))
+		viewport_h *= 2;
 	WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
 	       (viewport_w << 16) | viewport_h);
 
Signature · 1 line
2.3.4
author
#33 lore raw

PATCH 33/155 drm/radeon: drop setting UPLL to sleep mode

In reply to Jiri Slaby

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

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit a17d4996e051e78d164989b894608cf37cd5110b upstream.

Just keep it working, seems to fix some PLL problems.

---
 drivers/gpu/drm/radeon/si.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/gpu/drm/radeon/si.c +2 -4
index 6301b3638bb4..c9f229f2048a 100644
@@ -6819,8 +6819,7 @@ int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
 	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK);
 
 	if (!vclk || !dclk) {
-		/* keep the Bypass mode, put PLL to sleep */
-		WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK);
+		/* keep the Bypass mode */
 		return 0;
 	}
 
@@ -6836,8 +6835,7 @@ int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
 	/* set VCO_MODE to 1 */
 	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_VCO_MODE_MASK, ~UPLL_VCO_MODE_MASK);
 
-	/* toggle UPLL_SLEEP to 1 then back to 0 */
-	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK);
+	/* disable sleep mode */
 	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_SLEEP_MASK);
 
 	/* deassert UPLL_RESET */
Signature · 1 line
2.3.4
author
#34 lore raw

PATCH 34/155 LZ4 : fix the data abort issue

In reply to Jiri Slaby

From: JeHyeon Yeon <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit d5e7cafd69da24e6d6cc988fab6ea313a2577efc upstream.

If the part of the compression data are corrupted, or the compression data is totally fake, the memory access over the limit is possible.

This is the log from my system usning lz4 decompression.
[6502]data abort, halting

   [6503]r0  0x00000000 r1  0x00000000 r2  0xdcea0ffc r3  0xdcea0ffc
   [6509]r4  0xb9ab0bfd r5  0xdcea0ffc r6  0xdcea0ff8 r7  0xdce80000
   [6515]r8  0x00000000 r9  0x00000000 r10 0x00000000 r11 0xb9a98000
   [6522]r12 0xdcea1000 usp 0x00000000 ulr 0x00000000 pc  0x820149bc
   [6528]spsr 0x400001f3
and the memory addresses of some variables at the moment are
    ref:0xdcea0ffc, op:0xdcea0ffc, oend:0xdcea1000

As you can see, COPYLENGH is 8bytes, so @ref and @op can access the momory over @oend.

---
 lib/lz4/lz4_decompress.c | 3 +++
 1 file changed, 3 insertions(+)
lib/lz4/lz4_decompress.c +3 -0
index 7a85967060a5..f0f5c5c3de12 100644
@@ -139,6 +139,9 @@ static int lz4_uncompress(const char *source, char *dest, int osize)
 			/* Error: request to write beyond destination buffer */
 			if (cpy > oend)
 				goto _output_error;
+			if ((ref + COPYLENGTH) > oend ||
+					(op + COPYLENGTH) > oend)
+				goto _output_error;
 			LZ4_SECURECOPY(ref, op, (oend - COPYLENGTH));
 			while (op < cpy)
 				*op++ = *ref++;
Signature · 1 line
2.3.4
author
#35 lore raw

PATCH 35/155 fuse: set stolen page uptodate

In reply to Jiri Slaby

From: Miklos Szeredi <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit aa991b3b267e24f578bac7b09cc57579b660304b upstream.

Regular pipe buffers' ->steal method (generic_pipe_buf_steal()) doesn't set PG_uptodate.

Don't warn on this condition, just set the uptodate flag.

---
 fs/fuse/dev.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
fs/fuse/dev.c +2 -2
index fc8e4991736a..706e587cbd34 100644
@@ -819,8 +819,8 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
 
 	newpage = buf->page;
 
-	if (WARN_ON(!PageUptodate(newpage)))
-		return -EIO;
+	if (!PageUptodate(newpage))
+		SetPageUptodate(newpage);
 
 	ClearPageMappedToDisk(newpage);
 
Signature · 1 line
2.3.4
author
#36 lore raw

PATCH 36/155 fuse: notify: don't move pages

In reply to Jiri Slaby

From: Miklos Szeredi <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 0d2783626a53d4c922f82d51fa675cb5d13f0d36 upstream.

fuse_try_move_page() is not prepared for replacing pages that have already been read.

---
 fs/fuse/dev.c | 3 +++
 1 file changed, 3 insertions(+)
fs/fuse/dev.c +3 -0
index 706e587cbd34..be1f2813c4f0 100644
@@ -1725,6 +1725,9 @@ copy_finish:
 static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code,
 		       unsigned int size, struct fuse_copy_state *cs)
 {
+	/* Don't try to move pages (yet) */
+	cs->move_pages = 0;
+
 	switch (code) {
 	case FUSE_NOTIFY_POLL:
 		return fuse_notify_poll(fc, size, cs);
Signature · 1 line
2.3.4
author
#37 lore raw

PATCH 37/155 console: Fix console name size mismatch

In reply to Jiri Slaby

From: Peter Hurley <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 30a22c215a0007603ffc08021f2e8b64018517dd upstream.

commit 6ae9200f2cab7 ("enlarge console.name") increased the storage for the console name to 16 bytes, but not the corresponding struct console_cmdline::name storage. Console names longer than 8 bytes cause read beyond end-of-string and failure to match console; I'm not sure if there are other unexpected consequences.

---
 kernel/printk/console_cmdline.h | 2 +-
 kernel/printk/printk.c          | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)
kernel/printk/console_cmdline.h +1 -1
index cbd69d842341..2ca4a8b5fe57 100644
@@ -3,7 +3,7 @@
 
 struct console_cmdline
 {
-	char	name[8];			/* Name of the driver	    */
+	char	name[16];			/* Name of the driver	    */
 	int	index;				/* Minor dev. to use	    */
 	char	*options;			/* Options for the driver   */
 #ifdef CONFIG_A11Y_BRAILLE_CONSOLE
kernel/printk/printk.c +1 -0
index 0f9149036885..fbafa885eee1 100644
@@ -2281,6 +2281,7 @@ void register_console(struct console *newcon)
 	for (i = 0, c = console_cmdline;
 	     i < MAX_CMDLINECONSOLES && c->name[0];
 	     i++, c++) {
+		BUILD_BUG_ON(sizeof(c->name) != sizeof(newcon->name));
 		if (strcmp(c->name, newcon->name) != 0)
 			continue;
 		if (newcon->index >= 0 &&
Signature · 1 line
2.3.4
author
#38 lore raw

PATCH 38/155 virtio_console: init work unconditionally

In reply to Jiri Slaby

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

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 4f6e24ed9de8634d6471ef86b382cba6d4e57ca8 upstream.

when multiport is off, we don't initialize config work, but we then cancel uninitialized control_work on freeze.

---
 drivers/char/virtio_console.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/char/virtio_console.c +2 -1
index b79cf3e1b793..4d5fcc2d6c9c 100644
@@ -2030,12 +2030,13 @@ static int virtcons_probe(struct virtio_device *vdev)
 	spin_lock_init(&portdev->ports_lock);
 	INIT_LIST_HEAD(&portdev->ports);
 
+	INIT_WORK(&portdev->control_work, &control_work_handler);
+
 	if (multiport) {
 		unsigned int nr_added_bufs;
 
 		spin_lock_init(&portdev->c_ivq_lock);
 		spin_lock_init(&portdev->c_ovq_lock);
-		INIT_WORK(&portdev->control_work, &control_work_handler);
 
 		nr_added_bufs = fill_queue(portdev->c_ivq,
 					   &portdev->c_ivq_lock);
Signature · 1 line
2.3.4
author
#39 lore raw

PATCH 39/155 virtio_console: avoid config access from irq

In reply to Jiri Slaby

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

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit eeb8a7e8bb123e84daeef84f5a2eab99ad2839a2 upstream.

when multiport is off, virtio console invokes config access from irq context, config access is blocking on s390.
Fix this up by scheduling work from config irq - similar to what we do for multiport configs.

---
 drivers/char/virtio_console.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
drivers/char/virtio_console.c +16 -0
index 4d5fcc2d6c9c..f6b96ba57b32 100644
@@ -142,6 +142,7 @@ struct ports_device {
 	 * notification
 	 */
 	struct work_struct control_work;
+	struct work_struct config_work;
 
 	struct list_head ports;
 
@@ -1833,10 +1834,21 @@ static void config_intr(struct virtio_device *vdev)
 
 	portdev = vdev->priv;
 
+	if (!use_multiport(portdev))
+		schedule_work(&portdev->config_work);
+}
+
+static void config_work_handler(struct work_struct *work)
+{
+	struct ports_device *portdev;
+
+	portdev = container_of(work, struct ports_device, control_work);
 	if (!use_multiport(portdev)) {
+		struct virtio_device *vdev;
 		struct port *port;
 		u16 rows, cols;
 
+		vdev = portdev->vdev;
 		vdev->config->get(vdev,
 				  offsetof(struct virtio_console_config, cols),
 				  &cols, sizeof(u16));
@@ -2030,6 +2042,7 @@ static int virtcons_probe(struct virtio_device *vdev)
 	spin_lock_init(&portdev->ports_lock);
 	INIT_LIST_HEAD(&portdev->ports);
 
+	INIT_WORK(&portdev->config_work, &config_work_handler);
 	INIT_WORK(&portdev->control_work, &control_work_handler);
 
 	if (multiport) {
@@ -2104,6 +2117,8 @@ static void virtcons_remove(struct virtio_device *vdev)
 	/* Finish up work that's lined up */
 	if (use_multiport(portdev))
 		cancel_work_sync(&portdev->control_work);
+	else
+		cancel_work_sync(&portdev->config_work);
 
 	list_for_each_entry_safe(port, port2, &portdev->ports, list)
 		unplug_port(port);
@@ -2155,6 +2170,7 @@ static int virtcons_freeze(struct virtio_device *vdev)
 
 	virtqueue_disable_cb(portdev->c_ivq);
 	cancel_work_sync(&portdev->control_work);
+	cancel_work_sync(&portdev->config_work);
 	/*
 	 * Once more: if control_work_handler() was running, it would
 	 * enable the cb as the last step.
Signature · 1 line
2.3.4
author
#40 lore raw

PATCH 40/155 Change email address for 8250_pci

In reply to Jiri Slaby

From: Russell King <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit f2e0ea861117bda073d1d7ffbd3120c07c0d5d34 upstream.

I'm still receiving reports to my email address, so let's point this at the linux-serial mailing list instead.

---
 drivers/tty/serial/8250/8250_pci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/8250/8250_pci.c +1 -1
index ee1f7c52bd52..eac50ec4c70d 100644
@@ -68,7 +68,7 @@ static void moan_device(const char *str, struct pci_dev *dev)
 	       "Please send the output of lspci -vv, this\n"
 	       "message (0x%04x,0x%04x,0x%04x,0x%04x), the\n"
 	       "manufacturer and name of serial board or\n"
-	       "modem board to [email protected].\n",
+	       "modem board to <[email protected]>.\n",
 	       pci_name(dev), str, dev->vendor, dev->device,
 	       dev->subsystem_vendor, dev->subsystem_device);
 }
Signature · 1 line
2.3.4
author
#41 lore raw

PATCH 41/155 can: add missing initialisations in CAN related skbuffs

In reply to Jiri Slaby

From: Oliver Hartkopp <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 969439016d2cf61fef53a973d7e6d2061c3793b1 upstream.

When accessing CAN network interfaces with AF_PACKET sockets e.g. by dhclient this can lead to a skb_under_panic due to missing skb initialisations.

Add the missing initialisations at the CAN skbuff creation times on driver level (rx path) and in the network layer (tx path).

---
 drivers/net/can/dev.c | 8 ++++++++
 net/can/af_can.c      | 3 +++
 2 files changed, 11 insertions(+)
drivers/net/can/dev.c +8 -0
index a4694aa20a3e..f66aeb79abdf 100644
@@ -503,6 +503,14 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
 	skb->pkt_type = PACKET_BROADCAST;
 	skb->ip_summed = CHECKSUM_UNNECESSARY;
 
+	skb_reset_mac_header(skb);
+	skb_reset_network_header(skb);
+	skb_reset_transport_header(skb);
+
+	skb_reset_mac_header(skb);
+	skb_reset_network_header(skb);
+	skb_reset_transport_header(skb);
+
 	can_skb_reserve(skb);
 	can_skb_prv(skb)->ifindex = dev->ifindex;
 
net/can/af_can.c +3 -0
index ae3f07eb6cd7..5a668268f7ff 100644
@@ -262,6 +262,9 @@ int can_send(struct sk_buff *skb, int loop)
 		goto inval_skb;
 	}
 
+	skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+	skb_reset_mac_header(skb);
 	skb_reset_network_header(skb);
 	skb_reset_transport_header(skb);
 
Signature · 1 line
2.3.4
author
#42 lore raw

PATCH 42/155 workqueue: fix hang involving racing cancel[_delayed]_work_sync()'s for PREEMPT_NONE

In reply to Jiri Slaby

From: Tejun Heo <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 8603e1b30027f943cc9c1eef2b291d42c3347af1 upstream.

cancel[_delayed]_work_sync() are implemented using __cancel_work_timer() which grabs the PENDING bit using try_to_grab_pending() and then flushes the work item with PENDING set to prevent the on-going execution of the work item from requeueing itself.

try_to_grab_pending() can always grab PENDING bit without blocking except when someone else is doing the above flushing during cancelation. In that case, try_to_grab_pending() returns -ENOENT. In this case, __cancel_work_timer() currently invokes flush_work(). The assumption is that the completion of the work item is what the other canceling task would be waiting for too and thus waiting for the same condition and retrying should allow forward progress without excessive busy looping

Unfortunately, this doesn't work if preemption is disabled or the latter task has real time priority. Let's say task A just got woken up from flush_work() by the completion of the target work item. If, before task A starts executing, task B gets scheduled and invokes __cancel_work_timer() on the same work item, its try_to_grab_pending() will return -ENOENT as the work item is still being canceled by task A and flush_work() will also immediately return false as the work item is no longer executing. This puts task B in a busy loop possibly preventing task A from executing and clearing the canceling state on the work item leading to a hang.

task A task B worker

executing work
__cancel_work_timer()
try_to_grab_pending()
set work CANCELING
flush_work()
block for work completion
completion, wakes up A
__cancel_work_timer()
while (forever) {
try_to_grab_pending()
-ENOENT as work is being canceled
flush_work()
false as work is no longer executing
}

This patch removes the possible hang by updating __cancel_work_timer() to explicitly wait for clearing of CANCELING rather than invoking flush_work() after try_to_grab_pending() fails with -ENOENT.

v3: bit_waitqueue() can't be used for work items defined in vmalloc
area. Switched to custom wake function which matches the target work item and exclusive wait and wakeup.

v2: v1 used wake_up() on bit_waitqueue() which leads to NULL deref if
the target bit waitqueue has wait_bit_queue's on it. Use DEFINE_WAIT_BIT() and __wake_up_bit() instead. Reported by Tomeu Vizoso.

---
 include/linux/workqueue.h |  3 ++-
 kernel/workqueue.c        | 56 +++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 54 insertions(+), 5 deletions(-)
include/linux/workqueue.h +2 -1
index eff358e6945d..0f67a9c82787 100644
@@ -71,7 +71,8 @@ enum {
 	/* data contains off-queue information when !WORK_STRUCT_PWQ */
 	WORK_OFFQ_FLAG_BASE	= WORK_STRUCT_COLOR_SHIFT,
 
-	WORK_OFFQ_CANCELING	= (1 << WORK_OFFQ_FLAG_BASE),
+	__WORK_OFFQ_CANCELING	= WORK_OFFQ_FLAG_BASE,
+	WORK_OFFQ_CANCELING	= (1 << __WORK_OFFQ_CANCELING),
 
 	/*
 	 * When a work item is off queue, its high bits point to the last
kernel/workqueue.c +52 -4

77 lines not on this page · raw message

Signature · 1 line
2.3.4
author
#43 lore raw

PATCH 43/155 cpuset: Fix cpuset sched_relax_domain_level

In reply to Jiri Slaby

From: Jason Low <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 283cb41f426b723a0255702b761b0fc5d1b53a81 upstream.

The cpuset.sched_relax_domain_level can control how far we do immediate load balancing on a system. However, it was found on recent kernels that echo'ing a value into cpuset.sched_relax_domain_level did not reduce any immediate load balancing.

The reason this occurred was because the update_domain_attr_tree() traversal did not update for the "top_cpuset". This resulted in nothing being changed when modifying the sched_relax_domain_level parameter.

This patch is able to address that problem by having update_domain_attr_tree() allow updates for the root in the cpuset traversal.

Fixes fc560a26acce ("cpuset: replace cpuset->stack_list with cpuset_for_each_descendant_pre()")
---
 kernel/cpuset.c | 3 ---
 1 file changed, 3 deletions(-)
kernel/cpuset.c +0 -3
index c8289138cad4..b5f0faa4bfbd 100644
@@ -503,9 +503,6 @@ static void update_domain_attr_tree(struct sched_domain_attr *dattr,
 
 	rcu_read_lock();
 	cpuset_for_each_descendant_pre(cp, pos_css, root_cs) {
-		if (cp == root_cs)
-			continue;
-
 		/* skip the whole subtree if @cp doesn't have any CPU */
 		if (cpumask_empty(cp->cpus_allowed)) {
 			pos_css = css_rightmost_descendant(pos_css);
Signature · 1 line
2.3.4
author
#44 lore raw

PATCH 44/155 tpm/ibmvtpm: Additional LE support for tpm_ibmvtpm_send

In reply to Jiri Slaby

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

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 62dfd912ab3b5405b6fe72d0135c37e9648071f1 upstream.

Problem: When IMA and VTPM are both enabled in kernel config, kernel hangs during bootup on LE OS.

Why?: IMA calls tpm_pcr_read() which results in tpm_ibmvtpm_send and tpm_ibmtpm_recv getting called. A trace showed that tpm_ibmtpm_recv was hanging.

Resolution: tpm_ibmtpm_recv was hanging because tpm_ibmvtpm_send was sending CRQ message that probably did not make much sense to phype because of Endianness. The fix below sends correctly converted CRQ for LE. This was not caught before because it seems IMA is not enabled by default in kernel config and IMA exercises this particular code path in vtpm.

Tested with IMA and VTPM enabled in kernel config and VTPM enabled on both a BE OS and a LE OS ppc64 lpar. This exercised CRQ and TPM command code paths in vtpm.
Patch is against Peter's tpmdd tree on github which included Vicky's previous vtpm le patches.

---
 drivers/char/tpm/tpm_ibmvtpm.c | 10 +++++-----
 drivers/char/tpm/tpm_ibmvtpm.h |  6 +++---
 2 files changed, 8 insertions(+), 8 deletions(-)
drivers/char/tpm/tpm_ibmvtpm.c +5 -5
index 538856f3e68a..09df26f9621d 100644
@@ -124,7 +124,7 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
 {
 	struct ibmvtpm_dev *ibmvtpm;
 	struct ibmvtpm_crq crq;
-	u64 *word = (u64 *) &crq;
+	__be64 *word = (__be64 *)&crq;
 	int rc;
 
 	ibmvtpm = (struct ibmvtpm_dev *)TPM_VPRIV(chip);
@@ -145,11 +145,11 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
 	memcpy((void *)ibmvtpm->rtce_buf, (void *)buf, count);
 	crq.valid = (u8)IBMVTPM_VALID_CMD;
 	crq.msg = (u8)VTPM_TPM_COMMAND;
-	crq.len = (u16)count;
-	crq.data = ibmvtpm->rtce_dma_handle;
+	crq.len = cpu_to_be16(count);
+	crq.data = cpu_to_be32(ibmvtpm->rtce_dma_handle);
 
-	rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(word[0]),
-			      cpu_to_be64(word[1]));
+	rc = ibmvtpm_send_crq(ibmvtpm->vdev, be64_to_cpu(word[0]),
+			      be64_to_cpu(word[1]));
 	if (rc != H_SUCCESS) {
 		dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc);
 		rc = 0;
drivers/char/tpm/tpm_ibmvtpm.h +3 -3
index bd82a791f995..b2c231b1beec 100644
@@ -22,9 +22,9 @@
 struct ibmvtpm_crq {
 	u8 valid;
 	u8 msg;
-	u16 len;
-	u32 data;
-	u64 reserved;
+	__be16 len;
+	__be32 data;
+	__be64 reserved;
 } __attribute__((packed, aligned(8)));
 
 struct ibmvtpm_crq_queue {
Signature · 1 line
2.3.4
author
#45 lore raw

PATCH 45/155 spi: pl022: Fix race in giveback() leading to driver lock-up

In reply to Jiri Slaby

From: Alexander Sverdlin <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit cd6fa8d2ca53cac3226fdcffcf763be390abae32 upstream.

Commit fd316941c ("spi/pl022: disable port when unused") introduced a race, which leads to possible driver lock up (easily reproducible on SMP).

The problem happens in giveback() function where the completion of the transfer is signalled to SPI subsystem and then the HW SPI controller is disabled. Another transfer might be setup in between, which brings driver in locked-up state.

Exact event sequence on SMP:

core0 core1

                                        => pump_transfers()
                                        /* message->state == STATE_DONE */
                                          => giveback()
                                            => spi_finalize_current_message()

=> pl022_unprepare_transfer_hardware()
=> pl022_transfer_one_message
=> flush()
=> do_interrupt_dma_transfer()

    => set_up_next_transfer()
    /* Enable SSP, turn on interrupts */
    writew((readw(SSP_CR1(pl022->virtbase)) |
           SSP_CR1_MASK_SSE), SSP_CR1(pl022->virtbase));

...

=> pl022_interrupt_handler()
=> readwriter()

                                        /* disable the SPI/SSP operation */
                                        => writew((readw(SSP_CR1(pl022->virtbase)) &
                                                  (~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase));

Lockup! SPI controller is disabled and the data will never be received. Whole SPI subsystem is waiting for transfer ACK and blocked.

So, only signal transfer completion after disabling the controller.

Fixes fd316941c (spi/pl022: disable port when unused)
---
 drivers/spi/spi-pl022.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/spi/spi-pl022.c +1 -1
index b1a9ba893fab..0bc4e4508e6f 100644
@@ -503,12 +503,12 @@ static void giveback(struct pl022 *pl022)
 	pl022->cur_msg = NULL;
 	pl022->cur_transfer = NULL;
 	pl022->cur_chip = NULL;
-	spi_finalize_current_message(pl022->master);
 
 	/* disable the SPI/SSP operation */
 	writew((readw(SSP_CR1(pl022->virtbase)) &
 		(~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase));
 
+	spi_finalize_current_message(pl022->master);
 }
 
 /**
Signature · 1 line
2.3.4
author
#46 lore raw

PATCH 46/155 ALSA: snd-usb: add quirks for Roland UA-22

In reply to Jiri Slaby

From: Daniel Mack <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit fcdcd1dec6d2c7b718385ec743ae5a9a233edad4 upstream.

The device complies to the UAC1 standard but hides that fact with proprietary descriptors. The autodetect quirk for Roland devices catches the audio interface but misses the MIDI part, so a specific quirk is needed.

---
 sound/usb/quirks-table.h | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
sound/usb/quirks-table.h +30 -0
index 83bddbdb90e9..5293b5ac8b9d 100644
@@ -1773,6 +1773,36 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 		}
 	}
 },
+{
+	USB_DEVICE(0x0582, 0x0159),
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+		/* .vendor_name = "Roland", */
+		/* .product_name = "UA-22", */
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = (const struct snd_usb_audio_quirk[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_AUDIO_STANDARD_INTERFACE
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_AUDIO_STANDARD_INTERFACE
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_MIDI_FIXED_ENDPOINT,
+				.data = & (const struct snd_usb_midi_endpoint_info) {
+					.out_cables = 0x0001,
+					.in_cables = 0x0001
+				}
+			},
+			{
+				.ifnum = -1
+			}
+		}
+	}
+},
 /* this catches most recent vendor-specific Roland devices */
 {
 	.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
Signature · 1 line
2.3.4
author
#47 lore raw

PATCH 47/155 ALSA: control: Add sanity checks for user ctl id name string

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit be3bb8236db2d0fcd705062ae2e2a9d75131222f upstream.

There was no check about the id string of user control elements, so we accepted even a control element with an empty string, which is obviously bogus. This patch adds more sanity checks of id strings.

---
 sound/core/control.c | 4 ++++
 1 file changed, 4 insertions(+)
sound/core/control.c +4 -0
index 98a29b26c5f4..f2082a35b890 100644
@@ -1168,6 +1168,10 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
 
 	if (info->count < 1)
 		return -EINVAL;
+	if (!*info->id.name)
+		return -EINVAL;
+	if (strnlen(info->id.name, sizeof(info->id.name)) >= sizeof(info->id.name))
+		return -EINVAL;
 	access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
 		(info->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
 				 SNDRV_CTL_ELEM_ACCESS_INACTIVE|
Signature · 1 line
2.3.4
author
#48 lore raw

PATCH 48/155 ALSA: hda - Fix built-in mic on Compaq Presario CQ60

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit ddb6ca75b5671b8fbf1909bc588c449ee74b34f9 upstream.

Compaq Presario CQ60 laptop with CX20561 gives a wrong pin for the built-in mic NID 0x17 instead of NID 0x1d, and it results in the non-working mic. This patch just remaps the pin correctly via fixup.

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

---
 sound/pci/hda/patch_conexant.c | 11 +++++++++++
 1 file changed, 11 insertions(+)
sound/pci/hda/patch_conexant.c +11 -0
index 131d7d459cb6..9baf0037866f 100644
@@ -3227,6 +3227,7 @@ enum {
 	CXT_PINCFG_LENOVO_TP410,
 	CXT_PINCFG_LEMOTE_A1004,
 	CXT_PINCFG_LEMOTE_A1205,
+	CXT_PINCFG_COMPAQ_CQ60,
 	CXT_FIXUP_STEREO_DMIC,
 	CXT_FIXUP_INC_MIC_BOOST,
 	CXT_FIXUP_HEADPHONE_MIC_PIN,
@@ -3357,6 +3358,15 @@ static const struct hda_fixup cxt_fixups[] = {
 		.type = HDA_FIXUP_PINS,
 		.v.pins = cxt_pincfg_lemote,
 	},
+	[CXT_PINCFG_COMPAQ_CQ60] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = (const struct hda_pintbl[]) {
+			/* 0x17 was falsely set up as a mic, it should 0x1d */
+			{ 0x17, 0x400001f0 },
+			{ 0x1d, 0x97a70120 },
+			{ }
+		}
+	},
 	[CXT_FIXUP_STEREO_DMIC] = {
 		.type = HDA_FIXUP_FUNC,
 		.v.func = cxt_fixup_stereo_dmic,
@@ -3396,6 +3406,7 @@ static const struct hda_fixup cxt_fixups[] = {
 };
 
 static const struct snd_pci_quirk cxt5051_fixups[] = {
+	SND_PCI_QUIRK(0x103c, 0x360b, "Compaq CQ60", CXT_PINCFG_COMPAQ_CQ60),
 	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200),
 	{}
 };
Signature · 1 line
2.3.4
author
#49 lore raw

PATCH 49/155 ALSA: hda - Don't access stereo amps for mono channel widgets

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit ef403edb75580a3ec5d155f5de82155f0419c621 upstream.

The current HDA generic parser initializes / modifies the amp values always in stereo, but this seems causing the problem on ALC3229 codec that has a few mono channel widgets: namely, these mono widgets react to actions for both channels equally.

In the driver code, we do care the mono channel and create a control only for the left channel (as defined in HD-audio spec) for such a node. When the control is updated, only the left channel value is changed. However, in the resume, the right channel value is also restored from the initial value we took as stereo, and this overwrites the left channel value. This ends up being the silent output as the right channel has been never touched and remains muted.

This patch covers the places where unconditional stereo amp accesses are done and converts to the conditional accesses.

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

---
 sound/pci/hda/hda_generic.c | 30 ++++++++++++++++++++++--------
 1 file changed, 22 insertions(+), 8 deletions(-)
sound/pci/hda/hda_generic.c +22 -8
index 31da88bf6c1c..91fabbadd07b 100644
@@ -657,7 +657,23 @@ static void init_amp(struct hda_codec *codec, hda_nid_t nid, int dir, int idx)
 {
 	unsigned int caps = query_amp_caps(codec, nid, dir);
 	int val = get_amp_val_to_activate(codec, nid, dir, caps, false);
-	snd_hda_codec_amp_init_stereo(codec, nid, dir, idx, 0xff, val);
+
+	if (get_wcaps(codec, nid) & AC_WCAP_STEREO)
+		snd_hda_codec_amp_init_stereo(codec, nid, dir, idx, 0xff, val);
+	else
+		snd_hda_codec_amp_init(codec, nid, 0, dir, idx, 0xff, val);
+}
+
+/* update the amp, doing in stereo or mono depending on NID */
+static int update_amp(struct hda_codec *codec, hda_nid_t nid, int dir, int idx,
+		      unsigned int mask, unsigned int val)
+{
+	if (get_wcaps(codec, nid) & AC_WCAP_STEREO)
+		return snd_hda_codec_amp_stereo(codec, nid, dir, idx,
+						mask, val);
+	else
+		return snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
+						mask, val);
 }
 
 /* calculate amp value mask we can modify;
@@ -697,7 +713,7 @@ static void activate_amp(struct hda_codec *codec, hda_nid_t nid, int dir,
 		return;
 
 	val &= mask;
-	snd_hda_codec_amp_stereo(codec, nid, dir, idx, mask, val);
+	update_amp(codec, nid, dir, idx, mask, val);
 }
 
 static void activate_amp_out(struct hda_codec *codec, struct nid_path *path,
@@ -4331,13 +4347,11 @@ static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix)
 	has_amp = nid_has_mute(codec, mix, HDA_INPUT);
 	for (i = 0; i < nums; i++) {
 		if (has_amp)
-			snd_hda_codec_amp_stereo(codec, mix,
-						 HDA_INPUT, i,
-						 0xff, HDA_AMP_MUTE);
+			update_amp(codec, mix, HDA_INPUT, i,
+				   0xff, HDA_AMP_MUTE);
 		else if (nid_has_volume(codec, conn[i], HDA_OUTPUT))
-			snd_hda_codec_amp_stereo(codec, conn[i],
-						 HDA_OUTPUT, 0,
-						 0xff, HDA_AMP_MUTE);
+			update_amp(codec, conn[i], HDA_OUTPUT, 0,
+				   0xff, HDA_AMP_MUTE);
 	}
 }
 
Signature · 1 line
2.3.4
author
#50 lore raw

PATCH 50/155 ALSA: hda - Set single_adc_amp flag for CS420x codecs

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit bad994f5b4ab57eec8d56c180edca00505c3eeb2 upstream.

CS420x codecs seem to deal only the single amps of ADC nodes even though the nodes receive multiple inputs. This leads to the inconsistent amp value after S3/S4 resume, for example.

The fix is just to set codec->single_adc_amp flag. Then the driver handles these ADC amps as if single connections.

---
 sound/pci/hda/patch_cirrus.c | 1 +
 1 file changed, 1 insertion(+)
sound/pci/hda/patch_cirrus.c +1 -0
index 072755c8289c..593b541d4f06 100644
@@ -572,6 +572,7 @@ static int patch_cs420x(struct hda_codec *codec)
 		return -ENOMEM;
 
 	spec->gen.automute_hook = cs_automute;
+	codec->single_adc_amp = 1;
 
 	snd_hda_pick_fixup(codec, cs420x_models, cs420x_fixup_tbl,
 			   cs420x_fixups);
Signature · 1 line
2.3.4
author
#51 lore raw

PATCH 51/155 ALSA: hda - Add workaround for MacBook Air 5,2 built-in mic

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 2ddee91abe9cc34ddb6294ee14702b46ae07d460 upstream.

MacBook Air 5,2 has the same problem as MacBook Pro 8,1 where the built-in mic records only the right channel. Apply the same workaround as MBP8,1 to spread the mono channel via a Cirrus codec vendor-specific COEF setup.

---
 sound/pci/hda/patch_cirrus.c | 1 +
 1 file changed, 1 insertion(+)
sound/pci/hda/patch_cirrus.c +1 -0
index 593b541d4f06..ab0d0a384c15 100644
@@ -381,6 +381,7 @@ static const struct snd_pci_quirk cs420x_fixup_tbl[] = {
 	SND_PCI_QUIRK(0x106b, 0x1c00, "MacBookPro 8,1", CS420X_MBP81),
 	SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122),
 	SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101),
+	SND_PCI_QUIRK(0x106b, 0x5600, "MacBookAir 5,2", CS420X_MBP81),
 	SND_PCI_QUIRK(0x106b, 0x5b00, "MacBookAir 4,2", CS420X_MBA42),
 	SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE),
 	{} /* terminator */
Signature · 1 line
2.3.4
author
#52 lore raw

PATCH 52/155 ALSA: hda - Treat stereo-to-mono mix properly

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit cc261738add93947d138d2fabad9f4dbed4e5c00 upstream.

The commit [ef403edb7558: ALSA: hda - Don't access stereo amps for mono channel widgets] fixed the handling of mono widgets in general, but it still misses an exceptional case: namely, a mono mixer widget taking a single stereo input. In this case, it has stereo volumes although it's a mono widget, and thus we have to take care of both left and right input channels, as stated in HD-audio spec ("7.1.3 Widget Interconnection Rules").

This patch covers this missing piece by adding proper checks of stereo amps in both the generic parser and the proc output codes.

---
 sound/pci/hda/hda_generic.c | 21 +++++++++++++++++++--
 sound/pci/hda/hda_proc.c    | 38 ++++++++++++++++++++++++++++++--------
 2 files changed, 49 insertions(+), 10 deletions(-)
sound/pci/hda/hda_generic.c +19 -2
index 91fabbadd07b..1b1243450d8e 100644
@@ -652,13 +652,30 @@ static int get_amp_val_to_activate(struct hda_codec *codec, hda_nid_t nid,
 	return val;
 }
 
+/* is this a stereo widget or a stereo-to-mono mix? */
+static bool is_stereo_amps(struct hda_codec *codec, hda_nid_t nid, int dir)
+{
+	unsigned int wcaps = get_wcaps(codec, nid);
+	hda_nid_t conn;
+
+	if (wcaps & AC_WCAP_STEREO)
+		return true;
+	if (dir != HDA_INPUT || get_wcaps_type(wcaps) != AC_WID_AUD_MIX)
+		return false;
+	if (snd_hda_get_num_conns(codec, nid) != 1)
+		return false;
+	if (snd_hda_get_connections(codec, nid, &conn, 1) < 0)
+		return false;
+	return !!(get_wcaps(codec, conn) & AC_WCAP_STEREO);
+}
+
 /* initialize the amp value (only at the first time) */
 static void init_amp(struct hda_codec *codec, hda_nid_t nid, int dir, int idx)
 {
 	unsigned int caps = query_amp_caps(codec, nid, dir);
 	int val = get_amp_val_to_activate(codec, nid, dir, caps, false);
 
-	if (get_wcaps(codec, nid) & AC_WCAP_STEREO)
+	if (is_stereo_amps(codec, nid, dir))
 		snd_hda_codec_amp_init_stereo(codec, nid, dir, idx, 0xff, val);
 	else
 		snd_hda_codec_amp_init(codec, nid, 0, dir, idx, 0xff, val);
@@ -668,7 +685,7 @@ static void init_amp(struct hda_codec *codec, hda_nid_t nid, int dir, int idx)
 static int update_amp(struct hda_codec *codec, hda_nid_t nid, int dir, int idx,
 		      unsigned int mask, unsigned int val)
 {
-	if (get_wcaps(codec, nid) & AC_WCAP_STEREO)
+	if (is_stereo_amps(codec, nid, dir))
 		return snd_hda_codec_amp_stereo(codec, nid, dir, idx,
 						mask, val);
 	else
sound/pci/hda/hda_proc.c +30 -8
index a8cb22eec89e..d64193c1a387 100644
@@ -129,13 +129,38 @@ static void print_amp_caps(struct snd_info_buffer *buffer,
 		    (caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT);
 }
 
+/* is this a stereo widget or a stereo-to-mono mix? */
+static bool is_stereo_amps(struct hda_codec *codec, hda_nid_t nid,
+			   int dir, unsigned int wcaps, int indices)
+{
+	hda_nid_t conn;
+
+	if (wcaps & AC_WCAP_STEREO)
+		return true;
+	/* check for a stereo-to-mono mix; it must be:
+	 * only a single connection, only for input, and only a mixer widget
+	 */
+	if (indices != 1 || dir != HDA_INPUT ||
+	    get_wcaps_type(wcaps) != AC_WID_AUD_MIX)
+		return false;
+
+	if (snd_hda_get_raw_connections(codec, nid, &conn, 1) < 0)
+		return false;
+	/* the connection source is a stereo? */
+	wcaps = snd_hda_param_read(codec, conn, AC_PAR_AUDIO_WIDGET_CAP);
+	return !!(wcaps & AC_WCAP_STEREO);
+}
+
 static void print_amp_vals(struct snd_info_buffer *buffer,
 			   struct hda_codec *codec, hda_nid_t nid,
-			   int dir, int stereo, int indices)
+			   int dir, unsigned int wcaps, int indices)
 {
 	unsigned int val;
+	bool stereo;
 	int i;
 
+	stereo = is_stereo_amps(codec, nid, dir, wcaps, indices);
+
 	dir = dir == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT;
 	for (i = 0; i < indices; i++) {
 		snd_iprintf(buffer, " [");
@@ -727,12 +752,10 @@ static void print_codec_info(struct snd_info_entry *entry,
 			    (codec->single_adc_amp &&
 			     wid_type == AC_WID_AUD_IN))
 				print_amp_vals(buffer, codec, nid, HDA_INPUT,
-					       wid_caps & AC_WCAP_STEREO,
-					       1);
+					       wid_caps, 1);
 			else
 				print_amp_vals(buffer, codec, nid, HDA_INPUT,
-					       wid_caps & AC_WCAP_STEREO,
-					       conn_len);
+					       wid_caps, conn_len);
 		}
 		if (wid_caps & AC_WCAP_OUT_AMP) {
 			snd_iprintf(buffer, "  Amp-Out caps: ");
@@ -741,11 +764,10 @@ static void print_codec_info(struct snd_info_entry *entry,
 			if (wid_type == AC_WID_PIN &&
 			    codec->pin_amp_workaround)
 				print_amp_vals(buffer, codec, nid, HDA_OUTPUT,
-					       wid_caps & AC_WCAP_STEREO,
-					       conn_len);
+					       wid_caps, conn_len);
 			else
 				print_amp_vals(buffer, codec, nid, HDA_OUTPUT,
-					       wid_caps & AC_WCAP_STEREO, 1);
+					       wid_caps, 1);
 		}
 
 		switch (wid_type) {
Signature · 1 line
2.3.4
author
#53 lore raw

PATCH 53/155 bnx2x: Force fundamental reset for EEH recovery

In reply to Jiri Slaby

From: Brian King <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit da293700568ed3d96fcf062ac15d7d7c41377f11 upstream.

EEH recovery for bnx2x based adapters is not reliable on all Power systems using the default hot reset, which can result in an unrecoverable EEH error. Forcing the use of fundamental reset during EEH recovery fixes this.

---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +4 -0
index b42f89ce02ef..237a5611d3f6 100644
@@ -12236,6 +12236,10 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev,
 	/* clean indirect addresses */
 	pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS,
 			       PCICFG_VENDOR_ID_OFFSET);
+
+	/* Set PCIe reset type to fundamental for EEH recovery */
+	pdev->needs_freset = 1;
+
 	/*
 	 * Clean the following indirect addresses for all functions since it
 	 * is not used by the driver.
Signature · 1 line
2.3.4
author
#54 lore raw

PATCH 54/155 regulator: Only enable disabled regulators on resume

In reply to Jiri Slaby

From: Javier Martinez Canillas <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 0548bf4f5ad6fc3bd93c4940fa48078b34609682 upstream.

The _regulator_do_enable() call ought to be a no-op when called on an already-enabled regulator. However, as an optimization _regulator_enable() doesn't call _regulator_do_enable() on an already enabled regulator. That means we never test the case of calling _regulator_do_enable() during normal usage and there may be hidden bugs or warnings. We have seen warnings issued by the tps65090 driver and bugs when using the GPIO enable pin.

Let's match the same optimization that _regulator_enable() in regulator_suspend_finish(). That may speed up suspend/resume and also avoids exposing hidden bugs.

[Use much clearer commit message from Doug Anderson]

---
 drivers/regulator/core.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/regulator/core.c +5 -3
index a2ce8e86ced7..c860eed8735e 100644
@@ -3569,9 +3569,11 @@ int regulator_suspend_finish(void)
 	list_for_each_entry(rdev, &regulator_list, list) {
 		mutex_lock(&rdev->mutex);
 		if (rdev->use_count > 0  || rdev->constraints->always_on) {
-			error = _regulator_do_enable(rdev);
-			if (error)
-				ret = error;
+			if (!_regulator_is_enabled(rdev)) {
+				error = _regulator_do_enable(rdev);
+				if (error)
+					ret = error;
+			}
 		} else {
 			if (!has_full_constraints)
 				goto unlock;
Signature · 1 line
2.3.4
author
#55 lore raw

PATCH 55/155 regulator: core: Fix enable GPIO reference counting

In reply to Jiri Slaby

From: Doug Anderson <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 29d62ec5f87fbeec8413e2215ddad12e7f972e4c upstream.

Normally _regulator_do_enable() isn't called on an already-enabled rdev. That's because the main caller, _regulator_enable() always calls _regulator_is_enabled() and only calls _regulator_do_enable() if the rdev was not already enabled.

However, there is one caller of _regulator_do_enable() that doesn't
check: regulator_suspend_finish(). While we might want to make regulator_suspend_finish() behave more like _regulator_enable(), it's probably also a good idea to make _regulator_do_enable() robust if it is called on an already enabled rdev.

At the moment, _regulator_do_enable() is _not_ robust for already enabled rdevs if we're using an ena_pin. Each time _regulator_do_enable() is called for an rdev using an ena_pin the reference count of the ena_pin is incremented even if the rdev was already enabled. This is not as intended because the ena_pin is for something else: for keeping track of how many active rdevs there are sharing the same ena_pin.

Here's how the reference counting works here:

* Each time _regulator_enable() is called we increment rdev->use_count, so _regulator_enable() calls need to be balanced with _regulator_disable() calls.

* There is no explicit reference counting in _regulator_do_enable() which is normally just a warapper around rdev->desc->ops->enable() with code for supporting delays. It's not expected that the "ops->enable()" call do reference counting.

* Since regulator_ena_gpio_ctrl() does have reference counting (handling the sharing of the pin amongst multiple rdevs), we shouldn't call it if the current rdev is already enabled.

Note that as part of this we cleanup (remove) the initting of ena_gpio_state in regulator_register(). In _regulator_do_enable(), _regulator_do_disable() and _regulator_is_enabled() is is clear that ena_gpio_state should be the state of whether this particular rdev has requested the GPIO be enabled. regulator_register() was initting it as the actual state of the pin.

Fixes 967cfb18c0e3 ("regulator: core: manage enable GPIO list")
---
 drivers/regulator/core.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)
drivers/regulator/core.c +12 -14
index c860eed8735e..ef79c1c4280f 100644
@@ -1690,10 +1690,12 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
 	trace_regulator_enable(rdev_get_name(rdev));
 
 	if (rdev->ena_pin) {
-		ret = regulator_ena_gpio_ctrl(rdev, true);
-		if (ret < 0)
-			return ret;
-		rdev->ena_gpio_state = 1;
+		if (!rdev->ena_gpio_state) {
+			ret = regulator_ena_gpio_ctrl(rdev, true);
+			if (ret < 0)
+				return ret;
+			rdev->ena_gpio_state = 1;
+		}
 	} else if (rdev->desc->ops->enable) {
 		ret = rdev->desc->ops->enable(rdev);
 		if (ret < 0)
@@ -1795,10 +1797,12 @@ static int _regulator_do_disable(struct regulator_dev *rdev)
 	trace_regulator_disable(rdev_get_name(rdev));
 
 	if (rdev->ena_pin) {
-		ret = regulator_ena_gpio_ctrl(rdev, false);
-		if (ret < 0)
-			return ret;
-		rdev->ena_gpio_state = 0;
+		if (rdev->ena_gpio_state) {
+			ret = regulator_ena_gpio_ctrl(rdev, false);
+			if (ret < 0)
+				return ret;
+			rdev->ena_gpio_state = 0;
+		}
 
 	} else if (rdev->desc->ops->disable) {
 		ret = rdev->desc->ops->disable(rdev);
@@ -3392,12 +3396,6 @@ regulator_register(const struct regulator_desc *regulator_desc,
 				 config->ena_gpio, ret);
 			goto wash;
 		}
-
-		if (config->ena_gpio_flags & GPIOF_OUT_INIT_HIGH)
-			rdev->ena_gpio_state = 1;
-
-		if (config->ena_gpio_invert)
-			rdev->ena_gpio_state = !rdev->ena_gpio_state;
 	}
 
 	/* set regulator constraints */
Signature · 1 line
2.3.4
author
#56 lore raw

PATCH 56/155 nilfs2: fix deadlock of segment constructor during recovery

In reply to Jiri Slaby

From: Ryusuke Konishi <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 283ee1482f349d6c0c09dfb725db5880afc56813 upstream.

According to a report from Yuxuan Shui, nilfs2 in kernel 3.19 got stuck during recovery at mount time. The code path that caused the deadlock was as follows:

nilfs_fill_super()
load_nilfs()
nilfs_salvage_orphan_logs()
* Do roll-forwarding, attach segment constructor for recovery, and kick it.

nilfs_segctor_thread()
nilfs_segctor_thread_construct()
* A lock is held with nilfs_transaction_lock() nilfs_segctor_do_construct() nilfs_segctor_drop_written_files()
iput()
iput_final()
write_inode_now()
writeback_single_inode()
__writeback_single_inode()
do_writepages()
nilfs_writepage()
nilfs_construct_dsync_segment()
nilfs_transaction_lock() --> deadlock

This can happen if commit 7ef3ff2fea8b ("nilfs2: fix deadlock of segment constructor over I_SYNC flag") is applied and roll-forward recovery was performed at mount time. The roll-forward recovery can happen if datasync write is done and the file system crashes immediately after that. For instance, we can reproduce the issue with the following steps:

< nilfs2 is mounted on /nilfs (device: /dev/sdb1) >

 # dd if=/dev/zero of=/nilfs/test bs=4k count=1 && sync
 # dd if=/dev/zero of=/nilfs/test conv=notrunc oflag=dsync bs=4k
 count=1 && reboot -nfh
 < the system will immediately reboot >
 # mount -t nilfs2 /dev/sdb1 /nilfs

The deadlock occurs because iput() can run segment constructor through writeback_single_inode() if MS_ACTIVE flag is not set on sb->s_flags. The above commit changed segment constructor so that it calls iput() asynchronously for inodes with i_nlink == 0, but that change was imperfect.

This fixes the another deadlock by deferring iput() in segment constructor even for the case that mount is not finished, that is, for the case that MS_ACTIVE flag is not set.

---
 fs/nilfs2/segment.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
fs/nilfs2/segment.c +4 -3
index a0c815b71e6a..85a9bb94a72b 100644
@@ -1907,6 +1907,7 @@ static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci,
 					     struct the_nilfs *nilfs)
 {
 	struct nilfs_inode_info *ii, *n;
+	int during_mount = !(sci->sc_super->s_flags & MS_ACTIVE);
 	int defer_iput = false;
 
 	spin_lock(&nilfs->ns_inode_lock);
@@ -1919,10 +1920,10 @@ static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci,
 		brelse(ii->i_bh);
 		ii->i_bh = NULL;
 		list_del_init(&ii->i_dirty);
-		if (!ii->vfs_inode.i_nlink) {
+		if (!ii->vfs_inode.i_nlink || during_mount) {
 			/*
-			 * Defer calling iput() to avoid a deadlock
-			 * over I_SYNC flag for inodes with i_nlink == 0
+			 * Defer calling iput() to avoid deadlocks if
+			 * i_nlink == 0 or mount is not yet finished.
 			 */
 			list_add_tail(&ii->i_dirty, &sci->sc_iput_queue);
 			defer_iput = true;
Signature · 1 line
2.3.4
author
#57 lore raw

PATCH 57/155 drm/vmwgfx: Reorder device takedown somewhat

In reply to Jiri Slaby

From: Thomas Hellstrom <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 3458390b9f0ba784481d23134798faee27b5f16f upstream.

To take down the MOB and GMR memory types, the driver may have to issue fence objects and thus make sure that the fence manager is taken down after those memory types.
Reorder device init accordingly.

---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 47 ++++++++++++++++++++-----------------
 1 file changed, 25 insertions(+), 22 deletions(-)
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +25 -22
index 0508f93b9795..59cd2baf6dc0 100644
@@ -550,21 +550,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
 		goto out_err1;
 	}
 
-	ret = ttm_bo_init_mm(&dev_priv->bdev, TTM_PL_VRAM,
-			     (dev_priv->vram_size >> PAGE_SHIFT));
-	if (unlikely(ret != 0)) {
-		DRM_ERROR("Failed initializing memory manager for VRAM.\n");
-		goto out_err2;
-	}
-
-	dev_priv->has_gmr = true;
-	if (ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_GMR,
-			   dev_priv->max_gmr_ids) != 0) {
-		DRM_INFO("No GMR memory available. "
-			 "Graphics memory resources are very limited.\n");
-		dev_priv->has_gmr = false;
-	}
-
 	dev_priv->mmio_mtrr = arch_phys_wc_add(dev_priv->mmio_start,
 					       dev_priv->mmio_size);
 
@@ -627,6 +612,22 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
 		goto out_no_fman;
 	}
 
+
+	ret = ttm_bo_init_mm(&dev_priv->bdev, TTM_PL_VRAM,
+			     (dev_priv->vram_size >> PAGE_SHIFT));
+	if (unlikely(ret != 0)) {
+		DRM_ERROR("Failed initializing memory manager for VRAM.\n");
+		goto out_no_vram;
+	}
+
+	dev_priv->has_gmr = true;
+	if (ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_GMR,
+			   dev_priv->max_gmr_ids) != 0) {
+		DRM_INFO("No GMR memory available. "
+			 "Graphics memory resources are very limited.\n");
+		dev_priv->has_gmr = false;
+	}
+
 	vmw_kms_save_vga(dev_priv);
 
 	/* Start kms and overlay systems, needs fifo. */
@@ -652,6 +653,10 @@ out_no_fifo:
 	vmw_kms_close(dev_priv);
 out_no_kms:
 	vmw_kms_restore_vga(dev_priv);
+	if (dev_priv->has_gmr)
+		(void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR);
+	(void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM);
+out_no_vram:
 	vmw_fence_manager_takedown(dev_priv->fman);
 out_no_fman:
 	if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
@@ -667,10 +672,6 @@ out_err4:
 	iounmap(dev_priv->mmio_virt);
 out_err3:
 	arch_phys_wc_del(dev_priv->mmio_mtrr);
-	if (dev_priv->has_gmr)
-		(void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR);
-	(void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM);
-out_err2:
 	(void)ttm_bo_device_release(&dev_priv->bdev);
 out_err1:
 	vmw_ttm_global_release(dev_priv);
@@ -700,6 +701,11 @@ static int vmw_driver_unload(struct drm_device *dev)
 	}
 	vmw_kms_close(dev_priv);
 	vmw_overlay_close(dev_priv);
+
+	if (dev_priv->has_gmr)
+		(void)ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR);
+	(void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM);
+
 	vmw_fence_manager_takedown(dev_priv->fman);
 	if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
 		drm_irq_uninstall(dev_priv->dev);
@@ -711,9 +717,6 @@ static int vmw_driver_unload(struct drm_device *dev)
 	ttm_object_device_release(&dev_priv->tdev);
 	iounmap(dev_priv->mmio_virt);
 	arch_phys_wc_del(dev_priv->mmio_mtrr);
-	if (dev_priv->has_gmr)
-		(void)ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR);
-	(void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM);
 	(void)ttm_bo_device_release(&dev_priv->bdev);
 	vmw_ttm_global_release(dev_priv);
 
Signature · 1 line
2.3.4
author
#58 lore raw

PATCH 58/155 xen-pciback: limit guest control of command register

In reply to Jiri Slaby

From: Jan Beulich <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit af6fc858a35b90e89ea7a7ee58e66628c55c776b upstream.

Otherwise the guest can abuse that control to cause e.g. PCIe Unsupported Request responses by disabling memory and/or I/O decoding and subsequently causing (CPU side) accesses to the respective address ranges, which (depending on system configuration) may be fatal to the host.

Note that to alter any of the bits collected together as PCI_COMMAND_GUEST permissive mode is now required to be enabled globally or on the specific device.

This is CVE-2015-2150 / XSA-120.

---
 drivers/xen/xen-pciback/conf_space.c        |  2 +-
 drivers/xen/xen-pciback/conf_space.h        |  2 +
 drivers/xen/xen-pciback/conf_space_header.c | 61 +++++++++++++++++++++++------
 3 files changed, 51 insertions(+), 14 deletions(-)
drivers/xen/xen-pciback/conf_space.c +1 -1
index 46ae0f9f02ad..75fe3d466515 100644
@@ -16,7 +16,7 @@
 #include "conf_space.h"
 #include "conf_space_quirks.h"
 
-static bool permissive;
+bool permissive;
 module_param(permissive, bool, 0644);
 
 /* This is where xen_pcibk_read_config_byte, xen_pcibk_read_config_word,
drivers/xen/xen-pciback/conf_space.h +2 -0
index e56c934ad137..2e1d73d1d5d0 100644
@@ -64,6 +64,8 @@ struct config_field_entry {
 	void *data;
 };
 
+extern bool permissive;
+
 #define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset)
 
 /* Add fields to a device - the add_fields macro expects to get a pointer to
drivers/xen/xen-pciback/conf_space_header.c +48 -13

94 lines not on this page · raw message

Signature · 1 line
2.3.4
author
#59 lore raw

PATCH 59/155 libsas: Fix Kernel Crash in smp_execute_task

In reply to Jiri Slaby

From: James Bottomley <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 6302ce4d80aa82b3fdb5c5cd68e7268037091b47 upstream.

This crash was reported:

[  366.947370] sd 3:0:1:0: [sdb] Spinning up disk....
[  368.804046] BUG: unable to handle kernel NULL pointer dereference at           (null)
[  368.804072] IP: [<ffffffff81358457>] __mutex_lock_common.isra.7+0x9c/0x15b
[  368.804098] PGD 0
[  368.804114] Oops: 0002 [#1] SMP
[  368.804143] CPU 1
[  368.804151] Modules linked in: sg netconsole s3g(PO) uinput joydev hid_multitouch usbhid hid snd_hda_codec_via cpufreq_userspace cpufreq_powersave cpufreq_stats uhci_hcd cpufreq_conservative snd_hda_intel snd_hda_codec snd_hwdep snd_pcm sdhci_pci snd_page_alloc sdhci snd_timer snd psmouse evdev serio_raw pcspkr soundcore xhci_hcd shpchp s3g_drm(O) mvsas mmc_core ahci libahci drm i2c_core acpi_cpufreq mperf video processor button thermal_sys dm_dmirror exfat_fs exfat_core dm_zcache dm_mod padlock_aes aes_generic padlock_sha iscsi_target_mod target_core_mod configfs sswipe libsas libata scsi_transport_sas picdev via_cputemp hwmon_vid fuse parport_pc ppdev lp parport autofs4 ext4 crc16 mbcache jbd2 sd_mod crc_t10dif usb_storage scsi_mod ehci_hcd usbcore usb_common
[  368.804749]
[  368.804764] Pid: 392, comm: kworker/u:3 Tainted: P        W  O 3.4.87-logicube-ng.22 #1 To be filled by O.E.M. To be filled by O.E.M./EPIA-M920
[  368.804802] RIP: 0010:[<ffffffff81358457>]  [<ffffffff81358457>] __mutex_lock_common.isra.7+0x9c/0x15b
[  368.804827] RSP: 0018:ffff880117001cc0  EFLAGS: 00010246
[  368.804842] RAX: 0000000000000000 RBX: ffff8801185030d0 RCX: ffff88008edcb420
[  368.804857] RDX: 0000000000000000 RSI: 0000000000000002 RDI: ffff8801185030d4
[  368.804873] RBP: ffff8801181531c0 R08: 0000000000000020 R09: 00000000fffffffe
[  368.804885] R10: 0000000000000000 R11: 0000000000000000 R12: ffff8801185030d4
[  368.804899] R13: 0000000000000002 R14: ffff880117001fd8 R15: ffff8801185030d8
[  368.804916] FS:  0000000000000000(0000) GS:ffff88011fc80000(0000) knlGS:0000000000000000
[  368.804931] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[  368.804946] CR2: 0000000000000000 CR3: 000000000160b000 CR4: 00000000000006e0
[  368.804962] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[  368.804978] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[  368.804995] Process kworker/u:3 (pid: 392, threadinfo ffff880117000000, task ffff8801181531c0)
[  368.805009] Stack:
[  368.805017]  ffff8801185030d8 0000000000000000 ffffffff8161ddf0 ffffffff81056f7c
[  368.805062]  000000000000b503 ffff8801185030d0 ffff880118503000 0000000000000000
[  368.805100]  ffff8801185030d0 ffff8801188b8000 ffff88008edcb420 ffffffff813583ac
[  368.805135] Call Trace:
[  368.805153]  [<ffffffff81056f7c>] ? up+0xb/0x33
[  368.805168]  [<ffffffff813583ac>] ? mutex_lock+0x16/0x25
[  368.805194]  [<ffffffffa018c414>] ? smp_execute_task+0x4e/0x222 [libsas]
[  368.805217]  [<ffffffffa018ce1c>] ? sas_find_bcast_dev+0x3c/0x15d [libsas]
[  368.805240]  [<ffffffffa018ce4f>] ? sas_find_bcast_dev+0x6f/0x15d [libsas]
[  368.805264]  [<ffffffffa018e989>] ? sas_ex_revalidate_domain+0x37/0x2ec [libsas]
[  368.805280]  [<ffffffff81355a2a>] ? printk+0x43/0x48
[  368.805296]  [<ffffffff81359a65>] ? _raw_spin_unlock_irqrestore+0xc/0xd
[  368.805318]  [<ffffffffa018b767>] ? sas_revalidate_domain+0x85/0xb6 [libsas]
[  368.805336]  [<ffffffff8104e5d9>] ? process_one_work+0x151/0x27c
[  368.805351]  [<ffffffff8104f6cd>] ? worker_thread+0xbb/0x152
[  368.805366]  [<ffffffff8104f612>] ? manage_workers.isra.29+0x163/0x163
[  368.805382]  [<ffffffff81052c4e>] ? kthread+0x79/0x81
[  368.805399]  [<ffffffff8135fea4>] ? kernel_thread_helper+0x4/0x10
[  368.805416]  [<ffffffff81052bd5>] ? kthread_flush_work_fn+0x9/0x9
[  368.805431]  [<ffffffff8135fea0>] ? gs_change+0x13/0x13
[  368.805442] Code: 83 7d 30 63 7e 04 f3 90 eb ab 4c 8d 63 04 4c 8d 7b 08 4c 89 e7 e8 fa 15 00 00 48 8b 43 10 4c 89 3c 24 48 89 63 10 48 89 44 24 08 <48> 89 20 83 c8 ff 48 89 6c 24 10 87 03 ff c8 74 35 4d 89 ee 41
[  368.805851] RIP  [<ffffffff81358457>] __mutex_lock_common.isra.7+0x9c/0x15b
[  368.805877]  RSP <ffff880117001cc0>
[  368.805886] CR2: 0000000000000000
[  368.805899] ---[ end trace b720682065d8f4cc ]---

It's directly caused by 89d3cf6 [SCSI] libsas: add mutex for SMP task execution, but shows a deeper cause: expander functions expect to be able to cast to and treat domain devices as expanders. The correct fix is to only do expander discover when we know we've got an expander device to avoid wrongly casting a non-expander device.

---
 drivers/scsi/libsas/sas_discover.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/scsi/libsas/sas_discover.c +4 -2
index 62b58d38ce2e..60de66252fa2 100644
@@ -500,6 +500,7 @@ static void sas_revalidate_domain(struct work_struct *work)
 	struct sas_discovery_event *ev = to_sas_discovery_event(work);
 	struct asd_sas_port *port = ev->port;
 	struct sas_ha_struct *ha = port->ha;
+	struct domain_device *ddev = port->port_dev;
 
 	/* prevent revalidation from finding sata links in recovery */
 	mutex_lock(&ha->disco_mutex);
@@ -514,8 +515,9 @@ static void sas_revalidate_domain(struct work_struct *work)
 	SAS_DPRINTK("REVALIDATING DOMAIN on port %d, pid:%d\n", port->id,
 		    task_pid_nr(current));
 
-	if (port->port_dev)
-		res = sas_ex_revalidate_domain(port->port_dev);
+	if (ddev && (ddev->dev_type == SAS_FANOUT_EXPANDER_DEVICE ||
+		     ddev->dev_type == SAS_EDGE_EXPANDER_DEVICE))
+		res = sas_ex_revalidate_domain(ddev);
 
 	SAS_DPRINTK("done REVALIDATING DOMAIN on port %d, pid:%d, res 0x%x\n",
 		    port->id, task_pid_nr(current), res);
Signature · 1 line
2.3.4
author
#60 lore raw

PATCH 60/155 pagemap: do not leak physical addresses to non-privileged userspace

In reply to Jiri Slaby

From: "Kirill A. Shutemov" <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit ab676b7d6fbf4b294bf198fb27ade5b0e865c7ce upstream.

As pointed by recent post[1] on exploiting DRAM physical imperfection, /proc/PID/pagemap exposes sensitive information which can be used to do attacks.

This disallows anybody without CAP_SYS_ADMIN to read the pagemap.

[1] http://googleprojectzero.blogspot.com/2015/03/exploiting-dram-rowhammer-bug-to-gain.html

[ Eventually we might want to do anything more finegrained, but for now
this is the simple model. - Linus ]

---
 fs/proc/task_mmu.c | 3 +++
 1 file changed, 3 insertions(+)
fs/proc/task_mmu.c +3 -0
index 7724fbdf443f..1db8ce0086ed 100644
@@ -1230,6 +1230,9 @@ out:
 
 static int pagemap_open(struct inode *inode, struct file *file)
 {
+	/* do not disclose physical addresses: attack vector */
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
 	pr_warn_once("Bits 55-60 of /proc/PID/pagemap entries are about "
 			"to stop being page-shift some time soon. See the "
 			"linux/Documentation/vm/pagemap.txt for details.\n");
Signature · 1 line
2.3.4
author
#61 lore raw

PATCH 61/155 crypto: aesni - fix memory usage in GCM decryption

In reply to Jiri Slaby

From: Stephan Mueller <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit ccfe8c3f7e52ae83155cb038753f4c75b774ca8a upstream.

The kernel crypto API logic requires the caller to provide the length of (ciphertext || authentication tag) as cryptlen for the AEAD decryption operation. Thus, the cipher implementation must calculate the size of the plaintext output itself and cannot simply use cryptlen.

The RFC4106 GCM decryption operation tries to overwrite cryptlen memory in req->dst. As the destination buffer for decryption only needs to hold the plaintext memory but cryptlen references the input buffer holding (ciphertext || authentication tag), the assumption of the destination buffer length in RFC4106 GCM operation leads to a too large size. This patch simply uses the already calculated plaintext size.

In addition, this patch fixes the offset calculation of the AAD buffer
pointer: as mentioned before, cryptlen already includes the size of the tag. Thus, the tag does not need to be added. With the addition, the AAD will be written beyond the already allocated buffer.

Note, this fixes a kernel crash that can be triggered from user space via AF_ALG(aead) -- simply use the libkcapi test application from [1] and update it to use rfc4106-gcm-aes.

Using [1], the changes were tested using CAVS vectors to demonstrate that the crypto operation still delivers the right results.

[1] http://www.chronox.de/libkcapi.html

---
 arch/x86/crypto/aesni-intel_glue.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/crypto/aesni-intel_glue.c +2 -2
index f89e7490d303..990c9699b662 100644
@@ -989,7 +989,7 @@ static int __driver_rfc4106_decrypt(struct aead_request *req)
 		src = kmalloc(req->cryptlen + req->assoclen, GFP_ATOMIC);
 		if (!src)
 			return -ENOMEM;
-		assoc = (src + req->cryptlen + auth_tag_len);
+		assoc = (src + req->cryptlen);
 		scatterwalk_map_and_copy(src, req->src, 0, req->cryptlen, 0);
 		scatterwalk_map_and_copy(assoc, req->assoc, 0,
 			req->assoclen, 0);
@@ -1014,7 +1014,7 @@ static int __driver_rfc4106_decrypt(struct aead_request *req)
 		scatterwalk_done(&src_sg_walk, 0, 0);
 		scatterwalk_done(&assoc_sg_walk, 0, 0);
 	} else {
-		scatterwalk_map_and_copy(dst, req->dst, 0, req->cryptlen, 1);
+		scatterwalk_map_and_copy(dst, req->dst, 0, tempCipherLen, 1);
 		kfree(src);
 	}
 	return retval;
Signature · 1 line
2.3.4
author
#62 lore raw

PATCH 62/155 x86/fpu: Avoid math_state_restore() without used_math() in __restore_xstate_sig()

In reply to Jiri Slaby

From: Oleg Nesterov <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit a7c80ebcac3068b1c3cb27d538d29558c30010c8 upstream.

math_state_restore() assumes it is called with irqs disabled, but this is not true if the caller is __restore_xstate_sig().

This means that if ia32_fxstate == T and __copy_from_user() fails, __restore_xstate_sig() returns with irqs disabled too.

This triggers:

  BUG: sleeping function called from invalid context at kernel/locking/rwsem.c:41
   dump_stack
   ___might_sleep
   ? _raw_spin_unlock_irqrestore
   __might_sleep
   down_read
   ? _raw_spin_unlock_irqrestore
   print_vma_addr
   signal_fault
   sys32_rt_sigreturn

Change __restore_xstate_sig() to call set_used_math() unconditionally. This avoids enabling and disabling interrupts in math_state_restore(). If copy_from_user() fails, we can simply do fpu_finit() by hand.

[ Note: this is only the first step. math_state_restore() should
not check used_math(), it should set this flag. While init_fpu() should simply die. ]

Cc Andy Lutomirski <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Dave Hansen <[email protected]>
Cc Fenghua Yu <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Pekka Riikonen <[email protected]>
Cc Quentin Casasnovas <[email protected]>
Cc Rik van Riel <[email protected]>
Cc Suresh Siddha <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 arch/x86/kernel/xsave.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
arch/x86/kernel/xsave.c +4 -3
index f5869fc65d66..bf640b8db9b3 100644
@@ -375,7 +375,7 @@ int __restore_xstate_sig(void __user *buf, void __user *buf_fx, int size)
 		 * thread's fpu state, reconstruct fxstate from the fsave
 		 * header. Sanitize the copied state etc.
 		 */
-		struct xsave_struct *xsave = &tsk->thread.fpu.state->xsave;
+		struct fpu *fpu = &tsk->thread.fpu;
 		struct user_i387_ia32_struct env;
 		int err = 0;
 
@@ -389,14 +389,15 @@ int __restore_xstate_sig(void __user *buf, void __user *buf_fx, int size)
 		 */
 		drop_fpu(tsk);
 
-		if (__copy_from_user(xsave, buf_fx, state_size) ||
+		if (__copy_from_user(&fpu->state->xsave, buf_fx, state_size) ||
 		    __copy_from_user(&env, buf, sizeof(env))) {
+			fpu_finit(fpu);
 			err = -1;
 		} else {
 			sanitize_restored_xstate(tsk, &env, xstate_bv, fx_only);
-			set_used_math();
 		}
 
+		set_used_math();
 		if (use_eager_fpu()) {
 			preempt_disable();
 			math_state_restore();
Signature · 1 line
2.3.4
author
#63 lore raw

PATCH 63/155 x86/fpu: Drop_fpu() should not assume that tsk equals current

In reply to Jiri Slaby

From: Oleg Nesterov <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit f4c3686386393c120710dd34df2a74183ab805fd upstream.

drop_fpu() does clear_used_math() and usually this is correct because tsk == current.

However switch_fpu_finish()->restore_fpu_checking() is called before __switch_to() updates the "current_task" variable. If it fails, we will wrongly clear the PF_USED_MATH flag of the previous task.

So use clear_stopped_child_used_math() instead.

Cc Andy Lutomirski <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Dave Hansen <[email protected]>
Cc Fenghua Yu <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Pekka Riikonen <[email protected]>
Cc Quentin Casasnovas <[email protected]>
Cc Suresh Siddha <[email protected]>
Cc Thomas Gleixner <[email protected]>
---
 arch/x86/include/asm/fpu-internal.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/fpu-internal.h +1 -1
index 5be9f879957f..18cd5ed4e1ba 100644
@@ -368,7 +368,7 @@ static inline void drop_fpu(struct task_struct *tsk)
 	preempt_disable();
 	tsk->fpu_counter = 0;
 	__drop_fpu(tsk);
-	clear_used_math();
+	clear_stopped_child_used_math(tsk);
 	preempt_enable();
 }
 
Signature · 1 line
2.3.4
author
#64 lore raw

PATCH 64/155 x86/vdso: Fix the build on GCC5

In reply to Jiri Slaby

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit e893286918d2cde3a94850d8f7101cd1039e0c62 upstream.

On gcc5 the kernel does not link:

ld: .eh_frame_hdr table[4] FDE at 0000000000000648 overlaps table[5] FDE at 0000000000000670.

Because prior GCC versions always emitted NOPs on ALIGN directives, but gcc5 started omitting them.

.LSTARTFDEDLSI1 says:

/* HACK: The dwarf2 unwind routines will subtract 1 from the
return address to get an address in the middle of the presumed call instruction. Since we didn't get here via a call, we need to include the nop before the real start to make up for it. */
.long .LSTART_sigreturn-1-. /* PC-relative start address */

But commit 69d0627a7f6e ("x86 vDSO: reorder vdso32 code") from 2.6.25 replaced .org __kernel_vsyscall+32,0x90 by ALIGN right before __kernel_sigreturn.

Of course, ALIGN need not generate any NOP in there. Esp. gcc5 collapses vclock_gettime.o and int80.o together with no generated NOPs as "ALIGN".

So fix this by adding to that point at least a single NOP and make the function ALIGN possibly with more NOPs then.

Kudos for reporting and diagnosing should go to Richard.

---
 arch/x86/vdso/vdso32/sigreturn.S | 1 +
 1 file changed, 1 insertion(+)
arch/x86/vdso/vdso32/sigreturn.S +1 -0
index 31776d0efc8c..d7ec4e251c0a 100644
@@ -17,6 +17,7 @@
 	.text
 	.globl __kernel_sigreturn
 	.type __kernel_sigreturn,@function
+	nop /* this guy is needed for .LSTARTFDEDLSI1 below (watch for HACK) */
 	ALIGN
 __kernel_sigreturn:
 .LSTART_sigreturn:
Signature · 1 line
2.3.4
author
#65 lore raw

PATCH 65/155 ARM: at91: pm: fix at91rm9200 standby

In reply to Jiri Slaby

From: Alexandre Belloni <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 84e871660bebfddb9a62ebd6f19d02536e782f0a upstream.

at91rm9200 standby and suspend to ram has been broken since 00482a4078f4. It is wrongly using AT91_BASE_SYS which is a physical address and actually doesn't correspond to any register on at91rm9200.

Use the correct at91_ramc_base[0] instead.

Fixes 00482a4078f4 (ARM: at91: implement the standby function for pm/cpuidle)
---
 arch/arm/mach-at91/pm.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mach-at91/pm.h +1 -1
index 2f5908f0b8c5..d8af0755bddc 100644
@@ -37,7 +37,7 @@ static inline void at91rm9200_standby(void)
 		"    mcr    p15, 0, %0, c7, c0, 4\n\t"
 		"    str    %5, [%1, %2]"
 		:
-		: "r" (0), "r" (AT91_BASE_SYS), "r" (AT91RM9200_SDRAMC_LPR),
+		: "r" (0), "r" (at91_ramc_base[0]), "r" (AT91RM9200_SDRAMC_LPR),
 		  "r" (1), "r" (AT91RM9200_SDRAMC_SRR),
 		  "r" (lpr));
 }
Signature · 1 line
2.3.4
author
#66 lore raw

PATCH 66/155 target: Fix reference leak in target_get_sess_cmd() error path

In reply to Jiri Slaby

From: Bart Van Assche <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 7544e597343e2166daba3f32e4708533aa53c233 upstream.

This patch fixes a se_cmd->cmd_kref leak buf when se_sess->sess_tearing_down is true within target_get_sess_cmd() submission path code.

This se_cmd reference leak can occur during active session shutdown when ack_kref=1 is passed by target_submit_cmd_[map_sgls,tmr]() callers.

---
 drivers/target/target_core_transport.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/target/target_core_transport.c +4 -0
index 3931b50eeefd..65ecaa1c59a7 100644
@@ -2328,6 +2328,10 @@ int target_get_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd,
 	list_add_tail(&se_cmd->se_cmd_list, &se_sess->sess_cmd_list);
 out:
 	spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+
+	if (ret && ack_kref)
+		target_put_sess_cmd(se_sess, se_cmd);
+
 	return ret;
 }
 EXPORT_SYMBOL(target_get_sess_cmd);
Signature · 1 line
2.3.4
author
#67 lore raw

PATCH 67/155 target: Fix virtual LUN=0 target_configure_device failure OOPs

In reply to Jiri Slaby

From: Nicholas Bellinger <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 5f7da044f8bc1cfb21c962edf34bd5699a76e7ae upstream.

This patch fixes a NULL pointer dereference triggered by a late target_configure_device() -> alloc_workqueue() failure that results in target_free_device() being called with DF_CONFIGURED already set, which subsequently OOPses in destroy_workqueue() code.

Currently this only happens at modprobe target_core_mod time when core_dev_setup_virtual_lun0() -> target_configure_device() fails, and the explicit target_free_device() gets called.

To address this bug originally introduced by commit 0fd97ccf45, go ahead and move DF_CONFIGURED to end of target_configure_device() code to handle this special failure case.

---
 drivers/target/target_core_device.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/target/target_core_device.c +2 -2
index c67a56e7ee1c..4711e437479e 100644
@@ -1492,8 +1492,6 @@ int target_configure_device(struct se_device *dev)
 	ret = dev->transport->configure_device(dev);
 	if (ret)
 		goto out;
-	dev->dev_flags |= DF_CONFIGURED;
-
 	/*
 	 * XXX: there is not much point to have two different values here..
 	 */
@@ -1555,6 +1553,8 @@ int target_configure_device(struct se_device *dev)
 	list_add_tail(&dev->g_dev_node, &g_device_list);
 	mutex_unlock(&g_device_mutex);
 
+	dev->dev_flags |= DF_CONFIGURED;
+
 	return 0;
 
 out_free_alua:
Signature · 1 line
2.3.4
author
#68 lore raw

PATCH 68/155 iscsi-target: Avoid early conn_logout_comp for iser connections

In reply to Jiri Slaby

From: Nicholas Bellinger <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit f068fbc82e7696d67b1bb8189306865bedf368b6 upstream.

This patch fixes a iser specific logout bug where early complete() of conn->conn_logout_comp in iscsit_close_connection() was causing isert_wait4logout() to complete too soon, triggering a use after free NULL pointer dereference of iscsi_conn memory.

The complete() was originally added for traditional iscsi-target when a ISCSI_LOGOUT_OP failed in iscsi_target_rx_opcode(), but given iser-target does not wait in logout failure, this special case needs to be avoided.

---
 drivers/target/iscsi/iscsi_target.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/target/iscsi/iscsi_target.c +10 -4
index c60277e86e4b..8ec8dc92baf4 100644
@@ -4194,11 +4194,17 @@ int iscsit_close_connection(
 	pr_debug("Closing iSCSI connection CID %hu on SID:"
 		" %u\n", conn->cid, sess->sid);
 	/*
-	 * Always up conn_logout_comp just in case the RX Thread is sleeping
-	 * and the logout response never got sent because the connection
-	 * failed.
+	 * Always up conn_logout_comp for the traditional TCP case just in case
+	 * the RX Thread in iscsi_target_rx_opcode() is sleeping and the logout
+	 * response never got sent because the connection failed.
+	 *
+	 * However for iser-target, isert_wait4logout() is using conn_logout_comp
+	 * to signal logout response TX interrupt completion.  Go ahead and skip
+	 * this for iser since isert_rx_opcode() does not wait on logout failure,
+	 * and to avoid iscsi_conn pointer dereference in iser-target code.
 	 */
-	complete(&conn->conn_logout_comp);
+	if (conn->conn_transport->transport_type == ISCSI_TCP)
+		complete(&conn->conn_logout_comp);
 
 	iscsi_release_thread_set(conn);
 
Signature · 1 line
2.3.4
author
#69 lore raw

PATCH 69/155 target/pscsi: Fix NULL pointer dereference in get_device_type

In reply to Jiri Slaby

From: Nicholas Bellinger <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 215a8fe4198f607f34ecdbc9969dae783d8b5a61 upstream.

This patch fixes a NULL pointer dereference OOPs with pSCSI backends within target_core_stat.c code. The bug is caused by a configfs attr read if no pscsi_dev_virt->pdv_sd has been configured.

---
 drivers/target/target_core_pscsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/target/target_core_pscsi.c +1 -1
index 0f199f6a0738..29f28808fc03 100644
@@ -1111,7 +1111,7 @@ static u32 pscsi_get_device_type(struct se_device *dev)
 	struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
 	struct scsi_device *sd = pdv->pdv_sd;
 
-	return sd->type;
+	return (sd) ? sd->type : TYPE_NO_LUN;
 }
 
 static sector_t pscsi_get_blocks(struct se_device *dev)
Signature · 1 line
2.3.4
author
#70 lore raw

PATCH 70/155 target: Fix R_HOLDER bit usage for AllRegistrants

In reply to Jiri Slaby

From: Nicholas Bellinger <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit d16ca7c5198fd668db10d2c7b048ed3359c12c54 upstream.

This patch fixes the usage of R_HOLDER bit for an All Registrants reservation in READ_FULL_STATUS, where only the registration who issued RESERVE was being reported as having an active reservation.

It changes core_scsi3_pri_read_full_status() to check ahead of the list walk of active registrations to see if All Registrants is active, and if so set R_HOLDER bit and scope/type fields for all active registrations.

---
 drivers/target/target_core_pr.c | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)
drivers/target/target_core_pr.c +23 -3
index 36c507c1b4fd..39f0e32c77e7 100644
@@ -3855,7 +3855,8 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd)
 	unsigned char *buf;
 	u32 add_desc_len = 0, add_len = 0, desc_len, exp_desc_len;
 	u32 off = 8; /* off into first Full Status descriptor */
-	int format_code = 0;
+	int format_code = 0, pr_res_type = 0, pr_res_scope = 0;
+	bool all_reg = false;
 
 	if (cmd->data_length < 8) {
 		pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u"
@@ -3872,6 +3873,19 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd)
 	buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff);
 	buf[3] = (dev->t10_pr.pr_generation & 0xff);
 
+	spin_lock(&dev->dev_reservation_lock);
+	if (dev->dev_pr_res_holder) {
+		struct t10_pr_registration *pr_holder = dev->dev_pr_res_holder;
+
+		if (pr_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG ||
+		    pr_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG) {
+			all_reg = true;
+			pr_res_type = pr_holder->pr_res_type;
+			pr_res_scope = pr_holder->pr_res_scope;
+		}
+	}
+	spin_unlock(&dev->dev_reservation_lock);
+
 	spin_lock(&pr_tmpl->registration_lock);
 	list_for_each_entry_safe(pr_reg, pr_reg_tmp,
 			&pr_tmpl->registration_list, pr_reg_list) {
@@ -3921,14 +3935,20 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd)
 		 * reservation holder for PR_HOLDER bit.
 		 *
 		 * Also, if this registration is the reservation
-		 * holder, fill in SCOPE and TYPE in the next byte.
+		 * holder or there is an All Registrants reservation
+		 * active, fill in SCOPE and TYPE in the next byte.
 		 */
 		if (pr_reg->pr_res_holder) {
 			buf[off++] |= 0x01;
 			buf[off++] = (pr_reg->pr_res_scope & 0xf0) |
 				     (pr_reg->pr_res_type & 0x0f);
-		} else
+		} else if (all_reg) {
+			buf[off++] |= 0x01;
+			buf[off++] = (pr_res_scope & 0xf0) |
+				     (pr_res_type & 0x0f);
+		} else {
 			off += 2;
+		}
 
 		off += 4; /* Skip over reserved area */
 		/*
Signature · 1 line
2.3.4
author
#71 lore raw

PATCH 71/155 target: Avoid dropping AllRegistrants reservation during unregister

In reply to Jiri Slaby

From: Nicholas Bellinger <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 6c3c9baa0debeb4bcc52a78c4463a0a97518de10 upstream.

This patch fixes an issue with AllRegistrants reservations where an unregister operation by the I_T nexus reservation holder would incorrectly drop the reservation, instead of waiting until the last active I_T nexus is unregistered as per SPC-4.

This includes updating __core_scsi3_complete_pro_release() to reset dev->dev_pr_res_holder with another pr_reg for this special case, as well as a new 'unreg' parameter to determine when the release is occuring from an implicit unregister, vs. explicit RELEASE.

It also adds special handling in core_scsi3_free_pr_reg_from_nacl() to release the left-over pr_res_holder, now that pr_reg is deleted from pr_reg_list within __core_scsi3_complete_pro_release().

---
 drivers/target/target_core_pr.c | 87 ++++++++++++++++++++++++++++++-----------
 1 file changed, 65 insertions(+), 22 deletions(-)
drivers/target/target_core_pr.c +65 -22
index 39f0e32c77e7..13a4836765ea 100644
@@ -76,7 +76,7 @@ enum preempt_type {
 };
 
 static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *,
-			struct t10_pr_registration *, int);
+					      struct t10_pr_registration *, int, int);
 
 static sense_reason_t
 target_scsi2_reservation_check(struct se_cmd *cmd)
@@ -1186,7 +1186,7 @@ static int core_scsi3_check_implict_release(
 		 *    service action with the SERVICE ACTION RESERVATION KEY
 		 *    field set to zero (see 5.7.11.3).
 		 */
-		__core_scsi3_complete_pro_release(dev, nacl, pr_reg, 0);
+		__core_scsi3_complete_pro_release(dev, nacl, pr_reg, 0, 1);
 		ret = 1;
 		/*
 		 * For 'All Registrants' reservation types, all existing
@@ -1228,7 +1228,8 @@ static void __core_scsi3_free_registration(
 
 	pr_reg->pr_reg_deve->def_pr_registered = 0;
 	pr_reg->pr_reg_deve->pr_res_key = 0;
-	list_del(&pr_reg->pr_reg_list);
+	if (!list_empty(&pr_reg->pr_reg_list))
+		list_del(&pr_reg->pr_reg_list);
 	/*
 	 * Caller accessing *pr_reg using core_scsi3_locate_pr_reg(),
 	 * so call core_scsi3_put_pr_reg() to decrement our reference.
@@ -1280,6 +1281,7 @@ void core_scsi3_free_pr_reg_from_nacl(
 {
 	struct t10_reservation *pr_tmpl = &dev->t10_pr;
 	struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_res_holder;
+	bool free_reg = false;
 	/*
 	 * If the passed se_node_acl matches the reservation holder,
 	 * release the reservation.
@@ -1287,13 +1289,18 @@ void core_scsi3_free_pr_reg_from_nacl(
 	spin_lock(&dev->dev_reservation_lock);
 	pr_res_holder = dev->dev_pr_res_holder;
 	if ((pr_res_holder != NULL) &&
-	    (pr_res_holder->pr_reg_nacl == nacl))
-		__core_scsi3_complete_pro_release(dev, nacl, pr_res_holder, 0);
+	    (pr_res_holder->pr_reg_nacl == nacl)) {
+		__core_scsi3_complete_pro_release(dev, nacl, pr_res_holder, 0, 1);
+		free_reg = true;
+	}
 	spin_unlock(&dev->dev_reservation_lock);
 	/*
 	 * Release any registration associated with the struct se_node_acl.
 	 */
 	spin_lock(&pr_tmpl->registration_lock);
+	if (pr_res_holder && free_reg)
+		__core_scsi3_free_registration(dev, pr_res_holder, NULL, 0);
+
 	list_for_each_entry_safe(pr_reg, pr_reg_tmp,
 			&pr_tmpl->registration_list, pr_reg_list) {
 
@@ -1316,7 +1323,7 @@ void core_scsi3_free_all_registrations(
 	if (pr_res_holder != NULL) {
 		struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl;
 		__core_scsi3_complete_pro_release(dev, pr_res_nacl,
-				pr_res_holder, 0);
+						  pr_res_holder, 0, 0);
 	}
 	spin_unlock(&dev->dev_reservation_lock);
 
@@ -2126,13 +2133,13 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key,
 		/*
 		 * sa_res_key=0 Unregister Reservation Key for registered I_T Nexus.
 		 */
-		pr_holder = core_scsi3_check_implict_release(
-				cmd->se_dev, pr_reg);
+		type = pr_reg->pr_res_type;
+		pr_holder = core_scsi3_check_implict_release(cmd->se_dev,
+							      pr_reg);
 		if (pr_holder < 0) {
 			ret = TCM_RESERVATION_CONFLICT;
 			goto out;
 		}
-		type = pr_reg->pr_res_type;
 
 		spin_lock(&pr_tmpl->registration_lock);
 		/*
@@ -2406,23 +2413,59 @@ static void __core_scsi3_complete_pro_release(
 	struct se_device *dev,
 	struct se_node_acl *se_nacl,
 	struct t10_pr_registration *pr_reg,
-	int explict)
+	int explict,
+	int unreg)
 {
 	struct target_core_fabric_ops *tfo = se_nacl->se_tpg->se_tpg_tfo;
 	char i_buf[PR_REG_ISID_ID_LEN];
+	int pr_res_type = 0, pr_res_scope = 0;
 
 	memset(i_buf, 0, PR_REG_ISID_ID_LEN);
 	core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN);
 	/*
 	 * Go ahead and release the current PR reservation holder.
+	 * If an All Registrants reservation is currently active and
+	 * a unregister operation is requested, replace the current
+	 * dev_pr_res_holder with another active registration.
 	 */
-	dev->dev_pr_res_holder = NULL;
+	if (dev->dev_pr_res_holder) {
+		pr_res_type = dev->dev_pr_res_holder->pr_res_type;
+		pr_res_scope = dev->dev_pr_res_holder->pr_res_scope;
+		dev->dev_pr_res_holder->pr_res_type = 0;
+		dev->dev_pr_res_holder->pr_res_scope = 0;
+		dev->dev_pr_res_holder->pr_res_holder = 0;
+		dev->dev_pr_res_holder = NULL;
+	}
+	if (!unreg)
+		goto out;
 
-	pr_debug("SPC-3 PR [%s] Service Action: %s RELEASE cleared"
-		" reservation holder TYPE: %s ALL_TG_PT: %d\n",
-		tfo->get_fabric_name(), (explict) ? "explict" : "implict",
-		core_scsi3_pr_dump_type(pr_reg->pr_res_type),
-		(pr_reg->pr_reg_all_tg_pt) ? 1 : 0);
+	spin_lock(&dev->t10_pr.registration_lock);
+	list_del_init(&pr_reg->pr_reg_list);
+	/*
+	 * If the I_T nexus is a reservation holder, the persistent reservation
+	 * is of an all registrants type, and the I_T nexus is the last remaining
+	 * registered I_T nexus, then the device server shall also release the
+	 * persistent reservation.
+	 */
+	if (!list_empty(&dev->t10_pr.registration_list) &&
+	    ((pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
+	     (pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG))) {
+		dev->dev_pr_res_holder =
+			list_entry(dev->t10_pr.registration_list.next,
+				   struct t10_pr_registration, pr_reg_list);
+		dev->dev_pr_res_holder->pr_res_type = pr_res_type;
+		dev->dev_pr_res_holder->pr_res_scope = pr_res_scope;
+		dev->dev_pr_res_holder->pr_res_holder = 1;
+	}
+	spin_unlock(&dev->t10_pr.registration_lock);
+out:
+	if (!dev->dev_pr_res_holder) {
+		pr_debug("SPC-3 PR [%s] Service Action: %s RELEASE cleared"
+			" reservation holder TYPE: %s ALL_TG_PT: %d\n",
+			tfo->get_fabric_name(), (explict) ? "explict" :
+			"implict", core_scsi3_pr_dump_type(pr_res_type),
+			(pr_reg->pr_reg_all_tg_pt) ? 1 : 0);
+	}
 	pr_debug("SPC-3 PR [%s] RELEASE Node: %s%s\n",
 		tfo->get_fabric_name(), se_nacl->initiatorname,
 		i_buf);
@@ -2553,7 +2596,7 @@ core_scsi3_emulate_pro_release(struct se_cmd *cmd, int type, int scope,
 	 *    server shall not establish a unit attention condition.
 	 */
 	__core_scsi3_complete_pro_release(dev, se_sess->se_node_acl,
-			pr_reg, 1);
+					  pr_reg, 1, 0);
 
 	spin_unlock(&dev->dev_reservation_lock);
 
@@ -2641,7 +2684,7 @@ core_scsi3_emulate_pro_clear(struct se_cmd *cmd, u64 res_key)
 	if (pr_res_holder) {
 		struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl;
 		__core_scsi3_complete_pro_release(dev, pr_res_nacl,
-			pr_res_holder, 0);
+						  pr_res_holder, 0, 0);
 	}
 	spin_unlock(&dev->dev_reservation_lock);
 	/*
@@ -2700,7 +2743,7 @@ static void __core_scsi3_complete_pro_preempt(
 	 */
 	if (dev->dev_pr_res_holder)
 		__core_scsi3_complete_pro_release(dev, nacl,
-				dev->dev_pr_res_holder, 0);
+						  dev->dev_pr_res_holder, 0, 0);
 
 	dev->dev_pr_res_holder = pr_reg;
 	pr_reg->pr_res_holder = 1;
@@ -2944,8 +2987,8 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
 	 */
 	if (pr_reg_n != pr_res_holder)
 		__core_scsi3_complete_pro_release(dev,
-				pr_res_holder->pr_reg_nacl,
-				dev->dev_pr_res_holder, 0);
+						  pr_res_holder->pr_reg_nacl,
+						  dev->dev_pr_res_holder, 0, 0);
 	/*
 	 * b) Remove the registrations for all I_T nexuses identified
 	 *    by the SERVICE ACTION RESERVATION KEY field, except the
@@ -3415,7 +3458,7 @@ after_iport_check:
 	 *    holder (i.e., the I_T nexus on which the
 	 */
 	__core_scsi3_complete_pro_release(dev, pr_res_nacl,
-			dev->dev_pr_res_holder, 0);
+					  dev->dev_pr_res_holder, 0, 0);
 	/*
 	 * g) Move the persistent reservation to the specified I_T nexus using
 	 *    the same scope and type as the persistent reservation released in
Signature · 1 line
2.3.4
author
#72 lore raw

PATCH 72/155 target: Allow AllRegistrants to re-RESERVE existing reservation

In reply to Jiri Slaby

From: Nicholas Bellinger <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit ae450e246e8540300699480a3780a420a028b73f upstream.

This patch changes core_scsi3_pro_release() logic to allow an existing AllRegistrants type reservation to be re-reserved by any registered I_T nexus.

This addresses a issue where AllRegistrants type RESERVE was receiving RESERVATION_CONFLICT status if dev_pr_res_holder did not match the same I_T nexus, instead of just returning GOOD status following spc4r34 Section 5.9.9:

"If the device server receives a PERSISTENT RESERVE OUT command
with RESERVE service action where the TYPE field and the SCOPE field contain the same values as the existing type and scope from a persistent reservation holder, it shall not make any change to the existing persistent reservation and shall complete the command with GOOD status."

---
 drivers/target/target_core_pr.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/target/target_core_pr.c +4 -1
index 13a4836765ea..98e2f02b48f6 100644
@@ -2297,6 +2297,7 @@ core_scsi3_pro_reserve(struct se_cmd *cmd, int type, int scope, u64 res_key)
 	spin_lock(&dev->dev_reservation_lock);
 	pr_res_holder = dev->dev_pr_res_holder;
 	if (pr_res_holder) {
+		int pr_res_type = pr_res_holder->pr_res_type;
 		/*
 		 * From spc4r17 Section 5.7.9: Reserving:
 		 *
@@ -2307,7 +2308,9 @@ core_scsi3_pro_reserve(struct se_cmd *cmd, int type, int scope, u64 res_key)
 		 * the logical unit, then the command shall be completed with
 		 * RESERVATION CONFLICT status.
 		 */
-		if (pr_res_holder != pr_reg) {
+		if ((pr_res_holder != pr_reg) &&
+		    (pr_res_type != PR_TYPE_WRITE_EXCLUSIVE_ALLREG) &&
+		    (pr_res_type != PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) {
 			struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl;
 			pr_err("SPC-3 PR: Attempted RESERVE from"
 				" [%s]: %s while reservation already held by"
Signature · 1 line
2.3.4
author
#73 lore raw

PATCH 73/155 target: Allow Write Exclusive non-reservation holders to READ

In reply to Jiri Slaby

From: Lee Duncan <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 1ecc7586922662e3ca2f3f0c3f17fec8749fc621 upstream.

For PGR reservation of type Write Exclusive Access, allow all non reservation holding I_T nexuses with active registrations to READ from the device.

This addresses a bug where active registrations that attempted to READ would result in an reservation conflict.

---
 drivers/target/target_core_pr.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/target/target_core_pr.c +12 -0
index 98e2f02b48f6..a50982a7304f 100644
@@ -528,6 +528,18 @@ static int core_scsi3_pr_seq_non_holder(
 
 			return 0;
 		}
+       } else if (we && registered_nexus) {
+               /*
+                * Reads are allowed for Write Exclusive locks
+                * from all registrants.
+                */
+               if (cmd->data_direction == DMA_FROM_DEVICE) {
+                       pr_debug("Allowing READ CDB: 0x%02x for %s"
+                               " reservation\n", cdb[0],
+                               core_scsi3_pr_dump_type(pr_reg_type));
+
+                       return 0;
+               }
 	}
 	pr_debug("%s Conflict for %sregistered nexus %s CDB: 0x%2x"
 		" for %s reservation\n", transport_dump_cmd_direction(cmd),
Signature · 1 line
2.3.4
author
#74 lore raw

PATCH 74/155 power, sched: stop updating inside arch_update_cpu_topology() when nothing to be update

In reply to Jiri Slaby

From: Michael Wang <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 9a0133613e4412b2caaaf0d9dd81f213bcededf1 upstream.

Since v1:
Edited the comment according to Srivatsa's suggestion.

During the testing, we encounter below WARN followed by Oops:

	WARNING: at kernel/sched/core.c:6218
	...
	NIP [c000000000101660] .build_sched_domains+0x11d0/0x1200
	LR [c000000000101358] .build_sched_domains+0xec8/0x1200
	PACATMSCRATCH [800000000000f032]
	Call Trace:
	[c00000001b103850] [c000000000101358] .build_sched_domains+0xec8/0x1200
	[c00000001b1039a0] [c00000000010aad4] .partition_sched_domains+0x484/0x510
	[c00000001b103aa0] [c00000000016d0a8] .rebuild_sched_domains+0x68/0xa0
	[c00000001b103b30] [c00000000005cbf0] .topology_work_fn+0x10/0x30
	...
	Oops: Kernel access of bad area, sig: 11 [#1]
	...
	NIP [c00000000045c000] .__bitmap_weight+0x60/0xf0
	LR [c00000000010132c] .build_sched_domains+0xe9c/0x1200
	PACATMSCRATCH [8000000000029032]
	Call Trace:
	[c00000001b1037a0] [c000000000288ff4] .kmem_cache_alloc_node_trace+0x184/0x3a0
	[c00000001b103850] [c00000000010132c] .build_sched_domains+0xe9c/0x1200
	[c00000001b1039a0] [c00000000010aad4] .partition_sched_domains+0x484/0x510
	[c00000001b103aa0] [c00000000016d0a8] .rebuild_sched_domains+0x68/0xa0
	[c00000001b103b30] [c00000000005cbf0] .topology_work_fn+0x10/0x30
	...

This was caused by that 'sd->groups == NULL' after building groups, which was caused by the empty 'sd->span'.

The cpu's domain contained nothing because the cpu was assigned to a wrong node, due to the following unfortunate sequence of events:

1. The hypervisor sent a topology update to the guest OS, to notify changes to the cpu-node mapping. However, the update was actually redundant - i.e., the "new" mapping was exactly the same as the old one.

2. Due to this, the 'updated_cpus' mask turned out to be empty after exiting the 'for-loop' in arch_update_cpu_topology().

3. So we ended up calling stop-machine() with an empty cpumask list, which made stop-machine internally elect cpumask_first(cpu_online_mask), i.e., CPU0 as the cpu to run the payload (the update_cpu_topology() function).

4. This causes update_cpu_topology() to be run by CPU0. And since 'updates' is kzalloc()'ed inside arch_update_cpu_topology(), update_cpu_topology() finds update->cpu as well as update->new_nid to be 0. In other words, we end up assigning CPU0 (and eventually its siblings) to node 0, incorrectly.

Along with the following wrong updating, it causes the sched-domain rebuild code to break and crash the system.

Fix this by skipping the topology update in cases where we find that the topology has not actually changed in reality (ie., spurious updates).

CC Benjamin Herrenschmidt <[email protected]>
CC Paul Mackerras <[email protected]>
CC Nathan Fontenot <[email protected]>
CC Stephen Rothwell <[email protected]>
CC Andrew Morton <[email protected]>
CC Robert Jennings <[email protected]>
CC Jesse Larrew <[email protected]>
CC "Srivatsa S. Bhat" <[email protected]>
CC Alistair Popple <[email protected]>
---
 arch/powerpc/mm/numa.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
arch/powerpc/mm/numa.c +15 -0
index e91079b796d2..5a5a483d5000 100644
@@ -1569,6 +1569,20 @@ int arch_update_cpu_topology(void)
 		cpu = cpu_last_thread_sibling(cpu);
 	}
 
+	/*
+	 * In cases where we have nothing to update (because the updates list
+	 * is too short or because the new topology is same as the old one),
+	 * skip invoking update_cpu_topology() via stop-machine(). This is
+	 * necessary (and not just a fast-path optimization) since stop-machine
+	 * can end up electing a random CPU to run update_cpu_topology(), and
+	 * thus trick us into setting up incorrect cpu-node mappings (since
+	 * 'updates' is kzalloc()'ed).
+	 *
+	 * And for the similar reason, we will skip all the following updating.
+	 */
+	if (!cpumask_weight(&updated_cpus))
+		goto out;
+
 	stop_machine(update_cpu_topology, &updates[0], &updated_cpus);
 
 	/*
@@ -1590,6 +1604,7 @@ int arch_update_cpu_topology(void)
 		changed = 1;
 	}
 
+out:
 	kfree(updates);
 	return changed;
 }
Signature · 1 line
2.3.4
author
#75 lore raw

PATCH 75/155 Don't leak a key reference if request_key() tries to use a revoked keyring

In reply to Jiri Slaby

From: David Jeffery <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit d0709f1e66e8066c4ac6a54620ec116aa41937c0 upstream.

If a request_key() call to allocate and fill out a key attempts to insert the key structure into a revoked keyring, the key will leak, using memory and part of the user's key quota until the system reboots. This is from a failure of construct_alloc_key() to decrement the key's reference count after the attempt to insert into the requested keyring is rejected.

key_put() needs to be called in the link_prealloc_failed callpath to ensure the unused key is released.

---
 security/keys/request_key.c | 1 +
 1 file changed, 1 insertion(+)
security/keys/request_key.c +1 -0
index c411f9bb156b..5678616cde9d 100644
@@ -432,6 +432,7 @@ link_check_failed:
 
 link_prealloc_failed:
 	mutex_unlock(&user->cons_lock);
+	key_put(key);
 	kleave(" = %d [prelink]", ret);
 	return ret;
 
Signature · 1 line
2.3.4
author
#76 lore raw

PATCH 76/155 ipc/sem.c: fully initialize sem_array before making it visible

In reply to Jiri Slaby

From: Manfred Spraul <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit e8577d1f0329d4842e8302e289fb2c22156abef4 upstream.

ipc_addid() makes a new ipc identifier visible to everyone. New objects start as locked, so that the caller can complete the initialization after the call. Within struct sem_array, at least sma->sem_base and sma->sem_nsems are accessed without any locks, therefore this approach doesn't work.

Thus: Move the ipc_addid() to the end of the initialization.

---
 ipc/sem.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)
ipc/sem.c +8 -7
index 0c312ac04e49..d8456ad6131c 100644
@@ -515,13 +515,6 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params)
 		return retval;
 	}
 
-	id = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni);
-	if (id < 0) {
-		ipc_rcu_putref(sma, sem_rcu_free);
-		return id;
-	}
-	ns->used_sems += nsems;
-
 	sma->sem_base = (struct sem *) &sma[1];
 
 	for (i = 0; i < nsems; i++) {
@@ -536,6 +529,14 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params)
 	INIT_LIST_HEAD(&sma->list_id);
 	sma->sem_nsems = nsems;
 	sma->sem_ctime = get_seconds();
+
+	id = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni);
+	if (id < 0) {
+		ipc_rcu_putref(sma, sem_rcu_free);
+		return id;
+	}
+	ns->used_sems += nsems;
+
 	sem_unlock(sma, -1);
 	rcu_read_unlock();
 
Signature · 1 line
2.3.4
author
#77 lore raw

PATCH 77/155 ipc/shm.c: fix overly aggressive shmdt() when calls span multiple segments

In reply to Jiri Slaby

From: Dave Hansen <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit d3c97900b427b8d5a476fdfe484267f09df418d6 upstream.

This is a highly-contrived scenario. But, a single shmdt() call can be induced in to unmapping memory from mulitple shm segments. Example code is here:

	http://www.sr71.net/~dave/intel/shmfun.c

The fix is pretty simple: Record the 'struct file' for the first VMA we encounter and then stick to it. Decline to unmap anything not from the same file and thus the same segment.

I found this by inspection and the odds of anyone hitting this in practice are pretty darn small.

Lightly tested, but it's a pretty small patch.

---
 ipc/shm.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)
ipc/shm.c +13 -5
index 7a51443a51d6..b039a85e2b8d 100644
@@ -1227,6 +1227,7 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr)
 	int retval = -EINVAL;
 #ifdef CONFIG_MMU
 	loff_t size = 0;
+	struct file *file;
 	struct vm_area_struct *next;
 #endif
 
@@ -1243,7 +1244,8 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr)
 	 *   started at address shmaddr. It records it's size and then unmaps
 	 *   it.
 	 * - Then it unmaps all shm vmas that started at shmaddr and that
-	 *   are within the initially determined size.
+	 *   are within the initially determined size and that are from the
+	 *   same shm segment from which we determined the size.
 	 * Errors from do_munmap are ignored: the function only fails if
 	 * it's called with invalid parameters or if it's called to unmap
 	 * a part of a vma. Both calls in this function are for full vmas,
@@ -1269,8 +1271,14 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr)
 		if ((vma->vm_ops == &shm_vm_ops) &&
 			(vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff) {
 
-
-			size = file_inode(vma->vm_file)->i_size;
+			/*
+			 * Record the file of the shm segment being
+			 * unmapped.  With mremap(), someone could place
+			 * page from another segment but with equal offsets
+			 * in the range we are unmapping.
+			 */
+			file = vma->vm_file;
+			size = file_inode(file)->i_size;
 			do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start);
 			/*
 			 * We discovered the size of the shm segment, so
@@ -1296,8 +1304,8 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr)
 
 		/* finding a matching vma now does not alter retval */
 		if ((vma->vm_ops == &shm_vm_ops) &&
-			(vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff)
-
+		    ((vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff) &&
+		    (vma->vm_file == file))
 			do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start);
 		vma = next;
 	}
Signature · 1 line
2.3.4
author
#78 lore raw

PATCH 78/155 shmdt: use i_size_read() instead of ->i_size

In reply to Jiri Slaby

From: Dave Hansen <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 07a46ed27dc6344de831a450df82336270a157a9 upstream.

Andrew Morton noted

	http://lkml.kernel.org/r/[email protected]

that the shmdt uses inode->i_size outside of i_mutex being held. There is one more case in shm.c in shm_destroy(). This converts both users over to use i_size_read().

---
 ipc/shm.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
ipc/shm.c +3 -2
index b039a85e2b8d..623bc3877118 100644
@@ -218,7 +218,8 @@ static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
 	if (!is_file_hugepages(shm_file))
 		shmem_lock(shm_file, 0, shp->mlock_user);
 	else if (shp->mlock_user)
-		user_shm_unlock(file_inode(shm_file)->i_size, shp->mlock_user);
+		user_shm_unlock(i_size_read(file_inode(shm_file)),
+				shp->mlock_user);
 	fput(shm_file);
 	ipc_rcu_putref(shp, shm_rcu_free);
 }
@@ -1278,7 +1279,7 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr)
 			 * in the range we are unmapping.
 			 */
 			file = vma->vm_file;
-			size = file_inode(file)->i_size;
+			size = i_size_read(file_inode(vma->vm_file));
 			do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start);
 			/*
 			 * We discovered the size of the shm segment, so
Signature · 1 line
2.3.4
author
#79 lore raw

PATCH 79/155 crypto: sha - Handle unaligned input data in generic sha256 and sha512.

In reply to Jiri Slaby

From: "David S. Miller" <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit be34c4ef693ff5c10f55606dbd656ddf0b4a8340 upstream.

Like SHA1, use get_unaligned_be*() on the raw input data.

---
 crypto/sha256_generic.c | 3 ++-
 crypto/sha512_generic.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)
crypto/sha256_generic.c +2 -1
index 136381bdd48d..f85b1340e459 100644
@@ -24,6 +24,7 @@
 #include <linux/types.h>
 #include <crypto/sha.h>
 #include <asm/byteorder.h>
+#include <asm/unaligned.h>
 
 static inline u32 Ch(u32 x, u32 y, u32 z)
 {
@@ -42,7 +43,7 @@ static inline u32 Maj(u32 x, u32 y, u32 z)
 
 static inline void LOAD_OP(int I, u32 *W, const u8 *input)
 {
-	W[I] = __be32_to_cpu( ((__be32*)(input))[I] );
+	W[I] = get_unaligned_be32((__u32 *)input + I);
 }
 
 static inline void BLEND_OP(int I, u32 *W)
crypto/sha512_generic.c +2 -1
index 6c6d901a7cc1..13a23e169a7b 100644
@@ -20,6 +20,7 @@
 #include <crypto/sha.h>
 #include <linux/percpu.h>
 #include <asm/byteorder.h>
+#include <asm/unaligned.h>
 
 static inline u64 Ch(u64 x, u64 y, u64 z)
 {
@@ -68,7 +69,7 @@ static const u64 sha512_K[80] = {
 
 static inline void LOAD_OP(int I, u64 *W, const u8 *input)
 {
-	W[I] = __be64_to_cpu( ((__be64*)(input))[I] );
+	W[I] = get_unaligned_be64((__u64 *)input + I);
 }
 
 static inline void BLEND_OP(int I, u64 *W)
Signature · 1 line
2.3.4
author
#80 lore raw

PATCH 80/155 crypto: testmgr - don't use interruptible wait in tests

In reply to Jiri Slaby

From: Rabin Vincent <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 8a45ac12ec5b6ee67f8559c78ae11d9af8b821ee upstream.

tcrypt/testmgr uses wait_for_completion_interruptible() everywhere when it waits for a request to be completed. If it's interrupted, then the test is aborted and the request is freed.

However, if any of these calls actually do get interrupted, the result will likely be a kernel crash, when the driver handles the now-freed request. Use wait_for_completion() instead.

---
 crypto/tcrypt.c  | 10 ++++------
 crypto/testmgr.c | 48 ++++++++++++++++++++----------------------------
 2 files changed, 24 insertions(+), 34 deletions(-)
crypto/tcrypt.c +4 -6
index 25a5934f0e50..fa9956e79308 100644
@@ -490,10 +490,9 @@ static inline int do_one_ahash_op(struct ahash_request *req, int ret)
 	if (ret == -EINPROGRESS || ret == -EBUSY) {
 		struct tcrypt_result *tr = req->base.data;
 
-		ret = wait_for_completion_interruptible(&tr->completion);
-		if (!ret)
-			ret = tr->err;
+		wait_for_completion(&tr->completion);
 		INIT_COMPLETION(tr->completion);
+		ret = tr->err;
 	}
 	return ret;
 }
@@ -718,10 +717,9 @@ static inline int do_one_acipher_op(struct ablkcipher_request *req, int ret)
 	if (ret == -EINPROGRESS || ret == -EBUSY) {
 		struct tcrypt_result *tr = req->base.data;
 
-		ret = wait_for_completion_interruptible(&tr->completion);
-		if (!ret)
-			ret = tr->err;
+		wait_for_completion(&tr->completion);
 		INIT_COMPLETION(tr->completion);
+		ret = tr->err;
 	}
 
 	return ret;
crypto/testmgr.c +20 -28

90 lines not on this page · raw message

Signature · 1 line
2.3.4
author
#81 lore raw

PATCH 81/155 NFS: Add attribute update barriers to nfs_setattr_update_inode()

In reply to Jiri Slaby

From: Trond Myklebust <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit f044636d972246d451e06226cc1675d5da389762 upstream.

Ensure that other operations which raced with our setattr RPC call cannot revert the file attribute changes that were made on the server. To do so, we artificially bump the attribute generation counter on the inode so that all calls to nfs_fattr_init() that precede ours will be dropped.

The motivation for the patch came from Chuck Lever's reports of readaheads racing with truncate operations and causing the file size to be reverted.

---
 fs/nfs/inode.c         | 17 ++++++++++++-----
 fs/nfs/nfs3proc.c      |  2 +-
 fs/nfs/nfs4proc.c      |  6 +++---
 fs/nfs/proc.c          |  2 +-
 include/linux/nfs_fs.h |  2 +-
 5 files changed, 18 insertions(+), 11 deletions(-)
fs/nfs/inode.c +12 -5
index e5eb677ca9ce..127a6d9d81b7 100644
@@ -545,6 +545,7 @@ EXPORT_SYMBOL_GPL(nfs_setattr);
  * This is a copy of the common vmtruncate, but with the locking
  * corrected to take into account the fact that NFS requires
  * inode->i_size to be updated under the inode->i_lock.
+ * Note: must be called with inode->i_lock held!
  */
 static int nfs_vmtruncate(struct inode * inode, loff_t offset)
 {
@@ -554,11 +555,11 @@ static int nfs_vmtruncate(struct inode * inode, loff_t offset)
 	if (err)
 		goto out;
 
-	spin_lock(&inode->i_lock);
 	i_size_write(inode, offset);
-	spin_unlock(&inode->i_lock);
 
+	spin_unlock(&inode->i_lock);
 	truncate_pagecache(inode, offset);
+	spin_lock(&inode->i_lock);
 out:
 	return err;
 }
@@ -571,10 +572,15 @@ out:
  * Note: we do this in the *proc.c in order to ensure that
  *       it works for things like exclusive creates too.
  */
-void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
+void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr,
+		struct nfs_fattr *fattr)
 {
+	/* Barrier: bump the attribute generation count. */
+	fattr->gencount = nfs_inc_attr_generation_counter();
+
+	spin_lock(&inode->i_lock);
+	NFS_I(inode)->attr_gencount = fattr->gencount;
 	if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) {
-		spin_lock(&inode->i_lock);
 		if ((attr->ia_valid & ATTR_MODE) != 0) {
 			int mode = attr->ia_mode & S_IALLUGO;
 			mode |= inode->i_mode & ~S_IALLUGO;
@@ -585,12 +591,13 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
 		if ((attr->ia_valid & ATTR_GID) != 0)
 			inode->i_gid = attr->ia_gid;
 		NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
-		spin_unlock(&inode->i_lock);
 	}
 	if ((attr->ia_valid & ATTR_SIZE) != 0) {
 		nfs_inc_stats(inode, NFSIOS_SETATTRTRUNC);
 		nfs_vmtruncate(inode, attr->ia_size);
 	}
+	nfs_update_inode(inode, fattr);
+	spin_unlock(&inode->i_lock);
 }
 EXPORT_SYMBOL_GPL(nfs_setattr_update_inode);
 
fs/nfs/nfs3proc.c +1 -1
index 90cb10d7b693..8ef5276776f9 100644
@@ -136,7 +136,7 @@ nfs3_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
 	nfs_fattr_init(fattr);
 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
 	if (status == 0)
-		nfs_setattr_update_inode(inode, sattr);
+		nfs_setattr_update_inode(inode, sattr, fattr);
 	dprintk("NFS reply setattr: %d\n", status);
 	return status;
 }
fs/nfs/nfs4proc.c +3 -3
index 43c27110387a..36a72b59d7c8 100644
@@ -2276,8 +2276,8 @@ static int _nfs4_do_open(struct inode *dir,
 				opendata->o_res.f_attr, sattr,
 				state, label, olabel);
 		if (status == 0) {
-			nfs_setattr_update_inode(state->inode, sattr);
-			nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr);
+			nfs_setattr_update_inode(state->inode, sattr,
+					opendata->o_res.f_attr);
 			nfs_setsecurity(state->inode, opendata->o_res.f_attr, olabel);
 		}
 	}
@@ -3114,7 +3114,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
 
 	status = nfs4_do_setattr(inode, cred, fattr, sattr, state, NULL, label);
 	if (status == 0) {
-		nfs_setattr_update_inode(inode, sattr);
+		nfs_setattr_update_inode(inode, sattr, fattr);
 		nfs_setsecurity(inode, fattr, label);
 	}
 	nfs4_label_free(label);
fs/nfs/proc.c +1 -1
index a8f57c728df5..7ffaeffc1330 100644
@@ -139,7 +139,7 @@ nfs_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
 	nfs_fattr_init(fattr);
 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
 	if (status == 0)
-		nfs_setattr_update_inode(inode, sattr);
+		nfs_setattr_update_inode(inode, sattr, fattr);
 	dprintk("NFS reply setattr: %d\n", status);
 	return status;
 }
include/linux/nfs_fs.h +1 -1
index a632498d42fa..f4bf1b593327 100644
@@ -354,7 +354,7 @@ extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode);
 extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *);
 extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping);
 extern int nfs_setattr(struct dentry *, struct iattr *);
-extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr);
+extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, struct nfs_fattr *);
 extern void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
 				struct nfs4_label *label);
 extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx);
Signature · 1 line
2.3.4
author
#82 lore raw

PATCH 82/155 ntp: Fixup adjtimex freq validation on 32-bit systems

In reply to Jiri Slaby

From: John Stultz <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 29183a70b0b828500816bd794b3fe192fce89f73 upstream.

Additional validation of adjtimex freq values to avoid potential multiplication overflows were added in commit 5e5aeb4367b (time: adjtimex: Validate the ADJ_FREQUENCY values)

Unfortunately the patch used LONG_MAX/MIN instead of LLONG_MAX/MIN, which was fine on 64-bit systems, but being much smaller on 32-bit systems caused false positives resulting in most direct frequency adjustments to fail w/ EINVAL.

ntpd only does direct frequency adjustments at startup, so the issue was not as easily observed there, but other time sync applications like ptpd and chrony were more effected by the bug.

See bugs:

https://bugzilla.kernel.org/show_bug.cgi?id=92481
https://bugzilla.redhat.com/show_bug.cgi?id=1188074

This patch changes the checks to use LLONG_MAX for clarity, and additionally the checks are disabled on 32-bit systems since LLONG_MAX/PPM_SCALE is always larger then the 32-bit long freq value, so multiplication overflows aren't possible there.

---
 kernel/time/ntp.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
kernel/time/ntp.c +7 -3
index 28db9bedc857..6211d5d6d465 100644
@@ -631,10 +631,14 @@ int ntp_validate_timex(struct timex *txc)
 	if ((txc->modes & ADJ_SETOFFSET) && (!capable(CAP_SYS_TIME)))
 		return -EPERM;
 
-	if (txc->modes & ADJ_FREQUENCY) {
-		if (LONG_MIN / PPM_SCALE > txc->freq)
+	/*
+	 * Check for potential multiplication overflows that can
+	 * only happen on 64-bit systems:
+	 */
+	if ((txc->modes & ADJ_FREQUENCY) && (BITS_PER_LONG == 64)) {
+		if (LLONG_MIN / PPM_SCALE > txc->freq)
 			return -EINVAL;
-		if (LONG_MAX / PPM_SCALE < txc->freq)
+		if (LLONG_MAX / PPM_SCALE < txc->freq)
 			return -EINVAL;
 	}
 
Signature · 1 line
2.3.4
author
#83 lore raw

PATCH 83/155 hung_task: check the value of "sysctl_hung_task_timeout_sec"

In reply to Jiri Slaby

From: Liu Hua <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 80df28476505ed4e6701c3448c63c9229a50c655 upstream.

As sysctl_hung_task_timeout_sec is unsigned long, when this value is larger then LONG_MAX/HZ, the function schedule_timeout_interruptible in watchdog will return immediately without sleep and with print :

schedule_timeout: wrong timeout value ffffffffffffff83

and then the funtion watchdog will call schedule_timeout_interruptible again and again. The screen will be filled with

"schedule_timeout: wrong timeout value ffffffffffffff83"

This patch does some check and correction in sysctl, to let the function schedule_timeout_interruptible allways get the valid parameter.

---
 kernel/sysctl.c | 6 ++++++
 1 file changed, 6 insertions(+)
kernel/sysctl.c +6 -0
index 167741003616..6a9b0c42fb30 100644
@@ -142,6 +142,11 @@ static int minolduid;
 static int ngroups_max = NGROUPS_MAX;
 static const int cap_last_cap = CAP_LAST_CAP;
 
+/*this is needed for proc_doulongvec_minmax of sysctl_hung_task_timeout_secs */
+#ifdef CONFIG_DETECT_HUNG_TASK
+static unsigned long hung_task_timeout_max = (LONG_MAX/HZ);
+#endif
+
 #ifdef CONFIG_INOTIFY_USER
 #include <linux/inotify.h>
 #endif
@@ -971,6 +976,7 @@ static struct ctl_table kern_table[] = {
 		.maxlen		= sizeof(unsigned long),
 		.mode		= 0644,
 		.proc_handler	= proc_dohung_task_timeout_secs,
+		.extra2		= &hung_task_timeout_max,
 	},
 	{
 		.procname	= "hung_task_warnings",
Signature · 1 line
2.3.4
author
#84 lore raw

PATCH 84/155 topology: Fix compilation warning when not in SMP

In reply to Jiri Slaby

From: Vincent Stehlé <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 53974e06603977f348ed978d75c426b0532daa67 upstream.

The topology_##name() macro does not use its argument when CONFIG_SMP is not set, as it ultimately calls the cpu_data() macro.

So we avoid maintaining a possibly unused `cpu' variable, to avoid the following compilation warning:

drivers/base/topology.c: In function ‘show_physical_package_id’:
drivers/base/topology.c:103:118: warning: unused variable ‘cpu’ [-Wunused-variable]
define_id_show_func(physical_package_id);

drivers/base/topology.c: In function ‘show_core_id’:
drivers/base/topology.c:106:106: warning: unused variable ‘cpu’ [-Wunused-variable]
define_id_show_func(core_id);

This can be seen with e.g. x86 defconfig and CONFIG_SMP not set.

---
 drivers/base/topology.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/base/topology.c +1 -2
index 94ffee378f10..37a5661ca5f9 100644
@@ -40,8 +40,7 @@
 static ssize_t show_##name(struct device *dev,			\
 		struct device_attribute *attr, char *buf)	\
 {								\
-	unsigned int cpu = dev->id;				\
-	return sprintf(buf, "%d\n", topology_##name(cpu));	\
+	return sprintf(buf, "%d\n", topology_##name(dev->id));	\
 }
 
 #if defined(topology_thread_cpumask) || defined(topology_core_cpumask) || \
Signature · 1 line
2.3.4
author
#85 lore raw

PATCH 85/155 xen-blkfront: revoke foreign access for grants not mapped by the backend

In reply to Jiri Slaby

From: Roger Pau Monne <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit fbe363c476afe8ec992d3baf682670a4bd1b6ce6 upstream.

There's no need to keep the foreign access in a grant if it is not persistently mapped by the backend. This allows us to free grants that are not mapped by the backend, thus preventing blkfront from hoarding all grants.

The main effect of this is that blkfront will only persistently map the same grants as the backend, and it will always try to use grants that are already mapped by the backend. Also the number of persistent grants in blkfront is the same as in blkback (and is controlled by the value in blkback).

---
 drivers/block/xen-blkfront.c | 33 +++++++++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 4 deletions(-)
drivers/block/xen-blkfront.c +29 -4
index e85bc358e052..7b0500b020e8 100644
@@ -1013,13 +1013,38 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
 	}
 	/* Add the persistent grant into the list of free grants */
 	for (i = 0; i < nseg; i++) {
-		list_add(&s->grants_used[i]->node, &info->persistent_gnts);
-		info->persistent_gnts_c++;
+		if (gnttab_query_foreign_access(s->grants_used[i]->gref)) {
+			/*
+			 * If the grant is still mapped by the backend (the
+			 * backend has chosen to make this grant persistent)
+			 * we add it at the head of the list, so it will be
+			 * reused first.
+			 */
+			list_add(&s->grants_used[i]->node, &info->persistent_gnts);
+			info->persistent_gnts_c++;
+		} else {
+			/*
+			 * If the grant is not mapped by the backend we end the
+			 * foreign access and add it to the tail of the list,
+			 * so it will not be picked again unless we run out of
+			 * persistent grants.
+			 */
+			gnttab_end_foreign_access(s->grants_used[i]->gref, 0, 0UL);
+			s->grants_used[i]->gref = GRANT_INVALID_REF;
+			list_add_tail(&s->grants_used[i]->node, &info->persistent_gnts);
+		}
 	}
 	if (s->req.operation == BLKIF_OP_INDIRECT) {
 		for (i = 0; i < INDIRECT_GREFS(nseg); i++) {
-			list_add(&s->indirect_grants[i]->node, &info->persistent_gnts);
-			info->persistent_gnts_c++;
+			if (gnttab_query_foreign_access(s->indirect_grants[i]->gref)) {
+				list_add(&s->indirect_grants[i]->node, &info->persistent_gnts);
+				info->persistent_gnts_c++;
+			} else {
+				gnttab_end_foreign_access(s->indirect_grants[i]->gref, 0, 0UL);
+				s->indirect_grants[i]->gref = GRANT_INVALID_REF;
+				list_add_tail(&s->indirect_grants[i]->node,
+				              &info->persistent_gnts);
+			}
 		}
 	}
 }
Signature · 1 line
2.3.4
author
#86 lore raw

PATCH 86/155 xen-blkfront: restore the non-persistent data path

In reply to Jiri Slaby

From: Roger Pau Monne <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit bfe11d6de1c416cea4f3f0f35f864162063ce3fa upstream.

When persistent grants were added they were always used, even if the backend doesn't have this feature (there's no harm in always using the same set of pages). This restores the old data path when the backend doesn't have persistent grants, removing the burden of doing a memcpy when it is not actually needed.

Cc Felipe Franciosi <[email protected]>
Cc Konrad Rzeszutek Wilk <[email protected]>
Cc David Vrabel <[email protected]>
[v2: Fix up whitespace issues]
---
 drivers/block/xen-blkfront.c | 125 ++++++++++++++++++++++++++++++++++---------
 1 file changed, 100 insertions(+), 25 deletions(-)
drivers/block/xen-blkfront.c +100 -25
index 7b0500b020e8..3bb5efdcdc8a 100644
@@ -121,7 +121,8 @@ struct blkfront_info
 	struct work_struct work;
 	struct gnttab_free_callback callback;
 	struct blk_shadow shadow[BLK_RING_SIZE];
-	struct list_head persistent_gnts;
+	struct list_head grants;
+	struct list_head indirect_pages;
 	unsigned int persistent_gnts_c;
 	unsigned long shadow_free;
 	unsigned int feature_flush;
@@ -200,15 +201,17 @@ static int fill_grant_buffer(struct blkfront_info *info, int num)
 		if (!gnt_list_entry)
 			goto out_of_memory;
 
-		granted_page = alloc_page(GFP_NOIO);
-		if (!granted_page) {
-			kfree(gnt_list_entry);
-			goto out_of_memory;
+		if (info->feature_persistent) {
+			granted_page = alloc_page(GFP_NOIO);
+			if (!granted_page) {
+				kfree(gnt_list_entry);
+				goto out_of_memory;
+			}
+			gnt_list_entry->pfn = page_to_pfn(granted_page);
 		}
 
-		gnt_list_entry->pfn = page_to_pfn(granted_page);
 		gnt_list_entry->gref = GRANT_INVALID_REF;
-		list_add(&gnt_list_entry->node, &info->persistent_gnts);
+		list_add(&gnt_list_entry->node, &info->grants);
 		i++;
 	}
 
@@ -216,9 +219,10 @@ static int fill_grant_buffer(struct blkfront_info *info, int num)
 
 out_of_memory:
 	list_for_each_entry_safe(gnt_list_entry, n,
-	                         &info->persistent_gnts, node) {
+	                         &info->grants, node) {
 		list_del(&gnt_list_entry->node);
-		__free_page(pfn_to_page(gnt_list_entry->pfn));
+		if (info->feature_persistent)
+			__free_page(pfn_to_page(gnt_list_entry->pfn));
 		kfree(gnt_list_entry);
 		i--;
 	}
@@ -227,13 +231,14 @@ out_of_memory:
 }
 
 static struct grant *get_grant(grant_ref_t *gref_head,
+                               unsigned long pfn,
                                struct blkfront_info *info)
 {
 	struct grant *gnt_list_entry;
 	unsigned long buffer_mfn;
 
-	BUG_ON(list_empty(&info->persistent_gnts));
-	gnt_list_entry = list_first_entry(&info->persistent_gnts, struct grant,
+	BUG_ON(list_empty(&info->grants));
+	gnt_list_entry = list_first_entry(&info->grants, struct grant,
 	                                  node);
 	list_del(&gnt_list_entry->node);
 
@@ -245,6 +250,10 @@ static struct grant *get_grant(grant_ref_t *gref_head,
 	/* Assign a gref to this page */
 	gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head);
 	BUG_ON(gnt_list_entry->gref == -ENOSPC);
+	if (!info->feature_persistent) {
+		BUG_ON(!pfn);
+		gnt_list_entry->pfn = pfn;
+	}
 	buffer_mfn = pfn_to_mfn(gnt_list_entry->pfn);
 	gnttab_grant_foreign_access_ref(gnt_list_entry->gref,
 	                                info->xbdev->otherend_id,
@@ -477,22 +486,34 @@ static int blkif_queue_request(struct request *req)
 
 			if ((ring_req->operation == BLKIF_OP_INDIRECT) &&
 			    (i % SEGS_PER_INDIRECT_FRAME == 0)) {
+				unsigned long pfn;
+
 				if (segments)
 					kunmap_atomic(segments);
 
 				n = i / SEGS_PER_INDIRECT_FRAME;
-				gnt_list_entry = get_grant(&gref_head, info);
+				if (!info->feature_persistent) {
+					struct page *indirect_page;
+
+					/* Fetch a pre-allocated page to use for indirect grefs */
+					BUG_ON(list_empty(&info->indirect_pages));
+					indirect_page = list_first_entry(&info->indirect_pages,
+					                                 struct page, lru);
+					list_del(&indirect_page->lru);
+					pfn = page_to_pfn(indirect_page);
+				}
+				gnt_list_entry = get_grant(&gref_head, pfn, info);
 				info->shadow[id].indirect_grants[n] = gnt_list_entry;
 				segments = kmap_atomic(pfn_to_page(gnt_list_entry->pfn));
 				ring_req->u.indirect.indirect_grefs[n] = gnt_list_entry->gref;
 			}
 
-			gnt_list_entry = get_grant(&gref_head, info);
+			gnt_list_entry = get_grant(&gref_head, page_to_pfn(sg_page(sg)), info);
 			ref = gnt_list_entry->gref;
 
 			info->shadow[id].grants_used[i] = gnt_list_entry;
 
-			if (rq_data_dir(req)) {
+			if (rq_data_dir(req) && info->feature_persistent) {
 				char *bvec_data;
 				void *shared_data;
 
@@ -904,21 +925,36 @@ static void blkif_free(struct blkfront_info *info, int suspend)
 		blk_stop_queue(info->rq);
 
 	/* Remove all persistent grants */
-	if (!list_empty(&info->persistent_gnts)) {
+	if (!list_empty(&info->grants)) {
 		list_for_each_entry_safe(persistent_gnt, n,
-		                         &info->persistent_gnts, node) {
+		                         &info->grants, node) {
 			list_del(&persistent_gnt->node);
 			if (persistent_gnt->gref != GRANT_INVALID_REF) {
 				gnttab_end_foreign_access(persistent_gnt->gref,
 				                          0, 0UL);
 				info->persistent_gnts_c--;
 			}
-			__free_page(pfn_to_page(persistent_gnt->pfn));
+			if (info->feature_persistent)
+				__free_page(pfn_to_page(persistent_gnt->pfn));
 			kfree(persistent_gnt);
 		}
 	}
 	BUG_ON(info->persistent_gnts_c != 0);
 
+	/*
+	 * Remove indirect pages, this only happens when using indirect
+	 * descriptors but not persistent grants
+	 */
+	if (!list_empty(&info->indirect_pages)) {
+		struct page *indirect_page, *n;
+
+		BUG_ON(info->feature_persistent);
+		list_for_each_entry_safe(indirect_page, n, &info->indirect_pages, lru) {
+			list_del(&indirect_page->lru);
+			__free_page(indirect_page);
+		}
+	}
+
 	for (i = 0; i < BLK_RING_SIZE; i++) {
 		/*
 		 * Clear persistent grants present in requests already
@@ -933,7 +969,8 @@ static void blkif_free(struct blkfront_info *info, int suspend)
 		for (j = 0; j < segs; j++) {
 			persistent_gnt = info->shadow[i].grants_used[j];
 			gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL);
-			__free_page(pfn_to_page(persistent_gnt->pfn));
+			if (info->feature_persistent)
+				__free_page(pfn_to_page(persistent_gnt->pfn));
 			kfree(persistent_gnt);
 		}
 
@@ -992,7 +1029,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
 	nseg = s->req.operation == BLKIF_OP_INDIRECT ?
 		s->req.u.indirect.nr_segments : s->req.u.rw.nr_segments;
 
-	if (bret->operation == BLKIF_OP_READ) {
+	if (bret->operation == BLKIF_OP_READ && info->feature_persistent) {
 		/*
 		 * Copy the data received from the backend into the bvec.
 		 * Since bv_offset can be different than 0, and bv_len different
@@ -1020,7 +1057,10 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
 			 * we add it at the head of the list, so it will be
 			 * reused first.
 			 */
-			list_add(&s->grants_used[i]->node, &info->persistent_gnts);
+			if (!info->feature_persistent)
+				pr_alert_ratelimited("backed has not unmapped grant: %u\n",
+						     s->grants_used[i]->gref);
+			list_add(&s->grants_used[i]->node, &info->grants);
 			info->persistent_gnts_c++;
 		} else {
 			/*
@@ -1031,19 +1071,29 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
 			 */
 			gnttab_end_foreign_access(s->grants_used[i]->gref, 0, 0UL);
 			s->grants_used[i]->gref = GRANT_INVALID_REF;
-			list_add_tail(&s->grants_used[i]->node, &info->persistent_gnts);
+			list_add_tail(&s->grants_used[i]->node, &info->grants);
 		}
 	}
 	if (s->req.operation == BLKIF_OP_INDIRECT) {
 		for (i = 0; i < INDIRECT_GREFS(nseg); i++) {
 			if (gnttab_query_foreign_access(s->indirect_grants[i]->gref)) {
-				list_add(&s->indirect_grants[i]->node, &info->persistent_gnts);
+				if (!info->feature_persistent)
+					pr_alert_ratelimited("backed has not unmapped grant: %u\n",
+							     s->indirect_grants[i]->gref);
+				list_add(&s->indirect_grants[i]->node, &info->grants);
 				info->persistent_gnts_c++;
 			} else {
+				struct page *indirect_page;
+
 				gnttab_end_foreign_access(s->indirect_grants[i]->gref, 0, 0UL);
+				/*
+				 * Add the used indirect page back to the list of
+				 * available pages for indirect grefs.
+				 */
+				indirect_page = pfn_to_page(s->indirect_grants[i]->pfn);
+				list_add(&indirect_page->lru, &info->indirect_pages);
 				s->indirect_grants[i]->gref = GRANT_INVALID_REF;
-				list_add_tail(&s->indirect_grants[i]->node,
-				              &info->persistent_gnts);
+				list_add_tail(&s->indirect_grants[i]->node, &info->grants);
 			}
 		}
 	}
@@ -1338,7 +1388,8 @@ static int blkfront_probe(struct xenbus_device *dev,
 	spin_lock_init(&info->io_lock);
 	info->xbdev = dev;
 	info->vdevice = vdevice;
-	INIT_LIST_HEAD(&info->persistent_gnts);
+	INIT_LIST_HEAD(&info->grants);
+	INIT_LIST_HEAD(&info->indirect_pages);
 	info->persistent_gnts_c = 0;
 	info->connected = BLKIF_STATE_DISCONNECTED;
 	INIT_WORK(&info->work, blkif_restart_queue);
@@ -1685,6 +1736,23 @@ static int blkfront_setup_indirect(struct blkfront_info *info)
 	if (err)
 		goto out_of_memory;
 
+	if (!info->feature_persistent && info->max_indirect_segments) {
+		/*
+		 * We are using indirect descriptors but not persistent
+		 * grants, we need to allocate a set of pages that can be
+		 * used for mapping indirect grefs
+		 */
+		int num = INDIRECT_GREFS(segs) * BLK_RING_SIZE;
+
+		BUG_ON(!list_empty(&info->indirect_pages));
+		for (i = 0; i < num; i++) {
+			struct page *indirect_page = alloc_page(GFP_NOIO);
+			if (!indirect_page)
+				goto out_of_memory;
+			list_add(&indirect_page->lru, &info->indirect_pages);
+		}
+	}
+
 	for (i = 0; i < BLK_RING_SIZE; i++) {
 		info->shadow[i].grants_used = kzalloc(
 			sizeof(info->shadow[i].grants_used[0]) * segs,
@@ -1715,6 +1783,13 @@ out_of_memory:
 		kfree(info->shadow[i].indirect_grants);
 		info->shadow[i].indirect_grants = NULL;
 	}
+	if (!list_empty(&info->indirect_pages)) {
+		struct page *indirect_page, *n;
+		list_for_each_entry_safe(indirect_page, n, &info->indirect_pages, lru) {
+			list_del(&indirect_page->lru);
+			__free_page(indirect_page);
+		}
+	}
 	return -ENOMEM;
 }
 
Signature · 1 line
2.3.4
author
#87 lore raw

PATCH 87/155 crypto: s390 - fix aes,des ctr mode concurrency finding.

In reply to Jiri Slaby

From: Harald Freudenberger <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 3901c1124ec5099254a9396085f7798153a7293f upstream.

An additional testcase found an issue with the last series of patches applied: the fallback solution may not save the iv value after operation. This very small fix just makes sure the iv is copied back to the walk/desc struct.

---
 arch/s390/crypto/aes_s390.c | 3 +++
 arch/s390/crypto/des_s390.c | 3 +++
 2 files changed, 6 insertions(+)
arch/s390/crypto/aes_s390.c +3 -0
index f8d9cb14adce..92eb4d6ad39d 100644
@@ -818,6 +818,9 @@ static int ctr_aes_crypt(struct blkcipher_desc *desc, long func,
 		else
 			memcpy(walk->iv, ctrptr, AES_BLOCK_SIZE);
 		spin_unlock(&ctrblk_lock);
+	} else {
+		if (!nbytes)
+			memcpy(walk->iv, ctrptr, AES_BLOCK_SIZE);
 	}
 	/*
 	 * final block may be < AES_BLOCK_SIZE, copy only nbytes
arch/s390/crypto/des_s390.c +3 -0
index a3e24d4d2530..a89feffb22b5 100644
@@ -429,6 +429,9 @@ static int ctr_desall_crypt(struct blkcipher_desc *desc, long func,
 		else
 			memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE);
 		spin_unlock(&ctrblk_lock);
+	} else {
+		if (!nbytes)
+			memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE);
 	}
 	/* final block may be < DES_BLOCK_SIZE, copy only nbytes */
 	if (nbytes) {
Signature · 1 line
2.3.4
author
#88 lore raw

PATCH 88/155 ARM: OMAP4: Fix the boot regression with CPU_IDLE enabled

In reply to Jiri Slaby

From: Santosh Shilimkar <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 4b353a706a86598ba47307c47301c3c428b79e09 upstream.

On OMAP4 panda board, there have been several bug reports about boot hang and lock-ups with CPU_IDLE enabled. The root cause of the issue is missing interrupts while in idle state. Commit cb7094e8 {cpuidle / omap4 :
use CPUIDLE_FLAG_TIMER_STOP flag} moved the broadcast notifiers to common code for right reasons but on OMAP4 which suffers from a nasty ROM code bug with GIC, commit ff999b8a {ARM: OMAP4460: Workaround for ROM bug ..}, we loose interrupts which leads to issues like lock-up, hangs etc.

Patch reverts commit cb7094 {cpuidle / omap4 : use CPUIDLE_FLAG_TIMER_STOP flag} and 54769d6 {cpuidle: OMAP4: remove timer broadcast initialization} to avoid the issue. With this change, OMAP4 panda boards, the mentioned issues are getting fixed. We no longer loose interrupts which was the cause of the regression.

Fixes cb7094e8 (cpuidle / omap4 : use CPUIDLE_FLAG_TIMER_STOP flag)
Fixes ff999b8a (cpuidle: OMAP4: remove timer broadcast initialization)
Cc Roger Quadros <[email protected]>
Cc Kevin Hilman <[email protected]>
Cc Tony Lindgren <[email protected]>
Cc Daniel Lezcano <[email protected]>
---
 arch/arm/mach-omap2/cpuidle44xx.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)
arch/arm/mach-omap2/cpuidle44xx.c +21 -4
index 4c8982ae9529..d159ec39cd3e 100644
@@ -14,6 +14,7 @@
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
 #include <linux/export.h>
+#include <linux/clockchips.h>
 
 #include <asm/cpuidle.h>
 #include <asm/proc-fns.h>
@@ -80,6 +81,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
 			int index)
 {
 	struct idle_statedata *cx = state_ptr + index;
+	int cpu_id = smp_processor_id();
 
 	/*
 	 * CPU0 has to wait and stay ON until CPU1 is OFF state.
@@ -104,6 +106,8 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
 		}
 	}
 
+	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id);
+
 	/*
 	 * Call idle CPU PM enter notifier chain so that
 	 * VFP and per CPU interrupt context is saved.
@@ -147,6 +151,8 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
 		(cx->mpu_logic_state == PWRDM_POWER_OFF))
 		cpu_cluster_pm_exit();
 
+	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
+
 fail:
 	cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
 	cpu_done[dev->cpu] = false;
@@ -154,6 +160,16 @@ fail:
 	return index;
 }
 
+/*
+ * For each cpu, setup the broadcast timer because local timers
+ * stops for the states above C1.
+ */
+static void omap_setup_broadcast_timer(void *arg)
+{
+	int cpu = smp_processor_id();
+	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
+}
+
 static struct cpuidle_driver omap4_idle_driver = {
 	.name				= "omap4_idle",
 	.owner				= THIS_MODULE,
@@ -171,8 +187,7 @@ static struct cpuidle_driver omap4_idle_driver = {
 			/* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */
 			.exit_latency = 328 + 440,
 			.target_residency = 960,
-			.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED |
-			         CPUIDLE_FLAG_TIMER_STOP,
+			.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED,
 			.enter = omap_enter_idle_coupled,
 			.name = "C2",
 			.desc = "CPUx OFF, MPUSS CSWR",
@@ -181,8 +196,7 @@ static struct cpuidle_driver omap4_idle_driver = {
 			/* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
 			.exit_latency = 460 + 518,
 			.target_residency = 1100,
-			.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED |
-			         CPUIDLE_FLAG_TIMER_STOP,
+			.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED,
 			.enter = omap_enter_idle_coupled,
 			.name = "C3",
 			.desc = "CPUx OFF, MPUSS OSWR",
@@ -213,5 +227,8 @@ int __init omap4_idle_init(void)
 	if (!cpu_clkdm[0] || !cpu_clkdm[1])
 		return -ENODEV;
 
+	/* Configure the broadcast timer on each cpu */
+	on_each_cpu(omap_setup_broadcast_timer, NULL, 1);
+
 	return cpuidle_register(&omap4_idle_driver, cpu_online_mask);
 }
Signature · 1 line
2.3.4
author
#89 lore raw

PATCH 89/155 iscsi-target: Fix wrong buffer / buffer overrun in iscsi_change_param_value()

In reply to Jiri Slaby

From: Roland Dreier <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 79d59d08082dd0a0a18f8ceb78c99f9f321d72aa upstream.

In non-leading connection login, iscsi_login_non_zero_tsih_s1() calls iscsi_change_param_value() with the buffer it uses to hold the login PDU, not a temporary buffer. This leads to the login header getting corrupted and login failing for non-leading connections in MC/S.

Fix this by adding a wrapper iscsi_change_param_sprintf() that handles the temporary buffer itself to avoid confusion. Also handle sending a reject in case of failure in the wrapper, which lets the calling code get quite a bit smaller and easier to read.

Finally, bump the size of the temporary buffer from 32 to 64 bytes to be safe, since "MaxRecvDataSegmentLength=" by itself is 25 bytes; with a trailing NUL, a value >= 1M will lead to a buffer overrun. (This isn't the default but we don't need to run right at the ragged edge here)

(Fix up context changes for v3.10.y - nab)

---
 drivers/target/iscsi/iscsi_target_login.c | 50 +++++++++++++++++--------------
 1 file changed, 27 insertions(+), 23 deletions(-)
drivers/target/iscsi/iscsi_target_login.c +27 -23
index 0c15772c5035..805c35aafe61 100644
@@ -249,6 +249,28 @@ static void iscsi_login_set_conn_values(
 	mutex_unlock(&auth_id_lock);
 }
 
+static __printf(2, 3) int iscsi_change_param_sprintf(
+	struct iscsi_conn *conn,
+	const char *fmt, ...)
+{
+	va_list args;
+	unsigned char buf[64];
+
+	memset(buf, 0, sizeof buf);
+
+	va_start(args, fmt);
+	vsnprintf(buf, sizeof buf, fmt, args);
+	va_end(args);
+
+	if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
+		iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+				ISCSI_LOGIN_STATUS_NO_RESOURCES);
+		return -1;
+	}
+
+	return 0;
+}
+
 /*
  *	This is the leading connection of a new session,
  *	or session reinstatement.
@@ -338,7 +360,6 @@ static int iscsi_login_zero_tsih_s2(
 {
 	struct iscsi_node_attrib *na;
 	struct iscsi_session *sess = conn->sess;
-	unsigned char buf[32];
 	bool iser = false;
 
 	sess->tpg = conn->tpg;
@@ -379,26 +400,16 @@ static int iscsi_login_zero_tsih_s2(
 	 *
 	 * In our case, we have already located the struct iscsi_tiqn at this point.
 	 */
-	memset(buf, 0, 32);
-	sprintf(buf, "TargetPortalGroupTag=%hu", ISCSI_TPG_S(sess)->tpgt);
-	if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
-		iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
-				ISCSI_LOGIN_STATUS_NO_RESOURCES);
+	if (iscsi_change_param_sprintf(conn, "TargetPortalGroupTag=%hu", sess->tpg->tpgt))
 		return -1;
-	}
 
 	/*
 	 * Workaround for Initiators that have broken connection recovery logic.
 	 *
 	 * "We would really like to get rid of this." Linux-iSCSI.org team
 	 */
-	memset(buf, 0, 32);
-	sprintf(buf, "ErrorRecoveryLevel=%d", na->default_erl);
-	if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
-		iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
-				ISCSI_LOGIN_STATUS_NO_RESOURCES);
+	if (iscsi_change_param_sprintf(conn, "ErrorRecoveryLevel=%d", na->default_erl))
 		return -1;
-	}
 
 	if (iscsi_login_disable_FIM_keys(conn->param_list, conn) < 0)
 		return -1;
@@ -410,12 +421,9 @@ static int iscsi_login_zero_tsih_s2(
 		unsigned long mrdsl, off;
 		int rc;
 
-		sprintf(buf, "RDMAExtensions=Yes");
-		if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
-			iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
-				ISCSI_LOGIN_STATUS_NO_RESOURCES);
+		if (iscsi_change_param_sprintf(conn, "RDMAExtensions=Yes"))
 			return -1;
-		}
+
 		/*
 		 * Make MaxRecvDataSegmentLength PAGE_SIZE aligned for
 		 * Immediate Data + Unsolicitied Data-OUT if necessary..
@@ -445,12 +453,8 @@ static int iscsi_login_zero_tsih_s2(
 		pr_warn("Aligning ISER MaxRecvDataSegmentLength: %lu down"
 			" to PAGE_SIZE\n", mrdsl);
 
-		sprintf(buf, "MaxRecvDataSegmentLength=%lu\n", mrdsl);
-		if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
-			iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
-				ISCSI_LOGIN_STATUS_NO_RESOURCES);
+		if (iscsi_change_param_sprintf(conn, "MaxRecvDataSegmentLength=%lu\n", mrdsl))
 			return -1;
-		}
 	}
 
 	return 0;
Signature · 1 line
2.3.4
author
#90 lore raw

PATCH 90/155 megaraid: Use resource_size_t for PCI resources, not long

In reply to Jiri Slaby

From: Ben Collins <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 11f8a7b31f2140b0dc164bb484281235ffbe51d3 upstream.

The assumption that sizeof(long) >= sizeof(resource_size_t) can lead to truncation of the PCI resource address, meaning this driver didn't work on 32-bit systems with 64-bit PCI adressing ranges.

---
 drivers/scsi/megaraid/megaraid_sas.h      | 1 -
 drivers/scsi/megaraid/megaraid_sas_base.c | 5 +++--
 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/scsi/megaraid/megaraid_sas.h +0 -1
index 0c73ba4bf451..f2bb2f09bff1 100644
@@ -1527,7 +1527,6 @@ struct megasas_instance {
 	u32 *reply_queue;
 	dma_addr_t reply_queue_h;
 
-	unsigned long base_addr;
 	struct megasas_register_set __iomem *reg_set;
 	u32 *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY];
 	struct megasas_pd_list          pd_list[MEGASAS_MAX_PD];
drivers/scsi/megaraid/megaraid_sas_base.c +3 -2
index 855dc7c4cad7..6da7e62b13fb 100644
@@ -3613,6 +3613,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
 	u32 max_sectors_1;
 	u32 max_sectors_2;
 	u32 tmp_sectors, msix_enable, scratch_pad_2;
+	resource_size_t base_addr;
 	struct megasas_register_set __iomem *reg_set;
 	struct megasas_ctrl_info *ctrl_info;
 	unsigned long bar_list;
@@ -3621,14 +3622,14 @@ static int megasas_init_fw(struct megasas_instance *instance)
 	/* Find first memory bar */
 	bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
 	instance->bar = find_first_bit(&bar_list, sizeof(unsigned long));
-	instance->base_addr = pci_resource_start(instance->pdev, instance->bar);
 	if (pci_request_selected_regions(instance->pdev, instance->bar,
 					 "megasas: LSI")) {
 		printk(KERN_DEBUG "megasas: IO memory region busy!\n");
 		return -EBUSY;
 	}
 
-	instance->reg_set = ioremap_nocache(instance->base_addr, 8192);
+	base_addr = pci_resource_start(instance->pdev, instance->bar);
+	instance->reg_set = ioremap_nocache(base_addr, 8192);
 
 	if (!instance->reg_set) {
 		printk(KERN_DEBUG "megasas: Failed to map IO mem\n");
Signature · 1 line
2.3.4
author
#91 lore raw

PATCH 91/155 iio:adc:max1363 incorrect resolutions for max11604, max11605, max11610 and max11611.

In reply to Jiri Slaby

From: Jonathan Cameron <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit a91a73c8b39a6b8bcc53fafa5372c65387c81233 upstream.

---
 drivers/iio/adc/max1363.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/iio/adc/max1363.c +8 -8
index cfb3d39b6664..a9102ef8db38 100644
@@ -1214,8 +1214,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
 		.num_modes = ARRAY_SIZE(max1238_mode_list),
 		.default_mode = s0to11,
 		.info = &max1238_info,
-		.channels = max1238_channels,
-		.num_channels = ARRAY_SIZE(max1238_channels),
+		.channels = max1038_channels,
+		.num_channels = ARRAY_SIZE(max1038_channels),
 	},
 	[max11605] = {
 		.bits = 8,
@@ -1224,8 +1224,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
 		.num_modes = ARRAY_SIZE(max1238_mode_list),
 		.default_mode = s0to11,
 		.info = &max1238_info,
-		.channels = max1238_channels,
-		.num_channels = ARRAY_SIZE(max1238_channels),
+		.channels = max1038_channels,
+		.num_channels = ARRAY_SIZE(max1038_channels),
 	},
 	[max11606] = {
 		.bits = 10,
@@ -1274,8 +1274,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
 		.num_modes = ARRAY_SIZE(max1238_mode_list),
 		.default_mode = s0to11,
 		.info = &max1238_info,
-		.channels = max1238_channels,
-		.num_channels = ARRAY_SIZE(max1238_channels),
+		.channels = max1138_channels,
+		.num_channels = ARRAY_SIZE(max1138_channels),
 	},
 	[max11611] = {
 		.bits = 10,
@@ -1284,8 +1284,8 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
 		.num_modes = ARRAY_SIZE(max1238_mode_list),
 		.default_mode = s0to11,
 		.info = &max1238_info,
-		.channels = max1238_channels,
-		.num_channels = ARRAY_SIZE(max1238_channels),
+		.channels = max1138_channels,
+		.num_channels = ARRAY_SIZE(max1138_channels),
 	},
 	[max11612] = {
 		.bits = 12,
Signature · 1 line
2.3.4
author
#92 lore raw

PATCH 92/155 parisc: add serial ports of C8000/1GHz machine to hardware database

In reply to Jiri Slaby

From: Helge Deller <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit eadcc7208a2237016be7bdff4551ba7614da85c8 upstream.

---
 arch/parisc/kernel/hardware.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/parisc/kernel/hardware.c +2 -1
index 06cb3992907e..5b2c5f394035 100644
@@ -1205,7 +1205,8 @@ static struct hp_hardware hp_hardware_list[] = {
 	{HPHW_FIO, 0x004, 0x00320, 0x0, "Metheus Frame Buffer"}, 
 	{HPHW_FIO, 0x004, 0x00340, 0x0, "BARCO CX4500 VME Grphx Cnsl"}, 
 	{HPHW_FIO, 0x004, 0x00360, 0x0, "Hughes TOG VME FDDI"}, 
-	{HPHW_FIO, 0x076, 0x000AD, 0x00, "Crestone Peak RS-232"},
+	{HPHW_FIO, 0x076, 0x000AD, 0x0, "Crestone Peak Core RS-232"},
+	{HPHW_FIO, 0x077, 0x000AD, 0x0, "Crestone Peak Fast? Core RS-232"},
 	{HPHW_IOA, 0x185, 0x0000B, 0x00, "Java BC Summit Port"}, 
 	{HPHW_IOA, 0x1FF, 0x0000B, 0x00, "Hitachi Ghostview Summit Port"}, 
 	{HPHW_IOA, 0x580, 0x0000B, 0x10, "U2-IOA BC Runway Port"}, 
Signature · 1 line
2.3.4
author
#93 lore raw

PATCH 93/155 stable_kernel_rules: Add pointer to netdev-FAQ for network patches

In reply to Jiri Slaby

From: Dave Chiluk <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit b76fc285337b6b256e9ba20a40cfd043f70c27af upstream.

Stable_kernel_rules should point submitters of network stable patches to the netdev_FAQ.txt as requests for stable network patches should go to netdev first.

---
 Documentation/stable_kernel_rules.txt | 3 +++
 1 file changed, 3 insertions(+)
Documentation/stable_kernel_rules.txt +3 -0
index b0714d8f678a..8dfb6a5f427d 100644
@@ -29,6 +29,9 @@ Rules on what kind of patches are accepted, and which ones are not, into the
 
 Procedure for submitting patches to the -stable tree:
 
+ - If the patch covers files in net/ or drivers/net please follow netdev stable
+   submission guidelines as described in
+   Documentation/networking/netdev-FAQ.txt
  - Send the patch, after verifying that it follows the above rules, to
    [email protected].  You must note the upstream commit ID in the
    changelog of your submission, as well as the kernel version you wish
Signature · 1 line
2.3.4
author
#94 lore raw

PATCH 94/155 ARM: OMAP2+: hwmod: Rearm wake-up interrupts for DT when MUSB is idled

In reply to Jiri Slaby

From: Tony Lindgren <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit cc824534d4fef0e46e4486d5c1e10d3c6b1ebadc upstream.

Looks like MUSB cable removal can cause wake-up interrupts to stop working for device tree based booting at least for UART3 even as nothing is dynamically remuxed. This can be fixed by calling reconfigure_io_chain() for device tree based booting in hwmod code. Note that we already do that for legacy booting if the legacy mux is configured.

My guess is that this is related to UART3 and MUSB ULPI hsusb0_data0 and hsusb0_data1 support for Carkit mode that somehow affect the configured IO chain for UART3 and require rearming the wake-up interrupts.

In general, for device tree based booting, pinctrl-single calls the rearm hook that in turn calls reconfigure_io_chain so calling reconfigure_io_chain should not be needed from the hwmod code for other events.

So let's limit the hwmod rearming of iochain only to HWMOD_FORCE_MSTANDBY where MUSB is currently the only user of it. If we see other devices needing similar changes we can add more checks for it.

---
 arch/arm/mach-omap2/omap_hwmod.c | 4 ++++
 1 file changed, 4 insertions(+)
arch/arm/mach-omap2/omap_hwmod.c +4 -0
index 832adb1a6dd2..3d29fb972cd0 100644
@@ -2179,6 +2179,8 @@ static int _enable(struct omap_hwmod *oh)
 			 oh->mux->pads_dynamic))) {
 		omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
 		_reconfigure_io_chain();
+	} else if (oh->flags & HWMOD_FORCE_MSTANDBY) {
+		_reconfigure_io_chain();
 	}
 
 	_add_initiator_dep(oh, mpu_oh);
@@ -2285,6 +2287,8 @@ static int _idle(struct omap_hwmod *oh)
 	if (oh->mux && oh->mux->pads_dynamic) {
 		omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
 		_reconfigure_io_chain();
+	} else if (oh->flags & HWMOD_FORCE_MSTANDBY) {
+		_reconfigure_io_chain();
 	}
 
 	oh->_state = _HWMOD_STATE_IDLE;
Signature · 1 line
2.3.4
author
#95 lore raw

PATCH 95/155 MIPS: asm/reg.h: Make 32- and 64-bit definitions available at the same time

In reply to Jiri Slaby

From: Alex Smith <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit bcec7c8da6b092b1ff3327fd83c2193adb12f684 upstream.

Get rid of the WANT_COMPAT_REG_H test and instead define both the 32- and 64-bit register offset definitions at the same time with MIPS{32,64}_ prefixes, then define the existing EF_* names to the correct definitions for the kernel's bitness.

This patch is a prerequisite of the following bug fix patch.

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

---
 arch/mips/include/asm/reg.h      | 260 +++++++++++++++++++++++++--------------
 arch/mips/kernel/binfmt_elfo32.c |  32 ++---
 2 files changed, 182 insertions(+), 110 deletions(-)
arch/mips/include/asm/reg.h +169 -91
index 910e71a12466..b8343ccbc989 100644
@@ -12,116 +12,194 @@
 #ifndef __ASM_MIPS_REG_H
 #define __ASM_MIPS_REG_H
 
-
-#if defined(CONFIG_32BIT) || defined(WANT_COMPAT_REG_H)
-
-#define EF_R0			6
-#define EF_R1			7
-#define EF_R2			8
-#define EF_R3			9
-#define EF_R4			10
-#define EF_R5			11
-#define EF_R6			12
-#define EF_R7			13
-#define EF_R8			14
-#define EF_R9			15
-#define EF_R10			16
-#define EF_R11			17
-#define EF_R12			18
-#define EF_R13			19
-#define EF_R14			20
-#define EF_R15			21
-#define EF_R16			22
-#define EF_R17			23
-#define EF_R18			24
-#define EF_R19			25
-#define EF_R20			26
-#define EF_R21			27
-#define EF_R22			28
-#define EF_R23			29
-#define EF_R24			30
-#define EF_R25			31
+#define MIPS32_EF_R0		6
+#define MIPS32_EF_R1		7
+#define MIPS32_EF_R2		8
+#define MIPS32_EF_R3		9
+#define MIPS32_EF_R4		10
+#define MIPS32_EF_R5		11
+#define MIPS32_EF_R6		12
+#define MIPS32_EF_R7		13
+#define MIPS32_EF_R8		14
+#define MIPS32_EF_R9		15
+#define MIPS32_EF_R10		16
+#define MIPS32_EF_R11		17
+#define MIPS32_EF_R12		18
+#define MIPS32_EF_R13		19
+#define MIPS32_EF_R14		20
+#define MIPS32_EF_R15		21
+#define MIPS32_EF_R16		22
+#define MIPS32_EF_R17		23
+#define MIPS32_EF_R18		24
+#define MIPS32_EF_R19		25
+#define MIPS32_EF_R20		26
+#define MIPS32_EF_R21		27
+#define MIPS32_EF_R22		28
+#define MIPS32_EF_R23		29
+#define MIPS32_EF_R24		30
+#define MIPS32_EF_R25		31
 
 /*
  * k0/k1 unsaved
  */
-#define EF_R26			32
-#define EF_R27			33
+#define MIPS32_EF_R26		32
+#define MIPS32_EF_R27		33
 
-#define EF_R28			34
-#define EF_R29			35
-#define EF_R30			36
-#define EF_R31			37
+#define MIPS32_EF_R28		34
+#define MIPS32_EF_R29		35
+#define MIPS32_EF_R30		36
+#define MIPS32_EF_R31		37
 
 /*
  * Saved special registers
  */
-#define EF_LO			38
-#define EF_HI			39
-
-#define EF_CP0_EPC		40
-#define EF_CP0_BADVADDR		41
-#define EF_CP0_STATUS		42
-#define EF_CP0_CAUSE		43
-#define EF_UNUSED0		44
-
-#define EF_SIZE			180
-
-#endif
-
-#if defined(CONFIG_64BIT) && !defined(WANT_COMPAT_REG_H)
-
-#define EF_R0			 0
-#define EF_R1			 1
-#define EF_R2			 2
-#define EF_R3			 3
-#define EF_R4			 4
-#define EF_R5			 5
-#define EF_R6			 6
-#define EF_R7			 7
-#define EF_R8			 8
-#define EF_R9			 9
-#define EF_R10			10
-#define EF_R11			11
-#define EF_R12			12
-#define EF_R13			13
-#define EF_R14			14
-#define EF_R15			15
-#define EF_R16			16
-#define EF_R17			17
-#define EF_R18			18
-#define EF_R19			19
-#define EF_R20			20
-#define EF_R21			21
-#define EF_R22			22
-#define EF_R23			23
-#define EF_R24			24
-#define EF_R25			25
+#define MIPS32_EF_LO		38
+#define MIPS32_EF_HI		39
+
+#define MIPS32_EF_CP0_EPC	40
+#define MIPS32_EF_CP0_BADVADDR	41
+#define MIPS32_EF_CP0_STATUS	42
+#define MIPS32_EF_CP0_CAUSE	43
+#define MIPS32_EF_UNUSED0	44
+
+#define MIPS32_EF_SIZE		180
+
+#define MIPS64_EF_R0		0
+#define MIPS64_EF_R1		1
+#define MIPS64_EF_R2		2
+#define MIPS64_EF_R3		3
+#define MIPS64_EF_R4		4
+#define MIPS64_EF_R5		5
+#define MIPS64_EF_R6		6
+#define MIPS64_EF_R7		7
+#define MIPS64_EF_R8		8
+#define MIPS64_EF_R9		9
+#define MIPS64_EF_R10		10
+#define MIPS64_EF_R11		11
+#define MIPS64_EF_R12		12
+#define MIPS64_EF_R13		13
+#define MIPS64_EF_R14		14
+#define MIPS64_EF_R15		15
+#define MIPS64_EF_R16		16
+#define MIPS64_EF_R17		17
+#define MIPS64_EF_R18		18
+#define MIPS64_EF_R19		19
+#define MIPS64_EF_R20		20
+#define MIPS64_EF_R21		21
+#define MIPS64_EF_R22		22
+#define MIPS64_EF_R23		23
+#define MIPS64_EF_R24		24
+#define MIPS64_EF_R25		25
 
 /*
  * k0/k1 unsaved
  */
-#define EF_R26			26
-#define EF_R27			27
+#define MIPS64_EF_R26		26
+#define MIPS64_EF_R27		27
 
 
-#define EF_R28			28
-#define EF_R29			29
-#define EF_R30			30
-#define EF_R31			31
+#define MIPS64_EF_R28		28
+#define MIPS64_EF_R29		29
+#define MIPS64_EF_R30		30
+#define MIPS64_EF_R31		31
 
 /*
  * Saved special registers
  */
-#define EF_LO			32
-#define EF_HI			33
-
-#define EF_CP0_EPC		34
-#define EF_CP0_BADVADDR		35
-#define EF_CP0_STATUS		36
-#define EF_CP0_CAUSE		37
-
-#define EF_SIZE			304	/* size in bytes */
+#define MIPS64_EF_LO		32
+#define MIPS64_EF_HI		33
+
+#define MIPS64_EF_CP0_EPC	34
+#define MIPS64_EF_CP0_BADVADDR	35
+#define MIPS64_EF_CP0_STATUS	36
+#define MIPS64_EF_CP0_CAUSE	37
+
+#define MIPS64_EF_SIZE		304	/* size in bytes */
+
+#if defined(CONFIG_32BIT)
+
+#define EF_R0			MIPS32_EF_R0
+#define EF_R1			MIPS32_EF_R1
+#define EF_R2			MIPS32_EF_R2
+#define EF_R3			MIPS32_EF_R3
+#define EF_R4			MIPS32_EF_R4
+#define EF_R5			MIPS32_EF_R5
+#define EF_R6			MIPS32_EF_R6
+#define EF_R7			MIPS32_EF_R7
+#define EF_R8			MIPS32_EF_R8
+#define EF_R9			MIPS32_EF_R9
+#define EF_R10			MIPS32_EF_R10
+#define EF_R11			MIPS32_EF_R11
+#define EF_R12			MIPS32_EF_R12
+#define EF_R13			MIPS32_EF_R13
+#define EF_R14			MIPS32_EF_R14
+#define EF_R15			MIPS32_EF_R15
+#define EF_R16			MIPS32_EF_R16
+#define EF_R17			MIPS32_EF_R17
+#define EF_R18			MIPS32_EF_R18
+#define EF_R19			MIPS32_EF_R19
+#define EF_R20			MIPS32_EF_R20
+#define EF_R21			MIPS32_EF_R21
+#define EF_R22			MIPS32_EF_R22
+#define EF_R23			MIPS32_EF_R23
+#define EF_R24			MIPS32_EF_R24
+#define EF_R25			MIPS32_EF_R25
+#define EF_R26			MIPS32_EF_R26
+#define EF_R27			MIPS32_EF_R27
+#define EF_R28			MIPS32_EF_R28
+#define EF_R29			MIPS32_EF_R29
+#define EF_R30			MIPS32_EF_R30
+#define EF_R31			MIPS32_EF_R31
+#define EF_LO			MIPS32_EF_LO
+#define EF_HI			MIPS32_EF_HI
+#define EF_CP0_EPC		MIPS32_EF_CP0_EPC
+#define EF_CP0_BADVADDR		MIPS32_EF_CP0_BADVADDR
+#define EF_CP0_STATUS		MIPS32_EF_CP0_STATUS
+#define EF_CP0_CAUSE		MIPS32_EF_CP0_CAUSE
+#define EF_UNUSED0		MIPS32_EF_UNUSED0
+#define EF_SIZE			MIPS32_EF_SIZE
+
+#elif defined(CONFIG_64BIT)
+
+#define EF_R0			MIPS64_EF_R0
+#define EF_R1			MIPS64_EF_R1
+#define EF_R2			MIPS64_EF_R2
+#define EF_R3			MIPS64_EF_R3
+#define EF_R4			MIPS64_EF_R4
+#define EF_R5			MIPS64_EF_R5
+#define EF_R6			MIPS64_EF_R6
+#define EF_R7			MIPS64_EF_R7
+#define EF_R8			MIPS64_EF_R8
+#define EF_R9			MIPS64_EF_R9
+#define EF_R10			MIPS64_EF_R10
+#define EF_R11			MIPS64_EF_R11
+#define EF_R12			MIPS64_EF_R12
+#define EF_R13			MIPS64_EF_R13
+#define EF_R14			MIPS64_EF_R14
+#define EF_R15			MIPS64_EF_R15
+#define EF_R16			MIPS64_EF_R16
+#define EF_R17			MIPS64_EF_R17
+#define EF_R18			MIPS64_EF_R18
+#define EF_R19			MIPS64_EF_R19
+#define EF_R20			MIPS64_EF_R20
+#define EF_R21			MIPS64_EF_R21
+#define EF_R22			MIPS64_EF_R22
+#define EF_R23			MIPS64_EF_R23
+#define EF_R24			MIPS64_EF_R24
+#define EF_R25			MIPS64_EF_R25
+#define EF_R26			MIPS64_EF_R26
+#define EF_R27			MIPS64_EF_R27
+#define EF_R28			MIPS64_EF_R28
+#define EF_R29			MIPS64_EF_R29
+#define EF_R30			MIPS64_EF_R30
+#define EF_R31			MIPS64_EF_R31
+#define EF_LO			MIPS64_EF_LO
+#define EF_HI			MIPS64_EF_HI
+#define EF_CP0_EPC		MIPS64_EF_CP0_EPC
+#define EF_CP0_BADVADDR		MIPS64_EF_CP0_BADVADDR
+#define EF_CP0_STATUS		MIPS64_EF_CP0_STATUS
+#define EF_CP0_CAUSE		MIPS64_EF_CP0_CAUSE
+#define EF_SIZE			MIPS64_EF_SIZE
 
 #endif /* CONFIG_64BIT */
 
arch/mips/kernel/binfmt_elfo32.c +13 -19
index 202e581e6096..7fdf1de0447f 100644
@@ -58,12 +58,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
 
 #include <asm/processor.h>
 
-/*
- * When this file is selected, we are definitely running a 64bit kernel.
- * So using the right regs define in asm/reg.h
- */
-#define WANT_COMPAT_REG_H
-
 /* These MUST be defined before elf.h gets included */
 extern void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs);
 #define ELF_CORE_COPY_REGS(_dest, _regs) elf32_core_copy_regs(_dest, _regs);
@@ -135,21 +129,21 @@ void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs)
 {
 	int i;
 
-	for (i = 0; i < EF_R0; i++)
+	for (i = 0; i < MIPS32_EF_R0; i++)
 		grp[i] = 0;
-	grp[EF_R0] = 0;
+	grp[MIPS32_EF_R0] = 0;
 	for (i = 1; i <= 31; i++)
-		grp[EF_R0 + i] = (elf_greg_t) regs->regs[i];
-	grp[EF_R26] = 0;
-	grp[EF_R27] = 0;
-	grp[EF_LO] = (elf_greg_t) regs->lo;
-	grp[EF_HI] = (elf_greg_t) regs->hi;
-	grp[EF_CP0_EPC] = (elf_greg_t) regs->cp0_epc;
-	grp[EF_CP0_BADVADDR] = (elf_greg_t) regs->cp0_badvaddr;
-	grp[EF_CP0_STATUS] = (elf_greg_t) regs->cp0_status;
-	grp[EF_CP0_CAUSE] = (elf_greg_t) regs->cp0_cause;
-#ifdef EF_UNUSED0
-	grp[EF_UNUSED0] = 0;
+		grp[MIPS32_EF_R0 + i] = (elf_greg_t) regs->regs[i];
+	grp[MIPS32_EF_R26] = 0;
+	grp[MIPS32_EF_R27] = 0;
+	grp[MIPS32_EF_LO] = (elf_greg_t) regs->lo;
+	grp[MIPS32_EF_HI] = (elf_greg_t) regs->hi;
+	grp[MIPS32_EF_CP0_EPC] = (elf_greg_t) regs->cp0_epc;
+	grp[MIPS32_EF_CP0_BADVADDR] = (elf_greg_t) regs->cp0_badvaddr;
+	grp[MIPS32_EF_CP0_STATUS] = (elf_greg_t) regs->cp0_status;
+	grp[MIPS32_EF_CP0_CAUSE] = (elf_greg_t) regs->cp0_cause;
+#ifdef MIPS32_EF_UNUSED0
+	grp[MIPS32_EF_UNUSED0] = 0;
 #endif
 }
 
Signature · 1 line
2.3.4
author
#96 lore raw

PATCH 96/155 ACPI: Run fixed event device notifications in process context

In reply to Jiri Slaby

From: Lan Tianyu <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 236105db632c6279a020f78c83e22eaef746006b upstream.

Currently, notify callbacks for fixed button events are run from interrupt context. That is not necessary and after commit 0bf6368ee8f2 (ACPI / button: Add ACPI Button event via netlink routine) it causes netlink routines to be called from interrupt context which is not correct.

Also, that is different from non-fixed device events (including non-fixed button events) whose notify callbacks are all executed from process context.

For the above reasons, make fixed button device notify callbacks run in process context which will avoid the deadlock when using netlink to report button events to user space.

Fixes 0bf6368ee8f2 (ACPI / button: Add ACPI Button event via netlink routine)
[rjw: Function names, subject and changelog.]
---
 drivers/acpi/scan.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/acpi/scan.c +10 -5
index d047771c179a..332b126ee3c4 100644
@@ -834,12 +834,17 @@ static void acpi_device_notify(acpi_handle handle, u32 event, void *data)
 	device->driver->ops.notify(device, event);
 }
 
-static acpi_status acpi_device_notify_fixed(void *data)
+static void acpi_device_notify_fixed(void *data)
 {
 	struct acpi_device *device = data;
 
 	/* Fixed hardware devices have no handles */
 	acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device);
+}
+
+static acpi_status acpi_device_fixed_event(void *data)
+{
+	acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_device_notify_fixed, data);
 	return AE_OK;
 }
 
@@ -850,12 +855,12 @@ static int acpi_device_install_notify_handler(struct acpi_device *device)
 	if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON)
 		status =
 		    acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
-						     acpi_device_notify_fixed,
+						     acpi_device_fixed_event,
 						     device);
 	else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON)
 		status =
 		    acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
-						     acpi_device_notify_fixed,
+						     acpi_device_fixed_event,
 						     device);
 	else
 		status = acpi_install_notify_handler(device->handle,
@@ -872,10 +877,10 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device)
 {
 	if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON)
 		acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
-						acpi_device_notify_fixed);
+						acpi_device_fixed_event);
 	else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON)
 		acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
-						acpi_device_notify_fixed);
+						acpi_device_fixed_event);
 	else
 		acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
 					   acpi_device_notify);
Signature · 1 line
2.3.4
author
#97 lore raw

PATCH 97/155 USB: zte_ev: fix removed PIDs

In reply to Jiri Slaby

From: Johan Hovold <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 3096691011d01cef56b243a5e65431405c07d574 upstream.

Add back some PIDs that were mistakingly remove when reverting commit 73228a0538a7 ("USB: option,zte_ev: move most ZTE CDMA devices to zte_ev"), which apparently did more than its commit message claimed in that it not only moved some PIDs from option to zte_ev but also added some new ones.

Fixes 63a901c06e3c ("Revert "USB: option,zte_ev: move most ZTE CDMA

devices to zte_ev"")

---
 drivers/usb/serial/zte_ev.c | 8 ++++++++
 1 file changed, 8 insertions(+)
drivers/usb/serial/zte_ev.c +8 -0
index 88dd32ce5224..d6a3fbd029be 100644
@@ -273,6 +273,14 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
 }
 
 static const struct usb_device_id id_table[] = {
+	{ USB_DEVICE(0x19d2, 0xffec) },
+	{ USB_DEVICE(0x19d2, 0xffee) },
+	{ USB_DEVICE(0x19d2, 0xfff6) },
+	{ USB_DEVICE(0x19d2, 0xfff7) },
+	{ USB_DEVICE(0x19d2, 0xfff8) },
+	{ USB_DEVICE(0x19d2, 0xfff9) },
+	{ USB_DEVICE(0x19d2, 0xfffb) },
+	{ USB_DEVICE(0x19d2, 0xfffc) },
 	/* MG880 */
 	{ USB_DEVICE(0x19d2, 0xfffd) },
 	{ },
Signature · 1 line
2.3.4
author
#98 lore raw

PATCH 98/155 ACPICA: Update to GPIO region handler interface.

In reply to Jiri Slaby

From: Bob Moore <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 75ec6e55f1384548311a13ce4fcb39c516053314 upstream.

Changes to correct several GPIO issues:

1) The update_rule in a GPIO field definition is now ignored; a read-modify-write operation is never performed for GPIO fields. (Internally, this means that the field assembly/disassembly code is completely bypassed for GPIO.)

2) The Address parameter passed to a GPIO region handler is now the bit offset of the field from a previous Connection() operator. Thus, it becomes a "Pin Number Index" into the Connection() resource descriptor.

3) The bit_width parameter passed to a GPIO region handler is now the exact bit width of the GPIO field. Thus, it can be interpreted as "number of pins".

Overall, we can now say that the region handler interface to GPIO handlers is a raw "bit/pin" addressed interface, not a byte-addressed interface like the system_memory handler interface.

---
 drivers/acpi/acpica/aclocal.h  |  1 +
 drivers/acpi/acpica/acobject.h |  1 +
 drivers/acpi/acpica/dsfield.c  |  2 ++
 drivers/acpi/acpica/evregion.c | 47 +++++++++++++++++++----------
 drivers/acpi/acpica/exfield.c  | 67 ++++++++++++++++++++++++++++++++++++++++++
 drivers/acpi/acpica/exprep.c   |  2 ++
 6 files changed, 104 insertions(+), 16 deletions(-)
drivers/acpi/acpica/aclocal.h +1 -0
index 0ed00669cd21..ca8196ea12d1 100644
@@ -254,6 +254,7 @@ struct acpi_create_field_info {
 	u32 field_bit_position;
 	u32 field_bit_length;
 	u16 resource_length;
+	u16 pin_number_index;
 	u8 field_flags;
 	u8 attribute;
 	u8 field_type;
drivers/acpi/acpica/acobject.h +1 -0
index cc7ab6dd724e..a47cc78ffd4f 100644
@@ -263,6 +263,7 @@ struct acpi_object_region_field {
 	ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO u16 resource_length;
 	union acpi_operand_object *region_obj;	/* Containing op_region object */
 	u8 *resource_buffer;	/* resource_template for serial regions/fields */
+	u16 pin_number_index;	/* Index relative to previous Connection/Template */
 };
 
 struct acpi_object_bank_field {
drivers/acpi/acpica/dsfield.c +2 -0
index d4bfe7b7f90a..10bc062a4a88 100644
@@ -360,6 +360,7 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,
 			 */
 			info->resource_buffer = NULL;
 			info->connection_node = NULL;
+			info->pin_number_index = 0;
 
 			/*
 			 * A Connection() is either an actual resource descriptor (buffer)
@@ -437,6 +438,7 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,
 			}
 
 			info->field_bit_position += info->field_bit_length;
+			info->pin_number_index++;	/* Index relative to previous Connection() */
 			break;
 
 		default:
drivers/acpi/acpica/evregion.c +31 -16

77 lines not on this page · raw message

drivers/acpi/acpica/exfield.c +67 -0

79 lines not on this page · raw message

drivers/acpi/acpica/exprep.c +2 -0
index 5a588611ab48..8c88cfdec441 100644
@@ -484,6 +484,8 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
 			obj_desc->field.resource_length = info->resource_length;
 		}
 
+		obj_desc->field.pin_number_index = info->pin_number_index;
+
 		/* Allow full data read from EC address space */
 
 		if ((obj_desc->field.region_obj->region.space_id ==
Signature · 1 line
2.3.4
author
#99 lore raw

PATCH 99/155 powerpc/perf: Fix ABIv2 kernel backtraces

In reply to Jiri Slaby

From: Anton Blanchard <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 85101af13bb854a6572fa540df7c7201958624b9 upstream.

ABIv2 kernels are failing to backtrace through the kernel. An example:

39.30% readseek2_proce [kernel.kallsyms] [k] find_get_entry

            |
            --- find_get_entry
               __GI___libc_read

The problem is in valid_next_sp() where we check that the new stack pointer is at least STACK_FRAME_OVERHEAD below the previous one.

ABIv1 has a minimum stack frame size of 112 bytes consisting of 48 bytes and 64 bytes of parameter save area. ABIv2 changes that to 32 bytes with no paramter save area.

STACK_FRAME_OVERHEAD is in theory the minimum stack frame size, but we over 240 uses of it, some of which assume that it includes space for the parameter area.

We need to work through all our stack defines and rationalise them but let's fix perf now by creating STACK_FRAME_MIN_SIZE and using in valid_next_sp(). This fixes the issue:

30.64% readseek2_proce [kernel.kallsyms] [k] find_get_entry

            |
            --- find_get_entry
               pagecache_get_page
               generic_file_read_iter
               new_sync_read
               vfs_read
               sys_read
               syscall_exit
               __GI___libc_read
---
 arch/powerpc/include/asm/ptrace.h | 7 +++++++
 arch/powerpc/perf/callchain.c     | 2 +-
 2 files changed, 8 insertions(+), 1 deletion(-)
arch/powerpc/include/asm/ptrace.h +7 -0
index 279b80f3bb29..c0c61fa9cd9e 100644
@@ -47,6 +47,12 @@
 				 STACK_FRAME_OVERHEAD + KERNEL_REDZONE_SIZE)
 #define STACK_FRAME_MARKER	12
 
+#if defined(_CALL_ELF) && _CALL_ELF == 2
+#define STACK_FRAME_MIN_SIZE	32
+#else
+#define STACK_FRAME_MIN_SIZE	STACK_FRAME_OVERHEAD
+#endif
+
 /* Size of dummy stack frame allocated when calling signal handler. */
 #define __SIGNAL_FRAMESIZE	128
 #define __SIGNAL_FRAMESIZE32	64
@@ -60,6 +66,7 @@
 #define STACK_FRAME_REGS_MARKER	ASM_CONST(0x72656773)
 #define STACK_INT_FRAME_SIZE	(sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD)
 #define STACK_FRAME_MARKER	2
+#define STACK_FRAME_MIN_SIZE	STACK_FRAME_OVERHEAD
 
 /* Size of stack frame allocated when calling signal handler. */
 #define __SIGNAL_FRAMESIZE	64
arch/powerpc/perf/callchain.c +1 -1
index 74d1e780748b..2396dda282cd 100644
@@ -35,7 +35,7 @@ static int valid_next_sp(unsigned long sp, unsigned long prev_sp)
 		return 0;		/* must be 16-byte aligned */
 	if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD))
 		return 0;
-	if (sp >= prev_sp + STACK_FRAME_OVERHEAD)
+	if (sp >= prev_sp + STACK_FRAME_MIN_SIZE)
 		return 1;
 	/*
 	 * sp could decrease when we jump off an interrupt stack
Signature · 1 line
2.3.4
author
#100 lore raw

PATCH 100/155 ARC: [nsimosci] Allow "headless" models to boot

In reply to Jiri Slaby

From: Vineet Gupta <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 5c05483e2db91890faa9a7be0a831701a3f442d6 upstream.

There are certain test configuration of virtual platform which don't have any real console device (uart/pgu). So add tty0 as a fallback console device to allow system to boot and be accessible via telnet

Otherwise with ttyS0 as only console, but 8250 disabled in kernel build, init chokes.

---
 arch/arc/boot/dts/nsimosci.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arc/boot/dts/nsimosci.dts +1 -1
index 4f31b2eb5cdf..398064cef746 100644
@@ -20,7 +20,7 @@
 		/* this is for console on PGU */
 		/* bootargs = "console=tty0 consoleblank=0"; */
 		/* this is for console on serial */
-		bootargs = "earlycon=uart8250,mmio32,0xc0000000,115200n8 console=ttyS0,115200n8 consoleblank=0 debug";
+		bootargs = "earlycon=uart8250,mmio32,0xc0000000,115200n8 console=tty0 console=ttyS0,115200n8 consoleblank=0 debug";
 	};
 
 	aliases {
Signature · 1 line
2.3.4
author
#101 lore raw

PATCH 101/155 ARC: Update order of registers in KGDB to match GDB 7.5

In reply to Jiri Slaby

From: Anton Kolesov <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit ebc0c74e76cec9c4dd860eb0ca1c0b39dc63c482 upstream.

Order of registers has changed in GDB moving from 6.8 to 7.5. This patch updates KGDB to work properly with GDB 7.5, though makes it incompatible with 6.8.

---
 arch/arc/include/asm/kgdb.h | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)
arch/arc/include/asm/kgdb.h +18 -14
index b65fca7ffeb5..fea931634136 100644
@@ -19,7 +19,7 @@
  * register API yet */
 #undef DBG_MAX_REG_NUM
 
-#define GDB_MAX_REGS		39
+#define GDB_MAX_REGS		87
 
 #define BREAK_INSTR_SIZE	2
 #define CACHE_FLUSH_IS_SAFE	1
@@ -33,23 +33,27 @@ static inline void arch_kgdb_breakpoint(void)
 
 extern void kgdb_trap(struct pt_regs *regs);
 
-enum arc700_linux_regnums {
+/* This is the numbering of registers according to the GDB. See GDB's
+ * arc-tdep.h for details.
+ *
+ * Registers are ordered for GDB 7.5. It is incompatible with GDB 6.8. */
+enum arc_linux_regnums {
 	_R0		= 0,
 	_R1, _R2, _R3, _R4, _R5, _R6, _R7, _R8, _R9, _R10, _R11, _R12, _R13,
 	_R14, _R15, _R16, _R17, _R18, _R19, _R20, _R21, _R22, _R23, _R24,
 	_R25, _R26,
-	_BTA		= 27,
-	_LP_START	= 28,
-	_LP_END		= 29,
-	_LP_COUNT	= 30,
-	_STATUS32	= 31,
-	_BLINK		= 32,
-	_FP		= 33,
-	__SP		= 34,
-	_EFA		= 35,
-	_RET		= 36,
-	_ORIG_R8	= 37,
-	_STOP_PC	= 38
+	_FP		= 27,
+	__SP		= 28,
+	_R30		= 30,
+	_BLINK		= 31,
+	_LP_COUNT	= 60,
+	_STOP_PC	= 64,
+	_RET		= 64,
+	_LP_START	= 65,
+	_LP_END		= 66,
+	_STATUS32	= 67,
+	_ECR		= 76,
+	_BTA		= 82,
 };
 
 #else
Signature · 1 line
2.3.4
author
#102 lore raw

PATCH 102/155 ARM: Correct BUG() assembly to ensure it is endian-agnostic

In reply to Jiri Slaby

From: Ben Dooks <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 63328070eff2f4fd730c86966a0dbc976147c39f upstream.

Currently BUG() uses .word or .hword to create the necessary illegal instructions. However if we are building BE8 then these get swapped by the linker into different illegal instructions in the text. This means that the BUG() macro does not get trapped properly.

Change to using <asm/opcodes.h> to provide the necessary ARM instruction building as we cannot rely on gcc/gas having the .inst instructions which where added to try and resolve this issue (reported by Dave Martin <[email protected]>).

---
 arch/arm/include/asm/bug.h | 10 ++++++----
 arch/arm/kernel/traps.c    |  8 +++++---
 2 files changed, 11 insertions(+), 7 deletions(-)
arch/arm/include/asm/bug.h +6 -4
index 7af5c6c3653a..b274bde24905 100644
@@ -2,6 +2,8 @@
 #define _ASMARM_BUG_H
 
 #include <linux/linkage.h>
+#include <linux/types.h>
+#include <asm/opcodes.h>
 
 #ifdef CONFIG_BUG
 
@@ -12,10 +14,10 @@
  */
 #ifdef CONFIG_THUMB2_KERNEL
 #define BUG_INSTR_VALUE 0xde02
-#define BUG_INSTR_TYPE ".hword "
+#define BUG_INSTR(__value) __inst_thumb16(__value)
 #else
 #define BUG_INSTR_VALUE 0xe7f001f2
-#define BUG_INSTR_TYPE ".word "
+#define BUG_INSTR(__value) __inst_arm(__value)
 #endif
 
 
@@ -33,7 +35,7 @@
 
 #define __BUG(__file, __line, __value)				\
 do {								\
-	asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n"	\
+	asm volatile("1:\t" BUG_INSTR(__value) "\n"  \
 		".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \
 		"2:\t.asciz " #__file "\n" 			\
 		".popsection\n" 				\
@@ -48,7 +50,7 @@ do {								\
 
 #define __BUG(__file, __line, __value)				\
 do {								\
-	asm volatile(BUG_INSTR_TYPE #__value);			\
+	asm volatile(BUG_INSTR(__value) "\n");			\
 	unreachable();						\
 } while (0)
 #endif  /* CONFIG_DEBUG_BUGVERBOSE */
arch/arm/kernel/traps.c +5 -3
index 8e6cd760cc68..3c2f438e2daa 100644
@@ -347,15 +347,17 @@ void arm_notify_die(const char *str, struct pt_regs *regs,
 int is_valid_bugaddr(unsigned long pc)
 {
 #ifdef CONFIG_THUMB2_KERNEL
-	unsigned short bkpt;
+	u16 bkpt;
+	u16 insn = __opcode_to_mem_thumb16(BUG_INSTR_VALUE);
 #else
-	unsigned long bkpt;
+	u32 bkpt;
+	u32 insn = __opcode_to_mem_arm(BUG_INSTR_VALUE);
 #endif
 
 	if (probe_kernel_address((unsigned *)pc, bkpt))
 		return 0;
 
-	return bkpt == BUG_INSTR_VALUE;
+	return bkpt == insn;
 }
 
 #endif
Signature · 1 line
2.3.4
author
#103 lore raw

PATCH 103/155 md/bitmap: always wait for writes on unplug.

In reply to Jiri Slaby

From: NeilBrown <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 4b5060ddae2b03c5387321fafc089d242225697a upstream.

If two threads call bitmap_unplug at the same time, then one might schedule all the writes, and the other might decide that it doesn't need to wait. But really it does.

It rarely hurts to wait when it isn't absolutely necessary, and the current code doesn't really focus on 'absolutely necessary' anyway. So just wait always.

This can potentially lead to data corruption if a crash happens at an awkward time and data was written before the bitmap was updated. It is very unlikely, but this should go to -stable just to be safe. Appropriate for any -stable.

Cc [email protected] (please delay until 3.18 is released)
---
 drivers/md/bitmap.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)
drivers/md/bitmap.c +6 -10
index a7fd82133b12..03b2edd35e19 100644
@@ -883,7 +883,6 @@ void bitmap_unplug(struct bitmap *bitmap)
 {
 	unsigned long i;
 	int dirty, need_write;
-	int wait = 0;
 
 	if (!bitmap || !bitmap->storage.filemap ||
 	    test_bit(BITMAP_STALE, &bitmap->flags))
@@ -901,16 +900,13 @@ void bitmap_unplug(struct bitmap *bitmap)
 			clear_page_attr(bitmap, i, BITMAP_PAGE_PENDING);
 			write_page(bitmap, bitmap->storage.filemap[i], 0);
 		}
-		if (dirty)
-			wait = 1;
-	}
-	if (wait) { /* if any writes were performed, we need to wait on them */
-		if (bitmap->storage.file)
-			wait_event(bitmap->write_wait,
-				   atomic_read(&bitmap->pending_writes)==0);
-		else
-			md_super_wait(bitmap->mddev);
 	}
+	if (bitmap->storage.file)
+		wait_event(bitmap->write_wait,
+			   atomic_read(&bitmap->pending_writes)==0);
+	else
+		md_super_wait(bitmap->mddev);
+
 	if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags))
 		bitmap_file_kick(bitmap);
 }
Signature · 1 line
2.3.4
author
#104 lore raw

PATCH 104/155 Btrfs: don't delay inode ref updates during log replay

In reply to Jiri Slaby

From: Chris Mason <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 6f8960541b1eb6054a642da48daae2320fddba93 upstream.

Commit 1d52c78afbb (Btrfs: try not to ENOSPC on log replay) added a check to skip delayed inode updates during log replay because it confuses the enospc code. But the delayed processing will end up ignoring delayed refs from log replay because the inode itself wasn't put through the delayed code.

This can end up triggering a warning at commit time:

WARNING: CPU: 2 PID: 778 at fs/btrfs/delayed-inode.c:1410 btrfs_assert_delayed_root_empty+0x32/0x34()

Which is repeated for each commit because we never process the delayed inode ref update.

The fix used here is to change btrfs_delayed_delete_inode_ref to return an error if we're currently in log replay. The caller will do the ref deletion immediately and everything will work properly.

---
 fs/btrfs/delayed-inode.c | 8 ++++++++
 1 file changed, 8 insertions(+)
fs/btrfs/delayed-inode.c +8 -0
index cbd9523ad09c..ebc592317848 100644
@@ -1804,6 +1804,14 @@ int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans,
 	struct btrfs_delayed_node *delayed_node;
 	int ret = 0;
 
+	/*
+	 * we don't do delayed inode updates during log recovery because it
+	 * leads to enospc problems.  This means we also can't do
+	 * delayed inode refs
+	 */
+	if (BTRFS_I(inode)->root->fs_info->log_root_recovering)
+		return -EAGAIN;
+
 	delayed_node = btrfs_get_or_create_delayed_node(inode);
 	if (IS_ERR(delayed_node))
 		return PTR_ERR(delayed_node);
Signature · 1 line
2.3.4
author
#105 lore raw

PATCH 105/155 ARC: [nsimosci] move peripherals to match model to FPGA

In reply to Jiri Slaby

From: Vineet Gupta <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit e8ef060b37c2d3cc5fd0c0edbe4e42ec1cb9768b upstream.

This allows the sdplite/Zebu images to run on OSCI simulation platform

Cc <[email protected]> #3.10, 3.12, 3.14, 3.16
---
 arch/arc/boot/dts/nsimosci.dts | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)
arch/arc/boot/dts/nsimosci.dts +9 -9
index 398064cef746..4c169d825415 100644
@@ -20,7 +20,7 @@
 		/* this is for console on PGU */
 		/* bootargs = "console=tty0 consoleblank=0"; */
 		/* this is for console on serial */
-		bootargs = "earlycon=uart8250,mmio32,0xc0000000,115200n8 console=tty0 console=ttyS0,115200n8 consoleblank=0 debug";
+		bootargs = "earlycon=uart8250,mmio32,0xf0000000,115200n8 console=tty0 console=ttyS0,115200n8 consoleblank=0 debug";
 	};
 
 	aliases {
@@ -46,9 +46,9 @@
 			#interrupt-cells = <1>;
 		};
 
-		uart0: serial@c0000000 {
+		uart0: serial@f0000000 {
 			compatible = "ns8250";
-			reg = <0xc0000000 0x2000>;
+			reg = <0xf0000000 0x2000>;
 			interrupts = <11>;
 			clock-frequency = <3686400>;
 			baud = <115200>;
@@ -57,21 +57,21 @@
 			no-loopback-test = <1>;
 		};
 
-		pgu0: pgu@c9000000 {
+		pgu0: pgu@f9000000 {
 			compatible = "snps,arcpgufb";
-			reg = <0xc9000000 0x400>;
+			reg = <0xf9000000 0x400>;
 		};
 
-		ps2: ps2@c9001000 {
+		ps2: ps2@f9001000 {
 			compatible = "snps,arc_ps2";
-			reg = <0xc9000400 0x14>;
+			reg = <0xf9000400 0x14>;
 			interrupts = <13>;
 			interrupt-names = "arc_ps2_irq";
 		};
 
-		eth0: ethernet@c0003000 {
+		eth0: ethernet@f0003000 {
 			compatible = "snps,oscilan";
-			reg = <0xc0003000 0x44>;
+			reg = <0xf0003000 0x44>;
 			interrupts = <7>, <8>;
 			interrupt-names = "rx", "tx";
 		};
Signature · 1 line
2.3.4
author
#106 lore raw

PATCH 106/155 cfg80211: Fix 160 MHz channels with 80+80 and 160 MHz drivers

In reply to Jiri Slaby

From: Jouni Malinen <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 08f6f147773b23b765b94633a8eaa82e7defcf4c upstream.

The VHT supported channel width field is a two bit integer, not a bitfield. cfg80211_chandef_usable() was interpreting it incorrectly and ended up rejecting 160 MHz channel width if the driver indicated support for both 160 and 80+80 MHz channels.

Fixes 3d9d1d6656a73 ("nl80211/cfg80211: support VHT channel configuration")

(however, no real drivers had 160 MHz support it until 3.16)

---
 net/wireless/chan.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
net/wireless/chan.c +6 -3
index 50f6195c8b70..e5af85d10212 100644
@@ -368,7 +368,7 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
 {
 	struct ieee80211_sta_ht_cap *ht_cap;
 	struct ieee80211_sta_vht_cap *vht_cap;
-	u32 width, control_freq;
+	u32 width, control_freq, cap;
 
 	if (WARN_ON(!cfg80211_chandef_valid(chandef)))
 		return false;
@@ -406,7 +406,8 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
 			return false;
 		break;
 	case NL80211_CHAN_WIDTH_80P80:
-		if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))
+		cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
+		if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
 			return false;
 	case NL80211_CHAN_WIDTH_80:
 		if (!vht_cap->vht_supported)
@@ -417,7 +418,9 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
 	case NL80211_CHAN_WIDTH_160:
 		if (!vht_cap->vht_supported)
 			return false;
-		if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ))
+		cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
+		if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ &&
+		    cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
 			return false;
 		prohibited_flags |= IEEE80211_CHAN_NO_160MHZ;
 		width = 160;
Signature · 1 line
2.3.4
author
#107 lore raw

PATCH 107/155 ARM: 7866/1: include: asm: use 'long long' instead of 'u64' within atomic.h

In reply to Jiri Slaby

From: Chen Gang <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 237f12337cfa2175474e4dd015bc07a25eb9080d upstream.

atomic* value is signed value, and atomic* functions need also process signed value (parameter value, and return value), so 32-bit arm need use 'long long' instead of 'u64'.

After replacement, it will also fix a bug for atomic64_add_negative():
"u64 is never less than 0".

The modifications are:

in vim, use "1,% s/\<u64\>/long long/g" command. remove '__aligned(8)' which is useless for 64-bit. be sure of 80 column limitation after replacement.

---
 arch/arm/include/asm/atomic.h | 49 ++++++++++++++++++++++---------------------
 1 file changed, 25 insertions(+), 24 deletions(-)
arch/arm/include/asm/atomic.h +25 -24
index da1c77d39327..a715ac049e4c 100644
@@ -238,15 +238,15 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
 
 #ifndef CONFIG_GENERIC_ATOMIC64
 typedef struct {
-	u64 __aligned(8) counter;
+	long long counter;
 } atomic64_t;
 
 #define ATOMIC64_INIT(i) { (i) }
 
 #ifdef CONFIG_ARM_LPAE
-static inline u64 atomic64_read(const atomic64_t *v)
+static inline long long atomic64_read(const atomic64_t *v)
 {
-	u64 result;
+	long long result;
 
 	__asm__ __volatile__("@ atomic64_read\n"
 "	ldrd	%0, %H0, [%1]"
@@ -257,7 +257,7 @@ static inline u64 atomic64_read(const atomic64_t *v)
 	return result;
 }
 
-static inline void atomic64_set(atomic64_t *v, u64 i)
+static inline void atomic64_set(atomic64_t *v, long long i)
 {
 	__asm__ __volatile__("@ atomic64_set\n"
 "	strd	%2, %H2, [%1]"
@@ -266,9 +266,9 @@ static inline void atomic64_set(atomic64_t *v, u64 i)
 	);
 }
 #else
-static inline u64 atomic64_read(const atomic64_t *v)
+static inline long long atomic64_read(const atomic64_t *v)
 {
-	u64 result;
+	long long result;
 
 	__asm__ __volatile__("@ atomic64_read\n"
 "	ldrexd	%0, %H0, [%1]"
@@ -279,9 +279,9 @@ static inline u64 atomic64_read(const atomic64_t *v)
 	return result;
 }
 
-static inline void atomic64_set(atomic64_t *v, u64 i)
+static inline void atomic64_set(atomic64_t *v, long long i)
 {
-	u64 tmp;
+	long long tmp;
 
 	__asm__ __volatile__("@ atomic64_set\n"
 "1:	ldrexd	%0, %H0, [%2]\n"
@@ -294,9 +294,9 @@ static inline void atomic64_set(atomic64_t *v, u64 i)
 }
 #endif
 
-static inline void atomic64_add(u64 i, atomic64_t *v)
+static inline void atomic64_add(long long i, atomic64_t *v)
 {
-	u64 result;
+	long long result;
 	unsigned long tmp;
 
 	__asm__ __volatile__("@ atomic64_add\n"
@@ -311,9 +311,9 @@ static inline void atomic64_add(u64 i, atomic64_t *v)
 	: "cc");
 }
 
-static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
+static inline long long atomic64_add_return(long long i, atomic64_t *v)
 {
-	u64 result;
+	long long result;
 	unsigned long tmp;
 
 	smp_mb();
@@ -334,9 +334,9 @@ static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
 	return result;
 }
 
-static inline void atomic64_sub(u64 i, atomic64_t *v)
+static inline void atomic64_sub(long long i, atomic64_t *v)
 {
-	u64 result;
+	long long result;
 	unsigned long tmp;
 
 	__asm__ __volatile__("@ atomic64_sub\n"
@@ -351,9 +351,9 @@ static inline void atomic64_sub(u64 i, atomic64_t *v)
 	: "cc");
 }
 
-static inline u64 atomic64_sub_return(u64 i, atomic64_t *v)
+static inline long long atomic64_sub_return(long long i, atomic64_t *v)
 {
-	u64 result;
+	long long result;
 	unsigned long tmp;
 
 	smp_mb();
@@ -374,9 +374,10 @@ static inline u64 atomic64_sub_return(u64 i, atomic64_t *v)
 	return result;
 }
 
-static inline u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old, u64 new)
+static inline long long atomic64_cmpxchg(atomic64_t *ptr, long long old,
+					long long new)
 {
-	u64 oldval;
+	long long oldval;
 	unsigned long res;
 
 	smp_mb();
@@ -398,9 +399,9 @@ static inline u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old, u64 new)
 	return oldval;
 }
 
-static inline u64 atomic64_xchg(atomic64_t *ptr, u64 new)
+static inline long long atomic64_xchg(atomic64_t *ptr, long long new)
 {
-	u64 result;
+	long long result;
 	unsigned long tmp;
 
 	smp_mb();
@@ -419,9 +420,9 @@ static inline u64 atomic64_xchg(atomic64_t *ptr, u64 new)
 	return result;
 }
 
-static inline u64 atomic64_dec_if_positive(atomic64_t *v)
+static inline long long atomic64_dec_if_positive(atomic64_t *v)
 {
-	u64 result;
+	long long result;
 	unsigned long tmp;
 
 	smp_mb();
@@ -445,9 +446,9 @@ static inline u64 atomic64_dec_if_positive(atomic64_t *v)
 	return result;
 }
 
-static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
+static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
 {
-	u64 val;
+	long long val;
 	unsigned long tmp;
 	int ret = 1;
 
Signature · 1 line
2.3.4
author
#108 lore raw

PATCH 108/155 ARM: 7867/1: include: asm: use 'int' instead of 'unsigned long' for 'oldval' in atomic_cmpxchg().

In reply to Jiri Slaby

From: Chen Gang <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 4dcc1cf7316a26e112f5c9fcca531ff98ef44700 upstream.

For atomic_cmpxchg(), the type of 'oldval' need be 'int' to match the type of "*ptr" (used by 'ldrex' instruction) and 'old' (used by 'teq' instruction).

---
 arch/arm/include/asm/atomic.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm/include/asm/atomic.h +2 -1
index a715ac049e4c..9ee7e01066f9 100644
@@ -114,7 +114,8 @@ static inline int atomic_sub_return(int i, atomic_t *v)
 
 static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
 {
-	unsigned long oldval, res;
+	int oldval;
+	unsigned long res;
 
 	smp_mb();
 
Signature · 1 line
2.3.4
author
#109 lore raw

PATCH 109/155 ARM: 7931/1: Correct virt_addr_valid

In reply to Jiri Slaby

From: Laura Abbott <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit efea3403d4b7c6d1dd5d5ac3234c161e8b314d66 upstream.

The definition of virt_addr_valid is that virt_addr_valid should return true if and only if virt_to_page returns a valid pointer. The current definition of virt_addr_valid only checks against the virtual address range. There's no guarantee that just because a virtual address falls bewteen PAGE_OFFSET and high_memory the associated physical memory has a valid backing struct page. Follow the example of other architectures and convert to pfn_valid to verify that the virtual address is actually valid. The check for an address between PAGE_OFFSET and high_memory is still necessary as vmalloc/highmem addresses are not valid with virt_to_page.

---
 arch/arm/include/asm/memory.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm/include/asm/memory.h +2 -1
index e750a938fd3c..152b8e67f8b8 100644
@@ -285,7 +285,8 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
 #define ARCH_PFN_OFFSET		PHYS_PFN_OFFSET
 
 #define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
-#define virt_addr_valid(kaddr)	((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory)
+#define virt_addr_valid(kaddr)	(((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) \
+					&& pfn_valid(__pa(kaddr) >> PAGE_SHIFT) )
 
 #endif
 
Signature · 1 line
2.3.4
author
#110 lore raw

PATCH 110/155 ARM: 8108/1: mm: Introduce {pte,pmd}_isset and {pte,pmd}_isclear

In reply to Jiri Slaby

From: Steven Capper <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit f2950706871c4b6e8c0f0d7c3f62d35930b8de63 upstream.

Long descriptors on ARM are 64 bits, and some pte functions such as pte_dirty return a bitwise-and of a flag with the pte value. If the flag to be tested resides in the upper 32 bits of the pte, then we run into the danger of the result being dropped if downcast.

For example:

	gather_stats(page, md, pte_dirty(*pte), 1);

where pte_dirty(*pte) is downcast to an int.

This patch introduces a new macro pte_isset which performs the bitwise and, then performs a double logical invert (where needed) to ensure predictable downcasting. The logical inverse pte_isclear is also introduced.

Equivalent pmd functions for Transparent HugePages have also been added.

---
 arch/arm/include/asm/pgtable-3level.h | 12 ++++++++----
 arch/arm/include/asm/pgtable.h        | 14 +++++++++-----
 2 files changed, 17 insertions(+), 9 deletions(-)
arch/arm/include/asm/pgtable-3level.h +8 -4
index ceb4807ee8b2..738a2e346e1c 100644
@@ -204,14 +204,18 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
 #define pte_huge(pte)		(pte_val(pte) && !(pte_val(pte) & PTE_TABLE_BIT))
 #define pte_mkhuge(pte)		(__pte(pte_val(pte) & ~PTE_TABLE_BIT))
 
-#define pmd_young(pmd)		(pmd_val(pmd) & PMD_SECT_AF)
+#define pmd_isset(pmd, val)	((u32)(val) == (val) ? pmd_val(pmd) & (val) \
+						: !!(pmd_val(pmd) & (val)))
+#define pmd_isclear(pmd, val)	(!(pmd_val(pmd) & (val)))
+
+#define pmd_young(pmd)		(pmd_isset((pmd), PMD_SECT_AF))
 
 #define __HAVE_ARCH_PMD_WRITE
-#define pmd_write(pmd)		(!(pmd_val(pmd) & PMD_SECT_RDONLY))
+#define pmd_write(pmd)		(pmd_isclear((pmd), PMD_SECT_RDONLY))
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
-#define pmd_trans_huge(pmd)	(pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
-#define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING)
+#define pmd_trans_huge(pmd)	(pmd_val(pmd) && !pmd_table(pmd))
+#define pmd_trans_splitting(pmd) (pmd_isset((pmd), PMD_SECT_SPLITTING))
 #endif
 
 #define PMD_BIT_FUNC(fn,op) \
arch/arm/include/asm/pgtable.h +9 -5
index 1571d126e9dd..a348bfd34f66 100644
@@ -214,12 +214,16 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
 
 #define pte_clear(mm,addr,ptep)	set_pte_ext(ptep, __pte(0), 0)
 
+#define pte_isset(pte, val)	((u32)(val) == (val) ? pte_val(pte) & (val) \
+						: !!(pte_val(pte) & (val)))
+#define pte_isclear(pte, val)	(!(pte_val(pte) & (val)))
+
 #define pte_none(pte)		(!pte_val(pte))
-#define pte_present(pte)	(pte_val(pte) & L_PTE_PRESENT)
-#define pte_write(pte)		(!(pte_val(pte) & L_PTE_RDONLY))
-#define pte_dirty(pte)		(pte_val(pte) & L_PTE_DIRTY)
-#define pte_young(pte)		(pte_val(pte) & L_PTE_YOUNG)
-#define pte_exec(pte)		(!(pte_val(pte) & L_PTE_XN))
+#define pte_present(pte)	(pte_isset((pte), L_PTE_PRESENT))
+#define pte_write(pte)		(pte_isclear((pte), L_PTE_RDONLY))
+#define pte_dirty(pte)		(pte_isset((pte), L_PTE_DIRTY))
+#define pte_young(pte)		(pte_isset((pte), L_PTE_YOUNG))
+#define pte_exec(pte)		(pte_isclear((pte), L_PTE_XN))
 #define pte_special(pte)	(0)
 
 #define pte_present_user(pte)  (pte_present(pte) && (pte_val(pte) & L_PTE_USER))
Signature · 1 line
2.3.4
author
#111 lore raw

PATCH 111/155 ARM: 8109/1: mm: Modify pte_write and pmd_write logic for LPAE

In reply to Jiri Slaby

From: Steven Capper <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit ded9477984690d026e46dd75e8157392cea3f13f upstream.

For LPAE, we have the following means for encoding writable or dirty ptes:

                              L_PTE_DIRTY       L_PTE_RDONLY
    !pte_dirty && !pte_write        0               1
    !pte_dirty && pte_write         0               1
    pte_dirty && !pte_write         1               1
    pte_dirty && pte_write          1               0

So we can't distinguish between writeable clean ptes and read only ptes. This can cause problems with ptes being incorrectly flagged as read only when they are writeable but not dirty.

This patch renumbers L_PTE_RDONLY from AP[2] to a software bit #58, and adds additional logic to set AP[2] whenever the pte is read only or not dirty. That way we can distinguish between clean writeable ptes and read only ptes.

HugeTLB pages will use this new logic automatically.

We need to add some logic to Transparent HugePages to ensure that they correctly interpret the revised pgprot permissions (L_PTE_RDONLY has moved and no longer matches PMD_SECT_AP2). In the process of revising THP, the names of the PMD software bits have been prefixed with L_ to make them easier to distinguish from their hardware bit counterparts.

---
 arch/arm/include/asm/pgtable-3level-hwdef.h |  3 ++-
 arch/arm/include/asm/pgtable-3level.h       | 41 +++++++++++++++++------------
 arch/arm/mm/proc-v7-3level.S                |  9 +++++--
 3 files changed, 33 insertions(+), 20 deletions(-)
arch/arm/include/asm/pgtable-3level-hwdef.h +2 -1
index 626989fec4d3..9fd61c72a33a 100644
@@ -43,7 +43,7 @@
 #define PMD_SECT_BUFFERABLE	(_AT(pmdval_t, 1) << 2)
 #define PMD_SECT_CACHEABLE	(_AT(pmdval_t, 1) << 3)
 #define PMD_SECT_USER		(_AT(pmdval_t, 1) << 6)		/* AP[1] */
-#define PMD_SECT_RDONLY		(_AT(pmdval_t, 1) << 7)		/* AP[2] */
+#define PMD_SECT_AP2		(_AT(pmdval_t, 1) << 7)		/* read only */
 #define PMD_SECT_S		(_AT(pmdval_t, 3) << 8)
 #define PMD_SECT_AF		(_AT(pmdval_t, 1) << 10)
 #define PMD_SECT_nG		(_AT(pmdval_t, 1) << 11)
@@ -72,6 +72,7 @@
 #define PTE_TABLE_BIT		(_AT(pteval_t, 1) << 1)
 #define PTE_BUFFERABLE		(_AT(pteval_t, 1) << 2)		/* AttrIndx[0] */
 #define PTE_CACHEABLE		(_AT(pteval_t, 1) << 3)		/* AttrIndx[1] */
+#define PTE_AP2			(_AT(pteval_t, 1) << 7)		/* AP[2] */
 #define PTE_EXT_SHARED		(_AT(pteval_t, 3) << 8)		/* SH[1:0], inner shareable */
 #define PTE_EXT_AF		(_AT(pteval_t, 1) << 10)	/* Access Flag */
 #define PTE_EXT_NG		(_AT(pteval_t, 1) << 11)	/* nG */
arch/arm/include/asm/pgtable-3level.h +24 -17

79 lines not on this page · raw message

arch/arm/mm/proc-v7-3level.S +7 -2
index 22e3ad63500c..eb81123a845d 100644
@@ -86,8 +86,13 @@ ENTRY(cpu_v7_set_pte_ext)
 	tst	rh, #1 << (57 - 32)		@ L_PTE_NONE
 	bicne	rl, #L_PTE_VALID
 	bne	1f
-	tst	rh, #1 << (55 - 32)		@ L_PTE_DIRTY
-	orreq	rl, #L_PTE_RDONLY
+
+	eor	ip, rh, #1 << (55 - 32)	@ toggle L_PTE_DIRTY in temp reg to
+					@ test for !L_PTE_DIRTY || L_PTE_RDONLY
+	tst	ip, #1 << (55 - 32) | 1 << (58 - 32)
+	orrne	rl, #PTE_AP2
+	biceq	rl, #PTE_AP2
+
 1:	strd	r2, r3, [r0]
 	ALT_SMP(W(nop))
 	ALT_UP (mcr	p15, 0, r0, c7, c10, 1)		@ flush_pte
Signature · 1 line
2.3.4
author
#112 lore raw

PATCH 112/155 powerpc/smp: Wait until secondaries are active & online

In reply to Jiri Slaby

From: Michael Ellerman <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 875ebe940d77a41682c367ad799b4f39f128d3fa upstream.

Anton has a busy ppc64le KVM box where guests sometimes hit the infamous "kernel BUG at kernel/smpboot.c:134!" issue during boot:

  BUG_ON(td->cpu != smp_processor_id());

Basically a per CPU hotplug thread scheduled on the wrong CPU. The oops output confirms it:

  CPU: 0
  Comm: watchdog/130

The problem is that we aren't ensuring the CPU active bit is set for the secondary before allowing the master to continue on. The master unparks the secondary CPU's kthreads and the scheduler looks for a CPU to run on. It calls select_task_rq() and realises the suggested CPU is not in the cpus_allowed mask. It then ends up in select_fallback_rq(), and since the active bit isnt't set we choose some other CPU to run on.

This seems to have been introduced by 6acbfb96976f "sched: Fix hotplug vs. set_cpus_allowed_ptr()", which changed from setting active before online to setting active after online. However that was in turn fixing a bug where other code assumed an active CPU was also online, so we can't just revert that fix.

The simplest fix is just to spin waiting for both active & online to be set. We already have a barrier prior to set_cpu_online() (which also sets active), to ensure all other setup is completed before online & active are set.

Fixes 6acbfb96976f ("sched: Fix hotplug vs. set_cpus_allowed_ptr()")
---
 arch/powerpc/kernel/smp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/powerpc/kernel/smp.c +2 -2
index 8e59abc237d7..0732d75ca84a 100644
@@ -567,8 +567,8 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 	if (smp_ops->give_timebase)
 		smp_ops->give_timebase();
 
-	/* Wait until cpu puts itself in the online map */
-	while (!cpu_online(cpu))
+	/* Wait until cpu puts itself in the online & active maps */
+	while (!cpu_online(cpu) || !cpu_active(cpu))
 		cpu_relax();
 
 	return 0;
Signature · 1 line
2.3.4
author
#113 lore raw

PATCH 113/155 module: set nx before marking module MODULE_STATE_COMING.

In reply to Jiri Slaby

From: Rusty Russell <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 4982223e51e8ea9d09bb33c8323b5ec1877b2b51 upstream.

We currently set RO & NX on modules very late: after we move them from MODULE_STATE_UNFORMED to MODULE_STATE_COMING, and after we call parse_args() (which can exec code in the module).

Much better is to do it in complete_formation() and then call the notifier.

This means that the notifiers will be called on a module which is already RO & NX, so that may cause problems (ftrace already changed so they're unaffected).

---
 kernel/module.c | 32 +++++++++++++++++---------------
 1 file changed, 17 insertions(+), 15 deletions(-)
kernel/module.c +17 -15
index f3c612e45330..3edb91fabc7a 100644
@@ -3048,21 +3048,6 @@ static int do_init_module(struct module *mod)
 	 */
 	current->flags &= ~PF_USED_ASYNC;
 
-	blocking_notifier_call_chain(&module_notify_list,
-			MODULE_STATE_COMING, mod);
-
-	/* Set RO and NX regions for core */
-	set_section_ro_nx(mod->module_core,
-				mod->core_text_size,
-				mod->core_ro_size,
-				mod->core_size);
-
-	/* Set RO and NX regions for init */
-	set_section_ro_nx(mod->module_init,
-				mod->init_text_size,
-				mod->init_ro_size,
-				mod->init_size);
-
 	do_mod_ctors(mod);
 	/* Start the module */
 	if (mod->init != NULL)
@@ -3194,9 +3179,26 @@ static int complete_formation(struct module *mod, struct load_info *info)
 	/* This relies on module_mutex for list integrity. */
 	module_bug_finalize(info->hdr, info->sechdrs, mod);
 
+	/* Set RO and NX regions for core */
+	set_section_ro_nx(mod->module_core,
+				mod->core_text_size,
+				mod->core_ro_size,
+				mod->core_size);
+
+	/* Set RO and NX regions for init */
+	set_section_ro_nx(mod->module_init,
+				mod->init_text_size,
+				mod->init_ro_size,
+				mod->init_size);
+
 	/* Mark state as coming so strong_try_module_get() ignores us,
 	 * but kallsyms etc. can see us. */
 	mod->state = MODULE_STATE_COMING;
+	mutex_unlock(&module_mutex);
+
+	blocking_notifier_call_chain(&module_notify_list,
+				     MODULE_STATE_COMING, mod);
+	return 0;
 
 out:
 	mutex_unlock(&module_mutex);
Signature · 1 line
2.3.4
author
#114 lore raw

PATCH 114/155 module: Clean up ro/nx after early module load failures

In reply to Jiri Slaby

From: Andy Lutomirski <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit ff7e0055bb5ddbbb320cdd8dfd3e18672bddd2ad upstream.

The commit

4982223e51e8 module: set nx before marking module MODULE_STATE_COMING.

introduced a regression: if a module fails to parse its arguments or if mod_sysfs_setup fails, then the module's memory will be freed while still read-only. Anything that reuses that memory will crash as soon as it tries to write to it.

---
 kernel/module.c | 5 +++++
 1 file changed, 5 insertions(+)
kernel/module.c +5 -0
index 3edb91fabc7a..a97785308f25 100644
@@ -3332,6 +3332,11 @@ static int load_module(struct load_info *info, const char __user *uargs,
 	mutex_lock(&module_mutex);
 	module_bug_cleanup(mod);
 	mutex_unlock(&module_mutex);
+
+	/* we can't deallocate the module until we clear memory protection */
+	unset_module_init_ro_nx(mod);
+	unset_module_core_ro_nx(mod);
+
  ddebug_cleanup:
 	dynamic_debug_remove(info->debug);
 	synchronize_sched();
Signature · 1 line
2.3.4
author
#115 lore raw

PATCH 115/155 x86/microcode/intel: Guard against stack overflow in the loader

In reply to Jiri Slaby

From: Quentin Casasnovas <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit f84598bd7c851f8b0bf8cd0d7c3be0d73c432ff4 upstream.

mc_saved_tmp is a static array allocated on the stack, we need to make sure mc_saved_count stays within its bounds, otherwise we're overflowing the stack in _save_mc(). A specially crafted microcode header could lead to a kernel crash or potentially kernel execution.

---
 arch/x86/kernel/microcode_intel_early.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/microcode_intel_early.c +1 -1
index 1575deb2e636..c44f7db7ce44 100644
@@ -321,7 +321,7 @@ get_matching_model_microcode(int cpu, unsigned long start,
 	unsigned int mc_saved_count = mc_saved_data->mc_saved_count;
 	int i;
 
-	while (leftover) {
+	while (leftover && mc_saved_count < ARRAY_SIZE(mc_saved_tmp)) {
 		mc_header = (struct microcode_header_intel *)ucode_ptr;
 
 		mc_size = get_totalsize(mc_header);
Signature · 1 line
2.3.4
author
#116 lore raw

PATCH 116/155 powerpc: Fix sys_call_table declaration to enable syscall tracing

In reply to Jiri Slaby

From: Romeo Cane <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 1028ccf560b97adbf272381a61a67e17d44d1054 upstream.

Declaring sys_call_table as a pointer causes the compiler to generate the wrong lookup code in arch_syscall_addr().

     <arch_syscall_addr>:
        lis     r9,-16384
        rlwinm  r3,r3,2,0,29
  -     lwz     r11,30640(r9)
  -     lwzx    r3,r11,r3
  +     addi    r9,r9,30640
  +     lwzx    r3,r9,r3

blr

The actual sys_call_table symbol, declared in assembler, is an array. If we lie about that to the compiler we get the wrong code generated, as above.

This definition seems only to be used by the syscall tracing code in kernel/trace/trace_syscalls.c. With this patch I can successfully use the syscall tracepoints:

  bash-3815  [002] ....   333.239082: sys_write -> 0x2
  bash-3815  [002] ....   333.239087: sys_dup2(oldfd: a, newfd: 1)
  bash-3815  [002] ....   333.239088: sys_dup2 -> 0x1
  bash-3815  [002] ....   333.239092: sys_fcntl(fd: a, cmd: 1, arg: 0)
  bash-3815  [002] ....   333.239093: sys_fcntl -> 0x1
  bash-3815  [002] ....   333.239094: sys_close(fd: a)
  bash-3815  [002] ....   333.239094: sys_close -> 0x0
---
 arch/powerpc/include/asm/syscall.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/include/asm/syscall.h +1 -1
index b54b2add07be..528ba9d8eed5 100644
@@ -17,7 +17,7 @@
 
 /* ftrace syscalls requires exporting the sys_call_table */
 #ifdef CONFIG_FTRACE_SYSCALLS
-extern const unsigned long *sys_call_table;
+extern const unsigned long sys_call_table[];
 #endif /* CONFIG_FTRACE_SYSCALLS */
 
 static inline long syscall_get_nr(struct task_struct *task,
Signature · 1 line
2.3.4
author
#117 lore raw

PATCH 117/155 intel_idle: Add CPU model 54 (Atom N2000 series)

In reply to Jiri Slaby

From: Jan Kiszka <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit acead1b0fac5b10d0ae3f1cc5f7820b9f9f924f5 upstream.

Add CPU ID for Atom N2600/N2800 processors. Datasheets indicate support for this, detailed information about potential quirks or limitations are missing, though. So we just reuse the definition for the previous ATOM series. Tests on N2800 systems showed that this addition is fine an can reduce power consumption by about 0.25 W (personally confirmed on Intel DN2800MT).

---
 drivers/idle/intel_idle.c | 1 +
 1 file changed, 1 insertion(+)
drivers/idle/intel_idle.c +1 -0
index 97f4e807c862..7be7ddf47797 100644
@@ -503,6 +503,7 @@ static const struct x86_cpu_id intel_idle_ids[] = {
 	ICPU(0x2f, idle_cpu_nehalem),
 	ICPU(0x2a, idle_cpu_snb),
 	ICPU(0x2d, idle_cpu_snb),
+	ICPU(0x36, idle_cpu_atom),
 	ICPU(0x3a, idle_cpu_ivb),
 	ICPU(0x3e, idle_cpu_ivb),
 	ICPU(0x3c, idle_cpu_hsw),
Signature · 1 line
2.3.4
author
#118 lore raw

PATCH 118/155 iommu/core: Check for the right function pointer in iommu_map()

In reply to Jiri Slaby

From: Joerg Roedel <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 9db4ad9183aad0e9567f6afb23db1bdc9aa6c2a9 upstream.

Check for the ->map and not the ->unmap pointer.

---
 drivers/iommu/iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/iommu.c +1 -1
index fbe9ca734f8f..9d71a57c96b1 100644
@@ -794,7 +794,7 @@ int iommu_map(struct iommu_domain *domain, unsigned long iova,
 	size_t orig_size = size;
 	int ret = 0;
 
-	if (unlikely(domain->ops->unmap == NULL ||
+	if (unlikely(domain->ops->map == NULL ||
 		     domain->ops->pgsize_bitmap == 0UL))
 		return -ENODEV;
 
Signature · 1 line
2.3.4
author
#119 lore raw

PATCH 119/155 x86/irq: Check for valid irq descriptor in check_irq_vectors_for_cpu_disable()

In reply to Jiri Slaby

From: Joerg Roedel <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit d97eb8966c91f2c9d05f0a22eb89ed5b76d966d1 upstream.

When an interrupt is migrated away from a cpu it will stay in its vector_irq array until smp_irq_move_cleanup_interrupt succeeded. The cfg->move_in_progress flag is cleared already when the IPI was sent.

When the interrupt is destroyed after migration its 'struct irq_desc' is freed and the vector_irq arrays are cleaned up. But since cfg->move_in_progress is already 0 the references at cpus before the last migration will not be cleared. So this would leave a reference to an already destroyed irq alive.

When the cpu is taken down at this point, the check_irq_vectors_for_cpu_disable() function finds a valid irq number in the vector_irq array, but gets NULL for its descriptor and dereferences it, causing a kernel panic.

This has been observed on real systems at shutdown. Add a check to check_irq_vectors_for_cpu_disable() for a valid 'struct irq_desc' to prevent this issue.

---
 arch/x86/kernel/irq.c | 3 +++
 1 file changed, 3 insertions(+)
arch/x86/kernel/irq.c +3 -0
index 39100783cf26..549b119ed781 100644
@@ -291,6 +291,9 @@ int check_irq_vectors_for_cpu_disable(void)
 		irq = __this_cpu_read(vector_irq[vector]);
 		if (irq >= 0) {
 			desc = irq_to_desc(irq);
+			if (!desc)
+				continue;
+
 			data = irq_desc_get_irq_data(desc);
 			cpumask_copy(&affinity_new, data->affinity);
 			cpu_clear(this_cpu, affinity_new);
Signature · 1 line
2.3.4
author
#120 lore raw

PATCH 120/155 core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle errors

In reply to Jiri Slaby

From: Zoltan Kiss <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 36d5fe6a000790f56039afe26834265db0a3ad4c upstream.

skb_zerocopy can copy elements of the frags array between skbs, but it doesn't orphan them. Also, it doesn't handle errors, so this patch takes care of that as well, and modify the callers accordingly. skb_tx_error() is also added to the callers so they will signal the failed delivery towards the creator of the skb.

[bwh: Backported to 3.13: skb_zerocopy() is new in 3.14, but was moved from a
static function in nfnetlink_queue. We need to patch that and its caller, but not openvswitch.]

---
 net/netfilter/nfnetlink_queue_core.c | 29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)
net/netfilter/nfnetlink_queue_core.c +21 -8
index ae2e5c11d01a..f5c34db24498 100644
@@ -235,22 +235,23 @@ nfqnl_flush(struct nfqnl_instance *queue, nfqnl_cmpfn cmpfn, unsigned long data)
 	spin_unlock_bh(&queue->lock);
 }
 
-static void
+static int
 nfqnl_zcopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen)
 {
 	int i, j = 0;
 	int plen = 0; /* length of skb->head fragment */
+	int ret;
 	struct page *page;
 	unsigned int offset;
 
 	/* dont bother with small payloads */
-	if (len <= skb_tailroom(to)) {
-		skb_copy_bits(from, 0, skb_put(to, len), len);
-		return;
-	}
+	if (len <= skb_tailroom(to))
+		return skb_copy_bits(from, 0, skb_put(to, len), len);
 
 	if (hlen) {
-		skb_copy_bits(from, 0, skb_put(to, hlen), hlen);
+		ret = skb_copy_bits(from, 0, skb_put(to, hlen), hlen);
+		if (unlikely(ret))
+			return ret;
 		len -= hlen;
 	} else {
 		plen = min_t(int, skb_headlen(from), len);
@@ -268,6 +269,11 @@ nfqnl_zcopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen)
 	to->len += len + plen;
 	to->data_len += len + plen;
 
+	if (unlikely(skb_orphan_frags(from, GFP_ATOMIC))) {
+		skb_tx_error(from);
+		return -ENOMEM;
+	}
+
 	for (i = 0; i < skb_shinfo(from)->nr_frags; i++) {
 		if (!len)
 			break;
@@ -278,6 +284,8 @@ nfqnl_zcopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen)
 		j++;
 	}
 	skb_shinfo(to)->nr_frags = j;
+
+	return 0;
 }
 
 static int
@@ -374,13 +382,16 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
 
 	skb = nfnetlink_alloc_skb(&init_net, size, queue->peer_portid,
 				  GFP_ATOMIC);
-	if (!skb)
+	if (!skb) {
+		skb_tx_error(entskb);
 		return NULL;
+	}
 
 	nlh = nlmsg_put(skb, 0, 0,
 			NFNL_SUBSYS_QUEUE << 8 | NFQNL_MSG_PACKET,
 			sizeof(struct nfgenmsg), 0);
 	if (!nlh) {
+		skb_tx_error(entskb);
 		kfree_skb(skb);
 		return NULL;
 	}
@@ -504,13 +515,15 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
 		nla->nla_type = NFQA_PAYLOAD;
 		nla->nla_len = nla_attr_size(data_len);
 
-		nfqnl_zcopy(skb, entskb, data_len, hlen);
+		if (nfqnl_zcopy(skb, entskb, data_len, hlen))
+			goto nla_put_failure;
 	}
 
 	nlh->nlmsg_len = skb->len;
 	return skb;
 
 nla_put_failure:
+	skb_tx_error(entskb);
 	kfree_skb(skb);
 	net_err_ratelimited("nf_queue: error creating packet message\n");
 	return NULL;
Signature · 1 line
2.3.4
author
#121 lore raw

PATCH 121/155 ipv6: reallocate addrconf router for ipv6 address when lo device up

In reply to Jiri Slaby

From: Gao feng <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 33d99113b1102c2d2f8603b9ba72d89d915c13f5 upstream.

commit 25fb6ca4ed9cad72f14f61629b68dc03c0d9713f
"net IPv6 : Fix broken IPv6 routing table after loopback down-up" allocates addrconf router for ipv6 address when lo device up. but commit a881ae1f625c599b460cc8f8a7fcb1c438f699ad "ipv6:don't call addrconf_dst_alloc again when enable lo" breaks this behavior.

Since the addrconf router is moved to the garbage list when lo device down, we should release this router and rellocate a new one for ipv6 address when lo device up.

This patch solves bug 67951 on bugzilla
https://bugzilla.kernel.org/show_bug.cgi?id=67951

change from v1:
use ip6_rt_put to repleace ip6_del_rt, thanks Hannes! change code style, suggested by Sergei.

---
 net/ipv6/addrconf.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
net/ipv6/addrconf.c +12 -2
index 5dac9fd72465..87f1a70bd234 100644
@@ -2641,8 +2641,18 @@ static void init_loopback(struct net_device *dev)
 			if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE))
 				continue;
 
-			if (sp_ifa->rt)
-				continue;
+			if (sp_ifa->rt) {
+				/* This dst has been added to garbage list when
+				 * lo device down, release this obsolete dst and
+				 * reallocate a new router for ifa.
+				 */
+				if (sp_ifa->rt->dst.obsolete > 0) {
+					ip6_rt_put(sp_ifa->rt);
+					sp_ifa->rt = NULL;
+				} else {
+					continue;
+				}
+			}
 
 			sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0);
 
Signature · 1 line
2.3.4
author
#122 lore raw

PATCH 122/155 dns_resolver: Null-terminate the right string

In reply to Jiri Slaby

From: Ben Hutchings <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 640d7efe4c08f06c4ae5d31b79bd8740e7f6790a upstream.

*_result[len] is parsed as *(_result[len]) which is not at all what we want to touch here.

Fixes 84a7c0b1db1c ("dns_resolver: assure that dns_query() result is null-terminated")
---
 net/dns_resolver/dns_query.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/dns_resolver/dns_query.c +1 -1
index ede0e2d7412e..2022b46ab38f 100644
@@ -151,7 +151,7 @@ int dns_query(const char *type, const char *name, size_t namelen,
 		goto put;
 
 	memcpy(*_result, upayload->data, len);
-	*_result[len] = '\0';
+	(*_result)[len] = '\0';
 
 	if (_expiry)
 		*_expiry = rkey->expiry;
Signature · 1 line
2.3.4
author
#123 lore raw

PATCH 123/155 net: mvneta: Fix big endian issue in mvneta_txq_desc_csum()

In reply to Jiri Slaby

From: Thomas Fitzsimmons <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 0a1985879437d14bda8c90d0dae3455c467d7642 upstream.

This commit fixes the command value generated for CSUM calculation when running in big endian mode. The Ethernet protocol ID for IP was being unconditionally byte-swapped in the layer 3 protocol check (with swab16), which caused the mvneta driver to not function correctly in big endian mode. This patch byte-swaps the ID conditionally with htons.

---
 drivers/net/ethernet/marvell/mvneta.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/marvell/mvneta.c +1 -1
index 9c66d3168911..834b71d1c668 100644
@@ -1182,7 +1182,7 @@ static u32 mvneta_txq_desc_csum(int l3_offs, int l3_proto,
 	command =  l3_offs    << MVNETA_TX_L3_OFF_SHIFT;
 	command |= ip_hdr_len << MVNETA_TX_IP_HLEN_SHIFT;
 
-	if (l3_proto == swab16(ETH_P_IP))
+	if (l3_proto == htons(ETH_P_IP))
 		command |= MVNETA_TXD_IP_CSUM;
 	else
 		command |= MVNETA_TX_L3_IP6;
Signature · 1 line
2.3.4
author
#124 lore raw

PATCH 124/155 net: fix sparse warning in sk_dst_set()

In reply to Jiri Slaby

From: Eric Dumazet <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 5925a0555bdaf0b396a84318cbc21ba085f6c0d3 upstream.

sk_dst_cache has __rcu annotation, so we need a cast to avoid following sparse error :

include/net/sock.h:1774:19: warning: incorrect type in initializer (different address spaces)
include/net/sock.h:1774:19: expected struct dst_entry [noderef] <asn:4>*__ret
include/net/sock.h:1774:19: got struct dst_entry *dst

Fixes 7f502361531e ("ipv4: irq safe sk_dst_[re]set() and ipv4_sk_update_pmtu() fix")
---
 include/net/sock.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/net/sock.h +1 -1
index 3899018a6b21..d157f4f56f01 100644
@@ -1791,7 +1791,7 @@ sk_dst_set(struct sock *sk, struct dst_entry *dst)
 	struct dst_entry *old_dst;
 
 	sk_tx_queue_clear(sk);
-	old_dst = xchg(&sk->sk_dst_cache, dst);
+	old_dst = xchg((__force struct dst_entry **)&sk->sk_dst_cache, dst);
 	dst_release(old_dst);
 }
 
Signature · 1 line
2.3.4
author
#125 lore raw

PATCH 125/155 net/mlx4_core: pass pci_device_id.driver_data to __mlx4_init_one during reset

In reply to Jiri Slaby

From: Wei Yang <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 97a5221f56bad2e1c7e8ab55da4ac4748ef59c64 upstream.

The second parameter of __mlx4_init_one() is used to identify whether the pci_dev is a PF or VF. Currently, when it is invoked in mlx4_pci_slot_reset() this information is missed.

This patch match the pci_dev with mlx4_pci_table and passes the pci_device_id.driver_data to __mlx4_init_one() in mlx4_pci_slot_reset().

---
 drivers/net/ethernet/mellanox/mlx4/main.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx4/main.c +5 -1
index 60c9f4f103fc..4aa9d48ef72b 100644
@@ -2525,7 +2525,11 @@ static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev,
 
 static pci_ers_result_t mlx4_pci_slot_reset(struct pci_dev *pdev)
 {
-	int ret = __mlx4_init_one(pdev, 0);
+	const struct pci_device_id *id;
+	int ret;
+
+	id = pci_match_id(mlx4_pci_table, pdev);
+	ret = __mlx4_init_one(pdev, id->driver_data);
 
 	return ret ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
 }
Signature · 1 line
2.3.4
author
#126 lore raw

PATCH 126/155 net/mlx4_core: Preserve pci_dev_data after __mlx4_remove_one()

In reply to Jiri Slaby

From: Wei Yang <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

[ Upstream commit befdf8978accecac2e0739e6b5075afc62db37fe ]

pci_match_id() just match the static pci_device_id, which may return NULL if someone binds the driver to a device manually using /sys/bus/pci/drivers/.../new_id.

This patch wrap up a helper function __mlx4_remove_one() which does the tear down function but preserve the drv_data. Functions like mlx4_pci_err_detected() and mlx4_restart_one() will call this one with out releasing drvdata.

Fixes 97a5221 "net/mlx4_core: pass pci_device_id.driver_data to __mlx4_init_one during reset".
---
 drivers/net/ethernet/mellanox/mlx4/main.c | 170 +++++++++++++++++-------------
 drivers/net/ethernet/mellanox/mlx4/mlx4.h |   1 +
 2 files changed, 95 insertions(+), 76 deletions(-)
drivers/net/ethernet/mellanox/mlx4/main.c +94 -76
index 4aa9d48ef72b..d98586085cab 100644
@@ -2134,13 +2134,8 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)
 	/* Allow large DMA segments, up to the firmware limit of 1 GB */
 	dma_set_max_seg_size(&pdev->dev, 1024 * 1024 * 1024);
 
-	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-	if (!priv) {
-		err = -ENOMEM;
-		goto err_release_regions;
-	}
-
-	dev       = &priv->dev;
+	dev       = pci_get_drvdata(pdev);
+	priv      = mlx4_priv(dev);
 	dev->pdev = pdev;
 	INIT_LIST_HEAD(&priv->ctx_list);
 	spin_lock_init(&priv->ctx_lock);
@@ -2308,8 +2303,7 @@ slave_start:
 	mlx4_sense_init(dev);
 	mlx4_start_sense(dev);
 
-	priv->pci_dev_data = pci_dev_data;
-	pci_set_drvdata(pdev, dev);
+	priv->removed = 0;
 
 	return 0;
 
@@ -2375,84 +2369,108 @@ err_disable_pdev:
 
 static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
+	struct mlx4_priv *priv;
+	struct mlx4_dev *dev;
+
 	printk_once(KERN_INFO "%s", mlx4_version);
 
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	dev       = &priv->dev;
+	pci_set_drvdata(pdev, dev);
+	priv->pci_dev_data = id->driver_data;
+
 	return __mlx4_init_one(pdev, id->driver_data);
 }
 
-static void mlx4_remove_one(struct pci_dev *pdev)
+static void __mlx4_remove_one(struct pci_dev *pdev)
 {
 	struct mlx4_dev  *dev  = pci_get_drvdata(pdev);
 	struct mlx4_priv *priv = mlx4_priv(dev);
+	int               pci_dev_data;
 	int p;
 
-	if (dev) {
-		/* in SRIOV it is not allowed to unload the pf's
-		 * driver while there are alive vf's */
-		if (mlx4_is_master(dev)) {
-			if (mlx4_how_many_lives_vf(dev))
-				printk(KERN_ERR "Removing PF when there are assigned VF's !!!\n");
-		}
-		mlx4_stop_sense(dev);
-		mlx4_unregister_device(dev);
+	if (priv->removed)
+		return;
 
-		for (p = 1; p <= dev->caps.num_ports; p++) {
-			mlx4_cleanup_port_info(&priv->port[p]);
-			mlx4_CLOSE_PORT(dev, p);
-		}
+	pci_dev_data = priv->pci_dev_data;
 
-		if (mlx4_is_master(dev))
-			mlx4_free_resource_tracker(dev,
-						   RES_TR_FREE_SLAVES_ONLY);
-
-		mlx4_cleanup_counters_table(dev);
-		mlx4_cleanup_qp_table(dev);
-		mlx4_cleanup_srq_table(dev);
-		mlx4_cleanup_cq_table(dev);
-		mlx4_cmd_use_polling(dev);
-		mlx4_cleanup_eq_table(dev);
-		mlx4_cleanup_mcg_table(dev);
-		mlx4_cleanup_mr_table(dev);
-		mlx4_cleanup_xrcd_table(dev);
-		mlx4_cleanup_pd_table(dev);
+	/* in SRIOV it is not allowed to unload the pf's
+	 * driver while there are alive vf's */
+	if (mlx4_is_master(dev) && mlx4_how_many_lives_vf(dev))
+		printk(KERN_ERR "Removing PF when there are assigned VF's !!!\n");
+	mlx4_stop_sense(dev);
+	mlx4_unregister_device(dev);
 
-		if (mlx4_is_master(dev))
-			mlx4_free_resource_tracker(dev,
-						   RES_TR_FREE_STRUCTS_ONLY);
-
-		iounmap(priv->kar);
-		mlx4_uar_free(dev, &priv->driver_uar);
-		mlx4_cleanup_uar_table(dev);
-		if (!mlx4_is_slave(dev))
-			mlx4_clear_steering(dev);
-		mlx4_free_eq_table(dev);
-		if (mlx4_is_master(dev))
-			mlx4_multi_func_cleanup(dev);
-		mlx4_close_hca(dev);
-		if (mlx4_is_slave(dev))
-			mlx4_multi_func_cleanup(dev);
-		mlx4_cmd_cleanup(dev);
-
-		if (dev->flags & MLX4_FLAG_MSI_X)
-			pci_disable_msix(pdev);
-		if (dev->flags & MLX4_FLAG_SRIOV) {
-			mlx4_warn(dev, "Disabling SR-IOV\n");
-			pci_disable_sriov(pdev);
-		}
+	for (p = 1; p <= dev->caps.num_ports; p++) {
+		mlx4_cleanup_port_info(&priv->port[p]);
+		mlx4_CLOSE_PORT(dev, p);
+	}
 
-		if (!mlx4_is_slave(dev))
-			mlx4_free_ownership(dev);
+	if (mlx4_is_master(dev))
+		mlx4_free_resource_tracker(dev,
+					   RES_TR_FREE_SLAVES_ONLY);
+
+	mlx4_cleanup_counters_table(dev);
+	mlx4_cleanup_qp_table(dev);
+	mlx4_cleanup_srq_table(dev);
+	mlx4_cleanup_cq_table(dev);
+	mlx4_cmd_use_polling(dev);
+	mlx4_cleanup_eq_table(dev);
+	mlx4_cleanup_mcg_table(dev);
+	mlx4_cleanup_mr_table(dev);
+	mlx4_cleanup_xrcd_table(dev);
+	mlx4_cleanup_pd_table(dev);
 
-		kfree(dev->caps.qp0_tunnel);
-		kfree(dev->caps.qp0_proxy);
-		kfree(dev->caps.qp1_tunnel);
-		kfree(dev->caps.qp1_proxy);
+	if (mlx4_is_master(dev))
+		mlx4_free_resource_tracker(dev,
+					   RES_TR_FREE_STRUCTS_ONLY);
 
-		kfree(priv);
-		pci_release_regions(pdev);
-		pci_disable_device(pdev);
-		pci_set_drvdata(pdev, NULL);
+	iounmap(priv->kar);
+	mlx4_uar_free(dev, &priv->driver_uar);
+	mlx4_cleanup_uar_table(dev);
+	if (!mlx4_is_slave(dev))
+		mlx4_clear_steering(dev);
+	mlx4_free_eq_table(dev);
+	if (mlx4_is_master(dev))
+		mlx4_multi_func_cleanup(dev);
+	mlx4_close_hca(dev);
+	if (mlx4_is_slave(dev))
+		mlx4_multi_func_cleanup(dev);
+	mlx4_cmd_cleanup(dev);
+
+	if (dev->flags & MLX4_FLAG_MSI_X)
+		pci_disable_msix(pdev);
+	if (dev->flags & MLX4_FLAG_SRIOV) {
+		mlx4_warn(dev, "Disabling SR-IOV\n");
+		pci_disable_sriov(pdev);
 	}
+
+	if (!mlx4_is_slave(dev))
+		mlx4_free_ownership(dev);
+
+	kfree(dev->caps.qp0_tunnel);
+	kfree(dev->caps.qp0_proxy);
+	kfree(dev->caps.qp1_tunnel);
+	kfree(dev->caps.qp1_proxy);
+
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+	memset(priv, 0, sizeof(*priv));
+	priv->pci_dev_data = pci_dev_data;
+	priv->removed = 1;
+}
+
+static void mlx4_remove_one(struct pci_dev *pdev)
+{
+	struct mlx4_dev  *dev  = pci_get_drvdata(pdev);
+	struct mlx4_priv *priv = mlx4_priv(dev);
+
+	__mlx4_remove_one(pdev);
+	kfree(priv);
+	pci_set_drvdata(pdev, NULL);
 }
 
 int mlx4_restart_one(struct pci_dev *pdev)
@@ -2462,7 +2480,7 @@ int mlx4_restart_one(struct pci_dev *pdev)
 	int		  pci_dev_data;
 
 	pci_dev_data = priv->pci_dev_data;
-	mlx4_remove_one(pdev);
+	__mlx4_remove_one(pdev);
 	return __mlx4_init_one(pdev, pci_dev_data);
 }
 
@@ -2517,7 +2535,7 @@ MODULE_DEVICE_TABLE(pci, mlx4_pci_table);
 static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev,
 					      pci_channel_state_t state)
 {
-	mlx4_remove_one(pdev);
+	__mlx4_remove_one(pdev);
 
 	return state == pci_channel_io_perm_failure ?
 		PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET;
@@ -2525,11 +2543,11 @@ static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev,
 
 static pci_ers_result_t mlx4_pci_slot_reset(struct pci_dev *pdev)
 {
-	const struct pci_device_id *id;
-	int ret;
+	struct mlx4_dev	 *dev  = pci_get_drvdata(pdev);
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	int               ret;
 
-	id = pci_match_id(mlx4_pci_table, pdev);
-	ret = __mlx4_init_one(pdev, id->driver_data);
+	ret = __mlx4_init_one(pdev, priv->pci_dev_data);
 
 	return ret ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
 }
drivers/net/ethernet/mellanox/mlx4/mlx4.h +1 -0
index 348bb8c7d9a7..796ed1a79284 100644
@@ -774,6 +774,7 @@ struct mlx4_priv {
 	spinlock_t		ctx_lock;
 
 	int			pci_dev_data;
+	int                     removed;
 
 	struct list_head        pgdir_list;
 	struct mutex            pgdir_mutex;
Signature · 1 line
2.3.4
author
#127 lore raw

PATCH 127/155 net: mvneta: increase the 64-bit rx/tx stats out of the hot path

In reply to Jiri Slaby

From: willy tarreau <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit dc4277dd41a80fd5f29a90412ea04bc3ba54fbf1 upstream.

Better count packets and bytes in the stack and on 32 bit then accumulate them at the end for once. This saves two memory writes and two memory barriers per packet. The incoming packet rate was increased by 4.7% on the Openblocks AX3 thanks to this.

---
 drivers/net/ethernet/marvell/mvneta.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/net/ethernet/marvell/mvneta.c +11 -4
index 834b71d1c668..7553248510ea 100644
@@ -1391,6 +1391,8 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo,
 {
 	struct net_device *dev = pp->dev;
 	int rx_done, rx_filled;
+	u32 rcvd_pkts = 0;
+	u32 rcvd_bytes = 0;
 
 	/* Get number of received packets */
 	rx_done = mvneta_rxq_busy_desc_num_get(pp, rxq);
@@ -1428,10 +1430,8 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo,
 
 		rx_bytes = rx_desc->data_size -
 			(ETH_FCS_LEN + MVNETA_MH_SIZE);
-		u64_stats_update_begin(&pp->rx_stats.syncp);
-		pp->rx_stats.packets++;
-		pp->rx_stats.bytes += rx_bytes;
-		u64_stats_update_end(&pp->rx_stats.syncp);
+		rcvd_pkts++;
+		rcvd_bytes += rx_bytes;
 
 		/* Linux processing */
 		skb_reserve(skb, MVNETA_MH_SIZE);
@@ -1452,6 +1452,13 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo,
 		}
 	}
 
+	if (rcvd_pkts) {
+		u64_stats_update_begin(&pp->rx_stats.syncp);
+		pp->rx_stats.packets += rcvd_pkts;
+		pp->rx_stats.bytes   += rcvd_bytes;
+		u64_stats_update_end(&pp->rx_stats.syncp);
+	}
+
 	/* Update rxq management counters */
 	mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_filled);
 
Signature · 1 line
2.3.4
author
#128 lore raw

PATCH 128/155 net: mvneta: use per_cpu stats to fix an SMP lock up

In reply to Jiri Slaby

From: willy tarreau <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 74c41b048db1073a04827d7f39e95ac1935524cc upstream.

Stats writers are mvneta_rx() and mvneta_tx(). They don't lock anything when they update the stats, and as a result, it randomly happens that the stats freeze on SMP if two updates happen during stats retrieval. This is very easily reproducible by starting two HTTP servers and binding each of them to a different CPU, then consulting /proc/net/dev in loops during transfers, the interface should immediately lock up. This issue also randomly happens upon link state changes during transfers, because the stats are collected in this situation, but it takes more attempts to reproduce it.

The comments in netdevice.h suggest using per_cpu stats instead to get rid of this issue.

This patch implements this. It merges both rx_stats and tx_stats into a single "stats" member with a single syncp. Both mvneta_rx() and mvneta_rx() now only update the a single CPU's counters.

In turn, mvneta_get_stats64() does the summing by iterating over all CPUs to get their respective stats.

With this change, stats are still correct and no more lockup is encountered.

Note that this bug was present since the first import of the mvneta driver. It might make sense to backport it to some stable trees. If so, it depends on "d33dc73 net: mvneta: increase the 64-bit rx/tx stats out of the hot path".

Cc Thomas Petazzoni <[email protected]>
Cc Gregory CLEMENT <[email protected]>
[wt: port to 3.10 : u64_stats_init() does not exist in 3.10 and is not needed]
---
 drivers/net/ethernet/marvell/mvneta.c | 74 +++++++++++++++++++++++------------
 1 file changed, 48 insertions(+), 26 deletions(-)
drivers/net/ethernet/marvell/mvneta.c +48 -26
index 7553248510ea..84694987c13d 100644
@@ -221,10 +221,12 @@
 
 #define MVNETA_RX_BUF_SIZE(pkt_size)   ((pkt_size) + NET_SKB_PAD)
 
-struct mvneta_stats {
+struct mvneta_pcpu_stats {
 	struct	u64_stats_sync syncp;
-	u64	packets;
-	u64	bytes;
+	u64	rx_packets;
+	u64	rx_bytes;
+	u64	tx_packets;
+	u64	tx_bytes;
 };
 
 struct mvneta_port {
@@ -250,8 +252,7 @@ struct mvneta_port {
 	u8 mcast_count[256];
 	u16 tx_ring_size;
 	u16 rx_ring_size;
-	struct mvneta_stats tx_stats;
-	struct mvneta_stats rx_stats;
+	struct mvneta_pcpu_stats *stats;
 
 	struct mii_bus *mii_bus;
 	struct phy_device *phy_dev;
@@ -461,21 +462,29 @@ struct rtnl_link_stats64 *mvneta_get_stats64(struct net_device *dev,
 {
 	struct mvneta_port *pp = netdev_priv(dev);
 	unsigned int start;
+	int cpu;
 
-	memset(stats, 0, sizeof(struct rtnl_link_stats64));
-
-	do {
-		start = u64_stats_fetch_begin_bh(&pp->rx_stats.syncp);
-		stats->rx_packets = pp->rx_stats.packets;
-		stats->rx_bytes	= pp->rx_stats.bytes;
-	} while (u64_stats_fetch_retry_bh(&pp->rx_stats.syncp, start));
+	for_each_possible_cpu(cpu) {
+		struct mvneta_pcpu_stats *cpu_stats;
+		u64 rx_packets;
+		u64 rx_bytes;
+		u64 tx_packets;
+		u64 tx_bytes;
 
+		cpu_stats = per_cpu_ptr(pp->stats, cpu);
+		do {
+			start = u64_stats_fetch_begin_bh(&cpu_stats->syncp);
+			rx_packets = cpu_stats->rx_packets;
+			rx_bytes   = cpu_stats->rx_bytes;
+			tx_packets = cpu_stats->tx_packets;
+			tx_bytes   = cpu_stats->tx_bytes;
+		} while (u64_stats_fetch_retry_bh(&cpu_stats->syncp, start));
 
-	do {
-		start = u64_stats_fetch_begin_bh(&pp->tx_stats.syncp);
-		stats->tx_packets = pp->tx_stats.packets;
-		stats->tx_bytes	= pp->tx_stats.bytes;
-	} while (u64_stats_fetch_retry_bh(&pp->tx_stats.syncp, start));
+		stats->rx_packets += rx_packets;
+		stats->rx_bytes   += rx_bytes;
+		stats->tx_packets += tx_packets;
+		stats->tx_bytes   += tx_bytes;
+	}
 
 	stats->rx_errors	= dev->stats.rx_errors;
 	stats->rx_dropped	= dev->stats.rx_dropped;
@@ -1453,10 +1462,12 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo,
 	}
 
 	if (rcvd_pkts) {
-		u64_stats_update_begin(&pp->rx_stats.syncp);
-		pp->rx_stats.packets += rcvd_pkts;
-		pp->rx_stats.bytes   += rcvd_bytes;
-		u64_stats_update_end(&pp->rx_stats.syncp);
+		struct mvneta_pcpu_stats *stats = this_cpu_ptr(pp->stats);
+
+		u64_stats_update_begin(&stats->syncp);
+		stats->rx_packets += rcvd_pkts;
+		stats->rx_bytes   += rcvd_bytes;
+		u64_stats_update_end(&stats->syncp);
 	}
 
 	/* Update rxq management counters */
@@ -1590,11 +1601,12 @@ static int mvneta_tx(struct sk_buff *skb, struct net_device *dev)
 
 out:
 	if (frags > 0) {
-		u64_stats_update_begin(&pp->tx_stats.syncp);
-		pp->tx_stats.packets++;
-		pp->tx_stats.bytes += len;
-		u64_stats_update_end(&pp->tx_stats.syncp);
+		struct mvneta_pcpu_stats *stats = this_cpu_ptr(pp->stats);
 
+		u64_stats_update_begin(&stats->syncp);
+		stats->tx_packets++;
+		stats->tx_bytes  += len;
+		u64_stats_update_end(&stats->syncp);
 	} else {
 		dev->stats.tx_dropped++;
 		dev_kfree_skb_any(skb);
@@ -2818,6 +2830,13 @@ static int mvneta_probe(struct platform_device *pdev)
 		goto err_clk;
 	}
 
+	/* Alloc per-cpu stats */
+	pp->stats = alloc_percpu(struct mvneta_pcpu_stats);
+	if (!pp->stats) {
+		err = -ENOMEM;
+		goto err_unmap;
+	}
+
 	dt_mac_addr = of_get_mac_address(dn);
 	if (dt_mac_addr && is_valid_ether_addr(dt_mac_addr)) {
 		mac_from = "device tree";
@@ -2847,7 +2866,7 @@ static int mvneta_probe(struct platform_device *pdev)
 	err = mvneta_init(pp, phy_addr);
 	if (err < 0) {
 		dev_err(&pdev->dev, "can't init eth hal\n");
-		goto err_unmap;
+		goto err_free_stats;
 	}
 	mvneta_port_power_up(pp, phy_mode);
 
@@ -2877,6 +2896,8 @@ static int mvneta_probe(struct platform_device *pdev)
 
 err_deinit:
 	mvneta_deinit(pp);
+err_free_stats:
+	free_percpu(pp->stats);
 err_unmap:
 	iounmap(pp->base);
 err_clk:
@@ -2897,6 +2918,7 @@ static int mvneta_remove(struct platform_device *pdev)
 	unregister_netdev(dev);
 	mvneta_deinit(pp);
 	clk_disable_unprepare(pp->clk);
+	free_percpu(pp->stats);
 	iounmap(pp->base);
 	irq_dispose_mapping(dev->irq);
 	free_netdev(dev);
Signature · 1 line
2.3.4
author
#129 lore raw

PATCH 129/155 net: mvneta: do not schedule in mvneta_tx_timeout

In reply to Jiri Slaby

From: willy tarreau <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 290213667ab53a95456397763205e4b1e30f46b5 upstream.

If a queue timeout is reported, we can oops because of some schedules while the caller is atomic, as shown below :

mvneta d0070000.ethernet eth0: tx timeout

  BUG: scheduling while atomic: bash/1528/0x00000100
  Modules linked in: slhttp_ethdiv(C) [last unloaded: slhttp_ethdiv]
  CPU: 2 PID: 1528 Comm: bash Tainted: G        WC   3.13.0-rc4-mvebu-nf #180
  [<c0011bd9>] (unwind_backtrace+0x1/0x98) from [<c000f1ab>] (show_stack+0xb/0xc)
  [<c000f1ab>] (show_stack+0xb/0xc) from [<c02ad323>] (dump_stack+0x4f/0x64)
  [<c02ad323>] (dump_stack+0x4f/0x64) from [<c02abe67>] (__schedule_bug+0x37/0x4c)
  [<c02abe67>] (__schedule_bug+0x37/0x4c) from [<c02ae261>] (__schedule+0x325/0x3ec)
  [<c02ae261>] (__schedule+0x325/0x3ec) from [<c02adb97>] (schedule_timeout+0xb7/0x118)
  [<c02adb97>] (schedule_timeout+0xb7/0x118) from [<c0020a67>] (msleep+0xf/0x14)
  [<c0020a67>] (msleep+0xf/0x14) from [<c01dcbe5>] (mvneta_stop_dev+0x21/0x194)
  [<c01dcbe5>] (mvneta_stop_dev+0x21/0x194) from [<c01dcfe9>] (mvneta_tx_timeout+0x19/0x24)
  [<c01dcfe9>] (mvneta_tx_timeout+0x19/0x24) from [<c024afc7>] (dev_watchdog+0x18b/0x1c4)
  [<c024afc7>] (dev_watchdog+0x18b/0x1c4) from [<c0020b53>] (call_timer_fn.isra.27+0x17/0x5c)
  [<c0020b53>] (call_timer_fn.isra.27+0x17/0x5c) from [<c0020cad>] (run_timer_softirq+0x115/0x170)
  [<c0020cad>] (run_timer_softirq+0x115/0x170) from [<c001ccb9>] (__do_softirq+0xbd/0x1a8)
  [<c001ccb9>] (__do_softirq+0xbd/0x1a8) from [<c001cfad>] (irq_exit+0x61/0x98)
  [<c001cfad>] (irq_exit+0x61/0x98) from [<c000d4bf>] (handle_IRQ+0x27/0x60)
  [<c000d4bf>] (handle_IRQ+0x27/0x60) from [<c000843b>] (armada_370_xp_handle_irq+0x33/0xc8)
  [<c000843b>] (armada_370_xp_handle_irq+0x33/0xc8) from [<c000fba9>] (__irq_usr+0x49/0x60)

Ben Hutchings attempted to propose a better fix consisting in using a scheduled work for this, but while it fixed this panic, it caused other random freezes and panics proving that the reset sequence in the driver is unreliable and that additional fixes should be investigated.

When sending multiple streams over a link limited to 100 Mbps, Tx timeouts happen from time to time, and the driver correctly recovers only when the function is disabled.

---
 drivers/net/ethernet/marvell/mvneta.c | 11 -----------
 1 file changed, 11 deletions(-)
drivers/net/ethernet/marvell/mvneta.c +0 -11
index 84694987c13d..f4e59b021e73 100644
@@ -2245,16 +2245,6 @@ static void mvneta_stop_dev(struct mvneta_port *pp)
 	mvneta_rx_reset(pp);
 }
 
-/* tx timeout callback - display a message and stop/start the network device */
-static void mvneta_tx_timeout(struct net_device *dev)
-{
-	struct mvneta_port *pp = netdev_priv(dev);
-
-	netdev_info(dev, "tx timeout\n");
-	mvneta_stop_dev(pp);
-	mvneta_start_dev(pp);
-}
-
 /* Return positive if MTU is valid */
 static int mvneta_check_mtu_valid(struct net_device *dev, int mtu)
 {
@@ -2635,7 +2625,6 @@ static const struct net_device_ops mvneta_netdev_ops = {
 	.ndo_set_rx_mode     = mvneta_set_rx_mode,
 	.ndo_set_mac_address = mvneta_set_mac_addr,
 	.ndo_change_mtu      = mvneta_change_mtu,
-	.ndo_tx_timeout      = mvneta_tx_timeout,
 	.ndo_get_stats64     = mvneta_get_stats64,
 	.ndo_do_ioctl        = mvneta_ioctl,
 };
Signature · 1 line
2.3.4
author
#130 lore raw

PATCH 130/155 net: mvneta: add missing bit descriptions for interrupt masks and causes

In reply to Jiri Slaby

From: willy tarreau <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 40ba35e74fa56866918d2f3bc0528b5b92725d5e upstream.

Marvell has not published the chip's datasheet yet, so it's very hard to find the relevant bits to manipulate to change the IRQ behaviour. Fortunately, these bits are described in the proprietary LSP patch set which is publicly available here :

http://www.plugcomputer.org/downloads/mirabox/

So let's put them back in the driver in order to reduce the burden of current and future maintenance.

---
 drivers/net/ethernet/marvell/mvneta.c | 44 +++++++++++++++++++++++++++++++++--
 1 file changed, 42 insertions(+), 2 deletions(-)
drivers/net/ethernet/marvell/mvneta.c +42 -2
index f4e59b021e73..77a421666bb5 100644
@@ -101,16 +101,56 @@
 #define      MVNETA_CPU_RXQ_ACCESS_ALL_MASK      0x000000ff
 #define      MVNETA_CPU_TXQ_ACCESS_ALL_MASK      0x0000ff00
 #define MVNETA_RXQ_TIME_COAL_REG(q)              (0x2580 + ((q) << 2))
+
+/* Exception Interrupt Port/Queue Cause register */
+
 #define MVNETA_INTR_NEW_CAUSE                    0x25a0
-#define      MVNETA_RX_INTR_MASK(nr_rxqs)        (((1 << nr_rxqs) - 1) << 8)
 #define MVNETA_INTR_NEW_MASK                     0x25a4
+
+/* bits  0..7  = TXQ SENT, one bit per queue.
+ * bits  8..15 = RXQ OCCUP, one bit per queue.
+ * bits 16..23 = RXQ FREE, one bit per queue.
+ * bit  29 = OLD_REG_SUM, see old reg ?
+ * bit  30 = TX_ERR_SUM, one bit for 4 ports
+ * bit  31 = MISC_SUM,   one bit for 4 ports
+ */
+#define      MVNETA_TX_INTR_MASK(nr_txqs)        (((1 << nr_txqs) - 1) << 0)
+#define      MVNETA_TX_INTR_MASK_ALL             (0xff << 0)
+#define      MVNETA_RX_INTR_MASK(nr_rxqs)        (((1 << nr_rxqs) - 1) << 8)
+#define      MVNETA_RX_INTR_MASK_ALL             (0xff << 8)
+
 #define MVNETA_INTR_OLD_CAUSE                    0x25a8
 #define MVNETA_INTR_OLD_MASK                     0x25ac
+
+/* Data Path Port/Queue Cause Register */
 #define MVNETA_INTR_MISC_CAUSE                   0x25b0
 #define MVNETA_INTR_MISC_MASK                    0x25b4
+
+#define      MVNETA_CAUSE_PHY_STATUS_CHANGE      BIT(0)
+#define      MVNETA_CAUSE_LINK_CHANGE            BIT(1)
+#define      MVNETA_CAUSE_PTP                    BIT(4)
+
+#define      MVNETA_CAUSE_INTERNAL_ADDR_ERR      BIT(7)
+#define      MVNETA_CAUSE_RX_OVERRUN             BIT(8)
+#define      MVNETA_CAUSE_RX_CRC_ERROR           BIT(9)
+#define      MVNETA_CAUSE_RX_LARGE_PKT           BIT(10)
+#define      MVNETA_CAUSE_TX_UNDERUN             BIT(11)
+#define      MVNETA_CAUSE_PRBS_ERR               BIT(12)
+#define      MVNETA_CAUSE_PSC_SYNC_CHANGE        BIT(13)
+#define      MVNETA_CAUSE_SERDES_SYNC_ERR        BIT(14)
+
+#define      MVNETA_CAUSE_BMU_ALLOC_ERR_SHIFT    16
+#define      MVNETA_CAUSE_BMU_ALLOC_ERR_ALL_MASK   (0xF << MVNETA_CAUSE_BMU_ALLOC_ERR_SHIFT)
+#define      MVNETA_CAUSE_BMU_ALLOC_ERR_MASK(pool) (1 << (MVNETA_CAUSE_BMU_ALLOC_ERR_SHIFT + (pool)))
+
+#define      MVNETA_CAUSE_TXQ_ERROR_SHIFT        24
+#define      MVNETA_CAUSE_TXQ_ERROR_ALL_MASK     (0xFF << MVNETA_CAUSE_TXQ_ERROR_SHIFT)
+#define      MVNETA_CAUSE_TXQ_ERROR_MASK(q)      (1 << (MVNETA_CAUSE_TXQ_ERROR_SHIFT + (q)))
+
 #define MVNETA_INTR_ENABLE                       0x25b8
 #define      MVNETA_TXQ_INTR_ENABLE_ALL_MASK     0x0000ff00
-#define      MVNETA_RXQ_INTR_ENABLE_ALL_MASK     0xff000000
+#define      MVNETA_RXQ_INTR_ENABLE_ALL_MASK     0xff000000  // note: neta says it's 0x000000FF
+
 #define MVNETA_RXQ_CMD                           0x2680
 #define      MVNETA_RXQ_DISABLE_SHIFT            8
 #define      MVNETA_RXQ_ENABLE_MASK              0x000000ff
Signature · 1 line
2.3.4
author
#131 lore raw

PATCH 131/155 net: mvneta: replace Tx timer with a real interrupt

In reply to Jiri Slaby

From: willy tarreau <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 71f6d1b31fb1f278a345a30a2180515adc7d80ae upstream.

Right now the mvneta driver doesn't handle Tx IRQ, and relies on two mechanisms to flush Tx descriptors : a flush at the end of mvneta_tx() and a timer. If a burst of packets is emitted faster than the device can send them, then the queue is stopped until next wake-up of the timer 10ms later. This causes jerky output traffic with bursts and pauses, making it difficult to reach line rate with very few streams.

A test on UDP traffic shows that it's not possible to go beyond 134 Mbps / 12 kpps of outgoing traffic with 1500-bytes IP packets. Routed traffic tends to observe pauses as well if the traffic is bursty, making it even burstier after the wake-up.

It seems that this feature was inherited from the original driver but nothing there mentions any reason for not using the interrupt instead, which the chip supports.

Thus, this patch enables Tx interrupts and removes the timer. It does the two at once because it's not really possible to make the two mechanisms coexist, so a split patch doesn't make sense.

First tests performed on a Mirabox (Armada 370) show that less CPU seems to be used when sending traffic. One reason might be that we now call the mvneta_tx_done_gbe() with a mask indicating which queues have been done instead of looping over all of them.

The same UDP test above now happily reaches 987 Mbps / 87.7 kpps. Single-stream TCP traffic can now more easily reach line rate. HTTP transfers of 1 MB objects over a single connection went from 730 to 840 Mbps. It is even possible to go significantly higher (>900 Mbps) by tweaking tcp_tso_win_divisor.

---
 drivers/net/ethernet/marvell/mvneta.c | 71 ++++++-----------------------------
 1 file changed, 12 insertions(+), 59 deletions(-)
drivers/net/ethernet/marvell/mvneta.c +12 -59
index 77a421666bb5..c54868523f27 100644
@@ -216,9 +216,6 @@
 #define MVNETA_RX_COAL_PKTS		32
 #define MVNETA_RX_COAL_USEC		100
 
-/* Timer */
-#define MVNETA_TX_DONE_TIMER_PERIOD	10
-
 /* Napi polling weight */
 #define MVNETA_RX_POLL_WEIGHT		64
 
@@ -274,16 +271,11 @@ struct mvneta_port {
 	void __iomem *base;
 	struct mvneta_rx_queue *rxqs;
 	struct mvneta_tx_queue *txqs;
-	struct timer_list tx_done_timer;
 	struct net_device *dev;
 
 	u32 cause_rx_tx;
 	struct napi_struct napi;
 
-	/* Flags */
-	unsigned long flags;
-#define MVNETA_F_TX_DONE_TIMER_BIT  0
-
 	/* Napi weight */
 	int weight;
 
@@ -1149,17 +1141,6 @@ static void mvneta_tx_done_pkts_coal_set(struct mvneta_port *pp,
 	txq->done_pkts_coal = value;
 }
 
-/* Trigger tx done timer in MVNETA_TX_DONE_TIMER_PERIOD msecs */
-static void mvneta_add_tx_done_timer(struct mvneta_port *pp)
-{
-	if (test_and_set_bit(MVNETA_F_TX_DONE_TIMER_BIT, &pp->flags) == 0) {
-		pp->tx_done_timer.expires = jiffies +
-			msecs_to_jiffies(MVNETA_TX_DONE_TIMER_PERIOD);
-		add_timer(&pp->tx_done_timer);
-	}
-}
-
-
 /* Handle rx descriptor fill by setting buf_cookie and buf_phys_addr */
 static void mvneta_rx_desc_fill(struct mvneta_rx_desc *rx_desc,
 				u32 phys_addr, u32 cookie)
@@ -1652,15 +1633,6 @@ out:
 		dev_kfree_skb_any(skb);
 	}
 
-	if (txq->count >= MVNETA_TXDONE_COAL_PKTS)
-		mvneta_txq_done(pp, txq);
-
-	/* If after calling mvneta_txq_done, count equals
-	 * frags, we need to set the timer
-	 */
-	if (txq->count == frags && frags > 0)
-		mvneta_add_tx_done_timer(pp);
-
 	return NETDEV_TX_OK;
 }
 
@@ -1936,14 +1908,22 @@ static int mvneta_poll(struct napi_struct *napi, int budget)
 
 	/* Read cause register */
 	cause_rx_tx = mvreg_read(pp, MVNETA_INTR_NEW_CAUSE) &
-		MVNETA_RX_INTR_MASK(rxq_number);
+		(MVNETA_RX_INTR_MASK(rxq_number) | MVNETA_TX_INTR_MASK(txq_number));
+
+	/* Release Tx descriptors */
+	if (cause_rx_tx & MVNETA_TX_INTR_MASK_ALL) {
+		int tx_todo = 0;
+
+		mvneta_tx_done_gbe(pp, (cause_rx_tx & MVNETA_TX_INTR_MASK_ALL), &tx_todo);
+		cause_rx_tx &= ~MVNETA_TX_INTR_MASK_ALL;
+	}
 
 	/* For the case where the last mvneta_poll did not process all
 	 * RX packets
 	 */
 	cause_rx_tx |= pp->cause_rx_tx;
 	if (rxq_number > 1) {
-		while ((cause_rx_tx != 0) && (budget > 0)) {
+		while ((cause_rx_tx & MVNETA_RX_INTR_MASK_ALL) && (budget > 0)) {
 			int count;
 			struct mvneta_rx_queue *rxq;
 			/* get rx queue number from cause_rx_tx */
@@ -1975,7 +1955,7 @@ static int mvneta_poll(struct napi_struct *napi, int budget)
 		napi_complete(napi);
 		local_irq_save(flags);
 		mvreg_write(pp, MVNETA_INTR_NEW_MASK,
-			    MVNETA_RX_INTR_MASK(rxq_number));
+			    MVNETA_RX_INTR_MASK(rxq_number) | MVNETA_TX_INTR_MASK(txq_number));
 		local_irq_restore(flags);
 	}
 
@@ -1983,26 +1963,6 @@ static int mvneta_poll(struct napi_struct *napi, int budget)
 	return rx_done;
 }
 
-/* tx done timer callback */
-static void mvneta_tx_done_timer_callback(unsigned long data)
-{
-	struct net_device *dev = (struct net_device *)data;
-	struct mvneta_port *pp = netdev_priv(dev);
-	int tx_done = 0, tx_todo = 0;
-
-	if (!netif_running(dev))
-		return ;
-
-	clear_bit(MVNETA_F_TX_DONE_TIMER_BIT, &pp->flags);
-
-	tx_done = mvneta_tx_done_gbe(pp,
-				     (((1 << txq_number) - 1) &
-				      MVNETA_CAUSE_TXQ_SENT_DESC_ALL_MASK),
-				     &tx_todo);
-	if (tx_todo > 0)
-		mvneta_add_tx_done_timer(pp);
-}
-
 /* Handle rxq fill: allocates rxq skbs; called when initializing a port */
 static int mvneta_rxq_fill(struct mvneta_port *pp, struct mvneta_rx_queue *rxq,
 			   int num)
@@ -2252,7 +2212,7 @@ static void mvneta_start_dev(struct mvneta_port *pp)
 
 	/* Unmask interrupts */
 	mvreg_write(pp, MVNETA_INTR_NEW_MASK,
-		    MVNETA_RX_INTR_MASK(rxq_number));
+		    MVNETA_RX_INTR_MASK(rxq_number) | MVNETA_TX_INTR_MASK(txq_number));
 
 	phy_start(pp->phy_dev);
 	netif_tx_start_all_queues(pp->dev);
@@ -2528,8 +2488,6 @@ static int mvneta_stop(struct net_device *dev)
 	free_irq(dev->irq, pp);
 	mvneta_cleanup_rxqs(pp);
 	mvneta_cleanup_txqs(pp);
-	del_timer(&pp->tx_done_timer);
-	clear_bit(MVNETA_F_TX_DONE_TIMER_BIT, &pp->flags);
 
 	return 0;
 }
@@ -2881,11 +2839,6 @@ static int mvneta_probe(struct platform_device *pdev)
 		}
 	}
 
-	pp->tx_done_timer.data = (unsigned long)dev;
-	pp->tx_done_timer.function = mvneta_tx_done_timer_callback;
-	init_timer(&pp->tx_done_timer);
-	clear_bit(MVNETA_F_TX_DONE_TIMER_BIT, &pp->flags);
-
 	pp->tx_ring_size = MVNETA_MAX_TXD;
 	pp->rx_ring_size = MVNETA_MAX_RXD;
 
Signature · 1 line
2.3.4
author
#132 lore raw

PATCH 132/155 ASoC: sgtl5000: remove useless register write clearing CHRGPUMP_POWERUP

In reply to Jiri Slaby

From: Eric Nelson <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit c7d910b87d3c8e9fcf4077089ca4327c12eee099 upstream.

The SGTL5000_CHIP_ANA_POWER register is cached. Update the cached value instead of writing it directly.

Patch inspired by Russell King's more colorful remarks in this patch:

	https://github.com/SolidRun/linux-imx6-3.14/commit/dd4bf6a
---
 sound/soc/codecs/sgtl5000.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)
sound/soc/codecs/sgtl5000.c +1 -7
index ba73f832e455..cc2d29cee002 100644
@@ -1197,13 +1197,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
 		/* Enable VDDC charge pump */
 		ana_pwr |= SGTL5000_VDDC_CHRGPMP_POWERUP;
 	} else if (vddio >= 3100 && vdda >= 3100) {
-		/*
-		 * if vddio and vddd > 3.1v,
-		 * charge pump should be clean before set ana_pwr
-		 */
-		snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
-				SGTL5000_VDDC_CHRGPMP_POWERUP, 0);
-
+		ana_pwr &= ~SGTL5000_VDDC_CHRGPMP_POWERUP;
 		/* VDDC use VDDIO rail */
 		lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD;
 		lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO <<
Signature · 1 line
2.3.4
author
#133 lore raw

PATCH 133/155 ASoC: pcm1681: Fix wrong value references for boolean kctl

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit d7f58db49d9ad92bdb12d21fdc2308b76bc2ed38 upstream.

The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[].
The former is long while the latter is int, so it's even incompatible on 64bit architectures.

---
 sound/soc/codecs/pcm1681.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/codecs/pcm1681.c +2 -2
index c91eba504f92..0819fa2ff710 100644
@@ -117,7 +117,7 @@ static int pcm1681_get_deemph(struct snd_kcontrol *kcontrol,
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
 
-	ucontrol->value.enumerated.item[0] = priv->deemph;
+	ucontrol->value.integer.value[0] = priv->deemph;
 
 	return 0;
 }
@@ -128,7 +128,7 @@ static int pcm1681_put_deemph(struct snd_kcontrol *kcontrol,
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
 
-	priv->deemph = ucontrol->value.enumerated.item[0];
+	priv->deemph = ucontrol->value.integer.value[0];
 
 	return pcm1681_set_deemph(codec);
 }
Signature · 1 line
2.3.4
author
#134 lore raw

PATCH 134/155 ASoC: cs4271: Fix wrong value references for boolean kctl

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit e8371aa0fecb73fb8a4b2e0296b025b11e7d6229 upstream.

The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[].
The former is long while the latter is int, so it's even incompatible on 64bit architectures.

---
 sound/soc/codecs/cs4271.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/codecs/cs4271.c +2 -2
index a20f1bb8f071..57950e110e61 100644
@@ -287,7 +287,7 @@ static int cs4271_get_deemph(struct snd_kcontrol *kcontrol,
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
 
-	ucontrol->value.enumerated.item[0] = cs4271->deemph;
+	ucontrol->value.integer.value[0] = cs4271->deemph;
 	return 0;
 }
 
@@ -297,7 +297,7 @@ static int cs4271_put_deemph(struct snd_kcontrol *kcontrol,
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
 
-	cs4271->deemph = ucontrol->value.enumerated.item[0];
+	cs4271->deemph = ucontrol->value.integer.value[0];
 	return cs4271_set_deemph(codec);
 }
 
Signature · 1 line
2.3.4
author
#135 lore raw

PATCH 135/155 ASoC: wm8960: Fix wrong value references for boolean kctl

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit b4a18c8b1af15ebfa9054a3d2aef7b0a7e6f2a05 upstream.

The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[].
The former is long while the latter is int, so it's even incompatible on 64bit architectures.

---
 sound/soc/codecs/wm8960.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/codecs/wm8960.c +2 -2
index 942ef8427347..2a0bfb848512 100644
@@ -181,7 +181,7 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol,
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
 
-	ucontrol->value.enumerated.item[0] = wm8960->deemph;
+	ucontrol->value.integer.value[0] = wm8960->deemph;
 	return 0;
 }
 
@@ -190,7 +190,7 @@ static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
-	int deemph = ucontrol->value.enumerated.item[0];
+	int deemph = ucontrol->value.integer.value[0];
 
 	if (deemph > 1)
 		return -EINVAL;
Signature · 1 line
2.3.4
author
#136 lore raw

PATCH 136/155 ASoC: tas5086: Fix wrong value references for boolean kctl

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 4c523ef61160b7d478371ddc9f48c8ce0a00d675 upstream.

The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[].
The former is long while the latter is int, so it's even incompatible on 64bit architectures.

---
 sound/soc/codecs/tas5086.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/codecs/tas5086.c +2 -2
index 6d31d88f7204..6b694e422344 100644
@@ -272,7 +272,7 @@ static int tas5086_get_deemph(struct snd_kcontrol *kcontrol,
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
 
-	ucontrol->value.enumerated.item[0] = priv->deemph;
+	ucontrol->value.integer.value[0] = priv->deemph;
 
 	return 0;
 }
@@ -283,7 +283,7 @@ static int tas5086_put_deemph(struct snd_kcontrol *kcontrol,
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
 
-	priv->deemph = ucontrol->value.enumerated.item[0];
+	priv->deemph = ucontrol->value.integer.value[0];
 
 	return tas5086_set_deemph(codec);
 }
Signature · 1 line
2.3.4
author
#137 lore raw

PATCH 137/155 ASoC: wm8731: Fix wrong value references for boolean kctl

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit bd14016fbf31aa199026f1e2358eab695f374eb1 upstream.

The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[].
The former is long while the latter is int, so it's even incompatible on 64bit architectures.

---
 sound/soc/codecs/wm8731.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/codecs/wm8731.c +2 -2
index bc7472c968e3..cb860099126f 100644
@@ -122,7 +122,7 @@ static int wm8731_get_deemph(struct snd_kcontrol *kcontrol,
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
 
-	ucontrol->value.enumerated.item[0] = wm8731->deemph;
+	ucontrol->value.integer.value[0] = wm8731->deemph;
 
 	return 0;
 }
@@ -132,7 +132,7 @@ static int wm8731_put_deemph(struct snd_kcontrol *kcontrol,
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
-	int deemph = ucontrol->value.enumerated.item[0];
+	int deemph = ucontrol->value.integer.value[0];
 	int ret = 0;
 
 	if (deemph > 1)
Signature · 1 line
2.3.4
author
#138 lore raw

PATCH 138/155 ASoC: wm2000: Fix wrong value references for boolean kctl

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 00a14c2968e3d55817e0fa35c78106ca840537bf upstream.

The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[].
The former is long while the latter is int, so it's even incompatible on 64bit architectures.

---
 sound/soc/codecs/wm2000.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
sound/soc/codecs/wm2000.c +4 -4
index 7fefd766b582..124fb538dfa9 100644
@@ -605,7 +605,7 @@ static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol,
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
 
-	ucontrol->value.enumerated.item[0] = wm2000->anc_active;
+	ucontrol->value.integer.value[0] = wm2000->anc_active;
 
 	return 0;
 }
@@ -615,7 +615,7 @@ static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol,
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
-	int anc_active = ucontrol->value.enumerated.item[0];
+	int anc_active = ucontrol->value.integer.value[0];
 	int ret;
 
 	if (anc_active > 1)
@@ -638,7 +638,7 @@ static int wm2000_speaker_get(struct snd_kcontrol *kcontrol,
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
 
-	ucontrol->value.enumerated.item[0] = wm2000->spk_ena;
+	ucontrol->value.integer.value[0] = wm2000->spk_ena;
 
 	return 0;
 }
@@ -648,7 +648,7 @@ static int wm2000_speaker_put(struct snd_kcontrol *kcontrol,
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
-	int val = ucontrol->value.enumerated.item[0];
+	int val = ucontrol->value.integer.value[0];
 	int ret;
 
 	if (val > 1)
Signature · 1 line
2.3.4
author
#139 lore raw

PATCH 139/155 ASoC: wm8903: Fix wrong value references for boolean kctl

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 24cc883c1fd16df34211ae41624aa6d3cd906693 upstream.

The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[].
The former is long while the latter is int, so it's even incompatible on 64bit architectures.

---
 sound/soc/codecs/wm8903.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/codecs/wm8903.c +2 -2
index eebcb1da3b7b..ae7d76efe063 100644
@@ -442,7 +442,7 @@ static int wm8903_get_deemph(struct snd_kcontrol *kcontrol,
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
 
-	ucontrol->value.enumerated.item[0] = wm8903->deemph;
+	ucontrol->value.integer.value[0] = wm8903->deemph;
 
 	return 0;
 }
@@ -452,7 +452,7 @@ static int wm8903_put_deemph(struct snd_kcontrol *kcontrol,
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
-	int deemph = ucontrol->value.enumerated.item[0];
+	int deemph = ucontrol->value.integer.value[0];
 	int ret = 0;
 
 	if (deemph > 1)
Signature · 1 line
2.3.4
author
#140 lore raw

PATCH 140/155 ASoC: wm8904: Fix wrong value references for boolean kctl

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit eaddf6fd959074f6a6e71deffe079c71eef35da6 upstream.

The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[].
The former is long while the latter is int, so it's even incompatible on 64bit architectures.

---
 sound/soc/codecs/wm8904.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/codecs/wm8904.c +2 -2
index 48bae0ec500f..07c67a37a131 100644
@@ -523,7 +523,7 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
 
-	ucontrol->value.enumerated.item[0] = wm8904->deemph;
+	ucontrol->value.integer.value[0] = wm8904->deemph;
 	return 0;
 }
 
@@ -532,7 +532,7 @@ static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
-	int deemph = ucontrol->value.enumerated.item[0];
+	int deemph = ucontrol->value.integer.value[0];
 
 	if (deemph > 1)
 		return -EINVAL;
Signature · 1 line
2.3.4
author
#141 lore raw

PATCH 141/155 ASoC: ak4641: Fix wrong value references for boolean kctl

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 08641d9b7bf915144a57a736b42642e13eb1167f upstream.

The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[].
The former is long while the latter is int, so it's even incompatible on 64bit architectures.

---
 sound/soc/codecs/ak4641.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/codecs/ak4641.c +2 -2
index 5f9af1fb76e8..68379c14720b 100644
@@ -74,7 +74,7 @@ static int ak4641_put_deemph(struct snd_kcontrol *kcontrol,
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
-	int deemph = ucontrol->value.enumerated.item[0];
+	int deemph = ucontrol->value.integer.value[0];
 
 	if (deemph > 1)
 		return -EINVAL;
@@ -90,7 +90,7 @@ static int ak4641_get_deemph(struct snd_kcontrol *kcontrol,
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
 
-	ucontrol->value.enumerated.item[0] = ak4641->deemph;
+	ucontrol->value.integer.value[0] = ak4641->deemph;
 	return 0;
 };
 
Signature · 1 line
2.3.4
author
#142 lore raw

PATCH 142/155 ASoC: adav80x: Fix wrong value references for boolean kctl

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 2bf4c1d483d911cda5dd385527194d23e5cea73d upstream.

The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[].
The former is long while the latter is int, so it's even incompatible on 64bit architectures.

---
 sound/soc/codecs/adav80x.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/codecs/adav80x.c +2 -2
index 15b012d0f226..3be52ff14362 100644
@@ -307,7 +307,7 @@ static int adav80x_put_deemph(struct snd_kcontrol *kcontrol,
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
-	unsigned int deemph = ucontrol->value.enumerated.item[0];
+	unsigned int deemph = ucontrol->value.integer.value[0];
 
 	if (deemph > 1)
 		return -EINVAL;
@@ -323,7 +323,7 @@ static int adav80x_get_deemph(struct snd_kcontrol *kcontrol,
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
 
-	ucontrol->value.enumerated.item[0] = adav80x->deemph;
+	ucontrol->value.integer.value[0] = adav80x->deemph;
 	return 0;
 };
 
Signature · 1 line
2.3.4
author
#143 lore raw

PATCH 143/155 ASoC: wm8955: Fix wrong value references for boolean kctl

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 07892b10356f17717abdc578acbef72db86c880e upstream.

The correct values referred by a boolean control are value.integer.value[], not value.enumerated.item[].
The former is long while the latter is int, so it's even incompatible on 64bit architectures.

---
 sound/soc/codecs/wm8955.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/codecs/wm8955.c +2 -2
index 82c8ba975720..1c1fc6119758 100644
@@ -393,7 +393,7 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
 
-	ucontrol->value.enumerated.item[0] = wm8955->deemph;
+	ucontrol->value.integer.value[0] = wm8955->deemph;
 	return 0;
 }
 
@@ -402,7 +402,7 @@ static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
-	int deemph = ucontrol->value.enumerated.item[0];
+	int deemph = ucontrol->value.integer.value[0];
 
 	if (deemph > 1)
 		return -EINVAL;
Signature · 1 line
2.3.4
author
#144 lore raw

PATCH 144/155 regmap: regcache-rbtree: Fix present bitmap resize

In reply to Jiri Slaby

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

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 328f494d95aac8bd4896aea2328bc281053bcb71 upstream.

When inserting a new register into a block at the lower end the present bitmap is currently shifted into the wrong direction. The effect of this is that the bitmap becomes corrupted and registers which are present might be reported as not present and vice versa.

Fix this by shifting left rather than right.

Fixes 472fdec7380c("regmap: rbtree: Reduce number of nodes, take 2")
---
 drivers/base/regmap/regcache-rbtree.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/base/regmap/regcache-rbtree.c +1 -1
index 930cad4e5df8..2b946bc4212d 100644
@@ -313,7 +313,7 @@ static int regcache_rbtree_insert_to_block(struct regmap *map,
 	if (pos == 0) {
 		memmove(blk + offset * map->cache_word_size,
 			blk, rbnode->blklen * map->cache_word_size);
-		bitmap_shift_right(present, present, offset, blklen);
+		bitmap_shift_left(present, present, offset, blklen);
 	}
 
 	/* update the rbnode block, its size and the base register */
Signature · 1 line
2.3.4
author
#145 lore raw

PATCH 145/155 tcm_fc: missing curly braces in ft_invl_hw_context()

In reply to Jiri Slaby

From: Dan Carpenter <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit d556546e7ecd9fca199df4698943024d40044f8e upstream.

This patch adds a missing set of conditional check braces in ft_invl_hw_context() originally introduced by commit dcd998ccd when handling DDP failures in ft_recv_write_data() code.

commit dcd998ccdbf74a7d8fe0f0a44e85da1ed5975946
Author: Kiran Patil <[email protected]>
Date: Wed Aug 3 09:20:01 2011 +0000

tcm_fc: Handle DDP/SW fc_frame_payload_get failures in ft_recv_write_data

---
 drivers/target/tcm_fc/tfc_io.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/target/tcm_fc/tfc_io.c +2 -1
index e415af32115a..c67d3795db4a 100644
@@ -346,7 +346,7 @@ void ft_invl_hw_context(struct ft_cmd *cmd)
 		ep = fc_seq_exch(seq);
 		if (ep) {
 			lport = ep->lp;
-			if (lport && (ep->xid <= lport->lro_xid))
+			if (lport && (ep->xid <= lport->lro_xid)) {
 				/*
 				 * "ddp_done" trigger invalidation of HW
 				 * specific DDP context
@@ -361,6 +361,7 @@ void ft_invl_hw_context(struct ft_cmd *cmd)
 				 * identified using ep->xid)
 				 */
 				cmd->was_ddp_setup = 0;
+			}
 		}
 	}
 }
Signature · 1 line
2.3.4
author
#146 lore raw

PATCH 146/155 tcm_qla2xxx: Fix incorrect use of __transport_register_session

In reply to Jiri Slaby

From: Bart Van Assche <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 75c3d0bf9caebb502e96683b2bc37f9692437e68 upstream.

This patch fixes the incorrect use of __transport_register_session() in tcm_qla2xxx_check_initiator_node_acl() code, that does not perform explicit se_tpg->session_lock when accessing se_tpg->tpg_sess_list to add new se_sess nodes.

Given that tcm_qla2xxx_check_initiator_node_acl() is not called with qla_hw->hardware_lock held for all accesses of ->tpg_sess_list, the code should be using transport_register_session() instead.

---
 drivers/scsi/qla2xxx/tcm_qla2xxx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/qla2xxx/tcm_qla2xxx.c +1 -1
index 80a1f9f40aac..783a0a9f8577 100644
@@ -1454,7 +1454,7 @@ static int tcm_qla2xxx_check_initiator_node_acl(
 	/*
 	 * Finally register the new FC Nexus with TCM
 	 */
-	__transport_register_session(se_nacl->se_tpg, se_nacl, se_sess, sess);
+	transport_register_session(se_nacl->se_tpg, se_nacl, se_sess, sess);
 
 	return 0;
 }
Signature · 1 line
2.3.4
author
#147 lore raw

PATCH 147/155 nl80211: ignore HT/VHT capabilities without QoS/WMM

In reply to Jiri Slaby

From: Johannes Berg <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 496fcc294daab18799e190c0264863d653588d1f upstream.

As HT/VHT depend heavily on QoS/WMM, it's not a good idea to let userspace add clients that have HT/VHT but not QoS/WMM. Since it does so in certain cases we've observed (client is using HT IEs but not QoS/WMM) just ignore the HT/VHT info at this point and don't pass it down to the drivers which might unconditionally use it.

---
 net/wireless/nl80211.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
net/wireless/nl80211.c +10 -0
index 388123667f1e..79c3e641581d 100644
@@ -4096,6 +4096,16 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
 	if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
 		return -EINVAL;
 
+	/* HT/VHT requires QoS, but if we don't have that just ignore HT/VHT
+	 * as userspace might just pass through the capabilities from the IEs
+	 * directly, rather than enforcing this restriction and returning an
+	 * error in this case.
+	 */
+	if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME))) {
+		params.ht_capa = NULL;
+		params.vht_capa = NULL;
+	}
+
 	/* When you run into this, adjust the code below for the new flag */
 	BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
 
Signature · 1 line
2.3.4
author
#148 lore raw

PATCH 148/155 mac80211: disable u-APSD queues by default

In reply to Jiri Slaby

From: Michal Kazior <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit aa75ebc275b2a91b193654a177daf900ad6703f0 upstream.

Some APs experience problems when working with U-APSD. Decreasing the probability of that happening by using legacy mode for all ACs but VO isn't enough.

Cisco 4410N originally forced us to enable VO by default only because it treated non-VO ACs as legacy.

However some APs (notably Netgear R7000) silently reclassify packets to different ACs. Since u-APSD ACs require trigger frames for frame retrieval clients would never see some frames (e.g. ARP responses) or would fetch them accidentally after a long time.

It makes little sense to enable u-APSD queues by default because it needs userspace applications to be aware of it to actually take advantage of the possible additional powersavings. Implicitly depending on driver autotrigger frame support doesn't make much sense.

---
 net/mac80211/ieee80211_i.h | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)
net/mac80211/ieee80211_i.h +17 -6
index 23c13165ce83..09d4201b9e81 100644
@@ -57,13 +57,24 @@ struct ieee80211_local;
 #define IEEE80211_UNSET_POWER_LEVEL	INT_MIN
 
 /*
- * Some APs experience problems when working with U-APSD. Decrease the
- * probability of that happening by using legacy mode for all ACs but VO.
- * The AP that caused us trouble was a Cisco 4410N. It ignores our
- * setting, and always treats non-VO ACs as legacy.
+ * Some APs experience problems when working with U-APSD. Decreasing the
+ * probability of that happening by using legacy mode for all ACs but VO isn't
+ * enough.
+ *
+ * Cisco 4410N originally forced us to enable VO by default only because it
+ * treated non-VO ACs as legacy.
+ *
+ * However some APs (notably Netgear R7000) silently reclassify packets to
+ * different ACs. Since u-APSD ACs require trigger frames for frame retrieval
+ * clients would never see some frames (e.g. ARP responses) or would fetch them
+ * accidentally after a long time.
+ *
+ * It makes little sense to enable u-APSD queues by default because it needs
+ * userspace applications to be aware of it to actually take advantage of the
+ * possible additional powersavings. Implicitly depending on driver autotrigger
+ * frame support doesn't make much sense.
  */
-#define IEEE80211_DEFAULT_UAPSD_QUEUES \
-	IEEE80211_WMM_IE_STA_QOSINFO_AC_VO
+#define IEEE80211_DEFAULT_UAPSD_QUEUES 0
 
 #define IEEE80211_DEFAULT_MAX_SP_LEN		\
 	IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL
Signature · 1 line
2.3.4
author
#149 lore raw

PATCH 149/155 mac80211: drop unencrypted frames in mesh fwding

In reply to Jiri Slaby

From: Bob Copeland <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit d0c22119f574b851e63360c6b8660fe9593bbc3c upstream.

The mesh forwarding path was not checking that data frames were protected when running an encrypted network; add the necessary check.

---
 net/mac80211/rx.c | 3 +++
 1 file changed, 3 insertions(+)
net/mac80211/rx.c +3 -0
index 03146a15f4f9..198fd6e1f6d4 100644
@@ -2078,6 +2078,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
 	hdr = (struct ieee80211_hdr *) skb->data;
 	mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
 
+	if (ieee80211_drop_unencrypted(rx, hdr->frame_control))
+		return RX_DROP_MONITOR;
+
 	/* frame is in RMC, don't forward */
 	if (ieee80211_is_data(hdr->frame_control) &&
 	    is_multicast_ether_addr(hdr->addr1) &&
Signature · 1 line
2.3.4
author
#150 lore raw

PATCH 150/155 perf: Fix irq_work 'tail' recursion

In reply to Jiri Slaby

From: Peter Zijlstra <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit d525211f9d1be8b523ec7633f080f2116f5ea536 upstream.

Vince reported a watchdog lockup like:

	[<ffffffff8115e114>] perf_tp_event+0xc4/0x210
	[<ffffffff810b4f8a>] perf_trace_lock+0x12a/0x160
	[<ffffffff810b7f10>] lock_release+0x130/0x260
	[<ffffffff816c7474>] _raw_spin_unlock_irqrestore+0x24/0x40
	[<ffffffff8107bb4d>] do_send_sig_info+0x5d/0x80
	[<ffffffff811f69df>] send_sigio_to_task+0x12f/0x1a0
	[<ffffffff811f71ce>] send_sigio+0xae/0x100
	[<ffffffff811f72b7>] kill_fasync+0x97/0xf0
	[<ffffffff8115d0b4>] perf_event_wakeup+0xd4/0xf0
	[<ffffffff8115d103>] perf_pending_event+0x33/0x60
	[<ffffffff8114e3fc>] irq_work_run_list+0x4c/0x80
	[<ffffffff8114e448>] irq_work_run+0x18/0x40
	[<ffffffff810196af>] smp_trace_irq_work_interrupt+0x3f/0xc0
	[<ffffffff816c99bd>] trace_irq_work_interrupt+0x6d/0x80

Which is caused by an irq_work generating new irq_work and therefore not allowing forward progress.

This happens because processing the perf irq_work triggers another perf event (tracepoint stuff) which in turn generates an irq_work ad infinitum.

Avoid this by raising the recursion counter in the irq_work -- which effectively disables all software events (including tracepoints) from actually triggering again.

---
 kernel/events/core.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
kernel/events/core.c +10 -0
index 452b2b0d7af1..18de86cbcdac 100644
@@ -4169,6 +4169,13 @@ static void perf_pending_event(struct irq_work *entry)
 {
 	struct perf_event *event = container_of(entry,
 			struct perf_event, pending);
+	int rctx;
+
+	rctx = perf_swevent_get_recursion_context();
+	/*
+	 * If we 'fail' here, that's OK, it means recursion is already disabled
+	 * and we won't recurse 'further'.
+	 */
 
 	if (event->pending_disable) {
 		event->pending_disable = 0;
@@ -4179,6 +4186,9 @@ static void perf_pending_event(struct irq_work *entry)
 		event->pending_wakeup = 0;
 		perf_event_wakeup(event);
 	}
+
+	if (rctx >= 0)
+		perf_swevent_put_recursion_context(rctx);
 }
 
 /*
Signature · 1 line
2.3.4
author
#151 lore raw

PATCH 151/155 vt6655: RFbSetPower fix missing rate RATE_12M

In reply to Jiri Slaby

From: Malcolm Priestley <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 40c8790bcb7ac74f3038153cd09310e220c6a1df upstream.

When the driver sets this rate a power of zero value is set causing data flow stoppage until another rate is tried.

---
 drivers/staging/vt6655/rf.c | 1 +
 1 file changed, 1 insertion(+)
drivers/staging/vt6655/rf.c +1 -0
index 6948984a25ab..c2d602825422 100644
@@ -966,6 +966,7 @@ bool RFbSetPower(
 		break;
 	case RATE_6M:
 	case RATE_9M:
+	case RATE_12M:
 	case RATE_18M:
 		byPwr = pDevice->abyOFDMPwrTbl[uCH];
 		if (pDevice->byRFType == RF_UW2452) {
Signature · 1 line
2.3.4
author
#152 lore raw

PATCH 152/155 dmaengine: dw: append MODULE_ALIAS for platform driver

In reply to Jiri Slaby

From: Andy Shevchenko <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit a104a45ba7a51b5b4c5e8437020d9d48edf22f89 upstream.

The commit 9cade1a46c77 (dma: dw: split driver to library part and platform code) introduced a separate platform driver but missed to add a MODULE_ALIAS("platform:dw_dmac"); to that module.

The patch adds this to get driver loaded automatically if platform device is registered.

Fixes 9cade1a46c77 (dma: dw: split driver to library part and platform code)
---
 drivers/dma/dw/platform.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/dma/dw/platform.c +4 -1
index e35d97590311..df0c6b042557 100644
@@ -48,6 +48,8 @@ static bool dw_dma_of_filter(struct dma_chan *chan, void *param)
 	return true;
 }
 
+#define DRV_NAME	"dw_dmac"
+
 static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec,
 					struct of_dma *ofdma)
 {
@@ -295,7 +297,7 @@ static struct platform_driver dw_driver = {
 	.remove		= dw_remove,
 	.shutdown	= dw_shutdown,
 	.driver = {
-		.name	= "dw_dmac",
+		.name	= DRV_NAME,
 		.pm	= &dw_dev_pm_ops,
 		.of_match_table = of_match_ptr(dw_dma_of_id_table),
 		.acpi_match_table = ACPI_PTR(dw_dma_acpi_id_table),
@@ -316,3 +318,4 @@ module_exit(dw_exit);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller platform driver");
+MODULE_ALIAS("platform:" DRV_NAME);
Signature · 1 line
2.3.4
author
#153 lore raw

PATCH 153/155 dm: hold suspend_lock while suspending device during device deletion

In reply to Jiri Slaby

From: Mikulas Patocka <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit ab7c7bb6f4ab95dbca96fcfc4463cd69843e3e24 upstream.

__dm_destroy() must take the suspend_lock so that its presuspend and postsuspend calls do not race with an internal suspend.

---
 drivers/md/dm.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/md/dm.c +6 -0
index 93f3fe443657..5a0b1742f794 100644
@@ -2439,10 +2439,16 @@ static void __dm_destroy(struct mapped_device *md, bool wait)
 	set_bit(DMF_FREEING, &md->flags);
 	spin_unlock(&_minor_lock);
 
+	/*
+	 * Take suspend_lock so that presuspend and postsuspend methods
+	 * do not race with internal suspend.
+	 */
+	mutex_lock(&md->suspend_lock);
 	if (!dm_suspended_md(md)) {
 		dm_table_presuspend_targets(map);
 		dm_table_postsuspend_targets(map);
 	}
+	mutex_unlock(&md->suspend_lock);
 
 	/* dm_put_live_table must be before msleep, otherwise deadlock is possible */
 	dm_put_live_table(md, srcu_idx);
Signature · 1 line
2.3.4
author
#154 lore raw

PATCH 154/155 dm io: deal with wandering queue limits when handling REQ_DISCARD and REQ_WRITE_SAME

In reply to Jiri Slaby

From: "Darrick J. Wong" <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit e5db29806b99ce2b2640d2e4d4fcb983cea115c5 upstream.

Since it's possible for the discard and write same queue limits to change while the upper level command is being sliced and diced, fix up both of them (a) to reject IO if the special command is unsupported at the start of the function and (b) read the limits once and let the commands error out on their own if the status happens to change.

---
 drivers/md/dm-io.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/md/dm-io.c +11 -4
index 951addc80fcc..d4e1a17325ac 100644
@@ -289,9 +289,16 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
 	struct request_queue *q = bdev_get_queue(where->bdev);
 	unsigned short logical_block_size = queue_logical_block_size(q);
 	sector_t num_sectors;
+	unsigned int uninitialized_var(special_cmd_max_sectors);
 
-	/* Reject unsupported discard requests */
-	if ((rw & REQ_DISCARD) && !blk_queue_discard(q)) {
+	/*
+	 * Reject unsupported discard and write same requests.
+	 */
+	if (rw & REQ_DISCARD)
+		special_cmd_max_sectors = q->limits.max_discard_sectors;
+	else if (rw & REQ_WRITE_SAME)
+		special_cmd_max_sectors = q->limits.max_write_same_sectors;
+	if ((rw & (REQ_DISCARD | REQ_WRITE_SAME)) && special_cmd_max_sectors == 0) {
 		dec_count(io, region, -EOPNOTSUPP);
 		return;
 	}
@@ -317,7 +324,7 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
 		store_io_and_region_in_bio(bio, io, region);
 
 		if (rw & REQ_DISCARD) {
-			num_sectors = min_t(sector_t, q->limits.max_discard_sectors, remaining);
+			num_sectors = min_t(sector_t, special_cmd_max_sectors, remaining);
 			bio->bi_size = num_sectors << SECTOR_SHIFT;
 			remaining -= num_sectors;
 		} else if (rw & REQ_WRITE_SAME) {
@@ -326,7 +333,7 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
 			 */
 			dp->get_page(dp, &page, &len, &offset);
 			bio_add_page(bio, page, logical_block_size, offset);
-			num_sectors = min_t(sector_t, q->limits.max_write_same_sectors, remaining);
+			num_sectors = min_t(sector_t, special_cmd_max_sectors, remaining);
 			bio->bi_size = num_sectors << SECTOR_SHIFT;
 
 			offset = 0;
Signature · 1 line
2.3.4
author
#155 lore raw

PATCH 155/155 hfsplus: fix B-tree corruption after insertion at position 0

In reply to Jiri Slaby

From: Sergei Antonov <[email protected]>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

commit 98cf21c61a7f5419d82f847c4d77bf6e96a76f5f upstream.

Fix B-tree corruption when a new record is inserted at position 0 in the node in hfs_brec_insert(). In this case a hfs_brec_update_parent() is called to update the parent index node (if exists) and it is passed hfs_find_data with a search_key containing a newly inserted key instead of the key to be updated. This results in an inconsistent index node. The bug reproduces on my machine after an extents overflow record for the catalog file (CNID=4) is inserted into the extents overflow B-tree. Because of a low (reserved) value of CNID=4, it has to become the first record in the first leaf node.

The resulting first leaf node is correct:

----------------------------------------------------
| key0.CNID=4 | key1.CNID=123 | key2.CNID=456, ... |
----------------------------------------------------

But the parent index key0 still contains the previous key CNID=123:

-----------------------
| key0.CNID=123 | ... |
-----------------------

A change in hfs_brec_insert() makes hfs_brec_update_parent() work correctly by preventing it from getting fd->record=-1 value from __hfs_brec_find().

Along the way, I removed duplicate code with unification of the if condition. The resulting code is equivalent to the original code because node is never 0.

Also hfs_brec_update_parent() will now return an error after getting a negative fd->record value. However, the return value of hfs_brec_update_parent() is not checked anywhere in the file and I'm leaving it unchanged by this patch. brec.c lacks error checking after some other calls too, but this issue is of less importance than the one being fixed by this patch.

---
 fs/hfsplus/brec.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)
fs/hfsplus/brec.c +11 -9
index 6e560d56094b..754fdf8c6356 100644
@@ -131,13 +131,16 @@ skip:
 	hfs_bnode_write(node, entry, data_off + key_len, entry_len);
 	hfs_bnode_dump(node);
 
-	if (new_node) {
-		/* update parent key if we inserted a key
-		 * at the start of the first node
-		 */
-		if (!rec && new_node != node)
-			hfs_brec_update_parent(fd);
+	/*
+	 * update parent key if we inserted a key
+	 * at the start of the node and it is not the new node
+	 */
+	if (!rec && new_node != node) {
+		hfs_bnode_read_key(node, fd->search_key, data_off + size);
+		hfs_brec_update_parent(fd);
+	}
 
+	if (new_node) {
 		hfs_bnode_put(fd->bnode);
 		if (!new_node->parent) {
 			hfs_btree_inc_height(tree);
@@ -168,9 +171,6 @@ skip:
 		goto again;
 	}
 
-	if (!rec)
-		hfs_brec_update_parent(fd);
-
 	return 0;
 }
 
@@ -370,6 +370,8 @@ again:
 	if (IS_ERR(parent))
 		return PTR_ERR(parent);
 	__hfs_brec_find(parent, fd, hfs_find_rec_by_key);
+	if (fd->record < 0)
+		return -ENOENT;
 	hfs_bnode_dump(parent);
 	rec = fd->record;
 
Signature · 1 line
2.3.4
#156 lore raw
In reply to Jiri Slaby
Quoted 8 lines · Jiri Slaby

This is the start of the stable review cycle for the 3.12.40 release. There are 155 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 14:50:04 CEST 2015. Anything received after that time might be too late.

Build results:

	total: 121 pass: 121 fail: 0
Qemu test results:
	total: 27 pass: 27 fail: 0

Details are available at http://server.roeck-us.net:8010/builders.

Guenter