2013-03-25 01:42:50

by Ben Hutchings

[permalink] [raw]
Subject: [ 000/104] 3.2.42-stable review

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

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

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

Ben.

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

Alan Stern (1):
usb: gadget: udc-core: fix a regression during gadget driver unbinding
[511f3c5326eabe1ece35202a404c24c0aeacc246]

Alex Deucher (1):
drm/radeon/benchmark: make sure bo blit copy exists before using it
[fa8d387dc3f62062a6b4afbbb2a3438094fd8584]

Ben Hutchings (11):
efivars: Fix check for CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE
[ca0ba26fbbd2d81c43085df49ce0abfe34535a90]
efivars: pstore: Do not check size when erasing variable
[not upstream; this is a fix for an incorrectly backported commit]
perf: Revert duplicated commit
[not upstream; the commits were correctly merged by git]
sfc: Convert firmware subtypes to native byte order in efx_mcdi_get_board_cfg()
[bfeed902946a31692e7a24ed355b6d13ac37d014]
sfc: Detach net device when stopping queues for reconfiguration
[29c69a4882641285a854d6d03ca5adbba68c0034]
sfc: Disable soft interrupt handling during efx_device_detach_sync()
[35205b211c8d17a8a0b5e8926cb7c73e9a7ef1ad]
sfc: Fix efx_rx_buf_offset() in the presence of swiotlb
[06e63c57acbb1df7c35ebe846ae416a8b88dfafa,
b590ace09d51cd39744e0f7662c5e4a0d1b5d952,
c73e787a8db9117d59b5180baf83203a42ecadca]
sfc: Fix timekeeping in efx_mcdi_poll()
[ebf98e797b4e26ad52ace1511a0b503ee60a6cd4]
sfc: Fix two causes of flush failure
[a606f4325dca6950996abbae452d33f2af095f39,
d5e8cc6c946e0857826dcfbb3585068858445bfe,
525d9e824018cd7cc8d8d44832ddcd363abfe6e1]
sfc: Only use TX push if a single descriptor is to be written
[fae8563b25f73dc584a07bcda7a82750ff4f7672]
sfc: Properly sync RX DMA buffer when it is not the last in the page
[3a68f19d7afb80f548d016effbc6ed52643a8085]

Benjamin Herrenschmidt (1):
powerpc: Fix cputable entry for 970MP rev 1.0
[d63ac5f6cf31c8a83170a9509b350c1489a7262b]

Bing Zhao (1):
mwifiex: fix potential out-of-boundary access to ibss rate table
[5f0fabf84d7b52f979dcbafa3d3c530c60d9a92c]

CQ Tang (1):
x86-64: Fix the failure case in copy_user_handle_tail()
[66db3feb486c01349f767b98ebb10b0c3d2d021b]

Cong Wang (1):
rds: limit the size allocated by rds_message_alloc()
[ece6b0a2b25652d684a7ced4ae680a863af041e0]

Cristian Bercaru (1):
bridging: fix rx_handlers return code
[3bc1b1add7a8484cc4a261c3e128dbe1528ce01f]

Dan Carpenter (1):
selinux: use GFP_ATOMIC under spin_lock
[4502403dcf8f5c76abd4dbab8726c8e4ecb5cd34]

Daniel Mack (2):
ALSA: snd-usb: mixer: ignore -EINVAL in snd_usb_mixer_controls()
[83ea5d18d74f032a760fecde78c0210f66f7f70c]
ALSA: snd-usb: mixer: propagate errors up the call chain
[4d7b86c98e445b075c2c4c3757eb6d3d6efbe72e]

Daniel Pieczko (1):
sfc: lock TX queues when calling netif_device_detach()
[c2f3b8e3a44b6fe9e36704e30157ebe1a88c08b1]

David Rientjes (1):
perf,x86: fix link failure for non-Intel configs
[6c4d3bc99b3341067775efd4d9d13cc8e655fd7c]

David Ward (1):
net/ipv4: Ensure that location of timestamp option is stored
[4660c7f498c07c43173142ea95145e9dac5a6d14]

Denis V. Lunev (1):
ipv4: fix definition of FIB_TABLE_HASHSZ
[5b9e12dbf92b441b37136ea71dac59f05f2673a9]

Dmitry Artamonow (1):
usb-storage: add unusual_devs entry for Samsung YP-Z3 mp3 player
[29f86e66428ee083aec106cca1748dc63d98ce23]

Dmitry Torokhov (1):
USB: xhci - fix bit definitions for IMAN register
[f8264340e694604863255cc0276491d17c402390]

Eric Dumazet (2):
tcp: fix skb_availroom()
[16fad69cfe4adbbfa813de516757b87bcae36d93]
tun: add a missing nf_reset() in tun_net_xmit()
[f8af75f3517a24838a36eb5797a1a3e60bf9e276]

Guillaume Nault (1):
l2tp: Restore socket refcount when sendmsg succeeds
[8b82547e33e85fc24d4d172a93c796de1fefa81a]

Hannes Frederic Sowa (2):
inet: limit length of fragment queue hash table bucket lists
[5a3da1fe9561828d0ca7eca664b16ec2b9bf0055]
ipv6: stop multicast forwarding to process interface scoped addresses
[ddf64354af4a702ee0b85d0a285ba74c7278a460]

Hannes Reinecke (1):
USB: xhci: correctly enable interrupts
[00eed9c814cb8f281be6f0f5d8f45025dc0a97eb]

Heiko Carstens (1):
s390/mm: fix flush_tlb_kernel_range()
[f6a70a07079518280022286a1dceb797d12e1edf]

Jan Kara (1):
jbd2: fix use after free in jbd2_journal_dirty_metadata()
[ad56edad089b56300fd13bb9eeb7d0424d978239]

Jeff Layton (1):
cifs: ignore everything in SPNEGO blob after mechTypes
[f853c616883a8de966873a1dab283f1369e275a1]

Jiri Slaby (1):
TTY: do not reset master's packet mode
[b81273a132177edd806476b953f6afeb17b786d5]

Joe Thornber (1):
dm thin: fix discard corruption
[f046f89a99ccfd9408b94c653374ff3065c7edb3]

Johan Hovold (18):
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: garmin_gps: fix memory leak on disconnect
[618aa1068df29c37a58045fe940f9106664153fd]
USB: io_edgeport: fix use-after-free in TIOCMIWAIT
[333576255d4cfc53efd056aad438568184b36af6]
USB: io_ti: fix get_icount for two port adapters
[5492bf3d5655b4954164f69c02955a7fca267611]
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: serial: fix interface refcounting
[d7971051e4df825e0bc11b995e87bfe86355b8e5]
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]

Kees Cook (2):
drm/i915: bounds check execbuffer relocation count
[3118a4f652c7b12c752f3222af0447008f9b2368]
drm/i915: restrict kernel address leak in debugfs
[2563a4524febe8f4a98e717e02436d1aaf672aa2]

Larry Finger (2):
rtlwifi: rtl8192cu: Fix problem that prevents reassociation
[9437a248e7cac427c898bdb11bd1ac6844a1ead4]
rtlwifi: rtl8192cu: Fix schedule while atomic bug splat
[664899786cb49cb52f620e06ac19c0be524a7cfa]

Laxman Dewangan (1):
i2c: tegra: check the clk_prepare_enable() return value
[132c803f7b70b17322579f6f4f3f65cf68e55135]

Lekensteyn (1):
i915: initialize CADL in opregion
[d627b62ff8d4d36761adbcd90ff143d79c94ab22]

Linus Torvalds (2):
perf,x86: fix wrmsr_on_cpu() warning on suspend/resume
[2a6e06b2aed6995af401dcd4feb5e79a0c7ea554]
vfs,proc: guarantee unique inodes in /proc
[51f0885e5415b4cc6535e9cdcc5145bfbc134353]

Lorenzo Colitti (1):
net: ipv6: Don't purge default router if accept_ra=2
[3e8b0ac3e41e3c882222a5522d5df7212438ab51]

Lukas Czerner (1):
ext4: convert number of blocks to clusters properly
[810da240f221d64bf90020f25941b05b378186fe]

Mateusz Guzik (1):
cifs: delay super block destruction until all cifsFileInfo objects are gone
[24261fc23db950951760d00c188ba63cc756b932]

Mathias Krause (4):
dcbnl: fix various netlink info leaks
[29cd8ae0e1a39e239a3a7b67da1986add1199fc0]
isofs: avoid info leak on export
[fe685aabf7c8c9f138e5ea900954d295bf229175]
rtnl: fix info leak on RTM_GETLINK request for VF devices
[84d73cd3fb142bf1298a8c13fd4ca50fd2432372]
udf: avoid info leak on export
[0143fc5e9f6f5aad4764801015bc8d4b4a278200]

Matt Fleming (2):
efivars: Handle duplicate names from get_next_variable()
[e971318bbed610e28bb3fde9d548e6aaf0a6b02e]
efivars: explicitly calculate length of VariableName
[ec50bd32f1672d38ddce10fb1841cbfda89cfe9a]

Michael S. Tsirkin (1):
vhost/net: fix heads usage of ubuf_info
[46aa92d1ba162b4b3d6b7102440e459d4e4ee255]

Neal Cardwell (1):
tcp: fix double-counted receiver RTT when leaving receiver fast path
[aab2b4bf224ef8358d262f95b568b8ad0cecf0a0]

Paul Moore (1):
netlabel: correctly list all the static label mappings
[0c1233aba1e948c37f6dc7620cb7c253fcd71ce9,
a6a8fe950e1b8596bb06f2c89c3a1a4bf2011ba9]

Seiji Aguchi (1):
efi_pstore: Introducing workqueue updating sysfs
[a93bc0c6e07ed9bac44700280e65e2945d864fd4]

Seth Forshee (2):
efivars: Add module parameter to disable use as a pstore backend
[ec0971ba5372a4dfa753f232449d23a8fd98490e]
efivars: Allow disabling use as a pstore backend
[ed9dc8ce7a1c8115dba9483a9b51df8b63a2e0ef]

Stephane Eranian (1):
perf,x86: fix kernel crash with PEBS/BTS after suspend/resume
[1d9d8639c063caf6efc2447f5f26aa637f844ff6]

Steven Rostedt (5):
tracing: Fix free of probe entry by calling call_rcu_sched()
[740466bc89ad8bd5afcc8de220f715f62b21e365]
tracing: Fix race in snapshot swapping
[2721e72dd10f71a3ba90f59781becf02638aa0d9]
tracing: Keep overwrite in sync between regular and snapshot buffers
[80902822658aab18330569587cdb69ac1dfdcea8]
tracing: Prevent buffer overwrite disabled for latency tracers
[613f04a0f51e6e68ac6fe571ab79da3c0a5eb4da]
tracing: Protect tracer flags with trace_types_lock
[69d34da2984c95b33ea21518227e1f9470f11d95]

Stuart Hodgson (1):
sfc: Do not attempt to flush queues if DMA is disabled
[3dca9d2dc285faf1910d405b65df845cab061356]

Stéphane Marchesin (1):
drm/i915: Increase the RC6p threshold.
[0920a48719f1ceefc909387a64f97563848c7854]

Takashi Iwai (2):
ALSA: hda - Fix typo in checking IEC958 emphasis bit
[a686fd141e20244ad75f80ad54706da07d7bb90a]
ALSA: hda/cirrus - Fix the digital beep registration
[a86b1a2cd2f81f74e815e07f756edd7bc5b6f034]

Theodore Ts'o (2):
ext4: fix data=journal fast mount/umount hang
[2b405bfa84063bfa35621d2d6879f52693c614b0]
ext4: use atomic64_t for the per-flexbg free_clusters count
[90ba983f6889e65a3b506b30dc606aa9d1d46cd2]

Tkhai Kirill (1):
sunsu: Fix panic in case of nonexistent port at "console=ttySY" cmdline option
[cb29529ea0030e60ef1bbbf8399a43d397a51526]

Tomas Hozza (1):
tools: hv: Netlink source address validation allows DoS
[95a69adab9acfc3981c504737a2b6578e4d846ef]

Torsten Duwe (2):
KMS: fix EDID detailed timing frame rate
[c19b3b0f6eed552952845e4ad908dba2113d67b4]
KMS: fix EDID detailed timing vsync parsing
[16dad1d743d31a104a849c8944e6b9eb479f6cd7]

Veaceslav Falico (2):
bonding: don't call update_speed_duplex() under spinlocks
[876254ae2758d50dcb08c7bd00caf6a806571178]
netconsole: don't call __netpoll_cleanup() while atomic
[3f315bef23075ea8a98a6fe4221a83b83456d970]

Vlad Yasevich (3):
macvlan: Set IFF_UNICAST_FLT flag to prevent unnecessary promisc mode.
[87ab7f6f2874f1115817e394a7ed2dea1c72549e]
rtnetlink: Mask the rta_type when range checking
[a5b8db91442fce9c9713fcd656c3698f1adde1d6]
sctp: Use correct sideffect command in duplicate cookie handling
[f2815633504b442ca0b0605c16bf3d88a3a0fcea]

Wanpeng Li (1):
mm/hugetlb: fix total hugetlbfs pages count when using memory overcommit accouting
[d00285884c0892bb1310df96bce6056e9ce9b9d9]

Xufeng Zhang (1):
sctp: don't break the loop while meeting the active_path so as to find the matched transport
[2317f449af30073cfa6ec8352e4a65a89e357bdd]

YOSHIFUJI Hideaki / 吉藤英明 (1):
6lowpan: Fix endianness issue in is_addr_link_local().
[9026c4927254f5bea695cc3ef2e255280e6a3011]

Zheng Liu (1):
ext4: fix the wrong number of the allocated blocks in ext4_split_extent()
[3a2256702e47f68f921dfad41b1764d05c572329]

Makefile | 4 +-
arch/powerpc/kernel/cputable.c | 2 +-
arch/s390/include/asm/tlbflush.h | 2 -
arch/x86/kernel/cpu/perf_event_intel_ds.c | 10 +
arch/x86/lib/usercopy_64.c | 4 +-
arch/x86/power/cpu.c | 2 +
drivers/firmware/Kconfig | 18 ++
drivers/firmware/efivars.c | 256 ++++++++++++++++++++------
drivers/gpu/drm/drm_edid.c | 3 +-
drivers/gpu/drm/i915/i915_debugfs.c | 2 +-
drivers/gpu/drm/i915/i915_gem_execbuffer.c | 11 +-
drivers/gpu/drm/i915/intel_display.c | 2 +-
drivers/gpu/drm/i915/intel_opregion.c | 23 ++-
drivers/gpu/drm/radeon/radeon_benchmark.c | 16 +-
drivers/i2c/busses/i2c-tegra.c | 13 +-
drivers/md/dm-thin.c | 4 +-
drivers/md/persistent-data/dm-btree-remove.c | 46 ++---
drivers/net/bonding/bond_main.c | 6 +-
drivers/net/ethernet/sfc/efx.c | 53 ++++--
drivers/net/ethernet/sfc/efx.h | 13 ++
drivers/net/ethernet/sfc/falcon.c | 2 +
drivers/net/ethernet/sfc/mcdi.c | 29 +--
drivers/net/ethernet/sfc/mcdi.h | 1 +
drivers/net/ethernet/sfc/mcdi_mac.c | 4 +-
drivers/net/ethernet/sfc/net_driver.h | 10 +-
drivers/net/ethernet/sfc/nic.c | 24 ++-
drivers/net/ethernet/sfc/nic.h | 2 +
drivers/net/ethernet/sfc/rx.c | 25 ++-
drivers/net/ethernet/sfc/selftest.c | 2 +-
drivers/net/ethernet/sfc/siena.c | 15 +-
drivers/net/macvlan.c | 1 +
drivers/net/netconsole.c | 20 +-
drivers/net/tun.c | 2 +
drivers/net/wireless/mwifiex/join.c | 7 +-
drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 89 ++++-----
drivers/tty/pty.c | 1 -
drivers/tty/serial/sunsu.c | 21 +--
drivers/usb/core/hcd-pci.c | 23 ++-
drivers/usb/gadget/udc-core.c | 2 +-
drivers/usb/host/xhci.c | 3 +-
drivers/usb/host/xhci.h | 4 +-
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/garmin_gps.c | 7 +-
drivers/usb/serial/io_edgeport.c | 12 +-
drivers/usb/serial/io_ti.c | 13 +-
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 | 3 +-
drivers/usb/storage/unusual_devs.h | 7 +
drivers/vhost/net.c | 3 +-
fs/cifs/asn1.c | 53 +-----
fs/cifs/cifsfs.c | 24 +++
fs/cifs/cifsfs.h | 4 +
fs/cifs/file.c | 6 +-
fs/ext4/balloc.c | 2 +-
fs/ext4/ext4.h | 6 +-
fs/ext4/extents.c | 6 +-
fs/ext4/ialloc.c | 4 +-
fs/ext4/inode.c | 3 +-
fs/ext4/mballoc.c | 18 +-
fs/ext4/resize.c | 6 +-
fs/ext4/super.c | 4 +-
fs/isofs/export.c | 1 +
fs/jbd2/transaction.c | 15 +-
fs/proc/inode.c | 12 +-
fs/udf/namei.c | 1 +
include/linux/efi.h | 3 +-
include/linux/perf_event.h | 6 +
include/linux/skbuff.h | 7 +-
include/linux/usb/serial.h | 2 +
include/net/inet_frag.h | 9 +
include/net/ip_fib.h | 12 +-
kernel/trace/ftrace.c | 4 +-
kernel/trace/trace.c | 59 ++++--
kernel/trace/trace.h | 7 +
kernel/trace/trace_irqsoff.c | 19 +-
kernel/trace/trace_sched_wakeup.c | 18 +-
mm/hugetlb.c | 8 +-
net/core/dev.c | 1 +
net/core/rtnetlink.c | 3 +-
net/dcb/dcbnl.c | 7 +
net/ieee802154/6lowpan.h | 2 +-
net/ipv4/inet_fragment.c | 20 +-
net/ipv4/ip_fragment.c | 12 +-
net/ipv4/ip_options.c | 5 +-
net/ipv4/tcp.c | 2 +-
net/ipv4/tcp_input.c | 6 +-
net/ipv4/tcp_output.c | 1 -
net/ipv6/ip6_input.c | 3 +-
net/ipv6/netfilter/nf_conntrack_reasm.c | 11 +-
net/ipv6/reassembly.c | 8 +-
net/ipv6/route.c | 3 +-
net/l2tp/l2tp_ppp.c | 1 +
net/netlabel/netlabel_unlabeled.c | 27 ++-
net/rds/message.c | 3 +
net/sctp/associola.c | 2 +-
net/sctp/sm_statefuns.c | 2 +-
security/selinux/xfrm.c | 2 +-
sound/pci/hda/hda_codec.c | 2 +-
sound/pci/hda/patch_conexant.c | 8 +-
sound/usb/mixer.c | 16 +-
tools/hv/hv_kvp_daemon.c | 8 +-
tools/perf/util/trace-event-parse.c | 2 -
111 files changed, 917 insertions(+), 516 deletions(-)

--
Ben Hutchings
The two most common things in the universe are hydrogen and stupidity.


2013-03-25 01:14:58

by Ben Hutchings

[permalink] [raw]
Subject: [ 004/104] perf,x86: fix link failure for non-Intel configs

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

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

From: David Rientjes <[email protected]>

commit 6c4d3bc99b3341067775efd4d9d13cc8e655fd7c upstream.

