Skip to contentSkip to conversation

3.12.34-stable review

PATCH In review Jiri Slaby 3 participants 105 messages Dec 3, 2014 – Dec 5, 2014 Stable branch

lore
Share & tools
lore

Jiri Slaby

author
#0 lore raw

cover 3.12.34-stable review

This is the start of the stable review cycle for the 3.12.34 release. There are 101 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 Fri Dec 5 12:25:22 CET 2014. 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.34-rc1.xz

and the diffstat can be found below.

thanks,
js

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

Al Viro (1):
fix O_SYNC|O_APPEND syncing the wrong range on write()

Alex Deucher (2):
drm/radeon: make sure mode init is complete in bandwidth_update drm/radeon: add missing crtc unlock when setting up the MC

Alexey Khoroshilov (1):
ieee802154: fix error handling in ieee802154fake_probe()

Allen Pais (2):
sunvdc: add cdrom and v1.1 protocol support
sunvdc: compute vdisk geometry from capacity

Andreas Larsson (1):
sparc32: Implement xchg and atomic_xchg using ATOMIC_HASH locks

Andreas Rohner (1):
nilfs2: add missing blkdev_issue_flush() to nilfs_sync_fs()

Andrey Vagin (1):
ipc: always handle a new value of auto_msgmni

Andy Lutomirski (1):
x86, x32, audit: Fix x32's AUDIT_ARCH wrt audit

Arnd Bergmann (3):
pcmcia: sa1100: H3100 and H3600 share a driver
pcmcia: pxa2xx: fix logic for lubbock
pcmcia: journada720: use sa1100 pin interfaces correctly

Ben Dooks (1):
ARM: probes: fix instruction fetch order with <asm/opcodes.h>

Bjorn Helgaas (3):
vmcore: Remove "weak" from function declarations
kgdb: Remove "weak" from kgdb_arch_pc() declaration
clocksource: Remove "weak" from clocksource_default_clock()
declaration

Christoph Hellwig (1):
scsi: only re-lock door after EH on devices that were reset

Cristian Stoica (1):
crypto: caam - remove duplicated sg copy functions

Dan Carpenter (2):
[media] usbvision-video: two use after frees drivers/vlynq/vlynq.c: fix another resource size off by 1 error

Daniel Borkmann (5):
net: sctp: fix NULL pointer dereference in af->from_addr_param on
malformed packet
net: sctp: fix memory leak in auth key management
net: sctp: fix remote memory pressure from excessive queueing
net: sctp: fix panic on duplicate ASCONF chunks
net: sctp: fix skb_over_panic when receiving malformed ASCONF chunks

David S. Miller (3):
sparc64: Fix crashes in schizo_pcierr_intr_other().
sparc64: Do irq_{enter,exit}() around generic_smp_call_function*().
sparc64: Fix constraints on swab helpers.

Dmitry Eremin-Solenikov (1):
Input: wm97xx - adapt parameters to tosa touchscreen.

Dmitry Torokhov (1):
Input: evdev - fix EVIOCG{type} ioctl

Dwight Engen (3):
sunvdc: limit each sg segment to a page
vio: fix reuse of vio_dring slot
sunvdc: don't call VD_OP_GET_VTOC

Emmanuel Grumbach (1):
iwlwifi: configure the LTR

Ezequiel Garcia (1):
parport: Add support for the WCH353 1S/1P multi-IO card

Fabian Frederick (1):
fs/jfs/jfs_inode.c: atomically set inode->i_flags

Florian Westphal (2):
netfilter: nf_log: account for size of NLMSG_DONE attribute
netfilter: nfnetlink_log: fix maximum packet length logged to
userspace

Greg Kurz (1):
hwrng: pseries - port to new read API and fix stack corruption

Heinz Mauelshagen (1):
dm raid: ensure superblock's size matches device's logical block size

Helge Deller (1):
parisc: Use compat layer for msgctl, shmat, shmctl and semtimedop
syscalls

Herbert Xu (2):
tun: Fix csum_start with VLAN acceleration
macvtap: Fix csum_start when VLAN tags are present

Houcheng Lin (1):
netfilter: nf_log: release skbuff on nlmsg put failure

Ilya Dryomov (1):
libceph: do not crash on large auth tickets

James Ralston (1):
ahci: Add Device IDs for Intel Sunrise Point PCH

Jammy Zhou (1):
drm/radeon: set correct CE ram size for CIK

Jan Kara (2):
block: Fix computation of merged request priority
nfs: Fix use of uninitialized variable in nfs_getattr()

Jiri Bohac (1):
ipx: fix locking regression in ipx_sendmsg and ipx_recvmsg

Joe Schultz (2):
vme_tsi148: Fix PCI address mapping assumption
vme_tsi148: Fix typo in tsi148_slave_get()

Joe Thornber (2):
dm thin: grab a virtual cell before looking up the mapping dm btree: fix a recursion depth bug in btree walking code

Johan Hovold (1):
pcmcia: at91_cf: fix deferred probe from __init

Johannes Berg (2):
mac80211: properly flush delayed scan work on interface removal
mac80211: fix use-after-free in defragmentation

Junjie Mao (1):
mac80211_hwsim: release driver when ieee80211_register_hw fails

Kyle McMartin (1):
arm64: __clear_user: handle exceptions on strb

Luciano Coelho (1):
mac80211: schedule the actual switch of the station before CSA count 0

Marcelo Leitner (1):
vxlan: Do not reuse sockets for a different address family

Martin Hauke (1):
qmi_wwan: Add support for HP lt4112 LTE/HSPA+ Gobi 4G Modem

Martyn Welch (1):
VME: Stop using memcpy_[to|from]io() due to unwanted behaviour

Mathias Krause (1):
pptp: fix stack info leak in pptp_getname()

Max Filippov (1):
xtensa: re-wire umount syscall to sys_oldumount

Michael Ellerman (1):
hwrng: pseries - Return errors to upper levels in pseries-rng.c

Micky Ching (1):
drivers/memstick/host/rtsx_pci_ms.c: add cancel_work when remove
driver

Miklos Szeredi (1):
audit: keep inode pinned

Mikulas Patocka (1):
dm bufio: change __GFP_IO to __GFP_FS in shrinker callbacks

Nadav Amit (1):
KVM: x86: Don't report guest userspace emulation error to userspace

Nathan Lynch (1):
ARM: 8198/1: make kuser helpers depend on MMU

Pablo Neira (1):
netfilter: xt_bpf: add mising opaque struct sk_filter definition

Pali Rohár (3):
Input: alps - ignore potential bare packets when device is out of sync
Input: alps - allow up to 2 invalid packets without resetting device
Input: alps - ignore bad data on Dell Latitudes E6440 and E7440

Panu Matilainen (1):
ipv4: Fix incorrect error code when adding an unreachable route

Paolo Bonzini (1):
x86: kvm: use alternatives for VMCALL vs. VMMCALL if kernel text is
read-only

Paul E. McKenney (1):
rcu: Make callers awaken grace-period kthread

Peng Tao (1):
nfs: fix pnfs direct write memory leak

Pranith Kumar (1):
rcu: Use rcu_gp_kthread_wake() to wake up grace period kthreads

Qi Yong (1):
minix zmap block counts calculation fix

Sergei Antonov (1):
hfsplus: emit proper file type from readdir

Sougata Santra (1):
fs/hfsplus/extents.c: fix concurrent acess of alloc_blocks

Stefan Richter (1):
firewire: cdev: prevent kernel stack leaking into ioctl arguments

Steffen Klassert (3):
ip6_tunnel: Use ip6_tnl_dev_init as the ndo_init function.
sit: Use ipip6_tunnel_init as the ndo_init function.
gre6: Move the setting of dev->iflink into the ndo_init functions.

Takashi Iwai (2):
ALSA: usb-audio: Fix memory leak in FTU quirk
pvpanic: Set high notifier priority

Tejun Heo (1):
ahci: disable MSI instead of NCQ on Samsung pci-e SSDs on macbooks

Theodore Ts'o (1):
ext4: atomically set inode->i_flags in ext4_set_inode_flags()

Tobias Klauser (1):
Input: altera_ps2 - write to correct register when disabling
interrupts

Trond Myklebust (4):
NFSv4: Ensure that we remove NFSv4.0 delegations when state has
expired
NFS: Don't try to reclaim delegation open state if recovery failed
NFSv4: Fix races between nfs_remove_bad_delegation() and delegation
return
NFSv4.1: nfs41_clear_delegation_stateid shouldn't trust
NFS_DELEGATED_STATE

Vincent BENAYOUN (1):
inetdevice: fixed signed integer overflow

Vyacheslav Dubeyko (1):
hfsplus: fix remount issue

Weijie Yang (1):
zram: avoid kunmap_atomic() of a NULL pointer

Will Deacon (1):
ARM: 8191/1: decompressor: ensure I-side picks up relocated code

 arch/arm/boot/compressed/head.S                 |  20 ++-
 arch/arm/kernel/kprobes-common.c                |  19 +--
 arch/arm/kernel/kprobes-thumb.c                 |  21 +--
 arch/arm/kernel/kprobes.c                       |   9 +-
 arch/arm/mm/Kconfig                             |   1 +
 arch/arm64/lib/clear_user.S                     |   2 +-
 arch/parisc/include/uapi/asm/shmbuf.h           |  25 ++--
 arch/parisc/kernel/syscall_table.S              |   8 +-
 arch/sparc/include/asm/atomic_32.h              |   2 +-
 arch/sparc/include/asm/cmpxchg_32.h             |  12 +-
 arch/sparc/include/asm/vio.h                    |  14 +-
 arch/sparc/include/uapi/asm/swab.h              |  12 +-
 arch/sparc/kernel/pci_schizo.c                  |   6 +-
 arch/sparc/kernel/smp_64.c                      |   4 +
 arch/sparc/lib/atomic32.c                       |  27 ++++
 arch/x86/include/asm/cpufeature.h               |   1 +
 arch/x86/include/asm/kvm_para.h                 |  10 +-
 arch/x86/kernel/cpu/amd.c                       |   7 +
 arch/x86/kernel/ptrace.c                        |  11 +-
 arch/x86/kvm/x86.c                              |   2 +-
 arch/xtensa/include/uapi/asm/unistd.h           |   3 +-
 drivers/ata/ahci.c                              |  19 ++-
 drivers/block/sunvdc.c                          | 176 +++++++++++++++++-------
 drivers/char/hw_random/pseries-rng.c            |  23 +++-
 drivers/crypto/caam/caamhash.c                  |  22 +--
 drivers/crypto/caam/sg_sw_sec4.h                |  38 -----
 drivers/firewire/core-cdev.c                    |   3 +-
 drivers/gpu/drm/radeon/cik.c                    |   7 +-
 drivers/gpu/drm/radeon/evergreen.c              |   4 +
 drivers/gpu/drm/radeon/r100.c                   |   3 +
 drivers/gpu/drm/radeon/rs600.c                  |   3 +
 drivers/gpu/drm/radeon/rs690.c                  |   3 +
 drivers/gpu/drm/radeon/rv515.c                  |   3 +
 drivers/gpu/drm/radeon/si.c                     |   3 +
 drivers/input/evdev.c                           |  13 +-
 drivers/input/mouse/alps.c                      |  26 +++-
 drivers/input/serio/altera_ps2.c                |   2 +-
 drivers/input/touchscreen/wm97xx-core.c         |   4 +-
 drivers/md/dm-bufio.c                           |  12 +-
 drivers/md/dm-raid.c                            |  11 +-
 drivers/md/dm-thin.c                            |  16 ++-
 drivers/md/persistent-data/dm-btree-internal.h  |   6 +
 drivers/md/persistent-data/dm-btree-spine.c     |   2 +-
 drivers/md/persistent-data/dm-btree.c           |  24 ++--
 drivers/media/usb/usbvision/usbvision-video.c   |   2 +
 drivers/memstick/host/rtsx_pci_ms.c             |   1 +
 drivers/net/ethernet/sun/sunvnet.c              |   4 +-
 drivers/net/ieee802154/fakehard.c               |  13 +-
 drivers/net/macvtap.c                           |   2 +
 drivers/net/ppp/pptp.c                          |   4 +-
 drivers/net/tun.c                               |  16 ++-
 drivers/net/usb/qmi_wwan.c                      |   1 +
 drivers/net/vxlan.c                             |  28 ++--
 drivers/net/wireless/iwlwifi/iwl-trans.h        |   2 +
 drivers/net/wireless/iwlwifi/mvm/fw-api-power.h |  35 ++++-
 drivers/net/wireless/iwlwifi/mvm/fw-api.h       |   1 +
 drivers/net/wireless/iwlwifi/mvm/fw.c           |   9 ++
 drivers/net/wireless/iwlwifi/mvm/ops.c          |   1 +
 drivers/net/wireless/iwlwifi/pcie/trans.c       |  16 ++-
 drivers/net/wireless/mac80211_hwsim.c           |   4 +-
 drivers/parport/parport_serial.c                |   9 ++
 drivers/pcmcia/Kconfig                          |   2 +-
 drivers/pcmcia/Makefile                         |   1 +
 drivers/pcmcia/at91_cf.c                        |  11 +-
 drivers/pcmcia/sa1111_jornada720.c              |  10 +-
 drivers/platform/x86/pvpanic.c                  |   1 +
 drivers/scsi/scsi_error.c                       |   4 +-
 drivers/staging/zram/zram_drv.c                 |   3 +-
 drivers/tty/serial/8250/8250_pci.c              |  10 ++
 drivers/vlynq/vlynq.c                           |   3 +-
 drivers/vme/bridges/vme_ca91cx42.c              |  29 ++--
 drivers/vme/bridges/vme_tsi148.c                |  28 ++--
 fs/cifs/file.c                                  |   4 +-
 fs/ext4/file.c                                  |   2 +-
 fs/ext4/inode.c                                 |   4 +-
 fs/hfsplus/dir.c                                |  20 ++-
 fs/hfsplus/extents.c                            |  14 +-
 fs/hfsplus/options.c                            |   2 +-
 fs/inode.c                                      |  31 +++++
 fs/ioprio.c                                     |  14 +-
 fs/jfs/jfs_inode.c                              |  16 +--
 fs/minix/bitmap.c                               |   2 +-
 fs/minix/inode.c                                |   4 +-
 fs/nfs/delegation.c                             |  25 +++-
 fs/nfs/delegation.h                             |   1 +
 fs/nfs/direct.c                                 |   1 +
 fs/nfs/inode.c                                  |   2 +-
 fs/nfs/nfs4proc.c                               |  68 +++++----
 fs/nilfs2/file.c                                |   8 +-
 fs/nilfs2/ioctl.c                               |   8 +-
 fs/nilfs2/segment.c                             |   3 +
 fs/nilfs2/super.c                               |   6 +
 fs/nilfs2/the_nilfs.h                           |  22 +++
 fs/ntfs/file.c                                  |   2 +-
 fs/sync.c                                       |  17 ---
 fs/xfs/xfs_file.c                               |   2 +-
 include/linux/clocksource.h                     |   2 +-
 include/linux/crash_dump.h                      |  15 +-
 include/linux/fs.h                              |  11 +-
 include/linux/inetdevice.h                      |   2 +-
 include/linux/kgdb.h                            |   2 +-
 include/linux/nfs_xdr.h                         |  11 ++
 include/net/sctp/sctp.h                         |   5 +
 include/net/sctp/sm.h                           |   6 +-
 include/uapi/linux/netfilter/xt_bpf.h           |   2 +
 ipc/ipc_sysctl.c                                |   3 +-
 kernel/audit_tree.c                             |   1 +
 kernel/rcutree.c                                |  22 ++-
 mm/filemap.c                                    |   4 +-
 net/ceph/crypto.c                               | 169 ++++++++++++++++++-----
 net/ipv4/fib_rules.c                            |   4 +
 net/ipv6/ip6_gre.c                              |   7 +-
 net/ipv6/ip6_tunnel.c                           |  10 +-
 net/ipv6/sit.c                                  |  15 +-
 net/ipx/af_ipx.c                                |   6 +-
 net/mac80211/iface.c                            |   7 +-
 net/mac80211/mlme.c                             |   3 +-
 net/mac80211/rx.c                               |  14 +-
 net/netfilter/nfnetlink_log.c                   |  31 +++--
 net/sctp/associola.c                            |   2 +
 net/sctp/auth.c                                 |   2 -
 net/sctp/inqueue.c                              |  33 +----
 net/sctp/sm_make_chunk.c                        | 102 ++++++++------
 net/sctp/sm_statefuns.c                         |  21 +--
 sound/usb/mixer_quirks.c                        |   6 +
 125 files changed, 1103 insertions(+), 582 deletions(-)
Signature · 1 line
2.1.3
author
#1 lore raw

PATCH 1/101 Input: evdev - fix EVIOCG{type} ioctl

From: Dmitry Torokhov <[email protected]>

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

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

commit 7c4f56070fde2367766fa1fb04852599b5e1ad35 upstream.

The 'max' size passed into the function is measured in number of bits (KEY_MAX, LED_MAX, etc) so we need to convert it accordingly before trying to copy the data out, otherwise we will try copying too much and end up with up with a page fault.

---
 drivers/input/evdev.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/input/evdev.c +8 -5
index a06e12552886..694af4958a98 100644
@@ -757,20 +757,23 @@ static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p)
  */
 static int evdev_handle_get_val(struct evdev_client *client,
 				struct input_dev *dev, unsigned int type,
-				unsigned long *bits, unsigned int max,
-				unsigned int size, void __user *p, int compat)
+				unsigned long *bits, unsigned int maxbit,
+				unsigned int maxlen, void __user *p,
+				int compat)
 {
 	int ret;
 	unsigned long *mem;
+	size_t len;
 
-	mem = kmalloc(sizeof(unsigned long) * max, GFP_KERNEL);
+	len = BITS_TO_LONGS(maxbit) * sizeof(unsigned long);
+	mem = kmalloc(len, GFP_KERNEL);
 	if (!mem)
 		return -ENOMEM;
 
 	spin_lock_irq(&dev->event_lock);
 	spin_lock(&client->buffer_lock);
 
-	memcpy(mem, bits, sizeof(unsigned long) * max);
+	memcpy(mem, bits, len);
 
 	spin_unlock(&dev->event_lock);
 
@@ -778,7 +781,7 @@ static int evdev_handle_get_val(struct evdev_client *client,
 
 	spin_unlock_irq(&client->buffer_lock);
 
-	ret = bits_to_user(mem, max, size, p, compat);
+	ret = bits_to_user(mem, maxbit, maxlen, p, compat);
 	if (ret < 0)
 		evdev_queue_syn_dropped(client);
 
Signature · 1 line
2.1.3
author
#2 lore raw

PATCH 2/101 ip6_tunnel: Use ip6_tnl_dev_init as the ndo_init function.

From: Steffen Klassert <[email protected]>

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

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

[ Upstream commit 6c6151daaf2d8dc2046d9926539feed5f66bf74e ]

ip6_tnl_dev_init() sets the dev->iflink via a call to ip6_tnl_link_config(). After that, register_netdevice() sets dev->iflink = -1. So we loose the iflink configuration for ipv6 tunnels. Fix this by using ip6_tnl_dev_init() as the ndo_init function. Then ip6_tnl_dev_init() is called after dev->iflink is set to -1 from register_netdevice().

---
 net/ipv6/ip6_tunnel.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)
net/ipv6/ip6_tunnel.c +1 -9
index 7c26d8a3fa1b..f8a70a120e75 100644
@@ -266,9 +266,6 @@ static int ip6_tnl_create2(struct net_device *dev)
 	int err;
 
 	t = netdev_priv(dev);
-	err = ip6_tnl_dev_init(dev);
-	if (err < 0)
-		goto out;
 
 	err = register_netdevice(dev);
 	if (err < 0)
@@ -1448,6 +1445,7 @@ ip6_tnl_change_mtu(struct net_device *dev, int new_mtu)
 
 
 static const struct net_device_ops ip6_tnl_netdev_ops = {
+	.ndo_init	= ip6_tnl_dev_init,
 	.ndo_uninit	= ip6_tnl_dev_uninit,
 	.ndo_start_xmit = ip6_tnl_xmit,
 	.ndo_do_ioctl	= ip6_tnl_ioctl,
@@ -1532,16 +1530,10 @@ static int __net_init ip6_fb_tnl_dev_init(struct net_device *dev)
 	struct ip6_tnl *t = netdev_priv(dev);
 	struct net *net = dev_net(dev);
 	struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
-	int err = ip6_tnl_dev_init_gen(dev);
-
-	if (err)
-		return err;
 
 	t->parms.proto = IPPROTO_IPV6;
 	dev_hold(dev);
 
-	ip6_tnl_link_config(t);
-
 	rcu_assign_pointer(ip6n->tnls_wc[0], t);
 	return 0;
 }
Signature · 1 line
2.1.3
author
#3 lore raw

PATCH 3/101 sit: Use ipip6_tunnel_init as the ndo_init function.

In reply to Jiri Slaby

From: Steffen Klassert <[email protected]>

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

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

[ Upstream commit ebe084aafb7e93adf210e80043c9f69adf56820d ]

ipip6_tunnel_init() sets the dev->iflink via a call to ipip6_tunnel_bind_dev(). After that, register_netdevice() sets dev->iflink = -1. So we loose the iflink configuration for ipv6 tunnels. Fix this by using ipip6_tunnel_init() as the ndo_init function. Then ipip6_tunnel_init() is called after dev->iflink is set to -1 from register_netdevice().

---
 net/ipv6/sit.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)
net/ipv6/sit.c +6 -9
index ebdf18bbcc02..8e8fc32a080f 100644
@@ -195,10 +195,8 @@ static int ipip6_tunnel_create(struct net_device *dev)
 	struct sit_net *sitn = net_generic(net, sit_net_id);
 	int err;
 
-	err = ipip6_tunnel_init(dev);
-	if (err < 0)
-		goto out;
-	ipip6_tunnel_clone_6rd(dev, sitn);
+	memcpy(dev->dev_addr, &t->parms.iph.saddr, 4);
+	memcpy(dev->broadcast, &t->parms.iph.daddr, 4);
 
 	if ((__force u16)t->parms.i_flags & SIT_ISATAP)
 		dev->priv_flags |= IFF_ISATAP;
@@ -207,7 +205,8 @@ static int ipip6_tunnel_create(struct net_device *dev)
 	if (err < 0)
 		goto out;
 
-	strcpy(t->parms.name, dev->name);
+	ipip6_tunnel_clone_6rd(dev, sitn);
+
 	dev->rtnl_link_ops = &sit_link_ops;
 
 	dev_hold(dev);
@@ -1279,6 +1278,7 @@ static int ipip6_tunnel_change_mtu(struct net_device *dev, int new_mtu)
 }
 
 static const struct net_device_ops ipip6_netdev_ops = {
+	.ndo_init	= ipip6_tunnel_init,
 	.ndo_uninit	= ipip6_tunnel_uninit,
 	.ndo_start_xmit	= sit_tunnel_xmit,
 	.ndo_do_ioctl	= ipip6_tunnel_ioctl,
@@ -1313,9 +1313,7 @@ static int ipip6_tunnel_init(struct net_device *dev)
 
 	tunnel->dev = dev;
 	tunnel->net = dev_net(dev);
-
-	memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
-	memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
+	strcpy(tunnel->parms.name, dev->name);
 
 	ipip6_tunnel_bind_dev(dev);
 	dev->tstats = alloc_percpu(struct pcpu_tstats);
@@ -1334,7 +1332,6 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev)
 
 	tunnel->dev = dev;
 	tunnel->net = dev_net(dev);
-	strcpy(tunnel->parms.name, dev->name);
 
 	iph->version		= 4;
 	iph->protocol		= IPPROTO_IPV6;
Signature · 1 line
2.1.3
author
#4 lore raw

PATCH 4/101 gre6: Move the setting of dev->iflink into the ndo_init functions.

In reply to Jiri Slaby

From: Steffen Klassert <[email protected]>

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

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

[ Upstream commit f03eb128e3f4276f46442d14f3b8f864f3775821 ]

Otherwise it gets overwritten by register_netdev().

---
 net/ipv6/ip6_gre.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
net/ipv6/ip6_gre.c +4 -3
index 99988b86f6af..88774ccb3dda 100644
@@ -965,8 +965,6 @@ static void ip6gre_tnl_link_config(struct ip6_tnl *t, int set_mtu)
 	else
 		dev->flags &= ~IFF_POINTOPOINT;
 
-	dev->iflink = p->link;
-
 	/* Precalculate GRE options length */
 	if (t->parms.o_flags&(GRE_CSUM|GRE_KEY|GRE_SEQ)) {
 		if (t->parms.o_flags&GRE_CSUM)
@@ -1269,6 +1267,8 @@ static int ip6gre_tunnel_init(struct net_device *dev)
 	if (!dev->tstats)
 		return -ENOMEM;
 
+	dev->iflink = tunnel->parms.link;
+
 	return 0;
 }
 
@@ -1285,7 +1285,6 @@ static void ip6gre_fb_tunnel_init(struct net_device *dev)
 	dev_hold(dev);
 }
 
-
 static struct inet6_protocol ip6gre_protocol __read_mostly = {
 	.handler     = ip6gre_rcv,
 	.err_handler = ip6gre_err,
@@ -1462,6 +1461,8 @@ static int ip6gre_tap_init(struct net_device *dev)
 	if (!dev->tstats)
 		return -ENOMEM;
 
+	dev->iflink = tunnel->parms.link;
+
 	return 0;
 }
 
Signature · 1 line
2.1.3
author
#5 lore raw

PATCH 5/101 vxlan: Do not reuse sockets for a different address family

In reply to Jiri Slaby

From: Marcelo Leitner <[email protected]>

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

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

[ Upstream commit 19ca9fc1445b76b60d34148f7ff837b055f5dcf3 ]

Currently, we only match against local port number in order to reuse socket. But if this new vxlan wants an IPv6 socket and a IPv4 one bound to that port, vxlan will reuse an IPv4 socket as IPv6 and a panic will follow. The following steps reproduce it:

   # ip link add vxlan6 type vxlan id 42 group 229.10.10.10 \
       srcport 5000 6000 dev eth0
   # ip link add vxlan7 type vxlan id 43 group ff0e::110 \
       srcport 5000 6000 dev eth0
   # ip link set vxlan6 up
   # ip link set vxlan7 up
   <panic>
[    4.187481] BUG: unable to handle kernel NULL pointer dereference at 0000000000000058
...
[    4.188076] Call Trace:
[    4.188085]  [<ffffffff81667c4a>] ? ipv6_sock_mc_join+0x3a/0x630
[    4.188098]  [<ffffffffa05a6ad6>] vxlan_igmp_join+0x66/0xd0 [vxlan]
[    4.188113]  [<ffffffff810a3430>] process_one_work+0x220/0x710
[    4.188125]  [<ffffffff810a33c4>] ? process_one_work+0x1b4/0x710
[    4.188138]  [<ffffffff810a3a3b>] worker_thread+0x11b/0x3a0
[    4.188149]  [<ffffffff810a3920>] ? process_one_work+0x710/0x710

So address family must also match in order to reuse a socket.

---
 drivers/net/vxlan.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)
drivers/net/vxlan.c +18 -10
index 23969eaf88c1..5407c11a9f14 100644
@@ -282,13 +282,15 @@ static inline struct vxlan_rdst *first_remote_rtnl(struct vxlan_fdb *fdb)
 	return list_first_entry(&fdb->remotes, struct vxlan_rdst, list);
 }
 
-/* Find VXLAN socket based on network namespace and UDP port */
-static struct vxlan_sock *vxlan_find_sock(struct net *net, __be16 port)
+/* Find VXLAN socket based on network namespace, address family and UDP port */
+static struct vxlan_sock *vxlan_find_sock(struct net *net,
+					  sa_family_t family, __be16 port)
 {
 	struct vxlan_sock *vs;
 
 	hlist_for_each_entry_rcu(vs, vs_head(net, port), hlist) {
-		if (inet_sk(vs->sock->sk)->inet_sport == port)
+		if (inet_sk(vs->sock->sk)->inet_sport == port &&
+		    inet_sk(vs->sock->sk)->sk.sk_family == family)
 			return vs;
 	}
 	return NULL;
@@ -307,11 +309,12 @@ static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs, u32 id)
 }
 
 /* Look up VNI in a per net namespace table */
