2013-04-22 14:54:09

by Ben Hutchings

[permalink] [raw]
Subject: [00/75] 3.2.44-rc1 review

This is the start of the stable review cycle for the 3.2.44 release.
There are 75 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 Apr 24 15:00:00 UTC 2013.
Anything received after that time might be too late.

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

Ben.

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

Alban Bedel (1):
ASoC: wm8903: Fix the bypass to HP/LINEOUT when no DAC or ADC is running
[f1ca493b0b5e8f42d3b2dc8877860db2983f47b6]

Andrew Honig (1):
KVM: Allow cross page reads and writes from cached translations.
[8f964525a121f2ff2df948dac908dcc65be21b5b]

Andy Honig (3):
KVM: Fix bounds checking in ioapic indirect register reads (CVE-2013-1798)
[a2c118bfab8bc6b8bb213abfc35201e441693d55]
KVM: x86: Convert MSR_KVM_SYSTEM_TIME to use gfn_to_hva_cache functions (CVE-2013-1797)
[0b79459b482e85cb7426aa7da683a9f2c97aeae1]
KVM: x86: fix for buffer overflow in handling of MSR_KVM_SYSTEM_TIME (CVE-2013-1796)
[c300aa64ddf57d9c5d9c898a64b36877345dd4a9]

Arnd Bergmann (1):
block: avoid using uninitialized value in from queue_var_store
[c678ef5286ddb5cf70384ad5af286b0afc9b73e1]

Boris Ostrovsky (1):
x86, mm: Patch out arch_flush_lazy_mmu_mode() when running on bare metal
[511ba86e1d386f671084b5d0e6f110bb30b8eeb2]

Carsten Emde (3):
drm/i915: panel: invert brightness acer aspire 5734z
[5a15ab5b93e4a3ebcd4fa6c76cf646a45e9cf806]
drm/i915: panel: invert brightness via parameter
[7bd90909bbf9ce7c40e1da3d72b97b93839c188a]
drm/i915: panel: invert brightness via quirk
[4dca20efb1a9c2efefc28ad2867e5d6c3f5e1955]

Chris Mason (1):
Btrfs: fix race between mmap writes and compression
[4adaa611020fa6ac65b0ac8db78276af4ec04e63]

Christoph Fritz (1):
can: sja1000: fix handling on dt properties on little endian systems
[0443de5fbf224abf41f688d8487b0c307dc5a4b4]

Dave Airlie (1):
fbcon: fix locking harder
[054430e773c9a1e26f38e30156eff02dedfffc17]

David Henningsson (1):
ALSA: hda - fix typo in proc output
[aeb3a97222832e5457c4b72d72235098ce4bfe8d]

David Woodhouse (1):
mtd: Disable mtdchar mmap on MMU systems
[f5cf8f07423b2677cebebcebc863af77223a4972]

Egbert Eich (1):
DRM/i915: Add QUIRK_INVERT_BRIGHTNESS for NCR machines.
[5f85f176c2f1c9d2a23f60ca0b99e4d0aa5a26a7]

Eldad Zack (1):
ALSA: usb-audio: fix endianness bug in snd_nativeinstruments_*
[889d66848b12d891248b03abcb2a42047f8e172a]

Emese Revfy (1):
kernel/signal.c: stop info leak via the tkill and the tgkill syscalls
[b9e146d8eb3b9ecae5086d373b50fa0c1f3e7f0f]

Felix Fietkau (2):
ath9k_htc: accept 1.x firmware newer than 1.3
[319e7bd96aca64a478f3aad40711c928405b8b77]
ath9k_hw: change AR9580 initvals to fix a stability issue
[f09a878511997c25a76bf111a32f6b8345a701a5]

Hayeswang (1):
r8169: fix auto speed down issue
[e2409d83434d77874b461b78af6a19cd6e6a1280]

Huacai Chen (1):
PM / reboot: call syscore_shutdown() after disable_nonboot_cpus()
[6f389a8f1dd22a24f3d9afc2812b30d639e94625]

Illia Ragozin (1):
ARM: 7696/1: Fix kexec by setting outer_cache.inv_all for Feroceon
[cd272d1ea71583170e95dde02c76166c7f9017e6]

Jan Kiszka (1):
ftrace: Consistently restore trace function on sysctl enabling
[5000c418840b309251c5887f0b56503aae30f84c]

Jani Nikula (3):
drm/i915: add quirk to invert brightness on Packard Bell NCL20
[5559ecadad5a73b27f863e92f4b4f369501dce6f]
drm/i915: add quirk to invert brightness on eMachines G725
[1ffff60320879830e469e26062c18f75236822ba]
drm/i915: add quirk to invert brightness on eMachines e725
[01e3a8feb40e54b962a20fa7eb595c5efef5e109]

Jay Estabrook (1):
alpha: Add irongate_io to PCI bus resources
[aa8b4be3ac049c8b1df2a87e4d1d902ccfc1f7a9]

Jean-Christophe PLAGNIOL-VILLARD (1):
of: introduce helper to manage boolean
[fa4d34ccd0914ac87336ea2c17e9370dfecef286]

Johan Hovold (15):
USB: ark3116: fix use-after-free in TIOCMIWAIT
[5018860321dc7a9e50a75d5f319bc981298fb5b7]
USB: ch341: fix use-after-free in TIOCMIWAIT
[fa1e11d5231c001c80a479160b5832933c5d35fb]
USB: cypress_m8: fix use-after-free in TIOCMIWAIT
[356050d8b1e526db093e9d2c78daf49d6bf418e3]
USB: ftdi_sio: fix use-after-free in TIOCMIWAIT
[71ccb9b01981fabae27d3c98260ea4613207618e]
USB: io_edgeport: fix use-after-free in TIOCMIWAIT
[333576255d4cfc53efd056aad438568184b36af6]
USB: io_ti: fix use-after-free in TIOCMIWAIT
[7b2459690584f239650a365f3411ba2ec1c6d1e0]
USB: mct_u232: fix use-after-free in TIOCMIWAIT
[cf1d24443677a0758cfa88ca40f24858b89261c0]
USB: mos7840: fix broken TIOCMIWAIT
[e670c6af12517d08a403487b1122eecf506021cf]
USB: mos7840: fix use-after-free in TIOCMIWAIT
[a14430db686b8e459e1cf070a6ecf391515c9ab9]
USB: oti6858: fix use-after-free in TIOCMIWAIT
[8edfdab37157d2683e51b8be5d3d5697f66a9f7b]
USB: pl2303: fix use-after-free in TIOCMIWAIT
[40509ca982c00c4b70fc00be887509feca0bff15]
USB: serial: add modem-status-change wait queue
[e5b33dc9d16053c2ae4c2c669cf008829530364b]
USB: spcp8x5: fix use-after-free in TIOCMIWAIT
[dbcea7615d8d7d58f6ff49d2c5568113f70effe9]
USB: ssu100: fix use-after-free in TIOCMIWAIT
[43a66b4c417ad15f6d2f632ce67ad195bdf999e8]
USB: ti_usb_3410_5052: fix use-after-free in TIOCMIWAIT
[fc98ab873aa3dbe783ce56a2ffdbbe7c7609521a]

Josef Bacik (1):
Btrfs: make sure nbytes are right after log replay
[4bc4bee4595662d8bff92180d5c32e3313a704b0]

Jussi Kivilinna (1):
crypto: gcm - fix assumption that assoc has one segment
[d3dde52209ab571e4e2ec26c66f85ad1355f7475]

Li Fei (1):
hwspinlock: fix __hwspin_lock_request error path
[c10b90d85a5126d25c89cbaa50dc9fdd1c4d001a]

Linus Torvalds (3):
kobject: fix kset_find_obj() race with concurrent last kobject_put()
[a49b7e82cab0f9b41f483359be83f44fbb6b4979]
net: fix incorrect credentials passing
[83f1b4ba917db5dc5a061a44b3403ddb6e783494]
spinlocks and preemption points need to be at least compiler barriers
[386afc91144b36b42117b0092893f15bc8798a80]

Maxim Mikityanskiy (1):
msi-wmi: Fix memory leak
[51c94491c82c3d9029f6e87a1a153db321d88e35]

Michael Bohan (1):
hrtimer: Don't reinitialize a cpu_base lock on CPU_UP
[84cc8fd2fe65866e49d70b38b3fdf7219dd92fe0]

Michael Wolf (1):
powerpc: pSeries_lpar_hpte_remove fails from Adjunct partition being performed before the ANDCOND test
[9fb2640159f9d4f5a2a9d60e490482d4cbecafdb]

Ming Lei (1):
USB: serial: fix hang when opening port
[eba0e3c3a0ba7b96f01cbe997680f6a4401a0bfc]

Namhyung Kim (2):
tracing: Fix double free when function profile init failed
[83e03b3fe4daffdebbb42151d5410d730ae50bd1]
tracing: Fix possible NULL pointer dereferences
[6a76f8c0ab19f215af2a3442870eeb5f0e81998d]

Naoya Horiguchi (1):
hugetlbfs: add swap entry check in follow_hugetlb_page()
[9cc3a5bd40067b9a0fbd49199d0780463fc2140f]

Nicholas Bellinger (2):
target: Fix MAINTENANCE_IN service action CDB checks to use lower 5 bits
[ba539743b70cd160c84bab1c82910d0789b820f8]
target: Fix incorrect fallthrough of ALUA Standby/Offline/Transition CDBs
[30f359a6f9da65a66de8cadf959f0f4a0d498bba]

Rainer Koenig (1):
ALSA: hda - Enabling Realtek ALC 671 codec
[1d87caa69c04008e09f5ff47b5e6acb6116febc7]

Richard Guy Briggs (1):
thermal: return an error on failure to register thermal class
[da28d966f6aa942ae836d09729f76a1647932309]

Russell King (1):
ARM: Do 15e0d9e37c (ARM: pm: let platforms select cpu_suspend support) properly
[b6c7aabd923a17af993c5a5d5d7995f0b27c000a]

Samu Kallio (1):
x86, mm, paravirt: Fix vmalloc_fault oops during lazy MMU updates
[1160c2779b826c6f5c08e5cc542de58fd1f667d5]

Shan Hai (2):
libata: Set max sector to 65535 for Slimtype DVD A DS8A8SH drive
[a32450e127fc6e5ca6d958ceb3cfea4d30a00846]
libata: Use integer return value for atapi_command_packet_set
[d8668fcb0b257d9fdcfbe5c172a99b8d85e1cd82]

Suleiman Souhlal (1):
vfs: Revert spurious fix to spinning prevention in prune_icache_sb
[5b55d708335a9e3e4f61f2dadf7511502205ccd1]

Tejun Heo (1):
sched: Convert BUG_ON()s in try_to_wake_up_local() to WARN_ON_ONCE()s
[383efcd00053ec40023010ce5034bd702e7ab373]

Thomas Gleixner (1):
sched_clock: Prevent 64bit inatomicity on 32bit systems
[a1cbcaa9ea87b87a96b9fc465951dcf36e459ca2]

Thomas Hellstrom (1):
kref: Implement kref_get_unless_zero v3
[4b20db3de8dab005b07c74161cb041db8c5ff3a7]

Tim Gardner (1):
rt2x00: rt2x00pci_regbusy_read() - only print register access failure once
[83589b30f1e1dc9898986293c9336b8ce1705dec]

Vyacheslav Dubeyko (1):
hfsplus: fix potential overflow in hfsplus_file_truncate()
[12f267a20aecf8b84a2a9069b9011f1661c779b4]

Wei Yongjun (1):
can: gw: use kmem_cache_free() instead of kfree()
[3480a2125923e4b7a56d79efc76743089bf273fc]

Will Deacon (1):
ARM: 7698/1: perf: fix group validation when using enable_on_exec
[cb2d8b342aa084d1f3ac29966245dec9163677fb]

Wu Fengguang (1):
writeback: fix dirtied pages accounting on redirty
[2f800fbd777b792de54187088df19a7df0251254]

Youquan Song (1):
ata_piix: Fix DVD not dectected at some Haswell platforms
[b55f84e2d527182e7c611d466cd0bb6ddce201de]

Documentation/kernel-parameters.txt | 14 +++++
Makefile | 4 +-
arch/alpha/kernel/sys_nautilus.c | 5 ++
arch/arm/kernel/perf_event.c | 5 +-
arch/arm/mm/cache-feroceon-l2.c | 1 +
arch/arm/mm/proc-arm920.S | 2 +-
arch/arm/mm/proc-arm926.S | 2 +-
arch/arm/mm/proc-sa1100.S | 2 +-
arch/arm/mm/proc-v6.S | 2 +-
arch/arm/mm/proc-xsc3.S | 2 +-
arch/arm/mm/proc-xscale.S | 2 +-
arch/powerpc/platforms/pseries/lpar.c | 8 ++-
arch/x86/include/asm/kvm_host.h | 4 +-
arch/x86/include/asm/paravirt.h | 5 +-
arch/x86/include/asm/paravirt_types.h | 2 +
arch/x86/kernel/paravirt.c | 25 ++++-----
arch/x86/kvm/x86.c | 43 +++++++--------
arch/x86/lguest/boot.c | 1 +
arch/x86/mm/fault.c | 6 ++-
arch/x86/xen/mmu.c | 1 +
block/blk-sysfs.c | 2 +
crypto/gcm.c | 17 ++++--
drivers/ata/ata_piix.c | 14 ++++-
drivers/ata/libata-core.c | 4 ++
drivers/gpu/drm/i915/i915_drv.h | 1 +
drivers/gpu/drm/i915/intel_display.c | 55 ++++++++++++++++++++
drivers/gpu/drm/i915/intel_panel.c | 24 +++++++++
drivers/gpu/vga/vga_switcheroo.c | 3 ++
drivers/hwspinlock/hwspinlock_core.c | 2 +
drivers/mtd/mtdchar.c | 6 ++-
drivers/net/can/sja1000/sja1000_of_platform.c | 31 ++++++-----
drivers/net/ethernet/realtek/r8169.c | 28 ++++++++--
.../net/wireless/ath/ath9k/ar9580_1p0_initvals.h | 2 +-
drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 +-
drivers/net/wireless/rt2x00/rt2x00pci.c | 4 +-
drivers/platform/x86/msi-wmi.c | 4 +-
drivers/target/target_core_alua.c | 9 ++--
drivers/target/target_core_transport.c | 3 +-
drivers/thermal/thermal_sys.c | 1 +
drivers/usb/serial/ark3116.c | 10 ++--
drivers/usb/serial/ch341.c | 11 ++--
drivers/usb/serial/cypress_m8.c | 14 ++---
drivers/usb/serial/ftdi_sio.c | 19 +++----
drivers/usb/serial/io_edgeport.c | 12 +++--
drivers/usb/serial/io_ti.c | 12 ++---
drivers/usb/serial/mct_u232.c | 13 ++---
drivers/usb/serial/mos7840.c | 16 +++---
drivers/usb/serial/oti6858.c | 10 ++--
drivers/usb/serial/pl2303.c | 11 ++--
drivers/usb/serial/spcp8x5.c | 9 ++--
drivers/usb/serial/ssu100.c | 12 +++--
drivers/usb/serial/ti_usb_3410_5052.c | 10 ++--
drivers/usb/serial/usb-serial.c | 1 +
drivers/video/console/fbcon.c | 11 ++--
drivers/video/fbmem.c | 2 +
fs/btrfs/extent_io.c | 33 ++++++++++++
fs/btrfs/extent_io.h | 2 +
fs/btrfs/inode.c | 14 +++++
fs/btrfs/tree-log.c | 48 ++++++++++++++---
fs/hfsplus/extents.c | 2 +-
fs/inode.c | 2 +-
include/linux/ata.h | 2 +-
include/linux/kref.h | 21 ++++++++
include/linux/kvm_host.h | 2 +-
include/linux/kvm_types.h | 1 +
include/linux/libata.h | 1 +
include/linux/of.h | 16 ++++++
include/linux/preempt.h | 18 ++++---
include/linux/socket.h | 1 +
include/linux/spinlock_up.h | 29 +++++++----
include/linux/usb/serial.h | 2 +
include/linux/writeback.h | 2 +
include/net/scm.h | 2 +-
kernel/hrtimer.c | 3 +-
kernel/sched.c | 6 ++-
kernel/sched_clock.c | 26 +++++++++
kernel/signal.c | 2 +-
kernel/sys.c | 3 +-
kernel/trace/ftrace.c | 19 +++----
lib/kobject.c | 9 +++-
mm/hugetlb.c | 12 ++++-
mm/page-writeback.c | 19 +++++++
net/can/gw.c | 6 +--
net/core/sock.c | 14 +++++
sound/pci/hda/hda_codec.c | 2 +-
sound/pci/hda/patch_realtek.c | 4 +-
sound/soc/codecs/wm8903.c | 2 +
sound/usb/mixer_quirks.c | 4 +-
sound/usb/quirks.c | 2 +-
virt/kvm/ioapic.c | 7 ++-
virt/kvm/kvm_main.c | 47 +++++++++++++----
91 files changed, 679 insertions(+), 227 deletions(-)

--
Ben Hutchings
Klipstein's 4th Law of Prototyping and Production:
A fail-safe circuit will destroy others.


2013-04-22 14:29:28

by Ben Hutchings

[permalink] [raw]
Subject: [09/75] USB: mct_u232: fix use-after-free in TIOCMIWAIT

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Johan Hovold <[email protected]>

commit cf1d24443677a0758cfa88ca40f24858b89261c0 upstream.

Use the port wait queue and make sure to check the serial disconnected
flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue
itself) can be gone when waking up after a disconnect.

Signed-off-by: Johan Hovold <[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/serial/mct_u232.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)

--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -168,8 +168,6 @@ struct mct_u232_private {
unsigned char last_msr; /* Modem Status Register */
unsigned int rx_flags; /* Throttling flags */
struct async_icount icount;
- wait_queue_head_t msr_wait; /* for handling sleeping while waiting
- for msr change to happen */
};