Commit 1d9d8639c063 ("perf,x86: fix kernel crash with PEBS/BTS after
suspend/resume") introduces a link failure since
perf_restore_debug_store() is only defined for CONFIG_CPU_SUP_INTEL:

arch/x86/power/built-in.o: In function `restore_processor_state':
(.text+0x45c): undefined reference to `perf_restore_debug_store'

Fix it by defining the dummy function appropriately.

Signed-off-by: David Rientjes <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
include/linux/perf_event.h | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1146,7 +1146,6 @@ extern void perf_swevent_put_recursion_c
extern void perf_event_enable(struct perf_event *event);
extern void perf_event_disable(struct perf_event *event);
extern void perf_event_task_tick(void);
-extern void perf_restore_debug_store(void);
#else
static inline void
perf_event_task_sched_in(struct task_struct *prev,
@@ -1185,6 +1184,11 @@ static inline void perf_swevent_put_recu
static inline void perf_event_enable(struct perf_event *event) { }
static inline void perf_event_disable(struct perf_event *event) { }
static inline void perf_event_task_tick(void) { }
+#endif
+
+#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL)
+extern void perf_restore_debug_store(void);
+#else
static inline void perf_restore_debug_store(void) { }
#endif


2013-03-25 01:15:11

by Ben Hutchings

[permalink] [raw]
Subject: [ 018/104] perf: Revert duplicated commit

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

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

From: Ben Hutchings <[email protected]>

This reverts commit 923415295307845e614589c1cce62abedd4d1731
'perf: Fix parsing of __print_flags() in TP_printk()'. The same
change was already included in 3.2 as commit
d06c27b22aa66e48e32f03f9387328a9af9b0625 but in 3.2.1 this change
was wrongly applied to similar code in a different function.

Thanks to Jiri for pointing this out in 3.0.y.

Signed-off-by: Ben Hutchings <[email protected]>
Cc: Jiri Slaby <[email protected]>
Cc: Andrew Vagin <[email protected]>
Cc: Steven Rostedt <[email protected]>
---
tools/perf/util/trace-event-parse.c | 2 --
1 file changed, 2 deletions(-)

--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -1582,8 +1582,6 @@ process_symbols(struct event *event, str
field = malloc_or_die(sizeof(*field));

type = process_arg(event, field, &token);
- while (type == EVENT_OP)
- type = process_op(event, field, &token);
if (test_type_token(type, token, EVENT_DELIM, ","))
goto out_free;


2013-03-25 01:15:18

by Ben Hutchings

[permalink] [raw]
Subject: [ 104/104] efivars: pstore: Do not check size when erasing variable

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

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

From: Ben Hutchings <[email protected]>

In 3.2, unlike mainline, efi_pstore_erase() calls efi_pstore_write()
with a size of 0, as the underlying EFI interface treats a size of 0
as meaning deletion.

This was not taken into account in my backport of commit d80a361d779a
'efi_pstore: Check remaining space with QueryVariableInfo() before
writing data'. The size check should be omitted when erasing.

Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -787,19 +787,21 @@ static int efi_pstore_write(enum pstore_

spin_lock_irqsave(&efivars->lock, flags);

- /*
- * Check if there is a space enough to log.
- * size: a size of logging data
- * DUMP_NAME_LEN * 2: a maximum size of variable name
- */
+ if (size) {
+ /*
+ * Check if there is a space enough to log.
+ * size: a size of logging data
+ * DUMP_NAME_LEN * 2: a maximum size of variable name
+ */

- status = check_var_size_locked(efivars, PSTORE_EFI_ATTRIBUTES,
- size + DUMP_NAME_LEN * 2);
+ status = check_var_size_locked(efivars, PSTORE_EFI_ATTRIBUTES,
+ size + DUMP_NAME_LEN * 2);

- if (status) {
- spin_unlock_irqrestore(&efivars->lock, flags);
- *id = part;
- return -ENOSPC;
+ if (status) {
+ spin_unlock_irqrestore(&efivars->lock, flags);
+ *id = part;
+ return -ENOSPC;
+ }
}

for (i = 0; i < DUMP_NAME_LEN; i++)

2013-03-25 01:15:24

by Ben Hutchings

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

3.2-stable 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]>
[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-03-25 01:15:41

by Ben Hutchings

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

3.2-stable 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-03-25 01:15:46

by Ben Hutchings

[permalink] [raw]
Subject: [ 073/104] dm thin: fix discard corruption

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

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

From: Joe Thornber <[email protected]>

commit f046f89a99ccfd9408b94c653374ff3065c7edb3 upstream.

Fix a bug in dm_btree_remove that could leave leaf values with incorrect
reference counts. The effect of this was that removal of a shared block
could result in the space maps thinking the block was no longer used.
More concretely, if you have a thin device and a snapshot of it, sending
a discard to a shared region of the thin could corrupt the snapshot.

Thinp uses a 2-level nested btree to store it's mappings. This first
level is indexed by thin device, and the second level by logical
block.

Often when we're removing an entry in this mapping tree we need to
rebalance nodes, which can involve shadowing them, possibly creating a
copy if the block is shared. If we do create a copy then children of
that node need to have their reference counts incremented. In this
way reference counts percolate down the tree as shared trees diverge.

The rebalance functions were incrementing the children at the
appropriate time, but they were always assuming the children were
internal nodes. This meant the leaf values (in our case packed
block/flags entries) were not being incremented.

Signed-off-by: Joe Thornber <[email protected]>
Signed-off-by: Alasdair G Kergon <[email protected]>
[bwh: Backported to 3.2: bump target version numbers from 1.0.1 to 1.0.2]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/md/dm-thin.c | 4 +--
drivers/md/persistent-data/dm-btree-remove.c | 46 ++++++++++++++------------
2 files changed, 26 insertions(+), 24 deletions(-)

--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -2212,7 +2212,7 @@ static struct target_type pool_target =
.name = "thin-pool",
.features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE |
DM_TARGET_IMMUTABLE,
- .version = {1, 0, 1},
+ .version = {1, 0, 2},
.module = THIS_MODULE,
.ctr = pool_ctr,
.dtr = pool_dtr,
@@ -2428,7 +2428,7 @@ static void thin_io_hints(struct dm_targ

static struct target_type thin_target = {
.name = "thin",
- .version = {1, 0, 1},
+ .version = {1, 0, 2},
.module = THIS_MODULE,
.ctr = thin_ctr,
.dtr = thin_dtr,
--- a/drivers/md/persistent-data/dm-btree-remove.c
+++ b/drivers/md/persistent-data/dm-btree-remove.c
@@ -139,15 +139,8 @@ struct child {
struct btree_node *n;
};

-static struct dm_btree_value_type le64_type = {
- .context = NULL,
- .size = sizeof(__le64),
- .inc = NULL,
- .dec = NULL,
- .equal = NULL
-};
-
-static int init_child(struct dm_btree_info *info, struct btree_node *parent,
+static int init_child(struct dm_btree_info *info, struct dm_btree_value_type *vt,
+ struct btree_node *parent,
unsigned index, struct child *result)
{
int r, inc;
@@ -164,7 +157,7 @@ static int init_child(struct dm_btree_in
result->n = dm_block_data(result->block);

if (inc)
- inc_children(info->tm, result->n, &le64_type);
+ inc_children(info->tm, result->n, vt);

*((__le64 *) value_ptr(parent, index, sizeof(__le64))) =
cpu_to_le64(dm_block_location(result->block));
@@ -236,7 +229,7 @@ static void __rebalance2(struct dm_btree
}

static int rebalance2(struct shadow_spine *s, struct dm_btree_info *info,
- unsigned left_index)
+ struct dm_btree_value_type *vt, unsigned left_index)
{
int r;
struct btree_node *parent;
@@ -244,11 +237,11 @@ static int rebalance2(struct shadow_spin

parent = dm_block_data(shadow_current(s));

- r = init_child(info, parent, left_index, &left);
+ r = init_child(info, vt, parent, left_index, &left);
if (r)
return r;

- r = init_child(info, parent, left_index + 1, &right);
+ r = init_child(info, vt, parent, left_index + 1, &right);
if (r) {
exit_child(info, &left);
return r;
@@ -368,7 +361,7 @@ static void __rebalance3(struct dm_btree
}

static int rebalance3(struct shadow_spine *s, struct dm_btree_info *info,
- unsigned left_index)
+ struct dm_btree_value_type *vt, unsigned left_index)
{
int r;
struct btree_node *parent = dm_block_data(shadow_current(s));
@@ -377,17 +370,17 @@ static int rebalance3(struct shadow_spin
/*
* FIXME: fill out an array?
*/
- r = init_child(info, parent, left_index, &left);
+ r = init_child(info, vt, parent, left_index, &left);
if (r)
return r;

- r = init_child(info, parent, left_index + 1, &center);
+ r = init_child(info, vt, parent, left_index + 1, &center);
if (r) {
exit_child(info, &left);
return r;
}

- r = init_child(info, parent, left_index + 2, &right);
+ r = init_child(info, vt, parent, left_index + 2, &right);
if (r) {
exit_child(info, &left);
exit_child(info, &center);
@@ -434,7 +427,8 @@ static int get_nr_entries(struct dm_tran
}

static int rebalance_children(struct shadow_spine *s,
- struct dm_btree_info *info, uint64_t key)
+ struct dm_btree_info *info,
+ struct dm_btree_value_type *vt, uint64_t key)
{
int i, r, has_left_sibling, has_right_sibling;
uint32_t child_entries;
@@ -472,13 +466,13 @@ static int rebalance_children(struct sha
has_right_sibling = i < (le32_to_cpu(n->header.nr_entries) - 1);

if (!has_left_sibling)
- r = rebalance2(s, info, i);
+ r = rebalance2(s, info, vt, i);

else if (!has_right_sibling)
- r = rebalance2(s, info, i - 1);
+ r = rebalance2(s, info, vt, i - 1);

else
- r = rebalance3(s, info, i - 1);
+ r = rebalance3(s, info, vt, i - 1);

return r;
}
@@ -529,7 +523,7 @@ static int remove_raw(struct shadow_spin
if (le32_to_cpu(n->header.flags) & LEAF_NODE)
return do_leaf(n, key, index);

- r = rebalance_children(s, info, key);
+ r = rebalance_children(s, info, vt, key);
if (r)
break;

@@ -550,6 +544,14 @@ static int remove_raw(struct shadow_spin
return r;
}

+static struct dm_btree_value_type le64_type = {
+ .context = NULL,
+ .size = sizeof(__le64),
+ .inc = NULL,
+ .dec = NULL,
+ .equal = NULL
+};
+
int dm_btree_remove(struct dm_btree_info *info, dm_block_t root,
uint64_t *keys, dm_block_t *new_root)
{

2013-03-25 01:16:16

by Ben Hutchings

[permalink] [raw]
Subject: [ 045/104] sfc: Properly sync RX DMA buffer when it is not the last in the page

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

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

From: Ben Hutchings <[email protected]>

[ Upstream commit 3a68f19d7afb80f548d016effbc6ed52643a8085 ]

We may currently allocate two RX DMA buffers to a page, and only unmap
the page when the second is completed. We do not sync the first RX
buffer to be completed; this can result in packet loss or corruption
if the last RX buffer completed in a NAPI poll is the first in a page
and is not DMA-coherent. (In the middle of a NAPI poll, we will
handle the following RX completion and unmap the page *before* looking
at the content of the first buffer.)

Signed-off-by: Ben Hutchings <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/ethernet/sfc/rx.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index 5ef4cc0..b4d3cd5 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -246,7 +246,8 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
}

static void efx_unmap_rx_buffer(struct efx_nic *efx,
- struct efx_rx_buffer *rx_buf)
+ struct efx_rx_buffer *rx_buf,
+ unsigned int used_len)
{
if (rx_buf->is_page && rx_buf->u.page) {
struct efx_rx_page_state *state;
@@ -257,6 +258,10 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx,
state->dma_addr,
efx_rx_buf_size(efx),
PCI_DMA_FROMDEVICE);
+ } else if (used_len) {
+ dma_sync_single_for_cpu(&efx->pci_dev->dev,
+ rx_buf->dma_addr, used_len,
+ DMA_FROM_DEVICE);
}
} else if (!rx_buf->is_page && rx_buf->u.skb) {
pci_unmap_single(efx->pci_dev, rx_buf->dma_addr,
@@ -279,7 +284,7 @@ static void efx_free_rx_buffer(struct efx_nic *efx,
static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue,
struct efx_rx_buffer *rx_buf)
{
- efx_unmap_rx_buffer(rx_queue->efx, rx_buf);
+ efx_unmap_rx_buffer(rx_queue->efx, rx_buf, 0);
efx_free_rx_buffer(rx_queue->efx, rx_buf);
}

@@ -550,10 +555,10 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
goto out;
}

- /* Release card resources - assumes all RX buffers consumed in-order
- * per RX queue
+ /* Release and/or sync DMA mapping - assumes all RX buffers
+ * consumed in-order per RX queue
*/
- efx_unmap_rx_buffer(efx, rx_buf);
+ efx_unmap_rx_buffer(efx, rx_buf, len);

/* Prefetch nice and early so data will (hopefully) be in cache by
* the time we look at it.

2013-03-25 01:16:34

by Ben Hutchings

[permalink] [raw]
Subject: [ 043/104] sfc: lock TX queues when calling netif_device_detach()

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

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

From: Daniel Pieczko <[email protected]>

[ Upstream commit c2f3b8e3a44b6fe9e36704e30157ebe1a88c08b1 ]

The assertion of netif_device_present() at the top of
efx_hard_start_xmit() may fail if we don't do this.

Signed-off-by: Ben Hutchings <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/ethernet/sfc/efx.c | 4 ++--
drivers/net/ethernet/sfc/efx.h | 13 +++++++++++++
drivers/net/ethernet/sfc/selftest.c | 2 +-
3 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index aa20047..34e51f3 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -2137,7 +2137,7 @@ int efx_reset(struct efx_nic *efx, enum reset_type method)
netif_info(efx, drv, efx->net_dev, "resetting (%s)\n",
RESET_TYPE(method));

- netif_device_detach(efx->net_dev);
+ efx_device_detach_sync(efx);
efx_reset_down(efx, method);

rc = efx->type->reset(efx, method);
@@ -2585,7 +2585,7 @@ static int efx_pm_freeze(struct device *dev)

efx->state = STATE_FINI;

- netif_device_detach(efx->net_dev);
+ efx_device_detach_sync(efx);

efx_stop_all(efx);
efx_fini_channels(efx);
diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h
index 1355245..55e72af 100644
--- a/drivers/net/ethernet/sfc/efx.h
+++ b/drivers/net/ethernet/sfc/efx.h
@@ -149,4 +149,17 @@ extern void efx_link_status_changed(struct efx_nic *efx);
extern void efx_link_set_advertising(struct efx_nic *efx, u32);
extern void efx_link_set_wanted_fc(struct efx_nic *efx, u8);

+static inline void efx_device_detach_sync(struct efx_nic *efx)
+{
+ struct net_device *dev = efx->net_dev;
+
+ /* Lock/freeze all TX queues so that we can be sure the
+ * TX scheduler is stopped when we're done and before
+ * netif_device_present() becomes false.
+ */
+ netif_tx_lock(dev);
+ netif_device_detach(dev);
+ netif_tx_unlock(dev);
+}
+
#endif /* EFX_EFX_H */
diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c
index 822f6c2..4907885 100644
--- a/drivers/net/ethernet/sfc/selftest.c
+++ b/drivers/net/ethernet/sfc/selftest.c
@@ -698,7 +698,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
/* Detach the device so the kernel doesn't transmit during the
* loopback test and the watchdog timeout doesn't fire.
*/
- netif_device_detach(efx->net_dev);
+ efx_device_detach_sync(efx);

mutex_lock(&efx->mac_lock);
if (efx->loopback_modes) {

2013-03-25 01:16:44

by Ben Hutchings

[permalink] [raw]
Subject: [ 021/104] mwifiex: fix potential out-of-boundary access to ibss rate table

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

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

From: Bing Zhao <[email protected]>

commit 5f0fabf84d7b52f979dcbafa3d3c530c60d9a92c upstream.

smatch found this error:

CHECK drivers/net/wireless/mwifiex/join.c
drivers/net/wireless/mwifiex/join.c:1121
mwifiex_cmd_802_11_ad_hoc_join()
error: testing array offset 'i' after use.

Signed-off-by: Bing Zhao <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/wireless/mwifiex/join.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)

--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -1062,10 +1062,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mw
adhoc_join->bss_descriptor.bssid,
adhoc_join->bss_descriptor.ssid);

- for (i = 0; bss_desc->supported_rates[i] &&
- i < MWIFIEX_SUPPORTED_RATES;
- i++)
- ;
+ for (i = 0; i < MWIFIEX_SUPPORTED_RATES &&
+ bss_desc->supported_rates[i]; i++)
+ ;
rates_size = i;

/* Copy Data Rates from the Rates recorded in scan response */

2013-03-25 01:16:48

by Ben Hutchings

[permalink] [raw]
Subject: [ 036/104] ipv4: fix definition of FIB_TABLE_HASHSZ

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

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

From: "Denis V. Lunev" <[email protected]>

[ Upstream commit 5b9e12dbf92b441b37136ea71dac59f05f2673a9 ]

a long time ago by the commit

commit 93456b6d7753def8760b423ac6b986eb9d5a4a95
Author: Denis V. Lunev <[email protected]>
Date: Thu Jan 10 03:23:38 2008 -0800

[IPV4]: Unify access to the routing tables.

the defenition of FIB_HASH_TABLE size has obtained wrong dependency:
it should depend upon CONFIG_IP_MULTIPLE_TABLES (as was in the original
code) but it was depended from CONFIG_IP_ROUTE_MULTIPATH

This patch returns the situation to the original state.

The problem was spotted by Tingwei Liu.

Signed-off-by: Denis V. Lunev <[email protected]>
CC: Tingwei Liu <[email protected]>
CC: Alexey Kuznetsov <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
include/net/ip_fib.h | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 10422ef..2124004 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -129,18 +129,16 @@ struct fib_result_nl {
};

#ifdef CONFIG_IP_ROUTE_MULTIPATH
-
#define FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel])
-
-#define FIB_TABLE_HASHSZ 2
-
#else /* CONFIG_IP_ROUTE_MULTIPATH */
-
#define FIB_RES_NH(res) ((res).fi->fib_nh[0])
+#endif /* CONFIG_IP_ROUTE_MULTIPATH */

+#ifdef CONFIG_IP_MULTIPLE_TABLES
#define FIB_TABLE_HASHSZ 256
-
-#endif /* CONFIG_IP_ROUTE_MULTIPATH */
+#else
+#define FIB_TABLE_HASHSZ 2
+#endif

extern __be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh);


2013-03-25 01:17:41

by Ben Hutchings

[permalink] [raw]
Subject: [ 022/104] rtlwifi: rtl8192cu: Fix schedule while atomic bug splat

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

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

From: Larry Finger <[email protected]>

commit 664899786cb49cb52f620e06ac19c0be524a7cfa upstream.

When run at debug 3 or higher, rtl8192cu reports a BUG as follows:

BUG: scheduling while atomic: kworker/u:0/5281/0x00000002
INFO: lockdep is turned off.
Modules linked in: rtl8192cu rtl8192c_common rtlwifi fuse af_packet bnep bluetooth b43 mac80211 cfg80211 ipv6 snd_hda_codec_conexant kvm_amd k
vm snd_hda_intel snd_hda_codec bcma rng_core snd_pcm ssb mmc_core snd_seq snd_timer snd_seq_device snd i2c_nforce2 sr_mod pcmcia forcedeth i2c_core soundcore
cdrom sg serio_raw k8temp hwmon joydev ac battery pcmcia_core snd_page_alloc video button wmi autofs4 ext4 mbcache jbd2 crc16 thermal processor scsi_dh_alua
scsi_dh_hp_sw scsi_dh_rdac scsi_dh_emc scsi_dh ata_generic pata_acpi pata_amd [last unloaded: rtlwifi]
Pid: 5281, comm: kworker/u:0 Tainted: G W 3.8.0-wl+ #119
Call Trace:
[<ffffffff814531e7>] __schedule_bug+0x62/0x70
[<ffffffff81459af0>] __schedule+0x730/0xa30
[<ffffffff81326e49>] ? usb_hcd_link_urb_to_ep+0x19/0xa0
[<ffffffff8145a0d4>] schedule+0x24/0x70
[<ffffffff814575ec>] schedule_timeout+0x18c/0x2f0
[<ffffffff81459ec0>] ? wait_for_common+0x40/0x180
[<ffffffff8133f461>] ? ehci_urb_enqueue+0xf1/0xee0
[<ffffffff810a579d>] ? trace_hardirqs_on+0xd/0x10
[<ffffffff81459f65>] wait_for_common+0xe5/0x180
[<ffffffff8107d1c0>] ? try_to_wake_up+0x2d0/0x2d0
[<ffffffff8145a08e>] wait_for_completion_timeout+0xe/0x10
[<ffffffff8132ab1c>] usb_start_wait_urb+0x8c/0x100
[<ffffffff8132adf9>] usb_control_msg+0xd9/0x130
[<ffffffffa057dd8d>] _usb_read_sync+0xcd/0x140 [rtlwifi]
[<ffffffffa057de0e>] _usb_read32_sync+0xe/0x10 [rtlwifi]
[<ffffffffa04b0555>] rtl92cu_update_hal_rate_table+0x1a5/0x1f0 [rtl8192cu]

The cause is a synchronous read from routine rtl92cu_update_hal_rate_table().
The resulting output is not critical, thus the debug statement is
deleted.

Reported-by: Jussi Kivilinna <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
[bwh: Backported to 3.2: the deleted code is slightly different]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 2 --
1 file changed, 2 deletions(-)

--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -2238,8 +2238,6 @@ void rtl92cu_update_hal_rate_table(struc
(shortgi_rate << 4) | (shortgi_rate);
}
rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
- RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("%x\n", rtl_read_dword(rtlpriv,
- REG_ARFR0)));
}

void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)

2013-03-25 01:17:39

by Ben Hutchings

[permalink] [raw]
Subject: [ 023/104] powerpc: Fix cputable entry for 970MP rev 1.0

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

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

From: Benjamin Herrenschmidt <[email protected]>

commit d63ac5f6cf31c8a83170a9509b350c1489a7262b upstream.

Commit 44ae3ab3358e962039c36ad4ae461ae9fb29596c forgot to update
the entry for the 970MP rev 1.0 processor when moving some CPU
features bits to the MMU feature bit mask. This breaks booting
on some rare G5 models using that chip revision.

Reported-by: Phileas Fogg <[email protected]>
Signed-off-by: Benjamin Herrenschmidt <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/powerpc/kernel/cputable.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -268,7 +268,7 @@ static struct cpu_spec __initdata cpu_sp
.cpu_features = CPU_FTRS_PPC970,
.cpu_user_features = COMMON_USER_POWER4 |
PPC_FEATURE_HAS_ALTIVEC_COMP,
- .mmu_features = MMU_FTR_HPTE_TABLE,
+ .mmu_features = MMU_FTRS_PPC970,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 8,

2013-03-25 01:16:43

by Ben Hutchings

[permalink] [raw]
Subject: [ 027/104] tools: hv: Netlink source address validation allows DoS

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

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

From: Tomas Hozza <[email protected]>

commit 95a69adab9acfc3981c504737a2b6578e4d846ef upstream.

The source code without this patch caused hypervkvpd to exit when it processed
a spoofed Netlink packet which has been sent from an untrusted local user.
Now Netlink messages with a non-zero nl_pid source address are ignored
and a warning is printed into the syslog.

Signed-off-by: Tomas Hozza <[email protected]>
Acked-by: K. Y. Srinivasan <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
tools/hv/hv_kvp_daemon.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -393,13 +393,19 @@ int main(void)
len = recvfrom(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0,
addr_p, &addr_l);

- if (len < 0 || addr.nl_pid) {
+ if (len < 0) {
syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s",
addr.nl_pid, errno, strerror(errno));
close(fd);
return -1;
}

+ if (addr.nl_pid) {
+ syslog(LOG_WARNING, "Received packet from untrusted pid:%u",
+ addr.nl_pid);
+ continue;
+ }
+
incoming_msg = (struct nlmsghdr *)kvp_recv_buffer;
incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg);


2013-03-25 01:18:17

by Ben Hutchings

[permalink] [raw]
Subject: [ 019/104] i915: initialize CADL in opregion

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

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

From: Lekensteyn <[email protected]>

commit d627b62ff8d4d36761adbcd90ff143d79c94ab22 upstream.

This is rather a hack to fix brightness hotkeys on a Clevo laptop. CADL is not
used anywhere in the driver code at the moment, but it could be used in BIOS as
is the case with the Clevo laptop.

The Clevo B7130 requires the CADL field to contain at least the ID of
the LCD device. If this field is empty, the ACPI methods that are called
on pressing brightness / display switching hotkeys will not trigger a
notification. As a result, it appears as no hotkey has been pressed.

Reference: https://bugs.freedesktop.org/show_bug.cgi?id=45452
Tested-by: Peter Wu <[email protected]>
Signed-off-by: Peter Wu <[email protected]>
Acked-by: Jesse Barnes <[email protected]>
Signed-off-by: Daniel Vetter <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/i915/intel_opregion.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)

--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -419,6 +419,25 @@ blind_set:
goto end;
}

+static void intel_setup_cadls(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_opregion *opregion = &dev_priv->opregion;
+ int i = 0;
+ u32 disp_id;
+
+ /* Initialize the CADL field by duplicating the DIDL values.
+ * Technically, this is not always correct as display outputs may exist,
+ * but not active. This initialization is necessary for some Clevo
+ * laptops that check this field before processing the brightness and
+ * display switching hotkeys. Just like DIDL, CADL is NULL-terminated if
+ * there are less than eight devices. */
+ do {
+ disp_id = ioread32(&opregion->acpi->didl[i]);
+ iowrite32(disp_id, &opregion->acpi->cadl[i]);
+ } while (++i < 8 && disp_id != 0);
+}
+
void intel_opregion_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -428,8 +447,10 @@ void intel_opregion_init(struct drm_devi
return;

if (opregion->acpi) {
- if (drm_core_check_feature(dev, DRIVER_MODESET))
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
intel_didl_outputs(dev);
+ intel_setup_cadls(dev);
+ }

/* Notify BIOS we are ready to handle ACPI video ext notifs.
* Right now, all the events are handled by the ACPI video module.

2013-03-25 01:18:36

by Ben Hutchings

[permalink] [raw]
Subject: [ 026/104] selinux: use GFP_ATOMIC under spin_lock

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

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

From: Dan Carpenter <[email protected]>

commit 4502403dcf8f5c76abd4dbab8726c8e4ecb5cd34 upstream.

The call tree here is:

sk_clone_lock() <- takes bh_lock_sock(newsk);
xfrm_sk_clone_policy()
__xfrm_sk_clone_policy()
clone_policy() <- uses GFP_ATOMIC for allocations
security_xfrm_policy_clone()
security_ops->xfrm_policy_clone_security()
selinux_xfrm_policy_clone()

Signed-off-by: Dan Carpenter <[email protected]>
Signed-off-by: James Morris <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
security/selinux/xfrm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -310,7 +310,7 @@ int selinux_xfrm_policy_clone(struct xfr

if (old_ctx) {
new_ctx = kmalloc(sizeof(*old_ctx) + old_ctx->ctx_len,
- GFP_KERNEL);
+ GFP_ATOMIC);
if (!new_ctx)
return -ENOMEM;


2013-03-25 01:16:41

by Ben Hutchings

[permalink] [raw]
Subject: [ 028/104] udf: avoid info leak on export

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

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

From: Mathias Krause <[email protected]>

commit 0143fc5e9f6f5aad4764801015bc8d4b4a278200 upstream.

For type 0x51 the udf.parent_partref member in struct fid gets copied
uninitialized to userland. Fix this by initializing it to 0.

Signed-off-by: Mathias Krause <[email protected]>
Signed-off-by: Jan Kara <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/udf/namei.c | 1 +
1 file changed, 1 insertion(+)

--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -1293,6 +1293,7 @@ static int udf_encode_fh(struct dentry *
*lenp = 3;
fid->udf.block = location.logicalBlockNum;
fid->udf.partref = location.partitionReferenceNum;
+ fid->udf.parent_partref = 0;
fid->udf.generation = inode->i_generation;

if (connectable && !S_ISDIR(inode->i_mode)) {

2013-03-25 01:16:39

by Ben Hutchings

[permalink] [raw]
Subject: [ 029/104] isofs: avoid info leak on export

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

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

From: Mathias Krause <[email protected]>

commit fe685aabf7c8c9f138e5ea900954d295bf229175 upstream.

For type 1 the parent_offset member in struct isofs_fid gets copied
uninitialized to userland. Fix this by initializing it to 0.

Signed-off-by: Mathias Krause <[email protected]>
Signed-off-by: Jan Kara <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/isofs/export.c | 1 +
1 file changed, 1 insertion(+)

--- a/fs/isofs/export.c
+++ b/fs/isofs/export.c
@@ -135,6 +135,7 @@ isofs_export_encode_fh(struct dentry *de
len = 3;
fh32[0] = ei->i_iget5_block;
fh16[2] = (__u16)ei->i_iget5_offset; /* fh16 [sic] */
+ fh16[3] = 0; /* avoid leaking uninitialized data */
fh32[2] = inode->i_generation;
if (connectable && !S_ISDIR(inode->i_mode)) {
struct inode *parent;

2013-03-25 01:19:24

by Ben Hutchings

[permalink] [raw]
Subject: [ 035/104] sctp: dont break the loop while meeting the active_path so as to find the matched transport

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

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

From: Xufeng Zhang <[email protected]>

[ Upstream commit 2317f449af30073cfa6ec8352e4a65a89e357bdd ]

sctp_assoc_lookup_tsn() function searchs which transport a certain TSN
was sent on, if not found in the active_path transport, then go search
all the other transports in the peer's transport_addr_list, however, we
should continue to the next entry rather than break the loop when meet
the active_path transport.

Signed-off-by: Xufeng Zhang <[email protected]>
Acked-by: Neil Horman <[email protected]>
Acked-by: Vlad Yasevich <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/sctp/associola.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index acd2edb..3c04692 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1050,7 +1050,7 @@ struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *asoc,
transports) {

if (transport == active)
- break;
+ continue;
list_for_each_entry(chunk, &transport->transmitted,
transmitted_list) {
if (key == chunk->subh.data_hdr->tsn) {

2013-03-25 01:19:45

by Ben Hutchings

[permalink] [raw]
Subject: [ 024/104] rtlwifi: rtl8192cu: Fix problem that prevents reassociation

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

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

From: Larry Finger <[email protected]>

commit 9437a248e7cac427c898bdb11bd1ac6844a1ead4 upstream.

The driver was failing to clear the BSSID when a disconnect happened. That
prevented a reconnection. This problem is reported at
https://bugzilla.redhat.com/show_bug.cgi?id=789605,
https://bugzilla.redhat.com/show_bug.cgi?id=866786,
https://bugzilla.redhat.com/show_bug.cgi?id=906734, and
https://bugzilla.kernel.org/show_bug.cgi?id=46171.

Thanks to Jussi Kivilinna for making the critical observation
that led to the solution.

Reported-by: Jussi Kivilinna <[email protected]>
Tested-by: Jussi Kivilinna <[email protected]>
Tested-by: Alessandro Lannocca <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 87 +++++++++++----------------
1 file changed, 35 insertions(+), 52 deletions(-)

--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -1557,74 +1557,57 @@ void rtl92cu_card_disable(struct ieee802

void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
{
- /* dummy routine needed for callback from rtl_op_configure_filter() */
-}
-
-/*========================================================================== */
-
-static void _rtl92cu_set_check_bssid(struct ieee80211_hw *hw,
- enum nl80211_iftype type)
-{
struct rtl_priv *rtlpriv = rtl_priv(hw);
- u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR);
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
- struct rtl_phy *rtlphy = &(rtlpriv->phy);
- u8 filterout_non_associated_bssid = false;
+ u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR);

- switch (type) {
- case NL80211_IFTYPE_ADHOC:
- case NL80211_IFTYPE_STATION:
- filterout_non_associated_bssid = true;
- break;
- case NL80211_IFTYPE_UNSPECIFIED:
- case NL80211_IFTYPE_AP:
- default:
- break;
- }
- if (filterout_non_associated_bssid) {
+ if (rtlpriv->psc.rfpwr_state != ERFON)
+ return;
+
+ if (check_bssid) {
+ u8 tmp;
if (IS_NORMAL_CHIP(rtlhal->version)) {
- switch (rtlphy->current_io_type) {
- case IO_CMD_RESUME_DM_BY_SCAN:
- reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
- rtlpriv->cfg->ops->set_hw_reg(hw,
- HW_VAR_RCR, (u8 *)(&reg_rcr));
- /* enable update TSF */
- _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4));
- break;
- case IO_CMD_PAUSE_DM_BY_SCAN:
- reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
- rtlpriv->cfg->ops->set_hw_reg(hw,
- HW_VAR_RCR, (u8 *)(&reg_rcr));
- /* disable update TSF */
- _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0);
- break;
- }
+ reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+ tmp = BIT(4);
} else {
- reg_rcr |= (RCR_CBSSID);
- rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
- (u8 *)(&reg_rcr));
- _rtl92cu_set_bcn_ctrl_reg(hw, 0, (BIT(4)|BIT(5)));
+ reg_rcr |= RCR_CBSSID;
+ tmp = BIT(4) | BIT(5);
}
- } else if (filterout_non_associated_bssid == false) {
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
+ (u8 *) (&reg_rcr));
+ _rtl92cu_set_bcn_ctrl_reg(hw, 0, tmp);
+ } else {
+ u8 tmp;
if (IS_NORMAL_CHIP(rtlhal->version)) {
- reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
- rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
- (u8 *)(&reg_rcr));
- _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0);
+ reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+ tmp = BIT(4);
} else {
- reg_rcr &= (~RCR_CBSSID);
- rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
- (u8 *)(&reg_rcr));
- _rtl92cu_set_bcn_ctrl_reg(hw, (BIT(4)|BIT(5)), 0);
+ reg_rcr &= ~RCR_CBSSID;
+ tmp = BIT(4) | BIT(5);
}
+ reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
+ rtlpriv->cfg->ops->set_hw_reg(hw,
+ HW_VAR_RCR, (u8 *) (&reg_rcr));
+ _rtl92cu_set_bcn_ctrl_reg(hw, tmp, 0);
}
}

+/*========================================================================== */
+
int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
if (_rtl92cu_set_media_status(hw, type))
return -EOPNOTSUPP;
- _rtl92cu_set_check_bssid(hw, type);
+
+ if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
+ if (type != NL80211_IFTYPE_AP)
+ rtl92cu_set_check_bssid(hw, true);
+ } else {
+ rtl92cu_set_check_bssid(hw, false);
+ }
+
return 0;
}


2013-03-25 01:16:37

by Ben Hutchings

[permalink] [raw]
Subject: [ 033/104] bonding: dont call update_speed_duplex() under spinlocks

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

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

From: Veaceslav Falico <[email protected]>

[ Upstream commit 876254ae2758d50dcb08c7bd00caf6a806571178 ]

bond_update_speed_duplex() might sleep while calling underlying slave's
routines. Move it out of atomic context in bond_enslave() and remove it
from bond_miimon_commit() - it was introduced by commit 546add79, however
when the slave interfaces go up/change state it's their responsibility to
fire NETDEV_UP/NETDEV_CHANGE events so that bonding can properly update
their speed.

I've tested it on all combinations of ifup/ifdown, autoneg/speed/duplex
changes, remote-controlled and local, on (not) MII-based cards. All changes
are visible.

Signed-off-by: Veaceslav Falico <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/bonding/bond_main.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 202ae34..63e3c47 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1715,6 +1715,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)

bond_compute_features(bond);

+ bond_update_speed_duplex(new_slave);
+
read_lock(&bond->lock);

new_slave->last_arp_rx = jiffies;
@@ -1758,8 +1760,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
new_slave->link = BOND_LINK_DOWN;
}

- bond_update_speed_duplex(new_slave);
-
if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) {
/* if there is a primary slave, remember it */
if (strcmp(bond->params.primary, new_slave->dev->name) == 0) {
@@ -2437,8 +2437,6 @@ static void bond_miimon_commit(struct bonding *bond)
bond_set_backup_slave(slave);
}

- bond_update_speed_duplex(slave);
-
pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex.\n",
bond->dev->name, slave->dev->name,
slave->speed, slave->duplex ? "full" : "half");

2013-03-25 01:20:09

by Ben Hutchings

[permalink] [raw]
Subject: [ 034/104] sctp: Use correct sideffect command in duplicate cookie handling

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

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

From: Vlad Yasevich <[email protected]>

[ Upstream commit f2815633504b442ca0b0605c16bf3d88a3a0fcea ]

When SCTP is done processing a duplicate cookie chunk, it tries
to delete a newly created association. For that, it has to set
the right association for the side-effect processing to work.
However, when it uses the SCTP_CMD_NEW_ASOC command, that performs
more work then really needed (like hashing the associationa and
assigning it an id) and there is no point to do that only to
delete the association as a next step. In fact, it also creates
an impossible condition where an association may be found by
the getsockopt() call, and that association is empty. This
causes a crash in some sctp getsockopts.

The solution is rather simple. We simply use SCTP_CMD_SET_ASOC
command that doesn't have all the overhead and does exactly
what we need.

Reported-by: Karl Heiss <[email protected]>
Tested-by: Karl Heiss <[email protected]>
CC: Neil Horman <[email protected]>
Signed-off-by: Vlad Yasevich <[email protected]>
Acked-by: Neil Horman <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/sctp/sm_statefuns.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 891f5db..cb1c430 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -2044,7 +2044,7 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const struct sctp_endpoint *ep,
}

/* Delete the tempory new association. */
- sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
+ sctp_add_cmd_sf(commands, SCTP_CMD_SET_ASOC, SCTP_ASOC(new_asoc));
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());

/* Restore association pointer to provide SCTP command interpeter

2013-03-25 01:20:36

by Ben Hutchings

[permalink] [raw]
Subject: [ 032/104] netconsole: dont call __netpoll_cleanup() while atomic

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

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

From: Veaceslav Falico <[email protected]>

[ Upstream commit 3f315bef23075ea8a98a6fe4221a83b83456d970 ]

__netpoll_cleanup() is called in netconsole_netdev_event() while holding a
spinlock. Release/acquire the spinlock before/after it and restart the
loop. Also, disable the netconsole completely, because we won't have chance
after the restart of the loop, and might end up in a situation where
nt->enabled == 1 and nt->np.dev == NULL.

Signed-off-by: Veaceslav Falico <[email protected]>
Acked-by: Neil Horman <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/netconsole.c | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 01b104e..bff6908 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -630,6 +630,7 @@ static int netconsole_netdev_event(struct notifier_block *this,
goto done;

spin_lock_irqsave(&target_list_lock, flags);
+restart:
list_for_each_entry(nt, &target_list, list) {
netconsole_target_get(nt);
if (nt->np.dev == dev) {
@@ -642,20 +643,17 @@ static int netconsole_netdev_event(struct notifier_block *this,
case NETDEV_UNREGISTER:
/*
* rtnl_lock already held
+ * we might sleep in __netpoll_cleanup()
*/
- if (nt->np.dev) {
- spin_unlock_irqrestore(
- &target_list_lock,
- flags);
- __netpoll_cleanup(&nt->np);
- spin_lock_irqsave(&target_list_lock,
- flags);
- dev_put(nt->np.dev);
- nt->np.dev = NULL;
- }
+ spin_unlock_irqrestore(&target_list_lock, flags);
+ __netpoll_cleanup(&nt->np);
+ spin_lock_irqsave(&target_list_lock, flags);
+ dev_put(nt->np.dev);
+ nt->np.dev = NULL;
nt->enabled = 0;
stopped = true;
- break;
+ netconsole_target_put(nt);
+ goto restart;
}
}
netconsole_target_put(nt);

2013-03-25 01:20:53

by Ben Hutchings

[permalink] [raw]
Subject: [ 025/104] vhost/net: fix heads usage of ubuf_info

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

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

From: "Michael S. Tsirkin" <[email protected]>

commit 46aa92d1ba162b4b3d6b7102440e459d4e4ee255 upstream.

ubuf info allocator uses guest controlled head as an index,
so a malicious guest could put the same head entry in the ring twice,
and we will get two callbacks on the same value.
To fix use upend_idx which is guaranteed to be unique.

