Skip to contentSkip to conversation

3.12.72-stable review

PATCH In review Jiri Slaby 2 participants 62 messages Mar 14, 2017

Subsystems (2)
lore
Share & tools
lore

Jiri Slaby

author
#0 lore raw

cover 3.12.72-stable review

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

Responses should be made by Thu Mar 16 14:14:28 CET 2017. 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.72-rc1.xz

and the diffstat can be found below.

thanks,
js

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

Alexander Popov (1):
tty: n_hdlc: get rid of racy n_hdlc.tbuf

Arnaldo Carvalho de Melo (1):
perf trace: Use the syscall raw_syscalls:sys_enter timestamp

Arnd Bergmann (1):
staging: rtl: fix possible NULL pointer dereference

Chao Peng (1):
KVM: VMX: use correct vmcs_read/write for guest segment selector/base

Christian Lamparter (1):
ath9k: use correct OTP register offsets for the AR9340 and AR9550

Davidlohr Bueso (1):
ipc/shm: Fix shmat mmap nil-page protection

Dmitry Tunin (1):
Bluetooth: Add another AR3012 04ca:3018 device

Felix Fietkau (1):
ath5k: drop bogus warning on drv_set_key with unsupported cipher

Feras Daoud (1):
IB/ipoib: Fix deadlock between rmmod and set_mode

Guennadi Liakhovetski (1):
uvcvideo: Fix a wrong macro

Hannes Reinecke (1):
sd: get disk reference in sd_check_events()

Ian Abbott (1):
serial: 8250_pci: Add MKS Tenta SCOM-0800 and SCOM-0801 cards

J. Bruce Fields (1):
NFSv4: fix getacl head length estimation

James Cowgill (1):
MIPS: OCTEON: Fix copy_from_user fault handling for large buffers

James Smart (1):
scsi: lpfc: Correct WQ creation for pagesize

Jan Kara (1):
ext4: trim allocation requests to group size

Jaroslav Kysela (1):
ALSA: hda - fix Lewisburg audio issue

Jason Gunthorpe (1):
RDMA/core: Fix incorrect structure packing for booleans

Jiri Slaby (1):
TTY: n_hdlc, fix lockdep false positive

Julian Wiedmann (1):
s390/qdio: clear DSCI prior to scanning multiple input queues

K. Y. Srinivasan (1):
drivers: hv: Turn off write permission on the hypercall page

Long Li (3):
scsi: storvsc: use tagged SRB requests if supported by the device
scsi: storvsc: properly handle SRB_ERROR when sense message is present
scsi: storvsc: properly set residual data length on errors

Marc Kleine-Budde (1):
can: usb_8dev: Fix memory leak of priv->cmd_msg_buffer

Marcelo Ricardo Leitner (1):
sctp: deny peeloff operation on asocs with threads sleeping on it

Martin Schwidefsky (1):
s390: TASK_SIZE for kernel threads

Mathias Svensson (1):
samples/seccomp: fix 64-bit comparison macros

Matt Chen (1):
mac80211: flush delayed work when entering suspend

Max Filippov (1):
xtensa: move parse_tag_fdt out of #ifdef CONFIG_BLK_DEV_INITRD

Michel Dänzer (1):
drm/ttm: Make sure BOs being swapped out are cacheable

Miklos Szeredi (1):
fuse: add missing FR_FORCE

OGAWA Hirofumi (1):
fat: fix using uninitialized fields of fat_inode/fsinfo_inode

Paul Burton (6):
MIPS: Clear ISA bit correctly in get_frame_info()
MIPS: Prevent unaligned accesses during stack unwinding
MIPS: Fix get_frame_info() handling of microMIPS function size
MIPS: Fix is_jump_ins() handling of 16b microMIPS instructions
MIPS: Calculate microMIPS ra properly when unwinding the stack
MIPS: Handle microMIPS jumps in the same way as MIPS32/MIPS64 jumps

Rafał Miłecki (1):
bcma: use (get|put)_device when probing/removing device driver

Raghava Aditya Renukunta (1):
scsi: aacraid: Reorder Adapter status check

Ralf Baechle (3):
MIPS: Fix special case in 64 bit IP checksumming.
MIPS: IP22: Reformat inline assembler code to modern standards.
MIPS: IP22: Fix build error due to binutils 2.25 uselessnes.

Ravi Bangoria (1):
powerpc/xmon: Fix data-breakpoint

Shmulik Ladkani (1):
net/sched: em_meta: Fix 'meta vlan' to correctly recognize zero VID
frames

Steve Wise (1):
rdma_cm: fail iwarp accepts w/o connection params

Steven Rostedt (VMware) (1):
ktest: Fix child exit code processing

Takashi Iwai (2):
ALSA: timer: Reject user params with too small ticks
ALSA: seq: Fix link corruption by event error handling

Theodore Ts'o (3):
jbd2: don't leak modified metadata buffers on an aborted journal
ext4: preserve the needs_recovery flag when the journal is aborted
ext4: return EROFS if device is r/o and journal replay is needed

Trond Myklebust (2):
NFSv4: Fix memory and state leak in _nfs4_open_and_get_state
nlm: Ensure callback code also checks that the files match

Vinayak Menon (1):
mm: vmpressure: fix sending wrong events on underflow

Vitaly Kuznetsov (1):
hv: allocate synic pages for all present CPUs

Weston Andros Adamson (1):
NFSv4: fix getacl ERANGE for some ACL buffer sizes

Y.C. Chen (1):
drm/ast: Fix test for VGA enabled

[email protected] (1):
md linear: fix a race between linear_add() and linear_congested()

 arch/mips/cavium-octeon/octeon-memcpy.S        |  20 ++--
 arch/mips/include/asm/checksum.h               |   2 +
 arch/mips/kernel/process.c                     | 153 ++++++++++++++++---------
 arch/mips/mm/sc-ip22.c                         |  54 +++++----
 arch/powerpc/kernel/hw_breakpoint.c            |   4 +-
 arch/s390/include/asm/processor.h              |   3 +-
 arch/x86/kvm/vmx.c                             |   2 +-
 arch/xtensa/kernel/setup.c                     |   4 +-
 drivers/bcma/main.c                            |   4 +
 drivers/bluetooth/ath3k.c                      |   2 +
 drivers/bluetooth/btusb.c                      |   1 +
 drivers/gpu/drm/ast/ast_post.c                 |   8 +-
 drivers/gpu/drm/ttm/ttm_bo.c                   |   4 +-
 drivers/hv/hv.c                                |   6 +-
 drivers/infiniband/core/cma.c                  |   3 +
 drivers/infiniband/ulp/ipoib/ipoib_cm.c        |  12 +-
 drivers/infiniband/ulp/ipoib/ipoib_main.c      |   6 +-
 drivers/md/linear.c                            |  29 ++++-
 drivers/md/linear.h                            |   1 +
 drivers/media/usb/uvc/uvc_queue.c              |   2 +-
 drivers/net/can/usb/usb_8dev.c                 |   9 +-
 drivers/net/wireless/ath/ath5k/mac80211-ops.c  |   3 +-
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.h |   4 +-
 drivers/s390/cio/qdio_thinint.c                |   8 +-
 drivers/scsi/aacraid/src.c                     |  21 +++-
 drivers/scsi/lpfc/lpfc_hw4.h                   |   2 +
 drivers/scsi/lpfc/lpfc_sli.c                   |   9 +-
 drivers/scsi/sd.c                              |   9 +-
 drivers/scsi/storvsc_drv.c                     |  32 +++++-
 drivers/staging/rtl8188eu/core/rtw_recv.c      |   3 +
 drivers/staging/rtl8712/rtl871x_recv.c         |   7 +-
 drivers/tty/n_hdlc.c                           | 143 +++++++++++------------
 drivers/tty/serial/8250/8250_pci.c             |  13 +++
 fs/ext4/mballoc.c                              |   7 ++
 fs/ext4/super.c                                |   9 +-
 fs/fat/inode.c                                 |  13 ++-
 fs/fuse/file.c                                 |   1 +
 fs/jbd2/transaction.c                          |   4 +-
 fs/nfs/nfs4proc.c                              |  10 +-
 fs/nfs/nfs4xdr.c                               |   2 +-
 include/linux/lockd/lockd.h                    |   3 +-
 include/rdma/ib_sa.h                           |   6 +-
 ipc/shm.c                                      |  13 ++-
 mm/vmpressure.c                                |  10 +-
 net/mac80211/pm.c                              |   1 +
 net/sched/em_meta.c                            |   9 +-
 net/sctp/socket.c                              |   8 +-
 samples/seccomp/bpf-helper.h                   | 125 +++++++++++---------
 sound/core/seq/seq_fifo.c                      |   3 +
 sound/core/timer.c                             |  18 ++-
 sound/pci/hda/hda_intel.c                      |   4 +-
 tools/perf/builtin-trace.c                     |   4 +-
 tools/testing/ktest/ktest.pl                   |   2 +-
 53 files changed, 535 insertions(+), 300 deletions(-)
Signature · 1 line
2.12.0
author
#1 lore raw

PATCH 1/60 md linear: fix a race between linear_add() and linear_congested()

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

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

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

commit 03a9e24ef2aaa5f1f9837356aed79c860521407a upstream.

Recently I receive a bug report that on Linux v3.0 based kerenl, hot add disk to a md linear device causes kernel crash at linear_congested(). From the crash image analysis, I find in linear_congested(), mddev->raid_disks contains value N, but conf->disks[] only has N-1 pointers available. Then a NULL pointer deference crashes the kernel.

There is a race between linear_add() and linear_congested(), RCU stuffs used in these two functions cannot avoid the race. Since Linuv v4.0 RCU code is replaced by introducing mddev_suspend(). After checking the upstream code, it seems linear_congested() is not called in generic_make_request() code patch, so mddev_suspend() cannot provent it from being called. The possible race still exists.

Here I explain how the race still exists in current code. For a machine has many CPUs, on one CPU, linear_add() is called to add a hard disk to a md linear device; at the same time on other CPU, linear_congested() is called to detect whether this md linear device is congested before issuing an I/O request onto it.

Now I use a possible code execution time sequence to demo how the possible race happens,

seq linear_add() linear_congested()
0 conf=mddev->private
1 oldconf=mddev->private
2 mddev->raid_disks++
3 for (i=0; i<mddev->raid_disks;i++)
4 bdev_get_queue(conf->disks[i].rdev->bdev)
5 mddev->private=newconf

In linear_add() mddev->raid_disks is increased in time seq 2, and on another CPU in linear_congested() the for-loop iterates conf->disks[i] by the increased mddev->raid_disks in time seq 3,4. But conf with one more element (which is a pointer to struct dev_info type) to conf->disks[] is not updated yet, accessing its structure member in time seq 4 will cause a NULL pointer deference fault.

To fix this race, there are 2 parts of modification in the patch,
1) Add 'int raid_disks' in struct linear_conf, as a copy of

    mddev->raid_disks. It is initialized in linear_conf(), always being
    consistent with pointers number of 'struct dev_info disks[]'. When
    iterating conf->disks[] in linear_congested(), use conf->raid_disks to
    replace mddev->raid_disks in the for-loop, then NULL pointer deference
    will not happen again.

2) RCU stuffs are back again, and use kfree_rcu() in linear_add() to free oldconf memory. Because oldconf may be referenced as mddev->private in linear_congested(), kfree_rcu() makes sure that its memory will not be released until no one uses it any more.
Also some code comments are added in this patch, to make this modification to be easier understandable.

This patch can be applied for kernels since v4.0 after commit:
3be260cc18f8 ("md/linear: remove rcu protections in favour of suspend/resume"). But this bug is reported on Linux v3.0 based kernel, for people who maintain kernels before Linux v4.0, they need to do some back back port to this patch.

Changelog:
- V3: add 'int raid_disks' in struct linear_conf, and use kfree_rcu() to replace rcu_call() in linear_add().
- v2: add RCU stuffs by suggestion from Shaohua and Neil.
- v1: initial effort.

---
 drivers/md/linear.c | 29 ++++++++++++++++++++++++++++-
 drivers/md/linear.h |  1 +
 2 files changed, 29 insertions(+), 1 deletion(-)
drivers/md/linear.c +28 -1
index f03fabd2b37b..f169afac0266 100644
@@ -97,6 +97,12 @@ static int linear_mergeable_bvec(struct request_queue *q,
 		return maxsectors << 9;
 }
 
+/*
+ * In linear_congested() conf->raid_disks is used as a copy of
+ * mddev->raid_disks to iterate conf->disks[], because conf->raid_disks
+ * and conf->disks[] are created in linear_conf(), they are always
+ * consitent with each other, but mddev->raid_disks does not.
+ */
 static int linear_congested(void *data, int bits)
 {
 	struct mddev *mddev = data;
@@ -109,7 +115,7 @@ static int linear_congested(void *data, int bits)
 	rcu_read_lock();
 	conf = rcu_dereference(mddev->private);
 
-	for (i = 0; i < mddev->raid_disks && !ret ; i++) {
+	for (i = 0; i < conf->raid_disks && !ret ; i++) {
 		struct request_queue *q = bdev_get_queue(conf->disks[i].rdev->bdev);
 		ret |= bdi_congested(&q->backing_dev_info, bits);
 	}
@@ -196,6 +202,19 @@ static struct linear_conf *linear_conf(struct mddev *mddev, int raid_disks)
 			conf->disks[i-1].end_sector +
 			conf->disks[i].rdev->sectors;
 
+	/*
+	 * conf->raid_disks is copy of mddev->raid_disks. The reason to
+	 * keep a copy of mddev->raid_disks in struct linear_conf is,
+	 * mddev->raid_disks may not be consistent with pointers number of
+	 * conf->disks[] when it is updated in linear_add() and used to
+	 * iterate old conf->disks[] earray in linear_congested().
+	 * Here conf->raid_disks is always consitent with number of
+	 * pointers in conf->disks[] array, and mddev->private is updated
+	 * with rcu_assign_pointer() in linear_addr(), such race can be
+	 * avoided.
+	 */
+	conf->raid_disks = raid_disks;
+
 	return conf;
 
 out:
@@ -252,10 +271,18 @@ static int linear_add(struct mddev *mddev, struct md_rdev *rdev)
 	if (!newconf)
 		return -ENOMEM;
 
+	/* newconf->raid_disks already keeps a copy of * the increased
+	 * value of mddev->raid_disks, WARN_ONCE() is just used to make
+	 * sure of this. It is possible that oldconf is still referenced
+	 * in linear_congested(), therefore kfree_rcu() is used to free
+	 * oldconf until no one uses it anymore.
+	 */
 	oldconf = rcu_dereference_protected(mddev->private,
 					    lockdep_is_held(
 						    &mddev->reconfig_mutex));
 	mddev->raid_disks++;
+	WARN_ONCE(mddev->raid_disks != newconf->raid_disks,
+		"copied raid_disks doesn't match mddev->raid_disks");
 	rcu_assign_pointer(mddev->private, newconf);
 	md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
 	set_capacity(mddev->gendisk, mddev->array_sectors);
drivers/md/linear.h +1 -0
index b685ddd7d7f7..8d392e6098b3 100644
@@ -10,6 +10,7 @@ struct linear_conf
 {
 	struct rcu_head		rcu;
 	sector_t		array_sectors;
+	int			raid_disks; /* a copy of mddev->raid_disks */
 	struct dev_info		disks[0];
 };
 #endif
Signature · 1 line
2.12.0
author
#2 lore raw

PATCH 2/60 sctp: deny peeloff operation on asocs with threads sleeping on it

From: Marcelo Ricardo Leitner <[email protected]>

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

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

commit dfcb9f4f99f1e9a49e43398a7bfbf56927544af1 upstream.

commit 2dcab5984841 ("sctp: avoid BUG_ON on sctp_wait_for_sndbuf") attempted to avoid a BUG_ON call when the association being used for a sendmsg() is blocked waiting for more sndbuf and another thread did a peeloff operation on such asoc, moving it to another socket.

As Ben Hutchings noticed, then in such case it would return without locking back the socket and would cause two unlocks in a row.

Further analysis also revealed that it could allow a double free if the application managed to peeloff the asoc that is created during the sendmsg call, because then sctp_sendmsg() would try to free the asoc that was created only for that call.

This patch takes another approach. It will deny the peeloff operation if there is a thread sleeping on the asoc, so this situation doesn't exist anymore. This avoids the issues described above and also honors the syscalls that are already being handled (it can be multiple sendmsg calls).

Joint work with Xin Long.

Fixes 2dcab5984841 ("sctp: avoid BUG_ON on sctp_wait_for_sndbuf")
Cc Alexander Popov <[email protected]>
Cc Ben Hutchings <[email protected]>
---
 net/sctp/socket.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
net/sctp/socket.c +6 -2
index 8e7cc3e2b08b..0059ce3fb747 100644
@@ -4298,6 +4298,12 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp)
 	if (!asoc)
 		return -EINVAL;
 
+	/* If there is a thread waiting on more sndbuf space for
+	 * sending on this asoc, it cannot be peeled.
+	 */
+	if (waitqueue_active(&asoc->wait))
+		return -EBUSY;
+
 	/* An association cannot be branched off from an already peeled-off
 	 * socket, nor is this supported for tcp style sockets.
 	 */
@@ -6712,8 +6718,6 @@ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p,
 		 */
 		sctp_release_sock(sk);
 		current_timeo = schedule_timeout(current_timeo);
-		if (sk != asoc->base.sk)
-			goto do_error;
 		sctp_lock_sock(sk);
 
 		*timeo_p = current_timeo;
Signature · 1 line
2.12.0
author
#3 lore raw

PATCH 3/60 net/sched: em_meta: Fix 'meta vlan' to correctly recognize zero VID frames

In reply to Jiri Slaby

From: Shmulik Ladkani <[email protected]>

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

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

commit d65f2fa680d6f91438461df54c83a331b3a631c9 upstream.

META_COLLECTOR int_vlan_tag() assumes that if the accel tag (vlan_tci) is zero, then no vlan accel tag is present.

This is incorrect for zero VID vlan accel packets, making the following match fail:
tc filter add ... basic match 'meta(vlan mask 0xfff eq 0)' ...

Apparently 'int_vlan_tag' was implemented prior VLAN_TAG_PRESENT was introduced in 05423b2 "vlan: allow null VLAN ID to be used" (and at time introduced, the 'vlan_tx_tag_get' call in em_meta was not
adapted).

Fix, testing skb_vlan_tag_present instead of testing skb_vlan_tag_get's value.

Fixes 05423b2413 ("vlan: allow null VLAN ID to be used")
Fixes 1a31f2042e ("netsched: Allow meta match on vlan tag on receive")
---
 net/sched/em_meta.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
net/sched/em_meta.c +5 -4
index 7c3de6ffa516..eba9d1e49faf 100644
@@ -176,11 +176,12 @@ META_COLLECTOR(int_vlan_tag)
 {
 	unsigned short tag;
 
-	tag = vlan_tx_tag_get(skb);
-	if (!tag && __vlan_get_tag(skb, &tag))
-		*err = -1;
-	else
+	if (vlan_tx_tag_present(skb))
+		dst->value = vlan_tx_tag_get(skb);
+	else if (!__vlan_get_tag(skb, &tag))
 		dst->value = tag;
+	else
+		*err = -1;
 }
 
 
Signature · 1 line
2.12.0
author
#4 lore raw

PATCH 4/60 perf trace: Use the syscall raw_syscalls:sys_enter timestamp

In reply to Jiri Slaby

From: Arnaldo Carvalho de Melo <[email protected]>

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

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

commit ecf1e2253ea79c6204f4d6a5e756e8fb4aed5a7e upstream.

Instead of the one when another syscall takes place while another is being processed (in another CPU, but we show it serialized, so need to "interrupt" the other), and also when finally showing the sys_enter + sys_exit + duration, where we were showing the sample->time for the sys_exit, duh.

Before:

  # perf trace sleep 1
  <SNIP>
     0.373 (   0.001 ms): close(fd: 3                   ) = 0
  1000.626 (1000.211 ms): nanosleep(rqtp: 0x7ffd6ddddfb0) = 0
  1000.653 (   0.003 ms): close(fd: 1                   ) = 0
  1000.657 (   0.002 ms): close(fd: 2                   ) = 0
  1000.667 (   0.000 ms): exit_group(                   )
  #

After:

  # perf trace sleep 1
  <SNIP>
     0.336 (   0.001 ms): close(fd: 3                   ) = 0
     0.373 (1000.086 ms): nanosleep(rqtp: 0x7ffe303e9550) = 0
  1000.481 (   0.002 ms): close(fd: 1                   ) = 0
  1000.485 (   0.001 ms): close(fd: 2                   ) = 0
  1000.494 (   0.000 ms): exit_group(                   )
[root@jouet linux]#

[js] no trace__printf_interrupted_entry in 3.12 yet

Cc Adrian Hunter <[email protected]>
Cc David Ahern <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Wang Nan <[email protected]>
Fixes 752fde44fd1c ("perf trace: Support interrupted syscalls")
---
 tools/perf/builtin-trace.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/builtin-trace.c +2 -2
index 99c8d9ad6729..4fad689f02e7 100644
@@ -732,7 +732,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
 
 	if (!strcmp(sc->name, "exit_group") || !strcmp(sc->name, "exit")) {
 		if (!trace->duration_filter) {
-			trace__fprintf_entry_head(trace, thread, 1, sample->time, trace->output);
+			trace__fprintf_entry_head(trace, thread, 1, ttrace->entry_time, trace->output);
 			fprintf(trace->output, "%-70s\n", ttrace->entry_str);
 		}
 	} else
@@ -775,7 +775,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
 	} else if (trace->duration_filter)
 		goto out;
 
