2016-11-07 13:04:34

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 00/72] 3.12.67-stable review

This is the start of the stable review cycle for the 3.12.67 release.
There are 72 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 Wed Nov 9 14:03:48 CET 2016.
Anything received after that time might be too late.

The whole patch series can be found in one patch at:
http://kernel.org/pub/linux/kernel/people/jirislaby/stable-review/patch-3.12.67-rc1.xz
and the diffstat can be found below.

thanks,
js

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


Al Viro (1):
arc: don't leak bits of kernel stack into coredump

Alex Deucher (3):
drm/radeon: narrow asic_init for virtualization
drm/radeon/si/dpm: fix phase shedding setup
drm/radeon: change vblank_time's calculation method to reduce
computational error.

Andrew Bresticker (1):
pstore/ram: Use memcpy_fromio() to save old buffer

Anton Blanchard (1):
powerpc/vdso64: Use double word compare on pointers

Arnaldo Carvalho de Melo (1):
perf symbols: Fixup symbol sizes before picking best ones

Bart Van Assche (1):
dm: mark request_queue dead before destroying the DM device

Brian King (1):
scsi: ibmvfc: Fix I/O hang when port is not mapped

Daeho Jeong (1):
ext4: reinforce check of i_dtime when clearing high fields of uid and
gid

Dan Carpenter (2):
scsi: zfcp: spin_lock_irqsave() is not nestable
scsi: arcmsr: Buffer overflow in arcmsr_iop_message_xfer()

Daniel Glöckner (1):
mmc: block: don't use CMD23 with very old MMC cards

Dave Gerlach (1):
hwrng: omap - Only fail if pm_runtime_get_sync returns < 0

Dmitry Torokhov (1):
Input: elantech - add Fujitsu Lifebook E556 to force crc_enabled

Furquan Shaikh (1):
pstore/ram: Use memcpy_toio instead of memcpy

Gavin Shan (1):
powerpc/powernv: Use CPU-endian PEST in pnv_pci_dump_p7ioc_diag_data()

Gerald Schaefer (1):
mm/hugetlb: fix memory offline with hugepage size > memory block size

Glauber Costa (1):
cfq: fix starvation of asynchronous writes

Guenter Roeck (1):
metag: Only define atomic_dec_if_positive conditionally

Guilherme G Piccoli (1):
i40e: avoid NULL pointer dereference and recursive errors on early PCI
error

Jack Morgenstein (1):
net/mlx4_core: Allow resetting VF admin mac to zero

Jan Kara (1):
isofs: Do not return EACCES for unknown filesystems

Jan Remmet (1):
regulator: tps65910: Work around silicon erratum SWCZ010

Jan Viktorin (1):
uio: fix dmem_region_start computation

Jesse Gross (1):
tunnels: Remove encapsulation offloads on decap.

Jiri Slaby (2):
mmc: core: Annotate cmd_hdr as __le32
Revert "fix minor infoleak in get_user_ex()"

Joe Perches (1):
ipc: remove use of seq_printf return value

Laurent Dufour (1):
powerpc/pseries: Fix stack corruption in htpe code

Liu Gang (1):
gpio: mpc8xxx: Correct irq handler function

Liu ShuoX (1):
pstore: Fix buffer overflow while write offset equal to buffer size

Manfred Spraul (1):
ipc/sem.c: fix complex_count vs. simple op race

Marcin Nowakowski (1):
MIPS: ptrace: Fix regs_return_value for kernel context

Matti Kurkela (1):
Input: elantech - force needed quirks on Fujitsu H760

Mauro Carvalho Chehab (4):
mb86a20s: fix the locking logic
mb86a20s: fix demod settings
cx231xx: don't return error on success
cx231xx: fix GPIOs for Pixelview SBTVD hybrid

Max Staudt (1):
fbdev/efifb: Fix 16 color palette entry calculation

Mike Galbraith (1):
reiserfs: Unlock superblock before calling reiserfs_quota_on_mount()

Ming Lei (1):
scsi: Fix use-after-free

Oleg Nesterov (1):
fs/super.c: fix race between freeze_super() and thaw_super()

Ondrej Mosnáček (1):
crypto: gcm - Fix IV buffer size in crypto_gcm_setkey

Pan Xinhui (1):
powerpc/nvram: Fix an incorrect partition merge

Paul E. McKenney (1):
compiler: Allow 1- and 2-byte smp_load_acquire() and
smp_store_release()

Paul Mackerras (1):
powerpc/64: Fix incorrect return value from __copy_tofrom_user

Pravin B Shelar (1):
introduce NETIF_F_GSO_ENCAP_ALL helper mask

Richard Weinberger (1):
ubifs: Fix xattr_names length in exit paths

Ross Lagerwall (1):
cifs: Limit the overall credit acquired

Ross Zwisler (1):
ext4: allow DAX writeback for hole punch

Russell Currey (1):
powerpc/eeh: Null check uses of eeh_pe_bus_get

Sebastian Andrzej Siewior (1):
pstore/core: drop cmpxchg based updates

Sebastian Frias (1):
genirq/generic_chip: Add irq_unmap callback

Steffen Maier (10):
zfcp: fix fc_host port_type with NPIV
zfcp: fix ELS/GS request&response length for hardware data router
zfcp: close window with unblocked rport during rport gone
zfcp: retain trace level for SCSI and HBA FSF response records
zfcp: restore: Dont use 0 to indicate invalid LUN in rec trace
zfcp: trace on request for open and close of WKA port
zfcp: restore tracing of handle for port and LUN with HBA records
zfcp: fix D_ID field with actual value on tracing SAN responses
zfcp: fix payload trace length for SAN request&response
zfcp: trace full payload of all SAN records (req,resp,iels)

Steve French (5):
Clarify locking of cifs file and tcon structures and make more
granular
Display number of credits available
Set previous session id correctly on SMB3 reconnect
SMB3: GUIDs should be constructed as random but valid uuids
Do not send SMB3 SET_INFO request if nothing is changing

Trond Myklebust (1):
NFSv4: Open state recovery must account for file permission changes

Vladimir Zapolskiy (1):
i2c: core: fix NULL pointer dereference under race condition

Yonglong Wu (1):
usb: hub: change CLEAR_FEATURE to SET_FEATURE

arch/arc/kernel/signal.c | 9 +-
arch/metag/include/asm/atomic.h | 3 +-
arch/mips/include/asm/ptrace.h | 2 +-
arch/powerpc/kernel/eeh_driver.c | 8 ++
arch/powerpc/kernel/nvram_64.c | 6 +-
arch/powerpc/kernel/vdso64/datapage.S | 2 +-
arch/powerpc/kernel/vdso64/gettimeofday.S | 2 +-
arch/powerpc/lib/copyuser_64.S | 2 +-
arch/powerpc/platforms/powernv/eeh-ioda.c | 5 +
arch/powerpc/platforms/powernv/pci.c | 4 +-
arch/powerpc/platforms/pseries/lpar.c | 4 +-
arch/x86/include/asm/uaccess.h | 6 +-
block/cfq-iosched.c | 13 +-
crypto/gcm.c | 2 +-
drivers/char/hw_random/omap-rng.c | 4 +-
drivers/gpio/gpio-mpc8xxx.c | 2 +-
drivers/gpu/drm/radeon/r600_dpm.c | 15 +--
drivers/gpu/drm/radeon/radeon_device.c | 5 +-
drivers/gpu/drm/radeon/si_dpm.c | 2 +-
drivers/gpu/drm/radeon/sislands_smc.h | 1 +
drivers/i2c/i2c-core.c | 2 +-
drivers/input/mouse/elantech.c | 25 +++-
drivers/md/dm.c | 5 +
drivers/media/dvb-frontends/mb86a20s.c | 104 ++++++++--------
drivers/media/usb/cx231xx/cx231xx-avcore.c | 5 +-
drivers/media/usb/cx231xx/cx231xx-cards.c | 2 +-
drivers/media/usb/cx231xx/cx231xx-core.c | 3 +-
drivers/mmc/card/block.c | 5 +-
drivers/mmc/card/queue.h | 2 +-
drivers/net/ethernet/intel/i40e/i40e_main.c | 6 +
drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 +-
drivers/regulator/tps65910-regulator.c | 6 +
drivers/s390/scsi/zfcp_dbf.c | 162 ++++++++++++++++++++++---
drivers/s390/scsi/zfcp_dbf.h | 14 ++-
drivers/s390/scsi/zfcp_erp.c | 12 +-
drivers/s390/scsi/zfcp_ext.h | 8 +-
drivers/s390/scsi/zfcp_fsf.c | 22 +++-
drivers/s390/scsi/zfcp_fsf.h | 4 +-
drivers/s390/scsi/zfcp_scsi.c | 8 +-
drivers/scsi/arcmsr/arcmsr_hba.c | 8 +-
drivers/scsi/ibmvscsi/ibmvfc.c | 1 -
drivers/scsi/scsi_scan.c | 2 +-
drivers/uio/uio_dmem_genirq.c | 2 +-
drivers/usb/core/hub.c | 2 +-
drivers/video/efifb.c | 6 +-
fs/cifs/cifs_debug.c | 1 +
fs/cifs/cifsfs.c | 3 +-
fs/cifs/cifsglob.h | 30 ++---
fs/cifs/cifssmb.c | 4 +-
fs/cifs/connect.c | 2 +-
fs/cifs/file.c | 66 +++++-----
fs/cifs/misc.c | 15 +--
fs/cifs/readdir.c | 6 +-
fs/cifs/smb2glob.h | 10 ++
fs/cifs/smb2inode.c | 6 +
fs/cifs/smb2misc.c | 16 +--
fs/cifs/smb2ops.c | 2 +-
fs/cifs/smb2pdu.c | 21 +++-
fs/cifs/smb2pdu.h | 2 +-
fs/ext4/inode.c | 12 +-
fs/isofs/inode.c | 8 +-
fs/nfs/nfs4state.c | 3 +
fs/pstore/ram_core.c | 51 +-------
fs/reiserfs/super.c | 12 +-
fs/super.c | 6 +-
fs/ubifs/xattr.c | 2 +
include/linux/compiler.h | 2 +-
include/linux/netdev_features.h | 4 +
include/linux/sem.h | 1 +
include/net/ip_tunnels.h | 16 +++
ipc/msg.c | 34 +++---
ipc/sem.c | 156 ++++++++++++++----------
ipc/shm.c | 42 ++++---
ipc/util.c | 6 +-
kernel/irq/generic-chip.c | 20 +++
mm/hugetlb.c | 13 +-
net/ipv4/ip_tunnel_core.c | 3 +-
net/ipv6/sit.c | 5 +-
tools/perf/util/symbol-elf.c | 2 +-
tools/perf/util/symbol.c | 2 +-
80 files changed, 714 insertions(+), 385 deletions(-)

--
2.10.2


2016-11-07 13:05:27

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 04/72] ext4: reinforce check of i_dtime when clearing high fields of uid and gid

From: Daeho Jeong <[email protected]>

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

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

commit 93e3b4e6631d2a74a8cf7429138096862ff9f452 upstream.

Now, ext4_do_update_inode() clears high 16-bit fields of uid/gid
of deleted and evicted inode to fix up interoperability with old
kernels. However, it checks only i_dtime of an inode to determine
whether the inode was deleted and evicted, and this is very risky,
because i_dtime can be used for the pointer maintaining orphan inode
list, too. We need to further check whether the i_dtime is being
used for the orphan inode list even if the i_dtime is not NULL.

We found that high 16-bit fields of uid/gid of inode are unintentionally
and permanently cleared when the inode truncation is just triggered,
but not finished, and the inode metadata, whose high uid/gid bits are
cleared, is written on disk, and the sudden power-off follows that
in order.

Signed-off-by: Daeho Jeong <[email protected]>
Signed-off-by: Hobin Woo <[email protected]>
Signed-off-by: Theodore Ts'o <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/ext4/inode.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index aa9a1e7b0255..ec5cc5467c80 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4399,14 +4399,14 @@ static int ext4_do_update_inode(handle_t *handle,
* Fix up interoperability with old kernels. Otherwise, old inodes get
* re-used with the upper 16 bits of the uid/gid intact
*/
- if (!ei->i_dtime) {
+ if (ei->i_dtime && list_empty(&ei->i_orphan)) {
+ raw_inode->i_uid_high = 0;
+ raw_inode->i_gid_high = 0;
+ } else {
raw_inode->i_uid_high =
cpu_to_le16(high_16_bits(i_uid));
raw_inode->i_gid_high =
cpu_to_le16(high_16_bits(i_gid));
- } else {
- raw_inode->i_uid_high = 0;
- raw_inode->i_gid_high = 0;
}
} else {
raw_inode->i_uid_low = cpu_to_le16(fs_high2lowuid(i_uid));
--
2.10.2

2016-11-07 13:05:29

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 05/72] ext4: allow DAX writeback for hole punch

From: Ross Zwisler <[email protected]>

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

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

commit cca32b7eeb4ea24fa6596650e06279ad9130af98 upstream.

Currently when doing a DAX hole punch with ext4 we fail to do a writeback.
This is because the logic around filemap_write_and_wait_range() in
ext4_punch_hole() only looks for dirty page cache pages in the radix tree,
not for dirty DAX exceptional entries.

Signed-off-by: Ross Zwisler <[email protected]>
Reviewed-by: Jan Kara <[email protected]>
Signed-off-by: Theodore Ts'o <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/ext4/inode.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index ec5cc5467c80..4a3735a795d0 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3565,7 +3565,7 @@ int ext4_can_truncate(struct inode *inode)
}

/*
- * ext4_punch_hole: punches a hole in a file by releaseing the blocks
+ * ext4_punch_hole: punches a hole in a file by releasing the blocks
* associated with the given offset and length
*
* @inode: File inode
@@ -3599,7 +3599,7 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
* Write out all dirty pages to avoid race conditions
* Then release them.
*/
- if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
+ if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
ret = filemap_write_and_wait_range(mapping, offset,
offset + length - 1);
if (ret)
--
2.10.2

2016-11-07 13:05:35

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 13/72] pstore/ram: Use memcpy_toio instead of memcpy

From: Furquan Shaikh <[email protected]>

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

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

commit 7e75678d23167c2527e655658a8ef36a36c8b4d9 upstream.

persistent_ram_update uses vmap / iomap based on whether the buffer is in
memory region or reserved region. However, both map it as non-cacheable
memory. For armv8 specifically, non-cacheable mapping requests use a
memory type that has to be accessed aligned to the request size. memcpy()
doesn't guarantee that.

Signed-off-by: Furquan Shaikh <[email protected]>
Signed-off-by: Enric Balletbo Serra <[email protected]>
Reviewed-by: Aaron Durbin <[email protected]>
Reviewed-by: Olof Johansson <[email protected]>
Tested-by: Furquan Shaikh <[email protected]>
Signed-off-by: Kees Cook <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/pstore/ram_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c
index ee3c6ec5348f..eb42483dbb05 100644
--- a/fs/pstore/ram_core.c
+++ b/fs/pstore/ram_core.c
@@ -263,7 +263,7 @@ static void notrace persistent_ram_update(struct persistent_ram_zone *prz,
const void *s, unsigned int start, unsigned int count)
{
struct persistent_ram_buffer *buffer = prz->buffer;
- memcpy(buffer->data + start, s, count);
+ memcpy_toio(buffer->data + start, s, count);
persistent_ram_update_ecc(prz, start, count);
}

--
2.10.2

2016-11-07 13:05:47

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 21/72] zfcp: fix ELS/GS request&response length for hardware data router

From: Steffen Maier <[email protected]>

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

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

commit 70369f8e15b220f50a16348c79a61d3f7054813c upstream.

In the hardware data router case, introduced with kernel 3.2
commit 86a9668a8d29 ("[SCSI] zfcp: support for hardware data router")
the ELS/GS request&response length needs to be initialized
as in the chained SBAL case.

Otherwise, the FCP channel rejects ELS requests with
FSF_REQUEST_SIZE_TOO_LARGE.

Such ELS requests can be issued by user space through BSG / HBA API,
or zfcp itself uses ADISC ELS for remote port link test on RSCN.
The latter can cause a short path outage due to
unnecessary remote target port recovery because the always
failing ADISC cannot detect extremely short path interruptions
beyond the local FCP channel.

Below example is decoded with zfcpdbf from s390-tools:

Timestamp : ...
Area : SAN
Subarea : 00
Level : 1
Exception : -
CPU id : ..
Caller : zfcp_dbf_san_req+0408
Record id : 1
Tag : fssels1
Request id : 0x<reqid>
Destination ID : 0x00<target d_id>
Payload info : 52000000 00000000 <our wwpn > [ADISC]
<our wwnn > 00<s_id> 00000000
00000000 00000000 00000000 00000000

Timestamp : ...
Area : HBA
Subarea : 00
Level : 1
Exception : -
CPU id : ..
Caller : zfcp_dbf_hba_fsf_res+0740
Record id : 1
Tag : fs_ferr
Request id : 0x<reqid>
Request status : 0x00000010
FSF cmnd : 0x0000000b [FSF_QTCB_SEND_ELS]
FSF sequence no: 0x...
FSF issued : ...
FSF stat : 0x00000061 [FSF_REQUEST_SIZE_TOO_LARGE]
FSF stat qual : 00000000 00000000 00000000 00000000
Prot stat : 0x00000100
Prot stat qual : 00000000 00000000 00000000 00000000

Signed-off-by: Steffen Maier <[email protected]>
Fixes: 86a9668a8d29 ("[SCSI] zfcp: support for hardware data router")
Reviewed-by: Benjamin Block <[email protected]>
Reviewed-by: Hannes Reinecke <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/s390/scsi/zfcp_fsf.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 08d488f47097..fd015c413740 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -984,8 +984,12 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
if (zfcp_adapter_multi_buffer_active(adapter)) {
if (zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sg_req))
return -EIO;
+ qtcb->bottom.support.req_buf_length =
+ zfcp_qdio_real_bytes(sg_req);
if (zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sg_resp))
return -EIO;
+ qtcb->bottom.support.resp_buf_length =
+ zfcp_qdio_real_bytes(sg_resp);

zfcp_qdio_set_data_div(qdio, &req->qdio_req,
zfcp_qdio_sbale_count(sg_req));
--
2.10.2

2016-11-07 13:05:59

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 45/72] fs/super.c: fix race between freeze_super() and thaw_super()

From: Oleg Nesterov <[email protected]>

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

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

commit 89f39af129382a40d7cd1f6914617282cfeee28e upstream.

Change thaw_super() to check frozen != SB_FREEZE_COMPLETE rather than
frozen == SB_UNFROZEN, otherwise it can race with freeze_super() which
drops sb->s_umount after SB_FREEZE_WRITE to preserve the lock ordering.

In this case thaw_super() will wrongly call s_op->unfreeze_fs() before
it was actually frozen, and call sb_freeze_unlock() which leads to the
unbalanced percpu_up_write(). Unfortunately lockdep can't detect this,
so this triggers misc BUG_ON()'s in kernel/rcu/sync.c.

Reported-and-tested-by: Nikolay Borisov <[email protected]>
Signed-off-by: Oleg Nesterov <[email protected]>
Signed-off-by: Al Viro <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/super.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/super.c b/fs/super.c
index e3406833d82f..d9a7d620e747 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1337,8 +1337,8 @@ int freeze_super(struct super_block *sb)
}
}
/*
- * This is just for debugging purposes so that fs can warn if it
- * sees write activity when frozen is set to SB_FREEZE_COMPLETE.
+ * For debugging purposes so that fs can warn if it sees write activity
+ * when frozen is set to SB_FREEZE_COMPLETE, and for thaw_super().
*/
sb->s_writers.frozen = SB_FREEZE_COMPLETE;
up_write(&sb->s_umount);
@@ -1357,7 +1357,7 @@ int thaw_super(struct super_block *sb)
int error;

down_write(&sb->s_umount);
- if (sb->s_writers.frozen == SB_UNFROZEN) {
+ if (sb->s_writers.frozen != SB_FREEZE_COMPLETE) {
up_write(&sb->s_umount);
return -EINVAL;
}
--
2.10.2

2016-11-07 13:06:07

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 43/72] ipc/sem.c: fix complex_count vs. simple op race

From: Manfred Spraul <[email protected]>

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

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

commit 5864a2fd3088db73d47942370d0f7210a807b9bc upstream.

Commit 6d07b68ce16a ("ipc/sem.c: optimize sem_lock()") introduced a
race:

sem_lock has a fast path that allows parallel simple operations.
There are two reasons why a simple operation cannot run in parallel:
- a non-simple operations is ongoing (sma->sem_perm.lock held)
- a complex operation is sleeping (sma->complex_count != 0)

As both facts are stored independently, a thread can bypass the current
checks by sleeping in the right positions. See below for more details
(or kernel bugzilla 105651).

The patch fixes that by creating one variable (complex_mode)
that tracks both reasons why parallel operations are not possible.

The patch also updates stale documentation regarding the locking.

With regards to stable kernels:
The patch is required for all kernels that include the
commit 6d07b68ce16a ("ipc/sem.c: optimize sem_lock()") (3.10?)

The alternative is to revert the patch that introduced the race.

The patch is safe for backporting, i.e. it makes no assumptions
about memory barriers in spin_unlock_wait().

Background:
Here is the race of the current implementation:

Thread A: (simple op)
- does the first "sma->complex_count == 0" test

Thread B: (complex op)
- does sem_lock(): This includes an array scan. But the scan can't
find Thread A, because Thread A does not own sem->lock yet.
- the thread does the operation, increases complex_count,
drops sem_lock, sleeps

Thread A:
- spin_lock(&sem->lock), spin_is_locked(sma->sem_perm.lock)
- sleeps before the complex_count test

Thread C: (complex op)
- does sem_lock (no array scan, complex_count==1)
- wakes up Thread B.
- decrements complex_count

Thread A:
- does the complex_count test

Bug:
Now both thread A and thread C operate on the same array, without
any synchronization.

[js] use set_mb instead of smp_store_mb

Fixes: 6d07b68ce16a ("ipc/sem.c: optimize sem_lock()")
Link: http://lkml.kernel.org/r/[email protected]
Reported-by: <[email protected]>
Cc: "H. Peter Anvin" <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Davidlohr Bueso <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
include/linux/sem.h | 1 +
ipc/sem.c | 130 ++++++++++++++++++++++++++++++----------------------
2 files changed, 76 insertions(+), 55 deletions(-)

diff --git a/include/linux/sem.h b/include/linux/sem.h
index 976ce3a19f1b..d0efd6e6c20a 100644
--- a/include/linux/sem.h
+++ b/include/linux/sem.h
@@ -21,6 +21,7 @@ struct sem_array {
struct list_head list_id; /* undo requests on this array */
int sem_nsems; /* no. of semaphores in array */
int complex_count; /* pending complex operations */
+ bool complex_mode; /* no parallel simple ops */
};

#ifdef CONFIG_SYSVIPC
diff --git a/ipc/sem.c b/ipc/sem.c
index 9e963c28a214..857f7f8c27c4 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -155,14 +155,21 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it);

/*
* Locking:
+ * a) global sem_lock() for read/write
* sem_undo.id_next,
* sem_array.complex_count,
- * sem_array.pending{_alter,_cont},
- * sem_array.sem_undo: global sem_lock() for read/write
- * sem_undo.proc_next: only "current" is allowed to read/write that field.
+ * sem_array.complex_mode
+ * sem_array.pending{_alter,_const},
+ * sem_array.sem_undo
*
+ * b) global or semaphore sem_lock() for read/write:
* sem_array.sem_base[i].pending_{const,alter}:
- * global or semaphore sem_lock() for read/write
+ * sem_array.complex_mode (for read)
+ *
+ * c) special:
+ * sem_undo_list.list_proc:
+ * * undo_list->lock for write
+ * * rcu for read
*/

#define sc_semmsl sem_ctls[0]
@@ -263,24 +270,25 @@ static void sem_rcu_free(struct rcu_head *head)
#define ipc_smp_acquire__after_spin_is_unlocked() smp_rmb()

/*
- * Wait until all currently ongoing simple ops have completed.
+ * Enter the mode suitable for non-simple operations:
* Caller must own sem_perm.lock.
- * New simple ops cannot start, because simple ops first check
- * that sem_perm.lock is free.
- * that a) sem_perm.lock is free and b) complex_count is 0.
*/
-static void sem_wait_array(struct sem_array *sma)
+static void complexmode_enter(struct sem_array *sma)
{
int i;
struct sem *sem;

- if (sma->complex_count) {
- /* The thread that increased sma->complex_count waited on
- * all sem->lock locks. Thus we don't need to wait again.
- */
+ if (sma->complex_mode) {
+ /* We are already in complex_mode. Nothing to do */
return;
}

+ /* We need a full barrier after seting complex_mode:
+ * The write to complex_mode must be visible
+ * before we read the first sem->lock spinlock state.
+ */
+ set_mb(sma->complex_mode, true);
+
for (i = 0; i < sma->sem_nsems; i++) {
sem = sma->sem_base + i;
spin_unlock_wait(&sem->lock);
@@ -289,6 +297,28 @@ static void sem_wait_array(struct sem_array *sma)
}

/*
+ * Try to leave the mode that disallows simple operations:
+ * Caller must own sem_perm.lock.
+ */
+static void complexmode_tryleave(struct sem_array *sma)
+{
+ if (sma->complex_count) {
+ /* Complex ops are sleeping.
+ * We must stay in complex mode
+ */
+ return;
+ }
+ /*
+ * Immediately after setting complex_mode to false,
+ * a simple op can start. Thus: all memory writes
+ * performed by the current operation must be visible
+ * before we set complex_mode to false.
+ */
+ smp_store_release(&sma->complex_mode, false);
+}
+
+#define SEM_GLOBAL_LOCK (-1)
+/*
* If the request contains only one semaphore operation, and there are
* no complex transactions pending, lock only the semaphore involved.
* Otherwise, lock the entire semaphore array, since we either have
@@ -304,56 +334,42 @@ static inline int sem_lock(struct sem_array *sma, struct sembuf *sops,
/* Complex operation - acquire a full lock */
ipc_lock_object(&sma->sem_perm);

- /* And wait until all simple ops that are processed
- * right now have dropped their locks.
- */
- sem_wait_array(sma);
- return -1;
+ /* Prevent parallel simple ops */
+ complexmode_enter(sma);
+ return SEM_GLOBAL_LOCK;
}

/*
* Only one semaphore affected - try to optimize locking.
- * The rules are:
- * - optimized locking is possible if no complex operation
- * is either enqueued or processed right now.
- * - The test for enqueued complex ops is simple:
- * sma->complex_count != 0
- * - Testing for complex ops that are processed right now is
- * a bit more difficult. Complex ops acquire the full lock
- * and first wait that the running simple ops have completed.
- * (see above)
- * Thus: If we own a simple lock and the global lock is free
- * and complex_count is now 0, then it will stay 0 and
- * thus just locking sem->lock is sufficient.
+ * Optimized locking is possible if no complex operation
+ * is either enqueued or processed right now.
+ *
+ * Both facts are tracked by complex_mode.
*/
sem = sma->sem_base + sops->sem_num;

- if (sma->complex_count == 0) {
+ /*
+ * Initial check for complex_mode. Just an optimization,
+ * no locking, no memory barrier.
+ */
+ if (!sma->complex_mode) {
/*
* It appears that no complex operation is around.
* Acquire the per-semaphore lock.
*/
spin_lock(&sem->lock);

- /* Then check that the global lock is free */
- if (!spin_is_locked(&sma->sem_perm.lock)) {
- /*
- * We need a memory barrier with acquire semantics,
- * otherwise we can race with another thread that does:
- * complex_count++;
- * spin_unlock(sem_perm.lock);
- */
- ipc_smp_acquire__after_spin_is_unlocked();
+ /*
+ * See 51d7d5205d33
+ * ("powerpc: Add smp_mb() to arch_spin_is_locked()"):
+ * A full barrier is required: the write of sem->lock
+ * must be visible before the read is executed
+ */
+ smp_mb();

- /*
- * Now repeat the test of complex_count:
- * It can't change anymore until we drop sem->lock.
- * Thus: if is now 0, then it will stay 0.
- */
- if (sma->complex_count == 0) {
- /* fast path successful! */
- return sops->sem_num;
- }
+ if (!smp_load_acquire(&sma->complex_mode)) {
+ /* fast path successful! */
+ return sops->sem_num;
}
spin_unlock(&sem->lock);
}
@@ -373,15 +389,16 @@ static inline int sem_lock(struct sem_array *sma, struct sembuf *sops,
/* Not a false alarm, thus complete the sequence for a
* full lock.
*/
- sem_wait_array(sma);
- return -1;
+ complexmode_enter(sma);
+ return SEM_GLOBAL_LOCK;
}
}

static inline void sem_unlock(struct sem_array *sma, int locknum)
{
- if (locknum == -1) {
+ if (locknum == SEM_GLOBAL_LOCK) {
unmerge_queues(sma);
+ complexmode_tryleave(sma);
ipc_unlock_object(&sma->sem_perm);
} else {
struct sem *sem = sma->sem_base + locknum;
@@ -534,6 +551,7 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params)
}

sma->complex_count = 0;
+ sma->complex_mode = true; /* dropped by sem_unlock below */
INIT_LIST_HEAD(&sma->pending_alter);
INIT_LIST_HEAD(&sma->pending_const);
INIT_LIST_HEAD(&sma->list_id);
@@ -2167,10 +2185,10 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it)
/*
* The proc interface isn't aware of sem_lock(), it calls
* ipc_lock_object() directly (in sysvipc_find_ipc).
- * In order to stay compatible with sem_lock(), we must wait until
- * all simple semop() calls have left their critical regions.
+ * In order to stay compatible with sem_lock(), we must
+ * enter / leave complex_mode.
*/
- sem_wait_array(sma);
+ complexmode_enter(sma);

sem_otime = get_semotime(sma);

@@ -2187,6 +2205,8 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it)
sem_otime,
sma->sem_ctime);