-static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id, __be16 port)
+static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id,
+					sa_family_t family, __be16 port)
 {
 	struct vxlan_sock *vs;
 
-	vs = vxlan_find_sock(net, port);
+	vs = vxlan_find_sock(net, family, port);
 	if (!vs)
 		return NULL;
 
@@ -1783,7 +1786,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
 			struct vxlan_dev *dst_vxlan;
 
 			ip_rt_put(rt);
-			dst_vxlan = vxlan_find_vni(dev_net(dev), vni, dst_port);
+			dst_vxlan = vxlan_find_vni(dev_net(dev), vni,
+						   dst->sa.sa_family, dst_port);
 			if (!dst_vxlan)
 				goto tx_error;
 			vxlan_encap_bypass(skb, vxlan, dst_vxlan);
@@ -1836,7 +1840,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
 			struct vxlan_dev *dst_vxlan;
 
 			dst_release(ndst);
-			dst_vxlan = vxlan_find_vni(dev_net(dev), vni, dst_port);
+			dst_vxlan = vxlan_find_vni(dev_net(dev), vni,
+						   dst->sa.sa_family, dst_port);
 			if (!dst_vxlan)
 				goto tx_error;
 			vxlan_encap_bypass(skb, vxlan, dst_vxlan);
@@ -1987,6 +1992,7 @@ static int vxlan_init(struct net_device *dev)
 {
 	struct vxlan_dev *vxlan = netdev_priv(dev);
 	struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
+	bool ipv6 = vxlan->flags & VXLAN_F_IPV6;
 	struct vxlan_sock *vs;
 
 	dev->tstats = alloc_percpu(struct pcpu_tstats);
@@ -1994,7 +2000,8 @@ static int vxlan_init(struct net_device *dev)
 		return -ENOMEM;
 
 	spin_lock(&vn->sock_lock);
-	vs = vxlan_find_sock(dev_net(dev), vxlan->dst_port);
+	vs = vxlan_find_sock(dev_net(dev), ipv6 ? AF_INET6 : AF_INET,
+			     vxlan->dst_port);
 	if (vs) {
 		/* If we have a socket with same port already, reuse it */
 		atomic_inc(&vs->refcnt);
@@ -2439,7 +2446,7 @@ struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
 		return vs;
 
 	spin_lock(&vn->sock_lock);
-	vs = vxlan_find_sock(net, port);
+	vs = vxlan_find_sock(net, ipv6 ? AF_INET6 : AF_INET, port);
 	if (vs) {
 		if (vs->rcv == rcv)
 			atomic_inc(&vs->refcnt);
@@ -2584,7 +2591,8 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
 	if (data[IFLA_VXLAN_PORT])
 		vxlan->dst_port = nla_get_be16(data[IFLA_VXLAN_PORT]);
 
-	if (vxlan_find_vni(net, vni, vxlan->dst_port)) {
+	if (vxlan_find_vni(net, vni, use_ipv6 ? AF_INET6 : AF_INET,
+			   vxlan->dst_port)) {
 		pr_info("duplicate VNI %u\n", vni);
 		return -EEXIST;
 	}
Signature · 1 line
2.1.3
author
#6 lore raw

PATCH 6/101 net: sctp: fix NULL pointer dereference in af->from_addr_param on malformed packet

In reply to Jiri Slaby

From: Daniel Borkmann <[email protected]>

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

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

[ Upstream commit e40607cbe270a9e8360907cb1e62ddf0736e4864 ]

An SCTP server doing ASCONF will panic on malformed INIT ping-of-death in the form of:

------------ INIT[PARAM: SET_PRIMARY_IP] ------------>

While the INIT chunk parameter verification dissects through many things in order to detect malformed input, it misses to actually check parameters inside of parameters. E.g. RFC5061, section 4.2.4 proposes a 'set primary IP address' parameter in ASCONF, which has as a subparameter an address parameter.

So an attacker may send a parameter type other than SCTP_PARAM_IPV4_ADDRESS or SCTP_PARAM_IPV6_ADDRESS, param_type2af() will subsequently return 0 and thus sctp_get_af_specific() returns NULL, too, which we then happily dereference unconditionally through af->from_addr_param().

The trace for the log:

BUG: unable to handle kernel NULL pointer dereference at 0000000000000078
IP: [<ffffffffa01e9c62>] sctp_process_init+0x492/0x990 [sctp]
PGD 0
Oops: 0000 [#1] SMP
[...]
Pid: 0, comm: swapper Not tainted 2.6.32-504.el6.x86_64 #1 Bochs Bochs
RIP: 0010:[<ffffffffa01e9c62>]  [<ffffffffa01e9c62>] sctp_process_init+0x492/0x990 [sctp]
[...]
Call Trace:
 <IRQ>
 [<ffffffffa01f2add>] ? sctp_bind_addr_copy+0x5d/0xe0 [sctp]
 [<ffffffffa01e1fcb>] sctp_sf_do_5_1B_init+0x21b/0x340 [sctp]
 [<ffffffffa01e3751>] sctp_do_sm+0x71/0x1210 [sctp]
 [<ffffffffa01e5c09>] ? sctp_endpoint_lookup_assoc+0xc9/0xf0 [sctp]
 [<ffffffffa01e61f6>] sctp_endpoint_bh_rcv+0x116/0x230 [sctp]
 [<ffffffffa01ee986>] sctp_inq_push+0x56/0x80 [sctp]
 [<ffffffffa01fcc42>] sctp_rcv+0x982/0xa10 [sctp]
 [<ffffffffa01d5123>] ? ipt_local_in_hook+0x23/0x28 [iptable_filter]
 [<ffffffff8148bdc9>] ? nf_iterate+0x69/0xb0
 [<ffffffff81496d10>] ? ip_local_deliver_finish+0x0/0x2d0
 [<ffffffff8148bf86>] ? nf_hook_slow+0x76/0x120
 [<ffffffff81496d10>] ? ip_local_deliver_finish+0x0/0x2d0

[...]

A minimal way to address this is to check for NULL as we do on all other such occasions where we know sctp_get_af_specific() could possibly return with NULL.

Fixes d6de3097592b ("[SCTP]: Add the handling of "Set Primary IP Address" parameter to INIT")
Cc Vlad Yasevich <[email protected]>
---
 net/sctp/sm_make_chunk.c | 3 +++
 1 file changed, 3 insertions(+)
net/sctp/sm_make_chunk.c +3 -0
index 1e06f3b23108..e3423876cb8d 100644
@@ -2622,6 +2622,9 @@ do_addr_param:
 		addr_param = param.v + sizeof(sctp_addip_param_t);
 
 		af = sctp_get_af_specific(param_type2af(param.p->type));
+		if (af == NULL)
+			break;
+
 		af->from_addr_param(&addr, addr_param,
 				    htons(asoc->peer.port), 0);
 
Signature · 1 line
2.1.3
author
#7 lore raw

PATCH 7/101 net: sctp: fix memory leak in auth key management

In reply to Jiri Slaby

From: Daniel Borkmann <[email protected]>

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

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

[ Upstream commit 4184b2a79a7612a9272ce20d639934584a1f3786 ]

A very minimal and simple user space application allocating an SCTP socket, setting SCTP_AUTH_KEY setsockopt(2) on it and then closing the socket again will leak the memory containing the authentication key from user space:

unreferenced object 0xffff8800837047c0 (size 16):
comm "a.out", pid 2789, jiffies 4296954322 (age 192.258s) hex dump (first 16 bytes):

    01 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00  ................
  backtrace:
    [<ffffffff816d7e8e>] kmemleak_alloc+0x4e/0xb0
    [<ffffffff811c88d8>] __kmalloc+0xe8/0x270
    [<ffffffffa0870c23>] sctp_auth_create_key+0x23/0x50 [sctp]
    [<ffffffffa08718b1>] sctp_auth_set_key+0xa1/0x140 [sctp]
    [<ffffffffa086b383>] sctp_setsockopt+0xd03/0x1180 [sctp]
    [<ffffffff815bfd94>] sock_common_setsockopt+0x14/0x20
    [<ffffffff815beb61>] SyS_setsockopt+0x71/0xd0
    [<ffffffff816e58a9>] system_call_fastpath+0x12/0x17
    [<ffffffffffffffff>] 0xffffffffffffffff

This is bad because of two things, we can bring down a machine from user space when auth_enable=1, but also we would leave security sensitive keying material in memory without clearing it after use. The issue is that sctp_auth_create_key() already sets the refcount to 1, but after allocation sctp_auth_set_key() does an additional refcount on it, and thus leaving it around when we free the socket.

Fixes 65b07e5d0d0 ("[SCTP]: API updates to suport SCTP-AUTH extensions.")
Cc Vlad Yasevich <[email protected]>
---
 net/sctp/auth.c | 2 --
 1 file changed, 2 deletions(-)
net/sctp/auth.c +0 -2
index 43b871f6cddf..4b842e9618ad 100644
@@ -868,8 +868,6 @@ int sctp_auth_set_key(struct sctp_endpoint *ep,
 		list_add(&cur_key->key_list, sh_keys);
 
 	cur_key->key = key;
-	sctp_auth_key_hold(key);
-
 	return 0;
 nomem:
 	if (!replace)
Signature · 1 line
2.1.3
author
#8 lore raw

PATCH 8/101 sunvdc: add cdrom and v1.1 protocol support

In reply to Jiri Slaby

From: Allen Pais <[email protected]>

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

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

[ Upstream commit 9bce21828d54a95143f1b74619705c2dd8e88b92 ]

Interpret the media type from v1.1 protocol to support CDROM/DVD.

For v1.0 protocol, a disk's size continues to be calculated from the geometry returned by the vdisk server. The geometry returned by the server can be less than the actual number of sectors available in the backing image/device due to the rounding in the division used to compute the geometry in the vdisk server.

In v1.1 protocol a disk's actual size in sectors is returned during the handshake. Use this size when v1.1 protocol is negotiated. Since this size will always be larger than the former geometry computed size, disks created under v1.0 will be forwards compatible to v1.1, but not vice versa.

---
 arch/sparc/include/asm/vio.h |  12 +++--
 drivers/block/sunvdc.c       | 109 ++++++++++++++++++++++++++++++++++++-------
 2 files changed, 101 insertions(+), 20 deletions(-)
arch/sparc/include/asm/vio.h +9 -3
index 432afa838861..a8210c5e5932 100644
@@ -118,12 +118,18 @@ struct vio_disk_attr_info {
 	u8			vdisk_type;
 #define VD_DISK_TYPE_SLICE	0x01 /* Slice in block device	*/
 #define VD_DISK_TYPE_DISK	0x02 /* Entire block device	*/
-	u16			resv1;
+	u8			vdisk_mtype;		/* v1.1 */
+#define VD_MEDIA_TYPE_FIXED	0x01 /* Fixed device */
+#define VD_MEDIA_TYPE_CD	0x02 /* CD Device    */
+#define VD_MEDIA_TYPE_DVD	0x03 /* DVD Device   */
+	u8			resv1;
 	u32			vdisk_block_size;
 	u64			operations;
-	u64			vdisk_size;
+	u64			vdisk_size;		/* v1.1 */
 	u64			max_xfer_size;
-	u64			resv2[2];
+	u32			phys_block_size;	/* v1.2 */
+	u32			resv2;
+	u64			resv3[1];
 };
 
 struct vio_disk_desc {
drivers/block/sunvdc.c +92 -17

180 lines not on this page · raw message

Signature · 1 line
2.1.3
author
#9 lore raw

PATCH 9/101 sunvdc: compute vdisk geometry from capacity

In reply to Jiri Slaby

From: Allen Pais <[email protected]>

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

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

[ Upstream commit de5b73f08468b4fc5e2f6d1505f650262622f78b ]

The LDom diskserver doesn't return reliable geometry data. In addition, the types for all fields in the vio_disk_geom are u16, which were being truncated in the cast into the u8's of the Linux struct hd_geometry.

Modify vdc_getgeo() to compute the geometry from the disk's capacity in a manner consistent with xen-blkfront::blkif_getgeo().

---
 drivers/block/sunvdc.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)
drivers/block/sunvdc.c +14 -9
index 66ddf704ad7f..1616ad091a5e 100644
@@ -70,7 +70,6 @@ struct vdc_port {
 
 	char			disk_name[32];
 
-	struct vio_disk_geom	geom;
 	struct vio_disk_vtoc	label;
 };
 
@@ -103,11 +102,15 @@ static inline u32 vdc_tx_dring_avail(struct vio_dring_state *dr)
 static int vdc_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
 	struct gendisk *disk = bdev->bd_disk;
-	struct vdc_port *port = disk->private_data;
+	sector_t nsect = get_capacity(disk);
+	sector_t cylinders = nsect;
 
-	geo->heads = (u8) port->geom.num_hd;
-	geo->sectors = (u8) port->geom.num_sec;
-	geo->cylinders = port->geom.num_cyl;
+	geo->heads = 0xff;
+	geo->sectors = 0x3f;
+	sector_div(cylinders, geo->heads * geo->sectors);
+	geo->cylinders = cylinders;
+	if ((sector_t)(geo->cylinders + 1) * geo->heads * geo->sectors < nsect)
+		geo->cylinders = 0xffff;
 
 	return 0;
 }
@@ -714,16 +717,18 @@ static int probe_disk(struct vdc_port *port)
 		if (port->vdisk_size == -1)
 			return -ENODEV;
 	} else {
+		struct vio_disk_geom geom;
+
 		err = generic_request(port, VD_OP_GET_DISKGEOM,
-				      &port->geom, sizeof(port->geom));
+				      &geom, sizeof(geom));
 		if (err < 0) {
 			printk(KERN_ERR PFX "VD_OP_GET_DISKGEOM returns "
 			       "error %d\n", err);
 			return err;
 		}
-		port->vdisk_size = ((u64)port->geom.num_cyl *
-				    (u64)port->geom.num_hd *
-				    (u64)port->geom.num_sec);
+		port->vdisk_size = ((u64)geom.num_cyl *
+				    (u64)geom.num_hd *
+				    (u64)geom.num_sec);
 	}
 
 	q = blk_init_queue(do_vdc_request, &port->vio.lock);
Signature · 1 line
2.1.3
author
#10 lore raw

PATCH 10/101 sunvdc: limit each sg segment to a page

In reply to Jiri Slaby

From: Dwight Engen <[email protected]>

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

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

[ Upstream commit 5eed69ffd248c9f68f56c710caf07db134aef28b ]

ldc_map_sg() could fail its check that the number of pages referred to by the sg scatterlist was <= the number of cookies.

This fixes the issue by doing a similar thing to the xen-blkfront driver, ensuring that the scatterlist will only ever contain a segment count <= port->ring_cookies, and each segment will be page aligned, and <= page size. This ensures that the scatterlist is always mappable.

Orabug: 19347817
OraBZ: 15945

---
 drivers/block/sunvdc.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/block/sunvdc.c +4 -0
index 1616ad091a5e..1a9360da1f54 100644
@@ -747,6 +747,10 @@ static int probe_disk(struct vdc_port *port)
 
 	port->disk = g;
 
+	/* Each segment in a request is up to an aligned page in size. */
+	blk_queue_segment_boundary(q, PAGE_SIZE - 1);
+	blk_queue_max_segment_size(q, PAGE_SIZE);
+
 	blk_queue_max_segments(q, port->ring_cookies);
 	blk_queue_max_hw_sectors(q, port->max_xfer_size);
 	g->major = vdc_major;
Signature · 1 line
2.1.3
author
#11 lore raw

PATCH 11/101 vio: fix reuse of vio_dring slot

In reply to Jiri Slaby

From: Dwight Engen <[email protected]>

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

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

[ Upstream commit d0aedcd4f14a22e23b313f42b7e6e6ebfc0fbc31 ]

vio_dring_avail() will allow use of every dring entry, but when the last entry is allocated then dr->prod == dr->cons which is indistinguishable from the ring empty condition. This causes the next allocation to reuse an entry. When this happens in sunvdc, the server side vds driver begins nack'ing the messages and ends up resetting the ldc channel. This problem does not effect sunvnet since it checks for < 2.

The fix here is to just never allocate the very last dring slot so that full and empty are not the same condition. The request start path was changed to check for the ring being full a bit earlier, and to stop the blk_queue if there is no space left. The blk_queue will be restarted once the ring is only half full again. The number of ring entries was increased to 512 which matches the sunvnet and Solaris vdc drivers, and greatly reduces the frequency of hitting the ring full condition and the associated blk_queue stop/starting. The checks in sunvent were adjusted to account for vio_dring_avail() returning 1 less.

Orabug: 19441666
OraBZ: 14983

---
 arch/sparc/include/asm/vio.h       |  2 +-
 drivers/block/sunvdc.c             | 39 ++++++++++++++++++++++----------------
 drivers/net/ethernet/sun/sunvnet.c |  4 ++--
 3 files changed, 26 insertions(+), 19 deletions(-)
arch/sparc/include/asm/vio.h +1 -1
index a8210c5e5932..55841c184e6d 100644
@@ -265,7 +265,7 @@ static inline u32 vio_dring_avail(struct vio_dring_state *dr,
 				  unsigned int ring_size)
 {
 	return (dr->pending -
-		((dr->prod - dr->cons) & (ring_size - 1)));
+		((dr->prod - dr->cons) & (ring_size - 1)) - 1);
 }
 
 #define VIO_MAX_TYPE_LEN	32
drivers/block/sunvdc.c +23 -16
index 1a9360da1f54..756b8ec00f16 100644
@@ -33,7 +33,7 @@ MODULE_DESCRIPTION("Sun LDOM virtual disk client driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_MODULE_VERSION);
 
-#define VDC_TX_RING_SIZE	256
+#define VDC_TX_RING_SIZE	512
 
 #define WAITING_FOR_LINK_UP	0x01
 #define WAITING_FOR_TX_SPACE	0x02
@@ -283,7 +283,9 @@ static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr,
 
 	__blk_end_request(req, (desc->status ? -EIO : 0), desc->size);
 
-	if (blk_queue_stopped(port->disk->queue))
+	/* restart blk queue when ring is half emptied */
+	if (blk_queue_stopped(port->disk->queue) &&
+	    vdc_tx_dring_avail(dr) * 100 / VDC_TX_RING_SIZE >= 50)
 		blk_start_queue(port->disk->queue);
 }
 
@@ -435,12 +437,6 @@ static int __send_request(struct request *req)
 	for (i = 0; i < nsg; i++)
 		len += sg[i].length;
 
-	if (unlikely(vdc_tx_dring_avail(dr) < 1)) {
-		blk_stop_queue(port->disk->queue);
-		err = -ENOMEM;
-		goto out;
-	}
-
 	desc = vio_dring_cur(dr);
 
 	err = ldc_map_sg(port->vio.lp, sg, nsg,
@@ -480,21 +476,32 @@ static int __send_request(struct request *req)
 		port->req_id++;
 		dr->prod = (dr->prod + 1) & (VDC_TX_RING_SIZE - 1);
 	}
-out:
 
 	return err;
 }
 
-static void do_vdc_request(struct request_queue *q)
+static void do_vdc_request(struct request_queue *rq)
 {
-	while (1) {
-		struct request *req = blk_fetch_request(q);
+	struct request *req;
 
-		if (!req)
-			break;
+	while ((req = blk_peek_request(rq)) != NULL) {
+		struct vdc_port *port;
+		struct vio_dring_state *dr;
 
-		if (__send_request(req) < 0)
-			__blk_end_request_all(req, -EIO);
+		port = req->rq_disk->private_data;
+		dr = &port->vio.drings[VIO_DRIVER_TX_RING];
+		if (unlikely(vdc_tx_dring_avail(dr) < 1))
+			goto wait;
+
+		blk_start_request(req);
+
+		if (__send_request(req) < 0) {
+			blk_requeue_request(rq, req);
+wait:
+			/* Avoid pointless unplugs. */
+			blk_stop_queue(rq);
+			break;
+		}
 	}
 }
 
drivers/net/ethernet/sun/sunvnet.c +2 -2
index 398faff8be7a..ade8bdfc03af 100644
@@ -656,7 +656,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	spin_lock_irqsave(&port->vio.lock, flags);
 
 	dr = &port->vio.drings[VIO_DRIVER_TX_RING];
-	if (unlikely(vnet_tx_dring_avail(dr) < 2)) {
+	if (unlikely(vnet_tx_dring_avail(dr) < 1)) {
 		if (!netif_queue_stopped(dev)) {
 			netif_stop_queue(dev);
 
@@ -704,7 +704,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev->stats.tx_bytes += skb->len;
 
 	dr->prod = (dr->prod + 1) & (VNET_TX_RING_SIZE - 1);
-	if (unlikely(vnet_tx_dring_avail(dr) < 2)) {
+	if (unlikely(vnet_tx_dring_avail(dr) < 1)) {
 		netif_stop_queue(dev);
 		if (vnet_tx_dring_avail(dr) > VNET_TX_WAKEUP_THRESH(dr))
 			netif_wake_queue(dev);
Signature · 1 line
2.1.3
author
#12 lore raw

PATCH 12/101 sunvdc: don't call VD_OP_GET_VTOC

In reply to Jiri Slaby

From: Dwight Engen <[email protected]>

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

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

[ Upstream commit 85b0c6e62c48bb9179fd5b3e954f362fb346cbd5 ]

The VD_OP_GET_VTOC operation will succeed only if the vdisk backend has a VTOC label, otherwise it will fail. In particular, it will return error 48 (ENOTSUP) if the disk has an EFI label. VTOC disk labels are already handled by directly reading the disk in block/partitions/sun.c (enabled by CONFIG_SUN_PARTITION which defaults to y on SPARC). Since port->label is unused in the driver, remove the call and the field.

---
 drivers/block/sunvdc.c | 9 ---------
 1 file changed, 9 deletions(-)
drivers/block/sunvdc.c +0 -9
index 756b8ec00f16..0ebadf93b6c5 100644
@@ -69,8 +69,6 @@ struct vdc_port {
 	u8			vdisk_mtype;
 
 	char			disk_name[32];
-
-	struct vio_disk_vtoc	label;
 };
 
 static inline struct vdc_port *to_vdc_port(struct vio_driver_state *vio)
@@ -710,13 +708,6 @@ static int probe_disk(struct vdc_port *port)
 	if (comp.err)
 		return comp.err;
 
-	err = generic_request(port, VD_OP_GET_VTOC,
-			      &port->label, sizeof(port->label));
-	if (err < 0) {
-		printk(KERN_ERR PFX "VD_OP_GET_VTOC returns error %d\n", err);
-		return err;
-	}
-
 	if (vdc_version_supported(port, 1, 1)) {
 		/* vdisk_size should be set during the handshake, if it wasn't
 		 * then the underlying disk is reserved by another system
Signature · 1 line
2.1.3
author
#13 lore raw

PATCH 13/101 sparc64: Fix crashes in schizo_pcierr_intr_other().

In reply to Jiri Slaby

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

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

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

[ Upstream commit 7da89a2a3776442a57e918ca0b8678d1b16a7072 ]

Meelis Roos reports crashes during bootup on a V480 that look like this:

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

[   61.300577] PCI: Scanning PBM /pci@9,600000
[   61.304867] schizo f009b070: PCI host bridge to bus 0003:00
[   61.310385] pci_bus 0003:00: root bus resource [io  0x7ffe9000000-0x7ffe9ffffff] (bus address [0x0000-0xffffff])
[   61.320515] pci_bus 0003:00: root bus resource [mem 0x7fb00000000-0x7fbffffffff] (bus address [0x00000000-0xffffffff])
[   61.331173] pci_bus 0003:00: root bus resource [bus 00]
[   61.385344] Unable to handle kernel NULL pointer dereference
[   61.390970] tsk->{mm,active_mm}->context = 0000000000000000
[   61.396515] tsk->{mm,active_mm}->pgd = fff000b000002000
[   61.401716]               \|/ ____ \|/
[   61.401716]               "@'/ .. \`@"
[   61.401716]               /_| \__/ |_\
[   61.401716]                  \__U_/
[   61.416362] swapper/0(0): Oops [#1]
[   61.419837] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.18.0-rc1-00422-g2cc9188-dirty #24
[   61.427975] task: fff000b0fd8e9c40 ti: fff000b0fd928000 task.ti: fff000b0fd928000
[   61.435426] TSTATE: 0000004480e01602 TPC: 00000000004455e4 TNPC: 00000000004455e8 Y: 00000000    Not tainted
[   61.445230] TPC: <schizo_pcierr_intr+0x104/0x560>
[   61.449897] g0: 0000000000000000 g1: 0000000000000000 g2: 0000000000a10f78 g3: 000000000000000a
[   61.458563] g4: fff000b0fd8e9c40 g5: fff000b0fdd82000 g6: fff000b0fd928000 g7: 000000000000000a
[   61.467229] o0: 000000000000003d o1: 0000000000000000 o2: 0000000000000006 o3: fff000b0ffa5fc7e
[   61.475894] o4: 0000000000060000 o5: c000000000000000 sp: fff000b0ffa5f3c1 ret_pc: 00000000004455cc
[   61.484909] RPC: <schizo_pcierr_intr+0xec/0x560>
[   61.489500] l0: fff000b0fd8e9c40 l1: 0000000000a20800 l2: 0000000000000000 l3: 000000000119a430
[   61.498164] l4: 0000000001742400 l5: 00000000011cfbe0 l6: 00000000011319c0 l7: fff000b0fd8ea348
[   61.506830] i0: 0000000000000000 i1: fff000b0fdb34000 i2: 0000000320000000 i3: 0000000000000000
[   61.515497] i4: 00060002010b003f i5: 0000040004e02000 i6: fff000b0ffa5f481 i7: 00000000004a9920
[   61.524175] I7: <handle_irq_event_percpu+0x40/0x140>
[   61.529099] Call Trace:
[   61.531531]  [00000000004a9920] handle_irq_event_percpu+0x40/0x140
[   61.537681]  [00000000004a9a58] handle_irq_event+0x38/0x80
[   61.543145]  [00000000004ac77c] handle_fasteoi_irq+0xbc/0x200
[   61.548860]  [00000000004a9084] generic_handle_irq+0x24/0x40
[   61.554500]  [000000000042be0c] handler_irq+0xac/0x100

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

The problem is that pbm->pci_bus->self is NULL.

This code is trying to go through the standard PCI config space interfaces to read the PCI controller's PCI_STATUS register.

This doesn't work, because we more often than not do not enumerate the PCI controller as a bonafide PCI device during the OF device node scan. Therefore bus->self remains NULL.

Existing common code for PSYCHO and PSYCHO-like PCI controllers handles this properly, by doing the config space access directly.

Do the same here, pbm->pci_ops->{read,write}().

---
 arch/sparc/kernel/pci_schizo.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
arch/sparc/kernel/pci_schizo.c +3 -3
index 8f76f23dac38..f9c6813c132d 100644
@@ -581,7 +581,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm)
 {
 	unsigned long csr_reg, csr, csr_error_bits;
 	irqreturn_t ret = IRQ_NONE;
-	u16 stat;
+	u32 stat;
 
 	csr_reg = pbm->pbm_regs + SCHIZO_PCI_CTRL;
 	csr = upa_readq(csr_reg);
@@ -617,7 +617,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm)
 			       pbm->name);
 		ret = IRQ_HANDLED;
 	}
-	pci_read_config_word(pbm->pci_bus->self, PCI_STATUS, &stat);
+	pbm->pci_ops->read(pbm->pci_bus, 0, PCI_STATUS, 2, &stat);
 	if (stat & (PCI_STATUS_PARITY |
 		    PCI_STATUS_SIG_TARGET_ABORT |
 		    PCI_STATUS_REC_TARGET_ABORT |
@@ -625,7 +625,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm)
 		    PCI_STATUS_SIG_SYSTEM_ERROR)) {
 		printk("%s: PCI bus error, PCI_STATUS[%04x]\n",
 		       pbm->name, stat);
-		pci_write_config_word(pbm->pci_bus->self, PCI_STATUS, 0xffff);
+		pbm->pci_ops->write(pbm->pci_bus, 0, PCI_STATUS, 2, 0xffff);
 		ret = IRQ_HANDLED;
 	}
 	return ret;
Signature · 1 line
2.1.3
author
#14 lore raw

PATCH 14/101 sparc64: Do irq_{enter,exit}() around generic_smp_call_function*().

In reply to Jiri Slaby

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

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

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

[ Upstream commit ab5c780913bca0a5763ca05dd5c2cb5cb08ccb26 ]

Otherwise rcu_irq_{enter,exit}() do not happen and we get dumps like:

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

[  188.275021] ===============================
[  188.309351] [ INFO: suspicious RCU usage. ]
[  188.343737] 3.18.0-rc3-00068-g20f3963-dirty #54 Not tainted
[  188.394786] -------------------------------
[  188.429170] include/linux/rcupdate.h:883 rcu_read_lock() used
illegally while idle!
[  188.505235]

other info that might help us debug this:

[  188.554230]
RCU used illegally from idle CPU!
rcu_scheduler_active = 1, debug_locks = 0
[  188.637587] RCU used illegally from extended quiescent state!
[  188.690684] 3 locks held by swapper/7/0:
[  188.721932]  #0:  (&x->wait#11){......}, at: [<0000000000495de8>] complete+0x8/0x60
[  188.797994]  #1:  (&p->pi_lock){-.-.-.}, at: [<000000000048510c>] try_to_wake_up+0xc/0x400
[  188.881343]  #2:  (rcu_read_lock){......}, at: [<000000000048a910>] select_task_rq_fair+0x90/0xb40
[  188.973043]stack backtrace:
[  188.993879] CPU: 7 PID: 0 Comm: swapper/7 Not tainted 3.18.0-rc3-00068-g20f3963-dirty #54
[  189.076187] Call Trace:
[  189.089719]  [0000000000499360] lockdep_rcu_suspicious+0xe0/0x100
[  189.147035]  [000000000048a99c] select_task_rq_fair+0x11c/0xb40
[  189.202253]  [00000000004852d8] try_to_wake_up+0x1d8/0x400
[  189.252258]  [000000000048554c] default_wake_function+0xc/0x20
[  189.306435]  [0000000000495554] __wake_up_common+0x34/0x80
[  189.356448]  [00000000004955b4] __wake_up_locked+0x14/0x40
[  189.406456]  [0000000000495e08] complete+0x28/0x60
[  189.448142]  [0000000000636e28] blk_end_sync_rq+0x8/0x20
[  189.496057]  [0000000000639898] __blk_mq_end_request+0x18/0x60
[  189.550249]  [00000000006ee014] scsi_end_request+0x94/0x180
[  189.601286]  [00000000006ee334] scsi_io_completion+0x1d4/0x600
[  189.655463]  [00000000006e51c4] scsi_finish_command+0xc4/0xe0
[  189.708598]  [00000000006ed958] scsi_softirq_done+0x118/0x140
[  189.761735]  [00000000006398ec] __blk_mq_complete_request_remote+0xc/0x20
[  189.827383]  [00000000004c75d0] generic_smp_call_function_single_interrupt+0x150/0x1c0
[  189.906581]  [000000000043e514] smp_call_function_single_client+0x14/0x40

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

Based almost entirely upon a patch by Paul E. McKenney.

---
 arch/sparc/kernel/smp_64.c | 4 ++++
 1 file changed, 4 insertions(+)
arch/sparc/kernel/smp_64.c +4 -0
index 2b4e03e9cd4b..226ff1af1d26 100644
@@ -822,13 +822,17 @@ void arch_send_call_function_single_ipi(int cpu)
 void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs)
 {
 	clear_softint(1 << irq);
+	irq_enter();
 	generic_smp_call_function_interrupt();
+	irq_exit();
 }
 
 void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs)
 {
 	clear_softint(1 << irq);
+	irq_enter();
 	generic_smp_call_function_single_interrupt();
+	irq_exit();
 }
 
 static void tsb_sync(void *info)
Signature · 1 line
2.1.3
author
#15 lore raw

PATCH 15/101 sparc32: Implement xchg and atomic_xchg using ATOMIC_HASH locks

In reply to Jiri Slaby

From: Andreas Larsson <[email protected]>

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

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

[ Upstream commit 1a17fdc4f4ed06b63fac1937470378a5441a663a ]

Atomicity between xchg and cmpxchg cannot be guaranteed when xchg is implemented with a swap and cmpxchg is implemented with locks. Without this, e.g. mcs_spin_lock and mcs_spin_unlock are broken.

---
 arch/sparc/include/asm/atomic_32.h  |  2 +-
 arch/sparc/include/asm/cmpxchg_32.h | 12 ++----------
 arch/sparc/lib/atomic32.c           | 27 +++++++++++++++++++++++++++
 3 files changed, 30 insertions(+), 11 deletions(-)
arch/sparc/include/asm/atomic_32.h +1 -1
index 905832aa9e9e..a0ed182ae73c 100644
@@ -21,7 +21,7 @@
 
 extern int __atomic_add_return(int, atomic_t *);
 extern int atomic_cmpxchg(atomic_t *, int, int);
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+extern int atomic_xchg(atomic_t *, int);
 extern int __atomic_add_unless(atomic_t *, int, int);
 extern void atomic_set(atomic_t *, int);
 
arch/sparc/include/asm/cmpxchg_32.h +2 -10
index 1fae1a02e3c2..ae0f9a7a314d 100644
@@ -11,22 +11,14 @@
 #ifndef __ARCH_SPARC_CMPXCHG__
 #define __ARCH_SPARC_CMPXCHG__
 
-static inline unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned long val)
-{
-	__asm__ __volatile__("swap [%2], %0"
-			     : "=&r" (val)
-			     : "0" (val), "r" (m)
-			     : "memory");
-	return val;
-}
-
+extern unsigned long __xchg_u32(volatile u32 *m, u32 new);
 extern void __xchg_called_with_bad_pointer(void);
 
 static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size)
 {
 	switch (size) {
 	case 4:
-		return xchg_u32(ptr, x);
+		return __xchg_u32(ptr, x);
 	}
 	__xchg_called_with_bad_pointer();
 	return x;
arch/sparc/lib/atomic32.c +27 -0
index 1d32b54089aa..8f2f94d53434 100644
@@ -40,6 +40,19 @@ int __atomic_add_return(int i, atomic_t *v)
 }
 EXPORT_SYMBOL(__atomic_add_return);
 
+int atomic_xchg(atomic_t *v, int new)
+{
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(ATOMIC_HASH(v), flags);
+	ret = v->counter;
+	v->counter = new;
+	spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
+	return ret;
+}
+EXPORT_SYMBOL(atomic_xchg);
+
 int atomic_cmpxchg(atomic_t *v, int old, int new)
 {
 	int ret;
@@ -132,3 +145,17 @@ unsigned long __cmpxchg_u32(volatile u32 *ptr, u32 old, u32 new)
 	return (unsigned long)prev;
 }
 EXPORT_SYMBOL(__cmpxchg_u32);
+
+unsigned long __xchg_u32(volatile u32 *ptr, u32 new)
+{
+	unsigned long flags;
+	u32 prev;
+
+	spin_lock_irqsave(ATOMIC_HASH(ptr), flags);
+	prev = *ptr;
+	*ptr = new;
+	spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags);
+
+	return (unsigned long)prev;
+}
+EXPORT_SYMBOL(__xchg_u32);
Signature · 1 line
2.1.3
author
#16 lore raw

PATCH 16/101 hwrng: pseries - Return errors to upper levels in pseries-rng.c

In reply to Jiri Slaby

From: Michael Ellerman <[email protected]>

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

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

commit d319fe2a0af3509f959d5195fb8916accbf14857 upstream.

We don't expect to get errors from the hypervisor when reading the rng, but if we do we should pass the error up to the hwrng driver. Otherwise the hwrng driver will continue calling us forever.

---
 drivers/char/hw_random/pseries-rng.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)
drivers/char/hw_random/pseries-rng.c +11 -3
index 5f1197929f0c..b761459a3436 100644
@@ -17,6 +17,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/hw_random.h>
 #include <asm/vio.h>
@@ -25,10 +28,15 @@
 
 static int pseries_rng_data_read(struct hwrng *rng, u32 *data)
 {
-	if (plpar_hcall(H_RANDOM, (unsigned long *)data) != H_SUCCESS) {
-		printk(KERN_ERR "pseries rng hcall error\n");
-		return 0;
+	int rc;
+
+	rc = plpar_hcall(H_RANDOM, (unsigned long *)data);
+	if (rc != H_SUCCESS) {
+		pr_err_ratelimited("H_RANDOM call failed %d\n", rc);
+		return -EIO;
 	}
+
+	/* The hypervisor interface returns 64 bits */
 	return 8;
 }
 
Signature · 1 line
2.1.3
author
#17 lore raw

PATCH 17/101 iwlwifi: configure the LTR

In reply to Jiri Slaby

From: Emmanuel Grumbach <[email protected]>

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

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

commit 9180ac50716a097a407c6d7e7e4589754a922260 upstream.

The LTR is the handshake between the device and the root complex about the latency allowed when the bus exits power save. This configuration was missing and this led to high latency in the link power up. The end user could experience high latency in the network because of this.

---
 drivers/net/wireless/iwlwifi/iwl-trans.h        |  2 ++
 drivers/net/wireless/iwlwifi/mvm/fw-api-power.h | 35 ++++++++++++++++++++++++-
 drivers/net/wireless/iwlwifi/mvm/fw-api.h       |  1 +
 drivers/net/wireless/iwlwifi/mvm/fw.c           |  9 +++++++
 drivers/net/wireless/iwlwifi/mvm/ops.c          |  1 +
 drivers/net/wireless/iwlwifi/pcie/trans.c       | 16 ++++++-----
 6 files changed, 56 insertions(+), 8 deletions(-)
drivers/net/wireless/iwlwifi/iwl-trans.h +2 -0
index 80b47508647c..c8d1e378f631 100644
@@ -484,6 +484,7 @@ enum iwl_trans_state {
  *	Set during transport allocation.
  * @hw_id_str: a string with info about HW ID. Set during transport allocation.
  * @pm_support: set to true in start_hw if link pm is supported
+ * @ltr_enabled: set to true if the LTR is enabled
  * @dev_cmd_pool: pool for Tx cmd allocation - for internal use only.
  *	The user should use iwl_trans_{alloc,free}_tx_cmd.
  * @dev_cmd_headroom: room needed for the transport's private use before the
@@ -508,6 +509,7 @@ struct iwl_trans {
 	u8 rx_mpdu_cmd, rx_mpdu_cmd_hdr_size;
 
 	bool pm_support;
+	bool ltr_enabled;
 
 	/* The following fields are internal only */
 	struct kmem_cache *dev_cmd_pool;
drivers/net/wireless/iwlwifi/mvm/fw-api-power.h +34 -1
index 8e7ab41079ca..4dacb20bf490 100644
@@ -66,13 +66,46 @@
 
 /* Power Management Commands, Responses, Notifications */
 
+/**
+ * enum iwl_ltr_config_flags - masks for LTR config command flags
+ * @LTR_CFG_FLAG_FEATURE_ENABLE: Feature operational status
+ * @LTR_CFG_FLAG_HW_DIS_ON_SHADOW_REG_ACCESS: allow LTR change on shadow
+ *	memory access
+ * @LTR_CFG_FLAG_HW_EN_SHRT_WR_THROUGH: allow LTR msg send on ANY LTR
+ *	reg change
+ * @LTR_CFG_FLAG_HW_DIS_ON_D0_2_D3: allow LTR msg send on transition from
+ *	D0 to D3
+ * @LTR_CFG_FLAG_SW_SET_SHORT: fixed static short LTR register
+ * @LTR_CFG_FLAG_SW_SET_LONG: fixed static short LONG register
+ * @LTR_CFG_FLAG_DENIE_C10_ON_PD: allow going into C10 on PD
+ */
+enum iwl_ltr_config_flags {
+	LTR_CFG_FLAG_FEATURE_ENABLE = BIT(0),
+	LTR_CFG_FLAG_HW_DIS_ON_SHADOW_REG_ACCESS = BIT(1),
+	LTR_CFG_FLAG_HW_EN_SHRT_WR_THROUGH = BIT(2),
+	LTR_CFG_FLAG_HW_DIS_ON_D0_2_D3 = BIT(3),
+	LTR_CFG_FLAG_SW_SET_SHORT = BIT(4),
+	LTR_CFG_FLAG_SW_SET_LONG = BIT(5),
+	LTR_CFG_FLAG_DENIE_C10_ON_PD = BIT(6),
+};
+
+/**
+ * struct iwl_ltr_config_cmd - configures the LTR
+ * @flags: See %enum iwl_ltr_config_flags
+ */
+struct iwl_ltr_config_cmd {
+	__le32 flags;
+	__le32 static_long;
+	__le32 static_short;
+} __packed;
+
 /* Radio LP RX Energy Threshold measured in dBm */
 #define POWER_LPRX_RSSI_THRESHOLD	75
 #define POWER_LPRX_RSSI_THRESHOLD_MAX	94
 #define POWER_LPRX_RSSI_THRESHOLD_MIN	30
 
 /**
- * enum iwl_scan_flags - masks for power table command flags
+ * enum iwl_power_flags - masks for power table command flags
  * @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off
  *		receiver and transmitter. '0' - does not allow.
  * @POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK: '0' Driver disables power management,
drivers/net/wireless/iwlwifi/mvm/fw-api.h +1 -0
index 66264cc5a016..cd59ae18ea8f 100644
@@ -138,6 +138,7 @@ enum {
 
 	/* Power - legacy power table command */
 	POWER_TABLE_CMD = 0x77,
+	LTR_CONFIG = 0xee,
 
 	/* Thermal Throttling*/
 	REPLY_THERMAL_MNG_BACKOFF = 0x7e,
drivers/net/wireless/iwlwifi/mvm/fw.c +9 -0
index c76299a3a1e0..08f12006ca77 100644
@@ -424,6 +424,15 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
 			goto error;
 	}
 
+	if (mvm->trans->ltr_enabled) {
+		struct iwl_ltr_config_cmd cmd = {
+			.flags = cpu_to_le32(LTR_CFG_FLAG_FEATURE_ENABLE),
+		};
+
+		WARN_ON(iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0,
+					     sizeof(cmd), &cmd));
+	}
+
 	IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
 	return 0;
  error:
drivers/net/wireless/iwlwifi/mvm/ops.c +1 -0
index 1fd08baa0d32..e3cdc97380d3 100644
@@ -303,6 +303,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
 	CMD(REPLY_BEACON_FILTERING_CMD),
 	CMD(REPLY_THERMAL_MNG_BACKOFF),
 	CMD(MAC_PM_POWER_TABLE),
+	CMD(LTR_CONFIG),
 };
 #undef CMD
 
drivers/net/wireless/iwlwifi/pcie/trans.c +9 -7
index dc875f4befef..67536a26df39 100644
@@ -121,6 +121,7 @@ static void iwl_pcie_apm_config(struct iwl_trans *trans)
 {
 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 	u16 lctl;
+	u16 cap;
 
 	/*
 	 * HW bug W/A for instability in PCIe bus L0S->L1 transition.
@@ -131,16 +132,17 @@ static void iwl_pcie_apm_config(struct iwl_trans *trans)
 	 *    power savings, even without L1.
 	 */
 	pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_LNKCTL, &lctl);
-	if (lctl & PCI_EXP_LNKCTL_ASPM_L1) {
-		/* L1-ASPM enabled; disable(!) L0S */
+	if (lctl & PCI_EXP_LNKCTL_ASPM_L1)
 		iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
-		dev_info(trans->dev, "L1 Enabled; Disabling L0S\n");
-	} else {
-		/* L1-ASPM disabled; enable(!) L0S */
+	else
 		iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
-		dev_info(trans->dev, "L1 Disabled; Enabling L0S\n");
-	}
 	trans->pm_support = !(lctl & PCI_EXP_LNKCTL_ASPM_L0S);
+
+	pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_DEVCTL2, &cap);
+	trans->ltr_enabled = cap & PCI_EXP_DEVCTL2_LTR_EN;
+	dev_info(trans->dev, "L1 %sabled - LTR %sabled\n",
+		 (lctl & PCI_EXP_LNKCTL_ASPM_L1) ? "En" : "Dis",
+		 trans->ltr_enabled ? "En" : "Dis");
 }
 
 /*
Signature · 1 line
2.1.3
author
#18 lore raw

PATCH 18/101 zram: avoid kunmap_atomic() of a NULL pointer

In reply to Jiri Slaby

From: Weijie Yang <[email protected]>

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

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

commit c406515239376fc93a30d5d03192182160cbd3fb upstream.

zram could kunmap_atomic() a NULL pointer in a rare situation: a zram page becomes a full-zeroed page after a partial write io. The current code doesn't handle this case and performs kunmap_atomic() on a NULL pointer, which panics the kernel.

This patch fixes this issue.

---
 drivers/staging/zram/zram_drv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/staging/zram/zram_drv.c +2 -1
index d02088f7dc33..162e01a27d40 100644
@@ -430,7 +430,8 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
 	}
 
 	if (page_zero_filled(uncmem)) {
-		kunmap_atomic(user_mem);
+		if (user_mem)
+			kunmap_atomic(user_mem);
 		/* Free memory associated with this sector now. */
 		zram_free_page(zram, index);
 
Signature · 1 line
2.1.3
author
#19 lore raw

PATCH 19/101 crypto: caam - remove duplicated sg copy functions

In reply to Jiri Slaby

From: Cristian Stoica <[email protected]>

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

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

commit 307fd543f3d23f8f56850eca1b27b1be2fe71017 upstream.

Replace equivalent (and partially incorrect) scatter-gather functions with ones from crypto-API.

The replacement is motivated by page-faults in sg_copy_part triggered by successive calls to crypto_hash_update. The following fault appears after calling crypto_ahash_update twice, first with 13 and then with 285 bytes:

Unable to handle kernel paging request for data at address 0x00000008
Faulting instruction address: 0xf9bf9a8c
Oops: Kernel access of bad area, sig: 11 [#1]
SMP NR_CPUS=8 CoreNet Generic
Modules linked in: tcrypt(+) caamhash caam_jr caam tls
CPU: 6 PID: 1497 Comm: cryptomgr_test Not tainted

3.12.19-rt30-QorIQ-SDK-V1.6+g9fda9f2 #75
task: e9308530 ti: e700e000 task.ti: e700e000
NIP: f9bf9a8c LR: f9bfcf28 CTR: c0019ea0
REGS: e700fb80 TRAP: 0300 Not tainted
(3.12.19-rt30-QorIQ-SDK-V1.6+g9fda9f2)
MSR: 00029002 <CE,EE,ME> CR: 44f92024 XER: 20000000
DEAR: 00000008, ESR: 00000000

GPR00: f9bfcf28 e700fc30 e9308530 e70b1e55 00000000 ffffffdd e70b1e54 0bebf888
GPR08: 902c7ef5 c0e771e2 00000002 00000888 c0019ea0 00000000 00000000 c07a4154
GPR16: c08d0000 e91a8f9c 00000001 e98fb400 00000100 e9c83028 e70b1e08 e70b1d48
GPR24: e992ce10 e70b1dc8 f9bfe4f4 e70b1e55 ffffffdd e70b1ce0 00000000 00000000 NIP [f9bf9a8c] sg_copy+0x1c/0x100 [caamhash]
LR [f9bfcf28] ahash_update_no_ctx+0x628/0x660 [caamhash]

Call Trace:
[e700fc30] [f9bf9c50] sg_copy_part+0xe0/0x160 [caamhash] (unreliable)
[e700fc50] [f9bfcf28] ahash_update_no_ctx+0x628/0x660 [caamhash]
[e700fcb0] [f954e19c] crypto_tls_genicv+0x13c/0x300 [tls]
[e700fd10] [f954e65c] crypto_tls_encrypt+0x5c/0x260 [tls]
[e700fd40] [c02250ec] __test_aead.constprop.9+0x2bc/0xb70
[e700fe40] [c02259f0] alg_test_aead+0x50/0xc0
[e700fe60] [c02241e4] alg_test+0x114/0x2e0
[e700fee0] [c022276c] cryptomgr_test+0x4c/0x60
[e700fef0] [c004f658] kthread+0x98/0xa0
[e700ff40] [c000fd04] ret_from_kernel_thread+0x5c/0x64
---
 drivers/crypto/caam/caamhash.c   | 22 ++++++++++++++--------
 drivers/crypto/caam/sg_sw_sec4.h | 38 --------------------------------------
 2 files changed, 14 insertions(+), 46 deletions(-)
drivers/crypto/caam/caamhash.c +14 -8
index e732bd962e98..af351f478b14 100644
@@ -832,8 +832,9 @@ static int ahash_update_ctx(struct ahash_request *req)
 					   edesc->sec4_sg + sec4_sg_src_index,
 					   chained);
 			if (*next_buflen) {
-				sg_copy_part(next_buf, req->src, to_hash -
-					     *buflen, req->nbytes);
+				scatterwalk_map_and_copy(next_buf, req->src,
+							 to_hash - *buflen,
+							 *next_buflen, 0);
 				state->current_buf = !state->current_buf;
 			}
 		} else {
@@ -866,7 +867,8 @@ static int ahash_update_ctx(struct ahash_request *req)
 			kfree(edesc);
 		}
 	} else if (*next_buflen) {
-		sg_copy(buf + *buflen, req->src, req->nbytes);
+		scatterwalk_map_and_copy(buf + *buflen, req->src, 0,
+					 req->nbytes, 0);
 		*buflen = *next_buflen;
 		*next_buflen = last_buflen;
 	}
@@ -1213,8 +1215,9 @@ static int ahash_update_no_ctx(struct ahash_request *req)
 		src_map_to_sec4_sg(jrdev, req->src, src_nents,
 				   edesc->sec4_sg + 1, chained);
 		if (*next_buflen) {
-			sg_copy_part(next_buf, req->src, to_hash - *buflen,
-				    req->nbytes);
+			scatterwalk_map_and_copy(next_buf, req->src,
+						 to_hash - *buflen,
+						 *next_buflen, 0);
 			state->current_buf = !state->current_buf;
 		}
 
@@ -1245,7 +1248,8 @@ static int ahash_update_no_ctx(struct ahash_request *req)
 			kfree(edesc);
 		}
 	} else if (*next_buflen) {
-		sg_copy(buf + *buflen, req->src, req->nbytes);
+		scatterwalk_map_and_copy(buf + *buflen, req->src, 0,
+					 req->nbytes, 0);
 		*buflen = *next_buflen;
 		*next_buflen = 0;
 	}
@@ -1402,7 +1406,8 @@ static int ahash_update_first(struct ahash_request *req)
 		}
 
 		if (*next_buflen)
