2013-03-18 04:49:46

by Ben Hutchings

[permalink] [raw]
Subject: [ 00/82] 3.2.41-stable review

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

Responses should be made by Wed Mar 20 12:00:00 UTC 2013.
Anything received after that time might be too late.

A combined patch relative to 3.2.40 will be posted as an additional
response to this. A shortlog and diffstat can be found below.

Ben.

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

Al Viro (1):
vfs: fix pipe counter breakage
[a930d8790552658140d7d0d2e316af4f0d76a512]

Alan Stern (2):
NLS: improve UTF8 -> UTF16 string conversion routine
[0720a06a7518c9d0c0125bd5d1f3b6264c55c3dd]
USB: EHCI: don't check DMA values in QH overlays
[feca7746d5d9e84b105a613b7f3b6ad00d327372]

Alex Deucher (1):
drm/radeon: add primary dac adj quirk for R200 board
[e8fc41377f5037ff7a661ea06adc05f1daec1548]

Amit Shah (1):
virtio: rng: disallow multiple device registrations, fixes crashes
[e84e7a56a3aa2963db506299e29a5f3f09377f9b]

Avinash Patil (1):
mwifiex: correct sleep delay counter
[3e7a4ff7c5b6423ddb644df9c41b8b6d2fb79d30]

Axel Lin (1):
hwmon: (lineage-pem) Add missing terminating entry for pem_[input|fan]_attributes
[df069079c153d22adf6c28dcc0b1cf62bba75167]

Ben Hutchings (2):
Revert "powerpc/eeh: Fix crash when adding a device in a slot with DDW"
[not upstream; the reverted change was correct in mainline but not
needed in 3.2]
dmi_scan: fix missing check for _DMI_ signature in smbios_present()
[a40e7cf8f06b4e322ba902e4e9f6a6b0c2daa907]

Bjørn Mork (2):
USB: option: add Huawei E5331
[daec90e7382cbd0e73eb6861109b3da91e5ab1f3]
USB: storage: fix Huawei mode switching regression
[ab4b71644a26d1ab92b987b2fd30e17c25e89f85]

Christian Schmiedl (1):
USB: added support for Cinterion's products AH6 and PLS8
[1941138e1c024ecb5bd797d414928d3eb94d8662]

Dan Carpenter (1):
[SCSI] dc395x: uninitialized variable in device_alloc()
[208afec4f3be8c51ad6eebe6611dd6d2ad2fa298]

Dan Williams (1):
qcaux: add Franklin U600
[2d90e63603ac235aecd7d20e234616e0682c8b1f]

David Howells (1):
keys: fix race with concurrent install_user_keyrings()
[0da9dfdd2cd9889201bc6f6f43580c99165cd087]

Eric Sandeen (1):
btrfs: use rcu_barrier() to wait for bdev puts at unmount
[bc178622d40d87e75abc131007342429c9b03351]

Eric W. Biederman (1):
decnet: Fix disappearing sysctl entries
[not upstream; fixed by rewrite of sysctl in 3.4]

Felix Fietkau (2):
ath9k: fix RSSI dummy marker value
[a3d63cadbad97671d740a9698acc2c95d1ca6e79]
ath9k_htc: fix signal strength handling issues
[838f427955dcfd16858b0108ce29029da0d56a4e]

Fernando Luis Vázquez Cao (2):
HID: add support for Sony RF receiver with USB product id 0x0374
[a464918419f94a0043d2f549d6defb4c3f69f68a]
HID: clean up quirk for Sony RF receivers
[99d249021abd4341771523ed8dd7946276103432]

Guenter Roeck (3):
hwmon: (pmbus/ltc2978) Fix peak attribute handling
[dbd712c2272764a536e29ad6841dba74989a39d9]
hwmon: (pmbus/ltc2978) Fix temperature reporting
[8c958c703ef8804093437959221951eaf0e1e664]
hwmon: (pmbus/ltc2978) Use detected chip ID to select supported functionality
[f366fccd0809f13ba20d64cae3c83f7338c88af7]

Guo Chao (3):
block: use i_size_write() in bd_set_size()
[d646a02a9d44d1421f273ae3923d97b47b918176]
loopdev: fix a deadlock
[5370019dc2d2c2ff90e95d181468071362934f3a]
loopdev: remove an user triggerable oops
[b1a6650406875b9097a032eed89af50682fe1160]

Ilya Zykov (1):
tty: Correct tty buffer flush.
[64325a3be08d364a62ee8f84b2cf86934bc2544a]

James Ralston (2):
ahci: Add Device IDs for Intel Lynx Point-LP PCH
[77b12bc9cf7b10c7c1a04ca45272fbb4287902d0]
ahci: Add Device IDs for Intel Wellsburg PCH
[151743fd8dfb02956c5184b5f4f0f42677eb75bc]

Jeff Layton (1):
cifs: ensure that cifs_get_root() only traverses directories
[ce2ac52105aa663056dfc17966ebed1bf93e6e64]

Jiang Liu (1):
mm/hotplug: correctly add new zone to all other nodes' zone lists
[08dff7b7d629807dbb1f398c68dd9cd58dd657a1]

Johannes Berg (1):
iwlwifi: always copy first 16 bytes of commands
[8a964f44e01ad3bbc208c3e80d931ba91b9ea786]

Josh Boyer (2):
efi: be more paranoid about available space when creating variables
[68d929862e29a8b52a7f2f2f86a0600423b093cd]
efivars: Disable external interrupt while holding efivars->lock
[81fa4e581d9283f7992a0d8c534bb141eb840a14]

K. Y. Srinivasan (1):
[SCSI] storvsc: Initialize the sglist
[9d2696e658ef4f209955ddaa987d43f1a1bd81a1]

Kees Cook (2):
proc connector: reject unprivileged listener bumps
[e70ab977991964a5a7ad1182799451d067e62669]
signal: always clear sa_restorer on execve
[2ca39528c01a933f6689cd6505ce65bd6d68a530]

Konrad Rzeszutek Wilk (2):
xen/pci: We don't do multiple MSI's.
[884ac2978a295b7df3c4a686d3bff6932bbbb460]
xen/pciback: Don't disable a PCI device that is already disabled.
[bdc5c1812cea6efe1aaefb3131fcba28cd0b2b68]

Konstantin Khlebnikov (1):
e1000e: fix pci-device enable-counter balance
[4e0855dff094b0d56d6b5b271e0ce7851cc1e063]

Lars-Peter Clausen (1):
ext3: Fix format string issues
[8d0c2d10dd72c5292eda7a06231056a4c972e4cc]

Laszlo Ersek (1):
xen-netfront: delay gARP until backend switches to Connected
[08e34eb14fe4cfd934b5c169a7682a969457c4ea]

Ley Foon Tan (1):
tty/serial: Add support for Altera serial port
[e06c93cacb82dd147266fd1bdb2d0a0bd45ff2c1]

Malcolm Priestley (1):
staging: vt6656: Fix oops on resume from suspend.
[6987a6dabfc40222ef767f67b57212fe3a0225fb]

Marcin Jurkowski (1):
w1: fix oops when w1_search is called from netlink connector
[9d1817cab2f030f6af360e961cc69bb1da8ad765]

Mark Brown (1):
hwmon: (sht15) Check return value of regulator_enable()
[3e78080f81481aa8340374d5a37ae033c1cf4272]

Mathias Krause (1):
crypto: user - fix info leaks in report API
[9a5467bf7b6e9e02ec9c3da4e23747c05faeaac6]

Mathieu Desnoyers (1):
Fix: compat_rw_copy_check_uvector() misuse in aio, readv, writev, and security keys
[8aec0f5d4137532de14e6554fd5dd201ff3a3c49]

Matwey V. Kornilov (1):
usb: cp210x new Vendor/Device IDs
[be3101c23394af59694c8a2aae6d07f5da62fea5]

Mikulas Patocka (2):
dm snapshot: add missing module aliases
[23cb21092eb9dcec9d3604b68d95192b79915890]
dm: fix truncated status strings
[fd7c092e711ebab55b2688d3859d95dfd0301f73]

NeilBrown (2):
md: fix two bugs when attempting to resize RAID0 array.
[a64685399181780998281fe07309a94b25dd24c3]
md: raid0: fix error return from create_stripe_zones.
[58ebb34c49fcfcaa029e4b1c1453d92583900f9a]

Oliver Neukum (1):
USB: cdc-wdm: fix buffer overflow
[c0f5ecee4e741667b2493c742b60b6218d40b3aa]

Paul Bolle (1):
tty: serial: fix typo "ARCH_S5P6450"
[827aa0d36d486f359808c8fb931cf7a71011a09d]

Paul Kot (1):
batman-adv: bat_socket_read missing checks
[c00b6856fc642b234895cfabd15b289e76726430]

Russell King (2):
ARM: VFP: fix emulation of second VFP instruction
[5e4ba617c1b584b2e376f31a63bd4e734109318a]
ARM: fix scheduling while atomic warning in alignment handling code
[b255188f90e2bade1bd11a986dd1ca4861869f4d]

Rusty Russell (1):
hw_random: make buffer usable in scatterlist.
[f7f154f1246ccc5a0a7e9ce50932627d60a0c878]

Sarah Sharp (4):
USB: Don't use EHCI port sempahore for USB 3.0 hubs.
[0fe51aa5eee51db7c7ecd201d42a977ad79c58b6]
USB: Fix connected device switch to Inactive state.
[d3b9d7a9051d7024a93c76a84b2f84b3b66ad6d5]
USB: Prepare for refactoring by adding extra udev checks.
[2d4fa940f99663c82ba55b2244638833b388e4e2]
USB: Rip out recursive call on warm port reset.
[a24a6078754f28528bc91e7e7b3e6ae86bd936d8]

Scott Ashcroft (1):
Fix 4 port and add support for 8 port 'Unknown' PCI serial port cards
[d13402a4a944e72612a9ec5c9190e35717c02a9d]

Sebastian Riemer (1):
md: protect against crash upon fsync on ro array
[bbfa57c0f2243a7c31fd248d22e9861a2802cad5]

Seiji Aguchi (1):
efi_pstore: Check remaining space with QueryVariableInfo() before writing data
[d80a361d779a9f19498943d1ca84243209cd5647]

Seth Heasley (2):
ahci: AHCI-mode SATA patch for Intel Avoton DeviceIDs
[29e674dd5c8e781589f09c3ee139c80f6da274e4]
ahci: AHCI-mode SATA patch for Intel Lynx Point DeviceIDs
[ea4ace66782fc35245133d2766f38d62827761cc]

Shuah Khan (1):
iommu/amd: Initialize device table after dma_ops
[f528d980c17b8714aedc918ba86e058af914d66b]

Steve Conklin (1):
usb: serial: Add Rigblaster Advantage to device table
[a57e82a18779ab8a5e5a1f5841cef937cf578913]

Steven Rostedt (1):
ftrace: Update the kconfig for DYNAMIC_FTRACE
[db05021d49a994ee40a9735d9c3cb0060c9babb8]

Sven Eckelmann (1):
batman-adv: Only write requested number of byte to user buffer
[b5a1eeef04cc7859f34dec9b72ea1b28e4aba07c]

Takashi Iwai (2):
ALSA: seq: Fix missing error handling in snd_seq_timer_open()
[66efdc71d95887b652a742a5dae51fa834d71465]
ALSA: vmaster: Fix slave change notification
[2069d483b39a603a5f3428a19d3b4ac89aa97f48]

Thomas Gleixner (1):
btrfs: Init io_lock after cloning btrfs device struct
[1cba0cdf5e4dbcd9e5fa5b54d7a028e55e2ca057]

Trond Myklebust (2):
NFS: Don't allow NFS silly-renamed files to be deleted, no signal
[5a7a613a47a715711b3f2d3322a0eac21d459166]
SUNRPC: Don't start the retransmission timer when out of socket space
[a9a6b52ee1baa865283a91eb8d443ee91adfca56]

Ville Syrjälä (1):
drm/i915: Don't clobber crtc->fb when queue_flip fails
[4a35f83b2b7c6aae3fc0d1c4554fdc99dc33ad07]

Wang YanQing (1):
serial: 8250_pci: add support for another kind of NetMos Technology PCI 9835 Multi-I/O Controller
[8d2f8cd424ca0b99001f3ff4f5db87c4e525f366]

Will Deacon (1):
ARM: 7663/1: perf: fix ARMv7 EVTYPE_MASK to include NSH bit
[f2fe09b055e2549de41fb107b34c60bac4a1b0cf]

Xiaobing Tu (1):
Fix memory leak in cpufreq stats.
[e37736777254ce1abc85493a5cacbefe5983b896]

.../devicetree/bindings/tty/serial/of-serial.txt | 3 +
Makefile | 4 +-
arch/arm/kernel/perf_event_v7.c | 2 +-
arch/arm/mm/alignment.c | 11 +-
arch/arm/vfp/vfpmodule.c | 2 +-
arch/powerpc/include/asm/eeh.h | 3 -
arch/powerpc/kernel/of_platform.c | 3 -
arch/powerpc/kernel/pci-common.c | 7 +-
arch/powerpc/platforms/pseries/eeh.c | 24 +-
arch/x86/pci/xen.c | 9 +
crypto/ablkcipher.c | 12 +-
crypto/aead.c | 9 +-
crypto/ahash.c | 2 +-
crypto/blkcipher.c | 6 +-
crypto/crypto_user.c | 22 +-
crypto/pcompress.c | 3 +-
crypto/rng.c | 2 +-
crypto/shash.c | 3 +-
drivers/ata/ahci.c | 40 +++
drivers/block/loop.c | 24 +-
drivers/char/hw_random/core.c | 19 +-
drivers/char/hw_random/virtio-rng.c | 13 +-
drivers/connector/cn_proc.c | 8 +
drivers/cpufreq/cpufreq_stats.c | 1 +
drivers/firmware/dmi_scan.c | 5 +-
drivers/firmware/efivars.c | 136 ++++++--
drivers/gpu/drm/i915/intel_display.c | 11 +-
drivers/gpu/drm/radeon/radeon_combios.c | 9 +
drivers/hid/hid-core.c | 1 +
drivers/hid/hid-ids.h | 1 +
drivers/hid/hid-sony.c | 18 +-
drivers/hv/hv_kvp.c | 10 +-
drivers/hwmon/lineage-pem.c | 2 +
drivers/hwmon/pmbus/ltc2978.c | 40 +--
drivers/hwmon/sht15.c | 8 +-
drivers/iommu/amd_iommu_init.c | 10 +-
drivers/md/dm-crypt.c | 39 +--
drivers/md/dm-delay.c | 8 +-
drivers/md/dm-flakey.c | 7 +-
drivers/md/dm-ioctl.c | 14 +-
drivers/md/dm-linear.c | 7 +-
drivers/md/dm-mpath.c | 8 +-
drivers/md/dm-raid.c | 8 +-
drivers/md/dm-raid1.c | 8 +-
drivers/md/dm-snap.c | 18 +-
drivers/md/dm-stripe.c | 7 +-
drivers/md/dm-thin.c | 78 +++--
drivers/md/md.c | 7 +
drivers/md/raid0.c | 5 +-
drivers/net/ethernet/intel/e1000e/netdev.c | 2 +-
drivers/net/wireless/ath/ath9k/common.h | 2 +-
drivers/net/wireless/ath/ath9k/htc.h | 1 +
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 18 +-
drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 9 +
drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 72 ++++-
drivers/net/wireless/mwifiex/pcie.c | 2 +-
drivers/net/xen-netfront.c | 4 +-
drivers/scsi/dc395x.c | 2 +-
drivers/staging/hv/storvsc_drv.c | 1 +
drivers/staging/vt6656/main_usb.c | 4 -
drivers/tty/serial/8250.c | 21 ++
drivers/tty/serial/8250_pci.c | 21 +-
drivers/tty/serial/Kconfig | 2 +-
drivers/tty/serial/of_serial.c | 6 +
drivers/tty/tty_buffer.c | 11 +-
drivers/usb/class/cdc-wdm.c | 23 +-
drivers/usb/core/hub.c | 178 ++++++-----
drivers/usb/host/ehci-q.c | 18 +-
drivers/usb/serial/cp210x.c | 20 ++
drivers/usb/serial/option.c | 5 +
drivers/usb/serial/qcaux.c | 1 +
drivers/usb/storage/initializers.c | 76 +----
drivers/usb/storage/initializers.h | 4 +-
drivers/usb/storage/unusual_devs.h | 329 +++++++++++++++++++-
drivers/w1/w1.c | 3 +-
drivers/xen/xen-pciback/pciback_ops.c | 3 +-
fs/block_dev.c | 4 +-
fs/btrfs/volumes.c | 7 +
fs/cifs/cifsfs.c | 5 +
fs/compat.c | 15 +-
fs/ext3/super.c | 4 +-
fs/fat/namei_vfat.c | 3 +-
fs/nfs/unlink.c | 20 +-
fs/nls/nls_base.c | 43 ++-
fs/pipe.c | 3 +
include/linux/device-mapper.h | 4 +-
include/linux/efi.h | 6 +
include/linux/nls.h | 5 +-
include/linux/serial_core.h | 5 +-
kernel/signal.c | 3 +
kernel/trace/Kconfig | 24 +-
mm/memory_hotplug.c | 15 +-
mm/process_vm_access.c | 8 -
net/batman-adv/icmp_socket.c | 5 +-
net/decnet/af_decnet.c | 4 +
net/decnet/sysctl_net_decnet.c | 28 ++
net/sunrpc/xprt.c | 6 +-
security/keys/compat.c | 4 +-
security/keys/process_keys.c | 2 +-
sound/core/seq/seq_timer.c | 8 +-
sound/core/vmaster.c | 5 +-
101 files changed, 1221 insertions(+), 550 deletions(-)

--
Ben Hutchings
Never attribute to conspiracy what can adequately be explained by stupidity.


2013-03-18 04:30:02

by Ben Hutchings

[permalink] [raw]
Subject: [ 02/82] btrfs: Init io_lock after cloning btrfs device struct

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

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

From: Thomas Gleixner <[email protected]>

commit 1cba0cdf5e4dbcd9e5fa5b54d7a028e55e2ca057 upstream.

__btrfs_close_devices() clones btrfs device structs with
memcpy(). Some of the fields in the clone are reinitialized, but it's
missing to init io_lock. In mainline this goes unnoticed, but on RT it
leaves the plist pointing to the original about to be freed lock
struct.

Initialize io_lock after cloning, so no references to the original
struct are left.

Reported-and-tested-by: Mike Galbraith <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Chris Mason <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/btrfs/volumes.c | 1 +
1 file changed, 1 insertion(+)