+ complexmode_tryleave(sma);
+
return 0;
}
#endif
--
2.10.2

2016-11-07 13:06:03

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 44/72] arc: don't leak bits of kernel stack into coredump

From: Al Viro <[email protected]>

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

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

commit 7798bf2140ebcc36eafec6a4194fffd8d585d471 upstream.

On faulting sigreturn we do get SIGSEGV, all right, but anything
we'd put into pt_regs could end up in the coredump. And since
__copy_from_user() never zeroed on arc, we'd better bugger off
on its failure without copying random uninitialized bits of
kernel stack into pt_regs...

Signed-off-by: Al Viro <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/arc/kernel/signal.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c
index a0c63fc48457..ca6bcd132a14 100644
--- a/arch/arc/kernel/signal.c
+++ b/arch/arc/kernel/signal.c
@@ -80,13 +80,14 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf)
int err;

err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
- if (!err)
- set_current_blocked(&set);
-
err |= __copy_from_user(regs, &(sf->uc.uc_mcontext.regs.scratch),
sizeof(sf->uc.uc_mcontext.regs.scratch));
+ if (err)
+ return err;

- return err;
+ set_current_blocked(&set);
+
+ return 0;
}

static inline int is_do_ss_needed(unsigned int magic)
--
2.10.2

2016-11-07 13:06:36

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 61/72] tunnels: Remove encapsulation offloads on decap.

From: Jesse Gross <[email protected]>

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

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

commit a09a4c8dd1ec7f830e1fb9e59eb72bddc965d168 upstream.

If a packet is either locally encapsulated or processed through GRO
it is marked with the offloads that it requires. However, when it is
decapsulated these tunnel offload indications are not removed. This
means that if we receive an encapsulated TCP packet, aggregate it with
GRO, decapsulate, and retransmit the resulting frame on a NIC that does
not support encapsulation, we won't be able to take advantage of hardware
offloads even though it is just a simple TCP packet at this point.

This fixes the problem by stripping off encapsulation offload indications
when packets are decapsulated.

The performance impacts of this bug are significant. In a test where a
Geneve encapsulated TCP stream is sent to a hypervisor, GRO'ed, decapsulated,
and bridged to a VM performance is improved by 60% (5Gbps->8Gbps) as a
result of avoiding unnecessary segmentation at the VM tap interface.

[js] no fou in 3.12 yet

Reported-by: Ramu Ramamurthy <[email protected]>
Fixes: 68c33163 ("v4 GRE: Add TCP segmentation offload for GRE")
Signed-off-by: Jesse Gross <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
(backported from commit a09a4c8dd1ec7f830e1fb9e59eb72bddc965d168)
[adapt iptunnel_pull_header arguments, avoid 7f290c9]
Signed-off-by: Stefan Bader <[email protected]>
Signed-off-by: Juerg Haefliger <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
include/net/ip_tunnels.h | 16 ++++++++++++++++
net/ipv4/ip_tunnel_core.c | 3 ++-
net/ipv6/sit.c | 5 +++--
3 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index a0a4a100f5c9..df661ab4aa23 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -150,6 +150,22 @@ int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb,
__be32 src, __be32 dst, __u8 proto,
__u8 tos, __u8 ttl, __be16 df, bool xnet);

+static inline int iptunnel_pull_offloads(struct sk_buff *skb)
+{
+ if (skb_is_gso(skb)) {
+ int err;
+
+ err = skb_unclone(skb, GFP_ATOMIC);
+ if (unlikely(err))
+ return err;
+ skb_shinfo(skb)->gso_type &= ~(NETIF_F_GSO_ENCAP_ALL >>
+ NETIF_F_GSO_SHIFT);
+ }
+
+ skb->encapsulation = 0;
+ return 0;
+}
+
static inline void iptunnel_xmit_stats(int err,
struct net_device_stats *err_stats,
struct pcpu_tstats __percpu *stats)
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
index ff3f84f38e6d..792dd807c635 100644
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -114,6 +114,7 @@ int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto)
skb->vlan_tci = 0;
skb_set_queue_mapping(skb, 0);
skb->pkt_type = PACKET_HOST;
- return 0;
+
+ return iptunnel_pull_offloads(skb);
}
EXPORT_SYMBOL_GPL(iptunnel_pull_header);
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index a883776bcec8..a28d8d2bbd8f 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -647,14 +647,15 @@ static int ipip6_rcv(struct sk_buff *skb)
skb->mac_header = skb->network_header;
skb_reset_network_header(skb);
IPCB(skb)->flags = 0;
- skb->protocol = htons(ETH_P_IPV6);
+ skb->dev = tunnel->dev;

if (packet_is_spoofed(skb, iph, tunnel)) {
tunnel->dev->stats.rx_errors++;
goto out;
}

- __skb_tunnel_rx(skb, tunnel->dev, tunnel->net);
+ if (iptunnel_pull_header(skb, 0, htons(ETH_P_IPV6)))
+ goto out;

err = IP_ECN_decapsulate(iph, skb);
if (unlikely(err)) {
--
2.10.2

2016-11-07 13:06:35

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 52/72] net/mlx4_core: Allow resetting VF admin mac to zero

From: Jack Morgenstein <[email protected]>

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

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

commit 6e5224224faa50ec4c8949dcefadf895e565f0d1 upstream.

The VF administrative mac addresses (stored in the PF driver) are
initialized to zero when the PF driver starts up.

These addresses may be modified in the PF driver through ndo calls
initiated by iproute2 or libvirt.

While we allow the PF/host to change the VF admin mac address from zero
to a valid unicast mac, we do not allow restoring the VF admin mac to
zero. We currently only allow changing this mac to a different unicast mac.

This leads to problems when libvirt scripts are used to deal with
VF mac addresses, and libvirt attempts to revoke the mac so this
host will not use it anymore.

Fix this by allowing resetting a VF administrative MAC back to zero.

Fixes: 8f7ba3ca12f6 ('net/mlx4: Add set VF mac address support')
Signed-off-by: Jack Morgenstein <[email protected]>
Reported-by: Moshe Levi <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Juerg Haefliger <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 35d3821bed50..58ccdc2b012d 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -2077,7 +2077,7 @@ static int mlx4_en_set_vf_mac(struct net_device *dev, int queue, u8 *mac)
struct mlx4_en_dev *mdev = en_priv->mdev;
u64 mac_u64 = mlx4_en_mac_to_u64(mac);

- if (!is_valid_ether_addr(mac))
+ if (is_multicast_ether_addr(mac))
return -EINVAL;

return mlx4_set_vf_mac(mdev->dev, en_priv->port, queue, mac_u64);
--
2.10.2

2016-11-07 13:07:17

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 53/72] isofs: Do not return EACCES for unknown filesystems

From: Jan Kara <[email protected]>

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

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

commit a2ed0b391dd9c3ef1d64c7c3e370f4a5ffcd324a upstream.

When isofs_mount() is called to mount a device read-write, it returns
EACCES even before it checks that the device actually contains an isofs
filesystem. This may confuse mount(8) which then tries to mount all
subsequent filesystem types in read-only mode.

Fix the problem by returning EACCES only once we verify that the device
indeed contains an iso9660 filesystem.

Fixes: 17b7f7cf58926844e1dd40f5eb5348d481deca6a
Reported-by: Kent Overstreet <[email protected]>
Reported-by: Karel Zak <[email protected]>
Signed-off-by: Jan Kara <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/isofs/inode.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 2e2af97df075..77ac62441385 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -710,6 +710,11 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
pri_bh = NULL;

root_found:
+ /* We don't support read-write mounts */
+ if (!(s->s_flags & MS_RDONLY)) {
+ error = -EACCES;
+ goto out_freebh;
+ }

if (joliet_level && (pri == NULL || !opt.rock)) {
/* This is the case of Joliet with the norock mount flag.
@@ -1522,9 +1527,6 @@ struct inode *__isofs_iget(struct super_block *sb,
static struct dentry *isofs_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
- /* We don't support read-write mounts */
- if (!(flags & MS_RDONLY))
- return ERR_PTR(-EACCES);
return mount_bdev(fs_type, flags, dev_name, data, isofs_fill_super);
}

--
2.10.2

2016-11-07 13:07:19

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 46/72] cifs: Limit the overall credit acquired

From: Ross Lagerwall <[email protected]>

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

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

commit 7d414f396c91a3382e51cf628c1cf0709ad0188b upstream.

The kernel client requests 2 credits for many operations even though
they only use 1 credit (presumably to build up a buffer of credit).
Some servers seem to give the client as much credit as is requested. In
this case, the amount of credit the client has continues increasing to
the point where (server->credits * MAX_BUFFER_SIZE) overflows in
smb2_wait_mtu_credits().

Fix this by throttling the credit requests if an set limit is reached.
For async requests where the credit charge may be > 1, request as much
credit as what is charged.
The limit is chosen somewhat arbitrarily. The Windows client
defaults to 128 credits, the Windows server allows clients up to
512 credits (or 8192 for Windows 2016), and the NetApp server
(and at least one other) does not limit clients at all.
Choose a high enough value such that the client shouldn't limit
performance.

This behavior was seen with a NetApp filer (NetApp Release 9.0RC2).

[js] no smb2_async_readv and smb2_async_writev yet

Signed-off-by: Ross Lagerwall <[email protected]>
Signed-off-by: Steve French <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/cifs/smb2glob.h | 10 ++++++++++
fs/cifs/smb2pdu.c | 16 +++++++++++++++-
2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/fs/cifs/smb2glob.h b/fs/cifs/smb2glob.h
index 0ffa18094335..238759c146ba 100644
--- a/fs/cifs/smb2glob.h
+++ b/fs/cifs/smb2glob.h
@@ -61,4 +61,14 @@
/* Maximum buffer size value we can send with 1 credit */
#define SMB2_MAX_BUFFER_SIZE 65536

+/*
+ * Maximum number of credits to keep available.
+ * This value is chosen somewhat arbitrarily. The Windows client
+ * defaults to 128 credits, the Windows server allows clients up to
+ * 512 credits, and the NetApp server does not limit clients at all.
+ * Choose a high enough value such that the client shouldn't limit
+ * performance.
+ */
+#define SMB2_MAX_CREDITS_AVAILABLE 32000
+
#endif /* _SMB2_GLOB_H */
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 609350a69680..ac76b1dab3b8 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -102,7 +102,21 @@ smb2_hdr_assemble(struct smb2_hdr *hdr, __le16 smb2_cmd /* command */ ,
hdr->ProtocolId[3] = 'B';
hdr->StructureSize = cpu_to_le16(64);
hdr->Command = smb2_cmd;
- hdr->CreditRequest = cpu_to_le16(2); /* BB make this dynamic */
+ if (tcon && tcon->ses && tcon->ses->server) {
+ struct TCP_Server_Info *server = tcon->ses->server;
+
+ spin_lock(&server->req_lock);
+ /* Request up to 2 credits but don't go over the limit. */
+ if (server->credits >= SMB2_MAX_CREDITS_AVAILABLE)
+ hdr->CreditRequest = cpu_to_le16(0);
+ else
+ hdr->CreditRequest = cpu_to_le16(
+ min_t(int, SMB2_MAX_CREDITS_AVAILABLE -
+ server->credits, 2));
+ spin_unlock(&server->req_lock);
+ } else {
+ hdr->CreditRequest = cpu_to_le16(2);
+ }
hdr->ProcessId = cpu_to_le32((__u16)current->tgid);

if (!tcon)
--
2.10.2

2016-11-07 13:07:14

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 54/72] mmc: core: Annotate cmd_hdr as __le32

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

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

commit 3f2d26643595973e835e8356ea90c7c15cb1b0f1 upstream.

Commit f68381a70bb2 (mmc: block: fix packed command header endianness)
correctly fixed endianness handling of packed_cmd_hdr in
mmc_blk_packed_hdr_wrq_prep.

But now, sparse complains about incorrect types:
drivers/mmc/card/block.c:1613:27: sparse: incorrect type in assignment (different base types)
drivers/mmc/card/block.c:1613:27: expected unsigned int [unsigned] [usertype] <noident>
drivers/mmc/card/block.c:1613:27: got restricted __le32 [usertype] <noident>
...

So annotate cmd_hdr properly using __le32 to make everyone happy.

Signed-off-by: Jiri Slaby <[email protected]>
Fixes: f68381a70bb2 (mmc: block: fix packed command header endianness)
Signed-off-by: Ulf Hansson <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/mmc/card/block.c | 2 +-
drivers/mmc/card/queue.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 449b9f1d7502..9a7e7e251338 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1598,7 +1598,7 @@ static void mmc_blk_packed_hdr_wrq_prep(struct mmc_queue_req *mqrq,
struct mmc_blk_data *md = mq->data;
struct mmc_packed *packed = mqrq->packed;
bool do_rel_wr, do_data_tag;
- u32 *packed_cmd_hdr;
+ __le32 *packed_cmd_hdr;
u8 hdr_blocks;
u8 i = 1;

diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h
index 99e6521e6169..f42c11293dd8 100644
--- a/drivers/mmc/card/queue.h
+++ b/drivers/mmc/card/queue.h
@@ -24,7 +24,7 @@ enum mmc_packed_type {

struct mmc_packed {
struct list_head list;
- u32 cmd_hdr[1024];
+ __le32 cmd_hdr[1024];
unsigned int blocks;
u8 nr_entries;
u8 retries;
--
2.10.2

2016-11-07 13:07:10

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 55/72] ubifs: Fix xattr_names length in exit paths

From: Richard Weinberger <[email protected]>

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

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

commit 843741c5778398ea67055067f4cc65ae6c80ca0e upstream.

When the operation fails we also have to undo the changes
we made to ->xattr_names. Otherwise listxattr() will report
wrong lengths.

Signed-off-by: Richard Weinberger <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/ubifs/xattr.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
index 0f7139bdb2c2..69a42f36b421 100644
--- a/fs/ubifs/xattr.c
+++ b/fs/ubifs/xattr.c
@@ -167,6 +167,7 @@ out_cancel:
host_ui->xattr_cnt -= 1;
host_ui->xattr_size -= CALC_DENT_SIZE(nm->len);
host_ui->xattr_size -= CALC_XATTR_BYTES(size);
+ host_ui->xattr_names -= nm->len;
mutex_unlock(&host_ui->ui_mutex);
out_free:
make_bad_inode(inode);
@@ -514,6 +515,7 @@ out_cancel:
host_ui->xattr_cnt += 1;
host_ui->xattr_size += CALC_DENT_SIZE(nm->len);
host_ui->xattr_size += CALC_XATTR_BYTES(ui->data_len);
+ host_ui->xattr_names += nm->len;
mutex_unlock(&host_ui->ui_mutex);
ubifs_release_budget(c, &req);
make_bad_inode(inode);
--
2.10.2

2016-11-07 13:07:07

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 57/72] drm/radeon/si/dpm: fix phase shedding setup

From: Alex Deucher <[email protected]>

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

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

commit 427920292b00474d978d632bc03a8e4e50029af3 upstream.

Used the wrong index to setup the phase shedding mask.

Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/gpu/drm/radeon/si_dpm.c | 2 +-
drivers/gpu/drm/radeon/sislands_smc.h | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c
index db9c7d26ed16..c1281fc39040 100644
--- a/drivers/gpu/drm/radeon/si_dpm.c
+++ b/drivers/gpu/drm/radeon/si_dpm.c
@@ -3968,7 +3968,7 @@ static int si_populate_smc_voltage_tables(struct radeon_device *rdev,
&rdev->pm.dpm.dyn_state.phase_shedding_limits_table)) {
si_populate_smc_voltage_table(rdev, &si_pi->vddc_phase_shed_table, table);

- table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] =
+ table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING] =
cpu_to_be32(si_pi->vddc_phase_shed_table.mask_low);

si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_phase_shedding_delay,
diff --git a/drivers/gpu/drm/radeon/sislands_smc.h b/drivers/gpu/drm/radeon/sislands_smc.h
index 5578e9837026..0c3f65dfa743 100644
--- a/drivers/gpu/drm/radeon/sislands_smc.h
+++ b/drivers/gpu/drm/radeon/sislands_smc.h
@@ -194,6 +194,7 @@ typedef struct SISLANDS_SMC_SWSTATE SISLANDS_SMC_SWSTATE;
#define SISLANDS_SMC_VOLTAGEMASK_VDDC 0
#define SISLANDS_SMC_VOLTAGEMASK_MVDD 1
#define SISLANDS_SMC_VOLTAGEMASK_VDDCI 2
+#define SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING 3
#define SISLANDS_SMC_VOLTAGEMASK_MAX 4

struct SISLANDS_SMC_VOLTAGEMASKTABLE
--
2.10.2

2016-11-07 13:07:13

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 56/72] drm/radeon: narrow asic_init for virtualization

From: Alex Deucher <[email protected]>

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

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

commit 884031f0aacf57dad1575f96714efc80de9b19cc upstream.

Only needed on CIK+ due to the way pci reset is handled
by the GPU.

Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/gpu/drm/radeon/radeon_device.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index b05ce8ac9bf4..dbfd435485fe 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -570,8 +570,9 @@ bool radeon_card_posted(struct radeon_device *rdev)
{
uint32_t reg;

- /* for pass through, always force asic_init */
- if (radeon_device_is_virtual())
+ /* for pass through, always force asic_init for CI */
+ if (rdev->family >= CHIP_BONAIRE &&
+ radeon_device_is_virtual())
return false;

/* required for EFI mode on macbook2,1 which uses an r5xx asic */
--
2.10.2

2016-11-07 13:07:03

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 58/72] drm/radeon: change vblank_time's calculation method to reduce computational error.

From: Alex Deucher <[email protected]>

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

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

commit 02cfb5fccb0f9f968f0e208d89d9769aa16267bc upstream.

Ported from Rex's amdgpu change.

Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/gpu/drm/radeon/r600_dpm.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c
index 729ad831886f..d52ab40369b6 100644
--- a/drivers/gpu/drm/radeon/r600_dpm.c
+++ b/drivers/gpu/drm/radeon/r600_dpm.c
@@ -155,19 +155,20 @@ u32 r600_dpm_get_vblank_time(struct radeon_device *rdev)
struct drm_device *dev = rdev->ddev;
struct drm_crtc *crtc;
struct radeon_crtc *radeon_crtc;
- u32 line_time_us, vblank_lines;
+ u32 vblank_in_pixels;
u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */

if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
radeon_crtc = to_radeon_crtc(crtc);
if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
- line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) /
- radeon_crtc->hw_mode.clock;
- vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end -
- radeon_crtc->hw_mode.crtc_vdisplay +
- (radeon_crtc->v_border * 2);
- vblank_time_us = vblank_lines * line_time_us;
+ vblank_in_pixels =
+ radeon_crtc->hw_mode.crtc_htotal *
+ (radeon_crtc->hw_mode.crtc_vblank_end -
+ radeon_crtc->hw_mode.crtc_vdisplay +
+ (radeon_crtc->v_border * 2));
+
+ vblank_time_us = vblank_in_pixels * 1000 / radeon_crtc->hw_mode.clock;
break;
}
}
--
2.10.2

2016-11-07 13:07:02

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 59/72] mm/hugetlb: fix memory offline with hugepage size > memory block size

From: Gerald Schaefer <[email protected]>

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

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

commit 2247bb335ab9c40058484cac36ea74ee652f3b7b upstream.

Patch series "mm/hugetlb: memory offline issues with hugepages", v4.

This addresses several issues with hugepages and memory offline. While
the first patch fixes a panic, and is therefore rather important, the
last patch is just a performance optimization.

The second patch fixes a theoretical issue with reserved hugepages,
while still leaving some ugly usability issue, see description.

This patch (of 3):

dissolve_free_huge_pages() will either run into the VM_BUG_ON() or a
list corruption and addressing exception when trying to set a memory
block offline that is part (but not the first part) of a "gigantic"
hugetlb page with a size > memory block size.

When no other smaller hugetlb page sizes are present, the VM_BUG_ON()
will trigger directly. In the other case we will run into an addressing
exception later, because dissolve_free_huge_page() will not work on the
head page of the compound hugetlb page which will result in a NULL
hstate from page_hstate().

To fix this, first remove the VM_BUG_ON() because it is wrong, and then
use the compound head page in dissolve_free_huge_page(). This means
that an unused pre-allocated gigantic page that has any part of itself
inside the memory block that is going offline will be dissolved
completely. Losing an unused gigantic hugepage is preferable to failing
the memory offline, for example in the situation where a (possibly
faulty) memory DIMM needs to go offline.

Changes for v4.4 stable:
- make it apply w/o commit c1470b33 "mm/hugetlb: fix incorrect
hugepages count during mem hotplug"

Fixes: c8721bbb ("mm: memory-hotplug: enable memory hotplug to handle hugepage")
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Gerald Schaefer <[email protected]>
Acked-by: Michal Hocko <[email protected]>
Acked-by: Naoya Horiguchi <[email protected]>
Cc: "Kirill A . Shutemov" <[email protected]>
Cc: Vlastimil Babka <[email protected]>
Cc: Mike Kravetz <[email protected]>
Cc: "Aneesh Kumar K . V" <[email protected]>
Cc: Martin Schwidefsky <[email protected]>
Cc: Heiko Carstens <[email protected]>
Cc: Rui Teng <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Gerald Schaefer <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
mm/hugetlb.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index a3a9676c65cf..2aaf11bdfb17 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -899,12 +899,13 @@ static void dissolve_free_huge_page(struct page *page)
{
spin_lock(&hugetlb_lock);
if (PageHuge(page) && !page_count(page)) {
- struct hstate *h = page_hstate(page);
- int nid = page_to_nid(page);
- list_del(&page->lru);
+ struct page *head = compound_head(page);
+ struct hstate *h = page_hstate(head);
+ int nid = page_to_nid(head);
+ list_del(&head->lru);
h->free_huge_pages--;
h->free_huge_pages_node[nid]--;
- update_and_free_page(h, page);
+ update_and_free_page(h, head);
}
spin_unlock(&hugetlb_lock);
}
@@ -912,7 +913,8 @@ static void dissolve_free_huge_page(struct page *page)
/*
* Dissolve free hugepages in a given pfn range. Used by memory hotplug to
* make specified memory blocks removable from the system.
- * Note that start_pfn should aligned with (minimum) hugepage size.
+ * Note that this will dissolve a free gigantic hugepage completely, if any
+ * part of it lies within the given range.
*/
void dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn)
{
@@ -924,7 +926,6 @@ void dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn)
for_each_hstate(h)
if (order > huge_page_order(h))
order = huge_page_order(h);
- VM_BUG_ON(!IS_ALIGNED(start_pfn, 1 << order));
for (pfn = start_pfn; pfn < end_pfn; pfn += 1 << order)
dissolve_free_huge_page(pfn_to_page(pfn));
}
--
2.10.2

2016-11-07 13:07:00

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 60/72] introduce NETIF_F_GSO_ENCAP_ALL helper mask

From: Pravin B Shelar <[email protected]>

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

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

part of commit f6eec614d2252a99b861e288b6301599d2d58da4 upstream.

Add NETIF_F_GSO_ENCAP_ALL mask covering all encapsulation GSO flags.

[mk] only introduce the helper, do not pick the openvswitch change the
original commit was about.

Signed-off-by: Pravin B Shelar <[email protected]>
Acked-by: Andy Zhou <[email protected]>
Signed-off-by: Michal Kubecek <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
include/linux/netdev_features.h | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index a2a89a5c7be5..05009a1631fa 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -157,4 +157,8 @@ enum {
/* changeable features with no special hardware requirements */
#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO)

+#define NETIF_F_GSO_ENCAP_ALL (NETIF_F_GSO_GRE | \
+ NETIF_F_GSO_UDP_TUNNEL | \
+ NETIF_F_GSO_MPLS)
+
#endif /* _LINUX_NETDEV_FEATURES_H */
--
2.10.2

2016-11-07 13:12:14

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 40/72] scsi: Fix use-after-free

From: Ming Lei <[email protected]>

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

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

commit bcd8f2e94808fcddf6ef3af5f060a36820dcc432 upstream.

This patch fixes one use-after-free report[1] by KASAN.

In __scsi_scan_target(), when a type 31 device is probed,
SCSI_SCAN_TARGET_PRESENT is returned and the target will be scanned
again.

Inside the following scsi_report_lun_scan(), one new scsi_device
instance is allocated, and scsi_probe_and_add_lun() is called again to
probe the target and still see type 31 device, finally
__scsi_remove_device() is called to remove & free the device at the end
of scsi_probe_and_add_lun(), so cause use-after-free in
scsi_report_lun_scan().

And the following SCSI log can be observed:

scsi 0:0:2:0: scsi scan: INQUIRY pass 1 length 36
scsi 0:0:2:0: scsi scan: INQUIRY successful with code 0x0
scsi 0:0:2:0: scsi scan: peripheral device type of 31, no device added
scsi 0:0:2:0: scsi scan: Sending REPORT LUNS to (try 0)
scsi 0:0:2:0: scsi scan: REPORT LUNS successful (try 0) result 0x0
scsi 0:0:2:0: scsi scan: REPORT LUN scan
scsi 0:0:2:0: scsi scan: INQUIRY pass 1 length 36
scsi 0:0:2:0: scsi scan: INQUIRY successful with code 0x0
scsi 0:0:2:0: scsi scan: peripheral device type of 31, no device added
BUG: KASAN: use-after-free in __scsi_scan_target+0xbf8/0xe40 at addr ffff88007b44a104

This patch fixes the issue by moving the putting reference at
the end of scsi_report_lun_scan().