-			sg_copy_part(next_buf, req->src, to_hash, req->nbytes);
+			scatterwalk_map_and_copy(next_buf, req->src, to_hash,
+						 *next_buflen, 0);
 
 		sh_len = desc_len(sh_desc);
 		desc = edesc->hw_desc;
@@ -1435,7 +1440,8 @@ static int ahash_update_first(struct ahash_request *req)
 		state->update = ahash_update_no_ctx;
 		state->finup = ahash_finup_no_ctx;
 		state->final = ahash_final_no_ctx;
-		sg_copy(next_buf, req->src, req->nbytes);
+		scatterwalk_map_and_copy(next_buf, req->src, 0,
+					 req->nbytes, 0);
 	}
 #ifdef DEBUG
 	print_hex_dump(KERN_ERR, "next buf@"__stringify(__LINE__)": ",
drivers/crypto/caam/sg_sw_sec4.h +0 -38
index e0037c8ee243..ce28a563effc 100644
@@ -116,41 +116,3 @@ static int dma_unmap_sg_chained(struct device *dev, struct scatterlist *sg,
 	}
 	return nents;
 }
-
-/* Copy from len bytes of sg to dest, starting from beginning */
-static inline void sg_copy(u8 *dest, struct scatterlist *sg, unsigned int len)
-{
-	struct scatterlist *current_sg = sg;
-	int cpy_index = 0, next_cpy_index = current_sg->length;
-
-	while (next_cpy_index < len) {
-		memcpy(dest + cpy_index, (u8 *) sg_virt(current_sg),
-		       current_sg->length);
-		current_sg = scatterwalk_sg_next(current_sg);
-		cpy_index = next_cpy_index;
-		next_cpy_index += current_sg->length;
-	}
-	if (cpy_index < len)
-		memcpy(dest + cpy_index, (u8 *) sg_virt(current_sg),
-		       len - cpy_index);
-}
-
-/* Copy sg data, from to_skip to end, to dest */
-static inline void sg_copy_part(u8 *dest, struct scatterlist *sg,
-				      int to_skip, unsigned int end)
-{
-	struct scatterlist *current_sg = sg;
-	int sg_index, cpy_index;
-
-	sg_index = current_sg->length;
-	while (sg_index <= to_skip) {
-		current_sg = scatterwalk_sg_next(current_sg);
-		sg_index += current_sg->length;
-	}
-	cpy_index = sg_index - to_skip;
-	memcpy(dest, (u8 *) sg_virt(current_sg) +
-	       current_sg->length - cpy_index, cpy_index);
-	current_sg = scatterwalk_sg_next(current_sg);
-	if (end - sg_index)
-		sg_copy(dest + cpy_index, current_sg, end - sg_index);
-}
Signature · 1 line
2.1.3
author
#20 lore raw

PATCH 20/101 hwrng: pseries - port to new read API and fix stack corruption

In reply to Jiri Slaby

From: Greg Kurz <[email protected]>

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

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

commit 24c65bc7037e7d0f362c0df70d17dd72ee64b8b9 upstream.

The add_early_randomness() function in drivers/char/hw_random/core.c passes a 16-byte buffer to pseries_rng_data_read(). Unfortunately, plpar_hcall() returns four 64-bit values and trashes 16 bytes on the stack.

This bug has been lying around for a long time. It got unveiled by:

commit d3cc7996473a7bdd33256029988ea690754e4e2a

Author: Amit Shah <[email protected]>
Date:   Thu Jul 10 15:42:34 2014 +0530

hwrng: fetch randomness only after device init

It may trig a oops while loading or unloading the pseries-rng module for both PowerVM and PowerKVM guests.

This patch does two things:
- pass an intermediate well sized buffer to plpar_hcall(). This is acceptalbe since we're not on a hot path.
- move to the new read API so that we know the return buffer size for sure.

---
 drivers/char/hw_random/pseries-rng.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/char/hw_random/pseries-rng.c +7 -4
index b761459a3436..ab11c16352f8 100644
@@ -26,18 +26,21 @@
 
 #define MODULE_NAME "pseries-rng"
 