-	trace__fprintf_entry_head(trace, thread, duration, sample->time, trace->output);
+	trace__fprintf_entry_head(trace, thread, duration, ttrace->entry_time, trace->output);
 
 	if (ttrace->entry_pending) {
 		fprintf(trace->output, "%-70s", ttrace->entry_str);
Signature · 1 line
2.12.0
author
#5 lore raw

PATCH 5/60 MIPS: Fix special case in 64 bit IP checksumming.

In reply to Jiri Slaby

From: Ralf Baechle <[email protected]>

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

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

commit 66fd848cadaa6be974a8c780fbeb328f0af4d3bd upstream.

For certain arguments such as saddr = 0xc0a8fd60, daddr = 0xc0a8fda1, len = 80, proto = 17, sum = 0x7eae049d there will be a carry when folding the intermediate 64 bit checksum to 32 bit but the code doesn't add the carry back to the one's complement sum, thus an incorrect result will be generated.

---
 arch/mips/include/asm/checksum.h | 2 ++
 1 file changed, 2 insertions(+)
arch/mips/include/asm/checksum.h +2 -0
index ac3d2b8a20d4..d48cf440010c 100644
@@ -155,7 +155,9 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr,
 	"	daddu	%0, %4		\n"
 	"	dsll32	$1, %0, 0	\n"
 	"	daddu	%0, $1		\n"
+	"	sltu	$1, %0, $1	\n"
 	"	dsra32	%0, %0, 0	\n"
+	"	addu	%0, $1		\n"
 #endif
 	"	.set	pop"
 	: "=r" (sum)
Signature · 1 line
2.12.0
author
#6 lore raw

PATCH 6/60 MIPS: OCTEON: Fix copy_from_user fault handling for large buffers

In reply to Jiri Slaby

From: James Cowgill <[email protected]>

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

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

commit 884b426917e4b3c85f33b382c792a94305dfdd62 upstream.

If copy_from_user is called with a large buffer (>= 128 bytes) and the userspace buffer refers partially to unreadable memory, then it is possible for Octeon's copy_from_user to report the wrong number of bytes have been copied. In the case where the buffer size is an exact multiple of 128 and the fault occurs in the last 64 bytes, copy_from_user will report that all the bytes were copied successfully but leave some garbage in the destination buffer.

The bug is in the main __copy_user_common loop in octeon-memcpy.S where in the middle of the loop, src and dst are incremented by 128 bytes. The l_exc_copy fault handler is used after this but that assumes that "src < THREAD_BUADDR($28)". This is not the case if src has already been incremented.

Fix by adding an extra fault handler which rewinds the src and dst pointers 128 bytes before falling though to l_exc_copy.

Thanks to the pwritev test from the strace test suite for originally highlighting this bug!

Fixes 5b3b16880f40 ("MIPS: Add Cavium OCTEON processor support ...")
Cc Ralf Baechle <[email protected]>

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

---
 arch/mips/cavium-octeon/octeon-memcpy.S | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)
arch/mips/cavium-octeon/octeon-memcpy.S +12 -8
index 64e08df51d65..8b7004132491 100644
@@ -208,18 +208,18 @@ EXC(	STORE	t2, UNIT(6)(dst),	s_exc_p10u)
 	ADD	src, src, 16*NBYTES
 EXC(	STORE	t3, UNIT(7)(dst),	s_exc_p9u)
 	ADD	dst, dst, 16*NBYTES
-EXC(	LOAD	t0, UNIT(-8)(src),	l_exc_copy)
-EXC(	LOAD	t1, UNIT(-7)(src),	l_exc_copy)
-EXC(	LOAD	t2, UNIT(-6)(src),	l_exc_copy)
-EXC(	LOAD	t3, UNIT(-5)(src),	l_exc_copy)
+EXC(	LOAD	t0, UNIT(-8)(src),	l_exc_copy_rewind16)
+EXC(	LOAD	t1, UNIT(-7)(src),	l_exc_copy_rewind16)
+EXC(	LOAD	t2, UNIT(-6)(src),	l_exc_copy_rewind16)
+EXC(	LOAD	t3, UNIT(-5)(src),	l_exc_copy_rewind16)
 EXC(	STORE	t0, UNIT(-8)(dst),	s_exc_p8u)
 EXC(	STORE	t1, UNIT(-7)(dst),	s_exc_p7u)
 EXC(	STORE	t2, UNIT(-6)(dst),	s_exc_p6u)
 EXC(	STORE	t3, UNIT(-5)(dst),	s_exc_p5u)
-EXC(	LOAD	t0, UNIT(-4)(src),	l_exc_copy)
-EXC(	LOAD	t1, UNIT(-3)(src),	l_exc_copy)
-EXC(	LOAD	t2, UNIT(-2)(src),	l_exc_copy)
-EXC(	LOAD	t3, UNIT(-1)(src),	l_exc_copy)
+EXC(	LOAD	t0, UNIT(-4)(src),	l_exc_copy_rewind16)
+EXC(	LOAD	t1, UNIT(-3)(src),	l_exc_copy_rewind16)
+EXC(	LOAD	t2, UNIT(-2)(src),	l_exc_copy_rewind16)
+EXC(	LOAD	t3, UNIT(-1)(src),	l_exc_copy_rewind16)
 EXC(	STORE	t0, UNIT(-4)(dst),	s_exc_p4u)
 EXC(	STORE	t1, UNIT(-3)(dst),	s_exc_p3u)
 EXC(	STORE	t2, UNIT(-2)(dst),	s_exc_p2u)
@@ -383,6 +383,10 @@ done:
 	 nop
 	END(memcpy)
 
+l_exc_copy_rewind16:
+	/* Rewind src and dst by 16*NBYTES for l_exc_copy */
+	SUB	src, src, 16*NBYTES
+	SUB	dst, dst, 16*NBYTES
 l_exc_copy:
 	/*
 	 * Copy bytes from src until faulting load address (or until a
Signature · 1 line
2.12.0
author
#7 lore raw

PATCH 7/60 MIPS: Clear ISA bit correctly in get_frame_info()

In reply to Jiri Slaby

From: Paul Burton <[email protected]>

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

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

commit ccaf7caf2c73c6db920772bf08bf1d47b2170634 upstream.

get_frame_info() can be called in microMIPS kernels with the ISA bit already clear. For example this happens when unwind_stack_by_address() is called because we begin with a PC that has the ISA bit set & subtract the (odd) offset from the preceding symbol (which does not have the ISA bit set). Since get_frame_info() unconditionally subtracts 1 from the PC in microMIPS kernels it incorrectly misaligns the address it then attempts to access code at, leading to an address error exception.

Fix this by using msk_isa16_mode() to clear the ISA bit, which allows get_frame_info() to function regardless of whether it is provided with a PC that has the ISA bit set or not.

Fixes 34c2f668d0f6 ("MIPS: microMIPS: Add unaligned access support.")
Cc Leonid Yegoshin <[email protected]>

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

---
 arch/mips/kernel/process.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)
arch/mips/kernel/process.c +2 -5
index ddc76103e78c..c5880a894a25 100644
@@ -325,17 +325,14 @@ static inline int is_sp_move_ins(union mips_instruction *ip)
 
 static int get_frame_info(struct mips_frame_info *info)
 {
-#ifdef CONFIG_CPU_MICROMIPS
-	union mips_instruction *ip = (void *) (((char *) info->func) - 1);
-#else
-	union mips_instruction *ip = info->func;
-#endif
+	union mips_instruction *ip;
 	unsigned max_insns = info->func_size / sizeof(union mips_instruction);
 	unsigned i;
 
 	info->pc_offset = -1;
 	info->frame_size = 0;
 
+	ip = (void *)msk_isa16_mode((ulong)info->func);
 	if (!ip)
 		goto err;
 
Signature · 1 line
2.12.0
author
#8 lore raw

PATCH 8/60 MIPS: Prevent unaligned accesses during stack unwinding

In reply to Jiri Slaby

From: Paul Burton <[email protected]>

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

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

commit a3552dace7d1d0cabf573e88fc3025cb90c4a601 upstream.

During stack unwinding we call a number of functions to determine what type of instruction we're looking at. The union mips_instruction pointer provided to them may be pointing at a 2 byte, but not 4 byte, aligned address & we thus cannot directly access the 4 byte wide members of the union mips_instruction. To avoid this is_ra_save_ins() copies the required half-words of the microMIPS instruction to a correctly aligned union mips_instruction on the stack, which it can then access safely. The is_jump_ins() & is_sp_move_ins() functions do not correctly perform this temporary copy, and instead attempt to directly dereference 4 byte fields which may be misaligned and lead to an address exception.

Fix this by copying the instruction halfwords to a temporary union mips_instruction in get_frame_info() such that we can provide a 4 byte aligned union mips_instruction to the is_*_ins() functions and they do not need to deal with misalignment themselves.

Fixes 34c2f668d0f6 ("MIPS: microMIPS: Add unaligned access support.")
Cc Leonid Yegoshin <[email protected]>

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

---
 arch/mips/kernel/process.c | 70 +++++++++++++++++++++++-----------------------
 1 file changed, 35 insertions(+), 35 deletions(-)
arch/mips/kernel/process.c +35 -35
index c5880a894a25..5b91c4d88f46 100644
@@ -220,8 +220,6 @@ struct mips_frame_info {
 static inline int is_ra_save_ins(union mips_instruction *ip)
 {
 #ifdef CONFIG_CPU_MICROMIPS
-	union mips_instruction mmi;
-
 	/*
 	 * swsp ra,offset
 	 * swm16 reglist,offset(sp)
@@ -231,23 +229,20 @@ static inline int is_ra_save_ins(union mips_instruction *ip)
 	 *
 	 * microMIPS is way more fun...
 	 */