Reported-by: Rusty Russell <[email protected]>
Signed-off-by: Michael S. Tsirkin <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/vhost/net.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -234,7 +234,8 @@ static void handle_tx(struct vhost_net *
msg.msg_controllen = 0;
ubufs = NULL;
} else {
- struct ubuf_info *ubuf = &vq->ubuf_info[head];
+ struct ubuf_info *ubuf;
+ ubuf = vq->ubuf_info + vq->upend_idx;

vq->heads[vq->upend_idx].len = len;
ubuf->callback = vhost_zerocopy_callback;

2013-03-25 01:21:24

by Ben Hutchings

[permalink] [raw]
Subject: [ 038/104] rtnetlink: Mask the rta_type when range checking

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

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

From: Vlad Yasevich <[email protected]>

[ Upstream commit a5b8db91442fce9c9713fcd656c3698f1adde1d6 ]

Range/validity checks on rta_type in rtnetlink_rcv_msg() do
not account for flags that may be set. This causes the function
to return -EINVAL when flags are set on the type (for example
NLA_F_NESTED).

Signed-off-by: Vlad Yasevich <[email protected]>
Acked-by: Thomas Graf <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/core/rtnetlink.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 5229c7f..0cf60eb 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2041,7 +2041,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
struct rtattr *attr = (void *)nlh + NLMSG_ALIGN(min_len);

while (RTA_OK(attr, attrlen)) {
- unsigned flavor = attr->rta_type;
+ unsigned int flavor = attr->rta_type & NLA_TYPE_MASK;
if (flavor) {
if (flavor > rta_max[sz_idx])
return -EINVAL;

2013-03-25 01:21:22

by Ben Hutchings

[permalink] [raw]
Subject: [ 030/104] sunsu: Fix panic in case of nonexistent port at "console=ttySY" cmdline option

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

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

From: Tkhai Kirill <[email protected]>

[ Upstream commit cb29529ea0030e60ef1bbbf8399a43d397a51526 ]

If a machine has X (X < 4) sunsu ports and cmdline
option "console=ttySY" is passed, where X < Y <= 4,
than the following panic happens:

Unable to handle kernel NULL pointer dereference
TPC: <sunsu_console_setup+0x78/0xe0>
RPC: <sunsu_console_setup+0x74/0xe0>
I7: <register_console+0x378/0x3e0>
Call Trace:
[0000000000453a38] register_console+0x378/0x3e0
[0000000000576fa0] uart_add_one_port+0x2e0/0x340
[000000000057af40] su_probe+0x160/0x2e0
[00000000005b8a4c] platform_drv_probe+0xc/0x20
[00000000005b6c2c] driver_probe_device+0x12c/0x220
[00000000005b6da8] __driver_attach+0x88/0xa0
[00000000005b4df4] bus_for_each_dev+0x54/0xa0
[00000000005b5a54] bus_add_driver+0x154/0x260
[00000000005b7190] driver_register+0x50/0x180
[00000000006d250c] sunsu_init+0x18c/0x1e0
[00000000006c2668] do_one_initcall+0xe8/0x160
[00000000006c282c] kernel_init_freeable+0x12c/0x1e0
[0000000000603764] kernel_init+0x4/0x100
[0000000000405f64] ret_from_syscall+0x1c/0x2c
[0000000000000000] (null)

1)Fix the panic;
2)Increment registered port number every successful
probe.

Signed-off-by: Kirill Tkhai <[email protected]>
CC: David Miller <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/tty/serial/sunsu.c | 21 +++++++++------------
1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c
index ad0f8f5..2dc4d9b 100644
--- a/drivers/tty/serial/sunsu.c
+++ b/drivers/tty/serial/sunsu.c
@@ -968,6 +968,7 @@ static struct uart_ops sunsu_pops = {
#define UART_NR 4

static struct uart_sunsu_port sunsu_ports[UART_NR];
+static int nr_inst; /* Number of already registered ports */

#ifdef CONFIG_SERIO

@@ -1337,13 +1338,8 @@ static int __init sunsu_console_setup(struct console *co, char *options)
printk("Console: ttyS%d (SU)\n",
(sunsu_reg.minor - 64) + co->index);

- /*
- * Check whether an invalid uart number has been specified, and
- * if so, search for the first available port that does have
- * console support.
- */
- if (co->index >= UART_NR)
- co->index = 0;
+ if (co->index > nr_inst)
+ return -ENODEV;
port = &sunsu_ports[co->index].port;

/*
@@ -1408,7 +1404,6 @@ static enum su_type __devinit su_get_type(struct device_node *dp)

static int __devinit su_probe(struct platform_device *op)
{
- static int inst;
struct device_node *dp = op->dev.of_node;
struct uart_sunsu_port *up;
struct resource *rp;
@@ -1418,16 +1413,16 @@ static int __devinit su_probe(struct platform_device *op)

type = su_get_type(dp);
if (type == SU_PORT_PORT) {
- if (inst >= UART_NR)
+ if (nr_inst >= UART_NR)
return -EINVAL;
- up = &sunsu_ports[inst];
+ up = &sunsu_ports[nr_inst];
} else {
up = kzalloc(sizeof(*up), GFP_KERNEL);
if (!up)
return -ENOMEM;
}

- up->port.line = inst;
+ up->port.line = nr_inst;

spin_lock_init(&up->port.lock);

@@ -1461,6 +1456,8 @@ static int __devinit su_probe(struct platform_device *op)
}
dev_set_drvdata(&op->dev, up);

+ nr_inst++;
+
return 0;
}

@@ -1488,7 +1485,7 @@ static int __devinit su_probe(struct platform_device *op)

dev_set_drvdata(&op->dev, up);

- inst++;
+ nr_inst++;

return 0;


2013-03-25 01:21:21

by Ben Hutchings

[permalink] [raw]
Subject: [ 031/104] net/ipv4: Ensure that location of timestamp option is stored

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

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

From: David Ward <[email protected]>

[ Upstream commit 4660c7f498c07c43173142ea95145e9dac5a6d14 ]

This is needed in order to detect if the timestamp option appears
more than once in a packet, to remove the option if the packet is
fragmented, etc. My previous change neglected to store the option
location when the router addresses were prespecified and Pointer >
Length. But now the option location is also stored when Flag is an
unrecognized value, to ensure these option handling behaviors are
still performed.

Signed-off-by: David Ward <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/ipv4/ip_options.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index 42dd1a9..40eb4fc 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -358,7 +358,6 @@ int ip_options_compile(struct net *net,
}
switch (optptr[3]&0xF) {
case IPOPT_TS_TSONLY:
- opt->ts = optptr - iph;
if (skb)
timeptr = &optptr[optptr[2]-1];
opt->ts_needtime = 1;
@@ -369,7 +368,6 @@ int ip_options_compile(struct net *net,
pp_ptr = optptr + 2;
goto error;
}
- opt->ts = optptr - iph;
if (rt) {
memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4);
timeptr = &optptr[optptr[2]+3];
@@ -383,7 +381,6 @@ int ip_options_compile(struct net *net,
pp_ptr = optptr + 2;
goto error;
}
- opt->ts = optptr - iph;
{
__be32 addr;
memcpy(&addr, &optptr[optptr[2]-1], 4);
@@ -416,12 +413,12 @@ int ip_options_compile(struct net *net,
pp_ptr = optptr + 3;
goto error;
}
- opt->ts = optptr - iph;
if (skb) {
optptr[3] = (optptr[3]&0xF)|((overflow+1)<<4);
opt->is_changed = 1;
}
}
+ opt->ts = optptr - iph;
break;
case IPOPT_RA:
if (optlen < 4) {

2013-03-25 01:22:11

by Ben Hutchings

[permalink] [raw]
Subject: [ 037/104] tcp: fix skb_availroom()

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit 16fad69cfe4adbbfa813de516757b87bcae36d93 ]

Chrome OS team reported a crash on a Pixel ChromeBook in TCP stack :

https://code.google.com/p/chromium/issues/detail?id=182056

commit a21d45726acac (tcp: avoid order-1 allocations on wifi and tx
path) did a poor choice adding an 'avail_size' field to skb, while
what we really needed was a 'reserved_tailroom' one.

It would have avoided commit 22b4a4f22da (tcp: fix retransmit of
partially acked frames) and this commit.

Crash occurs because skb_split() is not aware of the 'avail_size'
management (and should not be aware)

Signed-off-by: Eric Dumazet <[email protected]>
Reported-by: Mukesh Agrawal <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
include/linux/skbuff.h | 7 +++++--
net/ipv4/tcp.c | 2 +-
net/ipv4/tcp_output.c | 1 -
3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 53dc7e7..da65890 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -455,7 +455,7 @@ struct sk_buff {
union {
__u32 mark;
__u32 dropcount;
- __u32 avail_size;
+ __u32 reserved_tailroom;
};

__u16 vlan_tci;
@@ -1332,7 +1332,10 @@ static inline int skb_tailroom(const struct sk_buff *skb)
*/
static inline int skb_availroom(const struct sk_buff *skb)
{
- return skb_is_nonlinear(skb) ? 0 : skb->avail_size - skb->len;
+ if (skb_is_nonlinear(skb))
+ return 0;
+
+ return skb->end - skb->tail - skb->reserved_tailroom;
}

/**
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 52edbb8..fe381c2 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -704,7 +704,7 @@ struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp)
* Make sure that we have exactly size bytes
* available to the caller, no more, no less.
*/
- skb->avail_size = size;
+ skb->reserved_tailroom = skb->end - skb->tail - size;
return skb;
}
__kfree_skb(skb);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 921cbac..9bb7400 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1096,7 +1096,6 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)
eat = min_t(int, len, skb_headlen(skb));
if (eat) {
__skb_pull(skb, eat);
- skb->avail_size -= eat;
len -= eat;
if (!len)
return;

2013-03-25 01:16:32

by Ben Hutchings

[permalink] [raw]
Subject: [ 044/104] sfc: Fix timekeeping in efx_mcdi_poll()

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

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

From: Ben Hutchings <[email protected]>

[ Upstream commit ebf98e797b4e26ad52ace1511a0b503ee60a6cd4 ]

efx_mcdi_poll() uses get_seconds() to read the current time and to
implement a polling timeout. The use of this function was chosen
partly because it could easily be replaced in a co-sim environment
with a macro that read the simulated time.

Unfortunately the real get_seconds() returns the system time (real
time) which is subject to adjustment by e.g. ntpd. If the system time
is adjusted forward during a polled MCDI operation, the effective
timeout can be shorter than the intended 10 seconds, resulting in a
spurious failure. It is also possible for a backward adjustment to
delay detection of a areal failure.

Use jiffies instead, and change MCDI_RPC_TIMEOUT to be denominated in
jiffies. Also correct rounding of the timeout: check time > finish
(or rather time_after(time, finish)) and not time >= finish.

Signed-off-by: Ben Hutchings <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/ethernet/sfc/mcdi.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c
index 85e070e..c1000ce 100644
--- a/drivers/net/ethernet/sfc/mcdi.c
+++ b/drivers/net/ethernet/sfc/mcdi.c
@@ -30,7 +30,7 @@
#define REBOOT_FLAG_PORT0 0x3f8
#define REBOOT_FLAG_PORT1 0x3fc

-#define MCDI_RPC_TIMEOUT 10 /*seconds */
+#define MCDI_RPC_TIMEOUT (10 * HZ)

#define MCDI_PDU(efx) \
(efx_port_num(efx) ? CMD_PDU_PORT1 : CMD_PDU_PORT0)
@@ -120,7 +120,7 @@ static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen)
static int efx_mcdi_poll(struct efx_nic *efx)
{
struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
- unsigned int time, finish;
+ unsigned long time, finish;
unsigned int respseq, respcmd, error;
unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx);
unsigned int rc, spins;
@@ -136,7 +136,7 @@ static int efx_mcdi_poll(struct efx_nic *efx)
* and poll once a jiffy (approximately)
*/
spins = TICK_USEC;
- finish = get_seconds() + MCDI_RPC_TIMEOUT;
+ finish = jiffies + MCDI_RPC_TIMEOUT;

while (1) {
if (spins != 0) {
@@ -146,7 +146,7 @@ static int efx_mcdi_poll(struct efx_nic *efx)
schedule_timeout_uninterruptible(1);
}

- time = get_seconds();
+ time = jiffies;

rmb();
efx_readd(efx, &reg, pdu);
@@ -158,7 +158,7 @@ static int efx_mcdi_poll(struct efx_nic *efx)
EFX_DWORD_FIELD(reg, MCDI_HEADER_RESPONSE))
break;

- if (time >= finish)
+ if (time_after(time, finish))
return -ETIMEDOUT;
}

@@ -250,7 +250,7 @@ static int efx_mcdi_await_completion(struct efx_nic *efx)
if (wait_event_timeout(
mcdi->wq,
atomic_read(&mcdi->state) == MCDI_STATE_COMPLETED,
- msecs_to_jiffies(MCDI_RPC_TIMEOUT * 1000)) == 0)
+ MCDI_RPC_TIMEOUT) == 0)
return -ETIMEDOUT;

/* Check if efx_mcdi_set_mode() switched us back to polled completions.

2013-03-25 01:16:30

by Ben Hutchings

[permalink] [raw]
Subject: [ 041/104] sfc: Convert firmware subtypes to native byte order in efx_mcdi_get_board_cfg()

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

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

From: Ben Hutchings <[email protected]>

[ Upstream commit bfeed902946a31692e7a24ed355b6d13ac37d014 ]

On big-endian systems the MTD partition names currently have mangled
subtype numbers and are not recognised by the firmware update tool
(sfupdate).

Signed-off-by: Ben Hutchings <[email protected]>
[bwh: Backported to 3.2: use old macros for length of firmware subtype array]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/ethernet/sfc/mcdi.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c
index 81a4253..85e070e 100644
--- a/drivers/net/ethernet/sfc/mcdi.c
+++ b/drivers/net/ethernet/sfc/mcdi.c
@@ -666,9 +666,8 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address,
u16 *fw_subtype_list)
{
uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LEN];
- size_t outlen;
+ size_t outlen, offset, i;
int port_num = efx_port_num(efx);
- int offset;
int rc;

BUILD_BUG_ON(MC_CMD_GET_BOARD_CFG_IN_LEN != 0);
@@ -688,10 +687,16 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address,
: MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_OFST;
if (mac_address)
memcpy(mac_address, outbuf + offset, ETH_ALEN);
- if (fw_subtype_list)
- memcpy(fw_subtype_list,
- outbuf + MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST,
- MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN);
+ if (fw_subtype_list) {
+ offset = MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST;
+ for (i = 0;
+ i < MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN / 2;
+ i++) {
+ fw_subtype_list[i] =
+ le16_to_cpup((__le16 *)(outbuf + offset));
+ offset += 2;
+ }
+ }

return 0;


2013-03-25 01:22:49

by Ben Hutchings

[permalink] [raw]
Subject: [ 040/104] sfc: Do not attempt to flush queues if DMA is disabled

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

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

From: Stuart Hodgson <[email protected]>

[ Upstream commit 3dca9d2dc285faf1910d405b65df845cab061356 ]

efx_nic_fatal_interrupt() disables DMA before scheduling a reset.
After this, we need not and *cannot* flush queues.

Signed-off-by: Ben Hutchings <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/ethernet/sfc/efx.c | 33 +++++++++++++++++++--------------
1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index a6611f1..aa20047 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -650,25 +650,30 @@ static void efx_fini_channels(struct efx_nic *efx)
struct efx_channel *channel;
struct efx_tx_queue *tx_queue;
struct efx_rx_queue *rx_queue;
+ struct pci_dev *dev = efx->pci_dev;
int rc;

EFX_ASSERT_RESET_SERIALISED(efx);
BUG_ON(efx->port_enabled);

- rc = efx_nic_flush_queues(efx);
- if (rc && EFX_WORKAROUND_7803(efx)) {
- /* Schedule a reset to recover from the flush failure. The
- * descriptor caches reference memory we're about to free,
- * but falcon_reconfigure_mac_wrapper() won't reconnect
- * the MACs because of the pending reset. */
- netif_err(efx, drv, efx->net_dev,
- "Resetting to recover from flush failure\n");
- efx_schedule_reset(efx, RESET_TYPE_ALL);
- } else if (rc) {
- netif_err(efx, drv, efx->net_dev, "failed to flush queues\n");
- } else {
- netif_dbg(efx, drv, efx->net_dev,
- "successfully flushed all queues\n");
+ /* Only perform flush if dma is enabled */
+ if (dev->is_busmaster) {
+ rc = efx_nic_flush_queues(efx);
+
+ if (rc && EFX_WORKAROUND_7803(efx)) {
+ /* Schedule a reset to recover from the flush failure. The
+ * descriptor caches reference memory we're about to free,
+ * but falcon_reconfigure_mac_wrapper() won't reconnect
+ * the MACs because of the pending reset. */
+ netif_err(efx, drv, efx->net_dev,
+ "Resetting to recover from flush failure\n");
+ efx_schedule_reset(efx, RESET_TYPE_ALL);
+ } else if (rc) {
+ netif_err(efx, drv, efx->net_dev, "failed to flush queues\n");
+ } else {
+ netif_dbg(efx, drv, efx->net_dev,
+ "successfully flushed all queues\n");
+ }
}

efx_for_each_channel(channel, efx) {

2013-03-25 01:23:13

by Ben Hutchings

[permalink] [raw]
Subject: [ 042/104] sfc: Fix two causes of flush failure

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

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

From: Ben Hutchings <[email protected]>

[ Upstream commits a606f4325dca6950996abbae452d33f2af095f39,
d5e8cc6c946e0857826dcfbb3585068858445bfe,
525d9e824018cd7cc8d8d44832ddcd363abfe6e1 ]

The TX DMA engine issues upstream read requests when there is room in
the TX FIFO for the completion. However, the fetches for the rest of
the packet might be delayed by any back pressure. Since a flush must
wait for an EOP, the entire flush may be delayed by back pressure.

Mitigate this by disabling flow control before the flushes are
started. Since PF and VF flushes run in parallel introduce
fc_disable, a reference count of the number of flushes outstanding.

The same principle could be applied to Falcon, but that
would bring with it its own testing.

We sometimes hit a "failed to flush" timeout on some TX queues, but the
flushes have completed and the flush completion events seem to go missing.
In this case, we can check the TX_DESC_PTR_TBL register and drain the
queues if the flushes had finished.

Signed-off-by: Ben Hutchings <[email protected]>
[bwh: Backported to 3.2:
- Call efx_nic_type::finish_flush() on both success and failure paths
- Check the TX_DESC_PTR_TBL registers in the polling loop
- Declare efx_mcdi_set_mac() extern]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/ethernet/sfc/falcon.c | 2 ++
drivers/net/ethernet/sfc/mcdi.h | 1 +
drivers/net/ethernet/sfc/mcdi_mac.c | 4 +++-
drivers/net/ethernet/sfc/net_driver.h | 6 ++++++
drivers/net/ethernet/sfc/nic.c | 21 ++++++++++++++++++---
drivers/net/ethernet/sfc/nic.h | 2 ++
drivers/net/ethernet/sfc/siena.c | 15 ++++++++++++++-
7 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c
index 97b606b..26cd6c0 100644
--- a/drivers/net/ethernet/sfc/falcon.c
+++ b/drivers/net/ethernet/sfc/falcon.c
@@ -1762,6 +1762,7 @@ const struct efx_nic_type falcon_a1_nic_type = {
.remove_port = falcon_remove_port,
.handle_global_event = falcon_handle_global_event,
.prepare_flush = falcon_prepare_flush,
+ .finish_flush = efx_port_dummy_op_void,
.update_stats = falcon_update_nic_stats,
.start_stats = falcon_start_nic_stats,
.stop_stats = falcon_stop_nic_stats,
@@ -1804,6 +1805,7 @@ const struct efx_nic_type falcon_b0_nic_type = {
.remove_port = falcon_remove_port,
.handle_global_event = falcon_handle_global_event,
.prepare_flush = falcon_prepare_flush,
+ .finish_flush = efx_port_dummy_op_void,
.update_stats = falcon_update_nic_stats,
.start_stats = falcon_start_nic_stats,
.stop_stats = falcon_stop_nic_stats,
diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h
index aced2a7..b61eea0 100644
--- a/drivers/net/ethernet/sfc/mcdi.h
+++ b/drivers/net/ethernet/sfc/mcdi.h
@@ -126,5 +126,6 @@ extern int efx_mcdi_wol_filter_set_magic(struct efx_nic *efx,
extern int efx_mcdi_wol_filter_get_magic(struct efx_nic *efx, int *id_out);
extern int efx_mcdi_wol_filter_remove(struct efx_nic *efx, int id);
extern int efx_mcdi_wol_filter_reset(struct efx_nic *efx);
+extern int efx_mcdi_set_mac(struct efx_nic *efx);

#endif /* EFX_MCDI_H */
diff --git a/drivers/net/ethernet/sfc/mcdi_mac.c b/drivers/net/ethernet/sfc/mcdi_mac.c
index 50c2077..da269d7 100644
--- a/drivers/net/ethernet/sfc/mcdi_mac.c
+++ b/drivers/net/ethernet/sfc/mcdi_mac.c
@@ -13,7 +13,7 @@
#include "mcdi.h"
#include "mcdi_pcol.h"

-static int efx_mcdi_set_mac(struct efx_nic *efx)
+int efx_mcdi_set_mac(struct efx_nic *efx)
{
u32 reject, fcntl;
u8 cmdbytes[MC_CMD_SET_MAC_IN_LEN];
@@ -45,6 +45,8 @@ static int efx_mcdi_set_mac(struct efx_nic *efx)
}
if (efx->wanted_fc & EFX_FC_AUTO)
fcntl = MC_CMD_FCNTL_AUTO;
+ if (efx->fc_disable)
+ fcntl = MC_CMD_FCNTL_OFF;

MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_FCNTL, fcntl);

diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index b8e251a..9e2e802 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -689,6 +689,9 @@ struct efx_filter_state;
* @promiscuous: Promiscuous flag. Protected by netif_tx_lock.
* @multicast_hash: Multicast hash table
* @wanted_fc: Wanted flow control flags
+ * @fc_disable: When non-zero flow control is disabled. Typically used to
+ * ensure that network back pressure doesn't delay dma queue flushes.
+ * Serialised by the rtnl lock.
* @mac_work: Work item for changing MAC promiscuity and multicast hash
* @loopback_mode: Loopback status
* @loopback_modes: Supported loopback mode bitmask
@@ -782,6 +785,7 @@ struct efx_nic {
bool promiscuous;
union efx_multicast_hash multicast_hash;
u8 wanted_fc;
+ unsigned fc_disable;

atomic_t rx_reset;
enum efx_loopback_mode loopback_mode;
@@ -835,6 +839,7 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
* @remove_port: Free resources allocated by probe_port()
* @handle_global_event: Handle a "global" event (may be %NULL)
* @prepare_flush: Prepare the hardware for flushing the DMA queues
+ * @finish_flush: Clean up after flushing the DMA queues
* @update_stats: Update statistics not provided by event handling
* @start_stats: Start the regular fetching of statistics
* @stop_stats: Stop the regular fetching of statistics
@@ -880,6 +885,7 @@ struct efx_nic_type {
void (*remove_port)(struct efx_nic *efx);
bool (*handle_global_event)(struct efx_channel *channel, efx_qword_t *);
void (*prepare_flush)(struct efx_nic *efx);
+ void (*finish_flush)(struct efx_nic *efx);
void (*update_stats)(struct efx_nic *efx);
void (*start_stats)(struct efx_nic *efx);
void (*stop_stats)(struct efx_nic *efx);
diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c
index 3edfbaf..9cca2a6 100644
--- a/drivers/net/ethernet/sfc/nic.c
+++ b/drivers/net/ethernet/sfc/nic.c
@@ -1261,13 +1261,27 @@ int efx_nic_flush_queues(struct efx_nic *efx)
}
efx_for_each_possible_channel_tx_queue(tx_queue, channel) {
if (tx_queue->initialised &&
- tx_queue->flushed != FLUSH_DONE)
- ++tx_pending;
+ tx_queue->flushed != FLUSH_DONE) {
+ efx_oword_t txd_ptr_tbl;
+
+ efx_reado_table(efx, &txd_ptr_tbl,
+ FR_BZ_TX_DESC_PTR_TBL,
+ tx_queue->queue);
+ if (EFX_OWORD_FIELD(txd_ptr_tbl,
+ FRF_AZ_TX_DESCQ_FLUSH) ||
+ EFX_OWORD_FIELD(txd_ptr_tbl,
+ FRF_AZ_TX_DESCQ_EN))
+ ++tx_pending;
+ else
+ tx_queue->flushed = FLUSH_DONE;
+ }
}
}

- if (rx_pending == 0 && tx_pending == 0)
+ if (rx_pending == 0 && tx_pending == 0) {
+ efx->type->finish_flush(efx);
return 0;
+ }

msleep(EFX_FLUSH_INTERVAL);
efx_poll_flush_events(efx);
@@ -1293,6 +1307,7 @@ int efx_nic_flush_queues(struct efx_nic *efx)
}
}

+ efx->type->finish_flush(efx);
return -ETIMEDOUT;
}

diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index 66ece48..58302a2 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -210,6 +210,8 @@ extern void falcon_irq_ack_a1(struct efx_nic *efx);

/* Global Resources */
extern int efx_nic_flush_queues(struct efx_nic *efx);
+extern void siena_prepare_flush(struct efx_nic *efx);
+extern void siena_finish_flush(struct efx_nic *efx);
extern void falcon_start_nic_stats(struct efx_nic *efx);
extern void falcon_stop_nic_stats(struct efx_nic *efx);
extern void falcon_setup_xaui(struct efx_nic *efx);
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c
index cc2549c..c58b973 100644
--- a/drivers/net/ethernet/sfc/siena.c
+++ b/drivers/net/ethernet/sfc/siena.c
@@ -137,6 +137,18 @@ static void siena_remove_port(struct efx_nic *efx)
efx_nic_free_buffer(efx, &efx->stats_buffer);
}

+void siena_prepare_flush(struct efx_nic *efx)
+{
+ if (efx->fc_disable++ == 0)
+ efx_mcdi_set_mac(efx);
+}
+
+void siena_finish_flush(struct efx_nic *efx)
+{
+ if (--efx->fc_disable == 0)
+ efx_mcdi_set_mac(efx);
+}
+
static const struct efx_nic_register_test siena_register_tests[] = {
{ FR_AZ_ADR_REGION,
EFX_OWORD32(0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF) },
@@ -624,7 +636,8 @@ const struct efx_nic_type siena_a0_nic_type = {
.reset = siena_reset_hw,
.probe_port = siena_probe_port,
.remove_port = siena_remove_port,
- .prepare_flush = efx_port_dummy_op_void,
+ .prepare_flush = siena_prepare_flush,
+ .finish_flush = siena_finish_flush,
.update_stats = siena_update_nic_stats,
.start_stats = siena_start_nic_stats,
.stop_stats = siena_stop_nic_stats,

2013-03-25 01:23:11

by Ben Hutchings

[permalink] [raw]
Subject: [ 039/104] inet: limit length of fragment queue hash table bucket lists

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

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

From: Hannes Frederic Sowa <[email protected]>

[ Upstream commit 5a3da1fe9561828d0ca7eca664b16ec2b9bf0055 ]

This patch introduces a constant limit of the fragment queue hash
table bucket list lengths. Currently the limit 128 is choosen somewhat
arbitrary and just ensures that we can fill up the fragment cache with
empty packets up to the default ip_frag_high_thresh limits. It should
just protect from list iteration eating considerable amounts of cpu.

If we reach the maximum length in one hash bucket a warning is printed.
This is implemented on the caller side of inet_frag_find to distinguish
between the different users of inet_fragment.c.

I dropped the out of memory warning in the ipv4 fragment lookup path,
because we already get a warning by the slab allocator.

Cc: Eric Dumazet <[email protected]>
Cc: Jesper Dangaard Brouer <[email protected]>
Signed-off-by: Hannes Frederic Sowa <[email protected]>
Acked-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
include/net/inet_frag.h | 9 +++++++++
net/ipv4/inet_fragment.c | 20 +++++++++++++++++++-
net/ipv4/ip_fragment.c | 12 ++++++------
net/ipv6/netfilter/nf_conntrack_reasm.c | 11 ++++++-----
net/ipv6/reassembly.c | 8 ++++++--
5 files changed, 46 insertions(+), 14 deletions(-)

diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index 16ff29a..b289bd2 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -33,6 +33,13 @@ struct inet_frag_queue {

#define INETFRAGS_HASHSZ 64

+/* averaged:
+ * max_depth = default ipfrag_high_thresh / INETFRAGS_HASHSZ /
+ * rounded up (SKB_TRUELEN(0) + sizeof(struct ipq or
+ * struct frag_queue))
+ */
+#define INETFRAGS_MAXDEPTH 128
+
struct inet_frags {
struct hlist_head hash[INETFRAGS_HASHSZ];
rwlock_t lock;
@@ -64,6 +71,8 @@ int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f);
struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
struct inet_frags *f, void *key, unsigned int hash)
__releases(&f->lock);
+void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q,
+ const char *prefix);

static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f)
{
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index 5ff2a51..210b710 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -21,6 +21,7 @@
#include <linux/rtnetlink.h>
#include <linux/slab.h>

+#include <net/sock.h>
#include <net/inet_frag.h>

static void inet_frag_secret_rebuild(unsigned long dummy)
@@ -271,6 +272,7 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
{
struct inet_frag_queue *q;
struct hlist_node *n;
+ int depth = 0;

hlist_for_each_entry(q, n, &f->hash[hash], list) {
if (q->net == nf && f->match(q, key)) {
@@ -278,9 +280,25 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
read_unlock(&f->lock);
return q;
}
+ depth++;
}
read_unlock(&f->lock);

- return inet_frag_create(nf, f, key);
+ if (depth <= INETFRAGS_MAXDEPTH)
+ return inet_frag_create(nf, f, key);
+ else
+ return ERR_PTR(-ENOBUFS);
}
EXPORT_SYMBOL(inet_frag_find);
+
+void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q,
+ const char *prefix)
+{
+ static const char msg[] = "inet_frag_find: Fragment hash bucket"
+ " list length grew over limit " __stringify(INETFRAGS_MAXDEPTH)
+ ". Dropping fragment.\n";
+
+ if (PTR_ERR(q) == -ENOBUFS)
+ LIMIT_NETDEBUG(KERN_WARNING "%s%s", prefix, msg);
+}
+EXPORT_SYMBOL(inet_frag_maybe_warn_overflow);
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index a4e7131..b2cfe83 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -20,6 +20,8 @@
* Patrick McHardy : LRU queue of frag heads for evictor.
*/

+#define pr_fmt(fmt) "IPv4: " fmt
+
#include <linux/compiler.h>
#include <linux/module.h>
#include <linux/types.h>
@@ -293,14 +295,12 @@ static inline struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user)
hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol);

q = inet_frag_find(&net->ipv4.frags, &ip4_frags, &arg, hash);
- if (q == NULL)
- goto out_nomem;
+ if (IS_ERR_OR_NULL(q)) {
+ inet_frag_maybe_warn_overflow(q, pr_fmt());
+ return NULL;
+ }

return container_of(q, struct ipq, q);
-
-out_nomem:
- LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n");
- return NULL;
}

/* Is the fragment too far ahead to be part of ipq? */
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 38f00b0..52e2f65 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -14,6 +14,8 @@
* 2 of the License, or (at your option) any later version.
*/

+#define pr_fmt(fmt) "IPv6-nf: " fmt
+
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/string.h>
@@ -176,13 +178,12 @@ fq_find(__be32 id, u32 user, struct in6_addr *src, struct in6_addr *dst)

q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash);
local_bh_enable();
- if (q == NULL)
- goto oom;
+ if (IS_ERR_OR_NULL(q)) {
+ inet_frag_maybe_warn_overflow(q, pr_fmt());
+ return NULL;
+ }

return container_of(q, struct nf_ct_frag6_queue, q);
-
-oom:
- return NULL;
}


diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index dfb164e..2b0a4ca 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -26,6 +26,9 @@
* YOSHIFUJI,H. @USAGI Always remove fragment header to
* calculate ICV correctly.
*/
+
+#define pr_fmt(fmt) "IPv6: " fmt
+
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/string.h>
@@ -240,9 +243,10 @@ fq_find(struct net *net, __be32 id, const struct in6_addr *src, const struct in6
hash = inet6_hash_frag(id, src, dst, ip6_frags.rnd);

q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash);
- if (q == NULL)
+ if (IS_ERR_OR_NULL(q)) {
+ inet_frag_maybe_warn_overflow(q, pr_fmt());
return NULL;
-
+ }
return container_of(q, struct frag_queue, q);
}


2013-03-25 01:16:15

by Ben Hutchings

[permalink] [raw]
Subject: [ 047/104] sfc: Detach net device when stopping queues for reconfiguration

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

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

From: Ben Hutchings <[email protected]>

[ Upstream commit 29c69a4882641285a854d6d03ca5adbba68c0034 ]

We must only ever stop TX queues when they are full or the net device
is not 'ready' so far as the net core, and specifically the watchdog,
is concerned. Otherwise, the watchdog may fire *immediately* if no
packets have been added to the queue in the last 5 seconds.

The device is ready if all the following are true:

(a) It has a qdisc
(b) It is marked present
(c) It is running
(d) The link is reported up

(a) and (c) are normally true, and must not be changed by a driver.
(d) is under our control, but fake link changes may disturb userland.
This leaves (b). We already mark the device absent during reset
and self-test, but we need to do the same during MTU changes and ring
reallocation. We don't need to do this when the device is brought
down because then (c) is already false.

Signed-off-by: Ben Hutchings <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/ethernet/sfc/efx.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 34e51f3..5d5a05f 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -719,6 +719,7 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries)
unsigned i;
int rc;

+ efx_device_detach_sync(efx);
efx_stop_all(efx);
efx_fini_channels(efx);

@@ -762,6 +763,7 @@ out:

efx_init_channels(efx);
efx_start_all(efx);
+ netif_device_attach(efx->net_dev);
return rc;

rollback:
@@ -1530,8 +1532,12 @@ static void efx_stop_all(struct efx_nic *efx)
/* Flush efx_mac_work(), refill_workqueue, monitor_work */
efx_flush_all(efx);

- /* Stop the kernel transmit interface late, so the watchdog
- * timer isn't ticking over the flush */
+ /* Stop the kernel transmit interface. This is only valid if
+ * the device is stopped or detached; otherwise the watchdog
+ * may fire immediately.
+ */
+ WARN_ON(netif_running(efx->net_dev) &&
+ netif_device_present(efx->net_dev));
if (efx_dev_registered(efx)) {
netif_tx_stop_all_queues(efx->net_dev);
netif_tx_lock_bh(efx->net_dev);
@@ -1832,10 +1838,11 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu)
if (new_mtu > EFX_MAX_MTU)
return -EINVAL;