#define THROTTLED 0x01
@@ -449,7 +447,6 @@ static int mct_u232_startup(struct usb_s
if (!priv)
return -ENOMEM;
spin_lock_init(&priv->lock);
- init_waitqueue_head(&priv->msr_wait);
usb_set_serial_port_data(serial->port[0], priv);

init_waitqueue_head(&serial->port[0]->write_wait);
@@ -675,7 +672,7 @@ static void mct_u232_read_int_callback(s
tty_kref_put(tty);
}
#endif
- wake_up_interruptible(&priv->msr_wait);
+ wake_up_interruptible(&port->delta_msr_wait);
spin_unlock_irqrestore(&priv->lock, flags);
exit:
retval = usb_submit_urb(urb, GFP_ATOMIC);
@@ -896,13 +893,17 @@ static int mct_u232_ioctl(struct tty_st
cprev = mct_u232_port->icount;
spin_unlock_irqrestore(&mct_u232_port->lock, flags);
for ( ; ; ) {
- prepare_to_wait(&mct_u232_port->msr_wait,
+ prepare_to_wait(&port->delta_msr_wait,
&wait, TASK_INTERRUPTIBLE);
schedule();
- finish_wait(&mct_u232_port->msr_wait, &wait);
+ finish_wait(&port->delta_msr_wait, &wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
+
+ if (port->serial->disconnected)
+ return -EIO;
+
spin_lock_irqsave(&mct_u232_port->lock, flags);
cnow = mct_u232_port->icount;
spin_unlock_irqrestore(&mct_u232_port->lock, flags);

2013-04-22 14:29:32

by Ben Hutchings

[permalink] [raw]
Subject: [14/75] USB: spcp8x5: fix use-after-free in TIOCMIWAIT

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Johan Hovold <[email protected]>

commit dbcea7615d8d7d58f6ff49d2c5568113f70effe9 upstream.

Use the port wait queue and make sure to check the serial disconnected
flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue
itself) can be gone when waking up after a disconnect.

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[bwh: Backported to 3.2: adjust context, indentation]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/spcp8x5.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -163,7 +163,6 @@ static struct usb_driver spcp8x5_driver
struct spcp8x5_private {
spinlock_t lock;
enum spcp8x5_type type;
- wait_queue_head_t delta_msr_wait;
u8 line_control;
u8 line_status;
};
@@ -197,7 +196,6 @@ static int spcp8x5_startup(struct usb_se
goto cleanup;

spin_lock_init(&priv->lock);
- init_waitqueue_head(&priv->delta_msr_wait);
priv->type = type;
usb_set_serial_port_data(serial->port[i] , priv);
}
@@ -502,7 +500,7 @@ static void spcp8x5_process_read_urb(str
priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
spin_unlock_irqrestore(&priv->lock, flags);
/* wake up the wait for termios */
- wake_up_interruptible(&priv->delta_msr_wait);
+ wake_up_interruptible(&port->delta_msr_wait);

if (!urb->actual_length)
return;
@@ -552,12 +550,15 @@ static int spcp8x5_wait_modem_info(struc

while (1) {
/* wake up in bulk read */
- interruptible_sleep_on(&priv->delta_msr_wait);
+ interruptible_sleep_on(&port->delta_msr_wait);

/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;

+ if (port->serial->disconnected)
+ return -EIO;
+
spin_lock_irqsave(&priv->lock, flags);
status = priv->line_status;
spin_unlock_irqrestore(&priv->lock, flags);

2013-04-22 14:29:47

by Ben Hutchings

[permalink] [raw]
Subject: [20/75] libata: Use integer return value for atapi_command_packet_set

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Shan Hai <[email protected]>

commit d8668fcb0b257d9fdcfbe5c172a99b8d85e1cd82 upstream.

The function returns type of ATAPI drives so it should return integer value.
The commit 4dce8ba94c7 (libata: Use 'bool' return value for ata_id_XXX) since
v2.6.39 changed the type of return value from int to bool, the change would
cause all of the ATAPI class drives to be treated as TYPE_TAPE and the
max_sectors of the drives to be set to 65535 because of the commit
f8d8e5799b7(libata: increase 128 KB / cmd limit for ATAPI tape drives), for the
function would return true for all ATAPI class drives and the TYPE_TAPE is
defined as 0x01.

Signed-off-by: Shan Hai <[email protected]>
Signed-off-by: Jeff Garzik <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
include/linux/ata.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -937,7 +937,7 @@ static inline int atapi_cdb_len(const u1
}
}

-static inline bool atapi_command_packet_set(const u16 *dev_id)
+static inline int atapi_command_packet_set(const u16 *dev_id)
{
return (dev_id[ATA_ID_CONFIG] >> 8) & 0x1f;
}

2013-04-22 14:29:51

by Ben Hutchings

[permalink] [raw]
Subject: [69/75] fbcon: fix locking harder

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Dave Airlie <[email protected]>

commit 054430e773c9a1e26f38e30156eff02dedfffc17 upstream.

Okay so Alan's patch handled the case where there was no registered fbcon,
however the other path entered in set_con2fb_map pit.

In there we called fbcon_takeover, but we also took the console lock in a couple
of places. So push the console lock out to the callers of set_con2fb_map,

this means fbmem and switcheroo needed to take the lock around the fb notifier
entry points that lead to this.

This should fix the efifb regression seen by Maarten.

Tested-by: Maarten Lankhorst <[email protected]>
Tested-by: Lu Hua <[email protected]>
Signed-off-by: Dave Airlie <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/vga/vga_switcheroo.c | 3 +++
drivers/video/console/fbcon.c | 11 ++++++++---
drivers/video/fbmem.c | 2 ++
3 files changed, 13 insertions(+), 3 deletions(-)

--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -26,6 +26,7 @@
#include <linux/fb.h>

#include <linux/pci.h>
+#include <linux/console.h>
#include <linux/vga_switcheroo.h>

struct vga_switcheroo_client {
@@ -256,8 +257,10 @@ static int vga_switchto_stage2(struct vg

if (new_client->fb_info) {
struct fb_event event;
+ console_lock();
event.info = new_client->fb_info;
fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event);
+ console_unlock();
}

ret = vgasr_priv.handler->switchto(new_client->id);
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -843,6 +843,8 @@ static void con2fb_init_display(struct v
*
* Maps a virtual console @unit to a frame buffer device
* @newidx.
+ *
+ * This should be called with the console lock held.
*/
static int set_con2fb_map(int unit, int newidx, int user)
{
@@ -860,7 +862,7 @@ static int set_con2fb_map(int unit, int

if (!search_for_mapped_con() || !con_is_bound(&fb_con)) {
info_idx = newidx;
- return fbcon_takeover(0);
+ return do_fbcon_takeover(0);
}

if (oldidx != -1)
@@ -868,7 +870,6 @@ static int set_con2fb_map(int unit, int

found = search_fb_in_map(newidx);

- console_lock();
con2fb_map[unit] = newidx;
if (!err && !found)
err = con2fb_acquire_newinfo(vc, info, unit, oldidx);
@@ -895,7 +896,6 @@ static int set_con2fb_map(int unit, int
if (!search_fb_in_map(info_idx))
info_idx = newidx;

- console_unlock();
return err;
}

@@ -3026,6 +3026,7 @@ static inline int fbcon_unbind(void)
}
#endif /* CONFIG_VT_HW_CONSOLE_BINDING */

+/* called with console_lock held */
static int fbcon_fb_unbind(int idx)
{
int i, new_idx = -1, ret = 0;
@@ -3052,6 +3053,7 @@ static int fbcon_fb_unbind(int idx)
return ret;
}

+/* called with console_lock held */
static int fbcon_fb_unregistered(struct fb_info *info)
{
int i, idx;
@@ -3089,6 +3091,7 @@ static int fbcon_fb_unregistered(struct
return 0;
}

+/* called with console_lock held */
static void fbcon_remap_all(int idx)
{
int i;
@@ -3133,6 +3136,7 @@ static inline void fbcon_select_primary(
}
#endif /* CONFIG_FRAMEBUFFER_DETECT_PRIMARY */

+/* called with console_lock held */
static int fbcon_fb_registered(struct fb_info *info)
{
int ret = 0, i, idx;
@@ -3285,6 +3289,7 @@ static int fbcon_event_notify(struct not
ret = fbcon_fb_unregistered(info);
break;
case FB_EVENT_SET_CONSOLE_MAP:
+ /* called with console lock held */
con2fb = event->data;
ret = set_con2fb_map(con2fb->console - 1,
con2fb->framebuffer, 1);
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1154,8 +1154,10 @@ static long do_fb_ioctl(struct fb_info *
event.data = &con2fb;
if (!lock_fb_info(info))
return -ENODEV;
+ console_lock();
event.info = info;
ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event);
+ console_unlock();
unlock_fb_info(info);
break;
case FBIOBLANK:

2013-04-22 14:29:53

by Ben Hutchings

[permalink] [raw]
Subject: [60/75] drm/i915: add quirk to invert brightness on eMachines G725

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Jani Nikula <[email protected]>

commit 1ffff60320879830e469e26062c18f75236822ba upstream.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=59628
Reported-by: Roland Gruber <[email protected]>
Signed-off-by: Jani Nikula <[email protected]>
Signed-off-by: Daniel Vetter <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/i915/intel_display.c | 3 +++
1 file changed, 3 insertions(+)

--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8907,6 +8907,9 @@ struct intel_quirk intel_quirks[] = {

/* Acer Aspire 5734Z must invert backlight brightness */
{ 0x2a42, 0x1025, 0x0459, quirk_invert_brightness },
+
+ /* Acer/eMachines G725 */
+ { 0x2a42, 0x1025, 0x0210, quirk_invert_brightness },
};

static void intel_init_quirks(struct drm_device *dev)

2013-04-22 14:29:55

by Ben Hutchings

[permalink] [raw]
Subject: [66/75] block: avoid using uninitialized value in from queue_var_store

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Arnd Bergmann <[email protected]>

commit c678ef5286ddb5cf70384ad5af286b0afc9b73e1 upstream.

As found by gcc-4.8, the QUEUE_SYSFS_BIT_FNS macro creates functions
that use a value generated by queue_var_store independent of whether
that value was set or not.

block/blk-sysfs.c: In function 'queue_store_nonrot':
block/blk-sysfs.c:244:385: warning: 'val' may be used uninitialized in this function [-Wmaybe-uninitialized]

Unlike most other such warnings, this one is not a false positive,
writing any non-number string into the sysfs files indeed has
an undefined result, rather than returning an error.

Signed-off-by: Arnd Bergmann <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
block/blk-sysfs.c | 2 ++
1 file changed, 2 insertions(+)

--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -200,6 +200,8 @@ queue_store_##name(struct request_queue
unsigned long val; \
ssize_t ret; \
ret = queue_var_store(&val, page, count); \
+ if (ret < 0) \
+ return ret; \
if (neg) \
val = !val; \
\

2013-04-22 14:30:05

by Ben Hutchings

[permalink] [raw]
Subject: [53/75] thermal: return an error on failure to register thermal class

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Richard Guy Briggs <[email protected]>

commit da28d966f6aa942ae836d09729f76a1647932309 upstream.

The return code from the registration of the thermal class is used to
unallocate resources, but this failure isn't passed back to the caller of
thermal_init. Return this failure back to the caller.

This bug was introduced in changeset 4cb18728 which overwrote the return code
when the variable was re-used to catch the return code of the registration of
the genetlink thermal socket family.

Signed-off-by: Richard Guy Briggs <[email protected]>
Signed-off-by: Zhang Rui <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/thermal/thermal_sys.c | 1 +
1 file changed, 1 insertion(+)

--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -1399,6 +1399,7 @@ static int __init thermal_init(void)
idr_destroy(&thermal_cdev_idr);
mutex_destroy(&thermal_idr_lock);
mutex_destroy(&thermal_list_lock);
+ return result;
}
result = genetlink_init();
return result;

2013-04-22 14:29:59

by Ben Hutchings

[permalink] [raw]
Subject: [58/75] drm/i915: panel: invert brightness acer aspire 5734z

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Carsten Emde <[email protected]>

commit 5a15ab5b93e4a3ebcd4fa6c76cf646a45e9cf806 upstream.

Mark the Acer Aspire 5734Z that this machines requires the module to
invert the panel backlight brightness value after reading from and prior
to writing to the PCI configuration space.

Signed-off-by: Carsten Emde <[email protected]>
Acked-by: Chris Wilson <[email protected]>
Signed-off-by: Daniel Vetter <[email protected]>
Acked-by: Jani Nikula <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/i915/intel_display.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8832,7 +8832,8 @@ static void quirk_ssc_force_disable(stru
}

/*
- * A machine may need to invert the panel backlight brightness value
+ * A machine (e.g. Acer Aspire 5734Z) may need to invert the panel backlight
+ * brightness value
*/
static void quirk_invert_brightness(struct drm_device *dev)
{
@@ -8874,6 +8875,9 @@ struct intel_quirk intel_quirks[] = {

/* Sony Vaio Y cannot use SSC on LVDS */
{ 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable },
+
+ /* Acer Aspire 5734Z must invert backlight brightness */
+ { 0x2a42, 0x1025, 0x0459, quirk_invert_brightness },
};

static void intel_init_quirks(struct drm_device *dev)

2013-04-22 14:30:35

by Ben Hutchings

[permalink] [raw]
Subject: [34/75] x86, mm, paravirt: Fix vmalloc_fault oops during lazy MMU updates

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Samu Kallio <[email protected]>

commit 1160c2779b826c6f5c08e5cc542de58fd1f667d5 upstream.

In paravirtualized x86_64 kernels, vmalloc_fault may cause an oops
when lazy MMU updates are enabled, because set_pgd effects are being
deferred.

One instance of this problem is during process mm cleanup with memory
cgroups enabled. The chain of events is as follows:

- zap_pte_range enables lazy MMU updates
- zap_pte_range eventually calls mem_cgroup_charge_statistics,
which accesses the vmalloc'd mem_cgroup per-cpu stat area
- vmalloc_fault is triggered which tries to sync the corresponding
PGD entry with set_pgd, but the update is deferred
- vmalloc_fault oopses due to a mismatch in the PUD entries

The OOPs usually looks as so:

------------[ cut here ]------------
kernel BUG at arch/x86/mm/fault.c:396!
invalid opcode: 0000 [#1] SMP
.. snip ..
CPU 1
Pid: 10866, comm: httpd Not tainted 3.6.10-4.fc18.x86_64 #1
RIP: e030:[<ffffffff816271bf>] [<ffffffff816271bf>] vmalloc_fault+0x11f/0x208
.. snip ..
Call Trace:
[<ffffffff81627759>] do_page_fault+0x399/0x4b0
[<ffffffff81004f4c>] ? xen_mc_extend_args+0xec/0x110
[<ffffffff81624065>] page_fault+0x25/0x30
[<ffffffff81184d03>] ? mem_cgroup_charge_statistics.isra.13+0x13/0x50
[<ffffffff81186f78>] __mem_cgroup_uncharge_common+0xd8/0x350
[<ffffffff8118aac7>] mem_cgroup_uncharge_page+0x57/0x60
[<ffffffff8115fbc0>] page_remove_rmap+0xe0/0x150
[<ffffffff8115311a>] ? vm_normal_page+0x1a/0x80
[<ffffffff81153e61>] unmap_single_vma+0x531/0x870
[<ffffffff81154962>] unmap_vmas+0x52/0xa0
[<ffffffff81007442>] ? pte_mfn_to_pfn+0x72/0x100
[<ffffffff8115c8f8>] exit_mmap+0x98/0x170
[<ffffffff810050d9>] ? __raw_callee_save_xen_pmd_val+0x11/0x1e
[<ffffffff81059ce3>] mmput+0x83/0xf0
[<ffffffff810624c4>] exit_mm+0x104/0x130
[<ffffffff8106264a>] do_exit+0x15a/0x8c0
[<ffffffff810630ff>] do_group_exit+0x3f/0xa0
[<ffffffff81063177>] sys_exit_group+0x17/0x20
[<ffffffff8162bae9>] system_call_fastpath+0x16/0x1b

Calling arch_flush_lazy_mmu_mode immediately after set_pgd makes the
changes visible to the consistency checks.

RedHat-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=914737
Tested-by: Josh Boyer <[email protected]>
Reported-and-Tested-by: Krishna Raman <[email protected]>
Signed-off-by: Samu Kallio <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Tested-by: Konrad Rzeszutek Wilk <[email protected]>
Signed-off-by: Konrad Rzeszutek Wilk <[email protected]>
Signed-off-by: H. Peter Anvin <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/x86/mm/fault.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -377,10 +377,12 @@ static noinline __kprobes int vmalloc_fa
if (pgd_none(*pgd_ref))
return -1;

- if (pgd_none(*pgd))
+ if (pgd_none(*pgd)) {
set_pgd(pgd, *pgd_ref);
- else
+ arch_flush_lazy_mmu_mode();
+ } else {
BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
+ }

/*
* Below here mismatches are bugs because these lower tables

2013-04-22 14:30:33

by Ben Hutchings

[permalink] [raw]
Subject: [28/75] ftrace: Consistently restore trace function on sysctl enabling

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Jan Kiszka <[email protected]>

commit 5000c418840b309251c5887f0b56503aae30f84c upstream.

If we reenable ftrace via syctl, we currently set ftrace_trace_function
based on the previous simplistic algorithm. This is inconsistent with
what update_ftrace_function does. So better call that helper instead.

Link: http://lkml.kernel.org/r/[email protected]

Signed-off-by: Jan Kiszka <[email protected]>
Signed-off-by: Steven Rostedt <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
kernel/trace/ftrace.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)

--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -3964,12 +3964,8 @@ ftrace_enable_sysctl(struct ctl_table *t
ftrace_startup_sysctl();

/* we are starting ftrace again */
- if (ftrace_ops_list != &ftrace_list_end) {
- if (ftrace_ops_list->next == &ftrace_list_end)
- ftrace_trace_function = ftrace_ops_list->func;
- else
- ftrace_trace_function = ftrace_ops_list_func;
- }
+ if (ftrace_ops_list != &ftrace_list_end)
+ update_ftrace_function();

} else {
/* stopping ftrace calls (just send to ftrace_stub) */

2013-04-22 14:30:30

by Ben Hutchings

[permalink] [raw]
Subject: [30/75] can: gw: use kmem_cache_free() instead of kfree()

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Wei Yongjun <[email protected]>

commit 3480a2125923e4b7a56d79efc76743089bf273fc upstream.

Memory allocated by kmem_cache_alloc() should be freed using
kmem_cache_free(), not kfree().

Signed-off-by: Wei Yongjun <[email protected]>
Acked-by: Oliver Hartkopp <[email protected]>
Signed-off-by: Marc Kleine-Budde <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/can/gw.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

--- a/net/can/gw.c
+++ b/net/can/gw.c
@@ -436,7 +436,7 @@ static int cgw_notifier(struct notifier_
if (gwj->src.dev == dev || gwj->dst.dev == dev) {
hlist_del(&gwj->list);
cgw_unregister_filter(gwj);
- kfree(gwj);
+ kmem_cache_free(cgw_cache, gwj);
}
}
}
@@ -850,7 +850,7 @@ static void cgw_remove_all_jobs(void)
hlist_for_each_entry_safe(gwj, n, nx, &cgw_list, list) {
hlist_del(&gwj->list);
cgw_unregister_filter(gwj);
- kfree(gwj);
+ kmem_cache_free(cgw_cache, gwj);
}
}

@@ -903,7 +903,7 @@ static int cgw_remove_job(struct sk_buff

hlist_del(&gwj->list);
cgw_unregister_filter(gwj);
- kfree(gwj);
+ kmem_cache_free(cgw_cache, gwj);
err = 0;
break;
}

2013-04-22 14:31:55

by Ben Hutchings

[permalink] [raw]
Subject: [19/75] rt2x00: rt2x00pci_regbusy_read() - only print register access failure once

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Tim Gardner <[email protected]>

commit 83589b30f1e1dc9898986293c9336b8ce1705dec upstream.

BugLink: http://bugs.launchpad.net/bugs/1128840

It appears that when this register read fails it never recovers, so
I think there is no need to repeat the same error message ad infinitum.

Cc: Ivo van Doorn <[email protected]>
Cc: Gertjan van Wingerde <[email protected]>
Cc: Helmut Schaa <[email protected]>
Cc: "John W. Linville" <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Tim Gardner <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/wireless/rt2x00/rt2x00pci.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -52,8 +52,8 @@ int rt2x00pci_regbusy_read(struct rt2x00
udelay(REGISTER_BUSY_DELAY);
}

- ERROR(rt2x00dev, "Indirect register access failed: "
- "offset=0x%.08x, value=0x%.08x\n", offset, *reg);
+ printk_once(KERN_ERR "%s() Indirect register access failed: "
+ "offset=0x%.08x, value=0x%.08x\n", __func__, offset, *reg);
*reg = ~0;

return 0;

2013-04-22 14:31:53

by Ben Hutchings

[permalink] [raw]
Subject: [26/75] powerpc: pSeries_lpar_hpte_remove fails from Adjunct partition being performed before the ANDCOND test

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Michael Wolf <[email protected]>

commit 9fb2640159f9d4f5a2a9d60e490482d4cbecafdb upstream.

Some versions of pHyp will perform the adjunct partition test before the
ANDCOND test. The result of this is that H_RESOURCE can be returned and
cause the BUG_ON condition to occur. The HPTE is not removed. So add a
check for H_RESOURCE, it is ok if this HPTE is not removed as
pSeries_lpar_hpte_remove is looking for an HPTE to remove and not a
specific HPTE to remove. So it is ok to just move on to the next slot
and try again.

Signed-off-by: Michael Wolf <[email protected]>
Signed-off-by: Stephen Rothwell <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/powerpc/platforms/pseries/lpar.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -186,7 +186,13 @@ static long pSeries_lpar_hpte_remove(uns
(0x1UL << 4), &dummy1, &dummy2);
if (lpar_rc == H_SUCCESS)
return i;
- BUG_ON(lpar_rc != H_NOT_FOUND);
+
+ /*
+ * The test for adjunct partition is performed before the
+ * ANDCOND test. H_RESOURCE may be returned, so we need to
+ * check for that as well.
+ */
+ BUG_ON(lpar_rc != H_NOT_FOUND && lpar_rc != H_RESOURCE);

slot_offset++;
slot_offset &= 0x7;

2013-04-22 14:30:27

by Ben Hutchings

[permalink] [raw]
Subject: [35/75] x86, mm: Patch out arch_flush_lazy_mmu_mode() when running on bare metal

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Boris Ostrovsky <[email protected]>

commit 511ba86e1d386f671084b5d0e6f110bb30b8eeb2 upstream.

Invoking arch_flush_lazy_mmu_mode() results in calls to
preempt_enable()/disable() which may have performance impact.

Since lazy MMU is not used on bare metal we can patch away
arch_flush_lazy_mmu_mode() so that it is never called in such
environment.

[ hpa: the previous patch "Fix vmalloc_fault oops during lazy MMU
updates" may cause a minor performance regression on
bare metal. This patch resolves that performance regression. It is
somewhat unclear to me if this is a good -stable candidate. ]

Signed-off-by: Boris Ostrovsky <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Tested-by: Josh Boyer <[email protected]>
Tested-by: Konrad Rzeszutek Wilk <[email protected]>
Acked-by: Borislav Petkov <[email protected]>
Signed-off-by: Konrad Rzeszutek Wilk <[email protected]>
Signed-off-by: H. Peter Anvin <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/x86/include/asm/paravirt.h | 5 ++++-
arch/x86/include/asm/paravirt_types.h | 2 ++
arch/x86/kernel/paravirt.c | 25 +++++++++++++------------
arch/x86/lguest/boot.c | 1 +
arch/x86/xen/mmu.c | 1 +
5 files changed, 21 insertions(+), 13 deletions(-)

--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -740,7 +740,10 @@ static inline void arch_leave_lazy_mmu_m
PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave);
}

-void arch_flush_lazy_mmu_mode(void);
+static inline void arch_flush_lazy_mmu_mode(void)
+{
+ PVOP_VCALL0(pv_mmu_ops.lazy_mode.flush);
+}

static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx,
phys_addr_t phys, pgprot_t flags)
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -91,6 +91,7 @@ struct pv_lazy_ops {
/* Set deferred update mode, used for batching operations. */
void (*enter)(void);
void (*leave)(void);
+ void (*flush)(void);
};

struct pv_time_ops {
@@ -680,6 +681,7 @@ void paravirt_end_context_switch(struct

void paravirt_enter_lazy_mmu(void);
void paravirt_leave_lazy_mmu(void);
+void paravirt_flush_lazy_mmu(void);

void _paravirt_nop(void);
u32 _paravirt_ident_32(u32);
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -261,6 +261,18 @@ void paravirt_leave_lazy_mmu(void)
leave_lazy(PARAVIRT_LAZY_MMU);
}

+void paravirt_flush_lazy_mmu(void)
+{
+ preempt_disable();
+
+ if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) {
+ arch_leave_lazy_mmu_mode();
+ arch_enter_lazy_mmu_mode();
+ }
+
+ preempt_enable();
+}
+
void paravirt_start_context_switch(struct task_struct *prev)
{
BUG_ON(preemptible());
@@ -290,18 +302,6 @@ enum paravirt_lazy_mode paravirt_get_laz
return percpu_read(paravirt_lazy_mode);
}

-void arch_flush_lazy_mmu_mode(void)
-{
- preempt_disable();
-
- if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) {
- arch_leave_lazy_mmu_mode();
- arch_enter_lazy_mmu_mode();
- }
-
- preempt_enable();
-}
-
struct pv_info pv_info = {
.name = "bare hardware",
.paravirt_enabled = 0,
@@ -475,6 +475,7 @@ struct pv_mmu_ops pv_mmu_ops = {
.lazy_mode = {
.enter = paravirt_nop,
.leave = paravirt_nop,
+ .flush = paravirt_nop,
},

.set_fixmap = native_set_fixmap,
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -1328,6 +1328,7 @@ __init void lguest_init(void)
pv_mmu_ops.read_cr3 = lguest_read_cr3;
pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu;
pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mmu_mode;
+ pv_mmu_ops.lazy_mode.flush = paravirt_flush_lazy_mmu;
pv_mmu_ops.pte_update = lguest_pte_update;
pv_mmu_ops.pte_update_defer = lguest_pte_update;

--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -2079,6 +2079,7 @@ static const struct pv_mmu_ops xen_mmu_o
.lazy_mode = {
.enter = paravirt_enter_lazy_mmu,
.leave = xen_leave_lazy_mmu,
+ .flush = paravirt_flush_lazy_mmu,
},

.set_fixmap = xen_set_fixmap,

2013-04-22 14:32:58

by Ben Hutchings

[permalink] [raw]
Subject: [24/75] ALSA: usb-audio: fix endianness bug in snd_nativeinstruments_*

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Eldad Zack <[email protected]>

commit 889d66848b12d891248b03abcb2a42047f8e172a upstream.

The usb_control_msg() function expects __u16 types and performs
the endianness conversions by itself.
However, in three places, a conversion is performed before it is
handed over to usb_control_msg(), which leads to a double conversion
(= no conversion):
* snd_usb_nativeinstruments_boot_quirk()
* snd_nativeinstruments_control_get()
* snd_nativeinstruments_control_put()

Caught by sparse:

sound/usb/mixer_quirks.c:512:38: warning: incorrect type in argument 6 (different base types)
sound/usb/mixer_quirks.c:512:38: expected unsigned short [unsigned] [usertype] index
sound/usb/mixer_quirks.c:512:38: got restricted __le16 [usertype] <noident>
sound/usb/mixer_quirks.c:543:35: warning: incorrect type in argument 5 (different base types)
sound/usb/mixer_quirks.c:543:35: expected unsigned short [unsigned] [usertype] value
sound/usb/mixer_quirks.c:543:35: got restricted __le16 [usertype] <noident>
sound/usb/mixer_quirks.c:543:56: warning: incorrect type in argument 6 (different base types)
sound/usb/mixer_quirks.c:543:56: expected unsigned short [unsigned] [usertype] index
sound/usb/mixer_quirks.c:543:56: got restricted __le16 [usertype] <noident>
sound/usb/quirks.c:502:35: warning: incorrect type in argument 5 (different base types)
sound/usb/quirks.c:502:35: expected unsigned short [unsigned] [usertype] value
sound/usb/quirks.c:502:35: got restricted __le16 [usertype] <noident>

Signed-off-by: Eldad Zack <[email protected]>
Acked-by: Daniel Mack <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
sound/usb/mixer_quirks.c | 4 ++--
sound/usb/quirks.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)

--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -396,7 +396,7 @@ static int snd_nativeinstruments_control
else
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
- 0, cpu_to_le16(wIndex),
+ 0, wIndex,
&tmp, sizeof(tmp), 1000);
up_read(&mixer->chip->shutdown_rwsem);

@@ -427,7 +427,7 @@ static int snd_nativeinstruments_control
else
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
- cpu_to_le16(wValue), cpu_to_le16(wIndex),
+ wValue, wIndex,
NULL, 0, 1000);
up_read(&mixer->chip->shutdown_rwsem);

--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -482,7 +482,7 @@ static int snd_usb_nativeinstruments_boo
{
int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
0xaf, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- cpu_to_le16(1), 0, NULL, 0, 1000);
+ 1, 0, NULL, 0, 1000);

if (ret < 0)
return ret;

2013-04-22 14:32:56

by Ben Hutchings

[permalink] [raw]
Subject: [25/75] alpha: Add irongate_io to PCI bus resources

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Jay Estabrook <[email protected]>

commit aa8b4be3ac049c8b1df2a87e4d1d902ccfc1f7a9 upstream.

Fixes a NULL pointer dereference at boot on UP1500.

Reviewed-and-Tested-by: Matt Turner <[email protected]>
Signed-off-by: Jay Estabrook <[email protected]>
Signed-off-by: Matt Turner <[email protected]>
Signed-off-by: Michael Cree <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/alpha/kernel/sys_nautilus.c | 5 +++++
1 file changed, 5 insertions(+)

--- a/arch/alpha/kernel/sys_nautilus.c
+++ b/arch/alpha/kernel/sys_nautilus.c
@@ -189,6 +189,10 @@ nautilus_machine_check(unsigned long vec
extern void free_reserved_mem(void *, void *);
extern void pcibios_claim_one_bus(struct pci_bus *);

+static struct resource irongate_io = {
+ .name = "Irongate PCI IO",
+ .flags = IORESOURCE_IO,
+};
static struct resource irongate_mem = {
.name = "Irongate PCI MEM",
.flags = IORESOURCE_MEM,
@@ -210,6 +214,7 @@ nautilus_init_pci(void)

irongate = pci_get_bus_and_slot(0, 0);
bus->self = irongate;
+ bus->resource[0] = &irongate_io;
bus->resource[1] = &irongate_mem;

pci_bus_size_bridges(bus);

2013-04-22 14:33:49

by Ben Hutchings

[permalink] [raw]
Subject: [21/75] libata: Set max sector to 65535 for Slimtype DVD A DS8A8SH drive

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Shan Hai <[email protected]>

commit a32450e127fc6e5ca6d958ceb3cfea4d30a00846 upstream.

The Slimtype DVD A DS8A8SH drive locks up when max sector is smaller than
65535, and the blow backtrace is observed on locking up:

INFO: task flush-8:32:1130 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
flush-8:32 D ffffffff8180cf60 0 1130 2 0x00000000
ffff880273aef618 0000000000000046 0000000000000005 ffff880273aee000
ffff880273aee000 ffff880273aeffd8 ffff880273aee010 ffff880273aee000
ffff880273aeffd8 ffff880273aee000 ffff88026e842ea0 ffff880274a10000
Call Trace:
[<ffffffff8168fc2d>] schedule+0x5d/0x70
[<ffffffff8168fccc>] io_schedule+0x8c/0xd0
[<ffffffff81324461>] get_request+0x731/0x7d0
[<ffffffff8133dc60>] ? cfq_allow_merge+0x50/0x90
[<ffffffff81083aa0>] ? wake_up_bit+0x40/0x40
[<ffffffff81320443>] ? bio_attempt_back_merge+0x33/0x110
[<ffffffff813248ea>] blk_queue_bio+0x23a/0x3f0
[<ffffffff81322176>] generic_make_request+0xc6/0x120
[<ffffffff81322308>] submit_bio+0x138/0x160
[<ffffffff811d7596>] ? bio_alloc_bioset+0x96/0x120
[<ffffffff811d1f61>] submit_bh+0x1f1/0x220
[<ffffffff811d48b8>] __block_write_full_page+0x228/0x340
[<ffffffff811d3650>] ? attach_nobh_buffers+0xc0/0xc0
[<ffffffff811d8960>] ? I_BDEV+0x10/0x10
[<ffffffff811d8960>] ? I_BDEV+0x10/0x10
[<ffffffff811d4ab6>] block_write_full_page_endio+0xe6/0x100
[<ffffffff811d4ae5>] block_write_full_page+0x15/0x20
[<ffffffff811d9268>] blkdev_writepage+0x18/0x20
[<ffffffff81142527>] __writepage+0x17/0x40
[<ffffffff811438ba>] write_cache_pages+0x34a/0x4a0
[<ffffffff81142510>] ? set_page_dirty+0x70/0x70
[<ffffffff81143a61>] generic_writepages+0x51/0x80
[<ffffffff81143ab0>] do_writepages+0x20/0x50
[<ffffffff811c9ed6>] __writeback_single_inode+0xa6/0x2b0
[<ffffffff811ca861>] writeback_sb_inodes+0x311/0x4d0
[<ffffffff811caaa6>] __writeback_inodes_wb+0x86/0xd0
[<ffffffff811cad43>] wb_writeback+0x1a3/0x330
[<ffffffff816916cf>] ? _raw_spin_lock_irqsave+0x3f/0x50
[<ffffffff811b8362>] ? get_nr_inodes+0x52/0x70
[<ffffffff811cb0ac>] wb_do_writeback+0x1dc/0x260
[<ffffffff8168dd34>] ? schedule_timeout+0x204/0x240
[<ffffffff811cb232>] bdi_writeback_thread+0x102/0x2b0
[<ffffffff811cb130>] ? wb_do_writeback+0x260/0x260
[<ffffffff81083550>] kthread+0xc0/0xd0
[<ffffffff81083490>] ? kthread_worker_fn+0x1b0/0x1b0
[<ffffffff8169a3ec>] ret_from_fork+0x7c/0xb0
[<ffffffff81083490>] ? kthread_worker_fn+0x1b0/0x1b0

The above trace was triggered by
"dd if=/dev/zero of=/dev/sr0 bs=2048 count=32768"

It was previously working by accident, since another bug introduced
by 4dce8ba94c7 (libata: Use 'bool' return value for ata_id_XXX) caused
all drives to use maxsect=65535.

Signed-off-by: Shan Hai <[email protected]>
Signed-off-by: Jeff Garzik <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/ata/libata-core.c | 4 ++++
include/linux/libata.h | 1 +
2 files changed, 5 insertions(+)

--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2401,6 +2401,9 @@ int ata_dev_configure(struct ata_device
dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128,
dev->max_sectors);

+ if (dev->horkage & ATA_HORKAGE_MAX_SEC_LBA48)
+ dev->max_sectors = ATA_MAX_SECTORS_LBA48;
+
if (ap->ops->dev_config)
ap->ops->dev_config(dev);

@@ -4057,6 +4060,7 @@ static const struct ata_blacklist_entry
/* Weird ATAPI devices */
{ "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 },
{ "QUANTUM DAT DAT72-000", NULL, ATA_HORKAGE_ATAPI_MOD16_DMA },
+ { "Slimtype DVD A DS8A8SH", NULL, ATA_HORKAGE_MAX_SEC_LBA48 },

/* Devices we expect to fail diagnostics */

--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -392,6 +392,7 @@ enum {
ATA_HORKAGE_NOSETXFER = (1 << 14), /* skip SETXFER, SATA only */
ATA_HORKAGE_BROKEN_FPDMA_AA = (1 << 15), /* skip AA */
ATA_HORKAGE_DUMP_ID = (1 << 16), /* dump IDENTIFY data */
+ ATA_HORKAGE_MAX_SEC_LBA48 = (1 << 17), /* Set max sects to 65535 */

/* DMA mask for user DMA control: User visible values; DO NOT
renumber */

2013-04-22 14:34:09

by Ben Hutchings

[permalink] [raw]
Subject: [22/75] ata_piix: Fix DVD not dectected at some Haswell platforms

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Youquan Song <[email protected]>

commit b55f84e2d527182e7c611d466cd0bb6ddce201de upstream.

There is a quirk patch 5e5a4f5d5a08c9c504fe956391ac3dae2c66556d
"ata_piix: make DVD Drive recognisable on systems with Intel Sandybridge
chipsets(v2)" fixing the 4 ports IDE controller 32bit PIO mode.

We've hit a problem with DVD not recognized on Haswell Desktop platform which
includes Lynx Point 2-port SATA controller.

This quirk patch disables 32bit PIO on this controller in IDE mode.

v2: Change spelling error in statememnt pointed by Sergei Shtylyov.
v3: Change comment statememnt and spliting line over 80 characters pointed by
Libor Pechacek and also rebase the patch against 3.8-rc7 kernel.

Tested-by: Lee, Chun-Yi <[email protected]>
Signed-off-by: Youquan Song <[email protected]>
Signed-off-by: Jeff Garzik <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/ata/ata_piix.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)

--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -150,6 +150,7 @@ enum piix_controller_ids {
tolapai_sata,
piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */
ich8_sata_snb,
+ ich8_2port_sata_snb,
};

struct piix_map_db {
@@ -326,7 +327,7 @@ static const struct pci_device_id piix_p
/* SATA Controller IDE (Lynx Point) */
{ 0x8086, 0x8c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
/* SATA Controller IDE (Lynx Point) */
- { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+ { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_snb },
/* SATA Controller IDE (Lynx Point) */
{ 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
/* SATA Controller IDE (Lynx Point-LP) */
@@ -519,6 +520,7 @@ static const struct piix_map_db *piix_ma
[ich8m_apple_sata] = &ich8m_apple_map_db,
[tolapai_sata] = &tolapai_map_db,
[ich8_sata_snb] = &ich8_map_db,
+ [ich8_2port_sata_snb] = &ich8_2port_map_db,
};

static struct ata_port_info piix_port_info[] = {
@@ -657,6 +659,16 @@ static struct ata_port_info piix_port_in
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
+ .port_ops = &piix_sata_ops,
+ },
+
+ [ich8_2port_sata_snb] =
+ {
+ .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR
+ | PIIX_FLAG_PIO16,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},

2013-04-22 14:30:21

by Ben Hutchings

[permalink] [raw]
Subject: [38/75] tracing: Fix possible NULL pointer dereferences

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Namhyung Kim <[email protected]>

commit 6a76f8c0ab19f215af2a3442870eeb5f0e81998d upstream.

Currently set_ftrace_pid and set_graph_function files use seq_lseek
for their fops. However seq_open() is called only for FMODE_READ in
the fops->open() so that if an user tries to seek one of those file
when she open it for writing, it sees NULL seq_file and then panic.

It can be easily reproduced with following command:

$ cd /sys/kernel/debug/tracing
$ echo 1234 | sudo tee -a set_ftrace_pid

In this example, GNU coreutils' tee opens the file with fopen(, "a")
and then the fopen() internally calls lseek().

Link: http://lkml.kernel.org/r/[email protected]

Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Namhyung Kim <[email protected]>
Signed-off-by: Namhyung Kim <[email protected]>
Signed-off-by: Steven Rostedt <[email protected]>
[bwh: Backported to 3.2: ftrace_regex_lseek() is static]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -2316,7 +2316,7 @@ ftrace_notrace_open(struct inode *inode,
}

static loff_t
-ftrace_regex_lseek(struct file *file, loff_t offset, int origin)
+ftrace_filter_lseek(struct file *file, loff_t offset, int origin)
{
loff_t ret;

@@ -3134,7 +3134,7 @@ static const struct file_operations ftra
.open = ftrace_filter_open,
.read = seq_read,
.write = ftrace_filter_write,
- .llseek = ftrace_regex_lseek,
+ .llseek = ftrace_filter_lseek,
.release = ftrace_regex_release,
};

@@ -3142,7 +3142,7 @@ static const struct file_operations ftra
.open = ftrace_notrace_open,
.read = seq_read,
.write = ftrace_notrace_write,
- .llseek = ftrace_regex_lseek,
+ .llseek = ftrace_filter_lseek,
.release = ftrace_regex_release,
};

@@ -3350,8 +3350,8 @@ static const struct file_operations ftra
.open = ftrace_graph_open,
.read = seq_read,
.write = ftrace_graph_write,
+ .llseek = ftrace_filter_lseek,
.release = ftrace_graph_release,
- .llseek = seq_lseek,
};
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */

@@ -3843,7 +3843,7 @@ static const struct file_operations ftra
.open = ftrace_pid_open,
.write = ftrace_pid_write,
.read = seq_read,
- .llseek = seq_lseek,
+ .llseek = ftrace_filter_lseek,
.release = ftrace_pid_release,
};

2013-04-22 14:34:32

by Ben Hutchings

[permalink] [raw]
Subject: [27/75] sched_clock: Prevent 64bit inatomicity on 32bit systems

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Thomas Gleixner <[email protected]>

commit a1cbcaa9ea87b87a96b9fc465951dcf36e459ca2 upstream.

The sched_clock_remote() implementation has the following inatomicity
problem on 32bit systems when accessing the remote scd->clock, which
is a 64bit value.

CPU0 CPU1

sched_clock_local() sched_clock_remote(CPU0)
...
remote_clock = scd[CPU0]->clock
read_low32bit(scd[CPU0]->clock)
cmpxchg64(scd->clock,...)
read_high32bit(scd[CPU0]->clock)

While the update of scd->clock is using an atomic64 mechanism, the
readout on the remote cpu is not, which can cause completely bogus
readouts.

It is a quite rare problem, because it requires the update to hit the
narrow race window between the low/high readout and the update must go
across the 32bit boundary.

The resulting misbehaviour is, that CPU1 will see the sched_clock on
CPU1 ~4 seconds ahead of it's own and update CPU1s sched_clock value
to this bogus timestamp. This stays that way due to the clamping
implementation for about 4 seconds until the synchronization with
CLOCK_MONOTONIC undoes the problem.

The issue is hard to observe, because it might only result in a less
accurate SCHED_OTHER timeslicing behaviour. To create observable
damage on realtime scheduling classes, it is necessary that the bogus
update of CPU1 sched_clock happens in the context of an realtime
thread, which then gets charged 4 seconds of RT runtime, which results
in the RT throttler mechanism to trigger and prevent scheduling of RT
tasks for a little less than 4 seconds. So this is quite unlikely as
well.

The issue was quite hard to decode as the reproduction time is between
2 days and 3 weeks and intrusive tracing makes it less likely, but the
following trace recorded with trace_clock=global, which uses
sched_clock_local(), gave the final hint:

<idle>-0 0d..30 400269.477150: hrtimer_cancel: hrtimer=0xf7061e80
<idle>-0 0d..30 400269.477151: hrtimer_start: hrtimer=0xf7061e80 ...
irq/20-S-587 1d..32 400273.772118: sched_wakeup: comm= ... target_cpu=0
<idle>-0 0dN.30 400273.772118: hrtimer_cancel: hrtimer=0xf7061e80

What happens is that CPU0 goes idle and invokes
sched_clock_idle_sleep_event() which invokes sched_clock_local() and
CPU1 runs a remote wakeup for CPU0 at the same time, which invokes
sched_remote_clock(). The time jump gets propagated to CPU0 via
sched_remote_clock() and stays stale on both cores for ~4 seconds.

There are only two other possibilities, which could cause a stale
sched clock:

1) ktime_get() which reads out CLOCK_MONOTONIC returns a sporadic
wrong value.

2) sched_clock() which reads the TSC returns a sporadic wrong value.

#1 can be excluded because sched_clock would continue to increase for
one jiffy and then go stale.

#2 can be excluded because it would not make the clock jump
forward. It would just result in a stale sched_clock for one jiffy.

After quite some brain twisting and finding the same pattern on other
traces, sched_clock_remote() remained the only place which could cause
such a problem and as explained above it's indeed racy on 32bit
systems.

So while on 64bit systems the readout is atomic, we need to verify the
remote readout on 32bit machines. We need to protect the local->clock
readout in sched_clock_remote() on 32bit as well because an NMI could
hit between the low and the high readout, call sched_clock_local() and
modify local->clock.

Thanks to Siegfried Wulsch for bearing with my debug requests and
going through the tedious tasks of running a bunch of reproducer
systems to generate the debug information which let me decode the
issue.

Reported-by: Siegfried Wulsch <[email protected]>
Acked-by: Peter Zijlstra <[email protected]>
Cc: Steven Rostedt <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
[bwh: Backported to 3.2: adjust filename]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/kernel/sched_clock.c
+++ b/kernel/sched_clock.c
@@ -176,10 +176,36 @@ static u64 sched_clock_remote(struct sch
u64 this_clock, remote_clock;
u64 *ptr, old_val, val;

+#if BITS_PER_LONG != 64
+again:
+ /*
+ * Careful here: The local and the remote clock values need to
+ * be read out atomic as we need to compare the values and
+ * then update either the local or the remote side. So the
+ * cmpxchg64 below only protects one readout.
+ *
+ * We must reread via sched_clock_local() in the retry case on
+ * 32bit as an NMI could use sched_clock_local() via the
+ * tracer and hit between the readout of
+ * the low32bit and the high 32bit portion.
+ */
+ this_clock = sched_clock_local(my_scd);
+ /*
+ * We must enforce atomic readout on 32bit, otherwise the
+ * update on the remote cpu can hit inbetween the readout of
+ * the low32bit and the high 32bit portion.
+ */
+ remote_clock = cmpxchg64(&scd->clock, 0, 0);
+#else
+ /*
+ * On 64bit the read of [my]scd->clock is atomic versus the
+ * update, so we can avoid the above 32bit dance.
+ */
sched_clock_local(my_scd);
again:
this_clock = my_scd->clock;
remote_clock = scd->clock;
+#endif

/*
* Use the opportunity that we have both locks

2013-04-22 14:34:30

by Ben Hutchings

[permalink] [raw]
Subject: [23/75] hwspinlock: fix __hwspin_lock_request error path

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Li Fei <[email protected]>

commit c10b90d85a5126d25c89cbaa50dc9fdd1c4d001a upstream.

Even in failed case of pm_runtime_get_sync, the usage_count
is incremented. In order to keep the usage_count with correct
value and runtime power management to behave correctly, call
pm_runtime_put_noidle in such case.

In __hwspin_lock_request, module_put is also called before
return in pm_runtime_get_sync failed case.

Signed-off-by Liu Chuansheng <[email protected]>
Signed-off-by: Li Fei <[email protected]>
[edit commit log]
Signed-off-by: Ohad Ben-Cohen <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/hwspinlock/hwspinlock_core.c | 2 ++
1 file changed, 2 insertions(+)

--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -416,6 +416,8 @@ static int __hwspin_lock_request(struct
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
dev_err(dev, "%s: can't power on device\n", __func__);
+ pm_runtime_put_noidle(dev);
+ module_put(dev->driver->owner);
return ret;
}

2013-04-22 14:35:03

by Ben Hutchings

[permalink] [raw]
Subject: [29/75] PM / reboot: call syscore_shutdown() after disable_nonboot_cpus()

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Huacai Chen <[email protected]>

commit 6f389a8f1dd22a24f3d9afc2812b30d639e94625 upstream.

As commit 40dc166c (PM / Core: Introduce struct syscore_ops for core
subsystems PM) say, syscore_ops operations should be carried with one
CPU on-line and interrupts disabled. However, after commit f96972f2d
(kernel/sys.c: call disable_nonboot_cpus() in kernel_restart()),
syscore_shutdown() is called before disable_nonboot_cpus(), so break
the rules. We have a MIPS machine with a 8259A PIC, and there is an
external timer (HPET) linked at 8259A. Since 8259A has been shutdown
too early (by syscore_shutdown()), disable_nonboot_cpus() runs without
timer interrupt, so it hangs and reboot fails. This patch call
syscore_shutdown() a little later (after disable_nonboot_cpus()) to
avoid reboot failure, this is the same way as poweroff does.

For consistency, add disable_nonboot_cpus() to kernel_halt().

Signed-off-by: Huacai Chen <[email protected]>
Signed-off-by: Rafael J. Wysocki <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
kernel/sys.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -320,7 +320,6 @@ void kernel_restart_prepare(char *cmd)
system_state = SYSTEM_RESTART;
usermodehelper_disable();
device_shutdown();
- syscore_shutdown();
}

/**
@@ -366,6 +365,7 @@ void kernel_restart(char *cmd)
{
kernel_restart_prepare(cmd);
disable_nonboot_cpus();
+ syscore_shutdown();
if (!cmd)
printk(KERN_EMERG "Restarting system.\n");
else
@@ -391,6 +391,7 @@ static void kernel_shutdown_prepare(enum
void kernel_halt(void)
{
kernel_shutdown_prepare(SYSTEM_HALT);
+ disable_nonboot_cpus();
syscore_shutdown();
printk(KERN_EMERG "System halted.\n");
kmsg_dump(KMSG_DUMP_HALT);

2013-04-22 14:35:05

by Ben Hutchings

[permalink] [raw]
Subject: [31/75] ASoC: wm8903: Fix the bypass to HP/LINEOUT when no DAC or ADC is running

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Alban Bedel <[email protected]>

commit f1ca493b0b5e8f42d3b2dc8877860db2983f47b6 upstream.

The Charge Pump needs the DSP clock to work properly, without it the
bypass to HP/LINEOUT is not working properly. This requirement is not
mentioned in the datasheet but has been confirmed by Mark Brown from
Wolfson.

Signed-off-by: Alban Bedel <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
sound/soc/codecs/wm8903.c | 2 ++
1 file changed, 2 insertions(+)

--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -1101,6 +1101,8 @@ static const struct snd_soc_dapm_route w
{ "ROP", NULL, "Right Speaker PGA" },
{ "RON", NULL, "Right Speaker PGA" },

+ { "Charge Pump", NULL, "CLK_DSP" },
+
{ "Left Headphone Output PGA", NULL, "Charge Pump" },
{ "Right Headphone Output PGA", NULL, "Charge Pump" },
{ "Left Line Output PGA", NULL, "Charge Pump" },

2013-04-22 14:35:49

by Ben Hutchings

[permalink] [raw]
Subject: [36/75] target: Fix MAINTENANCE_IN service action CDB checks to use lower 5 bits

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Nicholas Bellinger <[email protected]>

commit ba539743b70cd160c84bab1c82910d0789b820f8 upstream.

This patch fixes the MAINTENANCE_IN service action type checks to only
look at the proper lower 5 bits of cdb byte 1. This addresses the case
where MI_REPORT_TARGET_PGS w/ extended header using the upper three bits of
cdb byte 1 was not processed correctly in transport_generic_cmd_sequencer,
as well as the three cases for standby, unavailable, and transition ALUA
primary access state checks.

Also add MAINTENANCE_IN to the excluded list in transport_generic_prepare_cdb()
to prevent the PARAMETER DATA FORMAT bits from being cleared.

Cc: Hannes Reinecke <[email protected]>
Cc: Rob Evers <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Roland Dreier <[email protected]>
Signed-off-by: Nicholas Bellinger <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/target/target_core_alua.c | 6 +++---
drivers/target/target_core_transport.c | 3 ++-
2 files changed, 5 insertions(+), 4 deletions(-)

--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -394,7 +394,7 @@ static inline int core_alua_state_standb
case RECEIVE_DIAGNOSTIC:
case SEND_DIAGNOSTIC:
case MAINTENANCE_IN:
- switch (cdb[1]) {
+ switch (cdb[1] & 0x1f) {
case MI_REPORT_TARGET_PGS:
return 0;
default:
@@ -436,7 +436,7 @@ static inline int core_alua_state_unavai
case INQUIRY:
case REPORT_LUNS:
case MAINTENANCE_IN:
- switch (cdb[1]) {
+ switch (cdb[1] & 0x1f) {
case MI_REPORT_TARGET_PGS:
return 0;
default:
@@ -476,7 +476,7 @@ static inline int core_alua_state_transi
case INQUIRY:
case REPORT_LUNS:
case MAINTENANCE_IN:
- switch (cdb[1]) {
+ switch (cdb[1] & 0x1f) {
case MI_REPORT_TARGET_PGS:
return 0;
default:
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1445,6 +1445,7 @@ static inline void transport_generic_pre
case VERIFY_16: /* SBC - VRProtect */
case WRITE_VERIFY: /* SBC - VRProtect */
case WRITE_VERIFY_12: /* SBC - VRProtect */
+ case MAINTENANCE_IN: /* SPC - Parameter Data Format for SA RTPG */
break;
default:
cdb[1] &= 0x1f; /* clear logical unit number */
@@ -2683,7 +2684,7 @@ static int transport_generic_cmd_sequenc
/*
* Check for emulated MI_REPORT_TARGET_PGS.
*/
- if (cdb[1] == MI_REPORT_TARGET_PGS &&
+ if ((cdb[1] & 0x1f) == MI_REPORT_TARGET_PGS &&
su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) {
cmd->execute_task =
target_emulate_report_target_port_groups;

2013-04-22 14:37:01

by Ben Hutchings

[permalink] [raw]
Subject: [33/75] tracing: Fix double free when function profile init failed

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Namhyung Kim <[email protected]>

commit 83e03b3fe4daffdebbb42151d5410d730ae50bd1 upstream.

On the failure path, stat->start and stat->pages will refer same page.
So it'll attempt to free the same page again and get kernel panic.

Link: http://lkml.kernel.org/r/[email protected]

Cc: Frederic Weisbecker <[email protected]>
Cc: Namhyung Kim <[email protected]>
Signed-off-by: Namhyung Kim <[email protected]>
Signed-off-by: Steven Rostedt <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
kernel/trace/ftrace.c | 1 -
1 file changed, 1 deletion(-)

--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -572,7 +572,6 @@ int ftrace_profile_pages_init(struct ftr
free_page(tmp);
}

- free_page((unsigned long)stat->pages);
stat->pages = NULL;
stat->start = NULL;

2013-04-22 14:30:18

by Ben Hutchings

[permalink] [raw]
Subject: [49/75] ARM: 7698/1: perf: fix group validation when using enable_on_exec

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Will Deacon <[email protected]>

commit cb2d8b342aa084d1f3ac29966245dec9163677fb upstream.

Events may be created with attr->disabled == 1 and attr->enable_on_exec
== 1, which confuses the group validation code because events with the
PERF_EVENT_STATE_OFF are not considered candidates for scheduling, which
may lead to failure at group scheduling time.

This patch fixes the validation check for ARM, so that events in the
OFF state are still considered when enable_on_exec is true.

Cc: Peter Zijlstra <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Jiri Olsa <[email protected]>
Reported-by: Sudeep KarkadaNagesha <[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.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -326,7 +326,10 @@ validate_event(struct pmu_hw_events *hw_
struct hw_perf_event fake_event = event->hw;
struct pmu *leader_pmu = event->group_leader->pmu;

- if (event->pmu != leader_pmu || event->state <= PERF_EVENT_STATE_OFF)
+ if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF)
+ return 1;
+
+ if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec)
return 1;

return armpmu->get_event_idx(hw_events, &fake_event) >= 0;

2013-04-22 14:37:29

by Ben Hutchings

[permalink] [raw]
Subject: [45/75] of: introduce helper to manage boolean

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Jean-Christophe PLAGNIOL-VILLARD <[email protected]>

commit fa4d34ccd0914ac87336ea2c17e9370dfecef286 upstream.

of_property_read_bool

Search for a property in a device node.
Returns true if the property exist false otherwise.

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <[email protected]>
Acked-by: Rob Herring <[email protected]>
Acked-by: Arnd Bergmann <[email protected]>
Acked-by: Grant Likely <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
include/linux/of.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)

--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -336,6 +336,22 @@ static inline int of_machine_is_compatib
#define of_match_node(_matches, _node) NULL
#endif /* CONFIG_OF */

+/**
+ * of_property_read_bool - Findfrom a property
+ * @np: device node from which the property value is to be read.
+ * @propname: name of the property to be searched.
+ *
+ * Search for a property in a device node.
+ * Returns true if the property exist false otherwise.
+ */
+static inline bool of_property_read_bool(const struct device_node *np,
+ const char *propname)
+{
+ struct property *prop = of_find_property(np, propname, NULL);
+
+ return prop ? true : false;
+}
+
static inline int of_property_read_u32(const struct device_node *np,
const char *propname,
u32 *out_value)

2013-04-22 14:37:54

by Ben Hutchings

[permalink] [raw]
Subject: [32/75] spinlocks and preemption points need to be at least compiler barriers

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Linus Torvalds <[email protected]>

commit 386afc91144b36b42117b0092893f15bc8798a80 upstream.

In UP and non-preempt respectively, the spinlocks and preemption
disable/enable points are stubbed out entirely, because there is no
regular code that can ever hit the kind of concurrency they are meant to
protect against.

However, while there is no regular code that can cause scheduling, we
_do_ end up having some exceptional (literally!) code that can do so,
and that we need to make sure does not ever get moved into the critical
region by the compiler.

In particular, get_user() and put_user() is generally implemented as
inline asm statements (even if the inline asm may then make a call
instruction to call out-of-line), and can obviously cause a page fault
and IO as a result. If that inline asm has been scheduled into the
middle of a preemption-safe (or spinlock-protected) code region, we
obviously lose.

Now, admittedly this is *very* unlikely to actually ever happen, and
we've not seen examples of actual bugs related to this. But partly
exactly because it's so hard to trigger and the resulting bug is so
subtle, we should be extra careful to get this right.

So make sure that even when preemption is disabled, and we don't have to
generate any actual *code* to explicitly tell the system that we are in
a preemption-disabled region, we need to at least tell the compiler not
to move things around the critical region.

This patch grew out of the same discussion that caused commits
79e5f05edcbf ("ARC: Add implicit compiler barrier to raw_local_irq*
functions") and 3e2e0d2c222b ("tile: comment assumption about
__insn_mtspr for <asm/irqflags.h>") to come about.

Note for stable: use discretion when/if applying this. As mentioned,
this bug may never have actually bitten anybody, and gcc may never have
done the required code motion for it to possibly ever trigger in
practice.

Cc: Steven Rostedt <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
[bwh: Backported to 3.2: drop sched_preempt_enable_no_resched()]
Signed-off-by: Ben Hutchings <[email protected]>
---
include/linux/preempt.h | 22 ++++++++++++++--------
include/linux/spinlock_up.h | 29 ++++++++++++++++++-----------
2 files changed, 32 insertions(+), 19 deletions(-)

--- a/include/linux/preempt.h
+++ b/include/linux/preempt.h
@@ -91,13 +91,19 @@ do { \

#else /* !CONFIG_PREEMPT_COUNT */

-#define preempt_disable() do { } while (0)
-#define preempt_enable_no_resched() do { } while (0)
-#define preempt_enable() do { } while (0)
+/*
+ * Even if we don't have any preemption, we need preempt disable/enable
+ * to be barriers, so that we don't have things like get_user/put_user
+ * that can cause faults and scheduling migrate into our preempt-protected
+ * region.
+ */
+#define preempt_disable() barrier()
+#define preempt_enable_no_resched() barrier()
+#define preempt_enable() barrier()

-#define preempt_disable_notrace() do { } while (0)
-#define preempt_enable_no_resched_notrace() do { } while (0)
-#define preempt_enable_notrace() do { } while (0)
+#define preempt_disable_notrace() barrier()
+#define preempt_enable_no_resched_notrace() barrier()
+#define preempt_enable_notrace() barrier()

#endif /* CONFIG_PREEMPT_COUNT */

--- a/include/linux/spinlock_up.h
+++ b/include/linux/spinlock_up.h
@@ -16,7 +16,10 @@
* In the debug case, 1 means unlocked, 0 means locked. (the values
* are inverted, to catch initialization bugs)
*
- * No atomicity anywhere, we are on UP.
+ * No atomicity anywhere, we are on UP. However, we still need
+ * the compiler barriers, because we do not want the compiler to
+ * move potentially faulting instructions (notably user accesses)
+ * into the locked sequence, resulting in non-atomic execution.
*/

#ifdef CONFIG_DEBUG_SPINLOCK
@@ -25,6 +28,7 @@
static inline void arch_spin_lock(arch_spinlock_t *lock)
{
lock->slock = 0;
+ barrier();
}

static inline void
@@ -32,6 +36,7 @@ arch_spin_lock_flags(arch_spinlock_t *lo
{
local_irq_save(flags);
lock->slock = 0;
+ barrier();
}

static inline int arch_spin_trylock(arch_spinlock_t *lock)
@@ -39,32 +44,34 @@ static inline int arch_spin_trylock(arch
char oldval = lock->slock;

lock->slock = 0;
+ barrier();

return oldval > 0;
}

static inline void arch_spin_unlock(arch_spinlock_t *lock)
{
+ barrier();
lock->slock = 1;
}

/*
* Read-write spinlocks. No debug version.
*/
-#define arch_read_lock(lock) do { (void)(lock); } while (0)
-#define arch_write_lock(lock) do { (void)(lock); } while (0)
-#define arch_read_trylock(lock) ({ (void)(lock); 1; })
-#define arch_write_trylock(lock) ({ (void)(lock); 1; })
-#define arch_read_unlock(lock) do { (void)(lock); } while (0)
-#define arch_write_unlock(lock) do { (void)(lock); } while (0)
+#define arch_read_lock(lock) do { barrier(); (void)(lock); } while (0)
+#define arch_write_lock(lock) do { barrier(); (void)(lock); } while (0)
+#define arch_read_trylock(lock) ({ barrier(); (void)(lock); 1; })
+#define arch_write_trylock(lock) ({ barrier(); (void)(lock); 1; })
+#define arch_read_unlock(lock) do { barrier(); (void)(lock); } while (0)
+#define arch_write_unlock(lock) do { barrier(); (void)(lock); } while (0)

#else /* DEBUG_SPINLOCK */
#define arch_spin_is_locked(lock) ((void)(lock), 0)
/* for sched.c and kernel_lock.c: */
-# define arch_spin_lock(lock) do { (void)(lock); } while (0)
-# define arch_spin_lock_flags(lock, flags) do { (void)(lock); } while (0)
-# define arch_spin_unlock(lock) do { (void)(lock); } while (0)
-# define arch_spin_trylock(lock) ({ (void)(lock); 1; })
+# define arch_spin_lock(lock) do { barrier(); (void)(lock); } while (0)
+# define arch_spin_lock_flags(lock, flags) do { barrier(); (void)(lock); } while (0)
+# define arch_spin_unlock(lock) do { barrier(); (void)(lock); } while (0)
+# define arch_spin_trylock(lock) ({ barrier(); (void)(lock); 1; })
#endif /* DEBUG_SPINLOCK */

#define arch_spin_is_contended(lock) (((void)(lock), 0))

2013-04-22 14:38:20

by Ben Hutchings

[permalink] [raw]
Subject: [46/75] can: sja1000: fix handling on dt properties on little endian systems

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Christoph Fritz <[email protected]>

commit 0443de5fbf224abf41f688d8487b0c307dc5a4b4 upstream.

To get correct endianes on little endian cpus (like arm) while reading device
tree properties, this patch replaces of_get_property() with
of_property_read_u32(). While there use of_property_read_bool() for the
handling of the boolean "nxp,no-comparator-bypass" property.

Signed-off-by: Christoph Fritz <[email protected]>
Signed-off-by: Marc Kleine-Budde <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/can/sja1000/sja1000_of_platform.c | 31 ++++++++++++-------------
1 file changed, 15 insertions(+), 16 deletions(-)

--- a/drivers/net/can/sja1000/sja1000_of_platform.c
+++ b/drivers/net/can/sja1000/sja1000_of_platform.c
@@ -94,8 +94,8 @@ static int __devinit sja1000_ofp_probe(s
struct net_device *dev;
struct sja1000_priv *priv;
struct resource res;
- const u32 *prop;
- int err, irq, res_size, prop_size;
+ u32 prop;
+ int err, irq, res_size;
void __iomem *base;

err = of_address_to_resource(np, 0, &res);
@@ -136,27 +136,27 @@ static int __devinit sja1000_ofp_probe(s
priv->read_reg = sja1000_ofp_read_reg;
priv->write_reg = sja1000_ofp_write_reg;

- prop = of_get_property(np, "nxp,external-clock-frequency", &prop_size);
- if (prop && (prop_size == sizeof(u32)))
- priv->can.clock.freq = *prop / 2;
+ err = of_property_read_u32(np, "nxp,external-clock-frequency", &prop);
+ if (!err)
+ priv->can.clock.freq = prop / 2;
else
priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */

- prop = of_get_property(np, "nxp,tx-output-mode", &prop_size);
- if (prop && (prop_size == sizeof(u32)))
- priv->ocr |= *prop & OCR_MODE_MASK;
+ err = of_property_read_u32(np, "nxp,tx-output-mode", &prop);
+ if (!err)
+ priv->ocr |= prop & OCR_MODE_MASK;
else
priv->ocr |= OCR_MODE_NORMAL; /* default */

- prop = of_get_property(np, "nxp,tx-output-config", &prop_size);
- if (prop && (prop_size == sizeof(u32)))
- priv->ocr |= (*prop << OCR_TX_SHIFT) & OCR_TX_MASK;
+ err = of_property_read_u32(np, "nxp,tx-output-config", &prop);
+ if (!err)
+ priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK;
else
priv->ocr |= OCR_TX0_PULLDOWN; /* default */

- prop = of_get_property(np, "nxp,clock-out-frequency", &prop_size);
- if (prop && (prop_size == sizeof(u32)) && *prop) {
- u32 divider = priv->can.clock.freq * 2 / *prop;
+ err = of_property_read_u32(np, "nxp,clock-out-frequency", &prop);
+ if (!err && prop) {
+ u32 divider = priv->can.clock.freq * 2 / prop;

if (divider > 1)
priv->cdr |= divider / 2 - 1;
@@ -166,8 +166,7 @@ static int __devinit sja1000_ofp_probe(s
priv->cdr |= CDR_CLK_OFF; /* default */
}

- prop = of_get_property(np, "nxp,no-comparator-bypass", NULL);
- if (!prop)
+ if (!of_property_read_bool(np, "nxp,no-comparator-bypass"))
priv->cdr |= CDR_CBP; /* default */

priv->irq_flags = IRQF_SHARED;

2013-04-22 14:38:18

by Ben Hutchings

[permalink] [raw]
Subject: [37/75] target: Fix incorrect fallthrough of ALUA Standby/Offline/Transition CDBs

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Nicholas Bellinger <[email protected]>

commit 30f359a6f9da65a66de8cadf959f0f4a0d498bba upstream.

This patch fixes a bug where a handful of informational / control CDBs
that should be allowed during ALUA access state Standby/Offline/Transition
where incorrectly returning CHECK_CONDITION + ASCQ_04H_ALUA_TG_PT_*.

This includes INQUIRY + REPORT_LUNS, which would end up preventing LUN
registration when LUN scanning occured during these ALUA access states.

Cc: Hannes Reinecke <[email protected]>
Signed-off-by: Nicholas Bellinger <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/target/target_core_alua.c | 3 +++
1 file changed, 3 insertions(+)

--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -393,6 +393,7 @@ static inline int core_alua_state_standb
case REPORT_LUNS:
case RECEIVE_DIAGNOSTIC:
case SEND_DIAGNOSTIC:
+ return 0;
case MAINTENANCE_IN:
switch (cdb[1] & 0x1f) {
case MI_REPORT_TARGET_PGS:
@@ -435,6 +436,7 @@ static inline int core_alua_state_unavai
switch (cdb[0]) {
case INQUIRY:
case REPORT_LUNS:
+ return 0;
case MAINTENANCE_IN:
switch (cdb[1] & 0x1f) {
case MI_REPORT_TARGET_PGS:
@@ -475,6 +477,7 @@ static inline int core_alua_state_transi
switch (cdb[0]) {
case INQUIRY:
case REPORT_LUNS:
+ return 0;
case MAINTENANCE_IN:
switch (cdb[1] & 0x1f) {
case MI_REPORT_TARGET_PGS:

2013-04-22 14:30:15

by Ben Hutchings

[permalink] [raw]
Subject: [47/75] ath9k_hw: change AR9580 initvals to fix a stability issue

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Felix Fietkau <[email protected]>

commit f09a878511997c25a76bf111a32f6b8345a701a5 upstream.

The hardware parsing of Control Wrapper Frames needs to be disabled, as
it has been causing spurious decryption error reports. The initvals for
other chips have been updated to disable it, but AR9580 was left out for
some reason.

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/ar9580_1p0_initvals.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
@@ -648,7 +648,7 @@ static const u32 ar9580_1p0_mac_core[][2
{0x00008258, 0x00000000},
{0x0000825c, 0x40000000},
{0x00008260, 0x00080922},
- {0x00008264, 0x9bc00010},
+ {0x00008264, 0x9d400010},
{0x00008268, 0xffffffff},
{0x0000826c, 0x0000ffff},
{0x00008270, 0x00000000},

2013-04-22 14:39:40

by Ben Hutchings

[permalink] [raw]
Subject: [41/75] kobject: fix kset_find_obj() race with concurrent last kobject_put()

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Linus Torvalds <[email protected]>

commit a49b7e82cab0f9b41f483359be83f44fbb6b4979 upstream.

Anatol Pomozov identified a race condition that hits module unloading
and re-loading. To quote Anatol:

"This is a race codition that exists between kset_find_obj() and
kobject_put(). kset_find_obj() might return kobject that has refcount
equal to 0 if this kobject is freeing by kobject_put() in other
thread.

Here is timeline for the crash in case if kset_find_obj() searches for
an object tht nobody holds and other thread is doing kobject_put() on
the same kobject:

THREAD A (calls kset_find_obj()) THREAD B (calls kobject_put())
splin_lock()
atomic_dec_return(kobj->kref), counter gets zero here
... starts kobject cleanup ....
spin_lock() // WAIT thread A in kobj_kset_leave()
iterate over kset->list
atomic_inc(kobj->kref) (counter becomes 1)
spin_unlock()
spin_lock() // taken
// it does not know that thread A increased counter so it
remove obj from list
spin_unlock()
vfree(module) // frees module object with containing kobj

// kobj points to freed memory area!!
kobject_put(kobj) // OOPS!!!!

The race above happens because module.c tries to use kset_find_obj()
when somebody unloads module. The module.c code was introduced in
commit 6494a93d55fa"

Anatol supplied a patch specific for module.c that worked around the
problem by simply not using kset_find_obj() at all, but rather than make
a local band-aid, this just fixes kset_find_obj() to be thread-safe
using the proper model of refusing the get a new reference if the
refcount has already dropped to zero.

See examples of this proper refcount handling not only in the kref
documentation, but in various other equivalent uses of this pattern by
grepping for atomic_inc_not_zero().

[ Side note: the module race does indicate that module loading and
unloading is not properly serialized wrt sysfs information using the
module mutex. That may require further thought, but this is the
correct fix at the kobject layer regardless. ]

Reported-analyzed-and-tested-by: Anatol Pomozov <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Al Viro <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -531,6 +531,13 @@ struct kobject *kobject_get(struct kobje
return kobj;
}

+static struct kobject *kobject_get_unless_zero(struct kobject *kobj)
+{
+ if (!kref_get_unless_zero(&kobj->kref))
+ kobj = NULL;
+ return kobj;
+}
+
/*
* kobject_cleanup - free kobject resources.
* @kobj: object to cleanup
@@ -785,7 +792,7 @@ struct kobject *kset_find_obj_hinted(str
slow_search:
list_for_each_entry(k, &kset->list, entry) {
if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
- ret = kobject_get(k);
+ ret = kobject_get_unless_zero(k);
break;
}
}

2013-04-22 14:39:39

by Ben Hutchings

[permalink] [raw]
Subject: [40/75] kref: Implement kref_get_unless_zero v3

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Thomas Hellstrom <[email protected]>

commit 4b20db3de8dab005b07c74161cb041db8c5ff3a7 upstream.

This function is intended to simplify locking around refcounting for
objects that can be looked up from a lookup structure, and which are
removed from that lookup structure in the object destructor.
Operations on such objects require at least a read lock around
lookup + kref_get, and a write lock around kref_put + remove from lookup
structure. Furthermore, RCU implementations become extremely tricky.
With a lookup followed by a kref_get_unless_zero *with return value check*
locking in the kref_put path can be deferred to the actual removal from
the lookup structure and RCU lookups become trivial.

v2: Formatting fixes.
v3: Invert the return value.

Signed-off-by: Thomas Hellstrom <[email protected]>
Signed-off-by: Dave Airlie <[email protected]>
[bwh: Backported to 3.2:
- Adjust context
- Add #include <linux/atomic.h>]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/include/linux/kref.h
+++ b/include/linux/kref.h
@@ -16,6 +16,7 @@
#define _KREF_H_

#include <linux/types.h>
+#include <linux/atomic.h>

struct kref {
atomic_t refcount;
@@ -27,4 +28,24 @@ int kref_put(struct kref *kref, void (*r
int kref_sub(struct kref *kref, unsigned int count,
void (*release) (struct kref *kref));

+/**
+ * kref_get_unless_zero - Increment refcount for object unless it is zero.
+ * @kref: object.
+ *
+ * Return non-zero if the increment succeeded. Otherwise return 0.
+ *
+ * This function is intended to simplify locking around refcounting for
+ * objects that can be looked up from a lookup structure, and which are
+ * removed from that lookup structure in the object destructor.
+ * Operations on such objects require at least a read lock around
+ * lookup + kref_get, and a write lock around kref_put + remove from lookup
+ * structure. Furthermore, RCU implementations become extremely tricky.
+ * With a lookup followed by a kref_get_unless_zero *with return value check*
+ * locking in the kref_put path can be deferred to the actual removal from
+ * the lookup structure and RCU lookups become trivial.
+ */
+static inline int __must_check kref_get_unless_zero(struct kref *kref)
+{
+ return atomic_add_unless(&kref->refcount, 1, 0);
+}
#endif /* _KREF_H_ */

2013-04-22 14:30:13

by Ben Hutchings

[permalink] [raw]
Subject: [50/75] hugetlbfs: add swap entry check in follow_hugetlb_page()

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Naoya Horiguchi <[email protected]>

commit 9cc3a5bd40067b9a0fbd49199d0780463fc2140f upstream.

With applying the previous patch "hugetlbfs: stop setting VM_DONTDUMP in
initializing vma(VM_HUGETLB)" to reenable hugepage coredump, if a memory
error happens on a hugepage and the affected processes try to access the
error hugepage, we hit VM_BUG_ON(atomic_read(&page->_count) <= 0) in
get_page().

The reason for this bug is that coredump-related code doesn't recognise
"hugepage hwpoison entry" with which a pmd entry is replaced when a memory
error occurs on a hugepage.

In other words, physical address information is stored in different bit
layout between hugepage hwpoison entry and pmd entry, so
follow_hugetlb_page() which is called in get_dump_page() returns a wrong
page from a given address.

The expected behavior is like this:

absent is_swap_pte FOLL_DUMP Expected behavior
-------------------------------------------------------------------
true false false hugetlb_fault
false true false hugetlb_fault
false false false return page
true false true skip page (to avoid allocation)
false true true hugetlb_fault
false false true return page

With this patch, we can call hugetlb_fault() and take proper actions (we
wait for migration entries, fail with VM_FAULT_HWPOISON_LARGE for
hwpoisoned entries,) and as the result we can dump all hugepages except
for hwpoisoned ones.

Signed-off-by: Naoya Horiguchi <[email protected]>
Cc: Rik van Riel <[email protected]>
Acked-by: Michal Hocko <[email protected]>
Cc: HATAYAMA Daisuke <[email protected]>
Acked-by: KOSAKI Motohiro <[email protected]>
Acked-by: David Rientjes <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
mm/hugetlb.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2889,7 +2889,17 @@ int follow_hugetlb_page(struct mm_struct
break;
}

- if (absent ||
+ /*
+ * We need call hugetlb_fault for both hugepages under migration
+ * (in which case hugetlb_fault waits for the migration,) and
+ * hwpoisoned hugepages (in which case we need to prevent the
+ * caller from accessing to them.) In order to do this, we use
+ * here is_swap_pte instead of is_hugetlb_entry_migration and
+ * is_hugetlb_entry_hwpoisoned. This is because it simply covers
+ * both cases, and because we can't follow correct pages
+ * directly from any kind of swap entries.
+ */
+ if (absent || is_swap_pte(huge_ptep_get(pte)) ||
((flags & FOLL_WRITE) && !pte_write(huge_ptep_get(pte)))) {
int ret;

2013-04-22 14:40:46

by Ben Hutchings

[permalink] [raw]
Subject: [39/75] Btrfs: make sure nbytes are right after log replay

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Josef Bacik <[email protected]>

commit 4bc4bee4595662d8bff92180d5c32e3313a704b0 upstream.

While trying to track down a tree log replay bug I noticed that fsck was always
complaining about nbytes not being right for our fsynced file. That is because
the new fsync stuff doesn't wait for ordered extents to complete, so the inodes
nbytes are not necessarily updated properly when we log it. So to fix this we
need to set nbytes to whatever it is on the inode that is on disk, so when we
replay the extents we can just add the bytes that are being added as we replay
the extent. This makes it work for the case that we have the wrong nbytes or
the case that we logged everything and nbytes is actually correct. With this
I'm no longer getting nbytes errors out of btrfsck.

Signed-off-by: Josef Bacik <[email protected]>
Signed-off-by: Chris Mason <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/btrfs/tree-log.c | 48 ++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 42 insertions(+), 6 deletions(-)

--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -316,6 +316,7 @@ static noinline int overwrite_item(struc
unsigned long src_ptr;
unsigned long dst_ptr;
int overwrite_root = 0;
+ bool inode_item = key->type == BTRFS_INODE_ITEM_KEY;

if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID)
overwrite_root = 1;
@@ -325,6 +326,9 @@ static noinline int overwrite_item(struc

/* look for the key in the destination tree */
ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
+ if (ret < 0)
+ return ret;
+
if (ret == 0) {
char *src_copy;
char *dst_copy;
@@ -366,6 +370,30 @@ static noinline int overwrite_item(struc
return 0;
}

+ /*
+ * We need to load the old nbytes into the inode so when we
+ * replay the extents we've logged we get the right nbytes.
+ */
+ if (inode_item) {
+ struct btrfs_inode_item *item;
+ u64 nbytes;
+
+ item = btrfs_item_ptr(path->nodes[0], path->slots[0],
+ struct btrfs_inode_item);
+ nbytes = btrfs_inode_nbytes(path->nodes[0], item);
+ item = btrfs_item_ptr(eb, slot,
+ struct btrfs_inode_item);
+ btrfs_set_inode_nbytes(eb, item, nbytes);
+ }
+ } else if (inode_item) {
+ struct btrfs_inode_item *item;
+
+ /*
+ * New inode, set nbytes to 0 so that the nbytes comes out
+ * properly when we replay the extents.
+ */
+ item = btrfs_item_ptr(eb, slot, struct btrfs_inode_item);
+ btrfs_set_inode_nbytes(eb, item, 0);
}
insert:
btrfs_release_path(path);
@@ -488,7 +516,7 @@ static noinline int replay_one_extent(st
u64 extent_end;
u64 alloc_hint;
u64 start = key->offset;
- u64 saved_nbytes;
+ u64 nbytes = 0;
struct btrfs_file_extent_item *item;
struct inode *inode = NULL;
unsigned long size;
@@ -498,10 +526,19 @@ static noinline int replay_one_extent(st
found_type = btrfs_file_extent_type(eb, item);

if (found_type == BTRFS_FILE_EXTENT_REG ||
- found_type == BTRFS_FILE_EXTENT_PREALLOC)
- extent_end = start + btrfs_file_extent_num_bytes(eb, item);
- else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
+ found_type == BTRFS_FILE_EXTENT_PREALLOC) {
+ nbytes = btrfs_file_extent_num_bytes(eb, item);
+ extent_end = start + nbytes;
+
+ /*
+ * We don't add to the inodes nbytes if we are prealloc or a
+ * hole.
+ */
+ if (btrfs_file_extent_disk_bytenr(eb, item) == 0)
+ nbytes = 0;
+ } else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
size = btrfs_file_extent_inline_len(eb, item);
+ nbytes = btrfs_file_extent_ram_bytes(eb, item);
extent_end = (start + size + mask) & ~mask;
} else {
ret = 0;
@@ -550,7 +587,6 @@ static noinline int replay_one_extent(st
}
btrfs_release_path(path);

- saved_nbytes = inode_get_bytes(inode);
/* drop any overlapping extents */
ret = btrfs_drop_extents(trans, inode, start, extent_end,
&alloc_hint, 1);
@@ -638,7 +674,7 @@ static noinline int replay_one_extent(st
BUG_ON(ret);
}

- inode_set_bytes(inode, saved_nbytes);
+ inode_add_bytes(inode, nbytes);
btrfs_update_inode(trans, root, inode);
out:
if (inode)

2013-04-22 14:41:08

by Ben Hutchings

[permalink] [raw]
Subject: [42/75] vfs: Revert spurious fix to spinning prevention in prune_icache_sb

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Suleiman Souhlal <[email protected]>

commit 5b55d708335a9e3e4f61f2dadf7511502205ccd1 upstream.

Revert commit 62a3ddef6181 ("vfs: fix spinning prevention in prune_icache_sb").

This commit doesn't look right: since we are looking at the tail of the
list (sb->s_inode_lru.prev) if we want to skip an inode, we should put
it back at the head of the list instead of the tail, otherwise we will
keep spinning on it.

Discovered when investigating why prune_icache_sb came top in perf
reports of a swapping load.

Signed-off-by: Suleiman Souhlal <[email protected]>
Signed-off-by: Hugh Dickins <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/inode.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/fs/inode.c
+++ b/fs/inode.c
@@ -634,7 +634,7 @@ void prune_icache_sb(struct super_block
* inode to the back of the list so we don't spin on it.
*/
if (!spin_trylock(&inode->i_lock)) {
- list_move_tail(&inode->i_lru, &sb->s_inode_lru);
+ list_move(&inode->i_lru, &sb->s_inode_lru);
continue;
}

2013-04-22 14:41:36

by Ben Hutchings

[permalink] [raw]
Subject: [44/75] ath9k_htc: accept 1.x firmware newer than 1.3

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Felix Fietkau <[email protected]>

commit 319e7bd96aca64a478f3aad40711c928405b8b77 upstream.

Since the firmware has been open sourced, the minor version has been
bumped to 1.4 and the API/ABI will stay compatible across further 1.x
releases.

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/htc_drv_init.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -801,7 +801,7 @@ static int ath9k_init_firmware_version(s
* required version.
*/
if (priv->fw_version_major != MAJOR_VERSION_REQ ||
- priv->fw_version_minor != MINOR_VERSION_REQ) {
+ priv->fw_version_minor < MINOR_VERSION_REQ) {
dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n",
MAJOR_VERSION_REQ, MINOR_VERSION_REQ);
return -EINVAL;

2013-04-22 14:41:58

by Ben Hutchings

[permalink] [raw]
Subject: [43/75] ARM: Do 15e0d9e37c (ARM: pm: let platforms select cpu_suspend support) properly

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Russell King <[email protected]>

commit b6c7aabd923a17af993c5a5d5d7995f0b27c000a upstream.

Let's do the changes properly and fix the same problem everywhere, not
just for one case.

Signed-off-by: Russell King <[email protected]>
[bwh: Backported to 3.2: mohawk doesn't support suspend at all]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -380,7 +380,7 @@ ENTRY(cpu_arm920_set_pte_ext)
/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
.globl cpu_arm920_suspend_size
.equ cpu_arm920_suspend_size, 4 * 3
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ARM_CPU_SUSPEND
ENTRY(cpu_arm920_do_suspend)
stmfd sp!, {r4 - r6, lr}
mrc p15, 0, r4, c13, c0, 0 @ PID
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -395,7 +395,7 @@ ENTRY(cpu_arm926_set_pte_ext)
/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
.globl cpu_arm926_suspend_size
.equ cpu_arm926_suspend_size, 4 * 3
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ARM_CPU_SUSPEND
ENTRY(cpu_arm926_do_suspend)
stmfd sp!, {r4 - r6, lr}
mrc p15, 0, r4, c13, c0, 0 @ PID
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -169,7 +169,7 @@ ENTRY(cpu_sa1100_set_pte_ext)

.globl cpu_sa1100_suspend_size
.equ cpu_sa1100_suspend_size, 4 * 3
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ARM_CPU_SUSPEND
ENTRY(cpu_sa1100_do_suspend)
stmfd sp!, {r4 - r6, lr}
mrc p15, 0, r4, c3, c0, 0 @ domain ID
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -129,7 +129,7 @@ ENTRY(cpu_v6_set_pte_ext)
/* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
.globl cpu_v6_suspend_size
.equ cpu_v6_suspend_size, 4 * 6
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ARM_CPU_SUSPEND
ENTRY(cpu_v6_do_suspend)
stmfd sp!, {r4 - r9, lr}
mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -407,7 +407,7 @@ ENTRY(cpu_xsc3_set_pte_ext)

.globl cpu_xsc3_suspend_size
.equ cpu_xsc3_suspend_size, 4 * 6
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ARM_CPU_SUSPEND
ENTRY(cpu_xsc3_do_suspend)
stmfd sp!, {r4 - r9, lr}
mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -521,7 +521,7 @@ ENTRY(cpu_xscale_set_pte_ext)

.globl cpu_xscale_suspend_size
.equ cpu_xscale_suspend_size, 4 * 6
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ARM_CPU_SUSPEND
ENTRY(cpu_xscale_do_suspend)
stmfd sp!, {r4 - r9, lr}
mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode

2013-04-22 14:42:33

by Ben Hutchings

[permalink] [raw]
Subject: [55/75] Btrfs: fix race between mmap writes and compression

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Chris Mason <[email protected]>

commit 4adaa611020fa6ac65b0ac8db78276af4ec04e63 upstream.

Btrfs uses page_mkwrite to ensure stable pages during
crc calculations and mmap workloads. We call clear_page_dirty_for_io
before we do any crcs, and this forces any application with the file
mapped to wait for the crc to finish before it is allowed to change
the file.

With compression on, the clear_page_dirty_for_io step is happening after
we've compressed the pages. This means the applications might be
changing the pages while we are compressing them, and some of those
modifications might not hit the disk.

This commit adds the clear_page_dirty_for_io before compression starts
and makes sure to redirty the page if we have to fallback to
uncompressed IO as well.

Signed-off-by: Chris Mason <[email protected]>
Reported-by: Alexandre Oliva <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/btrfs/extent_io.c | 33 +++++++++++++++++++++++++++++++++
fs/btrfs/extent_io.h | 2 ++
fs/btrfs/inode.c | 14 ++++++++++++++
3 files changed, 49 insertions(+)

--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -1209,6 +1209,39 @@ int unlock_extent(struct extent_io_tree
mask);
}

+int extent_range_clear_dirty_for_io(struct inode *inode, u64 start, u64 end)
+{
+ unsigned long index = start >> PAGE_CACHE_SHIFT;
+ unsigned long end_index = end >> PAGE_CACHE_SHIFT;
+ struct page *page;
+
+ while (index <= end_index) {
+ page = find_get_page(inode->i_mapping, index);
+ BUG_ON(!page); /* Pages should be in the extent_io_tree */
+ clear_page_dirty_for_io(page);
+ page_cache_release(page);
+ index++;
+ }
+ return 0;
+}
+
+int extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end)
+{
+ unsigned long index = start >> PAGE_CACHE_SHIFT;
+ unsigned long end_index = end >> PAGE_CACHE_SHIFT;
+ struct page *page;
+
+ while (index <= end_index) {
+ page = find_get_page(inode->i_mapping, index);
+ BUG_ON(!page); /* Pages should be in the extent_io_tree */
+ account_page_redirty(page);
+ __set_page_dirty_nobuffers(page);
+ page_cache_release(page);
+ index++;
+ }
+ return 0;
+}
+
/*
* helper function to set both pages and extents in the tree writeback
*/
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -304,6 +304,8 @@ int map_private_extent_buffer(struct ext
unsigned long *map_len);
int extent_range_uptodate(struct extent_io_tree *tree,
u64 start, u64 end);
+int extent_range_clear_dirty_for_io(struct inode *inode, u64 start, u64 end);
+int extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end);
int extent_clear_unlock_delalloc(struct inode *inode,
struct extent_io_tree *tree,
u64 start, u64 end, struct page *locked_page,
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -343,6 +343,7 @@ static noinline int compress_file_range(
int i;
int will_compress;
int compress_type = root->fs_info->compress_type;
+ int redirty = 0;

/* if this is a small write inside eof, kick off a defragbot */
if (end <= BTRFS_I(inode)->disk_i_size && (end - start + 1) < 16 * 1024)
@@ -404,6 +405,17 @@ again:
if (BTRFS_I(inode)->force_compress)
compress_type = BTRFS_I(inode)->force_compress;

+ /*
+ * we need to call clear_page_dirty_for_io on each
+ * page in the range. Otherwise applications with the file
+ * mmap'd can wander in and change the page contents while
+ * we are compressing them.
+ *
+ * If the compression fails for any reason, we set the pages
+ * dirty again later on.
+ */
+ extent_range_clear_dirty_for_io(inode, start, end);
+ redirty = 1;
ret = btrfs_compress_pages(compress_type,
inode->i_mapping, start,
total_compressed, pages,
@@ -541,6 +553,8 @@ cleanup_and_bail_uncompressed:
__set_page_dirty_nobuffers(locked_page);
/* unlocked later on in the async handlers */
}
+ if (redirty)
+ extent_range_redirty_for_io(inode, start, end);
add_async_extent(async_cow, start, end - start + 1,
0, NULL, 0, BTRFS_COMPRESS_NONE);
*num_added += 1;

2013-04-22 14:42:32

by Ben Hutchings

[permalink] [raw]
Subject: [52/75] net: fix incorrect credentials passing

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Linus Torvalds <[email protected]>

commit 83f1b4ba917db5dc5a061a44b3403ddb6e783494 upstream.

Commit 257b5358b32f ("scm: Capture the full credentials of the scm
sender") changed the credentials passing code to pass in the effective
uid/gid instead of the real uid/gid.

Obviously this doesn't matter most of the time (since normally they are
the same), but it results in differences for suid binaries when the wrong
uid/gid ends up being used.

This just undoes that (presumably unintentional) part of the commit.

Reported-by: Andy Lutomirski <[email protected]>
Cc: Eric W. Biederman <[email protected]>
Cc: Serge E. Hallyn <[email protected]>
Cc: David S. Miller <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Acked-by: "Eric W. Biederman" <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
[bwh: Backported to 3.2: scm_set_cred() does user namespace conversion
of euid/egid using cred_to_ucred(). Add and use cred_real_to_ucred() to
do the same thing for real uid/gid.]
Signed-off-by: Ben Hutchings <[email protected]>
---
include/net/scm.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -50,7 +50,7 @@ static __inline__ void scm_set_cred(stru
{
scm->pid = get_pid(pid);
scm->cred = cred ? get_cred(cred) : NULL;
- cred_to_ucred(pid, cred, &scm->creds);
+ cred_real_to_ucred(pid, cred, &scm->creds);
}

static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -761,6 +761,20 @@ void cred_to_ucred(struct pid *pid, cons
}
EXPORT_SYMBOL_GPL(cred_to_ucred);

+void cred_real_to_ucred(struct pid *pid, const struct cred *cred,
+ struct ucred *ucred)
+{
+ ucred->pid = pid_vnr(pid);
+ ucred->uid = ucred->gid = -1;
+ if (cred) {
+ struct user_namespace *current_ns = current_user_ns();
+
+ ucred->uid = user_ns_map_uid(current_ns, cred, cred->uid);
+ ucred->gid = user_ns_map_gid(current_ns, cred, cred->gid);
+ }
+}
+EXPORT_SYMBOL_GPL(cred_real_to_ucred);
+
int sock_getsockopt(struct socket *sock, int level, int optname,
char __user *optval, int __user *optlen)
{
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -317,6 +317,7 @@ struct ucred {
#define IPX_TYPE 1

extern void cred_to_ucred(struct pid *pid, const struct cred *cred, struct ucred *ucred);
+extern void cred_real_to_ucred(struct pid *pid, const struct cred *cred, struct ucred *ucred);

extern int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
extern int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,

2013-04-22 14:42:30

by Ben Hutchings

[permalink] [raw]
Subject: [51/75] kernel/signal.c: stop info leak via the tkill and the tgkill syscalls

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Emese Revfy <[email protected]>

commit b9e146d8eb3b9ecae5086d373b50fa0c1f3e7f0f upstream.

This fixes a kernel memory contents leak via the tkill and tgkill syscalls
for compat processes.

This is visible in the siginfo_t->_sifields._rt.si_sigval.sival_ptr field
when handling signals delivered from tkill.

The place of the infoleak:

int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
{
...
put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr);
...
}

Signed-off-by: Emese Revfy <[email protected]>
Reviewed-by: PaX Team <[email protected]>
Signed-off-by: Kees Cook <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Oleg Nesterov <[email protected]>
Cc: "Eric W. Biederman" <[email protected]>
Cc: Serge Hallyn <[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 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2790,7 +2790,7 @@ do_send_specific(pid_t tgid, pid_t pid,

static int do_tkill(pid_t tgid, pid_t pid, int sig)
{
- struct siginfo info;
+ struct siginfo info = {};

info.si_signo = sig;
info.si_errno = 0;

2013-04-22 14:42:28

by Ben Hutchings

[permalink] [raw]
Subject: [48/75] ARM: 7696/1: Fix kexec by setting outer_cache.inv_all for Feroceon

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Illia Ragozin <[email protected]>

commit cd272d1ea71583170e95dde02c76166c7f9017e6 upstream.

On Feroceon the L2 cache becomes non-coherent with the CPU
when the L1 caches are disabled. Thus the L2 needs to be invalidated
after both L1 caches are disabled.

On kexec before the starting the code for relocation the kernel,
the L1 caches are disabled in cpu_froc_fin (cpu_v7_proc_fin for Feroceon),
but after L2 cache is never invalidated, because inv_all is not set
in cache-feroceon-l2.c.
So kernel relocation and decompression may has (and usually has) errors.
Setting the function enables L2 invalidation and fixes the issue.

Signed-off-by: Illia Ragozin <[email protected]>
Acked-by: Jason Cooper <[email protected]>
Signed-off-by: Russell King <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/arm/mm/cache-feroceon-l2.c | 1 +
1 file changed, 1 insertion(+)

--- a/arch/arm/mm/cache-feroceon-l2.c
+++ b/arch/arm/mm/cache-feroceon-l2.c
@@ -342,6 +342,7 @@ void __init feroceon_l2_init(int __l2_wt
outer_cache.inv_range = feroceon_l2_inv_range;
outer_cache.clean_range = feroceon_l2_clean_range;
outer_cache.flush_range = feroceon_l2_flush_range;
+ outer_cache.inv_all = l2_inv_all;

enable_l2();

2013-04-22 14:43:39

by Ben Hutchings

[permalink] [raw]
Subject: [63/75] msi-wmi: Fix memory leak

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Maxim Mikityanskiy <[email protected]>

commit 51c94491c82c3d9029f6e87a1a153db321d88e35 upstream.

Fix memory leak - don't forget to kfree ACPI object when returning from
msi_wmi_notify() after suppressing key event.

Signed-off-by: Maxim Mikityanskiy <[email protected]>
Acked-by: Anisse Astier <[email protected]>
Signed-off-by: Lee, Chun-Yi <[email protected]>
Signed-off-by: Matthew Garrett <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/platform/x86/msi-wmi.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c
index 2264331..b96766b 100644
--- a/drivers/platform/x86/msi-wmi.c
+++ b/drivers/platform/x86/msi-wmi.c
@@ -176,7 +176,7 @@ static void msi_wmi_notify(u32 value, void *context)
pr_debug("Suppressed key event 0x%X - "
"Last press was %lld us ago\n",
key->code, ktime_to_us(diff));
- return;
+ goto msi_wmi_notify_exit;
}
last_pressed[key->code - SCANCODE_BASE] = cur;

@@ -195,6 +195,8 @@ static void msi_wmi_notify(u32 value, void *context)
pr_info("Unknown key pressed - %x\n", eventcode);
} else
pr_info("Unknown event received\n");
+
+msi_wmi_notify_exit:
kfree(response.pointer);
}

2013-04-22 14:44:00

by Ben Hutchings

[permalink] [raw]
Subject: [54/75] writeback: fix dirtied pages accounting on redirty

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Wu Fengguang <[email protected]>

commit 2f800fbd777b792de54187088df19a7df0251254 upstream.

De-account the accumulative dirty counters on page redirty.

Page redirties (very common in ext4) will introduce mismatch between
counters (a) and (b)

a) NR_DIRTIED, BDI_DIRTIED, tsk->nr_dirtied
b) NR_WRITTEN, BDI_WRITTEN

This will introduce systematic errors in balanced_rate and result in
dirty page position errors (ie. the dirty pages are no longer balanced
around the global/bdi setpoints).

Acked-by: Jan Kara <[email protected]>
Acked-by: Peter Zijlstra <[email protected]>
Signed-off-by: Wu Fengguang <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
include/linux/writeback.h | 2 ++
mm/page-writeback.c | 19 +++++++++++++++++++
2 files changed, 21 insertions(+)

--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -195,6 +195,8 @@ void writeback_set_ratelimit(void);
void tag_pages_for_writeback(struct address_space *mapping,
pgoff_t start, pgoff_t end);

+void account_page_redirty(struct page *page);
+
/* pdflush.c */
extern int nr_pdflush_threads; /* Global so it can be exported to sysctl
read-only. */
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -1801,6 +1801,24 @@ int __set_page_dirty_nobuffers(struct pa
EXPORT_SYMBOL(__set_page_dirty_nobuffers);

/*
+ * Call this whenever redirtying a page, to de-account the dirty counters
+ * (NR_DIRTIED, BDI_DIRTIED, tsk->nr_dirtied), so that they match the written
+ * counters (NR_WRITTEN, BDI_WRITTEN) in long term. The mismatches will lead to
+ * systematic errors in balanced_dirty_ratelimit and the dirty pages position
+ * control.
+ */
+void account_page_redirty(struct page *page)
+{
+ struct address_space *mapping = page->mapping;
+ if (mapping && mapping_cap_account_dirty(mapping)) {
+ current->nr_dirtied--;
+ dec_zone_page_state(page, NR_DIRTIED);
+ dec_bdi_stat(mapping->backing_dev_info, BDI_DIRTIED);
+ }
+}
+EXPORT_SYMBOL(account_page_redirty);
+
+/*
* When a writepage implementation decides that it doesn't want to write this
* page for some reason, it should redirty the locked page via
* redirty_page_for_writepage() and it should then unlock the page and return 0
@@ -1808,6 +1826,7 @@ EXPORT_SYMBOL(__set_page_dirty_nobuffers
int redirty_page_for_writepage(struct writeback_control *wbc, struct page *page)
{
wbc->pages_skipped++;
+ account_page_redirty(page);
return __set_page_dirty_nobuffers(page);
}
EXPORT_SYMBOL(redirty_page_for_writepage);

2013-04-22 14:44:43

by Ben Hutchings

[permalink] [raw]
Subject: [57/75] drm/i915: panel: invert brightness via quirk

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Carsten Emde <[email protected]>

commit 4dca20efb1a9c2efefc28ad2867e5d6c3f5e1955 upstream.

A machine may need to invert the panel backlight brightness value. This
patch adds the infrastructure for a quirk to do so.

Signed-off-by: Carsten Emde <[email protected]>
Reviewed-by: Chris Wilson <[email protected]>
Signed-off-by: Daniel Vetter <[email protected]>
Acked-by: Jani Nikula <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
Documentation/kernel-parameters.txt | 17 +++++++++++------
drivers/gpu/drm/i915/i915_drv.h | 1 +
drivers/gpu/drm/i915/intel_display.c | 9 +++++++++
drivers/gpu/drm/i915/intel_panel.c | 15 +++++++++++----
4 files changed, 32 insertions(+), 10 deletions(-)

--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -948,14 +948,19 @@ bytes respectively. Such letter suffixes
i8k.restricted [HW] Allow controlling fans only if SYS_ADMIN
capability is set.

- i915.invert_brightness
+ i915.invert_brightness=
[DRM] Invert the sense of the variable that is used to
set the brightness of the panel backlight. Normally a
- value of 0 indicates backlight switched off, and the
- maximum value sets the backlight to maximum brightness.
- If this parameter is specified, a value of 0 sets the
- backlight to maximum brightness, and the maximum value
- switches the backlight off.
+ brightness value of 0 indicates backlight switched off,
+ and the maximum of the brightness value sets the backlight
+ to maximum brightness. If this parameter is set to 0
+ (default) and the machine requires it, or this parameter
+ is set to 1, a brightness value of 0 sets the backlight
+ to maximum brightness, and the maximum of the brightness
+ value switches the backlight off.
+ -1 -- never invert brightness
+ 0 -- machine default
+ 1 -- force brightness inversion

icn= [HW,ISDN]
Format: <io>[,<membase>[,<icn_id>[,<icn_id2>]]]
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -274,6 +274,7 @@ enum intel_pch {

#define QUIRK_PIPEA_FORCE (1<<0)
#define QUIRK_LVDS_SSC_DISABLE (1<<1)
+#define QUIRK_INVERT_BRIGHTNESS (1<<2)

struct intel_fbdev;
struct intel_fbc_work;
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8831,6 +8831,15 @@ static void quirk_ssc_force_disable(stru
dev_priv->quirks |= QUIRK_LVDS_SSC_DISABLE;
}

+/*
+ * A machine may need to invert the panel backlight brightness value
+ */
+static void quirk_invert_brightness(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ dev_priv->quirks |= QUIRK_INVERT_BRIGHTNESS;
+}
+
struct intel_quirk {
int device;
int subsystem_vendor;
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -192,15 +192,22 @@ u32 intel_panel_get_max_backlight(struct
return max;
}

-static bool i915_panel_invert_brightness;
-MODULE_PARM_DESC(invert_brightness, "Invert backlight brightness, please "
+static int i915_panel_invert_brightness;
+MODULE_PARM_DESC(invert_brightness, "Invert backlight brightness "
+ "(-1 force normal, 0 machine defaults, 1 force inversion), please "
"report PCI device ID, subsystem vendor and subsystem device ID "
"to [email protected], if your machine needs it. "
"It will then be included in an upcoming module version.");
-module_param_named(invert_brightness, i915_panel_invert_brightness, bool, 0600);
+module_param_named(invert_brightness, i915_panel_invert_brightness, int, 0600);
static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val)
{
- if (i915_panel_invert_brightness)
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (i915_panel_invert_brightness < 0)
+ return val;
+
+ if (i915_panel_invert_brightness > 0 ||
+ dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS)
return intel_panel_get_max_backlight(dev) - val;

return val;

2013-04-22 14:45:22

by Ben Hutchings

[permalink] [raw]
Subject: [56/75] drm/i915: panel: invert brightness via parameter

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Carsten Emde <[email protected]>

commit 7bd90909bbf9ce7c40e1da3d72b97b93839c188a upstream.

Following the documentation of the Legacy Backlight Brightness (LBB)
Register in the configuration space of some Intel PCI graphics adapters,
setting the LBB register with the value 0x0 causes the backlight to be
turned off, and 0xFF causes the backlight to be set to 100% intensity
(http://download.intel.com/embedded/processors/Whitepaper/324567.pdf).
The Acer Aspire 5734Z, however, turns the backlight off at 0xFF and sets
it to maximum intensity at 0. In consequence, the screen of this systems
becomes dark at an early boot stage which makes it unusable. The same
inversion applies to the BLC_PWM_CTL I915 register. This problem was
introduced in kernel version 2.6.38 when the PCI device of this system
was first supported by the i915 KMS module.

This patch adds a parameter to the i915 module to enable inversion of
the brightness variable (i915.invert_brightness).

Signed-off-by: Carsten Emde <[email protected]>
Reviewed-by: Chris Wilson <[email protected]>
Signed-off-by: Daniel Vetter <[email protected]>
Acked-by: Jani Nikula <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
Documentation/kernel-parameters.txt | 9 +++++++++
drivers/gpu/drm/i915/intel_panel.c | 17 +++++++++++++++++
2 files changed, 26 insertions(+)

--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -948,6 +948,15 @@ bytes respectively. Such letter suffixes
i8k.restricted [HW] Allow controlling fans only if SYS_ADMIN
capability is set.

+ i915.invert_brightness
+ [DRM] Invert the sense of the variable that is used to
+ set the brightness of the panel backlight. Normally a
+ value of 0 indicates backlight switched off, and the
+ maximum value sets the backlight to maximum brightness.
+ If this parameter is specified, a value of 0 sets the
+ backlight to maximum brightness, and the maximum value
+ switches the backlight off.
+
icn= [HW,ISDN]
Format: <io>[,<membase>[,<icn_id>[,<icn_id2>]]]

--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -28,6 +28,7 @@
* Chris Wilson <[email protected]>
*/

+#include <linux/moduleparam.h>
#include "intel_drv.h"

#define PCI_LBPC 0xf4 /* legacy/combination backlight modes */
@@ -191,6 +192,20 @@ u32 intel_panel_get_max_backlight(struct
return max;
}

+static bool i915_panel_invert_brightness;
+MODULE_PARM_DESC(invert_brightness, "Invert backlight brightness, please "
+ "report PCI device ID, subsystem vendor and subsystem device ID "
+ "to [email protected], if your machine needs it. "
+ "It will then be included in an upcoming module version.");
+module_param_named(invert_brightness, i915_panel_invert_brightness, bool, 0600);
+static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val)
+{
+ if (i915_panel_invert_brightness)
+ return intel_panel_get_max_backlight(dev) - val;
+
+ return val;
+}
+
u32 intel_panel_get_backlight(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -211,6 +226,7 @@ u32 intel_panel_get_backlight(struct drm
}
}

+ val = intel_panel_compute_brightness(dev, val);
DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val);
return val;
}
@@ -228,6 +244,7 @@ static void intel_panel_actually_set_bac
u32 tmp;

DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
+ level = intel_panel_compute_brightness(dev, level);

if (HAS_PCH_SPLIT(dev))
return intel_pch_panel_set_backlight(dev, level);

2013-04-22 14:46:04

by Ben Hutchings

[permalink] [raw]
Subject: [64/75] ALSA: hda - Enabling Realtek ALC 671 codec

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Rainer Koenig <[email protected]>

commit 1d87caa69c04008e09f5ff47b5e6acb6116febc7 upstream.

* Added the device ID to the modalias list and assinged ALC662 patches
for it
* Added 4 port support for the device ID 0671 in alc662_parse_auto_config

Signed-off-by: Rainer Koenig <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
sound/pci/hda/patch_realtek.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -5595,7 +5595,8 @@ static int alc662_parse_auto_config(stru
const hda_nid_t *ssids;

if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
- codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
+ codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670 ||
+ codec->vendor_id == 0x10ec0671)
ssids = alc663_ssids;
else
ssids = alc662_ssids;
@@ -6045,6 +6046,7 @@ static const struct hda_codec_preset snd
{ .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
{ .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 },
{ .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
+ { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 },
{ .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },

2013-04-22 14:46:24

by Ben Hutchings

[permalink] [raw]
Subject: [61/75] drm/i915: add quirk to invert brightness on eMachines e725

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Jani Nikula <[email protected]>

commit 01e3a8feb40e54b962a20fa7eb595c5efef5e109 upstream.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=31522#c35
[Note: There are more than one broken setups in the bug. This fixes one.]
Reported-by: Martins <[email protected]>
Signed-off-by: Jani Nikula <[email protected]>
Signed-off-by: Daniel Vetter <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/i915/intel_display.c | 3 +++
1 file changed, 3 insertions(+)

--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8910,6 +8910,9 @@ struct intel_quirk intel_quirks[] = {

/* Acer/eMachines G725 */
{ 0x2a42, 0x1025, 0x0210, quirk_invert_brightness },
+
+ /* Acer/eMachines e725 */
+ { 0x2a42, 0x1025, 0x0212, quirk_invert_brightness },
};

static void intel_init_quirks(struct drm_device *dev)

2013-04-22 14:46:44

by Ben Hutchings

[permalink] [raw]
Subject: [59/75] DRM/i915: Add QUIRK_INVERT_BRIGHTNESS for NCR machines.

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Egbert Eich <[email protected]>

commit 5f85f176c2f1c9d2a23f60ca0b99e4d0aa5a26a7 upstream.

NCR machines with LVDS panels using Intel chipsets need to have the
QUIRK_INVERT_BRIGHTNESS bit set.
Unfortunately NCR doesn't set a meaningful subvendor/subdevice ID,
therefore we add a DMI dependent quirk list.

Signed-off-by: Egbert Eich <[email protected]>
[danvet: fixup whitespace fail.]
Signed-off-by: Daniel Vetter <[email protected]>
Acked-by: Jani Nikula <[email protected]>
[bwh: Backported to 3.2:
- Adjust context
- Add #include <linux/dmi.h>]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/i915/intel_display.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)

--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -25,6 +25,7 @@
*/

#include <linux/cpufreq.h>
+#include <linux/dmi.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/i2c.h>
@@ -8848,6 +8849,34 @@ struct intel_quirk {
void (*hook)(struct drm_device *dev);
};

+/* For systems that don't have a meaningful PCI subdevice/subvendor ID */
+struct intel_dmi_quirk {
+ void (*hook)(struct drm_device *dev);
+ const struct dmi_system_id (*dmi_id_list)[];
+};
+
+static int intel_dmi_reverse_brightness(const struct dmi_system_id *id)
+{
+ DRM_INFO("Backlight polarity reversed on %s\n", id->ident);
+ return 1;
+}
+
+static const struct intel_dmi_quirk intel_dmi_quirks[] = {
+ {
+ .dmi_id_list = &(const struct dmi_system_id[]) {
+ {
+ .callback = intel_dmi_reverse_brightness,
+ .ident = "NCR Corporation",
+ .matches = {DMI_MATCH(DMI_SYS_VENDOR, "NCR Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, ""),
+ },
+ },
+ { } /* terminating entry */
+ },
+ .hook = quirk_invert_brightness,
+ },
+};
+
struct intel_quirk intel_quirks[] = {
/* HP Compaq 2730p needs pipe A force quirk (LP: #291555) */
{ 0x2a42, 0x103c, 0x30eb, quirk_pipea_force },
@@ -8895,6 +8924,10 @@ static void intel_init_quirks(struct drm
q->subsystem_device == PCI_ANY_ID))
q->hook(dev);
}
+ for (i = 0; i < ARRAY_SIZE(intel_dmi_quirks); i++) {
+ if (dmi_check_system(*intel_dmi_quirks[i].dmi_id_list) != 0)
+ intel_dmi_quirks[i].hook(dev);
+ }
}

/* Disable the VGA plane that we never use */

2013-04-22 14:29:49

by Ben Hutchings

[permalink] [raw]
Subject: [74/75] KVM: Allow cross page reads and writes from cached translations.

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Andrew Honig <[email protected]>

commit 8f964525a121f2ff2df948dac908dcc65be21b5b upstream.

This patch adds support for kvm_gfn_to_hva_cache_init functions for
reads and writes that will cross a page. If the range falls within
the same memslot, then this will be a fast operation. If the range
is split between two memslots, then the slower kvm_read_guest and
kvm_write_guest are used.

Tested: Test against kvm_clock unit tests.

Signed-off-by: Andrew Honig <[email protected]>
Signed-off-by: Gleb Natapov <[email protected]>
[bwh: Backported to 3.2:
- Drop change in lapic.c
- Keep using __gfn_to_memslot() in kvm_gfn_to_hva_cache_init()]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1480,7 +1480,8 @@ static int kvm_pv_enable_async_pf(struct
return 0;
}

- if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa))
+ if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa,
+ sizeof(u32)))
return 1;

vcpu->arch.apf.send_user_only = !(data & KVM_ASYNC_PF_SEND_ALWAYS);
@@ -1594,12 +1595,9 @@ int kvm_set_msr_common(struct kvm_vcpu *

gpa_offset = data & ~(PAGE_MASK | 1);

- /* Check that the address is 32-byte aligned. */
- if (gpa_offset & (sizeof(struct pvclock_vcpu_time_info) - 1))
- break;
-
if (kvm_gfn_to_hva_cache_init(vcpu->kvm,
- &vcpu->arch.pv_time, data & ~1ULL))
+ &vcpu->arch.pv_time, data & ~1ULL,
+ sizeof(struct pvclock_vcpu_time_info)))
vcpu->arch.pv_time_enabled = false;
else
vcpu->arch.pv_time_enabled = true;
@@ -1618,7 +1616,8 @@ int kvm_set_msr_common(struct kvm_vcpu *
return 1;

if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.st.stime,
- data & KVM_STEAL_VALID_BITS))
+ data & KVM_STEAL_VALID_BITS,
+ sizeof(struct kvm_steal_time)))
return 1;

vcpu->arch.st.msr_val = data;
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -396,7 +396,7 @@ int kvm_write_guest(struct kvm *kvm, gpa
int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
void *data, unsigned long len);
int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
- gpa_t gpa);
+ gpa_t gpa, unsigned long len);
int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len);
int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len);
struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn);
--- a/include/linux/kvm_types.h
+++ b/include/linux/kvm_types.h
@@ -71,6 +71,7 @@ struct gfn_to_hva_cache {
u64 generation;
gpa_t gpa;
unsigned long hva;
+ unsigned long len;
struct kvm_memory_slot *memslot;
};

--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1401,21 +1401,38 @@ int kvm_write_guest(struct kvm *kvm, gpa
}

int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
- gpa_t gpa)
+ gpa_t gpa, unsigned long len)
{
struct kvm_memslots *slots = kvm_memslots(kvm);
int offset = offset_in_page(gpa);
- gfn_t gfn = gpa >> PAGE_SHIFT;
+ gfn_t start_gfn = gpa >> PAGE_SHIFT;
+ gfn_t end_gfn = (gpa + len - 1) >> PAGE_SHIFT;
+ gfn_t nr_pages_needed = end_gfn - start_gfn + 1;
+ gfn_t nr_pages_avail;

ghc->gpa = gpa;
ghc->generation = slots->generation;
- ghc->memslot = __gfn_to_memslot(slots, gfn);
- ghc->hva = gfn_to_hva_many(ghc->memslot, gfn, NULL);
- if (!kvm_is_error_hva(ghc->hva))
+ ghc->len = len;
+ ghc->memslot = __gfn_to_memslot(slots, start_gfn);
+ ghc->hva = gfn_to_hva_many(ghc->memslot, start_gfn, &nr_pages_avail);
+ if (!kvm_is_error_hva(ghc->hva) && nr_pages_avail >= nr_pages_needed) {
ghc->hva += offset;
- else
- return -EFAULT;
-
+ } else {
+ /*
+ * If the requested region crosses two memslots, we still
+ * verify that the entire region is valid here.
+ */
+ while (start_gfn <= end_gfn) {
+ ghc->memslot = __gfn_to_memslot(slots, start_gfn);
+ ghc->hva = gfn_to_hva_many(ghc->memslot, start_gfn,
+ &nr_pages_avail);
+ if (kvm_is_error_hva(ghc->hva))
+ return -EFAULT;
+ start_gfn += nr_pages_avail;
+ }
+ /* Use the slow path for cross page reads and writes. */
+ ghc->memslot = NULL;
+ }
return 0;
}
EXPORT_SYMBOL_GPL(kvm_gfn_to_hva_cache_init);
@@ -1426,8 +1443,13 @@ int kvm_write_guest_cached(struct kvm *k
struct kvm_memslots *slots = kvm_memslots(kvm);
int r;

+ BUG_ON(len > ghc->len);
+
if (slots->generation != ghc->generation)
- kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa);
+ kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa, ghc->len);
+
+ if (unlikely(!ghc->memslot))
+ return kvm_write_guest(kvm, ghc->gpa, data, len);

if (kvm_is_error_hva(ghc->hva))
return -EFAULT;
@@ -1447,8 +1469,13 @@ int kvm_read_guest_cached(struct kvm *kv
struct kvm_memslots *slots = kvm_memslots(kvm);
int r;

+ BUG_ON(len > ghc->len);
+
if (slots->generation != ghc->generation)
- kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa);
+ kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa, ghc->len);
+
+ if (unlikely(!ghc->memslot))
+ return kvm_read_guest(kvm, ghc->gpa, data, len);

if (kvm_is_error_hva(ghc->hva))
return -EFAULT;

2013-04-22 14:47:08

by Ben Hutchings

[permalink] [raw]
Subject: [65/75] ALSA: hda - fix typo in proc output

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: David Henningsson <[email protected]>

commit aeb3a97222832e5457c4b72d72235098ce4bfe8d upstream.

Rename "Digitial In" to "Digital In". This function is only used for
proc output, so should not cause any problems to change.

Signed-off-by: David Henningsson <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
sound/pci/hda/hda_codec.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -163,7 +163,7 @@ const char *snd_hda_get_jack_type(u32 cf
"Line Out", "Speaker", "HP Out", "CD",
"SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
"Line In", "Aux", "Mic", "Telephony",
- "SPDIF In", "Digitial In", "Reserved", "Other"
+ "SPDIF In", "Digital In", "Reserved", "Other"
};

return jack_types[(cfg & AC_DEFCFG_DEVICE)

2013-04-22 14:29:45

by Ben Hutchings

[permalink] [raw]
Subject: [18/75] crypto: gcm - fix assumption that assoc has one segment

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Jussi Kivilinna <[email protected]>

commit d3dde52209ab571e4e2ec26c66f85ad1355f7475 upstream.

rfc4543(gcm(*)) code for GMAC assumes that assoc scatterlist always contains
only one segment and only makes use of this first segment. However ipsec passes
assoc with three segments when using 'extended sequence number' thus in this
case rfc4543(gcm(*)) fails to function correctly. Patch fixes this issue.

Reported-by: Chaoxing Lin <[email protected]>
Tested-by: Chaoxing Lin <[email protected]>
Signed-off-by: Jussi Kivilinna <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
crypto/gcm.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)

--- a/crypto/gcm.c
+++ b/crypto/gcm.c
@@ -44,6 +44,7 @@ struct crypto_rfc4543_ctx {

struct crypto_rfc4543_req_ctx {
u8 auth_tag[16];
+ u8 assocbuf[32];
struct scatterlist cipher[1];
struct scatterlist payload[2];
struct scatterlist assoc[2];
@@ -1142,9 +1143,19 @@ static struct aead_request *crypto_rfc45
scatterwalk_crypto_chain(payload, dst, vdst == req->iv + 8, 2);
assoclen += 8 + req->cryptlen - (enc ? 0 : authsize);

- sg_init_table(assoc, 2);
- sg_set_page(assoc, sg_page(req->assoc), req->assoc->length,
- req->assoc->offset);
+ if (req->assoc->length == req->assoclen) {
+ sg_init_table(assoc, 2);
+ sg_set_page(assoc, sg_page(req->assoc), req->assoc->length,
+ req->assoc->offset);
+ } else {
+ BUG_ON(req->assoclen > sizeof(rctx->assocbuf));
+
+ scatterwalk_map_and_copy(rctx->assocbuf, req->assoc, 0,
+ req->assoclen, 0);
+
+ sg_init_table(assoc, 2);
+ sg_set_buf(assoc, rctx->assocbuf, req->assoclen);
+ }
scatterwalk_crypto_chain(assoc, payload, 0, 2);

aead_request_set_tfm(subreq, ctx->child);

2013-04-22 14:47:51

by Ben Hutchings

[permalink] [raw]
Subject: [71/75] KVM: x86: fix for buffer overflow in handling of MSR_KVM_SYSTEM_TIME (CVE-2013-1796)

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Andy Honig <[email protected]>

commit c300aa64ddf57d9c5d9c898a64b36877345dd4a9 upstream.

If the guest sets the GPA of the time_page so that the request to update the
time straddles a page then KVM will write onto an incorrect page. The
write is done byusing kmap atomic to get a pointer to the page for the time
structure and then performing a memcpy to that page starting at an offset
that the guest controls. Well behaved guests always provide a 32-byte aligned
address, however a malicious guest could use this to corrupt host kernel
memory.

Tested: Tested against kvmclock unit test.

Signed-off-by: Andrew Honig <[email protected]>
Signed-off-by: Marcelo Tosatti <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/x86/kvm/x86.c | 5 +++++
1 file changed, 5 insertions(+)

--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1603,6 +1603,11 @@ int kvm_set_msr_common(struct kvm_vcpu *
/* ...but clean it before doing the actual write */
vcpu->arch.time_offset = data & ~(PAGE_MASK | 1);

+ /* Check that the address is 32-byte aligned. */
+ if (vcpu->arch.time_offset &
+ (sizeof(struct pvclock_vcpu_time_info) - 1))
+ break;
+
vcpu->arch.time_page =
gfn_to_page(vcpu->kvm, data >> PAGE_SHIFT);

2013-04-22 14:29:43

by Ben Hutchings

[permalink] [raw]
Subject: [72/75] KVM: x86: Convert MSR_KVM_SYSTEM_TIME to use gfn_to_hva_cache functions (CVE-2013-1797)

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Andy Honig <[email protected]>

commit 0b79459b482e85cb7426aa7da683a9f2c97aeae1 upstream.

There is a potential use after free issue with the handling of
MSR_KVM_SYSTEM_TIME. If the guest specifies a GPA in a movable or removable
memory such as frame buffers then KVM might continue to write to that
address even after it's removed via KVM_SET_USER_MEMORY_REGION. KVM pins
the page in memory so it's unlikely to cause an issue, but if the user
space component re-purposes the memory previously used for the guest, then
the guest will be able to corrupt that memory.

Tested: Tested against kvmclock unit test

Signed-off-by: Andrew Honig <[email protected]>
Signed-off-by: Marcelo Tosatti <[email protected]>
[bwh: Backported to 3.2:
- Adjust context
- We do not implement the PVCLOCK_GUEST_STOPPED flag]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -393,8 +393,8 @@ struct kvm_vcpu_arch {
gpa_t time;
struct pvclock_vcpu_time_info hv_clock;
unsigned int hw_tsc_khz;
- unsigned int time_offset;
- struct page *time_page;
+ struct gfn_to_hva_cache pv_time;
+ bool pv_time_enabled;

struct {
u64 msr_val;
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1105,7 +1105,6 @@ static int kvm_guest_time_update(struct
{
unsigned long flags;
struct kvm_vcpu_arch *vcpu = &v->arch;
- void *shared_kaddr;
unsigned long this_tsc_khz;
s64 kernel_ns, max_kernel_ns;
u64 tsc_timestamp;
@@ -1141,7 +1140,7 @@ static int kvm_guest_time_update(struct

local_irq_restore(flags);

- if (!vcpu->time_page)
+ if (!vcpu->pv_time_enabled)
return 0;

/*
@@ -1199,14 +1198,9 @@ static int kvm_guest_time_update(struct
*/
vcpu->hv_clock.version += 2;

- shared_kaddr = kmap_atomic(vcpu->time_page, KM_USER0);
-
- memcpy(shared_kaddr + vcpu->time_offset, &vcpu->hv_clock,
- sizeof(vcpu->hv_clock));
-
- kunmap_atomic(shared_kaddr, KM_USER0);
-
- mark_page_dirty(v->kvm, vcpu->time >> PAGE_SHIFT);
+ kvm_write_guest_cached(v->kvm, &vcpu->pv_time,
+ &vcpu->hv_clock,
+ sizeof(vcpu->hv_clock));
return 0;
}

@@ -1496,10 +1490,7 @@ static int kvm_pv_enable_async_pf(struct

static void kvmclock_reset(struct kvm_vcpu *vcpu)
{
- if (vcpu->arch.time_page) {
- kvm_release_page_dirty(vcpu->arch.time_page);
- vcpu->arch.time_page = NULL;
- }
+ vcpu->arch.pv_time_enabled = false;
}

static void accumulate_steal_time(struct kvm_vcpu *vcpu)
@@ -1591,6 +1582,7 @@ int kvm_set_msr_common(struct kvm_vcpu *
break;
case MSR_KVM_SYSTEM_TIME_NEW:
case MSR_KVM_SYSTEM_TIME: {
+ u64 gpa_offset;
kvmclock_reset(vcpu);

vcpu->arch.time = data;
@@ -1600,21 +1592,17 @@ int kvm_set_msr_common(struct kvm_vcpu *
if (!(data & 1))
break;

- /* ...but clean it before doing the actual write */
- vcpu->arch.time_offset = data & ~(PAGE_MASK | 1);
+ gpa_offset = data & ~(PAGE_MASK | 1);

/* Check that the address is 32-byte aligned. */
- if (vcpu->arch.time_offset &
- (sizeof(struct pvclock_vcpu_time_info) - 1))
+ if (gpa_offset & (sizeof(struct pvclock_vcpu_time_info) - 1))
break;

- vcpu->arch.time_page =
- gfn_to_page(vcpu->kvm, data >> PAGE_SHIFT);
-
- if (is_error_page(vcpu->arch.time_page)) {
- kvm_release_page_clean(vcpu->arch.time_page);
- vcpu->arch.time_page = NULL;
- }
+ if (kvm_gfn_to_hva_cache_init(vcpu->kvm,
+ &vcpu->arch.pv_time, data & ~1ULL))
+ vcpu->arch.pv_time_enabled = false;
+ else
+ vcpu->arch.pv_time_enabled = true;
break;
}
case MSR_KVM_ASYNC_PF_EN:
@@ -6554,6 +6542,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *
if (!zalloc_cpumask_var(&vcpu->arch.wbinvd_dirty_mask, GFP_KERNEL))
goto fail_free_mce_banks;

+ vcpu->arch.pv_time_enabled = false;
kvm_async_pf_hash_reset(vcpu);

return 0;

2013-04-22 14:29:42

by Ben Hutchings

[permalink] [raw]
Subject: [68/75] mtd: Disable mtdchar mmap on MMU systems

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: David Woodhouse <[email protected]>

commit f5cf8f07423b2677cebebcebc863af77223a4972 upstream.

This code was broken because it assumed that all MTD devices were map-based.
Disable it for now, until it can be fixed properly for the next merge window.

Signed-off-by: David Woodhouse <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/mtd/mtdchar.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -1154,7 +1154,11 @@ static int mtd_mmap(struct file *file, s
unsigned long off;
u32 len;

- if (mtd->type == MTD_RAM || mtd->type == MTD_ROM) {
+ /* This is broken because it assumes the MTD device is map-based
+ and that mtd->priv is a valid struct map_info. It should be
+ replaced with something that uses the mtd_get_unmapped_area()
+ operation properly. */
+ if (0 /*mtd->type == MTD_RAM || mtd->type == MTD_ROM*/) {
off = vma->vm_pgoff << PAGE_SHIFT;
start = map->phys;
len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size);

2013-04-22 14:48:28

by Ben Hutchings

[permalink] [raw]
Subject: [67/75] r8169: fix auto speed down issue

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: hayeswang <[email protected]>

commit e2409d83434d77874b461b78af6a19cd6e6a1280 upstream.

It would cause no link after suspending or shutdowning when the
nic changes the speed to 10M and connects to a link partner which
forces the speed to 100M.

Check the link partner ability to determine which speed to set.

Signed-off-by: Hayes Wang <[email protected]>
Acked-by: Francois Romieu <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/ethernet/realtek/r8169.c | 28 +++++++++++++++++++++++++---
1 file changed, 25 insertions(+), 3 deletions(-)

--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -3516,6 +3516,30 @@ static void __devinit rtl_init_mdio_ops(
}
}

+static void rtl_speed_down(struct rtl8169_private *tp)
+{
+ u32 adv;
+ int lpa;
+
+ rtl_writephy(tp, 0x1f, 0x0000);
+ lpa = rtl_readphy(tp, MII_LPA);
+
+ if (lpa & (LPA_10HALF | LPA_10FULL))
+ adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full;
+ else if (lpa & (LPA_100HALF | LPA_100FULL))
+ adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
+ else
+ adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
+ (tp->mii.supports_gmii ?
+ ADVERTISED_1000baseT_Half |
+ ADVERTISED_1000baseT_Full : 0);
+
+ rtl8169_set_speed(tp->dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL,
+ adv);
+}
+
static void rtl_wol_suspend_quirk(struct rtl8169_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
@@ -3541,9 +3565,7 @@ static bool rtl_wol_pll_power_down(struc
if (!(__rtl8169_get_wol(tp) & WAKE_ANY))
return false;

- rtl_writephy(tp, 0x1f, 0x0000);
- rtl_writephy(tp, MII_BMCR, 0x0000);
-
+ rtl_speed_down(tp);
rtl_wol_suspend_quirk(tp);

return true;

2013-04-22 14:48:51

by Ben Hutchings

[permalink] [raw]
Subject: [73/75] KVM: Fix bounds checking in ioapic indirect register reads (CVE-2013-1798)

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Andy Honig <[email protected]>

commit a2c118bfab8bc6b8bb213abfc35201e441693d55 upstream.

If the guest specifies a IOAPIC_REG_SELECT with an invalid value and follows
that with a read of the IOAPIC_REG_WINDOW KVM does not properly validate
that request. ioapic_read_indirect contains an
ASSERT(redir_index < IOAPIC_NUM_PINS), but the ASSERT has no effect in
non-debug builds. In recent kernels this allows a guest to cause a kernel
oops by reading invalid memory. In older kernels (pre-3.3) this allows a
guest to read from large ranges of host memory.

Tested: tested against apic unit tests.

Signed-off-by: Andrew Honig <[email protected]>
Signed-off-by: Marcelo Tosatti <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
virt/kvm/ioapic.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)

--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -73,9 +73,12 @@ static unsigned long ioapic_read_indirec
u32 redir_index = (ioapic->ioregsel - 0x10) >> 1;
u64 redir_content;

- ASSERT(redir_index < IOAPIC_NUM_PINS);
+ if (redir_index < IOAPIC_NUM_PINS)
+ redir_content =
+ ioapic->redirtbl[redir_index].bits;
+ else
+ redir_content = ~0ULL;

- redir_content = ioapic->redirtbl[redir_index].bits;
result = (ioapic->ioregsel & 0x1) ?
(redir_content >> 32) & 0xffffffff :
redir_content & 0xffffffff;

2013-04-22 14:29:39

by Ben Hutchings

[permalink] [raw]
Subject: [62/75] drm/i915: add quirk to invert brightness on Packard Bell NCL20

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Jani Nikula <[email protected]>

commit 5559ecadad5a73b27f863e92f4b4f369501dce6f upstream.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=44156
Reported-by: Alan Zimmerman <[email protected]>
Signed-off-by: Jani Nikula <[email protected]>
Signed-off-by: Daniel Vetter <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/i915/intel_display.c | 3 +++
1 file changed, 3 insertions(+)

--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8913,6 +8913,9 @@ struct intel_quirk intel_quirks[] = {

/* Acer/eMachines e725 */
{ 0x2a42, 0x1025, 0x0212, quirk_invert_brightness },
+
+ /* Acer/Packard Bell NCL20 */
+ { 0x2a42, 0x1025, 0x034b, quirk_invert_brightness },
};

static void intel_init_quirks(struct drm_device *dev)

2013-04-22 14:49:26

by Ben Hutchings

[permalink] [raw]
Subject: [70/75] hfsplus: fix potential overflow in hfsplus_file_truncate()

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Vyacheslav Dubeyko <[email protected]>

commit 12f267a20aecf8b84a2a9069b9011f1661c779b4 upstream.

Change a u32 to loff_t hfsplus_file_truncate().

Signed-off-by: Vyacheslav Dubeyko <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Hin-Tak Leung <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/hfsplus/extents.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/fs/hfsplus/extents.c
+++ b/fs/hfsplus/extents.c
@@ -517,7 +517,7 @@ void hfsplus_file_truncate(struct inode
struct address_space *mapping = inode->i_mapping;
struct page *page;
void *fsdata;
- u32 size = inode->i_size;
+ loff_t size = inode->i_size;

res = pagecache_write_begin(NULL, mapping, size, 0,
AOP_FLAG_UNINTERRUPTIBLE,

2013-04-22 14:49:24

by Ben Hutchings

[permalink] [raw]
Subject: [75/75] sched: Convert BUG_ON()s in try_to_wake_up_local() to WARN_ON_ONCE()s

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Tejun Heo <[email protected]>

commit 383efcd00053ec40023010ce5034bd702e7ab373 upstream.

try_to_wake_up_local() should only be invoked to wake up another
task in the same runqueue and BUG_ON()s are used to enforce the
rule. Missing try_to_wake_up_local() can stall workqueue
execution but such stalls are likely to be finite either by
another work item being queued or the one blocked getting
unblocked. There's no reason to trigger BUG while holding rq
lock crashing the whole system.

Convert BUG_ON()s in try_to_wake_up_local() to WARN_ON_ONCE()s.

Signed-off-by: Tejun Heo <[email protected]>
Acked-by: Steven Rostedt <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
[bwh: Backported to 3.2: adjust filename]
Signed-off-by: Ben Hutchings <[email protected]>
---
kernel/sched.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -2889,8 +2889,10 @@ static void try_to_wake_up_local(struct
{
struct rq *rq = task_rq(p);

- BUG_ON(rq != this_rq());
- BUG_ON(p == current);
+ if (WARN_ON_ONCE(rq != this_rq()) ||
+ WARN_ON_ONCE(p == current))
+ return;
+
lockdep_assert_held(&rq->lock);

if (!raw_spin_trylock(&p->pi_lock)) {

2013-04-22 14:50:29

by Ben Hutchings

[permalink] [raw]
Subject: [16/75] USB: ti_usb_3410_5052: fix use-after-free in TIOCMIWAIT

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Johan Hovold <[email protected]>

commit fc98ab873aa3dbe783ce56a2ffdbbe7c7609521a upstream.

Use the port wait queue and make sure to check the serial disconnected
flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue
itself) can be gone when waking up after a disconnect.

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]ndation.org>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/ti_usb_3410_5052.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -75,7 +75,6 @@ struct ti_port {
int tp_flags;
int tp_closing_wait;/* in .01 secs */
struct async_icount tp_icount;
- wait_queue_head_t tp_msr_wait; /* wait for msr change */
wait_queue_head_t tp_write_wait;
struct ti_device *tp_tdev;
struct usb_serial_port *tp_port;
@@ -447,7 +446,6 @@ static int ti_startup(struct usb_serial
tport->tp_uart_base_addr = (i == 0 ?
TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR);
tport->tp_closing_wait = closing_wait;
- init_waitqueue_head(&tport->tp_msr_wait);
init_waitqueue_head(&tport->tp_write_wait);
if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE,
GFP_KERNEL)) {
@@ -848,9 +846,13 @@ static int ti_ioctl(struct tty_struct *t
dbg("%s - (%d) TIOCMIWAIT", __func__, port->number);
cprev = tport->tp_icount;
while (1) {
- interruptible_sleep_on(&tport->tp_msr_wait);
+ interruptible_sleep_on(&port->delta_msr_wait);
if (signal_pending(current))
return -ERESTARTSYS;
+
+ if (port->serial->disconnected)
+ return -EIO;
+
cnow = tport->tp_icount;
if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
@@ -1481,7 +1483,7 @@ static void ti_handle_new_msr(struct ti_
icount->dcd++;
if (msr & TI_MSR_DELTA_RI)
icount->rng++;
- wake_up_interruptible(&tport->tp_msr_wait);
+ wake_up_interruptible(&tport->tp_port->delta_msr_wait);
spin_unlock_irqrestore(&tport->tp_lock, flags);
}

2013-04-22 14:50:27

by Ben Hutchings

[permalink] [raw]
Subject: [17/75] hrtimer: Don't reinitialize a cpu_base lock on CPU_UP

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Michael Bohan <[email protected]>

commit 84cc8fd2fe65866e49d70b38b3fdf7219dd92fe0 upstream.

The current code makes the assumption that a cpu_base lock won't be
held if the CPU corresponding to that cpu_base is offline, which isn't
always true.

If a hrtimer is not queued, then it will not be migrated by
migrate_hrtimers() when a CPU is offlined. Therefore, the hrtimer's
cpu_base may still point to a CPU which has subsequently gone offline
if the timer wasn't enqueued at the time the CPU went down.

Normally this wouldn't be a problem, but a cpu_base's lock is blindly
reinitialized each time a CPU is brought up. If a CPU is brought
online during the period that another thread is performing a hrtimer
operation on a stale hrtimer, then the lock will be reinitialized
under its feet, and a SPIN_BUG() like the following will be observed:

<0>[ 28.082085] BUG: spinlock already unlocked on CPU#0, swapper/0/0
<0>[ 28.087078] lock: 0xc4780b40, value 0x0 .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1
<4>[ 42.451150] [<c0014398>] (unwind_backtrace+0x0/0x120) from [<c0269220>] (do_raw_spin_unlock+0x44/0xdc)
<4>[ 42.460430] [<c0269220>] (do_raw_spin_unlock+0x44/0xdc) from [<c071b5bc>] (_raw_spin_unlock+0x8/0x30)
<4>[ 42.469632] [<c071b5bc>] (_raw_spin_unlock+0x8/0x30) from [<c00a9ce0>] (__hrtimer_start_range_ns+0x1e4/0x4f8)
<4>[ 42.479521] [<c00a9ce0>] (__hrtimer_start_range_ns+0x1e4/0x4f8) from [<c00aa014>] (hrtimer_start+0x20/0x28)
<4>[ 42.489247] [<c00aa014>] (hrtimer_start+0x20/0x28) from [<c00e6190>] (rcu_idle_enter_common+0x1ac/0x320)
<4>[ 42.498709] [<c00e6190>] (rcu_idle_enter_common+0x1ac/0x320) from [<c00e6440>] (rcu_idle_enter+0xa0/0xb8)
<4>[ 42.508259] [<c00e6440>] (rcu_idle_enter+0xa0/0xb8) from [<c000f268>] (cpu_idle+0x24/0xf0)
<4>[ 42.516503] [<c000f268>] (cpu_idle+0x24/0xf0) from [<c06ed3c0>] (rest_init+0x88/0xa0)
<4>[ 42.524319] [<c06ed3c0>] (rest_init+0x88/0xa0) from [<c0c00978>] (start_kernel+0x3d0/0x434)

As an example, this particular crash occurred when hrtimer_start() was
executed on CPU #0. The code locked the hrtimer's current cpu_base
corresponding to CPU #1. CPU #0 then tried to switch the hrtimer's
cpu_base to an optimal CPU which was online. In this case, it selected
the cpu_base corresponding to CPU #3.

Before it could proceed, CPU #1 came online and reinitialized the
spinlock corresponding to its cpu_base. Thus now CPU #0 held a lock
which was reinitialized. When CPU #0 finally ended up unlocking the
old cpu_base corresponding to CPU #1 so that it could switch to CPU
#3, we hit this SPIN_BUG() above while in switch_hrtimer_base().

CPU #0 CPU #1
---- ----
... <offline>
hrtimer_start()
lock_hrtimer_base(base #1)
... init_hrtimers_cpu()
switch_hrtimer_base() ...
... raw_spin_lock_init(&cpu_base->lock)
raw_spin_unlock(&cpu_base->lock) ...
<spin_bug>

Solve this by statically initializing the lock.

Signed-off-by: Michael Bohan <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
kernel/hrtimer.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -61,6 +61,7 @@
DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
{

+ .lock = __RAW_SPIN_LOCK_UNLOCKED(hrtimer_bases.lock),
.clock_base =
{
{
@@ -1640,8 +1641,6 @@ static void __cpuinit init_hrtimers_cpu(
struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu);
int i;

- raw_spin_lock_init(&cpu_base->lock);
-
for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
cpu_base->clock_base[i].cpu_base = cpu_base;
timerqueue_init_head(&cpu_base->clock_base[i].active);

2013-04-22 14:51:08

by Ben Hutchings

[permalink] [raw]
Subject: [13/75] USB: pl2303: fix use-after-free in TIOCMIWAIT

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Johan Hovold <[email protected]>

commit 40509ca982c00c4b70fc00be887509feca0bff15 upstream.

Use the port wait queue and make sure to check the serial disconnected
flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue
itself) can be gone when waking up after a disconnect.

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/pl2303.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)

--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -150,7 +150,6 @@ enum pl2303_type {

struct pl2303_private {
spinlock_t lock;
- wait_queue_head_t delta_msr_wait;
u8 line_control;
u8 line_status;
enum pl2303_type type;
@@ -204,7 +203,6 @@ static int pl2303_startup(struct usb_ser
if (!priv)
goto cleanup;
spin_lock_init(&priv->lock);
- init_waitqueue_head(&priv->delta_msr_wait);
priv->type = type;
usb_set_serial_port_data(serial->port[i], priv);
}
@@ -599,11 +597,14 @@ static int wait_modem_info(struct usb_se
spin_unlock_irqrestore(&priv->lock, flags);

while (1) {
- interruptible_sleep_on(&priv->delta_msr_wait);
+ interruptible_sleep_on(&port->delta_msr_wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;

+ if (port->serial->disconnected)
+ return -EIO;
+
spin_lock_irqsave(&priv->lock, flags);
status = priv->line_status;
spin_unlock_irqrestore(&priv->lock, flags);
@@ -725,7 +726,7 @@ static void pl2303_update_line_status(st
spin_unlock_irqrestore(&priv->lock, flags);
if (priv->line_status & UART_BREAK_ERROR)
usb_serial_handle_break(port);
- wake_up_interruptible(&priv->delta_msr_wait);
+ wake_up_interruptible(&port->delta_msr_wait);

tty = tty_port_tty_get(&port->port);
if (!tty)
@@ -792,7 +793,7 @@ static void pl2303_process_read_urb(stru
line_status = priv->line_status;
priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
spin_unlock_irqrestore(&priv->lock, flags);
- wake_up_interruptible(&priv->delta_msr_wait);
+ wake_up_interruptible(&port->delta_msr_wait);

if (!urb->actual_length)
return;

2013-04-22 14:51:06

by Ben Hutchings

[permalink] [raw]
Subject: [15/75] USB: ssu100: fix use-after-free in TIOCMIWAIT

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Johan Hovold <[email protected]>

commit 43a66b4c417ad15f6d2f632ce67ad195bdf999e8 upstream.

Use the port wait queue and make sure to check the serial disconnected
flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue
itself) can be gone when waking up after a disconnect.

Signed-off-by: Johan Hovold <[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/serial/ssu100.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)

--- a/drivers/usb/serial/ssu100.c
+++ b/drivers/usb/serial/ssu100.c
@@ -78,7 +78,6 @@ struct ssu100_port_private {
spinlock_t status_lock;
u8 shadowLSR;
u8 shadowMSR;
- wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
struct async_icount icount;
};

@@ -387,8 +386,9 @@ static int wait_modem_info(struct usb_se
spin_unlock_irqrestore(&priv->status_lock, flags);

while (1) {
- wait_event_interruptible(priv->delta_msr_wait,
- ((priv->icount.rng != prev.rng) ||
+ wait_event_interruptible(port->delta_msr_wait,
+ (port->serial->disconnected ||
+ (priv->icount.rng != prev.rng) ||
(priv->icount.dsr != prev.dsr) ||
(priv->icount.dcd != prev.dcd) ||
(priv->icount.cts != prev.cts)));
@@ -396,6 +396,9 @@ static int wait_modem_info(struct usb_se
if (signal_pending(current))
return -ERESTARTSYS;

+ if (port->serial->disconnected)
+ return -EIO;
+
spin_lock_irqsave(&priv->status_lock, flags);
cur = priv->icount;
spin_unlock_irqrestore(&priv->status_lock, flags);
@@ -478,7 +481,6 @@ static int ssu100_attach(struct usb_seri
}

spin_lock_init(&priv->status_lock);
- init_waitqueue_head(&priv->delta_msr_wait);
usb_set_serial_port_data(port, priv);

return ssu100_initdevice(serial->dev);
@@ -564,7 +566,7 @@ static void ssu100_update_msr(struct usb
priv->icount.dcd++;
if (msr & UART_MSR_TERI)
priv->icount.rng++;
- wake_up_interruptible(&priv->delta_msr_wait);
+ wake_up_interruptible(&port->delta_msr_wait);
}
}

2013-04-22 14:51:54

by Ben Hutchings

[permalink] [raw]
Subject: [12/75] USB: oti6858: fix use-after-free in TIOCMIWAIT

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Johan Hovold <[email protected]>

commit 8edfdab37157d2683e51b8be5d3d5697f66a9f7b upstream.

Use the port wait queue and make sure to check the serial disconnected
flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue
itself) can be gone when waking up after a disconnect.

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[bwh: Backported to 3.2: adjust context, indentation]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/oti6858.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

--- a/drivers/usb/serial/oti6858.c
+++ b/drivers/usb/serial/oti6858.c
@@ -196,7 +196,6 @@ struct oti6858_private {
u8 setup_done;
struct delayed_work delayed_setup_work;

- wait_queue_head_t intr_wait;
struct usb_serial_port *port; /* USB port with which associated */
};

@@ -357,7 +356,6 @@ static int oti6858_startup(struct usb_se
break;

spin_lock_init(&priv->lock);
- init_waitqueue_head(&priv->intr_wait);
/* INIT_WORK(&priv->setup_work, setup_line, serial->port[i]); */
/* INIT_WORK(&priv->write_work, send_data, serial->port[i]); */
priv->port = port;
@@ -705,11 +703,15 @@ static int wait_modem_info(struct usb_se
spin_unlock_irqrestore(&priv->lock, flags);

while (1) {
- wait_event_interruptible(priv->intr_wait,
+ wait_event_interruptible(port->delta_msr_wait,
+ port->serial->disconnected ||
priv->status.pin_state != prev);
if (signal_pending(current))
return -ERESTARTSYS;

+ if (port->serial->disconnected)
+ return -EIO;
+
spin_lock_irqsave(&priv->lock, flags);
status = priv->status.pin_state & PIN_MASK;
spin_unlock_irqrestore(&priv->lock, flags);
@@ -821,7 +823,7 @@ static void oti6858_read_int_callback(st

if (!priv->transient) {
if (xs->pin_state != priv->status.pin_state)
- wake_up_interruptible(&priv->intr_wait);
+ wake_up_interruptible(&port->delta_msr_wait);
memcpy(&priv->status, xs, OTI6858_CTRL_PKT_SIZE);
}

2013-04-22 14:51:53

by Ben Hutchings

[permalink] [raw]
Subject: [11/75] USB: mos7840: fix use-after-free in TIOCMIWAIT

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Johan Hovold <[email protected]>

commit a14430db686b8e459e1cf070a6ecf391515c9ab9 upstream.

Use the port wait queue and make sure to check the serial disconnected
flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue
itself) can be gone when waking up after a disconnect.

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/mos7840.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)

--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -240,7 +240,6 @@ struct moschip_port {
char open;
char open_ports;
wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */
- wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */
int delta_msr_cond;
struct async_icount icount;
struct usb_serial_port *port; /* loop back to the owner of this object */
@@ -455,7 +454,7 @@ static void mos7840_handle_new_msr(struc
}

mos7840_port->delta_msr_cond = 1;
- wake_up_interruptible(&mos7840_port->delta_msr_wait);
+ wake_up_interruptible(&port->port->delta_msr_wait);
}
}

@@ -1118,7 +1117,6 @@ static int mos7840_open(struct tty_struc

/* initialize our wait queues */
init_waitqueue_head(&mos7840_port->wait_chase);
- init_waitqueue_head(&mos7840_port->delta_msr_wait);

/* initialize our icount structure */
memset(&(mos7840_port->icount), 0x00, sizeof(mos7840_port->icount));
@@ -2285,13 +2283,18 @@ static int mos7840_ioctl(struct tty_stru
while (1) {
/* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */
mos7840_port->delta_msr_cond = 0;
- wait_event_interruptible(mos7840_port->delta_msr_wait,
- (mos7840_port->
+ wait_event_interruptible(port->delta_msr_wait,
+ (port->serial->disconnected ||
+ mos7840_port->
delta_msr_cond == 1));

/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
+
+ if (port->serial->disconnected)
+ return -EIO;
+
cnow = mos7840_port->icount;
smp_rmb();
if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&

2013-04-22 14:52:29

by Ben Hutchings

[permalink] [raw]
Subject: [10/75] USB: mos7840: fix broken TIOCMIWAIT

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Johan Hovold <[email protected]>

commit e670c6af12517d08a403487b1122eecf506021cf upstream.

Make sure waiting processes are woken on modem-status changes.

Currently processes are only woken on termios changes regardless of
whether the modem status has changed.

Signed-off-by: Johan Hovold <[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/serial/mos7840.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -453,6 +453,9 @@ static void mos7840_handle_new_msr(struc
icount->rng++;
smp_wmb();
}
+
+ mos7840_port->delta_msr_cond = 1;
+ wake_up_interruptible(&mos7840_port->delta_msr_wait);
}
}

@@ -2073,8 +2076,6 @@ static void mos7840_change_port_settings
mos7840_port->read_urb_busy = false;
}
}
- wake_up(&mos7840_port->delta_msr_wait);
- mos7840_port->delta_msr_cond = 1;
dbg("mos7840_change_port_settings mos7840_port->shadowLCR is End %x",
mos7840_port->shadowLCR);
}

2013-04-22 14:29:24

by Ben Hutchings

[permalink] [raw]
Subject: [04/75] USB: ch341: fix use-after-free in TIOCMIWAIT

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Johan Hovold <[email protected]>

commit fa1e11d5231c001c80a479160b5832933c5d35fb upstream.

Use the port wait queue and make sure to check the serial disconnected
flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue
itself) can be gone when waking up after a disconnect.

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/ch341.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)

--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -82,7 +82,6 @@ MODULE_DEVICE_TABLE(usb, id_table);

struct ch341_private {
spinlock_t lock; /* access lock */
- wait_queue_head_t delta_msr_wait; /* wait queue for modem status */
unsigned baud_rate; /* set baud rate */
u8 line_control; /* set line control value RTS/DTR */
u8 line_status; /* active status of modem control inputs */
@@ -262,7 +261,6 @@ static int ch341_attach(struct usb_seria
return -ENOMEM;

spin_lock_init(&priv->lock);
- init_waitqueue_head(&priv->delta_msr_wait);
priv->baud_rate = DEFAULT_BAUD_RATE;
priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;

@@ -299,7 +297,7 @@ static void ch341_dtr_rts(struct usb_ser
priv->line_control &= ~(CH341_BIT_RTS | CH341_BIT_DTR);
spin_unlock_irqrestore(&priv->lock, flags);
ch341_set_handshake(port->serial->dev, priv->line_control);
- wake_up_interruptible(&priv->delta_msr_wait);
+ wake_up_interruptible(&port->delta_msr_wait);
}

static void ch341_close(struct usb_serial_port *port)
@@ -503,7 +501,7 @@ static void ch341_read_int_callback(stru
tty_kref_put(tty);
}

- wake_up_interruptible(&priv->delta_msr_wait);
+ wake_up_interruptible(&port->delta_msr_wait);
}

exit:
@@ -529,11 +527,14 @@ static int wait_modem_info(struct usb_se
spin_unlock_irqrestore(&priv->lock, flags);

while (!multi_change) {
- interruptible_sleep_on(&priv->delta_msr_wait);
+ interruptible_sleep_on(&port->delta_msr_wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;

+ if (port->serial->disconnected)
+ return -EIO;
+
spin_lock_irqsave(&priv->lock, flags);
status = priv->line_status;
multi_change = priv->multi_status_change;

2013-04-22 14:29:23

by Ben Hutchings

[permalink] [raw]
Subject: [06/75] USB: ftdi_sio: fix use-after-free in TIOCMIWAIT

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Johan Hovold <[email protected]>

commit 71ccb9b01981fabae27d3c98260ea4613207618e upstream.

Use the port wait queue and make sure to check the serial disconnected
flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue
itself) can be gone when waking up after a disconnect.

When switching to tty ports, some lifetime assumptions were changed.
Specifically, close can now be called before the final tty reference is
dropped as part of hangup at device disconnect. Even with the ftdi
private-data refcounting this means that the port private data can be
freed while a process is sleeping on modem-status changes and thus
cannot be relied on to detect disconnects when woken up.

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/ftdi_sio.c | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)

--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -74,9 +74,7 @@ struct ftdi_private {
int flags; /* some ASYNC_xxxx flags are supported */
unsigned long last_dtr_rts; /* saved modem control outputs */
struct async_icount icount;
- wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
char prev_status; /* Used for TIOCMIWAIT */
- bool dev_gone; /* Used to abort TIOCMIWAIT */
char transmit_empty; /* If transmitter is empty or not */
struct usb_serial_port *port;
__u16 interface; /* FT2232C, FT2232H or FT4232H port interface
@@ -1708,10 +1706,8 @@ static int ftdi_sio_port_probe(struct us
kref_init(&priv->kref);
mutex_init(&priv->cfg_lock);
memset(&priv->icount, 0x00, sizeof(priv->icount));
- init_waitqueue_head(&priv->delta_msr_wait);

priv->flags = ASYNC_LOW_LATENCY;
- priv->dev_gone = false;

if (quirk && quirk->port_probe)
quirk->port_probe(priv);
@@ -1869,8 +1865,7 @@ static int ftdi_sio_port_remove(struct u

dbg("%s", __func__);

- priv->dev_gone = true;
- wake_up_interruptible_all(&priv->delta_msr_wait);
+ wake_up_interruptible(&port->delta_msr_wait);

remove_sysfs_attrs(port);

@@ -2025,7 +2020,7 @@ static int ftdi_process_packet(struct tt
if (diff_status & FTDI_RS0_RLSD)
priv->icount.dcd++;

- wake_up_interruptible_all(&priv->delta_msr_wait);
+ wake_up_interruptible(&port->delta_msr_wait);
priv->prev_status = status;
}

@@ -2424,11 +2419,15 @@ static int ftdi_ioctl(struct tty_struct
*/
case TIOCMIWAIT:
cprev = priv->icount;
- while (!priv->dev_gone) {
- interruptible_sleep_on(&priv->delta_msr_wait);
+ for (;;) {
+ interruptible_sleep_on(&port->delta_msr_wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
+
+ if (port->serial->disconnected)
+ return -EIO;
+
cnow = priv->icount;
if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
@@ -2438,8 +2437,6 @@ static int ftdi_ioctl(struct tty_struct
}
cprev = cnow;
}
- return -EIO;
- break;
case TIOCSERGETLSR:
return get_lsr_info(port, (struct serial_struct __user *)arg);
break;

2013-04-22 14:29:21

by Ben Hutchings

[permalink] [raw]
Subject: [01/75] USB: serial: add modem-status-change wait queue

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Johan Hovold <[email protected]>

commit e5b33dc9d16053c2ae4c2c669cf008829530364b upstream.

Add modem-status-change wait queue to struct usb_serial_port that
subdrivers can use to implement TIOCMIWAIT.

Currently subdrivers use a private wait queue which may have been
released when waking up after device disconnected.

Note that we're adding a new wait queue rather than reusing the tty-port
one as we do not want to get woken up at hangup (yet).

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
include/linux/usb/serial.h | 2 ++
1 file changed, 2 insertions(+)

--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -71,6 +71,7 @@ enum port_dev_state {
* port.
* @flags: usb serial port flags
* @write_wait: a wait_queue_head_t used by the port.
+ * @delta_msr_wait: modem-status-change wait queue
* @work: work queue entry for the line discipline waking up.
* @throttled: nonzero if the read urb is inactive to throttle the device
* @throttle_req: nonzero if the tty wants to throttle us
@@ -114,6 +115,7 @@ struct usb_serial_port {

unsigned long flags;
wait_queue_head_t write_wait;
+ wait_queue_head_t delta_msr_wait;
struct work_struct work;
char throttled;
char throttle_req;

2013-04-22 14:29:19

by Ben Hutchings

[permalink] [raw]
Subject: [03/75] USB: ark3116: fix use-after-free in TIOCMIWAIT

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Johan Hovold <[email protected]>

commit 5018860321dc7a9e50a75d5f319bc981298fb5b7 upstream.

Use the port wait queue and make sure to check the serial disconnected
flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue
itself) can be gone when waking up after a disconnect.

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/ark3116.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

--- a/drivers/usb/serial/ark3116.c
+++ b/drivers/usb/serial/ark3116.c
@@ -68,7 +68,6 @@ static int is_irda(struct usb_serial *se
}

struct ark3116_private {
- wait_queue_head_t delta_msr_wait;
struct async_icount icount;
int irda; /* 1 for irda device */

@@ -148,7 +147,6 @@ static int ark3116_attach(struct usb_ser
if (!priv)
return -ENOMEM;

- init_waitqueue_head(&priv->delta_msr_wait);
mutex_init(&priv->hw_lock);
spin_lock_init(&priv->status_lock);

@@ -460,10 +458,14 @@ static int ark3116_ioctl(struct tty_stru
case TIOCMIWAIT:
for (;;) {
struct async_icount prev = priv->icount;
- interruptible_sleep_on(&priv->delta_msr_wait);
+ interruptible_sleep_on(&port->delta_msr_wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
+
+ if (port->serial->disconnected)
+ return -EIO;
+
if ((prev.rng == priv->icount.rng) &&
(prev.dsr == priv->icount.dsr) &&
(prev.dcd == priv->icount.dcd) &&
@@ -584,7 +586,7 @@ static void ark3116_update_msr(struct us
priv->icount.dcd++;
if (msr & UART_MSR_TERI)
priv->icount.rng++;
- wake_up_interruptible(&priv->delta_msr_wait);
+ wake_up_interruptible(&port->delta_msr_wait);
}
}

2013-04-22 14:29:18

by Ben Hutchings

[permalink] [raw]
Subject: [07/75] USB: io_edgeport: fix use-after-free in TIOCMIWAIT

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Johan Hovold <[email protected]>

commit 333576255d4cfc53efd056aad438568184b36af6 upstream.

Use the port wait queue and make sure to check the serial disconnected
flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue
itself) can be gone when waking up after a disconnect.

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/io_edgeport.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)

--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -114,7 +114,6 @@ struct edgeport_port {
wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */
wait_queue_head_t wait_open; /* for handling sleeping while waiting for open to finish */
wait_queue_head_t wait_command; /* for handling sleeping while waiting for command to finish */
- wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */

struct async_icount icount;
struct usb_serial_port *port; /* loop back to the owner of this object */
@@ -885,7 +884,6 @@ static int edge_open(struct tty_struct *
/* initialize our wait queues */
init_waitqueue_head(&edge_port->wait_open);
init_waitqueue_head(&edge_port->wait_chase);
- init_waitqueue_head(&edge_port->delta_msr_wait);
init_waitqueue_head(&edge_port->wait_command);

/* initialize our icount structure */
@@ -1703,13 +1701,17 @@ static int edge_ioctl(struct tty_struct
dbg("%s (%d) TIOCMIWAIT", __func__, port->number);
cprev = edge_port->icount;
while (1) {
- prepare_to_wait(&edge_port->delta_msr_wait,
+ prepare_to_wait(&port->delta_msr_wait,
&wait, TASK_INTERRUPTIBLE);
schedule();
- finish_wait(&edge_port->delta_msr_wait, &wait);
+ finish_wait(&port->delta_msr_wait, &wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
+
+ if (port->serial->disconnected)
+ return -EIO;
+
cnow = edge_port->icount;
if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
@@ -2090,7 +2092,7 @@ static void handle_new_msr(struct edgepo
icount->dcd++;
if (newMsr & EDGEPORT_MSR_DELTA_RI)
icount->rng++;
- wake_up_interruptible(&edge_port->delta_msr_wait);
+ wake_up_interruptible(&edge_port->port->delta_msr_wait);
}

/* Save the new modem status */

2013-04-22 14:29:16

by Ben Hutchings

[permalink] [raw]
Subject: [05/75] USB: cypress_m8: fix use-after-free in TIOCMIWAIT

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Johan Hovold <[email protected]>

commit 356050d8b1e526db093e9d2c78daf49d6bf418e3 upstream.

Use the port wait queue and make sure to check the serial disconnected
flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue
itself) can be gone when waking up after a disconnect.

Also remove bogus test for private data pointer being NULL as it is
never assigned in the loop.

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/cypress_m8.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)

--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -150,7 +150,6 @@ struct cypress_private {
int baud_rate; /* stores current baud rate in
integer form */
int isthrottled; /* if throttled, discard reads */
- wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */
char prev_status, diff_status; /* used for TIOCMIWAIT */
/* we pass a pointer to this as the argument sent to
cypress_set_termios old_termios */
@@ -488,7 +487,6 @@ static int generic_startup(struct usb_se
kfree(priv);
return -ENOMEM;
}
- init_waitqueue_head(&priv->delta_msr_wait);

usb_reset_configuration(serial->dev);

@@ -928,12 +926,16 @@ static int cypress_ioctl(struct tty_stru
switch (cmd) {
/* This code comes from drivers/char/serial.c and ftdi_sio.c */
case TIOCMIWAIT:
- while (priv != NULL) {
- interruptible_sleep_on(&priv->delta_msr_wait);
+ for (;;) {
+ interruptible_sleep_on(&port->delta_msr_wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
- else {
+
+ if (port->serial->disconnected)
+ return -EIO;
+
+ {
char diff = priv->diff_status;
if (diff == 0)
return -EIO; /* no change => error */
@@ -1261,7 +1263,7 @@ static void cypress_read_int_callback(st
if (priv->current_status != priv->prev_status) {
priv->diff_status |= priv->current_status ^
priv->prev_status;
- wake_up_interruptible(&priv->delta_msr_wait);
+ wake_up_interruptible(&port->delta_msr_wait);
priv->prev_status = priv->current_status;
}
spin_unlock_irqrestore(&priv->lock, flags);

2013-04-22 14:54:08

by Ben Hutchings

[permalink] [raw]
Subject: [08/75] USB: io_ti: fix use-after-free in TIOCMIWAIT

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Johan Hovold <[email protected]>

commit 7b2459690584f239650a365f3411ba2ec1c6d1e0 upstream.

Use the port wait queue and make sure to check the serial disconnected
flag before accessing private port data after waking up.

This is is needed as the private port data (including the wait queue
itself) can be gone when waking up after a disconnect.

Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/io_ti.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -98,9 +98,6 @@ struct edgeport_port {
int close_pending;
int lsr_event;
struct async_icount icount;
- wait_queue_head_t delta_msr_wait; /* for handling sleeping while
- waiting for msr change to
- happen */
struct edgeport_serial *edge_serial;
struct usb_serial_port *port;
__u8 bUartMode; /* Port type, 0: RS232, etc. */
@@ -1557,7 +1554,7 @@ static void handle_new_msr(struct edgepo
icount->dcd++;
if (msr & EDGEPORT_MSR_DELTA_RI)
icount->rng++;
- wake_up_interruptible(&edge_port->delta_msr_wait);
+ wake_up_interruptible(&edge_port->port->delta_msr_wait);
}

/* Save the new modem status */
@@ -1876,7 +1873,6 @@ static int edge_open(struct tty_struct *
dev = port->serial->dev;

memset(&(edge_port->icount), 0x00, sizeof(edge_port->icount));
- init_waitqueue_head(&edge_port->delta_msr_wait);

/* turn off loopback */
status = ti_do_config(edge_port, UMPC_SET_CLR_LOOPBACK, 0);
@@ -2574,10 +2570,14 @@ static int edge_ioctl(struct tty_struct
dbg("%s - (%d) TIOCMIWAIT", __func__, port->number);
cprev = edge_port->icount;
while (1) {
- interruptible_sleep_on(&edge_port->delta_msr_wait);
+ interruptible_sleep_on(&port->delta_msr_wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
+
+ if (port->serial->disconnected)
+ return -EIO;
+
cnow = edge_port->icount;
if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)

2013-04-22 14:54:06

by Ben Hutchings

[permalink] [raw]
Subject: [02/75] USB: serial: fix hang when opening port

3.2.44-rc1 review patch. If anyone has any objections, please let me know.

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

From: Ming Lei <[email protected]>

commit eba0e3c3a0ba7b96f01cbe997680f6a4401a0bfc upstream.

Johan's 'fix use-after-free in TIOCMIWAIT' patchset[1] introduces
one bug which can cause kernel hang when opening port.

This patch initialized the 'port->delta_msr_wait' waitqueue head
to fix the bug which is introduced in 3.9-rc4.

[1], http://marc.info/?l=linux-usb&m=136368139627876&w=2

Signed-off-by: Ming Lei <[email protected]>
Acked-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/serial/usb-serial.c | 1 +
1 file changed, 1 insertion(+)

--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -905,6 +905,7 @@ int usb_serial_probe(struct usb_interfac
port->port.ops = &serial_port_ops;
port->serial = serial;
spin_lock_init(&port->lock);
+ init_waitqueue_head(&port->delta_msr_wait);
/* Keep this for private driver use for the moment but
should probably go away */
INIT_WORK(&port->work, usb_serial_port_work);