-	if (mm_insn_16bit(ip->halfword[0])) {
-		mmi.word = (ip->halfword[0] << 16);
-		return ((mmi.mm16_r5_format.opcode == mm_swsp16_op &&
-			 mmi.mm16_r5_format.rt == 31) ||
-			(mmi.mm16_m_format.opcode == mm_pool16c_op &&
-			 mmi.mm16_m_format.func == mm_swm16_op));
+	if (mm_insn_16bit(ip->halfword[1])) {
+		return (ip->mm16_r5_format.opcode == mm_swsp16_op &&
+			ip->mm16_r5_format.rt == 31) ||
+		       (ip->mm16_m_format.opcode == mm_pool16c_op &&
+			ip->mm16_m_format.func == mm_swm16_op);
 	}
 	else {
-		mmi.halfword[0] = ip->halfword[1];
-		mmi.halfword[1] = ip->halfword[0];
-		return ((mmi.mm_m_format.opcode == mm_pool32b_op &&
-			 mmi.mm_m_format.rd > 9 &&
-			 mmi.mm_m_format.base == 29 &&
-			 mmi.mm_m_format.func == mm_swm32_func) ||
-			(mmi.i_format.opcode == mm_sw32_op &&
-			 mmi.i_format.rs == 29 &&
-			 mmi.i_format.rt == 31));
+		return (ip->mm_m_format.opcode == mm_pool32b_op &&
+			ip->mm_m_format.rd > 9 &&
+			ip->mm_m_format.base == 29 &&
+			ip->mm_m_format.func == mm_swm32_func) ||
+		       (ip->i_format.opcode == mm_sw32_op &&
+			ip->i_format.rs == 29 &&
+			ip->i_format.rt == 31);
 	}
 #else
 	/* sw / sd $ra, offset($sp) */
@@ -268,12 +263,8 @@ static inline int is_jump_ins(union mips_instruction *ip)
 	 *
 	 * microMIPS is kind of more fun...
 	 */
-	union mips_instruction mmi;
-
-	mmi.word = (ip->halfword[0] << 16);
-
-	if ((mmi.mm16_r5_format.opcode == mm_pool16c_op &&
-	    (mmi.mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op) ||
+	if ((ip->mm16_r5_format.opcode == mm_pool16c_op &&
+	    (ip->mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op) ||
 	    ip->j_format.opcode == mm_jal32_op)
 		return 1;
 	if (ip->r_format.opcode != mm_pool32a_op ||
@@ -302,15 +293,13 @@ static inline int is_sp_move_ins(union mips_instruction *ip)
 	 *
 	 * microMIPS is not more fun...
 	 */
-	if (mm_insn_16bit(ip->halfword[0])) {
-		union mips_instruction mmi;
-
-		mmi.word = (ip->halfword[0] << 16);
-		return ((mmi.mm16_r3_format.opcode == mm_pool16d_op &&
-			 mmi.mm16_r3_format.simmediate && mm_addiusp_func) ||
-			(mmi.mm16_r5_format.opcode == mm_pool16d_op &&
-			 mmi.mm16_r5_format.rt == 29));
+	if (mm_insn_16bit(ip->halfword[1])) {
+		return (ip->mm16_r3_format.opcode == mm_pool16d_op &&
+			ip->mm16_r3_format.simmediate && mm_addiusp_func) ||
+		       (ip->mm16_r5_format.opcode == mm_pool16d_op &&
+			ip->mm16_r5_format.rt == 29);
 	}
+
 	return (ip->mm_i_format.opcode == mm_addiu32_op &&
 		 ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29);
 #else
@@ -325,7 +314,8 @@ static inline int is_sp_move_ins(union mips_instruction *ip)
 
 static int get_frame_info(struct mips_frame_info *info)
 {
-	union mips_instruction *ip;
+	bool is_mmips = IS_ENABLED(CONFIG_CPU_MICROMIPS);
+	union mips_instruction insn, *ip;
 	unsigned max_insns = info->func_size / sizeof(union mips_instruction);
 	unsigned i;
 
@@ -341,11 +331,21 @@ static int get_frame_info(struct mips_frame_info *info)
 	max_insns = min(128U, max_insns);
 
 	for (i = 0; i < max_insns; i++, ip++) {
+		if (is_mmips && mm_insn_16bit(ip->halfword[0])) {
+			insn.halfword[0] = 0;
+			insn.halfword[1] = ip->halfword[0];
+		} else if (is_mmips) {
+			insn.halfword[0] = ip->halfword[1];
+			insn.halfword[1] = ip->halfword[0];
+		} else {
+			insn.word = ip->word;
+		}
 
-		if (is_jump_ins(ip))
+		if (is_jump_ins(&insn))
 			break;
+
 		if (!info->frame_size) {
-			if (is_sp_move_ins(ip))
+			if (is_sp_move_ins(&insn))
 			{
 #ifdef CONFIG_CPU_MICROMIPS
 				if (mm_insn_16bit(ip->halfword[0]))
@@ -368,7 +368,7 @@ static int get_frame_info(struct mips_frame_info *info)
 			}
 			continue;
 		}
-		if (info->pc_offset == -1 && is_ra_save_ins(ip)) {
+		if (info->pc_offset == -1 && is_ra_save_ins(&insn)) {
 			info->pc_offset =
 				ip->i_format.simmediate / sizeof(long);
 			break;
Signature · 1 line
2.12.0
author
#9 lore raw

PATCH 9/60 MIPS: Fix get_frame_info() handling of microMIPS function size

In reply to Jiri Slaby

From: Paul Burton <[email protected]>

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

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

commit b6c7a324df37bf05ef7a2c1580683cf10d082d97 upstream.

get_frame_info() is meant to iterate over up to the first 128 instructions within a function, but for microMIPS kernels it will not reach that many instructions unless the function is 512 bytes long since we calculate the maximum number of instructions to check by dividing the function length by the 4 byte size of a union mips_instruction. In microMIPS kernels this won't do since instructions are variable length.

Fix this by instead checking whether the pointer to the current instruction has reached the end of the function, and use max_insns as a simple constant to check the number of iterations against.

Fixes 34c2f668d0f6 ("MIPS: microMIPS: Add unaligned access support.")
Cc Leonid Yegoshin <[email protected]>

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

---
 arch/mips/kernel/process.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)
arch/mips/kernel/process.c +5 -7
index 5b91c4d88f46..664e61ef690b 100644
@@ -315,9 +315,9 @@ static inline int is_sp_move_ins(union mips_instruction *ip)
 static int get_frame_info(struct mips_frame_info *info)
 {
 	bool is_mmips = IS_ENABLED(CONFIG_CPU_MICROMIPS);
-	union mips_instruction insn, *ip;
-	unsigned max_insns = info->func_size / sizeof(union mips_instruction);
-	unsigned i;
+	union mips_instruction insn, *ip, *ip_end;
+	const unsigned int max_insns = 128;
+	unsigned int i;
 
 	info->pc_offset = -1;
 	info->frame_size = 0;
@@ -326,11 +326,9 @@ static int get_frame_info(struct mips_frame_info *info)
 	if (!ip)
 		goto err;
 
-	if (max_insns == 0)
-		max_insns = 128U;	/* unknown function size */
-	max_insns = min(128U, max_insns);
+	ip_end = (void *)ip + info->func_size;
 
-	for (i = 0; i < max_insns; i++, ip++) {
+	for (i = 0; i < max_insns && ip < ip_end; i++, ip++) {
 		if (is_mmips && mm_insn_16bit(ip->halfword[0])) {
 			insn.halfword[0] = 0;
 			insn.halfword[1] = ip->halfword[0];
Signature · 1 line
2.12.0
author
#10 lore raw

PATCH 10/60 MIPS: Fix is_jump_ins() handling of 16b microMIPS instructions

In reply to Jiri Slaby

From: Paul Burton <[email protected]>

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

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

commit 67c75057709a6d85c681c78b9b2f9b71191f01a2 upstream.

is_jump_ins() checks 16b instruction fields without verifying that the instruction is indeed 16b, as is done by is_ra_save_ins() & is_sp_move_ins(). Add the appropriate check.

Fixes 34c2f668d0f6 ("MIPS: microMIPS: Add unaligned access support.")
Cc Leonid Yegoshin <[email protected]>

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

---
 arch/mips/kernel/process.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)
arch/mips/kernel/process.c +8 -3
index 664e61ef690b..92cec1380f8c 100644
@@ -263,9 +263,14 @@ static inline int is_jump_ins(union mips_instruction *ip)
 	 *
 	 * microMIPS is kind of more fun...
 	 */
-	if ((ip->mm16_r5_format.opcode == mm_pool16c_op &&
-	    (ip->mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op) ||
-	    ip->j_format.opcode == mm_jal32_op)
+	if (mm_insn_16bit(ip->halfword[1])) {
+		if ((ip->mm16_r5_format.opcode == mm_pool16c_op &&
+		    (ip->mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op))
+			return 1;
+		return 0;
+	}
+
+	if (ip->j_format.opcode == mm_jal32_op)
 		return 1;
 	if (ip->r_format.opcode != mm_pool32a_op ||
 			ip->r_format.func != mm_pool32axf_op)
Signature · 1 line
2.12.0
author
#11 lore raw

PATCH 11/60 MIPS: Calculate microMIPS ra properly when unwinding the stack

In reply to Jiri Slaby

From: Paul Burton <[email protected]>

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

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

commit bb9bc4689b9c635714fbcd5d335bad9934a7ebfc upstream.

get_frame_info() calculates the offset of the return address within a stack frame simply by dividing a the bottom 16 bits of the instruction, treated as a signed integer, by the size of a long. Whilst this works for MIPS32 & MIPS64 ISAs where the sw or sd instructions are used, it's incorrect for microMIPS where encodings differ. The result is that we typically completely fail to unwind the stack on microMIPS.

Fix this by adjusting is_ra_save_ins() to calculate the return address offset, and take into account the various different encodings there in the same place as we consider whether an instruction is storing the ra/$31 register.

With this we are now able to unwind the stack for kernels targetting the microMIPS ISA, for example we can produce:

    Call Trace:
    [<80109e1f>] show_stack+0x63/0x7c
    [<8011ea17>] __warn+0x9b/0xac
    [<8011ea45>] warn_slowpath_fmt+0x1d/0x20
    [<8013fe53>] register_console+0x43/0x314
    [<8067c58d>] of_setup_earlycon+0x1dd/0x1ec
    [<8067f63f>] early_init_dt_scan_chosen_stdout+0xe7/0xf8
    [<8066c115>] do_early_param+0x75/0xac
    [<801302f9>] parse_args+0x1dd/0x308
    [<8066c459>] parse_early_options+0x25/0x28
    [<8066c48b>] parse_early_param+0x2f/0x38
    [<8066e8cf>] setup_arch+0x113/0x488
    [<8066c4f3>] start_kernel+0x57/0x328
    ---[ end trace 0000000000000000 ]---

Whereas previously we only produced:

    Call Trace:
    [<80109e1f>] show_stack+0x63/0x7c
    ---[ end trace 0000000000000000 ]---
Fixes 34c2f668d0f6 ("MIPS: microMIPS: Add unaligned access support.")
Cc Leonid Yegoshin <[email protected]>

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

---
 arch/mips/kernel/process.c | 83 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 63 insertions(+), 20 deletions(-)
arch/mips/kernel/process.c +63 -20
index 92cec1380f8c..a79bcd66778f 100644
@@ -217,7 +217,7 @@ struct mips_frame_info {
 #define J_TARGET(pc,target)	\
 		(((unsigned long)(pc) & 0xf0000000) | ((target) << 2))
 
-static inline int is_ra_save_ins(union mips_instruction *ip)
+static inline int is_ra_save_ins(union mips_instruction *ip, int *poff)
 {
 #ifdef CONFIG_CPU_MICROMIPS
 	/*
@@ -230,25 +230,70 @@ static inline int is_ra_save_ins(union mips_instruction *ip)
 	 * microMIPS is way more fun...
 	 */
 	if (mm_insn_16bit(ip->halfword[1])) {
-		return (ip->mm16_r5_format.opcode == mm_swsp16_op &&
-			ip->mm16_r5_format.rt == 31) ||
-		       (ip->mm16_m_format.opcode == mm_pool16c_op &&
-			ip->mm16_m_format.func == mm_swm16_op);
+		switch (ip->mm16_r5_format.opcode) {
+		case mm_swsp16_op:
+			if (ip->mm16_r5_format.rt != 31)
+				return 0;
+
+			*poff = ip->mm16_r5_format.simmediate;
+			*poff = (*poff << 2) / sizeof(ulong);
+			return 1;
+
+		case mm_pool16c_op:
+			switch (ip->mm16_m_format.func) {
+			case mm_swm16_op:
+				*poff = ip->mm16_m_format.imm;
+				*poff += 1 + ip->mm16_m_format.rlist;
+				*poff = (*poff << 2) / sizeof(ulong);
+				return 1;
+
+			default:
+				return 0;
+			}
+
+		default:
+			return 0;
+		}
 	}
-	else {
-		return (ip->mm_m_format.opcode == mm_pool32b_op &&
-			ip->mm_m_format.rd > 9 &&
-			ip->mm_m_format.base == 29 &&
-			ip->mm_m_format.func == mm_swm32_func) ||
-		       (ip->i_format.opcode == mm_sw32_op &&
-			ip->i_format.rs == 29 &&
-			ip->i_format.rt == 31);
+
+	switch (ip->i_format.opcode) {
+	case mm_sw32_op:
+		if (ip->i_format.rs != 29)
+			return 0;
+		if (ip->i_format.rt != 31)
+			return 0;
+
+		*poff = ip->i_format.simmediate / sizeof(ulong);
+		return 1;
+
+	case mm_pool32b_op:
+		switch (ip->mm_m_format.func) {
+		case mm_swm32_func:
+			if (ip->mm_m_format.rd < 0x10)
+				return 0;
+			if (ip->mm_m_format.base != 29)
+				return 0;
+
+			*poff = ip->mm_m_format.simmediate;
+			*poff += (ip->mm_m_format.rd & 0xf) * sizeof(u32);
+			*poff /= sizeof(ulong);
+			return 1;
+		default:
+			return 0;
+		}
+
+	default:
+		return 0;
 	}
 #else
 	/* sw / sd $ra, offset($sp) */
-	return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) &&
-		ip->i_format.rs == 29 &&
-		ip->i_format.rt == 31;
+	if ((ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) &&
+		ip->i_format.rs == 29 && ip->i_format.rt == 31) {
+		*poff = ip->i_format.simmediate / sizeof(ulong);
+		return 1;
+	}
+
+	return 0;
 #endif
 }
 
@@ -371,11 +416,9 @@ static int get_frame_info(struct mips_frame_info *info)
 			}
 			continue;
 		}
-		if (info->pc_offset == -1 && is_ra_save_ins(&insn)) {
-			info->pc_offset =
-				ip->i_format.simmediate / sizeof(long);
+		if (info->pc_offset == -1 &&
+		    is_ra_save_ins(&insn, &info->pc_offset))
 			break;
-		}
 	}
 	if (info->frame_size && info->pc_offset >= 0) /* nested */
 		return 0;
Signature · 1 line
2.12.0
author
#12 lore raw

PATCH 12/60 MIPS: Handle microMIPS jumps in the same way as MIPS32/MIPS64 jumps

In reply to Jiri Slaby

From: Paul Burton <[email protected]>

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

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

commit 096a0de427ea333f56f0ee00328cff2a2731bcf1 upstream.

is_jump_ins() checks for plain jump ("j") instructions since commit e7438c4b893e ("MIPS: Fix sibling call handling in get_frame_info") but that commit didn't make the same change to the microMIPS code, leaving it inconsistent with the MIPS32/MIPS64 code. Handle the microMIPS encoding of the jump instruction too such that it behaves consistently.

Fixes e7438c4b893e ("MIPS: Fix sibling call handling in get_frame_info")
Cc Tony Wu <[email protected]>

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

---
 arch/mips/kernel/process.c | 2 ++
 1 file changed, 2 insertions(+)
arch/mips/kernel/process.c +2 -0
index a79bcd66778f..77e938d34f44 100644
@@ -315,6 +315,8 @@ static inline int is_jump_ins(union mips_instruction *ip)
 		return 0;
 	}
 
+	if (ip->j_format.opcode == mm_j32_op)
+		return 1;
 	if (ip->j_format.opcode == mm_jal32_op)
 		return 1;
 	if (ip->r_format.opcode != mm_pool32a_op ||
Signature · 1 line
2.12.0
author
#13 lore raw

PATCH 13/60 uvcvideo: Fix a wrong macro

In reply to Jiri Slaby

From: Guennadi Liakhovetski <[email protected]>

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

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

commit 17c341ec0115837a610b2da15e32546e26068234 upstream.

Don't mix up UVC_BUF_STATE_* and VB2_BUF_STATE_* codes.

Fixes 6998b6fb4b1c ("[media] uvcvideo: Use videobuf2-vmalloc")
---
 drivers/media/usb/uvc/uvc_queue.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/usb/uvc/uvc_queue.c +1 -1
index cd962be860ca..7e743958dbce 100644
@@ -375,7 +375,7 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
 		nextbuf = NULL;
 	spin_unlock_irqrestore(&queue->irqlock, flags);
 
-	buf->state = buf->error ? VB2_BUF_STATE_ERROR : UVC_BUF_STATE_DONE;
+	buf->state = buf->error ? UVC_BUF_STATE_ERROR : UVC_BUF_STATE_DONE;
 	vb2_set_plane_payload(&buf->buf, 0, buf->bytesused);
 	vb2_buffer_done(&buf->buf, VB2_BUF_STATE_DONE);
 
Signature · 1 line
2.12.0
author
#14 lore raw

PATCH 14/60 ALSA: hda - fix Lewisburg audio issue

In reply to Jiri Slaby

From: Jaroslav Kysela <[email protected]>

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

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

commit e7480b34ad1ab84a63540b2c884cb92c0764ab74 upstream.

Like for Sunrise Point, the total stream number of Lewisburg's input and output stream exceeds 15 (GCAP is 0x9701), which will cause some streams do not work because of the overflow on SDxCTL.STRM field if using the legacy stream tag allocation method.

Fixes 5cf92c8b3dc5 ("ALSA: hda - Add Intel Lewisburg device IDs Audio")
---
 sound/pci/hda/hda_intel.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
sound/pci/hda/hda_intel.c +2 -2
index 202150d7873c..9aefed5aa99b 100644
@@ -4118,9 +4118,9 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
 	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
 	/* Lewisburg */
 	{ PCI_DEVICE(0x8086, 0xa1f0),
-	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
+	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
 	{ PCI_DEVICE(0x8086, 0xa270),
-	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
+	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
 	/* Lynx Point-LP */
 	{ PCI_DEVICE(0x8086, 0x9c20),
 	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
Signature · 1 line
2.12.0
author
#15 lore raw

PATCH 15/60 ALSA: timer: Reject user params with too small ticks

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 71321eb3f2d0df4e6c327e0b936eec4458a12054 upstream.

When a user sets a too small ticks with a fine-grained timer like hrtimer, the kernel tries to fire up the timer irq too frequently. This may lead to the condensed locks, eventually the kernel spinlock lockup with warnings.

For avoiding such a situation, we define a lower limit of the resolution, namely 1ms. When the user passes a too small tick value that results in less than that, the kernel returns -EINVAL now.

---
 sound/core/timer.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)
sound/core/timer.c +15 -3
index e02c36b48630..6629c9ce155c 100644
@@ -1669,9 +1669,21 @@ static int snd_timer_user_params(struct file *file,
 		return -EBADFD;
 	if (copy_from_user(&params, _params, sizeof(params)))
 		return -EFAULT;
-	if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE) && params.ticks < 1) {
-		err = -EINVAL;
-		goto _end;
+	if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) {
+		u64 resolution;
+
+		if (params.ticks < 1) {
+			err = -EINVAL;
+			goto _end;
+		}
+
+		/* Don't allow resolution less than 1ms */
+		resolution = snd_timer_resolution(tu->timeri);
+		resolution *= params.ticks;
+		if (resolution < 1000000) {
+			err = -EINVAL;
+			goto _end;
+		}
 	}
 	if (params.queue_size > 0 &&
 	    (params.queue_size < 32 || params.queue_size > 1024)) {
Signature · 1 line
2.12.0
author
#16 lore raw

PATCH 16/60 ALSA: seq: Fix link corruption by event error handling

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

The sequencer FIFO management has a bug that may lead to a corruption (shortage) of the cell linked list. When a sequencer client faces an error at the event delivery, it tries to put back the dequeued cell. When the first queue was put back, this forgot the tail pointer tracking, and the link will be screwed up.

Although there is no memory corruption, the sequencer client may stall forever at exit while flushing the pending FIFO cells in snd_seq_pool_done(), as spotted by syzkaller.

This patch addresses the missing tail pointer tracking at snd_seq_fifo_cell_putback(). Also the patch makes sure to clear the cell->enxt pointer at snd_seq_fifo_event_in() for avoiding a similar mess-up of the FIFO linked list.

---
 sound/core/seq/seq_fifo.c | 3 +++
 1 file changed, 3 insertions(+)
sound/core/seq/seq_fifo.c +3 -0
index 0d75afa786bc..118481839d46 100644
@@ -137,6 +137,7 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f,
 	f->tail = cell;
 	if (f->head == NULL)
 		f->head = cell;
+	cell->next = NULL;
 	f->cells++;
 	spin_unlock_irqrestore(&f->lock, flags);
 
@@ -216,6 +217,8 @@ void snd_seq_fifo_cell_putback(struct snd_seq_fifo *f,
 		spin_lock_irqsave(&f->lock, flags);
 		cell->next = f->head;
 		f->head = cell;
+		if (!f->tail)
+			f->tail = cell;
 		f->cells++;
 		spin_unlock_irqrestore(&f->lock, flags);
 	}
Signature · 1 line
2.12.0
author
#17 lore raw

PATCH 17/60 staging: rtl: fix possible NULL pointer dereference

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

gcc-7 detects that wlanhdr_to_ethhdr() in two drivers calls memcpy() with a destination argument that an earlier function call may have set to NULL:

staging/rtl8188eu/core/rtw_recv.c: In function 'wlanhdr_to_ethhdr':
staging/rtl8188eu/core/rtw_recv.c:1318:2: warning: argument 1 null where non-null expected [-Wnonnull] staging/rtl8712/rtl871x_recv.c: In function 'r8712_wlanhdr_to_ethhdr':
staging/rtl8712/rtl871x_recv.c:649:2: warning: argument 1 null where non-null expected [-Wnonnull]

I'm fixing this by adding a NULL pointer check and returning failure from the function, which is hopefully already handled properly.

This seems to date back to when the drivers were originally added, so backporting the fix to stable seems appropriate. There are other related realtek drivers in the kernel, but none of them contain a function with a similar name or produce this warning.

Fixes 1cc18a22b96b ("staging: r8188eu: Add files for new driver - part 5")
Fixes 2865d42c78a9 ("staging: r8712u: Add the new driver to the mainline kernel")
---
 drivers/staging/rtl8188eu/core/rtw_recv.c | 3 +++
 drivers/staging/rtl8712/rtl871x_recv.c    | 7 ++++++-
 2 files changed, 9 insertions(+), 1 deletion(-)
drivers/staging/rtl8188eu/core/rtw_recv.c +3 -0
index 33243ed40a1e..36834165705d 100644
@@ -1502,6 +1502,9 @@ _func_enter_;
 		ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
 	}
 
+	if (!ptr)
+		return _FAIL;
+
 	memcpy(ptr, pattrib->dst, ETH_ALEN);
 	memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN);
 
drivers/staging/rtl8712/rtl871x_recv.c +6 -1
index 274c359279ef..820d3dd50de1 100644
@@ -641,11 +641,16 @@ sint r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe)
 		/* append rx status for mp test packets */
 		ptr = recvframe_pull(precvframe, (rmv_len -
 		      sizeof(struct ethhdr) + 2) - 24);
+		if (!ptr)
+			return _FAIL;
 		memcpy(ptr, get_rxmem(precvframe), 24);
 		ptr += 24;
-	} else
+	} else {
 		ptr = recvframe_pull(precvframe, (rmv_len -
 		      sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
+		if (!ptr)
+			return _FAIL;
+	}
 
 	memcpy(ptr, pattrib->dst, ETH_ALEN);
 	memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN);
Signature · 1 line
2.12.0
author
#18 lore raw

PATCH 18/60 mm: vmpressure: fix sending wrong events on underflow

In reply to Jiri Slaby

From: Vinayak Menon <[email protected]>

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

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

commit e1587a4945408faa58d0485002c110eb2454740c upstream.

At the end of a window period, if the reclaimed pages is greater than scanned, an unsigned underflow can result in a huge pressure value and thus a critical event. Reclaimed pages is found to go higher than scanned because of the addition of reclaimed slab pages to reclaimed in shrink_node without a corresponding increment to scanned pages.

Minchan Kim mentioned that this can also happen in the case of a THP page where the scanned is 1 and reclaimed could be 512.

---
 mm/vmpressure.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
mm/vmpressure.c +9 -1
index c98b14ee69d6..7ef7172d44f8 100644
@@ -111,9 +111,16 @@ static enum vmpressure_levels vmpressure_calc_level(unsigned long scanned,
 						    unsigned long reclaimed)
 {
 	unsigned long scale = scanned + reclaimed;
-	unsigned long pressure;
+	unsigned long pressure = 0;
 
 	/*
+	 * reclaimed can be greater than scanned in cases
+	 * like THP, where the scanned is 1 and reclaimed
+	 * could be 512
+	 */
+	if (reclaimed >= scanned)
+		goto out;
+	/*
 	 * We calculate the ratio (in percents) of how many pages were
 	 * scanned vs. reclaimed in a given time frame (window). Note that
 	 * time is in VM reclaimer's "ticks", i.e. number of pages
@@ -123,6 +130,7 @@ static enum vmpressure_levels vmpressure_calc_level(unsigned long scanned,
 	pressure = scale - (reclaimed * scale / scanned);
 	pressure = pressure * 100 / scale;
 
+out:
 	pr_debug("%s: %3lu  (s: %lu  r: %lu)\n", __func__, pressure,
 		 scanned, reclaimed);
 
Signature · 1 line
2.12.0
author
#19 lore raw

PATCH 19/60 ipc/shm: Fix shmat mmap nil-page protection

In reply to Jiri Slaby

From: Davidlohr Bueso <[email protected]>

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

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

commit 95e91b831f87ac8e1f8ed50c14d709089b4e01b8 upstream.

The issue is described here, with a nice testcase:

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

The problem is that shmat() calls do_mmap_pgoff() with MAP_FIXED, and the address rounded down to 0. For the regular mmap case, the protection mentioned above is that the kernel gets to generate the address -- arch_get_unmapped_area() will always check for MAP_FIXED and return that address. So by the time we do security_mmap_addr(0) things get funky for shmat().

The testcase itself shows that while a regular user crashes, root will not have a problem attaching a nil-page. There are two possible fixes to this. The first, and which this patch does, is to simply allow root to crash as well -- this is also regular mmap behavior, ie when hacking up the testcase and adding mmap(... |MAP_FIXED). While this approach is the safer option, the second alternative is to ignore SHM_RND if the rounded address is 0, thus only having MAP_SHARED flags. This makes the behavior of shmat() identical to the mmap() case. The downside of this is obviously user visible, but does make sense in that it maintains semantics after the round-down wrt 0 address and mmap.

Passes shm related ltp tests.

---
 ipc/shm.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)
ipc/shm.c +9 -4
index 4066519acc64..8fb9f99fe021 100644
@@ -1042,8 +1042,8 @@ out_unlock1:
  * "raddr" thing points to kernel space, and there has to be a wrapper around
  * this.
  */
-long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
-	      unsigned long shmlba)
+long do_shmat(int shmid, char __user *shmaddr, int shmflg,
+	      ulong *raddr, unsigned long shmlba)
 {
 	struct shmid_kernel *shp;
 	unsigned long addr;
@@ -1064,8 +1064,13 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
 		goto out;
 	else if ((addr = (ulong)shmaddr)) {
 		if (addr & (shmlba - 1)) {
-			if (shmflg & SHM_RND)
-				addr &= ~(shmlba - 1);	   /* round down */
+			/*
+			 * Round down to the nearest multiple of shmlba.
+			 * For sane do_mmap_pgoff() parameters, avoid
+			 * round downs that trigger nil-page and MAP_FIXED.
+			 */
+			if ((shmflg & SHM_RND) && addr >= shmlba)
+				addr &= ~(shmlba - 1);
 			else
 #ifndef __ARCH_FORCE_SHMLBA
 				if (addr & ~PAGE_MASK)
Signature · 1 line
2.12.0
author
#20 lore raw

PATCH 20/60 scsi: storvsc: use tagged SRB requests if supported by the device

In reply to Jiri Slaby

From: Long Li <[email protected]>

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

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

commit 3cd6d3d9b1abab8dcdf0800224ce26daac24eea2 upstream.

Properly set SRB flags when hosting device supports tagged queuing. This patch improves the performance on Fiber Channel disks.

---
 drivers/scsi/storvsc_drv.c | 9 +++++++++
 1 file changed, 9 insertions(+)
drivers/scsi/storvsc_drv.c +9 -0
index f9da66fa850b..c612a76dce49 100644
@@ -133,6 +133,8 @@ struct hv_fc_wwn_packet {
 #define SRB_FLAGS_PORT_DRIVER_RESERVED		0x0F000000
 #define SRB_FLAGS_CLASS_DRIVER_RESERVED		0xF0000000
 
+#define SP_UNTAGGED			((unsigned char) ~0)
+#define SRB_SIMPLE_TAG_REQUEST		0x20
 
 /*
  * Platform neutral description of a scsi request -
@@ -1612,6 +1614,13 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
 	vm_srb->win8_extension.srb_flags |=
 		SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
 
+	if (scmnd->device->tagged_supported) {
+		vm_srb->win8_extension.srb_flags |=
+		(SRB_FLAGS_QUEUE_ACTION_ENABLE | SRB_FLAGS_NO_QUEUE_FREEZE);
+		vm_srb->win8_extension.queue_tag = SP_UNTAGGED;
+		vm_srb->win8_extension.queue_action = SRB_SIMPLE_TAG_REQUEST;
+	}
+
 	/* Build the SRB */
 	switch (scmnd->sc_data_direction) {
 	case DMA_TO_DEVICE:
Signature · 1 line
2.12.0
author
#21 lore raw

PATCH 21/60 scsi: storvsc: properly handle SRB_ERROR when sense message is present

In reply to Jiri Slaby

From: Long Li <[email protected]>

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

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

commit bba5dc332ec2d3a685cb4dae668c793f6a3713a3 upstream.

When sense message is present on error, we should pass along to the upper layer to decide how to deal with the error.
This patch fixes connectivity issues with Fiber Channel devices.

---
 drivers/scsi/storvsc_drv.c | 7 +++++++
 1 file changed, 7 insertions(+)
drivers/scsi/storvsc_drv.c +7 -0
index c612a76dce49..d0d7b277a0c2 100644
@@ -1011,6 +1011,13 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
 	switch (vm_srb->srb_status) {
 	case SRB_STATUS_ERROR:
 		/*
+		 * Let upper layer deal with error when
+		 * sense message is present.
+		 */
+
+		if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID)
+			break;
+		/*
 		 * If there is an error; offline the device since all
 		 * error recovery strategies would have already been
 		 * deployed on the host side. However, if the command
Signature · 1 line
2.12.0
author
#22 lore raw

PATCH 22/60 scsi: storvsc: properly set residual data length on errors

In reply to Jiri Slaby

From: Long Li <[email protected]>

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

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

commit 40630f462824ee24bc00d692865c86c3828094e0 upstream.

On I/O errors, the Windows driver doesn't set data_transfer_length on error conditions other than SRB_STATUS_DATA_OVERRUN.
In these cases we need to set data_transfer_length to 0,
indicating there is no data transferred. On SRB_STATUS_DATA_OVERRUN, data_transfer_length is set by the Windows driver to the actual data transferred.

---
 drivers/scsi/storvsc_drv.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)
drivers/scsi/storvsc_drv.c +13 -3
index d0d7b277a0c2..808dc677ed93 100644
@@ -306,6 +306,7 @@ enum storvsc_request_type {
 #define SRB_STATUS_SUCCESS	0x01
 #define SRB_STATUS_ABORTED	0x02
 #define SRB_STATUS_ERROR	0x04
+#define SRB_STATUS_DATA_OVERRUN	0x12
 
 /*
  * This is the end of Protocol specific defines.
@@ -1082,6 +1083,7 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
 	struct scsi_sense_hdr sense_hdr;
 	struct vmscsi_request *vm_srb;
 	struct stor_mem_pools *memp = scmnd->device->hostdata;
+	u32 data_transfer_length;
 	struct Scsi_Host *host;
 	struct storvsc_device *stor_dev;
 	struct hv_device *dev = host_dev->dev;
@@ -1090,6 +1092,7 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
 	host = stor_dev->host;
 
 	vm_srb = &cmd_request->vstor_packet.vm_srb;
+	data_transfer_length = vm_srb->data_transfer_length;
 	if (cmd_request->bounce_sgl_count) {
 		if (vm_srb->data_in == READ_TYPE)
 			copy_from_bounce_buffer(scsi_sglist(scmnd),
@@ -1108,13 +1111,20 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
 			scsi_print_sense_hdr("storvsc", &sense_hdr);
 	}
 
-	if (vm_srb->srb_status != SRB_STATUS_SUCCESS)
+	if (vm_srb->srb_status != SRB_STATUS_SUCCESS) {
 		storvsc_handle_error(vm_srb, scmnd, host, sense_hdr.asc,
 					 sense_hdr.ascq);
+		/*
+		 * The Windows driver set data_transfer_length on
+		 * SRB_STATUS_DATA_OVERRUN. On other errors, this value
+		 * is untouched.  In these cases we set it to 0.
+		 */
+		if (vm_srb->srb_status != SRB_STATUS_DATA_OVERRUN)
+			data_transfer_length = 0;
+	}
 
 	scsi_set_resid(scmnd,
-		cmd_request->data_buffer.len -
-		vm_srb->data_transfer_length);
+		cmd_request->data_buffer.len - data_transfer_length);
 
 	scsi_done_fn = scmnd->scsi_done;
 
Signature · 1 line
2.12.0
author
#23 lore raw

PATCH 23/60 scsi: aacraid: Reorder Adapter status check

In reply to Jiri Slaby

From: Raghava Aditya Renukunta <[email protected]>

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

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

commit c421530bf848604e97d0785a03b3fe2c62775083 upstream.

The driver currently checks the SELF_TEST_FAILED first and then KERNEL_PANIC next. Under error conditions(boot code failure) both SELF_TEST_FAILED and KERNEL_PANIC can be set at the same time.

The driver has the capability to reset the controller on an KERNEL_PANIC, but not on SELF_TEST_FAILED.

Fixed by first checking KERNEL_PANIC and then the others.

Fixes e8b12f0fb835223752 ([SCSI] aacraid: Add new code for PMC-Sierra's SRC base controller family)
---
 drivers/scsi/aacraid/src.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)
drivers/scsi/aacraid/src.c +17 -4
index 7e17107643d4..05c999429ffe 100644
@@ -359,16 +359,23 @@ static int aac_src_check_health(struct aac_dev *dev)
 	u32 status = src_readl(dev, MUnit.OMR);
 
 	/*
+	 *	Check to see if the board panic'd.
+	 */
+	if (unlikely(status & KERNEL_PANIC))
+		goto err_blink;
+
+	/*
 	 *	Check to see if the board failed any self tests.
 	 */
 	if (unlikely(status & SELF_TEST_FAILED))
-		return -1;
+		goto err_out;
 
 	/*
-	 *	Check to see if the board panic'd.
+	 *	Check to see if the board failed any self tests.
 	 */
-	if (unlikely(status & KERNEL_PANIC))
-		return (status >> 16) & 0xFF;
+	if (unlikely(status & MONITOR_PANIC))
+		goto err_out;
+
 	/*
 	 *	Wait for the adapter to be up and running.
 	 */
@@ -378,6 +385,12 @@ static int aac_src_check_health(struct aac_dev *dev)
 	 *	Everything is OK
 	 */
 	return 0;
+
+err_out:
+	return -1;
+
+err_blink:
+	return (status > 16) & 0xFF;
 }
 
 /**
Signature · 1 line
2.12.0
author
#24 lore raw

PATCH 24/60 sd: get disk reference in sd_check_events()

In reply to Jiri Slaby

From: Hannes Reinecke <[email protected]>

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

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

commit eb72d0bb84eee5d0dc3044fd17b75e7101dabb57 upstream.

sd_check_events() is called asynchronously, and might race with device removal. So always take a disk reference when processing the event to avoid the device being removed while the event is processed.

---
 drivers/scsi/sd.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/scsi/sd.c +7 -2
index f1e3b5398887..bf7ff64ac7eb 100644
@@ -1365,11 +1365,15 @@ static int media_not_present(struct scsi_disk *sdkp,
  **/
 static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing)
 {
-	struct scsi_disk *sdkp = scsi_disk(disk);
-	struct scsi_device *sdp = sdkp->device;
+	struct scsi_disk *sdkp = scsi_disk_get(disk);
+	struct scsi_device *sdp;
 	struct scsi_sense_hdr *sshdr = NULL;
 	int retval;
 
+	if (!sdkp)
+		return 0;
+
+	sdp = sdkp->device;
 	SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_check_events\n"));
 
 	/*
@@ -1426,6 +1430,7 @@ out:
 	kfree(sshdr);
 	retval = sdp->changed ? DISK_EVENT_MEDIA_CHANGE : 0;
 	sdp->changed = 0;
+	scsi_disk_put(sdkp);
 	return retval;
 }
 
Signature · 1 line
2.12.0
author
#25 lore raw

PATCH 25/60 jbd2: don't leak modified metadata buffers on an aborted journal

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

If the journal has been aborted, we shouldn't mark the underlying buffer head as dirty, since that will cause the metadata block to get modified. And if the journal has been aborted, we shouldn't allow this since it will almost certainly lead to a corrupted file system.

---
 fs/jbd2/transaction.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
fs/jbd2/transaction.c +3 -1
index f18b5352df02..44e4f024ec53 100644
@@ -1785,7 +1785,9 @@ static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh)
 
 	__blist_del_buffer(list, jh);
 	jh->b_jlist = BJ_None;
-	if (test_clear_buffer_jbddirty(bh))
+	if (transaction && is_journal_aborted(transaction->t_journal))
+		clear_buffer_jbddirty(bh);
+	else if (test_clear_buffer_jbddirty(bh))
 		mark_buffer_dirty(bh);	/* Expose it to the VM */
 }
 
Signature · 1 line
2.12.0
author
#26 lore raw

PATCH 26/60 ext4: trim allocation requests to group size

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

If filesystem groups are artifically small (using parameter -g to mkfs.ext4), ext4_mb_normalize_request() can result in a request that is larger than a block group. Trim the request size to not confuse allocation code.

---
 fs/ext4/mballoc.c | 7 +++++++
 1 file changed, 7 insertions(+)
fs/ext4/mballoc.c +7 -0
index 2b4ed2bf9569..16a763af556c 100644
@@ -3084,6 +3084,13 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
 	if (ar->pright && start + size - 1 >= ar->lright)
 		size -= start + size - ar->lright;
 
+	/*
+	 * Trim allocation request for filesystems with artificially small
+	 * groups.
+	 */
+	if (size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb))
+		size = EXT4_BLOCKS_PER_GROUP(ac->ac_sb);
+
 	end = start + size;
 
 	/* check we don't cross already preallocated blocks */
Signature · 1 line
2.12.0
author
#27 lore raw

PATCH 27/60 ext4: preserve the needs_recovery flag when the journal is aborted

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 97abd7d4b5d9c48ec15c425485f054e1c15e591b upstream.

If the journal is aborted, the needs_recovery feature flag should not be removed. Otherwise, it's the journal might not get replayed and this could lead to more data getting lost.

---
 fs/ext4/super.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
fs/ext4/super.c +4 -2
index 7bc05f7bb2a7..01fc2b14db0e 100644
@@ -763,6 +763,7 @@ static void ext4_put_super(struct super_block *sb)
 {
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 	struct ext4_super_block *es = sbi->s_es;
+	int aborted = 0;
 	int i, err;
 
 	ext4_unregister_li_request(sb);
@@ -772,9 +773,10 @@ static void ext4_put_super(struct super_block *sb)
 	destroy_workqueue(sbi->rsv_conversion_wq);
 
 	if (sbi->s_journal) {
+		aborted = is_journal_aborted(sbi->s_journal);
 		err = jbd2_journal_destroy(sbi->s_journal);
 		sbi->s_journal = NULL;
-		if (err < 0)
+		if ((err < 0) && !aborted)
 			ext4_abort(sb, "Couldn't clean up the journal");
 	}
 
@@ -785,7 +787,7 @@ static void ext4_put_super(struct super_block *sb)
 	ext4_ext_release(sb);
 	ext4_xattr_put_super(sb);
 
-	if (!(sb->s_flags & MS_RDONLY)) {
+	if (!(sb->s_flags & MS_RDONLY) && !aborted) {
 		EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
 		es->s_state = cpu_to_le16(sbi->s_mount_state);
 	}
Signature · 1 line
2.12.0
author
#28 lore raw

PATCH 28/60 ext4: return EROFS if device is r/o and journal replay is needed

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 4753d8a24d4588657bc0a4cd66d4e282dff15c8c upstream.

If the file system requires journal recovery, and the device is read-ony, return EROFS to the mount system call. This allows xfstests generic/050 to pass.

---
 fs/ext4/super.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
fs/ext4/super.c +2 -1
index 01fc2b14db0e..3f19909f5431 100644
@@ -3977,7 +3977,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 	 */
 	if (!test_opt(sb, NOLOAD) &&
 	    EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) {
-		if (ext4_load_journal(sb, es, journal_devnum))
+		err = ext4_load_journal(sb, es, journal_devnum);
+		if (err)
 			goto failed_mount3;
 	} else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) &&
 	      EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) {
Signature · 1 line
2.12.0
author
#29 lore raw

PATCH 29/60 samples/seccomp: fix 64-bit comparison macros

In reply to Jiri Slaby

From: Mathias Svensson <[email protected]>

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

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

commit 916cafdc95843fb9af5fd5f83ca499d75473d107 upstream.

There were some bugs in the JNE64 and JLT64 comparision macros. This fixes them, improves comments, and cleans up the file while we are at it.

---
 samples/seccomp/bpf-helper.h | 125 +++++++++++++++++++++++++------------------
 1 file changed, 72 insertions(+), 53 deletions(-)
samples/seccomp/bpf-helper.h +72 -53
index 38ee70f3cd5b..1d8de9edd858 100644
@@ -138,7 +138,7 @@ union arg64 {
 #define ARG_32(idx) \
 	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, LO_ARG(idx))
 
-/* Loads hi into A and lo in X */
+/* Loads lo into M[0] and hi into M[1] and A */
 #define ARG_64(idx) \
 	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, LO_ARG(idx)), \
 	BPF_STMT(BPF_ST, 0), /* lo -> M[0] */ \
@@ -153,88 +153,107 @@ union arg64 {
 	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (value), 1, 0), \
 	jt
 
-/* Checks the lo, then swaps to check the hi. A=lo,X=hi */
+#define JA32(value, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (value), 0, 1), \
+	jt
+
+#define JGE32(value, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 0, 1), \
+	jt
+
+#define JGT32(value, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 0, 1), \
+	jt
+
+#define JLE32(value, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 1, 0), \
+	jt
+
+#define JLT32(value, jt) \
+	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 1, 0), \
+	jt
+
+/*
+ * All the JXX64 checks assume lo is saved in M[0] and hi is saved in both
+ * A and M[1]. This invariant is kept by restoring A if necessary.
+ */
 #define JEQ64(lo, hi, jt) \
+	/* if (hi != arg.hi) goto NOMATCH; */ \
 	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
 	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	/* if (lo != arg.lo) goto NOMATCH; */ \
 	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (lo), 0, 2), \
-	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), \
 	jt, \
-	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+	BPF_STMT(BPF_LD+BPF_MEM, 1)
 
 #define JNE64(lo, hi, jt) \
-	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 5, 0), \
-	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	/* if (hi != arg.hi) goto MATCH; */ \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 3), \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), \
+	/* if (lo != arg.lo) goto MATCH; */ \
 	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (lo), 2, 0), \
-	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), \
 	jt, \
-	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
-
-#define JA32(value, jt) \
-	BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (value), 0, 1), \
-	jt
+	BPF_STMT(BPF_LD+BPF_MEM, 1)
 
 #define JA64(lo, hi, jt) \
+	/* if (hi & arg.hi) goto MATCH; */ \
 	BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (hi), 3, 0), \