- efx_stop_all(efx);
-
netif_dbg(efx, drv, efx->net_dev, "changing MTU to %d\n", new_mtu);

+ efx_device_detach_sync(efx);
+ efx_stop_all(efx);
+
efx_fini_channels(efx);

mutex_lock(&efx->mac_lock);
@@ -1848,6 +1855,7 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu)
efx_init_channels(efx);

efx_start_all(efx);
+ netif_device_attach(efx->net_dev);
return rc;
}


2013-03-25 01:23:59

by Ben Hutchings

[permalink] [raw]
Subject: [ 046/104] sfc: Fix efx_rx_buf_offset() in the presence of swiotlb

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

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

From: Ben Hutchings <[email protected]>

[ Upstream commits 06e63c57acbb1df7c35ebe846ae416a8b88dfafa,
b590ace09d51cd39744e0f7662c5e4a0d1b5d952 and
c73e787a8db9117d59b5180baf83203a42ecadca ]

We assume that the mapping between DMA and virtual addresses is done
on whole pages, so we can find the page offset of an RX buffer using
the lower bits of the DMA address. However, swiotlb maps in units of
2K, breaking this assumption.

Add an explicit page_offset field to struct efx_rx_buffer.

Signed-off-by: Ben Hutchings <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/ethernet/sfc/net_driver.h | 4 +++-
drivers/net/ethernet/sfc/rx.c | 10 +++++-----
2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 9e2e802..8bcb8fd 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -213,6 +213,7 @@ struct efx_tx_queue {
* If both this and page are %NULL, the buffer slot is currently free.
* @page: The associated page buffer, if any.
* If both this and skb are %NULL, the buffer slot is currently free.
+ * @page_offset: Offset within page. Valid iff @flags & %EFX_RX_BUF_PAGE.
* @len: Buffer length, in bytes.
* @is_page: Indicates if @page is valid. If false, @skb is valid.
*/
@@ -222,7 +223,8 @@ struct efx_rx_buffer {
struct sk_buff *skb;
struct page *page;
} u;
- unsigned int len;
+ u16 page_offset;
+ u16 len;
bool is_page;
};

diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index b4d3cd5..9ce8665 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -95,11 +95,7 @@ static unsigned int rx_refill_limit = 95;
static inline unsigned int efx_rx_buf_offset(struct efx_nic *efx,
struct efx_rx_buffer *buf)
{
- /* Offset is always within one page, so we don't need to consider
- * the page order.
- */
- return (((__force unsigned long) buf->dma_addr & (PAGE_SIZE - 1)) +
- efx->type->rx_buffer_hash_size);
+ return buf->page_offset + efx->type->rx_buffer_hash_size;
}
static inline unsigned int efx_rx_buf_size(struct efx_nic *efx)
{
@@ -194,6 +190,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
struct efx_rx_buffer *rx_buf;
struct page *page;
void *page_addr;
+ unsigned int page_offset;
struct efx_rx_page_state *state;
dma_addr_t dma_addr;
unsigned index, count;
@@ -220,12 +217,14 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)

page_addr += sizeof(struct efx_rx_page_state);
dma_addr += sizeof(struct efx_rx_page_state);
+ page_offset = sizeof(struct efx_rx_page_state);

split:
index = rx_queue->added_count & rx_queue->ptr_mask;
rx_buf = efx_rx_buffer(rx_queue, index);
rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN;
rx_buf->u.page = page;
+ rx_buf->page_offset = page_offset + EFX_PAGE_IP_ALIGN;
rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN;
rx_buf->is_page = true;
++rx_queue->added_count;
@@ -237,6 +236,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
get_page(page);
dma_addr += (PAGE_SIZE >> 1);
page_addr += (PAGE_SIZE >> 1);
+ page_offset += (PAGE_SIZE >> 1);
++count;
goto split;
}

2013-03-25 01:23:58

by Ben Hutchings

[permalink] [raw]
Subject: [ 050/104] ext4: fix the wrong number of the allocated blocks in

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

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

From: Zheng Liu <[email protected]>

commit 3a2256702e47f68f921dfad41b1764d05c572329 upstream.

This commit fixes a wrong return value of the number of the allocated
blocks in ext4_split_extent. When the length of blocks we want to
allocate is greater than the length of the current extent, we return a
wrong number. Let's see what happens in the following case when we
call ext4_split_extent().

map: [48, 72]
ex: [32, 64, u]

'ex' will be split into two parts:
ex1: [32, 47, u]
ex2: [48, 64, w]

'map->m_len' is returned from this function, and the value is 24. But
the real length is 16. So it should be fixed.

Meanwhile in this commit we use right length of the allocated blocks
when get_reserved_cluster_alloc in ext4_ext_handle_uninitialized_extents
is called.

Signed-off-by: Zheng Liu <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
Cc: Dmitry Monakhov <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/ext4/extents.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2960,6 +2960,7 @@ static int ext4_split_extent(handle_t *h
int err = 0;
int uninitialized;
int split_flag1, flags1;
+ int allocated = map->m_len;

depth = ext_depth(inode);
ex = path[depth].p_ext;
@@ -2979,6 +2980,8 @@ static int ext4_split_extent(handle_t *h
map->m_lblk + map->m_len, split_flag1, flags1);
if (err)
goto out;
+ } else {
+ allocated = ee_len - (map->m_lblk - ee_block);
}

ext4_ext_drop_refs(path);
@@ -3001,7 +3004,7 @@ static int ext4_split_extent(handle_t *h

ext4_ext_show_leaf(inode, path);
out:
- return err ? err : map->m_len;
+ return err ? err : allocated;
}

#define EXT4_EXT_ZERO_LEN 7
@@ -3663,6 +3666,7 @@ out:
allocated - map->m_len);
allocated = map->m_len;
}
+ map->m_len = allocated;

/*
* If we have done fallocate with the offset that is already

2013-03-25 01:16:13

by Ben Hutchings

[permalink] [raw]
Subject: [ 058/104] tracing: Fix free of probe entry by calling call_rcu_sched()

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

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

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

commit 740466bc89ad8bd5afcc8de220f715f62b21e365 upstream.

Because function tracing is very invasive, and can even trace
calls to rcu_read_lock(), RCU access in function tracing is done
with preempt_disable_notrace(). This requires a synchronize_sched()
for updates and not a synchronize_rcu().

Function probes (traceon, traceoff, etc) must be freed after
a synchronize_sched() after its entry has been removed from the
hash. But call_rcu() is used. Fix this by using call_rcu_sched().

Also fix the usage to use hlist_del_rcu() instead of hlist_del().

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

--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -2725,8 +2725,8 @@ __unregister_ftrace_function_probe(char
continue;
}

- hlist_del(&entry->node);
- call_rcu(&entry->rcu, ftrace_free_entry_rcu);
+ hlist_del_rcu(&entry->node);
+ call_rcu_sched(&entry->rcu, ftrace_free_entry_rcu);
}
}
__disable_ftrace_function_probe();

2013-03-25 01:24:46

by Ben Hutchings

[permalink] [raw]
Subject: [ 051/104] jbd2: fix use after free in jbd2_journal_dirty_metadata()

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

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

From: Jan Kara <[email protected]>

commit ad56edad089b56300fd13bb9eeb7d0424d978239 upstream.

jbd2_journal_dirty_metadata() didn't get a reference to journal_head it
was working with. This is OK in most of the cases since the journal head
should be attached to a transaction but in rare occasions when we are
journalling data, __ext4_journalled_writepage() can race with
jbd2_journal_invalidatepage() stripping buffers from a page and thus
journal head can be freed under hands of jbd2_journal_dirty_metadata().

Fix the problem by getting own journal head reference in
jbd2_journal_dirty_metadata() (and also in jbd2_journal_set_triggers()
which can possibly have the same issue).

Reported-by: Zheng Liu <[email protected]>
Signed-off-by: Jan Kara <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/jbd2/transaction.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)

--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -1016,9 +1016,12 @@ out:
void jbd2_journal_set_triggers(struct buffer_head *bh,
struct jbd2_buffer_trigger_type *type)
{
- struct journal_head *jh = bh2jh(bh);
+ struct journal_head *jh = jbd2_journal_grab_journal_head(bh);

+ if (WARN_ON(!jh))
+ return;
jh->b_triggers = type;
+ jbd2_journal_put_journal_head(jh);
}

void jbd2_buffer_frozen_trigger(struct journal_head *jh, void *mapped_data,
@@ -1070,17 +1073,18 @@ int jbd2_journal_dirty_metadata(handle_t
{
transaction_t *transaction = handle->h_transaction;
journal_t *journal = transaction->t_journal;
- struct journal_head *jh = bh2jh(bh);
+ struct journal_head *jh;
int ret = 0;

- jbd_debug(5, "journal_head %p\n", jh);
- JBUFFER_TRACE(jh, "entry");
if (is_handle_aborted(handle))
goto out;
- if (!buffer_jbd(bh)) {
+ jh = jbd2_journal_grab_journal_head(bh);
+ if (!jh) {
ret = -EUCLEAN;
goto out;
}
+ jbd_debug(5, "journal_head %p\n", jh);
+ JBUFFER_TRACE(jh, "entry");

jbd_lock_bh_state(bh);

@@ -1171,6 +1175,7 @@ int jbd2_journal_dirty_metadata(handle_t
spin_unlock(&journal->j_list_lock);
out_unlock_bh:
jbd_unlock_bh_state(bh);
+ jbd2_journal_put_journal_head(jh);
out:
JBUFFER_TRACE(jh, "exit");
WARN_ON(ret); /* All errors are bugs, so dump the stack */

2013-03-25 01:24:47

by Ben Hutchings

[permalink] [raw]
Subject: [ 049/104] sfc: Only use TX push if a single descriptor is to be written

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

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

From: Ben Hutchings <[email protected]>

[ Upstream commit fae8563b25f73dc584a07bcda7a82750ff4f7672 ]

Using TX push when notifying the NIC of multiple new descriptors in
the ring will very occasionally cause the TX DMA engine to re-use an
old descriptor. This can result in a duplicated or partly duplicated
packet (new headers with old data), or an IOMMU page fault. This does
not happen when the pushed descriptor is the only one written.

TX push also provides little latency benefit when a packet requires
more than one descriptor.

Signed-off-by: Ben Hutchings <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/ethernet/sfc/nic.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c
index 9cca2a6..2e9ca10 100644
--- a/drivers/net/ethernet/sfc/nic.c
+++ b/drivers/net/ethernet/sfc/nic.c
@@ -371,7 +371,8 @@ efx_may_push_tx_desc(struct efx_tx_queue *tx_queue, unsigned int write_count)
return false;

tx_queue->empty_read_count = 0;
- return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0;
+ return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0
+ && tx_queue->write_count - write_count == 1;
}

/* For each entry inserted into the software descriptor ring, create a

2013-03-25 01:24:45

by Ben Hutchings

[permalink] [raw]
Subject: [ 048/104] sfc: Disable soft interrupt handling during efx_device_detach_sync()

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

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

From: Ben Hutchings <[email protected]>

[ Upstream commit 35205b211c8d17a8a0b5e8926cb7c73e9a7ef1ad ]

efx_device_detach_sync() locks all TX queues before marking the device
detached and thus disabling further TX scheduling. But it can still
be interrupted by TX completions which then result in TX scheduling in
soft interrupt context. This will deadlock when it tries to acquire
a TX queue lock that efx_device_detach_sync() already acquired.

To avoid deadlock, we must use netif_tx_{,un}lock_bh().

Signed-off-by: Ben Hutchings <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/ethernet/sfc/efx.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h
index 55e72af..9668d29 100644
--- a/drivers/net/ethernet/sfc/efx.h
+++ b/drivers/net/ethernet/sfc/efx.h
@@ -157,9 +157,9 @@ static inline void efx_device_detach_sync(struct efx_nic *efx)
* TX scheduler is stopped when we're done and before
* netif_device_present() becomes false.
*/
- netif_tx_lock(dev);
+ netif_tx_lock_bh(dev);
netif_device_detach(dev);
- netif_tx_unlock(dev);
+ netif_tx_unlock_bh(dev);
}

#endif /* EFX_EFX_H */

2013-03-25 01:16:11

by Ben Hutchings

[permalink] [raw]
Subject: [ 060/104] tracing: Keep overwrite in sync between regular and snapshot buffers

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

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

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

commit 80902822658aab18330569587cdb69ac1dfdcea8 upstream.

Changing the overwrite mode for the ring buffer via the trace
option only sets the normal buffer. But the snapshot buffer could
swap with it, and then the snapshot would be in non overwrite mode
and the normal buffer would be in overwrite mode, even though the
option flag states otherwise.

Keep the two buffers overwrite modes in sync.

Signed-off-by: Steven Rostedt <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
kernel/trace/trace.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -2650,8 +2650,12 @@ static void set_tracer_flags(unsigned in
if (mask == TRACE_ITER_RECORD_CMD)
trace_event_enable_cmd_record(enabled);

- if (mask == TRACE_ITER_OVERWRITE)
+ if (mask == TRACE_ITER_OVERWRITE) {
ring_buffer_change_overwrite(global_trace.buffer, enabled);
+#ifdef CONFIG_TRACER_MAX_TRACE
+ ring_buffer_change_overwrite(max_tr.buffer, enabled);
+#endif
+ }
}

static ssize_t

2013-03-25 01:25:50

by Ben Hutchings

[permalink] [raw]
Subject: [ 052/104] ext4: convert number of blocks to clusters properly

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

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

From: Lukas Czerner <[email protected]>

commit 810da240f221d64bf90020f25941b05b378186fe upstream.

We're using macro EXT4_B2C() to convert number of blocks to number of
clusters for bigalloc file systems. However, we should be using
EXT4_NUM_B2C().

Signed-off-by: Lukas Czerner <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
[bwh: Backported to 3.2:
- Adjust context
- Drop changes in ext4_setup_new_descs() and ext4_calculate_overhead()]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -571,7 +571,7 @@ ext4_fsblk_t ext4_count_free_clusters(st
brelse(bitmap_bh);
printk(KERN_DEBUG "ext4_count_free_clusters: stored = %llu"
", computed = %llu, %llu\n",
- EXT4_B2C(EXT4_SB(sb), ext4_free_blocks_count(es)),
+ EXT4_NUM_B2C(EXT4_SB(sb), ext4_free_blocks_count(es)),
desc_count, bitmap_count);
return bitmap_count;
#else
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -3485,7 +3485,7 @@ ext4_mb_new_inode_pa(struct ext4_allocat
win = offs;

ac->ac_b_ex.fe_logical = ac->ac_o_ex.fe_logical -
- EXT4_B2C(sbi, win);
+ EXT4_NUM_B2C(sbi, win);
BUG_ON(ac->ac_o_ex.fe_logical < ac->ac_b_ex.fe_logical);
BUG_ON(ac->ac_o_ex.fe_len > ac->ac_b_ex.fe_len);
}
@@ -4634,7 +4634,7 @@ do_more:
EXT4_BLOCKS_PER_GROUP(sb);
count -= overflow;
}
- count_clusters = EXT4_B2C(sbi, count);
+ count_clusters = EXT4_NUM_B2C(sbi, count);
bitmap_bh = ext4_read_block_bitmap(sb, block_group);
if (!bitmap_bh) {
err = -EIO;
@@ -4865,11 +4865,11 @@ int ext4_group_add_blocks(handle_t *hand
desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc);
ext4_unlock_group(sb, block_group);
percpu_counter_add(&sbi->s_freeclusters_counter,
- EXT4_B2C(sbi, blocks_freed));
+ EXT4_NUM_B2C(sbi, blocks_freed));