[1] KASAN report
==================================================================
[ 3.274597] PM: Adding info for serio:serio1
[ 3.275127] BUG: KASAN: use-after-free in __scsi_scan_target+0xd87/0xdf0 at addr ffff880254d8c304
[ 3.275653] Read of size 4 by task kworker/u10:0/27
[ 3.275903] CPU: 3 PID: 27 Comm: kworker/u10:0 Not tainted 4.8.0 #2121
[ 3.276258] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
[ 3.276797] Workqueue: events_unbound async_run_entry_fn
[ 3.277083] ffff880254d8c380 ffff880259a37870 ffffffff94bbc6c1 ffff880078402d80
[ 3.277532] ffff880254d8bb80 ffff880259a37898 ffffffff9459fec1 ffff880259a37930
[ 3.277989] ffff880254d8bb80 ffff880078402d80 ffff880259a37920 ffffffff945a0165
[ 3.278436] Call Trace:
[ 3.278528] [<ffffffff94bbc6c1>] dump_stack+0x65/0x84
[ 3.278797] [<ffffffff9459fec1>] kasan_object_err+0x21/0x70
[ 3.279063] device: 'psaux': device_add
[ 3.279616] [<ffffffff945a0165>] kasan_report_error+0x205/0x500
[ 3.279651] PM: Adding info for No Bus:psaux
[ 3.280202] [<ffffffff944ecd22>] ? kfree_const+0x22/0x30
[ 3.280486] [<ffffffff94bc2dc9>] ? kobject_release+0x119/0x370
[ 3.280805] [<ffffffff945a0543>] __asan_report_load4_noabort+0x43/0x50
[ 3.281170] [<ffffffff9507e1f7>] ? __scsi_scan_target+0xd87/0xdf0
[ 3.281506] [<ffffffff9507e1f7>] __scsi_scan_target+0xd87/0xdf0
[ 3.281848] [<ffffffff9507d470>] ? scsi_add_device+0x30/0x30
[ 3.282156] [<ffffffff94f7f660>] ? pm_runtime_autosuspend_expiration+0x60/0x60
[ 3.282570] [<ffffffff956ddb07>] ? _raw_spin_lock+0x17/0x40
[ 3.282880] [<ffffffff9507e505>] scsi_scan_channel+0x105/0x160
[ 3.283200] [<ffffffff9507e8a2>] scsi_scan_host_selected+0x212/0x2f0
[ 3.283563] [<ffffffff9507eb3c>] do_scsi_scan_host+0x1bc/0x250
[ 3.283882] [<ffffffff9507efc1>] do_scan_async+0x41/0x450
[ 3.284173] [<ffffffff941c1fee>] async_run_entry_fn+0xfe/0x610
[ 3.284492] [<ffffffff941a8954>] ? pwq_dec_nr_in_flight+0x124/0x2a0
[ 3.284876] [<ffffffff941d1770>] ? preempt_count_add+0x130/0x160
[ 3.285207] [<ffffffff941a9a84>] process_one_work+0x544/0x12d0
[ 3.285526] [<ffffffff941aa8e9>] worker_thread+0xd9/0x12f0
[ 3.285844] [<ffffffff941aa810>] ? process_one_work+0x12d0/0x12d0
[ 3.286182] [<ffffffff941bb365>] kthread+0x1c5/0x260
[ 3.286443] [<ffffffff940855cd>] ? __switch_to+0x88d/0x1430
[ 3.286745] [<ffffffff941bb1a0>] ? kthread_worker_fn+0x5a0/0x5a0
[ 3.287085] [<ffffffff956dde9f>] ret_from_fork+0x1f/0x40
[ 3.287368] [<ffffffff941bb1a0>] ? kthread_worker_fn+0x5a0/0x5a0
[ 3.287697] Object at ffff880254d8bb80, in cache kmalloc-2048 size: 2048
[ 3.288064] Allocated:
[ 3.288147] PID = 27
[ 3.288218] [<ffffffff940b27ab>] save_stack_trace+0x2b/0x50
[ 3.288531] [<ffffffff9459f246>] save_stack+0x46/0xd0
[ 3.288806] [<ffffffff9459f4bd>] kasan_kmalloc+0xad/0xe0
[ 3.289098] [<ffffffff9459c07e>] __kmalloc+0x13e/0x250
[ 3.289378] [<ffffffff95078e5a>] scsi_alloc_sdev+0xea/0xcf0
[ 3.289701] [<ffffffff9507de76>] __scsi_scan_target+0xa06/0xdf0
[ 3.290034] [<ffffffff9507e505>] scsi_scan_channel+0x105/0x160
[ 3.290362] [<ffffffff9507e8a2>] scsi_scan_host_selected+0x212/0x2f0
[ 3.290724] [<ffffffff9507eb3c>] do_scsi_scan_host+0x1bc/0x250
[ 3.291055] [<ffffffff9507efc1>] do_scan_async+0x41/0x450
[ 3.291354] [<ffffffff941c1fee>] async_run_entry_fn+0xfe/0x610
[ 3.291695] [<ffffffff941a9a84>] process_one_work+0x544/0x12d0
[ 3.292022] [<ffffffff941aa8e9>] worker_thread+0xd9/0x12f0
[ 3.292325] [<ffffffff941bb365>] kthread+0x1c5/0x260
[ 3.292594] [<ffffffff956dde9f>] ret_from_fork+0x1f/0x40
[ 3.292886] Freed:
[ 3.292945] PID = 27
[ 3.293016] [<ffffffff940b27ab>] save_stack_trace+0x2b/0x50
[ 3.293327] [<ffffffff9459f246>] save_stack+0x46/0xd0
[ 3.293600] [<ffffffff9459fa61>] kasan_slab_free+0x71/0xb0
[ 3.293916] [<ffffffff9459bac2>] kfree+0xa2/0x1f0
[ 3.294168] [<ffffffff9508158a>] scsi_device_dev_release_usercontext+0x50a/0x730
[ 3.294598] [<ffffffff941ace9a>] execute_in_process_context+0xda/0x130
[ 3.294974] [<ffffffff9508107c>] scsi_device_dev_release+0x1c/0x20
[ 3.295322] [<ffffffff94f566f6>] device_release+0x76/0x1e0
[ 3.295626] [<ffffffff94bc2db7>] kobject_release+0x107/0x370
[ 3.295942] [<ffffffff94bc29ce>] kobject_put+0x4e/0xa0
[ 3.296222] [<ffffffff94f56e17>] put_device+0x17/0x20
[ 3.296497] [<ffffffff9505201c>] scsi_device_put+0x7c/0xa0
[ 3.296801] [<ffffffff9507e1bc>] __scsi_scan_target+0xd4c/0xdf0
[ 3.297132] [<ffffffff9507e505>] scsi_scan_channel+0x105/0x160
[ 3.297458] [<ffffffff9507e8a2>] scsi_scan_host_selected+0x212/0x2f0
[ 3.297829] [<ffffffff9507eb3c>] do_scsi_scan_host+0x1bc/0x250
[ 3.298156] [<ffffffff9507efc1>] do_scan_async+0x41/0x450
[ 3.298453] [<ffffffff941c1fee>] async_run_entry_fn+0xfe/0x610
[ 3.298777] [<ffffffff941a9a84>] process_one_work+0x544/0x12d0
[ 3.299105] [<ffffffff941aa8e9>] worker_thread+0xd9/0x12f0
[ 3.299408] [<ffffffff941bb365>] kthread+0x1c5/0x260
[ 3.299676] [<ffffffff956dde9f>] ret_from_fork+0x1f/0x40
[ 3.299967] Memory state around the buggy address:
[ 3.300209] ffff880254d8c200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 3.300608] ffff880254d8c280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 3.300986] >ffff880254d8c300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 3.301408] ^
[ 3.301550] ffff880254d8c380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 3.301987] ffff880254d8c400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 3.302396]
==================================================================

Cc: Christoph Hellwig <[email protected]>
Signed-off-by: Ming Lei <[email protected]>
Reviewed-by: Christoph Hellwig <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/scsi/scsi_scan.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 25073167bcc4..1c87d74bf130 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1537,12 +1537,12 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
out_err:
kfree(lun_data);
out:
- scsi_device_put(sdev);
if (scsi_device_created(sdev))
/*
* the sdev we used didn't appear in the report luns scan
*/
__scsi_remove_device(sdev);
+ scsi_device_put(sdev);
return ret;
}

--
2.10.2

2016-11-07 13:12:12

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 41/72] metag: Only define atomic_dec_if_positive conditionally

From: Guenter Roeck <[email protected]>

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

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

commit 35d04077ad96ed33ceea2501f5a4f1eacda77218 upstream.

The definition of atomic_dec_if_positive() assumes that
atomic_sub_if_positive() exists, which is only the case if
metag specific atomics are used. This results in the following
build error when trying to build metag1_defconfig.

kernel/ucount.c: In function 'dec_ucount':
kernel/ucount.c:211: error:
implicit declaration of function 'atomic_sub_if_positive'

Moving the definition of atomic_dec_if_positive() into the metag
conditional code fixes the problem.

Fixes: 6006c0d8ce94 ("metag: Atomics, locks and bitops")
Signed-off-by: Guenter Roeck <[email protected]>
Signed-off-by: James Hogan <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/metag/include/asm/atomic.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/metag/include/asm/atomic.h b/arch/metag/include/asm/atomic.h
index 307ecd2bd9a1..d7d6b9e53e44 100644
--- a/arch/metag/include/asm/atomic.h
+++ b/arch/metag/include/asm/atomic.h
@@ -38,6 +38,7 @@
#define atomic_dec(v) atomic_sub(1, (v))

#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+#define atomic_dec_if_positive(v) atomic_sub_if_positive(1, v)

#define smp_mb__before_atomic_dec() barrier()
#define smp_mb__after_atomic_dec() barrier()
@@ -46,8 +47,6 @@

#endif

-#define atomic_dec_if_positive(v) atomic_sub_if_positive(1, v)
-
#include <asm-generic/atomic64.h>

#endif /* __ASM_METAG_ATOMIC_H */
--
2.10.2

2016-11-07 13:12:22

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 48/72] Display number of credits available

From: Steve French <[email protected]>

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

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

commit 9742805d6b1bfb45d7f267648c34fb5bcd347397 upstream.

In debugging smb3, it is useful to display the number
of credits available, so we can see when the server has not granted
sufficient operations for the client to make progress, or alternatively
the client has requested too many credits (as we saw in a recent bug)
so we can compare with the number of credits the server thinks
we have.

Add a /proc/fs/cifs/DebugData line to display the client view
on how many credits are available.

Signed-off-by: Steve French <[email protected]>
Reported-by: Germano Percossi <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/cifs/cifs_debug.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index f3ac4154cbb6..5a3e796461be 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -170,6 +170,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
list_for_each(tmp1, &cifs_tcp_ses_list) {
server = list_entry(tmp1, struct TCP_Server_Info,
tcp_ses_list);
+ seq_printf(m, "\nNumber of credits: %d", server->credits);
i++;
list_for_each(tmp2, &server->smb_ses_list) {
ses = list_entry(tmp2, struct cifs_ses,
--
2.10.2

2016-11-07 13:12:17

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 49/72] Set previous session id correctly on SMB3 reconnect

From: Steve French <[email protected]>

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

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

commit c2afb8147e69819885493edf3a7c1ce03aaf2d4e upstream.

Signed-off-by: Steve French <[email protected]>
Reported-by: David Goebel <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/cifs/smb2pdu.c | 5 +++++
fs/cifs/smb2pdu.h | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index ac76b1dab3b8..1a6dde4bce62 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -566,6 +566,7 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
char *security_blob;
char *ntlmssp_blob = NULL;
bool use_spnego = false; /* else use raw ntlmssp */
+ u64 previous_session = ses->Suid;

cifs_dbg(FYI, "Session Setup\n");

@@ -602,6 +603,10 @@ ssetup_ntlmssp_authenticate:
return rc;

req->hdr.SessionId = 0; /* First session, not a reauthenticate */
+
+ /* if reconnect, we need to send previous sess id, otherwise it is 0 */
+ req->PreviousSessionId = previous_session;
+
req->VcNumber = 0; /* MBZ */
/* to enable echos and oplocks */
req->hdr.CreditRequest = cpu_to_le16(3);
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
index 6133a4e45c6e..efcc77b51556 100644
--- a/fs/cifs/smb2pdu.h
+++ b/fs/cifs/smb2pdu.h
@@ -228,7 +228,7 @@ struct smb2_sess_setup_req {
__le32 Channel;
__le16 SecurityBufferOffset;
__le16 SecurityBufferLength;
- __le64 PreviousSessionId;
+ __u64 PreviousSessionId;
__u8 Buffer[1]; /* variable length GSS security buffer */
} __packed;

--
2.10.2

2016-11-07 13:12:09

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 50/72] SMB3: GUIDs should be constructed as random but valid uuids

From: Steve French <[email protected]>

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

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

commit fa70b87cc6641978b20e12cc5d517e9ffc0086d4 upstream.

GUIDs although random, and 16 bytes, need to be generated as
proper uuids.

[js] no create_durable_v2_buf in 3.12 yet

Signed-off-by: Steve French <[email protected]>
Reviewed-by: Aurelien Aptel <[email protected]>
Reported-by: David Goebels <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/cifs/cifsfs.c | 2 +-
fs/cifs/connect.c | 2 +-
fs/cifs/smb2ops.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 16714b0661a8..037b8f7e8a94 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -260,7 +260,7 @@ cifs_alloc_inode(struct super_block *sb)
cifs_inode->createtime = 0;
cifs_inode->epoch = 0;
#ifdef CONFIG_CIFS_SMB2
- get_random_bytes(cifs_inode->lease_key, SMB2_LEASE_KEY_SIZE);
+ generate_random_uuid(cifs_inode->lease_key);
#endif
/*
* Can not set i_flags here - they get immediately overwritten to zero
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 7bdcf8fbc1ff..54f507bd2c09 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2147,7 +2147,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr,
sizeof(tcp_ses->dstaddr));
#ifdef CONFIG_CIFS_SMB2
- get_random_bytes(tcp_ses->client_guid, SMB2_CLIENT_GUID_SIZE);
+ generate_random_uuid(tcp_ses->client_guid);
#endif
/*
* at this point we are the only ones with the pointer
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index a3a7a52aef04..6f74de30bd29 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -595,7 +595,7 @@ smb2_set_lease_key(struct inode *inode, struct cifs_fid *fid)
static void
smb2_new_lease_key(struct cifs_fid *fid)
{
- get_random_bytes(fid->lease_key, SMB2_LEASE_KEY_SIZE);
+ generate_random_uuid(fid->lease_key);
}

#define SMB2_SYMLINK_STRUCT_SIZE \
--
2.10.2

2016-11-07 13:12:06

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 51/72] Do not send SMB3 SET_INFO request if nothing is changing

From: Steve French <[email protected]>

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

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

commit 18dd8e1a65ddae2351d0f0d6dd4a334f441fc5fa upstream.

[CIFS] We had cases where we sent a SMB2/SMB3 setinfo request with all
timestamp (and DOS attribute) fields marked as 0 (ie do not change)
e.g. on chmod or chown.

Signed-off-by: Steve French <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/cifs/smb2inode.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
index f970c5d5b253..549676f7b811 100644
--- a/fs/cifs/smb2inode.c
+++ b/fs/cifs/smb2inode.c
@@ -266,9 +266,15 @@ smb2_set_file_info(struct inode *inode, const char *full_path,
struct tcon_link *tlink;
int rc;

+ if ((buf->CreationTime == 0) && (buf->LastAccessTime == 0) &&
+ (buf->LastWriteTime == 0) && (buf->ChangeTime) &&
+ (buf->Attributes == 0))
+ return 0; /* would be a no op, no sense sending this */
+
tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
return PTR_ERR(tlink);
+
rc = smb2_open_op_close(xid, tlink_tcon(tlink), cifs_sb, full_path,
FILE_WRITE_ATTRIBUTES, FILE_OPEN, 0, buf,
SMB2_OP_SET_INFO);
--
2.10.2

2016-11-07 13:13:46

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 47/72] Clarify locking of cifs file and tcon structures and make more granular

From: Steve French <[email protected]>

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

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

commit 3afca265b5f53a0b15b79531c13858049505582d upstream.

Remove the global file_list_lock to simplify cifs/smb3 locking and
have spinlocks that more closely match the information they are
protecting.

Add new tcon->open_file_lock and file->file_info_lock spinlocks.
Locks continue to follow a heirachy,
cifs_socket --> cifs_ses --> cifs_tcon --> cifs_file
where global tcp_ses_lock still protects socket and cifs_ses, while the
the newer locks protect the lower level structure's information
(tcon and cifs_file respectively).

Signed-off-by: Steve French <[email protected]>
Signed-off-by: Pavel Shilovsky <[email protected]>
Reviewed-by: Aurelien Aptel <[email protected]>
Reviewed-by: Germano Percossi <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/cifs/cifsfs.c | 1 -
fs/cifs/cifsglob.h | 30 ++++++++++++-------------
fs/cifs/cifssmb.c | 4 ++--
fs/cifs/file.c | 66 ++++++++++++++++++++++++++++++++----------------------
fs/cifs/misc.c | 15 +++++++------
fs/cifs/readdir.c | 6 ++---
fs/cifs/smb2misc.c | 16 ++++++-------
7 files changed, 75 insertions(+), 63 deletions(-)

diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index b9f5709b54ca..16714b0661a8 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -1185,7 +1185,6 @@ init_cifs(void)
GlobalTotalActiveXid = 0;
GlobalMaxActiveXid = 0;
spin_lock_init(&cifs_tcp_ses_lock);
- spin_lock_init(&cifs_file_list_lock);
spin_lock_init(&GlobalMid_Lock);

if (cifs_max_pending < 2) {
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index cee6a796d596..fa30efe15ba2 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -761,6 +761,7 @@ struct cifs_tcon {
struct list_head tcon_list;
int tc_count;
struct list_head openFileList;
+ spinlock_t open_file_lock; /* protects list above */
struct cifs_ses *ses; /* pointer to session associated with */
char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */
char *nativeFileSystem;
@@ -817,7 +818,7 @@ struct cifs_tcon {
#endif /* CONFIG_CIFS_STATS2 */
__u64 bytes_read;
__u64 bytes_written;
- spinlock_t stat_lock;
+ spinlock_t stat_lock; /* protects the two fields above */
#endif /* CONFIG_CIFS_STATS */
FILE_SYSTEM_DEVICE_INFO fsDevInfo;
FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */
@@ -959,8 +960,10 @@ struct cifs_fid_locks {
};

struct cifsFileInfo {
+ /* following two lists are protected by tcon->open_file_lock */
struct list_head tlist; /* pointer to next fid owned by tcon */
struct list_head flist; /* next fid (file instance) for this inode */
+ /* lock list below protected by cifsi->lock_sem */
struct cifs_fid_locks *llist; /* brlocks held by this fid */
kuid_t uid; /* allows finding which FileInfo structure */
__u32 pid; /* process id who opened file */
@@ -968,11 +971,12 @@ struct cifsFileInfo {
/* BB add lock scope info here if needed */ ;
/* lock scope id (0 if none) */
struct dentry *dentry;
- unsigned int f_flags;
struct tcon_link *tlink;
+ unsigned int f_flags;
bool invalidHandle:1; /* file closed via session abend */
bool oplock_break_cancelled:1;
- int count; /* refcount protected by cifs_file_list_lock */
+ int count;
+ spinlock_t file_info_lock; /* protects four flag/count fields above */
struct mutex fh_mutex; /* prevents reopen race after dead ses*/
struct cifs_search_info srch_inf;
struct work_struct oplock_break; /* work for oplock breaks */
@@ -1036,7 +1040,7 @@ struct cifs_writedata {

/*
* Take a reference on the file private data. Must be called with
- * cifs_file_list_lock held.
+ * cfile->file_info_lock held.
*/
static inline void
cifsFileInfo_get_locked(struct cifsFileInfo *cifs_file)
@@ -1422,8 +1426,10 @@ require use of the stronger protocol */
* GlobalMid_Lock protects:
* list operations on pending_mid_q and oplockQ
* updates to XID counters, multiplex id and SMB sequence numbers
- * cifs_file_list_lock protects:
- * list operations on tcp and SMB session lists and tCon lists
+ * tcp_ses_lock protects:
+ * list operations on tcp and SMB session lists
+ * tcon->open_file_lock protects the list of open files hanging off the tcon
+ * cfile->file_info_lock protects counters and fields in cifs file struct
* f_owner.lock protects certain per file struct operations
* mapping->page_lock protects certain per page operations
*
@@ -1455,18 +1461,12 @@ GLOBAL_EXTERN struct list_head cifs_tcp_ses_list;
* tcp session, and the list of tcon's per smb session. It also protects
* the reference counters for the server, smb session, and tcon. Finally,
* changes to the tcon->tidStatus should be done while holding this lock.
+ * generally the locks should be taken in order tcp_ses_lock before
+ * tcon->open_file_lock and that before file->file_info_lock since the
+ * structure order is cifs_socket-->cifs_ses-->cifs_tcon-->cifs_file
*/
GLOBAL_EXTERN spinlock_t cifs_tcp_ses_lock;

-/*
- * This lock protects the cifs_file->llist and cifs_file->flist
- * list operations, and updates to some flags (cifs_file->invalidHandle)
- * It will be moved to either use the tcon->stat_lock or equivalent later.
- * If cifs_tcp_ses_lock and the lock below are both needed to be held, then
- * the cifs_tcp_ses_lock must be grabbed first and released last.
- */
-GLOBAL_EXTERN spinlock_t cifs_file_list_lock;
-
#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
/* Outstanding dir notify requests */
GLOBAL_EXTERN struct list_head GlobalDnotifyReqList;
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index f53a6e8204d8..9c93c2f29af1 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -98,13 +98,13 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
struct list_head *tmp1;

/* list all files open on tree connection and mark them invalid */
- spin_lock(&cifs_file_list_lock);
+ spin_lock(&tcon->open_file_lock);
list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
open_file = list_entry(tmp, struct cifsFileInfo, tlist);
open_file->invalidHandle = true;
open_file->oplock_break_cancelled = true;
}
- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&tcon->open_file_lock);
/*
* BB Add call to invalidate_inodes(sb) for all superblocks mounted
* to this tcon.
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 381e60e6ef92..1e7883fb679d 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -306,6 +306,7 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
cfile->tlink = cifs_get_tlink(tlink);
INIT_WORK(&cfile->oplock_break, cifs_oplock_break);
mutex_init(&cfile->fh_mutex);
+ spin_lock_init(&cfile->file_info_lock);

cifs_sb_active(inode->i_sb);

@@ -318,7 +319,7 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
oplock = 0;
}

- spin_lock(&cifs_file_list_lock);
+ spin_lock(&tcon->open_file_lock);
if (fid->pending_open->oplock != CIFS_OPLOCK_NO_CHANGE && oplock)
oplock = fid->pending_open->oplock;
list_del(&fid->pending_open->olist);
@@ -327,12 +328,13 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
server->ops->set_fid(cfile, fid, oplock);

list_add(&cfile->tlist, &tcon->openFileList);
+
/* if readable file instance put first in list*/
if (file->f_mode & FMODE_READ)
list_add(&cfile->flist, &cinode->openFileList);
else
list_add_tail(&cfile->flist, &cinode->openFileList);
- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&tcon->open_file_lock);

if (fid->purge_cache)
cifs_invalidate_mapping(inode);
@@ -344,16 +346,16 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
struct cifsFileInfo *
cifsFileInfo_get(struct cifsFileInfo *cifs_file)
{
- spin_lock(&cifs_file_list_lock);
+ spin_lock(&cifs_file->file_info_lock);
cifsFileInfo_get_locked(cifs_file);
- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&cifs_file->file_info_lock);
return cifs_file;
}

/*
* Release a reference on the file private data. This may involve closing
* the filehandle out on the server. Must be called without holding
- * cifs_file_list_lock.
+ * tcon->open_file_lock and cifs_file->file_info_lock.
*/
void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
{
@@ -368,11 +370,15 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
struct cifs_pending_open open;
bool oplock_break_cancelled;

- spin_lock(&cifs_file_list_lock);
+ spin_lock(&tcon->open_file_lock);
+
+ spin_lock(&cifs_file->file_info_lock);
if (--cifs_file->count > 0) {
- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&cifs_file->file_info_lock);
+ spin_unlock(&tcon->open_file_lock);
return;
}
+ spin_unlock(&cifs_file->file_info_lock);

if (server->ops->get_lease_key)
server->ops->get_lease_key(inode, &fid);
@@ -396,7 +402,8 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
CIFS_I(inode)->invalid_mapping = true;
cifs_set_oplock_level(cifsi, 0);
}
- spin_unlock(&cifs_file_list_lock);
+
+ spin_unlock(&tcon->open_file_lock);

oplock_break_cancelled = cancel_work_sync(&cifs_file->oplock_break);

@@ -765,10 +772,10 @@ int cifs_closedir(struct inode *inode, struct file *file)
server = tcon->ses->server;

cifs_dbg(FYI, "Freeing private data in close dir\n");
- spin_lock(&cifs_file_list_lock);
+ spin_lock(&cfile->file_info_lock);
if (server->ops->dir_needs_close(cfile)) {
cfile->invalidHandle = true;
- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&cfile->file_info_lock);
if (server->ops->close_dir)
rc = server->ops->close_dir(xid, tcon, &cfile->fid);
else
@@ -777,7 +784,7 @@ int cifs_closedir(struct inode *inode, struct file *file)
/* not much we can do if it fails anyway, ignore rc */
rc = 0;
} else
- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&cfile->file_info_lock);

buf = cfile->srch_inf.ntwrk_buf_start;
if (buf) {
@@ -1719,12 +1726,13 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
{
struct cifsFileInfo *open_file = NULL;
struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
+ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);

/* only filter by fsuid on multiuser mounts */
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
fsuid_only = false;

- spin_lock(&cifs_file_list_lock);
+ spin_lock(&tcon->open_file_lock);
/* we could simply get the first_list_entry since write-only entries
are always at the end of the list but since the first entry might
have a close pending, we go through the whole list */
@@ -1735,8 +1743,8 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
if (!open_file->invalidHandle) {
/* found a good file */
/* lock it so it will not be closed on us */
- cifsFileInfo_get_locked(open_file);
- spin_unlock(&cifs_file_list_lock);
+ cifsFileInfo_get(open_file);
+ spin_unlock(&tcon->open_file_lock);
return open_file;
} /* else might as well continue, and look for
another, or simply have the caller reopen it
@@ -1744,7 +1752,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
} else /* write only file */
break; /* write only files are last so must be done */
}
- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&tcon->open_file_lock);
return NULL;
}

@@ -1753,6 +1761,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
{
struct cifsFileInfo *open_file, *inv_file = NULL;
struct cifs_sb_info *cifs_sb;
+ struct cifs_tcon *tcon;
bool any_available = false;
int rc;
unsigned int refind = 0;
@@ -1768,15 +1777,16 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
}

cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
+ tcon = cifs_sb_master_tcon(cifs_sb);

/* only filter by fsuid on multiuser mounts */
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
fsuid_only = false;

- spin_lock(&cifs_file_list_lock);
+ spin_lock(&tcon->open_file_lock);
refind_writable:
if (refind > MAX_REOPEN_ATT) {
- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&tcon->open_file_lock);
return NULL;
}
list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
@@ -1787,8 +1797,8 @@ refind_writable:
if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) {
if (!open_file->invalidHandle) {
/* found a good writable file */
- cifsFileInfo_get_locked(open_file);
- spin_unlock(&cifs_file_list_lock);
+ cifsFileInfo_get(open_file);
+ spin_unlock(&tcon->open_file_lock);
return open_file;
} else {
if (!inv_file)
@@ -1804,24 +1814,24 @@ refind_writable:

if (inv_file) {
any_available = false;
- cifsFileInfo_get_locked(inv_file);
+ cifsFileInfo_get(inv_file);
}

- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&tcon->open_file_lock);

if (inv_file) {
rc = cifs_reopen_file(inv_file, false);
if (!rc)
return inv_file;
else {
- spin_lock(&cifs_file_list_lock);
+ spin_lock(&tcon->open_file_lock);
list_move_tail(&inv_file->flist,
&cifs_inode->openFileList);
- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&tcon->open_file_lock);
cifsFileInfo_put(inv_file);
- spin_lock(&cifs_file_list_lock);
++refind;
inv_file = NULL;
+ spin_lock(&tcon->open_file_lock);
goto refind_writable;
}
}
@@ -3505,15 +3515,17 @@ static int cifs_readpage(struct file *file, struct page *page)
static int is_inode_writable(struct cifsInodeInfo *cifs_inode)
{
struct cifsFileInfo *open_file;
+ struct cifs_tcon *tcon =
+ cifs_sb_master_tcon(CIFS_SB(cifs_inode->vfs_inode.i_sb));

- spin_lock(&cifs_file_list_lock);
+ spin_lock(&tcon->open_file_lock);
list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) {
- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&tcon->open_file_lock);
return 1;
}
}
- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&tcon->open_file_lock);
return 0;
}

diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 912a52e5e8cc..e360c9494b00 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -120,6 +120,7 @@ tconInfoAlloc(void)
++ret_buf->tc_count;
INIT_LIST_HEAD(&ret_buf->openFileList);
INIT_LIST_HEAD(&ret_buf->tcon_list);
+ spin_lock_init(&ret_buf->open_file_lock);
#ifdef CONFIG_CIFS_STATS
spin_lock_init(&ret_buf->stat_lock);
#endif
@@ -462,7 +463,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
continue;

cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks);
- spin_lock(&cifs_file_list_lock);
+ spin_lock(&tcon->open_file_lock);
list_for_each(tmp2, &tcon->openFileList) {
netfile = list_entry(tmp2, struct cifsFileInfo,
tlist);
@@ -492,11 +493,11 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
&netfile->oplock_break);
netfile->oplock_break_cancelled = false;

- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&tcon->open_file_lock);
spin_unlock(&cifs_tcp_ses_lock);
return true;
}
- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&tcon->open_file_lock);
spin_unlock(&cifs_tcp_ses_lock);
cifs_dbg(FYI, "No matching file for oplock break\n");
return true;
@@ -645,9 +646,9 @@ backup_cred(struct cifs_sb_info *cifs_sb)
void
cifs_del_pending_open(struct cifs_pending_open *open)
{
- spin_lock(&cifs_file_list_lock);
+ spin_lock(&tlink_tcon(open->tlink)->open_file_lock);
list_del(&open->olist);
- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&tlink_tcon(open->tlink)->open_file_lock);
}

void
@@ -667,7 +668,7 @@ void
cifs_add_pending_open(struct cifs_fid *fid, struct tcon_link *tlink,
struct cifs_pending_open *open)
{
- spin_lock(&cifs_file_list_lock);
+ spin_lock(&tlink_tcon(tlink)->open_file_lock);
cifs_add_pending_open_locked(fid, tlink, open);
- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&tlink_tcon(open->tlink)->open_file_lock);
}
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 5454aff19d18..a4e276e65b0a 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -592,14 +592,14 @@ find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon, loff_t pos,
is_dir_changed(file)) || (index_to_find < first_entry_in_buffer)) {
/* close and restart search */
cifs_dbg(FYI, "search backing up - close and restart search\n");
- spin_lock(&cifs_file_list_lock);
+ spin_lock(&cfile->file_info_lock);
if (server->ops->dir_needs_close(cfile)) {
cfile->invalidHandle = true;
- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&cfile->file_info_lock);
if (server->ops->close_dir)
server->ops->close_dir(xid, tcon, &cfile->fid);
} else
- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&cfile->file_info_lock);
if (cfile->srch_inf.ntwrk_buf_start) {
cifs_dbg(FYI, "freeing SMB ff cache buf on search rewind\n");
if (cfile->srch_inf.smallBuf)
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
index b8021fde987d..579645d87f93 100644
--- a/fs/cifs/smb2misc.c
+++ b/fs/cifs/smb2misc.c
@@ -502,19 +502,19 @@ smb2_is_valid_lease_break(char *buffer)
list_for_each(tmp1, &server->smb_ses_list) {
ses = list_entry(tmp1, struct cifs_ses, smb_ses_list);

- spin_lock(&cifs_file_list_lock);
list_for_each(tmp2, &ses->tcon_list) {
tcon = list_entry(tmp2, struct cifs_tcon,
tcon_list);
+ spin_lock(&tcon->open_file_lock);
cifs_stats_inc(
&tcon->stats.cifs_stats.num_oplock_brks);
if (smb2_tcon_has_lease(tcon, rsp, lw)) {
- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&tcon->open_file_lock);
spin_unlock(&cifs_tcp_ses_lock);
return true;
}
+ spin_unlock(&tcon->open_file_lock);
}
- spin_unlock(&cifs_file_list_lock);
}
}
spin_unlock(&cifs_tcp_ses_lock);
@@ -556,7 +556,7 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);

cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks);
- spin_lock(&cifs_file_list_lock);
+ spin_lock(&tcon->open_file_lock);
list_for_each(tmp2, &tcon->openFileList) {
cfile = list_entry(tmp2, struct cifsFileInfo,
tlist);
@@ -568,7 +568,7 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)

cifs_dbg(FYI, "file id match, oplock break\n");
cinode = CIFS_I(cfile->dentry->d_inode);
-
+ spin_lock(&cfile->file_info_lock);
if (!CIFS_CACHE_WRITE(cinode) &&
rsp->OplockLevel == SMB2_OPLOCK_LEVEL_NONE)
cfile->oplock_break_cancelled = true;
@@ -590,14 +590,14 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
clear_bit(
CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
&cinode->flags);
-
+ spin_unlock(&cfile->file_info_lock);
queue_work(cifsiod_wq, &cfile->oplock_break);

- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&tcon->open_file_lock);
spin_unlock(&cifs_tcp_ses_lock);
return true;
}
- spin_unlock(&cifs_file_list_lock);
+ spin_unlock(&tcon->open_file_lock);
spin_unlock(&cifs_tcp_ses_lock);
cifs_dbg(FYI, "No matching file for oplock break\n");
return true;
--
2.10.2

2016-11-07 13:05:44

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 14/72] pstore/ram: Use memcpy_fromio() to save old buffer

From: Andrew Bresticker <[email protected]>

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

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

commit d771fdf94180de2bd811ac90cba75f0f346abf8d upstream.

The ramoops buffer may be mapped as either I/O memory or uncached
memory. On ARM64, this results in a device-type (strongly-ordered)
mapping. Since unnaligned accesses to device-type memory will
generate an alignment fault (regardless of whether or not strict
alignment checking is enabled), it is not safe to use memcpy().
memcpy_fromio() is guaranteed to only use aligned accesses, so use
that instead.

Signed-off-by: Andrew Bresticker <[email protected]>
Signed-off-by: Enric Balletbo Serra <[email protected]>
Reviewed-by: Puneet Kumar <[email protected]>
Signed-off-by: Kees Cook <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/pstore/ram_core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c
index eb42483dbb05..7df456db7c33 100644
--- a/fs/pstore/ram_core.c
+++ b/fs/pstore/ram_core.c
@@ -286,8 +286,8 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz)
}

prz->old_log_size = size;
- memcpy(prz->old_log, &buffer->data[start], size - start);
- memcpy(prz->old_log + size - start, &buffer->data[0], start);
+ memcpy_fromio(prz->old_log, &buffer->data[start], size - start);
+ memcpy_fromio(prz->old_log + size - start, &buffer->data[0], start);
}

int notrace persistent_ram_write(struct persistent_ram_zone *prz,
--
2.10.2

2016-11-07 13:14:04

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 42/72] compiler: Allow 1- and 2-byte smp_load_acquire() and smp_store_release()

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

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

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

commit 536fa402221f09633e7c5801b327055ab716a363 upstream.

CPUs without single-byte and double-byte loads and stores place some
"interesting" requirements on concurrent code. For example (adapted
from Peter Hurley's test code), suppose we have the following structure:

struct foo {
spinlock_t lock1;
spinlock_t lock2;
char a; /* Protected by lock1. */
char b; /* Protected by lock2. */
};
struct foo *foop;

Of course, it is common (and good) practice to place data protected
by different locks in separate cache lines. However, if the locks are
rarely acquired (for example, only in rare error cases), and there are
a great many instances of the data structure, then memory footprint can
trump false-sharing concerns, so that it can be better to place them in
the same cache cache line as above.

But if the CPU does not support single-byte loads and stores, a store
to foop->a will do a non-atomic read-modify-write operation on foop->b,
which will come as a nasty surprise to someone holding foop->lock2. So we
now require CPUs to support single-byte and double-byte loads and stores.
Therefore, this commit adjusts the definition of __native_word() to allow
these sizes to be used by smp_load_acquire() and smp_store_release().

Signed-off-by: Paul E. McKenney <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
include/linux/compiler.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 913532c0c140..f968eefaf1e8 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -362,7 +362,7 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s

/* Is this type a native word size -- useful for atomic operations */
#ifndef __native_word
-# define __native_word(t) (sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
+# define __native_word(t) (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
#endif

/* Compile time object size, -1 for unknown */
--
2.10.2

2016-11-07 13:14:27

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 39/72] NFSv4: Open state recovery must account for file permission changes

From: Trond Myklebust <[email protected]>

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

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

commit 304020fe48c6c7fff8b5a38f382b54404f0f79d3 upstream.

If the file permissions change on the server, then we may not be able to
recover open state. If so, we need to ensure that we mark the file
descriptor appropriately.

Signed-off-by: Trond Myklebust <[email protected]>
Tested-by: Oleg Drokin <[email protected]>
Signed-off-by: Anna Schumaker <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/nfs/nfs4state.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index fbe7e2f90a3c..e9eda0d5ba60 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1448,6 +1448,9 @@ restart:
"Zeroing state\n", __func__, status);
case -ENOENT:
case -ENOMEM:
+ case -EACCES:
+ case -EROFS:
+ case -EIO:
case -ESTALE:
/*
* Open state on this file cannot be recovered
--
2.10.2

2016-11-07 13:14:44

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 38/72] Input: elantech - add Fujitsu Lifebook E556 to force crc_enabled

From: Dmitry Torokhov <[email protected]>

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

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

commit 62837b3c1a95535d1a287c9c8c6563bbd8d37033 upstream.

Another Lifebook machine that needs the same quirk as other similar
models to make the driver working.

Also let's reorder elantech_dmi_force_crc_enabled list so LIfebook enries
are in alphabetical order.

Reported-by: William Linna <[email protected]>
Tested-by: William Linna <[email protected]>
Reviewed-by: Benjamin Tissoires <[email protected]>
Signed-off-by: Dmitry Torokhov <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/input/mouse/elantech.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index f24062ab80f6..a25fc40522f3 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -1396,6 +1396,13 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = {
},
},
{
+ /* Fujitsu LIFEBOOK E544 does not work with crc_enabled == 0 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E544"),
+ },
+ },
+ {
/* Fujitsu LIFEBOOK E554 does not work with crc_enabled == 0 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
@@ -1403,10 +1410,10 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = {
},
},
{
- /* Fujitsu LIFEBOOK E544 does not work with crc_enabled == 0 */
+ /* Fujitsu LIFEBOOK E556 does not work with crc_enabled == 0 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
- DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E544"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E556"),
},
},
{
--
2.10.2

2016-11-07 13:14:42

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 37/72] Input: elantech - force needed quirks on Fujitsu H760

From: Matti Kurkela <[email protected]>

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

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

commit f9a703a54d16ba2470391c4b12236ee56591d50c upstream.

Just like Fujitsu CELSIUS H730, the H760 also has an Elantech touchpad with
the same quirks. Without this patch, the touchpad is useless out-of-the-box
as the mouse pointer won't move.

This patch makes the driver aware of both the crc_enabled=1 requirement and
the middle button, making the touchpad fully functional out-of-the-box.

Signed-off-by: Matti Kurkela <[email protected]>
Signed-off-by: Dmitry Torokhov <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/input/mouse/elantech.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index cbe20b0099a2..f24062ab80f6 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -1389,6 +1389,13 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = {
},
},
{
+ /* Fujitsu H760 does not work with crc_enabled == 0 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H760"),
+ },
+ },
+ {
/* Fujitsu LIFEBOOK E554 does not work with crc_enabled == 0 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
@@ -1402,6 +1409,13 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E544"),
},
},
+ {
+ /* Fujitsu H760 also has a middle button */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H760"),
+ },
+ },
#endif
{ }
};
--
2.10.2

2016-11-07 13:15:15

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 35/72] cx231xx: fix GPIOs for Pixelview SBTVD hybrid

From: Mauro Carvalho Chehab <[email protected]>

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

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

commit 24b923f073ac37eb744f56a2c7f77107b8219ab2 upstream.

This device uses GPIOs: 28 to switch between analog and
digital modes: on digital mode, it should be set to 1.

The code that sets it on analog mode is OK, but it misses
the logic that sets it on digital mode.

Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/media/usb/cx231xx/cx231xx-cards.c | 2 +-
drivers/media/usb/cx231xx/cx231xx-core.c | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index a384f80f595e..0c106f34ab66 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -489,7 +489,7 @@ struct cx231xx_board cx231xx_boards[] = {
.output_mode = OUT_MODE_VIP11,
.demod_xfer_mode = 0,
.ctl_pin_status_mask = 0xFFFFFFC4,
- .agc_analog_digital_select_gpio = 0x00, /* According with PV cxPolaris.inf file */
+ .agc_analog_digital_select_gpio = 0x1c,
.tuner_sif_gpio = -1,
.tuner_scl_gpio = -1,
.tuner_sda_gpio = -1,
diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c
index 4ba3ce09b713..6f5ffcc19356 100644
--- a/drivers/media/usb/cx231xx/cx231xx-core.c
+++ b/drivers/media/usb/cx231xx/cx231xx-core.c
@@ -723,6 +723,7 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode)
break;
case CX231XX_BOARD_CNXT_RDE_253S:
case CX231XX_BOARD_CNXT_RDU_253S:
+ case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1);
break;
case CX231XX_BOARD_HAUPPAUGE_EXETER:
@@ -747,7 +748,7 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode)
case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL:
case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC:
- errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0);
+ errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0);
break;
default:
break;
--
2.10.2

2016-11-07 13:15:18

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 34/72] cx231xx: don't return error on success

From: Mauro Carvalho Chehab <[email protected]>

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

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

commit 1871d718a9db649b70f0929d2778dc01bc49b286 upstream.

The cx231xx_set_agc_analog_digital_mux_select() callers
expect it to return 0 or an error. Returning a positive value
makes the first attempt to switch between analog/digital to fail.

Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/media/usb/cx231xx/cx231xx-avcore.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c
index 89de00bf4f82..bd45858cc927 100644
--- a/drivers/media/usb/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c
@@ -1260,7 +1260,10 @@ int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev,
dev->board.agc_analog_digital_select_gpio,
analog_or_digital);

- return status;
+ if (status < 0)
+ return status;
+
+ return 0;
}

int cx231xx_enable_i2c_port_3(struct cx231xx *dev, bool is_port_3)
--
2.10.2

2016-11-07 13:15:10

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 36/72] MIPS: ptrace: Fix regs_return_value for kernel context

From: Marcin Nowakowski <[email protected]>

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

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

commit 74f1077b5b783e7bf4fa3007cefdc8dbd6c07518 upstream.

Currently regs_return_value always negates reg[2] if it determines
the syscall has failed, but when called in kernel context this check is
invalid and may result in returning a wrong value.

This fixes errors reported by CONFIG_KPROBES_SANITY_TEST

Fixes: d7e7528bcd45 ("Audit: push audit success and retcode into arch ptrace.h")
Signed-off-by: Marcin Nowakowski <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/14381/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/mips/include/asm/ptrace.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h
index 5e6cd0947393..a288de2199d8 100644
--- a/arch/mips/include/asm/ptrace.h
+++ b/arch/mips/include/asm/ptrace.h
@@ -73,7 +73,7 @@ static inline int is_syscall_success(struct pt_regs *regs)

static inline long regs_return_value(struct pt_regs *regs)
{
- if (is_syscall_success(regs))
+ if (is_syscall_success(regs) || !user_mode(regs))
return regs->regs[2];
else
return -regs->regs[2];
--
2.10.2

2016-11-07 13:16:47

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 33/72] mb86a20s: fix demod settings

From: Mauro Carvalho Chehab <[email protected]>

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

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

commit 505a0ea706fc1db4381baa6c6bd2e596e730a55e upstream.

With the current settings, only one channel locks properly.
That's likely because, when this driver was written, Brazil
were still using experimental transmissions.

Change it to reproduce the settings used by the newer drivers.
That makes it lock on other channels.

Tested with both PixelView SBTVD Hybrid (cx231xx-based) and
C3Tech Digital Duo HDTV/SDTV (em28xx-based) devices.

Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/media/dvb-frontends/mb86a20s.c | 92 ++++++++++++++++------------------
1 file changed, 42 insertions(+), 50 deletions(-)

diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c
index 3fbac5fd4d32..4a1346fb383e 100644
--- a/drivers/media/dvb-frontends/mb86a20s.c
+++ b/drivers/media/dvb-frontends/mb86a20s.c
@@ -75,25 +75,27 @@ static struct regdata mb86a20s_init1[] = {
};

static struct regdata mb86a20s_init2[] = {
- { 0x28, 0x22 }, { 0x29, 0x00 }, { 0x2a, 0x1f }, { 0x2b, 0xf0 },
+ { 0x50, 0xd1 }, { 0x51, 0x22 },
+ { 0x39, 0x01 },
+ { 0x71, 0x00 },
{ 0x3b, 0x21 },
- { 0x3c, 0x38 },
+ { 0x3c, 0x3a },
{ 0x01, 0x0d },
- { 0x04, 0x08 }, { 0x05, 0x03 },
+ { 0x04, 0x08 }, { 0x05, 0x05 },
{ 0x04, 0x0e }, { 0x05, 0x00 },
- { 0x04, 0x0f }, { 0x05, 0x37 },
- { 0x04, 0x0b }, { 0x05, 0x78 },
+ { 0x04, 0x0f }, { 0x05, 0x14 },
+ { 0x04, 0x0b }, { 0x05, 0x8c },
{ 0x04, 0x00 }, { 0x05, 0x00 },
- { 0x04, 0x01 }, { 0x05, 0x1e },
- { 0x04, 0x02 }, { 0x05, 0x07 },
- { 0x04, 0x03 }, { 0x05, 0xd0 },
+ { 0x04, 0x01 }, { 0x05, 0x07 },
+ { 0x04, 0x02 }, { 0x05, 0x0f },
+ { 0x04, 0x03 }, { 0x05, 0xa0 },
{ 0x04, 0x09 }, { 0x05, 0x00 },
{ 0x04, 0x0a }, { 0x05, 0xff },
- { 0x04, 0x27 }, { 0x05, 0x00 },
+ { 0x04, 0x27 }, { 0x05, 0x64 },
{ 0x04, 0x28 }, { 0x05, 0x00 },
- { 0x04, 0x1e }, { 0x05, 0x00 },
- { 0x04, 0x29 }, { 0x05, 0x64 },
- { 0x04, 0x32 }, { 0x05, 0x02 },
+ { 0x04, 0x1e }, { 0x05, 0xff },
+ { 0x04, 0x29 }, { 0x05, 0x0a },
+ { 0x04, 0x32 }, { 0x05, 0x0a },
{ 0x04, 0x14 }, { 0x05, 0x02 },
{ 0x04, 0x04 }, { 0x05, 0x00 },
{ 0x04, 0x05 }, { 0x05, 0x22 },
@@ -101,8 +103,6 @@ static struct regdata mb86a20s_init2[] = {
{ 0x04, 0x07 }, { 0x05, 0xd8 },
{ 0x04, 0x12 }, { 0x05, 0x00 },
{ 0x04, 0x13 }, { 0x05, 0xff },
- { 0x04, 0x15 }, { 0x05, 0x4e },
- { 0x04, 0x16 }, { 0x05, 0x20 },

/*
* On this demod, when the bit count reaches the count below,
@@ -156,42 +156,36 @@ static struct regdata mb86a20s_init2[] = {
{ 0x50, 0x51 }, { 0x51, 0x04 }, /* MER symbol 4 */
{ 0x45, 0x04 }, /* CN symbol 4 */
{ 0x48, 0x04 }, /* CN manual mode */
-
+ { 0x50, 0xd5 }, { 0x51, 0x01 },
{ 0x50, 0xd6 }, { 0x51, 0x1f },
{ 0x50, 0xd2 }, { 0x51, 0x03 },
- { 0x50, 0xd7 }, { 0x51, 0xbf },
- { 0x28, 0x74 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0xff },
- { 0x28, 0x46 }, { 0x29, 0x00 }, { 0x2a, 0x1a }, { 0x2b, 0x0c },
-
- { 0x04, 0x40 }, { 0x05, 0x00 },
- { 0x28, 0x00 }, { 0x2b, 0x08 },
- { 0x28, 0x05 }, { 0x2b, 0x00 },
+ { 0x50, 0xd7 }, { 0x51, 0x3f },
{ 0x1c, 0x01 },
- { 0x28, 0x06 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x1f },
- { 0x28, 0x07 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x18 },
- { 0x28, 0x08 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x12 },
- { 0x28, 0x09 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x30 },
- { 0x28, 0x0a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x37 },
- { 0x28, 0x0b }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x02 },
- { 0x28, 0x0c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x09 },
- { 0x28, 0x0d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x06 },
- { 0x28, 0x0e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x7b },
- { 0x28, 0x0f }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x76 },
- { 0x28, 0x10 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x7d },
- { 0x28, 0x11 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x08 },
- { 0x28, 0x12 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0b },
- { 0x28, 0x13 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x00 },
- { 0x28, 0x14 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xf2 },
- { 0x28, 0x15 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xf3 },
- { 0x28, 0x16 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x05 },
- { 0x28, 0x17 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x16 },
- { 0x28, 0x18 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0f },
- { 0x28, 0x19 }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xef },
- { 0x28, 0x1a }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xd8 },
- { 0x28, 0x1b }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xf1 },
- { 0x28, 0x1c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x3d },
- { 0x28, 0x1d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x94 },
- { 0x28, 0x1e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0xba },
+ { 0x28, 0x06 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x03 },
+ { 0x28, 0x07 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0d },
+ { 0x28, 0x08 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x02 },
+ { 0x28, 0x09 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x01 },
+ { 0x28, 0x0a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x21 },
+ { 0x28, 0x0b }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x29 },
+ { 0x28, 0x0c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x16 },
+ { 0x28, 0x0d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x31 },
+ { 0x28, 0x0e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0e },
+ { 0x28, 0x0f }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x4e },
+ { 0x28, 0x10 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x46 },
+ { 0x28, 0x11 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0f },
+ { 0x28, 0x12 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x56 },
+ { 0x28, 0x13 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x35 },
+ { 0x28, 0x14 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbe },
+ { 0x28, 0x15 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0x84 },
+ { 0x28, 0x16 }, { 0x29, 0x00 }, { 0x2a, 0x03 }, { 0x2b, 0xee },
+ { 0x28, 0x17 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x98 },
+ { 0x28, 0x18 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x9f },
+ { 0x28, 0x19 }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xb2 },
+ { 0x28, 0x1a }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0xc2 },
+ { 0x28, 0x1b }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0x4a },
+ { 0x28, 0x1c }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbc },
+ { 0x28, 0x1d }, { 0x29, 0x00 }, { 0x2a, 0x04 }, { 0x2b, 0xba },
+ { 0x28, 0x1e }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0x14 },
{ 0x50, 0x1e }, { 0x51, 0x5d },
{ 0x50, 0x22 }, { 0x51, 0x00 },
{ 0x50, 0x23 }, { 0x51, 0xc8 },
@@ -200,9 +194,7 @@ static struct regdata mb86a20s_init2[] = {
{ 0x50, 0x26 }, { 0x51, 0x00 },
{ 0x50, 0x27 }, { 0x51, 0xc3 },
{ 0x50, 0x39 }, { 0x51, 0x02 },
- { 0xec, 0x0f },
- { 0xeb, 0x1f },
- { 0x28, 0x6a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x00 },
+ { 0x50, 0xd5 }, { 0x51, 0x01 },
{ 0xd0, 0x00 },
};

--
2.10.2

2016-11-07 13:17:23

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 30/72] scsi: zfcp: spin_lock_irqsave() is not nestable

From: Dan Carpenter <[email protected]>

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

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

commit e7cb08e894a0b876443ef8fdb0706575dc00a5d2 upstream.

We accidentally overwrite the original saved value of "flags" so that we
can't re-enable IRQs at the end of the function. Presumably this
function is mostly called with IRQs disabled or it would be obvious in
testing.

Fixes: aceeffbb59bb ("zfcp: trace full payload of all SAN records (req,resp,iels)")
Signed-off-by: Dan Carpenter <[email protected]>
Signed-off-by: Steffen Maier <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/s390/scsi/zfcp_dbf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 589db1db6dd2..371aed75eb83 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -384,7 +384,7 @@ void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf,
/* if (len > rec_len):
* dump data up to cap_len ignoring small duplicate in rec->payload
*/
- spin_lock_irqsave(&dbf->pay_lock, flags);
+ spin_lock(&dbf->pay_lock);
memset(payload, 0, sizeof(*payload));
memcpy(payload->area, paytag, ZFCP_DBF_TAG_LEN);
payload->fsf_req_id = req_id;
--
2.10.2

2016-11-07 13:17:26

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 28/72] zfcp: fix payload trace length for SAN request&response

From: Steffen Maier <[email protected]>

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

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

commit 94db3725f049ead24c96226df4a4fb375b880a77 upstream.

commit 2c55b750a884b86dea8b4cc5f15e1484cc47a25c
("[SCSI] zfcp: Redesign of the debug tracing for SAN records.")
started to add FC_CT_HDR_LEN which made zfcp dump random data
out of bounds for RSPN GS responses because u.rspn.rsp
is the largest and last field in the union of struct zfcp_fc_req.
Other request/response types only happened to stay within bounds
due to the padding of the union or
due to the trace capping of u.gspn.rsp to ZFCP_DBF_SAN_MAX_PAYLOAD.

Timestamp : ...
Area : SAN
Subarea : 00
Level : 1
Exception : -
CPU id : ..
Caller : ...
Record id : 2
Tag : fsscth2
Request id : 0x...
Destination ID : 0x00fffffc
Payload short : 01000000 fc020000 80020000 00000000
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx <===
00000000 00000000 00000000 00000000
Payload length : 32 <===

struct zfcp_fc_req {
[0] struct zfcp_fsf_ct_els ct_els;
[56] struct scatterlist sg_req;
[96] struct scatterlist sg_rsp;
union {
struct {req; rsp;} adisc; SIZE: 28+28= 56
struct {req; rsp;} gid_pn; SIZE: 24+20= 44
struct {rspsg; req;} gpn_ft; SIZE: 40*4+20=180
struct {req; rsp;} gspn; SIZE: 20+273= 293
struct {req; rsp;} rspn; SIZE: 277+16= 293
[136] } u;
}
SIZE: 432

Signed-off-by: Steffen Maier <[email protected]>
Fixes: 2c55b750a884 ("[SCSI] zfcp: Redesign of the debug tracing for SAN records.")
Reviewed-by: Alexey Ishchuk <[email protected]>
Reviewed-by: Benjamin Block <[email protected]>
Reviewed-by: Hannes Reinecke <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/s390/scsi/zfcp_dbf.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 9bab228ef7ac..b8712c4d7f58 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -389,7 +389,7 @@ void zfcp_dbf_san_req(char *tag, struct zfcp_fsf_req *fsf, u32 d_id)
struct zfcp_fsf_ct_els *ct_els = fsf->data;
u16 length;

- length = (u16)(ct_els->req->length + FC_CT_HDR_LEN);
+ length = (u16)(ct_els->req->length);
zfcp_dbf_san(tag, dbf, sg_virt(ct_els->req), ZFCP_DBF_SAN_REQ, length,
fsf->req_id, d_id);
}
@@ -405,7 +405,7 @@ void zfcp_dbf_san_res(char *tag, struct zfcp_fsf_req *fsf)
struct zfcp_fsf_ct_els *ct_els = fsf->data;
u16 length;

- length = (u16)(ct_els->resp->length + FC_CT_HDR_LEN);
+ length = (u16)(ct_els->resp->length);
zfcp_dbf_san(tag, dbf, sg_virt(ct_els->resp), ZFCP_DBF_SAN_RES, length,
fsf->req_id, ct_els->d_id);
}
--
2.10.2

2016-11-07 13:17:37

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 25/72] zfcp: trace on request for open and close of WKA port

From: Steffen Maier <[email protected]>

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

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

commit d27a7cb91960cf1fdd11b10071e601828cbf4b1f upstream.

Since commit a54ca0f62f953898b05549391ac2a8a4dad6482b
("[SCSI] zfcp: Redesign of the debug tracing for HBA records.")
HBA records no longer contain WWPN, D_ID, or LUN
to reduce duplicate information which is already in REC records.
In contrast to "regular" target ports, we don't use recovery to open
WKA ports such as directory/nameserver, so we don't get REC records.
Therefore, introduce pseudo REC running records without any
actual recovery action but including D_ID of WKA port on open/close.