-	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), \
+	/* if (lo & arg.lo) goto MATCH; */ \
 	BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (lo), 0, 2), \
-	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), \
 	jt, \
-	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+	BPF_STMT(BPF_LD+BPF_MEM, 1)
 
-#define JGE32(value, jt) \
-	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 0, 1), \
-	jt
-
-#define JLT32(value, jt) \
-	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 1, 0), \
-	jt
-
-/* Shortcut checking if hi > arg.hi. */
 #define JGE64(lo, hi, jt) \
+	/* if (hi > arg.hi) goto MATCH; */ \
 	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 4, 0), \
+	/* if (hi != arg.hi) goto NOMATCH; */ \
 	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
-	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), \
+	/* if (lo >= arg.lo) goto MATCH; */ \
 	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (lo), 0, 2), \
-	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
-	jt, \
-	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
-
-#define JLT64(lo, hi, jt) \
-	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (hi), 0, 4), \
-	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
-	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
-	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 2, 0), \
-	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), \
 	jt, \
-	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+	BPF_STMT(BPF_LD+BPF_MEM, 1)
 
-#define JGT32(value, jt) \
-	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 0, 1), \
-	jt
-
-#define JLE32(value, jt) \
-	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 1, 0), \
-	jt
-
-/* Check hi > args.hi first, then do the GE checking */
 #define JGT64(lo, hi, jt) \