-static int pseries_rng_data_read(struct hwrng *rng, u32 *data)
+static int pseries_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
 {
+	u64 buffer[PLPAR_HCALL_BUFSIZE];
+	size_t size = max < 8 ? max : 8;
 	int rc;
 
-	rc = plpar_hcall(H_RANDOM, (unsigned long *)data);
+	rc = plpar_hcall(H_RANDOM, (unsigned long *)buffer);
 	if (rc != H_SUCCESS) {
 		pr_err_ratelimited("H_RANDOM call failed %d\n", rc);
 		return -EIO;
 	}
+	memcpy(data, buffer, size);
 
 	/* The hypervisor interface returns 64 bits */
-	return 8;
+	return size;
 }
 
 /**
@@ -56,7 +59,7 @@ static unsigned long pseries_rng_get_desired_dma(struct vio_dev *vdev)
 
 static struct hwrng pseries_rng = {
 	.name		= MODULE_NAME,
-	.data_read	= pseries_rng_data_read,
+	.read		= pseries_rng_read,
 };
 
 static int __init pseries_rng_probe(struct vio_dev *dev,
Signature · 1 line
2.1.3
author
#21 lore raw

PATCH 21/101 tun: Fix csum_start with VLAN acceleration

In reply to Jiri Slaby

From: Herbert Xu <[email protected]>

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

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

commit a8f9bfdf982e2b1fb9f094e4de9ab08c57f3d2fd upstream.

When VLAN acceleration is in use on the xmit path, we end up setting csum_start to the wrong place. The result is that the whoever ends up doing the checksum setting will corrupt the packet instead of writing the checksum to the expected location, usually this means writing the checksum with an offset of -4.

This patch fixes this by adjusting csum_start when VLAN acceleration is detected.

Fixes 6680ec68eff4 ("tuntap: hardware vlan tx support")
---
 drivers/net/tun.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)
drivers/net/tun.c +9 -7
index 495830a8ee28..d72d06301642 100644
@@ -1189,6 +1189,10 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 	struct tun_pi pi = { 0, skb->protocol };
 	ssize_t total = 0;
 	int vlan_offset = 0, copied;
+	int vlan_hlen = 0;
+
+	if (vlan_tx_tag_present(skb))
+		vlan_hlen = VLAN_HLEN;
 
 	if (!(tun->flags & TUN_NO_PI)) {
 		if ((len -= sizeof(pi)) < 0)
@@ -1240,7 +1244,8 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 
 		if (skb->ip_summed == CHECKSUM_PARTIAL) {
 			gso.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
-			gso.csum_start = skb_checksum_start_offset(skb);
+			gso.csum_start = skb_checksum_start_offset(skb) +
+					 vlan_hlen;
 			gso.csum_offset = skb->csum_offset;
 		} else if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
 			gso.flags = VIRTIO_NET_HDR_F_DATA_VALID;
@@ -1253,10 +1258,9 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 	}
 
 	copied = total;
-	total += skb->len;
-	if (!vlan_tx_tag_present(skb)) {
-		len = min_t(int, skb->len, len);
-	} else {
+	len = min_t(int, skb->len + vlan_hlen, len);
+	total += skb->len + vlan_hlen;
+	if (vlan_hlen) {
 		int copy, ret;
 		struct {
 			__be16 h_vlan_proto;
@@ -1267,8 +1271,6 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 		veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb));
 
 		vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto);
-		len = min_t(int, skb->len + VLAN_HLEN, len);
-		total += VLAN_HLEN;
 
 		copy = min_t(int, vlan_offset, len);
 		ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy);
Signature · 1 line
2.1.3
author
#22 lore raw

PATCH 22/101 x86, x32, audit: Fix x32's AUDIT_ARCH wrt audit

In reply to Jiri Slaby

From: Andy Lutomirski <[email protected]>

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

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

commit 81f49a8fd7088cfcb588d182eeede862c0e3303e upstream.

is_compat_task() is the wrong check for audit arch; the check should be is_ia32_task(): x32 syscalls should be AUDIT_ARCH_X86_64, not AUDIT_ARCH_I386.

CONFIG_AUDITSYSCALL is currently incompatible with x32, so this has no visible effect.

---
 arch/x86/kernel/ptrace.c | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)
arch/x86/kernel/ptrace.c +1 -10
index 7461f50d5bb1..0686fe313b3b 100644
@@ -1441,15 +1441,6 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
 	force_sig_info(SIGTRAP, &info, tsk);
 }
 
-
-#ifdef CONFIG_X86_32
-# define IS_IA32	1
-#elif defined CONFIG_IA32_EMULATION
-# define IS_IA32	is_compat_task()
-#else
-# define IS_IA32	0
-#endif
-
 /*
  * We must return the syscall number to actually look up in the table.
  * This can be -1L to skip running any syscall at all.
@@ -1487,7 +1478,7 @@ long syscall_trace_enter(struct pt_regs *regs)
 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
 		trace_sys_enter(regs, regs->orig_ax);
 
-	if (IS_IA32)
+	if (is_ia32_task())
 		audit_syscall_entry(AUDIT_ARCH_I386,
 				    regs->orig_ax,
 				    regs->bx, regs->cx,
Signature · 1 line
2.1.3
author
#23 lore raw

PATCH 23/101 audit: keep inode pinned

In reply to Jiri Slaby

From: Miklos Szeredi <[email protected]>

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

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

commit 799b601451b21ebe7af0e6e8f6e2ccd4683c5064 upstream.

Audit rules disappear when an inode they watch is evicted from the cache. This is likely not what we want.

The guilty commit is "fsnotify: allow marks to not pin inodes in core", which didn't take into account that audit_tree adds watches with a zero mask.

Adding any mask should fix this.

Fixes 90b1e7a57880 ("fsnotify: allow marks to not pin inodes in core")
---
 kernel/audit_tree.c | 1 +
 1 file changed, 1 insertion(+)
kernel/audit_tree.c +1 -0
index 43c307dc9453..00c4459f76df 100644
@@ -154,6 +154,7 @@ static struct audit_chunk *alloc_chunk(int count)
 		chunk->owners[i].index = i;
 	}
 	fsnotify_init_mark(&chunk->mark, audit_tree_destroy_watch);
+	chunk->mark.mask = FS_IN_IGNORED;
 	return chunk;
 }
 
Signature · 1 line
2.1.3
author
#24 lore raw

PATCH 24/101 ahci: Add Device IDs for Intel Sunrise Point PCH

In reply to Jiri Slaby

From: James Ralston <[email protected]>

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

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

commit 690000b930456a98663567d35dd5c54b688d1e3f upstream.

This patch adds the AHCI-mode SATA Device IDs for the Intel Sunrise Point PCH.

---
 drivers/ata/ahci.c | 5 +++++
 1 file changed, 5 insertions(+)
drivers/ata/ahci.c +5 -0
index a875de67fb7c..0fc168c3a574 100644
@@ -312,6 +312,11 @@ static const struct pci_device_id ahci_pci_tbl[] = {
 	{ PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */
 	{ PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */
 	{ PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */
+	{ PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */
+	{ PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H RAID */
+	{ PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */
+	{ PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */
+	{ PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
 
 	/* JMicron 360/1/3/5/6, match class to avoid IDE function */
 	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
Signature · 1 line
2.1.3
author
#25 lore raw

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

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 66a7cbc303f4d28f201529b06061944d51ab530c upstream.

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

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

PATCH 26/101 ALSA: usb-audio: Fix memory leak in FTU quirk

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

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

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

commit 1a290581ded60e87276741f8ca97b161d2b226fc upstream.

M-audio FastTrack Ultra quirk doesn't release the kzalloc'ed memory. This patch adds the private_free callback to release it properly.

---
 sound/usb/mixer_quirks.c | 6 ++++++
 1 file changed, 6 insertions(+)
sound/usb/mixer_quirks.c +6 -0
index d42a584cf829..ea4b9a8a90bd 100644
@@ -802,6 +802,11 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl,
 	return changed;
 }
 
+static void kctl_private_value_free(struct snd_kcontrol *kctl)
+{
+	kfree((void *)kctl->private_value);
+}
+
 static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer,
 	int validx, int bUnitID)
 {
@@ -836,6 +841,7 @@ static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer,
 		return -ENOMEM;
 	}
 
+	kctl->private_free = kctl_private_value_free;
 	err = snd_ctl_add(mixer->chip->card, kctl);
 	if (err < 0)
 		return err;
Signature · 1 line
2.1.3
author
#27 lore raw

PATCH 27/101 xtensa: re-wire umount syscall to sys_oldumount

In reply to Jiri Slaby

From: Max Filippov <[email protected]>

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

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

commit 2651cc6974d47fc43bef1cd8cd26966e4f5ba306 upstream.

Userspace actually passes single parameter (path name) to the umount syscall, so new umount just fails. Fix it by requesting old umount syscall implementation and re-wiring umount to it.

---
 arch/xtensa/include/uapi/asm/unistd.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/xtensa/include/uapi/asm/unistd.h +2 -1
index 51940fec6990..513effd48060 100644
@@ -384,7 +384,8 @@ __SYSCALL(174, sys_chroot, 1)
 #define __NR_pivot_root 			175
 __SYSCALL(175, sys_pivot_root, 2)
 #define __NR_umount 				176
-__SYSCALL(176, sys_umount, 2)
+__SYSCALL(176, sys_oldumount, 1)
+#define __ARCH_WANT_SYS_OLDUMOUNT
 #define __NR_swapoff 				177
 __SYSCALL(177, sys_swapoff, 1)
 #define __NR_sync 				178
Signature · 1 line
2.1.3
author
#28 lore raw

PATCH 28/101 libceph: do not crash on large auth tickets

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

Large (greater than 32k, the value of PAGE_ALLOC_COSTLY_ORDER) auth tickets will have their buffers vmalloc'ed, which leads to the following crash in crypto:

[   28.685082] BUG: unable to handle kernel paging request at ffffeb04000032c0
[   28.686032] IP: [<ffffffff81392b42>] scatterwalk_pagedone+0x22/0x80
[   28.686032] PGD 0
[   28.688088] Oops: 0000 [#1] PREEMPT SMP
[   28.688088] Modules linked in:
[   28.688088] CPU: 0 PID: 878 Comm: kworker/0:2 Not tainted 3.17.0-vm+ #305
[   28.688088] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007
[   28.688088] Workqueue: ceph-msgr con_work
[   28.688088] task: ffff88011a7f9030 ti: ffff8800d903c000 task.ti: ffff8800d903c000
[   28.688088] RIP: 0010:[<ffffffff81392b42>]  [<ffffffff81392b42>] scatterwalk_pagedone+0x22/0x80
[   28.688088] RSP: 0018:ffff8800d903f688  EFLAGS: 00010286
[   28.688088] RAX: ffffeb04000032c0 RBX: ffff8800d903f718 RCX: ffffeb04000032c0
[   28.688088] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff8800d903f750
[   28.688088] RBP: ffff8800d903f688 R08: 00000000000007de R09: ffff8800d903f880
[   28.688088] R10: 18df467c72d6257b R11: 0000000000000000 R12: 0000000000000010
[   28.688088] R13: ffff8800d903f750 R14: ffff8800d903f8a0 R15: 0000000000000000
[   28.688088] FS:  00007f50a41c7700(0000) GS:ffff88011fc00000(0000) knlGS:0000000000000000
[   28.688088] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[   28.688088] CR2: ffffeb04000032c0 CR3: 00000000da3f3000 CR4: 00000000000006b0
[   28.688088] Stack:
[   28.688088]  ffff8800d903f698 ffffffff81392ca8 ffff8800d903f6e8 ffffffff81395d32
[   28.688088]  ffff8800dac96000 ffff880000000000 ffff8800d903f980 ffff880119b7e020
[   28.688088]  ffff880119b7e010 0000000000000000 0000000000000010 0000000000000010
[   28.688088] Call Trace:
[   28.688088]  [<ffffffff81392ca8>] scatterwalk_done+0x38/0x40
[   28.688088]  [<ffffffff81392ca8>] scatterwalk_done+0x38/0x40
[   28.688088]  [<ffffffff81395d32>] blkcipher_walk_done+0x182/0x220
[   28.688088]  [<ffffffff813990bf>] crypto_cbc_encrypt+0x15f/0x180
[   28.688088]  [<ffffffff81399780>] ? crypto_aes_set_key+0x30/0x30
[   28.688088]  [<ffffffff8156c40c>] ceph_aes_encrypt2+0x29c/0x2e0
[   28.688088]  [<ffffffff8156d2a3>] ceph_encrypt2+0x93/0xb0
[   28.688088]  [<ffffffff8156d7da>] ceph_x_encrypt+0x4a/0x60
[   28.688088]  [<ffffffff8155b39d>] ? ceph_buffer_new+0x5d/0xf0
[   28.688088]  [<ffffffff8156e837>] ceph_x_build_authorizer.isra.6+0x297/0x360
[   28.688088]  [<ffffffff8112089b>] ? kmem_cache_alloc_trace+0x11b/0x1c0
[   28.688088]  [<ffffffff8156b496>] ? ceph_auth_create_authorizer+0x36/0x80
[   28.688088]  [<ffffffff8156ed83>] ceph_x_create_authorizer+0x63/0xd0
[   28.688088]  [<ffffffff8156b4b4>] ceph_auth_create_authorizer+0x54/0x80
[   28.688088]  [<ffffffff8155f7c0>] get_authorizer+0x80/0xd0
[   28.688088]  [<ffffffff81555a8b>] prepare_write_connect+0x18b/0x2b0
[   28.688088]  [<ffffffff81559289>] try_read+0x1e59/0x1f10

This is because we set up crypto scatterlists as if all buffers were kmalloc'ed. Fix it.

---
 net/ceph/crypto.c | 169 ++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 132 insertions(+), 37 deletions(-)
net/ceph/crypto.c +132 -37
index 6e7a236525b6..06f19b9e159a 100644
@@ -89,11 +89,82 @@ static struct crypto_blkcipher *ceph_crypto_alloc_cipher(void)
 
 static const u8 *aes_iv = (u8 *)CEPH_AES_IV;
 
+/*
+ * Should be used for buffers allocated with ceph_kvmalloc().
+ * Currently these are encrypt out-buffer (ceph_buffer) and decrypt
+ * in-buffer (msg front).
+ *
+ * Dispose of @sgt with teardown_sgtable().
+ *
+ * @prealloc_sg is to avoid memory allocation inside sg_alloc_table()
+ * in cases where a single sg is sufficient.  No attempt to reduce the
+ * number of sgs by squeezing physically contiguous pages together is
+ * made though, for simplicity.
+ */
+static int setup_sgtable(struct sg_table *sgt, struct scatterlist *prealloc_sg,
+			 const void *buf, unsigned int buf_len)
+{
+	struct scatterlist *sg;
+	const bool is_vmalloc = is_vmalloc_addr(buf);
+	unsigned int off = offset_in_page(buf);
+	unsigned int chunk_cnt = 1;
+	unsigned int chunk_len = PAGE_ALIGN(off + buf_len);
+	int i;
+	int ret;
+
+	if (buf_len == 0) {
+		memset(sgt, 0, sizeof(*sgt));
+		return -EINVAL;
+	}
+
+	if (is_vmalloc) {
+		chunk_cnt = chunk_len >> PAGE_SHIFT;
+		chunk_len = PAGE_SIZE;
+	}
+
+	if (chunk_cnt > 1) {
+		ret = sg_alloc_table(sgt, chunk_cnt, GFP_NOFS);
+		if (ret)
+			return ret;
+	} else {
+		WARN_ON(chunk_cnt != 1);
+		sg_init_table(prealloc_sg, 1);
+		sgt->sgl = prealloc_sg;
+		sgt->nents = sgt->orig_nents = 1;
+	}
+
+	for_each_sg(sgt->sgl, sg, sgt->orig_nents, i) {
+		struct page *page;
+		unsigned int len = min(chunk_len - off, buf_len);
+
+		if (is_vmalloc)
+			page = vmalloc_to_page(buf);
+		else
+			page = virt_to_page(buf);
+
+		sg_set_page(sg, page, len, off);
+
+		off = 0;
+		buf += len;
+		buf_len -= len;
+	}
+	WARN_ON(buf_len != 0);
+
+	return 0;
+}
+
+static void teardown_sgtable(struct sg_table *sgt)
+{
+	if (sgt->orig_nents > 1)
+		sg_free_table(sgt);
+}
+
 static int ceph_aes_encrypt(const void *key, int key_len,
 			    void *dst, size_t *dst_len,
 			    const void *src, size_t src_len)
 {
-	struct scatterlist sg_in[2], sg_out[1];
+	struct scatterlist sg_in[2], prealloc_sg;
+	struct sg_table sg_out;
 	struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
 	struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 };
 	int ret;
@@ -109,16 +180,18 @@ static int ceph_aes_encrypt(const void *key, int key_len,
 
 	*dst_len = src_len + zero_padding;
 
-	crypto_blkcipher_setkey((void *)tfm, key, key_len);
 	sg_init_table(sg_in, 2);
 	sg_set_buf(&sg_in[0], src, src_len);
 	sg_set_buf(&sg_in[1], pad, zero_padding);
-	sg_init_table(sg_out, 1);
-	sg_set_buf(sg_out, dst, *dst_len);
+	ret = setup_sgtable(&sg_out, &prealloc_sg, dst, *dst_len);
+	if (ret)
+		goto out_tfm;
+
+	crypto_blkcipher_setkey((void *)tfm, key, key_len);
 	iv = crypto_blkcipher_crt(tfm)->iv;
 	ivsize = crypto_blkcipher_ivsize(tfm);
-
 	memcpy(iv, aes_iv, ivsize);
+
 	/*
 	print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
 		       key, key_len, 1);
@@ -127,16 +200,22 @@ static int ceph_aes_encrypt(const void *key, int key_len,
 	print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
 			pad, zero_padding, 1);
 	*/
-	ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in,
+	ret = crypto_blkcipher_encrypt(&desc, sg_out.sgl, sg_in,
 				     src_len + zero_padding);
-	crypto_free_blkcipher(tfm);
-	if (ret < 0)
+	if (ret < 0) {
 		pr_err("ceph_aes_crypt failed %d\n", ret);
+		goto out_sg;
+	}
 	/*
 	print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
 		       dst, *dst_len, 1);
 	*/
-	return 0;
+
+out_sg:
+	teardown_sgtable(&sg_out);
+out_tfm:
+	crypto_free_blkcipher(tfm);
+	return ret;
 }
 
 static int ceph_aes_encrypt2(const void *key, int key_len, void *dst,
@@ -144,7 +223,8 @@ static int ceph_aes_encrypt2(const void *key, int key_len, void *dst,
 			     const void *src1, size_t src1_len,
 			     const void *src2, size_t src2_len)
 {
-	struct scatterlist sg_in[3], sg_out[1];
+	struct scatterlist sg_in[3], prealloc_sg;
+	struct sg_table sg_out;
 	struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
 	struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 };
 	int ret;
@@ -160,17 +240,19 @@ static int ceph_aes_encrypt2(const void *key, int key_len, void *dst,
 
 	*dst_len = src1_len + src2_len + zero_padding;
 
-	crypto_blkcipher_setkey((void *)tfm, key, key_len);
 	sg_init_table(sg_in, 3);
 	sg_set_buf(&sg_in[0], src1, src1_len);
 	sg_set_buf(&sg_in[1], src2, src2_len);
 	sg_set_buf(&sg_in[2], pad, zero_padding);
-	sg_init_table(sg_out, 1);
-	sg_set_buf(sg_out, dst, *dst_len);
+	ret = setup_sgtable(&sg_out, &prealloc_sg, dst, *dst_len);
+	if (ret)
+		goto out_tfm;
+
+	crypto_blkcipher_setkey((void *)tfm, key, key_len);
 	iv = crypto_blkcipher_crt(tfm)->iv;
 	ivsize = crypto_blkcipher_ivsize(tfm);
-
 	memcpy(iv, aes_iv, ivsize);
+
 	/*
 	print_hex_dump(KERN_ERR, "enc  key: ", DUMP_PREFIX_NONE, 16, 1,
 		       key, key_len, 1);
@@ -181,23 +263,30 @@ static int ceph_aes_encrypt2(const void *key, int key_len, void *dst,
 	print_hex_dump(KERN_ERR, "enc  pad: ", DUMP_PREFIX_NONE, 16, 1,
 			pad, zero_padding, 1);
 	*/
-	ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in,
+	ret = crypto_blkcipher_encrypt(&desc, sg_out.sgl, sg_in,
 				     src1_len + src2_len + zero_padding);
-	crypto_free_blkcipher(tfm);
-	if (ret < 0)
+	if (ret < 0) {
 		pr_err("ceph_aes_crypt2 failed %d\n", ret);
+		goto out_sg;
+	}
 	/*
 	print_hex_dump(KERN_ERR, "enc  out: ", DUMP_PREFIX_NONE, 16, 1,
 		       dst, *dst_len, 1);
 	*/
-	return 0;
+
+out_sg:
+	teardown_sgtable(&sg_out);
+out_tfm:
+	crypto_free_blkcipher(tfm);
+	return ret;
 }
 
 static int ceph_aes_decrypt(const void *key, int key_len,
 			    void *dst, size_t *dst_len,
 			    const void *src, size_t src_len)
 {
-	struct scatterlist sg_in[1], sg_out[2];
+	struct sg_table sg_in;
+	struct scatterlist sg_out[2], prealloc_sg;
 	struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
 	struct blkcipher_desc desc = { .tfm = tfm };
 	char pad[16];
@@ -209,16 +298,16 @@ static int ceph_aes_decrypt(const void *key, int key_len,
 	if (IS_ERR(tfm))
 		return PTR_ERR(tfm);
 
-	crypto_blkcipher_setkey((void *)tfm, key, key_len);
-	sg_init_table(sg_in, 1);
 	sg_init_table(sg_out, 2);
-	sg_set_buf(sg_in, src, src_len);
 	sg_set_buf(&sg_out[0], dst, *dst_len);
 	sg_set_buf(&sg_out[1], pad, sizeof(pad));
+	ret = setup_sgtable(&sg_in, &prealloc_sg, src, src_len);
+	if (ret)
+		goto out_tfm;
 
+	crypto_blkcipher_setkey((void *)tfm, key, key_len);
 	iv = crypto_blkcipher_crt(tfm)->iv;
 	ivsize = crypto_blkcipher_ivsize(tfm);
-
 	memcpy(iv, aes_iv, ivsize);
 
 	/*
@@ -227,12 +316,10 @@ static int ceph_aes_decrypt(const void *key, int key_len,
 	print_hex_dump(KERN_ERR, "dec  in: ", DUMP_PREFIX_NONE, 16, 1,
 		       src, src_len, 1);
 	*/
-
-	ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len);
-	crypto_free_blkcipher(tfm);
+	ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in.sgl, src_len);
 	if (ret < 0) {
 		pr_err("ceph_aes_decrypt failed %d\n", ret);
-		return ret;
+		goto out_sg;
 	}
 
 	if (src_len <= *dst_len)
@@ -250,7 +337,12 @@ static int ceph_aes_decrypt(const void *key, int key_len,
 	print_hex_dump(KERN_ERR, "dec out: ", DUMP_PREFIX_NONE, 16, 1,
 		       dst, *dst_len, 1);
 	*/
-	return 0;
+
+out_sg:
+	teardown_sgtable(&sg_in);
+out_tfm:
+	crypto_free_blkcipher(tfm);
+	return ret;
 }
 
 static int ceph_aes_decrypt2(const void *key, int key_len,
@@ -258,7 +350,8 @@ static int ceph_aes_decrypt2(const void *key, int key_len,
 			     void *dst2, size_t *dst2_len,
 			     const void *src, size_t src_len)
 {
-	struct scatterlist sg_in[1], sg_out[3];
+	struct sg_table sg_in;
+	struct scatterlist sg_out[3], prealloc_sg;
 	struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
 	struct blkcipher_desc desc = { .tfm = tfm };
 	char pad[16];
@@ -270,17 +363,17 @@ static int ceph_aes_decrypt2(const void *key, int key_len,
 	if (IS_ERR(tfm))
 		return PTR_ERR(tfm);
 
-	sg_init_table(sg_in, 1);
-	sg_set_buf(sg_in, src, src_len);
 	sg_init_table(sg_out, 3);
 	sg_set_buf(&sg_out[0], dst1, *dst1_len);
 	sg_set_buf(&sg_out[1], dst2, *dst2_len);
 	sg_set_buf(&sg_out[2], pad, sizeof(pad));
+	ret = setup_sgtable(&sg_in, &prealloc_sg, src, src_len);
+	if (ret)
+		goto out_tfm;
 
 	crypto_blkcipher_setkey((void *)tfm, key, key_len);
 	iv = crypto_blkcipher_crt(tfm)->iv;
 	ivsize = crypto_blkcipher_ivsize(tfm);
-
 	memcpy(iv, aes_iv, ivsize);
 
 	/*
@@ -289,12 +382,10 @@ static int ceph_aes_decrypt2(const void *key, int key_len,
 	print_hex_dump(KERN_ERR, "dec   in: ", DUMP_PREFIX_NONE, 16, 1,
 		       src, src_len, 1);
 	*/
-
-	ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len);
-	crypto_free_blkcipher(tfm);
+	ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in.sgl, src_len);
 	if (ret < 0) {
 		pr_err("ceph_aes_decrypt failed %d\n", ret);
-		return ret;
+		goto out_sg;
 	}
 
 	if (src_len <= *dst1_len)
@@ -324,7 +415,11 @@ static int ceph_aes_decrypt2(const void *key, int key_len,
 		       dst2, *dst2_len, 1);
 	*/
 
-	return 0;
+out_sg:
+	teardown_sgtable(&sg_in);
+out_tfm:
+	crypto_free_blkcipher(tfm);
+	return ret;
 }
 
 
Signature · 1 line
2.1.3
author
#29 lore raw

PATCH 29/101 macvtap: Fix csum_start when VLAN tags are present

In reply to Jiri Slaby

From: Herbert Xu <[email protected]>

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

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

commit 3ce9b20f1971690b8b3b620e735ec99431573b39 upstream.

When VLAN is in use in macvtap_put_user, we end up setting csum_start to the wrong place. The result is that the whoever ends up doing the checksum setting will corrupt the packet instead of writing the checksum to the expected location, usually this means writing the checksum with an offset of -4.

This patch fixes this by adjusting csum_start when VLAN tags are detected.

Fixes f09e2249c4f5 ("macvtap: restore vlan header on user read")
---
 drivers/net/macvtap.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/net/macvtap.c +2 -0
index 4abd98efdc34..89d21fc47a16 100644
@@ -625,6 +625,8 @@ static int macvtap_skb_to_vnet_hdr(const struct sk_buff *skb,
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		vnet_hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
 		vnet_hdr->csum_start = skb_checksum_start_offset(skb);
+		if (vlan_tx_tag_present(skb))
+			vnet_hdr->csum_start += VLAN_HLEN;
 		vnet_hdr->csum_offset = skb->csum_offset;
 	} else if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
 		vnet_hdr->flags = VIRTIO_NET_HDR_F_DATA_VALID;
Signature · 1 line
2.1.3
author
#30 lore raw

PATCH 30/101 mac80211_hwsim: release driver when ieee80211_register_hw fails

In reply to Jiri Slaby

From: Junjie Mao <[email protected]>

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

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

commit 805dbe17d1c832ad341f14fae8cedf41b67ca6fa upstream.

The driver is not released when ieee80211_register_hw fails in mac80211_hwsim_create_radio, leading to the access to the unregistered (and possibly freed) device in platform_driver_unregister:

[    0.447547] mac80211_hwsim: ieee80211_register_hw failed (-2)
[    0.448292] ------------[ cut here ]------------
[    0.448854] WARNING: CPU: 0 PID: 1 at ../include/linux/kref.h:47 kobject_get+0x33/0x50()
[    0.449839] CPU: 0 PID: 1 Comm: swapper Not tainted 3.17.0-00001-gdd46990-dirty #2
[    0.450813] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
[    0.451512]  00000000 00000000 78025e38 7967c6c6 78025e68 7905e09b 7988b480 00000000
[    0.452579]  00000001 79887d62 0000002f 79170bb3 79170bb3 78397008 79ac9d74 00000001
[    0.453614]  78025e78 7905e15d 00000009 00000000 78025e84 79170bb3 78397000 78025e8c
[    0.454632] Call Trace:
[    0.454921]  [<7967c6c6>] dump_stack+0x16/0x18
[    0.455453]  [<7905e09b>] warn_slowpath_common+0x6b/0x90
[    0.456067]  [<79170bb3>] ? kobject_get+0x33/0x50
[    0.456612]  [<79170bb3>] ? kobject_get+0x33/0x50
[    0.457155]  [<7905e15d>] warn_slowpath_null+0x1d/0x20
[    0.457748]  [<79170bb3>] kobject_get+0x33/0x50
[    0.458274]  [<7925824f>] get_device+0xf/0x20
[    0.458779]  [<7925b5cd>] driver_detach+0x3d/0xa0
[    0.459331]  [<7925a3ff>] bus_remove_driver+0x8f/0xb0
[    0.459927]  [<7925bf80>] ? class_unregister+0x40/0x80
[    0.460660]  [<7925bad7>] driver_unregister+0x47/0x50
[    0.461248]  [<7925c033>] ? class_destroy+0x13/0x20
[    0.461824]  [<7925d07b>] platform_driver_unregister+0xb/0x10
[    0.462507]  [<79b51ba0>] init_mac80211_hwsim+0x3e8/0x3f9
[    0.463161]  [<79b30c58>] do_one_initcall+0x106/0x1a9
[    0.463758]  [<79b517b8>] ? if_spi_init_module+0xac/0xac
[    0.464393]  [<79b517b8>] ? if_spi_init_module+0xac/0xac
[    0.465001]  [<79071935>] ? parse_args+0x2f5/0x480
[    0.465569]  [<7906b41e>] ? __usermodehelper_set_disable_depth+0x3e/0x50
[    0.466345]  [<79b30dd9>] kernel_init_freeable+0xde/0x17d
[    0.466972]  [<79b304d6>] ? do_early_param+0x7a/0x7a
[    0.467546]  [<79677b1b>] kernel_init+0xb/0xe0
[    0.468072]  [<79075f42>] ? schedule_tail+0x12/0x40
[    0.468658]  [<79686580>] ret_from_kernel_thread+0x20/0x30
[    0.469303]  [<79677b10>] ? rest_init+0xc0/0xc0
[    0.469829] ---[ end trace ad8ac403ff8aef5c ]---
[    0.470509] ------------[ cut here ]------------
[    0.471047] WARNING: CPU: 0 PID: 1 at ../kernel/locking/lockdep.c:3161 __lock_acquire.isra.22+0x7aa/0xb00()
[    0.472163] DEBUG_LOCKS_WARN_ON(id >= MAX_LOCKDEP_KEYS)
[    0.472774] CPU: 0 PID: 1 Comm: swapper Tainted: G        W      3.17.0-00001-gdd46990-dirty #2
[    0.473815] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
[    0.474492]  78025de0 78025de0 78025da0 7967c6c6 78025dd0 7905e09b 79888931 78025dfc
[    0.475515]  00000001 79888a93 00000c59 7907f33a 7907f33a 78028000 fffe9d09 00000000
[    0.476519]  78025de8 7905e10e 00000009 78025de0 79888931 78025dfc 78025e24 7907f33a
[    0.477523] Call Trace:
[    0.477821]  [<7967c6c6>] dump_stack+0x16/0x18
[    0.478352]  [<7905e09b>] warn_slowpath_common+0x6b/0x90
[    0.478976]  [<7907f33a>] ? __lock_acquire.isra.22+0x7aa/0xb00
[    0.479658]  [<7907f33a>] ? __lock_acquire.isra.22+0x7aa/0xb00
[    0.480417]  [<7905e10e>] warn_slowpath_fmt+0x2e/0x30
[    0.480479]  [<7907f33a>] __lock_acquire.isra.22+0x7aa/0xb00
[    0.480479]  [<79078aa5>] ? sched_clock_cpu+0xb5/0xf0
[    0.480479]  [<7907fd06>] lock_acquire+0x56/0x70
[    0.480479]  [<7925b5e8>] ? driver_detach+0x58/0xa0
[    0.480479]  [<79682d11>] mutex_lock_nested+0x61/0x2a0
[    0.480479]  [<7925b5e8>] ? driver_detach+0x58/0xa0
[    0.480479]  [<7925b5e8>] ? driver_detach+0x58/0xa0
[    0.480479]  [<7925b5e8>] driver_detach+0x58/0xa0
[    0.480479]  [<7925a3ff>] bus_remove_driver+0x8f/0xb0
[    0.480479]  [<7925bf80>] ? class_unregister+0x40/0x80
[    0.480479]  [<7925bad7>] driver_unregister+0x47/0x50
[    0.480479]  [<7925c033>] ? class_destroy+0x13/0x20
[    0.480479]  [<7925d07b>] platform_driver_unregister+0xb/0x10
[    0.480479]  [<79b51ba0>] init_mac80211_hwsim+0x3e8/0x3f9
[    0.480479]  [<79b30c58>] do_one_initcall+0x106/0x1a9
[    0.480479]  [<79b517b8>] ? if_spi_init_module+0xac/0xac
[    0.480479]  [<79b517b8>] ? if_spi_init_module+0xac/0xac
[    0.480479]  [<79071935>] ? parse_args+0x2f5/0x480
[    0.480479]  [<7906b41e>] ? __usermodehelper_set_disable_depth+0x3e/0x50
[    0.480479]  [<79b30dd9>] kernel_init_freeable+0xde/0x17d
[    0.480479]  [<79b304d6>] ? do_early_param+0x7a/0x7a
[    0.480479]  [<79677b1b>] kernel_init+0xb/0xe0
[    0.480479]  [<79075f42>] ? schedule_tail+0x12/0x40
[    0.480479]  [<79686580>] ret_from_kernel_thread+0x20/0x30
[    0.480479]  [<79677b10>] ? rest_init+0xc0/0xc0
[    0.480479] ---[ end trace ad8ac403ff8aef5d ]---
[    0.495478] BUG: unable to handle kernel paging request at 00200200
[    0.496257] IP: [<79682de5>] mutex_lock_nested+0x135/0x2a0
[    0.496923] *pde = 00000000
[    0.497290] Oops: 0002 [#1]
[    0.497653] CPU: 0 PID: 1 Comm: swapper Tainted: G        W      3.17.0-00001-gdd46990-dirty #2
[    0.498659] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
[    0.499321] task: 78028000 ti: 78024000 task.ti: 78024000
[    0.499955] EIP: 0060:[<79682de5>] EFLAGS: 00010097 CPU: 0
[    0.500620] EIP is at mutex_lock_nested+0x135/0x2a0
[    0.501145] EAX: 00200200 EBX: 78397434 ECX: 78397460 EDX: 78025e70
[    0.501816] ESI: 00000246 EDI: 78028000 EBP: 78025e8c ESP: 78025e54
[    0.502497]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
[    0.503076] CR0: 8005003b CR2: 00200200 CR3: 01b9d000 CR4: 00000690
[    0.503773] Stack:
[    0.503998]  00000000 00000001 00000000 7925b5e8 78397460 7925b5e8 78397474 78397460
[    0.504944]  00200200 11111111 78025e70 78397000 79ac9d74 00000001 78025ea0 7925b5e8
[    0.505451]  79ac9d74 fffffffe 00000001 78025ebc 7925a3ff 7a251398 78025ec8 7925bf80
[    0.505451] Call Trace:
[    0.505451]  [<7925b5e8>] ? driver_detach+0x58/0xa0
[    0.505451]  [<7925b5e8>] ? driver_detach+0x58/0xa0
[    0.505451]  [<7925b5e8>] driver_detach+0x58/0xa0
[    0.505451]  [<7925a3ff>] bus_remove_driver+0x8f/0xb0
[    0.505451]  [<7925bf80>] ? class_unregister+0x40/0x80
[    0.505451]  [<7925bad7>] driver_unregister+0x47/0x50
[    0.505451]  [<7925c033>] ? class_destroy+0x13/0x20
[    0.505451]  [<7925d07b>] platform_driver_unregister+0xb/0x10
[    0.505451]  [<79b51ba0>] init_mac80211_hwsim+0x3e8/0x3f9
[    0.505451]  [<79b30c58>] do_one_initcall+0x106/0x1a9
[    0.505451]  [<79b517b8>] ? if_spi_init_module+0xac/0xac
[    0.505451]  [<79b517b8>] ? if_spi_init_module+0xac/0xac
[    0.505451]  [<79071935>] ? parse_args+0x2f5/0x480
[    0.505451]  [<7906b41e>] ? __usermodehelper_set_disable_depth+0x3e/0x50
[    0.505451]  [<79b30dd9>] kernel_init_freeable+0xde/0x17d
[    0.505451]  [<79b304d6>] ? do_early_param+0x7a/0x7a
[    0.505451]  [<79677b1b>] kernel_init+0xb/0xe0
[    0.505451]  [<79075f42>] ? schedule_tail+0x12/0x40
[    0.505451]  [<79686580>] ret_from_kernel_thread+0x20/0x30
[    0.505451]  [<79677b10>] ? rest_init+0xc0/0xc0
[    0.505451] Code: 89 d8 e8 cf 9b 9f ff 8b 4f 04 8d 55 e4 89 d8 e8 72 9d 9f ff 8d 43 2c 89 c1 89 45 d8 8b 43 30 8d 55 e4 89 53 30 89 4d e4 89 45 e8 <89> 10 8b 55 dc 8b 45 e0 89 7d ec e8 db af 9f ff eb 11 90 31 c0
[    0.505451] EIP: [<79682de5>] mutex_lock_nested+0x135/0x2a0 SS:ESP 0068:78025e54
[    0.505451] CR2: 0000000000200200
[    0.505451] ---[ end trace ad8ac403ff8aef5e ]---
[    0.505451] Kernel panic - not syncing: Fatal exception
Fixes 9ea927748ced ("mac80211_hwsim: Register and bind to driver")
---
 drivers/net/wireless/mac80211_hwsim.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/wireless/mac80211_hwsim.c +3 -1
index 2cd3f54e1efa..38b8b7139ba3 100644
@@ -2261,7 +2261,7 @@ static int __init init_mac80211_hwsim(void)
 			printk(KERN_DEBUG
 			       "mac80211_hwsim: device_bind_driver failed (%d)\n",
 			       err);
-			goto failed_hw;
+			goto failed_bind;
 		}
 
 		skb_queue_head_init(&data->pending);
@@ -2563,6 +2563,8 @@ failed_mon:
 	return err;
 
 failed_hw:
+	device_release_driver(data->dev);
+failed_bind:
 	device_unregister(data->dev);
 failed_drvdata:
 	ieee80211_free_hw(hw);
Signature · 1 line
2.1.3
author
#31 lore raw

PATCH 31/101 mac80211: properly flush delayed scan work on interface removal

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 46238845bd609a5c0fbe076e1b82b4c5b33360b2 upstream.

When an interface is deleted, an ongoing hardware scan is canceled and the driver must abort the scan, at the very least reporting completion while the interface is removed.

However, if it scheduled the work that might only run after everything is said and done, which leads to cfg80211 warning that the scan isn't reported as finished yet; this is no fault of the driver, it already did, but mac80211 hasn't processed it.

To fix this situation, flush the delayed work when the interface being removed is the one that was executing the scan.

---
 net/mac80211/iface.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
net/mac80211/iface.c +6 -1
index d019b42e4a65..31da72ce76ef 100644
@@ -749,10 +749,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
 	u32 hw_reconf_flags = 0;
 	int i, flushed;
 	struct ps_data *ps;
+	bool cancel_scan;
 
 	clear_bit(SDATA_STATE_RUNNING, &sdata->state);
 
-	if (rcu_access_pointer(local->scan_sdata) == sdata)
+	cancel_scan = rcu_access_pointer(local->scan_sdata) == sdata;
+	if (cancel_scan)
 		ieee80211_scan_cancel(local);
 
 	/*
@@ -959,6 +961,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
 
 	ieee80211_recalc_ps(local, -1);
 
+	if (cancel_scan)
+		flush_delayed_work(&local->scan_work);
+
 	if (local->open_count == 0) {
 		ieee80211_stop_device(local);
 
Signature · 1 line
2.1.3
author
#32 lore raw

PATCH 32/101 mac80211: schedule the actual switch of the station before CSA count 0

In reply to Jiri Slaby

From: Luciano Coelho <[email protected]>

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

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

commit ff1e417c7c239b7abfe70aa90460a77eaafc7f83 upstream.

Due to the time it takes to process the beacon that started the CSA process, we may be late for the switch if we try to reach exactly beacon 0. To avoid that, use count - 1 when calculating the switch time.

---
 net/mac80211/mlme.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
net/mac80211/mlme.c +2 -1
index 5fa4ee07dd7a..023bc33bab9a 100644
@@ -1265,7 +1265,8 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 		ieee80211_queue_work(&local->hw, &ifmgd->chswitch_work);
 	else
 		mod_timer(&ifmgd->chswitch_timer,
-			  TU_TO_EXP_TIME(count * cbss->beacon_interval));
+			  TU_TO_EXP_TIME((count - 1) *
+					 cbss->beacon_interval));
 }
 
 static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
Signature · 1 line
2.1.3
author
#33 lore raw

PATCH 33/101 mac80211: fix use-after-free in defragmentation

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

Upon receiving the last fragment, all but the first fragment are freed, but the multicast check for statistics at the end of the function refers to the current skb (the last fragment) causing a use-after-free bug.

Since multicast frames cannot be fragmented and we check for this early in the function, just modify that check to also do the accounting to fix the issue.

---
 net/mac80211/rx.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
net/mac80211/rx.c +7 -7
index 1e5bd0d75732..275cb85bfa31 100644
@@ -1646,11 +1646,14 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
 	sc = le16_to_cpu(hdr->seq_ctrl);
 	frag = sc & IEEE80211_SCTL_FRAG;
 
-	if (likely((!ieee80211_has_morefrags(fc) && frag == 0) ||
-		   is_multicast_ether_addr(hdr->addr1))) {
-		/* not fragmented */
+	if (likely(!ieee80211_has_morefrags(fc) && frag == 0))
+		goto out;
+
+	if (is_multicast_ether_addr(hdr->addr1)) {
+		rx->local->dot11MulticastReceivedFrameCount++;
 		goto out;
 	}
+
 	I802_DEBUG_INC(rx->local->rx_handlers_fragments);
 
 	if (skb_linearize(rx->skb))
@@ -1743,10 +1746,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
  out:
 	if (rx->sta)
 		rx->sta->rx_packets++;
-	if (is_multicast_ether_addr(hdr->addr1))
-		rx->local->dot11MulticastReceivedFrameCount++;
-	else
-		ieee80211_led_rx(rx->local);
+	ieee80211_led_rx(rx->local);
 	return RX_CONTINUE;
 }
 
Signature · 1 line
2.1.3
author
#34 lore raw

PATCH 34/101 drm/radeon: set correct CE ram size for CIK

In reply to Jiri Slaby

From: Jammy Zhou <[email protected]>

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

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

commit dc4edad6530a9b7b66c3d905e2bc06021a05dcad upstream.

CE ram size is 32k/0k/0k for GFX/CS0/CS1 with CIK

Ported from amdgpu driver.

---
 drivers/gpu/drm/radeon/cik.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/radeon/cik.c +2 -2
index ceba819891f4..8cefe1cf7df7 100644
@@ -3343,8 +3343,8 @@ static int cik_cp_gfx_start(struct radeon_device *rdev)
 	/* init the CE partitions.  CE only used for gfx on CIK */
 	radeon_ring_write(ring, PACKET3(PACKET3_SET_BASE, 2));
 	radeon_ring_write(ring, PACKET3_BASE_INDEX(CE_PARTITION_BASE));
-	radeon_ring_write(ring, 0xc000);
-	radeon_ring_write(ring, 0xc000);
+	radeon_ring_write(ring, 0x8000);
+	radeon_ring_write(ring, 0x8000);
 
 	/* setup clear context state */
 	radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
Signature · 1 line
2.1.3
author
#35 lore raw

PATCH 35/101 drm/radeon: make sure mode init is complete in bandwidth_update

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

The power management code calls into the display code for certain things. If certain power management sysfs attributes are called before the driver has finished initializing all of the hardware we can run into problems with uninitialized modesetting state. Add a check to make sure modesetting init has completed to the bandwidth update callbacks to fix this. Can be triggered by the tlp and laptop start up scripts depending on the timing.

bugs:
https://bugzilla.kernel.org/show_bug.cgi?id=83611
https://bugs.freedesktop.org/show_bug.cgi?id=85771

---
 drivers/gpu/drm/radeon/cik.c       | 3 +++
 drivers/gpu/drm/radeon/evergreen.c | 3 +++
 drivers/gpu/drm/radeon/r100.c      | 3 +++
 drivers/gpu/drm/radeon/rs600.c     | 3 +++
 drivers/gpu/drm/radeon/rs690.c     | 3 +++
 drivers/gpu/drm/radeon/rv515.c     | 3 +++
 drivers/gpu/drm/radeon/si.c        | 3 +++
 7 files changed, 21 insertions(+)
drivers/gpu/drm/radeon/cik.c +3 -0
index 8cefe1cf7df7..0fc5fd6b3b41 100644
@@ -8105,6 +8105,9 @@ void dce8_bandwidth_update(struct radeon_device *rdev)
 	u32 num_heads = 0, lb_size;
 	int i;
 
+	if (!rdev->mode_info.mode_config_initialized)
+		return;
+
 	radeon_update_display_priority(rdev);
 
 	for (i = 0; i < rdev->num_crtc; i++) {
drivers/gpu/drm/radeon/evergreen.c +3 -0
index 7ca58fc7a1c6..9e726f2d2e75 100644
@@ -2312,6 +2312,9 @@ void evergreen_bandwidth_update(struct radeon_device *rdev)
 	u32 num_heads = 0, lb_size;
 	int i;
 
+	if (!rdev->mode_info.mode_config_initialized)
+		return;
+
 	radeon_update_display_priority(rdev);
 
 	for (i = 0; i < rdev->num_crtc; i++) {
drivers/gpu/drm/radeon/r100.c +3 -0
index d71333033b2b..f98dcbeb9a72 100644
@@ -3189,6 +3189,9 @@ void r100_bandwidth_update(struct radeon_device *rdev)
 	uint32_t pixel_bytes1 = 0;
 	uint32_t pixel_bytes2 = 0;
 
+	if (!rdev->mode_info.mode_config_initialized)
+		return;
+
 	radeon_update_display_priority(rdev);
 
 	if (rdev->mode_info.crtcs[0]->base.enabled) {
drivers/gpu/drm/radeon/rs600.c +3 -0
index e0daa4fdb073..bbe84591f159 100644
@@ -826,6 +826,9 @@ void rs600_bandwidth_update(struct radeon_device *rdev)
 	u32 d1mode_priority_a_cnt, d2mode_priority_a_cnt;
 	/* FIXME: implement full support */
 
+	if (!rdev->mode_info.mode_config_initialized)
+		return;
+
 	radeon_update_display_priority(rdev);
 
 	if (rdev->mode_info.crtcs[0]->base.enabled)
drivers/gpu/drm/radeon/rs690.c +3 -0
index 3c38f0af78fb..d33b4ad39b25 100644
@@ -585,6 +585,9 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
 	u32 d1mode_priority_a_cnt, d1mode_priority_b_cnt;
 	u32 d2mode_priority_a_cnt, d2mode_priority_b_cnt;
 
+	if (!rdev->mode_info.mode_config_initialized)
+		return;
+
 	radeon_update_display_priority(rdev);
 
 	if (rdev->mode_info.crtcs[0]->base.enabled)
drivers/gpu/drm/radeon/rv515.c +3 -0
index 873eb4b193b4..9de81c5487e9 100644
@@ -1279,6 +1279,9 @@ void rv515_bandwidth_update(struct radeon_device *rdev)
 	struct drm_display_mode *mode0 = NULL;
 	struct drm_display_mode *mode1 = NULL;
 
+	if (!rdev->mode_info.mode_config_initialized)
+		return;
+
 	radeon_update_display_priority(rdev);
 
 	if (rdev->mode_info.crtcs[0]->base.enabled)
drivers/gpu/drm/radeon/si.c +3 -0
index 53769e9cf595..50482e763d80 100644
@@ -2230,6 +2230,9 @@ void dce6_bandwidth_update(struct radeon_device *rdev)
 	u32 num_heads = 0, lb_size;
 	int i;
 
+	if (!rdev->mode_info.mode_config_initialized)
+		return;
+
 	radeon_update_display_priority(rdev);
 
 	for (i = 0; i < rdev->num_crtc; i++) {
Signature · 1 line
2.1.3
author
#36 lore raw

PATCH 36/101 drm/radeon: add missing crtc unlock when setting up the MC

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

Need to unlock the crtc after updating the blanking state.

---
 drivers/gpu/drm/radeon/evergreen.c | 1 +
 1 file changed, 1 insertion(+)
drivers/gpu/drm/radeon/evergreen.c +1 -0
index 9e726f2d2e75..20b00a0f42b4 100644
@@ -2523,6 +2523,7 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
 					WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
 					tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
 					WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
+					WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
 				}
 			} else {
 				tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
Signature · 1 line
2.1.3
author
#37 lore raw

PATCH 37/101 ARM: 8198/1: make kuser helpers depend on MMU

In reply to Jiri Slaby

From: Nathan Lynch <[email protected]>

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

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

commit 08b964ff3c51b10aaf2e6ba639f40054c09f0f7a upstream.

The kuser helpers page is not set up on non-MMU systems, so it does not make sense to allow CONFIG_KUSER_HELPERS to be enabled when CONFIG_MMU=n. Allowing it to be set on !MMU results in an oops in set_tls (used in execve and the arm_syscall trap handler):

Unhandled exception: IPSR = 00000005 LR = fffffff1

CPU: 0 PID: 1 Comm: swapper Not tainted 3.18.0-rc1-00041-ga30465a #216
task: 8b838000 ti: 8b82a000 task.ti: 8b82a000
PC is at flush_thread+0x32/0x40
LR is at flush_thread+0x21/0x40
pc : [<8f00157a>]    lr : [<8f001569>]    psr: 4100000b

sp : 8b82be20 ip : 00000000 fp : 8b83c000
r10: 00000001 r9 : 88018c84 r8 : 8bb85000
r7 : 8b838000 r6 : 00000000 r5 : 8bb77400 r4 : 8b82a000 r3 : ffff0ff0 r2 : 8b82a000 r1 : 00000000 r0 : 88020354
xPSR: 4100000b

CPU: 0 PID: 1 Comm: swapper Not tainted 3.18.0-rc1-00041-ga30465a #216
[<8f002bc1>] (unwind_backtrace) from [<8f002033>] (show_stack+0xb/0xc)
[<8f002033>] (show_stack) from [<8f00265b>] (__invalid_entry+0x4b/0x4c)

As best I can tell this issue existed for the set_tls ARM syscall before commit fbfb872f5f41 "ARM: 8148/1: flush TLS and thumbee register state during exec" consolidated the TLS manipulation code into the set_tls helper function, but now that we're using it to flush register state during execve, !MMU users encounter the oops at the first exec.

Prevent CONFIG_MMU=n configurations from enabling
CONFIG_KUSER_HELPERS.

Fixes fbfb872f5f41 (ARM: 8148/1: flush TLS and thumbee register state during exec)
---
 arch/arm/mm/Kconfig | 1 +
 1 file changed, 1 insertion(+)
arch/arm/mm/Kconfig +1 -0
index b3b1b883bd08..426f531754ec 100644
@@ -798,6 +798,7 @@ config NEED_KUSER_HELPERS
 
 config KUSER_HELPERS
 	bool "Enable kuser helpers in vector page" if !NEED_KUSER_HELPERS
+	depends on MMU
 	default y
 	help
 	  Warning: disabling this option may break user programs.
Signature · 1 line
2.1.3
author
#38 lore raw

PATCH 38/101 ARM: 8191/1: decompressor: ensure I-side picks up relocated code

In reply to Jiri Slaby

From: Will Deacon <[email protected]>

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

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

commit 238962ac71910d6c20162ea5230685fead1836a4 upstream.

To speed up decompression, the decompressor sets up a flat, cacheable mapping of memory. However, when there is insufficient space to hold the page tables for this mapping, we don't bother to enable the caches and subsequently skip all the cache maintenance hooks.

Skipping the cache maintenance before jumping to the relocated code allows the processor to predict the branch and populate the I-cache with stale data before the relocation loop has completed (since a bootloader may have SCTLR.I set, which permits normal, cacheable instruction fetches regardless of SCTLR.M).

This patch moves the cache maintenance check into the maintenance routines themselves, allowing the v6/v7 versions to invalidate the I-cache regardless of the MMU state.

---
 arch/arm/boot/compressed/head.S | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)
arch/arm/boot/compressed/head.S +16 -4
index 75189f13cf54..de5143e4ad04 100644
@@ -399,8 +399,7 @@ dtb_check_done:
 		add	sp, sp, r6
 #endif
 
-		tst	r4, #1
-		bleq	cache_clean_flush
+		bl	cache_clean_flush
 
 		adr	r0, BSYM(restart)
 		add	r0, r0, r6
@@ -1053,6 +1052,8 @@ cache_clean_flush:
 		b	call_cache_fn
 
 __armv4_mpu_cache_flush:
+		tst	r4, #1
+		movne	pc, lr
 		mov	r2, #1
 		mov	r3, #0
 		mcr	p15, 0, ip, c7, c6, 0	@ invalidate D cache
@@ -1070,6 +1071,8 @@ __armv4_mpu_cache_flush:
 		mov	pc, lr
 		
 __fa526_cache_flush:
+		tst	r4, #1
+		movne	pc, lr
 		mov	r1, #0
 		mcr	p15, 0, r1, c7, c14, 0	@ clean and invalidate D cache
 		mcr	p15, 0, r1, c7, c5, 0	@ flush I cache
@@ -1078,13 +1081,16 @@ __fa526_cache_flush:
 
 __armv6_mmu_cache_flush:
 		mov	r1, #0
-		mcr	p15, 0, r1, c7, c14, 0	@ clean+invalidate D
+		tst	r4, #1
+		mcreq	p15, 0, r1, c7, c14, 0	@ clean+invalidate D
 		mcr	p15, 0, r1, c7, c5, 0	@ invalidate I+BTB
-		mcr	p15, 0, r1, c7, c15, 0	@ clean+invalidate unified
+		mcreq	p15, 0, r1, c7, c15, 0	@ clean+invalidate unified
 		mcr	p15, 0, r1, c7, c10, 4	@ drain WB
 		mov	pc, lr
 
 __armv7_mmu_cache_flush:
+		tst	r4, #1
+		bne	iflush
 		mrc	p15, 0, r10, c0, c1, 5	@ read ID_MMFR1
 		tst	r10, #0xf << 16		@ hierarchical cache (ARMv7)
 		mov	r10, #0
@@ -1145,6 +1151,8 @@ iflush:
 		mov	pc, lr
 
 __armv5tej_mmu_cache_flush:
+		tst	r4, #1
+		movne	pc, lr
 1:		mrc	p15, 0, r15, c7, c14, 3	@ test,clean,invalidate D cache
 		bne	1b
 		mcr	p15, 0, r0, c7, c5, 0	@ flush I cache
@@ -1152,6 +1160,8 @@ __armv5tej_mmu_cache_flush:
 		mov	pc, lr
 
 __armv4_mmu_cache_flush:
+		tst	r4, #1
+		movne	pc, lr
 		mov	r2, #64*1024		@ default: 32K dcache size (*2)
 		mov	r11, #32		@ default: 32 byte line size
 		mrc	p15, 0, r3, c0, c0, 1	@ read cache type
@@ -1185,6 +1195,8 @@ no_cache_id:
 
 __armv3_mmu_cache_flush:
 __armv3_mpu_cache_flush:
+		tst	r4, #1
+		movne	pc, lr
 		mov	r1, #0
 		mcr	p15, 0, r1, c7, c0, 0	@ invalidate whole cache v3
 		mov	pc, lr
Signature · 1 line
2.1.3
author
#39 lore raw

PATCH 39/101 dm thin: grab a virtual cell before looking up the mapping

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

Avoids normal IO racing with discard.

---
 drivers/md/dm-thin.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)
drivers/md/dm-thin.c +12 -4
index f8c36d30eca8..0396d7fc1d8b 100644
@@ -1504,6 +1504,14 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
 		return DM_MAPIO_SUBMITTED;
 	}
 
+	/*
+	 * We must hold the virtual cell before doing the lookup, otherwise
+	 * there's a race with discard.
+	 */
+	build_virtual_key(tc->td, block, &key);
+	if (dm_bio_detain(tc->pool->prison, &key, bio, &cell1, &cell_result))
+		return DM_MAPIO_SUBMITTED;
+
 	r = dm_thin_find_block(td, block, 0, &result);
 
 	/*
@@ -1527,13 +1535,10 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
 			 * shared flag will be set in their case.
 			 */
 			thin_defer_bio(tc, bio);
+			cell_defer_no_holder_no_free(tc, &cell1);
 			return DM_MAPIO_SUBMITTED;
 		}
 
-		build_virtual_key(tc->td, block, &key);
-		if (dm_bio_detain(tc->pool->prison, &key, bio, &cell1, &cell_result))
-			return DM_MAPIO_SUBMITTED;
-
 		build_data_key(tc->td, result.block, &key);
 		if (dm_bio_detain(tc->pool->prison, &key, bio, &cell2, &cell_result)) {
 			cell_defer_no_holder_no_free(tc, &cell1);
@@ -1554,6 +1559,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
 			 * of doing so.  Just error it.
 			 */
 			bio_io_error(bio);
+			cell_defer_no_holder_no_free(tc, &cell1);
 			return DM_MAPIO_SUBMITTED;
 		}
 		/* fall through */
@@ -1564,6 +1570,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
 		 * provide the hint to load the metadata into cache.
 		 */
 		thin_defer_bio(tc, bio);
+		cell_defer_no_holder_no_free(tc, &cell1);
 		return DM_MAPIO_SUBMITTED;
 
 	default:
@@ -1573,6 +1580,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
 		 * pool is switched to fail-io mode.
 		 */
 		bio_io_error(bio);
+		cell_defer_no_holder_no_free(tc, &cell1);
 		return DM_MAPIO_SUBMITTED;
 	}
 }
Signature · 1 line
2.1.3
author
#40 lore raw

PATCH 40/101 arm64: __clear_user: handle exceptions on strb

In reply to Jiri Slaby

From: Kyle McMartin <[email protected]>

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

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

commit 97fc15436b36ee3956efad83e22a557991f7d19d upstream.

ARM64 currently doesn't fix up faults on the single-byte (strb) case of __clear_user... which means that we can cause a nasty kernel panic as an ordinary user with any multiple PAGE_SIZE+1 read from /dev/zero. i.e.: dd if=/dev/zero of=foo ibs=1 count=1 (or ibs=65537, etc.)

This is a pretty obscure bug in the general case since we'll only __do_kernel_fault (since there's no extable entry for pc) if the mmap_sem is contended. However, with CONFIG_DEBUG_VM enabled, we'll always fault.

if (!down_read_trylock(&mm->mmap_sem)) {
	if (!user_mode(regs) && !search_exception_tables(regs->pc))
		goto no_context;
retry:
	down_read(&mm->mmap_sem);
} else {
	/*
	 * The above down_read_trylock() might have succeeded in
	 * which
	 * case, we'll have missed the might_sleep() from
	 * down_read().
	 */
	might_sleep();
	if (!user_mode(regs) && !search_exception_tables(regs->pc))
		goto no_context;
}

Fix that by adding an extable entry for the strb instruction, since it touches user memory, similar to the other stores in __clear_user.

---
 arch/arm64/lib/clear_user.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/lib/clear_user.S +1 -1
index 6e0ed93d51fe..c17967fdf5f6 100644
@@ -46,7 +46,7 @@ USER(9f, strh	wzr, [x0], #2	)
 	sub	x1, x1, #2
 4:	adds	x1, x1, #1
 	b.mi	5f
-	strb	wzr, [x0]
+USER(9f, strb	wzr, [x0]	)
 5:	mov	x0, #0
 	ret
 ENDPROC(__clear_user)
Signature · 1 line
2.1.3
author
#41 lore raw

PATCH 41/101 firewire: cdev: prevent kernel stack leaking into ioctl arguments

In reply to Jiri Slaby

From: Stefan Richter <[email protected]>

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

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

commit eaca2d8e75e90a70a63a6695c9f61932609db212 upstream.

Found by the UC-KLEE tool: A user could supply less input to firewire-cdev ioctls than write- or write/read-type ioctl handlers expect. The handlers used data from uninitialized kernel stack then.

This could partially leak back to the user if the kernel subsequently generated fw_cdev_event_'s (to be read from the firewire-cdev fd) which notably would contain the _u64 closure field which many of the ioctl argument structures contain.

The fact that the handlers would act on random garbage input is a lesser issue since all handlers must check their input anyway.

The fix simply always null-initializes the entire ioctl argument buffer regardless of the actual length of expected user input. That is, a runtime overhead of memset(..., 40) is added to each firewirew-cdev ioctl() call. [Comment from Clemens Ladisch: This part of the stack is most likely to be already in the cache.]

Remarks:
- There was never any leak from kernel stack to the ioctl output buffer itself. IOW, it was not possible to read kernel stack by a read-type or write/read-type ioctl alone; the leak could at most happen in combination with read()ing subsequent event data.
- The actual expected minimum user input of each ioctl from

    include/uapi/linux/firewire-cdev.h is, in bytes:
    [0x00] = 32, [0x05] =  4, [0x0a] = 16, [0x0f] = 20, [0x14] = 16,
    [0x01] = 36, [0x06] = 20, [0x0b] =  4, [0x10] = 20, [0x15] = 20,
    [0x02] = 20, [0x07] =  4, [0x0c] =  0, [0x11] =  0, [0x16] =  8,
    [0x03] =  4, [0x08] = 24, [0x0d] = 20, [0x12] = 36, [0x17] = 12,
    [0x04] = 20, [0x09] = 24, [0x0e] =  4, [0x13] = 40, [0x18] =  4.
---
 drivers/firewire/core-cdev.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/firewire/core-cdev.c +1 -2
index d7d5c8af92b9..6d4456898007 100644
@@ -1637,8 +1637,7 @@ static int dispatch_ioctl(struct client *client,
 	    _IOC_SIZE(cmd) > sizeof(buffer))
 		return -ENOTTY;
 
-	if (_IOC_DIR(cmd) == _IOC_READ)
-		memset(&buffer, 0, _IOC_SIZE(cmd));
+	memset(&buffer, 0, sizeof(buffer));
 
 	if (_IOC_DIR(cmd) & _IOC_WRITE)
 		if (copy_from_user(&buffer, arg, _IOC_SIZE(cmd)))
Signature · 1 line
2.1.3
author
#42 lore raw

PATCH 42/101 nfs: fix pnfs direct write memory leak

In reply to Jiri Slaby

From: Peng Tao <[email protected]>

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

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

commit 8c393f9a721c30a030049a680e1bf896669bb279 upstream.

For pNFS direct writes, layout driver may dynamically allocate ds_cinfo.buckets. So we need to take care to free them when freeing dreq.

Ideally this needs to be done inside layout driver where ds_cinfo.buckets are allocated. But buckets are attached to dreq and reused across LD IO iterations. So I feel it's OK to free them in the generic layer.

---
 fs/nfs/direct.c         |  1 +
 include/linux/nfs_xdr.h | 11 +++++++++++
 2 files changed, 12 insertions(+)
fs/nfs/direct.c +1 -0
index af5f3ffcb157..d751a2383c24 100644
@@ -179,6 +179,7 @@ static void nfs_direct_req_free(struct kref *kref)
 {
 	struct nfs_direct_req *dreq = container_of(kref, struct nfs_direct_req, kref);
 
+	nfs_free_pnfs_ds_cinfo(&dreq->ds_cinfo);
 	if (dreq->l_ctx != NULL)
 		nfs_put_lock_context(dreq->l_ctx);
 	if (dreq->ctx != NULL)
include/linux/nfs_xdr.h +11 -0
index 2b307018979d..715671e4c7e6 100644
@@ -1223,11 +1223,22 @@ struct nfs41_free_stateid_res {
 	unsigned int			status;
 };
 
+static inline void
+nfs_free_pnfs_ds_cinfo(struct pnfs_ds_commit_info *cinfo)
+{
+	kfree(cinfo->buckets);
+}
+
 #else
 
 struct pnfs_ds_commit_info {
 };
 
+static inline void
+nfs_free_pnfs_ds_cinfo(struct pnfs_ds_commit_info *cinfo)
+{
+}
+
 #endif /* CONFIG_NFS_V4_1 */
 
 struct nfs_page;
Signature · 1 line
2.1.3
author
#43 lore raw

PATCH 43/101 scsi: only re-lock door after EH on devices that were reset

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 48379270fe6808cf4612ee094adc8da2b7a83baa upstream.

Setups that use the blk-mq I/O path can lock up if a host with a single device that has its door locked enters EH. Make sure to only send the command to re-lock the door to devices that actually were reset and thus might have lost their state. Otherwise the EH code might be get blocked on blk_get_request as all requests for non-reset devices might be in use.

---
 drivers/scsi/scsi_error.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/scsi/scsi_error.c +3 -1
index 9ba3642cb19e..066e3198838d 100644
@@ -1746,8 +1746,10 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
 	 * is no point trying to lock the door of an off-line device.
 	 */
 	shost_for_each_device(sdev, shost) {
-		if (scsi_device_online(sdev) && sdev->locked)
+		if (scsi_device_online(sdev) && sdev->was_reset && sdev->locked) {
 			scsi_eh_lock_door(sdev);
+			sdev->was_reset = 0;
+		}
 	}
 
 	/*
Signature · 1 line
2.1.3
author
#44 lore raw

PATCH 44/101 parisc: Use compat layer for msgctl, shmat, shmctl and semtimedop syscalls

In reply to Jiri Slaby

From: Helge Deller <[email protected]>

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

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

commit 2fe749f50b0bec07650ef135b29b1f55bf543869 upstream.

Switch over the msgctl, shmat, shmctl and semtimedop syscalls to use the compat layer. The problem was found with the debian procenv package, which called

	shmctl(0, SHM_INFO, &info);

in which the shmctl syscall then overwrote parts of the surrounding areas on the stack on which the info variable was stored and thus lead to a segfault later on.

Additionally fix the definition of struct shminfo64 to use unsigned longs like the other architectures. This has no impact on userspace since we only have a 32bit userspace up to now.

---
 arch/parisc/include/uapi/asm/shmbuf.h | 25 +++++++++----------------
 arch/parisc/kernel/syscall_table.S    |  8 ++++----
 2 files changed, 13 insertions(+), 20 deletions(-)
arch/parisc/include/uapi/asm/shmbuf.h +9 -16
index 0a3eada1863b..f395cde7b593 100644
@@ -36,23 +36,16 @@ struct shmid64_ds {
 	unsigned int		__unused2;
 };
 
-#ifdef CONFIG_64BIT
-/* The 'unsigned int' (formerly 'unsigned long') data types below will
- * ensure that a 32-bit app calling shmctl(*,IPC_INFO,*) will work on
- * a wide kernel, but if some of these values are meant to contain pointers
- * they may need to be 'long long' instead. -PB XXX FIXME
- */
-#endif
 struct shminfo64 {
-	unsigned int	shmmax;
-	unsigned int	shmmin;
-	unsigned int	shmmni;
-	unsigned int	shmseg;
-	unsigned int	shmall;
-	unsigned int	__unused1;
-	unsigned int	__unused2;
-	unsigned int	__unused3;
-	unsigned int	__unused4;
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
 };
 
 #endif /* _PARISC_SHMBUF_H */
arch/parisc/kernel/syscall_table.S +4 -4
index 10a0c2aad8cf..b24732d1bdbf 100644
@@ -286,11 +286,11 @@
 	ENTRY_COMP(msgsnd)
 	ENTRY_COMP(msgrcv)
 	ENTRY_SAME(msgget)		/* 190 */
-	ENTRY_SAME(msgctl)
-	ENTRY_SAME(shmat)
+	ENTRY_COMP(msgctl)
+	ENTRY_COMP(shmat)
 	ENTRY_SAME(shmdt)
 	ENTRY_SAME(shmget)
-	ENTRY_SAME(shmctl)		/* 195 */
+	ENTRY_COMP(shmctl)		/* 195 */
 	ENTRY_SAME(ni_syscall)		/* streams1 */
 	ENTRY_SAME(ni_syscall)		/* streams2 */
 	ENTRY_SAME(lstat64)
@@ -323,7 +323,7 @@
 	ENTRY_SAME(epoll_ctl)		/* 225 */
 	ENTRY_SAME(epoll_wait)
  	ENTRY_SAME(remap_file_pages)
-	ENTRY_SAME(semtimedop)
+	ENTRY_COMP(semtimedop)
 	ENTRY_COMP(mq_open)
 	ENTRY_SAME(mq_unlink)		/* 230 */
 	ENTRY_COMP(mq_timedsend)
Signature · 1 line
2.1.3
author
#45 lore raw

PATCH 45/101 block: Fix computation of merged request priority

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

Priority of a merged request is computed by ioprio_best(). If one of the requests has undefined priority (IOPRIO_CLASS_NONE) and another request has priority from IOPRIO_CLASS_BE, the function will return the undefined priority which is wrong. Fix the function to properly return priority of a request with the defined priority.

Fixes d58cdfb89ce0c6bd5f81ae931a984ef298dbda20
---
 fs/ioprio.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)
fs/ioprio.c +8 -6
index e50170ca7c33..31666c92b46a 100644
@@ -157,14 +157,16 @@ out:
 
 int ioprio_best(unsigned short aprio, unsigned short bprio)
 {
-	unsigned short aclass = IOPRIO_PRIO_CLASS(aprio);
-	unsigned short bclass = IOPRIO_PRIO_CLASS(bprio);
+	unsigned short aclass;
+	unsigned short bclass;
 
-	if (aclass == IOPRIO_CLASS_NONE)
-		aclass = IOPRIO_CLASS_BE;
-	if (bclass == IOPRIO_CLASS_NONE)
-		bclass = IOPRIO_CLASS_BE;
+	if (!ioprio_valid(aprio))
+		aprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, IOPRIO_NORM);
+	if (!ioprio_valid(bprio))
+		bprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, IOPRIO_NORM);
 
+	aclass = IOPRIO_PRIO_CLASS(aprio);
+	bclass = IOPRIO_PRIO_CLASS(bprio);
 	if (aclass == bclass)
 		return min(aprio, bprio);
 	if (aclass > bclass)
Signature · 1 line
2.1.3
author
#46 lore raw

PATCH 46/101 dm bufio: change __GFP_IO to __GFP_FS in shrinker callbacks

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

The shrinker uses gfp flags to indicate what kind of operation can the driver wait for. If __GFP_IO flag is present, the driver can wait for block I/O operations, if __GFP_FS flag is present, the driver can wait on operations involving the filesystem.

dm-bufio tested for __GFP_IO. However, dm-bufio can run on a loop block device that makes calls into the filesystem. If __GFP_IO is present and __GFP_FS isn't, dm-bufio could still block on filesystem operations if it runs on a loop block device.

The change from __GFP_IO to __GFP_FS supposedly fixes one observed (though unreproducible) deadlock involving dm-bufio and loop device.

---
 drivers/md/dm-bufio.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/md/dm-bufio.c +6 -6
index a42efc7f69ed..140be2dd3e23 100644
@@ -1418,9 +1418,9 @@ static void drop_buffers(struct dm_bufio_client *c)
 
 /*
  * Test if the buffer is unused and too old, and commit it.
- * At if noio is set, we must not do any I/O because we hold
- * dm_bufio_clients_lock and we would risk deadlock if the I/O gets rerouted to
- * different bufio client.
+ * And if GFP_NOFS is used, we must not do any I/O because we hold
+ * dm_bufio_clients_lock and we would risk deadlock if the I/O gets
+ * rerouted to different bufio client.
  */
 static int __cleanup_old_buffer(struct dm_buffer *b, gfp_t gfp,
 				unsigned long max_jiffies)
@@ -1428,7 +1428,7 @@ static int __cleanup_old_buffer(struct dm_buffer *b, gfp_t gfp,
 	if (jiffies - b->last_accessed < max_jiffies)
 		return 0;
 
-	if (!(gfp & __GFP_IO)) {
+	if (!(gfp & __GFP_FS)) {
 		if (test_bit(B_READING, &b->state) ||
 		    test_bit(B_WRITING, &b->state) ||
 		    test_bit(B_DIRTY, &b->state))
@@ -1470,7 +1470,7 @@ dm_bufio_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
 	unsigned long freed;
 
 	c = container_of(shrink, struct dm_bufio_client, shrinker);
-	if (sc->gfp_mask & __GFP_IO)
+	if (sc->gfp_mask & __GFP_FS)
 		dm_bufio_lock(c);
 	else if (!dm_bufio_trylock(c))
 		return SHRINK_STOP;
@@ -1487,7 +1487,7 @@ dm_bufio_shrink_count(struct shrinker *shrink, struct shrink_control *sc)
 	unsigned long count;
 
 	c = container_of(shrink, struct dm_bufio_client, shrinker);
-	if (sc->gfp_mask & __GFP_IO)
+	if (sc->gfp_mask & __GFP_FS)
 		dm_bufio_lock(c);
 	else if (!dm_bufio_trylock(c))
 		return 0;
Signature · 1 line
2.1.3
author
#47 lore raw

PATCH 47/101 dm btree: fix a recursion depth bug in btree walking code

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

The walk code was using a 'ro_spine' to hold it's locked btree nodes. But this data structure is designed for the rolling lock scheme, and as such automatically unlocks blocks that are two steps up the call chain. This is not suitable for the simple recursive walk algorithm, which retraces its steps.

This code is only used by the persistent array code, which in turn is only used by dm-cache. In order to trigger it you need to have a mapping tree that is more than 2 levels deep; which equates to 8-16 million cache blocks. For instance a 4T ssd with a very small block size of 32k only just triggers this bug.

The fix just places the locked blocks on the stack, and stops using the ro_spine altogether.

---
 drivers/md/persistent-data/dm-btree-internal.h |  6 ++++++
 drivers/md/persistent-data/dm-btree-spine.c    |  2 +-
 drivers/md/persistent-data/dm-btree.c          | 24 ++++++++++--------------
 3 files changed, 17 insertions(+), 15 deletions(-)
drivers/md/persistent-data/dm-btree-internal.h +6 -0
index 37d367bb9aa8..bf2b80d5c470 100644
@@ -42,6 +42,12 @@ struct btree_node {
 } __packed;
 
 
+/*
+ * Locks a block using the btree node validator.
+ */
+int bn_read_lock(struct dm_btree_info *info, dm_block_t b,
+		 struct dm_block **result);
+
 void inc_children(struct dm_transaction_manager *tm, struct btree_node *n,
 		  struct dm_btree_value_type *vt);
 
drivers/md/persistent-data/dm-btree-spine.c +1 -1
index cf9fd676ae44..1b5e13ec7f96 100644
@@ -92,7 +92,7 @@ struct dm_block_validator btree_node_validator = {
 
 /*----------------------------------------------------------------*/
 
-static int bn_read_lock(struct dm_btree_info *info, dm_block_t b,
+int bn_read_lock(struct dm_btree_info *info, dm_block_t b,
 		 struct dm_block **result)
 {
 	return dm_tm_read_lock(info->tm, b, &btree_node_validator, result);
drivers/md/persistent-data/dm-btree.c +10 -14
index 468e371ee9b2..9701d29c94e1 100644
@@ -828,22 +828,26 @@ EXPORT_SYMBOL_GPL(dm_btree_find_highest_key);
  * FIXME: We shouldn't use a recursive algorithm when we have limited stack
  * space.  Also this only works for single level trees.
  */
-static int walk_node(struct ro_spine *s, dm_block_t block,
+static int walk_node(struct dm_btree_info *info, dm_block_t block,
 		     int (*fn)(void *context, uint64_t *keys, void *leaf),
 		     void *context)
 {
 	int r;
 	unsigned i, nr;
+	struct dm_block *node;
 	struct btree_node *n;
 	uint64_t keys;
 
-	r = ro_step(s, block);
-	n = ro_node(s);
+	r = bn_read_lock(info, block, &node);
+	if (r)
+		return r;
+
+	n = dm_block_data(node);
 
 	nr = le32_to_cpu(n->header.nr_entries);
 	for (i = 0; i < nr; i++) {
 		if (le32_to_cpu(n->header.flags) & INTERNAL_NODE) {
-			r = walk_node(s, value64(n, i), fn, context);
+			r = walk_node(info, value64(n, i), fn, context);
 			if (r)
 				goto out;
 		} else {
@@ -855,7 +859,7 @@ static int walk_node(struct ro_spine *s, dm_block_t block,
 	}
 
 out:
-	ro_pop(s);
+	dm_tm_unlock(info->tm, node);
 	return r;
 }
 
@@ -863,15 +867,7 @@ int dm_btree_walk(struct dm_btree_info *info, dm_block_t root,
 		  int (*fn)(void *context, uint64_t *keys, void *leaf),
 		  void *context)
 {
-	int r;
-	struct ro_spine spine;
-
 	BUG_ON(info->levels > 1);
-
-	init_ro_spine(&spine, info);
-	r = walk_node(&spine, root, fn, context);
-	exit_ro_spine(&spine);
-
-	return r;
+	return walk_node(info, root, fn, context);
 }
 EXPORT_SYMBOL_GPL(dm_btree_walk);
Signature · 1 line
2.1.3
author
#48 lore raw

PATCH 48/101 dm raid: ensure superblock's size matches device's logical block size

In reply to Jiri Slaby

From: Heinz Mauelshagen <[email protected]>

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

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

commit 40d43c4b4cac4c2647bf07110d7b07d35f399a84 upstream.

The dm-raid superblock (struct dm_raid_superblock) is padded to 512 bytes and that size is being used to read it in from the metadata device into one preallocated page.

Reading or writing this on a 512-byte sector device works fine but on a 4096-byte sector device this fails.

Set the dm-raid superblock's size to the logical block size of the metadata device, because IO at that size is guaranteed too work. Also add a size check to avoid silent partial metadata loss in case the superblock should ever grow past the logical block size or PAGE_SIZE.

[includes pointer math fix from Dan Carpenter]
---
 drivers/md/dm-raid.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/md/dm-raid.c +7 -4
index 4880b69e2e9e..59715389b3cf 100644
@@ -785,8 +785,7 @@ struct dm_raid_superblock {
 	__le32 layout;
 	__le32 stripe_sectors;
 
-	__u8 pad[452];		/* Round struct to 512 bytes. */
-				/* Always set to 0 when writing. */
+	/* Remainder of a logical block is zero-filled when writing (see super_sync()). */
 } __packed;
 
 static int read_disk_sb(struct md_rdev *rdev, int size)
@@ -823,7 +822,7 @@ static void super_sync(struct mddev *mddev, struct md_rdev *rdev)
 		    test_bit(Faulty, &(rs->dev[i].rdev.flags)))
 			failed_devices |= (1ULL << i);
 
-	memset(sb, 0, sizeof(*sb));
+	memset(sb + 1, 0, rdev->sb_size - sizeof(*sb));
 
 	sb->magic = cpu_to_le32(DM_RAID_MAGIC);
 	sb->features = cpu_to_le32(0);	/* No features yet */
@@ -858,7 +857,11 @@ static int super_load(struct md_rdev *rdev, struct md_rdev *refdev)
 	uint64_t events_sb, events_refsb;
 
 	rdev->sb_start = 0;
-	rdev->sb_size = sizeof(*sb);
+	rdev->sb_size = bdev_logical_block_size(rdev->meta_bdev);
+	if (rdev->sb_size < sizeof(*sb) || rdev->sb_size > PAGE_SIZE) {
+		DMERR("superblock size of a logical block is no longer valid");
+		return -EINVAL;
+	}
 
 	ret = read_disk_sb(rdev, rdev->sb_size);
 	if (ret)
Signature · 1 line
2.1.3
author
#49 lore raw

PATCH 49/101 Input: alps - ignore potential bare packets when device is out of sync

In reply to Jiri Slaby

From: Pali Rohár <[email protected]>

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

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

commit 4ab8f7f320f91f279c3f06a9795cfea5c972888a upstream.

5th and 6th byte of ALPS trackstick V3 protocol match condition for first byte of PS/2 3 bytes packet. When driver enters out of sync state and ALPS trackstick is sending data then driver match 5th, 6th and next 1st bytes as PS/2.

It basically means if user is using trackstick when driver is in out of sync state driver will never resync. Processing these bytes as 3 bytes PS/2 data cause total mess (random cursor movements, random clicks) and make trackstick unusable until psmouse driver decide to do full device reset.

Lot of users reported problems with ALPS devices on Dell Latitude E6440, E6540 and E7440 laptops. ALPS device or Dell EC for unknown reason send some invalid ALPS PS/2 bytes which cause driver out of sync. It looks like that i8042 and psmouse/alps driver always receive group of 6 bytes packets so there are no missing bytes and no bytes were inserted between valid ones.

This patch does not fix root of problem with ALPS devices found in Dell Latitude laptops but it does not allow to process some (invalid) subsequence of 6 bytes ALPS packets as 3 bytes PS/2 when driver is out of sync.

So with this patch trackstick input device does not report bogus data when also driver is out of sync, so trackstick should be usable on those machines.

---
 drivers/input/mouse/alps.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/input/mouse/alps.c +7 -1
index 7c5d72a6a26a..071bd835594c 100644
@@ -873,7 +873,13 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
 {
 	struct alps_data *priv = psmouse->private;
 
-	if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */
+	/*
+	 * Check if we are dealing with a bare PS/2 packet, presumably from
+	 * a device connected to the external PS/2 port. Because bare PS/2
+	 * protocol does not have enough constant bits to self-synchronize
+	 * properly we only do this if the device is fully synchronized.
+	 */
+	if (!psmouse->out_of_sync_cnt && (psmouse->packet[0] & 0xc8) == 0x08) {
 		if (psmouse->pktcnt == 3) {
 			alps_report_bare_ps2_packet(psmouse, psmouse->packet,
 						    true);
Signature · 1 line
2.1.3
author
#50 lore raw

PATCH 50/101 Input: alps - allow up to 2 invalid packets without resetting device

In reply to Jiri Slaby

From: Pali Rohár <[email protected]>

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

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

commit 9d720b34c0a432639252f63012e18b0507f5b432 upstream.

On some Dell Latitude laptops ALPS device or Dell EC send one invalid byte in 6 bytes ALPS packet. In this case psmouse driver enter out of sync state. It looks like that all other bytes in packets are valid and also device working properly. So there is no need to do full device reset, just need to wait for byte which match condition for first byte (start of packet). Because ALPS packets are bigger (6 or 8 bytes) default limit is small.

This patch increase number of invalid bytes to size of 2 ALPS packets which psmouse driver can drop before do full reset.

Resetting ALPS devices take some time and when doing reset on some Dell laptops touchpad, trackstick and also keyboard do not respond. So it is better to do it only if really necessary.

---
 drivers/input/mouse/alps.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/input/mouse/alps.c +3 -0
index 071bd835594c..19e070f16e6b 100644
@@ -1822,6 +1822,9 @@ int alps_init(struct psmouse *psmouse)
 	/* We are having trouble resyncing ALPS touchpads so disable it for now */
 	psmouse->resync_time = 0;
 
+	/* Allow 2 invalid packets without resetting device */
+	psmouse->resetafter = psmouse->pktsize * 2;
+
 	return 0;
 
 init_fail:
Signature · 1 line
2.1.3
author
#51 lore raw

PATCH 51/101 Input: alps - ignore bad data on Dell Latitudes E6440 and E7440

In reply to Jiri Slaby

From: Pali Rohár <[email protected]>

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

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

commit a7ef82aee91f26da79b981b9f5bca43b8817d3e4 upstream.

Sometimes on Dell Latitude laptops psmouse/alps driver receive invalid ALPS protocol V3 packets with bit7 set in last byte. More often it can be reproduced on Dell Latitude E6440 or E7440 with closed lid and pushing cover above touchpad.

If bit7 in last packet byte is set then it is not valid ALPS packet. I was told that ALPS devices never send these packets. It is not know yet who send those packets, it could be Dell EC, bug in BIOS and also bug in touchpad firmware...

With this patch alps driver does not process those invalid packets, but instead of reporting PSMOUSE_BAD_DATA, getting into out of sync state, getting back in sync with the next byte and spam dmesg we return PSMOUSE_FULL_PACKET. If driver is truly out of sync we'll fail the checks on the next byte and report PSMOUSE_BAD_DATA then.

---
 drivers/input/mouse/alps.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
drivers/input/mouse/alps.c +15 -0
index 19e070f16e6b..642a42f719b1 100644
@@ -909,6 +909,21 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
 		psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
 			    psmouse->pktcnt - 1,
 			    psmouse->packet[psmouse->pktcnt - 1]);
+
+		if (priv->proto_version == ALPS_PROTO_V3 &&
+		    psmouse->pktcnt == psmouse->pktsize) {
+			/*
+			 * Some Dell boxes, such as Latitude E6440 or E7440
+			 * with closed lid, quite often smash last byte of
+			 * otherwise valid packet with 0xff. Given that the
+			 * next packet is very likely to be valid let's
+			 * report PSMOUSE_FULL_PACKET but not process data,
+			 * rather than reporting PSMOUSE_BAD_DATA and
+			 * filling the logs.
+			 */
+			return PSMOUSE_FULL_PACKET;
+		}
+
 		return PSMOUSE_BAD_DATA;
 	}
 
Signature · 1 line
2.1.3
author
#52 lore raw

PATCH 52/101 NFSv4: Ensure that we remove NFSv4.0 delegations when state has expired

In reply to Jiri Slaby

From: Trond Myklebust <[email protected]>

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

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

commit 4dfd4f7af0afd201706ad186352ca423b0f17d4b upstream.

NFSv4.0 does not have TEST_STATEID/FREE_STATEID functionality, so unlike NFSv4.1, the recovery procedure when stateids have expired or have been revoked requires us to just forget the delegation.

http://lkml.kernel.org/r/CAN-5tyHwG=Cn2Q9KsHWadewjpTTy_K26ee+UnSvHvG4192p-Xw@mail.gmail.com

---
 fs/nfs/nfs4proc.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)
fs/nfs/nfs4proc.c +23 -1
index 9f7f1a0d30dc..1d8af4f5842e 100644
@@ -2026,6 +2026,28 @@ static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *sta
 	return ret;
 }
 
+static void nfs_finish_clear_delegation_stateid(struct nfs4_state *state)
+{
+	nfs_remove_bad_delegation(state->inode);
+	write_seqlock(&state->seqlock);
+	nfs4_stateid_copy(&state->stateid, &state->open_stateid);
+	write_sequnlock(&state->seqlock);
+	clear_bit(NFS_DELEGATED_STATE, &state->flags);
+}
+
+static void nfs40_clear_delegation_stateid(struct nfs4_state *state)
+{
+	if (rcu_access_pointer(NFS_I(state->inode)->delegation) != NULL)
+		nfs_finish_clear_delegation_stateid(state);
+}
+
+static int nfs40_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state)
+{
+	/* NFSv4.0 doesn't allow for delegation recovery on open expire */
+	nfs40_clear_delegation_stateid(state);
+	return nfs4_open_expired(sp, state);
+}
+
 #if defined(CONFIG_NFS_V4_1)
 static void nfs41_clear_delegation_stateid(struct nfs4_state *state)
 {
@@ -7902,7 +7924,7 @@ static const struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = {
 static const struct nfs4_state_recovery_ops nfs40_nograce_recovery_ops = {
 	.owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE,
 	.state_flag_bit	= NFS_STATE_RECLAIM_NOGRACE,
-	.recover_open	= nfs4_open_expired,
+	.recover_open	= nfs40_open_expired,
 	.recover_lock	= nfs4_lock_expired,
 	.establish_clid = nfs4_init_clientid,
 };
Signature · 1 line
2.1.3
author
#53 lore raw

PATCH 53/101 NFS: Don't try to reclaim delegation open state if recovery failed

In reply to Jiri Slaby

From: Trond Myklebust <[email protected]>

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

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

commit f8ebf7a8ca35dde321f0cd385fee6f1950609367 upstream.

If state recovery failed, then we should not attempt to reclaim delegated state.

http://lkml.kernel.org/r/CAN-5tyHwG=Cn2Q9KsHWadewjpTTy_K26ee+UnSvHvG4192p-Xw@mail.gmail.com

---
 fs/nfs/delegation.c | 2 ++
 1 file changed, 2 insertions(+)
fs/nfs/delegation.c +2 -0
index 5d8ccecf5f5c..6acc11e6ebad 100644
@@ -109,6 +109,8 @@ again:
 			continue;
 		if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
 			continue;
+		if (!nfs4_valid_open_stateid(state))
+			continue;
 		if (!nfs4_stateid_match(&state->stateid, stateid))
 			continue;
 		get_nfs_open_context(ctx);
Signature · 1 line
2.1.3
author
#54 lore raw

PATCH 54/101 nfs: Fix use of uninitialized variable in nfs_getattr()

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 16caf5b6101d03335b386e77e9e14136f989be87 upstream.

Variable 'err' needn't be initialized when nfs_getattr() uses it to check whether it should call generic_fillattr() or not. That can result in spurious error returns. Initialize 'err' properly.

---
 fs/nfs/inode.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/inode.c +1 -1
index 7f5799d098fd..e5eb677ca9ce 100644
@@ -598,7 +598,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
 {
 	struct inode *inode = dentry->d_inode;
 	int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME;
-	int err;
+	int err = 0;
 
 	trace_nfs_getattr_enter(inode);
 	/* Flush out writes to the server in order to update c/mtime.  */
Signature · 1 line
2.1.3
author
#55 lore raw

PATCH 55/101 NFSv4: Fix races between nfs_remove_bad_delegation() and delegation return

In reply to Jiri Slaby

From: Trond Myklebust <[email protected]>

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

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

commit 869f9dfa4d6d57b79e0afc3af14772c2a023eeb1 upstream.

Any attempt to call nfs_remove_bad_delegation() while a delegation is being returned is currently a no-op. This means that we can end up looping forever in nfs_end_delegation_return() if something causes the delegation to be revoked.
This patch adds a mechanism whereby the state recovery code can communicate to the delegation return code that the delegation is no longer valid and that it should not be used when reclaiming state.
It also changes the return value for nfs4_handle_delegation_recall_error() to ensure that nfs_end_delegation_return() does not reattempt the lock reclaim before state recovery is done.

http://lkml.kernel.org/r/CAN-5tyHwG=Cn2Q9KsHWadewjpTTy_K26ee+UnSvHvG4192p-Xw@mail.gmail.com

---
 fs/nfs/delegation.c | 23 +++++++++++++++++++++--
 fs/nfs/delegation.h |  1 +
 fs/nfs/nfs4proc.c   |  2 +-
 3 files changed, 23 insertions(+), 3 deletions(-)
fs/nfs/delegation.c +21 -2
index 6acc11e6ebad..3ed1be9aade3 100644
@@ -179,7 +179,11 @@ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *
 {
 	int res = 0;
 
-	res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid, issync);
+	if (!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
+		res = nfs4_proc_delegreturn(inode,
+				delegation->cred,
+				&delegation->stateid,
+				issync);
 	nfs_free_delegation(delegation);
 	return res;
 }
@@ -366,11 +370,13 @@ static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation
 {
 	struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
 	struct nfs_inode *nfsi = NFS_I(inode);
-	int err;
+	int err = 0;
 
 	if (delegation == NULL)
 		return 0;
 	do {
+		if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
+			break;
 		err = nfs_delegation_claim_opens(inode, &delegation->stateid);
 		if (!issync || err != -EAGAIN)
 			break;
@@ -591,10 +597,23 @@ static void nfs_client_mark_return_unused_delegation_types(struct nfs_client *cl
 	rcu_read_unlock();
 }
 
+static void nfs_revoke_delegation(struct inode *inode)
+{
+	struct nfs_delegation *delegation;
+	rcu_read_lock();
+	delegation = rcu_dereference(NFS_I(inode)->delegation);
+	if (delegation != NULL) {
+		set_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
+		nfs_mark_return_delegation(NFS_SERVER(inode), delegation);
+	}
+	rcu_read_unlock();
+}
+
 void nfs_remove_bad_delegation(struct inode *inode)
 {
 	struct nfs_delegation *delegation;
 
+	nfs_revoke_delegation(inode);
 	delegation = nfs_inode_detach_delegation(inode);
 	if (delegation) {
 		nfs_inode_find_state_and_recover(inode, &delegation->stateid);
fs/nfs/delegation.h +1 -0
index 9a79c7a99d6d..e02b090ab9da 100644
@@ -31,6 +31,7 @@ enum {
 	NFS_DELEGATION_RETURN_IF_CLOSED,
 	NFS_DELEGATION_REFERENCED,
 	NFS_DELEGATION_RETURNING,
+	NFS_DELEGATION_REVOKED,
 };
 
 int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
fs/nfs/nfs4proc.c +1 -1
index 1d8af4f5842e..9dcfa4248c59 100644
@@ -1579,7 +1579,7 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct
 			nfs_inode_find_state_and_recover(state->inode,
 					stateid);
 			nfs4_schedule_stateid_recovery(server, state);
-			return 0;
+			return -EAGAIN;
 		case -NFS4ERR_DELAY:
 		case -NFS4ERR_GRACE:
 			set_bit(NFS_DELEGATED_STATE, &state->flags);
Signature · 1 line
2.1.3
author
#56 lore raw

PATCH 56/101 NFSv4.1: nfs41_clear_delegation_stateid shouldn't trust NFS_DELEGATED_STATE

In reply to Jiri Slaby

From: Trond Myklebust <[email protected]>

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

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

commit 0c116cadd94b16b30b1dd90d38b2784d9b39b01a upstream.

This patch removes the assumption made previously, that we only need to check the delegation stateid when it matches the stateid on a cached open.

If we believe that we hold a delegation for this file, then we must assume that its stateid may have been revoked or expired too. If we don't test it then our state recovery process may end up caching open/lock state in a situation where it should not.
We therefore rename the function nfs41_clear_delegation_stateid as nfs41_check_delegation_stateid, and change it to always run through the delegation stateid test and recovery process as outlined in RFC5661.

http://lkml.kernel.org/r/CAN-5tyHwG=Cn2Q9KsHWadewjpTTy_K26ee+UnSvHvG4192p-Xw@mail.gmail.com

---
 fs/nfs/nfs4proc.c | 42 +++++++++++++++++-------------------------
 1 file changed, 17 insertions(+), 25 deletions(-)
fs/nfs/nfs4proc.c +17 -25
index 9dcfa4248c59..759875038791 100644
@@ -2049,45 +2049,37 @@ static int nfs40_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
 }
 
 #if defined(CONFIG_NFS_V4_1)
-static void nfs41_clear_delegation_stateid(struct nfs4_state *state)
+static void nfs41_check_delegation_stateid(struct nfs4_state *state)
 {
 	struct nfs_server *server = NFS_SERVER(state->inode);
-	nfs4_stateid *stateid = &state->stateid;
+	nfs4_stateid stateid;
 	struct nfs_delegation *delegation;
-	struct rpc_cred *cred = NULL;
-	int status = -NFS4ERR_BAD_STATEID;
-
-	/* If a state reset has been done, test_stateid is unneeded */
-	if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0)
-		return;
+	struct rpc_cred *cred;
+	int status;
 
 	/* Get the delegation credential for use by test/free_stateid */
 	rcu_read_lock();
 	delegation = rcu_dereference(NFS_I(state->inode)->delegation);
-	if (delegation != NULL &&
-	    nfs4_stateid_match(&delegation->stateid, stateid)) {
-		cred = get_rpccred(delegation->cred);
-		rcu_read_unlock();
-		status = nfs41_test_stateid(server, stateid, cred);
-		trace_nfs4_test_delegation_stateid(state, NULL, status);
-	} else
+	if (delegation == NULL) {
 		rcu_read_unlock();
+		return;
+	}
+
+	nfs4_stateid_copy(&stateid, &delegation->stateid);
+	cred = get_rpccred(delegation->cred);
+	rcu_read_unlock();
+	status = nfs41_test_stateid(server, &stateid, cred);
+	trace_nfs4_test_delegation_stateid(state, NULL, status);
 
 	if (status != NFS_OK) {
 		/* Free the stateid unless the server explicitly
 		 * informs us the stateid is unrecognized. */
 		if (status != -NFS4ERR_BAD_STATEID)
-			nfs41_free_stateid(server, stateid, cred);
-		nfs_remove_bad_delegation(state->inode);
-
-		write_seqlock(&state->seqlock);
-		nfs4_stateid_copy(&state->stateid, &state->open_stateid);
-		write_sequnlock(&state->seqlock);
-		clear_bit(NFS_DELEGATED_STATE, &state->flags);
+			nfs41_free_stateid(server, &stateid, cred);
+		nfs_finish_clear_delegation_stateid(state);
 	}
 
-	if (cred != NULL)
-		put_rpccred(cred);
+	put_rpccred(cred);
 }
 
 /**
@@ -2131,7 +2123,7 @@ static int nfs41_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
 {
 	int status;
 
-	nfs41_clear_delegation_stateid(state);
+	nfs41_check_delegation_stateid(state);
 	status = nfs41_check_open_stateid(state);
 	if (status != NFS_OK)
 		status = nfs4_open_expired(sp, state);
Signature · 1 line
2.1.3
author
#57 lore raw

PATCH 57/101 vmcore: Remove "weak" from function declarations

In reply to Jiri Slaby

From: Bjorn Helgaas <[email protected]>

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

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

commit 5ab03ac5aaa1f032e071f1b3dc433b7839359c03 upstream.

For the following functions:

elfcorehdr_alloc()
elfcorehdr_free()
elfcorehdr_read()
elfcorehdr_read_notes()
remap_oldmem_pfn_range()

fs/proc/vmcore.c provides default definitions explicitly marked "weak". arch/s390 provides its own definitions intended to override the default ones, but the "weak" attribute on the declarations applied to the s390 definitions as well, so the linker chose one based on link order (see 10629d711ed7 ("PCI: Remove __weak annotation from pcibios_get_phb_of_node decl")).

Remove the "weak" attribute from the declarations so we always prefer a non-weak definition over the weak one, independent of link order.

Fixes be8a8d069e50 ("vmcore: introduce ELF header in new memory feature")
Fixes 9cb218131de1 ("vmcore: introduce remap_oldmem_pfn_range()")
CC Michael Holzheu <[email protected]>
---
 include/linux/crash_dump.h | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)
include/linux/crash_dump.h +7 -8
index 7032518f8542..60023e5d3169 100644
@@ -14,14 +14,13 @@
 extern unsigned long long elfcorehdr_addr;
 extern unsigned long long elfcorehdr_size;
 
-extern int __weak elfcorehdr_alloc(unsigned long long *addr,
-				   unsigned long long *size);
-extern void __weak elfcorehdr_free(unsigned long long addr);
-extern ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos);
-extern ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos);
-extern int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma,
-					 unsigned long from, unsigned long pfn,
-					 unsigned long size, pgprot_t prot);
+extern int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size);
+extern void elfcorehdr_free(unsigned long long addr);
+extern ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos);
+extern ssize_t elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos);
+extern int remap_oldmem_pfn_range(struct vm_area_struct *vma,
+				  unsigned long from, unsigned long pfn,
+				  unsigned long size, pgprot_t prot);
 
 extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
 						unsigned long, int);
Signature · 1 line
2.1.3
author
#58 lore raw

PATCH 58/101 kgdb: Remove "weak" from kgdb_arch_pc() declaration

In reply to Jiri Slaby

From: Bjorn Helgaas <[email protected]>

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

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

commit 107bcc6d566cb40184068d888637f9aefe6252dd upstream.

kernel/debug/debug_core.c provides a default kgdb_arch_pc() definition explicitly marked "weak". Several architectures provide their own definitions intended to override the default, but the "weak" attribute on the declaration applied to the arch definitions as well, so the linker chose one based on link order (see 10629d711ed7 ("PCI: Remove __weak annotation from pcibios_get_phb_of_node decl")).

Remove the "weak" attribute from the declaration so we always prefer a non-weak definition over the weak one, independent of link order.

Fixes 688b744d8bc8 ("kgdb: fix signedness mixmatches, add statics, add declaration to header")
---
 include/linux/kgdb.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/kgdb.h +1 -1
index c6e091bf39a5..bdfc95bddde9 100644
@@ -283,7 +283,7 @@ struct kgdb_io {
 
 extern struct kgdb_arch		arch_kgdb_ops;
 
-extern unsigned long __weak kgdb_arch_pc(int exception, struct pt_regs *regs);
+extern unsigned long kgdb_arch_pc(int exception, struct pt_regs *regs);
 
 #ifdef CONFIG_SERIAL_KGDB_NMI
 extern int kgdb_register_nmi_console(void);
Signature · 1 line
2.1.3
author
#59 lore raw

PATCH 59/101 clocksource: Remove "weak" from clocksource_default_clock() declaration

In reply to Jiri Slaby

From: Bjorn Helgaas <[email protected]>

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

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

commit 96a2adbc6f501996418da9f7afe39bf0e4d006a9 upstream.

kernel/time/jiffies.c provides a default clocksource_default_clock() definition explicitly marked "weak". arch/s390 provides its own definition intended to override the default, but the "weak" attribute on the declaration applied to the s390 definition as well, so the linker chose one based on link order (see 10629d711ed7 ("PCI: Remove __weak annotation from pcibios_get_phb_of_node decl")).

Remove the "weak" attribute from the clocksource_default_clock() declaration so we always prefer a non-weak definition over the weak one, independent of link order.

Fixes f1b82746c1e9 ("clocksource: Cleanup clocksource selection")
CC Daniel Lezcano <[email protected]>
CC Martin Schwidefsky <[email protected]>
---
 include/linux/clocksource.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/clocksource.h +1 -1
index dbbf8aa7731b..48028261924c 100644
@@ -289,7 +289,7 @@ extern struct clocksource* clocksource_get_next(void);
 extern void clocksource_change_rating(struct clocksource *cs, int rating);
 extern void clocksource_suspend(void);
 extern void clocksource_resume(void);
-extern struct clocksource * __init __weak clocksource_default_clock(void);
+extern struct clocksource * __init clocksource_default_clock(void);
 extern void clocksource_mark_unstable(struct clocksource *cs);
 
 extern void
Signature · 1 line
2.1.3
author
#60 lore raw

PATCH 60/101 ipc: always handle a new value of auto_msgmni

In reply to Jiri Slaby

From: Andrey Vagin <[email protected]>

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

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

commit 1195d94e006b23c6292e78857e154872e33b6d7e upstream.

proc_dointvec_minmax() returns zero if a new value has been set. So we don't need to check all charecters have been handled.

Below you can find two examples. In the new value has not been handled properly.

$ strace ./a.out
open("/proc/sys/kernel/auto_msgmni", O_WRONLY) = 3
write(3, "0\n\0", 3)                    = 2
close(3)                                = 0
exit_group(0)
$ cat /sys/kernel/debug/tracing/trace

$strace ./a.out open("/proc/sys/kernel/auto_msgmni", O_WRONLY) = 3
write(3, "0\n", 2) = 2
close(3) = 0

$ cat /sys/kernel/debug/tracing/trace
a.out-697   [000] ....  3280.998235: unregister_ipcns_notifier <-proc_ipcauto_dointvec_minmax
Fixes 9eefe520c814 ("ipc: do not use a negative value to re-enable msgmni automatic recomputin")
Cc Mathias Krause <[email protected]>
Cc Manfred Spraul <[email protected]>
Cc Joe Perches <[email protected]>
Cc Davidlohr Bueso <[email protected]>
---
 ipc/ipc_sysctl.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
ipc/ipc_sysctl.c +1 -2
index b0e99deb6d05..a0f0ab2ac2a8 100644
@@ -123,7 +123,6 @@ static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write,
 	void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	struct ctl_table ipc_table;
-	size_t lenp_bef = *lenp;
 	int oldval;
 	int rc;
 
@@ -133,7 +132,7 @@ static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write,
 
 	rc = proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos);
 
-	if (write && !rc && lenp_bef == *lenp) {
+	if (write && !rc) {
 		int newval = *((int *)(ipc_table.data));
 		/*
 		 * The file "auto_msgmni" has correctly been set.
Signature · 1 line
2.1.3
author
#61 lore raw

PATCH 61/101 netfilter: nf_log: account for size of NLMSG_DONE attribute

In reply to Jiri Slaby

From: Florian Westphal <[email protected]>

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

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

commit 9dfa1dfe4d5e5e66a991321ab08afe69759d797a upstream.

We currently neither account for the nlattr size, nor do we consider the size of the trailing NLMSG_DONE when allocating nlmsg skb.

This can result in nflog to stop working, as __nfulnl_send() re-tries sending forever if it failed to append NLMSG_DONE (which will never work if buffer is not large enough).

---
 net/netfilter/nfnetlink_log.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
net/netfilter/nfnetlink_log.c +3 -3
index d92cc317bf8b..65791530f460 100644
@@ -651,7 +651,8 @@ nfulnl_log_packet(struct net *net,
 		+ nla_total_size(sizeof(u_int32_t))	/* gid */
 		+ nla_total_size(plen)			/* prefix */
 		+ nla_total_size(sizeof(struct nfulnl_msg_packet_hw))
-		+ nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp));
+		+ nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp))
+		+ nla_total_size(sizeof(struct nfgenmsg));	/* NLMSG_DONE */
 
 	if (in && skb_mac_header_was_set(skb)) {
 		size +=   nla_total_size(skb->dev->hard_header_len)
@@ -694,8 +695,7 @@ nfulnl_log_packet(struct net *net,
 		goto unlock_and_release;
 	}
 
-	if (inst->skb &&
-	    size > skb_tailroom(inst->skb) - sizeof(struct nfgenmsg)) {
+	if (inst->skb && size > skb_tailroom(inst->skb)) {
 		/* either the queue len is too high or we don't have
 		 * enough room in the skb left. flush to userspace. */
 		__nfulnl_flush(inst);
Signature · 1 line
2.1.3
author
#62 lore raw

PATCH 62/101 netfilter: nfnetlink_log: fix maximum packet length logged to userspace

In reply to Jiri Slaby

From: Florian Westphal <[email protected]>

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

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

commit c1e7dc91eed0ed1a51c9b814d648db18bf8fc6e9 upstream.

don't try to queue payloads > 0xffff - NLA_HDRLEN, it does not work. The nla length includes the size of the nla struct, so anything larger results in u16 integer overflow.

This patch is similar to
9cefbbc9c8f9abe (netfilter: nfnetlink_queue: cleanup copy_range usage).

---
 net/netfilter/nfnetlink_log.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
net/netfilter/nfnetlink_log.c +5 -3
index 65791530f460..39010fc1e9c0 100644
@@ -45,7 +45,8 @@
 #define NFULNL_NLBUFSIZ_DEFAULT	NLMSG_GOODSIZE
 #define NFULNL_TIMEOUT_DEFAULT 	100	/* every second */
 #define NFULNL_QTHRESH_DEFAULT 	100	/* 100 packets */
-#define NFULNL_COPY_RANGE_MAX	0xFFFF	/* max packet size is limited by 16-bit struct nfattr nfa_len field */
+/* max packet size is limited by 16-bit struct nfattr nfa_len field */
+#define NFULNL_COPY_RANGE_MAX	(0xFFFF - NLA_HDRLEN)
 
 #define PRINTR(x, args...)	do { if (net_ratelimit()) \
 				     printk(x, ## args); } while (0);
@@ -255,6 +256,8 @@ nfulnl_set_mode(struct nfulnl_instance *inst, u_int8_t mode,
 
 	case NFULNL_COPY_PACKET:
 		inst->copy_mode = mode;
+		if (range == 0)
+			range = NFULNL_COPY_RANGE_MAX;
 		inst->copy_range = min_t(unsigned int,
 					 range, NFULNL_COPY_RANGE_MAX);
 		break;
@@ -681,8 +684,7 @@ nfulnl_log_packet(struct net *net,
 		break;
 
 	case NFULNL_COPY_PACKET:
-		if (inst->copy_range == 0
-		    || inst->copy_range > skb->len)
+		if (inst->copy_range > skb->len)
 			data_len = skb->len;
 		else
 			data_len = inst->copy_range;
Signature · 1 line
2.1.3
author
#63 lore raw

PATCH 63/101 netfilter: nf_log: release skbuff on nlmsg put failure

In reply to Jiri Slaby

From: Houcheng Lin <[email protected]>

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

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

commit b51d3fa364885a2c1e1668f88776c67c95291820 upstream.

The kernel should reserve enough room in the skb so that the DONE message can always be appended. However, in case of e.g. new attribute erronously not being size-accounted for, __nfulnl_send() will still try to put next nlmsg into this full skbuf, causing the skb to be stuck forever and blocking delivery of further messages.

Fix issue by releasing skb immediately after nlmsg_put error and WARN() so we can track down the cause of such size mismatch.

[ [email protected]: add tailroom/len info to WARN ]

---
 net/netfilter/nfnetlink_log.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)
net/netfilter/nfnetlink_log.c +8 -9
index 39010fc1e9c0..09172d7abee2 100644
@@ -348,26 +348,25 @@ nfulnl_alloc_skb(u32 peer_portid, unsigned int inst_size, unsigned int pkt_size)
 	return skb;
 }
 
-static int
+static void
 __nfulnl_send(struct nfulnl_instance *inst)
 {
-	int status = -1;
-
 	if (inst->qlen > 1) {
 		struct nlmsghdr *nlh = nlmsg_put(inst->skb, 0, 0,
 						 NLMSG_DONE,
 						 sizeof(struct nfgenmsg),
 						 0);
-		if (!nlh)
+		if (WARN_ONCE(!nlh, "bad nlskb size: %u, tailroom %d\n",
+			      inst->skb->len, skb_tailroom(inst->skb))) {
+			kfree_skb(inst->skb);
 			goto out;
+		}
 	}
-	status = nfnetlink_unicast(inst->skb, inst->net, inst->peer_portid,
-				   MSG_DONTWAIT);
-
+	nfnetlink_unicast(inst->skb, inst->net, inst->peer_portid,
+			  MSG_DONTWAIT);
+out:
 	inst->qlen = 0;
 	inst->skb = NULL;
-out:
-	return status;
 }
 
 static void
Signature · 1 line
2.1.3
author
#64 lore raw

PATCH 64/101 netfilter: xt_bpf: add mising opaque struct sk_filter definition

In reply to Jiri Slaby

From: Pablo Neira <[email protected]>

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

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

commit e10038a8ec06ac819b7552bb67aaa6d2d6f850c1 upstream.

This structure is not exposed to userspace, so fix this by defining struct sk_filter; so we skip the casting in kernelspace. This is safe since userspace has no way to lurk with that internal pointer.

Fixes e6f30c7 ("netfilter: x_tables: add xt_bpf match")
---
 include/uapi/linux/netfilter/xt_bpf.h | 2 ++
 1 file changed, 2 insertions(+)
include/uapi/linux/netfilter/xt_bpf.h +2 -0
index 5dda450eb55b..2ec9fbcd06f9 100644
@@ -6,6 +6,8 @@
 
 #define XT_BPF_MAX_NUM_INSTR	64
 
+struct sk_filter;
+
 struct xt_bpf_info {
 	__u16 bpf_program_num_elem;
 	struct sock_filter bpf_program[XT_BPF_MAX_NUM_INSTR];
Signature · 1 line
2.1.3
author
#65 lore raw

PATCH 65/101 ARM: probes: fix instruction fetch order with <asm/opcodes.h>

In reply to Jiri Slaby

From: Ben Dooks <[email protected]>

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

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

commit 888be25402021a425da3e85e2d5a954d7509286e upstream.

If we are running BE8, the data and instruction endianness do not match, so use <asm/opcodes.h> to correctly translate memory accesses into ARM instructions.

[wangnan: backport to 3.10 and 3.14:
- adjust context
- backport all changes on arch/arm/kernel/probes.c to arch/arm/kernel/kprobes-common.c since we don't have commit c18377c303787ded44b7decd7dee694db0f205e9.
- After the above adjustments, becomes same to Taras Kondratiuk's original patch:

     http://lists.linaro.org/pipermail/linaro-kernel/2014-January/010346.html

]

---
 arch/arm/kernel/kprobes-common.c | 19 +++++++++++--------
 arch/arm/kernel/kprobes-thumb.c  | 21 +++++++++++++--------
 arch/arm/kernel/kprobes.c        |  9 +++++----
 3 files changed, 29 insertions(+), 20 deletions(-)
arch/arm/kernel/kprobes-common.c +11 -8
index 18a76282970e..380c20fb9c85 100644
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/kprobes.h>
 #include <asm/system_info.h>
+#include <asm/opcodes.h>
 
 #include "kprobes.h"
 
@@ -305,7 +306,8 @@ kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 
 	if (handler) {
 		/* We can emulate the instruction in (possibly) modified form */
-		asi->insn[0] = (insn & 0xfff00000) | (rn << 16) | reglist;
+		asi->insn[0] = __opcode_to_mem_arm((insn & 0xfff00000) |
+						   (rn << 16) | reglist);
 		asi->insn_handler = handler;
 		return INSN_GOOD;
 	}
@@ -334,13 +336,14 @@ prepare_emulated_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
 #ifdef CONFIG_THUMB2_KERNEL
 	if (thumb) {
 		u16 *thumb_insn = (u16 *)asi->insn;
-		thumb_insn[1] = 0x4770; /* Thumb bx lr */
-		thumb_insn[2] = 0x4770; /* Thumb bx lr */
+		/* Thumb bx lr */
+		thumb_insn[1] = __opcode_to_mem_thumb16(0x4770);
+		thumb_insn[2] = __opcode_to_mem_thumb16(0x4770);
 		return insn;
 	}
-	asi->insn[1] = 0xe12fff1e; /* ARM bx lr */
+	asi->insn[1] = __opcode_to_mem_arm(0xe12fff1e); /* ARM bx lr */
 #else
-	asi->insn[1] = 0xe1a0f00e; /* mov pc, lr */
+	asi->insn[1] = __opcode_to_mem_arm(0xe1a0f00e); /* mov pc, lr */
 #endif
 	/* Make an ARM instruction unconditional */
 	if (insn < 0xe0000000)
@@ -360,12 +363,12 @@ set_emulated_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
 	if (thumb) {
 		u16 *ip = (u16 *)asi->insn;
 		if (is_wide_instruction(insn))
-			*ip++ = insn >> 16;
-		*ip++ = insn;
+			*ip++ = __opcode_to_mem_thumb16(insn >> 16);
+		*ip++ = __opcode_to_mem_thumb16(insn);
 		return;
 	}
 #endif
-	asi->insn[0] = insn;
+	asi->insn[0] = __opcode_to_mem_arm(insn);
 }
 
 /*
arch/arm/kernel/kprobes-thumb.c +13 -8
index 6123daf397a7..241222c66a13 100644
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/kprobes.h>
 #include <linux/module.h>
+#include <asm/opcodes.h>
 
 #include "kprobes.h"
 
@@ -163,9 +164,9 @@ t32_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 	enum kprobe_insn ret = kprobe_decode_ldmstm(insn, asi);
 
 	/* Fixup modified instruction to have halfwords in correct order...*/
-	insn = asi->insn[0];
-	((u16 *)asi->insn)[0] = insn >> 16;
-	((u16 *)asi->insn)[1] = insn & 0xffff;
+	insn = __mem_to_opcode_arm(asi->insn[0]);
+	((u16 *)asi->insn)[0] = __opcode_to_mem_thumb16(insn >> 16);
+	((u16 *)asi->insn)[1] = __opcode_to_mem_thumb16(insn & 0xffff);
 
 	return ret;
 }
@@ -1153,7 +1154,7 @@ t16_decode_hiregs(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 {
 	insn &= ~0x00ff;
 	insn |= 0x001; /* Set Rdn = R1 and Rm = R0 */
-	((u16 *)asi->insn)[0] = insn;
+	((u16 *)asi->insn)[0] = __opcode_to_mem_thumb16(insn);
 	asi->insn_handler = t16_emulate_hiregs;
 	return INSN_GOOD;
 }
@@ -1182,8 +1183,10 @@ t16_decode_push(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 	 * and call it with R9=SP and LR in the register list represented
 	 * by R8.
 	 */
-	((u16 *)asi->insn)[0] = 0xe929;		/* 1st half STMDB R9!,{} */
-	((u16 *)asi->insn)[1] = insn & 0x1ff;	/* 2nd half (register list) */
+	/* 1st half STMDB R9!,{} */
+	((u16 *)asi->insn)[0] = __opcode_to_mem_thumb16(0xe929);
+	/* 2nd half (register list) */
+	((u16 *)asi->insn)[1] = __opcode_to_mem_thumb16(insn & 0x1ff);
 	asi->insn_handler = t16_emulate_push;
 	return INSN_GOOD;
 }
@@ -1232,8 +1235,10 @@ t16_decode_pop(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 	 * and call it with R9=SP and PC in the register list represented
 	 * by R8.
 	 */
-	((u16 *)asi->insn)[0] = 0xe8b9;		/* 1st half LDMIA R9!,{} */
-	((u16 *)asi->insn)[1] = insn & 0x1ff;	/* 2nd half (register list) */
+	/* 1st half LDMIA R9!,{} */
+	((u16 *)asi->insn)[0] = __opcode_to_mem_thumb16(0xe8b9);
+	/* 2nd half (register list) */
+	((u16 *)asi->insn)[1] = __opcode_to_mem_thumb16(insn & 0x1ff);
 	asi->insn_handler = insn & 0x100 ? t16_emulate_pop_pc
 					 : t16_emulate_pop_nopc;
 	return INSN_GOOD;
arch/arm/kernel/kprobes.c +5 -4
index 170e9f34003f..1c6ece51781c 100644
@@ -26,6 +26,7 @@
 #include <linux/stop_machine.h>
 #include <linux/stringify.h>
 #include <asm/traps.h>
+#include <asm/opcodes.h>
 #include <asm/cacheflush.h>
 
 #include "kprobes.h"
@@ -62,10 +63,10 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
 #ifdef CONFIG_THUMB2_KERNEL
 	thumb = true;
 	addr &= ~1; /* Bit 0 would normally be set to indicate Thumb code */
-	insn = ((u16 *)addr)[0];
+	insn = __mem_to_opcode_thumb16(((u16 *)addr)[0]);
 	if (is_wide_instruction(insn)) {
-		insn <<= 16;
-		insn |= ((u16 *)addr)[1];
+		u16 inst2 = __mem_to_opcode_thumb16(((u16 *)addr)[1]);
+		insn = __opcode_thumb32_compose(insn, inst2);
 		decode_insn = thumb32_kprobe_decode_insn;
 	} else
 		decode_insn = thumb16_kprobe_decode_insn;
@@ -73,7 +74,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
 	thumb = false;
 	if (addr & 0x3)
 		return -EINVAL;
-	insn = *p->addr;
+	insn = __mem_to_opcode_arm(*p->addr);
 	decode_insn = arm_kprobe_decode_insn;
 #endif
 
Signature · 1 line
2.1.3
author
#66 lore raw

PATCH 66/101 rcu: Make callers awaken grace-period kthread

In reply to Jiri Slaby

From: "Paul E. McKenney" <[email protected]>

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

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

commit 48a7639ce80cf279834d0d44865e49ecd714f37d upstream.

The rcu_start_gp_advanced() function currently uses irq_work_queue() to defer wakeups of the RCU grace-period kthread. This deferring is necessary to avoid RCU-scheduler deadlocks involving the rcu_node structure's lock, meaning that RCU cannot call any of the scheduler's wake-up functions while holding one of these locks.

Unfortunately, the second and subsequent calls to irq_work_queue() are ignored, and the first call will be ignored (aside from queuing the work item) if the scheduler-clock tick is turned off. This is OK for many uses, especially those where irq_work_queue() is called from an interrupt or softirq handler, because in those cases the scheduler-clock-tick state will be re-evaluated, which will turn the scheduler-clock tick back on. On the next tick, any deferred work will then be processed.

However, this strategy does not always work for RCU, which can be invoked at process level from idle CPUs. In this case, the tick might never be turned back on, indefinitely defering a grace-period start request. Note that the RCU CPU stall detector cannot see this condition, because there is no RCU grace period in progress. Therefore, we can (and do!) see long tens-of-seconds stalls in grace-period handling. In theory, we could see a full grace-period hang, but rcutorture testing to date has seen only the tens-of-seconds stalls. Event tracing demonstrates that irq_work_queue() is being called repeatedly to no effect during these stalls: The "newreq" event appears repeatedly from a task that is not one of the grace-period kthreads.

In theory, irq_work_queue() might be fixed to avoid this sort of issue, but RCU's requirements are unusual and it is quite straightforward to pass wake-up responsibility up through RCU's call chain, so that the wakeup happens when the offending locks are released.

This commit therefore makes this change. The rcu_start_gp_advanced(), rcu_start_future_gp(), rcu_accelerate_cbs(), rcu_advance_cbs(), __note_gp_changes(), and rcu_start_gp() functions now return a boolean which indicates when a wake-up is needed. A new rcu_gp_kthread_wake() does the wakeup when it is necessary and safe to do so: No self-wakes, no wake-ups if the ->gp_flags field indicates there is no need (as in someone else did the wake-up before we got around to it), and no wake-ups before the grace-period kthread has been created.

Cc Peter Zijlstra <[email protected]>
Cc Steven Rostedt <[email protected]>
Cc Frederic Weisbecker <[email protected]>

[ Pranith: backport to 3.13-stable: just rcu_gp_kthread_wake(),
prereq for 2aa792e "rcu: Use rcu_gp_kthread_wake() to wake up grace period kthreads" ]

---
 kernel/rcutree.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)
kernel/rcutree.c +17 -1
index 32618b3fe4e6..ec5848e9d5d9 100644
@@ -1131,6 +1131,22 @@ static int rcu_future_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp)
 }
 
 /*
+ * Awaken the grace-period kthread for the specified flavor of RCU.
+ * Don't do a self-awaken, and don't bother awakening when there is
+ * nothing for the grace-period kthread to do (as in several CPUs
+ * raced to awaken, and we lost), and finally don't try to awaken
+ * a kthread that has not yet been created.
+ */
+static void rcu_gp_kthread_wake(struct rcu_state *rsp)
+{
+	if (current == rsp->gp_kthread ||
+	    !ACCESS_ONCE(rsp->gp_flags) ||
+	    !rsp->gp_kthread)
+		return;
+	wake_up(&rsp->gp_wq);
+}
+
+/*
  * If there is room, assign a ->completed number to any callbacks on
  * this CPU that have not already been assigned.  Also accelerate any
  * callbacks that were previously assigned a ->completed number that has
@@ -1528,7 +1544,7 @@ static void rsp_wakeup(struct irq_work *work)
 	struct rcu_state *rsp = container_of(work, struct rcu_state, wakeup_work);
 
 	/* Wake up rcu_gp_kthread() to start the grace period. */
-	wake_up(&rsp->gp_wq);
+	rcu_gp_kthread_wake(rsp);
 }
 
 /*
Signature · 1 line
2.1.3
author
#67 lore raw

PATCH 67/101 rcu: Use rcu_gp_kthread_wake() to wake up grace period kthreads

In reply to Jiri Slaby

From: Pranith Kumar <[email protected]>

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

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

commit 2aa792e6faf1a00f5accf1f69e87e11a390ba2cd upstream.

The rcu_gp_kthread_wake() function checks for three conditions before waking up grace period kthreads:

*  Is the thread we are trying to wake up the current thread?
*  Are the gp_flags zero? (all threads wait on non-zero gp_flags condition)
*  Is there no thread created for this flavour, hence nothing to wake up?

If any one of these condition is true, we do not call wake_up(). It was found that there are quite a few avoidable wake ups both during idle time and under stress induced by rcutorture.

Idle:

Total:66000, unnecessary:66000, case1:61827, case2:66000, case3:0 Total:68000, unnecessary:68000, case1:63696, case2:68000, case3:0

rcutorture:

Total:254000, unnecessary:254000, case1:199913, case2:254000, case3:0 Total:256000, unnecessary:256000, case1:201784, case2:256000, case3:0

Here case{1-3} are the cases listed above. We can avoid these wake ups by using rcu_gp_kthread_wake() to conditionally wake up the grace period kthreads.

There is a comment about an implied barrier supplied by the wake_up() logic. This barrier is necessary for the awakened thread to see the updated ->gp_flags. This flag is always being updated with the root node lock held. Also, the awakened thread tries to acquire the root node lock before reading ->gp_flags because of which there is proper ordering.

Hence this commit tries to avoid calling wake_up() whenever we can by using rcu_gp_kthread_wake() function.

---
 kernel/rcutree.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/rcutree.c +2 -2
index ec5848e9d5d9..e27526232b5f 100644
@@ -1618,7 +1618,7 @@ static void rcu_report_qs_rsp(struct rcu_state *rsp, unsigned long flags)
 {
 	WARN_ON_ONCE(!rcu_gp_in_progress(rsp));
 	raw_spin_unlock_irqrestore(&rcu_get_root(rsp)->lock, flags);
-	wake_up(&rsp->gp_wq);  /* Memory barrier implied by wake_up() path. */
+	rcu_gp_kthread_wake(rsp);
 }
 
 /*
@@ -2188,7 +2188,7 @@ static void force_quiescent_state(struct rcu_state *rsp)
 	}
 	rsp->gp_flags |= RCU_GP_FLAG_FQS;
 	raw_spin_unlock_irqrestore(&rnp_old->lock, flags);
-	wake_up(&rsp->gp_wq);  /* Memory barrier implied by wake_up() path. */
+	rcu_gp_kthread_wake(rsp);
 }
 
 /*
Signature · 1 line
2.1.3
author
#68 lore raw

PATCH 68/101 KVM: x86: Don't report guest userspace emulation error to userspace

In reply to Jiri Slaby

From: Nadav Amit <[email protected]>

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

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

commit a2b9e6c1a35afcc0973acb72e591c714e78885ff upstream.

Commit fc3a9157d314 ("KVM: X86: Don't report L2 emulation failures to user-space") disabled the reporting of L2 (nested guest) emulation failures to userspace due to race-condition between a vmexit and the instruction emulator. The same rational applies also to userspace applications that are permitted by the guest OS to access MMIO area or perform PIO.

This patch extends the current behavior - of injecting a #UD instead of reporting it to userspace - also for guest userspace code.

---
 arch/x86/kvm/x86.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/x86.c +1 -1
index 590fd966b37a..790551bc4f15 100644
@@ -4871,7 +4871,7 @@ static int handle_emulation_failure(struct kvm_vcpu *vcpu)
 
 	++vcpu->stat.insn_emulation_fail;
 	trace_kvm_emulate_insn_failed(vcpu);
-	if (!is_guest_mode(vcpu)) {
+	if (!is_guest_mode(vcpu) && kvm_x86_ops->get_cpl(vcpu) == 0) {
 		vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
 		vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
 		vcpu->run->internal.ndata = 0;
Signature · 1 line
2.1.3
author
#69 lore raw

PATCH 69/101 net: sctp: fix remote memory pressure from excessive queueing

In reply to Jiri Slaby

From: Daniel Borkmann <[email protected]>

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

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

commit 26b87c7881006311828bb0ab271a551a62dcceb4 upstream.

This scenario is not limited to ASCONF, just taken as one example triggering the issue. When receiving ASCONF probes in the form of ...

-------------- INIT[ASCONF; ASCONF_ACK] -------------> <----------- INIT-ACK[ASCONF; ASCONF_ACK] ------------ -------------------- COOKIE-ECHO --------------------> <-------------------- COOKIE-ACK --------------------- ---- ASCONF_a; [ASCONF_b; ...; ASCONF_n;] JUNK ------> [...]
---- ASCONF_m; [ASCONF_o; ...; ASCONF_z;] JUNK ------>

... where ASCONF_a, ASCONF_b, ..., ASCONF_z are good-formed ASCONFs and have increasing serial numbers, we process such ASCONF chunk(s) marked with !end_of_packet and !singleton, since we have not yet reached the SCTP packet end. SCTP does only do verification on a chunk by chunk basis, as an SCTP packet is nothing more than just a container of a stream of chunks which it eats up one by one.

We could run into the case that we receive a packet with a malformed tail, above marked as trailing JUNK. All previous chunks are here goodformed, so the stack will eat up all previous chunks up to this point. In case JUNK does not fit into a chunk header and there are no more other chunks in the input queue, or in case JUNK contains a garbage chunk header, but the encoded chunk length would exceed the skb tail, or we came here from an entirely different scenario and the chunk has pdiscard=1 mark (without having had a flush point), it will happen, that we will excessively queue up the association's output queue (a correct final chunk may then turn it into a response flood when flushing the queue ;)): I ran a simple script with incremental ASCONF serial numbers and could see the server side consuming excessive amount of RAM [before/after: up to 2GB and more].

The issue at heart is that the chunk train basically ends with !end_of_packet and !singleton markers and since commit 2e3216cd54b1 ("sctp: Follow security requirement of responding with 1 packet") therefore preventing an output queue flush point in sctp_do_sm() -> sctp_cmd_interpreter() on the input chunk (chunk = event_arg) even though local_cork is set, but its precedence has changed since then. In the normal case, the last chunk with end_of_packet=1 would trigger the queue flush to accommodate possible outgoing bundling.

In the input queue, sctp_inq_pop() seems to do the right thing in terms of discarding invalid chunks. So, above JUNK will not enter the state machine and instead be released and exit the sctp_assoc_bh_rcv() chunk processing loop. It's simply the flush point being missing at loop exit. Adding a try-flush approach on the output queue might not work as the underlying infrastructure might be long gone at this point due to the side-effect interpreter run.

One possibility, albeit a bit of a kludge, would be to defer invalid chunk freeing into the state machine in order to possibly trigger packet discards and thus indirectly a queue flush on error. It would surely be better to discard chunks as in the current, perhaps better controlled environment, but going back and forth, it's simply architecturally not possible. I tried various trailing JUNK attack cases and it seems to look good now.

Joint work with Vlad Yasevich.

Fixes 2e3216cd54b1 ("sctp: Follow security requirement of responding with 1 packet")
Cc Josh Boyer <[email protected]>
---
 net/sctp/inqueue.c      | 33 +++++++--------------------------
 net/sctp/sm_statefuns.c |  3 +++
 2 files changed, 10 insertions(+), 26 deletions(-)
net/sctp/inqueue.c +7 -26
index 5856932fdc38..560cd418a181 100644
@@ -141,18 +141,9 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
 		} else {
 			/* Nothing to do. Next chunk in the packet, please. */
 			ch = (sctp_chunkhdr_t *) chunk->chunk_end;
-
 			/* Force chunk->skb->data to chunk->chunk_end.  */
-			skb_pull(chunk->skb,
-				 chunk->chunk_end - chunk->skb->data);
-
-			/* Verify that we have at least chunk headers
-			 * worth of buffer left.
-			 */
-			if (skb_headlen(chunk->skb) < sizeof(sctp_chunkhdr_t)) {
-				sctp_chunk_free(chunk);
-				chunk = queue->in_progress = NULL;
-			}
+			skb_pull(chunk->skb, chunk->chunk_end - chunk->skb->data);
+			/* We are guaranteed to pull a SCTP header. */
 		}
 	}
 
@@ -188,24 +179,14 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
 	skb_pull(chunk->skb, sizeof(sctp_chunkhdr_t));
 	chunk->subh.v = NULL; /* Subheader is no longer valid.  */
 
-	if (chunk->chunk_end < skb_tail_pointer(chunk->skb)) {
+	if (chunk->chunk_end + sizeof(sctp_chunkhdr_t) <
+	    skb_tail_pointer(chunk->skb)) {
 		/* This is not a singleton */
 		chunk->singleton = 0;
 	} else if (chunk->chunk_end > skb_tail_pointer(chunk->skb)) {
-		/* RFC 2960, Section 6.10  Bundling
-		 *
-		 * Partial chunks MUST NOT be placed in an SCTP packet.
-		 * If the receiver detects a partial chunk, it MUST drop
-		 * the chunk.
-		 *
-		 * Since the end of the chunk is past the end of our buffer
-		 * (which contains the whole packet, we can freely discard
-		 * the whole packet.
-		 */
-		sctp_chunk_free(chunk);
-		chunk = queue->in_progress = NULL;
-
-		return NULL;
+		/* Discard inside state machine. */
+		chunk->pdiscard = 1;
+		chunk->chunk_end = skb_tail_pointer(chunk->skb);
 	} else {
 		/* We are at the end of the packet, so mark the chunk
 		 * in case we need to send a SACK.
net/sctp/sm_statefuns.c +3 -0
index 1dbcc6a4d800..62623ccc4089 100644
@@ -171,6 +171,9 @@ sctp_chunk_length_valid(struct sctp_chunk *chunk,
 {
 	__u16 chunk_length = ntohs(chunk->chunk_hdr->length);
 
+	/* Previously already marked? */
+	if (unlikely(chunk->pdiscard))
+		return 0;
 	if (unlikely(chunk_length < required_length))
 		return 0;
 
Signature · 1 line
2.1.3
author
#70 lore raw

PATCH 70/101 net: sctp: fix panic on duplicate ASCONF chunks

In reply to Jiri Slaby

From: Daniel Borkmann <[email protected]>

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

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

commit b69040d8e39f20d5215a03502a8e8b4c6ab78395 upstream.

When receiving a e.g. semi-good formed connection scan in the form of ...

-------------- INIT[ASCONF; ASCONF_ACK] -------------> <----------- INIT-ACK[ASCONF; ASCONF_ACK] ------------ -------------------- COOKIE-ECHO --------------------> <-------------------- COOKIE-ACK --------------------- ---------------- ASCONF_a; ASCONF_b ----------------->

... where ASCONF_a equals ASCONF_b chunk (at least both serials need to be equal), we panic an SCTP server!

The problem is that good-formed ASCONF chunks that we reply with ASCONF_ACK chunks are cached per serial. Thus, when we receive a same ASCONF chunk twice (e.g. through a lost ASCONF_ACK), we do not need to process them again on the server side (that was the idea, also proposed in the RFC). Instead, we know it was cached and we just resend the cached chunk instead. So far, so good.

Where things get nasty is in SCTP's side effect interpreter, that is, sctp_cmd_interpreter():

While incoming ASCONF_a (chunk = event_arg) is being marked !end_of_packet and !singleton, and we have an association context, we do not flush the outqueue the first time after processing the ASCONF_ACK singleton chunk via SCTP_CMD_REPLY. Instead, we keep it queued up, although we set local_cork to 1. Commit 2e3216cd54b1 changed the precedence, so that as long as we get bundled, incoming chunks we try possible bundling on outgoing queue as well. Before this commit, we would just flush the output queue.

Now, while ASCONF_a's ASCONF_ACK sits in the corked outq, we continue to process the same ASCONF_b chunk from the packet. As we have cached the previous ASCONF_ACK, we find it, grab it and do another SCTP_CMD_REPLY command on it. So, effectively, we rip the chunk->list pointers and requeue the same ASCONF_ACK chunk another time. Since we process ASCONF_b, it's correctly marked with end_of_packet and we enforce an uncork, and thus flush, thus crashing the kernel.

Fix it by testing if the ASCONF_ACK is currently pending and if that is the case, do not requeue it. When flushing the output queue we may relink the chunk for preparing an outgoing packet, but eventually unlink it when it's copied into the skb right before transmission.

Joint work with Vlad Yasevich.

Fixes 2e3216cd54b1 ("sctp: Follow security requirement of responding with 1 packet")
Cc Josh Boyer <[email protected]>
---
 include/net/sctp/sctp.h | 5 +++++
 net/sctp/associola.c    | 2 ++
 2 files changed, 7 insertions(+)
include/net/sctp/sctp.h +5 -0
index 3794c5ad20fe..3848934ab162 100644
@@ -454,6 +454,11 @@ static inline void sctp_assoc_pending_pmtu(struct sock *sk, struct sctp_associat
 	asoc->pmtu_pending = 0;
 }
 
+static inline bool sctp_chunk_pending(const struct sctp_chunk *chunk)
+{
+	return !list_empty(&chunk->list);
+}
+
 /* Walk through a list of TLV parameters.  Don't trust the
  * individual parameter lengths and instead depend on
  * the chunk length to indicate when to stop.  Make sure
net/sctp/associola.c +2 -0
index ad5cd6f20e78..737050f1b2b2 100644
@@ -1645,6 +1645,8 @@ struct sctp_chunk *sctp_assoc_lookup_asconf_ack(
 	 * ack chunk whose serial number matches that of the request.
 	 */
 	list_for_each_entry(ack, &asoc->asconf_ack_list, transmitted_list) {
+		if (sctp_chunk_pending(ack))
+			continue;
 		if (ack->subh.addip_hdr->serial == serial) {
 			sctp_chunk_hold(ack);
 			return ack;
Signature · 1 line
2.1.3
author
#71 lore raw

PATCH 71/101 net: sctp: fix skb_over_panic when receiving malformed ASCONF chunks

In reply to Jiri Slaby

From: Daniel Borkmann <[email protected]>

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

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

commit 9de7922bc709eee2f609cd01d98aaedc4cf5ea74 upstream.

Commit 6f4c618ddb0 ("SCTP : Add paramters validity check for ASCONF chunk") added basic verification of ASCONF chunks, however, it is still possible to remotely crash a server by sending a special crafted ASCONF chunk, even up to pre 2.6.12 kernels:

skb_over_panic: text:ffffffffa01ea1c3 len:31056 put:30768
head:ffff88011bd81800 data:ffff88011bd81800 tail:0x7950 end:0x440 dev:<NULL>

 ------------[ cut here ]------------
kernel BUG at net/core/skbuff.c:129!
[...]
Call Trace:
 <IRQ>
 [<ffffffff8144fb1c>] skb_put+0x5c/0x70
 [<ffffffffa01ea1c3>] sctp_addto_chunk+0x63/0xd0 [sctp]
 [<ffffffffa01eadaf>] sctp_process_asconf+0x1af/0x540 [sctp]
 [<ffffffff8152d025>] ? _read_unlock_bh+0x15/0x20
 [<ffffffffa01e0038>] sctp_sf_do_asconf+0x168/0x240 [sctp]
 [<ffffffffa01e3751>] sctp_do_sm+0x71/0x1210 [sctp]
 [<ffffffff8147645d>] ? fib_rules_lookup+0xad/0xf0
 [<ffffffffa01e6b22>] ? sctp_cmp_addr_exact+0x32/0x40 [sctp]
 [<ffffffffa01e8393>] sctp_assoc_bh_rcv+0xd3/0x180 [sctp]
 [<ffffffffa01ee986>] sctp_inq_push+0x56/0x80 [sctp]
 [<ffffffffa01fcc42>] sctp_rcv+0x982/0xa10 [sctp]
 [<ffffffffa01d5123>] ? ipt_local_in_hook+0x23/0x28 [iptable_filter]
 [<ffffffff8148bdc9>] ? nf_iterate+0x69/0xb0
 [<ffffffff81496d10>] ? ip_local_deliver_finish+0x0/0x2d0
 [<ffffffff8148bf86>] ? nf_hook_slow+0x76/0x120
 [<ffffffff81496d10>] ? ip_local_deliver_finish+0x0/0x2d0
 [<ffffffff81496ded>] ip_local_deliver_finish+0xdd/0x2d0
 [<ffffffff81497078>] ip_local_deliver+0x98/0xa0
 [<ffffffff8149653d>] ip_rcv_finish+0x12d/0x440
 [<ffffffff81496ac5>] ip_rcv+0x275/0x350
 [<ffffffff8145c88b>] __netif_receive_skb+0x4ab/0x750
 [<ffffffff81460588>] netif_receive_skb+0x58/0x60

This can be triggered e.g., through a simple scripted nmap connection scan injecting the chunk after the handshake, for example, ...

-------------- INIT[ASCONF; ASCONF_ACK] -------------> <----------- INIT-ACK[ASCONF; ASCONF_ACK] ------------ -------------------- COOKIE-ECHO --------------------> <-------------------- COOKIE-ACK --------------------- ------------------ ASCONF; UNKNOWN ------------------>

... where ASCONF chunk of length 280 contains 2 parameters ...

1) Add IP address parameter (param length: 16)
2) Add/del IP address parameter (param length: 255)

... followed by an UNKNOWN chunk of e.g. 4 bytes. Here, the Address Parameter in the ASCONF chunk is even missing, too. This is just an example and similarly-crafted ASCONF chunks could be used just as well.

The ASCONF chunk passes through sctp_verify_asconf() as all parameters passed sanity checks, and after walking, we ended up successfully at the chunk end boundary, and thus may invoke sctp_process_asconf(). Parameter walking is done with WORD_ROUND() to take padding into account.

In sctp_process_asconf()'s TLV processing, we may fail in sctp_process_asconf_param() e.g., due to removal of the IP address that is also the source address of the packet containing the ASCONF chunk, and thus we need to add all TLVs after the failure to our ASCONF response to remote via helper function sctp_add_asconf_response(), which basically invokes a sctp_addto_chunk() adding the error parameters to the given skb.

When walking to the next parameter this time, we proceed with ...

  length = ntohs(asconf_param->param_hdr.length);
  asconf_param = (void *)asconf_param + length;

... instead of the WORD_ROUND()'ed length, thus resulting here in an off-by-one that leads to reading the follow-up garbage parameter length of 12336, and thus throwing an skb_over_panic for the reply when trying to sctp_addto_chunk() next time, which implicitly calls the skb_put() with that length.

Fix it by using sctp_walk_params() [ which is also used in INIT parameter processing ] macro in the verification *and* in ASCONF processing: it will make sure we don't spill over, that we walk parameters WORD_ROUND()'ed. Moreover, we're being more defensive and guard against unknown parameter types and missized addresses.

Joint work with Vlad Yasevich.

Fixes b896b82be4ae ("[SCTP] ADDIP: Support for processing incoming ASCONF_ACK chunks.")
Cc Josh Boyer <[email protected]>
---
 include/net/sctp/sm.h    |  6 +--
 net/sctp/sm_make_chunk.c | 99 +++++++++++++++++++++++++++---------------------
 net/sctp/sm_statefuns.c  | 18 +--------
 3 files changed, 60 insertions(+), 63 deletions(-)
include/net/sctp/sm.h +3 -3
index 4ef75af340b6..c91b6f5c07a5 100644
@@ -249,9 +249,9 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *,
 					      int, __be16);
 struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
 					     union sctp_addr *addr);
-int sctp_verify_asconf(const struct sctp_association *asoc,
-		       struct sctp_paramhdr *param_hdr, void *chunk_end,
-		       struct sctp_paramhdr **errp);
+bool sctp_verify_asconf(const struct sctp_association *asoc,
+			struct sctp_chunk *chunk, bool addr_param_needed,
+			struct sctp_paramhdr **errp);
 struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
 				       struct sctp_chunk *asconf);
 int sctp_process_asconf_ack(struct sctp_association *asoc,
net/sctp/sm_make_chunk.c +55 -44

158 lines not on this page · raw message

net/sctp/sm_statefuns.c +2 -16
index 62623ccc4089..bf12098bbe1c 100644
@@ -3595,9 +3595,7 @@ sctp_disposition_t sctp_sf_do_asconf(struct net *net,
 	struct sctp_chunk	*asconf_ack = NULL;
 	struct sctp_paramhdr	*err_param = NULL;
 	sctp_addiphdr_t		*hdr;
-	union sctp_addr_param	*addr_param;
 	__u32			serial;
-	int			length;
 
 	if (!sctp_vtag_verify(chunk, asoc)) {
 		sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
@@ -3622,17 +3620,8 @@ sctp_disposition_t sctp_sf_do_asconf(struct net *net,
 	hdr = (sctp_addiphdr_t *)chunk->skb->data;
 	serial = ntohl(hdr->serial);
 
-	addr_param = (union sctp_addr_param *)hdr->params;
-	length = ntohs(addr_param->p.length);
-	if (length < sizeof(sctp_paramhdr_t))
-		return sctp_sf_violation_paramlen(net, ep, asoc, type, arg,
-			   (void *)addr_param, commands);
-
 	/* Verify the ASCONF chunk before processing it. */
-	if (!sctp_verify_asconf(asoc,
-			    (sctp_paramhdr_t *)((void *)addr_param + length),
-			    (void *)chunk->chunk_end,
-			    &err_param))
+	if (!sctp_verify_asconf(asoc, chunk, true, &err_param))
 		return sctp_sf_violation_paramlen(net, ep, asoc, type, arg,
 						  (void *)err_param, commands);
 
@@ -3750,10 +3739,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(struct net *net,
 	rcvd_serial = ntohl(addip_hdr->serial);
 
 	/* Verify the ASCONF-ACK chunk before processing it. */
-	if (!sctp_verify_asconf(asoc,
-	    (sctp_paramhdr_t *)addip_hdr->params,
-	    (void *)asconf_ack->chunk_end,
-	    &err_param))
+	if (!sctp_verify_asconf(asoc, asconf_ack, false, &err_param))
 		return sctp_sf_violation_paramlen(net, ep, asoc, type, arg,
 			   (void *)err_param, commands);
 
Signature · 1 line
2.1.3
author
#72 lore raw

PATCH 72/101 drivers/memstick/host/rtsx_pci_ms.c: add cancel_work when remove driver

In reply to Jiri Slaby

From: Micky Ching <[email protected]>

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

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

commit b6226b45c66196e14ef628d3aead2139700db1ad upstream.

Add cancel_work_sync() in rtsx_pci_ms_drv_remove() to cancel pending request work when removing the driver.

Cc Samuel Ortiz <[email protected]> says:
Cc Maxim Levitsky <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
Cc Alex Dubov <[email protected]>
Cc Roger Tseng <[email protected]>
Cc Wei WANG <[email protected]>
---
 drivers/memstick/host/rtsx_pci_ms.c | 1 +
 1 file changed, 1 insertion(+)
drivers/memstick/host/rtsx_pci_ms.c +1 -0
index 25f8f93decb6..8d70fcf18901 100644
@@ -591,6 +591,7 @@ static int rtsx_pci_ms_drv_remove(struct platform_device *pdev)
 	pcr->slots[RTSX_MS_CARD].card_event = NULL;
 	msh = host->msh;
 	host->eject = true;
+	cancel_work_sync(&host->handle_req);
 
 	mutex_lock(&host->host_mutex);
 	if (host->req) {
Signature · 1 line
2.1.3
author
#73 lore raw

PATCH 73/101 usbvision-video: two use after frees

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 470a9147899500eb4898f77816520c4b4aa1a698 upstream.

The lock has been freed in usbvision_release() so there is no need to call mutex_unlock() here.

---
 drivers/media/usb/usbvision/usbvision-video.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/media/usb/usbvision/usbvision-video.c +2 -0
index 5c9e3123ad2e..661f7f2a9e8b 100644
@@ -446,6 +446,7 @@ static int usbvision_v4l2_close(struct file *file)
 	if (usbvision->remove_pending) {
 		printk(KERN_INFO "%s: Final disconnect\n", __func__);
 		usbvision_release(usbvision);
+		return 0;
 	}
 	mutex_unlock(&usbvision->v4l2_lock);
 
@@ -1221,6 +1222,7 @@ static int usbvision_radio_close(struct file *file)
 	if (usbvision->remove_pending) {
 		printk(KERN_INFO "%s: Final disconnect\n", __func__);
 		usbvision_release(usbvision);
+		return err_code;
 	}
 
 	mutex_unlock(&usbvision->v4l2_lock);
Signature · 1 line
2.1.3
author
#74 lore raw

PATCH 74/101 Input: altera_ps2 - write to correct register when disabling interrupts

In reply to Jiri Slaby

From: Tobias Klauser <[email protected]>

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

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

commit d0269b8475020718afd7f559064698f5500fa879 upstream.

In altera_ps2_close, the data register (offset 0) is written instead of the control register (offset 4), leading to the RX interrupt not being disabled. Fix this by calling writel() with the offset for the proper register.

---
 drivers/input/serio/altera_ps2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/input/serio/altera_ps2.c +1 -1
index 4777a73cd390..b6d370ba408f 100644
@@ -75,7 +75,7 @@ static void altera_ps2_close(struct serio *io)
 {
 	struct ps2if *ps2if = io->port_data;
 
-	writel(0, ps2if->base); /* disable rx irq */
+	writel(0, ps2if->base + 4); /* disable rx irq */
 }
 
 /*
Signature · 1 line
2.1.3
author
#75 lore raw

PATCH 75/101 Input: wm97xx - adapt parameters to tosa touchscreen.

In reply to Jiri Slaby

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

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

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

commit 859abd1d59e2db07d2e4db27074fc33568353d11 upstream.

Sharp SL-6000 (tosa) touchscreen needs wider limits to properly map all points on the screen. Expand ranges in abs_x and abs_y arrays according to the touchscreen area.

---
 drivers/input/touchscreen/wm97xx-core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/input/touchscreen/wm97xx-core.c +2 -2
index 7e45c9f6e6b7..b08c16bd816e 100644
@@ -70,11 +70,11 @@
  * Documentation/input/input-programming.txt for more details.
  */
 
-static int abs_x[3] = {350, 3900, 5};
+static int abs_x[3] = {150, 4000, 5};
 module_param_array(abs_x, int, NULL, 0);
 MODULE_PARM_DESC(abs_x, "Touchscreen absolute X min, max, fuzz");
 
-static int abs_y[3] = {320, 3750, 40};
+static int abs_y[3] = {200, 4000, 40};
 module_param_array(abs_y, int, NULL, 0);
 MODULE_PARM_DESC(abs_y, "Touchscreen absolute Y min, max, fuzz");
 
Signature · 1 line
2.1.3
author
#76 lore raw

PATCH 76/101 pcmcia: at91_cf: fix deferred probe from __init

In reply to Jiri Slaby

From: Johan Hovold <[email protected]>

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

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

commit 16a7c7cfd21cca8a260b63467e4f5c6a6d548b09 upstream.

Move probe out of __init section and don't use platform_driver_probe which cannot be used with deferred probing.

Since commit e9354576 ("gpiolib: Defer failed gpio requests by default") this driver might return -EPROBE_DEFER if a gpio_request fails.

---
 drivers/pcmcia/at91_cf.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/pcmcia/at91_cf.c +5 -6
index b8f5acf02261..de24232c5191 100644
@@ -245,7 +245,7 @@ static int at91_cf_dt_init(struct platform_device *pdev)
 }
 #endif
 
-static int __init at91_cf_probe(struct platform_device *pdev)
+static int at91_cf_probe(struct platform_device *pdev)
 {
 	struct at91_cf_socket	*cf;
 	struct at91_cf_data	*board = pdev->dev.platform_data;
@@ -354,7 +354,7 @@ fail0a:
 	return status;
 }
 
-static int __exit at91_cf_remove(struct platform_device *pdev)
+static int at91_cf_remove(struct platform_device *pdev)
 {
 	struct at91_cf_socket	*cf = platform_get_drvdata(pdev);
 
@@ -404,14 +404,13 @@ static struct platform_driver at91_cf_driver = {
 		.owner		= THIS_MODULE,
 		.of_match_table = of_match_ptr(at91_cf_dt_ids),
 	},
-	.remove		= __exit_p(at91_cf_remove),
+	.probe		= at91_cf_probe,
+	.remove		= at91_cf_remove,
 	.suspend	= at91_cf_suspend,
 	.resume		= at91_cf_resume,
 };
 
-/*--------------------------------------------------------------------------*/
-
-module_platform_driver_probe(at91_cf_driver, at91_cf_probe);
+module_platform_driver(at91_cf_driver);
 
 MODULE_DESCRIPTION("AT91 Compact Flash Driver");
 MODULE_AUTHOR("David Brownell");
Signature · 1 line
2.1.3
author
#77 lore raw

PATCH 77/101 pcmcia: sa1100: H3100 and H3600 share a driver

In reply to Jiri Slaby

From: Arnd Bergmann <[email protected]>

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

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

commit d8477126f46b036b26d95b127689a3774a080e34 upstream.

When building a iPAQ H3100-only kernel with PCMCIA enabled, we get this build error:

ERROR: "pcmcia_h3600_init" [drivers/pcmcia/sa1100_cs.ko] undefined!

The defconfig normally works fine because it enables both H3100 and H3600 support. This patch fixes the Makefile to build the driver if at least one of the two machines are selected.

---
 drivers/pcmcia/Makefile | 1 +
 1 file changed, 1 insertion(+)
drivers/pcmcia/Makefile +1 -0
index 7745b512a87c..fd55a6951402 100644
@@ -49,6 +49,7 @@ sa1100_cs-y					+= sa1100_generic.o
 sa1100_cs-$(CONFIG_SA1100_ASSABET)		+= sa1100_assabet.o
 sa1100_cs-$(CONFIG_SA1100_CERF)			+= sa1100_cerf.o
 sa1100_cs-$(CONFIG_SA1100_COLLIE)		+= pxa2xx_sharpsl.o
+sa1100_cs-$(CONFIG_SA1100_H3100)		+= sa1100_h3600.o
 sa1100_cs-$(CONFIG_SA1100_H3600)		+= sa1100_h3600.o
 sa1100_cs-$(CONFIG_SA1100_NANOENGINE)		+= sa1100_nanoengine.o
 sa1100_cs-$(CONFIG_SA1100_SHANNON)		+= sa1100_shannon.o
Signature · 1 line
2.1.3
author
#78 lore raw

PATCH 78/101 pcmcia: pxa2xx: fix logic for lubbock

In reply to Jiri Slaby

From: Arnd Bergmann <[email protected]>

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

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

commit f1674f213ec81c55c909bb6805d3502b5883754d upstream.

The lubbock platform uses the sa1111 companion chip with a pxa250 CPU, which means it requires both the PCMCIA_SA1111 and the PCMCIA_PXA2XX code to be built into the kernel. Unfortunately, the Makefile and Kconfig don't agree on how this is accomplished, leading to a situation where you get this link error when building a lubbock kernel with PCMCIA_SA1111 enabled but PCMCIA_PXA2XX disabled:

ERROR: "pxa2xx_configure_sockets" [drivers/pcmcia/sa1111_cs.ko] undefined!
ERROR: "pxa2xx_drv_pcmcia_ops" [drivers/pcmcia/sa1111_cs.ko] undefined!
ERROR: "pxa2xx_drv_pcmcia_add_one" [drivers/pcmcia/sa1111_cs.ko] undefined!

This patch changes the Kconfig code to disallow that particular configuration.

---
 drivers/pcmcia/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pcmcia/Kconfig +1 -1
index 0c657d6af03d..51cf8083b299 100644
@@ -202,6 +202,7 @@ config PCMCIA_SA1111
 	depends on ARM && SA1111 && PCMCIA
 	select PCMCIA_SOC_COMMON
 	select PCMCIA_SA11XX_BASE if ARCH_SA1100
+	select PCMCIA_PXA2XX if ARCH_LUBBOCK && SA1111
 	help
 	  Say Y  here to include support for SA1111-based PCMCIA or CF
 	  sockets, found on the Jornada 720, Graphicsmaster and other
@@ -217,7 +218,6 @@ config PCMCIA_PXA2XX
 		    || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \
 		    || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \
 		    || MACH_COLIBRI320 || MACH_H4700)
-	select PCMCIA_SA1111 if ARCH_LUBBOCK && SA1111
 	select PCMCIA_SOC_COMMON
 	help
 	  Say Y here to include support for the PXA2xx PCMCIA controller
Signature · 1 line
2.1.3
author
#79 lore raw

PATCH 79/101 pcmcia: journada720: use sa1100 pin interfaces correctly

In reply to Jiri Slaby

From: Arnd Bergmann <[email protected]>

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

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

commit 58409f9d21a9d372e35857b5b8aaf334997b127b upstream.

commit dabd14684bc2 "PCMCIA: sa1111: remove duplicated initializers" incorrectly moved some code into the pcmcia_jornada720_init, causing a few build errors, and for unknown reasons, the driver lacks an inclusion of <linux/io.h>, so we get the build errors, and more:

sa1111_jornada720.c: In function 'pcmcia_jornada720_init':
sa1111_jornada720.c:101:3: error: implicit declaration of function 'IOMEM' [-Werror=implicit-function-declaration]
GRER |= 0x00000002;
^
sa1111_jornada720.c:104:3: warning: passing argument 1 of 'sa1111_set_io_dir' from incompatible pointer type [enabled by default]
sa1111_set_io_dir(dev, pin, 0, 0);
^

This patch uses the SA1111_DEV() to convert the dev pointer to the correct type before passing it and adds the missing include.

---
 drivers/pcmcia/sa1111_jornada720.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/pcmcia/sa1111_jornada720.c +6 -4
index 3baa3ef09682..40e040314503 100644
@@ -9,6 +9,7 @@
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/hardware/sa1111.h>
@@ -94,6 +95,7 @@ static struct pcmcia_low_level jornada720_pcmcia_ops = {
 int pcmcia_jornada720_init(struct device *dev)
 {
 	int ret = -ENODEV;
+	struct sa1111_dev *sadev = SA1111_DEV(dev);
 
 	if (machine_is_jornada720()) {
 		unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
@@ -101,12 +103,12 @@ int pcmcia_jornada720_init(struct device *dev)
 		GRER |= 0x00000002;
 
 		/* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
-		sa1111_set_io_dir(dev, pin, 0, 0);
-		sa1111_set_io(dev, pin, 0);
-		sa1111_set_sleep_io(dev, pin, 0);
+		sa1111_set_io_dir(sadev, pin, 0, 0);
+		sa1111_set_io(sadev, pin, 0);
+		sa1111_set_sleep_io(sadev, pin, 0);
 
 		sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops);
-		ret = sa1111_pcmcia_add(dev, &jornada720_pcmcia_ops,
+		ret = sa1111_pcmcia_add(sadev, &jornada720_pcmcia_ops,
 				sa11xx_drv_pcmcia_add_one);
 	}
 
Signature · 1 line
2.1.3
author
#80 lore raw

PATCH 80/101 parport: Add support for the WCH353 1S/1P multi-IO card

In reply to Jiri Slaby

From: Ezequiel Garcia <[email protected]>

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

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

commit feb5814254094c306429fe6d7b9c534fa0250f4c upstream.

This Multi-IO card has one serial 16550-like and one parallel port connector. Here's the lspci output, after this commit is applied:

03:07.0 Serial controller: Device 4348:5053 (rev 10) (prog-if 02 [16550])
Subsystem: Device 4348:5053
Control: I/O+ Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Interrupt: pin A routed to IRQ 21
Region 0: I/O ports at cf00 [size=8]
Region 1: I/O ports at ce00 [size=8]
Kernel driver in use: parport_serial
Kernel modules: 8250_pci, parport_serial

This commit adds an entry with the device ID to the blacklist declared in 8250_pci to prevent the driver from taking ownership. Also, and as was done for the 2S/1P variant, add a quirk to skip autodetection and set the correct type to 16550A clone.

Proper entries are added to parport_serial, to support the device parallel and serial ports.

---
 drivers/parport/parport_serial.c   |  9 +++++++++
 drivers/tty/serial/8250/8250_pci.c | 10 ++++++++++
 2 files changed, 19 insertions(+)
drivers/parport/parport_serial.c +9 -0
index 1b8bdb7e9bf4..72b73657576b 100644
@@ -62,6 +62,7 @@ enum parport_pc_pci_cards {
 	timedia_9079a,
 	timedia_9079b,
 	timedia_9079c,
+	wch_ch353_1s1p,
 	wch_ch353_2s1p,
 	sunix_2s1p,
 };
@@ -148,6 +149,7 @@ static struct parport_pc_pci cards[] = {
 	/* timedia_9079a */             { 1, { { 2, 3 }, } },
 	/* timedia_9079b */             { 1, { { 2, 3 }, } },
 	/* timedia_9079c */             { 1, { { 2, 3 }, } },
+	/* wch_ch353_1s1p*/             { 1, { { 1, -1}, } },
 	/* wch_ch353_2s1p*/             { 1, { { 2, -1}, } },
 	/* sunix_2s1p */                { 1, { { 3, -1 }, } },
 };
@@ -253,6 +255,7 @@ static struct pci_device_id parport_serial_pci_tbl[] = {
 	{ 0x1409, 0x7168, 0x1409, 0xd079, 0, 0, timedia_9079c },
 
 	/* WCH CARDS */
+	{ 0x4348, 0x5053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, wch_ch353_1s1p},
 	{ 0x4348, 0x7053, 0x4348, 0x3253, 0, 0, wch_ch353_2s1p},
 
 	/*
@@ -479,6 +482,12 @@ static struct pciserial_board pci_parport_serial_boards[] = {
 		.base_baud	= 921600,
 		.uart_offset	= 8,
 	},
+	[wch_ch353_1s1p] = {
+		.flags          = FL_BASE0|FL_BASE_BARS,
+		.num_ports      = 1,
+		.base_baud      = 115200,
+		.uart_offset    = 8,
+	},
 	[wch_ch353_2s1p] = {
 		.flags          = FL_BASE0|FL_BASE_BARS,
 		.num_ports      = 2,
drivers/tty/serial/8250/8250_pci.c +10 -0
index 6d402cf84cf1..ee1f7c52bd52 100644
@@ -1558,6 +1558,7 @@ pci_wch_ch353_setup(struct serial_private *priv,
 #define PCI_DEVICE_ID_WCH_CH352_2S	0x3253
 #define PCI_DEVICE_ID_WCH_CH353_4S	0x3453
 #define PCI_DEVICE_ID_WCH_CH353_2S1PF	0x5046
+#define PCI_DEVICE_ID_WCH_CH353_1S1P	0x5053
 #define PCI_DEVICE_ID_WCH_CH353_2S1P	0x7053
 #define PCI_VENDOR_ID_AGESTAR		0x5372
 #define PCI_DEVICE_ID_AGESTAR_9375	0x6872
@@ -2159,6 +2160,14 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
 		.subdevice	= PCI_ANY_ID,
 		.setup		= pci_omegapci_setup,
 	},
+	/* WCH CH353 1S1P card (16550 clone) */
+	{
+		.vendor         = PCI_VENDOR_ID_WCH,
+		.device         = PCI_DEVICE_ID_WCH_CH353_1S1P,
+		.subvendor      = PCI_ANY_ID,
+		.subdevice      = PCI_ANY_ID,
+		.setup          = pci_wch_ch353_setup,
+	},
 	/* WCH CH353 2S1P card (16550 clone) */
 	{
 		.vendor         = PCI_VENDOR_ID_WCH,
@@ -3228,6 +3237,7 @@ static const struct pci_device_id blacklist[] = {
 
 	/* multi-io cards handled by parport_serial */
 	{ PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */
+	{ PCI_DEVICE(0x4348, 0x5053), }, /* WCH CH353 1S1P */
 };
 
 /*
Signature · 1 line
2.1.3
author
#81 lore raw

PATCH 81/101 vme_tsi148: Fix PCI address mapping assumption

In reply to Jiri Slaby

From: Joe Schultz <[email protected]>

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

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

commit 226572b110ab6083cb8c1d6afb191166b4178179 upstream.

Previously, tsi148_master_set() assumed the address contained in its PCI bus resource represented the actual PCI bus address. This is a fine assumption on some platforms. However, on platforms that don't use a 1:1 (CPU:PCI) mapping this results in the tsi148 driver configuring an invalid master window translation.

This patch updates the vme_tsi148 driver to first convert the address contained in the PCI bus resource into a PCI bus address before using it.

[asierra: account for pcibios_resource_to_bus() prototype change]
---
 drivers/vme/bridges/vme_tsi148.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/vme/bridges/vme_tsi148.c +7 -1
index 7db4e6395e23..6783ad0d1875 100644
@@ -910,11 +910,15 @@ static int tsi148_master_set(struct vme_master_resource *image, int enabled,
 	unsigned long long pci_bound, vme_offset, pci_base;
 	struct vme_bridge *tsi148_bridge;
 	struct tsi148_driver *bridge;
+	struct pci_bus_region region;
+	struct pci_dev *pdev;
 
 	tsi148_bridge = image->parent;
 
 	bridge = tsi148_bridge->driver_priv;
 
+	pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev);
+
 	/* Verify input data */
 	if (vme_base & 0xFFFF) {
 		dev_err(tsi148_bridge->parent, "Invalid VME Window "
@@ -949,7 +953,9 @@ static int tsi148_master_set(struct vme_master_resource *image, int enabled,
 		pci_bound = 0;
 		vme_offset = 0;
 	} else {
-		pci_base = (unsigned long long)image->bus_resource.start;
+		pcibios_resource_to_bus(pdev, &region,
+					&image->bus_resource);
+		pci_base = region.start;
 
 		/*
 		 * Bound address is a valid address for the window, adjust
Signature · 1 line
2.1.3
author
#82 lore raw

PATCH 82/101 vme_tsi148: Fix typo in tsi148_slave_get()

In reply to Jiri Slaby

From: Joe Schultz <[email protected]>

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

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

commit 098ced8fefe4a4e4240fa47b1ed9b00d65b6cd21 upstream.

This patch corrects a typo where "vme_base" was used instead of "*vme_base". The typo resulted in an incorrect value being returned to userspace (via vme_user).

It also removes the following compile warning on some platforms:

warning: cast from pointer to integer of different size

[asierra: commit title/log rewording]
---
 drivers/vme/bridges/vme_tsi148.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/vme/bridges/vme_tsi148.c +1 -1
index 6783ad0d1875..b92eb181dcda 100644
@@ -741,7 +741,7 @@ static int tsi148_slave_get(struct vme_slave_resource *image, int *enabled,
 	reg_join(vme_bound_high, vme_bound_low, &vme_bound);
 	reg_join(pci_offset_high, pci_offset_low, &pci_offset);
 
-	*pci_base = (dma_addr_t)vme_base + pci_offset;
+	*pci_base = (dma_addr_t)(*vme_base + pci_offset);
 
 	*enabled = 0;
 	*aspace = 0;
Signature · 1 line
2.1.3
author
#83 lore raw

PATCH 83/101 VME: Stop using memcpy_[to|from]io() due to unwanted behaviour

In reply to Jiri Slaby

From: Martyn Welch <[email protected]>

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

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

commit a2a720e15f59be60c7ae1c58b5b4ac1003dd5078 upstream.

The ca91cx42 and tsi148 VME bridges use the width of reads and writes on the PCI bus in part to control the width of the cycles on the VME bus. It is important that we can control the width of cycles on the VME bus as some VME hardware requires cycles of a specific width. The memcpy_toio() and memcpy_fromio() functions do not provide sufficient control, so instead loop using ioread functions.

---
 drivers/vme/bridges/vme_ca91cx42.c | 29 ++++++++++++++---------------
 drivers/vme/bridges/vme_tsi148.c   | 18 +++++++++---------
 2 files changed, 23 insertions(+), 24 deletions(-)
drivers/vme/bridges/vme_ca91cx42.c +14 -15
index 0b2fefbfcd10..1abbf80ffb19 100644
@@ -869,14 +869,13 @@ static ssize_t ca91cx42_master_read(struct vme_master_resource *image,
 
 	spin_lock(&image->lock);
 
-	/* The following code handles VME address alignment problem
-	 * in order to assure the maximal data width cycle.
-	 * We cannot use memcpy_xxx directly here because it
-	 * may cut data transfer in 8-bits cycles, thus making
-	 * D16 cycle impossible.
-	 * From the other hand, the bridge itself assures that
-	 * maximal configured data cycle is used and splits it
-	 * automatically for non-aligned addresses.
+	/* The following code handles VME address alignment. We cannot use
+	 * memcpy_xxx here because it may cut data transfers in to 8-bit
+	 * cycles when D16 or D32 cycles are required on the VME bus.
+	 * On the other hand, the bridge itself assures that the maximum data
+	 * cycle configured for the transfer is used and splits it
+	 * automatically for non-aligned addresses, so we don't want the
+	 * overhead of needlessly forcing small transfers for the entire cycle.
 	 */
 	if ((uintptr_t)addr & 0x1) {
 		*(u8 *)buf = ioread8(addr);
@@ -896,9 +895,9 @@ static ssize_t ca91cx42_master_read(struct vme_master_resource *image,
 	}
 
 	count32 = (count - done) & ~0x3;
-	if (count32 > 0) {
-		memcpy_fromio(buf + done, addr + done, (unsigned int)count);
-		done += count32;
+	while (done < count32) {
+		*(u32 *)(buf + done) = ioread32(addr + done);
+		done += 4;
 	}
 
 	if ((count - done) & 0x2) {
@@ -930,7 +929,7 @@ static ssize_t ca91cx42_master_write(struct vme_master_resource *image,
 	spin_lock(&image->lock);
 
 	/* Here we apply for the same strategy we do in master_read
-	 * function in order to assure D16 cycle when required.
+	 * function in order to assure the correct cycles.
 	 */
 	if ((uintptr_t)addr & 0x1) {
 		iowrite8(*(u8 *)buf, addr);
@@ -950,9 +949,9 @@ static ssize_t ca91cx42_master_write(struct vme_master_resource *image,
 	}
 
 	count32 = (count - done) & ~0x3;
-	if (count32 > 0) {
-		memcpy_toio(addr + done, buf + done, count32);
-		done += count32;
+	while (done < count32) {
+		iowrite32(*(u32 *)(buf + done), addr + done);
+		done += 4;
 	}
 
 	if ((count - done) & 0x2) {
drivers/vme/bridges/vme_tsi148.c +9 -9
index b92eb181dcda..ef9028f87da3 100644
@@ -1282,8 +1282,8 @@ static ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf,
 	spin_lock(&image->lock);
 
 	/* The following code handles VME address alignment. We cannot use
-	 * memcpy_xxx directly here because it may cut small data transfers in
-	 * to 8-bit cycles, thus making D16 cycle impossible.
+	 * memcpy_xxx here because it may cut data transfers in to 8-bit
+	 * cycles when D16 or D32 cycles are required on the VME bus.
 	 * On the other hand, the bridge itself assures that the maximum data
 	 * cycle configured for the transfer is used and splits it
 	 * automatically for non-aligned addresses, so we don't want the
@@ -1307,9 +1307,9 @@ static ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf,
 	}
 
 	count32 = (count - done) & ~0x3;
-	if (count32 > 0) {
-		memcpy_fromio(buf + done, addr + done, count32);
-		done += count32;
+	while (done < count32) {
+		*(u32 *)(buf + done) = ioread32(addr + done);
+		done += 4;
 	}
 
 	if ((count - done) & 0x2) {
@@ -1369,7 +1369,7 @@ static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
 	spin_lock(&image->lock);
 
 	/* Here we apply for the same strategy we do in master_read
-	 * function in order to assure D16 cycle when required.
+	 * function in order to assure the correct cycles.
 	 */
 	if ((uintptr_t)addr & 0x1) {
 		iowrite8(*(u8 *)buf, addr);
@@ -1389,9 +1389,9 @@ static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
 	}
 
 	count32 = (count - done) & ~0x3;
-	if (count32 > 0) {
-		memcpy_toio(addr + done, buf + done, count32);
-		done += count32;
+	while (done < count32) {
+		iowrite32(*(u32 *)(buf + done), addr + done);
+		done += 4;
 	}
 
 	if ((count - done) & 0x2) {
Signature · 1 line
2.1.3
author
#84 lore raw

PATCH 84/101 drivers/vlynq/vlynq.c: fix another resource size off by 1 error

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 59d42cd43c7335a3a8081fd6ee54ea41b0c239be upstream.

We fixed the call to request_mem_region() in commit 3354f73b24c6 ("drivers/vlynq/vlynq.c: fix resource size off by 1 error"). But we need to fix the call the release_mem_region() as well.

---
 drivers/vlynq/vlynq.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/vlynq/vlynq.c +2 -1
index 7b07135ab26e..c0227f9418eb 100644
@@ -762,7 +762,8 @@ static int vlynq_remove(struct platform_device *pdev)
 
 	device_unregister(&dev->dev);
 	iounmap(dev->local);
-	release_mem_region(dev->regs_start, dev->regs_end - dev->regs_start);
+	release_mem_region(dev->regs_start,
+			   dev->regs_end - dev->regs_start + 1);
 
 	kfree(dev);
 
Signature · 1 line
2.1.3
author
#85 lore raw

PATCH 85/101 hfsplus: fix remount issue

In reply to Jiri Slaby

From: Vyacheslav Dubeyko <[email protected]>

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

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

commit bd2c00353286d63542a8a0896a8c747f7c880edd upstream.

Current implementation of HFS+ driver has small issue with remount option. Namely, for example, you are unable to remount from RO mode into RW mode by means of command "mount -o remount,rw /dev/loop0 /mnt/hfsplus". Trying to execute sequence of commands results in an error message:

mount /dev/loop0 /mnt/hfsplus
mount -o remount,ro /dev/loop0 /mnt/hfsplus
mount -o remount,rw /dev/loop0 /mnt/hfsplus

mount: you must specify the filesystem type

mount -t hfsplus -o remount,rw /dev/loop0 /mnt/hfsplus

mount: /mnt/hfsplus not mounted or bad option

The reason of such issue is failure of mount syscall:

mount("/dev/loop0", "/mnt/hfsplus", 0x2282a60, MS_MGC_VAL|MS_REMOUNT, NULL) = -1 EINVAL (Invalid argument)

Namely, hfsplus_parse_options_remount() method receives empty "input" argument and return false in such case. As a result, hfsplus_remount() returns -EINVAL error code.

This patch fixes the issue by means of return true for the case of empty "input" argument in hfsplus_parse_options_remount() method.

---
 fs/hfsplus/options.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/hfsplus/options.c +1 -1
index 968eab5bc1f5..68537e8b7a09 100644
@@ -75,7 +75,7 @@ int hfsplus_parse_options_remount(char *input, int *force)
 	int token;
 
 	if (!input)
-		return 0;
+		return 1;
 
 	while ((p = strsep(&input, ",")) != NULL) {
 		if (!*p)
Signature · 1 line
2.1.3
author
#86 lore raw

PATCH 86/101 fs/hfsplus/extents.c: fix concurrent acess of alloc_blocks

In reply to Jiri Slaby

From: Sougata Santra <[email protected]>

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

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

commit d7bdb996aef67ea24c62707ca4e29b07025e9683 upstream.

Concurrent access to alloc_blocks in hfsplus_inode_info() is protected by extents_lock mutex. This patch fixes two instances where alloc_blocks modification was not protected with this lock.

This fixes possible allocation bitmap corruption in race conditions while extending and truncating files.

[[email protected]: take extents_lock before taking a copy of ->alloc_blocks]
[[email protected]: remove now-unused label `out']
Cc Vyacheslav Dubeyko <[email protected]>
Cc Alexey Khoroshilov <[email protected]>
---
 fs/hfsplus/extents.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)
fs/hfsplus/extents.c +9 -5
index fbb212fbb1ef..f0f601c83ad6 100644
@@ -498,11 +498,13 @@ int hfsplus_file_extend(struct inode *inode)
 			goto insert_extent;
 	}
 out:
-	mutex_unlock(&hip->extents_lock);
 	if (!res) {
 		hip->alloc_blocks += len;
+		mutex_unlock(&hip->extents_lock);
 		hfsplus_mark_inode_dirty(inode, HFSPLUS_I_ALLOC_DIRTY);
+		return 0;
 	}
+	mutex_unlock(&hip->extents_lock);
 	return res;
 
 insert_extent:
@@ -556,11 +558,13 @@ void hfsplus_file_truncate(struct inode *inode)
 
 	blk_cnt = (inode->i_size + HFSPLUS_SB(sb)->alloc_blksz - 1) >>
 			HFSPLUS_SB(sb)->alloc_blksz_shift;
+
+	mutex_lock(&hip->extents_lock);
+
 	alloc_cnt = hip->alloc_blocks;
 	if (blk_cnt == alloc_cnt)
-		goto out;
+		goto out_unlock;
 
-	mutex_lock(&hip->extents_lock);
 	res = hfs_find_init(HFSPLUS_SB(sb)->ext_tree, &fd);
 	if (res) {
 		mutex_unlock(&hip->extents_lock);
@@ -592,10 +596,10 @@ void hfsplus_file_truncate(struct inode *inode)
 		hfs_brec_remove(&fd);
 	}
 	hfs_find_exit(&fd);
-	mutex_unlock(&hip->extents_lock);
 
 	hip->alloc_blocks = blk_cnt;
-out:
+out_unlock:
+	mutex_unlock(&hip->extents_lock);
 	hip->phys_size = inode->i_size;
 	hip->fs_blocks = (inode->i_size + sb->s_blocksize - 1) >>
 		sb->s_blocksize_bits;
Signature · 1 line
2.1.3
author
#87 lore raw

PATCH 87/101 hfsplus: emit proper file type from readdir

In reply to Jiri Slaby

From: Sergei Antonov <[email protected]>

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

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

commit 97a62eaefdc196969e9d3857f65fc8a90ee1fe3c upstream.

hfsplus_readdir() incorrectly returned DT_REG for symbolic links and special files. Return DT_REG, DT_LNK, DT_FIFO, DT_CHR, DT_BLK, DT_SOCK, or DT_UNKNOWN according to mode field in catalog record. Programs relying on information from readdir will now work correctly with HFS+.

Cc Anton Altaparmakov <[email protected]>
Cc Al Viro <[email protected]>
Cc Christoph Hellwig <[email protected]>
Cc Vyacheslav Dubeyko <[email protected]>
Cc Hin-Tak Leung <[email protected]>
---
 fs/hfsplus/dir.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)
fs/hfsplus/dir.c +19 -1
index 4a4fea002673..64112185f47c 100644
@@ -212,13 +212,31 @@ static int hfsplus_readdir(struct file *file, struct dir_context *ctx)
 				    be32_to_cpu(entry.folder.id), DT_DIR))
 				break;
 		} else if (type == HFSPLUS_FILE) {
+			u16 mode;
+			unsigned type = DT_UNKNOWN;
+
 			if (fd.entrylength < sizeof(struct hfsplus_cat_file)) {
 				pr_err("small file entry\n");
 				err = -EIO;
 				goto out;
 			}
+
+			mode = be16_to_cpu(entry.file.permissions.mode);
+			if (S_ISREG(mode))
+				type = DT_REG;
+			else if (S_ISLNK(mode))
+				type = DT_LNK;
+			else if (S_ISFIFO(mode))
+				type = DT_FIFO;
+			else if (S_ISCHR(mode))
+				type = DT_CHR;
+			else if (S_ISBLK(mode))
+				type = DT_BLK;
+			else if (S_ISSOCK(mode))
+				type = DT_SOCK;
+
 			if (!dir_emit(ctx, strbuf, len,
-				    be32_to_cpu(entry.file.id), DT_REG))
+				      be32_to_cpu(entry.file.id), type))
 				break;
 		} else {
 			pr_err("bad catalog entry type\n");
Signature · 1 line
2.1.3
author
#88 lore raw

PATCH 88/101 pvpanic: Set high notifier priority

In reply to Jiri Slaby

From: Takashi Iwai <[email protected]>

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

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

commit 7939831eacd81fccbd7a956b30c7bb3abb9079db upstream.

We've observed the missing pvpanic call at panic, and it turned out that this was blocked by the broken notifier of drm_fb_helper, where scheduling may be called during switching to the fb console. It's fairly difficult to fix the drm_fb problem and a quick fix isn't foreseen, a simpler solution for the missing pvpanic call would be just to call this earlier.

In order to assure that, this patch sets a higher priority to pvpanic notifier_block. Once when the issue of drm_fb is resolved, we can remove this priority again.

---
 drivers/platform/x86/pvpanic.c | 1 +
 1 file changed, 1 insertion(+)
drivers/platform/x86/pvpanic.c +1 -0
index 47ae0c47d4b5..469e182c5461 100644
@@ -71,6 +71,7 @@ pvpanic_panic_notify(struct notifier_block *nb, unsigned long code,
 
 static struct notifier_block pvpanic_panic_nb = {
 	.notifier_call = pvpanic_panic_notify,
+	.priority = 1, /* let this called before broken drm_fb_helper */
 };
 
 
Signature · 1 line
2.1.3
author
#89 lore raw

PATCH 89/101 sparc64: Fix constraints on swab helpers.

In reply to Jiri Slaby

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

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

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

[ Upstream commit 5a2b59d3993e8ca4f7788a48a23e5cb303f26954 ]

We are reading the memory location, so we have to have a memory constraint in there purely for the sake of showing the data flow to the compiler.

---
 arch/sparc/include/uapi/asm/swab.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
arch/sparc/include/uapi/asm/swab.h +6 -6
index a34ad079487e..4c7c12d69bea 100644
@@ -9,9 +9,9 @@ static inline __u16 __arch_swab16p(const __u16 *addr)
 {
 	__u16 ret;
 
-	__asm__ __volatile__ ("lduha [%1] %2, %0"
+	__asm__ __volatile__ ("lduha [%2] %3, %0"
 			      : "=r" (ret)
-			      : "r" (addr), "i" (ASI_PL));
+			      : "m" (*addr), "r" (addr), "i" (ASI_PL));
 	return ret;
 }
 #define __arch_swab16p __arch_swab16p
@@ -20,9 +20,9 @@ static inline __u32 __arch_swab32p(const __u32 *addr)
 {
 	__u32 ret;
 
-	__asm__ __volatile__ ("lduwa [%1] %2, %0"
+	__asm__ __volatile__ ("lduwa [%2] %3, %0"
 			      : "=r" (ret)
-			      : "r" (addr), "i" (ASI_PL));
+			      : "m" (*addr), "r" (addr), "i" (ASI_PL));
 	return ret;
 }
 #define __arch_swab32p __arch_swab32p
@@ -31,9 +31,9 @@ static inline __u64 __arch_swab64p(const __u64 *addr)
 {
 	__u64 ret;
 
-	__asm__ __volatile__ ("ldxa [%1] %2, %0"
+	__asm__ __volatile__ ("ldxa [%2] %3, %0"
 			      : "=r" (ret)
-			      : "r" (addr), "i" (ASI_PL));
+			      : "m" (*addr), "r" (addr), "i" (ASI_PL));
 	return ret;
 }
 #define __arch_swab64p __arch_swab64p
Signature · 1 line
2.1.3
author
#90 lore raw

PATCH 90/101 inetdevice: fixed signed integer overflow

In reply to Jiri Slaby

From: Vincent BENAYOUN <[email protected]>

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

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

[ Upstream commit 84bc88688e3f6ef843aa8803dbcd90168bb89faf ]

There could be a signed overflow in the following code.

The expression, (32-logmask) is comprised between 0 and 31 included. It may be equal to 31.
In such a case the left shift will produce a signed integer overflow. According to the C99 Standard, this is an undefined behavior. A simple fix is to replace the signed int 1 with the unsigned int 1U.

---
 include/linux/inetdevice.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/inetdevice.h +1 -1
index 79640e015a86..f738f922542d 100644
@@ -234,7 +234,7 @@ static inline void in_dev_put(struct in_device *idev)
 static __inline__ __be32 inet_make_mask(int logmask)
 {
 	if (logmask)
-		return htonl(~((1<<(32-logmask))-1));
+		return htonl(~((1U<<(32-logmask))-1));
 	return 0;
 }
 
Signature · 1 line
2.1.3
author
#91 lore raw

PATCH 91/101 ipv4: Fix incorrect error code when adding an unreachable route

In reply to Jiri Slaby

From: Panu Matilainen <[email protected]>

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

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

[ Upstream commit 49dd18ba4615eaa72f15c9087dea1c2ab4744cf5 ]

Trying to add an unreachable route incorrectly returns -ESRCH if if custom FIB rules are present:

[root@localhost ~]# ip route add 74.125.31.199 dev eth0 via 1.2.3.4 RTNETLINK answers: Network is unreachable [root@localhost ~]# ip rule add to 55.66.77.88 table 200 [root@localhost ~]# ip route add 74.125.31.199 dev eth0 via 1.2.3.4 RTNETLINK answers: No such process
[root@localhost ~]#

Commit 83886b6b636173b206f475929e58fac75c6f2446 ("[NET]: Change "not found" return value for rule lookup") changed fib_rules_lookup()
to use -ESRCH as a "not found" code internally, but for user space it should be translated into -ENETUNREACH. Handle the translation centrally in ipv4-specific fib_lookup(), leaving the DECnet case alone.

On a related note, commit b7a71b51ee37d919e4098cd961d59a883fd272d8 ("ipv4: removed redundant conditional") removed a similar translation from ip_route_input_slow() prematurely AIUI.

Fixes b7a71b51ee37 ("ipv4: removed redundant conditional")
---
 net/ipv4/fib_rules.c | 4 ++++
 1 file changed, 4 insertions(+)
net/ipv4/fib_rules.c +4 -0
index f2e15738534d..8f7bd56955b0 100644
@@ -62,6 +62,10 @@ int __fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res)
 	else
 		res->tclassid = 0;
 #endif
+
+	if (err == -ESRCH)
+		err = -ENETUNREACH;
+
 	return err;
 }
 EXPORT_SYMBOL_GPL(__fib_lookup);
Signature · 1 line
2.1.3
author
#92 lore raw

PATCH 92/101 ieee802154: fix error handling in ieee802154fake_probe()

In reply to Jiri Slaby

From: Alexey Khoroshilov <[email protected]>

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

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

[ Upstream commit 8c2dd54485ccee7fc4086611e188478584758c8d ]

In case of any failure ieee802154fake_probe() just calls unregister_netdev(). But it does not look safe to unregister netdevice before it was registered.

The patch implements straightforward resource deallocation in case of failure in ieee802154fake_probe().

Found by Linux Driver Verification project (linuxtesting.org).

---
 drivers/net/ieee802154/fakehard.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/net/ieee802154/fakehard.c +8 -5
index bf0d55e2dd63..6adbef89c4b0 100644
@@ -376,17 +376,20 @@ static int ieee802154fake_probe(struct platform_device *pdev)
 
 	err = wpan_phy_register(phy);
 	if (err)
-		goto out;
+		goto err_phy_reg;
 
 	err = register_netdev(dev);
-	if (err < 0)
-		goto out;
+	if (err)
+		goto err_netdev_reg;
 
 	dev_info(&pdev->dev, "Added ieee802154 HardMAC hardware\n");
 	return 0;
 
-out:
-	unregister_netdev(dev);
+err_netdev_reg:
+	wpan_phy_unregister(phy);
+err_phy_reg:
+	free_netdev(dev);
+	wpan_phy_free(phy);
 	return err;
 }
 
Signature · 1 line
2.1.3
author
#93 lore raw

PATCH 93/101 qmi_wwan: Add support for HP lt4112 LTE/HSPA+ Gobi 4G Modem

In reply to Jiri Slaby

From: Martin Hauke <[email protected]>

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

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

[ Upstream commit bb2bdeb83fb125c95e47fc7eca2a3e8f868e2a74 ]

Added the USB VID/PID for the HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e)

---
 drivers/net/usb/qmi_wwan.c | 1 +
 1 file changed, 1 insertion(+)
drivers/net/usb/qmi_wwan.c +1 -0
index 2d8bf4232502..7f22d27070fc 100644
@@ -756,6 +756,7 @@ static const struct usb_device_id products[] = {
 	{QMI_FIXED_INTF(0x413c, 0x81a4, 8)},	/* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */
 	{QMI_FIXED_INTF(0x413c, 0x81a8, 8)},	/* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card */
 	{QMI_FIXED_INTF(0x413c, 0x81a9, 8)},	/* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */
+	{QMI_FIXED_INTF(0x03f0, 0x581d, 4)},	/* HP lt4112 LTE/HSPA+ Gobi 4G Module (Huawei me906e) */
 
 	/* 4. Gobi 1000 devices */
 	{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},	/* Acer Gobi Modem Device */
Signature · 1 line
2.1.3
author
#94 lore raw

PATCH 94/101 pptp: fix stack info leak in pptp_getname()

In reply to Jiri Slaby

From: Mathias Krause <[email protected]>

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

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

[ Upstream commit a5f6fc28d6e6cc379c6839f21820e62262419584 ]

pptp_getname() only partially initializes the stack variable sa, particularly only fills the pptp part of the sa_addr union. The code thereby discloses 16 bytes of kernel stack memory via getsockname().

Fix this by memset(0)'ing the union before.

---
 drivers/net/ppp/pptp.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ppp/pptp.c +3 -1
index 1aff970be33e..1dc628ffce2b 100644
@@ -506,7 +506,9 @@ static int pptp_getname(struct socket *sock, struct sockaddr *uaddr,
 	int len = sizeof(struct sockaddr_pppox);
 	struct sockaddr_pppox sp;
 
-	sp.sa_family	  = AF_PPPOX;
+	memset(&sp.sa_addr, 0, sizeof(sp.sa_addr));
+
+	sp.sa_family    = AF_PPPOX;
 	sp.sa_protocol  = PX_PROTO_PPTP;
 	sp.sa_addr.pptp = pppox_sk(sock->sk)->proto.pptp.src_addr;
 
Signature · 1 line
2.1.3
author
#95 lore raw

PATCH 95/101 ipx: fix locking regression in ipx_sendmsg and ipx_recvmsg

In reply to Jiri Slaby

From: Jiri Bohac <[email protected]>

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

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

[ Upstream commit 01462405f0c093b2f8dfddafcadcda6c9e4c5cdf ]

This fixes an old regression introduced by commit
b0d0d915 (ipx: remove the BKL).

When a recvmsg syscall blocks waiting for new data, no data can be sent on the same socket with sendmsg because ipx_recvmsg() sleeps with the socket locked.

This breaks mars-nwe (NetWare emulator):
- the ncpserv process reads the request using recvmsg
- ncpserv forks and spawns nwconn
- ncpserv calls a (blocking) recvmsg and waits for new requests
- nwconn deadlocks in sendmsg on the same socket

Commit b0d0d915 has simply replaced BKL locking with lock_sock/release_sock. Unlike now, BKL got unlocked while sleeping, so a blocking recvmsg did not block a concurrent sendmsg.

Only keep the socket locked while actually working with the socket data and release it prior to calling skb_recv_datagram().

---
 net/ipx/af_ipx.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
net/ipx/af_ipx.c +5 -1
index e096025b477f..6857ae49dc8c 100644
@@ -1778,6 +1778,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
 	struct ipxhdr *ipx = NULL;
 	struct sk_buff *skb;
 	int copied, rc;
+	bool locked = true;
 
 	lock_sock(sk);
 	/* put the autobinding in */
@@ -1804,6 +1805,8 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
 	if (sock_flag(sk, SOCK_ZAPPED))
 		goto out;
 
+	release_sock(sk);
+	locked = false;
 	skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
 				flags & MSG_DONTWAIT, &rc);
 	if (!skb)
@@ -1837,7 +1840,8 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
 out_free:
 	skb_free_datagram(sk, skb);
 out:
-	release_sock(sk);
+	if (locked)
+		release_sock(sk);
 	return rc;
 }
 
Signature · 1 line
2.1.3
author
#96 lore raw

PATCH 96/101 fix O_SYNC|O_APPEND syncing the wrong range on write()

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

It actually goes back to 2004 ([PATCH] Concurrent O_SYNC write support) when sync_page_range() had been introduced; generic_file_write{,v}() correctly synced
pos_after_write - written .. pos_after_write - 1
but generic_file_aio_write() synced
pos_before_write .. pos_before_write + written - 1
instead. Which is not the same thing with O_APPEND, obviously.
A couple of years later correct variant had been killed off when everything switched to use of generic_file_aio_write().

All users of generic_file_aio_write() are affected, and the same bug has been copied into other instances of ->aio_write().

The fix is trivial; the only subtle point is that generic_write_sync() ought to be inlined to avoid calculations useless for the majority of calls.

---
 fs/cifs/file.c     |  4 ++--
 fs/ext4/file.c     |  2 +-
 fs/ntfs/file.c     |  2 +-
 fs/sync.c          | 17 -----------------
 fs/xfs/xfs_file.c  |  2 +-
 include/linux/fs.h |  8 +++++++-
 mm/filemap.c       |  4 ++--
 7 files changed, 14 insertions(+), 25 deletions(-)
fs/cifs/file.c +2 -2
index a2793c93d6ed..f9715276a257 100644
@@ -2590,8 +2590,8 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov,
 	if (rc > 0) {
 		ssize_t err;
 
-		err = generic_write_sync(file, pos, rc);
-		if (err < 0 && rc > 0)
+		err = generic_write_sync(file, iocb->ki_pos - rc, rc);
+		if (err < 0)
 			rc = err;
 	}
 
fs/ext4/file.c +1 -1
index 1b890101397b..7b316011bfef 100644
@@ -152,7 +152,7 @@ ext4_file_dio_write(struct kiocb *iocb, const struct iovec *iov,
 	if (ret > 0) {
 		ssize_t err;
 
-		err = generic_write_sync(file, pos, ret);
+		err = generic_write_sync(file, iocb->ki_pos - ret, ret);
 		if (err < 0 && ret > 0)
 			ret = err;
 	}
fs/ntfs/file.c +1 -1
index a0b2f345da2b..86ddab916b66 100644
@@ -2133,7 +2133,7 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 	ret = ntfs_file_aio_write_nolock(iocb, iov, nr_segs, &iocb->ki_pos);
 	mutex_unlock(&inode->i_mutex);
 	if (ret > 0) {
-		int err = generic_write_sync(file, pos, ret);
+		int err = generic_write_sync(file, iocb->ki_pos - ret, ret);
 		if (err < 0)
 			ret = err;
 	}
fs/sync.c +0 -17
index 905f3f6b3d85..354831ddf54b 100644
@@ -219,23 +219,6 @@ SYSCALL_DEFINE1(fdatasync, unsigned int, fd)
 	return do_fsync(fd, 1);
 }
 
-/**
- * generic_write_sync - perform syncing after a write if file / inode is sync
- * @file:	file to which the write happened
- * @pos:	offset where the write started
- * @count:	length of the write
- *
- * This is just a simple wrapper about our general syncing function.
- */
-int generic_write_sync(struct file *file, loff_t pos, loff_t count)
-{
-	if (!(file->f_flags & O_DSYNC) && !IS_SYNC(file->f_mapping->host))
-		return 0;
-	return vfs_fsync_range(file, pos, pos + count - 1,
-			       (file->f_flags & __O_SYNC) ? 0 : 1);
-}
-EXPORT_SYMBOL(generic_write_sync);
-
 /*
  * sys_sync_file_range() permits finely controlled syncing over a segment of
  * a file in the range offset .. (offset+nbytes-1) inclusive.  If nbytes is
fs/xfs/xfs_file.c +1 -1
index d56b136e68fe..aa606453a0f8 100644
@@ -811,7 +811,7 @@ xfs_file_aio_write(
 		XFS_STATS_ADD(xs_write_bytes, ret);
 
 		/* Handle various SYNC-type writes */
-		err = generic_write_sync(file, pos, ret);
+		err = generic_write_sync(file, iocb->ki_pos - ret, ret);
 		if (err < 0)
 			ret = err;
 	}
include/linux/fs.h +7 -1
index 164d2a91667f..6535d5af027e 100644
@@ -2217,7 +2217,13 @@ extern int filemap_fdatawrite_range(struct address_space *mapping,
 extern int vfs_fsync_range(struct file *file, loff_t start, loff_t end,
 			   int datasync);
 extern int vfs_fsync(struct file *file, int datasync);
-extern int generic_write_sync(struct file *file, loff_t pos, loff_t count);
+static inline int generic_write_sync(struct file *file, loff_t pos, loff_t count)
+{
+	if (!(file->f_flags & O_DSYNC) && !IS_SYNC(file->f_mapping->host))
+		return 0;
+	return vfs_fsync_range(file, pos, pos + count - 1,
+			       (file->f_flags & __O_SYNC) ? 0 : 1);
+}
 extern void emergency_sync(void);
 extern void emergency_remount(void);
 #ifdef CONFIG_BLOCK
mm/filemap.c +2 -2
index b012daefc2d7..e94c70380deb 100644
@@ -2723,8 +2723,8 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 	if (ret > 0) {
 		ssize_t err;
 
-		err = generic_write_sync(file, pos, ret);
-		if (err < 0 && ret > 0)
+		err = generic_write_sync(file, iocb->ki_pos - ret, ret);
+		if (err < 0)
 			ret = err;
 	}
 	return ret;
Signature · 1 line
2.1.3
author
#97 lore raw

PATCH 97/101 nilfs2: add missing blkdev_issue_flush() to nilfs_sync_fs()

In reply to Jiri Slaby

From: Andreas Rohner <[email protected]>

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

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

commit e2c7617ae36b27f97643bfa08aabe27e630c1a76 upstream.

Under normal circumstances nilfs_sync_fs() writes out the super block, which causes a flush of the underlying block device. But this depends on the THE_NILFS_SB_DIRTY flag, which is only set if the pointer to the last segment crosses a segment boundary. So if only a small amount of data is written before the call to nilfs_sync_fs(), no flush of the block device occurs.

In the above case an additional call to blkdev_issue_flush() is needed. To prevent unnecessary overhead, the new flag nilfs->ns_flushed_device is introduced, which is cleared whenever new logs are written and set whenever the block device is flushed. For convenience the function nilfs_flush_device() is added, which contains the above logic.

---
 fs/nilfs2/file.c      |  8 +++-----
 fs/nilfs2/ioctl.c     |  8 +++-----
 fs/nilfs2/segment.c   |  3 +++
 fs/nilfs2/super.c     |  6 ++++++
 fs/nilfs2/the_nilfs.h | 22 ++++++++++++++++++++++
 5 files changed, 37 insertions(+), 10 deletions(-)
fs/nilfs2/file.c +3 -5
index 08fdb77852ac..e31952112eb4 100644
@@ -56,11 +56,9 @@ int nilfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
 	mutex_unlock(&inode->i_mutex);
 
 	nilfs = inode->i_sb->s_fs_info;
-	if (!err && nilfs_test_opt(nilfs, BARRIER)) {
-		err = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
-		if (err != -EIO)
-			err = 0;
-	}
+	if (!err)
+		err = nilfs_flush_device(nilfs);
+
 	return err;
 }
 
fs/nilfs2/ioctl.c +3 -5
index b44bdb291b84..4915e543dc51 100644
@@ -694,11 +694,9 @@ static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
 		return ret;
 
 	nilfs = inode->i_sb->s_fs_info;
-	if (nilfs_test_opt(nilfs, BARRIER)) {
-		ret = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
-		if (ret == -EIO)
-			return ret;
-	}
+	ret = nilfs_flush_device(nilfs);
+	if (ret < 0)
+		return ret;
 
 	if (argp != NULL) {
 		down_read(&nilfs->ns_segctor_sem);
fs/nilfs2/segment.c +3 -0
index a1a191634abc..0b7d2cad0426 100644
@@ -1833,6 +1833,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
 	nilfs_set_next_segment(nilfs, segbuf);
 
 	if (update_sr) {
+		nilfs->ns_flushed_device = 0;
 		nilfs_set_last_segment(nilfs, segbuf->sb_pseg_start,
 				       segbuf->sb_sum.seg_seq, nilfs->ns_cno++);
 
@@ -2216,6 +2217,8 @@ int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode,
 	sci->sc_dsync_end = end;
 
 	err = nilfs_segctor_do_construct(sci, SC_LSEG_DSYNC);
+	if (!err)
+		nilfs->ns_flushed_device = 0;
 
 	nilfs_transaction_unlock(sb);
 	return err;
fs/nilfs2/super.c +6 -0
index 7ac2a122ca1d..0bdc0245e0aa 100644
@@ -310,6 +310,9 @@ int nilfs_commit_super(struct super_block *sb, int flag)
 					    nilfs->ns_sbsize));
 	}
 	clear_nilfs_sb_dirty(nilfs);
+	nilfs->ns_flushed_device = 1;
+	/* make sure store to ns_flushed_device cannot be reordered */
+	smp_wmb();
 	return nilfs_sync_super(sb, flag);
 }
 
@@ -514,6 +517,9 @@ static int nilfs_sync_fs(struct super_block *sb, int wait)
 	}
 	up_write(&nilfs->ns_sem);
 
+	if (!err)
+		err = nilfs_flush_device(nilfs);
+
 	return err;
 }
 
fs/nilfs2/the_nilfs.h +22 -0
index de8cc53b4a5c..005e1dcf8afb 100644
@@ -45,6 +45,7 @@ enum {
 /**
  * struct the_nilfs - struct to supervise multiple nilfs mount points
  * @ns_flags: flags
+ * @ns_flushed_device: flag indicating if all volatile data was flushed
  * @ns_bdev: block device
  * @ns_sem: semaphore for shared states
  * @ns_snapshot_mount_mutex: mutex to protect snapshot mounts
@@ -98,6 +99,7 @@ enum {
  */
 struct the_nilfs {
 	unsigned long		ns_flags;
+	int			ns_flushed_device;
 
 	struct block_device    *ns_bdev;
 	struct rw_semaphore	ns_sem;
@@ -353,4 +355,24 @@ static inline int nilfs_segment_is_active(struct the_nilfs *nilfs, __u64 n)
 	return n == nilfs->ns_segnum || n == nilfs->ns_nextnum;
 }
 
+static inline int nilfs_flush_device(struct the_nilfs *nilfs)
+{
+	int err;
+
+	if (!nilfs_test_opt(nilfs, BARRIER) || nilfs->ns_flushed_device)
+		return 0;
+
+	nilfs->ns_flushed_device = 1;
+	/*
+	 * the store to ns_flushed_device must not be reordered after
+	 * blkdev_issue_flush().
+	 */
+	smp_wmb();
+
+	err = blkdev_issue_flush(nilfs->ns_bdev, GFP_KERNEL, NULL);
+	if (err != -EIO)
+		err = 0;
+	return err;
+}
+
 #endif /* _THE_NILFS_H */
Signature · 1 line
2.1.3
author
#98 lore raw

PATCH 98/101 minix zmap block counts calculation fix

In reply to Jiri Slaby

From: Qi Yong <[email protected]>

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

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

commit 6d6747f85314687f72012ae85cde401db531e130 upstream.

The original minix zmap blocks calculation was correct, in the formula of:

	sbi->s_nzones - sbi->s_firstdatazone + 1

It is

	sp->s_zones - (sp->s_firstdatazone - 1)

in the minix3 source code.

But a later commit 016e8d44bc06 ("fs/minix: Verify bitmap block counts before mounting") has changed it unfortunately as:

sbi->s_nzones - (sbi->s_firstdatazone + 1)

This would show free blocks one block less than the real when the total data blocks are in "full zmap blocks plus one".

This patch corrects that zmap blocks calculation and tidy a printk message while at it.

---
 fs/minix/bitmap.c | 2 +-
 fs/minix/inode.c  | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)
fs/minix/bitmap.c +1 -1
index 4bc50dac8e97..742942a983be 100644
@@ -96,7 +96,7 @@ int minix_new_block(struct inode * inode)
 unsigned long minix_count_free_blocks(struct super_block *sb)
 {
 	struct minix_sb_info *sbi = minix_sb(sb);
-	u32 bits = sbi->s_nzones - (sbi->s_firstdatazone + 1);
+	u32 bits = sbi->s_nzones - sbi->s_firstdatazone + 1;
 
 	return (count_free(sbi->s_zmap, sb->s_blocksize, bits)
 		<< sbi->s_log_zone_size);
fs/minix/inode.c +2 -2
index 0332109162a5..a2e71752f011 100644
@@ -266,12 +266,12 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
 	block = minix_blocks_needed(sbi->s_ninodes, s->s_blocksize);
 	if (sbi->s_imap_blocks < block) {
 		printk("MINIX-fs: file system does not have enough "
-				"imap blocks allocated.  Refusing to mount\n");
+				"imap blocks allocated.  Refusing to mount.\n");
 		goto out_no_bitmap;
 	}
 
 	block = minix_blocks_needed(
-			(sbi->s_nzones - (sbi->s_firstdatazone + 1)),
+			(sbi->s_nzones - sbi->s_firstdatazone + 1),
 			s->s_blocksize);
 	if (sbi->s_zmap_blocks < block) {
 		printk("MINIX-fs: file system does not have enough "
Signature · 1 line
2.1.3
author
#99 lore raw

PATCH 99/101 ext4: atomically set inode->i_flags in ext4_set_inode_flags()

In reply to Jiri Slaby

From: Theodore Ts'o <[email protected]>

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

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

commit 5f16f3225b06242a9ee876f07c1c9b6ed36a22b6 upstream.

Use cmpxchg() to atomically set i_flags instead of clearing out the S_IMMUTABLE, S_APPEND, etc. flags and then setting them from the EXT4_IMMUTABLE_FL, EXT4_APPEND_FL flags, since this opens up a race where an immutable file has the immutable flag cleared for a brief window of time.

js: there is no change for ext4. This patch defines merely
inode_set_flags for jffs in the next patch. I wonder why do we have both inode_set_flags and set_mask_bits? Looks like an improperly resolved merge conflict.

---
 fs/ext4/inode.c    |  4 ++--
 fs/inode.c         | 31 +++++++++++++++++++++++++++++++
 include/linux/fs.h |  3 +++
 3 files changed, 36 insertions(+), 2 deletions(-)
fs/ext4/inode.c +2 -2
index a58a796bb92b..ba68d211d748 100644
@@ -3970,8 +3970,8 @@ void ext4_set_inode_flags(struct inode *inode)
 		new_fl |= S_NOATIME;
 	if (flags & EXT4_DIRSYNC_FL)
 		new_fl |= S_DIRSYNC;
-	set_mask_bits(&inode->i_flags,
-		      S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC, new_fl);
+	inode_set_flags(inode, new_fl,
+			S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
 }
 
 /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */
fs/inode.c +31 -0
index 1e6e8468f2d8..d9134a0f5dd9 100644
@@ -1871,3 +1871,34 @@ void inode_dio_done(struct inode *inode)
 		wake_up_bit(&inode->i_state, __I_DIO_WAKEUP);
 }
 EXPORT_SYMBOL(inode_dio_done);
+
+/*
+ * inode_set_flags - atomically set some inode flags
+ *
+ * Note: the caller should be holding i_mutex, or else be sure that
+ * they have exclusive access to the inode structure (i.e., while the
+ * inode is being instantiated).  The reason for the cmpxchg() loop
+ * --- which wouldn't be necessary if all code paths which modify
+ * i_flags actually followed this rule, is that there is at least one
+ * code path which doesn't today --- for example,
+ * __generic_file_aio_write() calls file_remove_suid() without holding
+ * i_mutex --- so we use cmpxchg() out of an abundance of caution.
+ *
+ * In the long run, i_mutex is overkill, and we should probably look
+ * at using the i_lock spinlock to protect i_flags, and then make sure
+ * it is so documented in include/linux/fs.h and that all code follows
+ * the locking convention!!
+ */
+void inode_set_flags(struct inode *inode, unsigned int flags,
+		     unsigned int mask)
+{
+	unsigned int old_flags, new_flags;
+
+	WARN_ON_ONCE(flags & ~mask);
+	do {
+		old_flags = ACCESS_ONCE(inode->i_flags);
+		new_flags = (old_flags & ~mask) | flags;
+	} while (unlikely(cmpxchg(&inode->i_flags, old_flags,
+				  new_flags) != old_flags));
+}
+EXPORT_SYMBOL(inode_set_flags);
include/linux/fs.h +3 -0
index 6535d5af027e..9cb726aa09fc 100644
@@ -2496,6 +2496,9 @@ static inline ssize_t blockdev_direct_IO(int rw, struct kiocb *iocb,
 void inode_dio_wait(struct inode *inode);
 void inode_dio_done(struct inode *inode);
 
+extern void inode_set_flags(struct inode *inode, unsigned int flags,
+			    unsigned int mask);
+
 extern const struct file_operations generic_ro_fops;
 
 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
Signature · 1 line
2.1.3
author
#100 lore raw

PATCH 100/101 fs/jfs/jfs_inode.c: atomically set inode->i_flags

In reply to Jiri Slaby

From: Fabian Frederick <[email protected]>

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

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

commit 24e4a0f3de21ad715c9235367e241554c64b9adb upstream.

According to commit 5f16f3225b0624

ext4: atomically set inode->i_flags in ext4_set_inode_flags()

---
 fs/jfs/jfs_inode.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
fs/jfs/jfs_inode.c +8 -8
index 7f464c513ba0..6b0f816201a2 100644
@@ -29,20 +29,20 @@
 void jfs_set_inode_flags(struct inode *inode)
 {
 	unsigned int flags = JFS_IP(inode)->mode2;
-
-	inode->i_flags &= ~(S_IMMUTABLE | S_APPEND |
-		S_NOATIME | S_DIRSYNC | S_SYNC);
+	unsigned int new_fl = 0;
 
 	if (flags & JFS_IMMUTABLE_FL)
-		inode->i_flags |= S_IMMUTABLE;
+		new_fl |= S_IMMUTABLE;
 	if (flags & JFS_APPEND_FL)
-		inode->i_flags |= S_APPEND;
+		new_fl |= S_APPEND;
 	if (flags & JFS_NOATIME_FL)
-		inode->i_flags |= S_NOATIME;
+		new_fl |= S_NOATIME;
 	if (flags & JFS_DIRSYNC_FL)
-		inode->i_flags |= S_DIRSYNC;
+		new_fl |= S_DIRSYNC;
 	if (flags & JFS_SYNC_FL)
-		inode->i_flags |= S_SYNC;
+		new_fl |= S_SYNC;
+	inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND | S_NOATIME |
+			S_DIRSYNC | S_SYNC);
 }
 
 void jfs_get_inode_flags(struct jfs_inode_info *jfs_ip)
Signature · 1 line
2.1.3
author
#101 lore raw

PATCH 101/101 x86: kvm: use alternatives for VMCALL vs. VMMCALL if kernel text is read-only

In reply to Jiri Slaby

From: Paolo Bonzini <[email protected]>

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

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

commit c1118b3602c2329671ad5ec8bdf8e374323d6343 upstream.

On x86_64, kernel text mappings are mapped read-only with CONFIG_DEBUG_RODATA. In that case, KVM will fail to patch VMCALL instructions to VMMCALL as required on AMD processors.

The failure mode is currently a divide-by-zero exception, which obviously is a KVM bug that has to be fixed. However, picking the right instruction between VMCALL and VMMCALL will be faster and will help if you cannot upgrade the hypervisor.

---
 arch/x86/include/asm/cpufeature.h |  1 +
 arch/x86/include/asm/kvm_para.h   | 10 ++++++++--
 arch/x86/kernel/cpu/amd.c         |  7 +++++++
 3 files changed, 16 insertions(+), 2 deletions(-)
arch/x86/include/asm/cpufeature.h +1 -0
index 89270b4318db..c2f19a83498d 100644
@@ -203,6 +203,7 @@
 #define X86_FEATURE_DECODEASSISTS (8*32+12) /* AMD Decode Assists support */
 #define X86_FEATURE_PAUSEFILTER (8*32+13) /* AMD filtered pause intercept */
 #define X86_FEATURE_PFTHRESHOLD (8*32+14) /* AMD pause filter threshold */
+#define X86_FEATURE_VMMCALL	(8*32+15) /* Prefer vmmcall to vmcall */
 
 
 /* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
arch/x86/include/asm/kvm_para.h +8 -2
index c7678e43465b..e62cf897f781 100644
@@ -2,6 +2,7 @@
 #define _ASM_X86_KVM_PARA_H
 
 #include <asm/processor.h>
+#include <asm/alternative.h>
 #include <uapi/asm/kvm_para.h>
 
 extern void kvmclock_init(void);
@@ -16,10 +17,15 @@ static inline bool kvm_check_and_clear_guest_paused(void)
 }
 #endif /* CONFIG_KVM_GUEST */
 
-/* This instruction is vmcall.  On non-VT architectures, it will generate a
- * trap that we will then rewrite to the appropriate instruction.
+#ifdef CONFIG_DEBUG_RODATA
+#define KVM_HYPERCALL \
+        ALTERNATIVE(".byte 0x0f,0x01,0xc1", ".byte 0x0f,0x01,0xd9", X86_FEATURE_VMMCALL)
+#else
+/* On AMD processors, vmcall will generate a trap that we will
+ * then rewrite to the appropriate instruction.
  */
 #define KVM_HYPERCALL ".byte 0x0f,0x01,0xc1"
+#endif
 
 /* For KVM hypercalls, a three-byte sequence of either the vmcall or the vmmcall
  * instruction.  The hypervisor may replace it with something else but only the
arch/x86/kernel/cpu/amd.c +7 -0
index 28233b9e45cc..ee51e67df1b1 100644
@@ -509,6 +509,13 @@ static void early_init_amd(struct cpuinfo_x86 *c)
 	}
 #endif
 
+	/*
+	 * This is only needed to tell the kernel whether to use VMCALL
+	 * and VMMCALL.  VMMCALL is never executed except under virt, so
+	 * we can set it unconditionally.
+	 */
+	set_cpu_cap(c, X86_FEATURE_VMMCALL);
+
 	/* F16h erratum 793, CVE-2013-6885 */
 	if (c->x86 == 0x16 && c->x86_model <= 0xf) {
 		u64 val;
Signature · 1 line
2.1.3
#102 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.34 release. There are 101 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 Fri Dec 5 12:25:22 CET 2014. Anything received after that time might be too late.

Build results:

	total: 135 pass: 135 fail: 0

Qemu tests:

	total: 27 pass: 27 fail: 0

Details are available at http://server.roeck-us.net:8010/builders.

Guenter

author
#103 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.34 release. There are 101 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 Fri Dec 5 12:25:22 CET 2014. Anything received after that time might be too late.

Build results:

	total: 135 pass: 135 fail: 0

Qemu tests:

	total: 27 pass: 27 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
#104 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.34 release. There are 101 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 Fri Dec 5 12:25:22 CET 2014. Anything received after that time might be too late.

Quoted 7 lines

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

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

and the diffstat can be found below.

thanks,
js

Compiled and booted on my test system. No dmesg regressions.

-- Shuah

Signature · 5 lines
Shuah Khan
Sr. Linux Kernel Developer
Samsung Open Source Group
Samsung Research America (Silicon Valley)
[email protected] | (970) 217-8978