Signed-off-by: Steffen Maier <[email protected]>
Fixes: a54ca0f62f95 ("[SCSI] zfcp: Redesign of the debug tracing for HBA records.")
Reviewed-by: Benjamin Block <[email protected]>
Reviewed-by: Hannes Reinecke <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/s390/scsi/zfcp_dbf.c | 32 ++++++++++++++++++++++++++++++++
drivers/s390/scsi/zfcp_ext.h | 1 +
drivers/s390/scsi/zfcp_fsf.c | 8 ++++++--
3 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 311773280bac..b65de8ae5ef3 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -321,6 +321,38 @@ void zfcp_dbf_rec_run(char *tag, struct zfcp_erp_action *erp)
spin_unlock_irqrestore(&dbf->rec_lock, flags);
}

+/**
+ * zfcp_dbf_rec_run_wka - trace wka port event with info like running recovery
+ * @tag: identifier for event
+ * @wka_port: well known address port
+ * @req_id: request ID to correlate with potential HBA trace record
+ */
+void zfcp_dbf_rec_run_wka(char *tag, struct zfcp_fc_wka_port *wka_port,
+ u64 req_id)
+{
+ struct zfcp_dbf *dbf = wka_port->adapter->dbf;
+ struct zfcp_dbf_rec *rec = &dbf->rec_buf;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dbf->rec_lock, flags);
+ memset(rec, 0, sizeof(*rec));
+
+ rec->id = ZFCP_DBF_REC_RUN;
+ memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+ rec->port_status = wka_port->status;
+ rec->d_id = wka_port->d_id;
+ rec->lun = ZFCP_DBF_INVALID_LUN;
+
+ rec->u.run.fsf_req_id = req_id;
+ rec->u.run.rec_status = ~0;
+ rec->u.run.rec_step = ~0;
+ rec->u.run.rec_action = ~0;
+ rec->u.run.rec_count = ~0;
+
+ debug_event(dbf->rec, 1, rec, sizeof(*rec));
+ spin_unlock_irqrestore(&dbf->rec_lock, flags);
+}
+
static inline
void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, void *data, u8 id, u16 len,
u64 req_id, u32 d_id)
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 673f85103d72..1f1fe41ecb97 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -35,6 +35,7 @@ extern void zfcp_dbf_adapter_unregister(struct zfcp_adapter *);
extern void zfcp_dbf_rec_trig(char *, struct zfcp_adapter *,
struct zfcp_port *, struct scsi_device *, u8, u8);
extern void zfcp_dbf_rec_run(char *, struct zfcp_erp_action *);
+extern void zfcp_dbf_rec_run_wka(char *, struct zfcp_fc_wka_port *, u64);
extern void zfcp_dbf_hba_fsf_uss(char *, struct zfcp_fsf_req *);
extern void zfcp_dbf_hba_fsf_res(char *, int, struct zfcp_fsf_req *);
extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *);
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index fd015c413740..3658485e25b8 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -1582,7 +1582,7 @@ out:
int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port)
{
struct zfcp_qdio *qdio = wka_port->adapter->qdio;
- struct zfcp_fsf_req *req;
+ struct zfcp_fsf_req *req = NULL;
int retval = -EIO;

spin_lock_irq(&qdio->req_q_lock);
@@ -1611,6 +1611,8 @@ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port)
zfcp_fsf_req_free(req);
out:
spin_unlock_irq(&qdio->req_q_lock);
+ if (req && !IS_ERR(req))
+ zfcp_dbf_rec_run_wka("fsowp_1", wka_port, req->req_id);
return retval;
}

@@ -1635,7 +1637,7 @@ static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req)
int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port)
{
struct zfcp_qdio *qdio = wka_port->adapter->qdio;
- struct zfcp_fsf_req *req;
+ struct zfcp_fsf_req *req = NULL;
int retval = -EIO;

spin_lock_irq(&qdio->req_q_lock);
@@ -1664,6 +1666,8 @@ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port)
zfcp_fsf_req_free(req);
out:
spin_unlock_irq(&qdio->req_q_lock);
+ if (req && !IS_ERR(req))
+ zfcp_dbf_rec_run_wka("fscwp_1", wka_port, req->req_id);
return retval;
}

--
2.10.2

2016-11-07 13:17:44

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 24/72] zfcp: restore: Dont use 0 to indicate invalid LUN in rec trace

From: Steffen Maier <[email protected]>

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

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

commit 0102a30a6ff60f4bb4c07358ca3b1f92254a6c25 upstream.

bring back
commit d21e9daa63e009ce5b87bbcaa6d11ce48e07bbbe
("[SCSI] zfcp: Dont use 0 to indicate invalid LUN in rec trace")
which was lost with
commit ae0904f60fab7cb20c48d32eefdd735e478b91fb
("[SCSI] zfcp: Redesign of the debug tracing for recovery actions.")

Signed-off-by: Steffen Maier <[email protected]>
Fixes: ae0904f60fab ("[SCSI] zfcp: Redesign of the debug tracing for recovery actions.")
Reviewed-by: Benjamin Block <[email protected]>
Reviewed-by: Hannes Reinecke <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/s390/scsi/zfcp_dbf.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index bbd1ed552d7d..311773280bac 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -241,7 +241,8 @@ static void zfcp_dbf_set_common(struct zfcp_dbf_rec *rec,
if (sdev) {
rec->lun_status = atomic_read(&sdev_to_zfcp(sdev)->status);
rec->lun = zfcp_scsi_dev_lun(sdev);
- }
+ } else
+ rec->lun = ZFCP_DBF_INVALID_LUN;
}

/**
--
2.10.2

2016-11-07 13:17:34

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 26/72] zfcp: restore tracing of handle for port and LUN with HBA records

From: Steffen Maier <[email protected]>

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

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

commit 7c964ffe586bc0c3d9febe9bf97a2e4b2866e5b7 upstream.

This information was lost with
commit a54ca0f62f953898b05549391ac2a8a4dad6482b
("[SCSI] zfcp: Redesign of the debug tracing for HBA records.")
but is required to debug e.g. invalid handle situations.

Signed-off-by: Steffen Maier <[email protected]>
Fixes: a54ca0f62f95 ("[SCSI] zfcp: Redesign of the debug tracing for HBA records.")
Reviewed-by: Benjamin Block <[email protected]>
Reviewed-by: Hannes Reinecke <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/s390/scsi/zfcp_dbf.c | 2 ++
drivers/s390/scsi/zfcp_dbf.h | 2 ++
2 files changed, 4 insertions(+)

diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index b65de8ae5ef3..9bd96b37ba66 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -85,6 +85,8 @@ void zfcp_dbf_hba_fsf_res(char *tag, int level, struct zfcp_fsf_req *req)
rec->u.res.req_issued = req->issued;
rec->u.res.prot_status = q_pref->prot_status;
rec->u.res.fsf_status = q_head->fsf_status;
+ rec->u.res.port_handle = q_head->port_handle;
+ rec->u.res.lun_handle = q_head->lun_handle;

memcpy(rec->u.res.prot_status_qual, &q_pref->prot_status_qual,
FSF_PROT_STATUS_QUAL_SIZE);
diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h
index 97f46e6964d4..ac7bce8aab59 100644
--- a/drivers/s390/scsi/zfcp_dbf.h
+++ b/drivers/s390/scsi/zfcp_dbf.h
@@ -131,6 +131,8 @@ struct zfcp_dbf_hba_res {
u8 prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE];
u32 fsf_status;
u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];
+ u32 port_handle;
+ u32 lun_handle;
} __packed;

/**
--
2.10.2

2016-11-07 13:17:30

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 27/72] zfcp: fix D_ID field with actual value on tracing SAN responses

From: Steffen Maier <[email protected]>

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

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

commit 771bf03537ddfa4a4dde62ef9dfbc82e4f77ab20 upstream.

With commit 2c55b750a884b86dea8b4cc5f15e1484cc47a25c
("[SCSI] zfcp: Redesign of the debug tracing for SAN records.")
we lost the N_Port-ID where an ELS response comes from.
With commit 7c7dc196814b9e1d5cc254dc579a5fa78ae524f7
("[SCSI] zfcp: Simplify handling of ct and els requests")
we lost the N_Port-ID where a CT response comes from.
It's especially useful if the request SAN trace record
with D_ID was already lost due to trace buffer wrap.

GS uses an open WKA port handle and ELS just a D_ID, and
only for ELS we could get D_ID from QTCB bottom via zfcp_fsf_req.
To cover both cases, add a new field to zfcp_fsf_ct_els
and fill it in on request to use in SAN response trace.
Strictly speaking the D_ID on SAN response is the FC frame's S_ID.
We don't need a field for the other end which is always us.

Signed-off-by: Steffen Maier <[email protected]>
Fixes: 2c55b750a884 ("[SCSI] zfcp: Redesign of the debug tracing for SAN records.")
Fixes: 7c7dc196814b ("[SCSI] zfcp: Simplify handling of ct and els requests")
Reviewed-by: Benjamin Block <[email protected]>
Reviewed-by: Hannes Reinecke <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/s390/scsi/zfcp_dbf.c | 2 +-
drivers/s390/scsi/zfcp_fsf.c | 2 ++
drivers/s390/scsi/zfcp_fsf.h | 4 +++-
3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 9bd96b37ba66..9bab228ef7ac 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -407,7 +407,7 @@ void zfcp_dbf_san_res(char *tag, struct zfcp_fsf_req *fsf)

length = (u16)(ct_els->resp->length + FC_CT_HDR_LEN);
zfcp_dbf_san(tag, dbf, sg_virt(ct_els->resp), ZFCP_DBF_SAN_RES, length,
- fsf->req_id, 0);
+ fsf->req_id, ct_els->d_id);
}

/**
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 3658485e25b8..6065212fdeed 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -1079,6 +1079,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port,

req->handler = zfcp_fsf_send_ct_handler;
req->qtcb->header.port_handle = wka_port->handle;
+ ct->d_id = wka_port->d_id;
req->data = ct;

zfcp_dbf_san_req("fssct_1", req, wka_port->d_id);
@@ -1175,6 +1176,7 @@ int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id,

hton24(req->qtcb->bottom.support.d_id, d_id);
req->handler = zfcp_fsf_send_els_handler;
+ els->d_id = d_id;
req->data = els;

zfcp_dbf_san_req("fssels1", req, d_id);
diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h
index 57ae3ae1046d..be1c04b334c5 100644
--- a/drivers/s390/scsi/zfcp_fsf.h
+++ b/drivers/s390/scsi/zfcp_fsf.h
@@ -3,7 +3,7 @@
*
* Interface to the FSF support functions.
*
- * Copyright IBM Corp. 2002, 2010
+ * Copyright IBM Corp. 2002, 2015
*/

#ifndef FSF_H
@@ -436,6 +436,7 @@ struct zfcp_blk_drv_data {
* @handler_data: data passed to handler function
* @port: Optional pointer to port for zfcp internal ELS (only test link ADISC)
* @status: used to pass error status to calling function
+ * @d_id: Destination ID of either open WKA port for CT or of D_ID for ELS
*/
struct zfcp_fsf_ct_els {
struct scatterlist *req;
@@ -444,6 +445,7 @@ struct zfcp_fsf_ct_els {
void *handler_data;
struct zfcp_port *port;
int status;
+ u32 d_id;
};

#endif /* FSF_H */
--
2.10.2

2016-11-07 13:17:25

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 29/72] zfcp: trace full payload of all SAN records (req,resp,iels)

From: Steffen Maier <[email protected]>

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

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

commit aceeffbb59bb91404a0bda32a542d7ebf878433a upstream.

This was lost with commit 2c55b750a884b86dea8b4cc5f15e1484cc47a25c
("[SCSI] zfcp: Redesign of the debug tracing for SAN records.")
but is necessary for problem determination, e.g. to see the
currently active zone set during automatic port scan.

For the large GPN_FT response (4 pages), save space by not dumping
any empty residual entries.

Signed-off-by: Steffen Maier <[email protected]>
Fixes: 2c55b750a884 ("[SCSI] zfcp: Redesign of the debug tracing for SAN records.")
Reviewed-by: Alexey Ishchuk <[email protected]>
Reviewed-by: Benjamin Block <[email protected]>
Reviewed-by: Hannes Reinecke <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/s390/scsi/zfcp_dbf.c | 116 ++++++++++++++++++++++++++++++++++++++-----
drivers/s390/scsi/zfcp_dbf.h | 1 +
2 files changed, 104 insertions(+), 13 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index b8712c4d7f58..589db1db6dd2 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -3,7 +3,7 @@
*
* Debug traces for zfcp.
*
- * Copyright IBM Corp. 2002, 2015
+ * Copyright IBM Corp. 2002, 2016
*/

#define KMSG_COMPONENT "zfcp"
@@ -356,12 +356,15 @@ void zfcp_dbf_rec_run_wka(char *tag, struct zfcp_fc_wka_port *wka_port,
}

static inline
-void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, void *data, u8 id, u16 len,
- u64 req_id, u32 d_id)
+void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf,
+ char *paytag, struct scatterlist *sg, u8 id, u16 len,
+ u64 req_id, u32 d_id, u16 cap_len)
{
struct zfcp_dbf_san *rec = &dbf->san_buf;
u16 rec_len;
unsigned long flags;
+ struct zfcp_dbf_pay *payload = &dbf->pay_buf;
+ u16 pay_sum = 0;

spin_lock_irqsave(&dbf->san_lock, flags);
memset(rec, 0, sizeof(*rec));
@@ -369,10 +372,41 @@ void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, void *data, u8 id, u16 len,
rec->id = id;
rec->fsf_req_id = req_id;
rec->d_id = d_id;
- rec_len = min(len, (u16)ZFCP_DBF_SAN_MAX_PAYLOAD);
- memcpy(rec->payload, data, rec_len);
memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+ rec->pl_len = len; /* full length even if we cap pay below */
+ if (!sg)
+ goto out;
+ rec_len = min_t(unsigned int, sg->length, ZFCP_DBF_SAN_MAX_PAYLOAD);
+ memcpy(rec->payload, sg_virt(sg), rec_len); /* part of 1st sg entry */
+ if (len <= rec_len)
+ goto out; /* skip pay record if full content in rec->payload */
+
+ /* if (len > rec_len):
+ * dump data up to cap_len ignoring small duplicate in rec->payload
+ */
+ spin_lock_irqsave(&dbf->pay_lock, flags);
+ memset(payload, 0, sizeof(*payload));
+ memcpy(payload->area, paytag, ZFCP_DBF_TAG_LEN);
+ payload->fsf_req_id = req_id;
+ payload->counter = 0;
+ for (; sg && pay_sum < cap_len; sg = sg_next(sg)) {
+ u16 pay_len, offset = 0;
+
+ while (offset < sg->length && pay_sum < cap_len) {
+ pay_len = min((u16)ZFCP_DBF_PAY_MAX_REC,
+ (u16)(sg->length - offset));
+ /* cap_len <= pay_sum < cap_len+ZFCP_DBF_PAY_MAX_REC */
+ memcpy(payload->data, sg_virt(sg) + offset, pay_len);
+ debug_event(dbf->pay, 1, payload,
+ zfcp_dbf_plen(pay_len));
+ payload->counter++;
+ offset += pay_len;
+ pay_sum += pay_len;
+ }
+ }
+ spin_unlock(&dbf->pay_lock);

+out:
debug_event(dbf->san, 1, rec, sizeof(*rec));
spin_unlock_irqrestore(&dbf->san_lock, flags);
}
@@ -389,9 +423,62 @@ void zfcp_dbf_san_req(char *tag, struct zfcp_fsf_req *fsf, u32 d_id)
struct zfcp_fsf_ct_els *ct_els = fsf->data;
u16 length;

- length = (u16)(ct_els->req->length);
- zfcp_dbf_san(tag, dbf, sg_virt(ct_els->req), ZFCP_DBF_SAN_REQ, length,
- fsf->req_id, d_id);
+ length = (u16)zfcp_qdio_real_bytes(ct_els->req);
+ zfcp_dbf_san(tag, dbf, "san_req", ct_els->req, ZFCP_DBF_SAN_REQ,
+ length, fsf->req_id, d_id, length);
+}
+
+static u16 zfcp_dbf_san_res_cap_len_if_gpn_ft(char *tag,
+ struct zfcp_fsf_req *fsf,
+ u16 len)
+{
+ struct zfcp_fsf_ct_els *ct_els = fsf->data;
+ struct fc_ct_hdr *reqh = sg_virt(ct_els->req);
+ struct fc_ns_gid_ft *reqn = (struct fc_ns_gid_ft *)(reqh + 1);
+ struct scatterlist *resp_entry = ct_els->resp;
+ struct fc_gpn_ft_resp *acc;
+ int max_entries, x, last = 0;
+
+ if (!(memcmp(tag, "fsscth2", 7) == 0
+ && ct_els->d_id == FC_FID_DIR_SERV
+ && reqh->ct_rev == FC_CT_REV
+ && reqh->ct_in_id[0] == 0
+ && reqh->ct_in_id[1] == 0
+ && reqh->ct_in_id[2] == 0
+ && reqh->ct_fs_type == FC_FST_DIR
+ && reqh->ct_fs_subtype == FC_NS_SUBTYPE
+ && reqh->ct_options == 0
+ && reqh->_ct_resvd1 == 0
+ && reqh->ct_cmd == FC_NS_GPN_FT
+ /* reqh->ct_mr_size can vary so do not match but read below */
+ && reqh->_ct_resvd2 == 0
+ && reqh->ct_reason == 0
+ && reqh->ct_explan == 0
+ && reqh->ct_vendor == 0
+ && reqn->fn_resvd == 0
+ && reqn->fn_domain_id_scope == 0
+ && reqn->fn_area_id_scope == 0
+ && reqn->fn_fc4_type == FC_TYPE_FCP))
+ return len; /* not GPN_FT response so do not cap */
+
+ acc = sg_virt(resp_entry);
+ max_entries = (reqh->ct_mr_size * 4 / sizeof(struct fc_gpn_ft_resp))
+ + 1 /* zfcp_fc_scan_ports: bytes correct, entries off-by-one
+ * to account for header as 1st pseudo "entry" */;
+
+ /* the basic CT_IU preamble is the same size as one entry in the GPN_FT
+ * response, allowing us to skip special handling for it - just skip it
+ */
+ for (x = 1; x < max_entries && !last; x++) {
+ if (x % (ZFCP_FC_GPN_FT_ENT_PAGE + 1))
+ acc++;
+ else
+ acc = sg_virt(++resp_entry);
+
+ last = acc->fp_flags & FC_NS_FID_LAST;
+ }
+ len = min(len, (u16)(x * sizeof(struct fc_gpn_ft_resp)));
+ return len; /* cap after last entry */
}

/**
@@ -405,9 +492,10 @@ void zfcp_dbf_san_res(char *tag, struct zfcp_fsf_req *fsf)
struct zfcp_fsf_ct_els *ct_els = fsf->data;
u16 length;

- length = (u16)(ct_els->resp->length);
- zfcp_dbf_san(tag, dbf, sg_virt(ct_els->resp), ZFCP_DBF_SAN_RES, length,
- fsf->req_id, ct_els->d_id);
+ length = (u16)zfcp_qdio_real_bytes(ct_els->resp);
+ zfcp_dbf_san(tag, dbf, "san_res", ct_els->resp, ZFCP_DBF_SAN_RES,
+ length, fsf->req_id, ct_els->d_id,
+ zfcp_dbf_san_res_cap_len_if_gpn_ft(tag, fsf, length));
}

/**
@@ -421,11 +509,13 @@ void zfcp_dbf_san_in_els(char *tag, struct zfcp_fsf_req *fsf)
struct fsf_status_read_buffer *srb =
(struct fsf_status_read_buffer *) fsf->data;
u16 length;
+ struct scatterlist sg;

length = (u16)(srb->length -
offsetof(struct fsf_status_read_buffer, payload));
- zfcp_dbf_san(tag, dbf, srb->payload.data, ZFCP_DBF_SAN_ELS, length,
- fsf->req_id, ntoh24(srb->d_id));
+ sg_init_one(&sg, srb->payload.data, length);
+ zfcp_dbf_san(tag, dbf, "san_els", &sg, ZFCP_DBF_SAN_ELS, length,
+ fsf->req_id, ntoh24(srb->d_id), length);
}

/**
diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h
index ac7bce8aab59..440aa619da1d 100644
--- a/drivers/s390/scsi/zfcp_dbf.h
+++ b/drivers/s390/scsi/zfcp_dbf.h
@@ -115,6 +115,7 @@ struct zfcp_dbf_san {
u32 d_id;
#define ZFCP_DBF_SAN_MAX_PAYLOAD (FC_CT_HDR_LEN + 32)
char payload[ZFCP_DBF_SAN_MAX_PAYLOAD];
+ u16 pl_len;
} __packed;

/**
--
2.10.2

2016-11-07 13:17:20

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 31/72] fbdev/efifb: Fix 16 color palette entry calculation

From: Max Staudt <[email protected]>

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

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

commit d50b3f43db739f03fcf8c0a00664b3d2fed0496e upstream.

When using efifb with a 16-bit (5:6:5) visual, fbcon's text is rendered
in the wrong colors - e.g. text gray (#aaaaaa) is rendered as green
(#50bc50) and neighboring pixels have slightly different values
(such as #50bc78).

The reason is that fbcon loads its 16 color palette through
efifb_setcolreg(), which in turn calculates a 32-bit value to write
into memory for each palette index.
Until now, this code could only handle 8-bit visuals and didn't mask
overlapping values when ORing them.

With this patch, fbcon displays the correct colors when a qemu VM is
booted in 16-bit mode (in GRUB: "set gfxpayload=800x600x16").

Fixes: 7c83172b98e5 ("x86_64 EFI boot support: EFI frame buffer driver") # v2.6.24+
Signed-off-by: Max Staudt <[email protected]>
Acked-By: Peter Jones <[email protected]>
Signed-off-by: Tomi Valkeinen <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/video/efifb.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index fcb950031246..dbd5fb207869 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -54,9 +54,9 @@ static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green,
return 1;

if (regno < 16) {
- red >>= 8;
- green >>= 8;
- blue >>= 8;
+ red >>= 16 - info->var.red.length;
+ green >>= 16 - info->var.green.length;
+ blue >>= 16 - info->var.blue.length;
((u32 *)(info->pseudo_palette))[regno] =
(red << info->var.red.offset) |
(green << info->var.green.offset) |
--
2.10.2

2016-11-07 13:17:16

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 32/72] mb86a20s: fix the locking logic

From: Mauro Carvalho Chehab <[email protected]>

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

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

commit dafb65fb98d85d8e78405e82c83e81975e5d5480 upstream.

On this frontend, it takes a while to start output normal
TS data. That only happens on state S9. On S8, the TS output
is enabled, but it is not reliable enough.

However, the zigzag loop is too fast to let it sync.

As, on practical tests, the zigzag software loop doesn't
seem to be helping, but just slowing down the tuning, let's
switch to hardware algorithm, as the tuners used on such
devices are capable of work with frequency drifts without
any help from software.

Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/media/dvb-frontends/mb86a20s.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c
index 2c7217fb1415..3fbac5fd4d32 100644
--- a/drivers/media/dvb-frontends/mb86a20s.c
+++ b/drivers/media/dvb-frontends/mb86a20s.c
@@ -321,7 +321,11 @@ static int mb86a20s_read_status(struct dvb_frontend *fe, fe_status_t *status)
if (val >= 7)
*status |= FE_HAS_SYNC;

- if (val >= 8) /* Maybe 9? */
+ /*
+ * Actually, on state S8, it starts receiving TS, but the TS
+ * output is only on normal state after the transition to S9.
+ */
+ if (val >= 9)
*status |= FE_HAS_LOCK;

dev_dbg(&state->i2c->dev, "%s: Status = 0x%02x (state = %d)\n",
@@ -2080,6 +2084,11 @@ static void mb86a20s_release(struct dvb_frontend *fe)
kfree(state);
}

+static int mb86a20s_get_frontend_algo(struct dvb_frontend *fe)
+{
+ return DVBFE_ALGO_HW;
+}
+
static struct dvb_frontend_ops mb86a20s_ops;

struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
@@ -2153,6 +2162,7 @@ static struct dvb_frontend_ops mb86a20s_ops = {
.read_status = mb86a20s_read_status_and_stats,
.read_signal_strength = mb86a20s_read_signal_strength_from_cache,
.tune = mb86a20s_tune,
+ .get_frontend_algo = mb86a20s_get_frontend_algo,
};

MODULE_DESCRIPTION("DVB Frontend module for Fujitsu mb86A20s hardware");
--
2.10.2

2016-11-07 13:19:54

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 23/72] zfcp: retain trace level for SCSI and HBA FSF response records

From: Steffen Maier <[email protected]>

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

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

commit 35f040df97fa0e94c7851c054ec71533c88b4b81 upstream.

While retaining the actual filtering according to trace level,
the following commits started to write such filtered records
with a hardcoded record level of 1 instead of the actual record level:
commit 250a1352b95e1db3216e5c5d4f4365bea5122f4a
("[SCSI] zfcp: Redesign of the debug tracing for SCSI records.")
commit a54ca0f62f953898b05549391ac2a8a4dad6482b
("[SCSI] zfcp: Redesign of the debug tracing for HBA records.")

Now we can distinguish written records again for offline level filtering.

Signed-off-by: Steffen Maier <[email protected]>
Fixes: 250a1352b95e ("[SCSI] zfcp: Redesign of the debug tracing for SCSI records.")
Fixes: a54ca0f62f95 ("[SCSI] zfcp: Redesign of the debug tracing for HBA records.")
Reviewed-by: Benjamin Block <[email protected]>
Reviewed-by: Hannes Reinecke <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/s390/scsi/zfcp_dbf.c | 11 ++++++-----
drivers/s390/scsi/zfcp_dbf.h | 4 ++--
drivers/s390/scsi/zfcp_ext.h | 7 ++++---
3 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 132a905b6bdb..bbd1ed552d7d 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -3,7 +3,7 @@
*
* Debug traces for zfcp.
*
- * Copyright IBM Corp. 2002, 2013
+ * Copyright IBM Corp. 2002, 2015
*/

#define KMSG_COMPONENT "zfcp"
@@ -65,7 +65,7 @@ void zfcp_dbf_pl_write(struct zfcp_dbf *dbf, void *data, u16 length, char *area,
* @tag: tag indicating which kind of unsolicited status has been received
* @req: request for which a response was received
*/
-void zfcp_dbf_hba_fsf_res(char *tag, struct zfcp_fsf_req *req)
+void zfcp_dbf_hba_fsf_res(char *tag, int level, struct zfcp_fsf_req *req)
{
struct zfcp_dbf *dbf = req->adapter->dbf;
struct fsf_qtcb_prefix *q_pref = &req->qtcb->prefix;
@@ -97,7 +97,7 @@ void zfcp_dbf_hba_fsf_res(char *tag, struct zfcp_fsf_req *req)
rec->pl_len, "fsf_res", req->req_id);
}

- debug_event(dbf->hba, 1, rec, sizeof(*rec));
+ debug_event(dbf->hba, level, rec, sizeof(*rec));
spin_unlock_irqrestore(&dbf->hba_lock, flags);
}

@@ -399,7 +399,8 @@ void zfcp_dbf_san_in_els(char *tag, struct zfcp_fsf_req *fsf)
* @sc: pointer to struct scsi_cmnd
* @fsf: pointer to struct zfcp_fsf_req
*/
-void zfcp_dbf_scsi(char *tag, struct scsi_cmnd *sc, struct zfcp_fsf_req *fsf)
+void zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *sc,
+ struct zfcp_fsf_req *fsf)
{
struct zfcp_adapter *adapter =
(struct zfcp_adapter *) sc->device->host->hostdata[0];
@@ -441,7 +442,7 @@ void zfcp_dbf_scsi(char *tag, struct scsi_cmnd *sc, struct zfcp_fsf_req *fsf)
}
}

- debug_event(dbf->scsi, 1, rec, sizeof(*rec));
+ debug_event(dbf->scsi, level, rec, sizeof(*rec));
spin_unlock_irqrestore(&dbf->scsi_lock, flags);
}

diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h
index b5afa3d01e93..97f46e6964d4 100644
--- a/drivers/s390/scsi/zfcp_dbf.h
+++ b/drivers/s390/scsi/zfcp_dbf.h
@@ -284,7 +284,7 @@ static inline
void zfcp_dbf_hba_fsf_resp(char *tag, int level, struct zfcp_fsf_req *req)
{
if (level <= req->adapter->dbf->hba->level)
- zfcp_dbf_hba_fsf_res(tag, req);
+ zfcp_dbf_hba_fsf_res(tag, level, req);
}

/**
@@ -323,7 +323,7 @@ void _zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *scmd,
scmd->device->host->hostdata[0];

if (level <= adapter->dbf->scsi->level)
- zfcp_dbf_scsi(tag, scmd, req);
+ zfcp_dbf_scsi(tag, level, scmd, req);
}

/**
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index a9c570a09b85..673f85103d72 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -3,7 +3,7 @@
*
* External function declarations.
*
- * Copyright IBM Corp. 2002, 2010
+ * Copyright IBM Corp. 2002, 2015
*/

#ifndef ZFCP_EXT_H
@@ -36,7 +36,7 @@ extern void zfcp_dbf_rec_trig(char *, struct zfcp_adapter *,
struct zfcp_port *, struct scsi_device *, u8, u8);
extern void zfcp_dbf_rec_run(char *, struct zfcp_erp_action *);
extern void zfcp_dbf_hba_fsf_uss(char *, struct zfcp_fsf_req *);
-extern void zfcp_dbf_hba_fsf_res(char *, struct zfcp_fsf_req *);
+extern void zfcp_dbf_hba_fsf_res(char *, int, struct zfcp_fsf_req *);
extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *);
extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *);
extern void zfcp_dbf_hba_def_err(struct zfcp_adapter *, u64, u16, void **);
@@ -44,7 +44,8 @@ extern void zfcp_dbf_hba_basic(char *, struct zfcp_adapter *);
extern void zfcp_dbf_san_req(char *, struct zfcp_fsf_req *, u32);
extern void zfcp_dbf_san_res(char *, struct zfcp_fsf_req *);
extern void zfcp_dbf_san_in_els(char *, struct zfcp_fsf_req *);
-extern void zfcp_dbf_scsi(char *, struct scsi_cmnd *, struct zfcp_fsf_req *);
+extern void zfcp_dbf_scsi(char *, int, struct scsi_cmnd *,
+ struct zfcp_fsf_req *);

/* zfcp_erp.c */
extern void zfcp_erp_set_adapter_status(struct zfcp_adapter *, u32);
--
2.10.2

2016-11-07 13:19:50

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 22/72] zfcp: close window with unblocked rport during rport gone

From: Steffen Maier <[email protected]>

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

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

commit 4eeaa4f3f1d6c47b69f70e222297a4df4743363e upstream.

On a successful end of reopen port forced,
zfcp_erp_strategy_followup_success() re-uses the port erp_action
and the subsequent zfcp_erp_action_cleanup() now
sees ZFCP_ERP_SUCCEEDED with
erp_action->action==ZFCP_ERP_ACTION_REOPEN_PORT
instead of ZFCP_ERP_ACTION_REOPEN_PORT_FORCED
but must not perform zfcp_scsi_schedule_rport_register().

We can detect this because the fresh port reopen erp_action
is in its very first step ZFCP_ERP_STEP_UNINITIALIZED.

Otherwise this opens a time window with unblocked rport
(until the followup port reopen recovery would block it again).
If a scsi_cmnd timeout occurs during this time window
fc_timed_out() cannot work as desired and such command
would indeed time out and trigger scsi_eh. This prevents
a clean and timely path failover.
This should not happen if the path issue can be recovered
on FC transport layer such as path issues involving RSCNs.

Also, unnecessary and repeated DID_IMM_RETRY for pending and
undesired new requests occur because internally zfcp still
has its zfcp_port blocked.

As follow-on errors with scsi_eh, it can cause,
in the worst case, permanently lost paths due to one of:
sd <scsidev>: [<scsidisk>] Medium access timeout failure. Offlining disk!
sd <scsidev>: Device offlined - not ready after error recovery

For fix validation and to aid future debugging with other recoveries
we now also trace (un)blocking of rports.

Signed-off-by: Steffen Maier <[email protected]>
Fixes: 5767620c383a ("[SCSI] zfcp: Do not unblock rport from REOPEN_PORT_FORCED")
Fixes: a2fa0aede07c ("[SCSI] zfcp: Block FC transport rports early on errors")
Fixes: 5f852be9e11d ("[SCSI] zfcp: Fix deadlock between zfcp ERP and SCSI")
Fixes: 338151e06608 ("[SCSI] zfcp: make use of fc_remote_port_delete when target port is unavailable")
Fixes: 3859f6a248cb ("[PATCH] zfcp: add rports to enable scsi_add_device to work again")
Reviewed-by: Benjamin Block <[email protected]>
Reviewed-by: Hannes Reinecke <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/s390/scsi/zfcp_dbf.h | 7 ++++++-
drivers/s390/scsi/zfcp_erp.c | 12 +++++++++---
drivers/s390/scsi/zfcp_scsi.c | 8 +++++++-
3 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h
index 3ac7a4b30dd9..b5afa3d01e93 100644
--- a/drivers/s390/scsi/zfcp_dbf.h
+++ b/drivers/s390/scsi/zfcp_dbf.h
@@ -2,7 +2,7 @@
* zfcp device driver
* debug feature declarations
*
- * Copyright IBM Corp. 2008, 2010
+ * Copyright IBM Corp. 2008, 2015
*/

#ifndef ZFCP_DBF_H
@@ -17,6 +17,11 @@

#define ZFCP_DBF_INVALID_LUN 0xFFFFFFFFFFFFFFFFull

+enum zfcp_dbf_pseudo_erp_act_type {
+ ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD = 0xff,
+ ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL = 0xfe,
+};
+
/**
* struct zfcp_dbf_rec_trigger - trace record for triggered recovery action
* @ready: number of ready recovery actions
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index c82fe65c4128..ac86ff90c897 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -3,7 +3,7 @@
*
* Error Recovery Procedures (ERP).
*
- * Copyright IBM Corp. 2002, 2010
+ * Copyright IBM Corp. 2002, 2015
*/

#define KMSG_COMPONENT "zfcp"
@@ -1224,8 +1224,14 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
break;

case ZFCP_ERP_ACTION_REOPEN_PORT:
- if (result == ZFCP_ERP_SUCCEEDED)
- zfcp_scsi_schedule_rport_register(port);
+ /* This switch case might also happen after a forced reopen
+ * was successfully done and thus overwritten with a new
+ * non-forced reopen at `ersfs_2'. In this case, we must not
+ * do the clean-up of the non-forced version.
+ */
+ if (act->step != ZFCP_ERP_STEP_UNINITIALIZED)
+ if (result == ZFCP_ERP_SUCCEEDED)
+ zfcp_scsi_schedule_rport_register(port);
/* fall through */
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
put_device(&port->dev);
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 7b353647cb90..38ee0df633a3 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -3,7 +3,7 @@
*
* Interface to Linux SCSI midlayer.
*
- * Copyright IBM Corp. 2002, 2013
+ * Copyright IBM Corp. 2002, 2015
*/

#define KMSG_COMPONENT "zfcp"
@@ -577,6 +577,9 @@ static void zfcp_scsi_rport_register(struct zfcp_port *port)
ids.port_id = port->d_id;
ids.roles = FC_RPORT_ROLE_FCP_TARGET;

+ zfcp_dbf_rec_trig("scpaddy", port->adapter, port, NULL,
+ ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD,
+ ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD);
rport = fc_remote_port_add(port->adapter->scsi_host, 0, &ids);
if (!rport) {
dev_err(&port->adapter->ccw_device->dev,
@@ -598,6 +601,9 @@ static void zfcp_scsi_rport_block(struct zfcp_port *port)
struct fc_rport *rport = port->rport;

if (rport) {
+ zfcp_dbf_rec_trig("scpdely", port->adapter, port, NULL,
+ ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL,
+ ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL);
fc_remote_port_delete(rport);
port->rport = NULL;
}
--
2.10.2

2016-11-07 13:20:33

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 20/72] zfcp: fix fc_host port_type with NPIV

From: Steffen Maier <[email protected]>

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

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

commit bd77befa5bcff8c51613de271913639edf85fbc2 upstream.

For an NPIV-enabled FCP device, zfcp can erroneously show
"NPort (fabric via point-to-point)" instead of "NPIV VPORT"
for the port_type sysfs attribute of the corresponding
fc_host.
s390-tools that can be affected are dbginfo.sh and ziomon.

zfcp_fsf_exchange_config_evaluate() ignores
fsf_qtcb_bottom_config.connection_features indicating NPIV
and only sets fc_host_port_type to FC_PORTTYPE_NPORT if
fsf_qtcb_bottom_config.fc_topology is FSF_TOPO_FABRIC.

Only the independent zfcp_fsf_exchange_port_evaluate()
evaluates connection_features to overwrite fc_host_port_type
to FC_PORTTYPE_NPIV in case of NPIV.
Code was introduced with upstream kernel 2.6.30
commit 0282985da5923fa6365adcc1a1586ae0c13c1617
("[SCSI] zfcp: Report fc_host_port_type as NPIV").

This works during FCP device recovery (such as set online)
because it performs FSF_QTCB_EXCHANGE_CONFIG_DATA followed by
FSF_QTCB_EXCHANGE_PORT_DATA in sequence.

However, the zfcp-specific scsi host sysfs attributes
"requests", "megabytes", or "seconds_active" trigger only
zfcp_fsf_exchange_config_evaluate() resetting fc_host
port_type to FC_PORTTYPE_NPORT despite NPIV.

The zfcp-specific scsi host sysfs attribute "utilization"
triggers only zfcp_fsf_exchange_port_evaluate() correcting
the fc_host port_type again in case of NPIV.

Evaluate fsf_qtcb_bottom_config.connection_features
in zfcp_fsf_exchange_config_evaluate() where it belongs to.

Signed-off-by: Steffen Maier <[email protected]>
Fixes: 0282985da592 ("[SCSI] zfcp: Report fc_host_port_type as NPIV")
Reviewed-by: Benjamin Block <[email protected]>
Reviewed-by: Hannes Reinecke <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/s390/scsi/zfcp_fsf.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 0fe8d5d95119..08d488f47097 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -3,7 +3,7 @@
*
* Implementation of FSF commands.
*
- * Copyright IBM Corp. 2002, 2013
+ * Copyright IBM Corp. 2002, 2015
*/

#define KMSG_COMPONENT "zfcp"
@@ -508,7 +508,10 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
fc_host_port_type(shost) = FC_PORTTYPE_PTP;
break;
case FSF_TOPO_FABRIC:
- fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
+ if (bottom->connection_features & FSF_FEATURE_NPIV_MODE)
+ fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
+ else
+ fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
break;
case FSF_TOPO_AL:
fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
@@ -613,7 +616,6 @@ static void zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *req)

if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) {
fc_host_permanent_port_name(shost) = bottom->wwpn;
- fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
} else
fc_host_permanent_port_name(shost) = fc_host_port_name(shost);
fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
--
2.10.2

2016-11-07 13:20:35

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 19/72] powerpc/pseries: Fix stack corruption in htpe code

From: Laurent Dufour <[email protected]>

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

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

commit 05af40e885955065aee8bb7425058eb3e1adca08 upstream.

This commit fixes a stack corruption in the pseries specific code dealing
with the huge pages.

In __pSeries_lpar_hugepage_invalidate() the buffer used to pass arguments
to the hypervisor is not large enough. This leads to a stack corruption
where a previously saved register could be corrupted leading to unexpected
result in the caller, like the following panic:

Oops: Kernel access of bad area, sig: 11 [#1]
SMP NR_CPUS=2048 NUMA pSeries
Modules linked in: virtio_balloon ip_tables x_tables autofs4
virtio_blk 8139too virtio_pci virtio_ring 8139cp virtio
CPU: 11 PID: 1916 Comm: mmstress Not tainted 4.8.0 #76
task: c000000005394880 task.stack: c000000005570000
NIP: c00000000027bf6c LR: c00000000027bf64 CTR: 0000000000000000
REGS: c000000005573820 TRAP: 0300 Not tainted (4.8.0)
MSR: 8000000000009033 <SF,EE,ME,IR,DR,RI,LE> CR: 84822884 XER: 20000000
CFAR: c00000000010a924 DAR: 420000000014e5e0 DSISR: 40000000 SOFTE: 1
GPR00: c00000000027bf64 c000000005573aa0 c000000000e02800 c000000004447964
GPR04: c00000000404de18 c000000004d38810 00000000042100f5 00000000f5002104
GPR08: e0000000f5002104 0000000000000001 042100f5000000e0 00000000042100f5
GPR12: 0000000000002200 c00000000fe02c00 c00000000404de18 0000000000000000
GPR16: c1ffffffffffe7ff 00003fff62000000 420000000014e5e0 00003fff63000000
GPR20: 0008000000000000 c0000000f7014800 0405e600000000e0 0000000000010000
GPR24: c000000004d38810 c000000004447c10 c00000000404de18 c000000004447964
GPR28: c000000005573b10 c000000004d38810 00003fff62000000 420000000014e5e0
NIP [c00000000027bf6c] zap_huge_pmd+0x4c/0x470
LR [c00000000027bf64] zap_huge_pmd+0x44/0x470
Call Trace:
[c000000005573aa0] [c00000000027bf64] zap_huge_pmd+0x44/0x470 (unreliable)
[c000000005573af0] [c00000000022bbd8] unmap_page_range+0xcf8/0xed0
[c000000005573c30] [c00000000022c2d4] unmap_vmas+0x84/0x120
[c000000005573c80] [c000000000235448] unmap_region+0xd8/0x1b0
[c000000005573d80] [c0000000002378f0] do_munmap+0x2d0/0x4c0
[c000000005573df0] [c000000000237be4] SyS_munmap+0x64/0xb0
[c000000005573e30] [c000000000009560] system_call+0x38/0x108
Instruction dump:
fbe1fff8 fb81ffe0 7c7f1b78 7ca32b78 7cbd2b78 f8010010 7c9a2378 f821ffb1
7cde3378 4bfffea9 7c7b1b79 41820298 <e87f0000> 48000130 7fa5eb78 7fc4f378

Most of the time, the bug is surfacing in a caller up in the stack from
__pSeries_lpar_hugepage_invalidate() which is quite confusing.

This bug is pending since v3.11 but was hidden if a caller of the
caller of __pSeries_lpar_hugepage_invalidate() has pushed the corruped
register (r18 in this case) in the stack and is not using it until
restoring it. GCC 6.2.0 seems to raise it more frequently.

This commit also change the definition of the parameter buffer in
pSeries_lpar_flush_hash_range() to rely on the global define
PLPAR_HCALL9_BUFSIZE (no functional change here).

Fixes: 1a5272866f87 ("powerpc: Optimize hugepage invalidate")
Signed-off-by: Laurent Dufour <[email protected]>
Reviewed-by: Aneesh Kumar K.V <[email protected]>
Acked-by: Balbir Singh <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/powerpc/platforms/pseries/lpar.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 691a479f7d97..73f2c2f35f6d 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -373,7 +373,7 @@ static void __pSeries_lpar_hugepage_invalidate(unsigned long *slot,
unsigned long *vpn, int count,
int psize, int ssize)
{
- unsigned long param[8];
+ unsigned long param[PLPAR_HCALL9_BUFSIZE];
int i = 0, pix = 0, rc;
unsigned long flags = 0;
int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
@@ -490,7 +490,7 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
unsigned long flags = 0;
struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
- unsigned long param[9];
+ unsigned long param[PLPAR_HCALL9_BUFSIZE];
unsigned long hash, index, shift, hidx, slot;
real_pte_t pte;
int psize, ssize;
--
2.10.2

2016-11-07 13:22:05

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 17/72] powerpc/powernv: Use CPU-endian PEST in pnv_pci_dump_p7ioc_diag_data()

From: Gavin Shan <[email protected]>

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

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

commit 5adaf8629b193f185ca5a1665b9e777a0579f518 upstream.

This fixes the warnings reported from sparse:

pci.c:312:33: warning: restricted __be64 degrades to integer
pci.c:313:33: warning: restricted __be64 degrades to integer

Fixes: cee72d5bb489 ("powerpc/powernv: Display diag data on p7ioc EEH errors")
Signed-off-by: Gavin Shan <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/powerpc/platforms/powernv/pci.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index 52746b3caf08..ec78cdb13288 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -179,8 +179,8 @@ static void pnv_pci_dump_p7ioc_diag_data(struct pnv_phb *phb)
pr_info(" dma1ErrorLog1 = 0x%016llx\n", data->dma1ErrorLog1);

for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++) {
- if ((data->pestA[i] >> 63) == 0 &&
- (data->pestB[i] >> 63) == 0)
+ if ((be64_to_cpu(data->pestA[i]) >> 63) == 0 &&
+ (be64_to_cpu(data->pestB[i]) >> 63) == 0)
continue;
pr_info(" PE[%3d] PESTA = 0x%016llx\n", i, data->pestA[i]);
pr_info(" PESTB = 0x%016llx\n", data->pestB[i]);
--
2.10.2

2016-11-07 13:22:01

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 15/72] dm: mark request_queue dead before destroying the DM device

From: Bart Van Assche <[email protected]>

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

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

commit 3b785fbcf81c3533772c52b717f77293099498d3 upstream.

This avoids that new requests are queued while __dm_destroy() is in
progress.

[js] use md->queue instead of non-present helper

Signed-off-by: Bart Van Assche <[email protected]>
Signed-off-by: Mike Snitzer <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/md/dm.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 78ab0a131cf1..8c82835a4749 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -2428,6 +2428,7 @@ EXPORT_SYMBOL_GPL(dm_device_name);

static void __dm_destroy(struct mapped_device *md, bool wait)
{
+ struct request_queue *q = md->queue;
struct dm_table *map;
int srcu_idx;

@@ -2438,6 +2439,10 @@ static void __dm_destroy(struct mapped_device *md, bool wait)
set_bit(DMF_FREEING, &md->flags);
spin_unlock(&_minor_lock);

+ spin_lock_irq(q->queue_lock);
+ queue_flag_set(QUEUE_FLAG_DYING, q);
+ spin_unlock_irq(q->queue_lock);
+
/*
* Take suspend_lock so that presuspend and postsuspend methods
* do not race with internal suspend.
--
2.10.2

2016-11-07 13:21:56

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 16/72] powerpc/vdso64: Use double word compare on pointers

From: Anton Blanchard <[email protected]>

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

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

commit 5045ea37377ce8cca6890d32b127ad6770e6dce5 upstream.

__kernel_get_syscall_map() and __kernel_clock_getres() use cmpli to
check if the passed in pointer is non zero. cmpli maps to a 32 bit
compare on binutils, so we ignore the top 32 bits.

A simple test case can be created by passing in a bogus pointer with
the bottom 32 bits clear. Using a clk_id that is handled by the VDSO,
then one that is handled by the kernel shows the problem:

printf("%d\n", clock_getres(CLOCK_REALTIME, (void *)0x100000000));
printf("%d\n", clock_getres(CLOCK_BOOTTIME, (void *)0x100000000));

And we get:

0
-1

The bigger issue is if we pass a valid pointer with the bottom 32 bits
clear, in this case we will return success but won't write any data
to the pointer.

I stumbled across this issue because the LLVM integrated assembler
doesn't accept cmpli with 3 arguments. Fix this by converting them to
cmpldi.

Fixes: a7f290dad32e ("[PATCH] powerpc: Merge vdso's and add vdso support to 32 bits kernel")
Signed-off-by: Anton Blanchard <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/powerpc/kernel/vdso64/datapage.S | 2 +-
arch/powerpc/kernel/vdso64/gettimeofday.S | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/vdso64/datapage.S b/arch/powerpc/kernel/vdso64/datapage.S
index 79796de11737..3263ee23170d 100644
--- a/arch/powerpc/kernel/vdso64/datapage.S
+++ b/arch/powerpc/kernel/vdso64/datapage.S
@@ -57,7 +57,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map)
bl V_LOCAL_FUNC(__get_datapage)
mtlr r12
addi r3,r3,CFG_SYSCALL_MAP64
- cmpli cr0,r4,0
+ cmpldi cr0,r4,0
crclr cr0*4+so
beqlr
li r0,__NR_syscalls
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S
index a76b4af37ef2..382021324883 100644
--- a/arch/powerpc/kernel/vdso64/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso64/gettimeofday.S
@@ -145,7 +145,7 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
bne cr0,99f

li r3,0
- cmpli cr0,r4,0
+ cmpldi cr0,r4,0
crclr cr0*4+so
beqlr
lis r5,CLOCK_REALTIME_RES@h
--
2.10.2

2016-11-07 13:21:53

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 18/72] powerpc/64: Fix incorrect return value from __copy_tofrom_user

From: Paul Mackerras <[email protected]>

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

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

commit 1a34439e5a0b2235e43f96816dbb15ee1154f656 upstream.

Debugging a data corruption issue with virtio-net/vhost-net led to
the observation that __copy_tofrom_user was occasionally returning
a value 16 larger than it should. Since the return value from
__copy_tofrom_user is the number of bytes not copied, this means
that __copy_tofrom_user can occasionally return a value larger
than the number of bytes it was asked to copy. In turn this can
cause higher-level copy functions such as copy_page_to_iter_iovec
to corrupt memory by copying data into the wrong memory locations.

It turns out that the failing case involves a fault on the store
at label 79, and at that point the first unmodified byte of the
destination is at R3 + 16. Consequently the exception handler
for that store needs to add 16 to R3 before using it to work out
how many bytes were not copied, but in this one case it was not
adding the offset to R3. To fix it, this moves the label 179 to
the point where we add 16 to R3. I have checked manually all the
exception handlers for the loads and stores in this code and the
rest of them are correct (it would be excellent to have an
automated test of all the exception cases).

This bug has been present since this code was initially
committed in May 2002 to Linux version 2.5.20.

Signed-off-by: Paul Mackerras <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/powerpc/lib/copyuser_64.S | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/lib/copyuser_64.S b/arch/powerpc/lib/copyuser_64.S
index d73a59014900..be94e1be4ae3 100644
--- a/arch/powerpc/lib/copyuser_64.S
+++ b/arch/powerpc/lib/copyuser_64.S
@@ -336,6 +336,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
addi r3,r3,8
171:
177:
+179:
addi r3,r3,8
370:
372:
@@ -350,7 +351,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
173:
174:
175:
-179:
181:
184:
186:
--
2.10.2

2016-11-07 13:23:07

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 12/72] pstore/core: drop cmpxchg based updates

From: Sebastian Andrzej Siewior <[email protected]>

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

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

commit d5a9bf0b38d2ac85c9a693c7fb851f74fd2a2494 upstream.

I have here a FPGA behind PCIe which exports SRAM which I use for
pstore. Now it seems that the FPGA no longer supports cmpxchg based
updates and writes back 0xff…ff and returns the same. This leads to
crash during crash rendering pstore useless.
Since I doubt that there is much benefit from using cmpxchg() here, I am
dropping this atomic access and use the spinlock based version.

Cc: Anton Vorontsov <[email protected]>
Cc: Colin Cross <[email protected]>
Cc: Kees Cook <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Rabin Vincent <[email protected]>
Tested-by: Rabin Vincent <[email protected]>
Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
Reviewed-by: Guenter Roeck <[email protected]>
[kees: remove "_locked" suffix since it's the only option now]
Signed-off-by: Kees Cook <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/pstore/ram_core.c | 43 ++-----------------------------------------
1 file changed, 2 insertions(+), 41 deletions(-)

diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c
index 0b367ef7a7d6..ee3c6ec5348f 100644
--- a/fs/pstore/ram_core.c
+++ b/fs/pstore/ram_core.c
@@ -45,43 +45,10 @@ static inline size_t buffer_start(struct persistent_ram_zone *prz)
return atomic_read(&prz->buffer->start);
}

-/* increase and wrap the start pointer, returning the old value */
-static size_t buffer_start_add_atomic(struct persistent_ram_zone *prz, size_t a)
-{
- int old;
- int new;
-
- do {
- old = atomic_read(&prz->buffer->start);
- new = old + a;
- while (unlikely(new >= prz->buffer_size))
- new -= prz->buffer_size;
- } while (atomic_cmpxchg(&prz->buffer->start, old, new) != old);
-
- return old;
-}
-
-/* increase the size counter until it hits the max size */
-static void buffer_size_add_atomic(struct persistent_ram_zone *prz, size_t a)
-{
- size_t old;
- size_t new;
-
- if (atomic_read(&prz->buffer->size) == prz->buffer_size)
- return;
-
- do {
- old = atomic_read(&prz->buffer->size);
- new = old + a;
- if (new > prz->buffer_size)
- new = prz->buffer_size;
- } while (atomic_cmpxchg(&prz->buffer->size, old, new) != old);
-}
-
static DEFINE_RAW_SPINLOCK(buffer_lock);

/* increase and wrap the start pointer, returning the old value */
-static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a)
+static size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a)
{
int old;
int new;
@@ -101,7 +68,7 @@ static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a)
}

/* increase the size counter until it hits the max size */
-static void buffer_size_add_locked(struct persistent_ram_zone *prz, size_t a)
+static void buffer_size_add(struct persistent_ram_zone *prz, size_t a)
{
size_t old;
size_t new;
@@ -122,9 +89,6 @@ exit:
raw_spin_unlock_irqrestore(&buffer_lock, flags);
}

-static size_t (*buffer_start_add)(struct persistent_ram_zone *, size_t) = buffer_start_add_atomic;
-static void (*buffer_size_add)(struct persistent_ram_zone *, size_t) = buffer_size_add_atomic;
-
static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz,
uint8_t *data, size_t len, uint8_t *ecc)
{
@@ -426,9 +390,6 @@ static void *persistent_ram_iomap(phys_addr_t start, size_t size,
return NULL;
}

- buffer_start_add = buffer_start_add_locked;
- buffer_size_add = buffer_size_add_locked;
-
if (memtype)
va = ioremap(start, size);
else
--
2.10.2

2016-11-07 13:23:22

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 03/72] scsi: ibmvfc: Fix I/O hang when port is not mapped

From: Brian King <[email protected]>

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

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

commit 07d0e9a847401ffd2f09bd450d41644cd090e81d upstream.

If a VFC port gets unmapped in the VIOS, it may not respond with a CRQ
init complete following H_REG_CRQ. If this occurs, we can end up having
called scsi_block_requests and not a resulting unblock until the init
complete happens, which may never occur, and we end up hanging I/O
requests. This patch ensures the host action stay set to
IBMVFC_HOST_ACTION_TGT_DEL so we move all rports into devloss state and
unblock unless we receive an init complete.

Signed-off-by: Brian King <[email protected]>
Acked-by: Tyrel Datwyler <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/scsi/ibmvscsi/ibmvfc.c | 1 -
1 file changed, 1 deletion(-)

diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 23f5ba5e6472..26d31b7e7331 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -717,7 +717,6 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost)
spin_lock_irqsave(vhost->host->host_lock, flags);
vhost->state = IBMVFC_NO_CRQ;
vhost->logged_in = 0;
- ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE);

/* Clean out the queue */
memset(crq->msgs, 0, PAGE_SIZE);
--
2.10.2

2016-11-07 13:23:36

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 11/72] mmc: block: don't use CMD23 with very old MMC cards

From: Daniel Glöckner <[email protected]>

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

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

commit 0ed50abb2d8fc81570b53af25621dad560cd49b3 upstream.

CMD23 aka SET_BLOCK_COUNT was introduced with MMC v3.1.
Older versions of the specification allowed to terminate
multi-block transfers only with CMD12.

The patch fixes the following problem:

mmc0: new MMC card at address 0001
mmcblk0: mmc0:0001 SDMB-16 15.3 MiB
mmcblk0: timed out sending SET_BLOCK_COUNT command, card status 0x400900
...
blk_update_request: I/O error, dev mmcblk0, sector 0
Buffer I/O error on dev mmcblk0, logical block 0, async page read
mmcblk0: unable to read partition table

Signed-off-by: Daniel Glöckner <[email protected]>
Signed-off-by: Ulf Hansson <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/mmc/card/block.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 0405fba9f7a8..449b9f1d7502 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -2121,7 +2121,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
set_capacity(md->disk, size);

