Skip to contentSkip to conversation

3.12.56-stable review

PATCH In review Jiri Slaby 3 participants 120 messages Mar 4, 2016 – Mar 8, 2016 Stable branch

lore
Share & tools
lore

Jiri Slaby

author
#0 lore raw

cover 3.12.56-stable review

This is the start of the stable review cycle for the 3.12.56 release. There are 116 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 Tue Mar 8 10:01:48 CET 2016. 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.56-rc1.xz

and the diffstat can be found below.

thanks,
js

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

Adrian Hunter (1):
mmc: sdhci: Fix sdhci_runtime_pm_bus_on/off()

Al Viro (2):
bcache: fix a leak in bch_cached_dev_run()
do_last(): don't let a bogus return value from ->open() et.al. to
confuse us

Alex Deucher (3):
drm/radeon: make rv770_set_sw_state failures non-fatal drm/radeon: clean up fujitsu quirks
drm/radeon/pm: adjust display configuration after powerstate

Amir Vadai (1):
net/mlx4_en: Count HW buffer overrun only once

Anand Jain (1):
Btrfs: add missing brelse when superblock checksum fails

Andrey Ryabinin (1):
lockd: create NSM handles per net namespace

Andrey Skvortsov (1):
USB: option: add support for SIM7100E

Andy Shevchenko (1):
dmaengine: dw: convert to __ffs()

Anton Protopopov (1):
rtnl: RTM_GETNETCONF: fix wrong return value

Antonio Ospite (1):
gspca: ov534/topro: prevent a division by 0

Benjamin Coddington (1):
NFSv4: Fix a dentry leak on alias use

Bin Liu (1):
usb: musb: cppi41: correct the macro name EP_MODE_AUTOREG_*

Bjørn Mork (2):
qmi_wwan: add "4G LTE usb-modem U901"
USB: option: add "4G LTE usb-modem U901"

Borislav Petkov (2):
EDAC: Robustify workqueues destruction
EDAC, mc_sysfs: Fix freeing bus' name

Christian Borntraeger (1):
KVM: async_pf: do not warn on page allocation failures

Christoph Hellwig (1):
nfs: fix nfs_size_to_loff_t

Christophe Leroy (1):
splice: sendfile() at once fails for big files

Corey Wright (1):
proc: Fix ptrace-based permission checks for accessing task maps

Dan Carpenter (1):
devres: fix a for loop bounds check

Dmitry V. Levin (2):
unix_diag: fix incorrect sign extension in unix_lookup_by_ino
sparc64: fix incorrect sign extension in sys_sparc64_personality

Egbert Eich (1):
drm/ast: Initialized data needed to map fbdev memory

Eric Dumazet (4):
tcp: fix NULL deref in tcp_v4_send_ack()
af_unix: fix struct pid memory leak
ipv6: fix a lockdep splat
ipv4: fix memory leaks in ip_cmsg_send() callers

Eugenia Emantayev (1):
net/mlx4_en: Choose time-stamping shift value according to HW
frequency

Filipe Manana (2):
Btrfs: send, don't BUG_ON() when an empty symlink is found
Btrfs: fix number of transaction units required to create symlink

Gerd Hoffmann (1):
drm/qxl: use kmalloc_array to alloc reloc_info in
qxl_process_single_command

Gerhard Uttenthaler (1):
can: ems_usb: Fix possible tx overflow

Guillaume Nault (1):
pppoe: fix reference counting in PPPoE proxy

Hangbin Liu (1):
net/ipv6: add sysctl option accept_ra_min_hop_limit

Hannes Frederic Sowa (1):
pptp: fix illegal memory access caused by multiple bind()s

Hannes Reinecke (1):
bio: return EINTR if copying to user space got interrupted

Hans Westgaard Ry (1):
net:Add sysctl_max_skb_frags

Hariprasad S (1):
iw_cxgb3: Fix incorrectly returning error on success

Ilya Dryomov (1):
libceph: don't bail early from try_read() when skipping a message

James Bottomley (2):
ses: Fix problems with simple enclosures
ses: fix additional element traversal bug

Jan Engelhardt (1):
target: fix COMPARE_AND_WRITE non zero SGL offset data corruption

Jan Kara (1):
vfs: Avoid softlockups with sendfile(2)

Jani Nikula (1):
drm/i915/dp: fall back to 18 bpp when sink capability is unknown

Jay Vosburgh (1):
bonding: Fix ARP monitor validation

Jeff Layton (1):
locks: fix unlock when fcntl_setlk races with a close

Joe Thornber (3):
dm thin metadata: fix bug when taking a metadata snapshot dm space map metadata: fix ref counting bug when bootstrapping a new
space map
dm btree: fix bufio buffer leaks in dm_btree_del() error path

Johannes Berg (3):
mac80211: mesh: fix call_rcu() usage
rfkill: copy the name into the rfkill struct
rfkill: fix rfkill_fop_read wait_event usage

Josef Bacik (1):
Btrfs: igrab inode in writepage

K. Y. Srinivasan (1):
storvsc: Don't set the SRB_FLAGS_QUEUE_ACTION_ENABLE flag

Kees Cook (1):
mac: validate mac_partition is within sector

Ken Lin (1):
USB: cp210x: add IDs for GE B650V3 and B850V3 boards

Kirill A. Shutemov (1):
vgaarb: fix signal handling in vga_get()

Konrad Rzeszutek Wilk (1):
xen/pcifront: Fix mysterious crashes when NUMA locality information
was extracted.

Linus Walleij (1):
mmc: mmci: fix an ages old detection error

Luca Porzio (1):
mmc: remove bondage between REQ_META and reliable write

Malcolm Priestley (1):
media: dvb-core: Don't force CAN_INVERSION_AUTO in oneshot mode

Manfred Rudigier (1):
net: dp83640: Fix tx timestamp overflow handling.

Manish Chopra (1):
bnx2x: Don't notify about scratchpad parities

Marcelo Ricardo Leitner (1):
sctp: allow setting SCTP_SACK_IMMEDIATELY by the application

Mauro Carvalho Chehab (1):
tda1004x: only update the frontend properties if locked

Mike Marciniszyn (1):
IB/qib: fix mcast detach when qp not attached

Mike Snitzer (1):
dm space map metadata: remove unused variable in brb_pop()

Mikulas Patocka (2):
sata_sil: disable trim
dm snapshot: fix hung bios when copy error occurs

Neil Horman (1):
sctp: Fix port hash table size computation

Nicholas Bellinger (1):
target: Fix race for SCF_COMPARE_AND_WRITE_POST checking

Nicolai Hähnle (1):
drm/radeon: hold reference to fences in radeon_sa_bo_new

Olga Kornievskaia (1):
Failing to send a CLOSE if file is opened WRONLY and server reboots on
a 4.x mount

Oliver Neukum (1):
cdc-acm:exclude Samsung phone 04e8:685d

Paolo Abeni (1):
ipv6/udp: use sticky pktinfo egress ifindex on connect()

Peter Rosin (1):
hwmon: (ads1015) Handle negative conversion values correctly

Peter Zijlstra (5):
sched: Clean up idle task SMP logic
sched: Replace post_schedule with a balance callback list
sched: Allow balance callbacks for check_class_changed() sched,rt: Remove return value from pull_rt_task() sched, rt: Convert switched_{from, to}_rt() / prio_changed_rt() to
balance callbacks

Rainer Weikusat (1):
af_unix: Guard against other == sk in unix_dgram_sendmsg

Rasmus Villemoes (1):
drm/radeon: use post-decrement in error handling

Richard Cochran (1):
posix-clock: Fix return code on the poll method's error path

Rob Clark (1):
drm/vmwgfx: respect 'nomodeset'

Roman Volkov (2):
dts: vt8500: Add SDHC node to DTS file for WM8650 clocksource/drivers/vt8500: Increase the minimum delta

Russell King (1):
scripts: recordmcount: break hardlinks

Sasha Levin (1):
sched/core: Remove false-positive warning from wake_up_process()

Sebastian Andrzej Siewior (1):
PCI/AER: Flush workqueue on device remove to avoid use-after-free

Simon Guinot (1):
kernel/resource.c: fix muxed resource handling in __request_region()

Siva Reddy Kallam (1):
tg3: Fix for tg3 transmit queue 0 timed out when too many gso_segs

Stefan Haberland (2):
s390/dasd: prevent incorrect length error under z/VM after PAV changes s390/dasd: fix refcount for PAV reassignment

Stefan Hajnoczi (1):
sunrpc/cache: fix off-by-one in qword_get()

Steven Rostedt (Red Hat) (3):
tracepoints: Do not trace when cpu is offline
ring-buffer: Update read stamp with first real commit on page
tracing: Fix showing function event in available_events

Suman Anna (1):
virtio: fix memory leak of virtio ida cache layers

Tejun Heo (1):
libata: fix sff host state machine locking while polling

Thomas Gleixner (1):
genirq: Prevent chip buslock deadlock

Ursula Braun (1):
af_iucv: Validate socket address length in iucv_sock_bind()

Valentin Rothberg (1):
wm831x_power: Use IRQF_ONESHOT to request threaded IRQs

Veaceslav Falico (1):
bonding: fix bond_arp_rcv() race of curr_active_slave

Vegard Nossum (2):
uml: flush stdout before forking
uml: fix hostfs mknod()

Xin Long (2):
sctp: translate network order to host order when users get a hmacid
route: check and remove route cache when we get route

Xunlei Pang (1):
sched/core: Clear the root_domain cpumasks in init_rootdomain()

Zheng Liu (1):
bcache: unregister reboot notifier if bcache fails to unregister
device

[email protected] (2):
megaraid_sas: Do not use PAGE_SIZE for max_sectors megaraid_sas : SMAP restriction--do not access user memory from IOCTL
code

 Documentation/networking/ip-sysctl.txt             |  8 +++
 arch/arm/boot/dts/wm8650.dtsi                      |  9 +++
 arch/sparc/kernel/sys_sparc_64.c                   |  2 +-
 arch/um/os-Linux/start_up.c                        |  2 +
 block/partitions/mac.c                             | 10 ++-
 drivers/ata/libata-sff.c                           | 32 ++++-----
 drivers/ata/sata_sil.c                             |  3 +
 drivers/clocksource/vt8500_timer.c                 |  6 +-
 drivers/dma/dw/core.c                              | 12 ++--
 drivers/edac/edac_device.c                         |  9 +--
 drivers/edac/edac_mc.c                             | 14 +---
 drivers/edac/edac_mc_sysfs.c                       | 18 +++--
 drivers/edac/edac_pci.c                            |  9 ++-
 drivers/gpu/drm/ast/ast_drv.h                      |  1 +
 drivers/gpu/drm/ast/ast_fb.c                       |  7 ++
 drivers/gpu/drm/ast/ast_main.c                     |  1 +
 drivers/gpu/drm/ast/ast_mode.c                     |  2 +
 drivers/gpu/drm/i915/intel_display.c               | 20 ++++--
 drivers/gpu/drm/qxl/qxl_ioctl.c                    |  3 +-
 drivers/gpu/drm/radeon/radeon_atombios.c           | 12 +---
 drivers/gpu/drm/radeon/radeon_pm.c                 |  5 +-
 drivers/gpu/drm/radeon/radeon_sa.c                 |  5 ++
 drivers/gpu/drm/radeon/radeon_ttm.c                |  2 +-
 drivers/gpu/drm/radeon/rv770_dpm.c                 |  2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c                |  7 ++
 drivers/gpu/vga/vgaarb.c                           |  6 +-
 drivers/hwmon/ads1015.c                            |  2 +-
 drivers/infiniband/hw/cxgb3/iwch_cm.c              |  4 +-
 drivers/infiniband/hw/qib/qib_verbs_mcast.c        | 35 +++++-----
 drivers/md/bcache/super.c                          |  9 ++-
 drivers/md/dm-exception-store.h                    |  2 +-
 drivers/md/dm-snap-persistent.c                    |  5 +-
 drivers/md/dm-snap-transient.c                     |  4 +-
 drivers/md/dm-snap.c                               | 20 ++----
 drivers/md/dm-thin-metadata.c                      |  6 ++
 drivers/md/persistent-data/dm-btree.c              | 16 ++++-
 drivers/md/persistent-data/dm-space-map-metadata.c | 29 +++++---
 drivers/media/dvb-core/dvb_frontend.c              |  6 +-
 drivers/media/dvb-frontends/tda1004x.c             |  9 +++
 drivers/media/usb/gspca/ov534.c                    |  9 ++-
 drivers/media/usb/gspca/topro.c                    |  6 +-
 drivers/mmc/card/block.c                           | 11 +---
 drivers/mmc/host/mmci.c                            |  2 +-
 drivers/mmc/host/sdhci.c                           |  4 +-
 drivers/net/bonding/bond_main.c                    | 46 +++++++++----
 drivers/net/can/usb/ems_usb.c                      | 14 ++--
 drivers/net/ethernet/broadcom/bnx2x/bnx2x.h        | 11 ++--
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c   | 20 ++++--
 drivers/net/ethernet/broadcom/tg3.c                | 22 +++++--
 drivers/net/ethernet/mellanox/mlx4/en_clock.c      | 25 +++++--
 drivers/net/ethernet/mellanox/mlx4/en_port.c       |  4 +-
 drivers/net/phy/dp83640.c                          | 17 +++++
 drivers/net/ppp/pppoe.c                            |  2 +
 drivers/net/ppp/pptp.c                             | 34 +++++++---
 drivers/net/usb/qmi_wwan.c                         |  1 +
 drivers/pci/pcie/aer/aerdrv.c                      |  4 +-
 drivers/pci/pcie/aer/aerdrv.h                      |  1 -
 drivers/pci/pcie/aer/aerdrv_core.c                 |  2 -
 drivers/pci/xen-pcifront.c                         | 10 +--
 drivers/power/wm831x_power.c                       |  6 +-
 drivers/s390/block/dasd_alias.c                    | 23 +++++--
 drivers/scsi/megaraid/megaraid_sas.h               |  2 +
 drivers/scsi/megaraid/megaraid_sas_base.c          | 15 ++++-
 drivers/scsi/ses.c                                 | 30 ++++++++-
 drivers/scsi/storvsc_drv.c                         |  3 +-
 drivers/target/target_core_sbc.c                   | 17 +++--
 drivers/target/target_core_transport.c             | 14 ++--
 drivers/usb/class/cdc-acm.c                        |  5 ++
 drivers/usb/musb/musb_cppi41.c                     | 12 ++--
 drivers/usb/serial/cp210x.c                        |  2 +
 drivers/usb/serial/option.c                        |  9 +++
 drivers/virtio/virtio.c                            |  1 +
 fs/bio.c                                           | 12 ++--
 fs/btrfs/disk-io.c                                 |  1 +
 fs/btrfs/inode.c                                   | 21 +++++-
 fs/btrfs/send.c                                    | 16 ++++-
 fs/hostfs/hostfs_kern.c                            |  4 +-
 fs/lockd/host.c                                    |  7 +-
 fs/lockd/mon.c                                     | 36 ++++++----
 fs/lockd/netns.h                                   |  1 +
 fs/lockd/svc.c                                     |  1 +
 fs/lockd/svc4proc.c                                |  2 +-
 fs/lockd/svcproc.c                                 |  2 +-
 fs/locks.c                                         | 51 ++++++++------
 fs/namei.c                                         |  4 ++
 fs/nfs/nfs4proc.c                                  |  4 +-
 fs/nfs/nfs4state.c                                 |  2 +-
 fs/proc/task_mmu.c                                 |  4 +-
 fs/proc/task_nommu.c                               |  2 +-
 fs/splice.c                                        | 13 +++-
 include/linux/enclosure.h                          |  4 ++
 include/linux/ipv6.h                               |  1 +
 include/linux/lockd/lockd.h                        |  9 ++-
 include/linux/nfs_fs.h                             |  4 +-
 include/linux/skbuff.h                             |  1 +
 include/linux/tracepoint.h                         |  6 ++
 include/net/ip_fib.h                               |  1 +
 include/target/target_core_base.h                  |  2 +-
 include/uapi/linux/ipv6.h                          |  2 +
 kernel/irq/manage.c                                |  6 +-
 kernel/resource.c                                  |  5 +-
 kernel/sched/core.c                                | 67 ++++++++++++++-----
 kernel/sched/idle_task.c                           |  9 +--
 kernel/sched/rt.c                                  | 71 +++++++++++---------
 kernel/sched/sched.h                               | 19 +++++-
 kernel/time/posix-clock.c                          |  4 +-
 kernel/trace/ring_buffer.c                         | 12 ++--
 kernel/trace/trace_events.c                        |  3 +-
 lib/devres.c                                       |  2 +-
 net/ceph/messenger.c                               |  4 +-
 net/core/skbuff.c                                  |  2 +
 net/core/sysctl_net_core.c                         | 10 +++
 net/ipv4/devinet.c                                 |  2 +-
 net/ipv4/ip_sockglue.c                             |  2 +
 net/ipv4/ping.c                                    |  4 +-
 net/ipv4/raw.c                                     |  4 +-
 net/ipv4/route.c                                   | 77 ++++++++++++++++++----
 net/ipv4/tcp.c                                     |  4 +-
 net/ipv4/tcp_ipv4.c                                | 13 ++--
 net/ipv4/udp.c                                     |  4 +-
 net/ipv6/addrconf.c                                | 12 +++-
 net/ipv6/datagram.c                                |  3 +
 net/ipv6/ip6_flowlabel.c                           |  5 +-
 net/ipv6/ndisc.c                                   | 16 ++---
 net/iucv/af_iucv.c                                 |  3 +
 net/mac80211/mesh_pathtbl.c                        |  8 +--
 net/rfkill/core.c                                  | 22 ++-----
 net/sctp/protocol.c                                | 47 ++++++++++---
 net/sctp/socket.c                                  | 10 ++-
 net/sunrpc/cache.c                                 |  2 +-
 net/unix/af_unix.c                                 |  8 ++-
 net/unix/diag.c                                    |  2 +-
 scripts/recordmcount.c                             | 14 ++++
 virt/kvm/async_pf.c                                |  2 +-
 134 files changed, 971 insertions(+), 458 deletions(-)
Signature · 1 line
2.7.2
author
#1 lore raw

PATCH 1/116 proc: Fix ptrace-based permission checks for accessing task maps

From: Corey Wright <[email protected]>

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

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

Modify mm_access() calls in fs/proc/task_mmu.c and fs/proc/task_nommu.c to have the mode include PTRACE_MODE_FSCREDS so accessing /proc/pid/maps and /proc/pid/pagemap is not denied to all users.

In backporting upstream commit caaee623 to pre-3.18 kernel versions it was overlooked that mm_access() is used in fs/proc/task_*mmu.c as those calls were removed in 3.18 (by upstream commit 29a40ace) and did not exist at the time of the original commit.

Fixes caaee6234d ("ptrace: use fsuid, fsgid, effective creds for fs access checks")
---
 fs/proc/task_mmu.c   | 4 ++--
 fs/proc/task_nommu.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)
fs/proc/task_mmu.c +2 -2
index d20f37d1c6e7..4fe8b1082cf3 100644
@@ -172,7 +172,7 @@ static void *m_start(struct seq_file *m, loff_t *pos)
 	if (!priv->task)
 		return ERR_PTR(-ESRCH);
 
-	mm = mm_access(priv->task, PTRACE_MODE_READ);
+	mm = mm_access(priv->task, PTRACE_MODE_READ_FSCREDS);
 	if (!mm || IS_ERR(mm))
 		return mm;
 	down_read(&mm->mmap_sem);
@@ -1186,7 +1186,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
 	if (!pm.buffer)
 		goto out_task;
 
-	mm = mm_access(task, PTRACE_MODE_READ);
+	mm = mm_access(task, PTRACE_MODE_READ_FSCREDS);
 	ret = PTR_ERR(mm);
 	if (!mm || IS_ERR(mm))
 		goto out_free;
fs/proc/task_nommu.c +1 -1
index 56123a6f462e..123c19890b14 100644
@@ -223,7 +223,7 @@ static void *m_start(struct seq_file *m, loff_t *pos)
 	if (!priv->task)
 		return ERR_PTR(-ESRCH);
 
-	mm = mm_access(priv->task, PTRACE_MODE_READ);
+	mm = mm_access(priv->task, PTRACE_MODE_READ_FSCREDS);
 	if (!mm || IS_ERR(mm)) {
 		put_task_struct(priv->task);
 		priv->task = NULL;
Signature · 1 line
2.7.2
author
#2 lore raw

PATCH 2/116 usb: musb: cppi41: correct the macro name EP_MODE_AUTOREG_*

From: Bin Liu <[email protected]>

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

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

commit 0149b07a9e28b0d8bd2fc1c238ffe7d530c2673f upstream.

The macro EP_MODE_AUTOREG_* should be called EP_MODE_AUTOREQ_*, as they are used for register AUTOREQ.

---
 drivers/usb/musb/musb_cppi41.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/usb/musb/musb_cppi41.c +6 -6
index 2ed1695ff5ad..cce32e91fd9e 100644
@@ -9,9 +9,9 @@
 
 #define RNDIS_REG(x) (0x80 + ((x - 1) * 4))
 
-#define EP_MODE_AUTOREG_NONE		0
-#define EP_MODE_AUTOREG_ALL_NEOP	1
-#define EP_MODE_AUTOREG_ALWAYS		3
+#define EP_MODE_AUTOREQ_NONE		0
+#define EP_MODE_AUTOREQ_ALL_NEOP	1
+#define EP_MODE_AUTOREQ_ALWAYS		3
 
 #define EP_MODE_DMA_TRANSPARENT		0
 #define EP_MODE_DMA_RNDIS		1
@@ -376,19 +376,19 @@ static bool cppi41_configure_channel(struct dma_channel *channel,
 
 			/* auto req */
 			cppi41_set_autoreq_mode(cppi41_channel,
-					EP_MODE_AUTOREG_ALL_NEOP);
+					EP_MODE_AUTOREQ_ALL_NEOP);
 		} else {
 			musb_writel(musb->ctrl_base,
 					RNDIS_REG(cppi41_channel->port_num), 0);
 			cppi41_set_dma_mode(cppi41_channel,
 					EP_MODE_DMA_TRANSPARENT);
 			cppi41_set_autoreq_mode(cppi41_channel,
-					EP_MODE_AUTOREG_NONE);
+					EP_MODE_AUTOREQ_NONE);
 		}
 	} else {
 		/* fallback mode */
 		cppi41_set_dma_mode(cppi41_channel, EP_MODE_DMA_TRANSPARENT);
-		cppi41_set_autoreq_mode(cppi41_channel, EP_MODE_AUTOREG_NONE);
+		cppi41_set_autoreq_mode(cppi41_channel, EP_MODE_AUTOREQ_NONE);
 		len = min_t(u32, packet_sz, len);
 	}
 	cppi41_channel->prog_len = len;
Signature · 1 line
2.7.2
author
#3 lore raw

PATCH 3/116 af_iucv: Validate socket address length in iucv_sock_bind()

In reply to Jiri Slaby

From: Ursula Braun <[email protected]>

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

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

[ Upstream commit 52a82e23b9f2a9e1d429c5207f8575784290d008 ]

---
 net/iucv/af_iucv.c | 3 +++
 1 file changed, 3 insertions(+)
net/iucv/af_iucv.c +3 -0
index 1465363a452b..bb3969a40b8e 100644
@@ -697,6 +697,9 @@ static int iucv_sock_bind(struct socket *sock, struct sockaddr *addr,
 	if (!addr || addr->sa_family != AF_IUCV)
 		return -EINVAL;
 
+	if (addr_len < sizeof(struct sockaddr_iucv))
+		return -EINVAL;
+
 	lock_sock(sk);
 	if (sk->sk_state != IUCV_OPEN) {
 		err = -EBADFD;
Signature · 1 line
2.7.2
author
#4 lore raw

PATCH 4/116 net: dp83640: Fix tx timestamp overflow handling.

In reply to Jiri Slaby

From: Manfred Rudigier <[email protected]>

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

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

[ Upstream commit 81e8f2e930fe76b9814c71b9d87c30760b5eb705 ]

PHY status frames are not reliable, the PHY may not be able to send them during heavy receive traffic. This overflow condition is signaled by the PHY in the next status frame, but the driver did not make use of it. Instead it always reported wrong tx timestamps to user space after an overflow happened because it assigned newly received tx timestamps to old packets in the queue.

This commit fixes this issue by clearing the tx timestamp queue every time an overflow happens, so that no timestamps are delivered for overflow packets. This way time stamping will continue correctly after an overflow.

---
 drivers/net/phy/dp83640.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
drivers/net/phy/dp83640.c +17 -0
index d2907a6e3dab..be37c042cd69 100644
@@ -698,6 +698,11 @@ static void decode_rxts(struct dp83640_private *dp83640,
 {
 	struct rxts *rxts;
 	unsigned long flags;
+	u8 overflow;
+
+	overflow = (phy_rxts->ns_hi >> 14) & 0x3;
+	if (overflow)
+		pr_debug("rx timestamp queue overflow, count %d\n", overflow);
 
 	spin_lock_irqsave(&dp83640->rx_lock, flags);
 
@@ -721,6 +726,7 @@ static void decode_txts(struct dp83640_private *dp83640,
 	struct skb_shared_hwtstamps shhwtstamps;
 	struct sk_buff *skb;
 	u64 ns;
+	u8 overflow;
 
 	/* We must already have the skb that triggered this. */
 
@@ -730,6 +736,17 @@ static void decode_txts(struct dp83640_private *dp83640,
 		pr_debug("have timestamp but tx_queue empty\n");
 		return;
 	}
+
+	overflow = (phy_txts->ns_hi >> 14) & 0x3;
+	if (overflow) {
+		pr_debug("tx timestamp queue overflow, count %d\n", overflow);
+		while (skb) {
+			skb_complete_tx_timestamp(skb, NULL);
+			skb = skb_dequeue(&dp83640->tx_queue);
+		}
+		return;
+	}
+
 	ns = phy2txts(phy_txts);
 	memset(&shhwtstamps, 0, sizeof(shhwtstamps));
 	shhwtstamps.hwtstamp = ns_to_ktime(ns);
Signature · 1 line
2.7.2
author
#5 lore raw

PATCH 5/116 tcp: fix NULL deref in tcp_v4_send_ack()

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 e62a123b8ef7c5dc4db2c16383d506860ad21b47 ]

Neal reported crashes with this stack trace :

 RIP: 0010:[<ffffffff8c57231b>] tcp_v4_send_ack+0x41/0x20f
...
 CR2: 0000000000000018 CR3: 000000044005c000 CR4: 00000000001427e0
...
  [<ffffffff8c57258e>] tcp_v4_reqsk_send_ack+0xa5/0xb4
  [<ffffffff8c1a7caa>] tcp_check_req+0x2ea/0x3e0
  [<ffffffff8c19e420>] tcp_rcv_state_process+0x850/0x2500
  [<ffffffff8c1a6d21>] tcp_v4_do_rcv+0x141/0x330
  [<ffffffff8c56cdb2>] sk_backlog_rcv+0x21/0x30
  [<ffffffff8c098bbd>] tcp_recvmsg+0x75d/0xf90
  [<ffffffff8c0a8700>] inet_recvmsg+0x80/0xa0
  [<ffffffff8c17623e>] sock_aio_read+0xee/0x110
  [<ffffffff8c066fcf>] do_sync_read+0x6f/0xa0
  [<ffffffff8c0673a1>] SyS_read+0x1e1/0x290
  [<ffffffff8c5ca262>] system_call_fastpath+0x16/0x1b

The problem here is the skb we provide to tcp_v4_send_ack() had to be parked in the backlog of a new TCP fastopen child because this child was owned by the user at the time an out of window packet arrived.

Before queuing a packet, TCP has to set skb->dev to NULL as the device could disappear before packet is removed from the queue.

Fix this issue by using the net pointer provided by the socket (being a timewait or a request socket).

IPv6 is immune to the bug : tcp_v6_send_response() already gets the net pointer from the socket if provided.

Fixes 168a8f58059a ("tcp: TCP Fast Open Server - main code path")
Cc Jerry Chu <[email protected]>
Cc Yuchung Cheng <[email protected]>
---
 net/ipv4/tcp_ipv4.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)
net/ipv4/tcp_ipv4.c +8 -5
index 09451a2cbd6a..6184d17c9126 100644
@@ -710,7 +710,8 @@ release_sk1:
    outside socket context is ugly, certainly. What can I do?
  */
 
-static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
+static void tcp_v4_send_ack(struct net *net,
+			    struct sk_buff *skb, u32 seq, u32 ack,
 			    u32 win, u32 tsval, u32 tsecr, int oif,
 			    struct tcp_md5sig_key *key,
 			    int reply_flags, u8 tos)
@@ -725,7 +726,6 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
 			];
 	} rep;
 	struct ip_reply_arg arg;
-	struct net *net = dev_net(skb_dst(skb)->dev);
 
 	memset(&rep.th, 0, sizeof(struct tcphdr));
 	memset(&arg, 0, sizeof(arg));
@@ -786,7 +786,8 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
 	struct inet_timewait_sock *tw = inet_twsk(sk);
 	struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
 
-	tcp_v4_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
+	tcp_v4_send_ack(sock_net(sk), skb,
+			tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
 			tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
 			tcp_time_stamp + tcptw->tw_ts_offset,
 			tcptw->tw_ts_recent,
@@ -805,8 +806,10 @@ static void tcp_v4_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
 	/* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV
 	 * sk->sk_state == TCP_SYN_RECV -> for Fast Open.
 	 */
-	tcp_v4_send_ack(skb, (sk->sk_state == TCP_LISTEN) ?
-			tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt,
+	u32 seq = (sk->sk_state == TCP_LISTEN) ? tcp_rsk(req)->snt_isn + 1 :
+					     tcp_sk(sk)->snd_nxt;
+
+	tcp_v4_send_ack(sock_net(sk), skb, seq,
 			tcp_rsk(req)->rcv_nxt, req->rcv_wnd,
 			tcp_time_stamp,
 			req->ts_recent,
Signature · 1 line
2.7.2
author
#6 lore raw

PATCH 6/116 af_unix: fix struct pid memory leak

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 fa0dc04df259ba2df3ce1920e9690c7842f8fa4b ]

Dmitry reported a struct pid leak detected by a syzkaller program.

Bug happens in unix_stream_recvmsg() when we break the loop when a signal is pending, without properly releasing scm.

Fixes b3ca9b02b007 ("net: fix multithreaded signal handling in unix recv routines")
Cc Rainer Weikusat <[email protected]>
---
 net/unix/af_unix.c | 1 +
 1 file changed, 1 insertion(+)
net/unix/af_unix.c +1 -0
index 31b88dcb0f01..5fb2d2af3e52 100644
@@ -2131,6 +2131,7 @@ again:
 
 			if (signal_pending(current)) {
 				err = sock_intr_errno(timeo);
+				scm_destroy(siocb->scm);
 				goto out;
 			}
 
Signature · 1 line
2.7.2
author
#7 lore raw

PATCH 7/116 pptp: fix illegal memory access caused by multiple bind()s

In reply to Jiri Slaby

From: Hannes Frederic Sowa <[email protected]>

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

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

[ Upstream commit 9a368aff9cb370298fa02feeffa861f2db497c18 ]

Several times already this has been reported as kasan reports caused by syzkaller and trinity and people always looked at RCU races, but it is much more simple. :)

In case we bind a pptp socket multiple times, we simply add it to the callid_sock list but don't remove the old binding. Thus the old socket stays in the bucket with unused call_id indexes and doesn't get cleaned up. This causes various forms of kasan reports which were hard to pinpoint.

Simply don't allow multiple binds and correct error handling in pptp_bind. Also keep sk_state bits in place in pptp_connect.

Fixes 00959ade36acad ("PPTP: PPP over IPv4 (Point-to-Point Tunneling Protocol)")
Cc Dmitry Kozlov <[email protected]>
Cc Sasha Levin <[email protected]>
Cc Dmitry Vyukov <[email protected]>
Cc Dave Jones <[email protected]>
---
 drivers/net/ppp/pptp.c | 34 ++++++++++++++++++++++++----------
 1 file changed, 24 insertions(+), 10 deletions(-)
drivers/net/ppp/pptp.c +24 -10
index 0710214df2bf..bb1ab1ffbc8b 100644
@@ -131,24 +131,27 @@ static int lookup_chan_dst(u16 call_id, __be32 d_addr)
 	return i < MAX_CALLID;
 }
 
-static int add_chan(struct pppox_sock *sock)
+static int add_chan(struct pppox_sock *sock,
+		    struct pptp_addr *sa)
 {
 	static int call_id;
 
 	spin_lock(&chan_lock);
-	if (!sock->proto.pptp.src_addr.call_id)	{
+	if (!sa->call_id)	{
 		call_id = find_next_zero_bit(callid_bitmap, MAX_CALLID, call_id + 1);
 		if (call_id == MAX_CALLID) {
 			call_id = find_next_zero_bit(callid_bitmap, MAX_CALLID, 1);
 			if (call_id == MAX_CALLID)
 				goto out_err;
 		}
-		sock->proto.pptp.src_addr.call_id = call_id;
-	} else if (test_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap))
+		sa->call_id = call_id;
+	} else if (test_bit(sa->call_id, callid_bitmap)) {
 		goto out_err;
+	}
 
-	set_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap);
-	rcu_assign_pointer(callid_sock[sock->proto.pptp.src_addr.call_id], sock);
+	sock->proto.pptp.src_addr = *sa;
+	set_bit(sa->call_id, callid_bitmap);
+	rcu_assign_pointer(callid_sock[sa->call_id], sock);
 	spin_unlock(&chan_lock);
 
 	return 0;
@@ -417,7 +420,6 @@ static int pptp_bind(struct socket *sock, struct sockaddr *uservaddr,
 	struct sock *sk = sock->sk;
 	struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr;
 	struct pppox_sock *po = pppox_sk(sk);
-	struct pptp_opt *opt = &po->proto.pptp;
 	int error = 0;
 
 	if (sockaddr_len < sizeof(struct sockaddr_pppox))
@@ -425,10 +427,22 @@ static int pptp_bind(struct socket *sock, struct sockaddr *uservaddr,
 
 	lock_sock(sk);
 
-	opt->src_addr = sp->sa_addr.pptp;
-	if (add_chan(po))
+	if (sk->sk_state & PPPOX_DEAD) {
+		error = -EALREADY;
+		goto out;
+	}
+
+	if (sk->sk_state & PPPOX_BOUND) {
 		error = -EBUSY;
+		goto out;
+	}
+
+	if (add_chan(po, &sp->sa_addr.pptp))
+		error = -EBUSY;
+	else
+		sk->sk_state |= PPPOX_BOUND;
 
+out:
 	release_sock(sk);
 	return error;
 }
@@ -499,7 +513,7 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr,
 	}
 
 	opt->dst_addr = sp->sa_addr.pptp;
-	sk->sk_state = PPPOX_CONNECTED;
+	sk->sk_state |= PPPOX_CONNECTED;
 
  end:
 	release_sock(sk);
Signature · 1 line
2.7.2
author
#8 lore raw

PATCH 8/116 sctp: allow setting SCTP_SACK_IMMEDIATELY by the application

In reply to Jiri Slaby

From: Marcelo Ricardo Leitner <[email protected]>

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

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

[ Upstream commit 27f7ed2b11d42ab6d796e96533c2076ec220affc ]

This patch extends commit b93d6471748d ("sctp: implement the sender side for SACK-IMMEDIATELY extension") as it didn't white list SCTP_SACK_IMMEDIATELY on sctp_msghdr_parse(), causing it to be understood as an invalid flag and returning -EINVAL to the application.

Note that the actual handling of the flag is already there in sctp_datamsg_from_user().

https://tools.ietf.org/html/rfc7053#section-7

Fixes b93d6471748d ("sctp: implement the sender side for SACK-IMMEDIATELY extension")
---
 net/sctp/socket.c | 1 +
 1 file changed, 1 insertion(+)
net/sctp/socket.c +1 -0
index 9c47fbc5de0c..92de688a966f 100644
@@ -6420,6 +6420,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs)
 			/* Minimally, validate the sinfo_flags. */
 			if (cmsgs->info->sinfo_flags &
 			    ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
+			      SCTP_SACK_IMMEDIATELY |
 			      SCTP_ABORT | SCTP_EOF))
 				return -EINVAL;
 			break;
Signature · 1 line
2.7.2
author
#9 lore raw

PATCH 9/116 ipv6/udp: use sticky pktinfo egress ifindex on connect()

In reply to Jiri Slaby

From: Paolo Abeni <[email protected]>

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

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

[ Upstream commit 1cdda91871470f15e79375991bd2eddc6e86ddb1 ]