+	/* if (hi > arg.hi) goto MATCH; */ \
 	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 4, 0), \
+	/* if (hi != arg.hi) goto NOMATCH; */ \
 	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
-	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), \
+	/* if (lo > arg.lo) goto MATCH; */ \
 	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 0, 2), \
-	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), \
 	jt, \
-	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+	BPF_STMT(BPF_LD+BPF_MEM, 1)
 
 #define JLE64(lo, hi, jt) \
-	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 6, 0), \
-	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 3), \
-	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+	/* if (hi < arg.hi) goto MATCH; */ \
+	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (hi), 0, 4), \
+	/* if (hi != arg.hi) goto NOMATCH; */ \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), \
+	/* if (lo <= arg.lo) goto MATCH; */ \
 	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 2, 0), \
-	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), \
+	jt, \
+	BPF_STMT(BPF_LD+BPF_MEM, 1)
+
+#define JLT64(lo, hi, jt) \
+	/* if (hi < arg.hi) goto MATCH; */ \
+	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (hi), 0, 4), \
+	/* if (hi != arg.hi) goto NOMATCH; */ \
+	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+	BPF_STMT(BPF_LD+BPF_MEM, 0), \
+	/* if (lo < arg.lo) goto MATCH; */ \
+	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (lo), 2, 0), \
+	BPF_STMT(BPF_LD+BPF_MEM, 1), \
 	jt, \
-	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+	BPF_STMT(BPF_LD+BPF_MEM, 1)
 
 #define LOAD_SYSCALL_NR \
 	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
Signature · 1 line
2.12.0
author
#30 lore raw

PATCH 30/60 ath5k: drop bogus warning on drv_set_key with unsupported cipher

In reply to Jiri Slaby

From: Felix Fietkau <[email protected]>

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

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

commit a70e1d6fd6b5e1a81fa6171600942bee34f5128f upstream.

Simply return -EOPNOTSUPP instead.

---
 drivers/net/wireless/ath/ath5k/mac80211-ops.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/wireless/ath/ath5k/mac80211-ops.c +1 -2
index 4ee01f654235..9adbfb335387 100644
@@ -511,8 +511,7 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 			break;
 		return -EOPNOTSUPP;
 	default:
-		WARN_ON(1);
-		return -EINVAL;
+		return -EOPNOTSUPP;
 	}
 
 	mutex_lock(&ah->lock);
Signature · 1 line
2.12.0
author
#31 lore raw

PATCH 31/60 ath9k: use correct OTP register offsets for the AR9340 and AR9550

In reply to Jiri Slaby

From: Christian Lamparter <[email protected]>

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

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

commit c9f1e32600816d695f817477d56490bfc2ba43c6 upstream.

This patch fixes the OTP register definitions for the AR934x and AR9550 WMAC SoC.

Previously, the ath9k driver was unable to initialize the integrated WMAC on an Aerohive AP121:

| ath: phy0: timeout (1000 us) on reg 0x30018: 0xbadc0ffe & 0x00000007 != 0x00000004
| ath: phy0: timeout (1000 us) on reg 0x30018: 0xbadc0ffe & 0x00000007 != 0x00000004
| ath: phy0: Unable to initialize hardware; initialization status: -5
| ath9k ar934x_wmac: failed to initialize device
| ath9k: probe of ar934x_wmac failed with error -5

It turns out that the AR9300_OTP_STATUS and AR9300_OTP_DATA definitions contain a typo.

