3.4.19-stable review
Subsystems (35)
Greg Kroah-Hartman
maintainercover 3.4.19-stable review
This is the start of the stable review cycle for the 3.4.19 release. There are 57 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat Nov 17 04:09:24 UTC 2012. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.4.19-rc1.gz
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 3.4.19-rc1
Dave Chinner <[email protected]>
xfs: fix reading of wrapped log data
Johan Hovold <[email protected]>
USB: mos7840: remove unused variable
Daniel Vetter <[email protected]>
drm/i915: clear the entire sdvo infoframe buffer
Daniel Vetter <[email protected]>
drm/i915: fixup infoframe support for sdvo
Alex Deucher <[email protected]>
drm/radeon/si: add some missing regs to the VM reg checker
Alex Deucher <[email protected]>
drm/radeon/cayman: add some missing regs to the VM reg checker
Thomas Hellstrom <[email protected]>
drm/vmwgfx: Fix a case where the code would BUG when trying to pin GMR memory
Thomas Hellstrom <[email protected]>
drm/vmwgfx: Fix hibernation device reset
Chris Ball <[email protected]>
mmc: sdhci: fix NULL dereference in sdhci_request() tuning
Thomas Gleixner <[email protected]>
futex: Handle futex_pi OWNER_DIED take over correctly
Hannes Frederic Sowa <[email protected]>
ipv6: send unsolicited neighbour advertisements to all-nodes
Eric Leblond <[email protected]>
af-packet: fix oops when socket is not present
Cyrill Gorcunov <[email protected]>
net: inet_diag -- Return error code if protocol handler is missed
Tom Parkin <[email protected]>
l2tp: fix oops in l2tp_eth_create() error path
Peter Senna Tschudin <[email protected]>
drivers/net/ethernet/nxp/lpc_eth.c: Call mdiobus_unregister before mdiobus_free
Jesper Dangaard Brouer <[email protected]>
net: fix divide by zero in tcp algorithm illinois
Hemant Kumar <[email protected]>
net: usb: Fix memory leak on Tx data path
Li RongQing <[email protected]>
ipv6: Set default hoplimit as zero.
Eric Dumazet <[email protected]>
tcp: fix FIONREAD/SIOCINQ
Eric Dumazet <[email protected]>
netlink: use kfree_rcu() in netlink_release()
Zijie Pan <[email protected]>
sctp: fix call to SCTP_CMD_PROCESS_SACK in sctp_cmd_interpreter()
Takashi Iwai <[email protected]>
ALSA: Avoid endless sleep after disconnect
Takashi Iwai <[email protected]>
ALSA: Add a reference counter to card instance
Takashi Iwai <[email protected]>
ALSA: usb-audio: Fix races at disconnection in mixer_quirks.c
Takashi Iwai <[email protected]>
ALSA: usb-audio: Use rwsem for disconnect protection
Takashi Iwai <[email protected]>
ALSA: usb-audio: Fix races at disconnection
Takashi Iwai <[email protected]>
ALSA: PCM: Fix some races at disconnection
Jean Delvare <[email protected]>
hwmon: (w83627ehf) Force initial bank selection
Ilija Hadzic <[email protected]>
drm: restore open_count if drm_setup fails
Trond Myklebust <[email protected]>
NFS: Fix Oopses in nfs_lookup_revalidate and nfs4_lookup_revalidate
NeilBrown <[email protected]>
NFS: fix bug in legacy DNS resolver.
J. Bruce Fields <[email protected]>
nfsd: add get_uint for u32's
Trond Myklebust <[email protected]>
NFSv4.1: We must release the sequence id when we fail to get a session slot
Trond Myklebust <[email protected]>
NFSv4: nfs4_locku_done must release the sequence id
Ben Hutchings <[email protected]>
nfs: Show original device name verbatim in /proc/*/mount{s,info}Scott Mayhew <[email protected]>
nfsv3: Make v3 mounts fail with ETIMEDOUTs instead EIO on mountd timeouts
Antonio Quartulli <[email protected]>
mac80211: fix SSID copy on IBSS JOIN
Johannes Berg <[email protected]>
mac80211: make sure data is accessible in EAPOL check
Johannes Berg <[email protected]>
mac80211: verify that skb data is present
Johannes Berg <[email protected]>
mac80211: check management frame header length
Dave Airlie <[email protected]>
drm/udl: fix stride issues scanning out stride != width*bpp
Egbert Eich <[email protected]>
DRM/Radeon: Fix Load Detection on legacy primary DAC.
Javier Cardona <[email protected]>
mac80211: don't inspect Sequence Control field on control frames
Javier Cardona <[email protected]>
mac80211: Only process mesh config header on frames that RA_MATCH
Johannes Berg <[email protected]>
mac80211: use blacklist for duplicate IE check
Johannes Berg <[email protected]>
wireless: drop invalid mesh address extension frames
Felix Fietkau <[email protected]>
cfg80211: fix antenna gain handling
Steve Hodgson <[email protected]>
target: Fix incorrect usage of nested IRQ spinlocks in ABORT_TASK path
Roland Dreier <[email protected]>
iscsi-target: Fix missed wakeup race in TX thread
Roland Dreier <[email protected]>
target: Avoid integer overflow in se_dev_align_max_sectors()
Roland Dreier <[email protected]>
target: Don't return success from module_init() if setup fails
Stanislaw Gruszka <[email protected]>
rt2800: validate step value for temperature compensation
Sven Eckelmann <[email protected]>
ath9k: Test for TID only in BlockAcks while checking tx status
Felix Fietkau <[email protected]>
ath9k: fix stale pointers potentially causing access to free'd skbs
Rolf Eike Beer <[email protected]>
Input: tsc40 - remove wrong announcement of pressure support
Konrad Rzeszutek Wilk <[email protected]>
xen/mmu: Use Xen specific TLB flush instead of the generic one.
David Vrabel <[email protected]>
xen/gntdev: don't leak memory from IOCTL_GNTDEV_MAP_GRANT_REF
-------------
Diffstat:
Makefile | 4 +- arch/x86/xen/mmu.c | 21 +++++++- drivers/gpu/drm/drm_fops.c | 5 +- drivers/gpu/drm/i915/intel_drv.h | 4 +- drivers/gpu/drm/i915/intel_sdvo.c | 59 ++++++++++++++------ drivers/gpu/drm/i915/intel_sdvo_regs.h | 2 + drivers/gpu/drm/radeon/evergreen_cs.c | 3 ++ drivers/gpu/drm/radeon/evergreend.h | 4 ++ drivers/gpu/drm/radeon/radeon_legacy_encoders.c | 1 + drivers/gpu/drm/radeon/si.c | 1 + drivers/gpu/drm/radeon/sid.h | 1 + drivers/gpu/drm/udl/udl_drv.h | 2 +- drivers/gpu/drm/udl/udl_fb.c | 12 +++-- drivers/gpu/drm/udl/udl_transfer.c | 5 +- drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 5 ++ drivers/hwmon/w83627ehf.c | 1 + drivers/input/touchscreen/tsc40.c | 1 - drivers/mmc/host/sdhci.c | 23 ++++---- drivers/net/ethernet/nxp/lpc_eth.c | 1 + drivers/net/usb/usbnet.c | 3 ++ drivers/net/wireless/ath/ath9k/xmit.c | 10 +++- drivers/net/wireless/rt2x00/rt2800lib.c | 2 +- drivers/target/iscsi/iscsi_target.c | 4 +- drivers/target/iscsi/iscsi_target_core.h | 1 + drivers/target/iscsi/iscsi_target_login.c | 1 + drivers/target/iscsi/iscsi_target_util.c | 22 +++++++- drivers/target/iscsi/iscsi_target_util.h | 1 + drivers/target/target_core_configfs.c | 3 +- drivers/target/target_core_device.c | 18 +++---- drivers/target/target_core_tmr.c | 6 +-- drivers/usb/serial/mos7840.c | 1 - drivers/xen/gntdev.c | 36 +++++++------ fs/nfs/dir.c | 4 +- fs/nfs/dns_resolve.c | 5 +- fs/nfs/internal.h | 5 +- fs/nfs/mount_clnt.c | 2 +- fs/nfs/namespace.c | 19 +++++-- fs/nfs/nfs4namespace.c | 3 +- fs/nfs/nfs4proc.c | 37 ++++++++----- fs/nfs/super.c | 2 +- fs/nfsd/export.c | 6 +-- fs/xfs/xfs_log_recover.c | 2 +- include/linux/sunrpc/cache.h | 16 ++++++ include/net/cfg80211.h | 9 ++++ include/sound/core.h | 3 ++ include/trace/events/xen.h | 8 +++ kernel/futex.c | 41 +++++++------- net/core/dev.c | 2 +- net/ipv4/inet_diag.c | 5 +- net/ipv4/tcp.c | 8 ++- net/ipv4/tcp_illinois.c | 8 +-- net/ipv6/ndisc.c | 3 +- net/ipv6/route.c | 4 +- net/l2tp/l2tp_eth.c | 1 + net/mac80211/ibss.c | 2 +- net/mac80211/rx.c | 72 +++++++++++++++++++------ net/mac80211/util.c | 39 +++++++++++--- net/netlink/af_netlink.c | 19 +++++-- net/sctp/sm_sideeffect.c | 3 +- net/wireless/core.c | 3 +- net/wireless/util.c | 14 ++--- sound/core/compress_offload.c | 9 +++- sound/core/control.c | 5 ++ sound/core/hwdep.c | 12 ++++- sound/core/init.c | 50 ++++++++++------- sound/core/oss/mixer_oss.c | 10 +++- sound/core/oss/pcm_oss.c | 6 +++ sound/core/pcm.c | 13 ++++- sound/core/pcm_native.c | 33 +++++++++--- sound/core/rawmidi.c | 26 ++++++++- sound/core/sound.c | 11 +++- sound/core/sound_oss.c | 10 +++- sound/usb/card.c | 12 +++-- sound/usb/card.h | 1 + sound/usb/endpoint.c | 9 ++-- sound/usb/mixer.c | 65 ++++++++++++++-------- sound/usb/mixer_quirks.c | 37 +++++++++++-- sound/usb/pcm.c | 35 ++++++++---- sound/usb/proc.c | 4 +- sound/usb/usbaudio.h | 2 +- 81 files changed, 697 insertions(+), 263 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/57 xen/gntdev: dont leak memory from IOCTL_GNTDEV_MAP_GRANT_REF
3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Vrabel <[email protected]>
commit a67baeb77375199bbd842fa308cb565164dd1f19 upstream.
map->kmap_ops allocated in gntdev_alloc_map() wasn't freed by gntdev_put_map().
Add a gntdev_free_map() helper function to free everything allocated by gntdev_alloc_map().
--- drivers/xen/gntdev.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-)
drivers/xen/gntdev.c +19 -17
@@ -105,6 +105,21 @@ static void gntdev_print_maps(struct gnt#endif } +static void gntdev_free_map (struct grant_map *map) +{ +if (map ==NULL ) +return ; + +if (map->pages) +free_xenballooned_pages (map->count, map->pages); +kfree (map->pages); +kfree (map->grants); +kfree (map->map_ops); +kfree (map->unmap_ops); +kfree (map->kmap_ops); +kfree (map); +} +static struct grant_map *gntdev_alloc_map (struct gntdev_priv *priv,int count) {struct grant_map *add;
@@ -142,12 +157,7 @@ static struct grant_map *gntdev_alloc_mareturn add; err: -kfree (add->pages); -kfree (add->grants); -kfree (add->map_ops); -kfree (add->unmap_ops); -kfree (add->kmap_ops); -kfree (add); +gntdev_free_map (add);return NULL ; }
@@ -198,17 +208,9 @@ static void gntdev_put_map(struct grant_evtchn_put (map->notify.event); } -if (map->pages) { -if (!use_ptemod) -unmap_grant_pages (map,0 , map->count); - -free_xenballooned_pages (map->count, map->pages); - } -kfree (map->pages); -kfree (map->grants); -kfree (map->map_ops); -kfree (map->unmap_ops); -kfree (map); +if (map->pages && !use_ptemod) +unmap_grant_pages (map,0 , map->count); +gntdev_free_map (map); }/* ------------------------------------------------------------------ */
Greg Kroah-Hartman
maintainerPATCH 2/57 xen/mmu: Use Xen specific TLB flush instead of the generic one.
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Rzeszutek Wilk <[email protected]>
commit 95a7d76897c1e7243d4137037c66d15cbf2cce76 upstream.
As Mukesh explained it, the MMUEXT_TLB_FLUSH_ALL allows the hypervisor to do a TLB flush on all active vCPUs. If instead we were using the generic one (which ends up being xen_flush_tlb) we end up making the MMUEXT_TLB_FLUSH_LOCAL hypercall. But before we make that hypercall the kernel will IPI all of the vCPUs (even those that were asleep from the hypervisor perspective). The end result is that we needlessly wake them up and do a TLB flush when we can just let the hypervisor do it correctly.
This patch gives around 50% speed improvement when migrating idle guest's from one host to another.
Oracle-bug: 14630170
--- arch/x86/xen/mmu.c | 21 ++++++++++++++++++++- include/trace/events/xen.h | 8 ++++++++ 2 files changed, 28 insertions(+), 1 deletion(-)
arch/x86/xen/mmu.c +20 -1
@@ -1203,6 +1203,25 @@ unsigned long xen_read_cr2_direct(void)return this_cpu_read (xen_vcpu_info.arch.cr2); } +void xen_flush_tlb_all (void ) +{ +struct mmuext_op *op; +struct multicall_space mcs; + +trace_xen_mmu_flush_tlb_all (0 ); + +preempt_disable (); + + mcs =xen_mc_entry (sizeof (*op)); + + op = mcs.args; + op->cmd =MMUEXT_TLB_FLUSH_ALL ; +MULTI_mmuext_op (mcs.mc, op,1 ,NULL ,DOMID_SELF ); + +xen_mc_issue (PARAVIRT_LAZY_MMU ); + +preempt_enable (); +}static void xen_flush_tlb (void ) {struct mmuext_op *op;
@@ -2364,7 +2383,7 @@ int xen_remap_domain_mfn_range(struct vm err =0 ; out: -flush_tlb_all (); +xen_flush_tlb_all ();return err; }
include/trace/events/xen.h +8 -0
@@ -377,6 +377,14 @@ DECLARE_EVENT_CLASS(xen_mmu_pgd,DEFINE_XEN_MMU_PGD_EVENT (xen_mmu_pgd_pin);DEFINE_XEN_MMU_PGD_EVENT (xen_mmu_pgd_unpin); +TRACE_EVENT (xen_mmu_flush_tlb_all, + TP_PROTO(int x), +TP_ARGS (x), +TP_STRUCT__entry (__array (char, x,0 )), +TP_fast_assign ((void )x), +TP_printk ("%s" ,"" ) + ); + TRACE_EVENT(xen_mmu_flush_tlb, TP_PROTO(int x), TP_ARGS(x),
Greg Kroah-Hartman
maintainerPATCH 3/57 Input: tsc40 - remove wrong announcement of pressure support
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rolf Eike Beer <[email protected]>
commit 32ed1911fc79908d704023317d4ddeb3883fd07e upstream.
The tsc40 driver announces it supports the pressure event, but will never send one. The announcement will cause tslib to wait for such events and sending all touch events with a pressure of 0. Removing the announcement will make tslib fall back to emulating the pressure on touch events so everything works as expected.
--- drivers/input/touchscreen/tsc40.c | 1 - 1 file changed, 1 deletion(-)
drivers/input/touchscreen/tsc40.c +0 -1
@@ -107,7 +107,6 @@ static int tsc_connect(struct serio *ser__set_bit (BTN_TOUCH , input_dev->keybit);input_set_abs_params (ptsc->dev,ABS_X ,0 ,0x3ff ,0 ,0 );input_set_abs_params (ptsc->dev,ABS_Y ,0 ,0x3ff ,0 ,0 ); -input_set_abs_params (ptsc->dev,ABS_PRESSURE ,0 ,0 ,0 ,0 );serio_set_drvdata (serio, ptsc);
Greg Kroah-Hartman
maintainerPATCH 4/57 ath9k: fix stale pointers potentially causing access to freed skbs
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau <[email protected]>
commit 8c6e30936a7893a85f6222084f0f26aceb81137a upstream.
bf->bf_next is only while buffers are chained as part of an A-MPDU in the tx queue. When a tid queue is flushed (e.g. on tearing down an aggregation session), frames can be enqueued again as normal transmission, without bf_next being cleared. This can lead to the old pointer being dereferenced again later.
This patch might fix crashes and "Failed to stop TX DMA!" messages.
--- drivers/net/wireless/ath/ath9k/xmit.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/wireless/ath/ath9k/xmit.c +2 -0
@@ -337,6 +337,7 @@ static struct ath_buf *ath_tx_get_buffer } bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); + bf->bf_next =NULL ;list_del (&bf->list);spin_unlock_bh (&sc->tx.txbuflock);
@@ -1760,6 +1761,7 @@ static void ath_tx_send_normal(struct atlist_add_tail (&bf->list, &bf_head); bf->bf_state.bf_type =0 ; + bf->bf_next =NULL ; bf->bf_lastbf = bf;ath_tx_fill_desc (sc, bf, txq, fi->framelen);ath_tx_txqaddbuf (sc, txq, &bf_head, false);
Greg Kroah-Hartman
maintainerPATCH 5/57 ath9k: Test for TID only in BlockAcks while checking tx status
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit 6fe7cc71bbf3a0bc28c9cec3c00bc11e81344412 upstream.
The ath9k xmit functions for AMPDUs can send frames as non-aggregate in case only one frame is currently available. The client will then answer using a normal Ack instead of a BlockAck. This acknowledgement has no TID stored and therefore the hardware is not able to provide us the corresponding TID.
The TID set by the hardware in the tx status descriptor has to be seen as undefined and not as a valid TID value for normal acknowledgements. Doing otherwise results in a massive amount of retransmissions and stalls of connections.
Users may experience low bandwidth and complete connection stalls in environments with transfers using multiple TIDs.
This regression was introduced in b11b160defc48e4daa283f785192ea3a23a51f8e ("ath9k: validate the TID in the tx status information").
--- drivers/net/wireless/ath/ath9k/xmit.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath9k/xmit.c +6 -2
@@ -419,7 +419,7 @@ static void ath_tx_complete_aggr(structu16 seq_st =0 , acked_cnt =0 , txfail_cnt =0 , seq_first;u32 ba[WME_BA_BMP_SIZE >>5 ];int isaggr, txfail, txpending, sendbar =0 , needreset =0 , nbad =0 ; -bool rc_update = true; +bool rc_update = true, isba;struct ieee80211_tx_rate rates[4 ];struct ath_frame_info *fi;int nframes;
@@ -463,13 +463,17 @@ static void ath_tx_complete_aggr(struct tidno =ieee80211_get_qos_ctl (hdr)[0 ] &IEEE80211_QOS_CTL_TID_MASK ; tid =ATH_AN_2_TID (an, tidno); seq_first = tid->seq_start; + isba = ts->ts_flags &ATH9K_TX_BA ;/* * The hardware occasionally sends a tx status for the wrong TID. * In this case, the BA status cannot be considered valid and all * subframes need to be retransmitted +* +* Only BlockAcks have a TID and therefore normal Acks cannot be +* checked */ -if (tidno != ts->tid) +if (isba && tidno != ts->tid) txok = false; isaggr =bf_isaggr (bf);
Greg Kroah-Hartman
maintainerPATCH 6/57 rt2800: validate step value for temperature compensation
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stanislaw Gruszka <[email protected]>
commit bf7e1abe434ba9e22e8dc04a4cba4ab504b788b8 upstream.
Some hardware has correct (!= 0xff) value of tssi_bounds[4] in the EEPROM, but step is equal to 0xff. This results on ridiculous delta calculations and completely broke TX power settings.
--- drivers/net/wireless/rt2x00/rt2800lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/rt2x00/rt2800lib.c +1 -1
@@ -2235,7 +2235,7 @@ static int rt2800_get_gain_calibration_d/* * Check if temperature compensation is supported. */ -if (tssi_bounds[4 ] ==0xff ) +if (tssi_bounds[4 ] ==0xff || step ==0xff )return 0 ;/*
Greg Kroah-Hartman
maintainerPATCH 7/57 target: Dont return success from module_init() if setup fails
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roland Dreier <[email protected]>
commit 0d0f9dfb31e0a6c92063e235417b42df185b3275 upstream.
If the call to core_dev_release_virtual_lun0() fails, then nothing sets ret to anything other than 0, so even though everything is torn down and freed, target_core_init_configfs() will seem to succeed and the module will be loaded. Fix this by passing the return value on up the chain.
--- drivers/target/target_core_configfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/target/target_core_configfs.c +2 -1
@@ -3197,7 +3197,8 @@ static int __init target_core_init_confiif (ret <0 ) goto out; -if (core_dev_setup_virtual_lun0 () <0 ) + ret =core_dev_setup_virtual_lun0 (); +if (ret <0 ) goto out;return 0 ;
Greg Kroah-Hartman
maintainerPATCH 8/57 target: Avoid integer overflow in se_dev_align_max_sectors()
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roland Dreier <[email protected]>
commit 3e03989b5868acf69a391a424dc71fcd6cc48167 upstream.
The expression (max_sectors * block_size) might overflow a u32 (indeed, since iblock sets max_hw_sectors to UINT_MAX, it is guaranteed to overflow and end up with a much-too-small result in many common cases). Fix this by doing an equivalent calculation that doesn't require multiplication.
While we're touching this code, avoid splitting a printk format across two lines and use pr_info(...) instead of printk(KERN_INFO ...).
--- drivers/target/target_core_device.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
drivers/target/target_core_device.c +9 -9
@@ -826,20 +826,20 @@ int se_dev_check_shutdown(struct se_deviu32 se_dev_align_max_sectors (u32 max_sectors,u32 block_size) { -u32 tmp, aligned_max_sectors; +u32 aligned_max_sectors; +u32 alignment;/* * Limit max_sectors to a PAGE_SIZE aligned value for modern * transport_allocate_data_tasks() operation. */ - tmp =rounddown ((max_sectors * block_size),PAGE_SIZE ); - aligned_max_sectors = (tmp / block_size); -if (max_sectors != aligned_max_sectors) { -printk (KERN_INFO "Rounding down aligned max_sectors from %u" -" to %u\n" , max_sectors, aligned_max_sectors); -return aligned_max_sectors; - } + alignment =max (1ul ,PAGE_SIZE / block_size); + aligned_max_sectors =rounddown (max_sectors, alignment); -return max_sectors; +if (max_sectors != aligned_max_sectors) +pr_info ("Rounding down aligned max_sectors from %u to %u\n" , + max_sectors, aligned_max_sectors); + +return aligned_max_sectors; } void se_dev_set_default_attribs(
Greg Kroah-Hartman
maintainerPATCH 9/57 iscsi-target: Fix missed wakeup race in TX thread
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roland Dreier <[email protected]>
commit d5627acba9ae584cf4928af19f7ddf5f6837de32 upstream.
The sleeping code in iscsi_target_tx_thread() is susceptible to the classic missed wakeup race:
- TX thread finishes handle_immediate_queue() and handle_response_queue(), thinks both queues are empty.
- Another thread adds a queue entry and does wake_up_process(), which does nothing because the TX thread is still awake.
- TX thread does schedule_timeout() and sleeps forever.
In practice this can kill an iSCSI connection if for example an initiator does single-threaded writes and the target misses the wakeup window when queueing an R2T; in this case the connection will be stuck until the initiator loses patience and does some task management operation (or kills the connection entirely).
Fix this by converting to wait_event_interruptible(), which does not suffer from this sort of race.
--- drivers/target/iscsi/iscsi_target.c | 4 +++- drivers/target/iscsi/iscsi_target_core.h | 1 + drivers/target/iscsi/iscsi_target_login.c | 1 + drivers/target/iscsi/iscsi_target_util.c | 22 ++++++++++++++++++++-- drivers/target/iscsi/iscsi_target_util.h | 1 + 5 files changed, 26 insertions(+), 3 deletions(-)
drivers/target/iscsi/iscsi_target.c +3 -1
@@ -3514,7 +3514,9 @@ restart:*/ iscsit_thread_check_cpumask (conn, current,1 ); -schedule_timeout_interruptible (MAX_SCHEDULE_TIMEOUT ); +wait_event_interruptible (conn->queues_wq, + !iscsit_conn_all_queues_empty (conn) || + ts->status ==ISCSI_THREAD_SET_RESET );if ((ts->status ==ISCSI_THREAD_SET_RESET ) ||signal_pending (current))
drivers/target/iscsi/iscsi_target_core.h +1 -0
@@ -491,6 +491,7 @@ struct iscsi_tmr_req { };struct iscsi_conn { +wait_queue_head_t queues_wq;/* Authentication Successful for this connection */ u8 auth_complete;/* State connection is currently in */
drivers/target/iscsi/iscsi_target_login.c +1 -0
@@ -45,6 +45,7 @@ extern spinlock_t sess_idr_lock;static int iscsi_login_init_conn (struct iscsi_conn *conn) { +init_waitqueue_head (&conn->queues_wq);INIT_LIST_HEAD (&conn->conn_list);INIT_LIST_HEAD (&conn->conn_cmd_list);INIT_LIST_HEAD (&conn->immed_queue_list);
drivers/target/iscsi/iscsi_target_util.c +20 -2
@@ -656,7 +656,7 @@ void iscsit_add_cmd_to_immediate_queue(atomic_set (&conn->check_immediate_queue,1 );spin_unlock_bh (&conn->immed_queue_lock); -wake_up_process (conn->thread_set->tx_thread); +wake_up (&conn->queues_wq); }struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue (struct iscsi_conn *conn)
@@ -730,7 +730,7 @@ void iscsit_add_cmd_to_response_queue(atomic_inc (&cmd->response_queue_count);spin_unlock_bh (&conn->response_queue_lock); -wake_up_process (conn->thread_set->tx_thread); +wake_up (&conn->queues_wq); }struct iscsi_queue_req *iscsit_get_cmd_from_response_queue (struct iscsi_conn *conn)
@@ -784,6 +784,24 @@ static void iscsit_remove_cmd_from_respo } } +bool iscsit_conn_all_queues_empty (struct iscsi_conn *conn) +{ +bool empty; + +spin_lock_bh (&conn->immed_queue_lock); + empty =list_empty (&conn->immed_queue_list); +spin_unlock_bh (&conn->immed_queue_lock); + +if (!empty) +return empty; + +spin_lock_bh (&conn->response_queue_lock); + empty =list_empty (&conn->response_queue_list); +spin_unlock_bh (&conn->response_queue_lock); + +return empty; +} +void iscsit_free_queue_reqs_for_conn (struct iscsi_conn *conn) {struct iscsi_queue_req *qr, *qr_tmp;
drivers/target/iscsi/iscsi_target_util.h +1 -0
@@ -28,6 +28,7 @@ extern struct iscsi_queue_req *iscsit_geextern void iscsit_add_cmd_to_response_queue (struct iscsi_cmd *,struct iscsi_conn *,u8 );extern struct iscsi_queue_req *iscsit_get_cmd_from_response_queue (struct iscsi_conn *);extern void iscsit_remove_cmd_from_tx_queues (struct iscsi_cmd *,struct iscsi_conn *); +extern bool iscsit_conn_all_queues_empty (struct iscsi_conn *);extern void iscsit_free_queue_reqs_for_conn (struct iscsi_conn *);extern void iscsit_release_cmd (struct iscsi_cmd *);extern void iscsit_free_cmd (struct iscsi_cmd *);
Greg Kroah-Hartman
maintainerPATCH 10/57 target: Fix incorrect usage of nested IRQ spinlocks in ABORT_TASK path
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve Hodgson <[email protected]>
commit ab74b3d62f05192bf8fb8f169e7999d1183b2e08 upstream.
This patch changes core_tmr_abort_task() to use spin_lock -> spin_unlock around se_cmd->t_state_lock while spin_lock_irqsave is held via se_sess->sess_cmd_lock.
--- drivers/target/target_core_tmr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/target/target_core_tmr.c +3 -3
@@ -140,15 +140,15 @@ void core_tmr_abort_task(printk ("ABORT_TASK: Found referenced %s task_tag: %u\n" , se_cmd->se_tfo->get_fabric_name (), ref_tag); -spin_lock_irq (&se_cmd->t_state_lock); +spin_lock (&se_cmd->t_state_lock);if (se_cmd->transport_state &CMD_T_COMPLETE ) {printk ("ABORT_TASK: ref_tag: %u already complete, skipping\n" , ref_tag); -spin_unlock_irq (&se_cmd->t_state_lock); +spin_unlock (&se_cmd->t_state_lock);spin_unlock_irqrestore (&se_sess->sess_cmd_lock, flags); goto out; } se_cmd->transport_state |=CMD_T_ABORTED ; -spin_unlock_irq (&se_cmd->t_state_lock); +spin_unlock (&se_cmd->t_state_lock);list_del_init (&se_cmd->se_cmd_list);kref_get (&se_cmd->cmd_kref);
Greg Kroah-Hartman
maintainerPATCH 11/57 cfg80211: fix antenna gain handling
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau <[email protected]>
commit c4a9fafc77a5318f5ed26c509bbcddf03e18c201 upstream.
No driver initializes chan->max_antenna_gain to something sensible, and the only place where it is being used right now is inside ath9k. This leads to ath9k potentially using less tx power than it can use, which can decrease performance/range in some rare cases.
Rather than going through every single driver, this patch initializes chan->orig_mag in wiphy_register(), ignoring whatever value the driver left in there. If a driver for some reason wishes to limit it independent from regulatory rulesets, it can do so internally.
--- net/wireless/core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
net/wireless/core.c +1 -2
@@ -552,8 +552,7 @@ int wiphy_register(struct wiphy *wiphy)for (i =0 ; i < sband->n_channels; i++) { sband->channels[i].orig_flags = sband->channels[i].flags; - sband->channels[i].orig_mag = - sband->channels[i].max_antenna_gain; + sband->channels[i].orig_mag =INT_MAX ; sband->channels[i].orig_mpwr = sband->channels[i].max_power; sband->channels[i].band = band;
Greg Kroah-Hartman
maintainerPATCH 12/57 wireless: drop invalid mesh address extension frames
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
commit 7dd111e8ee10cc6816669eabcad3334447673236 upstream.
The mesh header can have address extension by a 4th or a 5th and 6th address, but never both. Drop such frames in 802.11 -> 802.3 conversion along with any frames that have the wrong extension.
--- net/wireless/util.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
net/wireless/util.c +6 -5
@@ -293,18 +293,15 @@ EXPORT_SYMBOL(ieee80211_get_hdrlen_from_static int ieee80211_get_mesh_hdrlen (struct ieee80211s_hdr *meshhdr) {int ae = meshhdr->flags &MESH_FLAGS_AE ; -/* 7.1.3.5a.2 */ +/* 802.11-2012, 8.2.4.7.3 */ switch (ae) { +default :case 0 :return 6 ;case MESH_FLAGS_AE_A4 :return 12 ;case MESH_FLAGS_AE_A5_A6 :return 18 ; -case (MESH_FLAGS_AE_A4 |MESH_FLAGS_AE_A5_A6 ): -return 24 ; -default : -return 6 ; } }
@@ -354,6 +351,8 @@ int ieee80211_data_to_8023(struct sk_buf/* make sure meshdr->flags is on the linear part */ if (!pskb_may_pull (skb, hdrlen +1 ))return -1 ; +if (meshdr->flags &MESH_FLAGS_AE_A4 ) +return -1 ;if (meshdr->flags &MESH_FLAGS_AE_A5_A6 ) { skb_copy_bits(skb, hdrlen + offsetof(struct ieee80211s_hdr, eaddr1),
@@ -378,6 +377,8 @@ int ieee80211_data_to_8023(struct sk_buf/* make sure meshdr->flags is on the linear part */ if (!pskb_may_pull (skb, hdrlen +1 ))return -1 ; +if (meshdr->flags &MESH_FLAGS_AE_A5_A6 ) +return -1 ;if (meshdr->flags &MESH_FLAGS_AE_A4 ) skb_copy_bits(skb, hdrlen + offsetof(struct ieee80211s_hdr, eaddr1),
Greg Kroah-Hartman
maintainerPATCH 13/57 mac80211: use blacklist for duplicate IE check
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
commit 9690fb169b433a66485c808e4fc352b8a0f8d866 upstream.
Instead of the current whitelist which accepts duplicates only for the quiet and vendor IEs, use a blacklist of all IEs (that we currently parse) that can't be duplicated.
This avoids detecting a beacon as corrupt in the future when new IEs are added that can be duplicated.
--- net/mac80211/util.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-)
net/mac80211/util.c +32 -7
@@ -592,13 +592,38 @@ u32 ieee802_11_parse_elems_crc(u8 *startbreak ; } -if (id !=WLAN_EID_VENDOR_SPECIFIC && - id !=WLAN_EID_QUIET && -test_bit (id, seen_elems)) { - elems->parse_error = true; - left -= elen; - pos += elen; -continue ; +switch (id) { +case WLAN_EID_SSID : +case WLAN_EID_SUPP_RATES : +case WLAN_EID_FH_PARAMS : +case WLAN_EID_DS_PARAMS : +case WLAN_EID_CF_PARAMS : +case WLAN_EID_TIM : +case WLAN_EID_IBSS_PARAMS : +case WLAN_EID_CHALLENGE : +case WLAN_EID_RSN : +case WLAN_EID_ERP_INFO : +case WLAN_EID_EXT_SUPP_RATES : +case WLAN_EID_HT_CAPABILITY : +case WLAN_EID_MESH_ID : +case WLAN_EID_MESH_CONFIG : +case WLAN_EID_PEER_MGMT : +case WLAN_EID_PREQ : +case WLAN_EID_PREP : +case WLAN_EID_PERR : +case WLAN_EID_RANN : +case WLAN_EID_CHANNEL_SWITCH : +case WLAN_EID_EXT_CHANSWITCH_ANN : +case WLAN_EID_COUNTRY : +case WLAN_EID_PWR_CONSTRAINT : +case WLAN_EID_TIMEOUT_INTERVAL : +if (test_bit (id, seen_elems)) { + elems->parse_error = true; + left -= elen; + pos += elen; +continue ; + } +break ; }if (calc_crc && id <64 && (filter & (1ULL << id)))
Greg Kroah-Hartman
maintainerPATCH 14/57 mac80211: Only process mesh config header on frames that RA_MATCH
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Cardona <[email protected]>
commit 555cb715be8ef98b8ec362b23dfc254d432a35b1 upstream.
Doing otherwise is wrong, and may wreak havoc on the mpp tables, specially if the frame is encrypted.
--- net/mac80211/rx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
net/mac80211/rx.c +2 -4
@@ -1900,7 +1900,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata))return RX_DROP_MONITOR ; -if (!ieee80211_is_data (hdr->frame_control)) +if (!ieee80211_is_data (hdr->frame_control) || + !(status->rx_flags &IEEE80211_RX_RA_MATCH ))return RX_CONTINUE ;if (!mesh_hdr->ttl)
@@ -1944,9 +1945,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 }skb_set_queue_mapping (skb, q); -if (!(status->rx_flags &IEEE80211_RX_RA_MATCH )) - goto out; -if (!--mesh_hdr->ttl) {IEEE80211_IFSTA_MESH_CTR_INC (ifmsh, dropped_frames_ttl);return RX_DROP_MONITOR ;
Greg Kroah-Hartman
maintainerPATCH 15/57 mac80211: dont inspect Sequence Control field on control frames
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Cardona <[email protected]>
commit f7fbf70ee9db6da6033ae50d100e017ac1f26555 upstream.
Per IEEE Std. 802.11-2012, Sec 8.2.4.4.1, the sequence Control field is not present in control frames. We noticed this problem when processing Block Ack Requests.
--- net/mac80211/rx.c | 4 ++++ 1 file changed, 4 insertions(+)
net/mac80211/rx.c +4 -0
@@ -1465,6 +1465,10 @@ ieee80211_rx_h_defragment(struct ieee802 hdr = (struct ieee80211_hdr *)rx->skb->data; fc = hdr->frame_control; + +if (ieee80211_is_ctl (fc)) +return RX_CONTINUE ; + sc =le16_to_cpu (hdr->seq_ctrl); frag = sc &IEEE80211_SCTL_FRAG ;
Greg Kroah-Hartman
maintainerPATCH 16/57 DRM/Radeon: Fix Load Detection on legacy primary DAC.
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Egbert Eich <[email protected]>
commit 83325d072185899b706de2956170b246585aaec9 upstream.
An uninitialized variable led to broken load detection.
--- drivers/gpu/drm/radeon/radeon_legacy_encoders.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/radeon/radeon_legacy_encoders.c +1 -0
@@ -650,6 +650,7 @@ static enum drm_connector_status radeon_ tmp |=RADEON_DAC_RANGE_CNTL_PS2 |RADEON_DAC_CMP_EN ;WREG32 (RADEON_DAC_CNTL , tmp); + tmp = dac_macro_cntl; tmp &= ~(RADEON_DAC_PDWN_R |RADEON_DAC_PDWN_G |RADEON_DAC_PDWN_B );
Greg Kroah-Hartman
maintainerPATCH 17/57 drm/udl: fix stride issues scanning out stride != width*bpp
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Airlie <[email protected]>
commit 3916e1d71b62b120888aa50bcc8d9a6200fc19a7 upstream.
When buffer sharing with the i915 and using a 1680x1050 monitor, the i915 gives is a 6912 buffer for the 6720 width, the code doesn't render this properly as it uses one value to set the base address for reading from the vmap and for where to start on the device.
This fixes it by calculating the values correctly for the device and for the pixmap. No idea how I haven't seen this before now.
--- drivers/gpu/drm/udl/udl_drv.h | 2 +- drivers/gpu/drm/udl/udl_fb.c | 12 +++++++----- drivers/gpu/drm/udl/udl_transfer.c | 5 +++-- 3 files changed, 11 insertions(+), 8 deletions(-)
drivers/gpu/drm/udl/udl_drv.h +1 -1
@@ -103,7 +103,7 @@ udl_fb_user_fb_create(struct drm_deviceint udl_render_hline (struct drm_device *dev,int bpp,struct urb **urb_ptr,const char *front,char **urb_buf_ptr, -u32 byte_offset,u32 byte_width, +u32 byte_offset,u32 device_byte_offset,u32 byte_width,int *ident_ptr,int *sent_ptr); int udl_dumb_create(struct drm_file *file_priv,
drivers/gpu/drm/udl/udl_fb.c +7 -5
@@ -114,9 +114,10 @@ static void udlfb_dpy_deferred_io(structlist_for_each_entry (cur, &fbdefio->pagelist, lru) {if (udl_render_hline (dev, (ufbdev->ufb.base.bits_per_pixel /8 ), - &urb, (char *) info->fix.smem_start, - &cmd, cur->index <<PAGE_SHIFT , -PAGE_SIZE , &bytes_identical, &bytes_sent)) + &urb, (char *) info->fix.smem_start, + &cmd, cur->index <<PAGE_SHIFT , + cur->index <<PAGE_SHIFT , +PAGE_SIZE , &bytes_identical, &bytes_sent)) goto error; bytes_rendered +=PAGE_SIZE ; }
@@ -178,10 +179,11 @@ int udl_handle_damage(struct udl_framebufor (i = y; i < y + height ; i++) {const int line_offset = fb->base.pitches[0 ] * i;const int byte_offset = line_offset + (x * bpp); - +const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp);if (udl_render_hline (dev, bpp, &urb, (char *) fb->obj->vmapping, - &cmd, byte_offset, width * bpp, + &cmd, byte_offset, dev_byte_offset, + width * bpp, &bytes_identical, &bytes_sent)) goto error; }
drivers/gpu/drm/udl/udl_transfer.c +3 -2
@@ -213,11 +213,12 @@ static void udl_compress_hline16(*/ int udl_render_hline (struct drm_device *dev,int bpp,struct urb **urb_ptr,const char *front,char **urb_buf_ptr, -u32 byte_offset,u32 byte_width, +u32 byte_offset,u32 device_byte_offset, +u32 byte_width,int *ident_ptr,int *sent_ptr) {const u8 *line_start, *line_end, *next_pixel; -u32 base16 =0 + (byte_offset / bpp) *2 ; +u32 base16 =0 + (device_byte_offset / bpp) *2 ;struct urb *urb = *urb_ptr;u8 *cmd = *urb_buf_ptr;u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length;
Greg Kroah-Hartman
maintainerPATCH 18/57 mac80211: check management frame header length
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
commit 4a4f1a5808c8bb0b72a4f6e5904c53fb8c9cd966 upstream.
Due to pskb_may_pull() checking the skb length, all non-management frames are checked on input whether their 802.11 header is fully present. Also add that check for management frames and remove a check that is now duplicate. This prevents accessing skb data beyond the frame end.
--- net/mac80211/rx.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
net/mac80211/rx.c +8 -4
@@ -1473,7 +1473,6 @@ ieee80211_rx_h_defragment(struct ieee802 frag = sc &IEEE80211_SCTL_FRAG ;if (likely ((!ieee80211_has_morefrags (fc) && frag ==0 ) || - (rx->skb)->len <24 ||is_multicast_ether_addr (hdr->addr1))) {/* not fragmented */ goto out;
@@ -2929,10 +2928,15 @@ static void __ieee80211_rx_handle_packet test_bit(SCAN_SW_SCANNING, &local->scanning))) status->rx_flags |= IEEE80211_RX_IN_SCAN; -if (ieee80211_is_mgmt (fc)) - err =skb_linearize (skb); -else +if (ieee80211_is_mgmt (fc)) { +/* drop frame if too short for header */ +if (skb->len <ieee80211_hdrlen (fc)) + err = -ENOBUFS ; +else + err =skb_linearize (skb); + }else { err = !pskb_may_pull (skb,ieee80211_hdrlen (fc)); + }if (err) {dev_kfree_skb (skb);
Greg Kroah-Hartman
maintainerPATCH 19/57 mac80211: verify that skb data is present
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
commit 9b395bc3be1cebf0144a127c7e67d56dbdac0930 upstream.
A number of places in the mesh code don't check that the frame data is present and in the skb header when trying to access. Add those checks and the necessary pskb_may_pull() calls. This prevents accessing data that doesn't actually exist.
To do this, export ieee80211_get_mesh_hdrlen() to be able to use it in mac80211.
--- include/net/cfg80211.h | 9 +++++++++ net/mac80211/rx.c | 32 +++++++++++++++++++++++++++++++- net/wireless/util.c | 3 ++- 3 files changed, 42 insertions(+), 2 deletions(-)
include/net/cfg80211.h +9 -0
@@ -2480,6 +2480,15 @@ unsigned int ieee80211_get_hdrlen_from_s unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc);/** +* ieee80211_get_mesh_hdrlen - get mesh extension header length +* @meshhdr: the mesh extension header, only the flags field +* (first byte) will be accessed +* Returns the length of the extension header, which is always at +* least 6 bytes and at most 18 if address 5 and 6 are present. +*/ +unsigned int ieee80211_get_mesh_hdrlen (struct ieee80211s_hdr *meshhdr); + +/** * DOC: Data path helpers * * In addition to generic utilities, cfg80211 also offers
net/mac80211/rx.c +31 -1
@@ -513,6 +513,11 @@ ieee80211_rx_mesh_check(struct ieee80211if (ieee80211_is_action (hdr->frame_control)) {u8 category; + +/* make sure category field is present */ +if (rx->skb->len <IEEE80211_MIN_ACTION_SIZE ) +return RX_DROP_MONITOR ; + mgmt = (struct ieee80211_mgmt *)hdr; category = mgmt->u.action.category; if (category != WLAN_CATEGORY_MESH_ACTION &&
@@ -1895,6 +1900,20 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 hdr = (struct ieee80211_hdr *) skb->data; hdrlen =ieee80211_hdrlen (hdr->frame_control); + +/* make sure fixed part of mesh header is there, also checks skb len */ +if (!pskb_may_pull (rx->skb, hdrlen +6 )) +return RX_DROP_MONITOR ; + + mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); + +/* make sure full mesh header is there, also checks skb len */ +if (!pskb_may_pull (rx->skb, + hdrlen +ieee80211_get_mesh_hdrlen (mesh_hdr))) +return RX_DROP_MONITOR ; + +/* reload pointers */ + hdr = (struct ieee80211_hdr *) skb->data; mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);/* frame is in RMC, don't forward */
@@ -1918,9 +1937,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80if (is_multicast_ether_addr (hdr->addr1)) { mpp_addr = hdr->addr3; proxied_addr = mesh_hdr->eaddr1; - }else { + }else if (mesh_hdr->flags &MESH_FLAGS_AE_A5_A6 ) { +/* has_a4 already checked in ieee80211_rx_mesh_check */ mpp_addr = hdr->addr4; proxied_addr = mesh_hdr->eaddr2; + }else { +return RX_DROP_MONITOR ; }rcu_read_lock ();
@@ -2362,6 +2384,10 @@ ieee80211_rx_h_action(struct ieee80211_r }break ;case WLAN_CATEGORY_SELF_PROTECTED : +if (len < (IEEE80211_MIN_ACTION_SIZE + +sizeof (mgmt->u.action.u.self_prot.action_code))) +break ; +switch (mgmt->u.action.u.self_prot.action_code) {case WLAN_SP_MESH_PEERING_OPEN :case WLAN_SP_MESH_PEERING_CLOSE :
@@ -2380,6 +2406,10 @@ ieee80211_rx_h_action(struct ieee80211_r }break ;case WLAN_CATEGORY_MESH_ACTION : +if (len < (IEEE80211_MIN_ACTION_SIZE + +sizeof (mgmt->u.action.u.mesh_action.action_code))) +break ; +if (!ieee80211_vif_is_mesh (&sdata->vif))break ; if (mesh_action_is_path_sel(mgmt) &&
net/wireless/util.c +2 -1
@@ -290,7 +290,7 @@ unsigned int ieee80211_get_hdrlen_from_s }EXPORT_SYMBOL (ieee80211_get_hdrlen_from_skb); -static int ieee80211_get_mesh_hdrlen (struct ieee80211s_hdr *meshhdr) +unsigned int ieee80211_get_mesh_hdrlen (struct ieee80211s_hdr *meshhdr) {int ae = meshhdr->flags &MESH_FLAGS_AE ;/* 802.11-2012, 8.2.4.7.3 */
@@ -304,6 +304,7 @@ static int ieee80211_get_mesh_hdrlen(strreturn 18 ; } } +EXPORT_SYMBOL (ieee80211_get_mesh_hdrlen);int ieee80211_data_to_8023 (struct sk_buff *skb,const u8 *addr,enum nl80211_iftype iftype)
Greg Kroah-Hartman
maintainerPATCH 20/57 mac80211: make sure data is accessible in EAPOL check
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
commit 6dbda2d00d466225f9db1dc695ff852443f28832 upstream.
The code to allow EAPOL frames even when the station isn't yet marked associated needs to check that the incoming frame is long enough and due to paged RX it also can't assume skb->data contains the right data, it must use skb_copy_bits(). Fix this to avoid using data that doesn't really exist.
--- net/mac80211/rx.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
net/mac80211/rx.c +9 -7
@@ -874,14 +874,16 @@ ieee80211_rx_h_check(struct ieee80211_rx*/ if (rx->sta && rx->sdata->vif.type ==NL80211_IFTYPE_STATION &&ieee80211_is_data_present (hdr->frame_control)) { -u16 ethertype; -u8 *payload; +unsigned int hdrlen; +__be16 ethertype; - payload = rx->skb->data + -ieee80211_hdrlen (hdr->frame_control); - ethertype = (payload[6 ] <<8 ) | payload[7 ]; -if (cpu_to_be16 (ethertype) == - rx->sdata->control_port_protocol) + hdrlen =ieee80211_hdrlen (hdr->frame_control); + +if (rx->skb->len < hdrlen +8 ) +return RX_DROP_MONITOR ; + +skb_copy_bits (rx->skb, hdrlen +6 , ðertype,2 ); +if (ethertype == rx->sdata->control_port_protocol)return RX_CONTINUE ; }
Greg Kroah-Hartman
maintainerPATCH 21/57 mac80211: fix SSID copy on IBSS JOIN
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antonio Quartulli <[email protected]>
commit badecb001a310408d3473b1fc2ed5aefd0bc92a9 upstream.
The 'ssid' field of the cfg80211_ibss_params is a u8 pointer and its length is likely to be less than IEEE80211_MAX_SSID_LEN most of the time.
This patch fixes the ssid copy in ieee80211_ibss_join() by using the SSID length to prevent it from reading beyond the string.
--- net/mac80211/ibss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/mac80211/ibss.c +1 -1
@@ -1110,7 +1110,7 @@ int ieee80211_ibss_join(struct ieee80211 sdata->u.ibss.state =IEEE80211_IBSS_MLME_SEARCH ; sdata->u.ibss.ibss_join_req = jiffies; -memcpy (sdata->u.ibss.ssid, params->ssid,IEEE80211_MAX_SSID_LEN ); +memcpy (sdata->u.ibss.ssid, params->ssid, params->ssid_len); sdata->u.ibss.ssid_len = params->ssid_len;mutex_unlock (&sdata->u.ibss.mtx);
Greg Kroah-Hartman
maintainerPATCH 22/57 nfsv3: Make v3 mounts fail with ETIMEDOUTs instead EIO on mountd timeouts
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Scott Mayhew <[email protected]>
commit acce94e68a0f346115fd41cdc298197d2d5a59ad upstream.
In very busy v3 environment, rpc.mountd can respond to the NULL procedure but not the MNT procedure in a timely manner causing the MNT procedure to time out. The problem is the mount system call returns EIO which causes the mount to fail, instead of ETIMEDOUT, which would cause the mount to be retried.
This patch sets the RPC_TASK_SOFT|RPC_TASK_TIMEOUT flags to the rpc_call_sync() call in nfs_mount() which causes ETIMEDOUT to be returned on timed out connections.
--- fs/nfs/mount_clnt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/mount_clnt.c +1 -1
@@ -181,7 +181,7 @@ int nfs_mount(struct nfs_mount_request *else msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC_MNT ]; - status =rpc_call_sync (mnt_clnt, &msg,0 ); + status =rpc_call_sync (mnt_clnt, &msg,RPC_TASK_SOFT |RPC_TASK_TIMEOUT );rpc_shutdown_client (mnt_clnt);if (status <0 )
Greg Kroah-Hartman
maintainerPATCH 23/57 nfs: Show original device name verbatim in /proc/*/mount{s,info}
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings <[email protected]>
commit 97a54868262da1629a3e65121e65b8e8c4419d9f upstream.
Since commit c7f404b ('vfs: new superblock methods to override /proc/*/mount{s,info}'), nfs_path() is used to generate the mounted device name reported back to userland.
nfs_path() always generates a trailing slash when the given dentry is the root of an NFS mount, but userland may expect the original device name to be returned verbatim (as it used to be). Make this canonicalisation optional and change the callers accordingly.
Reference: http://bugs.debian.org/669314
--- fs/nfs/internal.h | 5 +++-- fs/nfs/namespace.c | 19 ++++++++++++++----- fs/nfs/nfs4namespace.c | 3 ++- fs/nfs/super.c | 2 +- 4 files changed, 20 insertions(+), 9 deletions(-)
fs/nfs/internal.h +3 -2
@@ -277,8 +277,9 @@ extern void nfs_sb_active(struct super_bextern void nfs_sb_deactive (struct super_block *sb);/* namespace.c */ +#define NFS_PATH_CANONICAL 1extern char *nfs_path (char **p,struct dentry *dentry, -char *buffer,ssize_t buflen); +char *buffer,ssize_t buflen,unsigned flags);extern struct vfsmount *nfs_d_automount (struct path *path);#ifdef CONFIG_NFS_V4 rpc_authflavor_t nfs_find_best_sec (struct nfs4_secinfo_flavors *);
@@ -371,7 +372,7 @@ static inline char *nfs_devname(struct d char *buffer, ssize_t buflen) {char *dummy; -return nfs_path (&dummy, dentry, buffer, buflen); +return nfs_path (&dummy, dentry, buffer, buflen,NFS_PATH_CANONICAL ); }/*
fs/nfs/namespace.c +14 -5
@@ -37,6 +37,7 @@ static struct vfsmount *nfs_do_submount(* @dentry - pointer to dentry * @buffer - result buffer * @buflen - length of buffer +* @flags - options (see below) * * Helper function for constructing the server pathname * by arbitrary hashed dentry.
@@ -44,8 +45,14 @@ static struct vfsmount *nfs_do_submount(* This is mainly for use in figuring out the path on the * server side when automounting on top of an existing partition * and in generating /proc/mounts and friends. +* +* Supported flags: +* NFS_PATH_CANONICAL: ensure there is exactly one slash after +* the original device (export) name +* (if unset, the original name is returned verbatim) */ -char *nfs_path (char **p,struct dentry *dentry,char *buffer,ssize_t buflen) +char *nfs_path (char **p,struct dentry *dentry,char *buffer,ssize_t buflen, +unsigned flags) {char *end;int namelen;
@@ -78,7 +85,7 @@ rename_retry:rcu_read_unlock (); goto rename_retry; } -if (*end !='/' ) { +if ((flags &NFS_PATH_CANONICAL ) && *end !='/' ) {if (--buflen <0 ) {spin_unlock (&dentry->d_lock);rcu_read_unlock ();
@@ -95,9 +102,11 @@ rename_retry:return end; } namelen =strlen (base); -/* Strip off excess slashes in base string */ -while (namelen >0 && base[namelen -1 ] =='/' ) - namelen--; +if (flags &NFS_PATH_CANONICAL ) { +/* Strip off excess slashes in base string */ +while (namelen >0 && base[namelen -1 ] =='/' ) + namelen--; + } buflen -= namelen;if (buflen <0 ) {spin_unlock (&dentry->d_lock);
fs/nfs/nfs4namespace.c +2 -1
@@ -81,7 +81,8 @@ static char *nfs_path_component(const chstatic char *nfs4_path (struct dentry *dentry,char *buffer,ssize_t buflen) {char *limit; -char *path =nfs_path (&limit, dentry, buffer, buflen); +char *path =nfs_path (&limit, dentry, buffer, buflen, +NFS_PATH_CANONICAL );if (!IS_ERR (path)) {char *path_component =nfs_path_component (path, limit);if (path_component)
fs/nfs/super.c +1 -1
@@ -812,7 +812,7 @@ static int nfs_show_devname(struct seq_fint err =0 ;if (!page)return -ENOMEM ; - devname =nfs_path (&dummy, root, page,PAGE_SIZE ); + devname =nfs_path (&dummy, root, page,PAGE_SIZE ,0 );if (IS_ERR (devname)) err =PTR_ERR (devname);else
Greg Kroah-Hartman
maintainerPATCH 24/57 NFSv4: nfs4_locku_done must release the sequence id
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
commit 2b1bc308f492589f7d49012ed24561534ea2be8c upstream.
If the state recovery machinery is triggered by the call to nfs4_async_handle_error() then we can deadlock.
--- fs/nfs/nfs4proc.c | 1 + 1 file changed, 1 insertion(+)
fs/nfs/nfs4proc.c +1 -0
@@ -4306,6 +4306,7 @@ static void nfs4_locku_done(struct rpc_tif (nfs4_async_handle_error (task, calldata->server,NULL ) == -EAGAIN )rpc_restart_call_prepare (task); } +nfs_release_seqid (calldata->arg.seqid); }static void nfs4_locku_prepare (struct rpc_task *task,void *data)
Greg Kroah-Hartman
maintainerPATCH 25/57 NFSv4.1: We must release the sequence id when we fail to get a session slot
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
commit 2240a9e2d013d8269ea425b73e1d7a54c7bc141f upstream.
If we do not release the sequence id in cases where we fail to get a session slot, then we can deadlock if we hit a recovery scenario.
--- fs/nfs/nfs4proc.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-)
fs/nfs/nfs4proc.c +23 -13
@@ -1478,9 +1478,11 @@ static void nfs4_open_prepare(struct rpc data->timestamp = jiffies;if (nfs4_setup_sequence (data->o_arg.server, &data->o_arg.seq_args, - &data->o_res.seq_res, task)) -return ; -rpc_call_start (task); + &data->o_res.seq_res, + task) !=0 ) +nfs_release_seqid (data->o_arg.seqid); +else +rpc_call_start (task);return ; unlock_no_action:rcu_read_unlock ();
@@ -2097,9 +2099,10 @@ static void nfs4_close_prepare(struct rpif (nfs4_setup_sequence (NFS_SERVER (calldata->inode), &calldata->arg.seq_args, &calldata->res.seq_res, - task)) - goto out; -rpc_call_start (task); + task) !=0 ) +nfs_release_seqid (calldata->arg.seqid); +else +rpc_call_start (task); out:dprintk ("%s: done!\n" , __func__); }
@@ -4323,9 +4326,11 @@ static void nfs4_locku_prepare(struct rp calldata->timestamp = jiffies;if (nfs4_setup_sequence (calldata->server, &calldata->arg.seq_args, - &calldata->res.seq_res, task)) -return ; -rpc_call_start (task); + &calldata->res.seq_res, + task) !=0 ) +nfs_release_seqid (calldata->arg.seqid); +else +rpc_call_start (task); }static const struct rpc_call_ops nfs4_locku_ops = {
@@ -4470,7 +4475,7 @@ static void nfs4_lock_prepare(struct rpc/* Do we need to do an open_to_lock_owner? */ if (!(data->arg.lock_seqid->sequence->flags &NFS_SEQID_CONFIRMED )) {if (nfs_wait_on_sequence (data->arg.open_seqid, task) !=0 ) -return ; + goto out_release_lock_seqid; data->arg.open_stateid = &state->stateid; data->arg.new_lock_owner =1 ; data->res.open_seqid = data->arg.open_seqid;
@@ -4479,10 +4484,15 @@ static void nfs4_lock_prepare(struct rpc data->timestamp = jiffies;if (nfs4_setup_sequence (data->server, &data->arg.seq_args, - &data->res.seq_res, task)) + &data->res.seq_res, + task) ==0 ) { +rpc_call_start (task);return ; -rpc_call_start (task); -dprintk ("%s: done!, ret = %d\n" , __func__, data->rpc_status); + } +nfs_release_seqid (data->arg.open_seqid); +out_release_lock_seqid: +nfs_release_seqid (data->arg.lock_seqid); +dprintk ("%s: done!, ret = %d\n" , __func__, task->tk_status); }static void nfs4_recover_lock_prepare (struct rpc_task *task,void *calldata)
Greg Kroah-Hartman
maintainerPATCH 26/57 nfsd: add get_uint for u32s
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: "J. Bruce Fields" <[email protected]>
commit a007c4c3e943ecc054a806c259d95420a188754b upstream.
I don't think there's a practical difference for the range of values these interfaces should see, but it would be safer to be unambiguous.
--- fs/nfsd/export.c | 6 +++--- include/linux/sunrpc/cache.h | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-)
fs/nfsd/export.c +3 -3
@@ -401,7 +401,7 @@ fsloc_parse(char **mesg, char *buf, struint migrated, i, err;/* listsize */ - err =get_int (mesg, &fsloc->locations_count); + err =get_uint (mesg, &fsloc->locations_count);if (err)return err;if (fsloc->locations_count >MAX_FS_LOCATIONS )
@@ -459,7 +459,7 @@ static int secinfo_parse(char **mesg, chreturn -EINVAL ;for (f = exp->ex_flavors; f < exp->ex_flavors + listsize; f++) { - err =get_int (mesg, &f->pseudoflavor); + err =get_uint (mesg, &f->pseudoflavor);if (err)return err;/*
@@ -468,7 +468,7 @@ static int secinfo_parse(char **mesg, ch* problem at export time instead of when a client fails * to authenticate. */ - err =get_int (mesg, &f->flags); + err =get_uint (mesg, &f->flags);if (err)return err;/* Only some flags are allowed to differ between flavors: */
include/linux/sunrpc/cache.h +16 -0
@@ -228,6 +228,22 @@ static inline int get_int(char **bpp, inreturn 0 ; } +static inline int get_uint (char **bpp,unsigned int *anint) +{ +char buf[50 ]; +int len =qword_get (bpp, buf,sizeof (buf)); + +if (len <0 ) +return -EINVAL ; +if (len ==0 ) +return -ENOENT ; + +if (kstrtouint (buf,0 , anint)) +return -EINVAL ; + +return 0 ; +} +/* * timestamps kept in the cache are expressed in seconds * since boot. This is the best for measuring differences in
Greg Kroah-Hartman
maintainerPATCH 27/57 NFS: fix bug in legacy DNS resolver.
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
commit 8d96b10639fb402357b75b055b1e82a65ff95050 upstream.
The DNS resolver's use of the sunrpc cache involves a 'ttl' number (relative) rather that a timeout (absolute). This confused me when I wrote
commit c5b29f885afe890f953f7f23424045cdad31d3e4
"sunrpc: use seconds since boot in expiry cache"
and I managed to break it. The effect is that any TTL is interpreted as 0, and nothing useful gets into the cache.
This patch removes the use of get_expiry() - which really expects an expiry time - and uses get_uint() instead, treating the int correctly as a ttl.
This fixes a regression that has been present since 2.6.37, causing certain NFS accesses in certain environments to incorrectly fail.
--- fs/nfs/dns_resolve.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/nfs/dns_resolve.c +3 -2
@@ -214,7 +214,7 @@ static int nfs_dns_parse(struct cache_de {char buf1[NFS_DNS_HOSTNAME_MAXLEN +1 ];struct nfs_dns_ent key, *item; -unsigned long ttl; +unsigned int ttl;ssize_t len;int ret = -EINVAL ;
@@ -237,7 +237,8 @@ static int nfs_dns_parse(struct cache_de key.namelen = len;memset (&key.h,0 ,sizeof (key.h)); - ttl =get_expiry (&buf); +if (get_uint (&buf, &ttl) <0 ) + goto out;if (ttl ==0 ) goto out; key.h.expiry_time = ttl +seconds_since_boot ();
Greg Kroah-Hartman
maintainerPATCH 28/57 NFS: Fix Oopses in nfs_lookup_revalidate and nfs4_lookup_revalidate
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[Fixed upstream as part of 0b728e1911c, but that's a much larger patch, this is only the nfs portion backported as needed.]
Fix the following Oops in 3.5.1:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000038 IP: [<ffffffffa03789cd>] nfs_lookup_revalidate+0x2d/0x480 [nfs] PGD 337c63067 PUD 0 Oops: 0000 [#1] SMP CPU 5 Modules linked in: nfs fscache nfsd lockd nfs_acl auth_rpcgss sunrpc af_packet binfmt_misc cpufreq_conservative cpufreq_userspace cpufreq_powersave dm_mod acpi_cpufreq mperf coretemp gpio_ich kvm_intel joydev kvm ioatdma hid_generic igb lpc_ich i7core_edac edac_core ptp serio_raw dca pcspkr i2c_i801 mfd_core sg pps_core usbhid crc32c_intel microcode button autofs4 uhci_hcd ttm drm_kms_helper drm i2c_algo_bit sysimgblt sysfillrect syscopyarea ehci_hcd usbcore usb_common scsi_dh_rdac scsi_dh_emc scsi_dh_hp_sw scsi_dh_alua scsi_dh edd fan ata_piix thermal processor thermal_sys
Pid: 30431, comm: java Not tainted 3.5.1-2-default #1 Supermicro X8DTT/X8DTT
RIP: 0010:[<ffffffffa03789cd>] [<ffffffffa03789cd>] nfs_lookup_revalidate+0x2d/0x480 [nfs] RSP: 0018:ffff8801b418bd38 EFLAGS: 00010292 RAX: 00000000fffffff6 RBX: ffff88032016d800 RCX: 0000000000000020 RDX: ffffffff00000000 RSI: 0000000000000000 RDI: ffff8801824a7b00 RBP: ffff8801b418bdf8 R08: 7fffff0034323030 R09: fffffffff04c03ed R10: ffff8801824a7b00 R11: 0000000000000002 R12: ffff8801824a7b00 R13: ffff8801824a7b00 R14: 0000000000000000 R15: ffff8803201725d0 FS: 00002b53a46cb700(0000) GS:ffff88033fc20000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000038 CR3: 000000020a426000 CR4: 00000000000007e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process java (pid: 30431, threadinfo ffff8801b418a000, task ffff8801b5d20600) Stack: ffff8801b418be44 ffff88032016d800 ffff8801b418bdf8 0000000000000000 ffff8801824a7b00 ffff8801b418bdd7 ffff8803201725d0 ffffffff8116a9c0 ffff8801b5c38dc0 0000000000000007 ffff88032016d800 0000000000000000 Call Trace: [<ffffffff8116a9c0>] lookup_dcache+0x80/0xe0 [<ffffffff8116aa43>] __lookup_hash+0x23/0x90 [<ffffffff8116b4a5>] lookup_one_len+0xc5/0x100 [<ffffffffa03869a3>] nfs_sillyrename+0xe3/0x210 [nfs] [<ffffffff8116cadf>] vfs_unlink.part.25+0x7f/0xe0 [<ffffffff8116f22c>] do_unlinkat+0x1ac/0x1d0 [<ffffffff815717b9>] system_call_fastpath+0x16/0x1b [<00002b5348b5f527>] 0x2b5348b5f526 Code: ec 38 b8 f6 ff ff ff 4c 89 64 24 18 4c 89 74 24 28 49 89 fc 48 89 5c 24 08 48 89 6c 24 10 49 89 f6 4c 89 6c 24 20 4c 89 7c 24 30 <f6> 46 38 40 0f 85 d1 00 00 00 e8 c4 c4 df e0 48 8b 58 30 49 89 RIP [<ffffffffa03789cd>] nfs_lookup_revalidate+0x2d/0x480 [nfs] RSP <ffff8801b418bd38> CR2: 0000000000000038 ---[ end trace 845113ed191985dd ]---
This Oops affects 3.5 kernels and older, and is due to lookup_one_len() calling down to the dentry revalidation code with a NULL pointer to struct nameidata.
It is fixed upstream by commit 0b728e1911c (stop passing nameidata * to ->d_revalidate())
--- fs/nfs/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/nfs/dir.c +2 -2
@@ -1103,7 +1103,7 @@ static int nfs_lookup_revalidate(structstruct nfs_fattr *fattr =NULL ;int error; -if (nd->flags &LOOKUP_RCU ) +if (nd && (nd->flags &LOOKUP_RCU ))return -ECHILD ; parent =dget_parent (dentry);
@@ -1502,7 +1502,7 @@ static int nfs_open_revalidate(struct destruct iattr attr;int openflags, ret =0 ; -if (nd->flags &LOOKUP_RCU ) +if (nd && (nd->flags &LOOKUP_RCU ))return -ECHILD ; inode = dentry->d_inode;
Greg Kroah-Hartman
maintainerPATCH 29/57 drm: restore open_count if drm_setup fails
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilija Hadzic <[email protected]>
commit 0f1cb1bd94a9c967cd4ad3de51cfdabe61eb5dcc upstream.
If drm_setup (called at first open) fails, the whole open call has failed, so we should not keep the open_count incremented.
--- drivers/gpu/drm/drm_fops.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/gpu/drm/drm_fops.c +4 -1
@@ -139,8 +139,11 @@ int drm_open(struct inode *inode, struct retcode =drm_open_helper (inode, filp, dev);if (!retcode) {atomic_inc (&dev->counts[_DRM_STAT_OPENS]); -if (!dev->open_count++) +if (!dev->open_count++) { retcode =drm_setup (dev); +if (retcode) + dev->open_count--; + } }if (!retcode) {mutex_lock (&dev->struct_mutex);
Greg Kroah-Hartman
maintainerPATCH 30/57 hwmon: (w83627ehf) Force initial bank selection
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jean Delvare <[email protected]>
commit 3300fb4f88688029fff8dfb9ec0734f6e4cba3e7 upstream.
Don't assume bank 0 is selected at device probe time. This may not be the case. Force bank selection at first register access to guarantee that we read the right registers upon driver loading.
--- drivers/hwmon/w83627ehf.c | 1 + 1 file changed, 1 insertion(+)
drivers/hwmon/w83627ehf.c +1 -0
@@ -2082,6 +2082,7 @@ static int __devinit w83627ehf_probe(strmutex_init (&data->lock);mutex_init (&data->update_lock); data->name = w83627ehf_device_names[sio_data->kind]; + data->bank =0xff ;/* Force initial bank selection */ platform_set_drvdata (pdev, data);/* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */
Greg Kroah-Hartman
maintainerPATCH 31/57 ALSA: PCM: Fix some races at disconnection
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 9b0573c07f278e9888c352aa9724035c75784ea0 upstream.
Fix races at PCM disconnection:
- while a PCM device is being opened or closed
- while the PCM state is being changed without lock in prepare, hw_params, hw_free ops
--- sound/core/pcm.c | 7 ++++++- sound/core/pcm_native.c | 16 ++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-)
sound/core/pcm.c +6 -1
@@ -1086,11 +1086,15 @@ static int snd_pcm_dev_disconnect(structif (list_empty (&pcm->list)) goto unlock; +mutex_lock (&pcm->open_mutex);list_del_init (&pcm->list);for (cidx =0 ; cidx <2 ; cidx++) -for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) +for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) { +snd_pcm_stream_lock_irq (substream);if (substream->runtime) substream->runtime->status->state =SNDRV_PCM_STATE_DISCONNECTED ; +snd_pcm_stream_unlock_irq (substream); + }list_for_each_entry (notify, &snd_pcm_notify_list, list) { notify->n_disconnect (pcm); }
@@ -1106,6 +1110,7 @@ static int snd_pcm_dev_disconnect(struct }snd_unregister_device (devtype, pcm->card, pcm->device); } +mutex_unlock (&pcm->open_mutex); unlock:mutex_unlock (®ister_mutex);return 0 ;
sound/core/pcm_native.c +12 -4
@@ -369,6 +369,14 @@ static int period_to_usecs(struct snd_pcreturn usecs; } +static void snd_pcm_set_state (struct snd_pcm_substream *substream,int state) +{ +snd_pcm_stream_lock_irq (substream); +if (substream->runtime->status->state !=SNDRV_PCM_STATE_DISCONNECTED ) + substream->runtime->status->state = state; +snd_pcm_stream_unlock_irq (substream); +} +static int snd_pcm_hw_params (struct snd_pcm_substream *substream,struct snd_pcm_hw_params *params) {
@@ -452,7 +460,7 @@ static int snd_pcm_hw_params(struct snd_ runtime->boundary *=2 ;snd_pcm_timer_resolution_change (substream); - runtime->status->state =SNDRV_PCM_STATE_SETUP ; +snd_pcm_set_state (substream,SNDRV_PCM_STATE_SETUP );if (pm_qos_request_active (&substream->latency_pm_qos_req))pm_qos_remove_request (&substream->latency_pm_qos_req);
@@ -464,7 +472,7 @@ static int snd_pcm_hw_params(struct snd_/* hardware might be unusable from this time, so we force application to retry to set the correct hardware parameter settings */ - runtime->status->state =SNDRV_PCM_STATE_OPEN ; +snd_pcm_set_state (substream,SNDRV_PCM_STATE_OPEN );if (substream->ops->hw_free !=NULL ) substream->ops->hw_free (substream);return err;
@@ -512,7 +520,7 @@ static int snd_pcm_hw_free(struct snd_pcreturn -EBADFD ;if (substream->ops->hw_free) result = substream->ops->hw_free (substream); - runtime->status->state =SNDRV_PCM_STATE_OPEN ; +snd_pcm_set_state (substream,SNDRV_PCM_STATE_OPEN );pm_qos_remove_request (&substream->latency_pm_qos_req);return result; }
@@ -1320,7 +1328,7 @@ static void snd_pcm_post_prepare(struct {struct snd_pcm_runtime *runtime = substream->runtime; runtime->control->appl_ptr = runtime->status->hw_ptr; - runtime->status->state =SNDRV_PCM_STATE_PREPARED ; +snd_pcm_set_state (substream,SNDRV_PCM_STATE_PREPARED ); }static struct action_ops snd_pcm_action_prepare = {
Greg Kroah-Hartman
maintainerPATCH 32/57 ALSA: usb-audio: Fix races at disconnection
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 978520b75f0a1ce82b17e1e8186417250de6d545 upstream.
Close some races at disconnection of a USB audio device by adding the chip->shutdown_mutex and chip->shutdown check at appropriate places.
The spots to put bandaids are:
- PCM prepare, hw_params and hw_free
- where the usb device is accessed for communication or get speed, in mixer.c and others; the device speed is now cached in subs->speed instead of accessing to chip->dev
The accesses in PCM open and close don't need the mutex protection because these are already handled in the core PCM disconnection code.
The autosuspend/autoresume codes are still uncovered by this patch because of possible mutex deadlocks. They'll be covered by the upcoming change to rwsem.
Also the mixer codes are untouched, too. These will be fixed in another patch, too.
--- sound/usb/card.h | 1 sound/usb/endpoint.c | 9 ++++--- sound/usb/mixer.c | 65 +++++++++++++++++++++++++++++++++------------------ sound/usb/pcm.c | 31 ++++++++++++++++++------ sound/usb/proc.c | 4 +-- 5 files changed, 76 insertions(+), 34 deletions(-)
sound/usb/card.h +1 -0
@@ -87,6 +87,7 @@ struct snd_usb_substream {struct snd_urb_ctx syncurb[SYNC_URBS ];/* sync urb table */ char *syncbuf;/* sync buffer for all sync URBs */ dma_addr_t sync_dma;/* DMA address of syncbuf */ +unsigned int speed;/* USB_SPEED_XXX */ u64 formats;/* format bitmasks (all or'ed) */ unsigned int num_formats;/* number of supported audio formats (list) */
sound/usb/endpoint.c +6 -3
@@ -148,8 +148,10 @@ void snd_usb_release_substream_urbs(struint i;/* stop urbs (to be sure) */ -deactivate_urbs (subs, force,1 ); -wait_clear_urbs (subs); +if (!subs->stream->chip->shutdown) { +deactivate_urbs (subs, force,1 ); +wait_clear_urbs (subs); + }for (i =0 ; i <MAX_URBS ; i++)release_urb_ctx (&subs->dataurb[i]);
@@ -895,7 +897,8 @@ void snd_usb_init_substream(struct snd_u subs->dev = as->chip->dev; subs->txfr_quirk = as->chip->txfr_quirk; subs->ops = audio_urb_ops[stream]; -if (snd_usb_get_speed (subs->dev) >=USB_SPEED_HIGH ) + subs->speed =snd_usb_get_speed (subs->dev); +if (subs->speed >=USB_SPEED_HIGH ) subs->ops.prepare_sync = prepare_capture_sync_urb_hs;snd_usb_set_pcm_ops (as->pcm, stream);
sound/usb/mixer.c +43 -22
117 lines not on this page · raw message
sound/usb/pcm.c +24 -7
@@ -67,6 +67,8 @@ static snd_pcm_uframes_t snd_usb_pcm_poiunsigned int hwptr_done; subs = (struct snd_usb_substream *)substream->runtime->private_data; +if (subs->stream->chip->shutdown) +return SNDRV_PCM_POS_XRUN ;spin_lock (&subs->lock); hwptr_done = subs->hwptr_done; substream->runtime->delay = snd_usb_pcm_delay(subs,
@@ -373,8 +375,14 @@ static int snd_usb_hw_params(struct snd_ changed = subs->cur_audiofmt != fmt || subs->period_bytes !=params_period_bytes (hw_params) || subs->cur_rate != rate; + +mutex_lock (&subs->stream->chip->shutdown_mutex); +if (subs->stream->chip->shutdown) { + ret = -ENODEV ; + goto unlock; + }if ((ret =set_format (subs, fmt)) <0 ) -return ret; + goto unlock;if (subs->cur_rate != rate) {struct usb_host_interface *alts;
@@ -383,12 +391,11 @@ static int snd_usb_hw_params(struct snd_ alts = &iface->altsetting[fmt->altset_idx]; ret =snd_usb_init_sample_rate (subs->stream->chip, subs->interface, alts, fmt, rate);if (ret <0 ) -return ret; + goto unlock; subs->cur_rate = rate; }if (changed) { -mutex_lock (&subs->stream->chip->shutdown_mutex);/* format changed */ snd_usb_release_substream_urbs (subs,0 );/* influenced: period_bytes, channels, rate, format, */
@@ -396,9 +403,10 @@ static int snd_usb_hw_params(struct snd_params_rate (hw_params),snd_pcm_format_physical_width (params_format (hw_params)) * params_channels(hw_params)); -mutex_unlock (&subs->stream->chip->shutdown_mutex); } +unlock: +mutex_unlock (&subs->stream->chip->shutdown_mutex);return ret; }
@@ -429,12 +437,18 @@ static int snd_usb_pcm_prepare(struct sn {struct snd_pcm_runtime *runtime = substream->runtime;struct snd_usb_substream *subs = runtime->private_data; +int ret =0 ;if (! subs->cur_audiofmt) {snd_printk (KERN_ERR "usbaudio: no format is specified!\n" );return -ENXIO ; } +mutex_lock (&subs->stream->chip->shutdown_mutex); +if (subs->stream->chip->shutdown) { + ret = -ENODEV ; + goto unlock; + }/* some unit conversions in runtime */ subs->maxframesize =bytes_to_frames (runtime, subs->maxpacksize); subs->curframesize =bytes_to_frames (runtime, subs->curpacksize);
@@ -447,7 +461,10 @@ static int snd_usb_pcm_prepare(struct sn subs->last_frame_number =0 ; runtime->delay =0 ; -return snd_usb_substream_prepare (subs, runtime); + ret =snd_usb_substream_prepare (subs, runtime); + unlock: +mutex_unlock (&subs->stream->chip->shutdown_mutex); +return ret; } static struct snd_pcm_hardware snd_usb_hardware =
@@ -500,7 +517,7 @@ static int hw_check_valid_format(structreturn 0 ; }/* check whether the period time is >= the data packet interval */ -if (snd_usb_get_speed (subs->dev) !=USB_SPEED_FULL ) { +if (subs->speed !=USB_SPEED_FULL ) { ptime =125 * (1 << fp->datainterval);if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {hwc_debug (" > check: ptime %u > max %u\n" , ptime, pt->max);
@@ -778,7 +795,7 @@ static int setup_hw_info(struct snd_pcm_return err; param_period_time_if_needed =SNDRV_PCM_HW_PARAM_PERIOD_TIME ; -if (snd_usb_get_speed (subs->dev) ==USB_SPEED_FULL ) +if (subs->speed ==USB_SPEED_FULL )/* full speed devices have fixed data packet interval */ ptmin =1000 ;if (ptmin ==1000 )
sound/usb/proc.c +2 -2
@@ -107,7 +107,7 @@ static void proc_dump_substream_formats( }snd_iprintf (buffer,"\n" ); } -if (snd_usb_get_speed (subs->dev) !=USB_SPEED_FULL ) +if (subs->speed !=USB_SPEED_FULL )snd_iprintf (buffer," Data packet interval: %d us\n" ,125 * (1 << fp->datainterval));// snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize);
@@ -128,7 +128,7 @@ static void proc_dump_substream_status(ssnd_iprintf (buffer,"]\n" );snd_iprintf (buffer," Packet Size = %d\n" , subs->curpacksize);snd_iprintf (buffer," Momentary freq = %u Hz (%#x.%04x)\n" , -snd_usb_get_speed (subs->dev) ==USB_SPEED_FULL + subs->speed ==USB_SPEED_FULL ?get_full_speed_hz (subs->freqm) :get_high_speed_hz (subs->freqm), subs->freqm >>16 , subs->freqm &0xffff );
Greg Kroah-Hartman
maintainerPATCH 33/57 ALSA: usb-audio: Use rwsem for disconnect protection
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 34f3c89fda4fba9fe689db22253ca8db2f5e6386 upstream.
Replace mutex with rwsem for codec->shutdown protection so that concurrent accesses are allowed.
Also add the protection to snd_usb_autosuspend() and snd_usb_autoresume(), too.
--- sound/usb/card.c | 12 ++++++++---- sound/usb/mixer.c | 12 ++++++------ sound/usb/pcm.c | 12 ++++++------ sound/usb/usbaudio.h | 2 +- 4 files changed, 21 insertions(+), 17 deletions(-)
sound/usb/card.c +8 -4
@@ -336,7 +336,7 @@ static int snd_usb_audio_create(struct ureturn -ENOMEM ; } -mutex_init (&chip->shutdown_mutex); +init_rwsem (&chip->shutdown_rwsem); chip->index = idx; chip->dev = dev; chip->card = card;
@@ -556,7 +556,7 @@ static void snd_usb_audio_disconnect(str card = chip->card;mutex_lock (®ister_mutex); -mutex_lock (&chip->shutdown_mutex); +down_write (&chip->shutdown_rwsem); chip->shutdown =1 ; chip->num_interfaces--;if (chip->num_interfaces <=0 ) {
@@ -574,11 +574,11 @@ static void snd_usb_audio_disconnect(strsnd_usb_mixer_disconnect (p); } usb_chip[chip->index] =NULL ; -mutex_unlock (&chip->shutdown_mutex); +up_write (&chip->shutdown_rwsem);mutex_unlock (®ister_mutex);snd_card_free_when_closed (card); }else { -mutex_unlock (&chip->shutdown_mutex); +up_write (&chip->shutdown_rwsem);mutex_unlock (®ister_mutex); } }
@@ -610,16 +610,20 @@ int snd_usb_autoresume(struct snd_usb_au {int err = -ENODEV ; +down_read (&chip->shutdown_rwsem);if (!chip->shutdown && !chip->probing) err =usb_autopm_get_interface (chip->pm_intf); +up_read (&chip->shutdown_rwsem);return err; }void snd_usb_autosuspend (struct snd_usb_audio *chip) { +down_read (&chip->shutdown_rwsem);if (!chip->shutdown && !chip->probing)usb_autopm_put_interface (chip->pm_intf); +up_read (&chip->shutdown_rwsem); }static int usb_audio_suspend (struct usb_interface *intf,pm_message_t message)
sound/usb/mixer.c +6 -6
@@ -292,7 +292,7 @@ static int get_ctl_value_v1(struct usb_m err =snd_usb_autoresume (cval->mixer->chip);if (err <0 )return -EIO ; -mutex_lock (&chip->shutdown_mutex); +down_read (&chip->shutdown_rwsem);while (timeout-- >0 ) {if (chip->shutdown)break ;
@@ -310,7 +310,7 @@ static int get_ctl_value_v1(struct usb_m err = -EINVAL ; out: -mutex_unlock (&chip->shutdown_mutex); +up_read (&chip->shutdown_rwsem);snd_usb_autosuspend (cval->mixer->chip);return err; }
@@ -337,7 +337,7 @@ static int get_ctl_value_v2(struct usb_mif (ret) goto error; -mutex_lock (&chip->shutdown_mutex); +down_read (&chip->shutdown_rwsem);if (chip->shutdown) ret = -ENODEV ;else {
@@ -346,7 +346,7 @@ static int get_ctl_value_v2(struct usb_mUSB_RECIP_INTERFACE |USB_TYPE_CLASS |USB_DIR_IN , validx, idx, buf, size); } -mutex_unlock (&chip->shutdown_mutex); +up_read (&chip->shutdown_rwsem);snd_usb_autosuspend (chip);if (ret <0 ) {
@@ -453,7 +453,7 @@ int snd_usb_mixer_set_ctl_value(struct u err =snd_usb_autoresume (chip);if (err <0 )return -EIO ; -mutex_lock (&chip->shutdown_mutex); +down_read (&chip->shutdown_rwsem);while (timeout-- >0 ) {if (chip->shutdown)break ;
@@ -471,7 +471,7 @@ int snd_usb_mixer_set_ctl_value(struct u err = -EINVAL ; out: -mutex_unlock (&chip->shutdown_mutex); +up_read (&chip->shutdown_rwsem);snd_usb_autosuspend (chip);return err; }
sound/usb/pcm.c +6 -6
@@ -376,7 +376,7 @@ static int snd_usb_hw_params(struct snd_ subs->period_bytes !=params_period_bytes (hw_params) || subs->cur_rate != rate; -mutex_lock (&subs->stream->chip->shutdown_mutex); +down_read (&subs->stream->chip->shutdown_rwsem);if (subs->stream->chip->shutdown) { ret = -ENODEV ; goto unlock;
@@ -406,7 +406,7 @@ static int snd_usb_hw_params(struct snd_ } unlock: -mutex_unlock (&subs->stream->chip->shutdown_mutex); +up_read (&subs->stream->chip->shutdown_rwsem);return ret; }
@@ -422,9 +422,9 @@ static int snd_usb_hw_free(struct snd_pc subs->cur_audiofmt =NULL ; subs->cur_rate =0 ; subs->period_bytes =0 ; -mutex_lock (&subs->stream->chip->shutdown_mutex); +down_read (&subs->stream->chip->shutdown_rwsem);snd_usb_release_substream_urbs (subs,0 ); -mutex_unlock (&subs->stream->chip->shutdown_mutex); +up_read (&subs->stream->chip->shutdown_rwsem);return snd_pcm_lib_free_vmalloc_buffer (substream); }
@@ -444,7 +444,7 @@ static int snd_usb_pcm_prepare(struct snreturn -ENXIO ; } -mutex_lock (&subs->stream->chip->shutdown_mutex); +down_read (&subs->stream->chip->shutdown_rwsem);if (subs->stream->chip->shutdown) { ret = -ENODEV ; goto unlock;
@@ -463,7 +463,7 @@ static int snd_usb_pcm_prepare(struct sn ret =snd_usb_substream_prepare (subs, runtime); unlock: -mutex_unlock (&subs->stream->chip->shutdown_mutex); +up_read (&subs->stream->chip->shutdown_rwsem);return ret; }
sound/usb/usbaudio.h +1 -1
@@ -36,7 +36,7 @@ struct snd_usb_audio {struct snd_card *card;struct usb_interface *pm_intf;u32 usb_id; -struct mutex shutdown_mutex; +struct rw_semaphore shutdown_rwsem; unsigned int shutdown:1; unsigned int probing:1; unsigned int autosuspended:1;
Greg Kroah-Hartman
maintainerPATCH 34/57 ALSA: usb-audio: Fix races at disconnection in mixer_quirks.c
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 888ea7d5ac6815ba16b3b3a20f665a92c7af6724 upstream.
Similar like the previous commit, cover with chip->shutdown_rwsem and chip->shutdown checks.
--- sound/usb/mixer_quirks.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-)
sound/usb/mixer_quirks.c +33 -4
@@ -186,6 +186,11 @@ static int snd_audigy2nx_led_put(structif (value >1 )return -EINVAL ; changed = value != mixer->audigy2nx_leds[index]; +down_read (&mixer->chip->shutdown_rwsem); +if (mixer->chip->shutdown) { + err = -ENODEV ; + goto out; + }if (mixer->chip->usb_id ==USB_ID (0x041e ,0x3042 )) err = snd_usb_ctl_msg(mixer->chip->dev, usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
@@ -202,6 +207,8 @@ static int snd_audigy2nx_led_put(structusb_sndctrlpipe (mixer->chip->dev,0 ),0x24 ,USB_DIR_OUT |USB_TYPE_VENDOR |USB_RECIP_OTHER , value, index + 2, NULL, 0); + out: +up_read (&mixer->chip->shutdown_rwsem);if (err <0 )return err; mixer->audigy2nx_leds[index] = value;
@@ -295,11 +302,16 @@ static void snd_audigy2nx_proc_read(strufor (i =0 ; jacks[i].name; ++i) {snd_iprintf (buffer,"%s: " , jacks[i].name); - err =snd_usb_ctl_msg (mixer->chip->dev, +down_read (&mixer->chip->shutdown_rwsem); +if (mixer->chip->shutdown) + err =0 ; +else + err =snd_usb_ctl_msg (mixer->chip->dev,usb_rcvctrlpipe (mixer->chip->dev,0 ),UAC_GET_MEM ,USB_DIR_IN |USB_TYPE_CLASS |USB_RECIP_INTERFACE ,0 , jacks[i].unitid <<8 , buf,3 ); +up_read (&mixer->chip->shutdown_rwsem);if (err ==3 && (buf[0 ] ==3 || buf[0 ] ==6 ))snd_iprintf (buffer,"%02x %02x\n" , buf[1 ], buf[2 ]);else
@@ -329,10 +341,15 @@ static int snd_xonar_u1_switch_put(strucelse new_status = old_status & ~0x02 ; changed = new_status != old_status; - err =snd_usb_ctl_msg (mixer->chip->dev, +down_read (&mixer->chip->shutdown_rwsem); +if (mixer->chip->shutdown) + err = -ENODEV ; +else + err =snd_usb_ctl_msg (mixer->chip->dev,usb_sndctrlpipe (mixer->chip->dev,0 ),0x08 ,USB_DIR_OUT |USB_TYPE_VENDOR |USB_RECIP_OTHER ,50 ,0 , &new_status,1 ); +up_read (&mixer->chip->shutdown_rwsem);if (err <0 )return err; mixer->xonar_u1_status = new_status;
@@ -371,11 +388,17 @@ static int snd_nativeinstruments_controlu8 bRequest = (kcontrol->private_value >>16 ) &0xff ;u16 wIndex = kcontrol->private_value &0xffff ;u8 tmp; +int ret; -int ret =usb_control_msg (dev,usb_rcvctrlpipe (dev,0 ), bRequest, +down_read (&mixer->chip->shutdown_rwsem); +if (mixer->chip->shutdown) + ret = -ENODEV ; +else + ret =usb_control_msg (dev,usb_rcvctrlpipe (dev,0 ), bRequest,USB_TYPE_VENDOR |USB_RECIP_DEVICE |USB_DIR_IN ,0 ,cpu_to_le16 (wIndex), &tmp,sizeof (tmp),1000 ); +up_read (&mixer->chip->shutdown_rwsem);if (ret <0 ) { snd_printk(KERN_ERR
@@ -396,11 +419,17 @@ static int snd_nativeinstruments_controlu8 bRequest = (kcontrol->private_value >>16 ) &0xff ;u16 wIndex = kcontrol->private_value &0xffff ;u16 wValue = ucontrol->value.integer.value[0 ]; +int ret; -int ret =usb_control_msg (dev,usb_sndctrlpipe (dev,0 ), bRequest, +down_read (&mixer->chip->shutdown_rwsem); +if (mixer->chip->shutdown) + ret = -ENODEV ; +else + ret =usb_control_msg (dev,usb_sndctrlpipe (dev,0 ), bRequest,USB_TYPE_VENDOR |USB_RECIP_DEVICE |USB_DIR_OUT ,cpu_to_le16 (wValue),cpu_to_le16 (wIndex),NULL ,0 ,1000 ); +up_read (&mixer->chip->shutdown_rwsem);if (ret <0 ) { snd_printk(KERN_ERR
Greg Kroah-Hartman
maintainerPATCH 35/57 ALSA: Add a reference counter to card instance
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit a0830dbd4e42b38aefdf3fb61ba5019a1a99ea85 upstream.
For more strict protection for wild disconnections, a refcount is introduced to the card instance, and let it up/down when an object is referred via snd_lookup_*() in the open ops.
The free-after-last-close check is also changed to check this refcount instead of the empty list, too.
--- include/sound/core.h | 3 ++ sound/core/compress_offload.c | 9 +++++-- sound/core/control.c | 3 ++ sound/core/hwdep.c | 5 +++- sound/core/init.c | 50 +++++++++++++++++++++++++----------------- sound/core/oss/mixer_oss.c | 10 ++++++-- sound/core/oss/pcm_oss.c | 2 + sound/core/pcm_native.c | 9 +++++-- sound/core/rawmidi.c | 6 ++++- sound/core/sound.c | 11 +++++++-- sound/core/sound_oss.c | 10 ++++++-- 11 files changed, 86 insertions(+), 32 deletions(-)
include/sound/core.h +3 -0
@@ -132,6 +132,7 @@ struct snd_card {int shutdown;/* this card is going down */ int free_on_last_close;/* free in context of file_release */ wait_queue_head_t shutdown_sleep; +atomic_t refcount;/* refcount for disconnection */ struct device *dev;/* device assigned to this card */ struct device *card_dev;/* cardX object for sysfs */
@@ -189,6 +190,7 @@ struct snd_minor {const struct file_operations *f_ops;/* file operations */ void *private_data;/* private data for f_ops->open */ struct device *dev;/* device for sysfs */ +struct snd_card *card_ptr;/* assigned card instance */ };/* return a device pointer linked to each sound device as a parent */
@@ -295,6 +297,7 @@ int snd_card_info_done(void);int snd_component_add (struct snd_card *card,const char *component);int snd_card_file_add (struct snd_card *card,struct file *file);int snd_card_file_remove (struct snd_card *card,struct file *file); +void snd_card_unref (struct snd_card *card);#define snd_card_set_dev (card, devptr) ((card)->dev = (devptr))
sound/core/compress_offload.c +7 -2
@@ -102,12 +102,15 @@ static int snd_compr_open(struct inode *if (dirn != compr->direction) {pr_err ("this device doesn't support this direction\n" ); +snd_card_unref (compr->card);return -EINVAL ; } data =kzalloc (sizeof (*data),GFP_KERNEL ); -if (!data) +if (!data) { +snd_card_unref (compr->card);return -ENOMEM ; + } data->stream.ops = compr->ops; data->stream.direction = dirn; data->stream.private_data = compr->private_data;
@@ -115,6 +118,7 @@ static int snd_compr_open(struct inode * runtime =kzalloc (sizeof (*runtime),GFP_KERNEL );if (!runtime) {kfree (data); +snd_card_unref (compr->card);return -ENOMEM ; } runtime->state =SNDRV_PCM_STATE_OPEN ;
@@ -128,7 +132,8 @@ static int snd_compr_open(struct inode *kfree (runtime);kfree (data); } -return ret; +snd_card_unref (compr->card); +return 0 ; }static int snd_compr_free (struct inode *inode,struct file *f)
sound/core/control.c +3 -0
@@ -86,6 +86,7 @@ static int snd_ctl_open(struct inode *inwrite_lock_irqsave (&card->ctl_files_rwlock, flags);list_add_tail (&ctl->list, &card->ctl_files);write_unlock_irqrestore (&card->ctl_files_rwlock, flags); +snd_card_unref (card);return 0 ; __error:
@@ -93,6 +94,8 @@ static int snd_ctl_open(struct inode *in __error2:snd_card_file_remove (card, file); __error1: +if (card) +snd_card_unref (card);return err; }
sound/core/hwdep.c +4 -1
@@ -100,8 +100,10 @@ static int snd_hwdep_open(struct inode *if (hw ==NULL )return -ENODEV ; -if (!try_module_get (hw->card->module)) +if (!try_module_get (hw->card->module)) { +snd_card_unref (hw->card);return -EFAULT ; + }init_waitqueue_entry (&wait, current);add_wait_queue (&hw->open_wait, &wait);
@@ -148,6 +150,7 @@ static int snd_hwdep_open(struct inode *mutex_unlock (&hw->open_mutex);if (err <0 )module_put (hw->card->module); +snd_card_unref (hw->card);return err; }
sound/core/init.c +30 -20
96 lines not on this page · raw message
sound/core/oss/mixer_oss.c +8 -2
@@ -52,14 +52,19 @@ static int snd_mixer_oss_open(struct ino SNDRV_OSS_DEVICE_TYPE_MIXER);if (card ==NULL )return -ENODEV ; -if (card->mixer_oss ==NULL ) +if (card->mixer_oss ==NULL ) { +snd_card_unref (card);return -ENODEV ; + } err =snd_card_file_add (card, file); -if (err <0 ) +if (err <0 ) { +snd_card_unref (card);return err; + } fmixer =kzalloc (sizeof (*fmixer),GFP_KERNEL );if (fmixer ==NULL ) {snd_card_file_remove (card, file); +snd_card_unref (card);return -ENOMEM ; } fmixer->card = card;
@@ -68,6 +73,7 @@ static int snd_mixer_oss_open(struct inoif (!try_module_get (card->module)) {kfree (fmixer);snd_card_file_remove (card, file); +snd_card_unref (card);return -EFAULT ; }return 0 ;
sound/core/oss/pcm_oss.c +2 -0
@@ -2457,6 +2457,8 @@ static int snd_pcm_oss_open(struct inode __error2:snd_card_file_remove (pcm->card, file); __error1: +if (pcm) +snd_card_unref (pcm->card);return err; }
sound/core/pcm_native.c +7 -2
@@ -1631,6 +1631,7 @@ static int snd_pcm_link(struct snd_pcm_swrite_unlock_irq (&snd_pcm_link_rwlock);up_write (&snd_pcm_link_rwsem); _nolock: +snd_card_unref (substream1->pcm->card);fput (file);if (res <0 )kfree (group);
@@ -2105,7 +2106,9 @@ static int snd_pcm_playback_open(structreturn err; pcm =snd_lookup_minor_data (iminor (inode),SNDRV_DEVICE_TYPE_PCM_PLAYBACK ); -return snd_pcm_open (file, pcm,SNDRV_PCM_STREAM_PLAYBACK ); + err =snd_pcm_open (file, pcm,SNDRV_PCM_STREAM_PLAYBACK ); +snd_card_unref (pcm->card); +return err; }static int snd_pcm_capture_open (struct inode *inode,struct file *file)
@@ -2116,7 +2119,9 @@ static int snd_pcm_capture_open(struct ireturn err; pcm =snd_lookup_minor_data (iminor (inode),SNDRV_DEVICE_TYPE_PCM_CAPTURE ); -return snd_pcm_open (file, pcm,SNDRV_PCM_STREAM_CAPTURE ); + err =snd_pcm_open (file, pcm,SNDRV_PCM_STREAM_CAPTURE ); +snd_card_unref (pcm->card); +return err; }static int snd_pcm_open (struct file *file,struct snd_pcm *pcm,int stream)
sound/core/rawmidi.c +5 -1
@@ -379,8 +379,10 @@ static int snd_rawmidi_open(struct inodeif (rmidi ==NULL )return -ENODEV ; -if (!try_module_get (rmidi->card->module)) +if (!try_module_get (rmidi->card->module)) { +snd_card_unref (rmidi->card);return -ENXIO ; + }mutex_lock (&rmidi->open_mutex); card = rmidi->card;
@@ -440,6 +442,7 @@ static int snd_rawmidi_open(struct inode#endif file->private_data = rawmidi_file;mutex_unlock (&rmidi->open_mutex); +snd_card_unref (rmidi->card);return 0 ; __error:
@@ -447,6 +450,7 @@ static int snd_rawmidi_open(struct inode __error_card:mutex_unlock (&rmidi->open_mutex);module_put (rmidi->card->module); +snd_card_unref (rmidi->card);return err; }
sound/core/sound.c +9 -2
@@ -99,6 +99,10 @@ static void snd_request_other(int minor)* * Checks that a minor device with the specified type is registered, and returns * its user data pointer. +* +* This function increments the reference counter of the card instance +* if an associated instance with the given minor number and type is found. +* The caller must call snd_card_unref() appropriately later. */ void *snd_lookup_minor_data (unsigned int minor,int type) {
@@ -109,9 +113,11 @@ void *snd_lookup_minor_data(unsigned intreturn NULL ;mutex_lock (&sound_mutex); mreg = snd_minors[minor]; -if (mreg && mreg->type == type) +if (mreg && mreg->type == type) { private_data = mreg->private_data; -else +if (mreg->card_ptr) +atomic_inc (&mreg->card_ptr->refcount); + }else private_data =NULL ;mutex_unlock (&sound_mutex);return private_data;
@@ -276,6 +282,7 @@ int snd_register_device_for_dev(int type preg->device = dev; preg->f_ops = f_ops; preg->private_data = private_data; + preg->card_ptr = card;mutex_lock (&sound_mutex);#ifdef CONFIG_SND_DYNAMIC_MINORS minor =snd_find_free_minor (type);
sound/core/sound_oss.c +8 -2
@@ -40,6 +40,9 @@static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS ];static DEFINE_MUTEX (sound_oss_mutex); +/* NOTE: This function increments the refcount of the associated card like +* snd_lookup_minor_data(); the caller must call snd_card_unref() appropriately +*/ void *snd_lookup_oss_minor_data (unsigned int minor,int type) {struct snd_minor *mreg;
@@ -49,9 +52,11 @@ void *snd_lookup_oss_minor_data(unsignedreturn NULL ;mutex_lock (&sound_oss_mutex); mreg = snd_oss_minors[minor]; -if (mreg && mreg->type == type) +if (mreg && mreg->type == type) { private_data = mreg->private_data; -else +if (mreg->card_ptr) +atomic_inc (&mreg->card_ptr->refcount); + }else private_data =NULL ;mutex_unlock (&sound_oss_mutex);return private_data;
@@ -123,6 +128,7 @@ int snd_register_oss_device(int type, st preg->device = dev; preg->f_ops = f_ops; preg->private_data = private_data; + preg->card_ptr = card;mutex_lock (&sound_oss_mutex); snd_oss_minors[minor] = preg; minor_unit =SNDRV_MINOR_OSS_DEVICE (minor);
Greg Kroah-Hartman
maintainerPATCH 36/57 ALSA: Avoid endless sleep after disconnect
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 0914f7961babbf28aaa2f19b453951fb4841c03f upstream.
When disconnect callback is called, each component should wake up sleepers and check card->shutdown flag for avoiding the endless sleep blocking the proper resource release.
--- sound/core/control.c | 2 ++ sound/core/hwdep.c | 7 +++++++ sound/core/oss/pcm_oss.c | 4 ++++ sound/core/pcm.c | 6 +++++- sound/core/pcm_native.c | 8 ++++++++ sound/core/rawmidi.c | 20 ++++++++++++++++++++ 6 files changed, 46 insertions(+), 1 deletion(-)
sound/core/control.c +2 -0
@@ -1436,6 +1436,8 @@ static ssize_t snd_ctl_read(struct filespin_unlock_irq (&ctl->read_lock);schedule ();remove_wait_queue (&ctl->change_sleep, &wait); +if (ctl->card->shutdown) +return -ENODEV ;if (signal_pending (current))return -ERESTARTSYS ;spin_lock_irq (&ctl->read_lock);
sound/core/hwdep.c +7 -0
@@ -131,6 +131,10 @@ static int snd_hwdep_open(struct inode *mutex_unlock (&hw->open_mutex);schedule ();mutex_lock (&hw->open_mutex); +if (hw->card->shutdown) { + err = -ENODEV ; +break ; + }if (signal_pending (current)) { err = -ERESTARTSYS ;break ;
@@ -462,12 +466,15 @@ static int snd_hwdep_dev_disconnect(strumutex_unlock (®ister_mutex);return -EINVAL ; } +mutex_lock (&hwdep->open_mutex); +wake_up (&hwdep->open_wait);#ifdef CONFIG_SND_OSSEMUL if (hwdep->ossreg)snd_unregister_oss_device (hwdep->oss_type, hwdep->card, hwdep->device);#endif snd_unregister_device (SNDRV_DEVICE_TYPE_HWDEP , hwdep->card, hwdep->device);list_del_init (&hwdep->list); +mutex_unlock (&hwdep->open_mutex);mutex_unlock (®ister_mutex);return 0 ; }
sound/core/oss/pcm_oss.c +4 -0
@@ -2441,6 +2441,10 @@ static int snd_pcm_oss_open(struct inodemutex_unlock (&pcm->open_mutex);schedule ();mutex_lock (&pcm->open_mutex); +if (pcm->card->shutdown) { + err = -ENODEV ; +break ; + }if (signal_pending (current)) { err = -ERESTARTSYS ;break ;
sound/core/pcm.c +5 -1
@@ -1087,12 +1087,16 @@ static int snd_pcm_dev_disconnect(struct goto unlock;mutex_lock (&pcm->open_mutex); +wake_up (&pcm->open_wait);list_del_init (&pcm->list);for (cidx =0 ; cidx <2 ; cidx++)for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) {snd_pcm_stream_lock_irq (substream); -if (substream->runtime) +if (substream->runtime) { substream->runtime->status->state =SNDRV_PCM_STATE_DISCONNECTED ; +wake_up (&substream->runtime->sleep); +wake_up (&substream->runtime->tsleep); + }snd_pcm_stream_unlock_irq (substream); }list_for_each_entry (notify, &snd_pcm_notify_list, list) {
sound/core/pcm_native.c +8 -0
@@ -1508,6 +1508,10 @@ static int snd_pcm_drain(struct snd_pcm_down_read (&snd_pcm_link_rwsem);snd_pcm_stream_lock_irq (substream);remove_wait_queue (&to_check->sleep, &wait); +if (card->shutdown) { + result = -ENODEV ; +break ; + }if (tout ==0 ) {if (substream->runtime->status->state ==SNDRV_PCM_STATE_SUSPENDED ) result = -ESTRPIPE ;
@@ -2158,6 +2162,10 @@ static int snd_pcm_open(struct file *filmutex_unlock (&pcm->open_mutex);schedule ();mutex_lock (&pcm->open_mutex); +if (pcm->card->shutdown) { + err = -ENODEV ; +break ; + }if (signal_pending (current)) { err = -ERESTARTSYS ;break ;
sound/core/rawmidi.c +20 -0
@@ -424,6 +424,10 @@ static int snd_rawmidi_open(struct inodemutex_unlock (&rmidi->open_mutex);schedule ();mutex_lock (&rmidi->open_mutex); +if (rmidi->card->shutdown) { + err = -ENODEV ; +break ; + }if (signal_pending (current)) { err = -ERESTARTSYS ;break ;
@@ -995,6 +999,8 @@ static ssize_t snd_rawmidi_read(struct fspin_unlock_irq (&runtime->lock);schedule ();remove_wait_queue (&runtime->sleep, &wait); +if (rfile->rmidi->card->shutdown) +return -ENODEV ;if (signal_pending (current))return result >0 ? result : -ERESTARTSYS ;if (!runtime->avail)
@@ -1238,6 +1244,8 @@ static ssize_t snd_rawmidi_write(structspin_unlock_irq (&runtime->lock); timeout =schedule_timeout (30 *HZ );remove_wait_queue (&runtime->sleep, &wait); +if (rfile->rmidi->card->shutdown) +return -ENODEV ;if (signal_pending (current))return result >0 ? result : -ERESTARTSYS ;if (!runtime->avail && !timeout)
@@ -1613,9 +1621,20 @@ static int snd_rawmidi_dev_register(strustatic int snd_rawmidi_dev_disconnect (struct snd_device *device) {struct snd_rawmidi *rmidi = device->device_data; +int dir;mutex_lock (®ister_mutex); +mutex_lock (&rmidi->open_mutex); +wake_up (&rmidi->open_wait);list_del_init (&rmidi->list); +for (dir =0 ; dir <2 ; dir++) { +struct snd_rawmidi_substream *s; +list_for_each_entry (s, &rmidi->streams[dir].substreams, list) { +if (s->runtime) +wake_up (&s->runtime->sleep); + } + } +#ifdef CONFIG_SND_OSSEMUL if (rmidi->ossreg) {if ((int )rmidi->device == midi_map[rmidi->card->number]) {
@@ -1630,6 +1649,7 @@ static int snd_rawmidi_dev_disconnect(st }#endif /* CONFIG_SND_OSSEMUL */ snd_unregister_device (SNDRV_DEVICE_TYPE_RAWMIDI , rmidi->card, rmidi->device); +mutex_unlock (&rmidi->open_mutex);mutex_unlock (®ister_mutex);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 37/57 sctp: fix call to SCTP_CMD_PROCESS_SACK in sctp_cmd_interpreter()
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zijie Pan <[email protected]>
[ Upstream commit f6e80abeab928b7c47cc1fbf53df13b4398a2bec ]
Bug introduced by commit edfee0339e681a784ebacec7e8c2dc97dc6d2839 (sctp: check src addr when processing SACK to update transport state)
--- net/sctp/sm_sideeffect.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/sctp/sm_sideeffect.c +2 -1
@@ -1610,8 +1610,9 @@ static int sctp_cmd_interpreter(sctp_eve asoc->outqueue.outstanding_bytes; sackh.num_gap_ack_blocks =0 ; sackh.num_dup_tsns =0 ; + chunk->subh.sack_hdr = &sackh;sctp_add_cmd_sf (commands,SCTP_CMD_PROCESS_SACK , -SCTP_SACKH (&sackh)); +SCTP_CHUNK (chunk));break ;case SCTP_CMD_DISCARD_PACKET :
Greg Kroah-Hartman
maintainerPATCH 38/57 netlink: use kfree_rcu() in netlink_release()
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 6d772ac5578f711d1ce7b03535d1c95bffb21dff ]
On some suspend/resume operations involving wimax device, we have noticed some intermittent memory corruptions in netlink code.
Stéphane Marchesin tracked this corruption in netlink_update_listeners() and suggested a patch.
It appears netlink_release() should use kfree_rcu() instead of kfree() for the listeners structure as it may be used by other cpus using RCU protection.
netlink_release() must set to NULL the listeners pointer when it is about to be freed.
Also have to protect netlink_update_listeners() and netlink_has_listeners() if listeners is NULL.
Add a nl_deref_protected() lockdep helper to properly document which locks protects us.
--- net/netlink/af_netlink.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
net/netlink/af_netlink.c +15 -4
@@ -137,6 +137,8 @@ static void netlink_destroy_callback(strstatic DEFINE_RWLOCK (nl_table_lock);static atomic_t nl_table_users =ATOMIC_INIT (0 ); +#define nl_deref_protected (X ) rcu_dereference_protected(X, lockdep_is_held(&nl_table_lock)); +static ATOMIC_NOTIFIER_HEAD (netlink_chain);static inline u32 netlink_group_mask (u32 group)
@@ -332,6 +334,11 @@ netlink_update_listeners(struct sock *skstruct hlist_node *node;unsigned long mask;unsigned int i; +struct listeners *listeners; + + listeners =nl_deref_protected (tbl->listeners); +if (!listeners) +return ;for (i =0 ; i <NLGRPLONGS (tbl->groups); i++) { mask =0 ;
@@ -339,7 +346,7 @@ netlink_update_listeners(struct sock *skif (i <NLGRPLONGS (nlk_sk (sk)->ngroups)) mask |=nlk_sk (sk)->groups[i]; } - tbl->listeners->masks[i] = mask; + listeners->masks[i] = mask; }/* this function is only called with the netlink table "grabbed", which * makes sure updates are visible before bind or setsockopt return. */
@@ -520,7 +527,11 @@ static int netlink_release(struct socketif (netlink_is_kernel (sk)) {BUG_ON (nl_table[sk->sk_protocol].registered ==0 );if (--nl_table[sk->sk_protocol].registered ==0 ) { -kfree (nl_table[sk->sk_protocol].listeners); +struct listeners *old; + + old =nl_deref_protected (nl_table[sk->sk_protocol].listeners); +RCU_INIT_POINTER (nl_table[sk->sk_protocol].listeners,NULL ); +kfree_rcu (old, rcu); nl_table[sk->sk_protocol].module =NULL ; nl_table[sk->sk_protocol].registered =0 ; }
@@ -950,7 +961,7 @@ int netlink_has_listeners(struct sock *srcu_read_lock (); listeners =rcu_dereference (nl_table[sk->sk_protocol].listeners); -if (group -1 < nl_table[sk->sk_protocol].groups) +if (listeners && group -1 < nl_table[sk->sk_protocol].groups) res =test_bit (group -1 , listeners->masks);rcu_read_unlock ();
@@ -1582,7 +1593,7 @@ int __netlink_change_ngroups(struct sock new =kzalloc (sizeof (*new) +NLGRPSZ (groups),GFP_ATOMIC );if (!new)return -ENOMEM ; - old =rcu_dereference_protected (tbl->listeners,1 ); + old =nl_deref_protected (tbl->listeners);memcpy (new->masks, old->masks,NLGRPSZ (tbl->groups));rcu_assign_pointer (tbl->listeners, new);
Greg Kroah-Hartman
maintainerPATCH 39/57 tcp: fix FIONREAD/SIOCINQ
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit a3374c42aa5f7237e87ff3b0622018636b0c847e ]
tcp_ioctl() tries to take into account if tcp socket received a FIN to report correct number bytes in receive queue.
But its flaky because if the application ate the last skb, we return 1 instead of 0.
Correct way to detect that FIN was received is to test SOCK_DONE.
--- net/ipv4/tcp.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
net/ipv4/tcp.c +3 -5
@@ -481,14 +481,12 @@ int tcp_ioctl(struct sock *sk, int cmd, !tp->urg_data || before(tp->urg_seq, tp->copied_seq) || !before(tp->urg_seq, tp->rcv_nxt)) { -struct sk_buff *skb; answ = tp->rcv_nxt - tp->copied_seq; -/* Subtract 1, if FIN is in queue. */ - skb =skb_peek_tail (&sk->sk_receive_queue); -if (answ && skb) - answ -=tcp_hdr (skb)->fin; +/* Subtract 1, if FIN was received */ +if (answ &&sock_flag (sk,SOCK_DONE )) + answ--; } else answ = tp->urg_seq - tp->copied_seq;release_sock (sk);
Greg Kroah-Hartman
maintainerPATCH 40/57 ipv6: Set default hoplimit as zero.
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li RongQing <[email protected]>
[ Upstream commit 14edd87dc67311556f1254a8f29cf4dd6cb5b7d1 ]
Commit a02e4b7dae4551(Demark default hoplimit as zero) only changes the hoplimit checking condition and default value in ip6_dst_hoplimit, not zeros all hoplimit default value.
Keep the zeroing ip6_template_metrics[RTAX_HOPLIMIT - 1] to force it as const, cause as a37e6e344910(net: force dst_default_metrics to const section)
--- net/ipv6/route.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/ipv6/route.c +2 -2
@@ -203,7 +203,7 @@ static struct dst_ops ip6_dst_blackhole_ };static const u32 ip6_template_metrics[RTAX_MAX ] = { - [RTAX_HOPLIMIT -1 ] =255 , + [RTAX_HOPLIMIT -1 ] =0 , };static struct rt6_info ip6_null_entry_template = {
@@ -1135,7 +1135,7 @@ struct dst_entry *icmp6_dst_alloc(struct rt->rt6i_dst.addr = fl6->daddr; rt->rt6i_dst.plen =128 ; rt->rt6i_idev = idev; -dst_metric_set (&rt->dst,RTAX_HOPLIMIT ,255 ); +dst_metric_set (&rt->dst,RTAX_HOPLIMIT ,0 );spin_lock_bh (&icmp6_dst_lock); rt->dst.next = icmp6_dst_gc_list;
Greg Kroah-Hartman
maintainerPATCH 41/57 net: usb: Fix memory leak on Tx data path
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hemant Kumar <[email protected]>
[ Upstream commit 39707c2a3ba5011038b363f84d37c8a98d2d9db1 ]
Driver anchors the tx urbs and defers the urb submission if a transmit request comes when the interface is suspended. Anchoring urb increments the urb reference count. These deferred urbs are later accessed by calling usb_get_from_anchor() for submission during interface resume. usb_get_from_anchor() unanchors the urb but urb reference count remains same. This causes the urb reference count to remain non-zero after usb_free_urb() gets called and urb never gets freed. Hence call usb_put_urb() after anchoring the urb to properly balance the reference count for these deferred urbs. Also, unanchor these deferred urbs during disconnect, to free them up.
--- drivers/net/usb/usbnet.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/usb/usbnet.c +3 -0
@@ -1158,6 +1158,7 @@ netdev_tx_t usbnet_start_xmit (struct skusb_anchor_urb (urb, &dev->deferred);/* no use to process more packets */ netif_stop_queue (net); +usb_put_urb (urb);spin_unlock_irqrestore (&dev->txq.lock, flags);netdev_dbg (dev->net,"Delaying transmission for resumption\n" ); goto deferred;
@@ -1299,6 +1300,8 @@ void usbnet_disconnect (struct usb_intercancel_work_sync (&dev->kevent); +usb_scuttle_anchored_urbs (&dev->deferred); +if (dev->driver_info->unbind) dev->driver_info->unbind (dev, intf);
Greg Kroah-Hartman
maintainerPATCH 42/57 net: fix divide by zero in tcp algorithm illinois
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesper Dangaard Brouer <[email protected]>
[ Upstream commit 8f363b77ee4fbf7c3bbcf5ec2c5ca482d396d664 ]
Reading TCP stats when using TCP Illinois congestion control algorithm can cause a divide by zero kernel oops.
The division by zero occur in tcp_illinois_info() at:
do_div(t, ca->cnt_rtt);
where ca->cnt_rtt can become zero (when rtt_reset is called)
Steps to Reproduce:
1. Register tcp_illinois:
# sysctl -w net.ipv4.tcp_congestion_control=illinois
2. Monitor internal TCP information via command "ss -i"
# watch -d ss -i
3. Establish new TCP conn to machineEither it fails at the initial conn, or else it needs to wait for a loss or a reset.
This is only related to reading stats. The function avg_delay() also performs the same divide, but is guarded with a (ca->cnt_rtt > 0) at its calling point in update_params(). Thus, simply fix tcp_illinois_info().
Function tcp_illinois_info() / get_info() is called without socket lock. Thus, eliminate any race condition on ca->cnt_rtt by using a local stack variable. Simply reuse info.tcpv_rttcnt, as its already set to ca->cnt_rtt.
Function avg_delay() is not affected by this race condition, as its called with the socket lock.
--- net/ipv4/tcp_illinois.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
net/ipv4/tcp_illinois.c +5 -3
@@ -313,11 +313,13 @@ static void tcp_illinois_info(struct soc .tcpv_rttcnt = ca->cnt_rtt, .tcpv_minrtt = ca->base_rtt, }; -u64 t = ca->sum_rtt; -do_div (t, ca->cnt_rtt); - info.tcpv_rtt = t; +if (info.tcpv_rttcnt >0 ) { +u64 t = ca->sum_rtt; +do_div (t, info.tcpv_rttcnt); + info.tcpv_rtt = t; + }nla_put (skb,INET_DIAG_VEGASINFO ,sizeof (info), &info); } }
Greg Kroah-Hartman
maintainerPATCH 43/57 drivers/net/ethernet/nxp/lpc_eth.c: Call mdiobus_unregister before mdiobus_free
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Senna Tschudin <[email protected]>
[ Upstream commit 57c10b61c84bfed68b1b317d6f507a392724b9c4 ]
Based on commit b27393aecf66199f5ddad37c302d3e0cfadbe6c0
Calling mdiobus_free without calling mdiobus_unregister causes BUG_ON(). This patch fixes the issue.
The semantic patch that found this issue(http://coccinelle.lip6.fr/):
// <smpl>
@@
expression E;
@@
... when != mdiobus_unregister(E);
+ mdiobus_unregister(E);
mdiobus_free(E);
// </smpl>
--- drivers/net/ethernet/nxp/lpc_eth.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/nxp/lpc_eth.c +1 -0
@@ -1523,6 +1523,7 @@ static int lpc_eth_drv_remove(struct pla pldat->dma_buff_base_p);free_irq (ndev->irq, ndev);iounmap (pldat->net_base); +mdiobus_unregister (pldat->mii_bus);mdiobus_free (pldat->mii_bus);clk_disable (pldat->clk);clk_put (pldat->clk);
Greg Kroah-Hartman
maintainerPATCH 44/57 l2tp: fix oops in l2tp_eth_create() error path
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tom Parkin <[email protected]>
[ Upstream commit 789336360e0a2aeb9750c16ab704a02cbe035e9e ]
When creating an L2TPv3 Ethernet session, if register_netdev() should fail for any reason (for example, automatic naming for "l2tpeth%d" interfaces hits the 32k-interface limit), the netdev is freed in the error path. However, the l2tp_eth_sess structure's dev pointer is left uncleared, and this results in l2tp_eth_delete() then attempting to unregister the same netdev later in the session teardown. This results in an oops.
To avoid this, clear the session dev pointer in the error path.
--- net/l2tp/l2tp_eth.c | 1 + 1 file changed, 1 insertion(+)
net/l2tp/l2tp_eth.c +1 -0
@@ -269,6 +269,7 @@ static int l2tp_eth_create(struct net *n out_del_dev:free_netdev (dev); + spriv->dev =NULL ; out_del_session:l2tp_session_delete (session); out:
Greg Kroah-Hartman
maintainerPATCH 45/57 net: inet_diag -- Return error code if protocol handler is missed
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cyrill Gorcunov <[email protected]>
[ Upstream commit cacb6ba0f36ab14a507f4ee7697e8332899015d2 ]
We've observed that in case if UDP diag module is not supported in kernel the netlink returns NLMSG_DONE without notifying a caller that handler is missed.
This patch makes __inet_diag_dump to return error code instead.
So as example it become possible to detect such situation and handle it gracefully on userspace level.
--- net/ipv4/inet_diag.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
net/ipv4/inet_diag.c +4 -1
@@ -875,13 +875,16 @@ static int __inet_diag_dump(struct sk_bu struct inet_diag_req_v2 *r, struct nlattr *bc) { const struct inet_diag_handler *handler; +int err =0 ; handler =inet_diag_lock_handler (r->sdiag_protocol);if (!IS_ERR (handler)) handler->dump (skb, cb, r, bc); +else + err =PTR_ERR (handler);inet_diag_unlock_handler (handler); -return skb->len; +return err ? : skb->len; }static int inet_diag_dump (struct sk_buff *skb,struct netlink_callback *cb)
Greg Kroah-Hartman
maintainerPATCH 46/57 af-packet: fix oops when socket is not present
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Leblond <[email protected]>
[ Upstream commit a3d744e995d2b936c500585ae39d99ee251c89b4 ]
Due to a NULL dereference, the following patch is causing oops in normal trafic condition:
commit c0de08d04215031d68fa13af36f347a6cfa252ca
Author: Eric Leblond <[email protected]>
Date: Thu Aug 16 22:02:58 2012 +0000
af_packet: don't emit packet on orig fanout group
This buggy patch was a feature fix and has reached most stable branches.
When skb->sk is NULL and when packet fanout is used, there is a crash in match_fanout_group where skb->sk is accessed. This patch fixes the issue by returning false as soon as the socket is NULL: this correspond to the wanted behavior because the kernel as to resend the skb to all the listening socket in this case.
--- net/core/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/dev.c +1 -1
@@ -1643,7 +1643,7 @@ static inline int deliver_skb(struct sk_static inline bool skb_loop_sk (struct packet_type *ptype,struct sk_buff *skb) { -if (ptype->af_packet_priv ==NULL ) +if (!ptype->af_packet_priv || !skb->sk)return false;if (ptype->id_match)
Greg Kroah-Hartman
maintainerPATCH 47/57 ipv6: send unsolicited neighbour advertisements to all-nodes
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hannes Frederic Sowa <[email protected]>
[ Upstream commit 60713a0ca7fd6651b951cc1b4dbd528d1fc0281b ]
As documented in RFC4861 (Neighbor Discovery for IP version 6) 7.2.6., unsolicited neighbour advertisements should be sent to the all-nodes multicast address.
--- net/ipv6/ndisc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
net/ipv6/ndisc.c +1 -2
@@ -593,7 +593,7 @@ static void ndisc_send_unsol_na(struct n {struct inet6_dev *idev;struct inet6_ifaddr *ifa; -struct in6_addr mcaddr; +struct in6_addr mcaddr =IN6ADDR_LINKLOCAL_ALLNODES_INIT ; idev =in6_dev_get (dev);if (!idev)
@@ -601,7 +601,6 @@ static void ndisc_send_unsol_na(struct nread_lock_bh (&idev->lock);list_for_each_entry (ifa, &idev->addr_list, if_list) { -addrconf_addr_solict_mult (&ifa->addr, &mcaddr); ndisc_send_na(dev, NULL, &mcaddr, &ifa->addr, /*router=*/ !!idev->cnf.forwarding, /*solicited=*/ false, /*override=*/ true,
Greg Kroah-Hartman
maintainerPATCH 48/57 futex: Handle futex_pi OWNER_DIED take over correctly
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
commit 59fa6245192159ab5e1e17b8e31f15afa9cff4bf upstream.
Siddhesh analyzed a failure in the take over of pi futexes in case the owner died and provided a workaround.
See: http://sourceware.org/bugzilla/show_bug.cgi?id=14076
The detailed problem analysis shows:
Futex F is initialized with PTHREAD_PRIO_INHERIT and PTHREAD_MUTEX_ROBUST_NP attributes.
T1 lock_futex_pi(F);
T2 lock_futex_pi(F);
--> T2 blocks on the futex and creates pi_state which is associated
to T1.
T1 exits
--> exit_robust_list() runs
--> Futex F userspace value TID field is set to 0 and
FUTEX_OWNER_DIED bit is set.
T3 lock_futex_pi(F);
--> Succeeds due to the check for F's userspace TID field == 0 --> Claims ownership of the futex and sets its own TID into the
userspace TID field of futex F
--> returns to user space
T1 --> exit_pi_state_list()
--> Transfers pi_state to waiter T2 and wakes T2 via
rt_mutex_unlock(&pi_state->mutex)T2 --> acquires pi_state->mutex and gains real ownership of the
pi_state
--> Claims ownership of the futex and sets its own TID into the
userspace TID field of futex F
--> returns to user space
T3 --> observes inconsistent state
This problem is independent of UP/SMP, preemptible/non preemptible kernels, or process shared vs. private. The only difference is that certain configurations are more likely to expose it.
So as Siddhesh correctly analyzed the following check in futex_lock_pi_atomic() is the culprit:
if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) {We check the userspace value for a TID value of 0 and take over the futex unconditionally if that's true.
AFAICT this check is there as it is correct for a different corner case of futexes: the WAITERS bit became stale.
Now the proposed change
- if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) {
+ if (unlikely(ownerdied ||
+ !(curval & (FUTEX_TID_MASK | FUTEX_WAITERS)))) {
solves the problem, but it's not obvious why and it wreckages the "stale WAITERS bit" case.
What happens is, that due to the WAITERS bit being set (T2 is blocked on that futex) it enforces T3 to go through lookup_pi_state(), which in the above case returns an existing pi_state and therefor forces T3 to legitimately fight with T2 over the ownership of the pi_state (via pi_state->mutex). Probelm solved!
Though that does not work for the "WAITERS bit is stale" problem because if lookup_pi_state() does not find existing pi_state it returns -ERSCH (due to TID == 0) which causes futex_lock_pi() to return -ESRCH to user space because the OWNER_DIED bit is not set.
Now there is a different solution to that problem. Do not look at the user space value at all and enforce a lookup of possibly available pi_state. If pi_state can be found, then the new incoming locker T3 blocks on that pi_state and legitimately races with T2 to acquire the rt_mutex and the pi_state and therefor the proper ownership of the user space futex.
lookup_pi_state() has the correct order of checks. It first tries to find a pi_state associated with the user space futex and only if that fails it checks for futex TID value = 0. If no pi_state is available nothing can create new state at that point because this happens with the hash bucket lock held.
So the above scenario changes to:
T1 lock_futex_pi(F);
T2 lock_futex_pi(F);
--> T2 blocks on the futex and creates pi_state which is associated
to T1.
T1 exits
--> exit_robust_list() runs
--> Futex F userspace value TID field is set to 0 and
FUTEX_OWNER_DIED bit is set.
T3 lock_futex_pi(F);
--> Finds pi_state and blocks on pi_state->rt_mutex
T1 --> exit_pi_state_list()
--> Transfers pi_state to waiter T2 and wakes it via
rt_mutex_unlock(&pi_state->mutex)T2 --> acquires pi_state->mutex and gains ownership of the pi_state
--> Claims ownership of the futex and sets its own TID into the
userspace TID field of futex F
--> returns to user space
This covers all gazillion points on which T3 might come in between T1's exit_robust_list() clearing the TID field and T2 fixing it up. It also solves the "WAITERS bit stale" problem by forcing the take over.
Another benefit of changing the code this way is that it makes it less dependent on untrusted user space values and therefor minimizes the possible wreckage which might be inflicted.
As usual after staring for too long at the futex code my brain hurts so much that I really want to ditch that whole optimization of avoiding the syscall for the non contended case for PI futexes and rip out the maze of corner case handling code. Unfortunately we can't as user space relies on that existing behaviour, but at least thinking about it helps me to preserve my mental sanity. Maybe we should nevertheless :)
--- kernel/futex.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-)
kernel/futex.c +22 -19
@@ -716,7 +716,7 @@ static int futex_lock_pi_atomic(u32 __usstruct futex_pi_state **ps, struct task_struct *task, int set_waiters) { - int lock_taken, ret, ownerdied = 0; + int lock_taken, ret, force_take = 0;u32 uval, newval, curval, vpid =task_pid_vnr (task); retry:
@@ -755,17 +755,15 @@ retry: newval = curval |FUTEX_WAITERS ;/* -* There are two cases, where a futex might have no owner (the -* owner TID is 0): OWNER_DIED. We take over the futex in this -* case. We also do an unconditional take over, when the owner -* of the futex died. -* -* This is safe as we are protected by the hash bucket lock ! +* Should we force take the futex? See below. */ -if (unlikely (ownerdied || !(curval &FUTEX_TID_MASK ))) { -/* Keep the OWNER_DIED bit */ +if (unlikely (force_take)) { +/* +* Keep the OWNER_DIED and the WAITERS bit and set the +* new TID value. +*/ newval = (curval & ~FUTEX_TID_MASK ) | vpid; - ownerdied =0 ; + force_take =0 ; lock_taken =1 ; }
@@ -775,7 +773,7 @@ retry: goto retry;/* -* We took the lock due to owner died take over. +* We took the lock due to forced take over. */ if (unlikely (lock_taken))return 1 ;
@@ -790,20 +788,25 @@ retry:switch (ret) {case -ESRCH :/* -* No owner found for this futex. Check if the -* OWNER_DIED bit is set to figure out whether -* this is a robust futex or not. +* We failed to find an owner for this +* futex. So we have no pi_state to block +* on. This can happen in two cases: +* +* 1) The owner died +* 2) A stale FUTEX_WAITERS bit +* +* Re-read the futex value. */ if (get_futex_value_locked (&curval, uaddr))return -EFAULT ;/* -* We simply start over in case of a robust -* futex. The code above will take the futex -* and return happy. +* If the owner died or we have a stale +* WAITERS bit the owner TID in the user space +* futex is 0. */ -if (curval &FUTEX_OWNER_DIED ) { - ownerdied =1 ; +if (!(curval &FUTEX_TID_MASK )) { + force_take =1 ; goto retry; }default :
Greg Kroah-Hartman
maintainerPATCH 49/57 mmc: sdhci: fix NULL dereference in sdhci_request() tuning
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Ball <[email protected]>
commit 14efd957209461bbdf285bf0d67e931955d04a4c upstream.
Commit 473b095a72a9 ("mmc: sdhci: fix incorrect command used in tuning") introduced a NULL dereference at resume-time if an SD 3.0 host controller raises the SDHCI_NEEDS_TUNING flag while no card is inserted. Seen on an OLPC XO-4 with sdhci-pxav3, but presumably affects other controllers too.
--- drivers/mmc/host/sdhci.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-)
drivers/mmc/host/sdhci.c +12 -9
@@ -1294,16 +1294,19 @@ static void sdhci_request(struct mmc_hos*/ if ((host->flags &SDHCI_NEEDS_RETUNING ) && !(present_state & (SDHCI_DOING_WRITE |SDHCI_DOING_READ ))) { -/* eMMC uses cmd21 while sd and sdio use cmd19 */ - tuning_opcode = mmc->card->type ==MMC_TYPE_MMC ? -MMC_SEND_TUNING_BLOCK_HS200 : -MMC_SEND_TUNING_BLOCK ; -spin_unlock_irqrestore (&host->lock, flags); -sdhci_execute_tuning (mmc, tuning_opcode); -spin_lock_irqsave (&host->lock, flags); +if (mmc->card) { +/* eMMC uses cmd21 but sd and sdio use cmd19 */ + tuning_opcode = + mmc->card->type ==MMC_TYPE_MMC ? +MMC_SEND_TUNING_BLOCK_HS200 : +MMC_SEND_TUNING_BLOCK ; +spin_unlock_irqrestore (&host->lock, flags); +sdhci_execute_tuning (mmc, tuning_opcode); +spin_lock_irqsave (&host->lock, flags); -/* Restore original mmc_request structure */ - host->mrq = mrq; +/* Restore original mmc_request structure */ + host->mrq = mrq; + } }if (mrq->sbc && !(host->flags &SDHCI_AUTO_CMD23 ))
Greg Kroah-Hartman
maintainerPATCH 50/57 drm/vmwgfx: Fix hibernation device reset
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Hellstrom <[email protected]>
commit 95e8f6a21996c4cc2c4574b231c6e858b749dce3 upstream.
The device would not reset properly when resuming from hibernation.
--- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +5 -0
@@ -1102,6 +1102,11 @@ static void vmw_pm_complete(struct devicstruct drm_device *dev =pci_get_drvdata (pdev);struct vmw_private *dev_priv =vmw_priv (dev); +mutex_lock (&dev_priv->hw_mutex); +vmw_write (dev_priv,SVGA_REG_ID ,SVGA_ID_2 ); + (void )vmw_read (dev_priv,SVGA_REG_ID ); +mutex_unlock (&dev_priv->hw_mutex); +/** * Reclaim 3d reference held by fbdev and potentially * start fifo.
Greg Kroah-Hartman
maintainerPATCH 51/57 drm/vmwgfx: Fix a case where the code would BUG when trying to pin GMR memory
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Hellstrom <[email protected]>
commit afcc87aa6a233e52df73552dc1dc9ae3881b7cc8 upstream.
--- drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c +1 -1
@@ -306,7 +306,7 @@ void vmw_bo_pin(struct ttm_buffer_objectBUG_ON (!atomic_read (&bo->reserved));BUG_ON (old_mem_type !=TTM_PL_VRAM && - old_mem_type !=VMW_PL_FLAG_GMR ); + old_mem_type !=VMW_PL_GMR ); pl_flags =TTM_PL_FLAG_VRAM |VMW_PL_FLAG_GMR |TTM_PL_FLAG_CACHED ;if (pin)
Greg Kroah-Hartman
maintainerPATCH 52/57 drm/radeon/cayman: add some missing regs to the VM reg checker
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 860fe2f05fa2eacac84368e23547ec8cf3cc6652 upstream.
These regs were being wronly rejected leading to rendering issues.
fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=56876
--- drivers/gpu/drm/radeon/evergreen_cs.c | 3 +++ drivers/gpu/drm/radeon/evergreend.h | 4 ++++ 2 files changed, 7 insertions(+)
drivers/gpu/drm/radeon/evergreen_cs.c +3 -0
@@ -2671,6 +2671,9 @@ static bool evergreen_vm_reg_valid(u32 r/* check config regs */ switch (reg) {case GRBM_GFX_INDEX : +case CP_STRMOUT_CNTL : +case CP_COHER_CNTL : +case CP_COHER_SIZE :case VGT_VTX_VECT_EJECT_REG :case VGT_CACHE_INVALIDATION :case VGT_GS_VERTEX_REUSE :
drivers/gpu/drm/radeon/evergreend.h +4 -0
@@ -77,6 +77,10 @@#define CONFIG_MEMSIZE 0x5428 +#define CP_STRMOUT_CNTL 0x84FC + +#define CP_COHER_CNTL 0x85F0 +#define CP_COHER_SIZE 0x85F4#define CP_COHER_BASE 0x85F8#define CP_ME_CNTL 0x86D8#define CP_ME_HALT (1 << 28)
Greg Kroah-Hartman
maintainerPATCH 53/57 drm/radeon/si: add some missing regs to the VM reg checker
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit f418b88aad0c42b4caf4d79a0cf8d14a5d0a2284 upstream.
This register is needed for streamout to work properly.
--- drivers/gpu/drm/radeon/si.c | 1 + drivers/gpu/drm/radeon/sid.h | 1 + 2 files changed, 2 insertions(+)
drivers/gpu/drm/radeon/si.c +1 -0
@@ -2593,6 +2593,7 @@ static bool si_vm_reg_valid(u32 reg)/* check config regs */ switch (reg) {case GRBM_GFX_INDEX : +case CP_STRMOUT_CNTL :case VGT_VTX_VECT_EJECT_REG :case VGT_CACHE_INVALIDATION :case VGT_ESGS_RING_SIZE :
drivers/gpu/drm/radeon/sid.h +1 -0
@@ -413,6 +413,7 @@# define RDERR_INT_ENABLE (1 << 0)# define GUI_IDLE_INT_ENABLE (1 << 19) +#define CP_STRMOUT_CNTL 0x84FC#define SCRATCH_REG0 0x8500#define SCRATCH_REG1 0x8504#define SCRATCH_REG2 0x8508
Greg Kroah-Hartman
maintainerPATCH 54/57 drm/i915: fixup infoframe support for sdvo
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Vetter <[email protected]>
commit 81014b9d0b55fb0b48f26cd2a943359750d532db upstream.
At least the worst offenders:
- SDVO specifies that the encoder should compute the ecc. Testing also shows that we must not send the ecc field, so copy the dip_infoframe struct to a temporay place and avoid the ecc field. This way the avi infoframe is exactly 17 bytes long, which agrees with what the spec mandates as a minimal storage capacity (with the ecc field it would be 18 bytes).
- Only 17 when sending the avi infoframe. The SDVO spec explicitly says that sending more data than what the device announces results in undefined behaviour.
- Add __attribute__((packed)) to the avi and spd infoframes, for otherwise they're wrongly aligned. Noticed because the avi infoframe ended up being 18 bytes large instead of 17. We haven't noticed this yet because we don't use the uint16_t fields yet (which are the only ones that would be wrongly aligned).
This regression has been introduce by
3c17fe4b8f40a112a85758a9ab2aebf772bdd647 is the first bad commit commit 3c17fe4b8f40a112a85758a9ab2aebf772bdd647
Author: David Härdeman <[email protected]> Date: Fri Sep 24 21:44:32 2010 +0200
i915: enable AVI infoframe for intel_hdmi.c [v4]
Patch tested on my g33 with a sdvo hdmi adaptor.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=25732
--- drivers/gpu/drm/i915/intel_drv.h | 4 ++-- drivers/gpu/drm/i915/intel_sdvo.c | 11 +++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-)
drivers/gpu/drm/i915/intel_drv.h +2 -2
@@ -247,12 +247,12 @@ struct dip_infoframe {uint16_t bottom_bar_start;uint16_t left_bar_end;uint16_t right_bar_start; - } avi; + } __attribute__ ((packed)) avi;struct {uint8_t vn[8 ];uint8_t pd[16 ];uint8_t sdi; - } spd; + } __attribute__ ((packed)) spd;uint8_t payload[27 ]; } __attribute__ ((packed)) body; } __attribute__((packed));
drivers/gpu/drm/i915/intel_sdvo.c +9 -2
@@ -877,17 +877,24 @@ static bool intel_sdvo_set_avi_infoframe };uint8_t tx_rate =SDVO_HBUF_TX_VSYNC ;uint8_t set_buf_index[2 ] = {1 ,0 }; -uint64_t *data = (uint64_t *)&avi_if; +uint8_t sdvo_data[4 +sizeof (avi_if.body.avi)]; +uint64_t *data = (uint64_t *)sdvo_data;unsigned i;intel_dip_infoframe_csum (&avi_if); +/* sdvo spec says that the ecc is handled by the hw, and it looks like +* we must not send the ecc field, either. */ +memcpy (sdvo_data, &avi_if,3 ); + sdvo_data[3 ] = avi_if.checksum; +memcpy (&sdvo_data[4 ], &avi_if.body,sizeof (avi_if.body.avi)); +if (!intel_sdvo_set_value (intel_sdvo,SDVO_CMD_SET_HBUF_INDEX , set_buf_index,2 ))return false; -for (i =0 ; i <sizeof (avi_if); i +=8 ) { +for (i =0 ; i <sizeof (sdvo_data); i +=8 ) {if (!intel_sdvo_set_value (intel_sdvo,SDVO_CMD_SET_HBUF_DATA , data,8 ))
Greg Kroah-Hartman
maintainerPATCH 55/57 drm/i915: clear the entire sdvo infoframe buffer
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Vetter <[email protected]>
commit b6e0e543f75729f207b9c72b0162ae61170635b2 upstream.
Like in the case of native hdmi, which is fixed already in
commit adf00b26d18e1b3570451296e03bcb20e4798cdd
Author: Paulo Zanoni <[email protected]> Date: Tue Sep 25 13:23:34 2012 -0300
drm/i915: make sure we write all the DIP data bytes
we need to clear the entire sdvo buffer to avoid upsetting the display.
Since infoframe buffer writing is now a bit more elaborate, extract it into it's own function. This will be useful if we ever get around to properly update the ELD for sdvo. Also #define proper names for the two buffer indexes with fixed usage.
v2: Cite the right commit above, spotted by Paulo Zanoni.
v3: I'm too stupid to paste the right commit.
v4: Ben Hutchings noticed that I've failed to handle an underflow in my loop logic, breaking it for i >= length + 8. Since I've just lost C programmer license, use his solution. Also, make the frustrated 0-base buffer size a notch more clear.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=25732
--- drivers/gpu/drm/i915/intel_sdvo.c | 62 ++++++++++++++++++++++----------- drivers/gpu/drm/i915/intel_sdvo_regs.h | 2 + 2 files changed, 44 insertions(+), 20 deletions(-)
drivers/gpu/drm/i915/intel_sdvo.c +42 -20
@@ -868,6 +868,45 @@ static void intel_sdvo_dump_hdmi_buf(str }#endif +static bool intel_sdvo_write_infoframe (struct intel_sdvo *intel_sdvo, +unsigned if_index,uint8_t tx_rate, +uint8_t *data,unsigned length) +{ +uint8_t set_buf_index[2 ] = { if_index,0 }; +uint8_t hbuf_size, tmp[8 ]; +int i; + +if (!intel_sdvo_set_value (intel_sdvo, +SDVO_CMD_SET_HBUF_INDEX , + set_buf_index,2 )) +return false; + +if (!intel_sdvo_get_value (intel_sdvo,SDVO_CMD_GET_HBUF_INFO , + &hbuf_size,1 )) +return false; + +/* Buffer size is 0 based, hooray! */ + hbuf_size++; + +DRM_DEBUG_KMS ("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n" , + if_index, length, hbuf_size); + +for (i =0 ; i < hbuf_size; i +=8 ) { +memset (tmp,0 ,8 ); +if (i < length) +memcpy (tmp, data + i,min_t (unsigned,8 , length - i)); + +if (!intel_sdvo_set_value (intel_sdvo, +SDVO_CMD_SET_HBUF_DATA , + tmp,8 )) +return false; + } + +return intel_sdvo_set_value (intel_sdvo, +SDVO_CMD_SET_HBUF_TXRATE , + &tx_rate,1 ); +} +static bool intel_sdvo_set_avi_infoframe (struct intel_sdvo *intel_sdvo) {struct dip_infoframe avi_if = {
@@ -875,11 +914,7 @@ static bool intel_sdvo_set_avi_infoframe .ver = DIP_VERSION_AVI, .len = DIP_LEN_AVI, }; -uint8_t tx_rate =SDVO_HBUF_TX_VSYNC ; -uint8_t set_buf_index[2 ] = {1 ,0 };uint8_t sdvo_data[4 +sizeof (avi_if.body.avi)]; -uint64_t *data = (uint64_t *)sdvo_data; -unsigned i;intel_dip_infoframe_csum (&avi_if);
@@ -889,22 +924,9 @@ static bool intel_sdvo_set_avi_infoframe sdvo_data[3 ] = avi_if.checksum;memcpy (&sdvo_data[4 ], &avi_if.body,sizeof (avi_if.body.avi)); -if (!intel_sdvo_set_value (intel_sdvo, -SDVO_CMD_SET_HBUF_INDEX , - set_buf_index,2 )) -return false; - -for (i =0 ; i <sizeof (sdvo_data); i +=8 ) { -if (!intel_sdvo_set_value (intel_sdvo, -SDVO_CMD_SET_HBUF_DATA , - data,8 )) -return false; - data++; - } - -return intel_sdvo_set_value (intel_sdvo, -SDVO_CMD_SET_HBUF_TXRATE , - &tx_rate,1 ); +return intel_sdvo_write_infoframe (intel_sdvo,SDVO_HBUF_INDEX_AVI_IF , +SDVO_HBUF_TX_VSYNC , + sdvo_data,sizeof (sdvo_data)); }static bool intel_sdvo_set_tv_format (struct intel_sdvo *intel_sdvo)
drivers/gpu/drm/i915/intel_sdvo_regs.h +2 -0
@@ -708,6 +708,8 @@ struct intel_sdvo_enhancements_arg {#define SDVO_CMD_SET_AUDIO_STAT 0x91#define SDVO_CMD_GET_AUDIO_STAT 0x92#define SDVO_CMD_SET_HBUF_INDEX 0x93 +#define SDVO_HBUF_INDEX_ELD 0 +#define SDVO_HBUF_INDEX_AVI_IF 1#define SDVO_CMD_GET_HBUF_INDEX 0x94#define SDVO_CMD_GET_HBUF_INFO 0x95#define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96
Greg Kroah-Hartman
maintainerPATCH 56/57 USB: mos7840: remove unused variable
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
Fix warning about unused variable introduced by commit e681b66f2e19fa ("USB: mos7840: remove invalid disconnect handling") upstream.
A subsequent fix which removed the disconnect function got rid of the warning but that one was only backported to v3.6.
--- drivers/usb/serial/mos7840.c | 1 - 1 file changed, 1 deletion(-)
drivers/usb/serial/mos7840.c +0 -1
@@ -2581,7 +2581,6 @@ error:static void mos7840_disconnect (struct usb_serial *serial) {int i; -unsigned long flags;struct moschip_port *mos7840_port;dbg ("%s" ," disconnect :entering.........." );
Greg Kroah-Hartman
maintainerPATCH 57/57 xfs: fix reading of wrapped log data
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Chinner <[email protected]>
commit 6ce377afd1755eae5c93410ca9a1121dfead7b87 upstream.
Commit 4439647 ("xfs: reset buffer pointers before freeing them") in 3.0-rc1 introduced a regression when recovering log buffers that wrapped around the end of log. The second part of the log buffer at the start of the physical log was being read into the header buffer rather than the data buffer, and hence recovery was seeing garbage in the data buffer when it got to the region of the log buffer that was incorrectly read.
--- fs/xfs/xfs_log_recover.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/xfs/xfs_log_recover.c +1 -1
@@ -3514,7 +3514,7 @@ xlog_do_recovery_pass(* - order is important. */ error =xlog_bread_offset (log,0 , - bblks - split_bblks, hbp, + bblks - split_bblks, dbp, offset +BBTOB (split_bblks));if (error) goto bread_err2;