if (mmc_host_cmd23(card->host)) {
- if (mmc_card_mmc(card) ||
+ if ((mmc_card_mmc(card) &&
+ card->csd.mmca_vsn >= CSD_SPEC_VER_3) ||
(mmc_card_sd(card) &&
card->scr.cmds & SD_SCR_CMD23_SUPPORT))
md->flags |= MMC_BLK_CMD23;
--
2.10.2

2016-11-07 13:23:31

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 01/72] i40e: avoid NULL pointer dereference and recursive errors on early PCI error

From: Guilherme G Piccoli <[email protected]>

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

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

commit edfc23ee3e0ebbb6713d7574ab1b00abff178f6c upstream.

Although rare, it's possible to hit PCI error early on device
probe, meaning possibly some structs are not entirely initialized,
and some might even be completely uninitialized, leading to NULL
pointer dereference.

The i40e driver currently presents a "bad" behavior if device hits
such early PCI error: firstly, the struct i40e_pf might not be
attached to pci_dev yet, leading to a NULL pointer dereference on
access to pf->state.

Even checking if the struct is NULL and avoiding the access in that
case isn't enough, since the driver cannot recover from PCI error
that early; in our experiments we saw multiple failures on kernel
log, like:

[549.664] i40e 0007:01:00.1: Initial pf_reset failed: -15
[549.664] i40e: probe of 0007:01:00.1 failed with error -15
[...]
[871.644] i40e 0007:01:00.1: The driver for the device stopped because the
device firmware failed to init. Try updating your NVM image.
[871.644] i40e: probe of 0007:01:00.1 failed with error -32
[...]
[872.516] i40e 0007:01:00.0: ARQ: Unknown event 0x0000 ignored

Between the first probe failure (error -15) and the second (error -32)
another PCI error happened due to the first bad probe. Also, driver
started to flood console with those ARQ event messages.

This patch will prevent these issues by allowing error recovery
mechanism to remove the failed device from the system instead of
trying to recover from early PCI errors during device probe.

Signed-off-by: Guilherme G Piccoli <[email protected]>
Acked-by: Jacob Keller <[email protected]>
Tested-by: Andrew Bowers <[email protected]>
Signed-off-by: Jeff Kirsher <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 221aa4795017..1c7c3048117b 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -7265,6 +7265,12 @@ static pci_ers_result_t i40e_pci_error_detected(struct pci_dev *pdev,

dev_info(&pdev->dev, "%s: error %d\n", __func__, error);

+ if (!pf) {
+ dev_info(&pdev->dev,
+ "Cannot recover - error happened during device probe\n");
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+
/* shutdown all operations */
i40e_pf_quiesce_all_vsi(pf);

--
2.10.2

2016-11-07 13:23:26

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 02/72] reiserfs: Unlock superblock before calling reiserfs_quota_on_mount()

From: Mike Galbraith <[email protected]>

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

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

commit 420902c9d086848a7548c83e0a49021514bd71b7 upstream.

If we hold the superblock lock while calling reiserfs_quota_on_mount(), we can
deadlock our own worker - mount blocks kworker/3:2, sleeps forever more.

crash> ps|grep UN
715 2 3 ffff880220734d30 UN 0.0 0 0 [kworker/3:2]
9369 9341 2 ffff88021ffb7560 UN 1.3 493404 123184 Xorg
9665 9664 3 ffff880225b92ab0 UN 0.0 47368 812 udisks-daemon
10635 10403 3 ffff880222f22c70 UN 0.0 14904 936 mount
crash> bt ffff880220734d30
PID: 715 TASK: ffff880220734d30 CPU: 3 COMMAND: "kworker/3:2"
#0 [ffff8802244c3c20] schedule at ffffffff8144584b
#1 [ffff8802244c3cc8] __rt_mutex_slowlock at ffffffff814472b3
#2 [ffff8802244c3d28] rt_mutex_slowlock at ffffffff814473f5
#3 [ffff8802244c3dc8] reiserfs_write_lock at ffffffffa05f28fd [reiserfs]
#4 [ffff8802244c3de8] flush_async_commits at ffffffffa05ec91d [reiserfs]
#5 [ffff8802244c3e08] process_one_work at ffffffff81073726
#6 [ffff8802244c3e68] worker_thread at ffffffff81073eba
#7 [ffff8802244c3ec8] kthread at ffffffff810782e0
#8 [ffff8802244c3f48] kernel_thread_helper at ffffffff81450064
crash> rd ffff8802244c3cc8 10
ffff8802244c3cc8: ffffffff814472b3 ffff880222f23250 .rD.....P2."....
ffff8802244c3cd8: 0000000000000000 0000000000000286 ................
ffff8802244c3ce8: ffff8802244c3d30 ffff880220734d80 0=L$.....Ms ....
ffff8802244c3cf8: ffff880222e8f628 0000000000000000 (.."............
ffff8802244c3d08: 0000000000000000 0000000000000002 ................
crash> struct rt_mutex ffff880222e8f628
struct rt_mutex {
wait_lock = {
raw_lock = {
slock = 65537
}
},
wait_list = {
node_list = {
next = 0xffff8802244c3d48,
prev = 0xffff8802244c3d48
}
},
owner = 0xffff880222f22c71,
save_state = 0
}
crash> bt 0xffff880222f22c70
PID: 10635 TASK: ffff880222f22c70 CPU: 3 COMMAND: "mount"
#0 [ffff8802216a9868] schedule at ffffffff8144584b
#1 [ffff8802216a9910] schedule_timeout at ffffffff81446865
#2 [ffff8802216a99a0] wait_for_common at ffffffff81445f74
#3 [ffff8802216a9a30] flush_work at ffffffff810712d3
#4 [ffff8802216a9ab0] schedule_on_each_cpu at ffffffff81074463
#5 [ffff8802216a9ae0] invalidate_bdev at ffffffff81178aba
#6 [ffff8802216a9af0] vfs_load_quota_inode at ffffffff811a3632
#7 [ffff8802216a9b50] dquot_quota_on_mount at ffffffff811a375c
#8 [ffff8802216a9b80] finish_unfinished at ffffffffa05dd8b0 [reiserfs]
#9 [ffff8802216a9cc0] reiserfs_fill_super at ffffffffa05de825 [reiserfs]
RIP: 00007f7b9303997a RSP: 00007ffff443c7a8 RFLAGS: 00010202
RAX: 00000000000000a5 RBX: ffffffff8144ef12 RCX: 00007f7b932e9ee0
RDX: 00007f7b93d9a400 RSI: 00007f7b93d9a3e0 RDI: 00007f7b93d9a3c0
RBP: 00007f7b93d9a2c0 R8: 00007f7b93d9a550 R9: 0000000000000001
R10: ffffffffc0ed040e R11: 0000000000000202 R12: 000000000000040e
R13: 0000000000000000 R14: 00000000c0ed040e R15: 00007ffff443ca20
ORIG_RAX: 00000000000000a5 CS: 0033 SS: 002b

Signed-off-by: Mike Galbraith <[email protected]>
Acked-by: Frederic Weisbecker <[email protected]>
Acked-by: Mike Galbraith <[email protected]>
Signed-off-by: Jan Kara <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/reiserfs/super.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 580b038456f8..77663d68ee02 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -188,7 +188,15 @@ static int remove_save_link_only(struct super_block *s,
static int reiserfs_quota_on_mount(struct super_block *, int);
#endif

-/* look for uncompleted unlinks and truncates and complete them */
+/*
+ * Look for uncompleted unlinks and truncates and complete them
+ *
+ * Called with superblock write locked. If quotas are enabled, we have to
+ * release/retake lest we call dquot_quota_on_mount(), proceed to
+ * schedule_on_each_cpu() in invalidate_bdev() and deadlock waiting for the per
+ * cpu worklets to complete flush_async_commits() that in turn wait for the
+ * superblock write lock.
+ */
static int finish_unfinished(struct super_block *s)
{
INITIALIZE_PATH(path);
@@ -235,7 +243,9 @@ static int finish_unfinished(struct super_block *s)
quota_enabled[i] = 0;
continue;
}
+ reiserfs_write_unlock(s);
ret = reiserfs_quota_on_mount(s, i);
+ reiserfs_write_lock(s);
if (ret < 0)
reiserfs_warning(s, "reiserfs-2500",
"cannot turn on journaled "
--
2.10.2

2016-11-07 13:24:20

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 09/72] gpio: mpc8xxx: Correct irq handler function

From: Liu Gang <[email protected]>

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

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

commit d71cf15b865bdd45925f7b094d169aaabd705145 upstream.

>From the beginning of the gpio-mpc8xxx.c, the "handle_level_irq"
has being used to handle GPIO interrupts in the PowerPC/Layerscape
platforms. But actually, almost all PowerPC/Layerscape platforms
assert an interrupt request upon either a high-to-low change or
any change on the state of the signal.

So the "handle_level_irq" is not reasonable for PowerPC/Layerscape
GPIO interrupt, it should be "handle_edge_irq". Otherwise the system
may lost some interrupts from the PIN's state changes.

Signed-off-by: Liu Gang <[email protected]>
Signed-off-by: Linus Walleij <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/gpio/gpio-mpc8xxx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index 2aa3ca215bd6..d5376aa1c5e1 100644
--- a/drivers/gpio/gpio-mpc8xxx.c
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -295,7 +295,7 @@ static int mpc8xxx_gpio_irq_map(struct irq_domain *h, unsigned int virq,
mpc8xxx_irq_chip.irq_set_type = mpc8xxx_gc->of_dev_id_data;

irq_set_chip_data(virq, h->host_data);
- irq_set_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq);
+ irq_set_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_edge_irq);

return 0;
}
--
2.10.2

2016-11-07 13:24:19

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 10/72] regulator: tps65910: Work around silicon erratum SWCZ010

From: Jan Remmet <[email protected]>

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

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

commit 8f9165c981fed187bb483de84caf9adf835aefda upstream.

http://www.ti.com/lit/pdf/SWCZ010:
DCDC o/p voltage can go higher than programmed value

Impact:
VDDI, VDD2, and VIO output programmed voltage level can go higher than
expected or crash, when coming out of PFM to PWM mode or using DVFS.

Description:
When DCDC CLK SYNC bits are 11/01:
* VIO 3-MHz oscillator is the source clock of the digital core and input
clock of VDD1 and VDD2
* Turn-on of VDD1 and VDD2 HSD PFETis synchronized or at a constant
phase shift
* Current pulled though VCC1+VCC2 is Iload(VDD1) + Iload(VDD2)
* The 3 HSD PFET will be turned-on at the same time, causing the highest
possible switching noise on the application. This noise level depends
on the layout, the VBAT level, and the load current. The noise level
increases with improper layout.

When DCDC CLK SYNC bits are 00:
* VIO 3-MHz oscillator is the source clock of digital core
* VDD1 and VDD2 are running on their own 3-MHz oscillator
* Current pulled though VCC1+VCC2 average of Iload(VDD1) + Iload(VDD2)
* The switching noise of the 3 SMPS will be randomly spread over time,
causing lower overall switching noise.

Workaround:
Set DCDCCTRL_REG[1:0]= 00.

Signed-off-by: Jan Remmet <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/regulator/tps65910-regulator.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c
index 45c16447744b..1ed4145164d6 100644
--- a/drivers/regulator/tps65910-regulator.c
+++ b/drivers/regulator/tps65910-regulator.c
@@ -1080,6 +1080,12 @@ static int tps65910_probe(struct platform_device *pdev)
pmic->num_regulators = ARRAY_SIZE(tps65910_regs);
pmic->ext_sleep_control = tps65910_ext_sleep_control;
info = tps65910_regs;
+ /* Work around silicon erratum SWCZ010: output programmed
+ * voltage level can go higher than expected or crash
+ * Workaround: use no synchronization of DCDC clocks
+ */
+ tps65910_reg_clear_bits(pmic->mfd, TPS65910_DCDCCTRL,
+ DCDCCTRL_DCDCCKSYNC_MASK);
break;
case TPS65911:
pmic->get_ctrl_reg = &tps65911_get_ctrl_register;
--
2.10.2

2016-11-07 13:24:57

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 06/72] cfq: fix starvation of asynchronous writes

From: Glauber Costa <[email protected]>

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

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

commit 3932a86b4b9d1f0b049d64d4591ce58ad18b44ec upstream.

While debugging timeouts happening in my application workload (ScyllaDB), I have
observed calls to open() taking a long time, ranging everywhere from 2 seconds -
the first ones that are enough to time out my application - to more than 30
seconds.

The problem seems to happen because XFS may block on pending metadata updates
under certain circumnstances, and that's confirmed with the following backtrace
taken by the offcputime tool (iovisor/bcc):

ffffffffb90c57b1 finish_task_switch
ffffffffb97dffb5 schedule
ffffffffb97e310c schedule_timeout
ffffffffb97e1f12 __down
ffffffffb90ea821 down
ffffffffc046a9dc xfs_buf_lock
ffffffffc046abfb _xfs_buf_find
ffffffffc046ae4a xfs_buf_get_map
ffffffffc046babd xfs_buf_read_map
ffffffffc0499931 xfs_trans_read_buf_map
ffffffffc044a561 xfs_da_read_buf
ffffffffc0451390 xfs_dir3_leaf_read.constprop.16
ffffffffc0452b90 xfs_dir2_leaf_lookup_int
ffffffffc0452e0f xfs_dir2_leaf_lookup
ffffffffc044d9d3 xfs_dir_lookup
ffffffffc047d1d9 xfs_lookup
ffffffffc0479e53 xfs_vn_lookup
ffffffffb925347a path_openat
ffffffffb9254a71 do_filp_open
ffffffffb9242a94 do_sys_open
ffffffffb9242b9e sys_open
ffffffffb97e42b2 entry_SYSCALL_64_fastpath
00007fb0698162ed [unknown]

Inspecting my run with blktrace, I can see that the xfsaild kthread exhibit very
high "Dispatch wait" times, on the dozens of seconds range and consistent with
the open() times I have saw in that run.

Still from the blktrace output, we can after searching a bit, identify the
request that wasn't dispatched:

8,0 11 152 81.092472813 804 A WM 141698288 + 8 <- (8,1) 141696240
8,0 11 153 81.092472889 804 Q WM 141698288 + 8 [xfsaild/sda1]
8,0 11 154 81.092473207 804 G WM 141698288 + 8 [xfsaild/sda1]
8,0 11 206 81.092496118 804 I WM 141698288 + 8 ( 22911) [xfsaild/sda1]
<==== 'I' means Inserted (into the IO scheduler) ===================================>
8,0 0 289372 96.718761435 0 D WM 141698288 + 8 (15626265317) [swapper/0]
<==== Only 15s later the CFQ scheduler dispatches the request ======================>

As we can see above, in this particular example CFQ took 15 seconds to dispatch
this request. Going back to the full trace, we can see that the xfsaild queue
had plenty of opportunity to run, and it was selected as the active queue many
times. It would just always be preempted by something else (example):

8,0 1 0 81.117912979 0 m N cfq1618SN / insert_request
8,0 1 0 81.117913419 0 m N cfq1618SN / add_to_rr
8,0 1 0 81.117914044 0 m N cfq1618SN / preempt
8,0 1 0 81.117914398 0 m N cfq767A / slice expired t=1
8,0 1 0 81.117914755 0 m N cfq767A / resid=40
8,0 1 0 81.117915340 0 m N / served: vt=1948520448 min_vt=1948520448
8,0 1 0 81.117915858 0 m N cfq767A / sl_used=1 disp=0 charge=0 iops=1 sect=0

where cfq767 is the xfsaild queue and cfq1618 corresponds to one of the ScyllaDB
IO dispatchers.

The requests preempting the xfsaild queue are synchronous requests. That's a
characteristic of ScyllaDB workloads, as we only ever issue O_DIRECT requests.
While it can be argued that preempting ASYNC requests in favor of SYNC is part
of the CFQ logic, I don't believe that doing so for 15+ seconds is anyone's
goal.

Moreover, unless I am misunderstanding something, that breaks the expectation
set by the "fifo_expire_async" tunable, which in my system is set to the
default.

Looking at the code, it seems to me that the issue is that after we make
an async queue active, there is no guarantee that it will execute any request.

When the queue itself tests if it cfq_may_dispatch() it can bail if it sees SYNC
requests in flight. An incoming request from another queue can also preempt it
in such situation before we have the chance to execute anything (as seen in the
trace above).

This patch sets the must_dispatch flag if we notice that we have requests
that are already fifo_expired. This flag is always cleared after
cfq_dispatch_request() returns from cfq_dispatch_requests(), so it won't pin
the queue for subsequent requests (unless they are themselves expired)

Care is taken during preempt to still allow rt requests to preempt us
regardless.

Testing my workload with this patch applied produces much better results.
>From the application side I see no timeouts, and the open() latency histogram
generated by systemtap looks much better, with the worst outlier at 131ms:

Latency histogram of xfs_buf_lock acquisition (microseconds):
value |-------------------------------------------------- count
0 | 11
1 |@@@@ 161
2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1966
4 |@ 54
8 | 36
16 | 7
32 | 0
64 | 0
~
1024 | 0
2048 | 0
4096 | 1
8192 | 1
16384 | 2
32768 | 0
65536 | 0
131072 | 1
262144 | 0
524288 | 0

Signed-off-by: Glauber Costa <[email protected]>
CC: Jens Axboe <[email protected]>
CC: [email protected]
CC: [email protected]
Signed-off-by: Glauber Costa <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
block/cfq-iosched.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index b19c9f391761..cf3c8dc4acce 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -2812,7 +2812,6 @@ static struct request *cfq_check_fifo(struct cfq_queue *cfqq)
if (time_before(jiffies, rq_fifo_time(rq)))
rq = NULL;

- cfq_log_cfqq(cfqq->cfqd, cfqq, "fifo=%p", rq);
return rq;
}

@@ -3186,6 +3185,9 @@ static bool cfq_may_dispatch(struct cfq_data *cfqd, struct cfq_queue *cfqq)
{
unsigned int max_dispatch;

+ if (cfq_cfqq_must_dispatch(cfqq))
+ return true;
+
/*
* Drain async requests before we start sync IO
*/
@@ -3277,15 +3279,20 @@ static bool cfq_dispatch_request(struct cfq_data *cfqd, struct cfq_queue *cfqq)

BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list));

+ rq = cfq_check_fifo(cfqq);
+ if (rq)
+ cfq_mark_cfqq_must_dispatch(cfqq);
+
if (!cfq_may_dispatch(cfqd, cfqq))
return false;

/*
* follow expired path, else get first next available
*/
- rq = cfq_check_fifo(cfqq);
if (!rq)
rq = cfqq->next_rq;
+ else
+ cfq_log_cfqq(cfqq->cfqd, cfqq, "fifo=%p", rq);

/*
* insert request into driver dispatch list
@@ -3794,7 +3801,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
* if the new request is sync, but the currently running queue is
* not, let the sync request have priority.
*/
- if (rq_is_sync(rq) && !cfq_cfqq_sync(cfqq))
+ if (rq_is_sync(rq) && !cfq_cfqq_sync(cfqq) && !cfq_cfqq_must_dispatch(cfqq))
return true;

if (new_cfqq->cfqg != cfqq->cfqg)
--
2.10.2

2016-11-07 13:24:53

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 08/72] ipc: remove use of seq_printf return value

From: Joe Perches <[email protected]>

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

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

commit 7f032d6ef6154868a2a5d5f6b2c3f8587292196c upstream.

The seq_printf return value, because it's frequently misused,
will eventually be converted to void.

See: commit 1f33c41c03da ("seq_file: Rename seq_overflow() to
seq_has_overflowed() and make public")

Signed-off-by: Joe Perches <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
ipc/msg.c | 34 ++++++++++++++++++----------------
ipc/sem.c | 26 ++++++++++++++------------
ipc/shm.c | 42 ++++++++++++++++++++++--------------------
ipc/util.c | 6 ++++--
4 files changed, 58 insertions(+), 50 deletions(-)

diff --git a/ipc/msg.c b/ipc/msg.c
index f8c22afff450..b92acb6a138c 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -1046,21 +1046,23 @@ static int sysvipc_msg_proc_show(struct seq_file *s, void *it)
struct user_namespace *user_ns = seq_user_ns(s);
struct msg_queue *msq = it;

- return seq_printf(s,
- "%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n",
- msq->q_perm.key,
- msq->q_perm.id,
- msq->q_perm.mode,
- msq->q_cbytes,
- msq->q_qnum,
- msq->q_lspid,
- msq->q_lrpid,
- from_kuid_munged(user_ns, msq->q_perm.uid),
- from_kgid_munged(user_ns, msq->q_perm.gid),
- from_kuid_munged(user_ns, msq->q_perm.cuid),
- from_kgid_munged(user_ns, msq->q_perm.cgid),
- msq->q_stime,
- msq->q_rtime,
- msq->q_ctime);
+ seq_printf(s,
+ "%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n",
+ msq->q_perm.key,
+ msq->q_perm.id,
+ msq->q_perm.mode,
+ msq->q_cbytes,
+ msq->q_qnum,
+ msq->q_lspid,
+ msq->q_lrpid,
+ from_kuid_munged(user_ns, msq->q_perm.uid),
+ from_kgid_munged(user_ns, msq->q_perm.gid),
+ from_kuid_munged(user_ns, msq->q_perm.cuid),
+ from_kgid_munged(user_ns, msq->q_perm.cgid),
+ msq->q_stime,
+ msq->q_rtime,
+ msq->q_ctime);
+
+ return 0;
}
#endif
diff --git a/ipc/sem.c b/ipc/sem.c
index 7fb486739cbb..9e963c28a214 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -2174,17 +2174,19 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it)

sem_otime = get_semotime(sma);

- return seq_printf(s,
- "%10d %10d %4o %10u %5u %5u %5u %5u %10lu %10lu\n",
- sma->sem_perm.key,
- sma->sem_perm.id,
- sma->sem_perm.mode,
- sma->sem_nsems,
- from_kuid_munged(user_ns, sma->sem_perm.uid),
- from_kgid_munged(user_ns, sma->sem_perm.gid),
- from_kuid_munged(user_ns, sma->sem_perm.cuid),
- from_kgid_munged(user_ns, sma->sem_perm.cgid),
- sem_otime,
- sma->sem_ctime);
+ seq_printf(s,
+ "%10d %10d %4o %10u %5u %5u %5u %5u %10lu %10lu\n",
+ sma->sem_perm.key,
+ sma->sem_perm.id,
+ sma->sem_perm.mode,
+ sma->sem_nsems,
+ from_kuid_munged(user_ns, sma->sem_perm.uid),
+ from_kgid_munged(user_ns, sma->sem_perm.gid),
+ from_kuid_munged(user_ns, sma->sem_perm.cuid),
+ from_kgid_munged(user_ns, sma->sem_perm.cgid),
+ sem_otime,
+ sma->sem_ctime);
+
+ return 0;
}
#endif
diff --git a/ipc/shm.c b/ipc/shm.c
index 02f7125c8a0f..4066519acc64 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -1340,25 +1340,27 @@ static int sysvipc_shm_proc_show(struct seq_file *s, void *it)
#define SIZE_SPEC "%21lu"
#endif

- return seq_printf(s,
- "%10d %10d %4o " SIZE_SPEC " %5u %5u "
- "%5lu %5u %5u %5u %5u %10lu %10lu %10lu "
- SIZE_SPEC " " SIZE_SPEC "\n",
- shp->shm_perm.key,
- shp->shm_perm.id,
- shp->shm_perm.mode,
- shp->shm_segsz,
- shp->shm_cprid,
- shp->shm_lprid,
- shp->shm_nattch,
- from_kuid_munged(user_ns, shp->shm_perm.uid),
- from_kgid_munged(user_ns, shp->shm_perm.gid),
- from_kuid_munged(user_ns, shp->shm_perm.cuid),
- from_kgid_munged(user_ns, shp->shm_perm.cgid),
- shp->shm_atim,
- shp->shm_dtim,
- shp->shm_ctim,
- rss * PAGE_SIZE,
- swp * PAGE_SIZE);
+ seq_printf(s,
+ "%10d %10d %4o " SIZE_SPEC " %5u %5u "
+ "%5lu %5u %5u %5u %5u %10lu %10lu %10lu "
+ SIZE_SPEC " " SIZE_SPEC "\n",
+ shp->shm_perm.key,
+ shp->shm_perm.id,
+ shp->shm_perm.mode,
+ shp->shm_segsz,
+ shp->shm_cprid,
+ shp->shm_lprid,
+ shp->shm_nattch,
+ from_kuid_munged(user_ns, shp->shm_perm.uid),
+ from_kgid_munged(user_ns, shp->shm_perm.gid),
+ from_kuid_munged(user_ns, shp->shm_perm.cuid),
+ from_kgid_munged(user_ns, shp->shm_perm.cgid),
+ shp->shm_atim,
+ shp->shm_dtim,
+ shp->shm_ctim,
+ rss * PAGE_SIZE,
+ swp * PAGE_SIZE);
+
+ return 0;
}
#endif
diff --git a/ipc/util.c b/ipc/util.c
index 735342570a87..cc106890784b 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -904,8 +904,10 @@ static int sysvipc_proc_show(struct seq_file *s, void *it)
struct ipc_proc_iter *iter = s->private;
struct ipc_proc_iface *iface = iter->iface;

- if (it == SEQ_START_TOKEN)
- return seq_puts(s, iface->header);
+ if (it == SEQ_START_TOKEN) {
+ seq_puts(s, iface->header);
+ return 0;
+ }

return iface->show(s, it);
}
--
2.10.2

2016-11-07 13:25:33

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 07/72] pstore: Fix buffer overflow while write offset equal to buffer size

From: Liu ShuoX <[email protected]>

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

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

commit 017321cf390045dd4c4afc4a232995ea50bcf66d upstream.

In case new offset is equal to prz->buffer_size, it won't wrap at this
time and will return old(overflow) value next time.

Signed-off-by: Liu ShuoX <[email protected]>
Acked-by: Kees Cook <[email protected]>
Signed-off-by: Tony Luck <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/pstore/ram_core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c
index bda61a759b68..0b367ef7a7d6 100644
--- a/fs/pstore/ram_core.c
+++ b/fs/pstore/ram_core.c
@@ -54,7 +54,7 @@ static size_t buffer_start_add_atomic(struct persistent_ram_zone *prz, size_t a)
do {
old = atomic_read(&prz->buffer->start);
new = old + a;
- while (unlikely(new > prz->buffer_size))
+ while (unlikely(new >= prz->buffer_size))
new -= prz->buffer_size;
} while (atomic_cmpxchg(&prz->buffer->start, old, new) != old);

@@ -91,7 +91,7 @@ static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a)

old = atomic_read(&prz->buffer->start);
new = old + a;
- while (unlikely(new > prz->buffer_size))
+ while (unlikely(new >= prz->buffer_size))
new -= prz->buffer_size;
atomic_set(&prz->buffer->start, new);

--
2.10.2

2016-11-07 13:32:21

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 70/72] i2c: core: fix NULL pointer dereference under race condition

From: Vladimir Zapolskiy <[email protected]>

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

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

commit 147b36d5b70c083cc76770c47d60b347e8eaf231 upstream.

Race condition between registering an I2C device driver and
deregistering an I2C adapter device which is assumed to manage that
I2C device may lead to a NULL pointer dereference due to the
uninitialized list head of driver clients.

The root cause of the issue is that the I2C bus may know about the
registered device driver and thus it is matched by bus_for_each_drv(),
but the list of clients is not initialized and commonly it is NULL,
because I2C device drivers define struct i2c_driver as static and
clients field is expected to be initialized by I2C core:

i2c_register_driver() i2c_del_adapter()
driver_register() ...
bus_add_driver() ...
... bus_for_each_drv(..., __process_removed_adapter)
... i2c_do_del_adapter()
... list_for_each_entry_safe(..., &driver->clients, ...)
INIT_LIST_HEAD(&driver->clients);

To solve the problem it is sufficient to do clients list head
initialization before calling driver_register().

The problem was found while using an I2C device driver with a sluggish
registration routine on a bus provided by a physically detachable I2C
master controller, but practically the oops may be reproduced under
the race between arbitraty I2C device driver registration and managing
I2C bus device removal e.g. by unbinding the latter over sysfs:

