2.6.33.13-longterm review
Subsystems (38)
cover 2.6.33.13-longterm review
This is the start of the stable review cycle for the 2.6.33.13 release. There are 43 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 us know. If anyone is a maintainer of the proper subsystem, and wants to add a Signed-off-by: line to the patch, please respond with it.
Responses should be made by Sunday, May 8, 2011, 00:01:00 UTC. 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/v2.6/stable-review/patch-2.6.33.13-rc1.gz
and the diffstat can be found below.
thanks,
greg k-h
Makefile | 2 +- arch/arm/kernel/sys_oabi-compat.c | 2 +- arch/m68k/mm/motorola.c | 2 ++ arch/parisc/mm/init.c | 4 +++- arch/x86/kernel/cpu/amd.c | 2 +- arch/x86/kernel/pci-gart_64.c | 9 ++++++++- block/blk-sysfs.c | 4 +++- drivers/ata/libata-scsi.c | 24 ++++++++++++++++++------ drivers/char/agp/generic.c | 19 +++++++++++++++---- drivers/char/i8k.c | 7 ++++--- drivers/gpu/drm/radeon/atom.c | 6 +++--- drivers/input/xen-kbdfront.c | 12 +++++++++++- drivers/media/dvb/b2c2/flexcop-pci.c | 2 +- drivers/mmc/host/sdhci-pci.c | 1 + drivers/mmc/host/sdhci.c | 9 ++++++++- drivers/net/igbvf/igbvf.h | 1 - drivers/net/wireless/ath/regd_common.h | 1 + drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-tx.c | 8 ++++++-- drivers/net/wireless/p54/txrx.c | 2 +- drivers/pci/intel-iommu.c | 15 +++++++++++++-- drivers/s390/block/dasd_eckd.c | 2 +- drivers/scsi/mpt2sas/mpt2sas_ctl.c | 23 +++++++++++++++++++++-- drivers/scsi/pmcraid.c | 3 +++ drivers/scsi/scsi_sysfs.c | 16 ++++++++-------- drivers/serial/imx.c | 3 ++- drivers/staging/usbip/vhci_hcd.c | 2 +- drivers/usb/musb/musb_core.c | 1 + fs/nfs/inode.c | 26 +++++++++++++++++--------- fs/nfs/nfs4state.c | 4 ++-- fs/nfs/super.c | 9 +++++++++ fs/nfsd/vfs.c | 9 ++++++++- fs/partitions/ldm.c | 16 ++++++++++++---- fs/ubifs/recovery.c | 26 ++++++++++++++++++++++++++ init/Kconfig | 1 + net/can/bcm.c | 7 ++++++- net/ipv4/ip_output.c | 9 ++++++--- net/unix/af_unix.c | 16 +++++++++++++++- scripts/kconfig/conf.c | 2 +- sound/soc/codecs/wm_hubs.c | 8 ++++---- 40 files changed, 246 insertions(+), 71 deletions(-)
PATCH 1/43 ath: add missing regdomain pair 0x5c mapping
2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Christian Lamparter <[email protected]>
commit bd39a274fb7b43374c797bafdb7f506598f36f77 upstream.
Joe Culler reported a problem with his AR9170 device:
Quoted 4 lines
ath: EEPROM regdomain:
0x5c
ath: EEPROM indicates we should expect a direct regpair map
ath: invalid regulatory domain/country code0x5c
ath: Invalid EEPROM contents
It turned out that the regdomain 'APL7_FCCA' was not mapped yet. According to Luis R. Rodriguez [Atheros' engineer] APL7 maps to FCC_CTL and FCCA maps to FCC_CTL as well, so the attached patch should be correct.
--- drivers/net/wireless/ath/regd_common.h | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/ath/regd_common.h +1 -0
@@ -195,6 +195,7 @@ static struct reg_dmn_pair_mapping regDo {APL9_WORLD, CTL_ETSI, CTL_ETSI}, {APL3_FCCA, CTL_FCC, CTL_FCC}, + {APL7_FCCA, CTL_FCC, CTL_FCC}, {APL1_ETSIC, CTL_FCC, CTL_ETSI}, {APL2_ETSIC, CTL_FCC, CTL_ETSI}, {APL2_APLD, CTL_FCC, NO_CTL},
PATCH 2/43 block, blk-sysfs: Fix an err return path in blk_register_queue()
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Liu Yuan <[email protected]>
commit ed5302d3c25006a9edc7a7fbea97a30483f89ef7 upstream.
We do not call blk_trace_remove_sysfs() in err return path if kobject_add() fails. This path fixes it.
--- block/blk-sysfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
block/blk-sysfs.c +3 -1
@@ -473,8 +473,10 @@ int blk_register_queue(struct gendisk *dreturn ret; ret =kobject_add (&q->kobj,kobject_get (&dev->kobj),"%s" ,"queue" ); -if (ret <0 ) +if (ret <0 ) { +blk_trace_remove_sysfs (dev);return ret; + }kobject_uevent (&q->kobj,KOBJ_ADD );
PATCH 3/43 p54: Initialize extra_len in p54_tx_80211
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Jason Conti <[email protected]>
commit a6756da9eace8b4af73e9dea43f1fc2889224c94 upstream.
This patch fixes a very serious off-by-one bug in the driver, which could leave the device in an unresponsive state.
The problem was that the extra_len variable [used to reserve extra scratch buffer space for the firmware] was left uninitialized. Because p54_assign_address later needs the value to reserve additional space, the resulting frame could be to big for the small device's memory window and everything would immediately come to a grinding halt.
Reference: https://bugs.launchpad.net/bugs/722185
--- drivers/net/wireless/p54/txrx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/p54/txrx.c +1 -1
@@ -703,7 +703,7 @@ int p54_tx_80211(struct ieee80211_hw *destruct p54_tx_info *p54info;struct p54_hdr *hdr;struct p54_tx_data *txhdr; -unsigned int padding, len, extra_len; +unsigned int padding, len, extra_len =0 ;int i, j, ridx;u16 hdr_flags =0 , aid =0 ;u8 rate, queue =0 , crypt_offset =0 ;
PATCH 4/43 x86, gart: Make sure GART does not map physmem above 1TB
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Joerg Roedel <[email protected]>
commit 665d3e2af83c8fbd149534db8f57d82fa6fa6753 upstream.
The GART can only map physical memory below 1TB. Make sure the gart driver in the kernel does not try to map memory above 1TB.
--- arch/x86/kernel/pci-gart_64.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
arch/x86/kernel/pci-gart_64.c +8 -1
@@ -79,6 +79,9 @@ static u32 gart_unmapped_entry;#define AGPEXTERN #endif +/* GART can only remap to physical addresses < 1TB */ +#define GART_MAX_PHYS_ADDR (1ULL << 40) +/* backdoor interface to AGP driver */ AGPEXTERN int agp_memory_reserved; AGPEXTERN __u32 *agp_gatt_table;
@@ -210,9 +213,13 @@ static dma_addr_t dma_map_area(struct de size_t size, int dir, unsigned long align_mask) { unsigned long npages = iommu_num_pages(phys_mem, size, PAGE_SIZE); -unsigned long iommu_page =alloc_iommu (dev, npages, align_mask); +unsigned long iommu_page;int i; +if (unlikely (phys_mem + size >GART_MAX_PHYS_ADDR )) +return bad_dma_addr; + + iommu_page =alloc_iommu (dev, npages, align_mask);if (iommu_page ==-1 ) {if (!nonforced_iommu (dev, phys_mem, size))return phys_mem;
PATCH 5/43 intel-iommu: Unlink domain from iommu
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Alex Williamson <[email protected]>
commit a97590e56d0d58e1dd262353f7cbd84e81d8e600 upstream.
When we remove a device, we unlink the iommu from the domain, but we never do the reverse unlinking of the domain from the iommu. This means that we never clear iommu->domain_ids, eventually leading to resource exhaustion if we repeatedly bind and unbind a device to a driver. Also free empty domains to avoid a resource leak.
--- drivers/pci/intel-iommu.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/pci/intel-iommu.c +12 -1
@@ -3238,9 +3238,15 @@ static int device_notifier(struct notifiif (!domain)return 0 ; -if (action ==BUS_NOTIFY_UNBOUND_DRIVER && !iommu_pass_through) +if (action ==BUS_NOTIFY_UNBOUND_DRIVER && !iommu_pass_through) {domain_remove_one_dev_info (domain, pdev); +if (!(domain->flags &DOMAIN_FLAG_VIRTUAL_MACHINE ) && + !(domain->flags &DOMAIN_FLAG_STATIC_IDENTITY ) && +list_empty (&domain->devices)) +domain_exit (domain); + } +return 0 ; }
@@ -3389,6 +3395,11 @@ static void domain_remove_one_dev_info(s domain->iommu_count--;domain_update_iommu_cap (domain);spin_unlock_irqrestore (&domain->iommu_lock, tmp_flags); + +spin_lock_irqsave (&iommu->lock, tmp_flags); +clear_bit (domain->id, iommu->domain_ids); + iommu->domains[domain->id] =NULL ; +spin_unlock_irqrestore (&iommu->lock, tmp_flags); }spin_unlock_irqrestore (&device_domain_lock, flags);
PATCH 6/43 intel-iommu: Fix get_domain_for_dev() error path
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Alex Williamson <[email protected]>
commit 2fe9723df8e45fd247782adea244a5e653c30bf4 upstream.
If we run out of domain_ids and fail iommu_attach_domain(), we fall into domain_exit() without having setup enough of the domain structure for this to do anything useful. In fact, it typically runs off into the weeds walking the bogus domain->devices list. Just free the domain.
--- drivers/pci/intel-iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/intel-iommu.c +1 -1
@@ -1852,7 +1852,7 @@ static struct dmar_domain *get_domain_fo ret =iommu_attach_domain (domain, iommu);if (ret) { -domain_exit (domain); +free_domain_mem (domain); goto error; }
PATCH 7/43 drm/radeon/kms: fix bad shift in atom iio table parser
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Alex Deucher <[email protected]>
commit 8e461123f28e6b17456225e70eb834b3b30d28bb upstream.
Noticed by Patrick Lowry.
--- drivers/gpu/drm/radeon/atom.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/radeon/atom.c +3 -3
@@ -128,7 +128,7 @@ static uint32_t atom_iio_execute(structcase ATOM_IIO_MOVE_INDEX : temp &= ~((0xFFFFFFFF >> (32 -CU8 (base +1 ))) << -CU8 (base +2 )); +CU8 (base +3 )); temp |= ((index >>CU8 (base +2 )) & (0xFFFFFFFF >> (32 - CU8(base + 1)))) << CU8(base +
@@ -138,7 +138,7 @@ static uint32_t atom_iio_execute(structcase ATOM_IIO_MOVE_DATA : temp &= ~((0xFFFFFFFF >> (32 -CU8 (base +1 ))) << -CU8 (base +2 )); +CU8 (base +3 )); temp |= ((data >>CU8 (base +2 )) & (0xFFFFFFFF >> (32 - CU8(base + 1)))) << CU8(base +
@@ -148,7 +148,7 @@ static uint32_t atom_iio_execute(structcase ATOM_IIO_MOVE_ATTR : temp &= ~((0xFFFFFFFF >> (32 -CU8 (base +1 ))) << -CU8 (base +2 )); +CU8 (base +3 )); temp |= ((ctx-> io_attr >> CU8(base + 2)) & (0xFFFFFFFF >> (32 -
PATCH 8/43 NFS: nfs_wcc_update_inode() should set nfsi->attr_gencount
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Trond Myklebust <[email protected]>
commit 27dc1cd3ad9300f81e1219e5fc305d91d85353f8 upstream.
If the call to nfs_wcc_update_inode() results in an attribute update, we need to ensure that the inode's attr_gencount gets bumped too, otherwise we are not protected against races with other GETATTR calls.
--- fs/nfs/inode.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-)
fs/nfs/inode.c +17 -9
@@ -861,9 +861,10 @@ out:return ret; } -static void nfs_wcc_update_inode (struct inode *inode,struct nfs_fattr *fattr) +static unsigned long nfs_wcc_update_inode (struct inode *inode,struct nfs_fattr *fattr) {struct nfs_inode *nfsi =NFS_I (inode); +unsigned long ret =0 ;if ((fattr->valid &NFS_ATTR_FATTR_PRECHANGE ) && (fattr->valid & NFS_ATTR_FATTR_CHANGE)
@@ -871,25 +872,32 @@ static void nfs_wcc_update_inode(struct nfsi->change_attr = fattr->change_attr;if (S_ISDIR (inode->i_mode)) nfsi->cache_validity |=NFS_INO_INVALID_DATA ; + ret |=NFS_INO_INVALID_ATTR ; }/* If we have atomic WCC data, we may update some attributes */ if ((fattr->valid &NFS_ATTR_FATTR_PRECTIME ) && (fattr->valid &NFS_ATTR_FATTR_CTIME ) - &×pec_equal (&inode->i_ctime, &fattr->pre_ctime)) -memcpy (&inode->i_ctime, &fattr->ctime,sizeof (inode->i_ctime)); + &×pec_equal (&inode->i_ctime, &fattr->pre_ctime)) { +memcpy (&inode->i_ctime, &fattr->ctime,sizeof (inode->i_ctime)); + ret |=NFS_INO_INVALID_ATTR ; + }if ((fattr->valid &NFS_ATTR_FATTR_PREMTIME ) && (fattr->valid &NFS_ATTR_FATTR_MTIME ) &×pec_equal (&inode->i_mtime, &fattr->pre_mtime)) { -memcpy (&inode->i_mtime, &fattr->mtime,sizeof (inode->i_mtime)); -if (S_ISDIR (inode->i_mode)) - nfsi->cache_validity |=NFS_INO_INVALID_DATA ; +memcpy (&inode->i_mtime, &fattr->mtime,sizeof (inode->i_mtime)); +if (S_ISDIR (inode->i_mode)) + nfsi->cache_validity |=NFS_INO_INVALID_DATA ; + ret |=NFS_INO_INVALID_ATTR ; }if ((fattr->valid &NFS_ATTR_FATTR_PRESIZE ) && (fattr->valid &NFS_ATTR_FATTR_SIZE ) &&i_size_read (inode) ==nfs_size_to_loff_t (fattr->pre_size) - && nfsi->npages ==0 ) -i_size_write (inode,nfs_size_to_loff_t (fattr->size)); + && nfsi->npages ==0 ) { +i_size_write (inode,nfs_size_to_loff_t (fattr->size)); + ret |=NFS_INO_INVALID_ATTR ; + } +return ret; }/**
@@ -1183,7 +1191,7 @@ static int nfs_update_inode(struct inode | NFS_INO_REVAL_PAGECACHE);/* Do atomic weak cache consistency updates */ -nfs_wcc_update_inode (inode, fattr); + invalid |=nfs_wcc_update_inode (inode, fattr);/* More cache consistency checks */ if (fattr->valid &NFS_ATTR_FATTR_CHANGE ) {
PATCH 9/43 serial/imx: read cts state only after acking cts change irq
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <[email protected]>
commit 5680e94148a86e8c31fdc5cb0ea0d5c6810c05b0 upstream.
If cts changes between reading the level at the cts input (USR1_RTSS) and acking the irq (USR1_RTSD) the last edge doesn't generate an irq and uart_handle_cts_change is called with a outdated value for cts.
The race was introduced by commit
ceca629 ([ARM] 2971/1: i.MX uart handle rts irq)
--- drivers/serial/imx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/serial/imx.c +2 -1
@@ -382,12 +382,13 @@ static void imx_start_tx(struct uart_porstatic irqreturn_t imx_rtsint (int irq,void *dev_id) {struct imx_port *sport = dev_id; -unsigned int val =readl (sport->port.membase +USR1 ) &USR1_RTSS ; +unsigned int val;unsigned long flags;spin_lock_irqsave (&sport->port.lock, flags);writel (USR1_RTSD , sport->port.membase +USR1 ); + val =readl (sport->port.membase +USR1 ) &USR1_RTSS ;uart_handle_cts_change (&sport->port, !!val);wake_up_interruptible (&sport->port.state->port.delta_msr_wait);
PATCH 10/43 ASoC: Fix output PGA enabling in wm_hubs CODECs
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Mark Brown <[email protected]>
commit 39cca168bdfaef9d0c496ec27f292445d6184946 upstream.
The output PGA was not being powered up in headphone and speaker paths, removing the ability to offer volume control and mute with the output PGA.
--- sound/soc/codecs/wm_hubs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
sound/soc/codecs/wm_hubs.c +4 -4
@@ -593,12 +593,12 @@ static const struct snd_soc_dapm_route a { "SPKL", "Input Switch", "MIXINL" }, { "SPKL", "IN1LP Switch", "IN1LP" }, - { "SPKL", "Output Switch", "Left Output Mixer" }, + { "SPKL", "Output Switch", "Left Output PGA" }, { "SPKL", NULL, "TOCLK" }, { "SPKR", "Input Switch", "MIXINR" }, { "SPKR", "IN1RP Switch", "IN1RP" }, - { "SPKR", "Output Switch", "Right Output Mixer" }, + { "SPKR", "Output Switch", "Right Output PGA" }, { "SPKR", NULL, "TOCLK" }, { "SPKL Boost", "Direct Voice Switch", "Direct Voice" },
@@ -620,8 +620,8 @@ static const struct snd_soc_dapm_route a { "SPKOUTRP", NULL, "SPKR Driver" }, { "SPKOUTRN", NULL, "SPKR Driver" }, - { "Left Headphone Mux", "Mixer", "Left Output Mixer" }, - { "Right Headphone Mux", "Mixer", "Right Output Mixer" }, + { "Left Headphone Mux", "Mixer", "Left Output PGA" }, + { "Right Headphone Mux", "Mixer", "Right Output PGA" }, { "Headphone PGA", NULL, "Left Headphone Mux" }, { "Headphone PGA", NULL, "Right Headphone Mux" },
PATCH 11/43 kconfig: Avoid buffer underrun in choice input
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Ben Hutchings <[email protected]>
commit 3ba41621156681afcdbcd624e3191cbc65eb94f4 upstream.
Commit 40aee729b350 ('kconfig: fix default value for choice input') fixed some cases where kconfig would select the wrong option from a choice with a single valid option and thus enter an infinite loop.
However, this broke the test for user input of the form 'N?', because when kconfig selects the single valid option the input is zero-length and the test will read the byte before the input buffer. If this happens to contain '?' (as it will in a mips build on Debian unstable today) then kconfig again enters an infinite loop.
--- scripts/kconfig/conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/kconfig/conf.c +1 -1
@@ -330,7 +330,7 @@ static int conf_choice(struct menu *menu }if (!child)continue ; -if (line[strlen (line) -1 ] =='?' ) { +if (line[0 ] && line[strlen (line) -1 ] =='?' ) {print_help (child);continue ; }
PATCH 12/43 UBIFS: fix master node recovery
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Artem Bityutskiy <[email protected]>
commit 6e0d9fd38b750d678bf9fd07db23582f52fafa55 upstream.
This patch fixes the following symptoms:
1. Unmount UBIFS cleanly.
2. Start mounting UBIFS R/W and have a power cut immediately
3. Start mounting UBIFS R/O, this succeeds
4. Try to re-mount UBIFS R/W - this fails immediately or later on, because UBIFS will write the master node to the flash area which has been written before.
The analysis of the problem:
1. UBIFS is unmounted cleanly, both copies of the master node are clean.
2. UBIFS is being mounter R/W, starts changing master node copy 1, and a power cut happens. The copy N1 becomes corrupted.
3. UBIFS is being mounted R/O. It notices the copy N1 is corrupted and reads copy N2. Copy N2 is clean.
4. Because of R/O mode, UBIFS cannot recover copy 1.
5. The mount code (ubifs_mount()) sees that the master node is clean, so it decides that no recovery is needed.
6. We are re-mounting R/W. UBIFS believes no recovery is needed and starts updating the master node, but copy N1 is still corrupted and was not recovered!
Fix this problem by marking the master node as dirty every time we recover it and we are in R/O mode. This forces further recovery and the UBIFS cleans-up the corruptions and recovers the copy N1 when re-mounting R/W later.
--- fs/ubifs/recovery.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
fs/ubifs/recovery.c +26 -0
@@ -299,6 +299,32 @@ int ubifs_recover_master_node(struct ubi goto out_free; }memcpy (c->rcvrd_mst_node, c->mst_node,UBIFS_MST_NODE_SZ ); + +/* +* We had to recover the master node, which means there was an +* unclean reboot. However, it is possible that the master node +* is clean at this point, i.e., %UBIFS_MST_DIRTY is not set. +* E.g., consider the following chain of events: +* +* 1. UBIFS was cleanly unmounted, so the master node is clean +* 2. UBIFS is being mounted R/W and starts changing the master +* node in the first (%UBIFS_MST_LNUM). A power cut happens, +* so this LEB ends up with some amount of garbage at the +* end. +* 3. UBIFS is being mounted R/O. We reach this place and +* recover the master node from the second LEB +* (%UBIFS_MST_LNUM + 1). But we cannot update the media +* because we are being mounted R/O. We have to defer the +* operation. +* 4. However, this master node (@c->mst_node) is marked as +* clean (since the step 1). And if we just return, the +* mount code will be confused and won't recover the master +* node when it is re-mounter R/W later. +* +* Thus, to force the recovery by marking the master node as +* dirty. +*/ + c->mst_node->flags |=cpu_to_le32 (UBIFS_MST_DIRTY ); }else {/* Write the recovered master node */ c->max_sqnum =le64_to_cpu (mst->ch.sqnum) -1 ;
PATCH 13/43 Remove extra struct page member from the buffer info structure
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Greg Rose <[email protected]>
commit b1d670f10e8078485884f0cf7e384d890909aeaa upstream.
declaration.
--- drivers/net/igbvf/igbvf.h | 1 - 1 file changed, 1 deletion(-)
drivers/net/igbvf/igbvf.h +0 -1
@@ -126,7 +126,6 @@ struct igbvf_buffer {unsigned int page_offset; }; }; -struct page *page; };union igbvf_desc {
PATCH 14/43 dasd: correct device table
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Stefan Haberland <[email protected]>
commit 5da24b7627ff821e154a3aaecd5d60e1d8e228a5 upstream.
The 3880 storage control unit supports a 3380 device type, but not a 3390 device type.
--- drivers/s390/block/dasd_eckd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/s390/block/dasd_eckd.c +1 -1
@@ -63,7 +63,7 @@ static struct dasd_discipline dasd_eckd_static struct ccw_device_id dasd_eckd_ids[] = { {CCW_DEVICE_DEVTYPE (0x3990 ,0 ,0x3390 ,0 ), .driver_info =0x1 }, {CCW_DEVICE_DEVTYPE (0x2105 ,0 ,0x3390 ,0 ), .driver_info =0x2 }, - {CCW_DEVICE_DEVTYPE (0x3880 ,0 ,0x3390 ,0 ), .driver_info =0x3 }, + {CCW_DEVICE_DEVTYPE (0x3880 ,0 ,0x3380 ,0 ), .driver_info =0x3 }, {CCW_DEVICE_DEVTYPE (0x3990 ,0 ,0x3380 ,0 ), .driver_info =0x4 }, {CCW_DEVICE_DEVTYPE (0x2105 ,0 ,0x3380 ,0 ), .driver_info =0x5 }, {CCW_DEVICE_DEVTYPE (0x9343 ,0 ,0x9345 ,0 ), .driver_info =0x6 },
PATCH 15/43 iwlagn: Support new 5000 microcode.
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Fry, Donald H <[email protected]>
commit 41504cce240f791f1e16561db95728c5537fbad9 upstream.
New iwlwifi-5000 microcode requires driver support for API version 5.
--- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/iwlwifi/iwl-5000.c +1 -1
@@ -48,7 +48,7 @@#include "iwl-6000-hw.h" /* Highest firmware API version supported */ -#define IWL5000_UCODE_API_MAX 2 +#define IWL5000_UCODE_API_MAX 5#define IWL5150_UCODE_API_MAX 2/* Lowest firmware API version supported */
PATCH 16/43 udp: Fix bogus UFO packet generation
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Herbert Xu <[email protected]>
commit 26cde9f7e2747b6d254b704594eed87ab959afa5 upstream.
It has been reported that the new UFO software fallback path fails under certain conditions with NFS. I tracked the problem down to the generation of UFO packets that are smaller than the MTU. The software fallback path simply discards these packets.
This patch fixes the problem by not generating such packets on the UFO path.
--- net/ipv4/ip_output.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
net/ipv4/ip_output.c +6 -3
@@ -870,8 +870,10 @@ int ip_append_data(struct sock *sk, !exthdrlen) csummode =CHECKSUM_PARTIAL ; + skb =skb_peek_tail (&sk->sk_write_queue); + inet->cork.length += length; -if (((length> mtu) || !skb_queue_empty (&sk->sk_write_queue)) && +if (((length > mtu) || (skb &&skb_is_gso (skb))) && (sk->sk_protocol ==IPPROTO_UDP ) && (rt->u.dst.dev->features &NETIF_F_UFO )) { err = ip_ufo_append_data(sk, getfrag, from, length, hh_len,
@@ -889,7 +891,7 @@ int ip_append_data(struct sock *sk,* adding appropriate IP header. */ -if ((skb =skb_peek_tail (&sk->sk_write_queue)) ==NULL ) +if (!skb) goto alloc_new_skb;while (length >0 ) {
@@ -1118,7 +1120,8 @@ ssize_t ip_append_page(struct sock *sk,return -EINVAL ; inet->cork.length += size; -if ((sk->sk_protocol ==IPPROTO_UDP ) && +if ((size + skb->len > mtu) && + (sk->sk_protocol ==IPPROTO_UDP ) && (rt->u.dst.dev->features &NETIF_F_UFO )) {skb_shinfo (skb)->gso_size = mtu - fragheaderlen;skb_shinfo (skb)->gso_type =SKB_GSO_UDP ;
PATCH 17/43 slub: fix panic with DISCONTIGMEM
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: James Bottomley <[email protected]>
commit 4a5fa3590f09999f6db41bc386bce40848fa9f63 upstream.
Slub makes assumptions about page_to_nid() which are violated by DISCONTIGMEM and !NUMA. This violation results in a panic because page_to_nid() can be non-zero for pages in the discontiguous ranges and this leads to a null return by get_node(). The assertion by the maintainer is that DISCONTIGMEM should only be allowed when NUMA is also defined. However, at least six architectures: alpha, ia64, m32r, m68k, mips, parisc violate this. The panic is a regression against slab, so just mark slub broken in the problem configuration to prevent users reporting these panics.
--- init/Kconfig | 1 + 1 file changed, 1 insertion(+)
init/Kconfig +1 -0
@@ -1070,6 +1070,7 @@ config SLAB per cpu and per node queues. config SLUB + depends on BROKEN || NUMA || !DISCONTIGMEM bool "SLUB (Unqueued Allocator)" help SLUB is a slab allocator that minimizes cache line usage
PATCH 18/43 set memory ranges in N_NORMAL_MEMORY when onlined
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: David Rientjes <[email protected]>
commit d9b41e0b54fd7e164daf1e9c539c1070398aa02e upstream.
When a DISCONTIGMEM memory range is brought online as a NUMA node, it also needs to have its bet set in N_NORMAL_MEMORY. This is necessary for generic kernel code that utilizes N_NORMAL_MEMORY as a subset of N_ONLINE for memory savings.
These types of hacks can hopefully be removed once DISCONTIGMEM is either removed or abstracted away from CONFIG_NUMA.
Fixes a panic in the slub code which only initializes structures for N_NORMAL_MEMORY to save memory:
Backtrace: [<000000004021c938>] add_partial+0x28/0x98 [<000000004021faa0>] __slab_free+0x1d0/0x1d8 [<000000004021fd04>] kmem_cache_free+0xc4/0x128 [<000000004033bf9c>] ida_get_new_above+0x21c/0x2c0 [<00000000402a8980>] sysfs_new_dirent+0xd0/0x238 [<00000000402a974c>] create_dir+0x5c/0x168 [<00000000402a9ab0>] sysfs_create_dir+0x98/0x128 [<000000004033d6c4>] kobject_add_internal+0x114/0x258 [<000000004033d9ac>] kobject_add_varg+0x7c/0xa0 [<000000004033df20>] kobject_add+0x50/0x90 [<000000004033dfb4>] kobject_create_and_add+0x54/0xc8 [<00000000407862a0>] cgroup_init+0x138/0x1f0 [<000000004077ce50>] start_kernel+0x5a0/0x840 [<000000004011fa3c>] start_parisc+0xa4/0xb8 [<00000000404bb034>] packet_ioctl+0x16c/0x208 [<000000004049ac30>] ip_mroute_setsockopt+0x260/0xf20
--- arch/parisc/mm/init.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/parisc/mm/init.c +3 -1
@@ -265,8 +265,10 @@ static void __init setup_bootmem(void) }memset (pfnnid_map,0xff ,sizeof (pfnnid_map)); -for (i =0 ; i < npmem_ranges; i++) +for (i =0 ; i < npmem_ranges; i++) { +node_set_state (i,N_NORMAL_MEMORY );node_set_online (i); + }#endif /*
PATCH 19/43 FLEXCOP-PCI: fix __xlate_proc_name-warning for flexcop-pci
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Patrick Boettcher <[email protected]>
commit b934c20de1398d4a82d2ecfeb588a214a910f13f upstream.
This patch fixes the warning about bad names for sys-fs and other kernel-things. The flexcop-pci driver was using '/'-characters in it, which is not good. This has been fixed in several attempts by several people, but obviously never made it into the kernel.
--- drivers/media/dvb/b2c2/flexcop-pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/dvb/b2c2/flexcop-pci.c +1 -1
@@ -38,7 +38,7 @@ MODULE_PARM_DESC(debug, DEBSTATUS);#define DRIVER_VERSION "0.1" -#define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver" +#define DRIVER_NAME "flexcop-pci"#define DRIVER_AUTHOR "Patrick Boettcher <[email protected]>"struct flexcop_pci {
PATCH 20/43 m68k/mm: Set all online nodes in N_NORMAL_MEMORY
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Michael Schmitz <[email protected]>
commit 4aac0b4815ba592052758f4b468f253d383dc9d6 upstream.
For m68k, N_NORMAL_MEMORY represents all nodes that have present memory since it does not support HIGHMEM. This patch sets the bit at the time node_present_pages has been set by free_area_init_node.
At the time the node is brought online, the node state would have to be done unconditionally since information about present memory has not yet been recorded.
If N_NORMAL_MEMORY is not accurate, slub may encounter errors since it uses this nodemask to setup per-cache kmem_cache_node data structures.
This pach is an alternative to the one proposed by David Rientjes <[email protected]> attempting to set node state immediately when bringing the node online.
--- arch/m68k/mm/motorola.c | 2 ++ 1 file changed, 2 insertions(+)
arch/m68k/mm/motorola.c +2 -0
@@ -299,6 +299,8 @@ void __init paging_init(void) zones_size[ZONE_DMA ] = m68k_memory[i].size >>PAGE_SHIFT ;free_area_init_node (i, zones_size, m68k_memory[i].addr >>PAGE_SHIFT ,NULL ); +if (node_present_pages (i)) +node_set_state (i,N_NORMAL_MEMORY ); } }
PATCH 21/43 nfs: dont lose MS_SYNCHRONOUS on remount of noac mount
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Jeff Layton <[email protected]>
commit 26c4c170731f00008f4317a2888a0a07ac99d90d upstream.
On a remount, the VFS layer will clear the MS_SYNCHRONOUS bit on the assumption that the flags on the mount syscall will have it set if the remounted fs is supposed to keep it.
In the case of "noac" though, MS_SYNCHRONOUS is implied. A remount of such a mount will lose the MS_SYNCHRONOUS flag since "sync" isn't part of the mount options.
--- fs/nfs/super.c | 9 +++++++++ 1 file changed, 9 insertions(+)
fs/nfs/super.c +9 -0
@@ -1981,6 +1981,15 @@ nfs_remount(struct super_block *sb, intif (error <0 ) goto out; +/* +* noac is a special case. It implies -o sync, but that's not +* necessarily reflected in the mtab options. do_remount_sb +* will clear MS_SYNCHRONOUS if -o sync wasn't specified in the +* remount options, so we have to explicitly reset it. +*/ +if (data->flags &NFS_MOUNT_NOAC ) + *flags |=MS_SYNCHRONOUS ; +/* compare new mount options with old ones */ error =nfs_compare_remount_data (nfss, data); out:
PATCH 22/43 NFSv4.1: Ensure state manager thread dies on last umount
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Trond Myklebust <[email protected]>
commit 47c2199b6eb5fbe38ddb844db7cdbd914d304f9c upstream.
Currently, the state manager may continue to try recovering state forever even after the last filesystem to reference that nfs_client has umounted.
--- fs/nfs/nfs4state.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/nfs/nfs4state.c +2 -2
@@ -1330,7 +1330,7 @@ static void nfs4_state_manager(struct nfint status =0 ;/* Ensure exclusive access to NFSv4 state */ -for (;;) { + do { if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) { /* We're going to have to re-establish a clientid */ status = nfs4_reclaim_lease(clp);
@@ -1404,7 +1404,7 @@ static void nfs4_state_manager(struct nfbreak ;if (test_and_set_bit (NFS4CLNT_MANAGER_RUNNING , &clp->cl_state) !=0 )break ; - } + }while (atomic_read (&clp->cl_count) >1 );return ; out_error: printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s"
PATCH 23/43 agp: fix arbitrary kernel memory writes
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Vasiliy Kulikov <[email protected]>
commit 194b3da873fd334ef183806db751473512af29ce upstream.
pg_start is copied from userspace on AGPIOC_BIND and AGPIOC_UNBIND ioctl cmds of agp_ioctl() and passed to agpioc_bind_wrap(). As said in the comment, (pg_start + mem->page_count) may wrap in case of AGPIOC_BIND, and it is not checked at all in case of AGPIOC_UNBIND. As a result, user with sufficient privileges (usually "video" group) may generate either local DoS or privilege escalation.
--- drivers/char/agp/generic.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/char/agp/generic.c +8 -3
@@ -1123,8 +1123,8 @@ int agp_generic_insert_memory(struct agpreturn -EINVAL ; } -/* AK: could wrap */ -if ((pg_start + mem->page_count) > num_entries) +if (((pg_start + mem->page_count) > num_entries) || + ((pg_start + mem->page_count) < pg_start))return -EINVAL ; j = pg_start;
@@ -1158,7 +1158,7 @@ int agp_generic_remove_memory(struct agp {size_t i;struct agp_bridge_data *bridge; -int mask_type; +int mask_type, num_entries; bridge = mem->bridge;if (!bridge)
@@ -1170,6 +1170,11 @@ int agp_generic_remove_memory(struct agpif (type != mem->type)return -EINVAL ; + num_entries =agp_num_entries (); +if (((pg_start + mem->page_count) > num_entries) || + ((pg_start + mem->page_count) < pg_start)) +return -EINVAL ; + mask_type = bridge->driver->agp_type_to_mask_type (bridge, type);if (mask_type !=0 ) {/* The generic routines know nothing of memory types */
PATCH 24/43 agp: fix OOM and buffer overflow
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Vasiliy Kulikov <[email protected]>
commit b522f02184b413955f3bc952e3776ce41edc6355 upstream.
page_count is copied from userspace. agp_allocate_memory() tries to check whether this number is too big, but doesn't take into account the wrap case. Also agp_create_user_memory() doesn't check whether alloc_size is calculated from num_agp_pages variable without overflow. This may lead to allocation of too small buffer with following buffer overflow.
Another problem in agp code is not addressed in the patch - kernel memory exhaustion (AGPIOC_RESERVE and AGPIOC_ALLOCATE ioctls). It is not checked whether requested pid is a pid of the caller (no check in agpioc_reserve_wrap()). Each allocation is limited to 16KB, though, there is no per-process limit. This might lead to OOM situation, which is not even solved in case of the caller death by OOM killer - the memory is allocated for another (faked) process.
--- drivers/char/agp/generic.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/char/agp/generic.c +7 -1
@@ -123,6 +123,9 @@ static struct agp_memory *agp_create_usestruct agp_memory *new;unsigned long alloc_size = num_agp_pages*sizeof (struct page *); +if (INT_MAX /sizeof (struct page *) < num_agp_pages) +return NULL ; + new =kzalloc (sizeof (struct agp_memory ),GFP_KERNEL );if (new ==NULL )return NULL ;
@@ -242,11 +245,14 @@ struct agp_memory *agp_allocate_memory(sint scratch_pages;struct agp_memory *new;size_t i; +int cur_memory;if (!bridge)return NULL ; -if ((atomic_read (&bridge->current_memory_agp) + page_count) > bridge->max_memory_agp) + cur_memory =atomic_read (&bridge->current_memory_agp); +if ((cur_memory + page_count > bridge->max_memory_agp) || + (cur_memory + page_count < page_count))return NULL ;if (type >=AGP_USER_TYPES ) {
PATCH 25/43 Input: xen-kbdfront - fix mouse getting stuck after save/restore
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Igor Mammedov <[email protected]>
commit c36b58e8a9112017c2bcc322cc98e71241814303 upstream.
Mouse gets "stuck" after restore of PV guest but buttons are in working condition.
If driver has been configured for ABS coordinates at start it will get XENKBD_TYPE_POS events and then suddenly after restore it'll start getting XENKBD_TYPE_MOTION events, that will be dropped later and they won't get into user-space.
Regression was introduced by hunk 5 and 6 of 5ea5254aa0ad269cfbd2875c973ef25ab5b5e9db
("Input: xen-kbdfront - advertise either absolute or relative coordinates").
Driver on restore should ask xen for request-abs-pointer again if it is available. So restore parts that did it before 5ea5254.
--- drivers/input/xen-kbdfront.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/input/xen-kbdfront.c +11 -1
@@ -284,7 +284,7 @@ static void xenkbd_backend_changed(struc enum xenbus_state backend_state) {struct xenkbd_info *info =dev_get_drvdata (&dev->dev); -int val; +int ret, val;switch (backend_state) {case XenbusStateInitialising:
@@ -295,6 +295,16 @@ static void xenkbd_backend_changed(struccase XenbusStateInitWait: InitWait: + ret =xenbus_scanf (XBT_NIL , info->xbdev->otherend, +"feature-abs-pointer" ,"%d" , &val); +if (ret <0 ) + val =0 ; +if (val) { + ret =xenbus_printf (XBT_NIL , info->xbdev->nodename, +"request-abs-pointer" ,"1" ); +if (ret) +pr_warning ("can't request abs-pointer\n" ); + }xenbus_switch_state (dev, XenbusStateConnected);break ;
PATCH 26/43 pmcraid: reject negative request size
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Dan Rosenberg <[email protected]>
commit 5f6279da3760ce48f478f2856aacebe0c59a39f3 upstream.
There's a code path in pmcraid that can be reached via device ioctl that causes all sorts of ugliness, including heap corruption or triggering the OOM killer due to consecutive allocation of large numbers of pages. Not especially relevant from a security perspective, since users must have CAP_SYS_ADMIN to open the character device.
First, the user can call pmcraid_chr_ioctl() with a type PMCRAID_PASSTHROUGH_IOCTL. A pmcraid_passthrough_ioctl_buffer is copied in, and the request_size variable is set to buffer->ioarcb.data_transfer_length, which is an arbitrary 32-bit signed value provided by the user.
If a negative value is provided here, bad things can happen. For example, pmcraid_build_passthrough_ioadls() is called with this request_size, which immediately calls pmcraid_alloc_sglist() with a negative size. The resulting math on allocating a scatter list can result in an overflow in the kzalloc() call (if num_elem is 0, the sglist will be smaller than expected), or if num_elem is unexpectedly large the subsequent loop will call alloc_pages() repeatedly, a high number of pages will be allocated and the OOM killer might be invoked.
Prevent this value from being negative in pmcraid_ioctl_passthrough().
--- drivers/scsi/pmcraid.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/scsi/pmcraid.c +3 -0
@@ -3527,6 +3527,9 @@ static long pmcraid_ioctl_passthrough( rc = -EFAULT ; goto out_free_buffer; } + }else if (request_size <0 ) { + rc = -EINVAL ; + goto out_free_buffer; }/* check if we have any additional command parameters */
PATCH 27/43 mpt2sas: prevent heap overflows and unchecked reads
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Dan Rosenberg <[email protected]>
commit a1f74ae82d133ebb2aabb19d181944b4e83e9960 upstream.
At two points in handling device ioctls via /dev/mpt2ctl, user-supplied length values are used to copy data from userspace into heap buffers without bounds checking, allowing controllable heap corruption and subsequently privilege escalation.
Additionally, user-supplied values are used to determine the size of a copy_to_user() as well as the offset into the buffer to be read, with no bounds checking, allowing users to read arbitrary kernel memory.
--- drivers/scsi/mpt2sas/mpt2sas_ctl.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-)
drivers/scsi/mpt2sas/mpt2sas_ctl.c +21 -2
@@ -636,6 +636,13 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPT data_out_sz = karg.data_out_size; data_in_sz = karg.data_in_size; +/* Check for overflow and wraparound */ +if (karg.data_sge_offset *4 > ioc->request_sz || + karg.data_sge_offset > (UINT_MAX /4 )) { + ret = -EINVAL ; + goto out; + } +/* copy in request message frame from user */ if (copy_from_user (mpi_request, mf, karg.data_sge_offset*4 )) { printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, __LINE__,
@@ -1876,7 +1883,7 @@ _ctl_diag_read_buffer(void __user *arg,Mpi2DiagBufferPostReply_t *mpi_reply;int rc, i;u8 buffer_type; -unsigned long timeleft; +unsigned long timeleft, request_size, copy_size;u16 smid;u16 ioc_status;u8 issue_reset =0 ;
@@ -1912,6 +1919,8 @@ _ctl_diag_read_buffer(void __user *arg,return -ENOMEM ; } + request_size = ioc->diag_buffer_sz[buffer_type]; +if ((karg.starting_offset %4 ) || (karg.bytes_to_read %4 )) { printk(MPT2SAS_ERR_FMT "%s: either the starting_offset " "or bytes_to_read are not 4 byte aligned\n", ioc->name,
@@ -1919,13 +1928,23 @@ _ctl_diag_read_buffer(void __user *arg,return -EINVAL ; } +if (karg.starting_offset > request_size) +return -EINVAL ; + diag_data = (void *)(request_data + karg.starting_offset);dctlprintk (ioc,printk (MPT2SAS_DEBUG_FMT "%s: diag_buffer(%p), " "offset(%d), sz(%d)\n" , ioc->name, __func__, diag_data, karg.starting_offset, karg.bytes_to_read)); +/* Truncate data on requests that are too large */ +if ((diag_data + karg.bytes_to_read < diag_data) || + (diag_data + karg.bytes_to_read > request_data + request_size)) + copy_size = request_size - karg.starting_offset; +else + copy_size = karg.bytes_to_read; +if (copy_to_user ((void __user *)uarg->diagnostic_data, - diag_data, karg.bytes_to_read)) { + diag_data, copy_size)) {printk (MPT2SAS_ERR_FMT "%s: Unable to write " "mpt_diag_read_buffer_t data @ %p\n" , ioc->name, __func__, diag_data);
PATCH 28/43 put stricter guards on queue dead checks
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: James Bottomley <[email protected]>
commit 86cbfb5607d4b81b1a993ff689bbd2addd5d3a9b upstream.
SCSI uses request_queue->queuedata == NULL as a signal that the queue is dying. We set this state in the sdev release function. However, this allows a small window where we release the last reference but haven't quite got to this stage yet and so something will try to take a reference in scsi_request_fn and oops. It's very rare, but we had a report here, so we're pushing this as a bug fix
The actual fix is to set request_queue->queuedata to NULL in scsi_remove_device() before we drop the reference. This causes correct automatic rejects from scsi_request_fn as people who hold additional references try to submit work and prevents anything from getting a new reference to the sdev that way.
--- drivers/scsi/scsi_sysfs.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/scsi/scsi_sysfs.c +8 -8
@@ -318,14 +318,8 @@ static void scsi_device_dev_release_userkfree (evt); } -if (sdev->request_queue) { - sdev->request_queue->queuedata =NULL ; -/* user context needed to free queue */ -scsi_free_queue (sdev->request_queue); -/* temporary expedient, try to catch use of queue lock -* after free of sdev */ - sdev->request_queue =NULL ; - } +/* NULL queue means the device can't be used */ + sdev->request_queue =NULL ;scsi_target_reap (scsi_target (sdev));
@@ -963,6 +957,12 @@ void __scsi_remove_device(struct scsi_deif (sdev->host->hostt->slave_destroy) sdev->host->hostt->slave_destroy (sdev);transport_destroy_device (dev); + +/* cause the request function to reject all I/O requests */ + sdev->request_queue->queuedata =NULL ; + +/* Freeing the queue signals to block that we're done */ +scsi_free_queue (sdev->request_queue);put_device (dev); }
PATCH 29/43 mmc: sdhci-pci: Fix error case in sdhci_pci_probe_slot()
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Chris Ball <[email protected]>
commit 9fdcdbb0d84922e7ccda2f717a04ea62629f7e18 upstream.
If pci_ioremap_bar() fails during probe, we "goto release;" and free the host, but then we return 0 -- which tells sdhci_pci_probe() that the probe succeeded. Since we think the probe succeeded, when we unload sdhci we'll go to sdhci_pci_remove_slot() and it will try to dereference slot->host, which is now NULL because we freed it in the error path earlier.
The patch simply sets ret appropriately, so that sdhci_pci_probe() will detect the failure immediately and bail out.
--- drivers/mmc/host/sdhci-pci.c | 1 + 1 file changed, 1 insertion(+)
drivers/mmc/host/sdhci-pci.c +1 -0
@@ -644,6 +644,7 @@ static struct sdhci_pci_slot * __devinit host->ioaddr =pci_ioremap_bar (pdev, bar);if (!host->ioaddr) {dev_err (&pdev->dev,"failed to remap registers\n" ); + ret = -ENOMEM ; goto release; }
PATCH 30/43 mmc: sdhci: Check mrq->cmd in sdhci_tasklet_finish
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Ben Dooks <[email protected]>
commit b7b4d3426d2b5ecab21578eb20d8e456a1aace8f upstream.
It seems that under certain circumstances that the sdhci_tasklet_finish() call can be entered with mrq->cmd set to NULL, causing the system to crash with a NULL pointer de-reference.
Unable to handle kernel NULL pointer dereference at virtual address 00000000 PC is at sdhci_tasklet_finish+0x34/0xe8 LR is at sdhci_tasklet_finish+0x24/0xe8
Seen on S3C6410 system.
--- drivers/mmc/host/sdhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mmc/host/sdhci.c +1 -1
@@ -1277,7 +1277,7 @@ static void sdhci_tasklet_finish(unsigne* upon error conditions. */ if (!(host->flags &SDHCI_DEVICE_DEAD ) && - (mrq->cmd->error || + ((mrq->cmd && mrq->cmd->error) || (mrq->data && (mrq->data->error || (mrq->data->stop && mrq->data->stop->error))) || (host->quirks &SDHCI_QUIRK_RESET_AFTER_REQUEST ))) {
PATCH 31/43 mmc: sdhci: Check mrq != NULL in sdhci_tasklet_finish
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Chris Ball <[email protected]>
commit 0c9c99a765321104cc5f9c97f949382a9ba4927e upstream.
It seems that under certain circumstances the sdhci_tasklet_finish() call can be entered with mrq set to NULL, causing the system to crash with a NULL pointer de-reference.
Seen on S3C6410 system. Based on a patch by Dimitris Papastamos.
--- drivers/mmc/host/sdhci.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/mmc/host/sdhci.c +7 -0
@@ -1266,6 +1266,13 @@ static void sdhci_tasklet_finish(unsigne host = (struct sdhci_host *)param; +/* +* If this tasklet gets rescheduled while running, it will +* be run again afterwards but without any active request. +*/ +if (!host->mrq) +return ; +spin_lock_irqsave (&host->lock, flags);del_timer (&host->timer);
PATCH 32/43 USB: fix regression in usbip by setting has_tt flag
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Alan Stern <[email protected]>
commit cee6a262550f53a13acfefbc1e3e5ff35c96182c upstream.
This patch (as1460) fixes a regression in the usbip driver caused by the new check for Transaction Translators in USB-2 hubs. The root hub registered by vhci_hcd needs to have the has_tt flag set, because it can connect to low- and full-speed devices as well as high-speed devices.
--- drivers/staging/usbip/vhci_hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/usbip/vhci_hcd.c +1 -1
@@ -1134,7 +1134,7 @@ static int vhci_hcd_probe(struct platforusbip_uerr ("create hcd failed\n" );return -ENOMEM ; } - + hcd->has_tt =1 ;/* this is private data for vhci_hcd */ the_controller =hcd_to_vhci (hcd);
PATCH 33/43 x86, AMD: Fix APIC timer erratum 400 affecting K8 Rev.A-E processors
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Boris Ostrovsky <[email protected]>
commit e20a2d205c05cef6b5783df339a7d54adeb50962 upstream.
Older AMD K8 processors (Revisions A-E) are affected by erratum 400 (APIC timer interrupts don't occur in C states greater than C1). This, for example, means that X86_FEATURE_ARAT flag should not be set for these parts.
This addresses regression introduced by commit b87cf80af3ba4b4c008b4face3c68d604e1715c6 ("x86, AMD: Set ARAT feature on AMD processors") where the system may become unresponsive until external interrupt (such as keyboard input) occurs. This results, for example, in time not being reported correctly, lack of progress on the system and other lockups.
--- arch/x86/kernel/cpu/amd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/cpu/amd.c +1 -1
@@ -651,7 +651,7 @@ cpu_dev_register(amd_cpu_dev);*/ const int amd_erratum_400[] = -AMD_OSVW_ERRATUM (1 ,AMD_MODEL_RANGE (0xf ,0x41 ,0x2 ,0xff ,0xf ), +AMD_OSVW_ERRATUM (1 ,AMD_MODEL_RANGE (0x0f ,0x4 ,0x2 ,0xff ,0xf ),AMD_MODEL_RANGE (0x10 ,0x2 ,0x1 ,0xff ,0xf ));
PATCH 34/43 af_unix: Only allow recv on connected seqpacket sockets.
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Eric W. Biederman <[email protected]>
commit a05d2ad1c1f391c7f514a1d1e09b5417968a7d07 upstream.
This fixes the following oops discovered by Dan Aloni:
Quoted 11 lines
Anyway, the following is the output of the Oops that I got on the Ubuntu kernel on which I first detected the problem (2.6.37-12-generic). The Oops that followed will be more useful, I guess.
[ 5594.669852] BUG: unable to handle kernel NULL pointer dereference at (null) [ 5594.681606] IP: [<ffffffff81550b7b>] unix_dgram_recvmsg+0x1fb/0x420 [ 5594.687576] PGD 2a05d067 PUD 2b951067 PMD 0 [ 5594.693720] Oops: 0002 [#1] SMP [ 5594.699888] last sysfs file:
The bug was that unix domain sockets use a pseduo packet for connecting and accept uses that psudo packet to get the socket. In the buggy seqpacket case we were allowing unconnected sockets to call recvmsg and try to receive the pseudo packet.
That is always wrong and as of commit 7361c36c5 the pseudo packet had become enough different from a normal packet that the kernel started oopsing.
Do for seqpacket_recv what was done for seqpacket_send in 2.5 and only allow it on connected seqpacket sockets.
--- net/unix/af_unix.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
net/unix/af_unix.c +15 -1
@@ -503,6 +503,8 @@ static int unix_dgram_connect(struct soc int, int);static int unix_seqpacket_sendmsg (struct kiocb *,struct socket *,struct msghdr *,size_t ); +static int unix_seqpacket_recvmsg (struct kiocb *,struct socket *, +struct msghdr *,size_t ,int );static const struct proto_ops unix_stream_ops = { .family =PF_UNIX ,
@@ -562,7 +564,7 @@ static const struct proto_ops unix_seqpa .setsockopt = sock_no_setsockopt, .getsockopt = sock_no_getsockopt, .sendmsg = unix_seqpacket_sendmsg, - .recvmsg = unix_dgram_recvmsg, + .recvmsg = unix_seqpacket_recvmsg, .mmap = sock_no_mmap, .sendpage = sock_no_sendpage, };
@@ -1631,6 +1633,18 @@ static int unix_seqpacket_sendmsg(structreturn unix_dgram_sendmsg (kiocb, sock, msg, len); } +static int unix_seqpacket_recvmsg (struct kiocb *iocb,struct socket *sock, +struct msghdr *msg,size_t size, +int flags) +{ +struct sock *sk = sock->sk; + +if (sk->sk_state !=TCP_ESTABLISHED ) +return -ENOTCONN ; + +return unix_dgram_recvmsg (iocb, sock, msg, size, flags); +} +static void unix_copy_addr (struct msghdr *msg,struct sock *sk) {struct unix_sock *u =unix_sk (sk);
PATCH 35/43 ARM: 6891/1: prevent heap corruption in OABI semtimedop
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Dan Rosenberg <[email protected]>
commit 0f22072ab50cac7983f9660d33974b45184da4f9 upstream.
When CONFIG_OABI_COMPAT is set, the wrapper for semtimedop does not bound the nsops argument. A sufficiently large value will cause an integer overflow in allocation size, followed by copying too much data into the allocated buffer. Fix this by restricting nsops to SEMOPM. Untested.
--- arch/arm/kernel/sys_oabi-compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/kernel/sys_oabi-compat.c +1 -1
@@ -311,7 +311,7 @@ asmlinkage long sys_oabi_semtimedop(intlong err;int i; -if (nsops <1 ) +if (nsops <1 || nsops >SEMOPM )return -EINVAL ; sops =kmalloc (sizeof (*sops) * nsops,GFP_KERNEL );if (!sops)
PATCH 36/43 i8k: Tell gcc that *regs gets clobbered
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Jim Bos <[email protected]>
commit 6b4e81db2552bad04100e7d5ddeed7e848f53b48 upstream.
More recent GCC caused the i8k driver to stop working, on Slackware compiler was upgraded from gcc-4.4.4 to gcc-4.5.1 after which it didn't work anymore, meaning the driver didn't load or gave total nonsensical output.
As it turned out the asm(..) statement forgot to mention it modifies the *regs variable.
Credits to Andi Kleen and Andreas Schwab for providing the fix.
--- drivers/char/i8k.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/char/i8k.c +3 -2
@@ -141,7 +141,7 @@ static int i8k_smm(struct smm_regs *regs "lahf\n\t" "shrl $8,%%eax\n\t" "andl $1,%%eax\n" - :"=a"(rc) + :"=a"(rc), "+m" (*regs) : "a"(regs) : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");#else
@@ -166,7 +166,8 @@ static int i8k_smm(struct smm_regs *regs "movl %%edx,0(%%eax)\n\t" "lahf\n\t" "shrl $8,%%eax\n\t" - "andl $1,%%eax\n":"=a"(rc) + "andl $1,%%eax\n" + :"=a"(rc), "+m" (*regs) : "a"(regs) : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");#endif
PATCH 37/43 Fix gcc 4.5.1 miscompiling drivers/char/i8k.c (again)
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Jim Bos <[email protected]>
commit 22d3243de86bc92d874abb7c5b185d5c47aba323 upstream.
The fix in commit 6b4e81db2552 ("i8k: Tell gcc that *regs gets clobbered") to work around the gcc miscompiling i8k.c to add "+m (*regs)" caused register pressure problems and a build failure.
Changing the 'asm' statement to 'asm volatile' instead should prevent that and works around the gcc bug as well, so we can remove the "+m".
[ Background on the gcc bug: a memory clobber fails to mark the function
the asm resides in as non-pure (aka "__attribute__((const))"), so if the function does nothing else that triggers the non-pure logic, gcc will think that that function has no side effects at all. As a result, callers will be mis-compiled.
Adding the "+m" made gcc see that it's not a pure function, and so does "asm volatile". The problem was never really the need to mark "*regs" as changed, since the memory clobber did that part - the problem was just a bug in the gcc "pure" function analysis - Linus ]
--- drivers/char/i8k.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/char/i8k.c +4 -4
@@ -119,7 +119,7 @@ static int i8k_smm(struct smm_regs *regsint eax = regs->eax;#if defined(CONFIG_X86_64 ) - asm("pushq %%rax\n\t" + asmvolatile ("pushq %%rax\n\t" "movl 0(%%rax),%%edx\n\t" "pushq %%rdx\n\t" "movl 4(%%rax),%%ebx\n\t"
@@ -141,11 +141,11 @@ static int i8k_smm(struct smm_regs *regs "lahf\n\t" "shrl $8,%%eax\n\t" "andl $1,%%eax\n" - :"=a"(rc), "+m" (*regs) + :"=a"(rc) : "a"(regs) : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");#else - asm("pushl %%eax\n\t" + asmvolatile ("pushl %%eax\n\t" "movl 0(%%eax),%%edx\n\t" "push %%edx\n\t" "movl 4(%%eax),%%ebx\n\t"
@@ -167,7 +167,7 @@ static int i8k_smm(struct smm_regs *regs "lahf\n\t" "shrl $8,%%eax\n\t" "andl $1,%%eax\n" - :"=a"(rc), "+m" (*regs) + :"=a"(rc) : "a"(regs) : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");#endif
PATCH 38/43 Open with O_CREAT flag set fails to open existing files on non writable directories
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Sachin Prabhu <[email protected]>
commit 1574dff8996ab1ed92c09012f8038b5566fce313 upstream.
An open on a NFS4 share using the O_CREAT flag on an existing file for which we have permissions to open but contained in a directory with no write permissions will fail with EACCES.
A tcpdump shows that the client had set the open mode to UNCHECKED which indicates that the file should be created if it doesn't exist and encountering an existing flag is not an error. Since in this case the file exists and can be opened by the user, the NFS server is wrong in attempting to check create permissions on the parent directory.
The patch adds a conditional statement to check for create permissions only if the file doesn't exist.
--- fs/nfsd/vfs.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
fs/nfsd/vfs.c +8 -1
@@ -1387,7 +1387,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, s goto out;if (!(iap->ia_valid &ATTR_MODE )) iap->ia_mode =0 ; - err =fh_verify (rqstp, fhp,S_IFDIR ,NFSD_MAY_CREATE ); + err =fh_verify (rqstp, fhp,S_IFDIR ,NFSD_MAY_EXEC );if (err) goto out;
@@ -1409,6 +1409,13 @@ nfsd_create_v3(struct svc_rqst *rqstp, sif (IS_ERR (dchild)) goto out_nfserr; +/* If file doesn't exist, check for permissions to create one */ +if (!dchild->d_inode) { + err =fh_verify (rqstp, fhp,S_IFDIR ,NFSD_MAY_CREATE ); +if (err) + goto out; + } + err =fh_compose (resfhp, fhp->fh_export, dchild, fhp);if (err) goto out;
PATCH 39/43 can: Add missing socket check in can/bcm release.
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Dave Jones <[email protected]>
commit c6914a6f261aca0c9f715f883a353ae7ff51fe83 upstream.
We can get here with a NULL socket argument passed from userspace, so we need to handle it accordingly.
--- net/can/bcm.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
net/can/bcm.c +6 -1
@@ -1412,9 +1412,14 @@ static int bcm_init(struct sock *sk)static int bcm_release (struct socket *sock) {struct sock *sk = sock->sk; -struct bcm_sock *bo =bcm_sk (sk); +struct bcm_sock *bo;struct bcm_op *op, *next; +if (sk ==NULL ) +return 0 ; + + bo =bcm_sk (sk); +/* remove bcm_ops, timer, rx_unregister(), etc. */ unregister_netdevice_notifier (&bo->notifier);
PATCH 40/43 fs/partitions/ldm.c: fix oops caused by corrupted partition table
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Timo Warns <[email protected]>
commit c340b1d640001c8c9ecff74f68fd90422ae2448a upstream.
The kernel automatically evaluates partition tables of storage devices. The code for evaluating LDM partitions (in fs/partitions/ldm.c) contains a bug that causes a kernel oops on certain corrupted LDM partitions. A kernel subsystem seems to crash, because, after the oops, the kernel no longer recognizes newly connected storage devices.
The patch validates the value of vblk_size.
--- fs/partitions/ldm.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
fs/partitions/ldm.c +12 -4
@@ -1299,6 +1299,11 @@ static bool ldm_frag_add (const u8 *dataBUG_ON (!data || !frags); +if (size <2 *VBLK_SIZE_HEAD ) { +ldm_error ("Value of size is to small." ); +return false; + } + group =get_unaligned_be32 (data +0x08 ); rec =get_unaligned_be16 (data +0x0C ); num =get_unaligned_be16 (data +0x0E );
@@ -1306,6 +1311,10 @@ static bool ldm_frag_add (const u8 *dataldm_error ("A VBLK claims to have %d parts." , num);return false; } +if (rec >= num) { +ldm_error ("REC value (%d) exceeds NUM value (%d)" , rec, num); +return false; + } list_for_each (item, frags) { f = list_entry (item, struct frag, list);
@@ -1334,10 +1343,9 @@ found: f->map |= (1 << rec); -if (num >0 ) { - data +=VBLK_SIZE_HEAD ; - size -=VBLK_SIZE_HEAD ; - } + data +=VBLK_SIZE_HEAD ; + size -=VBLK_SIZE_HEAD ; +memcpy (f->data+rec*(size-VBLK_SIZE_HEAD )+VBLK_SIZE_HEAD , data, size);return true;
PATCH 41/43 libata: set queue DMA alignment to sector size for ATAPI too
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Tejun Heo <[email protected]>
commit 729a6a300e628a48cf12bac93a964a535e83cd1d upstream.
ata_pio_sectors() expects buffer for each sector to be contained in a single page; otherwise, it ends up overrunning the first page. This is achieved by setting queue DMA alignment. If sector_size is smaller than PAGE_SIZE and all buffers are sector_size aligned, buffer for each sector is always contained in a single page.
This wasn't applied to ATAPI devices but IDENTIFY_PACKET is executed as ATA_PROT_PIO and thus uses ata_pio_sectors(). Newer versions of udev issue IDENTIFY_PACKET with unaligned buffer triggering the problem and causing oops.
This patch fixes the problem by setting sdev->sector_size to ATA_SECT_SIZE on ATATPI devices and always setting DMA alignment to sector_size. While at it, add a warning for the unlikely but still possible scenario where sector_size is larger than PAGE_SIZE, in which case the alignment wouldn't be enough.
--- drivers/ata/libata-scsi.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)
drivers/ata/libata-scsi.c +18 -6
@@ -1099,13 +1099,13 @@ static int ata_scsi_dev_config(struct sc/* configure max sectors */ blk_queue_max_sectors (sdev->request_queue, dev->max_sectors); + sdev->sector_size =ATA_SECT_SIZE ; +if (dev->class ==ATA_DEV_ATAPI ) {struct request_queue *q = sdev->request_queue;void *buf; -/* set the min alignment and padding */ -blk_queue_update_dma_alignment (sdev->request_queue, -ATA_DMA_PAD_SZ -1 ); +/* set DMA padding */ blk_queue_update_dma_pad (sdev->request_queue,ATA_DMA_PAD_SZ -1 );
@@ -1119,12 +1119,24 @@ static int ata_scsi_dev_config(struct scblk_queue_dma_drain (q, atapi_drain_needed, buf,ATAPI_MAX_DRAIN ); }else { -/* ATA devices must be sector aligned */ -blk_queue_update_dma_alignment (sdev->request_queue, -ATA_SECT_SIZE -1 ); sdev->manage_start_stop =1 ; } +/* +* ata_pio_sectors() expects buffer for each sector to not cross +* page boundary. Enforce it by requiring buffers to be sector +* aligned, which works iff sector_size is not larger than +* PAGE_SIZE. ATAPI devices also need the alignment as +* IDENTIFY_PACKET is executed as ATA_PROT_PIO. +*/ +if (sdev->sector_size >PAGE_SIZE ) +ata_dev_printk (dev,KERN_WARNING , +"sector_size=%u > PAGE_SIZE, PIO may malfunction\n" , + sdev->sector_size); + +blk_queue_update_dma_alignment (sdev->request_queue, + sdev->sector_size -1 ); +if (dev->flags &ATA_DFLAG_AN )set_bit (SDEV_EVT_MEDIA_CHANGE , sdev->supported_events);
PATCH 42/43 usb: musb: core: set has_tt flag
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Felipe Balbi <[email protected]>
commit ec95d35a6bd0047f05fe8a21e6c52f8bb418da55 upstream.
MUSB is a non-standard host implementation which can handle all speeds with the same core. We need to set has_tt flag after commit d199c96d41d80a567493e12b8e96ea056a1350c1 (USB: prevent buggy hubs from crashing the USB stack) in order for MUSB HCD to continue working.
--- drivers/usb/musb/musb_core.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/musb/musb_core.c +1 -0
@@ -1798,6 +1798,7 @@ allocate_instance(struct device *dev,INIT_LIST_HEAD (&musb->out_bulk); hcd->uses_new_polling =1 ; + hcd->has_tt =1 ; musb->vbuserr_retry =VBUSERR_RETRY_COUNT ; musb->a_wait_bcon =OTG_TIME_A_WAIT_BCON ;
PATCH 43/43 iwlwifi: fix skb usage after free
In reply to Greg KH2.6.33-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Stanislaw Gruszka <[email protected]>
commit b25026981aecde3685dd0e45ad980fff9f528daa upstream.
Since
commit a120e912eb51e347f36c71b60a1d13af74d30e83
Author: Stanislaw Gruszka <[email protected]> Date: Fri Feb 19 15:47:33 2010 -0800
iwlwifi: sanity check before counting number of tfds can be free
we use skb->data after calling ieee80211_tx_status_irqsafe(), which could free skb instantly.
On current kernels I do not observe practical problems related with bug, but on 2.6.35.y it cause random system hangs when stressing wireless link.
--- drivers/net/wireless/iwlwifi/iwl-tx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/wireless/iwlwifi/iwl-tx.c +6 -2
@@ -1162,11 +1162,15 @@ int iwl_tx_queue_reclaim(struct iwl_priv q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { tx_info = &txq->txb[txq->q.read_ptr]; -iwl_tx_status (priv, tx_info->skb[0 ]); + +if (WARN_ON_ONCE (tx_info->skb ==NULL )) +continue ; hdr = (struct ieee80211_hdr *)tx_info->skb[0 ]->data; -if (hdr &&ieee80211_is_data_qos (hdr->frame_control)) +if (ieee80211_is_data_qos (hdr->frame_control)) nfreed++; + +iwl_tx_status (priv, tx_info->skb[0 ]); tx_info->skb[0 ] =NULL ;if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)