Currently, the egress interface index specified via IPV6_PKTINFO is ignored by __ip6_datagram_connect(), so that RFC 3542 section 6.7 can be subverted when the user space application calls connect() before sendmsg().
Fix it by initializing properly flowi6_oif in connect() before performing the route lookup.

---
 net/ipv6/datagram.c | 3 +++
 1 file changed, 3 insertions(+)
net/ipv6/datagram.c +3 -0
index e24fa8c01dd2..fcfa2885df0e 100644
@@ -163,6 +163,9 @@ ipv4_connected:
 	fl6.fl6_dport = inet->inet_dport;
 	fl6.fl6_sport = inet->inet_sport;
 
+	if (!fl6.flowi6_oif)
+		fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex;
+
 	if (!fl6.flowi6_oif && (addr_type&IPV6_ADDR_MULTICAST))
 		fl6.flowi6_oif = np->mcast_oif;
 
Signature · 1 line
2.7.2
author
#10 lore raw

PATCH 10/116 net/ipv6: add sysctl option accept_ra_min_hop_limit

In reply to Jiri Slaby

From: Hangbin Liu <[email protected]>

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

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

[ Upstream commit 8013d1d7eafb0589ca766db6b74026f76b7f5cb4 ]

Commit 6fd99094de2b ("ipv6: Don't reduce hop limit for an interface") disabled accept hop limit from RA if it is smaller than the current hop limit for security stuff. But this behavior kind of break the RFC definition.

RFC 4861, 6.3.4. Processing Received Router Advertisements
A Router Advertisement field (e.g., Cur Hop Limit, Reachable Time, and Retrans Timer) may contain a value denoting that it is unspecified. In such cases, the parameter should be ignored and the host should continue using whatever value it is already using.

If the received Cur Hop Limit value is non-zero, the host SHOULD set its CurHopLimit variable to the received value.

So add sysctl option accept_ra_min_hop_limit to let user choose the minimum hop limit value they can accept from RA. And set default to 1 to meet RFC standards.

---
 Documentation/networking/ip-sysctl.txt |  8 ++++++++
 include/linux/ipv6.h                   |  1 +
 include/uapi/linux/ipv6.h              |  2 ++
 net/ipv6/addrconf.c                    | 10 ++++++++++
 net/ipv6/ndisc.c                       | 16 +++++++---------
 5 files changed, 28 insertions(+), 9 deletions(-)
Documentation/networking/ip-sysctl.txt +8 -0
index 7d8dc93fe2eb..3e5b1b5466e5 100644
@@ -1156,6 +1156,14 @@ accept_ra_defrtr - BOOLEAN
 	Functional default: enabled if accept_ra is enabled.
 			    disabled if accept_ra is disabled.
 
+accept_ra_min_hop_limit - INTEGER
+	Minimum hop limit Information in Router Advertisement.
+
+	Hop limit Information in Router Advertisement less than this
+	variable shall be ignored.
+
+	Default: 1
+
 accept_ra_pinfo - BOOLEAN
 	Learn Prefix Information in Router Advertisement.
 
include/linux/ipv6.h +1 -0
index 88c0cf0079ad..167c976554fa 100644
@@ -30,6 +30,7 @@ struct ipv6_devconf {
 #endif
 	__s32		max_addresses;
 	__s32		accept_ra_defrtr;
+	__s32		accept_ra_min_hop_limit;
 	__s32		accept_ra_pinfo;
 #ifdef CONFIG_IPV6_ROUTER_PREF
 	__s32		accept_ra_rtr_pref;
include/uapi/linux/ipv6.h +2 -0
index 593b0e32d956..25955206757a 100644
@@ -163,6 +163,8 @@ enum {
 	DEVCONF_MLDV1_UNSOLICITED_REPORT_INTERVAL,
 	DEVCONF_MLDV2_UNSOLICITED_REPORT_INTERVAL,
 	DEVCONF_SUPPRESS_FRAG_NDISC,
+	DEVCONF_USE_OIF_ADDRS_ONLY,
+	DEVCONF_ACCEPT_RA_MIN_HOP_LIMIT,
 	DEVCONF_MAX
 };
 
net/ipv6/addrconf.c +10 -0
index 38540a3ed92f..6c629ffb8756 100644
@@ -192,6 +192,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
 #endif
 	.max_addresses		= IPV6_MAX_ADDRESSES,
 	.accept_ra_defrtr	= 1,
+	.accept_ra_min_hop_limit= 1,
 	.accept_ra_pinfo	= 1,
 #ifdef CONFIG_IPV6_ROUTER_PREF
 	.accept_ra_rtr_pref	= 1,
@@ -230,6 +231,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
 #endif
 	.max_addresses		= IPV6_MAX_ADDRESSES,
 	.accept_ra_defrtr	= 1,
+	.accept_ra_min_hop_limit= 1,
 	.accept_ra_pinfo	= 1,
 #ifdef CONFIG_IPV6_ROUTER_PREF
 	.accept_ra_rtr_pref	= 1,
@@ -4150,6 +4152,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
 #endif
 	array[DEVCONF_MAX_ADDRESSES] = cnf->max_addresses;
 	array[DEVCONF_ACCEPT_RA_DEFRTR] = cnf->accept_ra_defrtr;
+	array[DEVCONF_ACCEPT_RA_MIN_HOP_LIMIT] = cnf->accept_ra_min_hop_limit;
 	array[DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo;
 #ifdef CONFIG_IPV6_ROUTER_PREF
 	array[DEVCONF_ACCEPT_RA_RTR_PREF] = cnf->accept_ra_rtr_pref;
@@ -4908,6 +4911,13 @@ static struct addrconf_sysctl_table
 			.proc_handler	= proc_dointvec,
 		},
 		{
+			.procname	= "accept_ra_min_hop_limit",
+			.data		= &ipv6_devconf.accept_ra_min_hop_limit,
+			.maxlen		= sizeof(int),
+			.mode		= 0644,
+			.proc_handler	= proc_dointvec,
+		},
+		{
 			.procname	= "accept_ra_pinfo",
 			.data		= &ipv6_devconf.accept_ra_pinfo,
 			.maxlen		= sizeof(int),
net/ipv6/ndisc.c +7 -9
index fda5d95e39f4..e34a6b3520c6 100644
@@ -1190,18 +1190,16 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 
 	if (rt)
 		rt6_set_expires(rt, jiffies + (HZ * lifetime));
-	if (ra_msg->icmph.icmp6_hop_limit) {
-		/* Only set hop_limit on the interface if it is higher than
-		 * the current hop_limit.
-		 */
-		if (in6_dev->cnf.hop_limit < ra_msg->icmph.icmp6_hop_limit) {
+	if (in6_dev->cnf.accept_ra_min_hop_limit < 256 &&
+	    ra_msg->icmph.icmp6_hop_limit) {
+		if (in6_dev->cnf.accept_ra_min_hop_limit <= ra_msg->icmph.icmp6_hop_limit) {
 			in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
+			if (rt)
+				dst_metric_set(&rt->dst, RTAX_HOPLIMIT,
+					       ra_msg->icmph.icmp6_hop_limit);
 		} else {
-			ND_PRINTK(2, warn, "RA: Got route advertisement with lower hop_limit than current\n");
+			ND_PRINTK(2, warn, "RA: Got route advertisement with lower hop_limit than minimum\n");
 		}
-		if (rt)
-			dst_metric_set(&rt->dst, RTAX_HOPLIMIT,
-				       ra_msg->icmph.icmp6_hop_limit);
 	}
 
 skip_defrtr:
Signature · 1 line
2.7.2
author
#11 lore raw

PATCH 11/116 ipv6: fix a lockdep splat

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 44c3d0c1c0a880354e9de5d94175742e2c7c9683 ]

Silence lockdep false positive about rcu_dereference() being used in the wrong context.

First one should use rcu_dereference_protected() as we own the spinlock.

Second one should be a normal assignation, as no barrier is needed.

Fixes 18367681a10bd ("ipv6 flowlabel: Convert np->ipv6_fl_list to RCU.")
---
 net/ipv6/ip6_flowlabel.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
net/ipv6/ip6_flowlabel.c +3 -2
index f0ccdb787100..d14c74b2dfa3 100644
@@ -527,12 +527,13 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
 	case IPV6_FL_A_PUT:
 		spin_lock_bh(&ip6_sk_fl_lock);
 		for (sflp = &np->ipv6_fl_list;
-		     (sfl = rcu_dereference(*sflp))!=NULL;
+		     (sfl = rcu_dereference_protected(*sflp,
+						      lockdep_is_held(&ip6_sk_fl_lock))) != NULL;
 		     sflp = &sfl->next) {
 			if (sfl->fl->label == freq.flr_label) {
 				if (freq.flr_label == (np->flow_label&IPV6_FLOWLABEL_MASK))
 					np->flow_label &= ~IPV6_FLOWLABEL_MASK;
-				*sflp = rcu_dereference(sfl->next);
+				*sflp = sfl->next;
 				spin_unlock_bh(&ip6_sk_fl_lock);
 				fl_release(sfl->fl);
 				kfree_rcu(sfl, rcu);
Signature · 1 line
2.7.2
author
#12 lore raw

PATCH 12/116 net:Add sysctl_max_skb_frags

In reply to Jiri Slaby

From: Hans Westgaard Ry <[email protected]>

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

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

[ Upstream commit 5f74f82ea34c0da80ea0b49192bb5ea06e063593 ]

Devices may have limits on the number of fragments in an skb they support. Current codebase uses a constant as maximum for number of fragments one skb can hold and use.
When enabling scatter/gather and running traffic with many small messages the codebase uses the maximum number of fragments and may thereby violate the max for certain devices.
The patch introduces a global variable as max number of fragments.

---
 include/linux/skbuff.h     |  1 +
 net/core/skbuff.c          |  2 ++
 net/core/sysctl_net_core.c | 10 ++++++++++
 net/ipv4/tcp.c             |  4 ++--
 4 files changed, 15 insertions(+), 2 deletions(-)
include/linux/skbuff.h +1 -0
index 16e753a9922a..e492ab7aadbf 100644
@@ -149,6 +149,7 @@ struct sk_buff;
 #else
 #define MAX_SKB_FRAGS (65536/PAGE_SIZE + 1)
 #endif
+extern int sysctl_max_skb_frags;
 
 typedef struct skb_frag_struct skb_frag_t;
 
net/core/skbuff.c +2 -0
index 56cdf3bb1e7f..7df6f539a402 100644
@@ -76,6 +76,8 @@
 
 struct kmem_cache *skbuff_head_cache __read_mostly;
 static struct kmem_cache *skbuff_fclone_cache __read_mostly;
+int sysctl_max_skb_frags __read_mostly = MAX_SKB_FRAGS;
+EXPORT_SYMBOL(sysctl_max_skb_frags);
 
 /**
  *	skb_panic - private function for out-of-line support
net/core/sysctl_net_core.c +10 -0
index f3413ae3d973..d7962397d90f 100644
@@ -27,6 +27,7 @@ static int one = 1;
 static int ushort_max = USHRT_MAX;
 static int min_sndbuf = SOCK_MIN_SNDBUF;
 static int min_rcvbuf = SOCK_MIN_RCVBUF;
+static int max_skb_frags = MAX_SKB_FRAGS;
 
 #ifdef CONFIG_RPS
 static int rps_sock_flow_sysctl(struct ctl_table *table, int write,
@@ -362,6 +363,15 @@ static struct ctl_table net_core_table[] = {
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec
 	},
+	{
+		.procname	= "max_skb_frags",
+		.data		= &sysctl_max_skb_frags,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &one,
+		.extra2		= &max_skb_frags,
+	},
 	{ }
 };
 
net/ipv4/tcp.c +2 -2
index a880ccc10f61..392d3259f9ad 100644
@@ -886,7 +886,7 @@ new_segment:
 
 		i = skb_shinfo(skb)->nr_frags;
 		can_coalesce = skb_can_coalesce(skb, i, page, offset);
-		if (!can_coalesce && i >= MAX_SKB_FRAGS) {
+		if (!can_coalesce && i >= sysctl_max_skb_frags) {
 			tcp_mark_push(tp, skb);
 			goto new_segment;
 		}
@@ -1169,7 +1169,7 @@ new_segment:
 
 				if (!skb_can_coalesce(skb, i, pfrag->page,
 						      pfrag->offset)) {
-					if (i == MAX_SKB_FRAGS || !sg) {
+					if (i == sysctl_max_skb_frags || !sg) {
 						tcp_mark_push(tp, skb);
 						goto new_segment;
 					}
Signature · 1 line
2.7.2
author
#13 lore raw

PATCH 13/116 tg3: Fix for tg3 transmit queue 0 timed out when too many gso_segs

In reply to Jiri Slaby

From: Siva Reddy Kallam <[email protected]>

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

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

[ Upstream commit b7d987295c74500b733a0ba07f9a9bcc4074fa83 ]

tg3_tso_bug() can hit a condition where the entire tx ring is not big enough to segment the GSO packet. For example, if MSS is very small, gso_segs can exceed the tx ring size. When we hit the condition, it will cause tx timeout.

tg3_tso_bug() is called to handle TSO and DMA hardware bugs. For TSO bugs, if tg3_tso_bug() cannot succeed, we have to drop the packet. For DMA bugs, we can still fall back to linearize the SKB and let the hardware transmit the TSO packet.

This patch adds a function tg3_tso_bug_gso_check() to check if there are enough tx descriptors for GSO before calling tg3_tso_bug(). The caller will then handle the error appropriately - drop or lineraize the SKB.

v2: Corrected patch description to avoid confusion.

---
 drivers/net/ethernet/broadcom/tg3.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)
drivers/net/ethernet/broadcom/tg3.c +18 -4
index fe601e264f94..ea86c17541b3 100644
@@ -7809,6 +7809,14 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
 	return ret;
 }
 
+static bool tg3_tso_bug_gso_check(struct tg3_napi *tnapi, struct sk_buff *skb)
+{
+	/* Check if we will never have enough descriptors,
+	 * as gso_segs can be more than current ring size
+	 */
+	return skb_shinfo(skb)->gso_segs < tnapi->tx_pending / 3;
+}
+
 static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *);
 
 /* Use GSO to workaround a rare TSO bug that may be triggered when the
@@ -7910,8 +7918,11 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		 * vlan encapsulated.
 		 */
 		if (skb->protocol == htons(ETH_P_8021Q) ||
-		    skb->protocol == htons(ETH_P_8021AD))
-			return tg3_tso_bug(tp, skb);
+		    skb->protocol == htons(ETH_P_8021AD)) {
+			if (tg3_tso_bug_gso_check(tnapi, skb))
+				return tg3_tso_bug(tp, skb);
+			goto drop;
+		}
 
 		if (!skb_is_gso_v6(skb)) {
 			iph->check = 0;
@@ -7919,8 +7930,11 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		}
 
 		if (unlikely((ETH_HLEN + hdr_len) > 80) &&
-		    tg3_flag(tp, TSO_BUG))
-			return tg3_tso_bug(tp, skb);
+		    tg3_flag(tp, TSO_BUG)) {
+			if (tg3_tso_bug_gso_check(tnapi, skb))
+				return tg3_tso_bug(tp, skb);
+			goto drop;
+		}
 
 		base_flags |= (TXD_FLAG_CPU_PRE_DMA |
 			       TXD_FLAG_CPU_POST_DMA);
Signature · 1 line
2.7.2
author
#14 lore raw

PATCH 14/116 sctp: translate network order to host order when users get a hmacid

In reply to Jiri Slaby

From: Xin Long <[email protected]>

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

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

[ Upstream commit 7a84bd46647ff181eb2659fdc99590e6f16e501d ]

Commit ed5a377d87dc ("sctp: translate host order to network order when setting a hmacid") corrected the hmacid byte-order when setting a hmacid. but the same issue also exists on getting a hmacid.

We fix it by changing hmacids to host order when users get them with getsockopt.

Fixes Commit ed5a377d87dc ("sctp: translate host order to network order when setting a hmacid")
---
 net/sctp/socket.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
net/sctp/socket.c +7 -2
index 92de688a966f..ead3a8adca08 100644
@@ -5369,6 +5369,7 @@ static int sctp_getsockopt_hmac_ident(struct sock *sk, int len,
 	struct sctp_hmac_algo_param *hmacs;
 	__u16 data_len = 0;
 	u32 num_idents;
+	int i;
 
 	if (!ep->auth_enable)
 		return -EACCES;
@@ -5386,8 +5387,12 @@ static int sctp_getsockopt_hmac_ident(struct sock *sk, int len,
 		return -EFAULT;
 	if (put_user(num_idents, &p->shmac_num_idents))
 		return -EFAULT;
-	if (copy_to_user(p->shmac_idents, hmacs->hmac_ids, data_len))
-		return -EFAULT;
+	for (i = 0; i < num_idents; i++) {
+		__u16 hmacid = ntohs(hmacs->hmac_ids[i]);
+
+		if (copy_to_user(&p->shmac_idents[i], &hmacid, sizeof(__u16)))
+			return -EFAULT;
+	}
 	return 0;
 }
 
Signature · 1 line
2.7.2
author
#15 lore raw

PATCH 15/116 bonding: fix bond_arp_rcv() race of curr_active_slave

In reply to Jiri Slaby

From: Veaceslav Falico <[email protected]>

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

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

commit 010d3c3989706d800ae72253773fa6537cc9f74c upstream.

bond->curr_active_slave can be changed between its deferences, even to NULL, and thus we might panic.

We're always holding the rcu (rx_handler->bond_handle_frame()->bond_arp_rcv()) so fix this by rcu_dereferencing() it and using the saved.

Fixes aeea64a ("bonding: don't trust arp requests unless active slave really works")
CC Jay Vosburgh <[email protected]>
CC Andy Gospodarek <[email protected]>
---
 drivers/net/bonding/bond_main.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
drivers/net/bonding/bond_main.c +7 -3
index b3892b0d2e61..282d416559dc 100644
@@ -2435,6 +2435,7 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
 		 struct slave *slave)
 {
 	struct arphdr *arp = (struct arphdr *)skb->data;
+	struct slave *curr_active_slave;
 	unsigned char *arp_ptr;
 	__be32 sip, tip;
 	int alen;
@@ -2479,6 +2480,8 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
 		 bond->params.arp_validate, slave_do_arp_validate(bond, slave),
 		 &sip, &tip);
 
+	curr_active_slave = rcu_dereference(bond->curr_active_slave);
+
 	/*
 	 * Backup slaves won't see the ARP reply, but do come through
 	 * here for each ARP probe (so we swap the sip/tip to validate
@@ -2492,11 +2495,12 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
 	 * is done to avoid endless looping when we can't reach the
 	 * arp_ip_target and fool ourselves with our own arp requests.
 	 */
+
 	if (bond_is_active_slave(slave))
 		bond_validate_arp(bond, slave, sip, tip);
-	else if (bond->curr_active_slave &&
-		 time_after(slave_last_rx(bond, bond->curr_active_slave),
-			    bond->curr_active_slave->jiffies))
+	else if (curr_active_slave &&
+		 time_after(slave_last_rx(bond, curr_active_slave),
+			    curr_active_slave->jiffies))
 		bond_validate_arp(bond, slave, tip, sip);
 
 out_unlock:
Signature · 1 line
2.7.2
author
#16 lore raw

PATCH 16/116 bonding: Fix ARP monitor validation

In reply to Jiri Slaby

From: Jay Vosburgh <[email protected]>

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

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

[ Upstream commit 21a75f0915dde8674708b39abfcda113911c49b1 ]

The current logic in bond_arp_rcv will accept an incoming ARP for validation if (a) the receiving slave is either "active" (which includes the currently active slave, or the current ARP slave) or, (b) there is a currently active slave, and it has received an ARP since it became active. For case (b), the receiving slave isn't the currently active slave, and is receiving the original broadcast ARP request, not an ARP reply from the target.

This logic can fail if there is no currently active slave. In
this situation, the ARP probe logic cycles through all slaves, assigning each in turn as the "current_arp_slave" for one arp_interval, then setting that one as "active," and sending an ARP probe from that slave. The current logic expects the ARP reply to arrive on the sending current_arp_slave, however, due to switch FDB updating delays, the reply may be directed to another slave.

This can arise if the bonding slaves and switch are working, but
the ARP target is not responding. When the ARP target recovers, a condition may result wherein the ARP target host replies faster than the switch can update its forwarding table, causing each ARP reply to be sent to the previous current_arp_slave. This will never pass the logic in bond_arp_rcv, as neither of the above conditions (a) or (b) are met.

Some experimentation on a LAN shows ARP reply round trips in the
200 usec range, but my available switches never update their FDB in less than 4000 usec.

This patch changes the logic in bond_arp_rcv to additionally
accept an ARP reply for validation on any slave if there is a current ARP slave and it sent an ARP probe during the previous arp_interval.

Fixes aeea64ac717a ("bonding: don't trust arp requests unless active slave really works")
Cc Veaceslav Falico <[email protected]>
Cc Andy Gospodarek <[email protected]>
---
 drivers/net/bonding/bond_main.c | 40 ++++++++++++++++++++++++++++------------
 1 file changed, 28 insertions(+), 12 deletions(-)
drivers/net/bonding/bond_main.c +28 -12
index 282d416559dc..5dcac318e317 100644
@@ -259,6 +259,8 @@ struct bond_parm_tbl ad_select_tbl[] = {
 
 static int bond_init(struct net_device *bond_dev);
 static void bond_uninit(struct net_device *bond_dev);
+static bool bond_time_in_interval(struct bonding *bond, unsigned long last_act,
+				  int mod);
 
 /*---------------------------- General routines -----------------------------*/
 
@@ -2435,7 +2437,7 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
 		 struct slave *slave)
 {
 	struct arphdr *arp = (struct arphdr *)skb->data;
-	struct slave *curr_active_slave;
+	struct slave *curr_active_slave, *curr_arp_slave;
 	unsigned char *arp_ptr;
 	__be32 sip, tip;
 	int alen;
@@ -2481,27 +2483,41 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
 		 &sip, &tip);
 
 	curr_active_slave = rcu_dereference(bond->curr_active_slave);
+	curr_arp_slave = rcu_dereference(bond->current_arp_slave);
 
-	/*
-	 * Backup slaves won't see the ARP reply, but do come through
-	 * here for each ARP probe (so we swap the sip/tip to validate
-	 * the probe).  In a "redundant switch, common router" type of
-	 * configuration, the ARP probe will (hopefully) travel from
-	 * the active, through one switch, the router, then the other
-	 * switch before reaching the backup.
+	/* We 'trust' the received ARP enough to validate it if:
+	 *
+	 * (a) the slave receiving the ARP is active (which includes the
+	 * current ARP slave, if any), or
+	 *
+	 * (b) the receiving slave isn't active, but there is a currently
+	 * active slave and it received valid arp reply(s) after it became
+	 * the currently active slave, or
 	 *
-	 * We 'trust' the arp requests if there is an active slave and
-	 * it received valid arp reply(s) after it became active. This
-	 * is done to avoid endless looping when we can't reach the
+	 * (c) there is an ARP slave that sent an ARP during the prior ARP
+	 * interval, and we receive an ARP reply on any slave.  We accept
+	 * these because switch FDB update delays may deliver the ARP
+	 * reply to a slave other than the sender of the ARP request.
+	 *
+	 * Note: for (b), backup slaves are receiving the broadcast ARP
+	 * request, not a reply.  This request passes from the sending
+	 * slave through the L2 switch(es) to the receiving slave.  Since
+	 * this is checking the request, sip/tip are swapped for
+	 * validation.
+	 *
+	 * This is done to avoid endless looping when we can't reach the
 	 * arp_ip_target and fool ourselves with our own arp requests.
 	 */
-
 	if (bond_is_active_slave(slave))
 		bond_validate_arp(bond, slave, sip, tip);
 	else if (curr_active_slave &&
 		 time_after(slave_last_rx(bond, curr_active_slave),
 			    curr_active_slave->jiffies))
 		bond_validate_arp(bond, slave, tip, sip);
+	else if (curr_arp_slave && (arp->ar_op == htons(ARPOP_REPLY)) &&
+		 bond_time_in_interval(bond,
+				       dev_trans_start(curr_arp_slave->dev), 1))
+		bond_validate_arp(bond, slave, sip, tip);
 
 out_unlock:
 	read_unlock(&bond->lock);
Signature · 1 line
2.7.2
author
#17 lore raw

PATCH 17/116 ipv4: fix memory leaks in ip_cmsg_send() callers

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 919483096bfe75dda338e98d56da91a263746a0a ]

Dmitry reported memory leaks of IP options allocated in ip_cmsg_send() when/if this function returns an error.

Callers are responsible for the freeing.

Many thanks to Dmitry for the report and diagnostic.

---
 net/ipv4/ip_sockglue.c | 2 ++
 net/ipv4/ping.c        | 4 +++-
 net/ipv4/raw.c         | 4 +++-
 net/ipv4/udp.c         | 4 +++-
 4 files changed, 11 insertions(+), 3 deletions(-)
net/ipv4/ip_sockglue.c +2 -0
index f6603142cb33..9e4f832aaf13 100644
@@ -200,6 +200,8 @@ int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc)
 		switch (cmsg->cmsg_type) {
 		case IP_RETOPTS:
 			err = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr));
+
+			/* Our caller is responsible for freeing ipc->opt */
 			err = ip_options_get(net, &ipc->opt, CMSG_DATA(cmsg),
 					     err < 40 ? err : 40);
 			if (err)
net/ipv4/ping.c +3 -1
index 54012b8c0ef9..716dff49d0b9 100644
@@ -740,8 +740,10 @@ int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 
 	if (msg->msg_controllen) {
 		err = ip_cmsg_send(sock_net(sk), msg, &ipc);
-		if (err)
+		if (unlikely(err)) {
+			kfree(ipc.opt);
 			return err;
+		}
 		if (ipc.opt)
 			free = 1;
 	}
net/ipv4/raw.c +3 -1
index 6183d36c038b..ed96b2320e5f 100644
@@ -523,8 +523,10 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 
 	if (msg->msg_controllen) {
 		err = ip_cmsg_send(sock_net(sk), msg, &ipc);
-		if (err)
+		if (unlikely(err)) {
+			kfree(ipc.opt);
 			goto out;
+		}
 		if (ipc.opt)
 			free = 1;
 	}