Cc Gabor Juhos <[email protected]>
Fixes add295a4afbdf5852d0 "ath9k: use correct OTP register offsets for AR9550"
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +2 -2
index 75d4fb41962f..c876a21aca2b 100644
@@ -71,13 +71,13 @@
 #define AR9300_OTP_BASE \
 		((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30000 : 0x14000)
 #define AR9300_OTP_STATUS \
-		((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30018 : 0x15f18)
+		((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x31018 : 0x15f18)
 #define AR9300_OTP_STATUS_TYPE		0x7
 #define AR9300_OTP_STATUS_VALID		0x4
 #define AR9300_OTP_STATUS_ACCESS_BUSY	0x2
 #define AR9300_OTP_STATUS_SM_BUSY	0x1
 #define AR9300_OTP_READ_DATA \
-		((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3001c : 0x15f1c)
+		((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3101c : 0x15f1c)
 
 enum targetPowerHTRates {
 	HT_TARGET_RATE_0_8_16,
Signature · 1 line
2.12.0
author
#32 lore raw

PATCH 32/60 fuse: add missing FR_FORCE

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 2e38bea99a80eab408adee27f873a188d57b76cb upstream.

fuse_file_put() was missing the "force" flag for the RELEASE request when sending synchronously (fuseblk).

If this flag is not set, then a sync request may be interrupted before it is dequeued by the userspace filesystem. In this case the OPEN won't be balanced with a RELEASE.

[js] force is a variable, not a bit

Fixes 5a18ec176c93 ("fuse: fix hang of single threaded fuseblk filesystem")
---
 fs/fuse/file.c | 1 +
 1 file changed, 1 insertion(+)
fs/fuse/file.c +1 -0
index f6314cd3e3b0..75dee32d41b5 100644
@@ -128,6 +128,7 @@ static void fuse_file_put(struct fuse_file *ff, bool sync)
 		struct fuse_req *req = ff->reserved_req;
 
 		if (sync) {
+			req->force = 1;
 			req->background = 0;
 			fuse_request_send(ff->fc, req);
 			path_put(&req->misc.release.path);
Signature · 1 line
2.12.0
author
#33 lore raw

PATCH 33/60 can: usb_8dev: Fix memory leak of priv->cmd_msg_buffer

In reply to Jiri Slaby

From: Marc Kleine-Budde <[email protected]>

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

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

commit 7c42631376306fb3f34d51fda546b50a9b6dd6ec upstream.

The priv->cmd_msg_buffer is allocated in the probe function, but never kfree()ed. This patch converts the kzalloc() to resource-managed kzalloc.

---
 drivers/net/can/usb/usb_8dev.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)
drivers/net/can/usb/usb_8dev.c +3 -6
index 8becd3d838b5..baa822523239 100644
@@ -957,8 +957,8 @@ static int usb_8dev_probe(struct usb_interface *intf,
 	for (i = 0; i < MAX_TX_URBS; i++)
 		priv->tx_contexts[i].echo_index = MAX_TX_URBS;
 
-	priv->cmd_msg_buffer = kzalloc(sizeof(struct usb_8dev_cmd_msg),
-				      GFP_KERNEL);
+	priv->cmd_msg_buffer = devm_kzalloc(&intf->dev, sizeof(struct usb_8dev_cmd_msg),
+					    GFP_KERNEL);
 	if (!priv->cmd_msg_buffer)
 		goto cleanup_candev;
 
@@ -972,7 +972,7 @@ static int usb_8dev_probe(struct usb_interface *intf,
 	if (err) {
 		netdev_err(netdev,
 			"couldn't register CAN device: %d\n", err);
-		goto cleanup_cmd_msg_buffer;
+		goto cleanup_candev;
 	}
 
 	err = usb_8dev_cmd_version(priv, &version);
@@ -993,9 +993,6 @@ static int usb_8dev_probe(struct usb_interface *intf,
 cleanup_unregister_candev:
 	unregister_netdev(priv->netdev);
 
-cleanup_cmd_msg_buffer:
-	kfree(priv->cmd_msg_buffer);
-
 cleanup_candev:
 	free_candev(netdev);
 
Signature · 1 line
2.12.0
author
#34 lore raw

PATCH 34/60 hv: allocate synic pages for all present CPUs

In reply to Jiri Slaby

From: Vitaly Kuznetsov <[email protected]>

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

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

commit 421b8f20d3c381b215f988b42428f56fc3b82405 upstream.

It may happen that not all CPUs are online when we do hv_synic_alloc() and in case more CPUs come online later we may try accessing these allocated structures.

---
 drivers/hv/hv.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/hv/hv.c +2 -2
index 88f4096fa078..3fdb9af08705 100644
@@ -271,7 +271,7 @@ int hv_synic_alloc(void)
 	size_t size = sizeof(struct tasklet_struct);
 	int cpu;
 
-	for_each_online_cpu(cpu) {
+	for_each_present_cpu(cpu) {
 		hv_context.event_dpc[cpu] = kmalloc(size, GFP_ATOMIC);
 		if (hv_context.event_dpc[cpu] == NULL) {
 			pr_err("Unable to allocate event dpc\n");
@@ -314,7 +314,7 @@ void hv_synic_free(void)
 {
 	int cpu;
 
-	for_each_online_cpu(cpu)
+	for_each_present_cpu(cpu)
 		hv_synic_free_cpu(cpu);
 }
 
Signature · 1 line
2.12.0
author
#35 lore raw

PATCH 35/60 RDMA/core: Fix incorrect structure packing for booleans

In reply to Jiri Slaby

From: Jason Gunthorpe <[email protected]>

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

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

commit 55efcfcd7776165b294f8b5cd6e05ca00ec89b7c upstream.

The RDMA core uses ib_pack() to convert from unpacked CPU structs to on-the-wire bitpacked structs.

This process requires that 1 bit fields are declared as u8 in the unpacked struct, otherwise the packing process does not read the value properly and the packed result is wired to 0. Several places wrongly used int.

Crucially this means the kernel has never, set reversible correctly in the path record request. It has always asked for irreversible paths even if the ULP requests otherwise.

When the kernel is used with a SM that supports this feature, it completely breaks communication management if reversible paths are not properly requested.

The only reason this ever worked is because opensm ignores the reversible bit.

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 include/rdma/ib_sa.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
include/rdma/ib_sa.h +3 -3
index 125f8714301d..7173cc4f2522 100644
@@ -137,12 +137,12 @@ struct ib_sa_path_rec {
 	union ib_gid sgid;
 	__be16       dlid;
 	__be16       slid;
-	int          raw_traffic;
+	u8           raw_traffic;
 	/* reserved */
 	__be32       flow_label;
 	u8           hop_limit;
 	u8           traffic_class;
-	int          reversible;
+	u8           reversible;
 	u8           numb_path;
 	__be16       pkey;
 	__be16       qos_class;
@@ -193,7 +193,7 @@ struct ib_sa_mcmember_rec {
 	u8           hop_limit;
 	u8           scope;
 	u8           join_state;
-	int          proxy_join;
+	u8           proxy_join;
 };
 
 /* Service Record Component Mask Sec 15.2.5.14 Ver 1.1	*/
Signature · 1 line
2.12.0
author
#36 lore raw

PATCH 36/60 rdma_cm: fail iwarp accepts w/o connection params

In reply to Jiri Slaby

From: Steve Wise <[email protected]>

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

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

commit f2625f7db4dd0bbd16a9c7d2950e7621f9aa57ad upstream.

cma_accept_iw() needs to return an error if conn_params is NULL. Since this is coming from user space, we can crash.

---
 drivers/infiniband/core/cma.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/infiniband/core/cma.c +3 -0
index 1429143301a7..ce6a1afcb410 100644
@@ -2914,6 +2914,9 @@ static int cma_accept_iw(struct rdma_id_private *id_priv,
 	struct iw_cm_conn_param iw_param;
 	int ret;
 
+	if (!conn_param)
+		return -EINVAL;
+
 	ret = cma_modify_qp_rtr(id_priv, conn_param);
 	if (ret)
 		return ret;
Signature · 1 line
2.12.0
author
#37 lore raw

PATCH 37/60 NFSv4: Fix memory and state leak in _nfs4_open_and_get_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 a974deee477af89411e0f80456bfb344ac433c98 upstream.

If we exit because the file access check failed, we currently leak the struct nfs4_state. We need to attach it to the open context before returning.

Fixes 3efb9722475e ("NFSv4: Refactor _nfs4_open_and_get_state..")
---
 fs/nfs/nfs4proc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/nfs4proc.c +1 -1
index a94ec130003b..907d363337eb 100644
@@ -2169,6 +2169,7 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
 	ret = PTR_ERR(state);
 	if (IS_ERR(state))
 		goto out;
+	ctx->state = state;
 	if (server->caps & NFS_CAP_POSIX_LOCK)
 		set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
 
@@ -2191,7 +2192,6 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
 	if (ret != 0)
 		goto out;
 
-	ctx->state = state;
 	if (dentry->d_inode == state->inode) {
 		nfs_inode_attach_open_context(ctx);
 		if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
Signature · 1 line
2.12.0
author
#38 lore raw

PATCH 38/60 NFSv4: fix getacl head length estimation

In reply to Jiri Slaby

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

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

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

commit 6682c14bbe505a8b912c57faf544f866777ee48d upstream.

Bitmap and attrlen follow immediately after the op reply header. This was an oversight from commit bf118a342f.

Consequences of this are just minor efficiency (extra calls to xdr_shrink_bufhead).

Fixes bf118a342f10 "NFSv4: include bitmap in nfsv4 get acl data"
---
 fs/nfs/nfs4xdr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/nfs4xdr.c +1 -1
index 1c2beb18a713..a31b34936d93 100644
@@ -2486,7 +2486,7 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr,
 	encode_compound_hdr(xdr, req, &hdr);
 	encode_sequence(xdr, &args->seq_args, &hdr);
 	encode_putfh(xdr, args->fh, &hdr);
-	replen = hdr.replen + op_decode_hdr_maxsz + 1;
+	replen = hdr.replen + op_decode_hdr_maxsz;
 	encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr);
 
 	xdr_inline_pages(&req->rq_rcv_buf, replen << 2,
Signature · 1 line
2.12.0
author
#39 lore raw

PATCH 39/60 NFSv4: fix getacl ERANGE for some ACL buffer sizes

In reply to Jiri Slaby

From: Weston Andros Adamson <[email protected]>

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

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

commit ed92d8c137b7794c2c2aa14479298b9885967607 upstream.

We're not taking into account that the space needed for the (variable length) attr bitmap, with the result that we'd sometimes get a spurious ERANGE when the ACL data got close to the end of a page.

Just add in an extra page to make sure.

---
 fs/nfs/nfs4proc.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
fs/nfs/nfs4proc.c +2 -6
index 907d363337eb..5ffa56fd634a 100644
@@ -4418,7 +4418,7 @@ out:
  */
 static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
 {
-	struct page *pages[NFS4ACL_MAXPAGES] = {NULL, };
+	struct page *pages[NFS4ACL_MAXPAGES + 1] = {NULL, };
 	struct nfs_getaclargs args = {
 		.fh = NFS_FH(inode),
 		.acl_pages = pages,
@@ -4432,13 +4432,9 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
 		.rpc_argp = &args,
 		.rpc_resp = &res,
 	};
-	unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE);
+	unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE) + 1;
 	int ret = -ENOMEM, i;
 
-	/* As long as we're doing a round trip to the server anyway,
-	 * let's be prepared for a page of acl data. */
-	if (npages == 0)
-		npages = 1;
 	if (npages > ARRAY_SIZE(pages))
 		return -ERANGE;
 
Signature · 1 line
2.12.0
author
#40 lore raw

PATCH 40/60 bcma: use (get|put)_device when probing/removing device driver

In reply to Jiri Slaby

From: Rafał Miłecki <[email protected]>

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

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

commit a971df0b9d04674e325346c17de9a895425ca5e1 upstream.

This allows tracking device state and e.g. makes devm work as expected.

---
 drivers/bcma/main.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/bcma/main.c +4 -0
index 90ee350442a9..04f4e89edce5 100644
@@ -451,8 +451,11 @@ static int bcma_device_probe(struct device *dev)
 					       drv);
 	int err = 0;
 
+	get_device(dev);
 	if (adrv->probe)
 		err = adrv->probe(core);
+	if (err)
+		put_device(dev);
 
 	return err;
 }
@@ -465,6 +468,7 @@ static int bcma_device_remove(struct device *dev)
 
 	if (adrv->remove)
 		adrv->remove(core);
+	put_device(dev);
 
 	return 0;
 }
Signature · 1 line
2.12.0
author
#41 lore raw

PATCH 41/60 powerpc/xmon: Fix data-breakpoint

In reply to Jiri Slaby

From: Ravi Bangoria <[email protected]>

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

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

commit c21a493a2b44650707d06741601894329486f2ad upstream.

Currently xmon data-breakpoint feature is broken.

Whenever there is a watchpoint match occurs, hw_breakpoint_handler will be called by do_break via notifier chains mechanism. If watchpoint is registered by xmon, hw_breakpoint_handler won't find any associated perf_event and returns immediately with NOTIFY_STOP. Similarly, do_break also returns without notifying to xmon.

Solve this by returning NOTIFY_DONE when hw_breakpoint_handler does not find any perf_event associated with matched watchpoint, rather than NOTIFY_STOP, which tells the core code to continue calling the other breakpoint handlers including the xmon one.

---
 arch/powerpc/kernel/hw_breakpoint.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
arch/powerpc/kernel/hw_breakpoint.c +3 -1
index f0b47d1a6b0e..7531f9abf10d 100644
@@ -228,8 +228,10 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
 	rcu_read_lock();
 
 	bp = __get_cpu_var(bp_per_reg);
-	if (!bp)
+	if (!bp) {
+		rc = NOTIFY_DONE;
 		goto out;
+	}
 	info = counter_arch_bp(bp);
 
 	/*
Signature · 1 line
2.12.0
author
#42 lore raw

PATCH 42/60 MIPS: IP22: Reformat inline assembler code to modern standards.

In reply to Jiri Slaby

From: Ralf Baechle <[email protected]>

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

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

commit f9f1c8db1c37253805eaa32265e1e1af3ae7d0a4 upstream.

---
 arch/mips/mm/sc-ip22.c | 43 +++++++++++++++++++++++--------------------
 1 file changed, 23 insertions(+), 20 deletions(-)
arch/mips/mm/sc-ip22.c +23 -20
index dc7c5a5214a9..203e4661bc81 100644
@@ -31,26 +31,29 @@ static inline void indy_sc_wipe(unsigned long first, unsigned long last)
 	unsigned long tmp;
 
 	__asm__ __volatile__(
-	".set\tpush\t\t\t# indy_sc_wipe\n\t"
-	".set\tnoreorder\n\t"
-	".set\tmips3\n\t"
-	".set\tnoat\n\t"
-	"mfc0\t%2, $12\n\t"
-	"li\t$1, 0x80\t\t\t# Go 64 bit\n\t"
-	"mtc0\t$1, $12\n\t"
-
-	"dli\t$1, 0x9000000080000000\n\t"
-	"or\t%0, $1\t\t\t# first line to flush\n\t"
-	"or\t%1, $1\t\t\t# last line to flush\n\t"
-	".set\tat\n\t"
-
-	"1:\tsw\t$0, 0(%0)\n\t"
-	"bne\t%0, %1, 1b\n\t"
-	" daddu\t%0, 32\n\t"
-
-	"mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t"
-	"nop; nop; nop; nop;\n\t"
-	".set\tpop"
+	"	.set	push			# indy_sc_wipe		\n"
+	"	.set	noreorder					\n"
+	"	.set	mips3						\n"
+	"	.set	noat						\n"
+	"	mfc0	%2, $12						\n"
+	"	li	$1, 0x80		# Go 64 bit		\n"
+	"	mtc0	$1, $12						\n"
+	"								\n"
+	"	dli	$1, 0x9000000080000000				\n"
+	"	or	%0, $1			# first line to flush	\n"
+	"	or	%1, $1			# last line to flush	\n"
+	"	.set	at						\n"
+	"								\n"
+	"1:	sw	$0, 0(%0)					\n"
+	"	bne	%0, %1, 1b					\n"
+	"	 daddu	%0, 32						\n"
+	"								\n"
+	"	mtc0	%2, $12			# Back to 32 bit	\n"
+	"	nop				# pipeline hazard	\n"
+	"	nop							\n"
+	"	nop							\n"
+	"	nop							\n"
+	"	.set	pop						\n"
 	: "=r" (first), "=r" (last), "=&r" (tmp)
 	: "0" (first), "1" (last));
 }
Signature · 1 line
2.12.0
author
#43 lore raw

PATCH 43/60 MIPS: IP22: Fix build error due to binutils 2.25 uselessnes.

In reply to Jiri Slaby

From: Ralf Baechle <[email protected]>

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

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

commit ae2f5e5ed04a17c1aa1f0a3714c725e12c21d2a9 upstream.

Fix the following build error with binutils 2.25.

CC arch/mips/mm/sc-ip22.o
{standard input}: Assembler messages:
{standard input}:132: Error: number (0x9000000080000000) larger than 32 bits {standard input}:159: Error: number (0x9000000080000000) larger than 32 bits {standard input}:200: Error: number (0x9000000080000000) larger than 32 bits scripts/Makefile.build:293: recipe for target 'arch/mips/mm/sc-ip22.o' failed make[1]: *** [arch/mips/mm/sc-ip22.o] Error 1

MIPS has used .set mips3 to temporarily switch the assembler to 64 bit mode in 64 bit kernels virtually forever. Binutils 2.25 broke this behavious partially by happily accepting 64 bit instructions in .set mips3 mode but puking on 64 bit constants when generating 32 bit ELF. Binutils 2.26 restored the old behaviour again.

Fix build with binutils 2.25 by open coding the offending

	dli $1, 0x9000000080000000

as

	li	$1, 0x9000
	dsll	$1, $1, 48

which is ugly be the only thing that will build on all binutils vintages.

---
 arch/mips/mm/sc-ip22.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
arch/mips/mm/sc-ip22.c +12 -1
index 203e4661bc81..efaf364fe581 100644
@@ -39,7 +39,18 @@ static inline void indy_sc_wipe(unsigned long first, unsigned long last)
 	"	li	$1, 0x80		# Go 64 bit		\n"
 	"	mtc0	$1, $12						\n"
 	"								\n"
-	"	dli	$1, 0x9000000080000000				\n"
+	"	#							\n"
+	"	# Open code a dli $1, 0x9000000080000000		\n"
+	"	#							\n"
+	"	# Required because binutils 2.25 will happily accept	\n"
+	"	# 64 bit instructions in .set mips3 mode but puke on	\n"
+	"	# 64 bit constants when generating 32 bit ELF		\n"
+	"	#							\n"
+	"	lui	$1,0x9000					\n"
+	"	dsll	$1,$1,0x10					\n"
+	"	ori	$1,$1,0x8000					\n"
+	"	dsll	$1,$1,0x10					\n"
+	"								\n"
 	"	or	%0, $1			# first line to flush	\n"
 	"	or	%1, $1			# last line to flush	\n"
 	"	.set	at						\n"
Signature · 1 line
2.12.0
author
#44 lore raw

PATCH 44/60 scsi: lpfc: Correct WQ creation for pagesize

In reply to Jiri Slaby

From: James Smart <[email protected]>

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

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

commit 8ea73db486cda442f0671f4bc9c03a76be398a28 upstream.

Correct WQ creation for pagesize

The driver was calculating the adapter command pagesize indicator from the system pagesize. However, the buffers the driver allocates are only one size (SLI4_PAGE_SIZE), so no calculation was necessary.

---
 drivers/scsi/lpfc/lpfc_hw4.h | 2 ++
 drivers/scsi/lpfc/lpfc_sli.c | 9 +++++----
 2 files changed, 7 insertions(+), 4 deletions(-)
drivers/scsi/lpfc/lpfc_hw4.h +2 -0
index 086c3f28caa6..55aa164fde78 100644
@@ -1180,6 +1180,7 @@ struct lpfc_mbx_wq_create {
 #define lpfc_mbx_wq_create_page_size_SHIFT	0
 #define lpfc_mbx_wq_create_page_size_MASK	0x000000FF
 #define lpfc_mbx_wq_create_page_size_WORD	word1
+#define LPFC_WQ_PAGE_SIZE_4096	0x1
 #define lpfc_mbx_wq_create_wqe_size_SHIFT	8
 #define lpfc_mbx_wq_create_wqe_size_MASK	0x0000000F
 #define lpfc_mbx_wq_create_wqe_size_WORD	word1
@@ -1251,6 +1252,7 @@ struct rq_context {
 #define lpfc_rq_context_page_size_SHIFT	0		/* Version 1 Only */
 #define lpfc_rq_context_page_size_MASK	0x000000FF
 #define lpfc_rq_context_page_size_WORD	word0
+#define	LPFC_RQ_PAGE_SIZE_4096	0x1
 	uint32_t reserved1;
 	uint32_t word2;
 #define lpfc_rq_context_cq_id_SHIFT	16
drivers/scsi/lpfc/lpfc_sli.c +5 -4
index 2d1ffd157c28..b4e77d21a701 100644
@@ -12916,7 +12916,7 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
 			       LPFC_WQ_WQE_SIZE_128);
 			bf_set(lpfc_mbx_wq_create_page_size,
 			       &wq_create->u.request_1,
-			       (PAGE_SIZE/SLI4_PAGE_SIZE));
+			       LPFC_WQ_PAGE_SIZE_4096);
 			page = wq_create->u.request_1.page;
 			break;
 		}
@@ -12942,8 +12942,9 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
 			       LPFC_WQ_WQE_SIZE_128);
 			break;
 		}
-		bf_set(lpfc_mbx_wq_create_page_size, &wq_create->u.request_1,
-		       (PAGE_SIZE/SLI4_PAGE_SIZE));
+		bf_set(lpfc_mbx_wq_create_page_size,
+		       &wq_create->u.request_1,
+		       LPFC_WQ_PAGE_SIZE_4096);
 		page = wq_create->u.request_1.page;
 		break;
 	default:
@@ -13129,7 +13130,7 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq,
 		       LPFC_RQE_SIZE_8);
 		bf_set(lpfc_rq_context_page_size,
 		       &rq_create->u.request.context,
-		       (PAGE_SIZE/SLI4_PAGE_SIZE));
+		       LPFC_RQ_PAGE_SIZE_4096);
 	} else {
 		switch (hrq->entry_count) {
 		default:
Signature · 1 line
2.12.0
author
#45 lore raw

PATCH 45/60 TTY: n_hdlc, fix lockdep false positive

In reply to Jiri Slaby

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

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

commit e9b736d88af1a143530565929390cadf036dc799 upstream.

The class of 4 n_hdls buf locks is the same because a single function n_hdlc_buf_list_init is used to init all the locks. But since
flush_tx_queue takes n_hdlc->tx_buf_list.spinlock and then calls
n_hdlc_buf_put which takes n_hdlc->tx_free_buf_list.spinlock, lockdep
emits a warning:
=============================================
[ INFO: possible recursive locking detected ]
4.3.0-25.g91e30a7-default #1 Not tainted
---------------------------------------------
a.out/1248 is trying to acquire lock:
(&(&list->spinlock)->rlock){......}, at: [<ffffffffa01fd020>] n_hdlc_buf_put+0x20/0x60 [n_hdlc]

but task is already holding lock:
(&(&list->spinlock)->rlock){......}, at: [<ffffffffa01fdc07>] n_hdlc_tty_ioctl+0x127/0x1d0 [n_hdlc]

other info that might help us debug this:

 Possible unsafe locking scenario:
       CPU0
       ----

lock(&(&list->spinlock)->rlock);
lock(&(&list->spinlock)->rlock);

*** DEADLOCK ***

May be due to missing lock nesting notation

2 locks held by a.out/1248:
#0: (&tty->ldisc_sem){++++++}, at: [<ffffffff814c9eb0>] tty_ldisc_ref_wait+0x20/0x50 #1: (&(&list->spinlock)->rlock){......}, at: [<ffffffffa01fdc07>] n_hdlc_tty_ioctl+0x127/0x1d0 [n_hdlc]
...

Call Trace:
...
 [<ffffffff81738fd0>] _raw_spin_lock_irqsave+0x50/0x70
 [<ffffffffa01fd020>] n_hdlc_buf_put+0x20/0x60 [n_hdlc]
 [<ffffffffa01fdc24>] n_hdlc_tty_ioctl+0x144/0x1d0 [n_hdlc]
 [<ffffffff814c25c1>] tty_ioctl+0x3f1/0xe40

...

Fix it by initializing the spin_locks separately. This removes also reduntand memset of a freshly kzallocated space.

---
 drivers/tty/n_hdlc.c | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)
drivers/tty/n_hdlc.c +4 -15
index 1b2db9a3038c..f26657c06870 100644
@@ -159,7 +159,6 @@ struct n_hdlc {
 /*
  * HDLC buffer list manipulation functions
  */
-static void n_hdlc_buf_list_init(struct n_hdlc_buf_list *list);
 static void n_hdlc_buf_put(struct n_hdlc_buf_list *list,
 			   struct n_hdlc_buf *buf);
 static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *list);
@@ -855,10 +854,10 @@ static struct n_hdlc *n_hdlc_alloc(void)
 
 	memset(n_hdlc, 0, sizeof(*n_hdlc));
 
-	n_hdlc_buf_list_init(&n_hdlc->rx_free_buf_list);
-	n_hdlc_buf_list_init(&n_hdlc->tx_free_buf_list);
-	n_hdlc_buf_list_init(&n_hdlc->rx_buf_list);
-	n_hdlc_buf_list_init(&n_hdlc->tx_buf_list);
+	spin_lock_init(&n_hdlc->rx_free_buf_list.spinlock);
+	spin_lock_init(&n_hdlc->tx_free_buf_list.spinlock);
+	spin_lock_init(&n_hdlc->rx_buf_list.spinlock);
+	spin_lock_init(&n_hdlc->tx_buf_list.spinlock);
 	
 	/* allocate free rx buffer list */
 	for(i=0;i<DEFAULT_RX_BUF_COUNT;i++) {
@@ -887,16 +886,6 @@ static struct n_hdlc *n_hdlc_alloc(void)
 }	/* end of n_hdlc_alloc() */
 
 /**
- * n_hdlc_buf_list_init - initialize specified HDLC buffer list
- * @list - pointer to buffer list
- */
-static void n_hdlc_buf_list_init(struct n_hdlc_buf_list *list)
-{
-	memset(list, 0, sizeof(*list));
-	spin_lock_init(&list->spinlock);
-}	/* end of n_hdlc_buf_list_init() */
-
-/**
  * n_hdlc_buf_put - add specified HDLC buffer to tail of specified list
  * @list - pointer to buffer list
  * @buf	- pointer to buffer
Signature · 1 line
2.12.0
author
#46 lore raw

PATCH 46/60 tty: n_hdlc: get rid of racy n_hdlc.tbuf

In reply to Jiri Slaby

From: Alexander Popov <[email protected]>

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

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

commit 82f2341c94d270421f383641b7cd670e474db56b upstream.

Currently N_HDLC line discipline uses a self-made singly linked list for data buffers and has n_hdlc.tbuf pointer for buffer retransmitting after an error.

The commit be10eb7589337e5defbe214dae038a53dd21add8
("tty: n_hdlc add buffer flushing") introduced racy access to n_hdlc.tbuf. After tx error concurrent flush_tx_queue() and n_hdlc_send_frames() can put one data buffer to tx_free_buf_list twice. That causes double free in n_hdlc_release().

Let's use standard kernel linked list and get rid of n_hdlc.tbuf:
in case of tx error put current data buffer after the head of tx_buf_list.

---
 drivers/tty/n_hdlc.c | 132 +++++++++++++++++++++++++++------------------------
 1 file changed, 69 insertions(+), 63 deletions(-)
drivers/tty/n_hdlc.c +69 -63
index f26657c06870..66fb07684133 100644
@@ -114,7 +114,7 @@
 #define DEFAULT_TX_BUF_COUNT 3
 
 struct n_hdlc_buf {
-	struct n_hdlc_buf *link;
+	struct list_head  list_item;
 	int		  count;
 	char		  buf[1];
 };
@@ -122,8 +122,7 @@ struct n_hdlc_buf {
 #define	N_HDLC_BUF_SIZE	(sizeof(struct n_hdlc_buf) + maxframe)
 
 struct n_hdlc_buf_list {
-	struct n_hdlc_buf *head;
-	struct n_hdlc_buf *tail;
+	struct list_head  list;
 	int		  count;
 	spinlock_t	  spinlock;
 };
@@ -136,7 +135,6 @@ struct n_hdlc_buf_list {
  * @backup_tty - TTY to use if tty gets closed
  * @tbusy - reentrancy flag for tx wakeup code
  * @woke_up - FIXME: describe this field
- * @tbuf - currently transmitting tx buffer
  * @tx_buf_list - list of pending transmit frame buffers
  * @rx_buf_list - list of received frame buffers
  * @tx_free_buf_list - list unused transmit frame buffers
@@ -149,7 +147,6 @@ struct n_hdlc {
 	struct tty_struct	*backup_tty;
 	int			tbusy;
 	int			woke_up;
-	struct n_hdlc_buf	*tbuf;
 	struct n_hdlc_buf_list	tx_buf_list;
 	struct n_hdlc_buf_list	rx_buf_list;
 	struct n_hdlc_buf_list	tx_free_buf_list;
@@ -159,6 +156,8 @@ struct n_hdlc {
 /*
  * HDLC buffer list manipulation functions
  */
+static void n_hdlc_buf_return(struct n_hdlc_buf_list *buf_list,
+						struct n_hdlc_buf *buf);
 static void n_hdlc_buf_put(struct n_hdlc_buf_list *list,
 			   struct n_hdlc_buf *buf);
 static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *list);
@@ -208,16 +207,9 @@ static void flush_tx_queue(struct tty_struct *tty)
 {
 	struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
 	struct n_hdlc_buf *buf;
-	unsigned long flags;
 
 	while ((buf = n_hdlc_buf_get(&n_hdlc->tx_buf_list)))
 		n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, buf);
- 	spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags);
-	if (n_hdlc->tbuf) {
-		n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, n_hdlc->tbuf);
-		n_hdlc->tbuf = NULL;
-	}
-	spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags);
 }
 
 static struct tty_ldisc_ops n_hdlc_ldisc = {
@@ -283,7 +275,6 @@ static void n_hdlc_release(struct n_hdlc *n_hdlc)
 		} else
 			break;
 	}