--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -543,6 +543,7 @@ static int __btrfs_close_devices(struct
new_device->writeable = 0;
new_device->in_fs_metadata = 0;
new_device->can_discard = 0;
+ spin_lock_init(&new_device->io_lock);
list_replace_rcu(&device->dev_list, &new_device->dev_list);

call_rcu(&device->rcu, free_device);

2013-03-18 04:30:09

by Ben Hutchings

[permalink] [raw]
Subject: [ 13/82] ath9k: fix RSSI dummy marker value

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

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

From: Felix Fietkau <[email protected]>

commit a3d63cadbad97671d740a9698acc2c95d1ca6e79 upstream.

RSSI is being stored internally as s8 in several places. The indication
of an unset RSSI value, ATH_RSSI_DUMMY_MARKER, was supposed to have been
set to 127, but ended up being set to 0x127 because of a code cleanup
mistake. This could lead to invalid signal strength values in a few
places.

Signed-off-by: Felix Fietkau <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/wireless/ath/ath9k/common.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -35,7 +35,7 @@
#define WME_AC_BK 3
#define WME_NUM_AC 4

-#define ATH_RSSI_DUMMY_MARKER 0x127
+#define ATH_RSSI_DUMMY_MARKER 127
#define ATH_RSSI_LPF_LEN 10
#define RSSI_LPF_THRESHOLD -20
#define ATH_RSSI_EP_MULTIPLIER (1<<7)

2013-03-18 04:30:24

by Ben Hutchings

[permalink] [raw]
Subject: [ 18/82] dm: fix truncated status strings

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

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

From: Mikulas Patocka <[email protected]>

commit fd7c092e711ebab55b2688d3859d95dfd0301f73 upstream.

Avoid returning a truncated table or status string instead of setting
the DM_BUFFER_FULL_FLAG when the last target of a table fills the
buffer.

When processing a table or status request, the function retrieve_status
calls ti->type->status. If ti->type->status returns non-zero,
retrieve_status assumes that the buffer overflowed and sets
DM_BUFFER_FULL_FLAG.

However, targets don't return non-zero values from their status method
on overflow. Most targets returns always zero.

If a buffer overflow happens in a target that is not the last in the
table, it gets noticed during the next iteration of the loop in
retrieve_status; but if a buffer overflow happens in the last target, it
goes unnoticed and erroneously truncated data is returned.

In the current code, the targets behave in the following way:
* dm-crypt returns -ENOMEM if there is not enough space to store the
key, but it returns 0 on all other overflows.
* dm-thin returns errors from the status method if a disk error happened.
This is incorrect because retrieve_status doesn't check the error
code, it assumes that all non-zero values mean buffer overflow.
* all the other targets always return 0.

This patch changes the ti->type->status function to return void (because
most targets don't use the return code). Overflow is detected in
retrieve_status: if the status method fills up the remaining space
completely, it is assumed that buffer overflow happened.

Signed-off-by: Mikulas Patocka <[email protected]>
Signed-off-by: Alasdair G Kergon <[email protected]>
[bwh: Backported to 3.2:
- Adjust context
- dm_status_fn doesn't take a status_flags parameter
- Bump the last component of each current version (verified not to
match any version used in mainline)
- Drop changes to dm-verity]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1262,20 +1262,6 @@ static int crypt_decode_key(u8 *key, cha
return 0;
}

-/*
- * Encode key into its hex representation
- */
-static void crypt_encode_key(char *hex, u8 *key, unsigned int size)
-{
- unsigned int i;
-
- for (i = 0; i < size; i++) {
- sprintf(hex, "%02x", *key);
- hex += 2;
- key++;
- }
-}
-
static void crypt_free_tfms(struct crypt_config *cc, int cpu)
{
struct crypt_cpu *cpu_cc = per_cpu_ptr(cc->cpu, cpu);
@@ -1739,11 +1725,11 @@ static int crypt_map(struct dm_target *t
return DM_MAPIO_SUBMITTED;
}

-static int crypt_status(struct dm_target *ti, status_type_t type,
- char *result, unsigned int maxlen)
+static void crypt_status(struct dm_target *ti, status_type_t type,
+ char *result, unsigned maxlen)
{
struct crypt_config *cc = ti->private;
- unsigned int sz = 0;
+ unsigned i, sz = 0;

switch (type) {
case STATUSTYPE_INFO:
@@ -1753,17 +1739,11 @@ static int crypt_status(struct dm_target
case STATUSTYPE_TABLE:
DMEMIT("%s ", cc->cipher_string);

- if (cc->key_size > 0) {
- if ((maxlen - sz) < ((cc->key_size << 1) + 1))
- return -ENOMEM;
-
- crypt_encode_key(result + sz, cc->key, cc->key_size);
- sz += cc->key_size << 1;
- } else {
- if (sz >= maxlen)
- return -ENOMEM;
- result[sz++] = '-';
- }
+ if (cc->key_size > 0)
+ for (i = 0; i < cc->key_size; i++)
+ DMEMIT("%02x", cc->key[i]);
+ else
+ DMEMIT("-");

DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset,
cc->dev->name, (unsigned long long)cc->start);
@@ -1773,7 +1753,6 @@ static int crypt_status(struct dm_target

break;
}
- return 0;
}

static void crypt_postsuspend(struct dm_target *ti)
@@ -1867,7 +1846,7 @@ static int crypt_iterate_devices(struct

static struct target_type crypt_target = {
.name = "crypt",
- .version = {1, 11, 0},
+ .version = {1, 11, 1},
.module = THIS_MODULE,
.ctr = crypt_ctr,
.dtr = crypt_dtr,
--- a/drivers/md/dm-delay.c
+++ b/drivers/md/dm-delay.c
@@ -293,8 +293,8 @@ static int delay_map(struct dm_target *t
return delay_bio(dc, dc->read_delay, bio);
}

-static int delay_status(struct dm_target *ti, status_type_t type,
- char *result, unsigned maxlen)
+static void delay_status(struct dm_target *ti, status_type_t type,
+ char *result, unsigned maxlen)
{
struct delay_c *dc = ti->private;
int sz = 0;
@@ -314,8 +314,6 @@ static int delay_status(struct dm_target
dc->write_delay);
break;
}
-
- return 0;
}

static int delay_iterate_devices(struct dm_target *ti,
@@ -337,7 +335,7 @@ out:

static struct target_type delay_target = {
.name = "delay",
- .version = {1, 1, 0},
+ .version = {1, 1, 1},
.module = THIS_MODULE,
.ctr = delay_ctr,
.dtr = delay_dtr,
--- a/drivers/md/dm-flakey.c
+++ b/drivers/md/dm-flakey.c
@@ -331,8 +331,8 @@ static int flakey_end_io(struct dm_targe
return error;
}

-static int flakey_status(struct dm_target *ti, status_type_t type,
- char *result, unsigned int maxlen)
+static void flakey_status(struct dm_target *ti, status_type_t type,
+ char *result, unsigned maxlen)
{
unsigned sz = 0;
struct flakey_c *fc = ti->private;
@@ -362,7 +362,6 @@ static int flakey_status(struct dm_targe

break;
}
- return 0;
}

static int flakey_ioctl(struct dm_target *ti, unsigned int cmd, unsigned long arg)
@@ -405,7 +404,7 @@ static int flakey_iterate_devices(struct

static struct target_type flakey_target = {
.name = "flakey",
- .version = {1, 2, 0},
+ .version = {1, 2, 1},
.module = THIS_MODULE,
.ctr = flakey_ctr,
.dtr = flakey_dtr,
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1065,6 +1065,7 @@ static void retrieve_status(struct dm_ta
num_targets = dm_table_get_num_targets(table);
for (i = 0; i < num_targets; i++) {
struct dm_target *ti = dm_table_get_target(table, i);
+ size_t l;

remaining = len - (outptr - outbuf);
if (remaining <= sizeof(struct dm_target_spec)) {
@@ -1089,14 +1090,17 @@ static void retrieve_status(struct dm_ta

/* Get the status/table string from the target driver */
if (ti->type->status) {
- if (ti->type->status(ti, type, outptr, remaining)) {
- param->flags |= DM_BUFFER_FULL_FLAG;
- break;
- }
+ ti->type->status(ti, type, outptr, remaining);
} else
outptr[0] = '\0';

- outptr += strlen(outptr) + 1;
+ l = strlen(outptr) + 1;
+ if (l == remaining) {
+ param->flags |= DM_BUFFER_FULL_FLAG;
+ break;
+ }
+
+ outptr += l;
used = param->data_start + (outptr - outbuf);

outptr = align_ptr(outptr);
--- a/drivers/md/dm-linear.c
+++ b/drivers/md/dm-linear.c
@@ -94,8 +94,8 @@ static int linear_map(struct dm_target *
return DM_MAPIO_REMAPPED;
}

-static int linear_status(struct dm_target *ti, status_type_t type,
- char *result, unsigned int maxlen)
+static void linear_status(struct dm_target *ti, status_type_t type,
+ char *result, unsigned maxlen)
{
struct linear_c *lc = (struct linear_c *) ti->private;

@@ -109,7 +109,6 @@ static int linear_status(struct dm_targe
(unsigned long long)lc->start);
break;
}
- return 0;
}

static int linear_ioctl(struct dm_target *ti, unsigned int cmd,
@@ -154,7 +153,7 @@ static int linear_iterate_devices(struct

static struct target_type linear_target = {
.name = "linear",
- .version = {1, 1, 0},
+ .version = {1, 1, 1},
.module = THIS_MODULE,
.ctr = linear_ctr,
.dtr = linear_dtr,
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -1323,8 +1323,8 @@ static void multipath_resume(struct dm_t
* [priority selector-name num_ps_args [ps_args]*
* num_paths num_selector_args [path_dev [selector_args]* ]+ ]+
*/
-static int multipath_status(struct dm_target *ti, status_type_t type,
- char *result, unsigned int maxlen)
+static void multipath_status(struct dm_target *ti, status_type_t type,
+ char *result, unsigned maxlen)
{
int sz = 0;
unsigned long flags;
@@ -1427,8 +1427,6 @@ static int multipath_status(struct dm_ta
}

spin_unlock_irqrestore(&m->lock, flags);
-
- return 0;
}

static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
@@ -1623,7 +1621,7 @@ out:
*---------------------------------------------------------------*/
static struct target_type multipath_target = {
.name = "multipath",
- .version = {1, 3, 0},
+ .version = {1, 3, 1},
.module = THIS_MODULE,
.ctr = multipath_ctr,
.dtr = multipath_dtr,
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -1017,8 +1017,8 @@ static int raid_map(struct dm_target *ti
return DM_MAPIO_SUBMITTED;
}

-static int raid_status(struct dm_target *ti, status_type_t type,
- char *result, unsigned maxlen)
+static void raid_status(struct dm_target *ti, status_type_t type,
+ char *result, unsigned maxlen)
{
struct raid_set *rs = ti->private;
unsigned raid_param_cnt = 1; /* at least 1 for chunksize */
@@ -1153,8 +1153,6 @@ static int raid_status(struct dm_target
DMEMIT(" -");
}
}
-
- return 0;
}

static int raid_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data)
@@ -1208,7 +1206,7 @@ static void raid_resume(struct dm_target

static struct target_type raid_target = {
.name = "raid",
- .version = {1, 1, 0},
+ .version = {1, 1, 1},
.module = THIS_MODULE,
.ctr = raid_ctr,
.dtr = raid_dtr,
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -1358,8 +1358,8 @@ static char device_status_char(struct mi
}


-static int mirror_status(struct dm_target *ti, status_type_t type,
- char *result, unsigned int maxlen)
+static void mirror_status(struct dm_target *ti, status_type_t type,
+ char *result, unsigned maxlen)
{
unsigned int m, sz = 0;
struct mirror_set *ms = (struct mirror_set *) ti->private;
@@ -1394,8 +1394,6 @@ static int mirror_status(struct dm_targe
if (ms->features & DM_RAID1_HANDLE_ERRORS)
DMEMIT(" 1 handle_errors");
}
-
- return 0;
}

static int mirror_iterate_devices(struct dm_target *ti,
@@ -1414,7 +1412,7 @@ static int mirror_iterate_devices(struct

static struct target_type mirror_target = {
.name = "mirror",
- .version = {1, 12, 1},
+ .version = {1, 12, 2},
.module = THIS_MODULE,
.ctr = mirror_ctr,
.dtr = mirror_dtr,
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -1845,8 +1845,8 @@ static void snapshot_merge_resume(struct
start_merge(s);
}

-static int snapshot_status(struct dm_target *ti, status_type_t type,
- char *result, unsigned int maxlen)
+static void snapshot_status(struct dm_target *ti, status_type_t type,
+ char *result, unsigned maxlen)
{
unsigned sz = 0;
struct dm_snapshot *snap = ti->private;
@@ -1892,8 +1892,6 @@ static int snapshot_status(struct dm_tar
maxlen - sz);
break;
}
-
- return 0;
}

static int snapshot_iterate_devices(struct dm_target *ti,
@@ -2148,8 +2146,8 @@ static void origin_resume(struct dm_targ
ti->split_io = get_origin_minimum_chunksize(dev->bdev);
}

-static int origin_status(struct dm_target *ti, status_type_t type, char *result,
- unsigned int maxlen)
+static void origin_status(struct dm_target *ti, status_type_t type,
+ char *result, unsigned maxlen)
{
struct dm_dev *dev = ti->private;

@@ -2162,8 +2160,6 @@ static int origin_status(struct dm_targe
snprintf(result, maxlen, "%s", dev->name);
break;
}
-
- return 0;
}

static int origin_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
@@ -2191,7 +2187,7 @@ static int origin_iterate_devices(struct

static struct target_type origin_target = {
.name = "snapshot-origin",
- .version = {1, 7, 1},
+ .version = {1, 7, 2},
.module = THIS_MODULE,
.ctr = origin_ctr,
.dtr = origin_dtr,
@@ -2204,7 +2200,7 @@ static struct target_type origin_target

static struct target_type snapshot_target = {
.name = "snapshot",
- .version = {1, 10, 0},
+ .version = {1, 10, 1},
.module = THIS_MODULE,
.ctr = snapshot_ctr,
.dtr = snapshot_dtr,
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -301,8 +301,8 @@ static int stripe_map(struct dm_target *
*
*/

-static int stripe_status(struct dm_target *ti,
- status_type_t type, char *result, unsigned int maxlen)
+static void stripe_status(struct dm_target *ti, status_type_t type,
+ char *result, unsigned maxlen)
{
struct stripe_c *sc = (struct stripe_c *) ti->private;
char buffer[sc->stripes + 1];
@@ -329,7 +329,6 @@ static int stripe_status(struct dm_targe
(unsigned long long)sc->stripe[i].physical_start);
break;
}
- return 0;
}

static int stripe_end_io(struct dm_target *ti, struct bio *bio,
@@ -418,7 +417,7 @@ static int stripe_merge(struct dm_target

static struct target_type stripe_target = {
.name = "striped",
- .version = {1, 4, 0},
+ .version = {1, 4, 1},
.module = THIS_MODULE,
.ctr = stripe_ctr,
.dtr = stripe_dtr,
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -2090,8 +2090,8 @@ static int pool_message(struct dm_target
* <transaction id> <used metadata sectors>/<total metadata sectors>
* <used data sectors>/<total data sectors> <held metadata root>
*/
-static int pool_status(struct dm_target *ti, status_type_t type,
- char *result, unsigned maxlen)
+static void pool_status(struct dm_target *ti, status_type_t type,
+ char *result, unsigned maxlen)
{
int r;
unsigned sz = 0;
@@ -2108,32 +2108,41 @@ static int pool_status(struct dm_target

switch (type) {
case STATUSTYPE_INFO:
- r = dm_pool_get_metadata_transaction_id(pool->pmd,
- &transaction_id);
- if (r)
- return r;
-
- r = dm_pool_get_free_metadata_block_count(pool->pmd,
- &nr_free_blocks_metadata);
- if (r)
- return r;
+ r = dm_pool_get_metadata_transaction_id(pool->pmd, &transaction_id);
+ if (r) {
+ DMERR("dm_pool_get_metadata_transaction_id returned %d", r);
+ goto err;
+ }
+
+ r = dm_pool_get_free_metadata_block_count(pool->pmd, &nr_free_blocks_metadata);
+ if (r) {
+ DMERR("dm_pool_get_free_metadata_block_count returned %d", r);
+ goto err;
+ }

r = dm_pool_get_metadata_dev_size(pool->pmd, &nr_blocks_metadata);
- if (r)
- return r;
+ if (r) {
+ DMERR("dm_pool_get_metadata_dev_size returned %d", r);
+ goto err;
+ }

- r = dm_pool_get_free_block_count(pool->pmd,
- &nr_free_blocks_data);
- if (r)
- return r;
+ r = dm_pool_get_free_block_count(pool->pmd, &nr_free_blocks_data);
+ if (r) {
+ DMERR("dm_pool_get_free_block_count returned %d", r);
+ goto err;
+ }

r = dm_pool_get_data_dev_size(pool->pmd, &nr_blocks_data);
- if (r)
- return r;
+ if (r) {
+ DMERR("dm_pool_get_data_dev_size returned %d", r);
+ goto err;
+ }

r = dm_pool_get_held_metadata_root(pool->pmd, &held_root);
- if (r)
- return r;
+ if (r) {
+ DMERR("dm_pool_get_held_metadata_root returned %d", r);
+ goto err;
+ }

DMEMIT("%llu %llu/%llu %llu/%llu ",
(unsigned long long)transaction_id,
@@ -2162,8 +2171,10 @@ static int pool_status(struct dm_target
DMEMIT("skip_block_zeroing ");
break;
}
+ return;

- return 0;
+err:
+ DMEMIT("Error");
}

static int pool_iterate_devices(struct dm_target *ti,
@@ -2201,7 +2212,7 @@ static struct target_type pool_target =
.name = "thin-pool",
.features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE |
DM_TARGET_IMMUTABLE,
- .version = {1, 0, 0},
+ .version = {1, 0, 1},
.module = THIS_MODULE,
.ctr = pool_ctr,
.dtr = pool_dtr,
@@ -2339,8 +2350,8 @@ static void thin_postsuspend(struct dm_t
/*
* <nr mapped sectors> <highest mapped sector>
*/
-static int thin_status(struct dm_target *ti, status_type_t type,
- char *result, unsigned maxlen)
+static void thin_status(struct dm_target *ti, status_type_t type,
+ char *result, unsigned maxlen)
{
int r;
ssize_t sz = 0;
@@ -2354,12 +2365,16 @@ static int thin_status(struct dm_target
switch (type) {
case STATUSTYPE_INFO:
r = dm_thin_get_mapped_count(tc->td, &mapped);
- if (r)
- return r;
+ if (r) {
+ DMERR("dm_thin_get_mapped_count returned %d", r);
+ goto err;
+ }

r = dm_thin_get_highest_mapped_block(tc->td, &highest);
- if (r < 0)
- return r;
+ if (r < 0) {
+ DMERR("dm_thin_get_highest_mapped_block returned %d", r);
+ goto err;
+ }

DMEMIT("%llu ", mapped * tc->pool->sectors_per_block);
if (r)
@@ -2377,7 +2392,10 @@ static int thin_status(struct dm_target
}
}

- return 0;
+ return;
+
+err:
+ DMEMIT("Error");
}

static int thin_iterate_devices(struct dm_target *ti,
@@ -2410,7 +2428,7 @@ static void thin_io_hints(struct dm_targ

static struct target_type thin_target = {
.name = "thin",
- .version = {1, 0, 0},
+ .version = {1, 0, 1},
.module = THIS_MODULE,
.ctr = thin_ctr,
.dtr = thin_dtr,
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -72,8 +72,8 @@ typedef void (*dm_postsuspend_fn) (struc
typedef int (*dm_preresume_fn) (struct dm_target *ti);
typedef void (*dm_resume_fn) (struct dm_target *ti);

-typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type,
- char *result, unsigned int maxlen);
+typedef void (*dm_status_fn) (struct dm_target *ti, status_type_t status_type,
+ char *result, unsigned maxlen);

typedef int (*dm_message_fn) (struct dm_target *ti, unsigned argc, char **argv);


2013-03-18 04:30:30

by Ben Hutchings

[permalink] [raw]
Subject: [ 09/82] ARM: fix scheduling while atomic warning in alignment handling code

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

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

From: Russell King <[email protected]>

commit b255188f90e2bade1bd11a986dd1ca4861869f4d upstream.

Paolo Pisati reports that IPv6 triggers this warning:

BUG: scheduling while atomic: swapper/0/0/0x40000100
Modules linked in:
[<c001b1c4>] (unwind_backtrace+0x0/0xf0) from [<c0503c5c>] (__schedule_bug+0x48/0x5c)
[<c0503c5c>] (__schedule_bug+0x48/0x5c) from [<c0508608>] (__schedule+0x700/0x740)
[<c0508608>] (__schedule+0x700/0x740) from [<c007007c>] (__cond_resched+0x24/0x34)
[<c007007c>] (__cond_resched+0x24/0x34) from [<c05086dc>] (_cond_resched+0x3c/0x44)
[<c05086dc>] (_cond_resched+0x3c/0x44) from [<c0021f6c>] (do_alignment+0x178/0x78c)
[<c0021f6c>] (do_alignment+0x178/0x78c) from [<c00083e0>] (do_DataAbort+0x34/0x98)
[<c00083e0>] (do_DataAbort+0x34/0x98) from [<c0509a60>] (__dabt_svc+0x40/0x60)
Exception stack(0xc0763d70 to 0xc0763db8)
3d60: e97e805e e97e806e 2c000000 11000000
3d80: ea86bb00 0000002c 00000011 e97e807e c076d2a8 e97e805e e97e806e 0000002c
3da0: 3d000000 c0763dbc c04b98fc c02a8490 00000113 ffffffff
[<c0509a60>] (__dabt_svc+0x40/0x60) from [<c02a8490>] (__csum_ipv6_magic+0x8/0xc8)

Fix this by using probe_kernel_address() stead of __get_user().

Reported-by: Paolo Pisati <[email protected]>
Tested-by: Paolo Pisati <[email protected]>
Signed-off-by: Russell King <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/arm/mm/alignment.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)

--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -749,7 +749,6 @@ do_alignment(unsigned long addr, unsigne
unsigned long instr = 0, instrptr;
int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs);
unsigned int type;
- mm_segment_t fs;
unsigned int fault;
u16 tinstr = 0;
int isize = 4;
@@ -760,16 +759,15 @@ do_alignment(unsigned long addr, unsigne

instrptr = instruction_pointer(regs);

- fs = get_fs();
- set_fs(KERNEL_DS);
if (thumb_mode(regs)) {
- fault = __get_user(tinstr, (u16 *)(instrptr & ~1));
+ u16 *ptr = (u16 *)(instrptr & ~1);
+ fault = probe_kernel_address(ptr, tinstr);
if (!fault) {
if (cpu_architecture() >= CPU_ARCH_ARMv7 &&
IS_T32(tinstr)) {
/* Thumb-2 32-bit */
u16 tinst2 = 0;
- fault = __get_user(tinst2, (u16 *)(instrptr+2));
+ fault = probe_kernel_address(ptr + 1, tinst2);
instr = (tinstr << 16) | tinst2;
thumb2_32b = 1;
} else {
@@ -778,8 +776,7 @@ do_alignment(unsigned long addr, unsigne
}
}
} else
- fault = __get_user(instr, (u32 *)instrptr);
- set_fs(fs);
+ fault = probe_kernel_address(instrptr, instr);

if (fault) {
type = TYPE_FAULT;

2013-03-18 04:30:54

by Ben Hutchings

[permalink] [raw]
Subject: [ 07/82] [SCSI] dc395x: uninitialized variable in device_alloc()

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

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

From: Dan Carpenter <[email protected]>

commit 208afec4f3be8c51ad6eebe6611dd6d2ad2fa298 upstream.

This bug was introduced back in bitkeeper days in 2003. We use
"dcb->dev_mode" before it has been initialized.

Signed-off-by: Dan Carpenter <[email protected]>
Acked-by: Oliver Neukum <[email protected]>
Signed-off-by: James Bottomley <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/scsi/dc395x.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -3747,13 +3747,13 @@ static struct DeviceCtlBlk *device_alloc
dcb->max_command = 1;
dcb->target_id = target;
dcb->target_lun = lun;
+ dcb->dev_mode = eeprom->target[target].cfg0;
#ifndef DC395x_NO_DISCONNECT
dcb->identify_msg =
IDENTIFY(dcb->dev_mode & NTC_DO_DISCONNECT, lun);
#else
dcb->identify_msg = IDENTIFY(0, lun);
#endif
- dcb->dev_mode = eeprom->target[target].cfg0;
dcb->inquiry7 = 0;
dcb->sync_mode = 0;
dcb->min_nego_period = clock_period[period_index];

2013-03-18 04:31:31

by Ben Hutchings

[permalink] [raw]
Subject: [ 61/82] tty: serial: fix typo "ARCH_S5P6450"

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

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

From: Paul Bolle <[email protected]>

commit 827aa0d36d486f359808c8fb931cf7a71011a09d upstream.

This could have been either ARCH_S5P64X0 or CPU_S5P6450. Looking at
commit 2555e663b367b8d555e76023f4de3f6338c28d6c ("ARM: S5P64X0: Add UART
serial support for S5P6450") - which added this typo - makes clear this
should be CPU_S5P6450.

Signed-off-by: Paul Bolle <[email protected]>
Acked-by: Kukjin Kim <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/tty/serial/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -464,7 +464,7 @@ config SERIAL_SAMSUNG_UARTS_4
config SERIAL_SAMSUNG_UARTS
int
depends on ARM && PLAT_SAMSUNG
- default 6 if ARCH_S5P6450
+ default 6 if CPU_S5P6450
default 4 if SERIAL_SAMSUNG_UARTS_4
default 3
help

2013-03-18 04:31:46

by Ben Hutchings

[permalink] [raw]
Subject: [ 56/82] ext3: Fix format string issues

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

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

From: Lars-Peter Clausen <[email protected]>

commit 8d0c2d10dd72c5292eda7a06231056a4c972e4cc upstream.

ext3_msg() takes the printk prefix as the second parameter and the
format string as the third parameter. Two callers of ext3_msg omit the
prefix and pass the format string as the second parameter and the first
parameter to the format string as the third parameter. In both cases
this string comes from an arbitrary source. Which means the string may
contain format string characters, which will
lead to undefined and potentially harmful behavior.

The issue was introduced in commit 4cf46b67eb("ext3: Unify log messages
in ext3") and is fixed by this patch.

Signed-off-by: Lars-Peter Clausen <[email protected]>
Signed-off-by: Jan Kara <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/ext3/super.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -374,7 +374,7 @@ static struct block_device *ext3_blkdev_
return bdev;

fail:
- ext3_msg(sb, "error: failed to open journal device %s: %ld",
+ ext3_msg(sb, KERN_ERR, "error: failed to open journal device %s: %ld",
__bdevname(dev, b), PTR_ERR(bdev));

return NULL;
@@ -902,7 +902,7 @@ static ext3_fsblk_t get_sb_block(void **
/*todo: use simple_strtoll with >32bit ext3 */
sb_block = simple_strtoul(options, &options, 0);
if (*options && *options != ',') {
- ext3_msg(sb, "error: invalid sb specification: %s",
+ ext3_msg(sb, KERN_ERR, "error: invalid sb specification: %s",
(char *) *data);
return 1;
}

2013-03-18 04:31:56

by Ben Hutchings

[permalink] [raw]
Subject: [ 42/82] decnet: Fix disappearing sysctl entries

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

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

From: "Eric W. Biederman" <[email protected]>

When decnet is built as a module a simple:
echo 0.0 >/proc/sys/net/decnet/node_address

results in most of the sysctl entries under /proc/sys/net/decnet and
/proc/sys/net/decnet/conf disappearing.

For more details see http://www.spinics.net/lists/netdev/msg226123.html.

This change applies the same workaround used in
net/core/sysctl_net_core.c and net/ipv6/sysctl_net_ipv6.c of creating
a skeleton of decnet sysctl entries before doing anything else.

The problem first appeared in kernel 2.6.27. The later rewrite of
sysctl in kernel 3.4 restored the previous behavior and eliminated the
need for this workaround.

This patch was heavily inspired by a similar but more complex patch by
Larry Baker.

Reported-by: Larry Baker <[email protected]>
Signed-off-by: "Eric W. Biederman" <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/decnet/af_decnet.c | 4 ++++
net/decnet/sysctl_net_decnet.c | 28 ++++++++++++++++++++++++++++
2 files changed, 32 insertions(+), 0 deletions(-)

--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -2354,6 +2354,8 @@ static const struct proto_ops dn_proto_o
.sendpage = sock_no_sendpage,
};

+void dn_register_sysctl_skeleton(void);
+void dn_unregister_sysctl_skeleton(void);
void dn_register_sysctl(void);
void dn_unregister_sysctl(void);

@@ -2374,6 +2376,7 @@ static int __init decnet_init(void)
if (rc != 0)
goto out;

+ dn_register_sysctl_skeleton();
dn_neigh_init();
dn_dev_init();
dn_route_init();
@@ -2413,6 +2416,7 @@ static void __exit decnet_exit(void)
dn_fib_cleanup();

proc_net_remove(&init_net, "decnet");
+ dn_unregister_sysctl_skeleton();

proto_unregister(&dn_proto);

--- a/net/decnet/sysctl_net_decnet.c
+++ b/net/decnet/sysctl_net_decnet.c
@@ -55,6 +55,7 @@ static int max_decnet_no_fc_max_cwnd[] =
static char node_name[7] = "???";

static struct ctl_table_header *dn_table_header = NULL;
+static struct ctl_table_header *dn_skeleton_table_header = NULL;

/*
* ctype.h :-)
@@ -357,6 +358,27 @@ static struct ctl_path dn_path[] = {
{ }
};

+static struct ctl_table empty[1];
+
+static struct ctl_table dn_skeleton[] = {
+ {
+ .procname = "conf",
+ .mode = 0555,
+ .child = empty,
+ },
+ { }
+};
+
+void dn_register_sysctl_skeleton(void)
+{
+ dn_skeleton_table_header = register_sysctl_paths(dn_path, dn_skeleton);
+}
+
+void dn_unregister_sysctl_skeleton(void)
+{
+ unregister_sysctl_table(dn_skeleton_table_header);
+}
+
void dn_register_sysctl(void)
{
dn_table_header = register_sysctl_paths(dn_path, dn_table);
@@ -368,6 +390,12 @@ void dn_unregister_sysctl(void)
}

#else /* CONFIG_SYSCTL */
+void dn_register_sysctl_skeleton(void)
+{
+}
+void dn_unregister_sysctl_skeleton(void)
+{
+}
void dn_unregister_sysctl(void)
{
}

2013-03-18 04:31:54

by Ben Hutchings

[permalink] [raw]
Subject: [ 37/82] tty: Correct tty buffer flush.

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

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

From: Ilya Zykov <[email protected]>

commit 64325a3be08d364a62ee8f84b2cf86934bc2544a upstream.

The root of problem is carelessly zeroing pointer(in function __tty_buffer_flush()),
when another thread can use it. It can be cause of "NULL pointer dereference".
Main idea of the patch, this is never free last (struct tty_buffer) in the active buffer.
Only flush the data for ldisc(buf->head->read = buf->head->commit).
At that moment driver can collect(write) data in buffer without conflict.
It is repeat behavior of flush_to_ldisc(), only without feeding data to ldisc.

Signed-off-by: Ilya Zykov <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -114,11 +114,14 @@ static void __tty_buffer_flush(struct tt
{
struct tty_buffer *thead;

- while ((thead = tty->buf.head) != NULL) {
- tty->buf.head = thead->next;
- tty_buffer_free(tty, thead);
+ if (tty->buf.head == NULL)
+ return;
+ while ((thead = tty->buf.head->next) != NULL) {
+ tty_buffer_free(tty, tty->buf.head);
+ tty->buf.head = thead;
}
- tty->buf.tail = NULL;
+ WARN_ON(tty->buf.head != tty->buf.tail);
+ tty->buf.head->read = tty->buf.head->commit;
}

/**

2013-03-18 04:31:50

by Ben Hutchings

[permalink] [raw]
Subject: [ 41/82] ftrace: Update the kconfig for DYNAMIC_FTRACE

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

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

From: Steven Rostedt <[email protected]>

commit db05021d49a994ee40a9735d9c3cb0060c9babb8 upstream.

The prompt to enable DYNAMIC_FTRACE (the ability to nop and
enable function tracing at run time) had a confusing statement:

"enable/disable ftrace tracepoints dynamically"

This was written before tracepoints were added to the kernel,
but now that tracepoints have been added, this is very confusing
and has confused people enough to give wrong information during
presentations.

Not only that, I looked at the help text, and it still references
that dreaded daemon that use to wake up once a second to update
the nop locations and brick NICs, that hasn't been around for over
five years.

Time to bring the text up to the current decade.

Reported-by: Ezequiel Garcia <[email protected]>
Signed-off-by: Steven Rostedt <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
kernel/trace/Kconfig | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)

--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -386,24 +386,28 @@ config KPROBE_EVENT
If you want to use perf tools, this option is strongly recommended.

config DYNAMIC_FTRACE
- bool "enable/disable ftrace tracepoints dynamically"
+ bool "enable/disable function tracing dynamically"
depends on FUNCTION_TRACER
depends on HAVE_DYNAMIC_FTRACE
default y
help
- This option will modify all the calls to ftrace dynamically
- (will patch them out of the binary image and replace them
- with a No-Op instruction) as they are called. A table is
- created to dynamically enable them again.
+ This option will modify all the calls to function tracing
+ dynamically (will patch them out of the binary image and
+ replace them with a No-Op instruction) on boot up. During
+ compile time, a table is made of all the locations that ftrace
+ can function trace, and this table is linked into the kernel
+ image. When this is enabled, functions can be individually
+ enabled, and the functions not enabled will not affect
+ performance of the system.
+
+ See the files in /sys/kernel/debug/tracing:
+ available_filter_functions
+ set_ftrace_filter
+ set_ftrace_notrace

This way a CONFIG_FUNCTION_TRACER kernel is slightly larger, but
otherwise has native performance as long as no tracing is active.

- The changes to the code are done by a kernel thread that
- wakes up once a second and checks to see if any ftrace calls
- were made. If so, it runs stop_machine (stops all CPUS)
- and modifies the code to jump over the call to ftrace.
-
config FUNCTION_PROFILER
bool "Kernel function profiler"
depends on FUNCTION_TRACER

2013-03-18 04:31:42

by Ben Hutchings

[permalink] [raw]
Subject: [ 59/82] Fix 4 port and add support for 8 port Unknown PCI serial port cards

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

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

From: Scott Ashcroft <[email protected]>

commit d13402a4a944e72612a9ec5c9190e35717c02a9d upstream.

I've managed to find an 8 port version of the card 4 port card which was discussed here:

http://marc.info/?l=linux-serial&m=120760744205314&w=2

Looking back at that thread there were two issues in the original patch.

1) The I/O ports for the UARTs are within BAR2 not BAR0. This can been seen in the original post.
2) A serial quirk isn't needed as these cards have no memory in BAR0 which makes pci_plx9050_init just return.

This patch fixes the 4 port support to use BAR2, removes the bogus quirk and adds support for the 8 port card.

$ lspci -vvv -n -s 00:08.0
00:08.0 0780: 10b5:9050 (rev 01)
Subsystem: 10b5:1588
Control: I/O+ Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Interrupt: pin A routed to IRQ 17
Region 1: I/O ports at ff00 [size=128]
Region 2: I/O ports at fe00 [size=64]
Region 3: I/O ports at fd00 [size=8]
Capabilities: <access denied>
Kernel driver in use: serial

$ dmesg | grep 0000:00:08.0:
[ 0.083320] pci 0000:00:08.0: [10b5:9050] type 0 class 0x000780
[ 0.083355] pci 0000:00:08.0: reg 14: [io 0xff00-0xff7f]
[ 0.083369] pci 0000:00:08.0: reg 18: [io 0xfe00-0xfe3f]
[ 0.083382] pci 0000:00:08.0: reg 1c: [io 0xfd00-0xfd07]
[ 0.083460] pci 0000:00:08.0: PME# supported from D0 D3hot
[ 1.212867] 0000:00:08.0: ttyS4 at I/O 0xfe00 (irq = 17) is a 16550A
[ 1.233073] 0000:00:08.0: ttyS5 at I/O 0xfe08 (irq = 17) is a 16550A
[ 1.253270] 0000:00:08.0: ttyS6 at I/O 0xfe10 (irq = 17) is a 16550A
[ 1.273468] 0000:00:08.0: ttyS7 at I/O 0xfe18 (irq = 17) is a 16550A
[ 1.293666] 0000:00:08.0: ttyS8 at I/O 0xfe20 (irq = 17) is a 16550A
[ 1.313863] 0000:00:08.0: ttyS9 at I/O 0xfe28 (irq = 17) is a 16550A
[ 1.334061] 0000:00:08.0: ttyS10 at I/O 0xfe30 (irq = 17) is a 16550A
[ 1.354258] 0000:00:08.0: ttyS11 at I/O 0xfe38 (irq = 17) is a 16550A

Signed-off-by: Scott Ashcroft <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[bwh: Backported to 3.2: adjust filename, context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/tty/serial/8250_pci.c | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)

--- a/drivers/tty/serial/8250_pci.c
+++ b/drivers/tty/serial/8250_pci.c
@@ -1154,6 +1154,7 @@ pci_xr17c154_setup(struct serial_private

/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
+#define PCI_SUBDEVICE_ID_UNKNOWN_0x1588 0x1588

/*
* Master list of serial port init/setup/exit quirks.
@@ -1418,15 +1419,6 @@ static struct pci_serial_quirk pci_seria
},
{
.vendor = PCI_VENDOR_ID_PLX,
- .device = PCI_DEVICE_ID_PLX_9050,
- .subvendor = PCI_VENDOR_ID_PLX,
- .subdevice = PCI_SUBDEVICE_ID_UNKNOWN_0x1584,
- .init = pci_plx9050_init,
- .setup = pci_default_setup,
- .exit = __devexit_p(pci_plx9050_exit),
- },
- {
- .vendor = PCI_VENDOR_ID_PLX,
.device = PCI_DEVICE_ID_PLX_ROMULUS,
.subvendor = PCI_VENDOR_ID_PLX,
.subdevice = PCI_DEVICE_ID_PLX_ROMULUS,
@@ -3120,7 +3112,12 @@ static struct pci_device_id serial_pci_t
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
PCI_VENDOR_ID_PLX,
PCI_SUBDEVICE_ID_UNKNOWN_0x1584, 0, 0,
- pbn_b0_4_115200 },
+ pbn_b2_4_115200 },
+ /* Unknown card - subdevice 0x1588 */
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_VENDOR_ID_PLX,
+ PCI_SUBDEVICE_ID_UNKNOWN_0x1588, 0, 0,
+ pbn_b2_8_115200 },
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
PCI_SUBVENDOR_ID_KEYSPAN,
PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0,

2013-03-18 04:31:40

by Ben Hutchings

[permalink] [raw]
Subject: [ 55/82] qcaux: add Franklin U600

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

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

From: Dan Williams <[email protected]>

commit 2d90e63603ac235aecd7d20e234616e0682c8b1f upstream.

4 ports; AT/PPP is standard CDC-ACM. The other three (added by this
patch) are QCDM/DIAG, possibly GPS, and unknown.

Signed-off-by: Dan Williams <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/qcaux.c | 1 +
1 file changed, 1 insertion(+)

--- a/drivers/usb/serial/qcaux.c
+++ b/drivers/usb/serial/qcaux.c
@@ -69,6 +69,7 @@ static struct usb_device_id id_table[] =
{ USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfd, 0xff) }, /* NMEA */
{ USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfe, 0xff) }, /* WMC */
{ USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xff, 0xff) }, /* DIAG */
+ { USB_DEVICE_AND_INTERFACE_INFO(0x1fac, 0x0151, 0xff, 0xff, 0xff) },
{ },
};
MODULE_DEVICE_TABLE(usb, id_table);

2013-03-18 04:31:37

by Ben Hutchings

[permalink] [raw]
Subject: [ 45/82] USB: EHCI: dont check DMA values in QH overlays

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

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

From: Alan Stern <[email protected]>

commit feca7746d5d9e84b105a613b7f3b6ad00d327372 upstream.

This patch (as1661) fixes a rather obscure bug in ehci-hcd. In a
couple of places, the driver compares the DMA address stored in a QH's
overlay region with the address of a particular qTD, in order to see
whether that qTD is the one currently being processed by the hardware.
(If it is then the status in the QH's overlay region is more
up-to-date than the status in the qTD, and if it isn't then the
overlay's value needs to be adjusted when the QH is added back to the
active schedule.)

However, DMA address in the overlay region isn't always valid. It
sometimes will contain a stale value, which may happen by coincidence
to be equal to a qTD's DMA address. Instead of checking the DMA
address, we should check whether the overlay region is active and
valid. The patch tests the ACTIVE bit in the overlay, and clears this
bit when the overlay becomes invalid (which happens when the
currently-executing URB is unlinked).

This is the second part of a fix for the regression reported at:

https://bugs.launchpad.net/bugs/1088733

Signed-off-by: Alan Stern <[email protected]>
Reported-by: Joseph Salisbury <[email protected]>
Reported-and-tested-by: Stephen Thirlwall <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/host/ehci-q.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)

--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -135,7 +135,7 @@ qh_refresh (struct ehci_hcd *ehci, struc
* qtd is updated in qh_completions(). Update the QH
* overlay here.
*/
- if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) {
+ if (qh->hw->hw_token & ACTIVE_BIT(ehci)) {
qh->hw->hw_qtd_next = qtd->hw_next;
qtd = NULL;
}
@@ -444,11 +444,19 @@ qh_completions (struct ehci_hcd *ehci, s
else if (last_status == -EINPROGRESS && !urb->unlinked)
continue;

- /* qh unlinked; token in overlay may be most current */
- if (state == QH_STATE_IDLE
- && cpu_to_hc32(ehci, qtd->qtd_dma)
- == hw->hw_current) {
+ /*
+ * If this was the active qtd when the qh was unlinked
+ * and the overlay's token is active, then the overlay
+ * hasn't been written back to the qtd yet so use its
+ * token instead of the qtd's. After the qtd is
+ * processed and removed, the overlay won't be valid
+ * any more.
+ */
+ if (state == QH_STATE_IDLE &&
+ qh->qtd_list.next == &qtd->qtd_list &&
+ (hw->hw_token & ACTIVE_BIT(ehci))) {
token = hc32_to_cpu(ehci, hw->hw_token);
+ hw->hw_token &= ~ACTIVE_BIT(ehci);

/* An unlink may leave an incomplete
* async transaction in the TT buffer.

2013-03-18 04:31:29

by Ben Hutchings

[permalink] [raw]
Subject: [ 54/82] staging: vt6656: Fix oops on resume from suspend.

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

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

From: Malcolm Priestley <[email protected]>

commit 6987a6dabfc40222ef767f67b57212fe3a0225fb upstream.

Remove usb_put_dev from vt6656_suspend and usb_get_dev
from vt6566_resume.

These are not normally in suspend/resume functions.

Signed-off-by: Malcolm Priestley <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/staging/vt6656/main_usb.c | 4 ----
1 file changed, 4 deletions(-)

--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -718,8 +718,6 @@ static int vt6656_suspend(struct usb_int
if (device->flags & DEVICE_FLAGS_OPENED)
device_close(device->dev);

- usb_put_dev(interface_to_usbdev(intf));
-
return 0;
}

@@ -730,8 +728,6 @@ static int vt6656_resume(struct usb_inte
if (!device || !device->dev)
return -ENODEV;

- usb_get_dev(interface_to_usbdev(intf));
-
if (!(device->flags & DEVICE_FLAGS_OPENED))
device_open(device->dev);


2013-03-18 04:31:26

by Ben Hutchings

[permalink] [raw]
Subject: [ 64/82] USB: cdc-wdm: fix buffer overflow

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

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

From: Oliver Neukum <[email protected]>

commit c0f5ecee4e741667b2493c742b60b6218d40b3aa upstream.

The buffer for responses must not overflow.
If this would happen, set a flag, drop the data and return
an error after user space has read all remaining data.

Signed-off-by: Oliver Neukum <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/class/cdc-wdm.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)

--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -70,6 +70,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
#define WDM_POLL_RUNNING 6
#define WDM_RESPONDING 7
#define WDM_SUSPENDING 8
+#define WDM_OVERFLOW 10

#define WDM_MAX 16

@@ -134,6 +135,7 @@ static void wdm_in_callback(struct urb *
{
struct wdm_device *desc = urb->context;
int status = urb->status;
+ int length = urb->actual_length;

spin_lock(&desc->iuspin);
clear_bit(WDM_RESPONDING, &desc->flags);
@@ -164,9 +166,17 @@ static void wdm_in_callback(struct urb *
}

desc->rerr = status;
- desc->reslength = urb->actual_length;
- memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength);
- desc->length += desc->reslength;
+ if (length + desc->length > desc->wMaxCommand) {
+ /* The buffer would overflow */
+ set_bit(WDM_OVERFLOW, &desc->flags);
+ } else {
+ /* we may already be in overflow */
+ if (!test_bit(WDM_OVERFLOW, &desc->flags)) {
+ memmove(desc->ubuf + desc->length, desc->inbuf, length);
+ desc->length += length;
+ desc->reslength = length;
+ }
+ }
skip_error:
wake_up(&desc->wait);

@@ -433,6 +443,11 @@ retry:
rv = -ENODEV;
goto err;
}
+ if (test_bit(WDM_OVERFLOW, &desc->flags)) {
+ clear_bit(WDM_OVERFLOW, &desc->flags);
+ rv = -ENOBUFS;
+ goto err;
+ }
i++;
if (file->f_flags & O_NONBLOCK) {
if (!test_bit(WDM_READ, &desc->flags)) {
@@ -472,6 +487,7 @@ retry:
spin_unlock_irq(&desc->iuspin);
goto retry;
}
+
if (!desc->reslength) { /* zero length read */
dev_dbg(&desc->intf->dev, "%s: zero length - clearing WDM_READ\n", __func__);
clear_bit(WDM_READ, &desc->flags);
@@ -926,6 +942,7 @@ static int wdm_post_reset(struct usb_int
struct wdm_device *desc = usb_get_intfdata(intf);
int rv;

+ clear_bit(WDM_OVERFLOW, &desc->flags);
rv = recover_from_urb_loss(desc);
mutex_unlock(&desc->wlock);
mutex_unlock(&desc->rlock);

2013-03-18 04:31:23

by Ben Hutchings

[permalink] [raw]
Subject: [ 63/82] w1: fix oops when w1_search is called from netlink connector

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

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

From: Marcin Jurkowski <[email protected]>

commit 9d1817cab2f030f6af360e961cc69bb1da8ad765 upstream.

On Sat, Mar 02, 2013 at 10:45:10AM +0100, Sven Geggus wrote:
> This is the bad commit I found doing git bisect:
> 04f482faf50535229a5a5c8d629cf963899f857c is the first bad commit
> commit 04f482faf50535229a5a5c8d629cf963899f857c
> Author: Patrick McHardy <[email protected]>
> Date: Mon Mar 28 08:39:36 2011 +0000

Good job. I was too lazy to bisect for bad commit;)

Reading the code I found problematic kthread_should_stop call from netlink
connector which causes the oops. After applying a patch, I've been testing
owfs+w1 setup for nearly two days and it seems to work very reliable (no
hangs, no memleaks etc).
More detailed description and possible fix is given below:

Function w1_search can be called from either kthread or netlink callback.
While the former works fine, the latter causes oops due to kthread_should_stop
invocation.

This patch adds a check if w1_search is serving netlink command, skipping
kthread_should_stop invocation if so.

Signed-off-by: Marcin Jurkowski <[email protected]>
Acked-by: Evgeniy Polyakov <[email protected]>
Cc: Josh Boyer <[email protected]>
Tested-by: Sven Geggus <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/w1/w1.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -918,7 +918,8 @@ void w1_search(struct w1_master *dev, u8
tmp64 = (triplet_ret >> 2);
rn |= (tmp64 << i);

- if (kthread_should_stop()) {
+ /* ensure we're called from kthread and not by netlink callback */
+ if (!dev->priv && kthread_should_stop()) {
dev_dbg(&dev->dev, "Abort w1_search\n");
return;
}

2013-03-18 04:31:21

by Ben Hutchings

[permalink] [raw]
Subject: [ 79/82] loopdev: fix a deadlock

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

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

From: Guo Chao <[email protected]>

commit 5370019dc2d2c2ff90e95d181468071362934f3a upstream.

bd_mutex and lo_ctl_mutex can be held in different order.

Path #1:

blkdev_open
blkdev_get
__blkdev_get (hold bd_mutex)
lo_open (hold lo_ctl_mutex)

Path #2:

blkdev_ioctl
lo_ioctl (hold lo_ctl_mutex)
lo_set_capacity (hold bd_mutex)

Lockdep does not report it, because path #2 actually holds a subclass of
lo_ctl_mutex. This subclass seems creep into the code by mistake. The
patch author actually just mentioned it in the changelog, see commit
f028f3b2 ("loop: fix circular locking in loop_clr_fd()"), also see:

http://marc.info/?l=linux-kernel&m=123806169129727&w=2

Path #2 hold bd_mutex to call bd_set_size(), I've protected it
with i_mutex in a previous patch, so drop bd_mutex at this site.

Signed-off-by: Guo Chao <[email protected]>
Cc: Alexander Viro <[email protected]>
Cc: Guo Chao <[email protected]>
Cc: M. Hindess <[email protected]>
Cc: Nikanth Karthikesan <[email protected]>
Cc: Jens Axboe <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/block/loop.c | 2 --
1 file changed, 2 deletions(-)

--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1262,11 +1262,9 @@ static int loop_set_capacity(struct loop
/* the width of sector_t may be narrow for bit-shift */
sz = sec;
sz <<= 9;
- mutex_lock(&bdev->bd_mutex);
bd_set_size(bdev, sz);
/* let user-space know about the new size */
kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE);
- mutex_unlock(&bdev->bd_mutex);

out:
return err;

2013-03-18 04:31:18

by Ben Hutchings

[permalink] [raw]
Subject: [ 70/82] USB: Dont use EHCI port sempahore for USB 3.0 hubs.

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

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

From: Sarah Sharp <[email protected]>

commit 0fe51aa5eee51db7c7ecd201d42a977ad79c58b6 upstream.

The EHCI host controller needs to prevent EHCI initialization when the
UHCI or OHCI companion controller is in the middle of a port reset. It
uses ehci_cf_port_reset_rwsem to do this. USB 3.0 hubs can't be under
an EHCI host controller, so it makes no sense to down the semaphore for
USB 3.0 hubs. It also makes the warm port reset code more complex.

Don't down ehci_cf_port_reset_rwsem for USB 3.0 hubs.

Signed-off-by: Sarah Sharp <[email protected]>
Acked-by: Alan Stern <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/core/hub.c | 15 +++++++--------
1 files changed, 7 insertions(+), 8 deletions(-)

--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2271,17 +2271,16 @@ static int hub_port_reset(struct usb_hub
{
int i, status;

- if (!warm) {
- /* Block EHCI CF initialization during the port reset.
- * Some companion controllers don't like it when they mix.
- */
- down_read(&ehci_cf_port_reset_rwsem);
- } else {
- if (!hub_is_superspeed(hub->hdev)) {
+ if (!hub_is_superspeed(hub->hdev)) {
+ if (warm) {
dev_err(hub->intfdev, "only USB3 hub support "
"warm reset\n");
return -EINVAL;
}
+ /* Block EHCI CF initialization during the port reset.
+ * Some companion controllers don't like it when they mix.
+ */
+ down_read(&ehci_cf_port_reset_rwsem);
}

/* Reset the port */
@@ -2319,7 +2318,7 @@ static int hub_port_reset(struct usb_hub
port1);

done:
- if (!warm)
+ if (!hub_is_superspeed(hub->hdev))
up_read(&ehci_cf_port_reset_rwsem);

return status;

2013-03-18 04:34:33

by Ben Hutchings

[permalink] [raw]
Subject: [ 21/82] ARM: 7663/1: perf: fix ARMv7 EVTYPE_MASK to include NSH bit

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

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

From: Will Deacon <[email protected]>

commit f2fe09b055e2549de41fb107b34c60bac4a1b0cf upstream.

Masked out PMXEVTYPER.NSH means that we can't enable profiling at PL2,
regardless of the settings in the HDCR.

This patch fixes the broken mask.

Reported-by: Christoffer Dall <[email protected]>
Signed-off-by: Will Deacon <[email protected]>
Signed-off-by: Russell King <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/arm/kernel/perf_event_v7.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -720,7 +720,7 @@ static const unsigned armv7_a15_perf_cac
/*
* PMXEVTYPER: Event selection reg
*/
-#define ARMV7_EVTYPE_MASK 0xc00000ff /* Mask for writable bits */
+#define ARMV7_EVTYPE_MASK 0xc80000ff /* Mask for writable bits */
#define ARMV7_EVTYPE_EVENT 0xff /* Mask for EVENT bits */

/*

2013-03-18 04:31:14

by Ben Hutchings

[permalink] [raw]
Subject: [ 47/82] USB: option: add Huawei E5331

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

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

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

commit daec90e7382cbd0e73eb6861109b3da91e5ab1f3 upstream.

Another device using CDC ACM with vendor specific protocol to mark
serial functions.

Signed-off-by: Bjørn Mork <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/option.c | 1 +
1 file changed, 1 insertion(+)

--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -579,6 +579,7 @@ static const struct usb_device_id option
{ USB_DEVICE(QUANTA_VENDOR_ID, 0xea42),
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c05, USB_CLASS_COMM, 0x02, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c1f, USB_CLASS_COMM, 0x02, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t) &net_intf1_blacklist },

2013-03-18 04:34:55

by Ben Hutchings

[permalink] [raw]
Subject: [ 20/82] drm/i915: Dont clobber crtc->fb when queue_flip fails

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

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

From: Ville Syrjälä <[email protected]>

commit 4a35f83b2b7c6aae3fc0d1c4554fdc99dc33ad07 upstream.

Restore crtc->fb to the old framebuffer if queue_flip fails.

While at it, kill the pointless intel_fb temp variable.

v2: Update crtc->fb before queue_flip and restore it back
after a failure.

Signed-off-by: Ville Syrjälä <[email protected]>
Reviewed-by: Chris Wilson <[email protected]>
Reported-and-Tested-by: Mika Kuoppala <[email protected]>
Signed-off-by: Daniel Vetter <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/i915/intel_display.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)

--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7280,8 +7280,8 @@ static int intel_crtc_page_flip(struct d
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_framebuffer *intel_fb;
- struct drm_i915_gem_object *obj;
+ struct drm_framebuffer *old_fb = crtc->fb;
+ struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_unpin_work *work;
unsigned long flags;
@@ -7293,8 +7293,7 @@ static int intel_crtc_page_flip(struct d

work->event = event;
work->dev = crtc->dev;
- intel_fb = to_intel_framebuffer(crtc->fb);
- work->old_fb_obj = intel_fb->obj;
+ work->old_fb_obj = to_intel_framebuffer(old_fb)->obj;
INIT_WORK(&work->work, intel_unpin_work_fn);

ret = drm_vblank_get(dev, intel_crtc->pipe);
@@ -7314,9 +7313,6 @@ static int intel_crtc_page_flip(struct d
intel_crtc->unpin_work = work;
spin_unlock_irqrestore(&dev->event_lock, flags);

- intel_fb = to_intel_framebuffer(fb);
- obj = intel_fb->obj;
-
mutex_lock(&dev->struct_mutex);

/* Reference the objects for the scheduled work. */
@@ -7347,6 +7343,7 @@ static int intel_crtc_page_flip(struct d

cleanup_pending:
atomic_sub(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip);
+ crtc->fb = old_fb;
drm_gem_object_unreference(&work->old_fb_obj->base);
drm_gem_object_unreference(&obj->base);
mutex_unlock(&dev->struct_mutex);

2013-03-18 04:34:57

by Ben Hutchings

[permalink] [raw]
Subject: [ 24/82] hwmon: (sht15) Check return value of regulator_enable()

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

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

From: Mark Brown <[email protected]>

commit 3e78080f81481aa8340374d5a37ae033c1cf4272 upstream.

Not having power is a pretty serious error so check that we are able to
enable the supply and error out if we can't.

Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Guenter Roeck <[email protected]>
[bwh: Backported to 3.2: driver does not use the devm API to manage
memory, so goto err_free_data rather than returning on error]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/hwmon/sht15.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

--- a/drivers/hwmon/sht15.c
+++ b/drivers/hwmon/sht15.c
@@ -926,7 +926,13 @@ static int __devinit sht15_probe(struct
if (voltage)
data->supply_uV = voltage;

- regulator_enable(data->reg);
+ ret = regulator_enable(data->reg);
+ if (ret != 0) {
+ dev_err(&pdev->dev,
+ "failed to enable regulator: %d\n", ret);
+ goto err_free_data;
+ }
+
/*
* Setup a notifier block to update this if another device
* causes the voltage to change

2013-03-18 04:35:01

by Ben Hutchings

[permalink] [raw]
Subject: [ 19/82] dm snapshot: add missing module aliases

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

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

From: Mikulas Patocka <[email protected]>

commit 23cb21092eb9dcec9d3604b68d95192b79915890 upstream.

Add module aliases so that autoloading works correctly if the user
tries to activate "snapshot-origin" or "snapshot-merge" targets.

Reference: https://bugzilla.redhat.com/889973

Reported-by: Chao Yang <[email protected]>
Signed-off-by: Mikulas Patocka <[email protected]>
Signed-off-by: Alasdair G Kergon <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/md/dm-snap.c | 2 ++
1 file changed, 2 insertions(+)

--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -2323,3 +2323,5 @@ module_exit(dm_snapshot_exit);
MODULE_DESCRIPTION(DM_NAME " snapshot target");
MODULE_AUTHOR("Joe Thornber");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("dm-snapshot-origin");
+MODULE_ALIAS("dm-snapshot-merge");

2013-03-18 04:35:46

by Ben Hutchings

[permalink] [raw]
Subject: [ 23/82] hwmon: (pmbus/ltc2978) Use detected chip ID to select supported functionality

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

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

From: Guenter Roeck <[email protected]>

commit f366fccd0809f13ba20d64cae3c83f7338c88af7 upstream.

We read the chip ID from the chip, use it to determine if the chip ID provided
to the driver is correct, and report it if wrong. We should also use the
correct chip ID to select supported functionality.

Signed-off-by: Guenter Roeck <[email protected]>
Acked-by: Jean Delvare <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/hwmon/pmbus/ltc2978.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/hwmon/pmbus/ltc2978.c
+++ b/drivers/hwmon/pmbus/ltc2978.c
@@ -328,7 +328,7 @@ static int ltc2978_probe(struct i2c_clie
data->temp_max = 0x7c00;
data->temp2_max = 0x7c00;

- switch (id->driver_data) {
+ switch (data->id) {
case ltc2978:
info->read_word_data = ltc2978_read_word_data;
info->pages = 8;

2013-03-18 04:31:12

by Ben Hutchings

[permalink] [raw]
Subject: [ 81/82] btrfs: use rcu_barrier() to wait for bdev puts at unmount

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

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

From: Eric Sandeen <[email protected]>

commit bc178622d40d87e75abc131007342429c9b03351 upstream.

Doing this would reliably fail with -EBUSY for me:

# mount /dev/sdb2 /mnt/scratch; umount /mnt/scratch; mkfs.btrfs -f /dev/sdb2
...
unable to open /dev/sdb2: Device or resource busy

because mkfs.btrfs tries to open the device O_EXCL, and somebody still has it.

Using systemtap to track bdev gets & puts shows a kworker thread doing a
blkdev put after mkfs attempts a get; this is left over from the unmount
path:

btrfs_close_devices
__btrfs_close_devices
call_rcu(&device->rcu, free_device);
free_device
INIT_WORK(&device->rcu_work, __free_device);
schedule_work(&device->rcu_work);

so unmount might complete before __free_device fires & does its blkdev_put.

Adding an rcu_barrier() to btrfs_close_devices() causes unmount to wait
until all blkdev_put()s are done, and the device is truly free once
unmount completes.

Signed-off-by: Eric Sandeen <[email protected]>
Signed-off-by: Josef Bacik <[email protected]>
Signed-off-by: Chris Mason <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/btrfs/volumes.c | 6 ++++++
1 file changed, 6 insertions(+)

--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -577,6 +577,12 @@ int btrfs_close_devices(struct btrfs_fs_
__btrfs_close_devices(fs_devices);
free_fs_devices(fs_devices);
}
+ /*
+ * Wait for rcu kworkers under __btrfs_close_devices
+ * to finish all blkdev_puts so device is really
+ * free when umount is done.
+ */
+ rcu_barrier();
return ret;
}


2013-03-18 04:36:08

by Ben Hutchings

[permalink] [raw]
Subject: [ 22/82] hwmon: (pmbus/ltc2978) Fix peak attribute handling

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

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

From: Guenter Roeck <[email protected]>

commit dbd712c2272764a536e29ad6841dba74989a39d9 upstream.

Peak attributes were not initialized and cleared correctly.
Also, temp2_max is only supported on page 0 and thus does not need to be
an array.

Signed-off-by: Guenter Roeck <[email protected]>
Acked-by: Jean Delvare <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/hwmon/pmbus/ltc2978.c | 28 +++++++++++++++-------------
1 file changed, 15 insertions(+), 13 deletions(-)

--- a/drivers/hwmon/pmbus/ltc2978.c
+++ b/drivers/hwmon/pmbus/ltc2978.c
@@ -62,7 +62,7 @@ struct ltc2978_data {
int temp_min, temp_max;
int vout_min[8], vout_max[8];
int iout_max[2];
- int temp2_max[2];
+ int temp2_max;
struct pmbus_driver_info info;
};

@@ -204,10 +204,9 @@ static int ltc3880_read_word_data(struct
ret = pmbus_read_word_data(client, page,
LTC3880_MFR_TEMPERATURE2_PEAK);
if (ret >= 0) {
- if (lin11_to_val(ret)
- > lin11_to_val(data->temp2_max[page]))
- data->temp2_max[page] = ret;
- ret = data->temp2_max[page];
+ if (lin11_to_val(ret) > lin11_to_val(data->temp2_max))
+ data->temp2_max = ret;
+ ret = data->temp2_max;
}
break;
case PMBUS_VIRT_READ_VIN_MIN:
@@ -248,11 +247,11 @@ static int ltc2978_write_word_data(struc

switch (reg) {
case PMBUS_VIRT_RESET_IOUT_HISTORY:
- data->iout_max[page] = 0x7fff;
+ data->iout_max[page] = 0x7c00;
ret = ltc2978_clear_peaks(client, page, data->id);
break;
case PMBUS_VIRT_RESET_TEMP2_HISTORY:
- data->temp2_max[page] = 0x7fff;
+ data->temp2_max = 0x7c00;
ret = ltc2978_clear_peaks(client, page, data->id);
break;
case PMBUS_VIRT_RESET_VOUT_HISTORY:
@@ -262,12 +261,12 @@ static int ltc2978_write_word_data(struc
break;
case PMBUS_VIRT_RESET_VIN_HISTORY:
data->vin_min = 0x7bff;
- data->vin_max = 0;
+ data->vin_max = 0x7c00;
ret = ltc2978_clear_peaks(client, page, data->id);
break;
case PMBUS_VIRT_RESET_TEMP_HISTORY:
data->temp_min = 0x7bff;
- data->temp_max = 0x7fff;
+ data->temp_max = 0x7c00;
ret = ltc2978_clear_peaks(client, page, data->id);
break;
default:
@@ -323,10 +322,11 @@ static int ltc2978_probe(struct i2c_clie
info = &data->info;
info->write_word_data = ltc2978_write_word_data;

- data->vout_min[0] = 0xffff;
data->vin_min = 0x7bff;
+ data->vin_max = 0x7c00;
data->temp_min = 0x7bff;
- data->temp_max = 0x7fff;
+ data->temp_max = 0x7c00;
+ data->temp2_max = 0x7c00;

switch (id->driver_data) {
case ltc2978:
@@ -338,7 +338,6 @@ static int ltc2978_probe(struct i2c_clie
for (i = 1; i < 8; i++) {
info->func[i] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT;
- data->vout_min[i] = 0xffff;
}
break;
case ltc3880:
@@ -354,12 +353,15 @@ static int ltc2978_probe(struct i2c_clie
| PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
| PMBUS_HAVE_POUT
| PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
- data->vout_min[1] = 0xffff;
+ data->iout_max[0] = 0x7c00;
+ data->iout_max[1] = 0x7c00;
break;
default:
ret = -ENODEV;
goto err_mem;
}
+ for (i = 0; i < info->pages; i++)
+ data->vout_min[i] = 0xffff;

ret = pmbus_do_probe(client, id, info);
if (ret)

2013-03-18 04:36:27

by Ben Hutchings

[permalink] [raw]
Subject: [ 30/82] HID: add support for Sony RF receiver with USB product id 0x0374

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

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

From: Fernando Luis Vázquez Cao <[email protected]>

commit a464918419f94a0043d2f549d6defb4c3f69f68a upstream.

Some Vaio desktop computers, among them the VGC-LN51JGB multimedia PC, have
a RF receiver, multi-interface USB device 054c:0374, that is used to connect
a wireless keyboard and a wireless mouse.

The keyboard works flawlessly, but the mouse (VGP-WMS3 in my case) does not
seem to be generating any pointer events. The problem is that the mouse pointer
is wrongly declared as a constant non-data variable in the report descriptor
(see lsusb and usbhid-dump output below), with the consequence that it is
ignored by the HID code.

Add this device to the have-special-driver list and fix up the report
descriptor in the Sony-specific driver which happens to already have a fixup
for a similar firmware bug.

# lsusb -vd 054C:0374
Bus 003 Device 002: ID 054c:0374 Sony Corp.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x054c Sony Corp.
idProduct 0x0374
iSerial 0
[...]
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 2 Mouse
iInterface 2 RF Receiver
[...]
Report Descriptor: (length is 100)
[...]
Item(Global): Usage Page, data= [ 0x01 ] 1
Generic Desktop Controls
Item(Local ): Usage, data= [ 0x30 ] 48
Direction-X
Item(Local ): Usage, data= [ 0x31 ] 49
Direction-Y
Item(Global): Report Count, data= [ 0x02 ] 2
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Logical Minimum, data= [ 0x81 ] 129
Item(Global): Logical Maximum, data= [ 0x7f ] 127
Item(Main ): Input, data= [ 0x07 ] 7
Constant Variable Relative No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield

# usbhid-dump
003:002:001:DESCRIPTOR 1357910009.758544
05 01 09 02 A1 01 05 01 09 02 A1 02 85 01 09 01
A1 00 05 09 19 01 29 05 95 05 75 01 15 00 25 01
81 02 75 03 95 01 81 01 05 01 09 30 09 31 95 02
75 08 15 81 25 7F 81 07 A1 02 85 01 09 38 35 00
45 00 15 81 25 7F 95 01 75 08 81 06 C0 A1 02 85
01 05 0C 15 81 25 7F 95 01 75 08 0A 38 02 81 06
C0 C0 C0 C0

Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Fernando Luis Vazquez Cao <[email protected]>
Signed-off-by: Jiri Kosina <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/hid/hid-core.c | 1 +
drivers/hid/hid-ids.h | 1 +
drivers/hid/hid-sony.c | 4 +++-
3 files changed, 5 insertions(+), 1 deletion(-)

--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1533,6 +1533,7 @@ static const struct hid_device_id hid_ha
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) },
{ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM) },
{ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX) },
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -644,6 +644,7 @@

#define USB_VENDOR_ID_SONY 0x054c
#define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b
+#define USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE 0x0374
#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
#define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f

--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -46,7 +46,7 @@ static __u8 *sony_report_fixup(struct hi

if ((sc->quirks & VAIO_RDESC_CONSTANT) &&
*rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) {
- hid_info(hdev, "Fixing up Sony Vaio VGX report descriptor\n");
+ hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n");
rdesc[55] = 0x06;
}

@@ -218,6 +218,8 @@ static const struct hid_device_id sony_d
.driver_data = SIXAXIS_CONTROLLER_BT },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
.driver_data = VAIO_RDESC_CONSTANT },
+ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE),
+ .driver_data = VAIO_RDESC_CONSTANT },
{ }
};
MODULE_DEVICE_TABLE(hid, sony_devices);

2013-03-18 04:36:25

by Ben Hutchings

[permalink] [raw]
Subject: [ 26/82] ALSA: vmaster: Fix slave change notification

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

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

From: Takashi Iwai <[email protected]>

commit 2069d483b39a603a5f3428a19d3b4ac89aa97f48 upstream.

When a value of a vmaster slave control is changed, the ctl change
notification is sometimes ignored. This happens when the master
control overrides, e.g. when the corresponding master control is
muted. The reason is that slave_put() returns the value of the actual
slave put callback, and it doesn't reflect the virtual slave value
change.

This patch fixes the function just to return 1 whenever a slave value
is changed.

Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
sound/core/vmaster.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

--- a/sound/core/vmaster.c
+++ b/sound/core/vmaster.c
@@ -209,7 +209,10 @@ static int slave_put(struct snd_kcontrol
}
if (!changed)
return 0;
- return slave_put_val(slave, ucontrol);
+ err = slave_put_val(slave, ucontrol);
+ if (err < 0)
+ return err;
+ return 1;
}

static int slave_tlv_cmd(struct snd_kcontrol *kcontrol,

2013-03-18 04:36:52

by Ben Hutchings

[permalink] [raw]
Subject: [ 29/82] iwlwifi: always copy first 16 bytes of commands

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

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

From: Johannes Berg <[email protected]>

commit 8a964f44e01ad3bbc208c3e80d931ba91b9ea786 upstream.

The FH hardware will always write back to the scratch field
in commands, even host commands not just TX commands, which
can overwrite parts of the command. This is problematic if
the command is re-used (with IWL_HCMD_DFL_NOCOPY) and can
cause calibration issues.

Address this problem by always putting at least the first
16 bytes into the buffer we also use for the command header
and therefore make the DMA engine write back into this.

For commands that are smaller than 16 bytes also always map
enough memory for the DMA engine to write back to.

Reviewed-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Johannes Berg <[email protected]>
[bwh: Backported to 3.2:
- Adjust context
- Drop the IWL_HCMD_DFL_DUP handling
- Fix descriptor addresses and lengths for tracepoint, but otherwise
leave it unchanged]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
@@ -180,6 +180,15 @@ struct iwl_queue {
#define TFD_TX_CMD_SLOTS 256
#define TFD_CMD_SLOTS 32

+/*
+ * The FH will write back to the first TB only, so we need
+ * to copy some data into the buffer regardless of whether
+ * it should be mapped or not. This indicates how much to
+ * copy, even for HCMDs it must be big enough to fit the
+ * DRAM scratch from the TX cmd, at least 16 bytes.
+ */
+#define IWL_HCMD_MIN_COPY_SIZE 16
+
struct iwl_tx_queue {
struct iwl_queue q;
struct iwl_tfd *tfds;
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
@@ -688,11 +688,13 @@ static int iwl_enqueue_hcmd(struct iwl_t
dma_addr_t phys_addr;
unsigned long flags;
u32 idx;
- u16 copy_size, cmd_size;
+ u16 copy_size, cmd_size, dma_size;
bool is_ct_kill = false;
bool had_nocopy = false;
int i;
u8 *cmd_dest;
+ const u8 *cmddata[IWL_MAX_CMD_TFDS];
+ u16 cmdlen[IWL_MAX_CMD_TFDS];
#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
const void *trace_bufs[IWL_MAX_CMD_TFDS + 1] = {};
int trace_lens[IWL_MAX_CMD_TFDS + 1] = {};
@@ -717,15 +719,30 @@ static int iwl_enqueue_hcmd(struct iwl_t
BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1);

for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
+ cmddata[i] = cmd->data[i];
+ cmdlen[i] = cmd->len[i];
+
if (!cmd->len[i])
continue;
+
+ /* need at least IWL_HCMD_MIN_COPY_SIZE copied */
+ if (copy_size < IWL_HCMD_MIN_COPY_SIZE) {
+ int copy = IWL_HCMD_MIN_COPY_SIZE - copy_size;
+
+ if (copy > cmdlen[i])
+ copy = cmdlen[i];
+ cmdlen[i] -= copy;
+ cmddata[i] += copy;
+ copy_size += copy;
+ }
+
if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) {
had_nocopy = true;
} else {
/* NOCOPY must not be followed by normal! */
if (WARN_ON(had_nocopy))
return -EINVAL;
- copy_size += cmd->len[i];
+ copy_size += cmdlen[i];
}
cmd_size += cmd->len[i];
}
@@ -778,13 +795,30 @@ static int iwl_enqueue_hcmd(struct iwl_t
/* and copy the data that needs to be copied */

cmd_dest = out_cmd->payload;
+ copy_size = sizeof(out_cmd->hdr);
for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
- if (!cmd->len[i])
+ int copy = 0;
+
+ if (!cmd->len)
continue;
- if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)
- break;
- memcpy(cmd_dest, cmd->data[i], cmd->len[i]);
- cmd_dest += cmd->len[i];
+
+ /* need at least IWL_HCMD_MIN_COPY_SIZE copied */
+ if (copy_size < IWL_HCMD_MIN_COPY_SIZE) {
+ copy = IWL_HCMD_MIN_COPY_SIZE - copy_size;
+
+ if (copy > cmd->len[i])
+ copy = cmd->len[i];
+ }
+
+ /* copy everything if not nocopy/dup */
+ if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
+ copy = cmd->len[i];
+
+ if (copy) {
+ memcpy(cmd_dest, cmd->data[i], copy);
+ cmd_dest += copy;
+ copy_size += copy;
+ }
}

IWL_DEBUG_HC(trans, "Sending command %s (#%x), seq: 0x%04X, "
@@ -794,7 +828,14 @@ static int iwl_enqueue_hcmd(struct iwl_t
le16_to_cpu(out_cmd->hdr.sequence), cmd_size,
q->write_ptr, idx, trans->shrd->cmd_queue);

- phys_addr = dma_map_single(bus(trans)->dev, &out_cmd->hdr, copy_size,
+ /*
+ * If the entire command is smaller than IWL_HCMD_MIN_COPY_SIZE, we must
+ * still map at least that many bytes for the hardware to write back to.
+ * We have enough space, so that's not a problem.
+ */
+ dma_size = max_t(u16, copy_size, IWL_HCMD_MIN_COPY_SIZE);
+
+ phys_addr = dma_map_single(bus(trans)->dev, &out_cmd->hdr, dma_size,
DMA_BIDIRECTIONAL);
if (unlikely(dma_mapping_error(bus(trans)->dev, phys_addr))) {
idx = -ENOMEM;
@@ -802,7 +843,7 @@ static int iwl_enqueue_hcmd(struct iwl_t
}

dma_unmap_addr_set(out_meta, mapping, phys_addr);
- dma_unmap_len_set(out_meta, len, copy_size);
+ dma_unmap_len_set(out_meta, len, dma_size);

iwlagn_txq_attach_buf_to_tfd(trans, txq,
phys_addr, copy_size, 1);
@@ -812,14 +853,15 @@ static int iwl_enqueue_hcmd(struct iwl_t
trace_idx = 1;
#endif

+ /* map the remaining (adjusted) nocopy/dup fragments */
for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
- if (!cmd->len[i])
+ if (!cmdlen[i])
continue;
if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
continue;
phys_addr = dma_map_single(bus(trans)->dev,
- (void *)cmd->data[i],
- cmd->len[i], DMA_BIDIRECTIONAL);
+ (void *)cmddata[i],
+ cmdlen[i], DMA_BIDIRECTIONAL);
if (dma_mapping_error(bus(trans)->dev, phys_addr)) {
iwlagn_unmap_tfd(trans, out_meta,
&txq->tfds[q->write_ptr],
@@ -829,10 +871,10 @@ static int iwl_enqueue_hcmd(struct iwl_t
}

iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr,
- cmd->len[i], 0);
+ cmdlen[i], 0);
#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
- trace_bufs[trace_idx] = cmd->data[i];
- trace_lens[trace_idx] = cmd->len[i];
+ trace_bufs[trace_idx] = cmddata[i];
+ trace_lens[trace_idx] = cmdlen[i];
trace_idx++;
#endif
}

2013-03-18 04:31:08

by Ben Hutchings

[permalink] [raw]
Subject: [ 16/82] cifs: ensure that cifs_get_root() only traverses directories

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

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

From: Jeff Layton <[email protected]>

commit ce2ac52105aa663056dfc17966ebed1bf93e6e64 upstream.

Kjell Braden reported this oops:

[ 833.211970] BUG: unable to handle kernel NULL pointer dereference at (null)
[ 833.212816] IP: [< (null)>] (null)
[ 833.213280] PGD 1b9b2067 PUD e9f7067 PMD 0
[ 833.213874] Oops: 0010 [#1] SMP
[ 833.214344] CPU 0
[ 833.214458] Modules linked in: des_generic md4 nls_utf8 cifs vboxvideo drm snd_intel8x0 snd_ac97_codec ac97_bus snd_pcm snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq bnep rfcomm snd_timer bluetooth snd_seq_device ppdev snd vboxguest parport_pc joydev mac_hid soundcore snd_page_alloc psmouse i2c_piix4 serio_raw lp parport usbhid hid e1000
[ 833.215629]
[ 833.215629] Pid: 1752, comm: mount.cifs Not tainted 3.0.0-rc7-bisectcifs-fec11dd9a0+ #18 innotek GmbH VirtualBox/VirtualBox
[ 833.215629] RIP: 0010:[<0000000000000000>] [< (null)>] (null)
[ 833.215629] RSP: 0018:ffff8800119c9c50 EFLAGS: 00010282
[ 833.215629] RAX: ffffffffa02186c0 RBX: ffff88000c427780 RCX: 0000000000000000
[ 833.215629] RDX: 0000000000000000 RSI: ffff88000c427780 RDI: ffff88000c4362e8
[ 833.215629] RBP: ffff8800119c9c88 R08: ffff88001fc15e30 R09: 00000000d69515c7
[ 833.215629] R10: ffffffffa0201972 R11: ffff88000e8f6a28 R12: ffff88000c4362e8
[ 833.215629] R13: 0000000000000000 R14: 0000000000000000 R15: ffff88001181aaa6
[ 833.215629] FS: 00007f2986171700(0000) GS:ffff88001fc00000(0000) knlGS:0000000000000000
[ 833.215629] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[ 833.215629] CR2: 0000000000000000 CR3: 000000001b982000 CR4: 00000000000006f0
[ 833.215629] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 833.215629] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[ 833.215629] Process mount.cifs (pid: 1752, threadinfo ffff8800119c8000, task ffff88001c1c16f0)
[ 833.215629] Stack:
[ 833.215629] ffffffff8116a9b5 ffff8800119c9c88 ffffffff81178075 0000000000000286
[ 833.215629] 0000000000000000 ffff88000c4276c0 ffff8800119c9ce8 ffff8800119c9cc8
[ 833.215629] ffffffff8116b06e ffff88001bc6fc00 ffff88000c4276c0 ffff88000c4276c0
[ 833.215629] Call Trace:
[ 833.215629] [<ffffffff8116a9b5>] ? d_alloc_and_lookup+0x45/0x90
[ 833.215629] [<ffffffff81178075>] ? d_lookup+0x35/0x60
[ 833.215629] [<ffffffff8116b06e>] __lookup_hash.part.14+0x9e/0xc0
[ 833.215629] [<ffffffff8116b1d6>] lookup_one_len+0x146/0x1e0
[ 833.215629] [<ffffffff815e4f7e>] ? _raw_spin_lock+0xe/0x20
[ 833.215629] [<ffffffffa01eef0d>] cifs_do_mount+0x26d/0x500 [cifs]
[ 833.215629] [<ffffffff81163bd3>] mount_fs+0x43/0x1b0
[ 833.215629] [<ffffffff8117d41a>] vfs_kern_mount+0x6a/0xd0
[ 833.215629] [<ffffffff8117e584>] do_kern_mount+0x54/0x110
[ 833.215629] [<ffffffff8117fdc2>] do_mount+0x262/0x840
[ 833.215629] [<ffffffff81108a0e>] ? __get_free_pages+0xe/0x50
[ 833.215629] [<ffffffff8117f9ca>] ? copy_mount_options+0x3a/0x180
[ 833.215629] [<ffffffff8118075d>] sys_mount+0x8d/0xe0
[ 833.215629] [<ffffffff815ece82>] system_call_fastpath+0x16/0x1b
[ 833.215629] Code: Bad RIP value.
[ 833.215629] RIP [< (null)>] (null)
[ 833.215629] RSP <ffff8800119c9c50>
[ 833.215629] CR2: 0000000000000000
[ 833.238525] ---[ end trace ec00758b8d44f529 ]---

When walking down the path on the server, it's possible to hit a
symlink. The path walking code assumes that the caller will handle that
situation properly, but cifs_get_root() isn't set up for it. This patch
prevents the oops by simply returning an error.

A better solution would be to try and chase the symlinks here, but that's
fairly complicated to handle.

Fixes:

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

Reported-and-tested-by: Kjell Braden <[email protected]>
Signed-off-by: Jeff Layton <[email protected]>
Signed-off-by: Steve French <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/cifs/cifsfs.c | 5 +++++
1 file changed, 5 insertions(+)

--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -561,6 +561,11 @@ cifs_get_root(struct smb_vol *vol, struc
dentry = ERR_PTR(-ENOENT);
break;
}
+ if (!S_ISDIR(dir->i_mode)) {
+ dput(dentry);
+ dentry = ERR_PTR(-ENOTDIR);
+ break;
+ }

/* skip separators */
while (*s == sep)

2013-03-18 04:37:13

by Ben Hutchings

[permalink] [raw]
Subject: [ 39/82] efivars: Disable external interrupt while holding efivars->lock

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

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

From: Josh Boyer <[email protected]>

commit 81fa4e581d9283f7992a0d8c534bb141eb840a14 upstream.

[Problem]
There is a scenario which efi_pstore fails to log messages in a panic case.

- CPUA holds an efi_var->lock in either efivarfs parts
or efi_pstore with interrupt enabled.
- CPUB panics and sends IPI to CPUA in smp_send_stop().
- CPUA stops with holding the lock.
- CPUB kicks efi_pstore_write() via kmsg_dump(KSMG_DUMP_PANIC)
but it returns without logging messages.

[Patch Description]
This patch disables an external interruption while holding efivars->lock
as follows.

In efi_pstore_write() and get_var_data(), spin_lock/spin_unlock is
replaced by spin_lock_irqsave/spin_unlock_irqrestore because they may
be called in an interrupt context.

In other functions, they are replaced by spin_lock_irq/spin_unlock_irq.
because they are all called from a process context.

By applying this patch, we can avoid the problem above with
a following senario.

- CPUA holds an efi_var->lock with interrupt disabled.
- CPUB panics and sends IPI to CPUA in smp_send_stop().
- CPUA receives the IPI after releasing the lock because it is
disabling interrupt while holding the lock.
- CPUB waits for one sec until CPUA releases the lock.
- CPUB kicks efi_pstore_write() via kmsg_dump(KSMG_DUMP_PANIC)
And it can hold the lock successfully.

Signed-off-by: Seiji Aguchi <[email protected]>
Acked-by: Mike Waychison <[email protected]>
Acked-by: Matt Fleming <[email protected]>
Signed-off-by: Tony Luck <[email protected]>
[bwh: Backported to 3.2:
- Drop efivarfs changes
- Adjust context
- Drop change to efi_pstore_erase(), which is implemented using
efi_pstore_write() here]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/firmware/efivars.c | 84 ++++++++++++++++++++++++----------------------
1 file changed, 43 insertions(+), 41 deletions(-)

--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -393,10 +393,11 @@ static efi_status_t
get_var_data(struct efivars *efivars, struct efi_variable *var)
{
efi_status_t status;
+ unsigned long flags;

- spin_lock(&efivars->lock);
+ spin_lock_irqsave(&efivars->lock, flags);
status = get_var_data_locked(efivars, var);
- spin_unlock(&efivars->lock);
+ spin_unlock_irqrestore(&efivars->lock, flags);

if (status != EFI_SUCCESS) {
printk(KERN_WARNING "efivars: get_variable() failed 0x%lx!\n",
@@ -525,14 +526,14 @@ efivar_store_raw(struct efivar_entry *en
return -EINVAL;
}

- spin_lock(&efivars->lock);
+ spin_lock_irq(&efivars->lock);
status = efivars->ops->set_variable(new_var->VariableName,
&new_var->VendorGuid,
new_var->Attributes,
new_var->DataSize,
new_var->Data);

- spin_unlock(&efivars->lock);
+ spin_unlock_irq(&efivars->lock);

if (status != EFI_SUCCESS) {
printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
@@ -643,7 +644,7 @@ static int efi_pstore_open(struct pstore
{
struct efivars *efivars = psi->data;

- spin_lock(&efivars->lock);
+ spin_lock_irq(&efivars->lock);
efivars->walk_entry = list_first_entry(&efivars->list,
struct efivar_entry, list);
return 0;
@@ -653,7 +654,7 @@ static int efi_pstore_close(struct pstor
{
struct efivars *efivars = psi->data;

- spin_unlock(&efivars->lock);
+ spin_unlock_irq(&efivars->lock);
return 0;
}

@@ -708,11 +709,12 @@ static int efi_pstore_write(enum pstore_
int i, ret = 0;
u64 storage_space, remaining_space, max_variable_size;
efi_status_t status = EFI_NOT_FOUND;
+ unsigned long flags;

sprintf(stub_name, "dump-type%u-%u-", type, part);
sprintf(name, "%s%lu", stub_name, get_seconds());

- spin_lock(&efivars->lock);
+ spin_lock_irqsave(&efivars->lock, flags);

/*
* Check if there is a space enough to log.
@@ -724,7 +726,7 @@ static int efi_pstore_write(enum pstore_
&remaining_space,
&max_variable_size);
if (status || remaining_space < size + DUMP_NAME_LEN * 2) {
- spin_unlock(&efivars->lock);
+ spin_unlock_irqrestore(&efivars->lock, flags);
*id = part;
return -ENOSPC;
}
@@ -765,7 +767,7 @@ static int efi_pstore_write(enum pstore_
efivars->ops->set_variable(efi_name, &vendor, PSTORE_EFI_ATTRIBUTES,
size, psi->buf);

- spin_unlock(&efivars->lock);
+ spin_unlock_irqrestore(&efivars->lock, flags);

if (found)
efivar_unregister(found);
@@ -848,7 +850,7 @@ static ssize_t efivar_create(struct file
return -EINVAL;
}

- spin_lock(&efivars->lock);
+ spin_lock_irq(&efivars->lock);

/*
* Does this variable already exist?
@@ -866,7 +868,7 @@ static ssize_t efivar_create(struct file
}
}
if (found) {
- spin_unlock(&efivars->lock);
+ spin_unlock_irq(&efivars->lock);
return -EINVAL;
}

@@ -880,10 +882,10 @@ static ssize_t efivar_create(struct file
if (status != EFI_SUCCESS) {
printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
status);
- spin_unlock(&efivars->lock);
+ spin_unlock_irq(&efivars->lock);
return -EIO;
}
- spin_unlock(&efivars->lock);
+ spin_unlock_irq(&efivars->lock);

/* Create the entry in sysfs. Locking is not required here */
status = efivar_create_sysfs_entry(efivars,
@@ -911,7 +913,7 @@ static ssize_t efivar_delete(struct file
if (!capable(CAP_SYS_ADMIN))
return -EACCES;

- spin_lock(&efivars->lock);
+ spin_lock_irq(&efivars->lock);

/*
* Does this variable already exist?
@@ -929,7 +931,7 @@ static ssize_t efivar_delete(struct file
}
}
if (!found) {
- spin_unlock(&efivars->lock);
+ spin_unlock_irq(&efivars->lock);
return -EINVAL;
}
/* force the Attributes/DataSize to 0 to ensure deletion */
@@ -945,12 +947,12 @@ static ssize_t efivar_delete(struct file
if (status != EFI_SUCCESS) {
printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
status);
- spin_unlock(&efivars->lock);
+ spin_unlock_irq(&efivars->lock);
return -EIO;
}
list_del(&search_efivar->list);
/* We need to release this lock before unregistering. */
- spin_unlock(&efivars->lock);
+ spin_unlock_irq(&efivars->lock);
efivar_unregister(search_efivar);

/* It's dead Jim.... */
@@ -1058,9 +1060,9 @@ efivar_create_sysfs_entry(struct efivars
kfree(short_name);
short_name = NULL;

- spin_lock(&efivars->lock);
+ spin_lock_irq(&efivars->lock);
list_add(&new_efivar->list, &efivars->list);
- spin_unlock(&efivars->lock);
+ spin_unlock_irq(&efivars->lock);

return 0;
}
@@ -1129,9 +1131,9 @@ void unregister_efivars(struct efivars *
struct efivar_entry *entry, *n;

list_for_each_entry_safe(entry, n, &efivars->list, list) {
- spin_lock(&efivars->lock);
+ spin_lock_irq(&efivars->lock);
list_del(&entry->list);
- spin_unlock(&efivars->lock);
+ spin_unlock_irq(&efivars->lock);
efivar_unregister(entry);
}
if (efivars->new_var)

2013-03-18 04:37:17

by Ben Hutchings

[permalink] [raw]
Subject: [ 32/82] ahci: AHCI-mode SATA patch for Intel Lynx Point DeviceIDs

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

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

From: Seth Heasley <[email protected]>

commit ea4ace66782fc35245133d2766f38d62827761cc upstream.

This patch adds the AHCI-mode SATA DeviceIDs for the Intel Lynx Point PCH.

Signed-off-by: Seth Heasley <[email protected]>
Signed-off-by: Jeff Garzik <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/ata/ahci.c | 8 ++++++++
1 file changed, 8 insertions(+)

--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -262,6 +262,14 @@ static const struct pci_device_id ahci_p
{ PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */
{ PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point RAID */
{ PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */
+ { PCI_VDEVICE(INTEL, 0x8c02), board_ahci }, /* Lynx Point AHCI */
+ { PCI_VDEVICE(INTEL, 0x8c03), board_ahci }, /* Lynx Point AHCI */
+ { PCI_VDEVICE(INTEL, 0x8c04), board_ahci }, /* Lynx Point RAID */
+ { PCI_VDEVICE(INTEL, 0x8c05), board_ahci }, /* Lynx Point RAID */
+ { PCI_VDEVICE(INTEL, 0x8c06), board_ahci }, /* Lynx Point RAID */
+ { PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */
+ { PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */
+ { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point RAID */

/* JMicron 360/1/3/5/6, match class to avoid IDE function */
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,

2013-03-18 04:37:10

by Ben Hutchings

[permalink] [raw]
Subject: [ 28/82] dmi_scan: fix missing check for _DMI_ signature in smbios_present()

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

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

From: Ben Hutchings <[email protected]>

commit a40e7cf8f06b4e322ba902e4e9f6a6b0c2daa907 upstream.

Commit 9f9c9cbb6057 ("drivers/firmware/dmi_scan.c: fetch dmi version
from SMBIOS if it exists") hoisted the check for "_DMI_" into
dmi_scan_machine(), which means that we don't bother to check for
"_DMI_" at offset 16 in an SMBIOS entry. smbios_present() may also call
dmi_present() for an address where we found "_SM_", if it failed further
validation.

Check for "_DMI_" in smbios_present() before calling dmi_present().

[[email protected]: fix build]
Signed-off-by: Ben Hutchings <[email protected]>
Reported-by: Tim McGrath <[email protected]>
Tested-by: Tim Mcgrath <[email protected]>
Cc: Zhenzhong Duan <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
---
drivers/firmware/dmi_scan.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -442,7 +442,6 @@ static int __init dmi_present(const char
static int __init smbios_present(const char __iomem *p)
{
u8 buf[32];
- int offset = 0;

memcpy_fromio(buf, p, 32);
if ((buf[5] < 32) && dmi_checksum(buf, buf[5])) {
@@ -461,9 +460,9 @@ static int __init smbios_present(const c
dmi_ver = 0x0206;
break;
}
- offset = 16;
+ return memcmp(p + 16, "_DMI_", 5) || dmi_present(p + 16);
}
- return dmi_present(buf + offset);
+ return 1;
}

void __init dmi_scan_machine(void)

2013-03-18 04:37:06

by Ben Hutchings

[permalink] [raw]
Subject: [ 25/82] hw_random: make buffer usable in scatterlist.

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

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

From: Rusty Russell <[email protected]>

commit f7f154f1246ccc5a0a7e9ce50932627d60a0c878 upstream.

virtio_rng feeds the randomness buffer handed by the core directly
into the scatterlist, since commit bb347d98079a547e80bd4722dee1de61e4dca0e8.

However, if CONFIG_HW_RANDOM=m, the static buffer isn't a linear address
(at least on most archs). We could fix this in virtio_rng, but it's actually
far easier to just do it in the core as virtio_rng would have to allocate
a buffer every time (it doesn't know how much the core will want to read).

Reported-by: Aurelien Jarno <[email protected]>
Tested-by: Aurelien Jarno <[email protected]>
Signed-off-by: Rusty Russell <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/char/hw_random/core.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)

--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -40,6 +40,7 @@
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>


@@ -52,8 +53,12 @@ static struct hwrng *current_rng;
static LIST_HEAD(rng_list);
static DEFINE_MUTEX(rng_mutex);
static int data_avail;
-static u8 rng_buffer[SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES]
- __cacheline_aligned;
+static u8 *rng_buffer;
+
+static size_t rng_buffer_size(void)
+{
+ return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES;
+}

static inline int hwrng_init(struct hwrng *rng)
{
@@ -116,7 +121,7 @@ static ssize_t rng_dev_read(struct file

if (!data_avail) {
bytes_read = rng_get_data(current_rng, rng_buffer,
- sizeof(rng_buffer),
+ rng_buffer_size(),
!(filp->f_flags & O_NONBLOCK));
if (bytes_read < 0) {
err = bytes_read;
@@ -307,6 +312,14 @@ int hwrng_register(struct hwrng *rng)

mutex_lock(&rng_mutex);

+ /* kmalloc makes this safe for virt_to_page() in virtio_rng.c */
+ err = -ENOMEM;
+ if (!rng_buffer) {
+ rng_buffer = kmalloc(rng_buffer_size(), GFP_KERNEL);
+ if (!rng_buffer)
+ goto out_unlock;
+ }
+
/* Must not register two RNGs with the same name. */
err = -EEXIST;
list_for_each_entry(tmp, &rng_list, list) {

2013-03-18 04:38:14

by Ben Hutchings

[permalink] [raw]
Subject: [ 27/82] drm/radeon: add primary dac adj quirk for R200 board

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

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

From: Alex Deucher <[email protected]>

commit e8fc41377f5037ff7a661ea06adc05f1daec1548 upstream.

vbios values are wrong leading to colors that are
too bright. Use the default values instead.

Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/radeon/radeon_combios.c | 9 +++++++++
1 file changed, 9 insertions(+)

--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -958,6 +958,15 @@ struct radeon_encoder_primary_dac *radeo
found = 1;
}

+ /* quirks */
+ /* Radeon 9100 (R200) */
+ if ((dev->pdev->device == 0x514D) &&
+ (dev->pdev->subsystem_vendor == 0x174B) &&
+ (dev->pdev->subsystem_device == 0x7149)) {
+ /* vbios value is bad, use the default */
+ found = 0;
+ }
+
if (!found) /* fallback to defaults */
radeon_legacy_get_primary_dac_info_from_table(rdev, p_dac);


2013-03-18 04:38:13

by Ben Hutchings

[permalink] [raw]
Subject: [ 31/82] HID: clean up quirk for Sony RF receivers

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

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

From: Fernando Luis Vázquez Cao <[email protected]>

commit 99d249021abd4341771523ed8dd7946276103432 upstream.

Document what the fix-up is does and make it more robust by ensuring
that it is only applied to the USB interface that corresponds to the
mouse (sony_report_fixup() is called once per interface during probing).

Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Fernando Luis Vazquez Cao <[email protected]>
Signed-off-by: Jiri Kosina <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/hid/hid-sony.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)

--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -44,9 +44,19 @@ static __u8 *sony_report_fixup(struct hi
{
struct sony_sc *sc = hid_get_drvdata(hdev);

- if ((sc->quirks & VAIO_RDESC_CONSTANT) &&
- *rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) {
+ /*
+ * Some Sony RF receivers wrongly declare the mouse pointer as a
+ * a constant non-data variable.
+ */
+ if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 &&
+ /* usage page: generic desktop controls */
+ /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */
+ /* usage: mouse */
+ rdesc[2] == 0x09 && rdesc[3] == 0x02 &&
+ /* input (usage page for x,y axes): constant, variable, relative */
+ rdesc[54] == 0x81 && rdesc[55] == 0x07) {
hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n");
+ /* input: data, variable, relative */
rdesc[55] = 0x06;
}


2013-03-18 04:31:04

by Ben Hutchings

[permalink] [raw]
Subject: [ 12/82] proc connector: reject unprivileged listener bumps

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

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

From: Kees Cook <[email protected]>

commit e70ab977991964a5a7ad1182799451d067e62669 upstream.

While PROC_CN_MCAST_LISTEN/IGNORE is entirely advisory, it was possible
for an unprivileged user to turn off notifications for all listeners by
sending PROC_CN_MCAST_IGNORE. Instead, require the same privileges as
required for a multicast bind.

Signed-off-by: Kees Cook <[email protected]>
Cc: Evgeniy Polyakov <[email protected]>
Cc: Matt Helsley <[email protected]>
Acked-by: Evgeniy Polyakov <[email protected]>
Acked-by: Matt Helsley <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/connector/cn_proc.c | 8 ++++++++
1 file changed, 8 insertions(+)

--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -303,6 +303,12 @@ static void cn_proc_mcast_ctl(struct cn_
if (msg->len != sizeof(*mc_op))
return;

+ /* Can only change if privileged. */
+ if (!capable(CAP_NET_ADMIN)) {
+ err = EPERM;
+ goto out;
+ }
+
mc_op = (enum proc_cn_mcast_op*)msg->data;
switch (*mc_op) {
case PROC_CN_MCAST_LISTEN:
@@ -315,6 +321,8 @@ static void cn_proc_mcast_ctl(struct cn_
err = EINVAL;
break;
}
+
+out:
cn_proc_ack(err, msg->seq, msg->ack);
}


2013-03-18 04:38:59

by Ben Hutchings

[permalink] [raw]
Subject: [ 33/82] ahci: Add Device IDs for Intel Lynx Point-LP PCH

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

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

From: James Ralston <[email protected]>

commit 77b12bc9cf7b10c7c1a04ca45272fbb4287902d0 upstream.

This patch adds the AHCI-mode SATA Device IDs for the Intel Lynx Point-LP PCH

Signed-off-by: James Ralston <[email protected]>
Signed-off-by: Jeff Garzik <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/ata/ahci.c | 8 ++++++++
1 file changed, 8 insertions(+)

--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -270,6 +270,14 @@ static const struct pci_device_id ahci_p
{ PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */
{ PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */
{ PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point RAID */
+ { PCI_VDEVICE(INTEL, 0x9c02), board_ahci }, /* Lynx Point-LP AHCI */
+ { PCI_VDEVICE(INTEL, 0x9c03), board_ahci }, /* Lynx Point-LP AHCI */
+ { PCI_VDEVICE(INTEL, 0x9c04), board_ahci }, /* Lynx Point-LP RAID */
+ { PCI_VDEVICE(INTEL, 0x9c05), board_ahci }, /* Lynx Point-LP RAID */
+ { PCI_VDEVICE(INTEL, 0x9c06), board_ahci }, /* Lynx Point-LP RAID */
+ { PCI_VDEVICE(INTEL, 0x9c07), board_ahci }, /* Lynx Point-LP RAID */
+ { PCI_VDEVICE(INTEL, 0x9c0e), board_ahci }, /* Lynx Point-LP RAID */
+ { PCI_VDEVICE(INTEL, 0x9c0f), board_ahci }, /* Lynx Point-LP RAID */

/* JMicron 360/1/3/5/6, match class to avoid IDE function */
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,

2013-03-18 04:38:56

by Ben Hutchings

[permalink] [raw]
Subject: [ 38/82] efi_pstore: Check remaining space with QueryVariableInfo() before writing data

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

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

From: Seiji Aguchi <[email protected]>

commit d80a361d779a9f19498943d1ca84243209cd5647 upstream.

[Issue]

As discussed in a thread below, Running out of space in EFI isn't a well-tested scenario.
And we wouldn't expect all firmware to handle it gracefully.
http://marc.info/?l=linux-kernel&m=134305325801789&w=2

On the other hand, current efi_pstore doesn't check a remaining space of storage at writing time.
Therefore, efi_pstore may not work if it tries to write a large amount of data.

[Patch Description]

To avoid handling the situation above, this patch checks if there is a space enough to log with
QueryVariableInfo() before writing data.

Signed-off-by: Seiji Aguchi <[email protected]>
Acked-by: Mike Waychison <[email protected]>
Signed-off-by: Tony Luck <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/firmware/efivars.c | 18 ++++++++++++++++++
include/linux/efi.h | 1 +
2 files changed, 19 insertions(+)

--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -706,12 +706,29 @@ static int efi_pstore_write(enum pstore_
struct efivars *efivars = psi->data;
struct efivar_entry *entry, *found = NULL;
int i, ret = 0;
+ u64 storage_space, remaining_space, max_variable_size;
+ efi_status_t status = EFI_NOT_FOUND;

sprintf(stub_name, "dump-type%u-%u-", type, part);
sprintf(name, "%s%lu", stub_name, get_seconds());

spin_lock(&efivars->lock);

+ /*
+ * Check if there is a space enough to log.
+ * size: a size of logging data
+ * DUMP_NAME_LEN * 2: a maximum size of variable name
+ */
+ status = efivars->ops->query_variable_info(PSTORE_EFI_ATTRIBUTES,
+ &storage_space,
+ &remaining_space,
+ &max_variable_size);
+ if (status || remaining_space < size + DUMP_NAME_LEN * 2) {
+ spin_unlock(&efivars->lock);
+ *id = part;
+ return -ENOSPC;
+ }
+
for (i = 0; i < DUMP_NAME_LEN; i++)
efi_name[i] = stub_name[i];

@@ -1235,6 +1252,7 @@ efivars_init(void)
ops.get_variable = efi.get_variable;
ops.set_variable = efi.set_variable;
ops.get_next_variable = efi.get_next_variable;
+ ops.query_variable_info = efi.query_variable_info;
error = register_efivars(&__efivars, &ops, efi_kobj);
if (error)
goto err_put;
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -470,6 +470,7 @@ struct efivar_operations {
efi_get_variable_t *get_variable;
efi_get_next_variable_t *get_next_variable;
efi_set_variable_t *set_variable;
+ efi_query_variable_info_t *query_variable_info;
};

struct efivars {

2013-03-18 04:38:53

by Ben Hutchings

[permalink] [raw]
Subject: [ 35/82] ahci: Add Device IDs for Intel Wellsburg PCH

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

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

From: James Ralston <[email protected]>

commit 151743fd8dfb02956c5184b5f4f0f42677eb75bc upstream.

This patch adds the AHCI-mode SATA Device IDs for the Intel Wellsburg PCH

Signed-off-by: James Ralston <[email protected]>
Signed-off-by: Jeff Garzik <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/ata/ahci.c | 8 ++++++++
1 file changed, 8 insertions(+)

--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -294,6 +294,14 @@ static const struct pci_device_id ahci_p
{ PCI_VDEVICE(INTEL, 0x1f37), board_ahci }, /* Avoton RAID */
{ PCI_VDEVICE(INTEL, 0x1f3e), board_ahci }, /* Avoton RAID */
{ PCI_VDEVICE(INTEL, 0x1f3f), board_ahci }, /* Avoton RAID */
+ { PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */
+ { PCI_VDEVICE(INTEL, 0x8d04), board_ahci }, /* Wellsburg RAID */
+ { PCI_VDEVICE(INTEL, 0x8d06), board_ahci }, /* Wellsburg RAID */
+ { PCI_VDEVICE(INTEL, 0x8d0e), board_ahci }, /* Wellsburg RAID */
+ { PCI_VDEVICE(INTEL, 0x8d62), board_ahci }, /* Wellsburg AHCI */
+ { PCI_VDEVICE(INTEL, 0x8d64), board_ahci }, /* Wellsburg RAID */
+ { PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */
+ { PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */

/* JMicron 360/1/3/5/6, match class to avoid IDE function */
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,

2013-03-18 04:38:49

by Ben Hutchings

[permalink] [raw]
Subject: [ 36/82] iommu/amd: Initialize device table after dma_ops

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

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

From: Shuah Khan <[email protected]>

commit f528d980c17b8714aedc918ba86e058af914d66b upstream.

When dma_ops are initialized the unity mappings are created. The
init_device_table_dma() function makes sure DMA from all devices is
blocked by default. This opens a short window in time where DMA to
unity mapped regions is blocked by the IOMMU. Make sure this does not
happen by initializing the device table after dma_ops.

Tested on 3.2.38

Signed-off-by: Joerg Roedel <[email protected]>
Signed-off-by: Shuah Khan <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/iommu/amd_iommu_init.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)

--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -1396,6 +1396,7 @@ static struct syscore_ops amd_iommu_sysc
*/
static int __init amd_iommu_init(void)
{
+ struct amd_iommu *iommu;
int i, ret = 0;

/*
@@ -1444,9 +1445,6 @@ static int __init amd_iommu_init(void)
if (amd_iommu_pd_alloc_bitmap == NULL)
goto free;

- /* init the device table */
- init_device_table();
-
/*
* let all alias entries point to itself
*/
@@ -1496,6 +1494,12 @@ static int __init amd_iommu_init(void)
if (ret)
goto free_disable;

+ /* init the device table */
+ init_device_table();
+
+ for_each_iommu(iommu)
+ iommu_flush_all_caches(iommu);
+
amd_iommu_init_api();

amd_iommu_init_notifier();

2013-03-18 04:38:46

by Ben Hutchings

[permalink] [raw]
Subject: [ 34/82] ahci: AHCI-mode SATA patch for Intel Avoton DeviceIDs

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

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

From: Seth Heasley <[email protected]>

commit 29e674dd5c8e781589f09c3ee139c80f6da274e4 upstream.

This patch adds the AHCI and RAID-mode SATA DeviceIDs for the Intel Avoton SOC.

Signed-off-by: Seth Heasley <[email protected]>
Signed-off-by: Jeff Garzik <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/ata/ahci.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)

--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -278,6 +278,22 @@ static const struct pci_device_id ahci_p
{ PCI_VDEVICE(INTEL, 0x9c07), board_ahci }, /* Lynx Point-LP RAID */
{ PCI_VDEVICE(INTEL, 0x9c0e), board_ahci }, /* Lynx Point-LP RAID */
{ PCI_VDEVICE(INTEL, 0x9c0f), board_ahci }, /* Lynx Point-LP RAID */
+ { PCI_VDEVICE(INTEL, 0x1f22), board_ahci }, /* Avoton AHCI */
+ { PCI_VDEVICE(INTEL, 0x1f23), board_ahci }, /* Avoton AHCI */
+ { PCI_VDEVICE(INTEL, 0x1f24), board_ahci }, /* Avoton RAID */
+ { PCI_VDEVICE(INTEL, 0x1f25), board_ahci }, /* Avoton RAID */
+ { PCI_VDEVICE(INTEL, 0x1f26), board_ahci }, /* Avoton RAID */
+ { PCI_VDEVICE(INTEL, 0x1f27), board_ahci }, /* Avoton RAID */
+ { PCI_VDEVICE(INTEL, 0x1f2e), board_ahci }, /* Avoton RAID */
+ { PCI_VDEVICE(INTEL, 0x1f2f), board_ahci }, /* Avoton RAID */
+ { PCI_VDEVICE(INTEL, 0x1f32), board_ahci }, /* Avoton AHCI */
+ { PCI_VDEVICE(INTEL, 0x1f33), board_ahci }, /* Avoton AHCI */
+ { PCI_VDEVICE(INTEL, 0x1f34), board_ahci }, /* Avoton RAID */
+ { PCI_VDEVICE(INTEL, 0x1f35), board_ahci }, /* Avoton RAID */
+ { PCI_VDEVICE(INTEL, 0x1f36), board_ahci }, /* Avoton RAID */
+ { PCI_VDEVICE(INTEL, 0x1f37), board_ahci }, /* Avoton RAID */
+ { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci }, /* Avoton RAID */
+ { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci }, /* Avoton RAID */

/* JMicron 360/1/3/5/6, match class to avoid IDE function */
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,

2013-03-18 04:31:00

by Ben Hutchings

[permalink] [raw]
Subject: [ 11/82] md: raid0: fix error return from create_stripe_zones.

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

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

From: NeilBrown <[email protected]>

commit 58ebb34c49fcfcaa029e4b1c1453d92583900f9a upstream.

Create_stripe_zones returns an error slightly differently to
raid0_run and to raid0_takeover_*.

The error returned used by the second was wrong and an error would
result in mddev->private being set to NULL and sooner or later a
crash.

So never return NULL, return ERR_PTR(err), not NULL from
create_stripe_zones.

This bug has been present since 2.6.35 so the fix is suitable
for any kernel since then.

Signed-off-by: NeilBrown <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/md/raid0.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -286,7 +286,7 @@ abort:
kfree(conf->strip_zone);
kfree(conf->devlist);
kfree(conf);
- *private_conf = NULL;
+ *private_conf = ERR_PTR(err);
return err;
}


2013-03-18 04:40:14

by Ben Hutchings

[permalink] [raw]
Subject: [ 40/82] efi: be more paranoid about available space when creating variables

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

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

From: Josh Boyer <[email protected]>

commit 68d929862e29a8b52a7f2f2f86a0600423b093cd upstream.

UEFI variables are typically stored in flash. For various reasons, avaiable
space is typically not reclaimed immediately upon the deletion of a
variable - instead, the system will garbage collect during initialisation
after a reboot.

Some systems appear to handle this garbage collection extremely poorly,
failing if more than 50% of the system flash is in use. This can result in
the machine refusing to boot. The safest thing to do for the moment is to
forbid writes if they'd end up using more than half of the storage space.
We can make this more finegrained later if we come up with a method for
identifying the broken machines.

Signed-off-by: Matthew Garrett <[email protected]>
Signed-off-by: Matt Fleming <[email protected]>
[bwh: Backported to 3.2:
- Drop efivarfs changes and unused check_var_size()
- Add error codes to include/linux/efi.h, added upstream by
commit 5d9db883761a ('efi: Add support for a UEFI variable filesystem')
- Add efi_status_to_err(), added upstream by commit 7253eaba7b17
('efivarfs: Return an error if we fail to read a variable')]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/firmware/efivars.c | 106 +++++++++++++++++++++++++++++++++------------
1 file changed, 79 insertions(+), 27 deletions(-)

--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -406,6 +406,30 @@ get_var_data(struct efivars *efivars, st
return status;
}

+static efi_status_t
+check_var_size_locked(struct efivars *efivars, u32 attributes,
+ unsigned long size)
+{
+ u64 storage_size, remaining_size, max_size;
+ efi_status_t status;
+ const struct efivar_operations *fops = efivars->ops;
+
+ if (!efivars->ops->query_variable_info)
+ return EFI_UNSUPPORTED;
+
+ status = fops->query_variable_info(attributes, &storage_size,
+ &remaining_size, &max_size);
+
+ if (status != EFI_SUCCESS)
+ return status;
+
+ if (!storage_size || size > remaining_size || size > max_size ||
+ (remaining_size - size) < (storage_size / 2))
+ return EFI_OUT_OF_RESOURCES;
+
+ return status;
+}
+
static ssize_t
efivar_guid_read(struct efivar_entry *entry, char *buf)
{
@@ -527,11 +551,16 @@ efivar_store_raw(struct efivar_entry *en
}

spin_lock_irq(&efivars->lock);
- status = efivars->ops->set_variable(new_var->VariableName,
- &new_var->VendorGuid,
- new_var->Attributes,
- new_var->DataSize,
- new_var->Data);
+
+ status = check_var_size_locked(efivars, new_var->Attributes,
+ new_var->DataSize + utf16_strsize(new_var->VariableName, 1024));
+
+ if (status == EFI_SUCCESS || status == EFI_UNSUPPORTED)
+ status = efivars->ops->set_variable(new_var->VariableName,
+ &new_var->VendorGuid,
+ new_var->Attributes,
+ new_var->DataSize,
+ new_var->Data);

spin_unlock_irq(&efivars->lock);

@@ -638,6 +667,36 @@ efivar_unregister(struct efivar_entry *v
kobject_put(&var->kobj);
}

+static int efi_status_to_err(efi_status_t status)
+{
+ int err;
+
+ switch (status) {
+ case EFI_INVALID_PARAMETER:
+ err = -EINVAL;
+ break;
+ case EFI_OUT_OF_RESOURCES:
+ err = -ENOSPC;
+ break;
+ case EFI_DEVICE_ERROR:
+ err = -EIO;
+ break;
+ case EFI_WRITE_PROTECTED:
+ err = -EROFS;
+ break;
+ case EFI_SECURITY_VIOLATION:
+ err = -EACCES;
+ break;
+ case EFI_NOT_FOUND:
+ err = -ENOENT;
+ break;
+ default:
+ err = -EINVAL;
+ }
+
+ return err;
+}
+
#ifdef CONFIG_PSTORE

static int efi_pstore_open(struct pstore_info *psi)
@@ -707,7 +766,6 @@ static int efi_pstore_write(enum pstore_
struct efivars *efivars = psi->data;
struct efivar_entry *entry, *found = NULL;
int i, ret = 0;
- u64 storage_space, remaining_space, max_variable_size;
efi_status_t status = EFI_NOT_FOUND;
unsigned long flags;

@@ -721,11 +779,11 @@ static int efi_pstore_write(enum pstore_
* size: a size of logging data
* DUMP_NAME_LEN * 2: a maximum size of variable name
*/
- status = efivars->ops->query_variable_info(PSTORE_EFI_ATTRIBUTES,
- &storage_space,
- &remaining_space,
- &max_variable_size);
- if (status || remaining_space < size + DUMP_NAME_LEN * 2) {
+
+ status = check_var_size_locked(efivars, PSTORE_EFI_ATTRIBUTES,
+ size + DUMP_NAME_LEN * 2);
+
+ if (status) {
spin_unlock_irqrestore(&efivars->lock, flags);
*id = part;
return -ENOSPC;
@@ -872,6 +930,14 @@ static ssize_t efivar_create(struct file
return -EINVAL;
}

+ status = check_var_size_locked(efivars, new_var->Attributes,
+ new_var->DataSize + utf16_strsize(new_var->VariableName, 1024));
+
+ if (status && status != EFI_UNSUPPORTED) {
+ spin_unlock_irq(&efivars->lock);
+ return efi_status_to_err(status);
+ }
+
/* now *really* create the variable via EFI */
status = efivars->ops->set_variable(new_var->VariableName,
&new_var->VendorGuid,
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -30,7 +30,12 @@
#define EFI_UNSUPPORTED ( 3 | (1UL << (BITS_PER_LONG-1)))
#define EFI_BAD_BUFFER_SIZE ( 4 | (1UL << (BITS_PER_LONG-1)))
#define EFI_BUFFER_TOO_SMALL ( 5 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_NOT_READY ( 6 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_DEVICE_ERROR ( 7 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_WRITE_PROTECTED ( 8 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_OUT_OF_RESOURCES ( 9 | (1UL << (BITS_PER_LONG-1)))
#define EFI_NOT_FOUND (14 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_SECURITY_VIOLATION (26 | (1UL << (BITS_PER_LONG-1)))

typedef unsigned long efi_status_t;
typedef u8 efi_bool_t;

2013-03-18 04:30:57

by Ben Hutchings

[permalink] [raw]
Subject: [ 03/82] md: protect against crash upon fsync on ro array

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

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

From: Sebastian Riemer <[email protected]>

commit bbfa57c0f2243a7c31fd248d22e9861a2802cad5 upstream.

If an fsync occurs on a read-only array, we need to send a
completion for the IO and may not increment the active IO count.
Otherwise, we hit a bug trace and can't stop the MD array anymore.

By advice of Christoph Hellwig we return success upon a flush
request but we return -EROFS for other writes.
We detect flush requests by checking if the bio has zero sectors.

This patch is suitable to any -stable kernel to which it applies.

Cc: Christoph Hellwig <[email protected]>
Cc: Ben Hutchings <[email protected]>
Cc: NeilBrown <[email protected]>
Signed-off-by: Sebastian Riemer <[email protected]>
Reported-by: Ben Hutchings <[email protected]>
Acked-by: Paul Menzel <[email protected]>
Signed-off-by: NeilBrown <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/md/md.c | 4 ++++
1 file changed, 4 insertions(+)

--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -345,6 +345,10 @@ static void md_make_request(struct reque
bio_io_error(bio);
return;
}
+ if (mddev->ro == 1 && unlikely(rw == WRITE)) {
+ bio_endio(bio, bio_sectors(bio) == 0 ? 0 : -EROFS);
+ return;
+ }
smp_rmb(); /* Ensure implications of 'active' are visible */
rcu_read_lock();
if (mddev->suspended) {

2013-03-18 04:40:45

by Ben Hutchings

[permalink] [raw]
Subject: [ 43/82] Fix memory leak in cpufreq stats.

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

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

From: "Tu, Xiaobing" <[email protected]>

commit e37736777254ce1abc85493a5cacbefe5983b896 upstream.

When system enters sleep, non-boot CPUs will be disabled.
Cpufreq stats sysfs is created when the CPU is up, but it is not
freed when the CPU is going down. This will cause memory leak.

Signed-off-by: xiaobing tu <[email protected]>
Signed-off-by: guifang tang <[email protected]>
Signed-off-by: Rafael J. Wysocki <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/cpufreq/cpufreq_stats.c | 1 +
1 file changed, 1 insertion(+)

--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -330,6 +330,7 @@ static int __cpuinit cpufreq_stat_cpu_ca
cpufreq_update_policy(cpu);
break;
case CPU_DOWN_PREPARE:
+ case CPU_DOWN_PREPARE_FROZEN:
cpufreq_stats_free_sysfs(cpu);
break;
case CPU_DEAD:

2013-03-18 04:41:10

by Ben Hutchings

[permalink] [raw]
Subject: [ 44/82] vfs: fix pipe counter breakage

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

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

From: Al Viro <[email protected]>

commit a930d8790552658140d7d0d2e316af4f0d76a512 upstream.

If you open a pipe for neither read nor write, the pipe code will not
add any usage counters to the pipe, causing the 'struct pipe_inode_info"
to be potentially released early.

That doesn't normally matter, since you cannot actually use the pipe,
but the pipe release code - particularly fasync handling - still expects
the actual pipe infrastructure to all be there. And rather than adding
NULL pointer checks, let's just disallow this case, the same way we
already do for the named pipe ("fifo") case.

This is ancient going back to pre-2.4 days, and until trinity, nobody
naver noticed.

Reported-by: Dave Jones <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/pipe.c | 3 +++
1 file changed, 3 insertions(+)

--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -859,6 +859,9 @@ pipe_rdwr_open(struct inode *inode, stru
{
int ret = -ENOENT;

+ if (!(filp->f_mode & (FMODE_READ|FMODE_WRITE)))
+ return -EINVAL;
+
mutex_lock(&inode->i_mutex);

if (inode->i_pipe) {

2013-03-18 04:30:51

by Ben Hutchings

[permalink] [raw]
Subject: [ 15/82] mwifiex: correct sleep delay counter

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

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

From: Avinash Patil <[email protected]>

commit 3e7a4ff7c5b6423ddb644df9c41b8b6d2fb79d30 upstream.

Maximum delay for waking up card is 50 ms. Because of typo in
counter, this delay goes to 500ms. This patch fixes the bug.

Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Yogesh Ashok Powar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/wireless/mwifiex/pcie.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -290,7 +290,7 @@ static int mwifiex_pm_wakeup_card(struct
i++;
udelay(10);
/* 50ms max wait */
- if (i == 50000)
+ if (i == 5000)
break;
}


2013-03-18 04:30:47

by Ben Hutchings

[permalink] [raw]
Subject: [ 08/82] ARM: VFP: fix emulation of second VFP instruction

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

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

From: Russell King <[email protected]>

commit 5e4ba617c1b584b2e376f31a63bd4e734109318a upstream.

Martin Storsjö reports that the sequence:

ee312ac1 vsub.f32 s4, s3, s2
ee702ac0 vsub.f32 s5, s1, s0
e59f0028 ldr r0, [pc, #40]
ee111a90 vmov r1, s3

on Raspberry Pi (implementor 41 architecture 1 part 20 variant b rev 5)
where s3 is a denormal and s2 is zero results in incorrect behaviour -
the instruction "vsub.f32 s5, s1, s0" is not executed:

VFP: bounce: trigger ee111a90 fpexc d0000780
VFP: emulate: INST=0xee312ac1 SCR=0x00000000
...

As we can see, the instruction triggering the exception is the "vmov"
instruction, and we emulate the "vsub.f32 s4, s3, s2" but fail to
properly take account of the FPEXC_FP2V flag in FPEXC. This is because
the test for the second instruction register being valid is bogus, and
will always skip emulation of the second instruction.

Reported-by: Martin Storsjö <[email protected]>
Tested-by: Martin Storsjö <[email protected]>
Signed-off-by: Russell King <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/arm/vfp/vfpmodule.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -409,7 +409,7 @@ void VFP_bounce(u32 trigger, u32 fpexc,
* If there isn't a second FP instruction, exit now. Note that
* the FPEXC.FP2V bit is valid only if FPEXC.EX is 1.
*/
- if (fpexc ^ (FPEXC_EX | FPEXC_FP2V))
+ if ((fpexc & (FPEXC_EX | FPEXC_FP2V)) != (FPEXC_EX | FPEXC_FP2V))
goto exit;

/*

2013-03-18 04:41:38

by Ben Hutchings

[permalink] [raw]
Subject: [ 53/82] usb: cp210x new Vendor/Device IDs

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

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

From: "Matwey V. Kornilov" <[email protected]>

commit be3101c23394af59694c8a2aae6d07f5da62fea5 upstream.

This patch adds support for the Lake Shore Cryotronics devices to
the CP210x driver.

These lines are ported from cp210x driver distributed by Lake Shore web site:
http://www.lakeshore.com/Documents/Lake%20Shore%20cp210x-3.0.0.tar.gz
and licensed under the terms of GPLv2.

Moreover, I've tested this changes with Lake Shore 335 in my labs.

Signed-off-by: Matwey V. Kornilov <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/cp210x.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -156,6 +156,25 @@ static const struct usb_device_id id_tab
{ USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */
{ USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */
{ USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */
+ { USB_DEVICE(0x1FB9, 0x0100) }, /* Lake Shore Model 121 Current Source */
+ { USB_DEVICE(0x1FB9, 0x0200) }, /* Lake Shore Model 218A Temperature Monitor */
+ { USB_DEVICE(0x1FB9, 0x0201) }, /* Lake Shore Model 219 Temperature Monitor */
+ { USB_DEVICE(0x1FB9, 0x0202) }, /* Lake Shore Model 233 Temperature Transmitter */
+ { USB_DEVICE(0x1FB9, 0x0203) }, /* Lake Shore Model 235 Temperature Transmitter */
+ { USB_DEVICE(0x1FB9, 0x0300) }, /* Lake Shore Model 335 Temperature Controller */
+ { USB_DEVICE(0x1FB9, 0x0301) }, /* Lake Shore Model 336 Temperature Controller */
+ { USB_DEVICE(0x1FB9, 0x0302) }, /* Lake Shore Model 350 Temperature Controller */
+ { USB_DEVICE(0x1FB9, 0x0303) }, /* Lake Shore Model 371 AC Bridge */
+ { USB_DEVICE(0x1FB9, 0x0400) }, /* Lake Shore Model 411 Handheld Gaussmeter */
+ { USB_DEVICE(0x1FB9, 0x0401) }, /* Lake Shore Model 425 Gaussmeter */
+ { USB_DEVICE(0x1FB9, 0x0402) }, /* Lake Shore Model 455A Gaussmeter */
+ { USB_DEVICE(0x1FB9, 0x0403) }, /* Lake Shore Model 475A Gaussmeter */
+ { USB_DEVICE(0x1FB9, 0x0404) }, /* Lake Shore Model 465 Three Axis Gaussmeter */
+ { USB_DEVICE(0x1FB9, 0x0600) }, /* Lake Shore Model 625A Superconducting MPS */
+ { USB_DEVICE(0x1FB9, 0x0601) }, /* Lake Shore Model 642A Magnet Power Supply */
+ { USB_DEVICE(0x1FB9, 0x0602) }, /* Lake Shore Model 648 Magnet Power Supply */
+ { USB_DEVICE(0x1FB9, 0x0700) }, /* Lake Shore Model 737 VSM Controller */
+ { USB_DEVICE(0x1FB9, 0x0701) }, /* Lake Shore Model 776 Hall Matrix */
{ USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
{ USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */
{ USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */

2013-03-18 04:30:43

by Ben Hutchings

[permalink] [raw]
Subject: [ 06/82] [SCSI] storvsc: Initialize the sglist

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

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

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

commit 9d2696e658ef4f209955ddaa987d43f1a1bd81a1 upstream.

Properly initialize scatterlist before using it.

Signed-off-by: K. Y. Srinivasan <[email protected]>
Signed-off-by: James Bottomley <[email protected]>
[bwh: Backported to 3.2: adjust filename]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/staging/hv/storvsc_drv.c | 1 +
1 file changed, 1 insertion(+)

--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -815,6 +815,7 @@ static struct scatterlist *create_bounce
if (!bounce_sgl)
return NULL;

+ sg_init_table(bounce_sgl, num_pages);
for (i = 0; i < num_pages; i++) {
page_buf = alloc_page(GFP_ATOMIC);
if (!page_buf)

2013-03-18 04:42:00

by Ben Hutchings

[permalink] [raw]
Subject: [ 48/82] USB: storage: fix Huawei mode switching regression

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

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

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

commit ab4b71644a26d1ab92b987b2fd30e17c25e89f85 upstream.

This reverts commit 200e0d99 ("USB: storage: optimize to match the
Huawei USB storage devices and support new switch command" and the
followup bugfix commit cd060956 ("USB: storage: properly handle
the endian issues of idProduct").

The commit effectively added a large number of Huawei devices to
the deprecated usb-storage mode switching logic. Many of these
devices have been in use and supported by the userspace
usb_modeswitch utility for years. Forcing the switching inside
the kernel causes a number of regressions as a result of ignoring
existing onfigurations, and also completely takes away the ability
to configure mode switching per device/system/user.

Known regressions caused by this:
- Some of the devices support multiple modes, using different
switching commands. There are existing configurations taking
advantage of this.

- There is a real use case for disabling mode switching and
instead mounting the exposed storage device. This becomes
impossible with switching logic inside the usb-storage driver.

- At least on device fail as a result of the usb-storage switching
command, becoming completely unswitchable. This is possibly a
firmware bug, but still a regression because the device work as
expected using usb_modeswitch defaults.

In-kernel mode switching was deprecated years ago with the
development of the more user friendly userspace alternatives. The
existing list of devices in usb-storage was only kept to prevent
breaking already working systems. The long term plan is to remove
the list, not to add to it. Ref:
http://permalink.gmane.org/gmane.linux.usb.general/28543

Cc: <[email protected]>
Signed-off-by: Bjørn Mork <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/storage/initializers.c | 76 +--------
drivers/usb/storage/initializers.h | 4 +-
drivers/usb/storage/unusual_devs.h | 329 +++++++++++++++++++++++++++++++++++-
3 files changed, 331 insertions(+), 78 deletions(-)

--- a/drivers/usb/storage/initializers.c
+++ b/drivers/usb/storage/initializers.c
@@ -92,8 +92,8 @@ int usb_stor_ucr61s2b_init(struct us_dat
return 0;
}

-/* This places the HUAWEI usb dongles in multi-port mode */
-static int usb_stor_huawei_feature_init(struct us_data *us)
+/* This places the HUAWEI E220 devices in multi-port mode */
+int usb_stor_huawei_e220_init(struct us_data *us)
{
int result;

@@ -104,75 +104,3 @@ static int usb_stor_huawei_feature_init(
US_DEBUGP("Huawei mode set result is %d\n", result);
return 0;
}
-
-/*
- * It will send a scsi switch command called rewind' to huawei dongle.
- * When the dongle receives this command at the first time,
- * it will reboot immediately. After rebooted, it will ignore this command.
- * So it is unnecessary to read its response.
- */
-static int usb_stor_huawei_scsi_init(struct us_data *us)
-{
- int result = 0;
- int act_len = 0;
- struct bulk_cb_wrap *bcbw = (struct bulk_cb_wrap *) us->iobuf;
- char rewind_cmd[] = {0x11, 0x06, 0x20, 0x00, 0x00, 0x01, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
- bcbw->Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcbw->Tag = 0;
- bcbw->DataTransferLength = 0;
- bcbw->Flags = bcbw->Lun = 0;
- bcbw->Length = sizeof(rewind_cmd);
- memset(bcbw->CDB, 0, sizeof(bcbw->CDB));
- memcpy(bcbw->CDB, rewind_cmd, sizeof(rewind_cmd));
-
- result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcbw,
- US_BULK_CB_WRAP_LEN, &act_len);
- US_DEBUGP("transfer actual length=%d, result=%d\n", act_len, result);
- return result;
-}
-
-/*
- * It tries to find the supported Huawei USB dongles.
- * In Huawei, they assign the following product IDs
- * for all of their mobile broadband dongles,
- * including the new dongles in the future.
- * So if the product ID is not included in this list,
- * it means it is not Huawei's mobile broadband dongles.
- */
-static int usb_stor_huawei_dongles_pid(struct us_data *us)
-{
- struct usb_interface_descriptor *idesc;
- int idProduct;
-
- idesc = &us->pusb_intf->cur_altsetting->desc;
- idProduct = le16_to_cpu(us->pusb_dev->descriptor.idProduct);
- /* The first port is CDROM,
- * means the dongle in the single port mode,
- * and a switch command is required to be sent. */
- if (idesc && idesc->bInterfaceNumber == 0) {
- if ((idProduct == 0x1001)
- || (idProduct == 0x1003)
- || (idProduct == 0x1004)
- || (idProduct >= 0x1401 && idProduct <= 0x1500)
- || (idProduct >= 0x1505 && idProduct <= 0x1600)
- || (idProduct >= 0x1c02 && idProduct <= 0x2202)) {
- return 1;
- }
- }
- return 0;
-}
-
-int usb_stor_huawei_init(struct us_data *us)
-{
- int result = 0;
-
- if (usb_stor_huawei_dongles_pid(us)) {
- if (le16_to_cpu(us->pusb_dev->descriptor.idProduct) >= 0x1446)
- result = usb_stor_huawei_scsi_init(us);
- else
- result = usb_stor_huawei_feature_init(us);
- }
- return result;
-}
--- a/drivers/usb/storage/initializers.h
+++ b/drivers/usb/storage/initializers.h
@@ -46,5 +46,5 @@ int usb_stor_euscsi_init(struct us_data
* flash reader */
int usb_stor_ucr61s2b_init(struct us_data *us);

-/* This places the HUAWEI usb dongles in multi-port mode */
-int usb_stor_huawei_init(struct us_data *us);
+/* This places the HUAWEI E220 devices in multi-port mode */
+int usb_stor_huawei_e220_init(struct us_data *us);
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -1515,10 +1515,335 @@ UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x
/* Reported by fangxiaozhi <[email protected]>
* This brings the HUAWEI data card devices into multi-port mode
*/
-UNUSUAL_VENDOR_INTF(0x12d1, 0x08, 0x06, 0x50,
+UNUSUAL_DEV( 0x12d1, 0x1001, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_init,
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1004, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1401, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1402, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1403, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1404, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1405, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1406, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1407, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1408, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1409, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x140A, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x140B, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x140C, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x140D, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x140E, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x140F, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1410, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1411, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1412, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1413, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1414, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1415, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1416, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1417, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1418, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1419, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x141A, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x141B, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x141C, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x141D, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x141E, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x141F, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1420, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1421, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1422, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1423, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1424, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1425, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1426, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1427, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1428, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1429, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x142A, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x142B, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x142C, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x142D, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x142E, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x142F, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1430, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1431, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1432, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1433, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1434, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1435, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1436, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1437, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1438, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x1439, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x143A, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x143B, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x143C, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x143D, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x143E, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+ 0),
+UNUSUAL_DEV( 0x12d1, 0x143F, 0x0000, 0x0000,
+ "HUAWEI MOBILE",
+ "Mass Storage",
+ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),

/* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */

2013-03-18 04:42:04

by Ben Hutchings

[permalink] [raw]
Subject: [ 50/82] e1000e: fix pci-device enable-counter balance

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

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

From: Konstantin Khlebnikov <[email protected]>

commit 4e0855dff094b0d56d6b5b271e0ce7851cc1e063 upstream.

This patch removes redundant and unbalanced pci_disable_device() from
__e1000_shutdown(). pci_clear_master() is enough, device can go into
suspended state with elevated enable_cnt.

Bug was introduced in commit 23606cf5d1192c2b17912cb2ef6e62f9b11de133
("e1000e / PCI / PM: Add basic runtime PM support (rev. 4)") in v2.6.35

Cc: Bruce Allan <[email protected]>
Signed-off-by: Konstantin Khlebnikov <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
Tested-by: Borislav Petkov <[email protected]>
Tested-by: Aaron Brown <[email protected]>
Signed-off-by: Jeff Kirsher <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/ethernet/intel/e1000e/netdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -5402,7 +5402,7 @@ static int __e1000_shutdown(struct pci_d
*/
e1000e_release_hw_control(adapter);

- pci_disable_device(pdev);
+ pci_clear_master(pdev);

return 0;
}

2013-03-18 04:42:30

by Ben Hutchings

[permalink] [raw]
Subject: [ 49/82] USB: added support for Cinterions products AH6 and PLS8

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

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

From: Christian Schmiedl <[email protected]>

commit 1941138e1c024ecb5bd797d414928d3eb94d8662 upstream.

add support for Cinterion's products AH6 and PLS8 by adding Product IDs
and USB_DEVICE tuples.

Signed-off-by: Christian Schmiedl <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/option.c | 4 ++++
1 file changed, 4 insertions(+)

--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -341,6 +341,8 @@ static void option_instat_callback(struc
#define CINTERION_PRODUCT_EU3_E 0x0051
#define CINTERION_PRODUCT_EU3_P 0x0052
#define CINTERION_PRODUCT_PH8 0x0053
+#define CINTERION_PRODUCT_AH6 0x0055
+#define CINTERION_PRODUCT_PLS8 0x0060

/* Olivetti products */
#define OLIVETTI_VENDOR_ID 0x0b3c
@@ -1261,6 +1263,8 @@ static const struct usb_device_id option
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) },
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) },
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) },
+ { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AH6) },
+ { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLS8) },
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) },
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
{ USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) },

2013-03-18 04:30:40

by Ben Hutchings

[permalink] [raw]
Subject: [ 04/82] NFS: Dont allow NFS silly-renamed files to be deleted, no signal

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

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

From: Trond Myklebust <[email protected]>

commit 5a7a613a47a715711b3f2d3322a0eac21d459166 upstream.

Commit 73ca100 broke the code that prevents the client from deleting
a silly renamed dentry. This affected "delete on last close"
semantics as after that commit, nothing prevented removal of
silly-renamed files. As a result, a process holding a file open
could easily get an ESTALE on the file in a directory where some
other process issued 'rm -rf some_dir_containing_the_file' twice.
Before the commit, any attempt at unlinking silly renamed files would
fail inside may_delete() with -EBUSY because of the
DCACHE_NFSFS_RENAMED flag. The following testcase demonstrates
the problem:
tail -f /nfsmnt/dir/file &
rm -rf /nfsmnt/dir
rm -rf /nfsmnt/dir
# second removal does not fail, 'tail' process receives ESTALE

The problem with the above commit is that it unhashes the old and
new dentries from the lookup path, even in the normal case when
a signal is not encountered and it would have been safe to call
d_move. Unfortunately the old dentry has the special
DCACHE_NFSFS_RENAMED flag set on it. Unhashing has the
side-effect that future lookups call d_alloc(), allocating a new
dentry without the special flag for any silly-renamed files. As a
result, subsequent calls to unlink silly renamed files do not fail
but allow the removal to go through. This will result in ESTALE
errors for any other process doing operations on the file.

To fix this, go back to using d_move on success.
For the signal case, it's unclear what we may safely do beyond d_drop.

Reported-by: Dave Wysochanski <[email protected]>
Signed-off-by: Trond Myklebust <[email protected]>
Acked-by: Jeff Layton <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/nfs/unlink.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)

--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -366,20 +366,14 @@ static void nfs_async_rename_done(struct
struct inode *old_dir = data->old_dir;
struct inode *new_dir = data->new_dir;
struct dentry *old_dentry = data->old_dentry;
- struct dentry *new_dentry = data->new_dentry;

if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) {
rpc_restart_call_prepare(task);
return;
}

- if (task->tk_status != 0) {
+ if (task->tk_status != 0)
nfs_cancel_async_unlink(old_dentry);
- return;
- }
-
- d_drop(old_dentry);
- d_drop(new_dentry);
}

/**
@@ -589,6 +583,18 @@ nfs_sillyrename(struct inode *dir, struc
error = rpc_wait_for_completion_task(task);
if (error == 0)
error = task->tk_status;
+ switch (error) {
+ case 0:
+ /* The rename succeeded */
+ nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
+ d_move(dentry, sdentry);
+ break;
+ case -ERESTARTSYS:
+ /* The result of the rename is unknown. Play it safe by
+ * forcing a new lookup */
+ d_drop(dentry);
+ d_drop(sdentry);
+ }
rpc_put_task(task);
out_dput:
dput(sdentry);

2013-03-18 04:42:57

by Ben Hutchings

[permalink] [raw]
Subject: [ 46/82] xen/pciback: Dont disable a PCI device that is already disabled.

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

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

From: Konrad Rzeszutek Wilk <[email protected]>

commit bdc5c1812cea6efe1aaefb3131fcba28cd0b2b68 upstream.

While shuting down a HVM guest with pci devices passed through we
get this:

pciback 0000:04:00.0: restoring config space at offset 0x4 (was 0x100000, writing 0x100002)
------------[ cut here ]------------
WARNING: at drivers/pci/pci.c:1397 pci_disable_device+0x88/0xa0()
Hardware name: MS-7640
Device pciback
disabling already-disabled device
Modules linked in:
Pid: 53, comm: xenwatch Not tainted 3.9.0-rc1-20130304a+ #1
Call Trace:
[<ffffffff8106994a>] warn_slowpath_common+0x7a/0xc0
[<ffffffff81069a31>] warn_slowpath_fmt+0x41/0x50
[<ffffffff813cf288>] pci_disable_device+0x88/0xa0
[<ffffffff814554a7>] xen_pcibk_reset_device+0x37/0xd0
[<ffffffff81454b6f>] ? pcistub_put_pci_dev+0x6f/0x120
[<ffffffff81454b8d>] pcistub_put_pci_dev+0x8d/0x120
[<ffffffff814582a9>] __xen_pcibk_release_devices+0x59/0xa0

This fixes the bug.

Reported-and-Tested-by: Sander Eikelenboom <[email protected]>
Signed-off-by: Konrad Rzeszutek Wilk <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/xen/xen-pciback/pciback_ops.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/xen/xen-pciback/pciback_ops.c
+++ b/drivers/xen/xen-pciback/pciback_ops.c
@@ -114,7 +114,8 @@ void xen_pcibk_reset_device(struct pci_d
if (dev->msi_enabled)
pci_disable_msi(dev);
#endif
- pci_disable_device(dev);
+ if (pci_is_enabled(dev))
+ pci_disable_device(dev);

pci_write_config_word(dev, PCI_COMMAND, 0);


2013-03-18 04:43:15

by Ben Hutchings

[permalink] [raw]
Subject: [ 58/82] tty/serial: Add support for Altera serial port

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

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

From: Ley Foon Tan <[email protected]>

commit e06c93cacb82dd147266fd1bdb2d0a0bd45ff2c1 upstream.

Add support for Altera 8250/16550 compatible serial port.

Signed-off-by: Ley Foon Tan <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[bwh: Backported to 3.2: adjust filenames, context]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/Documentation/devicetree/bindings/tty/serial/of-serial.txt
+++ b/Documentation/devicetree/bindings/tty/serial/of-serial.txt
@@ -10,6 +10,9 @@ Required properties:
- "ns16850"
- "nvidia,tegra20-uart"
- "ibm,qpace-nwp-serial"
+ - "altr,16550-FIFO32"
+ - "altr,16550-FIFO64"
+ - "altr,16550-FIFO128"
- "serial" if the port type is unknown.
- reg : offset and length of the register set for the device.
- interrupts : should contain uart interrupt.
--- a/drivers/tty/serial/8250.c
+++ b/drivers/tty/serial/8250.c
@@ -322,6 +322,27 @@ static const struct serial8250_config ua
.tx_loadsz = 1024,
.flags = UART_CAP_HFIFO,
},
+ [PORT_ALTR_16550_F32] = {
+ .name = "Altera 16550 FIFO32",
+ .fifo_size = 32,
+ .tx_loadsz = 32,
+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+ .flags = UART_CAP_FIFO | UART_CAP_AFE,
+ },
+ [PORT_ALTR_16550_F64] = {
+ .name = "Altera 16550 FIFO64",
+ .fifo_size = 64,
+ .tx_loadsz = 64,
+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+ .flags = UART_CAP_FIFO | UART_CAP_AFE,
+ },
+ [PORT_ALTR_16550_F128] = {
+ .name = "Altera 16550 FIFO128",
+ .fifo_size = 128,
+ .tx_loadsz = 128,
+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+ .flags = UART_CAP_FIFO | UART_CAP_AFE,
+ },
};

#if defined(CONFIG_MIPS_ALCHEMY)
--- a/drivers/tty/serial/of_serial.c
+++ b/drivers/tty/serial/of_serial.c
@@ -182,6 +182,12 @@ static struct of_device_id __devinitdata
{ .compatible = "ns16750", .data = (void *)PORT_16750, },
{ .compatible = "ns16850", .data = (void *)PORT_16850, },
{ .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, },
+ { .compatible = "altr,16550-FIFO32",
+ .data = (void *)PORT_ALTR_16550_F32, },
+ { .compatible = "altr,16550-FIFO64",
+ .data = (void *)PORT_ALTR_16550_F64, },
+ { .compatible = "altr,16550-FIFO128",
+ .data = (void *)PORT_ALTR_16550_F128, },
#ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL
{ .compatible = "ibm,qpace-nwp-serial",
.data = (void *)PORT_NWPSERIAL, },
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -48,7 +48,10 @@
#define PORT_TEGRA 20 /* NVIDIA Tegra internal UART */
#define PORT_XR17D15X 21 /* Exar XR17D15x UART */
#define PORT_BRCM_TRUMANAGE 25
-#define PORT_MAX_8250 25 /* max port ID */
+#define PORT_ALTR_16550_F32 26 /* Altera 16550 UART with 32 FIFOs */
+#define PORT_ALTR_16550_F64 27 /* Altera 16550 UART with 64 FIFOs */
+#define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */
+#define PORT_MAX_8250 28 /* max port ID */

/*
* ARM specific type numbers. These are not currently guaranteed

2013-03-18 04:43:35

by Ben Hutchings

[permalink] [raw]
Subject: [ 51/82] virtio: rng: disallow multiple device registrations, fixes crashes

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

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

From: Amit Shah <[email protected]>

commit e84e7a56a3aa2963db506299e29a5f3f09377f9b upstream.

The code currently only supports one virtio-rng device at a time.
Invoking guests with multiple devices causes the guest to blow up.

Check if we've already registered and initialised the driver. Also
cleanup in case of registration errors or hot-unplug so that a new
device can be used.

Reported-by: Peter Krempa <[email protected]>
Reported-by: <[email protected]>
Signed-off-by: Amit Shah <[email protected]>
Signed-off-by: Rusty Russell <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/char/hw_random/virtio-rng.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)

--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -89,14 +89,22 @@ static int virtrng_probe(struct virtio_d
{
int err;

+ if (vq) {
+ /* We only support one device for now */
+ return -EBUSY;
+ }
/* We expect a single virtqueue. */
vq = virtio_find_single_vq(vdev, random_recv_done, "input");
- if (IS_ERR(vq))
- return PTR_ERR(vq);
+ if (IS_ERR(vq)) {
+ err = PTR_ERR(vq);
+ vq = NULL;
+ return err;
+ }

err = hwrng_register(&virtio_hwrng);
if (err) {
vdev->config->del_vqs(vdev);
+ vq = NULL;
return err;
}

@@ -108,6 +116,7 @@ static void __devexit virtrng_remove(str
vdev->config->reset(vdev);
hwrng_unregister(&virtio_hwrng);
vdev->config->del_vqs(vdev);
+ vq = NULL;
}

static struct virtio_device_id id_table[] = {

2013-03-18 04:30:35

by Ben Hutchings

[permalink] [raw]
Subject: [ 05/82] SUNRPC: Dont start the retransmission timer when out of socket space

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

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

From: Trond Myklebust <[email protected]>

commit a9a6b52ee1baa865283a91eb8d443ee91adfca56 upstream.

If the socket is full, we're better off just waiting until it empties,
or until the connection is broken. The reason why we generally don't
want to time out is that the call to xprt->ops->release_xprt() will
trigger a connection reset, which isn't helpful...

Let's make an exception for soft RPC calls, since they have to provide
timeout guarantees.

Signed-off-by: Trond Myklebust <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/sunrpc/xprt.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -481,13 +481,17 @@ EXPORT_SYMBOL_GPL(xprt_wake_pending_task
* xprt_wait_for_buffer_space - wait for transport output buffer to clear
* @task: task to be put to sleep
* @action: function pointer to be executed after wait
+ *
+ * Note that we only set the timer for the case of RPC_IS_SOFT(), since
+ * we don't in general want to force a socket disconnection due to
+ * an incomplete RPC call transmission.
*/
void xprt_wait_for_buffer_space(struct rpc_task *task, rpc_action action)
{
struct rpc_rqst *req = task->tk_rqstp;
struct rpc_xprt *xprt = req->rq_xprt;

- task->tk_timeout = req->rq_timeout;
+ task->tk_timeout = RPC_IS_SOFT(task) ? req->rq_timeout : 0;
rpc_sleep_on(&xprt->pending, task, action);
}
EXPORT_SYMBOL_GPL(xprt_wait_for_buffer_space);

2013-03-18 04:43:51

by Ben Hutchings

[permalink] [raw]
Subject: [ 52/82] ALSA: seq: Fix missing error handling in snd_seq_timer_open()

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

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

From: Takashi Iwai <[email protected]>

commit 66efdc71d95887b652a742a5dae51fa834d71465 upstream.

snd_seq_timer_open() didn't catch the whole error path but let through
if the timer id is a slave. This may lead to Oops by accessing the
uninitialized pointer.

BUG: unable to handle kernel NULL pointer dereference at 00000000000002ae
IP: [<ffffffff819b3477>] snd_seq_timer_open+0xe7/0x130
PGD 785cd067 PUD 76964067 PMD 0
Oops: 0002 [#4] SMP
CPU 0
Pid: 4288, comm: trinity-child7 Tainted: G D W 3.9.0-rc1+ #100 Bochs Bochs
RIP: 0010:[<ffffffff819b3477>] [<ffffffff819b3477>] snd_seq_timer_open+0xe7/0x130
RSP: 0018:ffff88006ece7d38 EFLAGS: 00010246
RAX: 0000000000000286 RBX: ffff88007851b400 RCX: 0000000000000000
RDX: 000000000000ffff RSI: ffff88006ece7d58 RDI: ffff88006ece7d38
RBP: ffff88006ece7d98 R08: 000000000000000a R09: 000000000000fffe
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
R13: ffff8800792c5400 R14: 0000000000e8f000 R15: 0000000000000007
FS: 00007f7aaa650700(0000) GS:ffff88007f800000(0000) GS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000000002ae CR3: 000000006efec000 CR4: 00000000000006f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process trinity-child7 (pid: 4288, threadinfo ffff88006ece6000, task ffff880076a8a290)
Stack:
0000000000000286 ffffffff828f2be0 ffff88006ece7d58 ffffffff810f354d
65636e6575716573 2065756575712072 ffff8800792c0030 0000000000000000
ffff88006ece7d98 ffff8800792c5400 ffff88007851b400 ffff8800792c5520
Call Trace:
[<ffffffff810f354d>] ? trace_hardirqs_on+0xd/0x10
[<ffffffff819b17e9>] snd_seq_queue_timer_open+0x29/0x70
[<ffffffff819ae01a>] snd_seq_ioctl_set_queue_timer+0xda/0x120
[<ffffffff819acb9b>] snd_seq_do_ioctl+0x9b/0xd0
[<ffffffff819acbe0>] snd_seq_ioctl+0x10/0x20
[<ffffffff811b9542>] do_vfs_ioctl+0x522/0x570
[<ffffffff8130a4b3>] ? file_has_perm+0x83/0xa0
[<ffffffff810f354d>] ? trace_hardirqs_on+0xd/0x10
[<ffffffff811b95ed>] sys_ioctl+0x5d/0xa0
[<ffffffff813663fe>] ? trace_hardirqs_on_thunk+0x3a/0x3f
[<ffffffff81faed69>] system_call_fastpath+0x16/0x1b

Reported-and-tested-by: Tommi Rantala <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
sound/core/seq/seq_timer.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -290,10 +290,10 @@ int snd_seq_timer_open(struct snd_seq_qu
tid.device = SNDRV_TIMER_GLOBAL_SYSTEM;
err = snd_timer_open(&t, str, &tid, q->queue);
}
- if (err < 0) {
- snd_printk(KERN_ERR "seq fatal error: cannot create timer (%i)\n", err);
- return err;
- }
+ }
+ if (err < 0) {
+ snd_printk(KERN_ERR "seq fatal error: cannot create timer (%i)\n", err);
+ return err;
}
t->callback = snd_seq_timer_interrupt;
t->callback_data = q;

2013-03-18 04:44:20

by Ben Hutchings

[permalink] [raw]
Subject: [ 60/82] serial: 8250_pci: add support for another kind of NetMos Technology PCI 9835 Multi-I/O Controller

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

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

From: Wang YanQing <[email protected]>

commit 8d2f8cd424ca0b99001f3ff4f5db87c4e525f366 upstream.

01:08.0 Communication controller: NetMos Technology PCI 9835 Multi-I/O Controller (rev 01)
Subsystem: Device [1000:0012]
Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Interrupt: pin A routed to IRQ 20
Region 0: I/O ports at e050 [size=8]
Region 1: I/O ports at e040 [size=8]
Region 2: I/O ports at e030 [size=8]
Region 3: I/O ports at e020 [size=8]
Region 4: I/O ports at e010 [size=8]
Region 5: I/O ports at e000 [size=16]

Signed-off-by: Wang YanQing <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[bwh: Backported to 3.2: adjust filename]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/tty/serial/8250_pci.c | 4 ++++
1 file changed, 4 insertions(+)

--- a/drivers/tty/serial/8250_pci.c
+++ b/drivers/tty/serial/8250_pci.c
@@ -4083,6 +4083,10 @@ static struct pci_device_id serial_pci_t
PCI_VENDOR_ID_IBM, 0x0299,
0, 0, pbn_b0_bt_2_115200 },

+ { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835,
+ 0x1000, 0x0012,
+ 0, 0, pbn_b0_bt_2_115200 },
+
{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901,
0xA000, 0x1000,
0, 0, pbn_b0_1_115200 },

2013-03-18 04:44:17

by Ben Hutchings

[permalink] [raw]
Subject: [ 57/82] keys: fix race with concurrent install_user_keyrings()

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

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

From: David Howells <[email protected]>

commit 0da9dfdd2cd9889201bc6f6f43580c99165cd087 upstream.

This fixes CVE-2013-1792.

There is a race in install_user_keyrings() that can cause a NULL pointer
dereference when called concurrently for the same user if the uid and
uid-session keyrings are not yet created. It might be possible for an
unprivileged user to trigger this by calling keyctl() from userspace in
parallel immediately after logging in.

Assume that we have two threads both executing lookup_user_key(), both
looking for KEY_SPEC_USER_SESSION_KEYRING.

THREAD A THREAD B
=============================== ===============================
==>call install_user_keyrings();
if (!cred->user->session_keyring)
==>call install_user_keyrings()
...
user->uid_keyring = uid_keyring;
if (user->uid_keyring)
return 0;
<==
key = cred->user->session_keyring [== NULL]
user->session_keyring = session_keyring;
atomic_inc(&key->usage); [oops]

At the point thread A dereferences cred->user->session_keyring, thread B
hasn't updated user->session_keyring yet, but thread A assumes it is
populated because install_user_keyrings() returned ok.

The race window is really small but can be exploited if, for example,
thread B is interrupted or preempted after initializing uid_keyring, but
before doing setting session_keyring.

This couldn't be reproduced on a stock kernel. However, after placing
systemtap probe on 'user->session_keyring = session_keyring;' that
introduced some delay, the kernel could be crashed reliably.

Fix this by checking both pointers before deciding whether to return.
Alternatively, the test could be done away with entirely as it is checked
inside the mutex - but since the mutex is global, that may not be the best
way.

Signed-off-by: David Howells <[email protected]>
Reported-by: Mateusz Guzik <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: James Morris <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
security/keys/process_keys.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -54,7 +54,7 @@ int install_user_keyrings(void)

kenter("%p{%u}", user, user->uid);

- if (user->uid_keyring) {
+ if (user->uid_keyring && user->session_keyring) {
kleave(" = 0 [exist]");
return 0;
}

2013-03-18 04:44:50

by Ben Hutchings

[permalink] [raw]
Subject: [ 62/82] usb: serial: Add Rigblaster Advantage to device table

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

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

From: Steve Conklin <[email protected]>

commit a57e82a18779ab8a5e5a1f5841cef937cf578913 upstream.

The Rigblaster Advantage is an amateur radio interface sold by West Mountain
Radio. It contains a cp210x serial interface but the device ID is not in
the driver.

Signed-off-by: Steve Conklin <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/cp210x.c | 1 +
1 file changed, 1 insertion(+)

--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -91,6 +91,7 @@ static const struct usb_device_id id_tab
{ USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */
{ USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
{ USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
+ { USB_DEVICE(0x2405, 0x0003) }, /* West Mountain Radio RIGblaster Advantage */
{ USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */
{ USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
{ USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */

2013-03-18 04:45:13

by Ben Hutchings

[permalink] [raw]
Subject: [ 76/82] mm/hotplug: correctly add new zone to all other nodes zone lists

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

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

From: Jiang Liu <[email protected]>

commit 08dff7b7d629807dbb1f398c68dd9cd58dd657a1 upstream.

When online_pages() is called to add new memory to an empty zone, it
rebuilds all zone lists by calling build_all_zonelists(). But there's a
bug which prevents the new zone to be added to other nodes' zone lists.

online_pages() {
build_all_zonelists()
.....
node_set_state(zone_to_nid(zone), N_HIGH_MEMORY)
}

Here the node of the zone is put into N_HIGH_MEMORY state after calling
build_all_zonelists(), but build_all_zonelists() only adds zones from
nodes in N_HIGH_MEMORY state to the fallback zone lists.
build_all_zonelists()

->__build_all_zonelists()
->build_zonelists()
->find_next_best_node()
->for_each_node_state(n, N_HIGH_MEMORY)

So memory in the new zone will never be used by other nodes, and it may
cause strange behavor when system is under memory pressure. So put node
into N_HIGH_MEMORY state before calling build_all_zonelists().

Signed-off-by: Jianguo Wu <[email protected]>
Signed-off-by: Jiang Liu <[email protected]>
Cc: Mel Gorman <[email protected]>
Cc: Michal Hocko <[email protected]>
Cc: Minchan Kim <[email protected]>
Cc: Rusty Russell <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: KAMEZAWA Hiroyuki <[email protected]>
Cc: KOSAKI Motohiro <[email protected]>
Cc: David Rientjes <[email protected]>
Cc: Keping Chen <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
mm/memory_hotplug.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)

--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -515,19 +515,20 @@ int __ref online_pages(unsigned long pfn

zone->present_pages += onlined_pages;
zone->zone_pgdat->node_present_pages += onlined_pages;
- if (need_zonelists_rebuild)
- build_all_zonelists(zone);
- else
- zone_pcp_update(zone);
+ if (onlined_pages) {
+ node_set_state(zone_to_nid(zone), N_HIGH_MEMORY);
+ if (need_zonelists_rebuild)
+ build_all_zonelists(zone);
+ else
+ zone_pcp_update(zone);
+ }

mutex_unlock(&zonelists_mutex);

init_per_zone_wmark_min();

- if (onlined_pages) {
+ if (onlined_pages)
kswapd_run(zone_to_nid(zone));
- node_set_state(zone_to_nid(zone), N_HIGH_MEMORY);
- }

vm_total_pages = nr_free_pagecache_pages();


2013-03-18 04:45:32

by Ben Hutchings

[permalink] [raw]
Subject: [ 67/82] hwmon: (pmbus/ltc2978) Fix temperature reporting

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

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

From: Guenter Roeck <[email protected]>

commit 8c958c703ef8804093437959221951eaf0e1e664 upstream.

On LTC2978, only READ_TEMPERATURE is supported. It reports
the internal junction temperature. This register is unpaged.

On LTC3880, READ_TEMPERATURE and READ_TEMPERATURE2 are supported.
READ_TEMPERATURE is paged and reports external temperatures.
READ_TEMPERATURE2 is unpaged and reports the internal junction
temperature.

Signed-off-by: Guenter Roeck <[email protected]>
Acked-by: Jean Delvare <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/hwmon/pmbus/ltc2978.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)

--- a/drivers/hwmon/pmbus/ltc2978.c
+++ b/drivers/hwmon/pmbus/ltc2978.c
@@ -59,7 +59,7 @@ enum chips { ltc2978, ltc3880 };
struct ltc2978_data {
enum chips id;
int vin_min, vin_max;
- int temp_min, temp_max;
+ int temp_min, temp_max[2];
int vout_min[8], vout_max[8];
int iout_max[2];
int temp2_max;
@@ -113,9 +113,10 @@ static int ltc2978_read_word_data_common
ret = pmbus_read_word_data(client, page,
LTC2978_MFR_TEMPERATURE_PEAK);
if (ret >= 0) {
- if (lin11_to_val(ret) > lin11_to_val(data->temp_max))
- data->temp_max = ret;
- ret = data->temp_max;
+ if (lin11_to_val(ret)
+ > lin11_to_val(data->temp_max[page]))
+ data->temp_max[page] = ret;
+ ret = data->temp_max[page];
}
break;
case PMBUS_VIRT_RESET_VOUT_HISTORY:
@@ -266,7 +267,7 @@ static int ltc2978_write_word_data(struc
break;
case PMBUS_VIRT_RESET_TEMP_HISTORY:
data->temp_min = 0x7bff;
- data->temp_max = 0x7c00;
+ data->temp_max[page] = 0x7c00;
ret = ltc2978_clear_peaks(client, page, data->id);
break;
default:
@@ -325,7 +326,8 @@ static int ltc2978_probe(struct i2c_clie
data->vin_min = 0x7bff;
data->vin_max = 0x7c00;
data->temp_min = 0x7bff;
- data->temp_max = 0x7c00;
+ for (i = 0; i < ARRAY_SIZE(data->temp_max); i++)
+ data->temp_max[i] = 0x7c00;
data->temp2_max = 0x7c00;

switch (data->id) {

2013-03-18 04:45:29

by Ben Hutchings

[permalink] [raw]
Subject: [ 65/82] signal: always clear sa_restorer on execve

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

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

From: Kees Cook <[email protected]>

commit 2ca39528c01a933f6689cd6505ce65bd6d68a530 upstream.

When the new signal handlers are set up, the location of sa_restorer is
not cleared, leaking a parent process's address space location to
children. This allows for a potential bypass of the parent's ASLR by
examining the sa_restorer value returned when calling sigaction().

Based on what should be considered "secret" about addresses, it only
matters across the exec not the fork (since the VMAs haven't changed
until the exec). But since exec sets SIG_DFL and keeps sa_restorer,
this is where it should be fixed.

Given the few uses of sa_restorer, a "set" function was not written
since this would be the only use. Instead, we use
__ARCH_HAS_SA_RESTORER, as already done in other places.

Example of the leak before applying this patch:

$ cat /proc/$$/maps
...
7fb9f3083000-7fb9f3238000 r-xp 00000000 fd:01 404469 .../libc-2.15.so
...
$ ./leak
...
7f278bc74000-7f278be29000 r-xp 00000000 fd:01 404469 .../libc-2.15.so
...
1 0 (nil) 0x7fb9f30b94a0
2 4000000 (nil) 0x7f278bcaa4a0
3 4000000 (nil) 0x7f278bcaa4a0
4 0 (nil) 0x7fb9f30b94a0
...

[[email protected]: use SA_RESTORER for backportability]
Signed-off-by: Kees Cook <[email protected]>
Reported-by: Emese Revfy <[email protected]>
Cc: Emese Revfy <[email protected]>
Cc: PaX Team <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Oleg Nesterov <[email protected]>
Cc: "Eric W. Biederman" <[email protected]>
Cc: Serge Hallyn <[email protected]>
Cc: Julien Tinnes <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
kernel/signal.c | 3 +++
1 file changed, 3 insertions(+)

--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -481,6 +481,9 @@ flush_signal_handlers(struct task_struct
if (force_default || ka->sa.sa_handler != SIG_IGN)
ka->sa.sa_handler = SIG_DFL;
ka->sa.sa_flags = 0;
+#ifdef SA_RESTORER
+ ka->sa.sa_restorer = NULL;
+#endif
sigemptyset(&ka->sa.sa_mask);
ka++;
}

2013-03-18 04:46:16

by Ben Hutchings

[permalink] [raw]
Subject: [ 68/82] crypto: user - fix info leaks in report API

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

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

From: Mathias Krause <[email protected]>

commit 9a5467bf7b6e9e02ec9c3da4e23747c05faeaac6 upstream.

Three errors resulting in kernel memory disclosure:

1/ The structures used for the netlink based crypto algorithm report API
are located on the stack. As snprintf() does not fill the remainder of
the buffer with null bytes, those stack bytes will be disclosed to users
of the API. Switch to strncpy() to fix this.

2/ crypto_report_one() does not initialize all field of struct
crypto_user_alg. Fix this to fix the heap info leak.

3/ For the module name we should copy only as many bytes as
module_name() returns -- not as much as the destination buffer could
hold. But the current code does not and therefore copies random data
from behind the end of the module name, as the module name is always
shorter than CRYPTO_MAX_ALG_NAME.

Also switch to use strncpy() to copy the algorithm's name and
driver_name. They are strings, after all.

Signed-off-by: Mathias Krause <[email protected]>
Cc: Steffen Klassert <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
crypto/ablkcipher.c | 12 ++++++------
crypto/aead.c | 9 ++++-----
crypto/ahash.c | 2 +-
crypto/blkcipher.c | 6 +++---
crypto/crypto_user.c | 22 +++++++++++-----------
crypto/pcompress.c | 3 +--
crypto/rng.c | 2 +-
crypto/shash.c | 3 ++-
8 files changed, 29 insertions(+), 30 deletions(-)

--- a/crypto/ablkcipher.c
+++ b/crypto/ablkcipher.c
@@ -388,9 +388,9 @@ static int crypto_ablkcipher_report(stru
{
struct crypto_report_blkcipher rblkcipher;

- snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "ablkcipher");
- snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s",
- alg->cra_ablkcipher.geniv ?: "<default>");
+ strncpy(rblkcipher.type, "ablkcipher", sizeof(rblkcipher.type));
+ strncpy(rblkcipher.geniv, alg->cra_ablkcipher.geniv ?: "<default>",
+ sizeof(rblkcipher.geniv));

rblkcipher.blocksize = alg->cra_blocksize;
rblkcipher.min_keysize = alg->cra_ablkcipher.min_keysize;
@@ -469,9 +469,9 @@ static int crypto_givcipher_report(struc
{
struct crypto_report_blkcipher rblkcipher;

- snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "givcipher");
- snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s",
- alg->cra_ablkcipher.geniv ?: "<built-in>");
+ strncpy(rblkcipher.type, "givcipher", sizeof(rblkcipher.type));
+ strncpy(rblkcipher.geniv, alg->cra_ablkcipher.geniv ?: "<built-in>",
+ sizeof(rblkcipher.geniv));

rblkcipher.blocksize = alg->cra_blocksize;
rblkcipher.min_keysize = alg->cra_ablkcipher.min_keysize;
--- a/crypto/aead.c
+++ b/crypto/aead.c
@@ -117,9 +117,8 @@ static int crypto_aead_report(struct sk_
struct crypto_report_aead raead;
struct aead_alg *aead = &alg->cra_aead;

- snprintf(raead.type, CRYPTO_MAX_ALG_NAME, "%s", "aead");
- snprintf(raead.geniv, CRYPTO_MAX_ALG_NAME, "%s",
- aead->geniv ?: "<built-in>");
+ strncpy(raead.type, "aead", sizeof(raead.type));
+ strncpy(raead.geniv, aead->geniv ?: "<built-in>", sizeof(raead.geniv));

raead.blocksize = alg->cra_blocksize;
raead.maxauthsize = aead->maxauthsize;
@@ -203,8 +202,8 @@ static int crypto_nivaead_report(struct
struct crypto_report_aead raead;
struct aead_alg *aead = &alg->cra_aead;

- snprintf(raead.type, CRYPTO_MAX_ALG_NAME, "%s", "nivaead");
- snprintf(raead.geniv, CRYPTO_MAX_ALG_NAME, "%s", aead->geniv);
+ strncpy(raead.type, "nivaead", sizeof(raead.type));
+ strncpy(raead.geniv, aead->geniv, sizeof(raead.geniv));

raead.blocksize = alg->cra_blocksize;
raead.maxauthsize = aead->maxauthsize;
--- a/crypto/ahash.c
+++ b/crypto/ahash.c
@@ -404,7 +404,7 @@ static int crypto_ahash_report(struct sk
{
struct crypto_report_hash rhash;

- snprintf(rhash.type, CRYPTO_MAX_ALG_NAME, "%s", "ahash");
+ strncpy(rhash.type, "ahash", sizeof(rhash.type));

rhash.blocksize = alg->cra_blocksize;
rhash.digestsize = __crypto_hash_alg_common(alg)->digestsize;
--- a/crypto/blkcipher.c
+++ b/crypto/blkcipher.c
@@ -499,9 +499,9 @@ static int crypto_blkcipher_report(struc
{
struct crypto_report_blkcipher rblkcipher;

- snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "blkcipher");
- snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s",
- alg->cra_blkcipher.geniv ?: "<default>");
+ strncpy(rblkcipher.type, "blkcipher", sizeof(rblkcipher.type));
+ strncpy(rblkcipher.geniv, alg->cra_blkcipher.geniv ?: "<default>",
+ sizeof(rblkcipher.geniv));

rblkcipher.blocksize = alg->cra_blocksize;
rblkcipher.min_keysize = alg->cra_blkcipher.min_keysize;
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -71,7 +71,7 @@ static int crypto_report_cipher(struct s
{
struct crypto_report_cipher rcipher;

- snprintf(rcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "cipher");
+ strncpy(rcipher.type, "cipher", sizeof(rcipher.type));

rcipher.blocksize = alg->cra_blocksize;
rcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
@@ -90,8 +90,7 @@ static int crypto_report_comp(struct sk_
{
struct crypto_report_comp rcomp;

- snprintf(rcomp.type, CRYPTO_MAX_ALG_NAME, "%s", "compression");
-
+ strncpy(rcomp.type, "compression", sizeof(rcomp.type));
NLA_PUT(skb, CRYPTOCFGA_REPORT_COMPRESS,
sizeof(struct crypto_report_comp), &rcomp);

@@ -104,12 +103,14 @@ nla_put_failure:
static int crypto_report_one(struct crypto_alg *alg,
struct crypto_user_alg *ualg, struct sk_buff *skb)
{
- memcpy(&ualg->cru_name, &alg->cra_name, sizeof(ualg->cru_name));
- memcpy(&ualg->cru_driver_name, &alg->cra_driver_name,
- sizeof(ualg->cru_driver_name));
- memcpy(&ualg->cru_module_name, module_name(alg->cra_module),
- CRYPTO_MAX_ALG_NAME);
+ strncpy(ualg->cru_name, alg->cra_name, sizeof(ualg->cru_name));
+ strncpy(ualg->cru_driver_name, alg->cra_driver_name,
+ sizeof(ualg->cru_driver_name));
+ strncpy(ualg->cru_module_name, module_name(alg->cra_module),
+ sizeof(ualg->cru_module_name));

+ ualg->cru_type = 0;
+ ualg->cru_mask = 0;
ualg->cru_flags = alg->cra_flags;
ualg->cru_refcnt = atomic_read(&alg->cra_refcnt);

@@ -118,8 +119,7 @@ static int crypto_report_one(struct cryp
if (alg->cra_flags & CRYPTO_ALG_LARVAL) {
struct crypto_report_larval rl;

- snprintf(rl.type, CRYPTO_MAX_ALG_NAME, "%s", "larval");
-
+ strncpy(rl.type, "larval", sizeof(rl.type));
NLA_PUT(skb, CRYPTOCFGA_REPORT_LARVAL,
sizeof(struct crypto_report_larval), &rl);

--- a/crypto/pcompress.c
+++ b/crypto/pcompress.c
@@ -53,8 +53,7 @@ static int crypto_pcomp_report(struct sk
{
struct crypto_report_comp rpcomp;

- snprintf(rpcomp.type, CRYPTO_MAX_ALG_NAME, "%s", "pcomp");
-
+ strncpy(rpcomp.type, "pcomp", sizeof(rpcomp.type));
NLA_PUT(skb, CRYPTOCFGA_REPORT_COMPRESS,
sizeof(struct crypto_report_comp), &rpcomp);

--- a/crypto/rng.c
+++ b/crypto/rng.c
@@ -65,7 +65,7 @@ static int crypto_rng_report(struct sk_b
{
struct crypto_report_rng rrng;

- snprintf(rrng.type, CRYPTO_MAX_ALG_NAME, "%s", "rng");
+ strncpy(rrng.type, "rng", sizeof(rrng.type));

rrng.seedsize = alg->cra_rng.seedsize;

--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -530,7 +530,8 @@ static int crypto_shash_report(struct sk
struct crypto_report_hash rhash;
struct shash_alg *salg = __crypto_shash_alg(alg);

- snprintf(rhash.type, CRYPTO_MAX_ALG_NAME, "%s", "shash");
+ strncpy(rhash.type, "shash", sizeof(rhash.type));
+
rhash.blocksize = alg->cra_blocksize;
rhash.digestsize = salg->digestsize;


2013-03-18 04:46:13

by Ben Hutchings

[permalink] [raw]
Subject: [ 78/82] block: use i_size_write() in bd_set_size()

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

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

From: Guo Chao <[email protected]>

commit d646a02a9d44d1421f273ae3923d97b47b918176 upstream.

blkdev_ioctl(GETBLKSIZE) uses i_size_read() to read size of block device.
If we update block size directly, reader may see intermediate result in
some machines and configurations. Use i_size_write() instead.

Signed-off-by: Guo Chao <[email protected]>
Cc: Alexander Viro <[email protected]>
Cc: Guo Chao <[email protected]>
Cc: M. Hindess <[email protected]>
Cc: Nikanth Karthikesan <[email protected]>
Cc: Jens Axboe <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/block_dev.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1064,7 +1064,9 @@ void bd_set_size(struct block_device *bd
{
unsigned bsize = bdev_logical_block_size(bdev);

- bdev->bd_inode->i_size = size;
+ mutex_lock(&bdev->bd_inode->i_mutex);
+ i_size_write(bdev->bd_inode, size);
+ mutex_unlock(&bdev->bd_inode->i_mutex);
while (bsize < PAGE_CACHE_SIZE) {
if (size & bsize)
break;

2013-03-18 04:46:10

by Ben Hutchings

[permalink] [raw]
Subject: [ 80/82] loopdev: remove an user triggerable oops

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

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

From: Guo Chao <[email protected]>

commit b1a6650406875b9097a032eed89af50682fe1160 upstream.

When loopdev is built as module and we pass an invalid parameter,
loop_init() will return directly without deregister misc device, which
will cause an oops when insert loop module next time because we left some
garbage in the misc device list.

Test case:
sudo modprobe loop max_part=1024
(failed due to invalid parameter)
sudo modprobe loop
(oops)

Clean up nicely to avoid such oops.

Signed-off-by: Guo Chao <[email protected]>
Cc: Alexander Viro <[email protected]>
Cc: Guo Chao <[email protected]>
Cc: M. Hindess <[email protected]>
Cc: Nikanth Karthikesan <[email protected]>
Cc: Jens Axboe <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/block/loop.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)

--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1834,11 +1834,15 @@ static int __init loop_init(void)
max_part = (1UL << part_shift) - 1;
}

- if ((1UL << part_shift) > DISK_MAX_PARTS)
- return -EINVAL;
+ if ((1UL << part_shift) > DISK_MAX_PARTS) {
+ err = -EINVAL;
+ goto misc_out;
+ }

- if (max_loop > 1UL << (MINORBITS - part_shift))
- return -EINVAL;
+ if (max_loop > 1UL << (MINORBITS - part_shift)) {
+ err = -EINVAL;
+ goto misc_out;
+ }

/*
* If max_loop is specified, create that many devices upfront.
@@ -1856,8 +1860,10 @@ static int __init loop_init(void)
range = 1UL << MINORBITS;
}

- if (register_blkdev(LOOP_MAJOR, "loop"))
- return -EIO;
+ if (register_blkdev(LOOP_MAJOR, "loop")) {
+ err = -EIO;
+ goto misc_out;
+ }

blk_register_region(MKDEV(LOOP_MAJOR, 0), range,
THIS_MODULE, loop_probe, NULL, NULL);
@@ -1870,6 +1876,10 @@ static int __init loop_init(void)

printk(KERN_INFO "loop: module loaded\n");
return 0;
+
+misc_out:
+ misc_deregister(&loop_misc);
+ return err;
}

static int loop_exit_cb(int id, void *ptr, void *data)

2013-03-18 04:30:22

by Ben Hutchings

[permalink] [raw]
Subject: [ 17/82] xen/pci: We dont do multiple MSIs.

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

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

From: Konrad Rzeszutek Wilk <[email protected]>

commit 884ac2978a295b7df3c4a686d3bff6932bbbb460 upstream.

There is no hypercall to setup multiple MSI per PCI device.
As such with these two new commits:
- 08261d87f7d1b6253ab3223756625a5c74532293
PCI/MSI: Enable multiple MSIs with pci_enable_msi_block_auto()
- 5ca72c4f7c412c2002363218901eba5516c476b1
AHCI: Support multiple MSIs

we would call the PHYSDEVOP_map_pirq 'nvec' times with the same
contents of the PCI device. Sander discovered that we would get
the same PIRQ value 'nvec' times and return said values to the
caller. That of course meant that the device was configured only
with one MSI and AHCI would fail with:

ahci 0000:00:11.0: version 3.0
xen: registering gsi 19 triggering 0 polarity 1
xen: --> pirq=19 -> irq=19 (gsi=19)
(XEN) [2013-02-27 19:43:07] IOAPIC[0]: Set PCI routing entry (6-19 -> 0x99 -> IRQ 19 Mode:1 Active:1)
ahci 0000:00:11.0: AHCI 0001.0200 32 slots 4 ports 6 Gbps 0xf impl SATA mode
ahci 0000:00:11.0: flags: 64bit ncq sntf ilck pm led clo pmp pio slum part
ahci: probe of 0000:00:11.0 failed with error -22

That is b/c in ahci_host_activate the second call to
devm_request_threaded_irq would return -EINVAL as we passed in
(on the second run) an IRQ that was never initialized.

Reported-and-Tested-by: Sander Eikelenboom <[email protected]>
Signed-off-by: Konrad Rzeszutek Wilk <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/x86/pci/xen.c | 9 +++++++++
1 file changed, 9 insertions(+)

--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -162,6 +162,9 @@ static int xen_setup_msi_irqs(struct pci
struct msi_desc *msidesc;
int *v;

+ if (type == PCI_CAP_ID_MSI && nvec > 1)
+ return 1;
+
v = kzalloc(sizeof(int) * max(1, nvec), GFP_KERNEL);
if (!v)
return -ENOMEM;
@@ -220,6 +223,9 @@ static int xen_hvm_setup_msi_irqs(struct
struct msi_desc *msidesc;
struct msi_msg msg;

+ if (type == PCI_CAP_ID_MSI && nvec > 1)
+ return 1;
+
list_for_each_entry(msidesc, &dev->msi_list, list) {
__read_msi_msg(msidesc, &msg);
pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) |
@@ -263,6 +269,9 @@ static int xen_initdom_setup_msi_irqs(st
int ret = 0;
struct msi_desc *msidesc;

+ if (type == PCI_CAP_ID_MSI && nvec > 1)
+ return 1;
+
list_for_each_entry(msidesc, &dev->msi_list, list) {
struct physdev_map_pirq map_irq;
domid_t domid;

2013-03-18 04:46:56

by Ben Hutchings

[permalink] [raw]
Subject: [ 77/82] xen-netfront: delay gARP until backend switches to Connected

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

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

From: Laszlo Ersek <[email protected]>

commit 08e34eb14fe4cfd934b5c169a7682a969457c4ea upstream.

After a guest is live migrated, the xen-netfront driver emits a gratuitous
ARP message, so that networking hardware on the target host's subnet can
take notice, and public routing to the guest is re-established. However,
if the packet appears on the backend interface before the backend is added
to the target host's bridge, the packet is lost, and the migrated guest's
peers become unable to talk to the guest.

A sufficient two-parts condition to prevent the above is:

(1) ensure that the backend only moves to Connected xenbus state after its
hotplug scripts completed, ie. the netback interface got added to the
bridge; and

(2) ensure the frontend only queues the gARP when it sees the backend move
to Connected.

These two together provide complete ordering. Sub-condition (1) is already
satisfied by commit f942dc2552b8 in Linus' tree, based on commit
6b0b80ca7165 from [1].

In general, the full condition is sufficient, not necessary, because,
according to [2], live migration has been working for a long time without
satisfying sub-condition (2). However, after 6b0b80ca7165 was backported
to the RHEL-5 host to ensure (1), (2) still proved necessary in the RHEL-6
guest. This patch intends to provide (2) for upstream.

The Reviewed-by line comes from [3].

[1] git://xenbits.xen.org/people/ianc/linux-2.6.git#upstream/dom0/backend/netback-history
[2] http://old-list-archives.xen.org/xen-devel/2011-06/msg01969.html
[3] http://old-list-archives.xen.org/xen-devel/2011-07/msg00484.html

Signed-off-by: Laszlo Ersek <[email protected]>
Reviewed-by: Ian Campbell <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/xen-netfront.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1707,7 +1707,6 @@ static void netback_changed(struct xenbu
case XenbusStateInitialised:
case XenbusStateReconfiguring:
case XenbusStateReconfigured:
- case XenbusStateConnected:
case XenbusStateUnknown:
case XenbusStateClosed:
break;
@@ -1718,6 +1717,9 @@ static void netback_changed(struct xenbu
if (xennet_connect(netdev) != 0)
break;
xenbus_switch_state(dev, XenbusStateConnected);
+ break;
+
+ case XenbusStateConnected:
netif_notify_peers(netdev);
break;


2013-03-18 04:47:20

by Ben Hutchings

[permalink] [raw]
Subject: [ 74/82] batman-adv: bat_socket_read missing checks

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

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

From: Paul Kot <[email protected]>

commit c00b6856fc642b234895cfabd15b289e76726430 upstream.

Writing a icmp_packet_rr and then reading icmp_packet can lead to kernel
memory corruption, if __user *buf is just below TASK_SIZE.

Signed-off-by: Paul Kot <[email protected]>
[[email protected]: made it checkpatch clean]
Signed-off-by: Sven Eckelmann <[email protected]>
Signed-off-by: Marek Lindner <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/batman-adv/icmp_socket.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -136,8 +136,8 @@ static ssize_t bat_socket_read(struct fi

spin_unlock_bh(&socket_client->lock);

- error = __copy_to_user(buf, &socket_packet->icmp_packet,
- socket_packet->icmp_len);
+ error = copy_to_user(buf, &socket_packet->icmp_packet,
+ socket_packet->icmp_len);

packet_len = socket_packet->icmp_len;
kfree(socket_packet);

2013-03-18 04:47:18

by Ben Hutchings

[permalink] [raw]
Subject: [ 72/82] USB: Rip out recursive call on warm port reset.

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

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

From: Sarah Sharp <[email protected]>

commit a24a6078754f28528bc91e7e7b3e6ae86bd936d8 upstream.

When a hot reset fails on a USB 3.0 port, the current port reset code
recursively calls hub_port_reset inside hub_port_wait_reset. This isn't
ideal, since we should avoid recursive calls in the kernel, and it also
doesn't allow us to issue multiple warm resets on reset failures.

Rip out the recursive call. Instead, add code to hub_port_reset to
issue a warm reset if the hot reset fails, and try multiple warm resets
before giving up on the port.

In hub_port_wait_reset, remove the recursive call and re-indent. The
code is basically the same, except:

1. It bails out early if the port has transitioned to Inactive or
Compliance Mode after the reset completed.

2. It doesn't consider a connect status change to be a failed reset. If
multiple warm resets needed to be issued, the connect status may have
changed, so we need to ignore that and look at the port link state
instead. hub_port_reset will now do that.

3. It unconditionally sets udev->speed on all types of successful
resets. The old recursive code would set the port speed when the second
hub_port_reset returned.

The old code did not handle connected devices needing a warm reset well.
There were only two situations that the old code handled correctly: an
empty port needing a warm reset, and a hot reset that migrated to a warm
reset.

When an empty port needed a warm reset, hub_port_reset was called with
the warm variable set. The code in hub_port_finish_reset would skip
telling the USB core and the xHC host that the device was reset, because
otherwise that would result in a NULL pointer dereference.

When a USB 3.0 device reset migrated to a warm reset, the recursive call
made the call stack look like this:

hub_port_reset(warm = false)
hub_wait_port_reset(warm = false)
hub_port_reset(warm = true)
hub_wait_port_reset(warm = true)
hub_port_finish_reset(warm = true)
(return up the call stack to the first wait)

hub_port_finish_reset(warm = false)

The old code didn't want to notify the USB core or the xHC host of device reset
twice, so it only did it in the second call to hub_port_finish_reset,
when warm was set to false. This was necessary because
before patch two ("USB: Ignore xHCI Reset Device status."), the USB core
would pay attention to the xHC Reset Device command error status, and
the second call would always fail.

Now that we no longer have the recursive call, and warm can change from
false to true in hub_port_reset, we need to have hub_port_finish_reset
unconditionally notify the USB core and the xHC of the device reset.

In hub_port_finish_reset, unconditionally clear the connect status
change (CSC) bit for USB 3.0 hubs when the port reset is done. If we
had to issue multiple warm resets for a device, that bit may have been
set if the device went into SS.Inactive and then was successfully warm
reset.

Signed-off-by: Sarah Sharp <[email protected]>
Acked-by: Alan Stern <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/core/hub.c | 150 ++++++++++++++++++++++--------------------------
1 files changed, 68 insertions(+), 82 deletions(-)

--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2148,73 +2148,35 @@ static int hub_port_wait_reset(struct us
if ((portstatus & USB_PORT_STAT_RESET))
goto delay;

- /*
- * Some buggy devices require a warm reset to be issued even
- * when the port appears not to be connected.
+ if (hub_port_warm_reset_required(hub, portstatus))
+ return -ENOTCONN;
+
+ /* Device went away? */
+ if (!(portstatus & USB_PORT_STAT_CONNECTION))
+ return -ENOTCONN;
+
+ /* bomb out completely if the connection bounced. A USB 3.0
+ * connection may bounce if multiple warm resets were issued,
+ * but the device may have successfully re-connected. Ignore it.
*/
- if (!warm) {
- /*
- * Some buggy devices can cause an NEC host controller
- * to transition to the "Error" state after a hot port
- * reset. This will show up as the port state in
- * "Inactive", and the port may also report a
- * disconnect. Forcing a warm port reset seems to make
- * the device work.
- *
- * See https://bugzilla.kernel.org/show_bug.cgi?id=41752
- */
- if (hub_port_warm_reset_required(hub, portstatus)) {
- int ret;
+ if (!hub_is_superspeed(hub->hdev) &&
+ (portchange & USB_PORT_STAT_C_CONNECTION))
+ return -ENOTCONN;

- if ((portchange & USB_PORT_STAT_C_CONNECTION))
- clear_port_feature(hub->hdev, port1,
- USB_PORT_FEAT_C_CONNECTION);
- if (portchange & USB_PORT_STAT_C_LINK_STATE)
- clear_port_feature(hub->hdev, port1,
- USB_PORT_FEAT_C_PORT_LINK_STATE);
- if (portchange & USB_PORT_STAT_C_RESET)
- clear_port_feature(hub->hdev, port1,
- USB_PORT_FEAT_C_RESET);
- dev_dbg(hub->intfdev, "hot reset failed, warm reset port %d\n",
- port1);
- ret = hub_port_reset(hub, port1,
- udev, HUB_BH_RESET_TIME,
- true);
- if ((portchange & USB_PORT_STAT_C_CONNECTION))
- clear_port_feature(hub->hdev, port1,
- USB_PORT_FEAT_C_CONNECTION);
- return ret;
- }
- /* Device went away? */
- if (!(portstatus & USB_PORT_STAT_CONNECTION))
- return -ENOTCONN;
-
- /* bomb out completely if the connection bounced */
- if ((portchange & USB_PORT_STAT_C_CONNECTION))
- return -ENOTCONN;
-
- if ((portstatus & USB_PORT_STAT_ENABLE)) {
- if (!udev)
- return 0;
-
- if (hub_is_wusb(hub))
- udev->speed = USB_SPEED_WIRELESS;
- else if (hub_is_superspeed(hub->hdev))
- udev->speed = USB_SPEED_SUPER;
- else if (portstatus & USB_PORT_STAT_HIGH_SPEED)
- udev->speed = USB_SPEED_HIGH;
- else if (portstatus & USB_PORT_STAT_LOW_SPEED)
- udev->speed = USB_SPEED_LOW;
- else
- udev->speed = USB_SPEED_FULL;
+ if ((portstatus & USB_PORT_STAT_ENABLE)) {
+ if (!udev)
return 0;
- }
- } else {
- if (!(portstatus & USB_PORT_STAT_CONNECTION) ||
- hub_port_warm_reset_required(hub,
- portstatus))
- return -ENOTCONN;

+ if (hub_is_wusb(hub))
+ udev->speed = USB_SPEED_WIRELESS;
+ else if (hub_is_superspeed(hub->hdev))
+ udev->speed = USB_SPEED_SUPER;
+ else if (portstatus & USB_PORT_STAT_HIGH_SPEED)
+ udev->speed = USB_SPEED_HIGH;
+ else if (portstatus & USB_PORT_STAT_LOW_SPEED)
+ udev->speed = USB_SPEED_LOW;
+ else
+ udev->speed = USB_SPEED_FULL;
return 0;
}

@@ -2232,23 +2194,21 @@ delay:
}

static void hub_port_finish_reset(struct usb_hub *hub, int port1,
- struct usb_device *udev, int *status, bool warm)
+ struct usb_device *udev, int *status)
{
switch (*status) {
case 0:
- if (!warm) {
- struct usb_hcd *hcd;
- /* TRSTRCY = 10 ms; plus some extra */
- msleep(10 + 40);
- if (udev) {
- update_devnum(udev, 0);
- hcd = bus_to_hcd(udev->bus);
- /* The xHC may think the device is already
- * reset, so ignore the status.
- */
- if (hcd->driver->reset_device)
- hcd->driver->reset_device(hcd, udev);
- }
+ /* TRSTRCY = 10 ms; plus some extra */
+ msleep(10 + 40);
+ if (udev) {
+ struct usb_hcd *hcd = bus_to_hcd(udev->bus);
+
+ update_devnum(udev, 0);
+ /* The xHC may think the device is already reset,
+ * so ignore the status.
+ */
+ if (hcd->driver->reset_device)
+ hcd->driver->reset_device(hcd, udev);
}
/* FALL THROUGH */
case -ENOTCONN:
@@ -2261,8 +2221,10 @@ static void hub_port_finish_reset(struct
USB_PORT_FEAT_C_BH_PORT_RESET);
clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_PORT_LINK_STATE);
+ clear_port_feature(hub->hdev, port1,
+ USB_PORT_FEAT_C_CONNECTION);
}
- if (!warm && udev)
+ if (udev)
usb_set_device_state(udev, *status
? USB_STATE_NOTATTACHED
: USB_STATE_DEFAULT);
@@ -2275,6 +2237,7 @@ static int hub_port_reset(struct usb_hub
struct usb_device *udev, unsigned int delay, bool warm)
{
int i, status;
+ u16 portchange, portstatus;

if (!hub_is_superspeed(hub->hdev)) {
if (warm) {
@@ -2306,10 +2269,33 @@ static int hub_port_reset(struct usb_hub
status);
}

- /* return on disconnect or reset */
+ /* Check for disconnect or reset */
if (status == 0 || status == -ENOTCONN || status == -ENODEV) {
- hub_port_finish_reset(hub, port1, udev, &status, warm);
- goto done;
+ hub_port_finish_reset(hub, port1, udev, &status);
+
+ if (!hub_is_superspeed(hub->hdev))
+ goto done;
+
+ /*
+ * If a USB 3.0 device migrates from reset to an error
+ * state, re-issue the warm reset.
+ */
+ if (hub_port_status(hub, port1,
+ &portstatus, &portchange) < 0)
+ goto done;
+
+ if (!hub_port_warm_reset_required(hub, portstatus))
+ goto done;
+
+ /*
+ * If the port is in SS.Inactive or Compliance Mode, the
+ * hot or warm reset failed. Try another warm reset.
+ */
+ if (!warm) {
+ dev_dbg(hub->intfdev, "hot reset failed, warm reset port %d\n",
+ port1);
+ warm = true;
+ }
}

dev_dbg (hub->intfdev,

2013-03-18 04:47:16

by Ben Hutchings

[permalink] [raw]
Subject: [ 75/82] batman-adv: Only write requested number of byte to user buffer

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

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

From: Sven Eckelmann <[email protected]>

commit b5a1eeef04cc7859f34dec9b72ea1b28e4aba07c upstream.

Don't write more than the requested number of bytes of an batman-adv icmp
packet to the userspace buffer. Otherwise unrelated userspace memory might get
overridden by the kernel.

Signed-off-by: Sven Eckelmann <[email protected]>
Signed-off-by: Marek Lindner <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/batman-adv/icmp_socket.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -136,10 +136,9 @@ static ssize_t bat_socket_read(struct fi

spin_unlock_bh(&socket_client->lock);

- error = copy_to_user(buf, &socket_packet->icmp_packet,
- socket_packet->icmp_len);
+ packet_len = min(count, socket_packet->icmp_len);
+ error = copy_to_user(buf, &socket_packet->icmp_packet, packet_len);

- packet_len = socket_packet->icmp_len;
kfree(socket_packet);

if (error)

2013-03-18 04:47:14

by Ben Hutchings

[permalink] [raw]
Subject: [ 66/82] hwmon: (lineage-pem) Add missing terminating entry for pem_[input|fan]_attributes

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

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

From: Axel Lin <[email protected]>

commit df069079c153d22adf6c28dcc0b1cf62bba75167 upstream.

Signed-off-by: Axel Lin <[email protected]>
Acked-by: Jean Delvare <[email protected]>
Signed-off-by: Guenter Roeck <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/hwmon/lineage-pem.c | 2 ++
1 file changed, 2 insertions(+)

--- a/drivers/hwmon/lineage-pem.c
+++ b/drivers/hwmon/lineage-pem.c
@@ -421,6 +421,7 @@ static struct attribute *pem_input_attri
&sensor_dev_attr_in2_input.dev_attr.attr,
&sensor_dev_attr_curr1_input.dev_attr.attr,
&sensor_dev_attr_power1_input.dev_attr.attr,
+ NULL
};

static const struct attribute_group pem_input_group = {
@@ -431,6 +432,7 @@ static struct attribute *pem_fan_attribu
&sensor_dev_attr_fan1_input.dev_attr.attr,
&sensor_dev_attr_fan2_input.dev_attr.attr,
&sensor_dev_attr_fan3_input.dev_attr.attr,
+ NULL
};

static const struct attribute_group pem_fan_group = {

2013-03-18 04:48:20

by Ben Hutchings

[permalink] [raw]
Subject: [ 71/82] USB: Prepare for refactoring by adding extra udev checks.

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

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

From: Sarah Sharp <[email protected]>

commit 2d4fa940f99663c82ba55b2244638833b388e4e2 upstream.

The next patch will refactor the hub port code to rip out the recursive
call to hub_port_reset on a failed hot reset. In preparation for that,
make sure all code paths can deal with being called with a NULL udev.
The usb_device will not be valid if warm reset was issued because a port
transitioned to the Inactive or Compliance Mode on a device connect.

This patch should have no effect on current behavior.

Signed-off-by: Sarah Sharp <[email protected]>
Acked-by: Alan Stern <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/core/hub.c | 21 +++++++++++++--------
1 files changed, 13 insertions(+), 8 deletions(-)

--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2194,6 +2194,9 @@ static int hub_port_wait_reset(struct us
return -ENOTCONN;

if ((portstatus & USB_PORT_STAT_ENABLE)) {
+ if (!udev)
+ return 0;
+
if (hub_is_wusb(hub))
udev->speed = USB_SPEED_WIRELESS;
else if (hub_is_superspeed(hub->hdev))
@@ -2237,13 +2240,15 @@ static void hub_port_finish_reset(struct
struct usb_hcd *hcd;
/* TRSTRCY = 10 ms; plus some extra */
msleep(10 + 40);
- update_devnum(udev, 0);
- hcd = bus_to_hcd(udev->bus);
- /* The xHC may think the device is already reset,
- * so ignore the status.
- */
- if (hcd->driver->reset_device)
- hcd->driver->reset_device(hcd, udev);
+ if (udev) {
+ update_devnum(udev, 0);
+ hcd = bus_to_hcd(udev->bus);
+ /* The xHC may think the device is already
+ * reset, so ignore the status.
+ */
+ if (hcd->driver->reset_device)
+ hcd->driver->reset_device(hcd, udev);
+ }
}
/* FALL THROUGH */
case -ENOTCONN:
@@ -2257,7 +2262,7 @@ static void hub_port_finish_reset(struct
clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_PORT_LINK_STATE);
}
- if (!warm)
+ if (!warm && udev)
usb_set_device_state(udev, *status
? USB_STATE_NOTATTACHED
: USB_STATE_DEFAULT);

2013-03-18 04:48:18

by Ben Hutchings

[permalink] [raw]
Subject: [ 69/82] Fix: compat_rw_copy_check_uvector() misuse in aio, readv, writev, and security keys

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

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

From: Mathieu Desnoyers <[email protected]>

commit 8aec0f5d4137532de14e6554fd5dd201ff3a3c49 upstream.

Looking at mm/process_vm_access.c:process_vm_rw() and comparing it to
compat_process_vm_rw() shows that the compatibility code requires an
explicit "access_ok()" check before calling
compat_rw_copy_check_uvector(). The same difference seems to appear when
we compare fs/read_write.c:do_readv_writev() to
fs/compat.c:compat_do_readv_writev().

This subtle difference between the compat and non-compat requirements
should probably be debated, as it seems to be error-prone. In fact,
there are two others sites that use this function in the Linux kernel,
and they both seem to get it wrong:

Now shifting our attention to fs/aio.c, we see that aio_setup_iocb()
also ends up calling compat_rw_copy_check_uvector() through
aio_setup_vectored_rw(). Unfortunately, the access_ok() check appears to
be missing. Same situation for
security/keys/compat.c:compat_keyctl_instantiate_key_iov().

I propose that we add the access_ok() check directly into
compat_rw_copy_check_uvector(), so callers don't have to worry about it,
and it therefore makes the compat call code similar to its non-compat
counterpart. Place the access_ok() check in the same location where
copy_from_user() can trigger a -EFAULT error in the non-compat code, so
the ABI behaviors are alike on both compat and non-compat.

While we are here, fix compat_do_readv_writev() so it checks for
compat_rw_copy_check_uvector() negative return values.

And also, fix a memory leak in compat_keyctl_instantiate_key_iov() error
handling.

Acked-by: Linus Torvalds <[email protected]>
Acked-by: Al Viro <[email protected]>
Signed-off-by: Mathieu Desnoyers <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/compat.c | 15 +++++++--------
mm/process_vm_access.c | 8 --------
security/keys/compat.c | 4 ++--
3 files changed, 9 insertions(+), 18 deletions(-)

--- a/fs/compat.c
+++ b/fs/compat.c
@@ -572,6 +572,10 @@ ssize_t compat_rw_copy_check_uvector(int
}
*ret_pointer = iov;

+ ret = -EFAULT;
+ if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector)))
+ goto out;
+
/*
* Single unix specification:
* We should -EINVAL if an element length is not >= 0 and fitting an
@@ -1103,17 +1107,12 @@ static ssize_t compat_do_readv_writev(in
if (!file->f_op)
goto out;

- ret = -EFAULT;
- if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector)))
- goto out;
-
- tot_len = compat_rw_copy_check_uvector(type, uvector, nr_segs,
+ ret = compat_rw_copy_check_uvector(type, uvector, nr_segs,
UIO_FASTIOV, iovstack, &iov, 1);
- if (tot_len == 0) {
- ret = 0;
+ if (ret <= 0)
goto out;
- }

+ tot_len = ret;
ret = rw_verify_area(type, file, pos, tot_len);
if (ret < 0)
goto out;
--- a/mm/process_vm_access.c
+++ b/mm/process_vm_access.c
@@ -434,12 +434,6 @@ compat_process_vm_rw(compat_pid_t pid,
if (flags != 0)
return -EINVAL;

- if (!access_ok(VERIFY_READ, lvec, liovcnt * sizeof(*lvec)))
- goto out;
-
- if (!access_ok(VERIFY_READ, rvec, riovcnt * sizeof(*rvec)))
- goto out;
-
if (vm_write)
rc = compat_rw_copy_check_uvector(WRITE, lvec, liovcnt,
UIO_FASTIOV, iovstack_l,
@@ -464,8 +458,6 @@ free_iovecs:
kfree(iov_r);
if (iov_l != iovstack_l)
kfree(iov_l);
-
-out:
return rc;
}

--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -40,12 +40,12 @@ long compat_keyctl_instantiate_key_iov(
ARRAY_SIZE(iovstack),
iovstack, &iov, 1);
if (ret < 0)
- return ret;
+ goto err;
if (ret == 0)
goto no_payload_free;

ret = keyctl_instantiate_key_common(id, iov, ioc, ret, ringid);
-
+err:
if (iov != iovstack)
kfree(iov);
return ret;

2013-03-18 04:48:16

by Ben Hutchings

[permalink] [raw]
Subject: [ 73/82] USB: Fix connected device switch to Inactive state.

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

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

From: Sarah Sharp <[email protected]>

commit d3b9d7a9051d7024a93c76a84b2f84b3b66ad6d5 upstream.

A USB 3.0 device can transition to the Inactive state if a U1 or U2 exit
transition fails. The current code in hub_events simply issues a warm
reset, but does not call any pre-reset or post-reset driver methods (or
unbind/rebind drivers without them). Therefore the drivers won't know
their device has just been reset.

hub_events should instead call usb_reset_device. This means
hub_port_reset now needs to figure out whether it should issue a warm
reset or a hot reset.

Remove the FIXME note about needing disconnect() for a NOTATTACHED
device. This patch fixes that.

Signed-off-by: Sarah Sharp <[email protected]>
Acked-by: Alan Stern <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/core/hub.c | 30 +++++++++++++++++++++++++-----
1 files changed, 25 insertions(+), 5 deletions(-)

--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2215,7 +2215,6 @@ static void hub_port_finish_reset(struct
case -ENODEV:
clear_port_feature(hub->hdev,
port1, USB_PORT_FEAT_C_RESET);
- /* FIXME need disconnect() for NOTATTACHED device */
if (hub_is_superspeed(hub->hdev)) {
clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_BH_PORT_RESET);
@@ -2249,6 +2248,18 @@ static int hub_port_reset(struct usb_hub
* Some companion controllers don't like it when they mix.
*/
down_read(&ehci_cf_port_reset_rwsem);
+ } else if (!warm) {
+ /*
+ * If the caller hasn't explicitly requested a warm reset,
+ * double check and see if one is needed.
+ */
+ status = hub_port_status(hub, port1,
+ &portstatus, &portchange);
+ if (status < 0)
+ goto done;
+
+ if (hub_port_warm_reset_required(hub, portstatus))
+ warm = true;
}

/* Reset the port */
@@ -3725,12 +3736,21 @@ static void hub_events(void)
*/
if (hub_port_warm_reset_required(hub, portstatus)) {
int status;
+ struct usb_device *udev =
+ hub->hdev->children[i - 1];

dev_dbg(hub_dev, "warm reset port %d\n", i);
- status = hub_port_reset(hub, i, NULL,
- HUB_BH_RESET_TIME, true);
- if (status < 0)
- hub_port_disable(hub, i, 1);
+ if (!udev) {
+ status = hub_port_reset(hub, i,
+ NULL, HUB_BH_RESET_TIME,
+ true);
+ if (status < 0)
+ hub_port_disable(hub, i, 1);
+ } else {
+ usb_lock_device(udev);
+ status = usb_reset_device(udev);
+ usb_unlock_device(udev);
+ }
connect_change = 0;
}


2013-03-18 04:48:15

by Ben Hutchings

[permalink] [raw]
Subject: [ 82/82] NLS: improve UTF8 -> UTF16 string conversion routine

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

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

From: Alan Stern <[email protected]>

commit 0720a06a7518c9d0c0125bd5d1f3b6264c55c3dd upstream.

The utf8s_to_utf16s conversion routine needs to be improved. Unlike
its utf16s_to_utf8s sibling, it doesn't accept arguments specifying
the maximum length of the output buffer or the endianness of its
16-bit output.

This patch (as1501) adds the two missing arguments, and adjusts the
only two places in the kernel where the function is called. A
follow-on patch will add a third caller that does utilize the new
capabilities.

The two conversion routines are still annoyingly inconsistent in the
way they handle invalid byte combinations. But that's a subject for a
different patch.

Signed-off-by: Alan Stern <[email protected]>
CC: Clemens Ladisch <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/hv/hv_kvp.c | 10 ++++++----
fs/fat/namei_vfat.c | 3 ++-
fs/nls/nls_base.c | 43 +++++++++++++++++++++++++++++++++----------
include/linux/nls.h | 5 +++--
4 files changed, 44 insertions(+), 17 deletions(-)

--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -212,11 +212,13 @@ kvp_respond_to_host(char *key, char *val
* The windows host expects the key/value pair to be encoded
* in utf16.
*/
- keylen = utf8s_to_utf16s(key_name, strlen(key_name),
- (wchar_t *)kvp_data->data.key);
+ keylen = utf8s_to_utf16s(key_name, strlen(key_name), UTF16_HOST_ENDIAN,
+ (wchar_t *) kvp_data->data.key,
+ HV_KVP_EXCHANGE_MAX_KEY_SIZE / 2);
kvp_data->data.key_size = 2*(keylen + 1); /* utf16 encoding */
- valuelen = utf8s_to_utf16s(value, strlen(value),
- (wchar_t *)kvp_data->data.value);
+ valuelen = utf8s_to_utf16s(value, strlen(value), UTF16_HOST_ENDIAN,
+ (wchar_t *) kvp_data->data.value,
+ HV_KVP_EXCHANGE_MAX_VALUE_SIZE / 2);
kvp_data->data.value_size = 2*(valuelen + 1); /* utf16 encoding */

kvp_data->data.value_type = REG_SZ; /* all our values are strings */
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -512,7 +512,8 @@ xlate_to_uni(const unsigned char *name,
int charlen;

if (utf8) {
- *outlen = utf8s_to_utf16s(name, len, (wchar_t *)outname);
+ *outlen = utf8s_to_utf16s(name, len, UTF16_HOST_ENDIAN,
+ (wchar_t *) outname, FAT_LFN_LEN + 2);
if (*outlen < 0)
return *outlen;
else if (*outlen > FAT_LFN_LEN)
--- a/fs/nls/nls_base.c
+++ b/fs/nls/nls_base.c
@@ -114,34 +114,57 @@ int utf32_to_utf8(unicode_t u, u8 *s, in
}
EXPORT_SYMBOL(utf32_to_utf8);

-int utf8s_to_utf16s(const u8 *s, int len, wchar_t *pwcs)
+static inline void put_utf16(wchar_t *s, unsigned c, enum utf16_endian endian)
+{
+ switch (endian) {
+ default:
+ *s = (wchar_t) c;
+ break;
+ case UTF16_LITTLE_ENDIAN:
+ *s = __cpu_to_le16(c);
+ break;
+ case UTF16_BIG_ENDIAN:
+ *s = __cpu_to_be16(c);
+ break;
+ }
+}
+
+int utf8s_to_utf16s(const u8 *s, int len, enum utf16_endian endian,
+ wchar_t *pwcs, int maxlen)
{
u16 *op;
int size;
unicode_t u;

op = pwcs;
- while (*s && len > 0) {
+ while (len > 0 && maxlen > 0 && *s) {
if (*s & 0x80) {
size = utf8_to_utf32(s, len, &u);
if (size < 0)
return -EINVAL;
+ s += size;
+ len -= size;

if (u >= PLANE_SIZE) {
+ if (maxlen < 2)
+ break;
u -= PLANE_SIZE;
- *op++ = (wchar_t) (SURROGATE_PAIR |
- ((u >> 10) & SURROGATE_BITS));
- *op++ = (wchar_t) (SURROGATE_PAIR |
+ put_utf16(op++, SURROGATE_PAIR |
+ ((u >> 10) & SURROGATE_BITS),
+ endian);
+ put_utf16(op++, SURROGATE_PAIR |
SURROGATE_LOW |
- (u & SURROGATE_BITS));
+ (u & SURROGATE_BITS),
+ endian);
+ maxlen -= 2;
} else {
- *op++ = (wchar_t) u;
+ put_utf16(op++, u, endian);
+ maxlen--;
}
- s += size;
- len -= size;
} else {
- *op++ = *s++;
+ put_utf16(op++, *s++, endian);
len--;
+ maxlen--;
}
}
return op - pwcs;
--- a/include/linux/nls.h
+++ b/include/linux/nls.h
@@ -43,7 +43,7 @@ enum utf16_endian {
UTF16_BIG_ENDIAN
};

-/* nls.c */
+/* nls_base.c */
extern int register_nls(struct nls_table *);
extern int unregister_nls(struct nls_table *);
extern struct nls_table *load_nls(char *);
@@ -52,7 +52,8 @@ extern struct nls_table *load_nls_defaul

extern int utf8_to_utf32(const u8 *s, int len, unicode_t *pu);
extern int utf32_to_utf8(unicode_t u, u8 *s, int maxlen);
-extern int utf8s_to_utf16s(const u8 *s, int len, wchar_t *pwcs);
+extern int utf8s_to_utf16s(const u8 *s, int len,
+ enum utf16_endian endian, wchar_t *pwcs, int maxlen);
extern int utf16s_to_utf8s(const wchar_t *pwcs, int len,
enum utf16_endian endian, u8 *s, int maxlen);


2013-03-18 04:30:15

by Ben Hutchings

[permalink] [raw]
Subject: [ 14/82] ath9k_htc: fix signal strength handling issues

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

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

From: Felix Fietkau <[email protected]>

commit 838f427955dcfd16858b0108ce29029da0d56a4e upstream.

The ath9k commit 2ef167557c0a26c88162ecffb017bfcc51eb7b29
(ath9k: fix signal strength reporting issues) fixed an issue where the
reported per-frame signal strength reported to mac80211 was being
overwritten with an internal average. The same issue is also present
in ath9k_htc.
In addition to preventing the driver from overwriting the value, this
commit also ensures that the internal average (which is used for ANI)
only tracks beacons of the AP that we're connected to.

Signed-off-by: Felix Fietkau <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
[bwh: Backported to 3.2: use compare_ether_addr() instead of
ether_addr_equal(), with opposite sense]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/wireless/ath/ath9k/htc.h | 1 +
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 18 +++++++++++-------
2 files changed, 12 insertions(+), 7 deletions(-)

--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -22,6 +22,7 @@
#include <linux/firmware.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include <linux/leds.h>
#include <linux/slab.h>
#include <net/mac80211.h>
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -1069,15 +1069,19 @@ static bool ath9k_rx_prepare(struct ath9

last_rssi = priv->rx.last_rssi;

- if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
- rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi,
- ATH_RSSI_EP_MULTIPLIER);
+ if (ieee80211_is_beacon(hdr->frame_control) &&
+ !is_zero_ether_addr(common->curbssid) &&
+ compare_ether_addr(hdr->addr3, common->curbssid) == 0) {
+ s8 rssi = rxbuf->rxstatus.rs_rssi;

- if (rxbuf->rxstatus.rs_rssi < 0)
- rxbuf->rxstatus.rs_rssi = 0;
+ if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
+ rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER);

- if (ieee80211_is_beacon(fc))
- priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;
+ if (rssi < 0)
+ rssi = 0;
+
+ priv->ah->stats.avgbrssi = rssi;
+ }

rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp);
rx_status->band = hw->conf.channel->band;

2013-03-18 04:49:41

by Ben Hutchings

[permalink] [raw]
Subject: [ 10/82] md: fix two bugs when attempting to resize RAID0 array.

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

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

From: NeilBrown <[email protected]>

commit a64685399181780998281fe07309a94b25dd24c3 upstream.

You cannot resize a RAID0 array (in terms of making the devices
bigger), but the code doesn't entirely stop you.
So:

disable setting of the available size on each device for
RAID0 and Linear devices. This must not change as doing so
can change the effective layout of data.

Make sure that the size that raid0_size() reports is accurate,
but rounding devices sizes to chunk sizes. As the device sizes
cannot change now, this isn't so important, but it is best to be
safe.

Without this change:
mdadm --grow /dev/md0 -z max
mdadm --grow /dev/md0 -Z max
then read to the end of the array

can cause a BUG in a RAID0 array.

These bugs have been present ever since it became possible
to resize any device, which is a long time. So the fix is
suitable for any -stable kerenl.

Signed-off-by: NeilBrown <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/md/md.c | 3 +++
drivers/md/raid0.c | 3 ++-
2 files changed, 5 insertions(+), 1 deletion(-)

--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2842,6 +2842,9 @@ rdev_size_store(struct md_rdev *rdev, co
} else if (!sectors)
sectors = (i_size_read(rdev->bdev->bd_inode) >> 9) -
rdev->data_offset;
+ if (!my_mddev->pers->resize)
+ /* Cannot change size for RAID0 or Linear etc */
+ return -EINVAL;
}
if (sectors < my_mddev->dev_sectors)
return -EINVAL; /* component must fit device */
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -330,7 +330,8 @@ static sector_t raid0_size(struct mddev
"%s does not support generic reshape\n", __func__);

list_for_each_entry(rdev, &mddev->disks, same_set)
- array_sectors += rdev->sectors;
+ array_sectors += (rdev->sectors &
+ ~(sector_t)(mddev->chunk_sectors-1));

return array_sectors;
}

2013-03-18 04:49:39

by Ben Hutchings

[permalink] [raw]
Subject: [ 01/82] Revert "powerpc/eeh: Fix crash when adding a device in a slot with DDW"

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

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

From: Ben Hutchings <[email protected]>

This reverts commit 066f289835f09a3f744d6bac96f25e25d20b3ded which was
6a040ce72598159a74969a2d01ab0ba5ee6536b3 upstream.

This was not needed and is not suitable for 3.2.y.

Reported-by: Michael Neuling <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/powerpc/include/asm/eeh.h | 3 ---
arch/powerpc/kernel/of_platform.c | 3 ---
arch/powerpc/kernel/pci-common.c | 7 ++-----
arch/powerpc/platforms/pseries/eeh.c | 24 +-----------------------
4 files changed, 3 insertions(+), 34 deletions(-)

diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index 21165a4..66ea9b8 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -61,7 +61,6 @@ void __init pci_addr_cache_build(void);
*/
void eeh_add_device_tree_early(struct device_node *);
void eeh_add_device_tree_late(struct pci_bus *);
-void eeh_add_sysfs_files(struct pci_bus *);

/**
* eeh_remove_device_recursive - undo EEH for device & children.
@@ -106,8 +105,6 @@ static inline void eeh_add_device_tree_early(struct device_node *dn) { }

static inline void eeh_add_device_tree_late(struct pci_bus *bus) { }

-static inline void eeh_add_sysfs_files(struct pci_bus *bus) { }
-
static inline void eeh_remove_bus_device(struct pci_dev *dev) { }
#define EEH_POSSIBLE_ERROR(val, type) (0)
#define EEH_IO_ERROR_VALUE(size) (-1UL)
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
index b10beef..e1612df 100644
--- a/arch/powerpc/kernel/of_platform.c
+++ b/arch/powerpc/kernel/of_platform.c
@@ -91,9 +91,6 @@ static int __devinit of_pci_phb_probe(struct platform_device *dev)
/* Add probed PCI devices to the device model */
pci_bus_add_devices(phb->bus);

- /* sysfs files should only be added after devices are added */
- eeh_add_sysfs_files(phb->bus);
-
return 0;
}

diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index a3cd949..458ed3b 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1536,14 +1536,11 @@ void pcibios_finish_adding_to_bus(struct pci_bus *bus)
pcibios_allocate_bus_resources(bus);
pcibios_claim_one_bus(bus);

- /* Fixup EEH */
- eeh_add_device_tree_late(bus);
-
/* Add new devices to global lists. Register in proc, sysfs. */
pci_bus_add_devices(bus);

- /* sysfs files should only be added after devices are added */
- eeh_add_sysfs_files(bus);
+ /* Fixup EEH */
+ eeh_add_device_tree_late(bus);
}
EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus);

diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 389e06b..5658690 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -1238,6 +1238,7 @@ static void eeh_add_device_late(struct pci_dev *dev)
pdn->pcidev = dev;

pci_addr_cache_insert_device(dev);
+ eeh_sysfs_add_device(dev);
}

void eeh_add_device_tree_late(struct pci_bus *bus)
@@ -1256,29 +1257,6 @@ void eeh_add_device_tree_late(struct pci_bus *bus)
EXPORT_SYMBOL_GPL(eeh_add_device_tree_late);

/**
- * eeh_add_sysfs_files - Add EEH sysfs files for the indicated PCI bus
- * @bus: PCI bus
- *
- * This routine must be used to add EEH sysfs files for PCI
- * devices which are attached to the indicated PCI bus. The PCI bus
- * is added after system boot through hotplug or dlpar.
- */
-void eeh_add_sysfs_files(struct pci_bus *bus)
-{
- struct pci_dev *dev;
-
- list_for_each_entry(dev, &bus->devices, bus_list) {
- eeh_sysfs_add_device(dev);
- if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
- struct pci_bus *subbus = dev->subordinate;
- if (subbus)
- eeh_add_sysfs_files(subbus);
- }
- }
-}
-EXPORT_SYMBOL_GPL(eeh_add_sysfs_files);
-
-/**
* eeh_remove_device - undo EEH setup for the indicated pci device
* @dev: pci device to be removed
*


2013-03-18 05:00:47

by Ben Hutchings

[permalink] [raw]
Subject: Re: [ 00/82] 3.2.41-stable review

This is the combined patch for 3.2.41-rc1 relative to 3.2.40.

Ben.

--
Ben Hutchings
Never attribute to conspiracy what can adequately be explained by stupidity.


Attachments:
linux-3.2.41-rc1.patch (129.04 kB)
signature.asc (828.00 B)
This is a digitally signed message part
Download all attachments

2013-03-19 03:09:12

by Ben Hutchings

[permalink] [raw]
Subject: Re: [ 45/82] USB: EHCI: dont check DMA values in QH overlays

On Mon, 2013-03-18 at 04:22 +0000, Ben Hutchings wrote:
> 3.2-stable review patch. If anyone has any objections, please let me know.
>
> ------------------
>
> From: Alan Stern <[email protected]>
>
> commit feca7746d5d9e84b105a613b7f3b6ad00d327372 upstream.
>
> This patch (as1661) fixes a rather obscure bug in ehci-hcd. In a
> couple of places, the driver compares the DMA address stored in a QH's
> overlay region with the address of a particular qTD, in order to see
> whether that qTD is the one currently being processed by the hardware.
> (If it is then the status in the QH's overlay region is more
> up-to-date than the status in the qTD, and if it isn't then the
> overlay's value needs to be adjusted when the QH is added back to the
> active schedule.)
>
> However, DMA address in the overlay region isn't always valid. It
> sometimes will contain a stale value, which may happen by coincidence
> to be equal to a qTD's DMA address. Instead of checking the DMA
> address, we should check whether the overlay region is active and
> valid. The patch tests the ACTIVE bit in the overlay, and clears this
> bit when the overlay becomes invalid (which happens when the
> currently-executing URB is unlinked).
>
> This is the second part of a fix for the regression reported at:
>
> https://bugs.launchpad.net/bugs/1088733

Alan, the first part (commit 6402c796d3b4 aka as1660) didn't apply and I
couldn't see how to adapt it for 3.2. Does this second part have any
value without the first? Or, if you could provide a backport of the
first part, that would be very much appreciated.

Ben.

> Signed-off-by: Alan Stern <[email protected]>
> Reported-by: Joseph Salisbury <[email protected]>
> Reported-and-tested-by: Stephen Thirlwall <[email protected]>
> Signed-off-by: Greg Kroah-Hartman <[email protected]>
> Signed-off-by: Ben Hutchings <[email protected]>
> ---
> drivers/usb/host/ehci-q.c | 18 +++++++++++++-----
> 1 file changed, 13 insertions(+), 5 deletions(-)
>
> --- a/drivers/usb/host/ehci-q.c
> +++ b/drivers/usb/host/ehci-q.c
> @@ -135,7 +135,7 @@ qh_refresh (struct ehci_hcd *ehci, struc
> * qtd is updated in qh_completions(). Update the QH
> * overlay here.
> */
> - if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) {
> + if (qh->hw->hw_token & ACTIVE_BIT(ehci)) {
> qh->hw->hw_qtd_next = qtd->hw_next;
> qtd = NULL;
> }
> @@ -444,11 +444,19 @@ qh_completions (struct ehci_hcd *ehci, s
> else if (last_status == -EINPROGRESS && !urb->unlinked)
> continue;
>
> - /* qh unlinked; token in overlay may be most current */
> - if (state == QH_STATE_IDLE
> - && cpu_to_hc32(ehci, qtd->qtd_dma)
> - == hw->hw_current) {
> + /*
> + * If this was the active qtd when the qh was unlinked
> + * and the overlay's token is active, then the overlay
> + * hasn't been written back to the qtd yet so use its
> + * token instead of the qtd's. After the qtd is
> + * processed and removed, the overlay won't be valid
> + * any more.
> + */
> + if (state == QH_STATE_IDLE &&
> + qh->qtd_list.next == &qtd->qtd_list &&
> + (hw->hw_token & ACTIVE_BIT(ehci))) {
> token = hc32_to_cpu(ehci, hw->hw_token);
> + hw->hw_token &= ~ACTIVE_BIT(ehci);
>
> /* An unlink may leave an incomplete
> * async transaction in the TT buffer.
>


--
Ben Hutchings
When you say `I wrote a program that crashed Windows', people just stare ...
and say `Hey, I got those with the system, *for free*'. - Linus Torvalds


Attachments:
signature.asc (828.00 B)
This is a digitally signed message part

2013-03-19 15:27:16

by Alan Stern

[permalink] [raw]
Subject: Re: [ 45/82] USB: EHCI: dont check DMA values in QH overlays

On Tue, 19 Mar 2013, Ben Hutchings wrote:

> On Mon, 2013-03-18 at 04:22 +0000, Ben Hutchings wrote:
> > 3.2-stable review patch. If anyone has any objections, please let me know.
> >
> > ------------------
> >
> > From: Alan Stern <[email protected]>
> >
> > commit feca7746d5d9e84b105a613b7f3b6ad00d327372 upstream.
> >
> > This patch (as1661) fixes a rather obscure bug in ehci-hcd. In a
> > couple of places, the driver compares the DMA address stored in a QH's
> > overlay region with the address of a particular qTD, in order to see
> > whether that qTD is the one currently being processed by the hardware.
> > (If it is then the status in the QH's overlay region is more
> > up-to-date than the status in the qTD, and if it isn't then the
> > overlay's value needs to be adjusted when the QH is added back to the
> > active schedule.)
> >
> > However, DMA address in the overlay region isn't always valid. It
> > sometimes will contain a stale value, which may happen by coincidence
> > to be equal to a qTD's DMA address. Instead of checking the DMA
> > address, we should check whether the overlay region is active and
> > valid. The patch tests the ACTIVE bit in the overlay, and clears this
> > bit when the overlay becomes invalid (which happens when the
> > currently-executing URB is unlinked).
> >
> > This is the second part of a fix for the regression reported at:
> >
> > https://bugs.launchpad.net/bugs/1088733
>
> Alan, the first part (commit 6402c796d3b4 aka as1660) didn't apply and I
> couldn't see how to adapt it for 3.2. Does this second part have any
> value without the first? Or, if you could provide a backport of the
> first part, that would be very much appreciated.

Without the first part, the second part can actually be dangerous.
Under the circumstances, I think it is best to apply neither.

Alan Stern

2013-03-19 20:31:41

by Ben Hutchings

[permalink] [raw]
Subject: Re: [ 45/82] USB: EHCI: dont check DMA values in QH overlays

On Tue, 2013-03-19 at 11:27 -0400, Alan Stern wrote:
> On Tue, 19 Mar 2013, Ben Hutchings wrote:
>
> > On Mon, 2013-03-18 at 04:22 +0000, Ben Hutchings wrote:
> > > 3.2-stable review patch. If anyone has any objections, please let me know.
> > >
> > > ------------------
> > >
> > > From: Alan Stern <[email protected]>
> > >
> > > commit feca7746d5d9e84b105a613b7f3b6ad00d327372 upstream.
> > >
> > > This patch (as1661) fixes a rather obscure bug in ehci-hcd. In a
> > > couple of places, the driver compares the DMA address stored in a QH's
> > > overlay region with the address of a particular qTD, in order to see
> > > whether that qTD is the one currently being processed by the hardware.
> > > (If it is then the status in the QH's overlay region is more
> > > up-to-date than the status in the qTD, and if it isn't then the
> > > overlay's value needs to be adjusted when the QH is added back to the
> > > active schedule.)
> > >
> > > However, DMA address in the overlay region isn't always valid. It
> > > sometimes will contain a stale value, which may happen by coincidence
> > > to be equal to a qTD's DMA address. Instead of checking the DMA
> > > address, we should check whether the overlay region is active and
> > > valid. The patch tests the ACTIVE bit in the overlay, and clears this
> > > bit when the overlay becomes invalid (which happens when the
> > > currently-executing URB is unlinked).
> > >
> > > This is the second part of a fix for the regression reported at:
> > >
> > > https://bugs.launchpad.net/bugs/1088733
> >
> > Alan, the first part (commit 6402c796d3b4 aka as1660) didn't apply and I
> > couldn't see how to adapt it for 3.2. Does this second part have any
> > value without the first? Or, if you could provide a backport of the
> > first part, that would be very much appreciated.
>
> Without the first part, the second part can actually be dangerous.
> Under the circumstances, I think it is best to apply neither.

Thanks, I've dropped this.

Ben.

--
Ben Hutchings
When you say `I wrote a program that crashed Windows', people just stare ...
and say `Hey, I got those with the system, *for free*'. - Linus Torvalds


Attachments:
signature.asc (828.00 B)
This is a digitally signed message part