if (sbi->s_log_groups_per_flex) {
ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
- atomic_add(EXT4_B2C(sbi, blocks_freed),
+ atomic_add(EXT4_NUM_B2C(sbi, blocks_freed),
&sbi->s_flex_groups[flex_group].free_clusters);
}

--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -938,7 +938,7 @@ int ext4_group_add(struct super_block *s

/* Update the free space counts */
percpu_counter_add(&sbi->s_freeclusters_counter,
- EXT4_B2C(sbi, input->free_blocks_count));
+ EXT4_NUM_B2C(sbi, input->free_blocks_count));
percpu_counter_add(&sbi->s_freeinodes_counter,
EXT4_INODES_PER_GROUP(sb));

@@ -946,7 +946,7 @@ int ext4_group_add(struct super_block *s
sbi->s_log_groups_per_flex) {
ext4_group_t flex_group;
flex_group = ext4_flex_group(sbi, input->group);
- atomic_add(EXT4_B2C(sbi, input->free_blocks_count),
+ atomic_add(EXT4_NUM_B2C(sbi, input->free_blocks_count),
&sbi->s_flex_groups[flex_group].free_clusters);
atomic_add(EXT4_INODES_PER_GROUP(sb),
&sbi->s_flex_groups[flex_group].free_inodes);

2013-03-25 01:16:10

by Ben Hutchings

[permalink] [raw]
Subject: [ 078/104] efivars: explicitly calculate length of VariableName

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

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

From: Matt Fleming <[email protected]>

commit ec50bd32f1672d38ddce10fb1841cbfda89cfe9a upstream.

It's not wise to assume VariableNameSize represents the length of
VariableName, as not all firmware updates VariableNameSize in the same
way (some don't update it at all if EFI_SUCCESS is returned). There
are even implementations out there that update VariableNameSize with
values that are both larger than the string returned in VariableName
and smaller than the buffer passed to GetNextVariableName(), which
resulted in the following bug report from Michael Schroeder,

> On HP z220 system (firmware version 1.54), some EFI variables are
> incorrectly named :
>
> ls -d /sys/firmware/efi/vars/*8be4d* | grep -v -- -8be returns
> /sys/firmware/efi/vars/dbxDefault-pport8be4df61-93ca-11d2-aa0d-00e098032b8c
> /sys/firmware/efi/vars/KEKDefault-pport8be4df61-93ca-11d2-aa0d-00e098032b8c
> /sys/firmware/efi/vars/SecureBoot-pport8be4df61-93ca-11d2-aa0d-00e098032b8c
> /sys/firmware/efi/vars/SetupMode-Information8be4df61-93ca-11d2-aa0d-00e098032b8c

The issue here is that because we blindly use VariableNameSize without
verifying its value, we can potentially read garbage values from the
buffer containing VariableName if VariableNameSize is larger than the
length of VariableName.

Since VariableName is a string, we can calculate its size by searching
for the terminating NULL character.

Reported-by: Frederic Crozat <[email protected]>
Cc: Matthew Garrett <[email protected]>
Cc: Josh Boyer <[email protected]>
Cc: Michael Schroeder <[email protected]>
Cc: Lee, Chun-Yi <[email protected]>
Cc: Lingzhu Xiang <[email protected]>
Cc: Seiji Aguchi <[email protected]>
Signed-off-by: Matt Fleming <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/firmware/efivars.c | 32 +++++++++++++++++++++++++++++++-
1 file changed, 31 insertions(+), 1 deletion(-)

--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -1043,6 +1043,31 @@ static bool variable_is_present(efi_char
return found;
}

+/*
+ * Returns the size of variable_name, in bytes, including the
+ * terminating NULL character, or variable_name_size if no NULL
+ * character is found among the first variable_name_size bytes.
+ */
+static unsigned long var_name_strnsize(efi_char16_t *variable_name,
+ unsigned long variable_name_size)
+{
+ unsigned long len;
+ efi_char16_t c;
+
+ /*
+ * The variable name is, by definition, a NULL-terminated
+ * string, so make absolutely sure that variable_name_size is
+ * the value we expect it to be. If not, return the real size.
+ */
+ for (len = 2; len <= variable_name_size; len += sizeof(c)) {
+ c = variable_name[(len / sizeof(c)) - 1];
+ if (!c)
+ break;
+ }
+
+ return min(len, variable_name_size);
+}
+
static void efivar_update_sysfs_entries(struct work_struct *work)
{
struct efivars *efivars = &__efivars;
@@ -1083,10 +1108,13 @@ static void efivar_update_sysfs_entries(
if (!found) {
kfree(variable_name);
break;
- } else
+ } else {
+ variable_name_size = var_name_strnsize(variable_name,
+ variable_name_size);
efivar_create_sysfs_entry(efivars,
variable_name_size,
variable_name, &vendor);
+ }
}
}

@@ -1317,6 +1345,8 @@ int register_efivars(struct efivars *efi
&vendor_guid);
switch (status) {
case EFI_SUCCESS:
+ variable_name_size = var_name_strnsize(variable_name,
+ variable_name_size);
efivar_create_sysfs_entry(efivars,
variable_name_size,
variable_name,

2013-03-25 01:26:17

by Ben Hutchings

[permalink] [raw]
Subject: [ 053/104] ext4: use atomic64_t for the per-flexbg free_clusters count

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

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

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

commit 90ba983f6889e65a3b506b30dc606aa9d1d46cd2 upstream.

A user who was using a 8TB+ file system and with a very large flexbg
size (> 65536) could cause the atomic_t used in the struct flex_groups
to overflow. This was detected by PaX security patchset:

http://forums.grsecurity.net/viewtopic.php?f=3&t=3289&p=12551#p12551

This bug was introduced in commit 9f24e4208f7e, so it's been around
since 2.6.30. :-(

Fix this by using an atomic64_t for struct orlav_stats's
free_clusters.

Signed-off-by: "Theodore Ts'o" <[email protected]>
Reviewed-by: Lukas Czerner <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/ext4/ext4.h | 6 +++---
fs/ext4/ialloc.c | 4 ++--
fs/ext4/mballoc.c | 12 ++++++------
fs/ext4/resize.c | 4 ++--
fs/ext4/super.c | 4 ++--
5 files changed, 15 insertions(+), 15 deletions(-)

--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -309,9 +309,9 @@ struct ext4_group_desc
*/

struct flex_groups {
- atomic_t free_inodes;
- atomic_t free_clusters;
- atomic_t used_dirs;
+ atomic64_t free_clusters;
+ atomic_t free_inodes;
+ atomic_t used_dirs;
};

#define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -294,8 +294,8 @@ error_return:
}

struct orlov_stats {
+ __u64 free_clusters;
__u32 free_inodes;
- __u32 free_clusters;
__u32 used_dirs;
};

@@ -312,7 +312,7 @@ static void get_orlov_stats(struct super

if (flex_size > 1) {
stats->free_inodes = atomic_read(&flex_group[g].free_inodes);
- stats->free_clusters = atomic_read(&flex_group[g].free_clusters);
+ stats->free_clusters = atomic64_read(&flex_group[g].free_clusters);
stats->used_dirs = atomic_read(&flex_group[g].used_dirs);
return;
}
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2866,8 +2866,8 @@ ext4_mb_mark_diskspace_used(struct ext4_
if (sbi->s_log_groups_per_flex) {
ext4_group_t flex_group = ext4_flex_group(sbi,
ac->ac_b_ex.fe_group);
- atomic_sub(ac->ac_b_ex.fe_len,
- &sbi->s_flex_groups[flex_group].free_clusters);
+ atomic64_sub(ac->ac_b_ex.fe_len,
+ &sbi->s_flex_groups[flex_group].free_clusters);
}

err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
@@ -4724,8 +4724,8 @@ do_more:

if (sbi->s_log_groups_per_flex) {
ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
- atomic_add(count_clusters,
- &sbi->s_flex_groups[flex_group].free_clusters);
+ atomic64_add(count_clusters,
+ &sbi->s_flex_groups[flex_group].free_clusters);
}

ext4_mb_unload_buddy(&e4b);
@@ -4869,8 +4869,8 @@ int ext4_group_add_blocks(handle_t *hand

if (sbi->s_log_groups_per_flex) {
ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
- atomic_add(EXT4_NUM_B2C(sbi, blocks_freed),
- &sbi->s_flex_groups[flex_group].free_clusters);
+ atomic64_add(EXT4_NUM_B2C(sbi, blocks_freed),
+ &sbi->s_flex_groups[flex_group].free_clusters);
}

ext4_mb_unload_buddy(&e4b);
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -946,8 +946,8 @@ int ext4_group_add(struct super_block *s
sbi->s_log_groups_per_flex) {
ext4_group_t flex_group;
flex_group = ext4_flex_group(sbi, input->group);
- atomic_add(EXT4_NUM_B2C(sbi, input->free_blocks_count),
- &sbi->s_flex_groups[flex_group].free_clusters);
+ atomic64_add(EXT4_NUM_B2C(sbi, input->free_blocks_count),
+ &sbi->s_flex_groups[flex_group].free_clusters);
atomic_add(EXT4_INODES_PER_GROUP(sb),
&sbi->s_flex_groups[flex_group].free_inodes);
}
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2047,8 +2047,8 @@ static int ext4_fill_flex_info(struct su
flex_group = ext4_flex_group(sbi, i);
atomic_add(ext4_free_inodes_count(sb, gdp),
&sbi->s_flex_groups[flex_group].free_inodes);
- atomic_add(ext4_free_group_clusters(sb, gdp),
- &sbi->s_flex_groups[flex_group].free_clusters);
+ atomic64_add(ext4_free_group_clusters(sb, gdp),
+ &sbi->s_flex_groups[flex_group].free_clusters);
atomic_add(ext4_used_dirs_count(sb, gdp),
&sbi->s_flex_groups[flex_group].used_dirs);
}

2013-03-25 01:26:34

by Ben Hutchings

[permalink] [raw]
Subject: [ 055/104] cifs: delay super block destruction until all cifsFileInfo objects

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

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

From: Mateusz Guzik <[email protected]>

commit 24261fc23db950951760d00c188ba63cc756b932 upstream.

cifsFileInfo objects hold references to dentries and it is possible that
these will still be around in workqueues when VFS decides to kill super
block during unmount.

This results in panics like this one:
BUG: Dentry ffff88001f5e76c0{i=66b4a,n=1M-2} still in use (1) [unmount of cifs cifs]
------------[ cut here ]------------
kernel BUG at fs/dcache.c:943!
[..]
Process umount (pid: 1781, threadinfo ffff88003d6e8000, task ffff880035eeaec0)
[..]
Call Trace:
[<ffffffff811b44f3>] shrink_dcache_for_umount+0x33/0x60
[<ffffffff8119f7fc>] generic_shutdown_super+0x2c/0xe0
[<ffffffff8119f946>] kill_anon_super+0x16/0x30
[<ffffffffa036623a>] cifs_kill_sb+0x1a/0x30 [cifs]
[<ffffffff8119fcc7>] deactivate_locked_super+0x57/0x80
[<ffffffff811a085e>] deactivate_super+0x4e/0x70
[<ffffffff811bb417>] mntput_no_expire+0xd7/0x130
[<ffffffff811bc30c>] sys_umount+0x9c/0x3c0
[<ffffffff81657c19>] system_call_fastpath+0x16/0x1b

Fix this by making each cifsFileInfo object hold a reference to cifs
super block, which implicitly keeps VFS super block around as well.

Signed-off-by: Mateusz Guzik <[email protected]>
Reviewed-by: Jeff Layton <[email protected]>
Reported-and-Tested-by: Ben Greear <[email protected]>
Signed-off-by: Steve French <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/cifs/cifsfs.c | 24 ++++++++++++++++++++++++
fs/cifs/cifsfs.h | 4 ++++
fs/cifs/file.c | 6 +++++-
3 files changed, 33 insertions(+), 1 deletion(-)

--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -90,6 +90,30 @@ extern mempool_t *cifs_sm_req_poolp;
extern mempool_t *cifs_req_poolp;
extern mempool_t *cifs_mid_poolp;

+/*
+ * Bumps refcount for cifs super block.
+ * Note that it should be only called if a referece to VFS super block is
+ * already held, e.g. in open-type syscalls context. Otherwise it can race with
+ * atomic_dec_and_test in deactivate_locked_super.
+ */
+void
+cifs_sb_active(struct super_block *sb)
+{
+ struct cifs_sb_info *server = CIFS_SB(sb);
+
+ if (atomic_inc_return(&server->active) == 1)
+ atomic_inc(&sb->s_active);
+}
+
+void
+cifs_sb_deactive(struct super_block *sb)
+{
+ struct cifs_sb_info *server = CIFS_SB(sb);
+
+ if (atomic_dec_and_test(&server->active))
+ deactivate_super(sb);
+}
+
static int
cifs_read_super(struct super_block *sb)
{
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -41,6 +41,10 @@ extern struct file_system_type cifs_fs_t
extern const struct address_space_operations cifs_addr_ops;
extern const struct address_space_operations cifs_addr_ops_smallbuf;

+/* Functions related to super block operations */
+extern void cifs_sb_active(struct super_block *sb);
+extern void cifs_sb_deactive(struct super_block *sb);
+
/* Functions related to inodes */
extern const struct inode_operations cifs_dir_inode_ops;
extern struct inode *cifs_root_iget(struct super_block *);
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -265,6 +265,8 @@ cifs_new_fileinfo(__u16 fileHandle, stru
mutex_init(&pCifsFile->fh_mutex);
INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break);

+ cifs_sb_active(inode->i_sb);
+
spin_lock(&cifs_file_list_lock);
list_add(&pCifsFile->tlist, &(tlink_tcon(tlink)->openFileList));
/* if readable file instance put first in list*/
@@ -293,7 +295,8 @@ void cifsFileInfo_put(struct cifsFileInf
struct inode *inode = cifs_file->dentry->d_inode;
struct cifs_tcon *tcon = tlink_tcon(cifs_file->tlink);
struct cifsInodeInfo *cifsi = CIFS_I(inode);
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+ struct super_block *sb = inode->i_sb;
+ struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifsLockInfo *li, *tmp;

spin_lock(&cifs_file_list_lock);
@@ -345,6 +348,7 @@ void cifsFileInfo_put(struct cifsFileInf

cifs_put_tlink(cifs_file->tlink);
dput(cifs_file->dentry);
+ cifs_sb_deactive(sb);
kfree(cifs_file);
}


2013-03-25 01:16:08

by Ben Hutchings

[permalink] [raw]
Subject: [ 065/104] ALSA: hda/cirrus - Fix the digital beep registration

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

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

From: Takashi Iwai <[email protected]>

commit a86b1a2cd2f81f74e815e07f756edd7bc5b6f034 upstream.

The argument passed to snd_hda_attach_beep_device() is a widget NID
while spec->beep_amp holds the composed value for amp controls.

Signed-off-by: Takashi Iwai <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
sound/pci/hda/patch_conexant.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -1236,7 +1236,7 @@ static int patch_cxt5045(struct hda_code
}

if (spec->beep_amp)
- snd_hda_attach_beep_device(codec, spec->beep_amp);
+ snd_hda_attach_beep_device(codec, get_amp_nid_(spec->beep_amp));

return 0;
}
@@ -2027,7 +2027,7 @@ static int patch_cxt5051(struct hda_code
}

if (spec->beep_amp)
- snd_hda_attach_beep_device(codec, spec->beep_amp);
+ snd_hda_attach_beep_device(codec, get_amp_nid_(spec->beep_amp));

conexant_init_jacks(codec);
if (spec->auto_mic & AUTO_MIC_PORTB)
@@ -3225,7 +3225,7 @@ static int patch_cxt5066(struct hda_code
}

if (spec->beep_amp)
- snd_hda_attach_beep_device(codec, spec->beep_amp);
+ snd_hda_attach_beep_device(codec, get_amp_nid_(spec->beep_amp));

return 0;
}
@@ -4556,7 +4556,7 @@ static int patch_conexant_auto(struct hd
spec->capture_stream = &cx_auto_pcm_analog_capture;
codec->patch_ops = cx_auto_patch_ops;
if (spec->beep_amp)
- snd_hda_attach_beep_device(codec, spec->beep_amp);
+ snd_hda_attach_beep_device(codec, get_amp_nid_(spec->beep_amp));
return 0;
}


2013-03-25 01:26:52

by Ben Hutchings

[permalink] [raw]
Subject: [ 056/104] drm/i915: restrict kernel address leak in debugfs

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

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

From: Kees Cook <[email protected]>

commit 2563a4524febe8f4a98e717e02436d1aaf672aa2 upstream.

Masks kernel address info-leak in object dumps with the %pK suffix,
so they cannot be used to target kernel memory corruption attacks if
the kptr_restrict sysctl is set.

Signed-off-by: Kees Cook <[email protected]>
Signed-off-by: Daniel Vetter <[email protected]>
[bwh: Backported to 3.2: the rest of the format string is different]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/i915/i915_debugfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -122,7 +122,7 @@ static const char *cache_level_str(int t
static void
describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
{
- seq_printf(m, "%p: %s%s %8zd %04x %04x %d %d%s%s%s",
+ seq_printf(m, "%pK: %s%s %8zd %04x %04x %d %d%s%s%s",
&obj->base,
get_pin_flag(obj),
get_tiling_flag(obj),

2013-03-25 01:26:50

by Ben Hutchings

[permalink] [raw]
Subject: [ 054/104] tracing: Fix race in snapshot swapping

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

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

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

commit 2721e72dd10f71a3ba90f59781becf02638aa0d9 upstream.

Although the swap is wrapped with a spin_lock, the assignment
of the temp buffer used to swap is not within that lock.
It needs to be moved into that lock, otherwise two swaps
happening on two different CPUs, can end up using the wrong
temp buffer to assign in the swap.

Luckily, all current callers of the swap function appear to have
their own locks. But in case something is added that allows two
different callers to call the swap, then there's a chance that
this race can trigger and corrupt the buffers.

New code is coming soon that will allow for this race to trigger.

I've Cc'd stable, so this bug will not show up if someone backports
one of the changes that can trigger this bug.

Signed-off-by: Steven Rostedt <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
kernel/trace/trace.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -652,7 +652,7 @@ __update_max_tr(struct trace_array *tr,
void
update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
{
- struct ring_buffer *buf = tr->buffer;
+ struct ring_buffer *buf;

if (trace_stop_count)
return;
@@ -664,6 +664,7 @@ update_max_tr(struct trace_array *tr, st
}
arch_spin_lock(&ftrace_max_lock);

+ buf = tr->buffer;
tr->buffer = max_tr.buffer;
max_tr.buffer = buf;


2013-03-25 01:27:27

by Ben Hutchings

[permalink] [raw]
Subject: [ 059/104] tracing: Protect tracer flags with trace_types_lock

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

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

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

commit 69d34da2984c95b33ea21518227e1f9470f11d95 upstream.

Seems that the tracer flags have never been protected from
synchronous writes. Luckily, admins don't usually modify the
tracing flags via two different tasks. But if scripts were to
be used to modify them, then they could get corrupted.

Move the trace_types_lock that protects against tracers changing
to also protect the flags being set.

Signed-off-by: Steven Rostedt <[email protected]>
[bwh: Backported to 3.2: also move failure return in
tracing_trace_options_write() after unlocking]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -2661,7 +2661,7 @@ tracing_trace_options_write(struct file
char buf[64];
char *cmp;
int neg = 0;
- int ret;
+ int ret = 0;
int i;

if (cnt >= sizeof(buf))
@@ -2678,6 +2678,8 @@ tracing_trace_options_write(struct file
cmp += 2;
}

+ mutex_lock(&trace_types_lock);
+
for (i = 0; trace_options[i]; i++) {
if (strcmp(cmp, trace_options[i]) == 0) {
set_tracer_flags(1 << i, !neg);
@@ -2686,13 +2688,13 @@ tracing_trace_options_write(struct file
}

/* If no option could be set, test the specific tracer options */
- if (!trace_options[i]) {
- mutex_lock(&trace_types_lock);
+ if (!trace_options[i])
ret = set_tracer_option(current_trace, cmp, neg);
- mutex_unlock(&trace_types_lock);
- if (ret)
- return ret;
- }
+
+ mutex_unlock(&trace_types_lock);
+
+ if (ret)
+ return ret;

*ppos += cnt;

@@ -4379,7 +4381,10 @@ trace_options_core_write(struct file *fi

if (val != 0 && val != 1)
return -EINVAL;
+
+ mutex_lock(&trace_types_lock);
set_tracer_flags(1 << index, val);
+ mutex_unlock(&trace_types_lock);

*ppos += cnt;


2013-03-25 01:27:44

by Ben Hutchings

[permalink] [raw]
Subject: [ 057/104] drm/i915: bounds check execbuffer relocation count

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

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

From: Kees Cook <[email protected]>

commit 3118a4f652c7b12c752f3222af0447008f9b2368 upstream.

It is possible to wrap the counter used to allocate the buffer for
relocation copies. This could lead to heap writing overflows.

CVE-2013-0913

v3: collapse test, improve comment
v2: move check into validate_exec_list

Signed-off-by: Kees Cook <[email protected]>
Reported-by: Pinkie Pie
Reviewed-by: Chris Wilson <[email protected]>
Signed-off-by: Daniel Vetter <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/i915/i915_gem_execbuffer.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)

--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -907,15 +907,20 @@ validate_exec_list(struct drm_i915_gem_e
int count)
{
int i;
+ int relocs_total = 0;
+ int relocs_max = INT_MAX / sizeof(struct drm_i915_gem_relocation_entry);

for (i = 0; i < count; i++) {
char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr;
int length; /* limited by fault_in_pages_readable() */

- /* First check for malicious input causing overflow */
- if (exec[i].relocation_count >
- INT_MAX / sizeof(struct drm_i915_gem_relocation_entry))
+ /* First check for malicious input causing overflow in
+ * the worst case where we need to allocate the entire
+ * relocation tree as a single array.
+ */
+ if (exec[i].relocation_count > relocs_max - relocs_total)
return -EINVAL;
+ relocs_total += exec[i].relocation_count;

length = exec[i].relocation_count *
sizeof(struct drm_i915_gem_relocation_entry);

2013-03-25 01:16:06

by Ben Hutchings

[permalink] [raw]
Subject: [ 064/104] drm/radeon/benchmark: make sure bo blit copy exists before using it

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

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

From: Alex Deucher <[email protected]>

commit fa8d387dc3f62062a6b4afbbb2a3438094fd8584 upstream.

Fixes a segfault on asics without a blit callback.

Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=62239

Reviewed-by: Michel Dänzer <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
[bwh: Backported to 3.2: s/copy\.blit/copy_blit/]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/radeon/radeon_benchmark.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)

--- a/drivers/gpu/drm/radeon/radeon_benchmark.c
+++ b/drivers/gpu/drm/radeon/radeon_benchmark.c
@@ -139,13 +139,15 @@ static void radeon_benchmark_move(struct
sdomain, ddomain, "dma");
}

- time = radeon_benchmark_do_move(rdev, size, saddr, daddr,
- RADEON_BENCHMARK_COPY_BLIT, n);
- if (time < 0)
- goto out_cleanup;
- if (time > 0)
- radeon_benchmark_log_results(n, size, time,
- sdomain, ddomain, "blit");
+ if (rdev->asic->copy_blit) {
+ time = radeon_benchmark_do_move(rdev, size, saddr, daddr,
+ RADEON_BENCHMARK_COPY_BLIT, n);
+ if (time < 0)
+ goto out_cleanup;
+ if (time > 0)
+ radeon_benchmark_log_results(n, size, time,
+ sdomain, ddomain, "blit");
+ }

out_cleanup:
if (sobj) {

2013-03-25 01:28:07

by Ben Hutchings

[permalink] [raw]
Subject: [ 063/104] usb-storage: add unusual_devs entry for Samsung YP-Z3 mp3 player

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

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

From: Dmitry Artamonow <[email protected]>

commit 29f86e66428ee083aec106cca1748dc63d98ce23 upstream.

Device stucks on filesystem writes, unless following quirk is passed:
echo 04e8:5136:m > /sys/module/usb_storage/parameters/quirks

Add corresponding entry to unusual_devs.h

Signed-off-by: Dmitry Artamonow <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/storage/unusual_devs.h | 7 +++++++
1 file changed, 7 insertions(+)

--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -488,6 +488,13 @@ UNUSUAL_DEV( 0x04e8, 0x5122, 0x0000, 0x
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_MAX_SECTORS_64 | US_FL_BULK_IGNORE_TAG),

+/* Added by Dmitry Artamonow <[email protected]> */
+UNUSUAL_DEV( 0x04e8, 0x5136, 0x0000, 0x9999,
+ "Samsung",
+ "YP-Z3",
+ USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+ US_FL_MAX_SECTORS_64),
+
/* Entry and supporting patch by Theodore Kilgore <[email protected]>.
* Device uses standards-violating 32-byte Bulk Command Block Wrappers and
* reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011.

2013-03-25 01:16:00

by Ben Hutchings

[permalink] [raw]
Subject: [ 074/104] efivars: Allow disabling use as a pstore backend

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

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

From: Seth Forshee <[email protected]>

commit ed9dc8ce7a1c8115dba9483a9b51df8b63a2e0ef upstream.

Add a new option, CONFIG_EFI_VARS_PSTORE, which can be set to N to
avoid using efivars as a backend to pstore, as some users may want to
compile out the code completely.

Set the default to Y to maintain backwards compatability, since this
feature has always been enabled until now.

Signed-off-by: Seth Forshee <[email protected]>
Cc: Josh Boyer <[email protected]>
Cc: Matthew Garrett <[email protected]>
Cc: Seiji Aguchi <[email protected]>
Cc: Tony Luck <[email protected]>
Signed-off-by: Matt Fleming <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -53,6 +53,15 @@ config EFI_VARS
Subsequent efibootmgr releases may be found at:
<http://linux.dell.com/efibootmgr>

+config EFI_VARS_PSTORE
+ bool "Register efivars backend for pstore"
+ depends on EFI_VARS && PSTORE
+ default y
+ help
+ Say Y here to enable use efivars as a backend to pstore. This
+ will allow writing console messages, crash dumps, or anything
+ else supported by pstore to EFI variables.
+
config EFI_PCDP
bool "Console device selection via EFI PCDP or HCDP table"
depends on ACPI && EFI && IA64
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -659,8 +659,6 @@ static struct kobj_type efivar_ktype = {
.default_attrs = def_attrs,
};

-static struct pstore_info efi_pstore_info;
-
static inline void
efivar_unregister(struct efivar_entry *var)
{
@@ -697,7 +695,7 @@ static int efi_status_to_err(efi_status_
return err;
}

-#ifdef CONFIG_PSTORE
+#ifdef CONFIG_EFI_VARS_PSTORE

static int efi_pstore_open(struct pstore_info *psi)
{
@@ -847,36 +845,6 @@ static int efi_pstore_erase(enum pstore_

return 0;
}
-#else
-static int efi_pstore_open(struct pstore_info *psi)
-{
- return 0;
-}
-
-static int efi_pstore_close(struct pstore_info *psi)
-{
- return 0;
-}
-
-static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
- struct timespec *timespec,
- char **buf, struct pstore_info *psi)
-{
- return -1;
-}
-
-static int efi_pstore_write(enum pstore_type_id type, u64 *id,
- unsigned int part, size_t size, struct pstore_info *psi)
-{
- return 0;
-}
-
-static int efi_pstore_erase(enum pstore_type_id type, u64 id,
- struct pstore_info *psi)
-{
- return 0;
-}
-#endif

static struct pstore_info efi_pstore_info = {
.owner = THIS_MODULE,
@@ -888,6 +856,24 @@ static struct pstore_info efi_pstore_inf
.erase = efi_pstore_erase,
};

+static void efivar_pstore_register(struct efivars *efivars)
+{
+ efivars->efi_pstore_info = efi_pstore_info;
+ efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
+ if (efivars->efi_pstore_info.buf) {
+ efivars->efi_pstore_info.bufsize = 1024;
+ efivars->efi_pstore_info.data = efivars;
+ spin_lock_init(&efivars->efi_pstore_info.buf_lock);
+ pstore_register(&efivars->efi_pstore_info);
+ }
+}
+#else
+static void efivar_pstore_register(struct efivars *efivars)
+{
+ return;
+}
+#endif
+
static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buf, loff_t pos, size_t count)
@@ -1271,15 +1257,7 @@ int register_efivars(struct efivars *efi
if (error)
unregister_efivars(efivars);

- efivars->efi_pstore_info = efi_pstore_info;
-
- efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
- if (efivars->efi_pstore_info.buf) {
- efivars->efi_pstore_info.bufsize = 1024;
- efivars->efi_pstore_info.data = efivars;
- spin_lock_init(&efivars->efi_pstore_info.buf_lock);
- pstore_register(&efivars->efi_pstore_info);
- }
+ efivar_pstore_register(efivars);

out:
kfree(variable_name);

2013-03-25 01:28:26

by Ben Hutchings

[permalink] [raw]
Subject: [ 061/104] tracing: Prevent buffer overwrite disabled for latency tracers

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

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

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

commit 613f04a0f51e6e68ac6fe571ab79da3c0a5eb4da upstream.

The latency tracers require the buffers to be in overwrite mode,
otherwise they get screwed up. Force the buffers to stay in overwrite
mode when latency tracers are enabled.

Added a flag_changed() method to the tracer structure to allow
the tracers to see what flags are being changed, and also be able
to prevent the change from happing.

Signed-off-by: Steven Rostedt <[email protected]>
[bwh: Backported to 3.2:
- Adjust context
- Drop some changes that are not needed because trace_set_options() is not
separate from tracing_trace_options_write()]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -2636,11 +2636,25 @@ static int set_tracer_option(struct trac
return -EINVAL;
}

-static void set_tracer_flags(unsigned int mask, int enabled)
+/* Some tracers require overwrite to stay enabled */
+int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set)
+{
+ if (tracer->enabled && (mask & TRACE_ITER_OVERWRITE) && !set)
+ return -1;
+
+ return 0;
+}
+
+int set_tracer_flag(unsigned int mask, int enabled)
{
/* do nothing if flag is already set */
if (!!(trace_flags & mask) == !!enabled)
- return;
+ return 0;
+
+ /* Give the tracer a chance to approve the change */
+ if (current_trace->flag_changed)
+ if (current_trace->flag_changed(current_trace, mask, !!enabled))
+ return -EINVAL;

if (enabled)
trace_flags |= mask;
@@ -2656,6 +2670,8 @@ static void set_tracer_flags(unsigned in
ring_buffer_change_overwrite(max_tr.buffer, enabled);
#endif
}
+
+ return 0;
}

static ssize_t
@@ -2686,7 +2702,7 @@ tracing_trace_options_write(struct file

for (i = 0; trace_options[i]; i++) {
if (strcmp(cmp, trace_options[i]) == 0) {
- set_tracer_flags(1 << i, !neg);
+ ret = set_tracer_flag(1 << i, !neg);
break;
}
}
@@ -3022,6 +3038,9 @@ static int tracing_set_tracer(const char
goto out;

trace_branch_disable();
+
+ current_trace->enabled = false;
+
if (current_trace && current_trace->reset)
current_trace->reset(tr);
if (current_trace && current_trace->use_max_tr) {
@@ -3051,6 +3070,7 @@ static int tracing_set_tracer(const char
goto out;
}

+ current_trace->enabled = true;
trace_branch_enable(tr);
out:
mutex_unlock(&trace_types_lock);
@@ -4387,9 +4407,12 @@ trace_options_core_write(struct file *fi
return -EINVAL;

mutex_lock(&trace_types_lock);
- set_tracer_flags(1 << index, val);
+ ret = set_tracer_flag(1 << index, val);
mutex_unlock(&trace_types_lock);

+ if (ret < 0)
+ return ret;
+
*ppos += cnt;

return cnt;
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -271,10 +271,14 @@ struct tracer {
enum print_line_t (*print_line)(struct trace_iterator *iter);
/* If you handled the flag setting, return 0 */
int (*set_flag)(u32 old_flags, u32 bit, int set);
+ /* Return 0 if OK with change, else return non-zero */
+ int (*flag_changed)(struct tracer *tracer,
+ u32 mask, int set);
struct tracer *next;
struct tracer_flags *flags;
int print_max;
int use_max_tr;
+ bool enabled;
};


@@ -815,6 +819,9 @@ extern struct list_head ftrace_events;
extern const char *__start___trace_bprintk_fmt[];
extern const char *__stop___trace_bprintk_fmt[];

+int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set);
+int set_tracer_flag(unsigned int mask, int enabled);
+
#undef FTRACE_ENTRY
#define FTRACE_ENTRY(call, struct_name, id, tstruct, print) \
extern struct ftrace_event_call \
--- a/kernel/trace/trace_irqsoff.c
+++ b/kernel/trace/trace_irqsoff.c
@@ -32,7 +32,7 @@ enum {

static int trace_type __read_mostly;

-static int save_lat_flag;
+static int save_flags;

static void stop_irqsoff_tracer(struct trace_array *tr, int graph);
static int start_irqsoff_tracer(struct trace_array *tr, int graph);
@@ -546,8 +546,11 @@ static void stop_irqsoff_tracer(struct t

static void __irqsoff_tracer_init(struct trace_array *tr)
{
- save_lat_flag = trace_flags & TRACE_ITER_LATENCY_FMT;
- trace_flags |= TRACE_ITER_LATENCY_FMT;
+ save_flags = trace_flags;
+
+ /* non overwrite screws up the latency tracers */
+ set_tracer_flag(TRACE_ITER_OVERWRITE, 1);
+ set_tracer_flag(TRACE_ITER_LATENCY_FMT, 1);

tracing_max_latency = 0;
irqsoff_trace = tr;
@@ -561,10 +564,13 @@ static void __irqsoff_tracer_init(struct

static void irqsoff_tracer_reset(struct trace_array *tr)
{
+ int lat_flag = save_flags & TRACE_ITER_LATENCY_FMT;
+ int overwrite_flag = save_flags & TRACE_ITER_OVERWRITE;
+
stop_irqsoff_tracer(tr, is_graph());

- if (!save_lat_flag)
- trace_flags &= ~TRACE_ITER_LATENCY_FMT;
+ set_tracer_flag(TRACE_ITER_LATENCY_FMT, lat_flag);
+ set_tracer_flag(TRACE_ITER_OVERWRITE, overwrite_flag);
}

static void irqsoff_tracer_start(struct trace_array *tr)
@@ -597,6 +603,7 @@ static struct tracer irqsoff_tracer __re
.print_line = irqsoff_print_line,
.flags = &tracer_flags,
.set_flag = irqsoff_set_flag,
+ .flag_changed = trace_keep_overwrite,
#ifdef CONFIG_FTRACE_SELFTEST
.selftest = trace_selftest_startup_irqsoff,
#endif
@@ -630,6 +637,7 @@ static struct tracer preemptoff_tracer _
.print_line = irqsoff_print_line,
.flags = &tracer_flags,
.set_flag = irqsoff_set_flag,
+ .flag_changed = trace_keep_overwrite,
#ifdef CONFIG_FTRACE_SELFTEST
.selftest = trace_selftest_startup_preemptoff,
#endif
@@ -665,6 +673,7 @@ static struct tracer preemptirqsoff_trac
.print_line = irqsoff_print_line,
.flags = &tracer_flags,
.set_flag = irqsoff_set_flag,
+ .flag_changed = trace_keep_overwrite,
#ifdef CONFIG_FTRACE_SELFTEST
.selftest = trace_selftest_startup_preemptirqsoff,
#endif
--- a/kernel/trace/trace_sched_wakeup.c
+++ b/kernel/trace/trace_sched_wakeup.c
@@ -36,7 +36,7 @@ static void __wakeup_reset(struct trace_
static int wakeup_graph_entry(struct ftrace_graph_ent *trace);
static void wakeup_graph_return(struct ftrace_graph_ret *trace);

-static int save_lat_flag;
+static int save_flags;

#define TRACE_DISPLAY_GRAPH 1

@@ -528,8 +528,11 @@ static void stop_wakeup_tracer(struct tr

static int __wakeup_tracer_init(struct trace_array *tr)
{
- save_lat_flag = trace_flags & TRACE_ITER_LATENCY_FMT;
- trace_flags |= TRACE_ITER_LATENCY_FMT;
+ save_flags = trace_flags;
+
+ /* non overwrite screws up the latency tracers */
+ set_tracer_flag(TRACE_ITER_OVERWRITE, 1);
+ set_tracer_flag(TRACE_ITER_LATENCY_FMT, 1);

tracing_max_latency = 0;
wakeup_trace = tr;
@@ -551,12 +554,15 @@ static int wakeup_rt_tracer_init(struct

static void wakeup_tracer_reset(struct trace_array *tr)
{
+ int lat_flag = save_flags & TRACE_ITER_LATENCY_FMT;
+ int overwrite_flag = save_flags & TRACE_ITER_OVERWRITE;
+
stop_wakeup_tracer(tr);
/* make sure we put back any tasks we are tracing */
wakeup_reset(tr);

- if (!save_lat_flag)
- trace_flags &= ~TRACE_ITER_LATENCY_FMT;
+ set_tracer_flag(TRACE_ITER_LATENCY_FMT, lat_flag);
+ set_tracer_flag(TRACE_ITER_OVERWRITE, overwrite_flag);
}

static void wakeup_tracer_start(struct trace_array *tr)
@@ -582,6 +588,7 @@ static struct tracer wakeup_tracer __rea
.print_line = wakeup_print_line,
.flags = &tracer_flags,
.set_flag = wakeup_set_flag,
+ .flag_changed = trace_keep_overwrite,
#ifdef CONFIG_FTRACE_SELFTEST
.selftest = trace_selftest_startup_wakeup,
#endif
@@ -603,6 +610,7 @@ static struct tracer wakeup_rt_tracer __
.print_line = wakeup_print_line,
.flags = &tracer_flags,
.set_flag = wakeup_set_flag,
+ .flag_changed = trace_keep_overwrite,
#ifdef CONFIG_FTRACE_SELFTEST
.selftest = trace_selftest_startup_wakeup,
#endif

2013-03-25 01:28:47

by Ben Hutchings

[permalink] [raw]
Subject: [ 062/104] USB: xhci: correctly enable interrupts

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

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

From: Hannes Reinecke <[email protected]>

commit 00eed9c814cb8f281be6f0f5d8f45025dc0a97eb upstream.

xhci has its own interrupt enabling routine, which will try to
use MSI-X/MSI if present. So the usb core shouldn't try to enable
legacy interrupts; on some machines the xhci legacy IRQ setting
is invalid.

v3: Be careful to not break XHCI_BROKEN_MSI workaround (by trenn)

Cc: Bjorn Helgaas <[email protected]>
Cc: Oliver Neukum <[email protected]>
Cc: Thomas Renninger <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: Frederik Himpe <[email protected]>
Cc: David Haerdeman <[email protected]>
Cc: Alan Stern <[email protected]>
Acked-by: Sarah Sharp <[email protected]>
Reviewed-by: Thomas Renninger <[email protected]>
Signed-off-by: Hannes Reinecke <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/core/hcd-pci.c | 23 ++++++++++++++---------
drivers/usb/host/xhci.c | 3 ++-
2 files changed, 16 insertions(+), 10 deletions(-)

--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -173,6 +173,7 @@ int usb_hcd_pci_probe(struct pci_dev *de
struct hc_driver *driver;
struct usb_hcd *hcd;
int retval;
+ int hcd_irq = 0;

if (usb_disabled())
return -ENODEV;
@@ -187,15 +188,19 @@ int usb_hcd_pci_probe(struct pci_dev *de
return -ENODEV;
dev->current_state = PCI_D0;

- /* The xHCI driver supports MSI and MSI-X,
- * so don't fail if the BIOS doesn't provide a legacy IRQ.
+ /*
+ * The xHCI driver has its own irq management
+ * make sure irq setup is not touched for xhci in generic hcd code
*/
- if (!dev->irq && (driver->flags & HCD_MASK) != HCD_USB3) {
- dev_err(&dev->dev,
- "Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
- pci_name(dev));
- retval = -ENODEV;
- goto disable_pci;
+ if ((driver->flags & HCD_MASK) != HCD_USB3) {
+ if (!dev->irq) {
+ dev_err(&dev->dev,
+ "Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
+ pci_name(dev));
+ retval = -ENODEV;
+ goto disable_pci;
+ }
+ hcd_irq = dev->irq;
}

hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev));
@@ -245,7 +250,7 @@ int usb_hcd_pci_probe(struct pci_dev *de

pci_set_master(dev);

- retval = usb_add_hcd(hcd, dev->irq, IRQF_SHARED);
+ retval = usb_add_hcd(hcd, hcd_irq, IRQF_SHARED);
if (retval != 0)
goto unmap_registers;
set_hs_companion(dev, hcd);
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -342,7 +342,7 @@ static int xhci_try_enable_msi(struct us
* generate interrupts. Don't even try to enable MSI.
*/
if (xhci->quirks & XHCI_BROKEN_MSI)
- return 0;
+ goto legacy_irq;

/* unregister the legacy interrupt */
if (hcd->irq)
@@ -363,6 +363,7 @@ static int xhci_try_enable_msi(struct us
return -EINVAL;
}

+ legacy_irq:
/* fall back to legacy interrupt*/
ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED,
hcd->irq_descr, hcd);

2013-03-25 01:29:05

by Ben Hutchings

[permalink] [raw]
Subject: [ 070/104] ext4: fix data=journal fast mount/umount hang

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

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

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

commit 2b405bfa84063bfa35621d2d6879f52693c614b0 upstream.

In data=journal mode, if we unmount the file system before a
transaction has a chance to complete, when the journal inode is being
evicted, we can end up calling into jbd2_log_wait_commit() for the
last transaction, after the journalling machinery has been shut down.

Arguably we should adjust ext4_should_journal_data() to return FALSE
for the journal inode, but the only place it matters is
ext4_evict_inode(), and so to save a bit of CPU time, and to make the
patch much more obviously correct by inspection(tm), we'll fix it by
explicitly not trying to waiting for a journal commit when we are
evicting the journal inode, since it's guaranteed to never succeed in
this case.

This can be easily replicated via:

mount -t ext4 -o data=journal /dev/vdb /vdb ; umount /vdb

------------[ cut here ]------------
WARNING: at /usr/projects/linux/ext4/fs/jbd2/journal.c:542 __jbd2_log_start_commit+0xba/0xcd()
Hardware name: Bochs
JBD2: bad log_start_commit: 3005630206 3005630206 0 0
Modules linked in:
Pid: 2909, comm: umount Not tainted 3.8.0-rc3 #1020
Call Trace:
[<c015c0ef>] warn_slowpath_common+0x68/0x7d
[<c02b7e7d>] ? __jbd2_log_start_commit+0xba/0xcd
[<c015c177>] warn_slowpath_fmt+0x2b/0x2f
[<c02b7e7d>] __jbd2_log_start_commit+0xba/0xcd
[<c02b8075>] jbd2_log_start_commit+0x24/0x34
[<c0279ed5>] ext4_evict_inode+0x71/0x2e3
[<c021f0ec>] evict+0x94/0x135
[<c021f9aa>] iput+0x10a/0x110
[<c02b7836>] jbd2_journal_destroy+0x190/0x1ce
[<c0175284>] ? bit_waitqueue+0x50/0x50
[<c028d23f>] ext4_put_super+0x52/0x294
[<c020efe3>] generic_shutdown_super+0x48/0xb4
[<c020f071>] kill_block_super+0x22/0x60
[<c020f3e0>] deactivate_locked_super+0x22/0x49
[<c020f5d6>] deactivate_super+0x30/0x33
[<c0222795>] mntput_no_expire+0x107/0x10c
[<c02233a7>] sys_umount+0x2cf/0x2e0
[<c02233ca>] sys_oldumount+0x12/0x14
[<c08096b8>] syscall_call+0x7/0xb
---[ end trace 6a954cc790501c1f ]---
jbd2_log_wait_commit: error: j_commit_request=-1289337090, tid=0

Signed-off-by: "Theodore Ts'o" <[email protected]>
Reviewed-by: Jan Kara <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/ext4/inode.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -142,7 +142,8 @@ void ext4_evict_inode(struct inode *inod
* don't use page cache.
*/
if (ext4_should_journal_data(inode) &&
- (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode))) {
+ (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode)) &&
+ inode->i_ino != EXT4_JOURNAL_INO) {
journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
tid_t commit_tid = EXT4_I(inode)->i_datasync_tid;


2013-03-25 01:15:58

by Ben Hutchings

[permalink] [raw]
Subject: [ 077/104] efi_pstore: Introducing workqueue updating sysfs

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

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

From: Seiji Aguchi <[email protected]>

commit a93bc0c6e07ed9bac44700280e65e2945d864fd4 upstream.

[Problem]
efi_pstore creates sysfs entries, which enable users to access to NVRAM,
in a write callback. If a kernel panic happens in an interrupt context,
it may fail because it could sleep due to dynamic memory allocations during
creating sysfs entries.

[Patch Description]
This patch removes sysfs operations from a write callback by introducing
a workqueue updating sysfs entries which is scheduled after the write
callback is called.

Also, the workqueue is kicked in a just oops case.
A system will go down in other cases such as panic, clean shutdown and emergency
restart. And we don't need to create sysfs entries because there is no chance for
users to access to them.

efi_pstore will be robust against a kernel panic in an interrupt context with this patch.

Signed-off-by: Seiji Aguchi <[email protected]>
Acked-by: Matt Fleming <[email protected]>
Signed-off-by: Tony Luck <[email protected]>
[bwh: Backported to 3.2:
- Adjust contest
- Don't check reason in efi_pstore_write(), as it is not given as a
parameter
- Move up declaration of __efivars]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -127,6 +127,8 @@ struct efivar_attribute {
ssize_t (*store)(struct efivar_entry *entry, const char *buf, size_t count);
};

+static struct efivars __efivars;
+
#define PSTORE_EFI_ATTRIBUTES \
(EFI_VARIABLE_NON_VOLATILE | \
EFI_VARIABLE_BOOTSERVICE_ACCESS | \
@@ -151,6 +153,13 @@ efivar_create_sysfs_entry(struct efivars
efi_char16_t *variable_name,
efi_guid_t *vendor_guid);

+/*
+ * Prototype for workqueue functions updating sysfs entry
+ */
+
+static void efivar_update_sysfs_entries(struct work_struct *);
+static DECLARE_WORK(efivar_work, efivar_update_sysfs_entries);
+
/* Return the number of unicode characters in data */
static unsigned long
utf16_strnlen(efi_char16_t *s, size_t maxlength)
@@ -833,11 +842,7 @@ static int efi_pstore_write(enum pstore_
if (found)
efivar_unregister(found);

- if (size)
- ret = efivar_create_sysfs_entry(efivars,
- utf16_strsize(efi_name,
- DUMP_NAME_LEN * 2),
- efi_name, &vendor);
+ schedule_work(&efivar_work);

*id = part;
return ret;
@@ -1016,6 +1021,75 @@ static ssize_t efivar_delete(struct file
return count;
}

+static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor)
+{
+ struct efivar_entry *entry, *n;
+ struct efivars *efivars = &__efivars;
+ unsigned long strsize1, strsize2;
+ bool found = false;
+
+ strsize1 = utf16_strsize(variable_name, 1024);
+ list_for_each_entry_safe(entry, n, &efivars->list, list) {
+ strsize2 = utf16_strsize(entry->var.VariableName, 1024);
+ if (strsize1 == strsize2 &&
+ !memcmp(variable_name, &(entry->var.VariableName),
+ strsize2) &&
+ !efi_guidcmp(entry->var.VendorGuid,
+ *vendor)) {
+ found = true;
+ break;
+ }
+ }
+ return found;
+}
+
+static void efivar_update_sysfs_entries(struct work_struct *work)
+{
+ struct efivars *efivars = &__efivars;
+ efi_guid_t vendor;
+ efi_char16_t *variable_name;
+ unsigned long variable_name_size = 1024;
+ efi_status_t status = EFI_NOT_FOUND;
+ bool found;
+
+ /* Add new sysfs entries */
+ while (1) {
+ variable_name = kzalloc(variable_name_size, GFP_KERNEL);
+ if (!variable_name) {
+ pr_err("efivars: Memory allocation failed.\n");
+ return;
+ }
+
+ spin_lock_irq(&efivars->lock);
+ found = false;
+ while (1) {
+ variable_name_size = 1024;
+ status = efivars->ops->get_next_variable(
+ &variable_name_size,
+ variable_name,
+ &vendor);
+ if (status != EFI_SUCCESS) {
+ break;
+ } else {
+ if (!variable_is_present(variable_name,
+ &vendor)) {
+ found = true;
+ break;
+ }
+ }
+ }
+ spin_unlock_irq(&efivars->lock);
+
+ if (!found) {
+ kfree(variable_name);
+ break;
+ } else
+ efivar_create_sysfs_entry(efivars,
+ variable_name_size,
+ variable_name, &vendor);
+ }
+}
+
/*
* Let's not leave out systab information that snuck into
* the efivars driver
@@ -1272,7 +1346,6 @@ out:
}
EXPORT_SYMBOL_GPL(register_efivars);

-static struct efivars __efivars;
static struct efivar_operations ops;

/*
@@ -1330,6 +1403,8 @@ err_put:
static void __exit
efivars_exit(void)
{
+ cancel_work_sync(&efivar_work);
+
if (efi_enabled(EFI_RUNTIME_SERVICES)) {
unregister_efivars(&__efivars);
kobject_put(efi_kobj);
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -484,7 +484,8 @@ struct efivars {
* 1) ->list - adds, removals, reads, writes
* 2) ops.[gs]et_variable() calls.
* It must not be held when creating sysfs entries or calling kmalloc.
- * ops.get_next_variable() is only called from register_efivars(),
+ * ops.get_next_variable() is only called from register_efivars()
+ * or efivar_update_sysfs_entries(),
* which is protected by the BKL, so that path is safe.
*/
spinlock_t lock;

2013-03-25 01:29:32

by Ben Hutchings

[permalink] [raw]
Subject: [ 079/104] efivars: Handle duplicate names from get_next_variable()

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

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

From: Matt Fleming <[email protected]>

commit e971318bbed610e28bb3fde9d548e6aaf0a6b02e upstream.

Some firmware exhibits a bug where the same VariableName and
VendorGuid values are returned on multiple invocations of
GetNextVariableName(). See,

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

As a consequence of such a bug, Andre reports hitting the following
WARN_ON() in the sysfs code after updating the BIOS on his, "Gigabyte
Technology Co., Ltd. To be filled by O.E.M./Z77X-UD3H, BIOS F19e
11/21/2012)" machine,

[ 0.581554] EFI Variables Facility v0.08 2004-May-17
[ 0.584914] ------------[ cut here ]------------
[ 0.585639] WARNING: at /home/andre/linux/fs/sysfs/dir.c:536 sysfs_add_one+0xd4/0x100()
[ 0.586381] Hardware name: To be filled by O.E.M.
[ 0.587123] sysfs: cannot create duplicate filename '/firmware/efi/vars/SbAslBufferPtrVar-01f33c25-764d-43ea-aeea-6b5a41f3f3e8'
[ 0.588694] Modules linked in:
[ 0.589484] Pid: 1, comm: swapper/0 Not tainted 3.8.0+ #7
[ 0.590280] Call Trace:
[ 0.591066] [<ffffffff81208954>] ? sysfs_add_one+0xd4/0x100
[ 0.591861] [<ffffffff810587bf>] warn_slowpath_common+0x7f/0xc0
[ 0.592650] [<ffffffff810588bc>] warn_slowpath_fmt+0x4c/0x50
[ 0.593429] [<ffffffff8134dd85>] ? strlcat+0x65/0x80
[ 0.594203] [<ffffffff81208954>] sysfs_add_one+0xd4/0x100
[ 0.594979] [<ffffffff81208b78>] create_dir+0x78/0xd0
[ 0.595753] [<ffffffff81208ec6>] sysfs_create_dir+0x86/0xe0
[ 0.596532] [<ffffffff81347e4c>] kobject_add_internal+0x9c/0x220
[ 0.597310] [<ffffffff81348307>] kobject_init_and_add+0x67/0x90
[ 0.598083] [<ffffffff81584a71>] ? efivar_create_sysfs_entry+0x61/0x1c0
[ 0.598859] [<ffffffff81584b2b>] efivar_create_sysfs_entry+0x11b/0x1c0
[ 0.599631] [<ffffffff8158517e>] register_efivars+0xde/0x420
[ 0.600395] [<ffffffff81d430a7>] ? edd_init+0x2f5/0x2f5
[ 0.601150] [<ffffffff81d4315f>] efivars_init+0xb8/0x104
[ 0.601903] [<ffffffff8100215a>] do_one_initcall+0x12a/0x180
[ 0.602659] [<ffffffff81d05d80>] kernel_init_freeable+0x13e/0x1c6
[ 0.603418] [<ffffffff81d05586>] ? loglevel+0x31/0x31
[ 0.604183] [<ffffffff816a6530>] ? rest_init+0x80/0x80
[ 0.604936] [<ffffffff816a653e>] kernel_init+0xe/0xf0
[ 0.605681] [<ffffffff816ce7ec>] ret_from_fork+0x7c/0xb0
[ 0.606414] [<ffffffff816a6530>] ? rest_init+0x80/0x80
[ 0.607143] ---[ end trace 1609741ab737eb29 ]---

There's not much we can do to work around and keep traversing the
variable list once we hit this firmware bug. Our only solution is to
terminate the loop because, as Lingzhu reports, some machines get
stuck when they encounter duplicate names,

> I had an IBM System x3100 M4 and x3850 X5 on which kernel would
> get stuck in infinite loop creating duplicate sysfs files because,
> for some reason, there are several duplicate boot entries in nvram
> getting GetNextVariableName into a circle of iteration (with
> period > 2).

Also disable the workqueue, as efivar_update_sysfs_entries() uses
GetNextVariableName() to figure out which variables have been created
since the last iteration. That algorithm isn't going to work if
GetNextVariableName() returns duplicates. Note that we don't disable
EFI variable creation completely on the affected machines, it's just
that any pstore dump-* files won't appear in sysfs until the next
boot.

Reported-by: Andre Heider <[email protected]>
Reported-by: Lingzhu Xiang <[email protected]>
Tested-by: Lingzhu Xiang <[email protected]>
Cc: Seiji Aguchi <[email protected]>
Signed-off-by: Matt Fleming <[email protected]>
[bwh: Backported to 3.2: reason is not checked in efi_pstore_write()]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -159,6 +159,7 @@ efivar_create_sysfs_entry(struct efivars

static void efivar_update_sysfs_entries(struct work_struct *);
static DECLARE_WORK(efivar_work, efivar_update_sysfs_entries);
+static bool efivar_wq_enabled = true;

/* Return the number of unicode characters in data */
static unsigned long
@@ -842,7 +843,8 @@ static int efi_pstore_write(enum pstore_
if (found)
efivar_unregister(found);

- schedule_work(&efivar_work);
+ if (efivar_wq_enabled)
+ schedule_work(&efivar_work);

*id = part;
return ret;
@@ -1305,6 +1307,35 @@ void unregister_efivars(struct efivars *
}
EXPORT_SYMBOL_GPL(unregister_efivars);

+/*
+ * Print a warning when duplicate EFI variables are encountered and
+ * disable the sysfs workqueue since the firmware is buggy.
+ */
+static void dup_variable_bug(efi_char16_t *s16, efi_guid_t *vendor_guid,
+ unsigned long len16)
+{
+ size_t i, len8 = len16 / sizeof(efi_char16_t);
+ char *s8;
+
+ /*
+ * Disable the workqueue since the algorithm it uses for
+ * detecting new variables won't work with this buggy
+ * implementation of GetNextVariableName().
+ */
+ efivar_wq_enabled = false;
+
+ s8 = kzalloc(len8, GFP_KERNEL);
+ if (!s8)
+ return;
+
+ for (i = 0; i < len8; i++)
+ s8[i] = s16[i];
+
+ printk(KERN_WARNING "efivars: duplicate variable: %s-%pUl\n",
+ s8, vendor_guid);
+ kfree(s8);
+}
+
int register_efivars(struct efivars *efivars,
const struct efivar_operations *ops,
struct kobject *parent_kobj)
@@ -1347,6 +1378,22 @@ int register_efivars(struct efivars *efi
case EFI_SUCCESS:
variable_name_size = var_name_strnsize(variable_name,
variable_name_size);
+
+ /*
+ * Some firmware implementations return the
+ * same variable name on multiple calls to
+ * get_next_variable(). Terminate the loop
+ * immediately as there is no guarantee that
+ * we'll ever see a different variable name,
+ * and may end up looping here forever.
+ */
+ if (variable_is_present(variable_name, &vendor_guid)) {
+ dup_variable_bug(variable_name, &vendor_guid,
+ variable_name_size);
+ status = EFI_NOT_FOUND;
+ break;
+ }
+
efivar_create_sysfs_entry(efivars,
variable_name_size,
variable_name,

2013-03-25 01:29:48

by Ben Hutchings

[permalink] [raw]
Subject: [ 067/104] x86-64: Fix the failure case in copy_user_handle_tail()

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

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

From: CQ Tang <[email protected]>

commit 66db3feb486c01349f767b98ebb10b0c3d2d021b upstream.

The increment of "to" in copy_user_handle_tail() will have incremented
before a failure has been noted. This causes us to skip a byte in the
failure case.

Only do the increment when assured there is no failure.

Signed-off-by: CQ Tang <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Mike Marciniszyn <[email protected]>
Signed-off-by: H. Peter Anvin <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/x86/lib/usercopy_64.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--- a/arch/x86/lib/usercopy_64.c
+++ b/arch/x86/lib/usercopy_64.c
@@ -169,10 +169,10 @@ copy_user_handle_tail(char *to, char *fr
char c;
unsigned zero_len;

- for (; len; --len) {
+ for (; len; --len, to++) {
if (__get_user_nocheck(c, from++, sizeof(char)))
break;
- if (__put_user_nocheck(c, to++, sizeof(char)))
+ if (__put_user_nocheck(c, to, sizeof(char)))
break;
}


2013-03-25 01:29:47

by Ben Hutchings

[permalink] [raw]
Subject: [ 075/104] efivars: Add module parameter to disable use as a pstore backend

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

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

From: Seth Forshee <[email protected]>

commit ec0971ba5372a4dfa753f232449d23a8fd98490e upstream.

We know that with some firmware implementations writing too much data to
UEFI variables can lead to bricking machines. Recent changes attempt to
address this issue, but for some it may still be prudent to avoid
writing large amounts of data until the solution has been proven on a
wide variety of hardware.

Crash dumps or other data from pstore can potentially be a large data
source. Add a pstore_module parameter to efivars to allow disabling its
use as a backend for pstore. Also add a config option,
CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE, to allow setting the default
value of this paramter to true (i.e. disabled by default).

Signed-off-by: Seth Forshee <[email protected]>
Cc: Josh Boyer <[email protected]>
Cc: Matthew Garrett <[email protected]>
Cc: Seiji Aguchi <[email protected]>
Cc: Tony Luck <[email protected]>
Signed-off-by: Matt Fleming <[email protected]>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -62,6 +62,15 @@ config EFI_VARS_PSTORE
will allow writing console messages, crash dumps, or anything
else supported by pstore to EFI variables.

+config EFI_VARS_PSTORE_DEFAULT_DISABLE
+ bool "Disable using efivars as a pstore backend by default"
+ depends on EFI_VARS_PSTORE
+ default n
+ help
+ Saying Y here will disable the use of efivars as a storage
+ backend for pstore by default. This setting can be overridden
+ using the efivars module's pstore_disable parameter.
+
config EFI_PCDP
bool "Console device selection via EFI PCDP or HCDP table"
depends on ACPI && EFI && IA64
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -92,6 +92,11 @@ MODULE_VERSION(EFIVARS_VERSION);

#define DUMP_NAME_LEN 52

+static bool efivars_pstore_disable =
+ IS_ENABLED(EFI_VARS_PSTORE_DEFAULT_DISABLE);
+
+module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644);
+
/*
* The maximum size of VariableName + Data = 1024
* Therefore, it's reasonable to save that much
@@ -1257,7 +1262,8 @@ int register_efivars(struct efivars *efi
if (error)
unregister_efivars(efivars);

- efivar_pstore_register(efivars);
+ if (!efivars_pstore_disable)
+ efivar_pstore_register(efivars);

out:
kfree(variable_name);

2013-03-25 01:30:21

by Ben Hutchings

[permalink] [raw]
Subject: [ 072/104] usb: gadget: udc-core: fix a regression during gadget driver

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

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

From: Alan Stern <[email protected]>

commit 511f3c5326eabe1ece35202a404c24c0aeacc246 upstream.

This patch (as1666) fixes a regression in the UDC core. The core
takes care of unbinding gadget drivers, and it does the unbinding
before telling the UDC driver to turn off the controller hardware.
When the call to the udc_stop callback is made, the gadget no longer
has a driver. The callback routine should not be invoked with a
pointer to the old driver; doing so can cause problems (such as
use-after-free accesses in net2280).

This patch should be applied, with appropriate context changes, to all
the stable kernels going back to 3.1.

Signed-off-by: Alan Stern <[email protected]>
Signed-off-by: Felipe Balbi <[email protected]>
[bwh: Backported to 3.2: adjust context, indentation]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/gadget/udc-core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/usb/gadget/udc-core.c
+++ b/drivers/usb/gadget/udc-core.c
@@ -213,7 +213,7 @@ static void usb_gadget_remove_driver(str
udc->driver->disconnect(udc->gadget);
usb_gadget_disconnect(udc->gadget);
udc->driver->unbind(udc->gadget);
- usb_gadget_udc_stop(udc->gadget, udc->driver);
+ usb_gadget_udc_stop(udc->gadget, NULL);
} else {
usb_gadget_stop(udc->gadget, udc->driver);
}

2013-03-25 01:15:56

by Ben Hutchings

[permalink] [raw]
Subject: [ 076/104] efivars: Fix check for CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE

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

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

From: Ben Hutchings <[email protected]>

commit ca0ba26fbbd2d81c43085df49ce0abfe34535a90 upstream.

The 'CONFIG_' prefix is not implicit in IS_ENABLED().

Signed-off-by: Ben Hutchings <[email protected]>
Cc: Seth Forshee <[email protected]>
Signed-off-by: Matt Fleming <[email protected]>
---
drivers/firmware/efivars.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -93,7 +93,7 @@ MODULE_VERSION(EFIVARS_VERSION);
#define DUMP_NAME_LEN 52

static bool efivars_pstore_disable =
- IS_ENABLED(EFI_VARS_PSTORE_DEFAULT_DISABLE);
+ IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE);

module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644);


2013-03-25 01:30:45

by Ben Hutchings

[permalink] [raw]
Subject: [ 081/104] USB: garmin_gps: fix memory leak on disconnect

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

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

From: Johan Hovold <[email protected]>

commit 618aa1068df29c37a58045fe940f9106664153fd upstream.

Remove bogus disconnect test introduced by 95bef012e ("USB: more serial
drivers writing after disconnect") which prevented queued data from
being freed on disconnect.

The possible IO it was supposed to prevent is long gone.

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/garmin_gps.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)

--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -973,10 +973,7 @@ static void garmin_close(struct usb_seri
if (!serial)
return;

- mutex_lock(&port->serial->disc_mutex);
-
- if (!port->serial->disconnected)
- garmin_clear(garmin_data_p);
+ garmin_clear(garmin_data_p);

/* shutdown our urbs */
usb_kill_urb(port->read_urb);
@@ -985,8 +982,6 @@ static void garmin_close(struct usb_seri
/* keep reset state so we know that we must start a new session */
if (garmin_data_p->state != STATE_RESET)
garmin_data_p->state = STATE_DISCONNECTED;
-
- mutex_unlock(&port->serial->disc_mutex);
}



2013-03-25 01:31:01

by Ben Hutchings

[permalink] [raw]
Subject: [ 066/104] USB: xhci - fix bit definitions for IMAN register

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

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

From: Dmitry Torokhov <[email protected]>

commit f8264340e694604863255cc0276491d17c402390 upstream.

According to XHCI specification (5.5.2.1) the IP is bit 0 and IE is bit 1
of IMAN register. Previously their definitions were reversed.

Even though there are no ill effects being observed from the swapped
definitions (because IMAN_IP is RW1C and in legacy PCI case we come in
with it already set to 1 so it was clearing itself even though we were
setting IMAN_IE instead of IMAN_IP), we should still correct the values.

This patch should be backported to kernels as old as 2.6.36, that
contain the commit 4e833c0b87a30798e67f06120cecebef6ee9644c "xhci: don't
re-enable IE constantly".

Signed-off-by: Dmitry Torokhov <[email protected]>
Signed-off-by: Sarah Sharp <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/usb/host/xhci.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -206,8 +206,8 @@ struct xhci_op_regs {
/* bits 12:31 are reserved (and should be preserved on writes). */

/* IMAN - Interrupt Management Register */
-#define IMAN_IP (1 << 1)
-#define IMAN_IE (1 << 0)
+#define IMAN_IE (1 << 1)
+#define IMAN_IP (1 << 0)

/* USBSTS - USB status - status bitmasks */
/* HC not running - set to 1 when run/stop bit is cleared. */

2013-03-25 01:31:20

by Ben Hutchings

[permalink] [raw]
Subject: [ 068/104] ALSA: snd-usb: mixer: propagate errors up the call chain

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

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

From: Daniel Mack <[email protected]>

commit 4d7b86c98e445b075c2c4c3757eb6d3d6efbe72e upstream.

In check_input_term() and parse_audio_feature_unit(), propagate the
error value that has been returned by a failing function instead of
-EINVAL. That helps cleaning up the error pathes in the mixer.

Signed-off-by: Daniel Mack <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
sound/usb/mixer.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -711,8 +711,9 @@ static int check_input_term(struct mixer
case UAC2_CLOCK_SELECTOR: {
struct uac_selector_unit_descriptor *d = p1;
/* call recursively to retrieve the channel info */
- if (check_input_term(state, d->baSourceID[0], term) < 0)
- return -ENODEV;
+ err = check_input_term(state, d->baSourceID[0], term);
+ if (err < 0)
+ return err;
term->type = d->bDescriptorSubtype << 16; /* virtual type */
term->id = id;
term->name = uac_selector_unit_iSelector(d);
@@ -1263,8 +1264,9 @@ static int parse_audio_feature_unit(stru
return err;

/* determine the input source type and name */
- if (check_input_term(state, hdr->bSourceID, &iterm) < 0)
- return -EINVAL;
+ err = check_input_term(state, hdr->bSourceID, &iterm);
+ if (err < 0)
+ return err;

master_bits = snd_usb_combine_bytes(bmaControls, csize);
/* master configuration quirks */

2013-03-25 01:31:37

by Ben Hutchings

[permalink] [raw]
Subject: [ 071/104] ALSA: hda - Fix typo in checking IEC958 emphasis bit

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

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

From: Takashi Iwai <[email protected]>

commit a686fd141e20244ad75f80ad54706da07d7bb90a upstream.

There is a typo in convert_to_spdif_status() about checking the
emphasis IEC958 status bit. It should check the given value instead
of the resultant value.

Reported-by: Martin Weishart <[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
@@ -2771,7 +2771,7 @@ static unsigned int convert_to_spdif_sta
if (val & AC_DIG1_PROFESSIONAL)
sbits |= IEC958_AES0_PROFESSIONAL;
if (sbits & IEC958_AES0_PROFESSIONAL) {
- if (sbits & AC_DIG1_EMPHASIS)
+ if (val & AC_DIG1_EMPHASIS)
sbits |= IEC958_AES0_PRO_EMPHASIS_5015;
} else {
if (val & AC_DIG1_EMPHASIS)

2013-03-25 01:31:52

by Ben Hutchings

[permalink] [raw]
Subject: [ 069/104] ALSA: snd-usb: mixer: ignore -EINVAL in snd_usb_mixer_controls()

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

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

From: Daniel Mack <[email protected]>

commit 83ea5d18d74f032a760fecde78c0210f66f7f70c upstream.

Creation of individual mixer controls may fail, but that shouldn't cause
the entire mixer creation to fail. Even worse, if the mixer creation
fails, that will error out the entire device probing.

All the functions called by parse_audio_unit() should return -EINVAL if
they find descriptors that are unsupported or believed to be malformed,
so we can safely handle this error code as a non-fatal condition in
snd_usb_mixer_controls().

That fixes a long standing bug which is commonly worked around by
adding quirks which make the driver ignore entire interfaces. Some of
them might now be unnecessary.

Signed-off-by: Daniel Mack <[email protected]>
Reported-and-tested-by: Rodolfo Thomazelli <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
sound/usb/mixer.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -2020,7 +2020,7 @@ static int snd_usb_mixer_controls(struct
state.oterm.type = le16_to_cpu(desc->wTerminalType);
state.oterm.name = desc->iTerminal;
err = parse_audio_unit(&state, desc->bSourceID);
- if (err < 0)
+ if (err < 0 && err != -EINVAL)
return err;
} else { /* UAC_VERSION_2 */
struct uac2_output_terminal_descriptor *desc = p;
@@ -2032,12 +2032,12 @@ static int snd_usb_mixer_controls(struct
state.oterm.type = le16_to_cpu(desc->wTerminalType);
state.oterm.name = desc->iTerminal;
err = parse_audio_unit(&state, desc->bSourceID);
- if (err < 0)
+ if (err < 0 && err != -EINVAL)
return err;

/* for UAC2, use the same approach to also add the clock selectors */
err = parse_audio_unit(&state, desc->bCSourceID);
- if (err < 0)
+ if (err < 0 && err != -EINVAL)
return err;
}
}

2013-03-25 01:32:34

by Ben Hutchings

[permalink] [raw]
Subject: [ 080/104] cifs: ignore everything in SPNEGO blob after mechTypes

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

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

From: Jeff Layton <[email protected]>

commit f853c616883a8de966873a1dab283f1369e275a1 upstream.

We've had several reports of people attempting to mount Windows 8 shares
and getting failures with a return code of -EINVAL. The default sec=
mode changed recently to sec=ntlmssp. With that, we expect and parse a
SPNEGO blob from the server in the NEGOTIATE reply.

The current decode_negTokenInit function first parses all of the
mechTypes and then tries to parse the rest of the negTokenInit reply.
The parser however currently expects a mechListMIC or nothing to follow the
mechTypes, but Windows 8 puts a mechToken field there instead to carry
some info for the new NegoEx stuff.

In practice, we don't do anything with the fields after the mechTypes
anyway so I don't see any real benefit in continuing to parse them.
This patch just has the kernel ignore the fields after the mechTypes.
We'll probably need to reinstate some of this if we ever want to support
NegoEx.

Reported-by: Jason Burgess <[email protected]>
Reported-by: Yan Li <[email protected]>
Signed-off-by: Jeff Layton <[email protected]>
Signed-off-by: Steve French <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/cifs/asn1.c | 53 +++++------------------------------------------------
1 file changed, 5 insertions(+), 48 deletions(-)

--- a/fs/cifs/asn1.c
+++ b/fs/cifs/asn1.c
@@ -614,53 +614,10 @@ decode_negTokenInit(unsigned char *secur
}
}

- /* mechlistMIC */
- if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
- /* Check if we have reached the end of the blob, but with
- no mechListMic (e.g. NTLMSSP instead of KRB5) */
- if (ctx.error == ASN1_ERR_DEC_EMPTY)
- goto decode_negtoken_exit;
- cFYI(1, "Error decoding last part negTokenInit exit3");
- return 0;
- } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
- /* tag = 3 indicating mechListMIC */
- cFYI(1, "Exit 4 cls = %d con = %d tag = %d end = %p (%d)",
- cls, con, tag, end, *end);
- return 0;
- }
-
- /* sequence */
- if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
- cFYI(1, "Error decoding last part negTokenInit exit5");
- return 0;
- } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
- || (tag != ASN1_SEQ)) {
- cFYI(1, "cls = %d con = %d tag = %d end = %p (%d)",
- cls, con, tag, end, *end);
- }
-
- /* sequence of */
- if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
- cFYI(1, "Error decoding last part negTokenInit exit 7");
- return 0;
- } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
- cFYI(1, "Exit 8 cls = %d con = %d tag = %d end = %p (%d)",
- cls, con, tag, end, *end);
- return 0;
- }
-
- /* general string */
- if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
- cFYI(1, "Error decoding last part negTokenInit exit9");
- return 0;
- } else if ((cls != ASN1_UNI) || (con != ASN1_PRI)
- || (tag != ASN1_GENSTR)) {
- cFYI(1, "Exit10 cls = %d con = %d tag = %d end = %p (%d)",
- cls, con, tag, end, *end);
- return 0;
- }
- cFYI(1, "Need to call asn1_octets_decode() function for %s",
- ctx.pointer); /* is this UTF-8 or ASCII? */
-decode_negtoken_exit:
+ /*
+ * We currently ignore anything at the end of the SPNEGO blob after
+ * the mechTypes have been parsed, since none of that info is
+ * used at the moment.
+ */
return 1;
}

2013-03-25 01:32:53

by Ben Hutchings

[permalink] [raw]
Subject: [ 082/104] USB: io_ti: fix get_icount for two port adapters

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

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

From: Johan Hovold <[email protected]>

commit 5492bf3d5655b4954164f69c02955a7fca267611 upstream.

Add missing get_icount field to two-port driver.

The two-port driver was not updated when switching to the new icount
interface in commit 0bca1b913aff ("tty: Convert the USB drivers to the
new icount interface").

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 | 1 +
1 file changed, 1 insertion(+)

--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -2796,6 +2796,7 @@ static struct usb_serial_driver edgeport
.set_termios = edge_set_termios,
.tiocmget = edge_tiocmget,
.tiocmset = edge_tiocmset,
+ .get_icount = edge_get_icount,
.write = edge_write,
.write_room = edge_write_room,
.chars_in_buffer = edge_chars_in_buffer,

2013-03-25 01:15:38

by Ben Hutchings

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

3.2-stable 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
@@ -1707,10 +1705,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);
@@ -1868,8 +1864,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);

@@ -2024,7 +2019,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;
}

@@ -2423,11 +2418,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)) ||
@@ -2437,8 +2436,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-03-25 01:33:10

by Ben Hutchings

[permalink] [raw]
Subject: [ 083/104] USB: serial: fix interface refcounting

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

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

From: Johan Hovold <[email protected]>

commit d7971051e4df825e0bc11b995e87bfe86355b8e5 upstream.

Make sure the interface is not released before our serial device.

Note that drivers are still not allowed to access the interface in
any way that may interfere with another driver that may have gotten
bound to the same interface after disconnect returns.

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/usb-serial.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -168,6 +168,7 @@ static void destroy_serial(struct kref *
}
}

+ usb_put_intf(serial->interface);
usb_put_dev(serial->dev);
kfree(serial);
}
@@ -624,7 +625,7 @@ static struct usb_serial *create_serial(
}
serial->dev = usb_get_dev(dev);
serial->type = driver;
- serial->interface = interface;
+ serial->interface = usb_get_intf(interface);
kref_init(&serial->kref);
mutex_init(&serial->disc_mutex);
serial->minor = SERIAL_TTY_NO_MINOR;

2013-03-25 01:15:36

by Ben Hutchings

[permalink] [raw]
Subject: [ 099/104] i2c: tegra: check the clk_prepare_enable() return value

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

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

From: Laxman Dewangan <[email protected]>

commit 132c803f7b70b17322579f6f4f3f65cf68e55135 upstream.

NVIDIA's Tegra SoC allows read/write of controller register only
if controller clock is enabled. System hangs if read/write happens
to registers without enabling clock.

clk_prepare_enable() can be fail due to unknown reason and hence
adding check for return value of this function. If this function
success then only access register otherwise return to caller with
error.

Signed-off-by: Laxman Dewangan <[email protected]>
Reviewed-by: Stephen Warren <[email protected]>
Signed-off-by: Wolfram Sang <[email protected]>
[bwh: Backported to 3.2:
- Adjust context
- Keep calling clk_enable() directly]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/i2c/busses/i2c-tegra.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)

--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -341,7 +341,11 @@ static int tegra_i2c_init(struct tegra_i
u32 val;
int err = 0;

- clk_enable(i2c_dev->clk);
+ err = clk_enable(i2c_dev->clk);
+ if (err < 0) {
+ dev_err(i2c_dev->dev, "Clock enable failed %d\n", err);
+ return err;
+ }

tegra_periph_reset_assert(i2c_dev->clk);
udelay(2);
@@ -536,7 +540,12 @@ static int tegra_i2c_xfer(struct i2c_ada
if (i2c_dev->is_suspended)
return -EBUSY;

- clk_enable(i2c_dev->clk);
+ ret = clk_enable(i2c_dev->clk);
+ if (ret < 0) {
+ dev_err(i2c_dev->dev, "Clock enable failed %d\n", ret);
+ return ret;
+ }
+
for (i = 0; i < num; i++) {
int stop = (i == (num - 1)) ? 1 : 0;
ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], stop);

2013-03-25 01:15:33

by Ben Hutchings

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

3.2-stable 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-03-25 01:15:31

by Ben Hutchings

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

3.2-stable 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-03-25 01:15:29

by Ben Hutchings

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

3.2-stable 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-03-25 01:34:31

by Ben Hutchings

[permalink] [raw]
Subject: [ 101/104] mm/hugetlb: fix total hugetlbfs pages count when using memory

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

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

From: Wanpeng Li <[email protected]>

commit d00285884c0892bb1310df96bce6056e9ce9b9d9 upstream.

hugetlb_total_pages is used for overcommit calculations but the current
implementation considers only the default hugetlb page size (which is
either the first defined hugepage size or the one specified by
default_hugepagesz kernel boot parameter).

If the system is configured for more than one hugepage size, which is
possible since commit a137e1cc6d6e ("hugetlbfs: per mount huge page
sizes") then the overcommit estimation done by __vm_enough_memory()
(resp. shown by meminfo_proc_show) is not precise - there is an
impression of more available/allowed memory. This can lead to an
unexpected ENOMEM/EFAULT resp. SIGSEGV when memory is accounted.

Testcase:
boot: hugepagesz=1G hugepages=1
the default overcommit ratio is 50
before patch:

egrep 'CommitLimit' /proc/meminfo
CommitLimit: 55434168 kB

after patch:

egrep 'CommitLimit' /proc/meminfo
CommitLimit: 54909880 kB

[[email protected]: coding-style tweak]
Signed-off-by: Wanpeng Li <[email protected]>
Acked-by: Michal Hocko <[email protected]>
Cc: "Aneesh Kumar K.V" <[email protected]>
Cc: Hillf Danton <[email protected]>
Cc: KAMEZAWA Hiroyuki <[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 | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2092,8 +2092,12 @@ int hugetlb_report_node_meminfo(int nid,
/* Return the number pages of memory we physically have, in PAGE_SIZE units. */
unsigned long hugetlb_total_pages(void)
{
- struct hstate *h = &default_hstate;
- return h->nr_huge_pages * pages_per_huge_page(h);
+ struct hstate *h;
+ unsigned long nr_total_pages = 0;
+
+ for_each_hstate(h)
+ nr_total_pages += h->nr_huge_pages * pages_per_huge_page(h);
+ return nr_total_pages;
}

static int hugetlb_acct_memory(struct hstate *h, long delta)

2013-03-25 01:34:33

by Ben Hutchings

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

3.2-stable 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-03-25 01:34:32

by Ben Hutchings

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

3.2-stable 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-03-25 01:35:26

by Ben Hutchings

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

3.2-stable 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-03-25 01:35:24

by Ben Hutchings

[permalink] [raw]
Subject: [ 092/104] USB: mos7840: fix broken TIOCMIWAIT

3.2-stable 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-03-25 01:36:05

by Ben Hutchings

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

3.2-stable 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-03-25 01:36:24

by Ben Hutchings

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

3.2-stable 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-03-25 01:36:43

by Ben Hutchings

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

3.2-stable 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-03-25 01:36:41

by Ben Hutchings

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

3.2-stable 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-03-25 01:36:40

by Ben Hutchings

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

3.2-stable 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-03-25 01:37:41

by Ben Hutchings

[permalink] [raw]
Subject: [ 103/104] KMS: fix EDID detailed timing frame rate

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

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

From: Torsten Duwe <[email protected]>

commit c19b3b0f6eed552952845e4ad908dba2113d67b4 upstream.

When KMS has parsed an EDID "detailed timing", it leaves the frame rate
zeroed. Consecutive (debug-) output of that mode thus yields 0 for
vsync. This simple fix also speeds up future invocations of
drm_mode_vrefresh().

While it is debatable whether this qualifies as a -stable fix I'd apply
it for consistency's sake; drm_helper_probe_single_connector_modes()
does the same thing already for all probed modes.

Signed-off-by: Torsten Duwe <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/drm_edid.c | 1 +
1 file changed, 1 insertion(+)

--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -933,6 +933,7 @@ set_size:
}

mode->type = DRM_MODE_TYPE_DRIVER;
+ mode->vrefresh = drm_mode_vrefresh(mode);
drm_mode_set_name(mode);

return mode;

2013-03-25 01:37:40

by Ben Hutchings

[permalink] [raw]
Subject: [ 102/104] KMS: fix EDID detailed timing vsync parsing

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

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

From: Torsten Duwe <[email protected]>

commit 16dad1d743d31a104a849c8944e6b9eb479f6cd7 upstream.

EDID spreads some values across multiple bytes; bit-fiddling is needed
to retrieve these. The current code to parse "detailed timings" has a
cut&paste error that results in a vsync offset of at most 15 lines
instead of 63.

See

http://en.wikipedia.org/wiki/EDID

and in the "EDID Detailed Timing Descriptor" see bytes 10+11 show why
that needs to be a left shift.

Signed-off-by: Torsten Duwe <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/drm_edid.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -852,7 +852,7 @@ static struct drm_display_mode *drm_mode
unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo;
unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2 | pt->hsync_offset_lo;
unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) << 4 | pt->hsync_pulse_width_lo;
- unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) >> 2 | pt->vsync_offset_pulse_width_lo >> 4;
+ unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) << 2 | pt->vsync_offset_pulse_width_lo >> 4;
unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 4 | (pt->vsync_offset_pulse_width_lo & 0xf);

/* ignore tiny modes */

2013-03-25 01:38:13

by Ben Hutchings

[permalink] [raw]
Subject: [ 100/104] vfs,proc: guarantee unique inodes in /proc

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

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

From: Linus Torvalds <[email protected]>

commit 51f0885e5415b4cc6535e9cdcc5145bfbc134353 upstream.

Dave Jones found another /proc issue with his Trinity tool: thanks to
the namespace model, we can have multiple /proc dentries that point to
the same inode, aliasing directories in /proc/<pid>/net/ for example.

This ends up being a total disaster, because it acts like hardlinked
directories, and causes locking problems. We rely on the topological
sort of the inodes pointed to by dentries, and if we have aliased
directories, that odering becomes unreliable.

In short: don't do this. Multiple dentries with the same (directory)
inode is just a bad idea, and the namespace code should never have
exposed things this way. But we're kind of stuck with it.

This solves things by just always allocating a new inode during /proc
dentry lookup, instead of using "iget_locked()" to look up existing
inodes by superblock and number. That actually simplies the code a bit,
at the cost of potentially doing more inode [de]allocations.

That said, the inode lookup wasn't free either (and did a lot of locking
of inodes), so it is probably not that noticeable. We could easily keep
the old lookup model for non-directory entries, but rather than try to
be excessively clever this just implements the minimal and simplest
workaround for the problem.

Reported-and-tested-by: Dave Jones <[email protected]>
Analyzed-by: Al Viro <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
[bwh: Backported to 3.2:
- Adjust context
- Never drop the pde reference in proc_get_inode(), as callers only
expect this when we return an existing inode, and we never do that now]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -427,12 +427,10 @@ static const struct file_operations proc

struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
{
- struct inode * inode;
+ struct inode *inode = new_inode_pseudo(sb);

- inode = iget_locked(sb, de->low_ino);
- if (!inode)
- return NULL;
- if (inode->i_state & I_NEW) {
+ if (inode) {
+ inode->i_ino = de->low_ino;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
PROC_I(inode)->fd = 0;
PROC_I(inode)->pde = de;
@@ -461,9 +459,7 @@ struct inode *proc_get_inode(struct supe
inode->i_fop = de->proc_fops;
}
}
- unlock_new_inode(inode);
- } else
- pde_put(de);
+ }
return inode;
}


2013-03-25 01:15:08

by Ben Hutchings

[permalink] [raw]
Subject: [ 013/104] ipv6: stop multicast forwarding to process interface scoped addresses

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

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

From: Hannes Frederic Sowa <[email protected]>

[ Upstream commit ddf64354af4a702ee0b85d0a285ba74c7278a460 ]

v2:
a) used struct ipv6_addr_props

v3:
a) reverted changes for ipv6_addr_props

v4:
a) do not use __ipv6_addr_needs_scope_id

Cc: YOSHIFUJI Hideaki <[email protected]>
Signed-off-by: Hannes Frederic Sowa <[email protected]>
Acked-by: YOSHIFUJI Hideaki <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/ipv6/ip6_input.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -265,7 +265,8 @@ int ip6_mc_input(struct sk_buff *skb)
* IPv6 multicast router mode is now supported ;)
*/
if (dev_net(skb->dev)->ipv6.devconf_all->mc_forwarding &&
- !(ipv6_addr_type(&hdr->daddr) & IPV6_ADDR_LINKLOCAL) &&
+ !(ipv6_addr_type(&hdr->daddr) &
+ (IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL)) &&
likely(!(IP6CB(skb)->flags & IP6SKB_FORWARDED))) {
/*
* Okay, we try to forward - split and duplicate

2013-03-25 01:15:06

by Ben Hutchings

[permalink] [raw]
Subject: [ 008/104] tcp: fix double-counted receiver RTT when leaving receiver fast path

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

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

From: Neal Cardwell <[email protected]>

[ Upstream commit aab2b4bf224ef8358d262f95b568b8ad0cecf0a0 ]

We should not update ts_recent and call tcp_rcv_rtt_measure_ts() both
before and after going to step5. That wastes CPU and double-counts the
receiver-side RTT sample.

Signed-off-by: Neal Cardwell <[email protected]>
Acked-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/ipv4/tcp_input.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5494,6 +5494,9 @@ int tcp_rcv_established(struct sock *sk,
if (tcp_checksum_complete_user(sk, skb))
goto csum_error;

+ if ((int)skb->truesize > sk->sk_forward_alloc)
+ goto step5;
+
/* Predicted packet is in window by definition.
* seq == rcv_nxt and rcv_wup <= rcv_nxt.
* Hence, check seq<=rcv_wup reduces to:
@@ -5505,9 +5508,6 @@ int tcp_rcv_established(struct sock *sk,

tcp_rcv_rtt_measure_ts(sk, skb);

- if ((int)skb->truesize > sk->sk_forward_alloc)
- goto step5;
-
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPHPHITS);

/* Bulk data transfer: receiver */

2013-03-25 01:38:57

by Ben Hutchings

[permalink] [raw]
Subject: [ 001/104] TTY: do not reset masters packet mode

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

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

From: Jiri Slaby <[email protected]>

commit b81273a132177edd806476b953f6afeb17b786d5 upstream.

Now that login from util-linux is forced to drop all references to a
TTY which it wants to hangup (to reach reference count 1) we are
seeing issues with telnet. When login closes its last reference to the
slave PTY, it also resets packet mode on the *master* side. And we
have a race here.

What telnet does is fork+exec of `login'. Then there are two
scenarios:
* `login' closes the slave TTY and resets thus master's packet mode,
but even now telnet properly sets the mode, or
* `telnetd' sets packet mode on the master, `login' closes the slave
TTY and resets master's packet mode.

The former case is OK. However the latter happens in much more cases,
by the order of magnitude to be precise. So when one tries to login to
such a messed telnet setup, they see the following:
inux login:
ogin incorrect

Note the missing first letters -- telnet thinks it is still in the
packet mode, so when it receives "linux login" from `login', it
considers "l" as the type of the packet and strips it.

SuS does not mention how the implementation should behave. Both BSDs I
checked (Free and Net) do not reset the flag upon the last close.

By this I am resurrecting an old bug, see References. We are hitting
it regularly now, i.e. with updated util-linux, ergo login.

Here, I am changing a behavior introduced back in 2.1 times. It would
better have a long time testing before goes upstream.

Signed-off-by: Jiri Slaby <[email protected]>
Cc: Mauro Carvalho Chehab <[email protected]>
Cc: Bryan Mason <[email protected]>
References: https://lkml.org/lkml/2009/11/11/223
References: https://bugzilla.redhat.com/show_bug.cgi?id=504703
References: https://bugzilla.novell.com/show_bug.cgi?id=797042
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/tty/pty.c | 1 -
1 file changed, 1 deletion(-)

--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -49,7 +49,6 @@ static void pty_close(struct tty_struct
tty->packet = 0;
if (!tty->link)
return;
- tty->link->packet = 0;
set_bit(TTY_OTHER_CLOSED, &tty->link->flags);
wake_up_interruptible(&tty->link->read_wait);
wake_up_interruptible(&tty->link->write_wait);

2013-03-25 01:39:22

by Ben Hutchings

[permalink] [raw]
Subject: [ 014/104] rtnl: fix info leak on RTM_GETLINK request for VF devices

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

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

From: Mathias Krause <[email protected]>

[ Upstream commit 84d73cd3fb142bf1298a8c13fd4ca50fd2432372 ]

Initialize the mac address buffer with 0 as the driver specific function
will probably not fill the whole buffer. In fact, all in-kernel drivers
fill only ETH_ALEN of the MAX_ADDR_LEN bytes, i.e. 6 of the 32 possible
bytes. Therefore we currently leak 26 bytes of stack memory to userland
via the netlink interface.

Signed-off-by: Mathias Krause <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/core/rtnetlink.c | 1 +
1 file changed, 1 insertion(+)

--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -973,6 +973,7 @@ static int rtnl_fill_ifinfo(struct sk_bu
* report anything.
*/
ivi.spoofchk = -1;
+ memset(ivi.mac, 0, sizeof(ivi.mac));
if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi))
break;
vf_mac.vf =

2013-03-25 01:39:35

by Ben Hutchings

[permalink] [raw]
Subject: [ 020/104] s390/mm: fix flush_tlb_kernel_range()

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

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

From: Heiko Carstens <[email protected]>

commit f6a70a07079518280022286a1dceb797d12e1edf upstream.

Our flush_tlb_kernel_range() implementation calls __tlb_flush_mm() with
&init_mm as argument. __tlb_flush_mm() however will only flush tlbs
for the passed in mm if its mm_cpumask is not empty.

For the init_mm however its mm_cpumask has never any bits set. Which in
turn means that our flush_tlb_kernel_range() implementation doesn't
work at all.

This can be easily verified with a vmalloc/vfree loop which allocates
a page, writes to it and then frees the page again. A crash will follow
almost instantly.

To fix this remove the cpumask_empty() check in __tlb_flush_mm() since
there shouldn't be too many mms with a zero mm_cpumask, besides the
init_mm of course.

Signed-off-by: Heiko Carstens <[email protected]>
Signed-off-by: Martin Schwidefsky <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/s390/include/asm/tlbflush.h | 2 --
1 file changed, 2 deletions(-)

--- a/arch/s390/include/asm/tlbflush.h
+++ b/arch/s390/include/asm/tlbflush.h
@@ -74,8 +74,6 @@ static inline void __tlb_flush_idte(unsi

static inline void __tlb_flush_mm(struct mm_struct * mm)
{
- if (unlikely(cpumask_empty(mm_cpumask(mm))))
- return;
/*
* If the machine has IDTE we prefer to do a per mm flush
* on all cpus instead of doing a local flush if the mm

2013-03-25 01:39:33

by Ben Hutchings

[permalink] [raw]
Subject: [ 011/104] netlabel: correctly list all the static label mappings

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

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

From: Paul Moore <[email protected]>

[ Upstream commits 0c1233aba1e948c37f6dc7620cb7c253fcd71ce9 and
a6a8fe950e1b8596bb06f2c89c3a1a4bf2011ba9 ]

When we have a large number of static label mappings that spill across
the netlink message boundary we fail to properly save our state in the
netlink_callback struct which causes us to repeat the same listings.
This patch fixes this problem by saving the state correctly between
calls to the NetLabel static label netlink "dumpit" routines.

Signed-off-by: Paul Moore <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/netlabel/netlabel_unlabeled.c | 27 +++++++++++----------------
1 file changed, 11 insertions(+), 16 deletions(-)

--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -1189,8 +1189,6 @@ static int netlbl_unlabel_staticlist(str
struct netlbl_unlhsh_walk_arg cb_arg;
u32 skip_bkt = cb->args[0];
u32 skip_chain = cb->args[1];
- u32 skip_addr4 = cb->args[2];
- u32 skip_addr6 = cb->args[3];
u32 iter_bkt;
u32 iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0;
struct netlbl_unlhsh_iface *iface;
@@ -1215,7 +1213,7 @@ static int netlbl_unlabel_staticlist(str
continue;
netlbl_af4list_foreach_rcu(addr4,
&iface->addr4_list) {
- if (iter_addr4++ < skip_addr4)
+ if (iter_addr4++ < cb->args[2])
continue;
if (netlbl_unlabel_staticlist_gen(
NLBL_UNLABEL_C_STATICLIST,
@@ -1231,7 +1229,7 @@ static int netlbl_unlabel_staticlist(str
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
netlbl_af6list_foreach_rcu(addr6,
&iface->addr6_list) {
- if (iter_addr6++ < skip_addr6)
+ if (iter_addr6++ < cb->args[3])
continue;
if (netlbl_unlabel_staticlist_gen(
NLBL_UNLABEL_C_STATICLIST,
@@ -1250,10 +1248,10 @@ static int netlbl_unlabel_staticlist(str

unlabel_staticlist_return:
rcu_read_unlock();
- cb->args[0] = skip_bkt;
- cb->args[1] = skip_chain;
- cb->args[2] = skip_addr4;
- cb->args[3] = skip_addr6;
+ cb->args[0] = iter_bkt;
+ cb->args[1] = iter_chain;
+ cb->args[2] = iter_addr4;
+ cb->args[3] = iter_addr6;
return skb->len;
}

@@ -1273,12 +1271,9 @@ static int netlbl_unlabel_staticlistdef(
{
struct netlbl_unlhsh_walk_arg cb_arg;
struct netlbl_unlhsh_iface *iface;
- u32 skip_addr4 = cb->args[0];
- u32 skip_addr6 = cb->args[1];
- u32 iter_addr4 = 0;
+ u32 iter_addr4 = 0, iter_addr6 = 0;
struct netlbl_af4list *addr4;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
- u32 iter_addr6 = 0;
struct netlbl_af6list *addr6;
#endif

@@ -1292,7 +1287,7 @@ static int netlbl_unlabel_staticlistdef(
goto unlabel_staticlistdef_return;

netlbl_af4list_foreach_rcu(addr4, &iface->addr4_list) {
- if (iter_addr4++ < skip_addr4)
+ if (iter_addr4++ < cb->args[0])
continue;
if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
iface,
@@ -1305,7 +1300,7 @@ static int netlbl_unlabel_staticlistdef(
}
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
netlbl_af6list_foreach_rcu(addr6, &iface->addr6_list) {
- if (iter_addr6++ < skip_addr6)
+ if (iter_addr6++ < cb->args[1])
continue;
if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
iface,
@@ -1320,8 +1315,8 @@ static int netlbl_unlabel_staticlistdef(

unlabel_staticlistdef_return:
rcu_read_unlock();
- cb->args[0] = skip_addr4;
- cb->args[1] = skip_addr6;
+ cb->args[0] = iter_addr4;
+ cb->args[1] = iter_addr6;
return skb->len;
}


2013-03-25 01:39:32

by Ben Hutchings

[permalink] [raw]
Subject: [ 010/104] macvlan: Set IFF_UNICAST_FLT flag to prevent unnecessary promisc mode.

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

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

From: Vlad Yasevich <[email protected]>

[ Upstream commit 87ab7f6f2874f1115817e394a7ed2dea1c72549e ]

Macvlan already supports hw address filters. Set the IFF_UNICAST_FLT
so that it doesn't needlesly enter PROMISC mode when macvlans are
stacked.

Signed-of-by: Vlad Yasevich <[email protected]>

Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/macvlan.c | 1 +
1 file changed, 1 insertion(+)

--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -585,6 +585,7 @@ void macvlan_common_setup(struct net_dev
ether_setup(dev);

dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
+ dev->priv_flags |= IFF_UNICAST_FLT;
dev->netdev_ops = &macvlan_netdev_ops;
dev->destructor = free_netdev;
dev->header_ops = &macvlan_hard_header_ops,

2013-03-25 01:39:30

by Ben Hutchings

[permalink] [raw]
Subject: [ 005/104] l2tp: Restore socket refcount when sendmsg succeeds

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

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

From: Guillaume Nault <[email protected]>

[ Upstream commit 8b82547e33e85fc24d4d172a93c796de1fefa81a ]

The sendmsg() syscall handler for PPPoL2TP doesn't decrease the socket
reference counter after successful transmissions. Any successful
sendmsg() call from userspace will then increase the reference counter
forever, thus preventing the kernel's session and tunnel data from
being freed later on.

The problem only happens when writing directly on L2TP sockets.
PPP sockets attached to L2TP are unaffected as the PPP subsystem
uses pppol2tp_xmit() which symmetrically increase/decrease reference
counters.

This patch adds the missing call to sock_put() before returning from
pppol2tp_sendmsg().

Signed-off-by: Guillaume Nault <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/l2tp/l2tp_ppp.c | 1 +
1 file changed, 1 insertion(+)

--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -360,6 +360,7 @@ static int pppol2tp_sendmsg(struct kiocb
l2tp_xmit_skb(session, skb, session->hdr_len);

sock_put(ps->tunnel_sock);
+ sock_put(sk);

return error;


2013-03-25 01:39:28

by Ben Hutchings

[permalink] [raw]
Subject: [ 009/104] tun: add a missing nf_reset() in tun_net_xmit()

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit f8af75f3517a24838a36eb5797a1a3e60bf9e276 ]

Dave reported following crash :

general protection fault: 0000 [#1] SMP
CPU 2
Pid: 25407, comm: qemu-kvm Not tainted 3.7.9-205.fc18.x86_64 #1 Hewlett-Packard HP Z400 Workstation/0B4Ch
RIP: 0010:[<ffffffffa0399bd5>] [<ffffffffa0399bd5>] destroy_conntrack+0x35/0x120 [nf_conntrack]
RSP: 0018:ffff880276913d78 EFLAGS: 00010206
RAX: 50626b6b7876376c RBX: ffff88026e530d68 RCX: ffff88028d158e00
RDX: ffff88026d0d5470 RSI: 0000000000000011 RDI: 0000000000000002
RBP: ffff880276913d88 R08: 0000000000000000 R09: ffff880295002900
R10: 0000000000000000 R11: 0000000000000003 R12: ffffffff81ca3b40
R13: ffffffff8151a8e0 R14: ffff880270875000 R15: 0000000000000002
FS: 00007ff3bce38a00(0000) GS:ffff88029fc40000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 00007fd1430bd000 CR3: 000000027042b000 CR4: 00000000000027e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process qemu-kvm (pid: 25407, threadinfo ffff880276912000, task ffff88028c369720)
Stack:
ffff880156f59100 ffff880156f59100 ffff880276913d98 ffffffff815534f7
ffff880276913db8 ffffffff8151a74b ffff880270875000 ffff880156f59100
ffff880276913dd8 ffffffff8151a5a6 ffff880276913dd8 ffff88026d0d5470
Call Trace:
[<ffffffff815534f7>] nf_conntrack_destroy+0x17/0x20
[<ffffffff8151a74b>] skb_release_head_state+0x7b/0x100
[<ffffffff8151a5a6>] __kfree_skb+0x16/0xa0
[<ffffffff8151a666>] kfree_skb+0x36/0xa0
[<ffffffff8151a8e0>] skb_queue_purge+0x20/0x40
[<ffffffffa02205f7>] __tun_detach+0x117/0x140 [tun]
[<ffffffffa022184c>] tun_chr_close+0x3c/0xd0 [tun]
[<ffffffff8119669c>] __fput+0xec/0x240
[<ffffffff811967fe>] ____fput+0xe/0x10
[<ffffffff8107eb27>] task_work_run+0xa7/0xe0
[<ffffffff810149e1>] do_notify_resume+0x71/0xb0
[<ffffffff81640152>] int_signal+0x12/0x17
Code: 00 00 04 48 89 e5 41 54 53 48 89 fb 4c 8b a7 e8 00 00 00 0f 85 de 00 00 00 0f b6 73 3e 0f b7 7b 2a e8 10 40 00 00 48 85 c0 74 0e <48> 8b 40 28 48 85 c0 74 05 48 89 df ff d0 48 c7 c7 08 6a 3a a0
RIP [<ffffffffa0399bd5>] destroy_conntrack+0x35/0x120 [nf_conntrack]
RSP <ffff880276913d78>

This is because tun_net_xmit() needs to call nf_reset()
before queuing skb into receive_queue

Reported-by: Dave Jones <[email protected]>
Signed-off-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/net/tun.c | 2 ++
1 file changed, 2 insertions(+)

--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -417,6 +417,8 @@ static netdev_tx_t tun_net_xmit(struct s
* for indefinite time. */
skb_orphan(skb);

+ nf_reset(skb);
+
/* Enqueue packet */
skb_queue_tail(&tun->socket.sk->sk_receive_queue, skb);


2013-03-25 01:39:27

by Ben Hutchings

[permalink] [raw]
Subject: [ 017/104] drm/i915: Increase the RC6p threshold.

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

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

From: Stéphane Marchesin <[email protected]>

commit 0920a48719f1ceefc909387a64f97563848c7854 upstream.

This increases GEN6_RC6p_THRESHOLD from 100000 to 150000. For some
reason this avoids the gen6_gt_check_fifodbg.isra warnings and
associated GPU lockups, which makes my ivy bridge machine stable.

Signed-off-by: Stéphane Marchesin <[email protected]>
Acked-by: Jesse Barnes <[email protected]>
Signed-off-by: Daniel Vetter <[email protected]>
[bwh: Backported to 3.2: adjust filename]
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/gpu/drm/i915/intel_pm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8059,7 +8059,7 @@ void gen6_enable_rps(struct drm_i915_pri
I915_WRITE(GEN6_RC_SLEEP, 0);
I915_WRITE(GEN6_RC1e_THRESHOLD, 1000);
I915_WRITE(GEN6_RC6_THRESHOLD, 50000);
- I915_WRITE(GEN6_RC6p_THRESHOLD, 100000);
+ I915_WRITE(GEN6_RC6p_THRESHOLD, 150000);
I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */

if (intel_enable_rc6(dev_priv->dev))

2013-03-25 01:39:26

by Ben Hutchings

[permalink] [raw]
Subject: [ 015/104] dcbnl: fix various netlink info leaks

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

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

From: Mathias Krause <[email protected]>

[ Upstream commit 29cd8ae0e1a39e239a3a7b67da1986add1199fc0 ]

The dcb netlink interface leaks stack memory in various places:
* perm_addr[] buffer is only filled at max with 12 of the 32 bytes but
copied completely,
* no in-kernel driver fills all fields of an IEEE 802.1Qaz subcommand,
so we're leaking up to 58 bytes for ieee_ets structs, up to 136 bytes
for ieee_pfc structs, etc.,
* the same is true for CEE -- no in-kernel driver fills the whole
struct,

Prevent all of the above stack info leaks by properly initializing the
buffers/structures involved.

Signed-off-by: Mathias Krause <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/dcb/dcbnl.c | 7 +++++++
1 file changed, 7 insertions(+)

--- a/net/dcb/dcbnl.c
+++ b/net/dcb/dcbnl.c
@@ -336,6 +336,7 @@ static int dcbnl_getperm_hwaddr(struct n
dcb->dcb_family = AF_UNSPEC;
dcb->cmd = DCB_CMD_GPERM_HWADDR;

+ memset(perm_addr, 0, sizeof(perm_addr));
netdev->dcbnl_ops->getpermhwaddr(netdev, perm_addr);

ret = nla_put(dcbnl_skb, DCB_ATTR_PERM_HWADDR, sizeof(perm_addr),
@@ -1238,6 +1239,7 @@ static int dcbnl_ieee_fill(struct sk_buf

if (ops->ieee_getets) {
struct ieee_ets ets;
+ memset(&ets, 0, sizeof(ets));
err = ops->ieee_getets(netdev, &ets);
if (!err)
NLA_PUT(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets);
@@ -1245,6 +1247,7 @@ static int dcbnl_ieee_fill(struct sk_buf

if (ops->ieee_getpfc) {
struct ieee_pfc pfc;
+ memset(&pfc, 0, sizeof(pfc));
err = ops->ieee_getpfc(netdev, &pfc);
if (!err)
NLA_PUT(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc);
@@ -1277,6 +1280,7 @@ static int dcbnl_ieee_fill(struct sk_buf
/* get peer info if available */
if (ops->ieee_peer_getets) {
struct ieee_ets ets;
+ memset(&ets, 0, sizeof(ets));
err = ops->ieee_peer_getets(netdev, &ets);
if (!err)
NLA_PUT(skb, DCB_ATTR_IEEE_PEER_ETS, sizeof(ets), &ets);
@@ -1284,6 +1288,7 @@ static int dcbnl_ieee_fill(struct sk_buf

if (ops->ieee_peer_getpfc) {
struct ieee_pfc pfc;
+ memset(&pfc, 0, sizeof(pfc));
err = ops->ieee_peer_getpfc(netdev, &pfc);
if (!err)
NLA_PUT(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc);
@@ -1463,6 +1468,7 @@ static int dcbnl_cee_fill(struct sk_buff
/* peer info if available */
if (ops->cee_peer_getpg) {
struct cee_pg pg;
+ memset(&pg, 0, sizeof(pg));
err = ops->cee_peer_getpg(netdev, &pg);
if (!err)
NLA_PUT(skb, DCB_ATTR_CEE_PEER_PG, sizeof(pg), &pg);
@@ -1470,6 +1476,7 @@ static int dcbnl_cee_fill(struct sk_buff

if (ops->cee_peer_getpfc) {
struct cee_pfc pfc;
+ memset(&pfc, 0, sizeof(pfc));
err = ops->cee_peer_getpfc(netdev, &pfc);
if (!err)
NLA_PUT(skb, DCB_ATTR_CEE_PEER_PFC, sizeof(pfc), &pfc);

2013-03-25 01:39:24

by Ben Hutchings

[permalink] [raw]
Subject: [ 012/104] bridging: fix rx_handlers return code

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

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

From: Cristian Bercaru <[email protected]>

[ Upstream commit 3bc1b1add7a8484cc4a261c3e128dbe1528ce01f ]

The frames for which rx_handlers return RX_HANDLER_CONSUMED are no longer
counted as dropped. They are counted as successfully received by
'netif_receive_skb'.

This allows network interface drivers to correctly update their RX-OK and
RX-DRP counters based on the result of 'netif_receive_skb'.

Signed-off-by: Cristian Bercaru <[email protected]>
Signed-off-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/core/dev.c | 1 +
1 file changed, 1 insertion(+)

--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3299,6 +3299,7 @@ ncls:
}
switch (rx_handler(&skb)) {
case RX_HANDLER_CONSUMED:
+ ret = NET_RX_SUCCESS;
goto out;
case RX_HANDLER_ANOTHER:
goto another_round;

2013-03-25 01:39:20

by Ben Hutchings

[permalink] [raw]
Subject: [ 007/104] net: ipv6: Dont purge default router if accept_ra=2

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

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

From: Lorenzo Colitti <[email protected]>

[ Upstream commit 3e8b0ac3e41e3c882222a5522d5df7212438ab51 ]

Setting net.ipv6.conf.<interface>.accept_ra=2 causes the kernel
to accept RAs even when forwarding is enabled. However, enabling
forwarding purges all default routes on the system, breaking
connectivity until the next RA is received. Fix this by not
purging default routes on interfaces that have accept_ra=2.

Signed-off-by: Lorenzo Colitti <[email protected]>
Acked-by: YOSHIFUJI Hideaki <[email protected]>
Acked-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/ipv6/route.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1920,7 +1920,8 @@ void rt6_purge_dflt_routers(struct net *
restart:
read_lock_bh(&table->tb6_lock);
for (rt = table->tb6_root.leaf; rt; rt = rt->dst.rt6_next) {
- if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) {
+ if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF) &&
+ (!rt->rt6i_idev || rt->rt6i_idev->cnf.accept_ra != 2)) {
dst_hold(&rt->dst);
read_unlock_bh(&table->tb6_lock);
ip6_del_rt(rt);

2013-03-25 01:39:18

by Ben Hutchings

[permalink] [raw]
Subject: [ 016/104] 6lowpan: Fix endianness issue in is_addr_link_local().

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

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

From: YOSHIFUJI Hideaki / 吉藤英明 <[email protected]>

[ Upstream commit 9026c4927254f5bea695cc3ef2e255280e6a3011 ]

Signed-off-by: YOSHIFUJI Hideaki <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/ieee802154/6lowpan.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/net/ieee802154/6lowpan.h
+++ b/net/ieee802154/6lowpan.h
@@ -87,7 +87,7 @@
(memcmp(addr1, addr2, length >> 3) == 0)

/* local link, i.e. FE80::/10 */
-#define is_addr_link_local(a) (((a)->s6_addr16[0]) == 0x80FE)
+#define is_addr_link_local(a) (((a)->s6_addr16[0]) == htons(0xFE80))

/*
* check whether we can compress the IID to 16 bits,

2013-03-25 01:39:17

by Ben Hutchings

[permalink] [raw]
Subject: [ 006/104] rds: limit the size allocated by rds_message_alloc()

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

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

From: Cong Wang <[email protected]>

[ Upstream commit ece6b0a2b25652d684a7ced4ae680a863af041e0 ]

Dave Jones reported the following bug:

"When fed mangled socket data, rds will trust what userspace gives it,
and tries to allocate enormous amounts of memory larger than what
kmalloc can satisfy."

WARNING: at mm/page_alloc.c:2393 __alloc_pages_nodemask+0xa0d/0xbe0()
Hardware name: GA-MA78GM-S2H
Modules linked in: vmw_vsock_vmci_transport vmw_vmci vsock fuse bnep dlci bridge 8021q garp stp mrp binfmt_misc l2tp_ppp l2tp_core rfcomm s
Pid: 24652, comm: trinity-child2 Not tainted 3.8.0+ #65
Call Trace:
[<ffffffff81044155>] warn_slowpath_common+0x75/0xa0
[<ffffffff8104419a>] warn_slowpath_null+0x1a/0x20
[<ffffffff811444ad>] __alloc_pages_nodemask+0xa0d/0xbe0
[<ffffffff8100a196>] ? native_sched_clock+0x26/0x90
[<ffffffff810b2128>] ? trace_hardirqs_off_caller+0x28/0xc0
[<ffffffff810b21cd>] ? trace_hardirqs_off+0xd/0x10
[<ffffffff811861f8>] alloc_pages_current+0xb8/0x180
[<ffffffff8113eaaa>] __get_free_pages+0x2a/0x80
[<ffffffff811934fe>] kmalloc_order_trace+0x3e/0x1a0
[<ffffffff81193955>] __kmalloc+0x2f5/0x3a0
[<ffffffff8104df0c>] ? local_bh_enable_ip+0x7c/0xf0
[<ffffffffa0401ab3>] rds_message_alloc+0x23/0xb0 [rds]
[<ffffffffa04043a1>] rds_sendmsg+0x2b1/0x990 [rds]
[<ffffffff810b21cd>] ? trace_hardirqs_off+0xd/0x10
[<ffffffff81564620>] sock_sendmsg+0xb0/0xe0
[<ffffffff810b2052>] ? get_lock_stats+0x22/0x70
[<ffffffff810b24be>] ? put_lock_stats.isra.23+0xe/0x40
[<ffffffff81567f30>] sys_sendto+0x130/0x180
[<ffffffff810b872d>] ? trace_hardirqs_on+0xd/0x10
[<ffffffff816c547b>] ? _raw_spin_unlock_irq+0x3b/0x60
[<ffffffff816cd767>] ? sysret_check+0x1b/0x56
[<ffffffff810b8695>] ? trace_hardirqs_on_caller+0x115/0x1a0
[<ffffffff81341d8e>] ? trace_hardirqs_on_thunk+0x3a/0x3f
[<ffffffff816cd742>] system_call_fastpath+0x16/0x1b
---[ end trace eed6ae990d018c8b ]---

Reported-by: Dave Jones <[email protected]>
Cc: Dave Jones <[email protected]>
Cc: David S. Miller <[email protected]>
Cc: Venkat Venkatsubra <[email protected]>
Signed-off-by: Cong Wang <[email protected]>
Acked-by: Venkat Venkatsubra <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
net/rds/message.c | 3 +++
1 file changed, 3 insertions(+)

--- a/net/rds/message.c
+++ b/net/rds/message.c
@@ -197,6 +197,9 @@ struct rds_message *rds_message_alloc(un
{
struct rds_message *rm;

+ if (extra_len > KMALLOC_MAX_SIZE - sizeof(struct rds_message))
+ return NULL;
+
rm = kzalloc(sizeof(struct rds_message) + extra_len, gfp);
if (!rm)
goto out;

2013-03-25 01:42:34

by Ben Hutchings

[permalink] [raw]
Subject: [ 003/104] perf,x86: fix wrmsr_on_cpu() warning on suspend/resume

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

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

From: Linus Torvalds <[email protected]>

commit 2a6e06b2aed6995af401dcd4feb5e79a0c7ea554 upstream.

Commit 1d9d8639c063 ("perf,x86: fix kernel crash with PEBS/BTS after
suspend/resume") fixed a crash when doing PEBS performance profiling
after resuming, but in using init_debug_store_on_cpu() to restore the
DS_AREA mtrr it also resulted in a new WARN_ON() triggering.

init_debug_store_on_cpu() uses "wrmsr_on_cpu()", which in turn uses CPU
cross-calls to do the MSR update. Which is not really valid at the
early resume stage, and the warning is quite reasonable. Now, it all
happens to _work_, for the simple reason that smp_call_function_single()
ends up just doing the call directly on the CPU when the CPU number
matches, but we really should just do the wrmsr() directly instead.

This duplicates the wrmsr() logic, but hopefully we can just remove the
wrmsr_on_cpu() version eventually.

Reported-and-tested-by: Parag Warudkar <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/x86/kernel/cpu/perf_event_intel_ds.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -739,8 +739,10 @@ void intel_ds_init(void)

void perf_restore_debug_store(void)
{
+ struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds);
+
if (!x86_pmu.bts && !x86_pmu.pebs)
return;

- init_debug_store_on_cpu(smp_processor_id());
+ wrmsrl(MSR_IA32_DS_AREA, (unsigned long)ds);
}

2013-03-25 01:42:48

by Ben Hutchings

[permalink] [raw]
Subject: [ 002/104] perf,x86: fix kernel crash with PEBS/BTS after suspend/resume

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

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

From: Stephane Eranian <[email protected]>

commit 1d9d8639c063caf6efc2447f5f26aa637f844ff6 upstream.

This patch fixes a kernel crash when using precise sampling (PEBS)
after a suspend/resume. Turns out the CPU notifier code is not invoked
on CPU0 (BP). Therefore, the DS_AREA (used by PEBS) is not restored properly
by the kernel and keeps it power-on/resume value of 0 causing any PEBS
measurement to crash when running on CPU0.

The workaround is to add a hook in the actual resume code to restore
the DS Area MSR value. It is invoked for all CPUS. So for all but CPU0,
the DS_AREA will be restored twice but this is harmless.

Reported-by: Linus Torvalds <[email protected]>
Signed-off-by: Stephane Eranian <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/x86/kernel/cpu/perf_event_intel_ds.c | 8 ++++++++
arch/x86/power/cpu.c | 2 ++
include/linux/perf_event.h | 2 ++
3 files changed, 12 insertions(+)

--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -736,3 +736,11 @@ void intel_ds_init(void)
}
}
}
+
+void perf_restore_debug_store(void)
+{
+ if (!x86_pmu.bts && !x86_pmu.pebs)
+ return;
+
+ init_debug_store_on_cpu(smp_processor_id());
+}
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -11,6 +11,7 @@
#include <linux/suspend.h>
#include <linux/export.h>
#include <linux/smp.h>
+#include <linux/perf_event.h>

#include <asm/pgtable.h>
#include <asm/proto.h>
@@ -225,6 +226,7 @@ static void __restore_processor_state(st

do_fpu_end();
mtrr_bp_restore();
+ perf_restore_debug_store();
}

/* Needed by apm.c */
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1146,6 +1146,7 @@ extern void perf_swevent_put_recursion_c
extern void perf_event_enable(struct perf_event *event);
extern void perf_event_disable(struct perf_event *event);
extern void perf_event_task_tick(void);
+extern void perf_restore_debug_store(void);
#else
static inline void
perf_event_task_sched_in(struct task_struct *prev,
@@ -1184,6 +1185,7 @@ static inline void perf_swevent_put_recu
static inline void perf_event_enable(struct perf_event *event) { }
static inline void perf_event_disable(struct perf_event *event) { }
static inline void perf_event_task_tick(void) { }
+static inline void perf_restore_debug_store(void) { }
#endif

#define perf_output_put(handle, x) perf_output_copy((handle), &(x), sizeof(x))

2013-03-25 02:06:42

by Ben Hutchings

[permalink] [raw]
Subject: Re: [ 000/104] 3.2.42-stable review

This is the combined patch for 3.2.42-rc1 relative to 3.2.41.

Ben.

--
Ben Hutchings
The two most common things in the universe are hydrogen and stupidity.


Attachments:
linux-3.2.42-rc1.patch (136.96 kB)
signature.asc (828.00 B)
This is a digitally signed message part
Download all attachments

2013-03-26 13:02:22

by Satoru Takeuchi

[permalink] [raw]
Subject: Re: [ 000/104] 3.2.42-stable review

At Mon, 25 Mar 2013 00:34:24 +0000,
Ben Hutchings wrote:
>
> This is the start of the stable review cycle for the 3.2.42 release.
> There are 104 patches in this series, which will be posted as responses
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Wed Mar 27 01:00:00 UTC 2013.
> Anything received after that time might be too late.
>
> A combined patch relative to 3.2.41 will be posted as an additional
> response to this. A shortlog and diffstat can be found below.

This kernel can be built and boot without any problem.
Building a kernel with this kernel also works fine.

- Build Machine: debian wheezy x86_64
CPU: Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz x 4
memory: 8GB

- Test machine: debian wheezy x86_64(KVM guest on the Build Machine)
vCPU: x2
memory: 2GB

Thanks,
Satoru

>
> Ben.
>
> -------------
>
> Alan Stern (1):
> usb: gadget: udc-core: fix a regression during gadget driver unbinding
> [511f3c5326eabe1ece35202a404c24c0aeacc246]
>
> Alex Deucher (1):
> drm/radeon/benchmark: make sure bo blit copy exists before using it
> [fa8d387dc3f62062a6b4afbbb2a3438094fd8584]
>
> Ben Hutchings (11):
> efivars: Fix check for CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE
> [ca0ba26fbbd2d81c43085df49ce0abfe34535a90]
> efivars: pstore: Do not check size when erasing variable
> [not upstream; this is a fix for an incorrectly backported commit]
> perf: Revert duplicated commit
> [not upstream; the commits were correctly merged by git]
> sfc: Convert firmware subtypes to native byte order in efx_mcdi_get_board_cfg()
> [bfeed902946a31692e7a24ed355b6d13ac37d014]
> sfc: Detach net device when stopping queues for reconfiguration
> [29c69a4882641285a854d6d03ca5adbba68c0034]
> sfc: Disable soft interrupt handling during efx_device_detach_sync()
> [35205b211c8d17a8a0b5e8926cb7c73e9a7ef1ad]
> sfc: Fix efx_rx_buf_offset() in the presence of swiotlb
> [06e63c57acbb1df7c35ebe846ae416a8b88dfafa,
> b590ace09d51cd39744e0f7662c5e4a0d1b5d952,
> c73e787a8db9117d59b5180baf83203a42ecadca]
> sfc: Fix timekeeping in efx_mcdi_poll()
> [ebf98e797b4e26ad52ace1511a0b503ee60a6cd4]
> sfc: Fix two causes of flush failure
> [a606f4325dca6950996abbae452d33f2af095f39,
> d5e8cc6c946e0857826dcfbb3585068858445bfe,
> 525d9e824018cd7cc8d8d44832ddcd363abfe6e1]
> sfc: Only use TX push if a single descriptor is to be written
> [fae8563b25f73dc584a07bcda7a82750ff4f7672]
> sfc: Properly sync RX DMA buffer when it is not the last in the page
> [3a68f19d7afb80f548d016effbc6ed52643a8085]
>
> Benjamin Herrenschmidt (1):
> powerpc: Fix cputable entry for 970MP rev 1.0
> [d63ac5f6cf31c8a83170a9509b350c1489a7262b]
>
> Bing Zhao (1):
> mwifiex: fix potential out-of-boundary access to ibss rate table
> [5f0fabf84d7b52f979dcbafa3d3c530c60d9a92c]
>
> CQ Tang (1):
> x86-64: Fix the failure case in copy_user_handle_tail()
> [66db3feb486c01349f767b98ebb10b0c3d2d021b]
>
> Cong Wang (1):
> rds: limit the size allocated by rds_message_alloc()
> [ece6b0a2b25652d684a7ced4ae680a863af041e0]
>
> Cristian Bercaru (1):
> bridging: fix rx_handlers return code
> [3bc1b1add7a8484cc4a261c3e128dbe1528ce01f]
>
> Dan Carpenter (1):
> selinux: use GFP_ATOMIC under spin_lock
> [4502403dcf8f5c76abd4dbab8726c8e4ecb5cd34]
>
> Daniel Mack (2):
> ALSA: snd-usb: mixer: ignore -EINVAL in snd_usb_mixer_controls()
> [83ea5d18d74f032a760fecde78c0210f66f7f70c]
> ALSA: snd-usb: mixer: propagate errors up the call chain
> [4d7b86c98e445b075c2c4c3757eb6d3d6efbe72e]
>
> Daniel Pieczko (1):
> sfc: lock TX queues when calling netif_device_detach()
> [c2f3b8e3a44b6fe9e36704e30157ebe1a88c08b1]
>
> David Rientjes (1):
> perf,x86: fix link failure for non-Intel configs
> [6c4d3bc99b3341067775efd4d9d13cc8e655fd7c]
>
> David Ward (1):
> net/ipv4: Ensure that location of timestamp option is stored
> [4660c7f498c07c43173142ea95145e9dac5a6d14]
>
> Denis V. Lunev (1):
> ipv4: fix definition of FIB_TABLE_HASHSZ
> [5b9e12dbf92b441b37136ea71dac59f05f2673a9]
>
> Dmitry Artamonow (1):
> usb-storage: add unusual_devs entry for Samsung YP-Z3 mp3 player
> [29f86e66428ee083aec106cca1748dc63d98ce23]
>
> Dmitry Torokhov (1):
> USB: xhci - fix bit definitions for IMAN register
> [f8264340e694604863255cc0276491d17c402390]
>
> Eric Dumazet (2):
> tcp: fix skb_availroom()
> [16fad69cfe4adbbfa813de516757b87bcae36d93]
> tun: add a missing nf_reset() in tun_net_xmit()
> [f8af75f3517a24838a36eb5797a1a3e60bf9e276]
>
> Guillaume Nault (1):
> l2tp: Restore socket refcount when sendmsg succeeds
> [8b82547e33e85fc24d4d172a93c796de1fefa81a]
>
> Hannes Frederic Sowa (2):
> inet: limit length of fragment queue hash table bucket lists
> [5a3da1fe9561828d0ca7eca664b16ec2b9bf0055]
> ipv6: stop multicast forwarding to process interface scoped addresses
> [ddf64354af4a702ee0b85d0a285ba74c7278a460]
>
> Hannes Reinecke (1):
> USB: xhci: correctly enable interrupts
> [00eed9c814cb8f281be6f0f5d8f45025dc0a97eb]
>
> Heiko Carstens (1):
> s390/mm: fix flush_tlb_kernel_range()
> [f6a70a07079518280022286a1dceb797d12e1edf]
>
> Jan Kara (1):
> jbd2: fix use after free in jbd2_journal_dirty_metadata()
> [ad56edad089b56300fd13bb9eeb7d0424d978239]
>
> Jeff Layton (1):
> cifs: ignore everything in SPNEGO blob after mechTypes
> [f853c616883a8de966873a1dab283f1369e275a1]
>
> Jiri Slaby (1):
> TTY: do not reset master's packet mode
> [b81273a132177edd806476b953f6afeb17b786d5]
>
> Joe Thornber (1):
> dm thin: fix discard corruption
> [f046f89a99ccfd9408b94c653374ff3065c7edb3]
>
> Johan Hovold (18):
> 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: garmin_gps: fix memory leak on disconnect
> [618aa1068df29c37a58045fe940f9106664153fd]
> USB: io_edgeport: fix use-after-free in TIOCMIWAIT
> [333576255d4cfc53efd056aad438568184b36af6]
> USB: io_ti: fix get_icount for two port adapters
> [5492bf3d5655b4954164f69c02955a7fca267611]
> 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: serial: fix interface refcounting
> [d7971051e4df825e0bc11b995e87bfe86355b8e5]
> 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]
>
> Kees Cook (2):
> drm/i915: bounds check execbuffer relocation count
> [3118a4f652c7b12c752f3222af0447008f9b2368]
> drm/i915: restrict kernel address leak in debugfs
> [2563a4524febe8f4a98e717e02436d1aaf672aa2]
>
> Larry Finger (2):
> rtlwifi: rtl8192cu: Fix problem that prevents reassociation
> [9437a248e7cac427c898bdb11bd1ac6844a1ead4]
> rtlwifi: rtl8192cu: Fix schedule while atomic bug splat
> [664899786cb49cb52f620e06ac19c0be524a7cfa]
>
> Laxman Dewangan (1):
> i2c: tegra: check the clk_prepare_enable() return value
> [132c803f7b70b17322579f6f4f3f65cf68e55135]
>
> Lekensteyn (1):
> i915: initialize CADL in opregion
> [d627b62ff8d4d36761adbcd90ff143d79c94ab22]
>
> Linus Torvalds (2):
> perf,x86: fix wrmsr_on_cpu() warning on suspend/resume
> [2a6e06b2aed6995af401dcd4feb5e79a0c7ea554]
> vfs,proc: guarantee unique inodes in /proc
> [51f0885e5415b4cc6535e9cdcc5145bfbc134353]
>
> Lorenzo Colitti (1):
> net: ipv6: Don't purge default router if accept_ra=2
> [3e8b0ac3e41e3c882222a5522d5df7212438ab51]
>
> Lukas Czerner (1):
> ext4: convert number of blocks to clusters properly
> [810da240f221d64bf90020f25941b05b378186fe]
>
> Mateusz Guzik (1):
> cifs: delay super block destruction until all cifsFileInfo objects are gone
> [24261fc23db950951760d00c188ba63cc756b932]
>
> Mathias Krause (4):
> dcbnl: fix various netlink info leaks
> [29cd8ae0e1a39e239a3a7b67da1986add1199fc0]
> isofs: avoid info leak on export
> [fe685aabf7c8c9f138e5ea900954d295bf229175]
> rtnl: fix info leak on RTM_GETLINK request for VF devices
> [84d73cd3fb142bf1298a8c13fd4ca50fd2432372]
> udf: avoid info leak on export
> [0143fc5e9f6f5aad4764801015bc8d4b4a278200]
>
> Matt Fleming (2):
> efivars: Handle duplicate names from get_next_variable()
> [e971318bbed610e28bb3fde9d548e6aaf0a6b02e]
> efivars: explicitly calculate length of VariableName
> [ec50bd32f1672d38ddce10fb1841cbfda89cfe9a]
>
> Michael S. Tsirkin (1):
> vhost/net: fix heads usage of ubuf_info
> [46aa92d1ba162b4b3d6b7102440e459d4e4ee255]
>
> Neal Cardwell (1):
> tcp: fix double-counted receiver RTT when leaving receiver fast path
> [aab2b4bf224ef8358d262f95b568b8ad0cecf0a0]
>
> Paul Moore (1):
> netlabel: correctly list all the static label mappings
> [0c1233aba1e948c37f6dc7620cb7c253fcd71ce9,
> a6a8fe950e1b8596bb06f2c89c3a1a4bf2011ba9]
>
> Seiji Aguchi (1):
> efi_pstore: Introducing workqueue updating sysfs
> [a93bc0c6e07ed9bac44700280e65e2945d864fd4]
>
> Seth Forshee (2):
> efivars: Add module parameter to disable use as a pstore backend
> [ec0971ba5372a4dfa753f232449d23a8fd98490e]
> efivars: Allow disabling use as a pstore backend
> [ed9dc8ce7a1c8115dba9483a9b51df8b63a2e0ef]
>
> Stephane Eranian (1):
> perf,x86: fix kernel crash with PEBS/BTS after suspend/resume
> [1d9d8639c063caf6efc2447f5f26aa637f844ff6]
>
> Steven Rostedt (5):
> tracing: Fix free of probe entry by calling call_rcu_sched()
> [740466bc89ad8bd5afcc8de220f715f62b21e365]
> tracing: Fix race in snapshot swapping
> [2721e72dd10f71a3ba90f59781becf02638aa0d9]
> tracing: Keep overwrite in sync between regular and snapshot buffers
> [80902822658aab18330569587cdb69ac1dfdcea8]
> tracing: Prevent buffer overwrite disabled for latency tracers
> [613f04a0f51e6e68ac6fe571ab79da3c0a5eb4da]
> tracing: Protect tracer flags with trace_types_lock
> [69d34da2984c95b33ea21518227e1f9470f11d95]
>
> Stuart Hodgson (1):
> sfc: Do not attempt to flush queues if DMA is disabled
> [3dca9d2dc285faf1910d405b65df845cab061356]
>
> Stéphane Marchesin (1):
> drm/i915: Increase the RC6p threshold.
> [0920a48719f1ceefc909387a64f97563848c7854]
>
> Takashi Iwai (2):
> ALSA: hda - Fix typo in checking IEC958 emphasis bit
> [a686fd141e20244ad75f80ad54706da07d7bb90a]
> ALSA: hda/cirrus - Fix the digital beep registration
> [a86b1a2cd2f81f74e815e07f756edd7bc5b6f034]
>
> Theodore Ts'o (2):
> ext4: fix data=journal fast mount/umount hang
> [2b405bfa84063bfa35621d2d6879f52693c614b0]
> ext4: use atomic64_t for the per-flexbg free_clusters count
> [90ba983f6889e65a3b506b30dc606aa9d1d46cd2]
>
> Tkhai Kirill (1):
> sunsu: Fix panic in case of nonexistent port at "console=ttySY" cmdline option
> [cb29529ea0030e60ef1bbbf8399a43d397a51526]
>
> Tomas Hozza (1):
> tools: hv: Netlink source address validation allows DoS
> [95a69adab9acfc3981c504737a2b6578e4d846ef]
>
> Torsten Duwe (2):
> KMS: fix EDID detailed timing frame rate
> [c19b3b0f6eed552952845e4ad908dba2113d67b4]
> KMS: fix EDID detailed timing vsync parsing
> [16dad1d743d31a104a849c8944e6b9eb479f6cd7]
>
> Veaceslav Falico (2):
> bonding: don't call update_speed_duplex() under spinlocks
> [876254ae2758d50dcb08c7bd00caf6a806571178]
> netconsole: don't call __netpoll_cleanup() while atomic
> [3f315bef23075ea8a98a6fe4221a83b83456d970]
>
> Vlad Yasevich (3):
> macvlan: Set IFF_UNICAST_FLT flag to prevent unnecessary promisc mode.
> [87ab7f6f2874f1115817e394a7ed2dea1c72549e]
> rtnetlink: Mask the rta_type when range checking
> [a5b8db91442fce9c9713fcd656c3698f1adde1d6]
> sctp: Use correct sideffect command in duplicate cookie handling
> [f2815633504b442ca0b0605c16bf3d88a3a0fcea]
>
> Wanpeng Li (1):
> mm/hugetlb: fix total hugetlbfs pages count when using memory overcommit accouting
> [d00285884c0892bb1310df96bce6056e9ce9b9d9]
>
> Xufeng Zhang (1):
> sctp: don't break the loop while meeting the active_path so as to find the matched transport
> [2317f449af30073cfa6ec8352e4a65a89e357bdd]
>
> YOSHIFUJI Hideaki / 吉藤英明 (1):
> 6lowpan: Fix endianness issue in is_addr_link_local().
> [9026c4927254f5bea695cc3ef2e255280e6a3011]
>
> Zheng Liu (1):
> ext4: fix the wrong number of the allocated blocks in ext4_split_extent()
> [3a2256702e47f68f921dfad41b1764d05c572329]
>
> Makefile | 4 +-
> arch/powerpc/kernel/cputable.c | 2 +-
> arch/s390/include/asm/tlbflush.h | 2 -
> arch/x86/kernel/cpu/perf_event_intel_ds.c | 10 +
> arch/x86/lib/usercopy_64.c | 4 +-
> arch/x86/power/cpu.c | 2 +
> drivers/firmware/Kconfig | 18 ++
> drivers/firmware/efivars.c | 256 ++++++++++++++++++++------
> drivers/gpu/drm/drm_edid.c | 3 +-
> drivers/gpu/drm/i915/i915_debugfs.c | 2 +-
> drivers/gpu/drm/i915/i915_gem_execbuffer.c | 11 +-
> drivers/gpu/drm/i915/intel_display.c | 2 +-
> drivers/gpu/drm/i915/intel_opregion.c | 23 ++-
> drivers/gpu/drm/radeon/radeon_benchmark.c | 16 +-
> drivers/i2c/busses/i2c-tegra.c | 13 +-
> drivers/md/dm-thin.c | 4 +-
> drivers/md/persistent-data/dm-btree-remove.c | 46 ++---
> drivers/net/bonding/bond_main.c | 6 +-
> drivers/net/ethernet/sfc/efx.c | 53 ++++--
> drivers/net/ethernet/sfc/efx.h | 13 ++
> drivers/net/ethernet/sfc/falcon.c | 2 +
> drivers/net/ethernet/sfc/mcdi.c | 29 +--
> drivers/net/ethernet/sfc/mcdi.h | 1 +
> drivers/net/ethernet/sfc/mcdi_mac.c | 4 +-
> drivers/net/ethernet/sfc/net_driver.h | 10 +-
> drivers/net/ethernet/sfc/nic.c | 24 ++-
> drivers/net/ethernet/sfc/nic.h | 2 +
> drivers/net/ethernet/sfc/rx.c | 25 ++-
> drivers/net/ethernet/sfc/selftest.c | 2 +-
> drivers/net/ethernet/sfc/siena.c | 15 +-
> drivers/net/macvlan.c | 1 +
> drivers/net/netconsole.c | 20 +-
> drivers/net/tun.c | 2 +
> drivers/net/wireless/mwifiex/join.c | 7 +-
> drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 89 ++++-----
> drivers/tty/pty.c | 1 -
> drivers/tty/serial/sunsu.c | 21 +--
> drivers/usb/core/hcd-pci.c | 23 ++-
> drivers/usb/gadget/udc-core.c | 2 +-
> drivers/usb/host/xhci.c | 3 +-
> drivers/usb/host/xhci.h | 4 +-
> 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/garmin_gps.c | 7 +-
> drivers/usb/serial/io_edgeport.c | 12 +-
> drivers/usb/serial/io_ti.c | 13 +-
> 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 | 3 +-
> drivers/usb/storage/unusual_devs.h | 7 +
> drivers/vhost/net.c | 3 +-
> fs/cifs/asn1.c | 53 +-----
> fs/cifs/cifsfs.c | 24 +++
> fs/cifs/cifsfs.h | 4 +
> fs/cifs/file.c | 6 +-
> fs/ext4/balloc.c | 2 +-
> fs/ext4/ext4.h | 6 +-
> fs/ext4/extents.c | 6 +-
> fs/ext4/ialloc.c | 4 +-
> fs/ext4/inode.c | 3 +-
> fs/ext4/mballoc.c | 18 +-
> fs/ext4/resize.c | 6 +-
> fs/ext4/super.c | 4 +-
> fs/isofs/export.c | 1 +
> fs/jbd2/transaction.c | 15 +-
> fs/proc/inode.c | 12 +-
> fs/udf/namei.c | 1 +
> include/linux/efi.h | 3 +-
> include/linux/perf_event.h | 6 +
> include/linux/skbuff.h | 7 +-
> include/linux/usb/serial.h | 2 +
> include/net/inet_frag.h | 9 +
> include/net/ip_fib.h | 12 +-
> kernel/trace/ftrace.c | 4 +-
> kernel/trace/trace.c | 59 ++++--
> kernel/trace/trace.h | 7 +
> kernel/trace/trace_irqsoff.c | 19 +-
> kernel/trace/trace_sched_wakeup.c | 18 +-
> mm/hugetlb.c | 8 +-
> net/core/dev.c | 1 +
> net/core/rtnetlink.c | 3 +-
> net/dcb/dcbnl.c | 7 +
> net/ieee802154/6lowpan.h | 2 +-
> net/ipv4/inet_fragment.c | 20 +-
> net/ipv4/ip_fragment.c | 12 +-
> net/ipv4/ip_options.c | 5 +-
> net/ipv4/tcp.c | 2 +-
> net/ipv4/tcp_input.c | 6 +-
> net/ipv4/tcp_output.c | 1 -
> net/ipv6/ip6_input.c | 3 +-
> net/ipv6/netfilter/nf_conntrack_reasm.c | 11 +-
> net/ipv6/reassembly.c | 8 +-
> net/ipv6/route.c | 3 +-
> net/l2tp/l2tp_ppp.c | 1 +
> net/netlabel/netlabel_unlabeled.c | 27 ++-
> net/rds/message.c | 3 +
> net/sctp/associola.c | 2 +-
> net/sctp/sm_statefuns.c | 2 +-
> security/selinux/xfrm.c | 2 +-
> sound/pci/hda/hda_codec.c | 2 +-
> sound/pci/hda/patch_conexant.c | 8 +-
> sound/usb/mixer.c | 16 +-
> tools/hv/hv_kvp_daemon.c | 8 +-
> tools/perf/util/trace-event-parse.c | 2 -
> 111 files changed, 917 insertions(+), 516 deletions(-)
>
> --
> Ben Hutchings
> The two most common things in the universe are hydrogen and stupidity.
>
> --
> To unsubscribe from this list: send the line "unsubscribe stable" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

2013-03-26 15:36:11

by Johan Hovold

[permalink] [raw]
Subject: Re: [ 084/104] USB: serial: add modem-status-change wait queue

On Mon, Mar 25, 2013 at 2:06 AM, Ben Hutchings <[email protected]> wrote:
> 3.2-stable review patch. If anyone has any objections, please let me know.

This patch is incorrect as the wait-queue initialisation is missing. A
fix has been posted to linux-usb:

http://marc.info/?l=linux-usb&m=136428758202815&w=2

and should show up in 3.9-rc5. This patch and the following
use-after-free patches should not be applied without that fix.

Johan

> ------------------
>
> 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-03-26 19:03:57

by Ben Hutchings

[permalink] [raw]
Subject: Re: [ 000/104] 3.2.42-stable review

On Tue, Mar 26, 2013 at 10:01:58PM +0900, Satoru Takeuchi wrote:
> At Mon, 25 Mar 2013 00:34:24 +0000,
> Ben Hutchings wrote:
> >
> > This is the start of the stable review cycle for the 3.2.42 release.
> > There are 104 patches in this series, which will be posted as responses
> > to this one. If anyone has any issues with these being applied, please
> > let me know.
> >
> > Responses should be made by Wed Mar 27 01:00:00 UTC 2013.
> > Anything received after that time might be too late.
> >
> > A combined patch relative to 3.2.41 will be posted as an additional
> > response to this. A shortlog and diffstat can be found below.
>
> This kernel can be built and boot without any problem.
> Building a kernel with this kernel also works fine.
>
> - Build Machine: debian wheezy x86_64
> CPU: Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz x 4
> memory: 8GB
>
> - Test machine: debian wheezy x86_64(KVM guest on the Build Machine)
> vCPU: x2
> memory: 2GB

Thanks.

Ben.

--
Ben Hutchings
We get into the habit of living before acquiring the habit of thinking.
- Albert Camus

2013-03-27 02:35:16

by Ben Hutchings

[permalink] [raw]
Subject: Re: [ 084/104] USB: serial: add modem-status-change wait queue

On Tue, 2013-03-26 at 16:36 +0100, Johan Hovold wrote:
> On Mon, Mar 25, 2013 at 2:06 AM, Ben Hutchings <[email protected]> wrote:
> > 3.2-stable review patch. If anyone has any objections, please let me know.
>
> This patch is incorrect as the wait-queue initialisation is missing. A
> fix has been posted to linux-usb:
>
> http://marc.info/?l=linux-usb&m=136428758202815&w=2
>
> and should show up in 3.9-rc5. This patch and the following
> use-after-free patches should not be applied without that fix.
[...]

OK, I've dropped these for now.

Ben.

--
Ben Hutchings
I'm not a reverse psychological virus. Please don't copy me into your sig.


Attachments:
signature.asc (828.00 B)
This is a digitally signed message part