-	kfree(n_hdlc->tbuf);
 	kfree(n_hdlc);
 	
 }	/* end of n_hdlc_release() */
@@ -402,13 +393,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
 	n_hdlc->woke_up = 0;
 	spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags);
 
-	/* get current transmit buffer or get new transmit */
-	/* buffer from list of pending transmit buffers */
-		
-	tbuf = n_hdlc->tbuf;
-	if (!tbuf)
-		tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
-		
+	tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
 	while (tbuf) {
 		if (debuglevel >= DEBUG_LEVEL_INFO)	
 			printk("%s(%d)sending frame %p, count=%d\n",
@@ -420,7 +405,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
 
 		/* rollback was possible and has been done */
 		if (actual == -ERESTARTSYS) {
-			n_hdlc->tbuf = tbuf;
+			n_hdlc_buf_return(&n_hdlc->tx_buf_list, tbuf);
 			break;
 		}
 		/* if transmit error, throw frame away by */
@@ -435,10 +420,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
 					
 			/* free current transmit buffer */
 			n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, tbuf);
-			
-			/* this tx buffer is done */
-			n_hdlc->tbuf = NULL;
-			
+
 			/* wait up sleeping writers */
 			wake_up_interruptible(&tty->write_wait);
 	
@@ -448,10 +430,12 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
 			if (debuglevel >= DEBUG_LEVEL_INFO)	
 				printk("%s(%d)frame %p pending\n",
 					__FILE__,__LINE__,tbuf);
-					
-			/* buffer not accepted by driver */
-			/* set this buffer as pending buffer */
-			n_hdlc->tbuf = tbuf;
+
+			/*
+			 * the buffer was not accepted by driver,
+			 * return it back into tx queue
+			 */
+			n_hdlc_buf_return(&n_hdlc->tx_buf_list, tbuf);
 			break;
 		}
 	}
@@ -749,7 +733,8 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
 	int error = 0;
 	int count;
 	unsigned long flags;
-	
+	struct n_hdlc_buf *buf = NULL;
+
 	if (debuglevel >= DEBUG_LEVEL_INFO)	
 		printk("%s(%d)n_hdlc_tty_ioctl() called %d\n",
 			__FILE__,__LINE__,cmd);
@@ -763,8 +748,10 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
 		/* report count of read data available */
 		/* in next available frame (if any) */
 		spin_lock_irqsave(&n_hdlc->rx_buf_list.spinlock,flags);
-		if (n_hdlc->rx_buf_list.head)
-			count = n_hdlc->rx_buf_list.head->count;
+		buf = list_first_entry_or_null(&n_hdlc->rx_buf_list.list,
+						struct n_hdlc_buf, list_item);
+		if (buf)
+			count = buf->count;
 		else
 			count = 0;
 		spin_unlock_irqrestore(&n_hdlc->rx_buf_list.spinlock,flags);
@@ -776,8 +763,10 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
 		count = tty_chars_in_buffer(tty);
 		/* add size of next output frame in queue */
 		spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags);
-		if (n_hdlc->tx_buf_list.head)
-			count += n_hdlc->tx_buf_list.head->count;
+		buf = list_first_entry_or_null(&n_hdlc->tx_buf_list.list,
+						struct n_hdlc_buf, list_item);
+		if (buf)
+			count += buf->count;
 		spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock,flags);
 		error = put_user(count, (int __user *)arg);
 		break;
@@ -825,14 +814,14 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
 		poll_wait(filp, &tty->write_wait, wait);
 
 		/* set bits for operations that won't block */
-		if (n_hdlc->rx_buf_list.head)
+		if (!list_empty(&n_hdlc->rx_buf_list.list))
 			mask |= POLLIN | POLLRDNORM;	/* readable */
 		if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
 			mask |= POLLHUP;
 		if (tty_hung_up_p(filp))
 			mask |= POLLHUP;
 		if (!tty_is_writelocked(tty) &&
-				n_hdlc->tx_free_buf_list.head)
+				!list_empty(&n_hdlc->tx_free_buf_list.list))
 			mask |= POLLOUT | POLLWRNORM;	/* writable */
 	}
 	return mask;
@@ -858,7 +847,12 @@ static struct n_hdlc *n_hdlc_alloc(void)
 	spin_lock_init(&n_hdlc->tx_free_buf_list.spinlock);
 	spin_lock_init(&n_hdlc->rx_buf_list.spinlock);
 	spin_lock_init(&n_hdlc->tx_buf_list.spinlock);
-	
+
+	INIT_LIST_HEAD(&n_hdlc->rx_free_buf_list.list);
+	INIT_LIST_HEAD(&n_hdlc->tx_free_buf_list.list);
+	INIT_LIST_HEAD(&n_hdlc->rx_buf_list.list);
+	INIT_LIST_HEAD(&n_hdlc->tx_buf_list.list);
+
 	/* allocate free rx buffer list */
 	for(i=0;i<DEFAULT_RX_BUF_COUNT;i++) {
 		buf = kmalloc(N_HDLC_BUF_SIZE, GFP_KERNEL);
@@ -886,53 +880,65 @@ static struct n_hdlc *n_hdlc_alloc(void)
 }	/* end of n_hdlc_alloc() */
 
 /**
+ * n_hdlc_buf_return - put the HDLC buffer after the head of the specified list
+ * @buf_list - pointer to the buffer list
+ * @buf - pointer to the buffer
+ */
+static void n_hdlc_buf_return(struct n_hdlc_buf_list *buf_list,
+						struct n_hdlc_buf *buf)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&buf_list->spinlock, flags);
+
+	list_add(&buf->list_item, &buf_list->list);
+	buf_list->count++;
+
+	spin_unlock_irqrestore(&buf_list->spinlock, flags);
+}
+
+/**
  * n_hdlc_buf_put - add specified HDLC buffer to tail of specified list
- * @list - pointer to buffer list
+ * @buf_list - pointer to buffer list
  * @buf	- pointer to buffer
  */
-static void n_hdlc_buf_put(struct n_hdlc_buf_list *list,
+static void n_hdlc_buf_put(struct n_hdlc_buf_list *buf_list,
 			   struct n_hdlc_buf *buf)
 {
 	unsigned long flags;
-	spin_lock_irqsave(&list->spinlock,flags);
-	
-	buf->link=NULL;
-	if (list->tail)
-		list->tail->link = buf;
-	else
-		list->head = buf;
-	list->tail = buf;
-	(list->count)++;
-	
-	spin_unlock_irqrestore(&list->spinlock,flags);
-	
+
+	spin_lock_irqsave(&buf_list->spinlock, flags);
+
+	list_add_tail(&buf->list_item, &buf_list->list);
+	buf_list->count++;
+
+	spin_unlock_irqrestore(&buf_list->spinlock, flags);
 }	/* end of n_hdlc_buf_put() */
 
 /**
  * n_hdlc_buf_get - remove and return an HDLC buffer from list
- * @list - pointer to HDLC buffer list
+ * @buf_list - pointer to HDLC buffer list
  * 
  * Remove and return an HDLC buffer from the head of the specified HDLC buffer
  * list.
  * Returns a pointer to HDLC buffer if available, otherwise %NULL.
  */
-static struct n_hdlc_buf* n_hdlc_buf_get(struct n_hdlc_buf_list *list)
+static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *buf_list)
 {
 	unsigned long flags;
 	struct n_hdlc_buf *buf;
-	spin_lock_irqsave(&list->spinlock,flags);
-	
-	buf = list->head;
+
+	spin_lock_irqsave(&buf_list->spinlock, flags);
+
+	buf = list_first_entry_or_null(&buf_list->list,
+						struct n_hdlc_buf, list_item);
 	if (buf) {
-		list->head = buf->link;
-		(list->count)--;
+		list_del(&buf->list_item);
+		buf_list->count--;
 	}
-	if (!list->head)
-		list->tail = NULL;
-	
-	spin_unlock_irqrestore(&list->spinlock,flags);
+
+	spin_unlock_irqrestore(&buf_list->spinlock, flags);
 	return buf;
-	
 }	/* end of n_hdlc_buf_get() */
 
 static char hdlc_banner[] __initdata =
Signature · 1 line
2.12.0
author
#47 lore raw

PATCH 47/60 serial: 8250_pci: Add MKS Tenta SCOM-0800 and SCOM-0801 cards

In reply to Jiri Slaby

From: Ian Abbott <[email protected]>

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

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

commit 1c9c858e2ff8ae8024a3d75d2ed080063af43754 upstream.

The MKS Instruments SCOM-0800 and SCOM-0801 cards (originally by Tenta Technologies) are 3U CompactPCI serial cards with 4 and 8 serial ports, respectively. The first 4 ports are implemented by an OX16PCI954 chip, and the second 4 ports are implemented by an OX16C954 chip on a local bus, bridged by the second PCI function of the OX16PCI954. The ports are jumper-selectable as RS-232 and RS-422/485, and the UARTs use a non-standard oscillator frequency of 20 MHz (base_baud = 1250000).

---
 drivers/tty/serial/8250/8250_pci.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)
drivers/tty/serial/8250/8250_pci.c +13 -0
index e93eaea14ccc..2e8f75bc54b9 100644
@@ -2388,6 +2388,8 @@ enum pci_board_num_t {
 	pbn_b0_4_1152000_200,
 	pbn_b0_8_1152000_200,
 
+	pbn_b0_4_1250000,
+
 	pbn_b0_2_1843200,
 	pbn_b0_4_1843200,
 
@@ -2610,6 +2612,13 @@ static struct pciserial_board pci_boards[] = {
 		.uart_offset	= 0x200,
 	},
 
+	[pbn_b0_4_1250000] = {
+		.flags		= FL_BASE0,
+		.num_ports	= 4,
+		.base_baud	= 1250000,
+		.uart_offset	= 8,
+	},
+
 	[pbn_b0_2_1843200] = {
 		.flags		= FL_BASE0,
 		.num_ports	= 2,
@@ -5017,6 +5026,10 @@ static struct pci_device_id serial_pci_tbl[] = {
 		0,
 		0, pbn_exar_XR17V358 },
 
+	/* MKS Tenta SCOM-080x serial cards */
+	{ PCI_DEVICE(0x1601, 0x0800), .driver_data = pbn_b0_4_1250000 },
+	{ PCI_DEVICE(0x1601, 0xa801), .driver_data = pbn_b0_4_1250000 },
+
 	/*
 	 * These entries match devices with class COMMUNICATION_SERIAL,
 	 * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL
Signature · 1 line
2.12.0
author
#48 lore raw

PATCH 48/60 KVM: VMX: use correct vmcs_read/write for guest segment selector/base

In reply to Jiri Slaby

From: Chao Peng <[email protected]>

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

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

commit 96794e4ed4d758272c486e1529e431efb7045265 upstream.

Guest segment selector is 16 bit field and guest segment base is natural width field. Fix two incorrect invocations accordingly.

Without this patch, build fails when aggressive inlining is used with ICC.

[js] no vmx_dump_sel in 3.12

---
 arch/x86/kvm/vmx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/vmx.c +1 -1
index c7f2b3c52d92..d9e567fc36c7 100644
@@ -3123,7 +3123,7 @@ static void fix_rmode_seg(int seg, struct kvm_segment *save)
 	}
 
 	vmcs_write16(sf->selector, var.selector);
-	vmcs_write32(sf->base, var.base);
+	vmcs_writel(sf->base, var.base);
 	vmcs_write32(sf->limit, var.limit);
 	vmcs_write32(sf->ar_bytes, vmx_segment_access_rights(&var));
 }
Signature · 1 line
2.12.0
author
#49 lore raw

PATCH 49/60 Bluetooth: Add another AR3012 04ca:3018 device

In reply to Jiri Slaby

From: Dmitry Tunin <[email protected]>

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

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

commit 441ad62d6c3f131f1dbd7dcdd9cbe3f74dbd8501 upstream.

T:  Bus=01 Lev=01 Prnt=01 Port=07 Cnt=04 Dev#=  5 Spd=12  MxCh= 0
D:  Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=04ca ProdID=3018 Rev=00.01
C:  #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I:  If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
I:  If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
---
 drivers/bluetooth/ath3k.c | 2 ++
 drivers/bluetooth/btusb.c | 1 +
 2 files changed, 3 insertions(+)
drivers/bluetooth/ath3k.c +2 -0
index 78e7f1a003be..295831e65509 100644
@@ -94,6 +94,7 @@ static struct usb_device_id ath3k_table[] = {
 	{ USB_DEVICE(0x04CA, 0x300f) },
 	{ USB_DEVICE(0x04CA, 0x3010) },
 	{ USB_DEVICE(0x04CA, 0x3014) },
+	{ USB_DEVICE(0x04CA, 0x3018) },
 	{ USB_DEVICE(0x0930, 0x0219) },
 	{ USB_DEVICE(0x0930, 0x021c) },
 	{ USB_DEVICE(0x0930, 0x0220) },
@@ -159,6 +160,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {
 	{ USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3018), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
drivers/bluetooth/btusb.c +1 -0
index a38d7d21f8a1..f3a37e3577a9 100644
@@ -171,6 +171,7 @@ static struct usb_device_id blacklist_table[] = {
 	{ USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3018), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
Signature · 1 line
2.12.0
author
#50 lore raw

PATCH 50/60 s390/qdio: clear DSCI prior to scanning multiple input queues

In reply to Jiri Slaby

From: Julian Wiedmann <[email protected]>

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

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

commit 1e4a382fdc0ba8d1a85b758c0811de3a3631085e upstream.

For devices with multiple input queues, tiqdio_call_inq_handlers() iterates over all input queues and clears the device's DSCI during each iteration. If the DSCI is re-armed during one of the later iterations, we therefore do not scan the previous queues again.
The re-arming also raises a new adapter interrupt. But its handler does not trigger a rescan for the device, as the DSCI has already been erroneously cleared.
This can result in queue stalls on devices with multiple input queues.

Fix it by clearing the DSCI just once, prior to scanning the queues.

As the code is moved in front of the loop, we also need to access the DSCI directly (ie irq->dsci) instead of going via each queue's parent pointer to the same irq. This is not a functional change, and a follow-up patch will clean up the other users.

In practice, this bug only affects CQ-enabled HiperSockets devices, ie. devices with sysfs-attribute "hsuid" set. Setting a hsuid is needed for AF_IUCV socket applications that use HiperSockets communication.

Fixes 104ea556ee7f ("qdio: support asynchronous delivery of storage blocks")
---
 drivers/s390/cio/qdio_thinint.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/s390/cio/qdio_thinint.c +4 -4
index 5d06253c2a7a..30e9fbbff051 100644
@@ -147,11 +147,11 @@ static inline void tiqdio_call_inq_handlers(struct qdio_irq *irq)
 	struct qdio_q *q;
 	int i;
 
-	for_each_input_queue(irq, q, i) {
-		if (!references_shared_dsci(irq) &&
-		    has_multiple_inq_on_dsci(irq))
-			xchg(q->irq_ptr->dsci, 0);
+	if (!references_shared_dsci(irq) &&
+	    has_multiple_inq_on_dsci(irq))
+		xchg(irq->dsci, 0);
 
+	for_each_input_queue(irq, q, i) {
 		if (q->u.in.queue_start_poll) {
 			/* skip if polling is enabled or already in work */
 			if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
Signature · 1 line
2.12.0
author
#51 lore raw

PATCH 51/60 s390: TASK_SIZE for kernel threads

In reply to Jiri Slaby

From: Martin Schwidefsky <[email protected]>

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

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

commit fb94a687d96c570d46332a4a890f1dcb7310e643 upstream.

Return a sensible value if TASK_SIZE if called from a kernel thread.

This gets us around an issue with copy_mount_options that does a magic size calculation "TASK_SIZE - (unsigned long)data" while in a kernel thread and data pointing to kernel space.

---
 arch/s390/include/asm/processor.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/s390/include/asm/processor.h +2 -1
index ca7821f07260..a42a05322d25 100644
@@ -48,7 +48,8 @@ extern void execve_tail(void);
 
 #else /* CONFIG_64BIT */
 
-#define TASK_SIZE_OF(tsk)	((tsk)->mm->context.asce_limit)
+#define TASK_SIZE_OF(tsk)	((tsk)->mm ? \
+				 (tsk)->mm->context.asce_limit : TASK_MAX_SIZE)
 #define TASK_UNMAPPED_BASE	(test_thread_flag(TIF_31BIT) ? \
 					(1UL << 30) : (1UL << 41))
 #define TASK_SIZE		TASK_SIZE_OF(current)