net/ipv4/udp.c +3 -1
index f8e304667108..f904b644a40c 100644
@@ -910,8 +910,10 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 
 	if (msg->msg_controllen) {
 		err = ip_cmsg_send(sock_net(sk), msg, &ipc);
-		if (err)
+		if (unlikely(err)) {
+			kfree(ipc.opt);
 			return err;
+		}
 		if (ipc.opt)
 			free = 1;
 		connected = 0;
Signature · 1 line
2.7.2
author
#18 lore raw

PATCH 18/116 af_unix: Guard against other == sk in unix_dgram_sendmsg

In reply to Jiri Slaby

From: Rainer Weikusat <[email protected]>

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

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

[ Upstream commit a5527dda344fff0514b7989ef7a755729769daa1 ]

The unix_dgram_sendmsg routine use the following test

if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {

to determine if sk and other are in an n:1 association (either established via connect or by using sendto to send messages to an unrelated socket identified by address). This isn't correct as the specified address could have been bound to the sending socket itself or because this socket could have been connected to itself by the time of the unix_peer_get but disconnected before the unix_state_lock(other). In both cases, the if-block would be entered despite other == sk which might either block the sender unintentionally or lead to trying to unlock the same spin lock twice for a non-blocking send. Add a other != sk check to guard against this.

Fixes 7d267278a9ec ("unix: avoid use-after-free in ep_remove_wait_queue")
---
 net/unix/af_unix.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
net/unix/af_unix.c +6 -1
index 5fb2d2af3e52..c5536b7d8ce4 100644
@@ -1700,7 +1700,12 @@ restart_locked:
 			goto out_unlock;
 	}
 
-	if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
+	/* other == sk && unix_peer(other) != sk if
+	 * - unix_peer(sk) == NULL, destination address bound to sk
+	 * - unix_peer(sk) == sk by time of get but disconnected before lock
+	 */
+	if (other != sk &&
+	    unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
 		if (timeo) {
 			timeo = unix_wait_for_peer(other, timeo);
 
Signature · 1 line
2.7.2
author
#19 lore raw

PATCH 19/116 qmi_wwan: add "4G LTE usb-modem U901"

In reply to Jiri Slaby

From: Bjørn Mork <[email protected]>

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

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

[ Upstream commit aac8d3c282e024c344c5b86dc1eab7af88bb9716 ]

Thomas reports:

T:  Bus=01 Lev=01 Prnt=01 Port=03 Cnt=01 Dev#=  4 Spd=480 MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=05c6 ProdID=6001 Rev=00.00
S:  Manufacturer=USB Modem
S:  Product=USB Modem
S:  SerialNumber=1234567890ABCDEF
C:  #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA
I:  If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I:  If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I:  If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I:  If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
I:  If#= 4 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
---
 drivers/net/usb/qmi_wwan.c | 1 +
 1 file changed, 1 insertion(+)
drivers/net/usb/qmi_wwan.c +1 -0
index 9356aa5f2033..0eb410b637de 100644
@@ -522,6 +522,7 @@ static const struct usb_device_id products[] = {
 
 	/* 3. Combined interface devices matching on interface number */
 	{QMI_FIXED_INTF(0x0408, 0xea42, 4)},	/* Yota / Megafon M100-1 */
+	{QMI_FIXED_INTF(0x05c6, 0x6001, 3)},	/* 4G LTE usb-modem U901 */
 	{QMI_FIXED_INTF(0x05c6, 0x7000, 0)},
 	{QMI_FIXED_INTF(0x05c6, 0x7001, 1)},
 	{QMI_FIXED_INTF(0x05c6, 0x7002, 1)},
Signature · 1 line
2.7.2
author
#20 lore raw

PATCH 20/116 net/mlx4_en: Count HW buffer overrun only once

In reply to Jiri Slaby

From: Amir Vadai <[email protected]>

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

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

[ Upstream commit 281e8b2fdf8e4ef366b899453cae50e09b577ada ]

RdropOvflw counts overrun of HW buffer, therefore should be used for rx_fifo_errors only.

Currently RdropOvflw counter is mistakenly also set into rx_missed_errors and rx_over_errors too, which makes the device total dropped packets accounting to show wrong results.

Fix that. Use it for rx_fifo_errors only.

Fixes c27a02cd94d6 ('mlx4_en: Add driver for Mellanox ConnectX 10GbE NIC')
---
 drivers/net/ethernet/mellanox/mlx4/en_port.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx4/en_port.c +2 -2
index 331791467a22..85dcd178e5ed 100644
@@ -174,11 +174,11 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
 			   be64_to_cpu(mlx4_en_stats->MCAST_novlan);
 	stats->collisions = 0;
 	stats->rx_length_errors = be32_to_cpu(mlx4_en_stats->RdropLength);
-	stats->rx_over_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
+	stats->rx_over_errors = 0;
 	stats->rx_crc_errors = be32_to_cpu(mlx4_en_stats->RCRC);
 	stats->rx_frame_errors = 0;
 	stats->rx_fifo_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
-	stats->rx_missed_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
+	stats->rx_missed_errors = 0;
 	stats->tx_aborted_errors = 0;
 	stats->tx_carrier_errors = 0;
 	stats->tx_fifo_errors = 0;
Signature · 1 line
2.7.2
author
#21 lore raw

PATCH 21/116 net/mlx4_en: Choose time-stamping shift value according to HW frequency

In reply to Jiri Slaby

From: Eugenia Emantayev <[email protected]>

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

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

[ Upstream commit 31c128b66e5b28f468076e4f3ca3025c35342041 ]

Previously, the shift value used for time-stamping was constant and didn't depend on the HW chip frequency. Change that to take the frequency into account and calculate the maximal value in cycles per wraparound of ten seconds. This time slot was chosen since it gives a good accuracy in time synchronization.

Algorithm for shift value calculation:
* Round up the maximal value in cycles to nearest power of two

* Calculate maximal multiplier by division of all 64 bits set to above result

* Then, invert the function clocksource_khz2mult() to get the shift from maximal mult value

Fixes ec693d47010e ('net/mlx4_en: Add HW timestamping (TS) support')
---
 drivers/net/ethernet/mellanox/mlx4/en_clock.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)
drivers/net/ethernet/mellanox/mlx4/en_clock.c +19 -6
index fd6441071319..9180c7e72c65 100644
@@ -111,6 +111,24 @@ void mlx4_en_fill_hwtstamps(struct mlx4_en_dev *mdev,
 	hwts->hwtstamp = ns_to_ktime(nsec);
 }
 
+#define MLX4_EN_WRAP_AROUND_SEC	10ULL
+
+/* This function calculates the max shift that enables the user range
+ * of MLX4_EN_WRAP_AROUND_SEC values in the cycles register.
+ */
+static u32 freq_to_shift(u16 freq)
+{
+	u32 freq_khz = freq * 1000;
+	u64 max_val_cycles = freq_khz * 1000 * MLX4_EN_WRAP_AROUND_SEC;
+	u64 max_val_cycles_rounded = is_power_of_2(max_val_cycles + 1) ?
+		max_val_cycles : roundup_pow_of_two(max_val_cycles) - 1;
+	/* calculate max possible multiplier in order to fit in 64bit */
+	u64 max_mul = div_u64(0xffffffffffffffffULL, max_val_cycles_rounded);
+
+	/* This comes from the reverse of clocksource_khz2mult */
+	return ilog2(div_u64(max_mul * freq_khz, 1000000));
+}
+
 void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev)
 {
 	struct mlx4_dev *dev = mdev->dev;
@@ -119,12 +137,7 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev)
 	memset(&mdev->cycles, 0, sizeof(mdev->cycles));
 	mdev->cycles.read = mlx4_en_read_clock;
 	mdev->cycles.mask = CLOCKSOURCE_MASK(48);
-	/* Using shift to make calculation more accurate. Since current HW
-	 * clock frequency is 427 MHz, and cycles are given using a 48 bits
-	 * register, the biggest shift when calculating using u64, is 14
-	 * (max_cycles * multiplier < 2^64)
-	 */
-	mdev->cycles.shift = 14;
+	mdev->cycles.shift = freq_to_shift(dev->caps.hca_core_clock);
 	mdev->cycles.mult =
 		clocksource_khz2mult(1000 * dev->caps.hca_core_clock, mdev->cycles.shift);
 
Signature · 1 line
2.7.2
author
#22 lore raw

PATCH 22/116 pppoe: fix reference counting in PPPoE proxy

In reply to Jiri Slaby

From: Guillaume Nault <[email protected]>

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

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

[ Upstream commit 29e73269aa4d36f92b35610c25f8b01c789b0dc8 ]

Drop reference on the relay_po socket when __pppoe_xmit() succeeds. This is already handled correctly in the error path.

---
 drivers/net/ppp/pppoe.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/net/ppp/pppoe.c +2 -0
index 1cfd4e841854..ec982788e6db 100644
@@ -392,6 +392,8 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb)
 
 		if (!__pppoe_xmit(sk_pppox(relay_po), skb))
 			goto abort_put;
+
+		sock_put(sk_pppox(relay_po));
 	} else {
 		if (sock_queue_rcv_skb(sk, skb))
 			goto abort_kfree;
Signature · 1 line
2.7.2
author
#23 lore raw

PATCH 23/116 route: check and remove route cache when we get route

In reply to Jiri Slaby

From: Xin Long <[email protected]>

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

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

[ Upstream commit deed49df7390d5239024199e249190328f1651e7 ]

Since the gc of ipv4 route was removed, the route cached would has no chance to be removed, and even it has been timeout, it still could be used, cause no code to check it's expires.

Fix this issue by checking and removing route cache when we get route.

---
 include/net/ip_fib.h |  1 +
 net/ipv4/route.c     | 77 ++++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 64 insertions(+), 14 deletions(-)
include/net/ip_fib.h +1 -0
index cbf2be37c91a..4dae9d5268ca 100644
@@ -59,6 +59,7 @@ struct fib_nh_exception {
 	struct rtable __rcu		*fnhe_rth_input;
 	struct rtable __rcu		*fnhe_rth_output;
 	unsigned long			fnhe_stamp;
+	struct rcu_head			rcu;
 };
 
 struct fnhe_hash_bucket {
net/ipv4/route.c +63 -14

119 lines not on this page · raw message

Signature · 1 line
2.7.2
author
#24 lore raw

PATCH 24/116 rtnl: RTM_GETNETCONF: fix wrong return value

In reply to Jiri Slaby

From: Anton Protopopov <[email protected]>

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

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

[ Upstream commit a97eb33ff225f34a8124774b3373fd244f0e83ce ]

An error response from a RTM_GETNETCONF request can return the positive error value EINVAL in the struct nlmsgerr that can mislead userspace.

---
 net/ipv4/devinet.c  | 2 +-
 net/ipv6/addrconf.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
net/ipv4/devinet.c +1 -1
index f4b34d8f92fe..68447109000f 100644
@@ -1785,7 +1785,7 @@ static int inet_netconf_get_devconf(struct sk_buff *in_skb,
 	if (err < 0)
 		goto errout;
 
-	err = EINVAL;
+	err = -EINVAL;
 	if (!tb[NETCONFA_IFINDEX])
 		goto errout;
 
net/ipv6/addrconf.c +1 -1
index 6c629ffb8756..bbf35875e4ef 100644
@@ -528,7 +528,7 @@ static int inet6_netconf_get_devconf(struct sk_buff *in_skb,
 	if (err < 0)
 		goto errout;
 
-	err = EINVAL;
+	err = -EINVAL;
 	if (!tb[NETCONFA_IFINDEX])
 		goto errout;
 
Signature · 1 line
2.7.2
author
#25 lore raw

PATCH 25/116 unix_diag: fix incorrect sign extension in unix_lookup_by_ino

In reply to Jiri Slaby

From: "Dmitry V. Levin" <[email protected]>

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

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

[ Upstream commit b5f0549231ffb025337be5a625b0ff9f52b016f0 ]

The value passed by unix_diag_get_exact to unix_lookup_by_ino has type __u32, but unix_lookup_by_ino's argument ino has type int, which is not a problem yet.
However, when ino is compared with sock_i_ino return value of type unsigned long, ino is sign extended to signed long, and this results to incorrect comparison on 64-bit architectures for inode numbers greater than INT_MAX.

This bug was found by strace test suite.

Fixes 5d3cae8bc39d ("unix_diag: Dumping exact socket core")
---
 net/unix/diag.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/unix/diag.c +1 -1
index 86fa0f3b2caf..27dd3dcb7739 100644
@@ -219,7 +219,7 @@ done:
 	return skb->len;
 }
 
-static struct sock *unix_lookup_by_ino(int ino)
+static struct sock *unix_lookup_by_ino(unsigned int ino)
 {
 	int i;
 	struct sock *sk;
Signature · 1 line
2.7.2
author
#26 lore raw

PATCH 26/116 sctp: Fix port hash table size computation

In reply to Jiri Slaby

From: Neil Horman <[email protected]>

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

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

[ Upstream commit d9749fb5942f51555dc9ce1ac0dbb1806960a975 ]

Dmitry Vyukov noted recently that the sctp_port_hashtable had an error in its size computation, observing that the current method never guaranteed that the hashsize (measured in number of entries) would be a power of two, which the input hash function for that table requires. The root cause of the problem is that two values need to be computed (one, the allocation order of the storage requries, as passed to __get_free_pages, and two the number of entries for the hash table). Both need to be ^2, but for different reasons, and the existing code is simply computing one order value, and using it as the basis for both, which is wrong (i.e. it assumes that ((1<<order)*PAGE_SIZE)/sizeof(bucket) is still ^2 when its not).

To fix this, we change the logic slightly. We start by computing a goal allocation order (which is limited by the maximum size hash table we want to support. Then we attempt to allocate that size table, decreasing the order until a successful allocation is made. Then, with the resultant successful order we compute the number of buckets that hash table supports, which we then round down to the nearest power of two, giving us the number of entries the table actually supports.

I've tested this locally here, using non-debug and spinlock-debug kernels, and the number of entries in the hashtable consistently work out to be powers of two in all cases.

---
 net/sctp/protocol.c | 47 ++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 38 insertions(+), 9 deletions(-)
net/sctp/protocol.c +38 -9
index 599757e0c23a..d8689fc37fcb 100644
@@ -61,6 +61,8 @@
 #include <net/inet_common.h>
 #include <net/inet_ecn.h>
 
+#define MAX_SCTP_PORT_HASH_ENTRIES (64 * 1024)
+
 /* Global data structures. */
 struct sctp_globals sctp_globals __read_mostly;
 
@@ -1333,6 +1335,8 @@ static __init int sctp_init(void)
 	unsigned long limit;
 	int max_share;
 	int order;
+	int num_entries;
+	int max_entry_order;
 
 	BUILD_BUG_ON(sizeof(struct sctp_ulpevent) >
 		     sizeof(((struct sk_buff *) 0)->cb));
@@ -1386,14 +1390,24 @@ static __init int sctp_init(void)
 
 	/* Size and allocate the association hash table.
 	 * The methodology is similar to that of the tcp hash tables.
+	 * Though not identical.  Start by getting a goal size
 	 */
 	if (totalram_pages >= (128 * 1024))
 		goal = totalram_pages >> (22 - PAGE_SHIFT);
 	else
 		goal = totalram_pages >> (24 - PAGE_SHIFT);
 
-	for (order = 0; (1UL << order) < goal; order++)
-		;
+	/* Then compute the page order for said goal */
+	order = get_order(goal);
+
+	/* Now compute the required page order for the maximum sized table we
+	 * want to create
+	 */
+	max_entry_order = get_order(MAX_SCTP_PORT_HASH_ENTRIES *
+				    sizeof(struct sctp_bind_hashbucket));
+
+	/* Limit the page order by that maximum hash table size */
+	order = min(order, max_entry_order);
 
 	do {
 		sctp_assoc_hashsize = (1UL << order) * PAGE_SIZE /
@@ -1427,27 +1441,42 @@ static __init int sctp_init(void)
 		INIT_HLIST_HEAD(&sctp_ep_hashtable[i].chain);
 	}
 
-	/* Allocate and initialize the SCTP port hash table.  */
+	/* Allocate and initialize the SCTP port hash table.
+	 * Note that order is initalized to start at the max sized
+	 * table we want to support.  If we can't get that many pages
+	 * reduce the order and try again
+	 */
 	do {
-		sctp_port_hashsize = (1UL << order) * PAGE_SIZE /
-					sizeof(struct sctp_bind_hashbucket);
-		if ((sctp_port_hashsize > (64 * 1024)) && order > 0)
-			continue;
 		sctp_port_hashtable = (struct sctp_bind_hashbucket *)
 			__get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order);
 	} while (!sctp_port_hashtable && --order > 0);
+
 	if (!sctp_port_hashtable) {
 		pr_err("Failed bind hash alloc\n");
 		status = -ENOMEM;
 		goto err_bhash_alloc;
 	}
+
+	/* Now compute the number of entries that will fit in the
+	 * port hash space we allocated
+	 */
+	num_entries = (1UL << order) * PAGE_SIZE /
+		      sizeof(struct sctp_bind_hashbucket);
+
+	/* And finish by rounding it down to the nearest power of two
+	 * this wastes some memory of course, but its needed because
+	 * the hash function operates based on the assumption that
+	 * that the number of entries is a power of two
+	 */
+	sctp_port_hashsize = rounddown_pow_of_two(num_entries);
+
 	for (i = 0; i < sctp_port_hashsize; i++) {
 		spin_lock_init(&sctp_port_hashtable[i].lock);
 		INIT_HLIST_HEAD(&sctp_port_hashtable[i].chain);
 	}
 
-	pr_info("Hash tables configured (established %d bind %d)\n",
-		sctp_assoc_hashsize, sctp_port_hashsize);
+	pr_info("Hash tables configured (established %d bind %d/%d)\n",
+		sctp_assoc_hashsize, sctp_port_hashsize, num_entries);
 
 	sctp_sysctl_register();
 
Signature · 1 line
2.7.2
author
#27 lore raw

PATCH 27/116 tracepoints: Do not trace when cpu is offline

In reply to Jiri Slaby

From: "Steven Rostedt (Red Hat)" <[email protected]>

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

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

commit f37755490fe9bf76f6ba1d8c6591745d3574a6a6 upstream.

The tracepoint infrastructure uses RCU sched protection to enable and disable tracepoints safely. There are some instances where tracepoints are used in infrastructure code (like kfree()) that get called after a CPU is going offline, and perhaps when it is coming back online but hasn't been registered yet.

This can probuce the following warning:

[ INFO: suspicious RCU usage. ]
4.4.0-00006-g0fe53e8-dirty #34 Tainted: G S
-------------------------------
include/trace/events/kmem.h:141 suspicious rcu_dereference_check() usage!

other info that might help us debug this:

RCU used illegally from offline CPU! rcu_scheduler_active = 1, debug_locks = 1 no locks held by swapper/8/0.

 stack backtrace:
  CPU: 8 PID: 0 Comm: swapper/8 Tainted: G S              4.4.0-00006-g0fe53e8-dirty #34
  Call Trace:
  [c0000005b76c78d0] [c0000000008b9540] .dump_stack+0x98/0xd4 (unreliable)
  [c0000005b76c7950] [c00000000010c898] .lockdep_rcu_suspicious+0x108/0x170
  [c0000005b76c79e0] [c00000000029adc0] .kfree+0x390/0x440
  [c0000005b76c7a80] [c000000000055f74] .destroy_context+0x44/0x100
  [c0000005b76c7b00] [c0000000000934a0] .__mmdrop+0x60/0x150
  [c0000005b76c7b90] [c0000000000e3ff0] .idle_task_exit+0x130/0x140
  [c0000005b76c7c20] [c000000000075804] .pseries_mach_cpu_die+0x64/0x310
  [c0000005b76c7cd0] [c000000000043e7c] .cpu_die+0x3c/0x60
  [c0000005b76c7d40] [c0000000000188d8] .arch_cpu_idle_dead+0x28/0x40
  [c0000005b76c7db0] [c000000000101e6c] .cpu_startup_entry+0x50c/0x560
  [c0000005b76c7ed0] [c000000000043bd8] .start_secondary+0x328/0x360
  [c0000005b76c7f90] [c000000000008a6c] start_secondary_prolog+0x10/0x14

This warning is not a false positive either. RCU is not protecting code that is being executed while the CPU is offline.

Instead of playing "whack-a-mole(TM)" and adding conditional statements to the tracepoints we find that are used in this instance, simply add a cpu_online() test to the tracepoint code where the tracepoint will be ignored if the CPU is offline.

Use of raw_smp_processor_id() is fine, as there should never be a case where the tracepoint code goes from running on a CPU that is online and suddenly gets migrated to a CPU that is offline.

Fixes 97e1c18e8d17b ("tracing: Kernel Tracepoints")
---
 include/linux/tracepoint.h | 6 ++++++
 1 file changed, 6 insertions(+)
include/linux/tracepoint.h +6 -0
index 0ecc46e7af3d..c1248996006f 100644
@@ -14,8 +14,11 @@
  * See the file COPYING for more details.
  */
 
+#include <linux/smp.h>
 #include <linux/errno.h>
 #include <linux/types.h>
+#include <linux/percpu.h>
+#include <linux/cpumask.h>
 #include <linux/rcupdate.h>
 #include <linux/static_key.h>
 
@@ -126,6 +129,9 @@ static inline void tracepoint_synchronize_unregister(void)
 		void *it_func;						\
 		void *__data;						\
 									\
+		if (!cpu_online(raw_smp_processor_id()))		\
+			return;						\
+									\
 		if (!(cond))						\
 			return;						\
 		prercu;							\
Signature · 1 line
2.7.2
author
#28 lore raw

PATCH 28/116 drm/ast: Initialized data needed to map fbdev memory

In reply to Jiri Slaby

From: Egbert Eich <[email protected]>

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

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

commit 28fb4cb7fa6f63dc2fbdb5f2564dcbead8e3eee0 upstream.

Due to a missing initialization there was no way to map fbdev memory. Thus for example using the Xserver with the fbdev driver failed. This fix adds initialization for fix.smem_start and fix.smem_len in the fb_info structure, which fixes this problem.

[pulled from SuSE tree by me - airlied]
---
 drivers/gpu/drm/ast/ast_drv.h  | 1 +
 drivers/gpu/drm/ast/ast_fb.c   | 7 +++++++
 drivers/gpu/drm/ast/ast_main.c | 1 +
 drivers/gpu/drm/ast/ast_mode.c | 2 ++
 4 files changed, 11 insertions(+)
drivers/gpu/drm/ast/ast_drv.h +1 -0
index 8492b68e873c..df2fa469e37c 100644
@@ -296,6 +296,7 @@ int ast_framebuffer_init(struct drm_device *dev,
 int ast_fbdev_init(struct drm_device *dev);
 void ast_fbdev_fini(struct drm_device *dev);
 void ast_fbdev_set_suspend(struct drm_device *dev, int state);
+void ast_fbdev_set_base(struct ast_private *ast, unsigned long gpu_addr);
 
 struct ast_bo {
 	struct ttm_buffer_object bo;
drivers/gpu/drm/ast/ast_fb.c +7 -0
index a28640f47c27..b55b6b1c9fe2 100644
@@ -367,3 +367,10 @@ void ast_fbdev_set_suspend(struct drm_device *dev, int state)
 
 	fb_set_suspend(ast->fbdev->helper.fbdev, state);
 }
+
+void ast_fbdev_set_base(struct ast_private *ast, unsigned long gpu_addr)
+{
+	ast->fbdev->helper.fbdev->fix.smem_start =
+		ast->fbdev->helper.fbdev->apertures->ranges[0].base + gpu_addr;
+	ast->fbdev->helper.fbdev->fix.smem_len = ast->vram_size - gpu_addr;
+}
drivers/gpu/drm/ast/ast_main.c +1 -0
index d57a38d1ca69..48f7ad1497c2 100644
@@ -359,6 +359,7 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags)
 	dev->mode_config.min_height = 0;
 	dev->mode_config.preferred_depth = 24;
 	dev->mode_config.prefer_shadow = 1;
+	dev->mode_config.fb_base = pci_resource_start(ast->dev->pdev, 0);
 
 	if (ast->chip == AST2100 ||
 	    ast->chip == AST2200 ||
drivers/gpu/drm/ast/ast_mode.c +2 -0
index e8f6418b6dec..f3a54ad77e3f 100644
@@ -509,6 +509,8 @@ static int ast_crtc_do_set_base(struct drm_crtc *crtc,
 		ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
 		if (ret)
 			DRM_ERROR("failed to kmap fbcon\n");
+		else
+			ast_fbdev_set_base(ast, gpu_addr);
 	}
 	ast_bo_unreserve(bo);
 
Signature · 1 line
2.7.2
author
#29 lore raw

PATCH 29/116 bcache: fix a leak in bch_cached_dev_run()

In reply to Jiri Slaby

From: Al Viro <[email protected]>

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

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

commit 4d4d8573a8451acc9f01cbea24b7e55f04a252fe upstream.

---
 drivers/md/bcache/super.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/md/bcache/super.c +4 -1
index f5004c5c4b96..391e04160c3f 100644
@@ -841,8 +841,11 @@ void bch_cached_dev_run(struct cached_dev *dc)
 	buf[SB_LABEL_SIZE] = '\0';
 	env[2] = kasprintf(GFP_KERNEL, "CACHED_LABEL=%s", buf);
 
-	if (atomic_xchg(&dc->running, 1))
+	if (atomic_xchg(&dc->running, 1)) {
+		kfree(env[1]);
+		kfree(env[2]);
 		return;
+	}
 
 	if (!d->c &&
 	    BDEV_STATE(&dc->sb) != BDEV_STATE_NONE) {
Signature · 1 line
2.7.2
author
#30 lore raw

PATCH 30/116 bcache: unregister reboot notifier if bcache fails to unregister device

In reply to Jiri Slaby

From: Zheng Liu <[email protected]>

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

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

commit 2ecf0cdb2b437402110ab57546e02abfa68a716b upstream.

In bcache_init() function it forgot to unregister reboot notifier if bcache fails to unregister a block device. This commit fixes this.

---
 drivers/md/bcache/super.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/md/bcache/super.c +3 -1
index 391e04160c3f..70d396ee69e2 100644
@@ -2043,8 +2043,10 @@ static int __init bcache_init(void)
 	closure_debug_init();
 
 	bcache_major = register_blkdev(0, "bcache");
-	if (bcache_major < 0)
+	if (bcache_major < 0) {
+		unregister_reboot_notifier(&reboot);
 		return bcache_major;
+	}
 
 	if (!(bcache_wq = create_workqueue("bcache")) ||
 	    !(bcache_kobj = kobject_create_and_add("bcache", fs_kobj)) ||
Signature · 1 line
2.7.2
author
#31 lore raw

PATCH 31/116 dm thin metadata: fix bug when taking a metadata snapshot

In reply to Jiri Slaby

From: Joe Thornber <[email protected]>

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

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

commit 49e99fc717f624aa75ca755d6e7bc029efd3f0e9 upstream.

When you take a metadata snapshot the btree roots for the mapping and details tree need to have their reference counts incremented so they persist for the lifetime of the metadata snap.

The roots being incremented were those currently written in the superblock, which could possibly be out of date if concurrent IO is triggering new mappings, breaking of sharing, etc.

Fix this by performing a commit with the metadata lock held while taking a metadata snapshot.

---
 drivers/md/dm-thin-metadata.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/md/dm-thin-metadata.c +6 -0
index 7e3da70ed646..f74821c6ec5f 100644
@@ -1205,6 +1205,12 @@ static int __reserve_metadata_snap(struct dm_pool_metadata *pmd)
 	dm_block_t held_root;
 
 	/*
+	 * We commit to ensure the btree roots which we increment in a
+	 * moment are up to date.
+	 */
+	__commit_transaction(pmd);
+
+	/*
 	 * Copy the superblock.
 	 */
 	dm_sm_inc_block(pmd->metadata_sm, THIN_SUPERBLOCK_LOCATION);
Signature · 1 line
2.7.2
author
#32 lore raw

PATCH 32/116 can: ems_usb: Fix possible tx overflow

In reply to Jiri Slaby

From: Gerhard Uttenthaler <[email protected]>

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

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

commit 90cfde46586d2286488d8ed636929e936c0c9ab2 upstream.

This patch fixes the problem that more CAN messages could be sent to the interface as could be send on the CAN bus. This was more likely for slow baud rates. The sleeping _start_xmit was woken up in the _write_bulk_callback. Under heavy TX load this produced another bulk transfer without checking the free_slots variable and hence caused the overflow in the interface.

---
 drivers/net/can/usb/ems_usb.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/net/can/usb/ems_usb.c +10 -4
index 5f9a7ad9b964..d921416295ce 100644
@@ -118,6 +118,9 @@ MODULE_LICENSE("GPL v2");
  */
 #define EMS_USB_ARM7_CLOCK 8000000
 
+#define CPC_TX_QUEUE_TRIGGER_LOW	25
+#define CPC_TX_QUEUE_TRIGGER_HIGH	35
+
 /*
  * CAN-Message representation in a CPC_MSG. Message object type is
  * CPC_MSG_TYPE_CAN_FRAME or CPC_MSG_TYPE_RTR_FRAME or
@@ -279,6 +282,11 @@ static void ems_usb_read_interrupt_callback(struct urb *urb)
 	switch (urb->status) {
 	case 0:
 		dev->free_slots = dev->intr_in_buffer[1];
+		if(dev->free_slots > CPC_TX_QUEUE_TRIGGER_HIGH){
+			if (netif_queue_stopped(netdev)){
+				netif_wake_queue(netdev);
+			}
+		}
 		break;
 
 	case -ECONNRESET: /* unlink */
@@ -530,8 +538,6 @@ static void ems_usb_write_bulk_callback(struct urb *urb)
 	/* Release context */
 	context->echo_index = MAX_TX_URBS;
 
-	if (netif_queue_stopped(netdev))
-		netif_wake_queue(netdev);
 }
 
 /*
@@ -591,7 +597,7 @@ static int ems_usb_start(struct ems_usb *dev)
 	int err, i;
 
 	dev->intr_in_buffer[0] = 0;
-	dev->free_slots = 15; /* initial size */
+	dev->free_slots = 50; /* initial size */
 
 	for (i = 0; i < MAX_RX_URBS; i++) {
 		struct urb *urb = NULL;
@@ -841,7 +847,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
 
 		/* Slow down tx path */
 		if (atomic_read(&dev->active_tx_urbs) >= MAX_TX_URBS ||
-		    dev->free_slots < 5) {
+		    dev->free_slots < CPC_TX_QUEUE_TRIGGER_LOW) {
 			netif_stop_queue(netdev);
 		}
 	}
Signature · 1 line
2.7.2
author
#33 lore raw

PATCH 33/116 USB: cp210x: add IDs for GE B650V3 and B850V3 boards

In reply to Jiri Slaby

From: Ken Lin <[email protected]>

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

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

commit 6627ae19385283b89356a199d7f03c75ba35fb29 upstream.

Add USB ID for cp2104/5 devices on GE B650v3 and B850v3 boards.

---
 drivers/usb/serial/cp210x.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/usb/serial/cp210x.c +2 -0
index c61684e69174..f288f3c1f5e2 100644
@@ -162,6 +162,8 @@ static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
 	{ USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
 	{ USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */
+	{ USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */
+	{ USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */
 	{ USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
 	{ USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
 	{ USB_DEVICE(0x1BA4, 0x0002) },	/* Silicon Labs 358x factory default */
Signature · 1 line
2.7.2
author
#34 lore raw

PATCH 34/116 USB: option: add support for SIM7100E

In reply to Jiri Slaby

From: Andrey Skvortsov <[email protected]>

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

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

commit 3158a8d416f4e1b79dcc867d67cb50013140772c upstream.

$ lsusb:
Bus 001 Device 101: ID 1e0e:9001 Qualcomm / Option
$ usb-devices:
T:  Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#=101 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  2
P:  Vendor=1e0e ProdID=9001 Rev= 2.32
S:  Manufacturer=SimTech, Incorporated
S:  Product=SimTech, Incorporated
S:  SerialNumber=0123456789ABCDEF
C:* #Ifs= 7 Cfg#= 1 Atr=80 MxPwr=500mA
I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
I:* If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none)

The last interface (6) is used for Android Composite ADB interface.

Serial port layout:
0: QCDM/DIAG
1: NMEA
2: AT
3: AT/PPP
4: audio

---
 drivers/usb/serial/option.c | 7 +++++++
 1 file changed, 7 insertions(+)
drivers/usb/serial/option.c +7 -0
index 81f6a572f016..90ad35798973 100644
@@ -315,6 +315,7 @@ static void option_instat_callback(struct urb *urb);
 #define TOSHIBA_PRODUCT_G450			0x0d45
 
 #define ALINK_VENDOR_ID				0x1e0e
+#define SIMCOM_PRODUCT_SIM7100E			0x9001 /* Yes, ALINK_VENDOR_ID */
 #define ALINK_PRODUCT_PH300			0x9100
 #define ALINK_PRODUCT_3GU			0x9200
 
@@ -615,6 +616,10 @@ static const struct option_blacklist_info zte_1255_blacklist = {
 	.reserved = BIT(3) | BIT(4),
 };
 
+static const struct option_blacklist_info simcom_sim7100e_blacklist = {
+	.reserved = BIT(5) | BIT(6),
+};
+
 static const struct option_blacklist_info telit_le910_blacklist = {
 	.sendsetup = BIT(0),
 	.reserved = BIT(1) | BIT(2),
@@ -1645,6 +1650,8 @@ static const struct usb_device_id option_ids[] = {
 	{ USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
 	{ USB_DEVICE(ALINK_VENDOR_ID, ALINK_PRODUCT_PH300) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE(ALINK_VENDOR_ID, SIMCOM_PRODUCT_SIM7100E),
+	  .driver_info = (kernel_ulong_t)&simcom_sim7100e_blacklist },
 	{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200),
 	  .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist
 	},
Signature · 1 line
2.7.2
author
#35 lore raw

PATCH 35/116 USB: option: add "4G LTE usb-modem U901"

In reply to Jiri Slaby

From: Bjørn Mork <[email protected]>

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

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

commit d061c1caa31d4d9792cfe48a2c6b309a0e01ef46 upstream.

Thomas reports:

T:  Bus=01 Lev=01 Prnt=01 Port=03 Cnt=01 Dev#=  4 Spd=480 MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=05c6 ProdID=6001 Rev=00.00
S:  Manufacturer=USB Modem
S:  Product=USB Modem
S:  SerialNumber=1234567890ABCDEF
C:  #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA
I:  If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I:  If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I:  If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I:  If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
I:  If#= 4 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
---
 drivers/usb/serial/option.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/usb/serial/option.c +2 -0
index 90ad35798973..9bab34cf01d4 100644
@@ -1135,6 +1135,8 @@ static const struct usb_device_id option_ids[] = {
 	{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) },
 	{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, 0x6001, 0xff, 0xff, 0xff), /* 4G LTE usb-modem U901 */
+	  .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */
 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
Signature · 1 line
2.7.2
author
#36 lore raw

PATCH 36/116 iw_cxgb3: Fix incorrectly returning error on success

In reply to Jiri Slaby

From: Hariprasad S <[email protected]>

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

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

commit 67f1aee6f45059fd6b0f5b0ecb2c97ad0451f6b3 upstream.

The cxgb3_*_send() functions return NET_XMIT_ values, which are positive integers values. So don't treat positive return values as an error.

[a pox on developers and maintainers who do not cc: stable for bug fixes like this - gregkh]
---
 drivers/infiniband/hw/cxgb3/iwch_cm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/infiniband/hw/cxgb3/iwch_cm.c +2 -2
index cb78b1e9bcd9..f504ba73e5dc 100644
@@ -149,7 +149,7 @@ static int iwch_l2t_send(struct t3cdev *tdev, struct sk_buff *skb, struct l2t_en
 	error = l2t_send(tdev, skb, l2e);
 	if (error < 0)
 		kfree_skb(skb);
-	return error;
+	return error < 0 ? error : 0;
 }
 
 int iwch_cxgb3_ofld_send(struct t3cdev *tdev, struct sk_buff *skb)
@@ -165,7 +165,7 @@ int iwch_cxgb3_ofld_send(struct t3cdev *tdev, struct sk_buff *skb)
 	error = cxgb3_ofld_send(tdev, skb);
 	if (error < 0)
 		kfree_skb(skb);
-	return error;
+	return error < 0 ? error : 0;
 }
 
 static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb)
Signature · 1 line
2.7.2
author
#37 lore raw

PATCH 37/116 splice: sendfile() at once fails for big files

In reply to Jiri Slaby

From: Christophe Leroy <[email protected]>

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

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

commit 0ff28d9f4674d781e492bcff6f32f0fe48cf0fed upstream.

Using sendfile with below small program to get MD5 sums of some files, it appear that big files (over 64kbytes with 4k pages system) get a wrong MD5 sum while small files get the correct sum.
This program uses sendfile() to send a file to an AF_ALG socket for hashing.

/* md5sum2.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <linux/if_alg.h>

int main(int argc, char **argv)

{
	int sk = socket(AF_ALG, SOCK_SEQPACKET, 0);
	struct stat st;
	struct sockaddr_alg sa = {
		.salg_family = AF_ALG,
		.salg_type = "hash",
		.salg_name = "md5",
	};
	int n;

	bind(sk, (struct sockaddr*)&sa, sizeof(sa));

	for (n = 1; n < argc; n++) {
		int size;
		int offset = 0;
		char buf[4096];
		int fd;
		int sko;
		int i;

		fd = open(argv[n], O_RDONLY);
		sko = accept(sk, NULL, 0);
		fstat(fd, &st);
		size = st.st_size;
		sendfile(sko, fd, &offset, size);
		size = read(sko, buf, sizeof(buf));
		for (i = 0; i < size; i++)
			printf("%2.2x", buf[i]);
		printf("  %s\n", argv[n]);
		close(fd);
		close(sko);
	}
	exit(0);
}

Test below is done using official linux patch files. First result is with a software based md5sum. Second result is with the program above.

root@vgoip:~# ls -l patch-3.6.*
-rw-r--r--    1 root     root         64011 Aug 24 12:01 patch-3.6.2.gz
-rw-r--r--    1 root     root         94131 Aug 24 12:01 patch-3.6.3.gz
root@vgoip:~# md5sum patch-3.6.*
b3ffb9848196846f31b2ff133d2d6443  patch-3.6.2.gz
c5e8f687878457db77cb7158c38a7e43  patch-3.6.3.gz
root@vgoip:~# ./md5sum2 patch-3.6.*
b3ffb9848196846f31b2ff133d2d6443  patch-3.6.2.gz
5fd77b24e68bb24dcc72d6e57c64790e  patch-3.6.3.gz

After investivation, it appears that sendfile() sends the files by blocks of 64kbytes (16 times PAGE_SIZE). The problem is that at the end of each block, the SPLICE_F_MORE flag is missing, therefore the hashing operation is reset as if it was the end of the file.

This patch adds SPLICE_F_MORE to the flags when more data is pending.

With the patch applied, we get the correct sums:

root@vgoip:~# md5sum patch-3.6.*
b3ffb9848196846f31b2ff133d2d6443  patch-3.6.2.gz
c5e8f687878457db77cb7158c38a7e43  patch-3.6.3.gz
root@vgoip:~# ./md5sum2 patch-3.6.*
b3ffb9848196846f31b2ff133d2d6443  patch-3.6.2.gz
c5e8f687878457db77cb7158c38a7e43  patch-3.6.3.gz
---
 fs/splice.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
fs/splice.c +11 -1
index c915e215a50e..76cb3a0b1ec4 100644
@@ -1175,7 +1175,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
 	long ret, bytes;
 	umode_t i_mode;
 	size_t len;
-	int i, flags;
+	int i, flags, more;
 
 	/*
 	 * We require the input being a regular file, as we don't want to
@@ -1218,6 +1218,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
 	 * Don't block on output, we have to drain the direct pipe.
 	 */
 	sd->flags &= ~SPLICE_F_NONBLOCK;
+	more = sd->flags & SPLICE_F_MORE;
 
 	while (len) {
 		size_t read_len;
@@ -1231,6 +1232,15 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
 		sd->total_len = read_len;
 
 		/*
+		 * If more data is pending, set SPLICE_F_MORE
+		 * If this is the last data and SPLICE_F_MORE was not set
+		 * initially, clears it.
+		 */
+		if (read_len < len)
+			sd->flags |= SPLICE_F_MORE;
+		else if (!more)
+			sd->flags &= ~SPLICE_F_MORE;
+		/*
 		 * NOTE: nonblocking mode only applies to the input. We
 		 * must not do the output in nonblocking mode as then we
 		 * could get stuck data in the internal pipe:
Signature · 1 line
2.7.2
author
#38 lore raw

PATCH 38/116 Failing to send a CLOSE if file is opened WRONLY and server reboots on a 4.x mount

In reply to Jiri Slaby

From: Olga Kornievskaia <[email protected]>

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

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

commit a41cbe86df3afbc82311a1640e20858c0cd7e065 upstream.

A test case is as the description says:
open(foobar, O_WRONLY);
sleep() --> reboot the server
close(foobar)

The bug is because in nfs4state.c in nfs4_reclaim_open_state() a few line before going to restart, there is clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &state->flags).

NFS4CLNT_RECLAIM_NOGRACE is a flag for the client states not open owner states. Value of NFS4CLNT_RECLAIM_NOGRACE is 4 which is the value of NFS_O_WRONLY_STATE in nfs4_state->flags. So clearing it wipes out state and when we go to close it, “call_close” doesn’t get set as state flag is not set and CLOSE doesn’t go on the wire.

---
 fs/nfs/nfs4state.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/nfs4state.c +1 -1
index 52c9b880697e..fbe7e2f90a3c 100644
@@ -1436,7 +1436,7 @@ restart:
 					spin_unlock(&state->state_lock);
 				}
 				nfs4_put_open_state(state);
-				clear_bit(NFS4CLNT_RECLAIM_NOGRACE,
+				clear_bit(NFS_STATE_RECLAIM_NOGRACE,
 					&state->flags);
 				spin_lock(&sp->so_lock);
 				goto restart;
Signature · 1 line
2.7.2
author
#39 lore raw

PATCH 39/116 bnx2x: Don't notify about scratchpad parities

In reply to Jiri Slaby

From: Manish Chopra <[email protected]>

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

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

commit ad6afbe9578d1fa26680faf78c846bd8c00d1d6e upstream.

The scratchpad is a shared block between all functions of a given device. Due to HW limitations, we can't properly close its parity notifications to all functions on legal flows.
E.g., it's possible that while taking a register dump from one function a parity error would be triggered on other functions.

Today driver doesn't consider this parity as a 'real' parity unless its being accompanied by additional indications [which would happen in a real parity scenario]; But it does print notifications for such events in the system logs.

This eliminates such prints - in case of real parities driver would have additional indications; But if this is the only signal user will not even see a parity being logged in the system.

---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x.h      | 11 +++++++----
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 20 ++++++++++++++------
 2 files changed, 21 insertions(+), 10 deletions(-)
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +7 -4
index 930ced0bcc8b..ce534b2bbd95 100644
@@ -2371,10 +2371,13 @@ void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, u8 idu_sb_id,
 				 AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR | \
 				 AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR)
 
-#define HW_PRTY_ASSERT_SET_3 (AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | \
-		AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | \
-		AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY | \
-		AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY)
+#define HW_PRTY_ASSERT_SET_3_WITHOUT_SCPAD \
+		(AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | \
+		 AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | \
+		 AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY)
+
+#define HW_PRTY_ASSERT_SET_3 (HW_PRTY_ASSERT_SET_3_WITHOUT_SCPAD | \
+			      AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY)
 
 #define HW_PRTY_ASSERT_SET_4 (AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR | \
 			      AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR)
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +14 -6
index 237a5611d3f6..1e912b16c487 100644
@@ -4613,9 +4613,7 @@ static bool bnx2x_check_blocks_with_parity3(struct bnx2x *bp, u32 sig,
 				res |= true;
 				break;
 			case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY:
-				if (print)
-					_print_next_block((*par_num)++,
-							  "MCP SCPAD");
+				(*par_num)++;
 				/* clear latched SCPAD PATIRY from MCP */
 				REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL,
 				       1UL << 10);
@@ -4677,6 +4675,7 @@ static bool bnx2x_parity_attn(struct bnx2x *bp, bool *global, bool print,
 	    (sig[3] & HW_PRTY_ASSERT_SET_3) ||
 	    (sig[4] & HW_PRTY_ASSERT_SET_4)) {
 		int par_num = 0;
+
 		DP(NETIF_MSG_HW, "Was parity error: HW block parity attention:\n"
 				 "[0]:0x%08x [1]:0x%08x [2]:0x%08x [3]:0x%08x [4]:0x%08x\n",
 			  sig[0] & HW_PRTY_ASSERT_SET_0,
@@ -4684,9 +4683,18 @@ static bool bnx2x_parity_attn(struct bnx2x *bp, bool *global, bool print,
 			  sig[2] & HW_PRTY_ASSERT_SET_2,
 			  sig[3] & HW_PRTY_ASSERT_SET_3,
 			  sig[4] & HW_PRTY_ASSERT_SET_4);
-		if (print)
-			netdev_err(bp->dev,
-				   "Parity errors detected in blocks: ");
+		if (print) {
+			if (((sig[0] & HW_PRTY_ASSERT_SET_0) ||
+			     (sig[1] & HW_PRTY_ASSERT_SET_1) ||
+			     (sig[2] & HW_PRTY_ASSERT_SET_2) ||
+			     (sig[4] & HW_PRTY_ASSERT_SET_4)) ||
+			     (sig[3] & HW_PRTY_ASSERT_SET_3_WITHOUT_SCPAD)) {
+				netdev_err(bp->dev,
+					   "Parity errors detected in blocks: ");
+			} else {
+				print = false;
+			}
+		}
 		res |= bnx2x_check_blocks_with_parity0(bp,
 			sig[0] & HW_PRTY_ASSERT_SET_0, &par_num, print);
 		res |= bnx2x_check_blocks_with_parity1(bp,
Signature · 1 line
2.7.2
author
#40 lore raw

PATCH 40/116 sched: Clean up idle task SMP logic

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 6c3b4d44ba2838f00614a5a2d777d4401e0bfd71 upstream.

The idle post_schedule flag is just a vile waste of time, furthermore it appears unneeded, move the idle_enter_fair() call into pick_next_task_idle().

---
 kernel/sched/idle_task.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)
kernel/sched/idle_task.c +1 -8
index d8da01008d39..ecc371e86da1 100644
@@ -19,11 +19,6 @@ static void pre_schedule_idle(struct rq *rq, struct task_struct *prev)
 	idle_exit_fair(rq);
 	rq_last_tick_reset(rq);
 }
-
-static void post_schedule_idle(struct rq *rq)
-{
-	idle_enter_fair(rq);
-}
 #endif /* CONFIG_SMP */
 /*
  * Idle tasks are unconditionally rescheduled:
@@ -37,8 +32,7 @@ static struct task_struct *pick_next_task_idle(struct rq *rq)
 {
 	schedstat_inc(rq, sched_goidle);
 #ifdef CONFIG_SMP
-	/* Trigger the post schedule to do an idle_enter for CFS */
-	rq->post_schedule = 1;
+	idle_enter_fair(rq);
 #endif
 	return rq->idle;
 }
@@ -102,7 +96,6 @@ const struct sched_class idle_sched_class = {
 #ifdef CONFIG_SMP
 	.select_task_rq		= select_task_rq_idle,
 	.pre_schedule		= pre_schedule_idle,
-	.post_schedule		= post_schedule_idle,
 #endif
 
 	.set_curr_task          = set_curr_task_idle,
Signature · 1 line
2.7.2
author
#41 lore raw

PATCH 41/116 sched: Replace post_schedule with a balance callback list

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 e3fca9e7cbfb72694a21c886fcdf9f059cfded9c upstream.

Generalize the post_schedule() stuff into a balance callback list. This allows us to more easily use it outside of schedule() and cross sched_class.

---
 kernel/sched/core.c  | 36 ++++++++++++++++++++++++------------
 kernel/sched/rt.c    | 27 ++++++++++++++++-----------
 kernel/sched/sched.h | 19 +++++++++++++++++--
 3 files changed, 57 insertions(+), 25 deletions(-)
kernel/sched/core.c +24 -12
index 0bcdceaca6e2..7bf52708993e 100644
@@ -1911,18 +1911,30 @@ static inline void pre_schedule(struct rq *rq, struct task_struct *prev)
 }
 
 /* rq->lock is NOT held, but preemption is disabled */
-static inline void post_schedule(struct rq *rq)
+static void __balance_callback(struct rq *rq)
 {
-	if (rq->post_schedule) {
-		unsigned long flags;
+	struct callback_head *head, *next;
+	void (*func)(struct rq *rq);
+	unsigned long flags;
 
-		raw_spin_lock_irqsave(&rq->lock, flags);
-		if (rq->curr->sched_class->post_schedule)
-			rq->curr->sched_class->post_schedule(rq);
-		raw_spin_unlock_irqrestore(&rq->lock, flags);
+	raw_spin_lock_irqsave(&rq->lock, flags);
+	head = rq->balance_callback;
+	rq->balance_callback = NULL;
+	while (head) {
+		func = (void (*)(struct rq *))head->func;
+		next = head->next;
+		head->next = NULL;
+		head = next;
 
-		rq->post_schedule = 0;
+		func(rq);
 	}
+	raw_spin_unlock_irqrestore(&rq->lock, flags);
+}
+
+static inline void balance_callback(struct rq *rq)
+{
+	if (unlikely(rq->balance_callback))
+		__balance_callback(rq);
 }
 
 #else
@@ -1931,7 +1943,7 @@ static inline void pre_schedule(struct rq *rq, struct task_struct *p)
 {
 }
 
-static inline void post_schedule(struct rq *rq)
+static inline void balance_callback(struct rq *rq)
 {
 }
 
@@ -1952,7 +1964,7 @@ asmlinkage void schedule_tail(struct task_struct *prev)
 	 * FIXME: do we need to worry about rq being invalidated by the
 	 * task_switch?
 	 */
-	post_schedule(rq);
+	balance_callback(rq);
 
 #ifdef __ARCH_WANT_UNLOCKED_CTXSW
 	/* In this case, finish_task_switch does not reenable preemption */
@@ -2449,7 +2461,7 @@ need_resched:
 	} else
 		raw_spin_unlock_irq(&rq->lock);
 
-	post_schedule(rq);
+	balance_callback(rq);
 
 	sched_preempt_enable_no_resched();
 	if (need_resched())
@@ -6516,7 +6528,7 @@ void __init sched_init(void)
 		rq->sd = NULL;
 		rq->rd = NULL;
 		rq->cpu_power = SCHED_POWER_SCALE;
-		rq->post_schedule = 0;
+		rq->balance_callback = NULL;
 		rq->active_balance = 0;
 		rq->next_balance = jiffies;
 		rq->push_cpu = 0;
kernel/sched/rt.c +16 -11
index e849d4070c7f..25f6d7ae589d 100644
@@ -315,6 +315,18 @@ static inline int has_pushable_tasks(struct rq *rq)
 	return !plist_head_empty(&rq->rt.pushable_tasks);
 }
 
+static DEFINE_PER_CPU(struct callback_head, rt_balance_head);
+
+static void push_rt_tasks(struct rq *);
+
+static inline void queue_push_tasks(struct rq *rq)
+{
+	if (!has_pushable_tasks(rq))
+		return;
+
+	queue_balance_callback(rq, &per_cpu(rt_balance_head, rq->cpu), push_rt_tasks);
+}
+
 static void enqueue_pushable_task(struct rq *rq, struct task_struct *p)
 {
 	plist_del(&p->pushable_tasks, &rq->rt.pushable_tasks);
@@ -359,6 +371,9 @@ void dec_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
 {
 }
 
+static inline void queue_push_tasks(struct rq *rq)
+{
+}
 #endif /* CONFIG_SMP */
 
 static inline int on_rt_rq(struct sched_rt_entity *rt_se)
@@ -1344,11 +1359,7 @@ static struct task_struct *pick_next_task_rt(struct rq *rq)
 		dequeue_pushable_task(rq, p);
 
 #ifdef CONFIG_SMP
-	/*
-	 * We detect this state here so that we can avoid taking the RQ
-	 * lock again later if there is no need to push
-	 */
-	rq->post_schedule = has_pushable_tasks(rq);
+	queue_push_tasks(rq);
 #endif
 
 	return p;
@@ -1726,11 +1737,6 @@ static void pre_schedule_rt(struct rq *rq, struct task_struct *prev)
 		pull_rt_task(rq);
 }
 
-static void post_schedule_rt(struct rq *rq)
-{
-	push_rt_tasks(rq);
-}
-
 /*
  * If we are not running and we are not going to reschedule soon, we should
  * try to push tasks away now
@@ -2003,7 +2009,6 @@ const struct sched_class rt_sched_class = {
 	.rq_online              = rq_online_rt,
 	.rq_offline             = rq_offline_rt,
 	.pre_schedule		= pre_schedule_rt,
-	.post_schedule		= post_schedule_rt,
 	.task_woken		= task_woken_rt,
 	.switched_from		= switched_from_rt,
 #endif
kernel/sched/sched.h +17 -2
index 1a1cdc3783ed..e09e3e0466f7 100644
@@ -460,9 +460,10 @@ struct rq {
 
 	unsigned long cpu_power;
 
+	struct callback_head *balance_callback;
+
 	unsigned char idle_balance;
 	/* For active balancing */
-	int post_schedule;
 	int active_balance;
 	int push_cpu;
 	struct cpu_stop_work active_balance_work;
@@ -554,6 +555,21 @@ static inline u64 rq_clock_task(struct rq *rq)
 
 #ifdef CONFIG_SMP
 
+static inline void
+queue_balance_callback(struct rq *rq,
+		       struct callback_head *head,
+		       void (*func)(struct rq *rq))
+{
+	lockdep_assert_held(&rq->lock);
+
+	if (unlikely(head->next))
+		return;
+
+	head->func = (void (*)(struct callback_head *))func;
+	head->next = rq->balance_callback;
+	rq->balance_callback = head;
+}
+
 #define rcu_dereference_check_sched_domain(p) \
 	rcu_dereference_check((p), \
 			      lockdep_is_held(&sched_domains_mutex))
@@ -981,7 +997,6 @@ struct sched_class {
 	void (*migrate_task_rq)(struct task_struct *p, int next_cpu);
 
 	void (*pre_schedule) (struct rq *this_rq, struct task_struct *task);
-	void (*post_schedule) (struct rq *this_rq);
 	void (*task_waking) (struct task_struct *task);
 	void (*task_woken) (struct rq *this_rq, struct task_struct *task);
 
Signature · 1 line
2.7.2
author
#42 lore raw

PATCH 42/116 sched: Allow balance callbacks for check_class_changed()

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 4c9a4bc89a9cca8128bce67d6bc8870d6b7ee0b2 upstream.

In order to remove dropping rq->lock from the switched_{to,from}()/prio_changed() sched_class methods, run the balance callbacks after it.

We need to remove dropping rq->lock because its buggy, suppose using sched_setattr()/sched_setscheduler() to change a running task from FIFO to OTHER.

By the time we get to switched_from_rt() the task is already enqueued on the cfs runqueues. If switched_from_rt() does pull_rt_task() and drops rq->lock, load-balancing can come in and move our task @p to another rq.

The subsequent switched_to_fair() still assumes @p is on @rq and bad things will happen.

By using balance callbacks we delay the load-balancing operations {rt,dl}x{push,pull} until we've done all the important work and the task is fully set up.

Furthermore, the balance callbacks do not know about @p, therefore they cannot get confused like this.

---
 kernel/sched/core.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)
kernel/sched/core.c +23 -1
index 7bf52708993e..9b2394fffc2f 100644
@@ -941,6 +941,13 @@ inline int task_curr(const struct task_struct *p)
 	return cpu_curr(task_cpu(p)) == p;
 }
 
+/*
+ * switched_from, switched_to and prio_changed must _NOT_ drop rq->lock,
+ * use the balance_callback list if you want balancing.
+ *
+ * this means any call to check_class_changed() must be followed by a call to
+ * balance_callback().
+ */
 static inline void check_class_changed(struct rq *rq, struct task_struct *p,
 				       const struct sched_class *prev_class,
 				       int oldprio)
@@ -1325,8 +1332,12 @@ ttwu_do_wakeup(struct rq *rq, struct task_struct *p, int wake_flags)
 
 	p->state = TASK_RUNNING;
 #ifdef CONFIG_SMP
-	if (p->sched_class->task_woken)
+	if (p->sched_class->task_woken) {
+		/*
+		 * XXX can drop rq->lock; most likely ok.
+		 */
 		p->sched_class->task_woken(rq, p);
+	}
 
 	if (rq->idle_stamp) {
 		u64 delta = rq_clock(rq) - rq->idle_stamp;
@@ -3087,7 +3098,11 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
 
 	check_class_changed(rq, p, prev_class, oldprio);
 out_unlock:
+	preempt_disable(); /* avoid rq from going away on us */
 	__task_rq_unlock(rq);
+
+	balance_callback(rq);
+	preempt_enable();
 }
 #endif
 void set_user_nice(struct task_struct *p, long nice)
@@ -3442,10 +3457,17 @@ recheck:
 		enqueue_task(rq, p, 0);
 
 	check_class_changed(rq, p, prev_class, oldprio);
+	preempt_disable(); /* avoid rq from going away on us */
 	task_rq_unlock(rq, p, &flags);
 
 	rt_mutex_adjust_pi(p);
 
+	/*
+	 * Run balance callbacks after we've adjusted the PI chain.
+	 */
+	balance_callback(rq);
+	preempt_enable();
+
 	return 0;
 }
 
Signature · 1 line
2.7.2
author
#43 lore raw

PATCH 43/116 sched,rt: Remove return value from pull_rt_task()

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 8046d6806247088de5725eaf8a2580b29e50ac5a upstream.

In order to be able to use pull_rt_task() from a callback, we need to do away with the return value.

Since the return value indicates if we should reschedule, do this inside the function. Since not all callers currently do this, this can increase the number of reschedules due rt balancing.

Too many reschedules is not a correctness issues, too few are.

---
 kernel/sched/rt.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)
kernel/sched/rt.c +8 -7
index 25f6d7ae589d..85a09baa8f9f 100644
@@ -1647,14 +1647,15 @@ static void push_rt_tasks(struct rq *rq)
 		;
 }
 
-static int pull_rt_task(struct rq *this_rq)
+static void pull_rt_task(struct rq *this_rq)
 {
-	int this_cpu = this_rq->cpu, ret = 0, cpu;
+	int this_cpu = this_rq->cpu, cpu;
+	bool resched = false;
 	struct task_struct *p;
 	struct rq *src_rq;
 
 	if (likely(!rt_overloaded(this_rq)))
-		return 0;
+		return;
 
 	/*
 	 * Match the barrier from rt_set_overloaded; this guarantees that if we
@@ -1711,7 +1712,7 @@ static int pull_rt_task(struct rq *this_rq)
 			if (p->prio < src_rq->curr->prio)
 				goto skip;
 
-			ret = 1;
+			resched = true;
 
 			deactivate_task(src_rq, p, 0);
 			set_task_cpu(p, this_cpu);
@@ -1727,7 +1728,8 @@ skip:
 		double_unlock_balance(this_rq, src_rq);
 	}
 
-	return ret;
+	if (resched)
+		resched_task(this_rq->curr);
 }
 
 static void pre_schedule_rt(struct rq *rq, struct task_struct *prev)
@@ -1830,8 +1832,7 @@ static void switched_from_rt(struct rq *rq, struct task_struct *p)
 	if (!p->on_rq || rq->rt.rt_nr_running)
 		return;
 
-	if (pull_rt_task(rq))
-		resched_task(rq->curr);
+	pull_rt_task(rq);
 }
 
 void init_sched_rt_class(void)
Signature · 1 line
2.7.2
author
#44 lore raw

PATCH 44/116 sched, rt: Convert switched_{from, to}_rt() / prio_changed_rt() to balance callbacks

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 fd7a4bed183523275279c9addbf42fce550c2e90 upstream.

Remove the direct {push,pull} balancing operations from switched_{from,to}_rt() / prio_changed_rt() and use the balance callback queue.

Again, err on the side of too many reschedules; since too few is a hard bug while too many is just annoying.

---
 kernel/sched/rt.c | 35 +++++++++++++++++++----------------
 1 file changed, 19 insertions(+), 16 deletions(-)
kernel/sched/rt.c +19 -16
index 85a09baa8f9f..10edf9d2a8b7 100644
@@ -315,16 +315,23 @@ static inline int has_pushable_tasks(struct rq *rq)
 	return !plist_head_empty(&rq->rt.pushable_tasks);
 }
 
-static DEFINE_PER_CPU(struct callback_head, rt_balance_head);
+static DEFINE_PER_CPU(struct callback_head, rt_push_head);
+static DEFINE_PER_CPU(struct callback_head, rt_pull_head);
 
 static void push_rt_tasks(struct rq *);
+static void pull_rt_task(struct rq *);
 
 static inline void queue_push_tasks(struct rq *rq)
 {
 	if (!has_pushable_tasks(rq))
 		return;
 
-	queue_balance_callback(rq, &per_cpu(rt_balance_head, rq->cpu), push_rt_tasks);
+	queue_balance_callback(rq, &per_cpu(rt_push_head, rq->cpu), push_rt_tasks);
+}
+
+static inline void queue_pull_task(struct rq *rq)
+{
+	queue_balance_callback(rq, &per_cpu(rt_pull_head, rq->cpu), pull_rt_task);
 }
 
 static void enqueue_pushable_task(struct rq *rq, struct task_struct *p)
@@ -1832,7 +1839,7 @@ static void switched_from_rt(struct rq *rq, struct task_struct *p)
 	if (!p->on_rq || rq->rt.rt_nr_running)
 		return;
 
-	pull_rt_task(rq);
+	queue_pull_task(rq);
 }
 
 void init_sched_rt_class(void)
@@ -1853,8 +1860,6 @@ void init_sched_rt_class(void)
  */
 static void switched_to_rt(struct rq *rq, struct task_struct *p)
 {
-	int check_resched = 1;
-
 	/*
 	 * If we are already running, then there's nothing
 	 * that needs to be done. But if we are not running
@@ -1864,13 +1869,12 @@ static void switched_to_rt(struct rq *rq, struct task_struct *p)
 	 */
 	if (p->on_rq && rq->curr != p) {
 #ifdef CONFIG_SMP
-		if (rq->rt.overloaded && push_rt_task(rq) &&
-		    /* Don't resched if we changed runqueues */
-		    rq != task_rq(p))
-			check_resched = 0;
-#endif /* CONFIG_SMP */
-		if (check_resched && p->prio < rq->curr->prio)
+		if (rq->rt.overloaded)
+			queue_push_tasks(rq);
+#else
+		if (p->prio < rq->curr->prio)
 			resched_task(rq->curr);
+#endif /* CONFIG_SMP */
 	}
 }
 
@@ -1891,14 +1895,13 @@ prio_changed_rt(struct rq *rq, struct task_struct *p, int oldprio)
 		 * may need to pull tasks to this runqueue.
 		 */
 		if (oldprio < p->prio)
-			pull_rt_task(rq);
+			queue_pull_task(rq);
+
 		/*
 		 * If there's a higher priority task waiting to run
-		 * then reschedule. Note, the above pull_rt_task
-		 * can release the rq lock and p could migrate.
-		 * Only reschedule if p is still on the same runqueue.
+		 * then reschedule.
 		 */
-		if (p->prio > rq->rt.highest_prio.curr && rq->curr == p)
+		if (p->prio > rq->rt.highest_prio.curr)
 			resched_task(p);
 #else
 		/* For UP simply resched on drop of prio */
Signature · 1 line
2.7.2
author
#45 lore raw

PATCH 45/116 genirq: Prevent chip buslock deadlock

In reply to Jiri Slaby

From: Thomas Gleixner <[email protected]>

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

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

commit abc7e40c81d113ef4bacb556f0a77ca63ac81d85 upstream.

If a interrupt chip utilizes chip->buslock then free_irq() can deadlock in the following way:

CPU0 CPU1
interrupt(X) (Shared or spurious)
free_irq(X) interrupt_thread(X)
chip_bus_lock(X)
irq_finalize_oneshot(X)
chip_bus_lock(X)
synchronize_irq(X)

synchronize_irq() waits for the interrupt thread to complete, i.e. forever.

Solution is simple: Drop chip_bus_lock() before calling synchronize_irq() as we do with the irq_desc lock. There is nothing to be protected after the point where irq_desc lock has been released.

This adds chip_bus_lock/unlock() to the remove_irq() code path, but that's actually correct in the case where remove_irq() is called on such an interrupt. The current users of remove_irq() are not affected as none of those interrupts is on a chip which requires buslock.

---
 kernel/irq/manage.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/irq/manage.c +3 -3
index 75a976a8ed58..504bb4b0d226 100644
@@ -1230,6 +1230,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
 	if (!desc)
 		return NULL;
 
+	chip_bus_lock(desc);
 	raw_spin_lock_irqsave(&desc->lock, flags);
 
 	/*
@@ -1243,7 +1244,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
 		if (!action) {
 			WARN(1, "Trying to free already-free IRQ %d\n", irq);
 			raw_spin_unlock_irqrestore(&desc->lock, flags);
-
+			chip_bus_sync_unlock(desc);
 			return NULL;
 		}
 
@@ -1266,6 +1267,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
 #endif
 
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
+	chip_bus_sync_unlock(desc);
 
 	unregister_handler_proc(irq, action);
 
@@ -1339,9 +1341,7 @@ void free_irq(unsigned int irq, void *dev_id)
 		desc->affinity_notify = NULL;
 #endif
 
-	chip_bus_lock(desc);
 	kfree(__free_irq(irq, dev_id));
-	chip_bus_sync_unlock(desc);
 }
 EXPORT_SYMBOL(free_irq);
 
Signature · 1 line
2.7.2
author
#46 lore raw

PATCH 46/116 dts: vt8500: Add SDHC node to DTS file for WM8650

In reply to Jiri Slaby

From: Roman Volkov <[email protected]>

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

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

commit 0f090bf14e51e7eefb71d9d1c545807f8b627986 upstream.

Since WM8650 has the same 'WMT' SDHC controller as WM8505, and the driver is already in the kernel, this node enables the controller support for WM8650

---
 arch/arm/boot/dts/wm8650.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)
arch/arm/boot/dts/wm8650.dtsi +9 -0
index 7525982262ac..2897c1ac47d8 100644
@@ -187,6 +187,15 @@
 			interrupts = <43>;
 		};
 
+		sdhc@d800a000 {
+			compatible = "wm,wm8505-sdhc";
+			reg = <0xd800a000 0x400>;
+			interrupts = <20>, <21>;
+			clocks = <&clksdhc>;
+			bus-width = <4>;
+			sdon-inverted;
+		};
+
 		fb: fb@d8050800 {
 			compatible = "wm,wm8505-fb";
 			reg = <0xd8050800 0x200>;
Signature · 1 line
2.7.2
author
#47 lore raw

PATCH 47/116 clocksource/drivers/vt8500: Increase the minimum delta

In reply to Jiri Slaby

From: Roman Volkov <[email protected]>

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

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

commit f9eccf24615672896dc13251410c3f2f33a14f95 upstream.

The vt8500 clocksource driver declares itself as capable to handle the minimum delay of 4 cycles by passing the value into clockevents_config_and_register(). The vt8500_timer_set_next_event() requires the passed cycles value to be at least 16. The impact is that userspace hangs in nanosleep() calls with small delay intervals.

This problem is reproducible in Linux 4.2 starting from:
c6eb3f70d448 ('hrtimer: Get rid of hrtimer softirq')

Quoted 1 line

From Russell King, more detailed explanation:

"It's a speciality of the StrongARM/PXA hardware. It takes a certain number of OSCR cycles for the value written to hit the compare registers. So, if a very small delta is written (eg, the compare register is written with a value of OSCR + 1), the OSCR will have incremented past this value before it hits the underlying hardware. The result is, that you end up waiting a very long time for the OSCR to wrap before the event fires.

So, we introduce a check in set_next_event() to detect this and return -ETIME if the calculated delta is too small, which causes the generic clockevents code to retry after adding the min_delta specified in clockevents_config_and_register() to the current time value.

min_delta must be sufficient that we don't re-trip the -ETIME check - if we do, we will return -ETIME, forward the next event time, try to set it, return -ETIME again, and basically lock the system up. So, min_delta must be larger than the check inside set_next_event(). A factor of two was chosen to ensure that this situation would never occur.

The PXA code worked on PXA systems for years, and I'd suggest no one changes this mechanism without access to a wide range of PXA systems, otherwise they're risking breakage."

---
 drivers/clocksource/vt8500_timer.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/clocksource/vt8500_timer.c +4 -2
index 64f553f04fa4..5874ebf9dced 100644
@@ -50,6 +50,8 @@
 
 #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
 
+#define MIN_OSCR_DELTA		16
+
 static void __iomem *regbase;
 
 static cycle_t vt8500_timer_read(struct clocksource *cs)
@@ -80,7 +82,7 @@ static int vt8500_timer_set_next_event(unsigned long cycles,
 		cpu_relax();
 	writel((unsigned long)alarm, regbase + TIMER_MATCH_VAL);
 
-	if ((signed)(alarm - clocksource.read(&clocksource)) <= 16)
+	if ((signed)(alarm - clocksource.read(&clocksource)) <= MIN_OSCR_DELTA)
 		return -ETIME;
 
 	writel(1, regbase + TIMER_IER_VAL);
@@ -162,7 +164,7 @@ static void __init vt8500_timer_init(struct device_node *np)
 		pr_err("%s: setup_irq failed for %s\n", __func__,
 							clockevent.name);
 	clockevents_config_and_register(&clockevent, VT8500_TIMER_HZ,
-					4, 0xf0000000);
+					MIN_OSCR_DELTA * 2, 0xf0000000);
 }
 
 CLOCKSOURCE_OF_DECLARE(vt8500, "via,vt8500-timer", vt8500_timer_init);
Signature · 1 line
2.7.2
author
#48 lore raw

PATCH 48/116 drm/radeon: make rv770_set_sw_state failures non-fatal

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 4e7697ed79d0c0d5f869c87a6b3ce3d5cd1a07d6 upstream.

On some cards it takes a relatively long time for the change to take place. Make a timeout non-fatal.

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

---
 drivers/gpu/drm/radeon/rv770_dpm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/radeon/rv770_dpm.c +1 -1
index 890cf1710253..7eda43c4b3ec 100644
@@ -1415,7 +1415,7 @@ int rv770_resume_smc(struct radeon_device *rdev)
 int rv770_set_sw_state(struct radeon_device *rdev)
 {
 	if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_SwitchToSwState) != PPSMC_Result_OK)
-		return -EINVAL;
+		DRM_ERROR("rv770_set_sw_state failed\n");
 	return 0;
 }
 
Signature · 1 line
2.7.2
author
#49 lore raw

PATCH 49/116 lockd: create NSM handles per net namespace

In reply to Jiri Slaby

From: Andrey Ryabinin <[email protected]>

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

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

commit 0ad95472bf169a3501991f8f33f5147f792a8116 upstream.

Commit cb7323fffa85 ("lockd: create and use per-net NSM
RPC clients on MON/UNMON requests") introduced per-net
NSM RPC clients. Unfortunately this doesn't make any sense without per-net nsm_handle.

E.g. the following scenario could happen
Two hosts (X and Y) in different namespaces (A and B) share the same nsm struct.

1. nsm_monitor(host_X) called => NSM rpc client created,

	nsm->sm_monitored bit set.
2. nsm_mointor(host-Y) called => nsm->sm_monitored already set,
	we just exit. Thus in namespace B ln->nsm_clnt == NULL.
3. host X destroyed => nsm->sm_count decremented to 1
4. host Y destroyed => nsm_unmonitor() => nsm_mon_unmon() => NULL-ptr
	dereference of *ln->nsm_clnt

So this could be fixed by making per-net nsm_handles list, instead of global. Thus different net namespaces will not be able share the same nsm_handle.

---
 fs/lockd/host.c             |  7 ++++---
 fs/lockd/mon.c              | 36 ++++++++++++++++++++++--------------
 fs/lockd/netns.h            |  1 +
 fs/lockd/svc.c              |  1 +
 fs/lockd/svc4proc.c         |  2 +-
 fs/lockd/svcproc.c          |  2 +-
 include/linux/lockd/lockd.h |  9 ++++++---
 7 files changed, 36 insertions(+), 22 deletions(-)
fs/lockd/host.c +4 -3
index 969d589c848d..b5f3c3ab0d5f 100644
@@ -116,7 +116,7 @@ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni,
 		atomic_inc(&nsm->sm_count);
 	else {
 		host = NULL;
-		nsm = nsm_get_handle(ni->sap, ni->salen,
+		nsm = nsm_get_handle(ni->net, ni->sap, ni->salen,
 					ni->hostname, ni->hostname_len);
 		if (unlikely(nsm == NULL)) {
 			dprintk("lockd: %s failed; no nsm handle\n",
@@ -534,17 +534,18 @@ static struct nlm_host *next_host_state(struct hlist_head *cache,
 
 /**
  * nlm_host_rebooted - Release all resources held by rebooted host
+ * @net:  network namespace
  * @info: pointer to decoded results of NLM_SM_NOTIFY call
  *
  * We were notified that the specified host has rebooted.  Release
  * all resources held by that peer.
  */
-void nlm_host_rebooted(const struct nlm_reboot *info)
+void nlm_host_rebooted(const struct net *net, const struct nlm_reboot *info)
 {
 	struct nsm_handle *nsm;
 	struct nlm_host	*host;
 
-	nsm = nsm_reboot_lookup(info);
+	nsm = nsm_reboot_lookup(net, info);
 	if (unlikely(nsm == NULL))
 		return;
 
fs/lockd/mon.c +22 -14
index 6ae664b489af..13fac49aff7f 100644
@@ -51,7 +51,6 @@ struct nsm_res {
 };
 
 static const struct rpc_program	nsm_program;
-static				LIST_HEAD(nsm_handles);
 static				DEFINE_SPINLOCK(nsm_lock);
 
 /*
@@ -259,33 +258,35 @@ void nsm_unmonitor(const struct nlm_host *host)
 	}
 }
 
-static struct nsm_handle *nsm_lookup_hostname(const char *hostname,
-					      const size_t len)
+static struct nsm_handle *nsm_lookup_hostname(const struct list_head *nsm_handles,
+					const char *hostname, const size_t len)
 {
 	struct nsm_handle *nsm;
 
-	list_for_each_entry(nsm, &nsm_handles, sm_link)
+	list_for_each_entry(nsm, nsm_handles, sm_link)
 		if (strlen(nsm->sm_name) == len &&
 		    memcmp(nsm->sm_name, hostname, len) == 0)
 			return nsm;
 	return NULL;
 }
 
-static struct nsm_handle *nsm_lookup_addr(const struct sockaddr *sap)
+static struct nsm_handle *nsm_lookup_addr(const struct list_head *nsm_handles,
+					const struct sockaddr *sap)
 {
 	struct nsm_handle *nsm;
 
-	list_for_each_entry(nsm, &nsm_handles, sm_link)
+	list_for_each_entry(nsm, nsm_handles, sm_link)
 		if (rpc_cmp_addr(nsm_addr(nsm), sap))
 			return nsm;
 	return NULL;
 }
 
-static struct nsm_handle *nsm_lookup_priv(const struct nsm_private *priv)
+static struct nsm_handle *nsm_lookup_priv(const struct list_head *nsm_handles,
+					const struct nsm_private *priv)
 {
 	struct nsm_handle *nsm;
 
-	list_for_each_entry(nsm, &nsm_handles, sm_link)
+	list_for_each_entry(nsm, nsm_handles, sm_link)
 		if (memcmp(nsm->sm_priv.data, priv->data,
 					sizeof(priv->data)) == 0)
 			return nsm;
@@ -350,6 +351,7 @@ static struct nsm_handle *nsm_create_handle(const struct sockaddr *sap,
 
 /**
  * nsm_get_handle - Find or create a cached nsm_handle
+ * @net: network namespace
  * @sap: pointer to socket address of handle to find
  * @salen: length of socket address
  * @hostname: pointer to C string containing hostname to find
@@ -362,11 +364,13 @@ static struct nsm_handle *nsm_create_handle(const struct sockaddr *sap,
  * @hostname cannot be found in the handle cache.  Returns NULL if
  * an error occurs.
  */
-struct nsm_handle *nsm_get_handle(const struct sockaddr *sap,
+struct nsm_handle *nsm_get_handle(const struct net *net,
+				  const struct sockaddr *sap,
 				  const size_t salen, const char *hostname,
 				  const size_t hostname_len)
 {
 	struct nsm_handle *cached, *new = NULL;
+	struct lockd_net *ln = net_generic(net, lockd_net_id);
 
 	if (hostname && memchr(hostname, '/', hostname_len) != NULL) {
 		if (printk_ratelimit()) {
@@ -381,9 +385,10 @@ retry:
 	spin_lock(&nsm_lock);
 
 	if (nsm_use_hostnames && hostname != NULL)
-		cached = nsm_lookup_hostname(hostname, hostname_len);
+		cached = nsm_lookup_hostname(&ln->nsm_handles,
+					hostname, hostname_len);
 	else
-		cached = nsm_lookup_addr(sap);
+		cached = nsm_lookup_addr(&ln->nsm_handles, sap);
 
 	if (cached != NULL) {
 		atomic_inc(&cached->sm_count);
@@ -397,7 +402,7 @@ retry:
 	}
 
 	if (new != NULL) {
-		list_add(&new->sm_link, &nsm_handles);
+		list_add(&new->sm_link, &ln->nsm_handles);
 		spin_unlock(&nsm_lock);
 		dprintk("lockd: created nsm_handle for %s (%s)\n",
 				new->sm_name, new->sm_addrbuf);
@@ -414,19 +419,22 @@ retry:
 
 /**
  * nsm_reboot_lookup - match NLMPROC_SM_NOTIFY arguments to an nsm_handle
+ * @net:  network namespace
  * @info: pointer to NLMPROC_SM_NOTIFY arguments
  *
  * Returns a matching nsm_handle if found in the nsm cache. The returned
  * nsm_handle's reference count is bumped. Otherwise returns NULL if some
  * error occurred.
  */
-struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info)
+struct nsm_handle *nsm_reboot_lookup(const struct net *net,
+				const struct nlm_reboot *info)
 {
 	struct nsm_handle *cached;
+	struct lockd_net *ln = net_generic(net, lockd_net_id);
 
 	spin_lock(&nsm_lock);
 
-	cached = nsm_lookup_priv(&info->priv);
+	cached = nsm_lookup_priv(&ln->nsm_handles, &info->priv);
 	if (unlikely(cached == NULL)) {
 		spin_unlock(&nsm_lock);
 		dprintk("lockd: never saw rebooted peer '%.*s' before\n",
fs/lockd/netns.h +1 -0
index 5010b55628b4..414da99744e9 100644
@@ -16,6 +16,7 @@ struct lockd_net {
 	spinlock_t nsm_clnt_lock;
 	unsigned int nsm_users;
 	struct rpc_clnt *nsm_clnt;
+	struct list_head nsm_handles;
 };
 
 extern int lockd_net_id;
fs/lockd/svc.c +1 -0
index 59a53f664005..bb1ad4df024d 100644
@@ -583,6 +583,7 @@ static int lockd_init_net(struct net *net)
 	INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender);
 	INIT_LIST_HEAD(&ln->grace_list);
 	spin_lock_init(&ln->nsm_clnt_lock);
+	INIT_LIST_HEAD(&ln->nsm_handles);
 	return 0;
 }
 
fs/lockd/svc4proc.c +1 -1
index b147d1ae71fd..09c576f26c7b 100644
@@ -421,7 +421,7 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
 		return rpc_system_err;
 	}
 
-	nlm_host_rebooted(argp);
+	nlm_host_rebooted(SVC_NET(rqstp), argp);
 	return rpc_success;
 }
 
fs/lockd/svcproc.c +1 -1
index 21171f0c6477..fb26b9f522e7 100644
@@ -464,7 +464,7 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
 		return rpc_system_err;
 	}
 
-	nlm_host_rebooted(argp);
+	nlm_host_rebooted(SVC_NET(rqstp), argp);
 	return rpc_success;
 }
 
include/linux/lockd/lockd.h +6 -3
index dcaad79f54ed..0adf073f13b3 100644
@@ -236,7 +236,8 @@ void		  nlm_rebind_host(struct nlm_host *);
 struct nlm_host * nlm_get_host(struct nlm_host *);
 void		  nlm_shutdown_hosts(void);
 void		  nlm_shutdown_hosts_net(struct net *net);
-void		  nlm_host_rebooted(const struct nlm_reboot *);
+void		  nlm_host_rebooted(const struct net *net,
+					const struct nlm_reboot *);
 
 /*
  * Host monitoring
@@ -244,11 +245,13 @@ void		  nlm_host_rebooted(const struct nlm_reboot *);
 int		  nsm_monitor(const struct nlm_host *host);
 void		  nsm_unmonitor(const struct nlm_host *host);
 
-struct nsm_handle *nsm_get_handle(const struct sockaddr *sap,
+struct nsm_handle *nsm_get_handle(const struct net *net,
+					const struct sockaddr *sap,
 					const size_t salen,
 					const char *hostname,
 					const size_t hostname_len);
-struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info);
+struct nsm_handle *nsm_reboot_lookup(const struct net *net,
+					const struct nlm_reboot *info);
 void		  nsm_release(struct nsm_handle *nsm);
 
 /*
Signature · 1 line
2.7.2
author
#50 lore raw

PATCH 50/116 devres: fix a for loop bounds check

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 1f35d04a02a652f14566f875aef3a6f2af4cb77b upstream.

The iomap[] array has PCIM_IOMAP_MAX (6) elements and not DEVICE_COUNT_RESOURCE (16). This bug was found using a static checker. It may be that the "if (!(mask & (1 << i)))" check means we never actually go past the end of the array in real life.

Fixes ec04b075843d ('iomap: implement pcim_iounmap_regions()')
---
 lib/devres.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
lib/devres.c +1 -1
index 823533138fa0..20afaf181b27 100644
@@ -423,7 +423,7 @@ void pcim_iounmap_regions(struct pci_dev *pdev, int mask)
 	if (!iomap)
 		return;
 
-	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+	for (i = 0; i < PCIM_IOMAP_MAX; i++) {
 		if (!(mask & (1 << i)))
 			continue;
 
Signature · 1 line
2.7.2
author
#51 lore raw

PATCH 51/116 wm831x_power: Use IRQF_ONESHOT to request threaded IRQs

In reply to Jiri Slaby

From: Valentin Rothberg <[email protected]>

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

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

commit 90adf98d9530054b8e665ba5a928de4307231d84 upstream.

Since commit 1c6c69525b40 ("genirq: Reject bogus threaded irq requests") threaded IRQs without a primary handler need to be requested with IRQF_ONESHOT, otherwise the request will fail.

scripts/coccinelle/misc/irqf_oneshot.cocci detected this issue.

Fixes b5874f33bbaf ("wm831x_power: Use genirq")
---
 drivers/power/wm831x_power.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/power/wm831x_power.c +3 -3
index 3bed2f55cf7d..3ccadf631d45 100644
@@ -567,7 +567,7 @@ static int wm831x_power_probe(struct platform_device *pdev)
 
 	irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "SYSLO"));
 	ret = request_threaded_irq(irq, NULL, wm831x_syslo_irq,
-				   IRQF_TRIGGER_RISING, "System power low",
+				   IRQF_TRIGGER_RISING | IRQF_ONESHOT, "System power low",
 				   power);
 	if (ret != 0) {
 		dev_err(&pdev->dev, "Failed to request SYSLO IRQ %d: %d\n",
@@ -577,7 +577,7 @@ static int wm831x_power_probe(struct platform_device *pdev)
 
 	irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "PWR SRC"));
 	ret = request_threaded_irq(irq, NULL, wm831x_pwr_src_irq,
-				   IRQF_TRIGGER_RISING, "Power source",
+				   IRQF_TRIGGER_RISING | IRQF_ONESHOT, "Power source",
 				   power);
 	if (ret != 0) {
 		dev_err(&pdev->dev, "Failed to request PWR SRC IRQ %d: %d\n",
@@ -590,7 +590,7 @@ static int wm831x_power_probe(struct platform_device *pdev)
 				 platform_get_irq_byname(pdev,
 							 wm831x_bat_irqs[i]));
 		ret = request_threaded_irq(irq, NULL, wm831x_bat_irq,
-					   IRQF_TRIGGER_RISING,
+					   IRQF_TRIGGER_RISING | IRQF_ONESHOT,
 					   wm831x_bat_irqs[i],
 					   power);
 		if (ret != 0) {
Signature · 1 line
2.7.2
author
#52 lore raw

PATCH 52/116 dmaengine: dw: convert to __ffs()

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 39416677b95bf1ab8bbfa229ec7e511c96ad5d0c upstream.

We replace __fls() by __ffs() since we have to find a *minimum* data width that satisfies both source and destination.

While here, rename dwc_fast_fls() to dwc_fast_ffs() which it really is.

Fixes 4c2d56c574db (dw_dmac: introduce dwc_fast_fls())
---
 drivers/dma/dw/core.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/dma/dw/core.c +6 -6
index c128aab076ab..fe083015a354 100644
@@ -180,7 +180,7 @@ static void dwc_initialize(struct dw_dma_chan *dwc)
 
 /*----------------------------------------------------------------------*/
 
-static inline unsigned int dwc_fast_fls(unsigned long long v)
+static inline unsigned int dwc_fast_ffs(unsigned long long v)
 {
 	/*
 	 * We can be a lot more clever here, but this should take care
@@ -744,7 +744,7 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
 			   dw->data_width[dwc->dst_master]);
 
 	src_width = dst_width = min_t(unsigned int, data_width,
-				      dwc_fast_fls(src | dest | len));
+				      dwc_fast_ffs(src | dest | len));
 
 	ctllo = DWC_DEFAULT_CTLLO(chan)
 			| DWC_CTLL_DST_WIDTH(dst_width)
@@ -823,7 +823,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 
 	switch (direction) {
 	case DMA_MEM_TO_DEV:
-		reg_width = __fls(sconfig->dst_addr_width);
+		reg_width = __ffs(sconfig->dst_addr_width);
 		reg = sconfig->dst_addr;
 		ctllo = (DWC_DEFAULT_CTLLO(chan)
 				| DWC_CTLL_DST_WIDTH(reg_width)
@@ -843,7 +843,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 			len = sg_dma_len(sg);
 
 			mem_width = min_t(unsigned int,
-					  data_width, dwc_fast_fls(mem | len));
+					  data_width, dwc_fast_ffs(mem | len));
 
 slave_sg_todev_fill_desc:
 			desc = dwc_desc_get(dwc);
@@ -883,7 +883,7 @@ slave_sg_todev_fill_desc:
 		}
 		break;
 	case DMA_DEV_TO_MEM:
-		reg_width = __fls(sconfig->src_addr_width);
+		reg_width = __ffs(sconfig->src_addr_width);
 		reg = sconfig->src_addr;
 		ctllo = (DWC_DEFAULT_CTLLO(chan)
 				| DWC_CTLL_SRC_WIDTH(reg_width)
@@ -903,7 +903,7 @@ slave_sg_todev_fill_desc:
 			len = sg_dma_len(sg);
 
 			mem_width = min_t(unsigned int,
-					  data_width, dwc_fast_fls(mem | len));
+					  data_width, dwc_fast_ffs(mem | len));
 
 slave_sg_fromdev_fill_desc:
 			desc = dwc_desc_get(dwc);
Signature · 1 line
2.7.2
author
#53 lore raw

PATCH 53/116 megaraid_sas: Do not use PAGE_SIZE for max_sectors

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 357ae967ad66e357f78b5cfb5ab6ca07fb4a7758 upstream.

Do not use PAGE_SIZE marco to calculate max_sectors per I/O request. Driver code assumes PAGE_SIZE will be always 4096 which can lead to wrongly calculated value if PAGE_SIZE is not 4096. This issue was reported in Ubuntu Bugzilla Bug #1475166.

---
 drivers/scsi/megaraid/megaraid_sas.h      | 2 ++
 drivers/scsi/megaraid/megaraid_sas_base.c | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)
drivers/scsi/megaraid/megaraid_sas.h +2 -0
index f2bb2f09bff1..deb1ed816c49 100644
@@ -334,6 +334,8 @@ enum MR_EVT_ARGS {
 	MR_EVT_ARGS_GENERIC,
 };
 
+
+#define SGE_BUFFER_SIZE	4096
 /*
  * define constants for device list query options
  */
drivers/scsi/megaraid/megaraid_sas_base.c +1 -1
index 6da7e62b13fb..884c33d46874 100644
@@ -3819,7 +3819,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
 		}
 	}
 	instance->max_sectors_per_req = instance->max_num_sge *
-						PAGE_SIZE / 512;
+						SGE_BUFFER_SIZE / 512;
 	if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors))
 		instance->max_sectors_per_req = tmp_sectors;
 
Signature · 1 line
2.7.2
author
#54 lore raw

PATCH 54/116 megaraid_sas : SMAP restriction--do not access user memory from IOCTL code

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 323c4a02c631d00851d8edc4213c4d184ef83647 upstream.

This is an issue on SMAP enabled CPUs and 32 bit apps running on 64 bit OS. Do not access user memory from kernel code. The SMAP bit restricts accessing user memory from kernel code.

---
 drivers/scsi/megaraid/megaraid_sas_base.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)
drivers/scsi/megaraid/megaraid_sas_base.c +11 -2
index 884c33d46874..6811a9b37053 100644
@@ -5284,6 +5284,9 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
 	int i;
 	int error = 0;
 	compat_uptr_t ptr;
+	unsigned long local_raw_ptr;
+	u32 local_sense_off;
+	u32 local_sense_len;
 
 	if (clear_user(ioc, sizeof(*ioc)))
 		return -EFAULT;
@@ -5301,9 +5304,15 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
 	 * sense_len is not null, so prepare the 64bit value under
 	 * the same condition.
 	 */
-	if (ioc->sense_len) {
+	if (get_user(local_raw_ptr, ioc->frame.raw) ||
+		get_user(local_sense_off, &ioc->sense_off) ||
+		get_user(local_sense_len, &ioc->sense_len))
+		return -EFAULT;
+
+
+	if (local_sense_len) {
 		void __user **sense_ioc_ptr =
-			(void __user **)(ioc->frame.raw + ioc->sense_off);
+			(void __user **)((u8*)local_raw_ptr + local_sense_off);
 		compat_uptr_t *sense_cioc_ptr =
 			(compat_uptr_t *)(cioc->frame.raw + cioc->sense_off);
 		if (get_user(ptr, sense_cioc_ptr) ||
Signature · 1 line
2.7.2
author
#55 lore raw

PATCH 55/116 storvsc: Don't set the SRB_FLAGS_QUEUE_ACTION_ENABLE flag

In reply to Jiri Slaby

From: "K. Y. Srinivasan" <[email protected]>

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

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

commit 8cf308e1225f5f93575f03cc4dbef24516fa81c9 upstream.

Don't set the SRB_FLAGS_QUEUE_ACTION_ENABLE flag since we are not specifying tags. Without this, the qlogic driver doesn't work properly with storvsc.

---
 drivers/scsi/storvsc_drv.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/scsi/storvsc_drv.c +1 -2
index 3bb6646bb406..f9da66fa850b 100644
@@ -1610,8 +1610,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
 	vm_srb->win8_extension.time_out_value = 60;
 
 	vm_srb->win8_extension.srb_flags |=
-		(SRB_FLAGS_QUEUE_ACTION_ENABLE |
-		SRB_FLAGS_DISABLE_SYNCH_TRANSFER);
+		SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
 
 	/* Build the SRB */
 	switch (scmnd->sc_data_direction) {
Signature · 1 line
2.7.2
author
#56 lore raw

PATCH 56/116 mmc: remove bondage between REQ_META and reliable write

In reply to Jiri Slaby

From: Luca Porzio <[email protected]>

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

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

commit d3df0465db00cf4ed9f90d0bfc3b827d32b9c796 upstream.

Anytime a write operation is performed with Reliable Write flag enabled, the eMMC device is enforced to bypass the cache and do a write to the underling NVM device by Jedec specification; this causes a performance penalty since write operations can't be optimized by the device cache.

In our tests, we replayed a typical mobile daily trace pattern and found ~9% overall time reduction in trace replay by using this patch. Also the write ops within 4KB~64KB chunk size range get a 40~60% performance improvement by using the patch (as this range of write chunks are the ones affected by REQ_META).

This patch has been discussed in the Mobile & Embedded Linux Storage Forum and it's the results of feedbacks from many people. We also checked with fsdevl and f2fs mailing list developers that this change in the usage of REQ_META is not affecting FS behavior and we got positive feedbacks. Reporting here the feedbacks:
http://comments.gmane.org/gmane.linux.file-systems/97219
http://thread.gmane.org/gmane.linux.file-systems.f2fs/3178/focus=3183

Fixes ce39f9d17c14 ("mmc: support packed write command for eMMC4.5 devices")
---
 drivers/mmc/card/block.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)
drivers/mmc/card/block.c +3 -8
index 88554c22265c..30076b4f3fee 100644
@@ -62,8 +62,7 @@ MODULE_ALIAS("mmc:block");
 #define MMC_SANITIZE_REQ_TIMEOUT 240000
 #define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16)
 
-#define mmc_req_rel_wr(req)	(((req->cmd_flags & REQ_FUA) || \
-				  (req->cmd_flags & REQ_META)) && \
+#define mmc_req_rel_wr(req)	((req->cmd_flags & REQ_FUA) && \
 				  (rq_data_dir(req) == WRITE))
 #define PACKED_CMD_VER	0x01
 #define PACKED_CMD_WR	0x02
@@ -1328,13 +1327,9 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
 
 	/*
 	 * Reliable writes are used to implement Forced Unit Access and
-	 * REQ_META accesses, and are supported only on MMCs.
-	 *
-	 * XXX: this really needs a good explanation of why REQ_META
-	 * is treated special.
+	 * are supported only on MMCs.
 	 */
-	bool do_rel_wr = ((req->cmd_flags & REQ_FUA) ||
-			  (req->cmd_flags & REQ_META)) &&
+	bool do_rel_wr = (req->cmd_flags & REQ_FUA) &&
 		(rq_data_dir(req) == WRITE) &&
 		(md->flags & MMC_BLK_REL_WR);
 
Signature · 1 line
2.7.2
author
#57 lore raw

PATCH 57/116 mac: validate mac_partition is within sector

In reply to Jiri Slaby

From: Kees Cook <[email protected]>

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

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

commit 02e2a5bfebe99edcf9d694575a75032d53fe1b73 upstream.

If md->signature == MAC_DRIVER_MAGIC and md->block_size == 1023, a single 512 byte sector would be read (secsize / 512). However the partition structure would be located past the end of the buffer (secsize % 512).

---
 block/partitions/mac.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
block/partitions/mac.c +7 -3
index 76d8ba6379a9..bd5b91465230 100644
@@ -32,7 +32,7 @@ int mac_partition(struct parsed_partitions *state)
 	Sector sect;
 	unsigned char *data;
 	int slot, blocks_in_map;
-	unsigned secsize;
+	unsigned secsize, datasize, partoffset;
 #ifdef CONFIG_PPC_PMAC
 	int found_root = 0;
 	int found_root_goodness = 0;
@@ -50,10 +50,14 @@ int mac_partition(struct parsed_partitions *state)
 	}
 	secsize = be16_to_cpu(md->block_size);
 	put_dev_sector(sect);
-	data = read_part_sector(state, secsize/512, &sect);
+	datasize = round_down(secsize, 512);
+	data = read_part_sector(state, datasize / 512, &sect);
 	if (!data)
 		return -1;
-	part = (struct mac_partition *) (data + secsize%512);
+	partoffset = secsize % 512;
+	if (partoffset + sizeof(*part) > datasize)
+		return -1;
+	part = (struct mac_partition *) (data + partoffset);
 	if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) {
 		put_dev_sector(sect);
 		return 0;		/* not a MacOS disk */
Signature · 1 line
2.7.2
author
#58 lore raw

PATCH 58/116 vfs: Avoid softlockups with sendfile(2)

In reply to Jiri Slaby

From: Jan Kara <[email protected]>

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

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

commit c2489e07c0a71a56fb2c84bc0ee66cddfca7d068 upstream.

The following test program from Dmitry can cause softlockups or RCU stalls as it copies 1GB from tmpfs into eventfd and we don't have any scheduling point at that path in sendfile(2) implementation:

        int r1 = eventfd(0, 0);
        int r2 = memfd_create("", 0);
        unsigned long n = 1<<30;
        fallocate(r2, 0, 0, n);
        sendfile(r1, r2, 0, n);

Add cond_resched() into __splice_from_pipe() to fix the problem.

---
 fs/splice.c | 1 +
 1 file changed, 1 insertion(+)
fs/splice.c +1 -0
index 76cb3a0b1ec4..76cbc01df6a4 100644
@@ -949,6 +949,7 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd,
 
 	splice_from_pipe_begin(sd);
 	do {
+		cond_resched();
 		ret = splice_from_pipe_next(pipe, sd);
 		if (ret > 0)
 			ret = splice_from_pipe_feed(pipe, sd, actor);
Signature · 1 line
2.7.2
author
#59 lore raw

PATCH 59/116 target: Fix race for SCF_COMPARE_AND_WRITE_POST checking

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 057085e522f8bf94c2e691a5b76880f68060f8ba upstream.

This patch addresses a race + use after free where the first stage of COMPARE_AND_WRITE in compare_and_write_callback() is rescheduled after the backend sends the secondary WRITE, resulting in second stage compare_and_write_post() callback completing in target_complete_ok_work() before the first can return.

Because current code depends on checking se_cmd->se_cmd_flags after return from se_cmd->transport_complete_callback(), this results in first stage having SCF_COMPARE_AND_WRITE_POST set, which incorrectly falls through into second stage CAW processing code, eventually triggering a NULL pointer dereference due to use after free.

To address this bug, pass in a new *post_ret parameter into se_cmd->transport_complete_callback(), and depend upon this value instead of ->se_cmd_flags to determine when to return or fall through into ->queue_status() code for CAW.

---
 drivers/target/target_core_sbc.c       | 13 +++++++++----
 drivers/target/target_core_transport.c | 14 ++++++++------
 include/target/target_core_base.h      |  2 +-
 3 files changed, 18 insertions(+), 11 deletions(-)
drivers/target/target_core_sbc.c +9 -4
index 75f126538a72..6e60ab250f55 100644
@@ -298,7 +298,8 @@ sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *o
 	return 0;
 }
 
-static sense_reason_t xdreadwrite_callback(struct se_cmd *cmd, bool success)
+static sense_reason_t xdreadwrite_callback(struct se_cmd *cmd, bool success,
+					   int *post_ret)
 {
 	unsigned char *buf, *addr;
 	struct scatterlist *sg;
@@ -362,7 +363,8 @@ sbc_execute_rw(struct se_cmd *cmd)
 			       cmd->data_direction);
 }
 
-static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success)
+static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success,
+					     int *post_ret)
 {
 	struct se_device *dev = cmd->se_dev;
 
@@ -372,8 +374,10 @@ static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success)
 	 * sent to the backend driver.
 	 */
 	spin_lock_irq(&cmd->t_state_lock);
-	if ((cmd->transport_state & CMD_T_SENT) && !cmd->scsi_status)
+	if ((cmd->transport_state & CMD_T_SENT) && !cmd->scsi_status) {
 		cmd->se_cmd_flags |= SCF_COMPARE_AND_WRITE_POST;
+		*post_ret = 1;
+	}
 	spin_unlock_irq(&cmd->t_state_lock);
 
 	/*
@@ -385,7 +389,8 @@ static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success)
 	return TCM_NO_SENSE;
 }
 
-static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool success)
+static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool success,
+						 int *post_ret)
 {
 	struct se_device *dev = cmd->se_dev;
 	struct scatterlist *write_sg = NULL, *sg;
drivers/target/target_core_transport.c +8 -6
index b52bf3cad494..b335709f050f 100644
@@ -1570,7 +1570,7 @@ bool target_stop_cmd(struct se_cmd *cmd, unsigned long *flags)
 void transport_generic_request_failure(struct se_cmd *cmd,
 		sense_reason_t sense_reason)
 {
-	int ret = 0;
+	int ret = 0, post_ret = 0;
 
 	pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08x"
 		" CDB: 0x%02x\n", cmd, cmd->se_tfo->get_task_tag(cmd),
@@ -1593,7 +1593,7 @@ void transport_generic_request_failure(struct se_cmd *cmd,
 	 */
 	if ((cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE) &&
 	     cmd->transport_complete_callback)
-		cmd->transport_complete_callback(cmd, false);
+		cmd->transport_complete_callback(cmd, false, &post_ret);
 
 	switch (sense_reason) {
 	case TCM_NON_EXISTENT_LUN:
@@ -1941,11 +1941,13 @@ static void target_complete_ok_work(struct work_struct *work)
 	 */
 	if (cmd->transport_complete_callback) {
 		sense_reason_t rc;
+		bool caw = (cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE);
+		bool zero_dl = !(cmd->data_length);
+		int post_ret = 0;
 
-		rc = cmd->transport_complete_callback(cmd, true);
-		if (!rc && !(cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE_POST)) {
-			if ((cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE) &&
-			    !cmd->data_length)
+		rc = cmd->transport_complete_callback(cmd, true, &post_ret);
+		if (!rc && !post_ret) {
+			if (caw && zero_dl)
 				goto queue_rsp;
 
 			return;
include/target/target_core_base.h +1 -1
index 085e6bedf393..5c5700bd1345 100644
@@ -457,7 +457,7 @@ struct se_cmd {
 	sense_reason_t		(*execute_cmd)(struct se_cmd *);
 	sense_reason_t		(*execute_rw)(struct se_cmd *, struct scatterlist *,
 					      u32, enum dma_data_direction);
-	sense_reason_t (*transport_complete_callback)(struct se_cmd *, bool);
+	sense_reason_t (*transport_complete_callback)(struct se_cmd *, bool, int *);
 
 	unsigned char		*t_task_cdb;
 	unsigned char		__t_task_cdb[TCM_MAX_COMMAND_SIZE];
Signature · 1 line
2.7.2
author
#60 lore raw

PATCH 60/116 target: fix COMPARE_AND_WRITE non zero SGL offset data corruption

In reply to Jiri Slaby

From: Jan Engelhardt <[email protected]>

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

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

commit d94e5a61357a04938ce14d6033b4d33a3c5fd780 upstream.

target_core_sbc's compare_and_write functionality suffers from taking data at the wrong memory location when writing a CAW request to disk when a SGL offset is non-zero.

This can happen with loopback and vhost-scsi fabric drivers when SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC is used to map existing user-space SGL memory into COMPARE_AND_WRITE READ/WRITE payload buffers.

Given the following sample LIO subtopology,

% targetcli ls /loopback/
o- loopback ................................. [1 Target]
o- naa.6001405ebb8df14a ....... [naa.60014059143ed2b3]

    o- luns ................................... [2 LUNs]
      o- lun0 ................ [iblock/ram0 (/dev/ram0)]
      o- lun1 ................ [iblock/ram1 (/dev/ram1)]
% lsscsi -g
[3:0:1:0]    disk    LIO-ORG  IBLOCK           4.0   /dev/sdc   /dev/sg3
[3:0:1:1]    disk    LIO-ORG  IBLOCK           4.0   /dev/sdd   /dev/sg4

the following bug can be observed in Linux 4.3 and 4.4~rc1:

% perl -e 'print chr$_ for 0..255,reverse 0..255' >rand % perl -e 'print "\0" x 512' >zero
% cat rand >/dev/sdd
% sg_compare_and_write -i rand -D zero --lba 0 /dev/sdd % sg_compare_and_write -i zero -D rand --lba 0 /dev/sdd Miscompare reported
% hexdump -Cn 512 /dev/sdd

00000000  0f 0e 0d 0c 0b 0a 09 08  07 06 05 04 03 02 01 00
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00

*
00000200

Rather than writing all-zeroes as instructed with the -D file, it corrupts the data in the sector by splicing some of the original bytes in. The page of the first entry of cmd->t_data_sg includes the CDB, and sg->offset is set to a position past the CDB. I presume that sg->offset is also the right choice to use for subsequent sglist members.

---
 drivers/target/target_core_sbc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/target/target_core_sbc.c +2 -2
index 6e60ab250f55..401fc7097935 100644
@@ -486,11 +486,11 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool succes
 
 		if (block_size < PAGE_SIZE) {
 			sg_set_page(&write_sg[i], m.page, block_size,
-				    block_size);
+				    m.piter.sg->offset + block_size);
 		} else {
 			sg_miter_next(&m);
 			sg_set_page(&write_sg[i], m.page, block_size,
-				    0);
+				    m.piter.sg->offset);
 		}
 		len -= block_size;
 		i++;
Signature · 1 line
2.7.2
author
#61 lore raw

PATCH 61/116 ring-buffer: Update read stamp with first real commit on page

In reply to Jiri Slaby

From: "Steven Rostedt (Red Hat)" <[email protected]>

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

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

commit b81f472a208d3e2b4392faa6d17037a89442f4ce upstream.

Do not update the read stamp after swapping out the reader page from the write buffer. If the reader page is swapped out of the buffer before an event is written to it, then the read_stamp may get an out of date timestamp, as the page timestamp is updated on the first commit to that page.

rb_get_reader_page() only returns a page if it has an event on it, otherwise it will return NULL. At that point, check if the page being returned has events and has not been read yet. Then at that point update the read_stamp to match the time stamp of the reader page.

---
 kernel/trace/ring_buffer.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)
kernel/trace/ring_buffer.c +5 -7
index d6b35d3a232c..321ee4205160 100644
@@ -1933,12 +1933,6 @@ rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer)
 		goto again;
 }
 
-static void rb_reset_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
-{
-	cpu_buffer->read_stamp = cpu_buffer->reader_page->page->time_stamp;
-	cpu_buffer->reader_page->read = 0;
-}
-
 static void rb_inc_iter(struct ring_buffer_iter *iter)
 {
 	struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
@@ -3576,7 +3570,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
 
 	/* Finally update the reader page to the new head */
 	cpu_buffer->reader_page = reader;
-	rb_reset_reader_page(cpu_buffer);
+	cpu_buffer->reader_page->read = 0;
 
 	if (overwrite != cpu_buffer->last_overrun) {
 		cpu_buffer->lost_events = overwrite - cpu_buffer->last_overrun;
@@ -3586,6 +3580,10 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
 	goto again;
 
  out:
+	/* Update the read_stamp on the first event */
+	if (reader && reader->read == 0)
+		cpu_buffer->read_stamp = reader->page->time_stamp;
+
 	arch_spin_unlock(&cpu_buffer->lock);
 	local_irq_restore(flags);
 
Signature · 1 line
2.7.2
author
#62 lore raw

PATCH 62/116 virtio: fix memory leak of virtio ida cache layers

In reply to Jiri Slaby

From: Suman Anna <[email protected]>

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

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

commit c13f99b7e945dad5273a8b7ee230f4d1f22d3354 upstream.

The virtio core uses a static ida named virtio_index_ida for assigning index numbers to virtio devices during registration. The ida core may allocate some internal idr cache layers and an ida bitmap upon any ida allocation, and all these layers are truely freed only upon the ida destruction. The virtio_index_ida is not destroyed at present, leading to a memory leak when using the virtio core as a module and atleast one virtio device is registered and unregistered.

Fix this by invoking ida_destroy() in the virtio core module exit.

---
 drivers/virtio/virtio.c | 1 +
 1 file changed, 1 insertion(+)
drivers/virtio/virtio.c +1 -0
index ee59b74768d9..beaa7cc4e857 100644
@@ -238,6 +238,7 @@ static int virtio_init(void)
 static void __exit virtio_exit(void)
 {
 	bus_unregister(&virtio_bus);
+	ida_destroy(&virtio_index_ida);
 }
 core_initcall(virtio_init);
 module_exit(virtio_exit);
Signature · 1 line
2.7.2
author
#63 lore raw

PATCH 63/116 mac80211: mesh: fix call_rcu() usage

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 c2e703a55245bfff3db53b1f7cbe59f1ee8a4339 upstream.

When using call_rcu(), the called function may be delayed quite significantly, and without a matching rcu_barrier() there's no way to be sure it has finished.
Therefore, global state that could be gone/freed/reused should never be touched in the callback.

Fix this in mesh by moving the atomic_dec() into the caller; that's not really a problem since we already unlinked the path and it will be destroyed anyway.

This fixes a crash Jouni observed when running certain tests in a certain order, in which the mesh interface was torn down, the memory reused for a function pointer (work struct) and running that then crashed since the pointer had been decremented by 1, resulting in an invalid instruction byte stream.

Fixes eb2b9311fd00 ("mac80211: mesh path table implementation")
---
 net/mac80211/mesh_pathtbl.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
net/mac80211/mesh_pathtbl.c +4 -4
index 89aacfd2756d..9ba6d8c7c793 100644
@@ -747,10 +747,8 @@ void mesh_plink_broken(struct sta_info *sta)
 static void mesh_path_node_reclaim(struct rcu_head *rp)
 {
 	struct mpath_node *node = container_of(rp, struct mpath_node, rcu);
-	struct ieee80211_sub_if_data *sdata = node->mpath->sdata;
 
 	del_timer_sync(&node->mpath->timer);
-	atomic_dec(&sdata->u.mesh.mpaths);
 	kfree(node->mpath);
 	kfree(node);
 }
@@ -758,8 +756,9 @@ static void mesh_path_node_reclaim(struct rcu_head *rp)
 /* needs to be called with the corresponding hashwlock taken */
 static void __mesh_path_del(struct mesh_table *tbl, struct mpath_node *node)
 {
-	struct mesh_path *mpath;
-	mpath = node->mpath;
+	struct mesh_path *mpath = node->mpath;
+	struct ieee80211_sub_if_data *sdata = node->mpath->sdata;
+
 	spin_lock(&mpath->state_lock);
 	mpath->flags |= MESH_PATH_RESOLVING;
 	if (mpath->is_gate)
@@ -767,6 +766,7 @@ static void __mesh_path_del(struct mesh_table *tbl, struct mpath_node *node)
 	hlist_del_rcu(&node->list);
 	call_rcu(&node->rcu, mesh_path_node_reclaim);
 	spin_unlock(&mpath->state_lock);
+	atomic_dec(&sdata->u.mesh.mpaths);
 	atomic_dec(&tbl->entries);
 }
 
Signature · 1 line
2.7.2
author
#64 lore raw

PATCH 64/116 sched/core: Clear the root_domain cpumasks in init_rootdomain()

In reply to Jiri Slaby

From: Xunlei Pang <[email protected]>

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

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

commit 8295c69925ad53ec32ca54ac9fc194ff21bc40e2 upstream.

root_domain::rto_mask allocated through alloc_cpumask_var() contains garbage data, this may cause problems. For instance, When doing pull_rt_task(), it may do useless iterations if rto_mask retains some extra garbage bits. Worse still, this violates the isolated domain rule for clustered scheduling using cpuset, because the tasks(with all the cpus allowed) belongs to one root domain can be pulled away into another root domain.

The patch cleans the garbage by using zalloc_cpumask_var() instead of alloc_cpumask_var() for root_domain::rto_mask allocation, thereby addressing the issues.

Do the same thing for root_domain's other cpumask memembers:
dlo_mask, span, and online.

---
 kernel/sched/core.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/sched/core.c +3 -3
index 9b2394fffc2f..e7de9175e586 100644
@@ -5054,11 +5054,11 @@ static int init_rootdomain(struct root_domain *rd)
 {
 	memset(rd, 0, sizeof(*rd));
 
-	if (!alloc_cpumask_var(&rd->span, GFP_KERNEL))
+	if (!zalloc_cpumask_var(&rd->span, GFP_KERNEL))
 		goto out;
-	if (!alloc_cpumask_var(&rd->online, GFP_KERNEL))
+	if (!zalloc_cpumask_var(&rd->online, GFP_KERNEL))
 		goto free_span;
-	if (!alloc_cpumask_var(&rd->rto_mask, GFP_KERNEL))
+	if (!zalloc_cpumask_var(&rd->rto_mask, GFP_KERNEL))
 		goto free_online;
 
 	if (cpupri_init(&rd->cpupri) != 0)
Signature · 1 line
2.7.2
author
#65 lore raw

PATCH 65/116 sched/core: Remove false-positive warning from wake_up_process()

In reply to Jiri Slaby

From: Sasha Levin <[email protected]>

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

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

commit 119d6f6a3be8b424b200dcee56e74484d5445f7e upstream.

Because wakeups can (fundamentally) be late, a task might not be in the expected state. Therefore testing against a task's state is racy, and can yield false positives.

Cc Mike Galbraith <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
Fixes 9067ac85d533 ("wake_up_process() should be never used to wakeup a TASK_STOPPED/TRACED task")
---
 kernel/sched/core.c | 1 -
 1 file changed, 1 deletion(-)
kernel/sched/core.c +0 -1
index e7de9175e586..3800316d7424 100644
@@ -1590,7 +1590,6 @@ out:
  */
 int wake_up_process(struct task_struct *p)
 {
-	WARN_ON(task_is_stopped_or_traced(p));
 	return try_to_wake_up(p, TASK_NORMAL, 0);
 }
 EXPORT_SYMBOL(wake_up_process);
Signature · 1 line
2.7.2
author
#66 lore raw

PATCH 66/116 sata_sil: disable trim

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 d98f1cd0a3b70ea91f1dfda3ac36c3b2e1a4d5e2 upstream.

When I connect an Intel SSD to SATA SIL controller (PCI ID 1095:3114), any TRIM command results in I/O errors being reported in the log. There is other similar error reported with TRIM and the SIL controller:
https://bugs.centos.org/view.php?id=5880

Apparently the controller doesn't support TRIM commands. This patch disables TRIM support on the SATA SIL controller.

ata7.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0 ata7.00: BMDMA2 stat 0x50001
ata7.00: failed command: DATA SET MANAGEMENT
ata7.00: cmd 06/01:01:00:00:00/00:00:00:00:00/a0 tag 0 dma 512 out

         res 51/04:01:00:00:00/00:00:00:00:00/a0 Emask 0x1 (device error)

ata7.00: status: { DRDY ERR }
ata7.00: error: { ABRT }
ata7.00: device reported invalid CHS sector 0
sd 8:0:0:0: [sdb] tag#0 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE sd 8:0:0:0: [sdb] tag#0 Sense Key : Illegal Request [current] [descriptor] sd 8:0:0:0: [sdb] tag#0 Add. Sense: Unaligned write command
sd 8:0:0:0: [sdb] tag#0 CDB: Write same(16) 93 08 00 00 00 00 00 21 95 88 00 20 00 00 00 00
blk_update_request: I/O error, dev sdb, sector 2200968

---
 drivers/ata/sata_sil.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/ata/sata_sil.c +3 -0
index b7695e804635..fa94fba8fa21 100644
@@ -631,6 +631,9 @@ static void sil_dev_config(struct ata_device *dev)
 	unsigned int n, quirks = 0;
 	unsigned char model_num[ATA_ID_PROD_LEN + 1];
 
+	/* This controller doesn't support trim */
+	dev->horkage |= ATA_HORKAGE_NOTRIM;
+
 	ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
 
 	for (n = 0; sil_blacklist[n].product; n++)
Signature · 1 line
2.7.2
author
#67 lore raw

PATCH 67/116 dm space map metadata: fix ref counting bug when bootstrapping a new space map

In reply to Jiri Slaby

From: Joe Thornber <[email protected]>

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

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

commit 50dd842ad83b43bed71790efb31cfb2f6c05c9c1 upstream.

When applying block operations (BOPs) do not remove them from the uncommitted BOP ring-buffer until after they've been applied -- in case we recurse.

Also, perform BOP_INC operation, in dm_sm_metadata_create() and sm_metadata_extend(), in terms of the uncommitted BOP ring-buffer rather than using direct calls to sm_ll_inc().

---
 drivers/md/persistent-data/dm-space-map-metadata.c | 32 +++++++++++++++-------
 1 file changed, 22 insertions(+), 10 deletions(-)
drivers/md/persistent-data/dm-space-map-metadata.c +22 -10
index f6dea401232c..722bd48024d6 100644
@@ -136,7 +136,7 @@ static int brb_push(struct bop_ring_buffer *brb,
 	return 0;
 }
 
-static int brb_pop(struct bop_ring_buffer *brb, struct block_op *result)
+static int brb_peek(struct bop_ring_buffer *brb, struct block_op *result)
 {
 	struct block_op *bop;
 
@@ -147,6 +147,17 @@ static int brb_pop(struct bop_ring_buffer *brb, struct block_op *result)
 	result->type = bop->type;
 	result->block = bop->block;
 
+	return 0;
+}
+
+static int brb_pop(struct bop_ring_buffer *brb)
+{
+	struct block_op *bop;
+
+	if (brb_empty(brb))
+		return -ENODATA;
+
+	bop = brb->bops + brb->begin;
 	brb->begin = brb_next(brb, brb->begin);
 
 	return 0;
@@ -211,7 +222,7 @@ static int apply_bops(struct sm_metadata *smm)
 	while (!brb_empty(&smm->uncommitted)) {
 		struct block_op bop;
 
-		r = brb_pop(&smm->uncommitted, &bop);
+		r = brb_peek(&smm->uncommitted, &bop);
 		if (r) {
 			DMERR("bug in bop ring buffer");
 			break;
@@ -220,6 +231,8 @@ static int apply_bops(struct sm_metadata *smm)
 		r = commit_bop(smm, &bop);
 		if (r)
 			break;
+
+		brb_pop(&smm->uncommitted);
 	}
 
 	return r;
@@ -681,7 +694,6 @@ static struct dm_space_map bootstrap_ops = {
 static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
 {
 	int r, i;
-	enum allocation_event ev;
 	struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
 	dm_block_t old_len = smm->ll.nr_blocks;
 
@@ -703,11 +715,12 @@ static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
 	 * allocate any new blocks.
 	 */
 	do {
-		for (i = old_len; !r && i < smm->begin; i++) {
-			r = sm_ll_inc(&smm->ll, i, &ev);
-			if (r)
-				goto out;
-		}
+		for (i = old_len; !r && i < smm->begin; i++)
+			r = add_bop(smm, BOP_INC, i);
+
+		if (r)
+			goto out;
+
 		old_len = smm->begin;
 
 		r = apply_bops(smm);
@@ -752,7 +765,6 @@ int dm_sm_metadata_create(struct dm_space_map *sm,
 {
 	int r;
 	dm_block_t i;
-	enum allocation_event ev;
 	struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
 
 	smm->begin = superblock + 1;
@@ -778,7 +790,7 @@ int dm_sm_metadata_create(struct dm_space_map *sm,
 	 * allocated blocks that they were built from.
 	 */
 	for (i = superblock; !r && i < smm->begin; i++)
-		r = sm_ll_inc(&smm->ll, i, &ev);
+		r = add_bop(smm, BOP_INC, i);
 
 	if (r)
 		return r;
Signature · 1 line
2.7.2
author
#68 lore raw

PATCH 68/116 dm btree: fix bufio buffer leaks in dm_btree_del() error path

In reply to Jiri Slaby

From: Joe Thornber <[email protected]>

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

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

commit ed8b45a3679eb49069b094c0711b30833f27c734 upstream.

If dm_btree_del()'s call to push_frame() fails, e.g. due to btree_node_validator finding invalid metadata, the dm_btree_del() error path must unlock all frames (which have active dm-bufio buffers) that were pushed onto the del_stack.

Otherwise, dm_bufio_client_destroy() will BUG_ON() because dm-bufio buffers have leaked, e.g.:
device-mapper: bufio: leaked buffer 3, hold count 1, list 0

---
 drivers/md/persistent-data/dm-btree.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)
drivers/md/persistent-data/dm-btree.c +15 -1
index 28662bd600e0..67eae74a5525 100644
@@ -250,6 +250,16 @@ static void pop_frame(struct del_stack *s)
 	dm_tm_unlock(s->tm, f->b);
 }
 
+static void unlock_all_frames(struct del_stack *s)
+{
+	struct frame *f;
+
+	while (unprocessed_frames(s)) {
+		f = s->spine + s->top--;
+		dm_tm_unlock(s->tm, f->b);
+	}
+}
+
 int dm_btree_del(struct dm_btree_info *info, dm_block_t root)
 {
 	int r;
@@ -306,9 +316,13 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root)
 			pop_frame(s);
 		}
 	}
-
 out:
+	if (r) {
+		/* cleanup all frames of del_stack */
+		unlock_all_frames(s);
+	}
 	kfree(s);
+
 	return r;
 }
 EXPORT_SYMBOL_GPL(dm_btree_del);
Signature · 1 line
2.7.2
author
#69 lore raw

PATCH 69/116 vgaarb: fix signal handling in vga_get()

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 9f5bd30818c42c6c36a51f93b4df75a2ea2bd85e upstream.

There are few defects in vga_get() related to signal hadning:

- we shouldn't check for pending signals for TASK_UNINTERRUPTIBLE

    case;

- if we found pending signal we must remove ourself from wait queue

    and change task state back to running;

- -ERESTARTSYS is more appropriate, I guess.

---
 drivers/gpu/vga/vgaarb.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/gpu/vga/vgaarb.c +4 -2
index af0259708358..bbb554d586d4 100644
@@ -392,8 +392,10 @@ int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible)
 		set_current_state(interruptible ?
 				  TASK_INTERRUPTIBLE :
 				  TASK_UNINTERRUPTIBLE);
-		if (signal_pending(current)) {
-			rc = -EINTR;
+		if (interruptible && signal_pending(current)) {
+			__set_current_state(TASK_RUNNING);
+			remove_wait_queue(&vga_wait_queue, &wait);
+			rc = -ERESTARTSYS;
 			break;
 		}
 		schedule();
Signature · 1 line
2.7.2
author
#70 lore raw

PATCH 70/116 rfkill: copy the name into the rfkill struct

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 b7bb110008607a915298bf0f47d25886ecb94477 upstream.

Some users of rfkill, like NFC and cfg80211, use a dynamic name when allocating rfkill, in those cases dev_name(). Therefore, the pointer passed to rfkill_alloc() might not be valid forever, I specifically found the case that the rfkill name was quite obviously an invalid pointer (or at least garbage) when the wiphy had been renamed.

Fix this by making a copy of the rfkill name in rfkill_alloc().

---
 net/rfkill/core.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
net/rfkill/core.c +3 -3
index 1bacc1079942..5a14f55a1926 100644
@@ -51,7 +51,6 @@
 struct rfkill {
 	spinlock_t		lock;
 
-	const char		*name;
 	enum rfkill_type	type;
 
 	unsigned long		state;
@@ -75,6 +74,7 @@ struct rfkill {
 	struct delayed_work	poll_work;
 	struct work_struct	uevent_work;
 	struct work_struct	sync_work;
+	char			name[];
 };
 #define to_rfkill(d)	container_of(d, struct rfkill, dev)
 
@@ -863,14 +863,14 @@ struct rfkill * __must_check rfkill_alloc(const char *name,
 	if (WARN_ON(type == RFKILL_TYPE_ALL || type >= NUM_RFKILL_TYPES))
 		return NULL;
 
-	rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL);
+	rfkill = kzalloc(sizeof(*rfkill) + strlen(name) + 1, GFP_KERNEL);
 	if (!rfkill)
 		return NULL;
 
 	spin_lock_init(&rfkill->lock);
 	INIT_LIST_HEAD(&rfkill->node);
 	rfkill->type = type;
-	rfkill->name = name;
+	strcpy(rfkill->name, name);
 	rfkill->ops = ops;
 	rfkill->data = ops_data;
 
Signature · 1 line
2.7.2
author
#71 lore raw

PATCH 71/116 ses: Fix problems with simple enclosures

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 3417c1b5cb1fdc10261dbed42b05cc93166a78fd upstream.

Simple enclosure implementations (mostly USB) are allowed to return only page 8 to every diagnostic query. That really confuses our implementation because we assume the return is the page we asked for and end up doing incorrect offsets based on bogus information leading to accesses outside of allocated ranges. Fix that by checking the page code of the return and giving an error if it isn't the one we asked for. This should fix reported bugs with USB storage by simply refusing to attach to enclosures that behave like this. It's also good defensive practise now that we're starting to see more USB enclosures.

---
 drivers/scsi/ses.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)
drivers/scsi/ses.c +19 -1
index eba183c428cf..b3051fed34f1 100644
@@ -70,6 +70,7 @@ static int ses_probe(struct device *dev)
 static int ses_recv_diag(struct scsi_device *sdev, int page_code,
 			 void *buf, int bufflen)
 {
+	int ret;
 	unsigned char cmd[] = {
 		RECEIVE_DIAGNOSTIC,
 		1,		/* Set PCV bit */
@@ -78,9 +79,26 @@ static int ses_recv_diag(struct scsi_device *sdev, int page_code,
 		bufflen & 0xff,
 		0
 	};
+	unsigned char recv_page_code;
 
-	return scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
+	ret =  scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
 				NULL, SES_TIMEOUT, SES_RETRIES, NULL);
+	if (unlikely(!ret))
+		return ret;
+
+	recv_page_code = ((unsigned char *)buf)[0];
+
+	if (likely(recv_page_code == page_code))
+		return ret;
+
+	/* successful diagnostic but wrong page code.  This happens to some
+	 * USB devices, just print a message and pretend there was an error */
+
+	sdev_printk(KERN_ERR, sdev,
+		    "Wrong diagnostic page; asked for %d got %u\n",
+		    page_code, recv_page_code);
+
+	return -EINVAL;
 }
 
 static int ses_send_diag(struct scsi_device *sdev, int page_code,
Signature · 1 line
2.7.2
author
#72 lore raw

PATCH 72/116 ses: fix additional element traversal bug

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 5e1033561da1152c57b97ee84371dba2b3d64c25 upstream.

KASAN found that our additional element processing scripts drop off the end of the VPD page into unallocated space. The reason is that not every element has additional information but our traversal routines think they do, leading to them expecting far more additional information than is present. Fix this by adding a gate to the traversal routine so that it only processes elements that are expected to have additional information (list is in SES-2 section 6.1.13.1:
Additional Element Status diagnostic page overview)

---
 drivers/scsi/ses.c        | 10 +++++++++-
 include/linux/enclosure.h |  4 ++++
 2 files changed, 13 insertions(+), 1 deletion(-)
drivers/scsi/ses.c +9 -1
index b3051fed34f1..3643bbf5456d 100644
@@ -454,7 +454,15 @@ static void ses_enclosure_data_process(struct enclosure_device *edev,
 			if (desc_ptr)
 				desc_ptr += len;
 
-			if (addl_desc_ptr)
+			if (addl_desc_ptr &&
+			    /* only find additional descriptions for specific devices */
+			    (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
+			     type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE ||
+			     type_ptr[0] == ENCLOSURE_COMPONENT_SAS_EXPANDER ||
+			     /* these elements are optional */
+			     type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_TARGET_PORT ||
+			     type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT ||
+			     type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS))
 				addl_desc_ptr += addl_desc_ptr[1] + 2;
 
 		}
include/linux/enclosure.h +4 -0
index 9a33c5f7e126..f6c229e2bffa 100644
@@ -29,7 +29,11 @@
 /* A few generic types ... taken from ses-2 */
 enum enclosure_component_type {
 	ENCLOSURE_COMPONENT_DEVICE = 0x01,
+	ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS = 0x07,
+	ENCLOSURE_COMPONENT_SCSI_TARGET_PORT = 0x14,
+	ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT = 0x15,
 	ENCLOSURE_COMPONENT_ARRAY_DEVICE = 0x17,
+	ENCLOSURE_COMPONENT_SAS_EXPANDER = 0x18,
 };
 
 /* ses-2 common element status */
Signature · 1 line
2.7.2
author
#73 lore raw

PATCH 73/116 scripts: recordmcount: break hardlinks

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 dd39a26538e37f6c6131e829a4a510787e43c783 upstream.

recordmcount edits the file in-place, which can cause problems when using ccache in hardlink mode. Arrange for recordmcount to break a hardlinked object.

---
 scripts/recordmcount.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
scripts/recordmcount.c +14 -0
index 9c22317778eb..ee625e3a56ba 100644
@@ -189,6 +189,20 @@ static void *mmap_file(char const *fname)
 		addr = umalloc(sb.st_size);
 		uread(fd_map, addr, sb.st_size);
 	}
+	if (sb.st_nlink != 1) {
+		/* file is hard-linked, break the hard link */
+		close(fd_map);
+		if (unlink(fname) < 0) {
+			perror(fname);
+			fail_file();
+		}
+		fd_map = open(fname, O_RDWR | O_CREAT, sb.st_mode);
+		if (fd_map < 0) {
+			perror(fname);
+			fail_file();
+		}
+		uwrite(fd_map, addr, sb.st_size);
+	}
 	return addr;
 }
 
Signature · 1 line
2.7.2
author
#74 lore raw

PATCH 74/116 Btrfs: add missing brelse when superblock checksum fails

In reply to Jiri Slaby

From: Anand Jain <[email protected]>

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

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

commit b2acdddfad13c38a1e8b927d83c3cf321f63601a upstream.

Looks like oversight, call brelse() when checksum fails. Further down the code, in the non error path, we do call brelse() and so we don't see brelse() in the goto error paths.

---
 fs/btrfs/disk-io.c | 1 +
 1 file changed, 1 insertion(+)
fs/btrfs/disk-io.c +1 -0
index 3ec1cb0808c3..2622ec8a76f0 100644
@@ -2340,6 +2340,7 @@ int open_ctree(struct super_block *sb,
 	bh = btrfs_read_dev_super(fs_devices->latest_bdev);
 	if (!bh) {
 		err = -EINVAL;
+		brelse(bh);
 		goto fail_alloc;
 	}
 
Signature · 1 line
2.7.2
author
#75 lore raw

PATCH 75/116 Btrfs: igrab inode in writepage

In reply to Jiri Slaby

From: Josef Bacik <[email protected]>

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

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

commit be7bd730841e69fe8f70120098596f648cd1f3ff upstream.

We hit this panic on a few of our boxes this week where we have an ordered_extent with an NULL inode. We do an igrab() of the inode in writepages, but weren't doing it in writepage which can be called directly from the VM on dirty pages. If the inode has been unlinked then we could have I_FREEING set which means igrab() would return NULL and we get this panic. Fix this by trying to igrab in btrfs_writepage, and if it returns NULL then just redirty the page and return AOP_WRITEPAGE_ACTIVATE; so the VM knows it wasn't successful. Thanks,

---
 fs/btrfs/inode.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)
fs/btrfs/inode.c +15 -2
index 264be61a3f40..c6f91432cc67 100644
@@ -7343,15 +7343,28 @@ int btrfs_readpage(struct file *file, struct page *page)
 static int btrfs_writepage(struct page *page, struct writeback_control *wbc)
 {
 	struct extent_io_tree *tree;
-
+	struct inode *inode = page->mapping->host;
+	int ret;
 
 	if (current->flags & PF_MEMALLOC) {
 		redirty_page_for_writepage(wbc, page);
 		unlock_page(page);
 		return 0;
 	}
+
+	/*
+	 * If we are under memory pressure we will call this directly from the
+	 * VM, we need to make sure we have the inode referenced for the ordered
+	 * extent.  If not just return like we didn't do anything.
+	 */
+	if (!igrab(inode)) {
+		redirty_page_for_writepage(wbc, page);
+		return AOP_WRITEPAGE_ACTIVATE;
+	}
 	tree = &BTRFS_I(page->mapping->host)->io_tree;
-	return extent_write_full_page(tree, page, btrfs_get_extent, wbc);
+	ret = extent_write_full_page(tree, page, btrfs_get_extent, wbc);
+	btrfs_add_delayed_iput(inode);
+	return ret;
 }
 
 static int btrfs_writepages(struct address_space *mapping,
Signature · 1 line
2.7.2
author
#76 lore raw

PATCH 76/116 Btrfs: send, don't BUG_ON() when an empty symlink is found

In reply to Jiri Slaby

From: Filipe Manana <[email protected]>

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

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

commit a879719b8c90e15c9e7fa7266d5e3c0ca962f9df upstream.

When a symlink is successfully created it always has an inline extent containing the source path. However if an error happens when creating the symlink, we can leave in the subvolume's tree a symlink inode without any such inline extent item - this happens if after btrfs_symlink() calls btrfs_end_transaction() and before it calls the inode eviction handler (through the final iput() call), the transaction gets committed and a crash happens before the eviction handler gets called, or if a snapshot of the subvolume is made before the eviction handler gets called. Sadly we can't just avoid this by making btrfs_symlink() call btrfs_end_transaction() after it calls the eviction handler, because the later can commit the current transaction before it removes any items from the subvolume tree (if it encounters ENOSPC errors while reserving space for removing all the items).

So make send fail more gracefully, with an -EIO error, and print a message to dmesg/syslog informing that there's an empty symlink inode, so that the user can delete the empty symlink or do something else about it.

---
 fs/btrfs/send.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)
fs/btrfs/send.c +15 -1
index 76736b57de5e..82892b18a744 100644
@@ -1335,7 +1335,21 @@ static int read_symlink(struct btrfs_root *root,
 	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
 	if (ret < 0)
 		goto out;
-	BUG_ON(ret);
+	if (ret) {
+		/*
+		 * An empty symlink inode. Can happen in rare error paths when
+		 * creating a symlink (transaction committed before the inode
+		 * eviction handler removed the symlink inode items and a crash
+		 * happened in between or the subvol was snapshoted in between).
+		 * Print an informative message to dmesg/syslog so that the user
+		 * can delete the symlink.
+		 */
+		btrfs_err(root->fs_info,
+			  "Found empty symlink inode %llu at root %llu",
+			  ino, root->root_key.objectid);
+		ret = -EIO;
+		goto out;
+	}
 
 	ei = btrfs_item_ptr(path->nodes[0], path->slots[0],
 			struct btrfs_file_extent_item);
Signature · 1 line
2.7.2
author
#77 lore raw

PATCH 77/116 Btrfs: fix number of transaction units required to create symlink

In reply to Jiri Slaby

From: Filipe Manana <[email protected]>

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

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

commit 9269d12b2d57d9e3d13036bb750762d1110d425c upstream.

We weren't accounting for the insertion of an inline extent item for the symlink inode nor that we need to update the parent inode item (through the call to btrfs_add_nondir()). So fix this by including two more transaction units.

---
 fs/btrfs/inode.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
fs/btrfs/inode.c +3 -1
index c6f91432cc67..89b5868ccfc7 100644
@@ -8417,9 +8417,11 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
 	/*
 	 * 2 items for inode item and ref
 	 * 2 items for dir items
+	 * 1 item for updating parent inode item
+	 * 1 item for the inline extent item
 	 * 1 item for xattr if selinux is on
 	 */
-	trans = btrfs_start_transaction(root, 5);
+	trans = btrfs_start_transaction(root, 7);
 	if (IS_ERR(trans))
 		return PTR_ERR(trans);
 
Signature · 1 line
2.7.2
author
#78 lore raw

PATCH 78/116 s390/dasd: prevent incorrect length error under z/VM after PAV changes

In reply to Jiri Slaby

From: Stefan Haberland <[email protected]>

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

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

commit 020bf042e5b397479c1174081b935d0ff15d1a64 upstream.

The channel checks the specified length and the provided amount of data for CCWs and provides an incorrect length error if the size does not match. Under z/VM with simulation activated the length may get changed. Having the suppress length indication bit set is stated as good CCW coding practice and avoids errors under z/VM.

---
 drivers/s390/block/dasd_alias.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/s390/block/dasd_alias.c +1 -1
index a2597e683e79..d52d7a23b2e7 100644
@@ -722,7 +722,7 @@ static int reset_summary_unit_check(struct alias_lcu *lcu,
 	ASCEBC((char *) &cqr->magic, 4);
 	ccw = cqr->cpaddr;
 	ccw->cmd_code = DASD_ECKD_CCW_RSCK;
-	ccw->flags = 0 ;
+	ccw->flags = CCW_FLAG_SLI;
 	ccw->count = 16;
 	ccw->cda = (__u32)(addr_t) cqr->data;
 	((char *)cqr->data)[0] = reason;
Signature · 1 line
2.7.2
author
#79 lore raw

PATCH 79/116 s390/dasd: fix refcount for PAV reassignment

In reply to Jiri Slaby

From: Stefan Haberland <[email protected]>

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

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

commit 9d862ababb609439c5d6987f6d3ddd09e703aa0b upstream.

Add refcount to the DASD device when a summary unit check worker is scheduled. This prevents that the device is set offline with worker in place.

---
 drivers/s390/block/dasd_alias.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)
drivers/s390/block/dasd_alias.c +16 -5
index d52d7a23b2e7..6a64e86e8ccd 100644
@@ -264,8 +264,10 @@ void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device)
 		spin_unlock_irqrestore(&lcu->lock, flags);
 		cancel_work_sync(&lcu->suc_data.worker);
 		spin_lock_irqsave(&lcu->lock, flags);
-		if (device == lcu->suc_data.device)
+		if (device == lcu->suc_data.device) {
+			dasd_put_device(device);
 			lcu->suc_data.device = NULL;
+		}
 	}
 	was_pending = 0;
 	if (device == lcu->ruac_data.device) {
@@ -273,8 +275,10 @@ void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device)
 		was_pending = 1;
 		cancel_delayed_work_sync(&lcu->ruac_data.dwork);
 		spin_lock_irqsave(&lcu->lock, flags);
-		if (device == lcu->ruac_data.device)
+		if (device == lcu->ruac_data.device) {
+			dasd_put_device(device);
 			lcu->ruac_data.device = NULL;
+		}
 	}
 	private->lcu = NULL;
 	spin_unlock_irqrestore(&lcu->lock, flags);
@@ -549,8 +553,10 @@ static void lcu_update_work(struct work_struct *work)
 	if ((rc && (rc != -EOPNOTSUPP)) || (lcu->flags & NEED_UAC_UPDATE)) {
 		DBF_DEV_EVENT(DBF_WARNING, device, "could not update"
 			    " alias data in lcu (rc = %d), retry later", rc);
-		schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ);
+		if (!schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ))
+			dasd_put_device(device);
 	} else {
+		dasd_put_device(device);
 		lcu->ruac_data.device = NULL;
 		lcu->flags &= ~UPDATE_PENDING;
 	}
@@ -593,8 +599,10 @@ static int _schedule_lcu_update(struct alias_lcu *lcu,
 	 */
 	if (!usedev)
 		return -EINVAL;
+	dasd_get_device(usedev);
 	lcu->ruac_data.device = usedev;
-	schedule_delayed_work(&lcu->ruac_data.dwork, 0);
+	if (!schedule_delayed_work(&lcu->ruac_data.dwork, 0))
+		dasd_put_device(usedev);
 	return 0;
 }
 
@@ -926,6 +934,7 @@ static void summary_unit_check_handling_work(struct work_struct *work)
 	/* 3. read new alias configuration */
 	_schedule_lcu_update(lcu, device);
 	lcu->suc_data.device = NULL;
+	dasd_put_device(device);
 	spin_unlock_irqrestore(&lcu->lock, flags);
 }
 
@@ -985,6 +994,8 @@ void dasd_alias_handle_summary_unit_check(struct dasd_device *device,
 	}
 	lcu->suc_data.reason = reason;
 	lcu->suc_data.device = device;
+	dasd_get_device(device);
 	spin_unlock(&lcu->lock);
-	schedule_work(&lcu->suc_data.worker);
+	if (!schedule_work(&lcu->suc_data.worker))
+		dasd_put_device(device);
 };
Signature · 1 line
2.7.2
author
#80 lore raw

PATCH 80/116 uml: flush stdout before forking

In reply to Jiri Slaby

From: Vegard Nossum <[email protected]>

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

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

commit 0754fb298f2f2719f0393491d010d46cfb25d043 upstream.

I was seeing some really weird behaviour where piping UML's output somewhere would cause output to get duplicated:

  $ ./vmlinux | head -n 40
  Checking that ptrace can change system call numbers...Core dump limits :
          soft - 0
          hard - NONE
  OK
  Checking syscall emulation patch for ptrace...Core dump limits :
          soft - 0
          hard - NONE
  OK
  Checking advanced syscall emulation patch for ptrace...Core dump limits :
          soft - 0
          hard - NONE
  OK
  Core dump limits :
          soft - 0
          hard - NONE

This is because these tests do a fork() which duplicates the non-empty stdout buffer, then glibc flushes the duplicated buffer as each child exits.

A simple workaround is to flush before forking.

---
 arch/um/os-Linux/start_up.c | 2 ++
 1 file changed, 2 insertions(+)
arch/um/os-Linux/start_up.c +2 -0
index 337518c5042a..b412c62486f0 100644
@@ -95,6 +95,8 @@ static int start_ptraced_child(void)
 {
 	int pid, n, status;
 
+	fflush(stdout);
+
 	pid = fork();
 	if (pid == 0)
 		ptrace_child();
Signature · 1 line
2.7.2
author
#81 lore raw

PATCH 81/116 uml: fix hostfs mknod()

In reply to Jiri Slaby

From: Vegard Nossum <[email protected]>

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

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

commit 9f2dfda2f2f1c6181c3732c16b85c59ab2d195e0 upstream.

An inverted return value check in hostfs_mknod() caused the function to return success after handling it as an error (and cleaning up).

It resulted in the following segfault when trying to bind() a named unix socket:

Pid: 198, comm: a.out Not tainted 4.4.0-rc4

  RIP: 0033:[<0000000061077df6>]
  RSP: 00000000daae5d60  EFLAGS: 00010202
  RAX: 0000000000000000 RBX: 000000006092a460 RCX: 00000000dfc54208
  RDX: 0000000061073ef1 RSI: 0000000000000070 RDI: 00000000e027d600
  RBP: 00000000daae5de0 R08: 00000000da980ac0 R09: 0000000000000000
  R10: 0000000000000003 R11: 00007fb1ae08f72a R12: 0000000000000000
  R13: 000000006092a460 R14: 00000000daaa97c0 R15: 00000000daaa9a88
  Kernel panic - not syncing: Kernel mode fault at addr 0x40, ip 0x61077df6
  CPU: 0 PID: 198 Comm: a.out Not tainted 4.4.0-rc4 #1
  Stack:
   e027d620 dfc54208 0000006f da981398
   61bee000 0000c1ed daae5de0 0000006e
   e027d620 dfcd4208 00000005 6092a460
  Call Trace:
   [<60dedc67>] SyS_bind+0xf7/0x110
   [<600587be>] handle_syscall+0x7e/0x80
   [<60066ad7>] userspace+0x3e7/0x4e0
   [<6006321f>] ? save_registers+0x1f/0x40
   [<6006c88e>] ? arch_prctl+0x1be/0x1f0
   [<60054985>] fork_handler+0x85/0x90

Let's also get rid of the "cosmic ray protection" while we're at it.

Fixes e9193059b1b3 "hostfs: fix races in dentry_name() and inode_name()"
Cc Jeff Dike <[email protected]>
Cc Al Viro <[email protected]>
---
 fs/hostfs/hostfs_kern.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
fs/hostfs/hostfs_kern.c +1 -3
index 25437280a207..04091cd05095 100644
@@ -726,15 +726,13 @@ static int hostfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
 
 	init_special_inode(inode, mode, dev);
 	err = do_mknod(name, mode, MAJOR(dev), MINOR(dev));
-	if (!err)
+	if (err)
 		goto out_free;
 
 	err = read_name(inode, name);
 	__putname(name);
 	if (err)
 		goto out_put;
-	if (err)
-		goto out_put;
 
 	d_instantiate(dentry, inode);
 	return 0;
Signature · 1 line
2.7.2
author
#82 lore raw

PATCH 82/116 media: dvb-core: Don't force CAN_INVERSION_AUTO in oneshot mode

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 c9d57de6103e343f2d4e04ea8d9e417e10a24da7 upstream.

When in FE_TUNE_MODE_ONESHOT the frontend must report the actual capabilities so user can take appropriate action.

With frontends that can't do auto inversion this is done by dvb-core automatically so CAN_INVERSION_AUTO is valid.

However, when in FE_TUNE_MODE_ONESHOT this is not true.

So only set FE_CAN_INVERSION_AUTO in modes other than FE_TUNE_MODE_ONESHOT

---
 drivers/media/dvb-core/dvb_frontend.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/media/dvb-core/dvb_frontend.c +3 -3
index 1f925e856974..46a984291b7d 100644
@@ -2195,9 +2195,9 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
 		dev_dbg(fe->dvb->device, "%s: current delivery system on cache: %d, V3 type: %d\n",
 				 __func__, c->delivery_system, fe->ops.info.type);
 
-		/* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't
-		 * do it, it is done for it. */
-		info->caps |= FE_CAN_INVERSION_AUTO;
+		/* Set CAN_INVERSION_AUTO bit on in other than oneshot mode */
+		if (!(fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT))
+			info->caps |= FE_CAN_INVERSION_AUTO;
 		err = 0;
 		break;
 	}
Signature · 1 line
2.7.2
author
#83 lore raw

PATCH 83/116 gspca: ov534/topro: prevent a division by 0

In reply to Jiri Slaby

From: Antonio Ospite <[email protected]>

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

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

commit dcc7fdbec53a960588f2c40232db2c6466c09917 upstream.

v4l2-compliance sends a zeroed struct v4l2_streamparm in v4l2-test-formats.cpp::testParmType(), and this results in a division by 0 in some gspca subdrivers:

divide error: 0000 [#1] SMP

  Modules linked in: gspca_ov534 gspca_main ...
  CPU: 0 PID: 17201 Comm: v4l2-compliance Not tainted 4.3.0-rc2-ao2 #1
  Hardware name: System manufacturer System Product Name/M2N-E SLI, BIOS
    ASUS M2N-E SLI ACPI BIOS Revision 1301 09/16/2010
  task: ffff8800818306c0 ti: ffff880095c4c000 task.ti: ffff880095c4c000
  RIP: 0010:[<ffffffffa079bd62>]  [<ffffffffa079bd62>] sd_set_streamparm+0x12/0x60 [gspca_ov534]
  RSP: 0018:ffff880095c4fce8  EFLAGS: 00010296
  RAX: 0000000000000000 RBX: ffff8800c9522000 RCX: ffffffffa077a140
  RDX: 0000000000000000 RSI: ffff880095e0c100 RDI: ffff8800c9522000
  RBP: ffff880095e0c100 R08: ffffffffa077a100 R09: 00000000000000cc
  R10: ffff880067ec7740 R11: 0000000000000016 R12: ffffffffa07bb400
  R13: 0000000000000000 R14: ffff880081b6a800 R15: 0000000000000000
  FS:  00007fda0de78740(0000) GS:ffff88012fc00000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: 00000000014630f8 CR3: 00000000cf349000 CR4: 00000000000006f0
  Stack:
   ffffffffa07a6431 ffff8800c9522000 ffffffffa077656e 00000000c0cc5616
   ffff8800c9522000 ffffffffa07a5e20 ffff880095e0c100 0000000000000000
   ffff880067ec7740 ffffffffa077a140 ffff880067ec7740 0000000000000016
  Call Trace:
   [<ffffffffa07a6431>] ? v4l_s_parm+0x21/0x50 [videodev]
   [<ffffffffa077656e>] ? vidioc_s_parm+0x4e/0x60 [gspca_main]
   [<ffffffffa07a5e20>] ? __video_do_ioctl+0x280/0x2f0 [videodev]
   [<ffffffffa07a5ba0>] ? video_ioctl2+0x20/0x20 [videodev]
   [<ffffffffa07a59b9>] ? video_usercopy+0x319/0x4e0 [videodev]
   [<ffffffff81182dc1>] ? page_add_new_anon_rmap+0x71/0xa0
   [<ffffffff811afb92>] ? mem_cgroup_commit_charge+0x52/0x90
   [<ffffffff81179b18>] ? handle_mm_fault+0xc18/0x1680
   [<ffffffffa07a15cc>] ? v4l2_ioctl+0xac/0xd0 [videodev]
   [<ffffffff811c846f>] ? do_vfs_ioctl+0x28f/0x480
   [<ffffffff811c86d4>] ? SyS_ioctl+0x74/0x80
   [<ffffffff8154a8b6>] ? entry_SYSCALL_64_fastpath+0x16/0x75
  Code: c7 93 d9 79 a0 5b 5d e9 f1 f3 9a e0 0f 1f 00 66 2e 0f 1f 84 00
    00 00 00 00 66 66 66 66 90 53 31 d2 48 89 fb 48 83 ec 08 8b 46 10 <f7>
    76 0c 80 bf ac 0c 00 00 00 88 87 4e 0e 00 00 74 09 80 bf 4f
  RIP  [<ffffffffa079bd62>] sd_set_streamparm+0x12/0x60 [gspca_ov534]
   RSP <ffff880095c4fce8>
  ---[ end trace 279710c2c6c72080 ]---

Following what the doc says about a zeroed timeperframe (see
http://www.linuxtv.org/downloads/v4l-dvb-apis/vidioc-g-parm.html):

...
To reset manually applications can just set this field to zero.

fix the issue by resetting the frame rate to a default value in case of an unusable timeperframe.

The fix is done in the subdrivers instead of gspca.c because only the subdrivers have notion of a default frame rate to reset the camera to.

---
 drivers/media/usb/gspca/ov534.c | 9 +++++++--
 drivers/media/usb/gspca/topro.c | 6 +++++-
 2 files changed, 12 insertions(+), 3 deletions(-)
drivers/media/usb/gspca/ov534.c +7 -2
index 03a33c46ca2c..9a9ad6ba56dd 100644
@@ -1489,8 +1489,13 @@ static void sd_set_streamparm(struct gspca_dev *gspca_dev,
 	struct v4l2_fract *tpf = &cp->timeperframe;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	/* Set requested framerate */
-	sd->frame_rate = tpf->denominator / tpf->numerator;
+	if (tpf->numerator == 0 || tpf->denominator == 0)
+		/* Set default framerate */
+		sd->frame_rate = 30;
+	else
+		/* Set requested framerate */
+		sd->frame_rate = tpf->denominator / tpf->numerator;
+
 	if (gspca_dev->streaming)
 		set_frame_rate(gspca_dev);
 
drivers/media/usb/gspca/topro.c +5 -1
index 4cb511ccc5f6..22ea6aefd22f 100644
@@ -4791,7 +4791,11 @@ static void sd_set_streamparm(struct gspca_dev *gspca_dev,
 	struct v4l2_fract *tpf = &cp->timeperframe;
 	int fr, i;
 
-	sd->framerate = tpf->denominator / tpf->numerator;
+	if (tpf->numerator == 0 || tpf->denominator == 0)
+		sd->framerate = 30;
+	else
+		sd->framerate = tpf->denominator / tpf->numerator;
+
 	if (gspca_dev->streaming)
 		setframerate(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure));
 
Signature · 1 line
2.7.2
author
#84 lore raw

PATCH 84/116 tda1004x: only update the frontend properties if locked

In reply to Jiri Slaby

From: Mauro Carvalho Chehab <[email protected]>

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

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

commit e8beb02343e7582980c6705816cd957cf4f74c7a upstream.

The tda1004x was updating the properties cache before locking. If the device is not locked, the data at the registers are just random values with no real meaning.

This caused the driver to fail with libdvbv5, as such library calls GET_PROPERTY from time to time, in order to return the DVB stats.

Tested with a saa7134 card 78:

	ASUSTeK P7131 Dual, vendor PCI ID: 1043:4862
---
 drivers/media/dvb-frontends/tda1004x.c | 9 +++++++++
 1 file changed, 9 insertions(+)
drivers/media/dvb-frontends/tda1004x.c +9 -0
index a2631be7ffac..08e0f0dd8728 100644
@@ -903,9 +903,18 @@ static int tda1004x_get_fe(struct dvb_frontend *fe)
 {
 	struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache;
 	struct tda1004x_state* state = fe->demodulator_priv;
+	int status;
 
 	dprintk("%s\n", __func__);
 
+	status = tda1004x_read_byte(state, TDA1004X_STATUS_CD);
+	if (status == -1)
+		return -EIO;
+
+	/* Only update the properties cache if device is locked */
+	if (!(status & 8))
+		return 0;
+
 	// inversion status
 	fe_params->inversion = INVERSION_OFF;
 	if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20)
Signature · 1 line
2.7.2
author
#85 lore raw

PATCH 85/116 dm space map metadata: remove unused variable in brb_pop()

In reply to Jiri Slaby

From: Mike Snitzer <[email protected]>

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

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

commit 512167788a6fe9481a33a3cce5f80b684631a1bb upstream.

Remove the unused struct block_op pointer that was inadvertantly introduced, via cut-and-paste of previous brb_op() code, as part of commit 50dd842ad.

(Cc'ing stable@ because commit 50dd842ad did)

Fixes 50dd842ad ("dm space map metadata: fix ref counting bug when bootstrapping a new space map")
---
 drivers/md/persistent-data/dm-space-map-metadata.c | 3 ---
 1 file changed, 3 deletions(-)
drivers/md/persistent-data/dm-space-map-metadata.c +0 -3
index 722bd48024d6..8a8f06bcde60 100644
@@ -152,12 +152,9 @@ static int brb_peek(struct bop_ring_buffer *brb, struct block_op *result)
 
 static int brb_pop(struct bop_ring_buffer *brb)
 {
-	struct block_op *bop;
-
 	if (brb_empty(brb))
 		return -ENODATA;
 
-	bop = brb->bops + brb->begin;
 	brb->begin = brb_next(brb, brb->begin);
 
 	return 0;
Signature · 1 line
2.7.2
author
#86 lore raw

PATCH 86/116 dm snapshot: fix hung bios when copy error occurs

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 385277bfb57faac44e92497104ba542cdd82d5fe upstream.

When there is an error copying a chunk dm-snapshot can incorrectly hold associated bios indefinitely, resulting in hung IO.

The function copy_callback sets pe->error if there was error copying the chunk, and then calls complete_exception. complete_exception calls pending_complete on error, otherwise it calls commit_exception with commit_callback (and commit_callback calls complete_exception).

The persistent exception store (dm-snap-persistent.c) assumes that calls to prepare_exception and commit_exception are paired. persistent_prepare_exception increases ps->pending_count and persistent_commit_exception decreases it.

If there is a copy error, persistent_prepare_exception is called but persistent_commit_exception is not. This results in the variable ps->pending_count never returning to zero and that causes some pending exceptions (and their associated bios) to be held forever.

Fix this by unconditionally calling commit_exception regardless of whether the copy was successful. A new "valid" parameter is added to commit_exception -- when the copy fails this parameter is set to zero so that the chunk that failed to copy (and all following chunks) is not recorded in the snapshot store. Also, remove commit_callback now that it is merely a wrapper around pending_complete.

---
 drivers/md/dm-exception-store.h |  2 +-
 drivers/md/dm-snap-persistent.c |  5 ++++-
 drivers/md/dm-snap-transient.c  |  4 ++--
 drivers/md/dm-snap.c            | 20 +++++---------------
 4 files changed, 12 insertions(+), 19 deletions(-)
drivers/md/dm-exception-store.h +1 -1
index 0b2536247cf5..84e27708ad97 100644
@@ -70,7 +70,7 @@ struct dm_exception_store_type {
 	 * Update the metadata with this exception.
 	 */
 	void (*commit_exception) (struct dm_exception_store *store,
-				  struct dm_exception *e,
+				  struct dm_exception *e, int valid,
 				  void (*callback) (void *, int success),
 				  void *callback_context);
 
drivers/md/dm-snap-persistent.c +4 -1
index 2d2b1b7588d7..8f6d3ea55401 100644
@@ -646,7 +646,7 @@ static int persistent_prepare_exception(struct dm_exception_store *store,
 }
 
 static void persistent_commit_exception(struct dm_exception_store *store,
-					struct dm_exception *e,
+					struct dm_exception *e, int valid,
 					void (*callback) (void *, int success),
 					void *callback_context)
 {
@@ -655,6 +655,9 @@ static void persistent_commit_exception(struct dm_exception_store *store,
 	struct core_exception ce;
 	struct commit_callback *cb;
 
+	if (!valid)
+		ps->valid = 0;
+
 	ce.old_chunk = e->old_chunk;
 	ce.new_chunk = e->new_chunk;
 	write_exception(ps, ps->current_committed++, &ce);
drivers/md/dm-snap-transient.c +2 -2
index 1ce9a2586e41..31439d53cf7e 100644
@@ -52,12 +52,12 @@ static int transient_prepare_exception(struct dm_exception_store *store,
 }
 
 static void transient_commit_exception(struct dm_exception_store *store,
-				       struct dm_exception *e,
+				       struct dm_exception *e, int valid,
 				       void (*callback) (void *, int success),
 				       void *callback_context)
 {
 	/* Just succeed */
-	callback(callback_context, 1);
+	callback(callback_context, valid);
 }
 
 static void transient_usage(struct dm_exception_store *store,
drivers/md/dm-snap.c +5 -15
index d892a05c84f4..dbd0f00f7395 100644
@@ -1388,8 +1388,9 @@ static void __invalidate_snapshot(struct dm_snapshot *s, int err)
 	dm_table_event(s->ti->table);
 }
 
-static void pending_complete(struct dm_snap_pending_exception *pe, int success)
+static void pending_complete(void *context, int success)
 {
+	struct dm_snap_pending_exception *pe = context;
 	struct dm_exception *e;
 	struct dm_snapshot *s = pe->snap;
 	struct bio *origin_bios = NULL;
@@ -1459,24 +1460,13 @@ out:
 	free_pending_exception(pe);
 }
 
-static void commit_callback(void *context, int success)
-{
-	struct dm_snap_pending_exception *pe = context;
-
-	pending_complete(pe, success);
-}
-
 static void complete_exception(struct dm_snap_pending_exception *pe)
 {
 	struct dm_snapshot *s = pe->snap;
 
-	if (unlikely(pe->copy_error))
-		pending_complete(pe, 0);
-
-	else
-		/* Update the metadata if we are persistent */
-		s->store->type->commit_exception(s->store, &pe->e,
-						 commit_callback, pe);
+	/* Update the metadata if we are persistent */
+	s->store->type->commit_exception(s->store, &pe->e, !pe->copy_error,
+					 pending_complete, pe);
 }
 
 /*
Signature · 1 line
2.7.2
author
#87 lore raw

PATCH 87/116 posix-clock: Fix return code on the poll method's error path

In reply to Jiri Slaby

From: Richard Cochran <[email protected]>

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

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

commit 1b9f23727abb92c5e58f139e7d180befcaa06fe0 upstream.

The posix_clock_poll function is supposed to return a bit mask of POLLxxx values. However, in case the hardware has disappeared (due to hot plugging for example) this code returns -ENODEV in a futile attempt to throw an error at the file descriptor level. The kernel's file_operations interface does not accept such error codes from the poll method. Instead, this function aught to return POLLERR.

The value -ENODEV does, in fact, contain the POLLERR bit (and almost all the other POLLxxx bits as well), but only by chance. This patch fixes code to return a proper bit mask.

Credit goes to Markus Elfring for pointing out the suspicious signed/unsigned mismatch.

---
 kernel/time/posix-clock.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/time/posix-clock.c +2 -2
index ce033c7aa2e8..9cff0ab82b63 100644
@@ -69,10 +69,10 @@ static ssize_t posix_clock_read(struct file *fp, char __user *buf,
 static unsigned int posix_clock_poll(struct file *fp, poll_table *wait)
 {
 	struct posix_clock *clk = get_posix_clock(fp);
-	int result = 0;
+	unsigned int result = 0;
 
 	if (!clk)
-		return -ENODEV;
+		return POLLERR;
 
 	if (clk->ops.poll)
 		result = clk->ops.poll(clk, fp, wait);
Signature · 1 line
2.7.2
author
#88 lore raw

PATCH 88/116 mmc: sdhci: Fix sdhci_runtime_pm_bus_on/off()

In reply to Jiri Slaby

From: Adrian Hunter <[email protected]>

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

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

commit 5c671c410c8704800f4f1673b6f572137e7e6ddd upstream.

sdhci has a legacy facility to prevent runtime suspend if the bus power is on. This is needed in cases where the power to the card is dependent on the bus power. It is controlled by a pair of functions: sdhci_runtime_pm_bus_on() and sdhci_runtime_pm_bus_off(). These functions use a boolean variable 'bus_on' to ensure changes are always paired. There is an additional check for 'runtime_suspended' which is the problem. In fact, its use is ill-conceived as the only requirement for the logic is that 'on' and 'off' are paired, which is actually broken by the check, for example if the bus power is turned on during runtime resume. So remove the check.

---
 drivers/mmc/host/sdhci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mmc/host/sdhci.c +2 -2
index bd2538d84f5d..4aa4d2d18933 100644
@@ -2650,7 +2650,7 @@ static int sdhci_runtime_pm_put(struct sdhci_host *host)
 
 static void sdhci_runtime_pm_bus_on(struct sdhci_host *host)
 {
-	if (host->runtime_suspended || host->bus_on)
+	if (host->bus_on)
 		return;
 	host->bus_on = true;
 	pm_runtime_get_noresume(host->mmc->parent);
@@ -2658,7 +2658,7 @@ static void sdhci_runtime_pm_bus_on(struct sdhci_host *host)
 
 static void sdhci_runtime_pm_bus_off(struct sdhci_host *host)
 {
-	if (host->runtime_suspended || !host->bus_on)
+	if (!host->bus_on)
 		return;
 	host->bus_on = false;
 	pm_runtime_put_noidle(host->mmc->parent);
Signature · 1 line
2.7.2
author
#89 lore raw

PATCH 89/116 mmc: mmci: fix an ages old detection error

In reply to Jiri Slaby

From: Linus Walleij <[email protected]>

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

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

commit 0bcb7efdff63564e80fe84dd36a9fbdfbf6697a4 upstream.

commit 4956e10903fd ("ARM: 6244/1: mmci: add variant data and default MCICLOCK support") added variant data for ARM, U300 and Ux500 variants. The Nomadik NHK8815/8820 variant was erroneously labeled as a U300 variant, and when the proper Nomadik variant was later introduced in commit 34fd421349ff ("ARM: 7378/1: mmci: add support for the Nomadik MMCI variant") this was not fixes. Let's say this fixes the latter commit as there was no proper Nomadik support until then.

Fixes 34fd421349ff ("ARM: 7378/1: mmci: add support for the Nomadik...")
---
 drivers/mmc/host/mmci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mmc/host/mmci.c +1 -1
index c3785edc0e92..3755f4a43622 100644
@@ -1827,7 +1827,7 @@ static struct amba_id mmci_ids[] = {
 	{
 		.id     = 0x00280180,
 		.mask   = 0x00ffffff,
-		.data	= &variant_u300,
+		.data	= &variant_nomadik,
 	},
 	{
 		.id     = 0x00480180,
Signature · 1 line
2.7.2
author
#90 lore raw

PATCH 90/116 EDAC: Robustify workqueues destruction

In reply to Jiri Slaby

From: Borislav Petkov <[email protected]>

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

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

commit fcd5c4dd8201595d4c598c9cca5e54760277d687 upstream.

EDAC workqueue destruction is really fragile. We cancel delayed work but if it is still running and requeues itself, we still go ahead and destroy the workqueue and the queued work explodes when workqueue core attempts to run it.

Make the destruction more robust by switching op_state to offline so that requeuing stops. Cancel any pending work *synchronously* too.

EDAC i7core: Driver loaded.

  general protection fault: 0000 [#1] SMP
  CPU 12
  Modules linked in:
  Supported: Yes
  Pid: 0, comm: kworker/0:1 Tainted: G          IE   3.0.101-0-default #1 HP ProLiant DL380 G7
  RIP: 0010:[<ffffffff8107dcd7>]  [<ffffffff8107dcd7>] __queue_work+0x17/0x3f0
  < ... regs ...>
  Process kworker/0:1 (pid: 0, threadinfo ffff88019def6000, task ffff88019def4600)
  Stack:
   ...
  Call Trace:
   call_timer_fn
   run_timer_softirq
   __do_softirq
   call_softirq
   do_softirq
   irq_exit
   smp_apic_timer_interrupt
   apic_timer_interrupt
   intel_idle
   cpuidle_idle_call
   cpu_idle
  Code: ...
  RIP  __queue_work
   RSP <...>
---
 drivers/edac/edac_device.c |  9 +++------
 drivers/edac/edac_mc.c     | 14 +++-----------
 drivers/edac/edac_pci.c    |  9 ++++-----
 3 files changed, 10 insertions(+), 22 deletions(-)
drivers/edac/edac_device.c +3 -6
index 211021dfec73..46ef63d05584 100644
@@ -435,13 +435,10 @@ void edac_device_workq_setup(struct edac_device_ctl_info *edac_dev,
  */
 void edac_device_workq_teardown(struct edac_device_ctl_info *edac_dev)
 {
-	int status;
+	edac_dev->op_state = OP_OFFLINE;
 
-	status = cancel_delayed_work(&edac_dev->work);
-	if (status == 0) {
-		/* workq instance might be running, wait for it */
-		flush_workqueue(edac_workqueue);
-	}
+	cancel_delayed_work_sync(&edac_dev->work);
+	flush_workqueue(edac_workqueue);
 }
 
 /*
drivers/edac/edac_mc.c +3 -11
index a9d98cdd11f4..f1f298b3ff16 100644
@@ -584,18 +584,10 @@ static void edac_mc_workq_setup(struct mem_ctl_info *mci, unsigned msec,
  */
 static void edac_mc_workq_teardown(struct mem_ctl_info *mci)
 {
-	int status;
-
-	if (mci->op_state != OP_RUNNING_POLL)
-		return;
-
-	status = cancel_delayed_work(&mci->work);
-	if (status == 0) {
-		edac_dbg(0, "not canceled, flush the queue\n");
+	mci->op_state = OP_OFFLINE;
 
-		/* workq instance might be running, wait for it */
-		flush_workqueue(edac_workqueue);
-	}
+	cancel_delayed_work_sync(&mci->work);
+	flush_workqueue(edac_workqueue);
 }
 
 /*
drivers/edac/edac_pci.c +4 -5
index dd370f92ace3..e1e6d3653e03 100644
@@ -274,13 +274,12 @@ static void edac_pci_workq_setup(struct edac_pci_ctl_info *pci,
  */
 static void edac_pci_workq_teardown(struct edac_pci_ctl_info *pci)
 {
-	int status;
-
 	edac_dbg(0, "\n");
 
-	status = cancel_delayed_work(&pci->work);
-	if (status == 0)
-		flush_workqueue(edac_workqueue);
+	pci->op_state = OP_OFFLINE;
+
+	cancel_delayed_work_sync(&pci->work);
+	flush_workqueue(edac_workqueue);
 }
 
 /*
Signature · 1 line
2.7.2
author
#91 lore raw

PATCH 91/116 sparc64: fix incorrect sign extension in sys_sparc64_personality

In reply to Jiri Slaby

From: "Dmitry V. Levin" <[email protected]>

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

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

commit 525fd5a94e1be0776fa652df5c687697db508c91 upstream.

The value returned by sys_personality has type "long int". It is saved to a variable of type "int", which is not a problem yet because the type of task_struct->pesonality is "unsigned int". The problem is the sign extension from "int" to "long int" that happens on return from sys_sparc64_personality.

For example, a userspace call personality((unsigned) -EINVAL) will result to any subsequent personality call, including absolutely harmless read-only personality(0xffffffff) call, failing with errno set to EINVAL.

---
 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 d188c591f2d6..608f9390396e 100644
@@ -411,7 +411,7 @@ out:
 
 SYSCALL_DEFINE1(sparc64_personality, unsigned long, personality)
 {
-	int ret;
+	long ret;
 
 	if (personality(current->personality) == PER_LINUX32 &&
 	    personality(personality) == PER_LINUX)
Signature · 1 line
2.7.2
author
#92 lore raw

PATCH 92/116 drm/vmwgfx: respect 'nomodeset'

In reply to Jiri Slaby

From: Rob Clark <[email protected]>

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

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

commit 96c5d076f0a5e2023ecdb44d8261f87641ee71e0 upstream.

---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 7 +++++++
 1 file changed, 7 insertions(+)
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +7 -0
index 59cd2baf6dc0..5214d65ebe65 100644
@@ -25,6 +25,7 @@
  *
  **************************************************************************/
 #include <linux/module.h>
+#include <linux/console.h>
 
 #include <drm/drmP.h>
 #include "vmwgfx_drv.h"
@@ -1175,6 +1176,12 @@ static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 static int __init vmwgfx_init(void)
 {
 	int ret;
+
+#ifdef CONFIG_VGA_CONSOLE
+	if (vgacon_text_force())
+		return -EINVAL;
+#endif
+
 	ret = drm_pci_init(&driver, &vmw_pci_driver);
 	if (ret)
 		DRM_ERROR("Failed initializing DRM.\n");
Signature · 1 line
2.7.2
author
#93 lore raw

PATCH 93/116 drm/radeon: clean up fujitsu quirks

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 0eb1c3d4084eeb6fb3a703f88d6ce1521f8fcdd1 upstream.

Combine the two quirks.

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

---
 drivers/gpu/drm/radeon/radeon_atombios.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)
drivers/gpu/drm/radeon/radeon_atombios.c +3 -9
index 0f538a442abf..1c71ff82f302 100644
@@ -453,7 +453,9 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,
 	}
 
 	/* Fujitsu D3003-S2 board lists DVI-I as DVI-D and VGA */
-	if (((dev->pdev->device == 0x9802) || (dev->pdev->device == 0x9806)) &&
+	if (((dev->pdev->device == 0x9802) ||
+	     (dev->pdev->device == 0x9805) ||
+	     (dev->pdev->device == 0x9806)) &&
 	    (dev->pdev->subsystem_vendor == 0x1734) &&
 	    (dev->pdev->subsystem_device == 0x11bd)) {
 		if (*connector_type == DRM_MODE_CONNECTOR_VGA) {
@@ -464,14 +466,6 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,
 		}
 	}
 
-	/* Fujitsu D3003-S2 board lists DVI-I as DVI-I and VGA */
-	if ((dev->pdev->device == 0x9805) &&
-	    (dev->pdev->subsystem_vendor == 0x1734) &&
-	    (dev->pdev->subsystem_device == 0x11bd)) {
-		if (*connector_type == DRM_MODE_CONNECTOR_VGA)
-			return false;
-	}
-
 	return true;
 }
 
Signature · 1 line
2.7.2
author
#94 lore raw

PATCH 94/116 drm/radeon: hold reference to fences in radeon_sa_bo_new

In reply to Jiri Slaby

From: Nicolai Hähnle <[email protected]>

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

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

commit f6ff4f67cdf8455d0a4226eeeaf5af17c37d05eb upstream.

An arbitrary amount of time can pass between spin_unlock and radeon_fence_wait_any, so we need to ensure that nobody frees the fences from under us.

Based on the analogous fix for amdgpu.

---
 drivers/gpu/drm/radeon/radeon_sa.c | 5 +++++
 1 file changed, 5 insertions(+)
drivers/gpu/drm/radeon/radeon_sa.c +5 -0
index f0bac68254b7..bb166849aa6e 100644
@@ -349,8 +349,13 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
 			/* see if we can skip over some allocations */
 		} while (radeon_sa_bo_next_hole(sa_manager, fences, tries));
 
+		for (i = 0; i < RADEON_NUM_RINGS; ++i)
+			radeon_fence_ref(fences[i]);
+
 		spin_unlock(&sa_manager->wq.lock);
 		r = radeon_fence_wait_any(rdev, fences, false);
+		for (i = 0; i < RADEON_NUM_RINGS; ++i)
+			radeon_fence_unref(&fences[i]);
 		spin_lock(&sa_manager->wq.lock);
 		/* if we have nothing to wait for block */
 		if (r == -ENOENT && block) {
Signature · 1 line
2.7.2
author
#95 lore raw

PATCH 95/116 drm/i915/dp: fall back to 18 bpp when sink capability is unknown

In reply to Jiri Slaby

From: Jani Nikula <[email protected]>

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

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

commit 5efd407674068dede403551bea3b0b134c32513a upstream.

Per DP spec, the source device should fall back to 18 bpp, VESA range RGB when the sink capability is unknown. Fix the color depth clamping. 18 bpp color depth should ensure full color range in automatic mode.

The clamping has been HDMI specific since its introduction in

commit 996a2239f93b03c5972923f04b097f65565c5bed

Author: Daniel Vetter <[email protected]>
Date:   Fri Apr 19 11:24:34 2013 +0200

drm/i915: Disable high-bpc on pre-1.4 EDID screens

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

(cherry picked from commit 013dd9e038723bbd2aa67be51847384b75be8253)
---
 drivers/gpu/drm/i915/intel_display.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)
drivers/gpu/drm/i915/intel_display.c +15 -5
index 37a9d3c89feb..af46a33d8715 100644
@@ -8200,11 +8200,21 @@ connected_sink_compute_bpp(struct intel_connector * connector,
 		pipe_config->pipe_bpp = connector->base.display_info.bpc*3;
 	}
 
-	/* Clamp bpp to 8 on screens without EDID 1.4 */
-	if (connector->base.display_info.bpc == 0 && bpp > 24) {
-		DRM_DEBUG_KMS("clamping display bpp (was %d) to default limit of 24\n",
-			      bpp);
-		pipe_config->pipe_bpp = 24;
+	/* Clamp bpp to default limit on screens without EDID 1.4 */
+	if (connector->base.display_info.bpc == 0) {
+		int type = connector->base.connector_type;
+		int clamp_bpp = 24;
+
+		/* Fall back to 18 bpp when DP sink capability is unknown. */
+		if (type == DRM_MODE_CONNECTOR_DisplayPort ||
+		    type == DRM_MODE_CONNECTOR_eDP)
+			clamp_bpp = 18;
+
+		if (bpp > clamp_bpp) {
+			DRM_DEBUG_KMS("clamping display bpp (was %d) to default limit of %d\n",
+				      bpp, clamp_bpp);
+			pipe_config->pipe_bpp = clamp_bpp;
+		}
 	}
 }
 
Signature · 1 line
2.7.2
author
#96 lore raw

PATCH 96/116 drm/qxl: use kmalloc_array to alloc reloc_info in qxl_process_single_command

In reply to Jiri Slaby

From: Gerd Hoffmann <[email protected]>

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

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

commit 34855706c30d52b0a744da44348b5d1cc39fbe51 upstream.

This avoids integer overflows on 32bit machines when calculating reloc_info size, as reported by Alan Cox.

---
 drivers/gpu/drm/qxl/qxl_ioctl.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/qxl/qxl_ioctl.c +2 -1
index 729debf83fa3..94008582b5e0 100644
@@ -168,7 +168,8 @@ static int qxl_process_single_command(struct qxl_device *qdev,
 		       cmd->command_size))
 		return -EFAULT;
 
-	reloc_info = kmalloc(sizeof(struct qxl_reloc_info) * cmd->relocs_num, GFP_KERNEL);
+	reloc_info = kmalloc_array(cmd->relocs_num,
+				   sizeof(struct qxl_reloc_info), GFP_KERNEL);
 	if (!reloc_info)
 		return -ENOMEM;
 
Signature · 1 line
2.7.2
author
#97 lore raw

PATCH 97/116 drm/radeon: use post-decrement in error handling

In reply to Jiri Slaby

From: Rasmus Villemoes <[email protected]>

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

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

commit bc3f5d8c4ca01555820617eb3b6c0857e4df710d upstream.

We need to use post-decrement to get the pci_map_page undone also for i==0, and to avoid some very unpleasant behaviour if pci_map_page failed already at i==0.

---
 drivers/gpu/drm/radeon/radeon_ttm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/radeon/radeon_ttm.c +1 -1
index 02d3c3820803..f5931e5f44fd 100644
@@ -621,7 +621,7 @@ static int radeon_ttm_tt_populate(struct ttm_tt *ttm)
 						       0, PAGE_SIZE,
 						       PCI_DMA_BIDIRECTIONAL);
 		if (pci_dma_mapping_error(rdev->pdev, gtt->ttm.dma_address[i])) {
-			while (--i) {
+			while (i--) {
 				pci_unmap_page(rdev->pdev, gtt->ttm.dma_address[i],
 					       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
 				gtt->ttm.dma_address[i] = 0;
Signature · 1 line
2.7.2
author
#98 lore raw

PATCH 98/116 drm/radeon/pm: adjust display configuration after powerstate

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 39d4275058baf53e89203407bf3841ff2c74fa32 upstream.

set_power_state defaults to no displays, so we need to update the display configuration after setting up the powerstate on the first call. In most cases this is not an issue since ends up getting called multiple times at any given modeset and the proper order is achieved in the display changed handling at the top of the function.

---
 drivers/gpu/drm/radeon/radeon_pm.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpu/drm/radeon/radeon_pm.c +3 -2
index 10fc97749a81..0526eca2402c 100644
@@ -896,8 +896,6 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev)
 
 	/* update display watermarks based on new power state */
 	radeon_bandwidth_update(rdev);
-	/* update displays */
-	radeon_dpm_display_configuration_changed(rdev);
 
 	rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs;
 	rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count;
@@ -917,6 +915,9 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev)
 
 	radeon_dpm_post_set_power_state(rdev);
 
+	/* update displays */
+	radeon_dpm_display_configuration_changed(rdev);
+
 	if (rdev->asic->dpm.force_performance_level) {
 		if (rdev->pm.dpm.thermal_active)
 			/* force low perf level for thermal */
Signature · 1 line
2.7.2
author
#99 lore raw

PATCH 99/116 IB/qib: fix mcast detach when qp not attached

In reply to Jiri Slaby

From: Mike Marciniszyn <[email protected]>

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

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

commit 09dc9cd6528f5b52bcbd3292a6312e762c85260f upstream.

The code produces the following trace:

[1750924.419007] general protection fault: 0000 [#3] SMP
[1750924.420364] Modules linked in: nfnetlink autofs4 rpcsec_gss_krb5 nfsv4

dcdbas rfcomm bnep bluetooth nfsd auth_rpcgss nfs_acl dm_multipath nfs lockd scsi_dh sunrpc fscache radeon ttm drm_kms_helper drm serio_raw parport_pc ppdev i2c_algo_bit lpc_ich ipmi_si ib_mthca ib_qib dca lp parport ib_ipoib mac_hid ib_cm i3000_edac ib_sa ib_uverbs edac_core ib_umad ib_mad ib_core ib_addr tg3 ptp dm_mirror dm_region_hash dm_log psmouse pps_core

[1750924.420364] CPU: 1 PID: 8401 Comm: python Tainted: G D
3.13.0-39-generic #66-Ubuntu
[1750924.420364] Hardware name: Dell Computer Corporation PowerEdge
860/0XM089, BIOS A04 07/24/2007
[1750924.420364] task: ffff8800366a9800 ti: ffff88007af1c000 task.ti:
ffff88007af1c000
[1750924.420364] RIP: 0010:[<ffffffffa0131d51>] [<ffffffffa0131d51>]
qib_mcast_qp_free+0x11/0x50 [ib_qib]
[1750924.420364] RSP: 0018:ffff88007af1dd70  EFLAGS: 00010246
[1750924.420364] RAX: 0000000000000001 RBX: ffff88007b822688 RCX:
000000000000000f
[1750924.420364] RDX: ffff88007b822688 RSI: ffff8800366c15a0 RDI:
6764697200000000
[1750924.420364] RBP: ffff88007af1dd78 R08: 0000000000000001 R09:
0000000000000000
[1750924.420364] R10: 0000000000000011 R11: 0000000000000246 R12:
ffff88007baa1d98
[1750924.420364] R13: ffff88003ecab000 R14: ffff88007b822660 R15:
0000000000000000
[1750924.420364] FS:  00007ffff7fd8740(0000) GS:ffff88007fc80000(0000)
knlGS:0000000000000000
[1750924.420364] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[1750924.420364] CR2: 00007ffff597c750 CR3: 000000006860b000 CR4:
00000000000007e0
[1750924.420364] Stack:
[1750924.420364]  ffff88007b822688 ffff88007af1ddf0 ffffffffa0132429
000000007af1de20
[1750924.420364]  ffff88007baa1dc8 ffff88007baa0000 ffff88007af1de70
ffffffffa00cb313
[1750924.420364]  00007fffffffde88 0000000000000000 0000000000000008
ffff88003ecab000
[1750924.420364] Call Trace:
[1750924.420364]  [<ffffffffa0132429>] qib_multicast_detach+0x1e9/0x350
[ib_qib]
[1750924.568035]  [<ffffffffa00cb313>] ? ib_uverbs_modify_qp+0x323/0x3d0
[ib_uverbs]
[1750924.568035]  [<ffffffffa0092d61>] ib_detach_mcast+0x31/0x50 [ib_core]
[1750924.568035]  [<ffffffffa00cc213>] ib_uverbs_detach_mcast+0x93/0x170
[ib_uverbs]
[1750924.568035]  [<ffffffffa00c61f6>] ib_uverbs_write+0xc6/0x2c0 [ib_uverbs]
[1750924.568035]  [<ffffffff81312e68>] ? apparmor_file_permission+0x18/0x20
[1750924.568035]  [<ffffffff812d4cd3>] ? security_file_permission+0x23/0xa0
[1750924.568035]  [<ffffffff811bd214>] vfs_write+0xb4/0x1f0
[1750924.568035]  [<ffffffff811bdc49>] SyS_write+0x49/0xa0
[1750924.568035]  [<ffffffff8172f7ed>] system_call_fastpath+0x1a/0x1f
[1750924.568035] Code: 66 2e 0f 1f 84 00 00 00 00 00 31 c0 5d c3 66 2e 0f 1f
84 00 00 00 00 00 66 90 0f 1f 44 00 00 55 48 89 e5 53 48 89 fb 48 8b 7f 10
<f0> ff 8f 40 01 00 00 74 0e 48 89 df e8 8e f8 06 e1 5b 5d c3 0f
[1750924.568035] RIP  [<ffffffffa0131d51>] qib_mcast_qp_free+0x11/0x50
[ib_qib]
[1750924.568035]  RSP <ffff88007af1dd70>
[1750924.650439] ---[ end trace 73d5d4b3f8ad4851 ]

The fix is to note the qib_mcast_qp that was found. If none is found, then
return EINVAL indicating the error.

---
 drivers/infiniband/hw/qib/qib_verbs_mcast.c | 35 +++++++++++++----------------
 1 file changed, 15 insertions(+), 20 deletions(-)
drivers/infiniband/hw/qib/qib_verbs_mcast.c +15 -20
index dabb697b1c2a..48ba1c3e945a 100644
@@ -286,15 +286,13 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
 	struct qib_ibdev *dev = to_idev(ibqp->device);
 	struct qib_ibport *ibp = to_iport(ibqp->device, qp->port_num);
 	struct qib_mcast *mcast = NULL;
-	struct qib_mcast_qp *p, *tmp;
+	struct qib_mcast_qp *p, *tmp, *delp = NULL;
 	struct rb_node *n;
 	int last = 0;
 	int ret;
 
-	if (ibqp->qp_num <= 1 || qp->state == IB_QPS_RESET) {
-		ret = -EINVAL;
-		goto bail;
-	}
+	if (ibqp->qp_num <= 1 || qp->state == IB_QPS_RESET)
+		return -EINVAL;
 
 	spin_lock_irq(&ibp->lock);
 
@@ -303,8 +301,7 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
 	while (1) {
 		if (n == NULL) {
 			spin_unlock_irq(&ibp->lock);
-			ret = -EINVAL;
-			goto bail;
+			return -EINVAL;
 		}
 
 		mcast = rb_entry(n, struct qib_mcast, rb_node);
@@ -328,6 +325,7 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
 		 */
 		list_del_rcu(&p->list);
 		mcast->n_attached--;
+		delp = p;
 
 		/* If this was the last attached QP, remove the GID too. */
 		if (list_empty(&mcast->qp_list)) {
@@ -338,15 +336,16 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
 	}
 
 	spin_unlock_irq(&ibp->lock);
+	/* QP not attached */
+	if (!delp)
+		return -EINVAL;
+	/*
+	 * Wait for any list walkers to finish before freeing the
+	 * list element.
+	 */
+	wait_event(mcast->wait, atomic_read(&mcast->refcount) <= 1);
+	qib_mcast_qp_free(delp);
 
-	if (p) {
-		/*
-		 * Wait for any list walkers to finish before freeing the
-		 * list element.
-		 */
-		wait_event(mcast->wait, atomic_read(&mcast->refcount) <= 1);
-		qib_mcast_qp_free(p);
-	}
 	if (last) {
 		atomic_dec(&mcast->refcount);
 		wait_event(mcast->wait, !atomic_read(&mcast->refcount));
@@ -355,11 +354,7 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
 		dev->n_mcast_grps_allocated--;
 		spin_unlock_irq(&dev->n_mcast_grps_lock);
 	}
-
-	ret = 0;
-
-bail:
-	return ret;
+	return 0;
 }
 
 int qib_mcast_tree_empty(struct qib_ibport *ibp)
Signature · 1 line
2.7.2
author
#100 lore raw

PATCH 100/116 hwmon: (ads1015) Handle negative conversion values correctly

In reply to Jiri Slaby

From: Peter Rosin <[email protected]>

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

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

commit acc146943957d7418a6846f06e029b2c5e87e0d5 upstream.

Make the divisor signed as DIV_ROUND_CLOSEST is undefined for negative dividends when the divisor is unsigned.

---
 drivers/hwmon/ads1015.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/ads1015.c +1 -1
index 126516414c11..44223f5d92d8 100644
@@ -126,7 +126,7 @@ static int ads1015_reg_to_mv(struct i2c_client *client, unsigned int channel,
 	struct ads1015_data *data = i2c_get_clientdata(client);
 	unsigned int pga = data->channel_data[channel].pga;
 	int fullscale = fullscale_table[pga];
-	const unsigned mask = data->id == ads1115 ? 0x7fff : 0x7ff0;
+	const int mask = data->id == ads1115 ? 0x7fff : 0x7ff0;
 
 	return DIV_ROUND_CLOSEST(reg * fullscale, mask);
 }
Signature · 1 line
2.7.2
author
#101 lore raw

PATCH 101/116 libceph: don't bail early from try_read() when skipping a message

In reply to Jiri Slaby

From: Ilya Dryomov <[email protected]>

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

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

commit e7a88e82fe380459b864e05b372638aeacb0f52d upstream.

The contract between try_read() and try_write() is that when called each processes as much data as possible. When instructed by osd_client to skip a message, try_read() is violating this contract by returning after receiving and discarding a single message instead of checking for more. try_write() then gets a chance to write out more requests, generating more replies/skips for try_read() to handle, forcing the messenger into a starvation loop.

---
 net/ceph/messenger.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/ceph/messenger.c +2 -2
index 057017bd3b42..469f3138d0f6 100644
@@ -2280,7 +2280,7 @@ static int read_partial_message(struct ceph_connection *con)
 		con->in_base_pos = -front_len - middle_len - data_len -
 			sizeof(m->footer);
 		con->in_tag = CEPH_MSGR_TAG_READY;
-		return 0;
+		return 1;
 	} else if ((s64)seq - (s64)con->in_seq > 1) {
 		pr_err("read_partial_message bad seq %lld expected %lld\n",
 		       seq, con->in_seq + 1);
@@ -2313,7 +2313,7 @@ static int read_partial_message(struct ceph_connection *con)
 				sizeof(m->footer);
 			con->in_tag = CEPH_MSGR_TAG_READY;
 			con->in_seq++;
-			return 0;
+			return 1;
 		}
 
 		BUG_ON(!con->in_msg);
Signature · 1 line
2.7.2
author
#102 lore raw

PATCH 102/116 cdc-acm:exclude Samsung phone 04e8:685d

In reply to Jiri Slaby

From: Oliver Neukum <[email protected]>

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

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

commit e912e685f372ab62a2405a1acd923597f524e94a upstream.

This phone needs to be handled by a specialised firmware tool and is reported to crash irrevocably if cdc-acm takes it.

---
 drivers/usb/class/cdc-acm.c | 5 +++++
 1 file changed, 5 insertions(+)
drivers/usb/class/cdc-acm.c +5 -0
index 0822bf1ed2e5..c0ed832d8ad5 100644
@@ -1720,6 +1720,11 @@ static const struct usb_device_id acm_ids[] = {
 	},
 #endif
 
+	/*Samsung phone in firmware update mode */
+	{ USB_DEVICE(0x04e8, 0x685d),
+	.driver_info = IGNORE_DEVICE,
+	},
+
 	/* Exclude Infineon Flash Loader utility */
 	{ USB_DEVICE(0x058b, 0x0041),
 	.driver_info = IGNORE_DEVICE,
Signature · 1 line
2.7.2
author
#103 lore raw

PATCH 103/116 rfkill: fix rfkill_fop_read wait_event usage

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 6736fde9672ff6717ac576e9bba2fd5f3dfec822 upstream.

The code within wait_event_interruptible() is called with !TASK_RUNNING, so mustn't call any functions that can sleep, like mutex_lock().

Since we re-check the list_empty() in a loop after the wait, it's safe to simply use list_empty() without locking.

This bug has existed forever, but was only discovered now because all userspace implementations, including the default 'rfkill' tool, use poll() or select() to get a readable fd before attempting to read.

Fixes c64fb01627e24 ("rfkill: create useful userspace interface")
---
 net/rfkill/core.c | 16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)
net/rfkill/core.c +4 -12
index 5a14f55a1926..918c5ebd239e 100644
@@ -1080,17 +1080,6 @@ static unsigned int rfkill_fop_poll(struct file *file, poll_table *wait)
 	return res;
 }
 
-static bool rfkill_readable(struct rfkill_data *data)
-{
-	bool r;
-
-	mutex_lock(&data->mtx);
-	r = !list_empty(&data->events);
-	mutex_unlock(&data->mtx);
-
-	return r;
-}
-
 static ssize_t rfkill_fop_read(struct file *file, char __user *buf,
 			       size_t count, loff_t *pos)
 {
@@ -1107,8 +1096,11 @@ static ssize_t rfkill_fop_read(struct file *file, char __user *buf,
 			goto out;
 		}
 		mutex_unlock(&data->mtx);
+		/* since we re-check and it just compares pointers,
+		 * using !list_empty() without locking isn't a problem
+		 */
 		ret = wait_event_interruptible(data->read_wait,
-					       rfkill_readable(data));
+					       !list_empty(&data->events));
 		mutex_lock(&data->mtx);
 
 		if (ret)
Signature · 1 line
2.7.2
author
#104 lore raw

PATCH 104/116 libata: fix sff host state machine locking while polling

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 8eee1d3ed5b6fc8e14389567c9a6f53f82bb7224 upstream.

The bulk of ATA host state machine is implemented by ata_sff_hsm_move(). The function is called from either the interrupt handler or, if polling, a work item. Unlike from the interrupt path, the polling path calls the function without holding the host lock and ata_sff_hsm_move() selectively grabs the lock.

This is completely broken. If an IRQ triggers while polling is in progress, the two can easily race and end up accessing the hardware and updating state machine state at the same time. This can put the state machine in an illegal state and lead to a crash like the following.

kernel BUG at drivers/ata/libata-sff.c:1302! invalid opcode: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN

  Modules linked in:
  CPU: 1 PID: 10679 Comm: syz-executor Not tainted 4.5.0-rc1+ #300
  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
  task: ffff88002bd00000 ti: ffff88002e048000 task.ti: ffff88002e048000
  RIP: 0010:[<ffffffff83a83409>]  [<ffffffff83a83409>] ata_sff_hsm_move+0x619/0x1c60
  ...
  Call Trace:
   <IRQ>
   [<ffffffff83a84c31>] __ata_sff_port_intr+0x1e1/0x3a0 drivers/ata/libata-sff.c:1584
   [<ffffffff83a85611>] ata_bmdma_port_intr+0x71/0x400 drivers/ata/libata-sff.c:2877
   [<     inline     >] __ata_sff_interrupt drivers/ata/libata-sff.c:1629
   [<ffffffff83a85bf3>] ata_bmdma_interrupt+0x253/0x580 drivers/ata/libata-sff.c:2902
   [<ffffffff81479f98>] handle_irq_event_percpu+0x108/0x7e0 kernel/irq/handle.c:157
   [<ffffffff8147a717>] handle_irq_event+0xa7/0x140 kernel/irq/handle.c:205
   [<ffffffff81484573>] handle_edge_irq+0x1e3/0x8d0 kernel/irq/chip.c:623
   [<     inline     >] generic_handle_irq_desc include/linux/irqdesc.h:146
   [<ffffffff811a92bc>] handle_irq+0x10c/0x2a0 arch/x86/kernel/irq_64.c:78
   [<ffffffff811a7e4d>] do_IRQ+0x7d/0x1a0 arch/x86/kernel/irq.c:240
   [<ffffffff86653d4c>] common_interrupt+0x8c/0x8c arch/x86/entry/entry_64.S:520
   <EOI>
   [<     inline     >] rcu_lock_acquire include/linux/rcupdate.h:490
   [<     inline     >] rcu_read_lock include/linux/rcupdate.h:874
   [<ffffffff8164b4a1>] filemap_map_pages+0x131/0xba0 mm/filemap.c:2145
   [<     inline     >] do_fault_around mm/memory.c:2943
   [<     inline     >] do_read_fault mm/memory.c:2962
   [<     inline     >] do_fault mm/memory.c:3133
   [<     inline     >] handle_pte_fault mm/memory.c:3308
   [<     inline     >] __handle_mm_fault mm/memory.c:3418
   [<ffffffff816efb16>] handle_mm_fault+0x2516/0x49a0 mm/memory.c:3447
   [<ffffffff8127dc16>] __do_page_fault+0x376/0x960 arch/x86/mm/fault.c:1238
   [<ffffffff8127e358>] trace_do_page_fault+0xe8/0x420 arch/x86/mm/fault.c:1331
   [<ffffffff8126f514>] do_async_page_fault+0x14/0xd0 arch/x86/kernel/kvm.c:264
   [<ffffffff86655578>] async_page_fault+0x28/0x30 arch/x86/entry/entry_64.S:986

Fix it by ensuring that the polling path is holding the host lock before entering ata_sff_hsm_move() so that all hardware accesses and state updates are performed under the host lock.

---
 drivers/ata/libata-sff.c | 32 +++++++++++---------------------
 1 file changed, 11 insertions(+), 21 deletions(-)
drivers/ata/libata-sff.c +11 -21
index 136803c47cdb..96e5ed188636 100644
@@ -997,12 +997,9 @@ static inline int ata_hsm_ok_in_wq(struct ata_port *ap,
 static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
 {
 	struct ata_port *ap = qc->ap;
-	unsigned long flags;
 
 	if (ap->ops->error_handler) {
 		if (in_wq) {
-			spin_lock_irqsave(ap->lock, flags);
-
 			/* EH might have kicked in while host lock is
 			 * released.
 			 */
@@ -1014,8 +1011,6 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
 				} else
 					ata_port_freeze(ap);
 			}
-
-			spin_unlock_irqrestore(ap->lock, flags);
 		} else {
 			if (likely(!(qc->err_mask & AC_ERR_HSM)))
 				ata_qc_complete(qc);
@@ -1024,10 +1019,8 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
 		}
 	} else {
 		if (in_wq) {
-			spin_lock_irqsave(ap->lock, flags);
 			ata_sff_irq_on(ap);
 			ata_qc_complete(qc);
-			spin_unlock_irqrestore(ap->lock, flags);
 		} else
 			ata_qc_complete(qc);
 	}
@@ -1048,9 +1041,10 @@ int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
 {
 	struct ata_link *link = qc->dev->link;
 	struct ata_eh_info *ehi = &link->eh_info;
-	unsigned long flags = 0;
 	int poll_next;
 
+	lockdep_assert_held(ap->lock);
+
 	WARN_ON_ONCE((qc->flags & ATA_QCFLAG_ACTIVE) == 0);
 
 	/* Make sure ata_sff_qc_issue() does not throw things
@@ -1112,14 +1106,6 @@ fsm_start:
 			}
 		}
 
-		/* Send the CDB (atapi) or the first data block (ata pio out).
-		 * During the state transition, interrupt handler shouldn't
-		 * be invoked before the data transfer is complete and
-		 * hsm_task_state is changed. Hence, the following locking.
-		 */
-		if (in_wq)
-			spin_lock_irqsave(ap->lock, flags);
-
 		if (qc->tf.protocol == ATA_PROT_PIO) {
 			/* PIO data out protocol.
 			 * send first data block.
@@ -1135,9 +1121,6 @@ fsm_start:
 			/* send CDB */
 			atapi_send_cdb(ap, qc);
 
-		if (in_wq)
-			spin_unlock_irqrestore(ap->lock, flags);
-
 		/* if polling, ata_sff_pio_task() handles the rest.
 		 * otherwise, interrupt handler takes over from here.
 		 */
@@ -1361,12 +1344,14 @@ static void ata_sff_pio_task(struct work_struct *work)
 	u8 status;
 	int poll_next;
 
+	spin_lock_irq(ap->lock);
+
 	BUG_ON(ap->sff_pio_task_link == NULL);
 	/* qc can be NULL if timeout occurred */
 	qc = ata_qc_from_tag(ap, link->active_tag);
 	if (!qc) {
 		ap->sff_pio_task_link = NULL;
-		return;
+		goto out_unlock;
 	}
 
 fsm_start:
@@ -1381,11 +1366,14 @@ fsm_start:
 	 */
 	status = ata_sff_busy_wait(ap, ATA_BUSY, 5);
 	if (status & ATA_BUSY) {
+		spin_unlock_irq(ap->lock);
 		ata_msleep(ap, 2);
+		spin_lock_irq(ap->lock);
+
 		status = ata_sff_busy_wait(ap, ATA_BUSY, 10);
 		if (status & ATA_BUSY) {
 			ata_sff_queue_pio_task(link, ATA_SHORT_PAUSE);
-			return;
+			goto out_unlock;
 		}
 	}
 
@@ -1402,6 +1390,8 @@ fsm_start:
 	 */
 	if (poll_next)
 		goto fsm_start;
+out_unlock:
+	spin_unlock_irq(ap->lock);
 }
 
 /**
Signature · 1 line
2.7.2
author
#105 lore raw

PATCH 105/116 PCI/AER: Flush workqueue on device remove to avoid use-after-free

In reply to Jiri Slaby

From: Sebastian Andrzej Siewior <[email protected]>

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

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

commit 4ae2182b1e3407de369f8c5d799543b7db74221b upstream.

A Root Port's AER structure (rpc) contains a queue of events. aer_irq() enqueues AER status information and schedules aer_isr() to dequeue and process it. When we remove a device, aer_remove() waits for the queue to be empty, then frees the rpc struct.

But aer_isr() references the rpc struct after dequeueing and possibly emptying the queue, which can cause a use-after-free error as in the following scenario with two threads, aer_isr() on the left and a concurrent aer_remove() on the right:

Thread A Thread B
-------- --------
aer_irq():

    rpc->prod_idx++
                                aer_remove():
                                  wait_event(rpc->prod_idx == rpc->cons_idx)
                                  # now blocked until queue becomes empty
  aer_isr():                      # ...
    rpc->cons_idx++               # unblocked because queue is now empty
    ...                           kfree(rpc)
    mutex_unlock(&rpc->rpc_mutex)

To prevent this problem, use flush_work() to wait until the last scheduled instance of aer_isr() has completed before freeing the rpc struct in aer_remove().

I reproduced this use-after-free by flashing a device FPGA and re-enumerating the bus to find the new device. With SLUB debug, this crashes with 0x6b bytes (POISON_FREE, the use-after-free magic number) in GPR25:

pcieport 0000:00:00.0: AER: Multiple Corrected error received: id=0000

  Unable to handle kernel paging request for data at address 0x27ef9e3e
  Workqueue: events aer_isr
  GPR24: dd6aa000 6b6b6b6b 605f8378 605f8360 d99b12c0 604fc674 606b1704 d99b12c0
  NIP [602f5328] pci_walk_bus+0xd4/0x104
[bhelgaas: changelog, stable tag]
---
 drivers/pci/pcie/aer/aerdrv.c      | 4 +---
 drivers/pci/pcie/aer/aerdrv.h      | 1 -
 drivers/pci/pcie/aer/aerdrv_core.c | 2 --
 3 files changed, 1 insertion(+), 6 deletions(-)
drivers/pci/pcie/aer/aerdrv.c +1 -3
index 0bf82a20a0fb..48d21e0edd56 100644
@@ -262,7 +262,6 @@ static struct aer_rpc *aer_alloc_rpc(struct pcie_device *dev)
 	rpc->rpd = dev;
 	INIT_WORK(&rpc->dpc_handler, aer_isr);
 	mutex_init(&rpc->rpc_mutex);
-	init_waitqueue_head(&rpc->wait_release);
 
 	/* Use PCIe bus function to store rpc into PCIe device */
 	set_service_data(dev, rpc);
@@ -285,8 +284,7 @@ static void aer_remove(struct pcie_device *dev)
 		if (rpc->isr)
 			free_irq(dev->irq, dev);
 
-		wait_event(rpc->wait_release, rpc->prod_idx == rpc->cons_idx);
-
+		flush_work(&rpc->dpc_handler);
 		aer_disable_rootport(rpc);
 		kfree(rpc);
 		set_service_data(dev, NULL);
drivers/pci/pcie/aer/aerdrv.h +0 -1
index 84420b7c9456..945c939a86c5 100644
@@ -72,7 +72,6 @@ struct aer_rpc {
 					 * recovery on the same
 					 * root port hierarchy
 					 */
-	wait_queue_head_t wait_release;
 };
 
 struct aer_broadcast_data {
drivers/pci/pcie/aer/aerdrv_core.c +0 -2
index 85ca36f2136d..28d4c0a0d31a 100644
@@ -785,8 +785,6 @@ void aer_isr(struct work_struct *work)
 	while (get_e_source(rpc, &e_src))
 		aer_isr_one_error(p_device, &e_src);
 	mutex_unlock(&rpc->rpc_mutex);
-
-	wake_up(&rpc->wait_release);
 }
 
 /**
Signature · 1 line
2.7.2
author
#106 lore raw

PATCH 106/116 nfs: fix nfs_size_to_loff_t

In reply to Jiri Slaby

From: Christoph Hellwig <[email protected]>

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

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

commit 50ab8ec74a153eb30db26529088bc57dd700b24c upstream.

See http: //www.infradead.org/rpr.html
X-Evolution-Source: [email protected]
Content-Transfer-Encoding: 8bit
Mime-Version: 1.0

We support OFFSET_MAX just fine, so don't round down below it. Also switch to using min_t to make the helper more readable.

Fixes 433c92379d9c ("NFS: Clean up nfs_size_to_loff_t()")
---
 include/linux/nfs_fs.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
include/linux/nfs_fs.h +1 -3
index f4bf1b593327..1c532adcedc5 100644
@@ -604,9 +604,7 @@ static inline void nfs3_forget_cached_acls(struct inode *inode)
 
 static inline loff_t nfs_size_to_loff_t(__u64 size)
 {
-	if (size > (__u64) OFFSET_MAX - 1)
-		return OFFSET_MAX - 1;
-	return (loff_t) size;
+	return min_t(u64, size, OFFSET_MAX);
 }
 
 static inline ino_t
Signature · 1 line
2.7.2
author
#107 lore raw

PATCH 107/116 NFSv4: Fix a dentry leak on alias use

In reply to Jiri Slaby

From: Benjamin Coddington <[email protected]>

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

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

commit d9dfd8d741683347ee159d25f5b50c346a0df557 upstream.

In the case where d_add_unique() finds an appropriate alias to use it will have already incremented the reference count. An additional dget() to swap the open context's dentry is unnecessary and will leak a reference.

Fixes 275bb307865a3 ("NFSv4: Move dentry instantiation into the NFSv4-...")
---
 fs/nfs/nfs4proc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
fs/nfs/nfs4proc.c +2 -2
index aa62c7308a1b..ae85a71e5045 100644
@@ -2179,9 +2179,9 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
 		dentry = d_add_unique(dentry, igrab(state->inode));
 		if (dentry == NULL) {
 			dentry = opendata->dentry;
-		} else if (dentry != ctx->dentry) {
+		} else {
 			dput(ctx->dentry);
-			ctx->dentry = dget(dentry);
+			ctx->dentry = dentry;
 		}
 		nfs_set_verifier(dentry,
 				nfs_save_change_attribute(opendata->dir->d_inode));
Signature · 1 line
2.7.2
author
#108 lore raw

PATCH 108/116 KVM: async_pf: do not warn on page allocation failures

In reply to Jiri Slaby

From: Christian Borntraeger <[email protected]>

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

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

commit d7444794a02ff655eda87e3cc54e86b940e7736f upstream.

In async_pf we try to allocate with NOWAIT to get an element quickly or fail. This code also handle failures gracefully. Lets silence potential page allocation failures under load.

qemu-system-s39: page allocation failure: order:0,mode:0x2200000 [...]

Call Trace:
([<00000000001146b8>] show_trace+0xf8/0x148)
[<000000000011476a>] show_stack+0x62/0xe8
[<00000000004a36b8>] dump_stack+0x70/0x98
[<0000000000272c3a>] warn_alloc_failed+0xd2/0x148
[<000000000027709e>] __alloc_pages_nodemask+0x94e/0xb38
[<00000000002cd36a>] new_slab+0x382/0x400
[<00000000002cf7ac>] ___slab_alloc.constprop.30+0x2dc/0x378
[<00000000002d03d0>] kmem_cache_alloc+0x160/0x1d0
[<0000000000133db4>] kvm_setup_async_pf+0x6c/0x198
[<000000000013dee8>] kvm_arch_vcpu_ioctl_run+0xd48/0xd58
[<000000000012fcaa>] kvm_vcpu_ioctl+0x372/0x690
[<00000000002f66f6>] do_vfs_ioctl+0x3be/0x510
[<00000000002f68ec>] SyS_ioctl+0xa4/0xb8
[<0000000000781c5e>] system_call+0xd6/0x264

[<000003ffa24fa06a>] 0x3ffa24fa06a

---
 virt/kvm/async_pf.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
virt/kvm/async_pf.c +1 -1
index 8a39dda7a325..0ae1bc4f16fa 100644
@@ -161,7 +161,7 @@ int kvm_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn,
 	 * do alloc nowait since if we are going to sleep anyway we
 	 * may as well sleep faulting in page
 	 */
-	work = kmem_cache_zalloc(async_pf_cache, GFP_NOWAIT);
+	work = kmem_cache_zalloc(async_pf_cache, GFP_NOWAIT | __GFP_NOWARN);
 	if (!work)
 		return 0;
 
Signature · 1 line
2.7.2
author
#109 lore raw

PATCH 109/116 tracing: Fix showing function event in available_events

In reply to Jiri Slaby

From: "Steven Rostedt (Red Hat)" <[email protected]>

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

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

commit d045437a169f899dfb0f6f7ede24cc042543ced9 upstream.

The ftrace:function event is only displayed for parsing the function tracer data. It is not used to enable function tracing, and does not include an "enable" file in its event directory.

Originally, this event was kept separate from other events because it did not have a ->reg parameter. But perf added a "reg" parameter for its use which caused issues, because it made the event available to functions where it was not compatible for.

Commit 9b63776fa3ca9 "tracing: Do not enable function event with enable" added a TRACE_EVENT_FL_IGNORE_ENABLE flag that prevented the function event from being enabled by normal trace events. But this commit missed keeping the function event from being displayed by the "available_events" directory, which is used to show what events can be enabled by set_event.

One documented way to enable all events is to:

cat available_events > set_event

But because the function event is displayed in the available_events, this now causes an INVALID error:

cat: write error: Invalid argument

Fixes 9b63776fa3ca9 "tracing: Do not enable function event with enable"
---
 kernel/trace/trace_events.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/trace/trace_events.c +2 -1
index be15da87b390..9514ee1791a7 100644
@@ -604,7 +604,8 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
 		 * The ftrace subsystem is for showing formats only.
 		 * They can not be enabled or disabled via the event files.
 		 */
-		if (call->class && call->class->reg)
+		if (call->class && call->class->reg &&
+		    !(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE))
 			return file;
 	}
 
Signature · 1 line
2.7.2
author
#110 lore raw

PATCH 110/116 sunrpc/cache: fix off-by-one in qword_get()

In reply to Jiri Slaby

From: Stefan Hajnoczi <[email protected]>

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

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

commit b7052cd7bcf3c1478796e93e3dff2b44c9e82943 upstream.

The qword_get() function NUL-terminates its output buffer. If the input string is in hex format \xXXXX... and the same length as the output buffer, there is an off-by-one:

  int qword_get(char **bpp, char *dest, int bufsize)
  {
      ...
      while (len < bufsize) {
          ...
          *dest++ = (h << 4) | l;
          len++;
      }
      ...
      *dest = '\0';
      return len;
  }

This patch ensures the NUL terminator doesn't fall outside the output buffer.

---
 net/sunrpc/cache.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/sunrpc/cache.c +1 -1
index 8a6e3b0d25d4..f3e2b7d8f325 100644
@@ -1232,7 +1232,7 @@ int qword_get(char **bpp, char *dest, int bufsize)
 	if (bp[0] == '\\' && bp[1] == 'x') {
 		/* HEX STRING */
 		bp += 2;
-		while (len < bufsize) {
+		while (len < bufsize - 1) {
 			int h, l;
 
 			h = hex_to_bin(bp[0]);
Signature · 1 line
2.7.2
author
#111 lore raw

PATCH 111/116 kernel/resource.c: fix muxed resource handling in __request_region()

In reply to Jiri Slaby

From: Simon Guinot <[email protected]>

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

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

commit 59ceeaaf355fa0fb16558ef7c24413c804932ada upstream.

In __request_region, if a conflict with a BUSY and MUXED resource is detected, then the caller goes to sleep and waits for the resource to be released. A pointer on the conflicting resource is kept. At wake-up this pointer is used as a parent to retry to request the region.

A first problem is that this pointer might well be invalid (if for example the conflicting resource have already been freed). Another problem is that the next call to __request_region() fails to detect a remaining conflict. The previously conflicting resource is passed as a parameter and __request_region() will look for a conflict among the children of this resource and not at the resource itself. It is likely to succeed anyway, even if there is still a conflict.

Instead, the parent of the conflicting resource should be passed to __request_region().

As a fix, this patch doesn't update the parent resource pointer in the case we have to wait for a muxed region right after.

---
 kernel/resource.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
kernel/resource.c +3 -2
index 3f285dce9347..449282e48bb1 100644
@@ -961,9 +961,10 @@ struct resource * __request_region(struct resource *parent,
 		if (!conflict)
 			break;
 		if (conflict != parent) {
-			parent = conflict;
-			if (!(conflict->flags & IORESOURCE_BUSY))
+			if (!(conflict->flags & IORESOURCE_BUSY)) {
+				parent = conflict;
 				continue;
+			}
 		}
 		if (conflict->flags & flags & IORESOURCE_MUXED) {
 			add_wait_queue(&muxed_resource_wait, &wait);
Signature · 1 line
2.7.2
author
#112 lore raw

PATCH 112/116 do_last(): don't let a bogus return value from ->open() et.al. to confuse us

In reply to Jiri Slaby

From: Al Viro <[email protected]>

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

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

commit c80567c82ae4814a41287618e315a60ecf513be6 upstream.

... into returning a positive to path_openat(), which would interpret that as "symlink had been encountered" and proceed to corrupt memory, etc. It can only happen due to a bug in some ->open() instance or in some LSM hook, etc., so we report any such event *and* make sure it doesn't trick us into further unpleasantness.

---
 fs/namei.c | 4 ++++
 1 file changed, 4 insertions(+)
fs/namei.c +4 -0
index d1c0b91b4534..b1b1781faca1 100644
@@ -3116,6 +3116,10 @@ opened:
 			goto exit_fput;
 	}
 out:
+	if (unlikely(error > 0)) {
+		WARN_ON(1);
+		error = -EINVAL;
+	}
 	if (got_write)
 		mnt_drop_write(nd->path.mnt);
 	path_put(&save_parent);
Signature · 1 line
2.7.2
author
#113 lore raw

PATCH 113/116 xen/pcifront: Fix mysterious crashes when NUMA locality information was extracted.

In reply to Jiri Slaby

From: Konrad Rzeszutek Wilk <[email protected]>

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

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

commit 4d8c8bd6f2062c9988817183a91fe2e623c8aa5e upstream.

Occasionaly PV guests would crash with:

pciback 0000:00:00.1: Xen PCI mapped GSI0 to IRQ16

BUG: unable to handle kernel paging request at 0000000d1a8c0be0
.. snip..
  <ffffffff8139ce1b>] find_next_bit+0xb/0x10
  [<ffffffff81387f22>] cpumask_next_and+0x22/0x40
  [<ffffffff813c1ef8>] pci_device_probe+0xb8/0x120
  [<ffffffff81529097>] ? driver_sysfs_add+0x77/0xa0
  [<ffffffff815293e4>] driver_probe_device+0x1a4/0x2d0
  [<ffffffff813c1ddd>] ? pci_match_device+0xdd/0x110
  [<ffffffff81529657>] __device_attach_driver+0xa7/0xb0
  [<ffffffff815295b0>] ? __driver_attach+0xa0/0xa0
  [<ffffffff81527622>] bus_for_each_drv+0x62/0x90
  [<ffffffff8152978d>] __device_attach+0xbd/0x110
  [<ffffffff815297fb>] device_attach+0xb/0x10
  [<ffffffff813b75ac>] pci_bus_add_device+0x3c/0x70
  [<ffffffff813b7618>] pci_bus_add_devices+0x38/0x80
  [<ffffffff813dc34e>] pcifront_scan_root+0x13e/0x1a0
  [<ffffffff817a0692>] pcifront_backend_changed+0x262/0x60b
  [<ffffffff814644c6>] ? xenbus_gather+0xd6/0x160
  [<ffffffff8120900f>] ? put_object+0x2f/0x50
  [<ffffffff81465c1d>] xenbus_otherend_changed+0x9d/0xa0
  [<ffffffff814678ee>] backend_changed+0xe/0x10
  [<ffffffff81463a28>] xenwatch_thread+0xc8/0x190
  [<ffffffff810f22f0>] ? woken_wake_function+0x10/0x10

which was the result of two things:

When we call pci_scan_root_bus we would pass in 'sd' (sysdata) pointer which was an 'pcifront_sd' structure. However in the pci_device_add it expects that the 'sd' is 'struct sysdata' and sets the dev->node to what is in sd->node (offset 4):

set_dev_node(&dev->dev, pcibus_to_node(bus));

__pcibus_to_node(const struct pci_bus *bus)

{
        const struct pci_sysdata *sd = bus->sysdata;

        return sd->node;
}

However our structure was pcifront_sd which had nothing at that offset:

struct pcifront_sd {
int domain; /* 0 4 */
/* XXX 4 bytes hole, try to pack */
struct pcifront_device * pdev; /* 8 8 */
}

That is an hole - filled with garbage as we used kmalloc instead of kzalloc (the second problem).

This patch fixes the issue by:
1) Use kzalloc to initialize to a well known state.
2) Put 'struct pci_sysdata' at the start of 'pcifront_sd'. That way access to the 'node' will access the right offset.

---
 drivers/pci/xen-pcifront.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/pci/xen-pcifront.c +6 -4
index eae7cd9fde7b..facd18c2ed46 100644
@@ -52,7 +52,7 @@ struct pcifront_device {
 };
 
 struct pcifront_sd {
-	int domain;
+	struct pci_sysdata sd;
 	struct pcifront_device *pdev;
 };
 
@@ -66,7 +66,9 @@ static inline void pcifront_init_sd(struct pcifront_sd *sd,
 				    unsigned int domain, unsigned int bus,
 				    struct pcifront_device *pdev)
 {
-	sd->domain = domain;
+	/* Because we do not expose that information via XenBus. */
+	sd->sd.node = first_online_node;
+	sd->sd.domain = domain;
 	sd->pdev = pdev;
 }
 
@@ -464,8 +466,8 @@ static int pcifront_scan_root(struct pcifront_device *pdev,
 	dev_info(&pdev->xdev->dev, "Creating PCI Frontend Bus %04x:%02x\n",
 		 domain, bus);
 
-	bus_entry = kmalloc(sizeof(*bus_entry), GFP_KERNEL);
-	sd = kmalloc(sizeof(*sd), GFP_KERNEL);
+	bus_entry = kzalloc(sizeof(*bus_entry), GFP_KERNEL);
+	sd = kzalloc(sizeof(*sd), GFP_KERNEL);
 	if (!bus_entry || !sd) {
 		err = -ENOMEM;
 		goto err_out;
Signature · 1 line
2.7.2
author
#114 lore raw

PATCH 114/116 locks: fix unlock when fcntl_setlk races with a close

In reply to Jiri Slaby

From: Jeff Layton <[email protected]>

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

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

commit 7f3697e24dc3820b10f445a4a7d914fc356012d1 upstream.

Dmitry reported that he was able to reproduce the WARN_ON_ONCE that fires in locks_free_lock_context when the flc_posix list isn't empty.

The problem turns out to be that we're basically rebuilding the file_lock from scratch in fcntl_setlk when we discover that the setlk has raced with a close. If the l_whence field is SEEK_CUR or SEEK_END, then we may end up with fl_start and fl_end values that differ from when the lock was initially set, if the file position or length of the file has changed in the interim.

Fix this by just reusing the same lock request structure, and simply override fl_type value with F_UNLCK as appropriate. That ensures that we really are unlocking the lock that was initially set.

While we're there, make sure that we do pop a WARN_ON_ONCE if the removal ever fails. Also return -EBADF in this event, since that's what we would have returned if the close had happened earlier.

Cc Alexander Viro <[email protected]>
Fixes c293621bbf67 (stale POSIX lock handling)
---
 fs/locks.c | 51 ++++++++++++++++++++++++++++++---------------------
 1 file changed, 30 insertions(+), 21 deletions(-)
fs/locks.c +30 -21
index 0d2b5febc627..c8779651ccc7 100644
@@ -1971,7 +1971,6 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
 		goto out;
 	}
 
-again:
 	error = flock_to_posix_lock(filp, file_lock, &flock);
 	if (error)
 		goto out;
@@ -2002,19 +2001,22 @@ again:
 	 * Attempt to detect a close/fcntl race and recover by
 	 * releasing the lock that was just acquired.
 	 */
-	/*
-	 * we need that spin_lock here - it prevents reordering between
-	 * update of inode->i_flock and check for it done in close().
-	 * rcu_read_lock() wouldn't do.
-	 */
-	spin_lock(&current->files->file_lock);
-	f = fcheck(fd);
-	spin_unlock(&current->files->file_lock);
-	if (!error && f != filp && flock.l_type != F_UNLCK) {
-		flock.l_type = F_UNLCK;
-		goto again;
+	if (!error && file_lock->fl_type != F_UNLCK) {
+		/*
+		 * We need that spin_lock here - it prevents reordering between
+		 * update of inode->i_flock and check for it done in
+		 * close(). rcu_read_lock() wouldn't do.
+		 */
+		spin_lock(&current->files->file_lock);
+		f = fcheck(fd);
+		spin_unlock(&current->files->file_lock);
+		if (f != filp) {
+			file_lock->fl_type = F_UNLCK;
+			error = do_lock_file_wait(filp, cmd, file_lock);
+			WARN_ON_ONCE(error);
+			error = -EBADF;
+		}
 	}
-
 out:
 	locks_free_lock(file_lock);
 	return error;
@@ -2089,7 +2091,6 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
 		goto out;
 	}
 
-again:
 	error = flock64_to_posix_lock(filp, file_lock, &flock);
 	if (error)
 		goto out;
@@ -2120,14 +2121,22 @@ again:
 	 * Attempt to detect a close/fcntl race and recover by
 	 * releasing the lock that was just acquired.
 	 */
-	spin_lock(&current->files->file_lock);
-	f = fcheck(fd);
-	spin_unlock(&current->files->file_lock);
-	if (!error && f != filp && flock.l_type != F_UNLCK) {
-		flock.l_type = F_UNLCK;
-		goto again;
+	if (!error && file_lock->fl_type != F_UNLCK) {
+		/*
+		 * We need that spin_lock here - it prevents reordering between
+		 * update of inode->i_flock and check for it done in
+		 * close(). rcu_read_lock() wouldn't do.
+		 */
+		spin_lock(&current->files->file_lock);
+		f = fcheck(fd);
+		spin_unlock(&current->files->file_lock);
+		if (f != filp) {
+			file_lock->fl_type = F_UNLCK;
+			error = do_lock_file_wait(filp, cmd, file_lock);
+			WARN_ON_ONCE(error);
+			error = -EBADF;
+		}
 	}
-
 out:
 	locks_free_lock(file_lock);
 	return error;
Signature · 1 line
2.7.2
author
#115 lore raw

PATCH 115/116 EDAC, mc_sysfs: Fix freeing bus' name

In reply to Jiri Slaby

From: Borislav Petkov <[email protected]>

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

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

commit 12e26969b32c79018165d52caff3762135614aa1 upstream.

I get the splat below when modprobing/rmmoding EDAC drivers. It happens because bus->name is invalid after bus_unregister() has run. The Code: section below corresponds to:

.loc 1 1108 0
movq 672(%rbx), %rax # mci_1(D)->bus, mci_1(D)->bus
.loc 1 1109 0
popq %rbx #

.loc 1 1108 0
movq (%rax), %rdi # _7->name,
jmp kfree #

and %rax has some funky stuff 2030203020312030 which looks a lot like something walked over it.

Fix that by saving the name ptr before doing stuff to string it points to.

  general protection fault: 0000 [#1] SMP
  Modules linked in: ...
  CPU: 4 PID: 10318 Comm: modprobe Tainted: G          I EN  3.12.51-11-default+ #48
  Hardware name: HP ProLiant DL380 G7, BIOS P67 05/05/2011
  task: ffff880311320280 ti: ffff88030da3e000 task.ti: ffff88030da3e000
  RIP: 0010:[<ffffffffa019da92>]  [<ffffffffa019da92>] edac_unregister_sysfs+0x22/0x30 [edac_core]
  RSP: 0018:ffff88030da3fe28  EFLAGS: 00010292
  RAX: 2030203020312030 RBX: ffff880311b4e000 RCX: 000000000000095c
  RDX: 0000000000000001 RSI: ffff880327bb9600 RDI: 0000000000000286
  RBP: ffff880311b4e750 R08: 0000000000000000 R09: ffffffff81296110
  R10: 0000000000000400 R11: 0000000000000000 R12: ffff88030ba1ac68
  R13: 0000000000000001 R14: 00000000011b02f0 R15: 0000000000000000
  FS:  00007fc9bf8f5700(0000) GS:ffff8801a7c40000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
  CR2: 0000000000403c90 CR3: 000000019ebdf000 CR4: 00000000000007e0
  Stack:
  Call Trace:
    i7core_unregister_mci.isra.9
    i7core_remove
    pci_device_remove
    __device_release_driver
    driver_detach
    bus_remove_driver
    pci_unregister_driver
    i7core_exit
    SyS_delete_module
    system_call_fastpath
    0x7fc9bf426536
  Code: 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 53 48 89 fb e8 52 2a 1f e1 48 8b bb a0 02 00 00 e8 46 59 1f e1 48 8b 83 a0 02 00 00 5b <48> 8b 38 e9 26 9a fe e0 66 0f 1f 44 00 00 66 66 66 66 90 48 8b
  RIP  [<ffffffffa019da92>] edac_unregister_sysfs+0x22/0x30 [edac_core]
   RSP <ffff88030da3fe28>
Cc Mauro Carvalho Chehab <[email protected]>
Fixes 7a623c039075 ("edac: rewrite the sysfs code to use struct device")
---
 drivers/edac/edac_mc_sysfs.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)
drivers/edac/edac_mc_sysfs.c +13 -5
index 66f2ccfa5665..e5fde4382552 100644
@@ -973,21 +973,26 @@ nomem:
  */
 int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
 {
+	char *name;
 	int i, err;
 
 	/*
 	 * The memory controller needs its own bus, in order to avoid
 	 * namespace conflicts at /sys/bus/edac.
 	 */
-	mci->bus->name = kasprintf(GFP_KERNEL, "mc%d", mci->mc_idx);
-	if (!mci->bus->name)
+	name = kasprintf(GFP_KERNEL, "mc%d", mci->mc_idx);
+	if (!name)
 		return -ENOMEM;
 
+	mci->bus->name = name;
+
 	edac_dbg(0, "creating bus %s\n", mci->bus->name);
 
 	err = bus_register(mci->bus);
-	if (err < 0)
+	if (err < 0) {
+		kfree(name);
 		return err;
+	}
 
 	/* get the /sys/devices/system/edac subsys reference */
 	mci->dev.type = &mci_attr_type;
@@ -1071,7 +1076,8 @@ fail:
 fail2:
 	device_unregister(&mci->dev);
 	bus_unregister(mci->bus);
-	kfree(mci->bus->name);
+	kfree(name);
+
 	return err;
 }
 
@@ -1102,10 +1108,12 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
 
 void edac_unregister_sysfs(struct mem_ctl_info *mci)
 {
+	const char *name = mci->bus->name;
+
 	edac_dbg(1, "Unregistering device %s\n", dev_name(&mci->dev));
 	device_unregister(&mci->dev);
 	bus_unregister(mci->bus);
-	kfree(mci->bus->name);
+	kfree(name);
 }
 
 static void mc_attr_release(struct device *dev)
Signature · 1 line
2.7.2
author
#116 lore raw

PATCH 116/116 bio: return EINTR if copying to user space got interrupted

In reply to Jiri Slaby

From: Hannes Reinecke <[email protected]>

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

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

commit 2d99b55d378c996b9692a0c93dd25f4ed5d58934 upstream.

Commit 35dc248383bbab0a7203fca4d722875bc81ef091 introduced a check for current->mm to see if we have a user space context and only copies data if we do. Now if an IO gets interrupted by a signal data isn't copied into user space any more (as we don't have a user space context) but user space isn't notified about it.

This patch modifies the behaviour to return -EINTR from bio_uncopy_user() to notify userland that a signal has interrupted the syscall, otherwise it could lead to a situation where the caller may get a buffer with no data returned.

This can be reproduced by issuing SG_IO ioctl()s in one thread while constantly sending signals to it.

[js] backport to 3.12

Fixes 35dc248 [SCSI] sg: Fix user memory corruption when SG_IO is interrupted by a signal
---
 fs/bio.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)
fs/bio.c +8 -4
index e7fb3f82f5f5..6405b44000cb 100644
@@ -1051,15 +1051,19 @@ int bio_uncopy_user(struct bio *bio)
 	if (!bio_flagged(bio, BIO_NULL_MAPPED)) {
 		/*
 		 * if we're in a workqueue, the request is orphaned, so
-		 * don't copy into a random user address space, just free.
+		 * don't copy into a random user address space, just free
+		 * and return -EINTR so user space doesn't expect any data.
 		 */
 		if (current->mm)
 			ret = __bio_copy_iov(bio, bmd->iovecs, bmd->sgvecs,
 					     bmd->nr_sgvecs, bio_data_dir(bio) == READ,
 					     0, bmd->is_our_pages);
-		else if (bmd->is_our_pages)
-			bio_for_each_segment_all(bvec, bio, i)
-				__free_page(bvec->bv_page);
+		else {
+			ret = -EINTR;
+			if (bmd->is_our_pages)
+				bio_for_each_segment_all(bvec, bio, i)
+					__free_page(bvec->bv_page);
+		}
 	}
 	bio_free_map_data(bmd);
 	bio_put(bio);
Signature · 1 line
2.7.2
#117 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.56 release. There are 116 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 Tue Mar 8 10:01:48 CET 2016. Anything received after that time might be too late.

Build results:

	total: 124 pass: 124 fail: 0
Qemu test results:
	total: 79 pass: 79 fail: 0

Details are available at http://kerneltests.org/builders.

Thanks,
Guenter

author
#118 lore raw
Quoted 14 lines · Guenter Roeck
Quoted 8 lines · Jiri Slaby

This is the start of the stable review cycle for the 3.12.56 release. There are 116 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 Tue Mar 8 10:01:48 CET 2016. Anything received after that time might be too late.

Build results:

    total: 124 pass: 124 fail: 0
Qemu test results:
    total: 79 pass: 79 fail: 0
Quoted 1 line · Shuah Khan

Compiled and booted on my test system. No dmesg regressions.

Thank you both!

Signature · 2 lines
js
suse labs
#119 lore raw
In reply to Jiri Slaby
Quoted 5 lines · Jiri Slaby

This is the start of the stable review cycle for the 3.12.56 release. There are 116 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.

Quoted 7 lines

Responses should be made by Tue Mar 8 10:01:48 CET 2016. 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.56-rc1.xz

and the diffstat can be found below.

Compiled and booted on my test system. No dmesg regressions.

thanks,
-- Shuah

Signature · 5 lines
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
[email protected] | (970) 217-8978