% echo 21a4000.i2c > /sys/bus/platform/drivers/imx-i2c/unbind
Unable to handle kernel NULL pointer dereference at virtual address 00000000
Internal error: Oops: 17 [#1] SMP ARM
CPU: 2 PID: 533 Comm: sh Not tainted 4.9.0-rc3+ #61
Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
task: e5ada400 task.stack: e4936000
PC is at i2c_do_del_adapter+0x20/0xcc
LR is at __process_removed_adapter+0x14/0x1c
Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
Control: 10c5387d Table: 35bd004a DAC: 00000051
Process sh (pid: 533, stack limit = 0xe4936210)
Stack: (0xe4937d28 to 0xe4938000)
Backtrace:
[<c0667be0>] (i2c_do_del_adapter) from [<c0667cc0>] (__process_removed_adapter+0x14/0x1c)
[<c0667cac>] (__process_removed_adapter) from [<c0516998>] (bus_for_each_drv+0x6c/0xa0)
[<c051692c>] (bus_for_each_drv) from [<c06685ec>] (i2c_del_adapter+0xbc/0x284)
[<c0668530>] (i2c_del_adapter) from [<bf0110ec>] (i2c_imx_remove+0x44/0x164 [i2c_imx])
[<bf0110a8>] (i2c_imx_remove [i2c_imx]) from [<c051a838>] (platform_drv_remove+0x2c/0x44)
[<c051a80c>] (platform_drv_remove) from [<c05183d8>] (__device_release_driver+0x90/0x12c)
[<c0518348>] (__device_release_driver) from [<c051849c>] (device_release_driver+0x28/0x34)
[<c0518474>] (device_release_driver) from [<c0517150>] (unbind_store+0x80/0x104)
[<c05170d0>] (unbind_store) from [<c0516520>] (drv_attr_store+0x28/0x34)
[<c05164f8>] (drv_attr_store) from [<c0298acc>] (sysfs_kf_write+0x50/0x54)
[<c0298a7c>] (sysfs_kf_write) from [<c029801c>] (kernfs_fop_write+0x100/0x214)
[<c0297f1c>] (kernfs_fop_write) from [<c0220130>] (__vfs_write+0x34/0x120)
[<c02200fc>] (__vfs_write) from [<c0221088>] (vfs_write+0xa8/0x170)
[<c0220fe0>] (vfs_write) from [<c0221e74>] (SyS_write+0x4c/0xa8)
[<c0221e28>] (SyS_write) from [<c0108a20>] (ret_fast_syscall+0x0/0x1c)

Signed-off-by: Vladimir Zapolskiy <[email protected]>
Signed-off-by: Wolfram Sang <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/i2c/i2c-core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index b5de139920e3..0a36be44dc72 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -1522,6 +1522,7 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
/* add the driver to the list of i2c drivers in the driver core */
driver->driver.owner = owner;
driver->driver.bus = &i2c_bus_type;
+ INIT_LIST_HEAD(&driver->clients);

/* When registration returns, the driver core
* will have called probe() for all matching-but-unbound devices.
@@ -1540,7 +1541,6 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)

pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);

- INIT_LIST_HEAD(&driver->clients);
/* Walk the adapters that are already present */
i2c_for_each_dev(driver, __process_new_driver);

--
2.10.2

2016-11-07 13:32:24

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 69/72] Revert "fix minor infoleak in get_user_ex()"

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

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

This reverts commit d42924ab1ec523c0671f5560d51750996be31d3a which is
1c109fabbd51863475cd12ac206bdd249aee35af upstream.

Signed-off-by: Jiri Slaby <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Linus Torvalds <[email protected]>
---
arch/x86/include/asm/uaccess.h | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index 01635e4e187a..5838fa911aa0 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -383,11 +383,7 @@ do { \
#define __get_user_asm_ex(x, addr, itype, rtype, ltype) \
asm volatile("1: mov"itype" %1,%"rtype"0\n" \
"2:\n" \
- ".section .fixup,\"ax\"\n" \
- "3:xor"itype" %"rtype"0,%"rtype"0\n" \
- " jmp 2b\n" \
- ".previous\n" \
- _ASM_EXTABLE_EX(1b, 3b) \
+ _ASM_EXTABLE_EX(1b, 2b) \
: ltype(x) : "m" (__m(addr)))

#define __put_user_nocheck(x, ptr, size) \
--
2.10.2

2016-11-07 13:32:26

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 68/72] powerpc/nvram: Fix an incorrect partition merge

From: Pan Xinhui <[email protected]>

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

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

commit 11b7e154b132232535befe51c55db048069c8461 upstream.

When we merge two contiguous partitions whose signatures are marked
NVRAM_SIG_FREE, We need update prev's length and checksum, then write it
to nvram, not cur's. So lets fix this mistake now.

Also use memset instead of strncpy to set the partition's name. It's
more readable if we want to fill up with duplicate chars .

Fixes: fa2b4e54d41f ("powerpc/nvram: Improve partition removal")
Signed-off-by: Pan Xinhui <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/powerpc/kernel/nvram_64.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
index 8213ee1eb05a..1def48da21b2 100644
--- a/arch/powerpc/kernel/nvram_64.c
+++ b/arch/powerpc/kernel/nvram_64.c
@@ -288,7 +288,7 @@ int __init nvram_remove_partition(const char *name, int sig,

/* Make partition a free partition */
part->header.signature = NVRAM_SIG_FREE;
- strncpy(part->header.name, "wwwwwwwwwwww", 12);
+ memset(part->header.name, 'w', 12);
part->header.checksum = nvram_checksum(&part->header);
rc = nvram_write_header(part);
if (rc <= 0) {
@@ -306,8 +306,8 @@ int __init nvram_remove_partition(const char *name, int sig,
}
if (prev) {
prev->header.length += part->header.length;
- prev->header.checksum = nvram_checksum(&part->header);
- rc = nvram_write_header(part);
+ prev->header.checksum = nvram_checksum(&prev->header);
+ rc = nvram_write_header(prev);
if (rc <= 0) {
printk(KERN_ERR "nvram_remove_partition: nvram_write failed (%d)\n", rc);
return rc;
--
2.10.2

2016-11-07 13:32:38

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 65/72] crypto: gcm - Fix IV buffer size in crypto_gcm_setkey

From: Ondrej Mosnáček <[email protected]>

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

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

commit 50d2e6dc1f83db0563c7d6603967bf9585ce934b upstream.

The cipher block size for GCM is 16 bytes, and thus the CTR transform
used in crypto_gcm_setkey() will also expect a 16-byte IV. However,
the code currently reserves only 8 bytes for the IV, causing
an out-of-bounds access in the CTR transform. This patch fixes
the issue by setting the size of the IV buffer to 16 bytes.

Fixes: 84c911523020 ("[CRYPTO] gcm: Add support for async ciphers")
Signed-off-by: Ondrej Mosnacek <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
crypto/gcm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto/gcm.c b/crypto/gcm.c
index d2a0f7371cf0..49b6fb20cceb 100644
--- a/crypto/gcm.c
+++ b/crypto/gcm.c
@@ -109,7 +109,7 @@ static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key,
struct crypto_ablkcipher *ctr = ctx->ctr;
struct {
be128 hash;
- u8 iv[8];
+ u8 iv[16];

struct crypto_gcm_setkey_result result;

--
2.10.2

2016-11-07 13:32:30

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 67/72] perf symbols: Fixup symbol sizes before picking best ones

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

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

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

commit 432746f8e0b6a82ba832b771afe31abd51af6752 upstream.

When we call symbol__fixup_duplicate() we use algorithms to pick the
"best" symbols for cases where there are various functions/aliases to an
address, and those check zero size symbols, which, before calling
symbol__fixup_end() are _all_ symbols in a just parsed kallsyms file.

So first fixup the end, then fixup the duplicates.

Found while trying to figure out why 'perf test vmlinux' failed, see the
output of 'perf test -v vmlinux' to see cases where the symbols picked
as best for vmlinux don't match the ones picked for kallsyms.

Cc: Anton Blanchard <[email protected]>
Cc: Adrian Hunter <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Masami Hiramatsu <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Wang Nan <[email protected]>
Fixes: 694bf407b061 ("perf symbols: Add some heuristics for choosing the best duplicate symbol")
Link: http://lkml.kernel.org/n/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
tools/perf/util/symbol-elf.c | 2 +-
tools/perf/util/symbol.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index a9c829be5216..0b6e9bacfe58 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -952,8 +952,8 @@ new_symbol:
* For misannotated, zeroed, ASM function sizes.
*/
if (nr > 0) {
- symbols__fixup_duplicate(&dso->symbols[map->type]);
symbols__fixup_end(&dso->symbols[map->type]);
+ symbols__fixup_duplicate(&dso->symbols[map->type]);
if (kmap) {
/*
* We need to fixup this here too because we create new
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 7eb0362f4ffd..3c8f825eb7d4 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -903,8 +903,8 @@ int dso__load_kallsyms(struct dso *dso, const char *filename,
if (dso__load_all_kallsyms(dso, filename, map) < 0)
return -1;

- symbols__fixup_duplicate(&dso->symbols[map->type]);
symbols__fixup_end(&dso->symbols[map->type]);
+ symbols__fixup_duplicate(&dso->symbols[map->type]);

if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;
--
2.10.2

2016-11-07 13:32:34

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 66/72] hwrng: omap - Only fail if pm_runtime_get_sync returns < 0

From: Dave Gerlach <[email protected]>

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

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

commit ad8529fde9e3601180a839867a8ab041109aebb5 upstream.

Currently omap-rng checks the return value of pm_runtime_get_sync and
reports failure if anything is returned, however it should be checking
if ret < 0 as pm_runtime_get_sync return 0 on success but also can return
1 if the device was already active which is not a failure case. Only
values < 0 are actual failures.

Fixes: 61dc0a446e5d ("hwrng: omap - Fix assumption that runtime_get_sync will always succeed")
Signed-off-by: Dave Gerlach <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/char/hw_random/omap-rng.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c
index d9c1fa0e3648..b950668ddd67 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -387,7 +387,7 @@ static int omap_rng_probe(struct platform_device *pdev)

pm_runtime_enable(&pdev->dev);
ret = pm_runtime_get_sync(&pdev->dev);
- if (ret) {
+ if (ret < 0) {
dev_err(&pdev->dev, "Failed to runtime_get device: %d\n", ret);
pm_runtime_put_noidle(&pdev->dev);
goto err_ioremap;
@@ -447,7 +447,7 @@ static int omap_rng_resume(struct device *dev)
int ret;

ret = pm_runtime_get_sync(dev);
- if (ret) {
+ if (ret < 0) {
dev_err(dev, "Failed to runtime_get device: %d\n", ret);
pm_runtime_put_noidle(dev);
return ret;
--
2.10.2

2016-11-07 13:32:17

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 71/72] scsi: arcmsr: Buffer overflow in arcmsr_iop_message_xfer()

From: Dan Carpenter <[email protected]>

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

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

commit 7bc2b55a5c030685b399bb65b6baa9ccc3d1f167 upstream.

We need to put an upper bound on "user_len" so the memcpy() doesn't
overflow.

[js] no ARCMSR_API_DATA_BUFLEN defined, use the number

Reported-by: Marco Grassi <[email protected]>
Signed-off-by: Dan Carpenter <[email protected]>
Reviewed-by: Tomas Henzl <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/scsi/arcmsr/arcmsr_hba.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 1822cb9ec623..66dda86e62e1 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1803,7 +1803,8 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,

case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
unsigned char *ver_addr;
- int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
+ uint32_t user_len;
+ int32_t my_empty_len, wqbuf_firstindex, wqbuf_lastindex;
uint8_t *pQbuffer, *ptmpuserbuffer;

ver_addr = kmalloc(1032, GFP_ATOMIC);
@@ -1820,6 +1821,11 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
}
ptmpuserbuffer = ver_addr;
user_len = pcmdmessagefld->cmdmessage.Length;
+ if (user_len > 1032) {
+ retvalue = ARCMSR_MESSAGE_FAIL;
+ kfree(ver_addr);
+ goto message_out;
+ }
memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len);
wqbuf_lastindex = acb->wqbuf_lastindex;
wqbuf_firstindex = acb->wqbuf_firstindex;
--
2.10.2

2016-11-07 13:32:14

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 72/72] usb: hub: change CLEAR_FEATURE to SET_FEATURE

From: Yonglong Wu <[email protected]>

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

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

commit 4e248000e0d3b406bd6612186835467f2f84486e upstream.

In USB20 specification, describes in chapter 9.4.5: The Remote Wakeup
field can be modified by the SetFeature() and ClearFeature() requests
using the DEVICE_REMOTE_WAKEUP feature selector.

In USB30 specification, also describes in chapter 9.4.5: The Function
Remote Wakeup field can be modified by the SetFeature() requests
using the FUNCTION_SUSPEND feature selector. In chapter 9.4.9 Set
Feature reference, it describes Function Remote Wake Enabled/Disabled
at suspend options by SET_FEATURE.

In USB30 specification only mentioned SetFeature(), so we need use
SET_FEATURE replace CLEAR_FEATURE to disable USB30 function remote
wakeup in suspend options.

Signed-off-by: Yonglong Wu <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/usb/core/hub.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 0fb8c85b77bf..5e788077675b 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2929,7 +2929,7 @@ static int usb_disable_remote_wakeup(struct usb_device *udev)
USB_CTRL_SET_TIMEOUT);
else
return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- USB_REQ_CLEAR_FEATURE, USB_RECIP_INTERFACE,
+ USB_REQ_SET_FEATURE, USB_RECIP_INTERFACE,
USB_INTRF_FUNC_SUSPEND, 0, NULL, 0,
USB_CTRL_SET_TIMEOUT);
}
--
2.10.2

2016-11-07 13:34:06

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 62/72] powerpc/eeh: Null check uses of eeh_pe_bus_get

From: Russell Currey <[email protected]>

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

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

commit 04fec21c06e35b169a83e75a84a015ab4606bf5e upstream.

eeh_pe_bus_get() can return NULL if a PCI bus isn't found for a given PE.
Some callers don't check this, and can cause a null pointer dereference
under certain circumstances.

Fix this by checking NULL everywhere eeh_pe_bus_get() is called.

Fixes: 8a6b1bc70dbb ("powerpc/eeh: EEH core to handle special event")
Signed-off-by: Russell Currey <[email protected]>
Reviewed-by: Andrew Donnellan <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/powerpc/kernel/eeh_driver.c | 8 ++++++++
arch/powerpc/platforms/powernv/eeh-ioda.c | 5 +++++
2 files changed, 13 insertions(+)

diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index d3a132c9127c..33d998fda24e 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -697,6 +697,14 @@ static void eeh_handle_special_event(void)

/* Notify all devices to be down */
bus = eeh_pe_bus_get(phb_pe);
+ if (!bus) {
+ pr_err("%s: Cannot find PCI bus for "
+ "PHB#%d-PE#%x\n",
+ __func__,
+ pe->phb->global_number,
+ pe->addr);
+ break;
+ }
eeh_pe_dev_traverse(pe,
eeh_report_failure, NULL);
pcibios_remove_pci_devices(bus);
diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c
index b91083370bc6..605a2f07618e 100644
--- a/arch/powerpc/platforms/powernv/eeh-ioda.c
+++ b/arch/powerpc/platforms/powernv/eeh-ioda.c
@@ -493,6 +493,11 @@ static int ioda_eeh_reset(struct eeh_pe *pe, int option)
ret = ioda_eeh_phb_reset(hose, option);
} else {
bus = eeh_pe_bus_get(pe);
+ if (!bus) {
+ pr_err("%s: Cannot find PCI bus for PHB#%d-PE#%x\n",
+ __func__, pe->phb->global_number, pe->addr);
+ return -EIO;
+ }
if (pci_is_root_bus(bus) ||
pci_is_root_bus(bus->parent))
ret = ioda_eeh_root_reset(hose, option);
--
2.10.2

2016-11-07 13:34:04

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 64/72] uio: fix dmem_region_start computation

From: Jan Viktorin <[email protected]>

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

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

commit 4d31a2588ae37a5d0f61f4d956454e9504846aeb upstream.

The variable i contains a total number of resources (including
IORESOURCE_IRQ). However, we want the dmem_region_start to point
after the last resource of type IORESOURCE_MEM. The original behaviour
leads (very likely) to skipping several UIO mapping regions and makes
them useless. Fix this by computing dmem_region_start from the uiomem
which points to the last used UIO mapping.

Fixes: 0a0c3b5a24bd ("Add new uio device for dynamic memory allocation")

Signed-off-by: Jan Viktorin <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/uio/uio_dmem_genirq.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c
index 1270f3b26139..9d6a9105d83f 100644
--- a/drivers/uio/uio_dmem_genirq.c
+++ b/drivers/uio/uio_dmem_genirq.c
@@ -229,7 +229,7 @@ static int uio_dmem_genirq_probe(struct platform_device *pdev)
++uiomem;
}

- priv->dmem_region_start = i;
+ priv->dmem_region_start = uiomem - &uioinfo->mem[0];
priv->num_dmem_regions = pdata->num_dynamic_regions;

for (i = 0; i < pdata->num_dynamic_regions; ++i) {
--
2.10.2

2016-11-07 13:34:03

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 63/72] genirq/generic_chip: Add irq_unmap callback

From: Sebastian Frias <[email protected]>

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

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

commit ee26c013cdee0b947e29d6cadfb9ff3341c69ff9 upstream.

Without this patch irq_domain_disassociate() cannot properly release the
interrupt. In fact, irq_map_generic_chip() checks a bit on 'gc->installed'
but said bit is never cleared, only set.

Commit 088f40b7b027 ("genirq: Generic chip: Add linear irq domain support")
added irq_map_generic_chip() function and also stated "This lacks a removal
function for now".

This commit provides an implementation of an unmap function that can be
called by irq_domain_disassociate().

[ tglx: Made the function static and removed the export as we have neither
a prototype nor a modular user. ]

[js] use irq_get_irq_data, irq_set_chip_and_handler, and
irq_set_chip_data in 3.12

Fixes: 088f40b7b027 ("genirq: Generic chip: Add linear irq domain support")
Signed-off-by: Sebastian Frias <[email protected]>
Cc: Marc Zyngier <[email protected]>
Cc: Mason <[email protected]>
Cc: Jason Cooper <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
kernel/irq/generic-chip.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)

diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c
index 452d6f2ba21d..6733fbf14dbe 100644
--- a/kernel/irq/generic-chip.c
+++ b/kernel/irq/generic-chip.c
@@ -395,8 +395,28 @@ static int irq_map_generic_chip(struct irq_domain *d, unsigned int virq,
return 0;
}

+static void irq_unmap_generic_chip(struct irq_domain *d, unsigned int virq)
+{
+ struct irq_data *data = irq_get_irq_data(virq);
+ struct irq_domain_chip_generic *dgc = d->gc;
+ unsigned int hw_irq = data->hwirq;
+ struct irq_chip_generic *gc;
+ int irq_idx;
+
+ gc = irq_get_domain_generic_chip(d, hw_irq);
+ if (!gc)
+ return;
+
+ irq_idx = hw_irq % dgc->irqs_per_chip;
+
+ clear_bit(irq_idx, &gc->installed);
+ irq_set_chip_and_handler(virq, &no_irq_chip, NULL);
+ irq_set_chip_data(virq, NULL);
+}
+
struct irq_domain_ops irq_generic_chip_ops = {
.map = irq_map_generic_chip,
+ .unmap = irq_unmap_generic_chip,
.xlate = irq_domain_xlate_onetwocell,
};
EXPORT_SYMBOL_GPL(irq_generic_chip_ops);
--
2.10.2

2016-11-07 17:04:39

by Linus Torvalds

[permalink] [raw]
Subject: Re: [PATCH 3.12 69/72] Revert "fix minor infoleak in get_user_ex()"

So a patch something like this might be a safe way to fix the
potential infoleak in older kernels.

THIS IS UNTESTED. It's a very obvious patch, though, so if it compiles
it probably works. It just initializes the output variable with 0 in
the inline asm description, instead of doing it in the exception
handler.

It will generate slightly worse code (a few unnecessary ALU
operations), but it doesn't have any interactions with the exception
handler implementation.

Linus


Attachments:
patch.diff (1.45 kB)

2016-11-07 17:17:06

by Guenter Roeck

[permalink] [raw]
Subject: Re: [PATCH 3.12 00/72] 3.12.67-stable review

On 11/07/2016 05:04 AM, Jiri Slaby wrote:
> This is the start of the stable review cycle for the 3.12.67 release.
> There are 72 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 Wed Nov 9 14:03:48 CET 2016.
> Anything received after that time might be too late.
>

Build results:
total: 128 pass: 127 fail: 1
Failed builds:
um:defconfig

Qemu test results:
total: 85 pass: 85 fail: 0

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

Build error log for um:defconfig:

ipc/sem.c: In function 'complexmode_tryleave':
ipc/sem.c:317:2: error: implicit declaration of function 'smp_store_release'
ipc/sem.c: In function 'sem_lock':
ipc/sem.c:370:3: error: implicit declaration of function 'smp_load_acquire'

Culprit is commit a198951bf258 ("ipc/sem.c: fix complex_count vs. simple op race"),
and reverting it fixes the problem. Copying the patch author for feedback.

Guenter

2016-11-07 18:35:07

by Shuah Khan

[permalink] [raw]
Subject: Re: [PATCH 3.12 00/72] 3.12.67-stable review

On 11/07/2016 06:04 AM, Jiri Slaby wrote:
> This is the start of the stable review cycle for the 3.12.67 release.
> There are 72 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 Wed Nov 9 14:03:48 CET 2016.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> http://kernel.org/pub/linux/kernel/people/jirislaby/stable-review/patch-3.12.67-rc1.xz
> and the diffstat can be found below.
>
> thanks,
> js
>

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

thanks,
-- Shuah

--
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America(Silicon Valley)
[email protected]

2016-11-08 10:37:23

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH 3.12 69/72] Revert "fix minor infoleak in get_user_ex()"

On Mon, Nov 07, 2016 at 08:45:59AM -0800, Linus Torvalds wrote:
> So a patch something like this might be a safe way to fix the
> potential infoleak in older kernels.
>
> THIS IS UNTESTED. It's a very obvious patch, though, so if it compiles
> it probably works. It just initializes the output variable with 0 in
> the inline asm description, instead of doing it in the exception
> handler.
>
> It will generate slightly worse code (a few unnecessary ALU
> operations), but it doesn't have any interactions with the exception
> handler implementation.

It builds here, so I've queued it up for 4.4-stable, let's see if
the auto-builders have any problems with it. Thanks for the patch.

greg k-h

2016-11-08 15:40:28

by Jiri Slaby

[permalink] [raw]
Subject: Re: [PATCH 3.12 00/72] 3.12.67-stable review

On 11/07/2016, 06:16 PM, Guenter Roeck wrote:
> On 11/07/2016 05:04 AM, Jiri Slaby wrote:
>> This is the start of the stable review cycle for the 3.12.67 release.
>> There are 72 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 Wed Nov 9 14:03:48 CET 2016.
>> Anything received after that time might be too late.
>>
>
> Build results:
> total: 128 pass: 127 fail: 1
> Failed builds:
> um:defconfig
>
> Qemu test results:
> total: 85 pass: 85 fail: 0
>
> Details are available at http://kerneltests.org/builders.
>
> Build error log for um:defconfig:
>
> ipc/sem.c: In function 'complexmode_tryleave':
> ipc/sem.c:317:2: error: implicit declaration of function
> 'smp_store_release'
> ipc/sem.c: In function 'sem_lock':
> ipc/sem.c:370:3: error: implicit declaration of function 'smp_load_acquire'
>
> Culprit is commit a198951bf258 ("ipc/sem.c: fix complex_count vs. simple
> op race"),
> and reverting it fixes the problem. Copying the patch author for feedback.

Oh, thanks!

I backported this to fix the problem:
commit 577f183acc88645eae116326cc2203dc88ea730c
Author: Michael S. Tsirkin <[email protected]>
Date: Mon Dec 21 09:22:18 2015 +0200

x86/um: reuse asm-generic/barrier.h

Everything should be fine now, let's see the results :).

thanks,
--
js
suse labs

2016-11-09 04:14:19

by Guenter Roeck

[permalink] [raw]
Subject: Re: [PATCH 3.12 00/72] 3.12.67-stable review

On 11/08/2016 07:40 AM, Jiri Slaby wrote:
> On 11/07/2016, 06:16 PM, Guenter Roeck wrote:
>> On 11/07/2016 05:04 AM, Jiri Slaby wrote:
>>> This is the start of the stable review cycle for the 3.12.67 release.
>>> There are 72 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 Wed Nov 9 14:03:48 CET 2016.
>>> Anything received after that time might be too late.
>>>
>>
>> Build results:
>> total: 128 pass: 127 fail: 1
>> Failed builds:
>> um:defconfig
>>
>> Qemu test results:
>> total: 85 pass: 85 fail: 0
>>
>> Details are available at http://kerneltests.org/builders.
>>
>> Build error log for um:defconfig:
>>
>> ipc/sem.c: In function 'complexmode_tryleave':
>> ipc/sem.c:317:2: error: implicit declaration of function
>> 'smp_store_release'
>> ipc/sem.c: In function 'sem_lock':
>> ipc/sem.c:370:3: error: implicit declaration of function 'smp_load_acquire'
>>
>> Culprit is commit a198951bf258 ("ipc/sem.c: fix complex_count vs. simple
>> op race"),
>> and reverting it fixes the problem. Copying the patch author for feedback.
>
> Oh, thanks!
>
> I backported this to fix the problem:
> commit 577f183acc88645eae116326cc2203dc88ea730c
> Author: Michael S. Tsirkin <[email protected]>
> Date: Mon Dec 21 09:22:18 2015 +0200
>
> x86/um: reuse asm-generic/barrier.h
>
> Everything should be fine now, let's see the results :).
>

Yes, all ok now.

Guenter

2016-11-10 18:50:47

by Jiri Slaby

[permalink] [raw]
Subject: Re: [PATCH 3.12 00/72] 3.12.67-stable review

On 11/09/2016, 05:14 AM, Guenter Roeck wrote:
> On 11/08/2016 07:40 AM, Jiri Slaby wrote:
>> On 11/07/2016, 06:16 PM, Guenter Roeck wrote:
>>> On 11/07/2016 05:04 AM, Jiri Slaby wrote:
>>>> This is the start of the stable review cycle for the 3.12.67 release.
>>>> There are 72 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 Wed Nov 9 14:03:48 CET 2016.
>>>> Anything received after that time might be too late.
>>>>
>>>
>>> Build results:
>>> total: 128 pass: 127 fail: 1
>>> Failed builds:
>>> um:defconfig
>>>
>>> Qemu test results:
>>> total: 85 pass: 85 fail: 0
>>>
>>> Details are available at http://kerneltests.org/builders.
>>>
>>> Build error log for um:defconfig:
>>>
>>> ipc/sem.c: In function 'complexmode_tryleave':
>>> ipc/sem.c:317:2: error: implicit declaration of function
>>> 'smp_store_release'
>>> ipc/sem.c: In function 'sem_lock':
>>> ipc/sem.c:370:3: error: implicit declaration of function
>>> 'smp_load_acquire'
>>>
>>> Culprit is commit a198951bf258 ("ipc/sem.c: fix complex_count vs. simple
>>> op race"),
>>> and reverting it fixes the problem. Copying the patch author for
>>> feedback.
>>
>> Oh, thanks!
>>
>> I backported this to fix the problem:
>> commit 577f183acc88645eae116326cc2203dc88ea730c
>> Author: Michael S. Tsirkin <[email protected]>
>> Date: Mon Dec 21 09:22:18 2015 +0200
>>
>> x86/um: reuse asm-generic/barrier.h
>>
>> Everything should be fine now, let's see the results :).
>>
>
> Yes, all ok now.

Ok, thanks for confirming!

--
js
suse labs

2016-11-10 18:51:06

by Jiri Slaby

[permalink] [raw]
Subject: Re: [PATCH 3.12 00/72] 3.12.67-stable review

On 11/07/2016, 07:34 PM, Shuah Khan wrote:
> Compiled and booted on my test system. No dmesg regressions.

Thanks for testing!

--
js
suse labs