Signature · 1 line
2.12.0
author
#52 lore raw

PATCH 52/60 IB/ipoib: Fix deadlock between rmmod and set_mode

In reply to Jiri Slaby

From: Feras Daoud <[email protected]>

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

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

commit 0a0007f28304cb9fc87809c86abb80ec71317f20 upstream.

When calling set_mode from sys/fs, the call flow locks the sys/fs lock first and then tries to lock rtnl_lock (when calling ipoib_set_mod). On the other hand, the rmmod call flow takes the rtnl_lock first (when calling unregister_netdev) and then tries to take the sys/fs lock. Deadlock a->b, b->a.

The problem starts when ipoib_set_mod frees it's rtnl_lck and tries to get it after that.

    set_mod:
    [<ffffffff8104f2bd>] ? check_preempt_curr+0x6d/0x90
    [<ffffffff814fee8e>] __mutex_lock_slowpath+0x13e/0x180
    [<ffffffff81448655>] ? __rtnl_unlock+0x15/0x20
    [<ffffffff814fed2b>] mutex_lock+0x2b/0x50
    [<ffffffff81448675>] rtnl_lock+0x15/0x20
    [<ffffffffa02ad807>] ipoib_set_mode+0x97/0x160 [ib_ipoib]
    [<ffffffffa02b5f5b>] set_mode+0x3b/0x80 [ib_ipoib]
    [<ffffffff8134b840>] dev_attr_store+0x20/0x30
    [<ffffffff811f0fe5>] sysfs_write_file+0xe5/0x170
    [<ffffffff8117b068>] vfs_write+0xb8/0x1a0
    [<ffffffff8117ba81>] sys_write+0x51/0x90
    [<ffffffff8100b0f2>] system_call_fastpath+0x16/0x1b

    rmmod:
    [<ffffffff81279ffc>] ? put_dec+0x10c/0x110
    [<ffffffff8127a2ee>] ? number+0x2ee/0x320
    [<ffffffff814fe6a5>] schedule_timeout+0x215/0x2e0
    [<ffffffff8127cc04>] ? vsnprintf+0x484/0x5f0
    [<ffffffff8127b550>] ? string+0x40/0x100
    [<ffffffff814fe323>] wait_for_common+0x123/0x180
    [<ffffffff81060250>] ? default_wake_function+0x0/0x20
    [<ffffffff8119661e>] ? ifind_fast+0x5e/0xb0
    [<ffffffff814fe43d>] wait_for_completion+0x1d/0x20
    [<ffffffff811f2e68>] sysfs_addrm_finish+0x228/0x270
    [<ffffffff811f2fb3>] sysfs_remove_dir+0xa3/0xf0
    [<ffffffff81273f66>] kobject_del+0x16/0x40
    [<ffffffff8134cd14>] device_del+0x184/0x1e0
    [<ffffffff8144e59b>] netdev_unregister_kobject+0xab/0xc0
    [<ffffffff8143c05e>] rollback_registered+0xae/0x130
    [<ffffffff8143c102>] unregister_netdevice+0x22/0x70
    [<ffffffff8143c16e>] unregister_netdev+0x1e/0x30
    [<ffffffffa02a91b0>] ipoib_remove_one+0xe0/0x120 [ib_ipoib]
    [<ffffffffa01ed95f>] ib_unregister_device+0x4f/0x100 [ib_core]
    [<ffffffffa021f5e1>] mlx4_ib_remove+0x41/0x180 [mlx4_ib]
    [<ffffffffa01ab771>] mlx4_remove_device+0x71/0x90 [mlx4_core]
Fixes 862096a8bbf8 ("IB/ipoib: Add more rtnl_link_ops callbacks")
Cc Or Gerlitz <[email protected]>
---
 drivers/infiniband/ulp/ipoib/ipoib_cm.c   | 12 +++++++-----
 drivers/infiniband/ulp/ipoib/ipoib_main.c |  6 ++----
 2 files changed, 9 insertions(+), 9 deletions(-)
drivers/infiniband/ulp/ipoib/ipoib_cm.c +7 -5
index 9474cb021c41..9bb33b76df7f 100644
@@ -1479,12 +1479,14 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
 
 	ret = ipoib_set_mode(dev, buf);
 
-	rtnl_unlock();
-
-	if (!ret)
-		return count;
+	/* The assumption is that the function ipoib_set_mode returned
+	 * with the rtnl held by it, if not the value -EBUSY returned,
+	 * then no need to rtnl_unlock
+	 */
+	if (ret != -EBUSY)
+		rtnl_unlock();
 
-	return ret;
+	return (!ret || ret == -EBUSY) ? count : ret;
 }
 
 static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, show_mode, set_mode);
drivers/infiniband/ulp/ipoib/ipoib_main.c +2 -4
index 469f98156b28..2f04586eb05d 100644
@@ -234,8 +234,7 @@ int ipoib_set_mode(struct net_device *dev, const char *buf)
 		priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM;
 
 		ipoib_flush_paths(dev);
-		rtnl_lock();
-		return 0;
+		return (!rtnl_trylock()) ? -EBUSY : 0;
 	}
 
 	if (!strcmp(buf, "datagram\n")) {
@@ -244,8 +243,7 @@ int ipoib_set_mode(struct net_device *dev, const char *buf)
 		dev_set_mtu(dev, min(priv->mcast_mtu, dev->mtu));
 		rtnl_unlock();
 		ipoib_flush_paths(dev);
-		rtnl_lock();
-		return 0;
+		return (!rtnl_trylock()) ? -EBUSY : 0;
 	}
 
 	return -EINVAL;
Signature · 1 line
2.12.0
author
#53 lore raw

PATCH 53/60 ktest: Fix child exit code processing

In reply to Jiri Slaby

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

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

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

commit 32677207dcc5e594254b7fb4fb2352b1755b1d5b upstream.

The child_exit errno needs to be shifted by 8 bits to compare against the return values for the bisect variables.

Fixes c5dacb88f0a64 ("ktest: Allow overriding bisect test results")
---
 tools/testing/ktest/ktest.pl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/ktest/ktest.pl +1 -1
index 999eab1bc64f..12e9cfd54ff5 100755
@@ -2375,7 +2375,7 @@ sub do_run_test {
     }
 
     waitpid $child_pid, 0;
-    $child_exit = $?;
+    $child_exit = $? >> 8;
 
     if (!$bug && $in_bisect) {
 	if (defined($bisect_ret_good)) {
Signature · 1 line
2.12.0
author
#54 lore raw

PATCH 54/60 nlm: Ensure callback code also checks that the files match

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 251af29c320d86071664f02c76f0d063a19fefdf upstream.

It is not sufficient to just check that the lock pids match when granting a callback, we also need to ensure that we're granting the callback on the right file.

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 include/linux/lockd/lockd.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
include/linux/lockd/lockd.h +2 -1
index 0adf073f13b3..669af5eaa898 100644
@@ -355,7 +355,8 @@ static inline int nlm_privileged_requester(const struct svc_rqst *rqstp)
 static inline int nlm_compare_locks(const struct file_lock *fl1,
 				    const struct file_lock *fl2)
 {
-	return	fl1->fl_pid   == fl2->fl_pid
+	return file_inode(fl1->fl_file) == file_inode(fl2->fl_file)
+	     && fl1->fl_pid   == fl2->fl_pid
 	     && fl1->fl_owner == fl2->fl_owner
 	     && fl1->fl_start == fl2->fl_start
 	     && fl1->fl_end   == fl2->fl_end
Signature · 1 line
2.12.0
author
#55 lore raw

PATCH 55/60 xtensa: move parse_tag_fdt out of #ifdef CONFIG_BLK_DEV_INITRD

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

FDT tag parsing is not related to whether BLK_DEV_INITRD is configured or not, move it out of the corresponding #ifdef/#endif block. This fixes passing external FDT to the kernel configured w/o BLK_DEV_INITRD support.

---
 arch/xtensa/kernel/setup.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/xtensa/kernel/setup.c +2 -2
index 946fb8d06c8b..faa0851c5dee 100644
@@ -160,6 +160,8 @@ static int __init parse_tag_initrd(const bp_tag_t* tag)
 
 __tagtable(BP_TAG_INITRD, parse_tag_initrd);
 
+#endif /* CONFIG_BLK_DEV_INITRD */
+
 #ifdef CONFIG_OF
 
 static int __init parse_tag_fdt(const bp_tag_t *tag)
@@ -179,8 +181,6 @@ void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
 
 #endif /* CONFIG_OF */
 
-#endif /* CONFIG_BLK_DEV_INITRD */
-
 static int __init parse_tag_cmdline(const bp_tag_t* tag)
 {
 	strlcpy(command_line, (char *)(tag->data), COMMAND_LINE_SIZE);
Signature · 1 line
2.12.0
author
#56 lore raw

PATCH 56/60 mac80211: flush delayed work when entering suspend

In reply to Jiri Slaby

From: Matt Chen <[email protected]>

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

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

commit a9e9200d8661c1a0be8c39f93deb383dc940de35 upstream.

The issue was found when entering suspend and resume. It triggers a warning in:
mac80211/key.c: ieee80211_enable_keys()
...
WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt ||

             sdata->crypto_tx_tailroom_pending_dec);

...

It points out sdata->crypto_tx_tailroom_pending_dec isn't cleaned up successfully in a delayed_work during suspend. Add a flush_delayed_work to fix it.

---
 net/mac80211/pm.c | 1 +
 1 file changed, 1 insertion(+)
net/mac80211/pm.c +1 -0
index efb510e6f206..a1f47b8d8013 100644
@@ -114,6 +114,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
 			break;
 		}
 
+		flush_delayed_work(&sdata->dec_tailroom_needed_wk);
 		drv_remove_interface(local, sdata);
 	}
 
Signature · 1 line
2.12.0
author
#57 lore raw

PATCH 57/60 drm/ast: Fix test for VGA enabled

In reply to Jiri Slaby

From: "Y.C. Chen" <[email protected]>

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

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

commit 905f21a49d388de3e99438235f3301cabf0c0ef4 upstream.

The test to see if VGA was already enabled is doing an unnecessary second test from a register that may or may not have been initialized to a valid value. Remove it.

---
 drivers/gpu/drm/ast/ast_post.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
drivers/gpu/drm/ast/ast_post.c +2 -6
index 977cfb35837a..d3464f35f427 100644
@@ -53,13 +53,9 @@ ast_is_vga_enabled(struct drm_device *dev)
 		/* TODO 1180 */
 	} else {
 		ch = ast_io_read8(ast, 0x43);
-		if (ch) {
-			ast_open_key(ast);
-			ch = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff);
-			return ch & 0x04;
-		}
+		return !!(ch & 0x01);
 	}
-	return 0;
+	return false;
 }
 #endif
 
Signature · 1 line
2.12.0
author
#58 lore raw

PATCH 58/60 drm/ttm: Make sure BOs being swapped out are cacheable

In reply to Jiri Slaby

From: Michel Dänzer <[email protected]>

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

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

commit 239ac65fa5ffab71adf66e642750f940e7241d99 upstream.

The current caching state may not be tt_cached, even though the placement contains TTM_PL_FLAG_CACHED, because placement can contain multiple caching flags. Trying to swap out such a BO would trip up the

	BUG_ON(ttm->caching_state != tt_cached);

in ttm_tt_swapout.

---
 drivers/gpu/drm/ttm/ttm_bo.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/ttm/ttm_bo.c +2 -2
index acd0fe0c80d2..548aa9f8edd7 100644
@@ -1612,7 +1612,6 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink)
 	struct ttm_buffer_object *bo;
 	int ret = -EBUSY;
 	int put_count;
-	uint32_t swap_placement = (TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM);
 
 	spin_lock(&glob->lru_lock);
 	list_for_each_entry(bo, &glob->swap_lru, swap) {
@@ -1650,7 +1649,8 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink)
 	if (unlikely(ret != 0))
 		goto out;
 
-	if ((bo->mem.placement & swap_placement) != swap_placement) {
+	if (bo->mem.mem_type != TTM_PL_SYSTEM ||
+	    bo->ttm->caching_state != tt_cached) {
 		struct ttm_mem_reg evict_mem;
 
 		evict_mem = bo->mem;
Signature · 1 line
2.12.0
author
#59 lore raw

PATCH 59/60 fat: fix using uninitialized fields of fat_inode/fsinfo_inode

In reply to Jiri Slaby

From: OGAWA Hirofumi <[email protected]>

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

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

commit c0d0e351285161a515396b7b1ee53ec9ffd97e3c upstream.

Recently fallocate patch was merged and it uses MSDOS_I(inode)->mmu_private at fat_evict_inode(). However, fat_inode/fsinfo_inode that was introduced in past didn't initialize MSDOS_I(inode) properly.

With those combinations, it became the cause of accessing random entry in FAT area.

---
 fs/fat/inode.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
fs/fat/inode.c +12 -1
index 0062da21dd8b..167d19052a00 100644
@@ -1193,6 +1193,16 @@ out:
 	return 0;
 }
 
+static void fat_dummy_inode_init(struct inode *inode)
+{
+	/* Initialize this dummy inode to work as no-op. */
+	MSDOS_I(inode)->mmu_private = 0;
+	MSDOS_I(inode)->i_start = 0;
+	MSDOS_I(inode)->i_logstart = 0;
+	MSDOS_I(inode)->i_attrs = 0;
+	MSDOS_I(inode)->i_pos = 0;
+}
+
 static int fat_read_root(struct inode *inode)
 {
 	struct super_block *sb = inode->i_sb;
@@ -1515,12 +1525,13 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
 	fat_inode = new_inode(sb);
 	if (!fat_inode)
 		goto out_fail;
-	MSDOS_I(fat_inode)->i_pos = 0;
+	fat_dummy_inode_init(fat_inode);
 	sbi->fat_inode = fat_inode;
 
 	fsinfo_inode = new_inode(sb);
 	if (!fsinfo_inode)
 		goto out_fail;
+	fat_dummy_inode_init(fsinfo_inode);
 	fsinfo_inode->i_ino = MSDOS_FSINFO_INO;
 	sbi->fsinfo_inode = fsinfo_inode;
 	insert_inode_hash(fsinfo_inode);
Signature · 1 line
2.12.0
author
#60 lore raw

PATCH 60/60 drivers: hv: Turn off write permission on the hypercall page

In reply to Jiri Slaby

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

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

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

commit 372b1e91343e657a7cc5e2e2bcecd5140ac28119 upstream.

The hypercall page only needs to be executable but currently it is setup to be writable as well. Fix the issue.

---
 drivers/hv/hv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hv/hv.c +1 -1
index 3fdb9af08705..9c0d458ec232 100644
@@ -154,7 +154,7 @@ int hv_init(void)
 	/* See if the hypercall page is already set */
 	rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
 
-	virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_EXEC);
+	virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_RX);
 
 	if (!virtaddr)
 		goto cleanup;
Signature · 1 line
2.12.0
#61 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.72 release. There are 60 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Thu Mar 16 14:14:28 CET 2017. Anything received after that time might be too late.

Build results:

	total: 128 pass: 128 fail: 0
Qemu test results:
	total: 93 pass: 93 fail: 0

Details are available at http://kerneltests.org/builders.

Guenter